]> git.sur5r.net Git - freertos/blob
a594d50b7d7c96eb5a237bd17e940349a1a87719
[freertos] /
1 /*\r
2  * @brief LPC18xx/43xx I2C driver\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 __I2C_18XX_43XX_H_\r
33 #define __I2C_18XX_43XX_H_\r
34 \r
35 #ifdef __cplusplus\r
36 extern "C" {\r
37 #endif\r
38 \r
39 /** @defgroup I2C_18XX_43XX CHIP: LPC18xx/43xx I2C Driver\r
40  * @ingroup CHIP_18XX_43XX_Drivers\r
41  * @{\r
42  */\r
43 \r
44 /**\r
45  * @brief       I2C interface IDs\r
46  * @note\r
47  * All Chip functions will take this as the first parameter,\r
48  * I2C_NUM_INTERFACE must never be used for calling any Chip\r
49  * functions, it is only used to find the number of interfaces\r
50  * available in the Chip.\r
51  */\r
52 typedef enum I2C_ID {\r
53         I2C0,                           /**< ID I2C0 */\r
54         I2C1,                           /**< ID I2C1 */\r
55         I2C_NUM_INTERFACE       /**< Number of I2C interfaces in the chip */\r
56 } I2C_ID_T;\r
57 \r
58 /**\r
59  * @brief       I2C master events\r
60  */\r
61 typedef enum {\r
62         I2C_EVENT_WAIT = 1,     /**< I2C Wait event */\r
63         I2C_EVENT_DONE,         /**< Done event that wakes up Wait event */\r
64         I2C_EVENT_LOCK,         /**< Re-entrency lock event for I2C transfer */\r
65         I2C_EVENT_UNLOCK,       /**< Re-entrency unlock event for I2C transfer */\r
66         I2C_EVENT_SLAVE_RX,     /**< Slave receive event */\r
67         I2C_EVENT_SLAVE_TX,     /**< Slave transmit event */\r
68 } I2C_EVENT_T;\r
69 \r
70 /**\r
71  * @brief       Event handler function type\r
72  */\r
73 typedef void (*I2C_EVENTHANDLER_T)(I2C_ID_T, I2C_EVENT_T);\r
74 \r
75 /**\r
76  * @brief       Initializes the LPC_I2C peripheral with specified parameter.\r
77  * @param       id                      : I2C peripheral ID (I2C0, I2C1 ... etc)\r
78  * @return      Nothing\r
79  */\r
80 void Chip_I2C_Init(I2C_ID_T id);\r
81 \r
82 /**\r
83  * @brief       De-initializes the I2C peripheral registers to their default reset values\r
84  * @param       id                      : I2C peripheral ID (I2C0, I2C1 ... etc)\r
85  * @return      Nothing\r
86  */\r
87 void Chip_I2C_DeInit(I2C_ID_T id);\r
88 \r
89 /**\r
90  * @brief       Set up clock rate for LPC_I2C peripheral.\r
91  * @param       id                      : I2C peripheral ID (I2C0, I2C1 ... etc)\r
92  * @param       clockrate       : Target clock rate value to initialized I2C peripheral (Hz)\r
93  * @return      Nothing\r
94  * @note\r
95  * Parameter @a clockrate for I2C0 should be from 1000 up to 1000000\r
96  * (1 KHz to 1 MHz), as I2C0 support Fast Mode Plus. I2C1 @a clockrate\r
97  * should be within the range of 1000 to 400000 (1 KHz to 400 KHz). If\r
98  * the frequency is above 400KHz (Fast Plus Mode) Board_I2C_EnableFastPlus()\r
99  * must be called prior to calling this function (Only I2C0 supports frequency\r
100  * above 400 KHz).\r
101  */\r
102 void Chip_I2C_SetClockRate(I2C_ID_T id, uint32_t clockrate);\r
103 \r
104 /**\r
105  * @brief       Get current clock rate for LPC_I2C peripheral.\r
106  * @param       id                      : I2C peripheral ID (I2C0, I2C1 ... etc)\r
107  * @return      The current I2C peripheral clock rate\r
108  */\r
109 uint32_t Chip_I2C_GetClockRate(I2C_ID_T id);\r
110 \r
111 /**\r
112  * @brief       Transmit and Receive data in master mode\r
113  * @param       id              : I2C peripheral selected (I2C0, I2C1 etc)\r
114  * @param       xfer    : Pointer to a I2C_XFER_T structure see notes below\r
115  * @return\r
116  * Any of #I2C_STATUS_T values, xfer->txSz will have number of bytes\r
117  * not sent due to error, xfer->rxSz will have the number of bytes yet\r
118  * to be received.\r
119  * @note\r
120  * The parameter @a xfer should have its member @a slaveAddr initialized\r
121  * to the 7-Bit slave address to which the master will do the xfer, Bit0\r
122  * to bit6 should have the address and Bit8 is ignored. During the transfer\r
123  * no code (like event handler) must change the content of the memory\r
124  * pointed to by @a xfer. The member of @a xfer, @a txBuff and @a txSz be\r
125  * initialized to the memory from which the I2C must pick the data to be\r
126  * transfered to slave and the number of bytes to send respectively, similarly\r
127  * @a rxBuff and @a rxSz must have pointer to memroy where data received\r
128  * from slave be stored and the number of data to get from slave respectilvely.\r
129  */\r
130 int Chip_I2C_MasterTransfer(I2C_ID_T id, I2C_XFER_T *xfer);\r
131 \r
132 /**\r
133  * @brief       Transmit data to I2C slave using I2C Master mode\r
134  * @param       id                      : I2C peripheral ID (I2C0, I2C1 .. etc)\r
135  * @param       slaveAddr       : Slave address to which the data be written\r
136  * @param       buff            : Pointer to buffer having the array of data\r
137  * @param       len                     : Number of bytes to be transfered from @a buff\r
138  * @return      Number of bytes successfully transfered\r
139  */\r
140 int Chip_I2C_MasterSend(I2C_ID_T id, uint8_t slaveAddr, const uint8_t *buff, uint8_t len);\r
141 \r
142 /**\r
143  * @brief       Transfer a command to slave and receive data from slave after a repeated start\r
144  * @param       id                      : I2C peripheral ID (I2C0, I2C1 ... etc)\r
145  * @param       slaveAddr       : Slave address of the I2C device\r
146  * @param       cmd                     : Command (Address/Register) to be written\r
147  * @param       buff            : Pointer to memory that will hold the data received\r
148  * @param       len                     : Number of bytes to receive\r
149  * @return      Number of bytes successfully received\r
150  */\r
151 int Chip_I2C_MasterCmdRead(I2C_ID_T id, uint8_t slaveAddr, uint8_t cmd, uint8_t *buff, int len);\r
152 \r
153 /**\r
154  * @brief       Get pointer to current function handling the events\r
155  * @param       id                      : I2C peripheral ID (I2C0, I2C1 ... etc)\r
156  * @return      Pointer to function handing events of I2C\r
157  */\r
158 I2C_EVENTHANDLER_T Chip_I2C_GetMasterEventHandler(I2C_ID_T id);\r
159 \r
160 /**\r
161  * @brief       Set function that must handle I2C events\r
162  * @param       id                      : I2C peripheral ID (I2C0, I2C1 ... etc)\r
163  * @param       event           : Pointer to function that will handle the event\r
164  *                                                (Should not be NULL)\r
165  * @return      1 when successful, 0 when a transfer is on going with its own event handler\r
166  */\r
167 int Chip_I2C_SetMasterEventHandler(I2C_ID_T id, I2C_EVENTHANDLER_T event);\r
168 \r
169 /**\r
170  * @brief       Set function that must handle I2C events\r
171  * @param       id                      : I2C peripheral ID (I2C0, I2C1 ... etc)\r
172  * @param       slaveAddr       : Slave address from which data be read\r
173  * @param       buff            : Pointer to memory where data read be stored\r
174  * @param       len                     : Number of bytes to read from slave\r
175  * @return      Number of bytes read successfully\r
176  */\r
177 int Chip_I2C_MasterRead(I2C_ID_T id, uint8_t slaveAddr, uint8_t *buff, int len);\r
178 \r
179 /**\r
180  * @brief       Default event handler for polling operation\r
181  * @param       id              : I2C peripheral ID (I2C0, I2C1 ... etc)\r
182  * @param       event   : Event ID of the event that called the function\r
183  * @return      Nothing\r
184  */\r
185 void Chip_I2C_EventHandlerPolling(I2C_ID_T id, I2C_EVENT_T event);\r
186 \r
187 /**\r
188  * @brief       Default event handler for interrupt base operation\r
189  * @param       id              : I2C peripheral ID (I2C0, I2C1 ... etc)\r
190  * @param       event   : Event ID of the event that called the function\r
191  * @return      Nothing\r
192  */\r
193 void Chip_I2C_EventHandler(I2C_ID_T id, I2C_EVENT_T event);\r
194 \r
195 /**\r
196  * @brief       I2C Master transfer state change handler\r
197  * @param       id              : I2C peripheral ID (I2C0, I2C1 ... etc)\r
198  * @return      Nothing\r
199  * @note        Usually called from the appropriate Interrupt handler\r
200  */\r
201 void Chip_I2C_MasterStateHandler(I2C_ID_T id);\r
202 \r
203 /**\r
204  * @brief       Disable I2C peripheral's operation\r
205  * @param       id                      : I2C peripheral ID (I2C0, I2C1 ... etc)\r
206  * @return      Nothing\r
207  */\r
208 void Chip_I2C_Disable(I2C_ID_T id);\r
209 \r
210 /**\r
211  * @brief       Checks if master xfer in progress\r
212  * @param       id              : I2C peripheral ID (I2C0, I2C1 ... etc)\r
213  * @return      1 if master xfer in progress 0 otherwise\r
214  * @note\r
215  * This API is generally used in interrupt handler\r
216  * of the application to decide whether to call\r
217  * master state handler or to call slave state handler\r
218  */\r
219 int Chip_I2C_IsMasterActive(I2C_ID_T id);\r
220 \r
221 /**\r
222  * @brief       Setup a slave I2C device\r
223  * @param       id                      : I2C peripheral ID (I2C0, I2C1 ... etc)\r
224  * @param       sid                     : I2C Slave peripheral ID (I2C_SLAVE_0, I2C_SLAVE_1 etc)\r
225  * @param       xfer            : Pointer to transfer structure (see note below for more info)\r
226  * @param       event           : Event handler for slave transfers\r
227  * @param       addrMask        : Address mask to use along with slave address (see notes below for more info)\r
228  * @return      Nothing\r
229  * @note\r
230  * Parameter @a xfer should point to a valid I2C_XFER_T structure object\r
231  * and must have @a slaveAddr initialized with 7bit Slave address (From Bit1 to Bit7),\r
232  * Bit0 when set enables general call handling, @a slaveAddr along with @a addrMask will\r
233  * be used to match the slave address. @a rxBuff and @a txBuff must point to valid buffers\r
234  * where slave can receive or send the data from, size of which will be provided by\r
235  * @a rxSz and @a txSz respectively. Function pointed to by @a event will be called\r
236  * for the following events #I2C_EVENT_SLAVE_RX (One byte of data received successfully\r
237  * from the master and stored inside memory pointed by xfer->rxBuff, incremented\r
238  * the pointer and decremented the @a xfer->rxSz), #I2C_EVENT_SLAVE_TX (One byte of\r
239  * data from xfer->txBuff was sent to master successfully, incremented the pointer\r
240  * and decremented xfer->txSz), #I2C_EVENT_DONE (Master is done doing its transfers\r
241  * with the slave).<br>\r
242  * <br>Bit-0 of the parameter @a addrMask is reserved and should always be 0. Any bit (BIT1\r
243  * to BIT7) set in @a addrMask will make the corresponding bit in *xfer->slaveAddr* as\r
244  * don't care. Thit is, if *xfer->slaveAddr* is (0x10 << 1) and @a addrMask is (0x03 << 1) then\r
245  * 0x10, 0x11, 0x12, 0x13 will all be considered as valid slave addresses for the registered\r
246  * slave. Upon receving any event *xfer->slaveAddr* (BIT1 to BIT7) will hold the actual\r
247  * address which was received from master.<br>\r
248  * <br><b>General Call Handling</b><br>\r
249  * Slave can receive data from master using general call address (0x00). General call\r
250  * handling must be setup as given below\r
251  *              - Call Chip_I2C_SlaveSetup() with argument @a sid as I2C_SLAVE_GENERAL\r
252  *                      - xfer->slaveAddr ignored, argument @a addrMask ignored\r
253  *                      - function provided by @a event will registered to be called when slave received data using addr 0x00\r
254  *                      - xfer->rxBuff and xfer->rxSz should be valid in argument @a xfer\r
255  *              - To handle General Call only (No other slaves are configured)\r
256  *                      - Call Chip_I2C_SlaveSetup() with sid as I2C_SLAVE_X (X=0,1,2,3)\r
257  *                      - setup @a xfer with slaveAddr member set to 0, @a event is ignored hence can be NULL\r
258  *                      - provide @a addrMask (typically 0, if not you better be knowing what you are doing)\r
259  *              - To handler General Call when other slave is active\r
260  *                      - Call Chip_I2C_SlaveSetup() with sid as I2C_SLAVE_X (X=0,1,2,3)\r
261  *                      - setup @a xfer with slaveAddr member set to 7-Bit Slave address [from Bit1 to 7]\r
262  *                      - Set Bit0 of @a xfer->slaveAddr as 1\r
263  *                      - Provide appropriate @a addrMask\r
264  *                      - Argument @a event must point to function, that handles events from actual slaveAddress and not the GC\r
265  * @warning\r
266  * If the slave has only one byte in its txBuff, once that byte is transfered to master the event handler\r
267  * will be called for event #I2C_EVENT_DONE. If the master attempts to read more bytes in the same transfer\r
268  * then the slave hardware will send 0xFF to master till the end of transfer, event handler will not be\r
269  * called to notify this. For more info see section below<br>\r
270  * <br><b> Last data handling in slave </b><br>\r
271  * If the user wants to implement a slave which will read a byte from a specific location over and over\r
272  * again whenever master reads the slave. If the user initializes the xfer->txBuff as the location to read\r
273  * the byte from and xfer->txSz as 1, then say, if master reads one byte; slave will send the byte read from\r
274  * xfer->txBuff and will call the event handler with #I2C_EVENT_DONE. If the master attempts to read another\r
275  * byte instead of sending the byte read from xfer->txBuff the slave hardware will send 0xFF and no event will\r
276  * occur. To handle this issue, slave should set xfer->txSz to 2, in which case when master reads the byte\r
277  * event handler will be called with #I2C_EVENT_SLAVE_TX, in which the slave implementation can reset the buffer\r
278  * and size back to original location (i.e, xfer->txBuff--, xfer->txSz++), if the master reads another byte\r
279  * in the same transfer, byte read from xfer->txBuff will be sent and #I2C_EVENT_SLAVE_TX will be called again, and\r
280  * the process repeats.\r
281  */\r
282 void Chip_I2C_SlaveSetup(I2C_ID_T id,\r
283                                                  I2C_SLAVE_ID sid,\r
284                                                  I2C_XFER_T *xfer,\r
285                                                  I2C_EVENTHANDLER_T event,\r
286                                                  uint8_t addrMask);\r
287 \r
288 /**\r
289  * @brief       I2C Slave event handler\r
290  * @param       id              : I2C peripheral ID (I2C0, I2C1 ... etc)\r
291  * @return      Nothing\r
292  */\r
293 void Chip_I2C_SlaveStateHandler(I2C_ID_T id);\r
294 \r
295 /**\r
296  * @brief       I2C peripheral state change checking\r
297  * @param       id              : I2C peripheral ID (I2C0, I2C1 ... etc)\r
298  * @return      1 if I2C peripheral @a id has changed its state,\r
299  *          0 if there is no state change\r
300  * @note        This function must be used by the application when\r
301  *          the polling has to be done based on state change.\r
302  */\r
303 int Chip_I2C_IsStateChanged(I2C_ID_T id);\r
304 \r
305 /**\r
306  * @}\r
307  */\r
308 \r
309  #ifdef __cplusplus\r
310 }\r
311 #endif\r
312 \r
313 #endif /* __I2C_18XX_43XX_H_ */\r