Implemented RTX driver for GDx platform, by now only supporting RX

replace/6e5291f1afa028b9cc292dbeca803800319302ca
Silvano Seva 2021-01-23 09:25:46 +01:00
rodzic 8afa1d700e
commit 72220c377e
3 zmienionych plików z 301 dodań i 9 usunięć

Wyświetl plik

@ -265,7 +265,7 @@ dm1801_src = src + mk22fn512_src + ['platform/targets/DM-1801/platform.c',
'platform/drivers/ADC/ADC0_GDx.c',
'platform/drivers/baseband/rtx_GDx.c',
'platform/drivers/baseband/AT1846S.c',
'platform/drivers/baseband/HR-C6000.c',
'platform/drivers/baseband/HR_C6000.c',
'platform/drivers/baseband/interfaces_GDx.c']
dm1801_inc = inc + mk22fn512_inc + ['platform/targets/DM-1801']
@ -428,7 +428,7 @@ targets = [
'flashable': true,
'wrap': 'UV3X0',
'load_addr': '0x0800C000'},
{'name': 'mduv380g',
'opts': mduv380g_opts,
'flashable': true,
@ -446,7 +446,7 @@ targets = [
'flashable': true,
'wrap': 'UV3X0',
'load_addr': '0x0800C000'},
{'name': 'md9600',
'opts': md9600_opts,
'flashable': true,

Wyświetl plik

@ -18,20 +18,212 @@
* along with this program; if not, see <http://www.gnu.org/licenses/> *
***************************************************************************/
#include <interfaces/platform.h>
#include <interfaces/gpio.h>
#include <interfaces/rtx.h>
#include <calibInfo_GDx.h>
#include <calibUtils.h>
#include <datatypes.h>
#include <hwconfig.h>
#include <interfaces/platform.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <interfaces/rtx.h>
#include <stdio.h>
#include "HR_C6000.h"
#include "AT1846S.h"
OS_MUTEX *cfgMutex; /* Mutex for incoming config messages */
OS_Q cfgMailbox; /* Queue for incoming config messages */
const gdxCalibration_t *calData; /* Pointer to calibration data */
rtxStatus_t rtxStatus; /* RTX driver status */
/*
* Helper functions to reduce code mess. They all access 'rtxStatus'
* internally.
*/
int8_t _getBandFromFrequency(freq_t freq)
{
if((freq >= FREQ_LIMIT_VHF_LO) && (freq <= FREQ_LIMIT_VHF_HI)) return 0;
if((freq >= FREQ_LIMIT_UHF_LO) && (freq <= FREQ_LIMIT_UHF_HI)) return 1;
return -1;
}
void _setBandwidth()
{
/* Override bandwidth configuration for digital modes */
uint8_t bandwidth = BW_12_5;
if(rtxStatus.opMode == FM) bandwidth = rtxStatus.bandwidth;
switch(bandwidth)
{
case BW_12_5:
AT1846S_setBandwidth(AT1846S_BW_12P5);
break;
case BW_20:
case BW_25:
AT1846S_setBandwidth(AT1846S_BW_25);
break;
default:
break;
}
}
void _setOpMode()
{
switch(rtxStatus.opMode)
{
case FM:
gpio_setPin(RX_AUDIO_MUX); /* Audio out to amplifier */
gpio_clearPin(TX_AUDIO_MUX); /* Audio in to microphone */
AT1846S_setOpMode(AT1846S_OP_FM);
break;
case DMR:
gpio_clearPin(RX_AUDIO_MUX); /* Audio out to HR_C6000 */
gpio_setPin(TX_AUDIO_MUX); /* Audio in from HR_C6000 */
AT1846S_setOpMode(AT1846S_OP_FM);
break;
default:
break;
}
}
void _setVcoFrequency()
{
freq_t freq = rtxStatus.rxFrequency;
if(rtxStatus.opStatus == TX) freq = rtxStatus.txFrequency;
AT1846S_setFrequency(freq);
}
void _enableTxStage()
{
if(rtxStatus.txDisable == 1) return;
gpio_clearPin(VHF_LNA_EN);
gpio_clearPin(UHF_LNA_EN);
gpio_clearPin(VHF_PA_EN);
gpio_clearPin(UHF_PA_EN);
int8_t band = _getBandFromFrequency(rtxStatus.txFrequency);
if(band < 0) return;
/*
* Set transmit power. Initial setting is 1W, overridden to 5W if tx power
* is greater than 1W.
* TODO: increase granularity
*/
// const uint8_t *paramPtr = calData->txLowPower;
// if(rtxStatus.txPower > 1.0f) paramPtr = calData->txHighPower;
// uint8_t apc = interpCalParameter(rtxStatus.txFrequency, calData->txFreq,
// paramPtr, 9);
// DAC->DHR12L1 = apc * 0xFF;
if(band == 0)
{
gpio_setPin(VHF_PA_EN);
}
else
{
gpio_setPin(UHF_PA_EN);
}
rtxStatus.opStatus = TX;
_setVcoFrequency();
AT1846S_setFuncMode(AT1846S_TX);
}
void _enableRxStage()
{
gpio_clearPin(VHF_LNA_EN);
gpio_clearPin(UHF_LNA_EN);
gpio_clearPin(VHF_PA_EN);
gpio_clearPin(UHF_PA_EN);
int8_t band = _getBandFromFrequency(rtxStatus.rxFrequency);
if(band < 0) return;
if(band == 0)
{
gpio_setPin(VHF_LNA_EN);
}
else
{
gpio_setPin(UHF_LNA_EN);
}
rtxStatus.opStatus = RX;
_setVcoFrequency();
AT1846S_setFuncMode(AT1846S_RX);
}
void _disableRtxStages()
{
gpio_clearPin(VHF_LNA_EN);
gpio_clearPin(UHF_LNA_EN);
gpio_clearPin(VHF_PA_EN);
gpio_clearPin(UHF_PA_EN);
AT1846S_setFuncMode(AT1846S_OFF);
rtxStatus.opStatus = OFF;
}
void _updateTuningParams()
{
int8_t band = _getBandFromFrequency(rtxStatus.rxFrequency);
if(band < 0) return;
const bandCalData_t *cal = &(calData->data[band]);
AT1846S_setPgaGain(cal->PGA_gain);
AT1846S_setMicGain(cal->analogMicGain);
AT1846S_setTxDeviation(cal->txDev_tone);
AT1846S_setAgcGain(cal->rxAGCgain);
AT1846S_setRxAudioGain(cal->rxAudioGainWideband, cal->rxAudioGainNarrowband);
AT1846S_setPaDrive(cal->PA_drv);
C6000_setDacRange(cal->dacDataRange);
C6000_setMod2Bias(cal->mod2Offset);
C6000_setModOffset(cal->mod1Bias);
uint8_t mod1Amp = 0;
uint8_t sqlTresh = 0;
if(band == 0)
{
/* VHF band */
mod1Amp = interpCalParameter(rtxStatus.txFrequency, calData->vhfCalPoints,
cal->mod1Amplitude, 8);
sqlTresh = interpCalParameter(rtxStatus.rxFrequency, calData->vhfCalPoints,
cal->analogSqlThresh, 8);
}
else
{
/* UHF band */
mod1Amp = interpCalParameter(rtxStatus.txFrequency, calData->uhfMod1CalPoints,
cal->mod1Amplitude, 8);
sqlTresh = interpCalParameter(rtxStatus.rxFrequency, calData->uhfMod1CalPoints,
cal->analogSqlThresh, 8);
}
C6000_setMod1Amplitude(mod1Amp);
AT1846S_setAnalogSqlThresh(sqlTresh);
}
void _setCTCSS()
{
/* TODO */
}
void _updateSqlThresholds()
{
/* TODO */
}
void rtx_init(OS_MUTEX *m)
{
/* Initialise mutex for configuration access */
@ -44,6 +236,41 @@ void rtx_init(OS_MUTEX *m)
(OS_MSG_QTY) 1,
(OS_ERR *) &err);
/*
* Configure RTX GPIOs
*/
gpio_setMode(VHF_LNA_EN, OUTPUT);
gpio_setMode(UHF_LNA_EN, OUTPUT);
gpio_setMode(VHF_PA_EN, OUTPUT);
gpio_setMode(UHF_PA_EN, OUTPUT);
gpio_clearPin(VHF_LNA_EN); /* Turn VHF LNA off */
gpio_clearPin(UHF_LNA_EN); /* Turn UHF LNA off */
gpio_clearPin(VHF_PA_EN); /* Turn VHF PA off */
gpio_clearPin(UHF_PA_EN); /* Turn UHF PA off */
/*
* Configure audio control GPIOs
*/
gpio_setMode(AUDIO_AMP_EN, OUTPUT);
gpio_setMode(RX_AUDIO_MUX, OUTPUT);
gpio_setMode(TX_AUDIO_MUX, OUTPUT);
gpio_clearPin(AUDIO_AMP_EN);
gpio_clearPin(RX_AUDIO_MUX);
gpio_clearPin(TX_AUDIO_MUX);
/*
* Load calibration data
*/
calData = ((const gdxCalibration_t *) platform_getCalibrationData());
/*
* Enable and configure both AT1846S and HR_C6000
*/
AT1846S_init();
C6000_init();
/*
* Default initialisation for rtx status
*/
@ -55,12 +282,17 @@ void rtx_init(OS_MUTEX *m)
rtxStatus.txFrequency = 430000000;
rtxStatus.txPower = 0.0f;
rtxStatus.sqlLevel = 1;
rtxStatus.rxToneEn = 0;
rtxStatus.rxTone = 0;
rtxStatus.txToneEn = 0;
rtxStatus.txTone = 0;
}
void rtx_terminate()
{
_disableRtxStages();
gpio_clearPin(AUDIO_AMP_EN);
C6000_terminate();
}
void rtx_configure(const rtxStatus_t *cfg)
@ -119,13 +351,58 @@ void rtx_taskFunc()
/* Done, release mutex */
OSMutexPost(cfgMutex, OS_OPT_POST_NONE, &err);
/* Update HW configuration */
_setOpMode();
_setBandwidth();
_updateTuningParams();
_setCTCSS();
_updateSqlThresholds();
_setVcoFrequency();
/* TODO: temporarily force to RX mode if rtx is off. */
if(rtxStatus.opStatus == OFF) _enableRxStage();
}
}
if(rtxStatus.opStatus == RX)
{
float sqlLevel = (rtx_getRssi() + 127.0f)/6.0f;
float sqlThresh = 7.0f;
if(rtxStatus.sqlLevel > 0) sqlThresh = 3.0f;
if((gpio_readPin(AUDIO_AMP_EN) == 0) && (sqlLevel > (sqlThresh + 0.1f)))
{
gpio_setPin(AUDIO_AMP_EN);
platform_ledOn(GREEN);
}
// Do nothing since this is a stub
if((gpio_readPin(AUDIO_AMP_EN) == 1) && (sqlLevel < sqlThresh))
{
gpio_clearPin(AUDIO_AMP_EN);
platform_ledOff(GREEN);
}
}
// if(platform_getPttStatus() && (rtxStatus.opStatus != TX))
// {
// _disableRtxStages();
// _enableTxStage();
// platform_ledOn(RED);
// }
//
// if(!platform_getPttStatus() && (rtxStatus.opStatus == TX))
// {
// _disableRtxStages();
// _enableRxStage();
// platform_ledOff(RED);
// }
}
float rtx_getRssi()
{
return 0.0;
uint16_t val = AT1846S_readRSSI();
int8_t rssi = -151 + (val >> 8);
return ((float) rssi);
}

Wyświetl plik

@ -19,8 +19,10 @@
***************************************************************************/
#include <interfaces/platform.h>
#include <ADC0_GDx.h>
#include <interfaces/nvmem.h>
#include <interfaces/gpio.h>
#include <calibInfo_GDx.h>
#include <ADC0_GDx.h>
#include <I2C0.h>
#include <os.h>
#include "hwconfig.h"
@ -29,6 +31,8 @@
OS_MUTEX adc_mutex;
OS_ERR e;
gdxCalibration_t calibration;
void platform_init()
{
/* Configure GPIOs */
@ -70,6 +74,12 @@ void platform_init()
gpio_setAlternateFunction(I2C_SDA, 3);
gpio_setAlternateFunction(I2C_SCL, 3);
i2c0_init();
/*
* Initialise non volatile memory manager and load calibration data.
*/
nvm_init();
nvm_readCalibData(&calibration);
}
void platform_terminate()
@ -169,3 +179,8 @@ void platform_setBacklightLevel(uint8_t level)
{
FTM0->CONTROLS[3].CnV = level;
}
const void *platform_getCalibrationData()
{
return ((const void *) &calibration);
}