Other Parts Discussed in Thread: SYSCONFIG
Tool/software:
I am using mcupsdk-core REL.MCUSDK.10.01.00.32
I am attempting to setup the udma to do burst gpmc transfers like in figure 6-40 and 6-41 in the AM64x datasheet.
Reading on the forums imply that norlike burst mode is not supported in the drivers and you will need to use udma if you want to have consistent bursts.
I built off of the udma example at examples/drivers/udma/udma_memcpy_polling
The code below is able to do transfers to the GPMC but from the captures it looks like it is doing 16 single transfers, and it is not driving the GPMC0_CLK pin, even though burst transfers are enabled in GPMC0_CONFIG1.
Questions:
- What else needs to be modified to enable burst mode?
- What are the maximum achievable burst sizes?
- 32 bit mode is not supported in sysconfig, can I just configure the device size to 32 GPMC_CONFIG1 and pinmux the rest of the pins to enable 32 bit mode, or is there more?
Capture:
This should be burst, but is doing 16 individual transfers

GPMC0_CONFIG* registers:
(gdb) printf "%p %p\n",GPMC0_CONFIG1,*GPMC0_CONFIG1
0x3b000060 0x78000003
(gdb) printf "%p %p\n",GPMC0_CONFIG2,*GPMC0_CONFIG2
0x3b000064 0x10001
(gdb) printf "%p %p\n",GPMC0_CONFIG3,*GPMC0_CONFIG3
0x3b000068 0x22060514
(gdb) printf "%p %p\n",GPMC0_CONFIG4,*GPMC0_CONFIG4
0x3b00006c 0x305e016
(gdb) printf "%p %p\n",GPMC0_CONFIG5,*GPMC0_CONFIG5
0x3b000070 0x10f1111
(gdb) printf "%p %p\n",GPMC0_CONFIG6,*GPMC0_CONFIG6
0x3b000074 0x8f000000
(gdb) printf "%p %p\n",GPMC0_CONFIG7,*GPMC0_CONFIG7
0x3b000078 0xf50
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 |
#include <drivers/gpio.h> #include <drivers/gpmc/v0/cslr_gpmc.h> #include <drivers/gpmc/v0/gpmc.h> #include <drivers/hw_include/cslr.h> #include <drivers/soc.h> #include <kernel/dpl/AddrTranslateP.h> #include "ti_drivers_config.h" #include "ti_drivers_open_close.h" #include <string.h> #define UDMA_TEST_NUM_BYTES (16U) #define UDMA_TEST_TRPD_SIZE (UDMA_GET_TRPD_TR15_SIZE(1U)) uint8_t gUdmaTestTrpdMem[UDMA_TEST_TRPD_SIZE] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT))); uint8_t gUdmaTestSrcBuf[UDMA_ALIGN_SIZE(UDMA_TEST_NUM_BYTES)] __attribute__((aligned(UDMA_CACHELINE_ALIGNMENT))); uint32_t *GPMC0_CONFIG1 = (uint32_t*)(CSL_GPMC0_CFG_BASE + CSL_GPMC_CONFIG1(0)); uint32_t *GPMC0_CONFIG2 = (uint32_t*)(CSL_GPMC0_CFG_BASE + CSL_GPMC_CONFIG2(0)); uint32_t *GPMC0_CONFIG3 = (uint32_t*)(CSL_GPMC0_CFG_BASE + CSL_GPMC_CONFIG3(0)); uint32_t *GPMC0_CONFIG4 = (uint32_t*)(CSL_GPMC0_CFG_BASE + CSL_GPMC_CONFIG4(0)); uint32_t *GPMC0_CONFIG5 = (uint32_t*)(CSL_GPMC0_CFG_BASE + CSL_GPMC_CONFIG5(0)); uint32_t *GPMC0_CONFIG6 = (uint32_t*)(CSL_GPMC0_CFG_BASE + CSL_GPMC_CONFIG6(0)); uint32_t *GPMC0_CONFIG7 = (uint32_t*)(CSL_GPMC0_CFG_BASE + CSL_GPMC_CONFIG7(0)); void App_udmaTrpdInit(Udma_ChHandle chHandle, uint8_t *trpdMem, const void *destBuf, const void *srcBuf, uint32_t length); void gpmc_configure(); void transfer(uint64_t trpdMemPhy, Udma_ChHandle chHandle); int main() { System_init(); Drivers_open(); // Configure gpmc with burst mode gpmc_configure(); GPMC_Handle *handle = GPMC_getHandle(0); // Get source and destination buffers uint32_t length = UDMA_TEST_NUM_BYTES; uint8_t *destBuf = (uint8_t*)AddrTranslateP_getLocalAddr(CSL_GPMC0_DATA_BASE); uint8_t *srcBuf = &gUdmaTestSrcBuf[0U]; // Has to be done after driver open Udma_ChHandle chHandle = gConfigUdma0BlkCopyChHandle[0]; // Get trpd buffers uint8_t *trpdMem = &gUdmaTestTrpdMem[0U]; uint64_t trpdMemPhy = (uint64_t) Udma_defaultVirtToPhyFxn(trpdMem, 0U, NULL); // Fill src with dummy memory memset(srcBuf, 0x55, UDMA_TEST_NUM_BYTES); // Enable channel DebugP_assert(Udma_chEnable(chHandle) == UDMA_SOK); // Init TR packet descriptor App_udmaTrpdInit(chHandle, trpdMem, destBuf, srcBuf, length); for (;;) { transfer(trpdMemPhy, chHandle); CacheP_inv(trpdMem, UDMA_TEST_TRPD_SIZE, CacheP_TYPE_ALLD); DebugP_assert(UdmaUtils_getTrpdTr15Response(trpdMem, 1U, 0U) == CSL_UDMAP_TR_RESPONSE_STATUS_COMPLETE); } } /** * Used example udma_memcpy_polling for this * modified icnt0, icnt1, dictn0, dictn1 according to: * e2e.ti.com/.../am2434-gpmc-burst-transfer-to-fpga-using-udma-tr-type-settings */ void App_udmaTrpdInit(Udma_ChHandle chHandle, uint8_t *trpdMem, const void *destBuf, const void *srcBuf, uint32_t length) { CSL_UdmapTR15 *pTr; uint32_t cqRingNum = Udma_chGetCqRingNum(chHandle); /* Make TRPD with TR15 TR type */ UdmaUtils_makeTrpdTr15(trpdMem, 1U, cqRingNum); /* Setup TR */ pTr = UdmaUtils_getTrpdTr15Pointer(trpdMem, 0U); pTr->flags = CSL_FMK(UDMAP_TR_FLAGS_TYPE, CSL_UDMAP_TR_FLAGS_TYPE_4D_BLOCK_MOVE_REPACKING_INDIRECTION); pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_STATIC, 0U); pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_EOL, CSL_UDMAP_TR_FLAGS_EOL_MATCH_SOL_EOL); pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_EVENT_SIZE, CSL_UDMAP_TR_FLAGS_EVENT_SIZE_COMPLETION); pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER0, CSL_UDMAP_TR_FLAGS_TRIGGER_NONE); pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER0_TYPE, CSL_UDMAP_TR_FLAGS_TRIGGER_TYPE_ALL); pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER1, CSL_UDMAP_TR_FLAGS_TRIGGER_NONE); pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_TRIGGER1_TYPE, CSL_UDMAP_TR_FLAGS_TRIGGER_TYPE_ALL); pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_CMD_ID, 0x25U); /* This will come back in TR response */ pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_SA_INDIRECT, 0U); pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_DA_INDIRECT, 0U); pTr->flags |= CSL_FMK(UDMAP_TR_FLAGS_EOP, 1U); pTr->icnt0 = 2U; pTr->icnt1 = length/2; pTr->icnt2 = 1U; pTr->icnt3 = 1U; pTr->dim1 = pTr->icnt0; pTr->dim2 = (pTr->icnt0 * pTr->icnt1); pTr->dim3 = (pTr->icnt0 * pTr->icnt1 * pTr->icnt2); pTr->addr = (uint64_t) Udma_defaultVirtToPhyFxn(srcBuf, 0U, NULL); pTr->fmtflags = 0x00000000U; /* Linear addressing, 1 byte per elem */ pTr->dicnt0 = 2U; pTr->dicnt1 = length/2; pTr->dicnt2 = 1U; pTr->dicnt3 = 1U; pTr->ddim1 = pTr->dicnt0; pTr->ddim2 = (pTr->dicnt0 * pTr->dicnt1); pTr->ddim3 = (pTr->dicnt0 * pTr->dicnt1 * pTr->dicnt2); pTr->daddr = (uint64_t) Udma_defaultVirtToPhyFxn(destBuf, 0U, NULL); /* Perform cache writeback */ CacheP_wb(trpdMem, UDMA_TEST_TRPD_SIZE, CacheP_TYPE_ALLD); return; } /** * Configure GPMC with synchronous burst mode */ void gpmc_configure() { CSL_FINST(*GPMC0_CONFIG1, GPMC_CONFIG1_WRITEMULTIPLE, WRMULTIPLE); CSL_FINST(*GPMC0_CONFIG1, GPMC_CONFIG1_READMULTIPLE, RDMULTIPLE); CSL_FINST(*GPMC0_CONFIG1, GPMC_CONFIG1_READTYPE, RDSYNC); CSL_FINST(*GPMC0_CONFIG1, GPMC_CONFIG1_WRITETYPE, WRSYNC); GPMC_Handle *handle = GPMC_getHandle(0); // If I don't run these, accesses to 0x50000000 fault GPMC_setDeviceType(handle); GPMC_setDeviceSize(handle); // If I don't run these, the UDMA fails to transfer GPMC_configurePrefetchPostWriteEngine(handle); GPMC_configureTimingParameters(handle); } /** * Polling udma queue and dequeue */ void transfer(uint64_t trpdMemPhy, Udma_ChHandle chHandle) { uint64_t pDesc; int32_t retVal = UDMA_SOK; retVal = Udma_ringQueueRaw(Udma_chGetFqRingHandle(chHandle), trpdMemPhy); DebugP_assert(retVal == UDMA_SOK); while(1) { retVal = Udma_ringDequeueRaw(Udma_chGetCqRingHandle(chHandle), &pDesc); if(UDMA_SOK == retVal) { break; } } } |


