am_hal_i2c_bit_bang.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757
  1. //*****************************************************************************
  2. //
  3. // am_hal_i2c_bit_bang.c
  4. //! @file
  5. //!
  6. //! @brief I2C bit bang module.
  7. //!
  8. //! These functions implement the I2C bit bang utility
  9. //! It implements an I2C interface at close to 400 kHz
  10. //
  11. //*****************************************************************************
  12. //*****************************************************************************
  13. //
  14. // Copyright (c) 2017, Ambiq Micro
  15. // All rights reserved.
  16. //
  17. // Redistribution and use in source and binary forms, with or without
  18. // modification, are permitted provided that the following conditions are met:
  19. //
  20. // 1. Redistributions of source code must retain the above copyright notice,
  21. // this list of conditions and the following disclaimer.
  22. //
  23. // 2. Redistributions in binary form must reproduce the above copyright
  24. // notice, this list of conditions and the following disclaimer in the
  25. // documentation and/or other materials provided with the distribution.
  26. //
  27. // 3. Neither the name of the copyright holder nor the names of its
  28. // contributors may be used to endorse or promote products derived from this
  29. // software without specific prior written permission.
  30. //
  31. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  32. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  33. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  34. // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
  35. // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  36. // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  37. // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  38. // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  39. // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  40. // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  41. // POSSIBILITY OF SUCH DAMAGE.
  42. //
  43. // This is part of revision 1.2.9 of the AmbiqSuite Development Package.
  44. //
  45. //*****************************************************************************
  46. #include <stdint.h>
  47. #include <stdbool.h>
  48. #include "am_mcu_apollo.h"
  49. //#include "am_util.h"
  50. #include "am_hal_i2c_bit_bang.h"
  51. // Max number of clock cycles to wait for clock stretch
  52. #define I2C_BB_MAX_CLOCK_STRETCH_WAIT 100
  53. #define I2C_BB_DESIRED_FREQ_HZ 400000
  54. #define I2C_BB_CYCLES_PER_DELAY_COUNT 3
  55. #define I2C_BB_ONE_BIT_TIME_IN_CYCLES (AM_HAL_CLKGEN_FREQ_MAX_HZ/I2C_BB_DESIRED_FREQ_HZ)
  56. #define I2C_BB_ONE_BIT_TIME_IN_DELAY_COUNT (I2C_BB_ONE_BIT_TIME_IN_CYCLES/I2C_BB_CYCLES_PER_DELAY_COUNT)
  57. // Number of loops (each worth 3 cycles) needed to delay for defined time
  58. // This is imprecise, as there is a setup time as well which is not accounted
  59. // for
  60. // One Bit time = 120 Cycles (400 kHz @ 48 MHz)
  61. #define HALF_BIT_TIME (I2C_BB_ONE_BIT_TIME_IN_DELAY_COUNT/2)
  62. #define QUARTER_BIT_TIME (I2C_BB_ONE_BIT_TIME_IN_DELAY_COUNT/4)
  63. #define ASM_DELAY am_hal_flash_delay
  64. // Empirically determined adjustments to account for the fact that there is a
  65. // variable time spent in actual processing as well, and hence we need not delay
  66. // for the full time. This processing time is variable based on exact processing
  67. // needed at various times, and will also vary based on compiler type and
  68. // optimization levels
  69. #define I2C_BB_TIMER_ADJUST 6 // Can not be more than QUARTER_BIT_TIME - 1
  70. #define I2C_BB_TIMER_HI_ADJUST 15 // Can not be more than HALF_BIT_TIME - 1
  71. #define I2C_BB_TIMER_LO_ADJUST 13 // Can not be more than HALF_BIT_TIME - 1
  72. // Wait till it is time to end the SCL Hi Period
  73. #define WAIT_I2C_CLOCK_HI_PERIOD() ASM_DELAY(HALF_BIT_TIME - I2C_BB_TIMER_HI_ADJUST)
  74. // Wait till it is time to end the SCL Lo Period
  75. #define WAIT_I2C_CLOCK_LOW_PERIOD() ASM_DELAY(HALF_BIT_TIME - I2C_BB_TIMER_LO_ADJUST)
  76. // Delay for Quarter Clock
  77. #define WAIT_FOR_QUARTER_I2C_CLOCK() ASM_DELAY(QUARTER_BIT_TIME - I2C_BB_TIMER_ADJUST)
  78. #define WRITE_SCL_LO() \
  79. do { \
  80. AM_REGVAL(am_hal_i2c_bit_bang_priv.sck_reg_clr_addr) = (am_hal_i2c_bit_bang_priv.sck_reg_val); \
  81. } while(0)
  82. #define PULL_SCL_HI() \
  83. do { \
  84. AM_REGVAL(am_hal_i2c_bit_bang_priv.sck_reg_set_addr) = (am_hal_i2c_bit_bang_priv.sck_reg_val); \
  85. } while(0)
  86. #define GET_SCL() (AM_REGVAL(am_hal_i2c_bit_bang_priv.sck_reg_read_addr) & (am_hal_i2c_bit_bang_priv.sck_reg_val))
  87. #define GET_SDA() (AM_REGVAL(am_hal_i2c_bit_bang_priv.sda_reg_read_addr) & (am_hal_i2c_bit_bang_priv.sda_reg_val))
  88. #define WRITE_SDA_LO() \
  89. do { \
  90. AM_REGVAL(am_hal_i2c_bit_bang_priv.sda_reg_clr_addr) = (am_hal_i2c_bit_bang_priv.sda_reg_val); \
  91. } while(0)
  92. #define PULL_SDA_HI() \
  93. do { \
  94. AM_REGVAL(am_hal_i2c_bit_bang_priv.sda_reg_set_addr) = (am_hal_i2c_bit_bang_priv.sda_reg_val); \
  95. } while(0)
  96. //*****************************************************************************
  97. //
  98. // I2C Bit Bang Private Data Structure
  99. //
  100. //*****************************************************************************
  101. typedef struct am_util_bit_bang_priv
  102. {
  103. bool start_flag;
  104. uint32_t sck_gpio_number;
  105. uint32_t sda_gpio_number;
  106. uint32_t sck_reg_set_addr;
  107. uint32_t sck_reg_clr_addr;
  108. uint32_t sck_reg_read_addr;
  109. uint32_t sck_reg_val;
  110. uint32_t sda_reg_set_addr;
  111. uint32_t sda_reg_clr_addr;
  112. uint32_t sda_reg_read_addr;
  113. uint32_t sda_reg_val;
  114. } am_hal_i2c_bit_bang_priv_t;
  115. static am_hal_i2c_bit_bang_priv_t am_hal_i2c_bit_bang_priv;
  116. //
  117. // Wait for any stretched clock to go high
  118. // If it times out - return failure
  119. //
  120. static bool
  121. i2c_pull_and_wait_scl_hi(void)
  122. {
  123. // Maximum time to wait for clock stretching
  124. uint32_t maxLoop = 4*I2C_BB_MAX_CLOCK_STRETCH_WAIT + 1;
  125. // Pull SCL High
  126. PULL_SCL_HI();
  127. // Poll for SCL to check for clock stretching
  128. while (!GET_SCL())
  129. {
  130. if (--maxLoop == 0)
  131. {
  132. // timeout!
  133. return true;
  134. }
  135. WAIT_FOR_QUARTER_I2C_CLOCK();
  136. }
  137. return false;
  138. }
  139. //*****************************************************************************
  140. //
  141. //! @brief Initialize i2c bit bang private data structure
  142. //!
  143. //! @param sck_gpio_number is the GPIO # for the I2C SCK clock pin
  144. //! @param sda_gpio_number is the GPIO # for the I2C SDA data pin
  145. //!
  146. //! This function initializes the I2C bit bang utility's internal data struct.
  147. //!
  148. //! returns None.
  149. //
  150. //*****************************************************************************
  151. am_hal_i2c_bit_bang_enum_t
  152. am_hal_i2c_bit_bang_init(uint32_t sck_gpio_number,
  153. uint32_t sda_gpio_number)
  154. {
  155. int i;
  156. //
  157. // remember GPIO pin assignments for I2C bus signals
  158. //
  159. am_hal_i2c_bit_bang_priv.sck_gpio_number = sck_gpio_number;
  160. am_hal_i2c_bit_bang_priv.sda_gpio_number = sda_gpio_number;
  161. am_hal_i2c_bit_bang_priv.sck_reg_set_addr = AM_HAL_GPIO_WTS_REG(sck_gpio_number);
  162. am_hal_i2c_bit_bang_priv.sck_reg_clr_addr = AM_HAL_GPIO_WTC_REG(sck_gpio_number);
  163. am_hal_i2c_bit_bang_priv.sck_reg_read_addr = AM_HAL_GPIO_RD_REG(sck_gpio_number);
  164. am_hal_i2c_bit_bang_priv.sck_reg_val = AM_HAL_GPIO_WTC_M(sck_gpio_number);
  165. am_hal_i2c_bit_bang_priv.sda_reg_set_addr = AM_HAL_GPIO_WTS_REG(sda_gpio_number);
  166. am_hal_i2c_bit_bang_priv.sda_reg_clr_addr = AM_HAL_GPIO_WTC_REG(sda_gpio_number);
  167. am_hal_i2c_bit_bang_priv.sda_reg_read_addr = AM_HAL_GPIO_RD_REG(sda_gpio_number);
  168. am_hal_i2c_bit_bang_priv.sda_reg_val = AM_HAL_GPIO_WTC_M(sda_gpio_number);
  169. //
  170. // Set SCK GPIO data bit high so we aren't pulling down the clock
  171. //
  172. am_hal_gpio_out_bit_set(sck_gpio_number);
  173. //
  174. // Set up SCK GPIO configuration bi-direction, input
  175. //
  176. am_hal_gpio_pin_config(sck_gpio_number, AM_HAL_PIN_OPENDRAIN);
  177. //
  178. // Set SDA GPIO data bit high so we aren't pulling down the data line
  179. //
  180. am_hal_gpio_out_bit_set(sda_gpio_number);
  181. //
  182. // Set up SDA GPIO configuration bi-direction, input
  183. //
  184. am_hal_gpio_pin_config(sda_gpio_number, AM_HAL_PIN_OPENDRAIN);
  185. // Now make sure we have control of the clock line
  186. //
  187. // Wait for any stretched clock to go high. Return if still not high
  188. //
  189. if (i2c_pull_and_wait_scl_hi())
  190. {
  191. return AM_HAL_I2C_BIT_BANG_CLOCK_TIMEOUT;
  192. }
  193. if (!GET_SDA())
  194. {
  195. // If previous transaction did not finish - SDA may be pulled low for a Read.
  196. // If so - need to flush out the data (max 8 bits) & NACK
  197. for (i = 0; i < 9; i++)
  198. {
  199. //
  200. // Pull down on clock line
  201. //
  202. WRITE_SCL_LO();
  203. //
  204. // Delay for 1/2 bit cell time to start the clock and let peer write on SDA
  205. //
  206. WAIT_I2C_CLOCK_LOW_PERIOD();
  207. if (i2c_pull_and_wait_scl_hi())
  208. {
  209. return AM_HAL_I2C_BIT_BANG_CLOCK_TIMEOUT;
  210. }
  211. if (GET_SDA())
  212. {
  213. // Send START/STOP to clear the bus
  214. //
  215. // Delay for 1/4 bit cell time
  216. //
  217. WAIT_FOR_QUARTER_I2C_CLOCK();
  218. WRITE_SDA_LO();
  219. //
  220. // Delay for 1/4 bit cell time
  221. //
  222. WAIT_FOR_QUARTER_I2C_CLOCK();
  223. //
  224. // Pull down on clock line
  225. //
  226. WRITE_SCL_LO();
  227. //
  228. // Delay for 1/2 bit cell time to start the clock and let peer write on SDA
  229. //
  230. WAIT_I2C_CLOCK_LOW_PERIOD();
  231. //
  232. // Release the clock line
  233. //
  234. PULL_SCL_HI();
  235. //
  236. // Delay for 1/4 bit cell time
  237. //
  238. WAIT_FOR_QUARTER_I2C_CLOCK();
  239. PULL_SDA_HI();
  240. //
  241. // Delay for 1/4 bit cell time
  242. //
  243. WAIT_FOR_QUARTER_I2C_CLOCK();
  244. break;
  245. }
  246. }
  247. if (i == 9)
  248. {
  249. // It is it still stuck after 9 clocks - something is wrong. Need to bail out
  250. return AM_HAL_I2C_BIT_BANG_DATA_TIMEOUT;
  251. }
  252. }
  253. return AM_HAL_I2C_BIT_BANG_SUCCESS;
  254. }
  255. //*****************************************************************************
  256. //
  257. //! @brief Receive one data byte from an I2C device
  258. //!
  259. //! This function handles sending one byte to a slave device
  260. //! bNack defines if we should send an ACK or NACK
  261. //!
  262. //! returns the byte received
  263. //
  264. //*****************************************************************************
  265. static am_hal_i2c_bit_bang_enum_t
  266. i2c_receive_byte(uint8_t *pRxByte, bool bNack)
  267. {
  268. int i;
  269. uint8_t data_byte = 0;
  270. //
  271. // Loop through receiving 8 bits
  272. //
  273. for (i = 0; i < 8; i++)
  274. {
  275. //
  276. // Pull down on clock line
  277. //
  278. WRITE_SCL_LO();
  279. //
  280. // release the data line from from the previous ACK
  281. //
  282. PULL_SDA_HI();
  283. //
  284. // Delay for 1/2 bit cell time to start the clock and let peer write on SDA
  285. //
  286. WAIT_I2C_CLOCK_LOW_PERIOD();
  287. if (i2c_pull_and_wait_scl_hi())
  288. {
  289. return AM_HAL_I2C_BIT_BANG_CLOCK_TIMEOUT;
  290. }
  291. //
  292. // grab the data bit here
  293. //
  294. if ( GET_SDA() )
  295. {
  296. //
  297. // set the bit in the data byte to be returned
  298. //
  299. data_byte |= (0x80 >> i);
  300. }
  301. //
  302. // Delay for 1/2 bit cell time while clock is high
  303. //
  304. WAIT_I2C_CLOCK_HI_PERIOD();
  305. }
  306. *pRxByte = data_byte;
  307. //
  308. // Pull down on clock line
  309. //
  310. WRITE_SCL_LO();
  311. //
  312. // pull the data line down so we can ACK/NAK the byte we just received
  313. //
  314. if (bNack)
  315. {
  316. //
  317. // Pull up on data line with clock low to indicate NAK
  318. //
  319. PULL_SDA_HI();
  320. }
  321. else
  322. {
  323. //
  324. // Pull down on data line with clock low to indicate ACK
  325. //
  326. WRITE_SDA_LO();
  327. }
  328. //
  329. // Delay for 1/2 bit cell time before sending ACK to device
  330. //
  331. WAIT_I2C_CLOCK_LOW_PERIOD();
  332. if (i2c_pull_and_wait_scl_hi())
  333. {
  334. return AM_HAL_I2C_BIT_BANG_CLOCK_TIMEOUT;
  335. }
  336. //
  337. // Delay for 1/2 bit cell time while clock is high to le peer sample the ACK/NAK
  338. //
  339. WAIT_I2C_CLOCK_HI_PERIOD();
  340. //
  341. // Give the received data byte back to them
  342. //
  343. return AM_HAL_I2C_BIT_BANG_SUCCESS;
  344. }
  345. //*****************************************************************************
  346. //
  347. //! @brief Send one data bytes to an I2C device
  348. //!
  349. //! @param one_byte the byte to send, could be address could be data
  350. //!
  351. //! This function handles sending one byte to a slave device
  352. //! Starts with 0 clock and runs till full cycle
  353. //!
  354. //! returns I2C BB ENUM
  355. //! {
  356. //! AM_HAL_I2C_BIT_BANG_SUCCESS,
  357. //! AM_HAL_I2C_BIT_BANG_ADDRESS_NAKED
  358. //! }
  359. //
  360. //*****************************************************************************
  361. static am_hal_i2c_bit_bang_enum_t
  362. i2c_send_byte(uint8_t one_byte)
  363. {
  364. int i;
  365. bool data_naked = false;
  366. //
  367. // Loop through sending 8 bits
  368. //
  369. for (i = 0; i < 8; i++)
  370. {
  371. //
  372. // Pull down on clock line
  373. //
  374. WRITE_SCL_LO();
  375. //
  376. // output the next data bit
  377. //
  378. if ( one_byte & (0x80 >> i) )
  379. {
  380. PULL_SDA_HI();
  381. }
  382. else
  383. {
  384. WRITE_SDA_LO();
  385. }
  386. //
  387. // Delay for 1/2 bit cell time to start the clock
  388. //
  389. WAIT_I2C_CLOCK_LOW_PERIOD();
  390. if (i2c_pull_and_wait_scl_hi())
  391. {
  392. return AM_HAL_I2C_BIT_BANG_CLOCK_TIMEOUT;
  393. }
  394. //
  395. // Delay for 1/2 bit cell time while clock is high
  396. //
  397. WAIT_I2C_CLOCK_HI_PERIOD();
  398. }
  399. //
  400. // Pull down on clock line
  401. //
  402. WRITE_SCL_LO();
  403. //
  404. // Delay for 1/2 bit cell time to start the clock
  405. //
  406. WAIT_I2C_CLOCK_LOW_PERIOD();
  407. if (i2c_pull_and_wait_scl_hi())
  408. {
  409. return AM_HAL_I2C_BIT_BANG_CLOCK_TIMEOUT;
  410. }
  411. //
  412. // Grab the state of the ACK bit and return it
  413. //
  414. data_naked = GET_SDA();
  415. //
  416. // Delay for 1/2 bit cell time to complete the high period
  417. //
  418. WAIT_I2C_CLOCK_HI_PERIOD();
  419. if ( data_naked )
  420. {
  421. return AM_HAL_I2C_BIT_BANG_DATA_NAKED;
  422. }
  423. else
  424. {
  425. return AM_HAL_I2C_BIT_BANG_SUCCESS;
  426. }
  427. }
  428. //*****************************************************************************
  429. //
  430. //! @brief Receive a string of data bytes from an I2C device
  431. //!
  432. //! @param address (only 8 bit I2C addresses are supported)
  433. //! LSB is I2C R/W
  434. //! @param number_of_bytes to transfer (# payload bytes)
  435. //! @param pData pointer to data buffer to receive payload
  436. //!
  437. //! This function handles receiving a payload from a slave device
  438. //!
  439. //! returns ENUM{AM_HAL_I2C_BIT_BANG_SUCCESS,AM_HAL_I2C_BIT_BANG_ADDRESS_NAKED}
  440. //
  441. //*****************************************************************************
  442. am_hal_i2c_bit_bang_enum_t
  443. am_hal_i2c_bit_bang_receive(uint8_t address, uint32_t number_of_bytes,
  444. uint8_t *pData, uint8_t ui8Offset,
  445. bool bUseOffset, bool bNoStop)
  446. {
  447. uint32_t ui32I;
  448. am_hal_i2c_bit_bang_enum_t status = AM_HAL_I2C_BIT_BANG_SUCCESS;
  449. if (i2c_pull_and_wait_scl_hi())
  450. {
  451. return AM_HAL_I2C_BIT_BANG_CLOCK_TIMEOUT;
  452. }
  453. //
  454. // Pull down on data line with clock high --> START CONDITION
  455. //
  456. WRITE_SDA_LO();
  457. //
  458. // Delay for 1/2 bit cell time to start the clock
  459. //
  460. WAIT_I2C_CLOCK_HI_PERIOD();
  461. //
  462. // send the address byte and wait for the ACK/NAK
  463. //
  464. status = i2c_send_byte(address);
  465. if ( status != AM_HAL_I2C_BIT_BANG_SUCCESS )
  466. {
  467. if ( status == AM_HAL_I2C_BIT_BANG_DATA_NAKED)
  468. {
  469. return AM_HAL_I2C_BIT_BANG_ADDRESS_NAKED;
  470. }
  471. return status;
  472. }
  473. if ( bUseOffset )
  474. {
  475. status = i2c_send_byte(ui8Offset);
  476. if ( status != AM_HAL_I2C_BIT_BANG_SUCCESS )
  477. {
  478. return status;
  479. }
  480. }
  481. //
  482. // receive the requested number of data bytes
  483. //
  484. for (ui32I = 0; ui32I < number_of_bytes - 1; ui32I++)
  485. {
  486. //
  487. // receive the data bytes and send ACK for each one
  488. //
  489. status = i2c_receive_byte(pData, false);
  490. if (status != AM_HAL_I2C_BIT_BANG_SUCCESS)
  491. {
  492. return status;
  493. }
  494. pData++;
  495. }
  496. // Send NAK for the last byte
  497. status = i2c_receive_byte(pData, true);
  498. if (status != AM_HAL_I2C_BIT_BANG_SUCCESS)
  499. {
  500. return status;
  501. }
  502. //********************
  503. // Send stop condition
  504. //********************
  505. //
  506. // Pull down on clock line
  507. //
  508. WRITE_SCL_LO();
  509. //
  510. // Delay for 1/4 bit cell time
  511. //
  512. WAIT_FOR_QUARTER_I2C_CLOCK();
  513. if (!bNoStop)
  514. {
  515. //
  516. // Pull down on data line with clock low
  517. //
  518. WRITE_SDA_LO();
  519. }
  520. else
  521. {
  522. //
  523. // Release data line with clock low itself, as we are not sending STOP
  524. //
  525. PULL_SDA_HI();
  526. }
  527. //
  528. //
  529. // Delay for 1/4 bit cell time
  530. //
  531. WAIT_FOR_QUARTER_I2C_CLOCK();
  532. if (i2c_pull_and_wait_scl_hi())
  533. {
  534. return AM_HAL_I2C_BIT_BANG_CLOCK_TIMEOUT;
  535. }
  536. //
  537. // Delay for 1/2 bit cell time while clock is high
  538. //
  539. WAIT_I2C_CLOCK_HI_PERIOD();
  540. if (!bNoStop)
  541. {
  542. //
  543. // release data line with clock high --> STOP CONDITION
  544. //
  545. PULL_SDA_HI();
  546. }
  547. //
  548. // message successfully received (how could we fail???)
  549. //
  550. return AM_HAL_I2C_BIT_BANG_SUCCESS;
  551. }
  552. //*****************************************************************************
  553. //
  554. //! @brief Send a string of data bytes to an I2C device
  555. //!
  556. //! @param address (only 8 bit I2C addresses are supported)
  557. //! LSB is I2C R/W
  558. //! @param number_of_bytes to transfer (# payload bytes)
  559. //! @param pData pointer to data buffer containing payload
  560. //!
  561. //! This function handles sending a payload to a slave device
  562. //!
  563. //! returns ENUM {AM_HAL_I2C_BIT_BANG_SUCCESS, AM_HAL_I2C_BIT_BANG_DATA_NAKED,
  564. //! AM_HAL_I2C_BIT_BANG_ADDRESS_NAKED}
  565. //
  566. //*****************************************************************************
  567. am_hal_i2c_bit_bang_enum_t
  568. am_hal_i2c_bit_bang_send(uint8_t address, uint32_t number_of_bytes,
  569. uint8_t *pData, uint8_t ui8Offset,
  570. bool bUseOffset, bool bNoStop)
  571. {
  572. uint32_t ui32I;
  573. am_hal_i2c_bit_bang_enum_t status;
  574. bool data_naked = false;
  575. if (i2c_pull_and_wait_scl_hi())
  576. {
  577. return AM_HAL_I2C_BIT_BANG_CLOCK_TIMEOUT;
  578. }
  579. //
  580. // Pull down on data line with clock high --> START CONDITION
  581. //
  582. WRITE_SDA_LO();
  583. //
  584. // Delay for 1/2 bit cell time to start the clock
  585. //
  586. WAIT_I2C_CLOCK_HI_PERIOD();
  587. //
  588. // send the address byte and wait for the ACK/NAK
  589. //
  590. status = i2c_send_byte(address);
  591. if ( status != AM_HAL_I2C_BIT_BANG_SUCCESS )
  592. {
  593. if ( status == AM_HAL_I2C_BIT_BANG_DATA_NAKED)
  594. {
  595. return AM_HAL_I2C_BIT_BANG_ADDRESS_NAKED;
  596. }
  597. return status;
  598. }
  599. if ( bUseOffset )
  600. {
  601. status = i2c_send_byte(ui8Offset);
  602. if ( status != AM_HAL_I2C_BIT_BANG_SUCCESS )
  603. {
  604. return status;
  605. }
  606. }
  607. //
  608. // send the requested number of data bytes
  609. //
  610. for (ui32I = 0; ui32I < number_of_bytes; ui32I++)
  611. {
  612. //
  613. // send out the data bytes while watching for premature NAK
  614. //
  615. status = i2c_send_byte(*pData++);
  616. if (status != AM_HAL_I2C_BIT_BANG_SUCCESS)
  617. {
  618. if (status == AM_HAL_I2C_BIT_BANG_DATA_NAKED)
  619. {
  620. if (ui32I != (number_of_bytes-1))
  621. {
  622. data_naked = true;
  623. // TODO - should we be sending the STOP bit in this case regardless of bNoStop?
  624. break;
  625. }
  626. else
  627. {
  628. status = AM_HAL_I2C_BIT_BANG_SUCCESS;
  629. }
  630. }
  631. else
  632. {
  633. return status;
  634. }
  635. }
  636. }
  637. //********************
  638. // Send stop condition
  639. //********************
  640. //
  641. // Pull down on clock line
  642. //
  643. WRITE_SCL_LO();
  644. //
  645. // Delay for 1/4 bit cell time
  646. //
  647. WAIT_FOR_QUARTER_I2C_CLOCK();
  648. if (!bNoStop)
  649. {
  650. //
  651. // Pull down on data line with clock low
  652. //
  653. WRITE_SDA_LO();
  654. }
  655. else
  656. {
  657. //
  658. // Release data line with clock low itself, as we are not sending STOP
  659. //
  660. PULL_SDA_HI();
  661. }
  662. //
  663. // Delay for 1/4 bit cell time
  664. //
  665. WAIT_FOR_QUARTER_I2C_CLOCK();
  666. if (i2c_pull_and_wait_scl_hi())
  667. {
  668. return AM_HAL_I2C_BIT_BANG_CLOCK_TIMEOUT;
  669. }
  670. if (!bNoStop)
  671. {
  672. //
  673. // release data line with clock high --> STOP CONDITION
  674. //
  675. PULL_SDA_HI();
  676. }
  677. //
  678. // Delay for 1/2 bit cell time while clock is high
  679. //
  680. WAIT_I2C_CLOCK_HI_PERIOD();
  681. if ( data_naked )
  682. {
  683. return AM_HAL_I2C_BIT_BANG_DATA_NAKED; // if it happens early
  684. }
  685. //
  686. // message successfully sent
  687. //
  688. return AM_HAL_I2C_BIT_BANG_SUCCESS;
  689. }