From 7d40e245bd026708da086fc9a47c7f7a169a2de9 Mon Sep 17 00:00:00 2001 From: Andy CA6JAU Date: Fri, 10 Feb 2017 14:03:14 -0300 Subject: [PATCH] Adding RSSI support for ADF7021, and RSSI for DStar and DMR --- ADF7021.cpp | 118 ++++++++++++++++++++++++++++++++++++++++---------- Config.h | 5 ++- DMRDMORX.cpp | 31 +++++++++---- DMRDMORX.h | 1 + DStarRX.cpp | 23 ++++++++-- DStarRX.h | 1 + IO.h | 67 +++++++++++++++------------- IOArduino.cpp | 6 +++ IOSTM.cpp | 11 +++++ 9 files changed, 197 insertions(+), 66 deletions(-) diff --git a/ADF7021.cpp b/ADF7021.cpp index 65a4367..585d78f 100644 --- a/ADF7021.cpp +++ b/ADF7021.cpp @@ -29,32 +29,106 @@ #include "ADF7021.h" #include -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) diff --git a/Config.h b/Config.h index a0cf55f..21a1ab5 100644 --- a/Config.h +++ b/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 diff --git a/DMRDMORX.cpp b/DMRDMORX.cpp index ea942de..0fc9bdc 100644 --- a/DMRDMORX.cpp +++ b/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 +} + diff --git a/DMRDMORX.h b/DMRDMORX.h index 0a549f3..4036e27 100644 --- a/DMRDMORX.h +++ b/DMRDMORX.h @@ -56,6 +56,7 @@ private: void correlateSync(); void bitsToBytes(uint16_t start, uint8_t count, uint8_t* buffer); + void writeRSSIData(uint8_t* frame); }; diff --git a/DStarRX.cpp b/DStarRX.cpp index 04e1ae3..9b3a2ff 100644 --- a/DStarRX.cpp +++ b/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 +} diff --git a/DStarRX.h b/DStarRX.h index 34404fd..4eda77c 100644 --- a/DStarRX.h +++ b/DStarRX.h @@ -58,6 +58,7 @@ private: void viterbiDecode(int* data); void traceBack(); bool checksum(const uint8_t* header) const; + void writeRSSIData(unsigned char* data); }; #endif diff --git a/IO.h b/IO.h index aef8442..90fbd23 100644 --- a/IO.h +++ b/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; diff --git a/IOArduino.cpp b/IOArduino.cpp index 370bc94..e80673b 100644 --- a/IOArduino.cpp +++ b/IOArduino.cpp @@ -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); diff --git a/IOSTM.cpp b/IOSTM.cpp index 4cc2e85..30c80f6 100644 --- a/IOSTM.cpp +++ b/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);