satdump/src-core/modules/noaa/noaa_deframer.cpp

122 lines
3.3 KiB
C++
Raw Normal View History

2021-02-14 12:05:44 +01:00
#include "noaa_deframer.h"
#define ST_IDLE 0
#define ST_SYNCED 1
#define HRPT_SYNC1 0x0284
#define HRPT_SYNC2 0x016F
#define HRPT_SYNC3 0x035C
#define HRPT_SYNC4 0x019D
#define HRPT_SYNC5 0x020F
#define HRPT_SYNC6 0x0095
#define HRPT_MINOR_FRAME_SYNC 0x0A116FD719D83C95LL
#define HRPT_SYNC_WORDS 6
#define HRPT_MINOR_FRAME_WORDS 11090
#define HRPT_BITS_PER_WORD 10
2021-02-14 13:23:54 +01:00
namespace noaa
2021-02-14 12:05:44 +01:00
{
2021-04-05 14:23:59 +02:00
template <typename T>
inline bool getBit(T &data, int &bit)
{
return (data >> bit) & 1;
}
// Compare 2 32-bits values bit per bit
int checkSyncMarker(uint64_t marker, uint64_t totest)
{
int errors = 0;
for (int i = 59; i >= 0; i--)
{
bool markerBit, testBit;
markerBit = getBit<uint64_t>(marker, i);
testBit = getBit<uint64_t>(totest, i);
if (markerBit != testBit)
errors++;
}
return errors;
}
2021-02-14 13:23:54 +01:00
void NOAADeframer::enter_idle()
{
d_state = ST_IDLE;
}
2021-02-14 12:05:44 +01:00
2021-02-14 13:23:54 +01:00
void NOAADeframer::enter_synced()
{
d_state = ST_SYNCED;
d_bit_count = HRPT_BITS_PER_WORD;
d_word_count = HRPT_MINOR_FRAME_WORDS - HRPT_SYNC_WORDS;
d_word = 0;
}
2021-02-14 12:05:44 +01:00
2021-04-05 14:23:59 +02:00
NOAADeframer::NOAADeframer(int thresold)
2021-02-14 12:05:44 +01:00
{
2021-04-05 14:23:59 +02:00
d_thresold = thresold;
2021-02-14 13:23:54 +01:00
d_mid_bit = true;
d_last_bit = 0;
enter_idle();
};
2021-02-14 12:05:44 +01:00
2021-02-14 13:23:54 +01:00
std::vector<uint16_t> NOAADeframer::work(uint8_t *input, int length)
{
std::vector<uint16_t> out;
int i = 0;
while (i < length)
2021-02-14 12:05:44 +01:00
{
2021-02-14 13:23:54 +01:00
char bit = input[i++];
char diff = bit ^ d_last_bit;
d_last_bit = bit;
2021-02-14 12:05:44 +01:00
2021-02-14 13:23:54 +01:00
// Wait for transition if not synced, otherwise, alternate bits
if (d_mid_bit && (diff | (d_state == ST_SYNCED)))
{
switch (d_state)
2021-02-14 12:05:44 +01:00
{
2021-02-14 13:23:54 +01:00
case ST_IDLE:
d_shifter = (d_shifter << 1) | bit; // MSB transmitted first
2021-02-14 12:05:44 +01:00
2021-04-05 14:23:59 +02:00
//if ((d_shifter & 0x0FFFFFFFFFFFFFFFLL) == HRPT_MINOR_FRAME_SYNC)
if (checkSyncMarker(d_shifter & 0x0FFFFFFFFFFFFFFFLL, HRPT_MINOR_FRAME_SYNC) <= d_thresold)
2021-02-14 13:23:54 +01:00
{
out.push_back(HRPT_SYNC1);
out.push_back(HRPT_SYNC2);
out.push_back(HRPT_SYNC3);
out.push_back(HRPT_SYNC4);
out.push_back(HRPT_SYNC5);
out.push_back(HRPT_SYNC6);
enter_synced();
}
break;
case ST_SYNCED:
d_word = (d_word << 1) | bit; // MSB transmitted first
if (--d_bit_count == 0)
2021-02-14 12:05:44 +01:00
{
2021-02-14 13:23:54 +01:00
out.push_back(d_word);
d_word = 0;
d_bit_count = HRPT_BITS_PER_WORD;
if (--d_word_count == 0)
{
enter_idle();
}
2021-02-14 12:05:44 +01:00
}
2021-02-14 13:23:54 +01:00
break;
default:
break;
2021-02-14 12:05:44 +01:00
}
2021-02-14 13:23:54 +01:00
d_mid_bit = false;
}
else
{
d_mid_bit = true;
2021-02-14 12:05:44 +01:00
}
}
2021-02-14 13:23:54 +01:00
return out;
}
} // namespace noaa