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