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.
Dependents: Nucleo_Hello_Encoder BLE_iBeaconScan AM1805_DEMO DISCO-F429ZI_ExportTemplate1 ... more
targets/TARGET_NXP/TARGET_MCUXpresso_MCUS/TARGET_LPC546XX/drivers/fsl_spi_dma.c@182:a56a73fd2a6f, 2018-03-20 (annotated)
- Committer:
- AnnaBridge
- Date:
- Tue Mar 20 16:56:18 2018 +0000
- Revision:
- 182:a56a73fd2a6f
- Parent:
- 175:af195413fb11
mbed-dev library. Release version 160
Who changed what in which revision?
| User | Revision | Line number | New contents of line | 
|---|---|---|---|
| Kojto | 170:19eb464bc2be | 1 | /* | 
| AnnaBridge | 182:a56a73fd2a6f | 2 | * The Clear BSD License | 
| Kojto | 170:19eb464bc2be | 3 | * Copyright (c) 2016, Freescale Semiconductor, Inc. | 
| Kojto | 170:19eb464bc2be | 4 | * Copyright 2016-2017 NXP | 
| AnnaBridge | 182:a56a73fd2a6f | 5 | * All rights reserved. | 
| Kojto | 170:19eb464bc2be | 6 | * | 
| Kojto | 170:19eb464bc2be | 7 | * Redistribution and use in source and binary forms, with or without modification, | 
| AnnaBridge | 182:a56a73fd2a6f | 8 | * are permitted (subject to the limitations in the disclaimer below) provided | 
| AnnaBridge | 182:a56a73fd2a6f | 9 | * that the following conditions are met: | 
| Kojto | 170:19eb464bc2be | 10 | * | 
| Kojto | 170:19eb464bc2be | 11 | * o Redistributions of source code must retain the above copyright notice, this list | 
| Kojto | 170:19eb464bc2be | 12 | * of conditions and the following disclaimer. | 
| Kojto | 170:19eb464bc2be | 13 | * | 
| Kojto | 170:19eb464bc2be | 14 | * o Redistributions in binary form must reproduce the above copyright notice, this | 
| Kojto | 170:19eb464bc2be | 15 | * list of conditions and the following disclaimer in the documentation and/or | 
| Kojto | 170:19eb464bc2be | 16 | * other materials provided with the distribution. | 
| Kojto | 170:19eb464bc2be | 17 | * | 
| Kojto | 170:19eb464bc2be | 18 | * o Neither the name of the copyright holder nor the names of its | 
| Kojto | 170:19eb464bc2be | 19 | * contributors may be used to endorse or promote products derived from this | 
| Kojto | 170:19eb464bc2be | 20 | * software without specific prior written permission. | 
| Kojto | 170:19eb464bc2be | 21 | * | 
| AnnaBridge | 182:a56a73fd2a6f | 22 | * NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS LICENSE. | 
| Kojto | 170:19eb464bc2be | 23 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | 
| Kojto | 170:19eb464bc2be | 24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 
| Kojto | 170:19eb464bc2be | 25 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 
| Kojto | 170:19eb464bc2be | 26 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR | 
| Kojto | 170:19eb464bc2be | 27 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 
| Kojto | 170:19eb464bc2be | 28 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 
| Kojto | 170:19eb464bc2be | 29 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | 
| Kojto | 170:19eb464bc2be | 30 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
| Kojto | 170:19eb464bc2be | 31 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 
| Kojto | 170:19eb464bc2be | 32 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
| Kojto | 170:19eb464bc2be | 33 | */ | 
| Kojto | 170:19eb464bc2be | 34 | |
| Kojto | 170:19eb464bc2be | 35 | #include "fsl_spi_dma.h" | 
| Kojto | 170:19eb464bc2be | 36 | |
| Kojto | 170:19eb464bc2be | 37 | /******************************************************************************* | 
| Kojto | 170:19eb464bc2be | 38 | * Definitons | 
| Kojto | 170:19eb464bc2be | 39 | ******************************************************************************/ | 
| Kojto | 170:19eb464bc2be | 40 | /*<! Structure definition for spi_dma_private_handle_t. The structure is private. */ | 
| Kojto | 170:19eb464bc2be | 41 | typedef struct _spi_dma_private_handle | 
| Kojto | 170:19eb464bc2be | 42 | { | 
| Kojto | 170:19eb464bc2be | 43 | SPI_Type *base; | 
| Kojto | 170:19eb464bc2be | 44 | spi_dma_handle_t *handle; | 
| Kojto | 170:19eb464bc2be | 45 | } spi_dma_private_handle_t; | 
| Kojto | 170:19eb464bc2be | 46 | |
| Kojto | 170:19eb464bc2be | 47 | /*! @brief SPI transfer state, which is used for SPI transactiaonl APIs' internal state. */ | 
| Kojto | 170:19eb464bc2be | 48 | enum _spi_dma_states_t | 
| Kojto | 170:19eb464bc2be | 49 | { | 
| Kojto | 170:19eb464bc2be | 50 | kSPI_Idle = 0x0, /*!< SPI is idle state */ | 
| Kojto | 170:19eb464bc2be | 51 | kSPI_Busy /*!< SPI is busy tranferring data. */ | 
| Kojto | 170:19eb464bc2be | 52 | }; | 
| Kojto | 170:19eb464bc2be | 53 | |
| Kojto | 170:19eb464bc2be | 54 | typedef struct _spi_dma_txdummy | 
| Kojto | 170:19eb464bc2be | 55 | { | 
| Kojto | 170:19eb464bc2be | 56 | uint32_t lastWord; | 
| Kojto | 170:19eb464bc2be | 57 | uint32_t word; | 
| Kojto | 170:19eb464bc2be | 58 | } spi_dma_txdummy_t; | 
| Kojto | 170:19eb464bc2be | 59 | |
| Kojto | 170:19eb464bc2be | 60 | /*<! Private handle only used for internally. */ | 
| Kojto | 170:19eb464bc2be | 61 | static spi_dma_private_handle_t s_dmaPrivateHandle[FSL_FEATURE_SOC_SPI_COUNT]; | 
| Kojto | 170:19eb464bc2be | 62 | /******************************************************************************* | 
| Kojto | 170:19eb464bc2be | 63 | * Prototypes | 
| Kojto | 170:19eb464bc2be | 64 | ******************************************************************************/ | 
| Kojto | 170:19eb464bc2be | 65 | |
| Kojto | 170:19eb464bc2be | 66 | /*! | 
| Kojto | 170:19eb464bc2be | 67 | * @brief SPI private function to return SPI configuration | 
| Kojto | 170:19eb464bc2be | 68 | * | 
| Kojto | 170:19eb464bc2be | 69 | * @param base SPI base address. | 
| Kojto | 170:19eb464bc2be | 70 | */ | 
| Kojto | 170:19eb464bc2be | 71 | void *SPI_GetConfig(SPI_Type *base); | 
| Kojto | 170:19eb464bc2be | 72 | |
| Kojto | 170:19eb464bc2be | 73 | /*! | 
| Kojto | 170:19eb464bc2be | 74 | * @brief DMA callback function for SPI send transfer. | 
| Kojto | 170:19eb464bc2be | 75 | * | 
| Kojto | 170:19eb464bc2be | 76 | * @param handle DMA handle pointer. | 
| Kojto | 170:19eb464bc2be | 77 | * @param userData User data for DMA callback function. | 
| Kojto | 170:19eb464bc2be | 78 | */ | 
| Kojto | 170:19eb464bc2be | 79 | static void SPI_TxDMACallback(dma_handle_t *handle, void *userData, bool transferDone, uint32_t intmode); | 
| Kojto | 170:19eb464bc2be | 80 | |
| Kojto | 170:19eb464bc2be | 81 | /*! | 
| Kojto | 170:19eb464bc2be | 82 | * @brief DMA callback function for SPI receive transfer. | 
| Kojto | 170:19eb464bc2be | 83 | * | 
| Kojto | 170:19eb464bc2be | 84 | * @param handle DMA handle pointer. | 
| Kojto | 170:19eb464bc2be | 85 | * @param userData User data for DMA callback function. | 
| Kojto | 170:19eb464bc2be | 86 | */ | 
| Kojto | 170:19eb464bc2be | 87 | static void SPI_RxDMACallback(dma_handle_t *handle, void *userData, bool transferDone, uint32_t intmode); | 
| Kojto | 170:19eb464bc2be | 88 | |
| Kojto | 170:19eb464bc2be | 89 | /******************************************************************************* | 
| Kojto | 170:19eb464bc2be | 90 | * Variables | 
| Kojto | 170:19eb464bc2be | 91 | ******************************************************************************/ | 
| Kojto | 170:19eb464bc2be | 92 | #if defined(__ICCARM__) | 
| Kojto | 170:19eb464bc2be | 93 | #pragma data_alignment = 4 | 
| Kojto | 170:19eb464bc2be | 94 | static spi_dma_txdummy_t s_txDummy[FSL_FEATURE_SOC_SPI_COUNT] = {0}; | 
| Kojto | 170:19eb464bc2be | 95 | #elif defined(__CC_ARM) | 
| Kojto | 170:19eb464bc2be | 96 | __attribute__((aligned(4))) static spi_dma_txdummy_t s_txDummy[FSL_FEATURE_SOC_SPI_COUNT] = {0}; | 
| Kojto | 170:19eb464bc2be | 97 | #elif defined(__GNUC__) | 
| Kojto | 170:19eb464bc2be | 98 | __attribute__((aligned(4))) static spi_dma_txdummy_t s_txDummy[FSL_FEATURE_SOC_SPI_COUNT] = {0}; | 
| Kojto | 170:19eb464bc2be | 99 | #endif | 
| Kojto | 170:19eb464bc2be | 100 | |
| Kojto | 170:19eb464bc2be | 101 | #if defined(__ICCARM__) | 
| Kojto | 170:19eb464bc2be | 102 | #pragma data_alignment = 4 | 
| Kojto | 170:19eb464bc2be | 103 | static uint16_t s_rxDummy; | 
| AnnaBridge | 182:a56a73fd2a6f | 104 | static uint32_t s_txLastWord[FSL_FEATURE_SOC_SPI_COUNT]; | 
| Kojto | 170:19eb464bc2be | 105 | #elif defined(__CC_ARM) | 
| Kojto | 170:19eb464bc2be | 106 | __attribute__((aligned(4))) static uint16_t s_rxDummy; | 
| AnnaBridge | 182:a56a73fd2a6f | 107 | __attribute__((aligned(4))) static uint32_t s_txLastWord[FSL_FEATURE_SOC_SPI_COUNT]; | 
| Kojto | 170:19eb464bc2be | 108 | #elif defined(__GNUC__) | 
| Kojto | 170:19eb464bc2be | 109 | __attribute__((aligned(4))) static uint16_t s_rxDummy; | 
| AnnaBridge | 182:a56a73fd2a6f | 110 | __attribute__((aligned(4))) static uint32_t s_txLastWord[FSL_FEATURE_SOC_SPI_COUNT]; | 
| Kojto | 170:19eb464bc2be | 111 | #endif | 
| Kojto | 170:19eb464bc2be | 112 | |
| Kojto | 170:19eb464bc2be | 113 | #if defined(__ICCARM__) | 
| Kojto | 170:19eb464bc2be | 114 | #pragma data_alignment = 16 | 
| Kojto | 170:19eb464bc2be | 115 | static dma_descriptor_t s_spi_descriptor_table[FSL_FEATURE_SOC_SPI_COUNT] = {0}; | 
| Kojto | 170:19eb464bc2be | 116 | #elif defined(__CC_ARM) | 
| Kojto | 170:19eb464bc2be | 117 | __attribute__((aligned(16))) static dma_descriptor_t s_spi_descriptor_table[FSL_FEATURE_SOC_SPI_COUNT] = {0}; | 
| Kojto | 170:19eb464bc2be | 118 | #elif defined(__GNUC__) | 
| Kojto | 170:19eb464bc2be | 119 | __attribute__((aligned(16))) static dma_descriptor_t s_spi_descriptor_table[FSL_FEATURE_SOC_SPI_COUNT] = {0}; | 
| Kojto | 170:19eb464bc2be | 120 | #endif | 
| Kojto | 170:19eb464bc2be | 121 | |
| AnnaBridge | 182:a56a73fd2a6f | 122 | /*! @brief Global variable for dummy data value setting. */ | 
| AnnaBridge | 182:a56a73fd2a6f | 123 | extern volatile uint8_t s_dummyData[]; | 
| Kojto | 170:19eb464bc2be | 124 | /******************************************************************************* | 
| Kojto | 170:19eb464bc2be | 125 | * Code | 
| Kojto | 170:19eb464bc2be | 126 | ******************************************************************************/ | 
| Kojto | 170:19eb464bc2be | 127 | |
| Kojto | 170:19eb464bc2be | 128 | static void XferToFifoWR(spi_transfer_t *xfer, uint32_t *fifowr) | 
| Kojto | 170:19eb464bc2be | 129 | { | 
| Kojto | 170:19eb464bc2be | 130 | *fifowr |= xfer->configFlags & (uint32_t)kSPI_FrameDelay ? (uint32_t)kSPI_FrameDelay : 0; | 
| Kojto | 170:19eb464bc2be | 131 | *fifowr |= xfer->configFlags & (uint32_t)kSPI_FrameAssert ? (uint32_t)kSPI_FrameAssert : 0; | 
| Kojto | 170:19eb464bc2be | 132 | } | 
| Kojto | 170:19eb464bc2be | 133 | |
| Kojto | 170:19eb464bc2be | 134 | static void SpiConfigToFifoWR(spi_config_t *config, uint32_t *fifowr) | 
| Kojto | 170:19eb464bc2be | 135 | { | 
| Kojto | 170:19eb464bc2be | 136 | *fifowr |= (SPI_DEASSERT_ALL & (~SPI_DEASSERTNUM_SSEL(config->sselNum))); | 
| Kojto | 170:19eb464bc2be | 137 | /* set width of data - range asserted at entry */ | 
| Kojto | 170:19eb464bc2be | 138 | *fifowr |= SPI_FIFOWR_LEN(config->dataWidth); | 
| Kojto | 170:19eb464bc2be | 139 | } | 
| Kojto | 170:19eb464bc2be | 140 | |
| AnnaBridge | 182:a56a73fd2a6f | 141 | static void PrepareTxLastWord(spi_transfer_t *xfer, uint32_t *txLastWord, spi_config_t *config) | 
| Kojto | 170:19eb464bc2be | 142 | { | 
| AnnaBridge | 182:a56a73fd2a6f | 143 | if (config->dataWidth > kSPI_Data8Bits) | 
| Kojto | 170:19eb464bc2be | 144 | { | 
| AnnaBridge | 182:a56a73fd2a6f | 145 | *txLastWord = (((uint32_t)xfer->txData[xfer->dataSize - 1] << 8U) | (xfer->txData[xfer->dataSize - 2])); | 
| Kojto | 170:19eb464bc2be | 146 | } | 
| AnnaBridge | 182:a56a73fd2a6f | 147 | else | 
| Kojto | 170:19eb464bc2be | 148 | { | 
| AnnaBridge | 182:a56a73fd2a6f | 149 | *txLastWord = xfer->txData[xfer->dataSize - 1]; | 
| Kojto | 170:19eb464bc2be | 150 | } | 
| AnnaBridge | 182:a56a73fd2a6f | 151 | XferToFifoWR(xfer, txLastWord); | 
| AnnaBridge | 182:a56a73fd2a6f | 152 | SpiConfigToFifoWR(config, txLastWord); | 
| Kojto | 170:19eb464bc2be | 153 | } | 
| Kojto | 170:19eb464bc2be | 154 | |
| AnnaBridge | 182:a56a73fd2a6f | 155 | static void SPI_SetupDummy(SPI_Type *base, spi_dma_txdummy_t *dummy, spi_transfer_t *xfer, spi_config_t *spi_config_p) | 
| Kojto | 170:19eb464bc2be | 156 | { | 
| AnnaBridge | 182:a56a73fd2a6f | 157 | uint32_t instance = SPI_GetInstance(base); | 
| AnnaBridge | 182:a56a73fd2a6f | 158 | dummy->word = ((uint32_t)s_dummyData[instance] << 8U | s_dummyData[instance]); | 
| AnnaBridge | 182:a56a73fd2a6f | 159 | dummy->lastWord = ((uint32_t)s_dummyData[instance] << 8U | s_dummyData[instance]); | 
| AnnaBridge | 182:a56a73fd2a6f | 160 | XferToFifoWR(xfer, &dummy->word); | 
| AnnaBridge | 182:a56a73fd2a6f | 161 | XferToFifoWR(xfer, &dummy->lastWord); | 
| AnnaBridge | 182:a56a73fd2a6f | 162 | SpiConfigToFifoWR(spi_config_p, &dummy->word); | 
| AnnaBridge | 182:a56a73fd2a6f | 163 | SpiConfigToFifoWR(spi_config_p, &dummy->lastWord); | 
| AnnaBridge | 182:a56a73fd2a6f | 164 | /* Clear the end of transfer bit for continue word transfer. */ | 
| AnnaBridge | 182:a56a73fd2a6f | 165 | dummy->word &= (uint32_t)(~kSPI_FrameAssert); | 
| Kojto | 170:19eb464bc2be | 166 | } | 
| Kojto | 170:19eb464bc2be | 167 | |
| Kojto | 170:19eb464bc2be | 168 | status_t SPI_MasterTransferCreateHandleDMA(SPI_Type *base, | 
| Kojto | 170:19eb464bc2be | 169 | spi_dma_handle_t *handle, | 
| Kojto | 170:19eb464bc2be | 170 | spi_dma_callback_t callback, | 
| Kojto | 170:19eb464bc2be | 171 | void *userData, | 
| Kojto | 170:19eb464bc2be | 172 | dma_handle_t *txHandle, | 
| Kojto | 170:19eb464bc2be | 173 | dma_handle_t *rxHandle) | 
| Kojto | 170:19eb464bc2be | 174 | { | 
| Kojto | 170:19eb464bc2be | 175 | int32_t instance = 0; | 
| Kojto | 170:19eb464bc2be | 176 | |
| Kojto | 170:19eb464bc2be | 177 | /* check 'base' */ | 
| Kojto | 170:19eb464bc2be | 178 | assert(!(NULL == base)); | 
| Kojto | 170:19eb464bc2be | 179 | if (NULL == base) | 
| Kojto | 170:19eb464bc2be | 180 | { | 
| Kojto | 170:19eb464bc2be | 181 | return kStatus_InvalidArgument; | 
| Kojto | 170:19eb464bc2be | 182 | } | 
| Kojto | 170:19eb464bc2be | 183 | /* check 'handle' */ | 
| Kojto | 170:19eb464bc2be | 184 | assert(!(NULL == handle)); | 
| Kojto | 170:19eb464bc2be | 185 | if (NULL == handle) | 
| Kojto | 170:19eb464bc2be | 186 | { | 
| Kojto | 170:19eb464bc2be | 187 | return kStatus_InvalidArgument; | 
| Kojto | 170:19eb464bc2be | 188 | } | 
| Kojto | 170:19eb464bc2be | 189 | |
| Kojto | 170:19eb464bc2be | 190 | instance = SPI_GetInstance(base); | 
| Kojto | 170:19eb464bc2be | 191 | |
| Kojto | 170:19eb464bc2be | 192 | memset(handle, 0, sizeof(*handle)); | 
| Kojto | 170:19eb464bc2be | 193 | /* Set spi base to handle */ | 
| Kojto | 170:19eb464bc2be | 194 | handle->txHandle = txHandle; | 
| Kojto | 170:19eb464bc2be | 195 | handle->rxHandle = rxHandle; | 
| Kojto | 170:19eb464bc2be | 196 | handle->callback = callback; | 
| Kojto | 170:19eb464bc2be | 197 | handle->userData = userData; | 
| Kojto | 170:19eb464bc2be | 198 | |
| Kojto | 170:19eb464bc2be | 199 | /* Set SPI state to idle */ | 
| Kojto | 170:19eb464bc2be | 200 | handle->state = kSPI_Idle; | 
| Kojto | 170:19eb464bc2be | 201 | |
| Kojto | 170:19eb464bc2be | 202 | /* Set handle to global state */ | 
| Kojto | 170:19eb464bc2be | 203 | s_dmaPrivateHandle[instance].base = base; | 
| Kojto | 170:19eb464bc2be | 204 | s_dmaPrivateHandle[instance].handle = handle; | 
| Kojto | 170:19eb464bc2be | 205 | |
| Kojto | 170:19eb464bc2be | 206 | /* Install callback for Tx dma channel */ | 
| Kojto | 170:19eb464bc2be | 207 | DMA_SetCallback(handle->txHandle, SPI_TxDMACallback, &s_dmaPrivateHandle[instance]); | 
| Kojto | 170:19eb464bc2be | 208 | DMA_SetCallback(handle->rxHandle, SPI_RxDMACallback, &s_dmaPrivateHandle[instance]); | 
| Kojto | 170:19eb464bc2be | 209 | |
| Kojto | 170:19eb464bc2be | 210 | return kStatus_Success; | 
| Kojto | 170:19eb464bc2be | 211 | } | 
| Kojto | 170:19eb464bc2be | 212 | |
| Kojto | 170:19eb464bc2be | 213 | status_t SPI_MasterTransferDMA(SPI_Type *base, spi_dma_handle_t *handle, spi_transfer_t *xfer) | 
| Kojto | 170:19eb464bc2be | 214 | { | 
| Kojto | 170:19eb464bc2be | 215 | int32_t instance; | 
| Kojto | 170:19eb464bc2be | 216 | status_t result = kStatus_Success; | 
| Kojto | 170:19eb464bc2be | 217 | spi_config_t *spi_config_p; | 
| Kojto | 170:19eb464bc2be | 218 | |
| Kojto | 170:19eb464bc2be | 219 | assert(!((NULL == handle) || (NULL == xfer))); | 
| Kojto | 170:19eb464bc2be | 220 | if ((NULL == handle) || (NULL == xfer)) | 
| Kojto | 170:19eb464bc2be | 221 | { | 
| Kojto | 170:19eb464bc2be | 222 | return kStatus_InvalidArgument; | 
| Kojto | 170:19eb464bc2be | 223 | } | 
| AnnaBridge | 182:a56a73fd2a6f | 224 | |
| AnnaBridge | 182:a56a73fd2a6f | 225 | /* Byte size is zero. */ | 
| AnnaBridge | 182:a56a73fd2a6f | 226 | assert(!(xfer->dataSize == 0)); | 
| AnnaBridge | 182:a56a73fd2a6f | 227 | if (xfer->dataSize == 0) | 
| Kojto | 170:19eb464bc2be | 228 | { | 
| Kojto | 170:19eb464bc2be | 229 | return kStatus_InvalidArgument; | 
| Kojto | 170:19eb464bc2be | 230 | } | 
| Kojto | 170:19eb464bc2be | 231 | /* cannot get instance from base address */ | 
| Kojto | 170:19eb464bc2be | 232 | instance = SPI_GetInstance(base); | 
| Kojto | 170:19eb464bc2be | 233 | assert(!(instance < 0)); | 
| Kojto | 170:19eb464bc2be | 234 | if (instance < 0) | 
| Kojto | 170:19eb464bc2be | 235 | { | 
| Kojto | 170:19eb464bc2be | 236 | return kStatus_InvalidArgument; | 
| Kojto | 170:19eb464bc2be | 237 | } | 
| Kojto | 170:19eb464bc2be | 238 | |
| Kojto | 170:19eb464bc2be | 239 | /* Check if the device is busy */ | 
| Kojto | 170:19eb464bc2be | 240 | if (handle->state == kSPI_Busy) | 
| Kojto | 170:19eb464bc2be | 241 | { | 
| Kojto | 170:19eb464bc2be | 242 | return kStatus_SPI_Busy; | 
| Kojto | 170:19eb464bc2be | 243 | } | 
| Kojto | 170:19eb464bc2be | 244 | else | 
| Kojto | 170:19eb464bc2be | 245 | { | 
| Kojto | 170:19eb464bc2be | 246 | uint32_t tmp; | 
| Kojto | 170:19eb464bc2be | 247 | dma_transfer_config_t xferConfig = {0}; | 
| Kojto | 170:19eb464bc2be | 248 | spi_config_p = (spi_config_t *)SPI_GetConfig(base); | 
| Kojto | 170:19eb464bc2be | 249 | |
| Kojto | 170:19eb464bc2be | 250 | handle->state = kStatus_SPI_Busy; | 
| Kojto | 170:19eb464bc2be | 251 | handle->transferSize = xfer->dataSize; | 
| Kojto | 170:19eb464bc2be | 252 | |
| Kojto | 170:19eb464bc2be | 253 | /* receive */ | 
| Kojto | 170:19eb464bc2be | 254 | SPI_EnableRxDMA(base, true); | 
| Kojto | 170:19eb464bc2be | 255 | if (xfer->rxData) | 
| Kojto | 170:19eb464bc2be | 256 | { | 
| AnnaBridge | 182:a56a73fd2a6f | 257 | DMA_PrepareTransfer(&xferConfig, (void *)&base->FIFORD, xfer->rxData, | 
| AnnaBridge | 182:a56a73fd2a6f | 258 | ((spi_config_p->dataWidth > kSPI_Data8Bits) ? (sizeof(uint16_t)) : (sizeof(uint8_t))), | 
| AnnaBridge | 182:a56a73fd2a6f | 259 | xfer->dataSize, kDMA_PeripheralToMemory, NULL); | 
| Kojto | 170:19eb464bc2be | 260 | } | 
| Kojto | 170:19eb464bc2be | 261 | else | 
| Kojto | 170:19eb464bc2be | 262 | { | 
| AnnaBridge | 182:a56a73fd2a6f | 263 | DMA_PrepareTransfer(&xferConfig, (void *)&base->FIFORD, &s_rxDummy, | 
| AnnaBridge | 182:a56a73fd2a6f | 264 | ((spi_config_p->dataWidth > kSPI_Data8Bits) ? (sizeof(uint16_t)) : (sizeof(uint8_t))), | 
| AnnaBridge | 182:a56a73fd2a6f | 265 | xfer->dataSize, kDMA_StaticToStatic, NULL); | 
| Kojto | 170:19eb464bc2be | 266 | } | 
| Kojto | 170:19eb464bc2be | 267 | DMA_SubmitTransfer(handle->rxHandle, &xferConfig); | 
| Kojto | 170:19eb464bc2be | 268 | handle->rxInProgress = true; | 
| Kojto | 170:19eb464bc2be | 269 | DMA_StartTransfer(handle->rxHandle); | 
| Kojto | 170:19eb464bc2be | 270 | |
| Kojto | 170:19eb464bc2be | 271 | /* transmit */ | 
| Kojto | 170:19eb464bc2be | 272 | SPI_EnableTxDMA(base, true); | 
| AnnaBridge | 182:a56a73fd2a6f | 273 | |
| AnnaBridge | 182:a56a73fd2a6f | 274 | if (xfer->configFlags & kSPI_FrameAssert) | 
| AnnaBridge | 182:a56a73fd2a6f | 275 | { | 
| AnnaBridge | 182:a56a73fd2a6f | 276 | PrepareTxLastWord(xfer, &s_txLastWord[instance], spi_config_p); | 
| AnnaBridge | 182:a56a73fd2a6f | 277 | } | 
| AnnaBridge | 182:a56a73fd2a6f | 278 | |
| Kojto | 170:19eb464bc2be | 279 | if (xfer->txData) | 
| Kojto | 170:19eb464bc2be | 280 | { | 
| AnnaBridge | 182:a56a73fd2a6f | 281 | /* If end of tranfer function is enabled and data transfer frame is bigger then 1, use dma | 
| AnnaBridge | 182:a56a73fd2a6f | 282 | * descriptor to send the last data. | 
| AnnaBridge | 182:a56a73fd2a6f | 283 | */ | 
| AnnaBridge | 182:a56a73fd2a6f | 284 | if ((xfer->configFlags & kSPI_FrameAssert) && | 
| AnnaBridge | 182:a56a73fd2a6f | 285 | ((spi_config_p->dataWidth > kSPI_Data8Bits) ? (xfer->dataSize > 2) : (xfer->dataSize > 1))) | 
| Kojto | 170:19eb464bc2be | 286 | { | 
| AnnaBridge | 182:a56a73fd2a6f | 287 | dma_xfercfg_t tmp_xfercfg = {0}; | 
| Kojto | 170:19eb464bc2be | 288 | tmp_xfercfg.valid = true; | 
| Kojto | 170:19eb464bc2be | 289 | tmp_xfercfg.swtrig = true; | 
| Kojto | 170:19eb464bc2be | 290 | tmp_xfercfg.intA = true; | 
| Kojto | 170:19eb464bc2be | 291 | tmp_xfercfg.byteWidth = sizeof(uint32_t); | 
| Kojto | 170:19eb464bc2be | 292 | tmp_xfercfg.srcInc = 0; | 
| Kojto | 170:19eb464bc2be | 293 | tmp_xfercfg.dstInc = 0; | 
| Kojto | 170:19eb464bc2be | 294 | tmp_xfercfg.transferCount = 1; | 
| AnnaBridge | 182:a56a73fd2a6f | 295 | /* Create chained descriptor to transmit last word */ | 
| AnnaBridge | 182:a56a73fd2a6f | 296 | DMA_CreateDescriptor(&s_spi_descriptor_table[instance], &tmp_xfercfg, &s_txLastWord[instance], | 
| AnnaBridge | 182:a56a73fd2a6f | 297 | (void *)&base->FIFOWR, NULL); | 
| AnnaBridge | 182:a56a73fd2a6f | 298 | |
| AnnaBridge | 182:a56a73fd2a6f | 299 | DMA_PrepareTransfer( | 
| AnnaBridge | 182:a56a73fd2a6f | 300 | &xferConfig, xfer->txData, (void *)&base->FIFOWR, | 
| AnnaBridge | 182:a56a73fd2a6f | 301 | ((spi_config_p->dataWidth > kSPI_Data8Bits) ? (sizeof(uint16_t)) : (sizeof(uint8_t))), | 
| AnnaBridge | 182:a56a73fd2a6f | 302 | ((spi_config_p->dataWidth > kSPI_Data8Bits) ? (xfer->dataSize - 2) : (xfer->dataSize - 1)), | 
| AnnaBridge | 182:a56a73fd2a6f | 303 | kDMA_MemoryToPeripheral, &s_spi_descriptor_table[instance]); | 
| AnnaBridge | 182:a56a73fd2a6f | 304 | /* Disable interrupts for first descriptor to avoid calling callback twice. */ | 
| Kojto | 170:19eb464bc2be | 305 | xferConfig.xfercfg.intA = false; | 
| Kojto | 170:19eb464bc2be | 306 | xferConfig.xfercfg.intB = false; | 
| Kojto | 170:19eb464bc2be | 307 | result = DMA_SubmitTransfer(handle->txHandle, &xferConfig); | 
| Kojto | 170:19eb464bc2be | 308 | if (result != kStatus_Success) | 
| Kojto | 170:19eb464bc2be | 309 | { | 
| Kojto | 170:19eb464bc2be | 310 | return result; | 
| Kojto | 170:19eb464bc2be | 311 | } | 
| Kojto | 170:19eb464bc2be | 312 | } | 
| Kojto | 170:19eb464bc2be | 313 | else | 
| Kojto | 170:19eb464bc2be | 314 | { | 
| AnnaBridge | 182:a56a73fd2a6f | 315 | DMA_PrepareTransfer( | 
| AnnaBridge | 182:a56a73fd2a6f | 316 | &xferConfig, xfer->txData, (void *)&base->FIFOWR, | 
| AnnaBridge | 182:a56a73fd2a6f | 317 | ((spi_config_p->dataWidth > kSPI_Data8Bits) ? (sizeof(uint16_t)) : (sizeof(uint8_t))), | 
| AnnaBridge | 182:a56a73fd2a6f | 318 | xfer->dataSize, kDMA_MemoryToPeripheral, NULL); | 
| AnnaBridge | 182:a56a73fd2a6f | 319 | DMA_SubmitTransfer(handle->txHandle, &xferConfig); | 
| AnnaBridge | 182:a56a73fd2a6f | 320 | } | 
| AnnaBridge | 182:a56a73fd2a6f | 321 | } | 
| AnnaBridge | 182:a56a73fd2a6f | 322 | else | 
| AnnaBridge | 182:a56a73fd2a6f | 323 | { | 
| AnnaBridge | 182:a56a73fd2a6f | 324 | /* Setup tx dummy data. */ | 
| AnnaBridge | 182:a56a73fd2a6f | 325 | SPI_SetupDummy(base, &s_txDummy[instance], xfer, spi_config_p); | 
| AnnaBridge | 182:a56a73fd2a6f | 326 | if ((xfer->configFlags & kSPI_FrameAssert) && | 
| AnnaBridge | 182:a56a73fd2a6f | 327 | ((spi_config_p->dataWidth > kSPI_Data8Bits) ? (xfer->dataSize > 2) : (xfer->dataSize > 1))) | 
| AnnaBridge | 182:a56a73fd2a6f | 328 | { | 
| AnnaBridge | 182:a56a73fd2a6f | 329 | dma_xfercfg_t tmp_xfercfg = {0}; | 
| AnnaBridge | 182:a56a73fd2a6f | 330 | tmp_xfercfg.valid = true; | 
| AnnaBridge | 182:a56a73fd2a6f | 331 | tmp_xfercfg.swtrig = true; | 
| AnnaBridge | 182:a56a73fd2a6f | 332 | tmp_xfercfg.intA = true; | 
| AnnaBridge | 182:a56a73fd2a6f | 333 | tmp_xfercfg.byteWidth = sizeof(uint32_t); | 
| AnnaBridge | 182:a56a73fd2a6f | 334 | tmp_xfercfg.srcInc = 0; | 
| AnnaBridge | 182:a56a73fd2a6f | 335 | tmp_xfercfg.dstInc = 0; | 
| AnnaBridge | 182:a56a73fd2a6f | 336 | tmp_xfercfg.transferCount = 1; | 
| AnnaBridge | 182:a56a73fd2a6f | 337 | /* Create chained descriptor to transmit last word */ | 
| AnnaBridge | 182:a56a73fd2a6f | 338 | DMA_CreateDescriptor(&s_spi_descriptor_table[instance], &tmp_xfercfg, &s_txDummy[instance].lastWord, | 
| AnnaBridge | 182:a56a73fd2a6f | 339 | (uint32_t *)&base->FIFOWR, NULL); | 
| AnnaBridge | 182:a56a73fd2a6f | 340 | /* Use common API to setup first descriptor */ | 
| AnnaBridge | 182:a56a73fd2a6f | 341 | DMA_PrepareTransfer( | 
| AnnaBridge | 182:a56a73fd2a6f | 342 | &xferConfig, &s_txDummy[instance].word, (void *)&base->FIFOWR, | 
| AnnaBridge | 182:a56a73fd2a6f | 343 | ((spi_config_p->dataWidth > kSPI_Data8Bits) ? (sizeof(uint16_t)) : (sizeof(uint8_t))), | 
| AnnaBridge | 182:a56a73fd2a6f | 344 | ((spi_config_p->dataWidth > kSPI_Data8Bits) ? (xfer->dataSize - 2) : (xfer->dataSize - 1)), | 
| AnnaBridge | 182:a56a73fd2a6f | 345 | kDMA_StaticToStatic, &s_spi_descriptor_table[instance]); | 
| AnnaBridge | 182:a56a73fd2a6f | 346 | /* Disable interrupts for first descriptor to avoid calling callback twice */ | 
| AnnaBridge | 182:a56a73fd2a6f | 347 | xferConfig.xfercfg.intA = false; | 
| AnnaBridge | 182:a56a73fd2a6f | 348 | xferConfig.xfercfg.intB = false; | 
| AnnaBridge | 182:a56a73fd2a6f | 349 | result = DMA_SubmitTransfer(handle->txHandle, &xferConfig); | 
| AnnaBridge | 182:a56a73fd2a6f | 350 | if (result != kStatus_Success) | 
| AnnaBridge | 182:a56a73fd2a6f | 351 | { | 
| AnnaBridge | 182:a56a73fd2a6f | 352 | return result; | 
| AnnaBridge | 182:a56a73fd2a6f | 353 | } | 
| AnnaBridge | 182:a56a73fd2a6f | 354 | } | 
| AnnaBridge | 182:a56a73fd2a6f | 355 | else | 
| AnnaBridge | 182:a56a73fd2a6f | 356 | { | 
| AnnaBridge | 182:a56a73fd2a6f | 357 | DMA_PrepareTransfer( | 
| AnnaBridge | 182:a56a73fd2a6f | 358 | &xferConfig, &s_txDummy[instance].word, (void *)&base->FIFOWR, | 
| AnnaBridge | 182:a56a73fd2a6f | 359 | ((spi_config_p->dataWidth > kSPI_Data8Bits) ? (sizeof(uint16_t)) : (sizeof(uint8_t))), | 
| AnnaBridge | 182:a56a73fd2a6f | 360 | xfer->dataSize, kDMA_StaticToStatic, NULL); | 
| Kojto | 170:19eb464bc2be | 361 | result = DMA_SubmitTransfer(handle->txHandle, &xferConfig); | 
| Kojto | 170:19eb464bc2be | 362 | if (result != kStatus_Success) | 
| Kojto | 170:19eb464bc2be | 363 | { | 
| Kojto | 170:19eb464bc2be | 364 | return result; | 
| Kojto | 170:19eb464bc2be | 365 | } | 
| Kojto | 170:19eb464bc2be | 366 | } | 
| Kojto | 170:19eb464bc2be | 367 | } | 
| AnnaBridge | 182:a56a73fd2a6f | 368 | |
| Kojto | 170:19eb464bc2be | 369 | handle->txInProgress = true; | 
| AnnaBridge | 182:a56a73fd2a6f | 370 | tmp = 0; | 
| AnnaBridge | 182:a56a73fd2a6f | 371 | XferToFifoWR(xfer, &tmp); | 
| AnnaBridge | 182:a56a73fd2a6f | 372 | SpiConfigToFifoWR(spi_config_p, &tmp); | 
| AnnaBridge | 182:a56a73fd2a6f | 373 | |
| AnnaBridge | 182:a56a73fd2a6f | 374 | /* Setup the control info. | 
| AnnaBridge | 182:a56a73fd2a6f | 375 | * Halfword writes to just the control bits (offset 0xE22) doesn't push anything into the FIFO. | 
| AnnaBridge | 182:a56a73fd2a6f | 376 | * And the data access type of control bits must be uint16_t, byte writes or halfword writes to FIFOWR | 
| AnnaBridge | 182:a56a73fd2a6f | 377 | * will push the data and the current control bits into the FIFO. | 
| AnnaBridge | 182:a56a73fd2a6f | 378 | */ | 
| AnnaBridge | 182:a56a73fd2a6f | 379 | if ((xfer->configFlags & kSPI_FrameAssert) && | 
| AnnaBridge | 182:a56a73fd2a6f | 380 | ((spi_config_p->dataWidth > kSPI_Data8Bits) ? (xfer->dataSize == 2U) : (xfer->dataSize == 1U))) | 
| AnnaBridge | 182:a56a73fd2a6f | 381 | { | 
| AnnaBridge | 182:a56a73fd2a6f | 382 | *(((uint16_t *)&(base->FIFOWR)) + 1) = (uint16_t)(tmp >> 16U); | 
| AnnaBridge | 182:a56a73fd2a6f | 383 | } | 
| AnnaBridge | 182:a56a73fd2a6f | 384 | else | 
| AnnaBridge | 182:a56a73fd2a6f | 385 | { | 
| AnnaBridge | 182:a56a73fd2a6f | 386 | /* Clear the SPI_FIFOWR_EOT_MASK bit when data is not the last. */ | 
| AnnaBridge | 182:a56a73fd2a6f | 387 | tmp &= (uint32_t)(~kSPI_FrameAssert); | 
| AnnaBridge | 182:a56a73fd2a6f | 388 | *(((uint16_t *)&(base->FIFOWR)) + 1) = (uint16_t)(tmp >> 16U); | 
| AnnaBridge | 182:a56a73fd2a6f | 389 | } | 
| AnnaBridge | 182:a56a73fd2a6f | 390 | |
| Kojto | 170:19eb464bc2be | 391 | DMA_StartTransfer(handle->txHandle); | 
| Kojto | 170:19eb464bc2be | 392 | } | 
| Kojto | 170:19eb464bc2be | 393 | |
| Kojto | 170:19eb464bc2be | 394 | return result; | 
| Kojto | 170:19eb464bc2be | 395 | } | 
| Kojto | 170:19eb464bc2be | 396 | |
| AnnaBridge | 182:a56a73fd2a6f | 397 | status_t SPI_MasterHalfDuplexTransferDMA(SPI_Type *base, spi_dma_handle_t *handle, spi_half_duplex_transfer_t *xfer) | 
| AnnaBridge | 182:a56a73fd2a6f | 398 | { | 
| AnnaBridge | 182:a56a73fd2a6f | 399 | assert(xfer); | 
| AnnaBridge | 182:a56a73fd2a6f | 400 | assert(handle); | 
| AnnaBridge | 182:a56a73fd2a6f | 401 | spi_transfer_t tempXfer = {0}; | 
| AnnaBridge | 182:a56a73fd2a6f | 402 | status_t status; | 
| AnnaBridge | 182:a56a73fd2a6f | 403 | |
| AnnaBridge | 182:a56a73fd2a6f | 404 | if (xfer->isTransmitFirst) | 
| AnnaBridge | 182:a56a73fd2a6f | 405 | { | 
| AnnaBridge | 182:a56a73fd2a6f | 406 | tempXfer.txData = xfer->txData; | 
| AnnaBridge | 182:a56a73fd2a6f | 407 | tempXfer.rxData = NULL; | 
| AnnaBridge | 182:a56a73fd2a6f | 408 | tempXfer.dataSize = xfer->txDataSize; | 
| AnnaBridge | 182:a56a73fd2a6f | 409 | } | 
| AnnaBridge | 182:a56a73fd2a6f | 410 | else | 
| AnnaBridge | 182:a56a73fd2a6f | 411 | { | 
| AnnaBridge | 182:a56a73fd2a6f | 412 | tempXfer.txData = NULL; | 
| AnnaBridge | 182:a56a73fd2a6f | 413 | tempXfer.rxData = xfer->rxData; | 
| AnnaBridge | 182:a56a73fd2a6f | 414 | tempXfer.dataSize = xfer->rxDataSize; | 
| AnnaBridge | 182:a56a73fd2a6f | 415 | } | 
| AnnaBridge | 182:a56a73fd2a6f | 416 | /* If the pcs pin keep assert between transmit and receive. */ | 
| AnnaBridge | 182:a56a73fd2a6f | 417 | if (xfer->isPcsAssertInTransfer) | 
| AnnaBridge | 182:a56a73fd2a6f | 418 | { | 
| AnnaBridge | 182:a56a73fd2a6f | 419 | tempXfer.configFlags = (xfer->configFlags) & (uint32_t)(~kSPI_FrameAssert); | 
| AnnaBridge | 182:a56a73fd2a6f | 420 | } | 
| AnnaBridge | 182:a56a73fd2a6f | 421 | else | 
| AnnaBridge | 182:a56a73fd2a6f | 422 | { | 
| AnnaBridge | 182:a56a73fd2a6f | 423 | tempXfer.configFlags = (xfer->configFlags) | kSPI_FrameAssert; | 
| AnnaBridge | 182:a56a73fd2a6f | 424 | } | 
| AnnaBridge | 182:a56a73fd2a6f | 425 | |
| AnnaBridge | 182:a56a73fd2a6f | 426 | status = SPI_MasterTransferBlocking(base, &tempXfer); | 
| AnnaBridge | 182:a56a73fd2a6f | 427 | if (status != kStatus_Success) | 
| AnnaBridge | 182:a56a73fd2a6f | 428 | { | 
| AnnaBridge | 182:a56a73fd2a6f | 429 | return status; | 
| AnnaBridge | 182:a56a73fd2a6f | 430 | } | 
| AnnaBridge | 182:a56a73fd2a6f | 431 | |
| AnnaBridge | 182:a56a73fd2a6f | 432 | if (xfer->isTransmitFirst) | 
| AnnaBridge | 182:a56a73fd2a6f | 433 | { | 
| AnnaBridge | 182:a56a73fd2a6f | 434 | tempXfer.txData = NULL; | 
| AnnaBridge | 182:a56a73fd2a6f | 435 | tempXfer.rxData = xfer->rxData; | 
| AnnaBridge | 182:a56a73fd2a6f | 436 | tempXfer.dataSize = xfer->rxDataSize; | 
| AnnaBridge | 182:a56a73fd2a6f | 437 | } | 
| AnnaBridge | 182:a56a73fd2a6f | 438 | else | 
| AnnaBridge | 182:a56a73fd2a6f | 439 | { | 
| AnnaBridge | 182:a56a73fd2a6f | 440 | tempXfer.txData = xfer->txData; | 
| AnnaBridge | 182:a56a73fd2a6f | 441 | tempXfer.rxData = NULL; | 
| AnnaBridge | 182:a56a73fd2a6f | 442 | tempXfer.dataSize = xfer->txDataSize; | 
| AnnaBridge | 182:a56a73fd2a6f | 443 | } | 
| AnnaBridge | 182:a56a73fd2a6f | 444 | tempXfer.configFlags = xfer->configFlags; | 
| AnnaBridge | 182:a56a73fd2a6f | 445 | |
| AnnaBridge | 182:a56a73fd2a6f | 446 | status = SPI_MasterTransferDMA(base, handle, &tempXfer); | 
| AnnaBridge | 182:a56a73fd2a6f | 447 | |
| AnnaBridge | 182:a56a73fd2a6f | 448 | return status; | 
| AnnaBridge | 182:a56a73fd2a6f | 449 | } | 
| AnnaBridge | 182:a56a73fd2a6f | 450 | |
| Kojto | 170:19eb464bc2be | 451 | static void SPI_RxDMACallback(dma_handle_t *handle, void *userData, bool transferDone, uint32_t intmode) | 
| Kojto | 170:19eb464bc2be | 452 | { | 
| Kojto | 170:19eb464bc2be | 453 | spi_dma_private_handle_t *privHandle = (spi_dma_private_handle_t *)userData; | 
| Kojto | 170:19eb464bc2be | 454 | spi_dma_handle_t *spiHandle = privHandle->handle; | 
| Kojto | 170:19eb464bc2be | 455 | SPI_Type *base = privHandle->base; | 
| Kojto | 170:19eb464bc2be | 456 | |
| Kojto | 170:19eb464bc2be | 457 | /* change the state */ | 
| Kojto | 170:19eb464bc2be | 458 | spiHandle->rxInProgress = false; | 
| Kojto | 170:19eb464bc2be | 459 | |
| Kojto | 170:19eb464bc2be | 460 | /* All finished, call the callback */ | 
| Kojto | 170:19eb464bc2be | 461 | if ((spiHandle->txInProgress == false) && (spiHandle->rxInProgress == false)) | 
| Kojto | 170:19eb464bc2be | 462 | { | 
| Kojto | 170:19eb464bc2be | 463 | spiHandle->state = kSPI_Idle; | 
| Kojto | 170:19eb464bc2be | 464 | if (spiHandle->callback) | 
| Kojto | 170:19eb464bc2be | 465 | { | 
| Kojto | 170:19eb464bc2be | 466 | (spiHandle->callback)(base, spiHandle, kStatus_Success, spiHandle->userData); | 
| Kojto | 170:19eb464bc2be | 467 | } | 
| Kojto | 170:19eb464bc2be | 468 | } | 
| Kojto | 170:19eb464bc2be | 469 | } | 
| Kojto | 170:19eb464bc2be | 470 | |
| Kojto | 170:19eb464bc2be | 471 | static void SPI_TxDMACallback(dma_handle_t *handle, void *userData, bool transferDone, uint32_t intmode) | 
| Kojto | 170:19eb464bc2be | 472 | { | 
| Kojto | 170:19eb464bc2be | 473 | spi_dma_private_handle_t *privHandle = (spi_dma_private_handle_t *)userData; | 
| Kojto | 170:19eb464bc2be | 474 | spi_dma_handle_t *spiHandle = privHandle->handle; | 
| Kojto | 170:19eb464bc2be | 475 | SPI_Type *base = privHandle->base; | 
| Kojto | 170:19eb464bc2be | 476 | |
| Kojto | 170:19eb464bc2be | 477 | /* change the state */ | 
| Kojto | 170:19eb464bc2be | 478 | spiHandle->txInProgress = false; | 
| Kojto | 170:19eb464bc2be | 479 | |
| Kojto | 170:19eb464bc2be | 480 | /* All finished, call the callback */ | 
| Kojto | 170:19eb464bc2be | 481 | if ((spiHandle->txInProgress == false) && (spiHandle->rxInProgress == false)) | 
| Kojto | 170:19eb464bc2be | 482 | { | 
| Kojto | 170:19eb464bc2be | 483 | spiHandle->state = kSPI_Idle; | 
| Kojto | 170:19eb464bc2be | 484 | if (spiHandle->callback) | 
| Kojto | 170:19eb464bc2be | 485 | { | 
| Kojto | 170:19eb464bc2be | 486 | (spiHandle->callback)(base, spiHandle, kStatus_Success, spiHandle->userData); | 
| Kojto | 170:19eb464bc2be | 487 | } | 
| Kojto | 170:19eb464bc2be | 488 | } | 
| Kojto | 170:19eb464bc2be | 489 | } | 
| Kojto | 170:19eb464bc2be | 490 | |
| Kojto | 170:19eb464bc2be | 491 | void SPI_MasterTransferAbortDMA(SPI_Type *base, spi_dma_handle_t *handle) | 
| Kojto | 170:19eb464bc2be | 492 | { | 
| Kojto | 170:19eb464bc2be | 493 | assert(NULL != handle); | 
| Kojto | 170:19eb464bc2be | 494 | |
| Kojto | 170:19eb464bc2be | 495 | /* Stop tx transfer first */ | 
| Kojto | 170:19eb464bc2be | 496 | DMA_AbortTransfer(handle->txHandle); | 
| Kojto | 170:19eb464bc2be | 497 | /* Then rx transfer */ | 
| Kojto | 170:19eb464bc2be | 498 | DMA_AbortTransfer(handle->rxHandle); | 
| Kojto | 170:19eb464bc2be | 499 | |
| Kojto | 170:19eb464bc2be | 500 | /* Set the handle state */ | 
| Kojto | 170:19eb464bc2be | 501 | handle->txInProgress = false; | 
| Kojto | 170:19eb464bc2be | 502 | handle->rxInProgress = false; | 
| Kojto | 170:19eb464bc2be | 503 | handle->state = kSPI_Idle; | 
| Kojto | 170:19eb464bc2be | 504 | } | 
| Kojto | 170:19eb464bc2be | 505 | |
| Kojto | 170:19eb464bc2be | 506 | status_t SPI_MasterTransferGetCountDMA(SPI_Type *base, spi_dma_handle_t *handle, size_t *count) | 
| Kojto | 170:19eb464bc2be | 507 | { | 
| Kojto | 170:19eb464bc2be | 508 | assert(handle); | 
| Kojto | 170:19eb464bc2be | 509 | |
| Kojto | 170:19eb464bc2be | 510 | if (!count) | 
| Kojto | 170:19eb464bc2be | 511 | { | 
| Kojto | 170:19eb464bc2be | 512 | return kStatus_InvalidArgument; | 
| Kojto | 170:19eb464bc2be | 513 | } | 
| Kojto | 170:19eb464bc2be | 514 | |
| Kojto | 170:19eb464bc2be | 515 | /* Catch when there is not an active transfer. */ | 
| Kojto | 170:19eb464bc2be | 516 | if (handle->state != kSPI_Busy) | 
| Kojto | 170:19eb464bc2be | 517 | { | 
| Kojto | 170:19eb464bc2be | 518 | *count = 0; | 
| Kojto | 170:19eb464bc2be | 519 | return kStatus_NoTransferInProgress; | 
| Kojto | 170:19eb464bc2be | 520 | } | 
| Kojto | 170:19eb464bc2be | 521 | |
| Kojto | 170:19eb464bc2be | 522 | size_t bytes; | 
| Kojto | 170:19eb464bc2be | 523 | |
| Kojto | 170:19eb464bc2be | 524 | bytes = DMA_GetRemainingBytes(handle->rxHandle->base, handle->rxHandle->channel); | 
| Kojto | 170:19eb464bc2be | 525 | |
| Kojto | 170:19eb464bc2be | 526 | *count = handle->transferSize - bytes; | 
| Kojto | 170:19eb464bc2be | 527 | |
| Kojto | 170:19eb464bc2be | 528 | return kStatus_Success; | 
| Kojto | 170:19eb464bc2be | 529 | } | 


