kopia lustrzana https://github.com/OpenRTX/OpenRTX
Implemented RTX driver for GDx platform, by now only supporting RX
rodzic
8afa1d700e
commit
72220c377e
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue