/* * aprs_prepare_buffer * * prepares the buffer for APRS transmission with the fix given as a reference. * checks for validity of the fix, does not change the buffer if the fix is unsuitable for transmission. * * backlog_fix contains a flag marking the fix as a backlog fix, containing a zero TLM sequence ID * * always transmits the latest temperature / battery voltage, no historical values! * */ inline void aprs_prepare_buffer(struct gps_fix* fix, uint8_t backlog_fix) { int16_t temp_aprs = 0; uint16_t seq_tmp; static uint16_t aprs_seqnum = 0; if (fix->type < 3) return; i16toa(fix->day, 2, &aprs_buf[APRS_TIME_START]); i16toa(fix->hour, 2, &aprs_buf[APRS_TIME_START + 2]); i16toa(fix->min, 2, &aprs_buf[APRS_TIME_START + 4]); base91_encode_latlon(&aprs_buf[APRS_LAT_START], 380926.0f * (90.0f - (float)fix->lat/10000000.0f)); base91_encode_latlon(&aprs_buf[APRS_LON_START], 190463.0f * (180.0f + (float)fix->lon/10000000.0f)); base91_encode_tlm(&aprs_buf[APRS_ALT_START], logf((float)fix->alt * 3.28f)/logf(1.002f)); if (backlog_fix) { seq_tmp = 0; } else { aprs_seqnum = (aprs_seqnum + 1) % 8281; seq_tmp = aprs_seqnum; } temp_aprs = fix->temperature_int + APRS_TLM_TEMP_OFFSET; base91_encode_tlm(&aprs_buf[APRS_SEQ_START], seq_tmp); base91_encode_tlm(&aprs_buf[APRS_TEMP_START], (uint16_t)temp_aprs); base91_encode_tlm(&aprs_buf[APRS_VOLT_START], fix->voltage_bat); base91_encode_tlm(&aprs_buf[APRS_VSOL_START], fix->voltage_sol); calculate_fcs(); }
/* * prepare_tx_buffer * * fills tx_buf with telemetry values. this depends on the * GPS having a fix and telemetry being extracted before * * telemetry format: * - callsign * - sentence id * - time * - latitude * - longitude * - altitude * - available satellites * - voltage of the AAA cell * - MSP430 temperature */ void prepare_tx_buffer(void) { static uint16_t sent_id = 0; int i; uint16_t crc; sent_id++; tlm_sent_id_length = i16toav(sent_id, &tx_buf[TX_BUF_SENT_ID_START]); tx_buf[TX_BUF_SENT_ID_START + tlm_sent_id_length] = ','; i16toa(current_fix.hour, 2, &tx_buf[TX_BUF_TIME_START]); i16toa(current_fix.min, 2, &tx_buf[TX_BUF_TIME_START + 2]); i16toa(current_fix.sec, 2, &tx_buf[TX_BUF_TIME_START + 4]); tx_buf[TX_BUF_TIME_START + TIME_LENGTH] = ','; if (current_fix.lat > 0) { tx_buf[TX_BUF_LAT_START] = '+'; i32toa(current_fix.lat, 9, &tx_buf[TX_BUF_LAT_START + 1]); } else { tx_buf[TX_BUF_LAT_START] = '-'; i32toa(0 - current_fix.lat, 9, &tx_buf[TX_BUF_LAT_START + 1]); } /* copy fraction of degrees one character towards the end, insert dot */ /* 012XXXXXX -> 012 XXXXXX */ for (i = 8; i >= 3; i--) { tx_buf[TX_BUF_LAT_START + i + 1] = tx_buf[TX_BUF_LAT_START + i]; } tx_buf[TX_BUF_LAT_START + 3] = '.'; tx_buf[TX_BUF_LAT_START + LAT_LENGTH + 1] = ','; if (current_fix.lon > 0) { tx_buf[TX_BUF_LON_START] = '+'; i32toa(current_fix.lon, 10, &tx_buf[TX_BUF_LON_START + 1]); } else { tx_buf[TX_BUF_LON_START] = '-'; i32toa(0 - current_fix.lon, 10, &tx_buf[TX_BUF_LON_START + 1]); } /* copy fraction of degrees one character towards the end, insert dot */ /* 51XXXXXX -> 51 XXXXXX */ for (i = 9; i >= 4; i--) { tx_buf[TX_BUF_LON_START + i + 1] = tx_buf[TX_BUF_LON_START + i]; } tx_buf[TX_BUF_LON_START + 4] = '.'; tx_buf[TX_BUF_LON_START + LON_LENGTH + 1] = ','; tlm_alt_length = i16toav(current_fix.alt, &tx_buf[TX_BUF_ALT_START]); tx_buf[TX_BUF_ALT_START + tlm_alt_length] = ','; i16toa(current_fix.num_svs, SAT_LENGTH, &tx_buf[TX_BUF_SAT_START]); tx_buf[TX_BUF_SAT_START + SAT_LENGTH] = ','; i16toa(current_fix.voltage_bat, VOLT_LENGTH, &tx_buf[TX_BUF_VOLT_START]); tx_buf[TX_BUF_VOLT_START + VOLT_LENGTH] = ','; if (current_fix.temperature_int < 0) { tx_buf[TX_BUF_TEMP_START] = '-'; i16toa(0 - current_fix.temperature_int, TEMP_LENGTH, &tx_buf[TX_BUF_TEMP_START + 1]); } else { tx_buf[TX_BUF_TEMP_START] = '+'; i16toa(current_fix.temperature_int, TEMP_LENGTH, &tx_buf[TX_BUF_TEMP_START + 1]); } tx_buf[TX_BUF_TEMP_START + TEMP_LENGTH + 1] = '*'; crc = calculate_txbuf_checksum(); i16tox(crc, &tx_buf[TX_BUF_CHECKSUM_START]); for (i = 0; i < TX_BUF_POSTFIX_LENGTH; i++) tx_buf[TX_BUF_POSTFIX_START + i] = TX_BUF_POSTFIX[i]; tx_buf_length = TX_BUF_FRAME_END; /* trigger transmission */ tx_buf_rdy = 1; }