15.3. 应用示例¶
15.3.1. PSRAM 初始化¶
15.3.1.1. PSRAM XIP 初始化¶
通过调用 PSRAM 驱动初始化接口 \ref psram_xip_init_by_type,参数如下:
type 为 psram 四线或八线模式,默认为 0,四线模式;
示例代码:
psram_xip_init_by_type(0);
15.3.1.2. PSRAM CPU读写操作¶
PSRAM XIP 初始化后,即可直接访问 PSRAM 映射的 XIP 地址进行读写操作;
PSRAM 读操作:
volatile uint8_t *data_8 = (uint8_t *)CONFIG_PSRAM_XIP_DBUS_BASE;
uint8_t n = data_8[0];
PSRAM 写操作:
volatile uint8_t *data_8 = (uint8_t *)CONFIG_PSRAM_XIP_DBUS_BASE;
uint8_t n = 0xa5;
data_8[0] = n;
15.3.2. PSRAM DMA 读写操作¶
从堆中申请一个 len 大小的 buffer, 并初始化赋值;
配置 dma 相关参数 \ref GX_DMA_AHB_CH_CONFIG,例如:dma 位宽,通道,busrt 长度,握手信号,流控等;
配置 dma 源地址为 buffer 起始地址,目的地址为 psram 起始地址 CONFIG_PSRAM_XIP_DBUS_BASE;
启动 dma 传输,将 buffer 中数据写入 psram 的起始地址处,等待 dma 传输完成状态;
比较写入到 psram 的数据与 buffer 中数据是否一直,验证 dma 写 psram 是否正确;
清空 buffer 中数据,更换 dma 配置参数中源地址和目的地址,源地址为 psram 起始地址,目的地址为 buffer 起始地址;
启动 dma 传输,将 psram 的起始地址处数据写入到 buffer 中,等待 dma 传输完成状态;
比较读取到 buffer 中数据与 psram 的数据是否一直,验证 dma 读 psram 是否正确;
代码示例:
int channel, i;
int len = 512;
GX_DMA_AHB_CH_CONFIG dma_config;
uint8_t *pbuf8 = NULL, *pdata8 = NULL;
volatile uint8_t *data_8 = (uint8_t*)CONFIG_PSRAM_XIP_DBUS_BASE;
pbuf8 = (uint8_t*) malloc(len);
for (i = 0; i < len; ++i)
{
pbuf8[i] = i;
}
pdata8 = (uint8_t*) data_8;
channel = gx_dma_select_channel();
if(channel < 0)
printf("get dma channel failed!\n");
/* dma source config */
dma_config.trans_width = GX_DMA_AHB_TRANS_WIDTH_8;
dma_config.src_addr_update = GX_DMA_AHB_CH_CTL_L_INC;
dma_config.src_hs_select = GX_DMA_AHB_HS_SEL_HW;
dma_config.src_master_select = GX_DMA_AHB_MASTER_3;
dma_config.src_msize = GX_DMA_AHB_BURST_TRANS_LEN_32;
dma_config.src_hs_per = 0;
/* dma destination config */
dma_config.dst_addr_update = GX_DMA_AHB_CH_CTL_L_INC;
dma_config.dst_hs_select = GX_DMA_AHB_HS_SEL_HW;
dma_config.dst_master_select = GX_DMA_AHB_MASTER_3;
dma_config.dst_msize = GX_DMA_AHB_BURST_TRANS_LEN_32;
dma_config.dst_hs_per = 0;
dma_config.flow_ctrl = GX_DMA_AHB_TT_FC_MEM_TO_MEM_DMAC;
gx_dcache_clean_range((uint32_t *)pbuf8, len);
if (gx_dma_xfer((void*)pdata8, (void*)pbuf8, len, channel, &dma_config) == -1){
printf("psram dma 8bit write start failed!\n");
return -1;
}
gx_dcache_invalid_range((uint32_t *)pdata8, len);
gx_dma_wait_complete(channel);
if(memcmp(pdata8, pbuf8, len) != 0) {
printf("base_addr:0x%x buff addr:%p, 8bit psram dma write memcmp error!\n", pdata8, pbuf8);
for(i = 0; i < len; i++) {
if(pdata8[i] != pbuf8[i]) {
printf("8bit dma write cmp error at i=0x%x, act:0x%x, exp:0x%x\n", i, pdata8[i], pbuf8[i]);
break;
}
}
return -1;
}
memset(pbuf8, 0x00, len);
gx_dcache_clean_range((uint32_t *)pbuf8, len);
gx_dcache_clean_range((uint32_t *)pdata8, len);
if (gx_dma_xfer((void*)pbuf8, (void*)pdata8, len, channel, &dma_config) == -1){
printf("psram dma 8bit read start failed!\n");
return -1;
}
gx_dcache_invalid_range((uint32_t *)pbuf8, len);
gx_dma_wait_complete(channel);
if(memcmp(pdata8, pbuf8, len) != 0) {
printf("base_addr:0x%x buff addr:0x%p, 8bit psram dma read memcmp error!\n", pdata8, pbuf8);
for(i = 0; i<len; i++) {
if(pdata8[i] != pbuf8[i]) {
printf("8bit dma read cmp error at i=0x%x, act:0x%x, exp:0x%x\n", i, pdata8[i], pbuf8[i]);
break;
}
}
return -1;
}
free(pbuf8);