diff --git a/latest/Firmware/Transponder/.cproject b/latest/Firmware/Transponder/.cproject
index cb129e6..440fc96 100644
--- a/latest/Firmware/Transponder/.cproject
+++ b/latest/Firmware/Transponder/.cproject
@@ -2299,6 +2299,184 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/latest/Firmware/Transponder/.gitignore b/latest/Firmware/Transponder/.gitignore
index 36ee013..87329cf 100644
--- a/latest/Firmware/Transponder/.gitignore
+++ b/latest/Firmware/Transponder/.gitignore
@@ -25,3 +25,5 @@ Debug
/L422-Board11.0-LegacyBreakouts/
/L422-Board11.0-LegacyBreakouts-Bootloader/
/L412-NewBreakouts-Bootloader/
+/L431-NewBreakouts-Bootloader/
+/L412-NewBreakouts/
diff --git a/latest/Firmware/Transponder/Inc/ConfigFlags.h b/latest/Firmware/Transponder/Inc/ConfigFlags.h
index 864e803..eb63527 100644
--- a/latest/Firmware/Transponder/Inc/ConfigFlags.h
+++ b/latest/Firmware/Transponder/Inc/ConfigFlags.h
@@ -21,6 +21,12 @@ typedef union
uint64_t dw[4];
} ConfigPage;
+typedef struct
+{
+ uint32_t magic;
+ uint8_t value;
+ uint8_t fill[3];
+} XOTrim;
#endif /* INC_CONFIGFLAGS_H_ */
diff --git a/latest/Firmware/Transponder/Inc/Configuration.hpp b/latest/Firmware/Transponder/Inc/Configuration.hpp
index a701fa1..85634c4 100644
--- a/latest/Firmware/Transponder/Inc/Configuration.hpp
+++ b/latest/Firmware/Transponder/Inc/Configuration.hpp
@@ -47,16 +47,13 @@ public:
void disableTX();
bool isTXEnabled();
+ bool isXOTrimmed();
+ void setXOTrimValue(uint8_t value);
+ uint8_t getXOTrimValue();
+ void reportXOTrimValue();
private:
Configuration();
- //bool eraseStationDataPage();
- //bool writeStationDataPage();
- //bool eraseConfigFlags();
-
- //bool readConfigFlags();
- //bool writeConfigFlags();
- //bool erasePage(uint32_t address);
uint32_t nextAvailableOTPSlot();
const char *hwRev();
diff --git a/latest/Firmware/Transponder/Inc/OTPData.h b/latest/Firmware/Transponder/Inc/OTPData.h
index e567cdd..ad12f20 100644
--- a/latest/Firmware/Transponder/Inc/OTPData.h
+++ b/latest/Firmware/Transponder/Inc/OTPData.h
@@ -14,12 +14,6 @@
#define OTP_REV 0x00000002
-#define MCU_UNKNOWN 0x00
-#define MCU_STM32L412 0x01
-#define MCU_STM32L422 0x02
-#define MCU_STM32L431 0x03
-#define MCU_STM32L432 0x04
-
// This structure must be double-word aligned
diff --git a/latest/Firmware/Transponder/Inc/RFIC.hpp b/latest/Firmware/Transponder/Inc/RFIC.hpp
index a51ede0..5328928 100644
--- a/latest/Firmware/Transponder/Inc/RFIC.hpp
+++ b/latest/Firmware/Transponder/Inc/RFIC.hpp
@@ -49,6 +49,8 @@ public:
void setRSSIAdjustment(short rssiAdj);
uint16_t partNumber();
bool isResponsive();
+
+ void setXOTrimValue(uint8_t value);
protected:
virtual void configure();
bool sendCmd(uint8_t cmd, void* params, uint8_t paramLen, void* result, uint8_t resultLen);
diff --git a/latest/Firmware/Transponder/Inc/RadioManager.hpp b/latest/Firmware/Transponder/Inc/RadioManager.hpp
index d43ce6a..73eb8df 100644
--- a/latest/Firmware/Transponder/Inc/RadioManager.hpp
+++ b/latest/Firmware/Transponder/Inc/RadioManager.hpp
@@ -48,8 +48,12 @@ public:
void processEvent(const Event &e);
void transmitCW(VHFChannel channel);
+ void stopTX();
+
VHFChannel alternateChannel(VHFChannel channel);
+ void setXOTrimValue(uint8_t value);
+
private:
RadioManager();
void spiOff();
diff --git a/latest/Firmware/Transponder/Inc/Transceiver.hpp b/latest/Firmware/Transponder/Inc/Transceiver.hpp
index a409d0d..2324c0c 100644
--- a/latest/Firmware/Transponder/Inc/Transceiver.hpp
+++ b/latest/Firmware/Transponder/Inc/Transceiver.hpp
@@ -45,7 +45,6 @@ public:
void assignTXPacket(TXPacket *p);
TXPacket *assignedTXPacket();
void startReceiving(VHFChannel channel, bool reconfigGPIOs);
- void startListening(VHFChannel channel, bool reconfigGPIOs);
void transmitCW(VHFChannel channel);
void processEvent(const Event &);
diff --git a/latest/Firmware/Transponder/Inc/bsp/bsp.hpp b/latest/Firmware/Transponder/Inc/bsp/bsp.hpp
index 20eb5d9..35036f4 100644
--- a/latest/Firmware/Transponder/Inc/bsp/bsp.hpp
+++ b/latest/Firmware/Transponder/Inc/bsp/bsp.hpp
@@ -73,6 +73,9 @@ void bsp_read_config_flags(ConfigFlags *flags);
void bsp_write_config_flags(const ConfigFlags &flags);
void bsp_erase_config_flags();
+void bsp_read_xo_trim(XOTrim *t);
+void bsp_write_xo_trim(const XOTrim &t);
+
// Callback for processing UART input (interrupt)
typedef void(*char_input_cb)(char c);
diff --git a/latest/Firmware/Transponder/Inc/config.h b/latest/Firmware/Transponder/Inc/config.h
index edef28b..3627ebd 100644
--- a/latest/Firmware/Transponder/Inc/config.h
+++ b/latest/Firmware/Transponder/Inc/config.h
@@ -25,7 +25,7 @@
#include "TXPowerSettings.h"
-#define FW_REV "4.3.0"
+#define FW_REV "4.4.0"
/*
diff --git a/latest/Firmware/Transponder/STM32L412_64k.ld b/latest/Firmware/Transponder/STM32L412_64k.ld
new file mode 100644
index 0000000..c9a0359
--- /dev/null
+++ b/latest/Firmware/Transponder/STM32L412_64k.ld
@@ -0,0 +1,202 @@
+/*
+******************************************************************************
+**
+
+** File : LinkerScript.ld
+**
+** Author : Auto-generated by System Workbench for STM32
+**
+** Abstract : Linker script for STM32L412KBUx series
+** 128Kbytes FLASH and 40Kbytes RAM
+**
+** Set heap size, stack size and stack location according
+** to application requirements.
+**
+** Set memory bank area and size if external memory is used.
+**
+** Target : STMicroelectronics STM32
+**
+** Distribution: The file is distributed “as is,” without any warranty
+** of any kind.
+**
+*****************************************************************************
+** @attention
+**
+** © COPYRIGHT(c) 2019 STMicroelectronics
+**
+** Redistribution and use in source and binary forms, with or without modification,
+** are permitted provided that the following conditions are met:
+** 1. Redistributions of source code must retain the above copyright notice,
+** this list of conditions and the following disclaimer.
+** 2. Redistributions in binary form must reproduce the above copyright notice,
+** this list of conditions and the following disclaimer in the documentation
+** and/or other materials provided with the distribution.
+** 3. Neither the name of STMicroelectronics nor the names of its contributors
+** may be used to endorse or promote products derived from this software
+** without specific prior written permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+**
+*****************************************************************************
+*/
+
+/* Entry Point */
+ENTRY(Reset_Handler)
+
+/* Highest address of the user mode stack */
+_estack = 0x2000A000; /* end of RAM */
+/* Generate a link error if heap and stack don't fit into RAM */
+_Min_Heap_Size = 0x400; /* required amount of heap */
+_Min_Stack_Size = 0x400; /* required amount of stack */
+
+/* Specify the memory areas */
+MEMORY
+{
+RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K
+FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 56K
+}
+
+/* Define output sections */
+SECTIONS
+{
+ /* The startup code goes first into FLASH */
+ .isr_vector :
+ {
+ . = ALIGN(8);
+ KEEP(*(.isr_vector)) /* Startup code */
+ . = ALIGN(8);
+ } >FLASH
+
+ /* The program code and other data goes into FLASH */
+ .text :
+ {
+ . = ALIGN(8);
+ *(.text) /* .text sections (code) */
+ *(.text*) /* .text* sections (code) */
+ *(.glue_7) /* glue arm to thumb code */
+ *(.glue_7t) /* glue thumb to arm code */
+ *(.eh_frame)
+
+ KEEP (*(.init))
+ KEEP (*(.fini))
+
+ . = ALIGN(8);
+ _etext = .; /* define a global symbols at end of code */
+ } >FLASH
+
+ /* Constant data goes into FLASH */
+ .rodata :
+ {
+ . = ALIGN(8);
+ *(.rodata) /* .rodata sections (constants, strings, etc.) */
+ *(.rodata*) /* .rodata* sections (constants, strings, etc.) */
+ . = ALIGN(8);
+ } >FLASH
+
+ .ARM.extab :
+ {
+ . = ALIGN(8);
+ *(.ARM.extab* .gnu.linkonce.armextab.*)
+ . = ALIGN(8);
+ } >FLASH
+ .ARM : {
+ . = ALIGN(8);
+ __exidx_start = .;
+ *(.ARM.exidx*)
+ __exidx_end = .;
+ . = ALIGN(8);
+ } >FLASH
+
+ .preinit_array :
+ {
+ . = ALIGN(8);
+ PROVIDE_HIDDEN (__preinit_array_start = .);
+ KEEP (*(.preinit_array*))
+ PROVIDE_HIDDEN (__preinit_array_end = .);
+ . = ALIGN(8);
+ } >FLASH
+
+ .init_array :
+ {
+ . = ALIGN(8);
+ PROVIDE_HIDDEN (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array*))
+ PROVIDE_HIDDEN (__init_array_end = .);
+ . = ALIGN(8);
+ } >FLASH
+ .fini_array :
+ {
+ . = ALIGN(8);
+ PROVIDE_HIDDEN (__fini_array_start = .);
+ KEEP (*(SORT(.fini_array.*)))
+ KEEP (*(.fini_array*))
+ PROVIDE_HIDDEN (__fini_array_end = .);
+ . = ALIGN(8);
+ } >FLASH
+
+ /* used by the startup to initialize data */
+ _sidata = LOADADDR(.data);
+
+ /* Initialized data sections goes into RAM, load LMA copy after code */
+ .data :
+ {
+ . = ALIGN(8);
+ _sdata = .; /* create a global symbol at data start */
+ *(.data) /* .data sections */
+ *(.data*) /* .data* sections */
+ *(.code_in_ram) /* code executing from RAM */
+ . = ALIGN(8);
+ _edata = .; /* define a global symbol at data end */
+ } >RAM AT> FLASH
+
+
+ /* Uninitialized data section */
+ . = ALIGN(4);
+ .bss :
+ {
+ /* This is used by the startup in order to initialize the .bss secion */
+ _sbss = .; /* define a global symbol at bss start */
+ __bss_start__ = _sbss;
+ *(.bss)
+ *(.bss*)
+ *(COMMON)
+
+ . = ALIGN(4);
+ _ebss = .; /* define a global symbol at bss end */
+ __bss_end__ = _ebss;
+ } >RAM
+
+ /* User_heap_stack section, used to check that there is enough RAM left */
+ ._user_heap_stack :
+ {
+ . = ALIGN(8);
+ PROVIDE ( end = . );
+ PROVIDE ( _end = . );
+ . = . + _Min_Heap_Size;
+ . = . + _Min_Stack_Size;
+ . = ALIGN(8);
+ } >RAM
+
+
+
+ /* Remove information from the standard libraries */
+ /DISCARD/ :
+ {
+ libc.a ( * )
+ libm.a ( * )
+ libgcc.a ( * )
+ }
+
+ .ARM.attributes 0 : { *(.ARM.attributes) }
+}
+
diff --git a/latest/Firmware/Transponder/Src/CommandProcessor.cpp b/latest/Firmware/Transponder/Src/CommandProcessor.cpp
index df3c533..a4c7bc0 100644
--- a/latest/Firmware/Transponder/Src/CommandProcessor.cpp
+++ b/latest/Firmware/Transponder/Src/CommandProcessor.cpp
@@ -155,6 +155,18 @@ void CommandProcessor::processCommand(const char *buff)
{
TXScheduler::instance().reportTXStatus();
}
+ else if ( s.find("txcw a") == 0 )
+ {
+ RadioManager::instance().transmitCW(CH_87);
+ }
+ else if ( s.find("txcw b") == 0 )
+ {
+ RadioManager::instance().transmitCW(CH_88);
+ }
+ else if ( s.find("stoptx") == 0 )
+ {
+ RadioManager::instance().stopTX();
+ }
else if (s.find("reboot") == 0 )
{
bsp_reboot();
@@ -185,6 +197,16 @@ void CommandProcessor::processCommand(const char *buff)
writeOTPData(s);
}
#endif
+ else if ( s.find("xotrim ") == 0 )
+ {
+ uint8_t value = Utils::toInt(s.substr(7));
+ RadioManager::instance().setXOTrimValue(value);
+ Configuration::instance().setXOTrimValue(value);
+ }
+ else if ( s.find("xotrim?") == 0 )
+ {
+ Configuration::instance().reportXOTrimValue();
+ }
}
void CommandProcessor::enterCLIMode()
diff --git a/latest/Firmware/Transponder/Src/Configuration.cpp b/latest/Firmware/Transponder/Src/Configuration.cpp
index 1d2aaf7..403f5a5 100644
--- a/latest/Firmware/Transponder/Src/Configuration.cpp
+++ b/latest/Firmware/Transponder/Src/Configuration.cpp
@@ -32,6 +32,7 @@
#define CONFIG_FLAGS_MAGIC 0x2092ED2C
+#define XO_TRIM_MAGIC 0x8112AAAA
//static StationDataPage __page;
@@ -195,6 +196,24 @@ void Configuration::reportOTPData()
}
#endif
+void Configuration::reportXOTrimValue()
+{
+ uint8_t value = 0;
+
+ if ( this->isXOTrimmed() )
+ {
+ value = this->getXOTrimValue();
+ }
+
+ Event *e = EventPool::instance().newEvent(PROPR_NMEA_SENTENCE);
+ if ( !e )
+ return;
+
+ sprintf(e->nmeaBuffer.sentence, "$PAIXOTR,%d*", value);
+ Utils::completeNMEA(e->nmeaBuffer.sentence);
+ EventQueue::instance().push(e);
+}
+
void Configuration::resetToDefaults()
{
bsp_erase_station_data();
@@ -217,6 +236,27 @@ bool Configuration::readStationData(StationData &data)
}
+bool Configuration::isXOTrimmed()
+{
+ XOTrim x;
+ bsp_read_xo_trim(&x);
+ return x.magic == XO_TRIM_MAGIC;
+}
+
+void Configuration::setXOTrimValue(uint8_t value)
+{
+ XOTrim x = {XO_TRIM_MAGIC, value, {0}};
+ bsp_write_xo_trim(x);
+}
+
+uint8_t Configuration::getXOTrimValue()
+{
+ XOTrim x;
+ bsp_read_xo_trim(&x);
+ return x.value;
+}
+
+
#if OTP_DATA
const OTPData *Configuration::readOTP()
{
diff --git a/latest/Firmware/Transponder/Src/RFIC.cpp b/latest/Firmware/Transponder/Src/RFIC.cpp
index 00880ea..869b511 100644
--- a/latest/Firmware/Transponder/Src/RFIC.cpp
+++ b/latest/Firmware/Transponder/Src/RFIC.cpp
@@ -24,6 +24,7 @@
#include "EZRadioPRO.h"
#include
#include "bsp.hpp"
+#include "Configuration.hpp"
RFIC::RFIC(GPIO_TypeDef *sdnPort,
uint32_t sdnPin,
@@ -187,6 +188,23 @@ void RFIC::configure()
sendCmd(cmd, cfg, count, NULL, 0); // send bytes to chip
cfg += count; // point at next line
}
+
+ if ( Configuration::instance().isXOTrimmed() )
+ {
+ setXOTrimValue(Configuration::instance().getXOTrimValue());
+ }
+}
+
+void RFIC::setXOTrimValue(uint8_t value)
+{
+ SET_PROPERTY_PARAMS params = {0};
+ params.Group = 0;
+ params.NumProperties = 2;
+ params.StartProperty = 0;
+ params.Data[0] = value;
+
+ sendCmd(SET_PROPERTY, ¶ms, sizeof params, NULL, 0);
+
}
uint16_t RFIC::partNumber()
diff --git a/latest/Firmware/Transponder/Src/RadioManager.cpp b/latest/Firmware/Transponder/Src/RadioManager.cpp
index eb7b339..59de27b 100644
--- a/latest/Firmware/Transponder/Src/RadioManager.cpp
+++ b/latest/Firmware/Transponder/Src/RadioManager.cpp
@@ -82,9 +82,25 @@ void RadioManager::init()
mInitializing = false;
}
+void RadioManager::setXOTrimValue(uint8_t value)
+{
+ if ( mTransceiverIC )
+ mTransceiverIC->setXOTrimValue(value);
+
+ if ( mReceiverIC )
+ mReceiverIC->setXOTrimValue(value);
+}
+
void RadioManager::transmitCW(VHFChannel channel)
{
- mTransceiverIC->transmitCW(channel);
+ if ( mTransceiverIC )
+ mTransceiverIC->transmitCW(channel);
+}
+
+void RadioManager::stopTX()
+{
+ if ( mTransceiverIC )
+ mTransceiverIC->startReceiving(CH_87, true);
}
void RadioManager::start()
diff --git a/latest/Firmware/Transponder/Src/Transceiver.cpp b/latest/Firmware/Transponder/Src/Transceiver.cpp
index 8a9980a..1c6313f 100644
--- a/latest/Firmware/Transponder/Src/Transceiver.cpp
+++ b/latest/Firmware/Transponder/Src/Transceiver.cpp
@@ -168,10 +168,6 @@ void Transceiver::configureGPIOsForTX()
sendCmd(GPIO_PIN_CFG, &gpiocfg, sizeof gpiocfg, NULL, 0);
}
-void Transceiver::startListening(VHFChannel channel, bool reconfigGPIOs)
-{
- Receiver::startListening(channel, reconfigGPIOs);
-}
void Transceiver::assignTXPacket(TXPacket *p)
{
@@ -249,7 +245,7 @@ void Transceiver::onBitClock()
}
}
}
- else
+ else if ( mTXPacket )
{
if ( mTXPacket->eof() )
{
@@ -281,6 +277,10 @@ void Transceiver::onBitClock()
HAL_GPIO_WritePin(PA_BIAS_PORT, PA_BIAS_PIN, GPIO_PIN_RESET);
}
}
+ else
+ {
+ // We're transmitting carrier wave, do nothing. This is only done during XO trimming.
+ }
}
diff --git a/latest/Firmware/Transponder/Src/bsp/bsp_11_3.cpp b/latest/Firmware/Transponder/Src/bsp/bsp_11_3.cpp
index 9913ab7..0585e05 100644
--- a/latest/Firmware/Transponder/Src/bsp/bsp_11_3.cpp
+++ b/latest/Firmware/Transponder/Src/bsp/bsp_11_3.cpp
@@ -31,6 +31,7 @@
#define EEPROM_ADDRESS (0x50 << 1)
#define EEPROM_STATION_ADDRESS 0x00
#define EEPROM_CONFIG_ADDRESS 0x40
+#define EEPROM_XOTRIM_ADDRESS 0x60
#define STATION_DATA_FLASH_ADDRESS 0x0800F800
const char *BSP_HW_REV = "11.x";
@@ -456,6 +457,29 @@ void bsp_erase_config_flags()
bsp_write_config_flags({0});
}
+
+void bsp_read_xo_trim(XOTrim *t)
+{
+ uint8_t *d = (uint8_t*)t;
+ for ( uint8_t i = 0; i < sizeof (XOTrim); ++i, ++d )
+ {
+ HAL_I2C_Mem_Read(&hi2c1, EEPROM_ADDRESS|1, i+EEPROM_XOTRIM_ADDRESS, 1, d, 1, 5);
+ }
+
+}
+
+void bsp_write_xo_trim(const XOTrim &t)
+{
+ XOTrim __t = t;
+ uint8_t *d = (uint8_t*)&__t;
+ for ( uint8_t i = 0; i < sizeof (XOTrim); ++i, ++d )
+ {
+ HAL_I2C_Mem_Write(&hi2c1, EEPROM_ADDRESS, i+EEPROM_XOTRIM_ADDRESS, 1, d, 1, 5);
+ HAL_Delay(5);
+ }
+
+}
+
void bsp_set_rx_mode()
{
HAL_GPIO_WritePin(PA_BIAS_PORT, PA_BIAS_PIN, GPIO_PIN_RESET); // Kill the RF MOSFET bias voltage