| 
									
										
										
										
											2020-12-29 16:18:16 +00:00
										 |  |  | /***************************************************************************
 | 
					
						
							|  |  |  |  *   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 <http://www.gnu.org/licenses/>   *
 | 
					
						
							|  |  |  |  ***************************************************************************/ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-14 16:34:40 +00:00
										 |  |  | #include <string.h>
 | 
					
						
							| 
									
										
										
										
											2021-01-02 14:17:15 +00:00
										 |  |  | #include <interfaces/delays.h>
 | 
					
						
							|  |  |  | #include <interfaces/nvmem.h>
 | 
					
						
							| 
									
										
										
										
											2020-12-29 16:18:16 +00:00
										 |  |  | #include <calibInfo_GDx.h>
 | 
					
						
							|  |  |  | #include "AT24Cx.h"
 | 
					
						
							|  |  |  | #include "W25Qx.h"
 | 
					
						
							| 
									
										
										
										
											2021-02-14 16:34:40 +00:00
										 |  |  | #include "nvmData_GDx.h"
 | 
					
						
							| 
									
										
										
										
											2020-12-29 16:18:16 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #if defined(PLATFORM_GD77)
 | 
					
						
							|  |  |  | static const uint32_t UHF_CAL_BASE = 0x8F000; | 
					
						
							|  |  |  | static const uint32_t VHF_CAL_BASE = 0x8F070; | 
					
						
							|  |  |  | #elif defined(PLATFORM_DM1801)
 | 
					
						
							|  |  |  | static const uint32_t UHF_CAL_BASE = 0x6F000; | 
					
						
							|  |  |  | static const uint32_t VHF_CAL_BASE = 0x6F070; | 
					
						
							|  |  |  | #else
 | 
					
						
							|  |  |  | #warning GDx calibration: platform not supported
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-14 16:34:40 +00:00
										 |  |  | //const uint32_t zoneBaseAddr    = 0x149e0;  /**< Base address of zones                */
 | 
					
						
							| 
									
										
										
										
											2021-02-18 14:41:59 +00:00
										 |  |  | const uint32_t channelBaseAddrEEPROM = 0x03780;  /**< Base address of channel data   */ | 
					
						
							| 
									
										
										
										
											2021-02-14 16:34:40 +00:00
										 |  |  | const uint32_t channelBaseAddrFlash  = 0x7b1c0;  /**< Base address of channel data   */ | 
					
						
							|  |  |  | const uint32_t contactBaseAddr = 0x87620;  /**< Base address of contacts             */ | 
					
						
							|  |  |  | const uint32_t maxNumChannels  = 1024;     /**< Maximum number of channels in memory */ | 
					
						
							|  |  |  | const uint32_t maxNumZones     = 68;      /**< Maximum number of zones in memory    */ | 
					
						
							|  |  |  | const uint32_t maxNumContacts  = 1024;    /**< Maximum number of contacts in memory */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-29 16:18:16 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * \internal Utility function to convert 4 byte BCD values into a 32-bit | 
					
						
							|  |  |  |  * unsigned integer ones. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | uint32_t _bcd2bin(uint32_t bcd) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     return ((bcd >> 28) & 0x0F) * 10000000 + | 
					
						
							|  |  |  |            ((bcd >> 24) & 0x0F) * 1000000 + | 
					
						
							|  |  |  |            ((bcd >> 20) & 0x0F) * 100000 + | 
					
						
							|  |  |  |            ((bcd >> 16) & 0x0F) * 10000 + | 
					
						
							|  |  |  |            ((bcd >> 12) & 0x0F) * 1000 + | 
					
						
							|  |  |  |            ((bcd >> 8) & 0x0F)  * 100 + | 
					
						
							|  |  |  |            ((bcd >> 4) & 0x0F)  * 10 + | 
					
						
							|  |  |  |            (bcd & 0x0F); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-21 11:34:11 +00:00
										 |  |  | /**
 | 
					
						
							|  |  |  |  * \internal Utility function for loading band-specific calibration data into | 
					
						
							|  |  |  |  * the corresponding data structure. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | void _loadBandCalData(uint32_t baseAddr, bandCalData_t *cal) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x08, &(cal->mod1Bias),              2); | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x0A, &(cal->mod2Offset),            1); | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x3F, cal->analogSqlThresh,          8); | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x47, &(cal->noise1_HighTsh_Wb),     1); | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x48, &(cal->noise1_LowTsh_Wb),      1); | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x49, &(cal->noise2_HighTsh_Wb),     1); | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x4A, &(cal->noise2_LowTsh_Wb),      1); | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x4B, &(cal->rssi_HighTsh_Wb),       1); | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x4C, &(cal->rssi_LowTsh_Wb),        1); | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x4D, &(cal->noise1_HighTsh_Nb),     1); | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x4E, &(cal->noise1_LowTsh_Nb),      1); | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x4F, &(cal->noise2_HighTsh_Nb),     1); | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x50, &(cal->noise2_LowTsh_Nb),      1); | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x51, &(cal->rssi_HighTsh_Nb),       1); | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x52, &(cal->rssi_LowTsh_Nb),        1); | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x53, &(cal->RSSILowerThreshold),    1); | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x54, &(cal->RSSIUpperThreshold),    1); | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x55, cal->mod1Amplitude,            8); | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x5D, &(cal->dacDataRange),          1); | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x5E, &(cal->txDev_DTMF),            1); | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x5F, &(cal->txDev_tone),            1); | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x60, &(cal->txDev_CTCSS_wb),        1); | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x61, &(cal->txDev_CTCSS_nb),        1); | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x62, &(cal->txDev_DCS_wb),          1); | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x63, &(cal->txDev_DCS_nb),          1); | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x64, &(cal->PA_drv),                1); | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x65, &(cal->PGA_gain),              1); | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x66, &(cal->analogMicGain),         1); | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x67, &(cal->rxAGCgain),             1); | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x68, &(cal->mixGainWideband),       2); | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x6A, &(cal->mixGainNarrowband),     2); | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x6C, &(cal->rxAudioGainWideband),   1); | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x6D, &(cal->rxAudioGainNarrowband), 1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     uint8_t txPwr[32] = {0}; | 
					
						
							|  |  |  |     W25Qx_readData(baseAddr + 0x0B, txPwr, 32); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for(uint8_t i = 0; i < 16; i++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         cal->txLowPower[i]  = txPwr[2*i]; | 
					
						
							|  |  |  |         cal->txHighPower[i] = txPwr[2*i+1]; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-29 16:18:16 +00:00
										 |  |  | void nvm_init() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     W25Qx_init(); | 
					
						
							|  |  |  |     AT24Cx_init(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void nvm_terminate() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     W25Qx_terminate(); | 
					
						
							|  |  |  |     AT24Cx_terminate(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void nvm_readCalibData(void *buf) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     W25Qx_wakeup(); | 
					
						
							|  |  |  |     delayUs(5); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     gdxCalibration_t *calib = ((gdxCalibration_t *) buf); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-21 11:34:11 +00:00
										 |  |  |     _loadBandCalData(VHF_CAL_BASE, &(calib->data[0]));  /* Load VHF band calibration data */ | 
					
						
							|  |  |  |     _loadBandCalData(UHF_CAL_BASE, &(calib->data[1]));  /* Load UHF band calibration data */ | 
					
						
							| 
									
										
										
										
											2020-12-29 16:18:16 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     W25Qx_sleep(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /*
 | 
					
						
							|  |  |  |      * Finally, load calibration points. These are common among all the GDx | 
					
						
							|  |  |  |      * devices. | 
					
						
							|  |  |  |      * VHF calibration head and tail are not equally spaced as the other points, | 
					
						
							|  |  |  |      * so we manually override the values. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     for(uint8_t i = 0; i < 16; i++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         uint8_t ii = i/2; | 
					
						
							|  |  |  |         calib->uhfMod1CalPoints[ii] = 405000000 + (5000000 * ii); | 
					
						
							|  |  |  |         calib->uhfPwrCalPoints[i]   = 400000000 + (5000000 * i); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     for(uint8_t i = 0; i < 8; i++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         calib->vhfCalPoints[i] = 135000000 + (5000000 * i); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     calib->vhfCalPoints[0] = 136000000; | 
					
						
							|  |  |  |     calib->vhfCalPoints[7] = 172000000; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-01 20:27:31 +00:00
										 |  |  | void nvm_loadHwInfo(hwInfo_t *info) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     /* GDx devices does not have any hardware info in the external flash. */ | 
					
						
							|  |  |  |     (void) info; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-10 19:30:57 +00:00
										 |  |  | int nvm_readVFOChannelData(channel_t *channel) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     (void) channel; | 
					
						
							|  |  |  |     return -1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-12-29 16:18:16 +00:00
										 |  |  | int nvm_readChannelData(channel_t *channel, uint16_t pos) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-02-14 16:34:40 +00:00
										 |  |  |     if((pos <= 0) || (pos > maxNumChannels)) | 
					
						
							|  |  |  |         return -1; | 
					
						
							|  |  |  |          | 
					
						
							|  |  |  |     // Channels are organized in 128-channel banks
 | 
					
						
							|  |  |  |     uint8_t bank_num = (pos - 1) / 128; | 
					
						
							|  |  |  |     // Note: pos is 1-based because an empty slot in a zone contains index 0
 | 
					
						
							|  |  |  |     uint8_t bank_channel = (pos - 1) % 128; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // ### Read channel bank bitmap ###
 | 
					
						
							|  |  |  |     uint8_t bitmap[16]; | 
					
						
							|  |  |  |     // First channel bank (128 channels) is saved in EEPROM
 | 
					
						
							|  |  |  |     if(pos <= 128) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         uint32_t readAddr = channelBaseAddrEEPROM + bank_num * sizeof(gdxChannelBank_t); | 
					
						
							|  |  |  |         AT24Cx_readData(readAddr, ((uint8_t *) &bitmap), sizeof(bitmap)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     // Remaining 7 channel banks (896 channels) are saved in SPI Flash
 | 
					
						
							|  |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         W25Qx_wakeup(); | 
					
						
							|  |  |  |         delayUs(5); | 
					
						
							|  |  |  |         uint32_t readAddr = channelBaseAddrFlash + (bank_num - 1) * sizeof(gdxChannelBank_t); | 
					
						
							|  |  |  |         W25Qx_readData(readAddr, ((uint8_t *) &bitmap), sizeof(bitmap)); | 
					
						
							|  |  |  |         W25Qx_sleep(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     uint8_t bitmap_byte = bank_channel / 8; | 
					
						
							|  |  |  |     uint8_t bitmap_bit = bank_channel % 8; | 
					
						
							| 
									
										
										
										
											2021-02-17 07:06:21 +00:00
										 |  |  |     gdxChannel_t chData; | 
					
						
							| 
									
										
										
										
											2021-02-14 16:34:40 +00:00
										 |  |  |     // The channel is marked not valid in the bitmap
 | 
					
						
							| 
									
										
										
										
											2021-02-19 14:08:29 +00:00
										 |  |  |     if(!(bitmap[bitmap_byte] & (1 << bitmap_bit))) | 
					
						
							| 
									
										
										
										
											2021-02-14 16:34:40 +00:00
										 |  |  |         return -1; | 
					
						
							|  |  |  |     // The channel is marked valid in the bitmap
 | 
					
						
							| 
									
										
										
										
											2021-02-17 07:06:21 +00:00
										 |  |  |     // ### Read desired channel from the correct bank ###
 | 
					
						
							| 
									
										
										
										
											2021-02-14 16:34:40 +00:00
										 |  |  |     else | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2021-02-17 07:06:21 +00:00
										 |  |  |         uint32_t channelOffset = sizeof(bitmap) + (pos - 1) * sizeof(gdxChannel_t); | 
					
						
							| 
									
										
										
										
											2021-02-14 16:34:40 +00:00
										 |  |  |         // First channel bank (128 channels) is saved in EEPROM
 | 
					
						
							|  |  |  |         if(pos <= 128) | 
					
						
							|  |  |  |         { | 
					
						
							| 
									
										
										
										
											2021-02-17 07:06:21 +00:00
										 |  |  |             uint32_t bankAddr = channelBaseAddrEEPROM + bank_num * sizeof(gdxChannelBank_t); | 
					
						
							|  |  |  |             AT24Cx_readData(bankAddr + channelOffset, ((uint8_t *) &chData), sizeof(gdxChannel_t)); | 
					
						
							| 
									
										
										
										
											2021-02-14 16:34:40 +00:00
										 |  |  |         } | 
					
						
							|  |  |  |         // Remaining 7 channel banks (896 channels) are saved in SPI Flash
 | 
					
						
							|  |  |  |         else | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             W25Qx_wakeup(); | 
					
						
							|  |  |  |             delayUs(5); | 
					
						
							| 
									
										
										
										
											2021-02-17 07:06:21 +00:00
										 |  |  |             uint32_t bankAddr = channelBaseAddrFlash + bank_num * sizeof(gdxChannelBank_t); | 
					
						
							|  |  |  |             W25Qx_readData(bankAddr + channelOffset, ((uint8_t *) &chData), sizeof(gdxChannel_t)); | 
					
						
							| 
									
										
										
										
											2021-02-14 16:34:40 +00:00
										 |  |  |             W25Qx_sleep(); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     // Copy data to OpenRTX channel_t
 | 
					
						
							|  |  |  |     channel->mode            = chData.channel_mode - 1; | 
					
						
							|  |  |  |     channel->bandwidth       = chData.bandwidth; | 
					
						
							|  |  |  |     channel->admit_criteria  = chData.admit_criteria; | 
					
						
							|  |  |  |     channel->squelch         = chData.squelch; | 
					
						
							|  |  |  |     channel->rx_only         = chData.rx_only; | 
					
						
							|  |  |  |     channel->vox             = chData.vox; | 
					
						
							|  |  |  |     channel->power           = ((chData.power == 1) ? 5.0f : 1.0f); | 
					
						
							|  |  |  |     channel->rx_frequency    = _bcd2bin(chData.rx_frequency) * 10; | 
					
						
							|  |  |  |     channel->tx_frequency    = _bcd2bin(chData.tx_frequency) * 10; | 
					
						
							|  |  |  |     channel->tot             = chData.tot; | 
					
						
							|  |  |  |     channel->tot_rekey_delay = chData.tot_rekey_delay; | 
					
						
							|  |  |  |     channel->emSys_index     = chData.emergency_system_index; | 
					
						
							|  |  |  |     channel->scanList_index  = chData.scan_list_index; | 
					
						
							|  |  |  |     channel->groupList_index = chData.group_list_index; | 
					
						
							|  |  |  |     memcpy(channel->name, chData.name, sizeof(chData.name)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /* Load mode-specific parameters */ | 
					
						
							|  |  |  |     if(channel->mode == FM) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         channel->fm.txToneEn = 0; | 
					
						
							|  |  |  |         channel->fm.rxToneEn = 0; | 
					
						
							|  |  |  |         uint16_t rx_css = chData.ctcss_dcs_receive; | 
					
						
							|  |  |  |         uint16_t tx_css = chData.ctcss_dcs_transmit; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // TODO: Implement binary search to speed up this lookup
 | 
					
						
							|  |  |  |         if((rx_css != 0) && (rx_css != 0xFFFF)) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             for(int i = 0; i < MAX_TONE_INDEX; i++) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 if(ctcss_tone[i] == ((uint16_t) _bcd2bin(rx_css))) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     channel->fm.rxTone = i; | 
					
						
							|  |  |  |                     channel->fm.rxToneEn = 1; | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if((tx_css != 0) && (tx_css != 0xFFFF)) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             for(int i = 0; i < MAX_TONE_INDEX; i++) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 if(ctcss_tone[i] == ((uint16_t) _bcd2bin(tx_css))) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     channel->fm.txTone = i; | 
					
						
							|  |  |  |                     channel->fm.txToneEn = 1; | 
					
						
							|  |  |  |                     break; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         // TODO: Implement warning screen if tone was not found
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     else if(channel->mode == DMR) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         channel->dmr.contactName_index = chData.contact_name_index; | 
					
						
							|  |  |  |         channel->dmr.dmr_timeslot      = chData.repeater_slot; | 
					
						
							|  |  |  |         channel->dmr.rxColorCode       = chData.colorcode_rx; | 
					
						
							|  |  |  |         channel->dmr.txColorCode       = chData.colorcode_tx; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return 0; | 
					
						
							| 
									
										
										
										
											2020-12-29 16:18:16 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2021-01-24 17:11:09 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | int nvm_readZoneData(zone_t *zone, uint16_t pos) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-02-03 13:50:00 +00:00
										 |  |  |     (void) zone; | 
					
						
							|  |  |  |     (void) pos; | 
					
						
							| 
									
										
										
										
											2021-01-24 17:11:09 +00:00
										 |  |  |     return -1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int nvm_readContactData(contact_t *contact, uint16_t pos) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2021-02-03 13:50:00 +00:00
										 |  |  |     (void) contact; | 
					
						
							|  |  |  |     (void) pos; | 
					
						
							| 
									
										
										
										
											2021-01-24 17:11:09 +00:00
										 |  |  |     return -1; | 
					
						
							|  |  |  | } |