PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

890 lines
43KB

  1. // RH_CC110.h
  2. //
  3. // Definitions for Texas Instruments CC110L transceiver.
  4. // http://www.ti.com/lit/ds/symlink/cc110l.pdf
  5. // As used in Anaren CC110L Air Module BoosterPack
  6. // https://www.anaren.com/air/cc110l-air-module-boosterpack-embedded-antenna-module-anaren
  7. //
  8. // Author: Mike McCauley (mikem@airspayce.com)
  9. // Copyright (C) 2016 Mike McCauley
  10. // $Id: RH_CC110.h,v 1.5 2016/04/04 01:40:12 mikem Exp $
  11. //
  12. #ifndef RH_CC110_h
  13. #define RH_CC110_h
  14. #include <RHNRFSPIDriver.h>
  15. // This is the maximum number of interrupts the driver can support
  16. // Most Arduinos can handle 2, Megas can handle more
  17. #define RH_CC110_NUM_INTERRUPTS 3
  18. // Max number of octets the FIFO can hold
  19. #define RH_CC110_FIFO_SIZE 64
  20. // This is the maximum number of bytes that can be carried by the chip
  21. // We use some for headers, keeping fewer for RadioHead messages
  22. #define RH_CC110_MAX_PAYLOAD_LEN RH_CC110_FIFO_SIZE
  23. // The length of the headers we add.
  24. // The headers are inside the chip payload
  25. #define RH_CC110_HEADER_LEN 4
  26. // This is the maximum message length that can be supported by this driver.
  27. // Can be pre-defined to a smaller size (to save SRAM) prior to including this header
  28. // Here we allow for 1 byte message length, 4 bytes headers, user data
  29. #ifndef RH_CC110_MAX_MESSAGE_LEN
  30. #define RH_CC110_MAX_MESSAGE_LEN (RH_CC110_MAX_PAYLOAD_LEN - RH_CC110_HEADER_LEN - 1)
  31. #endif
  32. #define RH_CC110_SPI_READ_MASK 0x80
  33. #define RH_CC110_SPI_BURST_MASK 0x40
  34. // Register definitions from Table 5-22
  35. #define RH_CC110_REG_00_IOCFG2 0x00
  36. #define RH_CC110_REG_01_IOCFG1 0x01
  37. #define RH_CC110_REG_02_IOCFG0 0x02
  38. #define RH_CC110_REG_03_FIFOTHR 0x03
  39. #define RH_CC110_REG_04_SYNC1 0x04
  40. #define RH_CC110_REG_05_SYNC0 0x05
  41. #define RH_CC110_REG_06_PKTLEN 0x06
  42. #define RH_CC110_REG_07_PKTCTRL1 0x07
  43. #define RH_CC110_REG_08_PKTCTRL0 0x08
  44. #define RH_CC110_REG_09_ADDR 0x09
  45. #define RH_CC110_REG_0A_CHANNR 0x0a
  46. #define RH_CC110_REG_0B_FSCTRL1 0x0b
  47. #define RH_CC110_REG_0C_FSCTRL0 0x0c
  48. #define RH_CC110_REG_0D_FREQ2 0x0d
  49. #define RH_CC110_REG_0E_FREQ1 0x0e
  50. #define RH_CC110_REG_0F_FREQ0 0x0f
  51. #define RH_CC110_REG_10_MDMCFG4 0x10
  52. #define RH_CC110_REG_11_MDMCFG3 0x11
  53. #define RH_CC110_REG_12_MDMCFG2 0x12
  54. #define RH_CC110_REG_13_MDMCFG1 0x13
  55. #define RH_CC110_REG_14_MDMCFG0 0x14
  56. #define RH_CC110_REG_15_DEVIATN 0x15
  57. #define RH_CC110_REG_16_MCSM2 0x16
  58. #define RH_CC110_REG_17_MCSM1 0x17
  59. #define RH_CC110_REG_18_MCSM0 0x18
  60. #define RH_CC110_REG_19_FOCCFG 0x19
  61. #define RH_CC110_REG_1A_BSCFG 0x1a
  62. #define RH_CC110_REG_1B_AGCCTRL2 0x1b
  63. #define RH_CC110_REG_1C_AGCCTRL1 0x1c
  64. #define RH_CC110_REG_1D_AGCCTRL0 0x1d
  65. #define RH_CC110_REG_1E_WOREVT1 0x1e
  66. #define RH_CC110_REG_1F_WOREVT0 0x1f
  67. #define RH_CC110_REG_20_WORCTRL 0x20
  68. #define RH_CC110_REG_21_FREND1 0x21
  69. #define RH_CC110_REG_22_FREND0 0x22
  70. #define RH_CC110_REG_23_FSCAL3 0x23
  71. #define RH_CC110_REG_24_FSCAL2 0x24
  72. #define RH_CC110_REG_25_FSCAL1 0x25
  73. #define RH_CC110_REG_26_FSCAL0 0x26
  74. #define RH_CC110_REG_27_RCCTRL1 0x28
  75. #define RH_CC110_REG_28_RCCTRL0 0x29
  76. #define RH_CC110_REG_29_FSTEST 0x2a
  77. #define RH_CC110_REG_2A_PTEST 0x2b
  78. #define RH_CC110_REG_2B_AGCTEST 0x2c
  79. #define RH_CC110_REG_2C_TEST2 0x2c
  80. #define RH_CC110_REG_2D_TEST1 0x2d
  81. #define RH_CC110_REG_2E_TEST0 0x2e
  82. // Single byte read and write version of registers 0x30 to 0x3f. Strobes
  83. // use spiCommand()
  84. #define RH_CC110_STROBE_30_SRES 0x30
  85. #define RH_CC110_STROBE_31_SFSTXON 0x31
  86. #define RH_CC110_STROBE_32_SXOFF 0x32
  87. #define RH_CC110_STROBE_33_SCAL 0x33
  88. #define RH_CC110_STROBE_34_SRX 0x34
  89. #define RH_CC110_STROBE_35_STX 0x35
  90. #define RH_CC110_STROBE_36_SIDLE 0x36
  91. #define RH_CC110_STROBE_39_SPWD 0x39
  92. #define RH_CC110_STROBE_3A_SFRX 0x3a
  93. #define RH_CC110_STROBE_3B_SFTX 0x3b
  94. #define RH_CC110_STROBE_3D_SNOP 0x3d
  95. // Burst read from these registers gives more data:
  96. // use spiBurstReadRegister()
  97. #define RH_CC110_REG_30_PARTNUM 0x30
  98. #define RH_CC110_REG_31_VERSION 0x31
  99. #define RH_CC110_REG_32_FREQEST 0x32
  100. #define RH_CC110_REG_33_CRC_REG 0x33
  101. #define RH_CC110_REG_34_RSSI 0x34
  102. #define RH_CC110_REG_35_MARCSTATE 0x35
  103. #define RH_CC110_REG_38_PKTSTATUS 0x38
  104. #define RH_CC110_REG_3A_TXBYTES 0x3a
  105. #define RH_CC110_REG_3B_RXBYTES 0x3b
  106. // PATABLE, TXFIFO, RXFIFO also support burst
  107. #define RH_CC110_REG_3E_PATABLE 0x3e
  108. #define RH_CC110_REG_3F_FIFO 0x3f
  109. // Status Byte
  110. #define RH_CC110_STATUS_CHIP_RDY 0x80
  111. #define RH_CC110_STATUS_STATE 0x70
  112. #define RH_CC110_STATUS_IDLE 0x00
  113. #define RH_CC110_STATUS_RX 0x10
  114. #define RH_CC110_STATUS_TX 0x20
  115. #define RH_CC110_STATUS_FSTXON 0x30
  116. #define RH_CC110_STATUS_CALIBRATE 0x40
  117. #define RH_CC110_STATUS_SETTLING 0x50
  118. #define RH_CC110_STATUS_RXFIFO_OVERFLOW 0x60
  119. #define RH_CC110_STATUS_TXFIFO_UNDERFLOW 0x70
  120. #define RH_CC110_STATUS_FIFOBYTES_AVAILABLE 0x0f
  121. // Register contents
  122. // Chip Status Byte, read from header, data or command strobe
  123. #define RH_CC110_CHIP_RDY 0x80
  124. #define RH_CC110_STATE 0x70
  125. #define RH_CC110_FIFO_BYTES_AVAILABLE 0x0f
  126. // Register bit field definitions
  127. // #define RH_CC110_REG_00_IOCFG2 0x00
  128. // #define RH_CC110_REG_01_IOCFG1 0x01
  129. // #define RH_CC110_REG_02_IOCFG0 0x02
  130. #define RH_CC110_GDO_CFG_RX_FIFO_THR 0x00
  131. #define RH_CC110_GDO_CFG_RX_FIFO_FULL 0x01
  132. #define RH_CC110_GDO_CFG_TX_FIFO_THR 0x02
  133. #define RH_CC110_GDO_CFG_TX_FIFO_EMPTY 0x03
  134. #define RH_CC110_GDO_CFG_RX_FIFO_OVERFLOW 0x04
  135. #define RH_CC110_GDO_CFG_TX_FIFO_UNDEFLOOW 0x05
  136. #define RH_CC110_GDO_CFG_SYNC 0x06
  137. #define RH_CC110_GDO_CFG_CRC_OK_AUTORESET 0x07
  138. #define RH_CC110_GDO_CFG_CCA 0x09
  139. #define RH_CC110_GDO_CFG_LOCK_DETECT 0x0a
  140. #define RH_CC110_GDO_CFG_SERIAL_CLOCK 0x0b
  141. #define RH_CC110_GDO_CFG_SYNCHRONOUS_SDO 0x0c
  142. #define RH_CC110_GDO_CFG_SDO 0x0d
  143. #define RH_CC110_GDO_CFG_CARRIER 0x0e
  144. #define RH_CC110_GDO_CFG_CRC_OK 0x0f
  145. #define RH_CC110_GDO_CFG_PA_PD 0x1b
  146. #define RH_CC110_GDO_CFG_LNA_PD 0x1c
  147. #define RH_CC110_GDO_CFG_CLK_32K 0x27
  148. #define RH_CC110_GDO_CFG_CHIP_RDYN 0x29
  149. #define RH_CC110_GDO_CFG_XOSC_STABLE 0x2b
  150. #define RH_CC110_GDO_CFG_HIGH_IMPEDANCE 0x2e
  151. #define RH_CC110_GDO_CFG_0 0x2f
  152. #define RH_CC110_GDO_CFG_CLK_XOSC_DIV_1 0x30
  153. #define RH_CC110_GDO_CFG_CLK_XOSC_DIV_1_5 0x31
  154. #define RH_CC110_GDO_CFG_CLK_XOSC_DIV_2 0x32
  155. #define RH_CC110_GDO_CFG_CLK_XOSC_DIV_3 0x33
  156. #define RH_CC110_GDO_CFG_CLK_XOSC_DIV_4 0x34
  157. #define RH_CC110_GDO_CFG_CLK_XOSC_DIV_6 0x35
  158. #define RH_CC110_GDO_CFG_CLK_XOSC_DIV_8 0x36
  159. #define RH_CC110_GDO_CFG_CLK_XOSC_DIV_12 0x37
  160. #define RH_CC110_GDO_CFG_CLK_XOSC_DIV_16 0x38
  161. #define RH_CC110_GDO_CFG_CLK_XOSC_DIV_24 0x39
  162. #define RH_CC110_GDO_CFG_CLK_XOSC_DIV_32 0x3a
  163. #define RH_CC110_GDO_CFG_CLK_XOSC_DIV_48 0x3b
  164. #define RH_CC110_GDO_CFG_CLK_XOSC_DIV_64 0x3c
  165. #define RH_CC110_GDO_CFG_CLK_XOSC_DIV_96 0x3d
  166. #define RH_CC110_GDO_CFG_CLK_XOSC_DIV_128 0x3e
  167. #define RH_CC110_GDO_CFG_CLK_XOSC_DIV_192 0x3f
  168. // #define RH_CC110_REG_03_FIFOTHR 0x03
  169. #define RH_CC110_ADC_RETENTION 0x80
  170. #define RH_CC110_CLOSE_IN_RX 0x30
  171. #define RH_CC110_CLOSE_IN_RX_0DB 0x00
  172. #define RH_CC110_CLOSE_IN_RX_6DB 0x10
  173. #define RH_CC110_CLOSE_IN_RX_12DB 0x20
  174. #define RH_CC110_CLOSE_IN_RX_18DB 0x30
  175. #define RH_CC110_FIFO_THR 0x0f
  176. // #define RH_CC110_REG_04_SYNC1 0x04
  177. // #define RH_CC110_REG_05_SYNC0 0x05
  178. // #define RH_CC110_REG_06_PKTLEN 0x06
  179. // #define RH_CC110_REG_07_PKTCTRL1 0x07
  180. #define RH_CC110_CRC_AUTOFLUSH 0x08
  181. #define RH_CC110_APPEND_STATUS 0x04
  182. #define RH_CC110_ADDR_CHK 0x03
  183. // can or the next 2:
  184. #define RH_CC110_ADDR_CHK_ADDRESS 0x01
  185. #define RH_CC110_ADDR_CHK_BROADCAST 0x02
  186. // #define RH_CC110_REG_08_PKTCTRL0 0x08
  187. #define RH_CC110_PKT_FORMAT 0x30
  188. #define RH_CC110_PKT_FORMAT_NORMAL 0x00
  189. #define RH_CC110_PKT_FORMAT_SYNC_SERIAL 0x10
  190. #define RH_CC110_PKT_FORMAT_RANDOM_TX 0x20
  191. #define RH_CC110_PKT_FORMAT_ASYNC_SERIAL 0x30
  192. #define RH_CC110_CRC_EN 0x04
  193. #define RH_CC110_LENGTH_CONFIG 0x03
  194. #define RH_CC110_LENGTH_CONFIG_FIXED 0x00
  195. #define RH_CC110_LENGTH_CONFIG_VARIABLE 0x01
  196. #define RH_CC110_LENGTH_CONFIG_INFINITE 0x02
  197. // #define RH_CC110_REG_09_ADDR 0x09
  198. // #define RH_CC110_REG_0A_CHANNR 0x0a
  199. // #define RH_CC110_REG_0B_FSCTRL1 0x0b
  200. // #define RH_CC110_REG_0C_FSCTRL0 0x0c
  201. // #define RH_CC110_REG_0D_FREQ2 0x0d
  202. // #define RH_CC110_REG_0E_FREQ1 0x0e
  203. // #define RH_CC110_REG_0F_FREQ0 0x0f
  204. // #define RH_CC110_REG_10_MDMCFG4 0x10
  205. #define RH_CC110_CHANBW_E 0xc0
  206. #define RH_CC110_CHANBW_M 0x30
  207. #define RH_CC110_DRATE_E 0x0f
  208. // #define RH_CC110_REG_11_MDMCFG3 0x11
  209. // #define RH_CC110_REG_12_MDMCFG2 0x12
  210. #define RH_CC110_DEM_DCFILT_OFF 0x80
  211. #define RH_CC110_MOD_FORMAT 0x70
  212. #define RH_CC110_MOD_FORMAT_2FSK 0x00
  213. #define RH_CC110_MOD_FORMAT_GFSK 0x10
  214. #define RH_CC110_MOD_FORMAT_OOK 0x30
  215. #define RH_CC110_MOD_FORMAT_4FSK 0x40
  216. #define RH_CC110_MANCHESTER_EN 0x08
  217. #define RH_CC110_SYNC_MODE 0x07
  218. #define RH_CC110_SYNC_MODE_NONE 0x00
  219. #define RH_CC110_SYNC_MODE_15_16 0x01
  220. #define RH_CC110_SYNC_MODE_16_16 0x02
  221. #define RH_CC110_SYNC_MODE_30_32 0x03
  222. #define RH_CC110_SYNC_MODE_NONE_CARRIER 0x04
  223. #define RH_CC110_SYNC_MODE_15_16_CARRIER 0x05
  224. #define RH_CC110_SYNC_MODE_16_16_CARRIER 0x06
  225. #define RH_CC110_SYNC_MODE_30_32_CARRIER 0x07
  226. // #define RH_CC110_REG_13_MDMCFG1 0x13
  227. #define RH_CC110_NUM_PREAMBLE 0x70
  228. #define RH_CC110_NUM_PREAMBLE_2 0x00
  229. #define RH_CC110_NUM_PREAMBLE_3 0x10
  230. #define RH_CC110_NUM_PREAMBLE_4 0x20
  231. #define RH_CC110_NUM_PREAMBLE_6 0x30
  232. #define RH_CC110_NUM_PREAMBLE_8 0x40
  233. #define RH_CC110_NUM_PREAMBLE_12 0x50
  234. #define RH_CC110_NUM_PREAMBLE_16 0x60
  235. #define RH_CC110_NUM_PREAMBLE_24 0x70
  236. #define RH_CC110_CHANSPC_E 0x03
  237. // #define RH_CC110_REG_14_MDMCFG0 0x14
  238. // #define RH_CC110_REG_15_DEVIATN 0x15
  239. #define RH_CC110_DEVIATION_E 0x70
  240. #define RH_CC110_DEVIATION_M 0x07
  241. // #define RH_CC110_REG_16_MCSM2 0x16
  242. #define RH_CC110_RX_TIME_RSSI 0x10
  243. // #define RH_CC110_REG_17_MCSM1 0x17
  244. #define RH_CC110_CCA_MODE 0x30
  245. #define RH_CC110_CCA_MODE_ALWAYS 0x00
  246. #define RH_CC110_CCA_MODE_RSSI 0x10
  247. #define RH_CC110_CCA_MODE_PACKET 0x20
  248. #define RH_CC110_CCA_MODE_RSSI_PACKET 0x30
  249. #define RH_CC110_RXOFF_MODE 0x0c
  250. #define RH_CC110_RXOFF_MODE_IDLE 0x00
  251. #define RH_CC110_RXOFF_MODE_FSTXON 0x04
  252. #define RH_CC110_RXOFF_MODE_TX 0x08
  253. #define RH_CC110_RXOFF_MODE_RX 0x0c
  254. #define RH_CC110_TXOFF_MODE 0x03
  255. #define RH_CC110_TXOFF_MODE_IDLE 0x00
  256. #define RH_CC110_TXOFF_MODE_FSTXON 0x01
  257. #define RH_CC110_TXOFF_MODE_TX 0x02
  258. #define RH_CC110_TXOFF_MODE_RX 0x03
  259. // #define RH_CC110_REG_18_MCSM0 0x18
  260. #define RH_CC110_FS_AUTOCAL 0x30
  261. #define RH_CC110_FS_AUTOCAL_NEVER 0x00
  262. #define RH_CC110_FS_AUTOCAL_FROM_IDLE 0x10
  263. #define RH_CC110_FS_AUTOCAL_TO_IDLE 0x20
  264. #define RH_CC110_FS_AUTOCAL_TO_IDLE_4 0x30
  265. #define RH_CC110_PO_TIMEOUT 0x0c
  266. #define RH_CC110_PO_TIMEOUT_1 0x00
  267. #define RH_CC110_PO_TIMEOUT_16 0x04
  268. #define RH_CC110_PO_TIMEOUT_64 0x08
  269. #define RH_CC110_PO_TIMEOUT_256 0x0c
  270. #define RH_CC110_XOSC_FORCE_ON 0x01
  271. // #define RH_CC110_REG_19_FOCCFG 0x19
  272. #define RH_CC110_FOC_BS_CS_GATE 0x20
  273. #define RH_CC110_FOC_PRE_K 0x18
  274. #define RH_CC110_FOC_PRE_K_0 0x00
  275. #define RH_CC110_FOC_PRE_K_1 0x08
  276. #define RH_CC110_FOC_PRE_K_2 0x10
  277. #define RH_CC110_FOC_PRE_K_3 0x18
  278. #define RH_CC110_FOC_POST_K 0x04
  279. #define RH_CC110_FOC_LIMIT 0x03
  280. #define RH_CC110_FOC_LIMIT_0 0x00
  281. #define RH_CC110_FOC_LIMIT_8 0x01
  282. #define RH_CC110_FOC_LIMIT_4 0x02
  283. #define RH_CC110_FOC_LIMIT_2 0x03
  284. // #define RH_CC110_REG_1A_BSCFG 0x1a
  285. #define RH_CC110_BS_PRE_K 0xc0
  286. #define RH_CC110_BS_PRE_K_1 0x00
  287. #define RH_CC110_BS_PRE_K_2 0x40
  288. #define RH_CC110_BS_PRE_K_3 0x80
  289. #define RH_CC110_BS_PRE_K_4 0xc0
  290. #define RH_CC110_BS_PRE_KP 0x30
  291. #define RH_CC110_BS_PRE_KP_1 0x00
  292. #define RH_CC110_BS_PRE_KP_2 0x10
  293. #define RH_CC110_BS_PRE_KP_3 0x20
  294. #define RH_CC110_BS_PRE_KP_4 0x30
  295. #define RH_CC110_BS_POST_KI 0x08
  296. #define RH_CC110_BS_POST_KP 0x04
  297. #define RH_CC110_BS_LIMIT 0x03
  298. #define RH_CC110_BS_LIMIT_0 0x00
  299. #define RH_CC110_BS_LIMIT_3 0x01
  300. #define RH_CC110_BS_LIMIT_6 0x02
  301. #define RH_CC110_BS_LIMIT_12 0x03
  302. // #define RH_CC110_REG_1B_AGCCTRL2 0x1b
  303. #define RH_CC110_MAX_DVA_GAIN 0xc0
  304. #define RH_CC110_MAX_DVA_GAIN_ALL 0x00
  305. #define RH_CC110_MAX_DVA_GAIN_ALL_LESS_1 0x40
  306. #define RH_CC110_MAX_DVA_GAIN_ALL_LESS_2 0x80
  307. #define RH_CC110_MAX_DVA_GAIN_ALL_LESS_3 0xc0
  308. #define RH_CC110_MAX_LNA_GAIN 0x38
  309. #define RH_CC110_MAGN_TARGET 0x07
  310. #define RH_CC110_MAGN_TARGET_24DB 0x00
  311. #define RH_CC110_MAGN_TARGET_27DB 0x01
  312. #define RH_CC110_MAGN_TARGET_30DB 0x02
  313. #define RH_CC110_MAGN_TARGET_33DB 0x03
  314. #define RH_CC110_MAGN_TARGET_36DB 0x04
  315. #define RH_CC110_MAGN_TARGET_38DB 0x05
  316. #define RH_CC110_MAGN_TARGET_40DB 0x06
  317. #define RH_CC110_MAGN_TARGET_42DB 0x07
  318. // #define RH_CC110_REG_1C_AGCCTRL1 0x1c
  319. #define RH_CC110_AGC_LNA_PRIORITY 0x40
  320. #define RH_CC110_CARRIER_SENSE_REL_THR 0x30
  321. #define RH_CC110_CARRIER_SENSE_REL_THR_0DB 0x00
  322. #define RH_CC110_CARRIER_SENSE_REL_THR_6DB 0x10
  323. #define RH_CC110_CARRIER_SENSE_REL_THR_10DB 0x20
  324. #define RH_CC110_CARRIER_SENSE_REL_THR_14DB 0x30
  325. #define RH_CC110_CARRIER_SENSE_ABS_THR 0x0f
  326. // #define RH_CC110_REG_1D_AGCCTRL0 0x1d
  327. #define RH_CC110_HYST_LEVEL 0xc0
  328. #define RH_CC110_HYST_LEVEL_NONE 0x00
  329. #define RH_CC110_HYST_LEVEL_LOW 0x40
  330. #define RH_CC110_HYST_LEVEL_MEDIUM 0x80
  331. #define RH_CC110_HYST_LEVEL_HIGH 0xc0
  332. #define RH_CC110_WAIT_TIME 0x30
  333. #define RH_CC110_WAIT_TIME_8 0x00
  334. #define RH_CC110_WAIT_TIME_16 0x10
  335. #define RH_CC110_WAIT_TIME_24 0x20
  336. #define RH_CC110_WAIT_TIME_32 0x30
  337. #define RH_CC110_AGC_FREEZE 0x0c
  338. #define RH_CC110_AGC_FILTER_LENGTH 0x03
  339. #define RH_CC110_AGC_FILTER_LENGTH_8 0x00
  340. #define RH_CC110_AGC_FILTER_LENGTH_16 0x01
  341. #define RH_CC110_AGC_FILTER_LENGTH_32 0x02
  342. #define RH_CC110_AGC_FILTER_LENGTH_64 0x03
  343. // #define RH_CC110_REG_1E_WOREVT1 0x1e
  344. // #define RH_CC110_REG_1F_WOREVT0 0x1f
  345. // #define RH_CC110_REG_20_WORCTRL 0x20
  346. // #define RH_CC110_REG_21_FREND1 0x21
  347. #define RH_CC110_LNA_CURRENT 0xc0
  348. #define RH_CC110_LNA2MIX_CURRENT 0x30
  349. #define RH_CC110_LODIV_BUF_CURRENT_RX 0x0c
  350. #define RH_CC110_MIX_CURRENT 0x03
  351. // #define RH_CC110_REG_22_FREND0 0x22
  352. #define RH_CC110_LODIV_BUF_CURRENT_TX 0x30
  353. #define RH_CC110_PA_POWER 0x07
  354. // #define RH_CC110_REG_23_FSCAL3 0x23
  355. #define RH_CC110_FSCAL3_7_6 0xc0
  356. #define RH_CC110_CHP_CURR_CAL_EN 0x30
  357. #define RH_CC110_FSCAL3_3_0 0x0f
  358. // #define RH_CC110_REG_24_FSCAL2 0x24
  359. #define RH_CC110_VCO_CORE_H_EN 0x20
  360. #define RH_CC110_FSCAL2 0x1f
  361. // #define RH_CC110_REG_25_FSCAL1 0x25
  362. #define RH_CC110_FSCAL1 0x3f
  363. // #define RH_CC110_REG_26_FSCAL0 0x26
  364. #define RH_CC110_FSCAL0 0x7f
  365. // #define RH_CC110_REG_27_RCCTRL1 0x28
  366. // #define RH_CC110_REG_28_RCCTRL0 0x29
  367. // #define RH_CC110_REG_29_FSTEST 0x2a
  368. // #define RH_CC110_REG_2A_PTEST 0x2b
  369. // #define RH_CC110_REG_2B_AGCTEST 0x2c
  370. // #define RH_CC110_REG_2C_TEST2 0x2c
  371. // #define RH_CC110_REG_2D_TEST1 0x2d
  372. // #define RH_CC110_REG_2E_TEST0 0x2e
  373. #define RH_CC110_TEST0_7_2 0xfc
  374. #define RH_CC110_VCO_SEL_CAL_EN 0x02
  375. #define RH_CC110_TEST0_0 0x01
  376. // #define RH_CC110_REG_30_PARTNUM 0x30
  377. // #define RH_CC110_REG_31_VERSION 0x31
  378. // #define RH_CC110_REG_32_FREQEST 0x32
  379. // #define RH_CC110_REG_33_CRC_REG 0x33
  380. #define RH_CC110_CRC_REG_CRC_OK 0x80
  381. // #define RH_CC110_REG_34_RSSI 0x34
  382. // #define RH_CC110_REG_35_MARCSTATE 0x35
  383. #define RH_CC110_MARC_STATE 0x1f
  384. #define RH_CC110_MARC_STATE_SLEEP 0x00
  385. #define RH_CC110_MARC_STATE_IDLE 0x01
  386. #define RH_CC110_MARC_STATE_XOFF 0x02
  387. #define RH_CC110_MARC_STATE_VCOON_MC 0x03
  388. #define RH_CC110_MARC_STATE_REGON_MC 0x04
  389. #define RH_CC110_MARC_STATE_MANCAL 0x05
  390. #define RH_CC110_MARC_STATE_VCOON 0x06
  391. #define RH_CC110_MARC_STATE_REGON 0x07
  392. #define RH_CC110_MARC_STATE_STARTCAL 0x08
  393. #define RH_CC110_MARC_STATE_BWBOOST 0x09
  394. #define RH_CC110_MARC_STATE_FS_LOCK 0x0a
  395. #define RH_CC110_MARC_STATE_IFADCON 0x0b
  396. #define RH_CC110_MARC_STATE_ENDCAL 0x0c
  397. #define RH_CC110_MARC_STATE_RX 0x0d
  398. #define RH_CC110_MARC_STATE_RX_END 0x0e
  399. #define RH_CC110_MARC_STATE_RX_RST 0x0f
  400. #define RH_CC110_MARC_STATE_TXRX_SWITCH 0x10
  401. #define RH_CC110_MARC_STATE_RXFIFO_OVERFLOW 0x11
  402. #define RH_CC110_MARC_STATE_FSTXON 0x12
  403. #define RH_CC110_MARC_STATE_TX 0x13
  404. #define RH_CC110_MARC_STATE_TX_END 0x14
  405. #define RH_CC110_MARC_STATE_RXTX_SWITCH 0x15
  406. #define RH_CC110_MARC_STATE_TXFIFO_UNDERFLOW 0x16
  407. // #define RH_CC110_REG_38_PKTSTATUS 0x38
  408. #define RH_CC110_PKTSTATUS_CRC_OK 0x80
  409. #define RH_CC110_PKTSTATUS_CS 0x40
  410. #define RH_CC110_PKTSTATUS_CCA 0x10
  411. #define RH_CC110_PKTSTATUS_SFD 0x08
  412. #define RH_CC110_PKTSTATUS_GDO2 0x04
  413. #define RH_CC110_PKTSTATUS_GDO0 0x01
  414. // #define RH_CC110_REG_3A_TXBYTES 0x3a
  415. #define RH_CC110_TXFIFO_UNDERFLOW 0x80
  416. #define RH_CC110_NUM_TXBYTES 0x7f
  417. // #define RH_CC110_REG_3B_RXBYTES 0x3b
  418. #define RH_CC110_RXFIFO_UNDERFLOW 0x80
  419. #define RH_CC110_NUM_RXBYTES 0x7f
  420. /////////////////////////////////////////////////////////////////////
  421. /// \class RH_CC110 RH_CC110.h <RH_CC110.h>
  422. /// \brief Send and receive addressed, reliable, acknowledged datagrams by Texas Instruments CC110L and compatible transceivers and modules.
  423. ///
  424. /// The TI CC110L is a low cost tranceiver chip capable of 300 to 928MHz and with a wide range of modulation types and speeds.
  425. /// The chip is typically provided on a module that also includes the antenna and coupling hardware
  426. /// and is therefore capable of a more restricted frequency range.
  427. ///
  428. /// Supported modules include:
  429. /// - Anaren AIR BoosterPack 430BOOST-CC110L
  430. ///
  431. /// This base class provides basic functions for sending and receiving unaddressed, unreliable datagrams
  432. /// of arbitrary length to 59 octets per packet at a selected data rate and modulation type.
  433. /// Use one of the Manager classes to get addressing and
  434. /// acknowledgement reliability, routing, meshes etc.
  435. ///
  436. /// Naturally, for any 2 radios to communicate that must be configured to use the same frequency and
  437. /// data rate, and with identical network addresses.
  438. ///
  439. /// Several CC110L modules can be connected to an Arduino, permitting the construction of translators
  440. /// and frequency changers, etc.
  441. ///
  442. /// Several GFSK modulation schemes are provided and may be selected by calling setModemConfig(). No FSK or OOK
  443. /// modulation schemes are provided though the implementor may configure the mnodem characteristics directly
  444. /// by calling setModemRegisters().
  445. ///
  446. /// Implementation based on:
  447. /// http://www.ti.com/lit/ds/symlink/cc110l.pdf
  448. /// and
  449. /// https://www.anaren.com/air/cc110l-air-module-boosterpack-embedded-antenna-module-anaren
  450. ///
  451. /// \par Crystal Frequency
  452. ///
  453. /// Modules based on the CC110L may contain a crystal oscillator with one of 2 possible frequencies: 26MHz or 27MHz.
  454. /// A number of radio configuration parameters (including carrier frequency and data rates) depend on the
  455. /// crystal oscillator frequency. The chip has no knowledge of the frequency, so it is up to the implementer
  456. /// to tell the driver the oscillator frequency by passing in the appropriate value of is27MHz to the constructor (default 26MHz)
  457. /// or by calling setIs27MHz() before calling init().
  458. /// Failure to correctly set this flag will cause incorrect frequency and modulation
  459. /// characteristics to be used.
  460. ///
  461. /// Caution: it is not easy to determine what the actual crystal frequency is on some modules. For example,
  462. /// the documentation for the Anaren BoosterPack indictes a 26MHz crystal, but measurements on the devices delivered here
  463. /// indicate a 27MHz crystal is actually installed. TI recommend 27MHz for
  464. ///
  465. /// \par Packet Format
  466. ///
  467. /// - 2 octets sync (a configurable network address)
  468. /// - 1 octet message length
  469. /// - 4 to 63 octets of payload consisting of:
  470. /// - 1 octet TO header
  471. /// - 1 octet FROM header
  472. /// - 1 octet ID header
  473. /// - 1 octet FLAGS header
  474. /// - 0 to 59 octets of user message
  475. /// - 2 octets CRC
  476. ///
  477. /// \par Connecting CC110L to Arduino
  478. ///
  479. /// Warning: the CC110L is a 3.3V part, and exposing it to 5V on any pin will damage it. Ensure you are using a 3.3V
  480. /// MCU or use level shifters. We tested with Teensy 3.1.
  481. ///
  482. /// The electrical connection between a CC110L module and the Arduino or other processor
  483. /// require 3.3V, the 3 x SPI pins (SCK, SDI, SDO),
  484. /// a Chip Select pin and an Interrupt pin.
  485. /// Examples below assume the Anaren BoosterPack. Caution: the pin numbering on the Anaren BoosterPack
  486. /// is a bit counter-intuitive: the direction of number on J1 is the reverse of J2. Check the pin numbers
  487. /// stencilied on the front of the board to be sure.
  488. ///
  489. /// \code
  490. /// Teensy 3.1 CC110L pin name Anaren BoosterPack pin
  491. /// 3.3V---------VDD (3.3V in) J1-1
  492. /// SS pin D10----------CSn (chip select in) J2-8
  493. /// SCK pin D13----------SCLK (SPI clock in) J1-7
  494. /// MOSI pin D11----------MOSI (SPI data in) J2-5
  495. /// MISO pin D12----------MISO (SPI data out) J2-4
  496. /// D2-----------GDO0 (Interrupt output) J2-9
  497. /// GND----------GND (ground in) J2-10
  498. /// \endcode
  499. /// and use the default RH_CC110 constructor. You can use other pins by passing the appropriate arguments
  500. /// to the RH_CC110 constructor, depending on what your MCU supports.
  501. ///
  502. /// For the Particle Photon:
  503. /// \code
  504. /// Photon CC110L pin name Anaren BoosterPack pin
  505. /// 3.3V---------VDD (3.3V in) J1-1
  506. /// SS pin A2-----------CSn (chip select in) J2-8
  507. /// SCK pin A3-----------SCLK (SPI clock in) J1-7
  508. /// MOSI pin A5-----------MOSI (SPI data in) J2-5
  509. /// MISO pin A4-----------MISO (SPI data out) J2-4
  510. /// D2-----------GDO0 (Interrupt output) J2-9
  511. /// GND----------GND (ground in) J2-10
  512. /// \endcode
  513. /// and use the default RH_CC110 constructor. You can use other pins by passing the appropriate arguments
  514. /// to the RH_CC110 constructor, depending on what your MCU supports.
  515. ///
  516. /// \par Example programs
  517. ///
  518. /// Several example programs are provided.
  519. ///
  520. /// \par Radio operating strategy and defaults
  521. ///
  522. /// The radio is enabled at all times and switched between RX, TX and IDLE modes.
  523. /// When RX is enabled (by calling available() or setModeRx()) the radio will stay in RX mode until a
  524. /// valid CRC correct message addressed to thiis node is received, when it will transition to IDLE.
  525. /// When TX is enabled (by calling send()) it will stay in TX mode until the message has ben sent
  526. /// and waitPacketSent() is called when it wil transition to IDLE
  527. ///(this radio has no 'packet sent' interrupt that could be used, so polling
  528. /// with waitPacketSent() is required
  529. ///
  530. /// The modulation schemes supported include the GFSK schemes provided by default in the TI SmartRF Suite.
  531. /// This software allows you to get the correct register values for diferent modulation schemes. All the modulation
  532. /// schemes prvided in the driver are based on the recommended register values given by SmartRF.
  533. /// Other schemes such a 2-FSK, 4-FSK and OOK are suported by the chip, but canned configurations are not provided with this driver.
  534. /// The implementer may choose to create their own modem configurations and pass them to setModemRegisters().
  535. ///
  536. class RH_CC110 : public RHNRFSPIDriver
  537. {
  538. public:
  539. /// \brief Defines register configuration values for a desired modulation
  540. ///
  541. /// Defines values for various configuration fields and registers to
  542. /// achieve a desired modulation speed and frequency deviation.
  543. typedef struct
  544. {
  545. uint8_t reg_0b; ///< RH_CC110_REG_0B_FSCTRL1
  546. uint8_t reg_0c; ///< RH_CC110_REG_0C_FSCTRL0
  547. uint8_t reg_10; ///< RH_CC110_REG_10_MDMCFG4
  548. uint8_t reg_11; ///< RH_CC110_REG_11_MDMCFG3
  549. uint8_t reg_12; ///< RH_CC110_REG_12_MDMCFG2
  550. uint8_t reg_15; ///< RH_CC110_REG_15_DEVIATN
  551. uint8_t reg_19; ///< RH_CC110_REG_19_FOCCFG
  552. uint8_t reg_1a; ///< RH_CC110_REG_1A_BSCFG
  553. uint8_t reg_1b; ///< RH_CC110_REG_1B_AGCCTRL2
  554. uint8_t reg_1c; ///< RH_CC110_REG_1C_AGCCTRL1
  555. uint8_t reg_1d; ///< RH_CC110_REG_1D_AGCCTRL0
  556. uint8_t reg_21; ///< RH_CC110_REG_21_FREND1
  557. uint8_t reg_22; ///< RH_CC110_REG_22_FREND0
  558. uint8_t reg_23; ///< RH_CC110_REG_23_FSCAL3
  559. uint8_t reg_24; ///< RH_CC110_REG_24_FSCAL2
  560. uint8_t reg_25; ///< RH_CC110_REG_25_FSCAL1
  561. uint8_t reg_26; ///< RH_CC110_REG_26_FSCAL0
  562. uint8_t reg_2c; ///< RH_CC110_REG_2C_TEST2
  563. uint8_t reg_2d; ///< RH_CC110_REG_2D_TEST1
  564. uint8_t reg_2e; ///< RH_CC110_REG_2E_TEST0
  565. } ModemConfig;
  566. /// Choices for setModemConfig() for a selected subset of common modulation types,
  567. /// and data rates. If you need another configuration, use the register calculator.
  568. /// and call setModemRegisters() with your desired settings.
  569. /// These are indexes into MODEM_CONFIG_TABLE. We strongly recommend you use these symbolic
  570. /// definitions and not their integer equivalents: its possible that new values will be
  571. /// introduced in later versions (though we will try to avoid it).
  572. /// All configs use SYNC_MODE = RH_CC110_SYNC_MODE_16_16 (2 byte sync)
  573. typedef enum
  574. {
  575. GFSK_Rb1_2Fd5_2 = 0, ///< GFSK, Data Rate: 1.2kBaud, Dev: 5.2kHz, RX BW 58kHz, optimised for sensitivity
  576. GFSK_Rb2_4Fd5_2, ///< GFSK, Data Rate: 2.4kBaud, Dev: 5.2kHz, RX BW 58kHz, optimised for sensitivity
  577. GFSK_Rb4_8Fd25_4, ///< GFSK, Data Rate: 4.8kBaud, Dev: 25.4kHz, RX BW 100kHz, optimised for sensitivity
  578. GFSK_Rb10Fd19, ///< GFSK, Data Rate: 10kBaud, Dev: 19kHz, RX BW 100kHz, optimised for sensitivity
  579. GFSK_Rb38_4Fd20, ///< GFSK, Data Rate: 38.4kBaud, Dev: 20kHz, RX BW 100kHz, optimised for sensitivity
  580. GFSK_Rb76_8Fd32, ///< GFSK, Data Rate: 76.8kBaud, Dev: 32kHz, RX BW 232kHz, optimised for sensitivity
  581. GFSK_Rb100Fd47, ///< GFSK, Data Rate: 100kBaud, Dev: 47kHz, RX BW 325kHz, optimised for sensitivity
  582. GFSK_Rb250Fd127, ///< GFSK, Data Rate: 250kBaud, Dev: 127kHz, RX BW 540kHz, optimised for sensitivity
  583. } ModemConfigChoice;
  584. /// These power outputs are based on the suggested optimum values for
  585. /// multilayer inductors in the 915MHz frequency band. Per table 5-15.
  586. /// Caution: these enum values are indexes into PaPowerValues.
  587. /// Do not change one without changing the other. Use the symbolic names, not the integer values
  588. typedef enum
  589. {
  590. TransmitPowerM30dBm = 0, ///< -30dBm
  591. TransmitPowerM20dBm, ///< -20dBm
  592. TransmitPowerM15dBm, ///< -15dBm
  593. TransmitPowerM10dBm, ///< -10dBm
  594. TransmitPower0dBm, ///< 0dBm
  595. TransmitPower5dBm, ///< 5dBm
  596. TransmitPower7dBm, ///< 7dBm
  597. TransmitPower10dBm, ///< 10dBm
  598. } TransmitPower;
  599. /// Constructor. You can have multiple instances, but each instance must have its own
  600. /// interrupt and slave select pin. After constructing, you must call init() to initialise the interface
  601. /// and the radio module. A maximum of 3 instances can co-exist on one processor, provided there are sufficient
  602. /// distinct interrupt lines, one for each instance.
  603. /// \param[in] slaveSelectPin the Arduino pin number of the output to use to select the CC110L before
  604. /// accessing it. Defaults to the normal SS pin for your Arduino (D10 for Diecimila, Uno etc, D53 for Mega, D10 for Maple)
  605. /// \param[in] interruptPin The interrupt Pin number that is connected to the CC110L GDO0 interrupt line.
  606. /// Defaults to pin 2.
  607. /// Caution: You must specify an interrupt capable pin.
  608. /// On many Arduino boards, there are limitations as to which pins may be used as interrupts.
  609. /// On Leonardo pins 0, 1, 2 or 3. On Mega2560 pins 2, 3, 18, 19, 20, 21. On Due and Teensy, any digital pin.
  610. /// On other Arduinos pins 2 or 3.
  611. /// See http://arduino.cc/en/Reference/attachInterrupt for more details.
  612. /// On Chipkit Uno32, pins 38, 2, 7, 8, 35.
  613. /// On other boards, any digital pin may be used.
  614. /// \param[in] is27MHz Set to true if your CC110 is equipped with a 27MHz crystal oscillator. Defaults to false.
  615. /// \param[in] spi Pointer to the SPI interface object to use.
  616. /// Defaults to the standard Arduino hardware SPI interface
  617. RH_CC110(uint8_t slaveSelectPin = SS, uint8_t interruptPin = 2, bool is27MHz = false, RHGenericSPI& spi = hardware_spi);
  618. /// Initialise the Driver transport hardware and software.
  619. /// Make sure the Driver is properly configured before calling init().
  620. /// In particular, ensure you have called setIs27MHz(true) if your module has a 27MHz crystal oscillator.
  621. /// After init(), the following default characteristics are set:
  622. /// TxPower: TransmitPower5dBm
  623. /// Frequency: 915.0
  624. /// Modulation: GFSK_Rb1_2Fd5_2 (GFSK, Data Rate: 1.2kBaud, Dev: 5.2kHz, RX BW 58kHz, optimised for sensitivity)
  625. /// Sync Words: 0xd3, 0x91
  626. /// \return true if initialisation succeeded.
  627. virtual bool init();
  628. /// Prints the value of all chip registers
  629. /// to the Serial device if RH_HAVE_SERIAL is defined for the current platform
  630. /// For debugging purposes only.
  631. /// \return true on success
  632. bool printRegisters();
  633. /// Blocks until the current message (if any)
  634. /// has been transmitted
  635. /// \return true on success, false if the chip is not in transmit mode or other transmit failure
  636. virtual bool waitPacketSent();
  637. /// Tests whether a new message is available
  638. /// from the Driver.
  639. /// On most drivers, this will also put the Driver into RHModeRx mode until
  640. /// a message is actually received by the transport, when it will be returned to RHModeIdle
  641. /// and available() will return true.
  642. /// This can be called multiple times in a timeout loop
  643. /// \return true if a new, complete, error-free uncollected message is available to be retreived by recv()
  644. virtual bool available();
  645. /// Turns the receiver on if it not already on (after wiaint gor any currenly transmitting message to complete).
  646. /// If there is a valid message available, copy it to buf and return true
  647. /// else return false.
  648. /// If a message is copied, *len is set to the length (Caution, 0 length messages are permitted).
  649. /// You should be sure to call this function frequently enough to not miss any messages
  650. /// It is recommended that you call it in your main loop.
  651. /// \param[in] buf Location to copy the received message
  652. /// \param[in,out] len Pointer to available space in buf. Set to the actual number of octets copied.
  653. /// \return true if a valid message was copied to buf. The message cannot be retreived again.
  654. virtual bool recv(uint8_t* buf, uint8_t* len);
  655. /// Waits until any previous transmit packet is finished being transmitted with waitPacketSent().
  656. /// Then loads a message into the transmitter and starts the transmitter. Note that a message length
  657. /// of 0 is permitted.
  658. /// \param[in] data Array of data to be sent
  659. /// \param[in] len Number of bytes of data to send
  660. /// \return true if the message length was valid and it was correctly queued for transmit
  661. virtual bool send(const uint8_t* data, uint8_t len);
  662. /// Returns the maximum message length
  663. /// available in this Driver.
  664. /// \return The maximum legal message length
  665. virtual uint8_t maxMessageLength();
  666. /// If current mode is Sleep, Rx or Tx changes it to Idle. If the transmitter or receiver is running,
  667. /// disables them.
  668. void setModeIdle();
  669. /// If current mode is Tx or Idle, changes it to Rx.
  670. /// Starts the receiver. The radio will stay in Rx mode until a CRC correct message addressed to this node
  671. /// is received, or the ode is changed to Tx, Idle or Sleep.
  672. void setModeRx();
  673. /// If current mode is Rx or Idle, changes it to Tx.
  674. /// Starts the transmitter sending the current message.
  675. void setModeTx();
  676. /// Sets the radio into low-power sleep mode.
  677. /// If successful, the transport will stay in sleep mode until woken by
  678. /// changing mode to idle, transmit or receive (eg by calling send(), recv(), available() etc)
  679. /// Caution: there is a time penalty as the radio takes a finite time to wake from sleep mode.
  680. /// Caution: waking up from sleep loses values from registers 0x29 through 0x2e
  681. /// \return true if sleep mode was successfully entered.
  682. virtual bool sleep();
  683. /// Set the Power Amplifier power setting.
  684. /// The PaTable settings are based on are based on the suggested optimum values for
  685. /// multilayer inductors in the 915MHz frequency band. Per table 5-15.
  686. /// If these values are not suitable, use setPaTable() directly.
  687. /// Caution: be a good neighbour and use the lowest power setting compatible with your application.
  688. /// Caution: Permissable power settings for your area may depend on frequency and modulation characteristics:
  689. /// consult local authorities.
  690. /// param[in] power One of TransmitPower enum values
  691. bool setTxPower(TransmitPower power);
  692. /// Indicates the presence of 27MHz crystal oscillator.
  693. /// You must indicate to the driver if your CC110L is equipped with a 27MHz crystal oscillator (26MHz is the default
  694. /// in the constructor).
  695. /// This should be called before calling init() if you have a 27MHz crystal.
  696. /// It can be called after calling init() but you must reset the frequency (with setFrequency()) and modulation
  697. /// (with setModemConfig()) afterwards.
  698. /// \param[in] is27MHz Pass true if the CC110L has a 27MHz crystal (default is true).
  699. void setIs27MHz(bool is27MHz = true);
  700. /// Sets the transmitter and receiver
  701. /// centre frequency.
  702. /// Caution: permissable frequency bands will depend on you country and area: consult local authorities.
  703. /// \param[in] centre Frequency in MHz. 300.0 to 928.0
  704. /// \return true if the selected frquency centre is within range
  705. bool setFrequency(float centre);
  706. /// Sets all the registers required to configure the data modem in the CC110, including the data rate,
  707. /// bandwidths etc. You cas use this to configure the modem with custom configuraitons if none of the
  708. /// canned configurations in ModemConfigChoice suit you.
  709. /// \param[in] config A ModemConfig structure containing values for the modem configuration registers.
  710. void setModemRegisters(const ModemConfig* config);
  711. /// Select one of the predefined modem configurations. If you need a modem configuration not provided
  712. /// here, use setModemRegisters() with your own ModemConfig.
  713. /// \param[in] index The configuration choice.
  714. /// \return true if index is a valid choice.
  715. bool setModemConfig(ModemConfigChoice index);
  716. /// Sets the sync words for transmit and receive in registers RH_CC110_REG_04_SYNC1 and RH_CC110_REG_05_SYNC0.
  717. /// Caution: SyncWords should be set to the same
  718. /// value on all nodes in your network. Nodes with different SyncWords set will never receive
  719. /// each others messages, so different SyncWords can be used to isolate different
  720. /// networks from each other. Default is { 0xd3, 0x91 }.
  721. /// \param[in] syncWords Array of sync words, 2 octets long
  722. /// \param[in] len Number of sync words to set. MUST be 2.
  723. void setSyncWords(const uint8_t* syncWords, uint8_t len);
  724. protected:
  725. /// This is a low level function to handle the interrupts for one instance of RH_RF95.
  726. /// Called automatically by isr*()
  727. /// Should not need to be called by user code.
  728. void handleInterrupt();
  729. /// Reads a single register from the CC110L
  730. /// \param[in] reg Register number, one of RH_CC110_REG
  731. /// \return The value of the register
  732. uint8_t spiReadRegister(uint8_t reg);
  733. /// Reads a single register in burst mode.
  734. /// On the CC110L, some registers yield different data when read in burst mode
  735. /// as opposed to single byte mode.
  736. /// \param[in] reg Register number, one of RH_CC110_REG (burst mode readable)
  737. /// \return The value of the register after a burst read
  738. uint8_t spiBurstReadRegister(uint8_t reg);
  739. /// Writes to a single single register on the CC110L
  740. /// \param[in] reg Register number, one of RH_CC110L_REG_*
  741. /// \param[in] val The value to write
  742. /// \return returns the chip status byte per table 5.2
  743. uint8_t spiWriteRegister(uint8_t reg, uint8_t val);
  744. /// Write a number of bytes to a burst capable register
  745. /// \param[in] reg Register number of the first register, one of RH_CC110L_REG_*
  746. /// \param[in] src Array of new register values to write. Must be at least len bytes
  747. /// \param[in] len Number of bytes to write
  748. /// \return the chip status byte per table 5.2
  749. uint8_t spiBurstWriteRegister(uint8_t reg, const uint8_t* src, uint8_t len);
  750. /// Examine the receive buffer to determine whether the message is for this node
  751. /// Sets _rxBufValid.
  752. void validateRxBuf();
  753. /// Clear our local receive buffer
  754. void clearRxBuf();
  755. /// Reads and returns the status byte by issuing the SNOP strobe
  756. /// \return The value of the status byte per Table 5-2
  757. uint8_t statusRead();
  758. /// Sets the PaTable registers directly.
  759. /// Ensure you use suitable PATABLE values per Tbale 5-15 or 5-16
  760. /// You may need to do this to implement an OOK modulation scheme.
  761. void setPaTable(uint8_t* patable, uint8_t patablesize);
  762. private:
  763. /// Low level interrupt service routine for device connected to interrupt 0
  764. static void isr0();
  765. /// Low level interrupt service routine for device connected to interrupt 1
  766. static void isr1();
  767. /// Low level interrupt service routine for device connected to interrupt 1
  768. static void isr2();
  769. /// Array of instances connected to interrupts 0 and 1
  770. static RH_CC110* _deviceForInterrupt[];
  771. /// Index of next interrupt number to use in _deviceForInterrupt
  772. static uint8_t _interruptCount;
  773. /// The configured interrupt pin connected to this instance
  774. uint8_t _interruptPin;
  775. /// The index into _deviceForInterrupt[] for this device (if an interrupt is already allocated)
  776. /// else 0xff
  777. uint8_t _myInterruptIndex;
  778. /// Number of octets in the buffer
  779. volatile uint8_t _bufLen;
  780. /// The receiver/transmitter buffer
  781. uint8_t _buf[RH_CC110_MAX_PAYLOAD_LEN];
  782. /// True when there is a valid message in the buffer
  783. volatile bool _rxBufValid;
  784. /// True if crystal oscillator is 26 MHz, not 26MHz.
  785. bool _is27MHz;
  786. };
  787. /// @example cc110_client.pde
  788. /// @example cc110_server.pde
  789. #endif