Adding second ADF7021 support and fixing some mistakes

This commit is contained in:
Andy CA6JAU 2017-05-01 01:02:47 -03:00
parent e86e1bfdd2
commit 0c22c47d5c
13 changed files with 379 additions and 28 deletions

View file

@ -38,6 +38,9 @@ volatile uint32_t AD7021_control_word;
uint32_t ADF7021_RX_REG0; uint32_t ADF7021_RX_REG0;
uint32_t ADF7021_TX_REG0; uint32_t ADF7021_TX_REG0;
uint32_t ADF7021_REG1;
uint32_t div2;
uint8_t m_control;
static void Send_AD7021_control_shift() static void Send_AD7021_control_shift()
{ {
@ -74,6 +77,24 @@ void Send_AD7021_control(bool doSle)
} }
} }
#if defined(DUPLEX)
static void Send_AD7021_control_sle2Pulse()
{
io.SLE2_pin(HIGH);
io.dlybit();
io.SLE2_pin(LOW);
}
void Send_AD7021_control2(bool doSle)
{
Send_AD7021_control_shift();
if (doSle) {
Send_AD7021_control_sle2Pulse();
}
}
#endif
#if defined(SEND_RSSI_DATA) #if defined(SEND_RSSI_DATA)
uint16_t CIO::readRSSI() uint16_t CIO::readRSSI()
{ {
@ -152,9 +173,7 @@ void CIO::ifConf(MMDVM_STATE modemState, bool reset)
float divider; float divider;
uint8_t N_divider; uint8_t N_divider;
uint16_t F_divider; uint16_t F_divider;
uint32_t div2;
uint32_t ADF7021_REG1 = 0;
uint32_t ADF7021_REG2 = 0; uint32_t ADF7021_REG2 = 0;
uint32_t ADF7021_REG3 = 0; uint32_t ADF7021_REG3 = 0;
uint32_t ADF7021_REG4 = 0; uint32_t ADF7021_REG4 = 0;
@ -420,12 +439,182 @@ void CIO::ifConf(MMDVM_STATE modemState, bool reset)
AD7021_control_word = 0x000E000F; AD7021_control_word = 0x000E000F;
#endif #endif
Send_AD7021_control(); Send_AD7021_control();
#if defined(DUPLEX)
if(m_duplex)
ifConf2(modemState);
#endif
} }
#if defined(DUPLEX)
void CIO::ifConf2(MMDVM_STATE modemState)
{
uint32_t ADF7021_REG2 = 0;
uint32_t ADF7021_REG3 = 0;
uint32_t ADF7021_REG4 = 0;
uint32_t ADF7021_REG10 = 0;
uint32_t ADF7021_REG13 = 0;
switch (modemState) {
case STATE_DSTAR:
// Dev: 1200 Hz, symb rate = 4800
ADF7021_REG3 = ADF7021_REG3_DSTAR;
ADF7021_REG10 = ADF7021_REG10_DSTAR;
// K=32
ADF7021_REG4 = (uint32_t) 0b0100 << 0; // register 4
ADF7021_REG4 |= (uint32_t) 0b001 << 4; // mode, GMSK
ADF7021_REG4 |= (uint32_t) 0b1 << 7;
ADF7021_REG4 |= (uint32_t) 0b10 << 8;
ADF7021_REG4 |= (uint32_t) ADF7021_DISC_BW_DSTAR << 10; // Disc BW
ADF7021_REG4 |= (uint32_t) ADF7021_POST_BW_DSTAR << 20; // Post dem BW
ADF7021_REG4 |= (uint32_t) 0b10 << 30; // IF filter
ADF7021_REG13 = (uint32_t) 0b1101 << 0; // register 13
ADF7021_REG13 |= (uint32_t) ADF7021_SLICER_TH_DSTAR << 4; // slicer threshold
ADF7021_REG2 = (uint32_t) 0b00 << 28; // clock normal
ADF7021_REG2 |= (uint32_t) (ADF7021_DEV_DSTAR / div2)<< 19; // deviation
ADF7021_REG2 |= (uint32_t) 0b001 << 4; // modulation (GMSK)
break;
case STATE_DMR:
// Dev: +1 symb 648 Hz, symb rate = 4800
ADF7021_REG3 = ADF7021_REG3_DMR;
ADF7021_REG10 = ADF7021_REG10_DMR;
// K=32
ADF7021_REG4 = (uint32_t) 0b0100 << 0; // register 4
ADF7021_REG4 |= (uint32_t) 0b011 << 4; // mode, 4FSK
ADF7021_REG4 |= (uint32_t) 0b0 << 7;
ADF7021_REG4 |= (uint32_t) 0b11 << 8;
ADF7021_REG4 |= (uint32_t) ADF7021_DISC_BW_DMR << 10; // Disc BW
ADF7021_REG4 |= (uint32_t) ADF7021_POST_BW_DMR << 20; // Post dem BW
ADF7021_REG4 |= (uint32_t) 0b10 << 30; // IF filter
ADF7021_REG13 = (uint32_t) 0b1101 << 0; // register 13
ADF7021_REG13 |= (uint32_t) ADF7021_SLICER_TH_DMR << 4; // slicer threshold
ADF7021_REG2 = (uint32_t) 0b10 << 28; // invert data (and RC alpha = 0.5)
ADF7021_REG2 |= (uint32_t) (ADF7021_DEV_DMR / div2) << 19; // deviation
ADF7021_REG2 |= (uint32_t) 0b111 << 4; // modulation (RC 4FSK)
break;
case STATE_YSF:
// Dev: +1 symb 900 Hz, symb rate = 4800
ADF7021_REG3 = (m_LoDevYSF ? ADF7021_REG3_YSF_L : ADF7021_REG3_YSF_H);
ADF7021_REG10 = ADF7021_REG10_YSF;
// K=28
ADF7021_REG4 = (uint32_t) 0b0100 << 0; // register 4
ADF7021_REG4 |= (uint32_t) 0b011 << 4; // mode, 4FSK
ADF7021_REG4 |= (uint32_t) 0b0 << 7;
ADF7021_REG4 |= (uint32_t) 0b11 << 8;
ADF7021_REG4 |= (uint32_t) (m_LoDevYSF ? ADF7021_DISC_BW_YSF_L : ADF7021_DISC_BW_YSF_H) << 10; // Disc BW
ADF7021_REG4 |= (uint32_t) ADF7021_POST_BW_YSF << 20; // Post dem BW
ADF7021_REG4 |= (uint32_t) 0b10 << 30; // IF filter
ADF7021_REG13 = (uint32_t) 0b1101 << 0; // register 13
ADF7021_REG13 |= (uint32_t) (m_LoDevYSF ? ADF7021_SLICER_TH_YSF_L : ADF7021_SLICER_TH_YSF_H) << 4; // slicer threshold
ADF7021_REG2 = (uint32_t) 0b10 << 28; // invert data (and RC alpha = 0.5)
ADF7021_REG2 |= (uint32_t) ((m_LoDevYSF ? ADF7021_DEV_YSF_L : ADF7021_DEV_YSF_H) / div2) << 19; // deviation
ADF7021_REG2 |= (uint32_t) 0b111 << 4; // modulation (RC 4FSK)
break;
case STATE_P25:
// Dev: +1 symb 600 Hz, symb rate = 4800
ADF7021_REG3 = ADF7021_REG3_P25;
ADF7021_REG10 = ADF7021_REG10_P25;
// K=32
ADF7021_REG4 = (uint32_t) 0b0100 << 0; // register 4
ADF7021_REG4 |= (uint32_t) 0b011 << 4; // mode, 4FSK
ADF7021_REG4 |= (uint32_t) 0b0 << 7;
ADF7021_REG4 |= (uint32_t) 0b11 << 8;
ADF7021_REG4 |= (uint32_t) ADF7021_DISC_BW_P25 << 10; // Disc BW
ADF7021_REG4 |= (uint32_t) ADF7021_POST_BW_P25 << 20; // Post dem BW
ADF7021_REG4 |= (uint32_t) 0b10 << 30; // IF filter
ADF7021_REG13 = (uint32_t) 0b1101 << 0; // register 13
ADF7021_REG13 |= (uint32_t) ADF7021_SLICER_TH_P25 << 4; // slicer threshold
ADF7021_REG2 = (uint32_t) 0b10 << 28; // invert data (and RC alpha = 0.5)
ADF7021_REG2 |= (uint32_t) (ADF7021_DEV_P25 / div2) << 19; // deviation
ADF7021_REG2 |= (uint32_t) 0b111 << 4; // modulation (RC 4FSK)
break;
default:
break;
}
// VCO/OSCILLATOR (1)
AD7021_control_word = ADF7021_REG1;
Send_AD7021_control2();
// TX/RX CLOCK (3)
AD7021_control_word = ADF7021_REG3;
Send_AD7021_control2();
// DEMOD (4)
AD7021_control_word = ADF7021_REG4;
Send_AD7021_control2();
// IF FILTER (5)
AD7021_control_word = ADF7021_REG5;
Send_AD7021_control2();
// Delay for coarse IF filter calibration
delay_ifcal_coarse();
// Frequency RX (0) and set to RX only
AD7021_control_word = ADF7021_RX_REG0;
Send_AD7021_control2();
// MODULATION (2)
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_word = ADF7021_REG2;
Send_AD7021_control2();
// TEST DAC (14)
AD7021_control_word = 0x0000000E;
Send_AD7021_control2();
// AGC (auto, defaults) (9)
AD7021_control_word = 0x000231E9;
Send_AD7021_control2();
// AFC (10)
AD7021_control_word = ADF7021_REG10;
Send_AD7021_control2();
// SYNC WORD DET (11)
AD7021_control_word = 0x0000003B;
Send_AD7021_control2();
// SWD/THRESHOLD (12)
AD7021_control_word = 0x0000010C;
Send_AD7021_control2();
// 3FSK/4FSK DEMOD (13)
AD7021_control_word = ADF7021_REG13;
Send_AD7021_control2();
// TEST MODE (disabled) (15)
AD7021_control_word = 0x000E000F;
Send_AD7021_control2();
}
#endif
void CIO::interrupt() void CIO::interrupt()
{ {
uint8_t bit = 0; uint8_t bit = 0;
uint8_t control = MARK_NONE;
if (!m_started) if (!m_started)
return; return;
@ -450,7 +639,7 @@ void CIO::interrupt()
// we set the TX bit at TXD low, sampling of ADF7021 happens at rising clock // we set the TX bit at TXD low, sampling of ADF7021 happens at rising clock
if (m_tx && clk == 0) { if (m_tx && clk == 0) {
m_txBuffer.get(bit, control); m_txBuffer.get(bit, m_control);
even = !even; even = !even;
// use this for tracking issues // use this for tracking issues
@ -493,13 +682,13 @@ void CIO::interrupt()
} }
// we sample the RX bit at rising TXD clock edge, so TXD must be 1 and we are not in tx mode // we sample the RX bit at rising TXD clock edge, so TXD must be 1 and we are not in tx mode
if (!m_tx && clk == 1) { if (!m_tx && clk == 1 && !m_duplex) {
if(RXD_pin()) if(RXD_pin())
bit = 1; bit = 1;
else else
bit = 0; bit = 0;
m_rxBuffer.put(bit, control); m_rxBuffer.put(bit, m_control);
} }
if (torx_request == true && even == false && m_tx && clk == 0) { if (torx_request == true && even == false && m_tx && clk == 0) {
@ -534,6 +723,22 @@ void CIO::interrupt()
m_scanPauseCnt++; m_scanPauseCnt++;
} }
#if defined(DUPLEX)
void CIO::interrupt2()
{
uint8_t bit = 0;
if(m_duplex) {
if(RXD2_pin())
bit = 1;
else
bit = 0;
m_rxBuffer.put(bit, m_control);
}
}
#endif
//====================================================================================================================== //======================================================================================================================
void CIO::setTX() void CIO::setTX()
{ {

View file

@ -227,6 +227,9 @@ www.analog.com/media/en/technical-documentation/data-sheets/ADF7021.pdf
#define bitRead(value, bit) (((value) >> (bit)) & 0x01) #define bitRead(value, bit) (((value) >> (bit)) & 0x01)
void Send_AD7021_control(bool doSle = true); void Send_AD7021_control(bool doSle = true);
#if defined(DUPLEX)
void Send_AD7021_control2(bool doSle = true);
#endif
#endif #endif

View file

@ -34,7 +34,7 @@
// #define ADF7021_N_VER // #define ADF7021_N_VER
// Enable duplex mode with dual ADF7021 // Enable duplex mode with dual ADF7021
// #define DUPLEX #define DUPLEX
// Bidirectional Data pin (Enable Standard TX/RX Data Interface of ADF7021): // Bidirectional Data pin (Enable Standard TX/RX Data Interface of ADF7021):
#define BIDIR_DATA_PIN #define BIDIR_DATA_PIN

View file

@ -67,19 +67,19 @@ void CDMRIdleRX::databit(bool bit)
} }
if (m_dataPtr == m_endPtr) { if (m_dataPtr == m_endPtr) {
uint16_t ptr = m_endPtr + 2; uint16_t ptr = m_endPtr + 1;
if (ptr >= DMR_FRAME_LENGTH_BITS) if (ptr >= DMR_FRAME_LENGTH_BITS)
ptr -= DMR_FRAME_LENGTH_BITS; ptr -= DMR_FRAME_LENGTH_BITS;
uint8_t frame[DMR_FRAME_LENGTH_BYTES + 1U]; uint8_t frame[DMR_FRAME_LENGTH_BYTES + 1U];
bitsToBytes(ptr, DMR_FRAME_LENGTH_BITS, frame + 1U); bitsToBytes(ptr, DMR_FRAME_LENGTH_BYTES, frame + 1U);
uint8_t colorCode; uint8_t colorCode;
uint8_t dataType; uint8_t dataType;
CDMRSlotType slotType; CDMRSlotType slotType;
slotType.decode(frame + 1U, colorCode, dataType); slotType.decode(frame + 1U, colorCode, dataType);
if (colorCode == m_colorCode && dataType == DT_CSBK) { if (colorCode == m_colorCode && dataType == DT_CSBK) {
frame[0U] = CONTROL_IDLE | CONTROL_DATA | DT_CSBK; frame[0U] = CONTROL_IDLE | CONTROL_DATA | DT_CSBK;
serial.writeDMRData(false, frame, DMR_FRAME_LENGTH_BYTES + 1U); serial.writeDMRData(false, frame, DMR_FRAME_LENGTH_BYTES + 1U);

View file

@ -44,11 +44,11 @@ void CDMRRX::databit(bool bit, const uint8_t control)
break; break;
default: default:
break; break;
dcd1 = m_slot1RX.databit(bit);
dcd2 = m_slot2RX.databit(bit);
} }
dcd1 = m_slot1RX.databit(bit);
dcd2 = m_slot2RX.databit(bit);
io.setDecode(dcd1 || dcd2); io.setDecode(dcd1 || dcd2);
} }

View file

@ -17,19 +17,19 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#define WANT_DEBUG
#include "Config.h" #include "Config.h"
#if defined(DUPLEX) #if defined(DUPLEX)
#define WANT_DEBUG
#include "Globals.h" #include "Globals.h"
#include "DMRSlotRX.h" #include "DMRSlotRX.h"
#include "DMRSlotType.h" #include "DMRSlotType.h"
#include "Utils.h" #include "Utils.h"
const uint16_t SCAN_START = 400U; const uint16_t SCAN_START = 170U;
const uint16_t SCAN_END = 490U; const uint16_t SCAN_END = 190U;
const uint8_t MAX_SYNC_BYTES_ERRS = 1U; const uint8_t MAX_SYNC_BYTES_ERRS = 1U;
@ -64,6 +64,7 @@ void CDMRSlotRX::start()
{ {
m_dataPtr = 0U; m_dataPtr = 0U;
m_delayPtr = 0U; m_delayPtr = 0U;
m_patternBuffer = 0U;
m_control = CONTROL_NONE; m_control = CONTROL_NONE;
} }
@ -86,7 +87,7 @@ bool CDMRSlotRX::databit(bool bit)
return m_state != DMRRXS_NONE; return m_state != DMRRXS_NONE;
// Ensure that the buffer doesn't overflow // Ensure that the buffer doesn't overflow
if (m_dataPtr > m_endPtr || m_dataPtr >= 900U) if (m_dataPtr > m_endPtr || m_dataPtr >= 400U)
return m_state != DMRRXS_NONE; return m_state != DMRRXS_NONE;
m_buffer[m_dataPtr] = bit; m_buffer[m_dataPtr] = bit;
@ -94,12 +95,11 @@ bool CDMRSlotRX::databit(bool bit)
m_patternBuffer <<= 1; m_patternBuffer <<= 1;
if (bit) if (bit)
m_patternBuffer |= 0x01U; m_patternBuffer |= 0x01U;
if (m_state == DMRRXS_NONE) { if (m_state == DMRRXS_NONE) {
if (m_dataPtr >= SCAN_START && m_dataPtr <= SCAN_END) if (m_dataPtr >= SCAN_START && m_dataPtr <= SCAN_END)
correlateSync(true); correlateSync(true);
} else { } else {
uint16_t min = m_syncPtr - 1U; uint16_t min = m_syncPtr - 1U;
uint16_t max = m_syncPtr + 1U; uint16_t max = m_syncPtr + 1U;
if (m_dataPtr >= min && m_dataPtr <= max) if (m_dataPtr >= min && m_dataPtr <= max)
@ -217,7 +217,7 @@ void CDMRSlotRX::correlateSync(bool first)
m_syncPtr = m_dataPtr; m_syncPtr = m_dataPtr;
m_startPtr = m_dataPtr - DMR_SLOT_TYPE_LENGTH_BITS / 2U - DMR_INFO_LENGTH_BITS / 2U - DMR_SYNC_LENGTH_BITS + 1; m_startPtr = m_dataPtr - DMR_SLOT_TYPE_LENGTH_BITS / 2U - DMR_INFO_LENGTH_BITS / 2U - DMR_SYNC_LENGTH_BITS + 1;
m_endPtr = m_dataPtr + DMR_SLOT_TYPE_LENGTH_BITS / 2U + DMR_INFO_LENGTH_BITS / 2U; m_endPtr = m_dataPtr + DMR_SLOT_TYPE_LENGTH_BITS / 2U + DMR_INFO_LENGTH_BITS / 2U;
DEBUG4("SYNC MS Data found pos/start/end:", m_dataPtr, m_startPtr, m_endPtr); DEBUG4("SYNC corr MS Data found pos/start/end:", m_dataPtr, m_startPtr, m_endPtr);
} else if (countBits64((m_patternBuffer & DMR_SYNC_BITS_MASK) ^ DMR_MS_VOICE_SYNC_BITS) <= MAX_SYNC_BYTES_ERRS) { } else if (countBits64((m_patternBuffer & DMR_SYNC_BITS_MASK) ^ DMR_MS_VOICE_SYNC_BITS) <= MAX_SYNC_BYTES_ERRS) {
@ -225,7 +225,7 @@ void CDMRSlotRX::correlateSync(bool first)
m_syncPtr = m_dataPtr; m_syncPtr = m_dataPtr;
m_startPtr = m_dataPtr - DMR_SLOT_TYPE_LENGTH_BITS / 2U - DMR_INFO_LENGTH_BITS / 2U - DMR_SYNC_LENGTH_BITS + 1; m_startPtr = m_dataPtr - DMR_SLOT_TYPE_LENGTH_BITS / 2U - DMR_INFO_LENGTH_BITS / 2U - DMR_SYNC_LENGTH_BITS + 1;
m_endPtr = m_dataPtr + DMR_SLOT_TYPE_LENGTH_BITS / 2U + DMR_INFO_LENGTH_BITS / 2U; m_endPtr = m_dataPtr + DMR_SLOT_TYPE_LENGTH_BITS / 2U + DMR_INFO_LENGTH_BITS / 2U;
DEBUG4("SYNC MS Voice found pos/start/end: ", m_dataPtr, m_startPtr, m_endPtr); DEBUG4("SYNC corr MS Voice found pos/start/end: ", m_dataPtr, m_startPtr, m_endPtr);
} }
} }

