📄 spi.s
字号:
.module spi.c
.area text(rom, con, rel)
.dbfile E:\单片机\源程序\Snail_mkII\STK500_V2\ICC\spi.c
.area data(ram, con, rel)
.dbfile E:\单片机\源程序\Snail_mkII\STK500_V2\ICC\spi.c
_use_sw_spi:
.blkb 1
.area idata
.byte 0
.area data(ram, con, rel)
.dbfile E:\单片机\源程序\Snail_mkII\STK500_V2\ICC\spi.c
.area text(rom, con, rel)
.dbfile E:\单片机\源程序\Snail_mkII\STK500_V2\ICC\spi.c
.dbfunc e spi_enable _spi_enable fV
; i0 -> R20
.even
_spi_enable::
st -y,R20
.dbline -1
.dbline 48
; /** \file
; <b>SPI</b><br>
; Autor: Matthias Wei遝r<br>
; Copyright 2005: Matthias Wei遝r<br>
; License: QPL (see license.txt)
; <hr>
; */
; #include <iccioavr.h>
; #include <eeprom.h>
; #include <macros.h>
; #include "spi.h"
; #include "tools.h"
; #include "extern_vars.h"
;
; static unsigned char use_sw_spi = 0;
;
;
; #if defined(ATMega8)
; // HW Normal M8 version
; #define MOSI_SET PORTB|=BIT(3);
; #define MOSI_CLEAR PORTB&=~BIT(3);
;
; #define MISO_IN (PINB & BIT(4))
; #define SCK_SET PORTB |= BIT(5);
; #define SCK_CLEAR PORTB &= ~BIT(5);
;
; #define DDR_MOSI_OUT DDRB |= BIT(3);
; #define DDR_MOSI_IN DDRB &= ~BIT(3);NOP();
; #define DDR_SCK_OUT DDRB |= BIT(5);
; #define DDR_SCK_IN DDRB &= ~BIT(5);NOP();
;
; #elif defined(ATMega16) || defined(ATMega32)
; // HW Snail Emluator Kit
; #define MOSI_SET PORTB |= BIT(5);
; #define MOSI_CLEAR PORTB &= ~BIT(5);
;
; #define MISO_IN (PINB & BIT(6))
; #define SCK_SET PORTB |= BIT(7);
; #define SCK_CLEAR PORTB &= ~BIT(7);
;
; #define DDR_MOSI_OUT DDRB |= BIT(5);
; #define DDR_MOSI_IN DDRB &= ~BIT(5);NOP();
; #define DDR_SCK_OUT DDRB |= BIT(7);
; #define DDR_SCK_IN DDRB &= ~BIT(7);NOP();
; #endif
;
; void spi_enable(void)
; {
.dbline 51
; unsigned char i;
;
; R_RES_ON;
ldi R24,-17
ldi R25,-1
in R2,0x18
and R2,R24
out 0x18,R2
.dbline 52
; wait_ms(2);
ldi R16,2
ldi R17,0
xcall _wait_ms
.dbline 56
;
; //PORTB &= BIT3_NEG & BIT5_NEG; //MOSI and SCK low
; //DDRB |= BIT3_POS | BIT5_POS; //MOSI and SCK als Ausgang
; MOSI_CLEAR;SCK_CLEAR;
cbi 0x18,5
.dbline 56
.dbline 56
cbi 0x18,7
.dbline 56
.dbline 57
; DDR_MOSI_OUT;DDR_SCK_OUT
sbi 0x17,5
.dbline 57
.dbline 57
sbi 0x17,7
.dbline 59
;
; if (EEPROMread((int)&eeprom_sck_period) > 64)
ldi R16,<_eeprom_sck_period
ldi R17,>_eeprom_sck_period
xcall _EEPROMread
ldi R24,64
cp R24,R16
brsh L3
X0:
.dbline 60
; {
.dbline 61
; use_sw_spi = 1; //使用模拟SPI
ldi R24,1
sts _use_sw_spi,R24
.dbline 62
; SPCR=0x00;
clr R2
out 0xd,R2
.dbline 63
; }
xjmp L4
L3:
.dbline 65
; else
; {
.dbline 66
; use_sw_spi = 0; //使用硬件SPI
clr R2
sts _use_sw_spi,R2
.dbline 67
; SPCR = 0x51; //SPI Master /16
ldi R24,81
out 0xd,R24
.dbline 68
; spi_set_speed(EEPROMread((int)&eeprom_sck_period));
ldi R16,<_eeprom_sck_period
ldi R17,>_eeprom_sck_period
xcall _EEPROMread
xcall _spi_set_speed
.dbline 69
; }
L4:
.dbline 71
;
; R_RES_OFF;
sbi 0x18,4
.dbline 72
; for (i=0;i<200;i++) asm("nop");
clr R20
xjmp L8
L5:
.dbline 72
nop
L6:
.dbline 72
inc R20
L8:
.dbline 72
cpi R20,200
brlo L5
X1:
.dbline 73
; R_RES_ON;
ldi R24,-17
ldi R25,-1
in R2,0x18
and R2,R24
out 0x18,R2
.dbline 74
; wait_ms(2);
ldi R16,2
ldi R17,0
xcall _wait_ms
.dbline -2
L2:
.dbline 0 ; func end
ld R20,y+
ret
.dbsym r i0 20 c
.dbend
.dbfunc e spi_disable _spi_disable fV
.even
_spi_disable::
.dbline -1
.dbline 79
;
; }
;
; void spi_disable(void)
; {
.dbline 80
; SPCR=0x00; //SPI aus
clr R2
out 0xd,R2
.dbline 82
; //DDRB &= BIT3_NEG & BIT5_NEG; //MOSI und SCK als Eingang (hochohmig)
; DDR_MOSI_IN;DDR_SCK_IN;
cbi 0x17,5
.dbline 82
nop
.dbline 82
.dbline 82
cbi 0x17,7
.dbline 82
nop
.dbline 82
.dbline 83
; R_RES_OFF;
sbi 0x18,4
.dbline -2
L9:
.dbline 0 ; func end
ret
.dbend
.dbfunc e spi_reset _spi_reset fV
.even
_spi_reset::
.dbline -1
.dbline 87
; }
;
; void spi_reset(void)
; {
.dbline 88
; R_RES_OFF;
sbi 0x18,4
.dbline 89
; wait_ms(2);
ldi R16,2
ldi R17,0
xcall _wait_ms
.dbline 90
; R_RES_ON;
ldi R24,-17
ldi R25,-1
in R2,0x18
and R2,R24
out 0x18,R2
.dbline -2
L10:
.dbline 0 ; func end
ret
.dbend
.dbfunc e spi_set_speed _spi_set_speed fV
; s -> R16
.even
_spi_set_speed::
st -y,R20
.dbline -1
.dbline 107
; }
;
; /**
; Stellt die Geschwindigkeit des SPI-Busses ein (bei f=8MHz)
; 0: /2 4MHz --SPI2X
; 1 /4 2MHz
; 2: /8 1MHz --SPI2X
; 3 /16 500kHz
; 4: /32 250kHz --SPI2X
; 5 /64 125kHz
; 6: /128 62,5kHz
;
; weitere Geschwindigkeiten geplant
; -> dann per Software-SPI
; */
; void spi_set_speed(unsigned char s)
; {
.dbline 109
; #if F_CPU <= 8000000
; if ((s==0)||(s==2)||(s==4)) SPSR|=1;
tst R16
breq L15
X2:
cpi R16,2
breq L15
X3:
cpi R16,4
brne L12
X4:
L15:
.dbline 109
sbi 0xe,0
xjmp L13
L12:
.dbline 110
; else SPSR&=0xFE;
in R24,0xe
andi R24,254
out 0xe,R24
L13:
.dbline 112
;
; switch (s)
mov R20,R16
tst R16
breq L19
X5:
cpi R16,1
breq L19
X6:
cpi R16,2
breq L20
X7:
cpi R16,3
breq L20
X8:
cpi R16,4
breq L21
X9:
cpi R16,5
breq L21
X10:
cpi R16,6
breq L22
X11:
xjmp L16
L19:
.dbline 116
; {
; case 0:
; case 1:
; SPCR&=0xFC;
in R24,0xd
andi R24,252
out 0xd,R24
.dbline 117
; break;
xjmp L17
L20:
.dbline 120
; case 2:
; case 3:
; SPCR&=0xFC;
in R24,0xd
andi R24,252
out 0xd,R24
.dbline 121
; SPCR|=0x01;
sbi 0xd,0
.dbline 122
; break;
xjmp L17
L21:
.dbline 125
; case 4:
; case 5:
; SPCR&=0xFC;
in R24,0xd
andi R24,252
out 0xd,R24
.dbline 126
; SPCR|=0x02;
sbi 0xd,1
.dbline 127
; break;
xjmp L17
L22:
.dbline 129
; case 6:
; SPCR|=0x03;
in R24,0xd
ori R24,3
out 0xd,R24
.dbline 130
; break;
xjmp L17
L16:
.dbline 132
; default: //Wenn Wert ung黮tig ganz langsam
; SPCR|=0x03;
in R24,0xd
ori R24,3
out 0xd,R24
.dbline 133
; break;
L17:
.dbline -2
L11:
.dbline 0 ; func end
ld R20,y+
ret
.dbsym r s 16 c
.dbend
.dbfunc e spi_clock_pulse _spi_clock_pulse fV
.even
_spi_clock_pulse::
.dbline -1
.dbline 194
; }
; #else
; /**
; Stellt die Geschwindigkeit des SPI-Busses ein (bei f=16MHz)
; 0: /4 4MHz
; 1 /8 2MHz -SPI2X
; 2: /16 1MHz
; 3 /32 500kHz -SPI2X
; 4: /64 250kHz
; 5 /128 125kHz -SPI2X
; 6: /128 62,5kHz
;
; weitere Geschwindigkeiten geplant
; -> dann per Software-SPI
; */
; if ((s==1)||(s==3))
; {
; SPSR|=1;
; }
; else
; {
; SPSR&=0xFE;
; }
;
; switch (s)
; {
; case 0:
; SPCR&=0xFC;
; break;
; case 1:
; SPCR&=0xFC;
; SPCR|=0x01;
; break;
; case 2:
; SPCR&=0xFC;
; SPCR|=0x01;
; break;
; case 3:
; SPCR&=0xFC;
; SPCR|=0x02;
; break;
; case 4:
; SPCR&=0xFC;
; SPCR|=0x02;
; break;
; case 5:
; SPCR|=0x03;
; break;
; case 6:
; SPCR|=0x03;
; break;
; default: //Wenn Wert ung黮tig ganz langsam
; SPCR|=0x03;
; break;
; }
;
; #endif
; }
;
; void spi_clock_pulse(void) //模拟SPI时钟
; {
.dbline 195
; if (!use_sw_spi)
lds R2,_use_sw_spi
tst R2
brne L24
X12:
.dbline 196
; {
.dbline 197
; SPCR&=BIT6_NEG; //SPI 使能关闭
ldi R24,-65
ldi R25,-1
in R2,0xd
and R2,R24
out 0xd,R2
.dbline 198
; }
L24:
.dbline 200
;
; SCK_SET
sbi 0x18,7
.dbline 202
; //PORTB|=BIT5_POS; //SPI SCK impuls
; wait_ms(2);
ldi R16,2
ldi R17,0
xcall _wait_ms
.dbline 204
; //PORTB&=BIT5_NEG;
; SCK_CLEAR
cbi 0x18,7
.dbline 206
;
; if (!use_sw_spi)
lds R2,_use_sw_spi
tst R2
brne L26
X13:
.dbline 207
; {
.dbline 208
; SPCR|=BIT6_POS; //SPI 使能
sbi 0xd,6
.dbline 209
; }
L26:
.dbline -2
L23:
.dbline 0 ; func end
ret
.dbend
.dbfunc e spi_transfer_8 _spi_transfer_8 fc
; j -> y+0
; i0 -> R22
; result0 -> R20
; d -> R16
.even
_spi_transfer_8::
st -y,R20
st -y,R22
sbiw R28,2
.dbline -1
.dbline 221
; }
;
; /**
; Does a 8 bit transfer over the SPI-Interface
; and gives back the byte received
;
; @param d the byte to be transmitted
;
; @return the byte received
; */
; unsigned char spi_transfer_8(unsigned char d)
; {
.dbline 222
; if (!use_sw_spi)
lds R2,_use_sw_spi
tst R2
brne L29
X14:
.dbline 223
; {
.dbline 224
; SPDR=d;
out 0xf,R16
L31:
.dbline 225
; while (!(SPSR&0x80));
L32:
.dbline 225
in R24,0xe
andi R24,128
breq L31
X15:
.dbline 227
;
; return SPDR;
in R16,0xf
xjmp L28
L29:
.dbline 230
; }
; else
; {
.dbline 231
; unsigned char result=0,i;
clr R20
.dbline 234
; volatile unsigned int j;
;
; for (i = 0; i < 8; i++)
clr R22
xjmp L37
L34:
.dbline 235
; {
.dbline 236
; if (d&0x80)
mov R24,R16
andi R24,128
breq L38
X16:
.dbline 237
; {
.dbline 238
; MOSI_SET;
sbi 0x18,5
.dbline 238
.dbline 239
; }
xjmp L39
L38:
.dbline 241
; else
; {
.dbline 242
; MOSI_CLEAR;
cbi 0x18,5
.dbline 242
.dbline 243
; }
L39:
.dbline 244
; d<<=1;
lsl R16
.dbline 245
; result<<=1;
lsl R20
.dbline 248
;
; #if F_CPU < 8000000
; for (j = 0; j < 18; j++) asm ("nop");
clr R2
clr R3
std y+1,R3
std y+0,R2
xjmp L43
L40:
.dbline 248
nop
L41:
.dbline 248
ldd R24,y+0
ldd R25,y+1
adiw R24,1
std y+1,R25
std y+0,R24
L43:
.dbline 248
ldd R24,y+0
ldd R25,y+1
cpi R24,18
ldi R30,0
cpc R25,R30
brlo L40
X17:
.dbline 252
; #else
; for (j = 0; j < 36; j++) asm ("nop");
; #endif
; SCK_SET
sbi 0x18,7
.dbline 254
; //PORTB|=BIT5_POS; //sck
; if (MISO_IN)
sbis 0x16,6
rjmp L44
X18:
.dbline 255
; {
.dbline 256
; result|=1;
ori R20,1
.dbline 257
; }
L44:
.dbline 259
; #if F_CPU < 8000000
; for (j = 0; j < 18; j++) asm ("nop");
clr R2
clr R3
std y+1,R3
std y+0,R2
xjmp L49
L46:
.dbline 259
nop
L47:
.dbline 259
ldd R24,y+0
ldd R25,y+1
adiw R24,1
std y+1,R25
std y+0,R24
L49:
.dbline 259
ldd R24,y+0
ldd R25,y+1
cpi R24,18
ldi R30,0
cpc R25,R30
brlo L46
X19:
.dbline 264
; #else
; for (j = 0; j < 36; j++) asm ("nop");
; #endif
; //PORTB&=BIT5_NEG;
; SCK_CLEAR
cbi 0x18,7
.dbline 265
; }
L35:
.dbline 234
inc R22
L37:
.dbline 234
cpi R22,8
brlo L34
X20:
.dbline 266
; MOSI_CLEAR;
cbi 0x18,5
.dbline 266
.dbline 268
;
; return result;
mov R16,R20
.dbline -2
L28:
.dbline 0 ; func end
adiw R28,2
ld R22,y+
ld R20,y+
ret
.dbsym l j 0 i
.dbsym r i0 22 c
.dbsym r result0 20 c
.dbsym r d 16 c
.dbend
.dbfunc e spi_transfer_16 _spi_transfer_16 fc
; d -> R20,R21
.even
_spi_transfer_16::
st -y,R20
st -y,R21
movw R20,R16
.dbline -1
.dbline 281
; }
; }
;
; /**
; Does a 16 bit transfer over the SPI-Interface
; and gives back the last byte received
;
; @param d the int to be transmitted
;
; @return the last byte received
; */
; unsigned char spi_transfer_16(unsigned int d)
; {
.dbline 282
; spi_transfer_8((d>>8)&0xFF);
movw R16,R20
mov R16,R17
clr R17
andi R17,0
xcall _spi_transfer_8
.dbline 283
; return spi_transfer_8(d&0xFF);
movw R16,R20
andi R17,0
xcall _spi_transfer_8
.dbline -2
L50:
.dbline 0 ; func end
ld R21,y+
ld R20,y+
ret
.dbsym r d 20 i
.dbend
.dbfunc e spi_transfer_32 _spi_transfer_32 fc
; d -> y+0
.even
_spi_transfer_32::
xcall push_arg4
.dbline -1
.dbline 295
; }
;
; /**
; Does a 32 bit transfer over the SPI-Interface
; and gives back the last byte received
;
; @param d the long to be transmitted
;
; @return the last byte received
; */
; unsigned char spi_transfer_32(unsigned long d)
; {
.dbline 296
; spi_transfer_8((d>>24)&0xFF);
ldi R24,24
ldi R25,0
ldd R16,y+0
ldd R17,y+1
ldd R18,y+2
ldd R19,y+3
st -y,R24
xcall lsr32
movw R2,R16
movw R4,R18
ldi R24,255
ldi R25,0
ldi R26,0
ldi R27,0
and R2,R24
and R3,R25
and R4,R26
and R5,R27
mov R16,R2
xcall _spi_transfer_8
.dbline 297
; spi_transfer_8((d>>16)&0xFF);
ldi R24,255
ldi R25,0
ldi R26,0
ldi R27,0
ldd R2,y+0
ldd R3,y+1
ldd R4,y+2
ldd R5,y+3
movw R2,R4
clr R4
clr R5
and R2,R24
and R3,R25
and R4,R26
and R5,R27
mov R16,R2
xcall _spi_transfer_8
.dbline 298
; spi_transfer_8((d>>8)&0xFF);
ldi R24,8
ldi R25,0
ldd R16,y+0
ldd R17,y+1
ldd R18,y+2
ldd R19,y+3
st -y,R24
xcall lsr32
movw R2,R16
movw R4,R18
ldi R24,255
ldi R25,0
ldi R26,0
ldi R27,0
and R2,R24
and R3,R25
and R4,R26
and R5,R27
mov R16,R2
xcall _spi_transfer_8
.dbline 299
; return spi_transfer_8(d&0xFF);
ldi R24,255
ldi R25,0
ldi R26,0
ldi R27,0
ldd R2,y+0
ldd R3,y+1
ldd R4,y+2
ldd R5,y+3
and R2,R24
and R3,R25
and R4,R26
and R5,R27
mov R16,R2
xcall _spi_transfer_8
.dbline -2
L51:
.dbline 0 ; func end
adiw R28,4
ret
.dbsym l d 0 l
.dbend
; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -