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