📄 sdcmd.s
字号:
.module sdcmd.c
.area text(rom, con, rel)
.dbfile D:\new_sd\SD\SD\sdcmd.c
.dbfunc e SD_SendCmd _SD_SendCmd fc
; rlen -> y+4
; tmp -> R10
; i -> y+0
; resp -> R12,R13
; resptype -> y+22
; param -> y+20
; cmd -> y+18
.even
_SD_SendCmd::
xcall push_arg4
xcall push_gset5
sbiw R28,8
ldd R12,y+24
ldd R13,y+25
.dbline -1
.dbline 17
; /*****************************************************************************************************
; ** Descriptions: sd 卡驱动软件包: SD卡物理层 ---- SD卡SPI模式支持的命令
; ********************************************************************************************************/
; #include "D:\new_sd\define.h"
;
;
; /********************************************************************************************************************
; ** 函数名称: INT8U SD_SendCmd() Name: INT8U SD_SendCmd()
; ** 功能描述: 向卡发送命令,并取得响应 Function: send command to the card,and get a response
; ** 输 入: INT8U cmd : 命令字 Input: INT8U cmd : command byte
; INT8U *param : 命令参数,长度为4字节 INT8U *param : command parameter,length is 4 bytes
; INT8U resptype : 响应类型 INT8U resptype: response type
; INT8U *resp : 响应,长度为1-5字节 INT8U *resp : response,length is 1-5 bytes
; ** 输 出: 0: 正确 >0: 错误码 Output: 0: right >0: error code
; ********************************************************************************************************************/
; uint8 SD_SendCmd(uint8 cmd, uint8 *param, uint8 resptype, uint8 *resp)
; {
.dbline 21
; int32 i,rlen; //所有SD卡命令都是6字节长
; uint8 tmp;
;
; SPI_CS_Assert(); //片选SPI从机
xcall _SPI_CS_Assert
.dbline 23
;
; SPI_SendByte((cmd & 0x3F) | 0x40); /* 发送命令头和命令字 send command header and word */
ldd R16,y+18
andi R16,63
ori R16,64
xcall _SPI_SendByte
.dbline 25
; //起始位为0(bit47),传输位为1(bit46)
; for (i = 3; i >= 0; i--)
ldi R20,3
ldi R21,0
ldi R22,0
ldi R23,0
movw R30,R28
std z+0,R20
std z+1,R21
std z+2,R22
std z+3,R23
L2:
.dbline 26
movw R30,R28
push R26
push R27
ldd R26,z+0
ldd R27,z+1
movw R30,R26
pop R27
pop R26
ldd R0,y+20
ldd R1,y+21
add R30,R0
adc R31,R1
ldd R16,z+0
xcall _SPI_SendByte
L3:
.dbline 25
ldi R20,1
ldi R21,0
ldi R22,0
ldi R23,0
movw R30,R28
ldd R2,z+0
ldd R3,z+1
ldd R4,z+2
ldd R5,z+3
sub R2,R20
sbc R3,R21
sbc R4,R22
sbc R5,R23
movw R30,R28
std z+0,R2
std z+1,R3
std z+2,R4
std z+3,R5
.dbline 25
ldi R20,0
ldi R21,0
ldi R22,0
ldi R23,0
movw R30,R28
ldd R2,z+0
ldd R3,z+1
ldd R4,z+2
ldd R5,z+3
cp R2,R20
cpc R3,R21
cpc R4,R22
cpc R5,R23
brlt X2
xjmp L2
X2:
.dbline 29
; SPI_SendByte(param[i]); /* 发送参数 send parameters */
;
; #if SD_CRC_EN
; tmp = SD_GetCmdByte6((cmd & 0x3F) | 0x40, param);
ldd R18,y+20
ldd R19,y+21
ldd R16,y+18
andi R16,63
ori R16,64
xcall _SD_GetCmdByte6
mov R10,R16
.dbline 30
; SPI_SendByte(tmp);
xcall _SPI_SendByte
.dbline 35
; #else
; SPI_SendByte(0x95); /* CRC校验码,只用于第1个命令 CRC,only used for the first command */
; #endif
;
; rlen = 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
.dbline 36
; switch (resptype) /* 根据不同的命令,得到不同的响应长度 */
ldd R14,y+22
clr R15
movw R24,R14
cpi R24,1
ldi R30,0
cpc R25,R30
breq L9
cpi R24,2
ldi R30,0
cpc R25,R30
breq L9
cpi R24,3
ldi R30,0
cpc R25,R30
breq L10
cpi R24,4
ldi R30,0
cpc R25,R30
breq L11
xjmp L6
X0:
.dbline 37
; { /* according various command,get the various response length */
L9:
.dbline 39
; case R1:
; case R1B: rlen = 1; break;
ldi R20,1
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
.dbline 39
xjmp L7
L10:
.dbline 41
;
; case R2: rlen = 2; break;
ldi R20,2
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
.dbline 41
xjmp L7
L11:
.dbline 43
;
; case R3: rlen = 5; break;
ldi R20,5
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
.dbline 43
xjmp L7
L6:
.dbline 45
;
; default: SPI_SendByte(0xFF);
ldi R16,255
xcall _SPI_SendByte
.dbline 46
; SPI_CS_Deassert();
xcall _SPI_CS_Deassert
.dbline 47
; return SD_ERR_CMD_RESPTYPE; /* 返回命令响应类型错误 return error of command response type */
ldi R16,16
xjmp L1
X1:
.dbline 48
; break;
L7:
.dbline 51
; }
;
; i = 0;
ldi R20,0
ldi R21,0
ldi R22,0
ldi R23,0
movw R30,R28
std z+0,R20
std z+1,R21
std z+2,R22
std z+3,R23
L12:
.dbline 53
; do /* 等待响应,响应的开始位为0 */
; { /* Wait for a response,a response is a start bit(zero) */
.dbline 54
; tmp = SPI_RecByte();
xcall _SPI_RecByte
mov R10,R16
.dbline 55
; i++;
ldi R20,1
ldi R21,0
ldi R22,0
ldi R23,0
movw R30,R28
ldd R2,z+0
ldd R3,z+1
ldd R4,z+2
ldd R5,z+3
add R2,R20
adc R3,R21
adc R4,R22
adc R5,R23
movw R30,R28
std z+0,R2
std z+1,R3
std z+2,R4
std z+3,R5
.dbline 56
; }
L13:
.dbline 57
; while (((tmp & 0x80) != 0) && (i < SD_CMD_TIMEOUT));
sbrs R10,7
rjmp L15
ldi R20,100
ldi R21,0
ldi R22,0
ldi R23,0
movw R30,R28
ldd R2,z+0
ldd R3,z+1
ldd R4,z+2
ldd R5,z+3
cp R2,R20
cpc R3,R21
cpc R4,R22
cpc R5,R23
brlt L12
L15:
.dbline 59
;
; if (i >= SD_CMD_TIMEOUT)
ldi R20,100
ldi R21,0
ldi R22,0
ldi R23,0
movw R30,R28
ldd R2,z+0
ldd R3,z+1
ldd R4,z+2
ldd R5,z+3
cp R2,R20
cpc R3,R21
cpc R4,R22
cpc R5,R23
brlt L16
.dbline 60
; {
.dbline 61
; SPI_CS_Deassert();
xcall _SPI_CS_Deassert
.dbline 62
; return SD_ERR_CMD_TIMEOUT; /* 返回命令超时 return response timeout of command */
ldi R16,17
xjmp L1
L16:
.dbline 65
; }
;
; for (i = rlen - 1; i >= 0; 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
sub R2,R20
sbc R3,R21
sbc R4,R22
sbc R5,R23
movw R30,R28
std z+0,R2
std z+1,R3
std z+2,R4
std z+3,R5
xjmp L21
L18:
.dbline 66
.dbline 67
movw R30,R28
push R26
push R27
ldd R26,z+0
ldd R27,z+1
movw R30,R26
pop R27
pop R26
add R30,R12
adc R31,R13
std z+0,R10
.dbline 68
xcall _SPI_RecByte
mov R10,R16
.dbline 69
L19:
.dbline 65
ldi R20,1
ldi R21,0
ldi R22,0
ldi R23,0
movw R30,R28
ldd R2,z+0
ldd R3,z+1
ldd R4,z+2
ldd R5,z+3
sub R2,R20
sbc R3,R21
sbc R4,R22
sbc R5,R23
movw R30,R28
std z+0,R2
std z+1,R3
std z+2,R4
std z+3,R5
L21:
.dbline 65
ldi R20,0
ldi R21,0
ldi R22,0
ldi R23,0
movw R30,R28
ldd R2,z+0
ldd R3,z+1
ldd R4,z+2
ldd R5,z+3
cp R2,R20
cpc R3,R21
cpc R4,R22
cpc R5,R23
brlt X3
xjmp L18
X3:
.dbline 71
; {
; resp[i] = tmp;
; tmp = SPI_RecByte(); /* 循环的最后发送8clock at the last recycle,clock out 8 clock */
; }
;
; SPI_CS_Deassert();
xcall _SPI_CS_Deassert
.dbline 72
; return SD_NO_ERR; /* 返回执行成功 return perform sucessfully */
clr R16
.dbline -2
L1:
adiw R28,8
xcall pop_gset5
adiw R28,4
.dbline 0 ; func end
ret
.dbsym l rlen 4 L
.dbsym r tmp 10 c
.dbsym l i 0 L
.dbsym r resp 12 pc
.dbsym l resptype 22 c
.dbsym l param 20 pc
.dbsym l cmd 18 c
.dbend
.dbfunc e SD_PackParam _SD_PackParam fV
; value -> y+2
; parameter -> R20,R21
.even
_SD_PackParam::
st -y,r19
st -y,r18
xcall push_gset1
movw R20,R16
.dbline -1
.dbline 83
; }
;
; /********************************************************************************************************************
; ** 函数名称: void SD_PackParam() Name: void SD_PackParam()
; ** 功能描述: 将32位的参数转为字节形式 Function: change 32bit parameter to bytes form
; ** 输 入: INT8U *parameter: 字节参数缓冲区 Input: INT8U *parameter: the buffer of bytes parameter
; INT32U value : 32位参数 INT32U value : 32bit parameter
; ** 输 出: 无 Output: NULL
; *********************************************************************************************************************/
; void SD_PackParam(uint8 *parameter, uint32 value)
; {
.dbline 84
; parameter[3] = (uint8)(value >> 24);
ldi R24,24
ldi R25,0
movw R30,R28
ldd R2,z+2
ldd R3,z+3
ldd R4,z+4
ldd R5,z+5
st -y,R24
movw R16,R2
movw R18,R4
xcall lsr32
movw R30,R20
std z+3,R16
.dbline 85
; parameter[2] = (uint8)(value >> 16);
movw R30,R28
ldd R2,z+2
ldd R3,z+3
ldd R4,z+4
ldd R5,z+5
movw R2,R4
clr R4
clr R5
movw R30,R20
std z+2,R2
.dbline 86
; parameter[1] = (uint8)(value >> 8);
ldi R24,8
ldi R25,0
movw R30,R28
ldd R2,z+2
ldd R3,z+3
ldd R4,z+4
ldd R5,z+5
st -y,R24
movw R16,R2
movw R18,R4
xcall lsr32
movw R30,R20
std z+1,R16
.dbline 87
; parameter[0] = (uint8)(value);
movw R30,R28
ldd R2,z+2
ldd R3,z+3
ldd R4,z+4
ldd R5,z+5
movw R30,R20
std z+0,R2
.dbline -2
L22:
xcall pop_gset1
adiw R28,2
.dbline 0 ; func end
ret
.dbsym l value 2 l
.dbsym r parameter 20 pc
.dbend
.dbfunc e SD_BlockCommand _SD_BlockCommand fc
; resp -> y+8
; param -> y+4
; ret -> R20
; parameter -> y+13
; resptype -> R22
; cmd -> R20
.even
_SD_BlockCommand::
xcall push_gset2
mov R22,R18
mov R20,R16
sbiw R28,9
.dbline -1
.dbline 99
; }
;
; /********************************************************************************************************************
; ** 函数名称: INT8U SD_BlockCommand() Name: INT8U SD_BlockCommand()
; ** 功能描述: 块命令 Function: command about block operation
; ** 输 入: INT8U cmd : 命令字 Input: INT8U cmd : command byte
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -