PIC24 Support Libraries
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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 __esos_spi_u16s[2]; // used to store arguments
153 
154 /* M A C R O S **************************************************************/
155 /**
156 Transaction: Write 1 (ONE) "word" stored in variable \em u16_d1 to SPI device.
157 \param u16_d1 Variable containing word (byte or 16-bits) to write
158 \note Assumes SPI peripheral has been properly configured.
159 \note SPI peripheral configuration determines whether 8 or 16 bits are written.
160 \sa ESOS_TASK_WAIT_ON_WRITE2SPI1
161 \sa ESOS_TASK_WAIT_ON_WRITENSPI1
162 \sa ESOS_TASK_WAIT_ON_XFERNSPI1
163 \hideinitializer
164 */
165 #define ESOS_TASK_WAIT_ON_WRITE1SPI1(u16_d1 ) \
166  do{ \
167  __esos_spi_u16s[0] = (uint16) (u16_d1); \
168  ESOS_TASK_SPAWN_AND_WAIT( (ESOS_TASK_HANDLE)&__stChildTaskSPI, __esos_pic24_xferNSPI1, &__esos_spi_u16s[0], NULLPTR, 1 ); \
169  }while(0)
170 
171 
172 // We need a 2-byte array to be able to use the buffer.
173 // Otherwise, we'd need two writeN calls, which require
174 // child tasks, i.e. code size grows
175 
176 /**
177 Transaction: Write 2 (TWO) "words" (bytes or 16-bits) stored in variables \em u16_d1 and \em u16_d2 to SPI device.
178 \param u16_d1 Variable containing first byte to write
179 \param u16_d2 Variable containing second byte to write
180 \note Assumes SPI peripheral has been properly configured.
181 \note SPI peripheral configuration determines whether 8 or 16 bits are written.
182 \sa ESOS_TASK_WAIT_ON_WRITE1SPI1
183 \sa ESOS_TASK_WAIT_ON_WRITENSPI1
184 \sa ESOS_TASK_WAIT_ON_XFERNSPI1
185 \hideinitializer
186 */
187 #define ESOS_TASK_WAIT_ON_WRITE2SPI1(u16_d1, u16_d2 ) \
188  do{ \
189  __esos_spi_u16s[0] = (uint16) (u16_d1); \
190  __esos_spi_u16s[1] = (uint16) (u16_d2); \
191  ESOS_TASK_SPAWN_AND_WAIT( (ESOS_TASK_HANDLE)&__stChildTaskSPI, __esos_pic24_xferNSPI1, &__esos_spi_u16s[0], NULLPTR, 2 ); \
192  }while(0)
193 
194 /**
195 Transaction: Write \em u16_cnt "words" (bytes or 16-bits) to SPI device
196 \param pu16_out Pointer to buffer containing words to send
197 \param u16_cnt Number of bytes to send
198 \note Assumes SPI peripheral has been properly configured.
199 \note SPI peripheral configuration determines whether 8 or 16 bits are written.
200 \sa ESOS_TASK_WAIT_ON_WRITE1SPI1
201 \sa ESOS_TASK_WAIT_ON_WRITE2SPI1
202 \sa ESOS_TASK_WAIT_ON_XFERNSPI1
203 \hideinitializer
204 */
205 #define ESOS_TASK_WAIT_ON_WRITENSPI1( pu16_out, u16_cnt ) \
206  ESOS_TASK_SPAWN_AND_WAIT( (ESOS_TASK_HANDLE)&__stChildTaskSPI, __esos_pic24_xferNSPI1, (pu16_out), NULLPTR, (u16_cnt) )
207 
208 /**
209 Transaction: Transfer (Read and write SPI simultaneously) \em u16_cnt "words" (bytes or 16-bits) to SPI device
210 \param pu16_out Pointer to buffer containing words to send
211 \param pu16_in Pointer to buffer to catch incoming words
212 \param u16_cnt Number of bytes to send
213 \note Assumes SPI peripheral has been properly configured.
214 \note SPI peripheral configuration determines whether 8 or 16 bits are written.
215 \note Assumes that both incoming and outgoing buffers are properly sized and available.
216 \sa ESOS_TASK_WAIT_ON_WRITE1SPI1
217 \sa ESOS_TASK_WAIT_ON_WRITE2SPI1
218 \sa ESOS_TASK_WAIT_ON_WRITENSPI1
219 \sa ESOS_TASK_WAIT_ON_READ1SPI1
220 \sa ESOS_TASK_WAIT_ON_READ2SPI1
221 \sa ESOS_TASK_WAIT_ON_READNSPI1
222 \hideinitializer
223 */
224 #define ESOS_TASK_WAIT_ON_XFERNSPI1( pu16_out, pu16_in, u16_cnt ) \
225  ESOS_TASK_SPAWN_AND_WAIT( (ESOS_TASK_HANDLE)&__stChildTaskSPI, __esos_pic24_xferNSPI1, (pu16_out), (pu16_in), (u16_cnt) )
226 
227 /**
228 Transaction: Read 1 (ONE) "word" from SPI device and stores result in variable \em u16_d1
229 \param u16_d1 Variable containing word (byte or 16-bits) to hold read results
230 \note Assumes SPI peripheral has been properly configured.
231 \note SPI peripheral configuration determines whether 8 or 16 bits are written.
232 \note This routine writes ZEROES to SPI device during reads
233 \sa ESOS_TASK_WAIT_ON_READ2SPI1
234 \sa ESOS_TASK_WAIT_ON_READNSPI1
235 \sa ESOS_TASK_WAIT_ON_XFERNSPI1
236 \hideinitializer
237 */
238 #define ESOS_TASK_WAIT_ON_READ1SPI1(u16_d1 ) \
239  do{ \
240  ESOS_TASK_SPAWN_AND_WAIT( (ESOS_TASK_HANDLE)&__stChildTaskSPI, __esos_pic24_xferNSPI1, NULLPTR, &__esos_spi_u16s[0], 1 ); \
241  (u16_d1) = __esos_spi_u16s[0]; \
242  }while(0)
243 
244 /**
245 Transaction: Read 2 (TWO) "words" (bytes or 16-bits) from SPI device. Stores results in variables \em u16_d1 and \em u16_d2
246 \param u16_d1 Variable containing first word/byte read
247 \param u16_d2 Variable containing second word/byte read
248 \note Assumes SPI peripheral has been properly configured.
249 \note SPI peripheral configuration determines whether 8 or 16 bits are written.
250 \note This routine writes ZEROES to SPI device during reads
251 \sa ESOS_TASK_WAIT_ON_READ1SPI1
252 \sa ESOS_TASK_WAIT_ON_READNSPI1
253 \sa ESOS_TASK_WAIT_ON_XFERNSPI1
254 \hideinitializer
255 */
256 #define ESOS_TASK_WAIT_ON_READ2SPI1(u16_d1, u16_d2) \
257  do{ \
258  ESOS_TASK_SPAWN_AND_WAIT( (ESOS_TASK_HANDLE)&__stChildTaskSPI, __esos_pic24_xferNSPI1, NULLPTR, &__esos_spi_u16s[0], 2 ); \
259  (u16_d1) = __esos_spi_u16s[0]; \
260  (u16_d2) = __esos_spi_u16s[1]; \
261  }while(0)
262 
263 /**
264 Transaction: Reads \em u16_cnt "words" (bytes or 16-bits) from SPI device. Results are written to buffer pointed to by \em pu16_d
265 \param pu16_in Pointer to buffer to catch read results
266 \param u16_cnt Number of bytes to read
267 \note Assumes SPI peripheral has been properly configured.
268 \note SPI peripheral configuration determines whether 8 or 16 bits are written.
269 \note This routine writes ZEROES to SPI device during reads
270 \sa ESOS_TASK_WAIT_ON_READ1SPI1
271 \sa ESOS_TASK_WAIT_ON_READ2SPI1
272 \sa ESOS_TASK_WAIT_ON_XFERNSPI1
273 \hideinitializer
274 */
275 #define ESOS_TASK_WAIT_ON_READNSPI1( pu16_in, u16_cnt ) \
276  ESOS_TASK_SPAWN_AND_WAIT( (ESOS_TASK_HANDLE)&__stChildTaskSPI, __esos_pic24_xferNSPI1, NULLPTR, (pu16_in), (u16_cnt) )
277 
278 
279 /* P U B L I C P R O T O T Y P E S *****************************************/
280 ESOS_CHILD_TASK( __esos_pic24_xferNSPI1, uint16* pu16_out, uint16* pu16_in, uint16 u16_cnt);
281 
282 /** @} */
283 #endif // end ESOS_PIC24_SPI_H