Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: WinAVR .C + .S
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Spider
Вот попытался писать как на Си так и на АСМе. Сначала не мог найти в какие регистры падают параметры передаваемые в функу. Нашёл. И попытался написать хардварный SPI.
Вот что получилось:
Код
.nolist
#define __SFR_OFFSET 0
#include <avr/io.h>    // Include device specific definitions.
.list

#define    miso 0
#define    mosi 2
#define    sck 3
#define    nss 4

;misc usage, must be in upper regs for IMMED mode
#define    temp    r16    
#define    temp1    r17
#define    spi_lo    r24
#define    spi_hi    r25

.macro    ss_active
    cbi    PORTC,nss
.endm

.macro    ss_inactive
    sbi    PORTC,nss
.endm

.macro    sck_hi
    sbi    PORTC,sck
.endm

.macro    sck_lo
    cbi    PORTC,sck
.endm

.macro    mosi_hi
    sbi    PORTC,mosi
.endm

.macro    mosi_lo
    cbi    PORTC,mosi
.endm

.macro    addi
    subi    @0, -@1    ;subtract the negative of an immediate value
.endm

.macro    set_delay    ;set up the time delay amount, from 1 to 7
    subi    @0, (@1 << 5);NOTE: THIS shift affects INC macro (below)!
.endm

.macro    inc_delay    ;bump the delay counter
    subi    @0, -(1 << 5);shift value here must be same as above!
.endm

;    .text
    .global init_spi
    .global ena_spi
    .global disa_spi
    .global    rw_spi

init_spi:
    ss_inactive        
    sbi    DDRC,nss    
;
    sck_hi            
    sbi    DDRC,sck;make it an output
;
    mosi_lo            
    sbi    DDRC,mosi    
;
    cbi    DDRC,miso    
    ret

ena_spi:
    sck_hi            
    mosi_lo
    ss_active
    ret

disa_spi:
    ss_inactive
    ret

rw_spi:    
    ldi temp1,8
spi_loop:
    lsl    spi_lo        
    brcc    lo_mosi
    mosi_hi
    rjmp    mosi_done;this branch creates setup time on MOSI
lo_mosi:
    mosi_lo
mosi_done:
    sck_lo
    ldi temp,100        
    subi temp,2
    brne .-4        
    sck_hi            

    sbic    PINC,miso    
    inc    spi_lo                
    ldi temp,100            
    subi temp,2
    brne .-4        

    dec    temp1
    brne    spi_loop
    clr r25
    ret

теперь пробую это в Си коде:
Код
#include <avr/io.h>
#include <avr/boot.h>

void (*jump_to_app)(void) = 0x0000;

extern void init_spi(void);
extern void ena_spi(void);
extern void disa_spi(void);
extern unsigned char rw_spi(unsigned char cmd);

int main(void)
{
    unsigned char data;
    init_spi();

    ena_spi();
    rw_spi(0x00);
    data=rw_spi(0x80);
    if (data!=0xff) while(1);
    data=rw_spi(0x42);
    if (data!=0x82 && data!=0xC4 && data!=0xCE && data!=0xCA) while(1);
    data=rw_spi(0xFF);
    if (data!=0x5A) while(1);
    data=rw_spi(0x00);
    rw_spi(0x00);
    disa_spi();
    if (data!=0xFF)
        jump_to_app();

    //код бутлодера
}

В итоге всё запускает и типа работает, но дойдя до if (data!=0xFF) как бы ресетится и начинает заново. Но если убрать if (data!=0xFF) , но оставить jump_to_app(); то всё это дело выходит из бутлодераи и начинает исполняться приложение. Если убрать обе строки, то исполняеся бутлодер как надо.
Т.е. на лицо не работает if (data!=0xFF). Но почему? Может я как-то не так написал код АСМ?
gormih
wdt проверял?
Spider
Цитата(gormih @ Feb 19 2007, 16:17) *
wdt проверял?

Да. Нету.

ЗЫ. переписал асм код на си и всё работает как из пушки. Но дело не закрыто, я хочу понять как писать и на асме и на си в ГСС.
Сергей Борщ
Цитата(Alexey Belyaev @ Feb 19 2007, 14:53) *
ЗЫ. переписал асм код на си и всё работает как из пушки. Но дело не закрыто, я хочу понять как писать и на асме и на си в ГСС.
А что говорил листинг подозрительного куска?
=GM=
Цитата(Alexey Belyaev @ Feb 19 2007, 07:58) *
Вот попытался писать как на Си так и на АСМе. Сначала не мог найти в какие регистры падают параметры передаваемые в функу. Нашёл. И попытался написать хардварный SPI.
Вот что получилось:
Код
rw_spi:    
    ldi temp1,8
