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