kopia lustrzana https://github.com/OpenRTX/OpenRTX
Initial implementation of rtx driver for TYT MD-380 radio, by now supporting only analog FM reception
rodzic
17376b819a
commit
55b182406d
|
@ -11,7 +11,6 @@ project('OpenRTX', 'c',
|
|||
|
||||
## OpenRTX
|
||||
|
||||
|
||||
openrtx_src = ['openrtx/src/bootstrap.c',
|
||||
'openrtx/src/state.c',
|
||||
'openrtx/src/ui.c',
|
||||
|
@ -32,6 +31,8 @@ openrtx_inc = ['openrtx/include/interfaces',
|
|||
'platform/drivers/NVM',
|
||||
'platform/drivers/tones',
|
||||
'openrtx/include/fonts/adafruit']
|
||||
'platform/drivers/tones',
|
||||
'platform/drivers/baseband']
|
||||
|
||||
## RTOS
|
||||
rtos_src = ['rtos/uC-OS3/Source/__dbg_uCOS-III.c',
|
||||
|
@ -174,6 +175,8 @@ md380_src = src + stm32f405_src + ['platform/drivers/display/HX83XX_MDx.c',
|
|||
'platform/drivers/NVM/extFlash_MDx.c',
|
||||
'platform/drivers/NVM/nvmem_MD3x0.c',
|
||||
'platform/drivers/tones/toneGenerator_MDx.c',
|
||||
'platform/drivers/baseband/pll_MD3x0.c',
|
||||
'platform/drivers/baseband/rtx_MD3x0.c',
|
||||
'platform/targets/MD-380/platform.c',
|
||||
'openrtx/src/graphics/graphics_rgb565.c']
|
||||
|
||||
|
|
|
@ -22,23 +22,23 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* \brief CTCSS and DCS type definition.
|
||||
*
|
||||
* Continuous Tone Controlled Squelch System (CTCSS)
|
||||
* sub-audible tone frequency are expressed in \em tenth of Hz.
|
||||
* For example, the subaudible tone of 88.5 Hz is represented within
|
||||
* Hamlib by 885.
|
||||
*
|
||||
* Digitally-Coded Squelch codes are simple direct integers.
|
||||
*/
|
||||
/**
|
||||
* \brief CTCSS and DCS type definition.
|
||||
*
|
||||
* Continuous Tone Controlled Squelch System (CTCSS)
|
||||
* sub-audible tone frequency are expressed in \em tenth of Hz.
|
||||
* For example, the subaudible tone of 88.5 Hz is represented within Hamlib by
|
||||
* 885.
|
||||
*
|
||||
* Digitally-Coded Squelch codes are simple direct integers.
|
||||
*/
|
||||
typedef unsigned int tone_t;
|
||||
|
||||
/**
|
||||
* \brief Frequency type,
|
||||
*
|
||||
* Frequency type unit in Hz, able to hold SHF frequencies.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Frequency type.
|
||||
*
|
||||
* Frequency type unit in Hz, able to hold SHF frequencies.
|
||||
*/
|
||||
typedef uint32_t freq_t;
|
||||
|
||||
#endif /* DATATYPES_H */
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
/***************************************************************************
|
||||
* 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/> *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef RTX_H
|
||||
#define RTX_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <datatypes.h>
|
||||
|
||||
enum funcmode
|
||||
{
|
||||
OFF,
|
||||
RX,
|
||||
TX
|
||||
};
|
||||
|
||||
enum tone
|
||||
{
|
||||
NONE,
|
||||
CTCSS_67_0,
|
||||
CTCSS_71_9,
|
||||
CTCSS_81_5
|
||||
};
|
||||
|
||||
enum bw
|
||||
{
|
||||
BW_12_5,
|
||||
BW_25
|
||||
};
|
||||
|
||||
enum opmode
|
||||
{
|
||||
FM,
|
||||
DMR
|
||||
};
|
||||
|
||||
void rtx_init();
|
||||
|
||||
void rtx_terminate();
|
||||
|
||||
void rtx_setTxFreq(freq_t freq);
|
||||
|
||||
void rtx_setRxFreq(freq_t freq);
|
||||
|
||||
void rtx_setFuncmode(enum funcmode mode);
|
||||
|
||||
void rtx_setToneRx(enum tone t);
|
||||
|
||||
void rtx_setToneTx(enum tone t);
|
||||
|
||||
void rtx_setBandwidth(enum bw b);
|
||||
|
||||
float rtx_getRssi();
|
||||
|
||||
void rtx_setOpmode(enum opmode mode);
|
||||
|
||||
#endif /* RTX_H */
|
|
@ -0,0 +1,111 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2020 by Silvano Seva IU2KWO and Niccolò Izzo IU2KIN *
|
||||
* *
|
||||
* 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/> *
|
||||
***************************************************************************/
|
||||
|
||||
#include "pll_MD3x0.h"
|
||||
#include <math.h>
|
||||
#include "gpio.h"
|
||||
#include "delays.h"
|
||||
#include "hwconfig.h"
|
||||
|
||||
#define REF_CLK 16800000.0F /* Reference clock: 16.8MHz */
|
||||
#define PHD_GAIN 0x1F /* Phase detector gain: hex value, max 0x1F */
|
||||
|
||||
void _spiSend(uint16_t value)
|
||||
{
|
||||
uint16_t temp = value;
|
||||
|
||||
gpio_clearPin(PLL_CS);
|
||||
delayUs(10);
|
||||
|
||||
for(uint8_t i = 0; i < 16; i++)
|
||||
{
|
||||
gpio_setPin(PLL_CLK);
|
||||
delayUs(1);
|
||||
|
||||
if(temp & 0x8000)
|
||||
{
|
||||
gpio_setPin(PLL_DAT);
|
||||
}
|
||||
else
|
||||
{
|
||||
gpio_clearPin(PLL_DAT);
|
||||
}
|
||||
|
||||
temp <<= 1;
|
||||
|
||||
delayUs(1);
|
||||
gpio_clearPin(PLL_CLK);
|
||||
delayUs(1);
|
||||
}
|
||||
|
||||
gpio_setPin(PLL_CLK);
|
||||
|
||||
delayUs(10);
|
||||
gpio_setPin(PLL_CS);
|
||||
}
|
||||
|
||||
void pll_init()
|
||||
{
|
||||
gpio_setMode(PLL_CLK, OUTPUT);
|
||||
gpio_setMode(PLL_DAT, OUTPUT);
|
||||
gpio_setMode(PLL_CS, OUTPUT);
|
||||
gpio_setPin(PLL_CS);
|
||||
gpio_setMode(PLL_LD, INPUT);
|
||||
|
||||
_spiSend(0x6000 | ((uint16_t) PHD_GAIN)); /* Phase detector gain */
|
||||
_spiSend(0x73D0); /* Power down/multiplexer control register */
|
||||
_spiSend(0x8000); /* Modulation control register */
|
||||
_spiSend(0x9000); /* Modulation data register */
|
||||
}
|
||||
|
||||
void pll_terminate()
|
||||
{
|
||||
gpio_setMode(PLL_CLK, INPUT);
|
||||
gpio_setMode(PLL_DAT, INPUT);
|
||||
gpio_setMode(PLL_CS, INPUT);
|
||||
}
|
||||
|
||||
void pll_setFrequency(float freq, uint8_t clkDiv)
|
||||
{
|
||||
/* Maximum allowable value for reference clock divider is 32 */
|
||||
if (clkDiv > 32) clkDiv = 32;
|
||||
|
||||
float K = freq/(REF_CLK/((float) clkDiv));
|
||||
float Ndiv = floor(K) - 32.0;
|
||||
float Ndnd = round(262144*(K - Ndiv - 32.0));
|
||||
|
||||
uint32_t dnd = ((uint32_t) Ndnd);
|
||||
uint16_t dndMsb = dnd >> 8;
|
||||
uint16_t dndLsb = dnd & 0x00FF;
|
||||
|
||||
_spiSend((uint16_t) Ndiv); /* Divider register */
|
||||
_spiSend(0x2000 | dndLsb); /* Dividend LSB register */
|
||||
_spiSend(0x1000 | dndMsb); /* Dividend MSB register */
|
||||
_spiSend(0x5000 | ((uint16_t)clkDiv - 1)); /* Reference clock divider */
|
||||
}
|
||||
|
||||
bool pll_locked()
|
||||
{
|
||||
return (gpio_readPin(PLL_LD) == 1) ? true : false;
|
||||
}
|
||||
|
||||
bool pll_spiInUse()
|
||||
{
|
||||
/* If PLL chip select is low, SPI is being used by this driver. */
|
||||
return (gpio_readPin(PLL_CS) == 1) ? false : true;
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2020 by Silvano Seva IU2KWO and Niccolò Izzo IU2KIN *
|
||||
* *
|
||||
* 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/> *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef PLL_MD3x0_H
|
||||
#define PLL_MD3x0_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* Driver for PLL in MD3x0 radios (MD380 and MD380), which is SKY73210.
|
||||
*
|
||||
* WARNING: the PLL and DMR chips share the SPI MOSI line, thus particular care
|
||||
* has to be put to avoid them stomping reciprocally. This driver does not make
|
||||
* any check if a SPI transfer is already in progress, deferring the correct bus
|
||||
* management to higher level modules. However, a function returning true if the
|
||||
* bus is currently in use by this driver is provided.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Initialise the PLL.
|
||||
*/
|
||||
void pll_init();
|
||||
|
||||
/**
|
||||
* Terminate PLL driver, bringing GPIOs back to reset state.
|
||||
*/
|
||||
void pll_terminate();
|
||||
|
||||
/**
|
||||
* Change VCO frequency.
|
||||
* @param freq: new VCO frequency, in Hz.
|
||||
* @param clkDiv: reference clock division factor.
|
||||
*/
|
||||
void pll_setFrequency(float freq, uint8_t clkDiv);
|
||||
|
||||
/**
|
||||
* Check if PLL is locked.
|
||||
* @return true if PLL is locked.
|
||||
*/
|
||||
bool pll_locked();
|
||||
|
||||
/**
|
||||
* Check if the SPI bus in common between PLL and DMR chips is in use by this
|
||||
* driver.
|
||||
* @return true if this driver is using the SPI bus.
|
||||
*/
|
||||
bool pll_spiInUse();
|
||||
|
||||
#endif /* PLL_H */
|
|
@ -0,0 +1,194 @@
|
|||
/***************************************************************************
|
||||
* 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/> *
|
||||
***************************************************************************/
|
||||
|
||||
#include <hwconfig.h>
|
||||
#include <datatypes.h>
|
||||
#include <gpio.h>
|
||||
#include "rtx.h"
|
||||
#include "pll_MD3x0.h"
|
||||
#include "ADC1_MDxx380.h"
|
||||
|
||||
const freq_t IF_FREQ = 49950000.0f; /* Intermediate frequency: 49.95MHz */
|
||||
|
||||
freq_t rxFreq = 430000000.0f;
|
||||
freq_t txFreq = 430000000.0f;
|
||||
|
||||
void _setMod2Bias(uint16_t value)
|
||||
{
|
||||
DAC->DHR12R2 = value;
|
||||
}
|
||||
|
||||
void _setApcTv(uint16_t value)
|
||||
{
|
||||
DAC->DHR12R1 = value;
|
||||
}
|
||||
|
||||
void rtx_init()
|
||||
{
|
||||
/*
|
||||
* Configure GPIOs
|
||||
*/
|
||||
gpio_setMode(PLL_PWR, OUTPUT);
|
||||
gpio_setMode(VCOVCC_SW, OUTPUT);
|
||||
gpio_setMode(DMR_SW, OUTPUT);
|
||||
gpio_setMode(WN_SW, OUTPUT);
|
||||
gpio_setMode(FM_SW, OUTPUT);
|
||||
// gpio_setMode(V_CS, OUTPUT);
|
||||
gpio_setMode(RF_APC_SW, OUTPUT);
|
||||
gpio_setMode(TX_STG_EN, OUTPUT);
|
||||
gpio_setMode(RX_STG_EN, OUTPUT);
|
||||
|
||||
gpio_clearPin(PLL_PWR); /* PLL off */
|
||||
gpio_setPin(VCOVCC_SW); /* VCOVCC high enables RX VCO, TX VCO if low */
|
||||
gpio_clearPin(WN_SW); /* 25kHz band (?) */
|
||||
gpio_clearPin(DMR_SW); /* Disconnect HR_C5000 input IF signal and audio out */
|
||||
gpio_clearPin(FM_SW); /* Disconnect analog FM audio path */
|
||||
// gpio_setPin(V_CS);
|
||||
gpio_clearPin(RF_APC_SW); /* Disable RF power control */
|
||||
gpio_clearPin(TX_STG_EN); /* Disable TX power stage */
|
||||
gpio_clearPin(RX_STG_EN); /* Disable RX input stage */
|
||||
|
||||
/*
|
||||
* Configure and enble DAC
|
||||
*/
|
||||
gpio_setMode(APC_TV, INPUT_ANALOG);
|
||||
gpio_setMode(MOD2_BIAS, INPUT_ANALOG);
|
||||
|
||||
RCC->APB1ENR |= RCC_APB1ENR_DACEN;
|
||||
DAC->CR = DAC_CR_EN2 | DAC_CR_EN1;
|
||||
DAC->DHR12R2 = 0;
|
||||
DAC->DHR12R1 = 0;
|
||||
|
||||
/*
|
||||
* Enable and configure PLL
|
||||
*/
|
||||
gpio_setPin(PLL_PWR);
|
||||
pll_init();
|
||||
}
|
||||
|
||||
void rtx_terminate()
|
||||
{
|
||||
pll_terminate();
|
||||
|
||||
gpio_clearPin(PLL_PWR); /* PLL off */
|
||||
gpio_clearPin(DMR_SW); /* Disconnect HR_C5000 input IF signal and audio out */
|
||||
gpio_clearPin(FM_SW); /* Disconnect analog FM audio path */
|
||||
gpio_clearPin(RF_APC_SW); /* Disable RF power control */
|
||||
gpio_clearPin(TX_STG_EN); /* Disable TX power stage */
|
||||
gpio_clearPin(RX_STG_EN); /* Disable RX input stage */
|
||||
|
||||
DAC->DHR12R2 = 0;
|
||||
DAC->DHR12R1 = 0;
|
||||
RCC->APB1ENR &= ~RCC_APB1ENR_DACEN;
|
||||
}
|
||||
|
||||
void rtx_setTxFreq(freq_t freq)
|
||||
{
|
||||
txFreq = freq;
|
||||
}
|
||||
|
||||
void rtx_setRxFreq(freq_t freq)
|
||||
{
|
||||
rxFreq = freq;
|
||||
}
|
||||
|
||||
void rtx_setFuncmode(enum funcmode mode)
|
||||
{
|
||||
switch(mode)
|
||||
{
|
||||
case OFF:
|
||||
gpio_clearPin(TX_STG_EN);
|
||||
gpio_clearPin(RX_STG_EN);
|
||||
break;
|
||||
|
||||
case RX:
|
||||
gpio_clearPin(TX_STG_EN);
|
||||
|
||||
gpio_clearPin(RF_APC_SW);
|
||||
gpio_setPin(VCOVCC_SW);
|
||||
pll_setFrequency(rxFreq - IF_FREQ, 5);
|
||||
_setMod2Bias(0x3c0); /* TODO use calibration */
|
||||
_setApcTv(0x956); /* TODO use calibration */
|
||||
|
||||
gpio_setPin(RX_STG_EN);
|
||||
break;
|
||||
|
||||
case TX:
|
||||
/* TODO */
|
||||
break;
|
||||
|
||||
default:
|
||||
/* TODO */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void rtx_setToneRx(enum tone t)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void rtx_setToneTx(enum tone t)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
void rtx_setBandwidth(enum bw b)
|
||||
{
|
||||
switch(b)
|
||||
{
|
||||
case BW_25:
|
||||
gpio_clearPin(WN_SW);
|
||||
break;
|
||||
|
||||
case BW_12_5:
|
||||
gpio_setPin(WN_SW);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* TODO */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
float rtx_getRssi()
|
||||
{
|
||||
return adc1_getMeasurement(1);
|
||||
}
|
||||
|
||||
void rtx_setOpmode(enum opmode mode)
|
||||
{
|
||||
switch(mode)
|
||||
{
|
||||
case FM:
|
||||
gpio_clearPin(DMR_SW);
|
||||
gpio_setPin(FM_SW);
|
||||
break;
|
||||
|
||||
case DMR:
|
||||
gpio_clearPin(FM_SW);
|
||||
gpio_setPin(DMR_SW);
|
||||
break;
|
||||
|
||||
default:
|
||||
/* TODO */
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -87,4 +87,35 @@
|
|||
#define FLASH_SDO GPIOB,4
|
||||
#define FLASH_SDI GPIOB,5
|
||||
|
||||
/* PLL */
|
||||
#define PLL_CS GPIOD,11
|
||||
#define PLL_CLK GPIOE,4
|
||||
#define PLL_DAT GPIOE,5 /* WARNING: this line is also HR_C5000 MOSI */
|
||||
#define PLL_LD GPIOD,10
|
||||
|
||||
/* HR_C5000 */
|
||||
#define DMR_CS GPIOE,2
|
||||
#define DMR_CLK GPIOC,13
|
||||
#define DMR_MOSI PLL_DAT
|
||||
#define DMR_MISO GPIOE,3
|
||||
#define DMR_SLEEP GPIOE,6
|
||||
#define V_CS GPIOB,12
|
||||
|
||||
/* RTX control */
|
||||
#define PLL_PWR GPIOA,8
|
||||
#define VCOVCC_SW GPIOA,9
|
||||
#define DMR_SW GPIOA,10
|
||||
#define FM_SW GPIOB,2
|
||||
#define WN_SW GPIOA,13
|
||||
#define RF_APC_SW GPIOC,4
|
||||
#define TX_STG_EN GPIOC,5
|
||||
#define RX_STG_EN GPIOC,9
|
||||
#define APC_TV GPIOA,4
|
||||
#define MOD2_BIAS GPIOA,5
|
||||
|
||||
/* Audio control */
|
||||
#define AMP_EN GPIOB,9
|
||||
#define SPK_MUTE GPIOB,8
|
||||
#define FM_MUTE GPIOE,13
|
||||
|
||||
#endif
|
||||
|
|
Ładowanie…
Reference in New Issue