| 
					
				 | 
			
			
				@@ -151,6 +151,8 @@ static void dma_transfer_config(uint32_t *srcbuf, uint32_t bufsize); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /* configure the DMA for SDIO receive request */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void dma_receive_config(uint32_t *dstbuf, uint32_t bufsize); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+unsigned long millis(void); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 /*! 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     \brief      initialize the SD card and make it in standby state 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     \param[in]  none 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -429,12 +431,11 @@ sd_error_enum sd_transfer_mode_config(uint32_t txmode) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     \param[in]  blocksize: the data block size 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     \retval     sd_error_enum 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-sd_error_enum sd_block_read(uint32_t *preadbuffer, uint64_t readaddr, uint16_t blocksize) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+sd_error_enum sd_block_read(uint32_t *preadbuffer, uint64_t readaddr, uint16_t blocksize, sdio_callback_t callback) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /* initialize the variables */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     sd_error_enum status = SD_OK; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     uint32_t count = 0, align = 0, datablksize = SDIO_DATABLOCKSIZE_1BYTE, *ptempbuff = preadbuffer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    __IO uint32_t timeout = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if(NULL == preadbuffer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         status = SD_PARAMETER_INVALID; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -540,12 +541,16 @@ sd_error_enum sd_block_read(uint32_t *preadbuffer, uint64_t readaddr, uint16_t b 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         sdio_interrupt_enable(SDIO_INT_CCRCERR | SDIO_INT_DTTMOUT | SDIO_INT_RXORE | SDIO_INT_DTEND | SDIO_INT_STBITE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         sdio_dma_enable(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         dma_receive_config(preadbuffer, blocksize); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        timeout = 100000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        while((RESET == dma_flag_get(DMA1, DMA_CH3, DMA_FLAG_FTF)) && (timeout > 0)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            timeout--; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if(0 == timeout) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        uint32_t start = millis(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        while((RESET == dma_flag_get(DMA1, DMA_CH3, DMA_FLAG_FTF))) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if((uint32_t)(millis() - start) > 1000) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 return SD_ERROR; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (callback) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                uint32_t complete = (blocksize - DMA_CHCNT(DMA1, DMA_CH3) * 4); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                callback(complete); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         status = SD_PARAMETER_INVALID; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -561,13 +566,12 @@ sd_error_enum sd_block_read(uint32_t *preadbuffer, uint64_t readaddr, uint16_t b 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     \param[in]  blocksnumber: number of blocks that will be read 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     \retval     sd_error_enum 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-sd_error_enum sd_multiblocks_read(uint32_t *preadbuffer, uint64_t readaddr, uint16_t blocksize, uint32_t blocksnumber) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+sd_error_enum sd_multiblocks_read(uint32_t *preadbuffer, uint64_t readaddr, uint16_t blocksize, uint32_t blocksnumber, sdio_callback_t callback) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /* initialize the variables */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     sd_error_enum status = SD_OK; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     uint32_t count = 0, align = 0, datablksize = SDIO_DATABLOCKSIZE_1BYTE, *ptempbuff = preadbuffer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    __IO uint32_t timeout = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if(NULL == preadbuffer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         status = SD_PARAMETER_INVALID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return status; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -612,7 +616,7 @@ sd_error_enum sd_multiblocks_read(uint32_t *preadbuffer, uint64_t readaddr, uint 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return status; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if(blocksnumber > 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(blocksnumber >= 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if(blocksnumber * blocksize > SD_MAX_DATA_LENGTH) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             /* exceeds the maximum length */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             status = SD_PARAMETER_INVALID; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -694,14 +698,22 @@ sd_error_enum sd_multiblocks_read(uint32_t *preadbuffer, uint64_t readaddr, uint 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             sdio_dma_enable(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             dma_receive_config(preadbuffer, totalnumber_bytes); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            timeout = 100000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            while((RESET == dma_flag_get(DMA1, DMA_CH3, DMA_FLAG_FTF)) && (timeout > 0)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                timeout--; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if(0 == timeout) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            uint32_t start = millis(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            while((RESET == dma_flag_get(DMA1, DMA_CH3, DMA_FLAG_FTF))) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if((uint32_t)(millis() - start) > 1000) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     return SD_ERROR; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (callback) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    uint32_t complete = (totalnumber_bytes - DMA_CHCNT(DMA1, DMA_CH3) * 4); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    callback(complete); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             while((0 == transend) && (SD_OK == transerror)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (callback) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    callback(totalnumber_bytes); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if(SD_OK != transerror) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 return transerror; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -721,15 +733,14 @@ sd_error_enum sd_multiblocks_read(uint32_t *preadbuffer, uint64_t readaddr, uint 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     \param[out] none 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     \retval     sd_error_enum 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-sd_error_enum sd_block_write(uint32_t *pwritebuffer, uint64_t writeaddr, uint16_t blocksize) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+sd_error_enum sd_block_write(uint32_t *pwritebuffer, uint64_t writeaddr, uint16_t blocksize, sdio_callback_t callback) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /* initialize the variables */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     sd_error_enum status = SD_OK; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     uint8_t cardstate = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     uint32_t count = 0, align = 0, datablksize = SDIO_DATABLOCKSIZE_1BYTE, *ptempbuff = pwritebuffer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     uint32_t transbytes = 0, restwords = 0, response = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    __IO uint32_t timeout = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if(NULL == pwritebuffer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         status = SD_PARAMETER_INVALID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return status; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -785,11 +796,19 @@ sd_error_enum sd_block_write(uint32_t *pwritebuffer, uint64_t writeaddr, uint16_ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     response = sdio_response_get(SDIO_RESPONSE0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    timeout = 100000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    while((0 == (response & SD_R1_READY_FOR_DATA)) && (timeout > 0)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    uint32_t start = millis(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    while((0 == (response & SD_R1_READY_FOR_DATA))) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /* continue to send CMD13 to polling the state of card until buffer empty or timeout */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        --timeout; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if((uint32_t)(millis() - start) > 1000) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return SD_ERROR; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (callback) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            callback(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         /* send CMD13(SEND_STATUS), addressed card sends its status registers */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         sdio_command_response_config(SD_CMD_SEND_STATUS, (uint32_t)sd_rca << SD_RCA_SHIFT, SDIO_RESPONSETYPE_SHORT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         sdio_wait_type_set(SDIO_WAITTYPE_NO); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -801,9 +820,6 @@ sd_error_enum sd_block_write(uint32_t *pwritebuffer, uint64_t writeaddr, uint16_ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         response = sdio_response_get(SDIO_RESPONSE0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if(0 == timeout) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return SD_ERROR; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /* send CMD24(WRITE_BLOCK) to write a block */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     sdio_command_response_config(SD_CMD_WRITE_BLOCK, writeaddr, SDIO_RESPONSETYPE_SHORT); 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -871,14 +887,22 @@ sd_error_enum sd_block_write(uint32_t *pwritebuffer, uint64_t writeaddr, uint16_ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         dma_transfer_config(pwritebuffer, blocksize); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         sdio_dma_enable(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        timeout = 100000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        while((RESET == dma_flag_get(DMA1, DMA_CH3, DMA_FLAG_FTF)) && (timeout > 0)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            timeout--; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if(0 == timeout) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        uint32_t start = millis(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        while((RESET == dma_flag_get(DMA1, DMA_CH3, DMA_FLAG_FTF))) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if((uint32_t)(millis() - start) > 1000) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 return SD_ERROR; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (callback) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                uint32_t complete = (blocksize - DMA_CHCNT(DMA1, DMA_CH3) * 4); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                callback(complete); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         while((0 == transend) && (SD_OK == transerror)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (callback) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                callback(blocksize); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if(SD_OK != transerror) { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -894,6 +918,10 @@ sd_error_enum sd_block_write(uint32_t *pwritebuffer, uint64_t writeaddr, uint16_ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /* get the card state and wait the card is out of programming and receiving state */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     status = sd_card_state_get(&cardstate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     while((SD_OK == status) && ((SD_CARDSTATE_PROGRAMMING == cardstate) || (SD_CARDSTATE_RECEIVING == cardstate))) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (callback) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            callback(blocksize); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         status = sd_card_state_get(&cardstate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return status; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -908,15 +936,14 @@ sd_error_enum sd_block_write(uint32_t *pwritebuffer, uint64_t writeaddr, uint16_ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     \param[out] none 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     \retval     sd_error_enum 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-sd_error_enum sd_multiblocks_write(uint32_t *pwritebuffer, uint64_t writeaddr, uint16_t blocksize, uint32_t blocksnumber) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+sd_error_enum sd_multiblocks_write(uint32_t *pwritebuffer, uint64_t writeaddr, uint16_t blocksize, uint32_t blocksnumber, sdio_callback_t callback) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /* initialize the variables */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     sd_error_enum status = SD_OK; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     uint8_t cardstate = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     uint32_t count = 0, align = 0, datablksize = SDIO_DATABLOCKSIZE_1BYTE, *ptempbuff = pwritebuffer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     uint32_t transbytes = 0, restwords = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    __IO uint32_t timeout = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     if(NULL == pwritebuffer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         status = SD_PARAMETER_INVALID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return status; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -971,7 +998,7 @@ sd_error_enum sd_multiblocks_write(uint32_t *pwritebuffer, uint64_t writeaddr, u 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         return status; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if(blocksnumber > 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if(blocksnumber >= 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if(blocksnumber * blocksize > SD_MAX_DATA_LENGTH) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             status = SD_PARAMETER_INVALID; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             return status; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1081,14 +1108,22 @@ sd_error_enum sd_multiblocks_write(uint32_t *pwritebuffer, uint64_t writeaddr, u 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             sdio_dma_enable(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             dma_transfer_config(pwritebuffer, totalnumber_bytes); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            timeout = 100000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            while((RESET == dma_flag_get(DMA1, DMA_CH3, DMA_FLAG_FTF) && (timeout > 0))) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                timeout--; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if(0 == timeout) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            uint32_t start = millis(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            while((RESET == dma_flag_get(DMA1, DMA_CH3, DMA_FLAG_FTF))) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if((uint32_t)(millis() - start) > 1000) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                     return SD_ERROR; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (callback) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    uint32_t complete = (totalnumber_bytes - DMA_CHCNT(DMA1, DMA_CH3) * 4); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    callback(complete); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             while((0 == transend) && (SD_OK == transerror)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (callback) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    callback(totalnumber_bytes); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             if(SD_OK != transerror) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				                 return transerror; 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -1104,6 +1139,10 @@ sd_error_enum sd_multiblocks_write(uint32_t *pwritebuffer, uint64_t writeaddr, u 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     /* get the card state and wait the card is out of programming and receiving state */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     status = sd_card_state_get(&cardstate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     while((SD_OK == status) && ((SD_CARDSTATE_PROGRAMMING == cardstate) || (SD_CARDSTATE_RECEIVING == cardstate))) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (callback) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            callback(totalnumber_bytes); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         status = sd_card_state_get(&cardstate); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     return status; 
			 |