Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
targets/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL27Z/drivers/fsl_flexio_spi_dma.c@0:f269e3021894, 2016-10-23 (annotated)
- Committer:
- elessair
- Date:
- Sun Oct 23 15:10:02 2016 +0000
- Revision:
- 0:f269e3021894
Initial commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
elessair | 0:f269e3021894 | 1 | /* |
elessair | 0:f269e3021894 | 2 | * Copyright (c) 2015, Freescale Semiconductor, Inc. |
elessair | 0:f269e3021894 | 3 | * All rights reserved. |
elessair | 0:f269e3021894 | 4 | * |
elessair | 0:f269e3021894 | 5 | * Redistribution and use in source and binary forms, with or without modification, |
elessair | 0:f269e3021894 | 6 | * are permitted provided that the following conditions are met: |
elessair | 0:f269e3021894 | 7 | * |
elessair | 0:f269e3021894 | 8 | * o Redistributions of source code must retain the above copyright notice, this list |
elessair | 0:f269e3021894 | 9 | * of conditions and the following disclaimer. |
elessair | 0:f269e3021894 | 10 | * |
elessair | 0:f269e3021894 | 11 | * o Redistributions in binary form must reproduce the above copyright notice, this |
elessair | 0:f269e3021894 | 12 | * list of conditions and the following disclaimer in the documentation and/or |
elessair | 0:f269e3021894 | 13 | * other materials provided with the distribution. |
elessair | 0:f269e3021894 | 14 | * |
elessair | 0:f269e3021894 | 15 | * o Neither the name of Freescale Semiconductor, Inc. nor the names of its |
elessair | 0:f269e3021894 | 16 | * contributors may be used to endorse or promote products derived from this |
elessair | 0:f269e3021894 | 17 | * software without specific prior written permission. |
elessair | 0:f269e3021894 | 18 | * |
elessair | 0:f269e3021894 | 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
elessair | 0:f269e3021894 | 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
elessair | 0:f269e3021894 | 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
elessair | 0:f269e3021894 | 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR |
elessair | 0:f269e3021894 | 23 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
elessair | 0:f269e3021894 | 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
elessair | 0:f269e3021894 | 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
elessair | 0:f269e3021894 | 26 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
elessair | 0:f269e3021894 | 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
elessair | 0:f269e3021894 | 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
elessair | 0:f269e3021894 | 29 | */ |
elessair | 0:f269e3021894 | 30 | |
elessair | 0:f269e3021894 | 31 | #include "fsl_flexio_spi_dma.h" |
elessair | 0:f269e3021894 | 32 | |
elessair | 0:f269e3021894 | 33 | /******************************************************************************* |
elessair | 0:f269e3021894 | 34 | * Definitons |
elessair | 0:f269e3021894 | 35 | ******************************************************************************/ |
elessair | 0:f269e3021894 | 36 | |
elessair | 0:f269e3021894 | 37 | /*<! Structure definition for spi_dma_private_handle_t. The structure is private. */ |
elessair | 0:f269e3021894 | 38 | typedef struct _flexio_spi_master_dma_private_handle |
elessair | 0:f269e3021894 | 39 | { |
elessair | 0:f269e3021894 | 40 | FLEXIO_SPI_Type *base; |
elessair | 0:f269e3021894 | 41 | flexio_spi_master_dma_handle_t *handle; |
elessair | 0:f269e3021894 | 42 | } flexio_spi_master_dma_private_handle_t; |
elessair | 0:f269e3021894 | 43 | |
elessair | 0:f269e3021894 | 44 | /******************************************************************************* |
elessair | 0:f269e3021894 | 45 | * Prototypes |
elessair | 0:f269e3021894 | 46 | ******************************************************************************/ |
elessair | 0:f269e3021894 | 47 | |
elessair | 0:f269e3021894 | 48 | /*! |
elessair | 0:f269e3021894 | 49 | * @brief DMA callback function for FLEXIO SPI send transfer. |
elessair | 0:f269e3021894 | 50 | * |
elessair | 0:f269e3021894 | 51 | * @param handle DMA handle pointer. |
elessair | 0:f269e3021894 | 52 | * @param param Callback function parameter. |
elessair | 0:f269e3021894 | 53 | */ |
elessair | 0:f269e3021894 | 54 | static void FLEXIO_SPI_TxDMACallback(dma_handle_t *handle, void *param); |
elessair | 0:f269e3021894 | 55 | |
elessair | 0:f269e3021894 | 56 | /*! |
elessair | 0:f269e3021894 | 57 | * @brief DMA callback function for FLEXIO SPI receive transfer. |
elessair | 0:f269e3021894 | 58 | * |
elessair | 0:f269e3021894 | 59 | * @param handle DMA handle pointer. |
elessair | 0:f269e3021894 | 60 | * @param param Callback function parameter. |
elessair | 0:f269e3021894 | 61 | */ |
elessair | 0:f269e3021894 | 62 | static void FLEXIO_SPI_RxDMACallback(dma_handle_t *handle, void *param); |
elessair | 0:f269e3021894 | 63 | |
elessair | 0:f269e3021894 | 64 | /*! |
elessair | 0:f269e3021894 | 65 | * @brief EDMA config for FLEXIO SPI transfer. |
elessair | 0:f269e3021894 | 66 | * |
elessair | 0:f269e3021894 | 67 | * @param base pointer to FLEXIO_SPI_Type structure. |
elessair | 0:f269e3021894 | 68 | * @param handle pointer to flexio_spi_master_dma_handle_t structure to store the transfer state. |
elessair | 0:f269e3021894 | 69 | * @param xfer Pointer to flexio spi transfer structure. |
elessair | 0:f269e3021894 | 70 | */ |
elessair | 0:f269e3021894 | 71 | static void FLEXIO_SPI_DMAConfig(FLEXIO_SPI_Type *base, |
elessair | 0:f269e3021894 | 72 | flexio_spi_master_dma_handle_t *handle, |
elessair | 0:f269e3021894 | 73 | flexio_spi_transfer_t *xfer); |
elessair | 0:f269e3021894 | 74 | |
elessair | 0:f269e3021894 | 75 | /******************************************************************************* |
elessair | 0:f269e3021894 | 76 | * Variables |
elessair | 0:f269e3021894 | 77 | ******************************************************************************/ |
elessair | 0:f269e3021894 | 78 | |
elessair | 0:f269e3021894 | 79 | /* Dummy data used to send */ |
elessair | 0:f269e3021894 | 80 | static const uint16_t s_dummyData = FLEXIO_SPI_DUMMYDATA; |
elessair | 0:f269e3021894 | 81 | |
elessair | 0:f269e3021894 | 82 | /*< @brief user configurable flexio spi handle count. */ |
elessair | 0:f269e3021894 | 83 | #define FLEXIO_SPI_HANDLE_COUNT 2 |
elessair | 0:f269e3021894 | 84 | |
elessair | 0:f269e3021894 | 85 | /*<! Private handle only used for internally. */ |
elessair | 0:f269e3021894 | 86 | static flexio_spi_master_dma_private_handle_t s_dmaPrivateHandle[FLEXIO_SPI_HANDLE_COUNT]; |
elessair | 0:f269e3021894 | 87 | |
elessair | 0:f269e3021894 | 88 | /******************************************************************************* |
elessair | 0:f269e3021894 | 89 | * Code |
elessair | 0:f269e3021894 | 90 | ******************************************************************************/ |
elessair | 0:f269e3021894 | 91 | |
elessair | 0:f269e3021894 | 92 | static void FLEXIO_SPI_TxDMACallback(dma_handle_t *handle, void *param) |
elessair | 0:f269e3021894 | 93 | { |
elessair | 0:f269e3021894 | 94 | flexio_spi_master_dma_private_handle_t *spiPrivateHandle = (flexio_spi_master_dma_private_handle_t *)param; |
elessair | 0:f269e3021894 | 95 | |
elessair | 0:f269e3021894 | 96 | /* Disable Tx DMA. */ |
elessair | 0:f269e3021894 | 97 | FLEXIO_SPI_EnableDMA(spiPrivateHandle->base, kFLEXIO_SPI_TxDmaEnable, false); |
elessair | 0:f269e3021894 | 98 | |
elessair | 0:f269e3021894 | 99 | /* Disable interrupt. */ |
elessair | 0:f269e3021894 | 100 | DMA_DisableInterrupts(handle->base, handle->channel); |
elessair | 0:f269e3021894 | 101 | |
elessair | 0:f269e3021894 | 102 | /* change the state. */ |
elessair | 0:f269e3021894 | 103 | spiPrivateHandle->handle->txInProgress = false; |
elessair | 0:f269e3021894 | 104 | |
elessair | 0:f269e3021894 | 105 | /* All finished, call the callback. */ |
elessair | 0:f269e3021894 | 106 | if ((spiPrivateHandle->handle->txInProgress == false) && (spiPrivateHandle->handle->rxInProgress == false)) |
elessair | 0:f269e3021894 | 107 | { |
elessair | 0:f269e3021894 | 108 | if (spiPrivateHandle->handle->callback) |
elessair | 0:f269e3021894 | 109 | { |
elessair | 0:f269e3021894 | 110 | (spiPrivateHandle->handle->callback)(spiPrivateHandle->base, spiPrivateHandle->handle, kStatus_Success, |
elessair | 0:f269e3021894 | 111 | spiPrivateHandle->handle->userData); |
elessair | 0:f269e3021894 | 112 | } |
elessair | 0:f269e3021894 | 113 | } |
elessair | 0:f269e3021894 | 114 | } |
elessair | 0:f269e3021894 | 115 | |
elessair | 0:f269e3021894 | 116 | static void FLEXIO_SPI_RxDMACallback(dma_handle_t *handle, void *param) |
elessair | 0:f269e3021894 | 117 | { |
elessair | 0:f269e3021894 | 118 | flexio_spi_master_dma_private_handle_t *spiPrivateHandle = (flexio_spi_master_dma_private_handle_t *)param; |
elessair | 0:f269e3021894 | 119 | |
elessair | 0:f269e3021894 | 120 | /* Disable Rx DMA. */ |
elessair | 0:f269e3021894 | 121 | FLEXIO_SPI_EnableDMA(spiPrivateHandle->base, kFLEXIO_SPI_RxDmaEnable, false); |
elessair | 0:f269e3021894 | 122 | |
elessair | 0:f269e3021894 | 123 | /* Disable interrupt. */ |
elessair | 0:f269e3021894 | 124 | DMA_DisableInterrupts(handle->base, handle->channel); |
elessair | 0:f269e3021894 | 125 | |
elessair | 0:f269e3021894 | 126 | /* change the state. */ |
elessair | 0:f269e3021894 | 127 | spiPrivateHandle->handle->rxInProgress = false; |
elessair | 0:f269e3021894 | 128 | |
elessair | 0:f269e3021894 | 129 | /* All finished, call the callback. */ |
elessair | 0:f269e3021894 | 130 | if ((spiPrivateHandle->handle->txInProgress == false) && (spiPrivateHandle->handle->rxInProgress == false)) |
elessair | 0:f269e3021894 | 131 | { |
elessair | 0:f269e3021894 | 132 | if (spiPrivateHandle->handle->callback) |
elessair | 0:f269e3021894 | 133 | { |
elessair | 0:f269e3021894 | 134 | (spiPrivateHandle->handle->callback)(spiPrivateHandle->base, spiPrivateHandle->handle, kStatus_Success, |
elessair | 0:f269e3021894 | 135 | spiPrivateHandle->handle->userData); |
elessair | 0:f269e3021894 | 136 | } |
elessair | 0:f269e3021894 | 137 | } |
elessair | 0:f269e3021894 | 138 | } |
elessair | 0:f269e3021894 | 139 | |
elessair | 0:f269e3021894 | 140 | static void FLEXIO_SPI_DMAConfig(FLEXIO_SPI_Type *base, |
elessair | 0:f269e3021894 | 141 | flexio_spi_master_dma_handle_t *handle, |
elessair | 0:f269e3021894 | 142 | flexio_spi_transfer_t *xfer) |
elessair | 0:f269e3021894 | 143 | { |
elessair | 0:f269e3021894 | 144 | dma_transfer_config_t xferConfig; |
elessair | 0:f269e3021894 | 145 | flexio_spi_shift_direction_t direction; |
elessair | 0:f269e3021894 | 146 | uint8_t bytesPerFrame; |
elessair | 0:f269e3021894 | 147 | |
elessair | 0:f269e3021894 | 148 | /* Configure the values in handle. */ |
elessair | 0:f269e3021894 | 149 | switch (xfer->flags) |
elessair | 0:f269e3021894 | 150 | { |
elessair | 0:f269e3021894 | 151 | case kFLEXIO_SPI_8bitMsb: |
elessair | 0:f269e3021894 | 152 | bytesPerFrame = 1; |
elessair | 0:f269e3021894 | 153 | direction = kFLEXIO_SPI_MsbFirst; |
elessair | 0:f269e3021894 | 154 | break; |
elessair | 0:f269e3021894 | 155 | case kFLEXIO_SPI_8bitLsb: |
elessair | 0:f269e3021894 | 156 | bytesPerFrame = 1; |
elessair | 0:f269e3021894 | 157 | direction = kFLEXIO_SPI_LsbFirst; |
elessair | 0:f269e3021894 | 158 | break; |
elessair | 0:f269e3021894 | 159 | case kFLEXIO_SPI_16bitMsb: |
elessair | 0:f269e3021894 | 160 | bytesPerFrame = 2; |
elessair | 0:f269e3021894 | 161 | direction = kFLEXIO_SPI_MsbFirst; |
elessair | 0:f269e3021894 | 162 | break; |
elessair | 0:f269e3021894 | 163 | case kFLEXIO_SPI_16bitLsb: |
elessair | 0:f269e3021894 | 164 | bytesPerFrame = 2; |
elessair | 0:f269e3021894 | 165 | direction = kFLEXIO_SPI_LsbFirst; |
elessair | 0:f269e3021894 | 166 | break; |
elessair | 0:f269e3021894 | 167 | default: |
elessair | 0:f269e3021894 | 168 | bytesPerFrame = 1; |
elessair | 0:f269e3021894 | 169 | direction = kFLEXIO_SPI_MsbFirst; |
elessair | 0:f269e3021894 | 170 | assert(true); |
elessair | 0:f269e3021894 | 171 | break; |
elessair | 0:f269e3021894 | 172 | } |
elessair | 0:f269e3021894 | 173 | |
elessair | 0:f269e3021894 | 174 | /* Save total transfer size. */ |
elessair | 0:f269e3021894 | 175 | handle->transferSize = xfer->dataSize; |
elessair | 0:f269e3021894 | 176 | |
elessair | 0:f269e3021894 | 177 | /* Configure tx transfer DMA. */ |
elessair | 0:f269e3021894 | 178 | xferConfig.destAddr = FLEXIO_SPI_GetTxDataRegisterAddress(base, direction); |
elessair | 0:f269e3021894 | 179 | xferConfig.enableDestIncrement = false; |
elessair | 0:f269e3021894 | 180 | if (bytesPerFrame == 1U) |
elessair | 0:f269e3021894 | 181 | { |
elessair | 0:f269e3021894 | 182 | xferConfig.srcSize = kDMA_Transfersize8bits; |
elessair | 0:f269e3021894 | 183 | xferConfig.destSize = kDMA_Transfersize8bits; |
elessair | 0:f269e3021894 | 184 | } |
elessair | 0:f269e3021894 | 185 | else |
elessair | 0:f269e3021894 | 186 | { |
elessair | 0:f269e3021894 | 187 | if (direction == kFLEXIO_SPI_MsbFirst) |
elessair | 0:f269e3021894 | 188 | { |
elessair | 0:f269e3021894 | 189 | xferConfig.destAddr -= 1U; |
elessair | 0:f269e3021894 | 190 | } |
elessair | 0:f269e3021894 | 191 | xferConfig.srcSize = kDMA_Transfersize16bits; |
elessair | 0:f269e3021894 | 192 | xferConfig.destSize = kDMA_Transfersize16bits; |
elessair | 0:f269e3021894 | 193 | } |
elessair | 0:f269e3021894 | 194 | |
elessair | 0:f269e3021894 | 195 | /* Configure DMA channel. */ |
elessair | 0:f269e3021894 | 196 | if (xfer->txData) |
elessair | 0:f269e3021894 | 197 | { |
elessair | 0:f269e3021894 | 198 | xferConfig.enableSrcIncrement = true; |
elessair | 0:f269e3021894 | 199 | xferConfig.srcAddr = (uint32_t)(xfer->txData); |
elessair | 0:f269e3021894 | 200 | } |
elessair | 0:f269e3021894 | 201 | else |
elessair | 0:f269e3021894 | 202 | { |
elessair | 0:f269e3021894 | 203 | /* Disable the source increasement and source set to dummyData. */ |
elessair | 0:f269e3021894 | 204 | xferConfig.enableSrcIncrement = false; |
elessair | 0:f269e3021894 | 205 | xferConfig.srcAddr = (uint32_t)(&s_dummyData); |
elessair | 0:f269e3021894 | 206 | } |
elessair | 0:f269e3021894 | 207 | |
elessair | 0:f269e3021894 | 208 | xferConfig.transferSize = xfer->dataSize; |
elessair | 0:f269e3021894 | 209 | |
elessair | 0:f269e3021894 | 210 | if (handle->txHandle) |
elessair | 0:f269e3021894 | 211 | { |
elessair | 0:f269e3021894 | 212 | DMA_SubmitTransfer(handle->txHandle, &xferConfig, kDMA_EnableInterrupt); |
elessair | 0:f269e3021894 | 213 | } |
elessair | 0:f269e3021894 | 214 | |
elessair | 0:f269e3021894 | 215 | /* Configure tx transfer DMA. */ |
elessair | 0:f269e3021894 | 216 | if (xfer->rxData) |
elessair | 0:f269e3021894 | 217 | { |
elessair | 0:f269e3021894 | 218 | xferConfig.srcAddr = FLEXIO_SPI_GetRxDataRegisterAddress(base, direction); |
elessair | 0:f269e3021894 | 219 | xferConfig.enableSrcIncrement = false; |
elessair | 0:f269e3021894 | 220 | xferConfig.destAddr = (uint32_t)(xfer->rxData); |
elessair | 0:f269e3021894 | 221 | xferConfig.enableDestIncrement = true; |
elessair | 0:f269e3021894 | 222 | DMA_SubmitTransfer(handle->rxHandle, &xferConfig, kDMA_EnableInterrupt); |
elessair | 0:f269e3021894 | 223 | handle->rxInProgress = true; |
elessair | 0:f269e3021894 | 224 | FLEXIO_SPI_EnableDMA(base, kFLEXIO_SPI_RxDmaEnable, true); |
elessair | 0:f269e3021894 | 225 | DMA_StartTransfer(handle->rxHandle); |
elessair | 0:f269e3021894 | 226 | } |
elessair | 0:f269e3021894 | 227 | |
elessair | 0:f269e3021894 | 228 | /* Always start Tx transfer. */ |
elessair | 0:f269e3021894 | 229 | if (handle->txHandle) |
elessair | 0:f269e3021894 | 230 | { |
elessair | 0:f269e3021894 | 231 | handle->txInProgress = true; |
elessair | 0:f269e3021894 | 232 | FLEXIO_SPI_EnableDMA(base, kFLEXIO_SPI_TxDmaEnable, true); |
elessair | 0:f269e3021894 | 233 | DMA_StartTransfer(handle->txHandle); |
elessair | 0:f269e3021894 | 234 | } |
elessair | 0:f269e3021894 | 235 | } |
elessair | 0:f269e3021894 | 236 | |
elessair | 0:f269e3021894 | 237 | status_t FLEXIO_SPI_MasterTransferCreateHandleDMA(FLEXIO_SPI_Type *base, |
elessair | 0:f269e3021894 | 238 | flexio_spi_master_dma_handle_t *handle, |
elessair | 0:f269e3021894 | 239 | flexio_spi_master_dma_transfer_callback_t callback, |
elessair | 0:f269e3021894 | 240 | void *userData, |
elessair | 0:f269e3021894 | 241 | dma_handle_t *txHandle, |
elessair | 0:f269e3021894 | 242 | dma_handle_t *rxHandle) |
elessair | 0:f269e3021894 | 243 | { |
elessair | 0:f269e3021894 | 244 | assert(handle); |
elessair | 0:f269e3021894 | 245 | |
elessair | 0:f269e3021894 | 246 | uint8_t index = 0; |
elessair | 0:f269e3021894 | 247 | |
elessair | 0:f269e3021894 | 248 | /* Find the an empty handle pointer to store the handle. */ |
elessair | 0:f269e3021894 | 249 | for (index = 0; index < FLEXIO_SPI_HANDLE_COUNT; index++) |
elessair | 0:f269e3021894 | 250 | { |
elessair | 0:f269e3021894 | 251 | if (s_dmaPrivateHandle[index].base == NULL) |
elessair | 0:f269e3021894 | 252 | { |
elessair | 0:f269e3021894 | 253 | s_dmaPrivateHandle[index].base = base; |
elessair | 0:f269e3021894 | 254 | s_dmaPrivateHandle[index].handle = handle; |
elessair | 0:f269e3021894 | 255 | break; |
elessair | 0:f269e3021894 | 256 | } |
elessair | 0:f269e3021894 | 257 | } |
elessair | 0:f269e3021894 | 258 | |
elessair | 0:f269e3021894 | 259 | if (index == FLEXIO_SPI_HANDLE_COUNT) |
elessair | 0:f269e3021894 | 260 | { |
elessair | 0:f269e3021894 | 261 | return kStatus_OutOfRange; |
elessair | 0:f269e3021894 | 262 | } |
elessair | 0:f269e3021894 | 263 | |
elessair | 0:f269e3021894 | 264 | /* Set spi base to handle. */ |
elessair | 0:f269e3021894 | 265 | handle->txHandle = txHandle; |
elessair | 0:f269e3021894 | 266 | handle->rxHandle = rxHandle; |
elessair | 0:f269e3021894 | 267 | |
elessair | 0:f269e3021894 | 268 | /* Register callback and userData. */ |
elessair | 0:f269e3021894 | 269 | handle->callback = callback; |
elessair | 0:f269e3021894 | 270 | handle->userData = userData; |
elessair | 0:f269e3021894 | 271 | |
elessair | 0:f269e3021894 | 272 | /* Set SPI state to idle. */ |
elessair | 0:f269e3021894 | 273 | handle->txInProgress = false; |
elessair | 0:f269e3021894 | 274 | handle->rxInProgress = false; |
elessair | 0:f269e3021894 | 275 | |
elessair | 0:f269e3021894 | 276 | /* Install callback for Tx/Rx dma channel. */ |
elessair | 0:f269e3021894 | 277 | if (handle->txHandle) |
elessair | 0:f269e3021894 | 278 | { |
elessair | 0:f269e3021894 | 279 | DMA_SetCallback(handle->txHandle, FLEXIO_SPI_TxDMACallback, &s_dmaPrivateHandle[index]); |
elessair | 0:f269e3021894 | 280 | } |
elessair | 0:f269e3021894 | 281 | if (handle->rxHandle) |
elessair | 0:f269e3021894 | 282 | { |
elessair | 0:f269e3021894 | 283 | DMA_SetCallback(handle->rxHandle, FLEXIO_SPI_RxDMACallback, &s_dmaPrivateHandle[index]); |
elessair | 0:f269e3021894 | 284 | } |
elessair | 0:f269e3021894 | 285 | |
elessair | 0:f269e3021894 | 286 | return kStatus_Success; |
elessair | 0:f269e3021894 | 287 | } |
elessair | 0:f269e3021894 | 288 | |
elessair | 0:f269e3021894 | 289 | status_t FLEXIO_SPI_MasterTransferDMA(FLEXIO_SPI_Type *base, |
elessair | 0:f269e3021894 | 290 | flexio_spi_master_dma_handle_t *handle, |
elessair | 0:f269e3021894 | 291 | flexio_spi_transfer_t *xfer) |
elessair | 0:f269e3021894 | 292 | { |
elessair | 0:f269e3021894 | 293 | assert(handle); |
elessair | 0:f269e3021894 | 294 | assert(xfer); |
elessair | 0:f269e3021894 | 295 | |
elessair | 0:f269e3021894 | 296 | uint32_t dataMode = 0; |
elessair | 0:f269e3021894 | 297 | uint16_t timerCmp = base->flexioBase->TIMCMP[base->timerIndex[0]]; |
elessair | 0:f269e3021894 | 298 | |
elessair | 0:f269e3021894 | 299 | timerCmp &= 0x00FFU; |
elessair | 0:f269e3021894 | 300 | |
elessair | 0:f269e3021894 | 301 | /* Check if the device is busy. */ |
elessair | 0:f269e3021894 | 302 | if ((handle->txInProgress) || (handle->rxInProgress)) |
elessair | 0:f269e3021894 | 303 | { |
elessair | 0:f269e3021894 | 304 | return kStatus_FLEXIO_SPI_Busy; |
elessair | 0:f269e3021894 | 305 | } |
elessair | 0:f269e3021894 | 306 | |
elessair | 0:f269e3021894 | 307 | /* Check if input parameter invalid. */ |
elessair | 0:f269e3021894 | 308 | if (((xfer->txData == NULL) && (xfer->rxData == NULL)) || (xfer->dataSize == 0U)) |
elessair | 0:f269e3021894 | 309 | { |
elessair | 0:f269e3021894 | 310 | return kStatus_InvalidArgument; |
elessair | 0:f269e3021894 | 311 | } |
elessair | 0:f269e3021894 | 312 | |
elessair | 0:f269e3021894 | 313 | /* configure data mode. */ |
elessair | 0:f269e3021894 | 314 | if ((xfer->flags == kFLEXIO_SPI_8bitMsb) || (xfer->flags == kFLEXIO_SPI_8bitLsb)) |
elessair | 0:f269e3021894 | 315 | { |
elessair | 0:f269e3021894 | 316 | dataMode = (8 * 2 - 1U) << 8U; |
elessair | 0:f269e3021894 | 317 | } |
elessair | 0:f269e3021894 | 318 | else if ((xfer->flags == kFLEXIO_SPI_16bitMsb) || (xfer->flags == kFLEXIO_SPI_16bitLsb)) |
elessair | 0:f269e3021894 | 319 | { |
elessair | 0:f269e3021894 | 320 | dataMode = (16 * 2 - 1U) << 8U; |
elessair | 0:f269e3021894 | 321 | } |
elessair | 0:f269e3021894 | 322 | else |
elessair | 0:f269e3021894 | 323 | { |
elessair | 0:f269e3021894 | 324 | dataMode = 8 * 2 - 1U; |
elessair | 0:f269e3021894 | 325 | } |
elessair | 0:f269e3021894 | 326 | |
elessair | 0:f269e3021894 | 327 | dataMode |= timerCmp; |
elessair | 0:f269e3021894 | 328 | |
elessair | 0:f269e3021894 | 329 | base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode; |
elessair | 0:f269e3021894 | 330 | |
elessair | 0:f269e3021894 | 331 | FLEXIO_SPI_DMAConfig(base, handle, xfer); |
elessair | 0:f269e3021894 | 332 | |
elessair | 0:f269e3021894 | 333 | return kStatus_Success; |
elessair | 0:f269e3021894 | 334 | } |
elessair | 0:f269e3021894 | 335 | |
elessair | 0:f269e3021894 | 336 | status_t FLEXIO_SPI_MasterTransferGetCountDMA(FLEXIO_SPI_Type *base, |
elessair | 0:f269e3021894 | 337 | flexio_spi_master_dma_handle_t *handle, |
elessair | 0:f269e3021894 | 338 | size_t *count) |
elessair | 0:f269e3021894 | 339 | { |
elessair | 0:f269e3021894 | 340 | assert(handle); |
elessair | 0:f269e3021894 | 341 | |
elessair | 0:f269e3021894 | 342 | if (!count) |
elessair | 0:f269e3021894 | 343 | { |
elessair | 0:f269e3021894 | 344 | return kStatus_InvalidArgument; |
elessair | 0:f269e3021894 | 345 | } |
elessair | 0:f269e3021894 | 346 | |
elessair | 0:f269e3021894 | 347 | if (handle->rxInProgress) |
elessair | 0:f269e3021894 | 348 | { |
elessair | 0:f269e3021894 | 349 | *count = (handle->transferSize - DMA_GetRemainingBytes(handle->rxHandle->base, handle->rxHandle->channel)); |
elessair | 0:f269e3021894 | 350 | } |
elessair | 0:f269e3021894 | 351 | else |
elessair | 0:f269e3021894 | 352 | { |
elessair | 0:f269e3021894 | 353 | *count = (handle->transferSize - DMA_GetRemainingBytes(handle->txHandle->base, handle->txHandle->channel)); |
elessair | 0:f269e3021894 | 354 | } |
elessair | 0:f269e3021894 | 355 | |
elessair | 0:f269e3021894 | 356 | return kStatus_Success; |
elessair | 0:f269e3021894 | 357 | } |
elessair | 0:f269e3021894 | 358 | |
elessair | 0:f269e3021894 | 359 | void FLEXIO_SPI_MasterTransferAbortDMA(FLEXIO_SPI_Type *base, flexio_spi_master_dma_handle_t *handle) |
elessair | 0:f269e3021894 | 360 | { |
elessair | 0:f269e3021894 | 361 | assert(handle); |
elessair | 0:f269e3021894 | 362 | |
elessair | 0:f269e3021894 | 363 | /* Disable dma. */ |
elessair | 0:f269e3021894 | 364 | DMA_AbortTransfer(handle->txHandle); |
elessair | 0:f269e3021894 | 365 | DMA_AbortTransfer(handle->rxHandle); |
elessair | 0:f269e3021894 | 366 | |
elessair | 0:f269e3021894 | 367 | /* Disable DMA enable bit. */ |
elessair | 0:f269e3021894 | 368 | FLEXIO_SPI_EnableDMA(base, kFLEXIO_SPI_DmaAllEnable, false); |
elessair | 0:f269e3021894 | 369 | |
elessair | 0:f269e3021894 | 370 | /* Set the handle state. */ |
elessair | 0:f269e3021894 | 371 | handle->txInProgress = false; |
elessair | 0:f269e3021894 | 372 | handle->rxInProgress = false; |
elessair | 0:f269e3021894 | 373 | } |
elessair | 0:f269e3021894 | 374 | |
elessair | 0:f269e3021894 | 375 | status_t FLEXIO_SPI_SlaveTransferDMA(FLEXIO_SPI_Type *base, |
elessair | 0:f269e3021894 | 376 | flexio_spi_slave_dma_handle_t *handle, |
elessair | 0:f269e3021894 | 377 | flexio_spi_transfer_t *xfer) |
elessair | 0:f269e3021894 | 378 | { |
elessair | 0:f269e3021894 | 379 | assert(handle); |
elessair | 0:f269e3021894 | 380 | assert(xfer); |
elessair | 0:f269e3021894 | 381 | |
elessair | 0:f269e3021894 | 382 | uint32_t dataMode = 0; |
elessair | 0:f269e3021894 | 383 | |
elessair | 0:f269e3021894 | 384 | /* Check if the device is busy. */ |
elessair | 0:f269e3021894 | 385 | if ((handle->txInProgress) || (handle->rxInProgress)) |
elessair | 0:f269e3021894 | 386 | { |
elessair | 0:f269e3021894 | 387 | return kStatus_FLEXIO_SPI_Busy; |
elessair | 0:f269e3021894 | 388 | } |
elessair | 0:f269e3021894 | 389 | |
elessair | 0:f269e3021894 | 390 | /* Check if input parameter invalid. */ |
elessair | 0:f269e3021894 | 391 | if (((xfer->txData == NULL) && (xfer->rxData == NULL)) || (xfer->dataSize == 0U)) |
elessair | 0:f269e3021894 | 392 | { |
elessair | 0:f269e3021894 | 393 | return kStatus_InvalidArgument; |
elessair | 0:f269e3021894 | 394 | } |
elessair | 0:f269e3021894 | 395 | |
elessair | 0:f269e3021894 | 396 | /* configure data mode. */ |
elessair | 0:f269e3021894 | 397 | if ((xfer->flags == kFLEXIO_SPI_8bitMsb) || (xfer->flags == kFLEXIO_SPI_8bitLsb)) |
elessair | 0:f269e3021894 | 398 | { |
elessair | 0:f269e3021894 | 399 | dataMode = 8 * 2 - 1U; |
elessair | 0:f269e3021894 | 400 | } |
elessair | 0:f269e3021894 | 401 | else if ((xfer->flags == kFLEXIO_SPI_16bitMsb) || (xfer->flags == kFLEXIO_SPI_16bitLsb)) |
elessair | 0:f269e3021894 | 402 | { |
elessair | 0:f269e3021894 | 403 | dataMode = 16 * 2 - 1U; |
elessair | 0:f269e3021894 | 404 | } |
elessair | 0:f269e3021894 | 405 | else |
elessair | 0:f269e3021894 | 406 | { |
elessair | 0:f269e3021894 | 407 | dataMode = 8 * 2 - 1U; |
elessair | 0:f269e3021894 | 408 | } |
elessair | 0:f269e3021894 | 409 | |
elessair | 0:f269e3021894 | 410 | base->flexioBase->TIMCMP[base->timerIndex[0]] = dataMode; |
elessair | 0:f269e3021894 | 411 | |
elessair | 0:f269e3021894 | 412 | FLEXIO_SPI_DMAConfig(base, handle, xfer); |
elessair | 0:f269e3021894 | 413 | |
elessair | 0:f269e3021894 | 414 | return kStatus_Success; |
elessair | 0:f269e3021894 | 415 | } |