PIC24 Support Libraries
esos_pic24_spi.h
Go to the documentation of this file.
1 /*
2  * "Copyright (c) 2008 Robert B. Reese, Bryan A. Jones, J. W. Bruce ("AUTHORS")"
3  * All rights reserved.
4  * (R. Reese, reese_AT_ece.msstate.edu, Mississippi State University)
5  * (B. A. Jones, bjones_AT_ece.msstate.edu, Mississippi State University)
6  * (J. W. Bruce, jwbruce_AT_ece.msstate.edu, Mississippi State University)
7  *
8  * Permission to use, copy, modify, and distribute this software and its
9  * documentation for any purpose, without fee, and without written agreement is
10  * hereby granted, provided that the above copyright notice, the following
11  * two paragraphs and the authors appear in all copies of this software.
12  *
13  * IN NO EVENT SHALL THE "AUTHORS" BE LIABLE TO ANY PARTY FOR
14  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
15  * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE "AUTHORS"
16  * HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
17  *
18  * THE "AUTHORS" SPECIFICALLY DISCLAIMS ANY WARRANTIES,
19  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20  * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
21  * ON AN "AS IS" BASIS, AND THE "AUTHORS" HAS NO OBLIGATION TO
22  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
23  *
24  * Please maintain this header in its entirety when copying/modifying
25  * these files.
26  *
27  *
28  */
29 
30 
31 #ifndef _ESOS_PIC24_SPI_H
32 #define _ESOS_PIC24_SPI_H
33 
34 
35 /**
36  * \addtogroup ESOS_SPI_Service
37  * @{
38  */
39 
40 
41 // Documentation for this file. If the \file tag isn't present,
42 // this file won't be documented.
43 /** \file
44  * This file contains routines which se SPI on the Microchip PIC24 MCU.
45  */
46 
47 
48 /* I N C L U D E S **********************************************************/
49 #include "esos.h"
50 #include "esos_pic24.h"
51 
52 /* D E F I N I T I O N S ****************************************************/
53 /*
54 The following macros are a subset of the AND/OR macros found in the
55 the MPLAB C30/src/peripheral_24F/spi.h file and placed
56 in this header for use solely and exclusively on Microchip
57 PICmicro Microcontroller products as
58 specified in the MPLAB C30/src/peripheral_24F/spi.h header.
59 */
60 
61 /* SPIXCON1: SPIx CONTROL REGISTER 1 */
62 #define DISABLE_SCK_PIN 0x1000 /* SCK pin is not used by module */
63 #define ENABLE_SCK_PIN 0x0000 /* SCK pin is used by module */
64 #define SCK_PIN_MASK (~DISABLE_SCK_PIN)
65 
66 #define DISABLE_SDO_PIN 0x0800 /* SDO pin is not used by module */
67 #define ENABLE_SDO_PIN 0x0000 /* SDO pin is used by module */
68 #define SDO_PIN_MASK (~DISABLE_SDO_PIN)
69 
70 #define SPI_MODE16_ON 0x0400 /* Communication is word wide */
71 #define SPI_MODE8_ON 0x0000 /* Communication is byte wide */
72 #define SPI_MODE_MASK (~SPI_MODE16_ON)
73 
74 #define SPI_SMP_ON 0x0200 /* Input data sampled at end of data output time */
75 #define SPI_SMP_OFF 0x0000 /* Input data sampled at middle of data output time */
76 #define SPI_SMP_MASK (~SPI_SMP_ON)
77 
78 #define SPI_CKE_ON 0x0100 /* Transmit happens from active clock state to idle clock state*/
79 #define SPI_CKE_OFF 0x0000 /* Transmit happens on transition from idle clock state to active clock state */
80 #define SPI_CKE_MASK (~SPI_CKE_ON)
81 
82 #define SLAVE_ENABLE_ON 0x0080 /* Slave Select enbale */
83 #define SLAVE_ENABLE_OFF 0x0000 /* Slave Select not used by module */
84 #define SLAVE_ENABLE_MASK (~SLAVE_ENABLE_ON)
85 
86 #define CLK_POL_ACTIVE_LOW 0x0040 /* Idle state for clock is high, active is low */
87 #define CLK_POL_ACTIVE_HIGH 0x0000 /* Idle state for clock is low, active is high */
88 #define CLK_POL_ACTIVE_MASK (~CLK_POL_ACTIVE_LOW)
89 
90 #define MASTER_ENABLE_ON 0x0020 /* Master Mode */
91 #define MASTER_ENABLE_OFF 0x0000 /* Slave Mode */
92 #define MASTER_ENABLE_MASK (~MASTER_ENABLE_ON)
93 
94 #define SEC_PRESCAL_1_1 0x001c /* Secondary Prescale 1:1 */
95 #define SEC_PRESCAL_2_1 0x0018 /* Secondary Prescale 2:1 */
96 #define SEC_PRESCAL_3_1 0x0014 /* Secondary Prescale 3:1 */
97 #define SEC_PRESCAL_4_1 0x0010/* Secondary Prescale 4:1 */
98 #define SEC_PRESCAL_5_1 0x000c /* Secondary Prescale 5:1 */
99 #define SEC_PRESCAL_6_1 0x0008/* Secondary Prescale 6:1 */
100 #define SEC_PRESCAL_7_1 0x0004 /* Secondary Prescale 7:1 */
101 #define SEC_PRESCAL_8_1 0x0000 /* Secondary Prescale 8:1 */
102 #define SEC_PRESCAL_MASK (~SEC_PRESCAL_1_1)
103 
104 #define PRI_PRESCAL_1_1 0x0003 /* Primary Prescale 1:1 */
105 #define PRI_PRESCAL_4_1 0x0002 /* Primary Prescale 4:1 */
106 #define PRI_PRESCAL_16_1 0x0001 /* Primary Prescale 16:1 */
107 #define PRI_PRESCAL_64_1 0x0000 /* Primary Prescale 64:1 */
108 #define PRI_PRESCAL_MASK (~PRI_PRESCAL_1_1)
109 
110 /* SPIxSTAT REGISTER */
111 #define SPI_ENABLE 0x8000 /* Enable module */
112 #define SPI_DISABLE 0x0000 /* Disable module */
113 #define SPI_ENBL_DSBL_MASK (~SPI_ENABLE)
114 
115 #define SPI_IDLE_STOP 0x2000 /* Discontinue module operation in idle mode */
116 #define SPI_IDLE_CON 0x0000 /* Continue module operation in idle mode */
117 #define SPI_IDLE_MASK (~SPI_IDLE_STOP)
118 
119 #define SPI_RX_OVFLOW 0x0040
120 #define SPI_RX_OVFLOW_CLR 0x0000 /* Clear receive overflow bit */
121 
122 #define SPI_TX_BUFFER_FULL 0x0002 /* TX not started yet; SPIxTXB is full */
123 #define SPI_TX_BUFFER_FULL_CLR (~SPI_TX_BUFFER_FULL) /* TX underway; SPIxTXB is empty */
124 
125 #define SPI_RX_BUFFER_FULL 0x0001 /* RX complete; SPIxRXB is full */
126 #define SPI_RX_BUFFER_FULL_CLR (~SPI_RX_BUFFER_FULL) /* RX complete; SPIxRXB is full */
127 
128 /* SPIxCON2: SPIx CONTROL REGISTER 2 */
129 #define FRAME_ENABLE_ON 0x8000 /* Frame SPI support enable */
130 #define FRAME_ENABLE_OFF 0x0000 /* Frame SPI support Disable */
131 #define FRAME_ENABLE_MASK (~FRAME_ENABLE_ON)
132 
133 #define FRAME_SYNC_INPUT 0x4000 /* Frame sync pulse Input (slave) */
134 #define FRAME_SYNC_OUTPUT 0x0000 /* Frame sync pulse Output (master)*/
135 #define FRAME_SYNC_MASK (~FRAME_SYNC_INPUT)
136 
137 #define FRAME_SYNC_ACTIVE_HIGH 0x2000 /* Frame sync pulse Input (slave) */
138 #define FRAME_SYNC_ACTIVE_LOW 0x0000 /* Frame sync pulse Output (master)*/
139 #define FRAME_SYNC_POL_MASK (~FRAME_SYNC_ACTIVE_HIGH)
140 
141 #define SPI_FRM_PULSE_FIRST_CLK 0x0002 /* frame pulse coincides with the first bit clock */
142 #define SPI_FRM_PULSE_PREV_CLK 0x0000 /* frame pulse precedes the first bit clock */
143 #define SPI_FRM_PULSE_MASK (~SPI_FRM_PULSE_FIRST_CLK)
144 
145 #define SPI_ENH_BUFF_ENABLE 0x0001 /* enable enhanced buffer */
146 #define SPI_ENH_BUFF_DISABLE 0x0000 /* disable enhanced buffer */
147 #define SPI_ENH_BUFF_MASK (~SPI_ENH_BUFF_ENABLE)
148 
149 
150 /* E X T E R N S ************************************************************/
151 extern struct stTask __stChildTaskSPI;
152 extern uint16_t __esos_spi_u16s[2]; // used to store arguments
153 
154 /* M A C R O S **************************************************************/
155 
156 #define ESOS_TASK_WAIT_ON_AVAILABLE_SPI() \
157  do { \
158  ESOS_TASK_WAIT_WHILE(__esos_IsSystemFlagSet(__ESOS_SYS_SPI_IS_BUSY)); \
159  __esos_SetSystemFlag(__ESOS_SYS_SPI_IS_BUSY); \
160  }while(0)
161 
162 #define ESOS_TASK_SIGNAL_AVAILABLE_SPI() __esos_ClearSystemFlag(__ESOS_SYS_SPI_IS_BUSY)
163 
164 /**
165 Transaction: Write 1 (ONE) "word" stored in variable \em u16_d1 to SPI device.
166 \param u16_d1 Variable containing word (byte or 16-bits) to write
167 \note Assumes SPI peripheral has been properly configured.
168 \note SPI peripheral configuration determines whether 8 or 16 bits are written.
169 \sa ESOS_TASK_WAIT_ON_WRITE2SPI1
170 \sa ESOS_TASK_WAIT_ON_WRITENSPI1
171 \sa ESOS_TASK_WAIT_ON_XFERNSPI1
172 \hideinitializer
173 */
174 #define ESOS_TASK_WAIT_ON_WRITE1SPI1(u16_d1 ) \
175  do{ \
176  __esos_spi_u16s[0] = (uint16_t) (u16_d1); \
177  ESOS_TASK_SPAWN_AND_WAIT( (ESOS_TASK_HANDLE)&__stChildTaskSPI, __esos_pic24_xferNSPI1, &__esos_spi_u16s[0], NULLPTR, 1 ); \
178  }while(0)
179 
180 
181 // We need a 2-byte array to be able to use the buffer.
182 // Otherwise, we'd need two writeN calls, which require
183 // child tasks, i.e. code size grows
184 
185 /**
186 Transaction: Write 2 (TWO) "words" (bytes or 16-bits) stored in variables \em u16_d1 and \em u16_d2 to SPI device.
187 \param u16_d1 Variable containing first byte to write
188 \param u16_d2 Variable containing second byte to write
189 \note Assumes SPI peripheral has been properly configured.
190 \note SPI peripheral configuration determines whether 8 or 16 bits are written.
191 \sa ESOS_TASK_WAIT_ON_WRITE1SPI1
192 \sa ESOS_TASK_WAIT_ON_WRITENSPI1
193 \sa ESOS_TASK_WAIT_ON_XFERNSPI1
194 \hideinitializer
195 */
196 #define ESOS_TASK_WAIT_ON_WRITE2SPI1(u16_d1, u16_d2 ) \
197  do{ \
198  __esos_spi_u16s[0] = (uint16_t) (u16_d1); \
199  __esos_spi_u16s[1] = (uint16_t) (u16_d2); \
200  ESOS_TASK_SPAWN_AND_WAIT( (ESOS_TASK_HANDLE)&__stChildTaskSPI, __esos_pic24_xferNSPI1, &__esos_spi_u16s[0], NULLPTR, 2 ); \
201  }while(0)
202 
203 /**
204 Transaction: Write \em u16_cnt "words" (bytes or 16-bits) to SPI device
205 \param pu16_out Pointer to buffer containing words to send
206 \param u16_cnt Number of bytes to send
207 \note Assumes SPI peripheral has been properly configured.
208 \note SPI peripheral configuration determines whether 8 or 16 bits are written.
209 \sa ESOS_TASK_WAIT_ON_WRITE1SPI1
210 \sa ESOS_TASK_WAIT_ON_WRITE2SPI1
211 \sa ESOS_TASK_WAIT_ON_XFERNSPI1
212 \hideinitializer
213 */
214 #define ESOS_TASK_WAIT_ON_WRITENSPI1( pu16_out, u16_cnt ) \
215  ESOS_TASK_SPAWN_AND_WAIT( (ESOS_TASK_HANDLE)&__stChildTaskSPI, __esos_pic24_xferNSPI1, (pu16_out), NULLPTR, (u16_cnt) )
216 
217 /**
218 Transaction: Transfer (Read and write SPI simultaneously) \em u16_cnt "words" (bytes or 16-bits) to SPI device
219 \param pu16_out Pointer to buffer containing words to send
220 \param pu16_in Pointer to buffer to catch incoming words
221 \param u16_cnt Number of bytes to send
222 \note Assumes SPI peripheral has been properly configured.
223 \note SPI peripheral configuration determines whether 8 or 16 bits are written.
224 \note Assumes that both incoming and outgoing buffers are properly sized and available.
225 \sa ESOS_TASK_WAIT_ON_WRITE1SPI1
226 \sa ESOS_TASK_WAIT_ON_WRITE2SPI1
227 \sa ESOS_TASK_WAIT_ON_WRITENSPI1
228 \sa ESOS_TASK_WAIT_ON_READ1SPI1
229 \sa ESOS_TASK_WAIT_ON_READ2SPI1
230 \sa ESOS_TASK_WAIT_ON_READNSPI1
231 \hideinitializer
232 */
233 #define ESOS_TASK_WAIT_ON_XFERNSPI1( pu16_out, pu16_in, u16_cnt ) \
234  ESOS_TASK_SPAWN_AND_WAIT( (ESOS_TASK_HANDLE)&__stChildTaskSPI, __esos_pic24_xferNSPI1, (pu16_out), (pu16_in), (u16_cnt) )
235 
236 /**
237 Transaction: Read 1 (ONE) "word" from SPI device and stores result in variable \em u16_d1
238 \param u16_d1 Variable containing word (byte or 16-bits) to hold read results
239 \note Assumes SPI peripheral has been properly configured.
240 \note SPI peripheral configuration determines whether 8 or 16 bits are written.
241 \note This routine writes ZEROES to SPI device during reads
242 \sa ESOS_TASK_WAIT_ON_READ2SPI1
243 \sa ESOS_TASK_WAIT_ON_READNSPI1
244 \sa ESOS_TASK_WAIT_ON_XFERNSPI1
245 \hideinitializer
246 */
247 #define ESOS_TASK_WAIT_ON_READ1SPI1(u16_d1 ) \
248  do{ \
249  ESOS_TASK_SPAWN_AND_WAIT( (ESOS_TASK_HANDLE)&__stChildTaskSPI, __esos_pic24_xferNSPI1, NULLPTR, &__esos_spi_u16s[0], 1 ); \
250  (u16_d1) = __esos_spi_u16s[0]; \
251  }while(0)
252 
253 /**
254 Transaction: Read 2 (TWO) "words" (bytes or 16-bits) from SPI device. Stores results in variables \em u16_d1 and \em u16_d2
255 \param u16_d1 Variable containing first word/byte read
256 \param u16_d2 Variable containing second word/byte read
257 \note Assumes SPI peripheral has been properly configured.
258 \note SPI peripheral configuration determines whether 8 or 16 bits are written.
259 \note This routine writes ZEROES to SPI device during reads
260 \sa ESOS_TASK_WAIT_ON_READ1SPI1
261 \sa ESOS_TASK_WAIT_ON_READNSPI1
262 \sa ESOS_TASK_WAIT_ON_XFERNSPI1
263 \hideinitializer
264 */
265 #define ESOS_TASK_WAIT_ON_READ2SPI1(u16_d1, u16_d2) \
266  do{ \
267  ESOS_TASK_SPAWN_AND_WAIT( (ESOS_TASK_HANDLE)&__stChildTaskSPI, __esos_pic24_xferNSPI1, NULLPTR, &__esos_spi_u16s[0], 2 ); \
268  (u16_d1) = __esos_spi_u16s[0]; \
269  (u16_d2) = __esos_spi_u16s[1]; \
270  }while(0)
271 
272 /**
273 Transaction: Reads \em u16_cnt "words" (bytes or 16-bits) from SPI device. Results are written to buffer pointed to by \em pu16_d
274 \param pu16_in Pointer to buffer to catch read results
275 \param u16_cnt Number of bytes to read
276 \note Assumes SPI peripheral has been properly configured.
277 \note SPI peripheral configuration determines whether 8 or 16 bits are written.
278 \note This routine writes ZEROES to SPI device during reads
279 \sa ESOS_TASK_WAIT_ON_READ1SPI1
280 \sa ESOS_TASK_WAIT_ON_READ2SPI1
281 \sa ESOS_TASK_WAIT_ON_XFERNSPI1
282 \hideinitializer
283 */
284 #define ESOS_TASK_WAIT_ON_READNSPI1( pu16_in, u16_cnt ) \
285  ESOS_TASK_SPAWN_AND_WAIT( (ESOS_TASK_HANDLE)&__stChildTaskSPI, __esos_pic24_xferNSPI1, NULLPTR, (pu16_in), (u16_cnt) )
286 
287 
288 /* P U B L I C P R O T O T Y P E S *****************************************/
289 ESOS_CHILD_TASK( __esos_pic24_xferNSPI1, uint16_t* pu16_out, uint16_t* pu16_in, uint16_t u16_cnt);
290 
291 /** @} */
292 #endif // end ESOS_PIC24_SPI_H
#define ESOS_CHILD_TASK(taskname,...)
Definition: esos_task.h:247
This is the master include file for implementing ESOS on Microchip PIC24 MCUs.