ds28e17.c 25 KB

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