1
0
mirror of https://github.com/peterantypas/maiana.git synced 2025-05-16 15:30:10 -07:00
This commit is contained in:
Peter Antypas 2021-09-20 14:26:37 -07:00
parent 7498806117
commit 735e36acd1
12 changed files with 127 additions and 35 deletions

View File

@ -22,6 +22,7 @@
#include "StationData.h" #include "StationData.h"
#include "OTPData.h" #include "OTPData.h"
#include "config.h"
// This should be plenty big (no need to be a whole flash page though) // This should be plenty big (no need to be a whole flash page though)
typedef union typedef union
@ -46,6 +47,7 @@ public:
void reportOTPData(); void reportOTPData();
const OTPData *readOTP(); const OTPData *readOTP();
bool writeOTP(const OTPData &data); bool writeOTP(const OTPData &data);
void reportSystemData();
private: private:
Configuration(); Configuration();
bool erasePage(); bool erasePage();

View File

@ -0,0 +1,21 @@
/*
* TXErrors.h
*
* Created on: Sep 18, 2021
* Author: peter
*/
#ifndef INC_TXERRORS_H_
#define INC_TXERRORS_H_
typedef enum
{
TX_NO_ERROR = 0,
TX_ALLOC_ERROR,
TX_QUEUE_FULL,
TX_PACKET_TOO_OLD,
} TXErrorCode;
#endif /* INC_TXERRORS_H_ */

View File

@ -30,6 +30,7 @@ private:
TXScheduler (); TXScheduler ();
virtual ~TXScheduler (); virtual ~TXScheduler ();
time_t positionReportTimeInterval(); time_t positionReportTimeInterval();
void sendNMEASentence(const char *sentence);
private: private:
VHFChannel mPositionReportChannel; VHFChannel mPositionReportChannel;
VHFChannel mStaticDataChannel; VHFChannel mStaticDataChannel;

View File

@ -83,6 +83,9 @@ void bsp_set_sotdma_timer_value(uint32_t v);
uint8_t bsp_tx_spi_byte(uint8_t b); uint8_t bsp_tx_spi_byte(uint8_t b);
extern const char *BSP_HW_REV;
// BSP headers go here // BSP headers go here
#if BOARD_REV == 93 #if BOARD_REV == 93

View File

@ -87,7 +87,8 @@
#define CLI_FLAG_MAGIC 0x209a388d #define CLI_FLAG_MAGIC 0x209a388d
#define CONFIGURATION_ADDRESS 0x0800F800 #define CONFIGURATION_ADDRESS 0x0800F800
#define OTP_DATA 0
#define FW_REV "3.1.0"
#endif /* CONFIG_H_ */ #endif /* CONFIG_H_ */

View File

@ -157,6 +157,7 @@ void CommandProcessor::processCommand(const char *buff)
{ {
TXScheduler::instance().queueMessage24(CH_87); TXScheduler::instance().queueMessage24(CH_87);
} }
#if OTP_DATA
else if ( s.find("otp?") == 0 ) else if ( s.find("otp?") == 0 )
{ {
dumpOTPData(); dumpOTPData();
@ -165,6 +166,7 @@ void CommandProcessor::processCommand(const char *buff)
{ {
writeOTPData(s); writeOTPData(s);
} }
#endif
} }
void CommandProcessor::enterCLIMode() void CommandProcessor::enterCLIMode()
@ -178,6 +180,7 @@ void CommandProcessor::jumpToBootloader()
bsp_enter_dfu(); bsp_enter_dfu();
} }
#if OTP_DATA
void CommandProcessor::dumpOTPData() void CommandProcessor::dumpOTPData()
{ {
Configuration::instance().reportOTPData(); Configuration::instance().reportOTPData();
@ -204,5 +207,5 @@ void CommandProcessor::writeOTPData(const std::string &s)
if ( result ) if ( result )
dumpOTPData(); dumpOTPData();
} }
#endif

View File

