/* * Copyright 2017 NXP * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include "fsl_device_registers.h" #include "fsl_debug_console.h" #include "fsl_lpspi.h" #include "pin_mux.h" #include "board.h" #include "fsl_lpspi_edma.h" #if defined(FSL_FEATURE_SOC_DMAMUX_COUNT) && FSL_FEATURE_SOC_DMAMUX_COUNT #include "fsl_dmamux.h" #endif #include "fsl_common.h" /******************************************************************************* * Definitions ******************************************************************************/ /* Slave related */ #define EXAMPLE_LPSPI_SLAVE_BASEADDR (LPSPI1) #define EXAMPLE_LPSPI_SLAVE_DMA_MUX_BASE (DMAMUX0) #define EXAMPLE_LPSPI_SLAVE_DMA_RX_REQUEST_SOURCE kDmaRequestMuxLPSPI1Rx #define EXAMPLE_LPSPI_SLAVE_DMA_TX_REQUEST_SOURCE kDmaRequestMuxLPSPI1Tx #define EXAMPLE_LPSPI_SLAVE_DMA_BASE (DMA0) #define EXAMPLE_LPSPI_SLAVE_DMA_RX_CHANNEL 0U #define EXAMPLE_LPSPI_SLAVE_DMA_TX_CHANNEL 1U #define EXAMPLE_LPSPI_SLAVE_PCS_FOR_INIT (kLPSPI_Pcs0) #define EXAMPLE_LPSPI_SLAVE_PCS_FOR_TRANSFER (kLPSPI_SlavePcs0) #define TRANSFER_SIZE 64 /* Transfer dataSize */ /******************************************************************************* * Prototypes ******************************************************************************/ /* LPSPI user callback */ void LPSPI_SlaveUserCallback(LPSPI_Type *base, lpspi_slave_edma_handle_t *handle, status_t status, void *userData); /******************************************************************************* * Variables ******************************************************************************/ AT_NONCACHEABLE_SECTION_INIT(uint8_t slaveRxData[TRANSFER_SIZE]) = {0}; AT_NONCACHEABLE_SECTION_INIT(uint8_t slaveTxData[TRANSFER_SIZE]) = {0}; AT_NONCACHEABLE_SECTION(lpspi_slave_edma_handle_t g_s_edma_handle); edma_handle_t lpspiEdmaSlaveRxRegToRxDataHandle; edma_handle_t lpspiEdmaSlaveTxDataToTxRegHandle; volatile bool isTransferCompleted = false; /******************************************************************************* * Code ******************************************************************************/ void LPSPI_SlaveUserCallback(LPSPI_Type *base, lpspi_slave_edma_handle_t *handle, status_t status, void *userData) { isTransferCompleted = true; } /*! * @brief Main function */ int main(void) { uint32_t i; uint32_t loopCounter = 0,errorCounter = 0; lpspi_slave_config_t slaveConfig; lpspi_transfer_t slaveXfer; edma_config_t userConfig; clock_root_config_t rootCfg = {0}; BOARD_ConfigMPU(); BOARD_InitPins(); /*Change pins conifg,Rate Field: Fast Slew Rate*/ BOARD_BootClockRUN(); BOARD_InitDebugConsole(); /* Configure LPSPI1 using OSC_RC_48M_DIV2 */ rootCfg.mux = kCLOCK_LPSPI1_ClockRoot_MuxOscRc48MDiv2; rootCfg.div = 2; CLOCK_SetRootClock(kCLOCK_Root_Lpspi1, &rootCfg); PRINTF("LPSPI board to board edma example.\r\n"); /*DMA Mux setting and EDMA init*/ #if defined(FSL_FEATURE_SOC_DMAMUX_COUNT) && FSL_FEATURE_SOC_DMAMUX_COUNT /* DMA MUX init*/ DMAMUX_Init(EXAMPLE_LPSPI_SLAVE_DMA_MUX_BASE); DMAMUX_SetSource(EXAMPLE_LPSPI_SLAVE_DMA_MUX_BASE, EXAMPLE_LPSPI_SLAVE_DMA_RX_CHANNEL, EXAMPLE_LPSPI_SLAVE_DMA_RX_REQUEST_SOURCE); DMAMUX_EnableChannel(EXAMPLE_LPSPI_SLAVE_DMA_MUX_BASE, EXAMPLE_LPSPI_SLAVE_DMA_RX_CHANNEL); DMAMUX_SetSource(EXAMPLE_LPSPI_SLAVE_DMA_MUX_BASE, EXAMPLE_LPSPI_SLAVE_DMA_TX_CHANNEL, EXAMPLE_LPSPI_SLAVE_DMA_TX_REQUEST_SOURCE); DMAMUX_EnableChannel(EXAMPLE_LPSPI_SLAVE_DMA_MUX_BASE, EXAMPLE_LPSPI_SLAVE_DMA_TX_CHANNEL); #endif /* EDMA init*/ /* * userConfig.enableRoundRobinArbitration = false; * userConfig.enableHaltOnError = true; * userConfig.enableContinuousLinkMode = false; * userConfig.enableDebugMode = false; */ EDMA_GetDefaultConfig(&userConfig); EDMA_Init(EXAMPLE_LPSPI_SLAVE_DMA_BASE, &userConfig); /*Slave config*/ LPSPI_SlaveGetDefaultConfig(&slaveConfig); slaveConfig.whichPcs = EXAMPLE_LPSPI_SLAVE_PCS_FOR_INIT; slaveConfig.cpol = kLPSPI_ClockPolarityActiveHigh; slaveConfig.cpha = kLPSPI_ClockPhaseFirstEdge; LPSPI_SlaveInit(EXAMPLE_LPSPI_SLAVE_BASEADDR, &slaveConfig); /*Set up slave EDMA. */ memset(&(lpspiEdmaSlaveRxRegToRxDataHandle), 0, sizeof(lpspiEdmaSlaveRxRegToRxDataHandle)); memset(&(lpspiEdmaSlaveTxDataToTxRegHandle), 0, sizeof(lpspiEdmaSlaveTxDataToTxRegHandle)); EDMA_CreateHandle(&(lpspiEdmaSlaveRxRegToRxDataHandle), EXAMPLE_LPSPI_SLAVE_DMA_BASE, EXAMPLE_LPSPI_SLAVE_DMA_RX_CHANNEL); EDMA_CreateHandle(&(lpspiEdmaSlaveTxDataToTxRegHandle), EXAMPLE_LPSPI_SLAVE_DMA_BASE, EXAMPLE_LPSPI_SLAVE_DMA_TX_CHANNEL); #if defined(FSL_FEATURE_EDMA_HAS_CHANNEL_MUX) && FSL_FEATURE_EDMA_HAS_CHANNEL_MUX EDMA_SetChannelMux(EXAMPLE_LPSPI_SLAVE_DMA_BASE, EXAMPLE_LPSPI_SLAVE_DMA_TX_CHANNEL, DEMO_LPSPI_TRANSMIT_EDMA_CHANNEL); EDMA_SetChannelMux(EXAMPLE_LPSPI_SLAVE_DMA_BASE, EXAMPLE_LPSPI_SLAVE_DMA_RX_CHANNEL, DEMO_LPSPI_RECEIVE_EDMA_CHANNEL); #endif LPSPI_SlaveTransferCreateHandleEDMA(EXAMPLE_LPSPI_SLAVE_BASEADDR, &g_s_edma_handle, LPSPI_SlaveUserCallback, NULL, &lpspiEdmaSlaveRxRegToRxDataHandle, &lpspiEdmaSlaveTxDataToTxRegHandle); /* Set up the transfer data */ for (i = 0U; i < TRANSFER_SIZE; i++) { slaveTxData[i] = i % 256U; slaveRxData[i] = 0U; } slaveXfer.txData = slaveTxData; slaveXfer.rxData = NULL; slaveXfer.dataSize = TRANSFER_SIZE; slaveXfer.configFlags = EXAMPLE_LPSPI_SLAVE_PCS_FOR_TRANSFER | kLPSPI_SlaveByteSwap; while (1) { LPSPI_SlaveTransferEDMA(EXAMPLE_LPSPI_SLAVE_BASEADDR, &g_s_edma_handle, &slaveXfer); while (!isTransferCompleted) { } isTransferCompleted = false; loopCounter++; #if 0 if(memcmp(slaveTxData, slaveRxData, sizeof(slaveTxData))) { PRINTF("LPSPI Slave Transfer data error\r\n"); PRINTF("errorCounter %d loopCounter %d\r\n", ++errorCounter, loopCounter); } #endif } }