1 /*!
2  * @file        apm32f4x_spi.h
3  *
4  * @brief       This file contains all the functions prototypes for the SPI firmware library
5  *
6  * @version     V1.0.2
7  *
8  * @date        2022-06-23
9  *
10  * @attention
11  *
12  *  Copyright (C) 2021-2022 Geehy Semiconductor
13  *
14  *  You may not use this file except in compliance with the
15  *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
16  *
17  *  The program is only for reference, which is distributed in the hope
18  *  that it will be usefull and instructional for customers to develop
19  *  their software. Unless required by applicable law or agreed to in
20  *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
21  *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
22  *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
23  *  and limitations under the License.
24  */
25 
26 /* Define to prevent recursive inclusion */
27 #ifndef __APM32F4XX_SPI_H
28 #define __APM32F4XX_SPI_H
29 
30 #ifdef __cplusplus
31   extern "C" {
32 #endif
33 
34 /* Includes */
35 #include "apm32f4xx.h"
36 
37 /** @addtogroup APM32F4xx_StdPeriphDriver
38   @{
39 */
40 
41 /** @addtogroup SPI_Driver
42   @{
43 */
44 
45 /** @defgroup SPI_Enumerations
46   @{
47 */
48 
49 /**
50  * @brief   SPI data direction mode
51  *
52  * @note    BIT0 refer to 1 line or 2 lines
53  *          BIT4 refer to Tx or Rx in 1 line
54  *          BIT8 refer to receive only or full-duplex in 2 lines
55  */
56 typedef enum
57 {
58     SPI_DIRECTION_2LINES_FULLDUPLEX = 0x0000,   /*!< 2 lines full duplex */
59     SPI_DIRECTION_2LINES_RXONLY     = 0x0100,   /*!< 2 lines but receive only */
60     SPI_DIRECTION_1LINE_RX          = 0x0001,   /*!< 1 line receive only */
61     SPI_DIRECTION_1LINE_TX          = 0x0011    /*!< 1 line send only */
62 } SPI_DIRECTION_T;
63 
64 /**
65  * @brief SPI mode
66  */
67 typedef enum
68 {
69     SPI_MODE_SLAVE,     /*!< Slave mode */
70     SPI_MODE_MASTER     /*!< Master mode */
71 } SPI_MODE_T;
72 
73 /**
74  * @brief SPI Data length
75  */
76 typedef enum
77 {
78     SPI_DATA_LENGTH_8B, /*!< Set data frame format to 8bit */
79     SPI_DATA_LENGTH_16B /*!< Set data frame format to 16bit */
80 } SPI_DATA_LENGTH_T;
81 
82 /**
83  * @brief SPI Clock Polarity
84  */
85 typedef enum
86 {
87     SPI_CLKPOL_LOW,     /*!< Set SCK polarity to low in idle state */
88     SPI_CLKPOL_HIGH     /*!< Set SCK polarity to high in idle state */
89 } SPI_CLKPOL_T;
90 
91 /**
92  * @brief SPI Clock Phase
93  */
94 typedef enum
95 {
96     SPI_CLKPHA_1EDGE,   /*!< Sample value in the first clock edge */
97     SPI_CLKPHA_2EDGE    /*!< Sample value in the second clock edge */
98 } SPI_CLKPHA_T;
99 
100 /**
101  * @brief SPI Slave Select management
102  */
103 typedef enum
104 {
105     SPI_NSS_HARD,   /*!< Disable software NSS mode */
106     SPI_NSS_SOFT    /*!< Enable software NSS mode */
107 } SPI_NSS_T;
108 
109 /**
110  * @brief SPI BaudRate Prescaler
111  */
112 typedef enum
113 {
114     SPI_BAUDRATE_DIV_2,     /*!< BaudRate DIV = 2 */
115     SPI_BAUDRATE_DIV_4,     /*!< BaudRate DIV = 4 */
116     SPI_BAUDRATE_DIV_8,     /*!< BaudRate DIV = 8 */
117     SPI_BAUDRATE_DIV_16,    /*!< BaudRate DIV = 16 */
118     SPI_BAUDRATE_DIV_32,    /*!< BaudRate DIV = 32 */
119     SPI_BAUDRATE_DIV_64,    /*!< BaudRate DIV = 64 */
120     SPI_BAUDRATE_DIV_128,   /*!< BaudRate DIV = 128 */
121     SPI_BAUDRATE_DIV_256,   /*!< BaudRate DIV = 256 */
122 } SPI_BAUDRATE_DIV_T;
123 
124 /**
125  * @brief SPI MSB LSB transmission
126  */
127 typedef enum
128 {
129     SPI_FIRSTBIT_MSB,   /*!< MSB first */
130     SPI_FIRSTBIT_LSB    /*!< LSB first */
131 } SPI_FIRSTBIT_T;
132 
133 /**
134  * @brief I2S Mode
135  */
136 typedef enum
137 {
138     I2S_MODE_SLAVE_TX,  /*!< Slave transmit mode */
139     I2S_MODE_SLAVE_RX,  /*!< Slave receive mode */
140     I2S_MODE_MASTER_TX, /*!< Master transmit mode */
141     I2S_MODE_MASTER_RX  /*!< Master receive mode */
142 } I2S_MODE_T;
143 
144 /**
145  * @brief I2S Standard
146  */
147 typedef enum
148 {
149     I2S_STANDARD_PHILLIPS = 0x00,   /*!< I2S phillips mode */
150     I2S_STANDARD_MSB      = 0x01,   /*!< MSB alignment mode */
151     I2S_STANDARD_LSB      = 0x02,   /*!< LSB alignment mode */
152     I2S_STANDARD_PCMSHORT = 0x03,   /*!< PCB short frame synchronization mode */
153     I2S_STANDARD_PCMLONG  = 0x13    /*!< PCB long frame synchronization mode */
154 } I2S_STANDARD_T;
155 
156 /**
157  * @brief I2S data length
158  */
159 typedef enum
160 {
161     I2S_DATA_LENGHT_16B   = 0x00,   /*!< Set the length of data to 16-bit */
162     I2S_DATA_LENGHT_16BEX = 0x01,   /*!< Set the length of data to 16-bit extended */
163     I2S_DATA_LENGHT_24B   = 0x03,   /*!< Set the length of data to 24-bit */
164     I2S_DATA_LENGHT_32B   = 0x05,   /*!< Set the length of data to 32-bit */
165 } I2S_DATA_LENGTH_T;
166 
167 /**
168  * @brief I2S MCLK Output
169  */
170 typedef enum
171 {
172     I2S_MCLK_OUTPUT_DISABLE,    /*!< Disable I2S MCLK output */
173     I2S_MCLK_OUTPUT_ENABLE      /*!< Enable I2S MCLK output */
174 } I2S_MCLK_OUTPUT_T;
175 
176 /**
177  * @brief I2S Audio divider
178  */
179 typedef enum
180 {
181     I2S_AUDIO_DIV_192K    = 192000, /*!< Audio div = 192K */
182     I2S_AUDIO_DIV_96K     = 96000,  /*!< Audio div = 96K */
183     I2S_AUDIO_DIV_48K     = 48000,  /*!< Audio div = 48K */
184     I2S_AUDIO_DIV_44K     = 44100,  /*!< Audio div = 44.1K */
185     I2S_AUDIO_DIV_32K     = 32000,  /*!< Audio div = 32K */
186     I2S_AUDIO_DIV_22K     = 22050,  /*!< Audio div = 22.05K */
187     I2S_AUDIO_DIV_16K     = 16000,  /*!< Audio div = 16K */
188     I2S_AUDIO_DIV_11K     = 11025,  /*!< Audio div = 11.025K */
189     I2S_AUDIO_DIV_8K      = 8000,   /*!< Audio div = 8K */
190     I2S_AUDIO_DIV_DEFAULT = 2       /*!< Audio div = 2 */
191 } I2S_AUDIO_DIV_T;
192 
193 /**
194  * @brief I2S Clock Polarity
195  */
196 typedef enum
197 {
198     I2S_CLKPOL_LOW,     /*!< Set clock polarity to low */
199     I2S_CLKPOL_HIGH     /*!< Set clock polarity to high */
200 } I2S_CLKPOL_T;
201 
202 /**
203  * @brief SPI I2S DMA requests
204  */
205 typedef enum
206 {
207     SPI_I2S_DMA_REQ_TX, /*!< Tx buffer DMA transfer request */
208     SPI_I2S_DMA_REQ_RX  /*!< Rx buffer DMA transfer request */
209 } SPI_I2S_DMA_REQ_T;
210 
211 /**
212  * @brief SPI Direction select
213  */
214 typedef enum
215 {
216     SPI_DIRECTION_RX,   /*!< Selects Rx receive direction */
217     SPI_DIRECTION_TX    /*!< Selects Tx transmission direction */
218 } SPI_DIRECTION_SELECT_T;
219 
220 /**
221  * @brief    SPI interrupts definition
222  */
223 typedef enum
224 {
225     SPI_I2S_INT_TXBE  = 0x8002, /*!< Tx buffer empty interrupt */
226     SPI_I2S_INT_RXBNE = 0x4001, /*!< Rx buffer not empty interrupt */
227     SPI_I2S_INT_ERR   = 0x2000, /*!< Error interrupt */
228     I2S_INT_UDR       = 0x2008, /*!< Underrun Error interrupt flag */
229     SPI_INT_CRCE      = 0x2010, /*!< CRC Error interrupt flag */
230     SPI_INT_ME        = 0x2020, /*!< Mode Error interrupt flag */
231     SPI_I2S_INT_OVR   = 0x2040  /*!< Overrun interrupt flag */
232 } SPI_I2S_INT_T;
233 
234 /**
235  * @brief SPI flags definition
236  */
237 typedef enum
238 {
239     SPI_FLAG_RXBNE  = 0x0001,   /*!< Receive buffer not empty flag */
240     SPI_FLAG_TXBE   = 0x0002,   /*!< Transmit buffer empty flag */
241     I2S_FLAG_SCHDIR = 0x0004,   /*!< Side Channel flag */
242     I2S_FLAG_UDR    = 0x0008,   /*!< Underrun Error flag */
243     SPI_FLAG_CRCE   = 0x0010,   /*!< CRC Error flag */
244     SPI_FLAG_ME     = 0x0020,   /*!< Mode Error flag */
245     SPI_FLAG_OVR    = 0x0040,   /*!< Overrun flag */
246     SPI_FLAG_BSY    = 0x0080    /*!< Busy flag */
247 } SPI_FLAG_T;
248 
249 /**@} end of group SPI_Enumerations*/
250 
251 /** @addtogroup SPI_Structure Data Structure
252   @{
253 */
254 
255 /**
256  * @brief SPI Config structure definition
257  */
258 typedef struct
259 {
260     SPI_MODE_T          mode;           /*!< SPI mode selection */
261     SPI_DATA_LENGTH_T   length;         /*!< SPI data length selection */
262     SPI_CLKPHA_T        phase;          /*!< SPI clock phase selection */
263     SPI_CLKPOL_T        polarity;       /*!< SPI clock polarity selection */
264     SPI_NSS_T           nss;            /*!< Set SPI software NSS */
265     SPI_FIRSTBIT_T      firstBit;       /*!< Set first bit */
266     SPI_DIRECTION_T     direction;      /*!< SPI data direction mode selection */
267     SPI_BAUDRATE_DIV_T  baudrateDiv;    /*!< SPI BaudRate Prescaler selection */
268     uint16_t            crcPolynomial;  /*!< Setup CRC polynomial value */
269 } SPI_Config_T;
270 
271 /**
272  * @brief I2S Config structure definition
273  */
274 typedef struct
275 {
276     I2S_MODE_T          mode;       /*!< I2S mode selection */
277     I2S_STANDARD_T      standard;   /*!< I2S standard selection */
278     I2S_DATA_LENGTH_T   length;     /*!< Set I2S data length */
279     I2S_MCLK_OUTPUT_T   MCLKOutput; /*!< Set I2S MCLK output */
280     I2S_AUDIO_DIV_T     audioDiv;   /*!< I2S Audio divider selection */
281     I2S_CLKPOL_T        polarity;   /*!< I2S Clock polarity selection */
282 } I2S_Config_T;
283 
284 /**@} end of group SPI_Structure*/
285 
286 /** @defgroup SPI_Functions
287   @{
288 */
289 
290 /* Reset */
291 void SPI_I2S_Reset(SPI_T* spi);
292 
293 /* Initialization and Configuration */
294 void SPI_Config(SPI_T* spi, SPI_Config_T* spiConfig);
295 void I2S_Config(SPI_T* spi, I2S_Config_T* i2sConfig);
296 void SPI_ConfigStructInit(SPI_Config_T* spiConfig);
297 void I2S_ConfigStructInit(I2S_Config_T* i2sConfig);
298 void SPI_Enable(SPI_T* spi);
299 void SPI_Disable(SPI_T* spi);
300 void I2S_Enable(SPI_T* spi);
301 void I2S_Disable(SPI_T* spi);
302 void SPI_ConfigDataSize(SPI_T* spi, SPI_DATA_LENGTH_T length);
303 
304 void SPI_SetSoftwareNSS(SPI_T* spi);
305 void SPI_ResetSoftwareNSS(SPI_T* spi);
306 void SPI_EnableSSOutput(SPI_T* spi);
307 void SPI_DisableSSOutput(SPI_T* spi);
308 void SPI_ConfigBiDirectionalLine(SPI_T* spi, SPI_DIRECTION_SELECT_T direction);
309 
310 void SPI_EnableTIMode(SPI_T* spi);
311 void SPI_DisableTIMode(SPI_T* spi);
312 void I2S_ConfigFullDuplex(SPI_T* spi, I2S_Config_T* i2sConfig);
313 
314 /* Data transfers */
315 void SPI_I2S_TxData(SPI_T* spi, uint16_t data);
316 uint16_t SPI_I2S_RxData(SPI_T* spi);
317 
318 /* Hardware CRC Calculation */
319 void SPI_EnableCRC(SPI_T* spi);
320 void SPI_DisableCRC(SPI_T* spi);
321 void SPI_TxCRC(SPI_T* spi);
322 uint16_t SPI_ReadTxCRC(SPI_T* spi);
323 uint16_t SPI_ReadRxCRC(SPI_T* spi);
324 uint16_t SPI_ReadCRCPolynomial(SPI_T* spi);
325 
326 /* DMA transfers */
327 void SPI_I2S_EnableDMA(SPI_T* spi, SPI_I2S_DMA_REQ_T dmaReq);
328 void SPI_I2S_DisableDMA(SPI_T* spi, SPI_I2S_DMA_REQ_T dmaReq);
329 
330 /* Interrupts and flags */
331 void SPI_I2S_EnableInterrupt(SPI_T* spi, uint32_t interrupt);
332 void SPI_I2S_DisableInterrupt(SPI_T* spi, uint32_t interrupt);
333 uint8_t SPI_I2S_ReadStatusFlag(SPI_T* spi, SPI_FLAG_T flag);
334 void SPI_I2S_ClearStatusFlag(SPI_T* spi, SPI_FLAG_T flag);
335 uint8_t SPI_I2S_ReadIntFlag(SPI_T* spi, SPI_I2S_INT_T flag);
336 void SPI_I2S_ClearIntFlag(SPI_T* spi, SPI_I2S_INT_T flag);
337 
338 #ifdef __cplusplus
339 }
340 #endif
341 
342 #endif /* __APM32F4XX_SPI_H */
343 
344 /**@} end of group SPI_Enumerations */
345 /**@} end of group SPI_Driver */
346 /**@} end of group APM32F4xx_StdPeriphDriver */
347