From 6706a796adb9cc6c48e2303a555b44b27bfb71b9 Mon Sep 17 00:00:00 2001 From: Federico Amedeo Izzo Date: Fri, 22 Jan 2021 21:16:13 +0100 Subject: [PATCH] CPS: Add code to read zone data from Codeplug --- openrtx/include/cps.h | 9 ++++ openrtx/include/interfaces/nvmem.h | 9 ++++ platform/drivers/NVM/nvmem_MDUV3x0.c | 53 ++++++++++++++++++++++- tests/platform/codeplug_demo.c | 65 ++++++++++++++++++++++++++++ 4 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 tests/platform/codeplug_demo.c diff --git a/openrtx/include/cps.h b/openrtx/include/cps.h index b912669b..ecd1b6ed 100644 --- a/openrtx/include/cps.h +++ b/openrtx/include/cps.h @@ -102,4 +102,13 @@ typedef struct }; } channel_t; +/** + * Data structure containing all the information of a zone. + */ +typedef struct +{ + char name[16]; /**< Zone name */ + uint16_t member[64]; /**< Channels 1...64, 0=empty zone */ +} zone_t; + #endif diff --git a/openrtx/include/interfaces/nvmem.h b/openrtx/include/interfaces/nvmem.h index 67a81996..692e82e9 100644 --- a/openrtx/include/interfaces/nvmem.h +++ b/openrtx/include/interfaces/nvmem.h @@ -55,4 +55,13 @@ void nvm_readCalibData(void *buf); */ int nvm_readChannelData(channel_t *channel, uint16_t pos); +/** + * Read one zone from table stored in nonvolatile memory. + * + * @param zone: pointer to the zone_t data structure to be populated. + * @param pos: position, inside the zone table, from which read data. + * @return 0 on success, -1 on failure + */ +int nvm_readZoneData(zone_t *zone, uint16_t pos); + #endif /* NVMEM_H */ diff --git a/platform/drivers/NVM/nvmem_MDUV3x0.c b/platform/drivers/NVM/nvmem_MDUV3x0.c index bb3d9fec..04adac5c 100644 --- a/platform/drivers/NVM/nvmem_MDUV3x0.c +++ b/platform/drivers/NVM/nvmem_MDUV3x0.c @@ -18,6 +18,7 @@ * along with this program; if not, see * ***************************************************************************/ +#include #include #include #include @@ -25,7 +26,7 @@ /** * \internal Data structure matching the one used by original MD3x0 firmware to - * manage channel data inside nonvolatile flash memory. + * manage codeplug data inside nonvolatile flash memory. * * Taken by dmrconfig repository: https://github.com/sergev/dmrconfig/blob/master/uv380.c */ @@ -116,8 +117,27 @@ typedef struct } mduv3x0Channel_t; +typedef struct { + // Bytes 0-31 + uint16_t name[16]; // Zone Name (Unicode) + + // Bytes 32-63 + uint16_t member_a[16]; // Member A: channels 1...16 +} mduv3x0Zone_t; + +typedef struct { + // Bytes 0-95 + uint16_t ext_a[48]; // Member A: channels 17...64 + + // Bytes 96-223 + uint16_t member_b[64]; // Member B: channels 1...64 +} mduv3x0ZoneExt_t; + const uint32_t chDataBaseAddr = 0x110000; /**< Base address of channel data */ +const uint32_t zoneBaseAddr = 0x149e0; /**< Base address of zones */ +const uint32_t zoneExtBaseAddr = 0x31000; /**< Base address of zone extensions */ const uint32_t maxNumChannels = 3000; /**< Maximum number of channels in memory */ +const uint32_t maxNumZones = 250; /**< Maximum number of zones and zone extensions in memory */ /** * \internal Utility function to convert 4 byte BCD values into a 32-bit @@ -301,3 +321,34 @@ int nvm_readChannelData(channel_t *channel, uint16_t pos) return 0; } + +int nvm_readZoneData(zone_t *zone, uint16_t pos) +{ + if(pos > maxNumZones) return -1; + + W25Qx_wakeup(); + delayUs(5); + + mduv3x0Zone_t zoneData; + mduv3x0ZoneExt_t zoneExtData; + uint32_t zoneAddr = zoneBaseAddr + pos * sizeof(mduv3x0Zone_t); + uint32_t zoneExtAddr = zoneBaseAddr + pos * sizeof(mduv3x0Zone_t); + W25Qx_readData(zoneAddr, ((uint8_t *) &zoneData), sizeof(mduv3x0Zone_t)); + W25Qx_readData(zoneExtAddr, ((uint8_t *) &zoneExtData), sizeof(mduv3x0ZoneExt_t)); + W25Qx_sleep(); + + /* + * Brutally convert channel name from unicode to char by truncating the most + * significant byte + */ + for(uint16_t i = 0; i < 16; i++) + { + zone->name[i] = ((char) (zoneData.name[i] & 0x00FF)); + } + // Copy zone channel indexes + memcpy(zone->member, zoneData.member_a, sizeof(uint16_t) * 16); + // Copy zone extension channel indexes + memcpy(zone->member + 16, zoneExtData.ext_a, sizeof(uint16_t) * 48); + + return 0; +} diff --git a/tests/platform/codeplug_demo.c b/tests/platform/codeplug_demo.c new file mode 100644 index 00000000..8a315a70 --- /dev/null +++ b/tests/platform/codeplug_demo.c @@ -0,0 +1,65 @@ +/*************************************************************************** + * Copyright (C) 2020 by Federico Amedeo Izzo IU2NUO, * + * Niccolò Izzo IU2KIN, * + * Frederik Saraci IU2NRO, * + * 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 + +int main() +{ + nvm_init(); + + getchar(); + printf("Codeplug Demo!\r\n\r\n"); + printf("Contacts:\r\n"); + for(uint16_t pos=0,result=0; result != -1 && pos < 20; pos++) + { + channel_t ch; + result = nvm_readChannelData(&ch, pos); + printf("Contact n.%d:\r\n", pos+1); + printf(" %s\r\n TX: %ld\r\n RX: %ld\r\n Mode: %s\r\n Bandwidth: %s\r\n", + ch.name, + ch.tx_frequency, + ch.rx_frequency, + (ch.mode == 1) ? "DMR" : "FM", + (ch.bandwidth == BW_12_5) ? "12.5kHz" : ((ch.bandwidth == BW_20) + ? "20kHz" : "25kHz")); + puts("\r"); + } + printf("Zones:\r\n"); + for(uint16_t pos=0,result=0; result != -1 && pos < 5; pos++) + { + zone_t zone; + result = nvm_readZoneData(&zone, pos); + printf("Zone n.%d:\r\n", pos+1); + printf(" %s\r\n", zone.name); + for(int x=0; x < 64; x++) + { + if(zone.member[x] != 0) + { + printf(" - Channel %d\r\n", zone.member[x]); + } + } + puts("\r"); + } + return 0; +}