You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

381 lines
13 KiB

/*
Copyright 2020-2025 Piotr Wilkon
This file is part of VP-Digi.
VP-Digi is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
VP-Digi is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with VP-Digi. If not, see <http://www.gnu.org/licenses/>.
*/
#include "modem.h"
#include "uart.h"
#include "config.h"
#include "common.h"
#include "usbd_cdc_if.h"
#include "digipeater.h"
#include "ax25.h"
#include "beacon.h"
#include "drivers/config_ll.h"
/**
* @brief Read string from configuration space
* @param address Relative address
* @param *data Output string pointer
* @param len Number of bytes
*/
static void readString(uint32_t address, void *data, uint16_t len)
{
uint8_t *d = data;
uint16_t i = 0;
for(; i < len; i += 2)
{
uint16_t t = read(address + i);
d[i] = t & 0xFF;
d[i + 1] = t >> 8;
}
if(len & 1)
{
d[i] = read(address + i);
}
}
/**
* @brief Write string to configuration space
* @param address Relative address
* @param *data Input string pointer
* @param len Number of bytes
*/
static void writeString(uint32_t address, const void *data, uint16_t len)
{
const uint8_t *d = data;
uint16_t i = 0;
for(; i < len; i += 2)
{
write(address + i, (uint16_t)d[i] | ((uint16_t)d[i + 1] << 8));
}
if(len & 1)
{
write(address + i, d[i]);
}
}
void ConfigErase(void)
{
unlock();
erase();
lock();
}
#ifdef BLUE_PILL
#define CONFIG_FLAG_WRITTEN 0x6B
//these are relative addresses, absolute address is calculated as relative address + MEM_CONFIG
//all fields are 16-bit or n*16-bit long, as data in flash is stored in 16-bit words
#define CONFIG_FLAG 0 //configuration written flag
#define CONFIG_CALL 2
#define CONFIG_SSID 8
#define CONFIG_TXDELAY 10
#define CONFIG_TXTAIL 12
#define CONFIG_TXQUIET 14
#define CONFIG_RS1BAUD 16
#define CONFIG_RS2BAUD 20
#define CONFIG_BEACONS 24
#define CONFIG_BCIV 26 //beacon intervals
#define CONFIG_BCDL 42 //beacon delays
#define CONFIG_BC0 58 //beacon information fields, null terminated
#define CONFIG_BC1 158
#define CONFIG_BC2 258
#define CONFIG_BC3 358
#define CONFIG_BC4 458
#define CONFIG_BC5 558
#define CONFIG_BC6 658
#define CONFIG_BC7 758
#define CONFIG_BCP0 858 //beacon paths, 14 bytes each
#define CONFIG_BCP1 872
#define CONFIG_BCP2 886
#define CONFIG_BCP3 900
#define CONFIG_BCP4 914
#define CONFIG_BCP5 928
#define CONFIG_BCP6 942
#define CONFIG_BCP7 956
#define CONFIG_DIGION 970
#define CONFIG_DIGIEN 972
#define CONFIG_DIGIVISC 974 //viscous-delay settings in higher half, direct-only in lower half
#define CONFIG_DIGIAL0 976
#define CONFIG_DIGIAL1 982
#define CONFIG_DIGIAL2 988
#define CONFIG_DIGIAL3 994
#define CONFIG_DIGIAL4 1000
#define CONFIG_DIGIAL5 1008
#define CONFIG_DIGIAL6 1016
#define CONFIG_DIGIAL7 1024
#define CONFIG_DIGIMAX0 1032
#define CONFIG_DIGIMAX1 1034
#define CONFIG_DIGIMAX2 1036
#define CONFIG_DIGIMAX3 1038
#define CONFIG_DIGIREP0 1040
#define CONFIG_DIGIREP1 1042
#define CONFIG_DIGIREP2 1044
#define CONFIG_DIGIREP3 1046
#define CONFIG_DIGITRACE 1048
#define CONFIG_DIGIDEDUPE 1050
#define CONFIG_DIGICALLFILEN 1052
#define CONFIG_DIGIFILLIST 1054
#define CONFIG_DIGIFILTYPE 1194
#define CONFIG_DIGISSID4 1196
#define CONFIG_DIGISSID5 1198
#define CONFIG_DIGISSID6 1200
#define CONFIG_DIGISSID7 1202
#define CONFIG_PWM_FLAT_PTT 1204
#define CONFIG_KISSMONITOR 1206
#define CONFIG_DEST 1208
#define CONFIG_ALLOWNONAPRS 1214
#define CONFIG_FX25 1216
#define CONFIG_MODEM 1218
#define CONFIG_MODE_USB 1220
#define CONFIG_MODE_UART1 1222
#define CONFIG_MODE_UART2 1224
#define CONFIG_TX_LEVEL 1226
#define CONFIG_XXX 1228 //next address (not used)
void ConfigWrite(void)
{
ConfigErase();
unlock();
writeString(CONFIG_CALL, GeneralConfig.call, 6);
write(CONFIG_SSID, GeneralConfig.callSsid);
writeString(CONFIG_DEST, GeneralConfig.dest, 6);
write(CONFIG_TXDELAY, Ax25Config.txDelayLength);
write(CONFIG_TXTAIL, Ax25Config.txTailLength);
write(CONFIG_TXQUIET, Ax25Config.quietTime);
#ifdef BLUE_PILL
writeString(CONFIG_RS1BAUD, (uint8_t*)&Uart1.config.baudrate, 4);
write(CONFIG_MODE_UART1, Uart1.config.defaultMode);
writeString(CONFIG_RS2BAUD, (uint8_t*)&Uart2.config.baudrate, 4);
write(CONFIG_MODE_UART2, Uart2.config.defaultMode);
#endif
write(CONFIG_BEACONS, (BeaconConfig[0].enable > 0) | ((BeaconConfig[1].enable > 0) << 1) | ((BeaconConfig[2].enable > 0) << 2) | ((BeaconConfig[3].enable > 0) << 3) | ((BeaconConfig[4].enable > 0) << 4) | ((BeaconConfig[5].enable > 0) << 5) | ((BeaconConfig[6].enable > 0) << 6) | ((BeaconConfig[7].enable > 0) << 7));
for(uint8_t s = 0; s < 8; s++)
{
write(CONFIG_BCIV + (2 * s), BeaconConfig[s].interval / 6000);
}
for(uint8_t s = 0; s < 8; s++)
{
write(CONFIG_BCDL + (2 * s), BeaconConfig[s].delay / 60);
}
writeString(CONFIG_BC0, BeaconConfig[0].data, 100);
writeString(CONFIG_BC1, BeaconConfig[1].data, 100);
writeString(CONFIG_BC2, BeaconConfig[2].data, 100);
writeString(CONFIG_BC3, BeaconConfig[3].data, 100);
writeString(CONFIG_BC4, BeaconConfig[4].data, 100);
writeString(CONFIG_BC5, BeaconConfig[5].data, 100);
writeString(CONFIG_BC6, BeaconConfig[6].data, 100);
writeString(CONFIG_BC7, BeaconConfig[7].data, 100);
writeString(CONFIG_BCP0, BeaconConfig[0].path, 14);
writeString(CONFIG_BCP1, BeaconConfig[1].path, 14);
writeString(CONFIG_BCP2, BeaconConfig[2].path, 14);
writeString(CONFIG_BCP3, BeaconConfig[3].path, 14);
writeString(CONFIG_BCP4, BeaconConfig[4].path, 14);
writeString(CONFIG_BCP5, BeaconConfig[5].path, 14);
writeString(CONFIG_BCP6, BeaconConfig[6].path, 14);
writeString(CONFIG_BCP7, BeaconConfig[7].path, 14);
write(CONFIG_DIGION, DigiConfig.enable);
write(CONFIG_DIGIEN, DigiConfig.enableAlias);
write(CONFIG_DIGIVISC, ((uint16_t)DigiConfig.viscous << 8) | (uint16_t)DigiConfig.directOnly);
writeString(CONFIG_DIGIAL0, DigiConfig.alias[0], 5);
writeString(CONFIG_DIGIAL1, DigiConfig.alias[1], 5);
writeString(CONFIG_DIGIAL2, DigiConfig.alias[2], 5);
writeString(CONFIG_DIGIAL3, DigiConfig.alias[3], 5);
writeString(CONFIG_DIGIAL4, DigiConfig.alias[4], 6);
writeString(CONFIG_DIGIAL5, DigiConfig.alias[5], 6);
writeString(CONFIG_DIGIAL6, DigiConfig.alias[6], 6);
writeString(CONFIG_DIGIAL7, DigiConfig.alias[7], 6);
write(CONFIG_DIGISSID4, DigiConfig.ssid[0]);
write(CONFIG_DIGISSID5, DigiConfig.ssid[1]);
write(CONFIG_DIGISSID6, DigiConfig.ssid[2]);
write(CONFIG_DIGISSID7, DigiConfig.ssid[3]);
write(CONFIG_DIGIMAX0, DigiConfig.max[0]);
write(CONFIG_DIGIMAX1, DigiConfig.max[1]);
write(CONFIG_DIGIMAX2, DigiConfig.max[2]);
write(CONFIG_DIGIMAX3, DigiConfig.max[3]);
write(CONFIG_DIGIREP0, DigiConfig.rep[0]);
write(CONFIG_DIGIREP1, DigiConfig.rep[1]);
write(CONFIG_DIGIREP2, DigiConfig.rep[2]);
write(CONFIG_DIGIREP3, DigiConfig.rep[3]);
write(CONFIG_DIGITRACE, DigiConfig.traced);
write(CONFIG_DIGIDEDUPE, DigiConfig.dupeTime);
write(CONFIG_DIGICALLFILEN, DigiConfig.callFilterEnable);
write(CONFIG_DIGIFILTYPE, DigiConfig.filterPolarity);
writeString(CONFIG_DIGIFILLIST, DigiConfig.callFilter[0], sizeof(DigiConfig.callFilter));
write(CONFIG_PWM_FLAT_PTT, ModemConfig.usePWM | (ModemConfig.flatAudioIn << 1) | (ModemConfig.pttOutput << 2));
write(CONFIG_TX_LEVEL, ModemConfig.txLevel);
write(CONFIG_KISSMONITOR, GeneralConfig.kissMonitor);
write(CONFIG_ALLOWNONAPRS, Ax25Config.allowNonAprs);
write(CONFIG_FX25, Ax25Config.fx25 | (Ax25Config.fx25Tx << 1));
write(CONFIG_MODEM, ModemConfig.modem);
write(CONFIG_MODE_USB, UartUsb.config.defaultMode);
write(CONFIG_FLAG, CONFIG_FLAG_WRITTEN);
lock();
}
uint8_t ConfigRead(void)
{
if(read(CONFIG_FLAG) != CONFIG_FLAG_WRITTEN) //no configuration stored
{
return 0;
}
readString(CONFIG_CALL, GeneralConfig.call, sizeof(GeneralConfig.call));
GeneralConfig.callSsid = (uint8_t)read(CONFIG_SSID);
uint8_t temp[6];
readString(CONFIG_DEST, temp, 6);
if((temp[0] >= ('A' << 1)) && (temp[0] <= ('Z' << 1)) && ((temp[0] & 1) == 0)) //check if stored destination address is correct (we just assume it by reading the first byte)
{
memcpy(GeneralConfig.dest, temp, 6);
}
Ax25Config.txDelayLength = read(CONFIG_TXDELAY);
Ax25Config.txTailLength = read(CONFIG_TXTAIL);
Ax25Config.quietTime = read(CONFIG_TXQUIET);
#ifdef BLUE_PILL
readString(CONFIG_RS1BAUD, (uint8_t*)&Uart1.config.baudrate, 4);
Uart1.config.defaultMode = read(CONFIG_MODE_UART1);
readString(CONFIG_RS2BAUD, (uint8_t*)&Uart2.config.baudrate, 4);
Uart2.config.defaultMode = read(CONFIG_MODE_UART2);
#endif
uint8_t bce = (uint8_t)read(CONFIG_BEACONS);
BeaconConfig[0].enable = (bce & 1) > 0;
BeaconConfig[1].enable = (bce & 2) > 0;
BeaconConfig[2].enable = (bce & 4) > 0;
BeaconConfig[3].enable = (bce & 8) > 0;
BeaconConfig[4].enable = (bce & 16) > 0;
BeaconConfig[5].enable = (bce & 32) > 0;
BeaconConfig[6].enable = (bce & 64) > 0;
BeaconConfig[7].enable = (bce & 128) > 0;
for(uint8_t s = 0; s < BEACON_COUNT; s++)
{
BeaconConfig[s].interval = read(CONFIG_BCIV + (2 * s)) * 6000;
}
for(uint8_t s = 0; s < BEACON_COUNT; s++)
{
BeaconConfig[s].delay = read(CONFIG_BCDL + (2 * s)) * 60;
}
for(uint8_t g = 0; g < BEACON_COUNT; g++)
{
readString(CONFIG_BC0 + (g * 100), BeaconConfig[g].data, 100);
}
for(uint8_t g = 0; g < BEACON_COUNT; g++)
{
readString(CONFIG_BCP0 + (g * 14), BeaconConfig[g].path, 14);
}
DigiConfig.enable = (uint8_t)read(CONFIG_DIGION);
DigiConfig.enableAlias = (uint8_t)read(CONFIG_DIGIEN);
uint16_t t = read(CONFIG_DIGIVISC);
DigiConfig.viscous = (t & 0xFF00) >> 8;
DigiConfig.directOnly = t & 0xFF;
readString(CONFIG_DIGIAL0, DigiConfig.alias[0], 5);
readString(CONFIG_DIGIAL1, DigiConfig.alias[1], 5);
readString(CONFIG_DIGIAL2, DigiConfig.alias[2], 5);
readString(CONFIG_DIGIAL3, DigiConfig.alias[3], 5);
readString(CONFIG_DIGIAL4, DigiConfig.alias[4], 6);
readString(CONFIG_DIGIAL5, DigiConfig.alias[5], 6);
readString(CONFIG_DIGIAL6, DigiConfig.alias[6], 6);
readString(CONFIG_DIGIAL7, DigiConfig.alias[7], 6);
DigiConfig.ssid[0] = (uint8_t)read(CONFIG_DIGISSID4);
DigiConfig.ssid[1] = (uint8_t)read(CONFIG_DIGISSID5);
DigiConfig.ssid[2] = (uint8_t)read(CONFIG_DIGISSID6);
DigiConfig.ssid[3] = (uint8_t)read(CONFIG_DIGISSID7);
DigiConfig.max[0] = (uint8_t)read(CONFIG_DIGIMAX0);
DigiConfig.max[1] = (uint8_t)read(CONFIG_DIGIMAX1);
DigiConfig.max[2] = (uint8_t)read(CONFIG_DIGIMAX2);
DigiConfig.max[3] = (uint8_t)read(CONFIG_DIGIMAX3);
DigiConfig.rep[0] = (uint8_t)read(CONFIG_DIGIREP0);
DigiConfig.rep[1] = (uint8_t)read(CONFIG_DIGIREP1);
DigiConfig.rep[2] = (uint8_t)read(CONFIG_DIGIREP2);
DigiConfig.rep[3] = (uint8_t)read(CONFIG_DIGIREP3);
DigiConfig.traced = (uint8_t)read(CONFIG_DIGITRACE);
DigiConfig.dupeTime = (uint8_t)read(CONFIG_DIGIDEDUPE);
DigiConfig.callFilterEnable = (uint8_t)read(CONFIG_DIGICALLFILEN);
DigiConfig.filterPolarity = (uint8_t)read(CONFIG_DIGIFILTYPE);
readString(CONFIG_DIGIFILLIST, DigiConfig.callFilter[0], 140);
t = (uint8_t)read(CONFIG_PWM_FLAT_PTT);
ModemConfig.usePWM = t & 1;
ModemConfig.flatAudioIn = (t & 2) > 0;
ModemConfig.pttOutput = (t & 4) > 0;
ModemConfig.txLevel = read(CONFIG_TX_LEVEL);
GeneralConfig.kissMonitor = (read(CONFIG_KISSMONITOR) == 1);
Ax25Config.allowNonAprs = (read(CONFIG_ALLOWNONAPRS) == 1);
t = (uint8_t)read(CONFIG_FX25);
Ax25Config.fx25 = t & 1;
Ax25Config.fx25Tx = (t & 2) > 0;
ModemConfig.modem = read(CONFIG_MODEM);
UartUsb.config.defaultMode = read(CONFIG_MODE_USB);
return 1;
}
#elif defined(AIOC)
#define CONFIG_FLAG_WRITTEN 0xA10C
#define CONFIG_FLAG 0 //configuration written flag
#define CONFIG_GENERAL 8 //GeneralConfig
#define CONFIG_AX25 (CONFIG_GENERAL + 64) //Ax25Config
#define CONFIG_BEACON (CONFIG_AX25 + 64) //BeaconConfig
#define CONFIG_MODEM (CONFIG_BEACON + 144 * 8) //ModemConfig
#define CONFIG_DIGI (CONFIG_MODEM + 256) //DigiConfig
#define CONFIG_USB (CONFIG_DIGI + 64) //UartUsb.config
void ConfigWrite(void)
{
ConfigErase();
unlock();
writeString(CONFIG_GENERAL, &GeneralConfig, sizeof(GeneralConfig));
writeString(CONFIG_AX25, &Ax25Config, sizeof(Ax25Config));
writeString(CONFIG_BEACON, BeaconConfig, sizeof(DigiConfig));
writeString(CONFIG_MODEM, &ModemConfig, sizeof(ModemConfig));
writeString(CONFIG_DIGI, &DigiConfig, sizeof(DigiConfig));
writeString(CONFIG_USB, &(UartUsb.config), sizeof(UartUsb.config));
write(CONFIG_FLAG, CONFIG_FLAG_WRITTEN);
lock();
}
uint8_t ConfigRead(void)
{
if(read(CONFIG_FLAG) != CONFIG_FLAG_WRITTEN) //no configuration stored
{
return 0;
}
readString(CONFIG_GENERAL, &GeneralConfig, sizeof(GeneralConfig));
readString(CONFIG_AX25, &Ax25Config, sizeof(Ax25Config));
readString(CONFIG_BEACON, BeaconConfig, sizeof(DigiConfig));
readString(CONFIG_MODEM, &ModemConfig, sizeof(ModemConfig));
readString(CONFIG_DIGI, &DigiConfig, sizeof(DigiConfig));
readString(CONFIG_USB, &(UartUsb.config), sizeof(UartUsb.config));
return 1;
}
#endif