Adding RSSI support for ADF7021, and RSSI for DStar and DMR

pull/2/head
Andy CA6JAU 9 years ago
parent d1976f1049
commit 7d40e245bd

@ -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)

@ -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

@ -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);
};

@ -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

@ -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);

@ -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…
Cancel
Save

Powered by TurnKey Linux.