mirror of
https://github.com/peterantypas/maiana.git
synced 2025-05-15 23:10:11 -07:00
WIP
This commit is contained in:
parent
7498806117
commit
735e36acd1
@ -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();
|
||||
|
21
latest/Firmware/Transponder/Inc/TXErrors.h
Normal file
21
latest/Firmware/Transponder/Inc/TXErrors.h
Normal 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_ */
|
@ -30,6 +30,7 @@ private:
|
||||
TXScheduler ();
|
||||
virtual ~TXScheduler ();
|
||||
time_t positionReportTimeInterval();
|
||||
void sendNMEASentence(const char *sentence);
|
||||
private:
|
||||
VHFChannel mPositionReportChannel;
|
||||
VHFChannel mStaticDataChannel;
|
||||
|
@ -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
|
||||
|
@ -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_ */
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 )
|
||||
|
@ -27,6 +27,8 @@
|
||||
|
||||
#if BOARD_REV==110
|
||||
|
||||
const char *BSP_HW_REV = "11.x";
|
||||
|
||||
SPI_HandleTypeDef hspi1;
|
||||
IWDG_HandleTypeDef hiwdg;
|
||||
UART_HandleTypeDef huart2;
|
||||
|
Loading…
x
Reference in New Issue
Block a user