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