diff --git a/grc/satnogs_upsat_fsk_frame_acquisition.xml b/grc/satnogs_upsat_fsk_frame_acquisition.xml
index 8c78be7..e03028f 100644
--- a/grc/satnogs_upsat_fsk_frame_acquisition.xml
+++ b/grc/satnogs_upsat_fsk_frame_acquisition.xml
@@ -1,38 +1,58 @@
- upsat_fsk_frame_acquisition
+ UPSAT FSK Frame Acquisition
satnogs_upsat_fsk_frame_acquisition
satnogs
import satnogs
- satnogs.upsat_fsk_frame_acquisition($&preamble, $&sync_word, $whitening, $manchester)
-
+ satnogs.upsat_fsk_frame_acquisition($preamble, $sync_word, $whitening, $manchester)
+
- ...
- ...
- ...
+ Frame Preamble
+ preamble
+ raw
-
+
+ Synchronization Word
+ sync_word
+ raw
+
+
+
+ Whitening
+ whitening
+ enum
+
+
+
+
+
+ Use Manchester Coding
+ manchester
+ enum
+
+
+
+
in
-
+ float
-
- out
-
+ pdu
+ message
diff --git a/include/satnogs/config.h b/include/satnogs/config.h
index 162be94..5771e62 100644
--- a/include/satnogs/config.h
+++ b/include/satnogs/config.h
@@ -31,6 +31,9 @@
*/
#define CW_DEBUG 1
-
+/*!
+ * The maximum allowed frame length of the UPSAT satellite
+ */
+#define UPSAT_MAX_FRAME_LEN 255
#endif /* INCLUDE_SATNOGS_CONFIG_H_ */
diff --git a/lib/upsat_fsk_frame_acquisition_impl.cc b/lib/upsat_fsk_frame_acquisition_impl.cc
index 3527d24..2737c4b 100644
--- a/lib/upsat_fsk_frame_acquisition_impl.cc
+++ b/lib/upsat_fsk_frame_acquisition_impl.cc
@@ -24,6 +24,7 @@
#include
#include "upsat_fsk_frame_acquisition_impl.h"
+#include
namespace gr
{
@@ -48,8 +49,27 @@ namespace gr
const std::vector &sync_word, bool whitening, bool manchester) :
gr::sync_block ("upsat_fsk_frame_acquisition",
gr::io_signature::make (1, 1, sizeof(float)),
- gr::io_signature::make (0, 0, 0))
+ gr::io_signature::make (0, 0, 0)),
+ d_preamble (preamble),
+ d_preamble_len (preamble.size ()),
+ d_sync_word (sync_word),
+ d_sync_word_len (sync_word.size ()),
+ d_state (SEARCHING),
+ d_shifting_byte (0x0),
+ d_decoded_bytes (0),
+ d_frame_len (0)
{
+ message_port_register_out (pmt::mp ("pdu"));
+ if (d_preamble_len < 2) {
+ throw std::invalid_argument ("Preamble must be at least 2 bytes long");
+ }
+
+ if (d_sync_word_len < 1) {
+ throw std::invalid_argument (
+ "Synchronization word must be at least 1 byte long");
+ }
+
+ d_pdu = new uint8_t[UPSAT_MAX_FRAME_LEN];
}
/*
@@ -57,6 +77,50 @@ namespace gr
*/
upsat_fsk_frame_acquisition_impl::~upsat_fsk_frame_acquisition_impl ()
{
+ delete[] d_pdu;
+ }
+
+ inline void
+ upsat_fsk_frame_acquisition_impl::slice_and_shift (float in)
+ {
+ uint8_t tmp;
+ /* Slice the input into 0 and 1 bits */
+ tmp = in > 0 ? 1 : 0;
+ d_shifting_byte = d_shifting_byte << 1;
+ d_shifting_byte |= tmp;
+ }
+
+ inline void
+ upsat_fsk_frame_acquisition_impl::reset_state ()
+ {
+ d_state = SEARCHING;
+ d_decoded_bytes = 0;
+ d_shifting_byte = 0;
+ }
+
+ inline void
+ upsat_fsk_frame_acquisition_impl::have_preamble ()
+ {
+ d_state = HAVE_PREAMBLE;
+ d_decoded_bytes = 1;
+ }
+
+ inline void
+ upsat_fsk_frame_acquisition_impl::have_sync ()
+ {
+ d_state = HAVE_SYNC_WORD;
+ }
+
+ inline void
+ upsat_fsk_frame_acquisition_impl::have_frame_len ()
+ {
+ d_state = HAVE_FRAME_LEN;
+ }
+
+ inline void
+ upsat_fsk_frame_acquisition_impl::have_payload ()
+ {
+ d_state = HAVE_PAYLOAD;
}
int
@@ -64,11 +128,32 @@ namespace gr
int noutput_items, gr_vector_const_void_star &input_items,
gr_vector_void_star &output_items)
{
+ int i;
const float *in = (const float *) input_items[0];
+ for (i = 0; i < noutput_items; i++) {
+ slice_and_shift (in[i]);
+ switch (d_state)
+ {
+ case SEARCHING:
+ if (d_shifting_byte == d_preamble[0]) {
+ have_preamble ();
+ }
+ break;
+ case HAVE_PREAMBLE:
+ break;
+ case HAVE_SYNC_WORD:
+ break;
+ case HAVE_PAYLOAD:
+ if (d_decoded_bytes == d_frame_len) {
+ message_port_pub (pmt::mp ("pdu"),
+ pmt::make_blob (d_pdu, d_frame_len));
+ }
+ break;
+ default:
+ LOG_WARN("Unknown decoding state");
+ }
+ }
- // Do <+signal processing+>
-
- // Tell runtime system how many output items we produced.
return noutput_items;
}
diff --git a/lib/upsat_fsk_frame_acquisition_impl.h b/lib/upsat_fsk_frame_acquisition_impl.h
index df269c2..0695031 100644
--- a/lib/upsat_fsk_frame_acquisition_impl.h
+++ b/lib/upsat_fsk_frame_acquisition_impl.h
@@ -21,6 +21,7 @@
#ifndef INCLUDED_SATNOGS_UPSAT_FSK_FRAME_ACQUISITION_IMPL_H
#define INCLUDED_SATNOGS_UPSAT_FSK_FRAME_ACQUISITION_IMPL_H
+#include
#include
namespace gr
@@ -31,7 +32,42 @@ namespace gr
class upsat_fsk_frame_acquisition_impl : public upsat_fsk_frame_acquisition
{
private:
- // Nothing to declare in this block.
+
+ /**
+ * Decoding FSM
+ */
+ typedef enum
+ {
+ SEARCHING, //!< SEARCHING when searching for the start of the preamble
+ HAVE_PREAMBLE, //!< HAVE_PREAMBLE when the decoder is inside the preamble
+ HAVE_SYNC_WORD, //!< HAVE_SYNC_WORD when the decoder is inside the sync word
+ HAVE_FRAME_LEN, //!< HAVE_FRAME_LEN when the decoder is inside the frame length field
+ HAVE_PAYLOAD //!< HAVE_PAYLOAD when the decoder process the palyload of the frame
+ } decoding_state_t;
+
+ const std::vector d_preamble;
+ const size_t d_preamble_len;
+ const std::vector d_sync_word;
+ const size_t d_sync_word_len;
+ decoding_state_t d_state;
+ uint8_t d_shifting_byte;
+ size_t d_decoded_bytes;
+ size_t d_frame_len;
+ uint8_t *d_pdu;
+
+ inline void
+ slice_and_shift (float in);
+
+ inline void
+ reset_state ();
+ inline void
+ have_preamble ();
+ inline void
+ have_sync ();
+ inline void
+ have_frame_len ();
+ inline void
+ have_payload ();
public:
upsat_fsk_frame_acquisition_impl (const std::vector &preamble,