PIC24 Support Libraries
esos_pic24_i2c.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_I2C_H
32 #define _ESOS_PIC24_I2C_H
33 
34 
35 /**
36  * \addtogroup ESOS_I2C_Service
37  * @{
38  */
39 
40 // Documentation for this file. If the \file tag isn't present,
41 // this file won't be documented.
42 /** \file
43  * \brief This file contains routines which configure and
44  * use I<sup>2</sup>C on the Microchip PIC24 MCUs.
45  */
46 
47 
48 /* I N C L U D E S **********************************************************/
49 #include "esos.h"
50 #include "esos_pic24.h"
51 
52 
53 /* D E F I N I T I O N S ****************************************************/
54 #ifndef I2C_ACK
55 #define I2C_ACK 0
56 #endif
57 #ifndef I2C_NAK
58 #define I2C_NAK 1
59 #endif
60 
61 /* E X T E R N S ************************************************************/
62 extern struct stTask __stChildTaskI2C, __stGrandChildTaskI2C;
63 extern uint8_t __esos_i2c_dataBytes[2]; // used to store arguments
64 
65 /* M A C R O S **************************************************************/
66 #define I2C_WADDR(x) (x & 0xFE) //clear R/W bit of I2C addr
67 #define I2C_RADDR(x) (x | 0x01) //set R/W bit of I2C addr
68 
69 #define ESOS_TASK_WAIT_ON_AVAILABLE_I2C() \
70  do { \
71  ESOS_TASK_WAIT_WHILE(__esos_IsSystemFlagSet(__ESOS_SYS_I2C_IS_BUSY)); \
72  __esos_SetSystemFlag(__ESOS_SYS_I2C_IS_BUSY); \
73  } while(0)
74 
75 #define ESOS_TASK_SIGNAL_AVAILABLE_I2C() __esos_ClearSystemFlag(__ESOS_SYS_I2C_IS_BUSY)
76 
77 // Macros to perform I2C operations within a child task
78 #define __PIC24_I2C1_START() \
79  do{ \
80  I2C1CONbits.SEN = 1; \
81  ESOS_TASK_WAIT_WHILE( I2C1CONbits.SEN); \
82  }while(0)
83 
84 #define __PIC24_I2C1_RSTART() \
85  do{ \
86  I2C1CONbits.RSEN = 1; \
87  ESOS_TASK_WAIT_WHILE( I2C1CONbits.RSEN); \
88  }while(0)
89 
90 #define __PIC24_I2C1_STOP() \
91  do{ \
92  I2C1CONbits.PEN = 1; \
93  ESOS_TASK_WAIT_WHILE( I2C1CONbits.PEN); \
94  }while(0)
95 
96 #define __PIC24_I2C1_PUT(byte) \
97  do{ \
98  I2C1TRN = (byte); \
99  ESOS_TASK_WAIT_WHILE( I2C1STATbits.TRSTAT); \
100  }while(0)
101 
102 #define ESOS_TASK_WAIT_ON_GETI2C1( pu8_get, u8_ack2Send ) \
103  ESOS_TASK_SPAWN_AND_WAIT( (ESOS_TASK_HANDLE)&__stGrandChildTaskI2C, __esos_pic24_getI2C1, (pu8_get), (u8_ack2Send) )
104 
105 // Must copy value to a var, send &var, just in case u8_d1 is a literal
106 /**
107 Transaction: Write 1 (ONE) byte stored in variable \em u8_d1 to I2C slave at address \em u8_addr.
108 \param u8_addr Slave I2C address
109 \param u8_d1 Variable containing first byte to write
110 \sa ESOS_TASK_WAIT_ON_WRITE2I2C1
111 \sa ESOS_TASK_WAIT_ON_WRITENI2C1
112 \sa esos_pic24_configI2C1
113 \hideinitializer
114 */
115 #define ESOS_TASK_WAIT_ON_WRITE1I2C1( u8_addr, u8_d1 ) \
116  do{ \
117  __esos_i2c_dataBytes[0] = (u8_d1); \
118  ESOS_TASK_SPAWN_AND_WAIT( (ESOS_TASK_HANDLE)&__stChildTaskI2C, __esos_pic24_writeNI2C1, (u8_addr), &__esos_i2c_dataBytes[0], 1 ); \
119  }while(0)
120 
121 // We needed a 2-byte array to be able to use the buffer.
122 // Otherwise, we'd need two writeN calls, which require
123 // child tasks, i.e. code size grows
124 
125 /**
126 Transaction: Write 2 (TWO) bytes stored in variables \em u8_d1 and \em u8_d2 to I2C slave at address \em u8_addr.
127 \param u8_addr Slave I2C address
128 \param u8_d1 Variable containing first byte to write
129 \param u8_d2 Variable containing second byte to write
130 \sa ESOS_TASK_WAIT_ON_WRITE1I2C1
131 \sa ESOS_TASK_WAIT_ON_WRITENI2C1
132 \hideinitializer
133 */
134 #define ESOS_TASK_WAIT_ON_WRITE2I2C1( u8_addr, u8_d1, u8_d2 ) \
135  do{ \
136  __esos_i2c_dataBytes[0] = (u8_d1); \
137  __esos_i2c_dataBytes[1] = (u8_d2); \
138  ESOS_TASK_SPAWN_AND_WAIT( (ESOS_TASK_HANDLE)&__stChildTaskI2C, __esos_pic24_writeNI2C1, (u8_addr), &__esos_i2c_dataBytes[0], 2 ); \
139  }while(0)
140 
141 /**
142 Transaction: Write \em u16_cnt bytes stored in buffer \em *pu8_d to I2C slave at address \em u8_addr.
143 \param u8_addr Slave I2C address
144 \param pu8_d Pointer to buffer containing bytes to send
145 \param u16_cnt Number of bytes to send
146 \sa ESOS_TASK_WAIT_ON_WRITE1I2C1
147 \sa ESOS_TASK_WAIT_ON_WRITE2I2C1
148 \hideinitializer
149 */
150 #define ESOS_TASK_WAIT_ON_WRITENI2C1( u8_addr, pu8_d, u16_cnt ) \
151  ESOS_TASK_SPAWN_AND_WAIT( (ESOS_TASK_HANDLE)&__stChildTaskI2C, __esos_pic24_writeNI2C1, (u8_addr), (pu8_d), (u16_cnt) )
152 
153 /**
154 Transaction: Read 1 (ONE) byte from I2C slave at address \em u8_addr, and save to variable \em u8_d1
155 As per the I2C standard, a NAK is returned for the last byte read from the slave, ACKs are returned for the other bytes.
156 \param u8_addr Slave I2C address
157 \param u8_d1 variable to hold the read byte
158 \hideinitializer
159 \sa ESOS_TASK_WAIT_ON_READ2I2C1
160 \sa ESOS_TASK_WAIT_ON_READNI2C1
161 \sa esos_pic24_configI2C1
162 */
163 #define ESOS_TASK_WAIT_ON_READ1I2C1( u8_addr, u8_d1 ) \
164  ESOS_TASK_SPAWN_AND_WAIT( (ESOS_TASK_HANDLE)&__stChildTaskI2C, __esos_pic24_readNI2C1, (u8_addr), &(u8_d1), 1 )
165 
166 // While READ1 still worked fine, READ2 needs a new trick, since u8_d1 and u8_d2 are
167 // not in consecutive memory locations. Can't do two READN calls, because that (again)
168 // requires another child task. Instead, just re-use our 2-byte array as a read buffer
169 
170 /**
171 Transaction: Read 2 (TWO) bytes from I2C slave at address \em u8_addr, save to variables \em u8_d1 and \em u8_d2
172 As per the I2C standard, a NAK is returned for the last byte read from the slave, ACKs are returned for the other bytes.
173 \param u8_addr Slave I2C address
174 \param u8_d1 variable to hold first read byte
175 \param u8_d2 variable to hold second read byte
176 \hideinitializer
177 \sa ESOS_TASK_WAIT_ON_READ1I2C1
178 \sa ESOS_TASK_WAIT_ON_READNI2C1
179 \sa esos_pic24_configI2C1
180 */
181 #define ESOS_TASK_WAIT_ON_READ2I2C1( u8_addr, u8_d1, u8_d2 ) \
182  do{ \
183  ESOS_TASK_SPAWN_AND_WAIT( (ESOS_TASK_HANDLE)&__stChildTaskI2C, __esos_pic24_readNI2C1, (u8_addr), &__esos_i2c_dataBytes[0], 2 ); \
184  (u8_d1) = __esos_i2c_dataBytes[0]; \
185  (u8_d2) = __esos_i2c_dataBytes[1]; \
186  }while(0)
187 
188 /**
189 Transaction: Read \em u16_cnt bytes from I2C slave at address \em u8_addr, save to buffer \em *pu8_d.
190 As per the I2C standard, a NAK is returned for the last byte read from the slave, ACKs are returned for the other bytes.
191 \param u8_addr Slave I2C address
192 \param pu8_d Pointer to buffer for storing bytes read from slave
193 \param u16_cnt Number of bytes read from slave.
194 \hideinitializer
195 \sa ESOS_TASK_WAIT_ON_READ1I2C1
196 \sa ESOS_TASK_WAIT_ON_READ2I2C1
197 \sa esos_pic24_configI2C1
198 */
199 #define ESOS_TASK_WAIT_ON_READNI2C1( u8_addr, pu8_d, u16_cnt ) \
200  ESOS_TASK_SPAWN_AND_WAIT( (ESOS_TASK_HANDLE)&__stChildTaskI2C, __esos_pic24_readNI2C1, (u8_addr), (pu8_d), (u16_cnt) )
201 
202 
203 /* P U B L I C P R O T O T Y P E S *****************************************/
204 
205 //I2C Operations
206 void esos_pic24_configI2C1(uint16_t u16_FkHZ);
207 
208 //I2C Transactions
209 ESOS_CHILD_TASK( __esos_pic24_getI2C1, uint8_t* pu8_x, uint8_t u8_ack2Send);
210 ESOS_CHILD_TASK( __esos_pic24_writeNI2C1, uint8_t u8_addr, uint8_t* pu8_d, uint16_t u16_cnt);
211 ESOS_CHILD_TASK( __esos_pic24_readNI2C1, uint8_t u8_addr, uint8_t* pu8_d, uint16_t u16_cnt);
212 
213 /** @} */
214 #endif // end ESOS_PIC24_I2C_H
void esos_pic24_configI2C1(uint16_t u16_FkHZ)
This is the master include file for implementing ESOS on Microchip PIC24 MCUs.
ESOS_CHILD_TASK(__esos_pic24_writeNI2C1, uint8_t u8_addr, uint8_t *pu8_d, uint16_t u16_cnt)
unsigned char uint8_t
An abbreviation for an 8-bit unsigned integer.
Definition: dataXferImpl.h:194