i2cbus_gpio.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. /*
  2. * Copyright (C) 2013 Uwe Bonnes(bon@elelktron.ikp.physik.tu-darmstadt.de
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. *
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. Neither the name of the copyright holders nor the names of
  16. * contributors may be used to endorse or promote products derived
  17. * from this software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  22. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  23. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  24. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  25. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  26. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  27. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  28. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  29. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  30. * SUCH DAMAGE.
  31. *
  32. * For additional information see http://www.ethernut.de/
  33. */
  34. /*!
  35. * \file dev/i2cbus_gpio.c
  36. * \brief I2C bus for GPIO code include file.
  37. *
  38. * This driver is in an early stage and has been tested on STM32 only.
  39. *
  40. * It is intended that this driver replaces the current GPIO TWI driver,
  41. * which doesn't allow to have different types of busses in a single
  42. * application, for example TWI hardware and bit banging interfaces.
  43. * This new I2C driver layout allows to attach any I2C slave driver to
  44. * any I2C bus driver by calling NutRegisterI2cSlave().
  45. *
  46. * \verbatim
  47. * $Id$
  48. * \endverbatim
  49. */
  50. /*!
  51. * \brief I2C bus driver for GPIO hardware.
  52. *
  53. * This is an polling driver, which supports master mode only.
  54. */
  55. /*!
  56. * \addtogroup xgI2cBusGPIO
  57. */
  58. /*@{*/
  59. /*
  60. * Falling edge on the data line while the clock line is high indicates
  61. * a start condition.
  62. *
  63. * Entry: SCL any, SDA any
  64. * Exit: SCL low, SDA low
  65. */
  66. static void TwStart(GPIO_TWICB* icb)
  67. {
  68. I2C_SDA_HI();
  69. NutMicroDelay (icb->delay_unit);
  70. I2C_SCL_HI();
  71. NutMicroDelay (icb->delay_unit);
  72. I2C_SDA_LO();
  73. NutMicroDelay (icb->delay_unit);
  74. I2C_SCL_LO();
  75. NutMicroDelay (icb->delay_unit);
  76. }
  77. /*
  78. * Rising edge on the data line while the clock line is high indicates
  79. * a stop condition.
  80. *
  81. * Entry: SCL low, SDA any
  82. * Exit: SCL high, SDA high
  83. */
  84. static void TwStop(GPIO_TWICB* icb)
  85. {
  86. I2C_SDA_LO();
  87. NutMicroDelay (icb->delay_unit);
  88. I2C_SCL_HI();
  89. NutMicroDelay (2 * icb->delay_unit);
  90. I2C_SDA_HI();
  91. NutMicroDelay (8 * icb->delay_unit);
  92. }
  93. /*
  94. * Toggles out a single byte in master mode.
  95. *
  96. * Entry: SCL low, SDA any
  97. * Exit: SCL low, SDA high
  98. *
  99. * Change SDA only when SCL is low!
  100. * Sample SDA short before setting SCL low!
  101. */
  102. static int TwPut(GPIO_TWICB* icb, uint8_t octet)
  103. {
  104. int i;
  105. for (i = 0x80; i; i >>= 1) {
  106. /* Set the data bit. */
  107. if (octet & i) {
  108. I2C_SDA_HI();
  109. } else {
  110. I2C_SDA_LO();
  111. }
  112. /* Wait for data to stabilize. */
  113. NutMicroDelay (2 * icb->delay_unit);
  114. /* Toggle the clock. */
  115. I2C_SCL_HI();
  116. NutMicroDelay (2 * icb->delay_unit);
  117. while(I2C_SCL_GET() == 0)
  118. {
  119. /* Clock stretching*/
  120. NutMicroDelay (2 * icb->delay_unit);
  121. }
  122. I2C_SCL_LO();
  123. }
  124. /* Release data line to receive the ACK bit. */
  125. I2C_SDA_HI();
  126. NutMicroDelay (2 * icb->delay_unit);
  127. I2C_SCL_HI();
  128. NutMicroDelay (2 * icb->delay_unit);
  129. if (I2C_SDA_GET()) {
  130. i = -1;
  131. } else {
  132. i = 0;
  133. }
  134. I2C_SCL_LO();
  135. NutMicroDelay (2 * icb->delay_unit);
  136. return i;
  137. }
  138. /*
  139. * Toggles in a single byte in master mode.
  140. *
  141. * Entry: SCL low, SDA any
  142. * Exit: SCL low, SDA low with ack set, high else
  143. *
  144. * Change SDA only when SCL is low!
  145. * Sample SDA short before setting SCL low!
  146. */
  147. static uint8_t TwGet(GPIO_TWICB* icb, uint8_t ack)
  148. {
  149. uint8_t rc = 0;
  150. int i;
  151. /* SDA is input. */
  152. I2C_SDA_HI();
  153. NutMicroDelay (1 * icb->delay_unit);
  154. for (i = 0x80; i; i >>= 1) {
  155. NutMicroDelay (2 * icb->delay_unit);
  156. I2C_SCL_HI();
  157. NutMicroDelay (2 * icb->delay_unit);
  158. while(I2C_SCL_GET() == 0)
  159. {
  160. /* Clock stretching*/
  161. NutMicroDelay (2 * icb->delay_unit);
  162. }
  163. if (I2C_SDA_GET()) {
  164. rc |= i;
  165. }
  166. I2C_SCL_LO();
  167. }
  168. if (ack)
  169. {
  170. /* Master sets acknowledge */
  171. I2C_SDA_LO();
  172. }
  173. NutMicroDelay (2 * icb->delay_unit);
  174. I2C_SCL_HI();
  175. NutMicroDelay (2 * icb->delay_unit);
  176. I2C_SCL_LO();
  177. NutMicroDelay (2 * icb->delay_unit);
  178. return rc;
  179. }
  180. #if 0
  181. /*
  182. * Toggles out an acknowledge bit in master mode.
  183. *
  184. * Entry: SCL low, SDA any
  185. * Exit: SCL low, SDA high
  186. */
  187. static void TwAck(GPIO_TWICB* icb)
  188. {
  189. I2C_SDA_LO();
  190. NutMicroDelay (icb->delay_unit);
  191. I2C_SCL_HI();
  192. NutMicroDelay (2 * icb->delay_unit);
  193. I2C_SCL_LO();
  194. NutMicroDelay (1 * icb->delay_unit);
  195. I2C_SDA_HI();
  196. }
  197. #endif
  198. /*!
  199. * \brief I2C bus transfer (GPIO TWI implementation).
  200. *
  201. * This function is called by the platform independent code via the
  202. * NUTI2C_BUS::bus_tran function pointer.
  203. */
  204. static int TwiBusTran(NUTI2C_SLAVE *slave, NUTI2C_MSG *msg)
  205. {
  206. NUTI2C_BUS *bus;
  207. GPIO_TWICB *icb;
  208. int i, rc = 0;
  209. bus = slave->slave_bus;
  210. icb = (GPIO_TWICB *) bus->bus_icb;
  211. msg->msg_widx = 0;
  212. msg->msg_ridx = 0;
  213. if (msg->msg_wlen)
  214. {
  215. /*
  216. * Process I2C write operation.
  217. */
  218. TwStart(icb);
  219. rc = TwPut(icb, (slave->slave_address << 1));
  220. if (rc == 0)
  221. {
  222. for (i = 0; i < msg->msg_wlen; i++)
  223. {
  224. rc = TwPut(icb, msg->msg_wdat[i]);
  225. if (rc)
  226. break;
  227. msg->msg_widx++;
  228. }
  229. }
  230. }
  231. if ((rc == 0) && msg->msg_rsiz)
  232. {
  233. TwStart(icb);
  234. rc = TwPut(icb, (slave->slave_address << 1)|1);
  235. if (rc == 0)
  236. {
  237. for (i = 0; i < msg->msg_rsiz; i++)
  238. {
  239. msg->msg_rdat[i] = TwGet(icb, i < (msg->msg_rsiz-1));
  240. msg->msg_ridx++;
  241. }
  242. }
  243. }
  244. TwStop(icb);
  245. if (rc)
  246. msg->msg_ridx = rc;
  247. return msg->msg_ridx;
  248. }
  249. /*!
  250. * \brief Configure the I2C bus controller (GPIO TWI implementation).
  251. *
  252. * This function is called by the platform independent code via the
  253. * NUTI2C_BUS::bus_conf function pointer. Most implementations will
  254. * also call this function during initialization to set the
  255. * default configuration.
  256. *
  257. * Right now only the bus clock rate is configurable.
  258. */
  259. static int TwiBusConf(NUTI2C_BUS *bus)
  260. {
  261. GPIO_TWICB *icb;
  262. long rate;
  263. /* Check parameters. */
  264. NUTASSERT(bus != NULL);
  265. NUTASSERT(bus->bus_icb != NULL);
  266. icb = (GPIO_TWICB *) bus->bus_icb;
  267. /* Get requested rate or use the default. */
  268. rate = bus->bus_rate;
  269. if (rate == 0) {
  270. rate = 100000L;
  271. }
  272. if (rate > 400000) {
  273. /* Speed out of range */
  274. return -1;
  275. }
  276. icb->delay_unit = 250000/rate;
  277. if (icb->delay_unit == 0)
  278. icb->delay_unit = 1;
  279. return 0;
  280. }
  281. /*!
  282. * \brief Initialize the I2C bus controller (GPIO implementation).
  283. *
  284. * This function is called by the platform independent code via the
  285. * NUTI2C_BUS::bus_init function pointer when the first slave is
  286. * attached to this bus. Note, that NUTI2C_BUS::bus_rate must be zero
  287. * initially. Otherwise no call to this function will take place.
  288. *
  289. * This function must do all required initializations so that the
  290. * driver will be ready to process transfers via NUTI2C_BUS::bus_tran.
  291. *
  292. * This function must return 0 on success or -1 otherwise.
  293. */
  294. static int TwiBusInit(NUTI2C_BUS *bus)
  295. {
  296. #if !defined(GPIO0_SDA_PORT) || !defined(GPIO0_SDA_PIN) || \
  297. !defined(GPIO0_SCL_PORT) || !defined(GPIO0_SCL_PIN)
  298. return -1;
  299. #endif
  300. /* Try to configure the bus and register the IRQ Handler */
  301. if (TwiBusConf(bus)) {
  302. return -1;
  303. }
  304. I2C_SDA_INIT();
  305. I2C_SCL_INIT();
  306. return 0;
  307. }
  308. /*!
  309. * \brief Probe the I2C bus for a specified slave address (GPIO implementation).
  310. *
  311. * This function is called by the platform independent code via the
  312. * NUTI2C_BUS::bus_probe function pointer. This may happen even if no
  313. * slave device had been attached to the bus and thus without any
  314. * previous call to NUTI2C_BUS::bus_init. However, in that case
  315. * NUTI2C_BUS::bus_configure will have been called.
  316. */
  317. static int TwiBusProbe(NUTI2C_BUS *bus, int sla)
  318. {
  319. int rc = -1;
  320. GPIO_TWICB *icb;
  321. icb = (GPIO_TWICB *) bus->bus_icb;
  322. if ((bus->bus_flags & I2C_BF_INITIALIZED) == 0) {
  323. int res;
  324. res = TwiBusInit(bus);
  325. if (res)
  326. return res;
  327. }
  328. TwStart(icb);
  329. rc = TwPut(icb, (sla<<1));
  330. TwStop(icb);
  331. return rc;
  332. }