dw_iic.c 49 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584
  1. /* ------------------------------------------
  2. * Copyright (c) 2017, Synopsys, Inc. All rights reserved.
  3. * Redistribution and use in source and binary forms, with or without modification,
  4. * are permitted provided that the following conditions are met:
  5. * 1) Redistributions of source code must retain the above copyright notice, this
  6. * list of conditions and the following disclaimer.
  7. * 2) Redistributions in binary form must reproduce the above copyright notice,
  8. * this list of conditions and the following disclaimer in the documentation and/or
  9. * other materials provided with the distribution.
  10. * 3) Neither the name of the Synopsys, Inc., nor the names of its contributors may
  11. * be used to endorse or promote products derived from this software without
  12. * specific prior written permission.
  13. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  14. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  15. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  16. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
  17. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  18. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  19. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  20. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  21. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  22. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  23. *
  24. * \version 2017.03
  25. * \date 2014-06-30
  26. * \author Huaqi Fang(Huaqi.Fang@synopsys.com)
  27. --------------------------------------------- */
  28. /**
  29. * \defgroup DEVICE_DW_IIC Designware IIC Driver
  30. * \ingroup DEVICE_DW
  31. * \brief Designware IIC Driver Implementation
  32. */
  33. /**
  34. * \file
  35. * \brief Designware iic driver
  36. * \ingroup DEVICE_DW_IIC
  37. */
  38. #include <string.h>
  39. #include "inc/embARC_toolchain.h"
  40. #include "inc/embARC_error.h"
  41. #include "inc/arc/arc_exception.h"
  42. #include "device/designware/iic/dw_iic_hal.h"
  43. #include "device/designware/iic/dw_iic.h"
  44. /** check expressions used in DesignWare IIC driver implementation */
  45. #define DW_IIC_CHECK_EXP(EXPR, ERROR_CODE) CHECK_EXP(EXPR, ercd, ERROR_CODE, error_exit)
  46. #ifndef DISABLE_DEVICE_OBJECT_VALID_CHECK
  47. /** valid check of iic info object */
  48. #define VALID_CHK_IIC_INFO_OBJECT(iicinfo_obj_ptr) { \
  49. DW_IIC_CHECK_EXP((iicinfo_obj_ptr)!=NULL, E_OBJ); \
  50. DW_IIC_CHECK_EXP(((iicinfo_obj_ptr)->iic_ctrl)!=NULL, E_OBJ); \
  51. }
  52. #endif
  53. /**
  54. * \name DesignWare IIC Interrupt Callback Routine Select Marcos
  55. * \brief DesignWare IIC interrupt callback routines select macros definitions
  56. * @{
  57. */
  58. #define DW_IIC_RDY_SND (1U) /*!< ready to send callback */
  59. #define DW_IIC_RDY_RCV (2U) /*!< ready to receive callback */
  60. /** @} */
  61. /**
  62. * \defgroup DEVICE_DW_IIC_STATIC DesignWare IIC Driver Static Functions
  63. * \ingroup DEVICE_DW_IIC
  64. * \brief Static or inline functions, variables for DesignWare IIC handle iic operations,
  65. * only used in this file.
  66. * @{
  67. */
  68. /** Disable designware iic device */
  69. Inline void dw_iic_disable(DW_IIC_REG *iic_reg_ptr)
  70. {
  71. iic_reg_ptr->IC_ENABLE = DW_IIC_DISABLE;
  72. }
  73. /** Enable designware iic device */
  74. Inline void dw_iic_enable(DW_IIC_REG *iic_reg_ptr)
  75. {
  76. iic_reg_ptr->IC_ENABLE = DW_IIC_ENABLE;
  77. }
  78. /** Clear all designware iic interrupt */
  79. Inline void dw_iic_clear_interrupt_all(DW_IIC_REG *iic_reg_ptr)
  80. {
  81. (void)iic_reg_ptr->IC_CLR_INTR;
  82. }
  83. /** test whether iic is ready to write, 1 ready, 0 not ready */
  84. Inline int32_t dw_iic_putready(DW_IIC_REG *iic_reg_ptr)
  85. {
  86. return ((iic_reg_ptr->IC_STATUS & IC_STATUS_TFNF) != 0);
  87. }
  88. /** test whether iic is ready to receive, 1 ready, 0 not ready */
  89. Inline int32_t dw_iic_getready(DW_IIC_REG *iic_reg_ptr)
  90. {
  91. return ((iic_reg_ptr->IC_STATUS & IC_STATUS_RFNE) != 0);
  92. }
  93. /** Write data into IIC TX FIFO with STOP/RESTART Condition, and R/W bit */
  94. Inline void dw_iic_putdata(DW_IIC_REG *iic_reg_ptr, uint32_t data)
  95. {
  96. iic_reg_ptr->IC_DATA_CMD = data;
  97. }
  98. /** Read Data from IIC RX FIFO */
  99. Inline uint32_t dw_iic_getdata(DW_IIC_REG *iic_reg_ptr)
  100. {
  101. return (iic_reg_ptr->IC_DATA_CMD) & 0xff;
  102. }
  103. /** Enable designware iic bit interrupt with mask */
  104. Inline void dw_iic_unmask_interrupt(DW_IIC_REG *iic_reg_ptr, uint32_t mask)
  105. {
  106. iic_reg_ptr->IC_INTR_MASK |= mask;
  107. }
  108. /** Disable designware iic bit interrupt with mask */
  109. Inline void dw_iic_mask_interrupt(DW_IIC_REG *iic_reg_ptr, uint32_t mask)
  110. {
  111. iic_reg_ptr->IC_INTR_MASK &= ~mask;
  112. }
  113. /** Get TX FIFO Length */
  114. Inline uint32_t dw_iic_get_txfifo_len(DW_IIC_REG *iic_reg_ptr)
  115. {
  116. uint32_t txfifolen;
  117. txfifolen = ((iic_reg_ptr->IC_COMP_PARAM_1 >> 16) & 0xff) + 1;
  118. return txfifolen;
  119. }
  120. /** Get RX FIFO Length */
  121. Inline uint32_t dw_iic_get_rxfifo_len(DW_IIC_REG *iic_reg_ptr)
  122. {
  123. uint32_t rxfifolen;
  124. rxfifolen = ((iic_reg_ptr->IC_COMP_PARAM_1 >> 8) & 0xff) + 1;
  125. return rxfifolen;
  126. }
  127. /** Set designware iic transfer in 7bit of 10bit addressing mode as a master */
  128. Inline void dw_iic_set_mstaddr_mode(DW_IIC_REG *iic_reg_ptr, uint32_t mode)
  129. {
  130. #if DW_IIC_DYNAMIC_TAR_UPDATE_SUPPORT
  131. if (mode == IIC_7BIT_ADDRESS) {
  132. iic_reg_ptr->IC_TAR &= ~IC_10BITADDR_MASTER;
  133. } else {
  134. iic_reg_ptr->IC_TAR |= IC_10BITADDR_MASTER;
  135. }
  136. #else
  137. dw_iic_disable(iic_reg_ptr);
  138. if (mode == IIC_7BIT_ADDRESS) {
  139. iic_reg_ptr->IC_CON &= ~MST_10_BIT_ADDR_MODE;
  140. } else {
  141. iic_reg_ptr->IC_CON |= MST_10_BIT_ADDR_MODE;
  142. }
  143. dw_iic_enable(iic_reg_ptr);
  144. #endif
  145. }
  146. /** Set designware iic transfer in 7bit of 10bit addressing mode as a slave */
  147. Inline void dw_iic_set_slvaddr_mode(DW_IIC_REG *iic_reg_ptr, uint32_t mode)
  148. {
  149. dw_iic_disable(iic_reg_ptr);
  150. if (mode == IIC_7BIT_ADDRESS) {
  151. iic_reg_ptr->IC_CON &= ~SLV_10_BIT_ADDR_MODE;
  152. } else {
  153. iic_reg_ptr->IC_CON |= SLV_10_BIT_ADDR_MODE;
  154. }
  155. dw_iic_enable(iic_reg_ptr);
  156. }
  157. /** Set designware iic transfer target address for addressing any iic slave device as a master */
  158. Inline void dw_iic_set_taraddr(DW_IIC_REG *iic_reg_ptr, uint32_t address)
  159. {
  160. #if DW_IIC_DYNAMIC_TAR_UPDATE_SUPPORT
  161. iic_reg_ptr->IC_TAR &= ~(IC_TAR_10BIT_ADDR_MASK);
  162. iic_reg_ptr->IC_TAR |= (IC_TAR_10BIT_ADDR_MASK & address);
  163. #else
  164. dw_iic_disable(iic_reg_ptr);
  165. iic_reg_ptr->IC_TAR &= ~(IC_TAR_10BIT_ADDR_MASK);
  166. iic_reg_ptr->IC_TAR |= (IC_TAR_10BIT_ADDR_MASK & address);
  167. dw_iic_enable(iic_reg_ptr);
  168. #endif
  169. }
  170. /** Set designware iic slave address as a slave */
  171. Inline void dw_iic_set_slvaddr(DW_IIC_REG *iic_reg_ptr, uint32_t address)
  172. {
  173. dw_iic_disable(iic_reg_ptr);
  174. iic_reg_ptr->IC_SAR &= ~(IC_SAR_10BIT_ADDR_MASK);
  175. iic_reg_ptr->IC_SAR |= (IC_SAR_10BIT_ADDR_MASK & address);
  176. dw_iic_enable(iic_reg_ptr);
  177. }
  178. /** Select speed mode, and return proper speed mode configuration */
  179. Inline uint32_t dw_iic_select_speedmode(uint32_t speedmode)
  180. {
  181. uint32_t speedcfg;
  182. if (speedmode == IIC_SPEED_STANDARD) {
  183. speedcfg = IC_CON_SPEED_STANDARD;
  184. } else if (speedmode == IIC_SPEED_FAST) {
  185. speedcfg = IC_CON_SPEED_FAST;
  186. } else if (speedmode == IIC_SPEED_FASTPLUS) {
  187. speedcfg = IC_CON_SPEED_FAST;
  188. } else if (speedmode == IIC_SPEED_HIGH) {
  189. speedcfg = IC_CON_SPEED_HIGH;
  190. } else {
  191. speedcfg = IC_CON_SPEED_HIGH;
  192. }
  193. return speedcfg;
  194. }
  195. /** Set designware iic speed mode */
  196. Inline void dw_iic_set_speedmode(DW_IIC_REG *iic_reg_ptr, uint32_t speedmode)
  197. {
  198. uint32_t ic_con_val;
  199. dw_iic_disable(iic_reg_ptr);
  200. ic_con_val = iic_reg_ptr->IC_CON & (~IC_CON_SPEED_MASK);
  201. ic_con_val |= dw_iic_select_speedmode(speedmode);
  202. iic_reg_ptr->IC_CON = ic_con_val;
  203. dw_iic_enable(iic_reg_ptr);
  204. }
  205. /** Set designware working mode as master or slave */
  206. Inline void dw_iic_set_working_mode(DW_IIC_REG *iic_reg_ptr, uint32_t mode)
  207. {
  208. uint32_t ic_con_val;
  209. dw_iic_disable(iic_reg_ptr);
  210. ic_con_val = iic_reg_ptr->IC_CON & (~IC_CON_MST_SLV_MODE_MASK);
  211. if (mode == DEV_MASTER_MODE) {
  212. ic_con_val |= IC_CON_ENA_MASTER_MODE;
  213. } else {
  214. ic_con_val |= IC_CON_ENA_SLAVE_MODE;
  215. }
  216. dw_iic_enable(iic_reg_ptr);
  217. }
  218. /** Set IC_CLK frequency by configuration the *CNT registers for different speed modes */
  219. Inline void dw_iic_set_scl_cnt(DW_IIC_REG *iic_reg_ptr, DW_IIC_SCL_CNT *scl_cnt)
  220. {
  221. dw_iic_disable(iic_reg_ptr);
  222. iic_reg_ptr->IC_SS_SCL_HCNT = scl_cnt->ss_scl_hcnt;
  223. iic_reg_ptr->IC_SS_SCL_LCNT = scl_cnt->ss_scl_lcnt;
  224. iic_reg_ptr->IC_FS_SCL_HCNT = scl_cnt->fs_scl_hcnt;
  225. iic_reg_ptr->IC_FS_SCL_LCNT = scl_cnt->fs_scl_lcnt;
  226. iic_reg_ptr->IC_HS_SCL_HCNT = scl_cnt->hs_scl_hcnt;
  227. iic_reg_ptr->IC_HS_SCL_LCNT = scl_cnt->hs_scl_lcnt;
  228. dw_iic_enable(iic_reg_ptr);
  229. }
  230. /** Set spike suppression configuration */
  231. Inline void dw_iic_set_spike_len(DW_IIC_REG *iic_reg_ptr, DW_IIC_SPKLEN *spklen)
  232. {
  233. dw_iic_disable(iic_reg_ptr);
  234. iic_reg_ptr->IC_FS_SPKLEN = spklen->fs_spklen;
  235. iic_reg_ptr->IC_HS_SPKLEN = spklen->hs_spklen;
  236. dw_iic_enable(iic_reg_ptr);
  237. }
  238. Inline void dw_iic_flush_tx(DW_IIC_REG *iic_reg_ptr)
  239. {
  240. (void)iic_reg_ptr->IC_CLR_INTR;
  241. }
  242. Inline void dw_iic_flush_rx(DW_IIC_REG *iic_reg_ptr)
  243. {
  244. }
  245. static uint32_t dw_iic_get_slv_state(DW_IIC_REG *iic_reg_ptr)
  246. {
  247. uint32_t status;
  248. uint32_t slv_state = IIC_SLAVE_STATE_FREE;
  249. status = iic_reg_ptr->IC_RAW_INTR_STAT;
  250. if (status & IC_INTR_STAT_GEN_CALL) {
  251. /* General Call address is received and it is acknowledged */
  252. slv_state |= IIC_SLAVE_STATE_GC_REQ;
  253. }
  254. if (status & IC_INTR_STAT_RX_FULL) {
  255. /* master is attempting to write data to this slave */
  256. slv_state |= IIC_SLAVE_STATE_WR_REQ;
  257. }
  258. if (status & IC_INTR_STAT_RD_REQ) {
  259. /* master is attempting to read data from this slave */
  260. slv_state |= IIC_SLAVE_STATE_RD_REQ;
  261. }
  262. if (status & IC_INTR_STAT_RX_DONE) {
  263. /* master does not acknowledge a transmitted byte, and transmission is done */
  264. slv_state |= IIC_SLAVE_STATE_RD_DONE;
  265. status = iic_reg_ptr->IC_CLR_RX_DONE;
  266. }
  267. if (status & IC_INTR_STAT_START_DET) {
  268. /* a START or RESTART condition has occurred */
  269. slv_state |= IIC_SLAVE_STATE_START;
  270. status = iic_reg_ptr->IC_CLR_START_DET; /* Clear it when read */
  271. }
  272. if (status & IC_INTR_STAT_STOP_DET) {
  273. /* a STOP condition has occurred */
  274. slv_state |= IIC_SLAVE_STATE_STOP;
  275. status = iic_reg_ptr->IC_CLR_STOP_DET; /* Clear it when read */
  276. }
  277. if (status & (IC_INTR_STAT_TX_ABRT|IC_INTR_STAT_TX_OVER\
  278. |IC_INTR_STAT_RX_OVER|IC_INTR_STAT_RX_UNDER)) {
  279. /* error case */
  280. slv_state |= IIC_SLAVE_STATE_ERROR;
  281. status = iic_reg_ptr->IC_CLR_TX_ABRT; /* Clear it when read */
  282. status = iic_reg_ptr->IC_CLR_TX_OVER;
  283. status = iic_reg_ptr->IC_CLR_RX_OVER;
  284. status = iic_reg_ptr->IC_CLR_RX_UNDER;
  285. }
  286. return slv_state;
  287. }
  288. /** Init Designware IIC Device into Master mode */
  289. static void dw_iic_master_init(DW_IIC_CTRL *iic_ctrl_ptr, uint32_t speed_mode, uint32_t addr_mode, uint32_t tar_addr)
  290. {
  291. uint32_t ic_con_val = 0;
  292. DW_IIC_REG *iic_reg_ptr = iic_ctrl_ptr->dw_iic_regs;
  293. dw_iic_disable(iic_reg_ptr);
  294. /* disable all iic interrupt */
  295. iic_reg_ptr->IC_INTR_MASK = IC_INT_DISABLE_ALL;
  296. /* Set to 7bit addressing and update target address */
  297. iic_reg_ptr->IC_TAR = (tar_addr & IC_TAR_10BIT_ADDR_MASK) | IC_TAR_SPECIAL | IC_TAR_GC_OR_START;
  298. /* master mode, restart enabled */
  299. ic_con_val = dw_iic_select_speedmode(speed_mode) | IC_CON_ENA_MASTER_MODE | IC_CON_RESTART_EN;
  300. #if DW_IIC_DYNAMIC_TAR_UPDATE_SUPPORT
  301. if (addr_mode == IIC_10BIT_ADDRESS) {
  302. iic_reg_ptr->IC_TAR |= MST_10_BIT_ADDR_MODE;
  303. }
  304. #else
  305. if (addr_mode == IIC_10BIT_ADDRESS) {
  306. ic_con_val |= MST_10_BIT_ADDR_MODE;
  307. }
  308. #endif
  309. /* Set final IC_CON value */
  310. iic_reg_ptr->IC_CON = ic_con_val;
  311. /* FIFO threshold settings */
  312. iic_reg_ptr->IC_TX_TL = IIC_TX_THRESHOLD;
  313. iic_reg_ptr->IC_RX_TL = IIC_RX_THRESHOLD;
  314. /* Master code settings */
  315. iic_reg_ptr->IC_HS_MADDR = iic_ctrl_ptr->iic_master_code;
  316. dw_iic_enable(iic_reg_ptr);
  317. /* Clock Settings */
  318. dw_iic_set_scl_cnt(iic_reg_ptr, &(iic_ctrl_ptr->iic_scl_cnt));
  319. dw_iic_set_spike_len(iic_reg_ptr, &(iic_ctrl_ptr->iic_spklen));
  320. }
  321. /** Init Designware IIC Device into Slave mode */
  322. static void dw_iic_slave_init(DW_IIC_CTRL *iic_ctrl_ptr, uint32_t addr_mode, uint32_t slv_addr)
  323. {
  324. uint32_t ic_con_val = 0;
  325. DW_IIC_REG *iic_reg_ptr = iic_ctrl_ptr->dw_iic_regs;
  326. dw_iic_disable(iic_reg_ptr);
  327. /* disable all iic interrupt */
  328. iic_reg_ptr->IC_INTR_MASK = IC_INT_DISABLE_ALL;
  329. /* Set slave device address as a slave */
  330. iic_reg_ptr->IC_SAR = slv_addr & IC_SAR_10BIT_ADDR_MASK;
  331. /* slave mode, 7 bit slave address */
  332. ic_con_val = IC_CON_ENA_SLAVE_MODE;
  333. /* If addr mode select to be 10 bit address mode */
  334. if (addr_mode == IIC_10BIT_ADDRESS) {
  335. ic_con_val |= SLV_10_BIT_ADDR_MODE;
  336. }
  337. /* Set final IC_CON value */
  338. iic_reg_ptr->IC_CON = ic_con_val;
  339. /* FIFO threshold settings */
  340. iic_reg_ptr->IC_TX_TL = IIC_TX_THRESHOLD;
  341. iic_reg_ptr->IC_RX_TL = IIC_RX_THRESHOLD;
  342. dw_iic_enable(iic_reg_ptr);
  343. }
  344. /** Check error for IIC master device */
  345. static int32_t dw_iic_mst_chkerr(DW_IIC_CTRL *iic_ctrl_ptr)
  346. {
  347. uint32_t status;
  348. int32_t ercd = IIC_ERR_NONE;
  349. DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs);
  350. status = iic_reg_ptr->IC_RAW_INTR_STAT;
  351. if (status & IC_INTR_STAT_TX_ABRT) {
  352. status = iic_reg_ptr->IC_TX_ABRT_SOURCE;
  353. if (status & IIC_MST_ABRT_LOST_BUS) {
  354. ercd = IIC_ERR_LOST_BUS;
  355. } else if (status & IIC_MST_ABRT_ADDR_NOACK) {
  356. ercd = IIC_ERR_ADDR_NOACK;
  357. } else if (status & IIC_MST_ABRT_DATA_NOACK) {
  358. ercd = IIC_ERR_DATA_NOACK;
  359. } else {
  360. ercd = IIC_ERR_UNDEF;
  361. }
  362. status = iic_reg_ptr->IC_CLR_TX_ABRT;
  363. } else {
  364. if (status & IC_INTR_STAT_TX_OVER) {
  365. iic_ctrl_ptr->iic_tx_over ++;
  366. status = iic_reg_ptr->IC_CLR_TX_OVER;
  367. }
  368. if (status & (IC_INTR_STAT_RX_OVER|IC_INTR_STAT_RX_UNDER)) {
  369. iic_ctrl_ptr->iic_rx_over ++;
  370. status = iic_reg_ptr->IC_CLR_RX_OVER;
  371. status = iic_reg_ptr->IC_CLR_RX_UNDER;
  372. }
  373. }
  374. return ercd;
  375. }
  376. /** Check error for IIC slave device */
  377. static int32_t dw_iic_slv_chkerr(DW_IIC_CTRL *iic_ctrl_ptr)
  378. {
  379. uint32_t status;
  380. int32_t ercd = IIC_ERR_NONE;
  381. DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs);
  382. status = iic_reg_ptr->IC_RAW_INTR_STAT;
  383. if (status & IC_INTR_STAT_TX_ABRT) {
  384. status = iic_reg_ptr->IC_TX_ABRT_SOURCE;
  385. if (status & IIC_SLV_ABRT_LOST_BUS) {
  386. ercd = IIC_ERR_LOST_BUS;
  387. } else if (status & IC_TX_ABRT_SLVFLUSH_TXFIFO) {
  388. /* Flush tx fifo */
  389. status = iic_reg_ptr->IC_TX_ABRT_SOURCE;
  390. } else {
  391. ercd = IIC_ERR_UNDEF;
  392. }
  393. status = iic_reg_ptr->IC_CLR_TX_ABRT;
  394. } else {
  395. if (status & IC_INTR_STAT_TX_OVER) {
  396. iic_ctrl_ptr->iic_tx_over ++;
  397. status = iic_reg_ptr->IC_CLR_TX_OVER;
  398. }
  399. if (status & (IC_INTR_STAT_RX_OVER|IC_INTR_STAT_RX_UNDER)) {
  400. iic_ctrl_ptr->iic_rx_over ++;
  401. status = iic_reg_ptr->IC_CLR_RX_OVER;
  402. status = iic_reg_ptr->IC_CLR_RX_UNDER;
  403. }
  404. }
  405. return ercd;
  406. }
  407. /** enable designware iic */
  408. static void dw_iic_enable_device(DEV_IIC_INFO *iic_info_ptr)
  409. {
  410. DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL *)(iic_info_ptr->iic_ctrl);
  411. DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs);
  412. if ((iic_info_ptr->status & DEV_ENABLED) == 0) {
  413. dw_iic_enable(iic_reg_ptr);
  414. iic_info_ptr->status |= DEV_ENABLED;
  415. }
  416. }
  417. /** disable designware iic */
  418. static void dw_iic_disable_device(DEV_IIC_INFO *iic_info_ptr)
  419. {
  420. DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL *)(iic_info_ptr->iic_ctrl);
  421. DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs);
  422. uint32_t i;
  423. for (i=0; i<DW_IIC_DISABLE_MAX_T_POLL_CNT; i++) {
  424. dw_iic_disable(iic_reg_ptr);
  425. if ((iic_reg_ptr->IC_ENABLE_STATUS & IC_ENABLE_STATUS_IC_EN) == 0) {
  426. break;
  427. }
  428. }
  429. iic_info_ptr->status &= ~DEV_ENABLED;
  430. }
  431. static void dw_iic_reset_device(DEV_IIC_INFO *iic_info_ptr)
  432. {
  433. DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL *)(iic_info_ptr->iic_ctrl);
  434. DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs);
  435. dw_iic_disable_device(iic_info_ptr);
  436. dw_iic_clear_interrupt_all(iic_reg_ptr);
  437. iic_info_ptr->next_cond = IIC_MODE_STOP;
  438. iic_info_ptr->cur_state = IIC_FREE;
  439. iic_info_ptr->err_state = IIC_ERR_NONE;
  440. iic_ctrl_ptr->iic_tx_over = 0;
  441. iic_ctrl_ptr->iic_rx_over = 0;
  442. dw_iic_enable_device(iic_info_ptr);
  443. }
  444. /** Disable iic master interrupt for transmit or receive */
  445. static void dw_iic_mst_dis_cbr(DW_IIC_CTRL *iic_ctrl_ptr, uint32_t cbrtn)
  446. {
  447. DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs);
  448. switch (cbrtn) {
  449. case DW_IIC_RDY_SND:
  450. dw_iic_mask_interrupt(iic_reg_ptr, IC_INT_MST_TX_ENABLE);
  451. iic_ctrl_ptr->int_status &= ~DW_IIC_TXINT_ENABLE;
  452. break;
  453. case DW_IIC_RDY_RCV:
  454. dw_iic_mask_interrupt(iic_reg_ptr, IC_INT_MST_RX_ENABLE);
  455. iic_ctrl_ptr->int_status &= ~DW_IIC_RXINT_ENABLE;
  456. break;
  457. default:
  458. break;
  459. }
  460. }
  461. /** Disable iic slave interrupt for transmit or receive */
  462. static void dw_iic_slv_dis_cbr(DW_IIC_CTRL *iic_ctrl_ptr, uint32_t cbrtn)
  463. {
  464. DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs);
  465. switch (cbrtn) {
  466. case DW_IIC_RDY_SND:
  467. dw_iic_mask_interrupt(iic_reg_ptr, IC_INT_SLV_TX_ENABLE);
  468. iic_ctrl_ptr->int_status &= ~DW_IIC_TXINT_ENABLE;
  469. break;
  470. case DW_IIC_RDY_RCV:
  471. dw_iic_mask_interrupt(iic_reg_ptr, IC_INT_SLV_RX_ENABLE);
  472. iic_ctrl_ptr->int_status &= ~DW_IIC_RXINT_ENABLE;
  473. break;
  474. default:
  475. break;
  476. }
  477. }
  478. /** Enable iic master interrupt for transmit or receive */
  479. static void dw_iic_mst_ena_cbr(DW_IIC_CTRL *iic_ctrl_ptr, uint32_t cbrtn)
  480. {
  481. DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs);
  482. switch (cbrtn) {
  483. case DW_IIC_RDY_SND:
  484. iic_ctrl_ptr->int_status |= DW_IIC_TXINT_ENABLE;
  485. dw_iic_unmask_interrupt(iic_reg_ptr, IC_INT_MST_TX_ENABLE);
  486. break;
  487. case DW_IIC_RDY_RCV:
  488. iic_ctrl_ptr->int_status |= DW_IIC_RXINT_ENABLE;
  489. dw_iic_unmask_interrupt(iic_reg_ptr, IC_INT_MST_RX_ENABLE);
  490. break;
  491. default:
  492. break;
  493. }
  494. }
  495. /** Enable iic slave interrupt for transmit or receive */
  496. static void dw_iic_slv_ena_cbr(DW_IIC_CTRL *iic_ctrl_ptr, uint32_t cbrtn)
  497. {
  498. DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs);
  499. switch (cbrtn) {
  500. case DW_IIC_RDY_SND:
  501. iic_ctrl_ptr->int_status |= DW_IIC_TXINT_ENABLE;
  502. dw_iic_unmask_interrupt(iic_reg_ptr, IC_INT_SLV_TX_ENABLE);
  503. break;
  504. case DW_IIC_RDY_RCV:
  505. iic_ctrl_ptr->int_status |= DW_IIC_RXINT_ENABLE;
  506. dw_iic_unmask_interrupt(iic_reg_ptr, IC_INT_SLV_RX_ENABLE);
  507. break;
  508. default:
  509. break;
  510. }
  511. }
  512. /**
  513. * \brief disable designware iic send or receive interrupt
  514. * \param[in] DEV_IIC_INFO *iic_info_ptr
  515. * \param[in] cbrtn control code of callback routine of send or receive
  516. */
  517. static void dw_iic_dis_cbr(DEV_IIC_INFO *iic_info_ptr, uint32_t cbrtn)
  518. {
  519. DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL *)(iic_info_ptr->iic_ctrl);
  520. if (iic_info_ptr->mode == DEV_MASTER_MODE) {
  521. dw_iic_mst_dis_cbr(iic_ctrl_ptr, cbrtn);
  522. } else {
  523. dw_iic_slv_dis_cbr(iic_ctrl_ptr, cbrtn);
  524. }
  525. if (iic_ctrl_ptr->int_status & DW_IIC_GINT_ENABLE) {
  526. if ((iic_ctrl_ptr->int_status & (DW_IIC_RXINT_ENABLE|DW_IIC_TXINT_ENABLE)) == 0) {
  527. int_disable(iic_ctrl_ptr->intno);
  528. iic_ctrl_ptr->int_status &= ~DW_IIC_GINT_ENABLE;
  529. }
  530. }
  531. }
  532. /**
  533. * \brief enable DesignWare IIC send or receive interrupt
  534. * \param[in] DEV_IIC_INFO *iic_info_ptr
  535. * \param[in] cbrtn control code of callback routine of send or receive
  536. */
  537. static void dw_iic_ena_cbr(DEV_IIC_INFO *iic_info_ptr, uint32_t cbrtn)
  538. {
  539. DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL *)(iic_info_ptr->iic_ctrl);
  540. if (iic_info_ptr->mode == DEV_MASTER_MODE) {
  541. dw_iic_mst_ena_cbr(iic_ctrl_ptr, cbrtn);
  542. } else {
  543. dw_iic_slv_ena_cbr(iic_ctrl_ptr, cbrtn);
  544. }
  545. if ((iic_ctrl_ptr->int_status & DW_IIC_GINT_ENABLE) == 0) {
  546. if (iic_ctrl_ptr->int_status & (DW_IIC_RXINT_ENABLE|DW_IIC_TXINT_ENABLE)) {
  547. iic_ctrl_ptr->int_status |= DW_IIC_GINT_ENABLE;
  548. int_enable(iic_ctrl_ptr->intno);
  549. }
  550. }
  551. }
  552. /**
  553. * \brief enable designware iic interrupt
  554. * \param iic_info_ptr iic information structure pointer
  555. */
  556. static void dw_iic_enable_interrupt(DEV_IIC_INFO *iic_info_ptr)
  557. {
  558. DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL *)(iic_info_ptr->iic_ctrl);
  559. int_handler_install(iic_ctrl_ptr->intno, iic_ctrl_ptr->dw_iic_int_handler);
  560. iic_ctrl_ptr->int_status |= DW_IIC_GINT_ENABLE;
  561. int_enable(iic_ctrl_ptr->intno); /** enable iic interrupt */
  562. }
  563. /**
  564. * \brief disable designware iic interrupt
  565. * \param iic_info_ptr iic information structure pointer
  566. */
  567. static void dw_iic_disable_interrupt(DEV_IIC_INFO *iic_info_ptr)
  568. {
  569. DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL *)(iic_info_ptr->iic_ctrl);
  570. /** disable iic send&receive interrupt after disable iic interrupt */
  571. dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_SND);
  572. dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_RCV);
  573. /* disable iic interrupt */
  574. int_disable(iic_ctrl_ptr->intno);
  575. iic_ctrl_ptr->int_status &= ~(DW_IIC_GINT_ENABLE|DW_IIC_TXINT_ENABLE|DW_IIC_RXINT_ENABLE);
  576. }
  577. /** abort current interrupt transmit transfer */
  578. static void dw_iic_abort_tx(DEV_IIC *iic_obj)
  579. {
  580. DEV_IIC_INFO *iic_info_ptr = &(iic_obj->iic_info);
  581. DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL *)(iic_info_ptr->iic_ctrl);
  582. if (iic_ctrl_ptr->int_status & DW_IIC_TXINT_ENABLE) {
  583. dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_SND);
  584. iic_info_ptr->status |= DEV_IN_TX_ABRT;
  585. if (iic_info_ptr->iic_cbs.tx_cb != NULL) {
  586. iic_info_ptr->iic_cbs.tx_cb(iic_obj);
  587. }
  588. iic_info_ptr->status &= ~(DEV_IN_TX_ABRT);
  589. }
  590. }
  591. /** abort current interrupt receive transfer */
  592. static void dw_iic_abort_rx(DEV_IIC *iic_obj)
  593. {
  594. DEV_IIC_INFO *iic_info_ptr = &(iic_obj->iic_info);
  595. DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL *)(iic_info_ptr->iic_ctrl);
  596. if (iic_ctrl_ptr->int_status & DW_IIC_RXINT_ENABLE) {
  597. dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_RCV);
  598. iic_info_ptr->status |= DEV_IN_RX_ABRT;
  599. if (iic_info_ptr->iic_cbs.rx_cb != NULL) {
  600. iic_info_ptr->iic_cbs.rx_cb(iic_obj);
  601. }
  602. iic_info_ptr->status &= ~(DEV_IN_RX_ABRT);
  603. }
  604. }
  605. /** Get available transmit fifo count */
  606. static int32_t dw_iic_get_txavail(DW_IIC_CTRL *iic_ctrl_ptr)
  607. {
  608. int32_t tx_avail = 0;
  609. DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs);
  610. if (iic_ctrl_ptr->tx_fifo_len <= 1) {
  611. if (dw_iic_putready(iic_reg_ptr) == 1) {
  612. tx_avail = 1;
  613. } else {
  614. tx_avail = 0;
  615. }
  616. } else {
  617. tx_avail = iic_ctrl_ptr->tx_fifo_len - iic_reg_ptr->IC_TXFLR;
  618. }
  619. return tx_avail;
  620. }
  621. /** Get available receive fifo count */
  622. static int32_t dw_iic_get_rxavail(DW_IIC_CTRL *iic_ctrl_ptr)
  623. {
  624. int32_t rx_avail = 0;
  625. DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs);
  626. if (iic_ctrl_ptr->rx_fifo_len <= 1) {
  627. if (dw_iic_getready(iic_reg_ptr) == 1) {
  628. rx_avail = 1;
  629. } else {
  630. rx_avail = 0;
  631. }
  632. } else {
  633. rx_avail = iic_reg_ptr->IC_RXFLR;
  634. }
  635. return rx_avail;
  636. }
  637. /**
  638. * IIC Master device transmit 1 data,
  639. * next_cond can be \ref IC_DATA_CMD_STOP,
  640. * \ref IC_DATA_CMD_RESTART and ref IC_DATA_CMD_NONE
  641. */
  642. static int32_t dw_iic_mst_write_data(DW_IIC_CTRL *iic_ctrl_ptr, uint32_t data, uint32_t next_cond)
  643. {
  644. uint32_t i = 0;
  645. int32_t ercd = IIC_ERR_NONE;
  646. DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs);
  647. while (dw_iic_putready(iic_reg_ptr) == 0) {
  648. if (i++ > iic_ctrl_ptr->retry_cnt) return IIC_ERR_TIMEOUT;
  649. ercd = dw_iic_mst_chkerr(iic_ctrl_ptr);
  650. if (ercd != IIC_ERR_NONE) return ercd;
  651. }
  652. dw_iic_putdata(iic_reg_ptr, data|IC_DATA_CMD_WRITE_REQ|next_cond);
  653. return ercd;
  654. }
  655. /** IIC Slave device transmit 1 data */
  656. static int32_t dw_iic_slv_write_data(DW_IIC_CTRL *iic_ctrl_ptr, uint32_t data)
  657. {
  658. uint32_t i = 0;
  659. int32_t ercd = IIC_ERR_NONE;
  660. uint32_t slv_state, temp;
  661. uint32_t ready2send = 0;
  662. DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs);
  663. for (i = 0; i < iic_ctrl_ptr->retry_cnt; i++) {
  664. ercd = dw_iic_slv_chkerr(iic_ctrl_ptr);
  665. if (ercd != IIC_ERR_NONE) return ercd;
  666. slv_state = iic_reg_ptr->IC_RAW_INTR_STAT;
  667. if (slv_state & IC_INTR_STAT_RD_REQ) {
  668. if (dw_iic_putready(iic_reg_ptr)) {
  669. temp = iic_reg_ptr->IC_CLR_RD_REQ;
  670. ready2send = 1;
  671. break;
  672. }
  673. } else if (slv_state & IC_INTR_STAT_RX_DONE) { /* Put RX Done before STOP */
  674. temp = iic_reg_ptr->IC_CLR_RX_DONE;
  675. return IIC_ERR_MSTSTOP;
  676. } else if (slv_state & IC_INTR_STAT_STOP_DET) {
  677. temp = iic_reg_ptr->IC_CLR_STOP_DET;
  678. return IIC_ERR_MSTSTOP;
  679. }
  680. }
  681. if (ready2send) {
  682. dw_iic_putdata(iic_reg_ptr, data|IC_DATA_CMD_WRITE_REQ);
  683. } else {
  684. ercd = IIC_ERR_TIMEOUT;
  685. }
  686. return ercd;
  687. }
  688. /**
  689. * IIC Master device receive 1 data,
  690. * next_cond can be \ref IC_DATA_CMD_STOP,
  691. * \ref IC_DATA_CMD_RESTART and ref IC_DATA_CMD_NONE
  692. */
  693. static int32_t dw_iic_mst_read_data(DW_IIC_CTRL *iic_ctrl_ptr, uint32_t *data, uint32_t next_cond)
  694. {
  695. uint32_t i = 0;
  696. int32_t ercd = IIC_ERR_NONE;
  697. DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs);
  698. /* Issue a read request */
  699. while (dw_iic_putready(iic_reg_ptr) == 0) {
  700. if (i++ > iic_ctrl_ptr->retry_cnt) return IIC_ERR_TIMEOUT;
  701. ercd = dw_iic_mst_chkerr(iic_ctrl_ptr);
  702. if (ercd != IIC_ERR_NONE) return ercd;
  703. }
  704. dw_iic_putdata(iic_reg_ptr, next_cond|IC_DATA_CMD_READ_REQ);
  705. /* Wait to read data */
  706. i = 0;
  707. while (dw_iic_getready(iic_reg_ptr) == 0) {
  708. if (i++ > iic_ctrl_ptr->retry_cnt) return IIC_ERR_TIMEOUT;
  709. ercd = dw_iic_mst_chkerr(iic_ctrl_ptr);
  710. if (ercd != IIC_ERR_NONE) return ercd;
  711. }
  712. *data = dw_iic_getdata(iic_reg_ptr);
  713. return ercd;
  714. }
  715. /** IIC Slave device receive 1 data */
  716. static int32_t dw_iic_slv_read_data(DW_IIC_CTRL *iic_ctrl_ptr, uint32_t *data)
  717. {
  718. uint32_t i = 0;
  719. int32_t ercd = IIC_ERR_NONE;
  720. uint32_t slv_state, temp;
  721. uint32_t ready2read = 0;
  722. DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs);
  723. for (i = 0; i < iic_ctrl_ptr->retry_cnt; i++) {
  724. ercd = dw_iic_slv_chkerr(iic_ctrl_ptr);
  725. if (ercd != IIC_ERR_NONE) return ercd;
  726. slv_state = iic_reg_ptr->IC_RAW_INTR_STAT;
  727. if (slv_state & IC_INTR_STAT_START_DET) {
  728. temp = iic_reg_ptr->IC_CLR_START_DET;
  729. }
  730. if (slv_state & IC_INTR_STAT_RX_FULL) {
  731. if (dw_iic_getready(iic_reg_ptr)) {
  732. ready2read = 1;
  733. break;
  734. }
  735. } else if (slv_state & IC_INTR_STAT_STOP_DET) {
  736. temp = iic_reg_ptr->IC_CLR_STOP_DET;
  737. return IIC_ERR_MSTSTOP;
  738. }
  739. }
  740. if (ready2read) {
  741. *data = dw_iic_getdata(iic_reg_ptr);
  742. } else {
  743. ercd = IIC_ERR_TIMEOUT;
  744. }
  745. return ercd;
  746. }
  747. /** IIC Master transmit called in interrupt */
  748. static void dw_iic_mst_int_write(DEV_IIC *iic_obj)
  749. {
  750. DEV_IIC_INFO *iic_info_ptr = &(iic_obj->iic_info);
  751. DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL_PTR)(iic_info_ptr->iic_ctrl);
  752. DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG_PTR)(iic_ctrl_ptr->dw_iic_regs);
  753. uint32_t iic_int_status; /** iic interrupt status */
  754. uint32_t last_cond, xmit_data, xmit_end = 0;
  755. DEV_BUFFER *buf_ptr;
  756. uint8_t *p_charbuf;
  757. if (iic_info_ptr->next_cond == IIC_MODE_STOP) {
  758. last_cond = IC_DATA_CMD_STOP;
  759. } else {
  760. last_cond = IC_DATA_CMD_RESTART;
  761. }
  762. iic_int_status = (iic_reg_ptr->IC_INTR_STAT);
  763. buf_ptr = &(iic_info_ptr->tx_buf);
  764. p_charbuf = (uint8_t *)buf_ptr->buf;
  765. if (p_charbuf) {
  766. if (iic_int_status & IC_INTR_STAT_TX_EMPTY) {
  767. xmit_end = 0;
  768. while (dw_iic_putready(iic_reg_ptr)) {
  769. xmit_data = (uint32_t)(p_charbuf[buf_ptr->ofs])|IC_DATA_CMD_WRITE_REQ;
  770. if (buf_ptr->ofs == (buf_ptr->len-1)) {
  771. xmit_end = 1;
  772. xmit_data |= last_cond;
  773. } else {
  774. xmit_data |= IC_DATA_CMD_NONE;
  775. }
  776. buf_ptr->ofs ++;
  777. dw_iic_putdata(iic_reg_ptr, xmit_data);
  778. if (xmit_end) {
  779. dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_SND);
  780. iic_info_ptr->cur_state = IIC_FREE;
  781. if (iic_info_ptr->iic_cbs.tx_cb) {
  782. iic_info_ptr->iic_cbs.tx_cb(iic_obj);
  783. }
  784. /* clear the send buffer pointer */
  785. memset(buf_ptr, 0, sizeof(DEV_BUFFER));
  786. break;
  787. }
  788. }
  789. }
  790. if (iic_int_status & IC_INTR_STAT_TX_OVER) {
  791. iic_ctrl_ptr->iic_tx_over ++;
  792. }
  793. if (iic_int_status & IC_INTR_STAT_TX_ABRT) {
  794. iic_info_ptr->err_state = dw_iic_mst_chkerr(iic_ctrl_ptr);
  795. if (iic_info_ptr->err_state != IIC_ERR_NONE) {
  796. dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_SND);
  797. iic_info_ptr->cur_state = IIC_FREE;
  798. if (iic_info_ptr->iic_cbs.err_cb) {
  799. iic_info_ptr->iic_cbs.err_cb(iic_obj);
  800. }
  801. /* clear the send buffer pointer */
  802. memset(buf_ptr, 0, sizeof(DEV_BUFFER));
  803. }
  804. }
  805. } else {
  806. dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_SND);
  807. iic_info_ptr->cur_state = IIC_FREE;
  808. }
  809. /* Clear Interrupt */
  810. iic_int_status = iic_reg_ptr->IC_CLR_INTR;
  811. }
  812. /** IIC Master receive called in interrupt */
  813. static void dw_iic_mst_int_read(DEV_IIC *iic_obj)
  814. {
  815. DEV_IIC_INFO *iic_info_ptr = &(iic_obj->iic_info);
  816. DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL_PTR)(iic_info_ptr->iic_ctrl);
  817. DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG_PTR)(iic_ctrl_ptr->dw_iic_regs);
  818. uint32_t iic_int_status; /** iic interrupt status */
  819. uint32_t last_cond, xmit_data;
  820. DEV_BUFFER *buf_ptr;
  821. DW_IIC_BUFFER *dw_iic_rxbuf_ptr;
  822. uint8_t *p_charbuf;
  823. if (iic_info_ptr->next_cond == IIC_MODE_STOP) {
  824. last_cond = IC_DATA_CMD_STOP;
  825. } else {
  826. last_cond = IC_DATA_CMD_RESTART;
  827. }
  828. iic_int_status = (iic_reg_ptr->IC_INTR_STAT);
  829. buf_ptr = &(iic_info_ptr->rx_buf);
  830. p_charbuf = (uint8_t *)buf_ptr->buf;
  831. if (p_charbuf) {
  832. dw_iic_rxbuf_ptr = &(iic_ctrl_ptr->dw_iic_rxbuf);
  833. if (iic_int_status & IC_INTR_STAT_TX_EMPTY) {
  834. while (dw_iic_putready(iic_reg_ptr)) {
  835. if (dw_iic_rxbuf_ptr->ofs >= dw_iic_rxbuf_ptr->len) {
  836. dw_iic_mask_interrupt(iic_reg_ptr, IC_INTR_STAT_TX_EMPTY);
  837. break;
  838. }
  839. xmit_data = IC_DATA_CMD_READ_REQ;
  840. if (dw_iic_rxbuf_ptr->ofs == (dw_iic_rxbuf_ptr->len-1)) {
  841. xmit_data |= last_cond;
  842. } else {
  843. xmit_data |= IC_DATA_CMD_NONE;
  844. }
  845. dw_iic_rxbuf_ptr->ofs ++;
  846. dw_iic_putdata(iic_reg_ptr, xmit_data);
  847. }
  848. }
  849. if (iic_int_status & IC_INTR_STAT_RX_FULL) {
  850. while (dw_iic_getready(iic_reg_ptr)) {
  851. p_charbuf[buf_ptr->ofs] = dw_iic_getdata(iic_reg_ptr);
  852. buf_ptr->ofs ++;
  853. if (buf_ptr->ofs >= buf_ptr->len) {
  854. dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_RCV);
  855. iic_info_ptr->cur_state = IIC_FREE;
  856. if (iic_info_ptr->iic_cbs.rx_cb) {
  857. iic_info_ptr->iic_cbs.rx_cb(iic_obj);
  858. }
  859. /* clear the send buffer pointer */
  860. memset(buf_ptr, 0, sizeof(DEV_BUFFER));
  861. dw_iic_rxbuf_ptr->ofs = 0;
  862. dw_iic_rxbuf_ptr->len = 0;
  863. break;
  864. }
  865. }
  866. }
  867. if (iic_int_status & (IC_INTR_STAT_RX_OVER|IC_INTR_STAT_RX_UNDER)) {
  868. iic_ctrl_ptr->iic_rx_over ++;
  869. }
  870. if (iic_int_status & IC_INTR_STAT_TX_ABRT) {
  871. iic_info_ptr->err_state = dw_iic_mst_chkerr(iic_ctrl_ptr);
  872. if (iic_info_ptr->err_state != IIC_ERR_NONE) {
  873. dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_RCV);
  874. iic_info_ptr->cur_state = IIC_FREE;
  875. if (iic_info_ptr->iic_cbs.err_cb) {
  876. iic_info_ptr->iic_cbs.err_cb(iic_obj);
  877. }
  878. /* clear the send buffer pointer */
  879. memset(buf_ptr, 0, sizeof(DEV_BUFFER));
  880. dw_iic_rxbuf_ptr->ofs = 0;
  881. dw_iic_rxbuf_ptr->len = 0;
  882. }
  883. }
  884. } else {
  885. dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_RCV);
  886. iic_info_ptr->cur_state = IIC_FREE;
  887. }
  888. /* Clear Interrupt */
  889. iic_int_status = iic_reg_ptr->IC_CLR_INTR;
  890. }
  891. /** IIC Slave transmit called in interrupt */
  892. static void dw_iic_slv_int_process(DEV_IIC *iic_obj)
  893. {
  894. DEV_IIC_INFO *iic_info_ptr = &(iic_obj->iic_info);
  895. DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL_PTR)(iic_info_ptr->iic_ctrl);
  896. DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG_PTR)(iic_ctrl_ptr->dw_iic_regs);
  897. uint32_t iic_int_status; /** iic interrupt status */
  898. iic_int_status = (iic_reg_ptr->IC_INTR_STAT);
  899. if (iic_int_status & IC_INTR_STAT_RD_REQ) { /* Read request from master */
  900. if (iic_info_ptr->iic_cbs.tx_cb) {
  901. iic_info_ptr->iic_cbs.tx_cb(iic_obj);
  902. } else { /* When tx callback function is not set disable this tx int for slave */
  903. dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_SND);
  904. }
  905. }
  906. if (iic_int_status & IC_INTR_STAT_RX_FULL) { /* Write request from master */
  907. if (iic_info_ptr->iic_cbs.rx_cb) {
  908. iic_info_ptr->iic_cbs.rx_cb(iic_obj);
  909. } else { /* When rx callback function is not set disable this rx int for slave */
  910. dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_RCV);
  911. }
  912. }
  913. if (iic_int_status & IC_INTR_STAT_TX_OVER) {
  914. iic_ctrl_ptr->iic_tx_over ++;
  915. }
  916. if (iic_int_status & (IC_INTR_STAT_RX_OVER|IC_INTR_STAT_RX_UNDER)) {
  917. iic_ctrl_ptr->iic_rx_over ++;
  918. }
  919. if (iic_int_status & IC_INTR_STAT_TX_ABRT) {
  920. iic_info_ptr->err_state = dw_iic_slv_chkerr(iic_ctrl_ptr);
  921. if (iic_info_ptr->err_state != IIC_ERR_NONE) {
  922. if (iic_info_ptr->iic_cbs.err_cb) {
  923. iic_info_ptr->iic_cbs.err_cb(iic_obj);
  924. }
  925. }
  926. }
  927. /* Clear Interrupt */
  928. iic_int_status = iic_reg_ptr->IC_CLR_INTR;
  929. }
  930. /** @} end of group DEVICE_DW_IIC_STATIC */
  931. /**
  932. * \defgroup DEVICE_DW_IIC_IMPLEMENT DesignWare IIC Driver Function API Implement
  933. * \ingroup DEVICE_DW_IIC
  934. * \brief implement device hal iic api with DesignWare IIC
  935. * @{
  936. */
  937. /**
  938. * \brief open a designware iic device
  939. * \param[in] iic_obj iic device object pointer
  940. * \param[in] mode iic working mode (master or slave)
  941. * \param[in] param When mode is \ref DEV_MASTER_MODE, param stands for \ref dev_iic_info::speed_mode "speed mode",
  942. * when mode is \ref DEV_SLAVE_MODE, param stands for \ref dev_iic_info::slv_addr "slave device 7bit address"
  943. * \retval E_OK Open successfully without any issues
  944. * \retval E_OPNED If device was opened before with different parameters,
  945. * then just increase the \ref dev_iic_info::opn_cnt "opn_cnt" and return \ref E_OPNED
  946. * \retval E_OBJ Device object is not valid
  947. * \retval E_SYS Device is opened for different mode before, if you want to open it with different mode, you need to fully close it first.
  948. * \retval E_PAR Parameter is not valid
  949. * \retval E_NOSPT Open settings are not supported
  950. */
  951. int32_t dw_iic_open (DEV_IIC *iic_obj, uint32_t mode, uint32_t param)
  952. {
  953. int32_t ercd = E_OK;
  954. uint32_t support_modes;
  955. uint32_t param2check;
  956. DEV_IIC_INFO *iic_info_ptr = &(iic_obj->iic_info);
  957. /* START ERROR CHECK */
  958. VALID_CHK_IIC_INFO_OBJECT(iic_info_ptr);
  959. DW_IIC_CHECK_EXP((mode==DEV_MASTER_MODE)||(mode==DEV_SLAVE_MODE), E_PAR);
  960. if (mode == DEV_MASTER_MODE) {
  961. DW_IIC_CHECK_EXP((param>=IIC_SPEED_STANDARD) && (param<=IIC_SPEED_ULTRA), E_PAR);
  962. }
  963. /* END OF ERROR CHECK */
  964. DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL *)(iic_info_ptr->iic_ctrl);
  965. /* Check supported modes, master or slave */
  966. support_modes = iic_ctrl_ptr->support_modes;
  967. DW_IIC_CHECK_EXP( (((support_modes)&DW_IIC_MASTER_SUPPORTED)&&(mode == DEV_MASTER_MODE)) || \
  968. (((support_modes)&DW_IIC_SLAVE_SUPPORTED)&&(mode == DEV_SLAVE_MODE)), E_NOSPT);
  969. /** Check opened before use case */
  970. if (iic_info_ptr->opn_cnt > 0) {
  971. if (mode != iic_info_ptr->mode) {
  972. /* current working mode is different from passing mode */
  973. return E_SYS;
  974. }
  975. if (mode == DEV_MASTER_MODE) { /* param is speed_mode when as master */
  976. param2check = iic_info_ptr->speed_mode;
  977. } else { /* param is slv_addr when as slave */
  978. param2check = iic_info_ptr->slv_addr;
  979. }
  980. iic_info_ptr->opn_cnt ++;
  981. if (param != param2check) { /* open with different speed mode */
  982. return E_OPNED;
  983. } else {
  984. return E_OK;
  985. }
  986. }
  987. /* auto increase open count */
  988. iic_info_ptr->opn_cnt ++;
  989. iic_info_ptr->mode = mode;
  990. if (iic_info_ptr->addr_mode == IIC_7BIT_ADDRESS) {
  991. iic_info_ptr->tar_addr &= IIC_7BIT_ADDRESS_MASK;
  992. iic_info_ptr->slv_addr &= IIC_7BIT_ADDRESS_MASK;
  993. } else {
  994. iic_info_ptr->addr_mode = IIC_10BIT_ADDRESS;
  995. iic_info_ptr->tar_addr &= IIC_10BIT_ADDRESS_MASK;
  996. iic_info_ptr->slv_addr &= IIC_10BIT_ADDRESS_MASK;
  997. }
  998. /* Do FIFO Length get before init */
  999. #if DW_IIC_CALC_FIFO_LEN_ENABLE
  1000. iic_ctrl_ptr->tx_fifo_len = dw_iic_get_txfifo_len(iic_ctrl_ptr->dw_iic_regs);
  1001. iic_ctrl_ptr->rx_fifo_len = dw_iic_get_rxfifo_len(iic_ctrl_ptr->dw_iic_regs);
  1002. #endif
  1003. /* Disable device before init it */
  1004. dw_iic_disable_device(iic_info_ptr);
  1005. if (mode == DEV_MASTER_MODE) {
  1006. iic_info_ptr->speed_mode = param;
  1007. dw_iic_master_init(iic_ctrl_ptr, param, iic_info_ptr->addr_mode, iic_info_ptr->tar_addr);
  1008. } else {
  1009. iic_info_ptr->slv_addr = param;
  1010. dw_iic_slave_init(iic_ctrl_ptr, iic_info_ptr->addr_mode, param);
  1011. }
  1012. iic_info_ptr->status = DEV_ENABLED;
  1013. iic_info_ptr->cur_state = IIC_FREE;
  1014. iic_info_ptr->err_state = IIC_ERR_NONE;
  1015. iic_info_ptr->next_cond = IIC_MODE_STOP;
  1016. iic_info_ptr->extra = NULL;
  1017. iic_ctrl_ptr->iic_tx_over = 0;
  1018. iic_ctrl_ptr->iic_rx_over = 0;
  1019. iic_ctrl_ptr->int_status = 0;
  1020. memset(&(iic_ctrl_ptr->dw_iic_rxbuf), 0, sizeof(DW_IIC_BUFFER));
  1021. iic_ctrl_ptr->dw_iic_rxbuf.buf = &(iic_info_ptr->rx_buf);
  1022. /** install iic interrupt into system */
  1023. dw_iic_disable_interrupt(iic_info_ptr);
  1024. int_handler_install(iic_ctrl_ptr->intno, iic_ctrl_ptr->dw_iic_int_handler);
  1025. memset(&(iic_info_ptr->tx_buf), 0, sizeof(DEV_BUFFER));
  1026. memset(&(iic_info_ptr->rx_buf), 0, sizeof(DEV_BUFFER));
  1027. memset(&(iic_info_ptr->iic_cbs), 0, sizeof(DEV_IIC_CBS));
  1028. error_exit:
  1029. return ercd;
  1030. }
  1031. /**
  1032. * \brief Close a DesignWare IIC device
  1033. * \param[in] iic_obj iic device object pointer
  1034. * \retval E_OK Close successfully without any issues(including secenary that device is already closed)
  1035. * \retval E_OPNED Device is still opened, the device \ref dev_iic_info::opn_cnt "opn_cnt" decreased by 1
  1036. * \retval E_OBJ Device object is not valid
  1037. */
  1038. int32_t dw_iic_close (DEV_IIC *iic_obj)
  1039. {
  1040. int32_t ercd = E_OK;
  1041. DEV_IIC_INFO *iic_info_ptr = &(iic_obj->iic_info);
  1042. /* START ERROR CHECK */
  1043. VALID_CHK_IIC_INFO_OBJECT(iic_info_ptr);
  1044. DW_IIC_CHECK_EXP(iic_info_ptr->opn_cnt > 0, E_OK);
  1045. /* END OF ERROR CHECK */
  1046. iic_info_ptr->opn_cnt --;
  1047. if (iic_info_ptr->opn_cnt == 0) {
  1048. dw_iic_disable_interrupt(iic_info_ptr);
  1049. dw_iic_abort_tx(iic_obj);
  1050. dw_iic_abort_rx(iic_obj);
  1051. memset(&(iic_info_ptr->tx_buf), 0, sizeof(DEV_BUFFER));
  1052. memset(&(iic_info_ptr->rx_buf), 0, sizeof(DEV_BUFFER));
  1053. memset(&(iic_info_ptr->iic_cbs), 0, sizeof(DEV_IIC_CBS));
  1054. dw_iic_disable_device(iic_info_ptr);
  1055. iic_info_ptr->status = DEV_DISABLED;
  1056. iic_info_ptr->next_cond = IIC_MODE_STOP;
  1057. iic_info_ptr->extra = NULL;
  1058. } else {
  1059. ercd = E_OPNED;
  1060. }
  1061. error_exit:
  1062. return ercd;
  1063. }
  1064. /**
  1065. * \brief Control iic by ctrl command
  1066. * \param[in] iic_obj iic device object pointer
  1067. * \param[in] ctrl_cmd \ref DEVICE_HAL_IIC_CTRLCMD "control command", to change or get some thing related to iic
  1068. * \param[in,out] param parameters that maybe argument of the command,
  1069. * or return values of the command, must not be NULL
  1070. * \retval E_OK Control device successfully
  1071. * \retval E_CLSED Device is not opened
  1072. * \retval E_OBJ Device object is not valid or not exists
  1073. * \retval E_PAR Parameter is not valid for current control command
  1074. * \retval E_SYS Control device failed, due to hardware issues, such as device is disabled
  1075. * \retval E_CTX Control device failed, due to different reasons like in transfer state
  1076. * \retval E_NOSPT Control command is not supported or not valid
  1077. */
  1078. int32_t dw_iic_control (DEV_IIC *iic_obj, uint32_t ctrl_cmd, void *param)
  1079. {
  1080. int32_t ercd = E_OK;
  1081. DEV_IIC_INFO *iic_info_ptr = &(iic_obj->iic_info);
  1082. /* START ERROR CHECK */
  1083. VALID_CHK_IIC_INFO_OBJECT(iic_info_ptr);
  1084. DW_IIC_CHECK_EXP(iic_info_ptr->opn_cnt > 0, E_CLSED);
  1085. /* END OF ERROR CHECK */
  1086. uint32_t val32; /** to receive unsigned int value */
  1087. DEV_BUFFER *devbuf;
  1088. DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL *)(iic_info_ptr->iic_ctrl);
  1089. DW_IIC_REG *iic_reg_ptr = (DW_IIC_REG *)(iic_ctrl_ptr->dw_iic_regs);
  1090. /* check whether current device is disabled */
  1091. if ((iic_info_ptr->status & DEV_ENABLED) == 0) {
  1092. /** When device is disabled,
  1093. * only IIC_CMD_ENA_DEV, IIC_CMD_DIS_DEV, IIC_CMD_GET_STATUS, IIC_CMD_RESET
  1094. * are available, other commands will return E_SYS
  1095. */
  1096. if ((ctrl_cmd != IIC_CMD_ENA_DEV) && \
  1097. (ctrl_cmd != IIC_CMD_DIS_DEV) && \
  1098. (ctrl_cmd != IIC_CMD_GET_STATUS) && \
  1099. (ctrl_cmd != IIC_CMD_RESET) ) {
  1100. return E_SYS;
  1101. }
  1102. }
  1103. switch (ctrl_cmd) {
  1104. /* Commmon commands for both master and slave mode */
  1105. case IIC_CMD_GET_STATUS:
  1106. DW_IIC_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR);
  1107. *((int32_t *)param) = iic_info_ptr->status;
  1108. break;
  1109. case IIC_CMD_ENA_DEV:
  1110. dw_iic_enable_device(iic_info_ptr);
  1111. break;
  1112. case IIC_CMD_DIS_DEV:
  1113. dw_iic_disable_device(iic_info_ptr);
  1114. break;
  1115. case IIC_CMD_RESET:
  1116. dw_iic_reset_device(iic_info_ptr);
  1117. break;
  1118. case IIC_CMD_FLUSH_TX:
  1119. dw_iic_flush_tx(iic_reg_ptr);
  1120. break;
  1121. case IIC_CMD_FLUSH_RX:
  1122. dw_iic_flush_rx(iic_reg_ptr);
  1123. break;
  1124. case IIC_CMD_SET_ADDR_MODE:
  1125. val32 = (uint32_t)param;
  1126. DW_IIC_CHECK_EXP((val32==IIC_7BIT_ADDRESS) || (val32==IIC_10BIT_ADDRESS), E_PAR);
  1127. if (iic_info_ptr->mode == DEV_MASTER_MODE) {
  1128. dw_iic_set_mstaddr_mode(iic_reg_ptr, val32);
  1129. } else {
  1130. dw_iic_set_slvaddr_mode(iic_reg_ptr, val32);
  1131. }
  1132. iic_info_ptr->addr_mode = val32;
  1133. break;
  1134. case IIC_CMD_GET_RXAVAIL:
  1135. DW_IIC_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR);
  1136. *((int32_t *)param) = dw_iic_get_rxavail(iic_ctrl_ptr);
  1137. break;
  1138. case IIC_CMD_GET_TXAVAIL:
  1139. DW_IIC_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR);
  1140. *((int32_t *)param) = dw_iic_get_txavail(iic_ctrl_ptr);
  1141. break;
  1142. case IIC_CMD_SET_TXCB:
  1143. DW_IIC_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR);
  1144. iic_info_ptr->iic_cbs.tx_cb = param;
  1145. break;
  1146. case IIC_CMD_SET_RXCB:
  1147. DW_IIC_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR);
  1148. iic_info_ptr->iic_cbs.rx_cb = param;
  1149. break;
  1150. case IIC_CMD_SET_ERRCB:
  1151. DW_IIC_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR);
  1152. iic_info_ptr->iic_cbs.err_cb = param;
  1153. break;
  1154. case IIC_CMD_ABORT_TX:
  1155. dw_iic_abort_tx(iic_obj);
  1156. if ((iic_info_ptr->mode == DEV_MASTER_MODE) \
  1157. && (iic_info_ptr->cur_state == IIC_IN_TX)) {
  1158. iic_info_ptr->cur_state = IIC_FREE;
  1159. }
  1160. break;
  1161. case IIC_CMD_ABORT_RX:
  1162. dw_iic_abort_rx(iic_obj);
  1163. if ((iic_info_ptr->mode == DEV_MASTER_MODE) \
  1164. && (iic_info_ptr->cur_state == IIC_IN_RX)) {
  1165. iic_info_ptr->cur_state = IIC_FREE;
  1166. }
  1167. break;
  1168. case IIC_CMD_SET_TXINT:
  1169. if (iic_info_ptr->mode == DEV_MASTER_MODE) {
  1170. DW_IIC_CHECK_EXP(iic_info_ptr->cur_state != IIC_IN_RX, E_CTX);
  1171. }
  1172. val32 = (uint32_t)param;
  1173. if (val32 == 0) {
  1174. dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_SND);
  1175. iic_info_ptr->cur_state = IIC_FREE;
  1176. } else {
  1177. iic_info_ptr->cur_state = IIC_IN_TX;
  1178. dw_iic_ena_cbr(iic_info_ptr, DW_IIC_RDY_SND);
  1179. }
  1180. break;
  1181. case IIC_CMD_SET_RXINT:
  1182. if (iic_info_ptr->mode == DEV_MASTER_MODE) {
  1183. DW_IIC_CHECK_EXP(iic_info_ptr->cur_state != IIC_IN_TX, E_CTX);
  1184. }
  1185. val32 = (uint32_t)param;
  1186. if (val32 == 0) {
  1187. iic_info_ptr->cur_state = IIC_FREE;
  1188. dw_iic_dis_cbr(iic_info_ptr, DW_IIC_RDY_RCV);
  1189. } else {
  1190. iic_info_ptr->cur_state = IIC_IN_RX;
  1191. dw_iic_ena_cbr(iic_info_ptr, DW_IIC_RDY_RCV);
  1192. }
  1193. break;
  1194. case IIC_CMD_SET_TXINT_BUF:
  1195. if (iic_info_ptr->mode == DEV_MASTER_MODE) {
  1196. DW_IIC_CHECK_EXP(iic_info_ptr->cur_state != IIC_IN_TX, E_CTX);
  1197. }
  1198. DW_IIC_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR);
  1199. if (param != NULL) {
  1200. devbuf = (DEV_BUFFER *)param;
  1201. iic_info_ptr->tx_buf = *devbuf;
  1202. iic_info_ptr->tx_buf.ofs = 0;
  1203. } else {
  1204. iic_info_ptr->tx_buf.buf = NULL;
  1205. iic_info_ptr->tx_buf.len = 0;
  1206. iic_info_ptr->tx_buf.ofs = 0;
  1207. }
  1208. break;
  1209. case IIC_CMD_SET_RXINT_BUF:
  1210. if (iic_info_ptr->mode == DEV_MASTER_MODE) {
  1211. DW_IIC_CHECK_EXP(iic_info_ptr->cur_state != IIC_IN_RX, E_CTX);
  1212. }
  1213. DW_IIC_CHECK_EXP(CHECK_ALIGN_4BYTES(param), E_PAR);
  1214. if (param != NULL) {
  1215. devbuf = (DEV_BUFFER *)param;
  1216. iic_info_ptr->rx_buf = *devbuf;
  1217. iic_info_ptr->rx_buf.ofs = 0;
  1218. iic_ctrl_ptr->dw_iic_rxbuf.ofs = 0;
  1219. iic_ctrl_ptr->dw_iic_rxbuf.len = devbuf->len;
  1220. } else {
  1221. iic_info_ptr->rx_buf.buf = NULL;
  1222. iic_info_ptr->rx_buf.len = 0;
  1223. iic_info_ptr->rx_buf.ofs = 0;
  1224. iic_ctrl_ptr->dw_iic_rxbuf.ofs = 0;
  1225. iic_ctrl_ptr->dw_iic_rxbuf.len = 0;
  1226. }
  1227. break;
  1228. /* Master mode only commands */
  1229. case IIC_CMD_MST_SET_SPEED_MODE:
  1230. DW_IIC_CHECK_EXP(iic_info_ptr->mode == DEV_MASTER_MODE, E_NOSPT);
  1231. val32 = (uint32_t)param;
  1232. DW_IIC_CHECK_EXP((val32>=IIC_SPEED_STANDARD) && (val32<=IIC_SPEED_ULTRA), E_PAR);
  1233. dw_iic_set_speedmode(iic_reg_ptr, val32);
  1234. iic_info_ptr->speed_mode = val32;
  1235. break;
  1236. case IIC_CMD_MST_SET_TAR_ADDR:
  1237. DW_IIC_CHECK_EXP(iic_info_ptr->mode == DEV_MASTER_MODE, E_NOSPT);
  1238. if (iic_info_ptr->addr_mode == IIC_7BIT_ADDRESS) {
  1239. val32 = ((uint32_t)param) & IIC_7BIT_ADDRESS_MASK;
  1240. } else {
  1241. val32 = ((uint32_t)param) & IIC_10BIT_ADDRESS_MASK;
  1242. }
  1243. if (val32 != iic_info_ptr->tar_addr) {
  1244. dw_iic_set_taraddr(iic_reg_ptr, val32);
  1245. iic_info_ptr->tar_addr = val32;
  1246. }
  1247. break;
  1248. case IIC_CMD_MST_SET_NEXT_COND:
  1249. DW_IIC_CHECK_EXP(iic_info_ptr->mode == DEV_MASTER_MODE, E_NOSPT);
  1250. val32 = (uint32_t)param;
  1251. DW_IIC_CHECK_EXP((val32==IIC_MODE_STOP) || (val32==IIC_MODE_RESTART), E_PAR);
  1252. iic_info_ptr->next_cond = (uint32_t)param;
  1253. break;
  1254. /* Slave mode only commands */
  1255. case IIC_CMD_SLV_SET_SLV_ADDR:
  1256. DW_IIC_CHECK_EXP(iic_info_ptr->mode == DEV_SLAVE_MODE, E_NOSPT);
  1257. if (iic_info_ptr->addr_mode == IIC_7BIT_ADDRESS) {
  1258. val32 = ((uint32_t)param) & IIC_7BIT_ADDRESS_MASK;
  1259. } else {
  1260. val32 = ((uint32_t)param) & IIC_10BIT_ADDRESS_MASK;
  1261. }
  1262. dw_iic_set_slvaddr(iic_reg_ptr, val32);
  1263. iic_info_ptr->slv_addr = val32;
  1264. break;
  1265. case IIC_CMD_SLV_GET_SLV_STATE:
  1266. DW_IIC_CHECK_EXP(iic_info_ptr->mode == DEV_SLAVE_MODE, E_NOSPT);
  1267. DW_IIC_CHECK_EXP((param!=NULL) && CHECK_ALIGN_4BYTES(param), E_PAR);
  1268. *((uint32_t *)param) = dw_iic_get_slv_state(iic_reg_ptr);
  1269. break;
  1270. default:
  1271. ercd = E_NOSPT;
  1272. break;
  1273. }
  1274. error_exit:
  1275. return ercd;
  1276. }
  1277. /**
  1278. * \brief poll transmit data through DesignWare IIC as master or slave
  1279. * \param[in] iic_obj iic device object pointer
  1280. * \param[in] data data that need to send (data must be uint8_t type)
  1281. * \param[in] len data length need to send
  1282. * \retval >0 Byte count that was successfully sent for poll method,
  1283. * it might can't send that much due to \ref \ref dev_iic_info::err_state "different error state".
  1284. * \retval E_OBJ Device object is not valid or not exists
  1285. * \retval E_PAR Parameter is not valid
  1286. * \retval E_CTX Device is still in transfer state
  1287. * \retval E_SYS Can't write data to hardware due to hardware issues, such as device is disabled
  1288. */
  1289. int32_t dw_iic_write (DEV_IIC *iic_obj, const void *data, uint32_t len)
  1290. {
  1291. int32_t ercd = E_OK;
  1292. DEV_IIC_INFO *iic_info_ptr = &(iic_obj->iic_info);
  1293. /* START ERROR CHECK */
  1294. VALID_CHK_IIC_INFO_OBJECT(iic_info_ptr);
  1295. DW_IIC_CHECK_EXP(iic_info_ptr->opn_cnt > 0, E_CLSED);
  1296. DW_IIC_CHECK_EXP(iic_info_ptr->status & DEV_ENABLED, E_SYS);
  1297. DW_IIC_CHECK_EXP(data!=NULL, E_PAR);
  1298. DW_IIC_CHECK_EXP(len>0, E_PAR);
  1299. /* END OF ERROR CHECK */
  1300. int32_t i = 0;
  1301. uint32_t last_cond = 0; /* Last data for transmit, STOP or RESTART */
  1302. int32_t error_state = IIC_ERR_NONE;
  1303. const uint8_t *p_charbuf = (const uint8_t *)data;
  1304. DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL_PTR)(iic_info_ptr->iic_ctrl);
  1305. if (iic_info_ptr->mode == DEV_MASTER_MODE) { /* Master mode transmit data */
  1306. if (iic_info_ptr->next_cond == IIC_MODE_STOP) {
  1307. last_cond = IC_DATA_CMD_STOP;
  1308. } else {
  1309. last_cond = IC_DATA_CMD_RESTART;
  1310. }
  1311. /* Try to transmit 0 -> (len-1) data */
  1312. len = len - 1; /* Last data write differently */
  1313. while (i < len) {
  1314. error_state = dw_iic_mst_write_data(iic_ctrl_ptr, (uint32_t)(p_charbuf[i]), IC_DATA_CMD_NONE);
  1315. if (error_state != IIC_ERR_NONE) {
  1316. break;
  1317. }
  1318. i ++;
  1319. }
  1320. /* Try to transmit the last data with STOP or RESTART condition */
  1321. if (error_state == IIC_ERR_NONE) {
  1322. error_state = dw_iic_mst_write_data(iic_ctrl_ptr, (uint32_t)(p_charbuf[len]), last_cond);
  1323. if (error_state == IIC_ERR_NONE) {
  1324. i = i + 1; /* Add last data into send count */
  1325. }
  1326. }
  1327. } else { /* Slave mode transmit data */
  1328. while (i < len) {
  1329. error_state = dw_iic_slv_write_data(iic_ctrl_ptr, (uint32_t)(p_charbuf[i]));
  1330. if (error_state != IIC_ERR_NONE) {
  1331. break;
  1332. }
  1333. i ++;
  1334. }
  1335. }
  1336. iic_info_ptr->err_state = error_state;
  1337. ercd = i;
  1338. error_exit:
  1339. return ercd;
  1340. }
  1341. /**
  1342. * \brief read data through DesignWare IIC
  1343. * \param[in] iic_obj iic device object pointer
  1344. * \param[out] data data that need to read (data must be uint8_t type)
  1345. * \param[in] len data count need to read
  1346. * \retval >0 Byte count that was successfully received for poll method,
  1347. * it might can't send that much due to \ref \ref dev_iic_info::err_state "different error state".
  1348. * \retval E_OBJ Device object is not valid or not exists
  1349. * \retval E_CTX Device is still in transfer state
  1350. * \retval E_PAR Parameter is not valid
  1351. * \retval E_SYS Can't receive data from hardware due to hardware issues, such as device is disabled
  1352. */
  1353. int32_t dw_iic_read (DEV_IIC *iic_obj, void *data, uint32_t len)
  1354. {
  1355. int32_t ercd = E_OK;
  1356. DEV_IIC_INFO *iic_info_ptr = &(iic_obj->iic_info);
  1357. /* START ERROR CHECK */
  1358. VALID_CHK_IIC_INFO_OBJECT(iic_info_ptr);
  1359. DW_IIC_CHECK_EXP(iic_info_ptr->opn_cnt > 0, E_CLSED);
  1360. DW_IIC_CHECK_EXP(iic_info_ptr->status & DEV_ENABLED, E_SYS);
  1361. DW_IIC_CHECK_EXP(data!=NULL, E_PAR);
  1362. DW_IIC_CHECK_EXP(len>0, E_PAR);
  1363. /* END OF ERROR CHECK */
  1364. int32_t i = 0;
  1365. uint32_t last_cond = 0; /* Last data for receive, STOP or RESTART */
  1366. uint32_t val32 = 0;
  1367. int32_t error_state = IIC_ERR_NONE;
  1368. uint8_t *p_charbuf = (uint8_t *)data;
  1369. DW_IIC_CTRL *iic_ctrl_ptr = (DW_IIC_CTRL_PTR)(iic_info_ptr->iic_ctrl);
  1370. if (iic_info_ptr->mode == DEV_MASTER_MODE) { /* Master mode receive data */
  1371. if (iic_info_ptr->next_cond == IIC_MODE_STOP) {
  1372. last_cond = IC_DATA_CMD_STOP;
  1373. } else {
  1374. last_cond = IC_DATA_CMD_RESTART;
  1375. }
  1376. /* Try to receive 0 -> (len-1) data */
  1377. len = len - 1; /* Last data write differently */
  1378. while (i < len) {
  1379. error_state = dw_iic_mst_read_data(iic_ctrl_ptr, &val32, IC_DATA_CMD_NONE);
  1380. if (error_state != IIC_ERR_NONE) {
  1381. break;
  1382. } else {
  1383. p_charbuf[i] = (uint8_t)val32;
  1384. }
  1385. i ++;
  1386. }
  1387. /* Try to receive the last data with STOP or RESTART condition */
  1388. if (error_state == IIC_ERR_NONE) {
  1389. error_state = dw_iic_mst_read_data(iic_ctrl_ptr, &val32, last_cond);
  1390. if (error_state == IIC_ERR_NONE) {
  1391. p_charbuf[len] = (uint8_t)val32;
  1392. i = i + 1; /* Add last data into send count */
  1393. }
  1394. }
  1395. } else { /* Slave mode receive data */
  1396. while (i < len) {
  1397. error_state = dw_iic_slv_read_data(iic_ctrl_ptr, &val32);
  1398. if (error_state != IIC_ERR_NONE) {
  1399. break;
  1400. } else {
  1401. p_charbuf[i] = (uint8_t)val32;
  1402. }
  1403. i ++;
  1404. }
  1405. }
  1406. iic_info_ptr->err_state = error_state;
  1407. ercd = i;
  1408. error_exit:
  1409. return ercd;
  1410. }
  1411. /**
  1412. * \brief DesignWare IIC interrupt processing routine
  1413. * \param[in] iic_info_ptr DEV_IIC *iic_obj
  1414. * \param[in] ptr extra information
  1415. */
  1416. void dw_iic_isr(DEV_IIC *iic_obj, void *ptr)
  1417. {
  1418. int32_t ercd = E_OK;
  1419. DEV_IIC_INFO *iic_info_ptr = &(iic_obj->iic_info);
  1420. /* START ERROR CHECK */
  1421. VALID_CHK_IIC_INFO_OBJECT(iic_info_ptr);
  1422. /* END OF ERROR CHECK */
  1423. if (iic_info_ptr->mode == DEV_MASTER_MODE) {
  1424. if (iic_info_ptr->cur_state == IIC_IN_TX) {
  1425. dw_iic_mst_int_write(iic_obj);
  1426. } else {
  1427. dw_iic_mst_int_read(iic_obj);
  1428. }
  1429. } else {
  1430. dw_iic_slv_int_process(iic_obj);
  1431. }
  1432. error_exit:
  1433. return;
  1434. }
  1435. /** @} end of group DEVICE_DW_IIC_IMPLEMENT */