onewire.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /*
  2. ChibiOS/RT - Copyright (C) 2014 Uladzimir Pylinsky aka barthess
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. #include <string.h>
  14. #include "hal.h"
  15. #include "onewire.h"
  16. /*
  17. * Forward declarations
  18. */
  19. #if ONEWIRE_USE_STRONG_PULLUP
  20. static void strong_pullup_assert(void);
  21. static void strong_pullup_release(void);
  22. #endif
  23. /*
  24. * VARIABLES
  25. */
  26. static uint8_t testbuf[12];
  27. /*
  28. ******************************************************************************
  29. ******************************************************************************
  30. * LOCAL FUNCTIONS
  31. ******************************************************************************
  32. ******************************************************************************
  33. */
  34. #if ONEWIRE_USE_STRONG_PULLUP
  35. /**
  36. *
  37. */
  38. static void strong_pullup_assert(void) {
  39. palSetPadMode(ONEWIRE_PORT, ONEWIRE_PIN, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
  40. }
  41. /**
  42. *
  43. */
  44. static void strong_pullup_release(void) {
  45. palSetPadMode(ONEWIRE_PORT, ONEWIRE_PIN, PAL_MODE_STM32_ALTERNATE_OPENDRAIN);
  46. }
  47. #endif /* ONEWIRE_USE_STRONG_PULLUP */
  48. /*
  49. *
  50. */
  51. void onewireMeasure(onewired_t * ow) {
  52. int16_t tmp;
  53. uint8_t rombuf[24];
  54. bool presence;
  55. onewireObjectInit(&OWD1);
  56. onewireStart(&OWD1, ow->ow_cfg);
  57. #if ONEWIRE_SYNTH_SEARCH_TEST
  58. synthSearchRomTest(&OWD1);
  59. #endif
  60. ow->temperature = -666000;
  61. if (true == onewireReset(&OWD1)){
  62. memset(rombuf, 0x55, sizeof(rombuf));
  63. ow->dev_on_bus = onewireSearchRom(&OWD1, rombuf, 3);
  64. if (ow->dev_on_bus == 0) {
  65. ow->err_code = onewire_No_Dev;
  66. return;
  67. }
  68. if (1 == ow->dev_on_bus){
  69. /* test read rom command */
  70. presence = onewireReset(&OWD1);
  71. if (true != presence) {
  72. ow->err_code = onewire_Dev_Lost;
  73. return;
  74. }
  75. testbuf[0] = ONEWIRE_CMD_READ_ROM;
  76. onewireWrite(&OWD1, testbuf, 1, 0);
  77. onewireRead(&OWD1, testbuf, 8);
  78. if (testbuf[7] != onewireCRC(testbuf, 7)) {
  79. ow->err_code = onewire_CRC_Err;
  80. return;
  81. }
  82. if (0 != memcmp(rombuf, testbuf, 8)) {
  83. ow->err_code = onewire_MemCmp_Err;
  84. return;
  85. }
  86. }
  87. /* start temperature measurement on all connected devices at once */
  88. presence = onewireReset(&OWD1);
  89. if (true != presence) {
  90. ow->err_code = onewire_Dev_Lost;
  91. return;
  92. }
  93. testbuf[0] = ONEWIRE_CMD_SKIP_ROM;
  94. testbuf[1] = ONEWIRE_CMD_CONVERT_TEMP;
  95. #if ONEWIRE_USE_STRONG_PULLUP
  96. onewireWrite(&OWD1, testbuf, 2, TIME_MS2I(750));
  97. #else
  98. onewireWrite(&OWD1, testbuf, 2, 0);
  99. /* poll bus waiting ready signal from all connected devices */
  100. testbuf[0] = 0;
  101. while (testbuf[0] == 0){
  102. osalThreadSleepMilliseconds(50);
  103. onewireRead(&OWD1, testbuf, 1);
  104. }
  105. #endif
  106. /* read temperature device by device from their scratchpads */
  107. presence = onewireReset(&OWD1);
  108. if (true != presence) {
  109. ow->err_code = onewire_Dev_Lost;
  110. return;
  111. }
  112. testbuf[0] = ONEWIRE_CMD_MATCH_ROM;
  113. memcpy(&testbuf[1], &rombuf[8], 8);
  114. testbuf[9] = ONEWIRE_CMD_READ_SCRATCHPAD;
  115. onewireWrite(&OWD1, testbuf, 10, 0);
  116. onewireRead(&OWD1, testbuf, 9);
  117. if (testbuf[8] != onewireCRC(testbuf, 8)) {
  118. ow->err_code = onewire_CRC_Err;
  119. return;
  120. }
  121. memcpy(&tmp, &testbuf, 2);
  122. ow->temperature = ((int32_t)tmp * 625) / 10;
  123. }
  124. else {
  125. ow->dev_on_bus = 0;
  126. }
  127. osalThreadSleep(1); /* enforce ChibiOS's stack overflow check */
  128. onewireStop(&OWD1);
  129. }
  130. onewire_error_t onewireGetErrorCode(onewired_t * ow) {
  131. return ow->err_code;
  132. }
  133. uint8_t onewireGetDevicesNum(onewired_t * ow) {
  134. return (uint8_t)ow->dev_on_bus;
  135. }
  136. int32_t onewireGetTemperature(onewired_t * ow) {
  137. if (ow->err_code == onewire_OK) {
  138. return ow->temperature;
  139. } else {
  140. return -333000;
  141. }
  142. }