Smart-Home am Beispiel der Präsenzerkennung im Raum Projektarbeit Lennart Heimbs, Johannes Krug, Sebastian Dohle und Kevin Holzschuh bei Prof. Oliver Hofmann SS2019
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

MyHwSTM32F1.cpp 5.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. /*
  2. * The MySensors Arduino library handles the wireless radio link and protocol
  3. * between your home built sensors/actuators and HA controller of choice.
  4. * The sensors forms a self healing radio network with optional repeaters. Each
  5. * repeater and gateway builds a routing tables in EEPROM which keeps track of the
  6. * network topology allowing messages to be routed to nodes.
  7. *
  8. * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
  9. * Copyright (C) 2013-2018 Sensnology AB
  10. * Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
  11. *
  12. * Documentation: http://www.mysensors.org
  13. * Support Forum: http://forum.mysensors.org
  14. *
  15. * This program is free software; you can redistribute it and/or
  16. * modify it under the terms of the GNU General Public License
  17. * version 2 as published by the Free Software Foundation.
  18. */
  19. #include "MyHwSTM32F1.h"
  20. /*
  21. * Pinout STM32F103C8 dev board:
  22. * http://wiki.stm32duino.com/images/a/ae/Bluepillpinout.gif
  23. *
  24. * Wiring RFM69 radio / SPI1
  25. * --------------------------------------------------
  26. * CLK PA5
  27. * MISO PA6
  28. * MOSI PA7
  29. * CSN PA4
  30. * CE NA
  31. * IRQ PA3 (default)
  32. *
  33. * Wiring RF24 radio / SPI1
  34. * --------------------------------------------------
  35. * CLK PA5
  36. * MISO PA6
  37. * MOSI PA7
  38. * CSN PA4
  39. * CE PB0 (default)
  40. * IRQ NA
  41. *
  42. */
  43. bool hwInit(void)
  44. {
  45. #if !defined(MY_DISABLED_SERIAL)
  46. MY_SERIALDEVICE.begin(MY_BAUD_RATE);
  47. #if defined(MY_GATEWAY_SERIAL)
  48. while (!MY_SERIALDEVICE) {}
  49. #endif
  50. #endif
  51. if (EEPROM.init() == EEPROM_OK) {
  52. uint16 cnt;
  53. EEPROM.count(&cnt);
  54. if(cnt>=EEPROM.maxcount()) {
  55. // tmp, WIP: format eeprom if full
  56. EEPROM.format();
  57. }
  58. return true;
  59. }
  60. return false;
  61. }
  62. void hwReadConfigBlock(void *buf, void *addr, size_t length)
  63. {
  64. uint8_t *dst = static_cast<uint8_t *>(buf);
  65. int pos = reinterpret_cast<int>(addr);
  66. while (length-- > 0) {
  67. *dst++ = EEPROM.read(pos++);
  68. }
  69. }
  70. void hwWriteConfigBlock(void *buf, void *addr, size_t length)
  71. {
  72. uint8_t *src = static_cast<uint8_t *>(buf);
  73. int pos = reinterpret_cast<int>(addr);
  74. while (length-- > 0) {
  75. EEPROM.write(pos++, *src++);
  76. }
  77. }
  78. uint8_t hwReadConfig(const int addr)
  79. {
  80. uint8_t value;
  81. hwReadConfigBlock(&value, reinterpret_cast<void *>(addr), 1);
  82. return value;
  83. }
  84. void hwWriteConfig(const int addr, uint8_t value)
  85. {
  86. hwWriteConfigBlock(&value, reinterpret_cast<void *>(addr), 1);
  87. }
  88. int8_t hwSleep(uint32_t ms)
  89. {
  90. // TODO: Not supported!
  91. (void)ms;
  92. return MY_SLEEP_NOT_POSSIBLE;
  93. }
  94. int8_t hwSleep(uint8_t interrupt, uint8_t mode, uint32_t ms)
  95. {
  96. // TODO: Not supported!
  97. (void)interrupt;
  98. (void)mode;
  99. (void)ms;
  100. return MY_SLEEP_NOT_POSSIBLE;
  101. }
  102. int8_t hwSleep(uint8_t interrupt1, uint8_t mode1, uint8_t interrupt2, uint8_t mode2,
  103. uint32_t ms)
  104. {
  105. // TODO: Not supported!
  106. (void)interrupt1;
  107. (void)mode1;
  108. (void)interrupt2;
  109. (void)mode2;
  110. (void)ms;
  111. return MY_SLEEP_NOT_POSSIBLE;
  112. }
  113. void hwRandomNumberInit(void)
  114. {
  115. // use internal temperature sensor as noise source
  116. adc_reg_map *regs = ADC1->regs;
  117. regs->CR2 |= ADC_CR2_TSVREFE;
  118. regs->SMPR1 |= ADC_SMPR1_SMP16;
  119. uint32_t seed = 0;
  120. uint16_t currentValue = 0;
  121. uint16_t newValue = 0;
  122. for (uint8_t i = 0; i < 32; i++) {
  123. const uint32_t timeout = hwMillis() + 20;
  124. while (timeout >= hwMillis()) {
  125. newValue = adc_read(ADC1, 16);
  126. if (newValue != currentValue) {
  127. currentValue = newValue;
  128. break;
  129. }
  130. }
  131. seed ^= ( (newValue + hwMillis()) & 7) << i;
  132. }
  133. randomSeed(seed);
  134. regs->CR2 &= ~ADC_CR2_TSVREFE; // disable VREFINT and temp sensor
  135. }
  136. bool hwUniqueID(unique_id_t *uniqueID)
  137. {
  138. (void)memcpy((uint8_t *)uniqueID, (uint32_t *)0x1FFFF7E0, 16); // FlashID + ChipID
  139. return true;
  140. }
  141. uint16_t hwCPUVoltage(void)
  142. {
  143. adc_reg_map *regs = ADC1->regs;
  144. regs->CR2 |= ADC_CR2_TSVREFE; // enable VREFINT and temp sensor
  145. regs->SMPR1 = ADC_SMPR1_SMP17; // sample rate for VREFINT ADC channel
  146. adc_calibrate(ADC1);
  147. const uint16_t vdd = adc_read(ADC1, 17);
  148. regs->CR2 &= ~ADC_CR2_TSVREFE; // disable VREFINT and temp sensor
  149. return 1200 * 4096 / vdd;
  150. }
  151. uint16_t hwCPUFrequency(void)
  152. {
  153. return F_CPU/100000UL;
  154. }
  155. int8_t hwCPUTemperature(void)
  156. {
  157. adc_reg_map *regs = ADC1->regs;
  158. regs->CR2 |= ADC_CR2_TSVREFE; // enable VREFINT and Temperature sensor
  159. regs->SMPR1 |= ADC_SMPR1_SMP16 | ADC_SMPR1_SMP17;
  160. adc_calibrate(ADC1);
  161. //const uint16_t adc_temp = adc_read(ADC1, 16);
  162. //const uint16_t vref = 1200 * 4096 / adc_read(ADC1, 17);
  163. // calibrated at 25°C, ADC output = 1430mV, avg slope = 4.3mV / °C, increasing temp ~ lower voltage
  164. const int8_t temp = static_cast<int8_t>((1430.0 - (adc_read(ADC1, 16) * 1200 / adc_read(ADC1,
  165. 17))) / 4.3 + 25.0);
  166. regs->CR2 &= ~ADC_CR2_TSVREFE; // disable VREFINT and temp sensor
  167. return (temp - MY_STM32F1_TEMPERATURE_OFFSET) / MY_STM32F1_TEMPERATURE_GAIN;
  168. }
  169. uint16_t hwFreeMem(void)
  170. {
  171. //Not yet implemented
  172. return FUNCTION_NOT_SUPPORTED;
  173. }
  174. void hwDebugPrint(const char *fmt, ...)
  175. {
  176. #ifndef MY_DISABLED_SERIAL
  177. char fmtBuffer[MY_SERIAL_OUTPUT_SIZE];
  178. #ifdef MY_GATEWAY_SERIAL
  179. // prepend debug message to be handled correctly by controller (C_INTERNAL, I_LOG_MESSAGE)
  180. snprintf_P(fmtBuffer, sizeof(fmtBuffer), PSTR("0;255;%" PRIu8 ";0;%" PRIu8 ";%" PRIu32 " "),
  181. C_INTERNAL, I_LOG_MESSAGE, hwMillis());
  182. MY_DEBUGDEVICE.print(fmtBuffer);
  183. #else
  184. // prepend timestamp
  185. MY_DEBUGDEVICE.print(hwMillis());
  186. MY_DEBUGDEVICE.print(F(" "));
  187. #endif
  188. va_list args;
  189. va_start(args, fmt);
  190. vsnprintf_P(fmtBuffer, sizeof(fmtBuffer), fmt, args);
  191. #ifdef MY_GATEWAY_SERIAL
  192. // Truncate message if this is gateway node
  193. fmtBuffer[sizeof(fmtBuffer) - 2] = '\n';
  194. fmtBuffer[sizeof(fmtBuffer) - 1] = '\0';
  195. #endif
  196. va_end(args);
  197. MY_DEBUGDEVICE.print(fmtBuffer);
  198. // Disable flush since current STM32duino implementation performs a reset
  199. // instead of an actual flush
  200. //MY_DEBUGDEVICE.flush();
  201. #else
  202. (void)fmt;
  203. #endif
  204. }