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 Controller 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 Controller (true) or Target (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 Controller mode.
200    */
201   uint32_t             refFreq;
202 
203   /**
204    * (Max) I2C bus frequency to use. This parameter is only applicable
205    * if operating in Controller 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 Controller 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 Target address used for I2C peripheral (when operating in Target 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 Target mode requires additional SW handling.
423  *
424  * @param[in] i2c
425  *   Pointer to I2C peripheral register block.
426  *
427  * @return
428  *   I2C Target 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 Target address to use for I2C peripheral (when operating in Target 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 Target
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 Target 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 Target address mask used for I2C peripheral (when operating in Target
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 Target address bit is ignored during
466  *   comparison (don't care). A bit position with value 1 means that the
467  *   corresponding Target 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 Target 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 Target address mask used for I2C peripheral (when operating in Target
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 Target address bit is ignored during
494  *   comparison (don't care). A bit position with value 1 means that the
495  *   corresponding Target 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 Target 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