mirror of
https://github.com/g4klx/MMDVM_HS.git
synced 2026-01-05 00:00:25 +01:00
Adding RSSI support for ADF7021, and RSSI for DStar and DMR
This commit is contained in:
parent
d1976f1049
commit
7d40e245bd
118
ADF7021.cpp
118
ADF7021.cpp
|
|
@ -29,32 +29,106 @@
|
|||
#include "ADF7021.h"
|
||||
#include <math.h>
|
||||
|
||||
volatile uint32_t AD7021_control_byte;
|
||||
volatile int AD7021_counter;
|
||||
volatile uint32_t AD7021_control_word;
|
||||
|
||||
uint32_t ADF7021_RX_REG0;
|
||||
uint32_t ADF7021_TX_REG0;
|
||||
|
||||
void Send_AD7021_control()
|
||||
{
|
||||
int AD7021_counter;
|
||||
|
||||
for(AD7021_counter = 31; AD7021_counter >= 0; AD7021_counter--) {
|
||||
if(bitRead(AD7021_control_byte, AD7021_counter) == HIGH)
|
||||
io.SDATA_pin(HIGH);
|
||||
if(bitRead(AD7021_control_word, AD7021_counter) == HIGH)
|
||||
io.SDATA_pin(HIGH);
|
||||
else
|
||||
io.SDATA_pin(LOW);
|
||||
|
||||
|
||||
io.dlybit();
|
||||
io.SCLK_pin(HIGH);
|
||||
io.dlybit();
|
||||
io.SCLK_pin(LOW);
|
||||
}
|
||||
|
||||
|
||||
io.SLE_pin(HIGH);
|
||||
io.dlybit();
|
||||
io.SLE_pin(LOW);
|
||||
io.SLE_pin(LOW);
|
||||
io.SDATA_pin(LOW);
|
||||
}
|
||||
|
||||
#if defined(SEND_RSSI_DATA)
|
||||
uint16_t CIO::readRSSI()
|
||||
{
|
||||
uint32_t AD7021_RB;
|
||||
uint16_t RB_word = 0;
|
||||
int AD7021_counter;
|
||||
uint8_t RB_code, gain_code, gain_corr;
|
||||
|
||||
// Register 7, readback enable, ADC RSSI mode
|
||||
AD7021_RB = 0x0147;
|
||||
|
||||
// Send control register
|
||||
for(AD7021_counter = 8; AD7021_counter >= 0; AD7021_counter--) {
|
||||
if(bitRead(AD7021_RB, AD7021_counter) == HIGH)
|
||||
SDATA_pin(HIGH);
|
||||
else
|
||||
SDATA_pin(LOW);
|
||||
|
||||
dlybit();
|
||||
SCLK_pin(HIGH);
|
||||
dlybit();
|
||||
SCLK_pin(LOW);
|
||||
}
|
||||
|
||||
SDATA_pin(LOW);
|
||||
SLE_pin(HIGH);
|
||||
dlybit();
|
||||
|
||||
// Read SREAD pin
|
||||
for(AD7021_counter = 17; AD7021_counter >= 0; AD7021_counter--) {
|
||||
SCLK_pin(HIGH);
|
||||
dlybit();
|
||||
|
||||
if( (AD7021_counter != 17) && (AD7021_counter != 0) )
|
||||
RB_word |= ( (SREAD_pin() & 0x01) << (AD7021_counter-1) );
|
||||
|
||||
SCLK_pin(LOW);
|
||||
dlybit();
|
||||
|
||||
}
|
||||
|
||||
SLE_pin(LOW);
|
||||
|
||||
// Process RSSI code
|
||||
RB_code = RB_word & 0x7f;
|
||||
gain_code = (RB_word >> 7) & 0x0f;
|
||||
|
||||
switch(gain_code) {
|
||||
case 0b1010:
|
||||
gain_corr = 0;
|
||||
break;
|
||||
case 0b0110:
|
||||
gain_corr = 24;
|
||||
break;
|
||||
case 0b0101:
|
||||
gain_corr = 38;
|
||||
break;
|
||||
case 0b0100:
|
||||
gain_corr = 58;
|
||||
break;
|
||||
case 0b0000:
|
||||
gain_corr = 86;
|
||||
break;
|
||||
default:
|
||||
gain_corr = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return ( 130 - (RB_code + gain_corr)/2 );
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
void CIO::ifConf()
|
||||
{
|
||||
float divider;
|
||||
|
|
@ -187,22 +261,22 @@ void CIO::ifConf()
|
|||
|
||||
// VCO/OSCILLATOR (REG1)
|
||||
if( (m_frequency_tx >= VHF_MIN) && (m_frequency_tx < VHF_MAX) )
|
||||
AD7021_control_byte = ADF7021_REG1_VHF; // VHF, external VCO
|
||||
AD7021_control_word = ADF7021_REG1_VHF; // VHF, external VCO
|
||||
else if( (m_frequency_tx >= UHF_MIN)&&(m_frequency_tx < UHF_MAX) )
|
||||
AD7021_control_byte = ADF7021_REG1_UHF; // UHF, internal VCO
|
||||
AD7021_control_word = ADF7021_REG1_UHF; // UHF, internal VCO
|
||||
|
||||
Send_AD7021_control();
|
||||
|
||||
// TX/RX CLOCK (3)
|
||||
AD7021_control_byte = ADF7021_REG3;
|
||||
AD7021_control_word = ADF7021_REG3;
|
||||
Send_AD7021_control();
|
||||
|
||||
// DEMOD (4)
|
||||
AD7021_control_byte = ADF7021_REG4;
|
||||
AD7021_control_word = ADF7021_REG4;
|
||||
Send_AD7021_control();
|
||||
|
||||
// IF FILTER (5)
|
||||
AD7021_control_byte = ADF7021_REG5;
|
||||
AD7021_control_word = ADF7021_REG5;
|
||||
Send_AD7021_control();
|
||||
|
||||
// Frequency RX (0)
|
||||
|
|
@ -212,35 +286,35 @@ void CIO::ifConf()
|
|||
ADF7021_REG2 |= (uint32_t) 0b0010; // register 2
|
||||
ADF7021_REG2 |= (uint32_t) m_power << 13; // power level
|
||||
ADF7021_REG2 |= (uint32_t) 0b110001 << 7; // PA
|
||||
AD7021_control_byte = ADF7021_REG2;
|
||||
AD7021_control_word = ADF7021_REG2;
|
||||
Send_AD7021_control();
|
||||
|
||||
// TEST MODE (disabled) (15)
|
||||
AD7021_control_byte = 0x000E000F;
|
||||
AD7021_control_word = 0x000E000F;
|
||||
Send_AD7021_control();
|
||||
|
||||
// IF FINE CAL (fine cal, defaults) (6)
|
||||
AD7021_control_byte = ADF7021_REG6;
|
||||
AD7021_control_word = ADF7021_REG6;
|
||||
Send_AD7021_control();
|
||||
|
||||
// AGC (auto, defaults) (9)
|
||||
AD7021_control_byte = 0x000231E9;
|
||||
AD7021_control_word = 0x000231E9;
|
||||
Send_AD7021_control();
|
||||
|
||||
// AFC (off, defaults) (10)
|
||||
AD7021_control_byte = ADF7021_REG10;
|
||||
AD7021_control_word = ADF7021_REG10;
|
||||
Send_AD7021_control();
|
||||
|
||||
// SYNC WORD DET (11)
|
||||
AD7021_control_byte = 0x0000003B;
|
||||
AD7021_control_word = 0x0000003B;
|
||||
Send_AD7021_control();
|
||||
|
||||
// SWD/THRESHOLD (12)
|
||||
AD7021_control_byte = 0x0000010C;
|
||||
AD7021_control_word = 0x0000010C;
|
||||
Send_AD7021_control();
|
||||
|
||||
// 3FSK/4FSK DEMOD (13)
|
||||
AD7021_control_byte = ADF7021_REG13;
|
||||
AD7021_control_word = ADF7021_REG13;
|
||||
Send_AD7021_control();
|
||||
}
|
||||
|
||||
|
|
@ -248,7 +322,7 @@ void CIO::ifConf()
|
|||
void CIO::setTX()
|
||||
{
|
||||
// Send register 0 for TX operation
|
||||
AD7021_control_byte = ADF7021_TX_REG0;
|
||||
AD7021_control_word = ADF7021_TX_REG0;
|
||||
Send_AD7021_control();
|
||||
|
||||
#if defined(BIDIR_DATA_PIN)
|
||||
|
|
@ -267,7 +341,7 @@ void CIO::setRX()
|
|||
delay_rx();
|
||||
|
||||
// Send register 0 for RX operation
|
||||
AD7021_control_byte = ADF7021_RX_REG0;
|
||||
AD7021_control_word = ADF7021_RX_REG0;
|
||||
Send_AD7021_control();
|
||||
|
||||
#if defined(BIDIR_DATA_PIN)
|
||||
|
|
|
|||
5
Config.h
5
Config.h
|
|
@ -23,7 +23,7 @@
|
|||
#define ENABLE_ADF7021
|
||||
|
||||
// Bidirectional Data pin (Enable Standard TX/RX Data Interface of ADF7021)
|
||||
#define BIDIR_DATA_PIN
|
||||
// #define BIDIR_DATA_PIN
|
||||
|
||||
// TCXO of the ADF7021:
|
||||
// For 14.7456 MHz:
|
||||
|
|
@ -37,6 +37,9 @@
|
|||
//#define STM32_USART1_HOST
|
||||
#define STM32_USB_HOST
|
||||
|
||||
// Send RSSI value
|
||||
// #define SEND_RSSI_DATA
|
||||
|
||||
// Enable Nextion LCD serial port repeater:
|
||||
//#define SERIAL_REPEATER
|
||||
|
||||
|
|
|
|||
31
DMRDMORX.cpp
31
DMRDMORX.cpp
|
|
@ -110,7 +110,7 @@ void CDMRDMORX::databit(bool bit)
|
|||
switch (dataType) {
|
||||
case DT_DATA_HEADER:
|
||||
DEBUG2("DMRDMORX: data header found pos", m_syncPtr);
|
||||
serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
||||
writeRSSIData(frame);
|
||||
m_state = DMORXS_DATA;
|
||||
m_type = 0x00U;
|
||||
break;
|
||||
|
|
@ -119,32 +119,32 @@ void CDMRDMORX::databit(bool bit)
|
|||
case DT_RATE_1_DATA:
|
||||
if (m_state == DMORXS_DATA) {
|
||||
DEBUG2("DMRDMORX: data payload found pos", m_syncPtr);
|
||||
serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
||||
writeRSSIData(frame);
|
||||
m_type = dataType;
|
||||
}
|
||||
break;
|
||||
case DT_VOICE_LC_HEADER:
|
||||
DEBUG2("DMRDMORX: voice header found pos", m_syncPtr);
|
||||
serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
||||
writeRSSIData(frame);
|
||||
m_state = DMORXS_VOICE;
|
||||
break;
|
||||
case DT_VOICE_PI_HEADER:
|
||||
if (m_state == DMORXS_VOICE) {
|
||||
DEBUG2("DMRDMORX: voice pi header found pos", m_syncPtr);
|
||||
serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
||||
writeRSSIData(frame);
|
||||
}
|
||||
m_state = DMORXS_VOICE;
|
||||
break;
|
||||
case DT_TERMINATOR_WITH_LC:
|
||||
if (m_state == DMORXS_VOICE) {
|
||||
DEBUG2("DMRDMORX: voice terminator found pos", m_syncPtr);
|
||||
serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
||||
writeRSSIData(frame);
|
||||
reset();
|
||||
}
|
||||
break;
|
||||
default: // DT_CSBK
|
||||
DEBUG2("DMRDMORX: csbk found pos", m_syncPtr);
|
||||
serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
||||
writeRSSIData(frame);
|
||||
reset();
|
||||
break;
|
||||
}
|
||||
|
|
@ -152,7 +152,7 @@ void CDMRDMORX::databit(bool bit)
|
|||
} else if (m_control == CONTROL_VOICE) {
|
||||
// Voice sync
|
||||
DEBUG2("DMRDMORX: voice sync found pos", m_syncPtr);
|
||||
serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
||||
writeRSSIData(frame);
|
||||
|
||||
m_state = DMORXS_VOICE;
|
||||
m_syncCount = 0U;
|
||||
|
|
@ -177,7 +177,7 @@ void CDMRDMORX::databit(bool bit)
|
|||
} else if (m_state == DMORXS_DATA) {
|
||||
if (m_type != 0x00U) {
|
||||
frame[0U] = CONTROL_DATA | m_type;
|
||||
serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
||||
writeRSSIData(frame);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -254,3 +254,18 @@ void CDMRDMORX::setColorCode(uint8_t colorCode)
|
|||
{
|
||||
m_colorCode = colorCode;
|
||||
}
|
||||
|
||||
void CDMRDMORX::writeRSSIData(uint8_t* frame)
|
||||
{
|
||||
#if defined(SEND_RSSI_DATA)
|
||||
uint16_t rssi = io.readRSSI();
|
||||
|
||||
frame[34U] = (rssi >> 8) & 0xFFU;
|
||||
frame[35U] = (rssi >> 0) & 0xFFU;
|
||||
|
||||
serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 3U);
|
||||
#else
|
||||
serial.writeDMRData(true, frame, DMR_FRAME_LENGTH_BYTES + 1U);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ private:
|
|||
|
||||
void correlateSync();
|
||||
void bitsToBytes(uint16_t start, uint8_t count, uint8_t* buffer);
|
||||
void writeRSSIData(uint8_t* frame);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
23
DStarRX.cpp
23
DStarRX.cpp
|
|
@ -301,7 +301,8 @@ void CDStarRX::processNone(bool bit)
|
|||
|
||||
io.setDecode(true);
|
||||
|
||||
serial.writeDStarData(DSTAR_DATA_SYNC_BYTES, DSTAR_DATA_LENGTH_BYTES);
|
||||
::memcpy(m_rxBuffer, DSTAR_DATA_SYNC_BYTES, DSTAR_DATA_LENGTH_BYTES);
|
||||
writeRSSIData(m_rxBuffer);
|
||||
|
||||
::memset(m_rxBuffer, 0x00U, DSTAR_DATA_LENGTH_BYTES + 2U);
|
||||
m_rxBufferBits = 0U;
|
||||
|
|
@ -412,11 +413,12 @@ void CDStarRX::processData(bool bit)
|
|||
m_rxBuffer[9U] = DSTAR_DATA_SYNC_BYTES[9U];
|
||||
m_rxBuffer[10U] = DSTAR_DATA_SYNC_BYTES[10U];
|
||||
m_rxBuffer[11U] = DSTAR_DATA_SYNC_BYTES[11U];
|
||||
}
|
||||
writeRSSIData(m_rxBuffer);
|
||||
} else
|
||||
serial.writeDStarData(m_rxBuffer, DSTAR_DATA_LENGTH_BYTES);
|
||||
|
||||
io.setDecode(true);
|
||||
|
||||
serial.writeDStarData(m_rxBuffer, DSTAR_DATA_LENGTH_BYTES);
|
||||
|
||||
// Start the next frame
|
||||
::memset(m_rxBuffer, 0x00U, DSTAR_DATA_LENGTH_BYTES + 2U);
|
||||
m_rxBufferBits = 0U;
|
||||
|
|
@ -639,3 +641,16 @@ bool CDStarRX::checksum(const uint8_t* header) const
|
|||
return crc8[0U] == header[DSTAR_HEADER_LENGTH_BYTES - 2U] && crc8[1U] == header[DSTAR_HEADER_LENGTH_BYTES - 1U];
|
||||
}
|
||||
|
||||
void CDStarRX::writeRSSIData(unsigned char* data)
|
||||
{
|
||||
#if defined(SEND_RSSI_DATA)
|
||||
uint16_t rssi = io.readRSSI();
|
||||
|
||||
data[12U] = (rssi >> 8) & 0xFFU;
|
||||
data[13U] = (rssi >> 0) & 0xFFU;
|
||||
|
||||
serial.writeDStarData(data, DSTAR_DATA_LENGTH_BYTES + 2U);
|
||||
#else
|
||||
serial.writeDStarData(data, DSTAR_DATA_LENGTH_BYTES + 0U);
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ private:
|
|||
void viterbiDecode(int* data);
|
||||
void traceBack();
|
||||
bool checksum(const uint8_t* header) const;
|
||||
void writeRSSIData(unsigned char* data);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
67
IO.h
67
IO.h
|
|
@ -41,49 +41,54 @@ public:
|
|||
CIO();
|
||||
|
||||
// Platform API
|
||||
void Init(void);
|
||||
void SCLK_pin(bool on);
|
||||
void SDATA_pin(bool on);
|
||||
void SLE_pin(bool on);
|
||||
bool RXD_pin();
|
||||
void Init(void);
|
||||
void SCLK_pin(bool on);
|
||||
void SDATA_pin(bool on);
|
||||
bool SREAD_pin(void);
|
||||
void SLE_pin(bool on);
|
||||
bool RXD_pin(void);
|
||||
#if defined(BIDIR_DATA_PIN)
|
||||
void RXD_pin_write(bool on);
|
||||
void RXD_pin_write(bool on);
|
||||
#endif
|
||||
void TXD_pin(bool on);
|
||||
void PTT_pin(bool on);
|
||||
void LED_pin(bool on);
|
||||
void DEB_pin(bool on);
|
||||
void DSTAR_pin(bool on);
|
||||
void DMR_pin(bool on);
|
||||
void YSF_pin(bool on);
|
||||
void P25_pin(bool on);
|
||||
void COS_pin(bool on);
|
||||
void interrupt(void);
|
||||
void TXD_pin(bool on);
|
||||
void PTT_pin(bool on);
|
||||
void LED_pin(bool on);
|
||||
void DEB_pin(bool on);
|
||||
void DSTAR_pin(bool on);
|
||||
void DMR_pin(bool on);
|
||||
void YSF_pin(bool on);
|
||||
void P25_pin(bool on);
|
||||
void COS_pin(bool on);
|
||||
void interrupt(void);
|
||||
|
||||
#if defined(BIDIR_DATA_PIN)
|
||||
void Data_dir_out(bool dir);
|
||||
#endif
|
||||
|
||||
// IO API
|
||||
void write(uint8_t* data, uint16_t length);
|
||||
uint16_t getSpace() const;
|
||||
void process();
|
||||
bool hasTXOverflow();
|
||||
bool hasRXOverflow();
|
||||
uint8_t setFreq(uint32_t frequency_rx, uint32_t frequency_tx);
|
||||
void setMode();
|
||||
void setDecode(bool dcd);
|
||||
void write(uint8_t* data, uint16_t length);
|
||||
uint16_t getSpace(void) const;
|
||||
void process(void);
|
||||
bool hasTXOverflow(void);
|
||||
bool hasRXOverflow(void);
|
||||
uint8_t setFreq(uint32_t frequency_rx, uint32_t frequency_tx);
|
||||
void setMode(void);
|
||||
void setDecode(bool dcd);
|
||||
|
||||
// RF interface API
|
||||
void setTX();
|
||||
void setRX();
|
||||
void ifConf();
|
||||
void start();
|
||||
void startInt();
|
||||
void setTX(void);
|
||||
void setRX(void);
|
||||
void ifConf(void);
|
||||
void start(void);
|
||||
void startInt(void);
|
||||
|
||||
#if defined(SEND_RSSI_DATA)
|
||||
uint16_t readRSSI(void);
|
||||
#endif
|
||||
|
||||
// Misc functions
|
||||
void dlybit(void);
|
||||
void delay_rx(void);
|
||||
void dlybit(void);
|
||||
void delay_rx(void);
|
||||
|
||||
private:
|
||||
bool m_started;
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ void CIO::Init()
|
|||
|
||||
pinMode(PIN_SCLK, OUTPUT);
|
||||
pinMode(PIN_SDATA, OUTPUT);
|
||||
pinMode(PIN_SREAD, INPUT);
|
||||
pinMode(PIN_SLE, OUTPUT);
|
||||
pinMode(PIN_RXD, INPUT);
|
||||
pinMode(PIN_CLKOUT, INPUT);
|
||||
|
|
@ -153,6 +154,11 @@ void CIO::SDATA_pin(bool on)
|
|||
digitalWrite(PIN_SDATA, on ? HIGH : LOW);
|
||||
}
|
||||
|
||||
bool CIO::SREAD_pin()
|
||||
{
|
||||
return digitalRead(PIN_SREAD) == HIGH;
|
||||
}
|
||||
|
||||
void CIO::SLE_pin(bool on)
|
||||
{
|
||||
digitalWrite(PIN_SLE, on ? HIGH : LOW);
|
||||
|
|
|
|||
11
IOSTM.cpp
11
IOSTM.cpp
|
|
@ -167,6 +167,12 @@ void CIO::Init()
|
|||
GPIO_InitStruct.GPIO_Pin = PIN_SDATA;
|
||||
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
|
||||
GPIO_Init(PORT_SDATA, &GPIO_InitStruct);
|
||||
|
||||
// Pin SREAD
|
||||
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_InitStruct.GPIO_Pin = PIN_SREAD;
|
||||
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||||
GPIO_Init(PORT_SREAD, &GPIO_InitStruct);
|
||||
|
||||
// Pin SLE
|
||||
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
|
|
@ -311,6 +317,11 @@ void CIO::SDATA_pin(bool on)
|
|||
GPIO_WriteBit(PORT_SDATA, PIN_SDATA, on ? Bit_SET : Bit_RESET);
|
||||
}
|
||||
|
||||
bool CIO::SREAD_pin()
|
||||
{
|
||||
return GPIO_ReadInputDataBit(PORT_SREAD, PIN_SREAD) == Bit_SET;
|
||||
}
|
||||
|
||||
void CIO::SLE_pin(bool on)
|
||||
{
|
||||
GPIO_WriteBit(PORT_SLE, PIN_SLE, on ? Bit_SET : Bit_RESET);
|
||||
|
|
|
|||
Loading…
Reference in a new issue