View file

@ -48,7 +48,7 @@ public:
private: private:
bool m_slot; bool m_slot;
uint64_t m_patternBuffer; uint64_t m_patternBuffer;
uint8_t m_buffer[900U]; uint8_t m_buffer[400U];
uint16_t m_dataPtr; uint16_t m_dataPtr;
uint16_t m_syncPtr; uint16_t m_syncPtr;
uint16_t m_startPtr; uint16_t m_startPtr;

View file

@ -18,7 +18,7 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
// #define WANT_DEBUG //#define WANT_DEBUG
#include "Config.h" #include "Config.h"
@ -220,6 +220,7 @@ void CDMRTX::writeByte(uint8_t c, uint8_t control)
{ {
uint8_t bit; uint8_t bit;
uint8_t mask = 0x80U; uint8_t mask = 0x80U;
uint8_t control_tmp;
for (uint8_t i = 0U; i < 8U; i++, c <<= 1) { for (uint8_t i = 0U; i < 8U; i++, c <<= 1) {
if ((c & mask) == mask) if ((c & mask) == mask)
@ -227,10 +228,13 @@ void CDMRTX::writeByte(uint8_t c, uint8_t control)
else else
bit = 0U; bit = 0U;
if( i != 3U) control_tmp = MARK_NONE;
control = MARK_NONE;
if( i == 0U)
control_tmp = control;
io.write(&bit, 1, &control); io.write(&bit, 1, &control_tmp);
} }
} }

