/* * Copyright (c) 2016, Freescale Semiconductor, Inc. * Copyright 2016-2017 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include "pin_mux.h" #include "board.h" #include "fsl_debug_console.h" #include "fsl_dma.h" #include "fsl_inputmux.h" #include #include "fsl_power.h" #if 0 // Default codes #else // Changed codes #include "fsl_pint.h" #endif /******************************************************************************* * Definitions ******************************************************************************/ #define DEMO_DMA_CHANNEL1 1 #define DEMO_DMA_CHANNEL0 0 #define DEMO_DMA_CHANNEL2 2 #define DEMO_DMA_CHANNEL_TRIGGER_INPUT kINPUTMUX_Otrig0ToDma0 #define DEMO_DMA_CHANNEL_TRIGGER_OUTPUT0 kINPUTMUX_Dma0Hash0TxTrigoutToTriginChannels #if 0 // Default codes #else // Changed codes #define DEMO_DMA_CHANNEL_TRIGGER_OUTPUT1 (1U + (DMA0_OTRIG_INMUX0 << PMUX_SHIFT)) #define DEMO_DMA_CHANNEL_TRIGGER_OUTPUT2 kINPUTMUX_Dma0HsLspiRxTrigoutToTriginChannels #endif #define BUFF_LENGTH 4U #define DMA_DESCRIPTOR_NUM 3U #if 0 // Default codes #define DEST_BUFFER_LENGTH 16U #else // Changed codes #define SRC_BUFFER_LENGTH 1024U #define DEST_BUFFER_LENGTH (SRC_BUFFER_LENGTH * 6U) #endif /******************************************************************************* * Prototypes ******************************************************************************/ /******************************************************************************* * Variables ******************************************************************************/ static dma_handle_t s_DMA_Handle0; static dma_handle_t s_DMA_Handle1; static dma_handle_t s_DMA_Handle2; static volatile bool s_Transfer0_Done = false; static volatile bool s_Transfer1_Done = false; static volatile bool s_Transfer2_Done = false; #if 0 // Default codes DMA_ALLOCATE_LINK_DESCRIPTORS(s_dma_table1, 1U); DMA_ALLOCATE_DATA_TRANSFER_BUFFER(static uint32_t s_srcBuffer0[BUFF_LENGTH], sizeof(uint32_t)) = {1, 2, 3, 4}; DMA_ALLOCATE_DATA_TRANSFER_BUFFER(static uint32_t s_srcBuffer1[BUFF_LENGTH], sizeof(uint32_t)) = {11, 22, 33, 44}; DMA_ALLOCATE_DATA_TRANSFER_BUFFER(static uint32_t s_srcBuffer2[BUFF_LENGTH], sizeof(uint32_t)) = {111, 222, 333, 444}; DMA_ALLOCATE_DATA_TRANSFER_BUFFER(static uint32_t s_srcBuffer3[BUFF_LENGTH], sizeof(uint32_t)) = {1111, 2222, 3333, 4444}; DMA_ALLOCATE_DATA_TRANSFER_BUFFER(static uint32_t s_destBuffer[BUFF_LENGTH * 4], sizeof(uint32_t)) = {0x00}; #else // Changed codes DMA_ALLOCATE_LINK_DESCRIPTORS(s_dma_table1, 3U); DMA_ALLOCATE_DATA_TRANSFER_BUFFER(static uint32_t s_srcBuffer0[SRC_BUFFER_LENGTH], sizeof(uint32_t)); DMA_ALLOCATE_DATA_TRANSFER_BUFFER(static uint32_t s_srcBuffer1[SRC_BUFFER_LENGTH], sizeof(uint32_t)); DMA_ALLOCATE_DATA_TRANSFER_BUFFER(static uint32_t s_srcBuffer2[SRC_BUFFER_LENGTH], sizeof(uint32_t)); DMA_ALLOCATE_DATA_TRANSFER_BUFFER(static uint32_t s_srcBuffer3[SRC_BUFFER_LENGTH], sizeof(uint32_t)); DMA_ALLOCATE_DATA_TRANSFER_BUFFER(static uint32_t s_srcBuffer4[SRC_BUFFER_LENGTH], sizeof(uint32_t)); DMA_ALLOCATE_DATA_TRANSFER_BUFFER(static uint32_t s_srcBuffer5[SRC_BUFFER_LENGTH], sizeof(uint32_t)); DMA_ALLOCATE_DATA_TRANSFER_BUFFER(static uint32_t s_destBuffer[DEST_BUFFER_LENGTH], sizeof(uint32_t)) = {0x00}; #endif static dma_channel_trigger_t s_channelTrigger = { .type = kDMA_FallingEdgeTrigger, #if 1 // Default codes .burst = kDMA_SingleTransfer, #else // Changed codes .burst = kDMA_EdgeBurstTransfer1024, #endif .wrap = kDMA_NoWrap, }; /******************************************************************************* * Code ******************************************************************************/ #if 0 // Default codes #else // Changed codes /*! * @brief Call back for PINT Pin interrupt 0-7. */ void pint_intr_callback(pint_pin_int_t pintr, uint32_t pmatch_status) { PRINTF("\r\nPINT Pin Interrupt %d event detected.", pintr); } #endif /* User callback function for DMA transfer. */ void DMA0_Callback(dma_handle_t *handle, void *param, bool transferDone, uint32_t tcds) { #if 0 // Default codes if (transferDone) #else // Changed codes if (transferDone && (tcds == kDMA_IntB)) #endif { s_Transfer0_Done = true; } } /* User callback function for DMA transfer. */ void DMA1_Callback(dma_handle_t *handle, void *param, bool transferDone, uint32_t tcds) { #if 0 // Default codes if (transferDone) #else // Changed codes if (transferDone && (tcds == kDMA_IntB)) #endif { s_Transfer1_Done = true; } } /* User callback function for DMA transfer. */ void DMA2_Callback(dma_handle_t *handle, void *param, bool transferDone, uint32_t tcds) { #if 0 // Default codes if (transferDone) #else // Changed codes if (transferDone && (tcds == kDMA_IntB)) #endif { s_Transfer2_Done = true; } } /*! * @brief Main function */ int main(void) { uint32_t i = 0; /* set BOD VBAT level to 1.65V */ POWER_SetBodVbatLevel(kPOWER_BodVbatLevel1650mv, kPOWER_BodHystLevel50mv, false); /* attach 12 MHz clock to FLEXCOMM0 (debug console) */ CLOCK_AttachClk(kFRO12M_to_FLEXCOMM0); BOARD_InitBootPins(); BOARD_InitBootClocks(); BOARD_InitDebugConsole(); #if 0 // Default codes #else // Changed codes for (i = 0; i < SRC_BUFFER_LENGTH; i++) { s_srcBuffer0[i] = i + 1; s_srcBuffer1[i] = SRC_BUFFER_LENGTH + i + 1; s_srcBuffer2[i] = (SRC_BUFFER_LENGTH * 2) + i + 1; s_srcBuffer3[i] = (SRC_BUFFER_LENGTH * 3) + i + 1; s_srcBuffer4[i] = (SRC_BUFFER_LENGTH * 4) + i + 1; s_srcBuffer5[i] = (SRC_BUFFER_LENGTH * 5) + i + 1; } #endif /* Print source buffer */ PRINTF("DMA channel chain example begin.\r\n"); PRINTF("Destination Buffer:\r\n"); for (i = 0; i < DEST_BUFFER_LENGTH; i++) { #if 0 // Default codes #else // Changed codes if (i > 0) { if (i % SRC_BUFFER_LENGTH == 0) { PRINTF("\r\n"); PRINTF("\r\n"); } else if (i % 8 == 0) { PRINTF("\r\n"); } } #endif PRINTF("%d\t", s_destBuffer[i]); } DMA_Init(DMA0); INPUTMUX_Init(INPUTMUX); #if 0 // Default codes INPUTMUX_AttachSignal(INPUTMUX, DEMO_DMA_CHANNEL1, DEMO_DMA_CHANNEL_TRIGGER_INPUT); INPUTMUX_AttachSignal(INPUTMUX, DEMO_DMA_CHANNEL2, DEMO_DMA_CHANNEL_TRIGGER_INPUT); INPUTMUX_AttachSignal(INPUTMUX, 0, DEMO_DMA_CHANNEL_TRIGGER_OUTPUT0); INPUTMUX_AttachSignal(INPUTMUX, DEMO_DMA_CHANNEL0, DEMO_DMA_CHANNEL_TRIGGER_INPUT); #else // Changed codes INPUTMUX_AttachSignal(INPUTMUX, kPINT_PinInt0, kINPUTMUX_GpioPort1Pin9ToPintsel); INPUTMUX_AttachSignal(INPUTMUX, DEMO_DMA_CHANNEL0, kINPUTMUX_PinInt0ToDma0); INPUTMUX_AttachSignal(INPUTMUX, 0, DEMO_DMA_CHANNEL_TRIGGER_OUTPUT0); INPUTMUX_AttachSignal(INPUTMUX, DEMO_DMA_CHANNEL1, kINPUTMUX_Otrig0ToDma0); INPUTMUX_AttachSignal(INPUTMUX, 1, DEMO_DMA_CHANNEL_TRIGGER_OUTPUT1); INPUTMUX_AttachSignal(INPUTMUX, DEMO_DMA_CHANNEL2, kINPUTMUX_Otrig1ToDma0); /* Turnoff clock to inputmux to save power. Clock is only needed to make changes */ INPUTMUX_Deinit(INPUTMUX); /* Initialize PINT */ PINT_Init(PINT); /* Setup Pin Interrupt 2 for falling edge */ PINT_PinInterruptConfig(PINT, kPINT_PinInt0, kPINT_PinIntEnableFallEdge, pint_intr_callback); /* Enable callbacks for PINT2 by Index */ PINT_EnableCallbackByIndex(PINT, kPINT_PinInt0); #endif /* configuration for channel0 */ DMA_CreateHandle(&s_DMA_Handle0, DMA0, DEMO_DMA_CHANNEL0); DMA_EnableChannel(DMA0, DEMO_DMA_CHANNEL0); DMA_SetCallback(&s_DMA_Handle0, DMA0_Callback, NULL); /* configuration for channel1 */ DMA_CreateHandle(&s_DMA_Handle1, DMA0, DEMO_DMA_CHANNEL1); DMA_EnableChannel(DMA0, DEMO_DMA_CHANNEL1); DMA_SetCallback(&s_DMA_Handle1, DMA1_Callback, NULL); /* configuration for channel2 */ DMA_CreateHandle(&s_DMA_Handle2, DMA0, DEMO_DMA_CHANNEL2); DMA_EnableChannel(DMA0, DEMO_DMA_CHANNEL2); DMA_SetCallback(&s_DMA_Handle2, DMA2_Callback, NULL); /* DMA channel0 trigger configurations */ DMA_SetChannelConfig(DMA0, DEMO_DMA_CHANNEL0, &s_channelTrigger, false); DMA_SetChannelConfig(DMA0, DEMO_DMA_CHANNEL1, &s_channelTrigger, false); DMA_SetChannelConfig(DMA0, DEMO_DMA_CHANNEL2, &s_channelTrigger, false); #if 0 // Default codes DMA_SetupDescriptor(&(s_dma_table1[0]), DMA_CHANNEL_XFER(false, false, false, true, 4U, kDMA_AddressInterleave1xWidth, kDMA_AddressInterleave1xWidth, 16U), s_srcBuffer3, &s_destBuffer[12], NULL); /* submit channel0 transfer parameter */ DMA_SubmitChannelTransferParameter(&s_DMA_Handle0, DMA_CHANNEL_XFER(true, true, true, false, 4U, kDMA_AddressInterleave1xWidth, kDMA_AddressInterleave1xWidth, 16U), s_srcBuffer0, &s_destBuffer[0], &(s_dma_table1[0])); /* submit channel1 transfer parameter */ DMA_SubmitChannelTransferParameter(&s_DMA_Handle1, DMA_CHANNEL_XFER(false, false, true, false, 4, kDMA_AddressInterleave1xWidth, kDMA_AddressInterleave1xWidth, 16U), s_srcBuffer1, &s_destBuffer[4], NULL); /* submit channel2 transfer parameter */ DMA_SubmitChannelTransferParameter(&s_DMA_Handle2, DMA_CHANNEL_XFER(false, false, true, false, 4, kDMA_AddressInterleave1xWidth, kDMA_AddressInterleave1xWidth, 16U), s_srcBuffer2, &s_destBuffer[8], NULL); /* software trigger channl0 transfer start firstly */ DMA_DoChannelSoftwareTrigger(DMA0, DEMO_DMA_CHANNEL0); #else // Changed codes DMA_SetupDescriptor(&(s_dma_table1[0]), DMA_CHANNEL_XFER(false, false, false, true, sizeof(s_srcBuffer3[0]), kDMA_AddressInterleave1xWidth, kDMA_AddressInterleave1xWidth, sizeof(s_srcBuffer3)), s_srcBuffer3, &s_destBuffer[SRC_BUFFER_LENGTH * 3], NULL); /* submit channel0 transfer parameter */ DMA_SubmitChannelTransferParameter(&s_DMA_Handle0, DMA_CHANNEL_XFER(true, true, true, false, sizeof(s_srcBuffer0[0]), kDMA_AddressInterleave1xWidth, kDMA_AddressInterleave1xWidth, sizeof(s_srcBuffer0)), s_srcBuffer0, &s_destBuffer[0], &(s_dma_table1[0])); DMA_SetupDescriptor(&(s_dma_table1[1]), DMA_CHANNEL_XFER(false, false, false, true, sizeof(s_srcBuffer4[0]), kDMA_AddressInterleave1xWidth, kDMA_AddressInterleave1xWidth, sizeof(s_srcBuffer4)), s_srcBuffer4, &s_destBuffer[SRC_BUFFER_LENGTH * 4], NULL); /* submit channel1 transfer parameter */ DMA_SubmitChannelTransferParameter(&s_DMA_Handle1, DMA_CHANNEL_XFER(true, true, true, false, sizeof(s_srcBuffer1[0]), kDMA_AddressInterleave1xWidth, kDMA_AddressInterleave1xWidth, sizeof(s_srcBuffer1)), s_srcBuffer1, &s_destBuffer[SRC_BUFFER_LENGTH], &(s_dma_table1[1])); DMA_SetupDescriptor(&(s_dma_table1[2]), DMA_CHANNEL_XFER(false, false, false, true, sizeof(s_srcBuffer5[0]), kDMA_AddressInterleave1xWidth, kDMA_AddressInterleave1xWidth, sizeof(s_srcBuffer5)), s_srcBuffer5, &s_destBuffer[SRC_BUFFER_LENGTH * 5], NULL); /* submit channel2 transfer parameter */ DMA_SubmitChannelTransferParameter(&s_DMA_Handle2, DMA_CHANNEL_XFER(true, true, true, false, sizeof(s_srcBuffer2[0]), kDMA_AddressInterleave1xWidth, kDMA_AddressInterleave1xWidth, sizeof(s_srcBuffer2)), s_srcBuffer2, &s_destBuffer[SRC_BUFFER_LENGTH * 2], &(s_dma_table1[2])); #endif /* Wait channel1 DMA transfer finish */ while (s_Transfer1_Done != true) { } /* Wait channel2 DMA transfer finish */ while (s_Transfer2_Done != true) { } /* Wait channel0 DMA transfer finish */ while (s_Transfer0_Done != true) { } /* Print destination buffer */ PRINTF("\r\nDMA channel chain example finish.\r\n"); PRINTF("Destination Buffer:\r\n"); for (i = 0; i < DEST_BUFFER_LENGTH; i++) { #if 0 // Default codes #else // Changed codes if (i > 0) { if (i % SRC_BUFFER_LENGTH == 0) { PRINTF("\r\n"); PRINTF("\r\n"); } else if (i % 8 == 0) { PRINTF("\r\n"); } } #endif PRINTF("%d\t", s_destBuffer[i]); } while (1) { } }