cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_SD_WriteBlocks always returns HAL_SD_ERROR_TX_UNDERRUN

jjpark78_superman
Associate II
void test_sdio_write_buffer(uint8_t sector, uint32_t* buffer, uint8_t ch) {
	printf("+++test_sdio_write_buffer called, sector: %d\n", sector, ch);
	printf("  Before HAL_SD_GetCardState returns : %d\n", HAL_SD_GetCardState(&hsd));
	printf("    perform HAL_SD_WriteBlocks\r\n");
	HAL_StatusTypeDef ret = HAL_SD_WriteBlocks(&hsd, (uint8_t *)buffer, sector, 1, 1000);
	printf("    HAL_SD_WriteBlocks done\r\n");
	printf("  After HAL_SD_GetCardState returns : %d\n", HAL_SD_GetCardState(&hsd));
	switch(ret) {
	case HAL_OK:
		printf("  HAL_SD_WriteBlocks returns OK\n");
		break;
	case HAL_BUSY:
		printf("  HAL_SD_WriteBlocks returns BUSY\n");
		break;
	case HAL_TIMEOUT:
		printf("  HAL_SD_WriteBlocks returns TIMEOUT\n");
		break;
	case HAL_ERROR:
		printf("  HAL_SD_WriteBlocks returns ERROR\n");
		print_sdio_errorcode(hsd.ErrorCode);
		break;
	}
	//printf("  SD_Write Write Done%d\n");
	printf("---test_sdio_write_buffer done\n");
}
 
