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.h"
<> 144:ef7eb2e8f9f7 32
<> 144:ef7eb2e8f9f7 33 /*******************************************************************************
<> 144:ef7eb2e8f9f7 34 * Definitions
<> 144:ef7eb2e8f9f7 35 ******************************************************************************/
<> 144:ef7eb2e8f9f7 36 /*! @brief Typedef for master interrupt handler. */
<> 144:ef7eb2e8f9f7 37 typedef void (*dspi_master_isr_t)(SPI_Type *base, dspi_master_handle_t *handle);
<> 144:ef7eb2e8f9f7 38
<> 144:ef7eb2e8f9f7 39 /*! @brief Typedef for slave interrupt handler. */
<> 144:ef7eb2e8f9f7 40 typedef void (*dspi_slave_isr_t)(SPI_Type *base, dspi_slave_handle_t *handle);
<> 144:ef7eb2e8f9f7 41
<> 144:ef7eb2e8f9f7 42 /*******************************************************************************
<> 144:ef7eb2e8f9f7 43 * Prototypes
<> 144:ef7eb2e8f9f7 44 ******************************************************************************/
<> 144:ef7eb2e8f9f7 45 /*!
<> 144:ef7eb2e8f9f7 46 * @brief Get instance number for DSPI module.
<> 144:ef7eb2e8f9f7 47 *
<> 144:ef7eb2e8f9f7 48 * @param base DSPI peripheral base address.
<> 144:ef7eb2e8f9f7 49 */
<> 144:ef7eb2e8f9f7 50 uint32_t DSPI_GetInstance(SPI_Type *base);
<> 144:ef7eb2e8f9f7 51
<> 144:ef7eb2e8f9f7 52 /*!
<> 144:ef7eb2e8f9f7 53 * @brief Configures the DSPI peripheral chip select polarity.
<> 144:ef7eb2e8f9f7 54 *
<> 144:ef7eb2e8f9f7 55 * This function takes in the desired peripheral chip select (Pcs) and it's corresponding desired polarity and
<> 144:ef7eb2e8f9f7 56 * configures the Pcs signal to operate with the desired characteristic.
<> 144:ef7eb2e8f9f7 57 *
<> 144:ef7eb2e8f9f7 58 * @param base DSPI peripheral address.
<> 144:ef7eb2e8f9f7 59 * @param pcs The particular peripheral chip select (parameter value is of type dspi_which_pcs_t) for which we wish to
<> 144:ef7eb2e8f9f7 60 * apply the active high or active low characteristic.
<> 144:ef7eb2e8f9f7 61 * @param activeLowOrHigh The setting for either "active high, inactive low (0)" or "active low, inactive high(1)" of
<> 144:ef7eb2e8f9f7 62 * type dspi_pcs_polarity_config_t.
<> 144:ef7eb2e8f9f7 63 */
<> 144:ef7eb2e8f9f7 64 static void DSPI_SetOnePcsPolarity(SPI_Type *base, dspi_which_pcs_t pcs, dspi_pcs_polarity_config_t activeLowOrHigh);
<> 144:ef7eb2e8f9f7 65
<> 144:ef7eb2e8f9f7 66 /*!
<> 144:ef7eb2e8f9f7 67 * @brief Master fill up the TX FIFO with data.
<> 144:ef7eb2e8f9f7 68 * This is not a public API as it is called from other driver functions.
<> 144:ef7eb2e8f9f7 69 */
<> 144:ef7eb2e8f9f7 70 static void DSPI_MasterTransferFillUpTxFifo(SPI_Type *base, dspi_master_handle_t *handle);
<> 144:ef7eb2e8f9f7 71
<> 144:ef7eb2e8f9f7 72 /*!
<> 144:ef7eb2e8f9f7 73 * @brief Master finish up a transfer.
<> 144:ef7eb2e8f9f7 74 * It would call back if there is callback function and set the state to idle.
<> 144:ef7eb2e8f9f7 75 * This is not a public API as it is called from other driver functions.
<> 144:ef7eb2e8f9f7 76 */
<> 144:ef7eb2e8f9f7 77 static void DSPI_MasterTransferComplete(SPI_Type *base, dspi_master_handle_t *handle);
<> 144:ef7eb2e8f9f7 78
<> 144:ef7eb2e8f9f7 79 /*!
<> 144:ef7eb2e8f9f7 80 * @brief Slave fill up the TX FIFO with data.
<> 144:ef7eb2e8f9f7 81 * This is not a public API as it is called from other driver functions.
<> 144:ef7eb2e8f9f7 82 */
<> 144:ef7eb2e8f9f7 83 static void DSPI_SlaveTransferFillUpTxFifo(SPI_Type *base, dspi_slave_handle_t *handle);
<> 144:ef7eb2e8f9f7 84
<> 144:ef7eb2e8f9f7 85 /*!
<> 144:ef7eb2e8f9f7 86 * @brief Slave finish up a transfer.
<> 144:ef7eb2e8f9f7 87 * It would call back if there is callback function and set the state to idle.
<> 144:ef7eb2e8f9f7 88 * This is not a public API as it is called from other driver functions.
<> 144:ef7eb2e8f9f7 89 */
<> 144:ef7eb2e8f9f7 90 static void DSPI_SlaveTransferComplete(SPI_Type *base, dspi_slave_handle_t *handle);
<> 144:ef7eb2e8f9f7 91
<> 144:ef7eb2e8f9f7 92 /*!
<> 144:ef7eb2e8f9f7 93 * @brief DSPI common interrupt handler.
<> 144:ef7eb2e8f9f7 94 *
<> 144:ef7eb2e8f9f7 95 * @param base DSPI peripheral address.
<> 144:ef7eb2e8f9f7 96 * @param handle pointer to g_dspiHandle which stores the transfer state.
<> 144:ef7eb2e8f9f7 97 */
<> 144:ef7eb2e8f9f7 98 static void DSPI_CommonIRQHandler(SPI_Type *base, void *param);
<> 144:ef7eb2e8f9f7 99
<> 144:ef7eb2e8f9f7 100 /*!
<> 144:ef7eb2e8f9f7 101 * @brief Master prepare the transfer.
<> 144:ef7eb2e8f9f7 102 * Basically it set up dspi_master_handle .
<> 144:ef7eb2e8f9f7 103 * This is not a public API as it is called from other driver functions. fsl_dspi_edma.c also call this function.
<> 144:ef7eb2e8f9f7 104 */
<> 144:ef7eb2e8f9f7 105 static void DSPI_MasterTransferPrepare(SPI_Type *base, dspi_master_handle_t *handle, dspi_transfer_t *transfer);
<> 144:ef7eb2e8f9f7 106
<> 144:ef7eb2e8f9f7 107 /*******************************************************************************
<> 144:ef7eb2e8f9f7 108 * Variables
<> 144:ef7eb2e8f9f7 109 ******************************************************************************/
<> 144:ef7eb2e8f9f7 110
<> 144:ef7eb2e8f9f7 111 /* Defines constant value arrays for the baud rate pre-scalar and scalar divider values.*/
<> 144:ef7eb2e8f9f7 112 static const uint32_t s_baudratePrescaler[] = {2, 3, 5, 7};
<> 144:ef7eb2e8f9f7 113 static const uint32_t s_baudrateScaler[] = {2, 4, 6, 8, 16, 32, 64, 128,
<> 144:ef7eb2e8f9f7 114 256, 512, 1024, 2048, 4096, 8192, 16384, 32768};
<> 144:ef7eb2e8f9f7 115
<> 144:ef7eb2e8f9f7 116 static const uint32_t s_delayPrescaler[] = {1, 3, 5, 7};
<> 144:ef7eb2e8f9f7 117 static const uint32_t s_delayScaler[] = {2, 4, 8, 16, 32, 64, 128, 256,
<> 144:ef7eb2e8f9f7 118 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536};
<> 144:ef7eb2e8f9f7 119
<> 144:ef7eb2e8f9f7 120 /*! @brief Pointers to dspi bases for each instance. */
<> 144:ef7eb2e8f9f7 121 static SPI_Type *const s_dspiBases[] = SPI_BASE_PTRS;
<> 144:ef7eb2e8f9f7 122
<> 144:ef7eb2e8f9f7 123 /*! @brief Pointers to dspi IRQ number for each instance. */
<> 144:ef7eb2e8f9f7 124 static IRQn_Type const s_dspiIRQ[] = SPI_IRQS;
<> 144:ef7eb2e8f9f7 125
<> 144:ef7eb2e8f9f7 126 /*! @brief Pointers to dspi clocks for each instance. */
<> 144:ef7eb2e8f9f7 127 static clock_ip_name_t const s_dspiClock[] = DSPI_CLOCKS;
<> 144:ef7eb2e8f9f7 128
<> 144:ef7eb2e8f9f7 129 /*! @brief Pointers to dspi handles for each instance. */
<> 144:ef7eb2e8f9f7 130 static void *g_dspiHandle[FSL_FEATURE_SOC_DSPI_COUNT];
<> 144:ef7eb2e8f9f7 131
<> 144:ef7eb2e8f9f7 132 /*! @brief Pointer to master IRQ handler for each instance. */
<> 144:ef7eb2e8f9f7 133 static dspi_master_isr_t s_dspiMasterIsr;
<> 144:ef7eb2e8f9f7 134
<> 144:ef7eb2e8f9f7 135 /*! @brief Pointer to slave IRQ handler for each instance. */
<> 144:ef7eb2e8f9f7 136 static dspi_slave_isr_t s_dspiSlaveIsr;
<> 144:ef7eb2e8f9f7 137
<> 144:ef7eb2e8f9f7 138 /**********************************************************************************************************************
<> 144:ef7eb2e8f9f7 139 * Code
<> 144:ef7eb2e8f9f7 140 *********************************************************************************************************************/
<> 144:ef7eb2e8f9f7 141 uint32_t DSPI_GetInstance(SPI_Type *base)
<> 144:ef7eb2e8f9f7 142 {
<> 144:ef7eb2e8f9f7 143 uint32_t instance;
<> 144:ef7eb2e8f9f7 144
<> 144:ef7eb2e8f9f7 145 /* Find the instance index from base address mappings. */
<> 144:ef7eb2e8f9f7 146 for (instance = 0; instance < FSL_FEATURE_SOC_DSPI_COUNT; instance++)
<> 144:ef7eb2e8f9f7 147 {
<> 144:ef7eb2e8f9f7 148 if (s_dspiBases[instance] == base)
<> 144:ef7eb2e8f9f7 149 {
<> 144:ef7eb2e8f9f7 150 break;
<> 144:ef7eb2e8f9f7 151 }
<> 144:ef7eb2e8f9f7 152 }
<> 144:ef7eb2e8f9f7 153
<> 144:ef7eb2e8f9f7 154 assert(instance < FSL_FEATURE_SOC_DSPI_COUNT);
<> 144:ef7eb2e8f9f7 155
<> 144:ef7eb2e8f9f7 156 return instance;
<> 144:ef7eb2e8f9f7 157 }
<> 144:ef7eb2e8f9f7 158
<> 144:ef7eb2e8f9f7 159 void DSPI_MasterInit(SPI_Type *base, const dspi_master_config_t *masterConfig, uint32_t srcClock_Hz)
<> 144:ef7eb2e8f9f7 160 {
<> 144:ef7eb2e8f9f7 161 uint32_t temp;
<> 144:ef7eb2e8f9f7 162 /* enable DSPI clock */
<> 144:ef7eb2e8f9f7 163 CLOCK_EnableClock(s_dspiClock[DSPI_GetInstance(base)]);
<> 144:ef7eb2e8f9f7 164
<> 144:ef7eb2e8f9f7 165 DSPI_Enable(base, true);
<> 144:ef7eb2e8f9f7 166 DSPI_StopTransfer(base);
<> 144:ef7eb2e8f9f7 167
<> 144:ef7eb2e8f9f7 168 DSPI_SetMasterSlaveMode(base, kDSPI_Master);
<> 144:ef7eb2e8f9f7 169
<> 144:ef7eb2e8f9f7 170 temp = base->MCR & (~(SPI_MCR_CONT_SCKE_MASK | SPI_MCR_MTFE_MASK | SPI_MCR_ROOE_MASK | SPI_MCR_SMPL_PT_MASK |
<> 144:ef7eb2e8f9f7 171 SPI_MCR_DIS_TXF_MASK | SPI_MCR_DIS_RXF_MASK));
<> 144:ef7eb2e8f9f7 172
<> 144:ef7eb2e8f9f7 173 base->MCR = temp | SPI_MCR_CONT_SCKE(masterConfig->enableContinuousSCK) |
<> 144:ef7eb2e8f9f7 174 SPI_MCR_MTFE(masterConfig->enableModifiedTimingFormat) |
<> 144:ef7eb2e8f9f7 175 SPI_MCR_ROOE(masterConfig->enableRxFifoOverWrite) | SPI_MCR_SMPL_PT(masterConfig->samplePoint) |
<> 144:ef7eb2e8f9f7 176 SPI_MCR_DIS_TXF(false) | SPI_MCR_DIS_RXF(false);
<> 144:ef7eb2e8f9f7 177
<> 144:ef7eb2e8f9f7 178 DSPI_SetOnePcsPolarity(base, masterConfig->whichPcs, masterConfig->pcsActiveHighOrLow);
<> 144:ef7eb2e8f9f7 179
<> 144:ef7eb2e8f9f7 180 if (0 == DSPI_MasterSetBaudRate(base, masterConfig->whichCtar, masterConfig->ctarConfig.baudRate, srcClock_Hz))
<> 144:ef7eb2e8f9f7 181 {
<> 144:ef7eb2e8f9f7 182 assert(false);
<> 144:ef7eb2e8f9f7 183 }
<> 144:ef7eb2e8f9f7 184
<> 144:ef7eb2e8f9f7 185 temp = base->CTAR[masterConfig->whichCtar] &
<> 144:ef7eb2e8f9f7 186 ~(SPI_CTAR_FMSZ_MASK | SPI_CTAR_CPOL_MASK | SPI_CTAR_CPHA_MASK | SPI_CTAR_LSBFE_MASK);
<> 144:ef7eb2e8f9f7 187
<> 144:ef7eb2e8f9f7 188 base->CTAR[masterConfig->whichCtar] =
<> 144:ef7eb2e8f9f7 189 temp | SPI_CTAR_FMSZ(masterConfig->ctarConfig.bitsPerFrame - 1) | SPI_CTAR_CPOL(masterConfig->ctarConfig.cpol) |
<> 144:ef7eb2e8f9f7 190 SPI_CTAR_CPHA(masterConfig->ctarConfig.cpha) | SPI_CTAR_LSBFE(masterConfig->ctarConfig.direction);
<> 144:ef7eb2e8f9f7 191
<> 144:ef7eb2e8f9f7 192 DSPI_MasterSetDelayTimes(base, masterConfig->whichCtar, kDSPI_PcsToSck, srcClock_Hz,
<> 144:ef7eb2e8f9f7 193 masterConfig->ctarConfig.pcsToSckDelayInNanoSec);
<> 144:ef7eb2e8f9f7 194 DSPI_MasterSetDelayTimes(base, masterConfig->whichCtar, kDSPI_LastSckToPcs, srcClock_Hz,
<> 144:ef7eb2e8f9f7 195 masterConfig->ctarConfig.lastSckToPcsDelayInNanoSec);
<> 144:ef7eb2e8f9f7 196 DSPI_MasterSetDelayTimes(base, masterConfig->whichCtar, kDSPI_BetweenTransfer, srcClock_Hz,
<> 144:ef7eb2e8f9f7 197 masterConfig->ctarConfig.betweenTransferDelayInNanoSec);
<> 144:ef7eb2e8f9f7 198
<> 144:ef7eb2e8f9f7 199 DSPI_StartTransfer(base);
<> 144:ef7eb2e8f9f7 200 }
<> 144:ef7eb2e8f9f7 201
<> 144:ef7eb2e8f9f7 202 void DSPI_MasterGetDefaultConfig(dspi_master_config_t *masterConfig)
<> 144:ef7eb2e8f9f7 203 {
<> 144:ef7eb2e8f9f7 204 masterConfig->whichCtar = kDSPI_Ctar0;
<> 144:ef7eb2e8f9f7 205 masterConfig->ctarConfig.baudRate = 500000;
<> 144:ef7eb2e8f9f7 206 masterConfig->ctarConfig.bitsPerFrame = 8;
<> 144:ef7eb2e8f9f7 207 masterConfig->ctarConfig.cpol = kDSPI_ClockPolarityActiveHigh;
<> 144:ef7eb2e8f9f7 208 masterConfig->ctarConfig.cpha = kDSPI_ClockPhaseFirstEdge;
<> 144:ef7eb2e8f9f7 209 masterConfig->ctarConfig.direction = kDSPI_MsbFirst;
<> 144:ef7eb2e8f9f7 210
<> 144:ef7eb2e8f9f7 211 masterConfig->ctarConfig.pcsToSckDelayInNanoSec = 1000;
<> 144:ef7eb2e8f9f7 212 masterConfig->ctarConfig.lastSckToPcsDelayInNanoSec = 1000;
<> 144:ef7eb2e8f9f7 213 masterConfig->ctarConfig.betweenTransferDelayInNanoSec = 1000;
<> 144:ef7eb2e8f9f7 214
<> 144:ef7eb2e8f9f7 215 masterConfig->whichPcs = kDSPI_Pcs0;
<> 144:ef7eb2e8f9f7 216 masterConfig->pcsActiveHighOrLow = kDSPI_PcsActiveLow;
<> 144:ef7eb2e8f9f7 217
<> 144:ef7eb2e8f9f7 218 masterConfig->enableContinuousSCK = false;
<> 144:ef7eb2e8f9f7 219 masterConfig->enableRxFifoOverWrite = false;
<> 144:ef7eb2e8f9f7 220 masterConfig->enableModifiedTimingFormat = false;
<> 144:ef7eb2e8f9f7 221 masterConfig->samplePoint = kDSPI_SckToSin0Clock;
<> 144:ef7eb2e8f9f7 222 }
<> 144:ef7eb2e8f9f7 223
<> 144:ef7eb2e8f9f7 224 void DSPI_SlaveInit(SPI_Type *base, const dspi_slave_config_t *slaveConfig)
<> 144:ef7eb2e8f9f7 225 {
<> 144:ef7eb2e8f9f7 226 uint32_t temp = 0;
<> 144:ef7eb2e8f9f7 227
<> 144:ef7eb2e8f9f7 228 /* enable DSPI clock */
<> 144:ef7eb2e8f9f7 229 CLOCK_EnableClock(s_dspiClock[DSPI_GetInstance(base)]);
<> 144:ef7eb2e8f9f7 230
<> 144:ef7eb2e8f9f7 231 DSPI_Enable(base, true);
<> 144:ef7eb2e8f9f7 232 DSPI_StopTransfer(base);
<> 144:ef7eb2e8f9f7 233
<> 144:ef7eb2e8f9f7 234 DSPI_SetMasterSlaveMode(base, kDSPI_Slave);
<> 144:ef7eb2e8f9f7 235
<> 144:ef7eb2e8f9f7 236 temp = base->MCR & (~(SPI_MCR_CONT_SCKE_MASK | SPI_MCR_MTFE_MASK | SPI_MCR_ROOE_MASK | SPI_MCR_SMPL_PT_MASK |
<> 144:ef7eb2e8f9f7 237 SPI_MCR_DIS_TXF_MASK | SPI_MCR_DIS_RXF_MASK));
<> 144:ef7eb2e8f9f7 238
<> 144:ef7eb2e8f9f7 239 base->MCR = temp | SPI_MCR_CONT_SCKE(slaveConfig->enableContinuousSCK) |
<> 144:ef7eb2e8f9f7 240 SPI_MCR_MTFE(slaveConfig->enableModifiedTimingFormat) |
<> 144:ef7eb2e8f9f7 241 SPI_MCR_ROOE(slaveConfig->enableRxFifoOverWrite) | SPI_MCR_SMPL_PT(slaveConfig->samplePoint) |
<> 144:ef7eb2e8f9f7 242 SPI_MCR_DIS_TXF(false) | SPI_MCR_DIS_RXF(false);
<> 144:ef7eb2e8f9f7 243
<> 144:ef7eb2e8f9f7 244 DSPI_SetOnePcsPolarity(base, kDSPI_Pcs0, kDSPI_PcsActiveLow);
<> 144:ef7eb2e8f9f7 245
<> 144:ef7eb2e8f9f7 246 temp = base->CTAR[slaveConfig->whichCtar] &
<> 144:ef7eb2e8f9f7 247 ~(SPI_CTAR_FMSZ_MASK | SPI_CTAR_CPOL_MASK | SPI_CTAR_CPHA_MASK | SPI_CTAR_LSBFE_MASK);
<> 144:ef7eb2e8f9f7 248
<> 144:ef7eb2e8f9f7 249 base->CTAR[slaveConfig->whichCtar] = temp | SPI_CTAR_SLAVE_FMSZ(slaveConfig->ctarConfig.bitsPerFrame - 1) |
<> 144:ef7eb2e8f9f7 250 SPI_CTAR_SLAVE_CPOL(slaveConfig->ctarConfig.cpol) |
<> 144:ef7eb2e8f9f7 251 SPI_CTAR_SLAVE_CPHA(slaveConfig->ctarConfig.cpha);
<> 144:ef7eb2e8f9f7 252
<> 144:ef7eb2e8f9f7 253 DSPI_StartTransfer(base);
<> 144:ef7eb2e8f9f7 254 }
<> 144:ef7eb2e8f9f7 255
<> 144:ef7eb2e8f9f7 256 void DSPI_SlaveGetDefaultConfig(dspi_slave_config_t *slaveConfig)
<> 144:ef7eb2e8f9f7 257 {
<> 144:ef7eb2e8f9f7 258 slaveConfig->whichCtar = kDSPI_Ctar0;
<> 144:ef7eb2e8f9f7 259 slaveConfig->ctarConfig.bitsPerFrame = 8;
<> 144:ef7eb2e8f9f7 260 slaveConfig->ctarConfig.cpol = kDSPI_ClockPolarityActiveHigh;
<> 144:ef7eb2e8f9f7 261 slaveConfig->ctarConfig.cpha = kDSPI_ClockPhaseFirstEdge;
<> 144:ef7eb2e8f9f7 262
<> 144:ef7eb2e8f9f7 263 slaveConfig->enableContinuousSCK = false;
<> 144:ef7eb2e8f9f7 264 slaveConfig->enableRxFifoOverWrite = false;
<> 144:ef7eb2e8f9f7 265 slaveConfig->enableModifiedTimingFormat = false;
<> 144:ef7eb2e8f9f7 266 slaveConfig->samplePoint = kDSPI_SckToSin0Clock;
<> 144:ef7eb2e8f9f7 267 }
<> 144:ef7eb2e8f9f7 268
<> 144:ef7eb2e8f9f7 269 void DSPI_Deinit(SPI_Type *base)
<> 144:ef7eb2e8f9f7 270 {
<> 144:ef7eb2e8f9f7 271 DSPI_StopTransfer(base);
<> 144:ef7eb2e8f9f7 272 DSPI_Enable(base, false);
<> 144:ef7eb2e8f9f7 273
<> 144:ef7eb2e8f9f7 274 /* disable DSPI clock */
<> 144:ef7eb2e8f9f7 275 CLOCK_DisableClock(s_dspiClock[DSPI_GetInstance(base)]);
<> 144:ef7eb2e8f9f7 276 }
<> 144:ef7eb2e8f9f7 277
<> 144:ef7eb2e8f9f7 278 static void DSPI_SetOnePcsPolarity(SPI_Type *base, dspi_which_pcs_t pcs, dspi_pcs_polarity_config_t activeLowOrHigh)
<> 144:ef7eb2e8f9f7 279 {
<> 144:ef7eb2e8f9f7 280 uint32_t temp;
<> 144:ef7eb2e8f9f7 281
<> 144:ef7eb2e8f9f7 282 temp = base->MCR;
<> 144:ef7eb2e8f9f7 283
<> 144:ef7eb2e8f9f7 284 if (activeLowOrHigh == kDSPI_PcsActiveLow)
<> 144:ef7eb2e8f9f7 285 {
<> 144:ef7eb2e8f9f7 286 temp |= SPI_MCR_PCSIS(pcs);
<> 144:ef7eb2e8f9f7 287 }
<> 144:ef7eb2e8f9f7 288 else
<> 144:ef7eb2e8f9f7 289 {
<> 144:ef7eb2e8f9f7 290 temp &= ~SPI_MCR_PCSIS(pcs);
<> 144:ef7eb2e8f9f7 291 }
<> 144:ef7eb2e8f9f7 292
<> 144:ef7eb2e8f9f7 293 base->MCR = temp;
<> 144:ef7eb2e8f9f7 294 }
<> 144:ef7eb2e8f9f7 295
<> 144:ef7eb2e8f9f7 296 uint32_t DSPI_MasterSetBaudRate(SPI_Type *base,
<> 144:ef7eb2e8f9f7 297 dspi_ctar_selection_t whichCtar,
<> 144:ef7eb2e8f9f7 298 uint32_t baudRate_Bps,
<> 144:ef7eb2e8f9f7 299 uint32_t srcClock_Hz)
<> 144:ef7eb2e8f9f7 300 {
<> 144:ef7eb2e8f9f7 301 /* for master mode configuration, if slave mode detected, return 0*/
<> 144:ef7eb2e8f9f7 302 if (!DSPI_IsMaster(base))
<> 144:ef7eb2e8f9f7 303 {
<> 144:ef7eb2e8f9f7 304 return 0;
<> 144:ef7eb2e8f9f7 305 }
<> 144:ef7eb2e8f9f7 306 uint32_t temp;
<> 144:ef7eb2e8f9f7 307 uint32_t prescaler, bestPrescaler;
<> 144:ef7eb2e8f9f7 308 uint32_t scaler, bestScaler;
<> 144:ef7eb2e8f9f7 309 uint32_t dbr, bestDbr;
<> 144:ef7eb2e8f9f7 310 uint32_t realBaudrate, bestBaudrate;
<> 144:ef7eb2e8f9f7 311 uint32_t diff, min_diff;
<> 144:ef7eb2e8f9f7 312 uint32_t baudrate = baudRate_Bps;
<> 144:ef7eb2e8f9f7 313
<> 144:ef7eb2e8f9f7 314 /* find combination of prescaler and scaler resulting in baudrate closest to the requested value */
<> 144:ef7eb2e8f9f7 315 min_diff = 0xFFFFFFFFU;
<> 144:ef7eb2e8f9f7 316 bestPrescaler = 0;
<> 144:ef7eb2e8f9f7 317 bestScaler = 0;
<> 144:ef7eb2e8f9f7 318 bestDbr = 1;
<> 144:ef7eb2e8f9f7 319 bestBaudrate = 0; /* required to avoid compilation warning */
<> 144:ef7eb2e8f9f7 320
<> 144:ef7eb2e8f9f7 321 /* In all for loops, if min_diff = 0, the exit for loop*/
<> 144:ef7eb2e8f9f7 322 for (prescaler = 0; (prescaler < 4) && min_diff; prescaler++)
<> 144:ef7eb2e8f9f7 323 {
<> 144:ef7eb2e8f9f7 324 for (scaler = 0; (scaler < 16) && min_diff; scaler++)
<> 144:ef7eb2e8f9f7 325 {
<> 144:ef7eb2e8f9f7 326 for (dbr = 1; (dbr < 3) && min_diff; dbr++)
<> 144:ef7eb2e8f9f7 327 {
<> 144:ef7eb2e8f9f7 328 realBaudrate = ((srcClock_Hz * dbr) / (s_baudratePrescaler[prescaler] * (s_baudrateScaler[scaler])));
<> 144:ef7eb2e8f9f7 329
<> 144:ef7eb2e8f9f7 330 /* calculate the baud rate difference based on the conditional statement that states that the calculated
<> 144:ef7eb2e8f9f7 331 * baud rate must not exceed the desired baud rate.
<> 144:ef7eb2e8f9f7 332 */
<> 144:ef7eb2e8f9f7 333 if (baudrate >= realBaudrate)
<> 144:ef7eb2e8f9f7 334 {
<> 144:ef7eb2e8f9f7 335 diff = baudrate - realBaudrate;
<> 144:ef7eb2e8f9f7 336 if (min_diff > diff)
<> 144:ef7eb2e8f9f7 337 {
<> 144:ef7eb2e8f9f7 338 /* a better match found */
<> 144:ef7eb2e8f9f7 339 min_diff = diff;
<> 144:ef7eb2e8f9f7 340 bestPrescaler = prescaler;
<> 144:ef7eb2e8f9f7 341 bestScaler = scaler;
<> 144:ef7eb2e8f9f7 342 bestBaudrate = realBaudrate;
<> 144:ef7eb2e8f9f7 343 bestDbr = dbr;
<> 144:ef7eb2e8f9f7 344 }
<> 144:ef7eb2e8f9f7 345 }
<> 144:ef7eb2e8f9f7 346 }
<> 144:ef7eb2e8f9f7 347 }
<> 144:ef7eb2e8f9f7 348 }
<> 144:ef7eb2e8f9f7 349
<> 144:ef7eb2e8f9f7 350 /* write the best dbr, prescalar, and baud rate scalar to the CTAR */
<> 144:ef7eb2e8f9f7 351 temp = base->CTAR[whichCtar] & ~(SPI_CTAR_DBR_MASK | SPI_CTAR_PBR_MASK | SPI_CTAR_BR_MASK);
<> 144:ef7eb2e8f9f7 352
<> 144:ef7eb2e8f9f7 353 base->CTAR[whichCtar] = temp | ((bestDbr - 1) << SPI_CTAR_DBR_SHIFT) | (bestPrescaler << SPI_CTAR_PBR_SHIFT) |
<> 144:ef7eb2e8f9f7 354 (bestScaler << SPI_CTAR_BR_SHIFT);
<> 144:ef7eb2e8f9f7 355
<> 144:ef7eb2e8f9f7 356 /* return the actual calculated baud rate */
<> 144:ef7eb2e8f9f7 357 return bestBaudrate;
<> 144:ef7eb2e8f9f7 358 }
<> 144:ef7eb2e8f9f7 359
<> 144:ef7eb2e8f9f7 360 void DSPI_MasterSetDelayScaler(
<> 144:ef7eb2e8f9f7 361 SPI_Type *base, dspi_ctar_selection_t whichCtar, uint32_t prescaler, uint32_t scaler, dspi_delay_type_t whichDelay)
<> 144:ef7eb2e8f9f7 362 {
<> 144:ef7eb2e8f9f7 363 /* these settings are only relevant in master mode */
<> 144:ef7eb2e8f9f7 364 if (DSPI_IsMaster(base))
<> 144:ef7eb2e8f9f7 365 {
<> 144:ef7eb2e8f9f7 366 switch (whichDelay)
<> 144:ef7eb2e8f9f7 367 {
<> 144:ef7eb2e8f9f7 368 case kDSPI_PcsToSck:
<> 144:ef7eb2e8f9f7 369 base->CTAR[whichCtar] = (base->CTAR[whichCtar] & (~SPI_CTAR_PCSSCK_MASK) & (~SPI_CTAR_CSSCK_MASK)) |
<> 144:ef7eb2e8f9f7 370 SPI_CTAR_PCSSCK(prescaler) | SPI_CTAR_CSSCK(scaler);
<> 144:ef7eb2e8f9f7 371 break;
<> 144:ef7eb2e8f9f7 372 case kDSPI_LastSckToPcs:
<> 144:ef7eb2e8f9f7 373 base->CTAR[whichCtar] = (base->CTAR[whichCtar] & (~SPI_CTAR_PASC_MASK) & (~SPI_CTAR_ASC_MASK)) |
<> 144:ef7eb2e8f9f7 374 SPI_CTAR_PASC(prescaler) | SPI_CTAR_ASC(scaler);
<> 144:ef7eb2e8f9f7 375 break;
<> 144:ef7eb2e8f9f7 376 case kDSPI_BetweenTransfer:
<> 144:ef7eb2e8f9f7 377 base->CTAR[whichCtar] = (base->CTAR[whichCtar] & (~SPI_CTAR_PDT_MASK) & (~SPI_CTAR_DT_MASK)) |
<> 144:ef7eb2e8f9f7 378 SPI_CTAR_PDT(prescaler) | SPI_CTAR_DT(scaler);
<> 144:ef7eb2e8f9f7 379 break;
<> 144:ef7eb2e8f9f7 380 default:
<> 144:ef7eb2e8f9f7 381 break;
<> 144:ef7eb2e8f9f7 382 }
<> 144:ef7eb2e8f9f7 383 }
<> 144:ef7eb2e8f9f7 384 }
<> 144:ef7eb2e8f9f7 385
<> 144:ef7eb2e8f9f7 386 uint32_t DSPI_MasterSetDelayTimes(SPI_Type *base,
<> 144:ef7eb2e8f9f7 387 dspi_ctar_selection_t whichCtar,
<> 144:ef7eb2e8f9f7 388 dspi_delay_type_t whichDelay,
<> 144:ef7eb2e8f9f7 389 uint32_t srcClock_Hz,
<> 144:ef7eb2e8f9f7 390 uint32_t delayTimeInNanoSec)
<> 144:ef7eb2e8f9f7 391 {
<> 144:ef7eb2e8f9f7 392 /* for master mode configuration, if slave mode detected, return 0 */
<> 144:ef7eb2e8f9f7 393 if (!DSPI_IsMaster(base))
<> 144:ef7eb2e8f9f7 394 {
<> 144:ef7eb2e8f9f7 395 return 0;
<> 144:ef7eb2e8f9f7 396 }
<> 144:ef7eb2e8f9f7 397
<> 144:ef7eb2e8f9f7 398 uint32_t prescaler, bestPrescaler;
<> 144:ef7eb2e8f9f7 399 uint32_t scaler, bestScaler;
<> 144:ef7eb2e8f9f7 400 uint32_t realDelay, bestDelay;
<> 144:ef7eb2e8f9f7 401 uint32_t diff, min_diff;
<> 144:ef7eb2e8f9f7 402 uint32_t initialDelayNanoSec;
<> 144:ef7eb2e8f9f7 403
<> 144:ef7eb2e8f9f7 404 /* find combination of prescaler and scaler resulting in the delay closest to the
<> 144:ef7eb2e8f9f7 405 * requested value
<> 144:ef7eb2e8f9f7 406 */
<> 144:ef7eb2e8f9f7 407 min_diff = 0xFFFFFFFFU;
<> 144:ef7eb2e8f9f7 408 /* Initialize prescaler and scaler to their max values to generate the max delay */
<> 144:ef7eb2e8f9f7 409 bestPrescaler = 0x3;
<> 144:ef7eb2e8f9f7 410 bestScaler = 0xF;
<> 144:ef7eb2e8f9f7 411 bestDelay = (((1000000000U * 4) / srcClock_Hz) * s_delayPrescaler[bestPrescaler] * s_delayScaler[bestScaler]) / 4;
<> 144:ef7eb2e8f9f7 412
<> 144:ef7eb2e8f9f7 413 /* First calculate the initial, default delay */
<> 144:ef7eb2e8f9f7 414 initialDelayNanoSec = 1000000000U / srcClock_Hz * 2;
<> 144:ef7eb2e8f9f7 415
<> 144:ef7eb2e8f9f7 416 /* If the initial, default delay is already greater than the desired delay, then
<> 144:ef7eb2e8f9f7 417 * set the delays to their initial value (0) and return the delay. In other words,
<> 144:ef7eb2e8f9f7 418 * there is no way to decrease the delay value further.
<> 144:ef7eb2e8f9f7 419 */
<> 144:ef7eb2e8f9f7 420 if (initialDelayNanoSec >= delayTimeInNanoSec)
<> 144:ef7eb2e8f9f7 421 {
<> 144:ef7eb2e8f9f7 422 DSPI_MasterSetDelayScaler(base, whichCtar, 0, 0, whichDelay);
<> 144:ef7eb2e8f9f7 423 return initialDelayNanoSec;
<> 144:ef7eb2e8f9f7 424 }
<> 144:ef7eb2e8f9f7 425
<> 144:ef7eb2e8f9f7 426 /* In all for loops, if min_diff = 0, the exit for loop */
<> 144:ef7eb2e8f9f7 427 for (prescaler = 0; (prescaler < 4) && min_diff; prescaler++)
<> 144:ef7eb2e8f9f7 428 {
<> 144:ef7eb2e8f9f7 429 for (scaler = 0; (scaler < 16) && min_diff; scaler++)
<> 144:ef7eb2e8f9f7 430 {
<> 144:ef7eb2e8f9f7 431 realDelay = ((4000000000U / srcClock_Hz) * s_delayPrescaler[prescaler] * s_delayScaler[scaler]) / 4;
<> 144:ef7eb2e8f9f7 432
<> 144:ef7eb2e8f9f7 433 /* calculate the delay difference based on the conditional statement
<> 144:ef7eb2e8f9f7 434 * that states that the calculated delay must not be less then the desired delay
<> 144:ef7eb2e8f9f7 435 */
<> 144:ef7eb2e8f9f7 436 if (realDelay >= delayTimeInNanoSec)
<> 144:ef7eb2e8f9f7 437 {
<> 144:ef7eb2e8f9f7 438 diff = realDelay - delayTimeInNanoSec;
<> 144:ef7eb2e8f9f7 439 if (min_diff > diff)
<> 144:ef7eb2e8f9f7 440 {
<> 144:ef7eb2e8f9f7 441 /* a better match found */
<> 144:ef7eb2e8f9f7 442 min_diff = diff;
<> 144:ef7eb2e8f9f7 443 bestPrescaler = prescaler;
<> 144:ef7eb2e8f9f7 444 bestScaler = scaler;
<> 144:ef7eb2e8f9f7 445 bestDelay = realDelay;
<> 144:ef7eb2e8f9f7 446 }
<> 144:ef7eb2e8f9f7 447 }
<> 144:ef7eb2e8f9f7 448 }
<> 144:ef7eb2e8f9f7 449 }
<> 144:ef7eb2e8f9f7 450
<> 144:ef7eb2e8f9f7 451 /* write the best dbr, prescalar, and baud rate scalar to the CTAR */
<> 144:ef7eb2e8f9f7 452 DSPI_MasterSetDelayScaler(base, whichCtar, bestPrescaler, bestScaler, whichDelay);
<> 144:ef7eb2e8f9f7 453
<> 144:ef7eb2e8f9f7 454 /* return the actual calculated baud rate */
<> 144:ef7eb2e8f9f7 455 return bestDelay;
<> 144:ef7eb2e8f9f7 456 }
<> 144:ef7eb2e8f9f7 457
<> 144:ef7eb2e8f9f7 458 void DSPI_GetDefaultDataCommandConfig(dspi_command_data_config_t *command)
<> 144:ef7eb2e8f9f7 459 {
<> 144:ef7eb2e8f9f7 460 command->isPcsContinuous = false;
<> 144:ef7eb2e8f9f7 461 command->whichCtar = kDSPI_Ctar0;
<> 144:ef7eb2e8f9f7 462 command->whichPcs = kDSPI_Pcs0;
<> 144:ef7eb2e8f9f7 463 command->isEndOfQueue = false;
<> 144:ef7eb2e8f9f7 464 command->clearTransferCount = false;
<> 144:ef7eb2e8f9f7 465 }
<> 144:ef7eb2e8f9f7 466
<> 144:ef7eb2e8f9f7 467 void DSPI_MasterWriteDataBlocking(SPI_Type *base, dspi_command_data_config_t *command, uint16_t data)
<> 144:ef7eb2e8f9f7 468 {
<> 144:ef7eb2e8f9f7 469 /* First, clear Transmit Complete Flag (TCF) */
<> 144:ef7eb2e8f9f7 470 DSPI_ClearStatusFlags(base, kDSPI_TxCompleteFlag);
<> 144:ef7eb2e8f9f7 471
<> 144:ef7eb2e8f9f7 472 while (!(DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag))
<> 144:ef7eb2e8f9f7 473 {
<> 144:ef7eb2e8f9f7 474 DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
<> 144:ef7eb2e8f9f7 475 }
<> 144:ef7eb2e8f9f7 476
<> 144:ef7eb2e8f9f7 477 base->PUSHR = SPI_PUSHR_CONT(command->isPcsContinuous) | SPI_PUSHR_CTAS(command->whichCtar) |
<> 144:ef7eb2e8f9f7 478 SPI_PUSHR_PCS(command->whichPcs) | SPI_PUSHR_EOQ(command->isEndOfQueue) |
<> 144:ef7eb2e8f9f7 479 SPI_PUSHR_CTCNT(command->clearTransferCount) | SPI_PUSHR_TXDATA(data);
<> 144:ef7eb2e8f9f7 480 DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
<> 144:ef7eb2e8f9f7 481
<> 144:ef7eb2e8f9f7 482 /* Wait till TCF sets */
<> 144:ef7eb2e8f9f7 483 while (!(DSPI_GetStatusFlags(base) & kDSPI_TxCompleteFlag))
<> 144:ef7eb2e8f9f7 484 {
<> 144:ef7eb2e8f9f7 485 }
<> 144:ef7eb2e8f9f7 486 }
<> 144:ef7eb2e8f9f7 487
<> 144:ef7eb2e8f9f7 488 void DSPI_MasterWriteCommandDataBlocking(SPI_Type *base, uint32_t data)
<> 144:ef7eb2e8f9f7 489 {
<> 144:ef7eb2e8f9f7 490 /* First, clear Transmit Complete Flag (TCF) */
<> 144:ef7eb2e8f9f7 491 DSPI_ClearStatusFlags(base, kDSPI_TxCompleteFlag);
<> 144:ef7eb2e8f9f7 492
<> 144:ef7eb2e8f9f7 493 while (!(DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag))
<> 144:ef7eb2e8f9f7 494 {
<> 144:ef7eb2e8f9f7 495 DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
<> 144:ef7eb2e8f9f7 496 }
<> 144:ef7eb2e8f9f7 497
<> 144:ef7eb2e8f9f7 498 base->PUSHR = data;
<> 144:ef7eb2e8f9f7 499
<> 144:ef7eb2e8f9f7 500 DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
<> 144:ef7eb2e8f9f7 501
<> 144:ef7eb2e8f9f7 502 /* Wait till TCF sets */
<> 144:ef7eb2e8f9f7 503 while (!(DSPI_GetStatusFlags(base) & kDSPI_TxCompleteFlag))
<> 144:ef7eb2e8f9f7 504 {
<> 144:ef7eb2e8f9f7 505 }
<> 144:ef7eb2e8f9f7 506 }
<> 144:ef7eb2e8f9f7 507
<> 144:ef7eb2e8f9f7 508 void DSPI_SlaveWriteDataBlocking(SPI_Type *base, uint32_t data)
<> 144:ef7eb2e8f9f7 509 {
<> 144:ef7eb2e8f9f7 510 /* First, clear Transmit Complete Flag (TCF) */
<> 144:ef7eb2e8f9f7 511 DSPI_ClearStatusFlags(base, kDSPI_TxCompleteFlag);
<> 144:ef7eb2e8f9f7 512
<> 144:ef7eb2e8f9f7 513 while (!(DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag))
<> 144:ef7eb2e8f9f7 514 {
<> 144:ef7eb2e8f9f7 515 DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
<> 144:ef7eb2e8f9f7 516 }
<> 144:ef7eb2e8f9f7 517
<> 144:ef7eb2e8f9f7 518 base->PUSHR_SLAVE = data;
<> 144:ef7eb2e8f9f7 519
<> 144:ef7eb2e8f9f7 520 DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
<> 144:ef7eb2e8f9f7 521
<> 144:ef7eb2e8f9f7 522 /* Wait till TCF sets */
<> 144:ef7eb2e8f9f7 523 while (!(DSPI_GetStatusFlags(base) & kDSPI_TxCompleteFlag))
<> 144:ef7eb2e8f9f7 524 {
<> 144:ef7eb2e8f9f7 525 }
<> 144:ef7eb2e8f9f7 526 }
<> 144:ef7eb2e8f9f7 527
<> 144:ef7eb2e8f9f7 528 void DSPI_EnableInterrupts(SPI_Type *base, uint32_t mask)
<> 144:ef7eb2e8f9f7 529 {
<> 144:ef7eb2e8f9f7 530 if (mask & SPI_RSER_TFFF_RE_MASK)
<> 144:ef7eb2e8f9f7 531 {
<> 144:ef7eb2e8f9f7 532 base->RSER &= ~SPI_RSER_TFFF_DIRS_MASK;
<> 144:ef7eb2e8f9f7 533 }
<> 144:ef7eb2e8f9f7 534 if (mask & SPI_RSER_RFDF_RE_MASK)
<> 144:ef7eb2e8f9f7 535 {
<> 144:ef7eb2e8f9f7 536 base->RSER &= ~SPI_RSER_RFDF_DIRS_MASK;
<> 144:ef7eb2e8f9f7 537 }
<> 144:ef7eb2e8f9f7 538 base->RSER |= mask;
<> 144:ef7eb2e8f9f7 539 }
<> 144:ef7eb2e8f9f7 540
<> 144:ef7eb2e8f9f7 541 /*Transactional APIs -- Master*/
<> 144:ef7eb2e8f9f7 542
<> 144:ef7eb2e8f9f7 543 void DSPI_MasterTransferCreateHandle(SPI_Type *base,
<> 144:ef7eb2e8f9f7 544 dspi_master_handle_t *handle,
<> 144:ef7eb2e8f9f7 545 dspi_master_transfer_callback_t callback,
<> 144:ef7eb2e8f9f7 546 void *userData)
<> 144:ef7eb2e8f9f7 547 {
<> 144:ef7eb2e8f9f7 548 assert(handle);
<> 144:ef7eb2e8f9f7 549
<> 144:ef7eb2e8f9f7 550 /* Zero the handle. */
<> 144:ef7eb2e8f9f7 551 memset(handle, 0, sizeof(*handle));
<> 144:ef7eb2e8f9f7 552
<> 144:ef7eb2e8f9f7 553 g_dspiHandle[DSPI_GetInstance(base)] = handle;
<> 144:ef7eb2e8f9f7 554
<> 144:ef7eb2e8f9f7 555 handle->callback = callback;
<> 144:ef7eb2e8f9f7 556 handle->userData = userData;
<> 144:ef7eb2e8f9f7 557 }
<> 144:ef7eb2e8f9f7 558
<> 144:ef7eb2e8f9f7 559 status_t DSPI_MasterTransferBlocking(SPI_Type *base, dspi_transfer_t *transfer)
<> 144:ef7eb2e8f9f7 560 {
<> 144:ef7eb2e8f9f7 561 assert(transfer);
<> 144:ef7eb2e8f9f7 562
<> 144:ef7eb2e8f9f7 563 uint16_t wordToSend = 0;
<> 144:ef7eb2e8f9f7 564 uint16_t wordReceived = 0;
<> 144:ef7eb2e8f9f7 565 uint8_t dummyData = DSPI_MASTER_DUMMY_DATA;
<> 144:ef7eb2e8f9f7 566 uint8_t bitsPerFrame;
<> 144:ef7eb2e8f9f7 567
<> 144:ef7eb2e8f9f7 568 uint32_t command;
<> 144:ef7eb2e8f9f7 569 uint32_t lastCommand;
<> 144:ef7eb2e8f9f7 570
<> 144:ef7eb2e8f9f7 571 uint8_t *txData;
<> 144:ef7eb2e8f9f7 572 uint8_t *rxData;
<> 144:ef7eb2e8f9f7 573 uint32_t remainingSendByteCount;
<> 144:ef7eb2e8f9f7 574 uint32_t remainingReceiveByteCount;
<> 144:ef7eb2e8f9f7 575
<> 144:ef7eb2e8f9f7 576 uint32_t fifoSize;
<> 144:ef7eb2e8f9f7 577 dspi_command_data_config_t commandStruct;
<> 144:ef7eb2e8f9f7 578
<> 144:ef7eb2e8f9f7 579 /* If the transfer count is zero, then return immediately.*/
<> 144:ef7eb2e8f9f7 580 if (transfer->dataSize == 0)
<> 144:ef7eb2e8f9f7 581 {
<> 144:ef7eb2e8f9f7 582 return kStatus_InvalidArgument;
<> 144:ef7eb2e8f9f7 583 }
<> 144:ef7eb2e8f9f7 584
<> 144:ef7eb2e8f9f7 585 DSPI_StopTransfer(base);
<> 144:ef7eb2e8f9f7 586 DSPI_DisableInterrupts(base, kDSPI_AllInterruptEnable);
<> 144:ef7eb2e8f9f7 587 DSPI_FlushFifo(base, true, true);
<> 144:ef7eb2e8f9f7 588 DSPI_ClearStatusFlags(base, kDSPI_AllStatusFlag);
<> 144:ef7eb2e8f9f7 589
<> 144:ef7eb2e8f9f7 590 /*Calculate the command and lastCommand*/
<> 144:ef7eb2e8f9f7 591 commandStruct.whichPcs =
<> 144:ef7eb2e8f9f7 592 (dspi_which_pcs_t)(1U << ((transfer->configFlags & DSPI_MASTER_PCS_MASK) >> DSPI_MASTER_PCS_SHIFT));
<> 144:ef7eb2e8f9f7 593 commandStruct.isEndOfQueue = false;
<> 144:ef7eb2e8f9f7 594 commandStruct.clearTransferCount = false;
<> 144:ef7eb2e8f9f7 595 commandStruct.whichCtar =
<> 144:ef7eb2e8f9f7 596 (dspi_ctar_selection_t)((transfer->configFlags & DSPI_MASTER_CTAR_MASK) >> DSPI_MASTER_CTAR_SHIFT);
<> 144:ef7eb2e8f9f7 597 commandStruct.isPcsContinuous = (bool)(transfer->configFlags & kDSPI_MasterPcsContinuous);
<> 144:ef7eb2e8f9f7 598
<> 144:ef7eb2e8f9f7 599 command = DSPI_MasterGetFormattedCommand(&(commandStruct));
<> 144:ef7eb2e8f9f7 600
<> 144:ef7eb2e8f9f7 601 commandStruct.isPcsContinuous = (bool)(transfer->configFlags & kDSPI_MasterActiveAfterTransfer);
<> 144:ef7eb2e8f9f7 602 lastCommand = DSPI_MasterGetFormattedCommand(&(commandStruct));
<> 144:ef7eb2e8f9f7 603
<> 144:ef7eb2e8f9f7 604 /*Calculate the bitsPerFrame*/
<> 144:ef7eb2e8f9f7 605 bitsPerFrame = ((base->CTAR[commandStruct.whichCtar] & SPI_CTAR_FMSZ_MASK) >> SPI_CTAR_FMSZ_SHIFT) + 1;
<> 144:ef7eb2e8f9f7 606
<> 144:ef7eb2e8f9f7 607 txData = transfer->txData;
<> 144:ef7eb2e8f9f7 608 rxData = transfer->rxData;
<> 144:ef7eb2e8f9f7 609 remainingSendByteCount = transfer->dataSize;
<> 144:ef7eb2e8f9f7 610 remainingReceiveByteCount = transfer->dataSize;
<> 144:ef7eb2e8f9f7 611
<> 144:ef7eb2e8f9f7 612 if ((base->MCR & SPI_MCR_DIS_RXF_MASK) || (base->MCR & SPI_MCR_DIS_TXF_MASK))
<> 144:ef7eb2e8f9f7 613 {
<> 144:ef7eb2e8f9f7 614 fifoSize = 1;
<> 144:ef7eb2e8f9f7 615 }
<> 144:ef7eb2e8f9f7 616 else
<> 144:ef7eb2e8f9f7 617 {
<> 144:ef7eb2e8f9f7 618 fifoSize = FSL_FEATURE_DSPI_FIFO_SIZEn(base);
<> 144:ef7eb2e8f9f7 619 }
<> 144:ef7eb2e8f9f7 620
<> 144:ef7eb2e8f9f7 621 DSPI_StartTransfer(base);
<> 144:ef7eb2e8f9f7 622
<> 144:ef7eb2e8f9f7 623 if (bitsPerFrame <= 8)
<> 144:ef7eb2e8f9f7 624 {
<> 144:ef7eb2e8f9f7 625 while (remainingSendByteCount > 0)
<> 144:ef7eb2e8f9f7 626 {
<> 144:ef7eb2e8f9f7 627 if (remainingSendByteCount == 1)
<> 144:ef7eb2e8f9f7 628 {
<> 144:ef7eb2e8f9f7 629 while ((remainingReceiveByteCount - remainingSendByteCount) >= fifoSize)
<> 144:ef7eb2e8f9f7 630 {
<> 144:ef7eb2e8f9f7 631 if (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag)
<> 144:ef7eb2e8f9f7 632 {
<> 144:ef7eb2e8f9f7 633 if (rxData != NULL)
<> 144:ef7eb2e8f9f7 634 {
<> 144:ef7eb2e8f9f7 635 *(rxData) = DSPI_ReadData(base);
<> 144:ef7eb2e8f9f7 636 rxData++;
<> 144:ef7eb2e8f9f7 637 }
<> 144:ef7eb2e8f9f7 638 else
<> 144:ef7eb2e8f9f7 639 {
<> 144:ef7eb2e8f9f7 640 DSPI_ReadData(base);
<> 144:ef7eb2e8f9f7 641 }
<> 144:ef7eb2e8f9f7 642 remainingReceiveByteCount--;
<> 144:ef7eb2e8f9f7 643
<> 144:ef7eb2e8f9f7 644 DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag);
<> 144:ef7eb2e8f9f7 645 }
<> 144:ef7eb2e8f9f7 646 }
<> 144:ef7eb2e8f9f7 647
<> 144:ef7eb2e8f9f7 648 while (!(DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag))
<> 144:ef7eb2e8f9f7 649 {
<> 144:ef7eb2e8f9f7 650 DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
<> 144:ef7eb2e8f9f7 651 }
<> 144:ef7eb2e8f9f7 652
<> 144:ef7eb2e8f9f7 653 if (txData != NULL)
<> 144:ef7eb2e8f9f7 654 {
<> 144:ef7eb2e8f9f7 655 base->PUSHR = (*txData) | (lastCommand);
<> 144:ef7eb2e8f9f7 656 txData++;
<> 144:ef7eb2e8f9f7 657 }
<> 144:ef7eb2e8f9f7 658 else
<> 144:ef7eb2e8f9f7 659 {
<> 144:ef7eb2e8f9f7 660 base->PUSHR = (lastCommand) | (dummyData);
<> 144:ef7eb2e8f9f7 661 }
<> 144:ef7eb2e8f9f7 662 DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
<> 144:ef7eb2e8f9f7 663 remainingSendByteCount--;
<> 144:ef7eb2e8f9f7 664
<> 144:ef7eb2e8f9f7 665 while (remainingReceiveByteCount > 0)
<> 144:ef7eb2e8f9f7 666 {
<> 144:ef7eb2e8f9f7 667 if (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag)
<> 144:ef7eb2e8f9f7 668 {
<> 144:ef7eb2e8f9f7 669 if (rxData != NULL)
<> 144:ef7eb2e8f9f7 670 {
<> 144:ef7eb2e8f9f7 671 /* Read data from POPR*/
<> 144:ef7eb2e8f9f7 672 *(rxData) = DSPI_ReadData(base);
<> 144:ef7eb2e8f9f7 673 rxData++;
<> 144:ef7eb2e8f9f7 674 }
<> 144:ef7eb2e8f9f7 675 else
<> 144:ef7eb2e8f9f7 676 {
<> 144:ef7eb2e8f9f7 677 DSPI_ReadData(base);
<> 144:ef7eb2e8f9f7 678 }
<> 144:ef7eb2e8f9f7 679 remainingReceiveByteCount--;
<> 144:ef7eb2e8f9f7 680
<> 144:ef7eb2e8f9f7 681 DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag);
<> 144:ef7eb2e8f9f7 682 }
<> 144:ef7eb2e8f9f7 683 }
<> 144:ef7eb2e8f9f7 684 }
<> 144:ef7eb2e8f9f7 685 else
<> 144:ef7eb2e8f9f7 686 {
<> 144:ef7eb2e8f9f7 687 /*Wait until Tx Fifo is not full*/
<> 144:ef7eb2e8f9f7 688 while (!(DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag))
<> 144:ef7eb2e8f9f7 689 {
<> 144:ef7eb2e8f9f7 690 DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
<> 144:ef7eb2e8f9f7 691 }
<> 144:ef7eb2e8f9f7 692 if (txData != NULL)
<> 144:ef7eb2e8f9f7 693 {
<> 144:ef7eb2e8f9f7 694 base->PUSHR = command | (uint16_t)(*txData);
<> 144:ef7eb2e8f9f7 695 txData++;
<> 144:ef7eb2e8f9f7 696 }
<> 144:ef7eb2e8f9f7 697 else
<> 144:ef7eb2e8f9f7 698 {
<> 144:ef7eb2e8f9f7 699 base->PUSHR = command | dummyData;
<> 144:ef7eb2e8f9f7 700 }
<> 144:ef7eb2e8f9f7 701 remainingSendByteCount--;
<> 144:ef7eb2e8f9f7 702
<> 144:ef7eb2e8f9f7 703 DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
<> 144:ef7eb2e8f9f7 704
<> 144:ef7eb2e8f9f7 705 if (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag)
<> 144:ef7eb2e8f9f7 706 {
<> 144:ef7eb2e8f9f7 707 if (rxData != NULL)
<> 144:ef7eb2e8f9f7 708 {
<> 144:ef7eb2e8f9f7 709 *(rxData) = DSPI_ReadData(base);
<> 144:ef7eb2e8f9f7 710 rxData++;
<> 144:ef7eb2e8f9f7 711 }
<> 144:ef7eb2e8f9f7 712 else
<> 144:ef7eb2e8f9f7 713 {
<> 144:ef7eb2e8f9f7 714 DSPI_ReadData(base);
<> 144:ef7eb2e8f9f7 715 }
<> 144:ef7eb2e8f9f7 716 remainingReceiveByteCount--;
<> 144:ef7eb2e8f9f7 717
<> 144:ef7eb2e8f9f7 718 DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag);
<> 144:ef7eb2e8f9f7 719 }
<> 144:ef7eb2e8f9f7 720 }
<> 144:ef7eb2e8f9f7 721 }
<> 144:ef7eb2e8f9f7 722 }
<> 144:ef7eb2e8f9f7 723 else
<> 144:ef7eb2e8f9f7 724 {
<> 144:ef7eb2e8f9f7 725 while (remainingSendByteCount > 0)
<> 144:ef7eb2e8f9f7 726 {
<> 144:ef7eb2e8f9f7 727 if (remainingSendByteCount <= 2)
<> 144:ef7eb2e8f9f7 728 {
<> 144:ef7eb2e8f9f7 729 while (((remainingReceiveByteCount - remainingSendByteCount) / 2) >= fifoSize)
<> 144:ef7eb2e8f9f7 730 {
<> 144:ef7eb2e8f9f7 731 if (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag)
<> 144:ef7eb2e8f9f7 732 {
<> 144:ef7eb2e8f9f7 733 wordReceived = DSPI_ReadData(base);
<> 144:ef7eb2e8f9f7 734
<> 144:ef7eb2e8f9f7 735 if (rxData != NULL)
<> 144:ef7eb2e8f9f7 736 {
<> 144:ef7eb2e8f9f7 737 *rxData = wordReceived;
<> 144:ef7eb2e8f9f7 738 ++rxData;
<> 144:ef7eb2e8f9f7 739 *rxData = wordReceived >> 8;
<> 144:ef7eb2e8f9f7 740 ++rxData;
<> 144:ef7eb2e8f9f7 741 }
<> 144:ef7eb2e8f9f7 742 remainingReceiveByteCount -= 2;
<> 144:ef7eb2e8f9f7 743
<> 144:ef7eb2e8f9f7 744 DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag);
<> 144:ef7eb2e8f9f7 745 }
<> 144:ef7eb2e8f9f7 746 }
<> 144:ef7eb2e8f9f7 747
<> 144:ef7eb2e8f9f7 748 while (!(DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag))
<> 144:ef7eb2e8f9f7 749 {
<> 144:ef7eb2e8f9f7 750 DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
<> 144:ef7eb2e8f9f7 751 }
<> 144:ef7eb2e8f9f7 752
<> 144:ef7eb2e8f9f7 753 if (txData != NULL)
<> 144:ef7eb2e8f9f7 754 {
<> 144:ef7eb2e8f9f7 755 wordToSend = *(txData);
<> 144:ef7eb2e8f9f7 756 ++txData;
<> 144:ef7eb2e8f9f7 757
<> 144:ef7eb2e8f9f7 758 if (remainingSendByteCount > 1)
<> 144:ef7eb2e8f9f7 759 {
<> 144:ef7eb2e8f9f7 760 wordToSend |= (unsigned)(*(txData)) << 8U;
<> 144:ef7eb2e8f9f7 761 ++txData;
<> 144:ef7eb2e8f9f7 762 }
<> 144:ef7eb2e8f9f7 763 }
<> 144:ef7eb2e8f9f7 764 else
<> 144:ef7eb2e8f9f7 765 {
<> 144:ef7eb2e8f9f7 766 wordToSend = dummyData;
<> 144:ef7eb2e8f9f7 767 }
<> 144:ef7eb2e8f9f7 768
<> 144:ef7eb2e8f9f7 769 base->PUSHR = lastCommand | wordToSend;
<> 144:ef7eb2e8f9f7 770
<> 144:ef7eb2e8f9f7 771 DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
<> 144:ef7eb2e8f9f7 772 remainingSendByteCount = 0;
<> 144:ef7eb2e8f9f7 773
<> 144:ef7eb2e8f9f7 774 while (remainingReceiveByteCount > 0)
<> 144:ef7eb2e8f9f7 775 {
<> 144:ef7eb2e8f9f7 776 if (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag)
<> 144:ef7eb2e8f9f7 777 {
<> 144:ef7eb2e8f9f7 778 wordReceived = DSPI_ReadData(base);
<> 144:ef7eb2e8f9f7 779
<> 144:ef7eb2e8f9f7 780 if (remainingReceiveByteCount != 1)
<> 144:ef7eb2e8f9f7 781 {
<> 144:ef7eb2e8f9f7 782 if (rxData != NULL)
<> 144:ef7eb2e8f9f7 783 {
<> 144:ef7eb2e8f9f7 784 *(rxData) = wordReceived;
<> 144:ef7eb2e8f9f7 785 ++rxData;
<> 144:ef7eb2e8f9f7 786 *(rxData) = wordReceived >> 8;
<> 144:ef7eb2e8f9f7 787 ++rxData;
<> 144:ef7eb2e8f9f7 788 }
<> 144:ef7eb2e8f9f7 789 remainingReceiveByteCount -= 2;
<> 144:ef7eb2e8f9f7 790 }
<> 144:ef7eb2e8f9f7 791 else
<> 144:ef7eb2e8f9f7 792 {
<> 144:ef7eb2e8f9f7 793 if (rxData != NULL)
<> 144:ef7eb2e8f9f7 794 {
<> 144:ef7eb2e8f9f7 795 *(rxData) = wordReceived;
<> 144:ef7eb2e8f9f7 796 ++rxData;
<> 144:ef7eb2e8f9f7 797 }
<> 144:ef7eb2e8f9f7 798 remainingReceiveByteCount--;
<> 144:ef7eb2e8f9f7 799 }
<> 144:ef7eb2e8f9f7 800 DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag);
<> 144:ef7eb2e8f9f7 801 }
<> 144:ef7eb2e8f9f7 802 }
<> 144:ef7eb2e8f9f7 803 }
<> 144:ef7eb2e8f9f7 804 else
<> 144:ef7eb2e8f9f7 805 {
<> 144:ef7eb2e8f9f7 806 /*Wait until Tx Fifo is not full*/
<> 144:ef7eb2e8f9f7 807 while (!(DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag))
<> 144:ef7eb2e8f9f7 808 {
<> 144:ef7eb2e8f9f7 809 DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
<> 144:ef7eb2e8f9f7 810 }
<> 144:ef7eb2e8f9f7 811
<> 144:ef7eb2e8f9f7 812 if (txData != NULL)
<> 144:ef7eb2e8f9f7 813 {
<> 144:ef7eb2e8f9f7 814 wordToSend = *(txData);
<> 144:ef7eb2e8f9f7 815 ++txData;
<> 144:ef7eb2e8f9f7 816 wordToSend |= (unsigned)(*(txData)) << 8U;
<> 144:ef7eb2e8f9f7 817 ++txData;
<> 144:ef7eb2e8f9f7 818 }
<> 144:ef7eb2e8f9f7 819 else
<> 144:ef7eb2e8f9f7 820 {
<> 144:ef7eb2e8f9f7 821 wordToSend = dummyData;
<> 144:ef7eb2e8f9f7 822 }
<> 144:ef7eb2e8f9f7 823 base->PUSHR = command | wordToSend;
<> 144:ef7eb2e8f9f7 824 remainingSendByteCount -= 2;
<> 144:ef7eb2e8f9f7 825
<> 144:ef7eb2e8f9f7 826 DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
<> 144:ef7eb2e8f9f7 827
<> 144:ef7eb2e8f9f7 828 if (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag)
<> 144:ef7eb2e8f9f7 829 {
<> 144:ef7eb2e8f9f7 830 wordReceived = DSPI_ReadData(base);
<> 144:ef7eb2e8f9f7 831
<> 144:ef7eb2e8f9f7 832 if (rxData != NULL)
<> 144:ef7eb2e8f9f7 833 {
<> 144:ef7eb2e8f9f7 834 *rxData = wordReceived;
<> 144:ef7eb2e8f9f7 835 ++rxData;
<> 144:ef7eb2e8f9f7 836 *rxData = wordReceived >> 8;
<> 144:ef7eb2e8f9f7 837 ++rxData;
<> 144:ef7eb2e8f9f7 838 }
<> 144:ef7eb2e8f9f7 839 remainingReceiveByteCount -= 2;
<> 144:ef7eb2e8f9f7 840
<> 144:ef7eb2e8f9f7 841 DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag);
<> 144:ef7eb2e8f9f7 842 }
<> 144:ef7eb2e8f9f7 843 }
<> 144:ef7eb2e8f9f7 844 }
<> 144:ef7eb2e8f9f7 845 }
<> 144:ef7eb2e8f9f7 846
<> 144:ef7eb2e8f9f7 847 return kStatus_Success;
<> 144:ef7eb2e8f9f7 848 }
<> 144:ef7eb2e8f9f7 849
<> 144:ef7eb2e8f9f7 850 static void DSPI_MasterTransferPrepare(SPI_Type *base, dspi_master_handle_t *handle, dspi_transfer_t *transfer)
<> 144:ef7eb2e8f9f7 851 {
<> 144:ef7eb2e8f9f7 852 dspi_command_data_config_t commandStruct;
<> 144:ef7eb2e8f9f7 853
<> 144:ef7eb2e8f9f7 854 DSPI_StopTransfer(base);
<> 144:ef7eb2e8f9f7 855 DSPI_FlushFifo(base, true, true);
<> 144:ef7eb2e8f9f7 856 DSPI_ClearStatusFlags(base, kDSPI_AllStatusFlag);
<> 144:ef7eb2e8f9f7 857
<> 144:ef7eb2e8f9f7 858 commandStruct.whichPcs =
<> 144:ef7eb2e8f9f7 859 (dspi_which_pcs_t)(1U << ((transfer->configFlags & DSPI_MASTER_PCS_MASK) >> DSPI_MASTER_PCS_SHIFT));
<> 144:ef7eb2e8f9f7 860 commandStruct.isEndOfQueue = false;
<> 144:ef7eb2e8f9f7 861 commandStruct.clearTransferCount = false;
<> 144:ef7eb2e8f9f7 862 commandStruct.whichCtar =
<> 144:ef7eb2e8f9f7 863 (dspi_ctar_selection_t)((transfer->configFlags & DSPI_MASTER_CTAR_MASK) >> DSPI_MASTER_CTAR_SHIFT);
<> 144:ef7eb2e8f9f7 864 commandStruct.isPcsContinuous = (bool)(transfer->configFlags & kDSPI_MasterPcsContinuous);
<> 144:ef7eb2e8f9f7 865 handle->command = DSPI_MasterGetFormattedCommand(&(commandStruct));
<> 144:ef7eb2e8f9f7 866
<> 144:ef7eb2e8f9f7 867 commandStruct.isPcsContinuous = (bool)(transfer->configFlags & kDSPI_MasterActiveAfterTransfer);
<> 144:ef7eb2e8f9f7 868 handle->lastCommand = DSPI_MasterGetFormattedCommand(&(commandStruct));
<> 144:ef7eb2e8f9f7 869
<> 144:ef7eb2e8f9f7 870 handle->bitsPerFrame = ((base->CTAR[commandStruct.whichCtar] & SPI_CTAR_FMSZ_MASK) >> SPI_CTAR_FMSZ_SHIFT) + 1;
<> 144:ef7eb2e8f9f7 871
<> 144:ef7eb2e8f9f7 872 if ((base->MCR & SPI_MCR_DIS_RXF_MASK) || (base->MCR & SPI_MCR_DIS_TXF_MASK))
<> 144:ef7eb2e8f9f7 873 {
<> 144:ef7eb2e8f9f7 874 handle->fifoSize = 1;
<> 144:ef7eb2e8f9f7 875 }
<> 144:ef7eb2e8f9f7 876 else
<> 144:ef7eb2e8f9f7 877 {
<> 144:ef7eb2e8f9f7 878 handle->fifoSize = FSL_FEATURE_DSPI_FIFO_SIZEn(base);
<> 144:ef7eb2e8f9f7 879 }
<> 144:ef7eb2e8f9f7 880 handle->txData = transfer->txData;
<> 144:ef7eb2e8f9f7 881 handle->rxData = transfer->rxData;
<> 144:ef7eb2e8f9f7 882 handle->remainingSendByteCount = transfer->dataSize;
<> 144:ef7eb2e8f9f7 883 handle->remainingReceiveByteCount = transfer->dataSize;
<> 144:ef7eb2e8f9f7 884 handle->totalByteCount = transfer->dataSize;
<> 144:ef7eb2e8f9f7 885 }
<> 144:ef7eb2e8f9f7 886
<> 144:ef7eb2e8f9f7 887 status_t DSPI_MasterTransferNonBlocking(SPI_Type *base, dspi_master_handle_t *handle, dspi_transfer_t *transfer)
<> 144:ef7eb2e8f9f7 888 {
<> 144:ef7eb2e8f9f7 889 assert(handle && transfer);
<> 144:ef7eb2e8f9f7 890
<> 144:ef7eb2e8f9f7 891 /* If the transfer count is zero, then return immediately.*/
<> 144:ef7eb2e8f9f7 892 if (transfer->dataSize == 0)
<> 144:ef7eb2e8f9f7 893 {
<> 144:ef7eb2e8f9f7 894 return kStatus_InvalidArgument;
<> 144:ef7eb2e8f9f7 895 }
<> 144:ef7eb2e8f9f7 896
<> 144:ef7eb2e8f9f7 897 /* Check that we're not busy.*/
<> 144:ef7eb2e8f9f7 898 if (handle->state == kDSPI_Busy)
<> 144:ef7eb2e8f9f7 899 {
<> 144:ef7eb2e8f9f7 900 return kStatus_DSPI_Busy;
<> 144:ef7eb2e8f9f7 901 }
<> 144:ef7eb2e8f9f7 902
<> 144:ef7eb2e8f9f7 903 handle->state = kDSPI_Busy;
<> 144:ef7eb2e8f9f7 904
<> 144:ef7eb2e8f9f7 905 DSPI_MasterTransferPrepare(base, handle, transfer);
<> 144:ef7eb2e8f9f7 906 DSPI_StartTransfer(base);
<> 144:ef7eb2e8f9f7 907
<> 144:ef7eb2e8f9f7 908 /* Enable the NVIC for DSPI peripheral. */
<> 144:ef7eb2e8f9f7 909 EnableIRQ(s_dspiIRQ[DSPI_GetInstance(base)]);
<> 144:ef7eb2e8f9f7 910
<> 144:ef7eb2e8f9f7 911 DSPI_MasterTransferFillUpTxFifo(base, handle);
<> 144:ef7eb2e8f9f7 912
<> 144:ef7eb2e8f9f7 913 /* RX FIFO Drain request: RFDF_RE to enable RFDF interrupt
<> 144:ef7eb2e8f9f7 914 * Since SPI is a synchronous interface, we only need to enable the RX interrupt.
<> 144:ef7eb2e8f9f7 915 * The IRQ handler will get the status of RX and TX interrupt flags.
<> 144:ef7eb2e8f9f7 916 */
<> 144:ef7eb2e8f9f7 917 s_dspiMasterIsr = DSPI_MasterTransferHandleIRQ;
<> 144:ef7eb2e8f9f7 918
<> 144:ef7eb2e8f9f7 919 DSPI_EnableInterrupts(base, kDSPI_RxFifoDrainRequestInterruptEnable);
<> 144:ef7eb2e8f9f7 920
<> 144:ef7eb2e8f9f7 921 return kStatus_Success;
<> 144:ef7eb2e8f9f7 922 }
<> 144:ef7eb2e8f9f7 923
<> 144:ef7eb2e8f9f7 924 status_t DSPI_MasterTransferGetCount(SPI_Type *base, dspi_master_handle_t *handle, size_t *count)
<> 144:ef7eb2e8f9f7 925 {
<> 144:ef7eb2e8f9f7 926 assert(handle);
<> 144:ef7eb2e8f9f7 927
<> 144:ef7eb2e8f9f7 928 if (!count)
<> 144:ef7eb2e8f9f7 929 {
<> 144:ef7eb2e8f9f7 930 return kStatus_InvalidArgument;
<> 144:ef7eb2e8f9f7 931 }
<> 144:ef7eb2e8f9f7 932
<> 144:ef7eb2e8f9f7 933 /* Catch when there is not an active transfer. */
<> 144:ef7eb2e8f9f7 934 if (handle->state != kDSPI_Busy)
<> 144:ef7eb2e8f9f7 935 {
<> 144:ef7eb2e8f9f7 936 *count = 0;
<> 144:ef7eb2e8f9f7 937 return kStatus_NoTransferInProgress;
<> 144:ef7eb2e8f9f7 938 }
<> 144:ef7eb2e8f9f7 939
<> 144:ef7eb2e8f9f7 940 *count = handle->totalByteCount - handle->remainingReceiveByteCount;
<> 144:ef7eb2e8f9f7 941 return kStatus_Success;
<> 144:ef7eb2e8f9f7 942 }
<> 144:ef7eb2e8f9f7 943
<> 144:ef7eb2e8f9f7 944 static void DSPI_MasterTransferComplete(SPI_Type *base, dspi_master_handle_t *handle)
<> 144:ef7eb2e8f9f7 945 {
<> 144:ef7eb2e8f9f7 946 /* Disable interrupt requests*/
<> 144:ef7eb2e8f9f7 947 DSPI_DisableInterrupts(base, kDSPI_RxFifoDrainRequestInterruptEnable | kDSPI_TxFifoFillRequestInterruptEnable);
<> 144:ef7eb2e8f9f7 948
<> 144:ef7eb2e8f9f7 949 status_t status = 0;
<> 144:ef7eb2e8f9f7 950 if (handle->state == kDSPI_Error)
<> 144:ef7eb2e8f9f7 951 {
<> 144:ef7eb2e8f9f7 952 status = kStatus_DSPI_Error;
<> 144:ef7eb2e8f9f7 953 }
<> 144:ef7eb2e8f9f7 954 else
<> 144:ef7eb2e8f9f7 955 {
<> 144:ef7eb2e8f9f7 956 status = kStatus_Success;
<> 144:ef7eb2e8f9f7 957 }
<> 144:ef7eb2e8f9f7 958
<> 144:ef7eb2e8f9f7 959 if (handle->callback)
<> 144:ef7eb2e8f9f7 960 {
<> 144:ef7eb2e8f9f7 961 handle->callback(base, handle, status, handle->userData);
<> 144:ef7eb2e8f9f7 962 }
<> 144:ef7eb2e8f9f7 963
<> 144:ef7eb2e8f9f7 964 /* The transfer is complete.*/
<> 144:ef7eb2e8f9f7 965 handle->state = kDSPI_Idle;
<> 144:ef7eb2e8f9f7 966 }
<> 144:ef7eb2e8f9f7 967
<> 144:ef7eb2e8f9f7 968 static void DSPI_MasterTransferFillUpTxFifo(SPI_Type *base, dspi_master_handle_t *handle)
<> 144:ef7eb2e8f9f7 969 {
<> 144:ef7eb2e8f9f7 970 uint16_t wordToSend = 0;
<> 144:ef7eb2e8f9f7 971 uint8_t dummyData = DSPI_MASTER_DUMMY_DATA;
<> 144:ef7eb2e8f9f7 972
<> 144:ef7eb2e8f9f7 973 /* If bits/frame is greater than one byte */
<> 144:ef7eb2e8f9f7 974 if (handle->bitsPerFrame > 8)
<> 144:ef7eb2e8f9f7 975 {
<> 144:ef7eb2e8f9f7 976 /* Fill the fifo until it is full or until the send word count is 0 or until the difference
<> 144:ef7eb2e8f9f7 977 * between the remainingReceiveByteCount and remainingSendByteCount equals the FIFO depth.
<> 144:ef7eb2e8f9f7 978 * The reason for checking the difference is to ensure we only send as much as the
<> 144:ef7eb2e8f9f7 979 * RX FIFO can receive.
<> 144:ef7eb2e8f9f7 980 * For this case where bitsPerFrame > 8, each entry in the FIFO contains 2 bytes of the
<> 144:ef7eb2e8f9f7 981 * send data, hence the difference between the remainingReceiveByteCount and
<> 144:ef7eb2e8f9f7 982 * remainingSendByteCount must be divided by 2 to convert this difference into a
<> 144:ef7eb2e8f9f7 983 * 16-bit (2 byte) value.
<> 144:ef7eb2e8f9f7 984 */
<> 144:ef7eb2e8f9f7 985 while ((DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag) &&
<> 144:ef7eb2e8f9f7 986 ((handle->remainingReceiveByteCount - handle->remainingSendByteCount) / 2 < handle->fifoSize))
<> 144:ef7eb2e8f9f7 987 {
<> 144:ef7eb2e8f9f7 988 if (handle->remainingSendByteCount <= 2)
<> 144:ef7eb2e8f9f7 989 {
<> 144:ef7eb2e8f9f7 990 if (handle->txData)
<> 144:ef7eb2e8f9f7 991 {
<> 144:ef7eb2e8f9f7 992 if (handle->remainingSendByteCount == 1)
<> 144:ef7eb2e8f9f7 993 {
<> 144:ef7eb2e8f9f7 994 wordToSend = *(handle->txData);
<> 144:ef7eb2e8f9f7 995 }
<> 144:ef7eb2e8f9f7 996 else
<> 144:ef7eb2e8f9f7 997 {
<> 144:ef7eb2e8f9f7 998 wordToSend = *(handle->txData);
<> 144:ef7eb2e8f9f7 999 ++handle->txData; /* increment to next data byte */
<> 144:ef7eb2e8f9f7 1000 wordToSend |= (unsigned)(*(handle->txData)) << 8U;
<> 144:ef7eb2e8f9f7 1001 }
<> 144:ef7eb2e8f9f7 1002 }
<> 144:ef7eb2e8f9f7 1003 else
<> 144:ef7eb2e8f9f7 1004 {
<> 144:ef7eb2e8f9f7 1005 wordToSend = dummyData;
<> 144:ef7eb2e8f9f7 1006 }
<> 144:ef7eb2e8f9f7 1007 handle->remainingSendByteCount = 0;
<> 144:ef7eb2e8f9f7 1008 base->PUSHR = handle->lastCommand | wordToSend;
<> 144:ef7eb2e8f9f7 1009 }
<> 144:ef7eb2e8f9f7 1010 /* For all words except the last word */
<> 144:ef7eb2e8f9f7 1011 else
<> 144:ef7eb2e8f9f7 1012 {
<> 144:ef7eb2e8f9f7 1013 if (handle->txData)
<> 144:ef7eb2e8f9f7 1014 {
<> 144:ef7eb2e8f9f7 1015 wordToSend = *(handle->txData);
<> 144:ef7eb2e8f9f7 1016 ++handle->txData; /* increment to next data byte */
<> 144:ef7eb2e8f9f7 1017 wordToSend |= (unsigned)(*(handle->txData)) << 8U;
<> 144:ef7eb2e8f9f7 1018 ++handle->txData; /* increment to next data byte */
<> 144:ef7eb2e8f9f7 1019 }
<> 144:ef7eb2e8f9f7 1020 else
<> 144:ef7eb2e8f9f7 1021 {
<> 144:ef7eb2e8f9f7 1022 wordToSend = dummyData;
<> 144:ef7eb2e8f9f7 1023 }
<> 144:ef7eb2e8f9f7 1024 handle->remainingSendByteCount -= 2; /* decrement remainingSendByteCount by 2 */
<> 144:ef7eb2e8f9f7 1025 base->PUSHR = handle->command | wordToSend;
<> 144:ef7eb2e8f9f7 1026 }
<> 144:ef7eb2e8f9f7 1027
<> 144:ef7eb2e8f9f7 1028 /* Try to clear the TFFF; if the TX FIFO is full this will clear */
<> 144:ef7eb2e8f9f7 1029 DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
<> 144:ef7eb2e8f9f7 1030
<> 144:ef7eb2e8f9f7 1031 /* exit loop if send count is zero, else update local variables for next loop */
<> 144:ef7eb2e8f9f7 1032 if (handle->remainingSendByteCount == 0)
<> 144:ef7eb2e8f9f7 1033 {
<> 144:ef7eb2e8f9f7 1034 break;
<> 144:ef7eb2e8f9f7 1035 }
<> 144:ef7eb2e8f9f7 1036 } /* End of TX FIFO fill while loop */
<> 144:ef7eb2e8f9f7 1037 }
<> 144:ef7eb2e8f9f7 1038 /* Optimized for bits/frame less than or equal to one byte. */
<> 144:ef7eb2e8f9f7 1039 else
<> 144:ef7eb2e8f9f7 1040 {
<> 144:ef7eb2e8f9f7 1041 /* Fill the fifo until it is full or until the send word count is 0 or until the difference
<> 144:ef7eb2e8f9f7 1042 * between the remainingReceiveByteCount and remainingSendByteCount equals the FIFO depth.
<> 144:ef7eb2e8f9f7 1043 * The reason for checking the difference is to ensure we only send as much as the
<> 144:ef7eb2e8f9f7 1044 * RX FIFO can receive.
<> 144:ef7eb2e8f9f7 1045 */
<> 144:ef7eb2e8f9f7 1046 while ((DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag) &&
<> 144:ef7eb2e8f9f7 1047 ((handle->remainingReceiveByteCount - handle->remainingSendByteCount) < handle->fifoSize))
<> 144:ef7eb2e8f9f7 1048 {
<> 144:ef7eb2e8f9f7 1049 if (handle->txData)
<> 144:ef7eb2e8f9f7 1050 {
<> 144:ef7eb2e8f9f7 1051 wordToSend = *(handle->txData);
<> 144:ef7eb2e8f9f7 1052 ++handle->txData;
<> 144:ef7eb2e8f9f7 1053 }
<> 144:ef7eb2e8f9f7 1054 else
<> 144:ef7eb2e8f9f7 1055 {
<> 144:ef7eb2e8f9f7 1056 wordToSend = dummyData;
<> 144:ef7eb2e8f9f7 1057 }
<> 144:ef7eb2e8f9f7 1058
<> 144:ef7eb2e8f9f7 1059 if (handle->remainingSendByteCount == 1)
<> 144:ef7eb2e8f9f7 1060 {
<> 144:ef7eb2e8f9f7 1061 base->PUSHR = handle->lastCommand | wordToSend;
<> 144:ef7eb2e8f9f7 1062 }
<> 144:ef7eb2e8f9f7 1063 else
<> 144:ef7eb2e8f9f7 1064 {
<> 144:ef7eb2e8f9f7 1065 base->PUSHR = handle->command | wordToSend;
<> 144:ef7eb2e8f9f7 1066 }
<> 144:ef7eb2e8f9f7 1067
<> 144:ef7eb2e8f9f7 1068 /* Try to clear the TFFF; if the TX FIFO is full this will clear */
<> 144:ef7eb2e8f9f7 1069 DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
<> 144:ef7eb2e8f9f7 1070
<> 144:ef7eb2e8f9f7 1071 --handle->remainingSendByteCount;
<> 144:ef7eb2e8f9f7 1072
<> 144:ef7eb2e8f9f7 1073 /* exit loop if send count is zero, else update local variables for next loop */
<> 144:ef7eb2e8f9f7 1074 if (handle->remainingSendByteCount == 0)
<> 144:ef7eb2e8f9f7 1075 {
<> 144:ef7eb2e8f9f7 1076 break;
<> 144:ef7eb2e8f9f7 1077 }
<> 144:ef7eb2e8f9f7 1078 }
<> 144:ef7eb2e8f9f7 1079 }
<> 144:ef7eb2e8f9f7 1080 }
<> 144:ef7eb2e8f9f7 1081
<> 144:ef7eb2e8f9f7 1082 void DSPI_MasterTransferAbort(SPI_Type *base, dspi_master_handle_t *handle)
<> 144:ef7eb2e8f9f7 1083 {
<> 144:ef7eb2e8f9f7 1084 DSPI_StopTransfer(base);
<> 144:ef7eb2e8f9f7 1085
<> 144:ef7eb2e8f9f7 1086 /* Disable interrupt requests*/
<> 144:ef7eb2e8f9f7 1087 DSPI_DisableInterrupts(base, kDSPI_RxFifoDrainRequestInterruptEnable | kDSPI_TxFifoFillRequestInterruptEnable);
<> 144:ef7eb2e8f9f7 1088
<> 144:ef7eb2e8f9f7 1089 handle->state = kDSPI_Idle;
<> 144:ef7eb2e8f9f7 1090 }
<> 144:ef7eb2e8f9f7 1091
<> 144:ef7eb2e8f9f7 1092 void DSPI_MasterTransferHandleIRQ(SPI_Type *base, dspi_master_handle_t *handle)
<> 144:ef7eb2e8f9f7 1093 {
<> 144:ef7eb2e8f9f7 1094 /* RECEIVE IRQ handler: Check read buffer only if there are remaining bytes to read. */
<> 144:ef7eb2e8f9f7 1095 if (handle->remainingReceiveByteCount)
<> 144:ef7eb2e8f9f7 1096 {
<> 144:ef7eb2e8f9f7 1097 /* Check read buffer.*/
<> 144:ef7eb2e8f9f7 1098 uint16_t wordReceived; /* Maximum supported data bit length in master mode is 16-bits */
<> 144:ef7eb2e8f9f7 1099
<> 144:ef7eb2e8f9f7 1100 /* If bits/frame is greater than one byte */
<> 144:ef7eb2e8f9f7 1101 if (handle->bitsPerFrame > 8)
<> 144:ef7eb2e8f9f7 1102 {
<> 144:ef7eb2e8f9f7 1103 while (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag)
<> 144:ef7eb2e8f9f7 1104 {
<> 144:ef7eb2e8f9f7 1105 wordReceived = DSPI_ReadData(base);
<> 144:ef7eb2e8f9f7 1106 /* clear the rx fifo drain request, needed for non-DMA applications as this flag
<> 144:ef7eb2e8f9f7 1107 * will remain set even if the rx fifo is empty. By manually clearing this flag, it
<> 144:ef7eb2e8f9f7 1108 * either remain clear if no more data is in the fifo, or it will set if there is
<> 144:ef7eb2e8f9f7 1109 * more data in the fifo.
<> 144:ef7eb2e8f9f7 1110 */
<> 144:ef7eb2e8f9f7 1111 DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag);
<> 144:ef7eb2e8f9f7 1112
<> 144:ef7eb2e8f9f7 1113 /* Store read bytes into rx buffer only if a buffer pointer was provided */
<> 144:ef7eb2e8f9f7 1114 if (handle->rxData)
<> 144:ef7eb2e8f9f7 1115 {
<> 144:ef7eb2e8f9f7 1116 /* For the last word received, if there is an extra byte due to the odd transfer
<> 144:ef7eb2e8f9f7 1117 * byte count, only save the the last byte and discard the upper byte
<> 144:ef7eb2e8f9f7 1118 */
<> 144:ef7eb2e8f9f7 1119 if (handle->remainingReceiveByteCount == 1)
<> 144:ef7eb2e8f9f7 1120 {
<> 144:ef7eb2e8f9f7 1121 *handle->rxData = wordReceived; /* Write first data byte */
<> 144:ef7eb2e8f9f7 1122 --handle->remainingReceiveByteCount;
<> 144:ef7eb2e8f9f7 1123 }
<> 144:ef7eb2e8f9f7 1124 else
<> 144:ef7eb2e8f9f7 1125 {
<> 144:ef7eb2e8f9f7 1126 *handle->rxData = wordReceived; /* Write first data byte */
<> 144:ef7eb2e8f9f7 1127 ++handle->rxData; /* increment to next data byte */
<> 144:ef7eb2e8f9f7 1128 *handle->rxData = wordReceived >> 8; /* Write second data byte */
<> 144:ef7eb2e8f9f7 1129 ++handle->rxData; /* increment to next data byte */
<> 144:ef7eb2e8f9f7 1130 handle->remainingReceiveByteCount -= 2;
<> 144:ef7eb2e8f9f7 1131 }
<> 144:ef7eb2e8f9f7 1132 }
<> 144:ef7eb2e8f9f7 1133 else
<> 144:ef7eb2e8f9f7 1134 {
<> 144:ef7eb2e8f9f7 1135 if (handle->remainingReceiveByteCount == 1)
<> 144:ef7eb2e8f9f7 1136 {
<> 144:ef7eb2e8f9f7 1137 --handle->remainingReceiveByteCount;
<> 144:ef7eb2e8f9f7 1138 }
<> 144:ef7eb2e8f9f7 1139 else
<> 144:ef7eb2e8f9f7 1140 {
<> 144:ef7eb2e8f9f7 1141 handle->remainingReceiveByteCount -= 2;
<> 144:ef7eb2e8f9f7 1142 }
<> 144:ef7eb2e8f9f7 1143 }
<> 144:ef7eb2e8f9f7 1144 if (handle->remainingReceiveByteCount == 0)
<> 144:ef7eb2e8f9f7 1145 {
<> 144:ef7eb2e8f9f7 1146 break;
<> 144:ef7eb2e8f9f7 1147 }
<> 144:ef7eb2e8f9f7 1148 } /* End of RX FIFO drain while loop */
<> 144:ef7eb2e8f9f7 1149 }
<> 144:ef7eb2e8f9f7 1150 /* Optimized for bits/frame less than or equal to one byte. */
<> 144:ef7eb2e8f9f7 1151 else
<> 144:ef7eb2e8f9f7 1152 {
<> 144:ef7eb2e8f9f7 1153 while (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag)
<> 144:ef7eb2e8f9f7 1154 {
<> 144:ef7eb2e8f9f7 1155 wordReceived = DSPI_ReadData(base);
<> 144:ef7eb2e8f9f7 1156 /* clear the rx fifo drain request, needed for non-DMA applications as this flag
<> 144:ef7eb2e8f9f7 1157 * will remain set even if the rx fifo is empty. By manually clearing this flag, it
<> 144:ef7eb2e8f9f7 1158 * either remain clear if no more data is in the fifo, or it will set if there is
<> 144:ef7eb2e8f9f7 1159 * more data in the fifo.
<> 144:ef7eb2e8f9f7 1160 */
<> 144:ef7eb2e8f9f7 1161 DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag);
<> 144:ef7eb2e8f9f7 1162
<> 144:ef7eb2e8f9f7 1163 /* Store read bytes into rx buffer only if a buffer pointer was provided */
<> 144:ef7eb2e8f9f7 1164 if (handle->rxData)
<> 144:ef7eb2e8f9f7 1165 {
<> 144:ef7eb2e8f9f7 1166 *handle->rxData = wordReceived;
<> 144:ef7eb2e8f9f7 1167 ++handle->rxData;
<> 144:ef7eb2e8f9f7 1168 }
<> 144:ef7eb2e8f9f7 1169
<> 144:ef7eb2e8f9f7 1170 --handle->remainingReceiveByteCount;
<> 144:ef7eb2e8f9f7 1171
<> 144:ef7eb2e8f9f7 1172 if (handle->remainingReceiveByteCount == 0)
<> 144:ef7eb2e8f9f7 1173 {
<> 144:ef7eb2e8f9f7 1174 break;
<> 144:ef7eb2e8f9f7 1175 }
<> 144:ef7eb2e8f9f7 1176 } /* End of RX FIFO drain while loop */
<> 144:ef7eb2e8f9f7 1177 }
<> 144:ef7eb2e8f9f7 1178 }
<> 144:ef7eb2e8f9f7 1179
<> 144:ef7eb2e8f9f7 1180 /* Check write buffer. We always have to send a word in order to keep the transfer
<> 144:ef7eb2e8f9f7 1181 * moving. So if the caller didn't provide a send buffer, we just send a zero.
<> 144:ef7eb2e8f9f7 1182 */
<> 144:ef7eb2e8f9f7 1183 if (handle->remainingSendByteCount)
<> 144:ef7eb2e8f9f7 1184 {
<> 144:ef7eb2e8f9f7 1185 DSPI_MasterTransferFillUpTxFifo(base, handle);
<> 144:ef7eb2e8f9f7 1186 }
<> 144:ef7eb2e8f9f7 1187
<> 144:ef7eb2e8f9f7 1188 /* Check if we're done with this transfer.*/
<> 144:ef7eb2e8f9f7 1189 if ((handle->remainingSendByteCount == 0) && (handle->remainingReceiveByteCount == 0))
<> 144:ef7eb2e8f9f7 1190 {
<> 144:ef7eb2e8f9f7 1191 /* Complete the transfer and disable the interrupts */
<> 144:ef7eb2e8f9f7 1192 DSPI_MasterTransferComplete(base, handle);
<> 144:ef7eb2e8f9f7 1193 }
<> 144:ef7eb2e8f9f7 1194 }
<> 144:ef7eb2e8f9f7 1195
<> 144:ef7eb2e8f9f7 1196 /*Transactional APIs -- Slave*/
<> 144:ef7eb2e8f9f7 1197 void DSPI_SlaveTransferCreateHandle(SPI_Type *base,
<> 144:ef7eb2e8f9f7 1198 dspi_slave_handle_t *handle,
<> 144:ef7eb2e8f9f7 1199 dspi_slave_transfer_callback_t callback,
<> 144:ef7eb2e8f9f7 1200 void *userData)
<> 144:ef7eb2e8f9f7 1201 {
<> 144:ef7eb2e8f9f7 1202 assert(handle);
<> 144:ef7eb2e8f9f7 1203
<> 144:ef7eb2e8f9f7 1204 /* Zero the handle. */
<> 144:ef7eb2e8f9f7 1205 memset(handle, 0, sizeof(*handle));
<> 144:ef7eb2e8f9f7 1206
<> 144:ef7eb2e8f9f7 1207 g_dspiHandle[DSPI_GetInstance(base)] = handle;
<> 144:ef7eb2e8f9f7 1208
<> 144:ef7eb2e8f9f7 1209 handle->callback = callback;
<> 144:ef7eb2e8f9f7 1210 handle->userData = userData;
<> 144:ef7eb2e8f9f7 1211 }
<> 144:ef7eb2e8f9f7 1212
<> 144:ef7eb2e8f9f7 1213 status_t DSPI_SlaveTransferNonBlocking(SPI_Type *base, dspi_slave_handle_t *handle, dspi_transfer_t *transfer)
<> 144:ef7eb2e8f9f7 1214 {
<> 144:ef7eb2e8f9f7 1215 assert(handle && transfer);
<> 144:ef7eb2e8f9f7 1216
<> 144:ef7eb2e8f9f7 1217 /* If receive length is zero */
<> 144:ef7eb2e8f9f7 1218 if (transfer->dataSize == 0)
<> 144:ef7eb2e8f9f7 1219 {
<> 144:ef7eb2e8f9f7 1220 return kStatus_InvalidArgument;
<> 144:ef7eb2e8f9f7 1221 }
<> 144:ef7eb2e8f9f7 1222
<> 144:ef7eb2e8f9f7 1223 /* If both send buffer and receive buffer is null */
<> 144:ef7eb2e8f9f7 1224 if ((!(transfer->txData)) && (!(transfer->rxData)))
<> 144:ef7eb2e8f9f7 1225 {
<> 144:ef7eb2e8f9f7 1226 return kStatus_InvalidArgument;
<> 144:ef7eb2e8f9f7 1227 }
<> 144:ef7eb2e8f9f7 1228
<> 144:ef7eb2e8f9f7 1229 /* Check that we're not busy.*/
<> 144:ef7eb2e8f9f7 1230 if (handle->state == kDSPI_Busy)
<> 144:ef7eb2e8f9f7 1231 {
<> 144:ef7eb2e8f9f7 1232 return kStatus_DSPI_Busy;
<> 144:ef7eb2e8f9f7 1233 }
<> 144:ef7eb2e8f9f7 1234 handle->state = kDSPI_Busy;
<> 144:ef7eb2e8f9f7 1235
<> 144:ef7eb2e8f9f7 1236 /* Enable the NVIC for DSPI peripheral. */
<> 144:ef7eb2e8f9f7 1237 EnableIRQ(s_dspiIRQ[DSPI_GetInstance(base)]);
<> 144:ef7eb2e8f9f7 1238
<> 144:ef7eb2e8f9f7 1239 /* Store transfer information */
<> 144:ef7eb2e8f9f7 1240 handle->txData = transfer->txData;
<> 144:ef7eb2e8f9f7 1241 handle->rxData = transfer->rxData;
<> 144:ef7eb2e8f9f7 1242 handle->remainingSendByteCount = transfer->dataSize;
<> 144:ef7eb2e8f9f7 1243 handle->remainingReceiveByteCount = transfer->dataSize;
<> 144:ef7eb2e8f9f7 1244 handle->totalByteCount = transfer->dataSize;
<> 144:ef7eb2e8f9f7 1245
<> 144:ef7eb2e8f9f7 1246 handle->errorCount = 0;
<> 144:ef7eb2e8f9f7 1247
<> 144:ef7eb2e8f9f7 1248 uint8_t whichCtar = (transfer->configFlags & DSPI_SLAVE_CTAR_MASK) >> DSPI_SLAVE_CTAR_SHIFT;
<> 144:ef7eb2e8f9f7 1249 handle->bitsPerFrame =
<> 144:ef7eb2e8f9f7 1250 (((base->CTAR_SLAVE[whichCtar]) & SPI_CTAR_SLAVE_FMSZ_MASK) >> SPI_CTAR_SLAVE_FMSZ_SHIFT) + 1;
<> 144:ef7eb2e8f9f7 1251
<> 144:ef7eb2e8f9f7 1252 DSPI_StopTransfer(base);
<> 144:ef7eb2e8f9f7 1253
<> 144:ef7eb2e8f9f7 1254 DSPI_FlushFifo(base, true, true);
<> 144:ef7eb2e8f9f7 1255 DSPI_ClearStatusFlags(base, kDSPI_AllStatusFlag);
<> 144:ef7eb2e8f9f7 1256
<> 144:ef7eb2e8f9f7 1257 DSPI_StartTransfer(base);
<> 144:ef7eb2e8f9f7 1258
<> 144:ef7eb2e8f9f7 1259 /* Prepare data to transmit */
<> 144:ef7eb2e8f9f7 1260 DSPI_SlaveTransferFillUpTxFifo(base, handle);
<> 144:ef7eb2e8f9f7 1261
<> 144:ef7eb2e8f9f7 1262 s_dspiSlaveIsr = DSPI_SlaveTransferHandleIRQ;
<> 144:ef7eb2e8f9f7 1263
<> 144:ef7eb2e8f9f7 1264 /* Enable RX FIFO drain request, the slave only use this interrupt */
<> 144:ef7eb2e8f9f7 1265 DSPI_EnableInterrupts(base, kDSPI_RxFifoDrainRequestInterruptEnable);
<> 144:ef7eb2e8f9f7 1266
<> 144:ef7eb2e8f9f7 1267 if (handle->rxData)
<> 144:ef7eb2e8f9f7 1268 {
<> 144:ef7eb2e8f9f7 1269 /* RX FIFO overflow request enable */
<> 144:ef7eb2e8f9f7 1270 DSPI_EnableInterrupts(base, kDSPI_RxFifoOverflowInterruptEnable);
<> 144:ef7eb2e8f9f7 1271 }
<> 144:ef7eb2e8f9f7 1272 if (handle->txData)
<> 144:ef7eb2e8f9f7 1273 {
<> 144:ef7eb2e8f9f7 1274 /* TX FIFO underflow request enable */
<> 144:ef7eb2e8f9f7 1275 DSPI_EnableInterrupts(base, kDSPI_TxFifoUnderflowInterruptEnable);
<> 144:ef7eb2e8f9f7 1276 }
<> 144:ef7eb2e8f9f7 1277
<> 144:ef7eb2e8f9f7 1278 return kStatus_Success;
<> 144:ef7eb2e8f9f7 1279 }
<> 144:ef7eb2e8f9f7 1280
<> 144:ef7eb2e8f9f7 1281 status_t DSPI_SlaveTransferGetCount(SPI_Type *base, dspi_slave_handle_t *handle, size_t *count)
<> 144:ef7eb2e8f9f7 1282 {
<> 144:ef7eb2e8f9f7 1283 assert(handle);
<> 144:ef7eb2e8f9f7 1284
<> 144:ef7eb2e8f9f7 1285 if (!count)
<> 144:ef7eb2e8f9f7 1286 {
<> 144:ef7eb2e8f9f7 1287 return kStatus_InvalidArgument;
<> 144:ef7eb2e8f9f7 1288 }
<> 144:ef7eb2e8f9f7 1289
<> 144:ef7eb2e8f9f7 1290 /* Catch when there is not an active transfer. */
<> 144:ef7eb2e8f9f7 1291 if (handle->state != kDSPI_Busy)
<> 144:ef7eb2e8f9f7 1292 {
<> 144:ef7eb2e8f9f7 1293 *count = 0;
<> 144:ef7eb2e8f9f7 1294 return kStatus_NoTransferInProgress;
<> 144:ef7eb2e8f9f7 1295 }
<> 144:ef7eb2e8f9f7 1296
<> 144:ef7eb2e8f9f7 1297 *count = handle->totalByteCount - handle->remainingReceiveByteCount;
<> 144:ef7eb2e8f9f7 1298 return kStatus_Success;
<> 144:ef7eb2e8f9f7 1299 }
<> 144:ef7eb2e8f9f7 1300
<> 144:ef7eb2e8f9f7 1301 static void DSPI_SlaveTransferFillUpTxFifo(SPI_Type *base, dspi_slave_handle_t *handle)
<> 144:ef7eb2e8f9f7 1302 {
<> 144:ef7eb2e8f9f7 1303 uint16_t transmitData = 0;
<> 144:ef7eb2e8f9f7 1304 uint8_t dummyPattern = DSPI_SLAVE_DUMMY_DATA;
<> 144:ef7eb2e8f9f7 1305
<> 144:ef7eb2e8f9f7 1306 /* Service the transmitter, if transmit buffer provided, transmit the data,
<> 144:ef7eb2e8f9f7 1307 * else transmit dummy pattern
<> 144:ef7eb2e8f9f7 1308 */
<> 144:ef7eb2e8f9f7 1309 while (DSPI_GetStatusFlags(base) & kDSPI_TxFifoFillRequestFlag)
<> 144:ef7eb2e8f9f7 1310 {
<> 144:ef7eb2e8f9f7 1311 /* Transmit data */
<> 144:ef7eb2e8f9f7 1312 if (handle->remainingSendByteCount > 0)
<> 144:ef7eb2e8f9f7 1313 {
<> 144:ef7eb2e8f9f7 1314 /* Have data to transmit, update the transmit data and push to FIFO */
<> 144:ef7eb2e8f9f7 1315 if (handle->bitsPerFrame <= 8)
<> 144:ef7eb2e8f9f7 1316 {
<> 144:ef7eb2e8f9f7 1317 /* bits/frame is 1 byte */
<> 144:ef7eb2e8f9f7 1318 if (handle->txData)
<> 144:ef7eb2e8f9f7 1319 {
<> 144:ef7eb2e8f9f7 1320 /* Update transmit data and transmit pointer */
<> 144:ef7eb2e8f9f7 1321 transmitData = *handle->txData;
<> 144:ef7eb2e8f9f7 1322 handle->txData++;
<> 144:ef7eb2e8f9f7 1323 }
<> 144:ef7eb2e8f9f7 1324 else
<> 144:ef7eb2e8f9f7 1325 {
<> 144:ef7eb2e8f9f7 1326 transmitData = dummyPattern;
<> 144:ef7eb2e8f9f7 1327 }
<> 144:ef7eb2e8f9f7 1328
<> 144:ef7eb2e8f9f7 1329 /* Decrease remaining dataSize */
<> 144:ef7eb2e8f9f7 1330 --handle->remainingSendByteCount;
<> 144:ef7eb2e8f9f7 1331 }
<> 144:ef7eb2e8f9f7 1332 /* bits/frame is 2 bytes */
<> 144:ef7eb2e8f9f7 1333 else
<> 144:ef7eb2e8f9f7 1334 {
<> 144:ef7eb2e8f9f7 1335 /* With multibytes per frame transmission, the transmit frame contains data from
<> 144:ef7eb2e8f9f7 1336 * transmit buffer until sent dataSize matches user request. Other bytes will set to
<> 144:ef7eb2e8f9f7 1337 * dummy pattern value.
<> 144:ef7eb2e8f9f7 1338 */
<> 144:ef7eb2e8f9f7 1339 if (handle->txData)
<> 144:ef7eb2e8f9f7 1340 {
<> 144:ef7eb2e8f9f7 1341 /* Update first byte of transmit data and transmit pointer */
<> 144:ef7eb2e8f9f7 1342 transmitData = *handle->txData;
<> 144:ef7eb2e8f9f7 1343 handle->txData++;
<> 144:ef7eb2e8f9f7 1344
<> 144:ef7eb2e8f9f7 1345 if (handle->remainingSendByteCount == 1)
<> 144:ef7eb2e8f9f7 1346 {
<> 144:ef7eb2e8f9f7 1347 /* Decrease remaining dataSize */
<> 144:ef7eb2e8f9f7 1348 --handle->remainingSendByteCount;
<> 144:ef7eb2e8f9f7 1349 /* Update second byte of transmit data to second byte of dummy pattern */
<> 144:ef7eb2e8f9f7 1350 transmitData = transmitData | (uint16_t)(((uint16_t)dummyPattern) << 8);
<> 144:ef7eb2e8f9f7 1351 }
<> 144:ef7eb2e8f9f7 1352 else
<> 144:ef7eb2e8f9f7 1353 {
<> 144:ef7eb2e8f9f7 1354 /* Update second byte of transmit data and transmit pointer */
<> 144:ef7eb2e8f9f7 1355 transmitData = transmitData | (uint16_t)((uint16_t)(*handle->txData) << 8);
<> 144:ef7eb2e8f9f7 1356 handle->txData++;
<> 144:ef7eb2e8f9f7 1357 handle->remainingSendByteCount -= 2;
<> 144:ef7eb2e8f9f7 1358 }
<> 144:ef7eb2e8f9f7 1359 }
<> 144:ef7eb2e8f9f7 1360 else
<> 144:ef7eb2e8f9f7 1361 {
<> 144:ef7eb2e8f9f7 1362 if (handle->remainingSendByteCount == 1)
<> 144:ef7eb2e8f9f7 1363 {
<> 144:ef7eb2e8f9f7 1364 --handle->remainingSendByteCount;
<> 144:ef7eb2e8f9f7 1365 }
<> 144:ef7eb2e8f9f7 1366 else
<> 144:ef7eb2e8f9f7 1367 {
<> 144:ef7eb2e8f9f7 1368 handle->remainingSendByteCount -= 2;
<> 144:ef7eb2e8f9f7 1369 }
<> 144:ef7eb2e8f9f7 1370 transmitData = (uint16_t)((uint16_t)(dummyPattern) << 8) | dummyPattern;
<> 144:ef7eb2e8f9f7 1371 }
<> 144:ef7eb2e8f9f7 1372 }
<> 144:ef7eb2e8f9f7 1373 }
<> 144:ef7eb2e8f9f7 1374 else
<> 144:ef7eb2e8f9f7 1375 {
<> 144:ef7eb2e8f9f7 1376 break;
<> 144:ef7eb2e8f9f7 1377 }
<> 144:ef7eb2e8f9f7 1378
<> 144:ef7eb2e8f9f7 1379 /* Write the data to the DSPI data register */
<> 144:ef7eb2e8f9f7 1380 base->PUSHR_SLAVE = transmitData;
<> 144:ef7eb2e8f9f7 1381
<> 144:ef7eb2e8f9f7 1382 /* Try to clear TFFF by writing a one to it; it will not clear if TX FIFO not full */
<> 144:ef7eb2e8f9f7 1383 DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
<> 144:ef7eb2e8f9f7 1384 }
<> 144:ef7eb2e8f9f7 1385 }
<> 144:ef7eb2e8f9f7 1386
<> 144:ef7eb2e8f9f7 1387 static void DSPI_SlaveTransferComplete(SPI_Type *base, dspi_slave_handle_t *handle)
<> 144:ef7eb2e8f9f7 1388 {
<> 144:ef7eb2e8f9f7 1389 /* Disable interrupt requests */
<> 144:ef7eb2e8f9f7 1390 DSPI_DisableInterrupts(base, kDSPI_TxFifoUnderflowInterruptEnable | kDSPI_TxFifoFillRequestInterruptEnable |
<> 144:ef7eb2e8f9f7 1391 kDSPI_RxFifoOverflowInterruptEnable | kDSPI_RxFifoDrainRequestInterruptEnable);
<> 144:ef7eb2e8f9f7 1392
<> 144:ef7eb2e8f9f7 1393 /* The transfer is complete. */
<> 144:ef7eb2e8f9f7 1394 handle->txData = NULL;
<> 144:ef7eb2e8f9f7 1395 handle->rxData = NULL;
<> 144:ef7eb2e8f9f7 1396 handle->remainingReceiveByteCount = 0;
<> 144:ef7eb2e8f9f7 1397 handle->remainingSendByteCount = 0;
<> 144:ef7eb2e8f9f7 1398
<> 144:ef7eb2e8f9f7 1399 status_t status = 0;
<> 144:ef7eb2e8f9f7 1400 if (handle->state == kDSPI_Error)
<> 144:ef7eb2e8f9f7 1401 {
<> 144:ef7eb2e8f9f7 1402 status = kStatus_DSPI_Error;
<> 144:ef7eb2e8f9f7 1403 }
<> 144:ef7eb2e8f9f7 1404 else
<> 144:ef7eb2e8f9f7 1405 {
<> 144:ef7eb2e8f9f7 1406 status = kStatus_Success;
<> 144:ef7eb2e8f9f7 1407 }
<> 144:ef7eb2e8f9f7 1408
<> 144:ef7eb2e8f9f7 1409 if (handle->callback)
<> 144:ef7eb2e8f9f7 1410 {
<> 144:ef7eb2e8f9f7 1411 handle->callback(base, handle, status, handle->userData);
<> 144:ef7eb2e8f9f7 1412 }
<> 144:ef7eb2e8f9f7 1413
<> 144:ef7eb2e8f9f7 1414 handle->state = kDSPI_Idle;
<> 144:ef7eb2e8f9f7 1415 }
<> 144:ef7eb2e8f9f7 1416
<> 144:ef7eb2e8f9f7 1417 void DSPI_SlaveTransferAbort(SPI_Type *base, dspi_slave_handle_t *handle)
<> 144:ef7eb2e8f9f7 1418 {
<> 144:ef7eb2e8f9f7 1419 DSPI_StopTransfer(base);
<> 144:ef7eb2e8f9f7 1420
<> 144:ef7eb2e8f9f7 1421 /* Disable interrupt requests */
<> 144:ef7eb2e8f9f7 1422 DSPI_DisableInterrupts(base, kDSPI_TxFifoUnderflowInterruptEnable | kDSPI_TxFifoFillRequestInterruptEnable |
<> 144:ef7eb2e8f9f7 1423 kDSPI_RxFifoOverflowInterruptEnable | kDSPI_RxFifoDrainRequestInterruptEnable);
<> 144:ef7eb2e8f9f7 1424
<> 144:ef7eb2e8f9f7 1425 handle->state = kDSPI_Idle;
<> 144:ef7eb2e8f9f7 1426 handle->remainingSendByteCount = 0;
<> 144:ef7eb2e8f9f7 1427 handle->remainingReceiveByteCount = 0;
<> 144:ef7eb2e8f9f7 1428 }
<> 144:ef7eb2e8f9f7 1429
<> 144:ef7eb2e8f9f7 1430 void DSPI_SlaveTransferHandleIRQ(SPI_Type *base, dspi_slave_handle_t *handle)
<> 144:ef7eb2e8f9f7 1431 {
<> 144:ef7eb2e8f9f7 1432 uint8_t dummyPattern = DSPI_SLAVE_DUMMY_DATA;
<> 144:ef7eb2e8f9f7 1433 uint32_t dataReceived;
<> 144:ef7eb2e8f9f7 1434 uint32_t dataSend = 0;
<> 144:ef7eb2e8f9f7 1435
<> 144:ef7eb2e8f9f7 1436 /* Because SPI protocol is synchronous, the number of bytes that that slave received from the
<> 144:ef7eb2e8f9f7 1437 * master is the actual number of bytes that the slave transmitted to the master. So we only
<> 144:ef7eb2e8f9f7 1438 * monitor the received dataSize to know when the transfer is complete.
<> 144:ef7eb2e8f9f7 1439 */
<> 144:ef7eb2e8f9f7 1440 if (handle->remainingReceiveByteCount > 0)
<> 144:ef7eb2e8f9f7 1441 {
<> 144:ef7eb2e8f9f7 1442 while (DSPI_GetStatusFlags(base) & kDSPI_RxFifoDrainRequestFlag)
<> 144:ef7eb2e8f9f7 1443 {
<> 144:ef7eb2e8f9f7 1444 /* Have received data in the buffer. */
<> 144:ef7eb2e8f9f7 1445 dataReceived = base->POPR;
<> 144:ef7eb2e8f9f7 1446 /*Clear the rx fifo drain request, needed for non-DMA applications as this flag
<> 144:ef7eb2e8f9f7 1447 * will remain set even if the rx fifo is empty. By manually clearing this flag, it
<> 144:ef7eb2e8f9f7 1448 * either remain clear if no more data is in the fifo, or it will set if there is
<> 144:ef7eb2e8f9f7 1449 * more data in the fifo.
<> 144:ef7eb2e8f9f7 1450 */
<> 144:ef7eb2e8f9f7 1451 DSPI_ClearStatusFlags(base, kDSPI_RxFifoDrainRequestFlag);
<> 144:ef7eb2e8f9f7 1452
<> 144:ef7eb2e8f9f7 1453 /* If bits/frame is one byte */
<> 144:ef7eb2e8f9f7 1454 if (handle->bitsPerFrame <= 8)
<> 144:ef7eb2e8f9f7 1455 {
<> 144:ef7eb2e8f9f7 1456 if (handle->rxData)
<> 144:ef7eb2e8f9f7 1457 {
<> 144:ef7eb2e8f9f7 1458 /* Receive buffer is not null, store data into it */
<> 144:ef7eb2e8f9f7 1459 *handle->rxData = dataReceived;
<> 144:ef7eb2e8f9f7 1460 ++handle->rxData;
<> 144:ef7eb2e8f9f7 1461 }
<> 144:ef7eb2e8f9f7 1462 /* Descrease remaining receive byte count */
<> 144:ef7eb2e8f9f7 1463 --handle->remainingReceiveByteCount;
<> 144:ef7eb2e8f9f7 1464
<> 144:ef7eb2e8f9f7 1465 if (handle->remainingSendByteCount > 0)
<> 144:ef7eb2e8f9f7 1466 {
<> 144:ef7eb2e8f9f7 1467 if (handle->txData)
<> 144:ef7eb2e8f9f7 1468 {
<> 144:ef7eb2e8f9f7 1469 dataSend = *handle->txData;
<> 144:ef7eb2e8f9f7 1470 ++handle->txData;
<> 144:ef7eb2e8f9f7 1471 }
<> 144:ef7eb2e8f9f7 1472 else
<> 144:ef7eb2e8f9f7 1473 {
<> 144:ef7eb2e8f9f7 1474 dataSend = dummyPattern;
<> 144:ef7eb2e8f9f7 1475 }
<> 144:ef7eb2e8f9f7 1476
<> 144:ef7eb2e8f9f7 1477 --handle->remainingSendByteCount;
<> 144:ef7eb2e8f9f7 1478 /* Write the data to the DSPI data register */
<> 144:ef7eb2e8f9f7 1479 base->PUSHR_SLAVE = dataSend;
<> 144:ef7eb2e8f9f7 1480 }
<> 144:ef7eb2e8f9f7 1481 }
<> 144:ef7eb2e8f9f7 1482 else /* If bits/frame is 2 bytes */
<> 144:ef7eb2e8f9f7 1483 {
<> 144:ef7eb2e8f9f7 1484 /* With multibytes frame receiving, we only receive till the received dataSize
<> 144:ef7eb2e8f9f7 1485 * matches user request. Other bytes will be ignored.
<> 144:ef7eb2e8f9f7 1486 */
<> 144:ef7eb2e8f9f7 1487 if (handle->rxData)
<> 144:ef7eb2e8f9f7 1488 {
<> 144:ef7eb2e8f9f7 1489 /* Receive buffer is not null, store first byte into it */
<> 144:ef7eb2e8f9f7 1490 *handle->rxData = dataReceived;
<> 144:ef7eb2e8f9f7 1491 ++handle->rxData;
<> 144:ef7eb2e8f9f7 1492
<> 144:ef7eb2e8f9f7 1493 if (handle->remainingReceiveByteCount == 1)
<> 144:ef7eb2e8f9f7 1494 {
<> 144:ef7eb2e8f9f7 1495 /* Decrease remaining receive byte count */
<> 144:ef7eb2e8f9f7 1496 --handle->remainingReceiveByteCount;
<> 144:ef7eb2e8f9f7 1497 }
<> 144:ef7eb2e8f9f7 1498 else
<> 144:ef7eb2e8f9f7 1499 {
<> 144:ef7eb2e8f9f7 1500 /* Receive buffer is not null, store second byte into it */
<> 144:ef7eb2e8f9f7 1501 *handle->rxData = dataReceived >> 8;
<> 144:ef7eb2e8f9f7 1502 ++handle->rxData;
<> 144:ef7eb2e8f9f7 1503 handle->remainingReceiveByteCount -= 2;
<> 144:ef7eb2e8f9f7 1504 }
<> 144:ef7eb2e8f9f7 1505 }
<> 144:ef7eb2e8f9f7 1506 /* If no handle->rxData*/
<> 144:ef7eb2e8f9f7 1507 else
<> 144:ef7eb2e8f9f7 1508 {
<> 144:ef7eb2e8f9f7 1509 if (handle->remainingReceiveByteCount == 1)
<> 144:ef7eb2e8f9f7 1510 {
<> 144:ef7eb2e8f9f7 1511 /* Decrease remaining receive byte count */
<> 144:ef7eb2e8f9f7 1512 --handle->remainingReceiveByteCount;
<> 144:ef7eb2e8f9f7 1513 }
<> 144:ef7eb2e8f9f7 1514 else
<> 144:ef7eb2e8f9f7 1515 {
<> 144:ef7eb2e8f9f7 1516 handle->remainingReceiveByteCount -= 2;
<> 144:ef7eb2e8f9f7 1517 }
<> 144:ef7eb2e8f9f7 1518 }
<> 144:ef7eb2e8f9f7 1519
<> 144:ef7eb2e8f9f7 1520 if (handle->remainingSendByteCount > 0)
<> 144:ef7eb2e8f9f7 1521 {
<> 144:ef7eb2e8f9f7 1522 if (handle->txData)
<> 144:ef7eb2e8f9f7 1523 {
<> 144:ef7eb2e8f9f7 1524 dataSend = *handle->txData;
<> 144:ef7eb2e8f9f7 1525 ++handle->txData;
<> 144:ef7eb2e8f9f7 1526
<> 144:ef7eb2e8f9f7 1527 if (handle->remainingSendByteCount == 1)
<> 144:ef7eb2e8f9f7 1528 {
<> 144:ef7eb2e8f9f7 1529 --handle->remainingSendByteCount;
<> 144:ef7eb2e8f9f7 1530 dataSend |= (uint16_t)((uint16_t)(dummyPattern) << 8);
<> 144:ef7eb2e8f9f7 1531 }
<> 144:ef7eb2e8f9f7 1532 else
<> 144:ef7eb2e8f9f7 1533 {
<> 144:ef7eb2e8f9f7 1534 dataSend |= (uint32_t)(*handle->txData) << 8;
<> 144:ef7eb2e8f9f7 1535 ++handle->txData;
<> 144:ef7eb2e8f9f7 1536 handle->remainingSendByteCount -= 2;
<> 144:ef7eb2e8f9f7 1537 }
<> 144:ef7eb2e8f9f7 1538 }
<> 144:ef7eb2e8f9f7 1539 /* If no handle->txData*/
<> 144:ef7eb2e8f9f7 1540 else
<> 144:ef7eb2e8f9f7 1541 {
<> 144:ef7eb2e8f9f7 1542 if (handle->remainingSendByteCount == 1)
<> 144:ef7eb2e8f9f7 1543 {
<> 144:ef7eb2e8f9f7 1544 --handle->remainingSendByteCount;
<> 144:ef7eb2e8f9f7 1545 }
<> 144:ef7eb2e8f9f7 1546 else
<> 144:ef7eb2e8f9f7 1547 {
<> 144:ef7eb2e8f9f7 1548 handle->remainingSendByteCount -= 2;
<> 144:ef7eb2e8f9f7 1549 }
<> 144:ef7eb2e8f9f7 1550 dataSend = (uint16_t)((uint16_t)(dummyPattern) << 8) | dummyPattern;
<> 144:ef7eb2e8f9f7 1551 }
<> 144:ef7eb2e8f9f7 1552 /* Write the data to the DSPI data register */
<> 144:ef7eb2e8f9f7 1553 base->PUSHR_SLAVE = dataSend;
<> 144:ef7eb2e8f9f7 1554 }
<> 144:ef7eb2e8f9f7 1555 }
<> 144:ef7eb2e8f9f7 1556 /* Try to clear TFFF by writing a one to it; it will not clear if TX FIFO not full */
<> 144:ef7eb2e8f9f7 1557 DSPI_ClearStatusFlags(base, kDSPI_TxFifoFillRequestFlag);
<> 144:ef7eb2e8f9f7 1558
<> 144:ef7eb2e8f9f7 1559 if (handle->remainingReceiveByteCount == 0)
<> 144:ef7eb2e8f9f7 1560 {
<> 144:ef7eb2e8f9f7 1561 break;
<> 144:ef7eb2e8f9f7 1562 }
<> 144:ef7eb2e8f9f7 1563 }
<> 144:ef7eb2e8f9f7 1564 }
<> 144:ef7eb2e8f9f7 1565 /* Check if remaining receive byte count matches user request */
<> 144:ef7eb2e8f9f7 1566 if ((handle->remainingReceiveByteCount == 0) || (handle->state == kDSPI_Error))
<> 144:ef7eb2e8f9f7 1567 {
<> 144:ef7eb2e8f9f7 1568 /* Other cases, stop the transfer. */
<> 144:ef7eb2e8f9f7 1569 DSPI_SlaveTransferComplete(base, handle);
<> 144:ef7eb2e8f9f7 1570 return;
<> 144:ef7eb2e8f9f7 1571 }
<> 144:ef7eb2e8f9f7 1572
<> 144:ef7eb2e8f9f7 1573 /* Catch tx fifo underflow conditions, service only if tx under flow interrupt enabled */
<> 144:ef7eb2e8f9f7 1574 if ((DSPI_GetStatusFlags(base) & kDSPI_TxFifoUnderflowFlag) && (base->RSER & SPI_RSER_TFUF_RE_MASK))
<> 144:ef7eb2e8f9f7 1575 {
<> 144:ef7eb2e8f9f7 1576 DSPI_ClearStatusFlags(base, kDSPI_TxFifoUnderflowFlag);
<> 144:ef7eb2e8f9f7 1577 /* Change state to error and clear flag */
<> 144:ef7eb2e8f9f7 1578 if (handle->txData)
<> 144:ef7eb2e8f9f7 1579 {
<> 144:ef7eb2e8f9f7 1580 handle->state = kDSPI_Error;
<> 144:ef7eb2e8f9f7 1581 }
<> 144:ef7eb2e8f9f7 1582 handle->errorCount++;
<> 144:ef7eb2e8f9f7 1583 }
<> 144:ef7eb2e8f9f7 1584 /* Catch rx fifo overflow conditions, service only if rx over flow interrupt enabled */
<> 144:ef7eb2e8f9f7 1585 if ((DSPI_GetStatusFlags(base) & kDSPI_RxFifoOverflowFlag) && (base->RSER & SPI_RSER_RFOF_RE_MASK))
<> 144:ef7eb2e8f9f7 1586 {
<> 144:ef7eb2e8f9f7 1587 DSPI_ClearStatusFlags(base, kDSPI_RxFifoOverflowFlag);
<> 144:ef7eb2e8f9f7 1588 /* Change state to error and clear flag */
<> 144:ef7eb2e8f9f7 1589 if (handle->txData)
<> 144:ef7eb2e8f9f7 1590 {
<> 144:ef7eb2e8f9f7 1591 handle->state = kDSPI_Error;
<> 144:ef7eb2e8f9f7 1592 }
<> 144:ef7eb2e8f9f7 1593 handle->errorCount++;
<> 144:ef7eb2e8f9f7 1594 }
<> 144:ef7eb2e8f9f7 1595 }
<> 144:ef7eb2e8f9f7 1596
<> 144:ef7eb2e8f9f7 1597 static void DSPI_CommonIRQHandler(SPI_Type *base, void *param)
<> 144:ef7eb2e8f9f7 1598 {
<> 144:ef7eb2e8f9f7 1599 if (DSPI_IsMaster(base))
<> 144:ef7eb2e8f9f7 1600 {
<> 144:ef7eb2e8f9f7 1601 s_dspiMasterIsr(base, (dspi_master_handle_t *)param);
<> 144:ef7eb2e8f9f7 1602 }
<> 144:ef7eb2e8f9f7 1603 else
<> 144:ef7eb2e8f9f7 1604 {
<> 144:ef7eb2e8f9f7 1605 s_dspiSlaveIsr(base, (dspi_slave_handle_t *)param);
<> 144:ef7eb2e8f9f7 1606 }
<> 144:ef7eb2e8f9f7 1607 }
<> 144:ef7eb2e8f9f7 1608
<> 144:ef7eb2e8f9f7 1609 #if defined(SPI0)
<> 144:ef7eb2e8f9f7 1610 void SPI0_DriverIRQHandler(void)
<> 144:ef7eb2e8f9f7 1611 {
<> 144:ef7eb2e8f9f7 1612 assert(g_dspiHandle[0]);
<> 144:ef7eb2e8f9f7 1613 DSPI_CommonIRQHandler(SPI0, g_dspiHandle[0]);
<> 144:ef7eb2e8f9f7 1614 }
<> 144:ef7eb2e8f9f7 1615 #endif
<> 144:ef7eb2e8f9f7 1616
<> 144:ef7eb2e8f9f7 1617 #if defined(SPI1)
<> 144:ef7eb2e8f9f7 1618 void SPI1_DriverIRQHandler(void)
<> 144:ef7eb2e8f9f7 1619 {
<> 144:ef7eb2e8f9f7 1620 assert(g_dspiHandle[1]);
<> 144:ef7eb2e8f9f7 1621 DSPI_CommonIRQHandler(SPI1, g_dspiHandle[1]);
<> 144:ef7eb2e8f9f7 1622 }
<> 144:ef7eb2e8f9f7 1623 #endif
<> 144:ef7eb2e8f9f7 1624
<> 144:ef7eb2e8f9f7 1625 #if defined(SPI2)
<> 144:ef7eb2e8f9f7 1626 void SPI2_DriverIRQHandler(void)
<> 144:ef7eb2e8f9f7 1627 {
<> 144:ef7eb2e8f9f7 1628 assert(g_dspiHandle[2]);
<> 144:ef7eb2e8f9f7 1629 DSPI_CommonIRQHandler(SPI2, g_dspiHandle[2]);
<> 144:ef7eb2e8f9f7 1630 }
<> 144:ef7eb2e8f9f7 1631 #endif
<> 144:ef7eb2e8f9f7 1632
<> 144:ef7eb2e8f9f7 1633 #if defined(SPI3)
<> 144:ef7eb2e8f9f7 1634 void SPI3_DriverIRQHandler(void)
<> 144:ef7eb2e8f9f7 1635 {
<> 144:ef7eb2e8f9f7 1636 assert(g_dspiHandle[3]);
<> 144:ef7eb2e8f9f7 1637 DSPI_CommonIRQHandler(SPI3, g_dspiHandle[3]);
<> 144:ef7eb2e8f9f7 1638 }
<> 144:ef7eb2e8f9f7 1639 #endif
<> 144:ef7eb2e8f9f7 1640
<> 144:ef7eb2e8f9f7 1641 #if defined(SPI4)
<> 144:ef7eb2e8f9f7 1642 void SPI4_DriverIRQHandler(void)
<> 144:ef7eb2e8f9f7 1643 {
<> 144:ef7eb2e8f9f7 1644 assert(g_dspiHandle[4]);
<> 144:ef7eb2e8f9f7 1645 DSPI_CommonIRQHandler(SPI4, g_dspiHandle[4]);
<> 144:ef7eb2e8f9f7 1646 }
<> 144:ef7eb2e8f9f7 1647 #endif
<> 144:ef7eb2e8f9f7 1648
<> 144:ef7eb2e8f9f7 1649 #if defined(SPI5)
<> 144:ef7eb2e8f9f7 1650 void SPI5_DriverIRQHandler(void)
<> 144:ef7eb2e8f9f7 1651 {
<> 144:ef7eb2e8f9f7 1652 assert(g_dspiHandle[5]);
<> 144:ef7eb2e8f9f7 1653 DSPI_CommonIRQHandler(SPI5, g_dspiHandle[5]);
<> 144:ef7eb2e8f9f7 1654 }
<> 144:ef7eb2e8f9f7 1655 #endif
<> 144:ef7eb2e8f9f7 1656
<> 144:ef7eb2e8f9f7 1657 #if (FSL_FEATURE_SOC_DSPI_COUNT > 6)
<> 144:ef7eb2e8f9f7 1658 #error "Should write the SPIx_DriverIRQHandler function that instance greater than 5 !"
<> 144:ef7eb2e8f9f7 1659 #endif