1 /******************************************************************************
2 *
3 * @brief providing APIs for configuring I2C module (I2C).
4 *
5 *******************************************************************************
6 *
7 * provide APIs for configuring I2C module (I2C).
8 ******************************************************************************/
9 #include "common.h"
10 #include "i2c.h"
11 
12 /******************************************************************************
13 * Global variables
14 ******************************************************************************/
15 
16 /******************************************************************************
17 * Constants and macros
18 ******************************************************************************/
19 
20 /******************************************************************************
21 * Local types
22 ******************************************************************************/
23 
24 /******************************************************************************
25 * Local function prototypes
26 ******************************************************************************/
27 
28 /******************************************************************************
29 * Local variables
30 ******************************************************************************/
31 static I2C_CallbackType I2C_Callback[2] = {(I2C_CallbackType)NULL};
32 /******************************************************************************
33 * Local functions
34 ******************************************************************************/
35 void I2C0_Isr( void );
36 
37 /******************************************************************************
38 * Global functions
39 ******************************************************************************/
40 
41 
42 /******************************************************************************
43 * define I2C APIs
44 *
45 *//*! @addtogroup i2c_api_list
46 * @{
47 *******************************************************************************/
48 /*****************************************************************************//*!
49    *
50    * @brief Initialize I2C module.
51    *
52    * @param[in] pI2Cx      point to I2C module type.
53  	 * @param[in] pI2CConfig point to I2C configure structure.
54    *
55    * @return none
56    *
57    * @ Pass/ Fail criteria: none
58 *****************************************************************************/
59 
I2C_Init(I2C_Type * pI2Cx,I2C_ConfigPtr pI2CConfig)60 void I2C_Init(I2C_Type *pI2Cx,I2C_ConfigPtr pI2CConfig)
61 {
62     uint8_t u8Temp;
63 
64 #if defined(CPU_NV32)
65     SIM->SCGC |= SIM_SCGC_IIC_MASK;
66 #elif defined(CPU_NV32M3)
67     SIM->SCGC |= SIM_SCGC_IIC_MASK;
68 #elif defined(CPU_NV32M4)
69     if(pI2Cx == I2C0)
70     {
71         SIM->SCGC |= SIM_SCGC_I2C0_MASK;
72     }
73     else
74     {
75         SIM->SCGC |= SIM_SCGC_I2C1_MASK;
76     }
77 #endif
78 
79 	I2C_SetBaudRate(pI2Cx,pI2CConfig->u16F);
80     I2C_SetSlaveAddress(pI2Cx,pI2CConfig->u16OwnA1);
81     pI2Cx->FLT = (uint8_t)pI2CConfig->u16Filt;
82     pI2Cx->RA = (uint8_t)pI2CConfig->u16RangeA & 0xfe;
83     I2C_SetSCLLowETMeout(pI2Cx,pI2CConfig->u16Slt);
84 
85     /* configure C2 control register */
86     u8Temp = 0;
87     if( pI2CConfig->sSetting.bGCAEn )
88     {
89         u8Temp |= I2C_C2_GCAEN_MASK;
90     }
91     if( pI2CConfig->sSetting.bAddressExt )
92     {
93         u8Temp |= I2C_C2_ADEXT_MASK;
94     }
95     if( pI2CConfig->sSetting.bRangeAddEn )
96     {
97         u8Temp |= I2C_C2_RMEN_MASK;
98     }
99     pI2Cx->C2 |= u8Temp;
100 
101     /* configure SMB rehister */
102     u8Temp = 0;
103     if( pI2CConfig->sSetting.bFackEn )
104     {
105         u8Temp |= I2C_SMB_FACK_MASK;
106     }
107     if( pI2CConfig->sSetting.bSMB_AlertEn )
108     {
109         u8Temp |= I2C_SMB_ALERTEN_MASK;
110     }
111     if( pI2CConfig->sSetting.bSecondAddressEn )
112     {
113         u8Temp |= I2C_SMB_SIICAEN_MASK;
114     }
115     if( pI2CConfig->sSetting.bSHTF2IntEn )
116     {
117         u8Temp |= I2C_SMB_SHTF2IE_MASK;
118     }
119     pI2Cx->SMB = u8Temp;
120 
121     /* configure C1 rehister */
122     u8Temp = 0;
123     if( pI2CConfig->sSetting.bIntEn )
124     {
125         u8Temp |= I2C_C1_IICIE_MASK;
126         if(pI2Cx == I2C0)
127         {
128             NVIC_EnableIRQ(I2C0_IRQn);
129         }
130     #if defined(CPU_NV32M4)
131         else if(pI2Cx == I2C1)
132         {
133             NVIC_EnableIRQ(I2C1_IRQn);
134         }
135     #endif
136         else
137         {
138             //
139         }
140     }
141     if( pI2CConfig->sSetting.bWakeUpEn )
142     {
143         u8Temp |= I2C_C1_WUEN_MASK;
144     }
145     if( pI2CConfig->sSetting.bI2CEn )
146     {
147         u8Temp |= I2C_C1_IICEN_MASK;
148     }
149     pI2Cx->C1 = u8Temp;
150 
151 
152 }
153 /*****************************************************************************//*!
154    *
155    * @brief send out start signals.
156    *
157    * @param[in] pI2Cx      point to I2C module type.
158    *
159    * @return error status
160    *
161    * @ Pass/ Fail criteria: none
162 *****************************************************************************/
I2C_Start(I2C_Type * pI2Cx)163 uint8_t I2C_Start(I2C_Type *pI2Cx)
164 {
165     uint32_t u32ETMeout;
166     uint8_t u8ErrorStatus;
167 
168     u32ETMeout = 0;
169     u8ErrorStatus = 0x00;
170 
171     I2C_TxEnable(pI2Cx);
172     pI2Cx->C1 |= I2C_C1_MST_MASK;
173 
174     while( (!I2C_IsBusy(pI2Cx)) && ( u32ETMeout < I2C_WAIT_STATUS_ETMEOUT))
175      {
176         u32ETMeout ++;
177      }
178 
179      if( u32ETMeout == I2C_WAIT_STATUS_ETMEOUT )
180      {
181         u8ErrorStatus |= I2C_ERROR_START_NO_BUSY_FLAG;
182      }
183 
184      return u8ErrorStatus;
185 }
186 
187 /*****************************************************************************//*!
188    *
189    * @brief send out stop signals.
190    *
191    * @param[in] pI2Cx      point to I2C module type.
192    *
193    * @return error status
194    *
195    * @ Pass/ Fail criteria: none
196 *****************************************************************************/
I2C_Stop(I2C_Type * pI2Cx)197 uint8_t I2C_Stop(I2C_Type *pI2Cx)
198 {
199     uint32_t u32ETMeout;
200     uint8_t u8ErrorStatus;
201 
202     u32ETMeout = 0;
203     u8ErrorStatus = 0x00;
204 
205     pI2Cx->C1 &= ~I2C_C1_MST_MASK;
206 
207     while( (I2C_IsBusy(pI2Cx) ) && ( u32ETMeout < I2C_WAIT_STATUS_ETMEOUT))
208      {
209         u32ETMeout ++;
210      }
211 
212      if( u32ETMeout == I2C_WAIT_STATUS_ETMEOUT )
213      {
214         u8ErrorStatus |= I2C_ERROR_STOP_BUSY_FLAG;
215      }
216 
217      return u8ErrorStatus;
218 }
219 
220 
221 /*****************************************************************************//*!
222    *
223    * @brief send out repeat start signals.
224    *
225    * @param[in] pI2Cx      point to I2C module type.
226    *
227    * @return error status.
228    *
229    * @ Pass/ Fail criteria: none
230 *****************************************************************************/
I2C_RepeatStart(I2C_Type * pI2Cx)231 uint8_t I2C_RepeatStart(I2C_Type *pI2Cx)
232 {
233     uint32_t u32ETMeout;
234     uint8_t u8ErrorStatus;
235 
236     u32ETMeout = 0;
237     u8ErrorStatus = 0x00;
238 
239     pI2Cx->C1 |= I2C_C1_RSTA_MASK;
240 
241     while( (!I2C_IsBusy(I2C0) ) && ( u32ETMeout < I2C_WAIT_STATUS_ETMEOUT))
242      {
243         u32ETMeout ++;
244      }
245 
246      if( u32ETMeout == I2C_WAIT_STATUS_ETMEOUT )
247      {
248         u8ErrorStatus |= I2C_ERROR_START_NO_BUSY_FLAG;
249      }
250 
251      return u8ErrorStatus;
252 }
253 
254 /*****************************************************************************//*!
255    *
256    * @brief set slave address.
257    *
258    * @param[in] pI2Cx      point to I2C module type.
259    *
260    * @return none
261    *
262    * @ Pass/ Fail criteria: none
263 *****************************************************************************/
I2C_SetSlaveAddress(I2C_Type * pI2Cx,uint16_t u16SlaveAddress)264 void I2C_SetSlaveAddress(I2C_Type *pI2Cx,uint16_t u16SlaveAddress)
265 {
266     /* write low 8bit address */
267     pI2Cx->A1 = (uint8_t)u16SlaveAddress;
268 
269     /* write high 3bit address if it support 10bit slave address */
270     pI2Cx->C2 &= ~I2C_C2_AD_MASK;
271     pI2Cx->C2 |= (uint8_t)(u16SlaveAddress>>8)&0x03;
272 }
273 
274 /*****************************************************************************//*!
275    *
276    * @brief disable IICIF interrupt.
277    *
278    * @param[in] pI2Cx      point to I2C module type.
279    *
280    * @return none.
281    *
282    * @ Pass/ Fail criteria: none
283 *****************************************************************************/
I2C_IntDisable(I2C_Type * pI2Cx)284 void I2C_IntDisable(I2C_Type *pI2Cx)
285 {
286     pI2Cx->C1 &= ~I2C_C1_IICIE_MASK;
287     if(pI2Cx == I2C0)
288     {
289         NVIC_DisableIRQ(I2C0_IRQn);
290     }
291     #if defined(CPU_NV32M4)
292     else if(pI2Cx == I2C1)
293     {
294         NVIC_DisableIRQ(I2C1_IRQn);
295     }
296     #endif
297     else
298     {
299 
300     }
301 }
302 /*****************************************************************************//*!
303    *
304    * @brief enable IICIF interrupt.
305    *
306    * @param[in] pI2Cx      point to I2C module type.
307    *
308    * @return none.
309    *
310    * @ Pass/ Fail criteria: none.
311 *****************************************************************************/
I2C_IntEnable(I2C_Type * pI2Cx)312 void I2C_IntEnable(I2C_Type *pI2Cx)
313 {
314     pI2Cx->C1 |= I2C_C1_IICIE_MASK;
315     if(pI2Cx == I2C0)
316     {
317         NVIC_EnableIRQ(I2C0_IRQn);
318     }
319     #if defined(CPU_NV32M4)
320     else if(pI2Cx == I2C1)
321     {
322         NVIC_EnableIRQ(I2C1_IRQn);
323     }
324     #endif
325     else
326     {
327 
328     }
329 }
330 
331 /*****************************************************************************//*!
332    *
333    * @brief SCL low ETMeout value that determines the ETMeout period of SCL low.
334    *
335    * @param[in] pI2Cx      point to I2C module type.
336    *
337    * @return none.
338    *
339    * @ Pass/ Fail criteria: none.
340 *****************************************************************************/
I2C_SetSCLLowETMeout(I2C_Type * pI2Cx,uint16_t u16ETMeout)341 void I2C_SetSCLLowETMeout(I2C_Type *pI2Cx, uint16_t u16ETMeout)
342 {
343     pI2Cx->SLTL = (uint8_t)u16ETMeout;
344     pI2Cx->SLTH = (uint8_t)(u16ETMeout>>8);
345 }
346 /*****************************************************************************//*!
347    *
348    * @brief deinit I2C module.
349    *
350    * @param[in] pI2Cx    point to I2C module type.
351    *
352    * @return none
353    *
354    * @ Pass/ Fail criteria: none
355 *****************************************************************************/
I2C_Deinit(I2C_Type * pI2Cx)356 void I2C_Deinit(I2C_Type *pI2Cx)
357 {
358      pI2Cx->C1 &= ~I2C_C1_IICEN_MASK;
359 #if defined(CPU_NV32)
360     SIM->SCGC &= ~SIM_SCGC_IIC_MASK;
361 #elif defined(CPU_NV32M3)
362     SIM->SCGC &= ~SIM_SCGC_IIC_MASK;
363 #elif defined(CPU_NV32M4)
364     if(pI2Cx == I2C0)
365     {
366         SIM->SCGC &= ~SIM_SCGC_I2C0_MASK;
367     }
368     else
369     {
370         SIM->SCGC &= ~SIM_SCGC_I2C1_MASK;
371     }
372 #endif
373 }
374 
375 /*****************************************************************************//*!
376    *
377    * @brief write a byte to I2C module.
378    *
379    * @param[in] pI2Cx    point to I2C module type.
380    * @param[in] u8WrBuff  data buffer for writing.
381    *
382    * @return error status
383    *
384    * @ Pass/ Fail criteria: none
385 *****************************************************************************/
386 
I2C_WriteOneByte(I2C_Type * pI2Cx,uint8_t u8WrBuff)387 uint8_t I2C_WriteOneByte(I2C_Type *pI2Cx, uint8_t u8WrBuff)
388 {
389     uint32_t u32ETMeout;
390     uint8_t u8ErrorStatus;
391 
392     u32ETMeout = 0;
393     u8ErrorStatus = 0x00;
394     while (((I2C_GetStatus(pI2Cx)&I2C_S_TCF_MASK) !=  I2C_S_TCF_MASK)
395             && (u32ETMeout<I2C_WAIT_STATUS_ETMEOUT))
396     {
397         u32ETMeout ++;
398     }
399     if (u32ETMeout >= I2C_WAIT_STATUS_ETMEOUT)
400     {
401         u8ErrorStatus |= I2C_ERROR_NO_WAIT_TCF_FLAG;
402         return u8ErrorStatus;
403     }
404 
405     I2C_TxEnable(pI2Cx);
406     I2C_WriteDataReg(pI2Cx,u8WrBuff);
407 
408     u32ETMeout = 0;
409     while (((I2C_GetStatus(pI2Cx)&I2C_S_IICIF_MASK) !=  I2C_S_IICIF_MASK)
410             && (u32ETMeout<I2C_WAIT_STATUS_ETMEOUT))
411     {
412         u32ETMeout ++;
413     }
414     if (u32ETMeout >= I2C_WAIT_STATUS_ETMEOUT)
415     {
416         u8ErrorStatus |= I2C_ERROR_NO_WAIT_IICIF_FLAG;
417         return u8ErrorStatus;
418     }
419 
420     /* clear IICIF flag */
421     I2C_ClearStatus(pI2Cx,I2C_S_IICIF_MASK);
422     if (I2C_GetStatus(pI2Cx) & I2C_S_RXAK_MASK)
423     {
424         u8ErrorStatus |= I2C_ERROR_NO_GET_ACK;
425     }
426     return u8ErrorStatus;
427 }
428 /*****************************************************************************//*!
429    *
430    * @brief read a byte from slave I2C.
431    *
432    * @param[in] pI2Cx    point to I2C module type.
433    * @param[out] pRdBuff point to the data read from slave I2C.
434    * @param[out] u8Ack   send out ack or nack.
435    *
436    * @return error status
437    *
438    * @ Pass/ Fail criteria:  none
439 *****************************************************************************/
440 
I2C_ReadOneByte(I2C_Type * pI2Cx,uint8_t * pRdBuff,uint8_t u8Ack)441 uint8_t I2C_ReadOneByte(I2C_Type *pI2Cx, uint8_t *pRdBuff, uint8_t u8Ack)
442 {
443     uint32_t u32ETMeout;
444     uint8_t u8ErrorStatus;
445 
446     u32ETMeout = 0;
447     u8ErrorStatus = 0x00;
448     while (((I2C_GetStatus(pI2Cx)&I2C_S_TCF_MASK) !=  I2C_S_TCF_MASK)
449             && (u32ETMeout<I2C_WAIT_STATUS_ETMEOUT))
450     {
451         u32ETMeout ++;
452     }
453     if (u32ETMeout >= I2C_WAIT_STATUS_ETMEOUT)
454     {
455         u8ErrorStatus |= I2C_ERROR_NO_WAIT_TCF_FLAG;
456         return u8ErrorStatus;
457     }
458 
459     I2C_RxEnable(pI2Cx);
460 
461     if( u8Ack )
462     {
463         /* send out nack */
464         I2C_SendNack(pI2Cx);
465 
466     }
467     else
468     {
469          /* send out ack */
470         I2C_SendAck(pI2Cx);
471     }
472     *pRdBuff = I2C_ReadDataReg(pI2Cx);
473 
474     u32ETMeout = 0;
475     while (((I2C_GetStatus(pI2Cx)&I2C_S_IICIF_MASK) !=  I2C_S_IICIF_MASK)
476             && (u32ETMeout<I2C_WAIT_STATUS_ETMEOUT))
477     {
478         u32ETMeout ++;
479     }
480     if (u32ETMeout >= I2C_WAIT_STATUS_ETMEOUT)
481     {
482         u8ErrorStatus |= I2C_ERROR_NO_WAIT_IICIF_FLAG;
483         return u8ErrorStatus;
484     }
485 
486     /* clear IICIF flag */
487     I2C_ClearStatus(pI2Cx,I2C_S_IICIF_MASK);
488 
489     return u8ErrorStatus;
490 }
491 /*****************************************************************************//*!
492    *
493    * @brief send data to I2C, and wait to complete transfering.
494    *
495    * @param[in]  pI2Cx    point to I2C module type.
496    * @param[in]  u16SlaveAddress slave address.
497    * @param[in]  pWrBuff point the first address of transfering data buffer.
498    * @param[in]  the length of transfering data.
499    *
500    * @return error status
501    *
502    * @ Pass/ Fail criteria:  none
503 *****************************************************************************/
504 
I2C_MasterSendWait(I2C_Type * pI2Cx,uint16_t u16SlaveAddress,uint8_t * pWrBuff,uint32_t u32Length)505 uint8_t I2C_MasterSendWait(I2C_Type *pI2Cx,uint16_t u16SlaveAddress,uint8_t *pWrBuff,uint32_t u32Length)
506 {
507     uint32_t i;
508     uint8_t u8ErrorStatus;
509 
510     /* send start signals to bus */
511     u8ErrorStatus = I2C_Start(pI2Cx);
512 
513     /* send device address to slave */
514     u8ErrorStatus = I2C_WriteOneByte(pI2Cx,((uint8_t)u16SlaveAddress<<1) | I2C_WRITE);
515 
516     /* if no error occur, received the correct ack from slave
517             continue to send data to slave
518         */
519     if( u8ErrorStatus == I2C_ERROR_NULL )
520     {
521         for(i=0;i<u32Length;i++)
522         {
523             u8ErrorStatus = I2C_WriteOneByte(pI2Cx,pWrBuff[i]);
524             if( u8ErrorStatus != I2C_ERROR_NULL )
525             {
526                 return u8ErrorStatus;
527             }
528         }
529      }
530 
531      /* send stop signals to bus */
532      u8ErrorStatus = I2C_Stop(pI2Cx);
533 
534      return u8ErrorStatus;
535 
536 }
537 /*****************************************************************************//*!
538    *
539    * @brief read data from I2C,and wait to complete transferring.
540    *
541    * @param[in] pI2Cx    point to I2C module type.
542    * @param[in]  u16SlaveAddress slave address.
543    * @param[in]  pRdBuff point the first address of reading data buffer.
544    * @param[in]  the length of transfering data.
545    *
546    * @return error status
547    *
548    * @ Pass/ Fail criteria:  none
549 *****************************************************************************/
550 
I2C_MasterReadWait(I2C_Type * pI2Cx,uint16_t u16SlaveAddress,uint8_t * pRdBuff,uint32_t u32Length)551 uint8_t I2C_MasterReadWait(I2C_Type *pI2Cx,uint16_t u16SlaveAddress,uint8_t *pRdBuff,uint32_t u32Length)
552 {
553     uint32_t i;
554     uint8_t u8ErrorStatus;
555 
556     /* send start signals to bus */
557     u8ErrorStatus = I2C_Start(pI2Cx);
558 
559     /* send device address to slave */
560     u8ErrorStatus = I2C_WriteOneByte(pI2Cx,((uint8_t)u16SlaveAddress<<1) | I2C_READ);
561 
562     /* if no error occur, received the correct ack from slave
563             continue to send data to slave
564         */
565     /* dummy read one byte to switch to Rx mode */
566     I2C_ReadOneByte(pI2Cx,&pRdBuff[0],I2C_SEND_ACK);
567 
568     if( u8ErrorStatus == I2C_ERROR_NULL )
569     {
570         for(i=0;i<u32Length-1;i++)
571         {
572             u8ErrorStatus = I2C_ReadOneByte(pI2Cx,&pRdBuff[i],I2C_SEND_ACK);
573             if( u8ErrorStatus != I2C_ERROR_NULL )
574             {
575                 return u8ErrorStatus;
576             }
577         }
578         u8ErrorStatus = I2C_ReadOneByte(pI2Cx,&pRdBuff[i],I2C_SEND_NACK);
579      }
580      /* send stop signals to bus */
581      u8ErrorStatus = I2C_Stop(pI2Cx);
582 
583      return u8ErrorStatus;
584 
585 }
586 /*****************************************************************************//*!
587    *
588    * @brief set call back function for I2C1 module.
589    *
590    * @param[in] pCallBack point to address of I2C1 call back function.
591    *
592    * @return none.
593    *
594    * @ Pass/ Fail criteria:  none.
595 *****************************************************************************/
596 
I2C1_SetCallBack(I2C_CallbackType pCallBack)597 void I2C1_SetCallBack( I2C_CallbackType pCallBack )
598 {
599     I2C_Callback[1] = pCallBack;
600 }
601 
602 /*****************************************************************************//*!
603    *
604    * @brief set call back function for I2C0 module.
605    *
606    * @param[in] pCallBack point to address of I2C0 call back function.
607    *
608    * @return none.
609    *
610    * @ Pass/ Fail criteria:  none.
611 *****************************************************************************/
612 
I2C0_SetCallBack(I2C_CallbackType pCallBack)613 void I2C0_SetCallBack( I2C_CallbackType pCallBack )
614 {
615     I2C_Callback[0] = pCallBack;
616 }
617 /*! @} End of i2c_api_list                                               						*/
618 
619 
620 /*****************************************************************************//*!
621    *
622    * @brief I2C0 interrupt service routine.
623    *
624    * @param
625    *
626    * @return none
627    *
628    * @ Pass/ Fail criteria:  none
629 *****************************************************************************/
I2C0_Isr(void)630 void I2C0_Isr( void )
631 {
632     if( I2C_Callback[0] )
633     {
634         I2C_Callback[0]();
635     }
636 }
637 /*****************************************************************************//*!
638    *
639    * @brief I2C1 interrupt service routine.
640    *
641    * @param
642    *
643    * @return none
644    *
645    * @ Pass/ Fail criteria:  none
646 *****************************************************************************/
I2C1_Isr(void)647 void I2C1_Isr( void )
648 {
649     if( I2C_Callback[1] )
650     {
651         I2C_Callback[1]();
652     }
653 }
654 
655 
656 
657