@ -23,6 +23,8 @@
#include "config.h" #include "config.h"
#include "EventQueue.hpp" #include "EventQueue.hpp"
#include <stdio.h> #include <stdio.h>
#include <bsp/bsp.hpp>
// These are not defined in ANY CMSIS or HAL header, WTF ST??? // These are not defined in ANY CMSIS or HAL header, WTF ST???
#define OTP_ADDRESS 0x1FFF7000 #define OTP_ADDRESS 0x1FFF7000
@ -60,11 +62,24 @@ void Configuration::init()
bool cliBootMode = *(uint32_t*)BOOTMODE_ADDRESS == CLI_FLAG_MAGIC; bool cliBootMode = *(uint32_t*)BOOTMODE_ADDRESS == CLI_FLAG_MAGIC;
if ( !cliBootMode ) if ( !cliBootMode )
{ {
reportOTPData(); //reportOTPData();
reportSystemData();
reportStationData(); reportStationData();
} }
} }
void Configuration::reportSystemData()
{
Event *e = EventPool::instance().newEvent(PROPR_NMEA_SENTENCE);
if ( !e )
return;
sprintf(e->nmeaBuffer.sentence, "$PAISYS,%s,%s,%s*", BSP_HW_REV, FW_REV, "");
Utils::completeNMEA(e->nmeaBuffer.sentence);
EventQueue::instance().push(e);
}
void Configuration::reportStationData() void Configuration::reportStationData()
{ {
StationData d; StationData d;
@ -72,6 +87,9 @@ void Configuration::reportStationData()
memset(&d, 0, sizeof d); memset(&d, 0, sizeof d);
Event *e = EventPool::instance().newEvent(PROPR_NMEA_SENTENCE); Event *e = EventPool::instance().newEvent(PROPR_NMEA_SENTENCE);
if ( !e )
return;
sprintf(e->nmeaBuffer.sentence, sprintf(e->nmeaBuffer.sentence,
"$PAISTN,%lu,%s,%s,%d,%d,%d,%d,%d*", "$PAISTN,%lu,%s,%s,%d,%d,%d,%d,%d*",
d.mmsi, d.mmsi,
@ -93,23 +111,23 @@ bool Configuration::isStationDataProvisioned()
return readStationData(d); return readStationData(d);
} }
#if OTP_DATA
void Configuration::reportOTPData() void Configuration::reportOTPData()
{ {
const OTPData *data = readOTP(); const OTPData *data = readOTP();
Event *e = EventPool::instance().newEvent(PROPR_NMEA_SENTENCE); Event *e = EventPool::instance().newEvent(PROPR_NMEA_SENTENCE);
if ( !e )
return;
if ( data == nullptr ) if ( data )
{ {
strcpy(e->nmeaBuffer.sentence, "$PAISYS,,*"); sprintf(e->nmeaBuffer.sentence, "$PAIOTP,%s,%s*", data->serialnum, data->hwrev);
}
else
{
sprintf(e->nmeaBuffer.sentence, "$PAISYS,%s,%s*", data->serialnum, data->hwrev);
} }
Utils::completeNMEA(e->nmeaBuffer.sentence); Utils::completeNMEA(e->nmeaBuffer.sentence);
EventQueue::instance().push(e); EventQueue::instance().push(e);
} }
#endif
bool Configuration::erasePage() bool Configuration::erasePage()
{ {
@ -184,6 +202,7 @@ bool Configuration::readStationData(StationData &data)
return data.magic == STATION_DATA_MAGIC; return data.magic == STATION_DATA_MAGIC;
} }
#if OTP_DATA
const OTPData *Configuration::readOTP() const OTPData *Configuration::readOTP()
{ {
uint32_t address = nextAvailableOTPSlot(); uint32_t address = nextAvailableOTPSlot();
@ -231,6 +250,7 @@ uint32_t Configuration::nextAvailableOTPSlot()
return OTP_ADDRESS+OTP_SIZE; return OTP_ADDRESS+OTP_SIZE;
} }
#endif

View File

@ -21,6 +21,16 @@
#include "bsp.hpp" #include "bsp.hpp"
#include "Configuration.hpp" #include "Configuration.hpp"
/**
* TODO: Update this to manage the status of the TX LED without any external hardware logic.
* It must take all inputs into consideration:
*
* - Presence of station data
* - Status of TX_DISABLE signal
* - Status of "tx off" software setting
*/
LEDManager::LEDManager() LEDManager::LEDManager()
{ {
// Do nothing // Do nothing

View File

@ -21,7 +21,7 @@
#include "RadioManager.hpp" #include "RadioManager.hpp"
#include "NoiseFloorDetector.hpp" #include "NoiseFloorDetector.hpp"
#include "bsp.hpp" #include "bsp.hpp"
#include "TXErrors.h"
void rxClockCB(); void rxClockCB();
void trxClockCB(); void trxClockCB();
@ -39,7 +39,6 @@ RadioManager::RadioManager()
mTransceiverIC = NULL; mTransceiverIC = NULL;
mReceiverIC = NULL; mReceiverIC = NULL;
mInitializing = true; mInitializing = true;
//mTXQueue = new CircularQueue<TXPacket*>(4);
mUTC = 0; mUTC = 0;
EventQueue::instance().addObserver(this, CLOCK_EVENT); EventQueue::instance().addObserver(this, CLOCK_EVENT);
} }
@ -52,24 +51,19 @@ bool RadioManager::initialized()
void RadioManager::init() void RadioManager::init()
{ {
NoiseFloorDetector::instance(); NoiseFloorDetector::instance();
//DBG("Initializing RF IC 1\r\n");
mTransceiverIC = new Transceiver(SDN1_PORT, SDN1_PIN, mTransceiverIC = new Transceiver(SDN1_PORT, SDN1_PIN,
CS1_PORT, CS1_PIN, CS1_PORT, CS1_PIN,
TRX_IC_DATA_PORT, TRX_IC_DATA_PIN, TRX_IC_DATA_PORT, TRX_IC_DATA_PIN,
TRX_IC_CLK_PORT, TRX_IC_CLK_PIN, 0); TRX_IC_CLK_PORT, TRX_IC_CLK_PIN, 0);
mTransceiverIC->init(); mTransceiverIC->init();
#ifndef TX_TEST_MODE
//DBG("Initializing RF IC 2\r\n");
mReceiverIC = new Receiver(SDN2_PORT, SDN2_PIN, mReceiverIC = new Receiver(SDN2_PORT, SDN2_PIN,
CS2_PORT, CS2_PIN, CS2_PORT, CS2_PIN,
RX_IC_DATA_PORT, RX_IC_DATA_PIN, RX_IC_DATA_PORT, RX_IC_DATA_PIN,
RX_IC_CLK_PORT, RX_IC_CLK_PIN, 1); RX_IC_CLK_PORT, RX_IC_CLK_PIN, 1);
mReceiverIC->init(); mReceiverIC->init();
#endif
mInitializing = false; mInitializing = false;
//DBG("Radio ICs initialized\r\n");
} }
void RadioManager::transmitCW(VHFChannel channel) void RadioManager::transmitCW(VHFChannel channel)
@ -79,7 +73,6 @@ void RadioManager::transmitCW(VHFChannel channel)
void RadioManager::start() void RadioManager::start()
{ {
//DBG("Radio Manager starting\r\n");
configureInterrupts(); configureInterrupts();
if ( mTransceiverIC ) if ( mTransceiverIC )
mTransceiverIC->startReceiving(CH_87, true); mTransceiverIC->startReceiving(CH_87, true);
@ -88,7 +81,6 @@ void RadioManager::start()
mReceiverIC->startReceiving(CH_88, true); mReceiverIC->startReceiving(CH_88, true);
GPS::instance().setDelegate(this); GPS::instance().setDelegate(this);
//DBG("Radio Manager started\r\n");
} }
void RadioManager::stop() void RadioManager::stop()
@ -124,14 +116,11 @@ void RadioManager::processEvent(const Event &e)
// Do we need to swap channels? // Do we need to swap channels?
if ( txChannel != mTransceiverIC->channel() ) if ( txChannel != mTransceiverIC->channel() )
{ {
//DBG("RadioManager swapping channels for ICs\r\n");
// The receiver needs to be explicitly told to switch channels // The receiver needs to be explicitly told to switch channels
if ( mReceiverIC ) if ( mReceiverIC )
mReceiverIC->switchToChannel(alternateChannel(txChannel)); mReceiverIC->switchToChannel(alternateChannel(txChannel));
} }
//DBG("RadioManager assigned TX packet\r\n");
// The transceiver will switch channel if the packet channel is different // The transceiver will switch channel if the packet channel is different
mTransceiverIC->assignTXPacket(packet); mTransceiverIC->assignTXPacket(packet);
} }
@ -170,22 +159,31 @@ void RadioManager::timeSlotStarted(uint32_t slotNumber)
if ( mInitializing ) if ( mInitializing )
return; return;
#ifndef TX_TEST_MODE
mTransceiverIC->timeSlotStarted(slotNumber); mTransceiverIC->timeSlotStarted(slotNumber);
mReceiverIC->timeSlotStarted(slotNumber); mReceiverIC->timeSlotStarted(slotNumber);
#endif
} }
void RadioManager::scheduleTransmission(TXPacket *packet) void RadioManager::scheduleTransmission(TXPacket *packet)
{ {
if ( mTXQueue.push(packet) ) Event *e = EventPool::instance().newEvent(PROPR_NMEA_SENTENCE);
if ( !mTXQueue.push(packet) )
{ {
//DBG("RadioManager queued TX packet for channel %d\r\n", ORDINAL_TO_ITU(packet->channel())); if ( e )
{
sprintf(e->nmeaBuffer.sentence, "$PAISCHTX,%s,%d*", packet->messageType(), TX_QUEUE_FULL);
Utils::completeNMEA(e->nmeaBuffer.sentence);
EventQueue::instance().push(e);
}
TXPacketPool::instance().deleteTXPacket(packet);
} }
else else
{ {
//DBG("RadioManager rejected TX packet for channel %d\r\n", ORDINAL_TO_ITU(packet->channel())); if ( e )
TXPacketPool::instance().deleteTXPacket(packet); {
sprintf(e->nmeaBuffer.sentence, "$PAISCHTX,%s,%d*", packet->messageType(), TX_NO_ERROR);
Utils::completeNMEA(e->nmeaBuffer.sentence);
EventQueue::instance().push(e);
}
} }
} }

