i2cbus_at91.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. /*
  2. * Copyright (C) 2012 by egnite GmbH
  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 arch/arm/dev/atmel/i2cbus_at91.c
  36. * \brief I2C bus driver for AT91 family.
  37. *
  38. * This driver is in an early stage and has been tested on Ethernut 5 only.
  39. *
  40. * It is intended that this driver replaces the current AT91 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. #include <dev/irqreg.h>
  51. #include <sys/nutdebug.h>
  52. #include <sys/timer.h>
  53. #include <sys/event.h>
  54. #include <stdlib.h>
  55. #include <dev/i2cbus_at91.h>
  56. /*!
  57. * \addtogroup xgI2cBusAt91
  58. */
  59. /*@{*/
  60. /*!
  61. * \brief Local data of the AT91 TWI bus driver.
  62. */
  63. typedef struct _AT91_TWICB {
  64. /*! \brief Register base. */
  65. uint32_t icb_base;
  66. /*! \brief System interrupt handler. */
  67. IRQ_HANDLER *icb_sig;
  68. /*! \brief I2C message. */
  69. NUTI2C_MSG *icb_msg;
  70. /*! \brief Thread waiting for completion. */
  71. HANDLE icb_queue;
  72. } AT91_TWICB;
  73. #if 0
  74. static void DumpTwiRegs(AT91_TWICB *icb)
  75. {
  76. printf("\nMMR %08lx\n", mem_rd32(icb->icb_base + TWI_MMR_OFF));
  77. printf("SMR %08lx\n", mem_rd32(icb->icb_base + TWI_SMR_OFF));
  78. printf("IADR %08lx\n", mem_rd32(icb->icb_base + TWI_IADRR_OFF));
  79. printf("CWGR %08lx\n", mem_rd32(icb->icb_base + TWI_CWGR_OFF));
  80. printf("SR %08lx\n", mem_rd32(icb->icb_base + TWI_SR_OFF));
  81. printf("IMR %08lx\n", mem_rd32(icb->icb_base + TWI_IMR_OFF));
  82. }
  83. #endif
  84. /*
  85. * AT91 TWI interrupt function.
  86. */
  87. static void TwiBusIrqHandler(void *arg)
  88. {
  89. AT91_TWICB *icb = (AT91_TWICB *) arg;
  90. NUTI2C_MSG *msg = icb->icb_msg;
  91. uint32_t sr = mem_rd32(icb->icb_base + TWI_SR_OFF);
  92. unsigned int ba = icb->icb_base;
  93. /* Process enabled interrupts only. */
  94. sr &= mem_rd32(ba + TWI_IMR_OFF);
  95. /*
  96. * Process transmit interrupt.
  97. */
  98. if (sr & TWI_TXRDY) {
  99. /* Check if more bytes to transmit. */
  100. if (msg->msg_widx < msg->msg_wlen) {
  101. /* Transmit the next byte. */
  102. mem_wr32(ba + TWI_THR_OFF, msg->msg_wdat[msg->msg_widx]);
  103. msg->msg_widx++;
  104. } else {
  105. /* All bytes sent, stop transfer. */
  106. mem_wr32(ba + TWI_IDR_OFF, TWI_TXRDY);
  107. mem_wr32(ba + TWI_CR_OFF, TWI_STOP);
  108. }
  109. }
  110. /*
  111. * Process receive interrupt.
  112. */
  113. else if (sr & TWI_RXRDY) {
  114. /* Check if more bytes to receive. */
  115. if (msg->msg_ridx < msg->msg_rsiz) {
  116. /* Store byte in receive buffer. */
  117. msg->msg_rdat[msg->msg_ridx++] = mem_rd32(ba + TWI_RHR_OFF);
  118. /* Check if the next byte will be last. */
  119. if (msg->msg_ridx + 1 == msg->msg_rsiz) {
  120. /* Set STOP condition. */
  121. mem_wr32(ba + TWI_CR_OFF, TWI_STOP);
  122. }
  123. }
  124. }
  125. /*
  126. * Process completion interrupt.
  127. */
  128. if (sr & TWI_TXCOMP) {
  129. /* Transfer complete, disable interrupts and wake up thread. */
  130. mem_wr32(ba + TWI_IDR_OFF, 0xFFFFFFFF);
  131. NutEventPostFromIrq(&icb->icb_queue);
  132. }
  133. }
  134. /*!
  135. * \brief I2C bus transfer (AT91 TWI implementation).
  136. *
  137. * This function is called by the platform independent code via the
  138. * NUTI2C_BUS::bus_tran function pointer.
  139. */
  140. static int TwiBusTran(NUTI2C_SLAVE *slave, NUTI2C_MSG *msg)
  141. {
  142. NUTI2C_BUS *bus;
  143. AT91_TWICB *icb;
  144. uint32_t ba;
  145. bus = slave->slave_bus;
  146. icb = (AT91_TWICB *) bus->bus_icb;
  147. icb->icb_msg = msg;
  148. ba = icb->icb_base;
  149. /*
  150. * Process I2C read operation.
  151. */
  152. if (msg->msg_rsiz) {
  153. uint32_t iadr = 0;
  154. int i;
  155. /* Check internal address size limit. */
  156. if (msg->msg_wlen > 3) {
  157. return -1;
  158. }
  159. /* Set internal address register. */
  160. for (i = 0; i < msg->msg_wlen; i++) {
  161. iadr <<= 8;
  162. iadr |= msg->msg_wdat[i];
  163. }
  164. mem_wr32(ba + TWI_IADRR_OFF, iadr);
  165. /* Set master mode register. */
  166. mem_wr32(ba + TWI_MMR_OFF,
  167. ((uint32_t) slave->slave_address << TWI_DADR_LSB) |
  168. TWI_MREAD |
  169. ((uint32_t) msg->msg_wlen << TWI_IADRSZ_LSB));
  170. /* Start transfer. */
  171. if (msg->msg_rsiz == 1) {
  172. /* Set STOP condition if this is the last byte. */
  173. mem_wr32(ba + TWI_CR_OFF, TWI_START | TWI_STOP);
  174. } else {
  175. mem_wr32(ba + TWI_CR_OFF, TWI_START);
  176. }
  177. mem_wr32(ba + TWI_IER_OFF, TWI_ARBLST | TWI_NACK | TWI_RXRDY | TWI_TXCOMP);
  178. }
  179. /*
  180. * Process I2C write operation.
  181. */
  182. else if (msg->msg_wlen) {
  183. mem_wr32(ba + TWI_MMR_OFF, (uint32_t) slave->slave_address << TWI_DADR_LSB);
  184. mem_wr32(ba + TWI_THR_OFF, msg->msg_wdat[0]);
  185. msg->msg_widx++;
  186. mem_wr32(ba + TWI_IER_OFF, TWI_ARBLST | TWI_NACK | TWI_TXRDY | TWI_TXCOMP);
  187. }
  188. /* Wait for transfer complete. */
  189. if (NutEventWait(&icb->icb_queue, slave->slave_timeout)) {
  190. mem_wr32(ba + TWI_IDR_OFF, 0xFFFFFFFF);
  191. return -1;
  192. }
  193. return msg->msg_ridx;
  194. }
  195. /*!
  196. * \brief Configure the I2C bus controller (AT91 TWI implementation).
  197. *
  198. * This function is called by the platform independent code via the
  199. * NUTI2C_BUS::bus_conf function pointer. Most implementations will
  200. * also call this function during initialization to set the
  201. * default configuration.
  202. *
  203. * Right now only the bus clock rate is configurable.
  204. */
  205. static int TwiBusConf(NUTI2C_BUS *bus)
  206. {
  207. AT91_TWICB *icb;
  208. uint32_t mck;
  209. uint32_t cdiv;
  210. uint32_t ckdiv;
  211. long rate;
  212. /* Check parameters. */
  213. NUTASSERT(bus != NULL);
  214. NUTASSERT(bus->bus_icb != NULL);
  215. icb = (AT91_TWICB *) bus->bus_icb;
  216. /* Get requested rate or use the default. */
  217. rate = bus->bus_rate;
  218. if (rate == 0) {
  219. rate = 100000L;
  220. }
  221. /* rate = MCK / (((CLDIV + CHDIV) * 2^CKDIV) + 4) */
  222. mck = NutClockGet(NUT_HWCLK_PERIPHERAL);
  223. cdiv = (mck >> 1) / rate - 4;
  224. for (ckdiv = 0; cdiv > 255; ckdiv++) {
  225. cdiv >>= 1;
  226. }
  227. if (ckdiv > 7) {
  228. /* Requested rate is not available. */
  229. return -1;
  230. }
  231. /* Set the actual rate. */
  232. bus->bus_rate = mck / (2 * cdiv * (1 << ckdiv) + 4);
  233. /* Set calculated clock divider. */
  234. mem_wr32(icb->icb_base + TWI_CWGR_OFF,
  235. (ckdiv << TWI_CKDIV_LSB) | (cdiv << TWI_CHDIV_LSB) | (cdiv << TWI_CLDIV_LSB));
  236. /* Enable master mode. */
  237. mem_wr32(icb->icb_base + TWI_CR_OFF, TWI_MSEN | TWI_SVDIS);
  238. return 0;
  239. }
  240. /*!
  241. * \brief Initialize the I2C bus controller (AT91 implementation).
  242. *
  243. * This function is called by the platform independent code via the
  244. * NUTI2C_BUS::bus_init function pointer when the first slave is
  245. * attached to this bus. Note, that NUTI2C_BUS::bus_rate must be zero
  246. * initially. Otherwise no call to this function will take place.
  247. *
  248. * This function must do all required initializations so that the
  249. * driver will be ready to process transfers via NUTI2C_BUS::bus_tran.
  250. *
  251. * On many platforms it is required to configure the pins in the
  252. * board initialization function.
  253. *
  254. * This function must return 0 on success or -1 otherwise.
  255. */
  256. static int TwiBusInit(NUTI2C_BUS *bus)
  257. {
  258. AT91_TWICB *icb;
  259. icb = (AT91_TWICB *) bus->bus_icb;
  260. /* Disable all interrupts. */
  261. mem_wr32(icb->icb_base + TWI_IDR_OFF, 0xFFFFFFFF);
  262. /* Reset bus. */
  263. mem_wr32(icb->icb_base + TWI_CR_OFF, TWI_SWRST);
  264. /* Try to configure the bus and register the IRQ Handler */
  265. if (TwiBusConf(bus) || NutRegisterIrqHandler(icb->icb_sig, TwiBusIrqHandler, icb)) {
  266. return -1;
  267. }
  268. /* Enable interrupts. */
  269. NutIrqEnable(icb->icb_sig);
  270. return 0;
  271. }
  272. /*!
  273. * \brief Probe the I2C bus for a specified slave address (AT91 implementation).
  274. *
  275. * This function is called by the platform independent code via the
  276. * NUTI2C_BUS::bus_probe function pointer. This may happen even if no
  277. * slave device had been attached to the bus and thus without any
  278. * previous call to NUTI2C_BUS::bus_init. However, in that case
  279. * NUTI2C_BUS::bus_configure will have been called.
  280. */
  281. static int TwiBusProbe(NUTI2C_BUS *bus, int sla)
  282. {
  283. int rc = -1;
  284. uint_fast8_t wt = 100;
  285. AT91_TWICB *icb;
  286. uint32_t sr;
  287. icb = (AT91_TWICB *) bus->bus_icb;
  288. /* Try to read one byte. */
  289. mem_wr32(icb->icb_base + TWI_MMR_OFF, (uint32_t) sla << TWI_DADR_LSB | TWI_MREAD);
  290. mem_wr32(icb->icb_base + TWI_CR_OFF, TWI_START | TWI_STOP);
  291. wt = bus->bus_timeout;
  292. do {
  293. sr = mem_rd32(icb->icb_base + TWI_SR_OFF) & (TWI_NACK | TWI_ARBLST | TWI_TXCOMP);
  294. if (sr) {
  295. if (sr == TWI_TXCOMP) {
  296. mem_rd32(icb->icb_base + TWI_RHR_OFF);
  297. rc = 0;
  298. }
  299. break;
  300. }
  301. NutSleep(1);
  302. } while (wt--);
  303. return rc;
  304. }
  305. static AT91_TWICB twi0cb = {
  306. TWI_BASE, /* icb_base */
  307. &sig_TWI, /* icb_sig */
  308. NULL, /* icb_msg */
  309. NULL /* icb_queue */
  310. };
  311. /*!
  312. * \brief I2C bus driver for AT91 TWI hardware.
  313. *
  314. * This is an interrupt driven driver, which supports master mode only.
  315. */
  316. NUTI2C_BUS i2cBus0At91 = {
  317. &twi0cb, /* bus_icb */
  318. TwiBusInit, /* bus_init */
  319. TwiBusConf, /* bus_configure */
  320. TwiBusProbe,/* bus_probe */
  321. TwiBusTran, /* bus_transceive */
  322. 100, /* bus_timeout */
  323. 0, /* bus_rate */
  324. 0, /* bus_flags */
  325. NULL /* bus_mutex */
  326. };
  327. /* Second interface currently disabled because of missing IRQ handler. */
  328. #if 0 && defined(TWI1_BASE)
  329. static AT91_TWICB twi1cb = {
  330. TWI1_BASE, /* icb_base */
  331. &sig_TWI1, /* icb_sig */
  332. NULL, /* icb_msg */
  333. NULL /* icb_queue */
  334. };
  335. NUTI2C_BUS i2cBus1At91 = {
  336. &twi1cb, /* bus_icb */
  337. TwiBusInit, /* bus_init */
  338. TwiBusConf, /* bus_configure */
  339. TwiBusProbe,/* bus_probe */
  340. TwiBusTran, /* bus_transceive */
  341. 100, /* bus_timeout */
  342. 0, /* bus_rate */
  343. 0, /* bus_flags */
  344. NULL /* bus_mutex */
  345. };
  346. #endif
  347. /*@}*/