From 80c7668faab1e6848219fdfbe8c48f0330431193 Mon Sep 17 00:00:00 2001 From: Silvano Seva Date: Mon, 1 Feb 2021 21:27:31 +0100 Subject: [PATCH] Added a data structure providing some hardware information parameters and the relative platform API function to retrieve them --- openrtx/include/interfaces/nvmem.h | 8 +++++ openrtx/include/interfaces/platform.h | 37 +++++++++++++++++++++ platform/drivers/NVM/nvmem_GDx.c | 6 ++++ platform/drivers/NVM/nvmem_MD3x0.c | 46 +++++++++++++++++++++++++++ platform/drivers/NVM/nvmem_MDUV3x0.c | 38 ++++++++++++++++++++++ platform/drivers/NVM/nvmem_linux.c | 6 ++++ platform/targets/DM-1801/platform.c | 18 +++++++++++ platform/targets/GD-77/platform.c | 18 +++++++++++ platform/targets/MD-380/platform.c | 10 ++++++ platform/targets/MD-390/platform.c | 12 ++++++- platform/targets/MD-UV380/platform.c | 14 ++++++-- 11 files changed, 210 insertions(+), 3 deletions(-) diff --git a/openrtx/include/interfaces/nvmem.h b/openrtx/include/interfaces/nvmem.h index 42e90548..9b475aa9 100644 --- a/openrtx/include/interfaces/nvmem.h +++ b/openrtx/include/interfaces/nvmem.h @@ -21,6 +21,7 @@ #ifndef NVMEM_H #define NVMEM_H +#include "platform.h" #include #include @@ -46,6 +47,13 @@ void nvm_terminate(); */ void nvm_readCalibData(void *buf); +/** + * Load all or some hardware information parameters from nonvolatile memory. + * + * @param info: destination data structure for hardware information data. + */ +void nvm_loadHwInfo(hwInfo_t *info); + /** * Read one channel entry from table stored in nonvolatile memory. * diff --git a/openrtx/include/interfaces/platform.h b/openrtx/include/interfaces/platform.h index fdb64f8e..f018ee3e 100644 --- a/openrtx/include/interfaces/platform.h +++ b/openrtx/include/interfaces/platform.h @@ -33,6 +33,10 @@ * - Screen backlight control */ +/** + * \enum led_t Enumeration type for platform LED control. To allow for a wide + * platform support, LEDs are identified by their color. + */ typedef enum { GREEN = 0, @@ -41,6 +45,28 @@ typedef enum WHITE, } led_t; +/** + * \struct hwInfo_t Data structure collecting all the hardware-dependent + * information: UHF and VHF band support, manufacturer-assigned hardware name + * and LCD driver type. + */ +typedef struct +{ + char name[10]; /* Manufacturer-assigned hardware name. */ + + uint16_t uhf_maxFreq; /* Upper bound for UHF band, in MHz. */ + uint16_t uhf_minFreq; /* Lower bound for UHF band, in MHz. */ + + uint16_t vhf_maxFreq; /* Upper bound for VHF band, in MHz. */ + uint16_t vhf_minFreq; /* Lower bound for VHF band, in MHz. */ + + uint8_t _unused : 4, + uhf_band : 1, /* Device allows UHF band operation. */ + vhf_band : 1, /* Device allows VHF band operation. */ + lcd_type : 2; /* LCD display type, meaningful only on MDx targets.*/ +} hwInfo_t; + + /** * This function handles device hardware initialization. * Usually called at power-on @@ -111,8 +137,19 @@ void platform_setBacklightLevel(uint8_t level); /** * This function returns a pointer to the device-specific calbration data, * application code has to cast it to the correct data structure. + * WARNING: calling code must ensure that free() is never called on the returned + * pointer! * @return pointer to device's calibration data. */ const void *platform_getCalibrationData(); +/** + * This function returns a pointer to a data structure containing all the + * hardware information. + * WARNING: calling code must ensure that free() is never called on the returned + * pointer! + * @return pointer to device's hardware information. + */ +const hwInfo_t *platform_getHwInfo(); + #endif /* PLATFORM_H */ diff --git a/platform/drivers/NVM/nvmem_GDx.c b/platform/drivers/NVM/nvmem_GDx.c index 360369da..f126ca65 100644 --- a/platform/drivers/NVM/nvmem_GDx.c +++ b/platform/drivers/NVM/nvmem_GDx.c @@ -233,6 +233,12 @@ void nvm_readCalibData(void *buf) calib->vhfCalPoints[7] = 172000000; } +void nvm_loadHwInfo(hwInfo_t *info) +{ + /* GDx devices does not have any hardware info in the external flash. */ + (void) info; +} + int nvm_readChannelData(channel_t *channel, uint16_t pos) { return -1; diff --git a/platform/drivers/NVM/nvmem_MD3x0.c b/platform/drivers/NVM/nvmem_MD3x0.c index 8f3c560f..c831fd01 100644 --- a/platform/drivers/NVM/nvmem_MD3x0.c +++ b/platform/drivers/NVM/nvmem_MD3x0.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "W25Qx.h" /** @@ -216,6 +217,51 @@ void nvm_readCalibData(void *buf) } } +void nvm_loadHwInfo(hwInfo_t *info) +{ + uint16_t freqMin = 0; + uint16_t freqMax = 0; + uint8_t lcdInfo = 0; + + /* + * Hardware information data in MD3x0 devices is stored in security register + * 0x3000. + */ + W25Qx_wakeup(); + delayUs(5); + + (void) W25Qx_readSecurityRegister(0x3000, info->name, 8); + (void) W25Qx_readSecurityRegister(0x3014, &freqMin, 2); + (void) W25Qx_readSecurityRegister(0x3016, &freqMax, 2); + (void) W25Qx_readSecurityRegister(0x301D, &lcdInfo, 1); + W25Qx_sleep(); + + /* Ensure correct null-termination of device name by removing the 0xff. */ + for(uint8_t i = 0; i < sizeof(info->name); i++) + { + if(info->name[i] == 0xFF) info->name[i] = '\0'; + } + + /* These devices are single-band only, either VHF or UHF. */ + freqMin = ((uint16_t) _bcd2bin(freqMin))/10; + freqMax = ((uint16_t) _bcd2bin(freqMax))/10; + + if(freqMin < 200) + { + info->vhf_maxFreq = freqMax; + info->vhf_minFreq = freqMin; + info->vhf_band = 1; + } + else + { + info->uhf_maxFreq = freqMax; + info->uhf_minFreq = freqMin; + info->uhf_band = 1; + } + + info->lcd_type = lcdInfo & 0x03; +} + int nvm_readChannelData(channel_t *channel, uint16_t pos) { if(pos > maxNumChannels) return -1; diff --git a/platform/drivers/NVM/nvmem_MDUV3x0.c b/platform/drivers/NVM/nvmem_MDUV3x0.c index be4f3d36..b7e5eb36 100644 --- a/platform/drivers/NVM/nvmem_MDUV3x0.c +++ b/platform/drivers/NVM/nvmem_MDUV3x0.c @@ -246,6 +246,44 @@ void nvm_readCalibData(void *buf) } } +void nvm_loadHwInfo(hwInfo_t *info) +{ + uint16_t vhf_freqMin = 0; + uint16_t vhf_freqMax = 0; + uint16_t uhf_freqMin = 0; + uint16_t uhf_freqMax = 0; + uint8_t lcdInfo = 0; + + /* + * Hardware information data in MDUV3x0 devices is stored in security register + * 0x3000. + */ + W25Qx_wakeup(); + delayUs(5); + + (void) W25Qx_readSecurityRegister(0x3000, info->name, 8); + (void) W25Qx_readSecurityRegister(0x3014, &uhf_freqMin, 2); + (void) W25Qx_readSecurityRegister(0x3016, &uhf_freqMax, 2); + (void) W25Qx_readSecurityRegister(0x3018, &vhf_freqMin, 2); + (void) W25Qx_readSecurityRegister(0x301a, &vhf_freqMax, 2); + (void) W25Qx_readSecurityRegister(0x301D, &lcdInfo, 1); + W25Qx_sleep(); + + /* Ensure correct null-termination of device name by removing the 0xff. */ + for(uint8_t i = 0; i < sizeof(info->name); i++) + { + if(info->name[i] == 0xFF) info->name[i] = '\0'; + } + + info->vhf_minFreq = ((uint16_t) _bcd2bin(vhf_freqMin))/10; + info->vhf_maxFreq = ((uint16_t) _bcd2bin(vhf_freqMax))/10; + info->uhf_minFreq = ((uint16_t) _bcd2bin(uhf_freqMin))/10; + info->uhf_maxFreq = ((uint16_t) _bcd2bin(uhf_freqMax))/10; + info->vhf_band = 1; + info->uhf_band = 1; + info->lcd_type = lcdInfo & 0x03; +} + int nvm_readChannelData(channel_t *channel, uint16_t pos) { if(pos >= maxNumChannels) return -1; diff --git a/platform/drivers/NVM/nvmem_linux.c b/platform/drivers/NVM/nvmem_linux.c index 29ea67f1..885695a8 100644 --- a/platform/drivers/NVM/nvmem_linux.c +++ b/platform/drivers/NVM/nvmem_linux.c @@ -35,6 +35,12 @@ void nvm_terminate() { } +void nvm_loadHwInfo(hwInfo_t *info) +{ + /* Linux devices does not have any hardware info in the external flash. */ + (void) info; +} + int nvm_readChannelData(channel_t *channel, uint16_t pos) { if(pos >= maxNumChannels) return -1; diff --git a/platform/targets/DM-1801/platform.c b/platform/targets/DM-1801/platform.c index 7db38030..3c64ad28 100644 --- a/platform/targets/DM-1801/platform.c +++ b/platform/targets/DM-1801/platform.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include "hwconfig.h" @@ -32,6 +33,7 @@ OS_MUTEX adc_mutex; OS_ERR e; gdxCalibration_t calibration; +hwInfo_t hwInfo; void platform_init() { @@ -80,6 +82,17 @@ void platform_init() */ nvm_init(); nvm_readCalibData(&calibration); + + /* Initialise hardware information structure */ + hwInfo.uhf_maxFreq = FREQ_LIMIT_UHF_HI/1000000; + hwInfo.uhf_minFreq = FREQ_LIMIT_UHF_LO/1000000; + hwInfo.vhf_maxFreq = FREQ_LIMIT_VHF_HI/1000000; + hwInfo.vhf_minFreq = FREQ_LIMIT_VHF_LO/1000000; + hwInfo.uhf_band = 1; + hwInfo.vhf_band = 1; + hwInfo.lcd_type = 0; + memcpy(hwInfo.name, "DM-1801", 7); + hwInfo.name[7] = '\0'; } void platform_terminate() @@ -184,3 +197,8 @@ const void *platform_getCalibrationData() { return ((const void *) &calibration); } + +const hwInfo_t *platform_getHwInfo() +{ + return &hwInfo; +} diff --git a/platform/targets/GD-77/platform.c b/platform/targets/GD-77/platform.c index 7db38030..ee05e938 100644 --- a/platform/targets/GD-77/platform.c +++ b/platform/targets/GD-77/platform.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include "hwconfig.h" @@ -32,6 +33,7 @@ OS_MUTEX adc_mutex; OS_ERR e; gdxCalibration_t calibration; +hwInfo_t hwInfo; void platform_init() { @@ -80,6 +82,17 @@ void platform_init() */ nvm_init(); nvm_readCalibData(&calibration); + + /* Initialise hardware information structure */ + hwInfo.uhf_maxFreq = FREQ_LIMIT_UHF_HI/1000000; + hwInfo.uhf_minFreq = FREQ_LIMIT_UHF_LO/1000000; + hwInfo.vhf_maxFreq = FREQ_LIMIT_VHF_HI/1000000; + hwInfo.vhf_minFreq = FREQ_LIMIT_VHF_LO/1000000; + hwInfo.uhf_band = 1; + hwInfo.vhf_band = 1; + hwInfo.lcd_type = 0; + memcpy(hwInfo.name, "GD-77", 5); + hwInfo.name[5] = '\0'; } void platform_terminate() @@ -184,3 +197,8 @@ const void *platform_getCalibrationData() { return ((const void *) &calibration); } + +const hwInfo_t *platform_getHwInfo() +{ + return &hwInfo; +} diff --git a/platform/targets/MD-380/platform.c b/platform/targets/MD-380/platform.c index 8161907b..c5169aa7 100644 --- a/platform/targets/MD-380/platform.c +++ b/platform/targets/MD-380/platform.c @@ -21,12 +21,14 @@ #include #include #include +#include #include #include #include #include md3x0Calib_t calibration; +hwInfo_t hwInfo; void platform_init() { @@ -51,8 +53,11 @@ void platform_init() */ adc1_init(); + memset(&hwInfo, 0x00, sizeof(hwInfo)); + nvm_init(); /* Initialise non volatile memory manager */ nvm_readCalibData(&calibration); /* Load calibration data */ + nvm_loadHwInfo(&hwInfo); /* Load hardware information data */ toneGen_init(); /* Initialise tone generator */ rtc_init(); /* Initialise RTC */ @@ -192,3 +197,8 @@ const void *platform_getCalibrationData() { return ((const void *) &calibration); } + +const hwInfo_t *platform_getHwInfo() +{ + return &hwInfo; +} diff --git a/platform/targets/MD-390/platform.c b/platform/targets/MD-390/platform.c index c3a72852..c5169aa7 100644 --- a/platform/targets/MD-390/platform.c +++ b/platform/targets/MD-390/platform.c @@ -21,12 +21,14 @@ #include #include #include +#include #include #include #include #include md3x0Calib_t calibration; +hwInfo_t hwInfo; void platform_init() { @@ -45,14 +47,17 @@ void platform_init() gpio_setMode(PTT_SW, INPUT); /* - * Initialise ADC1, for vbat, RSSI, ... + * Initialise ADC1, for vbat, RSSI, ... * Configuration of corresponding GPIOs in analog input mode is done inside * the driver. */ adc1_init(); + memset(&hwInfo, 0x00, sizeof(hwInfo)); + nvm_init(); /* Initialise non volatile memory manager */ nvm_readCalibData(&calibration); /* Load calibration data */ + nvm_loadHwInfo(&hwInfo); /* Load hardware information data */ toneGen_init(); /* Initialise tone generator */ rtc_init(); /* Initialise RTC */ @@ -192,3 +197,8 @@ const void *platform_getCalibrationData() { return ((const void *) &calibration); } + +const hwInfo_t *platform_getHwInfo() +{ + return &hwInfo; +} diff --git a/platform/targets/MD-UV380/platform.c b/platform/targets/MD-UV380/platform.c index 10ddfc49..e10126b2 100644 --- a/platform/targets/MD-UV380/platform.c +++ b/platform/targets/MD-UV380/platform.c @@ -21,12 +21,14 @@ #include #include #include +#include #include #include #include #include mduv3x0Calib_t calibration; +hwInfo_t hwInfo; #ifdef ENABLE_BKLIGHT_DIMMING void TIM1_TRG_COM_TIM11_IRQHandler() @@ -64,14 +66,17 @@ void platform_init() gpio_setMode(PTT_SW, INPUT); /* - * Initialise ADC1, for vbat, RSSI, ... + * Initialise ADC1, for vbat, RSSI, ... * Configuration of corresponding GPIOs in analog input mode is done inside * the driver. */ adc1_init(); + memset(&hwInfo, 0x00, sizeof(hwInfo)); + nvm_init(); /* Initialise non volatile memory manager */ nvm_readCalibData(&calibration); /* Load calibration data */ + nvm_loadHwInfo(&hwInfo); /* Load hardware information data */ rtc_init(); /* Initialise RTC */ #ifdef ENABLE_BKLIGHT_DIMMING @@ -156,7 +161,7 @@ uint8_t platform_getChSelector() bool platform_getPttStatus() { - /* PTT line has a pullup resistor with PTT switch closing to ground */ + /* PTT line has a pullup resistor with PTT switch closing to ground */ return (gpio_readPin(PTT_SW) == 0) ? true : false; } @@ -234,3 +239,8 @@ const void *platform_getCalibrationData() { return ((const void *) &calibration); } + +const hwInfo_t *platform_getHwInfo() +{ + return &hwInfo; +}