Color Oled(SSD1331) connect to STMicroelectronics Nucleo-F466

Dependencies:   ssd1331

Committer:
kadonotakashi
Date:
Thu Oct 11 02:27:46 2018 +0000
Revision:
3:f3764f852aa8
Parent:
0:8fdf9a60065b
Nucreo 446 + SSD1331 test version;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kadonotakashi 0:8fdf9a60065b 1 /*
kadonotakashi 0:8fdf9a60065b 2 * Copyright (c) 2015, Freescale Semiconductor, Inc.
kadonotakashi 0:8fdf9a60065b 3 * All rights reserved.
kadonotakashi 0:8fdf9a60065b 4 *
kadonotakashi 0:8fdf9a60065b 5 * Redistribution and use in source and binary forms, with or without modification,
kadonotakashi 0:8fdf9a60065b 6 * are permitted provided that the following conditions are met:
kadonotakashi 0:8fdf9a60065b 7 *
kadonotakashi 0:8fdf9a60065b 8 * o Redistributions of source code must retain the above copyright notice, this list
kadonotakashi 0:8fdf9a60065b 9 * of conditions and the following disclaimer.
kadonotakashi 0:8fdf9a60065b 10 *
kadonotakashi 0:8fdf9a60065b 11 * o Redistributions in binary form must reproduce the above copyright notice, this
kadonotakashi 0:8fdf9a60065b 12 * list of conditions and the following disclaimer in the documentation and/or
kadonotakashi 0:8fdf9a60065b 13 * other materials provided with the distribution.
kadonotakashi 0:8fdf9a60065b 14 *
kadonotakashi 0:8fdf9a60065b 15 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
kadonotakashi 0:8fdf9a60065b 16 * contributors may be used to endorse or promote products derived from this
kadonotakashi 0:8fdf9a60065b 17 * software without specific prior written permission.
kadonotakashi 0:8fdf9a60065b 18 *
kadonotakashi 0:8fdf9a60065b 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
kadonotakashi 0:8fdf9a60065b 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
kadonotakashi 0:8fdf9a60065b 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
kadonotakashi 0:8fdf9a60065b 22 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
kadonotakashi 0:8fdf9a60065b 23 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
kadonotakashi 0:8fdf9a60065b 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
kadonotakashi 0:8fdf9a60065b 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
kadonotakashi 0:8fdf9a60065b 26 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
kadonotakashi 0:8fdf9a60065b 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
kadonotakashi 0:8fdf9a60065b 28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
kadonotakashi 0:8fdf9a60065b 29 */
kadonotakashi 0:8fdf9a60065b 30
kadonotakashi 0:8fdf9a60065b 31 #include "fsl_spi.h"
kadonotakashi 0:8fdf9a60065b 32
kadonotakashi 0:8fdf9a60065b 33 /*******************************************************************************
kadonotakashi 0:8fdf9a60065b 34 * Definitons
kadonotakashi 0:8fdf9a60065b 35 ******************************************************************************/
kadonotakashi 0:8fdf9a60065b 36 /*! @brief SPI transfer state, which is used for SPI transactiaonl APIs' internal state. */
kadonotakashi 0:8fdf9a60065b 37 enum _spi_transfer_states_t
kadonotakashi 0:8fdf9a60065b 38 {
kadonotakashi 0:8fdf9a60065b 39 kSPI_Idle = 0x0, /*!< SPI is idle state */
kadonotakashi 0:8fdf9a60065b 40 kSPI_Busy /*!< SPI is busy tranferring data. */
kadonotakashi 0:8fdf9a60065b 41 };
kadonotakashi 0:8fdf9a60065b 42
kadonotakashi 0:8fdf9a60065b 43 /*! @brief Typedef for spi master interrupt handler. spi master and slave handle is the same. */
kadonotakashi 0:8fdf9a60065b 44 typedef void (*spi_isr_t)(SPI_Type *base, spi_master_handle_t *spiHandle);
kadonotakashi 0:8fdf9a60065b 45
kadonotakashi 0:8fdf9a60065b 46 /*******************************************************************************
kadonotakashi 0:8fdf9a60065b 47 * Prototypes
kadonotakashi 0:8fdf9a60065b 48 ******************************************************************************/
kadonotakashi 0:8fdf9a60065b 49 /*!
kadonotakashi 0:8fdf9a60065b 50 * @brief Get the instance for SPI module.
kadonotakashi 0:8fdf9a60065b 51 *
kadonotakashi 0:8fdf9a60065b 52 * @param base SPI base address
kadonotakashi 0:8fdf9a60065b 53 */
kadonotakashi 0:8fdf9a60065b 54 uint32_t SPI_GetInstance(SPI_Type *base);
kadonotakashi 0:8fdf9a60065b 55
kadonotakashi 0:8fdf9a60065b 56 /*!
kadonotakashi 0:8fdf9a60065b 57 * @brief Sends a buffer of data bytes in non-blocking way.
kadonotakashi 0:8fdf9a60065b 58 *
kadonotakashi 0:8fdf9a60065b 59 * @param base SPI base pointer
kadonotakashi 0:8fdf9a60065b 60 * @param buffer The data bytes to send
kadonotakashi 0:8fdf9a60065b 61 * @param size The number of data bytes to send
kadonotakashi 0:8fdf9a60065b 62 */
kadonotakashi 0:8fdf9a60065b 63 static void SPI_WriteNonBlocking(SPI_Type *base, uint8_t *buffer, size_t size);
kadonotakashi 0:8fdf9a60065b 64
kadonotakashi 0:8fdf9a60065b 65 /*!
kadonotakashi 0:8fdf9a60065b 66 * @brief Receive a buffer of data bytes in non-blocking way.
kadonotakashi 0:8fdf9a60065b 67 *
kadonotakashi 0:8fdf9a60065b 68 * @param base SPI base pointer
kadonotakashi 0:8fdf9a60065b 69 * @param buffer The data bytes to send
kadonotakashi 0:8fdf9a60065b 70 * @param size The number of data bytes to send
kadonotakashi 0:8fdf9a60065b 71 */
kadonotakashi 0:8fdf9a60065b 72 static void SPI_ReadNonBlocking(SPI_Type *base, uint8_t *buffer, size_t size);
kadonotakashi 0:8fdf9a60065b 73
kadonotakashi 0:8fdf9a60065b 74 /*!
kadonotakashi 0:8fdf9a60065b 75 * @brief Send a piece of data for SPI.
kadonotakashi 0:8fdf9a60065b 76 *
kadonotakashi 0:8fdf9a60065b 77 * This function computes the number of data to be written into D register or Tx FIFO,
kadonotakashi 0:8fdf9a60065b 78 * and write the data into it. At the same time, this function updates the values in
kadonotakashi 0:8fdf9a60065b 79 * master handle structure.
kadonotakashi 0:8fdf9a60065b 80 *
kadonotakashi 0:8fdf9a60065b 81 * @param handle Pointer to SPI master handle structure.
kadonotakashi 0:8fdf9a60065b 82 */
kadonotakashi 0:8fdf9a60065b 83 static void SPI_SendTransfer(SPI_Type *base, spi_master_handle_t *handle);
kadonotakashi 0:8fdf9a60065b 84
kadonotakashi 0:8fdf9a60065b 85 /*!
kadonotakashi 0:8fdf9a60065b 86 * @brief Receive a piece of data for SPI master.
kadonotakashi 0:8fdf9a60065b 87 *
kadonotakashi 0:8fdf9a60065b 88 * This function computes the number of data to receive from D register or Rx FIFO,
kadonotakashi 0:8fdf9a60065b 89 * and write the data to destination address. At the same time, this function updates
kadonotakashi 0:8fdf9a60065b 90 * the values in master handle structure.
kadonotakashi 0:8fdf9a60065b 91 *
kadonotakashi 0:8fdf9a60065b 92 * @param handle Pointer to SPI master handle structure.
kadonotakashi 0:8fdf9a60065b 93 */
kadonotakashi 0:8fdf9a60065b 94 static void SPI_ReceiveTransfer(SPI_Type *base, spi_master_handle_t *handle);
kadonotakashi 0:8fdf9a60065b 95 /*******************************************************************************
kadonotakashi 0:8fdf9a60065b 96 * Variables
kadonotakashi 0:8fdf9a60065b 97 ******************************************************************************/
kadonotakashi 0:8fdf9a60065b 98 /*! @brief SPI internal handle pointer array */
kadonotakashi 0:8fdf9a60065b 99 static spi_master_handle_t *s_spiHandle[FSL_FEATURE_SOC_SPI_COUNT];
kadonotakashi 0:8fdf9a60065b 100 /*! @brief Base pointer array */
kadonotakashi 0:8fdf9a60065b 101 static SPI_Type *const s_spiBases[] = SPI_BASE_PTRS;
kadonotakashi 0:8fdf9a60065b 102 /*! @brief IRQ name array */
kadonotakashi 0:8fdf9a60065b 103 static const IRQn_Type s_spiIRQ[] = SPI_IRQS;
kadonotakashi 0:8fdf9a60065b 104 /*! @brief Clock array name */
kadonotakashi 0:8fdf9a60065b 105 static const clock_ip_name_t s_spiClock[] = SPI_CLOCKS;
kadonotakashi 0:8fdf9a60065b 106
kadonotakashi 0:8fdf9a60065b 107 /*! @brief Pointer to master IRQ handler for each instance. */
kadonotakashi 0:8fdf9a60065b 108 static spi_isr_t s_spiIsr;
kadonotakashi 0:8fdf9a60065b 109
kadonotakashi 0:8fdf9a60065b 110 /*******************************************************************************
kadonotakashi 0:8fdf9a60065b 111 * Code
kadonotakashi 0:8fdf9a60065b 112 ******************************************************************************/
kadonotakashi 0:8fdf9a60065b 113 uint32_t SPI_GetInstance(SPI_Type *base)
kadonotakashi 0:8fdf9a60065b 114 {
kadonotakashi 0:8fdf9a60065b 115 uint32_t instance;
kadonotakashi 0:8fdf9a60065b 116
kadonotakashi 0:8fdf9a60065b 117 /* Find the instance index from base address mappings. */
kadonotakashi 0:8fdf9a60065b 118 for (instance = 0; instance < FSL_FEATURE_SOC_SPI_COUNT; instance++)
kadonotakashi 0:8fdf9a60065b 119 {
kadonotakashi 0:8fdf9a60065b 120 if (s_spiBases[instance] == base)
kadonotakashi 0:8fdf9a60065b 121 {
kadonotakashi 0:8fdf9a60065b 122 break;
kadonotakashi 0:8fdf9a60065b 123 }
kadonotakashi 0:8fdf9a60065b 124 }
kadonotakashi 0:8fdf9a60065b 125
kadonotakashi 0:8fdf9a60065b 126 assert(instance < FSL_FEATURE_SOC_SPI_COUNT);
kadonotakashi 0:8fdf9a60065b 127
kadonotakashi 0:8fdf9a60065b 128 return instance;
kadonotakashi 0:8fdf9a60065b 129 }
kadonotakashi 0:8fdf9a60065b 130
kadonotakashi 0:8fdf9a60065b 131 static void SPI_WriteNonBlocking(SPI_Type *base, uint8_t *buffer, size_t size)
kadonotakashi 0:8fdf9a60065b 132 {
kadonotakashi 0:8fdf9a60065b 133 uint32_t i = 0;
kadonotakashi 0:8fdf9a60065b 134 uint8_t bytesPerFrame = 1U;
kadonotakashi 0:8fdf9a60065b 135
kadonotakashi 0:8fdf9a60065b 136 #if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS
kadonotakashi 0:8fdf9a60065b 137 /* Check if 16 bits or 8 bits */
kadonotakashi 0:8fdf9a60065b 138 bytesPerFrame = ((base->C2 & SPI_C2_SPIMODE_MASK) >> SPI_C2_SPIMODE_SHIFT) + 1U;
kadonotakashi 0:8fdf9a60065b 139 #endif
kadonotakashi 0:8fdf9a60065b 140
kadonotakashi 0:8fdf9a60065b 141 while (i < size)
kadonotakashi 0:8fdf9a60065b 142 {
kadonotakashi 0:8fdf9a60065b 143 if (buffer != NULL)
kadonotakashi 0:8fdf9a60065b 144 {
kadonotakashi 0:8fdf9a60065b 145 #if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS
kadonotakashi 0:8fdf9a60065b 146 /*16 bit mode*/
kadonotakashi 0:8fdf9a60065b 147 if (base->C2 & SPI_C2_SPIMODE_MASK)
kadonotakashi 0:8fdf9a60065b 148 {
kadonotakashi 0:8fdf9a60065b 149 base->DL = *buffer++;
kadonotakashi 0:8fdf9a60065b 150 base->DH = *buffer++;
kadonotakashi 0:8fdf9a60065b 151 }
kadonotakashi 0:8fdf9a60065b 152 /* 8 bit mode */
kadonotakashi 0:8fdf9a60065b 153 else
kadonotakashi 0:8fdf9a60065b 154 {
kadonotakashi 0:8fdf9a60065b 155 base->DL = *buffer++;
kadonotakashi 0:8fdf9a60065b 156 }
kadonotakashi 0:8fdf9a60065b 157 #else
kadonotakashi 0:8fdf9a60065b 158 base->D = *buffer++;
kadonotakashi 0:8fdf9a60065b 159 #endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */
kadonotakashi 0:8fdf9a60065b 160 }
kadonotakashi 0:8fdf9a60065b 161 /* Send dummy data */
kadonotakashi 0:8fdf9a60065b 162 else
kadonotakashi 0:8fdf9a60065b 163 {
kadonotakashi 0:8fdf9a60065b 164 SPI_WriteData(base, SPI_DUMMYDATA);
kadonotakashi 0:8fdf9a60065b 165 }
kadonotakashi 0:8fdf9a60065b 166 i += bytesPerFrame;
kadonotakashi 0:8fdf9a60065b 167 }
kadonotakashi 0:8fdf9a60065b 168 }
kadonotakashi 0:8fdf9a60065b 169
kadonotakashi 0:8fdf9a60065b 170 static void SPI_ReadNonBlocking(SPI_Type *base, uint8_t *buffer, size_t size)
kadonotakashi 0:8fdf9a60065b 171 {
kadonotakashi 0:8fdf9a60065b 172 uint32_t i = 0;
kadonotakashi 0:8fdf9a60065b 173 uint8_t bytesPerFrame = 1U;
kadonotakashi 0:8fdf9a60065b 174
kadonotakashi 0:8fdf9a60065b 175 #if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS
kadonotakashi 0:8fdf9a60065b 176 /* Check if 16 bits or 8 bits */
kadonotakashi 0:8fdf9a60065b 177 bytesPerFrame = ((base->C2 & SPI_C2_SPIMODE_MASK) >> SPI_C2_SPIMODE_SHIFT) + 1U;
kadonotakashi 0:8fdf9a60065b 178 #endif
kadonotakashi 0:8fdf9a60065b 179
kadonotakashi 0:8fdf9a60065b 180 while (i < size)
kadonotakashi 0:8fdf9a60065b 181 {
kadonotakashi 0:8fdf9a60065b 182 if (buffer != NULL)
kadonotakashi 0:8fdf9a60065b 183 {
kadonotakashi 0:8fdf9a60065b 184 #if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS
kadonotakashi 0:8fdf9a60065b 185 /*16 bit mode*/
kadonotakashi 0:8fdf9a60065b 186 if (base->C2 & SPI_C2_SPIMODE_MASK)
kadonotakashi 0:8fdf9a60065b 187 {
kadonotakashi 0:8fdf9a60065b 188 *buffer++ = base->DL;
kadonotakashi 0:8fdf9a60065b 189 *buffer++ = base->DH;
kadonotakashi 0:8fdf9a60065b 190 }
kadonotakashi 0:8fdf9a60065b 191 /* 8 bit mode */
kadonotakashi 0:8fdf9a60065b 192 else
kadonotakashi 0:8fdf9a60065b 193 {
kadonotakashi 0:8fdf9a60065b 194 *buffer++ = base->DL;
kadonotakashi 0:8fdf9a60065b 195 }
kadonotakashi 0:8fdf9a60065b 196 #else
kadonotakashi 0:8fdf9a60065b 197 *buffer++ = base->D;
kadonotakashi 0:8fdf9a60065b 198 #endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */
kadonotakashi 0:8fdf9a60065b 199 }
kadonotakashi 0:8fdf9a60065b 200 else
kadonotakashi 0:8fdf9a60065b 201 {
kadonotakashi 0:8fdf9a60065b 202 SPI_ReadData(base);
kadonotakashi 0:8fdf9a60065b 203 }
kadonotakashi 0:8fdf9a60065b 204 i += bytesPerFrame;
kadonotakashi 0:8fdf9a60065b 205 }
kadonotakashi 0:8fdf9a60065b 206 }
kadonotakashi 0:8fdf9a60065b 207
kadonotakashi 0:8fdf9a60065b 208 static void SPI_SendTransfer(SPI_Type *base, spi_master_handle_t *handle)
kadonotakashi 0:8fdf9a60065b 209 {
kadonotakashi 0:8fdf9a60065b 210 uint8_t bytes = MIN((handle->watermark * 2U), handle->txRemainingBytes);
kadonotakashi 0:8fdf9a60065b 211
kadonotakashi 0:8fdf9a60065b 212 /* Read S register and ensure SPTEF is 1, otherwise the write would be ignored. */
kadonotakashi 0:8fdf9a60065b 213 if (handle->watermark == 1U)
kadonotakashi 0:8fdf9a60065b 214 {
kadonotakashi 0:8fdf9a60065b 215 if (bytes != 0U)
kadonotakashi 0:8fdf9a60065b 216 {
kadonotakashi 0:8fdf9a60065b 217 bytes = handle->bytePerFrame;
kadonotakashi 0:8fdf9a60065b 218 }
kadonotakashi 0:8fdf9a60065b 219
kadonotakashi 0:8fdf9a60065b 220 /* Send data */
kadonotakashi 0:8fdf9a60065b 221 if (base->C1 & SPI_C1_MSTR_MASK)
kadonotakashi 0:8fdf9a60065b 222 {
kadonotakashi 0:8fdf9a60065b 223 /* As a master, only write once */
kadonotakashi 0:8fdf9a60065b 224 if (base->S & SPI_S_SPTEF_MASK)
kadonotakashi 0:8fdf9a60065b 225 {
kadonotakashi 0:8fdf9a60065b 226 SPI_WriteNonBlocking(base, handle->txData, bytes);
kadonotakashi 0:8fdf9a60065b 227 /* Update handle information */
kadonotakashi 0:8fdf9a60065b 228 if (handle->txData)
kadonotakashi 0:8fdf9a60065b 229 {
kadonotakashi 0:8fdf9a60065b 230 handle->txData += bytes;
kadonotakashi 0:8fdf9a60065b 231 }
kadonotakashi 0:8fdf9a60065b 232 handle->txRemainingBytes -= bytes;
kadonotakashi 0:8fdf9a60065b 233 }
kadonotakashi 0:8fdf9a60065b 234 }
kadonotakashi 0:8fdf9a60065b 235 else
kadonotakashi 0:8fdf9a60065b 236 {
kadonotakashi 0:8fdf9a60065b 237 /* As a slave, send data until SPTEF cleared */
kadonotakashi 0:8fdf9a60065b 238 while ((base->S & SPI_S_SPTEF_MASK) && (handle->txRemainingBytes > 0))
kadonotakashi 0:8fdf9a60065b 239 {
kadonotakashi 0:8fdf9a60065b 240 SPI_WriteNonBlocking(base, handle->txData, bytes);
kadonotakashi 0:8fdf9a60065b 241
kadonotakashi 0:8fdf9a60065b 242 /* Update handle information */
kadonotakashi 0:8fdf9a60065b 243 if (handle->txData)
kadonotakashi 0:8fdf9a60065b 244 {
kadonotakashi 0:8fdf9a60065b 245 handle->txData += bytes;
kadonotakashi 0:8fdf9a60065b 246 }
kadonotakashi 0:8fdf9a60065b 247 handle->txRemainingBytes -= bytes;
kadonotakashi 0:8fdf9a60065b 248 }
kadonotakashi 0:8fdf9a60065b 249 }
kadonotakashi 0:8fdf9a60065b 250 }
kadonotakashi 0:8fdf9a60065b 251
kadonotakashi 0:8fdf9a60065b 252 #if defined(FSL_FEATURE_SPI_HAS_FIFO) && (FSL_FEATURE_SPI_HAS_FIFO)
kadonotakashi 0:8fdf9a60065b 253 /* If use FIFO */
kadonotakashi 0:8fdf9a60065b 254 else
kadonotakashi 0:8fdf9a60065b 255 {
kadonotakashi 0:8fdf9a60065b 256 if (base->S & SPI_S_TNEAREF_MASK)
kadonotakashi 0:8fdf9a60065b 257 {
kadonotakashi 0:8fdf9a60065b 258 SPI_WriteNonBlocking(base, handle->txData, bytes);
kadonotakashi 0:8fdf9a60065b 259
kadonotakashi 0:8fdf9a60065b 260 /* Update handle information */
kadonotakashi 0:8fdf9a60065b 261 if (handle->txData)
kadonotakashi 0:8fdf9a60065b 262 {
kadonotakashi 0:8fdf9a60065b 263 handle->txData += bytes;
kadonotakashi 0:8fdf9a60065b 264 }
kadonotakashi 0:8fdf9a60065b 265 handle->txRemainingBytes -= bytes;
kadonotakashi 0:8fdf9a60065b 266 }
kadonotakashi 0:8fdf9a60065b 267 }
kadonotakashi 0:8fdf9a60065b 268 #endif
kadonotakashi 0:8fdf9a60065b 269 }
kadonotakashi 0:8fdf9a60065b 270
kadonotakashi 0:8fdf9a60065b 271 static void SPI_ReceiveTransfer(SPI_Type *base, spi_master_handle_t *handle)
kadonotakashi 0:8fdf9a60065b 272 {
kadonotakashi 0:8fdf9a60065b 273 uint8_t bytes = MIN((handle->watermark * 2U), handle->rxRemainingBytes);
kadonotakashi 0:8fdf9a60065b 274 uint8_t val = 1U;
kadonotakashi 0:8fdf9a60065b 275
kadonotakashi 0:8fdf9a60065b 276 /* Read S register and ensure SPRF is 1, otherwise the write would be ignored. */
kadonotakashi 0:8fdf9a60065b 277 if (handle->watermark == 1U)
kadonotakashi 0:8fdf9a60065b 278 {
kadonotakashi 0:8fdf9a60065b 279 val = base->S & SPI_S_SPRF_MASK;
kadonotakashi 0:8fdf9a60065b 280 if (bytes != 0U)
kadonotakashi 0:8fdf9a60065b 281 {
kadonotakashi 0:8fdf9a60065b 282 bytes = handle->bytePerFrame;
kadonotakashi 0:8fdf9a60065b 283 }
kadonotakashi 0:8fdf9a60065b 284 }
kadonotakashi 0:8fdf9a60065b 285
kadonotakashi 0:8fdf9a60065b 286 if (val)
kadonotakashi 0:8fdf9a60065b 287 {
kadonotakashi 0:8fdf9a60065b 288 SPI_ReadNonBlocking(base, handle->rxData, bytes);
kadonotakashi 0:8fdf9a60065b 289
kadonotakashi 0:8fdf9a60065b 290 /* Update information in handle */
kadonotakashi 0:8fdf9a60065b 291 if (handle->rxData)
kadonotakashi 0:8fdf9a60065b 292 {
kadonotakashi 0:8fdf9a60065b 293 handle->rxData += bytes;
kadonotakashi 0:8fdf9a60065b 294 }
kadonotakashi 0:8fdf9a60065b 295 handle->rxRemainingBytes -= bytes;
kadonotakashi 0:8fdf9a60065b 296 }
kadonotakashi 0:8fdf9a60065b 297 }
kadonotakashi 0:8fdf9a60065b 298
kadonotakashi 0:8fdf9a60065b 299 void SPI_MasterGetDefaultConfig(spi_master_config_t *config)
kadonotakashi 0:8fdf9a60065b 300 {
kadonotakashi 0:8fdf9a60065b 301 config->enableMaster = true;
kadonotakashi 0:8fdf9a60065b 302 config->enableStopInWaitMode = false;
kadonotakashi 0:8fdf9a60065b 303 config->polarity = kSPI_ClockPolarityActiveHigh;
kadonotakashi 0:8fdf9a60065b 304 config->phase = kSPI_ClockPhaseFirstEdge;
kadonotakashi 0:8fdf9a60065b 305 config->direction = kSPI_MsbFirst;
kadonotakashi 0:8fdf9a60065b 306
kadonotakashi 0:8fdf9a60065b 307 #if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS
kadonotakashi 0:8fdf9a60065b 308 config->dataMode = kSPI_8BitMode;
kadonotakashi 0:8fdf9a60065b 309 #endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */
kadonotakashi 0:8fdf9a60065b 310
kadonotakashi 0:8fdf9a60065b 311 #if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO
kadonotakashi 0:8fdf9a60065b 312 config->txWatermark = kSPI_TxFifoOneHalfEmpty;
kadonotakashi 0:8fdf9a60065b 313 config->rxWatermark = kSPI_RxFifoOneHalfFull;
kadonotakashi 0:8fdf9a60065b 314 #endif /* FSL_FEATURE_SPI_HAS_FIFO */
kadonotakashi 0:8fdf9a60065b 315
kadonotakashi 0:8fdf9a60065b 316 config->pinMode = kSPI_PinModeNormal;
kadonotakashi 0:8fdf9a60065b 317 config->outputMode = kSPI_SlaveSelectAutomaticOutput;
kadonotakashi 0:8fdf9a60065b 318 config->baudRate_Bps = 500000U;
kadonotakashi 0:8fdf9a60065b 319 }
kadonotakashi 0:8fdf9a60065b 320
kadonotakashi 0:8fdf9a60065b 321 void SPI_MasterInit(SPI_Type *base, const spi_master_config_t *config, uint32_t srcClock_Hz)
kadonotakashi 0:8fdf9a60065b 322 {
kadonotakashi 0:8fdf9a60065b 323 assert(config && srcClock_Hz);
kadonotakashi 0:8fdf9a60065b 324
kadonotakashi 0:8fdf9a60065b 325 /* Open clock gate for SPI and open interrupt */
kadonotakashi 0:8fdf9a60065b 326 CLOCK_EnableClock(s_spiClock[SPI_GetInstance(base)]);
kadonotakashi 0:8fdf9a60065b 327
kadonotakashi 0:8fdf9a60065b 328 /* Disable SPI before configuration */
kadonotakashi 0:8fdf9a60065b 329 base->C1 &= ~SPI_C1_SPE_MASK;
kadonotakashi 0:8fdf9a60065b 330
kadonotakashi 0:8fdf9a60065b 331 /* Configure clock polarity and phase, set SPI to master */
kadonotakashi 0:8fdf9a60065b 332 base->C1 = SPI_C1_MSTR(1U) | SPI_C1_CPOL(config->polarity) | SPI_C1_CPHA(config->phase) |
kadonotakashi 0:8fdf9a60065b 333 SPI_C1_SSOE(config->outputMode & 1U) | SPI_C1_LSBFE(config->direction);
kadonotakashi 0:8fdf9a60065b 334
kadonotakashi 0:8fdf9a60065b 335 /* Set data mode, and also pin mode and mode fault settings */
kadonotakashi 0:8fdf9a60065b 336 #if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS
kadonotakashi 0:8fdf9a60065b 337 base->C2 = SPI_C2_MODFEN(config->outputMode >> 1U) | SPI_C2_BIDIROE(config->pinMode >> 1U) |
kadonotakashi 0:8fdf9a60065b 338 SPI_C2_SPISWAI(config->enableStopInWaitMode) | SPI_C2_SPC0(config->pinMode & 1U) |
kadonotakashi 0:8fdf9a60065b 339 SPI_C2_SPIMODE(config->dataMode);
kadonotakashi 0:8fdf9a60065b 340 #else
kadonotakashi 0:8fdf9a60065b 341 base->C2 = SPI_C2_MODFEN(config->outputMode >> 1U) | SPI_C2_BIDIROE(config->pinMode >> 1U) |
kadonotakashi 0:8fdf9a60065b 342 SPI_C2_SPISWAI(config->enableStopInWaitMode) | SPI_C2_SPC0(config->pinMode & 1U);
kadonotakashi 0:8fdf9a60065b 343 #endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */
kadonotakashi 0:8fdf9a60065b 344
kadonotakashi 0:8fdf9a60065b 345 /* Set watermark, FIFO is enabled */
kadonotakashi 0:8fdf9a60065b 346 #if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO
kadonotakashi 0:8fdf9a60065b 347 if (FSL_FEATURE_SPI_FIFO_SIZEn(base) != 0)
kadonotakashi 0:8fdf9a60065b 348 {
kadonotakashi 0:8fdf9a60065b 349 base->C3 = SPI_C3_TNEAREF_MARK(config->txWatermark) | SPI_C3_RNFULLF_MARK(config->rxWatermark) |
kadonotakashi 0:8fdf9a60065b 350 SPI_C3_INTCLR(0U) | SPI_C3_FIFOMODE(1U);
kadonotakashi 0:8fdf9a60065b 351 }
kadonotakashi 0:8fdf9a60065b 352 #endif /* FSL_FEATURE_SPI_HAS_FIFO */
kadonotakashi 0:8fdf9a60065b 353
kadonotakashi 0:8fdf9a60065b 354 /* Set baud rate */
kadonotakashi 0:8fdf9a60065b 355 SPI_MasterSetBaudRate(base, config->baudRate_Bps, srcClock_Hz);
kadonotakashi 0:8fdf9a60065b 356
kadonotakashi 0:8fdf9a60065b 357 /* Enable SPI */
kadonotakashi 0:8fdf9a60065b 358 if (config->enableMaster)
kadonotakashi 0:8fdf9a60065b 359 {
kadonotakashi 0:8fdf9a60065b 360 base->C1 |= SPI_C1_SPE_MASK;
kadonotakashi 0:8fdf9a60065b 361 }
kadonotakashi 0:8fdf9a60065b 362 }
kadonotakashi 0:8fdf9a60065b 363
kadonotakashi 0:8fdf9a60065b 364 void SPI_SlaveGetDefaultConfig(spi_slave_config_t *config)
kadonotakashi 0:8fdf9a60065b 365 {
kadonotakashi 0:8fdf9a60065b 366 config->enableSlave = true;
kadonotakashi 0:8fdf9a60065b 367 config->polarity = kSPI_ClockPolarityActiveHigh;
kadonotakashi 0:8fdf9a60065b 368 config->phase = kSPI_ClockPhaseFirstEdge;
kadonotakashi 0:8fdf9a60065b 369 config->direction = kSPI_MsbFirst;
kadonotakashi 0:8fdf9a60065b 370 config->enableStopInWaitMode = false;
kadonotakashi 0:8fdf9a60065b 371
kadonotakashi 0:8fdf9a60065b 372 #if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS
kadonotakashi 0:8fdf9a60065b 373 config->dataMode = kSPI_8BitMode;
kadonotakashi 0:8fdf9a60065b 374 #endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */
kadonotakashi 0:8fdf9a60065b 375
kadonotakashi 0:8fdf9a60065b 376 #if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO
kadonotakashi 0:8fdf9a60065b 377 config->txWatermark = kSPI_TxFifoOneHalfEmpty;
kadonotakashi 0:8fdf9a60065b 378 config->rxWatermark = kSPI_RxFifoOneHalfFull;
kadonotakashi 0:8fdf9a60065b 379 #endif /* FSL_FEATURE_SPI_HAS_FIFO */
kadonotakashi 0:8fdf9a60065b 380 }
kadonotakashi 0:8fdf9a60065b 381
kadonotakashi 0:8fdf9a60065b 382 void SPI_SlaveInit(SPI_Type *base, const spi_slave_config_t *config)
kadonotakashi 0:8fdf9a60065b 383 {
kadonotakashi 0:8fdf9a60065b 384 assert(config);
kadonotakashi 0:8fdf9a60065b 385
kadonotakashi 0:8fdf9a60065b 386 /* Open clock gate for SPI and open interrupt */
kadonotakashi 0:8fdf9a60065b 387 CLOCK_EnableClock(s_spiClock[SPI_GetInstance(base)]);
kadonotakashi 0:8fdf9a60065b 388
kadonotakashi 0:8fdf9a60065b 389 /* Disable SPI before configuration */
kadonotakashi 0:8fdf9a60065b 390 base->C1 &= ~SPI_C1_SPE_MASK;
kadonotakashi 0:8fdf9a60065b 391
kadonotakashi 0:8fdf9a60065b 392 /* Configure master and clock polarity and phase */
kadonotakashi 0:8fdf9a60065b 393 base->C1 =
kadonotakashi 0:8fdf9a60065b 394 SPI_C1_MSTR(0U) | SPI_C1_CPOL(config->polarity) | SPI_C1_CPHA(config->phase) | SPI_C1_LSBFE(config->direction);
kadonotakashi 0:8fdf9a60065b 395
kadonotakashi 0:8fdf9a60065b 396 /* Configure data mode if needed */
kadonotakashi 0:8fdf9a60065b 397 #if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS
kadonotakashi 0:8fdf9a60065b 398 base->C2 = SPI_C2_SPIMODE(config->dataMode) | SPI_C2_SPISWAI(config->enableStopInWaitMode);
kadonotakashi 0:8fdf9a60065b 399 #else
kadonotakashi 0:8fdf9a60065b 400 base->C2 = SPI_C2_SPISWAI(config->enableStopInWaitMode);
kadonotakashi 0:8fdf9a60065b 401 #endif /* FSL_FEATURE_SPI_16BIT_TRANSFERS */
kadonotakashi 0:8fdf9a60065b 402
kadonotakashi 0:8fdf9a60065b 403 /* Set watermark */
kadonotakashi 0:8fdf9a60065b 404 #if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO
kadonotakashi 0:8fdf9a60065b 405 if (FSL_FEATURE_SPI_FIFO_SIZEn(base) != 0U)
kadonotakashi 0:8fdf9a60065b 406 {
kadonotakashi 0:8fdf9a60065b 407 base->C3 = SPI_C3_TNEAREF_MARK(config->txWatermark) | SPI_C3_RNFULLF_MARK(config->rxWatermark) |
kadonotakashi 0:8fdf9a60065b 408 SPI_C3_INTCLR(0U) | SPI_C3_FIFOMODE(1U);
kadonotakashi 0:8fdf9a60065b 409 }
kadonotakashi 0:8fdf9a60065b 410 #endif /* FSL_FEATURE_SPI_HAS_FIFO */
kadonotakashi 0:8fdf9a60065b 411
kadonotakashi 0:8fdf9a60065b 412 /* Enable SPI */
kadonotakashi 0:8fdf9a60065b 413 if (config->enableSlave)
kadonotakashi 0:8fdf9a60065b 414 {
kadonotakashi 0:8fdf9a60065b 415 base->C1 |= SPI_C1_SPE_MASK;
kadonotakashi 0:8fdf9a60065b 416 }
kadonotakashi 0:8fdf9a60065b 417 }
kadonotakashi 0:8fdf9a60065b 418
kadonotakashi 0:8fdf9a60065b 419 void SPI_Deinit(SPI_Type *base)
kadonotakashi 0:8fdf9a60065b 420 {
kadonotakashi 0:8fdf9a60065b 421 /* Disable SPI module before shutting down */
kadonotakashi 0:8fdf9a60065b 422 base->C1 &= ~SPI_C1_SPE_MASK;
kadonotakashi 0:8fdf9a60065b 423
kadonotakashi 0:8fdf9a60065b 424 /* Gate the clock */
kadonotakashi 0:8fdf9a60065b 425 CLOCK_DisableClock(s_spiClock[SPI_GetInstance(base)]);
kadonotakashi 0:8fdf9a60065b 426 }
kadonotakashi 0:8fdf9a60065b 427
kadonotakashi 0:8fdf9a60065b 428 uint32_t SPI_GetStatusFlags(SPI_Type *base)
kadonotakashi 0:8fdf9a60065b 429 {
kadonotakashi 0:8fdf9a60065b 430 #if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO
kadonotakashi 0:8fdf9a60065b 431 if (FSL_FEATURE_SPI_FIFO_SIZEn(base) != 0)
kadonotakashi 0:8fdf9a60065b 432 {
kadonotakashi 0:8fdf9a60065b 433 return ((base->S) | (((uint32_t)base->CI) << 8U));
kadonotakashi 0:8fdf9a60065b 434 }
kadonotakashi 0:8fdf9a60065b 435 else
kadonotakashi 0:8fdf9a60065b 436 {
kadonotakashi 0:8fdf9a60065b 437 return (base->S);
kadonotakashi 0:8fdf9a60065b 438 }
kadonotakashi 0:8fdf9a60065b 439 #else
kadonotakashi 0:8fdf9a60065b 440 return (base->S);
kadonotakashi 0:8fdf9a60065b 441 #endif /* FSL_FEATURE_SPI_HAS_FIFO */
kadonotakashi 0:8fdf9a60065b 442 }
kadonotakashi 0:8fdf9a60065b 443
kadonotakashi 0:8fdf9a60065b 444 void SPI_EnableInterrupts(SPI_Type *base, uint32_t mask)
kadonotakashi 0:8fdf9a60065b 445 {
kadonotakashi 0:8fdf9a60065b 446 /* Rx full interrupt */
kadonotakashi 0:8fdf9a60065b 447 if (mask & kSPI_RxFullAndModfInterruptEnable)
kadonotakashi 0:8fdf9a60065b 448 {
kadonotakashi 0:8fdf9a60065b 449 base->C1 |= SPI_C1_SPIE_MASK;
kadonotakashi 0:8fdf9a60065b 450 }
kadonotakashi 0:8fdf9a60065b 451
kadonotakashi 0:8fdf9a60065b 452 /* Tx empty interrupt */
kadonotakashi 0:8fdf9a60065b 453 if (mask & kSPI_TxEmptyInterruptEnable)
kadonotakashi 0:8fdf9a60065b 454 {
kadonotakashi 0:8fdf9a60065b 455 base->C1 |= SPI_C1_SPTIE_MASK;
kadonotakashi 0:8fdf9a60065b 456 }
kadonotakashi 0:8fdf9a60065b 457
kadonotakashi 0:8fdf9a60065b 458 /* Data match interrupt */
kadonotakashi 0:8fdf9a60065b 459 if (mask & kSPI_MatchInterruptEnable)
kadonotakashi 0:8fdf9a60065b 460 {
kadonotakashi 0:8fdf9a60065b 461 base->C2 |= SPI_C2_SPMIE_MASK;
kadonotakashi 0:8fdf9a60065b 462 }
kadonotakashi 0:8fdf9a60065b 463
kadonotakashi 0:8fdf9a60065b 464 /* FIFO related interrupts */
kadonotakashi 0:8fdf9a60065b 465 #if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO
kadonotakashi 0:8fdf9a60065b 466 if (FSL_FEATURE_SPI_FIFO_SIZEn(base) != 0)
kadonotakashi 0:8fdf9a60065b 467 {
kadonotakashi 0:8fdf9a60065b 468 /* Rx FIFO near full interrupt */
kadonotakashi 0:8fdf9a60065b 469 if (mask & kSPI_RxFifoNearFullInterruptEnable)
kadonotakashi 0:8fdf9a60065b 470 {
kadonotakashi 0:8fdf9a60065b 471 base->C3 |= SPI_C3_RNFULLIEN_MASK;
kadonotakashi 0:8fdf9a60065b 472 }
kadonotakashi 0:8fdf9a60065b 473
kadonotakashi 0:8fdf9a60065b 474 /* Tx FIFO near empty interrupt */
kadonotakashi 0:8fdf9a60065b 475 if (mask & kSPI_TxFifoNearEmptyInterruptEnable)
kadonotakashi 0:8fdf9a60065b 476 {
kadonotakashi 0:8fdf9a60065b 477 base->C3 |= SPI_C3_TNEARIEN_MASK;
kadonotakashi 0:8fdf9a60065b 478 }
kadonotakashi 0:8fdf9a60065b 479 }
kadonotakashi 0:8fdf9a60065b 480 #endif /* FSL_FEATURE_SPI_HAS_FIFO */
kadonotakashi 0:8fdf9a60065b 481 }
kadonotakashi 0:8fdf9a60065b 482
kadonotakashi 0:8fdf9a60065b 483 void SPI_DisableInterrupts(SPI_Type *base, uint32_t mask)
kadonotakashi 0:8fdf9a60065b 484 {
kadonotakashi 0:8fdf9a60065b 485 /* Rx full interrupt */
kadonotakashi 0:8fdf9a60065b 486 if (mask & kSPI_RxFullAndModfInterruptEnable)
kadonotakashi 0:8fdf9a60065b 487 {
kadonotakashi 0:8fdf9a60065b 488 base->C1 &= (~SPI_C1_SPIE_MASK);
kadonotakashi 0:8fdf9a60065b 489 }
kadonotakashi 0:8fdf9a60065b 490
kadonotakashi 0:8fdf9a60065b 491 /* Tx empty interrupt */
kadonotakashi 0:8fdf9a60065b 492 if (mask & kSPI_TxEmptyInterruptEnable)
kadonotakashi 0:8fdf9a60065b 493 {
kadonotakashi 0:8fdf9a60065b 494 base->C1 &= (~SPI_C1_SPTIE_MASK);
kadonotakashi 0:8fdf9a60065b 495 }
kadonotakashi 0:8fdf9a60065b 496
kadonotakashi 0:8fdf9a60065b 497 /* Data match interrupt */
kadonotakashi 0:8fdf9a60065b 498 if (mask & kSPI_MatchInterruptEnable)
kadonotakashi 0:8fdf9a60065b 499 {
kadonotakashi 0:8fdf9a60065b 500 base->C2 &= (~SPI_C2_SPMIE_MASK);
kadonotakashi 0:8fdf9a60065b 501 }
kadonotakashi 0:8fdf9a60065b 502
kadonotakashi 0:8fdf9a60065b 503 #if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO
kadonotakashi 0:8fdf9a60065b 504 if (FSL_FEATURE_SPI_FIFO_SIZEn(base) != 0)
kadonotakashi 0:8fdf9a60065b 505 {
kadonotakashi 0:8fdf9a60065b 506 /* Rx FIFO near full interrupt */
kadonotakashi 0:8fdf9a60065b 507 if (mask & kSPI_RxFifoNearFullInterruptEnable)
kadonotakashi 0:8fdf9a60065b 508 {
kadonotakashi 0:8fdf9a60065b 509 base->C3 &= ~SPI_C3_RNFULLIEN_MASK;
kadonotakashi 0:8fdf9a60065b 510 }
kadonotakashi 0:8fdf9a60065b 511
kadonotakashi 0:8fdf9a60065b 512 /* Tx FIFO near empty interrupt */
kadonotakashi 0:8fdf9a60065b 513 if (mask & kSPI_TxFifoNearEmptyInterruptEnable)
kadonotakashi 0:8fdf9a60065b 514 {
kadonotakashi 0:8fdf9a60065b 515 base->C3 &= ~SPI_C3_TNEARIEN_MASK;
kadonotakashi 0:8fdf9a60065b 516 }
kadonotakashi 0:8fdf9a60065b 517 }
kadonotakashi 0:8fdf9a60065b 518 #endif /* FSL_FEATURE_SPI_HAS_FIFO */
kadonotakashi 0:8fdf9a60065b 519 }
kadonotakashi 0:8fdf9a60065b 520
kadonotakashi 0:8fdf9a60065b 521 void SPI_MasterSetBaudRate(SPI_Type *base, uint32_t baudRate_Bps, uint32_t srcClock_Hz)
kadonotakashi 0:8fdf9a60065b 522 {
kadonotakashi 0:8fdf9a60065b 523 uint32_t prescaler;
kadonotakashi 0:8fdf9a60065b 524 uint32_t bestPrescaler;
kadonotakashi 0:8fdf9a60065b 525 uint32_t rateDivisor;
kadonotakashi 0:8fdf9a60065b 526 uint32_t bestDivisor;
kadonotakashi 0:8fdf9a60065b 527 uint32_t rateDivisorValue;
kadonotakashi 0:8fdf9a60065b 528 uint32_t realBaudrate;
kadonotakashi 0:8fdf9a60065b 529 uint32_t diff;
kadonotakashi 0:8fdf9a60065b 530 uint32_t min_diff;
kadonotakashi 0:8fdf9a60065b 531 uint32_t freq = baudRate_Bps;
kadonotakashi 0:8fdf9a60065b 532
kadonotakashi 0:8fdf9a60065b 533 /* Find combination of prescaler and scaler resulting in baudrate closest to the requested value */
kadonotakashi 0:8fdf9a60065b 534 min_diff = 0xFFFFFFFFU;
kadonotakashi 0:8fdf9a60065b 535
kadonotakashi 0:8fdf9a60065b 536 /* Set the maximum divisor bit settings for each of the following divisors */
kadonotakashi 0:8fdf9a60065b 537 bestPrescaler = 7U;
kadonotakashi 0:8fdf9a60065b 538 bestDivisor = 8U;
kadonotakashi 0:8fdf9a60065b 539
kadonotakashi 0:8fdf9a60065b 540 /* In all for loops, if min_diff = 0, the exit for loop*/
kadonotakashi 0:8fdf9a60065b 541 for (prescaler = 0; (prescaler <= 7) && min_diff; prescaler++)
kadonotakashi 0:8fdf9a60065b 542 {
kadonotakashi 0:8fdf9a60065b 543 /* Initialize to div-by-2 */
kadonotakashi 0:8fdf9a60065b 544 rateDivisorValue = 2U;
kadonotakashi 0:8fdf9a60065b 545
kadonotakashi 0:8fdf9a60065b 546 for (rateDivisor = 0; (rateDivisor <= 8U) && min_diff; rateDivisor++)
kadonotakashi 0:8fdf9a60065b 547 {
kadonotakashi 0:8fdf9a60065b 548 /* Calculate actual baud rate, note need to add 1 to prescaler */
kadonotakashi 0:8fdf9a60065b 549 realBaudrate = ((srcClock_Hz) / ((prescaler + 1) * rateDivisorValue));
kadonotakashi 0:8fdf9a60065b 550
kadonotakashi 0:8fdf9a60065b 551 /* Calculate the baud rate difference based on the conditional statement ,that states that the
kadonotakashi 0:8fdf9a60065b 552 calculated baud rate must not exceed the desired baud rate */
kadonotakashi 0:8fdf9a60065b 553 if (freq >= realBaudrate)
kadonotakashi 0:8fdf9a60065b 554 {
kadonotakashi 0:8fdf9a60065b 555 diff = freq - realBaudrate;
kadonotakashi 0:8fdf9a60065b 556 if (min_diff > diff)
kadonotakashi 0:8fdf9a60065b 557 {
kadonotakashi 0:8fdf9a60065b 558 /* A better match found */
kadonotakashi 0:8fdf9a60065b 559 min_diff = diff;
kadonotakashi 0:8fdf9a60065b 560 bestPrescaler = prescaler;
kadonotakashi 0:8fdf9a60065b 561 bestDivisor = rateDivisor;
kadonotakashi 0:8fdf9a60065b 562 }
kadonotakashi 0:8fdf9a60065b 563 }
kadonotakashi 0:8fdf9a60065b 564
kadonotakashi 0:8fdf9a60065b 565 /* Multiply by 2 for each iteration, possible divisor values: 2, 4, 8, 16, ... 512 */
kadonotakashi 0:8fdf9a60065b 566 rateDivisorValue *= 2U;
kadonotakashi 0:8fdf9a60065b 567 }
kadonotakashi 0:8fdf9a60065b 568 }
kadonotakashi 0:8fdf9a60065b 569
kadonotakashi 0:8fdf9a60065b 570 /* Write the best prescalar and baud rate scalar */
kadonotakashi 0:8fdf9a60065b 571 base->BR = SPI_BR_SPR(bestDivisor) | SPI_BR_SPPR(bestPrescaler);
kadonotakashi 0:8fdf9a60065b 572 }
kadonotakashi 0:8fdf9a60065b 573
kadonotakashi 0:8fdf9a60065b 574 void SPI_WriteBlocking(SPI_Type *base, uint8_t *buffer, size_t size)
kadonotakashi 0:8fdf9a60065b 575 {
kadonotakashi 0:8fdf9a60065b 576 uint32_t i = 0;
kadonotakashi 0:8fdf9a60065b 577 uint8_t bytesPerFrame = 1U;
kadonotakashi 0:8fdf9a60065b 578
kadonotakashi 0:8fdf9a60065b 579 #if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS
kadonotakashi 0:8fdf9a60065b 580 /* Check if 16 bits or 8 bits */
kadonotakashi 0:8fdf9a60065b 581 bytesPerFrame = ((base->C2 & SPI_C2_SPIMODE_MASK) >> SPI_C2_SPIMODE_SHIFT) + 1U;
kadonotakashi 0:8fdf9a60065b 582 #endif
kadonotakashi 0:8fdf9a60065b 583
kadonotakashi 0:8fdf9a60065b 584 while (i < size)
kadonotakashi 0:8fdf9a60065b 585 {
kadonotakashi 0:8fdf9a60065b 586 while ((base->S & SPI_S_SPTEF_MASK) == 0)
kadonotakashi 0:8fdf9a60065b 587 {
kadonotakashi 0:8fdf9a60065b 588 }
kadonotakashi 0:8fdf9a60065b 589
kadonotakashi 0:8fdf9a60065b 590 /* Send a frame of data */
kadonotakashi 0:8fdf9a60065b 591 SPI_WriteNonBlocking(base, buffer, bytesPerFrame);
kadonotakashi 0:8fdf9a60065b 592
kadonotakashi 0:8fdf9a60065b 593 i += bytesPerFrame;
kadonotakashi 0:8fdf9a60065b 594 buffer += bytesPerFrame;
kadonotakashi 0:8fdf9a60065b 595 }
kadonotakashi 0:8fdf9a60065b 596 }
kadonotakashi 0:8fdf9a60065b 597
kadonotakashi 0:8fdf9a60065b 598 #if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO
kadonotakashi 0:8fdf9a60065b 599 void SPI_EnableFIFO(SPI_Type *base, bool enable)
kadonotakashi 0:8fdf9a60065b 600 {
kadonotakashi 0:8fdf9a60065b 601 if (FSL_FEATURE_SPI_FIFO_SIZEn(base) != 0U)
kadonotakashi 0:8fdf9a60065b 602 {
kadonotakashi 0:8fdf9a60065b 603 if (enable)
kadonotakashi 0:8fdf9a60065b 604 {
kadonotakashi 0:8fdf9a60065b 605 base->C3 |= SPI_C3_FIFOMODE_MASK;
kadonotakashi 0:8fdf9a60065b 606 }
kadonotakashi 0:8fdf9a60065b 607 else
kadonotakashi 0:8fdf9a60065b 608 {
kadonotakashi 0:8fdf9a60065b 609 base->C3 &= ~SPI_C3_FIFOMODE_MASK;
kadonotakashi 0:8fdf9a60065b 610 }
kadonotakashi 0:8fdf9a60065b 611 }
kadonotakashi 0:8fdf9a60065b 612 }
kadonotakashi 0:8fdf9a60065b 613 #endif /* FSL_FEATURE_SPI_HAS_FIFO */
kadonotakashi 0:8fdf9a60065b 614
kadonotakashi 0:8fdf9a60065b 615 void SPI_WriteData(SPI_Type *base, uint16_t data)
kadonotakashi 0:8fdf9a60065b 616 {
kadonotakashi 0:8fdf9a60065b 617 #if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && (FSL_FEATURE_SPI_16BIT_TRANSFERS)
kadonotakashi 0:8fdf9a60065b 618 base->DL = data & 0xFFU;
kadonotakashi 0:8fdf9a60065b 619 base->DH = (data >> 8U) & 0xFFU;
kadonotakashi 0:8fdf9a60065b 620 #else
kadonotakashi 0:8fdf9a60065b 621 base->D = data & 0xFFU;
kadonotakashi 0:8fdf9a60065b 622 #endif
kadonotakashi 0:8fdf9a60065b 623 }
kadonotakashi 0:8fdf9a60065b 624
kadonotakashi 0:8fdf9a60065b 625 uint16_t SPI_ReadData(SPI_Type *base)
kadonotakashi 0:8fdf9a60065b 626 {
kadonotakashi 0:8fdf9a60065b 627 uint16_t val = 0;
kadonotakashi 0:8fdf9a60065b 628 #if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && (FSL_FEATURE_SPI_16BIT_TRANSFERS)
kadonotakashi 0:8fdf9a60065b 629 val = base->DL;
kadonotakashi 0:8fdf9a60065b 630 val |= (uint16_t)((uint16_t)(base->DH) << 8U);
kadonotakashi 0:8fdf9a60065b 631 #else
kadonotakashi 0:8fdf9a60065b 632 val = base->D;
kadonotakashi 0:8fdf9a60065b 633 #endif
kadonotakashi 0:8fdf9a60065b 634 return val;
kadonotakashi 0:8fdf9a60065b 635 }
kadonotakashi 0:8fdf9a60065b 636
kadonotakashi 0:8fdf9a60065b 637 status_t SPI_MasterTransferBlocking(SPI_Type *base, spi_transfer_t *xfer)
kadonotakashi 0:8fdf9a60065b 638 {
kadonotakashi 0:8fdf9a60065b 639 assert(xfer);
kadonotakashi 0:8fdf9a60065b 640
kadonotakashi 0:8fdf9a60065b 641 uint8_t bytesPerFrame = 1U;
kadonotakashi 0:8fdf9a60065b 642
kadonotakashi 0:8fdf9a60065b 643 /* Check if the argument is legal */
kadonotakashi 0:8fdf9a60065b 644 if ((xfer->txData == NULL) && (xfer->rxData == NULL))
kadonotakashi 0:8fdf9a60065b 645 {
kadonotakashi 0:8fdf9a60065b 646 return kStatus_InvalidArgument;
kadonotakashi 0:8fdf9a60065b 647 }
kadonotakashi 0:8fdf9a60065b 648
kadonotakashi 0:8fdf9a60065b 649 #if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS
kadonotakashi 0:8fdf9a60065b 650 /* Check if 16 bits or 8 bits */
kadonotakashi 0:8fdf9a60065b 651 bytesPerFrame = ((base->C2 & SPI_C2_SPIMODE_MASK) >> SPI_C2_SPIMODE_SHIFT) + 1U;
kadonotakashi 0:8fdf9a60065b 652 #endif
kadonotakashi 0:8fdf9a60065b 653
kadonotakashi 0:8fdf9a60065b 654 /* Disable SPI and then enable it, this is used to clear S register */
kadonotakashi 0:8fdf9a60065b 655 base->C1 &= ~SPI_C1_SPE_MASK;
kadonotakashi 0:8fdf9a60065b 656 base->C1 |= SPI_C1_SPE_MASK;
kadonotakashi 0:8fdf9a60065b 657
kadonotakashi 0:8fdf9a60065b 658 #if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO
kadonotakashi 0:8fdf9a60065b 659
kadonotakashi 0:8fdf9a60065b 660 /* Disable FIFO, as the FIFO may cause data loss if the data size is not integer
kadonotakashi 0:8fdf9a60065b 661 times of 2bytes. As SPI cannot set watermark to 0, only can set to 1/2 FIFO size or 3/4 FIFO
kadonotakashi 0:8fdf9a60065b 662 size. */
kadonotakashi 0:8fdf9a60065b 663 if (FSL_FEATURE_SPI_FIFO_SIZEn(base) != 0)
kadonotakashi 0:8fdf9a60065b 664 {
kadonotakashi 0:8fdf9a60065b 665 base->C3 &= ~SPI_C3_FIFOMODE_MASK;
kadonotakashi 0:8fdf9a60065b 666 }
kadonotakashi 0:8fdf9a60065b 667
kadonotakashi 0:8fdf9a60065b 668 #endif /* FSL_FEATURE_SPI_HAS_FIFO */
kadonotakashi 0:8fdf9a60065b 669
kadonotakashi 0:8fdf9a60065b 670 /* Begin the polling transfer until all data sent */
kadonotakashi 0:8fdf9a60065b 671 while (xfer->dataSize > 0)
kadonotakashi 0:8fdf9a60065b 672 {
kadonotakashi 0:8fdf9a60065b 673 /* Data send */
kadonotakashi 0:8fdf9a60065b 674 while ((base->S & SPI_S_SPTEF_MASK) == 0U)
kadonotakashi 0:8fdf9a60065b 675 {
kadonotakashi 0:8fdf9a60065b 676 }
kadonotakashi 0:8fdf9a60065b 677 SPI_WriteNonBlocking(base, xfer->txData, bytesPerFrame);
kadonotakashi 0:8fdf9a60065b 678 if (xfer->txData)
kadonotakashi 0:8fdf9a60065b 679 {
kadonotakashi 0:8fdf9a60065b 680 xfer->txData += bytesPerFrame;
kadonotakashi 0:8fdf9a60065b 681 }
kadonotakashi 0:8fdf9a60065b 682
kadonotakashi 0:8fdf9a60065b 683 while ((base->S & SPI_S_SPRF_MASK) == 0U)
kadonotakashi 0:8fdf9a60065b 684 {
kadonotakashi 0:8fdf9a60065b 685 }
kadonotakashi 0:8fdf9a60065b 686 SPI_ReadNonBlocking(base, xfer->rxData, bytesPerFrame);
kadonotakashi 0:8fdf9a60065b 687 if (xfer->rxData)
kadonotakashi 0:8fdf9a60065b 688 {
kadonotakashi 0:8fdf9a60065b 689 xfer->rxData += bytesPerFrame;
kadonotakashi 0:8fdf9a60065b 690 }
kadonotakashi 0:8fdf9a60065b 691
kadonotakashi 0:8fdf9a60065b 692 /* Decrease the number */
kadonotakashi 0:8fdf9a60065b 693 xfer->dataSize -= bytesPerFrame;
kadonotakashi 0:8fdf9a60065b 694 }
kadonotakashi 0:8fdf9a60065b 695
kadonotakashi 0:8fdf9a60065b 696 return kStatus_Success;
kadonotakashi 0:8fdf9a60065b 697 }
kadonotakashi 0:8fdf9a60065b 698
kadonotakashi 0:8fdf9a60065b 699 void SPI_MasterTransferCreateHandle(SPI_Type *base,
kadonotakashi 0:8fdf9a60065b 700 spi_master_handle_t *handle,
kadonotakashi 0:8fdf9a60065b 701 spi_master_callback_t callback,
kadonotakashi 0:8fdf9a60065b 702 void *userData)
kadonotakashi 0:8fdf9a60065b 703 {
kadonotakashi 0:8fdf9a60065b 704 assert(handle);
kadonotakashi 0:8fdf9a60065b 705
kadonotakashi 0:8fdf9a60065b 706 uint8_t instance = SPI_GetInstance(base);
kadonotakashi 0:8fdf9a60065b 707
kadonotakashi 0:8fdf9a60065b 708 /* Initialize the handle */
kadonotakashi 0:8fdf9a60065b 709 s_spiHandle[instance] = handle;
kadonotakashi 0:8fdf9a60065b 710 handle->callback = callback;
kadonotakashi 0:8fdf9a60065b 711 handle->userData = userData;
kadonotakashi 0:8fdf9a60065b 712 s_spiIsr = SPI_MasterTransferHandleIRQ;
kadonotakashi 0:8fdf9a60065b 713
kadonotakashi 0:8fdf9a60065b 714 #if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO
kadonotakashi 0:8fdf9a60065b 715 uint8_t txSize = 0U;
kadonotakashi 0:8fdf9a60065b 716 /* Get the number to be sent if there is FIFO */
kadonotakashi 0:8fdf9a60065b 717 if (FSL_FEATURE_SPI_FIFO_SIZEn(base) != 0)
kadonotakashi 0:8fdf9a60065b 718 {
kadonotakashi 0:8fdf9a60065b 719 txSize = (base->C3 & SPI_C3_TNEAREF_MARK_MASK) >> SPI_C3_TNEAREF_MARK_SHIFT;
kadonotakashi 0:8fdf9a60065b 720 if (txSize == 0U)
kadonotakashi 0:8fdf9a60065b 721 {
kadonotakashi 0:8fdf9a60065b 722 handle->watermark = FSL_FEATURE_SPI_FIFO_SIZEn(base) * 3U / 4U;
kadonotakashi 0:8fdf9a60065b 723 }
kadonotakashi 0:8fdf9a60065b 724 else
kadonotakashi 0:8fdf9a60065b 725 {
kadonotakashi 0:8fdf9a60065b 726 handle->watermark = FSL_FEATURE_SPI_FIFO_SIZEn(base) / 2U;
kadonotakashi 0:8fdf9a60065b 727 }
kadonotakashi 0:8fdf9a60065b 728 }
kadonotakashi 0:8fdf9a60065b 729 /* If no FIFO, just set the watermark to 1 */
kadonotakashi 0:8fdf9a60065b 730 else
kadonotakashi 0:8fdf9a60065b 731 {
kadonotakashi 0:8fdf9a60065b 732 handle->watermark = 1U;
kadonotakashi 0:8fdf9a60065b 733 }
kadonotakashi 0:8fdf9a60065b 734 #else
kadonotakashi 0:8fdf9a60065b 735 handle->watermark = 1U;
kadonotakashi 0:8fdf9a60065b 736 #endif /* FSL_FEATURE_SPI_HAS_FIFO */
kadonotakashi 0:8fdf9a60065b 737
kadonotakashi 0:8fdf9a60065b 738 /* Get the bytes per frame */
kadonotakashi 0:8fdf9a60065b 739 #if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && (FSL_FEATURE_SPI_16BIT_TRANSFERS)
kadonotakashi 0:8fdf9a60065b 740 handle->bytePerFrame = ((base->C2 & SPI_C2_SPIMODE_MASK) >> SPI_C2_SPIMODE_SHIFT) + 1U;
kadonotakashi 0:8fdf9a60065b 741 #else
kadonotakashi 0:8fdf9a60065b 742 handle->bytePerFrame = 1U;
kadonotakashi 0:8fdf9a60065b 743 #endif
kadonotakashi 0:8fdf9a60065b 744
kadonotakashi 0:8fdf9a60065b 745 /* Enable SPI NVIC */
kadonotakashi 0:8fdf9a60065b 746 EnableIRQ(s_spiIRQ[instance]);
kadonotakashi 0:8fdf9a60065b 747 }
kadonotakashi 0:8fdf9a60065b 748
kadonotakashi 0:8fdf9a60065b 749 status_t SPI_MasterTransferNonBlocking(SPI_Type *base, spi_master_handle_t *handle, spi_transfer_t *xfer)
kadonotakashi 0:8fdf9a60065b 750 {
kadonotakashi 0:8fdf9a60065b 751 assert(handle && xfer);
kadonotakashi 0:8fdf9a60065b 752
kadonotakashi 0:8fdf9a60065b 753 /* Check if SPI is busy */
kadonotakashi 0:8fdf9a60065b 754 if (handle->state == kSPI_Busy)
kadonotakashi 0:8fdf9a60065b 755 {
kadonotakashi 0:8fdf9a60065b 756 return kStatus_SPI_Busy;
kadonotakashi 0:8fdf9a60065b 757 }
kadonotakashi 0:8fdf9a60065b 758
kadonotakashi 0:8fdf9a60065b 759 /* Check if the input arguments valid */
kadonotakashi 0:8fdf9a60065b 760 if (((xfer->txData == NULL) && (xfer->rxData == NULL)) || (xfer->dataSize == 0U))
kadonotakashi 0:8fdf9a60065b 761 {
kadonotakashi 0:8fdf9a60065b 762 return kStatus_InvalidArgument;
kadonotakashi 0:8fdf9a60065b 763 }
kadonotakashi 0:8fdf9a60065b 764
kadonotakashi 0:8fdf9a60065b 765 /* Set the handle information */
kadonotakashi 0:8fdf9a60065b 766 handle->txData = xfer->txData;
kadonotakashi 0:8fdf9a60065b 767 handle->rxData = xfer->rxData;
kadonotakashi 0:8fdf9a60065b 768 handle->transferSize = xfer->dataSize;
kadonotakashi 0:8fdf9a60065b 769 handle->txRemainingBytes = xfer->dataSize;
kadonotakashi 0:8fdf9a60065b 770 handle->rxRemainingBytes = xfer->dataSize;
kadonotakashi 0:8fdf9a60065b 771
kadonotakashi 0:8fdf9a60065b 772 /* Set the SPI state to busy */
kadonotakashi 0:8fdf9a60065b 773 handle->state = kSPI_Busy;
kadonotakashi 0:8fdf9a60065b 774
kadonotakashi 0:8fdf9a60065b 775 /* Disable SPI and then enable it, this is used to clear S register*/
kadonotakashi 0:8fdf9a60065b 776 base->C1 &= ~SPI_C1_SPE_MASK;
kadonotakashi 0:8fdf9a60065b 777 base->C1 |= SPI_C1_SPE_MASK;
kadonotakashi 0:8fdf9a60065b 778
kadonotakashi 0:8fdf9a60065b 779 /* Enable Interrupt, only enable Rx interrupt, use rx interrupt to driver SPI transfer */
kadonotakashi 0:8fdf9a60065b 780 #if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO
kadonotakashi 0:8fdf9a60065b 781 if (handle->watermark > 1U)
kadonotakashi 0:8fdf9a60065b 782 {
kadonotakashi 0:8fdf9a60065b 783 /* Enable Rx near full interrupt */
kadonotakashi 0:8fdf9a60065b 784 SPI_EnableInterrupts(base, kSPI_RxFifoNearFullInterruptEnable);
kadonotakashi 0:8fdf9a60065b 785 }
kadonotakashi 0:8fdf9a60065b 786 else
kadonotakashi 0:8fdf9a60065b 787 {
kadonotakashi 0:8fdf9a60065b 788 SPI_EnableInterrupts(base, kSPI_RxFullAndModfInterruptEnable);
kadonotakashi 0:8fdf9a60065b 789 }
kadonotakashi 0:8fdf9a60065b 790 #else
kadonotakashi 0:8fdf9a60065b 791 SPI_EnableInterrupts(base, kSPI_RxFullAndModfInterruptEnable);
kadonotakashi 0:8fdf9a60065b 792 #endif
kadonotakashi 0:8fdf9a60065b 793
kadonotakashi 0:8fdf9a60065b 794 /* First send a piece of data to Tx Data or FIFO to start a SPI transfer */
kadonotakashi 0:8fdf9a60065b 795 SPI_SendTransfer(base, handle);
kadonotakashi 0:8fdf9a60065b 796
kadonotakashi 0:8fdf9a60065b 797 return kStatus_Success;
kadonotakashi 0:8fdf9a60065b 798 }
kadonotakashi 0:8fdf9a60065b 799
kadonotakashi 0:8fdf9a60065b 800 status_t SPI_MasterTransferGetCount(SPI_Type *base, spi_master_handle_t *handle, size_t *count)
kadonotakashi 0:8fdf9a60065b 801 {
kadonotakashi 0:8fdf9a60065b 802 assert(handle);
kadonotakashi 0:8fdf9a60065b 803
kadonotakashi 0:8fdf9a60065b 804 status_t status = kStatus_Success;
kadonotakashi 0:8fdf9a60065b 805
kadonotakashi 0:8fdf9a60065b 806 if (handle->state != kStatus_SPI_Busy)
kadonotakashi 0:8fdf9a60065b 807 {
kadonotakashi 0:8fdf9a60065b 808 status = kStatus_NoTransferInProgress;
kadonotakashi 0:8fdf9a60065b 809 }
kadonotakashi 0:8fdf9a60065b 810 else
kadonotakashi 0:8fdf9a60065b 811 {
kadonotakashi 0:8fdf9a60065b 812 /* Return remaing bytes in different cases */
kadonotakashi 0:8fdf9a60065b 813 if (handle->rxData)
kadonotakashi 0:8fdf9a60065b 814 {
kadonotakashi 0:8fdf9a60065b 815 *count = handle->transferSize - handle->rxRemainingBytes;
kadonotakashi 0:8fdf9a60065b 816 }
kadonotakashi 0:8fdf9a60065b 817 else
kadonotakashi 0:8fdf9a60065b 818 {
kadonotakashi 0:8fdf9a60065b 819 *count = handle->transferSize - handle->txRemainingBytes;
kadonotakashi 0:8fdf9a60065b 820 }
kadonotakashi 0:8fdf9a60065b 821 }
kadonotakashi 0:8fdf9a60065b 822
kadonotakashi 0:8fdf9a60065b 823 return status;
kadonotakashi 0:8fdf9a60065b 824 }
kadonotakashi 0:8fdf9a60065b 825
kadonotakashi 0:8fdf9a60065b 826 void SPI_MasterTransferAbort(SPI_Type *base, spi_master_handle_t *handle)
kadonotakashi 0:8fdf9a60065b 827 {
kadonotakashi 0:8fdf9a60065b 828 assert(handle);
kadonotakashi 0:8fdf9a60065b 829
kadonotakashi 0:8fdf9a60065b 830 /* Stop interrupts */
kadonotakashi 0:8fdf9a60065b 831 #if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO
kadonotakashi 0:8fdf9a60065b 832 if (handle->watermark > 1U)
kadonotakashi 0:8fdf9a60065b 833 {
kadonotakashi 0:8fdf9a60065b 834 SPI_DisableInterrupts(base, kSPI_RxFifoNearFullInterruptEnable | kSPI_RxFullAndModfInterruptEnable);
kadonotakashi 0:8fdf9a60065b 835 }
kadonotakashi 0:8fdf9a60065b 836 else
kadonotakashi 0:8fdf9a60065b 837 {
kadonotakashi 0:8fdf9a60065b 838 SPI_DisableInterrupts(base, kSPI_RxFullAndModfInterruptEnable);
kadonotakashi 0:8fdf9a60065b 839 }
kadonotakashi 0:8fdf9a60065b 840 #else
kadonotakashi 0:8fdf9a60065b 841 SPI_DisableInterrupts(base, kSPI_RxFullAndModfInterruptEnable);
kadonotakashi 0:8fdf9a60065b 842 #endif
kadonotakashi 0:8fdf9a60065b 843
kadonotakashi 0:8fdf9a60065b 844 /* Transfer finished, set the state to Done*/
kadonotakashi 0:8fdf9a60065b 845 handle->state = kSPI_Idle;
kadonotakashi 0:8fdf9a60065b 846
kadonotakashi 0:8fdf9a60065b 847 /* Clear the internal state */
kadonotakashi 0:8fdf9a60065b 848 handle->rxRemainingBytes = 0;
kadonotakashi 0:8fdf9a60065b 849 handle->txRemainingBytes = 0;
kadonotakashi 0:8fdf9a60065b 850 }
kadonotakashi 0:8fdf9a60065b 851
kadonotakashi 0:8fdf9a60065b 852 void SPI_MasterTransferHandleIRQ(SPI_Type *base, spi_master_handle_t *handle)
kadonotakashi 0:8fdf9a60065b 853 {
kadonotakashi 0:8fdf9a60065b 854 assert(handle);
kadonotakashi 0:8fdf9a60065b 855
kadonotakashi 0:8fdf9a60065b 856 /* If needs to receive data, do a receive */
kadonotakashi 0:8fdf9a60065b 857 if (handle->rxRemainingBytes)
kadonotakashi 0:8fdf9a60065b 858 {
kadonotakashi 0:8fdf9a60065b 859 SPI_ReceiveTransfer(base, handle);
kadonotakashi 0:8fdf9a60065b 860 }
kadonotakashi 0:8fdf9a60065b 861
kadonotakashi 0:8fdf9a60065b 862 /* We always need to send a data to make the SPI run */
kadonotakashi 0:8fdf9a60065b 863 if (handle->txRemainingBytes)
kadonotakashi 0:8fdf9a60065b 864 {
kadonotakashi 0:8fdf9a60065b 865 SPI_SendTransfer(base, handle);
kadonotakashi 0:8fdf9a60065b 866 }
kadonotakashi 0:8fdf9a60065b 867
kadonotakashi 0:8fdf9a60065b 868 /* All the transfer finished */
kadonotakashi 0:8fdf9a60065b 869 if ((handle->txRemainingBytes == 0) && (handle->rxRemainingBytes == 0))
kadonotakashi 0:8fdf9a60065b 870 {
kadonotakashi 0:8fdf9a60065b 871 /* Complete the transfer */
kadonotakashi 0:8fdf9a60065b 872 SPI_MasterTransferAbort(base, handle);
kadonotakashi 0:8fdf9a60065b 873
kadonotakashi 0:8fdf9a60065b 874 if (handle->callback)
kadonotakashi 0:8fdf9a60065b 875 {
kadonotakashi 0:8fdf9a60065b 876 (handle->callback)(base, handle, kStatus_SPI_Idle, handle->userData);
kadonotakashi 0:8fdf9a60065b 877 }
kadonotakashi 0:8fdf9a60065b 878 }
kadonotakashi 0:8fdf9a60065b 879 }
kadonotakashi 0:8fdf9a60065b 880
kadonotakashi 0:8fdf9a60065b 881 void SPI_SlaveTransferCreateHandle(SPI_Type *base,
kadonotakashi 0:8fdf9a60065b 882 spi_slave_handle_t *handle,
kadonotakashi 0:8fdf9a60065b 883 spi_slave_callback_t callback,
kadonotakashi 0:8fdf9a60065b 884 void *userData)
kadonotakashi 0:8fdf9a60065b 885 {
kadonotakashi 0:8fdf9a60065b 886 assert(handle);
kadonotakashi 0:8fdf9a60065b 887
kadonotakashi 0:8fdf9a60065b 888 /* Slave create handle share same logic with master create handle, the only difference
kadonotakashi 0:8fdf9a60065b 889 is the Isr pointer. */
kadonotakashi 0:8fdf9a60065b 890 SPI_MasterTransferCreateHandle(base, handle, callback, userData);
kadonotakashi 0:8fdf9a60065b 891 s_spiIsr = SPI_SlaveTransferHandleIRQ;
kadonotakashi 0:8fdf9a60065b 892 }
kadonotakashi 0:8fdf9a60065b 893
kadonotakashi 0:8fdf9a60065b 894 void SPI_SlaveTransferHandleIRQ(SPI_Type *base, spi_slave_handle_t *handle)
kadonotakashi 0:8fdf9a60065b 895 {
kadonotakashi 0:8fdf9a60065b 896 assert(handle);
kadonotakashi 0:8fdf9a60065b 897
kadonotakashi 0:8fdf9a60065b 898 /* Do data send first in case of data missing. */
kadonotakashi 0:8fdf9a60065b 899 if (handle->txRemainingBytes)
kadonotakashi 0:8fdf9a60065b 900 {
kadonotakashi 0:8fdf9a60065b 901 SPI_SendTransfer(base, handle);
kadonotakashi 0:8fdf9a60065b 902 }
kadonotakashi 0:8fdf9a60065b 903
kadonotakashi 0:8fdf9a60065b 904 /* If needs to receive data, do a receive */
kadonotakashi 0:8fdf9a60065b 905 if (handle->rxRemainingBytes)
kadonotakashi 0:8fdf9a60065b 906 {
kadonotakashi 0:8fdf9a60065b 907 SPI_ReceiveTransfer(base, handle);
kadonotakashi 0:8fdf9a60065b 908 }
kadonotakashi 0:8fdf9a60065b 909
kadonotakashi 0:8fdf9a60065b 910 /* All the transfer finished */
kadonotakashi 0:8fdf9a60065b 911 if ((handle->txRemainingBytes == 0) && (handle->rxRemainingBytes == 0))
kadonotakashi 0:8fdf9a60065b 912 {
kadonotakashi 0:8fdf9a60065b 913 /* Complete the transfer */
kadonotakashi 0:8fdf9a60065b 914 SPI_SlaveTransferAbort(base, handle);
kadonotakashi 0:8fdf9a60065b 915
kadonotakashi 0:8fdf9a60065b 916 if (handle->callback)
kadonotakashi 0:8fdf9a60065b 917 {
kadonotakashi 0:8fdf9a60065b 918 (handle->callback)(base, handle, kStatus_SPI_Idle, handle->userData);
kadonotakashi 0:8fdf9a60065b 919 }
kadonotakashi 0:8fdf9a60065b 920 }
kadonotakashi 0:8fdf9a60065b 921 }
kadonotakashi 0:8fdf9a60065b 922
kadonotakashi 0:8fdf9a60065b 923 #if defined(SPI0)
kadonotakashi 0:8fdf9a60065b 924 void SPI0_DriverIRQHandler(void)
kadonotakashi 0:8fdf9a60065b 925 {
kadonotakashi 0:8fdf9a60065b 926 assert(s_spiHandle[0]);
kadonotakashi 0:8fdf9a60065b 927 s_spiIsr(SPI0, s_spiHandle[0]);
kadonotakashi 0:8fdf9a60065b 928 }
kadonotakashi 0:8fdf9a60065b 929 #endif
kadonotakashi 0:8fdf9a60065b 930
kadonotakashi 0:8fdf9a60065b 931 #if defined(SPI1)
kadonotakashi 0:8fdf9a60065b 932 void SPI1_DriverIRQHandler(void)
kadonotakashi 0:8fdf9a60065b 933 {
kadonotakashi 0:8fdf9a60065b 934 assert(s_spiHandle[1]);
kadonotakashi 0:8fdf9a60065b 935 s_spiIsr(SPI1, s_spiHandle[1]);
kadonotakashi 0:8fdf9a60065b 936 }
kadonotakashi 0:8fdf9a60065b 937 #endif
kadonotakashi 0:8fdf9a60065b 938
kadonotakashi 0:8fdf9a60065b 939 #if defined(SPI2)
kadonotakashi 0:8fdf9a60065b 940 void SPI2_DriverIRQHandler(void)
kadonotakashi 0:8fdf9a60065b 941 {
kadonotakashi 0:8fdf9a60065b 942 assert(s_spiHandle[2]);
kadonotakashi 0:8fdf9a60065b 943 s_spiIsr(SPI0, s_spiHandle[2]);
kadonotakashi 0:8fdf9a60065b 944 }
kadonotakashi 0:8fdf9a60065b 945 #endif