View File

@ -29,6 +29,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "RadioManager.hpp" #include "RadioManager.hpp"
#include "ChannelManager.hpp" #include "ChannelManager.hpp"
#include "TXErrors.h"
#include "printf_serial.h" #include "printf_serial.h"
#include "bsp.hpp" #include "bsp.hpp"
@ -144,15 +145,30 @@ void TXScheduler::processEvent(const Event &e)
} }
void TXScheduler::sendNMEASentence(const char *sentence)
{
Event *e = EventPool::instance().newEvent(PROPR_NMEA_SENTENCE);
if ( !e )
return;
strlcpy(e->nmeaBuffer.sentence, sentence, sizeof e->nmeaBuffer.sentence);
Utils::completeNMEA(e->nmeaBuffer.sentence);
EventQueue::instance().push(e);
}
void TXScheduler::queueMessage18(VHFChannel channel) void TXScheduler::queueMessage18(VHFChannel channel)
{ {
char sentence[48];
// If we don't have valid station data we don't do anything // If we don't have valid station data we don't do anything
if ( mStationData.magic != STATION_DATA_MAGIC ) if ( mStationData.magic != STATION_DATA_MAGIC )
return; return;
TXPacket *p1 = TXPacketPool::instance().newTXPacket(channel); TXPacket *p1 = TXPacketPool::instance().newTXPacket(channel);
if ( !p1 ) { if ( !p1 )
//DBG("Unable to allocate TX packet for message 18, will try again later\r\n"); {
sprintf(sentence, "$PAISCHTX,18,%d*", TX_ALLOC_ERROR);
sendNMEASentence(sentence);
return; return;
} }
@ -169,13 +185,17 @@ void TXScheduler::queueMessage18(VHFChannel channel)
void TXScheduler::queueMessage24(VHFChannel channel) void TXScheduler::queueMessage24(VHFChannel channel)
{ {
char sentence[48];
// If we don't have valid station data we don't do anything // If we don't have valid station data we don't do anything
if ( mStationData.magic != STATION_DATA_MAGIC ) if ( mStationData.magic != STATION_DATA_MAGIC )
return; return;
TXPacket *p2 = TXPacketPool::instance().newTXPacket(channel); TXPacket *p2 = TXPacketPool::instance().newTXPacket(channel);
if ( !p2 ) { if ( !p2 )
//DBG("Unable to allocate TX packet for 24A\r\n"); {
sprintf(sentence, "$PAISCHTX,24A,%d*", TX_ALLOC_ERROR);
sendNMEASentence(sentence);
return; return;
} }
@ -187,7 +207,8 @@ void TXScheduler::queueMessage24(VHFChannel channel)
TXPacket *p3 = TXPacketPool::instance().newTXPacket(channel); TXPacket *p3 = TXPacketPool::instance().newTXPacket(channel);
if ( !p3 ) if ( !p3 )
{ {
//DBG("Unable to allocate TX packet for 24B\r\n"); sprintf(sentence, "$PAISCHTX,24B,%d*", TX_ALLOC_ERROR);
sendNMEASentence(sentence);
return; return;
} }

View File

@ -25,6 +25,7 @@
#include "EZRadioPRO.h" #include "EZRadioPRO.h"
#include "AISChannels.h" #include "AISChannels.h"
#include "bsp.hpp" #include "bsp.hpp"
#include "TXErrors.h"
#include <stdio.h> #include <stdio.h>
Transceiver::Transceiver(GPIO_TypeDef *sdnPort, uint32_t sdnPin, GPIO_TypeDef *csPort, Transceiver::Transceiver(GPIO_TypeDef *sdnPort, uint32_t sdnPin, GPIO_TypeDef *csPort,
@ -214,11 +215,20 @@ void Transceiver::onBitClock()
else if ( mUTC && mUTC - mTXPacket->timestamp() >= MIN_MSG_18_TX_INTERVAL ) else if ( mUTC && mUTC - mTXPacket->timestamp() >= MIN_MSG_18_TX_INTERVAL )
{ {
// The packet is way too old. Discard it. // The packet is way too old. Discard it.
Event *e = EventPool::instance().newEvent(PROPR_NMEA_SENTENCE);
if ( e )
{
sprintf(e->nmeaBuffer.sentence, "$PAISCHTX,%s,%d*", mTXPacket->messageType(), TX_PACKET_TOO_OLD);
Utils::completeNMEA(e->nmeaBuffer.sentence);
EventQueue::instance().push(e);
}
TXPacketPool::instance().deleteTXPacket(mTXPacket); TXPacketPool::instance().deleteTXPacket(mTXPacket);
mTXPacket = NULL; mTXPacket = NULL;
} }
else if ( mUTC - mLastTXTime < MIN_TX_INTERVAL ) else if ( mUTC - mLastTXTime < MIN_TX_INTERVAL )
{ {
// It's not time to transmit yet
return; return;
} }
else if ( mUTC && mSlotBitNumber == CCA_SLOT_BIT && mTXPacket->channel() == mChannel ) else if ( mUTC && mSlotBitNumber == CCA_SLOT_BIT && mTXPacket->channel() == mChannel )

View File

@ -27,6 +27,8 @@
#if BOARD_REV==110 #if BOARD_REV==110
const char *BSP_HW_REV = "11.x";
SPI_HandleTypeDef hspi1; SPI_HandleTypeDef hspi1;
IWDG_HandleTypeDef hiwdg; IWDG_HandleTypeDef hiwdg;
UART_HandleTypeDef huart2; UART_HandleTypeDef huart2;