1 /*!
2  * @file        apm32f0xx_spi.h
3  *
4  * @brief       This file contains all the functions prototypes for the SPI firmware library
5  *
6  * @version     V1.0.3
7  *
8  * @date        2022-09-20
9  *
10  * @attention
11  *
12  *  Copyright (C) 2020-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 useful 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 #ifndef __APM32F0XX_SPI_H
27 #define __APM32F0XX_SPI_H
28 
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32 
33 #include "apm32f0xx.h"
34 
35 /** @addtogroup APM32F0xx_StdPeriphDriver
36   @{
37 */
38 
39 /** @addtogroup SPI_Driver SPI Driver
40   @{
41 */
42 
43 /** @defgroup SPI_Macros Macros
44   @{
45 */
46 
47 /**@} end of group SPI_Macros */
48 
49 /** @defgroup SPI_Enumerations Enumerations
50   @{
51 */
52 
53 /**
54  * @brief   SPI data direction mode
55  */
56 typedef enum
57 {
58     SPI_DIRECTION_2LINES_FULLDUPLEX     = ((uint16_t)0x0000),  /*!< Full duplex mode,in 2-line unidirectional data mode */
59     SPI_DIRECTION_2LINES_RXONLY         = ((uint16_t)0x0400),  /*!< Receiver only, in 2-line unidirectional data mode */
60     SPI_DIRECTION_1LINE_RX              = ((uint16_t)0x8000),  /*!< Receiver mode, in 1 line bidirectional data mode */
61     SPI_DIRECTION_1LINE_TX              = ((uint16_t)0xC000),  /*!< Transmit mode, in 1 line bidirectional data mode */
62 } SPI_DIRECTION_T;
63 
64 /**
65  * @brief   SPI mode
66  */
67 typedef enum
68 {
69     SPI_MODE_SLAVE      = ((uint8_t)0),     /*!< Slave mode */
70     SPI_MODE_MASTER     = ((uint8_t)1),     /*!< Master mode */
71 } SPI_MODE_T;
72 
73 /**
74  * @brief   SPI data length
75  */
76 typedef enum
77 {
78     SPI_DATA_LENGTH_4B    = ((uint8_t)0x03),   /*!< Set data length to 4 bits */
79     SPI_DATA_LENGTH_5B    = ((uint8_t)0x04),   /*!< Set data length to 5 bits */
80     SPI_DATA_LENGTH_6B    = ((uint8_t)0x05),   /*!< Set data length to 6 bits */
81     SPI_DATA_LENGTH_7B    = ((uint8_t)0x06),   /*!< Set data length to 7 bits */
82     SPI_DATA_LENGTH_8B    = ((uint8_t)0x07),   /*!< Set data length to 8 bits */
83     SPI_DATA_LENGTH_9B    = ((uint8_t)0x08),   /*!< Set data length to 9 bits */
84     SPI_DATA_LENGTH_10B   = ((uint8_t)0x09),   /*!< Set data length to 10 bits */
85     SPI_DATA_LENGTH_11B   = ((uint8_t)0x0A),   /*!< Set data length to 11 bits */
86     SPI_DATA_LENGTH_12B   = ((uint8_t)0x0B),   /*!< Set data length to 12 bits */
87     SPI_DATA_LENGTH_13B   = ((uint8_t)0x0C),   /*!< Set data length to 13 bits */
88     SPI_DATA_LENGTH_14B   = ((uint8_t)0x0D),   /*!< Set data length to 14 bits */
89     SPI_DATA_LENGTH_15B   = ((uint8_t)0x0E),   /*!< Set data length to 15 bits */
90     SPI_DATA_LENGTH_16B   = ((uint8_t)0x0F),   /*!< Set data length to 16 bits */
91 } SPI_DATA_LENGTH_T;
92 
93 /**
94  * @brief   SPI CRC length
95  */
96 typedef enum
97 {
98     SPI_CRC_LENGTH_8B       = ((uint8_t)0), /*!< 8-bit CRC length */
99     SPI_CRC_LENGTH_16B      = ((uint8_t)1), /*!< 16-bit CRC length */
100 } SPI_CRC_LENGTH_T;
101 
102 /**
103  * @brief   SPI Clock Polarity
104  */
105 typedef enum
106 {
107     SPI_CLKPOL_LOW          = ((uint8_t)0), /*!< Clock Polarity low */
108     SPI_CLKPOL_HIGH         = ((uint8_t)1), /*!< Clock Polarity high */
109 } SPI_CLKPOL_T;
110 
111 /**
112  * @brief   SPI Clock Phase
113  */
114 typedef enum
115 {
116     SPI_CLKPHA_1EDGE        = ((uint8_t)0), /*!< 1 edge clock phase */
117     SPI_CLKPHA_2EDGE        = ((uint8_t)1), /*!< 2 edge clock phase */
118 } SPI_CLKPHA_T;
119 
120 /**
121  * @brief   Software slave control
122  */
123 typedef enum
124 {
125     SPI_SSC_DISABLE         = ((uint8_t)0), //!< Disable software select slave */
126     SPI_SSC_ENABLE          = ((uint8_t)1), //!< Enable software select slave */
127 } SPI_SSC_T;
128 
129 /**
130  * @brief   SPI BaudRate divider
131  */
132 typedef enum
133 {
134     SPI_BAUDRATE_DIV_2      = ((uint8_t)0), //!< Baud rate divider is 2 */
135     SPI_BAUDRATE_DIV_4      = ((uint8_t)1), //!< Baud rate divider is 4 */
136     SPI_BAUDRATE_DIV_8      = ((uint8_t)2), //!< Baud rate divider is 8 */
137     SPI_BAUDRATE_DIV_16     = ((uint8_t)3), //!< Baud rate divider is 16 */
138     SPI_BAUDRATE_DIV_32     = ((uint8_t)4), //!< Baud rate divider is 32 */
139     SPI_BAUDRATE_DIV_64     = ((uint8_t)5), //!< Baud rate divider is 64 */
140     SPI_BAUDRATE_DIV_128    = ((uint8_t)6), //!< Baud rate divider is 128 */
141     SPI_BAUDRATE_DIV_256    = ((uint8_t)7), //!< Baud rate divider is 256 */
142 } SPI_BAUDRATE_DIV_T;
143 
144 /**
145  * @brief   MSB or LSB is transmitted/received first
146  */
147 typedef enum
148 {
149     SPI_FIRST_BIT_MSB       = ((uint8_t)0), //!< First bit is MSB */
150     SPI_FIRST_BIT_LSB       = ((uint8_t)1), //!< First bit is LSB */
151 } SPI_FIRST_BIT_T;
152 
153 /**
154  * @brief   SPI FIFO reception threshold
155  */
156 typedef enum
157 {
158     SPI_RXFIFO_HALF         = ((uint8_t)0), //!< FIFO level is greater than or equal to 1/2 (16-bit) */
159     SPI_RXFIFO_QUARTER      = ((uint8_t)1), //!< FIFO level is greater than or equal to 1/4 (8-bit) */
160 } SPI_RXFIFO_T;
161 
162 /**
163  * @brief   SPI last DMA transfers and reception
164  */
165 typedef enum
166 {
167     SPI_LAST_DMA_TXRXEVEN    = ((uint16_t)0x0000),  //!< transmission Even reception Even */
168     SPI_LAST_DMA_TXEVENRXODD = ((uint16_t)0x2000),  //!< transmission Even reception Odd */
169     SPI_LAST_DMA_TXODDRXEVEN = ((uint16_t)0x4000),  //!< transmission Odd reception Even */
170     SPI_LAST_DMA_TXRXODD     = ((uint16_t)0x6000),  //!< transmission Odd reception Odd */
171 } SPI_LAST_DMA_T;
172 
173 /**
174  * @brief   SPI transmission fifo level
175  */
176 typedef enum
177 {
178     SPI_TXFIFO_LEVEL_EMPTY   = ((uint8_t)0x00),     //!< Transmission FIFO filled level is empty */
179     SPI_TXFIFO_LEVEL_QUARTER = ((uint8_t)0x01),     //!< Transmission FIFO filled level is more than quarter */
180     SPI_TXFIFO_LEVEL_HALF    = ((uint8_t)0x02),     //!< Transmission FIFO filled level is more than half */
181     SPI_TXFIFO_LEVEL_FULL    = ((uint8_t)0x03),     //!< Transmission FIFO filled level is full */
182 } SPI_TXFIFO_LEVEL_T;
183 
184 /**
185  * @brief   SPI reception fifo level
186  */
187 typedef enum
188 {
189     SPI_RXFIFO_LEVEL_EMPTY    = ((uint8_t)0x00),    //!< Reception FIFO filled level is empty */
190     SPI_RXFIFO_LEVEL_QUARTER  = ((uint8_t)0x01),    //!< Reception FIFO filled level is more than quarter */
191     SPI_RXFIFO_LEVEL_HALF     = ((uint8_t)0x02),    //!< Reception FIFO filled level is more than half */
192     SPI_RXFIFO_LEVEL_FULL     = ((uint8_t)0x03),    //!< Reception FIFO filled level is full */
193 } SPI_RXFIFO_LEVEL_T;
194 
195 /**
196  * @brief   SPI flags definition
197  */
198 typedef enum
199 {
200     SPI_FLAG_RXBNE      = ((uint16_t)0x0001),       //!< Receive buffer not empty flag */
201     SPI_FLAG_TXBE       = ((uint16_t)0x0002),       //!< Transmit buffer empty flag */
202     I2S_FLAG_CHDIR      = ((uint16_t)0x0004),       //!< Channel direction flag */
203     I2S_FLAG_UDR        = ((uint16_t)0x0008),       //!< Underrun flag */
204     SPI_FLAG_CRCE       = ((uint16_t)0x0010),       //!< CRC error flag */
205     SPI_FLAG_MME        = ((uint16_t)0x0020),       //!< Master mode error flag */
206     SPI_FLAG_OVR        = ((uint16_t)0x0040),       //!< Receive Overrun flag */
207     SPI_FLAG_BUSY       = ((uint16_t)0x0080),       //!< Busy flag */
208     SPI_FLAG_FFE        = ((uint16_t)0x0100),       //!< Frame format error flag */
209 } SPI_FLAG_T;
210 
211 /**
212  * @brief   SPI interrupt source
213  */
214 typedef enum
215 {
216     SPI_INT_ERRIE       = ((uint8_t)0x20),          //!< Error interrupt */
217     SPI_INT_RXBNEIE     = ((uint8_t)0x40),          //!< Receive buffer not empty interrupt */
218     SPI_INT_TXBEIE      = ((uint8_t)0x80),          //!< Transmit buffer empty interrupt */
219 } SPI_INT_T;
220 
221 /**
222  * @brief   SPI interrupt flag
223  */
224 typedef enum
225 {
226     SPI_INT_FLAG_RXBNE      = ((uint32_t)0x400001), //!< Receive buffer not empty interrupt flag */
227     SPI_INT_FLAG_TXBE       = ((uint32_t)0x800002), //!< Transmit buffer empty interrupt flag */
228     SPI_INT_FLAG_UDR        = ((uint32_t)0x200008), //!< Underrun flag interrupt flag */
229     SPI_INT_FLAG_MME        = ((uint32_t)0x200020), //!< Master mode error interrupt flag */
230     SPI_INT_FLAG_OVR        = ((uint32_t)0x200040), //!< Receive Overrun interrupt flag */
231     SPI_INT_FLAG_FFE        = ((uint32_t)0x200100), //!< Frame format error interrupt flag */
232 } SPI_INT_FLAG_T;
233 
234 /**
235  * @brief   I2S mode
236  */
237 typedef enum
238 {
239     I2S_MODE_SLAVER_TX     = ((uint8_t)0),          //!< Slave TX mode */
240     I2S_MODE_SLAVER_RX     = ((uint8_t)1),          //!< Slave RX mode */
241     I2S_MODE_MASTER_TX     = ((uint8_t)2),          //!< Master TX mode */
242     I2S_MODE_MASTER_RX     = ((uint8_t)3),          //!< Master RX mode */
243 } I2S_MODE_T;
244 
245 /**
246  * @brief   I2S Standard
247  */
248 typedef enum
249 {
250     I2S_STANDARD_PHILIPS   = ((uint16_t)0x0000),    //!< I2S Philips standard. */
251     I2S_STANDARD_MSB       = ((uint16_t)0x0010),    //!< MSB justified standard (left justified) */
252     I2S_STANDARD_LSB       = ((uint16_t)0x0020),    //!< LSB justified standard (right justified) */
253     I2S_STANDARD_PCM_SHORT = ((uint16_t)0x0030),    //!< PCM short standard */
254     I2S_STANDARD_PCM_LONG  = ((uint16_t)0x00B0),    //!< PCM long standard */
255 } I2S_STANDARD_T;
256 
257 /**
258  * @brief   I2S data length
259  */
260 typedef enum
261 {
262     I2S_DATA_LENGTH_16B   = ((uint8_t)0x00),        //!< Set data length to 16 bits */
263     I2S_DATA_LENGTH_16BEX = ((uint8_t)0x01),        //!< Set data length to 16 bits */
264     I2S_DATA_LENGTH_24B   = ((uint8_t)0x03),        //!< Set data length to 24 bits */
265     I2S_DATA_LENGTH_32B   = ((uint8_t)0x05),        //!< Set data length to 32 bits */
266 } I2S_DATA_LENGTH_T;
267 
268 /**
269  * @brief   I2S MCLK Output
270  */
271 typedef enum
272 {
273     I2S_MCLK_OUTPUT_DISABLE = ((uint8_t)0x00),      //!< Set I2S MCLK Output disable */
274     I2S_MCLK_OUTPUT_ENABLE  = ((uint8_t)0x01),      //!< Set I2S MCLK Output enable */
275 } I2S_MCLK_OUTPUT_T;
276 
277 /**
278  * @brief   I2S Audio divider
279  */
280 typedef enum
281 {
282     I2S_AUDIO_DIV_192K    = ((uint32_t)192000), /*!< specifie the AUDIO divider division factor as 192K */
283     I2S_AUDIO_DIV_96K     = ((uint32_t)96000),  /*!< specifie the AUDIO divider division factor as 96K */
284     I2S_AUDIO_DIV_48K     = ((uint32_t)48000),  /*!< specifie the AUDIO divider division factor as 48K */
285     I2S_AUDIO_DIV_44K     = ((uint32_t)44100),  /*!< specifie the AUDIO divider division factor as 44K */
286     I2S_AUDIO_DIV_32K     = ((uint32_t)32000),  /*!< specifie the AUDIO divider division factor as 32K */
287     I2S_AUDIO_DIV_22K     = ((uint32_t)22050),  /*!< specifie the AUDIO divider division factor as 22K */
288     I2S_AUDIO_DIV_16K     = ((uint32_t)16000),  /*!< specifie the AUDIO divider division factor as 16K */
289     I2S_AUDIO_DIV_11K     = ((uint32_t)11025),  /*!< specifie the AUDIO divider division factor as 11K */
290     I2S_AUDIO_DIV_8K      = ((uint32_t)8000),   /*!< specifie the AUDIO divider division factor as 8K */
291     I2S_AUDIO_DIV_DEFAULT = ((uint32_t)2),      /*!< specifie the AUDIO divider division factor as DEFAULT value */
292 } I2S_AUDIO_DIV_T;
293 
294 /**
295  * @brief   I2S Clock Polarity
296  */
297 typedef enum
298 {
299     I2S_CLKPOL_LOW          = ((uint8_t)0), //!< Clock Polarity low */
300     I2S_CLKPOL_HIGH         = ((uint8_t)1), //!< Clock Polarity high */
301 } I2S_CLKPOL_T;
302 
303 /**@} end of group SPI_Enumerations*/
304 
305 /** @defgroup SPI_Structures Structures
306   @{
307 */
308 
309 /**
310  * @brief   SPI Config struct definition
311  */
312 typedef struct
313 {
314     SPI_MODE_T           mode;          /*!< Specifies the SPI mode */
315     SPI_DATA_LENGTH_T    length;        /*!< Specifies the SPI data length */
316     SPI_CLKPHA_T         phase;         /*!< Specifies the Clock phase */
317     SPI_CLKPOL_T         polarity;      /*!< Specifies the Clock polarity */
318     SPI_SSC_T            slaveSelect;   /*!< Specifies the slave select mode */
319     SPI_FIRST_BIT_T      firstBit;      /*!< Specifies the Frame format */
320     SPI_DIRECTION_T      direction;     /*!< Specifies the data direction mode */
321     SPI_BAUDRATE_DIV_T   baudrateDiv;   /*!< Specifies the baud rate divider */
322     uint8_t crcPolynomial;              /*!< Specifies the CRC polynomial */
323 } SPI_Config_T;
324 
325 /**
326  * @brief   I2S Config struct definition
327  */
328 typedef struct
329 {
330     I2S_MODE_T           mode;           /*!< Specifies the I2S mode */
331     I2S_STANDARD_T       standard;       /*!< Specifies the I2S standard */
332     I2S_DATA_LENGTH_T    length;         /*!< Specifies the I2S data length */
333     I2S_MCLK_OUTPUT_T    MCLKOutput;     /*!< Specifies the I2S MCLK Output */
334     I2S_AUDIO_DIV_T      audioDiv;       /*!< Specifies the I2S Audio Diver */
335     I2S_CLKPOL_T         polarity;       /*!< Specifies the Clock polarity */
336 } I2S_Config_T;
337 
338 /**@} end of group SPI_Structures*/
339 
340 /** @defgroup SPI_Variables Variables
341   @{
342 */
343 
344 /**@} end of group SPI_Variables */
345 
346 /** @defgroup SPI_Functions Functions
347   @{
348 */
349 
350 /** SPI reset and configuration */
351 void SPI_Reset(SPI_T* spi);
352 void SPI_Config(SPI_T* spi, SPI_Config_T* spiConfig);
353 void I2S_Config(SPI_T* spi, I2S_Config_T* i2sConfig);  /*!< Not for APM32F030 devices */
354 void SPI_ConfigStructInit(SPI_Config_T* spiConfig);
355 void I2S_ConfigStructInit(I2S_Config_T* i2sConfig);   /*!< Not for APM32F030 devices */
356 void SPI_Enable(SPI_T* spi);
357 void SPI_Disable(SPI_T* spi);
358 void I2S_Enable(SPI_T* spi);   /*!< Not for APM32F030 devices */
359 void I2S_Disable(SPI_T* spi);  /*!< Not for APM32F030 devices */
360 void SPI_EnableFrameFormatMode(SPI_T* spi);
361 void SPI_DisableFrameFormatMode(SPI_T* spi);
362 void SPI_ConfigDatalength(SPI_T* spi, uint8_t length);
363 void SPI_EnableOutputDirection(SPI_T* spi);
364 void SPI_DisableOutputDirection(SPI_T* spi);
365 void SPI_EnableInternalSlave(SPI_T* spi);
366 void SPI_DisableInternalSlave(SPI_T* spi);
367 void SPI_EnableSSoutput(SPI_T* spi);
368 void SPI_DisableSSoutput(SPI_T* spi);
369 void SPI_EnableNSSPulse(SPI_T* spi);
370 void SPI_DisableNSSPulse(SPI_T* spi);
371 
372 /**  CRC */
373 void SPI_CRCLength(SPI_T* spi, SPI_CRC_LENGTH_T  crcLength);
374 void SPI_EnableCRC(SPI_T* spi);
375 void SPI_DisableCRC(SPI_T* spi);
376 void SPI_TxCRC(SPI_T* spi);
377 uint16_t SPI_ReadRxCRC(SPI_T* spi);
378 uint16_t SPI_ReadTxCRC(SPI_T* spi);
379 uint16_t SPI_ReadCRCPolynomial(SPI_T* spi);
380 
381 /**  DMA */
382 void SPI_EnableDMARxBuffer(SPI_T* spi);
383 void SPI_DisableDMARxBuffer(SPI_T* spi);
384 void SPI_EnableDMATxBuffer(SPI_T* spi);
385 void SPI_DisableDMATxBuffer(SPI_T* spi);
386 void SPI_LastDMATransfer(SPI_T* spi, SPI_LAST_DMA_T  lastDMA);
387 
388 /** FIFO */
389 void SPI_ConfigFIFOThreshold(SPI_T* spi, SPI_RXFIFO_T  threshold);
390 uint8_t SPI_ReadTransmissionFIFOLeve(SPI_T* spi);
391 uint8_t SPI_ReadReceptionFIFOLeve(SPI_T* spi);
392 
393 /** Interrupt */
394 void SPI_EnableInterrupt(SPI_T* spi, uint8_t interrupt);
395 void SPI_DisableInterrupt(SPI_T* spi, uint8_t interrupt);
396 
397 /** Transmit and receive */
398 void SPI_TxData8(SPI_T* spi, uint8_t data);
399 void SPI_I2S_TxData16(SPI_T* spi, uint16_t data);
400 uint8_t SPI_RxData8(SPI_T* spi);
401 uint16_t SPI_I2S_RxData16(SPI_T* spi);
402 
403 /** flag */
404 uint8_t SPI_ReadStatusFlag(SPI_T* spi, SPI_FLAG_T flag);
405 void SPI_ClearStatusFlag(SPI_T* spi, uint8_t flag);
406 uint8_t SPI_ReadIntFlag(SPI_T* spi, SPI_INT_FLAG_T flag);
407 
408 #ifdef __cplusplus
409 }
410 #endif
411 
412 #endif /* __APM32F0XX_SPI_H */
413 
414 /**@} end of group SPI_Functions */
415 /**@} end of group SPI_Driver */
416 /**@} end of group APM32F0xx_StdPeriphDriver */
417