Hello,
I am working on the configuration of a DMAC channel for streaming data bytes from a buffer to the GPIO port 10, using only GPIOs from 0 to 2. I think I am missing something but I really can't make it work.
Since I am learning for now I am triggering the DMA by simply enabling the block, next I will trigger it with a CC0 of a counter. But, let's see what I got so far.
I have started an "Empty Project" from the getting started section. Then in the "Device Configurator" I simply set the DMAC channel 0 for a transfer of 1 byte.
/* NOTE: This is a preview only. It combines elements of the * cycfg_dmas.c and cycfg_dmas.h files located in the folder * C:/Users/Francesco/mtw/Empty_App_1/bsps/TARGET_APP_CY8CKIT-062S4/config/GeneratedSource. */ #include "cy_dmac.h" #if defined (CY_USING_HAL) #include "cyhal_hwmgr.h" #endif //defined (CY_USING_HAL) #define cpuss_0_dmac_0_chan_0_HW DMAC #define cpuss_0_dmac_0_chan_0_CHANNEL 0U #define cpuss_0_dmac_0_chan_0_IRQ cpuss_interrupts_dmac_0_IRQn cy_stc_dmac_descriptor_config_t cpuss_0_dmac_0_chan_0_Descriptor_0_config = { .retrigger = CY_DMAC_RETRIG_IM, .interruptType = CY_DMAC_1ELEMENT, .triggerOutType = CY_DMAC_1ELEMENT, .channelState = CY_DMAC_CHANNEL_ENABLED, .triggerInType = CY_DMAC_1ELEMENT, .dataPrefetch = false, .dataSize = CY_DMAC_WORD, .srcTransferSize = CY_DMAC_TRANSFER_SIZE_WORD, .dstTransferSize = CY_DMAC_TRANSFER_SIZE_WORD, .descriptorType = CY_DMAC_SINGLE_TRANSFER, .srcAddress = NULL, .dstAddress = NULL, .srcXincrement = 0, .dstXincrement = 0, .xCount = 1, .srcYincrement = 1, .dstYincrement = 1, .yCount = 1, .nextDescriptor = NULL, }; cy_stc_dmac_descriptor_t cpuss_0_dmac_0_chan_0_Descriptor_0 = { .ctl = 0UL, .src = 0UL, .dst = 0UL, .xSize = 0UL, .xIncr = 0UL, .ySize = 0UL, .yIncr = 0UL, .nextPtr = 0UL, }; cy_stc_dmac_channel_config_t cpuss_0_dmac_0_chan_0_channelConfig = { .descriptor = &cpuss_0_dmac_0_chan_0_Descriptor_0, .priority = 3, .enable = false, .bufferable = false, }; #if defined (CY_USING_HAL) const cyhal_resource_inst_t cpuss_0_dmac_0_chan_0_obj = { .type = CYHAL_RSC_DMA, .block_num = 2U, .channel_num = cpuss_0_dmac_0_chan_0_CHANNEL, }; #endif //defined (CY_USING_HAL) void reserve_cycfg_dmas(void) { #if defined (CY_USING_HAL) cyhal_hwmgr_reserve(&cpuss_0_dmac_0_chan_0_obj); #endif //defined (CY_USING_HAL) }
The three GPIOs P10_0..2 are configured as:
const cy_stc_gpio_pin_config_t CYBSP_A0_config = { .outVal = 0, .driveMode = CY_GPIO_DM_STRONG_IN_OFF, .hsiom = CYBSP_A0_HSIOM, .intEdge = CY_GPIO_INTR_DISABLE, .intMask = 0UL, .vtrip = CY_GPIO_VTRIP_CMOS, .slewRate = CY_GPIO_SLEW_FAST, .driveSel = CY_GPIO_DRIVE_1_2, .vregEn = 0UL, .ibufMode = 0UL, .vtripSel = 0UL, .vrefSel = 0UL, .vohSel = 0UL, };
Then in the main.c I set the destination and source:
#include "cyhal.h" #include "cybsp.h" #define scanline_dma_HW cpuss_0_dmac_0_chan_0_HW #define scanline_dma_descriptor cpuss_0_dmac_0_chan_0_Descriptor_0 #define scanline_dma_descriptor_cfg cpuss_0_dmac_0_chan_0_Descriptor_0_config #define scanline_dma_CH cpuss_0_dmac_0_chan_0_CHANNEL #define scanline_dma_CH_cfg cpuss_0_dmac_0_chan_0_channelConfig uint32_t pix = 0x5; GPIO_PRT_Type* scanline_rgb_port = GPIO_PRT10; int main(void) { cy_rslt_t result; #if defined (CY_DEVICE_SECURE) cyhal_wdt_t wdt_obj; /* Clear watchdog timer so that it doesn't trigger a reset */ result = cyhal_wdt_init(&wdt_obj, cyhal_wdt_get_max_timeout_ms()); CY_ASSERT(CY_RSLT_SUCCESS == result); cyhal_wdt_free(&wdt_obj); #endif /* Initialize the device and board peripherals */ result = cybsp_init(); /* Board init failed. Stop program execution */ if (result != CY_RSLT_SUCCESS) { CY_ASSERT(0); } /* Enable global interrupts */ __enable_irq(); Cy_DMAC_Descriptor_Init(&scanline_dma_descriptor, &scanline_dma_descriptor_cfg); Cy_DMAC_Descriptor_SetSrcAddress(&scanline_dma_descriptor, (void*)&pix); Cy_DMAC_Descriptor_SetDstAddress(&scanline_dma_descriptor, (void*)(scanline_rgb_port->OUT)); Cy_DMAC_Channel_Init(scanline_dma_HW, scanline_dma_CH, &scanline_dma_CH_cfg); Cy_DMAC_Channel_SetDescriptor(scanline_dma_HW, scanline_dma_CH, &scanline_dma_descriptor); Cy_DMAC_Channel_Enable(scanline_dma_HW, scanline_dma_CH); Cy_DMAC_Enable(scanline_dma_HW); for (;;) { } }
My Logic Analyzer should show signals 0 and 2 pulsing from low to high but nothing happens, I can't understand if the transfer doesn't start, or if the GPIO port is not correct for output.
I haven't been lucky in finding an example of the use of DMA on GPIOs, so I am asking here
Thank you.