10
IO.cpp
View file

@ -124,7 +124,17 @@ void CIO::process()
dstarRX.databit(bit); dstarRX.databit(bit);
break; break;
case STATE_DMR: case STATE_DMR:
#if defined(DUPLEX)
if (m_duplex) {
if (m_tx)
dmrRX.databit(bit, control);
else
dmrIdleRX.databit(bit);
} else
dmrDMORX.databit(bit);
#else
dmrDMORX.databit(bit); dmrDMORX.databit(bit);
#endif
break; break;
case STATE_YSF: case STATE_YSF:
ysfRX.databit(bit); ysfRX.databit(bit);

11
IO.h
View file

@ -20,6 +20,7 @@
#if !defined(CIO_H) #if !defined(CIO_H)
#define CIO_H #define CIO_H
#include "Config.h"
#include "Globals.h" #include "Globals.h"
#include "BitRB.h" #include "BitRB.h"
@ -53,6 +54,10 @@ public:
void SDATA_pin(bool on); void SDATA_pin(bool on);
bool SREAD_pin(void); bool SREAD_pin(void);
void SLE_pin(bool on); void SLE_pin(bool on);
#if defined(DUPLEX)
void SLE2_pin(bool on);
bool RXD2_pin(void);
#endif
void CE_pin(bool on); void CE_pin(bool on);
bool RXD_pin(void); bool RXD_pin(void);
bool CLK_pin(void); bool CLK_pin(void);
@ -71,6 +76,9 @@ public:
void P25_pin(bool on); void P25_pin(bool on);
void COS_pin(bool on); void COS_pin(bool on);
void interrupt(void); void interrupt(void);
#if defined(DUPLEX)
void interrupt2(void);
#endif
void resetWatchdog(void); void resetWatchdog(void);
#if defined(BIDIR_DATA_PIN) #if defined(BIDIR_DATA_PIN)
@ -92,6 +100,9 @@ public:
void setTX(void); void setTX(void);
void setRX(bool doSle = true); void setRX(bool doSle = true);
void ifConf(MMDVM_STATE modemState, bool reset); void ifConf(MMDVM_STATE modemState, bool reset);
#if defined(DUPLEX)
void ifConf2(MMDVM_STATE modemState);
#endif
void start(void); void start(void);
void startInt(void); void startInt(void);

