1 /**
2 ******************************************************************************
3 * @file rtl8721dhp_usi_ssi.c
4 * @author
5 * @version V1.0.0
6 * @date 2017-11-27
7 * @brief This file contains all the functions prototypes for USI-SPI:
8 * - Initialization
9 * - Clock polarity and phase setting
10 * - SPI data frame size setting
11 * - SPI baud rate setting
12 * - Receive/Send data interface
13 * - Get TRx FIFO valid entries
14 * - check SPI device busy status
15 * - DMA transfers management
16 * - Interrupts and management
17 *
18 ******************************************************************************
19 * @attention
20 *
21 * This module is a confidential and proprietary property of RealTek and
22 * possession or use of this module requires written permission of RealTek.
23 *
24 * Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
25 ******************************************************************************
26 */
27
28 #include "ameba_soc.h"
29
30 /** @addtogroup USI_SPI_Exported_Functions
31 *@verbatim
32 *
33 * ===================================================================
34 * How to use this driver
35 * ===================================================================
36 * 1. Enable peripheral clock using the following functions
37 *
38 *
39 * 2. Configure the SPIx pinmux.
40 *
41 *
42 * 3. Disable the SPI using the USI_SSI_Cmd() function
43 *
44 * 4. Program the Polarity,Phase,Transfer Mode,Baud Rate Prescaler,DataFrameSize,
45 * Interrupt TRx Threshold level,DMA TRx Threshold level and other parameters using
46 * the USI_SSI_Init() function.
47 *
48 * 5. Enable the USI-SPI using the USI_SSI_Cmd() function
49 *
50 * 6. When using poll:
51 * -Using USI_SSI_Writeable() function make sure that the transmit FIFO is not full,
52 * then using USI_SSI_WriteData() function to send data
53 *
54 * -Using USI_SSI_Readable() function make sure that the receive FIFO is not empty,
55 * then using USI_SSI_ReadData() function to receive data
56 *
57 * 7. Enable corresponding interrupt using the function USI_SSI_INTConfig() if you need to
58 * use interrupt mode.
59 *
60 * 8. When using the DMA mode
61 * - Configure & Initialize the DMA
62 * - Active the DMA Tx or Rx using USI_SSI_SetDmaEnable() function
63 *
64 * @endverbatim
65 */
66
67 /**
68 * @brief Fills each USI_SSI_InitStruct member with its default value.
69 * @param USI_SSI_InitStruct: pointer to a USI_SSI_InitTypeDef structure which will be
70 * initialized.
71 * @retval None
72 */
73 void
USI_SSI_StructInit(USI_SSI_InitTypeDef * USI_SSI_InitStruct)74 USI_SSI_StructInit(USI_SSI_InitTypeDef* USI_SSI_InitStruct)
75 {
76 USI_SSI_InitStruct->USI_SPI_RxThresholdLevel = 0; // if number of entries in the RX FIFO >= RxThresholdLevel + 1, RX interrupt asserted
77 USI_SSI_InitStruct->USI_SPI_TxThresholdLevel = 32; // if number of empty entries in th TX FIFO >= TxThresholdLevel, TX interrupt asserted
78 USI_SSI_InitStruct->USI_SPI_DmaRxDataLevel = 3;
79 USI_SSI_InitStruct->USI_SPI_DmaTxDataLevel = 56;
80 USI_SSI_InitStruct->USI_SPI_ClockDivider = 6;
81 USI_SSI_InitStruct->USI_SPI_DataFrameNumber = 0;
82 USI_SSI_InitStruct->USI_SPI_DataFrameSize = USI_SPI_DFS_8_BITS;
83 USI_SSI_InitStruct->USI_SPI_InterruptMask = 0x0;
84 USI_SSI_InitStruct->USI_SPI_SclkPhase = USI_SPI_SCPH_TOGGLES_AT_START;
85 USI_SSI_InitStruct->USI_SPI_SclkPolarity = USI_SPI_SCPOL_INACTIVE_IS_HIGH;
86 USI_SSI_InitStruct->USI_SPI_TransferMode = USI_SPI_TMOD_TR;
87
88 USI_SSI_InitStruct->USI_SPI_RxSampleDelay = 0;
89 USI_SSI_InitStruct->USI_SPI_SSTogglePhase = 0;
90 }
91
92
93 /**
94 * @brief Initializes the USI-SPI registers according to the specified parameters
95 * in USI_SSI_InitStruct.
96 * @param usi_dev: where spi_dev can be USI0_DEV.
97 * @param USI_SSI_InitStruct: pointer to a USI_SSI_InitTypeDef structure that contains
98 * the configuration information for the USI-SPI peripheral.
99 * @retval None
100 */
101
USI_SSI_Init(USI_TypeDef * usi_dev,USI_SSI_InitTypeDef * USI_SSI_InitStruct)102 void USI_SSI_Init(USI_TypeDef *usi_dev, USI_SSI_InitTypeDef *USI_SSI_InitStruct)
103 {
104 u32 TempValue1 = 0, TempValue2 = 0;
105
106 assert_param(IS_USI_SPI_RxThresholdLevel(USI_SSI_InitStruct->USI_SPI_RxThresholdLevel));
107 assert_param(IS_USI_SPI_TxThresholdLevel(USI_SSI_InitStruct->USI_SPI_TxThresholdLevel));
108
109 /* Set USI to SPI mode */
110 TempValue1 = usi_dev->USI_MODE_CTRL;
111 TempValue1 &= ~USI_SERIAL_MODE;
112 TempValue1 |= USI_SERIAL_SPI_MODE;
113 usi_dev->USI_MODE_CTRL = TempValue1;
114
115 /* Disable SPI and Tx/Rx Path, for some bits in SPI_CTRL are writeable only when Tx/Rx path are both disable.*/
116 USI_SSI_Cmd(usi_dev, DISABLE);
117 USI_SSI_TRxPath_Cmd(usi_dev, USI_SPI_RX_ENABLE | USI_SPI_TX_ENABLE, DISABLE);
118
119 /* Set SPI Control Register */
120 TempValue1 = 0;
121 TempValue1 |= USI_SSI_InitStruct->USI_SPI_DataFrameSize;
122 TempValue1 |= (USI_SSI_InitStruct->USI_SPI_SclkPhase << 6);
123 TempValue1 |= (USI_SSI_InitStruct->USI_SPI_SclkPolarity << 7);
124
125 /* Master Only */
126 if (USI_SSI_InitStruct->USI_SPI_Role & USI_SPI_MASTER) {
127 TempValue1 |= (USI_SSI_InitStruct->USI_SPI_ClockDivider) << 16;
128 TempValue1 |= (USI_SSI_InitStruct->USI_SPI_RxSampleDelay) << 8;
129 TempValue1 |= (USI_SSI_InitStruct->USI_SPI_SSTogglePhase) << 5;
130 TempValue1 |= USI_SPI_MASTER_MODE;
131
132 TempValue2 |= (USI_SSI_InitStruct->USI_SPI_DataFrameNumber) << 16;
133 }
134 usi_dev->SPI_CTRL = TempValue1;
135
136 /* Set Tx/Rx FIFO Threshold Level*/
137 usi_dev->TX_FIFO_CTRL = USI_SPI_TX_FIFO_DEPTH - USI_SSI_InitStruct->USI_SPI_TxThresholdLevel;
138 usi_dev->RX_FIFO_CTRL = USI_SSI_InitStruct->USI_SPI_RxThresholdLevel + 1;
139
140 /* Set interrupt */
141 usi_dev->INTERRUPT_ENABLE = USI_SSI_InitStruct->USI_SPI_InterruptMask & USI_SPI_INTERRUPT_MASK;
142
143 /*DMA level set */
144 USI_SSI_SetDmaLevel(usi_dev, USI_SSI_InitStruct->USI_SPI_DmaTxDataLevel, USI_SSI_InitStruct->USI_SPI_DmaRxDataLevel);
145
146 /* Set Tx/Rx Path enable */
147 switch(USI_SSI_InitStruct->USI_SPI_TransferMode){
148 case USI_SPI_TMOD_TO:
149 TempValue2 |= USI_SPI_TX_ENABLE;
150 break;
151 case USI_SPI_TMOD_RO:
152 TempValue2 |= USI_SPI_RX_ENABLE;
153 break;
154 case USI_SPI_TMOD_TR:
155 TempValue2 |= (USI_SPI_TX_ENABLE | USI_SPI_RX_ENABLE);
156 break;
157 default:
158 break;
159 }
160 usi_dev->SPI_TRANS_EN = TempValue2;
161
162 /* Enable SPI. SPI can work normally when Tx/Rx Path and all logic are released.*/
163 USI_SSI_Cmd(usi_dev, ENABLE);
164 }
165
166 /**
167 * @brief Enables or disables USI-SPI peripheral.
168 * @param usi_dev: where usi_dev can be USI0_DEV.
169 * @param NewStatus: This parameter can be one of the following values:
170 * @arg ENABLE
171 * @arg DISABLE
172 * @retval None
173 */
174
USI_SSI_Cmd(USI_TypeDef * usi_dev,u32 NewStatus)175 void USI_SSI_Cmd(USI_TypeDef *usi_dev, u32 NewStatus)
176 {
177 if (NewStatus != DISABLE) {
178 usi_dev->SW_RESET |= USI_SW_RESET_RSTB | USI_SW_RESET_RXFIFO_RSTB |
179 USI_SW_RESET_TXFIFO_RSTB | USI_SW_RESET_RX_RSTB | USI_SW_RESET_TX_RSTB;
180 } else {
181 usi_dev->SW_RESET &= ~USI_SW_RESET_RSTB;
182 }
183 }
184
185
186 /**
187 * @brief Enables or disables USI-SPI Tx or Rx path.
188 * @param usi_dev: where usi_dev can be USI0_DEV.
189 * @param path: Tx or Rx path control bit, which can be
190 * @arg USI_SPI_TX_ENABLE
191 * @arg USI_SPI_RX_ENABLE
192 * @param NewStatus: This parameter can be one of the following values:
193 * @arg ENABLE
194 * @arg DISABLE
195 * @retval None
196 */
197
USI_SSI_TRxPath_Cmd(USI_TypeDef * usi_dev,u32 path,u32 NewStatus)198 void USI_SSI_TRxPath_Cmd(USI_TypeDef *usi_dev, u32 path, u32 NewStatus)
199 {
200 if(NewStatus != DISABLE){
201 usi_dev->SPI_TRANS_EN |= path;
202 } else {
203 usi_dev->SPI_TRANS_EN &= ~path;
204 }
205 }
206
207 /**
208 * @brief Get USI-SPI Tx/Rx path configuration.
209 * @param usi_dev: where usi_dev can be USI0_DEV.
210 * @retval Current TRx Path setting, each bit of this value represents one
211 * path which is as follows:
212 *
213 * bit 1 : USI_SPI_RX_ENABLE
214 * - 0 : Rx Path is disable
215 * - 1 : Rx Path is enable
216 *
217 * bit 0 : USI_SPI_TX_ENABLE
218 * - 0 : Tx Path is disable
219 * - 1 : Tx Path is enable
220 *
221 * @retval None
222 */
USI_SSI_GetTRxPath(USI_TypeDef * usi_dev)223 u32 USI_SSI_GetTRxPath(USI_TypeDef *usi_dev)
224 {
225 return usi_dev->SPI_TRANS_EN & (USI_SPI_RX_ENABLE | USI_SPI_TX_ENABLE);
226 }
227
228 /**
229 * @brief Set USI SPI as Master or Slave.
230 * @param usi_dev: where spi_dev can be USI0_DEV.
231 * @param role: This parameter can be one of the following values:
232 * @arg USI_SPI_MASTER
233 * @arg USI_SPI_SLAVE
234 * @retval None
235 */
USI_SSI_SetRole(USI_TypeDef * usi_dev,u32 role)236 void USI_SSI_SetRole(USI_TypeDef *usi_dev, u32 role)
237 {
238 u32 Temp;
239 u32 trxpath = USI_SSI_GetTRxPath(usi_dev);
240
241 Temp = usi_dev->SPI_CTRL;
242 Temp &= ~USI_SPI_MASTER_MODE;
243 Temp |= (role << 4);
244
245 /* USI_SPI_MASTER_MODE is writeable only when Tx and Rx path are both disable */
246 USI_SSI_TRxPath_Cmd(usi_dev, trxpath, DISABLE);
247 usi_dev->SPI_CTRL = Temp;
248 USI_SSI_TRxPath_Cmd(usi_dev, trxpath, ENABLE);
249 }
250
251
252 /**
253 * @brief Enable or Disable USI-SPI interrupt.
254 * @param usi_dev: where usi_dev can be USI0_DEV.
255 * @param USI_SSI_IT: This parameter can be one of the following values or mixed:
256 * @arg USI_TXFIFO_ALMOST_EMTY_INTR_EN
257 * @arg USI_TXFIFO_OVERFLOW_INTR_EN
258 * @arg USI_TXFIFO_UNDERFLOW_INTR_EN
259 * @arg USI_RXFIFO_ALMOST_FULL_INTR_EN
260 * @arg USI_RXFIFO_OVERFLOW_INTR_EN
261 * @arg USI_RXFIFO_UNDERFLOW_INTR_EN
262 * @arg USI_SPI_RX_DATA_FRM_ERR_INTER_EN
263 * @param newState:This parameter can be one of the following values:
264 * @arg ENABLE
265 * @arg DISABLE
266 * @retval None
267 */
268 VOID
USI_SSI_INTConfig(USI_TypeDef * usi_dev,u32 USI_SSI_IT,u32 newState)269 USI_SSI_INTConfig(USI_TypeDef* usi_dev, u32 USI_SSI_IT, u32 newState)
270 {
271 if (newState == ENABLE) {
272 /* Enable the selected SSI interrupts */
273 usi_dev->INTERRUPT_ENABLE |= USI_SSI_IT;
274 } else {
275 /* Disable the selected SSI interrupts */
276 usi_dev->INTERRUPT_ENABLE &= ~USI_SSI_IT;
277 }
278 }
279
280 /**
281 * @brief Set USI-SPI clock polarity.
282 * @param usi_dev: where usi_dev can be USI0_DEV.
283 * @param SclkPolarity: This parameter can be one of the following values:
284 * @arg USI_SPI_SCPOL_INACTIVE_IS_HIGH
285 * @arg USI_SPI_SCPOL_INACTIVE_IS_LOW
286 * @retval None
287 */
288
USI_SSI_SetSclkPolarity(USI_TypeDef * usi_dev,u32 SclkPolarity)289 void USI_SSI_SetSclkPolarity(USI_TypeDef *usi_dev, u32 SclkPolarity)
290 {
291 u32 Value;
292 u32 trxpath = USI_SSI_GetTRxPath(usi_dev);
293
294 Value = usi_dev->SPI_CTRL;
295 Value &= ~ USI_SPI_CPOL;
296 Value |= (SclkPolarity << 7);
297
298 /* SPI_CPOL is writeable only when Tx and Rx path are both disable */
299 USI_SSI_TRxPath_Cmd(usi_dev, trxpath, DISABLE);
300 usi_dev->SPI_CTRL = Value;
301 USI_SSI_TRxPath_Cmd(usi_dev, trxpath, ENABLE);
302 }
303
304 /**
305 * @brief Set USI-SPI clock phase.
306 * @param usi_dev: where usi_dev can be USI0_DEV.
307 * @param SclkPhase: This parameter can be one of the following values:
308 * @arg USI_SPI_SCPH_TOGGLES_IN_MIDDLE
309 * @arg USI_SPI_SCPH_TOGGLES_AT_START
310 * @retval None
311 */
312
USI_SSI_SetSclkPhase(USI_TypeDef * usi_dev,u32 SclkPhase)313 void USI_SSI_SetSclkPhase(USI_TypeDef *usi_dev, u32 SclkPhase)
314 {
315 u32 Value;
316 u32 trxpath = USI_SSI_GetTRxPath(usi_dev);
317
318 Value = usi_dev->SPI_CTRL;
319 Value &= ~USI_SPI_CPH;
320 Value |= (SclkPhase << 6);
321
322 /* SPI_CPH is writeable only when Tx and Rx path are both disable */
323 USI_SSI_TRxPath_Cmd(usi_dev, trxpath, DISABLE);
324 usi_dev->SPI_CTRL = Value;
325 USI_SSI_TRxPath_Cmd(usi_dev, trxpath, ENABLE);
326 }
327
328
329 /**
330 * @brief Set USI-SPI SS Toggle Phase.
331 * @param usi_dev: where usi_dev can be USI0_DEV.
332 * @param TogglePhase: This parameter can be one of the following values:
333 * @arg USI_SPI_SS_NOT_TOGGLE , means SPI support continuous transfer when spi_cph=0
334 * @arg USI_SPI_SS_TOGGLE, means SPI donot support continuous transfer when spi_cph=0
335 * and SS(CS) needs break.
336 * @retval None
337 */
338
USI_SSI_SetSSTogglePhase(USI_TypeDef * usi_dev,u32 TogglePhase)339 void USI_SSI_SetSSTogglePhase(USI_TypeDef *usi_dev, u32 TogglePhase)
340 {
341 u32 Value;
342 u32 trxpath = USI_SSI_GetTRxPath(usi_dev);
343
344 Value = usi_dev->SPI_CTRL;
345 Value &= ~USI_SPI_SS_TOG_PHASE;
346 Value |= (TogglePhase << 5);
347
348 /* SPI_SS_TOG_PHASE is writeable only when Tx and Rx path are both disable */
349 USI_SSI_TRxPath_Cmd(usi_dev, trxpath, DISABLE);
350 usi_dev->SPI_CTRL = Value;
351 USI_SSI_TRxPath_Cmd(usi_dev, trxpath, ENABLE);
352 }
353
354
355 /**
356 * @brief Set USI-SPI data frame size.
357 * @param usi_dev: where usi_dev can be USI0_DEV.
358 * @param DataFrameSize: This parameter can be one of the following values:
359 * @arg USI_SPI_DFS_4_BITS
360 * @arg USI_SPI_DFS_5_BITS
361 * @arg USI_SPI_DFS_6_BITS
362 * @arg USI_SPI_DFS_7_BITS
363 * @arg USI_SPI_DFS_8_BITS
364 * @arg USI_SPI_DFS_9_BITS
365 * @arg USI_SPI_DFS_10_BITS
366 * @arg USI_SPI_DFS_11_BITS
367 * @arg USI_SPI_DFS_12_BITS
368 * @arg USI_SPI_DFS_13_BITS
369 * @arg USI_SPI_DFS_14_BITS
370 * @arg USI_SPI_DFS_15_BITS
371 * @arg USI_SPI_DFS_16_BITS
372 * @retval None
373 */
374
USI_SSI_SetDataFrameSize(USI_TypeDef * usi_dev,u32 DataFrameSize)375 void USI_SSI_SetDataFrameSize(USI_TypeDef *usi_dev, u32 DataFrameSize)
376 {
377 u32 Value;
378 u32 trxpath = USI_SSI_GetTRxPath(usi_dev);
379
380 Value = usi_dev->SPI_CTRL;
381 Value &= ~USI_SPI_DAT_FRM_SIZE;
382 Value |= DataFrameSize;
383
384 USI_SSI_TRxPath_Cmd(usi_dev, trxpath, DISABLE);
385 usi_dev->SPI_CTRL = Value;
386 USI_SSI_TRxPath_Cmd(usi_dev, trxpath, ENABLE);
387 }
388
389 /**
390 * @brief Set USI-SPI Rx Sample Dealy.
391 * @param usi_dev: where usi_dev can be USI0_DEV.
392 * @param SampleDelay: The number of ssi_clk cycles that to be delayed.
393 * @retval None
394 */
395
USI_SSI_SetSampleDelay(USI_TypeDef * usi_dev,u32 SampleDelay)396 void USI_SSI_SetSampleDelay(USI_TypeDef *usi_dev, u32 SampleDelay)
397 {
398 u32 Value;
399 u32 trxpath = USI_SSI_GetTRxPath(usi_dev);
400
401 Value = usi_dev->SPI_CTRL;
402 Value &= ~USI_SPI_RX_SAMPLE_DLY;
403 Value |= (SampleDelay << 8);
404
405 USI_SSI_TRxPath_Cmd(usi_dev, trxpath, DISABLE);
406 usi_dev->SPI_CTRL = Value;
407 USI_SSI_TRxPath_Cmd(usi_dev, trxpath, ENABLE);
408 }
409
410 /**
411 * @brief Set the number of data frame to be received.
412 * @note Valid only when the device is configured as a master in RX Only mode.
413 * @param usi_dev: where usi_dev can only be USI0_DEV.
414 * @param DataFrameNumber: The number of data frames that to be received.
415 * @retval None
416 */
417
USI_SSI_SetReadLen(USI_TypeDef * usi_dev,u32 DataFrameNumber)418 void USI_SSI_SetReadLen(USI_TypeDef *usi_dev, u32 DataFrameNumber)
419 {
420 u32 Value;
421 u32 trxpath = USI_SSI_GetTRxPath(usi_dev);
422 assert_param((DataFrameNumber >= 1)&&(DataFrameNumber <= 0x10000));
423
424 Value = usi_dev->SPI_TRANS_EN;
425 Value &= ~USI_SPI_RXONLY_NUM;
426 Value |= ((DataFrameNumber - 1) << 16);
427
428 USI_SSI_TRxPath_Cmd(usi_dev, trxpath, DISABLE);
429 usi_dev->SPI_TRANS_EN = Value;
430 USI_SSI_TRxPath_Cmd(usi_dev, trxpath, ENABLE);
431 }
432
433 /**
434 * @brief Set USI-SPI clock divider.
435 * @note Valid only when the device is configured as a master.
436 * And The LSB is always set to 0,and is unaffected by a write operation.
437 * @param usi_dev: where usi_dev can only be USI0_DEV.
438 * @param ClockDivider: Even value between 2 and 65534.
439 * And Fsclk_out=Fssi_clk/ClockDivider.
440 * @retval None
441 */
442
USI_SSI_SetBaudDiv(USI_TypeDef * usi_dev,u32 ClockDivider)443 void USI_SSI_SetBaudDiv(USI_TypeDef *usi_dev, u32 ClockDivider)
444 {
445 u32 Value;
446 u32 trxpath = USI_SSI_GetTRxPath(usi_dev);
447
448 Value = usi_dev->SPI_CTRL;
449 Value &= ~USI_SPI_MST_BAUD;
450 Value |= (ClockDivider << 16);
451
452 USI_SSI_TRxPath_Cmd(usi_dev, trxpath, DISABLE);
453 usi_dev->SPI_CTRL = Value;
454 USI_SSI_TRxPath_Cmd(usi_dev, trxpath, ENABLE);
455 }
456
457 /**
458 * @brief Set USI-SPI Master clock.
459 * @param USIx: where SPIx can be USI0_DEV.
460 * @param BaudRate: baudrate for SPI bus, unit is HZ.
461 * @param IpClk: IP Clock
462 * @retval None
463 * @note Valid only when the device is configured as a master.
464 * @note BaudRate <= (IpClk/2).
465 * @note As the clock divider can only be an even number. The final baudrate this function generates
466 * may be a little lower than the value of BaudRate,which is setted by user.
467 * @note Fsclk_out = Fssi_clk /SCKDV
468 * @note for FPGA IpClk = CPU_ClkGet(_TRUE)
469 * @note for ASIC IpClk = CPU_ClkGet(_FALSE)/2
470 */
471
USI_SSI_SetBaud(USI_TypeDef * USIx,u32 BaudRate,u32 IpClk)472 void USI_SSI_SetBaud(USI_TypeDef *USIx, u32 BaudRate, u32 IpClk)
473 {
474 u32 ClockDivider;
475
476 assert_param(USIx == USI0_DEV);
477 assert_param(BaudRate <= (IpClk/2));
478
479 /*Adjust SCKDV-Parameter to an even number */
480 ClockDivider = IpClk/BaudRate + 1;
481 if ((IpClk%BaudRate) > (BaudRate/2)) {
482 ClockDivider++;
483 }
484 if (ClockDivider >= 0xFFFF) {
485 /* devider is 16 bits */
486 ClockDivider = 0xFFFE;
487 }
488 ClockDivider &= 0xFFFE; // bit 0 always is 0
489
490 USI_SSI_SetBaudDiv(USIx, ClockDivider);
491 }
492
493 /**
494 * @brief Enables or disables USI-SPI TDMA and RDMA .
495 * @param usi_dev: where usi_dev can be USI0_DEV.
496 * @param newState: This parameter can be one of the following values:
497 * @arg ENABLE
498 * @arg DISABLE
499 * @param Mask: This parameter can be one of the following values or mixed:
500 * @arg USI_TX_DMA_ENABLE
501 * @arg USI_RX_DMA_ENABLE
502 * @retval None
503 */
504
USI_SSI_SetDmaEnable(USI_TypeDef * usi_dev,u32 newState,u32 Mask)505 void USI_SSI_SetDmaEnable(USI_TypeDef *usi_dev, u32 newState, u32 Mask)
506 {
507 if (newState == DISABLE)
508 usi_dev->DMA_ENABLE &= ~Mask;
509 else
510 usi_dev->DMA_ENABLE |= Mask;
511 }
512
513 /**
514 * @brief Set USI-SPI DMA TxLevel and RxLevel.
515 * @param usi_dev: where usi_dev can be USI0_DEV.
516 * @param TxLevel: Transmit FIFO Threshold level.Value range: 0 to 63.
517 * The dma_tx_req is generated when the number of valid data entries in
518 * the transmit FIFO is equal to or below this field value.
519 * @param RxLevel: Receive FIFO Threshold level.Value range: 0 to 63.
520 * The dma_rx_req is generated when the number of valid data entries in the
521 * receive FIFO is equal to or above this field value + 1.
522 * @retval None
523 */
524
USI_SSI_SetDmaLevel(USI_TypeDef * usi_dev,u32 TxLevel,u32 RxLevel)525 void USI_SSI_SetDmaLevel(USI_TypeDef *usi_dev, u32 TxLevel, u32 RxLevel)
526 {
527 u32 value = usi_dev->DMA_REQ_SIZE;
528
529 assert_param(IS_USI_SPI_TxDMALevel(TxLevel));
530 assert_param(IS_USI_SPI_RxDMALevel(RxLevel));
531
532 /* Set TX FIFO water level to trigger Tx DMA transfer */
533 value &= ~USI_TX_DMA_BURST_SIZE;
534 value |= (USI_SPI_TX_FIFO_DEPTH - TxLevel);
535
536 /* Set RX FIFO water level to trigger Rx DMA transfer */
537 value &= ~USI_RX_DMA_BURST_SIZE;
538 value |= ((RxLevel + 1) << 16);
539
540 usi_dev->DMA_REQ_SIZE = value;
541 }
542
543 /**
544 * @brief Init and Enable USI-SPI TX GDMA.
545 * @param Index: 0.
546 * @param GDMA_InitStruct: pointer to a GDMA_InitTypeDef structure that contains
547 * the configuration information for the GDMA peripheral.
548 * @param CallbackData: GDMA callback data.
549 * @param CallbackFunc: GDMA callback function.
550 * @param pTxData: Tx Buffer.
551 * @param Length: Tx Count.
552 * @retval TRUE/FLASE
553 */
554
USI_SSI_TXGDMA_Init(u32 Index,PGDMA_InitTypeDef GDMA_InitStruct,void * CallbackData,IRQ_FUN CallbackFunc,u8 * pTxData,u32 Length)555 BOOL USI_SSI_TXGDMA_Init(
556 u32 Index,
557 PGDMA_InitTypeDef GDMA_InitStruct,
558 void *CallbackData,
559 IRQ_FUN CallbackFunc,
560 u8 *pTxData,
561 u32 Length
562 )
563 {
564 USI_TypeDef *USIx = USI_DEV_TABLE[Index].USIx;
565 u32 DataFrameSize = USI_SSI_GetDataFrameSize(USIx);
566 u8 GdmaChnl;
567
568 assert_param(GDMA_InitStruct != NULL);
569
570 GdmaChnl = GDMA_ChnlAlloc(0, CallbackFunc, (u32)CallbackData, 12);//ACUT is 0x10, BCUT is 12
571 if (GdmaChnl == 0xFF) {
572 // No Available DMA channel
573 return _FALSE;
574 }
575
576 _memset((void *)GDMA_InitStruct, 0, sizeof(GDMA_InitTypeDef));
577
578 GDMA_InitStruct->GDMA_DIR = TTFCMemToPeri;
579 GDMA_InitStruct->GDMA_DstHandshakeInterface = USI_DEV_TABLE[Index].Tx_HandshakeInterface;
580 GDMA_InitStruct->GDMA_DstAddr = (u32)&USI_DEV_TABLE[Index].USIx->TX_FIFO_WRITE;
581 GDMA_InitStruct->GDMA_Index = 0;
582 GDMA_InitStruct->GDMA_ChNum = GdmaChnl;
583 GDMA_InitStruct->GDMA_IsrType = (BlockType|TransferType|ErrType);
584
585 GDMA_InitStruct->GDMA_SrcMsize = MsizeOne;
586 GDMA_InitStruct->GDMA_DstMsize = MsizeFour;
587 GDMA_InitStruct->GDMA_SrcDataWidth = TrWidthFourBytes;
588 GDMA_InitStruct->GDMA_DstDataWidth = TrWidthOneByte;
589 GDMA_InitStruct->GDMA_DstInc = NoChange;
590 GDMA_InitStruct->GDMA_SrcInc = IncType;
591
592 /* Cofigure GDMA transfer */
593 if (DataFrameSize > 8) {
594 /* 16~9 bits mode */
595 if (((Length & 0x03)==0) && (((u32)(pTxData) & 0x03)==0)) {
596 /* 4-bytes aligned, move 4 bytes each transfer */
597 GDMA_InitStruct->GDMA_SrcMsize = MsizeFour;
598 GDMA_InitStruct->GDMA_SrcDataWidth = TrWidthFourBytes;
599 GDMA_InitStruct->GDMA_DstMsize = MsizeEight;
600 GDMA_InitStruct->GDMA_DstDataWidth = TrWidthTwoBytes;
601 GDMA_InitStruct->GDMA_BlockSize = Length >> 2;
602 } else if (((Length & 0x01)==0) && (((u32)(pTxData) & 0x01)==0)) {
603 /* 2-bytes aligned, move 2 bytes each transfer */
604 GDMA_InitStruct->GDMA_SrcMsize = MsizeEight;
605 GDMA_InitStruct->GDMA_SrcDataWidth = TrWidthTwoBytes;
606 GDMA_InitStruct->GDMA_DstMsize = MsizeEight;
607 GDMA_InitStruct->GDMA_DstDataWidth = TrWidthTwoBytes;
608 GDMA_InitStruct->GDMA_BlockSize = Length >> 1;
609 } else {
610 DBG_8195A("SSI_TXGDMA_Init: Aligment Err: pTxData=0x%x, Length=%d\n", pTxData, Length);
611 return _FALSE;
612 }
613 } else {
614 /* 8~4 bits mode */
615 if (((Length & 0x03)==0) && (((u32)(pTxData) & 0x03)==0)) {
616 /* 4-bytes aligned, move 4 bytes each transfer */
617 GDMA_InitStruct->GDMA_SrcMsize = MsizeOne;
618 GDMA_InitStruct->GDMA_SrcDataWidth = TrWidthFourBytes;
619 GDMA_InitStruct->GDMA_BlockSize = Length >> 2;
620 } else {
621 GDMA_InitStruct->GDMA_SrcMsize = MsizeFour;
622 GDMA_InitStruct->GDMA_SrcDataWidth = TrWidthOneByte;
623 GDMA_InitStruct->GDMA_BlockSize = Length;
624 }
625 GDMA_InitStruct->GDMA_DstMsize = MsizeFour;
626 GDMA_InitStruct->GDMA_DstDataWidth = TrWidthOneByte;
627 }
628
629 assert_param(GDMA_InitStruct->GDMA_BlockSize <= 4096);
630
631 GDMA_InitStruct->GDMA_SrcAddr = (u32)pTxData;
632
633 /* Enable GDMA for TX */
634 GDMA_Init(GDMA_InitStruct->GDMA_Index, GDMA_InitStruct->GDMA_ChNum, GDMA_InitStruct);
635 GDMA_Cmd(GDMA_InitStruct->GDMA_Index, GDMA_InitStruct->GDMA_ChNum, ENABLE);
636
637 return _TRUE;
638 }
639
640 /**
641 * @brief Init and Enable USI-SPI RX GDMA.
642 * @param Index: 0.
643 * @param GDMA_InitStruct: pointer to a GDMA_InitTypeDef structure that contains
644 * the configuration information for the GDMA peripheral.
645 * @param CallbackData: GDMA callback data.
646 * @param CallbackFunc: GDMA callback function.
647 * @param pRxData: Rx Buffer.
648 * @param Length: Rx Count.
649 * @retval TRUE/FLASE
650 */
651
652 BOOL
USI_SSI_RXGDMA_Init(u8 Index,GDMA_InitTypeDef * GDMA_InitStruct,void * CallbackData,IRQ_FUN CallbackFunc,u8 * pRxData,u32 Length)653 USI_SSI_RXGDMA_Init(
654 u8 Index,
655 GDMA_InitTypeDef *GDMA_InitStruct,
656 void *CallbackData,
657 IRQ_FUN CallbackFunc,
658 u8 *pRxData,
659 u32 Length
660 )
661 {
662 USI_TypeDef *USIx = USI_DEV_TABLE[Index].USIx;
663 u32 DataFrameSize = USI_SSI_GetDataFrameSize(USIx);
664 u8 GdmaChnl;
665
666 assert_param(GDMA_InitStruct != NULL);
667
668 GdmaChnl = GDMA_ChnlAlloc(0, CallbackFunc, (u32)CallbackData, 12);//ACUT is 0x10, BCUT is 12
669 if (GdmaChnl == 0xFF) {
670 // No Available DMA channel
671 return _FALSE;
672 }
673
674 _memset((void *)GDMA_InitStruct, 0, sizeof(GDMA_InitTypeDef));
675
676 GDMA_InitStruct->GDMA_DIR = TTFCPeriToMem;
677 GDMA_InitStruct->GDMA_ReloadSrc = 0;
678 GDMA_InitStruct->GDMA_SrcHandshakeInterface = USI_DEV_TABLE[Index].Rx_HandshakeInterface;
679 GDMA_InitStruct->GDMA_SrcAddr = (u32)&USI_DEV_TABLE[Index].USIx->RX_FIFO_READ;
680 GDMA_InitStruct->GDMA_Index = 0;
681 GDMA_InitStruct->GDMA_ChNum = GdmaChnl;
682 GDMA_InitStruct->GDMA_IsrType = (BlockType|TransferType|ErrType);
683
684 GDMA_InitStruct->GDMA_SrcMsize = MsizeEight;
685 GDMA_InitStruct->GDMA_DstMsize = MsizeFour;
686 GDMA_InitStruct->GDMA_SrcDataWidth = TrWidthTwoBytes;
687 GDMA_InitStruct->GDMA_DstDataWidth = TrWidthFourBytes;
688 GDMA_InitStruct->GDMA_DstInc = IncType;
689 GDMA_InitStruct->GDMA_SrcInc = NoChange;
690
691 /* Cofigure GDMA transfer */
692 if (DataFrameSize > 8) {
693 /* 16~9 bits mode */
694 GDMA_InitStruct->GDMA_SrcMsize = MsizeFour;
695 GDMA_InitStruct->GDMA_SrcDataWidth = TrWidthTwoBytes;
696 GDMA_InitStruct->GDMA_BlockSize = Length >> 1;
697
698 if (((Length & 0x03)==0) && (((u32)(pRxData) & 0x03)==0)) {
699 /* 4-bytes aligned, move 4 bytes each transfer */
700 GDMA_InitStruct->GDMA_DstMsize = MsizeFour;
701 GDMA_InitStruct->GDMA_DstDataWidth = TrWidthFourBytes;
702 } else if (((Length & 0x01)==0) && (((u32)(pRxData) & 0x01)==0)) {
703 /* 2-bytes aligned, move 2 bytes each transfer */
704 GDMA_InitStruct->GDMA_DstMsize = MsizeEight;
705 GDMA_InitStruct->GDMA_DstDataWidth = TrWidthTwoBytes;
706 } else {
707 DBG_8195A("SSI_RXGDMA_Init: Aligment Err: pTxData=0x%x, Length=%d\n", pRxData, Length);
708 return _FALSE;
709 }
710 } else {
711 /* 8~4 bits mode */
712 GDMA_InitStruct->GDMA_SrcMsize = MsizeFour;
713 GDMA_InitStruct->GDMA_SrcDataWidth = TrWidthOneByte;
714 GDMA_InitStruct->GDMA_BlockSize = Length;
715 if (((Length & 0x03)==0) && (((u32)(pRxData) & 0x03)==0)) {
716 /* 4-bytes aligned, move 4 bytes each transfer */
717 GDMA_InitStruct->GDMA_DstMsize = MsizeOne;
718 GDMA_InitStruct->GDMA_DstDataWidth = TrWidthFourBytes;
719 } else {
720 GDMA_InitStruct->GDMA_DstMsize = MsizeFour;
721 GDMA_InitStruct->GDMA_DstDataWidth = TrWidthOneByte;
722 }
723 }
724
725 assert_param(GDMA_InitStruct->GDMA_BlockSize <= 4096);
726
727 GDMA_InitStruct->GDMA_DstAddr = (u32)pRxData;
728
729 /* Enable GDMA for RX */
730 GDMA_Init(GDMA_InitStruct->GDMA_Index, GDMA_InitStruct->GDMA_ChNum, GDMA_InitStruct);
731 GDMA_Cmd(GDMA_InitStruct->GDMA_Index, GDMA_InitStruct->GDMA_ChNum, ENABLE);
732
733 return _TRUE;
734 }
735
736 /**
737 * @brief Clear USI-SPI interrupt status.
738 * @param usi_dev: where usi_dev can be USI0_DEV.
739 * @param InterruptStatus: The value of current interrupt status .
740 * @retval None
741 */
742
USI_SSI_SetIsrClean(USI_TypeDef * usi_dev,u32 InterruptStatus)743 void USI_SSI_SetIsrClean(USI_TypeDef *usi_dev, u32 InterruptStatus)
744 {
745 usi_dev->INTERRUPT_STATUS_CLR = InterruptStatus & USI_SPI_INTERRUPT_CLEAR_MASK;
746 }
747
748 /**
749 * @brief Write data to USI-SPI transmit FIFO.
750 * @param usi_dev: where usi_dev can be USI0_DEV.
751 * @param value: The data value that is to be transmitted .
752 * @retval None
753 */
754
USI_SSI_WriteData(USI_TypeDef * usi_dev,u32 value)755 void USI_SSI_WriteData(USI_TypeDef *usi_dev, u32 value)
756 {
757 usi_dev->TX_FIFO_WRITE = (value & USI_TX_FIFO_WRITE_DATA);
758 }
759
760 /**
761 * @brief Set USI-SPI Rx FIFO threshold level
762 * @param usi_dev: where usi_dev can be USI0_DEV.
763 * @param RxThresholdLevel: Rx FIFO Threshold Level.Value range: 0 to 63.
764 * When the number of receive FIFO entries is greater than or equal to
765 * this value + 1, the receive FIFO full interrupt is triggered.
766 * @retval None
767 */
768
USI_SSI_SetRxFifoLevel(USI_TypeDef * usi_dev,u32 RxThresholdLevel)769 void USI_SSI_SetRxFifoLevel(USI_TypeDef *usi_dev, u32 RxThresholdLevel)
770 {
771 assert_param(IS_USI_SPI_RxThresholdLevel(RxThresholdLevel));
772
773 usi_dev->RX_FIFO_CTRL = RxThresholdLevel + 1;
774 }
775
776 /**
777 * @brief Set USI-SPI Tx FIFO threshold level.
778 * @param usi_dev: where usi_dev can be USI0_DEV.
779 * @param TxThresholdLevel: Tx FIFO Threshold Level.Value range: 0 to 63.
780 * When the number of transmit FIFO entries is less than or equal to this
781 * value, the transmit FIFO empty interrupt is triggered.
782 * @retval None
783 */
784
USI_SSI_SetTxFifoLevel(USI_TypeDef * usi_dev,u32 TxThresholdLevel)785 void USI_SSI_SetTxFifoLevel(USI_TypeDef *usi_dev, u32 TxThresholdLevel)
786 {
787 assert_param(IS_USI_SPI_TxThresholdLevel(TxThresholdLevel));
788
789 usi_dev->TX_FIFO_CTRL = USI_SPI_TX_FIFO_DEPTH - TxThresholdLevel;
790 }
791
792 /**
793 * @brief Detemines whether USI-SPI transmit FIFO is full or not
794 * @param usi_dev: where usi_dev can be USI0_DEV.
795 * @retval Transmit FIFO is full or not:
796 * - 1: Not Full
797 * - 0: Full
798 */
799
USI_SSI_Writeable(USI_TypeDef * usi_dev)800 u32 USI_SSI_Writeable(USI_TypeDef *usi_dev)
801 {
802 u32 Status = USI_SSI_GetTxFIFOStatus(usi_dev);
803 u32 Writeable = (((Status & USI_TXFIFO_FULL) == 0) ? 1 : 0);
804
805 return Writeable;
806 }
807
808 /**
809 * @brief Detemine USI-SPI Receive FIFO is empty or not.
810 * @param usi_dev: where usi_dev can be USI0_DEV.
811 * @retval Receive FIFO is empty or not:
812 * - 1: Not Empty
813 * - 0: Empty
814 */
815
USI_SSI_Readable(USI_TypeDef * usi_dev)816 u32 USI_SSI_Readable(USI_TypeDef *usi_dev)
817 {
818 u32 Status = USI_SSI_GetRxFIFOStatus(usi_dev);
819 u32 Readable = (((Status & USI_RXFIFO_EMPTY) == 0) ? 1 : 0);
820
821 return Readable;
822 }
823
824 /**
825 * @brief Read data from USI-SPI receive FIFO .
826 * @param usi_dev: where usi_dev can be USI0_DEV.
827 * @retval The data received.
828 */
829
USI_SSI_ReadData(USI_TypeDef * usi_dev)830 u32 USI_SSI_ReadData(USI_TypeDef *usi_dev)
831 {
832 return usi_dev->RX_FIFO_READ;
833 }
834
835 /**
836 * @brief receive data from rx FIFO
837 * @param usi_dev: where usi_dev can be USI0_DEV.
838 * @param RxData: buffer to save data read from USI-SPI FIFO.
839 * @param Length: number of data to be read.
840 * @retval transfer len
841 */
842
USI_SSI_ReceiveData(USI_TypeDef * usi_dev,void * RxData,u32 Length)843 u32 USI_SSI_ReceiveData(USI_TypeDef *usi_dev,
844 void* RxData,
845 u32 Length
846 )
847 {
848 u32 ReceiveLevel;
849 u32 DataFrameSize = USI_SSI_GetDataFrameSize(usi_dev);
850 volatile u32 Readable = USI_SSI_Readable(usi_dev);
851 u32 RxLength = Length;
852
853 while (Readable) {
854 ReceiveLevel = USI_SSI_GetRxCount(usi_dev);
855
856 while (ReceiveLevel--) {
857 if (RxData != NULL) {
858 if (DataFrameSize > 8) {
859 /* 16~9 bits mode */
860 *((u16*)(RxData)) = (u16)USI_SSI_ReadData(usi_dev);
861 RxData = (VOID*)(((u16*)RxData) + 1);
862 } else {
863 /* 8~4 bits mode */
864 *((u8*)(RxData)) = (u8)USI_SSI_ReadData(usi_dev);
865 RxData = (VOID*)(((u8*)RxData) + 1);
866 }
867 } else {
868 /* for Master mode, doing TX also will got RX data, so drop the dummy data */
869 USI_SSI_ReadData(usi_dev);
870 }
871
872 if (RxLength > 0) {
873 RxLength--;
874 }
875 if (RxLength == 0) {
876 break;
877 }
878 }
879
880 if (RxLength == 0) {
881 break;
882 }
883
884 Readable = USI_SSI_Readable(usi_dev);
885 }
886
887 return (Length - RxLength);
888 }
889
890 /**
891 * @brief Send data to tx FIFO
892 * @param usi_dev: where usi_dev can be USI0_DEV.
893 * @param TxData: buffer to be written to Tx FIFO.
894 * @param Length: number of data to be written.
895 * @param Role: USI_SPI_MASTER or USI_SPI_SLAVE.
896 * @retval transfer len
897 */
898
USI_SSI_SendData(USI_TypeDef * usi_dev,void * TxData,u32 Length,u32 Role)899 u32 USI_SSI_SendData(USI_TypeDef *usi_dev,
900 void* TxData,
901 u32 Length,
902 u32 Role
903 )
904 {
905 u32 Writeable = USI_SSI_Writeable(usi_dev);
906 u32 TxWriteMax = USI_SPI_TX_FIFO_DEPTH - USI_SSI_GetTxCount(usi_dev);
907 u32 DataFrameSize = USI_SSI_GetDataFrameSize(usi_dev);
908 u32 TxLength = Length;
909
910 if (Writeable) {
911 /* Disable Tx FIFO Empty IRQ */
912 USI_SSI_INTConfig(usi_dev, USI_TXFIFO_ALMOST_EMTY_INTR_EN, DISABLE);
913
914 while (TxWriteMax--) {
915 if (DataFrameSize > 8) {
916 // 16~9 bits mode
917 if (TxData != NULL) {
918 USI_SSI_WriteData(usi_dev, *((u16*)(TxData)));
919 TxData = (VOID*)(((u16*)TxData) + 1);
920 } else {
921 // For master mode: Push a dummy to TX FIFO for Read
922 if (Role == USI_SPI_MASTER) {
923 USI_SSI_WriteData(usi_dev, (u16)0);// Dummy byte
924 }
925 }
926 } else {
927 // 8~4 bits mode
928 if (TxData != NULL) {
929 USI_SSI_WriteData(usi_dev, *((u8*)(TxData)));
930 TxData = (VOID*)(((u8*)TxData) + 1);
931 } else {
932 // For master mode: Push a dummy to TX FIFO for Read
933 if (Role == USI_SPI_MASTER) {
934 USI_SSI_WriteData(usi_dev, (u8)0);// Dummy byte
935 }
936 }
937 }
938
939 TxLength--;
940
941 if (TxLength == 0)
942 break;
943 }
944
945 /* Enable Tx FIFO Empty IRQ */
946 USI_SSI_INTConfig(usi_dev, USI_TXFIFO_ALMOST_EMTY_INTR_EN, ENABLE);
947 }
948
949 return (Length - TxLength);
950 }
951
952 /**
953 * @brief Get the number of valid entries in receive FIFO.
954 * @param usi_dev: where usi_dev can be USI0_DEV.
955 * @retval The number of valid entries in receive FIFO.Value range:0-64.
956 */
957
USI_SSI_GetRxCount(USI_TypeDef * usi_dev)958 u32 USI_SSI_GetRxCount(USI_TypeDef *usi_dev)
959 {
960 u32 valid_cnt = (USI_SSI_GetRxFIFOStatus(usi_dev) & USI_RXFIFO_VALID_CNT) >> 8;
961 return valid_cnt;
962 }
963
964 /**
965 * @brief Get the number of valid entries in transmit FIFO.
966 * @param usi_dev: where usi_dev can be USI0_DEV.
967 * @retval The number of valid entries in transmit FIFO.Value range:0-64.
968 */
969
USI_SSI_GetTxCount(USI_TypeDef * usi_dev)970 u32 USI_SSI_GetTxCount(USI_TypeDef *usi_dev)
971 {
972 u32 empty_cnt = (USI_SSI_GetTxFIFOStatus(usi_dev) & USI_TXFIFO_EMPTY_SPACE) >> 8;
973 return USI_SPI_TX_FIFO_DEPTH - empty_cnt;
974 }
975
976 /**
977 * @brief Get USI-SPI Tx FIFO status.
978 * @param usi_dev: where usi_dev can be USI0_DEV.
979 * @retval Current Tx FIFO status:
980 *
981 * bit [8:14] : USI_TXFIFO_EMPTY_SPACE
982 * - Tx FIFO empty entry count
983 *
984 * bit 2 : USI_TXFIFO_ALMOST_EMPTY_COPY
985 * - 0 : Tx FIFO not almost empty
986 * - 1 : Tx FIFO almost empty
987 *
988 * bit 1 : USI_TXFIFO_EMPTY
989 * - 0 : Tx FIFO not empty
990 * - 1 : Tx FIFO is empty
991 *
992 * bit 0 : USI_TXFIFO_FULL
993 * - 0 : Tx FIFO not full
994 * - 1 : Tx FIFO is full
995 *
996 */
USI_SSI_GetTxFIFOStatus(USI_TypeDef * usi_dev)997 u32 USI_SSI_GetTxFIFOStatus(USI_TypeDef *usi_dev)
998 {
999 return usi_dev->TX_FIFO_STATUS;
1000 }
1001
1002 /**
1003 * @brief Get USI-SPI Rx FIFO status.
1004 * @param usi_dev: where usi_dev can be USI0_DEV.
1005 * @retval Current Rx FIFO status:
1006 *
1007 * bit [8:14] : USI_RXFIFO_VALID_CNT
1008 * - Rx FIFO valid count
1009 *
1010 * bit 2 : USI_RXFIFO_ALMOST_FULL_COPY
1011 * - 0 : Rx FIFO not almost full
1012 * - 1 : Rx FIFO almost full
1013 *
1014 * bit 1 : USI_RXFIFO_EMPTY
1015 * - 0 : Rx FIFO not empty
1016 * - 1 : Rx FIFO is empty
1017 *
1018 * bit 0 : USI_RXFIFO_FULL
1019 * - 0 : Rx FIFO not full
1020 * - 1 : Rx FIFO is full
1021 *
1022 */
USI_SSI_GetRxFIFOStatus(USI_TypeDef * usi_dev)1023 u32 USI_SSI_GetRxFIFOStatus(USI_TypeDef *usi_dev)
1024 {
1025 return usi_dev->RX_FIFO_STATUS;
1026 }
1027
1028 /**
1029 * @brief Get USI-SPI transfer status.
1030 * @param usi_dev: where usi_dev can be USI0_DEV.
1031 * @retval Current transfer status,each bit of this value represents one
1032 * transfer status which is as follows:
1033 *
1034 * bit 4 : USI_SPI_SLV_RX_ACTIVITY
1035 * - 0 : SPI slave Rx path idle
1036 * - 1 : SPI slave Rx path is active
1037 *
1038 * bit 3 : USI_SPI_SLV_TX_ACTIVITY
1039 * - 0 : SPI slave Tx path idle
1040 * - 1 : SPI slave Tx path is active
1041 *
1042 * bit 2 : USI_SPI_MST_RX_ACTIVITY
1043 * - 0 : SPI master Rx path idle
1044 * - 1 : SPI master Rx path is active
1045 *
1046 * bit 1 : USI_SPI_MST_TX_ACTIVITY
1047 * - 0 : SPI master Tx path idle
1048 * - 1 : SPI master Tx path is active
1049 *
1050 * bit 0 : USI_SPI_ACTIVITY
1051 * - 0 : idle
1052 * - 1 : active transferring data
1053 *
1054 */
USI_SSI_GetTransStatus(USI_TypeDef * usi_dev)1055 u32 USI_SSI_GetTransStatus(USI_TypeDef *usi_dev)
1056 {
1057 return usi_dev->SPI_TRANS_STATUS;
1058 }
1059
1060
1061 /**
1062 * @brief Get USI-SPI data frame size.
1063 * @param usi_dev: where usi_dev can be USI0_DEV.
1064 * @retval Data frame size(value range : 4-16):
1065 * - n : current data frame length is n bits
1066 */
1067
USI_SSI_GetDataFrameSize(USI_TypeDef * usi_dev)1068 u32 USI_SSI_GetDataFrameSize(USI_TypeDef *usi_dev)
1069 {
1070 u32 size = ((usi_dev->SPI_CTRL) & USI_SPI_DAT_FRM_SIZE) + 1;
1071 return size;
1072 }
1073
1074 /**
1075 * @brief Detemine USI-SPI is busy or not.
1076 * @param usi_dev: where usi_dev can be USI0_DEV.
1077 * @retval USI-SPI busy status value:
1078 * - 1: Busy
1079 * - 0: Not Busy
1080 */
1081
USI_SSI_Busy(USI_TypeDef * usi_dev)1082 u32 USI_SSI_Busy(USI_TypeDef *usi_dev)
1083 {
1084 u32 Status = USI_SSI_GetTransStatus(usi_dev);
1085 u32 Busy = (((Status & USI_SPI_ACTIVITY) != 0) ? 1 : 0);
1086
1087 return Busy;
1088 }
1089
1090 /**
1091 * @brief Get USI-SPI Interrupt Status.
1092 * @param usi_dev: where usi_dev can be USI0_DEV.
1093 * @retval Current Interrupt Status,each bit of this value represents one
1094 * interrupt status which is as follows:
1095 *
1096 * bit 16: USI_SPI_RX_DATA_FRM_ERR_INTS
1097 * - 0 : spi_rx_data_frame_err_intr interrupt not active after masking
1098 * - 1 : spi_rx_data_frame_err_intr interrupt is active after masking
1099
1100 * bit 6 : USI_RXFIFO_UNDERFLOW_INTS
1101 * - 0 : rxfifo_underflow_intr interrupt not active after masking
1102 * - 1 : rxfifo_underflow_intr interrupt is active after masking
1103 *
1104 * bit 5 : USI_RXFIFO_OVERFLOW_INTS
1105 * - 0 : rxfifo_overflow_intr interrupt is not active after masking
1106 * - 1 : rxfifo_overflow_intr interrupt is full after masking
1107 *
1108 * bit 4 : USI_RXFIFO_ALMOST_FULL_INTS
1109 * - 0 : rxfifo_almost_full_intr interrupt is not active after masking
1110 * - 1 : rxfifo_almost_full_intr interrupt is active after masking
1111 *
1112 * bit 2 : USI_TXFIFO_UNDERFLOW_INTS
1113 * - 0 : txfifo_underflow_intr interrupt is not active after masking
1114 * - 1 : txfifo_underflow_intr interrupt is active after masking
1115 *
1116 * bit 1 : USI_TXFIFO_OVERFLOW_INTS
1117 * - 0 : txfifo_overflow_intr interrupt is not active after masking
1118 * - 1 : txfifo_overflow_intr interrupt is active after masking
1119 *
1120 * bit 0 : USI_TXFIFO_ALMOST_EMTY_INTS
1121 * - 0 : txfifo_almost_empty_intr interrupt is not active after masking
1122 * - 1 : txfifo_almost_empty_intr interrupt is active after masking
1123 */
1124
USI_SSI_GetIsr(USI_TypeDef * usi_dev)1125 u32 USI_SSI_GetIsr(USI_TypeDef *usi_dev)
1126 {
1127 return usi_dev->INTERRUPT_STATUS;
1128 }
1129
1130 /**
1131 * @brief Get USI-SPI Raw Interrupt Status.
1132 * @param usi_dev: where usi_dev can be USI0_DEV.
1133 * @retval Current Raw Interrupt Status,each bit of this value represents one
1134 * raw interrupt status which is as follows:
1135 *
1136 * bit 16: USI_SPI_RX_DATA_FRM_ERR_RSTS
1137 * - 0 : spi_rx_data_frame_err_intr interrupt not active before masking
1138 * - 1 : spi_rx_data_frame_err_intr interrupt is active before masking
1139 *
1140 * bit 6 : USI_RXFIFO_UNDERFLOW_RSTS
1141 * - 0 : rxfifo_underflow_intr interrupt not active before masking
1142 * - 1 : rxfifo_underflow_intr interrupt is active before masking
1143 *
1144 * bit 5 : USI_RXFIFO_OVERFLOW_RSTS
1145 * - 0 : rxfifo_overflow_intr interrupt is not active before masking
1146 * - 1 : rxfifo_overflow_intr interrupt is full before masking
1147 *
1148 * bit 4 : USI_RXFIFO_ALMOST_FULL_RSTS
1149 * - 0 : rxfifo_almost_full_intr interrupt is not active before masking
1150 * - 1 : rxfifo_almost_full_intr interrupt is active before masking
1151 *
1152 * bit 2 : USI_TXFIFO_UNDERFLOW_RSTS
1153 * - 0 : txfifo_underflow_intr interrupt is not active before masking
1154 * - 1 : txfifo_underflow_intr interrupt is active before masking
1155 *
1156 * bit 1 : USI_TXFIFO_OVERFLOW_RSTS
1157 * - 0 : txfifo_overflow_intr interrupt is not active before masking
1158 * - 1 : txfifo_overflow_intr interrupt is active before masking
1159 *
1160 * bit 0 : USI_TXFIFO_ALMOST_EMTY_RSTS
1161 * - 0 : txfifo_almost_empty_intr interrupt is not active before masking
1162 * - 1 : txfifo_almost_empty_intr interrupt is active before masking
1163 *
1164 */
USI_SSI_GetRawIsr(USI_TypeDef * usi_dev)1165 u32 USI_SSI_GetRawIsr(USI_TypeDef *usi_dev)
1166 {
1167 return usi_dev->RAW_INTERRUPT_STATUS;
1168 }
1169
1170
1171 /******************* (C) COPYRIGHT 2016 Realtek Semiconductor *****END OF FILE****/
1172
1173