sd_drive.s
来自「Atmega64单片机程序(完整工程)」· S 代码 · 共 1,636 行 · 第 1/3 页
S
1,636 行
sbrc R3,7
com R4
clr R5
sbrc R4,7
com R5
ldd R24,y+10
clr R25
andi R24,63
andi R25,0
movw R6,R24
clr R8
sbrc R7,7
com R8
clr R9
sbrc R8,7
com R9
lsl R6
rol R7
rol R8
rol R9
add R6,R2
adc R7,R3
adc R8,R4
adc R9,R5
ldi R20,1
ldi R21,0
ldi R22,0
ldi R23,0
add R6,R20
adc R7,R21
adc R8,R22
adc R9,R23
sts _sds+8+1,R7
sts _sds+8,R6
sts _sds+8+2+1,R9
sts _sds+8+2,R8
; /* SD (SECTOR_SIZE + 1) */
;
; return SD_NO_ERR ;/* 返回执行成功 return perform sucessfully */
clr R16
L62:
adiw R28,20
xcall pop_gset3
.dbline 0 ; func end
ret
; time_u -> R14
; fator -> R10
; time_v -> R12
; tmp -> y+0
; csdbuf -> y+14
.even
_SD_CalTimeout::
st -y,r17
st -y,r16
xcall push_gset5
sbiw R28,4
; }
;
; /*******************************************************************************
; ** 函数名称: INT8U SD_CalTimeout()
; ** 功能描述: 计算读/写/擦超时时间
; ** 输 入: INT8U cardtype: 卡类型
; INT8U *csdbuf : CSD寄存器内容
; ** 输 出: 0: 正确 >0: 错误码
; *******************************************************************************/
; void SD_CalTimeout(INT8U *csdbuf)
; {
; INT32U tmp ;
; INT8U time_u,time_v,fator ;
;
; sds.timeout_read=READ_TIMEOUT_100MS ;/* 默认读超时为100ms */
ldi R20,160
ldi R21,134
ldi R22,1
ldi R23,0
sts _sds+12+1,R21
sts _sds+12,R20
sts _sds+12+2+1,R23
sts _sds+12+2,R22
; sds.timeout_write=WRITE_TIMEOUT_250MS ;/* 默认写超时为250ms */
ldi R20,144
ldi R21,208
ldi R22,3
ldi R23,0
sts _sds+16+1,R21
sts _sds+16,R20
sts _sds+16+2+1,R23
sts _sds+16+2,R22
; sds.timeout_erase=WRITE_TIMEOUT_250MS ;
ldi R20,144
ldi R21,208
ldi R22,3
ldi R23,0
sts _sds+20+1,R21
sts _sds+20,R20
sts _sds+20+2+1,R23
sts _sds+20+2,R22
;
; time_u=(csdbuf[TAAC_POS]&TAAC_MSK);/* 读超时时间单位 read timeout unit */
ldd R30,y+14
ldd R31,y+15
ldd R24,z+1
andi R24,7
mov R14,R24
; time_v=(csdbuf[TAAC_POS]&NSAC_MSK)>>3 ;/* 读超时时间值 read timeout value */
ldd R30,y+14
ldd R31,y+15
ldd R24,z+1
andi R24,120
mov R12,R24
lsr R12
lsr R12
lsr R12
; fator=(csdbuf[R2WFACTOR_POS]&R2WFACTOR_MSK)>>2 ;/* 写超时时间因数 write timeout factor */
ldd R30,y+14
ldd R31,y+15
ldd R24,z+12
andi R24,28
mov R10,R24
lsr R10
lsr R10
;
; if(time_v==0)
tst R12
brne L79
; return ;
xjmp L75
L79:
; if(fator>=6)
mov R24,R10
cpi R24,6
brlo L81
; return ;
xjmp L75
L81:
;
; tmp=SPI_CLOCK*time_value[time_v]/10/time_unit[time_u];/* TACC * f (单位 unit: clock) */
ldi R24,<_time_value
ldi R25,>_time_value
mov R30,R12
clr R31
add R30,R24
adc R31,R25
lpm R2,Z
clr R3
clr R4
clr R5
ldi R20,0
ldi R21,18
ldi R22,122
ldi R23,0
st -y,R5
st -y,R4
st -y,R3
st -y,R2
movw R16,R20
movw R18,R22
xcall empy32s
ldi R20,10
ldi R21,0
ldi R22,0
ldi R23,0
st -y,R23
st -y,R22
st -y,R21
st -y,R20
xcall div32s
movw R2,R16
movw R4,R18
ldi R24,4
mul R24,R14
movw R16,R0
ldi R24,<_time_unit
ldi R25,>_time_unit
add R16,R24
adc R17,R25
xcall lpm32
st -y,R19
st -y,R18
st -y,R17
st -y,R16
movw R16,R2
movw R18,R4
xcall div32u
movw R30,R28
std z+0,R16
std z+1,R17
std z+2,R18
std z+3,R19
; tmp=tmp+(INT32U)csdbuf[NSAC_POS]*100 ;/* TACC * f + NSAC * 100 (单位 unit: clock) */
ldd R30,y+14
ldd R31,y+15
ldd R2,z+2
clr R3
clr R4
clr R5
ldi R20,100
ldi R21,0
ldi R22,0
ldi R23,0
st -y,R5
st -y,R4
st -y,R3
st -y,R2
movw R16,R20
movw R18,R22
xcall empy32u
movw R30,R28
ldd R2,z+0
ldd R3,z+1
ldd R4,z+2
ldd R5,z+3
add R2,R16
adc R3,R17
adc R4,R18
adc R5,R19
movw R30,R28
std z+0,R2
std z+1,R3
std z+2,R4
std z+3,R5
;
; /* 计算得到的超时值 the timeout value of being calculated */
; sds.timeout_read=tmp ;
movw R30,R28
ldd R2,z+0
ldd R3,z+1
ldd R4,z+2
ldd R5,z+3
sts _sds+12+1,R3
sts _sds+12,R2
sts _sds+12+2+1,R5
sts _sds+12+2,R4
; sds.timeout_write=tmp*r2w_fator[fator];
ldi R24,<_r2w_fator
ldi R25,>_r2w_fator
mov R30,R10
clr R31
add R30,R24
adc R31,R25
lpm R2,Z
clr R3
clr R4
clr R5
movw R30,R28
ldd R6,z+0
ldd R7,z+1
ldd R8,z+2
ldd R9,z+3
st -y,R5
st -y,R4
st -y,R3
st -y,R2
movw R16,R6
movw R18,R8
xcall empy32u
sts _sds+16+1,R17
sts _sds+16,R16
sts _sds+16+2+1,R19
sts _sds+16+2,R18
; /* (TACC * f + NSAC * 100) * R2WFACTOR (单位 unit:clock)*/
;
; sds.timeout_read=sds.timeout_read*100/8 ;/* 实际值为计算值的100倍 */
lds R4,_sds+12+2
lds R5,_sds+12+2+1
lds R2,_sds+12
lds R3,_sds+12+1
ldi R20,100
ldi R21,0
ldi R22,0
ldi R23,0
st -y,R5
st -y,R4
st -y,R3
st -y,R2
movw R16,R20
movw R18,R22
xcall empy32u
ldi R24,3
ldi R25,0
st -y,R24
xcall lsr32
sts _sds+12+1,R17
sts _sds+12,R16
sts _sds+12+2+1,R19
sts _sds+12+2,R18
; sds.timeout_write=sds.timeout_write*100/8 ;
lds R4,_sds+16+2
lds R5,_sds+16+2+1
lds R2,_sds+16
lds R3,_sds+16+1
ldi R20,100
ldi R21,0
ldi R22,0
ldi R23,0
st -y,R5
st -y,R4
st -y,R3
st -y,R2
movw R16,R20
movw R18,R22
xcall empy32u
ldi R24,3
ldi R25,0
st -y,R24
xcall lsr32
sts _sds+16+1,R17
sts _sds+16,R16
sts _sds+16+2+1,R19
sts _sds+16+2,R18
;
; /* 取计算值与默认值中的最小值 */
; if(sds.timeout_read>READ_TIMEOUT_100MS)
ldi R20,160
ldi R21,134
ldi R22,1
ldi R23,0
lds R4,_sds+12+2
lds R5,_sds+12+2+1
lds R2,_sds+12
lds R3,_sds+12+1
cp R20,R2
cpc R21,R3
cpc R22,R4
cpc R23,R5
brsh L89
; sds.timeout_read=READ_TIMEOUT_100MS ;
ldi R20,160
ldi R21,134
ldi R22,1
ldi R23,0
sts _sds+12+1,R21
sts _sds+12,R20
sts _sds+12+2+1,R23
sts _sds+12+2,R22
L89:
;
; if(sds.timeout_write>WRITE_TIMEOUT_250MS)
ldi R20,144
ldi R21,208
ldi R22,3
ldi R23,0
lds R4,_sds+16+2
lds R5,_sds+16+2+1
lds R2,_sds+16
lds R3,_sds+16+1
cp R20,R2
cpc R21,R3
cpc R22,R4
cpc R23,R5
brsh L93
; sds.timeout_write=WRITE_TIMEOUT_250MS ;
ldi R20,144
ldi R21,208
ldi R22,3
ldi R23,0
sts _sds+16+1,R21
sts _sds+16,R20
sts _sds+16+2+1,R23
sts _sds+16+2,R22
L93:
;
; sds.timeout_erase=sds.timeout_write ;
lds R4,_sds+16+2
lds R5,_sds+16+2+1
lds R2,_sds+16
lds R3,_sds+16+1
sts _sds+20+1,R3
sts _sds+20,R2
sts _sds+20+2+1,R5
sts _sds+20+2,R4
L75:
adiw R28,4
xcall pop_gset5
adiw R28,2
.dbline 0 ; func end
ret
.area lit(rom, con, rel)
L100:
.byte 0,0
.byte 0,0
.area text(rom, con, rel)
; param -> y+13
; resp -> y+8
; i -> y+4
; ret -> R10
.even
_SD_ActiveInit::
xcall push_gset3
sbiw R28,17
; }
;
; /*******************************************************************************
; ** 函数名称: INT8U SD_CalTimeout()
; ** 功能描述: 计算读/写/擦超时时间
; ** 输 入: INT8U *cardtype: 卡类型接收缓冲
; ** 输 出: 0: 正确 >0: 错误码
; ** 函数说明: 该命令不断重复发送到SD卡,直到响应R1的Bit0(Idle)位为0
; 当响应的Idle位为0时,SD卡就完全进入SPI模式了。当然重复发送命令CMD1
; 是有次数限制的,最大次数为宏定义SD_IDLE_WAIT_MAX.
; *******************************************************************************/
; INT8U SD_ActiveInit(void)
; {
; INT8U param[4]={0,0,0,0},resp[5],ret ;
ldi R24,<L100
ldi R25,>L100
movw R30,R28
adiw R30,13
ldi R16,4
ldi R17,0
st -y,R31
st -y,R30
st -y,R25
st -y,R24
xcall asgncblk
; INT32U i=0 ;
ldi R20,0
ldi R21,0
ldi R22,0
ldi R23,0
movw R30,R28
std z+4,R20
std z+5,R21
std z+6,R22
std z+7,R23
L101:
;
; do
; {
; /* 发出CMD1, 查询卡的状态, send CMD1 to poll card status */
; ret=SD_SendCmd(CMD1,param,CMD1_R,resp);
movw R24,R28
adiw R24,8
std y+3,R25
std y+2,R24
ldi R24,1
std y+0,R24
movw R18,R28
subi R18,243 ; offset = 13
sbci R19,255
ldi R16,1
xcall _SD_SendCmd
mov R10,R16
; if(ret!=SD_NO_ERR)
tst R16
breq L104
; return ret ;
xjmp L99
L104:
; i++;
ldi R20,1
ldi R21,0
ldi R22,0
ldi R23,0
movw R30,R28
ldd R2,z+4
ldd R3,z+5
ldd R4,z+6
ldd R5,z+7
add R2,R20
adc R3,R21
adc R4,R22
adc R5,R23
movw R30,R28
std z+4,R2
std z+5,R3
std z+6,R4
std z+7,R5
; }
L102:
; while(((resp[0]&MSK_IDLE)==MSK_IDLE)&&(i<SD_IDLE_WAIT_MAX));
ldd R24,y+8
andi R24,1
cpi R24,1
brne L106
ldi R20,232
ldi R21,3
ldi R22,0
ldi R23,0
movw R30,R28
ldd R2,z+4
ldd R3,z+5
ldd R4,z+6
ldd R5,z+7
cp R2,R20
cpc R3,R21
cpc R4,R22
cpc R5,R23
brsh X2
xjmp L101
X2:
L106:
; /* 如果响应R1的最低位Idle位为1,则继续循环 */
;
; if(i>=SD_IDLE_WAIT_MAX)
ldi R20,232
ldi R21,3
ldi R22,0
ldi R23,0
movw R30,R28
ldd R2,z+4
ldd R3,z+5
ldd R4,z+6
ldd R5,z+7
cp R2,R20
cpc R3,R21
cpc R4,R22
cpc R5,R23
brlo L107
; return SD_ERR_TIMEOUT_WAITIDLE ;
ldi R16,52
xjmp L99
L107:
; /* 超时,返回错误 time out,return error */
;
; return SD_NO_ERR ;
clr R16
L99:
adiw R28,17
xcall pop_gset3
.dbline 0 ; func end
ret
.even
_SD_GetSDVer::
; }
;
; /*******************************************************************************
; ** 函数名称: INT16U SD_GetSDVer()
; ** 功能描述: 得到SD的版本号
; ** 输 入: 无
; ** 输 出: 版本号
; *******************************************************************************/
; INT16U SD_GetSDVer(void)
; {
; return 0x0100 ;
ldi R16,256
ldi R17,1
L109:
.dbline 0 ; func end
ret
.area bss(ram, con, rel)
_sds::
.blkb 24
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?