View file

@ -52,9 +52,12 @@
#define PIN_SREAD PB6 #define PIN_SREAD PB6
#define PIN_SDATA PB7 #define PIN_SDATA PB7
#define PIN_SLE PB8 #define PIN_SLE PB8
#define PIN_SLE2 PA6
#define PIN_CE PC14 #define PIN_CE PC14
#define PIN_RXD PB4 #define PIN_RXD PB4
#define PIN_RXD2 PA4
#define PIN_TXD PB3 #define PIN_TXD PB3
#define PIN_TXD2 PA5
#define PIN_CLKOUT PA15 #define PIN_CLKOUT PA15
#define PIN_LED PC13 #define PIN_LED PC13
#define PIN_DEB PB9 #define PIN_DEB PB9
@ -71,9 +74,12 @@
#define PIN_SREAD PB7 #define PIN_SREAD PB7
#define PIN_SDATA PB6 #define PIN_SDATA PB6
#define PIN_SLE PB8 #define PIN_SLE PB8
#define PIN_SLE2 PA6
#define PIN_CE PC14 #define PIN_CE PC14
#define PIN_RXD PB4 #define PIN_RXD PB4
#define PIN_RXD2 PA4
#define PIN_TXD PB3 #define PIN_TXD PB3
#define PIN_TXD2 PA5
#define PIN_CLKOUT PA15 #define PIN_CLKOUT PA15
#define PIN_LED PC13 #define PIN_LED PC13
#define PIN_DEB PB9 #define PIN_DEB PB9
@ -116,6 +122,14 @@ extern "C" {
} }
} }
#if defined(DUPLEX)
extern "C" {
void EXT_IRQHandler2(void) {
io.interrupt2();
}
}
#endif
void CIO::delay_ifcal_coarse() { void CIO::delay_ifcal_coarse() {
delayMicroseconds(300); delayMicroseconds(300);
} }
@ -152,6 +166,12 @@ void CIO::Init()
pinMode(PIN_PTT_LED, OUTPUT); pinMode(PIN_PTT_LED, OUTPUT);
pinMode(PIN_COS_LED, OUTPUT); pinMode(PIN_COS_LED, OUTPUT);
#if defined(DUPLEX)
pinMode(PIN_SLE2, OUTPUT);
pinMode(PIN_RXD2, INPUT);
pinMode(PIN_TXD2, INPUT);
#endif
#if defined(BIDIR_DATA_PIN) #if defined(BIDIR_DATA_PIN)
pinMode(PIN_TXD, INPUT); pinMode(PIN_TXD, INPUT);
#else #else
@ -180,6 +200,10 @@ void CIO::startInt()
#endif #endif
#endif #endif
#if defined(DUPLEX)
attachInterrupt(PIN_TXD2, EXT_IRQHandler2, RISING);
#endif
} }
#if defined(BIDIR_DATA_PIN) #if defined(BIDIR_DATA_PIN)
@ -213,6 +237,18 @@ void CIO::SLE_pin(bool on)
digitalWrite(PIN_SLE, on ? HIGH : LOW); digitalWrite(PIN_SLE, on ? HIGH : LOW);
} }
#if defined(DUPLEX)
void CIO::SLE2_pin(bool on)
{
digitalWrite(PIN_SLE2, on ? HIGH : LOW);
}
bool CIO::RXD2_pin()
{
return digitalRead(PIN_RXD2) == HIGH;
}
#endif
void CIO::CE_pin(bool on) void CIO::CE_pin(bool on)
{ {
digitalWrite(PIN_CE, on ? HIGH : LOW); digitalWrite(PIN_CE, on ? HIGH : LOW);

View file

@ -96,6 +96,9 @@
#define PIN_SLE GPIO_Pin_8 #define PIN_SLE GPIO_Pin_8
#define PORT_SLE GPIOB #define PORT_SLE GPIOB
#define PIN_SLE2 GPIO_Pin_6
#define PORT_SLE2 GPIOA
#define PIN_CE GPIO_Pin_14 #define PIN_CE GPIO_Pin_14
#define PORT_CE GPIOC #define PORT_CE GPIOC
@ -153,12 +156,18 @@
#define PIN_SLE GPIO_Pin_8 #define PIN_SLE GPIO_Pin_8
#define PORT_SLE GPIOB #define PORT_SLE GPIOB
#define PIN_SLE2 GPIO_Pin_6
#define PORT_SLE2 GPIOA
#define PIN_CE GPIO_Pin_14 #define PIN_CE GPIO_Pin_14
#define PORT_CE GPIOC #define PORT_CE GPIOC
#define PIN_RXD GPIO_Pin_4 #define PIN_RXD GPIO_Pin_4
#define PORT_RXD GPIOB #define PORT_RXD GPIOB
#define PIN_RXD2 GPIO_Pin_4
#define PORT_RXD2 GPIOA
// TXD used in SPI Data mode of ADF7021 // TXD used in SPI Data mode of ADF7021
// TXD is TxRxCLK of ADF7021, standard TX/RX data interface // TXD is TxRxCLK of ADF7021, standard TX/RX data interface
#define PIN_TXD GPIO_Pin_3 #define PIN_TXD GPIO_Pin_3
@ -166,6 +175,12 @@
#define PIN_TXD_INT GPIO_PinSource3 #define PIN_TXD_INT GPIO_PinSource3
#define PORT_TXD_INT GPIO_PortSourceGPIOB #define PORT_TXD_INT GPIO_PortSourceGPIOB
// TXD2 is TxRxCLK of the second ADF7021, standard TX/RX data interface
#define PIN_TXD2 GPIO_Pin_5
#define PORT_TXD2 GPIOA
#define PIN_TXD2_INT GPIO_PinSource5
#define PORT_TXD2_INT GPIO_PortSourceGPIOA
// CLKOUT used in SPI Data mode of ADF7021 // CLKOUT used in SPI Data mode of ADF7021
#define PIN_CLKOUT GPIO_Pin_15 #define PIN_CLKOUT GPIO_Pin_15
#define PORT_CLKOUT GPIOA #define PORT_CLKOUT GPIOA
@ -237,6 +252,15 @@ extern "C" {
} }
#endif #endif
#if defined(DUPLEX)
void EXTI9_5_IRQHandler(void) {
if(EXTI_GetITStatus(EXTI_Line5)!=RESET) {
io.interrupt2();
EXTI_ClearITPendingBit(EXTI_Line5);
}
}
#endif
#endif #endif
} }
@ -256,7 +280,8 @@ void CIO::Init()
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
EXTI_InitTypeDef EXTI_InitStructure; EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitTypeDef EXTI_InitStructure2;
GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitTypeDef GPIO_InitStruct;
GPIO_StructInit(&GPIO_InitStruct); GPIO_StructInit(&GPIO_InitStruct);
@ -297,6 +322,20 @@ void CIO::Init()
GPIO_InitStruct.GPIO_Pin = PIN_SLE; GPIO_InitStruct.GPIO_Pin = PIN_SLE;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(PORT_SLE, &GPIO_InitStruct); GPIO_Init(PORT_SLE, &GPIO_InitStruct);
#if defined(DUPLEX)
// Pin SLE2
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Pin = PIN_SLE2;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(PORT_SLE2, &GPIO_InitStruct);
// Pin RXD2
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Pin = PIN_RXD2;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(PORT_RXD2, &GPIO_InitStruct);
#endif
// Pin CE // Pin CE
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
@ -320,6 +359,9 @@ void CIO::Init()
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
#endif #endif
GPIO_Init(PORT_TXD, &GPIO_InitStruct); GPIO_Init(PORT_TXD, &GPIO_InitStruct);
#if defined(DUPLEX)
GPIO_Init(PORT_TXD2, &GPIO_InitStruct);
#endif
// Pin TXRX_CLK // Pin TXRX_CLK
#if !defined(BIDIR_DATA_PIN) #if !defined(BIDIR_DATA_PIN)
@ -405,17 +447,32 @@ void CIO::Init()
EXTI_InitStructure.EXTI_Line = EXTI_Line15; EXTI_InitStructure.EXTI_Line = EXTI_Line15;
#endif #endif
#if defined(DUPLEX)
// Connect EXTI5 Line
GPIO_EXTILineConfig(PORT_TXD2_INT, PIN_TXD2_INT);
// Configure EXT5 line
EXTI_InitStructure2.EXTI_Line = EXTI_Line5;
#endif
#endif #endif
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE; EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure); EXTI_Init(&EXTI_InitStructure);
#if defined(DUPLEX)
EXTI_InitStructure2.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure2.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_InitStructure2.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure2);
#endif
} }
void CIO::startInt() void CIO::startInt()
{ {
NVIC_InitTypeDef NVIC_InitStructure; NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure2;
#if defined(PI_HAT_7021_REV_02) #if defined(PI_HAT_7021_REV_02)
@ -431,12 +488,23 @@ void CIO::startInt()
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
#endif #endif
#if defined(DUPLEX)
NVIC_InitStructure2.NVIC_IRQChannel = EXTI9_5_IRQn;
#endif
#endif #endif
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 15; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 15;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure); NVIC_Init(&NVIC_InitStructure);
#if defined(DUPLEX)
NVIC_InitStructure2.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure2.NVIC_IRQChannelSubPriority = 15;
NVIC_InitStructure2.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure2);
#endif
} }
#if defined(BIDIR_DATA_PIN) #if defined(BIDIR_DATA_PIN)
@ -477,6 +545,18 @@ void CIO::SLE_pin(bool on)
GPIO_WriteBit(PORT_SLE, PIN_SLE, on ? Bit_SET : Bit_RESET); GPIO_WriteBit(PORT_SLE, PIN_SLE, on ? Bit_SET : Bit_RESET);
} }
#if defined(DUPLEX)
void CIO::SLE2_pin(bool on)
{
GPIO_WriteBit(PORT_SLE2, PIN_SLE2, on ? Bit_SET : Bit_RESET);
}
bool CIO::RXD2_pin()
{
return GPIO_ReadInputDataBit(PORT_RXD2, PIN_RXD2) == Bit_SET;
}
#endif
void CIO::CE_pin(bool on) void CIO::CE_pin(bool on)
{ {
GPIO_WriteBit(PORT_CE, PIN_CE, on ? Bit_SET : Bit_RESET); GPIO_WriteBit(PORT_CE, PIN_CE, on ? Bit_SET : Bit_RESET);

View file

@ -231,7 +231,9 @@ uint8_t CSerialPort::setConfig(const uint8_t* data, uint8_t length)
if (colorCode > 15U) if (colorCode > 15U)
return 4U; return 4U;
#if defined(DUPLEX)
uint8_t dmrDelay = data[7U]; uint8_t dmrDelay = data[7U];
#endif
m_modemState = modemState; m_modemState = modemState;