mirror of
https://github.com/peterantypas/maiana.git
synced 2025-05-18 00:10:08 -07:00
Overhauled event processing
This commit is contained in:
parent
db0a282699
commit
f080b18872
@ -16,6 +16,7 @@ MEMORY
|
||||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 40K
|
||||
CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 0K
|
||||
FLASH (rx) : ORIGIN = 0x08004000, LENGTH = 112K
|
||||
/* FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 128K */
|
||||
FLASHB1 (rx) : ORIGIN = 0x00000000, LENGTH = 0
|
||||
EXTMEMB0 (rx) : ORIGIN = 0x00000000, LENGTH = 0
|
||||
EXTMEMB1 (rx) : ORIGIN = 0x00000000, LENGTH = 0
|
||||
|
@ -43,7 +43,7 @@ uint32_t AISMessage::mmsi() const
|
||||
return mMMSI;
|
||||
}
|
||||
|
||||
bool AISMessage::decode(RXPacket &)
|
||||
bool AISMessage::decode(const RXPacket &)
|
||||
{
|
||||
// The base class method should never be called
|
||||
ASSERT(false);
|
||||
@ -211,7 +211,7 @@ AISMessage123::AISMessage123()
|
||||
{
|
||||
}
|
||||
|
||||
bool AISMessage123::decode(RXPacket &packet)
|
||||
bool AISMessage123::decode(const RXPacket &packet)
|
||||
{
|
||||
mType = packet.messageType();
|
||||
mRI = packet.repeatIndicator();
|
||||
@ -312,7 +312,7 @@ void AISMessage18::encode(const StationData &station, TXPacket &packet)
|
||||
finalize(payload, size, packet);
|
||||
}
|
||||
|
||||
bool AISMessage18::decode(RXPacket &packet)
|
||||
bool AISMessage18::decode(const RXPacket &packet)
|
||||
{
|
||||
mType = packet.messageType();
|
||||
mRI = packet.repeatIndicator();
|
||||
|
@ -29,7 +29,7 @@ public:
|
||||
AISMessage ();
|
||||
virtual ~AISMessage ();
|
||||
|
||||
virtual bool decode(RXPacket &packet);
|
||||
virtual bool decode(const RXPacket &packet);
|
||||
virtual void encode(const StationData &station, TXPacket &packet);
|
||||
|
||||
uint8_t type() const;
|
||||
@ -65,7 +65,7 @@ public:
|
||||
|
||||
AISMessage123();
|
||||
|
||||
bool decode(RXPacket &packet);
|
||||
bool decode(const RXPacket &packet);
|
||||
};
|
||||
|
||||
class AISMessage18 : public AISMessage
|
||||
@ -79,7 +79,7 @@ public:
|
||||
|
||||
AISMessage18();
|
||||
|
||||
bool decode(RXPacket &packet);
|
||||
bool decode(const RXPacket &packet);
|
||||
void encode(const StationData &data, TXPacket &packet);
|
||||
};
|
||||
|
||||
|
@ -44,7 +44,7 @@ bool ChannelManager::channelsDetermined()
|
||||
return true;
|
||||
}
|
||||
|
||||
void ChannelManager::processEvent(Event *)
|
||||
void ChannelManager::processEvent(const Event &)
|
||||
{
|
||||
//AISPacketEvent *pe = static_cast<AISPacketEvent*>(e);
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ public:
|
||||
static ChannelManager &instance();
|
||||
virtual ~ChannelManager();
|
||||
|
||||
void processEvent(Event *e);
|
||||
void processEvent(const Event &e);
|
||||
|
||||
const ais_channel &channelA();
|
||||
const ais_channel &channelB();
|
||||
|
@ -12,9 +12,13 @@
|
||||
#include "MenuScreens.hpp"
|
||||
#include "Events.hpp"
|
||||
#include <stdio.h>
|
||||
#include "Utils.hpp"
|
||||
#include <cstring>
|
||||
|
||||
#ifdef ENABLE_TERMINAL
|
||||
|
||||
static char __buff[128];
|
||||
|
||||
DataTerminal &DataTerminal::instance()
|
||||
{
|
||||
static DataTerminal __instance;
|
||||
@ -62,45 +66,60 @@ void DataTerminal::init()
|
||||
}
|
||||
|
||||
DataTerminal::DataTerminal()
|
||||
: mEscapes(0), mCurrentScreen(MAIN_SCREEN), mInteractive(false)
|
||||
: mCmdBuffPos(0)
|
||||
{
|
||||
EventQueue::instance().addObserver(this, CLOCK_EVENT|KEYPRESS_EVENT);
|
||||
mCmdTokens.reserve(5);
|
||||
EventQueue::instance().addObserver(this, RESPONSE_EVENT);
|
||||
}
|
||||
|
||||
void DataTerminal::processEvent(Event *e)
|
||||
void DataTerminal::processEvent(const Event &e)
|
||||
{
|
||||
if ( e->type() == CLOCK_EVENT ) {
|
||||
ClockEvent *c = static_cast<ClockEvent*>(e);
|
||||
if ( c->mTime % 2 == 0 ) {
|
||||
mEscapes = 0;
|
||||
}
|
||||
}
|
||||
else if ( e->type() == KEYPRESS_EVENT ) {
|
||||
KeyPressEvent *k = static_cast<KeyPressEvent*>(e);
|
||||
processCharacter(k->key);
|
||||
switch (e.type) {
|
||||
case RESPONSE_EVENT:
|
||||
sprintf(__buff, "[%s]%s\r\n", (e.response.success ? "OK" : "ERR"), e.response.data);
|
||||
write("RESPONSE", __buff);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DataTerminal::processCharacter(char c)
|
||||
{
|
||||
if ( !mInteractive ) {
|
||||
if ( c == 27 )
|
||||
++mEscapes;
|
||||
|
||||
if ( mEscapes == 3 ) {
|
||||
mInteractive = true;
|
||||
printf2("Entering interactive mode\r\n");
|
||||
showScreen(MAIN_SCREEN);
|
||||
}
|
||||
if ( c == 13 ) {
|
||||
mCmdBuffer[mCmdBuffPos] = 0;
|
||||
mCmdBuffPos = 0;
|
||||
processCommand();
|
||||
}
|
||||
else {
|
||||
if ( c == 13 ) {
|
||||
clearScreen();
|
||||
printf2("Exiting interactive mode\r\n");
|
||||
mInteractive = false;
|
||||
}
|
||||
}
|
||||
mCmdBuffer[mCmdBuffPos++] = c;
|
||||
if (mCmdBuffPos >= sizeof mCmdBuffer)
|
||||
mCmdBuffPos = 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void DataTerminal::processCommand()
|
||||
{
|
||||
string s(mCmdBuffer);
|
||||
Utils::trim(s);
|
||||
Utils::tokenize(s, ' ', mCmdTokens);
|
||||
|
||||
if ( mCmdTokens[0] == "set" && mCmdTokens.size() >= 3 ) {
|
||||
// TODO: Extract field and value and queue a command event
|
||||
Event *e = EventPool::instance().newEvent(REQUEST_EVENT);
|
||||
e->request.operation = OP_SET;
|
||||
strncpy(e->request.field, mCmdTokens[1].c_str(), sizeof e->request.field);
|
||||
strncpy(e->request.value, mCmdTokens[2].c_str(), sizeof e->request.value);
|
||||
EventQueue::instance().push(e);
|
||||
}
|
||||
else if ( mCmdTokens[0] == "get" && mCmdTokens.size() >= 2 ) {
|
||||
// TODO: Extract field
|
||||
Event *e = EventPool::instance().newEvent(REQUEST_EVENT);
|
||||
e->request.operation = OP_GET;
|
||||
strncpy(e->request.field, mCmdTokens[1].c_str(), sizeof e->request.field);
|
||||
EventQueue::instance().push(e);
|
||||
}
|
||||
}
|
||||
|
||||
void write_char(USART_TypeDef* USARTx, char c)
|
||||
@ -113,11 +132,8 @@ void write_char(USART_TypeDef* USARTx, char c)
|
||||
|
||||
#ifdef MULTIPLEXED_OUTPUT
|
||||
|
||||
void DataTerminal::write(const char *cls, const char* s, bool interactive)
|
||||
void DataTerminal::write(const char *cls, const char* s)
|
||||
{
|
||||
if ( mInteractive && !interactive )
|
||||
return;
|
||||
|
||||
write_char(USART3, '[');
|
||||
for ( size_t i = 0; i < strlen(cls); ++i )
|
||||
write_char(USART3, cls[i]);
|
||||
@ -140,60 +156,17 @@ void DataTerminal::write(const char* s, bool interactive)
|
||||
}
|
||||
#endif
|
||||
|
||||
void DataTerminal::clearScreen()
|
||||
{
|
||||
_write("\033[2J");
|
||||
_write("\033[H");
|
||||
}
|
||||
|
||||
|
||||
void DataTerminal::_write(const char *s)
|
||||
{
|
||||
#ifdef MULTIPLEXED_OUTPUT
|
||||
write("", s, true);
|
||||
write("", s);
|
||||
#else
|
||||
write(s, true);
|
||||
write(s);
|
||||
#endif
|
||||
}
|
||||
|
||||
void DataTerminal::showScreen(MenuScreen screen)
|
||||
{
|
||||
char buff[100];
|
||||
switch(screen) {
|
||||
case MAIN_SCREEN: {
|
||||
clearScreen();
|
||||
//_write("****************************** Interactive Mode ******************************\r\n");
|
||||
//_write("NOTICE: IT IS AGAINST USCG REGULATIONS FOR END USERS TO ALTER THEIR MMSI,\r\n");
|
||||
//_write("STATION NAME AND CALL SIGN AFTER INITIAL INSTALLATION.\r\n");
|
||||
//_write("IF YOUR UNIT HAS BEEN FACTORY PROGRAMMED, THIS TERMINAL WILL PROMPT YOU\r\n");
|
||||
//_write("FOR A SPECIAL CODE BEFORE ALLOWING THIS OPERATION. YOU CAN ONLY OBTAIN THE\r\n");
|
||||
//_write("CODE BY CONTACTING US AND PROVIDING THE UNIT'S SERIAL NUMBER AND CURRENT MMSI.\r\n\r\n");
|
||||
sprintf(buff, "Model: %s\r\n", MODEL);
|
||||
_write(buff);
|
||||
sprintf(buff, "Software revision: %s\r\n", REVISION);
|
||||
_write(buff);
|
||||
#if 0
|
||||
sprintf(buff, "MMSI: %d\r\n", STATION_MMSI);
|
||||
_write(buff);
|
||||
sprintf(buff, "Name: %s\r\n", STATION_NAME);
|
||||
_write(buff);
|
||||
sprintf(buff, "Call sign: %s\r\n", STATION_CALLSIGN);
|
||||
_write(buff);
|
||||
#endif
|
||||
_write("\r\n");
|
||||
_write("****************************** AIS Transponder Menu ******************************\r\n\r\n");
|
||||
_write("\t\033[1mP\033[0m\tProgram MMSI, station name and call sign \r\n");
|
||||
_write("\t\033[1mD\033[0m\tPerform diagnostics \r\n");
|
||||
_write("\t\033[1m<Enter>\033[0m\tReturn to AIS data mode\r\n\r\n");
|
||||
_write("**********************************************************************************\r\n\r\n");
|
||||
//_write("Note: The device will automatically return to AIS data mode if rebooted.\r\n");
|
||||
break;
|
||||
}
|
||||
case PROGRAMMING_SCREEN:
|
||||
break;
|
||||
}
|
||||
|
||||
mCurrentScreen = screen;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
@ -201,13 +174,7 @@ void USART3_IRQHandler(void)
|
||||
{
|
||||
if ( USART_GetITStatus(USART3, USART_IT_RXNE) ) {
|
||||
char c = (char) USART3->RDR; // This clears the interrupt right away
|
||||
KeyPressEvent *e = static_cast<KeyPressEvent*>(EventPool::instance().newEvent(KEYPRESS_EVENT));
|
||||
if ( e == NULL )
|
||||
return;
|
||||
|
||||
e->key = c;
|
||||
EventQueue::instance().push(e);
|
||||
//DataTerminal::instance().processCharacter(c);
|
||||
DataTerminal::instance().processCharacter(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,11 @@
|
||||
|
||||
#include "globals.h"
|
||||
#include "EventQueue.hpp"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#ifdef ENABLE_TERMINAL
|
||||
|
||||
|
||||
@ -20,31 +25,22 @@ public:
|
||||
|
||||
void init();
|
||||
|
||||
void processEvent(Event *e);
|
||||
void processEvent(const Event &e);
|
||||
#ifdef MULTIPLEXED_OUTPUT
|
||||
void write(const char* cls, const char* line, bool interactive=false);
|
||||
void write(const char* cls, const char* line);
|
||||
#else
|
||||
void write(const char* line, bool interactive = false);
|
||||
void write(const char* line);
|
||||
#endif
|
||||
void processCharacter(char c);
|
||||
private:
|
||||
DataTerminal();
|
||||
void processCommand();
|
||||
|
||||
typedef enum {
|
||||
MAIN_SCREEN = 0,
|
||||
PROGRAMMING_SCREEN = 1
|
||||
}
|
||||
MenuScreen;
|
||||
|
||||
void showScreen(MenuScreen s);
|
||||
|
||||
void clearScreen();
|
||||
void _write(const char* s);
|
||||
private:
|
||||
//uint32_t mTimeSlot;
|
||||
uint8_t mEscapes;
|
||||
MenuScreen mCurrentScreen;
|
||||
bool mInteractive;
|
||||
char mCmdBuffer[64];
|
||||
size_t mCmdBuffPos;
|
||||
vector<string> mCmdTokens;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
@ -18,9 +18,9 @@ DebugPrinter::~DebugPrinter()
|
||||
{
|
||||
}
|
||||
|
||||
void DebugPrinter::processEvent(Event *e)
|
||||
void DebugPrinter::processEvent(const Event &e)
|
||||
{
|
||||
DebugEvent *event = static_cast<DebugEvent*>(e);
|
||||
printf2(event->mBuffer);
|
||||
//DebugEvent *event = static_cast<DebugEvent*>(e);
|
||||
printf2(e.debugMessage.buffer);
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ public:
|
||||
DebugPrinter();
|
||||
virtual ~DebugPrinter();
|
||||
|
||||
void processEvent(Event* e);
|
||||
void processEvent(const Event &e);
|
||||
};
|
||||
|
||||
#endif /* DEBUGPRINTER_HPP_ */
|
||||
|
@ -58,11 +58,11 @@ void EventQueue::dispatch()
|
||||
|
||||
for ( map<EventConsumer*, uint32_t>::iterator c = mConsumers.begin(); c != mConsumers.end(); ++c ) {
|
||||
// Utils::delay(1000);
|
||||
if ( c->second & e->type() )
|
||||
c->first->processEvent(e);
|
||||
if ( c->second & e->type )
|
||||
c->first->processEvent(*e);
|
||||
}
|
||||
EventPool::instance().deleteEvent(e);
|
||||
if ( e->type() == AIS_PACKET_EVENT )
|
||||
if ( e->type == AIS_PACKET_EVENT )
|
||||
LEDManager::instance().blink(LEDManager::GREEN_LED);
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,9 @@ typedef enum {
|
||||
AIS_PACKET_EVENT = 8, // A packet was just decoded (not necessarily valid, must still be CRC checked, etc)
|
||||
INTERROGATION_EVENT = 16,
|
||||
DEBUG_EVENT = 32,
|
||||
KEYPRESS_EVENT = 64
|
||||
KEYPRESS_EVENT = 64,
|
||||
REQUEST_EVENT = 128,
|
||||
RESPONSE_EVENT = 256
|
||||
//GPS_ERROR_EVENT = 64, // A GPS failure
|
||||
//TRX_ERROR_EVENT = 128 // A radio failure
|
||||
}
|
||||
|
@ -17,89 +17,19 @@ EventPool &EventPool::instance()
|
||||
|
||||
void EventPool::init()
|
||||
{
|
||||
mGenericPool = new ObjectPool<Event>(10);
|
||||
mAISPacketPool = new ObjectPool<AISPacketEvent>(40);
|
||||
mGPSNMEAPool = new ObjectPool<GPSNMEASentence>(20);
|
||||
mGPSFixPool = new ObjectPool<GPSFIXEvent>(10);
|
||||
mClockPool = new ObjectPool<ClockEvent>(10);
|
||||
mDebugEventPool = new ObjectPool<DebugEvent>(2);
|
||||
mKeyPressPool = new ObjectPool<KeyPressEvent>(20);
|
||||
mGenericPool = new ObjectPool<Event>(40);
|
||||
}
|
||||
|
||||
Event *EventPool::newEvent(EventType type)
|
||||
{
|
||||
Event *result = NULL;
|
||||
switch(type) {
|
||||
case GPS_NMEA_SENTENCE:
|
||||
result = mGPSNMEAPool->get();
|
||||
break;
|
||||
case GPS_FIX_EVENT:
|
||||
result = mGPSFixPool->get();
|
||||
break;
|
||||
case CLOCK_EVENT:
|
||||
result = mClockPool->get();
|
||||
break;
|
||||
case AIS_PACKET_EVENT: {
|
||||
result = mAISPacketPool->get();
|
||||
break;
|
||||
}
|
||||
case DEBUG_EVENT: {
|
||||
result = mDebugEventPool->get();
|
||||
break;
|
||||
}
|
||||
case KEYPRESS_EVENT: {
|
||||
result = mKeyPressPool->get();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
result = mGenericPool->get();
|
||||
result->mType = type;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( result )
|
||||
result->prepare();
|
||||
|
||||
Event *result = mGenericPool->get();
|
||||
result->type = type;
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
void EventPool::deleteEvent(Event *event)
|
||||
{
|
||||
event->clear();
|
||||
switch(event->type()) {
|
||||
case GPS_NMEA_SENTENCE: {
|
||||
GPSNMEASentence *e = static_cast<GPSNMEASentence*>(event);
|
||||
mGPSNMEAPool->put(e);
|
||||
break;
|
||||
}
|
||||
case GPS_FIX_EVENT: {
|
||||
GPSFIXEvent *e = static_cast<GPSFIXEvent*>(event);
|
||||
mGPSFixPool->put(e);
|
||||
break;
|
||||
}
|
||||
case CLOCK_EVENT:{
|
||||
ClockEvent *e = static_cast<ClockEvent*>(event);
|
||||
mClockPool->put(e);
|
||||
break;
|
||||
}
|
||||
case AIS_PACKET_EVENT: {
|
||||
AISPacketEvent *p = static_cast<AISPacketEvent*>(event);
|
||||
mAISPacketPool->put(p);
|
||||
break;
|
||||
}
|
||||
case DEBUG_EVENT: {
|
||||
DebugEvent *e = static_cast<DebugEvent*>(event);
|
||||
mDebugEventPool->put(e);
|
||||
break;
|
||||
}
|
||||
case KEYPRESS_EVENT: {
|
||||
KeyPressEvent *e = static_cast<KeyPressEvent*>(event);
|
||||
mKeyPressPool->put(e);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
mGenericPool->put(event);
|
||||
break;
|
||||
}
|
||||
mGenericPool->put(event);
|
||||
}
|
||||
|
||||
|
@ -19,37 +19,64 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
typedef struct {
|
||||
char sentence[100];
|
||||
} NMEABuffer;
|
||||
|
||||
typedef struct {
|
||||
time_t utc;
|
||||
double lat;
|
||||
double lng;
|
||||
double speed;
|
||||
double cog;
|
||||
} GPSFix;
|
||||
|
||||
typedef struct {
|
||||
time_t utc;
|
||||
} ClockTick;
|
||||
|
||||
typedef struct {
|
||||
char buffer[128];
|
||||
} DebugMessage;
|
||||
|
||||
typedef enum {
|
||||
OP_GET,
|
||||
OP_SET
|
||||
} Operation;
|
||||
|
||||
|
||||
typedef struct {
|
||||
Operation operation;
|
||||
char field[16];
|
||||
char value[64];
|
||||
} Request;
|
||||
|
||||
typedef struct {
|
||||
bool success;
|
||||
char data[64];
|
||||
} Response;
|
||||
|
||||
/*
|
||||
* All events extend this class
|
||||
*/
|
||||
class Event
|
||||
{
|
||||
friend class EventPool;
|
||||
public:
|
||||
EventType type;
|
||||
|
||||
Event()
|
||||
: mType(UNKNOWN_EVENT) {
|
||||
: type(UNKNOWN_EVENT) {
|
||||
}
|
||||
|
||||
Event (EventType type): mType(type) {
|
||||
}
|
||||
|
||||
virtual ~Event () {
|
||||
}
|
||||
|
||||
virtual void prepare() {
|
||||
}
|
||||
|
||||
virtual void clear() {
|
||||
}
|
||||
|
||||
virtual EventType type() {
|
||||
return mType;
|
||||
}
|
||||
protected:
|
||||
EventType mType;
|
||||
union {
|
||||
NMEABuffer nmeaBuffer;
|
||||
GPSFix gpsFix;
|
||||
DebugMessage debugMessage;
|
||||
RXPacket rxPacket;
|
||||
ClockTick clock;
|
||||
Request request;
|
||||
Response response;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Event consumer abstract definition.
|
||||
*/
|
||||
@ -58,87 +85,7 @@ class EventConsumer
|
||||
{
|
||||
public:
|
||||
virtual ~EventConsumer() {}
|
||||
virtual void processEvent(Event *event)=0;
|
||||
};
|
||||
|
||||
class GPSNMEASentence : public Event
|
||||
{
|
||||
public:
|
||||
GPSNMEASentence()
|
||||
: Event(GPS_NMEA_SENTENCE){
|
||||
}
|
||||
|
||||
char mSentence[100];
|
||||
};
|
||||
|
||||
class GPSFIXEvent: public Event
|
||||
{
|
||||
public:
|
||||
GPSFIXEvent()
|
||||
: Event(GPS_FIX_EVENT) {
|
||||
}
|
||||
|
||||
time_t mUTC;
|
||||
double mLat;
|
||||
double mLng;
|
||||
double mSpeed;
|
||||
double mCOG;
|
||||
};
|
||||
|
||||
class ClockEvent : public Event
|
||||
{
|
||||
public:
|
||||
ClockEvent()
|
||||
: Event(CLOCK_EVENT) {
|
||||
}
|
||||
|
||||
|
||||
time_t mTime;
|
||||
};
|
||||
|
||||
class AISPacketEvent: public Event
|
||||
{
|
||||
public:
|
||||
AISPacketEvent()
|
||||
: Event(AIS_PACKET_EVENT) {
|
||||
}
|
||||
|
||||
|
||||
void prepare()
|
||||
{
|
||||
//mPacket = RXPacketPool::instance().newRXPacket();
|
||||
//mPacket->reset();
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
RXPacketPool::instance().deleteRXPacket(mPacket);
|
||||
mPacket = NULL;
|
||||
}
|
||||
|
||||
RXPacket *mPacket;
|
||||
};
|
||||
|
||||
|
||||
class DebugEvent: public Event
|
||||
{
|
||||
public:
|
||||
DebugEvent()
|
||||
: Event(DEBUG_EVENT) {
|
||||
}
|
||||
|
||||
char mBuffer[256];
|
||||
};
|
||||
|
||||
class KeyPressEvent : public Event
|
||||
{
|
||||
public:
|
||||
KeyPressEvent()
|
||||
: Event(KEYPRESS_EVENT) {
|
||||
}
|
||||
|
||||
|
||||
char key;
|
||||
virtual void processEvent(const Event &event)=0;
|
||||
};
|
||||
|
||||
class EventPool
|
||||
@ -152,12 +99,6 @@ public:
|
||||
|
||||
private:
|
||||
ObjectPool<Event> *mGenericPool;
|
||||
ObjectPool<AISPacketEvent> *mAISPacketPool;
|
||||
ObjectPool<GPSNMEASentence> *mGPSNMEAPool;
|
||||
ObjectPool<GPSFIXEvent> *mGPSFixPool;
|
||||
ObjectPool<ClockEvent> *mClockPool;
|
||||
ObjectPool<DebugEvent> *mDebugEventPool;
|
||||
ObjectPool<KeyPressEvent> *mKeyPressPool;
|
||||
};
|
||||
|
||||
|
||||
|
@ -161,9 +161,9 @@ void GPS::onRX(char c)
|
||||
}
|
||||
else if (c == '\n') {
|
||||
mBuff[mBuffPos] = 0;
|
||||
GPSNMEASentence *event = static_cast<GPSNMEASentence*>(EventPool::instance().newEvent(GPS_NMEA_SENTENCE));
|
||||
Event *event = EventPool::instance().newEvent(GPS_NMEA_SENTENCE);
|
||||
if ( event ) {
|
||||
memcpy(event->mSentence, mBuff, sizeof event->mSentence);
|
||||
memcpy(event->nmeaBuffer.sentence, mBuff, sizeof event->nmeaBuffer.sentence);
|
||||
EventQueue::instance ().push (event);
|
||||
}
|
||||
mBuffPos = 0;
|
||||
@ -203,20 +203,20 @@ void GPS::onPPS()
|
||||
}
|
||||
}
|
||||
|
||||
ClockEvent *event = static_cast<ClockEvent*>(EventPool::instance().newEvent(CLOCK_EVENT));
|
||||
Event *event = EventPool::instance().newEvent(CLOCK_EVENT);
|
||||
if ( event ) {
|
||||
event->mTime = mUTC;
|
||||
event->clock.utc = mUTC;
|
||||
EventQueue::instance ().push(event);
|
||||
}
|
||||
} // We have a valid UTC timestamp
|
||||
|
||||
}
|
||||
|
||||
void GPS::processEvent(Event *event)
|
||||
void GPS::processEvent(const Event &event)
|
||||
{
|
||||
//printf2("-> GPS::processEvent()\r\n");
|
||||
GPSNMEASentence *s = static_cast<GPSNMEASentence*>(event);
|
||||
processLine(s->mSentence);
|
||||
|
||||
processLine(event.nmeaBuffer.sentence);
|
||||
//printf2("<- GPS::processEvent()\r\n");
|
||||
}
|
||||
|
||||
@ -295,13 +295,13 @@ void GPS::parseSentence(const char *buff)
|
||||
mLng = Utils::longitudeFromNMEA(sentence.fields()[5], sentence.fields()[6]);
|
||||
mSpeed = Utils::toDouble(sentence.fields()[7]);
|
||||
mCOG = Utils::toDouble(sentence.fields()[8]);
|
||||
GPSFIXEvent *event = static_cast<GPSFIXEvent*>(EventPool::instance().newEvent(GPS_FIX_EVENT));
|
||||
Event *event = EventPool::instance().newEvent(GPS_FIX_EVENT);
|
||||
if ( event ) {
|
||||
event->mUTC = mUTC;
|
||||
event->mLat = mLat;
|
||||
event->mLng = mLng;
|
||||
event->mSpeed = mSpeed;
|
||||
event->mCOG = mCOG;
|
||||
event->gpsFix.utc = mUTC;
|
||||
event->gpsFix.lat = mLat;
|
||||
event->gpsFix.lng = mLng;
|
||||
event->gpsFix.speed = mSpeed;
|
||||
event->gpsFix.cog = mCOG;
|
||||
EventQueue::instance().push(event);
|
||||
}
|
||||
//printf2("Lat: %f, Lng: %f\r\n", mLat, mLng);
|
||||
|
@ -43,7 +43,7 @@ public:
|
||||
void setDelegate(GPSDelegate *delegate);
|
||||
|
||||
void onIRQ(uint32_t mask, void *data);
|
||||
void processEvent(Event *event);
|
||||
void processEvent(const Event &event);
|
||||
private:
|
||||
GPS();
|
||||
void reset();
|
||||
|
@ -51,15 +51,14 @@ uint8_t NoiseFloorDetector::getNoiseFloor(VHFChannel channel)
|
||||
}
|
||||
|
||||
|
||||
void NoiseFloorDetector::processEvent(Event *e)
|
||||
void NoiseFloorDetector::processEvent(const Event &e)
|
||||
{
|
||||
ClockEvent *ce = static_cast<ClockEvent*>(e);
|
||||
if ( mUTC == 0 ) {
|
||||
if ( e.clock.utc == 0 ) {
|
||||
printf2("Starting RSSI sample collection\r\n");
|
||||
mStartTime = ce->mTime;
|
||||
mStartTime = e.clock.utc;
|
||||
mLastDumpTime = mStartTime;
|
||||
}
|
||||
mUTC = ce->mTime;
|
||||
mUTC = e.clock.utc;
|
||||
|
||||
if ( mUTC - mLastDumpTime >= 30 )
|
||||
dump();
|
||||
|
@ -28,7 +28,7 @@ public:
|
||||
// Returns the current noise floor of the channel, 0xff if unknown
|
||||
uint8_t getNoiseFloor(VHFChannel channelIndex);
|
||||
|
||||
void processEvent(Event *e);
|
||||
void processEvent(const Event &e);
|
||||
private:
|
||||
typedef struct {
|
||||
time_t timestamp;
|
||||
|
@ -26,7 +26,7 @@ void RXPacket::setChannel(VHFChannel channel)
|
||||
mChannel = channel;
|
||||
}
|
||||
|
||||
VHFChannel RXPacket::channel()
|
||||
VHFChannel RXPacket::channel() const
|
||||
{
|
||||
return mChannel;
|
||||
}
|
||||
@ -75,7 +75,7 @@ void RXPacket::setSlot(uint32_t slot)
|
||||
mSlot = slot;
|
||||
}
|
||||
|
||||
uint32_t RXPacket::slot()
|
||||
uint32_t RXPacket::slot() const
|
||||
{
|
||||
return mSlot;
|
||||
}
|
||||
@ -86,7 +86,7 @@ void RXPacket::setRSSI(uint8_t rssi)
|
||||
mRSSI = rssi;
|
||||
}
|
||||
|
||||
uint8_t RXPacket::rssi()
|
||||
uint8_t RXPacket::rssi() const
|
||||
{
|
||||
return mRSSI;
|
||||
}
|
||||
@ -107,7 +107,7 @@ void RXPacket::addBit(uint8_t bit)
|
||||
++mSize;
|
||||
}
|
||||
|
||||
uint8_t RXPacket::bit(uint16_t pos)
|
||||
uint8_t RXPacket::bit(uint16_t pos) const
|
||||
{
|
||||
if ( pos < mSize ) {
|
||||
uint16_t index = pos / 8;
|
||||
@ -119,7 +119,7 @@ uint8_t RXPacket::bit(uint16_t pos)
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t RXPacket::bits(uint16_t pos, uint8_t count)
|
||||
uint32_t RXPacket::bits(uint16_t pos, uint8_t count) const
|
||||
{
|
||||
ASSERT(count <= 32);
|
||||
uint32_t result = 0;
|
||||
@ -166,13 +166,13 @@ void RXPacket::addByte(uint8_t byte)
|
||||
}
|
||||
|
||||
|
||||
uint16_t RXPacket::size()
|
||||
uint16_t RXPacket::size() const
|
||||
{
|
||||
return mSize;
|
||||
}
|
||||
|
||||
|
||||
bool RXPacket::isBad()
|
||||
bool RXPacket::isBad() const
|
||||
{
|
||||
/*
|
||||
* We don't anticipate anything less than 168 + 16 = 184 bits
|
||||
@ -182,7 +182,7 @@ bool RXPacket::isBad()
|
||||
return mSize < 64;
|
||||
}
|
||||
|
||||
uint16_t RXPacket::crc()
|
||||
uint16_t RXPacket::crc() const
|
||||
{
|
||||
return mCRC;
|
||||
}
|
||||
@ -203,7 +203,7 @@ void RXPacket::addFillBits(uint8_t numBits)
|
||||
|
||||
|
||||
|
||||
bool RXPacket::checkCRC()
|
||||
bool RXPacket::checkCRC() const
|
||||
{
|
||||
//uint16_t rcrc = ((mCRC & 0xff00) >> 8) | ((mCRC & 0x00ff) << 8);
|
||||
//trace_printf("%.4x %.4x %.4x\n", mCRC, ~(mCRC), ~(rcrc));
|
||||
@ -211,7 +211,7 @@ bool RXPacket::checkCRC()
|
||||
|
||||
}
|
||||
|
||||
uint8_t RXPacket::messageType()
|
||||
uint8_t RXPacket::messageType() const
|
||||
{
|
||||
if ( mType )
|
||||
return mType;
|
||||
@ -224,7 +224,7 @@ uint8_t RXPacket::messageType()
|
||||
return mType;
|
||||
}
|
||||
|
||||
uint8_t RXPacket::repeatIndicator()
|
||||
uint8_t RXPacket::repeatIndicator() const
|
||||
{
|
||||
if ( mRI )
|
||||
return mRI;
|
||||
@ -233,7 +233,7 @@ uint8_t RXPacket::repeatIndicator()
|
||||
return mRI;
|
||||
}
|
||||
|
||||
uint32_t RXPacket::mmsi()
|
||||
uint32_t RXPacket::mmsi() const
|
||||
{
|
||||
if ( mMMSI )
|
||||
return mMMSI;
|
||||
@ -253,6 +253,7 @@ uint32_t RXPacket::mmsi()
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if 0
|
||||
RXPacketPool &RXPacketPool::instance()
|
||||
{
|
||||
static RXPacketPool __instance;
|
||||
@ -274,6 +275,6 @@ void RXPacketPool::deleteRXPacket(RXPacket *p)
|
||||
ASSERT(p);
|
||||
mPool->put(p);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -17,20 +17,17 @@ using namespace std;
|
||||
|
||||
class RXPacket
|
||||
{
|
||||
friend class RXPacketPool;
|
||||
public:
|
||||
RXPacket ();
|
||||
private:
|
||||
~RXPacket ();
|
||||
RXPacket(const RXPacket ©);
|
||||
RXPacket &operator=(const RXPacket ©);
|
||||
~RXPacket ();
|
||||
public:
|
||||
|
||||
//void setStuffed(bool);
|
||||
void setSlot(uint32_t slot);
|
||||
|
||||
void setChannel(VHFChannel channel);
|
||||
VHFChannel channel();
|
||||
VHFChannel channel() const;
|
||||
|
||||
|
||||
void discardCRC();
|
||||
@ -38,25 +35,25 @@ public:
|
||||
|
||||
void addByte(uint8_t byte);
|
||||
|
||||
uint16_t size();
|
||||
uint8_t bit(uint16_t pos);
|
||||
uint32_t bits(uint16_t pos, uint8_t count);
|
||||
uint16_t size() const;
|
||||
uint8_t bit(uint16_t pos) const;
|
||||
uint32_t bits(uint16_t pos, uint8_t count) const;
|
||||
|
||||
uint16_t crc();
|
||||
bool checkCRC();
|
||||
bool isBad();
|
||||
uint16_t crc() const;
|
||||
bool checkCRC() const;
|
||||
bool isBad() const;
|
||||
void reset();
|
||||
|
||||
|
||||
|
||||
// Every AIS message contains these 3 attributes at a minimum, so we expose them at the packet level
|
||||
uint8_t messageType();
|
||||
uint8_t repeatIndicator();
|
||||
uint32_t mmsi();
|
||||
uint8_t messageType() const;
|
||||
uint8_t repeatIndicator() const;
|
||||
uint32_t mmsi() const;
|
||||
|
||||
// These are link-level attributes
|
||||
uint32_t slot();
|
||||
uint8_t rssi();
|
||||
uint32_t slot() const;
|
||||
uint8_t rssi() const;
|
||||
void setRSSI(uint8_t);
|
||||
private:
|
||||
void addBit(uint8_t bit);
|
||||
@ -65,15 +62,15 @@ private:
|
||||
uint8_t mPacket[MAX_AIS_RX_PACKET_SIZE/8+1];
|
||||
uint16_t mSize;
|
||||
uint16_t mCRC;
|
||||
uint8_t mType;
|
||||
uint8_t mRI;
|
||||
uint32_t mMMSI;
|
||||
mutable uint8_t mType;
|
||||
mutable uint8_t mRI;
|
||||
mutable uint32_t mMMSI;
|
||||
uint32_t mSlot;
|
||||
VHFChannel mChannel;
|
||||
uint8_t mRSSI;
|
||||
};
|
||||
|
||||
|
||||
#if 0
|
||||
class RXPacketPool
|
||||
{
|
||||
public:
|
||||
@ -88,6 +85,6 @@ private:
|
||||
ObjectPool<RXPacket> *mPool;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* RXPACKET_HPP_ */
|
||||
|
@ -31,23 +31,23 @@ RXPacketProcessor::~RXPacketProcessor ()
|
||||
// Should never be called
|
||||
}
|
||||
|
||||
void RXPacketProcessor::processEvent(Event *e)
|
||||
void RXPacketProcessor::processEvent(const Event &e)
|
||||
{
|
||||
//printf2("-> RXPacketProcessor::processEvent()\r\n");
|
||||
switch(e->type()) {
|
||||
switch(e.type) {
|
||||
case GPS_FIX_EVENT: {
|
||||
GPSFIXEvent *gfe = static_cast<GPSFIXEvent*> (e);
|
||||
mLat = gfe->mLat;
|
||||
mLng = gfe->mLng;
|
||||
//GPSFIXEvent *gfe = static_cast<GPSFIXEvent*> (e);
|
||||
mLat = e.gpsFix.lat;
|
||||
mLng = e.gpsFix.lng;
|
||||
break;
|
||||
}
|
||||
case CLOCK_EVENT: {
|
||||
ClockEvent *pe = static_cast<ClockEvent*>(e);
|
||||
//ClockEvent *pe = static_cast<ClockEvent*>(e);
|
||||
if ( mLastDumpTime == 0 ) {
|
||||
mLastDumpTime = pe->mTime;
|
||||
mLastDumpTime = e.clock.utc;
|
||||
}
|
||||
else if ( pe->mTime - mLastDumpTime >= 60 ) {
|
||||
mLastDumpTime = pe->mTime;
|
||||
else if ( e.clock.utc - mLastDumpTime >= 60 ) {
|
||||
mLastDumpTime = e.clock.utc;
|
||||
float yield = (float)mGoodCount / (float)(mGoodCount+mBadCRCCount+mInvalidCount);
|
||||
printf2("\r\n");
|
||||
printf2("[Yield: %.1fpct, Valid: %d, Wrong CRC: %d, Malformed: %d]\r\n", yield*100.0, mGoodCount, mBadCRCCount, mInvalidCount);
|
||||
@ -63,31 +63,30 @@ void RXPacketProcessor::processEvent(Event *e)
|
||||
break;
|
||||
}
|
||||
case AIS_PACKET_EVENT: {
|
||||
AISPacketEvent *pe = static_cast<AISPacketEvent*>(e);
|
||||
if ( pe->mPacket->isBad() ) {
|
||||
//AISPacketEvent *pe = static_cast<AISPacketEvent*>(e);
|
||||
if ( e.rxPacket.isBad() ) {
|
||||
++mInvalidCount;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if (pe->mPacket->checkCRC ()) {
|
||||
if (e.rxPacket.checkCRC ()) {
|
||||
++mGoodCount;
|
||||
|
||||
mUniqueMMSIs.insert (pe->mPacket->mmsi ());
|
||||
switch (pe->mPacket->messageType ()) {
|
||||
mUniqueMMSIs.insert (e.rxPacket.mmsi ());
|
||||
switch (e.rxPacket.messageType()) {
|
||||
case 1:
|
||||
case 2:
|
||||
case 3: {
|
||||
AISMessage123 msg;
|
||||
if (msg.decode (*pe->mPacket)) {
|
||||
double distance = Utils::haversineDistance (
|
||||
mLat, mLng, msg.latitude, msg.longitude);
|
||||
if (msg.decode (e.rxPacket)) {
|
||||
double distance = Utils::haversineDistance (mLat, mLng, msg.latitude, msg.longitude);
|
||||
double miles = distance / METERS_PER_NAUTICAL_MILE;
|
||||
|
||||
printf2 (
|
||||
"RSSI: %.2x, Ch: %c, Type: %d, MMSI: %d, Speed: %.1f kts, Pos: %.5f,%.5f, Dist: %.1f NM\r\n",
|
||||
pe->mPacket->rssi (),
|
||||
AIS_CHANNELS[pe->mPacket->channel ()].designation,
|
||||
e.rxPacket.rssi(),
|
||||
AIS_CHANNELS[e.rxPacket.channel()].designation,
|
||||
msg.type(), msg.mmsi(), msg.sog,
|
||||
msg.latitude, msg.longitude, miles);
|
||||
|
||||
@ -96,14 +95,13 @@ void RXPacketProcessor::processEvent(Event *e)
|
||||
}
|
||||
case 18: {
|
||||
AISMessage18 msg;
|
||||
if (msg.decode (*pe->mPacket)) {
|
||||
double distance = Utils::haversineDistance (
|
||||
mLat, mLng, msg.latitude, msg.longitude);
|
||||
if (msg.decode (e.rxPacket)) {
|
||||
double distance = Utils::haversineDistance (mLat, mLng, msg.latitude, msg.longitude);
|
||||
double miles = distance / METERS_PER_NAUTICAL_MILE;
|
||||
|
||||
printf2 ("RSSI: %.2x, Ch: %c, Type: %d, MMSI: %d, Speed: %.1f kts, Pos: %.5f,%.5f, Dist: %.1f NM\r\n",
|
||||
pe->mPacket->rssi (),
|
||||
AIS_CHANNELS[pe->mPacket->channel ()].designation,
|
||||
e.rxPacket.rssi (),
|
||||
AIS_CHANNELS[e.rxPacket.channel()].designation,
|
||||
msg.type(), msg.mmsi(), msg.sog,
|
||||
msg.latitude, msg.longitude, miles);
|
||||
|
||||
@ -114,11 +112,11 @@ void RXPacketProcessor::processEvent(Event *e)
|
||||
|
||||
printf2 (
|
||||
"RSSI: %.2x, Ch: %c, Type: %d, RI: %d, MMSI: %d\r\n",
|
||||
pe->mPacket->rssi (),
|
||||
AIS_CHANNELS[pe->mPacket->channel ()].designation,
|
||||
pe->mPacket->messageType (),
|
||||
pe->mPacket->repeatIndicator (),
|
||||
pe->mPacket->mmsi ());
|
||||
e.rxPacket.rssi (),
|
||||
AIS_CHANNELS[e.rxPacket.channel()].designation,
|
||||
e.rxPacket.messageType (),
|
||||
e.rxPacket.repeatIndicator (),
|
||||
e.rxPacket.mmsi ());
|
||||
|
||||
break;
|
||||
}
|
||||
@ -126,7 +124,8 @@ void RXPacketProcessor::processEvent(Event *e)
|
||||
|
||||
#ifdef ENABLE_TERMINAL
|
||||
mSentences.clear();
|
||||
mEncoder.encode(*pe->mPacket, mSentences);
|
||||
RXPacket p(e.rxPacket);
|
||||
mEncoder.encode(p, mSentences);
|
||||
for (vector<string>::iterator i = mSentences.begin(); i != mSentences.end(); ++i) {
|
||||
#ifdef MULTIPLEXED_OUTPUT
|
||||
sprintf(__buff, "%s\r\n", i->c_str());
|
||||
@ -137,7 +136,7 @@ void RXPacketProcessor::processEvent(Event *e)
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
switch (pe->mPacket->messageType()) {
|
||||
switch (e.rxPacket.messageType()) {
|
||||
case 15:
|
||||
// TODO: This is an interrogation. If we are a target, push an appropriate event into the queue
|
||||
break;
|
||||
|
@ -21,7 +21,7 @@ public:
|
||||
virtual
|
||||
~RXPacketProcessor ();
|
||||
|
||||
void processEvent(Event *e);
|
||||
void processEvent(const Event &e);
|
||||
private:
|
||||
NMEAEncoder mEncoder;
|
||||
time_t mLastDumpTime;
|
||||
|
@ -228,10 +228,10 @@ void RadioManager::configureInterrupts()
|
||||
|
||||
}
|
||||
|
||||
void RadioManager::processEvent(Event *e)
|
||||
void RadioManager::processEvent(const Event &e)
|
||||
{
|
||||
ClockEvent *ce = static_cast<ClockEvent*>(e);
|
||||
mUTC = ce->mTime;
|
||||
//ClockEvent *ce = static_cast<ClockEvent*>(e);
|
||||
mUTC = e.clock.utc;
|
||||
|
||||
// Evaluate the state of the transceiver IC and our queue ...
|
||||
if ( mTransceiverIC->assignedTXPacket() == NULL ) {
|
||||
|
@ -30,7 +30,7 @@ public:
|
||||
void scheduleTransmission(TXPacket *p);
|
||||
bool initialized();
|
||||
|
||||
void processEvent(Event *e);
|
||||
void processEvent(const Event &e);
|
||||
void transmitCW(VHFChannel channel);
|
||||
VHFChannel alternateChannel(VHFChannel channel);
|
||||
private:
|
||||
|
@ -33,7 +33,6 @@ bool Receiver::init()
|
||||
{
|
||||
printf2("Configuring IC\r\n");
|
||||
configure();
|
||||
mRXPacket = RXPacketPool::instance().newRXPacket();
|
||||
resetBitScanner();
|
||||
return true;
|
||||
}
|
||||
@ -75,8 +74,7 @@ void Receiver::resetBitScanner()
|
||||
mRXByte = 0;
|
||||
mBitState = BIT_STATE_PREAMBLE_SYNC;
|
||||
|
||||
ASSERT(mRXPacket);
|
||||
mRXPacket->reset();
|
||||
mRXPacket.reset();
|
||||
}
|
||||
|
||||
void Receiver::onBitClock()
|
||||
@ -93,7 +91,7 @@ void Receiver::onBitClock()
|
||||
rssi = readRSSI();
|
||||
rssi += mRSSIAdjustment;
|
||||
NoiseFloorDetector::instance().report(mChannel, rssi);
|
||||
mRXPacket->setRSSI(rssi);
|
||||
mRXPacket.setRSSI(rssi);
|
||||
}
|
||||
}
|
||||
|
||||
@ -108,7 +106,7 @@ void Receiver::timeSlotStarted(uint32_t slot)
|
||||
if ( mBitState == BIT_STATE_IN_PACKET )
|
||||
return;
|
||||
|
||||
mRXPacket->setSlot(slot);
|
||||
mRXPacket.setSlot(slot);
|
||||
if ( mSwitchAtNextSlot ) {
|
||||
mSwitchAtNextSlot = false;
|
||||
startReceiving(mSwitchToChannel);
|
||||
@ -136,13 +134,13 @@ void Receiver::processNRZIBit(uint8_t bit)
|
||||
*/
|
||||
if ( mBitWindow == 0b1010101001111110 || mBitWindow == 0b0101010101111110 ) {
|
||||
mBitState = BIT_STATE_IN_PACKET;
|
||||
mRXPacket->setChannel(mChannel);
|
||||
mRXPacket.setChannel(mChannel);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case BIT_STATE_IN_PACKET: {
|
||||
if ( mRXPacket->size() >= MAX_AIS_RX_PACKET_SIZE ) {
|
||||
if ( mRXPacket.size() >= MAX_AIS_RX_PACKET_SIZE ) {
|
||||
// Start over
|
||||
startReceiving(mChannel);
|
||||
//resetBitScanner();
|
||||
@ -200,7 +198,7 @@ bool Receiver::addBit(uint8_t bit)
|
||||
|
||||
if ( mBitCount == 8 ) {
|
||||
// Commit to the packet!
|
||||
mRXPacket->addByte(mRXByte);
|
||||
mRXPacket.addByte(mRXByte);
|
||||
mBitCount = 0;
|
||||
mRXByte = 0;
|
||||
}
|
||||
@ -210,15 +208,16 @@ bool Receiver::addBit(uint8_t bit)
|
||||
|
||||
void Receiver::pushPacket()
|
||||
{
|
||||
AISPacketEvent *p = static_cast<AISPacketEvent*>(EventPool::instance().newEvent(AIS_PACKET_EVENT));
|
||||
Event *p = EventPool::instance().newEvent(AIS_PACKET_EVENT);
|
||||
if ( p == NULL ) {
|
||||
printf2("AISPacket allocation failed\r\n");
|
||||
return;
|
||||
}
|
||||
|
||||
p->mPacket = mRXPacket;
|
||||
mRXPacket = RXPacketPool::instance().newRXPacket();
|
||||
ASSERT(mRXPacket);
|
||||
p->rxPacket = mRXPacket;
|
||||
mRXPacket.reset();
|
||||
//mRXPacket = RXPacketPool::instance().newRXPacket();
|
||||
//ASSERT(mRXPacket);
|
||||
EventQueue::instance().push(p);
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ private:
|
||||
void resetBitScanner();
|
||||
void configureGPIOs();
|
||||
protected:
|
||||
RXPacket *mRXPacket;
|
||||
RXPacket mRXPacket;
|
||||
uint16_t mBitWindow;
|
||||
uint8_t mLastNRZIBit;
|
||||
uint32_t mBitCount;
|
||||
|
@ -44,18 +44,18 @@ void TXScheduler::startTXTesting()
|
||||
mTesting = true;
|
||||
}
|
||||
|
||||
void TXScheduler::processEvent(Event *event)
|
||||
void TXScheduler::processEvent(const Event &e)
|
||||
{
|
||||
#ifndef ENABLE_TX
|
||||
return;
|
||||
#endif
|
||||
|
||||
switch(event->type()) {
|
||||
switch(e.type) {
|
||||
case GPS_FIX_EVENT: {
|
||||
if ( mTesting )
|
||||
return;
|
||||
|
||||
GPSFIXEvent *gfe = static_cast<GPSFIXEvent*> (event);
|
||||
//GPSFIXEvent *gfe = static_cast<GPSFIXEvent*> (event);
|
||||
|
||||
//printf2("UTC: %d\r\n", mUTC);
|
||||
|
||||
@ -74,11 +74,11 @@ void TXScheduler::processEvent(Event *event)
|
||||
}
|
||||
AISMessage18 msg;
|
||||
|
||||
msg.latitude = gfe->mLat;
|
||||
msg.longitude = gfe->mLng;
|
||||
msg.sog = gfe->mSpeed;
|
||||
msg.cog = gfe->mCOG;
|
||||
msg.utc = gfe->mUTC;
|
||||
msg.latitude = e.gpsFix.lat;
|
||||
msg.longitude = e.gpsFix.lng;
|
||||
msg.sog = e.gpsFix.speed;
|
||||
msg.cog = e.gpsFix.cog;
|
||||
msg.utc = e.gpsFix.utc;
|
||||
|
||||
msg.encode (mStationData, *p1);
|
||||
RadioManager::instance ().scheduleTransmission (p1);
|
||||
@ -116,8 +116,8 @@ void TXScheduler::processEvent(Event *event)
|
||||
}
|
||||
case CLOCK_EVENT: {
|
||||
// This is reliable and independent of GPS update frequency which could change to something other than 1Hz
|
||||
ClockEvent *c = static_cast<ClockEvent*>(event);
|
||||
mUTC = c->mTime;
|
||||
//ClockEvent *c = static_cast<ClockEvent*>(event);
|
||||
mUTC = e.clock.utc;
|
||||
if ( RadioManager::instance().initialized() && mTesting && mUTC % 1 == 0 ) {
|
||||
scheduleTestPacket();
|
||||
printf2("Scheduled test packet\r\n");
|
||||
|
@ -22,7 +22,7 @@ public:
|
||||
virtual
|
||||
~TXScheduler ();
|
||||
|
||||
void processEvent(Event *event);
|
||||
void processEvent(const Event &event);
|
||||
void startTXTesting();
|
||||
private:
|
||||
void scheduleTestPacket();
|
||||
|
@ -162,7 +162,7 @@ void Transceiver::onBitClock()
|
||||
// If we have an assigned packet and we're on the correct channel, at the right bit of the time slot,
|
||||
// and the RSSI is within 6dB of the noise floor for this channel, then fire!!!
|
||||
uint8_t noiseFloor = NoiseFloorDetector::instance().getNoiseFloor(mChannel);
|
||||
if ( mSlotBitNumber == CCA_SLOT_BIT+1 && mTXPacket && mTXPacket->channel() == mChannel && mRXPacket->rssi() < noiseFloor + 12 ) {
|
||||
if ( mSlotBitNumber == CCA_SLOT_BIT+1 && mTXPacket && mTXPacket->channel() == mChannel && mRXPacket.rssi() < noiseFloor + 12 ) {
|
||||
startTransmitting();
|
||||
}
|
||||
}
|
||||
|
@ -79,7 +79,7 @@ main(int argc, char* argv[])
|
||||
EventQueue::instance().init();
|
||||
EventPool::instance().init();
|
||||
TXPacketPool::instance().init();
|
||||
RXPacketPool::instance().init();
|
||||
|
||||
|
||||
LEDManager::instance().clear();
|
||||
TXScheduler txScheduler;
|
||||
|
@ -57,13 +57,13 @@ void USART_puts(USART_TypeDef* USARTx, const char *s)
|
||||
}
|
||||
#endif
|
||||
|
||||
static char __buffer[256];
|
||||
static char __buffer[128];
|
||||
|
||||
void printf2_now(const char *format, ...)
|
||||
{
|
||||
va_list list;
|
||||
va_start(list, format);
|
||||
vsnprintf(__buffer, 255, format, list);
|
||||
vsnprintf(__buffer, 128, format, list);
|
||||
va_end(list);
|
||||
#ifdef MULTIPLEXED_OUTPUT
|
||||
DataTerminal::instance().write("DEBUG", __buffer);
|
||||
@ -76,13 +76,13 @@ void printf2_now(const char *format, ...)
|
||||
void printf2(const char *format, ...)
|
||||
{
|
||||
if ( Utils::inISR() ) {
|
||||
DebugEvent *e = static_cast<DebugEvent*>(EventPool::instance().newEvent(DEBUG_EVENT));
|
||||
Event *e = EventPool::instance().newEvent(DEBUG_EVENT);
|
||||
if ( e == NULL )
|
||||
return;
|
||||
|
||||
va_list list;
|
||||
va_start(list, format);
|
||||
vsnprintf(e->mBuffer, 255, format, list);
|
||||
vsnprintf(e->debugMessage.buffer, 128, format, list);
|
||||
va_end(list);
|
||||
|
||||
EventQueue::instance().push(e);
|
||||
@ -90,7 +90,7 @@ void printf2(const char *format, ...)
|
||||
else {
|
||||
va_list list;
|
||||
va_start(list, format);
|
||||
vsnprintf(__buffer, 255, format, list);
|
||||
vsnprintf(__buffer, 128, format, list);
|
||||
va_end(list);
|
||||
#ifdef MULTIPLEXED_OUTPUT
|
||||
DataTerminal::instance().write("DEBUG", __buffer);
|
||||
|
Loading…
x
Reference in New Issue
Block a user