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