1
0
mirror of https://github.com/peterantypas/maiana.git synced 2025-05-15 23:10:11 -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 "OTPData.h"
#include "config.h"
// This should be plenty big (no need to be a whole flash page though)
typedef union
@ -46,6 +47,7 @@ public:
void reportOTPData();
const OTPData *readOTP();
bool writeOTP(const OTPData &data);
void reportSystemData();
private:
Configuration();
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 ();
virtual ~TXScheduler ();
time_t positionReportTimeInterval();
void sendNMEASentence(const char *sentence);
private:
VHFChannel mPositionReportChannel;
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);
extern const char *BSP_HW_REV;
// BSP headers go here
#if BOARD_REV == 93

View File

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

View File

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

View File

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

View File

@ -21,6 +21,16 @@
#include "bsp.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()
{
// Do nothing

View File

@ -21,7 +21,7 @@
#include "RadioManager.hpp"
#include "NoiseFloorDetector.hpp"
#include "bsp.hpp"
#include "TXErrors.h"
void rxClockCB();
void trxClockCB();
@ -39,7 +39,6 @@ RadioManager::RadioManager()
mTransceiverIC = NULL;
mReceiverIC = NULL;
mInitializing = true;
//mTXQueue = new CircularQueue<TXPacket*>(4);
mUTC = 0;
EventQueue::instance().addObserver(this, CLOCK_EVENT);
}
@ -52,24 +51,19 @@ bool RadioManager::initialized()
void RadioManager::init()
{
NoiseFloorDetector::instance();
//DBG("Initializing RF IC 1\r\n");
mTransceiverIC = new Transceiver(SDN1_PORT, SDN1_PIN,
CS1_PORT, CS1_PIN,
TRX_IC_DATA_PORT, TRX_IC_DATA_PIN,
TRX_IC_CLK_PORT, TRX_IC_CLK_PIN, 0);
mTransceiverIC->init();
#ifndef TX_TEST_MODE
//DBG("Initializing RF IC 2\r\n");
mReceiverIC = new Receiver(SDN2_PORT, SDN2_PIN,
CS2_PORT, CS2_PIN,
RX_IC_DATA_PORT, RX_IC_DATA_PIN,
RX_IC_CLK_PORT, RX_IC_CLK_PIN, 1);
mReceiverIC->init();
#endif
mInitializing = false;
//DBG("Radio ICs initialized\r\n");
}
void RadioManager::transmitCW(VHFChannel channel)
@ -79,7 +73,6 @@ void RadioManager::transmitCW(VHFChannel channel)
void RadioManager::start()
{
//DBG("Radio Manager starting\r\n");
configureInterrupts();
if ( mTransceiverIC )
mTransceiverIC->startReceiving(CH_87, true);
@ -88,7 +81,6 @@ void RadioManager::start()
mReceiverIC->startReceiving(CH_88, true);
GPS::instance().setDelegate(this);
//DBG("Radio Manager started\r\n");
}
void RadioManager::stop()
@ -124,14 +116,11 @@ void RadioManager::processEvent(const Event &e)
// Do we need to swap channels?
if ( txChannel != mTransceiverIC->channel() )
{
//DBG("RadioManager swapping channels for ICs\r\n");
// The receiver needs to be explicitly told to switch channels
if ( mReceiverIC )
mReceiverIC->switchToChannel(alternateChannel(txChannel));
}
//DBG("RadioManager assigned TX packet\r\n");
// The transceiver will switch channel if the packet channel is different
mTransceiverIC->assignTXPacket(packet);
}
@ -170,22 +159,31 @@ void RadioManager::timeSlotStarted(uint32_t slotNumber)
if ( mInitializing )
return;
#ifndef TX_TEST_MODE
mTransceiverIC->timeSlotStarted(slotNumber);
mReceiverIC->timeSlotStarted(slotNumber);
#endif
}
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
{
//DBG("RadioManager rejected TX packet for channel %d\r\n", ORDINAL_TO_ITU(packet->channel()));
TXPacketPool::instance().deleteTXPacket(packet);
if ( e )
{
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 "RadioManager.hpp"
#include "ChannelManager.hpp"
#include "TXErrors.h"
#include "printf_serial.h"
#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)
{
char sentence[48];
// If we don't have valid station data we don't do anything
if ( mStationData.magic != STATION_DATA_MAGIC )
return;
TXPacket *p1 = TXPacketPool::instance().newTXPacket(channel);
if ( !p1 ) {
//DBG("Unable to allocate TX packet for message 18, will try again later\r\n");
if ( !p1 )
{
sprintf(sentence, "$PAISCHTX,18,%d*", TX_ALLOC_ERROR);
sendNMEASentence(sentence);
return;
}
@ -169,13 +185,17 @@ void TXScheduler::queueMessage18(VHFChannel channel)
void TXScheduler::queueMessage24(VHFChannel channel)
{
char sentence[48];
// If we don't have valid station data we don't do anything
if ( mStationData.magic != STATION_DATA_MAGIC )
return;
TXPacket *p2 = TXPacketPool::instance().newTXPacket(channel);
if ( !p2 ) {
//DBG("Unable to allocate TX packet for 24A\r\n");
if ( !p2 )
{
sprintf(sentence, "$PAISCHTX,24A,%d*", TX_ALLOC_ERROR);
sendNMEASentence(sentence);
return;
}
@ -187,7 +207,8 @@ void TXScheduler::queueMessage24(VHFChannel channel)
TXPacket *p3 = TXPacketPool::instance().newTXPacket(channel);
if ( !p3 )
{
//DBG("Unable to allocate TX packet for 24B\r\n");
sprintf(sentence, "$PAISCHTX,24B,%d*", TX_ALLOC_ERROR);
sendNMEASentence(sentence);
return;
}

View File

@ -25,6 +25,7 @@
#include "EZRadioPRO.h"
#include "AISChannels.h"
#include "bsp.hpp"
#include "TXErrors.h"
#include <stdio.h>
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 )
{
// 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);
mTXPacket = NULL;
}
else if ( mUTC - mLastTXTime < MIN_TX_INTERVAL )
{
// It's not time to transmit yet
return;
}
else if ( mUTC && mSlotBitNumber == CCA_SLOT_BIT && mTXPacket->channel() == mChannel )

View File

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