Skip to content

Commit 1fe6c2f

Browse files
committed
KL27Z: Update the SPI driver
1.Fix SPI flag name error 2.Fix SPI write blocking function 3.Use function pointer to implement SPI IRQ handler to reduce code size Signed-off-by: Mahadevan Mahesh <[email protected]>
1 parent 8568c9e commit 1fe6c2f

File tree

2 files changed

+123
-52
lines changed

2 files changed

+123
-52
lines changed

hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL27Z/drivers/fsl_spi.c

Lines changed: 104 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ enum _spi_transfer_states_t
4040
kSPI_Busy /*!< SPI is busy tranferring data. */
4141
};
4242

43+
/*! @brief Typedef for spi master interrupt handler. spi master and slave handle is the same. */
44+
typedef void (*spi_isr_t)(SPI_Type *base, spi_master_handle_t *spiHandle);
45+
4346
/*******************************************************************************
4447
* Prototypes
4548
******************************************************************************/
@@ -92,15 +95,18 @@ static void SPI_ReceiveTransfer(SPI_Type *base, spi_master_handle_t *handle);
9295
/*******************************************************************************
9396
* Variables
9497
******************************************************************************/
95-
/* SPI internal handle pointer array */
98+
/*! @brief SPI internal handle pointer array */
9699
static spi_master_handle_t *s_spiHandle[FSL_FEATURE_SOC_SPI_COUNT];
97-
/* Base pointer array */
100+
/*! @brief Base pointer array */
98101
static SPI_Type *const s_spiBases[] = SPI_BASE_PTRS;
99-
/* IRQ name array */
102+
/*! @brief IRQ name array */
100103
static const IRQn_Type s_spiIRQ[] = SPI_IRQS;
101-
/* Clock array name */
104+
/*! @brief Clock array name */
102105
static const clock_ip_name_t s_spiClock[] = SPI_CLOCKS;
103106

107+
/*! @brief Pointer to master IRQ handler for each instance. */
108+
static spi_isr_t s_spiIsr;
109+
104110
/*******************************************************************************
105111
* Code
106112
******************************************************************************/
@@ -202,36 +208,64 @@ static void SPI_ReadNonBlocking(SPI_Type *base, uint8_t *buffer, size_t size)
202208
static void SPI_SendTransfer(SPI_Type *base, spi_master_handle_t *handle)
203209
{
204210
uint8_t bytes = MIN((handle->watermark * 2U), handle->txRemainingBytes);
205-
uint8_t val = 1U;
206211

207212
/* Read S register and ensure SPTEF is 1, otherwise the write would be ignored. */
208213
if (handle->watermark == 1U)
209214
{
210-
val = (base->S & SPI_S_SPTEF_MASK);
211215
if (bytes != 0U)
212216
{
213217
bytes = handle->bytePerFrame;
214218
}
219+
220+
/* Send data */
221+
if (base->C1 & SPI_C1_MSTR_MASK)
222+
{
223+
/* As a master, only write once */
224+
if (base->S & SPI_S_SPTEF_MASK)
225+
{
226+
SPI_WriteNonBlocking(base, handle->txData, bytes);
227+
/* Update handle information */
228+
if (handle->txData)
229+
{
230+
handle->txData += bytes;
231+
}
232+
handle->txRemainingBytes -= bytes;
233+
}
215234
}
216-
#if defined(FSL_FEATURE_SPI_HAS_FIFO) && (FSL_FEATURE_SPI_HAS_FIFO)
217235
else
218236
{
219-
val = (base->S & SPI_S_TNEAREF_MASK);
237+
/* As a slave, send data until SPTEF cleared */
238+
while ((base->S & SPI_S_SPTEF_MASK) && (handle->txRemainingBytes > 0))
239+
{
240+
SPI_WriteNonBlocking(base, handle->txData, bytes);
241+
242+
/* Update handle information */
243+
if (handle->txData)
244+
{
245+
handle->txData += bytes;
246+
}
247+
handle->txRemainingBytes -= bytes;
248+
}
249+
}
220250
}
221-
#endif
222251

223-
/* Write data */
224-
if (val)
252+
#if defined(FSL_FEATURE_SPI_HAS_FIFO) && (FSL_FEATURE_SPI_HAS_FIFO)
253+
/* If use FIFO */
254+
else
225255
{
226-
SPI_WriteNonBlocking(base, handle->txData, bytes);
227-
228-
/* Update handle information */
229-
if (handle->txData)
256+
if (base->S & SPI_S_TNEAREF_MASK)
230257
{
231-
handle->txData += bytes;
258+
SPI_WriteNonBlocking(base, handle->txData, bytes);
259+
260+
/* Update handle information */
261+
if (handle->txData)
262+
{
263+
handle->txData += bytes;
264+
}
265+
handle->txRemainingBytes -= bytes;
232266
}
233-
handle->txRemainingBytes -= bytes;
234267
}
268+
#endif
235269
}
236270

