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