// // Created by SQ5RWU on 2016-12-27. // #include #include #include "ublox.h" #include "delay.h" #include "init.h" GPSEntry currentGPSData; volatile uint8_t active = 0; volatile uint8_t ack_received = 0; volatile uint8_t nack_received = 0; void _sendSerialByte(uint8_t message) { while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) { } USART_SendData(USART1, message); while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) { } } void send_ublox(uint8_t msgClass, uint8_t msgId, uint8_t *payload, uint16_t payloadSize) { uBloxChecksum chksum = ublox_calc_checksum(msgClass, msgId, payload, payloadSize); _sendSerialByte(0xB5); _sendSerialByte(0x62); _sendSerialByte(msgClass); _sendSerialByte(msgId); _sendSerialByte((uint8_t) (payloadSize & 0xff)); _sendSerialByte((uint8_t) (payloadSize >> 8)); uint16_t i; for (i = 0; i < payloadSize; ++i) { _sendSerialByte(payload[i]); } _sendSerialByte(chksum.ck_a); _sendSerialByte(chksum.ck_b); } void send_ublox_packet(uBloxPacket * packet){ send_ublox(packet->header.messageClass, packet->header.messageId, (uint8_t*)&packet->data, packet->header.payloadSize); } uBloxChecksum ublox_calc_checksum(const uint8_t msgClass, const uint8_t msgId, const uint8_t *message, uint16_t size) { uBloxChecksum ck = {0, 0}; uint8_t i; ck.ck_a += msgClass; ck.ck_b += ck.ck_a; ck.ck_a += msgId; ck.ck_b += ck.ck_a; ck.ck_a += size & 0xff; ck.ck_b += ck.ck_a; ck.ck_a += size >> 8; ck.ck_b += ck.ck_a; for (i =0;iheader.sc1 = data; } else if (buffer_pos == 1 && data == 0x62){ sync = 1; buffer_pos = 2; incoming_packet->header.sc2 = data; } else { buffer_pos = 0; } } else { ((uint8_t *)incoming_packet)[buffer_pos] = data; if ((buffer_pos >= sizeof(uBloxHeader)-1) && (buffer_pos-1 == (incoming_packet->header.payloadSize + sizeof(uBloxHeader) + sizeof(uBloxChecksum)))){ ublox_handle_packet((uBloxPacket *) incoming_packet); buffer_pos = 0; sync = 0; } else { buffer_pos++; if (buffer_pos >= sizeof(uBloxPacket) + sizeof(uBloxChecksum)) { buffer_pos = 0; sync = 0; } } } } void ublox_handle_packet(uBloxPacket *pkt) { uBloxChecksum cksum = ublox_calc_checksum(pkt->header.messageClass, pkt->header.messageId, (const uint8_t *) &pkt->data, pkt->header.payloadSize); uBloxChecksum *checksum = (uBloxChecksum *)(((uint8_t*)&pkt->data) + pkt->header.payloadSize); if (cksum.ck_a != checksum->ck_a || cksum.ck_b != checksum->ck_b) { currentGPSData.bad_packets += 1; } else { if (pkt->header.messageClass == 0x01 && pkt->header.messageId == 0x07){ currentGPSData.ok_packets += 1; currentGPSData.fix = pkt->data.navpvt.fixType; currentGPSData.lat_raw = pkt->data.navpvt.lat; currentGPSData.lon_raw = pkt->data.navpvt.lon; currentGPSData.alt_raw = pkt->data.navpvt.hMSL; currentGPSData.hours = pkt->data.navpvt.hour; currentGPSData.minutes = pkt->data.navpvt.min; currentGPSData.seconds = pkt->data.navpvt.sec; currentGPSData.sats_raw = pkt->data.navpvt.numSV; currentGPSData.speed_raw = pkt->data.navpvt.gSpeed; } else if (pkt->header.messageClass == 0x01 && pkt->header.messageId == 0x02){ currentGPSData.ok_packets += 1; currentGPSData.lat_raw = pkt->data.navposllh.lat; currentGPSData.lon_raw = pkt->data.navposllh.lon; currentGPSData.alt_raw = pkt->data.navposllh.hMSL; } else if (pkt->header.messageClass == 0x01 && pkt->header.messageId == 0x06){ currentGPSData.fix = pkt->data.navsol.gpsFix; currentGPSData.sats_raw = pkt->data.navsol.numSV; } else if (pkt->header.messageClass == 0x01 && pkt->header.messageId == 0x21){ currentGPSData.hours = pkt->data.navtimeutc.hour; currentGPSData.minutes = pkt->data.navtimeutc.min; currentGPSData.seconds = pkt->data.navtimeutc.sec; } else if (pkt->header.messageClass == 0x05 && pkt->header.messageId == 0x01){ ack_received = 1; } else if (pkt->header.messageClass == 0x05 && pkt->header.messageId == 0x00){ nack_received = 1; } } } uint8_t ublox_wait_for_ack() { ack_received = 0; nack_received = 0; uint8_t timeout = 200; while(!ack_received && !nack_received){ _delay_ms(1); if (!timeout--){ break; } } return ack_received; }