1 /***************************************************************************//**
2  * @file
3  * @brief Inter-integrated 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 #include "em_part.h"
34 #include "em_i2c.h"
35 #include "em_cmu.h"
36 #include "em_bitband.h"
37 #include "em_assert.h"
38 
39 /***************************************************************************//**
40  * @addtogroup EM_Library
41  * @{
42  ******************************************************************************/
43 
44 /***************************************************************************//**
45  * @addtogroup I2C
46  * @brief Inter-integrated Circuit (I2C) Peripheral API
47  * @{
48  ******************************************************************************/
49 
50 /*******************************************************************************
51  *******************************   DEFINES   ***********************************
52  ******************************************************************************/
53 
54 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
55 
56 /** Validation of I2C register block pointer reference for assert statements. */
57 #if defined(_EFM32_GECKO_FAMILY) || defined(_EFM32_TINY_FAMILY)
58 #define I2C_REF_VALID(ref)    ((ref) == I2C0)
59 #endif
60 
61 #if defined(_EFM32_GIANT_FAMILY)
62 #define I2C_REF_VALID(ref)    ((ref == I2C0) || (ref == I2C1))
63 #endif
64 
65 /** Error flags indicating I2C transfer has failed somehow. */
66 /* Notice that I2C_IF_TXOF (transmit overflow) is not really possible with */
67 /* this SW supporting master mode. Likewise for I2C_IF_RXUF (receive underflow) */
68 /* RXUF is only likely to occur with this SW if using a debugger peeking into */
69 /* RXDATA register. Thus, we ignore those types of fault. */
70 #define I2C_IF_ERRORS    (I2C_IF_BUSERR | I2C_IF_ARBLOST)
71 
72 /** @endcond */
73 
74 /*******************************************************************************
75  ********************************   ENUMS   ************************************
76  ******************************************************************************/
77 
78 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
79 
80 /** Master mode transfer states. */
81 typedef enum
82 {
83   i2cStateStartAddrSend,       /**< Send start + (first part of) address. */
84   i2cStateAddrWFAckNack,       /**< Wait for ACK/NACK on (first part of) address. */
85   i2cStateAddrWF2ndAckNack,    /**< Wait for ACK/NACK on second part of 10 bit address. */
86   i2cStateRStartAddrSend,      /**< Send repeated start + (first part of) address. */
87   i2cStateRAddrWFAckNack,      /**< Wait for ACK/NACK on address sent after repeated start. */
88   i2cStateDataSend,            /**< Send data. */
89   i2cStateDataWFAckNack,       /**< Wait for ACK/NACK on data sent. */
90   i2cStateWFData,              /**< Wait for data. */
91   i2cStateWFStopSent,          /**< Wait for STOP to have been transmitted. */
92   i2cStateDone                 /**< Transfer completed successfully. */
93 } I2C_TransferState_TypeDef;
94 
95 /** @endcond */
96 
97 /*******************************************************************************
98  *******************************   STRUCTS   ***********************************
99  ******************************************************************************/
100 
101 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
102 
103 /** Structure used to store state information on an ongoing master mode transfer. */
104 typedef struct
105 {
106   /** Current state. */
107   I2C_TransferState_TypeDef  state;
108 
109   /** Result return code. */
110   I2C_TransferReturn_TypeDef result;
111 
112   /** Offset in current sequence buffer. */
113   uint16_t                   offset;
114 
115   /* Index to current sequence buffer in use. */
116   uint8_t                    bufIndx;
117 
118   /** Reference to I2C transfer sequence definition provided by user. */
119   I2C_TransferSeq_TypeDef    *seq;
120 } I2C_Transfer_TypeDef;
121 
122 /** @endcond */
123 
124 /*******************************************************************************
125  *****************************   LOCAL DATA   *******^**************************
126  ******************************************************************************/
127 
128 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
129 
130 /**
131  * Lookup table for Nlow + Nhigh setting defined by CLHR. Set undefined
132  * index (0x3) to reflect default setting just in case.
133  */
134 static const uint8_t i2cNSum[] = { 4 + 4, 6 + 3, 11 + 3, 4 + 4 };
135 
136 /** Transfer state info for ongoing master mode transfer */
137 static I2C_Transfer_TypeDef i2cTransfer[I2C_COUNT];
138 
139 /** @endcond */
140 
141 /*******************************************************************************
142  **************************   GLOBAL FUNCTIONS   *******************************
143  ******************************************************************************/
144 
145 /***************************************************************************//**
146  * @brief
147  *   Get current configured I2C bus frequency.
148  *
149  * @details
150  *   This frequency is only of relevance when acting as master.
151  *
152  * @param[in] i2c
153  *   Pointer to I2C peripheral register block.
154  *
155  * @return
156  *   Current I2C frequency in Hz.
157  ******************************************************************************/
I2C_BusFreqGet(I2C_TypeDef * i2c)158 uint32_t I2C_BusFreqGet(I2C_TypeDef *i2c)
159 {
160   uint32_t hfperclk;
161   uint32_t n;
162 
163   /* Max frequency is given by fSCL = fHFPERCLK/((Nlow + Nhigh)(DIV + 1) + 4) */
164   hfperclk = CMU_ClockFreqGet(cmuClock_HFPER);
165   n        = (uint32_t)(i2cNSum[(i2c->CTRL & _I2C_CTRL_CLHR_MASK) >> _I2C_CTRL_CLHR_SHIFT]);
166 
167   return(hfperclk / ((n * (i2c->CLKDIV + 1)) + 4));
168 }
169 
170 
171 /***************************************************************************//**
172  * @brief
173  *   Set I2C bus frequency.
174  *
175  * @details
176  *   The bus frequency is only of relevance when acting as a master. The bus
177  *   frequency should not be set higher than the max frequency accepted by the
178  *   slowest device on the bus.
179  *
180  *   Notice that due to asymmetric requirements on low and high I2C clock
181  *   cycles by the I2C specification, the actual max frequency allowed in order
182  *   to comply with the specification may be somewhat lower than expected.
183  *
184  *   Please refer to the reference manual, details on I2C clock generation,
185  *   for max allowed theoretical frequencies for different modes.
186  *
187  * @param[in] i2c
188  *   Pointer to I2C peripheral register block.
189  *
190  * @param[in] refFreq
191  *   I2C reference clock frequency in Hz that will be used. If set to 0,
192  *   the currently configured reference clock is assumed. Setting it to a higher
193  *   than actual configured value only has the consequence of reducing the real
194  *   I2C frequency.
195  *
196  * @param[in] freq
197  *   Bus frequency to set (actual bus speed may be lower due to integer
198  *   prescaling). Safe (according to I2C specification) max frequencies for
199  *   standard, fast and fast+ modes are available using I2C_FREQ_ defines.
200  *   (Using I2C_FREQ_ defines requires corresponding setting of @p type.)
201  *   Slowest slave device on bus must always be considered.
202  *
203  * @param[in] type
204  *   Clock low to high ratio type to use. If not using i2cClockHLRStandard,
205  *   make sure all devices on the bus support the specified mode. Using a
206  *   non-standard ratio is useful to achieve higher bus clock in fast and
207  *   fast+ modes.
208  ******************************************************************************/
I2C_BusFreqSet(I2C_TypeDef * i2c,uint32_t refFreq,uint32_t freq,I2C_ClockHLR_TypeDef type)209 void I2C_BusFreqSet(I2C_TypeDef *i2c,
210                     uint32_t refFreq,
211                     uint32_t freq,
212                     I2C_ClockHLR_TypeDef type)
213 {
214   uint32_t n;
215   uint32_t div;
216 
217   /* Unused parameter */
218   (void)type;
219 
220   /* Avoid divide by 0 */
221   EFM_ASSERT(freq);
222   if (!freq)
223   {
224     return;
225   }
226 
227   /* Frequency is given by fSCL = fHFPERCLK/((Nlow + Nhigh)(DIV + 1) + 4), thus */
228   /* DIV = ((fHFPERCLK - 4fSCL)/((Nlow + Nhigh)fSCL)) - 1 */
229 
230   if (!refFreq)
231   {
232     refFreq = CMU_ClockFreqGet(cmuClock_HFPER);
233   }
234   n = (uint32_t)(i2cNSum[(i2c->CTRL & _I2C_CTRL_CLHR_MASK) >> _I2C_CTRL_CLHR_SHIFT]);
235 
236   div = (refFreq - (4 * freq)) / (n * freq);
237   EFM_ASSERT(div);
238   if (div)
239   {
240     div--;
241   }
242 
243   /* Clock divisor must be at least 1 in slave mode according to reference */
244   /* manual (in which case there is normally no need to set bus frequency). */
245   if ((i2c->CTRL & I2C_CTRL_SLAVE) && !div)
246   {
247     div = 1;
248   }
249 
250   EFM_ASSERT(div <= _I2C_CLKDIV_DIV_MASK);
251   i2c->CLKDIV = div;
252 }
253 
254 
255 /***************************************************************************//**
256  * @brief
257  *   Enable/disable I2C.
258  *
259  * @note
260  *   After enabling the I2C (from being disabled), the I2C is in BUSY state.
261  *
262  * @param[in] i2c
263  *   Pointer to I2C peripheral register block.
264  *
265  * @param[in] enable
266  *   true to enable counting, false to disable.
267  ******************************************************************************/
I2C_Enable(I2C_TypeDef * i2c,bool enable)268 void I2C_Enable(I2C_TypeDef *i2c, bool enable)
269 {
270   EFM_ASSERT(I2C_REF_VALID(i2c));
271 
272   BITBAND_Peripheral(&(i2c->CTRL), _I2C_CTRL_EN_SHIFT, (unsigned int)enable);
273 }
274 
275 
276 /***************************************************************************//**
277  * @brief
278  *   Initialize I2C.
279  *
280  * @param[in] i2c
281  *   Pointer to I2C peripheral register block.
282  *
283  * @param[in] init
284  *   Pointer to I2C initialization structure.
285  ******************************************************************************/
I2C_Init(I2C_TypeDef * i2c,const I2C_Init_TypeDef * init)286 void I2C_Init(I2C_TypeDef *i2c, const I2C_Init_TypeDef *init)
287 {
288   EFM_ASSERT(I2C_REF_VALID(i2c));
289 
290   i2c->IEN = 0;
291   i2c->IFC = _I2C_IFC_MASK;
292 
293   I2C_BusFreqSet(i2c, init->refFreq, init->freq, init->clhr);
294 
295   BITBAND_Peripheral(&(i2c->CTRL),
296                      _I2C_CTRL_SLAVE_SHIFT,
297                      ~((unsigned int)(init->master)));
298 
299   BITBAND_Peripheral(&(i2c->CTRL),
300                      _I2C_CTRL_EN_SHIFT,
301                      (unsigned int)(init->enable));
302 }
303 
304 
305 /***************************************************************************//**
306  * @brief
307  *   Reset I2C to same state as after a HW reset.
308  *
309  * @note
310  *   The ROUTE register is NOT reset by this function, in order to allow for
311  *   centralized setup of this feature.
312  *
313  * @param[in] i2c
314  *   Pointer to I2C peripheral register block.
315  ******************************************************************************/
I2C_Reset(I2C_TypeDef * i2c)316 void I2C_Reset(I2C_TypeDef *i2c)
317 {
318   i2c->CTRL      = _I2C_CTRL_RESETVALUE;
319   i2c->CLKDIV    = _I2C_CLKDIV_RESETVALUE;
320   i2c->SADDR     = _I2C_SADDR_RESETVALUE;
321   i2c->SADDRMASK = _I2C_SADDRMASK_RESETVALUE;
322   i2c->IEN       = _I2C_IEN_RESETVALUE;
323   i2c->IFC       = _I2C_IFC_MASK;
324   /* Do not reset route register, setting should be done independently */
325 }
326 
327 
328 /***************************************************************************//**
329  * @brief
330  *   Continue an initiated I2C transfer (single master mode only).
331  *
332  * @details
333  *   This function is used repeatedly after a I2C_TransferInit() in order to
334  *   complete a transfer. It may be used in polled mode as the below example
335  *   shows:
336  * @verbatim
337  * I2C_TransferReturn_TypeDef ret;
338  *
339  * // Do a polled transfer
340  * ret = I2C_TransferInit(I2C0, seq);
341  * while (ret == i2cTransferInProgress)
342  * {
343  *   ret = I2C_Transfer(I2C0);
344  * }
345  * @endverbatim
346  *  It may also be used in interrupt driven mode, where this function is invoked
347  *  from the interrupt handler. Notice that if used in interrupt mode, NVIC
348  *  interrupts must be configured and enabled for the I2C bus used. I2C
349  *  peripheral specific interrupts are managed by this SW.
350  *
351  * @note
352  *   Only single master mode is supported.
353  *
354  * @param[in] i2c
355  *   Pointer to I2C peripheral register block.
356  *
357  * @return
358  *   Returns status for ongoing transfer.
359  *   @li #i2cTransferInProgress - indicates that transfer not finished.
360  *   @li #i2cTransferDone - transfer completed successfully.
361  *   @li otherwise some sort of error has occurred.
362  *
363  ******************************************************************************/
I2C_Transfer(I2C_TypeDef * i2c)364 I2C_TransferReturn_TypeDef I2C_Transfer(I2C_TypeDef *i2c)
365 {
366   uint32_t                tmp;
367   uint32_t                pending;
368   I2C_Transfer_TypeDef    *transfer;
369   I2C_TransferSeq_TypeDef *seq;
370 
371   EFM_ASSERT(I2C_REF_VALID(i2c));
372 
373   /* Support up to 2 I2C buses */
374   if (i2c == I2C0)
375   {
376     transfer = i2cTransfer;
377   }
378 #if (I2C_COUNT > 1)
379   else if (i2c == I2C1)
380   {
381     transfer = i2cTransfer + 1;
382   }
383 #endif
384   else
385   {
386     return(i2cTransferUsageFault);
387   }
388 
389   seq = transfer->seq;
390   for (;; )
391   {
392     pending = i2c->IF;
393 
394     /* If some sort of fault, abort transfer. */
395     if (pending & I2C_IF_ERRORS)
396     {
397       if (pending & I2C_IF_ARBLOST)
398       {
399         /* If arbitration fault, it indicates either a slave device */
400         /* not responding as expected, or other master which is not */
401         /* supported by this SW. */
402         transfer->result = i2cTransferArbLost;
403       }
404       else if (pending & I2C_IF_BUSERR)
405       {
406         /* A bus error indicates a misplaced start or stop, which should */
407         /* not occur in master mode controlled by this SW. */
408         transfer->result = i2cTransferBusErr;
409       }
410 
411       /* If error situation occurred, it is difficult to know */
412       /* exact cause and how to resolve. It will be up to a wrapper */
413       /* to determine how to handle a fault/recovery if possible. */
414       transfer->state = i2cStateDone;
415       goto done;
416     }
417 
418     switch (transfer->state)
419     {
420     /***************************************************/
421     /* Send first start+address (first byte if 10 bit) */
422     /***************************************************/
423     case i2cStateStartAddrSend:
424       if (seq->flags & I2C_FLAG_10BIT_ADDR)
425       {
426         tmp = (((uint32_t)(seq->addr) >> 8) & 0x06) | 0xf0;
427 
428         /* In 10 bit address mode, the address following the first */
429         /* start always indicate write. */
430       }
431       else
432       {
433         tmp = (uint32_t)(seq->addr) & 0xfe;
434 
435         if (seq->flags & I2C_FLAG_READ)
436         {
437           /* Indicate read request */
438           tmp |= 1;
439         }
440       }
441 
442       transfer->state = i2cStateAddrWFAckNack;
443       i2c->TXDATA     = tmp; /* Data not transmitted until START sent */
444       i2c->CMD        = I2C_CMD_START;
445       goto done;
446 
447     /*******************************************************/
448     /* Wait for ACK/NACK on address (first byte if 10 bit) */
449     /*******************************************************/
450     case i2cStateAddrWFAckNack:
451       if (pending & I2C_IF_NACK)
452       {
453         i2c->IFC         = I2C_IFC_NACK;
454         transfer->result = i2cTransferNack;
455         transfer->state  = i2cStateWFStopSent;
456         i2c->CMD         = I2C_CMD_STOP;
457       }
458       else if (pending & I2C_IF_ACK)
459       {
460         i2c->IFC = I2C_IFC_ACK;
461 
462         /* If 10 bit address, send 2nd byte of address. */
463         if (seq->flags & I2C_FLAG_10BIT_ADDR)
464         {
465           transfer->state = i2cStateAddrWF2ndAckNack;
466           i2c->TXDATA     = (uint32_t)(seq->addr) & 0xff;
467         }
468         else
469         {
470           /* Determine whether receiving or sending data */
471           if (seq->flags & I2C_FLAG_READ)
472           {
473             transfer->state = i2cStateWFData;
474           }
475           else
476           {
477             transfer->state = i2cStateDataSend;
478             continue;
479           }
480         }
481       }
482       goto done;
483 
484     /******************************************************/
485     /* Wait for ACK/NACK on second byte of 10 bit address */
486     /******************************************************/
487     case i2cStateAddrWF2ndAckNack:
488       if (pending & I2C_IF_NACK)
489       {
490         i2c->IFC         = I2C_IFC_NACK;
491         transfer->result = i2cTransferNack;
492         transfer->state  = i2cStateWFStopSent;
493         i2c->CMD         = I2C_CMD_STOP;
494       }
495       else if (pending & I2C_IF_ACK)
496       {
497         i2c->IFC = I2C_IFC_ACK;
498 
499         /* If using plain read sequence with 10 bit address, switch to send */
500         /* repeated start. */
501         if (seq->flags & I2C_FLAG_READ)
502         {
503           transfer->state = i2cStateRStartAddrSend;
504         }
505         /* Otherwise expected to write 0 or more bytes */
506         else
507         {
508           transfer->state = i2cStateDataSend;
509         }
510         continue;
511       }
512       goto done;
513 
514     /*******************************/
515     /* Send repeated start+address */
516     /*******************************/
517     case i2cStateRStartAddrSend:
518       if (seq->flags & I2C_FLAG_10BIT_ADDR)
519       {
520         tmp = ((seq->addr >> 8) & 0x06) | 0xf0;
521       }
522       else
523       {
524         tmp = seq->addr & 0xfe;
525       }
526 
527       /* If this is a write+read combined sequence, then read is about to start */
528       if (seq->flags & I2C_FLAG_WRITE_READ)
529       {
530         /* Indicate read request */
531         tmp |= 1;
532       }
533 
534       transfer->state = i2cStateRAddrWFAckNack;
535       /* We have to write START cmd first since repeated start, otherwise */
536       /* data would be sent first. */
537       i2c->CMD    = I2C_CMD_START;
538       i2c->TXDATA = tmp;
539       goto done;
540 
541     /**********************************************************************/
542     /* Wait for ACK/NACK on repeated start+address (first byte if 10 bit) */
543     /**********************************************************************/
544     case i2cStateRAddrWFAckNack:
545       if (pending & I2C_IF_NACK)
546       {
547         i2c->IFC         = I2C_IFC_NACK;
548         transfer->result = i2cTransferNack;
549         transfer->state  = i2cStateWFStopSent;
550         i2c->CMD         = I2C_CMD_STOP;
551       }
552       else if (pending & I2C_IF_ACK)
553       {
554         i2c->IFC = I2C_IFC_ACK;
555 
556         /* Determine whether receiving or sending data */
557         if (seq->flags & I2C_FLAG_WRITE_READ)
558         {
559           transfer->state = i2cStateWFData;
560         }
561         else
562         {
563           transfer->state = i2cStateDataSend;
564           continue;
565         }
566       }
567       goto done;
568 
569     /*****************************/
570     /* Send a data byte to slave */
571     /*****************************/
572     case i2cStateDataSend:
573       /* Reached end of data buffer? */
574       if (transfer->offset >= seq->buf[transfer->bufIndx].len)
575       {
576         /* Move to next message part */
577         transfer->offset = 0;
578         transfer->bufIndx++;
579 
580         /* Send repeated start when switching to read mode on 2nd buffer */
581         if (seq->flags & I2C_FLAG_WRITE_READ)
582         {
583           transfer->state = i2cStateRStartAddrSend;
584           continue;
585         }
586 
587         /* Only writing from one buffer, or finished both buffers */
588         if ((seq->flags & I2C_FLAG_WRITE) || (transfer->bufIndx > 1))
589         {
590           transfer->state = i2cStateWFStopSent;
591           i2c->CMD        = I2C_CMD_STOP;
592           goto done;
593         }
594 
595         /* Reprocess in case next buffer is empty */
596         continue;
597       }
598 
599       /* Send byte */
600       i2c->TXDATA     = (uint32_t)(seq->buf[transfer->bufIndx].data[transfer->offset++]);
601       transfer->state = i2cStateDataWFAckNack;
602       goto done;
603 
604     /*********************************************************/
605     /* Wait for ACK/NACK from slave after sending data to it */
606     /*********************************************************/
607     case i2cStateDataWFAckNack:
608       if (pending & I2C_IF_NACK)
609       {
610         i2c->IFC         = I2C_IFC_NACK;
611         transfer->result = i2cTransferNack;
612         transfer->state  = i2cStateWFStopSent;
613         i2c->CMD         = I2C_CMD_STOP;
614       }
615       else if (pending & I2C_IF_ACK)
616       {
617         i2c->IFC        = I2C_IFC_ACK;
618         transfer->state = i2cStateDataSend;
619         continue;
620       }
621       goto done;
622 
623     /****************************/
624     /* Wait for data from slave */
625     /****************************/
626     case i2cStateWFData:
627       if (pending & I2C_IF_RXDATAV)
628       {
629         uint8_t data;
630 
631         /* Must read out data in order to not block further progress */
632         data = (uint8_t)(i2c->RXDATA);
633 
634         /* Make sure not storing beyond end of buffer just in case */
635         if (transfer->offset < seq->buf[transfer->bufIndx].len)
636         {
637           seq->buf[transfer->bufIndx].data[transfer->offset++] = data;
638         }
639 
640         /* If we have read all requested data, then the sequence should end */
641         if (transfer->offset >= seq->buf[transfer->bufIndx].len)
642         {
643           transfer->state = i2cStateWFStopSent;
644           i2c->CMD        = I2C_CMD_NACK;
645           i2c->CMD        = I2C_CMD_STOP;
646         }
647         else
648         {
649           /* Send ACK and wait for next byte */
650           i2c->CMD = I2C_CMD_ACK;
651         }
652       }
653       goto done;
654 
655     /***********************************/
656     /* Wait for STOP to have been sent */
657     /***********************************/
658     case i2cStateWFStopSent:
659       if (pending & I2C_IF_MSTOP)
660       {
661         i2c->IFC        = I2C_IFC_MSTOP;
662         transfer->state = i2cStateDone;
663       }
664       goto done;
665 
666     /******************************/
667     /* Unexpected state, SW fault */
668     /******************************/
669     default:
670       transfer->result = i2cTransferSwFault;
671       transfer->state  = i2cStateDone;
672       goto done;
673     }
674   }
675 
676  done:
677 
678   if (transfer->state == i2cStateDone)
679   {
680     /* Disable interrupt sources when done */
681     i2c->IEN = 0;
682 
683     /* Update result unless some fault already occurred */
684     if (transfer->result == i2cTransferInProgress)
685     {
686       transfer->result = i2cTransferDone;
687     }
688   }
689   /* Until transfer is done keep returning i2cTransferInProgress */
690   else
691   {
692     return(i2cTransferInProgress);
693   }
694 
695   return transfer->result;
696 }
697 
698 
699 /***************************************************************************//**
700  * @brief
701  *   Prepare and start an I2C transfer (single master mode only).
702  *
703  * @details
704  *   This function must be invoked in order to start an I2C transfer
705  *   sequence. In order to actually complete the transfer, I2C_Transfer() must
706  *   be used either in polled mode or by adding a small driver wrapper utilizing
707  *   interrupts.
708  *
709  * @note
710  *   Only single master mode is supported.
711  *
712  * @param[in] i2c
713  *   Pointer to I2C peripheral register block.
714  *
715  * @param[in] seq
716  *   Pointer to sequence structure defining the I2C transfer to take place. The
717  *   referenced structure must exist until the transfer has fully completed.
718  *
719  * @return
720  *   Returns status for ongoing transfer:
721  *   @li #i2cTransferInProgress - indicates that transfer not finished.
722  *   @li otherwise some sort of error has occurred.
723  ******************************************************************************/
I2C_TransferInit(I2C_TypeDef * i2c,I2C_TransferSeq_TypeDef * seq)724 I2C_TransferReturn_TypeDef I2C_TransferInit(I2C_TypeDef *i2c,
725                                             I2C_TransferSeq_TypeDef *seq)
726 {
727   I2C_Transfer_TypeDef *transfer;
728 
729   EFM_ASSERT(I2C_REF_VALID(i2c));
730   EFM_ASSERT(seq);
731 
732   /* Support up to 2 I2C buses */
733   if (i2c == I2C0)
734   {
735     transfer = i2cTransfer;
736   }
737 #if (I2C_COUNT > 1)
738   else if (i2c == I2C1)
739   {
740     transfer = i2cTransfer + 1;
741   }
742 #endif
743   else
744   {
745     return(i2cTransferUsageFault);
746   }
747 
748   /* Check if in busy state. Since this SW assumes single master, we can */
749   /* just issue an abort. The BUSY state is normal after a reset. */
750   if (i2c->STATE & I2C_STATE_BUSY)
751   {
752     i2c->CMD = I2C_CMD_ABORT;
753   }
754 
755   /* Make sure user is not trying to read 0 bytes, it is not */
756   /* possible according to I2C spec, since slave will always start */
757   /* sending first byte ACK on address. The read operation can */
758   /* only be stopped by NACKing a received byte, ie minimum 1 byte. */
759   if (((seq->flags & I2C_FLAG_READ) && !(seq->buf[0].len)) ||
760       ((seq->flags & I2C_FLAG_WRITE_READ) && !(seq->buf[1].len))
761       )
762   {
763     return(i2cTransferUsageFault);
764   }
765 
766   /* Prepare for a transfer */
767   transfer->state   = i2cStateStartAddrSend;
768   transfer->result  = i2cTransferInProgress;
769   transfer->offset  = 0;
770   transfer->bufIndx = 0;
771   transfer->seq     = seq;
772 
773   /* Ensure buffers are empty */
774   i2c->CMD = I2C_CMD_CLEARPC | I2C_CMD_CLEARTX;
775   if (i2c->IF & I2C_IF_RXDATAV)
776   {
777     i2c->RXDATA;
778   }
779 
780   /* Clear all pending interrupts prior to starting transfer. */
781   i2c->IFC = _I2C_IFC_MASK;
782 
783   /* Enable those interrupts we are interested in throughout transfer. */
784   /* Notice that the I2C interrupt must also be enabled in the NVIC, but */
785   /* that is left for an additional driver wrapper. */
786   i2c->IEN = I2C_IF_NACK | I2C_IF_ACK | I2C_IF_MSTOP |
787              I2C_IF_RXDATAV | I2C_IF_ERRORS;
788 
789   /* Start transfer */
790   return(I2C_Transfer(i2c));
791 }
792 
793 /** @} (end addtogroup I2C) */
794 /** @} (end addtogroup EM_Library) */
795