]> git.sur5r.net Git - freertos/blob
127af15a4e4a39ed6a7c607c42f4470d2004f53f
[freertos] /
1 /*\r
2  * @brief SPI registers and control functions\r
3  *\r
4  * @note\r
5  * Copyright(C) NXP Semiconductors, 2012\r
6  * All rights reserved.\r
7  *\r
8  * @par\r
9  * Software that is described herein is for illustrative purposes only\r
10  * which provides customers with programming information regarding the\r
11  * LPC products.  This software is supplied "AS IS" without any warranties of\r
12  * any kind, and NXP Semiconductors and its licensor disclaim any and\r
13  * all warranties, express or implied, including all implied warranties of\r
14  * merchantability, fitness for a particular purpose and non-infringement of\r
15  * intellectual property rights.  NXP Semiconductors assumes no responsibility\r
16  * or liability for the use of the software, conveys no license or rights under any\r
17  * patent, copyright, mask work right, or any other intellectual property rights in\r
18  * or to any products. NXP Semiconductors reserves the right to make changes\r
19  * in the software without notification. NXP Semiconductors also makes no\r
20  * representation or warranty that such application will be suitable for the\r
21  * specified use without further testing or modification.\r
22  *\r
23  * @par\r
24  * Permission to use, copy, modify, and distribute this software and its\r
25  * documentation is hereby granted, under NXP Semiconductors' and its\r
26  * licensor's relevant copyrights in the software, without fee, provided that it\r
27  * is used in conjunction with NXP Semiconductors microcontrollers.  This\r
28  * copyright, permission, and disclaimer notice must appear in all copies of\r
29  * this code.\r
30  */\r
31 \r
32 #ifndef __SPI_001_H_\r
33 #define __SPI_001_H_\r
34 \r
35 #include "sys_config.h"\r
36 #include "cmsis.h"\r
37 \r
38 #ifdef __cplusplus\r
39 extern "C" {\r
40 #endif\r
41 \r
42 /** @defgroup IP_SPI_001 IP: SPI register block and driver\r
43  * @ingroup IP_Drivers\r
44  * @{\r
45  */\r
46 \r
47 /**\r
48  * @brief SPI register block structure\r
49  */\r
50 typedef struct {                                        /*!< SPI Structure          */\r
51         __IO uint32_t  CR;                              /*!< SPI Control Register. This register controls the operation of the SPI. */\r
52         __I  uint32_t  SR;                              /*!< SPI Status Register. This register shows the status of the SPI. */\r
53         __IO uint32_t  DR;                              /*!< SPI Data Register. This bi-directional register provides the transmit and receive data for the SPI. Transmit data is provided to the SPI0 by writing to this register. Data received by the SPI0 can be read from this register. */\r
54         __IO uint32_t  CCR;                             /*!< SPI Clock Counter Register. This register controls the frequency of a master's SCK0. */\r
55         __I  uint32_t  RESERVED0[3];\r
56         __IO uint32_t  INT;                             /*!< SPI Interrupt Flag. This register contains the interrupt flag for the SPI interface. */\r
57 } IP_SPI_001_T;\r
58 \r
59 /*\r
60  * Macro defines for SPI Control register\r
61  */\r
62 /* SPI CFG Register BitMask */\r
63 #define SPI_CR_BITMASK       ((uint32_t) 0xFFC)\r
64 /** Enable of controlling the number of bits per transfer  */\r
65 #define SPI_CR_BIT_EN         ((uint32_t) (1 << 2))\r
66 /** Mask of field of bit controlling */\r
67 #define SPI_CR_BITS_MASK      ((uint32_t) 0xF00)\r
68 /** Set the number of bits per a transfer */\r
69 #define SPI_CR_BITS(n)        ((uint32_t) ((n << 8) & 0xF00))   /* n is in range 8-16 */\r
70 /** SPI Clock Phase Select*/\r
71 #define SPI_CR_CPHA_FIRST     ((uint32_t) (0))  /*Capture data on the first edge, Change data on the following edge*/\r
72 #define SPI_CR_CPHA_SECOND    ((uint32_t) (1 << 3))     /*Change data on the first edge, Capture data on the following edge*/\r
73 /** SPI Clock Polarity Select*/\r
74 #define SPI_CR_CPOL_LO        ((uint32_t) (0))  /* The rest state of the clock (between frames) is low.*/\r
75 #define SPI_CR_CPOL_HI        ((uint32_t) (1 << 4))     /* The rest state of the clock (between frames) is high.*/\r
76 /** SPI Slave Mode Select */\r
77 #define SPI_CR_SLAVE_EN       ((uint32_t) 0)\r
78 /** SPI Master Mode Select */\r
79 #define SPI_CR_MASTER_EN      ((uint32_t) (1 << 5))\r
80 /** SPI MSB First mode enable */\r
81 #define SPI_CR_MSB_FIRST_EN   ((uint32_t) 0)    /*Data will be transmitted and received in standard order (MSB first).*/\r
82 /** SPI LSB First mode enable */\r
83 #define SPI_CR_LSB_FIRST_EN   ((uint32_t) (1 << 6))     /*Data will be transmitted and received in reverse order (LSB first).*/\r
84 /** SPI interrupt enable */\r
85 #define SPI_CR_INT_EN         ((uint32_t) (1 << 7))\r
86 \r
87 /*\r
88  * Macro defines for SPI Status register\r
89  */\r
90 /** SPI STAT Register BitMask */\r
91 #define SPI_SR_BITMASK        ((uint32_t) 0xF8)\r
92 /** Slave abort Flag */\r
93 #define SPI_SR_ABRT           ((uint32_t) (1 << 3))     /* When 1, this bit indicates that a slave abort has occurred. */\r
94 /* Mode fault Flag */\r
95 #define SPI_SR_MODF           ((uint32_t) (1 << 4))     /* when 1, this bit indicates that a Mode fault error has occurred. */\r
96 /** Read overrun flag*/\r
97 #define SPI_SR_ROVR           ((uint32_t) (1 << 5))     /* When 1, this bit indicates that a read overrun has occurred. */\r
98 /** Write collision flag. */\r
99 #define SPI_SR_WCOL           ((uint32_t) (1 << 6))     /* When 1, this bit indicates that a write collision has occurred.. */\r
100 /** SPI transfer complete flag. */\r
101 #define SPI_SR_SPIF           ((uint32_t) (1 << 7))             /* When 1, this bit indicates when a SPI data transfer is complete.. */\r
102 /** SPI error flag */\r
103 #define SPI_SR_ERROR          (SPI_SR_ABRT | SPI_SR_MODF | SPI_SR_ROVR | SPI_SR_WCOL)\r
104 /*\r
105  * Macro defines for SPI Test Control Register register\r
106  */\r
107 /*Enable SPI Test Mode */\r
108 #define SPI_TCR_TEST(n)       ((uint32_t) ((n & 0x3F) << 1))\r
109 \r
110 /*\r
111  * Macro defines for SPI Interrupt register\r
112  */\r
113 /** SPI interrupt flag */\r
114 #define SPI_INT_SPIF          ((uint32_t) (1 << 0))\r
115 \r
116 /**\r
117  * Macro defines for SPI Data register\r
118  */\r
119 /** Receiver Data  */\r
120 #define SPI_DR_DATA(n)        ((uint32_t) ((n) & 0xFFFF))\r
121 \r
122 /** @brief SPI Mode*/\r
123 typedef enum IP_SPI_MODE {\r
124         SPI_MODE_MASTER = SPI_CR_MASTER_EN,                     /* Master Mode */\r
125         SPI_MODE_SLAVE = SPI_CR_SLAVE_EN,                       /* Slave Mode */\r
126 } IP_SPI_MODE_T;\r
127 \r
128 /** @brief SPI Clock Mode*/\r
129 typedef enum IP_SPI_CLOCK_MODE {\r
130         SPI_CLOCK_CPHA0_CPOL0 = SPI_CR_CPOL_LO | SPI_CR_CPHA_FIRST,             /**< CPHA = 0, CPOL = 0 */\r
131         SPI_CLOCK_CPHA0_CPOL1 = SPI_CR_CPOL_HI | SPI_CR_CPHA_FIRST,             /**< CPHA = 0, CPOL = 1 */\r
132         SPI_CLOCK_CPHA1_CPOL0 = SPI_CR_CPOL_LO | SPI_CR_CPHA_SECOND,    /**< CPHA = 1, CPOL = 0 */\r
133         SPI_CLOCK_CPHA1_CPOL1 = SPI_CR_CPOL_HI | SPI_CR_CPHA_SECOND,    /**< CPHA = 1, CPOL = 1 */\r
134         SPI_CLOCK_MODE0 = SPI_CLOCK_CPHA0_CPOL0,/**< alias */\r
135         SPI_CLOCK_MODE1 = SPI_CLOCK_CPHA1_CPOL0,/**< alias */\r
136         SPI_CLOCK_MODE2 = SPI_CLOCK_CPHA0_CPOL1,/**< alias */\r
137         SPI_CLOCK_MODE3 = SPI_CLOCK_CPHA1_CPOL1,/**< alias */\r
138 } IP_SPI_CLOCK_MODE_T;\r
139 \r
140 /** @brief SPI Data Order Mode*/\r
141 typedef enum IP_SPI_DATA_ORDER {\r
142         SPI_DATA_MSB_FIRST = SPI_CR_MSB_FIRST_EN,                       /* Standard Order */\r
143         SPI_DATA_LSB_FIRST = SPI_CR_LSB_FIRST_EN,                       /* Reverse Order */\r
144 } IP_SPI_DATA_ORDER_T;\r
145 \r
146 /*\r
147  * @brief Number of bits per frame\r
148  */\r
149 typedef enum IP_SPI_BITS {\r
150         SPI_BITS_8 = SPI_CR_BITS(8),            /**< 8 bits/frame */\r
151         SPI_BITS_9 = SPI_CR_BITS(9),            /**< 9 bits/frame */\r
152         SPI_BITS_10 = SPI_CR_BITS(10),          /**< 10 bits/frame */\r
153         SPI_BITS_11 = SPI_CR_BITS(11),          /**< 11 bits/frame */\r
154         SPI_BITS_12 = SPI_CR_BITS(12),          /**< 12 bits/frame */\r
155         SPI_BITS_13 = SPI_CR_BITS(13),          /**< 13 bits/frame */\r
156         SPI_BITS_14 = SPI_CR_BITS(14),          /**< 14 bits/frame */\r
157         SPI_BITS_15 = SPI_CR_BITS(15),          /**< 15 bits/frame */\r
158         SPI_BITS_16 = SPI_CR_BITS(16),          /**< 16 bits/frame */\r
159 } IP_SPI_BITS_T;\r
160 \r
161 /**\r
162  * @brief       Get the current status of SPI controller\r
163  * @param       pSPI    : The base of SPI peripheral on the chip\r
164  * @return      SPI Status (Or-ed bit value of SPI_SR_*)\r
165  * @note         See user manual about how status bits are cleared.\r
166  */\r
167 STATIC INLINE uint32_t IP_SPI_GetStatus(IP_SPI_001_T *pSPI)\r
168 {\r
169         return pSPI->SR;\r
170 }\r
171 \r
172 /**\r
173  * @brief       Enable the interrupt for the SPI\r
174  * @param       pSPI            : The base of SPI peripheral on the chip\r
175  * @return      Nothing\r
176  */\r
177 STATIC INLINE void IP_SPI_IntEnable(IP_SPI_001_T *pSPI)\r
178 {\r
179         pSPI->CR |= SPI_CR_INT_EN;\r
180 }\r
181 \r
182 /**\r
183  * @brief       Disable the interrupt for the SPI\r
184  * @param       pSPI            : The base of SPI peripheral on the chip\r
185  * @return      Nothing\r
186  */\r
187 STATIC INLINE void IP_SPI_IntDisable(IP_SPI_001_T *pSPI)\r
188 {\r
189         pSPI->CR &= ~SPI_CR_INT_EN;\r
190 }\r
191 \r
192 /**\r
193  * @brief       Get the interrupt status\r
194  * @param       pSPI    : The base of SPI peripheral on the chip\r
195  * @return      SPI interrupt Status (Or-ed bit value of SPI_INT_*)\r
196  */\r
197 STATIC INLINE uint32_t IP_SPI_GetIntStatus(IP_SPI_001_T *pSPI)\r
198 {\r
199         return pSPI->INT;\r
200 }\r
201 \r
202 /**\r
203  * @brief       Clear the interrupt status\r
204  * @param       pSPI    : The base of SPI peripheral on the chip\r
205  * @param       mask    : SPI interrupt mask (Or-ed bit value of SPI_INT_*)\r
206  * @return      Nothing\r
207  */\r
208 STATIC INLINE void IP_SPI_ClearIntStatus(IP_SPI_001_T *pSPI, uint32_t mask)\r
209 {\r
210         pSPI->INT = mask;\r
211 }\r
212 \r
213 /**\r
214  * @brief       Send SPI 16-bit data\r
215  * @param       pSPI    : The base of SPI peripheral on the chip\r
216  * @param       data    : Transmit Data\r
217  * @return      Nothing\r
218  */\r
219 STATIC INLINE void IP_SPI_SendFrame(IP_SPI_001_T *pSPI, uint16_t data)\r
220 {\r
221         pSPI->DR = SPI_DR_DATA(data);\r
222 }\r
223 \r
224 /**\r
225  * @brief       Get received SPI data\r
226  * @param       pSPI    : The base of SPI peripheral on the chip\r
227  * @return      receive data\r
228  */\r
229 STATIC INLINE uint16_t IP_SPI_ReceiveFrame(IP_SPI_001_T *pSPI)\r
230 {\r
231         return SPI_DR_DATA(pSPI->DR);\r
232 }\r
233 \r
234 /**\r
235  * @brief       Set up output clocks per bit for SPI bus\r
236  * @param       pSPI            : The base of SPI peripheral on the chip\r
237  * @param       counter : the number of SPI peripheral clock cycles that make up an SPI clock\r
238  * @return       Nothing\r
239  * @note        The counter must be an even number greater than or equal to 8. <br>\r
240  *              The SPI SCK rate = PCLK_SPI / counter.\r
241  */\r
242 STATIC INLINE void IP_SPI_SetClockCounter(IP_SPI_001_T *pSPI, uint32_t counter)\r
243 {\r
244         pSPI->CCR = counter;\r
245 }\r
246 \r
247 /**\r
248  * @brief       Set up the SPI frame format\r
249  * @param       pSPI            : The base of SPI peripheral on the chip\r
250  * @param       bits            : The number of bits transferred in each frame.\r
251  * @param       clockMode       : Select Clock polarity and Clock phase, should be : <br>\r
252  *                                                      - SPI_CLOCK_CPHA0_CPOL0<br>\r
253  *                                                      - SPI_CLOCK_CPHA0_CPOL1<br>\r
254  *                                                      - SPI_CLOCK_CPHA1_CPOL0<br>\r
255  *                                                      - SPI_CLOCK_CPHA1_CPOL1<br>\r
256  *                                                      or SPI_CLOCK_MODE*\r
257  * @param       order   : Data order (MSB first/LSB first).\r
258  * @return       Nothing\r
259  * @note        Note: The clockFormat is only used in SPI mode\r
260  */\r
261 STATIC INLINE void IP_SPI_SetFormat(IP_SPI_001_T *pSPI, IP_SPI_BITS_T bits,\r
262                                                                         IP_SPI_CLOCK_MODE_T clockMode, IP_SPI_DATA_ORDER_T order)\r
263 {\r
264         pSPI->CR = (pSPI->CR & (~0xF1C)) | SPI_CR_BIT_EN | bits | clockMode | order;\r
265 }\r
266 \r
267 /**\r
268  * @brief       Get the number of bits transferred in each frame\r
269  * @param       pSPI    : The base of SPI peripheral on the chip\r
270  * @return       the number of bits transferred in each frame\r
271  */\r
272 STATIC INLINE IP_SPI_BITS_T IP_SPI_GetDataSize(IP_SPI_001_T *pSPI)\r
273 {\r
274         return (pSPI->CR & SPI_CR_BIT_EN) ? ((IP_SPI_BITS_T) (pSPI->CR & SPI_CR_BITS_MASK)) : SPI_BITS_8;\r
275 }\r
276 \r
277 /**\r
278  * @brief       Get the current CPHA & CPOL setting\r
279  * @param       pSPI    : The base of SPI peripheral on the chip\r
280  * @return      CPHA & CPOL setting\r
281  */\r
282 STATIC INLINE IP_SPI_CLOCK_MODE_T IP_SPI_GetClockMode(IP_SPI_001_T *pSPI)\r
283 {\r
284         return (IP_SPI_CLOCK_MODE_T) (pSPI->CR & (3 << 3));\r
285 }\r
286 \r
287 /**\r
288  * @brief       Set the SPI working as master or slave mode\r
289  * @param       pSPI    : The base of SPI peripheral on the chip\r
290  * @param       mode    : Operating mode\r
291  * @return       Nothing\r
292  */\r
293 STATIC INLINE void IP_SPI_SetMode(IP_SPI_001_T *pSPI, IP_SPI_MODE_T mode)\r
294 {\r
295         pSPI->CR = (pSPI->CR & (~(1 << 5))) | mode;\r
296 }\r
297 \r
298 /**\r
299  * @brief       Set the SPI working as master or slave mode\r
300  * @param       pSPI    : The base of SPI peripheral on the chip\r
301  * @return       Operating mode\r
302  */\r
303 STATIC INLINE IP_SPI_MODE_T IP_SPI_GetMode(IP_SPI_001_T *pSPI)\r
304 {\r
305         return (IP_SPI_MODE_T) (pSPI->CR & (1 << 5));\r
306 }\r
307 \r
308 /**\r
309  * @}\r
310  */\r
311 \r
312 #ifdef __cplusplus\r
313 }\r
314 #endif\r
315 \r
316 #endif /* __SPI_001_H_ */\r