I2C_LPC18xx.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968
  1. /* --------------------------------------------------------------------------
  2. * Copyright (c) 2013-2016 ARM Limited. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the License); you may
  7. * not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an AS IS BASIS, WITHOUT
  14. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. *
  18. * $Date: 02. March 2016
  19. * $Revision: V2.4
  20. *
  21. * Driver: Driver_I2C0, Driver_I2C1
  22. * Configured: via RTE_Device.h configuration file
  23. * Project: I2C Driver for NXP LPC18xx
  24. * --------------------------------------------------------------------------
  25. * Use the following configuration settings in the middleware component
  26. * to connect to this driver.
  27. *
  28. * Configuration Setting Value I2C Interface
  29. * --------------------- ----- -------------
  30. * Connect to hardware via Driver_I2C# = 0 use I2C0
  31. * Connect to hardware via Driver_I2C# = 1 use I2C1
  32. * -------------------------------------------------------------------------- */
  33. /* History:
  34. * Version 2.4
  35. * - Added Bus Clear Control
  36. * - Corrected PowerControl function for conditional Power full (driver must be initialized)
  37. * Version 2.3
  38. * - Pending IRQ flag cleared after aborted transfer
  39. * Version 2.2
  40. * - Updated initialization, uninitialization and power procedures
  41. * Version 2.1
  42. * - Updated to CMSIS Driver API V2.02
  43. * - Added Multi-master support
  44. * Version 2.0
  45. * - Based on API V2.00
  46. * Version 1.1
  47. * - Based on API V1.10 (namespace prefix ARM_ added)
  48. * Version 1.0
  49. * - Initial release
  50. */
  51. #include <string.h>
  52. #include "I2C_LPC18xx.h"
  53. #include "SCU_LPC18xx.h"
  54. #include "Driver_I2C.h"
  55. #include "RTE_Device.h"
  56. #include "RTE_Components.h"
  57. #define ARM_I2C_DRV_VERSION ARM_DRIVER_VERSION_MAJOR_MINOR(2,4) /* driver version */
  58. #if ((defined(RTE_Drivers_I2C0) || \
  59. defined(RTE_Drivers_I2C1)) \
  60. && !RTE_I2C0 \
  61. && !RTE_I2C1)
  62. #error "I2C not configured in RTE_Device.h!"
  63. #endif
  64. /* I2C core clock (system_LPC18xx.c) */
  65. extern uint32_t GetClockFreq (uint32_t clk_src);
  66. /* Driver Version */
  67. static const ARM_DRIVER_VERSION DriverVersion = {
  68. ARM_I2C_API_VERSION,
  69. ARM_I2C_DRV_VERSION
  70. };
  71. /* Driver Capabilities */
  72. static const ARM_I2C_CAPABILITIES DriverCapabilities = {
  73. 0 /* supports 10-bit addressing */
  74. };
  75. #if (RTE_I2C0)
  76. /* I2C0 Control Information */
  77. static I2C_CTRL I2C0_Ctrl = { 0 };
  78. /* I2C0 Resources */
  79. static I2C_RESOURCES I2C0_Resources = {
  80. LPC_I2C0,
  81. I2C0_IRQn,
  82. &LPC_CGU->BASE_APB1_CLK,
  83. &LPC_CCU1->CLK_APB1_I2C0_CFG,
  84. &LPC_CCU1->CLK_APB1_I2C0_STAT,
  85. RGU_RESET_I2C0,
  86. &I2C0_Ctrl
  87. };
  88. #endif /* RTE_I2C0 */
  89. #if (RTE_I2C1)
  90. /* I2C1 Control Information */
  91. static I2C_CTRL I2C1_Ctrl = { 0 };
  92. /* I2C1 Resources */
  93. static I2C_RESOURCES I2C1_Resources = {
  94. LPC_I2C1,
  95. I2C1_IRQn,
  96. &LPC_CGU->BASE_APB3_CLK,
  97. &LPC_CCU1->CLK_APB3_I2C1_CFG,
  98. &LPC_CCU1->CLK_APB3_I2C1_STAT,
  99. RGU_RESET_I2C1,
  100. &I2C1_Ctrl
  101. };
  102. #endif /* RTE_I2C1 */
  103. /**
  104. \fn ARM_DRIVER_VERSION I2C_GetVersion (void)
  105. \brief Get driver version.
  106. \return \ref ARM_DRIVER_VERSION
  107. */
  108. static ARM_DRIVER_VERSION I2C_GetVersion (void) {
  109. return DriverVersion;
  110. }
  111. /**
  112. \fn ARM_I2C_CAPABILITIES I2C_GetCapabilities (void)
  113. \brief Get driver capabilities.
  114. \return \ref ARM_I2C_CAPABILITIES
  115. */
  116. static ARM_I2C_CAPABILITIES I2C_GetCapabilities (void) {
  117. return DriverCapabilities;
  118. }
  119. /**
  120. \fn int32_t I2Cx_Initialize (ARM_I2C_SignalEvent_t cb_event,
  121. I2C_RESOURCES *i2c)
  122. \brief Initialize I2C Interface.
  123. \param[in] cb_event Pointer to \ref ARM_I2C_SignalEvent
  124. \param[in] i2c Pointer to I2C resources
  125. \return \ref execution_status
  126. */
  127. static int32_t I2Cx_Initialize (ARM_I2C_SignalEvent_t cb_event, I2C_RESOURCES *i2c) {
  128. if (i2c->ctrl->flags & I2C_FLAG_INIT) { return ARM_DRIVER_OK; }
  129. /* Configure I2C Pins */
  130. if (i2c->reg == LPC_I2C0) {
  131. SCU_I2C_PinConfigure (SCU_I2C_PIN_MODE_STANDARD_FAST);
  132. }
  133. else if (i2c->reg == LPC_I2C1) {
  134. SCU_PinConfigure (RTE_I2C1_SCL_PORT, RTE_I2C1_SCL_PIN, SCU_SFS_EZI | RTE_I2C1_SCL_FUNC);
  135. SCU_PinConfigure (RTE_I2C1_SDA_PORT, RTE_I2C1_SDA_PIN, SCU_SFS_EZI | RTE_I2C1_SDA_FUNC);
  136. }
  137. /* Reset Run-Time information structure */
  138. memset (i2c->ctrl, 0x00, sizeof (I2C_CTRL));
  139. i2c->ctrl->cb_event = cb_event;
  140. i2c->ctrl->flags = I2C_FLAG_INIT;
  141. return ARM_DRIVER_OK;
  142. }
  143. /**
  144. \fn int32_t I2Cx_Uninitialize (I2C_RESOURCES *i2c)
  145. \brief De-initialize I2C Interface.
  146. \param[in] i2c Pointer to I2C resources
  147. \return \ref execution_status
  148. */
  149. static int32_t I2Cx_Uninitialize (I2C_RESOURCES *i2c) {
  150. i2c->ctrl->flags = 0;
  151. /* Unconfigure SCL and SDA pins */
  152. if (i2c->reg == LPC_I2C0) {
  153. SCU_I2C_PinConfigure (0);
  154. }
  155. else if (i2c->reg == LPC_I2C1) {
  156. SCU_PinConfigure (RTE_I2C1_SCL_PORT, RTE_I2C1_SCL_PIN, 0);
  157. SCU_PinConfigure (RTE_I2C1_SDA_PORT, RTE_I2C1_SDA_PIN, 0);
  158. }
  159. return ARM_DRIVER_OK;
  160. }
  161. /**
  162. \fn int32_t I2Cx_PowerControl (ARM_POWER_STATE state,
  163. I2C_RESOURCES *i2c)
  164. \brief Control I2C Interface Power.
  165. \param[in] state Power state
  166. \param[in] i2c Pointer to I2C resources
  167. \return \ref execution_status
  168. */
  169. static int32_t I2Cx_PowerControl (ARM_POWER_STATE state, I2C_RESOURCES *i2c) {
  170. uint32_t conset;
  171. switch (state) {
  172. case ARM_POWER_OFF:
  173. /* Disable I2C interrupts */
  174. NVIC_DisableIRQ (i2c->i2c_ev_irq);
  175. if (i2c->ctrl->status.busy) {
  176. /* Master: send STOP to I2C bus */
  177. /* Slave: enter non-addressed Slave mode */
  178. conset = I2C_CON_STO | i2c->ctrl->con_aa;
  179. i2c->reg->CONSET = conset;
  180. i2c->reg->CONCLR = conset ^ I2C_CON_FLAGS;
  181. }
  182. i2c->ctrl->status.busy = 0U;
  183. i2c->ctrl->status.mode = 0U;
  184. i2c->ctrl->status.direction = 0U;
  185. i2c->ctrl->status.general_call = 0U;
  186. i2c->ctrl->status.arbitration_lost = 0U;
  187. i2c->ctrl->status.bus_error = 0U;
  188. i2c->ctrl->stalled = 0U;
  189. i2c->ctrl->snum = 0U;
  190. i2c->ctrl->flags &= ~I2C_FLAG_POWER;
  191. /* Reset I2C peripheral */
  192. LPC_RGU->RESET_CTRL1 = i2c->rgu_val;
  193. while (!(LPC_RGU->RESET_ACTIVE_STATUS1 & i2c->rgu_val));
  194. /* Disable I2C peripheral clock */
  195. *i2c->pclk_cfg_reg &= ~CCU_CLK_CFG_RUN;
  196. break;
  197. case ARM_POWER_FULL:
  198. if ((i2c->ctrl->flags & I2C_FLAG_INIT) == 0U) { return ARM_DRIVER_ERROR; }
  199. if ((i2c->ctrl->flags & I2C_FLAG_POWER) != 0U) { return ARM_DRIVER_OK; }
  200. /* Connect base clock */
  201. *i2c->base_clk_reg = (1 << 11) | /* Autoblock En */
  202. (0x09 << 24) ; /* PLL1 is APB clock source */
  203. /* Enable I2C peripheral clock */
  204. *i2c->pclk_cfg_reg = CCU_CLK_CFG_AUTO | CCU_CLK_CFG_RUN;
  205. while (!((*i2c->pclk_stat_reg) & CCU_CLK_STAT_RUN));
  206. /* Reset I2C peripheral */
  207. LPC_RGU->RESET_CTRL1 = i2c->rgu_val;
  208. while (!(LPC_RGU->RESET_ACTIVE_STATUS1 & i2c->rgu_val));
  209. /* Enable I2C Operation */
  210. i2c->reg->CONCLR = I2C_CON_FLAGS;
  211. i2c->reg->CONSET = I2C_CON_I2EN;
  212. i2c->ctrl->stalled = 0;
  213. i2c->ctrl->con_aa = 0;
  214. /* Enable I2C interrupts */
  215. NVIC_ClearPendingIRQ (i2c->i2c_ev_irq);
  216. NVIC_EnableIRQ (i2c->i2c_ev_irq);
  217. i2c->ctrl->flags |= I2C_FLAG_POWER;
  218. break;
  219. default:
  220. return ARM_DRIVER_ERROR_UNSUPPORTED;
  221. }
  222. return ARM_DRIVER_OK;
  223. }
  224. /**
  225. \fn int32_t I2Cx_MasterTransmit (uint32_t addr,
  226. const uint8_t *data,
  227. uint32_t num,
  228. bool xfer_pending,
  229. I2C_RESOURCES *i2c)
  230. \brief Start transmitting data as I2C Master.
  231. \param[in] addr Slave address (7-bit or 10-bit)
  232. \param[in] data Pointer to buffer with data to transmit to I2C Slave
  233. \param[in] num Number of data bytes to transmit
  234. \param[in] xfer_pending Transfer operation is pending - Stop condition will not be generated
  235. \param[in] i2c Pointer to I2C resources
  236. \return \ref execution_status
  237. */
  238. static int32_t I2Cx_MasterTransmit (uint32_t addr,
  239. const uint8_t *data,
  240. uint32_t num,
  241. bool xfer_pending,
  242. I2C_RESOURCES *i2c) {
  243. if (!data || !num || (addr > 0x7F)) {
  244. /* Invalid parameters */
  245. return ARM_DRIVER_ERROR_PARAMETER;
  246. }
  247. if (!(i2c->ctrl->flags & I2C_FLAG_SETUP)) {
  248. /* Driver not yet configured */
  249. return ARM_DRIVER_ERROR;
  250. }
  251. if (i2c->ctrl->status.busy || (i2c->ctrl->stalled & I2C_SLAVE)) {
  252. /* Transfer operation in progress, or Slave stalled */
  253. return ARM_DRIVER_ERROR_BUSY;
  254. }
  255. NVIC_DisableIRQ (i2c->i2c_ev_irq);
  256. /* Set control variables */
  257. i2c->ctrl->sla_rw = addr << 1;
  258. i2c->ctrl->pending = xfer_pending;
  259. i2c->ctrl->data = (uint8_t *)data;
  260. i2c->ctrl->num = num;
  261. i2c->ctrl->cnt = -1;
  262. /* Update driver status */
  263. i2c->ctrl->status.busy = 1;
  264. i2c->ctrl->status.mode = 1;
  265. i2c->ctrl->status.direction = 0;
  266. i2c->ctrl->status.arbitration_lost = 0;
  267. i2c->ctrl->status.bus_error = 0;
  268. if (!i2c->ctrl->stalled) {
  269. i2c->reg->CONSET = I2C_CON_STA | i2c->ctrl->con_aa;
  270. }
  271. NVIC_EnableIRQ (i2c->i2c_ev_irq);
  272. return ARM_DRIVER_OK;
  273. }
  274. /**
  275. \fn int32_t I2Cx_MasterReceive (uint32_t addr,
  276. uint8_t *data,
  277. uint32_t num,
  278. bool xfer_pending,
  279. I2C_RESOURCES *i2c)
  280. \brief Start receiving data as I2C Master.
  281. \param[in] addr Slave address (7-bit or 10-bit)
  282. \param[out] data Pointer to buffer for data to receive from I2C Slave
  283. \param[in] num Number of data bytes to receive
  284. \param[in] xfer_pending Transfer operation is pending - Stop condition will not be generated
  285. \param[in] i2c Pointer to I2C resources
  286. \return \ref execution_status
  287. */
  288. static int32_t I2Cx_MasterReceive (uint32_t addr,
  289. uint8_t *data,
  290. uint32_t num,
  291. bool xfer_pending,
  292. I2C_RESOURCES *i2c) {
  293. if (!data || !num || (addr > 0x7F)) {
  294. /* Invalid parameters */
  295. return ARM_DRIVER_ERROR_PARAMETER;
  296. }
  297. if (!(i2c->ctrl->flags & I2C_FLAG_SETUP)) {
  298. /* Driver not yet configured */
  299. return ARM_DRIVER_ERROR;
  300. }
  301. if (i2c->ctrl->status.busy || (i2c->ctrl->stalled & I2C_SLAVE)) {
  302. /* Transfer operation in progress, or Slave stalled */
  303. return ARM_DRIVER_ERROR_BUSY;
  304. }
  305. NVIC_DisableIRQ (i2c->i2c_ev_irq);
  306. /* Set control variables */
  307. i2c->ctrl->sla_rw = (addr << 1) | 0x01;
  308. i2c->ctrl->pending = xfer_pending;
  309. i2c->ctrl->data = data;
  310. i2c->ctrl->num = num;
  311. i2c->ctrl->cnt = -1;
  312. /* Update driver status */
  313. i2c->ctrl->status.busy = 1;
  314. i2c->ctrl->status.mode = 1;
  315. i2c->ctrl->status.direction = 0;
  316. i2c->ctrl->status.arbitration_lost = 0;
  317. i2c->ctrl->status.bus_error = 0;
  318. if (!i2c->ctrl->stalled) {
  319. i2c->reg->CONSET = I2C_CON_STA | i2c->ctrl->con_aa;
  320. }
  321. NVIC_EnableIRQ (i2c->i2c_ev_irq);
  322. return ARM_DRIVER_OK;
  323. }
  324. /**
  325. \fn int32_t I2Cx_SlaveTransmit (const uint8_t *data,
  326. uint32_t num,
  327. I2C_RESOURCES *i2c)
  328. \brief Start transmitting data as I2C Slave.
  329. \param[in] data Pointer to buffer with data to transmit to I2C Master
  330. \param[in] num Number of data bytes to transmit
  331. \param[in] i2c Pointer to I2C resources
  332. \return \ref execution_status
  333. */
  334. static int32_t I2Cx_SlaveTransmit (const uint8_t *data,
  335. uint32_t num,
  336. I2C_RESOURCES *i2c) {
  337. if (!data || !num) {
  338. /* Invalid parameters */
  339. return ARM_DRIVER_ERROR_PARAMETER;
  340. }
  341. if (i2c->ctrl->status.busy || (i2c->ctrl->stalled & (I2C_MASTER | I2C_SLAVE_RX))) {
  342. /* Transfer operation in progress, Master stalled or Slave receive stalled */
  343. return ARM_DRIVER_ERROR_BUSY;
  344. }
  345. NVIC_DisableIRQ (i2c->i2c_ev_irq);
  346. /* Set control variables */
  347. i2c->ctrl->flags &= ~I2C_FLAG_SLAVE_RX;
  348. i2c->ctrl->sdata = (uint8_t *)data;
  349. i2c->ctrl->snum = num;
  350. i2c->ctrl->cnt = -1;
  351. /* Update driver status */
  352. i2c->ctrl->status.general_call = 0;
  353. i2c->ctrl->status.bus_error = 0;
  354. NVIC_EnableIRQ (i2c->i2c_ev_irq);
  355. return ARM_DRIVER_OK;
  356. }
  357. /**
  358. \fn int32_t I2Cx_SlaveReceive (uint8_t *data,
  359. uint32_t num,
  360. I2C_RESOURCES *i2c)
  361. \brief Start receiving data as I2C Slave.
  362. \param[out] data Pointer to buffer for data to receive from I2C Master
  363. \param[in] num Number of data bytes to receive
  364. \param[in] i2c Pointer to I2C resources
  365. \return \ref execution_status
  366. */
  367. static int32_t I2Cx_SlaveReceive (uint8_t *data,
  368. uint32_t num,
  369. I2C_RESOURCES *i2c) {
  370. if (!data || !num) {
  371. /* Invalid parameters */
  372. return ARM_DRIVER_ERROR_PARAMETER;
  373. }
  374. if (i2c->ctrl->status.busy || (i2c->ctrl->stalled & (I2C_MASTER | I2C_SLAVE_TX))) {
  375. /* Transfer operation in progress, Master stalled or Slave transmit stalled */
  376. return ARM_DRIVER_ERROR_BUSY;
  377. }
  378. NVIC_DisableIRQ (i2c->i2c_ev_irq);
  379. /* Set control variables */
  380. i2c->ctrl->flags |= I2C_FLAG_SLAVE_RX;
  381. i2c->ctrl->sdata = data;
  382. i2c->ctrl->snum = num;
  383. i2c->ctrl->cnt = -1;
  384. /* Update driver status */
  385. i2c->ctrl->status.general_call = 0;
  386. i2c->ctrl->status.bus_error = 0;
  387. NVIC_EnableIRQ (i2c->i2c_ev_irq);
  388. return ARM_DRIVER_OK;
  389. }
  390. /**
  391. \fn int32_t I2Cx_GetDataCount (I2C_RESOURCES *i2c)
  392. \brief Get transferred data count.
  393. \return number of data bytes transferred; -1 when Slave is not addressed by Master
  394. */
  395. static int32_t I2Cx_GetDataCount (I2C_RESOURCES *i2c) {
  396. return (i2c->ctrl->cnt);
  397. }
  398. /**
  399. \fn int32_t I2Cx_Control (uint32_t control,
  400. uint32_t arg,
  401. I2C_RESOURCES *i2c)
  402. \brief Control I2C Interface.
  403. \param[in] control operation
  404. \param[in] arg argument of operation (optional)
  405. \param[in] i2c pointer to I2C resources
  406. \return \ref execution_status
  407. */
  408. static int32_t I2Cx_Control (uint32_t control, uint32_t arg, I2C_RESOURCES *i2c) {
  409. uint32_t val,clk,conset;
  410. if (!(i2c->ctrl->flags & I2C_FLAG_POWER)) {
  411. /* Driver not powered */
  412. return ARM_DRIVER_ERROR;
  413. }
  414. switch (control) {
  415. case ARM_I2C_OWN_ADDRESS:
  416. /* Set Own Slave Address */
  417. val = (arg << 1) & 0xFF;
  418. if (arg & ARM_I2C_ADDRESS_GC) {
  419. /* General call enable */
  420. val |= 0x01;
  421. }
  422. i2c->reg->ADR0 = val;
  423. /* Enable assert acknowledge */
  424. if (val) val = I2C_CON_AA;
  425. i2c->ctrl->con_aa = val;
  426. i2c->reg->CONSET = val;
  427. break;
  428. case ARM_I2C_BUS_SPEED:
  429. /* Set Bus Speed */
  430. clk = GetClockFreq (CLK_SRC_PLL1);
  431. switch (arg) {
  432. case ARM_I2C_BUS_SPEED_STANDARD:
  433. /* Standard Speed (100kHz) */
  434. clk /= 100000;
  435. break;
  436. case ARM_I2C_BUS_SPEED_FAST:
  437. /* Fast Speed (400kHz) */
  438. clk /= 400000;
  439. break;
  440. case ARM_I2C_BUS_SPEED_FAST_PLUS:
  441. /* Fast+ Speed ( 1MHz) */
  442. if (i2c->reg == LPC_I2C0) {
  443. clk /= 1000000;
  444. break;
  445. }
  446. default:
  447. return ARM_DRIVER_ERROR_UNSUPPORTED;
  448. }
  449. /* Improve accuracy */
  450. i2c->reg->SCLH = clk / 2;
  451. i2c->reg->SCLL = clk - i2c->reg->SCLH;
  452. /* Speed configured, I2C Master active */
  453. i2c->ctrl->flags |= I2C_FLAG_SETUP;
  454. break;
  455. case ARM_I2C_BUS_CLEAR:
  456. /* Execute Bus clear */
  457. NVIC_DisableIRQ (i2c->i2c_ev_irq);
  458. i2c->reg->CONSET = I2C_CON_STA;
  459. __NOP(); __NOP(); __NOP();
  460. if ((i2c->reg->CONSET & I2C_CON_SI) == 0) {
  461. for (val = 0; val < 2048; val++);
  462. }
  463. /* Clear start and interrupt flag */
  464. i2c->reg->CONCLR = I2C_CON_STA | I2C_CON_SI;
  465. /* Send STOP to end the transaction */
  466. i2c->reg->CONSET = I2C_CON_STO;
  467. NVIC_ClearPendingIRQ (i2c->i2c_ev_irq);
  468. NVIC_EnableIRQ (i2c->i2c_ev_irq);
  469. return ARM_DRIVER_OK;
  470. case ARM_I2C_ABORT_TRANSFER:
  471. /* Abort Master/Slave transfer */
  472. NVIC_DisableIRQ (i2c->i2c_ev_irq);
  473. i2c->ctrl->status.busy = 0;
  474. i2c->ctrl->stalled = 0;
  475. i2c->ctrl->snum = 0;
  476. /* Master: send STOP to I2C bus */
  477. /* Slave: enter non-addressed Slave mode */
  478. conset = I2C_CON_STO | i2c->ctrl->con_aa;
  479. i2c->reg->CONSET = conset;
  480. i2c->reg->CONCLR = conset ^ I2C_CON_FLAGS;
  481. NVIC_ClearPendingIRQ (i2c->i2c_ev_irq);
  482. NVIC_EnableIRQ (i2c->i2c_ev_irq);
  483. break;
  484. default:
  485. return ARM_DRIVER_ERROR_UNSUPPORTED;
  486. }
  487. return ARM_DRIVER_OK;
  488. }
  489. /**
  490. \fn ARM_I2C_STATUS I2Cx_GetStatus (I2C_RESOURCES *i2c)
  491. \brief Get I2C status.
  492. \param[in] i2c pointer to I2C resources
  493. \return I2C status \ref ARM_I2C_STATUS
  494. */
  495. static ARM_I2C_STATUS I2Cx_GetStatus (I2C_RESOURCES *i2c) {
  496. return (i2c->ctrl->status);
  497. }
  498. /**
  499. \fn void I2Cx_MasterHandler (I2C_RESOURCES *i2c)
  500. \brief I2C Master state event handler.
  501. \param[in] i2c Pointer to I2C resources
  502. \return I2C event notification flags
  503. */
  504. static uint32_t I2Cx_MasterHandler (I2C_RESOURCES *i2c) {
  505. uint32_t conset = i2c->ctrl->con_aa;
  506. uint32_t event = 0;
  507. if (i2c->ctrl->stalled) {
  508. /* Master resumes with repeated START here */
  509. /* Stalled states: I2C_STAT_MA_DT_A */
  510. /* I2C_STAT_MA_DR_NA */
  511. i2c->ctrl->stalled = 0;
  512. conset |= I2C_CON_STA;
  513. goto write_con;
  514. }
  515. switch (i2c->reg->STAT & 0xF8) {
  516. case I2C_STAT_BUSERR:
  517. /* I2C Bus error */
  518. i2c->ctrl->status.bus_error = 1;
  519. i2c->ctrl->status.busy = 0;
  520. i2c->ctrl->status.mode = 0;
  521. event = ARM_I2C_EVENT_BUS_ERROR |
  522. ARM_I2C_EVENT_TRANSFER_DONE |
  523. ARM_I2C_EVENT_TRANSFER_INCOMPLETE;
  524. conset |= I2C_CON_STO;
  525. break;
  526. case I2C_STAT_MA_START:
  527. /* START transmitted */
  528. case I2C_STAT_MA_RSTART:
  529. /* Repeated START transmitted */
  530. i2c->reg->DAT = i2c->ctrl->sla_rw;
  531. break;
  532. case I2C_STAT_MA_SLAW_NA:
  533. /* SLA+W transmitted, no ACK received */
  534. case I2C_STAT_MA_SLAR_NA:
  535. /* SLA+R transmitted, no ACK received */
  536. i2c->ctrl->status.busy = 0;
  537. i2c->ctrl->status.mode = 0;
  538. event = ARM_I2C_EVENT_ADDRESS_NACK |
  539. ARM_I2C_EVENT_TRANSFER_DONE |
  540. ARM_I2C_EVENT_TRANSFER_INCOMPLETE;
  541. conset |= I2C_CON_STO;
  542. break;
  543. case I2C_STAT_MA_SLAW_A:
  544. /* SLA+W transmitted, ACK received */
  545. i2c->ctrl->cnt = 0;
  546. i2c->reg->DAT = i2c->ctrl->data[0];
  547. break;
  548. case I2C_STAT_MA_DT_A:
  549. /* Data transmitted, ACK received */
  550. i2c->ctrl->cnt++;
  551. i2c->ctrl->num--;
  552. if (!i2c->ctrl->num) {
  553. goto xfer_done;
  554. }
  555. /* Send next byte */
  556. i2c->reg->DAT = i2c->ctrl->data[i2c->ctrl->cnt];
  557. break;
  558. case I2C_STAT_MA_DT_NA:
  559. /* Data transmitted, no ACK received */
  560. i2c->ctrl->status.busy = 0;
  561. i2c->ctrl->status.mode = 0;
  562. event = ARM_I2C_EVENT_TRANSFER_DONE |
  563. ARM_I2C_EVENT_TRANSFER_INCOMPLETE;
  564. conset |= I2C_CON_STO;
  565. break;
  566. case I2C_STAT_MA_ALOST:
  567. /* Arbitration lost */
  568. i2c->ctrl->status.arbitration_lost = 1;
  569. i2c->ctrl->status.busy = 0;
  570. i2c->ctrl->status.mode = 0;
  571. event = ARM_I2C_EVENT_ARBITRATION_LOST |
  572. ARM_I2C_EVENT_TRANSFER_DONE |
  573. ARM_I2C_EVENT_TRANSFER_INCOMPLETE;
  574. break;
  575. case I2C_STAT_MA_SLAR_A:
  576. /* SLA+R transmitted, ACK received */
  577. i2c->ctrl->cnt = 0;
  578. i2c->ctrl->status.direction = 1;
  579. goto upd_conset;
  580. case I2C_STAT_MA_DR_A:
  581. /* Data received, ACK returned */
  582. i2c->ctrl->data[i2c->ctrl->cnt++] = i2c->reg->DAT;
  583. i2c->ctrl->num--;
  584. upd_conset:
  585. conset = 0;
  586. if (i2c->ctrl->num > 1) {
  587. conset = I2C_CON_AA;
  588. }
  589. break;
  590. case I2C_STAT_MA_DR_NA:
  591. /* Data received, no ACK returned */
  592. i2c->ctrl->data[i2c->ctrl->cnt++] = i2c->reg->DAT;
  593. i2c->ctrl->num--;
  594. xfer_done:
  595. i2c->ctrl->status.busy = 0;
  596. event = ARM_I2C_EVENT_TRANSFER_DONE;
  597. if (i2c->ctrl->pending) {
  598. /* Stall I2C transaction */
  599. NVIC_DisableIRQ (i2c->i2c_ev_irq);
  600. i2c->ctrl->stalled = I2C_MASTER;
  601. return (event);
  602. }
  603. /* Generate STOP */
  604. conset |= I2C_CON_STO;
  605. break;
  606. }
  607. write_con:
  608. /* Set/clear control flags */
  609. i2c->reg->CONSET = conset;
  610. i2c->reg->CONCLR = conset ^ I2C_CON_FLAGS;
  611. return (event);
  612. }
  613. /**
  614. \fn void I2Cx_SlaveHandler (I2C_RESOURCES *i2c)
  615. \brief I2C Slave state event handler.
  616. \param[in] i2c Pointer to I2C resources
  617. \return I2C event notification flags
  618. */
  619. static uint32_t I2Cx_SlaveHandler (I2C_RESOURCES *i2c) {
  620. uint32_t conset = 0;
  621. uint32_t event = 0;
  622. switch (i2c->reg->STAT & 0xF8) {
  623. case I2C_STAT_SL_ALOST_GC:
  624. /* Arbitration lost in General call */
  625. i2c->ctrl->status.arbitration_lost = 1;
  626. case I2C_STAT_SL_GCA_A:
  627. /* General address recvd, ACK returned */
  628. i2c->ctrl->status.general_call = 1;
  629. goto slaw_a;
  630. case I2C_STAT_SL_ALOST_MW:
  631. /* Arbitration lost SLA+W */
  632. i2c->ctrl->status.arbitration_lost = 1;
  633. case I2C_STAT_SL_SLAW_A:
  634. /* SLA+W received, ACK returned */
  635. slaw_a:
  636. /* Stalled Slave receiver also resumes here */
  637. if (!i2c->ctrl->snum || !(i2c->ctrl->flags & I2C_FLAG_SLAVE_RX)) {
  638. /* Receive buffer unavailable */
  639. if (i2c->ctrl->stalled) {
  640. /* Already stalled, abort transaction to prevent dead-loops */
  641. event = ARM_I2C_EVENT_TRANSFER_DONE |
  642. ARM_I2C_EVENT_TRANSFER_INCOMPLETE;
  643. conset = I2C_CON_STO | i2c->ctrl->con_aa;
  644. break;
  645. }
  646. /* Stall I2C transaction */
  647. NVIC_DisableIRQ (i2c->i2c_ev_irq);
  648. i2c->ctrl->stalled = I2C_SLAVE_RX;
  649. return (ARM_I2C_EVENT_SLAVE_RECEIVE);
  650. }
  651. i2c->ctrl->status.direction = 1;
  652. i2c->ctrl->status.busy = 1;
  653. i2c->ctrl->cnt = 0;
  654. i2c->ctrl->stalled = 0;
  655. conset = I2C_CON_AA;
  656. break;
  657. case I2C_STAT_SL_DRGC_A:
  658. /* Data recvd General call, ACK returned */
  659. case I2C_STAT_SL_DR_A:
  660. /* Data received, ACK returned */
  661. i2c->ctrl->sdata[i2c->ctrl->cnt++] = i2c->reg->DAT;
  662. i2c->ctrl->snum--;
  663. if (i2c->ctrl->snum) {
  664. conset = I2C_CON_AA;
  665. }
  666. break;
  667. case I2C_STAT_SL_ALOST_MR:
  668. /* Arbitration lost SLA+R */
  669. i2c->ctrl->status.arbitration_lost = 1;
  670. case I2C_STAT_SL_SLAR_A:
  671. /* SLA+R received, ACK returned */
  672. /* Stalled Slave transmitter also resumes here */
  673. if (!i2c->ctrl->snum || (i2c->ctrl->flags & I2C_FLAG_SLAVE_RX)) {
  674. /* Transmit buffer unavailable */
  675. if (i2c->ctrl->stalled) {
  676. /* Already stalled, abort transaction to prevent dead-loops */
  677. event = ARM_I2C_EVENT_TRANSFER_DONE |
  678. ARM_I2C_EVENT_TRANSFER_INCOMPLETE;
  679. conset = I2C_CON_STO | i2c->ctrl->con_aa;
  680. break;
  681. }
  682. NVIC_DisableIRQ (i2c->i2c_ev_irq);
  683. i2c->ctrl->stalled = I2C_SLAVE_TX;
  684. return (ARM_I2C_EVENT_SLAVE_TRANSMIT);
  685. }
  686. i2c->ctrl->status.direction = 0;
  687. i2c->ctrl->status.busy = 1;
  688. i2c->ctrl->cnt = 0;
  689. i2c->ctrl->stalled = 0;
  690. case I2C_STAT_SL_DT_A:
  691. /* Data transmitted, ACK received */
  692. i2c->reg->DAT = i2c->ctrl->sdata[i2c->ctrl->cnt++];
  693. i2c->ctrl->snum--;
  694. if (i2c->ctrl->snum) {
  695. conset = I2C_CON_AA;
  696. }
  697. break;
  698. case I2C_STAT_SL_DT_NA:
  699. /* Data transmitted, no ACK received */
  700. case I2C_STAT_SL_LDT_A:
  701. /* Last data transmitted, ACK received */
  702. case I2C_STAT_SL_DR_NA:
  703. /* Data received, no ACK returned */
  704. case I2C_STAT_SL_DRGC_NA:
  705. /* Data recvd General call, no ACK returned */
  706. case I2C_STAT_SL_STOP:
  707. /* STOP received while addressed */
  708. i2c->ctrl->status.busy = 0;
  709. /* Slave operation completed, generate events */
  710. event = ARM_I2C_EVENT_TRANSFER_DONE;
  711. if (i2c->ctrl->status.arbitration_lost) {
  712. event |= ARM_I2C_EVENT_ARBITRATION_LOST;
  713. }
  714. if (i2c->ctrl->status.general_call) {
  715. event |= ARM_I2C_EVENT_GENERAL_CALL;
  716. }
  717. if (i2c->ctrl->snum) {
  718. event |= ARM_I2C_EVENT_TRANSFER_INCOMPLETE;
  719. }
  720. conset = i2c->ctrl->con_aa;
  721. break;
  722. }
  723. /* Set/clear control flags */
  724. i2c->reg->CONSET = conset;
  725. i2c->reg->CONCLR = conset ^ I2C_CON_FLAGS;
  726. return (event);
  727. }
  728. /**
  729. \fn void I2Cx_IRQHandler (I2C_RESOURCES *i2c)
  730. \brief I2C Event Interrupt handler.
  731. \param[in] i2c Pointer to I2C resources
  732. */
  733. static void I2Cx_IRQHandler (I2C_RESOURCES *i2c) {
  734. uint32_t event;
  735. if (i2c->reg->STAT < I2C_STAT_SL_SLAW_A) {
  736. event = I2Cx_MasterHandler (i2c);
  737. }
  738. else {
  739. event = I2Cx_SlaveHandler (i2c);
  740. }
  741. /* Callback event notification */
  742. if (event && i2c->ctrl->cb_event) {
  743. i2c->ctrl->cb_event (event);
  744. }
  745. }
  746. #if (RTE_I2C0)
  747. /* I2C0 Driver wrapper functions */
  748. static int32_t I2C0_Initialize (ARM_I2C_SignalEvent_t cb_event) {
  749. return (I2Cx_Initialize (cb_event, &I2C0_Resources));
  750. }
  751. static int32_t I2C0_Uninitialize (void) {
  752. return (I2Cx_Uninitialize (&I2C0_Resources));
  753. }
  754. static int32_t I2C0_PowerControl (ARM_POWER_STATE state) {
  755. return (I2Cx_PowerControl (state, &I2C0_Resources));
  756. }
  757. static int32_t I2C0_MasterTransmit (uint32_t addr, const uint8_t *data, uint32_t num, bool xfer_pending) {
  758. return (I2Cx_MasterTransmit (addr, data, num, xfer_pending, &I2C0_Resources));
  759. }
  760. static int32_t I2C0_MasterReceive (uint32_t addr, uint8_t *data, uint32_t num, bool xfer_pending) {
  761. return (I2Cx_MasterReceive (addr, data, num, xfer_pending, &I2C0_Resources));
  762. }
  763. static int32_t I2C0_SlaveTransmit (const uint8_t *data, uint32_t num) {
  764. return (I2Cx_SlaveTransmit (data, num, &I2C0_Resources));
  765. }
  766. static int32_t I2C0_SlaveReceive (uint8_t *data, uint32_t num) {
  767. return (I2Cx_SlaveReceive (data, num, &I2C0_Resources));
  768. }
  769. static int32_t I2C0_GetDataCount (void) {
  770. return (I2Cx_GetDataCount (&I2C0_Resources));
  771. }
  772. static int32_t I2C0_Control (uint32_t control, uint32_t arg) {
  773. return (I2Cx_Control (control, arg, &I2C0_Resources));
  774. }
  775. static ARM_I2C_STATUS I2C0_GetStatus (void) {
  776. return (I2Cx_GetStatus (&I2C0_Resources));
  777. }
  778. void I2C0_IRQHandler (void) {
  779. I2Cx_IRQHandler (&I2C0_Resources);
  780. }
  781. /* I2C0 Driver Control Block */
  782. ARM_DRIVER_I2C Driver_I2C0 = {
  783. I2C_GetVersion,
  784. I2C_GetCapabilities,
  785. I2C0_Initialize,
  786. I2C0_Uninitialize,
  787. I2C0_PowerControl,
  788. I2C0_MasterTransmit,
  789. I2C0_MasterReceive,
  790. I2C0_SlaveTransmit,
  791. I2C0_SlaveReceive,
  792. I2C0_GetDataCount,
  793. I2C0_Control,
  794. I2C0_GetStatus
  795. };
  796. #endif
  797. #if (RTE_I2C1)
  798. /* I2C1 Driver wrapper functions */
  799. static int32_t I2C1_Initialize (ARM_I2C_SignalEvent_t cb_event) {
  800. return (I2Cx_Initialize (cb_event, &I2C1_Resources));
  801. }
  802. static int32_t I2C1_Uninitialize (void) {
  803. return (I2Cx_Uninitialize (&I2C1_Resources));
  804. }
  805. static int32_t I2C1_PowerControl (ARM_POWER_STATE state) {
  806. return (I2Cx_PowerControl (state, &I2C1_Resources));
  807. }
  808. static int32_t I2C1_MasterTransmit (uint32_t addr, const uint8_t *data, uint32_t num, bool xfer_pending) {
  809. return (I2Cx_MasterTransmit (addr, data, num, xfer_pending, &I2C1_Resources));
  810. }
  811. static int32_t I2C1_MasterReceive (uint32_t addr, uint8_t *data, uint32_t num, bool xfer_pending) {
  812. return (I2Cx_MasterReceive (addr, data, num, xfer_pending, &I2C1_Resources));
  813. }
  814. static int32_t I2C1_SlaveTransmit (const uint8_t *data, uint32_t num) {
  815. return (I2Cx_SlaveTransmit (data, num, &I2C1_Resources));
  816. }
  817. static int32_t I2C1_SlaveReceive (uint8_t *data, uint32_t num) {
  818. return (I2Cx_SlaveReceive (data, num, &I2C1_Resources));
  819. }
  820. static int32_t I2C1_GetDataCount (void) {
  821. return (I2Cx_GetDataCount (&I2C1_Resources));
  822. }
  823. static int32_t I2C1_Control (uint32_t control, uint32_t arg) {
  824. return (I2Cx_Control (control, arg, &I2C1_Resources));
  825. }
  826. static ARM_I2C_STATUS I2C1_GetStatus (void) {
  827. return (I2Cx_GetStatus (&I2C1_Resources));
  828. }
  829. void I2C1_IRQHandler (void) {
  830. I2Cx_IRQHandler (&I2C1_Resources);
  831. }
  832. /* I2C1 Driver Control Block */
  833. ARM_DRIVER_I2C Driver_I2C1 = {
  834. I2C_GetVersion,
  835. I2C_GetCapabilities,
  836. I2C1_Initialize,
  837. I2C1_Uninitialize,
  838. I2C1_PowerControl,
  839. I2C1_MasterTransmit,
  840. I2C1_MasterReceive,
  841. I2C1_SlaveTransmit,
  842. I2C1_SlaveReceive,
  843. I2C1_GetDataCount,
  844. I2C1_Control,
  845. I2C1_GetStatus
  846. };
  847. #endif