ADSB RX now works \o/

Added tabs in RDS TX, multiple groups can be sent at once
Bugfix: text not updating on UI after text prompt
This commit is contained in:
furrtek
2017-08-16 10:02:57 +01:00
parent 160359166a
commit 9d902bc224
18 changed files with 664 additions and 590 deletions

View File

@@ -70,6 +70,27 @@ void encode_frame_id(ADSBFrame& frame, const uint32_t ICAO_address, const std::s
frame.make_CRC();
}
std::string decode_frame_id(ADSBFrame& frame) {
std::string callsign = "";
uint8_t * raw_data = frame.get_raw_data();
uint64_t callsign_coded = 0;
uint32_t c;
// Frame bytes to long
for (c = 5; c < 11; c++) {
callsign_coded <<= 8;
callsign_coded |= raw_data[c];
}
// Long to 6-bit characters
for (c = 0; c < 8; c++) {
callsign.append(1, icao_id_lut[(callsign_coded >> 42) & 0x3F]);
callsign_coded <<= 6;
}
return callsign;
}
/*void generate_frame_emergency(ADSBFrame& frame, const uint32_t ICAO_address, const uint8_t code) {
make_frame_mode_s(frame, ICAO_address);
@@ -141,26 +162,6 @@ int cpr_N(float lat, int is_odd) {
return nl;
}
// Decoding method (from dump1090):
// index int j = floor(((59 * latcprE - 60 * latcprO) / 131072) + 0.50)
// latE = DlatE * (cpr_mod(j, 60) + (latcprE / 131072))
// latO = DlatO * (cpr_mod(j, 59) + (latcprO / 131072))
// if latE >= 270 -> latE -= 360
// if latO >= 270 -> latO -= 360
// if (cpr_NL(latE) != cpr_NL(latO)) return;
// int ni = cpr_N(latE ,0);
// int m = floor((((loncprE * (cpr_NL(latE) - 1)) - (loncprO * cpr_NL(latE))) / 131072) + 0.5)
// lon = cpr_Dlon(latE, 0) * (cpr_mod(m, ni) + loncprE / 131072);
// lat = latE;
// ... or ...
// int ni = cpr_N(latO ,0);
// int m = floor((((loncprE * (cpr_NL(latO) - 1)) - (loncprO * cpr_NL(latO))) / 131072) + 0.5)
// lon = cpr_Dlon(latO, 0) * (cpr_mod(m, ni) + loncprO / 131072);
// lat = latO;
// ... and ...
// if (lon > 180) lon -= 360;
void encode_frame_pos(ADSBFrame& frame, const uint32_t ICAO_address, const int32_t altitude,
const float latitude, const float longitude, const uint32_t time_parity) {
@@ -202,6 +203,37 @@ void encode_frame_pos(ADSBFrame& frame, const uint32_t ICAO_address, const int32
frame.make_CRC();
}
// Decoding method (from dump1090):
// index int j = floor(((59 * latcprE - 60 * latcprO) / 131072) + 0.50)
// latE = DlatE * (cpr_mod(j, 60) + (latcprE / 131072))
// latO = DlatO * (cpr_mod(j, 59) + (latcprO / 131072))
// if latE >= 270 -> latE -= 360
// if latO >= 270 -> latO -= 360
// if (cpr_NL(latE) != cpr_NL(latO)) return;
// int ni = cpr_N(latE ,0);
// int m = floor((((loncprE * (cpr_NL(latE) - 1)) - (loncprO * cpr_NL(latE))) / 131072) + 0.5)
// lon = cpr_Dlon(latE, 0) * (cpr_mod(m, ni) + loncprE / 131072);
// lat = latE;
// ... or ...
// int ni = cpr_N(latO ,0);
// int m = floor((((loncprE * (cpr_NL(latO) - 1)) - (loncprO * cpr_NL(latO))) / 131072) + 0.5)
// lon = cpr_Dlon(latO, 0) * (cpr_mod(m, ni) + loncprO / 131072);
// lat = latO;
// ... and ...
// if (lon > 180) lon -= 360;
// Only altitude is decoded for now
uint32_t decode_frame_pos(ADSBFrame& frame) {
uint8_t * raw_data = frame.get_raw_data();
// Q-bit is present
if (raw_data[5] & 1)
return ((((raw_data[5] >> 1) << 4) | ((raw_data[6] & 0xF0) >> 4)) * 25) - 1000;
return 0;
}
// speed is in knots
// vertical rate is in ft/min
void encode_frame_velo(ADSBFrame& frame, const uint32_t ICAO_address, const uint32_t speed,

View File

@@ -68,12 +68,19 @@ const float adsb_lat_lut[58] = {
};
void make_frame_adsb(ADSBFrame& frame, const uint32_t ICAO_address);
void encode_frame_id(ADSBFrame& frame, const uint32_t ICAO_address, const std::string& callsign);
std::string decode_frame_id(ADSBFrame& frame);
void encode_frame_pos(ADSBFrame& frame, const uint32_t ICAO_address, const int32_t altitude,
const float latitude, const float longitude, const uint32_t time_parity);
uint32_t decode_frame_pos(ADSBFrame& frame);
void encode_frame_velo(ADSBFrame& frame, const uint32_t ICAO_address, const uint32_t speed,
const float angle, const int32_t v_rate);
//void encode_frame_emergency(ADSBFrame& frame, const uint32_t ICAO_address, const uint8_t code);
void encode_frame_squawk(ADSBFrame& frame, const uint32_t squawk);
} /* namespace adsb */

