ublox.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. //
  2. // Created by SQ5RWU on 2016-12-27.
  3. //
  4. #include <stm32f10x_usart.h>
  5. #include <string.h>
  6. #include "ublox.h"
  7. #include "delay.h"
  8. #include "init.h"
  9. GPSEntry currentGPSData;
  10. volatile uint8_t active = 0;
  11. volatile uint8_t ack_received = 0;
  12. volatile uint8_t nack_received = 0;
  13. void _sendSerialByte (uint8_t message)
  14. {
  15. while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) continue;
  16. USART_SendData(USART1, message);
  17. while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) continue;
  18. }
  19. void send_ublox (uint8_t msgClass, uint8_t msgId, uint8_t *payload, uint16_t payloadSize)
  20. {
  21. uBloxChecksum chksum = ublox_calc_checksum(msgClass, msgId, payload, payloadSize);
  22. _sendSerialByte(0xB5);
  23. _sendSerialByte(0x62);
  24. _sendSerialByte(msgClass);
  25. _sendSerialByte(msgId);
  26. _sendSerialByte((uint8_t) (payloadSize & 0xff));
  27. _sendSerialByte((uint8_t) (payloadSize >> 8));
  28. uint16_t i;
  29. for (i = 0; i < payloadSize; ++i)
  30. _sendSerialByte(payload[i]);
  31. _sendSerialByte(chksum.ck_a);
  32. _sendSerialByte(chksum.ck_b);
  33. }
  34. void send_ublox_packet(uBloxPacket * packet)
  35. {
  36. send_ublox(packet->header.messageClass, packet->header.messageId, (uint8_t*)&packet->data, packet->header.payloadSize);
  37. }
  38. uBloxChecksum ublox_calc_checksum (const uint8_t msgClass, const uint8_t msgId, const uint8_t *message, uint16_t size)
  39. {
  40. uBloxChecksum ck = {0, 0};
  41. uint8_t i;
  42. ck.ck_a += msgClass;
  43. ck.ck_b += ck.ck_a;
  44. ck.ck_a += msgId;
  45. ck.ck_b += ck.ck_a;
  46. ck.ck_a += size & 0xff;
  47. ck.ck_b += ck.ck_a;
  48. ck.ck_a += size >> 8;
  49. ck.ck_b += ck.ck_a;
  50. for (i =0; i<size; i++)
  51. {
  52. ck.ck_a += message[i];
  53. ck.ck_b += ck.ck_a;
  54. }
  55. return ck;
  56. }
  57. void ublox_get_last_data (GPSEntry * gpsEntry)
  58. {
  59. __disable_irq();
  60. memcpy(gpsEntry, &currentGPSData, sizeof(GPSEntry));
  61. __enable_irq();
  62. }
  63. void ublox_init (void)
  64. {
  65. uBloxPacket msgcfgrst = { .header = {0xb5, 0x62, .messageClass=0x06, .messageId=0x04, .payloadSize=sizeof(uBloxCFGRSTPayload) },
  66. .data.cfgrst = { .navBbrMask=0xffff, .resetMode=1, .reserved1 = 0} };
  67. init_usart_gps (38400, 1);
  68. _delay_ms (10);
  69. send_ublox_packet (&msgcfgrst);
  70. _delay_ms (800);
  71. init_usart_gps (9600, 1);
  72. _delay_ms (10);
  73. send_ublox_packet (&msgcfgrst);
  74. _delay_ms (800);
  75. uBloxPacket msgcgprt = { .header = {0xb5, 0x62, .messageClass=0x06, .messageId=0x00, .payloadSize=sizeof(uBloxCFGPRTPayload) },
  76. .data.cfgprt = { .portID=1, .reserved1=0, .txReady=0, .mode=0b00100011000000, .baudRate=38400,
  77. .inProtoMask=1, .outProtoMask=1, .flags=0, .reserved2={0,0} } };
  78. send_ublox_packet (&msgcgprt);
  79. init_usart_gps (38400, 1);
  80. _delay_ms (10);
  81. uBloxPacket msgcfgrxm = { .header = {0xb5, 0x62, .messageClass=0x06, .messageId=0x11, .payloadSize=sizeof(uBloxCFGRXMPayload) },
  82. .data.cfgrxm = {.reserved1=8, .lpMode=4} };
  83. do
  84. send_ublox_packet (&msgcfgrxm);
  85. while (!ublox_wait_for_ack());
  86. uBloxPacket msgcfgmsg = { .header = {0xb5, 0x62, .messageClass=0x06, .messageId=0x01, .payloadSize=sizeof(uBloxCFGMSGPayload) },
  87. .data.cfgmsg = {.msgClass=0x01, .msgID=0x02, .rate=1} };
  88. do
  89. send_ublox_packet(&msgcfgmsg);
  90. while (!ublox_wait_for_ack());
  91. msgcfgmsg.data.cfgmsg.msgID = 0x6;
  92. do
  93. send_ublox_packet(&msgcfgmsg);
  94. while (!ublox_wait_for_ack());
  95. msgcfgmsg.data.cfgmsg.msgID = 0x21;
  96. do
  97. send_ublox_packet(&msgcfgmsg);
  98. while (!ublox_wait_for_ack());
  99. uBloxPacket msgcfgnav5 = { .header = {0xb5, 0x62, .messageClass=0x06, .messageId=0x24, .payloadSize=sizeof(uBloxCFGNAV5Payload) },
  100. .data.cfgnav5={ .mask=0b00000001111111111, .dynModel=7, .fixMode=2, .fixedAlt=0, .fixedAltVar=10000,
  101. .minElev=5, .drLimit=0, .pDop=25, .tDop=25, .pAcc=100, .tAcc=300, .staticHoldThresh=0,
  102. .dgpsTimeOut=2, .reserved2=0, .reserved3=0, .reserved4=0}};
  103. do
  104. send_ublox_packet(&msgcfgnav5);
  105. while (!ublox_wait_for_ack());
  106. }
  107. void ublox_handle_incoming_byte (uint8_t data)
  108. {
  109. static uint8_t sync = 0;
  110. static uint8_t buffer_pos = 0;
  111. static uint8_t incoming_packet_buffer[sizeof(uBloxPacket) + sizeof(uBloxChecksum)];
  112. static uBloxPacket * incoming_packet = (uBloxPacket *) incoming_packet_buffer;
  113. if (!sync)
  114. {
  115. if (!buffer_pos && data == 0xB5)
  116. {
  117. buffer_pos = 1;
  118. incoming_packet->header.sc1 = data;
  119. }
  120. else
  121. if (buffer_pos == 1 && data == 0x62)
  122. {
  123. sync = 1;
  124. buffer_pos = 2;
  125. incoming_packet->header.sc2 = data;
  126. }
  127. else
  128. buffer_pos = 0;
  129. }
  130. else
  131. {
  132. ((uint8_t *)incoming_packet)[buffer_pos] = data;
  133. if ((buffer_pos >= sizeof(uBloxHeader)-1) &&
  134. (buffer_pos-1 == (incoming_packet->header.payloadSize + sizeof(uBloxHeader) + sizeof(uBloxChecksum))))
  135. {
  136. ublox_handle_packet((uBloxPacket *) incoming_packet);
  137. buffer_pos = 0;
  138. sync = 0;
  139. }
  140. else
  141. {
  142. buffer_pos++;
  143. if (buffer_pos >= sizeof(uBloxPacket) + sizeof(uBloxChecksum))
  144. {
  145. buffer_pos = 0;
  146. sync = 0;
  147. }
  148. }
  149. }
  150. }
  151. void ublox_handle_packet(uBloxPacket *pkt)
  152. {
  153. uBloxChecksum cksum = ublox_calc_checksum(pkt->header.messageClass, pkt->header.messageId, (const uint8_t *) &pkt->data, pkt->header.payloadSize);
  154. uBloxChecksum *checksum = (uBloxChecksum *)(((uint8_t*)&pkt->data) + pkt->header.payloadSize);
  155. if (cksum.ck_a != checksum->ck_a || cksum.ck_b != checksum->ck_b)
  156. currentGPSData.bad_packets += 1;
  157. else
  158. {
  159. if (pkt->header.messageClass == 0x01 && pkt->header.messageId == 0x07)
  160. {
  161. currentGPSData.ok_packets += 1;
  162. currentGPSData.fix = pkt->data.navpvt.fixType;
  163. currentGPSData.lat_raw = pkt->data.navpvt.lat;
  164. currentGPSData.lon_raw = pkt->data.navpvt.lon;
  165. currentGPSData.alt_raw = pkt->data.navpvt.hMSL;
  166. currentGPSData.year = pkt->data.navpvt.year - 2000;
  167. currentGPSData.month = pkt->data.navpvt.month;
  168. currentGPSData.day = pkt->data.navpvt.day;
  169. currentGPSData.hours = pkt->data.navpvt.hour;
  170. currentGPSData.minutes = pkt->data.navpvt.min;
  171. currentGPSData.seconds = pkt->data.navpvt.sec;
  172. currentGPSData.sats_raw = pkt->data.navpvt.numSV;
  173. currentGPSData.speed_raw = pkt->data.navpvt.gSpeed;
  174. }
  175. else
  176. if (pkt->header.messageClass == 0x01 && pkt->header.messageId == 0x02)
  177. {
  178. currentGPSData.ok_packets += 1;
  179. currentGPSData.lat_raw = pkt->data.navposllh.lat;
  180. currentGPSData.lon_raw = pkt->data.navposllh.lon;
  181. currentGPSData.alt_raw = pkt->data.navposllh.hMSL;
  182. }
  183. else
  184. if (pkt->header.messageClass == 0x01 && pkt->header.messageId == 0x06)
  185. {
  186. currentGPSData.fix = pkt->data.navsol.gpsFix;
  187. currentGPSData.sats_raw = pkt->data.navsol.numSV;
  188. }
  189. else
  190. if (pkt->header.messageClass == 0x01 && pkt->header.messageId == 0x21)
  191. {
  192. currentGPSData.year = pkt->data.navtimeutc.year - 2000;
  193. currentGPSData.month = pkt->data.navtimeutc.month;
  194. currentGPSData.day = pkt->data.navtimeutc.day;
  195. currentGPSData.hours = pkt->data.navtimeutc.hour;
  196. currentGPSData.minutes = pkt->data.navtimeutc.min;
  197. currentGPSData.seconds = pkt->data.navtimeutc.sec;
  198. }
  199. else
  200. if (pkt->header.messageClass == 0x05 && pkt->header.messageId == 0x01)
  201. ack_received = 1;
  202. else
  203. if (pkt->header.messageClass == 0x05 && pkt->header.messageId == 0x00)
  204. nack_received = 1;
  205. }
  206. }
  207. uint8_t ublox_wait_for_ack (void)
  208. {
  209. ack_received = 0;
  210. nack_received = 0;
  211. uint8_t timeout = 200;
  212. while (!ack_received && !nack_received)
  213. {
  214. _delay_ms(1);
  215. if (!timeout--) break;
  216. }
  217. return ack_received;
  218. }