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);