@@ -40,6 +40,9 @@ enum _spi_transfer_states_t
40
40
kSPI_Busy /*!< SPI is busy tranferring data. */
41
41
};
42
42
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
+
43
46
/*******************************************************************************
44
47
* Prototypes
45
48
******************************************************************************/
@@ -92,15 +95,18 @@ static void SPI_ReceiveTransfer(SPI_Type *base, spi_master_handle_t *handle);
92
95
/*******************************************************************************
93
96
* Variables
94
97
******************************************************************************/
95
- /* SPI internal handle pointer array */
98
+ /*! @brief SPI internal handle pointer array */
96
99
static spi_master_handle_t * s_spiHandle [FSL_FEATURE_SOC_SPI_COUNT ];
97
- /* Base pointer array */
100
+ /*! @brief Base pointer array */
98
101
static SPI_Type * const s_spiBases [] = SPI_BASE_PTRS ;
99
- /* IRQ name array */
102
+ /*! @brief IRQ name array */
100
103
static const IRQn_Type s_spiIRQ [] = SPI_IRQS ;
101
- /* Clock array name */
104
+ /*! @brief Clock array name */
102
105
static const clock_ip_name_t s_spiClock [] = SPI_CLOCKS ;
103
106
107
+ /*! @brief Pointer to master IRQ handler for each instance. */
108
+ static spi_isr_t s_spiIsr ;
109
+
104
110
/*******************************************************************************
105
111
* Code
106
112
******************************************************************************/
@@ -202,36 +208,64 @@ static void SPI_ReadNonBlocking(SPI_Type *base, uint8_t *buffer, size_t size)
202
208
static void SPI_SendTransfer (SPI_Type * base , spi_master_handle_t * handle )
203
209
{
204
210
uint8_t bytes = MIN ((handle -> watermark * 2U ), handle -> txRemainingBytes );
205
- uint8_t val = 1U ;
206
211
207
212
/* Read S register and ensure SPTEF is 1, otherwise the write would be ignored. */
208
213
if (handle -> watermark == 1U )
209
214
{
210
- val = (base -> S & SPI_S_SPTEF_MASK );
211
215
if (bytes != 0U )
212
216
{
213
217
bytes = handle -> bytePerFrame ;
214
218
}
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
+ }
215
234
}
216
- #if defined(FSL_FEATURE_SPI_HAS_FIFO ) && (FSL_FEATURE_SPI_HAS_FIFO )
217
235
else
218
236
{
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
+ }
220
250
}
221
- #endif
222
251
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
225
255
{
226
- SPI_WriteNonBlocking (base , handle -> txData , bytes );
227
-
228
- /* Update handle information */
229
- if (handle -> txData )
256
+ if (base -> S & SPI_S_TNEAREF_MASK )
230
257
{
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 ;
232
266
}
233
- handle -> txRemainingBytes -= bytes ;
234
267
}
268
+ #endif
235
269
}
236
270
237
271
static void SPI_ReceiveTransfer (SPI_Type * base , spi_master_handle_t * handle )
@@ -286,6 +320,8 @@ void SPI_MasterGetDefaultConfig(spi_master_config_t *config)
286
320
287
321
void SPI_MasterInit (SPI_Type * base , const spi_master_config_t * config , uint32_t srcClock_Hz )
288
322
{
323
+ assert (config && srcClock_Hz );
324
+
289
325
/* Open clock gate for SPI and open interrupt */
290
326
CLOCK_EnableClock (s_spiClock [SPI_GetInstance (base )]);
291
327
@@ -345,6 +381,8 @@ void SPI_SlaveGetDefaultConfig(spi_slave_config_t *config)
345
381
346
382
void SPI_SlaveInit (SPI_Type * base , const spi_slave_config_t * config )
347
383
{
384
+ assert (config );
385
+
348
386
/* Open clock gate for SPI and open interrupt */
349
387
CLOCK_EnableClock (s_spiClock [SPI_GetInstance (base )]);
350
388
@@ -536,21 +574,24 @@ void SPI_MasterSetBaudRate(SPI_Type *base, uint32_t baudRate_Bps, uint32_t srcCl
536
574
void SPI_WriteBlocking (SPI_Type * base , uint8_t * buffer , size_t size )
537
575
{
538
576
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
539
583
540
584
while (i < size )
541
585
{
542
586
while ((base -> S & SPI_S_SPTEF_MASK ) == 0 )
543
587
{
544
588
}
545
589
546
- /* Send data */
547
- SPI_WriteNonBlocking (base , buffer , size );
590
+ /* Send a frame of data */
591
+ SPI_WriteNonBlocking (base , buffer , bytesPerFrame );
548
592
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 ;
554
595
}
555
596
}
556
597
@@ -668,6 +709,7 @@ void SPI_MasterTransferCreateHandle(SPI_Type *base,
668
709
s_spiHandle [instance ] = handle ;
669
710
handle -> callback = callback ;
670
711
handle -> userData = userData ;
712
+ s_spiIsr = SPI_MasterTransferHandleIRQ ;
671
713
672
714
#if defined(FSL_FEATURE_SPI_HAS_FIFO ) && FSL_FEATURE_SPI_HAS_FIFO
673
715
uint8_t txSize = 0U ;
@@ -836,38 +878,68 @@ void SPI_MasterTransferHandleIRQ(SPI_Type *base, spi_master_handle_t *handle)
836
878
}
837
879
}
838
880
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 )
840
895
{
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 )
842
906
{
843
- SPI_MasterTransferHandleIRQ (base , ( spi_master_handle_t * ) handle );
907
+ SPI_ReceiveTransfer (base , handle );
844
908
}
845
- else
909
+
910
+ /* All the transfer finished */
911
+ if ((handle -> txRemainingBytes == 0 ) && (handle -> rxRemainingBytes == 0 ))
846
912
{
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
+ }
848
920
}
849
921
}
850
922
851
923
#if defined(SPI0 )
852
924
void SPI0_DriverIRQHandler (void )
853
925
{
854
926
assert (s_spiHandle [0 ]);
855
- SPI_TransferCommonIRQHandler (SPI0 , s_spiHandle [0 ]);
927
+ s_spiIsr (SPI0 , s_spiHandle [0 ]);
856
928
}
857
929
#endif
858
930
859
931
#if defined(SPI1 )
860
932
void SPI1_DriverIRQHandler (void )
861
933
{
862
934
assert (s_spiHandle [1 ]);
863
- SPI_TransferCommonIRQHandler (SPI1 , s_spiHandle [1 ]);
935
+ s_spiIsr (SPI1 , s_spiHandle [1 ]);
864
936
}
865
937
#endif
866
938
867
939
#if defined(SPI2 )
868
940
void SPI2_DriverIRQHandler (void )
869
941
{
870
942
assert (s_spiHandle [2 ]);
871
- SPI_TransferCommonIRQHandler (SPI0 , s_spiHandle [2 ]);
943
+ s_spiIsr (SPI0 , s_spiHandle [2 ]);
872
944
}
873
945
#endif
0 commit comments