1 /*************************************************************************************
2 * Copyright (C) 2017, Huada Semiconductor Co.,Ltd All rights reserved.
3 *
4 * This software is owned and published by:
5 * Huada Semiconductor Co.,Ltd ("HDSC").
6 *
7 * BY DOWNLOADING, INSTALLING OR USING THIS SOFTWARE, YOU AGREE TO BE BOUND
8 * BY ALL THE TERMS AND CONDITIONS OF THIS AGREEMENT.
9 *
10 * This software contains source code for use with HDSC
11 * components. This software is licensed by HDSC to be adapted only
12 * for use in systems utilizing HDSC components. HDSC shall not be
13 * responsible for misuse or illegal use of this software for devices not
14 * supported herein. HDSC is providing this software "AS IS" and will
15 * not be responsible for issues arising from incorrect user implementation
16 * of the software.
17 *
18 * Disclaimer:
19 * HDSC MAKES NO WARRANTY, EXPRESS OR IMPLIED, ARISING BY LAW OR OTHERWISE,
20 * REGARDING THE SOFTWARE (INCLUDING ANY ACOOMPANYING WRITTEN MATERIALS),
21 * ITS PERFORMANCE OR SUITABILITY FOR YOUR INTENDED USE, INCLUDING,
22 * WITHOUT LIMITATION, THE IMPLIED WARRANTY OF MERCHANTABILITY, THE IMPLIED
23 * WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE OR USE, AND THE IMPLIED
24 * WARRANTY OF NONINFRINGEMENT.
25 * HDSC SHALL HAVE NO LIABILITY (WHETHER IN CONTRACT, WARRANTY, TORT,
26 * NEGLIGENCE OR OTHERWISE) FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT
27 * LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION,
28 * LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING FROM USE OR
29 * INABILITY TO USE THE SOFTWARE, INCLUDING, WITHOUT LIMITATION, ANY DIRECT,
30 * INDIRECT, INCIDENTAL, SPECIAL OR CONSEQUENTIAL DAMAGES OR LOSS OF DATA,
31 * SAVINGS OR PROFITS,
32 * EVEN IF Disclaimer HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
33 * YOU ASSUME ALL RESPONSIBILITIES FOR SELECTION OF THE SOFTWARE TO ACHIEVE YOUR
34 * INTENDED RESULTS, AND FOR THE INSTALLATION OF, USE OF, AND RESULTS OBTAINED
35 * FROM, THE SOFTWARE.
36 *
37 * This software may be replicated in part or whole for the licensed use,
38 * with the restriction that this Disclaimer and Copyright notice must be
39 * included with each copy of this software, whether used in part or whole,
40 * at all times.
41 */
42 /******************************************************************************/
43 /** \file I2C.c
44  **
45  ** WDT function driver API.
46  ** @link SampleGroup Some description @endlink
47  **
48  **   - 2018-03-13  1.0  CJ First version for Device Driver Library of Module.
49  **
50  ******************************************************************************/
51 
52 /******************************************************************************/
53 /* Include files                                                              */
54 /******************************************************************************/
55 #include "i2c.h"
56 
57 /**
58  *******************************************************************************
59  ** \addtogroup I2cGroup
60  ******************************************************************************/
61 //@{
62 
63 /******************************************************************************/
64 /* Local function prototypes ('static')                                       */
65 /******************************************************************************/
66 static func_ptr_t pfnI2c0tCallback = NULL;
67 static func_ptr_t pfnI2c1tCallback = NULL;
68 /**
69  ******************************************************************************
70  ** \brief  I2C设置波特率配置寄存器
71  **
72  ** \param [in] u8Tm 波特率配置值
73  **
74  ** \retval enRet 成功或失败
75  **
76  ******************************************************************************/
I2C_SetBaud(en_i2c_channel_t enCh,uint8_t u8Tm)77  en_result_t I2C_SetBaud(en_i2c_channel_t enCh,uint8_t u8Tm)
78  {
79      en_result_t enRet = Error;
80      if(I2C0 == enCh)
81      {
82         M0P_I2C0->TM = u8Tm;
83      }
84      else
85      {
86         M0P_I2C1->TM = u8Tm;
87      }
88 
89      enRet = Ok;
90      return enRet;
91  }
92  /**
93  ******************************************************************************
94  ** \brief  I2C功能设置相关函数
95  **
96  ** \param [in] enFunc功能参数
97  **
98  ** \retval enRet 成功或失败
99  **
100  ******************************************************************************/
I2C_SetFunc(en_i2c_channel_t enCh,en_i2c_func_t enFunc)101 en_result_t I2C_SetFunc(en_i2c_channel_t enCh,en_i2c_func_t enFunc)
102 {
103     en_result_t enRet = Error;
104     if(I2C0 == enCh)
105     {
106         switch(enFunc)
107         {
108             case I2cMode_En:
109                 M0P_I2C0->CR_f.ENS = 1;
110                 break;
111             case I2cStart_En:
112                 M0P_I2C0->CR_f.STA = 1;
113                 break;
114             case I2cStop_En:
115                 M0P_I2C0->CR_f.STO = 1;
116                 break;
117             case I2cAck_En:
118                 M0P_I2C0->CR_f.AA = 1;
119                 break;
120             case I2cHlm_En:
121                 M0P_I2C0->CR_f.H1M = 1;
122                 break;
123             case I2cBaud_En:
124                 M0P_I2C0->TMRUN = 0x01;
125                 break;
126             default:
127                 return ErrorInvalidParameter;
128         }
129     }
130     else
131     {
132         switch(enFunc)
133         {
134             case I2cMode_En:
135                 M0P_I2C1->CR_f.ENS = 1;
136                 break;
137             case I2cStart_En:
138                 M0P_I2C1->CR_f.STA = 1;
139                 break;
140             case I2cStop_En:
141                 M0P_I2C1->CR_f.STO = 1;
142                 break;
143             case I2cAck_En:
144                 M0P_I2C1->CR_f.AA = 1;
145                 break;
146             case I2cHlm_En:
147                 M0P_I2C1->CR_f.H1M = 1;
148                 break;
149             case I2cBaud_En:
150                 M0P_I2C1->TMRUN = 0x01;
151                 break;
152             default:
153                 return ErrorInvalidParameter;
154         }
155     }
156 
157     enRet = Ok;
158     return enRet;
159 }
160  /**
161  ******************************************************************************
162  ** \brief  I2C功能清除相关函数
163  **
164  ** \param [in] enFunc功能参数
165  **
166  ** \retval enRet 成功或失败
167  **
168  ******************************************************************************/
I2C_ClearFunc(en_i2c_channel_t enCh,en_i2c_func_t enFunc)169  en_result_t I2C_ClearFunc(en_i2c_channel_t enCh,en_i2c_func_t enFunc)
170  {
171     en_result_t enRet = Error;
172     if(I2C0 == enCh)
173     {
174         switch(enFunc)
175         {
176             case I2cMode_En:
177                 M0P_I2C0->CR_f.ENS = 0;
178                 break;
179             case I2cStart_En:
180                 M0P_I2C0->CR_f.STA = 0;
181                 break;
182             case I2cStop_En:
183                 M0P_I2C0->CR_f.STO = 0;
184                 break;
185             case I2cAck_En:
186                 M0P_I2C0->CR_f.AA = 0;
187                 break;
188             case I2cHlm_En:
189                 M0P_I2C0->CR_f.H1M = 0;
190                 break;
191             case I2cBaud_En:
192                 M0P_I2C0->TMRUN = 0x00;
193                 break;
194             default:
195                 return ErrorInvalidParameter;
196         }
197     }
198     else
199     {
200         switch(enFunc)
201         {
202             case I2cMode_En:
203                 M0P_I2C1->CR_f.ENS = 0;
204                 break;
205             case I2cStart_En:
206                 M0P_I2C1->CR_f.STA = 0;
207                 break;
208             case I2cStop_En:
209                 M0P_I2C1->CR_f.STO = 0;
210                 break;
211             case I2cAck_En:
212                 M0P_I2C1->CR_f.AA = 0;
213                 break;
214             case I2cHlm_En:
215                 M0P_I2C1->CR_f.H1M = 0;
216                 break;
217             case I2cBaud_En:
218                 M0P_I2C1->TMRUN = 0x00;
219                 break;
220             default:
221                 return ErrorInvalidParameter;
222         }
223     }
224     enRet = Ok;
225     return enRet;
226  }
227  /**
228  ******************************************************************************
229  ** \brief  I2C获取中断标记函数
230  **
231  ** \param 无
232  **
233  ** \retval bIrq中断标记
234  **
235  ******************************************************************************/
I2C_GetIrq(en_i2c_channel_t enCh)236 boolean_t I2C_GetIrq(en_i2c_channel_t enCh)
237 {
238     boolean_t bIrq = FALSE;
239     if(I2C0 == enCh)
240     {
241         bIrq = M0P_I2C0->CR_f.SI;
242     }
243     else
244     {
245         bIrq = M0P_I2C1->CR_f.SI;
246     }
247 
248     return bIrq;
249 }
250 /**
251  ******************************************************************************
252  ** \brief  I2C清除中断标记函数
253  **
254  ** \param 无
255  **
256  ** \retval bIrq中断标记
257  **
258  ******************************************************************************/
I2C_ClearIrq(en_i2c_channel_t enCh)259 en_result_t I2C_ClearIrq(en_i2c_channel_t enCh)
260 {
261     en_result_t enRet = Error;
262     if(I2C0 == enCh)
263     {
264        M0P_I2C0->CR_f.SI = 0;
265     }
266     else
267     {
268        M0P_I2C1->CR_f.SI = 0;
269     }
270     enRet = Ok;
271     return enRet;
272 }
273  /**
274  ******************************************************************************
275  ** \brief  I2C获取相关状态
276  **
277  ** \param 无
278  **
279  ** \retval I2C状态
280  **
281  ******************************************************************************/
I2C_GetState(en_i2c_channel_t enCh)282 uint8_t I2C_GetState(en_i2c_channel_t enCh)
283 {
284     uint8_t u8State = 0;
285     if(I2C0 == enCh)
286     {
287         u8State = M0P_I2C0->STAT;
288     }
289     else
290     {
291         u8State = M0P_I2C1->STAT;
292     }
293     return u8State;
294 }
295 /**
296  ******************************************************************************
297  ** \brief  I2C写从机地址函数
298  **
299  ** \param u8SlaveAddr从机地址
300  **
301  ** \retval I2C写成功与否状态
302  **
303  ******************************************************************************/
I2C_WriteSlaveAddr(en_i2c_channel_t enCh,stc_i2c_addr_t * pstcSlaveAddr)304  en_result_t I2C_WriteSlaveAddr(en_i2c_channel_t enCh,stc_i2c_addr_t *pstcSlaveAddr)
305 {
306     en_result_t enRet = Error;
307     if(I2C0 == enCh)
308     {
309         M0P_I2C0->ADDR_f.ADR = pstcSlaveAddr->Addr;
310         M0P_I2C0->ADDR_f.GC = pstcSlaveAddr->Gc;
311     }
312     else
313     {
314         M0P_I2C1->ADDR_f.ADR = pstcSlaveAddr->Addr;
315         M0P_I2C1->ADDR_f.GC = pstcSlaveAddr->Gc;
316     }
317 
318     enRet = Ok;
319     return enRet;
320 }
321 /**
322  ******************************************************************************
323  ** \brief  字节写从机函数
324  **
325  ** \param u8Data写数据
326  **
327  ** \retval 写数据是否成功
328  **
329  ******************************************************************************/
I2C_WriteByte(en_i2c_channel_t enCh,uint8_t u8Data)330 en_result_t I2C_WriteByte(en_i2c_channel_t enCh,uint8_t u8Data)
331 {
332     en_result_t enRet = Error;
333     if(I2C0 == enCh)
334     {
335         M0P_I2C0->DATA = u8Data;
336     }
337     else
338     {
339         M0P_I2C1->DATA = u8Data;
340     }
341     enRet = Ok;
342     return enRet;
343 }
344 /**
345  ******************************************************************************
346  ** \brief  字节读从机函数
347  **
348  ** \param 无
349  **
350  ** \retval 读取数据
351  **
352  ******************************************************************************/
I2C_ReadByte(en_i2c_channel_t enCh)353 uint8_t I2C_ReadByte(en_i2c_channel_t enCh)
354 {
355     uint8_t u8Data = 0;
356     if(I2C0 == enCh)
357     {
358        u8Data = M0P_I2C0->DATA;
359     }
360     else
361     {
362        u8Data = M0P_I2C1->DATA;
363     }
364     return u8Data;
365 }
366  /**
367  ******************************************************************************
368  ** \brief  主机发送函数
369  **
370  ** \param u8Addr从机内存地址,pu8Data写数据,u32Len写数据长度
371  **
372  ** \retval 写数据是否成功
373  **
374  ******************************************************************************/
I2C_MasterWriteData(en_i2c_channel_t enCh,uint8_t u8DevAddr,uint8_t u8Addr,uint8_t * pu8Data,uint32_t u32Len)375 en_result_t I2C_MasterWriteData(en_i2c_channel_t enCh,uint8_t u8DevAddr,uint8_t u8Addr,uint8_t *pu8Data,uint32_t u32Len)
376 {
377     en_result_t enRet = Error;
378     uint8_t u8i=0,u8State;
379 
380     I2C_SetFunc(enCh,I2cStart_En);
381 	while(1)
382 	{
383 		while(0 == I2C_GetIrq(enCh))
384 		{}
385 		u8State = I2C_GetState(enCh);
386 		switch(u8State)
387 		{
388 			case 0x08:
389 				I2C_ClearFunc(enCh,I2cStart_En);
390 				I2C_WriteByte(enCh,u8DevAddr);//从设备地址发送
391 				break;
392 			case 0x18:
393 				I2C_WriteByte(enCh,u8Addr);//从设备内存地址发送
394 				break;
395 			case 0x28:
396 				I2C_WriteByte(enCh,pu8Data[u8i++]);
397 				break;
398 			case 0x20:
399 			case 0x38:
400 				I2C_SetFunc(enCh,I2cStart_En);
401 				break;
402 			case 0x30:
403 				I2C_SetFunc(enCh,I2cStop_En);
404 				break;
405 			default:
406 				break;
407 		}
408 		if(u8i>u32Len)
409 		{
410 			I2C_SetFunc(enCh,I2cStop_En);//此顺序不能调换,出停止条件
411 			I2C_ClearIrq(enCh);
412 			break;
413 		}
414 		I2C_ClearIrq(enCh);
415 	}
416     enRet = Ok;
417     return enRet;
418 }
419  /**
420  ******************************************************************************
421  ** \brief  从机发送函数
422  **
423  ** \param pu8Data发送数据缓存,u32Len发送数据长度
424  **
425  ** \retval 发送数据是否成功
426  **
427  ******************************************************************************/
I2C_SlaveWriteData(en_i2c_channel_t enCh,uint8_t * pu8Data,uint32_t * u32Len)428  en_result_t I2C_SlaveWriteData(en_i2c_channel_t enCh,uint8_t *pu8Data,uint32_t *u32Len)
429  {
430     uint8_t u8i=0,u8State;
431     //
432     while(1)
433     {
434 
435         while(0 == I2C_GetIrq(enCh))
436         {}
437         u8State = I2C_GetState(enCh);
438         switch(u8State)
439         {
440             case 0xA8:
441             case 0xB0:
442                 I2C_WriteByte(enCh,pu8Data[u8i++]);
443                 break;
444             case 0xB8:
445             case 0xC8:
446                 I2C_WriteByte(enCh,pu8Data[u8i++]);
447                 break;
448             case 0xF8:
449                 *u32Len = u8i;
450                 break;
451             default:
452 
453                 return ErrorInvalidParameter;
454         }
455 		I2C_ClearIrq(enCh);
456     }
457  }
458  /**
459  ******************************************************************************
460  ** \brief  从机接收函数
461  **
462  ** \param pu8Data接收数据存放缓存,u32Len接收数据指针
463  **
464  ** \retval 接收数据是否成功
465  **
466  ******************************************************************************/
I2C_SlaveReadData(en_i2c_channel_t enCh,uint8_t * pu8Data,uint32_t * pu32Len)467 en_result_t I2C_SlaveReadData(en_i2c_channel_t enCh,uint8_t *pu8Data,uint32_t *pu32Len)
468 {
469     uint8_t u8i=0,u8State;
470     while(0 == I2C_GetIrq(enCh))
471     {}
472     while(1)
473    {
474         while(0 == I2C_GetIrq(enCh))
475         {}
476         u8State = I2C_GetState(enCh);
477         switch(u8State)
478         {
479             case 0x60:
480             case 0x68:
481             case 0x70:
482             case 0x78:
483               break;
484             case 0x80:
485             case 0x90:
486                 pu8Data[u8i++] = I2C_ReadByte(enCh);
487                 break;
488             case 0xA0:
489                 *pu32Len = u8i;
490                 break;
491             default:
492                 return ErrorInvalidParameter;
493         }
494 		I2C_ClearIrq(enCh);
495         if(0xA0 == u8State)
496         {
497           return Ok;
498         }
499    }
500 }
501 
502 /**
503  ******************************************************************************
504  ** \brief  主机接收函数
505  **
506  ** \param u8Addr从机内存地址,pu8Data读数据存放缓存,u32Len读数据长度
507  **
508  ** \retval 读数据是否成功
509  **
510  ******************************************************************************/
I2C_MasterReadData(en_i2c_channel_t enCh,uint8_t u8DevAddr,uint8_t * pu8Data,uint8_t u8Addr,uint32_t u32Len)511  en_result_t I2C_MasterReadData(en_i2c_channel_t enCh,uint8_t u8DevAddr,uint8_t *pu8Data,uint8_t u8Addr,uint32_t u32Len)
512 {
513     en_result_t enRet = Error;
514     uint8_t u8i=0,u8State;
515 
516     I2C_SetFunc(enCh,I2cStart_En);
517 
518 	while(1)
519 	{
520 		while(0 == I2C_GetIrq(enCh))
521         {}
522 		u8State = I2C_GetState(enCh);
523 		switch(u8State)
524 		{
525 			case 0x08:
526 				I2C_ClearFunc(enCh,I2cStart_En);
527 				I2C_WriteByte(enCh,u8DevAddr);
528 				break;
529 			case 0x18:
530 				I2C_WriteByte(enCh,u8Addr);
531 				break;
532 			case 0x28:
533 				I2C_SetFunc(enCh,I2cStart_En);
534 				break;
535 			case 0x10:
536 				I2C_ClearFunc(enCh,I2cStart_En);
537 				I2C_WriteByte(enCh,u8DevAddr|0x01);//从机地址发送OK
538 				break;
539 			case 0x40:
540 				if(u32Len>1)
541 				{
542 					I2C_SetFunc(enCh,I2cAck_En);
543 				}
544 				break;
545 			case 0x50:
546 				pu8Data[u8i++] = I2C_ReadByte(enCh);
547 				if(u8i==u32Len-1)
548 				{
549 					I2C_ClearFunc(enCh,I2cAck_En);
550 				}
551 				break;
552 			case 0x58:
553 				pu8Data[u8i++] = I2C_ReadByte(enCh);
554 				I2C_SetFunc(enCh,I2cStop_En);
555 				break;
556 			case 0x38:
557 				I2C_SetFunc(enCh,I2cStart_En);
558 				break;
559 			case 0x48:
560 				I2C_SetFunc(enCh,I2cStop_En);
561 				I2C_SetFunc(enCh,I2cStart_En);
562 				break;
563 			default:
564 				I2C_SetFunc(enCh,I2cStart_En);//其他错误状态,重新发送起始条件
565 				break;
566 		}
567 		I2C_ClearIrq(enCh);
568 		if(u8i==u32Len)
569 		{
570 			break;
571 		}
572 	}
573 	enRet = Ok;
574 	return enRet;
575 }
576 /**
577  ******************************************************************************
578  ** \brief  I2C模块初始化
579  **
580  ** \param pstcI2CCfg初始化配置结构体
581  **
582  ** \retval 初始化是否成功
583  **
584  ******************************************************************************/
I2C_Init(en_i2c_channel_t enCh,stc_i2c_config_t * pstcI2CCfg)585 en_result_t I2C_Init(en_i2c_channel_t enCh,stc_i2c_config_t *pstcI2CCfg)
586 {
587    en_result_t enRet = Error;
588    enRet = I2C_SetFunc(enCh,pstcI2CCfg->enFunc);
589    enRet = I2C_SetBaud(enCh,pstcI2CCfg->u8Tm);
590    enRet = I2C_WriteSlaveAddr(enCh,&pstcI2CCfg->stcSlaveAddr);
591    if(pstcI2CCfg->u8Tm<9)
592    {
593        I2C_SetFunc(enCh,I2cHlm_En);
594    }
595    if(NULL!=pstcI2CCfg->pfnI2c0Cb)
596    {
597 		pfnI2c0tCallback = pstcI2CCfg->pfnI2c0Cb;
598    }
599    if(NULL!=pstcI2CCfg->pfnI2c1Cb)
600    {
601 		pfnI2c1tCallback = pstcI2CCfg->pfnI2c1Cb;
602    }
603    if(TRUE == pstcI2CCfg->bTouchNvic)
604    {
605         if(I2C0 == enCh)
606         {
607             EnableNvic(I2C0_IRQn,IrqLevel3,TRUE);
608         }
609         else
610         {
611             EnableNvic(I2C1_IRQn,IrqLevel3,TRUE);
612         }
613    }
614    return enRet;
615 }
616 /**
617  ******************************************************************************
618  ** \brief  I2C模块关闭初始化
619  **
620  ** \param 无
621  **
622  ** \retval 设置是否成功
623  **
624  ******************************************************************************/
I2C_DeInit(en_i2c_channel_t enCh)625  en_result_t I2C_DeInit(en_i2c_channel_t enCh)
626  {
627     en_result_t enRet = Error;
628     if(I2C0 == enCh)
629     {
630         M0P_I2C0->CR = 0x00;
631     }
632     else
633     {
634         M0P_I2C1->CR = 0x00;
635     }
636     enRet = Ok;
637     return enRet;
638  }
639  /**
640  ******************************************************************************
641  ** \brief  I2C模块中断处理函数
642  **
643  ** \param u8Param 无意义
644  **
645  ** \retval  无
646  **
647  ******************************************************************************/
I2c_IRQHandler(uint8_t u8Param)648 void I2c_IRQHandler(uint8_t u8Param)
649 {
650     if(I2C0 == u8Param)
651     {
652 		if(NULL != pfnI2c0tCallback)
653 		{
654 			pfnI2c0tCallback();
655 		}
656     }
657     else
658     {
659 		if(NULL != pfnI2c1tCallback)
660 		{
661 			pfnI2c1tCallback();
662 		}
663 	}
664 }
665 
666 //@} // I2cGroup
667