1 /***************************************************************************//**
2 * @file
3 * @brief Inter-intergrated circuit (I2C) peripheral API
4 * @author Energy Micro AS
5 * @version 3.0.0
6 *******************************************************************************
7 * @section License
8 * <b>(C) Copyright 2012 Energy Micro AS, http://www.energymicro.com</b>
9 *******************************************************************************
10 *
11 * Permission is granted to anyone to use this software for any purpose,
12 * including commercial applications, and to alter it and redistribute it
13 * freely, subject to the following restrictions:
14 *
15 * 1. The origin of this software must not be misrepresented; you must not
16 * claim that you wrote the original software.
17 * 2. Altered source versions must be plainly marked as such, and must not be
18 * misrepresented as being the original software.
19 * 3. This notice may not be removed or altered from any source distribution.
20 *
21 * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
22 * obligation to support this Software. Energy Micro AS is providing the
23 * Software "AS IS", with no express or implied warranties of any kind,
24 * including, but not limited to, any implied warranties of merchantability
25 * or fitness for any particular purpose or warranties against infringement
26 * of any proprietary rights of a third party.
27 *
28 * Energy Micro AS will not be liable for any consequential, incidental, or
29 * special damages, or any other relief, or for any claim by any third party,
30 * arising from your use of this Software.
31 *
32 ******************************************************************************/
33 #ifndef __EM_I2C_H
34 #define __EM_I2C_H
35
36 #include <stdbool.h>
37 #include "em_part.h"
38
39 #ifdef __cplusplus
40 extern "C" {
41 #endif
42
43 /***************************************************************************//**
44 * @addtogroup EM_Library
45 * @{
46 ******************************************************************************/
47
48 /***************************************************************************//**
49 * @addtogroup I2C
50 * @{
51 ******************************************************************************/
52
53 /*******************************************************************************
54 ******************************* DEFINES ***********************************
55 ******************************************************************************/
56
57 /**
58 * @brief
59 * Standard mode max frequency assuming using 4:4 ratio for Nlow:Nhigh.
60 * @details
61 * From I2C specification: Min Tlow = 4.7us, min Thigh = 4.0us,
62 * max Trise=1.0us, max Tfall=0.3us. Since ratio is 4:4, have to use
63 * worst case value of Tlow or Thigh as base.
64 *
65 * 1/(Tlow + Thigh + 1us + 0.3us) = 1/(4.7 + 4.7 + 1.3)us = 93458Hz
66 */
67 #define I2C_FREQ_STANDARD_MAX 93500
68
69 /**
70 * @brief
71 * Fast mode max frequency assuming using 6:3 ratio for Nlow:Nhigh.
72 * @details
73 * From I2C specification: Min Tlow = 1.3us, min Thigh = 0.6us,
74 * max Trise=0.3us, max Tfall=0.3us. Since ratio is 6:3, have to use
75 * worst case value of Tlow or 2xThigh as base.
76 *
77 * 1/(Tlow + Thigh + 0.3us + 0.3us) = 1/(1.3 + 0.65 + 0.6)us = 392157Hz
78 */
79 #define I2C_FREQ_FAST_MAX 392500
80
81
82 /**
83 * @brief
84 * Fast mode+ max frequency assuming using 11:6 ratio for Nlow:Nhigh.
85 * @details
86 * From I2C specification: Min Tlow = 0.5us, min Thigh = 0.26us,
87 * max Trise=0.012us, max Tfall=0.12us. Since ratio is 11:6, have to use
88 * worst case value of Tlow or (11/6)xThigh as base.
89 *
90 * 1/(Tlow + Thigh + 0.12us + 0.12us) = 1/(0.5 + 0.273 + 0.24)us = 987167Hz
91 */
92 #define I2C_FREQ_FASTPLUS_MAX 987500
93
94
95 /**
96 * @brief
97 * Indicate plain write sequence: S+ADDR(W)+DATA0+P.
98 * @details
99 * @li S - Start
100 * @li ADDR(W) - address with W/R bit cleared
101 * @li DATA0 - Data taken from buffer with index 0
102 * @li P - Stop
103 */
104 #define I2C_FLAG_WRITE 0x0001
105
106 /**
107 * @brief
108 * Indicate plain read sequence: S+ADDR(R)+DATA0+P.
109 * @details
110 * @li S - Start
111 * @li ADDR(R) - address with W/R bit set
112 * @li DATA0 - Data read into buffer with index 0
113 * @li P - Stop
114 */
115 #define I2C_FLAG_READ 0x0002
116
117 /**
118 * @brief
119 * Indicate combined write/read sequence: S+ADDR(W)+DATA0+Sr+ADDR(R)+DATA1+P.
120 * @details
121 * @li S - Start
122 * @li Sr - Repeated start
123 * @li ADDR(W) - address with W/R bit cleared
124 * @li ADDR(R) - address with W/R bit set
125 * @li DATAn - Data written from/read into buffer with index n
126 * @li P - Stop
127 */
128 #define I2C_FLAG_WRITE_READ 0x0004
129
130 /**
131 * @brief
132 * Indicate write sequence using two buffers: S+ADDR(W)+DATA0+DATA1+P.
133 * @details
134 * @li S - Start
135 * @li ADDR(W) - address with W/R bit cleared
136 * @li DATAn - Data written from buffer with index n
137 * @li P - Stop
138 */
139 #define I2C_FLAG_WRITE_WRITE 0x0008
140
141 /** Use 10 bit address. */
142 #define I2C_FLAG_10BIT_ADDR 0x0010
143
144
145 /*******************************************************************************
146 ******************************** ENUMS ************************************
147 ******************************************************************************/
148
149 /** Clock low to high ratio settings. */
150 typedef enum
151 {
152 i2cClockHLRStandard = _I2C_CTRL_CLHR_STANDARD, /**< Ratio is 4:4 */
153 i2cClockHLRAsymetric = _I2C_CTRL_CLHR_ASYMMETRIC, /**< Ratio is 6:3 */
154 i2cClockHLRFast = _I2C_CTRL_CLHR_FAST /**< Ratio is 11:3 */
155 } I2C_ClockHLR_TypeDef;
156
157
158 /** Return codes for single master mode transfer function. */
159 typedef enum
160 {
161 /* In progress code (>0) */
162 i2cTransferInProgress = 1, /**< Transfer in progress. */
163
164 /* Complete code (=0) */
165 i2cTransferDone = 0, /**< Transfer completed successfully. */
166
167 /* Transfer error codes (<0) */
168 i2cTransferNack = -1, /**< NACK received during transfer. */
169 i2cTransferBusErr = -2, /**< Bus error during transfer (misplaced START/STOP). */
170 i2cTransferArbLost = -3, /**< Arbitration lost during transfer. */
171 i2cTransferUsageFault = -4, /**< Usage fault. */
172 i2cTransferSwFault = -5 /**< SW fault. */
173 } I2C_TransferReturn_TypeDef;
174
175
176 /*******************************************************************************
177 ******************************* STRUCTS ***********************************
178 ******************************************************************************/
179
180 /** I2C initialization structure. */
181 typedef struct
182 {
183 /** Enable I2C peripheral when init completed. */
184 bool enable;
185
186 /** Set to master (true) or slave (false) mode */
187 bool master;
188
189 /**
190 * I2C reference clock assumed when configuring bus frequency setup.
191 * Set it to 0 if currently configurated reference clock shall be used
192 * This parameter is only applicable if operating in master mode.
193 */
194 uint32_t refFreq;
195
196 /**
197 * (Max) I2C bus frequency to use. This parameter is only applicable
198 * if operating in master mode.
199 */
200 uint32_t freq;
201
202 /** Clock low/high ratio control. */
203 I2C_ClockHLR_TypeDef clhr;
204 } I2C_Init_TypeDef;
205
206 /** Suggested default config for I2C init structure. */
207 #define I2C_INIT_DEFAULT \
208 { true, /* Enable when init done */ \
209 true, /* Set to master mode */ \
210 0, /* Use currently configured reference clock */ \
211 I2C_FREQ_STANDARD_MAX, /* Set to standard rate assuring being */ \
212 /* within I2C spec */ \
213 i2cClockHLRStandard /* Set to use 4:4 low/high duty cycle */ \
214 }
215
216
217 /**
218 * @brief
219 * Master mode transfer message structure used to define a complete
220 * I2C transfer sequence (from start to stop).
221 * @details
222 * The structure allows for defining the following types of sequences,
223 * please refer to defines for sequence details.
224 * @li #I2C_FLAG_READ - data read into buf[0].data
225 * @li #I2C_FLAG_WRITE - data written from buf[0].data
226 * @li #I2C_FLAG_WRITE_READ - data written from buf[0].data and read
227 * into buf[1].data
228 * @li #I2C_FLAG_WRITE_WRITE - data written from buf[0].data and
229 * buf[1].data
230 */
231 typedef struct
232 {
233 /**
234 * @brief
235 * Address to use after (repeated) start.
236 * @details
237 * Layout details, A = address bit, X = don't care bit (set to 0):
238 * @li 7 bit address - use format AAAA AAAX.
239 * @li 10 bit address - use format XXXX XAAX AAAA AAAA
240 */
241 uint16_t addr;
242
243 /** Flags defining sequence type and details, see I2C_FLAG_... defines. */
244 uint16_t flags;
245
246 /**
247 * Buffers used to hold data to send from or receive into depending
248 * on sequence type.
249 */
250 struct
251 {
252 /** Buffer used for data to transmit/receive, must be @p len long. */
253 uint8_t *data;
254
255 /**
256 * Number of bytes in @p data to send or receive. Notice that when
257 * receiving data to this buffer, at least 1 byte must be received.
258 * Setting @p len to 0 in the receive case is considered a usage fault.
259 * Transmitting 0 bytes is legal, in which case only the address
260 * is transmitted after the start condition.
261 */
262 uint16_t len;
263 } buf[2];
264 } I2C_TransferSeq_TypeDef;
265
266
267 /*******************************************************************************
268 ***************************** PROTOTYPES **********************************
269 ******************************************************************************/
270
271 uint32_t I2C_BusFreqGet(I2C_TypeDef *i2c);
272 void I2C_BusFreqSet(I2C_TypeDef *i2c,
273 uint32_t refFreq,
274 uint32_t freq,
275 I2C_ClockHLR_TypeDef type);
276 void I2C_Enable(I2C_TypeDef *i2c, bool enable);
277 void I2C_Init(I2C_TypeDef *i2c, const I2C_Init_TypeDef *init);
278
279 /***************************************************************************//**
280 * @brief
281 * Clear one or more pending I2C interrupts.
282 *
283 * @param[in] i2c
284 * Pointer to I2C peripheral register block.
285 *
286 * @param[in] flags
287 * Pending I2C interrupt source to clear. Use a bitwse logic OR combination of
288 * valid interrupt flags for the I2C module (I2C_IF_nnn).
289 ******************************************************************************/
I2C_IntClear(I2C_TypeDef * i2c,uint32_t flags)290 __STATIC_INLINE void I2C_IntClear(I2C_TypeDef *i2c, uint32_t flags)
291 {
292 i2c->IFC = flags;
293 }
294
295
296 /***************************************************************************//**
297 * @brief
298 * Disable one or more I2C interrupts.
299 *
300 * @param[in] i2c
301 * Pointer to I2C peripheral register block.
302 *
303 * @param[in] flags
304 * I2C interrupt sources to disable. Use a bitwise logic OR combination of
305 * valid interrupt flags for the I2C module (I2C_IF_nnn).
306 ******************************************************************************/
I2C_IntDisable(I2C_TypeDef * i2c,uint32_t flags)307 __STATIC_INLINE void I2C_IntDisable(I2C_TypeDef *i2c, uint32_t flags)
308 {
309 i2c->IEN &= ~(flags);
310 }
311
312
313 /***************************************************************************//**
314 * @brief
315 * Enable one or more I2C interrupts.
316 *
317 * @note
318 * Depending on the use, a pending interrupt may already be set prior to
319 * enabling the interrupt. Consider using I2C_IntClear() prior to enabling
320 * if such a pending interrupt should be ignored.
321 *
322 * @param[in] i2c
323 * Pointer to I2C peripheral register block.
324 *
325 * @param[in] flags
326 * I2C interrupt sources to enable. Use a bitwise logic OR combination of
327 * valid interrupt flags for the I2C module (I2C_IF_nnn).
328 ******************************************************************************/
I2C_IntEnable(I2C_TypeDef * i2c,uint32_t flags)329 __STATIC_INLINE void I2C_IntEnable(I2C_TypeDef *i2c, uint32_t flags)
330 {
331 i2c->IEN |= flags;
332 }
333
334
335 /***************************************************************************//**
336 * @brief
337 * Get pending I2C interrupt flags.
338 *
339 * @note
340 * The event bits are not cleared by the use of this function.
341 *
342 * @param[in] i2c
343 * Pointer to I2C peripheral register block.
344 *
345 * @return
346 * I2C interrupt sources pending. A bitwise logic OR combination of valid
347 * interrupt flags for the I2C module (I2C_IF_nnn).
348 ******************************************************************************/
I2C_IntGet(I2C_TypeDef * i2c)349 __STATIC_INLINE uint32_t I2C_IntGet(I2C_TypeDef *i2c)
350 {
351 return(i2c->IF);
352 }
353
354
355 /***************************************************************************//**
356 * @brief
357 * Set one or more pending I2C interrupts from SW.
358 *
359 * @param[in] i2c
360 * Pointer to I2C peripheral register block.
361 *
362 * @param[in] flags
363 * I2C interrupt sources to set to pending. Use a bitwise logic OR combination
364 * of valid interrupt flags for the I2C module (I2C_IF_nnn).
365 ******************************************************************************/
I2C_IntSet(I2C_TypeDef * i2c,uint32_t flags)366 __STATIC_INLINE void I2C_IntSet(I2C_TypeDef *i2c, uint32_t flags)
367 {
368 i2c->IFS = flags;
369 }
370
371 void I2C_Reset(I2C_TypeDef *i2c);
372
373 /***************************************************************************//**
374 * @brief
375 * Get slave address used for I2C peripheral (when operating in slave mode).
376 *
377 * @details
378 * For 10 bit addressing mode, the address is split in two bytes, and only
379 * the first byte setting is fetched, effectively only controlling the 2 most
380 * significant bits of the 10 bit address. Full handling of 10 bit addressing
381 * in slave mode requires additional SW handling.
382 *
383 * @param[in] i2c
384 * Pointer to I2C peripheral register block.
385 *
386 * @return
387 * I2C slave address in use. The 7 most significant bits define the actual
388 * address, the least significant bit is reserved and always returned as 0.
389 ******************************************************************************/
I2C_SlaveAddressGet(I2C_TypeDef * i2c)390 __STATIC_INLINE uint8_t I2C_SlaveAddressGet(I2C_TypeDef *i2c)
391 {
392 return((uint8_t)(i2c->SADDR));
393 }
394
395
396 /***************************************************************************//**
397 * @brief
398 * Set slave address to use for I2C peripheral (when operating in slave mode).
399 *
400 * @details
401 * For 10 bit addressing mode, the address is split in two bytes, and only
402 * the first byte is set, effectively only controlling the 2 most significant
403 * bits of the 10 bit address. Full handling of 10 bit addressing in slave
404 * mode requires additional SW handling.
405 *
406 * @param[in] i2c
407 * Pointer to I2C peripheral register block.
408 *
409 * @param[in] addr
410 * I2C slave address to use. The 7 most significant bits define the actual
411 * address, the least significant bit is reserved and always set to 0.
412 ******************************************************************************/
I2C_SlaveAddressSet(I2C_TypeDef * i2c,uint8_t addr)413 __STATIC_INLINE void I2C_SlaveAddressSet(I2C_TypeDef *i2c, uint8_t addr)
414 {
415 i2c->SADDR = (uint32_t)addr & 0xfe;
416 }
417
418
419 /***************************************************************************//**
420 * @brief
421 * Get slave address mask used for I2C peripheral (when operating in slave
422 * mode).
423 *
424 * @details
425 * The address mask defines how the comparator works. A bit position with
426 * value 0 means that the corresponding slave address bit is ignored during
427 * comparison (don't care). A bit position with value 1 means that the
428 * corresponding slave address bit must match.
429 *
430 * For 10 bit addressing mode, the address is split in two bytes, and only
431 * the mask for the first address byte is fetched, effectively only
432 * controlling the 2 most significant bits of the 10 bit address.
433 *
434 * @param[in] i2c
435 * Pointer to I2C peripheral register block.
436 *
437 * @return
438 * I2C slave address mask in use. The 7 most significant bits define the
439 * actual address mask, the least significant bit is reserved and always
440 * returned as 0.
441 ******************************************************************************/
I2C_SlaveAddressMaskGet(I2C_TypeDef * i2c)442 __STATIC_INLINE uint8_t I2C_SlaveAddressMaskGet(I2C_TypeDef *i2c)
443 {
444 return((uint8_t)(i2c->SADDRMASK));
445 }
446
447
448 /***************************************************************************//**
449 * @brief
450 * Set slave address mask used for I2C peripheral (when operating in slave
451 * mode).
452 *
453 * @details
454 * The address mask defines how the comparator works. A bit position with
455 * value 0 means that the corresponding slave address bit is ignored during
456 * comparison (don't care). A bit position with value 1 means that the
457 * corresponding slave address bit must match.
458 *
459 * For 10 bit addressing mode, the address is split in two bytes, and only
460 * the mask for the first address byte is set, effectively only controlling
461 * the 2 most significant bits of the 10 bit address.
462 *
463 * @param[in] i2c
464 * Pointer to I2C peripheral register block.
465 *
466 * @param[in] mask
467 * I2C slave address mask to use. The 7 most significant bits define the
468 * actual address mask, the least significant bit is reserved and should
469 * be 0.
470 ******************************************************************************/
I2C_SlaveAddressMaskSet(I2C_TypeDef * i2c,uint8_t mask)471 __STATIC_INLINE void I2C_SlaveAddressMaskSet(I2C_TypeDef *i2c, uint8_t mask)
472 {
473 i2c->SADDRMASK = (uint32_t)mask & 0xfe;
474 }
475
476
477 I2C_TransferReturn_TypeDef I2C_Transfer(I2C_TypeDef *i2c);
478 I2C_TransferReturn_TypeDef I2C_TransferInit(I2C_TypeDef *i2c,
479 I2C_TransferSeq_TypeDef *seq);
480
481 /** @} (end addtogroup I2C) */
482 /** @} (end addtogroup EM_Library) */
483
484 #ifdef __cplusplus
485 }
486 #endif
487
488 #endif /* __EM_I2C_H */
489