sd_drive.s

来自「Atmega64单片机程序(完整工程)」· S 代码 · 共 1,636 行 · 第 1/3 页

S
1,636
字号
;        return SD_ERR_TIMEOUT_WRITE ;
;     
;     ret=SD_GetNumWRBlcoks(&i);
;     /* 读正确写入的块数 read the blocks that be written correctly */
;     if(ret!=SD_NO_ERR)
;        return ret ;
;     
;     if(i!=blocknum)
;        return SD_ERR_WRITE_BLKNUMS ;
;     /* 正确写入块数错误 the blocks that be written correctly is error */
;     
;     return SD_NO_ERR ;
;     /* 返回写入成功 return write sucessfully */
; }
; #endif 
; 
; /*******************************************************************************
; ** 函数名称: INT8U SD_EraseBlock()					
; ** 功能描述: 擦除SD卡中的块							
; ** 输   入: INT32U startaddr: 起始地址				
; 	     INT32U endaddr  : 终止地址				
; ** 输   出: 0:   正确    >0:   错误码		  		
; ** 注    意: startaddr 和 blocknum 建议为sds.erase_uint的整数倍, 
;              因为有的卡只能以sds.erase_uint为单位进行擦除
; *******************************************************************************/
; #if SD_EraseBlock_EN 
; INT8U SD_EraseBlock(INT32U startaddr,INT32U blocknum)
; {
;     INT32S tmp ;
;     INT8U ret ;
;     
;     if((startaddr+blocknum)>sds.block_num)
	movw R30,R28
	ldd R2,z+14
	ldd R3,z+15
	ldd R4,z+16
	ldd R5,z+17
	movw R30,R28
	ldd R6,z+10
	ldd R7,z+11
	ldd R8,z+12
	ldd R9,z+13
	add R6,R2
	adc R7,R3
	adc R8,R4
	adc R9,R5
	lds R4,_sds+2
	lds R5,_sds+2+1
	lds R2,_sds
	lds R3,_sds+1
	cp R2,R6
	cpc R3,R7
	cpc R4,R8
	cpc R5,R9
	brsh L36
;         return SD_ERR_OVER_CARDRANGE ;
	ldi R16,5
	xjmp L35
L36:
;     /* 操作超出卡容量范围 operate over the card range */
;     
;     if(SD_ChkCardWP()==1)
	xcall _SD_ChkCardWP
	cpi R16,1
	brne L38
;         return SD_ERR_WRITE_PROTECT ;
	ldi R16,66
	xjmp L35
L38:
;     /* 卡有写保护 */
;     
;     tmp=blocknum-sds.erase_unit ;
	lds R4,_sds+8+2
	lds R5,_sds+8+2+1
	lds R2,_sds+8
	lds R3,_sds+8+1
	movw R30,R28
	ldd R6,z+14
	ldd R7,z+15
	ldd R8,z+16
	ldd R9,z+17
	sub R6,R2
	sbc R7,R3
	sbc R8,R4
	sbc R9,R5
	movw R30,R28
	std z+0,R6
	std z+1,R7
	std z+2,R8
	std z+3,R9
	xjmp L42
L41:
;     /* 每次擦除扇区大小 once erase is sector size */
;     while(tmp>=0)
;     {
;         ret=SD_EraseStartBlock(startaddr);
	movw R30,R28
	ldd R16,z+10
	ldd R17,z+11
	ldd R18,z+12
	ldd R19,z+13
	xcall _SD_EraseStartBlock
	mov R10,R16
;         /* 选择起始块地址 select start address */
;         if(ret!=SD_NO_ERR)
	tst R16
	breq L44
;             return ret ;
	xjmp L35
L44:
;         
;         ret=SD_EraseEndBlock(startaddr+sds.erase_unit-1);
	lds R4,_sds+8+2
	lds R5,_sds+8+2+1
	lds R2,_sds+8
	lds R3,_sds+8+1
	movw R30,R28
	ldd R6,z+10
	ldd R7,z+11
	ldd R8,z+12
	ldd R9,z+13
	add R6,R2
	adc R7,R3
	adc R8,R4
	adc R9,R5
	ldi R20,1
	ldi R21,0
	ldi R22,0
	ldi R23,0
	sub R6,R20
	sbc R7,R21
	sbc R8,R22
	sbc R9,R23
	movw R16,R6
	movw R18,R8
	xcall _SD_EraseEndBlock
	mov R10,R16
;         /* 选择终止块地址 select end address */
;         if(ret!=SD_NO_ERR)
	tst R16
	breq L47
;             return ret ;
	xjmp L35
L47:
;         
;         ret=SD_EraseSelectedBlock();
	xcall _SD_EraseSelectedBlock
	mov R10,R16
;         /* 擦除所选的块 erase blocks selected */
;         if(ret!=SD_NO_ERR)
	tst R16
	breq L49
;             return ret ;
	xjmp L35
L49:
	lds R4,_sds+8+2
	lds R5,_sds+8+2+1
	lds R2,_sds+8
	lds R3,_sds+8+1
	movw R30,R28
	ldd R6,z+10
	ldd R7,z+11
	ldd R8,z+12
	ldd R9,z+13
	add R6,R2
	adc R7,R3
	adc R8,R4
	adc R9,R5
	movw R30,R28
	std z+10,R6
	std z+11,R7
	std z+12,R8
	std z+13,R9
	lds R4,_sds+8+2
	lds R5,_sds+8+2+1
	lds R2,_sds+8
	lds R3,_sds+8+1
	movw R30,R28
	ldd R6,z+14
	ldd R7,z+15
	ldd R8,z+16
	ldd R9,z+17
	sub R6,R2
	sbc R7,R3
	sbc R8,R4
	sbc R9,R5
	movw R30,R28
	std z+14,R6
	std z+15,R7
	std z+16,R8
	std z+17,R9
	lds R4,_sds+8+2
	lds R5,_sds+8+2+1
	lds R2,_sds+8
	lds R3,_sds+8+1
	movw R30,R28
	ldd R6,z+14
	ldd R7,z+15
	ldd R8,z+16
	ldd R9,z+17
	sub R6,R2
	sbc R7,R3
	sbc R8,R4
	sbc R9,R5
	movw R30,R28
	std z+0,R6
	std z+1,R7
	std z+2,R8
	std z+3,R9
L42:
	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 X0
	xjmp L41
X0:
;         
;         startaddr+=sds.erase_unit ;
;         /* 起始地址递增 */
;         blocknum-=sds.erase_unit ;
;         tmp=blocknum-sds.erase_unit ;
;     };
;     
;     /* 擦除不够擦除扇区大小的块 */
;     if(blocknum>0)
	ldi R20,0
	ldi R21,0
	ldi R22,0
	ldi R23,0
	movw R30,R28
	ldd R2,z+14
	ldd R3,z+15
	ldd R4,z+16
	ldd R5,z+17
	cp R2,R20
	cpc R3,R21
	cpc R4,R22
	cpc R5,R23
	brne X1
	xjmp L54
X1:
;     {
;         /* erase blocks that numbers is not enough a sector */
;         ret=SD_EraseStartBlock(startaddr);
	movw R30,R28
	ldd R16,z+10
	ldd R17,z+11
	ldd R18,z+12
	ldd R19,z+13
	xcall _SD_EraseStartBlock
	mov R10,R16
;         if(ret!=SD_NO_ERR)
	tst R16
	breq L56
;             return ret ;
	xjmp L35
L56:
;         
;         ret=SD_EraseEndBlock(startaddr+blocknum-1);
	movw R30,R28
	ldd R2,z+14
	ldd R3,z+15
	ldd R4,z+16
	ldd R5,z+17
	movw R30,R28
	ldd R6,z+10
	ldd R7,z+11
	ldd R8,z+12
	ldd R9,z+13
	add R6,R2
	adc R7,R3
	adc R8,R4
	adc R9,R5
	ldi R20,1
	ldi R21,0
	ldi R22,0
	ldi R23,0
	sub R6,R20
	sbc R7,R21
	sbc R8,R22
	sbc R9,R23
	movw R16,R6
	movw R18,R8
	xcall _SD_EraseEndBlock
	mov R10,R16
;         if(ret!=SD_NO_ERR)
	tst R16
	breq L58
;             return ret ;
	xjmp L35
L58:
;         
;         ret=SD_EraseSelectedBlock();
	xcall _SD_EraseSelectedBlock
	mov R10,R16
;         if(ret!=SD_NO_ERR)
	tst R16
	breq L60
;             return ret ;
	xjmp L35
L60:
;     }
L54:
;     return SD_NO_ERR ;/* 返回擦除成功 return erase sucessfully */
	clr R16
L35:
	adiw R28,4
	xcall pop_gset3
	adiw R28,4
	.dbline 0 ; func end
	ret
;            tmp -> y+16
;            ret -> R10
;         csdbuf -> y+0
	.even
_SD_GetCardInfo::
	xcall push_gset3
	sbiw R28,20
; }
; #endif 
; 
; 
; /*******************************************************************************
; ** 函数名称: INT8U SD_GetCardInfo()				
; ** 功能描述: 获得SD卡的信息						
; ** 输   入: INT8U cardtype: 卡类型				
; ** 输   出: 0:   正确    >0:   错误码		  	O
; *******************************************************************************/
; INT8U SD_GetCardInfo(void)
; {
;     INT32U tmp ;
;     INT8U csdbuf[16],ret ;
;     
;     ret=SD_ReadCSD(16,csdbuf);/* 读CSD寄存器 */
	movw R18,R28
	ldi R16,16
	xcall _SD_ReadCSD
	mov R10,R16
;     if(ret!=SD_NO_ERR)
	tst R16
	breq L63
;         return ret ;
	xjmp L62
L63:
;     
;     SD_CalTimeout(csdbuf);/* 计算超时时间值 */
	movw R16,R28
	xcall _SD_CalTimeout
;     
;     /* 计算块的最大长度  */
;     /* calculate the size of a sector */
;     sds.block_len=1<<(csdbuf[READ_BL_LEN_POS]&READ_BL_LEN_MSK);
	ldd R18,y+5
	clr R19
	andi R18,15
	andi R19,0
	ldi R16,1
	ldi R17,0
	xcall lsl16
	movw R2,R16
	clr R4
	sbrc R3,7
	com R4
	clr R5
	sbrc R4,7
	com R5
	sts _sds+4+1,R3
	sts _sds+4,R2
	sts _sds+4+2+1,R5
	sts _sds+4+2,R4
;     /* (2 ^ READ_BL_LEN) */
;     
;     /* 计算卡中块的个数 */
;     /* calculate the sector numbers of the SD Card */
;     sds.block_num=((INT32U)(csdbuf[C_SIZE_POS1]&C_SIZE_MSK1)<<10)+((INT32U)csdbuf[C_SIZE_POS2]<<2)+((csdbuf[C_SIZE_POS3]&C_SIZE_MSK3)>>6)+1 ;
	ldi R24,2
	ldi R25,0
	ldd R2,y+7
	clr R3
	clr R4
	clr R5
	st -y,R24
	movw R16,R2
	movw R18,R4
	xcall lsl32
	movw R2,R16
	movw R4,R18
	ldi R24,10
	ldi R25,0
	ldd R30,y+6
	clr R31
	andi R30,3
	andi R31,0
	movw R6,R30
	clr R8
	sbrc R7,7
	com R8
	clr R9
	sbrc R8,7
	com R9
	st -y,R24
	movw R16,R6
	movw R18,R8
	xcall lsl32
	movw R6,R16
	movw R8,R18
	add R6,R2
	adc R7,R3
	adc R8,R4
	adc R9,R5
	ldi R18,6
	ldi R19,0
	ldd R16,y+8
	clr R17
	andi R16,192
	andi R17,0
	xcall asr16
	movw R2,R16
	clr R4
	sbrc R3,7
	com R4
	clr R5
	sbrc R4,7
	com R5
	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+1,R7
	sts _sds,R6
	sts _sds+2+1,R9
	sts _sds+2,R8
;     /* (C_SIZE + 1)*/
;     
;     tmp=((INT32U)(csdbuf[C_SIZE_MULT_POS1]&C_SIZE_MULT_MSK1)<<1)+((csdbuf[C_SIZE_MULT_POS2]&C_SIZE_MULT_MSK2)>>7)+2 ;
	ldi R18,7
	ldi R19,0
	ldd R16,y+10
	clr R17
	andi R16,128
	andi R17,0
	xcall asr16
	movw R2,R16
	clr R4
	sbrc R3,7
	com R4
	clr R5
	sbrc R4,7
	com R5
	ldd R24,y+9
	clr R25
	andi R24,3
	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,2
	ldi R21,0
	ldi R22,0
	ldi R23,0
	add R6,R20
	adc R7,R21
	adc R8,R22
	adc R9,R23
	movw R30,R28
	std z+16,R6
	std z+17,R7
	std z+18,R8
	std z+19,R9
;     /* (C_SIZE_MULT + 2) */
;     
;     /* 获得卡中块的数量 */
;     /* get the block numbers in card */
;     sds.block_num=sds.block_num*(1<<tmp);
	movw R30,R28
	ldd R18,z+16
	ldd R19,z+17
	ldi R16,1
	ldi R17,0
	xcall lsl16
	movw R2,R16
	clr R4
	sbrc R3,7
	com R4
	clr R5
	sbrc R4,7
	com R5
	lds R8,_sds+2
	lds R9,_sds+2+1
	lds R6,_sds
	lds R7,_sds+1
	st -y,R5
	st -y,R4
	st -y,R3
	st -y,R2
	movw R16,R6
	movw R18,R8
	xcall empy32u
	sts _sds+1,R17
	sts _sds,R16
	sts _sds+2+1,R19
	sts _sds+2,R18
;     /* (C_SIZE + 1) * 2 ^ (C_SIZE_MULT + 2) */
;     
;     /* 计算扇区大小 */
;     /*calculate the size of sector */
;     sds.erase_unit=((INT32U)(csdbuf[SECTOR_SIZE_POS1]&SECTOR_SIZE_MSK1)<<1)+((csdbuf[SECTOR_SIZE_POS2]&SECTOR_SIZE_MSK2)>>7)+1 ;
	ldi R18,7
	ldi R19,0
	ldd R16,y+11
	clr R17
	andi R16,128
	andi R17,0
	xcall asr16
	movw R2,R16
	clr R4

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?