PIC24 Support Libraries
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
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 __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 // Macros to perform I2C operations within a child task
70 #define __PIC24_I2C1_START() \
71  do{ \
72  I2C1CONbits.SEN = 1; \
73  ESOS_TASK_WAIT_WHILE( I2C1CONbits.SEN); \
74  }while(0)
75 
76 #define __PIC24_I2C1_RSTART() \
77  do{ \
78  I2C1CONbits.RSEN = 1; \
79  ESOS_TASK_WAIT_WHILE( I2C1CONbits.RSEN); \
80  }while(0)
81 
82 #define __PIC24_I2C1_STOP() \
83  do{ \
84  I2C1CONbits.PEN = 1; \
85  ESOS_TASK_WAIT_WHILE( I2C1CONbits.PEN); \
86  }while(0)
87 
88 #define __PIC24_I2C1_PUT(byte) \
89  do{ \
90  I2C1TRN = (byte); \
91  ESOS_TASK_WAIT_WHILE( I2C1STATbits.TRSTAT); \
92  }while(0)
93 
94 #define ESOS_TASK_WAIT_ON_GETI2C1( pu8_get, u8_ack2Send ) \
95  ESOS_TASK_SPAWN_AND_WAIT( (ESOS_TASK_HANDLE)&__stGrandChildTaskI2C, __esos_pic24_getI2C1, (pu8_get), (u8_ack2Send) )
96 
97 // Must copy value to a var, send &var, just in case u8_d1 is a literal
98 /**
99 Transaction: Write 1 (ONE) byte stored in variable \em u8_d1 to I2C slave at address \em u8_addr.
100 \param u8_addr Slave I2C address
101 \param u8_d1 Variable containing first byte to write
102 \sa ESOS_TASK_WAIT_ON_WRITE2I2C1
103 \sa ESOS_TASK_WAIT_ON_WRITENI2C1
104 \sa esos_pic24_configI2C1
105 \hideinitializer
106 */
107 #define ESOS_TASK_WAIT_ON_WRITE1I2C1( u8_addr, u8_d1 ) \
108  do{ \
109  __esos_i2c_dataBytes[0] = (u8_d1); \
110  ESOS_TASK_SPAWN_AND_WAIT( (ESOS_TASK_HANDLE)&__stChildTaskI2C, __esos_pic24_writeNI2C1, (u8_addr), &__esos_i2c_dataBytes[0], 1 ); \
111  }while(0)
112 
113 // We needed a 2-byte array to be able to use the buffer.
114 // Otherwise, we'd need two writeN calls, which require
115 // child tasks, i.e. code size grows
116 
117 /**
118 Transaction: Write 2 (TWO) bytes stored in variables \em u8_d1 and \em u8_d2 to I2C slave at address \em u8_addr.
119 \param u8_addr Slave I2C address
120 \param u8_d1 Variable containing first byte to write
121 \param u8_d2 Variable containing second byte to write
122 \sa ESOS_TASK_WAIT_ON_WRITE1I2C1
123 \sa ESOS_TASK_WAIT_ON_WRITENI2C1
124 \hideinitializer
125 */
126 #define ESOS_TASK_WAIT_ON_WRITE2I2C1( u8_addr, u8_d1, u8_d2 ) \
127  do{ \
128  __esos_i2c_dataBytes[0] = (u8_d1); \
129  __esos_i2c_dataBytes[1] = (u8_d2); \
130  ESOS_TASK_SPAWN_AND_WAIT( (ESOS_TASK_HANDLE)&__stChildTaskI2C, __esos_pic24_writeNI2C1, (u8_addr), &__esos_i2c_dataBytes[0], 2 ); \
131  }while(0)
132 
133 /**
134 Transaction: Write \em u16_cnt bytes stored in buffer \em *pu8_d to I2C slave at address \em u8_addr.
135 \param u8_addr Slave I2C address
136 \param pu8_d Pointer to buffer containing bytes to send
137 \param u16_cnt Number of bytes to send
138 \sa ESOS_TASK_WAIT_ON_WRITE1I2C1
139 \sa ESOS_TASK_WAIT_ON_WRITE2I2C1
140 \hideinitializer
141 */
142 #define ESOS_TASK_WAIT_ON_WRITENI2C1( u8_addr, pu8_d, u16_cnt ) \
143  ESOS_TASK_SPAWN_AND_WAIT( (ESOS_TASK_HANDLE)&__stChildTaskI2C, __esos_pic24_writeNI2C1, (u8_addr), (pu8_d), (u16_cnt) )
144 
145 /**
146 Transaction: Read 1 (ONE) byte from I2C slave at address \em u8_addr, and save to variable \em u8_d1
147 As per the I2C standard, a NAK is returned for the last byte read from the slave, ACKs are returned for the other bytes.
148 \param u8_addr Slave I2C address
149 \param u8_d1 variable to hold the read byte
150 \hideinitializer
151 \sa ESOS_TASK_WAIT_ON_READ2I2C1
152 \sa ESOS_TASK_WAIT_ON_READNI2C1
153 \sa esos_pic24_configI2C1
154 */
155 #define ESOS_TASK_WAIT_ON_READ1I2C1( u8_addr, u8_d1 ) \
156  ESOS_TASK_SPAWN_AND_WAIT( (ESOS_TASK_HANDLE)&__stChildTaskI2C, __esos_pic24_readNI2C1, (u8_addr), &(u8_d1), 1 )
157 
158 // While READ1 still worked fine, READ2 needs a new trick, since u8_d1 and u8_d2 are
159 // not in consecutive memory locations. Can't do two READN calls, because that (again)
160 // requires another child task. Instead, just re-use our 2-byte array as a read buffer
161 
162 /**
163 Transaction: Read 2 (TWO) bytes from I2C slave at address \em u8_addr, save to variables \em u8_d1 and \em u8_d2
164 As per the I2C standard, a NAK is returned for the last byte read from the slave, ACKs are returned for the other bytes.
165 \param u8_addr Slave I2C address
166 \param u8_d1 variable to hold first read byte
167 \param u8_d2 variable to hold second read byte
168 \hideinitializer
169 \sa ESOS_TASK_WAIT_ON_READ1I2C1
170 \sa ESOS_TASK_WAIT_ON_READNI2C1
171 \sa esos_pic24_configI2C1
172 */
173 #define ESOS_TASK_WAIT_ON_READ2I2C1( u8_addr, u8_d1, u8_d2 ) \
174  do{ \
175  ESOS_TASK_SPAWN_AND_WAIT( (ESOS_TASK_HANDLE)&__stChildTaskI2C, __esos_pic24_readNI2C1, (u8_addr), &__esos_i2c_dataBytes[0], 2 ); \
176  (u8_d1) = __esos_i2c_dataBytes[0]; \
177  (u8_d2) = __esos_i2c_dataBytes[1]; \
178  }while(0)
179 
180 /**
181 Transaction: Read \em u16_cnt bytes from I2C slave at address \em u8_addr, save to buffer \em *pu8_d.
182 As per the I2C standard, a NAK is returned for the last byte read from the slave, ACKs are returned for the other bytes.
183 \param u8_addr Slave I2C address
184 \param pu8_d Pointer to buffer for storing bytes read from slave
185 \param u16_cnt Number of bytes read from slave.
186 \hideinitializer
187 \sa ESOS_TASK_WAIT_ON_READ1I2C1
188 \sa ESOS_TASK_WAIT_ON_READ2I2C1
189 \sa esos_pic24_configI2C1
190 */
191 #define ESOS_TASK_WAIT_ON_READNI2C1( u8_addr, pu8_d, u16_cnt ) \
192  ESOS_TASK_SPAWN_AND_WAIT( (ESOS_TASK_HANDLE)&__stChildTaskI2C, __esos_pic24_readNI2C1, (u8_addr), (pu8_d), (u16_cnt) )
193 
194 
195 /* P U B L I C P R O T O T Y P E S *****************************************/
196 
197 //I2C Operations
198 void esos_pic24_configI2C1(uint16 u16_FkHZ);
199 
200 //I2C Transactions
201 ESOS_CHILD_TASK( __esos_pic24_getI2C1, uint8* pu8_x, uint8 u8_ack2Send);
202 ESOS_CHILD_TASK( __esos_pic24_writeNI2C1, uint8 u8_addr, uint8* pu8_d, uint16 u16_cnt);
203 ESOS_CHILD_TASK( __esos_pic24_readNI2C1, uint8 u8_addr, uint8* pu8_d, uint16 u16_cnt);
204 
205 /** @} */
206 #endif // end ESOS_PIC24_I2C_H