237271
static void SPI_ReceiveTransfer(SPI_Type *base, spi_master_handle_t *handle)
@@ -286,6 +320,8 @@ void SPI_MasterGetDefaultConfig(spi_master_config_t *config)
286320

287321
void SPI_MasterInit(SPI_Type *base, const spi_master_config_t *config, uint32_t srcClock_Hz)
288322
{
323+
assert(config && srcClock_Hz);
324+
289325
/* Open clock gate for SPI and open interrupt */
290326
CLOCK_EnableClock(s_spiClock[SPI_GetInstance(base)]);
291327

@@ -345,6 +381,8 @@ void SPI_SlaveGetDefaultConfig(spi_slave_config_t *config)
345381

346382
void SPI_SlaveInit(SPI_Type *base, const spi_slave_config_t *config)
347383
{
384+
assert(config);
385+
348386
/* Open clock gate for SPI and open interrupt */
349387
CLOCK_EnableClock(s_spiClock[SPI_GetInstance(base)]);
350388

@@ -536,21 +574,24 @@ void SPI_MasterSetBaudRate(SPI_Type *base, uint32_t baudRate_Bps, uint32_t srcCl
536574
void SPI_WriteBlocking(SPI_Type *base, uint8_t *buffer, size_t size)
537575
{
538576
uint32_t i = 0;
577+
uint8_t bytesPerFrame = 1U;
578+
579+
#if defined(FSL_FEATURE_SPI_16BIT_TRANSFERS) && FSL_FEATURE_SPI_16BIT_TRANSFERS
580+
/* Check if 16 bits or 8 bits */
581+
bytesPerFrame = ((base->C2 & SPI_C2_SPIMODE_MASK) >> SPI_C2_SPIMODE_SHIFT) + 1U;
582+
#endif
539583

540584
while (i < size)
541585
{
542586
while ((base->S & SPI_S_SPTEF_MASK) == 0)
543587
{
544588
}
545589

546-
/* Send data */
547-
SPI_WriteNonBlocking(base, buffer, size);
590+
/* Send a frame of data */
591+
SPI_WriteNonBlocking(base, buffer, bytesPerFrame);
548592

549-
/* Wait the data to be sent */
550-
while ((base->S & SPI_S_SPTEF_MASK) == 0)
551-
{
552-
}
553-
i++;
593+
i += bytesPerFrame;
594+
buffer += bytesPerFrame;
554595
}
555596
}
556597

@@ -668,6 +709,7 @@ void SPI_MasterTransferCreateHandle(SPI_Type *base,
668709
s_spiHandle[instance] = handle;
669710
handle->callback = callback;
670711
handle->userData = userData;
712+
s_spiIsr = SPI_MasterTransferHandleIRQ;
671713

672714
#if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO
673715
uint8_t txSize = 0U;
@@ -836,38 +878,68 @@ void SPI_MasterTransferHandleIRQ(SPI_Type *base, spi_master_handle_t *handle)
836878
}
837879
}
838880

839-
static void SPI_TransferCommonIRQHandler(SPI_Type *base, void *handle)
881+
void SPI_SlaveTransferCreateHandle(SPI_Type *base,
882+
spi_slave_handle_t *handle,
883+
spi_slave_callback_t callback,
884+
void *userData)
885+
{
886+
assert(handle);
887+
888+
/* Slave create handle share same logic with master create handle, the only difference
889+
is the Isr pointer. */
890+
SPI_MasterTransferCreateHandle(base, handle, callback, userData);
891+
s_spiIsr = SPI_SlaveTransferHandleIRQ;
892+
}
893+
894+
void SPI_SlaveTransferHandleIRQ(SPI_Type *base, spi_slave_handle_t *handle)
840895
{
841-
if (base->C1 & SPI_C1_MSTR_MASK)
896+
assert(handle);
897+
898+
/* Do data send first in case of data missing. */
899+
if (handle->txRemainingBytes)
900+
{
901+
SPI_SendTransfer(base, handle);
902+
}
903+
904+
/* If needs to receive data, do a receive */
905+
if (handle->rxRemainingBytes)
842906
{
843-
SPI_MasterTransferHandleIRQ(base, (spi_master_handle_t *)handle);
907+
SPI_ReceiveTransfer(base, handle);
844908
}
845-
else
909+
910+
/* All the transfer finished */
911+
if ((handle->txRemainingBytes == 0) && (handle->rxRemainingBytes == 0))
846912
{
847-
SPI_SlaveTransferHandleIRQ(base, (spi_slave_handle_t *)handle);
913+
/* Complete the transfer */
914+
SPI_SlaveTransferAbort(base, handle);
915+
916+
if (handle->callback)
917+
{
918+
(handle->callback)(base, handle, kStatus_SPI_Idle, handle->userData);
919+
}
848920
}
849921
}
850922

851923
#if defined(SPI0)
852924
void SPI0_DriverIRQHandler(void)
853925
{
854926
assert(s_spiHandle[0]);
855-
SPI_TransferCommonIRQHandler(SPI0, s_spiHandle[0]);
927+
s_spiIsr(SPI0, s_spiHandle[0]);
856928
}
857929
#endif
858930

859931
#if defined(SPI1)
860932
void SPI1_DriverIRQHandler(void)
861933
{
862934
assert(s_spiHandle[1]);
863-
SPI_TransferCommonIRQHandler(SPI1, s_spiHandle[1]);
935+
s_spiIsr(SPI1, s_spiHandle[1]);
864936
}
865937
#endif
866938

867939
#if defined(SPI2)
868940
void SPI2_DriverIRQHandler(void)
869941
{
870942
assert(s_spiHandle[2]);
871-
SPI_TransferCommonIRQHandler(SPI0, s_spiHandle[2]);
943+
s_spiIsr(SPI0, s_spiHandle[2]);
872944
}
873945
#endif

hal/targets/hal/TARGET_Freescale/TARGET_KSDK2_MCUS/TARGET_KL27Z/drivers/fsl_spi.h

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -37,20 +37,21 @@
3737
* @{
3838
*/
3939

40-
/*! @file */
4140

4241
/*******************************************************************************
4342
* Definitions
4443
******************************************************************************/
4544

4645
/*! @name Driver version */
4746
/*@{*/
48-
/*! @brief SPI driver version 2.0.0. */
49-
#define FSL_SPI_DRIVER_VERSION (MAKE_VERSION(2, 0, 0))
47+
/*! @brief SPI driver version 2.0.1. */
48+
#define FSL_SPI_DRIVER_VERSION (MAKE_VERSION(2, 0, 1))
5049
/*@}*/
5150

51+
#ifndef SPI_DUMMYDATA
5252
/*! @brief SPI dummy transfer data, the data is sent while txBuff is NULL. */
5353
#define SPI_DUMMYDATA (0xFFU)
54+
#endif
5455

5556
/*! @brief Return status for the SPI driver.*/
5657
enum _spi_status
@@ -130,10 +131,10 @@ enum _spi_flags
130131
#if defined(FSL_FEATURE_SPI_HAS_FIFO) && FSL_FEATURE_SPI_HAS_FIFO
131132
kSPI_RxFifoNearFullFlag = SPI_S_RNFULLF_MASK, /*!< Rx FIFO near full */
132133
kSPI_TxFifoNearEmptyFlag = SPI_S_TNEAREF_MASK, /*!< Tx FIFO near empty */
133-
kSPI_RxFifoFullFlag = SPI_S_TXFULLF_MASK, /*!< Rx FIFO full */
134-
kSPI_TxFifoEmptyFlag = SPI_S_RFIFOEF_MASK, /*!< Tx FIFO empty */
134+
kSPI_TxFifoFullFlag = SPI_S_TXFULLF_MASK, /*!< Tx FIFO full */
135+
kSPI_RxFifoEmptyFlag = SPI_S_RFIFOEF_MASK, /*!< Rx FIFO empty */
135136
kSPI_TxFifoError = SPI_CI_TXFERR_MASK << 8U, /*!< Tx FIFO error */
136-
kSPI_RxFifoError = SPI_CI_RXFERR_MASK << 8U, /*!< Rx FIFO Overflow */
137+
kSPI_RxFifoError = SPI_CI_RXFERR_MASK << 8U, /*!< Rx FIFO error */
137138
kSPI_TxOverflow = SPI_CI_TXFOF_MASK << 8U, /*!< Tx FIFO Overflow */
138139
kSPI_RxOverflow = SPI_CI_RXFOF_MASK << 8U /*!< Rx FIFO Overflow */
139140
#endif /* FSL_FEATURE_SPI_HAS_FIFO */
@@ -347,7 +348,7 @@ void SPI_Deinit(SPI_Type *base);
347348
* @param base SPI base pointer
348349
* @param enable pass true to enable module, false to disable module
349350
*/
350-
static inline void SPI_Enable(I2C_Type *base, bool enable)
351+
static inline void SPI_Enable(SPI_Type *base, bool enable)
351352
{
352353
if (enable)
353354
{
@@ -581,8 +582,10 @@ status_t SPI_MasterTransferBlocking(SPI_Type *base, spi_transfer_t *xfer);
581582
*
582583
* @note The API immediately returns after transfer initialization is finished.
583584
* Call SPI_GetStatusIRQ() to get the transfer status.
584-
* @note If using the SPI with FIFO for the interrupt transfer, the transfer size is the integer times of the watermark. Otherwise,
585-
* the last data may be lost because it cannot generate an interrupt request. Users can also call the functional API to get the last
585+
* @note If using the SPI with FIFO for the interrupt transfer, the transfer size is the integer times of the watermark.
586+
* Otherwise,
587+
* the last data may be lost because it cannot generate an interrupt request. Users can also call the functional API to
588+
* get the last
586589
* received data.
587590
*
588591
* @param base SPI peripheral base address.
@@ -632,21 +635,20 @@ void SPI_MasterTransferHandleIRQ(SPI_Type *base, spi_master_handle_t *handle);
632635
* @param callback Callback function.
633636
* @param userData User data.
634637
*/
635-
static inline void SPI_SlaveTransferCreateHandle(SPI_Type *base,
638+
void SPI_SlaveTransferCreateHandle(SPI_Type *base,
636639
spi_slave_handle_t *handle,
637640
spi_slave_callback_t callback,
638-
void *userData)
639-
{
640-
SPI_MasterTransferCreateHandle(base, handle, callback, userData);
641-
}
641+
void *userData);
642642

643643
/*!
644644
* @brief Performs a non-blocking SPI slave interrupt transfer.
645645
*
646646
* @note The API returns immediately after the transfer initialization is finished.
647647
* Call SPI_GetStatusIRQ() to get the transfer status.
648-
* @note If using the SPI with FIFO for the interrupt transfer, the transfer size is the integer times the watermark. Otherwise,
649-
* the last data may be lost because it cannot generate an interrupt request. Call the functional API to get the last several
648+
* @note If using the SPI with FIFO for the interrupt transfer, the transfer size is the integer times the watermark.
649+
* Otherwise,
650+
* the last data may be lost because it cannot generate an interrupt request. Call the functional API to get the last
651+
* several
650652
* receive data.
651653
*
652654
* @param base SPI peripheral base address.
@@ -692,10 +694,7 @@ static inline void SPI_SlaveTransferAbort(SPI_Type *base, spi_slave_handle_t *ha
692694
* @param base SPI peripheral base address.
693695
* @param handle pointer to spi_slave_handle_t structure which stores the transfer state
694696
*/
695-
static inline void SPI_SlaveTransferHandleIRQ(SPI_Type *base, spi_slave_handle_t *handle)
696-
{
697-
SPI_MasterTransferHandleIRQ(base, handle);
698-
}
697+
void SPI_SlaveTransferHandleIRQ(SPI_Type *base, spi_slave_handle_t *handle);
699698

700699
/*! @} */
701700

0 commit comments

Comments
 (0)