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.
