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