T113-S3 的SMHC1连接SD-NAND问题:
-
T113-s3的SMHC1接一片SD NAND ,但在读取数据时,传输描述符配置都正确的情况下。iDMA始终报描述符不可用中断。status_t sd_mmc_set_dma_table_config(v3x_sd_mmc_t *base,
sd_mmc_dma_config_t *dma_config,
sd_mmc_data_t *data_config,
uint32_t flags)
{
base->DMAC = 1;//IMAC 复位
const uint32_t *start_address;
uint32_t entries;
uint32_t i, dma_buffer_len = 0U;
sd_mmc_dma_descriptor_t *dma_entry_address;uint32_t data_bytes = data_config->block_size * data_config->block_count; const uint32_t *data = (data_config->rx_data == NULL) ? data_config->tx_data : data_config->rx_data; /* check DMA data buffer address align or not */ if ( ((uint32_t)data & 0x03) != 0U ) { return STA_DMA_DATA_ADDR_NOT_ALIGN; } /* * Add non aligned access support ,user need make sure your buffer size is big * enough to hold the data,in other words,user need make sure the buffer size * is 4 byte aligned */ data_bytes = (data_bytes + 3) & (~3); start_address = data; base->GCTL |= (SDXC_FIFO_RESET | SDXC_DMA_RESET | SDXC_DMA_ENABLE_BIT);/* reset fifo & dma*/ /* Check if ADMA descriptor's number is enough. */ if ((data_bytes % MMC_SD_DMA_DESCRIPTOR_MAX_LENGTH_PER_ENTRY) == 0U) entries = data_bytes / MMC_SD_DMA_DESCRIPTOR_MAX_LENGTH_PER_ENTRY; else entries = ((data_bytes / MMC_SD_DMA_DESCRIPTOR_MAX_LENGTH_PER_ENTRY) + 1U); if (entries > ((dma_config->dma_table_words * sizeof(uint32_t)) / sizeof(sd_mmc_dma_descriptor_t))) { /*如果超过预置(1个)数量,应该支持动态分配描述符表 */ if( STA_SUCCESS != sd_mmc_malloc_dma_descriptor( dma_config,entries)) return STA_MEM_ERROR; } dma_entry_address = (sd_mmc_dma_descriptor_t *)(dma_config->dma_table); for (i = 0U; i < entries; i++) { if (data_bytes > MMC_SD_DMA_DESCRIPTOR_MAX_LENGTH_PER_ENTRY) { dma_buffer_len = MMC_SD_DMA_DESCRIPTOR_MAX_LENGTH_PER_ENTRY; data_bytes -= dma_buffer_len; } else { dma_buffer_len = data_bytes; } /* */ dma_entry_address[i].buf_addr_ptr = (uint32_t)start_address; dma_entry_address[i].buf_size = dma_buffer_len ; dma_entry_address[i].config = SD_MMC_DESCRIPTOR_TC_INT_DIS | SD_MMC_DESCRIPTOR_CHAIM_MOD | SD_MMC_DESCRIPTOR_OWN_FLAG; dma_entry_address[i].buf_addr_next = (uint32_t)&dma_entry_address[i + 1]; start_address += (dma_buffer_len / sizeof(uint32_t));/*32bit 偏移*/ } /* set the end bit */ dma_entry_address[0].config = SD_MMC_DESCRIPTOR_FIRST_FLAG | SD_MMC_DESCRIPTOR_TC_INT_DIS | SD_MMC_DESCRIPTOR_CHAIM_MOD | SD_MMC_DESCRIPTOR_OWN_FLAG; uint32_t config = dma_entry_address[i - 1U].config & (~(SD_MMC_DESCRIPTOR_TC_INT_DIS )); dma_entry_address[i - 1U].config = config | SD_MMC_DESCRIPTOR_LAST_FLAG;// \ // | (1 << 5); /* end of ring */ dma_entry_address[i - 1U].buf_addr_next = 0; base->DMAC = (1 << 1) | (1 << 7); /* enable dma interrupt */ base->IDST = 0x3F; /*清除DMA中断状态 */ /*config the burst length */ base->FWLR = (burst_len_16 << 28) | (0x0f << 16) | 240;//0x10; /*允许dma中断 */ if(data_config->rx_data) { /*DMA 接收利用 DMA传输完毕产生中断*/ base->IDIE = ( SDXC_IDMAC_RECEIVE_INTERRUPT | SDXC_IDMAC_FATAL_BUS_ERROR | SDXC_IDMAC_DESTINATION_INVALID | SDXC_IDMAC_CARD_ERROR_SUM); base->IMKR &= ~(1 << 3); } else if(data_config->tx_data) { /*DMA 传输利用 MCI传输完毕产生中断*/ base->IDIE = ( SDXC_IDMAC_FATAL_BUS_ERROR | SDXC_IDMAC_TRANSMIT_INTERRUPT | SDXC_IDMAC_DESTINATION_INVALID | SDXC_IDMAC_CARD_ERROR_SUM); base->IMKR |= (1 << 3); } else base->IDIE = 0; base->DLBA = (uint32_t)(dma_config->dma_table); /* enable DMA */ sd_mmc_enable_dma(base);
/*动态分配的内存 ,需要刷新cache */
if (entries > ((dma_config->dma_table_words * sizeof(uint32_t)) / sizeof(sd_mmc_dma_descriptor_t)))
{
L1C_CleanDataCacheRange(dma_config->dma_table,dma_config->dma_table_words * entries);
}return STA_SUCCESS;
}
上面说使用的描述符的内存空间是位于非cache段的内存中。
从内存数据看配置都是正确的,数据已经从sd nsnd 传输到fifo中了,而 IDMA总是报描述符不可用,致使数据不能从fifo读取到内存中。 大家帮我看看问题可能在哪里。 -
原来是这样。总是有意外的惊喜。
-
-
-
@jordonwu 工控板,两个网口,其余两座是CAN +422+IO 口。
-
这块板调试成功了吗? CAN接口调通了吗? 这版你们是自用? 还是对外卖?
Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号