1 /**
2 ******************************************************************************
3 * @file rtl8721dhp_ssi.c
4 * @author
5 * @version V1.0.0
6 * @date 2016-05-17
7 * @brief This file contains all the functions prototypes for Serial peripheral interface (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 * - SPI device pinmux initialization and deinitialization
16 * - DMA transfers management
17 * - Interrupts and management
18 *
19 ******************************************************************************
20 * @attention
21 *
22 * This module is a confidential and proprietary property of RealTek and
23 * possession or use of this module requires written permission of RealTek.
24 *
25 * Copyright(c) 2016, Realtek Semiconductor Corporation. All rights reserved.
26 ******************************************************************************
27 */
28
29 #include "ameba_soc.h"
30
31 /** @addtogroup SPI_Exported_Functions
32 *@verbatim
33 *
34 * ===================================================================
35 * How to use this driver
36 * ===================================================================
37 * 1. Enable peripheral clock using the following functions
38 * RCC_PeriphClockCmd(APBPeriph_SPI0, APBPeriph_SPI0_CLOCK, ENABLE) for SPI0;
39 * RCC_PeriphClockCmd(APBPeriph_SPI1, APBPeriph_SPI1_CLOCK, ENABLE) for SPI1;
40 *
41 * 2. Configure the SPIx pinmux.
42 * PinCtrl(PERIPHERAL_SPI0, PinmuxSelect, ON) for SPI0;
43 * PinCtrl(PERIPHERAL_SPI1, PinmuxSelect, ON) for SPI1;
44 *
45 * 3. Disable the SPI using the SSI_Cmd() function
46 *
47 * 4. Program the Polarity,Phase,Transfer Mode,Baud Rate Prescaler,DataFrameSize,
48 * Interrupt TRx Threshold level,DMA TRx Threshold level and other parameters using
49 * the SSI_Init() function.
50 *
51 * 5. Enable the SPI using the SSI_Cmd() function
52 *
53 * 6. When using poll:
54 * -Using SSI_Writeable() function make sure that the transmit FIFO is not full,
55 * then using SSI_WriteData() function to send data
56 *
57 * -Using SSI_Readable() function make sure that the receive FIFO is not empty,
58 * then using SSI_ReadData() function to receive data
59 *
60 * 7. Enable corresponding interrupt using the function SSI_INTConfig() if you need to
61 * use interrupt mode.
62 *
63 * 8. When using the DMA mode
64 * - Configure & Initialize the DMA
65 * - Active the DMA Tx or Rx using SSI_SetDmaEnable() function
66 *
67 * @endverbatim
68 */
69
70
71 const SPI_DevTable SPI_DEV_TABLE[2] = {
72 {SPI0_DEV, GDMA_HANDSHAKE_INTERFACE_SPI0_TX, GDMA_HANDSHAKE_INTERFACE_SPI0_RX, SPI0_IRQ},
73 {SPI1_DEV, GDMA_HANDSHAKE_INTERFACE_SPI1_TX, GDMA_HANDSHAKE_INTERFACE_SPI1_RX, SPI1_IRQ},
74 };
75
76 /**
77 * @brief Fills each SSI_InitStruct member with its default value.
78 * @param SSI_InitStruct: pointer to a SSI_InitTypeDef structure which will be
79 * initialized.
80 * @retval None
81 */
82 void
SSI_StructInit(SSI_InitTypeDef * SSI_InitStruct)83 SSI_StructInit(SSI_InitTypeDef* SSI_InitStruct)
84 {
85 SSI_InitStruct->SPI_RxThresholdLevel = 0; // if number of entries in th RX FIFO >= (RxThresholdLevel+1), RX interrupt asserted
86 SSI_InitStruct->SPI_TxThresholdLevel = 32; // if number of entries in th TX FIFO <= TxThresholdLevel, TX interrupt asserted
87 SSI_InitStruct->SPI_DmaRxDataLevel = 3;
88 #ifdef SPI_SLAVE_TXERR_WORK_AROUND
89 SSI_InitStruct->SPI_DmaTxDataLevel = 48;
90 #else
91 SSI_InitStruct->SPI_DmaTxDataLevel = 56;
92 #endif
93 SSI_InitStruct->SPI_SlaveSelectEnable = 0;
94 SSI_InitStruct->SPI_ClockDivider = 6;
95 SSI_InitStruct->SPI_DataFrameNumber = 0;
96 SSI_InitStruct->SPI_DataFrameFormat = FRF_MOTOROLA_SPI;
97 SSI_InitStruct->SPI_DataFrameSize = DFS_8_BITS;
98 SSI_InitStruct->SPI_InterruptMask = 0x0;
99 SSI_InitStruct->SPI_SclkPhase = SCPH_TOGGLES_AT_START;
100 SSI_InitStruct->SPI_SclkPolarity = SCPOL_INACTIVE_IS_HIGH;
101 SSI_InitStruct->SPI_TransferMode = TMOD_TR;
102 SSI_InitStruct->SPI_MicrowireControlFrameSize = CFS_1_BIT;
103 SSI_InitStruct->SPI_MicrowireDirection = MW_DIRECTION_MASTER_TO_SLAVE;
104 SSI_InitStruct->SPI_MicrowireHandshaking = MW_HANDSHAKE_DISABLE;
105 SSI_InitStruct->SPI_MicrowireTransferMode = MW_TMOD_NONSEQUENTIAL;
106 }
107
108
109 /**
110 * @brief Initializes the SPI registers according to the specified parameters
111 * in SSI_InitStruct.
112 * @param spi_dev: where spi_dev can be SPI0_DEV or SPI1_DEV.
113 * @param SSI_InitStruct: pointer to a SSI_InitTypeDef structure that contains
114 * the configuration information for the SPI peripheral.
115 * @retval None
116 */
117
SSI_Init(SPI_TypeDef * spi_dev,SSI_InitTypeDef * SSI_InitStruct)118 void SSI_Init(SPI_TypeDef *spi_dev, SSI_InitTypeDef *SSI_InitStruct)
119 {
120 u32 TempValue = 0;
121
122 SSI_Cmd(spi_dev, DISABLE);
123
124 /* REG_DW_SSI_CTRLR0 */
125 TempValue |= SSI_InitStruct->SPI_DataFrameSize;
126 TempValue |= (SSI_InitStruct->SPI_DataFrameFormat << 4);
127 TempValue |= (SSI_InitStruct->SPI_SclkPhase << 6);
128 TempValue |= (SSI_InitStruct->SPI_SclkPolarity << 7);
129 TempValue |= (SSI_InitStruct->SPI_TransferMode << 8);
130 TempValue |= (SSI_InitStruct->SPI_MicrowireControlFrameSize << 12);
131 TempValue &= ~BIT_CTRLR0_SLV_OE;//(SlaveOutputEnable);
132
133 spi_dev->CTRLR0 = TempValue;
134
135 /* REG_DW_SSI_TXFTLR */
136 spi_dev->TXFTLR = SSI_InitStruct->SPI_TxThresholdLevel;
137
138 /* REG_DW_SSI_RXFTLR */
139 spi_dev->RXFTLR = SSI_InitStruct->SPI_RxThresholdLevel;
140
141 /* Master Only:REG_DW_SSI_CTRLR1, REG_DW_SSI_SER, REG_DW_SSI_BAUDR*/
142 if (SSI_InitStruct->SPI_Role & SSI_MASTER) {
143 spi_dev->CTRLR1 = SSI_InitStruct->SPI_DataFrameNumber;
144 SSI_SetSlaveEnable(spi_dev, SSI_InitStruct->SPI_SlaveSelectEnable);
145 spi_dev->BAUDR = SSI_InitStruct->SPI_ClockDivider;
146 }
147
148 // Microwire
149 TempValue = 0;
150 TempValue |= SSI_InitStruct->SPI_MicrowireTransferMode;
151 TempValue |= (SSI_InitStruct->SPI_MicrowireDirection << 1);
152 TempValue |= (SSI_InitStruct->SPI_MicrowireHandshaking << 2);
153
154 spi_dev->MWCR = TempValue;
155
156 /* REG_DW_SSI_IMR */
157 spi_dev->IMR = SSI_InitStruct->SPI_InterruptMask;
158
159 /*DMA level set */
160 SSI_SetDmaLevel(spi_dev, SSI_InitStruct->SPI_DmaTxDataLevel, SSI_InitStruct->SPI_DmaRxDataLevel);
161
162 SSI_Cmd(spi_dev, ENABLE);
163 }
164
165 /**
166 * @brief Enables or disables SPIx peripheral.
167 * @param spi_dev: where spi_dev can be SPI0_DEV or SPI1_DEV.
168 * @param NewStatus: This parameter can be one of the following values:
169 * @arg ENABLE
170 * @arg DISABLE
171 * @retval None
172 */
173
SSI_Cmd(SPI_TypeDef * spi_dev,u32 NewStatus)174 void SSI_Cmd(SPI_TypeDef *spi_dev, u32 NewStatus)
175 {
176 if (NewStatus != DISABLE) {
177 spi_dev->SSIENR |= BIT_SSIENR_SSI_EN;
178 } else {
179 spi_dev->SSIENR &= ~BIT_SSIENR_SSI_EN;
180 }
181 }
182
183 /**
184 * @brief Masks or unmasks SPIx interrupt.
185 * @param spi_dev: where spi_dev can be SPI0_DEV or SPI1_DEV.
186 * @param SSI_IT: This parameter can be one of the following values or mixed:
187 * @arg BIT_IMR_TXEIM
188 * @arg BIT_IMR_TXOIM
189 * @arg BIT_IMR_RXUIM
190 * @arg BIT_IMR_RXOIM
191 * @arg BIT_IMR_RXFIM
192 * @arg BIT_IMR_MSTIM
193 * @arg BIT_IMR_FAEIM
194 * @arg BIT_IMR_TXUIM
195 * @arg BIT_IMR_SSRIM
196 * @param newState:This parameter can be one of the following values:
197 * @arg ENABLE
198 * @arg DISABLE
199 * @retval None
200 * @note BIT_IMR_MSTIM is for Master only, and BIT_IMR_FAEIM, BIT_IMR_TXUIM, BIT_IMR_SSRIM
201 * are for Slave only.
202 */
203 VOID
SSI_INTConfig(SPI_TypeDef * spi_dev,u32 SSI_IT,u32 newState)204 SSI_INTConfig(SPI_TypeDef* spi_dev, u32 SSI_IT, u32 newState)
205 {
206 if (newState == ENABLE) {
207 /* Enable the selected SSI interrupts */
208 spi_dev->IMR |= SSI_IT;
209 } else {
210 /* Disable the selected SSI interrupts */
211 spi_dev->IMR &= ~SSI_IT;
212 }
213 }
214
215 /**
216 * @brief Set SPI0 as Master or Slave.
217 * @param spi_dev: where spi_dev can be SPI0_DEV.
218 * @param role: This parameter can be one of the following values:
219 * @arg SSI_MASTER
220 * @arg SSI_SLAVE
221 * @retval None
222 */
SSI_SetRole(SPI_TypeDef * spi_dev,u32 role)223 void SSI_SetRole(SPI_TypeDef *spi_dev, u32 role)
224 {
225 u32 Temp;
226
227 assert_param(spi_dev == SPI0_DEV);
228
229 Temp = HAL_READ32(SYSTEM_CTRL_BASE, REG_HS_SPI_CTRL);
230 Temp &= ~BIT_HS_SPI0_ROLE_SELECT;
231 Temp |= (role << 3);
232 HAL_WRITE32(SYSTEM_CTRL_BASE, REG_HS_SPI_CTRL, Temp);
233 }
234
235
236 /**
237 * @brief Set SPIx clock polarity.
238 * @param spi_dev: where spi_dev can be SPI0_DEV or SPI1_DEV.
239 * @param SclkPolarity: This parameter can be one of the following values:
240 * @arg SCPOL_INACTIVE_IS_HIGH
241 * @arg SCPOL_INACTIVE_IS_LOW
242 * @retval None
243 */
244
SSI_SetSclkPolarity(SPI_TypeDef * spi_dev,u32 SclkPolarity)245 void SSI_SetSclkPolarity(SPI_TypeDef *spi_dev, u32 SclkPolarity)
246 {
247 u32 Ctrlr0Value;
248
249 Ctrlr0Value = spi_dev->CTRLR0;
250 Ctrlr0Value &= ~BIT_CTRLR0_SCPOL;
251 Ctrlr0Value |= (SclkPolarity << 7);
252
253 SSI_Cmd(spi_dev, DISABLE);
254 spi_dev->CTRLR0 = Ctrlr0Value;
255 SSI_Cmd(spi_dev, ENABLE);
256 }
257
258 /**
259 * @brief Set SPIx clock phase.
260 * @param spi_dev: where spi_dev can be SPI0_DEV or SPI1_DEV.
261 * @param SclkPhase: This parameter can be one of the following values:
262 * @arg SCPH_TOGGLES_AT_START
263 * @arg SCPH_TOGGLES_IN_MIDDLE
264 * @retval None
265 */
266
SSI_SetSclkPhase(SPI_TypeDef * spi_dev,u32 SclkPhase)267 void SSI_SetSclkPhase(SPI_TypeDef *spi_dev, u32 SclkPhase)
268 {
269 u32 Ctrlr0Value;
270
271 Ctrlr0Value = spi_dev->CTRLR0;
272 Ctrlr0Value &= ~BIT_CTRLR0_SCPH;
273 Ctrlr0Value |= (SclkPhase << 6);
274
275 SSI_Cmd(spi_dev, DISABLE);
276 spi_dev->CTRLR0 = Ctrlr0Value;
277 SSI_Cmd(spi_dev, ENABLE);
278 }
279
280 /**
281 * @brief Set SPIx data frame size.
282 * @param spi_dev: where spi_dev can be SPI0_DEV or SPI1_DEV.
283 * @param DataFrameSize: This parameter can be one of the following values:
284 * @arg DFS_4_BITS
285 * @arg DFS_5_BITS
286 * @arg DFS_6_BITS
287 * @arg DFS_7_BITS
288 * @arg DFS_8_BITS
289 * @arg DFS_9_BITS
290 * @arg DFS_10_BITS
291 * @arg DFS_11_BITS
292 * @arg DFS_12_BITS
293 * @arg DFS_13_BITS
294 * @arg DFS_14_BITS
295 * @arg DFS_15_BITS
296 * @arg DFS_16_BITS
297 * @retval None
298 */
299
SSI_SetDataFrameSize(SPI_TypeDef * spi_dev,u32 DataFrameSize)300 void SSI_SetDataFrameSize(SPI_TypeDef *spi_dev, u32 DataFrameSize)
301 {
302 u32 Ctrlr0Value;
303
304 Ctrlr0Value = spi_dev->CTRLR0;
305 Ctrlr0Value &= ~BIT_CTRLR0_DFS;
306 Ctrlr0Value |= DataFrameSize;
307
308 SSI_Cmd(spi_dev, DISABLE);
309 spi_dev->CTRLR0 = Ctrlr0Value;
310 SSI_Cmd(spi_dev, ENABLE);
311 }
312
313 /**
314 * @brief Set SPI SS Toggle Phase.
315 * @param spi_dev: where spi_dev can be SPI0_DEV or SPI1_DEV.
316 * @param TogglePhase: This parameter can be one of the following values:
317 * @arg SPI_SS_NOT_TOGGLE , means SPI support continuous transfer when spi_cph=0
318 * @arg SPI_SS_TOGGLE, means SPI donot support continuous transfer when spi_cph=0
319 * and SS(CS) needs break.
320 * @retval None
321 * @note SS Toggle function is valid only for master.
322 */
SSI_SetSSTogglePhase(SPI_TypeDef * spi_dev,u32 TogglePhase)323 void SSI_SetSSTogglePhase(SPI_TypeDef *spi_dev, u32 TogglePhase)
324 {
325 u32 Ctrlr0Value;
326
327 Ctrlr0Value = spi_dev->CTRLR0;
328 Ctrlr0Value &= ~BIT_CTRLR0_SSTOGGLE;
329 Ctrlr0Value |= (TogglePhase << 31);
330
331 SSI_Cmd(spi_dev, DISABLE);
332 spi_dev->CTRLR0 = Ctrlr0Value;
333 SSI_Cmd(spi_dev, ENABLE);
334 }
335
336
337 /**
338 * @brief Set or reset SPIx data swap bit.
339 * @param spi_dev: where spi_dev can be SPI0_DEV or SPI1_DEV.
340 * @param SwapStatus: This parameter can be one of the following values or mixed:
341 * @arg BIT_CTRLR0_TXBYTESWP
342 * @arg BIT_CTRLR0_TXBITSWP
343 * @arg BIT_CTRLR0_RXBYTESWP
344 * @arg BIT_CTRLR0_RXBITSWP
345 * @param newState:This parameter can be one of the following values:
346 * @arg ENABLE
347 * @arg DISABLE
348 * @retval None
349 */
SSI_SetDataSwap(SPI_TypeDef * spi_dev,u32 SwapStatus,u32 newState)350 void SSI_SetDataSwap(SPI_TypeDef *spi_dev, u32 SwapStatus, u32 newState)
351 {
352 u32 Ctrlr0Value = spi_dev->CTRLR0;
353
354 if(newState == ENABLE)
355 Ctrlr0Value |= SwapStatus;
356 else
357 Ctrlr0Value &= ~SwapStatus;
358
359 SSI_Cmd(spi_dev, DISABLE);
360 spi_dev->CTRLR0 = Ctrlr0Value;
361 SSI_Cmd(spi_dev, ENABLE);
362 }
363
364 /**
365 * @brief Set SPIx Rx Sample Dealy. support form AZ BCUT
366 * @param spi_dev: where spi_dev can be SPI0_DEV or SPI1_DEV.
367 * @param SampleDelay: The number of ssi_clk cycles that to be delayed.
368 * @retval None
369 */
370
SSI_SetSampleDelay(SPI_TypeDef * spi_dev,u32 SampleDelay)371 void SSI_SetSampleDelay(SPI_TypeDef *spi_dev, u32 SampleDelay)
372 {
373 SSI_Cmd(spi_dev, DISABLE);
374 spi_dev->RX_SAMPLE_DLY = (SampleDelay & BIT_RX_SAMPLE_DELAY);
375 SSI_Cmd(spi_dev, ENABLE);
376 }
377
378 /**
379 * @brief Set SPI1 the number of data frame to be received.
380 * @note Valid only when the device is configured as a master in following mode:
381 * TMOD_RO || TMOD_EEPROM_R || (FRF_NS_MICROWIRE && MW_TMOD_SEQUENTIAL)
382 * @param spi_dev: where spi_dev can be SPI0_DEV or SPI1_DEV.
383 * @param DataFrameNumber: The number of data frames that to be received.
384 * @retval None
385 */
386
SSI_SetReadLen(SPI_TypeDef * spi_dev,u32 DataFrameNumber)387 void SSI_SetReadLen(SPI_TypeDef *spi_dev, u32 DataFrameNumber)
388 {
389 assert_param((DataFrameNumber >= 1)&&(DataFrameNumber <= 0x10000));
390 SSI_Cmd(spi_dev, DISABLE);
391 spi_dev->CTRLR1 = DataFrameNumber - 1;
392 SSI_Cmd(spi_dev, ENABLE);
393 }
394
395 /**
396 * @brief Set SPI1 clock divider.
397 * @note Valid only when the device is configured as a master.
398 * And The LSB is always set to 0,and is unaffected by a write operation.
399 * @param spi_dev: where spi_dev can only be SPI1_DEV.
400 * @param ClockDivider: Even value between 2 and 65534.
401 * And Fsclk_out=Fssi_clk/ClockDivider.
402 * @retval None
403 */
404
SSI_SetBaudDiv(SPI_TypeDef * spi_dev,u32 ClockDivider)405 void SSI_SetBaudDiv(SPI_TypeDef *spi_dev, u32 ClockDivider)
406 {
407 SSI_Cmd(spi_dev, DISABLE);
408 spi_dev->BAUDR = (ClockDivider & BIT_BAUDR_SCKDV);
409 SSI_Cmd(spi_dev, ENABLE);
410 }
411
412
413
414 /**
415 * @brief Enables or disables SPIx TDMA and RDMA .
416 * @param spi_dev: where spi_dev can be SPI0_DEV or SPI1_DEV.
417 * @param newState: This parameter can be one of the following values:
418 * @arg ENABLE
419 * @arg DISABLE
420 * @param Mask: This parameter can be one of the following values or mixed:
421 * @arg BIT_SHIFT_DMACR_RDMAE
422 * @arg BIT_SHIFT_DMACR_TDMAE
423 * @retval None
424 */
425
SSI_SetDmaEnable(SPI_TypeDef * spi_dev,u32 newState,u32 Mask)426 void SSI_SetDmaEnable(SPI_TypeDef *spi_dev, u32 newState, u32 Mask)
427 {
428 if (newState == DISABLE)
429 spi_dev->DMACR &= ~Mask;
430 else
431 spi_dev->DMACR |= Mask;
432 }
433
434 /**
435 * @brief Set SPIx DMA TxLevel and RxLevel.
436 * @param spi_dev: where spi_dev can be SPI0_DEV or SPI1_DEV.
437 * @param TxLevel: Transmit FIFO Threshold level.Value range: 0 to 63.
438 * The dma_tx_req is generated when the number of valid data entries in
439 * the transmit FIFO is equal to or below this field value.
440 * @param RxLevel: Receive FIFO Threshold level.Value range: 0 to 63.
441 * The dma_rx_req is generated when the number of valid data entries in the
442 * receive FIFO is equal to or above this field value + 1.
443 * @retval None
444 */
445
SSI_SetDmaLevel(SPI_TypeDef * spi_dev,u32 TxLevel,u32 RxLevel)446 void SSI_SetDmaLevel(SPI_TypeDef *spi_dev, u32 TxLevel, u32 RxLevel)
447 {
448 /* Set TX FIFO water level to trigger Tx DMA transfer */
449 spi_dev->DMATDLR = TxLevel;
450
451 /* Set RX FIFO water level to trigger Rx DMA transfer */
452 spi_dev->DMARDLR = RxLevel;
453 }
454
455 /**
456 * @brief Init and Enable SPI TX GDMA.
457 * @param Index: 0 or 1.
458 * @param GDMA_InitStruct: pointer to a GDMA_InitTypeDef structure that contains
459 * the configuration information for the GDMA peripheral.
460 * @param CallbackData: GDMA callback data.
461 * @param CallbackFunc: GDMA callback function.
462 * @param pTxData: Tx Buffer.
463 * @param Length: Tx Count.
464 * @retval TRUE/FLASE
465 */
466
SSI_TXGDMA_Init(u32 Index,PGDMA_InitTypeDef GDMA_InitStruct,void * CallbackData,IRQ_FUN CallbackFunc,u8 * pTxData,u32 Length)467 BOOL SSI_TXGDMA_Init(
468 u32 Index,
469 PGDMA_InitTypeDef GDMA_InitStruct,
470 void *CallbackData,
471 IRQ_FUN CallbackFunc,
472 u8 *pTxData,
473 u32 Length
474 )
475 {
476 SPI_TypeDef *SPIx = SPI_DEV_TABLE[Index].SPIx;
477 u32 DataFrameSize = SSI_GetDataFrameSize(SPIx);
478 u8 GdmaChnl;
479
480 assert_param(GDMA_InitStruct != NULL);
481
482 GdmaChnl = GDMA_ChnlAlloc(0, CallbackFunc, (u32)CallbackData, 12);//ACUT is 0x10, BCUT is 12
483 if (GdmaChnl == 0xFF) {
484 // No Available DMA channel
485 return _FALSE;
486 }
487
488 _memset((void *)GDMA_InitStruct, 0, sizeof(GDMA_InitTypeDef));
489
490 GDMA_InitStruct->GDMA_DIR = TTFCMemToPeri;
491 GDMA_InitStruct->GDMA_DstHandshakeInterface = SPI_DEV_TABLE[Index].Tx_HandshakeInterface;
492 GDMA_InitStruct->GDMA_DstAddr = (u32)&SPI_DEV_TABLE[Index].SPIx->DR;
493 GDMA_InitStruct->GDMA_Index = 0;
494 GDMA_InitStruct->GDMA_ChNum = GdmaChnl;
495 GDMA_InitStruct->GDMA_IsrType = (BlockType|TransferType|ErrType);
496
497 GDMA_InitStruct->GDMA_SrcMsize = MsizeOne;
498 GDMA_InitStruct->GDMA_DstMsize = MsizeFour;
499 GDMA_InitStruct->GDMA_SrcDataWidth = TrWidthFourBytes;
500 GDMA_InitStruct->GDMA_DstDataWidth = TrWidthOneByte;
501 GDMA_InitStruct->GDMA_DstInc = NoChange;
502 GDMA_InitStruct->GDMA_SrcInc = IncType;
503
504 /* Cofigure GDMA transfer */
505 if (DataFrameSize > 8) {
506 /* 16~9 bits mode */
507 if (((Length & 0x03)==0) && (((u32)(pTxData) & 0x03)==0)) {
508 /* 4-bytes aligned, move 4 bytes each transfer */
509 GDMA_InitStruct->GDMA_SrcMsize = MsizeFour;
510 GDMA_InitStruct->GDMA_SrcDataWidth = TrWidthFourBytes;
511 GDMA_InitStruct->GDMA_DstMsize = MsizeEight;
512 GDMA_InitStruct->GDMA_DstDataWidth = TrWidthTwoBytes;
513 GDMA_InitStruct->GDMA_BlockSize = Length >> 2;
514 } else if (((Length & 0x01)==0) && (((u32)(pTxData) & 0x01)==0)) {
515 /* 2-bytes aligned, move 2 bytes each transfer */
516 GDMA_InitStruct->GDMA_SrcMsize = MsizeEight;
517 GDMA_InitStruct->GDMA_SrcDataWidth = TrWidthTwoBytes;
518 GDMA_InitStruct->GDMA_DstMsize = MsizeEight;
519 GDMA_InitStruct->GDMA_DstDataWidth = TrWidthTwoBytes;
520 GDMA_InitStruct->GDMA_BlockSize = Length >> 1;
521 } else {
522 DBG_8195A("SSI_TXGDMA_Init: Aligment Err: pTxData=0x%x, Length=%d\n", pTxData, Length);
523 return _FALSE;
524 }
525 } else {
526 /* 8~4 bits mode */
527 if (((Length & 0x03)==0) && (((u32)(pTxData) & 0x03)==0)) {
528 /* 4-bytes aligned, move 4 bytes each transfer */
529 GDMA_InitStruct->GDMA_SrcMsize = MsizeOne;
530 GDMA_InitStruct->GDMA_SrcDataWidth = TrWidthFourBytes;
531 GDMA_InitStruct->GDMA_BlockSize = Length >> 2;
532 } else {
533 GDMA_InitStruct->GDMA_SrcMsize = MsizeFour;
534 GDMA_InitStruct->GDMA_SrcDataWidth = TrWidthOneByte;
535 GDMA_InitStruct->GDMA_BlockSize = Length;
536 }
537 GDMA_InitStruct->GDMA_DstMsize = MsizeFour;
538 GDMA_InitStruct->GDMA_DstDataWidth = TrWidthOneByte;
539 }
540
541 assert_param(GDMA_InitStruct->GDMA_BlockSize <= 4096);
542
543 GDMA_InitStruct->GDMA_SrcAddr = (u32)pTxData;
544
545 /* Enable GDMA for TX */
546 GDMA_Init(GDMA_InitStruct->GDMA_Index, GDMA_InitStruct->GDMA_ChNum, GDMA_InitStruct);
547 GDMA_Cmd(GDMA_InitStruct->GDMA_Index, GDMA_InitStruct->GDMA_ChNum, ENABLE);
548
549 return _TRUE;
550 }
551
552 /**
553 * @brief Init and Enable SPI RX GDMA.
554 * @param Index: 0 or 1.
555 * @param GDMA_InitStruct: pointer to a GDMA_InitTypeDef structure that contains
556 * the configuration information for the GDMA peripheral.
557 * @param CallbackData: GDMA callback data.
558 * @param CallbackFunc: GDMA callback function.
559 * @param pRxData: Rx Buffer.
560 * @param Length: Rx Count.
561 * @retval TRUE/FLASE
562 */
563
564 BOOL
SSI_RXGDMA_Init(u8 Index,GDMA_InitTypeDef * GDMA_InitStruct,void * CallbackData,IRQ_FUN CallbackFunc,u8 * pRxData,u32 Length)565 SSI_RXGDMA_Init(
566 u8 Index,
567 GDMA_InitTypeDef *GDMA_InitStruct,
568 void *CallbackData,
569 IRQ_FUN CallbackFunc,
570 u8 *pRxData,
571 u32 Length
572 )
573 {
574 SPI_TypeDef *SPIx = SPI_DEV_TABLE[Index].SPIx;
575 u32 DataFrameSize = SSI_GetDataFrameSize(SPIx);
576 u8 GdmaChnl;
577
578 assert_param(GDMA_InitStruct != NULL);
579
580 GdmaChnl = GDMA_ChnlAlloc(0, CallbackFunc, (u32)CallbackData, 12);//ACUT is 0x10, BCUT is 12
581 if (GdmaChnl == 0xFF) {
582 // No Available DMA channel
583 return _FALSE;
584 }
585
586 _memset((void *)GDMA_InitStruct, 0, sizeof(GDMA_InitTypeDef));
587
588 GDMA_InitStruct->GDMA_DIR = TTFCPeriToMem;
589 GDMA_InitStruct->GDMA_ReloadSrc = 0;
590 GDMA_InitStruct->GDMA_SrcHandshakeInterface = SPI_DEV_TABLE[Index].Rx_HandshakeInterface;
591 GDMA_InitStruct->GDMA_SrcAddr = (u32)&SPI_DEV_TABLE[Index].SPIx->DR;
592 GDMA_InitStruct->GDMA_Index = 0;
593 GDMA_InitStruct->GDMA_ChNum = GdmaChnl;
594 GDMA_InitStruct->GDMA_IsrType = (BlockType|TransferType|ErrType);
595
596 GDMA_InitStruct->GDMA_SrcMsize = MsizeEight;
597 GDMA_InitStruct->GDMA_DstMsize = MsizeFour;
598 GDMA_InitStruct->GDMA_SrcDataWidth = TrWidthTwoBytes;
599 GDMA_InitStruct->GDMA_DstDataWidth = TrWidthFourBytes;
600 GDMA_InitStruct->GDMA_DstInc = IncType;
601 GDMA_InitStruct->GDMA_SrcInc = NoChange;
602
603 /* Cofigure GDMA transfer */
604 if (DataFrameSize > 8) {
605 /* 16~9 bits mode */
606 GDMA_InitStruct->GDMA_SrcMsize = MsizeFour;
607 GDMA_InitStruct->GDMA_SrcDataWidth = TrWidthTwoBytes;
608 GDMA_InitStruct->GDMA_BlockSize = Length >> 1;
609
610 if (((Length & 0x03)==0) && (((u32)(pRxData) & 0x03)==0)) {
611 /* 4-bytes aligned, move 4 bytes each transfer */
612 GDMA_InitStruct->GDMA_DstMsize = MsizeFour;
613 GDMA_InitStruct->GDMA_DstDataWidth = TrWidthFourBytes;
614 } else if (((Length & 0x01)==0) && (((u32)(pRxData) & 0x01)==0)) {
615 /* 2-bytes aligned, move 2 bytes each transfer */
616 GDMA_InitStruct->GDMA_DstMsize = MsizeEight;
617 GDMA_InitStruct->GDMA_DstDataWidth = TrWidthTwoBytes;
618 } else {
619 DBG_8195A("SSI_RXGDMA_Init: Aligment Err: pTxData=0x%x, Length=%d\n", pRxData, Length);
620 return _FALSE;
621 }
622 } else {
623 /* 8~4 bits mode */
624 GDMA_InitStruct->GDMA_SrcMsize = MsizeFour;
625 GDMA_InitStruct->GDMA_SrcDataWidth = TrWidthOneByte;
626 GDMA_InitStruct->GDMA_BlockSize = Length;
627 if (((Length & 0x03)==0) && (((u32)(pRxData) & 0x03)==0)) {
628 /* 4-bytes aligned, move 4 bytes each transfer */
629 GDMA_InitStruct->GDMA_DstMsize = MsizeOne;
630 GDMA_InitStruct->GDMA_DstDataWidth = TrWidthFourBytes;
631 } else {
632 GDMA_InitStruct->GDMA_DstMsize = MsizeFour;
633 GDMA_InitStruct->GDMA_DstDataWidth = TrWidthOneByte;
634 }
635 }
636
637 assert_param(GDMA_InitStruct->GDMA_BlockSize <= 4096);
638
639 GDMA_InitStruct->GDMA_DstAddr = (u32)pRxData;
640
641 /* Enable GDMA for RX */
642 GDMA_Init(GDMA_InitStruct->GDMA_Index, GDMA_InitStruct->GDMA_ChNum, GDMA_InitStruct);
643 GDMA_Cmd(GDMA_InitStruct->GDMA_Index, GDMA_InitStruct->GDMA_ChNum, ENABLE);
644
645 return _TRUE;
646 }
647
648 /**
649 * @brief Clear SPIx interrupt status.
650 * @param spi_dev: where spi_dev can be SPI0_DEV or SPI1_DEV.
651 * @param InterruptStatus: The value of current interrupt status .
652 * @retval None
653 */
654
SSI_SetIsrClean(SPI_TypeDef * spi_dev,u32 InterruptStatus)655 void SSI_SetIsrClean(SPI_TypeDef *spi_dev, u32 InterruptStatus)
656 {
657
658 if (InterruptStatus & BIT_ISR_TXOIS) {
659 spi_dev->TXOICR;
660 }
661
662 if (InterruptStatus & BIT_ISR_RXUIS) {
663 spi_dev->RXUICR;
664 }
665
666 if (InterruptStatus & BIT_ISR_RXOIS) {
667 spi_dev->RXOICR;
668 }
669
670 if (InterruptStatus & BIT_ISR_MSTIS) {
671 /* Another master is actively transferring data */
672 /* TODO: Do reading data... */
673 spi_dev->MSTICR;
674 }
675
676 if(InterruptStatus & BIT_ISR_TXUIS) {
677 /* For slave only. This register is used as TXUICR in slave mode*/
678 spi_dev->IDR;
679 }
680
681 if(InterruptStatus & BIT_ISR_SSRIS) {
682 /* For slave only. This register is used as SSRICR in slave mode*/
683 spi_dev->SSI_COMP_VERSION;
684 }
685
686 }
687
688 /**
689 * @brief Write data to SPIx transmit FIFO.
690 * @param spi_dev: where spi_dev can be SPI0_DEV or SPI1_DEV.
691 * @param value: The data value that is to be transmitted .
692 * @retval None
693 */
694
SSI_WriteData(SPI_TypeDef * spi_dev,u32 value)695 void SSI_WriteData(SPI_TypeDef *spi_dev, u32 value)
696 {
697 spi_dev->DR[0] = (value & BIT_DR_DR);
698 }
699
700 /**
701 * @brief Set SPIx Rx FIFO threshold level
702 * @param spi_dev: where spi_dev can be SPI0_DEV or SPI1_DEV.
703 * @param RxThresholdLevel: Rx FIFO Threshold Level.Value range: 0 to 63.
704 * When the number of receive FIFO entries is greater than or equal to
705 * this value + 1, the receive FIFO full interrupt is triggered.
706 * @retval None
707 */
708
SSI_SetRxFifoLevel(SPI_TypeDef * spi_dev,u32 RxThresholdLevel)709 void SSI_SetRxFifoLevel(SPI_TypeDef *spi_dev, u32 RxThresholdLevel)
710 {
711 spi_dev->RXFTLR = RxThresholdLevel;
712 }
713
714 /**
715 * @brief Set SPIx Tx FIFO threshold level.
716 * @param spi_dev: where spi_dev can be SPI0_DEV or SPI1_DEV.
717 * @param TxThresholdLevel: Tx FIFO Threshold Level.Value range: 0 to 63.
718 * When the number of transmit FIFO entries is less than or equal to this
719 * value, the transmit FIFO empty interrupt is triggered.
720 * @retval None
721 */
722
SSI_SetTxFifoLevel(SPI_TypeDef * spi_dev,u32 TxThresholdLevel)723 void SSI_SetTxFifoLevel(SPI_TypeDef *spi_dev, u32 TxThresholdLevel)
724 {
725 spi_dev->TXFTLR = TxThresholdLevel;
726 }
727
728 /**
729 * @brief Enables or disables slave .
730 * @note Valid only when the device is configured as a master.
731 * @param spi_dev: where spi_dev can be SPI0_DEV or SPI1_DEV.
732 * @param SlaveIndex: the index of slave to be selected.
733 * @retval None
734 */
735
SSI_SetSlaveEnable(SPI_TypeDef * spi_dev,u32 SlaveIndex)736 void SSI_SetSlaveEnable(SPI_TypeDef *spi_dev, u32 SlaveIndex)
737 {
738 if (SSI_Busy(spi_dev)) {
739 DBG_8195A("SSI%d is busy\n", SlaveIndex);
740 return;
741 }
742
743 spi_dev->SER = (1 << SlaveIndex);
744 }
745
746 /**
747 * @brief Detemines whether SPIx transmit FIFO is full or not
748 * @param spi_dev: where spi_dev can be SPI0_DEV or SPI1_DEV.
749 * @retval Transmit FIFO is full or not:
750 * - 1: Not Full
751 * - 0: Full
752 */
753
SSI_Writeable(SPI_TypeDef * spi_dev)754 u32 SSI_Writeable(SPI_TypeDef *spi_dev)
755 {
756 u8 status = 0;
757 u32 value = 0;
758
759 #ifdef SPI_SLAVE_TXERR_WORK_AROUND
760 value = SSI_GetTxCount(spi_dev);
761 status = ((value < SSI_TX_FIFO_DEPTH - 1) ? 1 : 0);
762 #else
763 value = SSI_GetStatus(spi_dev);
764 status = (((value & BIT_SR_TFNF) != 0) ? 1 : 0);
765 #endif
766
767 return status;
768 }
769
770 /**
771 * @brief Detemine SPIx Receive FIFO is empty or not.
772 * @param spi_dev: where spi_dev can be SPI0_DEV or SPI1_DEV.
773 * @retval Receive FIFO is empty or not:
774 * - 1: Not Empty
775 * - 0: Empty
776 */
777
SSI_Readable(SPI_TypeDef * spi_dev)778 u32 SSI_Readable(SPI_TypeDef *spi_dev)
779 {
780 u32 Status = SSI_GetStatus(spi_dev);
781 u32 Readable = (((Status & BIT_SR_RFNE) != 0) ? 1 : 0);
782
783 return Readable;
784 }
785
786 /**
787 * @brief Read data from SPIx receive FIFO .
788 * @param spi_dev: where spi_dev can be SPI0_DEV or SPI1_DEV.
789 * @retval The data received.
790 */
791
SSI_ReadData(SPI_TypeDef * spi_dev)792 u32 SSI_ReadData(SPI_TypeDef *spi_dev)
793 {
794 return spi_dev->DR[0];
795 }
796
797 /**
798 * @brief receive data from rx FIFO
799 * @param spi_dev: where spi_dev can be SPI0_DEV or SPI1_DEV.
800 * @param RxData: buffer to save data read from SPI FIFO.
801 * @param Length: number of data to be read.
802 * @retval transfer len
803 */
804
SSI_ReceiveData(SPI_TypeDef * spi_dev,void * RxData,u32 Length)805 u32 SSI_ReceiveData(SPI_TypeDef *spi_dev,
806 void* RxData,
807 u32 Length
808 )
809 {
810 u32 ReceiveLevel;
811 u32 DataFrameSize = SSI_GetDataFrameSize(spi_dev);
812 volatile u32 Readable = SSI_Readable(spi_dev);
813 u32 RxLength = Length;
814
815 while (Readable) {
816 ReceiveLevel = SSI_GetRxCount(spi_dev);
817
818 while (ReceiveLevel--) {
819 if (RxData != NULL) {
820 if (DataFrameSize > 8) {
821 /* 16~9 bits mode */
822 *((u16*)(RxData)) = (u16)SSI_ReadData(spi_dev);
823 RxData = (VOID*)(((u16*)RxData) + 1);
824 } else {
825 /* 8~4 bits mode */
826 *((u8*)(RxData)) = (u8)SSI_ReadData(spi_dev);
827 RxData = (VOID*)(((u8*)RxData) + 1);
828 }
829 } else {
830 /* for Master mode, doing TX also will got RX data, so drop the dummy data */
831 SSI_ReadData(spi_dev);
832 }
833
834 if (RxLength > 0) {
835 RxLength--;
836 }
837 if (RxLength == 0) {
838 break;
839 }
840 }
841
842 if (RxLength == 0) {
843 break;
844 }
845
846 Readable = SSI_Readable(spi_dev);
847 }
848
849 return (Length - RxLength);
850 }
851
852 /**
853 * @brief Send data to tx FIFO
854 * @param spi_dev: where spi_dev can be SPI0_DEV or SPI1_DEV.
855 * @param TxData: buffer to be written to Tx FIFO.
856 * @param Length: number of data to be written.
857 * @param Role: SSI_MASTER or SSI_SLAVE.
858 * @retval transfer len
859 */
860
SSI_SendData(SPI_TypeDef * spi_dev,void * TxData,u32 Length,u32 Role)861 u32 SSI_SendData(SPI_TypeDef *spi_dev,
862 void* TxData,
863 u32 Length,
864 u32 Role
865 )
866 {
867 u32 Writeable = SSI_Writeable(spi_dev);
868 u32 TxWriteMax = SSI_TX_FIFO_DEPTH - SSI_GetTxCount(spi_dev);
869 u32 DataFrameSize = SSI_GetDataFrameSize(spi_dev);
870 u32 TxLength = Length;
871
872 #ifdef SPI_SLAVE_TXERR_WORK_AROUND
873 if (Role == SSI_SLAVE)
874 TxWriteMax = (TxWriteMax > 0) ? (TxWriteMax - 1) : 0;
875 #endif
876
877 if (Writeable) {
878 /* Disable Tx FIFO Empty IRQ */
879 SSI_INTConfig(spi_dev, BIT_IMR_TXEIM, DISABLE);
880
881 while (TxWriteMax--) {
882 if (DataFrameSize > 8) {
883 // 16~9 bits mode
884 if (TxData != NULL) {
885 SSI_WriteData(spi_dev, *((u16*)(TxData)));
886 TxData = (VOID*)(((u16*)TxData) + 1);
887 } else {
888 // For master mode: Push a dummy to TX FIFO for Read
889 if (Role == SSI_MASTER) {
890 SSI_WriteData(spi_dev, (u16)0);// Dummy byte
891 }
892 }
893 } else {
894 // 8~4 bits mode
895 if (TxData != NULL) {
896 SSI_WriteData(spi_dev, *((u8*)(TxData)));
897 TxData = (VOID*)(((u8*)TxData) + 1);
898 } else {
899 // For master mode: Push a dummy to TX FIFO for Read
900 if (Role == SSI_MASTER) {
901 SSI_WriteData(spi_dev, (u8)0);// Dummy byte
902 }
903 }
904 }
905
906 TxLength--;
907
908 if (TxLength == 0)
909 break;
910 }
911
912 /* Enable Tx FIFO Empty IRQ */
913 SSI_INTConfig(spi_dev, BIT_IMR_TXEIM, ENABLE);
914 }
915
916 return (Length - TxLength);
917 }
918
919 /**
920 * @brief Get SPIx the number of valid entries in receive FIFO.
921 * @param spi_dev: where spi_dev can be SPI0_DEV or SPI1_DEV.
922 * @retval The number of valid entries in receive FIFO.Value range:0-64.
923 */
924
SSI_GetRxCount(SPI_TypeDef * spi_dev)925 u32 SSI_GetRxCount(SPI_TypeDef *spi_dev)
926 {
927 return spi_dev->RXFLR & BIT_MASK_RXFLR_RXTFL;
928 }
929
930 /**
931 * @brief Get SPIx the number of valid entries in transmit FIFO.
932 * @param spi_dev: where spi_dev can be SPI0_DEV or SPI1_DEV.
933 * @retval The number of valid entries in transmit FIFO.Value range:0-64.
934 */
935
SSI_GetTxCount(SPI_TypeDef * spi_dev)936 u32 SSI_GetTxCount(SPI_TypeDef *spi_dev)
937 {
938 return spi_dev->TXFLR & BIT_MASK_TXFLR_TXTFL;
939 }
940
941 /**
942 * @brief Get SPIx transfer status.
943 * @param spi_dev: where spi_dev can be SPI0_DEV or SPI1_DEV.
944 * @retval Current transfer status,each bit of this value represents one
945 * transfer status which is as follows:
946 *
947 * bit 6 : DCOL Data Collision Error.(valid when device is master)
948 * - 0 : No Error
949 * - 1 : Transmit data collision error
950 *
951 * bit 5 : TXE Transmission Error.(valid when device is slave)
952 * - 0 : No Error
953 * - 1 : Transmission error
954 *
955 * bit 4 : RFF Receive FIFO Full.
956 * - 0 : Receive FIFO is not full
957 * - 1 : Receive FIFO is full
958 *
959 * bit 3 : RFNE Receive FIFO Not Empty.
960 * - 0 : Receive FIFO is empty
961 * - 1 : Receive FIFO is not empty
962 *
963 * bit 2 : TFE Transmit FIFO Empty.
964 * - 0 : Transmit FIFO is not empty
965 * - 1 : Transmit FIFO is empty
966 *
967 * bit 1 : TFNF Transmit FIFO Not Full.
968 * - 0 : Transmit FIFO is full
969 * - 1 : Transmit FIFO is not full
970 *
971 * bit 0 : BUSY SSI Busy Flag.
972 * - 0 : idle or disable
973 * - 1 : active transferring data
974 *
975 */
976
SSI_GetStatus(SPI_TypeDef * spi_dev)977 u32 SSI_GetStatus(SPI_TypeDef *spi_dev)
978 {
979 return spi_dev->SR;
980 }
981
982 /**
983 * @brief Get SPIx data frame size.
984 * @param spi_dev: where spi_dev can be SPI0_DEV or SPI1_DEV.
985 * @retval Data frame size(value range : 4-16):
986 * - n : current data frame length is n bits
987 */
988
SSI_GetDataFrameSize(SPI_TypeDef * spi_dev)989 u32 SSI_GetDataFrameSize(SPI_TypeDef *spi_dev)
990 {
991 u32 size = ((spi_dev->CTRLR0) & BIT_CTRLR0_DFS) + 1;
992 return size;
993 }
994
995 /**
996 * @brief Detemine SPIx is busy or not.
997 * @param spi_dev: where spi_dev can be SPI0_DEV or SPI1_DEV.
998 * @retval SPIx busy status value:
999 * - 1: Busy
1000 * - 0: Not Busy
1001 */
1002
SSI_Busy(SPI_TypeDef * spi_dev)1003 u32 SSI_Busy(SPI_TypeDef *spi_dev)
1004 {
1005 u32 Status = SSI_GetStatus(spi_dev);
1006 u32 Busy = (((Status & BIT_SR_BUSY) != 0) ? 1 : 0);
1007
1008 return Busy;
1009 }
1010
1011 /**
1012 * @brief Get SPIx Interrupt Status.
1013 * @param spi_dev: where spi_dev can be SPI0_DEV or SPI1_DEV.
1014 * @retval Current Interrupt Status,each bit of this value represents one
1015 * interrupt status which is as follows:
1016 *
1017 * bit 7 : SSRIS SS_N Rising Edge Detect Interrupt Status. (valid when device is slave)
1018 * - 0 : ssi_ssr_intr interrupt not active after masking
1019 * - 1 : ssi_ssr_intr interrupt is active after masking
1020 *
1021 * bit 6 : TXUIS Transmit FIFO Under Flow Interrupt Status. (valid when device is slave)
1022 * - 0 : ssi_txu_intr interrupt is not active after masking
1023 * - 1 : ssi_txu_intr interrupt is active after masking
1024 *
1025 * bit 5 : FAEIS Frame Alignment Interrupt Status. (valid when device is slave)
1026 * - 0 : ssi_fae_intr interrupt not active after masking
1027 * - 1 : ssi_fae_intr interrupt is active after masking
1028 *
1029 * bit 5 : MSTIS Multi-Master Contention Interrupt Status. (valid when device is master)
1030 * - 0 : ssi_mst_intr interrupt not active after masking
1031 * - 1 : ssi_mst_intr interrupt is active after masking
1032 *
1033 * bit 4 : RXFIS Receive FIFO Full Interrupt Status.
1034 * - 0 : ssi_rxf_intr interrupt is not active after masking
1035 * - 1 : ssi_rxf_intr interrupt is full after masking
1036 *
1037 * bit 3 : RXOIS Receive FIFO Overflow Interrupt Status.
1038 * - 0 : ssi_rxo_intr interrupt is not active after masking
1039 * - 1 : ssi_rxo_intr interrupt is active after masking
1040 *
1041 * bit 2 : RXUIS Receive FIFO Underflow Interrupt Status.
1042 * - 0 : ssi_rxu_intr interrupt is not active after masking
1043 * - 1 : ssi_rxu_intr interrupt is active after masking
1044 *
1045 * bit 1 : TXOIS Transmit FIFO Overflow Interrupt Status.
1046 * - 0 : ssi_txo_intr interrupt is not active after masking
1047 * - 1 : ssi_txo_intr interrupt is active after masking
1048 *
1049 * bit 0 : TXEIS Transmit FIFO Empty Interrupt Status.
1050 * - 0 : ssi_txe_intr interrupt is not active after masking
1051 * - 1 : ssi_txe_intr interrupt is active after masking
1052 */
1053
SSI_GetIsr(SPI_TypeDef * spi_dev)1054 u32 SSI_GetIsr(SPI_TypeDef *spi_dev)
1055 {
1056 return spi_dev->ISR;
1057 }
1058
1059 /**
1060 * @brief Get SPIx Raw Interrupt Status.
1061 * @param spi_dev: where spi_dev can be SPI0_DEV or SPI1_DEV.
1062 * @retval Current Raw Interrupt Status,each bit of this value represents one
1063 * raw interrupt status which is as follows:
1064 *
1065 * bit 7 : SSRIR SS_N Rising Edge Detect Interrupt Status. (valid when device is slave)
1066 * - 0 : ssi_ssr_intr interrupt not active after masking
1067 * - 1 : ssi_ssr_intr interrupt is active after masking
1068 *
1069 * bit 6 : TXUIR Transmit FIFO Under Flow Interrupt Status. (valid when device is slave)
1070 * - 0 : ssi_txu_intr interrupt is not active after masking
1071 * - 1 : ssi_txu_intr interrupt is active after masking
1072 *
1073 * bit 5 : FAEIR Frame Alignment Interrupt Status. (valid when device is slave)
1074 * - 0 : ssi_fae_intr interrupt not active after masking
1075 * - 1 : ssi_fae_intr interrupt is active after masking
1076 *
1077 * bit 5 : MSTIR Multi-Master Contention Raw Interrupt Status.(valid when device is master)
1078 * - 0 : ssi_mst_intr interrupt not active prior to masking
1079 * - 1 : ssi_mst_intr interrupt is active prior to masking
1080 *
1081 * bit 4 : RXFIR Receive FIFO Full Raw Interrupt Status.
1082 * - 0 : ssi_rxf_intr interrupt is not active prior to masking
1083 * - 1 : ssi_rxf_intr interrupt is full prior to masking
1084 *
1085 * bit 3 : RXOIR Receive FIFO Overflow Raw Interrupt Status.
1086 * - 0 : ssi_rxo_intr interrupt is not active prior to masking
1087 * - 1 : ssi_rxo_intr interrupt is active prior to masking
1088 *
1089 * bit 2 : RXUIR Receive FIFO Underflow Raw Interrupt Status.
1090 * - 0 : ssi_rxu_intr interrupt is not active prior to masking
1091 * - 1 : ssi_rxu_intr interrupt is active prior to masking
1092 *
1093 * bit 1 : TXOIR Transmit FIFO Overflow Raw Interrupt Status.
1094 * - 0 : ssi_txo_intr interrupt is not active prior to masking
1095 * - 1 : ssi_txo_intr interrupt is active prior to masking
1096 *
1097 * bit 0 : TXEIR Transmit FIFO Empty Raw Interrupt Status.
1098 * - 0 : ssi_txe_intr interrupt is not active prior to masking
1099 * - 1 : ssi_txe_intr interrupt is active prior to masking
1100 */
1101
SSI_GetRawIsr(SPI_TypeDef * spi_dev)1102 u32 SSI_GetRawIsr(SPI_TypeDef *spi_dev)
1103 {
1104 return spi_dev->RISR;
1105 }
1106
1107 /**
1108 * @brief Get which slave is selected.
1109 * @note Valid only when the device is configured as a master.
1110 * @param spi_dev: where spi_dev can be SPI0_DEV or SPI1_DEV.
1111 * @retval Each bit of this value which is set to 1 corresponds to the slave being slected.
1112 */
1113
SSI_GetSlaveEnable(SPI_TypeDef * spi_dev)1114 u32 SSI_GetSlaveEnable(SPI_TypeDef *spi_dev)
1115 {
1116 return spi_dev->SER;
1117 }
1118
1119 /******************* (C) COPYRIGHT 2016 Realtek Semiconductor *****END OF FILE****/
1120