ds28e17.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993
  1. /****************************************************************************
  2. * drivers/1wire/ds28e17.c
  3. *
  4. * Copyright (C) 2018 Haltian Ltd. All rights reserved.
  5. * Author: Juha Niskanen <juha.niskanen@haltian.com>
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. *
  11. * 1. Redistributions of source code must retain the above copyright
  12. * notice, this list of conditions and the following disclaimer.
  13. * 2. Redistributions in binary form must reproduce the above copyright
  14. * notice, this list of conditions and the following disclaimer in
  15. * the documentation and/or other materials provided with the
  16. * distribution.
  17. * 3. Neither the name NuttX nor the names of its contributors may be
  18. * used to endorse or promote products derived from this software
  19. * without specific prior written permission.
  20. *
  21. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  22. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  23. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  24. * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  25. * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  26. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  27. * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
  28. * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  29. * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  30. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  31. * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  32. * POSSIBILITY OF SUCH DAMAGE.
  33. *
  34. ****************************************************************************/
  35. /****************************************************************************
  36. * Included Files
  37. ****************************************************************************/
  38. #include <nuttx/config.h>
  39. #include <errno.h>
  40. #include <debug.h>
  41. #include <string.h>
  42. #include <nuttx/kmalloc.h>
  43. #include <nuttx/i2c/i2c_master.h>
  44. #include <nuttx/drivers/1wire.h>
  45. #include <nuttx/1wire/ds28e17.h>
  46. #include "1wire_internal.h"
  47. /****************************************************************************
  48. * Pre-processor Definitions
  49. ****************************************************************************/
  50. #ifndef CONFIG_DS28E17_I2C_FREQUENCY
  51. # define CONFIG_DS28E17_I2C_FREQUENCY 400000
  52. #endif
  53. /* DS28E17 device 1-Wire family ID */
  54. #define DS_FAMILY 0x19
  55. /* DS28E17 device I2C commands */
  56. #define DS_WRITE_DATA_WITH_STOP 0x4b
  57. #define DS_WRITE_DATA_NO_STOP 0x5a
  58. #define DS_WRITE_DATA_ONLY 0x69
  59. #define DS_WRITE_DATA_ONLY_WITH_STOP 0x78
  60. #define DS_READ_DATA_WITH_STOP 0x87
  61. #define DS_WRITE_READ_DATA_WITH_STOP 0x2d
  62. #define DS_WRITE_CONFIGURATION 0xd2
  63. #define DS_READ_CONFIGURATION 0xe1
  64. #define DS_ENABLE_SLEEP_MODE 0x1e
  65. #define DS_READ_DEVICE_REVISION 0xc4
  66. /* DS28E17 status bits */
  67. #define DS_STATUS_CRC 0x01
  68. #define DS_STATUS_ADDRESS 0x02
  69. #define DS_STATUS_START 0x08
  70. /* Maximum number of I2C bytes to transfer within one CRC16 protected onewire
  71. * command (same for either read and write).
  72. */
  73. #define DS_DATA_LIMIT 255
  74. /* Default I2C frequency to use when DS28E17 is detected. */
  75. #define DS_DEFAULT_FREQUENCY CONFIG_DS28E17_I2C_FREQUENCY
  76. /* Default I2C stretch value. */
  77. #define DS_DEFAULT_STRETCH 1
  78. /* How many times to retry check for chip busy condition vanishing. */
  79. #define DS_BUSYWAIT_RETRIES 500
  80. /****************************************************************************
  81. * Private Types
  82. ****************************************************************************/
  83. struct ds28e17_dev_s /* Must be cast-compatible with onewire_master_s */
  84. {
  85. FAR struct onewire_dev_s *dev; /* 1-wire interface */
  86. };
  87. /* I2C Device, Instance */
  88. struct ds_i2c_inst_s /* Must be cast-compatible with i2c_master_s */
  89. {
  90. FAR const struct i2c_ops_s *ops; /* Standard I2C operations */
  91. /* 1-wire data */
  92. FAR struct onewire_master_s *master; /* 1-wire bus master */
  93. FAR struct onewire_slave_s slave; /* Our slave data on 1-wire bus */
  94. /* I2C data */
  95. uint32_t frequency; /* Current I2C frequency */
  96. uint8_t stretch; /* Current I2C stretch value */
  97. };
  98. /****************************************************************************
  99. * Private Function Prototypes
  100. ****************************************************************************/
  101. static int ds_i2c_reset(FAR struct i2c_master_s *i2cdev);
  102. static int ds_i2c_transfer(FAR struct i2c_master_s *i2cdev,
  103. FAR struct i2c_msg_s *msgs, int count);
  104. /****************************************************************************
  105. * Private Data
  106. ****************************************************************************/
  107. /* Device Structures, Instantiation */
  108. static const struct i2c_ops_s ds_i2c_ops =
  109. {
  110. .transfer = ds_i2c_transfer
  111. #ifdef CONFIG_I2C_RESET
  112. , .reset = ds_i2c_reset
  113. #endif
  114. };
  115. /****************************************************************************
  116. * Private Functions
  117. ****************************************************************************/
  118. /****************************************************************************
  119. * Name: ds_i2c_sem_wait
  120. *
  121. * Description:
  122. * Take the exclusive access, waiting as necessary
  123. *
  124. ****************************************************************************/
  125. static inline void ds_i2c_sem_wait(FAR struct i2c_master_s *i2cdev)
  126. {
  127. FAR struct ds_i2c_inst_s *inst = (FAR struct ds_i2c_inst_s *)i2cdev;
  128. FAR struct onewire_master_s *master = inst->master;
  129. return onewire_sem_wait(master);
  130. }
  131. /****************************************************************************
  132. * Name: ds_i2c_sem_post
  133. *
  134. * Description:
  135. * Release the mutual exclusion semaphore
  136. *
  137. ****************************************************************************/
  138. static inline void ds_i2c_sem_post(FAR struct i2c_master_s *i2cdev)
  139. {
  140. FAR struct ds_i2c_inst_s *inst = (FAR struct ds_i2c_inst_s *)i2cdev;
  141. FAR struct onewire_master_s *master = inst->master;
  142. onewire_sem_post(master);
  143. }
  144. static int ds_error(uint8_t buf[])
  145. {
  146. /* Warnings */
  147. if (buf[0] & DS_STATUS_CRC)
  148. {
  149. i2cwarn("crc16 match failed\n");
  150. }
  151. if ((buf[0] & (DS_STATUS_CRC | DS_STATUS_ADDRESS)) == 0 && buf[1] != 0)
  152. {
  153. i2cwarn("I2C short write, no ack for %d bytes\n", buf[1]);
  154. }
  155. /* Error conditions */
  156. if (buf[0] & DS_STATUS_ADDRESS)
  157. {
  158. i2cerr("I2C device not responding\n");
  159. return -ENXIO;
  160. }
  161. if (buf[0] & DS_STATUS_START)
  162. {
  163. i2cerr("I2C status start\n");
  164. return -EAGAIN;
  165. }
  166. if (buf[0] != 0 || buf[1] != 0)
  167. {
  168. i2cerr("I2C IO error\n");
  169. return -EIO;
  170. }
  171. return OK;
  172. }
  173. static inline int ds_busywait_time(FAR struct ds_i2c_inst_s *inst)
  174. {
  175. int d;
  176. /* Return busywait time (us) for I2C speeds 100 kHz, 400 kHz
  177. * and 900 kHz, adjusted with current stretch value.
  178. */
  179. switch (inst->frequency)
  180. {
  181. case 100000:
  182. d = 90;
  183. break;
  184. case 400000:
  185. default:
  186. d = 23;
  187. break;
  188. case 900000:
  189. d = 10;
  190. break;
  191. }
  192. return d * inst->stretch;
  193. }
  194. static int ds_busywait(FAR struct ds_i2c_inst_s *inst, size_t length)
  195. {
  196. FAR struct onewire_master_s *master = inst->master;
  197. int retries = DS_BUSYWAIT_RETRIES;
  198. int delay;
  199. int ret;
  200. uint8_t bit = 1;
  201. /* Calculate delay time from current I2C settings. */
  202. delay = ds_busywait_time(inst);
  203. do
  204. {
  205. ret = ONEWIRE_READBIT(master->dev, &bit);
  206. if (ret < 0)
  207. {
  208. i2cerr("ERROR: ONEWIRE_READBIT failed\n");
  209. return ret;
  210. }
  211. if (bit == 0)
  212. {
  213. return OK;
  214. }
  215. if (retries == DS_BUSYWAIT_RETRIES)
  216. {
  217. /* First time, after checking bit once, do a big delay
  218. * for I2C to process all bytes in message.
  219. */
  220. up_udelay(delay * length);
  221. }
  222. else
  223. {
  224. /* Otherwise, wait for one byte duration. */
  225. up_udelay(delay);
  226. }
  227. } while (retries-- > 0);
  228. i2cwarn("busywait timeout\n");
  229. return -ETIMEDOUT;
  230. }
  231. /****************************************************************************
  232. * Name: ds_i2c_read
  233. *
  234. * Description:
  235. * Read data from I2C slave.
  236. *
  237. ****************************************************************************/
  238. static int ds_i2c_read(FAR struct ds_i2c_inst_s *inst, uint16_t i2c_addr,
  239. FAR uint8_t *buffer, ssize_t length)
  240. {
  241. FAR struct onewire_master_s *master = inst->master;
  242. uint16_t crc;
  243. int ret;
  244. uint8_t buf[5];
  245. if (length <= 0)
  246. {
  247. return -EINVAL;
  248. }
  249. if (length > DS_DATA_LIMIT)
  250. {
  251. i2cerr("ERROR: reading too many bytes!\n");
  252. return -EINVAL;
  253. }
  254. /* Send command to DS28E17. */
  255. buf[0] = DS_READ_DATA_WITH_STOP;
  256. buf[1] = i2c_addr << 1 | 0x01;
  257. buf[2] = length;
  258. crc = onewire_crc16(buf, 3, 0);
  259. buf[3] = ~(crc & 0xff);
  260. buf[4] = ~((crc >> 8) & 0xff);
  261. ret = ONEWIRE_WRITE(master->dev, buf, 5);
  262. if (ret < 0)
  263. {
  264. return ret;
  265. }
  266. /* Wait busy indication to vanish. */
  267. ret = ds_busywait(inst, length + 1);
  268. if (ret < 0)
  269. {
  270. return ret;
  271. }
  272. /* Read status from DS28E17. */
  273. ret = ONEWIRE_READ(master->dev, buf, 1);
  274. buf[1] = 0;
  275. /* Check error conditions. */
  276. ret = ds_error(buf);
  277. if (ret < 0)
  278. {
  279. return ret;
  280. }
  281. /* Read received I2C data from DS28E17. */
  282. return ONEWIRE_READ(master->dev, buffer, length);
  283. }
  284. /****************************************************************************
  285. * Name: ds_i2c_write
  286. *
  287. * Description:
  288. * Write data to I2C slave.
  289. *
  290. ****************************************************************************/
  291. static int ds_i2c_write(FAR struct ds_i2c_inst_s *inst, uint16_t i2c_addr,
  292. FAR const uint8_t *buffer, ssize_t length, bool stop)
  293. {
  294. FAR struct onewire_master_s *master = inst->master;
  295. uint16_t crc;
  296. int ret;
  297. uint8_t buf[3];
  298. if (length <= 0)
  299. {
  300. return -EINVAL;
  301. }
  302. if (length > DS_DATA_LIMIT)
  303. {
  304. /* TODO: split big writes into multiple chunks. */
  305. i2cerr("ERROR: writing too many bytes!\n");
  306. return -EINVAL;
  307. }
  308. /* Write command header. */
  309. buf[0] = stop ? DS_WRITE_DATA_WITH_STOP : DS_WRITE_DATA_NO_STOP;
  310. buf[1] = i2c_addr << 1;
  311. buf[2] = length;
  312. crc = onewire_crc16(buf, 3, 0);
  313. ret = ONEWIRE_WRITE(master->dev, buf, 3);
  314. if (ret < 0)
  315. {
  316. return ret;
  317. }
  318. /* Write payload I2C data to DS28E17. */
  319. crc = onewire_crc16(buffer, length, crc);
  320. ret = ONEWIRE_WRITE(master->dev, buffer, length);
  321. if (ret < 0)
  322. {
  323. return ret;
  324. }
  325. /* Write checksum. */
  326. buf[0] = ~(crc & 0xff);
  327. buf[1] = ~((crc >> 8) & 0xff);
  328. ret = ONEWIRE_WRITE(master->dev, buf, 2);
  329. if (ret < 0)
  330. {
  331. return ret;
  332. }
  333. /* Wait busy indication to vanish. */
  334. ret = ds_busywait(inst, length + 1);
  335. if (ret < 0)
  336. {
  337. return ret;
  338. }
  339. /* Read status from DS28E17. */
  340. ret = ONEWIRE_READ(master->dev, buf, 2);
  341. if (ret < 0)
  342. {
  343. return ret;
  344. }
  345. /* Check error conditions. */
  346. ret = ds_error(buf);
  347. if (ret < 0)
  348. {
  349. return ret;
  350. }
  351. /* Return count of bytes written. */
  352. return length;
  353. }
  354. /****************************************************************************
  355. * Name: ds_i2c_write_read
  356. *
  357. * Description:
  358. * Write data to I2C slave and read from same address.
  359. *
  360. ****************************************************************************/
  361. static int ds_i2c_write_read(FAR struct ds_i2c_inst_s *inst, uint16_t i2c_addr,
  362. FAR const uint8_t *wbuffer, ssize_t wlength,
  363. FAR uint8_t *rbuffer, ssize_t rlength)
  364. {
  365. FAR struct onewire_master_s *master = inst->master;
  366. uint16_t crc;
  367. int ret;
  368. uint8_t buf[3];
  369. if (wlength <= 0 || rlength <= 0)
  370. {
  371. return -EINVAL;
  372. }
  373. if (wlength > DS_DATA_LIMIT)
  374. {
  375. i2cerr("ERROR: writing too many bytes!\n");
  376. return -EINVAL;
  377. }
  378. if (rlength > DS_DATA_LIMIT)
  379. {
  380. i2cerr("ERROR: reading too many bytes!\n");
  381. return -EINVAL;
  382. }
  383. /* Write command header. */
  384. buf[0] = DS_WRITE_READ_DATA_WITH_STOP;
  385. buf[1] = i2c_addr << 1;
  386. buf[2] = wlength;
  387. crc = onewire_crc16(buf, 3, 0);
  388. ret = ONEWIRE_WRITE(master->dev, buf, 3);
  389. if (ret < 0)
  390. {
  391. return ret;
  392. }
  393. /* Write payload I2C data to DS28E17. */
  394. crc = onewire_crc16(wbuffer, wlength, crc);
  395. ret = ONEWIRE_WRITE(master->dev, wbuffer, wlength);
  396. if (ret < 0)
  397. {
  398. return ret;
  399. }
  400. /* Write read length and checksum. */
  401. buf[0] = rlength;
  402. crc = onewire_crc16(buf, 1, crc);
  403. buf[1] = ~(crc & 0xff);
  404. buf[2] = ~((crc >> 8) & 0xff);
  405. ret = ONEWIRE_WRITE(master->dev, buf, 3);
  406. if (ret < 0)
  407. {
  408. return ret;
  409. }
  410. /* Wait busy indication to vanish. */
  411. ret = ds_busywait(inst, wlength + 1 + rlength + 1);
  412. if (ret < 0)
  413. {
  414. return ret;
  415. }
  416. /* Read status from DS28E17. */
  417. ret = ONEWIRE_READ(master->dev, buf, 2);
  418. if (ret < 0)
  419. {
  420. return ret;
  421. }
  422. /* Check error conditions. */
  423. ret = ds_error(buf);
  424. if (ret < 0)
  425. {
  426. return ret;
  427. }
  428. /* Read received I2C data from DS28E17. */
  429. return ONEWIRE_READ(master->dev, rbuffer, rlength);
  430. }
  431. static int ds_i2c_setfrequency(FAR struct ds_i2c_inst_s *inst, uint32_t frequency)
  432. {
  433. FAR struct onewire_master_s *master = inst->master;
  434. uint8_t buf[2];
  435. int speed;
  436. int ret;
  437. switch (frequency)
  438. {
  439. case 100000:
  440. speed = 0;
  441. break;
  442. case 400000:
  443. speed = 1;
  444. break;
  445. case 900000:
  446. speed = 2;
  447. break;
  448. default:
  449. i2cerr("ERROR: bad I2C freq %u\n", frequency);
  450. return -EINVAL;
  451. }
  452. i2cinfo("Changing I2C freq %u -> %u\n", inst->frequency, frequency);
  453. /* Select DS28E17 */
  454. ret = onewire_reset_select(&inst->slave);
  455. if (ret < 0)
  456. {
  457. i2cerr("ERROR: cannot change I2C freq\n");
  458. return ret;
  459. }
  460. /* Write new speed to device */
  461. buf[0] = DS_WRITE_CONFIGURATION;
  462. buf[1] = speed;
  463. ret = ONEWIRE_WRITE(master->dev, buf, 2);
  464. if (ret < 0)
  465. {
  466. i2cerr("ERROR: cannot change I2C freq\n");
  467. return ret;
  468. }
  469. inst->frequency = frequency;
  470. return ret;
  471. }
  472. /****************************************************************************
  473. * Name: ds_i2c_process
  474. *
  475. * Description:
  476. * Common I2C transfer logic
  477. *
  478. * Initiates a master mode transaction on the I2C bus to transfer the
  479. * provided messages to and from the slave devices.
  480. *
  481. ****************************************************************************/
  482. static int ds_i2c_process(FAR struct i2c_master_s *i2cdev,
  483. FAR struct i2c_msg_s *msgs, int count)
  484. {
  485. FAR struct ds_i2c_inst_s *inst = (FAR struct ds_i2c_inst_s *)i2cdev;
  486. FAR struct onewire_master_s *master = inst->master;
  487. int ret;
  488. int i;
  489. /* Check from first message only, if we want to change I2C frequency. */
  490. if (inst->frequency != msgs[0].frequency)
  491. {
  492. ds_i2c_setfrequency(inst, msgs[0].frequency);
  493. }
  494. /* Select DS28E17 */
  495. i = onewire_reset_select(&inst->slave);
  496. if (i < 0)
  497. {
  498. goto errout;
  499. }
  500. while (i < count)
  501. {
  502. /* First we try to use DS_WRITE_READ_DATA_WITH_STOP to optimize
  503. * the common case of write followed by read to a same address.
  504. */
  505. if (i < count - 1 && msgs[i].addr == msgs[i+1].addr &&
  506. (msgs[i].flags & I2C_M_READ) == 0 &&
  507. (msgs[i+1].flags & I2C_M_READ))
  508. {
  509. /* Write-read combined transfer. */
  510. ret = ds_i2c_write_read(inst, msgs[i].addr,
  511. msgs[i].buffer, msgs[i].length,
  512. msgs[i+1].buffer, msgs[i+1].length);
  513. if (ret < 0)
  514. {
  515. i = ret;
  516. goto errout;
  517. }
  518. /* We processed two messages here. */
  519. i += 2;
  520. }
  521. else if (msgs[i].flags & I2C_M_READ)
  522. {
  523. /* Read transfer. */
  524. ret = ds_i2c_read(inst, msgs[i].addr, msgs[i].buffer, msgs[i].length);
  525. if (ret < 0)
  526. {
  527. i = ret;
  528. goto errout;
  529. }
  530. i++;
  531. }
  532. else
  533. {
  534. /* Write transfer. Stop condition only for last transfer. */
  535. ret = ds_i2c_write(inst, msgs[i].addr, msgs[i].buffer, msgs[i].length,
  536. i == (count-1));
  537. if (ret < 0)
  538. {
  539. i = ret;
  540. goto errout;
  541. }
  542. i++;
  543. }
  544. /* Any more messages to process? */
  545. if (i < count)
  546. {
  547. /* Yes. Resume to same DS28E17. */
  548. /* Oddness: Skip-ROM does not set RS-bit needed by resume. */
  549. if (master->nslaves > 1)
  550. {
  551. ret = onewire_reset_resume(master);
  552. }
  553. else
  554. {
  555. ret = onewire_reset_select(&inst->slave);
  556. }
  557. if (ret < 0)
  558. {
  559. i = ret;
  560. goto errout;
  561. }
  562. }
  563. }
  564. errout:
  565. return i;
  566. }
  567. /****************************************************************************
  568. * Name: ds_i2c_reset
  569. *
  570. * Description:
  571. * Reset an I2C bus
  572. *
  573. ****************************************************************************/
  574. #ifdef CONFIG_I2C_RESET
  575. static int ds_i2c_reset(FAR struct i2c_master_s *i2cdev)
  576. {
  577. FAR struct ds_i2c_inst_s *inst = (FAR struct ds_i2c_inst_s *)i2cdev;
  578. FAR struct onewire_master_s *master = inst->master;
  579. int ret;
  580. ds_i2c_sem_wait(i2cdev);
  581. ret = ONEWIRE_RESET(master->dev);
  582. ds_i2c_sem_post(i2cdev);
  583. return ret;
  584. }
  585. #endif
  586. /****************************************************************************
  587. * Name: ds_i2c_transfer
  588. *
  589. * Description:
  590. * Generic I2C transfer function
  591. *
  592. ****************************************************************************/
  593. static int ds_i2c_transfer(FAR struct i2c_master_s *i2cdev,
  594. FAR struct i2c_msg_s *msgs,
  595. int count)
  596. {
  597. int ret;
  598. ds_i2c_sem_wait(i2cdev);
  599. ret = ds_i2c_process(i2cdev, msgs, count);
  600. ds_i2c_sem_post(i2cdev);
  601. return ret;
  602. }
  603. /****************************************************************************
  604. * Name: ds28e17_selftest
  605. *
  606. * Description:
  607. *
  608. ****************************************************************************/
  609. static int ds28e17_selftest(FAR struct ds_i2c_inst_s *inst)
  610. {
  611. FAR struct onewire_master_s *master = inst->master;
  612. uint8_t txbuf[] = { ONEWIRE_CMD_READ_ROM };
  613. uint8_t rxbuf[8] = { 0 };
  614. uint64_t rom;
  615. uint8_t crc;
  616. int ret;
  617. /* Read ROM-code of single connected slave and
  618. * check its checksum.
  619. */
  620. ret = ONEWIRE_RESET(master->dev);
  621. if (ret < 0)
  622. {
  623. i2cerr("ERROR: ONEWIRE_RESET failed: %d\n", ret);
  624. return ret;
  625. }
  626. ret = ONEWIRE_WRITE(master->dev, txbuf, sizeof(txbuf));
  627. if (ret < 0)
  628. {
  629. i2cerr("ERROR: ONEWIRE_WRITE failed: %d\n", ret);
  630. return ret;
  631. }
  632. ret = ONEWIRE_READ(master->dev, rxbuf, sizeof(rxbuf));
  633. if (ret < 0)
  634. {
  635. i2cerr("ERROR: ONEWIRE_READ failed: %d\n", ret);
  636. return ret;
  637. }
  638. #ifdef CONFIG_DEBUG_I2C_INFO
  639. lib_dumpbuffer("ds28e17_selftest: rxbuf", rxbuf, sizeof(rxbuf));
  640. #endif
  641. memcpy(&rom, rxbuf, 8);
  642. i2cinfo("recv rom: 0x%llx\n", rom);
  643. crc = onewire_crc8(rxbuf, sizeof(rxbuf)-1);
  644. i2cinfo("crc8=%d, recv crc8=%d\n", crc, (int)rxbuf[7]);
  645. if (crc != rxbuf[7])
  646. {
  647. i2cerr("ERROR: crc8 does not match!\n");
  648. ret = -EIO;
  649. }
  650. return ret;
  651. }
  652. /****************************************************************************
  653. * Public Functions
  654. ****************************************************************************/
  655. /****************************************************************************
  656. * Name: ds28e17_search
  657. *
  658. * Description:
  659. * Search all DS28E17 devices from a 1-wire network.
  660. *
  661. * Input Parameters:
  662. * priv - Pointer to the associated DS28E17
  663. * cb_search - Callback to call on each device found
  664. * arg - Argument passed to cb_search
  665. *
  666. * Return Value:
  667. * Number of DS28E17 devices present.
  668. *
  669. ****************************************************************************/
  670. int ds28e17_search(FAR struct ds28e17_dev_s *priv,
  671. void (*cb_search)(int family, uint64_t romcode, void *arg),
  672. void *arg)
  673. {
  674. FAR struct onewire_master_s *master = (FAR struct onewire_master_s *)priv;
  675. int ret;
  676. DEBUGASSERT(master != NULL && cb_search != NULL);
  677. onewire_sem_wait(master);
  678. ret = onewire_search(master, DS_FAMILY, false, cb_search, arg);
  679. onewire_sem_post(master);
  680. return ret;
  681. }
  682. /****************************************************************************
  683. * Name: ds28e17_lower_half
  684. *
  685. * Description:
  686. * Initialize the lower half of the DS28E17 by creating a i2c_master_s
  687. * for the virtual i2c master and link it to the associated DS28E17 and
  688. * its port.
  689. *
  690. * Input Parameters:
  691. * dev - Pointer to the associated DS28E17
  692. * romcode - The unique 64-bit address in 1-wire network.
  693. * Use zero for skip-ROM mode.
  694. *
  695. * Returned Value:
  696. * i2c device instance; NULL on failure.
  697. *
  698. ****************************************************************************/
  699. FAR struct i2c_master_s *
  700. ds28e17_lower_half(FAR struct ds28e17_dev_s *priv, uint64_t romcode)
  701. {
  702. FAR struct ds_i2c_inst_s *inst; /* device, single instance */
  703. FAR struct onewire_master_s *master = (FAR struct onewire_master_s *)priv;
  704. DEBUGASSERT(master != NULL);
  705. /* Allocate instance */
  706. inst = kmm_zalloc(sizeof(struct ds_i2c_inst_s));
  707. if (inst == NULL)
  708. {
  709. i2cerr("ERROR: Failed to allocate instance\n");
  710. return NULL;
  711. }
  712. /* Initialize instance */
  713. inst->ops = &ds_i2c_ops;
  714. inst->master = master;
  715. inst->frequency = 400000; /* power-on frequency */
  716. inst->stretch = DS_DEFAULT_STRETCH;
  717. inst->slave.romcode = romcode;
  718. /* We need a recursive lock as this may be called from a search callback. */
  719. onewire_sem_wait(master);
  720. if (onewire_addslave(master, &inst->slave) < 0)
  721. {
  722. kmm_free(inst);
  723. i2cerr("ERROR: Failed to add slave\n");
  724. onewire_sem_post(master);
  725. return NULL;
  726. }
  727. /* Should default speed be different from DS28E17 power-on frequency? */
  728. if (inst->frequency != DS_DEFAULT_FREQUENCY)
  729. {
  730. ds_i2c_setfrequency(inst, DS_DEFAULT_FREQUENCY);
  731. }
  732. /* TODO: better selftest */
  733. if (master->maxslaves == 1)
  734. {
  735. ds28e17_selftest(inst);
  736. }
  737. onewire_sem_post(master);
  738. return (struct i2c_master_s *)inst;
  739. }
  740. /****************************************************************************
  741. * Name: ds28e17_lower_half_unregister
  742. *
  743. * Description:
  744. * Put back the lower half of the DS28E17.
  745. *
  746. * Input Parameters:
  747. * priv - Pointer to the associated DS28E17
  748. * i2cdev - i2c device instance from ds28e17_lower_half()
  749. *
  750. * Returned Value:
  751. * Zero on success; a negated errno value on failure.
  752. *
  753. ****************************************************************************/
  754. int ds28e17_lower_half_unregister(FAR struct ds28e17_dev_s *priv,
  755. FAR struct i2c_master_s *i2cdev)
  756. {
  757. FAR struct ds_i2c_inst_s *inst = (FAR struct ds_i2c_inst_s *)i2cdev;
  758. FAR struct onewire_master_s *master = inst->master;
  759. int ret;
  760. onewire_sem_wait(master);
  761. ret = onewire_removeslave(master, &inst->slave);
  762. if (ret < 0)
  763. {
  764. kmm_free(inst);
  765. i2cerr("ERROR: Failed to remove slave\n");
  766. onewire_sem_post(master);
  767. return ret;
  768. }
  769. kmm_free(inst);
  770. onewire_sem_post(master);
  771. return OK;
  772. }
  773. /****************************************************************************
  774. * Name: ds28e17_initialize
  775. *
  776. * Description:
  777. * Returns a common DS28E17 device from 1-wire lower half device
  778. *
  779. * Input Parameters:
  780. * dev - The allocated 1-wire lower half
  781. *
  782. ****************************************************************************/
  783. FAR struct ds28e17_dev_s *ds28e17_initialize(FAR struct onewire_dev_s *dev)
  784. {
  785. FAR struct onewire_master_s *priv;
  786. priv = onewire_initialize(dev, DS_DEFAULT_MAXSLAVES);
  787. /* We do not have our own data fields so just cast it. */
  788. return (FAR struct ds28e17_dev_s *)priv;
  789. }