Вот попытался писать как на Си так и на АСМе. Сначала не мог найти в какие регистры падают параметры передаваемые в функу. Нашёл. И попытался написать хардварный 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). Но почему? Может я как-то не так написал код АСМ?