@@ -52,6 +52,41 @@ static void FLEXIO_SPI_TransferSendTransaction(FLEXIO_SPI_Type *base, flexio_spi
52
52
*/
53
53
static void FLEXIO_SPI_TransferReceiveTransaction (FLEXIO_SPI_Type * base , flexio_spi_master_handle_t * handle );
54
54
55
+ /*!
56
+ * @brief Set the Timer 1 register TIMCFG
57
+ *
58
+ * This function is used for master mode. It sets the Timer 1 (used to control CS pin)
59
+ * TIMCFG register based on CS continous mode configuration, and return the old
60
+ * register value, for later recovery.
61
+ *
62
+ * @param base Pointer to FLEXIO_SPI_Type structure
63
+ * @param csContinuous Use CS continuous mode or not.
64
+ * @return The old TIMCFG register value.
65
+ */
66
+ static uint32_t FLEXIO_SPI_MasterSetTimer1Cfg (FLEXIO_SPI_Type * base , bool csContinuous );
67
+
68
+ /*!
69
+ * @brief Recover the Timer 1 register TIMCFG
70
+ *
71
+ * This function is used for master mode. It recovers the TIMCFG register using
72
+ * the value got by @ref FLEXIO_SPI_MasterSetTimer1Cfg.
73
+ *
74
+ * @param base Pointer to FLEXIO_SPI_Type structure
75
+ * @param The old TIMCFG register value.
76
+ */
77
+ static void FLEXIO_SPI_MasterRecoverTimer1Cfg (FLEXIO_SPI_Type * base , uint32_t timer1Cfg );
78
+
79
+ /*!
80
+ * @brief Force disable the Timer 1 register TIMCFG
81
+ *
82
+ * This function is used for master mode CS continuous mode. In this mode,
83
+ * the timer1 is set to kFLEXIO_TimerDisableNever, so after all data transfer
84
+ * done, this function should be called to disable the timer1.
85
+ *
86
+ * @param base Pointer to FLEXIO_SPI_Type structure
87
+ */
88
+ static void FLEXIO_SPI_MasterForceDisableTimer1 (FLEXIO_SPI_Type * base );
89
+
55
90
/*******************************************************************************
56
91
* Variables
57
92
******************************************************************************/
@@ -60,6 +95,64 @@ static void FLEXIO_SPI_TransferReceiveTransaction(FLEXIO_SPI_Type *base, flexio_
60
95
* Codes
61
96
******************************************************************************/
62
97
98
+ static uint32_t FLEXIO_SPI_MasterSetTimer1Cfg (FLEXIO_SPI_Type * base , bool csContinuous )
99
+ {
100
+ uint32_t timer1Cfg = base -> flexioBase -> TIMCFG [base -> timerIndex [1 ]];
101
+
102
+ /*
103
+ * Timer1 configuration for CS continuous and non-continuous modes.
104
+ *
105
+ * CS pin is configured to be logical one when timer1 enabled, so the
106
+ * keypoint is:
107
+ * - In CS non-continuous mode, set timers only enabled when the data frame
108
+ * transfer is in progress.
109
+ * - In CS continuous mode, set timer1 always enabled during data transfer.
110
+ *
111
+ * Non-continuous mode:
112
+ * In this mode, enable timer1 when timer0 is enabled, and disable timer1
113
+ * when timer0 is disabled. Timer0 controls SCK, it is enabled/disabled
114
+ * when a data frame starts/stops, so timer1 is only enabled when
115
+ * one data frame transfer is in progress.
116
+ *
117
+ * Continuous mode:
118
+ * In this mode, enable timer1 when timer0 is enabled, in other word, timer1
119
+ * will be enabled at the beginning of the whole data transfer. Timer1
120
+ * will never be disabled, until FLEXIO_SPI_MasterForceDisableTimer1 is called
121
+ * after all data transfer done. Also, the TIMDEC is set to
122
+ * kFLEXIO_TimerDecSrcOnPinInputShiftPinInput, so that the timer won't
123
+ * decrease in the whole process.
124
+ */
125
+
126
+ if (csContinuous )
127
+ {
128
+ base -> flexioBase -> TIMCFG [base -> timerIndex [1 ]] =
129
+ (base -> flexioBase -> TIMCFG [base -> timerIndex [1 ]] & ~(FLEXIO_TIMCFG_TIMDIS_MASK | FLEXIO_TIMCFG_TIMDEC_MASK )) |
130
+ FLEXIO_TIMCFG_TIMDIS (kFLEXIO_TimerDisableNever ) |
131
+ FLEXIO_TIMCFG_TIMDEC (kFLEXIO_TimerDecSrcOnPinInputShiftPinInput );
132
+ }
133
+ else
134
+ {
135
+ base -> flexioBase -> TIMCFG [base -> timerIndex [1 ]] =
136
+ (base -> flexioBase -> TIMCFG [base -> timerIndex [1 ]] & ~(FLEXIO_TIMCFG_TIMDIS_MASK | FLEXIO_TIMCFG_TIMDEC_MASK )) |
137
+ FLEXIO_TIMCFG_TIMDIS (kFLEXIO_TimerDisableOnPreTimerDisable ) |
138
+ FLEXIO_TIMCFG_TIMDEC (kFLEXIO_TimerDecSrcOnFlexIOClockShiftTimerOutput );
139
+ }
140
+
141
+ return timer1Cfg ;
142
+ }
143
+
144
+ static void FLEXIO_SPI_MasterRecoverTimer1Cfg (FLEXIO_SPI_Type * base , uint32_t timer1Cfg )
145
+ {
146
+ base -> flexioBase -> TIMCFG [base -> timerIndex [1 ]] = timer1Cfg ;
147
+ }
148
+
149
+ static void FLEXIO_SPI_MasterForceDisableTimer1 (FLEXIO_SPI_Type * base )
150
+ {
151
+ uint32_t timctl = base -> flexioBase -> TIMCTL [base -> timerIndex [1 ]];
152
+ base -> flexioBase -> TIMCTL [base -> timerIndex [1 ]] = timctl & (~FLEXIO_TIMCTL_TIMOD_MASK );
153
+ base -> flexioBase -> TIMCTL [base -> timerIndex [1 ]] = timctl ;
154
+ }
155
+
63
156
static uint32_t FLEXIO_SPI_GetInstance (FLEXIO_SPI_Type * base )
64
157
{
65
158
return FLEXIO_GetInstance (base -> flexioBase );
@@ -813,21 +906,11 @@ status_t FLEXIO_SPI_MasterTransferBlocking(FLEXIO_SPI_Type *base, flexio_spi_tra
813
906
#if SPI_RETRY_TIMES
814
907
uint32_t waitTimes ;
815
908
#endif
909
+ status_t status = kStatus_Success ;
910
+ bool isCsContinuous = ((xfer -> flags & (uint8_t )kFLEXIO_SPI_csContinuous ) != 0U );
816
911
817
912
timerCmp &= 0x00FFU ;
818
-
819
- if ((xfer -> flags & (uint8_t )kFLEXIO_SPI_csContinuous ) != 0U )
820
- {
821
- base -> flexioBase -> TIMCFG [base -> timerIndex [0 ]] =
822
- (base -> flexioBase -> TIMCFG [base -> timerIndex [0 ]] & ~FLEXIO_TIMCFG_TSTOP_MASK ) |
823
- FLEXIO_TIMCFG_TSTOP (kFLEXIO_TimerStopBitDisabled );
824
- }
825
- else
826
- {
827
- base -> flexioBase -> TIMCFG [base -> timerIndex [0 ]] =
828
- (base -> flexioBase -> TIMCFG [base -> timerIndex [0 ]] & ~FLEXIO_TIMCFG_TSTOP_MASK ) |
829
- FLEXIO_TIMCFG_TSTOP (kFLEXIO_TimerStopBitEnableOnTimerDisable );
830
- }
913
+ uint32_t timer1Cfg ;
831
914
832
915
/* Configure the values in handle. */
833
916
switch (dataFormat )
@@ -884,6 +967,8 @@ status_t FLEXIO_SPI_MasterTransferBlocking(FLEXIO_SPI_Type *base, flexio_spi_tra
884
967
return kStatus_InvalidArgument ;
885
968
}
886
969
970
+ timer1Cfg = FLEXIO_SPI_MasterSetTimer1Cfg (base , isCsContinuous );
971
+
887
972
/* Configure transfer size. */
888
973
base -> flexioBase -> TIMCMP [base -> timerIndex [0 ]] = dataMode ;
889
974
@@ -902,7 +987,8 @@ status_t FLEXIO_SPI_MasterTransferBlocking(FLEXIO_SPI_Type *base, flexio_spi_tra
902
987
#if SPI_RETRY_TIMES
903
988
if (waitTimes == 0U )
904
989
{
905
- return kStatus_FLEXIO_SPI_Timeout ;
990
+ status = kStatus_FLEXIO_SPI_Timeout ;
991
+ break ;
906
992
}
907
993
#endif
908
994
if (xfer -> txData != NULL )
@@ -967,7 +1053,8 @@ status_t FLEXIO_SPI_MasterTransferBlocking(FLEXIO_SPI_Type *base, flexio_spi_tra
967
1053
#if SPI_RETRY_TIMES
968
1054
if (waitTimes == 0U )
969
1055
{
970
- return kStatus_FLEXIO_SPI_Timeout ;
1056
+ status = kStatus_FLEXIO_SPI_Timeout ;
1057
+ break ;
971
1058
}
972
1059
#endif
973
1060
tmpData = FLEXIO_SPI_ReadData (base , direction );
@@ -1020,7 +1107,14 @@ status_t FLEXIO_SPI_MasterTransferBlocking(FLEXIO_SPI_Type *base, flexio_spi_tra
1020
1107
}
1021
1108
}
1022
1109
1023
- return kStatus_Success ;
1110
+ if (isCsContinuous )
1111
+ {
1112
+ FLEXIO_SPI_MasterForceDisableTimer1 (base );
1113
+ }
1114
+
1115
+ FLEXIO_SPI_MasterRecoverTimer1Cfg (base , timer1Cfg );
1116
+
1117
+ return status ;
1024
1118
}
1025
1119
1026
1120
/*!
@@ -1097,24 +1191,9 @@ status_t FLEXIO_SPI_MasterTransferNonBlocking(FLEXIO_SPI_Type *base,
1097
1191
return kStatus_InvalidArgument ;
1098
1192
}
1099
1193
1100
- /* Timer1 controls the CS signal which enables/disables(asserts/deasserts) when timer0 enable/disable. Timer0
1101
- enables when tx shifter is written and disables when timer compare. The timer compare event causes the
1102
- transmit shift registers to load which generates a tx register empty event. Since when timer stop bit is
1103
- disabled, a timer enable condition can be detected in the same cycle as a timer disable condition, so if
1104
- software writes the tx register upon the detection of tx register empty event, the timer enable condition
1105
- is triggered again, then the CS signal can remain low until software no longer writes the tx register. */
1106
- if ((xfer -> flags & (uint8_t )kFLEXIO_SPI_csContinuous ) != 0U )
1107
- {
1108
- base -> flexioBase -> TIMCFG [base -> timerIndex [0 ]] =
1109
- (base -> flexioBase -> TIMCFG [base -> timerIndex [0 ]] & ~FLEXIO_TIMCFG_TSTOP_MASK ) |
1110
- FLEXIO_TIMCFG_TSTOP (kFLEXIO_TimerStopBitDisabled );
1111
- }
1112
- else
1113
- {
1114
- base -> flexioBase -> TIMCFG [base -> timerIndex [0 ]] =
1115
- (base -> flexioBase -> TIMCFG [base -> timerIndex [0 ]] & ~FLEXIO_TIMCFG_TSTOP_MASK ) |
1116
- FLEXIO_TIMCFG_TSTOP (kFLEXIO_TimerStopBitEnableOnTimerDisable );
1117
- }
1194
+ handle -> isCsContinuous = ((xfer -> flags & (uint8_t )kFLEXIO_SPI_csContinuous ) != 0U );
1195
+
1196
+ handle -> timer1Cfg = FLEXIO_SPI_MasterSetTimer1Cfg (base , handle -> isCsContinuous );
1118
1197
1119
1198
/* Configure the values in handle */
1120
1199
switch (dataFormat )
@@ -1229,12 +1308,7 @@ status_t FLEXIO_SPI_MasterTransferNonBlocking(FLEXIO_SPI_Type *base,
1229
1308
1230
1309
/* Enable transmit and receive interrupt to handle rx. */
1231
1310
FLEXIO_SPI_EnableInterrupts (base , (uint32_t )kFLEXIO_SPI_RxFullInterruptEnable );
1232
-
1233
- if ((xfer -> flags & (uint8_t )kFLEXIO_SPI_csContinuous ) != 0U )
1234
- {
1235
- FLEXIO_SPI_EnableInterrupts (base , (uint32_t )kFLEXIO_SPI_TxEmptyInterruptEnable );
1236
- }
1237
-
1311
+
1238
1312
return kStatus_Success ;
1239
1313
}
1240
1314
@@ -1282,6 +1356,13 @@ void FLEXIO_SPI_MasterTransferAbort(FLEXIO_SPI_Type *base, flexio_spi_master_han
1282
1356
FLEXIO_SPI_DisableInterrupts (base , (uint32_t )kFLEXIO_SPI_RxFullInterruptEnable );
1283
1357
FLEXIO_SPI_DisableInterrupts (base , (uint32_t )kFLEXIO_SPI_TxEmptyInterruptEnable );
1284
1358
1359
+ if (handle -> isCsContinuous )
1360
+ {
1361
+ FLEXIO_SPI_MasterForceDisableTimer1 (base );
1362
+ }
1363
+
1364
+ FLEXIO_SPI_MasterRecoverTimer1Cfg (base , handle -> timer1Cfg );
1365
+
1285
1366
/* Transfer finished, set the state to idle. */
1286
1367
handle -> state = (uint32_t )kFLEXIO_SPI_Idle ;
1287
1368
@@ -1315,7 +1396,6 @@ void FLEXIO_SPI_MasterTransferHandleIRQ(void *spiType, void *spiHandle)
1315
1396
/* Receive interrupt. */
1316
1397
if ((status & (uint32_t )kFLEXIO_SPI_RxBufferFullFlag ) == 0U )
1317
1398
{
1318
- FLEXIO_SPI_TransferSendTransaction (base , handle );
1319
1399
return ;
1320
1400
}
1321
1401
0 commit comments