AP_GPS_SIRF.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. /*
  2. This program is free software: you can redistribute it and/or modify
  3. it under the terms of the GNU General Public License as published by
  4. the Free Software Foundation, either version 3 of the License, or
  5. (at your option) any later version.
  6. This program is distributed in the hope that it will be useful,
  7. but WITHOUT ANY WARRANTY; without even the implied warranty of
  8. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  9. GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License
  11. along with this program. If not, see <http://www.gnu.org/licenses/>.
  12. */
  13. //
  14. // SiRF Binary GPS driver for ArduPilot and ArduPilotMega.
  15. // Code by Michael Smith.
  16. //
  17. #include "AP_GPS_SIRF.h"
  18. #include <stdint.h>
  19. // Initialisation messages
  20. //
  21. // Turn off all messages except for 0x29.
  22. //
  23. // XXX the bytes show up on the wire, but at least my test unit (EM-411) seems to ignore them.
  24. //
  25. const uint8_t AP_GPS_SIRF::_initialisation_blob[] = {
  26. 0xa0, 0xa2, 0x00, 0x08, 0xa6, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xb0, 0xb3,
  27. 0xa0, 0xa2, 0x00, 0x08, 0xa6, 0x00, 0x29, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xb0, 0xb3
  28. };
  29. AP_GPS_SIRF::AP_GPS_SIRF(AP_GPS &_gps, AP_GPS::GPS_State &_state, AP_HAL::UARTDriver *_port) :
  30. AP_GPS_Backend(_gps, _state, _port)
  31. {
  32. gps.send_blob_start(state.instance, (const char *)_initialisation_blob, sizeof(_initialisation_blob));
  33. }
  34. // Process bytes available from the stream
  35. //
  36. // The stream is assumed to contain only messages we recognise. If it
  37. // contains other messages, and those messages contain the preamble
  38. // bytes, it is possible for this code to fail to synchronise to the
  39. // stream immediately. Without buffering the entire message and
  40. // re-processing it from the top, this is unavoidable. The parser
  41. // attempts to avoid this when possible.
  42. //
  43. bool
  44. AP_GPS_SIRF::read(void)
  45. {
  46. uint8_t data;
  47. int16_t numc;
  48. bool parsed = false;
  49. numc = port->available();
  50. while(numc--) {
  51. // read the next byte
  52. data = port->read();
  53. switch(_step) {
  54. // Message preamble detection
  55. //
  56. // If we fail to match any of the expected bytes, we reset
  57. // the state machine and re-consider the failed byte as
  58. // the first byte of the preamble. This improves our
  59. // chances of recovering from a mismatch and makes it less
  60. // likely that we will be fooled by the preamble appearing
  61. // as data in some other message.
  62. //
  63. case 1:
  64. if (PREAMBLE2 == data) {
  65. _step++;
  66. break;
  67. }
  68. _step = 0;
  69. FALLTHROUGH;
  70. case 0:
  71. if(PREAMBLE1 == data)
  72. _step++;
  73. break;
  74. // Message length
  75. //
  76. // We always collect the length so that we can avoid being
  77. // fooled by preamble bytes in messages.
  78. //
  79. case 2:
  80. _step++;
  81. _payload_length = (uint16_t)data << 8;
  82. break;
  83. case 3:
  84. _step++;
  85. _payload_length |= data;
  86. _payload_counter = 0;
  87. _checksum = 0;
  88. break;
  89. // Message header processing
  90. //
  91. // We sniff the message ID to determine whether we are going
  92. // to gather the message bytes or just discard them.
  93. //
  94. case 4:
  95. _step++;
  96. _accumulate(data);
  97. _payload_length--;
  98. _gather = false;
  99. switch(data) {
  100. case MSG_GEONAV:
  101. if (_payload_length == sizeof(sirf_geonav)) {
  102. _gather = true;
  103. _msg_id = data;
  104. }
  105. break;
  106. }
  107. break;
  108. // Receive message data
  109. //
  110. // Note that we are effectively guaranteed by the protocol
  111. // that the checksum and postamble cannot be mistaken for
  112. // the preamble, so if we are discarding bytes in this
  113. // message when the payload is done we return directly
  114. // to the preamble detector rather than bothering with
  115. // the checksum logic.
  116. //
  117. case 5:
  118. if (_gather) { // gather data if requested
  119. _accumulate(data);
  120. _buffer[_payload_counter] = data;
  121. if (++_payload_counter == _payload_length)
  122. _step++;
  123. } else {
  124. if (++_payload_counter == _payload_length)
  125. _step = 0;
  126. }
  127. break;
  128. // Checksum and message processing
  129. //
  130. case 6:
  131. _step++;
  132. if ((_checksum >> 8) != data) {
  133. _step = 0;
  134. }
  135. break;
  136. case 7:
  137. _step = 0;
  138. if ((_checksum & 0xff) != data) {
  139. break;
  140. }
  141. if (_gather) {
  142. parsed = _parse_gps(); // Parse the new GPS packet
  143. }
  144. }
  145. }
  146. return(parsed);
  147. }
  148. bool
  149. AP_GPS_SIRF::_parse_gps(void)
  150. {
  151. switch(_msg_id) {
  152. case MSG_GEONAV:
  153. //time = _swapl(&_buffer.nav.time);
  154. // parse fix type
  155. if (_buffer.nav.fix_invalid) {
  156. state.status = AP_GPS::NO_FIX;
  157. }else if ((_buffer.nav.fix_type & FIX_MASK) == FIX_3D) {
  158. state.status = AP_GPS::GPS_OK_FIX_3D;
  159. }else{
  160. state.status = AP_GPS::GPS_OK_FIX_2D;
  161. }
  162. state.location.lat = swap_int32(_buffer.nav.latitude);
  163. state.location.lng = swap_int32(_buffer.nav.longitude);
  164. state.location.alt = swap_int32(_buffer.nav.altitude_msl);
  165. state.ground_speed = swap_int32(_buffer.nav.ground_speed)*0.01f;
  166. state.ground_course = wrap_360(swap_int16(_buffer.nav.ground_course)*0.01f);
  167. state.num_sats = _buffer.nav.satellites;
  168. fill_3d_velocity();
  169. return true;
  170. }
  171. return false;
  172. }
  173. void
  174. AP_GPS_SIRF::_accumulate(uint8_t val)
  175. {
  176. _checksum = (_checksum + val) & 0x7fff;
  177. }
  178. /*
  179. detect a SIRF GPS
  180. */
  181. bool AP_GPS_SIRF::_detect(struct SIRF_detect_state &state, uint8_t data)
  182. {
  183. switch (state.step) {
  184. case 1:
  185. if (PREAMBLE2 == data) {
  186. state.step++;
  187. break;
  188. }
  189. state.step = 0;
  190. FALLTHROUGH;
  191. case 0:
  192. state.payload_length = state.payload_counter = state.checksum = 0;
  193. if (PREAMBLE1 == data)
  194. state.step++;
  195. break;
  196. case 2:
  197. state.step++;
  198. if (data != 0) {
  199. // only look for short messages
  200. state.step = 0;
  201. }
  202. break;
  203. case 3:
  204. state.step++;
  205. state.payload_length = data;
  206. break;
  207. case 4:
  208. state.checksum = (state.checksum + data) & 0x7fff;
  209. if (++state.payload_counter == state.payload_length) {
  210. state.step++;
  211. }
  212. break;
  213. case 5:
  214. state.step++;
  215. if ((state.checksum >> 8) != data) {
  216. state.step = 0;
  217. }
  218. break;
  219. case 6:
  220. state.step = 0;
  221. if ((state.checksum & 0xff) == data) {
  222. return true;
  223. }
  224. }
  225. return false;
  226. }