View File

@@ -60,39 +60,41 @@ public:
uint8_t * get_raw_data() {
return raw_data;
}
std::string get_callsign() {
uint64_t callsign_coded = 0;
uint32_t c;
std::string callsign = "";
// Frame bytes to long
for (c = 5; c < 11; c++) {
callsign_coded <<= 8;
callsign_coded |= raw_data[c];
}
// Long to 6-bit characters
for (c = 0; c < 8; c++) {
callsign.append(1, icao_id_lut[(callsign_coded >> 42) & 0x3F]);
callsign_coded <<= 6;
}
return callsign;
}
void make_CRC() {
uint8_t adsb_crc[14]; // Temp buffer
uint32_t computed_CRC = compute_CRC();
// Insert CRC in frame
raw_data[11] = (computed_CRC >> 16) & 0xFF;
raw_data[12] = (computed_CRC >> 8) & 0xFF;
raw_data[13] = computed_CRC & 0xFF;
}
bool check_CRC() {
uint32_t computed_CRC = compute_CRC();
if (raw_data[11] != ((computed_CRC >> 16) & 0xFF)) return false;
if (raw_data[12] != ((computed_CRC >> 8) & 0xFF)) return false;
if (raw_data[13] != (computed_CRC & 0xFF)) return false;
return true;
}
private:
static const uint8_t adsb_preamble[16];
static const char icao_id_lut[65];
alignas(4) uint8_t index { 0 };
alignas(4) uint8_t raw_data[14] { }; // 112 bits at most
uint32_t compute_CRC() {
uint8_t adsb_crc[14] = { 0 }; // Temp buffer
uint8_t b, c, s, bitn;
const uint32_t crc_poly = 0x1205FFF;
// Clear CRC
raw_data[11] = 0x00;
raw_data[12] = 0x00;
raw_data[13] = 0x00;
// Copy frame data
memcpy(adsb_crc, raw_data, 11);
// Compute CRC
memcpy(adsb_crc, raw_data, 14);
for (c = 0; c < 11; c++) {
for (b = 0; b < 8; b++) {
if ((adsb_crc[c] << b) & 0x80) {
@@ -104,15 +106,8 @@ public:
}
}
// Insert CRC in frame
memcpy(&raw_data[11], &adsb_crc[11], 3);
return (adsb_crc[11] << 16) + (adsb_crc[12] << 8) + adsb_crc[13];
}
private:
static const uint8_t adsb_preamble[16];
static const char icao_id_lut[65];
alignas(4) uint8_t index { 0 };
alignas(4) uint8_t raw_data[14] { }; // 112 bits at most
};
} /* namespace adsb */

View File

@@ -276,6 +276,35 @@ std::string View::title() const {
return "";
};
/* OptionTabView *********************************************************/
OptionTabView::OptionTabView(Rect parent_rect) {
set_parent_rect(parent_rect);
add_child(&check_enable);
hidden(true);
check_enable.on_select = [this](Checkbox&, bool value) {
enabled = value;
};
}
void OptionTabView::set_enabled(bool value) {
check_enable.set_value(value);
}
bool OptionTabView::is_enabled() {
return check_enable.value();
}
void OptionTabView::set_type(std::string type) {
check_enable.set_text("Transmit " + type);
}
void OptionTabView::focus() {
check_enable.focus();
}
/* Rectangle *************************************************************/
Rectangle::Rectangle(

View File

@@ -603,6 +603,29 @@ private:
bool show_max_;
};
class OptionTabView : public View {
public:
OptionTabView(Rect parent_rect);
void focus() override;
bool is_enabled();
void set_type(std::string type);
protected:
bool enabled { false };
void set_enabled(bool value);
private:
Checkbox check_enable {
{ 2 * 8, 0 * 16 },
20,
"",
false
};
};
} /* namespace ui */
#endif/*__UI_WIDGET_H__*/