1 /*
2  * ==========================================================
3  *
4  *    Copyright (C) 2020 QuickLogic Corporation
5  *    Licensed under the Apache License, Version 2.0 (the "License");
6  *    you may not use this file except in compliance with the License.
7  *    You may obtain a copy of the License at
8  * 		http://www.apache.org/licenses/LICENSE-2.0
9  *    Unless required by applicable law or agreed to in writing, software
10  *    distributed under the License is distributed on an "AS IS" BASIS,
11  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  *    See the License for the specific language governing permissions and
13  *    limitations under the License.
14  *
15  *    File      : eoss3_hal_spi.h
16  *    Purpose   :
17  *
18  *
19  * ===========================================================
20  *
21  */
22 
23 #ifndef TAMAR_HAL_SPI_H_
24 #define TAMAR_HAL_SPI_H_
25 
26 #include <stdint.h>
27 #include <stddef.h>
28 
29 #include "eoss3_hal_def.h"
30 #include "test_types.h"
31 
32 #define assert_param(expr)  	((expr) ? (void)0 : assert_failed(__FILE__,__LINE__))
33 
34 
35 /*!
36  * HAL SPI State structure definition
37  */
38 typedef enum
39 {
40 	HAL_SPI_STATE_RESET=0,		/*! SPI not yet initialized or disabled */
41 	HAL_SPI_STATE_READY,		/*! SPI initialized and ready for use 	*/
42 	HAL_SPI_STATE_TX_BUSY,		/*! SPI Data transmission process is ongoing  */
43 	HAL_SPI_STATE_RX_BUSY,		/*! SPI Reception process is ongoing */
44 	HAL_SPI_STATE_TX_RX_BUSY,
45 	HAL_SPI_STATE_ERROR
46 }HAL_SPI_StateTypeDef;
47 
48 typedef enum
49 {
50 	SPI_MODE_0 = 0,
51 	SPI_MODE_1,
52 	SPI_MODE_2,
53 	SPI_MODE_3,
54 	SPI_MODE_INVALID,
55 }SpiMode;
56 
57 typedef enum {
58 	CMD_WithResponse = 0,
59 	CMD_NoResponse,
60 	READ_CMD,
61 	PROGRAM_CMD,
62 }FlashCmdType;
63 
64 
65 // Return Message
66 typedef enum {
67     FlashOperationSuccess=1,
68     FlashWriteRegFailed,
69     FlashTimeOut,
70     FlashIsBusy,
71     FlashQuadNotEnable,
72     FlashAddressInvalid,
73     FlashInvalidParams,
74     FlashCmdFailed,
75     FlashMatchFound,
76     FlashNotFound,
77 }ReturnMsg;
78 
79 
80 /*! Sensor SPI Master PAD selection.
81 If ucSPI0PadSel = 0 then,
82 SPI_MOSI--> PAD6, SPI_MISO--> PAD8, SPI_CLK--> PAD10, SPI_SSN1--> PAD9,
83 SPI_SSN2--> PAD2, SPI_SSN3--> PAD4, SPI_SSN4--> PAD5, SPI_SSN5--> PAD7,
84 SPI_SSN6--> PAD11, SPI_SSN7--> PAD12, SPI_SSN8--> PAD13
85 
86 If ucSPI0PadSel = 1 then,
87 SPI_MOSI--> PAD28, SPI_MISO--> PAD29, SPI_CLK--> PAD31, SPI_SSN1--> PAD30,
88 SPI_SSN2--> PAD36, SPI_SSN3--> PAD4, SPI_SSN4--> PAD26, SPI_SSN5--> PAD27,
89 SPI_SSN6--> PAD33, SPI_SSN7--> PAD35, SPI_SSN8--> PAD37
90 */
91 
92 
93 /*!
94  * \brief SPI Configuration Structure definition
95  */
96 typedef struct
97 {
98 	UINT8_t  		ucSPIInf;			/*! SPI Interface : ucSPIInf = 0 (4-wire), ucSPIInf = 1 (3-wire) interface */
99 	FlashCmdType	ucCmdType;			/*! SPI Flash command type */
100 	UINT8_t			ucSSn;				/*! SPI slave select pin */
101 	UINT32_t		ucFreq;				/*! SPI Communication Frequency */
102 	UINT32_t 		ulDataSize;			/*! Specifies the SPI data size.*/
103 	UINT32_t 		ulCLKPolarity;		/*! Specifies the serial clock steady state.*/
104 	UINT32_t 		ulCLKPhase;			/*! Specifies the clock active edge for the bit capture. */
105 	UINT32_t 		ulFirstBit;			/*! Specifies whether data transfers start from MSB or LSB bit. */
106 }SPI_InitTypeDef;
107 
108 
109 /*!
110  * \brief SPI Handle structure definition
111  */
112 typedef struct __SPI_HandleTypeDef
113 {
114 	SPI_InitTypeDef 			Init;			/*! SPI Communication Parameters */
115 	UINT8_t 					ucSPIx;			/*! SPI Master index for base address*/
116 	UINT8_t 					*pTxBuffer;		/*! Pointer to SPI Tx transfer Buffer */
117 	UINT8_t 					*pRxBuffer;		/*! Pointer to SPI Rx transfer Buffer */
118 	UINT32_t 					usTxXferCount;	/*! SPI Tx total transfer count */
119 	UINT32_t 					usRxXferCount;	/*! SPI Rx total transfer count */
120 	UINT32_t 					usTxXferSize;	/*! SPI Tx transfer size for each transfer*/
121 	UINT32_t 					usRxXferSize;	/*! SPI Rx transfer size */
122 	HAL_SPI_StateTypeDef  		State;        	/*! SPI communication state */
123 	void 						(*RxISR)(struct __SPI_HandleTypeDef *spi);	/*! function pointer on Rx ISR */
124 	void 						(*TxISR)(struct __SPI_HandleTypeDef *spi);	/*! function pointer on Tx ISR */
125 	void 						(*HAL_SPI_TxRxComplCallback)(void);	/*! function pointer on Tx/Rx complete Callback */
126 }SPI_HandleTypeDef;
127 
128 
129 /* SPI Transaction size bit definition */
130 #define SPI_DATASIZE_8BIT			((UINT8_t)0x7)
131 #define SPI_DATASIZE_7BIT			((UINT8_t)0x6)
132 #define SPI_DATASIZE_6BIT			((UINT8_t)0x5)
133 #define SPI_DATASIZE_5BIT			((UINT8_t)0x4)
134 #define SPI_DATASIZE_4BIT			((UINT8_t)0x3)
135 #define SPI_DATASIZE_3BIT			((UINT8_t)0x2)
136 #define SPI_DATASIZE_2BIT			((UINT8_t)0x1)
137 #define SPI_DATASIZE_1BIT			((UINT8_t)0x0)
138 #define IS_SPI_DATASIZE(DATASIZE)	((DATASIZE == SPI_DATASIZE_8BIT) || (DATASIZE == SPI_DATASIZE_7BIT) || \
139 									 (DATASIZE == SPI_DATASIZE_6BIT) || (DATASIZE == SPI_DATASIZE_5BIT) || \
140 									 (DATASIZE == SPI_DATASIZE_4BIT) || (DATASIZE == SPI_DATASIZE_3BIT) || \
141 									 (DATASIZE == SPI_DATASIZE_2BIT) || (DATASIZE == SPI_DATASIZE_1BIT))
142 
143 
144 /* SPI Clock Polarity */
145 #define SPI_POLARITY_LOW			((UINT8_t)0x0)
146 #define SPI_POLARITY_HIGH			((UINT8_t)0x1)
147 #define IS_SPI_CPOL(CPOL)			((CPOL == SPI_POLARITY_LOW) || (CPOL == SPI_POLARITY_HIGH))
148 
149 /* SPI Clock Phase */
150 #define SPI_PHASE_1EDGE				((UINT8_t)0x0)
151 #define SPI_PHASE_2EDGE				((UINT8_t)0x1)
152 #define IS_SPI_CPHA(CPHA)			((CPHA == SPI_PHASE_1EDGE) || (CPHA == SPI_PHASE_2EDGE))
153 
154 /* SPI_MSB_LSB_transmission */
155 #define SPI_FIRSTBIT_MSB			((UINT8_t)0x0)
156 #define SPI_FIRSTBIT_LSB			((UINT8_t)0x1)
157 #define IS_SPI_FIRST_BIT(BIT)		((BIT == SPI_FIRSTBIT_MSB) || (BIT == SPI_FIRSTBIT_LSB))
158 
159 /* SPI 3-wire configuration */
160 #define SPI_BIDIR_MODE_DIS			((UINT8_t)0x0)
161 #define SPI_BIDIR_MODE_EN			((UINT8_t)0x1)
162 #define IS_SPI_BIDIR_MODE(MODE)		((MODE == SPI_BIDIR_MODE_DIS) || (MODE == SPI_BIDIR_MODE_EN))
163 
164 #define SPI_3_WIRE_MODE				(0x1)
165 #define SPI_4_WIRE_MODE				(0x0)
166 
167 /* SPI Interrupt/Status register bit definition */
168 #define SPI_XFER_IN_PROGRESS		((UINT8_t)0x4)
169 #define SPI_WRITE_XFER_DONE			((UINT8_t)0x2)
170 #define SPI_READ_XFER_DONE			((UINT8_t)0x1)
171 
172 /* SPI Slave select register bit definition */
173 #define SPI_SLAVE_1_SELECT			((UINT8_t)0x1 << BYTE_IDX_0)
174 #define SPI_SLAVE_2_SELECT			((UINT8_t)0x1 << BYTE_IDX_1)
175 #define SPI_SLAVE_3_SELECT			((UINT8_t)0x1 << BYTE_IDX_2)
176 #define SPI_SLAVE_4_SELECT			((UINT8_t)0x1 << BYTE_IDX_3)
177 #define SPI_SLAVE_5_SELECT			((UINT8_t)0x1 << BYTE_IDX_4)
178 #define SPI_SLAVE_6_SELECT			((UINT8_t)0x1 << BYTE_IDX_5)
179 #define SPI_SLAVE_7_SELECT			((UINT8_t)0x1 << BYTE_IDX_6)
180 #define SPI_SLAVE_8_SELECT			((UINT8_t)0x1 << BYTE_IDX_7)
181 
182 #define IS_SPI_SSN_VALID(SS)		((SS == SPI_SLAVE_1_SELECT) || (SS == SPI_SLAVE_2_SELECT) || (SS == SPI_SLAVE_3_SELECT) || \
183 									 (SS == SPI_SLAVE_4_SELECT) || (SS == SPI_SLAVE_5_SELECT) || (SS == SPI_SLAVE_6_SELECT) || \
184 									 (SS == SPI_SLAVE_7_SELECT)	||	(SS == SPI_SLAVE_8_SELECT))
185 
186 
187 #define IS_SPIx_VALID(n)			((n == SPI0_MASTER_SEL) || (n == SPI1_MASTER_SEL))
188 
189 /*! \def SPI0_MASTER_SEL
190     \brief A macro to select Sensor SPI Master controller in FFE subsystem
191 */
192 #define SPI0_MASTER_SEL				0
193 
194 /*! \def SPI1_MASTER_SEL
195     \brief A macro to select SPI Master controller connected to SPI Flash
196 */
197 #define SPI1_MASTER_SEL				1
198 
199 /*! \def I2C_0_SELECT
200     \brief A macro to select I2C_0 as slave to be accessed by WB master
201 */
202 #define I2C_0_SELECT				((UINT8_t)0x0)
203 
204 /*! \def I2C_1_SELECT
205     \brief A macro to select I2C_1 as slave to be accessed by WB master
206 */
207 #define I2C_1_SELECT				((UINT8_t)0x40)
208 
209 /*! \def SPI_0_SELECT
210     \brief A macro to select SPI_0 as slave to be accessed by WB master
211 */
212 #define SPI_0_SELECT				((UINT8_t)0x80)
213 
214 /*! \def SPI0_MUX_SEL_WB_MASTER
215     \brief A macro to define SPI_0 wishbone control mux select
216 */
217 #define SPI0_MUX_SEL_WB_MASTER		((UINT8_t)0x80)
218 
219 /*!
220  * \brief The following macros define the Sensor SPI Master register offsets
221  */
222 #define SPI0_BR_LSB_REG				0x0
223 #define SPI0_BR_MSB_REG				0x1
224 #define SPI0_CFG_REG				0x2
225 #define SPI0_TX_RX_REG				0x3
226 #define SPI0_CMD_STS_REG			0x4
227 #define SPI0_SS_REG				0x5
228 #define SPI0_CLK_CTRL_REG			0x6
229 #define SPI0_ADD_CLK_REG			0x7
230 
231 #define SPI_BAUDRATE_625KHZ			((UINT32_t)625000)
232 #define SPI_BAUDRATE_1MHZ			((UINT32_t)1000000)
233 #define SPI_BAUDRATE_2_5MHZ			((UINT32_t)2500000)
234 #define SPI_BAUDRATE_5MHZ			((UINT32_t)5000000)
235 #define SPI_BAUDRATE_6MHZ			((UINT32_t)6000000)
236 #define SPI_BAUDRATE_8MHZ			((UINT32_t)8000000)
237 #define SPI_BAUDRATE_10MHZ			((UINT32_t)10000000)
238 #define SPI_BAUDRATE_15MHZ          ((UINT32_t)15000000)
239 #define SPI_BAUDRATE_20MHZ          ((UINT32_t)20000000)
240 
241 
242 /*!
243  * \brief SPI command register (offset 0x4) bit definition
244  */
245 #define SPI_CMD_START				((UINT8_t)(1 << BYTE_IDX_0))
246 #define SPI_CMD_STOP				((UINT8_t)(1 << BYTE_IDX_1))
247 #define SPI_CMD_WRITE				((UINT8_t)(1 << BYTE_IDX_2))
248 #define SPI_CMD_READ				((UINT8_t)(1 << BYTE_IDX_3))
249 #define SPI_CMD_IACK				((UINT8_t)(1 << BYTE_IDX_7))
250 
251 /*!
252  * \brief SPI Interrupt/Status register bit definition
253  */
254 #define SPI_STAT_TIP				((UINT8_t) (1 << BYTE_IDX_2))
255 #define SPI_INTR_IW				((UINT8_t) (1 << BYTE_IDX_1))
256 #define SPI_INTR_IR				((UINT8_t) (1 << BYTE_IDX_0))
257 
258 
259 /*!
260  * \brief SPI configuration register (offset 0x2) bit definition
261  */
262 #define SPI_SYSTEM_EN				((UINT8_t)(1 << BYTE_IDX_7))
263 #define SPI_INTR_EN				((UINT8_t)(1 << BYTE_IDX_6))
264 
265 #define SPI_MS_INTR_EN				((UINT32_t)0x40000)
266 
267 #define SPI1_XFER_LEN_MAX			260
268 
269 #define CTX_ISR 1
270 #define CTX_TASK    2
271 
272 
273 /********************** Exported Functions ********************/
274 /*!
275 * \fn      void HAL_SPI_IRQHandler(void);
276 * \brief   SPI TX Interrupt handler
277 * \param   None
278 * \return  None
279 */
280 void HAL_SPI_IRQHandler(void);
281 
282 /*!
283 * \fn      void HAL_SPI_Init(SPI_HandleTypeDef  *hspi))
284 * \brief   Initializes the SPI Master controller
285 * \param   hspi --- SPI handle
286 * \return  None
287 */
288 HAL_StatusTypeDef HAL_SPI_Init(SPI_HandleTypeDef  *hspi);
289 
290 /*!
291 * \fn      void HAL_SPI_DeInit()
292 * \brief   De-initializes the SPI HAL
293 * \param   None
294 * \return  None
295 */
296 HAL_StatusTypeDef HAL_SPI_DeInit(SPI_HandleTypeDef  *hspi);
297 
298 /*!
299 *\fn       HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef  *hspi, UINT8_t *pData, UINT16_t ulTxLen, void (*HAL_SPI_Callback)(void))
300 *\brief    Transmit an amount of data, if callback funtion is NULL, it will be blocking call otherwise Non-Blocking.
301 *           In non blocking mode, callback function will be called from interrupt contex after data is Transmitted from FIFO
302 *\param    hspi --- SPI handle
303 *\param    pData --- Pointer to data buffer
304 *\param    ulTxLen --- amount of data to be sent
305 *\param    HAL_SPI_Callback --- Callback function, will be called after Transmit is done
306 *\return   HAL status
307 */
308 HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef  *hspi, UINT8_t *pData, UINT32_t ulTxLen, void (*HAL_SPI_Callback)(void));
309 
310 
311 /*!
312 * \fn      HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, UINT8_t *pTxData, const UINT16_t usTxSize, UINT8_t *pRxData,const UINT16_t usRxSize,
313 *                                          void (*HAL_SPI_TxRxComplCallback)(void))
314 * \brief   Transmit an amount of data and reads data in DMA mode, if callback function is Null, it will be a blocking call
315 *   otherwise Non-Blocking , In Non Blocking mode Read complete will be notified in callback function
316 * \param   hspi        --- SPI Handle
317 * \param   pTxData     --- pointer to transmission data buffer
318 * \param   pRxData     --- pointer to reception data buffer
319 * \param   usTxSize    --- amount of data to be sent
320 * \param   usRxSize    --- amount of data to be received
321 * \param   HAL_SPI_TxRxComplCallback --- callback function to be called after received data
322 * \return  HAL status
323 */
324 HAL_StatusTypeDef HAL_SPI_TransmitReceive(SPI_HandleTypeDef *hspi, UINT8_t *pTxData, const UINT32_t usTxSize,UINT8_t *pRxData, const UINT32_t usRxSize,void (*HAL_SPI_TxRxComplCallback)(void));
325 
326 /*!
327 * \fn      HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, UINT8_t *pRxData,const UINT16_t usRxSize,
328 *                                          void (*HAL_SPI_RxCompCallback)(void))
329 * \brief   Reads data in DMA mode, if callback function is Null, it will be a blocking call
330 *          otherwise Non-Blocking, In Non Blocking mode Read complete will be notified in callback function
331 * \param   hspi        --- SPI Handle
332 * \param   pTxData     --- pointer to transmission data buffer
333 * \param   pRxData     --- pointer to reception data buffer
334 * \param   usTxSize    --- amount of data to be sent
335 * \param   usRxSize    --- amount of data to be received
336 * \param   HAL_SPI_RxCompCallback --- callback function to be called after received data
337 * \return  HAL status
338 */
339 HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, UINT8_t *pRxData,const UINT16_t usRxSize,
340 								void (*HAL_SPI_RxCompCallback)(void));
341 
342 /*!
343 * \fn      void SPI_DMA_Complete(SPI_HandleTypeDef  *hspi)
344 * \brief   Callback for SPI Flash Read DMA complete
345 * \param   SPI Handle
346 * \return  None
347 */
348 void SPI_DMA_Complete(void);
349 
350 /*!
351 * \fn      void lock_spi1_bus()
352 * \brief   Take Lock of SPI bus for exclusive access to a Task
353 * \param   None
354 * \return  None
355 */
356 void lock_spi1_bus(void);
357 
358 /*!
359 * \fn      static void SPI_Enable(SPI_HandleTypeDef *hspi, UINT8_t ucEnable)
360 * \brief   Function to enable/disable SPI master
361 * \param   ucEnable --- Enable/Disable flag
362 * \param   hspi     --- SPI Handle
363 * \return  None
364 */
365 //static void SPI_Enable(SPI_HandleTypeDef *hspi, UINT8_t ucEnable);
366 
367 /*!
368 * \fn      void unlock_spi1_bus(UINT8_t Ctx)
369 * \brief   Release  Lock of SPI bus for take earlier for exclusive access
370 * \param   Ctx  --- Context from where LOck is released, use value CTX_ISR when released from ISR, CTX_TASK when released from Task Context
371 * \return  None
372 */
373 void unlock_spi1_bus(UINT8_t Ctx);
374 
375 
376 /*!
377  * \fn 		HAL_StatusTypeDef HAL_SPI_TransmitReceive2(SPI_HandleTypeDef *hspi, UINT8_t *pTxData, const UINT16_t usTxSize, UINT8_t *pRxData,const UINT16_t usRxSize,
378  *											void (*HAL_SPI_TxRxComplCallback)(SPI_HandleTypeDef *hspi))
379  *
380  *
381  * \brief	Transmits an amount of data in non-DMA mode and reads the data back in polling mode
382  * \param	hspi		--- SPI Handle
383  * \param	pTxData		--- pointer to transmission data buffer
384  * \param	pRxData		--- pointer to reception data buffer
385  * \param	usTxSize 	--- amount of data to be sent
386  * \param	usRxSize	--- amount of data to be received
387  * \param	callback function
388  * \return	HAL status
389  */
390 HAL_StatusTypeDef HAL_SPI_TransmitReceive2(SPI_HandleTypeDef *hspi, UINT8_t *pTxData, const UINT32_t usTxSize, UINT8_t *pRxData,const UINT32_t usRxSize,
391                                            void (*HAL_SPI_TxRxComplCallback)(void));
392 
393 
394 
395 #endif /* TAMAR_HAL_SPI_H_ */
396