EVE 1.0
i2c-master.h
Go to the documentation of this file.
1 #ifndef DRIVER_I2C_MASTER_H
2 #define DRIVER_I2C_MASTER_H
3 /**********************************************************************/
4 /*
5  * Copyright (c) 2013-2016, Jetro AS
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without modification,
9  * are permitted provided that the following conditions are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright notice,
12  * this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright notice,
14  * this list of conditions and the following disclaimer in the documentation
15  * and/or other materials provided with the distribution.
16  * 3. The name of the author may not be used to endorse or promote products
17  * derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONRIBUTORS ``AS IS'' AND ANY EXPRESS
20  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
22  * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
24  * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
27  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
28  * OF SUCH DAMAGE.
29  *
30  * This file is part of the EVE platform.
31  */
32 
33 /**
34  * \file
35  * @brief Driver for I2C in nRF52 uC.
36  *
37  * @author KLO, Jetro AS
38  * @author DT, Jetro AS
39  */ /******************************************************************/
40 
41 #include <hal/nrf_twi.h>
42 #include <core/work.h>
43 #include <lib/dlist.h>
44 
45 /**
46  * \defgroup i2c_master nRF52 I2C bus master driver
47  * \ingroup nrf52
48  * \{
49  *
50  * This I2C driver can be used for I2C0 and I2C1.
51  *
52  * First the driver setup the microcontroller to I2C master based on the i2c_t structure.
53  * Then the driver does:
54  * - Generates start condition
55  * - Transmits slave address
56  * - Transmits bytes (if any) from a given buffer
57  * - Generates restart condition if bytes should be received, then receives bytes
58  * to a given buffer (ACK is sent for each received byte except for
59  * the last on where NACK is sent).
60  * - Generates stop condition
61  *
62  * The driver returns true if communication OK, else false.
63  *
64  * While the I2C communication is in progress, the clock is locked and
65  * energy mode EM1 is minimum required.
66  */
67 
68 
69 /***********************************************************************
70  * Global defines
71 ***********************************************************************/
72 
73 struct i2c_t;
74 
75 /**
76  * Asynchronous callback type
77  *
78  * @param I2c Pointer to the I2C master instance object
79  * @param ErrorMask Bitmap of the possible bus error types, see enum i2c_error_t
80  * @param Data User data passed as I2cMasterAsync function parameter
81  */
82 typedef void (* i2c_completion_callback_t)(const struct i2c_t *I2c,
83  uint8_t ErrorMask,
84  void *Data);
85 
86 enum i2c_error_t
87 {
88  I2C_BUS_HUNG_SDA_LOW = (1 << 0),
89  I2C_ADDRESS_NAK = (1 << 1),
90  I2C_DATA_NACK = (1 << 2),
91  I2C_UNEXPECTED_STOP = (1 << 3),
92 };
93 
94 /**
95  * i2c_state_t structure holds clock lock state and other parameter used by the driver functions.
96  * The structure will be set by the I2cMaster() function when called.
97  *
98  */
100 {
101  i2c_completion_callback_t CompletionCallback; /**< Completion callback */
102  void *CompletionCallbackData; /**< Completion callback data */
103  uint32_t LastError; /**< Error reason bitmap or 0 if a transfer finished successfully */
104  struct dlist_t PendingI2cWorks; /**< List of works waiting for bus availability */
105 };
106 
107 /**
108  * i2c_t structure is used for configuration of I2C.
109  * The structure must be initialized before the I2C driver may be used.
110  *
111  */
112 struct i2c_t
113 {
114  NRF_TWIM_Type *Dev; /**< Hardware interface */
115  uint32_t IrqPriority; /**< HW IRQ priority (see enum EVE_IRQ_PRIORITIES) */
116  struct i2c_state_t *State; /**< Pointer to state structure allocated in RAM */
117  uint32_t Baudrate; /**< Rate in bit/s */
118  struct
119  {
120  uint8_t Scl; /**< SCL pin location. */
121  uint8_t Sda; /**< SDA pin location */
122  } Location;
123 };
124 
125  /**
126  * @name Functions called from application programs
127  * @{
128  */
129 
130 /**********************************************************************/
131 /**
132  * @brief Name: I2cMasterInit\n
133  * Initialize the driver. Function must be called before driver use.
134  *
135  * @param I2cMaster Pointer to I2C module
136  **********************************************************************/
137 extern void I2cMasterInit(const struct i2c_t *I2cMaster);
138 
139 /**********************************************************************/
140 /**
141  * @brief Name: I2cBusReset\n
142  * Reset the bus (clock through a bus hung)
143  *
144  * @param I2cMaster Pointer to I2C module
145  **********************************************************************/
146 extern void I2cBusReset(const struct i2c_t *I2cMaster);
147 
148 /**********************************************************************/
149 /**
150  * @brief Name: I2cMasterAsync\n
151  * Setup the microcontroller to I2C master based on the i2c_t structure (slave not supported).
152  * Then the driver does:
153  * - Generates start condition
154  * - Transmits slave address
155  * - Transmits from 0 til SrcCount bytes from the buffer SrcBuffer
156  * - Generates restart condition if bytes should be received (DstCount > 0),
157  * then receives DstCount bytes to the buffer DstBuffer
158  * - ACK is sent for each received byte except for the last on where NACK is sent.
159  * - Generates stop condition
160  * The transfer duration (number of bytes to transfer) must not exceed 50 ms.
161  *
162  * @param I2cMaster Pointer to I2C module
163  * @param SlaveAddress IIC slave address
164  * @param SrcBuffer Pointer to data to be written
165  * @param SrcCount Number of bytes to write
166  * @param DstBuffer Pointer to buffer to place read data
167  * @param DstCount Number of bytes to read
168  * @param Callback Completion callback
169  * @param CallbackData Completion callback data
170  * @return true if communication started, else false
171  **********************************************************************/
172 extern bool I2cMasterAsync(const struct i2c_t *I2cMaster,
173  uint8_t SlaveAddress,
174  const void *SrcBuffer,
175  uint8_t SrcCount,
176  void *DstBuffer,
177  uint8_t DstCount,
178  i2c_completion_callback_t Callback,
179  void *CallbackData);
180 
181 /**********************************************************************/
182 /**
183  * @brief Name: I2cMasterSchedule\n
184  * Schedule work when I2C bus becomes available.\n
185  * In case the bus is already free, the work is scheduled immediately.
186  *
187  * @param I2cMaster Pointer to I2C module
188  * @param Work Work to be scheduled immediately if I2C is free,
189  * otherwise after I2C becomes free.
190  **********************************************************************/
191 void I2cMasterSchedule(const struct i2c_t* I2cMaster, struct work_t* Work);
192 
193 /**********************************************************************/
194 /**
195  * @brief Name: I2cMasterAsyncWait\n
196  * Setup the microcontroller to I2C master based on the i2c_t structure (slave not supported).
197  * Then the driver does:
198  * - Generates start condition
199  * - Transmits slave address
200  * - Transmits from 0 til SrcCount bytes from the buffer SrcBuffer
201  * - Generates restart condition if bytes should be received (DstCount > 0),
202  * then receives DstCount bytes to the buffer DstBuffer
203  * - ACK is sent for each received byte except for the last on where NACK is sent.
204  * - Generates stop condition
205  * The transfer duration (number of bytes to transfer) must not exceed 50 ms.
206  *
207  * @param I2cMaster Pointer to I2C module
208  * @param SlaveAddress IIC slave address
209  * @param SrcBuffer Pointer to data to be written
210  * @param SrcCount Number of bytes to write
211  * @param DstBuffer Pointer to buffer to place read data
212  * @param DstCount Number of bytes to read
213  * @param Callback Completion callback
214  * @param CallbackData Completion callback data
215  * @param Work If I2C is busy, the Work to be scheduled after I2C is free again.
216  * @return true if communication started, false if work will be scheduled.
217  **********************************************************************/
218 inline bool I2cMasterAsyncWait(const struct i2c_t* I2cMaster, uint8_t SlaveAddress,
219  const void* SrcBuffer, uint8_t SrcCount,
220  void* DstBuffer, uint8_t DstCount,
221  i2c_completion_callback_t Callback, void* CallbackData,
222  struct work_t* Work)
223 {
224  if (!I2cMasterAsync(I2cMaster, SlaveAddress, SrcBuffer, SrcCount,
225  DstBuffer, DstCount, Callback, CallbackData))
226  {
227  I2cMasterSchedule(I2cMaster, Work);
228  return false;
229  }
230  return true;
231 }
232 
233 /**********************************************************************/
234 /**
235  * @brief Name: I2cMaster\n
236  * Setup the microcontroller to I2C master based on the i2c_t structure (slave not supported).
237  * Then the driver does:
238  * - Generates start condition
239  * - Transmits slave address
240  * - Transmits from 0 til SrcCount bytes from the buffer SrcBuffer
241  * - Generates restart condition if bytes should be received (DstCount > 0),
242  * then receives DstCount bytes to the buffer DstBuffer
243  * - ACK is sent for each received byte except for the last on where NACK is sent.
244  * - Generates stop condition
245  * The transfer duration (number of bytes to transfer) must not exceed 50 ms.
246  *
247  * @param I2cMaster Pointer to I2C module
248  * @param SlaveAddress IIC slave address
249  * @param SrcBuffer Pointer to data to be written
250  * @param SrcCount Number of bytes to write
251  * @param DstBuffer Pointer to buffer to place read data
252  * @param DstCount Number of bytes to read
253  * @return true if communication OK, else false
254  **********************************************************************/
255 extern bool I2cMaster(const struct i2c_t *I2cMaster,
256  uint8_t SlaveAddress,
257  const void *SrcBuffer,
258  uint16_t SrcCount,
259  void *DstBuffer,
260  uint16_t DstCount);
261 
262 /**********************************************************************/
263 /**
264  * @brief Name: I2cInterruptHandler\n
265  * I2C master interrupt handler
266  * Called from board.c at hardware interrupt context.
267  *
268  * @param I2cMaster I2C parameters to be used
269  ***********************************************************************/
270 extern void I2cMasterInterruptHandler(const struct i2c_t *I2cMaster);
271 
272 /** @} */
273 /** \} */
274 
275 #endif //DRIVER_I2C_MASTER_H
uint32_t IrqPriority
Definition: i2c-master.h:115
bool I2cMasterAsyncWait(const struct i2c_t *I2cMaster, uint8_t SlaveAddress, const void *SrcBuffer, uint8_t SrcCount, void *DstBuffer, uint8_t DstCount, i2c_completion_callback_t Callback, void *CallbackData, struct work_t *Work)
Name: I2cMasterAsyncWait Setup the microcontroller to I2C master based on the i2c_t structure (slave ...
Definition: i2c-master.h:218
i2c_completion_callback_t CompletionCallback
Definition: i2c-master.h:101
void I2cMasterSchedule(const struct i2c_t *I2cMaster, struct work_t *Work)
Name: I2cMasterSchedule Schedule work when I2C bus becomes available. In case the bus is already free...
uint32_t LastError
Definition: i2c-master.h:103
void I2cMasterInit(const struct i2c_t *I2cMaster)
Name: I2cMasterInit Initialize the driver. Function must be called before driver use.
uint32_t Baudrate
Definition: i2c-master.h:117
The code implements Dummy Headed Doubly Linked Circularlist (DHDLC) primitive.
void I2cBusReset(const struct i2c_t *I2cMaster)
Name: I2cBusReset Reset the bus (clock through a bus hung)
bool I2cMaster(const struct i2c_t *I2cMaster, uint8_t SlaveAddress, const void *SrcBuffer, uint16_t SrcCount, void *DstBuffer, uint16_t DstCount)
Name: I2cMaster Setup the microcontroller to I2C master based on the i2c_t structure (slave not suppo...
void * CompletionCallbackData
Definition: i2c-master.h:102
struct i2c_state_t * State
Definition: i2c-master.h:116
Header file for the EVE work scheduling.
void I2cMasterInterruptHandler(const struct i2c_t *I2cMaster)
Name: I2cInterruptHandler I2C master interrupt handler Called from board.c at hardware interrupt cont...
struct dlist_t PendingI2cWorks
Definition: i2c-master.h:104
Definition: dlist.h:66
uint8_t Sda
Definition: i2c-master.h:121
bool I2cMasterAsync(const struct i2c_t *I2cMaster, uint8_t SlaveAddress, const void *SrcBuffer, uint8_t SrcCount, void *DstBuffer, uint8_t DstCount, i2c_completion_callback_t Callback, void *CallbackData)
Name: I2cMasterAsync Setup the microcontroller to I2C master based on the i2c_t structure (slave not ...
NRF_TWIM_Type * Dev
Definition: i2c-master.h:114
Definition: work.h:140
void(* i2c_completion_callback_t)(const struct i2c_t *I2c, uint8_t ErrorMask, void *Data)
Definition: i2c-master.h:82
uint8_t Scl
Definition: i2c-master.h:120