onewire.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  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 "boarddef.h"
  16. #include "onewire.h"
  17. /*
  18. ******************************************************************************
  19. * DEFINES
  20. ******************************************************************************
  21. */
  22. /*
  23. ******************************************************************************
  24. * EXTERNS
  25. ******************************************************************************
  26. */
  27. /*
  28. ******************************************************************************
  29. * PROTOTYPES
  30. ******************************************************************************
  31. */
  32. /*
  33. * Forward declarations
  34. */
  35. #if ONEWIRE_USE_STRONG_PULLUP
  36. static void strong_pullup_assert(void);
  37. static void strong_pullup_release(void);
  38. #endif
  39. /*
  40. ******************************************************************************
  41. * GLOBAL VARIABLES
  42. ******************************************************************************
  43. */
  44. static uint8_t testbuf[12];
  45. /* stores 3 temperature values in millicelsius */
  46. static int32_t temperature[3];
  47. static size_t devices_on_bus = 0;
  48. static onewire_error_t error_code;
  49. /*
  50. * Config for underlying PWM driver.
  51. * Note! It is NOT constant because 1-wire driver needs to change them
  52. * during functioning.
  53. */
  54. static PWMConfig pwm_cfg = {
  55. 0,
  56. 0,
  57. NULL,
  58. {
  59. {PWM_OUTPUT_DISABLED, NULL},
  60. {PWM_OUTPUT_DISABLED, NULL},
  61. {PWM_OUTPUT_DISABLED, NULL},
  62. {PWM_OUTPUT_DISABLED, NULL}
  63. },
  64. 0,
  65. #if STM32_PWM_USE_ADVANCED
  66. 0,
  67. #endif
  68. 0,
  69. 0
  70. };
  71. /*
  72. *
  73. */
  74. static const onewireConfig ow_cfg = {
  75. &PWMD3,
  76. &pwm_cfg,
  77. PWM_OUTPUT_ACTIVE_LOW,
  78. ONEWIRE_MASTER_CHANNEL,
  79. ONEWIRE_SAMPLE_CHANNEL,
  80. ONEWIRE_PORT,
  81. ONEWIRE_PIN,
  82. #if defined(STM32F1XX)
  83. ONEWIRE_PAD_MODE_IDLE,
  84. #endif
  85. ONEWIRE_PAD_MODE_ACTIVE,
  86. #if ONEWIRE_USE_STRONG_PULLUP
  87. strong_pullup_assert,
  88. strong_pullup_release
  89. #endif
  90. };
  91. /*
  92. ******************************************************************************
  93. ******************************************************************************
  94. * LOCAL FUNCTIONS
  95. ******************************************************************************
  96. ******************************************************************************
  97. */
  98. #if ONEWIRE_USE_STRONG_PULLUP
  99. /**
  100. *
  101. */
  102. static void strong_pullup_assert(void) {
  103. palSetPadMode(ONEWIRE_PORT, ONEWIRE_PIN, PAL_MODE_STM32_ALTERNATE_PUSHPULL);
  104. }
  105. /**
  106. *
  107. */
  108. static void strong_pullup_release(void) {
  109. palSetPadMode(ONEWIRE_PORT, ONEWIRE_PIN, PAL_MODE_STM32_ALTERNATE_OPENDRAIN);
  110. }
  111. #endif /* ONEWIRE_USE_STRONG_PULLUP */
  112. /*
  113. ******************************************************************************
  114. * EXPORTED FUNCTIONS
  115. ******************************************************************************
  116. */
  117. /*
  118. *
  119. */
  120. void onewireMeasure(void) {
  121. error_code = onewire_OK;
  122. int16_t tmp;
  123. uint8_t rombuf[24];
  124. size_t i = 0;
  125. bool presence;
  126. onewireObjectInit(&OWD1);
  127. onewireStart(&OWD1, &ow_cfg);
  128. #if ONEWIRE_SYNTH_SEARCH_TEST
  129. synthSearchRomTest(&OWD1);
  130. #endif
  131. for (i=0; i<3; i++)
  132. temperature[i] = -666;
  133. if (true == onewireReset(&OWD1)){
  134. memset(rombuf, 0x55, sizeof(rombuf));
  135. devices_on_bus = onewireSearchRom(&OWD1, rombuf, 3);
  136. if (devices_on_bus == 0) {
  137. error_code = onewire_No_Dev;
  138. return;
  139. }
  140. if (1 == devices_on_bus){
  141. /* test read rom command */
  142. presence = onewireReset(&OWD1);
  143. if (true != presence) {
  144. error_code = onewire_Dev_Lost;
  145. return;
  146. }
  147. testbuf[0] = ONEWIRE_CMD_READ_ROM;
  148. onewireWrite(&OWD1, testbuf, 1, 0);
  149. onewireRead(&OWD1, testbuf, 8);
  150. if (testbuf[7] != onewireCRC(testbuf, 7)) {
  151. error_code = onewire_CRC_Err;
  152. return;
  153. }
  154. if (0 != memcmp(rombuf, testbuf, 8)) {
  155. error_code = onewire_MemCmp_Err;
  156. return;
  157. }
  158. }
  159. /* start temperature measurement on all connected devices at once */
  160. presence = onewireReset(&OWD1);
  161. if (true != presence) {
  162. error_code = onewire_Dev_Lost;
  163. return;
  164. }
  165. testbuf[0] = ONEWIRE_CMD_SKIP_ROM;
  166. testbuf[1] = ONEWIRE_CMD_CONVERT_TEMP;
  167. #if ONEWIRE_USE_STRONG_PULLUP
  168. onewireWrite(&OWD1, testbuf, 2, TIME_MS2I(750));
  169. #else
  170. onewireWrite(&OWD1, testbuf, 2, 0);
  171. /* poll bus waiting ready signal from all connected devices */
  172. testbuf[0] = 0;
  173. while (testbuf[0] == 0){
  174. osalThreadSleepMilliseconds(50);
  175. onewireRead(&OWD1, testbuf, 1);
  176. }
  177. #endif
  178. for (i=0; i<devices_on_bus; i++) {
  179. /* read temperature device by device from their scratchpads */
  180. presence = onewireReset(&OWD1);
  181. if (true != presence) {
  182. error_code = onewire_Dev_Lost;
  183. return;
  184. }
  185. testbuf[0] = ONEWIRE_CMD_MATCH_ROM;
  186. memcpy(&testbuf[1], &rombuf[i*8], 8);
  187. testbuf[9] = ONEWIRE_CMD_READ_SCRATCHPAD;
  188. onewireWrite(&OWD1, testbuf, 10, 0);
  189. onewireRead(&OWD1, testbuf, 9);
  190. if (testbuf[8] != onewireCRC(testbuf, 8)) {
  191. error_code = onewire_CRC_Err;
  192. return;
  193. }
  194. memcpy(&tmp, &testbuf, 2);
  195. temperature[i] = ((int32_t)tmp * 625) / 10;
  196. }
  197. }
  198. else {
  199. devices_on_bus = 0;
  200. }
  201. osalThreadSleep(1); /* enforce ChibiOS's stack overflow check */
  202. onewireStop(&OWD1);
  203. }
  204. onewire_error_t onewireGetErrorCode(void) {
  205. return error_code;
  206. }
  207. uint8_t onewireGetDevicesNum(void) {
  208. return (uint8_t)devices_on_bus;
  209. }
  210. int32_t onewireGetTemperature(const size_t num) {
  211. if ((num+1) > devices_on_bus || (num+1) < devices_on_bus) {
  212. return -999;
  213. } else {
  214. return temperature[num];
  215. }
  216. }