diff --git a/meson.build b/meson.build index 76f52db8..93dcd883 100644 --- a/meson.build +++ b/meson.build @@ -457,7 +457,9 @@ mod17_def += openrtx_def + stm32f405_def ## ## Connect Systems CS70000 ## -cs7000_src = ['platform/drivers/stubs/nvmem_stub.c', +cs7000_src = ['platform/drivers/NVM/nvmem_CS7000.c', + 'platform/drivers/NVM/W25Qx.c', + 'platform/drivers/NVM/eeep.c', 'platform/drivers/stubs/cps_io_stub.c', 'platform/drivers/stubs/radio_stub.c', 'platform/drivers/keyboard/keyboard_CS7000.c', diff --git a/platform/drivers/NVM/nvmem_CS7000.c b/platform/drivers/NVM/nvmem_CS7000.c new file mode 100644 index 00000000..b7bd13ed --- /dev/null +++ b/platform/drivers/NVM/nvmem_CS7000.c @@ -0,0 +1,147 @@ +/*************************************************************************** + * Copyright (C) 2024 by Silvano Seva IU2KWO * + * * + * This program 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. * + * * + * This program 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 this program; if not, see * + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "W25Qx.h" +#include "eeep.h" + +static const struct W25QxCfg cfg = +{ + .spi = (const struct spiDevice *) &flash_spi, + .cs = { FLASH_CS } +}; + +W25Qx_DEVICE_DEFINE(eflash, cfg, 0x1000000) // 16 MB, 128 Mbit +EEEP_DEVICE_DEFINE(eeep) + +const struct nvmPartition memPartitions[] = +{ + { + .offset = 0x0000, // First partition, calibration and other OEM data + .size = 32768 // 32kB + }, + { + .offset = 0x8000, // Second partition EEEP storage + .size = 16384 // 16kB + }, + { + .offset = 0xC000, // Third partition, available memory + .size = 0xFF4000 + } +}; + +static const struct nvmDescriptor extMem[] = +{ + { + .name = "External flash", + .dev = &eflash, + .partNum = sizeof(memPartitions)/sizeof(struct nvmPartition), + .partitions = memPartitions + }, + { + .name = "Virtual EEPROM", + .dev = &eeep, + .partNum = 0, + .partitions = NULL + } +}; + +static uint16_t settingsCrc; +static uint16_t vfoCrc; + +void nvm_init() +{ + spiBitbang_init(&flash_spi); + W25Qx_init(&eflash); + eeep_init(&eeep, 0, 1); +} + +void nvm_terminate() +{ + eeep_terminate(&eeep); + W25Qx_terminate(&eflash); + spiBitbang_terminate(&flash_spi); +} + +const struct nvmDescriptor *nvm_getDesc(const size_t index) +{ + if(index > 2) + return NULL; + + return &extMem[index]; +} + +void nvm_readCalibData(void *buf) +{ + (void) buf; +} + +void nvm_readHwInfo(hwInfo_t *info) +{ + (void) info; +} + +int nvm_readVfoChannelData(channel_t *channel) +{ + memset(channel, 0x00, sizeof(channel_t)); + int ret = nvm_read(1, -1, 0x0001, channel, sizeof(channel_t)); + if(ret < 0) + return -1; + + vfoCrc = crc_ccitt(channel, sizeof(channel_t)); + + return 0; +} + +int nvm_readSettings(settings_t *settings) +{ + memset(settings, 0x00, sizeof(settings_t)); + int ret = nvm_read(1, -1, 0x0002, settings, sizeof(settings_t)); + if(ret < 0) + return -1; + + settingsCrc = crc_ccitt(settings, sizeof(settings_t)); + + return 0; +} + +int nvm_writeSettings(const settings_t *settings) +{ + (void) settings; + + return -1; +} + +int nvm_writeSettingsAndVfo(const settings_t *settings, const channel_t *vfo) +{ + uint16_t crc = crc_ccitt(vfo, sizeof(channel_t)); + if(crc != vfoCrc) + nvm_write(1, -1, 0x0001, vfo, sizeof(channel_t)); + + crc = crc_ccitt(settings, sizeof(settings_t)); + if(crc != settingsCrc) + nvm_write(1, -1, 0x0002, settings, sizeof(settings_t)); + + return 0; +} diff --git a/platform/targets/CS7000/hwconfig.c b/platform/targets/CS7000/hwconfig.c index 6653b41b..e5cdf2aa 100644 --- a/platform/targets/CS7000/hwconfig.c +++ b/platform/targets/CS7000/hwconfig.c @@ -21,6 +21,15 @@ #include #include +static const struct spiConfig spiFlashCfg = +{ + .clk = { FLASH_CLK }, + .mosi = { FLASH_SDI }, + .miso = { FLASH_SDO }, + .clkPeriod = SCK_PERIOD_FROM_FREQ(1000000), + .flags = 0 +}; + /** * SPI bitbang function for SN74HC595 gpio extender. * @@ -61,5 +70,6 @@ static const struct gpioPin shiftRegStrobe = { GPIOEXT_STR }; static pthread_mutex_t adc1Mutex; SPI_CUSTOM_DEVICE_DEFINE(spiSr, spiSr_func, NULL, NULL) +SPI_BITBANG_DEVICE_DEFINE(flash_spi, spiFlashCfg, NULL) GPIO_SHIFTREG_DEVICE_DEFINE(extGpio, (const struct spiDevice *) &spiSr, shiftRegStrobe, 24) ADC_STM32_DEVICE_DEFINE(adc1, ADC1, &adc1Mutex, 3300000) diff --git a/platform/targets/CS7000/hwconfig.h b/platform/targets/CS7000/hwconfig.h index 6cbba353..4a9d623c 100644 --- a/platform/targets/CS7000/hwconfig.h +++ b/platform/targets/CS7000/hwconfig.h @@ -36,6 +36,7 @@ enum AdcChannels extern const struct Adc adc1; extern const struct spiCustomDevice spiSr; +extern const struct spiCustomDevice flash_spi; extern const struct gpioDev extGpio; /* Screen dimensions */ diff --git a/platform/targets/CS7000/pinmap.h b/platform/targets/CS7000/pinmap.h index 595d3179..ba44587c 100644 --- a/platform/targets/CS7000/pinmap.h +++ b/platform/targets/CS7000/pinmap.h @@ -89,7 +89,7 @@ #define BEEP_OUT GPIOA,5 // System "beep" /* External flash */ -#define FLASH_CS GPIOE,2 +#define FLASH_CS &GpioE,2 #define FLASH_CLK GPIOE,3 #define FLASH_SDO GPIOE,4 #define FLASH_SDI GPIOE,5 diff --git a/platform/targets/CS7000/platform.c b/platform/targets/CS7000/platform.c index 47268b1d..294d5fd4 100644 --- a/platform/targets/CS7000/platform.c +++ b/platform/targets/CS7000/platform.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -51,6 +52,7 @@ void platform_init() spi_init((const struct spiDevice *) &spiSr); gpioShiftReg_init(&extGpio); adcStm32_init(&adc1); + nvm_init(); #ifndef RUNNING_TESTSUITE gpioDev_set(MAIN_PWR_SW);