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.

SPIBCM.h 6.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  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. * Based on TMRh20 RF24 library, Copyright (c) 2015 Charles-Henri Hallard <tmrh20@gmail.com>
  20. */
  21. #ifndef SPIBCM_h
  22. #define SPIBCM_h
  23. #include <stdio.h>
  24. #include "bcm2835.h"
  25. #include "BCM.h"
  26. #define SPI_HAS_TRANSACTION
  27. #define SPI_CLOCK_BASE 256000000
  28. // SPI Clock divider
  29. #define SPI_CLOCK_DIV1 BCM2835_SPI_CLOCK_DIVIDER_1
  30. #define SPI_CLOCK_DIV2 BCM2835_SPI_CLOCK_DIVIDER_2
  31. #define SPI_CLOCK_DIV4 BCM2835_SPI_CLOCK_DIVIDER_4
  32. #define SPI_CLOCK_DIV8 BCM2835_SPI_CLOCK_DIVIDER_8
  33. #define SPI_CLOCK_DIV16 BCM2835_SPI_CLOCK_DIVIDER_16
  34. #define SPI_CLOCK_DIV32 BCM2835_SPI_CLOCK_DIVIDER_32
  35. #define SPI_CLOCK_DIV64 BCM2835_SPI_CLOCK_DIVIDER_64
  36. #define SPI_CLOCK_DIV128 BCM2835_SPI_CLOCK_DIVIDER_128
  37. #define SPI_CLOCK_DIV256 BCM2835_SPI_CLOCK_DIVIDER_256
  38. #define SPI_CLOCK_DIV512 BCM2835_SPI_CLOCK_DIVIDER_512
  39. #define SPI_CLOCK_DIV1024 BCM2835_SPI_CLOCK_DIVIDER_1024
  40. #define SPI_CLOCK_DIV2048 BCM2835_SPI_CLOCK_DIVIDER_2048
  41. #define SPI_CLOCK_DIV4096 BCM2835_SPI_CLOCK_DIVIDER_4096
  42. #define SPI_CLOCK_DIV8192 BCM2835_SPI_CLOCK_DIVIDER_8192
  43. #define SPI_CLOCK_DIV16384 BCM2835_SPI_CLOCK_DIVIDER_16384
  44. #define SPI_CLOCK_DIV32768 BCM2835_SPI_CLOCK_DIVIDER_32768
  45. #define SPI_CLOCK_DIV65536 BCM2835_SPI_CLOCK_DIVIDER_65536
  46. // SPI Data mode
  47. #define SPI_MODE0 BCM2835_SPI_MODE0
  48. #define SPI_MODE1 BCM2835_SPI_MODE1
  49. #define SPI_MODE2 BCM2835_SPI_MODE2
  50. #define SPI_MODE3 BCM2835_SPI_MODE3
  51. #define LSBFIRST BCM2835_SPI_BIT_ORDER_LSBFIRST
  52. #define MSBFIRST BCM2835_SPI_BIT_ORDER_MSBFIRST
  53. const uint8_t SS = 24;
  54. const uint8_t MOSI = 19;
  55. const uint8_t MISO = 21;
  56. const uint8_t SCK = 23;
  57. /**
  58. * SPISettings class
  59. */
  60. class SPISettings
  61. {
  62. public:
  63. /**
  64. * @brief SPISettings constructor.
  65. *
  66. * Default clock speed is 8Mhz.
  67. */
  68. SPISettings()
  69. {
  70. init(SPI_CLOCK_DIV32, MSBFIRST, SPI_MODE0);
  71. }
  72. /**
  73. * @brief SPISettings constructor.
  74. *
  75. * @param clock SPI clock speed in Hz.
  76. * @param bitOrder SPI bit order.
  77. * @param dataMode SPI data mode.
  78. */
  79. SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode)
  80. {
  81. uint16_t divider;
  82. if (clock >= SPI_CLOCK_BASE) {
  83. divider = SPI_CLOCK_DIV1;
  84. } else if (clock >= SPI_CLOCK_BASE / 2) {
  85. divider = SPI_CLOCK_DIV2;
  86. } else if (clock >= SPI_CLOCK_BASE / 4) {
  87. divider = SPI_CLOCK_DIV4;
  88. } else if (clock >= SPI_CLOCK_BASE / 8) {
  89. divider = SPI_CLOCK_DIV8;
  90. } else if (clock >= SPI_CLOCK_BASE / 16) {
  91. divider = SPI_CLOCK_DIV16;
  92. } else if (clock >= SPI_CLOCK_BASE / 32) {
  93. divider = SPI_CLOCK_DIV32;
  94. } else if (clock >= SPI_CLOCK_BASE / 64) {
  95. divider = SPI_CLOCK_DIV64;
  96. } else if (clock >= SPI_CLOCK_BASE / 128) {
  97. divider = SPI_CLOCK_DIV128;
  98. } else if (clock >= SPI_CLOCK_BASE / 256) {
  99. divider = SPI_CLOCK_DIV256;
  100. } else if (clock >= SPI_CLOCK_BASE / 512) {
  101. divider = SPI_CLOCK_DIV512;
  102. } else if (clock >= SPI_CLOCK_BASE / 1024) {
  103. divider = SPI_CLOCK_DIV1024;
  104. } else if (clock >= SPI_CLOCK_BASE / 2048) {
  105. divider = SPI_CLOCK_DIV2048;
  106. } else if (clock >= SPI_CLOCK_BASE / 4096) {
  107. divider = SPI_CLOCK_DIV4096;
  108. } else if (clock >= SPI_CLOCK_BASE / 8192) {
  109. divider = SPI_CLOCK_DIV8192;
  110. } else if (clock >= SPI_CLOCK_BASE / 16384) {
  111. divider = SPI_CLOCK_DIV16384;
  112. } else if (clock >= SPI_CLOCK_BASE / 32768) {
  113. divider = SPI_CLOCK_DIV32768;
  114. } else if (clock >= SPI_CLOCK_BASE / 65536) {
  115. divider = SPI_CLOCK_DIV65536;
  116. } else {
  117. // Default to 8Mhz
  118. divider = SPI_CLOCK_DIV32;
  119. }
  120. init(divider, bitOrder, dataMode);
  121. }
  122. uint16_t cdiv; //!< @brief SPI clock divider.
  123. uint8_t border; //!< @brief SPI bit order.
  124. uint8_t dmode; //!< @brief SPI data mode.
  125. private:
  126. /**
  127. * @brief Initialized class members.
  128. *
  129. * @param divider SPI clock divider.
  130. * @param bitOrder SPI bit order.
  131. * @param dataMode SPI data mode.
  132. */
  133. void init(uint16_t divider, uint8_t bitOrder, uint8_t dataMode)
  134. {
  135. cdiv = divider;
  136. border = bitOrder;
  137. dmode = dataMode;
  138. }
  139. friend class SPIBCMClass;
  140. };
  141. /**
  142. * SPIBCM class
  143. */
  144. class SPIBCMClass
  145. {
  146. public:
  147. /**
  148. * @brief Send and receive a byte.
  149. *
  150. * @param data to send.
  151. * @return byte received.
  152. */
  153. inline static uint8_t transfer(uint8_t data);
  154. /**
  155. * @brief Send and receive a number of bytes.
  156. *
  157. * @param tbuf Sending buffer.
  158. * @param rbuf Receive buffer.
  159. * @param len Buffer length.
  160. */
  161. inline static void transfernb(char* tbuf, char* rbuf, uint32_t len);
  162. /**
  163. * @brief Send and receive a number of bytes.
  164. *
  165. * @param buf Buffer to read from and write to.
  166. * @param len Buffer length.
  167. */
  168. inline static void transfern(char* buf, uint32_t len);
  169. /**
  170. * @brief Start SPI operations.
  171. */
  172. static void begin();
  173. /**
  174. * @brief End SPI operations.
  175. */
  176. static void end();
  177. /**
  178. * @brief Sets the SPI bit order.
  179. *
  180. * @param bit_order The desired bit order.
  181. */
  182. static void setBitOrder(uint8_t bit_order);
  183. /**
  184. * @brief Sets the SPI data mode.
  185. *
  186. * @param data_mode The desired data mode.
  187. */
  188. static void setDataMode(uint8_t data_mode);
  189. /**
  190. * @brief Sets the SPI clock divider and therefore the SPI clock speed.
  191. *
  192. * @param divider The desired SPI clock divider.
  193. */
  194. static void setClockDivider(uint16_t divider);
  195. /**
  196. * @brief Sets the chip select pin.
  197. *
  198. * @param csn_pin Specifies the CS pin.
  199. */
  200. static void chipSelect(int csn_pin);
  201. /**
  202. * @brief Start SPI transaction.
  203. *
  204. * @param settings for SPI.
  205. */
  206. static void beginTransaction(SPISettings settings);
  207. /**
  208. * @brief End SPI transaction.
  209. */
  210. static void endTransaction();
  211. /**
  212. * @brief Not implemented.
  213. *
  214. * @param interruptNumber ignored parameter.
  215. */
  216. static void usingInterrupt(uint8_t interruptNumber);
  217. /**
  218. * @brief Not implemented.
  219. *
  220. * @param interruptNumber ignored parameter.
  221. */
  222. static void notUsingInterrupt(uint8_t interruptNumber);
  223. private:
  224. static uint8_t initialized; //!< @brief SPI initialized flag.
  225. };
  226. uint8_t SPIBCMClass::transfer(uint8_t data)
  227. {
  228. return bcm2835_spi_transfer(data);
  229. }
  230. void SPIBCMClass::transfernb(char* tbuf, char* rbuf, uint32_t len)
  231. {
  232. bcm2835_spi_transfernb( tbuf, rbuf, len);
  233. }
  234. void SPIBCMClass::transfern(char* buf, uint32_t len)
  235. {
  236. transfernb(buf, buf, len);
  237. }
  238. extern SPIBCMClass SPIBCM;
  239. #endif