i2c.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666
  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. /* Include files */
  53. /******************************************************************************/
  54. #include "i2c.h"
  55. /**
  56. *******************************************************************************
  57. ** \addtogroup I2cGroup
  58. ******************************************************************************/
  59. //@{
  60. /******************************************************************************/
  61. /* Local function prototypes ('static') */
  62. /******************************************************************************/
  63. static func_ptr_t pfnI2c0tCallback = NULL;
  64. static func_ptr_t pfnI2c1tCallback = NULL;
  65. /**
  66. ******************************************************************************
  67. ** \brief I2C设置波特率配置寄存器
  68. **
  69. ** \param [in] u8Tm 波特率配置值
  70. **
  71. ** \retval enRet 成功或失败
  72. **
  73. ******************************************************************************/
  74. en_result_t I2C_SetBaud(en_i2c_channel_t enCh,uint8_t u8Tm)
  75. {
  76. en_result_t enRet = Error;
  77. if(I2C0 == enCh)
  78. {
  79. M0P_I2C0->TM = u8Tm;
  80. }
  81. else
  82. {
  83. M0P_I2C1->TM = u8Tm;
  84. }
  85. enRet = Ok;
  86. return enRet;
  87. }
  88. /**
  89. ******************************************************************************
  90. ** \brief I2C功能设置相关函数
  91. **
  92. ** \param [in] enFunc功能参数
  93. **
  94. ** \retval enRet 成功或失败
  95. **
  96. ******************************************************************************/
  97. en_result_t I2C_SetFunc(en_i2c_channel_t enCh,en_i2c_func_t enFunc)
  98. {
  99. en_result_t enRet = Error;
  100. if(I2C0 == enCh)
  101. {
  102. switch(enFunc)
  103. {
  104. case I2cMode_En:
  105. M0P_I2C0->CR_f.ENS = 1;
  106. break;
  107. case I2cStart_En:
  108. M0P_I2C0->CR_f.STA = 1;
  109. break;
  110. case I2cStop_En:
  111. M0P_I2C0->CR_f.STO = 1;
  112. break;
  113. case I2cAck_En:
  114. M0P_I2C0->CR_f.AA = 1;
  115. break;
  116. case I2cHlm_En:
  117. M0P_I2C0->CR_f.H1M = 1;
  118. break;
  119. case I2cBaud_En:
  120. M0P_I2C0->TMRUN = 0x01;
  121. break;
  122. default:
  123. return ErrorInvalidParameter;
  124. }
  125. }
  126. else
  127. {
  128. switch(enFunc)
  129. {
  130. case I2cMode_En:
  131. M0P_I2C1->CR_f.ENS = 1;
  132. break;
  133. case I2cStart_En:
  134. M0P_I2C1->CR_f.STA = 1;
  135. break;
  136. case I2cStop_En:
  137. M0P_I2C1->CR_f.STO = 1;
  138. break;
  139. case I2cAck_En:
  140. M0P_I2C1->CR_f.AA = 1;
  141. break;
  142. case I2cHlm_En:
  143. M0P_I2C1->CR_f.H1M = 1;
  144. break;
  145. case I2cBaud_En:
  146. M0P_I2C1->TMRUN = 0x01;
  147. break;
  148. default:
  149. return ErrorInvalidParameter;
  150. }
  151. }
  152. enRet = Ok;
  153. return enRet;
  154. }
  155. /**
  156. ******************************************************************************
  157. ** \brief I2C功能清除相关函数
  158. **
  159. ** \param [in] enFunc功能参数
  160. **
  161. ** \retval enRet 成功或失败
  162. **
  163. ******************************************************************************/
  164. en_result_t I2C_ClearFunc(en_i2c_channel_t enCh,en_i2c_func_t enFunc)
  165. {
  166. en_result_t enRet = Error;
  167. if(I2C0 == enCh)
  168. {
  169. switch(enFunc)
  170. {
  171. case I2cMode_En:
  172. M0P_I2C0->CR_f.ENS = 0;
  173. break;
  174. case I2cStart_En:
  175. M0P_I2C0->CR_f.STA = 0;
  176. break;
  177. case I2cStop_En:
  178. M0P_I2C0->CR_f.STO = 0;
  179. break;
  180. case I2cAck_En:
  181. M0P_I2C0->CR_f.AA = 0;
  182. break;
  183. case I2cHlm_En:
  184. M0P_I2C0->CR_f.H1M = 0;
  185. break;
  186. case I2cBaud_En:
  187. M0P_I2C0->TMRUN = 0x00;
  188. break;
  189. default:
  190. return ErrorInvalidParameter;
  191. }
  192. }
  193. else
  194. {
  195. switch(enFunc)
  196. {
  197. case I2cMode_En:
  198. M0P_I2C1->CR_f.ENS = 0;
  199. break;
  200. case I2cStart_En:
  201. M0P_I2C1->CR_f.STA = 0;
  202. break;
  203. case I2cStop_En:
  204. M0P_I2C1->CR_f.STO = 0;
  205. break;
  206. case I2cAck_En:
  207. M0P_I2C1->CR_f.AA = 0;
  208. break;
  209. case I2cHlm_En:
  210. M0P_I2C1->CR_f.H1M = 0;
  211. break;
  212. case I2cBaud_En:
  213. M0P_I2C1->TMRUN = 0x00;
  214. break;
  215. default:
  216. return ErrorInvalidParameter;
  217. }
  218. }
  219. enRet = Ok;
  220. return enRet;
  221. }
  222. /**
  223. ******************************************************************************
  224. ** \brief I2C获取中断标记函数
  225. **
  226. ** \param 无
  227. **
  228. ** \retval bIrq中断标记
  229. **
  230. ******************************************************************************/
  231. boolean_t I2C_GetIrq(en_i2c_channel_t enCh)
  232. {
  233. boolean_t bIrq = FALSE;
  234. if(I2C0 == enCh)
  235. {
  236. bIrq = M0P_I2C0->CR_f.SI;
  237. }
  238. else
  239. {
  240. bIrq = M0P_I2C1->CR_f.SI;
  241. }
  242. return bIrq;
  243. }
  244. /**
  245. ******************************************************************************
  246. ** \brief I2C清除中断标记函数
  247. **
  248. ** \param 无
  249. **
  250. ** \retval bIrq中断标记
  251. **
  252. ******************************************************************************/
  253. en_result_t I2C_ClearIrq(en_i2c_channel_t enCh)
  254. {
  255. en_result_t enRet = Error;
  256. if(I2C0 == enCh)
  257. {
  258. M0P_I2C0->CR_f.SI = 0;
  259. }
  260. else
  261. {
  262. M0P_I2C1->CR_f.SI = 0;
  263. }
  264. enRet = Ok;
  265. return enRet;
  266. }
  267. /**
  268. ******************************************************************************
  269. ** \brief I2C获取相关状态
  270. **
  271. ** \param 无
  272. **
  273. ** \retval I2C状态
  274. **
  275. ******************************************************************************/
  276. uint8_t I2C_GetState(en_i2c_channel_t enCh)
  277. {
  278. uint8_t u8State = 0;
  279. if(I2C0 == enCh)
  280. {
  281. u8State = M0P_I2C0->STAT;
  282. }
  283. else
  284. {
  285. u8State = M0P_I2C1->STAT;
  286. }
  287. return u8State;
  288. }
  289. /**
  290. ******************************************************************************
  291. ** \brief I2C写从机地址函数
  292. **
  293. ** \param u8SlaveAddr从机地址
  294. **
  295. ** \retval I2C写成功与否状态
  296. **
  297. ******************************************************************************/
  298. en_result_t I2C_WriteSlaveAddr(en_i2c_channel_t enCh,stc_i2c_addr_t *pstcSlaveAddr)
  299. {
  300. en_result_t enRet = Error;
  301. if(I2C0 == enCh)
  302. {
  303. M0P_I2C0->ADDR_f.ADR = pstcSlaveAddr->Addr;
  304. M0P_I2C0->ADDR_f.GC = pstcSlaveAddr->Gc;
  305. }
  306. else
  307. {
  308. M0P_I2C1->ADDR_f.ADR = pstcSlaveAddr->Addr;
  309. M0P_I2C1->ADDR_f.GC = pstcSlaveAddr->Gc;
  310. }
  311. enRet = Ok;
  312. return enRet;
  313. }
  314. /**
  315. ******************************************************************************
  316. ** \brief 字节写从机函数
  317. **
  318. ** \param u8Data写数据
  319. **
  320. ** \retval 写数据是否成功
  321. **
  322. ******************************************************************************/
  323. en_result_t I2C_WriteByte(en_i2c_channel_t enCh,uint8_t u8Data)
  324. {
  325. en_result_t enRet = Error;
  326. if(I2C0 == enCh)
  327. {
  328. M0P_I2C0->DATA = u8Data;
  329. }
  330. else
  331. {
  332. M0P_I2C1->DATA = u8Data;
  333. }
  334. enRet = Ok;
  335. return enRet;
  336. }
  337. /**
  338. ******************************************************************************
  339. ** \brief 字节读从机函数
  340. **
  341. ** \param 无
  342. **
  343. ** \retval 读取数据
  344. **
  345. ******************************************************************************/
  346. uint8_t I2C_ReadByte(en_i2c_channel_t enCh)
  347. {
  348. uint8_t u8Data = 0;
  349. if(I2C0 == enCh)
  350. {
  351. u8Data = M0P_I2C0->DATA;
  352. }
  353. else
  354. {
  355. u8Data = M0P_I2C1->DATA;
  356. }
  357. return u8Data;
  358. }
  359. /**
  360. ******************************************************************************
  361. ** \brief 主机发送函数
  362. **
  363. ** \param u8Addr从机内存地址,pu8Data写数据,u32Len写数据长度
  364. **
  365. ** \retval 写数据是否成功
  366. **
  367. ******************************************************************************/
  368. en_result_t I2C_MasterWriteData(en_i2c_channel_t enCh,uint8_t u8DevAddr,uint8_t u8Addr,uint8_t *pu8Data,uint32_t u32Len)
  369. {
  370. en_result_t enRet = Error;
  371. uint8_t u8i=0,u8State;
  372. I2C_SetFunc(enCh,I2cStart_En);
  373. while(1)
  374. {
  375. while(0 == I2C_GetIrq(enCh))
  376. {}
  377. u8State = I2C_GetState(enCh);
  378. switch(u8State)
  379. {
  380. case 0x08:
  381. I2C_ClearFunc(enCh,I2cStart_En);
  382. I2C_WriteByte(enCh,u8DevAddr);//从设备地址发送
  383. break;
  384. case 0x18:
  385. I2C_WriteByte(enCh,u8Addr);//从设备内存地址发送
  386. break;
  387. case 0x28:
  388. I2C_WriteByte(enCh,pu8Data[u8i++]);
  389. break;
  390. case 0x20:
  391. case 0x38:
  392. I2C_SetFunc(enCh,I2cStart_En);
  393. break;
  394. case 0x30:
  395. I2C_SetFunc(enCh,I2cStop_En);
  396. break;
  397. default:
  398. break;
  399. }
  400. if(u8i>u32Len)
  401. {
  402. I2C_SetFunc(enCh,I2cStop_En);//此顺序不能调换,出停止条件
  403. I2C_ClearIrq(enCh);
  404. break;
  405. }
  406. I2C_ClearIrq(enCh);
  407. }
  408. enRet = Ok;
  409. return enRet;
  410. }
  411. /**
  412. ******************************************************************************
  413. ** \brief 从机发送函数
  414. **
  415. ** \param pu8Data发送数据缓存,u32Len发送数据长度
  416. **
  417. ** \retval 发送数据是否成功
  418. **
  419. ******************************************************************************/
  420. en_result_t I2C_SlaveWriteData(en_i2c_channel_t enCh,uint8_t *pu8Data,uint32_t *u32Len)
  421. {
  422. uint8_t u8i=0,u8State;
  423. //
  424. while(1)
  425. {
  426. while(0 == I2C_GetIrq(enCh))
  427. {}
  428. u8State = I2C_GetState(enCh);
  429. switch(u8State)
  430. {
  431. case 0xA8:
  432. case 0xB0:
  433. I2C_WriteByte(enCh,pu8Data[u8i++]);
  434. break;
  435. case 0xB8:
  436. case 0xC8:
  437. I2C_WriteByte(enCh,pu8Data[u8i++]);
  438. break;
  439. case 0xF8:
  440. *u32Len = u8i;
  441. break;
  442. default:
  443. return ErrorInvalidParameter;
  444. }
  445. I2C_ClearIrq(enCh);
  446. }
  447. }
  448. /**
  449. ******************************************************************************
  450. ** \brief 从机接收函数
  451. **
  452. ** \param pu8Data接收数据存放缓存,u32Len接收数据指针
  453. **
  454. ** \retval 接收数据是否成功
  455. **
  456. ******************************************************************************/
  457. en_result_t I2C_SlaveReadData(en_i2c_channel_t enCh,uint8_t *pu8Data,uint32_t *pu32Len)
  458. {
  459. uint8_t u8i=0,u8State;
  460. while(0 == I2C_GetIrq(enCh))
  461. {}
  462. while(1)
  463. {
  464. while(0 == I2C_GetIrq(enCh))
  465. {}
  466. u8State = I2C_GetState(enCh);
  467. switch(u8State)
  468. {
  469. case 0x60:
  470. case 0x68:
  471. case 0x70:
  472. case 0x78:
  473. break;
  474. case 0x80:
  475. case 0x90:
  476. pu8Data[u8i++] = I2C_ReadByte(enCh);
  477. break;
  478. case 0xA0:
  479. *pu32Len = u8i;
  480. break;
  481. default:
  482. return ErrorInvalidParameter;
  483. }
  484. I2C_ClearIrq(enCh);
  485. if(0xA0 == u8State)
  486. {
  487. return Ok;
  488. }
  489. }
  490. }
  491. /**
  492. ******************************************************************************
  493. ** \brief 主机接收函数
  494. **
  495. ** \param u8Addr从机内存地址,pu8Data读数据存放缓存,u32Len读数据长度
  496. **
  497. ** \retval 读数据是否成功
  498. **
  499. ******************************************************************************/
  500. en_result_t I2C_MasterReadData(en_i2c_channel_t enCh,uint8_t u8DevAddr,uint8_t *pu8Data,uint8_t u8Addr,uint32_t u32Len)
  501. {
  502. en_result_t enRet = Error;
  503. uint8_t u8i=0,u8State;
  504. I2C_SetFunc(enCh,I2cStart_En);
  505. while(1)
  506. {
  507. while(0 == I2C_GetIrq(enCh))
  508. {}
  509. u8State = I2C_GetState(enCh);
  510. switch(u8State)
  511. {
  512. case 0x08:
  513. I2C_ClearFunc(enCh,I2cStart_En);
  514. I2C_WriteByte(enCh,u8DevAddr);
  515. break;
  516. case 0x18:
  517. I2C_WriteByte(enCh,u8Addr);
  518. break;
  519. case 0x28:
  520. I2C_SetFunc(enCh,I2cStart_En);
  521. break;
  522. case 0x10:
  523. I2C_ClearFunc(enCh,I2cStart_En);
  524. I2C_WriteByte(enCh,u8DevAddr|0x01);//从机地址发送OK
  525. break;
  526. case 0x40:
  527. if(u32Len>1)
  528. {
  529. I2C_SetFunc(enCh,I2cAck_En);
  530. }
  531. break;
  532. case 0x50:
  533. pu8Data[u8i++] = I2C_ReadByte(enCh);
  534. if(u8i==u32Len-1)
  535. {
  536. I2C_ClearFunc(enCh,I2cAck_En);
  537. }
  538. break;
  539. case 0x58:
  540. pu8Data[u8i++] = I2C_ReadByte(enCh);
  541. I2C_SetFunc(enCh,I2cStop_En);
  542. break;
  543. case 0x38:
  544. I2C_SetFunc(enCh,I2cStart_En);
  545. break;
  546. case 0x48:
  547. I2C_SetFunc(enCh,I2cStop_En);
  548. I2C_SetFunc(enCh,I2cStart_En);
  549. break;
  550. default:
  551. I2C_SetFunc(enCh,I2cStart_En);//其他错误状态,重新发送起始条件
  552. break;
  553. }
  554. I2C_ClearIrq(enCh);
  555. if(u8i==u32Len)
  556. {
  557. break;
  558. }
  559. }
  560. enRet = Ok;
  561. return enRet;
  562. }
  563. /**
  564. ******************************************************************************
  565. ** \brief I2C模块初始化
  566. **
  567. ** \param pstcI2CCfg初始化配置结构体
  568. **
  569. ** \retval 初始化是否成功
  570. **
  571. ******************************************************************************/
  572. en_result_t I2C_Init(en_i2c_channel_t enCh,stc_i2c_config_t *pstcI2CCfg)
  573. {
  574. en_result_t enRet = Error;
  575. enRet = I2C_SetFunc(enCh,pstcI2CCfg->enFunc);
  576. enRet = I2C_SetBaud(enCh,pstcI2CCfg->u8Tm);
  577. enRet = I2C_WriteSlaveAddr(enCh,&pstcI2CCfg->stcSlaveAddr);
  578. if(pstcI2CCfg->u8Tm<9)
  579. {
  580. I2C_SetFunc(enCh,I2cHlm_En);
  581. }
  582. if(NULL!=pstcI2CCfg->pfnI2c0Cb)
  583. {
  584. pfnI2c0tCallback = pstcI2CCfg->pfnI2c0Cb;
  585. }
  586. if(NULL!=pstcI2CCfg->pfnI2c1Cb)
  587. {
  588. pfnI2c1tCallback = pstcI2CCfg->pfnI2c1Cb;
  589. }
  590. if(TRUE == pstcI2CCfg->bTouchNvic)
  591. {
  592. if(I2C0 == enCh)
  593. {
  594. EnableNvic(I2C0_IRQn,IrqLevel3,TRUE);
  595. }
  596. else
  597. {
  598. EnableNvic(I2C1_IRQn,IrqLevel3,TRUE);
  599. }
  600. }
  601. return enRet;
  602. }
  603. /**
  604. ******************************************************************************
  605. ** \brief I2C模块关闭初始化
  606. **
  607. ** \param 无
  608. **
  609. ** \retval 设置是否成功
  610. **
  611. ******************************************************************************/
  612. en_result_t I2C_DeInit(en_i2c_channel_t enCh)
  613. {
  614. en_result_t enRet = Error;
  615. if(I2C0 == enCh)
  616. {
  617. M0P_I2C0->CR = 0x00;
  618. }
  619. else
  620. {
  621. M0P_I2C1->CR = 0x00;
  622. }
  623. enRet = Ok;
  624. return enRet;
  625. }
  626. /**
  627. ******************************************************************************
  628. ** \brief I2C模块中断处理函数
  629. **
  630. ** \param u8Param 无意义
  631. **
  632. ** \retval 无
  633. **
  634. ******************************************************************************/
  635. void I2c_IRQHandler(uint8_t u8Param)
  636. {
  637. if(I2C0 == u8Param)
  638. {
  639. if(NULL != pfnI2c0tCallback)
  640. {
  641. pfnI2c0tCallback();
  642. }
  643. }
  644. else
  645. {
  646. if(NULL != pfnI2c1tCallback)
  647. {
  648. pfnI2c1tCallback();
  649. }
  650. }
  651. }
  652. //@} // I2cGroup