spi_loop:    lsl    spi_lo        
    brcc    lo_mosi
    mosi_hi
    rjmp    mosi_done;this branch creates setup time on MOSI
lo_mosi:    mosi_lo
mosi_done:
    sck_lo
    ldi temp,100        
    subi temp,2
    brne .-4        
    sck_hi            

    sbic    PINC,miso    
    inc    spi_lo                
    ldi temp,100            
    subi temp,2
    brne .-4        

    dec    temp1
    brne    spi_loop
    clr r25
    ret

В итоге всё запускает и типа работает, но дойдя до if (data!=0xFF) как бы ресетится и начинает заново. Но если убрать if (data!=0xFF) , но оставить jump_to_app(); то всё это дело выходит из бутлодераи и начинает исполняться приложение. Если убрать обе строки, то исполняеся бутлодер как надо.
Т.е. на лицо не работает if (data!=0xFF). Но почему? Может я как-то не так написал код АСМ?

Пара вопросов по асмовой программе

1) Как вы передаете параметры из ассемблерной программы в си?

2) Если это аппаратная реализация, то зачем вы дрыгаете ногами спи?
Spider
Цитата(=GM= @ Feb 19 2007, 23:03) *
Цитата(Alexey Belyaev @ Feb 19 2007, 07:58) *

Вот попытался писать как на Си так и на АСМе. Сначала не мог найти в какие регистры падают параметры передаваемые в функу. Нашёл. И попытался написать хардварный SPI.

В итоге всё запускает и типа работает, но дойдя до if (data!=0xFF) как бы ресетится и начинает заново. Но если убрать if (data!=0xFF) , но оставить jump_to_app(); то всё это дело выходит из бутлодераи и начинает исполняться приложение. Если убрать обе строки, то исполняеся бутлодер как надо.
Т.е. на лицо не работает if (data!=0xFF). Но почему? Может я как-то не так написал код АСМ?

Пара вопросов по асмовой программе

1) Как вы передаете параметры из ассемблерной программы в си?

r24 должен содержать результат возврата. Об этом в мануале по гсс написано.
Цитата(=GM= @ Feb 19 2007, 23:03) *
2) Если это аппаратная реализация, то зачем вы дрыгаете ногами спи?

Очепятка. Пардон. Софтварный пишем.
=GM=
Цитата(Alexey Belyaev @ Feb 19 2007, 07:58) *
if (data!=0x5A) while(1);
data=rw_spi(0x00);
rw_spi(0x00);
disa_spi();
if (data!=0xFF) jump_to_app();
//код бутлодера
В итоге всё запускает и типа работает, но дойдя до if (data!=0xFF) как бы ресетится и начинает заново. Но если убрать if (data!=0xFF) , но оставить jump_to_app(); то всё это дело выходит из бутлодераи и начинает исполняться приложение. Если убрать обе строки, то исполняется бутлодер как надо.
Т.е. налицо не работает if (data!=0xFF). Но почему? Может я как-то не так написал код АСМ?

Видимо, то устройство, с которым вы работаете по спи, не присылает вам 0xFF, поэтому нет вызова jump_to_app(), значит по логике должен выполняться код загрузчика, никакого ресета.
Spider
Цитата(=GM= @ Feb 20 2007, 05:50) *
Цитата(Alexey Belyaev @ Feb 19 2007, 07:58) *

if (data!=0x5A) while(1);
data=rw_spi(0x00);
rw_spi(0x00);
disa_spi();
if (data!=0xFF) jump_to_app();
//код бутлодера
В итоге всё запускает и типа работает, но дойдя до if (data!=0xFF) как бы ресетится и начинает заново. Но если убрать if (data!=0xFF) , но оставить jump_to_app(); то всё это дело выходит из бутлодераи и начинает исполняться приложение. Если убрать обе строки, то исполняется бутлодер как надо.
Т.е. налицо не работает if (data!=0xFF). Но почему? Может я как-то не так написал код АСМ?

Видимо, то устройство, с которым вы работаете по спи, не присылает вам 0xFF, поэтому нет вызова jump_to_app(), значит по логике должен выполняться код загрузчика, никакого ресета.

А происходило что-то вроде ресета.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.