kopia lustrzana https://github.com/OpenRTX/OpenRTX
Cleanup and reorganisation of state header file, new OpenRTX CPS data structure
rodzic
da22d6ff64
commit
cbd3922325
|
@ -24,7 +24,7 @@ openrtx_src = ['openrtx/src/core/state.c',
|
|||
'openrtx/src/core/battery.c',
|
||||
'openrtx/src/core/graphics.cpp',
|
||||
'openrtx/src/core/input.c',
|
||||
'openrtx/src/core/calibUtils.c',
|
||||
'openrtx/src/core/utils.c',
|
||||
'openrtx/src/core/queue.c',
|
||||
'openrtx/src/core/chan.c',
|
||||
'openrtx/src/core/gps.c',
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2020 by Federico Amedeo Izzo IU2NUO, *
|
||||
* Niccolò Izzo IU2KIN, *
|
||||
* Frederik Saraci IU2NRO, *
|
||||
* Silvano Seva IU2KWO *
|
||||
* Copyright (C) 2020 - 2022 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 *
|
||||
|
@ -26,129 +26,262 @@
|
|||
#include <datatypes.h>
|
||||
#include <rtx.h>
|
||||
|
||||
/**
|
||||
* \enum admit_t Enumeration type defining the admission criteria to a the
|
||||
* channel.
|
||||
*/
|
||||
enum admit_t
|
||||
{
|
||||
ALWAYS = 0, /**< Always transmit when PTT is pressed */
|
||||
FREE = 1, /**< Transmit only if channel si free */
|
||||
TONE = 2, /**< Transmit on matching tone */
|
||||
COLOR = 3 /**< Transmit only if color code is not used yet */
|
||||
};
|
||||
// Magic number to identify the binary file
|
||||
#define CPS_MAGIC 0x52545843
|
||||
// Codeplug version v0.1
|
||||
#define CPS_VERSION_MAJOR 0
|
||||
#define CPS_VERSION_MINOR 1
|
||||
#define CPS_VERSION_NUMBER (CPS_VERSION_MAJOR << 8) | CPS_VERSION_MINOR
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* FM MODE *
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* Data structure containing all and only the information for analog FM channels,
|
||||
* like CTC/DCS tones.
|
||||
* Data structure containing the tone information for analog FM channels.
|
||||
* This is just a lookup table for the CTCSS frequencies and is not actually
|
||||
* present in the codeplug binary data.
|
||||
*/
|
||||
#define MAX_TONE_INDEX 50
|
||||
static const uint16_t ctcss_tone[MAX_TONE_INDEX] = {
|
||||
static const uint16_t ctcss_tone[MAX_TONE_INDEX] =
|
||||
{
|
||||
670, 693, 719, 744, 770, 797, 825, 854, 885, 915, 948, 974, 1000, 1034,
|
||||
1072, 1109, 1148, 1188, 1230, 1273, 1318, 1365, 1413, 1462, 1514, 1567,
|
||||
1598, 1622, 1655, 1679, 1713, 1738, 1773, 1799, 1835, 1862, 1899, 1928,
|
||||
1966, 1995, 2035, 2065, 2107, 2181, 2257, 2291, 2336, 2418, 2503, 2541
|
||||
};
|
||||
|
||||
/**
|
||||
* Data structure defining an analog-specific channel information such as tones.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t rxToneEn : 1, /**< RX CTC/DCS tone enable */
|
||||
rxTone : 7; /**< RX CTC/DCS tone index, squelch opens on match */
|
||||
uint8_t txToneEn : 1, /**< TX CTC/DCS tone enable */
|
||||
txTone : 7; /**< TX CTC/DCS tone index, sent alongside voice */
|
||||
uint8_t rxToneEn : 1, //< RX CTC/DCS tone enable
|
||||
rxTone : 7; //< RX CTC/DCS tone index
|
||||
uint8_t txToneEn : 1, //< TX CTC/DCS tone enable
|
||||
txTone : 7; //< TX CTC/DCS tone index
|
||||
}
|
||||
__attribute__((packed)) fmInfo_t;
|
||||
__attribute__((packed)) fmInfo_t; // 2B
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* DMR MODE *
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* Data structure containing all and only the information for DMR channels.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t rxColorCode : 4, /**< Color code for RX squelch opening */
|
||||
txColorCode : 4; /**< Color code sent during transmission */
|
||||
uint8_t rxColorCode : 4, //< Color code for RX squelch opening
|
||||
txColorCode : 4; //< Color code sent during transmission
|
||||
|
||||
uint8_t dmr_timeslot; /**< DMR timeslot, either 1 or 2 */
|
||||
uint16_t contactName_index; /**< Index to retrieve data from contact list */
|
||||
uint8_t dmr_timeslot; //< DMR timeslot, either 1 or 2
|
||||
uint16_t contactName_index; //< Index to retrieve contact from list
|
||||
}
|
||||
__attribute__((packed)) dmrInfo_t;
|
||||
__attribute__((packed)) dmrInfo_t; // 4B
|
||||
|
||||
/**
|
||||
* Enumeration type defining the types of a DMR contact.
|
||||
*/
|
||||
enum dmrContactType_t
|
||||
{
|
||||
GROUP = 0, //< Group contact (Talkgroup)
|
||||
PRIVATE = 1, //< Private contact
|
||||
ALL = 2 //< Broadcast call
|
||||
};
|
||||
|
||||
/**
|
||||
* Data structure describing a DMR contact entry.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint32_t id; //< DMR id
|
||||
|
||||
uint8_t contactType : 2, //< Call type
|
||||
rx_tone : 1, //< Call receive tone
|
||||
_unused : 5; //< Padding
|
||||
}
|
||||
__attribute__((packed)) dmrContact_t; // 5B
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* M17 MODE *
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* M17 channel modes.
|
||||
*/
|
||||
enum m17mode_t
|
||||
{
|
||||
DIGITAL_VOICE = 1, //< Digital Voice
|
||||
DIGITAL_DATA = 2, //< Digital Data
|
||||
DIGITAL_VOICE_DATA = 3 //< Digital Voice and Data
|
||||
};
|
||||
|
||||
/**
|
||||
* M17 channel encryption.
|
||||
*/
|
||||
enum m17crypto_t
|
||||
{
|
||||
PLAIN = 0, //< No encryption, plaintext data is sent
|
||||
AES256 = 1, //< AES-256 Encryption
|
||||
SCRAMBLER = 2 //< Scrambler
|
||||
};
|
||||
|
||||
/**
|
||||
* M17 gps operation.
|
||||
*/
|
||||
enum m17gps_t
|
||||
{
|
||||
NO_GPS = 0, //< No GPS information is sent
|
||||
GPS_META = 1 //< GPS position is sent along with payload
|
||||
};
|
||||
|
||||
/**
|
||||
* Data structure containing all and only the information for M17 channels.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t rxCan : 4, /**< Channel Access Number for RX squelch */
|
||||
txCan : 4; /**< Channel Access Number for TX squelch */
|
||||
|
||||
uint16_t contactName_index; /**< Index to retrieve data from contact list */
|
||||
uint8_t rxCan : 4, //< Channel Access Number for RX
|
||||
txCan : 4; //< Channel Access Number for TX
|
||||
uint8_t mode : 4, //< Channel operation mode
|
||||
encr : 4; //< Encryption mode
|
||||
uint8_t gps_mode; //< Channel GPS mode
|
||||
uint16_t contactName_index; //< Index to retrieve data from contact list
|
||||
}
|
||||
__attribute__((packed)) m17Info_t;
|
||||
__attribute__((packed)) m17Info_t; // 5B
|
||||
|
||||
/**
|
||||
* Data structure containing all the information of a channel, either FM or DMR.
|
||||
* Data structure describing M17-specific contact fields.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t mode; /**< Operating mode */
|
||||
uint8_t address[6]; //< M17 encoded address
|
||||
}
|
||||
__attribute__((packed)) m17Contact_t; // 6B
|
||||
|
||||
uint8_t bandwidth : 2, /**< Bandwidth */
|
||||
admit_criteria : 2, /**< Admit criterion */
|
||||
squelch : 1, /**< Squelch type: 0 = tight, 1 = normal */
|
||||
rx_only : 1, /**< 1 means RX-only channel */
|
||||
vox : 1, /**< VOX enable */
|
||||
_padding : 1; /**< Padding to 8 bits */
|
||||
|
||||
float power; /**< Transmission power, in watt */
|
||||
|
||||
freq_t rx_frequency; /**< RX Frequency, in Hz */
|
||||
freq_t tx_frequency; /**< TX Frequency, in Hz */
|
||||
/******************************************************************************
|
||||
* COMMON DATA STRUCTURES *
|
||||
******************************************************************************/
|
||||
|
||||
uint8_t tot; /**< TOT x 15sec: 0-Infinite, 1=15s...33=495s */
|
||||
uint8_t tot_rekey_delay; /**< TOT Rekey Delay: 0...255s */
|
||||
/**
|
||||
* Data structure for geolocation data
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
int8_t ch_lat_int; //< Latitude integer part
|
||||
uint16_t ch_lat_dec; //< Latitude decimal part
|
||||
int16_t ch_lon_int; //< Longitude integer part
|
||||
uint16_t ch_lon_dec; //< Longitude decimal part
|
||||
uint16_t ch_altitude; //< Meters MSL. Stored +500
|
||||
}
|
||||
__attribute__((packed)) geo_t; // 9B
|
||||
|
||||
uint8_t emSys_index; /**< Emergency System: None, System1...32 */
|
||||
uint8_t scanList_index; /**< Scan List: None, ScanList1...250 */
|
||||
uint8_t groupList_index; /**< Group List: None, GroupList1...128 */
|
||||
/**
|
||||
* Data structure containing all the information of a channel.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t mode; //< Operating mode
|
||||
|
||||
char name[16]; /**< Channel name */
|
||||
uint8_t bandwidth : 2, //< Bandwidth
|
||||
rx_only : 1, //< 1 means RX-only channel
|
||||
_unused : 5; //< Padding to 8 bits
|
||||
|
||||
uint8_t power; //< P = 10dBm + n*0.2dBm, we store n
|
||||
|
||||
freq_t rx_frequency; //< RX Frequency, in Hz
|
||||
freq_t tx_frequency; //< TX Frequency, in Hz
|
||||
|
||||
uint8_t scanList_index; //< Scan List: None, ScanList1...250
|
||||
uint8_t groupList_index; //< Group List: None, GroupList1...128
|
||||
|
||||
char name[16]; //< Channel name
|
||||
char descr[16]; //< Description of the channel
|
||||
geo_t ch_location; //< Transmitter geolocation
|
||||
|
||||
union
|
||||
{
|
||||
fmInfo_t fm; /**< Information block for FM channels */
|
||||
dmrInfo_t dmr; /**< Information block for DMR channels */
|
||||
m17Info_t m17; /**< Information block for M17 channels */
|
||||
fmInfo_t fm; //< Information block for FM channels
|
||||
dmrInfo_t dmr; //< Information block for DMR channels
|
||||
m17Info_t m17; //< Information block for M17 channels
|
||||
};
|
||||
}
|
||||
__attribute__((packed)) channel_t;
|
||||
|
||||
__attribute__((packed)) channel_t; // 59B
|
||||
|
||||
/**
|
||||
* Data structure containing all the information of a bank.
|
||||
* Data structure describing a codeplug contact.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
char name[16]; /**< Bank name */
|
||||
uint16_t member[64]; /**< Channel indexes */
|
||||
char name[16]; //< Display name of the contact
|
||||
uint8_t mode; //< Operating mode
|
||||
|
||||
union
|
||||
{
|
||||
dmrContact_t dmr; //< DMR specific contact info
|
||||
m17Contact_t m17; //< M17 specific contact info
|
||||
}
|
||||
info; // 6B
|
||||
}
|
||||
__attribute__((packed)) contact_t; // 23B
|
||||
|
||||
/**
|
||||
* Data structure containing all the information of a bank.
|
||||
* Legacy data structure for brackwards compatibility.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
char name[16]; //< Bank name
|
||||
uint16_t member[64]; //< Channel indexes
|
||||
}
|
||||
__attribute__((packed)) bank_t;
|
||||
|
||||
/**
|
||||
* Data structure containing all the information of a contact.
|
||||
* Data structure describing a bank header.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
char name[16]; /**< Contact name */
|
||||
uint32_t id; /**< DMR ID: 24bit number, 1...16777215 */
|
||||
uint8_t type; /**< Call Type: Group Call, Private Call or All Call */
|
||||
bool receive_tone; /**< Call Receive Tone: No or yes */
|
||||
char name[16];
|
||||
uint16_t ch_count; //< Count of all the channels in this bank
|
||||
}
|
||||
__attribute__((packed)) contact_t;
|
||||
__attribute__((packed)) bankHdr_t; // 18B + 2 * ch_count
|
||||
|
||||
/*
|
||||
|
||||
/**
|
||||
* The codeplug binary structure is composed by:
|
||||
* - A header struct
|
||||
* - A variable length array of all the contacts
|
||||
* - A variable length array of all the channels
|
||||
* - A variable length array of the offsets to reach each bank
|
||||
* - A binary dense structure of all the banks
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint64_t magic; //< Magic number "RTXC"
|
||||
uint16_t version_number; //< Version number for the cps structure
|
||||
char author[16]; //< Author of the codeplug
|
||||
char descr[16]; //< Description of the codeplug
|
||||
uint64_t timestamp; //< unix timestamp of the codeplug
|
||||
|
||||
uint16_t ct_count; //< Number of stored contacts
|
||||
uint16_t ch_count; //< Number of stored channels
|
||||
uint16_t b_count; //< Number of stored banks
|
||||
}
|
||||
__attribute__((packed)) cps_header_t; // 52B
|
||||
|
||||
/**
|
||||
* Create and return a viable channel for this radio.
|
||||
* Suitable for default VFO settings or the creation of a new channel.
|
||||
* Needs to be generated by a function frequency settings require details from the running hardware on limitations
|
||||
* Needs to be generated by a function frequency settings require details from
|
||||
* the running hardware on limitations.
|
||||
*/
|
||||
channel_t get_default_channel();
|
||||
channel_t cps_getDefaultChannel();
|
||||
|
||||
#endif
|
||||
#endif // CPS_H
|
||||
|
|
|
@ -20,13 +20,47 @@
|
|||
#ifndef GPS_H
|
||||
#define GPS_H
|
||||
|
||||
#include <state.h>
|
||||
#include <interfaces/rtc.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* Data structure representing a single satellite as part of a GPS fix.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t id; // ID of the satellite
|
||||
uint8_t elevation; // Elevation in degrees
|
||||
uint16_t azimuth; // Azimuth in degrees
|
||||
uint8_t snr; // Quality of the signal in range 0-99
|
||||
}
|
||||
sat_t;
|
||||
|
||||
/**
|
||||
* Data structure representing the last state received from the GPS module.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
curTime_t timestamp; // Timestamp of the latest GPS update
|
||||
uint8_t fix_quality; // 0: no fix, 1: GPS, 2: GPS SPS, 3: GPS PPS
|
||||
uint8_t fix_type; // 0: no fix, 1: 2D, 2: 3D
|
||||
uint8_t satellites_tracked; // Number of tracked satellites
|
||||
uint8_t satellites_in_view; // Satellites in view
|
||||
sat_t satellites[12]; // Details about satellites in view
|
||||
uint32_t active_sats; // Bitmap representing which sats are part of the fix
|
||||
float latitude; // Latitude coordinates
|
||||
float longitude; // Longitude coordinates
|
||||
float altitude; // Antenna altitude above mean sea level (geoid) in m
|
||||
float speed; // Ground speed in km/h
|
||||
float tmg_mag; // Course over ground, degrees, magnetic
|
||||
float tmg_true; // Course over ground, degrees, true
|
||||
}
|
||||
gps_t;
|
||||
|
||||
/**
|
||||
* This function perfoms the task of reading data from the GPS module,
|
||||
* if available, enabled and ready, decode NMEA sentences and update
|
||||
* the radio state with the retrieved data.
|
||||
*/
|
||||
void gps_taskFunc(char *line, int len, state_t *state);
|
||||
void gps_taskFunc(char *line, int len);
|
||||
|
||||
#endif /* GPS_H */
|
||||
|
|
|
@ -26,50 +26,18 @@
|
|||
#include <interfaces/rtc.h>
|
||||
#include <cps.h>
|
||||
#include <settings.h>
|
||||
|
||||
/**
|
||||
* Data structure representing a single satellite as part of a GPS fix.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
uint8_t id; // ID of the satellite
|
||||
uint8_t elevation; // Elevation in degrees
|
||||
uint16_t azimuth; // Azimuth in degrees
|
||||
uint8_t snr; // Quality of the signal in range 0-99
|
||||
}
|
||||
sat_t;
|
||||
|
||||
/**
|
||||
* Data structure representing the last state received from the GPS module.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
curTime_t timestamp; // Timestamp of the latest GPS update
|
||||
uint8_t fix_quality; // 0: no fix, 1: GPS, 2: GPS SPS, 3: GPS PPS
|
||||
uint8_t fix_type; // 0: no fix, 1: 2D, 2: 3D
|
||||
uint8_t satellites_tracked; // Number of tracked satellites
|
||||
uint8_t satellites_in_view; // Satellites in view
|
||||
sat_t satellites[12]; // Details about satellites in view
|
||||
uint32_t active_sats; // Bitmap representing which sats are part of the fix
|
||||
float latitude; // Latitude coordinates
|
||||
float longitude; // Longitude coordinates
|
||||
float altitude; // Antenna altitude above mean sea level (geoid) in m
|
||||
float speed; // Ground speed in km/h
|
||||
float tmg_mag; // Course over ground, degrees, magnetic
|
||||
float tmg_true; // Course over ground, degrees, true
|
||||
}
|
||||
gps_t;
|
||||
#include <gps.h>
|
||||
|
||||
/**
|
||||
* Data structure representing the settings of the M17 mode.
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
// char callsign[10];
|
||||
char dst_addr[10];
|
||||
}
|
||||
m17_t;
|
||||
|
||||
|
||||
/**
|
||||
* Part of this structure has been commented because the corresponding
|
||||
* functionality is not yet implemented.
|
||||
|
@ -85,12 +53,6 @@ typedef struct
|
|||
uint8_t ui_screen;
|
||||
uint8_t tuner_mode;
|
||||
|
||||
//time_t rx_status_tv;
|
||||
//bool rx_status;
|
||||
|
||||
//time_t tx_status_tv;
|
||||
//bool tx_status;
|
||||
|
||||
uint16_t channel_index;
|
||||
channel_t channel;
|
||||
channel_t vfo_channel;
|
||||
|
@ -130,12 +92,6 @@ extern state_t state;
|
|||
*/
|
||||
void state_init();
|
||||
|
||||
/**
|
||||
* Write default values to OpenRTX settings and VFO Channel configuration.
|
||||
* Writes out to flash and calls state_init again to reload it immediately.
|
||||
*/
|
||||
void defaultSettingsAndVfo();
|
||||
|
||||
/**
|
||||
* This function terminates the radio state saving persistent settings to flash.
|
||||
*/
|
||||
|
@ -146,6 +102,11 @@ void state_terminate();
|
|||
*/
|
||||
void state_update();
|
||||
|
||||
/**
|
||||
* Reset the fields of radio state containing user settings and VFO channel.
|
||||
*/
|
||||
void state_resetSettingsAndVfo();
|
||||
|
||||
/**
|
||||
* The RTC and state.time are set to UTC time
|
||||
* Use this function to get local time from UTC time based on timezone setting
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2020 by Federico Amedeo Izzo IU2NUO, *
|
||||
* Niccolò Izzo IU2KIN, *
|
||||
* Silvano Seva IU2KWO *
|
||||
* Copyright (C) 2020 - 2022 by Federico Amedeo Izzo IU2NUO, *
|
||||
* Niccolò Izzo IU2KIN, *
|
||||
* 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 *
|
||||
|
@ -32,6 +32,7 @@ extern "C" {
|
|||
* frequencies outside the calibration points. It works by searching the two
|
||||
* calibration points containing the target frequency and then by linearly
|
||||
* interpolating the calibration parameter among these two points.
|
||||
*
|
||||
* @param freq: target frequency for which a calibration value has to be
|
||||
* computed.
|
||||
* @param calPoints: pointer to the vector containing the frequencies of the
|
||||
|
@ -46,6 +47,15 @@ extern "C" {
|
|||
uint8_t interpCalParameter(const freq_t freq, const freq_t *calPoints,
|
||||
const uint8_t *param, const uint8_t elems);
|
||||
|
||||
/**
|
||||
* Convert from "OpenRTX dBm" to watt.
|
||||
* In OpenRTX cps power is stored as the coefficient n of the equation
|
||||
* P(dBm) = 10 + 2*0.2.
|
||||
*
|
||||
* @param n: coefficient of the dBm equation.
|
||||
* @return power in watt.
|
||||
*/
|
||||
float dBmToWatt(const uint8_t n);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
|
@ -1,8 +1,7 @@
|
|||
#include <interfaces/platform.h>
|
||||
#include <cps.h>
|
||||
|
||||
|
||||
channel_t get_default_channel()
|
||||
channel_t cps_getDefaultChannel()
|
||||
{
|
||||
channel_t channel;
|
||||
channel.mode = OPMODE_FM;
|
||||
|
|
|
@ -30,13 +30,15 @@
|
|||
/**
|
||||
* This function parses a GPS NMEA sentence and updates radio state
|
||||
*/
|
||||
void gps_taskFunc(char *line, __attribute__((unused)) int len, state_t *state)
|
||||
void gps_taskFunc(char *line, int len)
|
||||
{
|
||||
(void) len;
|
||||
|
||||
char nmea_id[3] = { 0 };
|
||||
|
||||
// Little mechanism to ensure that RTC is synced with GPS time only once.
|
||||
static bool isRtcSyncronised = false;
|
||||
if(!state->gps_set_time)
|
||||
if(!state.gps_set_time)
|
||||
{
|
||||
isRtcSyncronised = false;
|
||||
}
|
||||
|
@ -55,27 +57,27 @@ void gps_taskFunc(char *line, __attribute__((unused)) int len, state_t *state)
|
|||
struct minmea_sentence_rmc frame;
|
||||
if (minmea_parse_rmc(&frame, line))
|
||||
{
|
||||
state->gps_data.latitude = minmea_tocoord(&frame.latitude);
|
||||
state->gps_data.longitude = minmea_tocoord(&frame.longitude);
|
||||
state->gps_data.timestamp.hour = frame.time.hours;
|
||||
state->gps_data.timestamp.minute = frame.time.minutes;
|
||||
state->gps_data.timestamp.second = frame.time.seconds;
|
||||
state->gps_data.timestamp.day = 0;
|
||||
state->gps_data.timestamp.date = frame.date.day;
|
||||
state->gps_data.timestamp.month = frame.date.month;
|
||||
state->gps_data.timestamp.year = frame.date.year;
|
||||
state.gps_data.latitude = minmea_tocoord(&frame.latitude);
|
||||
state.gps_data.longitude = minmea_tocoord(&frame.longitude);
|
||||
state.gps_data.timestamp.hour = frame.time.hours;
|
||||
state.gps_data.timestamp.minute = frame.time.minutes;
|
||||
state.gps_data.timestamp.second = frame.time.seconds;
|
||||
state.gps_data.timestamp.day = 0;
|
||||
state.gps_data.timestamp.date = frame.date.day;
|
||||
state.gps_data.timestamp.month = frame.date.month;
|
||||
state.gps_data.timestamp.year = frame.date.year;
|
||||
}
|
||||
|
||||
// Synchronize RTC with GPS UTC clock, only when fix is done
|
||||
if((state->gps_set_time) &&
|
||||
(state->gps_data.fix_quality > 0) && (!isRtcSyncronised))
|
||||
if((state.gps_set_time) &&
|
||||
(state.gps_data.fix_quality > 0) && (!isRtcSyncronised))
|
||||
{
|
||||
rtc_setTime(state->gps_data.timestamp);
|
||||
rtc_setTime(state.gps_data.timestamp);
|
||||
isRtcSyncronised = true;
|
||||
}
|
||||
|
||||
state->gps_data.tmg_true = minmea_tofloat(&frame.course);
|
||||
state->gps_data.speed = minmea_tofloat(&frame.speed) * KNOTS2KMH;
|
||||
state.gps_data.tmg_true = minmea_tofloat(&frame.course);
|
||||
state.gps_data.speed = minmea_tofloat(&frame.speed) * KNOTS2KMH;
|
||||
} break;
|
||||
|
||||
case MINMEA_SENTENCE_GGA:
|
||||
|
@ -83,24 +85,24 @@ void gps_taskFunc(char *line, __attribute__((unused)) int len, state_t *state)
|
|||
struct minmea_sentence_gga frame;
|
||||
if (minmea_parse_gga(&frame, line))
|
||||
{
|
||||
state->gps_data.fix_quality = frame.fix_quality;
|
||||
state->gps_data.satellites_tracked = frame.satellites_tracked;
|
||||
state->gps_data.altitude = minmea_tofloat(&frame.altitude);
|
||||
state.gps_data.fix_quality = frame.fix_quality;
|
||||
state.gps_data.satellites_tracked = frame.satellites_tracked;
|
||||
state.gps_data.altitude = minmea_tofloat(&frame.altitude);
|
||||
}
|
||||
} break;
|
||||
|
||||
case MINMEA_SENTENCE_GSA:
|
||||
{
|
||||
state->gps_data.active_sats = 0;
|
||||
state.gps_data.active_sats = 0;
|
||||
struct minmea_sentence_gsa frame;
|
||||
if (minmea_parse_gsa(&frame, line))
|
||||
{
|
||||
state->gps_data.fix_type = frame.fix_type;
|
||||
state.gps_data.fix_type = frame.fix_type;
|
||||
for (int i = 0; i < 12; i++)
|
||||
{
|
||||
if (frame.sats[i] != 0)
|
||||
{
|
||||
state->gps_data.active_sats |= 1 << (frame.sats[i] - 1);
|
||||
state.gps_data.active_sats |= 1 << (frame.sats[i] - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -115,17 +117,17 @@ void gps_taskFunc(char *line, __attribute__((unused)) int len, state_t *state)
|
|||
// When the first sentence arrives, clear all the old data
|
||||
if (frame.msg_nr == 1)
|
||||
{
|
||||
bzero(&state->gps_data.satellites[0], 12 * sizeof(sat_t));
|
||||
bzero(&state.gps_data.satellites[0], 12 * sizeof(sat_t));
|
||||
}
|
||||
|
||||
state->gps_data.satellites_in_view = frame.total_sats;
|
||||
state.gps_data.satellites_in_view = frame.total_sats;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
int index = 4 * (frame.msg_nr - 1) + i;
|
||||
state->gps_data.satellites[index].id = frame.sats[i].nr;
|
||||
state->gps_data.satellites[index].elevation = frame.sats[i].elevation;
|
||||
state->gps_data.satellites[index].azimuth = frame.sats[i].azimuth;
|
||||
state->gps_data.satellites[index].snr = frame.sats[i].snr;
|
||||
state.gps_data.satellites[index].id = frame.sats[i].nr;
|
||||
state.gps_data.satellites[index].elevation = frame.sats[i].elevation;
|
||||
state.gps_data.satellites[index].azimuth = frame.sats[i].azimuth;
|
||||
state.gps_data.satellites[index].snr = frame.sats[i].snr;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
@ -135,9 +137,9 @@ void gps_taskFunc(char *line, __attribute__((unused)) int len, state_t *state)
|
|||
struct minmea_sentence_vtg frame;
|
||||
if (minmea_parse_vtg(&frame, line))
|
||||
{
|
||||
state->gps_data.speed = minmea_tofloat(&frame.speed_kph);
|
||||
state->gps_data.tmg_mag = minmea_tofloat(&frame.magnetic_track_degrees);
|
||||
state->gps_data.tmg_true = minmea_tofloat(&frame.true_track_degrees);
|
||||
state.gps_data.speed = minmea_tofloat(&frame.speed_kph);
|
||||
state.gps_data.tmg_mag = minmea_tofloat(&frame.magnetic_track_degrees);
|
||||
state.gps_data.tmg_true = minmea_tofloat(&frame.true_track_degrees);
|
||||
}
|
||||
} break;
|
||||
|
||||
|
|
|
@ -25,22 +25,10 @@
|
|||
#include <hwconfig.h>
|
||||
#include <interfaces/platform.h>
|
||||
#include <interfaces/nvmem.h>
|
||||
|
||||
#include <cps.h>
|
||||
|
||||
state_t state;
|
||||
|
||||
void defaultSettingsAndVfo()
|
||||
{
|
||||
|
||||
//don't need to lock state mutex because this is called from a section
|
||||
//that already does that - ui_updatefsm runs in a critical section in
|
||||
//the ui thread
|
||||
channel_t default_vfo = get_default_channel();
|
||||
nvm_writeSettingsAndVfo( &default_settings, &default_vfo );
|
||||
state_init();
|
||||
}
|
||||
|
||||
void state_init()
|
||||
{
|
||||
/*
|
||||
|
@ -59,7 +47,7 @@ void state_init()
|
|||
*/
|
||||
if(nvm_readVFOChannelData(&state.channel) < 0)
|
||||
{
|
||||
state.channel = get_default_channel();
|
||||
state.channel = cps_getDefaultChannel();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -114,6 +102,12 @@ void state_update()
|
|||
#endif
|
||||
}
|
||||
|
||||
void state_resetSettingsAndVfo()
|
||||
{
|
||||
state.settings = default_settings;
|
||||
state.channel = cps_getDefaultChannel();
|
||||
}
|
||||
|
||||
curTime_t state_getLocalTime(curTime_t utc_time)
|
||||
{
|
||||
curTime_t local_time = utc_time;
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include <queue.h>
|
||||
#include <minmea.h>
|
||||
#include <string.h>
|
||||
#include <utils.h>
|
||||
#ifdef HAS_GPS
|
||||
#include <interfaces/gps.h>
|
||||
#include <gps.h>
|
||||
|
@ -92,20 +93,22 @@ void *ui_task(void *arg)
|
|||
// If synchronization needed take mutex and update RTX configuration
|
||||
if(sync_rtx)
|
||||
{
|
||||
float power = dBmToWatt(state.channel.power);
|
||||
|
||||
pthread_mutex_lock(&rtx_mutex);
|
||||
rtx_cfg.opMode = state.channel.mode;
|
||||
rtx_cfg.bandwidth = state.channel.bandwidth;
|
||||
rtx_cfg.opMode = state.channel.mode;
|
||||
rtx_cfg.bandwidth = state.channel.bandwidth;
|
||||
rtx_cfg.rxFrequency = state.channel.rx_frequency;
|
||||
rtx_cfg.txFrequency = state.channel.tx_frequency;
|
||||
rtx_cfg.txPower = state.channel.power;
|
||||
rtx_cfg.sqlLevel = state.settings.sqlLevel;
|
||||
rtx_cfg.rxToneEn = state.channel.fm.rxToneEn;
|
||||
rtx_cfg.rxTone = ctcss_tone[state.channel.fm.rxTone];
|
||||
rtx_cfg.txToneEn = state.channel.fm.txToneEn;
|
||||
rtx_cfg.txTone = ctcss_tone[state.channel.fm.txTone];
|
||||
rtx_cfg.txPower = power;
|
||||
rtx_cfg.sqlLevel = state.settings.sqlLevel;
|
||||
rtx_cfg.rxToneEn = state.channel.fm.rxToneEn;
|
||||
rtx_cfg.rxTone = ctcss_tone[state.channel.fm.rxTone];
|
||||
rtx_cfg.txToneEn = state.channel.fm.txToneEn;
|
||||
rtx_cfg.txTone = ctcss_tone[state.channel.fm.txTone];
|
||||
|
||||
// Copy new M17 source and destination addresses
|
||||
strncpy(rtx_cfg.source_address, state.settings.callsign, 10);
|
||||
strncpy(rtx_cfg.source_address, state.settings.callsign, 10);
|
||||
strncpy(rtx_cfg.destination_address, state.m17_data.dst_addr, 10);
|
||||
|
||||
pthread_mutex_unlock(&rtx_mutex);
|
||||
|
@ -298,7 +301,7 @@ void *gps_task(void *arg)
|
|||
pthread_mutex_lock(&state_mutex);
|
||||
|
||||
// GPS readout is blocking, no need to delay here
|
||||
gps_taskFunc(line, len, &state);
|
||||
gps_taskFunc(line, len);
|
||||
|
||||
// Unlock state mutex
|
||||
pthread_mutex_unlock(&state_mutex);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2020 by Federico Amedeo Izzo IU2NUO, *
|
||||
* Niccolò Izzo IU2KIN, *
|
||||
* Silvano Seva IU2KWO *
|
||||
* Copyright (C) 2020 - 2022 by Federico Amedeo Izzo IU2NUO, *
|
||||
* Niccolò Izzo IU2KIN, *
|
||||
* 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 *
|
||||
|
@ -17,7 +17,8 @@
|
|||
* along with this program; if not, see <http://www.gnu.org/licenses/> *
|
||||
***************************************************************************/
|
||||
|
||||
#include <calibUtils.h>
|
||||
#include <utils.h>
|
||||
#include <math.h>
|
||||
|
||||
uint8_t interpCalParameter(const freq_t freq, const freq_t *calPoints,
|
||||
const uint8_t *param, const uint8_t elems)
|
||||
|
@ -49,3 +50,11 @@ uint8_t interpCalParameter(const freq_t freq, const freq_t *calPoints,
|
|||
|
||||
return interpValue;
|
||||
}
|
||||
|
||||
float dBmToWatt(const uint8_t n)
|
||||
{
|
||||
float dBm = 10.0f + ((float) n) * 0.2f;
|
||||
float power = pow(10.0f, (dBm - 30.0f)/10.0f);
|
||||
|
||||
return power;
|
||||
}
|
|
@ -764,10 +764,10 @@ void _ui_fsm_menuMacro(kbd_msg_t msg, bool *sync_rtx)
|
|||
}
|
||||
break;
|
||||
case 3:
|
||||
if (state.channel.power == 1.0f)
|
||||
state.channel.power = 5.0f;
|
||||
if (state.channel.power == 100)
|
||||
state.channel.power = 135;
|
||||
else
|
||||
state.channel.power = 1.0f;
|
||||
state.channel.power = 100;
|
||||
*sync_rtx = true;
|
||||
break;
|
||||
case 4:
|
||||
|
@ -1644,7 +1644,7 @@ void ui_updateFSM(event_t event, bool *sync_rtx)
|
|||
if(msg.keys & KEY_ENTER)
|
||||
{
|
||||
ui_state.edit_mode = false;
|
||||
defaultSettingsAndVfo();
|
||||
state_resetSettingsAndVfo();
|
||||
_ui_menuBack(MENU_SETTINGS);
|
||||
}
|
||||
else if(msg.keys & KEY_ESC)
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <backup.h>
|
||||
#include <utils.h>
|
||||
#include <ui.h>
|
||||
#include <interfaces/nvmem.h>
|
||||
#include <interfaces/cps_io.h>
|
||||
|
@ -718,7 +719,7 @@ bool _ui_drawMacroMenu()
|
|||
gfx_print(layout.line1_pos, layout.top_font, TEXT_ALIGN_RIGHT,
|
||||
yellow_fab413, "3 ");
|
||||
gfx_print(layout.line1_pos, layout.top_font, TEXT_ALIGN_RIGHT,
|
||||
color_white, "%.1gW", last_state.channel.power);
|
||||
color_white, "%.1gW", dBmToWatt(last_state.channel.power));
|
||||
// Second row
|
||||
// Calculate symmetric second row position, line2_pos is asymmetric like main screen
|
||||
point_t pos_2 = {layout.line1_pos.x, layout.line1_pos.y +
|
||||
|
|
|
@ -183,6 +183,8 @@ void nvm_loadHwInfo(hwInfo_t *info)
|
|||
|
||||
int nvm_readVFOChannelData(channel_t *channel)
|
||||
{
|
||||
memset(channel, 0x00, sizeof(channel_t));
|
||||
|
||||
gdxChannel_t chData;
|
||||
|
||||
AT24Cx_readData(vfoChannelBaseAddr, ((uint8_t *) &chData), sizeof(gdxChannel_t));
|
||||
|
@ -190,17 +192,10 @@ int nvm_readVFOChannelData(channel_t *channel)
|
|||
// 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->power = ((chData.power == 1) ? 135 : 100);
|
||||
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));
|
||||
// Terminate string with 0x00 instead of 0xFF
|
||||
|
@ -258,6 +253,8 @@ int cps_readChannelData(channel_t *channel, uint16_t pos)
|
|||
if((pos <= 0) || (pos > maxNumChannels))
|
||||
return -1;
|
||||
|
||||
memset(channel, 0x00, sizeof(channel_t));
|
||||
|
||||
// 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 bank contains index 0
|
||||
|
@ -310,16 +307,10 @@ int cps_readChannelData(channel_t *channel, uint16_t pos)
|
|||
// 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->power = ((chData.power == 1) ? 135 : 100);
|
||||
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));
|
||||
|
@ -427,11 +418,17 @@ int cps_readContactData(contact_t *contact, uint16_t pos)
|
|||
memcpy(contact->name, contactData.name, sizeof(contactData.name));
|
||||
// Terminate string with 0x00 instead of 0xFF
|
||||
_addStringTerminator(contact->name, sizeof(contactData.name));
|
||||
|
||||
contact->mode = DMR;
|
||||
|
||||
// Copy contact DMR ID
|
||||
contact->id = (contactData.id[0] | contactData.id[1] << 8 | contactData.id[2] << 16);
|
||||
contact->info.dmr.id = contactData.id[0]
|
||||
| (contactData.id[1] << 8)
|
||||
| (contactData.id[2] << 16);
|
||||
|
||||
// Copy contact details
|
||||
contact->type = contactData.type;
|
||||
contact->receive_tone = contactData.receive_tone ? true : false;
|
||||
contact->info.dmr.contactType = contactData.type;
|
||||
contact->info.dmr.rx_tone = contactData.receive_tone ? true : false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <interfaces/nvmem.h>
|
||||
#include <interfaces/delays.h>
|
||||
#include <calibInfo_MDx.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
#include "nvmData_MD3x0.h"
|
||||
#include "W25Qx.h"
|
||||
|
@ -171,6 +172,8 @@ int cps_readChannelData(channel_t *channel, uint16_t pos)
|
|||
{
|
||||
if((pos <= 0) || (pos > maxNumChannels)) return -1;
|
||||
|
||||
memset(channel, 0x00, sizeof(channel_t));
|
||||
|
||||
W25Qx_wakeup();
|
||||
delayUs(5);
|
||||
|
||||
|
@ -182,16 +185,10 @@ int cps_readChannelData(channel_t *channel, uint16_t pos)
|
|||
|
||||
channel->mode = chData.channel_mode;
|
||||
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->power = ((chData.power == 1) ? 135 : 100);
|
||||
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;
|
||||
|
||||
|
@ -309,11 +306,17 @@ int cps_readContactData(contact_t *contact, uint16_t pos)
|
|||
{
|
||||
contact->name[i] = ((char) (contactData.name[i] & 0x00FF));
|
||||
}
|
||||
|
||||
contact->mode = DMR;
|
||||
|
||||
// Copy contact DMR ID
|
||||
contact->id = (contactData.id[0] | contactData.id[1] << 8 | contactData.id[2] << 16);
|
||||
contact->info.dmr.id = contactData.id[0]
|
||||
| (contactData.id[1] << 8)
|
||||
| (contactData.id[2] << 16);
|
||||
|
||||
// Copy contact details
|
||||
contact->type = contactData.type;
|
||||
contact->receive_tone = contactData.receive_tone ? true : false;
|
||||
contact->info.dmr.contactType = contactData.type;
|
||||
contact->info.dmr.rx_tone = contactData.receive_tone ? true : false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -26,14 +26,14 @@
|
|||
#include "nvmData_MDUV3x0.h"
|
||||
#include "W25Qx.h"
|
||||
|
||||
const uint32_t zoneBaseAddr = 0x149E0; /**< Base address of zones */
|
||||
const uint32_t zoneExtBaseAddr = 0x31000; /**< Base address of zone extensions */
|
||||
const uint32_t vfoChannelBaseAddr = 0x2EF00; /**< Base address of VFO channel */
|
||||
const uint32_t chDataBaseAddr = 0x110000; /**< Base address of channel data */
|
||||
const uint32_t contactBaseAddr = 0x140000; /**< Base address of contacts */
|
||||
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 */
|
||||
const uint32_t maxNumContacts = 10000; /**< Maximum number of contacts in memory */
|
||||
const uint32_t zoneBaseAddr = 0x149E0; /**< Base address of zones */
|
||||
const uint32_t zoneExtBaseAddr = 0x31000; /**< Base address of zone extensions */
|
||||
const uint32_t vfoChannelBaseAddr = 0x2EF00; /**< Base address of VFO channel */
|
||||
const uint32_t chDataBaseAddr = 0x110000; /**< Base address of channel data */
|
||||
const uint32_t contactBaseAddr = 0x140000; /**< Base address of contacts */
|
||||
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 */
|
||||
const uint32_t maxNumContacts = 10000; /**< Maximum number of contacts in memory */
|
||||
/* This address has been chosen by OpenRTX to store the settings
|
||||
* because it is empty (0xFF) and has enough free space */
|
||||
const uint32_t settingsAddr = 0x6000;
|
||||
|
@ -71,29 +71,23 @@ int _cps_readChannelAtAddress(channel_t *channel, uint32_t addr)
|
|||
|
||||
channel->mode = chData.channel_mode;
|
||||
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->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;
|
||||
|
||||
if(chData.power == 3)
|
||||
{
|
||||
channel->power = 5.0f; /* High power -> 5W */
|
||||
channel->power = 135; /* High power -> 5W = 37dBm */
|
||||
}
|
||||
else if(chData.power == 2)
|
||||
{
|
||||
channel->power = 2.5f; /* Mid power -> 2.5W */
|
||||
channel->power = 120; /* Mid power -> 2.5W = 34dBm */
|
||||
}
|
||||
else
|
||||
{
|
||||
channel->power = 1.0f; /* Low power -> 1W */
|
||||
channel->power = 100; /* Low power -> 1W = 30dBm */
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -181,6 +175,8 @@ int cps_readChannelData(channel_t *channel, uint16_t pos)
|
|||
{
|
||||
if((pos <= 0) || (pos > maxNumChannels)) return -1;
|
||||
|
||||
memset(channel, 0x00, sizeof(channel_t));
|
||||
|
||||
// Note: pos is 1-based because an empty slot in a zone contains index 0
|
||||
uint32_t readAddr = chDataBaseAddr + (pos - 1) * sizeof(mduv3x0Channel_t);
|
||||
return _cps_readChannelAtAddress(channel, readAddr);
|
||||
|
@ -250,11 +246,17 @@ int cps_readContactData(contact_t *contact, uint16_t pos)
|
|||
{
|
||||
contact->name[i] = ((char) (contactData.name[i] & 0x00FF));
|
||||
}
|
||||
|
||||
contact->mode = DMR;
|
||||
|
||||
// Copy contact DMR ID
|
||||
contact->id = (contactData.id[0] | contactData.id[1] << 8 | contactData.id[2] << 16);
|
||||
contact->info.dmr.id = contactData.id[0]
|
||||
| (contactData.id[1] << 8)
|
||||
| (contactData.id[2] << 16);
|
||||
|
||||
// Copy contact details
|
||||
contact->type = contactData.type;
|
||||
contact->receive_tone = contactData.receive_tone ? true : false;
|
||||
contact->info.dmr.contactType = contactData.type;
|
||||
contact->info.dmr.rx_tone = contactData.receive_tone ? true : false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -26,14 +26,14 @@
|
|||
#include "nvmData_MDUV3x0.h"
|
||||
#include "W25Qx.h"
|
||||
|
||||
const uint32_t zoneBaseAddr = 0x149E0; /**< Base address of zones */
|
||||
const uint32_t zoneExtBaseAddr = 0x31000; /**< Base address of zone extensions */
|
||||
const uint32_t vfoChannelBaseAddr = 0x2EF00; /**< Base address of VFO channel */
|
||||
const uint32_t chDataBaseAddr = 0x110000; /**< Base address of channel data */
|
||||
const uint32_t contactBaseAddr = 0x140000; /**< Base address of contacts */
|
||||
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 */
|
||||
const uint32_t maxNumContacts = 10000; /**< Maximum number of contacts in memory */
|
||||
const uint32_t zoneBaseAddr = 0x149E0; /**< Base address of zones */
|
||||
const uint32_t zoneExtBaseAddr = 0x31000; /**< Base address of zone extensions */
|
||||
const uint32_t vfoChannelBaseAddr = 0x2EF00; /**< Base address of VFO channel */
|
||||
const uint32_t chDataBaseAddr = 0x110000; /**< Base address of channel data */
|
||||
const uint32_t contactBaseAddr = 0x140000; /**< Base address of contacts */
|
||||
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 */
|
||||
const uint32_t maxNumContacts = 10000; /**< Maximum number of contacts in memory */
|
||||
/* This address has been chosen by OpenRTX to store the settings
|
||||
* because it is empty (0xFF) and has enough free space */
|
||||
const uint32_t settingsAddr = 0x6000;
|
||||
|
@ -42,7 +42,7 @@ const uint32_t settingsAddr = 0x6000;
|
|||
* \internal Utility function to convert 4 byte BCD values into a 32-bit
|
||||
* unsigned integer ones.
|
||||
*/
|
||||
uint32_t _bcd2bin(uint32_t bcd)
|
||||
static uint32_t _bcd2bin(uint32_t bcd)
|
||||
{
|
||||
return ((bcd >> 28) & 0x0F) * 10000000 +
|
||||
((bcd >> 24) & 0x0F) * 1000000 +
|
||||
|
@ -57,7 +57,7 @@ uint32_t _bcd2bin(uint32_t bcd)
|
|||
/**
|
||||
* Used to read channel data from SPI flash into a channel_t struct
|
||||
*/
|
||||
int _cps_readChannelAtAddress(channel_t *channel, uint32_t addr)
|
||||
static int _cps_readChannelAtAddress(channel_t *channel, uint32_t addr)
|
||||
{
|
||||
W25Qx_wakeup();
|
||||
delayUs(5);
|
||||
|
@ -71,29 +71,23 @@ int _cps_readChannelAtAddress(channel_t *channel, uint32_t addr)
|
|||
|
||||
channel->mode = chData.channel_mode;
|
||||
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->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;
|
||||
|
||||
if(chData.power == 3)
|
||||
{
|
||||
channel->power = 5.0f; /* High power -> 5W */
|
||||
channel->power = 135; /* High power -> 5W = 37dBm */
|
||||
}
|
||||
else if(chData.power == 2)
|
||||
{
|
||||
channel->power = 2.5f; /* Mid power -> 2.5W */
|
||||
channel->power = 120; /* Mid power -> 2.5W = 34dBm */
|
||||
}
|
||||
else
|
||||
{
|
||||
channel->power = 1.0f; /* Low power -> 1W */
|
||||
channel->power = 100; /* Low power -> 1W = 30dBm */
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -281,6 +275,8 @@ int cps_readChannelData(channel_t *channel, uint16_t pos)
|
|||
{
|
||||
if((pos <= 0) || (pos > maxNumChannels)) return -1;
|
||||
|
||||
memset(channel, 0x00, sizeof(channel_t));
|
||||
|
||||
// Note: pos is 1-based because an empty slot in a zone contains index 0
|
||||
uint32_t readAddr = chDataBaseAddr + (pos - 1) * sizeof(mduv3x0Channel_t);
|
||||
return _cps_readChannelAtAddress(channel, readAddr);
|
||||
|
@ -350,11 +346,17 @@ int cps_readContactData(contact_t *contact, uint16_t pos)
|
|||
{
|
||||
contact->name[i] = ((char) (contactData.name[i] & 0x00FF));
|
||||
}
|
||||
|
||||
contact->mode = DMR;
|
||||
|
||||
// Copy contact DMR ID
|
||||
contact->id = (contactData.id[0] | contactData.id[1] << 8 | contactData.id[2] << 16);
|
||||
contact->info.dmr.id = contactData.id[0]
|
||||
| (contactData.id[1] << 8)
|
||||
| (contactData.id[2] << 16);
|
||||
|
||||
// Copy contact details
|
||||
contact->type = contactData.type;
|
||||
contact->receive_tone = contactData.receive_tone ? true : false;
|
||||
contact->info.dmr.contactType = contactData.type;
|
||||
contact->info.dmr.rx_tone = contactData.receive_tone ? true : false;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@ typedef struct
|
|||
}
|
||||
__attribute__((packed)) memory_t;
|
||||
|
||||
static const uint32_t validMagic = 0x5854504F; // "OPTX"
|
||||
static const uint32_t validMagic = 0x584E504F; // "OPNX"
|
||||
static const uint32_t baseAddress = 0x080E0000;
|
||||
memory_t *memory = ((memory_t *) baseAddress);
|
||||
|
||||
|
|
|
@ -22,9 +22,9 @@
|
|||
#include <interfaces/radio.h>
|
||||
#include <interfaces/gpio.h>
|
||||
#include <calibInfo_GDx.h>
|
||||
#include <calibUtils.h>
|
||||
#include <hwconfig.h>
|
||||
#include <algorithm>
|
||||
#include <utils.h>
|
||||
#include "radioUtils.h"
|
||||
#include "HR_C6000.h"
|
||||
#include "AT1846S.h"
|
||||
|
|
|
@ -23,10 +23,10 @@
|
|||
#include <interfaces/radio.h>
|
||||
#include <interfaces/gpio.h>
|
||||
#include <calibInfo_MDx.h>
|
||||
#include <calibUtils.h>
|
||||
#include <hwconfig.h>
|
||||
#include <ADC1_MDx.h>
|
||||
#include <algorithm>
|
||||
#include <utils.h>
|
||||
#include "HR_C5000.h"
|
||||
#include "SKY72310.h"
|
||||
|
||||
|
|
|
@ -22,9 +22,9 @@
|
|||
#include <interfaces/radio.h>
|
||||
#include <interfaces/gpio.h>
|
||||
#include <calibInfo_MDx.h>
|
||||
#include <calibUtils.h>
|
||||
#include <hwconfig.h>
|
||||
#include <algorithm>
|
||||
#include <utils.h>
|
||||
#include "radioUtils.h"
|
||||
#include "HR_C6000.h"
|
||||
#include "AT1846S.h"
|
||||
|
|
Ładowanie…
Reference in New Issue