mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2025-08-13 10:47:44 +00:00
acars to ext but disabled (#2288)
This commit is contained in:
@@ -314,12 +314,6 @@ endmacro()
|
||||
|
||||
set(add_to_firmware TRUE)
|
||||
|
||||
### ACARS RX
|
||||
|
||||
set(MODE_CPPSRC
|
||||
proc_acars.cpp
|
||||
)
|
||||
DeclareTargets(PACA acars)
|
||||
|
||||
### ADS-B RX
|
||||
|
||||
@@ -579,6 +573,15 @@ DeclareTargets(PUSB sd_over_usb)
|
||||
### Place external app and disabled images below so they don't get added to the firmware
|
||||
set(add_to_firmware FALSE)
|
||||
|
||||
|
||||
### ACARS RX
|
||||
|
||||
set(MODE_CPPSRC
|
||||
proc_acars.cpp
|
||||
)
|
||||
DeclareTargets(PACA acars)
|
||||
|
||||
|
||||
### AFSK RX
|
||||
|
||||
set(MODE_CPPSRC
|
||||
|
@@ -20,18 +20,27 @@
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "proc_acars.hpp"
|
||||
|
||||
#include "portapack_shared_memory.hpp"
|
||||
|
||||
#include "proc_acars.hpp"
|
||||
#include "dsp_fir_taps.hpp"
|
||||
#include "audio_dma.hpp"
|
||||
|
||||
#include "event_m4.hpp"
|
||||
|
||||
#define SYN 0x16
|
||||
#define SOH 0x01
|
||||
#define STX 0x02
|
||||
#define ETX 0x83
|
||||
#define ETB 0x97
|
||||
#define DLE 0x7f
|
||||
|
||||
ACARSProcessor::ACARSProcessor() {
|
||||
audio::dma::init_audio_out();
|
||||
decim_0.configure(taps_11k0_decim_0.taps);
|
||||
decim_1.configure(taps_11k0_decim_1.taps);
|
||||
packet.clear();
|
||||
decode_data = 0;
|
||||
decode_count_bit = 0;
|
||||
audio_output.configure(false);
|
||||
baseband_thread.start();
|
||||
}
|
||||
|
||||
@@ -45,6 +54,9 @@ void ACARSProcessor::execute(const buffer_c8_t& buffer) {
|
||||
/* 38.4kHz, 32 samples */
|
||||
feed_channel_stats(decimator_out);
|
||||
|
||||
auto audio = demod.execute(decimator_out, audio_buffer);
|
||||
audio_output.write(audio);
|
||||
|
||||
for (size_t i = 0; i < decimator_out.count; i++) {
|
||||
if (mf.execute_once(decimator_out.p[i])) {
|
||||
clock_recovery(mf.get_output());
|
||||
@@ -52,24 +64,134 @@ void ACARSProcessor::execute(const buffer_c8_t& buffer) {
|
||||
}
|
||||
}
|
||||
|
||||
void ACARSProcessor::consume_symbol(
|
||||
const float raw_symbol) {
|
||||
const uint_fast8_t sliced_symbol = (raw_symbol >= 0.0f) ? 1 : 0;
|
||||
// const auto decoded_symbol = acars_decode(sliced_symbol);
|
||||
|
||||
// DEBUG
|
||||
packet.add(sliced_symbol);
|
||||
if (packet.size() == 256) {
|
||||
payload_handler(packet);
|
||||
packet.clear();
|
||||
}
|
||||
|
||||
// packet_builder.execute(decoded_symbol);
|
||||
void ACARSProcessor::add_bit(uint8_t bit) {
|
||||
decode_data = decode_data << 1 | bit;
|
||||
decode_count_bit++;
|
||||
}
|
||||
|
||||
void ACARSProcessor::payload_handler(
|
||||
const baseband::Packet& packet) {
|
||||
const ACARSPacketMessage message{packet};
|
||||
uint16_t ACARSProcessor::update_crc(uint8_t dataByte) {
|
||||
(void)dataByte;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ACARSProcessor::sendDebug() {
|
||||
// if (curr_state <= 1) return;
|
||||
message.state = curr_state;
|
||||
shared_memory.application_queue.push(message);
|
||||
}
|
||||
|
||||
void ACARSProcessor::reset() {
|
||||
decode_data = 0;
|
||||
decode_count_bit = 0;
|
||||
curr_state = WSYN;
|
||||
message.msg_len = 0;
|
||||
memset(message.message, 0, 250);
|
||||
message.crc[0] = 0;
|
||||
message.crc[1] = 0;
|
||||
parity_errors = 0;
|
||||
}
|
||||
|
||||
void ACARSProcessor::consume_symbol(const float raw_symbol) {
|
||||
const uint_fast8_t sliced_symbol = (raw_symbol >= 0.0f) ? 1 : 0;
|
||||
|
||||
add_bit(sliced_symbol);
|
||||
if (curr_state == WSYN && decode_count_bit == 8) {
|
||||
if ((decode_data & 0xff) == SYN) {
|
||||
curr_state = SYN2;
|
||||
decode_data = 0;
|
||||
decode_count_bit = 0;
|
||||
} else {
|
||||
decode_count_bit -= 1; // just drop the first bit
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (curr_state == SYN2 && decode_count_bit == 8) {
|
||||
if ((decode_data & 0xff) == SYN) {
|
||||
curr_state = SOH1;
|
||||
decode_data = 0;
|
||||
decode_count_bit = 0;
|
||||
sendDebug();
|
||||
return;
|
||||
}
|
||||
// here i don't have the right packets. so reset
|
||||
reset();
|
||||
}
|
||||
if (curr_state == SOH1 && decode_count_bit == 8) {
|
||||
if ((decode_data & 0xff) == SOH) {
|
||||
reset();
|
||||
curr_state = TXT;
|
||||
sendDebug();
|
||||
return;
|
||||
}
|
||||
message.message[0] = (decode_data & 0xff); // debug
|
||||
reset();
|
||||
sendDebug();
|
||||
}
|
||||
if (curr_state == TXT && decode_count_bit == 8) {
|
||||
uint8_t ch = (decode_data & 0xff);
|
||||
message.message[message.msg_len++] = ch;
|
||||
|
||||
if (!ParityCheck::parity_check(ch)) {
|
||||
// parity error
|
||||
parity_errors++;
|
||||
if (parity_errors > 4) {
|
||||
reset(); // too many parity errors, skip packet
|
||||
sendDebug();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (ch == ETX || ch == ETB) {
|
||||
curr_state = CRC1;
|
||||
sendDebug();
|
||||
decode_data = 0;
|
||||
decode_count_bit = 0;
|
||||
return;
|
||||
}
|
||||
if (message.msg_len > 240) {
|
||||
reset();
|
||||
sendDebug();
|
||||
}
|
||||
if (message.msg_len > 20 && ch == DLE) {
|
||||
message.msg_len -= 3;
|
||||
message.crc[0] = message.message[message.msg_len];
|
||||
message.crc[1] = message.message[message.msg_len + 1];
|
||||
curr_state = CRC2;
|
||||
sendDebug();
|
||||
// to hack the path:
|
||||
decode_data = message.crc[1];
|
||||
} else {
|
||||
decode_count_bit = 0;
|
||||
decode_data = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (curr_state == CRC1 && decode_count_bit == 8) {
|
||||
message.crc[0] = (decode_data & 0xff);
|
||||
curr_state = CRC2;
|
||||
decode_data = 0;
|
||||
decode_count_bit = 0;
|
||||
sendDebug();
|
||||
}
|
||||
|
||||
if (curr_state == CRC2 && decode_count_bit == 8) {
|
||||
message.crc[1] = (decode_data & 0xff);
|
||||
// send it to app cpu, and it'll take care of the rest
|
||||
payload_handler();
|
||||
reset();
|
||||
curr_state = END;
|
||||
decode_data = 0;
|
||||
decode_count_bit = 0;
|
||||
sendDebug();
|
||||
}
|
||||
if (curr_state == END && decode_count_bit == 8) {
|
||||
reset();
|
||||
sendDebug();
|
||||
}
|
||||
}
|
||||
|
||||
void ACARSProcessor::payload_handler() {
|
||||
message.state = 255; // to indicate this is an actual payload, not a debug packet
|
||||
shared_memory.application_queue.push(message);
|
||||
}
|
||||
|
||||
@@ -77,4 +199,4 @@ int main() {
|
||||
EventDispatcher event_dispatcher{std::make_unique<ACARSProcessor>()};
|
||||
event_dispatcher.run();
|
||||
return 0;
|
||||
}
|
||||
}
|
@@ -46,11 +46,15 @@
|
||||
#include "baseband_packet.hpp"
|
||||
|
||||
#include "message.hpp"
|
||||
#include "dsp_demodulate.hpp"
|
||||
#include "audio_output.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
#include <bitset>
|
||||
|
||||
#include "crc.hpp"
|
||||
|
||||
// AIS:
|
||||
// IN: 2457600/8/8 = 38400
|
||||
// Offset: 2457600/4 = 614400 (614400/8/8 = 9600)
|
||||
@@ -101,6 +105,14 @@ constexpr std::array<std::complex<float>, 16> rect_taps_38k4_4k8_1t_2k4_p{{
|
||||
{4.4194173824e-02f, -4.4194173824e-02f},
|
||||
}};
|
||||
|
||||
typedef enum { WSYN,
|
||||
SYN2,
|
||||
SOH1,
|
||||
TXT,
|
||||
CRC1,
|
||||
CRC2,
|
||||
END } Acarsstate;
|
||||
|
||||
class ACARSProcessor : public BasebandProcessor {
|
||||
public:
|
||||
ACARSProcessor();
|
||||
@@ -124,24 +136,32 @@ class ACARSProcessor : public BasebandProcessor {
|
||||
2400,
|
||||
{0.0555f},
|
||||
[this](const float symbol) { this->consume_symbol(symbol); }};
|
||||
symbol_coding::ACARSDecoder acars_decode{};
|
||||
/*PacketBuilder<BitPattern, NeverMatch, FixedLength> packet_builder {
|
||||
{ 0b011010000110100010000000, 24, 1 }, // SYN, SYN, SOH
|
||||
{ },
|
||||
{ 128 },
|
||||
[this](const baseband::Packet& packet) {
|
||||
this->payload_handler(packet);
|
||||
}
|
||||
};*/
|
||||
baseband::Packet packet{};
|
||||
|
||||
uint16_t update_crc(uint8_t dataByte);
|
||||
void consume_symbol(const float symbol);
|
||||
void payload_handler();
|
||||
void add_bit(uint8_t bit);
|
||||
void reset();
|
||||
void sendDebug();
|
||||
|
||||
std::array<float, 32> audio{};
|
||||
const buffer_f32_t audio_buffer{
|
||||
audio.data(),
|
||||
audio.size()};
|
||||
dsp::demodulate::AM demod{};
|
||||
AudioOutput audio_output{};
|
||||
|
||||
Acarsstate curr_state = WSYN;
|
||||
|
||||
uint32_t decode_data = 0;
|
||||
uint8_t decode_count_bit = 0;
|
||||
ACARSPacketMessage message{};
|
||||
uint8_t parity_errors = 0;
|
||||
|
||||
/* NB: Threads should be the last members in the class definition. */
|
||||
BasebandThread baseband_thread{
|
||||
baseband_fs, this, baseband::Direction::Receive, /*auto_start*/ false};
|
||||
RSSIThread rssi_thread{};
|
||||
|
||||
void consume_symbol(const float symbol);
|
||||
void payload_handler(const baseband::Packet& packet);
|
||||
};
|
||||
|
||||
#endif /*__PROC_ACARS_H__*/
|
||||
#endif /*__PROC_ACARS_H__*/
|
Reference in New Issue
Block a user