added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
<>
Date:
Fri Sep 02 15:07:44 2016 +0100
Revision:
144:ef7eb2e8f9f7
This updates the lib to the mbed lib v125

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 144:ef7eb2e8f9f7 1 /*
<> 144:ef7eb2e8f9f7 2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
<> 144:ef7eb2e8f9f7 3 * All rights reserved.
<> 144:ef7eb2e8f9f7 4 *
<> 144:ef7eb2e8f9f7 5 * Redistribution and use in source and binary forms, with or without modification,
<> 144:ef7eb2e8f9f7 6 * are permitted provided that the following conditions are met:
<> 144:ef7eb2e8f9f7 7 *
<> 144:ef7eb2e8f9f7 8 * o Redistributions of source code must retain the above copyright notice, this list
<> 144:ef7eb2e8f9f7 9 * of conditions and the following disclaimer.
<> 144:ef7eb2e8f9f7 10 *
<> 144:ef7eb2e8f9f7 11 * o Redistributions in binary form must reproduce the above copyright notice, this
<> 144:ef7eb2e8f9f7 12 * list of conditions and the following disclaimer in the documentation and/or
<> 144:ef7eb2e8f9f7 13 * other materials provided with the distribution.
<> 144:ef7eb2e8f9f7 14 *
<> 144:ef7eb2e8f9f7 15 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
<> 144:ef7eb2e8f9f7 16 * contributors may be used to endorse or promote products derived from this
<> 144:ef7eb2e8f9f7 17 * software without specific prior written permission.
<> 144:ef7eb2e8f9f7 18 *
<> 144:ef7eb2e8f9f7 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
<> 144:ef7eb2e8f9f7 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
<> 144:ef7eb2e8f9f7 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
<> 144:ef7eb2e8f9f7 22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
<> 144:ef7eb2e8f9f7 23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
<> 144:ef7eb2e8f9f7 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
<> 144:ef7eb2e8f9f7 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
<> 144:ef7eb2e8f9f7 26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
<> 144:ef7eb2e8f9f7 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
<> 144:ef7eb2e8f9f7 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<> 144:ef7eb2e8f9f7 29 */
<> 144:ef7eb2e8f9f7 30
<> 144:ef7eb2e8f9f7 31 #include "fsl_dspi_edma.h"
<> 144:ef7eb2e8f9f7 32
<> 144:ef7eb2e8f9f7 33 /***********************************************************************************************************************
<> 144:ef7eb2e8f9f7 34 * Definitons
<> 144:ef7eb2e8f9f7 35 ***********************************************************************************************************************/
<> 144:ef7eb2e8f9f7 36
<> 144:ef7eb2e8f9f7 37 /*!
<> 144:ef7eb2e8f9f7 38 * @brief Structure definition for dspi_master_edma_private_handle_t. The structure is private.
<> 144:ef7eb2e8f9f7 39 */
<> 144:ef7eb2e8f9f7 40 typedef struct _dspi_master_edma_private_handle
<> 144:ef7eb2e8f9f7 41 {
<> 144:ef7eb2e8f9f7 42 SPI_Type *base; /*!< DSPI peripheral base address. */
<> 144:ef7eb2e8f9f7 43 dspi_master_edma_handle_t *handle; /*!< dspi_master_edma_handle_t handle */
<> 144:ef7eb2e8f9f7 44 } dspi_master_edma_private_handle_t;
<> 144:ef7eb2e8f9f7 45
<> 144:ef7eb2e8f9f7 46 /*!
<> 144:ef7eb2e8f9f7 47 * @brief Structure definition for dspi_slave_edma_private_handle_t. The structure is private.
<> 144:ef7eb2e8f9f7 48 */
<> 144:ef7eb2e8f9f7 49 typedef struct _dspi_slave_edma_private_handle
<> 144:ef7eb2e8f9f7 50 {
<> 144:ef7eb2e8f9f7 51 SPI_Type *base; /*!< DSPI peripheral base address. */
<> 144:ef7eb2e8f9f7 52 dspi_slave_edma_handle_t *handle; /*!< dspi_master_edma_handle_t handle */
<> 144:ef7eb2e8f9f7 53 } dspi_slave_edma_private_handle_t;
<> 144:ef7eb2e8f9f7 54
<> 144:ef7eb2e8f9f7 55 /***********************************************************************************************************************
<> 144:ef7eb2e8f9f7 56 * Prototypes
<> 144:ef7eb2e8f9f7 57 ***********************************************************************************************************************/
<> 144:ef7eb2e8f9f7 58 /*!
<> 144:ef7eb2e8f9f7 59 * @brief EDMA_DspiMasterCallback after the DSPI master transfer completed by using EDMA.
<> 144:ef7eb2e8f9f7 60 * This is not a public API as it is called from other driver functions.
<> 144:ef7eb2e8f9f7 61 */
<> 144:ef7eb2e8f9f7 62 static void EDMA_DspiMasterCallback(edma_handle_t *edmaHandle,
<> 144:ef7eb2e8f9f7 63 void *g_dspiEdmaPrivateHandle,
<> 144:ef7eb2e8f9f7 64 bool transferDone,
<> 144:ef7eb2e8f9f7 65 uint32_t tcds);
<> 144:ef7eb2e8f9f7 66
<> 144:ef7eb2e8f9f7 67 /*!
<> 144:ef7eb2e8f9f7 68 * @brief EDMA_DspiSlaveCallback after the DSPI slave transfer completed by using EDMA.
<> 144:ef7eb2e8f9f7 69 * This is not a public API as it is called from other driver functions.
<> 144:ef7eb2e8f9f7 70 */
<> 144:ef7eb2e8f9f7 71 static void EDMA_DspiSlaveCallback(edma_handle_t *edmaHandle,
<> 144:ef7eb2e8f9f7 72 void *g_dspiEdmaPrivateHandle,
<> 144:ef7eb2e8f9f7 73 bool transferDone,
<> 144:ef7eb2e8f9f7 74 uint32_t tcds);
<> 144:ef7eb2e8f9f7 75 /*!
<> 144:ef7eb2e8f9f7 76 * @brief Get instance number for DSPI module.
<> 144:ef7eb2e8f9f7 77 *
<> 144:ef7eb2e8f9f7 78 * This is not a public API and it's extern from fsl_dspi.c.
<> 144:ef7eb2e8f9f7 79 *
<> 144:ef7eb2e8f9f7 80 * @param base DSPI peripheral base address
<> 144:ef7eb2e8f9f7 81 */
<> 144:ef7eb2e8f9f7 82 extern uint32_t DSPI_GetInstance(SPI_Type *base);
<> 144:ef7eb2e8f9f7 83
<> 144:ef7eb2e8f9f7 84 /***********************************************************************************************************************
<> 144:ef7eb2e8f9f7 85 * Variables
<> 144:ef7eb2e8f9f7 86 ***********************************************************************************************************************/
<> 144:ef7eb2e8f9f7 87
<> 144:ef7eb2e8f9f7 88 /*! @brief Pointers to dspi edma handles for each instance. */
<> 144:ef7eb2e8f9f7 89 static dspi_master_edma_private_handle_t s_dspiMasterEdmaPrivateHandle[FSL_FEATURE_SOC_DSPI_COUNT];
<> 144:ef7eb2e8f9f7 90 static dspi_slave_edma_private_handle_t s_dspiSlaveEdmaPrivateHandle[FSL_FEATURE_SOC_DSPI_COUNT];
<> 144:ef7eb2e8f9f7 91
<> 144:ef7eb2e8f9f7 92 /***********************************************************************************************************************
<> 144:ef7eb2e8f9f7 93 * Code
<> 144:ef7eb2e8f9f7 94 ***********************************************************************************************************************/
<> 144:ef7eb2e8f9f7 95
<> 144:ef7eb2e8f9f7 96 void DSPI_MasterTransferCreateHandleEDMA(SPI_Type *base,
<> 144:ef7eb2e8f9f7 97 dspi_master_edma_handle_t *handle,
<> 144:ef7eb2e8f9f7 98 dspi_master_edma_transfer_callback_t callback,
<> 144:ef7eb2e8f9f7 99 void *userData,
<> 144:ef7eb2e8f9f7 100 edma_handle_t *edmaRxRegToRxDataHandle,
<> 144:ef7eb2e8f9f7 101 edma_handle_t *edmaTxDataToIntermediaryHandle,
<> 144:ef7eb2e8f9f7 102 edma_handle_t *edmaIntermediaryToTxRegHandle)
<> 144:ef7eb2e8f9f7 103 {
<> 144:ef7eb2e8f9f7 104 assert(handle);
<> 144:ef7eb2e8f9f7 105
<> 144:ef7eb2e8f9f7 106 /* Zero the handle. */
<> 144:ef7eb2e8f9f7 107 memset(handle, 0, sizeof(*handle));
<> 144:ef7eb2e8f9f7 108
<> 144:ef7eb2e8f9f7 109 uint32_t instance = DSPI_GetInstance(base);
<> 144:ef7eb2e8f9f7 110
<> 144:ef7eb2e8f9f7 111 s_dspiMasterEdmaPrivateHandle[instance].base = base;
<> 144:ef7eb2e8f9f7 112 s_dspiMasterEdmaPrivateHandle[instance].handle = handle;
<> 144:ef7eb2e8f9f7 113
<> 144:ef7eb2e8f9f7 114 handle->callback = callback;
<> 144:ef7eb2e8f9f7 115 handle->userData = userData;
<> 144:ef7eb2e8f9f7 116
<> 144:ef7eb2e8f9f7 117 handle->edmaRxRegToRxDataHandle = edmaRxRegToRxDataHandle;
<> 144:ef7eb2e8f9f7 118 handle->edmaTxDataToIntermediaryHandle = edmaTxDataToIntermediaryHandle;
<> 144:ef7eb2e8f9f7 119 handle->edmaIntermediaryToTxRegHandle = edmaIntermediaryToTxRegHandle;
<> 144:ef7eb2e8f9f7 120 }
<> 144:ef7eb2e8f9f7 121
<> 144:ef7eb2e8f9f7 122 status_t DSPI_MasterTransferEDMA(SPI_Type *base, dspi_master_edma_handle_t *handle, dspi_transfer_t *transfer)
<> 144:ef7eb2e8f9f7 123 {
<> 144:ef7eb2e8f9f7 124 assert(handle && transfer);
<> 144:ef7eb2e8f9f7 125
<> 144:ef7eb2e8f9f7 126 /* If the transfer count is zero, then return immediately.*/
<> 144:ef7eb2e8f9f7 127 if (transfer->dataSize == 0)
<> 144:ef7eb2e8f9f7 128 {
<> 144:ef7eb2e8f9f7 129 return kStatus_InvalidArgument;
<> 144:ef7eb2e8f9f7 130 }
<> 144:ef7eb2e8f9f7 131
<> 144:ef7eb2e8f9f7 132 /* If both send buffer and receive buffer is null */
<> 144:ef7eb2e8f9f7 133 if ((!(transfer->txData)) && (!(transfer->rxData)))
<> 144:ef7eb2e8f9f7 134 {
<> 144:ef7eb2e8f9f7 135 return kStatus_InvalidArgument;
<> 144:ef7eb2e8f9f7 136 }
<> 144:ef7eb2e8f9f7 137
<> 144:ef7eb2e8f9f7 138 /* Check that we're not busy.*/
<> 144:ef7eb2e8f9f7 139 if (handle->state == kDSPI_Busy)
<> 144:ef7eb2e8f9f7 140 {
<> 144:ef7eb2e8f9f7 141 return kStatus_DSPI_Busy;
<> 144:ef7eb2e8f9f7 142 }
<> 144:ef7eb2e8f9f7 143
<> 144:ef7eb2e8f9f7 144 uint32_t instance = DSPI_GetInstance(base);
<> 144:ef7eb2e8f9f7 145 uint16_t wordToSend = 0;
<> 144:ef7eb2e8f9f7 146 uint8_t dummyData = DSPI_MASTER_DUMMY_DATA;
<> 144:ef7eb2e8f9f7 147 uint8_t dataAlreadyFed = 0;
<> 144:ef7eb2e8f9f7 148 uint8_t dataFedMax = 2;
<> 144:ef7eb2e8f9f7 149
<> 144:ef7eb2e8f9f7 150 uint32_t rxAddr = DSPI_GetRxRegisterAddress(base);
<> 144:ef7eb2e8f9f7 151 uint32_t txAddr = DSPI_MasterGetTxRegisterAddress(base);
<> 144:ef7eb2e8f9f7 152
<> 144:ef7eb2e8f9f7 153 edma_tcd_t *softwareTCD = (edma_tcd_t *)((uint32_t)(&handle->dspiSoftwareTCD[1]) & (~0x1FU));
<> 144:ef7eb2e8f9f7 154
<> 144:ef7eb2e8f9f7 155 edma_transfer_config_t transferConfigA;
<> 144:ef7eb2e8f9f7 156 edma_transfer_config_t transferConfigB;
<> 144:ef7eb2e8f9f7 157 edma_transfer_config_t transferConfigC;
<> 144:ef7eb2e8f9f7 158
<> 144:ef7eb2e8f9f7 159 handle->txBuffIfNull = ((uint32_t)DSPI_MASTER_DUMMY_DATA << 8) | DSPI_MASTER_DUMMY_DATA;
<> 144:ef7eb2e8f9f7 160
<> 144:ef7eb2e8f9f7 161 handle->state = kDSPI_Busy;
<> 144:ef7eb2e8f9f7 162
<> 144:ef7eb2e8f9f7 163 dspi_command_data_config_t commandStruct;
<> 144:ef7eb2e8f9f7 164 DSPI_StopTransfer(base);
<> 144:ef7eb2e8f9f7 165 DSPI_FlushFifo(base, true, true);
<> 144:ef7eb2e8f9f7 166 DSPI_ClearStatusFlags(base, kDSPI_AllStatusFlag);
<> 144:ef7eb2e8f9f7 167
<> 144:ef7eb2e8f9f7 168 commandStruct.whichPcs =
<> 144:ef7eb2e8f9f7 169 (dspi_which_pcs_t)(1U << ((transfer->configFlags & DSPI_MASTER_PCS_MASK) >> DSPI_MASTER_PCS_SHIFT));
<> 144:ef7eb2e8f9f7 170 commandStruct.isEndOfQueue = false;
<> 144:ef7eb2e8f9f7 171 commandStruct.clearTransferCount = false;
<> 144:ef7eb2e8f9f7 172 commandStruct.whichCtar =
<> 144:ef7eb2e8f9f7 173 (dspi_ctar_selection_t)((transfer->configFlags & DSPI_MASTER_CTAR_MASK) >> DSPI_MASTER_CTAR_SHIFT);
<> 144:ef7eb2e8f9f7 174 commandStruct.isPcsContinuous = (bool)(transfer->configFlags & kDSPI_MasterPcsContinuous);
<> 144:ef7eb2e8f9f7 175 handle->command = DSPI_MasterGetFormattedCommand(&(commandStruct));
<> 144:ef7eb2e8f9f7 176
<> 144:ef7eb2e8f9f7 177 commandStruct.isPcsContinuous = (bool)(transfer->configFlags & kDSPI_MasterActiveAfterTransfer);
<> 144:ef7eb2e8f9f7 178 handle->lastCommand = DSPI_MasterGetFormattedCommand(&(commandStruct));
<> 144:ef7eb2e8f9f7 179
<> 144:ef7eb2e8f9f7 180 handle->bitsPerFrame = ((base->CTAR[commandStruct.whichCtar] & SPI_CTAR_FMSZ_MASK) >> SPI_CTAR_FMSZ_SHIFT) + 1;
<> 144:ef7eb2e8f9f7 181
<> 144:ef7eb2e8f9f7 182 if ((base->MCR & SPI_MCR_DIS_RXF_MASK) || (base->MCR & SPI_MCR_DIS_TXF_MASK))
<> 144:ef7eb2e8f9f7 183 {
<> 144:ef7eb2e8f9f7 184 handle->fifoSize = 1;
<> 144:ef7eb2e8f9f7 185 }
<> 144:ef7eb2e8f9f7 186 else
<> 144:ef7eb2e8f9f7 187 {
<> 144:ef7eb2e8f9f7 188 handle->fifoSize = FSL_FEATURE_DSPI_FIFO_SIZEn(base);
<> 144:ef7eb2e8f9f7 189 }
<> 144:ef7eb2e8f9f7 190 handle->txData = transfer->txData;
<> 144:ef7eb2e8f9f7 191 handle->rxData = transfer->rxData;
<> 144:ef7eb2e8f9f7 192 handle->remainingSendByteCount = transfer->dataSize;
<> 144:ef7eb2e8f9f7 193 handle->remainingReceiveByteCount = transfer->dataSize;
<> 144:ef7eb2e8f9f7 194 handle->totalByteCount = transfer->dataSize;
<> 144:ef7eb2e8f9f7 195
<> 144:ef7eb2e8f9f7 196 /* this limits the amount of data we can transfer due to the linked channel.
<> 144:ef7eb2e8f9f7 197 * The max bytes is 511 if 8-bit/frame or 1022 if 16-bit/frame
<> 144:ef7eb2e8f9f7 198 */
<> 144:ef7eb2e8f9f7 199 if (handle->bitsPerFrame > 8)
<> 144:ef7eb2e8f9f7 200 {
<> 144:ef7eb2e8f9f7 201 if (transfer->dataSize > 1022)
<> 144:ef7eb2e8f9f7 202 {
<> 144:ef7eb2e8f9f7 203 return kStatus_DSPI_OutOfRange;
<> 144:ef7eb2e8f9f7 204 }
<> 144:ef7eb2e8f9f7 205 }
<> 144:ef7eb2e8f9f7 206 else
<> 144:ef7eb2e8f9f7 207 {
<> 144:ef7eb2e8f9f7 208 if (transfer->dataSize > 511)
<> 144:ef7eb2e8f9f7 209 {
<> 144:ef7eb2e8f9f7 210 return kStatus_DSPI_OutOfRange;
<> 144:ef7eb2e8f9f7 211 }
<> 144:ef7eb2e8f9f7 212 }
<> 144:ef7eb2e8f9f7 213
<> 144:ef7eb2e8f9f7 214 DSPI_DisableDMA(base, kDSPI_RxDmaEnable | kDSPI_TxDmaEnable);
<> 144:ef7eb2e8f9f7 215
<> 144:ef7eb2e8f9f7 216 EDMA_SetCallback(handle->edmaRxRegToRxDataHandle, EDMA_DspiMasterCallback,
<> 144:ef7eb2e8f9f7 217 &s_dspiMasterEdmaPrivateHandle[instance]);
<> 144:ef7eb2e8f9f7 218
<> 144:ef7eb2e8f9f7 219 handle->isThereExtraByte = false;
<> 144:ef7eb2e8f9f7 220 if (handle->bitsPerFrame > 8)
<> 144:ef7eb2e8f9f7 221 {
<> 144:ef7eb2e8f9f7 222 if (handle->remainingSendByteCount % 2 == 1)
<> 144:ef7eb2e8f9f7 223 {
<> 144:ef7eb2e8f9f7 224 handle->remainingSendByteCount++;
<> 144:ef7eb2e8f9f7 225 handle->remainingReceiveByteCount--;
<> 144:ef7eb2e8f9f7 226 handle->isThereExtraByte = true;
<> 144:ef7eb2e8f9f7 227 }
<> 144:ef7eb2e8f9f7 228 }
<> 144:ef7eb2e8f9f7 229
<> 144:ef7eb2e8f9f7 230 /*If dspi has separate dma request , prepare the first data in "intermediary" .
<> 144:ef7eb2e8f9f7 231 else (dspi has shared dma request) , send first 2 data if there is fifo or send first 1 data if there is no fifo*/
<> 144:ef7eb2e8f9f7 232 if (1 == FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base))
<> 144:ef7eb2e8f9f7 233 {
<> 144:ef7eb2e8f9f7 234 /* For DSPI instances with separate RX/TX DMA requests, we'll use the TX DMA request to
<> 144:ef7eb2e8f9f7 235 * trigger the TX DMA channel and RX DMA request to trigger the RX DMA channel
<> 144:ef7eb2e8f9f7 236 */
<> 144:ef7eb2e8f9f7 237
<> 144:ef7eb2e8f9f7 238 /*Prepare the firt data*/
<> 144:ef7eb2e8f9f7 239 if (handle->bitsPerFrame > 8)
<> 144:ef7eb2e8f9f7 240 {
<> 144:ef7eb2e8f9f7 241 /* If it's the last word */
<> 144:ef7eb2e8f9f7 242 if (handle->remainingSendByteCount <= 2)
<> 144:ef7eb2e8f9f7 243 {
<> 144:ef7eb2e8f9f7 244 if (handle->txData)
<> 144:ef7eb2e8f9f7 245 {
<> 144:ef7eb2e8f9f7 246 if (handle->isThereExtraByte)
<> 144:ef7eb2e8f9f7 247 {
<> 144:ef7eb2e8f9f7 248 wordToSend = *(handle->txData) | ((uint32_t)dummyData << 8);
<> 144:ef7eb2e8f9f7 249 }
<> 144:ef7eb2e8f9f7 250 else
<> 144:ef7eb2e8f9f7 251 {
<> 144:ef7eb2e8f9f7 252 wordToSend = *(handle->txData);
<> 144:ef7eb2e8f9f7 253 ++handle->txData; /* increment to next data byte */
<> 144:ef7eb2e8f9f7 254 wordToSend |= (unsigned)(*(handle->txData)) << 8U;
<> 144:ef7eb2e8f9f7 255 }
<> 144:ef7eb2e8f9f7 256 }
<> 144:ef7eb2e8f9f7 257 else
<> 144:ef7eb2e8f9f7 258 {
<> 144:ef7eb2e8f9f7 259 wordToSend = ((uint32_t)dummyData << 8) | dummyData;
<> 144:ef7eb2e8f9f7 260 }
<> 144:ef7eb2e8f9f7 261 handle->lastCommand = (handle->lastCommand & 0xffff0000U) | wordToSend;
<> 144:ef7eb2e8f9f7 262 }
<> 144:ef7eb2e8f9f7 263 else /* For all words except the last word , frame > 8bits */
<> 144:ef7eb2e8f9f7 264 {
<> 144:ef7eb2e8f9f7 265 if (handle->txData)
<> 144:ef7eb2e8f9f7 266 {
<> 144:ef7eb2e8f9f7 267 wordToSend = *(handle->txData);
<> 144:ef7eb2e8f9f7 268 ++handle->txData; /* increment to next data byte */
<> 144:ef7eb2e8f9f7 269 wordToSend |= (unsigned)(*(handle->txData)) << 8U;
<> 144:ef7eb2e8f9f7 270 ++handle->txData; /* increment to next data byte */
<> 144:ef7eb2e8f9f7 271 }
<> 144:ef7eb2e8f9f7 272 else
<> 144:ef7eb2e8f9f7 273 {
<> 144:ef7eb2e8f9f7 274 wordToSend = ((uint32_t)dummyData << 8) | dummyData;
<> 144:ef7eb2e8f9f7 275 }
<> 144:ef7eb2e8f9f7 276 handle->command = (handle->command & 0xffff0000U) | wordToSend;
<> 144:ef7eb2e8f9f7 277 }
<> 144:ef7eb2e8f9f7 278 }
<> 144:ef7eb2e8f9f7 279 else /* Optimized for bits/frame less than or equal to one byte. */
<> 144:ef7eb2e8f9f7 280 {
<> 144:ef7eb2e8f9f7 281 if (handle->txData)
<> 144:ef7eb2e8f9f7 282 {
<> 144:ef7eb2e8f9f7 283 wordToSend = *(handle->txData);
<> 144:ef7eb2e8f9f7 284 ++handle->txData; /* increment to next data word*/
<> 144:ef7eb2e8f9f7 285 }
<> 144:ef7eb2e8f9f7 286 else
<> 144:ef7eb2e8f9f7 287 {
<> 144:ef7eb2e8f9f7 288 wordToSend = dummyData;
<> 144:ef7eb2e8f9f7 289 }
<> 144:ef7eb2e8f9f7 290
<> 144:ef7eb2e8f9f7 291 if (handle->remainingSendByteCount == 1)
<> 144:ef7eb2e8f9f7 292 {
<> 144:ef7eb2e8f9f7 293 handle->lastCommand = (handle->lastCommand & 0xffff0000U) | wordToSend;
<> 144:ef7eb2e8f9f7 294 }
<> 144:ef7eb2e8f9f7 295 else
<> 144:ef7eb2e8f9f7 296 {
<> 144:ef7eb2e8f9f7 297 handle->command = (handle->command & 0xffff0000U) | wordToSend;
<> 144:ef7eb2e8f9f7 298 }
<> 144:ef7eb2e8f9f7 299 }
<> 144:ef7eb2e8f9f7 300 }
<> 144:ef7eb2e8f9f7 301
<> 144:ef7eb2e8f9f7 302 else /*dspi has shared dma request*/
<> 144:ef7eb2e8f9f7 303
<> 144:ef7eb2e8f9f7 304 {
<> 144:ef7eb2e8f9f7 305 /* For DSPI instances with shared RX/TX DMA requests, we'll use the RX DMA request to
<> 144:ef7eb2e8f9f7 306 * trigger ongoing transfers and will link to the TX DMA channel from the RX DMA channel.
<> 144:ef7eb2e8f9f7 307 */
<> 144:ef7eb2e8f9f7 308
<> 144:ef7eb2e8f9f7 309 /* If bits/frame is greater than one byte */
<> 144:ef7eb2e8f9f7 310 if (handle->bitsPerFrame > 8)
<> 144:ef7eb2e8f9f7 311 {
<> 144:ef7eb2e8f9f7 312 while (DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag)
<> 144:ef7eb2e8f9f7 313 {
<> 144:ef7eb2e8f9f7 314 if (handle->remainingSendByteCount <= 2)
<> 144:ef7eb2e8f9f7 315 {
<> 144:ef7eb2e8f9f7 316 if (handle->txData)
<> 144:ef7eb2e8f9f7 317 {
<> 144:ef7eb2e8f9f7 318 if (handle->isThereExtraByte)
<> 144:ef7eb2e8f9f7 319 {
<> 144:ef7eb2e8f9f7 320 wordToSend = *(handle->txData) | ((uint32_t)dummyData << 8);
<> 144:ef7eb2e8f9f7 321 }
<> 144:ef7eb2e8f9f7 322 else
<> 144:ef7eb2e8f9f7 323 {
<> 144:ef7eb2e8f9f7 324 wordToSend = *(handle->txData);
<> 144:ef7eb2e8f9f7 325 ++handle->txData;
<> 144:ef7eb2e8f9f7 326 wordToSend |= (unsigned)(*(handle->txData)) << 8U;
<> 144:ef7eb2e8f9f7 327 }
<> 144:ef7eb2e8f9f7 328 }
<> 144:ef7eb2e8f9f7 329 else
<> 144:ef7eb2e8f9f7 330 {
<> 144:ef7eb2e8f9f7 331 wordToSend = ((uint32_t)dummyData << 8) | dummyData;
<> 144:ef7eb2e8f9f7 332 ;
<> 144:ef7eb2e8f9f7 333 }
<> 144:ef7eb2e8f9f7 334 handle->remainingSendByteCount = 0;
<> 144:ef7eb2e8f9f7 335 base->PUSHR = (handle->lastCommand & 0xffff0000U) | wordToSend;
<> 144:ef7eb2e8f9f7 336 }
<> 144:ef7eb2e8f9f7 337 /* For all words except the last word */
<> 144:ef7eb2e8f9f7 338 else
<> 144:ef7eb2e8f9f7 339 {
<> 144:ef7eb2e8f9f7 340 if (handle->txData)
<> 144:ef7eb2e8f9f7 341 {
<> 144:ef7eb2e8f9f7 342 wordToSend = *(handle->txData);
<> 144:ef7eb2e8f9f7 343 ++handle->txData;
<> 144:ef7eb2e8f9f7 344 wordToSend |= (unsigned)(*(handle->txData)) << 8U;
<> 144:ef7eb2e8f9f7 345 ++handle->txData;
<> 144:ef7eb2e8f9f7 346 }
<> 144:ef7eb2e8f9f7 347 else
<> 144:ef7eb2e8f9f7 348 {
<> 144:ef7eb2e8f9f7 349 wordToSend = ((uint32_t)dummyData << 8) | dummyData;
<> 144:ef7eb2e8f9f7 350 ;
<> 144:ef7eb2e8f9f7 351 }
<> 144:ef7eb2e8f9f7 352 handle->remainingSendByteCount -= 2;
<> 144:ef7eb2e8f9f7 353 base->PUSHR = (handle->command & 0xffff0000U) | wordToSend;
<> 144:ef7eb2e8f9f7 354 }
<> 144:ef7eb2e8f9f7 355
<> 144:ef7eb2e8f9f7 356 /* Try to clear the TFFF; if the TX FIFO is full this will clear */
<> 144:ef7eb2e8f9f7 357 DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
<> 144:ef7eb2e8f9f7 358
<> 144:ef7eb2e8f9f7 359 dataAlreadyFed += 2;
<> 144:ef7eb2e8f9f7 360
<> 144:ef7eb2e8f9f7 361 /* exit loop if send count is zero, else update local variables for next loop */
<> 144:ef7eb2e8f9f7 362 if ((handle->remainingSendByteCount == 0) || (dataAlreadyFed == (dataFedMax * 2)))
<> 144:ef7eb2e8f9f7 363 {
<> 144:ef7eb2e8f9f7 364 break;
<> 144:ef7eb2e8f9f7 365 }
<> 144:ef7eb2e8f9f7 366 } /* End of TX FIFO fill while loop */
<> 144:ef7eb2e8f9f7 367 }
<> 144:ef7eb2e8f9f7 368 else /* Optimized for bits/frame less than or equal to one byte. */
<> 144:ef7eb2e8f9f7 369 {
<> 144:ef7eb2e8f9f7 370 while (DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag)
<> 144:ef7eb2e8f9f7 371 {
<> 144:ef7eb2e8f9f7 372 if (handle->txData)
<> 144:ef7eb2e8f9f7 373 {
<> 144:ef7eb2e8f9f7 374 wordToSend = *(handle->txData);
<> 144:ef7eb2e8f9f7 375 ++handle->txData;
<> 144:ef7eb2e8f9f7 376 }
<> 144:ef7eb2e8f9f7 377 else
<> 144:ef7eb2e8f9f7 378 {
<> 144:ef7eb2e8f9f7 379 wordToSend = dummyData;
<> 144:ef7eb2e8f9f7 380 }
<> 144:ef7eb2e8f9f7 381
<> 144:ef7eb2e8f9f7 382 if (handle->remainingSendByteCount == 1)
<> 144:ef7eb2e8f9f7 383 {
<> 144:ef7eb2e8f9f7 384 base->PUSHR = (handle->lastCommand & 0xffff0000U) | wordToSend;
<> 144:ef7eb2e8f9f7 385 }
<> 144:ef7eb2e8f9f7 386 else
<> 144:ef7eb2e8f9f7 387 {
<> 144:ef7eb2e8f9f7 388 base->PUSHR = (handle->command & 0xffff0000U) | wordToSend;
<> 144:ef7eb2e8f9f7 389 }
<> 144:ef7eb2e8f9f7 390
<> 144:ef7eb2e8f9f7 391 /* Try to clear the TFFF; if the TX FIFO is full this will clear */
<> 144:ef7eb2e8f9f7 392 DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
<> 144:ef7eb2e8f9f7 393
<> 144:ef7eb2e8f9f7 394 --handle->remainingSendByteCount;
<> 144:ef7eb2e8f9f7 395
<> 144:ef7eb2e8f9f7 396 dataAlreadyFed++;
<> 144:ef7eb2e8f9f7 397
<> 144:ef7eb2e8f9f7 398 /* exit loop if send count is zero, else update local variables for next loop */
<> 144:ef7eb2e8f9f7 399 if ((handle->remainingSendByteCount == 0) || (dataAlreadyFed == dataFedMax))
<> 144:ef7eb2e8f9f7 400 {
<> 144:ef7eb2e8f9f7 401 break;
<> 144:ef7eb2e8f9f7 402 }
<> 144:ef7eb2e8f9f7 403 } /* End of TX FIFO fill while loop */
<> 144:ef7eb2e8f9f7 404 }
<> 144:ef7eb2e8f9f7 405 }
<> 144:ef7eb2e8f9f7 406
<> 144:ef7eb2e8f9f7 407 /***channel_A *** used for carry the data from Rx_Data_Register(POPR) to User_Receive_Buffer*/
<> 144:ef7eb2e8f9f7 408 EDMA_ResetChannel(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel);
<> 144:ef7eb2e8f9f7 409
<> 144:ef7eb2e8f9f7 410 transferConfigA.srcAddr = (uint32_t)rxAddr;
<> 144:ef7eb2e8f9f7 411 transferConfigA.srcOffset = 0;
<> 144:ef7eb2e8f9f7 412
<> 144:ef7eb2e8f9f7 413 if (handle->rxData)
<> 144:ef7eb2e8f9f7 414 {
<> 144:ef7eb2e8f9f7 415 transferConfigA.destAddr = (uint32_t) & (handle->rxData[0]);
<> 144:ef7eb2e8f9f7 416 transferConfigA.destOffset = 1;
<> 144:ef7eb2e8f9f7 417 }
<> 144:ef7eb2e8f9f7 418 else
<> 144:ef7eb2e8f9f7 419 {
<> 144:ef7eb2e8f9f7 420 transferConfigA.destAddr = (uint32_t) & (handle->rxBuffIfNull);
<> 144:ef7eb2e8f9f7 421 transferConfigA.destOffset = 0;
<> 144:ef7eb2e8f9f7 422 }
<> 144:ef7eb2e8f9f7 423
<> 144:ef7eb2e8f9f7 424 transferConfigA.destTransferSize = kEDMA_TransferSize1Bytes;
<> 144:ef7eb2e8f9f7 425
<> 144:ef7eb2e8f9f7 426 if (handle->bitsPerFrame <= 8)
<> 144:ef7eb2e8f9f7 427 {
<> 144:ef7eb2e8f9f7 428 transferConfigA.srcTransferSize = kEDMA_TransferSize1Bytes;
<> 144:ef7eb2e8f9f7 429 transferConfigA.minorLoopBytes = 1;
<> 144:ef7eb2e8f9f7 430 transferConfigA.majorLoopCounts = handle->remainingReceiveByteCount;
<> 144:ef7eb2e8f9f7 431 }
<> 144:ef7eb2e8f9f7 432 else
<> 144:ef7eb2e8f9f7 433 {
<> 144:ef7eb2e8f9f7 434 transferConfigA.srcTransferSize = kEDMA_TransferSize2Bytes;
<> 144:ef7eb2e8f9f7 435 transferConfigA.minorLoopBytes = 2;
<> 144:ef7eb2e8f9f7 436 transferConfigA.majorLoopCounts = handle->remainingReceiveByteCount / 2;
<> 144:ef7eb2e8f9f7 437 }
<> 144:ef7eb2e8f9f7 438 EDMA_SetTransferConfig(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel,
<> 144:ef7eb2e8f9f7 439 &transferConfigA, NULL);
<> 144:ef7eb2e8f9f7 440 EDMA_EnableChannelInterrupts(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel,
<> 144:ef7eb2e8f9f7 441 kEDMA_MajorInterruptEnable);
<> 144:ef7eb2e8f9f7 442
<> 144:ef7eb2e8f9f7 443 /***channel_B *** used for carry the data from User_Send_Buffer to "intermediary" because the SPIx_PUSHR should
<> 144:ef7eb2e8f9f7 444 write the 32bits at once time . Then use channel_C to carry the "intermediary" to SPIx_PUSHR. Note that the
<> 144:ef7eb2e8f9f7 445 SPIx_PUSHR upper 16 bits are the "command" and the low 16bits are data */
<> 144:ef7eb2e8f9f7 446 EDMA_ResetChannel(handle->edmaTxDataToIntermediaryHandle->base, handle->edmaTxDataToIntermediaryHandle->channel);
<> 144:ef7eb2e8f9f7 447
<> 144:ef7eb2e8f9f7 448 if (handle->remainingSendByteCount > 0)
<> 144:ef7eb2e8f9f7 449 {
<> 144:ef7eb2e8f9f7 450 if (handle->txData)
<> 144:ef7eb2e8f9f7 451 {
<> 144:ef7eb2e8f9f7 452 transferConfigB.srcAddr = (uint32_t)(handle->txData);
<> 144:ef7eb2e8f9f7 453 transferConfigB.srcOffset = 1;
<> 144:ef7eb2e8f9f7 454 }
<> 144:ef7eb2e8f9f7 455 else
<> 144:ef7eb2e8f9f7 456 {
<> 144:ef7eb2e8f9f7 457 transferConfigB.srcAddr = (uint32_t)(&handle->txBuffIfNull);
<> 144:ef7eb2e8f9f7 458 transferConfigB.srcOffset = 0;
<> 144:ef7eb2e8f9f7 459 }
<> 144:ef7eb2e8f9f7 460
<> 144:ef7eb2e8f9f7 461 transferConfigB.destAddr = (uint32_t)(&handle->command);
<> 144:ef7eb2e8f9f7 462 transferConfigB.destOffset = 0;
<> 144:ef7eb2e8f9f7 463
<> 144:ef7eb2e8f9f7 464 transferConfigB.srcTransferSize = kEDMA_TransferSize1Bytes;
<> 144:ef7eb2e8f9f7 465
<> 144:ef7eb2e8f9f7 466 if (handle->bitsPerFrame <= 8)
<> 144:ef7eb2e8f9f7 467 {
<> 144:ef7eb2e8f9f7 468 transferConfigB.destTransferSize = kEDMA_TransferSize1Bytes;
<> 144:ef7eb2e8f9f7 469 transferConfigB.minorLoopBytes = 1;
<> 144:ef7eb2e8f9f7 470
<> 144:ef7eb2e8f9f7 471 if (1 == FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base))
<> 144:ef7eb2e8f9f7 472 {
<> 144:ef7eb2e8f9f7 473 /*already prepared the first data in "intermediary" , so minus 1 */
<> 144:ef7eb2e8f9f7 474 transferConfigB.majorLoopCounts = handle->remainingSendByteCount - 1;
<> 144:ef7eb2e8f9f7 475 }
<> 144:ef7eb2e8f9f7 476 else
<> 144:ef7eb2e8f9f7 477 {
<> 144:ef7eb2e8f9f7 478 /*Only enable channel_B minorlink to channel_C , so need to add one count due to the last time is
<> 144:ef7eb2e8f9f7 479 majorlink , the majorlink would not trigger the channel_C*/
<> 144:ef7eb2e8f9f7 480 transferConfigB.majorLoopCounts = handle->remainingSendByteCount + 1;
<> 144:ef7eb2e8f9f7 481 }
<> 144:ef7eb2e8f9f7 482 }
<> 144:ef7eb2e8f9f7 483 else
<> 144:ef7eb2e8f9f7 484 {
<> 144:ef7eb2e8f9f7 485 transferConfigB.destTransferSize = kEDMA_TransferSize2Bytes;
<> 144:ef7eb2e8f9f7 486 transferConfigB.minorLoopBytes = 2;
<> 144:ef7eb2e8f9f7 487 if (1 == FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base))
<> 144:ef7eb2e8f9f7 488 {
<> 144:ef7eb2e8f9f7 489 /*already prepared the first data in "intermediary" , so minus 1 */
<> 144:ef7eb2e8f9f7 490 transferConfigB.majorLoopCounts = handle->remainingSendByteCount / 2 - 1;
<> 144:ef7eb2e8f9f7 491 }
<> 144:ef7eb2e8f9f7 492 else
<> 144:ef7eb2e8f9f7 493 {
<> 144:ef7eb2e8f9f7 494 /*Only enable channel_B minorlink to channel_C , so need to add one count due to the last time is
<> 144:ef7eb2e8f9f7 495 * majorlink*/
<> 144:ef7eb2e8f9f7 496 transferConfigB.majorLoopCounts = handle->remainingSendByteCount / 2 + 1;
<> 144:ef7eb2e8f9f7 497 }
<> 144:ef7eb2e8f9f7 498 }
<> 144:ef7eb2e8f9f7 499
<> 144:ef7eb2e8f9f7 500 EDMA_SetTransferConfig(handle->edmaTxDataToIntermediaryHandle->base,
<> 144:ef7eb2e8f9f7 501 handle->edmaTxDataToIntermediaryHandle->channel, &transferConfigB, NULL);
<> 144:ef7eb2e8f9f7 502 }
<> 144:ef7eb2e8f9f7 503
<> 144:ef7eb2e8f9f7 504 /***channel_C ***carry the "intermediary" to SPIx_PUSHR. used the edma Scatter Gather function on channel_C to
<> 144:ef7eb2e8f9f7 505 handle the last data */
<> 144:ef7eb2e8f9f7 506 EDMA_ResetChannel(handle->edmaIntermediaryToTxRegHandle->base, handle->edmaIntermediaryToTxRegHandle->channel);
<> 144:ef7eb2e8f9f7 507
<> 144:ef7eb2e8f9f7 508 if (((handle->remainingSendByteCount > 0) && (1 != FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base))) ||
<> 144:ef7eb2e8f9f7 509 ((((handle->remainingSendByteCount > 1) && (handle->bitsPerFrame <= 8)) ||
<> 144:ef7eb2e8f9f7 510 ((handle->remainingSendByteCount > 2) && (handle->bitsPerFrame > 8))) &&
<> 144:ef7eb2e8f9f7 511 (1 == FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base))))
<> 144:ef7eb2e8f9f7 512 {
<> 144:ef7eb2e8f9f7 513 if (handle->txData)
<> 144:ef7eb2e8f9f7 514 {
<> 144:ef7eb2e8f9f7 515 uint32_t bufferIndex = 0;
<> 144:ef7eb2e8f9f7 516
<> 144:ef7eb2e8f9f7 517 if (1 == FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base))
<> 144:ef7eb2e8f9f7 518 {
<> 144:ef7eb2e8f9f7 519 if (handle->bitsPerFrame <= 8)
<> 144:ef7eb2e8f9f7 520 {
<> 144:ef7eb2e8f9f7 521 bufferIndex = handle->remainingSendByteCount - 1;
<> 144:ef7eb2e8f9f7 522 }
<> 144:ef7eb2e8f9f7 523 else
<> 144:ef7eb2e8f9f7 524 {
<> 144:ef7eb2e8f9f7 525 bufferIndex = handle->remainingSendByteCount - 2;
<> 144:ef7eb2e8f9f7 526 }
<> 144:ef7eb2e8f9f7 527 }
<> 144:ef7eb2e8f9f7 528 else
<> 144:ef7eb2e8f9f7 529 {
<> 144:ef7eb2e8f9f7 530 bufferIndex = handle->remainingSendByteCount;
<> 144:ef7eb2e8f9f7 531 }
<> 144:ef7eb2e8f9f7 532
<> 144:ef7eb2e8f9f7 533 if (handle->bitsPerFrame <= 8)
<> 144:ef7eb2e8f9f7 534 {
<> 144:ef7eb2e8f9f7 535 handle->lastCommand = (handle->lastCommand & 0xffff0000U) | handle->txData[bufferIndex - 1];
<> 144:ef7eb2e8f9f7 536 }
<> 144:ef7eb2e8f9f7 537 else
<> 144:ef7eb2e8f9f7 538 {
<> 144:ef7eb2e8f9f7 539 if (handle->isThereExtraByte)
<> 144:ef7eb2e8f9f7 540 {
<> 144:ef7eb2e8f9f7 541 handle->lastCommand = (handle->lastCommand & 0xffff0000U) | handle->txData[bufferIndex - 2] |
<> 144:ef7eb2e8f9f7 542 ((uint32_t)dummyData << 8);
<> 144:ef7eb2e8f9f7 543 }
<> 144:ef7eb2e8f9f7 544 else
<> 144:ef7eb2e8f9f7 545 {
<> 144:ef7eb2e8f9f7 546 handle->lastCommand = (handle->lastCommand & 0xffff0000U) |
<> 144:ef7eb2e8f9f7 547 ((uint32_t)handle->txData[bufferIndex - 1] << 8) |
<> 144:ef7eb2e8f9f7 548 handle->txData[bufferIndex - 2];
<> 144:ef7eb2e8f9f7 549 }
<> 144:ef7eb2e8f9f7 550 }
<> 144:ef7eb2e8f9f7 551 }
<> 144:ef7eb2e8f9f7 552 else
<> 144:ef7eb2e8f9f7 553 {
<> 144:ef7eb2e8f9f7 554 if (handle->bitsPerFrame <= 8)
<> 144:ef7eb2e8f9f7 555 {
<> 144:ef7eb2e8f9f7 556 wordToSend = dummyData;
<> 144:ef7eb2e8f9f7 557 }
<> 144:ef7eb2e8f9f7 558 else
<> 144:ef7eb2e8f9f7 559 {
<> 144:ef7eb2e8f9f7 560 wordToSend = ((uint32_t)dummyData << 8) | dummyData;
<> 144:ef7eb2e8f9f7 561 }
<> 144:ef7eb2e8f9f7 562 handle->lastCommand = (handle->lastCommand & 0xffff0000U) | wordToSend;
<> 144:ef7eb2e8f9f7 563 }
<> 144:ef7eb2e8f9f7 564 }
<> 144:ef7eb2e8f9f7 565
<> 144:ef7eb2e8f9f7 566 if ((1 == FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base)) ||
<> 144:ef7eb2e8f9f7 567 ((1 != FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base)) && (handle->remainingSendByteCount > 0)))
<> 144:ef7eb2e8f9f7 568 {
<> 144:ef7eb2e8f9f7 569 transferConfigC.srcAddr = (uint32_t) & (handle->lastCommand);
<> 144:ef7eb2e8f9f7 570 transferConfigC.destAddr = (uint32_t)txAddr;
<> 144:ef7eb2e8f9f7 571 transferConfigC.srcTransferSize = kEDMA_TransferSize4Bytes;
<> 144:ef7eb2e8f9f7 572 transferConfigC.destTransferSize = kEDMA_TransferSize4Bytes;
<> 144:ef7eb2e8f9f7 573 transferConfigC.srcOffset = 0;
<> 144:ef7eb2e8f9f7 574 transferConfigC.destOffset = 0;
<> 144:ef7eb2e8f9f7 575 transferConfigC.minorLoopBytes = 4;
<> 144:ef7eb2e8f9f7 576 transferConfigC.majorLoopCounts = 1;
<> 144:ef7eb2e8f9f7 577
<> 144:ef7eb2e8f9f7 578 EDMA_TcdReset(softwareTCD);
<> 144:ef7eb2e8f9f7 579 EDMA_TcdSetTransferConfig(softwareTCD, &transferConfigC, NULL);
<> 144:ef7eb2e8f9f7 580 }
<> 144:ef7eb2e8f9f7 581
<> 144:ef7eb2e8f9f7 582 if (((handle->remainingSendByteCount > 1) && (handle->bitsPerFrame <= 8)) ||
<> 144:ef7eb2e8f9f7 583 ((handle->remainingSendByteCount > 2) && (handle->bitsPerFrame > 8)))
<> 144:ef7eb2e8f9f7 584 {
<> 144:ef7eb2e8f9f7 585 transferConfigC.srcAddr = (uint32_t)(&(handle->command));
<> 144:ef7eb2e8f9f7 586 transferConfigC.destAddr = (uint32_t)txAddr;
<> 144:ef7eb2e8f9f7 587
<> 144:ef7eb2e8f9f7 588 transferConfigC.srcTransferSize = kEDMA_TransferSize4Bytes;
<> 144:ef7eb2e8f9f7 589 transferConfigC.destTransferSize = kEDMA_TransferSize4Bytes;
<> 144:ef7eb2e8f9f7 590 transferConfigC.srcOffset = 0;
<> 144:ef7eb2e8f9f7 591 transferConfigC.destOffset = 0;
<> 144:ef7eb2e8f9f7 592 transferConfigC.minorLoopBytes = 4;
<> 144:ef7eb2e8f9f7 593
<> 144:ef7eb2e8f9f7 594 if (handle->bitsPerFrame <= 8)
<> 144:ef7eb2e8f9f7 595 {
<> 144:ef7eb2e8f9f7 596 transferConfigC.majorLoopCounts = handle->remainingSendByteCount - 1;
<> 144:ef7eb2e8f9f7 597 }
<> 144:ef7eb2e8f9f7 598 else
<> 144:ef7eb2e8f9f7 599 {
<> 144:ef7eb2e8f9f7 600 transferConfigC.majorLoopCounts = handle->remainingSendByteCount / 2 - 1;
<> 144:ef7eb2e8f9f7 601 }
<> 144:ef7eb2e8f9f7 602
<> 144:ef7eb2e8f9f7 603 EDMA_SetTransferConfig(handle->edmaIntermediaryToTxRegHandle->base,
<> 144:ef7eb2e8f9f7 604 handle->edmaIntermediaryToTxRegHandle->channel, &transferConfigC, softwareTCD);
<> 144:ef7eb2e8f9f7 605 EDMA_EnableAutoStopRequest(handle->edmaIntermediaryToTxRegHandle->base,
<> 144:ef7eb2e8f9f7 606 handle->edmaIntermediaryToTxRegHandle->channel, false);
<> 144:ef7eb2e8f9f7 607 }
<> 144:ef7eb2e8f9f7 608 else
<> 144:ef7eb2e8f9f7 609 {
<> 144:ef7eb2e8f9f7 610 EDMA_SetTransferConfig(handle->edmaIntermediaryToTxRegHandle->base,
<> 144:ef7eb2e8f9f7 611 handle->edmaIntermediaryToTxRegHandle->channel, &transferConfigC, NULL);
<> 144:ef7eb2e8f9f7 612 }
<> 144:ef7eb2e8f9f7 613
<> 144:ef7eb2e8f9f7 614 /*Start the EDMA channel_A , channel_B , channel_C transfer*/
<> 144:ef7eb2e8f9f7 615 EDMA_StartTransfer(handle->edmaRxRegToRxDataHandle);
<> 144:ef7eb2e8f9f7 616 EDMA_StartTransfer(handle->edmaTxDataToIntermediaryHandle);
<> 144:ef7eb2e8f9f7 617 EDMA_StartTransfer(handle->edmaIntermediaryToTxRegHandle);
<> 144:ef7eb2e8f9f7 618
<> 144:ef7eb2e8f9f7 619 /*Set channel priority*/
<> 144:ef7eb2e8f9f7 620 uint8_t channelPriorityLow = handle->edmaRxRegToRxDataHandle->channel;
<> 144:ef7eb2e8f9f7 621 uint8_t channelPriorityMid = handle->edmaTxDataToIntermediaryHandle->channel;
<> 144:ef7eb2e8f9f7 622 uint8_t channelPriorityHigh = handle->edmaIntermediaryToTxRegHandle->channel;
<> 144:ef7eb2e8f9f7 623 uint8_t t = 0;
<> 144:ef7eb2e8f9f7 624 if (channelPriorityLow > channelPriorityMid)
<> 144:ef7eb2e8f9f7 625 {
<> 144:ef7eb2e8f9f7 626 t = channelPriorityLow;
<> 144:ef7eb2e8f9f7 627 channelPriorityLow = channelPriorityMid;
<> 144:ef7eb2e8f9f7 628 channelPriorityMid = t;
<> 144:ef7eb2e8f9f7 629 }
<> 144:ef7eb2e8f9f7 630
<> 144:ef7eb2e8f9f7 631 if (channelPriorityLow > channelPriorityHigh)
<> 144:ef7eb2e8f9f7 632 {
<> 144:ef7eb2e8f9f7 633 t = channelPriorityLow;
<> 144:ef7eb2e8f9f7 634 channelPriorityLow = channelPriorityHigh;
<> 144:ef7eb2e8f9f7 635 channelPriorityHigh = t;
<> 144:ef7eb2e8f9f7 636 }
<> 144:ef7eb2e8f9f7 637
<> 144:ef7eb2e8f9f7 638 if (channelPriorityMid > channelPriorityHigh)
<> 144:ef7eb2e8f9f7 639 {
<> 144:ef7eb2e8f9f7 640 t = channelPriorityMid;
<> 144:ef7eb2e8f9f7 641 channelPriorityMid = channelPriorityHigh;
<> 144:ef7eb2e8f9f7 642 channelPriorityHigh = t;
<> 144:ef7eb2e8f9f7 643 }
<> 144:ef7eb2e8f9f7 644 edma_channel_Preemption_config_t preemption_config_t;
<> 144:ef7eb2e8f9f7 645 preemption_config_t.enableChannelPreemption = true;
<> 144:ef7eb2e8f9f7 646 preemption_config_t.enablePreemptAbility = true;
<> 144:ef7eb2e8f9f7 647 preemption_config_t.channelPriority = channelPriorityLow;
<> 144:ef7eb2e8f9f7 648
<> 144:ef7eb2e8f9f7 649 if (1 != FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base))
<> 144:ef7eb2e8f9f7 650 {
<> 144:ef7eb2e8f9f7 651 EDMA_SetChannelPreemptionConfig(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel,
<> 144:ef7eb2e8f9f7 652 &preemption_config_t);
<> 144:ef7eb2e8f9f7 653
<> 144:ef7eb2e8f9f7 654 preemption_config_t.channelPriority = channelPriorityMid;
<> 144:ef7eb2e8f9f7 655 EDMA_SetChannelPreemptionConfig(handle->edmaTxDataToIntermediaryHandle->base,
<> 144:ef7eb2e8f9f7 656 handle->edmaTxDataToIntermediaryHandle->channel, &preemption_config_t);
<> 144:ef7eb2e8f9f7 657
<> 144:ef7eb2e8f9f7 658 preemption_config_t.channelPriority = channelPriorityHigh;
<> 144:ef7eb2e8f9f7 659 EDMA_SetChannelPreemptionConfig(handle->edmaIntermediaryToTxRegHandle->base,
<> 144:ef7eb2e8f9f7 660 handle->edmaIntermediaryToTxRegHandle->channel, &preemption_config_t);
<> 144:ef7eb2e8f9f7 661 }
<> 144:ef7eb2e8f9f7 662 else
<> 144:ef7eb2e8f9f7 663 {
<> 144:ef7eb2e8f9f7 664 EDMA_SetChannelPreemptionConfig(handle->edmaIntermediaryToTxRegHandle->base,
<> 144:ef7eb2e8f9f7 665 handle->edmaIntermediaryToTxRegHandle->channel, &preemption_config_t);
<> 144:ef7eb2e8f9f7 666
<> 144:ef7eb2e8f9f7 667 preemption_config_t.channelPriority = channelPriorityMid;
<> 144:ef7eb2e8f9f7 668 EDMA_SetChannelPreemptionConfig(handle->edmaTxDataToIntermediaryHandle->base,
<> 144:ef7eb2e8f9f7 669 handle->edmaTxDataToIntermediaryHandle->channel, &preemption_config_t);
<> 144:ef7eb2e8f9f7 670
<> 144:ef7eb2e8f9f7 671 preemption_config_t.channelPriority = channelPriorityHigh;
<> 144:ef7eb2e8f9f7 672 EDMA_SetChannelPreemptionConfig(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel,
<> 144:ef7eb2e8f9f7 673 &preemption_config_t);
<> 144:ef7eb2e8f9f7 674 }
<> 144:ef7eb2e8f9f7 675
<> 144:ef7eb2e8f9f7 676 /*Set the channel link.
<> 144:ef7eb2e8f9f7 677 For DSPI instances with shared RX/TX DMA requests: Rx DMA request -> channel_A -> channel_B-> channel_C.
<> 144:ef7eb2e8f9f7 678 For DSPI instances with separate RX and TX DMA requests:
<> 144:ef7eb2e8f9f7 679 Rx DMA request -> channel_A
<> 144:ef7eb2e8f9f7 680 Tx DMA request -> channel_C -> channel_B . (so need prepare the first data in "intermediary" before the DMA
<> 144:ef7eb2e8f9f7 681 transfer and then channel_B is used to prepare the next data to "intermediary" ) */
<> 144:ef7eb2e8f9f7 682 if (1 == FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base))
<> 144:ef7eb2e8f9f7 683 {
<> 144:ef7eb2e8f9f7 684 /*if there is Tx DMA request , carry the 32bits data (handle->command) to PUSHR first , then link to channelB
<> 144:ef7eb2e8f9f7 685 to prepare the next 32bits data (User_send_buffer to handle->command) */
<> 144:ef7eb2e8f9f7 686 if (handle->remainingSendByteCount > 1)
<> 144:ef7eb2e8f9f7 687 {
<> 144:ef7eb2e8f9f7 688 EDMA_SetChannelLink(handle->edmaIntermediaryToTxRegHandle->base,
<> 144:ef7eb2e8f9f7 689 handle->edmaIntermediaryToTxRegHandle->channel, kEDMA_MinorLink,
<> 144:ef7eb2e8f9f7 690 handle->edmaTxDataToIntermediaryHandle->channel);
<> 144:ef7eb2e8f9f7 691 }
<> 144:ef7eb2e8f9f7 692
<> 144:ef7eb2e8f9f7 693 DSPI_EnableDMA(base, kDSPI_RxDmaEnable | kDSPI_TxDmaEnable);
<> 144:ef7eb2e8f9f7 694 }
<> 144:ef7eb2e8f9f7 695 else
<> 144:ef7eb2e8f9f7 696 {
<> 144:ef7eb2e8f9f7 697 if (handle->remainingSendByteCount > 0)
<> 144:ef7eb2e8f9f7 698 {
<> 144:ef7eb2e8f9f7 699 EDMA_SetChannelLink(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel,
<> 144:ef7eb2e8f9f7 700 kEDMA_MinorLink, handle->edmaTxDataToIntermediaryHandle->channel);
<> 144:ef7eb2e8f9f7 701
<> 144:ef7eb2e8f9f7 702 if (handle->isThereExtraByte)
<> 144:ef7eb2e8f9f7 703 {
<> 144:ef7eb2e8f9f7 704 EDMA_SetChannelLink(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel,
<> 144:ef7eb2e8f9f7 705 kEDMA_MajorLink, handle->edmaTxDataToIntermediaryHandle->channel);
<> 144:ef7eb2e8f9f7 706 }
<> 144:ef7eb2e8f9f7 707
<> 144:ef7eb2e8f9f7 708 EDMA_SetChannelLink(handle->edmaTxDataToIntermediaryHandle->base,
<> 144:ef7eb2e8f9f7 709 handle->edmaTxDataToIntermediaryHandle->channel, kEDMA_MinorLink,
<> 144:ef7eb2e8f9f7 710 handle->edmaIntermediaryToTxRegHandle->channel);
<> 144:ef7eb2e8f9f7 711 }
<> 144:ef7eb2e8f9f7 712
<> 144:ef7eb2e8f9f7 713 DSPI_EnableDMA(base, kDSPI_RxDmaEnable);
<> 144:ef7eb2e8f9f7 714 }
<> 144:ef7eb2e8f9f7 715
<> 144:ef7eb2e8f9f7 716 DSPI_StartTransfer(base);
<> 144:ef7eb2e8f9f7 717
<> 144:ef7eb2e8f9f7 718 return kStatus_Success;
<> 144:ef7eb2e8f9f7 719 }
<> 144:ef7eb2e8f9f7 720
<> 144:ef7eb2e8f9f7 721 static void EDMA_DspiMasterCallback(edma_handle_t *edmaHandle,
<> 144:ef7eb2e8f9f7 722 void *g_dspiEdmaPrivateHandle,
<> 144:ef7eb2e8f9f7 723 bool transferDone,
<> 144:ef7eb2e8f9f7 724 uint32_t tcds)
<> 144:ef7eb2e8f9f7 725 {
<> 144:ef7eb2e8f9f7 726 dspi_master_edma_private_handle_t *dspiEdmaPrivateHandle;
<> 144:ef7eb2e8f9f7 727
<> 144:ef7eb2e8f9f7 728 dspiEdmaPrivateHandle = (dspi_master_edma_private_handle_t *)g_dspiEdmaPrivateHandle;
<> 144:ef7eb2e8f9f7 729
<> 144:ef7eb2e8f9f7 730 uint32_t dataReceived;
<> 144:ef7eb2e8f9f7 731
<> 144:ef7eb2e8f9f7 732 DSPI_DisableDMA((dspiEdmaPrivateHandle->base), kDSPI_RxDmaEnable | kDSPI_TxDmaEnable);
<> 144:ef7eb2e8f9f7 733
<> 144:ef7eb2e8f9f7 734 if (dspiEdmaPrivateHandle->handle->isThereExtraByte)
<> 144:ef7eb2e8f9f7 735 {
<> 144:ef7eb2e8f9f7 736 while (!((dspiEdmaPrivateHandle->base)->SR & SPI_SR_RFDF_MASK))
<> 144:ef7eb2e8f9f7 737 {
<> 144:ef7eb2e8f9f7 738 }
<> 144:ef7eb2e8f9f7 739 dataReceived = (dspiEdmaPrivateHandle->base)->POPR;
<> 144:ef7eb2e8f9f7 740 if (dspiEdmaPrivateHandle->handle->rxData)
<> 144:ef7eb2e8f9f7 741 {
<> 144:ef7eb2e8f9f7 742 (dspiEdmaPrivateHandle->handle->rxData[dspiEdmaPrivateHandle->handle->totalByteCount - 1]) = dataReceived;
<> 144:ef7eb2e8f9f7 743 }
<> 144:ef7eb2e8f9f7 744 }
<> 144:ef7eb2e8f9f7 745
<> 144:ef7eb2e8f9f7 746 if (dspiEdmaPrivateHandle->handle->callback)
<> 144:ef7eb2e8f9f7 747 {
<> 144:ef7eb2e8f9f7 748 dspiEdmaPrivateHandle->handle->callback(dspiEdmaPrivateHandle->base, dspiEdmaPrivateHandle->handle,
<> 144:ef7eb2e8f9f7 749 kStatus_Success, dspiEdmaPrivateHandle->handle->userData);
<> 144:ef7eb2e8f9f7 750 }
<> 144:ef7eb2e8f9f7 751
<> 144:ef7eb2e8f9f7 752 dspiEdmaPrivateHandle->handle->state = kDSPI_Idle;
<> 144:ef7eb2e8f9f7 753 }
<> 144:ef7eb2e8f9f7 754
<> 144:ef7eb2e8f9f7 755 void DSPI_MasterTransferAbortEDMA(SPI_Type *base, dspi_master_edma_handle_t *handle)
<> 144:ef7eb2e8f9f7 756 {
<> 144:ef7eb2e8f9f7 757 DSPI_StopTransfer(base);
<> 144:ef7eb2e8f9f7 758
<> 144:ef7eb2e8f9f7 759 DSPI_DisableDMA(base, kDSPI_RxDmaEnable | kDSPI_TxDmaEnable);
<> 144:ef7eb2e8f9f7 760
<> 144:ef7eb2e8f9f7 761 EDMA_AbortTransfer(handle->edmaRxRegToRxDataHandle);
<> 144:ef7eb2e8f9f7 762 EDMA_AbortTransfer(handle->edmaTxDataToIntermediaryHandle);
<> 144:ef7eb2e8f9f7 763 EDMA_AbortTransfer(handle->edmaIntermediaryToTxRegHandle);
<> 144:ef7eb2e8f9f7 764
<> 144:ef7eb2e8f9f7 765 handle->state = kDSPI_Idle;
<> 144:ef7eb2e8f9f7 766 }
<> 144:ef7eb2e8f9f7 767
<> 144:ef7eb2e8f9f7 768 status_t DSPI_MasterTransferGetCountEDMA(SPI_Type *base, dspi_master_edma_handle_t *handle, size_t *count)
<> 144:ef7eb2e8f9f7 769 {
<> 144:ef7eb2e8f9f7 770 assert(handle);
<> 144:ef7eb2e8f9f7 771
<> 144:ef7eb2e8f9f7 772 if (!count)
<> 144:ef7eb2e8f9f7 773 {
<> 144:ef7eb2e8f9f7 774 return kStatus_InvalidArgument;
<> 144:ef7eb2e8f9f7 775 }
<> 144:ef7eb2e8f9f7 776
<> 144:ef7eb2e8f9f7 777 /* Catch when there is not an active transfer. */
<> 144:ef7eb2e8f9f7 778 if (handle->state != kDSPI_Busy)
<> 144:ef7eb2e8f9f7 779 {
<> 144:ef7eb2e8f9f7 780 *count = 0;
<> 144:ef7eb2e8f9f7 781 return kStatus_NoTransferInProgress;
<> 144:ef7eb2e8f9f7 782 }
<> 144:ef7eb2e8f9f7 783
<> 144:ef7eb2e8f9f7 784 size_t bytes;
<> 144:ef7eb2e8f9f7 785
<> 144:ef7eb2e8f9f7 786 bytes = EDMA_GetRemainingBytes(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel);
<> 144:ef7eb2e8f9f7 787
<> 144:ef7eb2e8f9f7 788 *count = handle->totalByteCount - bytes;
<> 144:ef7eb2e8f9f7 789
<> 144:ef7eb2e8f9f7 790 return kStatus_Success;
<> 144:ef7eb2e8f9f7 791 }
<> 144:ef7eb2e8f9f7 792
<> 144:ef7eb2e8f9f7 793 void DSPI_SlaveTransferCreateHandleEDMA(SPI_Type *base,
<> 144:ef7eb2e8f9f7 794 dspi_slave_edma_handle_t *handle,
<> 144:ef7eb2e8f9f7 795 dspi_slave_edma_transfer_callback_t callback,
<> 144:ef7eb2e8f9f7 796 void *userData,
<> 144:ef7eb2e8f9f7 797 edma_handle_t *edmaRxRegToRxDataHandle,
<> 144:ef7eb2e8f9f7 798 edma_handle_t *edmaTxDataToTxRegHandle)
<> 144:ef7eb2e8f9f7 799 {
<> 144:ef7eb2e8f9f7 800 assert(handle);
<> 144:ef7eb2e8f9f7 801
<> 144:ef7eb2e8f9f7 802 /* Zero the handle. */
<> 144:ef7eb2e8f9f7 803 memset(handle, 0, sizeof(*handle));
<> 144:ef7eb2e8f9f7 804
<> 144:ef7eb2e8f9f7 805 uint32_t instance = DSPI_GetInstance(base);
<> 144:ef7eb2e8f9f7 806
<> 144:ef7eb2e8f9f7 807 s_dspiSlaveEdmaPrivateHandle[instance].base = base;
<> 144:ef7eb2e8f9f7 808 s_dspiSlaveEdmaPrivateHandle[instance].handle = handle;
<> 144:ef7eb2e8f9f7 809
<> 144:ef7eb2e8f9f7 810 handle->callback = callback;
<> 144:ef7eb2e8f9f7 811 handle->userData = userData;
<> 144:ef7eb2e8f9f7 812
<> 144:ef7eb2e8f9f7 813 handle->edmaRxRegToRxDataHandle = edmaRxRegToRxDataHandle;
<> 144:ef7eb2e8f9f7 814 handle->edmaTxDataToTxRegHandle = edmaTxDataToTxRegHandle;
<> 144:ef7eb2e8f9f7 815 }
<> 144:ef7eb2e8f9f7 816
<> 144:ef7eb2e8f9f7 817 status_t DSPI_SlaveTransferEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle, dspi_transfer_t *transfer)
<> 144:ef7eb2e8f9f7 818 {
<> 144:ef7eb2e8f9f7 819 assert(handle && transfer);
<> 144:ef7eb2e8f9f7 820
<> 144:ef7eb2e8f9f7 821 /* If send/receive length is zero */
<> 144:ef7eb2e8f9f7 822 if (transfer->dataSize == 0)
<> 144:ef7eb2e8f9f7 823 {
<> 144:ef7eb2e8f9f7 824 return kStatus_InvalidArgument;
<> 144:ef7eb2e8f9f7 825 }
<> 144:ef7eb2e8f9f7 826
<> 144:ef7eb2e8f9f7 827 /* If both send buffer and receive buffer is null */
<> 144:ef7eb2e8f9f7 828 if ((!(transfer->txData)) && (!(transfer->rxData)))
<> 144:ef7eb2e8f9f7 829 {
<> 144:ef7eb2e8f9f7 830 return kStatus_InvalidArgument;
<> 144:ef7eb2e8f9f7 831 }
<> 144:ef7eb2e8f9f7 832
<> 144:ef7eb2e8f9f7 833 /* Check that we're not busy.*/
<> 144:ef7eb2e8f9f7 834 if (handle->state == kDSPI_Busy)
<> 144:ef7eb2e8f9f7 835 {
<> 144:ef7eb2e8f9f7 836 return kStatus_DSPI_Busy;
<> 144:ef7eb2e8f9f7 837 }
<> 144:ef7eb2e8f9f7 838
<> 144:ef7eb2e8f9f7 839 edma_tcd_t *softwareTCD = (edma_tcd_t *)((uint32_t)(&handle->dspiSoftwareTCD[1]) & (~0x1FU));
<> 144:ef7eb2e8f9f7 840
<> 144:ef7eb2e8f9f7 841 uint32_t instance = DSPI_GetInstance(base);
<> 144:ef7eb2e8f9f7 842 uint8_t whichCtar = (transfer->configFlags & DSPI_SLAVE_CTAR_MASK) >> DSPI_SLAVE_CTAR_SHIFT;
<> 144:ef7eb2e8f9f7 843 handle->bitsPerFrame =
<> 144:ef7eb2e8f9f7 844 (((base->CTAR_SLAVE[whichCtar]) & SPI_CTAR_SLAVE_FMSZ_MASK) >> SPI_CTAR_SLAVE_FMSZ_SHIFT) + 1;
<> 144:ef7eb2e8f9f7 845
<> 144:ef7eb2e8f9f7 846 /* If using a shared RX/TX DMA request, then this limits the amount of data we can transfer
<> 144:ef7eb2e8f9f7 847 * due to the linked channel. The max bytes is 511 if 8-bit/frame or 1022 if 16-bit/frame
<> 144:ef7eb2e8f9f7 848 */
<> 144:ef7eb2e8f9f7 849 if (1 != FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base))
<> 144:ef7eb2e8f9f7 850 {
<> 144:ef7eb2e8f9f7 851 if (handle->bitsPerFrame > 8)
<> 144:ef7eb2e8f9f7 852 {
<> 144:ef7eb2e8f9f7 853 if (transfer->dataSize > 1022)
<> 144:ef7eb2e8f9f7 854 {
<> 144:ef7eb2e8f9f7 855 return kStatus_DSPI_OutOfRange;
<> 144:ef7eb2e8f9f7 856 }
<> 144:ef7eb2e8f9f7 857 }
<> 144:ef7eb2e8f9f7 858 else
<> 144:ef7eb2e8f9f7 859 {
<> 144:ef7eb2e8f9f7 860 if (transfer->dataSize > 511)
<> 144:ef7eb2e8f9f7 861 {
<> 144:ef7eb2e8f9f7 862 return kStatus_DSPI_OutOfRange;
<> 144:ef7eb2e8f9f7 863 }
<> 144:ef7eb2e8f9f7 864 }
<> 144:ef7eb2e8f9f7 865 }
<> 144:ef7eb2e8f9f7 866
<> 144:ef7eb2e8f9f7 867 if ((handle->bitsPerFrame > 8) && (transfer->dataSize < 2))
<> 144:ef7eb2e8f9f7 868 {
<> 144:ef7eb2e8f9f7 869 return kStatus_InvalidArgument;
<> 144:ef7eb2e8f9f7 870 }
<> 144:ef7eb2e8f9f7 871
<> 144:ef7eb2e8f9f7 872 EDMA_SetCallback(handle->edmaRxRegToRxDataHandle, EDMA_DspiSlaveCallback, &s_dspiSlaveEdmaPrivateHandle[instance]);
<> 144:ef7eb2e8f9f7 873
<> 144:ef7eb2e8f9f7 874 handle->state = kDSPI_Busy;
<> 144:ef7eb2e8f9f7 875
<> 144:ef7eb2e8f9f7 876 /* Store transfer information */
<> 144:ef7eb2e8f9f7 877 handle->txData = transfer->txData;
<> 144:ef7eb2e8f9f7 878 handle->rxData = transfer->rxData;
<> 144:ef7eb2e8f9f7 879 handle->remainingSendByteCount = transfer->dataSize;
<> 144:ef7eb2e8f9f7 880 handle->remainingReceiveByteCount = transfer->dataSize;
<> 144:ef7eb2e8f9f7 881 handle->totalByteCount = transfer->dataSize;
<> 144:ef7eb2e8f9f7 882 handle->errorCount = 0;
<> 144:ef7eb2e8f9f7 883
<> 144:ef7eb2e8f9f7 884 handle->isThereExtraByte = false;
<> 144:ef7eb2e8f9f7 885 if (handle->bitsPerFrame > 8)
<> 144:ef7eb2e8f9f7 886 {
<> 144:ef7eb2e8f9f7 887 if (handle->remainingSendByteCount % 2 == 1)
<> 144:ef7eb2e8f9f7 888 {
<> 144:ef7eb2e8f9f7 889 handle->remainingSendByteCount++;
<> 144:ef7eb2e8f9f7 890 handle->remainingReceiveByteCount--;
<> 144:ef7eb2e8f9f7 891 handle->isThereExtraByte = true;
<> 144:ef7eb2e8f9f7 892 }
<> 144:ef7eb2e8f9f7 893 }
<> 144:ef7eb2e8f9f7 894
<> 144:ef7eb2e8f9f7 895 uint16_t wordToSend = 0;
<> 144:ef7eb2e8f9f7 896 uint8_t dummyData = DSPI_SLAVE_DUMMY_DATA;
<> 144:ef7eb2e8f9f7 897 uint8_t dataAlreadyFed = 0;
<> 144:ef7eb2e8f9f7 898 uint8_t dataFedMax = 2;
<> 144:ef7eb2e8f9f7 899
<> 144:ef7eb2e8f9f7 900 uint32_t rxAddr = DSPI_GetRxRegisterAddress(base);
<> 144:ef7eb2e8f9f7 901 uint32_t txAddr = DSPI_SlaveGetTxRegisterAddress(base);
<> 144:ef7eb2e8f9f7 902
<> 144:ef7eb2e8f9f7 903 edma_transfer_config_t transferConfigA;
<> 144:ef7eb2e8f9f7 904 edma_transfer_config_t transferConfigC;
<> 144:ef7eb2e8f9f7 905
<> 144:ef7eb2e8f9f7 906 DSPI_StopTransfer(base);
<> 144:ef7eb2e8f9f7 907
<> 144:ef7eb2e8f9f7 908 DSPI_FlushFifo(base, true, true);
<> 144:ef7eb2e8f9f7 909 DSPI_ClearStatusFlags(base, kDSPI_AllStatusFlag);
<> 144:ef7eb2e8f9f7 910
<> 144:ef7eb2e8f9f7 911 DSPI_DisableDMA(base, kDSPI_RxDmaEnable | kDSPI_TxDmaEnable);
<> 144:ef7eb2e8f9f7 912
<> 144:ef7eb2e8f9f7 913 DSPI_StartTransfer(base);
<> 144:ef7eb2e8f9f7 914
<> 144:ef7eb2e8f9f7 915 /*if dspi has separate dma request , need not prepare data first .
<> 144:ef7eb2e8f9f7 916 else (dspi has shared dma request) , send first 2 data into fifo if there is fifo or send first 1 data to
<> 144:ef7eb2e8f9f7 917 slaveGetTxRegister if there is no fifo*/
<> 144:ef7eb2e8f9f7 918 if (1 != FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base))
<> 144:ef7eb2e8f9f7 919 {
<> 144:ef7eb2e8f9f7 920 /* For DSPI instances with shared RX/TX DMA requests, we'll use the RX DMA request to
<> 144:ef7eb2e8f9f7 921 * trigger ongoing transfers and will link to the TX DMA channel from the RX DMA channel.
<> 144:ef7eb2e8f9f7 922 */
<> 144:ef7eb2e8f9f7 923 /* If bits/frame is greater than one byte */
<> 144:ef7eb2e8f9f7 924 if (handle->bitsPerFrame > 8)
<> 144:ef7eb2e8f9f7 925 {
<> 144:ef7eb2e8f9f7 926 while (DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag)
<> 144:ef7eb2e8f9f7 927 {
<> 144:ef7eb2e8f9f7 928 if (handle->txData)
<> 144:ef7eb2e8f9f7 929 {
<> 144:ef7eb2e8f9f7 930 wordToSend = *(handle->txData);
<> 144:ef7eb2e8f9f7 931 ++handle->txData; /* Increment to next data byte */
<> 144:ef7eb2e8f9f7 932 if ((handle->remainingSendByteCount == 2) && (handle->isThereExtraByte))
<> 144:ef7eb2e8f9f7 933 {
<> 144:ef7eb2e8f9f7 934 wordToSend |= (unsigned)(dummyData) << 8U;
<> 144:ef7eb2e8f9f7 935 ++handle->txData; /* Increment to next data byte */
<> 144:ef7eb2e8f9f7 936 }
<> 144:ef7eb2e8f9f7 937 else
<> 144:ef7eb2e8f9f7 938 {
<> 144:ef7eb2e8f9f7 939 wordToSend |= (unsigned)(*(handle->txData)) << 8U;
<> 144:ef7eb2e8f9f7 940 ++handle->txData; /* Increment to next data byte */
<> 144:ef7eb2e8f9f7 941 }
<> 144:ef7eb2e8f9f7 942 }
<> 144:ef7eb2e8f9f7 943 else
<> 144:ef7eb2e8f9f7 944 {
<> 144:ef7eb2e8f9f7 945 wordToSend = ((uint32_t)dummyData << 8) | dummyData;
<> 144:ef7eb2e8f9f7 946 }
<> 144:ef7eb2e8f9f7 947 handle->remainingSendByteCount -= 2; /* decrement remainingSendByteCount by 2 */
<> 144:ef7eb2e8f9f7 948 base->PUSHR_SLAVE = wordToSend;
<> 144:ef7eb2e8f9f7 949
<> 144:ef7eb2e8f9f7 950 /* Try to clear the TFFF; if the TX FIFO is full this will clear */
<> 144:ef7eb2e8f9f7 951 DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
<> 144:ef7eb2e8f9f7 952
<> 144:ef7eb2e8f9f7 953 dataAlreadyFed += 2;
<> 144:ef7eb2e8f9f7 954
<> 144:ef7eb2e8f9f7 955 /* Exit loop if send count is zero, else update local variables for next loop */
<> 144:ef7eb2e8f9f7 956 if ((handle->remainingSendByteCount == 0) || (dataAlreadyFed == (dataFedMax * 2)))
<> 144:ef7eb2e8f9f7 957 {
<> 144:ef7eb2e8f9f7 958 break;
<> 144:ef7eb2e8f9f7 959 }
<> 144:ef7eb2e8f9f7 960 } /* End of TX FIFO fill while loop */
<> 144:ef7eb2e8f9f7 961 }
<> 144:ef7eb2e8f9f7 962 else /* Optimized for bits/frame less than or equal to one byte. */
<> 144:ef7eb2e8f9f7 963 {
<> 144:ef7eb2e8f9f7 964 while (DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag)
<> 144:ef7eb2e8f9f7 965 {
<> 144:ef7eb2e8f9f7 966 if (handle->txData)
<> 144:ef7eb2e8f9f7 967 {
<> 144:ef7eb2e8f9f7 968 wordToSend = *(handle->txData);
<> 144:ef7eb2e8f9f7 969 /* Increment to next data word*/
<> 144:ef7eb2e8f9f7 970 ++handle->txData;
<> 144:ef7eb2e8f9f7 971 }
<> 144:ef7eb2e8f9f7 972 else
<> 144:ef7eb2e8f9f7 973 {
<> 144:ef7eb2e8f9f7 974 wordToSend = dummyData;
<> 144:ef7eb2e8f9f7 975 }
<> 144:ef7eb2e8f9f7 976
<> 144:ef7eb2e8f9f7 977 base->PUSHR_SLAVE = wordToSend;
<> 144:ef7eb2e8f9f7 978
<> 144:ef7eb2e8f9f7 979 /* Try to clear the TFFF; if the TX FIFO is full this will clear */
<> 144:ef7eb2e8f9f7 980 DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
<> 144:ef7eb2e8f9f7 981 /* Decrement remainingSendByteCount*/
<> 144:ef7eb2e8f9f7 982 --handle->remainingSendByteCount;
<> 144:ef7eb2e8f9f7 983
<> 144:ef7eb2e8f9f7 984 dataAlreadyFed++;
<> 144:ef7eb2e8f9f7 985
<> 144:ef7eb2e8f9f7 986 /* Exit loop if send count is zero, else update local variables for next loop */
<> 144:ef7eb2e8f9f7 987 if ((handle->remainingSendByteCount == 0) || (dataAlreadyFed == dataFedMax))
<> 144:ef7eb2e8f9f7 988 {
<> 144:ef7eb2e8f9f7 989 break;
<> 144:ef7eb2e8f9f7 990 }
<> 144:ef7eb2e8f9f7 991 } /* End of TX FIFO fill while loop */
<> 144:ef7eb2e8f9f7 992 }
<> 144:ef7eb2e8f9f7 993 }
<> 144:ef7eb2e8f9f7 994
<> 144:ef7eb2e8f9f7 995 /***channel_A *** used for carry the data from Rx_Data_Register(POPR) to User_Receive_Buffer*/
<> 144:ef7eb2e8f9f7 996 if (handle->remainingReceiveByteCount > 0)
<> 144:ef7eb2e8f9f7 997 {
<> 144:ef7eb2e8f9f7 998 EDMA_ResetChannel(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel);
<> 144:ef7eb2e8f9f7 999
<> 144:ef7eb2e8f9f7 1000 transferConfigA.srcAddr = (uint32_t)rxAddr;
<> 144:ef7eb2e8f9f7 1001 transferConfigA.srcOffset = 0;
<> 144:ef7eb2e8f9f7 1002
<> 144:ef7eb2e8f9f7 1003 if (handle->rxData)
<> 144:ef7eb2e8f9f7 1004 {
<> 144:ef7eb2e8f9f7 1005 transferConfigA.destAddr = (uint32_t) & (handle->rxData[0]);
<> 144:ef7eb2e8f9f7 1006 transferConfigA.destOffset = 1;
<> 144:ef7eb2e8f9f7 1007 }
<> 144:ef7eb2e8f9f7 1008 else
<> 144:ef7eb2e8f9f7 1009 {
<> 144:ef7eb2e8f9f7 1010 transferConfigA.destAddr = (uint32_t) & (handle->rxBuffIfNull);
<> 144:ef7eb2e8f9f7 1011 transferConfigA.destOffset = 0;
<> 144:ef7eb2e8f9f7 1012 }
<> 144:ef7eb2e8f9f7 1013
<> 144:ef7eb2e8f9f7 1014 transferConfigA.destTransferSize = kEDMA_TransferSize1Bytes;
<> 144:ef7eb2e8f9f7 1015
<> 144:ef7eb2e8f9f7 1016 if (handle->bitsPerFrame <= 8)
<> 144:ef7eb2e8f9f7 1017 {
<> 144:ef7eb2e8f9f7 1018 transferConfigA.srcTransferSize = kEDMA_TransferSize1Bytes;
<> 144:ef7eb2e8f9f7 1019 transferConfigA.minorLoopBytes = 1;
<> 144:ef7eb2e8f9f7 1020 transferConfigA.majorLoopCounts = handle->remainingReceiveByteCount;
<> 144:ef7eb2e8f9f7 1021 }
<> 144:ef7eb2e8f9f7 1022 else
<> 144:ef7eb2e8f9f7 1023 {
<> 144:ef7eb2e8f9f7 1024 transferConfigA.srcTransferSize = kEDMA_TransferSize2Bytes;
<> 144:ef7eb2e8f9f7 1025 transferConfigA.minorLoopBytes = 2;
<> 144:ef7eb2e8f9f7 1026 transferConfigA.majorLoopCounts = handle->remainingReceiveByteCount / 2;
<> 144:ef7eb2e8f9f7 1027 }
<> 144:ef7eb2e8f9f7 1028 EDMA_SetTransferConfig(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel,
<> 144:ef7eb2e8f9f7 1029 &transferConfigA, NULL);
<> 144:ef7eb2e8f9f7 1030 EDMA_EnableChannelInterrupts(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel,
<> 144:ef7eb2e8f9f7 1031 kEDMA_MajorInterruptEnable);
<> 144:ef7eb2e8f9f7 1032 }
<> 144:ef7eb2e8f9f7 1033
<> 144:ef7eb2e8f9f7 1034 if (handle->remainingSendByteCount > 0)
<> 144:ef7eb2e8f9f7 1035 {
<> 144:ef7eb2e8f9f7 1036 /***channel_C *** used for carry the data from User_Send_Buffer to Tx_Data_Register(PUSHR_SLAVE)*/
<> 144:ef7eb2e8f9f7 1037 EDMA_ResetChannel(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel);
<> 144:ef7eb2e8f9f7 1038
<> 144:ef7eb2e8f9f7 1039 /*If there is extra byte , it would use the */
<> 144:ef7eb2e8f9f7 1040 if (handle->isThereExtraByte)
<> 144:ef7eb2e8f9f7 1041 {
<> 144:ef7eb2e8f9f7 1042 if (handle->txData)
<> 144:ef7eb2e8f9f7 1043 {
<> 144:ef7eb2e8f9f7 1044 handle->txLastData =
<> 144:ef7eb2e8f9f7 1045 handle->txData[handle->remainingSendByteCount - 2] | ((uint32_t)DSPI_SLAVE_DUMMY_DATA << 8);
<> 144:ef7eb2e8f9f7 1046 }
<> 144:ef7eb2e8f9f7 1047 else
<> 144:ef7eb2e8f9f7 1048 {
<> 144:ef7eb2e8f9f7 1049 handle->txLastData = DSPI_SLAVE_DUMMY_DATA | ((uint32_t)DSPI_SLAVE_DUMMY_DATA << 8);
<> 144:ef7eb2e8f9f7 1050 }
<> 144:ef7eb2e8f9f7 1051 transferConfigC.srcAddr = (uint32_t)(&(handle->txLastData));
<> 144:ef7eb2e8f9f7 1052 transferConfigC.destAddr = (uint32_t)txAddr;
<> 144:ef7eb2e8f9f7 1053 transferConfigC.srcTransferSize = kEDMA_TransferSize4Bytes;
<> 144:ef7eb2e8f9f7 1054 transferConfigC.destTransferSize = kEDMA_TransferSize4Bytes;
<> 144:ef7eb2e8f9f7 1055 transferConfigC.srcOffset = 0;
<> 144:ef7eb2e8f9f7 1056 transferConfigC.destOffset = 0;
<> 144:ef7eb2e8f9f7 1057 transferConfigC.minorLoopBytes = 4;
<> 144:ef7eb2e8f9f7 1058 transferConfigC.majorLoopCounts = 1;
<> 144:ef7eb2e8f9f7 1059
<> 144:ef7eb2e8f9f7 1060 EDMA_TcdReset(softwareTCD);
<> 144:ef7eb2e8f9f7 1061 EDMA_TcdSetTransferConfig(softwareTCD, &transferConfigC, NULL);
<> 144:ef7eb2e8f9f7 1062 }
<> 144:ef7eb2e8f9f7 1063
<> 144:ef7eb2e8f9f7 1064 /*Set another transferConfigC*/
<> 144:ef7eb2e8f9f7 1065 if ((handle->isThereExtraByte) && (handle->remainingSendByteCount == 2))
<> 144:ef7eb2e8f9f7 1066 {
<> 144:ef7eb2e8f9f7 1067 EDMA_SetTransferConfig(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel,
<> 144:ef7eb2e8f9f7 1068 &transferConfigC, NULL);
<> 144:ef7eb2e8f9f7 1069 }
<> 144:ef7eb2e8f9f7 1070 else
<> 144:ef7eb2e8f9f7 1071 {
<> 144:ef7eb2e8f9f7 1072 transferConfigC.destAddr = (uint32_t)txAddr;
<> 144:ef7eb2e8f9f7 1073 transferConfigC.destOffset = 0;
<> 144:ef7eb2e8f9f7 1074
<> 144:ef7eb2e8f9f7 1075 if (handle->txData)
<> 144:ef7eb2e8f9f7 1076 {
<> 144:ef7eb2e8f9f7 1077 transferConfigC.srcAddr = (uint32_t)(&(handle->txData[0]));
<> 144:ef7eb2e8f9f7 1078 transferConfigC.srcOffset = 1;
<> 144:ef7eb2e8f9f7 1079 }
<> 144:ef7eb2e8f9f7 1080 else
<> 144:ef7eb2e8f9f7 1081 {
<> 144:ef7eb2e8f9f7 1082 transferConfigC.srcAddr = (uint32_t)(&handle->txBuffIfNull);
<> 144:ef7eb2e8f9f7 1083 transferConfigC.srcOffset = 0;
<> 144:ef7eb2e8f9f7 1084 if (handle->bitsPerFrame <= 8)
<> 144:ef7eb2e8f9f7 1085 {
<> 144:ef7eb2e8f9f7 1086 handle->txBuffIfNull = DSPI_SLAVE_DUMMY_DATA;
<> 144:ef7eb2e8f9f7 1087 }
<> 144:ef7eb2e8f9f7 1088 else
<> 144:ef7eb2e8f9f7 1089 {
<> 144:ef7eb2e8f9f7 1090 handle->txBuffIfNull = (DSPI_SLAVE_DUMMY_DATA << 8) | DSPI_SLAVE_DUMMY_DATA;
<> 144:ef7eb2e8f9f7 1091 }
<> 144:ef7eb2e8f9f7 1092 }
<> 144:ef7eb2e8f9f7 1093
<> 144:ef7eb2e8f9f7 1094 transferConfigC.srcTransferSize = kEDMA_TransferSize1Bytes;
<> 144:ef7eb2e8f9f7 1095
<> 144:ef7eb2e8f9f7 1096 if (handle->bitsPerFrame <= 8)
<> 144:ef7eb2e8f9f7 1097 {
<> 144:ef7eb2e8f9f7 1098 transferConfigC.destTransferSize = kEDMA_TransferSize1Bytes;
<> 144:ef7eb2e8f9f7 1099 transferConfigC.minorLoopBytes = 1;
<> 144:ef7eb2e8f9f7 1100 transferConfigC.majorLoopCounts = handle->remainingSendByteCount;
<> 144:ef7eb2e8f9f7 1101 }
<> 144:ef7eb2e8f9f7 1102 else
<> 144:ef7eb2e8f9f7 1103 {
<> 144:ef7eb2e8f9f7 1104 transferConfigC.destTransferSize = kEDMA_TransferSize2Bytes;
<> 144:ef7eb2e8f9f7 1105 transferConfigC.minorLoopBytes = 2;
<> 144:ef7eb2e8f9f7 1106 if (handle->isThereExtraByte)
<> 144:ef7eb2e8f9f7 1107 {
<> 144:ef7eb2e8f9f7 1108 transferConfigC.majorLoopCounts = handle->remainingSendByteCount / 2 - 1;
<> 144:ef7eb2e8f9f7 1109 }
<> 144:ef7eb2e8f9f7 1110 else
<> 144:ef7eb2e8f9f7 1111 {
<> 144:ef7eb2e8f9f7 1112 transferConfigC.majorLoopCounts = handle->remainingSendByteCount / 2;
<> 144:ef7eb2e8f9f7 1113 }
<> 144:ef7eb2e8f9f7 1114 }
<> 144:ef7eb2e8f9f7 1115
<> 144:ef7eb2e8f9f7 1116 if (handle->isThereExtraByte)
<> 144:ef7eb2e8f9f7 1117 {
<> 144:ef7eb2e8f9f7 1118 EDMA_SetTransferConfig(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel,
<> 144:ef7eb2e8f9f7 1119 &transferConfigC, softwareTCD);
<> 144:ef7eb2e8f9f7 1120 EDMA_EnableAutoStopRequest(handle->edmaTxDataToTxRegHandle->base,
<> 144:ef7eb2e8f9f7 1121 handle->edmaTxDataToTxRegHandle->channel, false);
<> 144:ef7eb2e8f9f7 1122 }
<> 144:ef7eb2e8f9f7 1123 else
<> 144:ef7eb2e8f9f7 1124 {
<> 144:ef7eb2e8f9f7 1125 EDMA_SetTransferConfig(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel,
<> 144:ef7eb2e8f9f7 1126 &transferConfigC, NULL);
<> 144:ef7eb2e8f9f7 1127 }
<> 144:ef7eb2e8f9f7 1128
<> 144:ef7eb2e8f9f7 1129 EDMA_StartTransfer(handle->edmaTxDataToTxRegHandle);
<> 144:ef7eb2e8f9f7 1130 }
<> 144:ef7eb2e8f9f7 1131 }
<> 144:ef7eb2e8f9f7 1132
<> 144:ef7eb2e8f9f7 1133 EDMA_StartTransfer(handle->edmaRxRegToRxDataHandle);
<> 144:ef7eb2e8f9f7 1134
<> 144:ef7eb2e8f9f7 1135 /*Set channel priority*/
<> 144:ef7eb2e8f9f7 1136 uint8_t channelPriorityLow = handle->edmaRxRegToRxDataHandle->channel;
<> 144:ef7eb2e8f9f7 1137 uint8_t channelPriorityHigh = handle->edmaTxDataToTxRegHandle->channel;
<> 144:ef7eb2e8f9f7 1138 uint8_t t = 0;
<> 144:ef7eb2e8f9f7 1139
<> 144:ef7eb2e8f9f7 1140 if (channelPriorityLow > channelPriorityHigh)
<> 144:ef7eb2e8f9f7 1141 {
<> 144:ef7eb2e8f9f7 1142 t = channelPriorityLow;
<> 144:ef7eb2e8f9f7 1143 channelPriorityLow = channelPriorityHigh;
<> 144:ef7eb2e8f9f7 1144 channelPriorityHigh = t;
<> 144:ef7eb2e8f9f7 1145 }
<> 144:ef7eb2e8f9f7 1146
<> 144:ef7eb2e8f9f7 1147 edma_channel_Preemption_config_t preemption_config_t;
<> 144:ef7eb2e8f9f7 1148 preemption_config_t.enableChannelPreemption = true;
<> 144:ef7eb2e8f9f7 1149 preemption_config_t.enablePreemptAbility = true;
<> 144:ef7eb2e8f9f7 1150 preemption_config_t.channelPriority = channelPriorityLow;
<> 144:ef7eb2e8f9f7 1151
<> 144:ef7eb2e8f9f7 1152 if (1 != FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base))
<> 144:ef7eb2e8f9f7 1153 {
<> 144:ef7eb2e8f9f7 1154 EDMA_SetChannelPreemptionConfig(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel,
<> 144:ef7eb2e8f9f7 1155 &preemption_config_t);
<> 144:ef7eb2e8f9f7 1156
<> 144:ef7eb2e8f9f7 1157 preemption_config_t.channelPriority = channelPriorityHigh;
<> 144:ef7eb2e8f9f7 1158 EDMA_SetChannelPreemptionConfig(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel,
<> 144:ef7eb2e8f9f7 1159 &preemption_config_t);
<> 144:ef7eb2e8f9f7 1160 }
<> 144:ef7eb2e8f9f7 1161 else
<> 144:ef7eb2e8f9f7 1162 {
<> 144:ef7eb2e8f9f7 1163 EDMA_SetChannelPreemptionConfig(handle->edmaTxDataToTxRegHandle->base, handle->edmaTxDataToTxRegHandle->channel,
<> 144:ef7eb2e8f9f7 1164 &preemption_config_t);
<> 144:ef7eb2e8f9f7 1165
<> 144:ef7eb2e8f9f7 1166 preemption_config_t.channelPriority = channelPriorityHigh;
<> 144:ef7eb2e8f9f7 1167 EDMA_SetChannelPreemptionConfig(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel,
<> 144:ef7eb2e8f9f7 1168 &preemption_config_t);
<> 144:ef7eb2e8f9f7 1169 }
<> 144:ef7eb2e8f9f7 1170
<> 144:ef7eb2e8f9f7 1171 /*Set the channel link.
<> 144:ef7eb2e8f9f7 1172 For DSPI instances with shared RX/TX DMA requests: Rx DMA request -> channel_A -> channel_C.
<> 144:ef7eb2e8f9f7 1173 For DSPI instances with separate RX and TX DMA requests:
<> 144:ef7eb2e8f9f7 1174 Rx DMA request -> channel_A
<> 144:ef7eb2e8f9f7 1175 Tx DMA request -> channel_C */
<> 144:ef7eb2e8f9f7 1176 if (1 != FSL_FEATURE_DSPI_HAS_SEPARATE_DMA_RX_TX_REQn(base))
<> 144:ef7eb2e8f9f7 1177 {
<> 144:ef7eb2e8f9f7 1178 if (handle->remainingSendByteCount > 0)
<> 144:ef7eb2e8f9f7 1179 {
<> 144:ef7eb2e8f9f7 1180 EDMA_SetChannelLink(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel,
<> 144:ef7eb2e8f9f7 1181 kEDMA_MinorLink, handle->edmaTxDataToTxRegHandle->channel);
<> 144:ef7eb2e8f9f7 1182 }
<> 144:ef7eb2e8f9f7 1183 DSPI_EnableDMA(base, kDSPI_RxDmaEnable);
<> 144:ef7eb2e8f9f7 1184 }
<> 144:ef7eb2e8f9f7 1185 else
<> 144:ef7eb2e8f9f7 1186 {
<> 144:ef7eb2e8f9f7 1187 DSPI_EnableDMA(base, kDSPI_RxDmaEnable | kDSPI_TxDmaEnable);
<> 144:ef7eb2e8f9f7 1188 }
<> 144:ef7eb2e8f9f7 1189
<> 144:ef7eb2e8f9f7 1190 return kStatus_Success;
<> 144:ef7eb2e8f9f7 1191 }
<> 144:ef7eb2e8f9f7 1192
<> 144:ef7eb2e8f9f7 1193 static void EDMA_DspiSlaveCallback(edma_handle_t *edmaHandle,
<> 144:ef7eb2e8f9f7 1194 void *g_dspiEdmaPrivateHandle,
<> 144:ef7eb2e8f9f7 1195 bool transferDone,
<> 144:ef7eb2e8f9f7 1196 uint32_t tcds)
<> 144:ef7eb2e8f9f7 1197 {
<> 144:ef7eb2e8f9f7 1198 dspi_slave_edma_private_handle_t *dspiEdmaPrivateHandle;
<> 144:ef7eb2e8f9f7 1199
<> 144:ef7eb2e8f9f7 1200 dspiEdmaPrivateHandle = (dspi_slave_edma_private_handle_t *)g_dspiEdmaPrivateHandle;
<> 144:ef7eb2e8f9f7 1201
<> 144:ef7eb2e8f9f7 1202 uint32_t dataReceived;
<> 144:ef7eb2e8f9f7 1203
<> 144:ef7eb2e8f9f7 1204 DSPI_DisableDMA((dspiEdmaPrivateHandle->base), kDSPI_RxDmaEnable | kDSPI_TxDmaEnable);
<> 144:ef7eb2e8f9f7 1205
<> 144:ef7eb2e8f9f7 1206 if (dspiEdmaPrivateHandle->handle->isThereExtraByte)
<> 144:ef7eb2e8f9f7 1207 {
<> 144:ef7eb2e8f9f7 1208 while (!((dspiEdmaPrivateHandle->base)->SR & SPI_SR_RFDF_MASK))
<> 144:ef7eb2e8f9f7 1209 {
<> 144:ef7eb2e8f9f7 1210 }
<> 144:ef7eb2e8f9f7 1211 dataReceived = (dspiEdmaPrivateHandle->base)->POPR;
<> 144:ef7eb2e8f9f7 1212 if (dspiEdmaPrivateHandle->handle->rxData)
<> 144:ef7eb2e8f9f7 1213 {
<> 144:ef7eb2e8f9f7 1214 (dspiEdmaPrivateHandle->handle->rxData[dspiEdmaPrivateHandle->handle->totalByteCount - 1]) = dataReceived;
<> 144:ef7eb2e8f9f7 1215 }
<> 144:ef7eb2e8f9f7 1216 }
<> 144:ef7eb2e8f9f7 1217
<> 144:ef7eb2e8f9f7 1218 if (dspiEdmaPrivateHandle->handle->callback)
<> 144:ef7eb2e8f9f7 1219 {
<> 144:ef7eb2e8f9f7 1220 dspiEdmaPrivateHandle->handle->callback(dspiEdmaPrivateHandle->base, dspiEdmaPrivateHandle->handle,
<> 144:ef7eb2e8f9f7 1221 kStatus_Success, dspiEdmaPrivateHandle->handle->userData);
<> 144:ef7eb2e8f9f7 1222 }
<> 144:ef7eb2e8f9f7 1223
<> 144:ef7eb2e8f9f7 1224 dspiEdmaPrivateHandle->handle->state = kDSPI_Idle;
<> 144:ef7eb2e8f9f7 1225 }
<> 144:ef7eb2e8f9f7 1226
<> 144:ef7eb2e8f9f7 1227 void DSPI_SlaveTransferAbortEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle)
<> 144:ef7eb2e8f9f7 1228 {
<> 144:ef7eb2e8f9f7 1229 DSPI_StopTransfer(base);
<> 144:ef7eb2e8f9f7 1230
<> 144:ef7eb2e8f9f7 1231 DSPI_DisableDMA(base, kDSPI_RxDmaEnable | kDSPI_TxDmaEnable);
<> 144:ef7eb2e8f9f7 1232
<> 144:ef7eb2e8f9f7 1233 EDMA_AbortTransfer(handle->edmaRxRegToRxDataHandle);
<> 144:ef7eb2e8f9f7 1234 EDMA_AbortTransfer(handle->edmaTxDataToTxRegHandle);
<> 144:ef7eb2e8f9f7 1235
<> 144:ef7eb2e8f9f7 1236 handle->state = kDSPI_Idle;
<> 144:ef7eb2e8f9f7 1237 }
<> 144:ef7eb2e8f9f7 1238
<> 144:ef7eb2e8f9f7 1239 status_t DSPI_SlaveTransferGetCountEDMA(SPI_Type *base, dspi_slave_edma_handle_t *handle, size_t *count)
<> 144:ef7eb2e8f9f7 1240 {
<> 144:ef7eb2e8f9f7 1241 assert(handle);
<> 144:ef7eb2e8f9f7 1242
<> 144:ef7eb2e8f9f7 1243 if (!count)
<> 144:ef7eb2e8f9f7 1244 {
<> 144:ef7eb2e8f9f7 1245 return kStatus_InvalidArgument;
<> 144:ef7eb2e8f9f7 1246 }
<> 144:ef7eb2e8f9f7 1247
<> 144:ef7eb2e8f9f7 1248 /* Catch when there is not an active transfer. */
<> 144:ef7eb2e8f9f7 1249 if (handle->state != kDSPI_Busy)
<> 144:ef7eb2e8f9f7 1250 {
<> 144:ef7eb2e8f9f7 1251 *count = 0;
<> 144:ef7eb2e8f9f7 1252 return kStatus_NoTransferInProgress;
<> 144:ef7eb2e8f9f7 1253 }
<> 144:ef7eb2e8f9f7 1254
<> 144:ef7eb2e8f9f7 1255 size_t bytes;
<> 144:ef7eb2e8f9f7 1256
<> 144:ef7eb2e8f9f7 1257 bytes = EDMA_GetRemainingBytes(handle->edmaRxRegToRxDataHandle->base, handle->edmaRxRegToRxDataHandle->channel);
<> 144:ef7eb2e8f9f7 1258
<> 144:ef7eb2e8f9f7 1259 *count = handle->totalByteCount - bytes;
<> 144:ef7eb2e8f9f7 1260
<> 144:ef7eb2e8f9f7 1261 return kStatus_Success;
<> 144:ef7eb2e8f9f7 1262 }