twbbif.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875
  1. /*
  2. * Copyright (C) 2005-2007 by egnite Software GmbH. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. Neither the name of the copyright holders nor the names of
  14. * contributors may be used to endorse or promote products derived
  15. * from this software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  18. * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  19. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  20. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  21. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  22. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  23. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  24. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  25. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  26. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
  27. * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  28. * SUCH DAMAGE.
  29. *
  30. * For additional information see http://www.ethernut.de/
  31. *
  32. */
  33. /*!
  34. * \file dev/twbbif.c
  35. * \brief Bit banging two wire interface.
  36. *
  37. * Tested with AT91R40008 only. Other ARMs or AVR may not work.
  38. *
  39. * \verbatim
  40. *
  41. * $Log$
  42. * Revision 1.11 2008/08/11 06:59:42 haraldkipp
  43. * BSD types replaced by stdint types (feature request #1282721).
  44. *
  45. * Revision 1.10 2008/02/15 17:04:49 haraldkipp
  46. * Spport for AT91SAM7SE512 added.
  47. *
  48. * Revision 1.9 2007/10/04 20:16:57 olereinhardt
  49. * Support for SAM7S256 added
  50. *
  51. * Revision 1.8 2007/07/09 13:38:50 olereinhardt
  52. * 2007-07-09 Ole Reinhardt <ole.reinhardt@embedded-it.de>
  53. * * dev/twbbif.c: Added default TWI_DELAY for avr architecture
  54. * to allow in-tree compilation
  55. * * net/Makefile: Commented out igmp support as long as it does
  56. * not exists to allow in-tree compilation
  57. *
  58. * Revision 1.7 2007/02/15 16:25:40 haraldkipp
  59. * Configurable port bits. Should work now on all AT91 MCUs.
  60. *
  61. * Revision 1.6 2006/10/08 16:48:09 haraldkipp
  62. * Documentation fixed
  63. *
  64. * Revision 1.5 2006/06/28 17:10:35 haraldkipp
  65. * Include more general header file for ARM.
  66. *
  67. * Revision 1.4 2006/05/25 09:30:23 haraldkipp
  68. * Compiles for AVR. Still not tested, though.
  69. *
  70. * Revision 1.3 2006/04/07 12:50:20 haraldkipp
  71. * Added additional delays in TwAck.
  72. * Clock and data forced to high before switching to input gives better
  73. * waveforms.
  74. * Additional delay added to set clock to 50% duty cycle. The PCF8563
  75. * seems to fail, if the clock's high time is much longer than the low time.
  76. *
  77. * Revision 1.2 2006/01/23 17:32:35 haraldkipp
  78. * Automatic initialization added.
  79. *
  80. * Revision 1.1 2005/10/24 10:21:57 haraldkipp
  81. * Initial check in.
  82. *
  83. *
  84. * \endverbatim
  85. */
  86. #include <cfg/os.h>
  87. #include <cfg/twi.h>
  88. #include <cfg/arch/gpio.h>
  89. #include <sys/heap.h>
  90. #include <sys/event.h>
  91. #include <string.h>
  92. #include <dev/twif.h>
  93. #if defined(__arm__)
  94. #include <arch/arm.h>
  95. /*!
  96. * \brief GPIO controller ID.
  97. *
  98. * Target specific defaults are set if the ID is not specified elsewhere.
  99. */
  100. #if !defined(TWI_PIO_ID)
  101. #if defined(MCU_AT91SAM7X) || defined(MCU_AT91SAM7S256) || defined(MCU_AT91SAM7SE512)
  102. #define TWI_PIO_ID PIOA_ID
  103. #elif defined(MCU_AT91SAM9260)
  104. #define TWI_PIO_ID PIOB_ID
  105. #else
  106. #define TWI_PIO_ID PIO_ID
  107. #endif
  108. #endif
  109. /*!
  110. * \brief GPIO bit of bit banging TWI data line.
  111. *
  112. * Target specific defaults are used if the bit is not specified elsewhere.
  113. */
  114. #ifndef TWI_SDA_BIT
  115. #if defined(MCU_AT91SAM9260)
  116. #define TWI_SDA_BIT 12
  117. #else
  118. #define TWI_SDA_BIT 10
  119. #endif
  120. #endif
  121. /*!
  122. * \brief Clock delay.
  123. */
  124. #ifndef TWI_DELAY
  125. #if defined(MCU_AT91SAM9260)
  126. #define TWI_DELAY 16
  127. #else
  128. #define TWI_DELAY 8
  129. #endif
  130. #endif
  131. /*!
  132. * \brief GPIO bit of bit banging TWI clock line.
  133. *
  134. * Target specific defaults are used if the bit is not specified elsewhere.
  135. */
  136. #ifndef TWI_SCL_BIT
  137. #if defined(MCU_AT91SAM9260)
  138. #define TWI_SCL_BIT 13
  139. #else
  140. #define TWI_SCL_BIT 11
  141. #endif
  142. #endif
  143. /*!
  144. * \brief Bit banging TWI GPIO registers.
  145. *
  146. * Based on the GPIO controller ID.
  147. */
  148. #if TWI_PIO_ID == PIOA_ID
  149. #ifndef TWI_SDA_PE_REG
  150. #define TWI_SDA_PE_REG PIOA_PER
  151. #endif
  152. #ifndef TWI_SDA_OE_REG
  153. #define TWI_SDA_OE_REG PIOA_OER
  154. #endif
  155. #ifndef TWI_SDA_OD_REG
  156. #define TWI_SDA_OD_REG PIOA_ODR
  157. #endif
  158. #ifndef TWI_SDA_COD_REG
  159. #define TWI_SDA_COD_REG PIOA_CODR
  160. #endif
  161. #ifndef TWI_SDA_SOD_REG
  162. #define TWI_SDA_SOD_REG PIOA_SODR
  163. #endif
  164. #ifndef TWI_SDA_PDS_REG
  165. #define TWI_SDA_PDS_REG PIOA_PDSR
  166. #endif
  167. #ifndef TWI_SCL_PE_REG
  168. #define TWI_SCL_PE_REG PIOA_PER
  169. #endif
  170. #ifndef TWI_SCL_OE_REG
  171. #define TWI_SCL_OE_REG PIOA_OER
  172. #endif
  173. #ifndef TWI_SCL_OD_REG
  174. #define TWI_SCL_OD_REG PIOA_ODR
  175. #endif
  176. #ifndef TWI_SCL_COD_REG
  177. #define TWI_SCL_COD_REG PIOA_CODR
  178. #endif
  179. #ifndef TWI_SCL_SOD_REG
  180. #define TWI_SCL_SOD_REG PIOA_SODR
  181. #endif
  182. #ifndef TWI_SCL_PDS_REG
  183. #define TWI_SCL_PDS_REG PIOA_PDSR
  184. #endif
  185. #elif TWI_PIO_ID == PIOB_ID
  186. #ifndef TWI_SDA_PE_REG
  187. #define TWI_SDA_PE_REG PIOB_PER
  188. #endif
  189. #ifndef TWI_SDA_OE_REG
  190. #define TWI_SDA_OE_REG PIOB_OER
  191. #endif
  192. #ifndef TWI_SDA_OD_REG
  193. #define TWI_SDA_OD_REG PIOB_ODR
  194. #endif
  195. #ifndef TWI_SDA_COD_REG
  196. #define TWI_SDA_COD_REG PIOB_CODR
  197. #endif
  198. #ifndef TWI_SDA_SOD_REG
  199. #define TWI_SDA_SOD_REG PIOB_SODR
  200. #endif
  201. #ifndef TWI_SDA_PDS_REG
  202. #define TWI_SDA_PDS_REG PIOB_PDSR
  203. #endif
  204. #ifndef TWI_SCL_PE_REG
  205. #define TWI_SCL_PE_REG PIOB_PER
  206. #endif
  207. #ifndef TWI_SCL_OE_REG
  208. #define TWI_SCL_OE_REG PIOB_OER
  209. #endif
  210. #ifndef TWI_SCL_OD_REG
  211. #define TWI_SCL_OD_REG PIOB_ODR
  212. #endif
  213. #ifndef TWI_SCL_COD_REG
  214. #define TWI_SCL_COD_REG PIOB_CODR
  215. #endif
  216. #ifndef TWI_SCL_SOD_REG
  217. #define TWI_SCL_SOD_REG PIOB_SODR
  218. #endif
  219. #ifndef TWI_SCL_PDS_REG
  220. #define TWI_SCL_PDS_REG PIOB_PDSR
  221. #endif
  222. #elif TWI_PIO_ID == PIOC_ID
  223. #ifndef TWI_SDA_PE_REG
  224. #define TWI_SDA_PE_REG PIOC_PER
  225. #endif
  226. #ifndef TWI_SDA_OE_REG
  227. #define TWI_SDA_OE_REG PIOC_OER
  228. #endif
  229. #ifndef TWI_SDA_OD_REG
  230. #define TWI_SDA_OD_REG PIOC_ODR
  231. #endif
  232. #ifndef TWI_SDA_COD_REG
  233. #define TWI_SDA_COD_REG PIOC_CODR
  234. #endif
  235. #ifndef TWI_SDA_SOD_REG
  236. #define TWI_SDA_SOD_REG PIOC_SODR
  237. #endif
  238. #ifndef TWI_SDA_PDS_REG
  239. #define TWI_SDA_PDS_REG PIOC_PDSR
  240. #endif
  241. #ifndef TWI_SCL_PE_REG
  242. #define TWI_SCL_PE_REG PIOC_PER
  243. #endif
  244. #ifndef TWI_SCL_OE_REG
  245. #define TWI_SCL_OE_REG PIOC_OER
  246. #endif
  247. #ifndef TWI_SCL_OD_REG
  248. #define TWI_SCL_OD_REG PIOC_ODR
  249. #endif
  250. #ifndef TWI_SCL_COD_REG
  251. #define TWI_SCL_COD_REG PIOC_CODR
  252. #endif
  253. #ifndef TWI_SCL_SOD_REG
  254. #define TWI_SCL_SOD_REG PIOC_SODR
  255. #endif
  256. #ifndef TWI_SCL_PDS_REG
  257. #define TWI_SCL_PDS_REG PIOC_PDSR
  258. #endif
  259. #else
  260. #ifndef TWI_SDA_PE_REG
  261. #define TWI_SDA_PE_REG PIO_PER
  262. #endif
  263. #ifndef TWI_SDA_OE_REG
  264. #define TWI_SDA_OE_REG PIO_OER
  265. #endif
  266. #ifndef TWI_SDA_OD_REG
  267. #define TWI_SDA_OD_REG PIO_ODR
  268. #endif
  269. #ifndef TWI_SDA_COD_REG
  270. #define TWI_SDA_COD_REG PIO_CODR
  271. #endif
  272. #ifndef TWI_SDA_SOD_REG
  273. #define TWI_SDA_SOD_REG PIO_SODR
  274. #endif
  275. #ifndef TWI_SDA_PDS_REG
  276. #define TWI_SDA_PDS_REG PIO_PDSR
  277. #endif
  278. #ifndef TWI_SCL_PE_REG
  279. #define TWI_SCL_PE_REG PIO_PER
  280. #endif
  281. #ifndef TWI_SCL_OE_REG
  282. #define TWI_SCL_OE_REG PIO_OER
  283. #endif
  284. #ifndef TWI_SCL_OD_REG
  285. #define TWI_SCL_OD_REG PIO_ODR
  286. #endif
  287. #ifndef TWI_SCL_COD_REG
  288. #define TWI_SCL_COD_REG PIO_CODR
  289. #endif
  290. #ifndef TWI_SCL_SOD_REG
  291. #define TWI_SCL_SOD_REG PIO_SODR
  292. #endif
  293. #ifndef TWI_SCL_PDS_REG
  294. #define TWI_SCL_PDS_REG PIO_PDSR
  295. #endif
  296. #endif
  297. #define TWI_ENABLE() { \
  298. outr(TWI_SDA_COD_REG, _BV(TWI_SDA_BIT)); \
  299. outr(TWI_SCL_COD_REG, _BV(TWI_SCL_BIT)); \
  300. outr(TWI_SDA_PE_REG, _BV(TWI_SDA_BIT)); \
  301. outr(TWI_SCL_PE_REG, _BV(TWI_SCL_BIT)); \
  302. }
  303. #define SDA_LOW() { \
  304. outr(TWI_SDA_COD_REG, _BV(TWI_SDA_BIT)); \
  305. outr(TWI_SDA_OE_REG, _BV(TWI_SDA_BIT)); \
  306. }
  307. #define SDA_HIGH() { \
  308. outr(TWI_SDA_SOD_REG, _BV(TWI_SDA_BIT)); \
  309. outr(TWI_SDA_OD_REG, _BV(TWI_SDA_BIT)); \
  310. }
  311. #define SDA_STAT() (inr(TWI_SDA_PDS_REG) & _BV(TWI_SDA_BIT))
  312. #define SCL_LOW() { \
  313. outr(TWI_SCL_COD_REG, _BV(TWI_SCL_BIT)); \
  314. outr(TWI_SCL_OE_REG, _BV(TWI_SCL_BIT)); \
  315. }
  316. #define SCL_HIGH() { \
  317. outr(TWI_SCL_SOD_REG, _BV(TWI_SCL_BIT)); \
  318. outr(TWI_SCL_OD_REG, _BV(TWI_SCL_BIT)); \
  319. }
  320. #elif defined(__AVR__)
  321. /*
  322. * AVR not yet tested.
  323. */
  324. #include <cfg/arch/avr.h>
  325. #ifndef TWI_SDA_BIT
  326. #define TWI_SDA_BIT 0
  327. #endif
  328. #if (TWI_SDA_AVRPORT == AVRPORTD)
  329. #define TWI_SDA_PORT PORTD
  330. #define TWI_SDA_PIN PIND
  331. #define TWI_SDA_DDR DDRD
  332. #elif (TWI_SDA_AVRPORT == AVRPORTE)
  333. #define TWI_SDA_PORT PORTE
  334. #define TWI_SDA_PIN PINE
  335. #define TWI_SDA_DDR DDRE
  336. #elif (TWI_SDA_AVRPORT == AVRPORTF)
  337. #define TWI_SDA_PORT PORTF
  338. #define TWI_SDA_PIN PINF
  339. #define TWI_SDA_DDR DDRF
  340. #else
  341. #define TWI_SDA_PORT PORTB
  342. #define TWI_SDA_PIN PINB
  343. #define TWI_SDA_DDR DDRB
  344. #endif
  345. #ifndef TWI_SCL_BIT
  346. #define TWI_SCL_BIT 1
  347. #endif
  348. #if (TWI_SCL_AVRPORT == AVRPORTD)
  349. #define TWI_SCL_PORT PORTD
  350. #define TWI_SCL_DDR DDRD
  351. #elif (TWI_SCL_AVRPORT == AVRPORTE)
  352. #define TWI_SCL_PORT PORTE
  353. #define TWI_SCL_DDR DDRE
  354. #elif (TWI_SCL_AVRPORT == AVRPORTF)
  355. #define TWI_SCL_PORT PORTF
  356. #define TWI_SCL_DDR DDRF
  357. #else
  358. #define TWI_SCL_PORT PORTB
  359. #define TWI_SCL_DDR DDRB
  360. #endif
  361. #define TWI_ENABLE() { \
  362. cbi(TWI_SDA_PORT, TWI_SDA_BIT); \
  363. cbi(TWI_SCL_PORT, TWI_SCL_BIT); \
  364. }
  365. #define SDA_LOW() sbi(TWI_SDA_DDR, TWI_SDA_BIT)
  366. #define SDA_HIGH() cbi(TWI_SDA_DDR, TWI_SDA_BIT)
  367. #define SDA_STAT() bit_is_set(TWI_SDA_PIN, TWI_SDA_BIT)
  368. #define SCL_LOW() sbi(TWI_SCL_DDR, TWI_SCL_BIT)
  369. #define SCL_HIGH() cbi(TWI_SCL_DDR, TWI_SCL_BIT)
  370. #ifndef TWI_DELAY
  371. #define TWI_DELAY 8
  372. #endif
  373. #endif /* __AVR__ */
  374. static int twibb_initialized;
  375. /*
  376. * Short delay.
  377. *
  378. * Our bit banging code relies on pull-up resistors. The I/O ports mimic
  379. * open collector outputs by switching to input mode for high level and
  380. * switching to output mode for low level. This is much slower than
  381. * switching an output between low to high. Thus we need some delay.
  382. */
  383. static void TwDelay(int nops)
  384. {
  385. while (nops--) {
  386. _NOP();
  387. }
  388. }
  389. /*
  390. * Falling edge on the data line while the clock line is high indicates
  391. * a start condition.
  392. *
  393. * Entry: SCL any, SDA any
  394. * Exit: SCL low, SDA low
  395. */
  396. static void TwStart(void)
  397. {
  398. SDA_HIGH();
  399. TwDelay(TWI_DELAY);
  400. SCL_HIGH();
  401. TwDelay(TWI_DELAY);
  402. SDA_LOW();
  403. TwDelay(TWI_DELAY);
  404. SCL_LOW();
  405. TwDelay(TWI_DELAY);
  406. }
  407. /*
  408. * Rising edge on the data line while the clock line is high indicates
  409. * a stop condition.
  410. *
  411. * Entry: SCL low, SDA any
  412. * Exit: SCL high, SDA high
  413. */
  414. static void TwStop(void)
  415. {
  416. SDA_LOW();
  417. TwDelay(TWI_DELAY);
  418. SCL_HIGH();
  419. TwDelay(2 * TWI_DELAY);
  420. SDA_HIGH();
  421. TwDelay(8 * TWI_DELAY);
  422. }
  423. /*
  424. * Toggles out a single byte in master mode.
  425. *
  426. * Entry: SCL low, SDA any
  427. * Exit: SCL low, SDA high
  428. */
  429. static int TwPut(uint8_t octet)
  430. {
  431. int i;
  432. for (i = 0x80; i; i >>= 1) {
  433. /* Set the data bit. */
  434. if (octet & i) {
  435. SDA_HIGH();
  436. } else {
  437. SDA_LOW();
  438. }
  439. /* Wait for data to stabelize. */
  440. TwDelay(TWI_DELAY);
  441. /* Toggle the clock. */
  442. SCL_HIGH();
  443. TwDelay(2 * TWI_DELAY);
  444. SCL_LOW();
  445. TwDelay(TWI_DELAY);
  446. }
  447. /* Set data line high to receive the ACK bit. */
  448. SDA_HIGH();
  449. /* ACK should appear shortly after the clock's rising edge. */
  450. SCL_HIGH();
  451. TwDelay(2 * TWI_DELAY);
  452. if (SDA_STAT()) {
  453. i = -1;
  454. } else {
  455. i = 0;
  456. }
  457. SCL_LOW();
  458. return i;
  459. }
  460. /*
  461. * Toggles in a single byte in master mode.
  462. *
  463. * Entry: SCL low, SDA any
  464. * Exit: SCL low, SDA high
  465. */
  466. static uint8_t TwGet(void)
  467. {
  468. uint8_t rc = 0;
  469. int i;
  470. /* SDA is input. */
  471. SDA_HIGH();
  472. TwDelay(TWI_DELAY);
  473. for (i = 0x80; i; i >>= 1) {
  474. TwDelay(TWI_DELAY);
  475. /* Data should appear shortly after the clock's rising edge. */
  476. SCL_HIGH();
  477. TwDelay(2 * TWI_DELAY);
  478. /* SDA read. */
  479. if (SDA_STAT()) {
  480. rc |= i;
  481. }
  482. SCL_LOW();
  483. }
  484. return rc;
  485. }
  486. /*
  487. * Toggles out an acknowledge bit in master mode.
  488. *
  489. * Entry: SCL low, SDA any
  490. * Exit: SCL low, SDA high
  491. */
  492. static void TwAck(void)
  493. {
  494. SDA_LOW();
  495. TwDelay(TWI_DELAY);
  496. SCL_HIGH();
  497. TwDelay(2 * TWI_DELAY);
  498. SCL_LOW();
  499. TwDelay(TWI_DELAY);
  500. SDA_HIGH();
  501. }
  502. /*!
  503. * \brief Transmit and/or receive data as a master.
  504. *
  505. * The two-wire serial interface must have been initialized by calling
  506. * TwInit() before this function can be used.
  507. *
  508. * \param sla Slave address of the destination. This slave address
  509. * must be specified as a 7-bit address. For example, the
  510. * PCF8574A may be configured to slave addresses from 0x38
  511. * to 0x3F.
  512. * \param txdata Points to the data to transmit. Ignored, if the number
  513. * of data bytes to transmit is zero.
  514. * \param txlen Number of data bytes to transmit. If zero, then the
  515. * interface will not send any data to the slave device
  516. * and will directly enter the master receive mode.
  517. * \param rxdata Points to a buffer, where the received data will be
  518. * stored. Ignored, if the maximum number of bytes to
  519. * receive is zero.
  520. * \param rxsiz Maximum number of bytes to receive. Set to zero, if
  521. * no bytes are expected from the slave device.
  522. * \param tmo Timeout in milliseconds. To disable timeout, set this
  523. * parameter to NUT_WAIT_INFINITE.
  524. *
  525. * \return The number of bytes received, -1 in case of an error or timeout.
  526. *
  527. * \note Timeout is not used in the bit banging version.
  528. */
  529. int NutTwiMasterTranceive(NUTTWIBUS *bus, uint8_t sla, const void *txdata, uint16_t txlen, void *rxdata, uint16_t rxsiz, uint32_t tmo)
  530. {
  531. int rc = 0;
  532. uint8_t *cp;
  533. NUTTWIICB *icb = bus->bus_icb;
  534. if (!twibb_initialized) {
  535. TwInit(0);
  536. }
  537. /* This routine is marked reentrant, so lock the interface. */
  538. if (NutEventWait(&bus->bus_mutex, tmo)) {
  539. icb->tw_mm_error = TWERR_IF_LOCKED;
  540. return -1;
  541. }
  542. TwStart();
  543. /* Send SLA+W and check for ACK. */
  544. if ((rc = TwPut(sla << 1)) == 0) {
  545. for (cp = (uint8_t *)txdata; txlen--; cp++) {
  546. if ((rc = TwPut(*cp)) != 0) {
  547. break;
  548. }
  549. }
  550. }
  551. if (rc == 0 && rxsiz) {
  552. TwStart();
  553. /* Send SLA+R and check for ACK. */
  554. if ((rc = TwPut((sla << 1) | 1)) == 0) {
  555. for (cp = rxdata;; cp++) {
  556. *cp = TwGet();
  557. if (++rc >= rxsiz) {
  558. break;
  559. }
  560. TwAck();
  561. }
  562. }
  563. }
  564. TwStop();
  565. if (rc == -1) {
  566. icb->tw_mm_error = TWERR_SLA_NACK;
  567. }
  568. /* Release the interface. */
  569. NutEventPost(&bus->bus_mutex);
  570. return rc;
  571. }
  572. /*!
  573. * \brief Get last master mode error.
  574. *
  575. * You may call this function to determine the specific cause
  576. * of an error after twi transaction failed.
  577. *
  578. */
  579. int NutTwiMasterError(NUTTWIBUS *bus)
  580. {
  581. int rc = bus->bus_icb->tw_mm_error;
  582. bus->bus_icb->tw_mm_error = 0;
  583. return rc;
  584. }
  585. /*!
  586. * \brief Listen for incoming data from a master.
  587. *
  588. * If this function returns without error, the bus is blocked. The caller
  589. * must immediately process the request and return a response by calling
  590. * TwSlaveRespond().
  591. *
  592. * \note Slave mode is not implemented in the bitbanging driver.
  593. * Thus the function always returns -1.
  594. *
  595. * \param sla Points to a byte variable, which receives the slave
  596. * address sent by the master. This can be used by the
  597. * caller to determine whether the the interface has been
  598. * addressed by a general call or its individual address.
  599. * \param rxdata Points to a data buffer where the received data bytes
  600. * are stored.
  601. * \param rxsiz Specifies the maximum number of data bytes to receive.
  602. * \param tmo Timeout in milliseconds. To disable timeout,
  603. * set this parameter to NUT_WAIT_INFINITE.
  604. *
  605. * \return The number of bytes received, -1 in case of an error or timeout.
  606. *
  607. */
  608. int NutTwiSlaveListen(NUTTWIBUS *bus, uint8_t *sla, void *rxdata, uint16_t rxsiz, uint32_t tmo)
  609. {
  610. return -1;
  611. }
  612. /*!
  613. * \brief Send response to a master.
  614. *
  615. * This function must be called as soon as possible after TwSlaveListen()
  616. * returned successfully, even if no data needs to be returned. Not doing
  617. * so will completely block the bus.
  618. *
  619. * \note Slave mode is not implemented in the bitbanging driver.
  620. * Thus the function always returns -1.
  621. *
  622. * \param txdata Points to the data to transmit. Ignored, if the
  623. * number of bytes to transmit is zero.
  624. * \param txlen Number of data bytes to transmit.
  625. * \param tmo Timeout in milliseconds. To disable timeout,
  626. * set this parameter to NUT_WAIT_INFINITE.
  627. *
  628. * \return The number of bytes transmitted, -1 in case of an error or timeout.
  629. */
  630. extern int NutTwiSlaveRespond(NUTTWIBUS *bus, void *txdata, uint16_t txlen, uint32_t tmo)
  631. {
  632. return -1;
  633. }
  634. /*!
  635. * \brief Get last slave mode error.
  636. *
  637. * You may call this function to determine the specific cause
  638. * of an error after TwSlaveListen() or TwSlaveRespond() failed.
  639. *
  640. * \return Error code or 0 if no error occurred.
  641. *
  642. * \note Slave mode is not implemented in the bitbanging driver.
  643. * Thus the function always returns TWERR_BUS.
  644. */
  645. extern int NutTwiSlaveError(NUTTWIBUS *bus)
  646. {
  647. return TWERR_BUS;
  648. }
  649. /*!
  650. * \brief Set Speed of I2C Interface.
  651. *
  652. * Setup Interface Speed
  653. */
  654. int NutTwiSetSpeed( NUTTWIBUS *bus, uint32_t speed)
  655. {
  656. int rc = -1;
  657. if (speed > 400000) {
  658. /* Speed out of range */
  659. return rc;
  660. }
  661. if (bus==NULL) {
  662. /* No bus selected */
  663. return rc;
  664. }
  665. return 0;
  666. }
  667. /*!
  668. * \brief Request Current Speed of I2C Interface.
  669. *
  670. * \return always 10000 which is just a dummy value
  671. */
  672. uint32_t NutTwiGetSpeed( NUTTWIBUS *bus)
  673. {
  674. return 10000;
  675. }
  676. /*!
  677. * \brief Perform TWI control functions.
  678. *
  679. * Not implemented in the bit banging version.
  680. *
  681. * \param req Requested control function.
  682. * \param conf Points to a buffer that contains any data required for
  683. * the given control function or receives data from that
  684. * function.
  685. *
  686. * \return Always 0.
  687. */
  688. int NutTwiIOCtl( NUTTWIBUS *bus, int req, void *conf )
  689. {
  690. int rc = 0;
  691. switch (req) {
  692. case TWI_SETSPEED:
  693. rc = NutTwiSetSpeed(bus, *((uint32_t *)conf));
  694. break;
  695. case TWI_GETSPEED:
  696. *((uint32_t *)conf) = NutTwiGetSpeed(bus);
  697. break;
  698. case TWI_GETSTATUS:
  699. rc = 0;
  700. break;
  701. case TWI_SETSTATUS:
  702. rc = 0;
  703. break;
  704. default:
  705. rc = -1;
  706. break;
  707. }
  708. return rc;
  709. }
  710. /*!
  711. * \brief Initialize TWI interface.
  712. *
  713. * The specified slave address is used only, if the local system
  714. * is running as a slave. Anyway, care must be taken that it doesn't
  715. * conflict with another connected device.
  716. *
  717. * \param sla Slave address, must be specified as a 7-bit address,
  718. * always lower than 128.
  719. *
  720. * \return Always 0.
  721. *
  722. */
  723. int TwBbifInit(void)
  724. {
  725. SDA_HIGH();
  726. SCL_HIGH();
  727. TWI_ENABLE();
  728. twibb_initialized = 1;
  729. return 0;
  730. }
  731. /*!
  732. * \brief Initialize TWI interface bus.
  733. *
  734. * The specified slave address is not used here as we don't support twi-slave
  735. * on the bitbanging interface
  736. *
  737. * \param sla Slave address, must be specified as a 7-bit address,
  738. * always lower than 128.
  739. */
  740. int NutRegisterTwiBus( NUTTWIBUS *bus, uint8_t sla )
  741. {
  742. int rc = 0;
  743. NUTTWIICB *icb = NULL;
  744. /* Check if bus was already registered */
  745. if( bus->bus_icb) {
  746. return 0;
  747. }
  748. /* Allocate ICB for this bus */
  749. icb = NutHeapAlloc(sizeof(NUTTWIICB));
  750. if( icb == NULL) {
  751. return rc;
  752. }
  753. memset( icb, 0, sizeof(NUTTWIICB));
  754. /* Link bus and ICB */
  755. bus->bus_icb = icb;
  756. /* Initialize interface hardware */
  757. if (bus->bus_initbus) {
  758. rc = bus->bus_initbus();
  759. }
  760. /* Initialize mutex semaphores. */
  761. NutEventPost(&bus->bus_mutex);
  762. return rc;
  763. }
  764. int NutDestroyTwiBus( NUTTWIBUS *bus)
  765. {
  766. if (bus->bus_icb) {
  767. NutHeapFree( bus->bus_icb);
  768. }
  769. return 0;
  770. }
  771. /*!
  772. * \brief TWI/I2C bus structure.
  773. */
  774. NUTTWIBUS TwBbifBus = {
  775. /*.bus_base = */ 0, /* Bus base address. */
  776. /*.bus_sig_ev = */ NULL, /* Bus data and event interrupt handler. */
  777. /*.bus_sig_er = */ NULL, /* Bus error interrupt handler. */
  778. /*.bus_mutex = */ NULL, /* Bus lock queue. */
  779. /*.bus_icb = */ NULL, /* Bus Runtime Data Pointer */
  780. /*.bus_dma_tx = */ 0, /* DMA channel for TX direction. */
  781. /*.bus_dma_rx = */ 0, /* DMA channel for RX direction. */
  782. /*.bus_initbus =*/ TwBbifInit, /* Initialize bus controller. */
  783. /*.bus_recover =*/ NULL, /* Recover bus controller */
  784. };