antplus_lev.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. /*
  2. This software is subject to the license described in the License.txt file
  3. included with this software distribution. You may not use this file except in compliance
  4. with this license.
  5. Copyright (c) Dynastream Innovations Inc. 2012
  6. All rights reserved.
  7. */
  8. #pragma once
  9. #include "types.h"
  10. #define LEV_REV 0.5 // Device Profile Revision Number that this was written to
  11. public ref class LEV
  12. {
  13. public:
  14. // Channel Parameters
  15. static const UCHAR DEVICE_TYPE = 20;
  16. static const UCHAR TX_TYPE = 5;
  17. static const USHORT MSG_PERIOD = 8192; // 4 Hz
  18. // Data Pages
  19. static const UCHAR PAGE1_SPEED_SYSTEM1 = 0x01;
  20. static const UCHAR PAGE2_SPEED_DISTANCE = 0x02;
  21. static const UCHAR PAGE3_SPEED_SYSTEM2 = 0x03;
  22. static const UCHAR PAGE4_BATTERY = 0x04;
  23. static const UCHAR PAGE5_CAPABILITES = 0x05;
  24. static const UCHAR PAGE16_DISPLAY_DATA = 0x10;
  25. static const UCHAR PAGE34_SPEED_DISTANCE = 0x22;
  26. static const UCHAR PAGE70_REQUEST = 0x46;
  27. // Acknowledged Messages
  28. static const UCHAR ACK_FAIL = 0;
  29. static const UCHAR ACK_SUCCESS = 1;
  30. static const UCHAR ACK_RETRY = 2;
  31. static const UCHAR MAX_RETRIES = 10; // defines the max number of times to retry before failing
  32. // Reserved/invalid values
  33. static const UCHAR RESERVED = 0xFF;
  34. // Bit Masks
  35. static const UCHAR BYTE_MASK = 0xFF;
  36. // Defines how often to send common pages (every 20th message)
  37. static const UCHAR LEV_COMMON_INTERVAL = 20;
  38. public:
  39. // LEV Data Page 1
  40. UCHAR ucTemperature; // Indicates current motor / battery temperature (0 = unsued)
  41. UCHAR ucTravelModeState; // Indicates the LEV's current travel mode
  42. UCHAR ucSystemState; // Indicates the current state of the LEV's peripheral sustem
  43. UCHAR ucGearState; // Indicates the current state of the LEV's gears
  44. UCHAR ucErrorMessage; // Indicates LEV error
  45. USHORT usCurrentLEVSpeed; // Instantaneous speed (0.1 km/hr), shared between page1 and page2
  46. // LEV Data Page 2
  47. ULONG ulOdometer; // 3 bytes, accumulated total distance (0.01 km)
  48. USHORT usRemainingRange; // Remaining range of the LEV battery (km)
  49. // LEV Data Page 3
  50. UCHAR ucBatteryCharge; // State of battery charge (0-100%)
  51. UCHAR ucPercentAssist; // Percent assistance the LEV motor is providing (0-100%)
  52. // LEV Data Page 4
  53. USHORT usChargeCycleCount; // Tracks the number of charge cycles the LEV has gone through
  54. USHORT usFuelConsumption; // Tracks the current rate of battery fuel consumption in watt-hours per km
  55. UCHAR ucBatteryVoltage; // Measured battery voltage (0 = unsued)
  56. USHORT usDistanceOnCharge; // Tracks the distance in km the LEV has traveled on the current charge
  57. // LEV Data Page 5
  58. UCHAR ucSupportedTravelModes; // Travel Modes Supported bit field
  59. USHORT usWheelCircumference; // Holds the wheel cirumference of the LEV in mm
  60. // LEV Data Page 16
  61. USHORT usP16WheelCircum; // Used to set the wheel circumference
  62. UCHAR ucP16TravelMode; // Indicates the current travel mode set/requested
  63. USHORT usP16DisplayCommand; // Command sent from the Display to the LEV
  64. USHORT usP16ManID; // Manufacturer ID of the Display
  65. //LEV Data Page 34
  66. ULONG ulP34Odometer; // Accumulated total distance travelled
  67. USHORT usP34FuelConsumption; // Indicates current rate of battery fuel consumption in watt-hrs per km.
  68. USHORT usSpeed; // Current LEV speed
  69. // LEV Data Page 70
  70. UCHAR ucP70TxTimes; // number of times the sensor should send the requested pages (broadcast only supported on LEV)
  71. UCHAR ucP70RequestedPage; // holds the page number to be requested
  72. public:
  73. LEV()
  74. {
  75. // initialize variables to invalid / zero
  76. ucTravelModeState = 0;
  77. ucSystemState = 0;
  78. ucGearState = 0;
  79. ucErrorMessage = 0;
  80. usCurrentLEVSpeed = 0;
  81. ucPercentAssist = 0;
  82. ulOdometer = 0;
  83. ucTemperature = 0;
  84. ucBatteryCharge = 0;
  85. usRemainingRange = 0;
  86. usChargeCycleCount = 0;
  87. usFuelConsumption = 0;
  88. ucBatteryVoltage = 0;
  89. usDistanceOnCharge = 0;
  90. ucSupportedTravelModes = 0;
  91. usWheelCircumference = 0;
  92. usP16WheelCircum = 0xFF;
  93. ucP16TravelMode = 0xFF;
  94. usP16DisplayCommand = 0;
  95. usP16ManID = 0;
  96. ulP34Odometer = 0;
  97. usP34FuelConsumption = 0;
  98. usSpeed = 0;
  99. ucP70TxTimes = 0;
  100. ucP70RequestedPage = 0;
  101. }
  102. ~LEV()
  103. {
  104. }
  105. public:
  106. /**************************************************************************
  107. * LEV::Decode
  108. *
  109. * Decodes all main data pages
  110. * Exceptions are thrown when dealing with non compliant pages
  111. * Further breakdowns inside the fields are dealt with in the display method
  112. *
  113. * pucRxBuffer_: pointer to the buffer containing the received data
  114. *
  115. * returns: N/A
  116. *
  117. **************************************************************************/
  118. void Decode(UCHAR* pucRxBuffer_)
  119. {
  120. ULONG ulTempHolder = 0;
  121. switch(pucRxBuffer_[0])
  122. {
  123. case PAGE1_SPEED_SYSTEM1:
  124. ucTemperature = pucRxBuffer_[1];
  125. ucTravelModeState = pucRxBuffer_[2];
  126. ucSystemState = pucRxBuffer_[3];
  127. ucGearState = pucRxBuffer_[4];
  128. ucErrorMessage = pucRxBuffer_[5];
  129. usCurrentLEVSpeed = pucRxBuffer_[6] | ((pucRxBuffer_[7] & 0x0F) << 8); // mask off the top bits which are reserved
  130. break;
  131. case PAGE2_SPEED_DISTANCE:
  132. ulOdometer = pucRxBuffer_[1]; // odometer LSB
  133. ulTempHolder = pucRxBuffer_[2] & 0xFF; // odometer
  134. ulOdometer = ulOdometer | (ulTempHolder << 8);
  135. ulTempHolder = pucRxBuffer_[3] & 0xFF; // odometer MSB
  136. ulOdometer = ulOdometer | (ulTempHolder << 16);
  137. usRemainingRange = pucRxBuffer_[4] | ((pucRxBuffer_[5] & 0x0F) << 8); // mask off top bits of byte 5 which are reserved
  138. usCurrentLEVSpeed = pucRxBuffer_[6] | ((pucRxBuffer_[7] & 0x0F) << 8); // mask off the top bits which are reserved
  139. break;
  140. case PAGE3_SPEED_SYSTEM2:
  141. ucBatteryCharge = pucRxBuffer_[1];
  142. ucTravelModeState = pucRxBuffer_[2];
  143. ucSystemState = pucRxBuffer_[3];
  144. ucGearState = pucRxBuffer_[4];
  145. ucPercentAssist = pucRxBuffer_[5];
  146. usCurrentLEVSpeed = pucRxBuffer_[6] | ((pucRxBuffer_[7] & 0x0F) << 8); // mask off the top bits which are reserved
  147. break;
  148. case PAGE4_BATTERY:
  149. usChargeCycleCount = pucRxBuffer_[2] | ((pucRxBuffer_[3] & 0x0F) << 8); // mask off top bits of byte 3 which are part of fuel consumption
  150. usFuelConsumption = pucRxBuffer_[4] | (((pucRxBuffer_[3] & 0xF0) >> 4) << 8); // LSB of fuel consumption is byte 4
  151. ucBatteryVoltage = pucRxBuffer_[5];
  152. usDistanceOnCharge = pucRxBuffer_[6] | (pucRxBuffer_[7] << 8);
  153. break;
  154. case PAGE5_CAPABILITES:
  155. ucSupportedTravelModes = pucRxBuffer_[2];
  156. usWheelCircumference = pucRxBuffer_[3] | ((pucRxBuffer_[4] & 0x0F) << 8);
  157. break;
  158. case PAGE16_DISPLAY_DATA:
  159. usP16WheelCircum = pucRxBuffer_[1] | ((pucRxBuffer_[2] & 0x0F) << 8);
  160. ucP16TravelMode = pucRxBuffer_[3];
  161. usP16DisplayCommand = pucRxBuffer_[4] | (pucRxBuffer_[5] << 8);
  162. usP16ManID = pucRxBuffer_[6] | (pucRxBuffer_[7] << 8);
  163. break;
  164. case PAGE34_SPEED_DISTANCE:
  165. ulP34Odometer = pucRxBuffer_[1] | ((pucRxBuffer_[2] & 0xFF) << 8 ) | ((pucRxBuffer_[3] & 0xFF) << 16);
  166. usP34FuelConsumption = (pucRxBuffer_[4] | ((pucRxBuffer_[5] & 0xFF) << 8)) & 0x0FFF;
  167. usSpeed = (pucRxBuffer_[6] | ((pucRxBuffer_[7] & 0xFF) << 8)) & 0x0FFF;
  168. break;
  169. default:
  170. break;
  171. }
  172. }
  173. /**************************************************************************
  174. * LEV::EncodeData
  175. *
  176. * Encodes the LEV data pages:
  177. * - Data Page 1 - Speed and System Information 1
  178. * - Data Page 2 - Speed and Distance Information
  179. * - Data Page 3 - Speed and System Information 2
  180. * - Data Page 4 - Battery Info
  181. * - Data Page 5 - Capabilities
  182. * - Data Page 16 - Display Data
  183. * - Data Page 70 - Request Data
  184. *
  185. * Exceptions are thrown when dealing with invalid data
  186. *
  187. * ucPageNum_: number of page to encode
  188. * pucTxBuffer_: pointer to the buffer that will store the encoded data
  189. *
  190. * returns: N/A
  191. *
  192. **************************************************************************/
  193. void EncodeData(UCHAR ucPageNum_, UCHAR* pucTxBuffer_)
  194. {
  195. switch(ucPageNum_)
  196. {
  197. case PAGE1_SPEED_SYSTEM1:
  198. pucTxBuffer_[0] = ucPageNum_; // page number
  199. pucTxBuffer_[1] = ucTemperature; // current temperature state
  200. pucTxBuffer_[2] = ucTravelModeState; // current travel mode
  201. pucTxBuffer_[3] = ucSystemState; // current state of peripheral system
  202. pucTxBuffer_[4] = ucGearState; // current state of gears
  203. pucTxBuffer_[5] = ucErrorMessage; // LEV error
  204. pucTxBuffer_[6] = usCurrentLEVSpeed & BYTE_MASK; // mask off top byte
  205. pucTxBuffer_[7] = (usCurrentLEVSpeed >> 8) & 0x0FFF; // shift top down and mask off top
  206. break;
  207. case PAGE2_SPEED_DISTANCE:
  208. pucTxBuffer_[0] = ucPageNum_;
  209. pucTxBuffer_[1] = ulOdometer & BYTE_MASK; // accum distance
  210. pucTxBuffer_[2] = (ulOdometer >> 8) & BYTE_MASK;
  211. pucTxBuffer_[3] = (ulOdometer >> 16) & BYTE_MASK;
  212. pucTxBuffer_[4] = usRemainingRange & BYTE_MASK; // mask off top byte
  213. pucTxBuffer_[5] = (usRemainingRange >> 8) & 0x0FFF; // shift top down and mask off top
  214. pucTxBuffer_[6] = usCurrentLEVSpeed & BYTE_MASK; // mask off top byte
  215. pucTxBuffer_[7] = (usCurrentLEVSpeed >> 8) & 0x0FFF; // shift top down and mask off top
  216. break;
  217. case PAGE3_SPEED_SYSTEM2:
  218. pucTxBuffer_[0] = ucPageNum_;
  219. pucTxBuffer_[1] = ucBatteryCharge; // battery charge
  220. pucTxBuffer_[2] = ucTravelModeState; // current travel mode
  221. pucTxBuffer_[3] = ucSystemState; // current state of peripheral system
  222. pucTxBuffer_[4] = ucGearState; // current state of gears
  223. pucTxBuffer_[5] = ucPercentAssist; // percent assist of motor
  224. pucTxBuffer_[6] = usCurrentLEVSpeed & BYTE_MASK; // mask off top byte
  225. pucTxBuffer_[7] = (usCurrentLEVSpeed >> 8) & 0x0FFF; // shift top down and mask off top
  226. break;
  227. case PAGE4_BATTERY:
  228. pucTxBuffer_[0] = ucPageNum_; // page number
  229. pucTxBuffer_[1] = RESERVED;
  230. pucTxBuffer_[2] = usChargeCycleCount & BYTE_MASK; // mask off top byte
  231. pucTxBuffer_[3] = ((usChargeCycleCount >> 8) | (usFuelConsumption >> 4) & 0xF0); // msn for both
  232. pucTxBuffer_[4] = usFuelConsumption & BYTE_MASK; // mask off top byte
  233. pucTxBuffer_[5] = ucBatteryVoltage; // battery voltage
  234. pucTxBuffer_[6] = usDistanceOnCharge & BYTE_MASK; // mask off top byte
  235. pucTxBuffer_[7] = (usDistanceOnCharge >> 8) & BYTE_MASK; // shift top down and mask off top
  236. break;
  237. case PAGE5_CAPABILITES:
  238. pucTxBuffer_[0] = ucPageNum_; // page number
  239. pucTxBuffer_[1] = RESERVED;
  240. pucTxBuffer_[2] = ucSupportedTravelModes; // travel modes supported
  241. pucTxBuffer_[3] = usWheelCircumference & BYTE_MASK; // mask off top byte
  242. pucTxBuffer_[4] = (usWheelCircumference >> 8) & 0x0FFF; // shift top down and mask off top
  243. pucTxBuffer_[5] = RESERVED;
  244. pucTxBuffer_[6] = RESERVED;
  245. pucTxBuffer_[7] = RESERVED;
  246. break;
  247. case PAGE16_DISPLAY_DATA:
  248. pucTxBuffer_[0] = ucPageNum_;
  249. pucTxBuffer_[1] = usP16WheelCircum & BYTE_MASK; // mask off top byte
  250. pucTxBuffer_[2] = (usP16WheelCircum >> 8) & 0x0FFF; // shift top down and mask off top
  251. pucTxBuffer_[3] = ucP16TravelMode; // current travel mode
  252. pucTxBuffer_[4] = usP16DisplayCommand & BYTE_MASK; // mask off top byte
  253. pucTxBuffer_[5] = (usP16DisplayCommand >> 8) & BYTE_MASK; // shift top down and mask off top
  254. pucTxBuffer_[6] = usP16ManID & BYTE_MASK; // mask off top byte
  255. pucTxBuffer_[7] = (usP16ManID >> 8) & BYTE_MASK; // shift top down and mask off top
  256. break;
  257. case PAGE34_SPEED_DISTANCE:
  258. pucTxBuffer_[0] = ucPageNum_;
  259. pucTxBuffer_[1] = ulP34Odometer & BYTE_MASK;
  260. pucTxBuffer_[2] = (ulP34Odometer >> 8) & BYTE_MASK;
  261. pucTxBuffer_[3] = (ulP34Odometer >> 16) & BYTE_MASK;
  262. pucTxBuffer_[4] = usP34FuelConsumption & BYTE_MASK;
  263. pucTxBuffer_[5] = ((usFuelConsumption >> 8) & BYTE_MASK) | 0xF0;
  264. pucTxBuffer_[6] = usSpeed & BYTE_MASK;
  265. pucTxBuffer_[7] = ((usSpeed >> 8) & BYTE_MASK) | 0xF0;
  266. break;
  267. case PAGE70_REQUEST:
  268. pucTxBuffer_[0] = ucPageNum_;
  269. pucTxBuffer_[1] = RESERVED;
  270. pucTxBuffer_[2] = RESERVED;
  271. pucTxBuffer_[3] = RESERVED;
  272. pucTxBuffer_[4] = RESERVED;
  273. pucTxBuffer_[5] = ucP70TxTimes; // number of times the sensor should send the requested pages (broadcast only supported on LEV)
  274. pucTxBuffer_[6] = ucP70RequestedPage; // this is the page number that the display is requesting
  275. pucTxBuffer_[7] = 0x01; // always 0x01 for Request Data Page
  276. break;
  277. default:
  278. break;
  279. }
  280. }
  281. };