void print_sdio_errorcode(uint32_t code) {
	switch (code) {
	case HAL_SD_ERROR_NONE:
		printf("      Error Message: HAL_SD_ERROR_NONE\r\n");
		break;
	case HAL_SD_ERROR_CMD_CRC_FAIL:
		printf("      Error Message: HAL_SD_ERROR_CMD_CRC_FAIL\r\n");
		break;
	case HAL_SD_ERROR_DATA_CRC_FAIL:
		printf("      Error Message: HAL_SD_ERROR_DATA_CRC_FAIL\r\n");
		break;
	case HAL_SD_ERROR_CMD_RSP_TIMEOUT:
		printf("      Error Message: HAL_SD_ERROR_CMD_RSP_TIMEOUT\r\n");
		break;
	case HAL_SD_ERROR_DATA_TIMEOUT:
		printf("      Error Message: HAL_SD_ERROR_DATA_TIMEOUT\r\n");
		break;
	case HAL_SD_ERROR_TX_UNDERRUN:
		printf("      Error Message: HAL_SD_ERROR_TX_UNDERRUN\r\n");
		break;
	case HAL_SD_ERROR_RX_OVERRUN:
		printf("      Error Message: HAL_SD_ERROR_RX_OVERRUN\r\n");
		break;
	case HAL_SD_ERROR_ADDR_MISALIGNED:
		printf("      Error Message: HAL_SD_ERROR_ADDR_MISALIGNED\r\n");
		break;
	case HAL_SD_ERROR_BLOCK_LEN_ERR:
		printf("      Error Message: HAL_SD_ERROR_BLOCK_LEN_ERR\r\n");
		break;
	case HAL_SD_ERROR_ERASE_SEQ_ERR:
		printf("      Error Message: HAL_SD_ERROR_ERASE_SEQ_ERR\r\n");
		break;
	case HAL_SD_ERROR_BAD_ERASE_PARAM:
		printf("      Error Message: HAL_SD_ERROR_BAD_ERASE_PARAM\r\n");
		break;
	case HAL_SD_ERROR_WRITE_PROT_VIOLATION:
		printf("      Error Message: HAL_SD_ERROR_WRITE_PROT_VIOLATION\r\n");
		break;
	case HAL_SD_ERROR_LOCK_UNLOCK_FAILED:
		printf("      Error Message: HAL_SD_ERROR_LOCK_UNLOCK_FAILED\r\n");
		break;
	case HAL_SD_ERROR_COM_CRC_FAILED:
		printf("      Error Message: HAL_SD_ERROR_COM_CRC_FAILED\r\n");
		break;
	case HAL_SD_ERROR_ILLEGAL_CMD:
		printf("      Error Message: HAL_SD_ERROR_ILLEGAL_CMD\r\n");
		break;
	case HAL_SD_ERROR_CARD_ECC_FAILED:
		printf("      Error Message: HAL_SD_ERROR_CARD_ECC_FAILED\r\n");
		break;
	case HAL_SD_ERROR_CC_ERR:
		printf("      Error Message: HAL_SD_ERROR_CC_ERR\r\n");
		break;
	case HAL_SD_ERROR_GENERAL_UNKNOWN_ERR:
		printf("      Error Message: HAL_SD_ERROR_GENERAL_UNKNOWN_ERR\r\n");
		break;
	case HAL_SD_ERROR_STREAM_READ_UNDERRUN:
		printf("      Error Message: HAL_SD_ERROR_STREAM_READ_UNDERRUN\r\n");
		break;
	case HAL_SD_ERROR_STREAM_WRITE_OVERRUN:
		printf("      Error Message: HAL_SD_ERROR_STREAM_WRITE_OVERRUN\r\n");
		break;
	case HAL_SD_ERROR_CID_CSD_OVERWRITE:
		printf("      Error Message: HAL_SD_ERROR_CID_CSD_OVERWRITE\r\n");
		break;
	case HAL_SD_ERROR_WP_ERASE_SKIP:
		printf("      Error Message: HAL_SD_ERROR_WP_ERASE_SKIP\r\n");
		break;
	case HAL_SD_ERROR_CARD_ECC_DISABLED:
		printf("      Error Message: HAL_SD_ERROR_CARD_ECC_DISABLED\r\n");
		break;
	case HAL_SD_ERROR_ERASE_RESET:
		printf("      Error Message: HAL_SD_ERROR_ERASE_RESET\r\n");
		break;
	case HAL_SD_ERROR_AKE_SEQ_ERR:
		printf("      Error Message: HAL_SD_ERROR_AKE_SEQ_ERR\r\n");
		break;
	case HAL_SD_ERROR_INVALID_VOLTRANGE:
		printf("      Error Message: HAL_SD_ERROR_INVALID_VOLTRANGE\r\n");
		break;
	case HAL_SD_ERROR_ADDR_OUT_OF_RANGE:
		printf("      Error Message: HAL_SD_ERROR_ADDR_OUT_OF_RANGE\r\n");
		break;
	case HAL_SD_ERROR_REQUEST_NOT_APPLICABLE:
		printf("      Error Message: HAL_SD_ERROR_REQUEST_NOT_APPLICABLE\r\n");
		break;
	case HAL_SD_ERROR_PARAM:
		printf("      Error Message: HAL_SD_ERROR_PARAM\r\n");
		break;
	case HAL_SD_ERROR_UNSUPPORTED_FEATURE:
		printf("      Error Message: HAL_SD_ERROR_UNSUPPORTED_FEATURE\r\n");
		break;
	case HAL_SD_ERROR_BUSY:
		printf("      Error Message: HAL_SD_ERROR_BUSY\r\n");
		break;
	case HAL_SD_ERROR_DMA:
		printf("      Error Message: HAL_SD_ERROR_DMA\r\n");
		break;
	case HAL_SD_ERROR_TIMEOUT:
		printf("      Error Message: HAL_SD_ERROR_TIMEOUT\r\n");
		break;
	default:
		printf("      Error Message: HAL_UNKNOWN_ERROR\r\n");
		break;
	}
}

i am developping some usb disk firmware with stm32f411

USB MSC Cass Registration is fully working,

and MX_SDIO_SD_Init() is also working.

but when i implement STORAGE_Write_FS function,

SDIO always returns HAL_SD_ERROR_TX_UNDERRUN

so i made a some testing function and following is it's log.

what am i doing worng ?? change to HAL_SD_WriteBlocks_IT will return HAL_OK but it's callback always got a Error and ErrorCode is same.

+++test_sdio_write_buffer called, sector: 0
  Before HAL_SD_GetCardState returns : 4
    perform HAL_SD_WriteBlocks
    HAL_SD_WriteBlocks done
  After HAL_SD_GetCardState returns : 4
  HAL_SD_WriteBlocks returns ERROR
      Error Message: HAL_SD_ERROR_TX_UNDERRUN
---test_sdio_write_buffer done

2 REPLIES 2
jjpark78_superman
Associate II

i found some post said UNDERRUN Error is related to SDIO_CK Speed.

and my initial ClockDiv value was 0, and change it to 10, wow it works fine.

 but i dont know why. somebody can teach me ?

TDK
Guru

With a fast clock rate, the cpu doesn't feed data to the peripheral fast enough and the buffer runs out, causing the underrun error. Could be solved by using DMA or using better optimized code.

If you feel a post has answered your question, please click "Accept as Solution".