MDC04_ATY.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802
  1. /**
  2. * @file MDC04_ATY.c
  3. *
  4. * @param Project DEVICE_GENERAL_ATY_LIB
  5. *
  6. * @author ATY
  7. *
  8. * @copyright
  9. * - Copyright 2017 - 2026 MZ-ATY
  10. * - This code follows:
  11. * - MZ-ATY Various Contents Joint Statement -
  12. * <a href="https://mengze.top/MZ-ATY_VCJS">
  13. * https://mengze.top/MZ-ATY_VCJS</a>
  14. * - CC 4.0 BY-NC-SA -
  15. * <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
  16. * https://creativecommons.org/licenses/by-nc-sa/4.0/</a>
  17. * - Your use will be deemed to have accepted the terms of this statement.
  18. *
  19. * @brief functions of MDC04 sensor for all embedded device
  20. *
  21. * @version
  22. * - 1_00_250101 > ATY
  23. * -# Initial version, support OneWire and I2C modes
  24. ********************************************************************************
  25. */
  26. #ifndef __MDC04_ATY_C
  27. #define __MDC04_ATY_C
  28. #include "MDC04_ATY.h"
  29. /******************************* For user *************************************/
  30. /******************************************************************************/
  31. /**
  32. * @brief Initialize MDC04 device
  33. *
  34. * @param dev device structure pointer
  35. * @return uint8_t status code
  36. * @note Initialize device and check presence
  37. */
  38. uint8_t MDC04_Init(struct MDC04_ATY_Dev *dev)
  39. {
  40. __ATY_LOCK(dev);
  41. if (dev == NULL) {
  42. __ATY_UNLOCK(dev);
  43. return MDC04_STATUS_ERROR;
  44. }
  45. // Initialize device parameters
  46. dev->devicePresent = 0;
  47. dev->temperature = 0.0f;
  48. dev->rawTemperature = 0;
  49. dev->initialized = 1; // Set initialization flag
  50. dev->conversionTime = 750; // Default conversion time 750ms
  51. // Clear ROM code
  52. for (uint8_t i = 0; i < 8; i++) {
  53. dev->romCode[i] = 0;
  54. }
  55. // Set default I2C address if not set
  56. if (dev->mode == MDC04_MODE_I2C && dev->i2cAddress == 0) {
  57. dev->i2cAddress = MDC04_I2C_ADDR_DEFAULT;
  58. }
  59. // Check device presence
  60. uint8_t status = MDC04_Reset(dev);
  61. if (dev->debugEnable == 1 && dev->LOG != NULL) {
  62. dev->LOG("\r\nMDC04 Init: Mode=%d, Status=%d", dev->mode, status);
  63. }
  64. dev->lastStatus = status;
  65. __ATY_UNLOCK(dev);
  66. return status;
  67. }
  68. /**
  69. * @brief Reset MDC04 device
  70. *
  71. * @param dev device structure pointer
  72. * @return uint8_t status code
  73. * @note Reset device and check presence pulse
  74. */
  75. uint8_t MDC04_Reset(struct MDC04_ATY_Dev *dev)
  76. {
  77. if (dev == NULL) return MDC04_STATUS_ERROR;
  78. if (dev->mode == MDC04_MODE_ONEWIRE) {
  79. // OneWire reset sequence
  80. if (dev->oneWireSetLow == NULL || dev->oneWireSetHigh == NULL ||
  81. dev->oneWireRead == NULL || dev->delayUs == NULL) {
  82. return MDC04_STATUS_ERROR;
  83. }
  84. // Pull line low for reset pulse
  85. dev->oneWireSetLow();
  86. dev->delayUs(MDC04_RESET_PULSE_TIME);
  87. // Release line and wait for presence pulse
  88. dev->oneWireSetHigh();
  89. dev->delayUs(MDC04_PRESENCE_WAIT_TIME);
  90. // Check for presence pulse (line should be low)
  91. uint8_t presence = dev->oneWireRead();
  92. dev->delayUs(MDC04_PRESENCE_PULSE_TIME);
  93. dev->devicePresent = (presence == 0) ? 1 : 0;
  94. if (dev->debugEnable == 1 && dev->LOG != NULL) {
  95. dev->LOG("\r\nMDC04 OneWire Reset: Presence=%d", dev->devicePresent);
  96. }
  97. return dev->devicePresent ? MDC04_STATUS_OK : MDC04_STATUS_NO_DEVICE;
  98. }
  99. else if (dev->mode == MDC04_MODE_I2C) {
  100. // I2C device detection
  101. if (dev->i2cStart == NULL || dev->i2cStop == NULL || dev->i2cWriteByte == NULL) {
  102. return MDC04_STATUS_ERROR;
  103. }
  104. uint8_t status = dev->i2cStart();
  105. if (status != 0) {
  106. dev->i2cStop();
  107. return MDC04_STATUS_ERROR;
  108. }
  109. status = dev->i2cWriteByte(dev->i2cAddress << 1); // Write address
  110. dev->i2cStop();
  111. dev->devicePresent = (status == 0) ? 1 : 0;
  112. if (dev->debugEnable == 1 && dev->LOG != NULL) {
  113. dev->LOG("\r\nMDC04 I2C Reset: Address=0x%02X, Present=%d", dev->i2cAddress, dev->devicePresent);
  114. }
  115. return dev->devicePresent ? MDC04_STATUS_OK : MDC04_STATUS_NO_DEVICE;
  116. }
  117. return MDC04_STATUS_ERROR;
  118. }
  119. /**
  120. * @brief Start temperature conversion
  121. *
  122. * @param dev device structure pointer
  123. * @return uint8_t status code
  124. * @note Start temperature conversion process
  125. */
  126. uint8_t MDC04_StartConversion(struct MDC04_ATY_Dev *dev)
  127. {
  128. if (dev == NULL) {
  129. return MDC04_STATUS_ERROR;
  130. }
  131. // Auto-initialize if not initialized
  132. if (!dev->initialized) {
  133. uint8_t initStatus = MDC04_Init(dev);
  134. if (initStatus != MDC04_STATUS_OK) {
  135. return initStatus;
  136. }
  137. }
  138. if (!dev->devicePresent) {
  139. return MDC04_STATUS_NO_DEVICE;
  140. }
  141. __ATY_LOCK(dev);
  142. if (dev->mode == MDC04_MODE_ONEWIRE) {
  143. // Reset and skip ROM
  144. if (MDC04_Reset(dev) != MDC04_STATUS_OK) {
  145. __ATY_UNLOCK(dev);
  146. return MDC04_STATUS_NO_DEVICE;
  147. }
  148. MDC04_OneWire_WriteByte(dev, MDC04_CMD_SKIP_ROM);
  149. MDC04_OneWire_WriteByte(dev, MDC04_CMD_READ_TEMP);
  150. if (dev->debugEnable == 1 && dev->LOG != NULL) {
  151. dev->LOG("\r\nMDC04 OneWire: Conversion started");
  152. }
  153. }
  154. else if (dev->mode == MDC04_MODE_I2C) {
  155. // I2C start conversion command
  156. uint8_t status = MDC04_I2C_WriteRegister(dev, 0x01, MDC04_CMD_READ_TEMP);
  157. if (status != MDC04_STATUS_OK) {
  158. __ATY_UNLOCK(dev);
  159. return status;
  160. }
  161. if (dev->debugEnable == 1 && dev->LOG != NULL) {
  162. dev->LOG("\r\nMDC04 I2C: Conversion started");
  163. }
  164. }
  165. __ATY_UNLOCK(dev);
  166. return MDC04_STATUS_OK;
  167. }
  168. /**
  169. * @brief Read temperature from MDC04
  170. *
  171. * @param dev device structure pointer
  172. * @return uint8_t status code
  173. * @note Read temperature data and convert to Celsius
  174. */
  175. uint8_t MDC04_ReadTemperature(struct MDC04_ATY_Dev *dev)
  176. {
  177. if (dev == NULL) {
  178. return MDC04_STATUS_ERROR;
  179. }
  180. // Auto-initialize if not initialized
  181. if (!dev->initialized) {
  182. uint8_t initStatus = MDC04_Init(dev);
  183. if (initStatus != MDC04_STATUS_OK) {
  184. return initStatus;
  185. }
  186. }
  187. if (!dev->devicePresent) {
  188. return MDC04_STATUS_NO_DEVICE;
  189. }
  190. __ATY_LOCK(dev);
  191. uint8_t data[9];
  192. uint8_t status = MDC04_STATUS_OK;
  193. if (dev->mode == MDC04_MODE_ONEWIRE) {
  194. // Reset and skip ROM
  195. if (MDC04_Reset(dev) != MDC04_STATUS_OK) {
  196. __ATY_UNLOCK(dev);
  197. return MDC04_STATUS_NO_DEVICE;
  198. }
  199. MDC04_OneWire_WriteByte(dev, MDC04_CMD_SKIP_ROM);
  200. MDC04_OneWire_WriteByte(dev, 0xBE); // Read scratchpad
  201. // Read 9 bytes of data
  202. for (uint8_t i = 0; i < 9; i++) {
  203. data[i] = MDC04_OneWire_ReadByte(dev);
  204. }
  205. // Verify CRC
  206. uint8_t crc = MDC04_OneWire_CRC8(data, 8);
  207. if (crc != data[8]) {
  208. status = MDC04_STATUS_CRC_ERROR;
  209. if (dev->debugEnable == 1 && dev->LOG != NULL) {
  210. dev->LOG("\r\nMDC04 OneWire: CRC Error, calc=0x%02X, recv=0x%02X", crc, data[8]);
  211. }
  212. } else {
  213. // Extract temperature data
  214. dev->rawTemperature = (data[1] << 8) | data[0];
  215. dev->temperature = MDC04_ConvertRawToTemperature(dev->rawTemperature);
  216. if (dev->debugEnable == 1 && dev->LOG != NULL) {
  217. dev->LOG("\r\nMDC04 OneWire: Temp=%.2f°C, Raw=0x%04X", dev->temperature, dev->rawTemperature);
  218. }
  219. }
  220. }
  221. else if (dev->mode == MDC04_MODE_I2C) {
  222. // Read temperature registers
  223. uint8_t tempData[2];
  224. status = MDC04_I2C_ReadMultiple(dev, 0x00, tempData, 2);
  225. if (status == MDC04_STATUS_OK) {
  226. dev->rawTemperature = (tempData[0] << 8) | tempData[1];
  227. dev->temperature = MDC04_ConvertRawToTemperature(dev->rawTemperature);
  228. if (dev->debugEnable == 1 && dev->LOG != NULL) {
  229. dev->LOG("\r\nMDC04 I2C: Temp=%.2f°C, Raw=0x%04X", dev->temperature, dev->rawTemperature);
  230. }
  231. }
  232. }
  233. dev->lastStatus = status;
  234. __ATY_UNLOCK(dev);
  235. return status;
  236. }
  237. /**
  238. * @brief Read ROM code (OneWire mode only)
  239. *
  240. * @param dev device structure pointer
  241. * @return uint8_t status code
  242. * @note Read 64-bit ROM code from device
  243. */
  244. uint8_t MDC04_ReadROM(struct MDC04_ATY_Dev *dev)
  245. {
  246. if (dev == NULL || dev->mode != MDC04_MODE_ONEWIRE) {
  247. return MDC04_STATUS_ERROR;
  248. }
  249. // Auto-initialize if not initialized
  250. if (!dev->initialized) {
  251. uint8_t initStatus = MDC04_Init(dev);
  252. if (initStatus != MDC04_STATUS_OK) {
  253. return initStatus;
  254. }
  255. }
  256. __ATY_LOCK(dev);
  257. // Reset device
  258. if (MDC04_Reset(dev) != MDC04_STATUS_OK) {
  259. __ATY_UNLOCK(dev);
  260. return MDC04_STATUS_NO_DEVICE;
  261. }
  262. // Send Read ROM command
  263. MDC04_OneWire_WriteByte(dev, MDC04_CMD_READ_ROM);
  264. // Read 8 bytes of ROM code
  265. for (uint8_t i = 0; i < 8; i++) {
  266. dev->romCode[i] = MDC04_OneWire_ReadByte(dev);
  267. }
  268. // Verify CRC
  269. uint8_t crc = MDC04_OneWire_CRC8(dev->romCode, 7);
  270. uint8_t status = (crc == dev->romCode[7]) ? MDC04_STATUS_OK : MDC04_STATUS_CRC_ERROR;
  271. if (dev->debugEnable == 1 && dev->LOG != NULL) {
  272. dev->LOG("\r\nMDC04 ROM: %02X%02X%02X%02X%02X%02X%02X%02X, CRC=%s",
  273. dev->romCode[0], dev->romCode[1], dev->romCode[2], dev->romCode[3],
  274. dev->romCode[4], dev->romCode[5], dev->romCode[6], dev->romCode[7],
  275. (status == MDC04_STATUS_OK) ? "OK" : "ERROR");
  276. }
  277. dev->lastStatus = status;
  278. __ATY_UNLOCK(dev);
  279. return status;
  280. }
  281. /**
  282. * @brief OneWire write byte
  283. *
  284. * @param dev device structure pointer
  285. * @param data byte to write
  286. * @return uint8_t status code
  287. */
  288. uint8_t MDC04_OneWire_WriteByte(struct MDC04_ATY_Dev *dev, uint8_t data)
  289. {
  290. if (dev == NULL || dev->mode != MDC04_MODE_ONEWIRE) {
  291. return MDC04_STATUS_ERROR;
  292. }
  293. for (uint8_t i = 0; i < 8; i++) {
  294. MDC04_OneWire_WriteBit(dev, (data >> i) & 0x01);
  295. }
  296. return MDC04_STATUS_OK;
  297. }
  298. /**
  299. * @brief OneWire read byte
  300. *
  301. * @param dev device structure pointer
  302. * @return uint8_t read data
  303. */
  304. uint8_t MDC04_OneWire_ReadByte(struct MDC04_ATY_Dev *dev)
  305. {
  306. if (dev == NULL || dev->mode != MDC04_MODE_ONEWIRE) {
  307. return 0;
  308. }
  309. uint8_t data = 0;
  310. for (uint8_t i = 0; i < 8; i++) {
  311. if (MDC04_OneWire_ReadBit(dev)) {
  312. data |= (1 << i);
  313. }
  314. }
  315. return data;
  316. }
  317. /**
  318. * @brief OneWire write bit
  319. *
  320. * @param dev device structure pointer
  321. * @param bit bit to write (0 or 1)
  322. * @return uint8_t status code
  323. */
  324. uint8_t MDC04_OneWire_WriteBit(struct MDC04_ATY_Dev *dev, uint8_t bit)
  325. {
  326. if (dev == NULL || dev->oneWireSetLow == NULL ||
  327. dev->oneWireSetHigh == NULL || dev->delayUs == NULL) {
  328. return MDC04_STATUS_ERROR;
  329. }
  330. if (bit) {
  331. // Write 1: short low pulse
  332. dev->oneWireSetLow();
  333. dev->delayUs(MDC04_WRITE_1_LOW_TIME);
  334. dev->oneWireSetHigh();
  335. dev->delayUs(MDC04_SLOT_TIME - MDC04_WRITE_1_LOW_TIME);
  336. } else {
  337. // Write 0: long low pulse
  338. dev->oneWireSetLow();
  339. dev->delayUs(MDC04_WRITE_0_LOW_TIME);
  340. dev->oneWireSetHigh();
  341. dev->delayUs(MDC04_SLOT_TIME - MDC04_WRITE_0_LOW_TIME);
  342. }
  343. return MDC04_STATUS_OK;
  344. }
  345. /**
  346. * @brief OneWire read bit
  347. *
  348. * @param dev device structure pointer
  349. * @return uint8_t read bit (0 or 1)
  350. */
  351. uint8_t MDC04_OneWire_ReadBit(struct MDC04_ATY_Dev *dev)
  352. {
  353. if (dev == NULL || dev->oneWireSetLow == NULL ||
  354. dev->oneWireSetHigh == NULL || dev->oneWireRead == NULL || dev->delayUs == NULL) {
  355. return 0;
  356. }
  357. uint8_t bit;
  358. // Initiate read slot
  359. dev->oneWireSetLow();
  360. dev->delayUs(MDC04_READ_LOW_TIME);
  361. dev->oneWireSetHigh();
  362. dev->delayUs(MDC04_READ_SAMPLE_TIME);
  363. // Sample the line
  364. bit = dev->oneWireRead();
  365. dev->delayUs(MDC04_SLOT_TIME - MDC04_READ_LOW_TIME - MDC04_READ_SAMPLE_TIME);
  366. return bit;
  367. }
  368. /**
  369. * @brief Calculate CRC8 for OneWire
  370. *
  371. * @param data data array
  372. * @param len data length
  373. * @return uint8_t CRC8 value
  374. */
  375. uint8_t MDC04_OneWire_CRC8(uint8_t *data, uint8_t len)
  376. {
  377. uint8_t crc = 0;
  378. for (uint8_t i = 0; i < len; i++) {
  379. uint8_t inbyte = data[i];
  380. for (uint8_t j = 0; j < 8; j++) {
  381. uint8_t mix = (crc ^ inbyte) & 0x01;
  382. crc >>= 1;
  383. if (mix) crc ^= 0x8C;
  384. inbyte >>= 1;
  385. }
  386. }
  387. return crc;
  388. }
  389. /**
  390. * @brief I2C write register
  391. *
  392. * @param dev device structure pointer
  393. * @param reg register address
  394. * @param data data to write
  395. * @return uint8_t status code
  396. */
  397. uint8_t MDC04_I2C_WriteRegister(struct MDC04_ATY_Dev *dev, uint8_t reg, uint8_t data)
  398. {
  399. if (dev == NULL || dev->mode != MDC04_MODE_I2C) {
  400. return MDC04_STATUS_ERROR;
  401. }
  402. if (dev->i2cStart == NULL || dev->i2cStop == NULL || dev->i2cWriteByte == NULL) {
  403. return MDC04_STATUS_ERROR;
  404. }
  405. uint8_t status;
  406. // Start condition
  407. status = dev->i2cStart();
  408. if (status != 0) {
  409. dev->i2cStop();
  410. return MDC04_STATUS_ERROR;
  411. }
  412. // Write device address
  413. status = dev->i2cWriteByte(dev->i2cAddress << 1);
  414. if (status != 0) {
  415. dev->i2cStop();
  416. return MDC04_STATUS_ERROR;
  417. }
  418. // Write register address
  419. status = dev->i2cWriteByte(reg);
  420. if (status != 0) {
  421. dev->i2cStop();
  422. return MDC04_STATUS_ERROR;
  423. }
  424. // Write data
  425. status = dev->i2cWriteByte(data);
  426. if (status != 0) {
  427. dev->i2cStop();
  428. return MDC04_STATUS_ERROR;
  429. }
  430. // Stop condition
  431. dev->i2cStop();
  432. return MDC04_STATUS_OK;
  433. }
  434. /**
  435. * @brief I2C read register
  436. *
  437. * @param dev device structure pointer
  438. * @param reg register address
  439. * @param data pointer to store read data
  440. * @return uint8_t status code
  441. */
  442. uint8_t MDC04_I2C_ReadRegister(struct MDC04_ATY_Dev *dev, uint8_t reg, uint8_t *data)
  443. {
  444. if (dev == NULL || dev->mode != MDC04_MODE_I2C || data == NULL) {
  445. return MDC04_STATUS_ERROR;
  446. }
  447. if (dev->i2cStart == NULL || dev->i2cStop == NULL ||
  448. dev->i2cWriteByte == NULL || dev->i2cReadByte == NULL) {
  449. return MDC04_STATUS_ERROR;
  450. }
  451. uint8_t status;
  452. // Write register address
  453. status = dev->i2cStart();
  454. if (status != 0) {
  455. dev->i2cStop();
  456. return MDC04_STATUS_ERROR;
  457. }
  458. status = dev->i2cWriteByte(dev->i2cAddress << 1);
  459. if (status != 0) {
  460. dev->i2cStop();
  461. return MDC04_STATUS_ERROR;
  462. }
  463. status = dev->i2cWriteByte(reg);
  464. if (status != 0) {
  465. dev->i2cStop();
  466. return MDC04_STATUS_ERROR;
  467. }
  468. // Restart and read data
  469. status = dev->i2cStart();
  470. if (status != 0) {
  471. dev->i2cStop();
  472. return MDC04_STATUS_ERROR;
  473. }
  474. status = dev->i2cWriteByte((dev->i2cAddress << 1) | 0x01);
  475. if (status != 0) {
  476. dev->i2cStop();
  477. return MDC04_STATUS_ERROR;
  478. }
  479. *data = dev->i2cReadByte(0); // NACK for single byte read
  480. dev->i2cStop();
  481. return MDC04_STATUS_OK;
  482. }
  483. /**
  484. * @brief I2C read multiple registers
  485. *
  486. * @param dev device structure pointer
  487. * @param reg starting register address
  488. * @param data pointer to store read data
  489. * @param len number of bytes to read
  490. * @return uint8_t status code
  491. */
  492. uint8_t MDC04_I2C_ReadMultiple(struct MDC04_ATY_Dev *dev, uint8_t reg, uint8_t *data, uint8_t len)
  493. {
  494. if (dev == NULL || dev->mode != MDC04_MODE_I2C || data == NULL || len == 0) {
  495. return MDC04_STATUS_ERROR;
  496. }
  497. if (dev->i2cStart == NULL || dev->i2cStop == NULL ||
  498. dev->i2cWriteByte == NULL || dev->i2cReadByte == NULL) {
  499. return MDC04_STATUS_ERROR;
  500. }
  501. uint8_t status;
  502. // Write register address
  503. status = dev->i2cStart();
  504. if (status != 0) {
  505. dev->i2cStop();
  506. return MDC04_STATUS_ERROR;
  507. }
  508. status = dev->i2cWriteByte(dev->i2cAddress << 1);
  509. if (status != 0) {
  510. dev->i2cStop();
  511. return MDC04_STATUS_ERROR;
  512. }
  513. status = dev->i2cWriteByte(reg);
  514. if (status != 0) {
  515. dev->i2cStop();
  516. return MDC04_STATUS_ERROR;
  517. }
  518. // Restart and read data
  519. status = dev->i2cStart();
  520. if (status != 0) {
  521. dev->i2cStop();
  522. return MDC04_STATUS_ERROR;
  523. }
  524. status = dev->i2cWriteByte((dev->i2cAddress << 1) | 0x01);
  525. if (status != 0) {
  526. dev->i2cStop();
  527. return MDC04_STATUS_ERROR;
  528. }
  529. // Read multiple bytes
  530. for (uint8_t i = 0; i < len; i++) {
  531. data[i] = dev->i2cReadByte((i == len - 1) ? 0 : 1); // NACK on last byte
  532. }
  533. dev->i2cStop();
  534. return MDC04_STATUS_OK;
  535. }
  536. /**
  537. * @brief Convert raw temperature to Celsius
  538. *
  539. * @param rawTemp raw temperature value
  540. * @return float temperature in Celsius
  541. */
  542. float MDC04_ConvertRawToTemperature(uint16_t rawTemp)
  543. {
  544. // Convert based on MDC04 specification
  545. // Assuming 12-bit resolution: 0.0625°C per LSB
  546. int16_t signedTemp = (int16_t)rawTemp;
  547. return (float)signedTemp * 0.0625f;
  548. }
  549. /**
  550. * @brief Get device status
  551. *
  552. * @param dev device structure pointer
  553. * @return uint8_t current device status
  554. */
  555. uint8_t MDC04_GetDeviceStatus(struct MDC04_ATY_Dev *dev)
  556. {
  557. if (dev == NULL) {
  558. return MDC04_STATUS_ERROR;
  559. }
  560. return dev->lastStatus;
  561. }
  562. /**
  563. * @brief Set I2C device address
  564. *
  565. * @param dev device structure pointer
  566. * @param address new I2C address
  567. */
  568. void MDC04_SetI2CAddress(struct MDC04_ATY_Dev *dev, uint8_t address)
  569. {
  570. if (dev != NULL && dev->mode == MDC04_MODE_I2C) {
  571. dev->i2cAddress = address;
  572. }
  573. }
  574. /**
  575. * @brief Search for devices on OneWire bus
  576. *
  577. * @param dev device structure pointer
  578. * @param deviceCount pointer to store device count
  579. * @return uint8_t status code
  580. * @note Basic implementation for single device detection
  581. */
  582. uint8_t MDC04_SearchDevices(struct MDC04_ATY_Dev *dev, uint8_t *deviceCount)
  583. {
  584. if (dev == NULL || dev->mode != MDC04_MODE_ONEWIRE || deviceCount == NULL) {
  585. return MDC04_STATUS_ERROR;
  586. }
  587. *deviceCount = 0;
  588. // Simple presence check
  589. if (MDC04_Reset(dev) == MDC04_STATUS_OK) {
  590. *deviceCount = 1;
  591. return MDC04_STATUS_OK;
  592. }
  593. return MDC04_STATUS_NO_DEVICE;
  594. }
  595. #endif /* __MDC04_ATY_C */
  596. /************************************ etc *************************************/
  597. /* OneWire Mode Usage Example */
  598. /*
  599. // GPIO control functions (platform specific)
  600. void MDC04_OneWire_SetHigh(void) {
  601. // Set GPIO pin high (open-drain or push-pull with external pull-up)
  602. GPIO_SET_H(MDC04_GPIO_Port, MDC04_Pin);
  603. }
  604. void MDC04_OneWire_SetLow(void) {
  605. // Set GPIO pin low
  606. GPIO_SET_L(MDC04_GPIO_Port, MDC04_Pin);
  607. }
  608. uint8_t MDC04_OneWire_Read(void) {
  609. // Read GPIO pin state
  610. return GPIO_READ(MDC04_GPIO_Port, MDC04_Pin);
  611. }
  612. void MDC04_DelayUs(uint32_t us) {
  613. // Microsecond delay implementation
  614. // Use timer or DWT for accurate timing
  615. }
  616. // struct MDC04_ATY_Dev mdc04_dev = {
  617. // .mode = MDC04_MODE_ONEWIRE,
  618. // .initialized = 0, // Initialize as not initialized
  619. // .oneWireSetHigh = MDC04_OneWire_SetHigh,
  620. // .oneWireSetLow = MDC04_OneWire_SetLow,
  621. // .oneWireRead = MDC04_OneWire_Read,
  622. // .delayUs = MDC04_DelayUs,
  623. // .lock = _ATY_UNLOCKED,
  624. // .debugEnable = 1,
  625. // .LOG = printf
  626. // };
  627. // Usage
  628. // No need to call MDC04_Init() manually - it will be called automatically
  629. // MDC04_StartConversion(&mdc04_dev); // Auto-init will be called here
  630. // // Wait for conversion (750ms typical)
  631. // delay_ms(750);
  632. // MDC04_ReadTemperature(&mdc04_dev); // Or auto-init will be called here
  633. // printf("Temperature: %.2f°C\n", mdc04_dev.temperature);
  634. */
  635. /* I2C Mode Usage Example */
  636. /*
  637. // I2C control functions (platform specific)
  638. uint8_t MDC04_I2C_Start(void) {
  639. // Generate I2C start condition
  640. return I2C_Start();
  641. }
  642. uint8_t MDC04_I2C_Stop(void) {
  643. // Generate I2C stop condition
  644. return I2C_Stop();
  645. }
  646. uint8_t MDC04_I2C_WriteByte(uint8_t data) {
  647. // Write byte and return ACK status (0=ACK, 1=NACK)
  648. return I2C_WriteByte(data);
  649. }
  650. uint8_t MDC04_I2C_ReadByte(uint8_t ack) {
  651. // Read byte and send ACK/NACK
  652. return I2C_ReadByte(ack);
  653. }
  654. // struct MDC04_ATY_Dev mdc04_i2c_dev = {
  655. // .mode = MDC04_MODE_I2C,
  656. // .initialized = 0, // Initialize as not initialized
  657. // .i2cStart = MDC04_I2C_Start,
  658. // .i2cStop = MDC04_I2C_Stop,
  659. // .i2cWriteByte = MDC04_I2C_WriteByte,
  660. // .i2cReadByte = MDC04_I2C_ReadByte,
  661. // .i2cAddress = MDC04_I2C_ADDR_DEFAULT,
  662. // .lock = _ATY_UNLOCKED,
  663. // .debugEnable = 1,
  664. // .LOG = printf
  665. // };
  666. // Usage
  667. // No need to call MDC04_Init() manually - it will be called automatically
  668. // MDC04_StartConversion(&mdc04_i2c_dev); // Auto-init will be called here
  669. // // Wait for conversion
  670. // delay_ms(750);
  671. // MDC04_ReadTemperature(&mdc04_i2c_dev); // Or auto-init will be called here
  672. // printf("Temperature: %.2f°C\n", mdc04_i2c_dev.temperature);
  673. */
  674. /******************************************************************************/
  675. /******************************** End Of File *********************************/