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 + -
显示快捷键?