enable ADF7021 AFC (this can be disabled in Defines.h); correct issues with DMR Rx in both DMO and duplex modes;

pull/2/head
Bryan Biedenkapp 5 years ago
parent f95e6f03cf
commit 438c525a70

@ -967,7 +967,6 @@ void IO::configureTxRx(DVM_STATE modemState)
ADF7021_REG4 |= (uint32_t)(dmrDiscBW & 0x3FFU) << 10; // discriminator BW ADF7021_REG4 |= (uint32_t)(dmrDiscBW & 0x3FFU) << 10; // discriminator BW
ADF7021_REG4 |= (uint32_t)(dmrPostBW & 0xFFFU) << 20; // post demod BW ADF7021_REG4 |= (uint32_t)(dmrPostBW & 0xFFFU) << 20; // post demod BW
ADF7021_REG4 |= (uint32_t)0b00 << 30; // IF filter (12.5 kHz) ADF7021_REG4 |= (uint32_t)0b00 << 30; // IF filter (12.5 kHz)
//ADF7021_REG4 |= (uint32_t)0b10 << 30; // IF filter (25 kHz)
/* /*
** 3FSK/4FSK Demod (Register 13) ** 3FSK/4FSK Demod (Register 13)
@ -983,11 +982,7 @@ void IO::configureTxRx(DVM_STATE modemState)
ADF7021_REG2 |= (uint32_t)0b110001 << 7; // PA ADF7021_REG2 |= (uint32_t)0b110001 << 7; // PA
ADF7021_REG2 |= (uint32_t)0b10 << 28; // invert data (and RC alpha = 0.5) ADF7021_REG2 |= (uint32_t)0b10 << 28; // invert data (and RC alpha = 0.5)
ADF7021_REG2 |= (uint32_t)(dmrDev / div2) << 19; // deviation ADF7021_REG2 |= (uint32_t)(dmrDev / div2) << 19; // deviation
#if defined(ADF7021_DISABLE_RC_4FSK)
ADF7021_REG2 |= (uint32_t)0b011 << 4; // modulation (4FSK)
#else
ADF7021_REG2 |= (uint32_t)0b111 << 4; // modulation (RC 4FSK) ADF7021_REG2 |= (uint32_t)0b111 << 4; // modulation (RC 4FSK)
#endif
} }
break; break;
@ -1027,11 +1022,7 @@ void IO::configureTxRx(DVM_STATE modemState)
ADF7021_REG2 |= (uint32_t)0b110001 << 7; // PA ADF7021_REG2 |= (uint32_t)0b110001 << 7; // PA
ADF7021_REG2 |= (uint32_t)0b10 << 28; // invert data (and RC alpha = 0.5) ADF7021_REG2 |= (uint32_t)0b10 << 28; // invert data (and RC alpha = 0.5)
ADF7021_REG2 |= (uint32_t)(p25Dev / div2) << 19; // deviation ADF7021_REG2 |= (uint32_t)(p25Dev / div2) << 19; // deviation
#if defined(ADF7021_DISABLE_RC_4FSK)
ADF7021_REG2 |= (uint32_t)0b011 << 4; // modulation (4FSK)
#else
ADF7021_REG2 |= (uint32_t)0b111 << 4; // modulation (RC 4FSK) ADF7021_REG2 |= (uint32_t)0b111 << 4; // modulation (RC 4FSK)
#endif
} }
break; break;
default: // GMSK default: // GMSK

@ -85,15 +85,32 @@
#define ADF_BIT_READ(value, bit) (((value) >> (bit)) & 0x01) #define ADF_BIT_READ(value, bit) (((value) >> (bit)) & 0x01)
#if defined(ADF7021_DISABLE_RC_4FSK)
#define ADF7021_EVEN_BIT true
#else
#define ADF7021_EVEN_BIT false #define ADF7021_EVEN_BIT false
#endif // ADF7021_DISABLE_RC_4FSK
#define ADF7021_DISC_BW_MAX 660 #define ADF7021_DISC_BW_MAX 660
#define ADF7021_POST_BW_MAX 1023 #define ADF7021_POST_BW_MAX 1023
#if defined(ADF7021_ENABLE_4FSK_AFC)
#if defined(ADF7021_AFC_POS)
#define AFC_OFFSET_DMR -125
#define AFC_OFFSET_P25 -125
#else
#define AFC_OFFSET_DMR 125
#define AFC_OFFSET_P25 125
#endif // ADF7021_AFC_POS
#else
#define AFC_OFFSET_DMR 0
#define AFC_OFFSET_P25 0
#endif // ADF7021_ENABLE_4FSK_AFC
/* /*
- Most of the registers values are obteined from ADI eval software: - Most of the registers values are obteined from ADI eval software:
http://www.analog.com/en/products/rf-microwave/integrated-transceivers-transmitters-receivers/low-power-rf-transceivers/adf7021.html http://www.analog.com/en/products/rf-microwave/integrated-transceivers-transmitters-receivers/low-power-rf-transceivers/adf7021.html
@ -198,24 +215,10 @@
#define ADF7021_REG10_DMR 0x01FE473A #define ADF7021_REG10_DMR 0x01FE473A
#define ADF7021_REG10_P25 0x01FE473A #define ADF7021_REG10_P25 0x01FE473A
#if defined(ADF7021_AFC_POS)
#define AFC_OFFSET_DMR -250
#define AFC_OFFSET_P25 -250
#else
#define AFC_OFFSET_DMR 250
#define AFC_OFFSET_P25 250
#endif // ADF7021_AFC_POS
#else #else
#define ADF7021_REG10_DMR 0x049E472A #define ADF7021_REG10_DMR 0x049E472A
#define ADF7021_REG10_P25 0x049E472A #define ADF7021_REG10_P25 0x049E472A
#define AFC_OFFSET_DMR 0
#define AFC_OFFSET_P25 0
#endif // ADF7021_ENABLE_4FSK_AFC #endif // ADF7021_ENABLE_4FSK_AFC
@ -307,24 +310,10 @@
#define ADF7021_REG10_DMR 0x01FE557A #define ADF7021_REG10_DMR 0x01FE557A
#define ADF7021_REG10_P25 0x01FE557A #define ADF7021_REG10_P25 0x01FE557A
#if defined(ADF7021_AFC_POS)
#define AFC_OFFSET_DMR -250
#define AFC_OFFSET_P25 -250
#else
#define AFC_OFFSET_DMR 250
#define AFC_OFFSET_P25 250
#endif // ADF7021_AFC_POS
#else #else
#define ADF7021_REG10_DMR 0x049E556A #define ADF7021_REG10_DMR 0x049E556A
#define ADF7021_REG10_P25 0x049E556A #define ADF7021_REG10_P25 0x049E556A
#define AFC_OFFSET_DMR 0
#define AFC_OFFSET_P25 0
#endif // ADF7021_ENABLE_4FSK_AFC #endif // ADF7021_ENABLE_4FSK_AFC

@ -111,17 +111,13 @@ typedef unsigned long long ulong64_t;
// #define ADF7021_12_2880 // #define ADF7021_12_2880
// Enable full duplex support with dual ADF7021 (valid for homebrew hotspots only) // Enable full duplex support with dual ADF7021 (valid for homebrew hotspots only)
// #define DUPLEX #define DUPLEX
// Disable TX Raised Cosine filter for 4FSK modulation in ADF7021
// #define ADF7021_DISABLE_RC_4FSK
// Support for ADF7021-N version: // Support for ADF7021-N version:
// #define ADF7021_N_VER // #define ADF7021_N_VER
// Enable AFC support for DMR, YSF, P25, and M17 (experimental) // Enable AFC support for DMR and P25 (experimental)
// (AFC is already enabled by default in D-Star) #define ADF7021_ENABLE_4FSK_AFC
// #define ADF7021_ENABLE_4FSK_AFC
// Configure AFC with positive initial frequency offset // Configure AFC with positive initial frequency offset
// #define ADF7021_AFC_POS // #define ADF7021_AFC_POS
@ -146,6 +142,6 @@ const uint8_t BIT_MASK_TABLE[] = { 0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x0
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
#define _WRITE_BIT(p, i, b) p[(i) >> 3] = (b) ? (p[(i) >> 3] | BIT_MASK_TABLE[(i) & 7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i) & 7]) #define _WRITE_BIT(p, i, b) p[(i) >> 3] = (b) ? (p[(i) >> 3] | BIT_MASK_TABLE[(i) & 7]) : (p[(i)>>3] & ~BIT_MASK_TABLE[(i) & 7])
#define _READ_BIT(p, i) (p[(i) >> 3] & BIT_MASK_TABLE[(i) & 7]) #define _READ_BIT(p, i) ((p[(i) >> 3] & BIT_MASK_TABLE[(i) & 7]) >> (7 - ((i) & 7)))
#endif // __DEFINES_H__ #endif // __DEFINES_H__

@ -69,6 +69,9 @@ const uint8_t MARK_SLOT1 = 0x08U;
const uint8_t MARK_SLOT2 = 0x04U; const uint8_t MARK_SLOT2 = 0x04U;
const uint8_t MARK_NONE = 0x00U; const uint8_t MARK_NONE = 0x00U;
const uint8_t CONTROL_SLOT1 = 0x00U;
const uint8_t CONTROL_SLOT2 = 0x01U;
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Macros // Macros
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------

@ -246,12 +246,6 @@ void DMRDMORX::setColorCode(uint8_t colorCode)
/// </summary> /// </summary>
void DMRDMORX::correlateSync() void DMRDMORX::correlateSync()
{ {
uint8_t errs = countBits32((m_bitBuffer & DMR_SYNC_BITS_MASK) ^ DMR_MS_DATA_SYNC_BITS);
// The voice sync is the complement of the data sync
bool data = (errs <= MAX_SYNC_BYTES_ERRS);
bool voice = (errs >= (DMR_SYNC_LENGTH_SYMBOLS - MAX_SYNC_BYTES_ERRS));
// unpack sync bytes // unpack sync bytes
uint8_t sync[DMR_SYNC_BYTES_LENGTH]; uint8_t sync[DMR_SYNC_BYTES_LENGTH];
sync[0U] = (uint8_t)((m_bitBuffer >> 48) & 0xFFU); sync[0U] = (uint8_t)((m_bitBuffer >> 48) & 0xFFU);
@ -262,58 +256,55 @@ void DMRDMORX::correlateSync()
sync[5U] = (uint8_t)((m_bitBuffer >> 8) & 0xFFU); sync[5U] = (uint8_t)((m_bitBuffer >> 8) & 0xFFU);
sync[6U] = (uint8_t)((m_bitBuffer >> 0) & 0xFFU); sync[6U] = (uint8_t)((m_bitBuffer >> 0) & 0xFFU);
if (data) { if ((countBits64((m_bitBuffer & DMR_SYNC_BITS_MASK) ^ DMR_MS_DATA_SYNC_BITS) <= MAX_SYNC_BYTES_ERRS) ||
(countBits64((m_bitBuffer & DMR_SYNC_BITS_MASK) ^ DMR_S2_DATA_SYNC_BITS) <= MAX_SYNC_BYTES_ERRS)) {
uint8_t errs = 0U; uint8_t errs = 0U;
for (uint8_t i = 0U; i < DMR_SYNC_BYTES_LENGTH; i++) for (uint8_t i = 0U; i < DMR_SYNC_BYTES_LENGTH; i++)
errs += countBits8((sync[i] & DMR_SYNC_BYTES_MASK[i]) ^ DMR_MS_DATA_SYNC_BYTES[i]); errs += countBits8((sync[i] & DMR_SYNC_BYTES_MASK[i]) ^ DMR_MS_DATA_SYNC_BYTES[i]);
if (errs <= MAX_SYNC_BYTES_ERRS) { DEBUG2("DMRDMORX: correlateSync(): correlateSync errs", errs);
DEBUG2("DMRDMORX: correlateSync(): correlateSync errs", errs);
DEBUG4("DMRDMORX: correlateSync(): sync [b0 - b2]", sync[0], sync[1], sync[2]); DEBUG4("DMRDMORX: correlateSync(): sync [b0 - b2]", sync[0], sync[1], sync[2]);
DEBUG4("DMRDMORX: correlateSync(): sync [b3 - b5]", sync[3], sync[4], sync[5]); DEBUG4("DMRDMORX: correlateSync(): sync [b3 - b5]", sync[3], sync[4], sync[5]);
DEBUG2("DMRDMORX: correlateSync(): sync [b6]", sync[6]); DEBUG2("DMRDMORX: correlateSync(): sync [b6]", sync[6]);
m_control = CONTROL_DATA; m_control = CONTROL_DATA;
m_syncPtr = m_dataPtr; m_syncPtr = m_dataPtr;
m_startPtr = m_dataPtr + DMO_BUFFER_LENGTH_BITS - DMR_SLOT_TYPE_LENGTH_BITS / 2U - DMR_INFO_LENGTH_BITS / 2U - DMR_SYNC_LENGTH_BITS + 1; m_startPtr = m_dataPtr + DMO_BUFFER_LENGTH_BITS - DMR_SLOT_TYPE_LENGTH_BITS / 2U - DMR_INFO_LENGTH_BITS / 2U - DMR_SYNC_LENGTH_BITS + 1;
if (m_startPtr >= DMO_BUFFER_LENGTH_BITS) if (m_startPtr >= DMO_BUFFER_LENGTH_BITS)
m_startPtr -= DMO_BUFFER_LENGTH_BITS; m_startPtr -= DMO_BUFFER_LENGTH_BITS;
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;
if (m_endPtr >= DMO_BUFFER_LENGTH_BITS) if (m_endPtr >= DMO_BUFFER_LENGTH_BITS)
m_endPtr -= DMO_BUFFER_LENGTH_BITS; m_endPtr -= DMO_BUFFER_LENGTH_BITS;
DEBUG4("DMRDMORX: correlateSync(): dataPtr/startPtr/endPtr", m_dataPtr, m_startPtr, m_endPtr); DEBUG4("DMRDMORX: correlateSync(): dataPtr/startPtr/endPtr", m_dataPtr, m_startPtr, m_endPtr);
} } else if ((countBits64((m_bitBuffer & DMR_SYNC_BITS_MASK) ^ DMR_MS_VOICE_SYNC_BITS) <= MAX_SYNC_BYTES_ERRS) ||
} (countBits64((m_bitBuffer & DMR_SYNC_BITS_MASK) ^ DMR_S2_VOICE_SYNC_BITS) <= MAX_SYNC_BYTES_ERRS)) {
else {
uint8_t errs = 0U; uint8_t errs = 0U;
for (uint8_t i = 0U; i < DMR_SYNC_BYTES_LENGTH; i++) for (uint8_t i = 0U; i < DMR_SYNC_BYTES_LENGTH; i++)
errs += countBits8((sync[i] & DMR_SYNC_BYTES_MASK[i]) ^ DMR_MS_VOICE_SYNC_BYTES[i]); errs += countBits8((sync[i] & DMR_SYNC_BYTES_MASK[i]) ^ DMR_MS_VOICE_SYNC_BYTES[i]);
if (errs <= MAX_SYNC_BYTES_ERRS) { DEBUG2("DMRDMORX: correlateSync(): correlateSync errs", errs);
DEBUG2("DMRDMORX: correlateSync(): correlateSync errs", errs);
DEBUG4("DMRDMORX: correlateSync(): sync [b0 - b2]", sync[0], sync[1], sync[2]); DEBUG4("DMRDMORX: correlateSync(): sync [b0 - b2]", sync[0], sync[1], sync[2]);
DEBUG4("DMRDMORX: correlateSync(): sync [b3 - b5]", sync[3], sync[4], sync[5]); DEBUG4("DMRDMORX: correlateSync(): sync [b3 - b5]", sync[3], sync[4], sync[5]);
DEBUG2("DMRDMORX: correlateSync(): sync [b6]", sync[6]); DEBUG2("DMRDMORX: correlateSync(): sync [b6]", sync[6]);
m_control = CONTROL_VOICE; m_control = CONTROL_VOICE;
m_syncPtr = m_dataPtr; m_syncPtr = m_dataPtr;
m_startPtr = m_dataPtr + DMO_BUFFER_LENGTH_BITS - DMR_SLOT_TYPE_LENGTH_BITS / 2U - DMR_INFO_LENGTH_BITS / 2U - DMR_SYNC_LENGTH_BITS + 1; m_startPtr = m_dataPtr + DMO_BUFFER_LENGTH_BITS - DMR_SLOT_TYPE_LENGTH_BITS / 2U - DMR_INFO_LENGTH_BITS / 2U - DMR_SYNC_LENGTH_BITS + 1;
if (m_startPtr >= DMO_BUFFER_LENGTH_BITS) if (m_startPtr >= DMO_BUFFER_LENGTH_BITS)
m_startPtr -= DMO_BUFFER_LENGTH_BITS; m_startPtr -= DMO_BUFFER_LENGTH_BITS;
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;
if (m_endPtr >= DMO_BUFFER_LENGTH_BITS) if (m_endPtr >= DMO_BUFFER_LENGTH_BITS)
m_endPtr -= DMO_BUFFER_LENGTH_BITS; m_endPtr -= DMO_BUFFER_LENGTH_BITS;
DEBUG4("DMRDMORX: correlateSync(): dataPtr/startPtr/endPtr", m_dataPtr, m_startPtr, m_endPtr); DEBUG4("DMRDMORX: correlateSync(): dataPtr/startPtr/endPtr", m_dataPtr, m_startPtr, m_endPtr);
} }
}
} }
/// <summary> /// <summary>

@ -80,12 +80,12 @@ namespace dmr
const uint8_t DMR_MS_VOICE_SYNC_BYTES[] = { 0x07U, 0xF7U, 0xD5U, 0xDDU, 0x57U, 0xDFU, 0xD0U }; const uint8_t DMR_MS_VOICE_SYNC_BYTES[] = { 0x07U, 0xF7U, 0xD5U, 0xDDU, 0x57U, 0xDFU, 0xD0U };
const uint8_t DMR_BS_DATA_SYNC_BYTES[] = { 0x0DU, 0xFFU, 0x57U, 0xD7U, 0x5DU, 0xF5U, 0xD0U }; const uint8_t DMR_BS_DATA_SYNC_BYTES[] = { 0x0DU, 0xFFU, 0x57U, 0xD7U, 0x5DU, 0xF5U, 0xD0U };
const uint8_t DMR_BS_VOICE_SYNC_BYTES[] = { 0x07U, 0x55U, 0xFDU, 0x7DU, 0xF7U, 0x5FU, 0x70U }; const uint8_t DMR_BS_VOICE_SYNC_BYTES[] = { 0x07U, 0x55U, 0xFDU, 0x7DU, 0xF7U, 0x5FU, 0x70U };
/*
const uint8_t DMR_S1_DATA_SYNC_BYTES[] = { 0x0FU, 0x7FU, 0xDDU, 0x5DU, 0xDFU, 0xD5U, 0x50U }; const uint8_t DMR_S1_DATA_SYNC_BYTES[] = { 0x0FU, 0x7FU, 0xDDU, 0x5DU, 0xDFU, 0xD5U, 0x50U };
const uint8_t DMR_S1_VOICE_SYNC_BYTES[] = { 0x05U, 0xD5U, 0x77U, 0xF7U, 0x75U, 0x7FU, 0xF0U }; const uint8_t DMR_S1_VOICE_SYNC_BYTES[] = { 0x05U, 0xD5U, 0x77U, 0xF7U, 0x75U, 0x7FU, 0xF0U };
const uint8_t DMR_S2_DATA_SYNC_BYTES[] = { 0x0DU, 0x75U, 0x57U, 0xF5U, 0xFFU, 0x7FU, 0x50U }; const uint8_t DMR_S2_DATA_SYNC_BYTES[] = { 0x0DU, 0x75U, 0x57U, 0xF5U, 0xFFU, 0x7FU, 0x50U };
const uint8_t DMR_S2_VOICE_SYNC_BYTES[] = { 0x07U, 0xDFU, 0xFDU, 0x5FU, 0x55U, 0xD5U, 0xF0U }; const uint8_t DMR_S2_VOICE_SYNC_BYTES[] = { 0x07U, 0xDFU, 0xFDU, 0x5FU, 0x55U, 0xD5U, 0xF0U };
*/
const uint8_t DMR_SYNC_BYTES_MASK[] = { 0x0FU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xF0U }; const uint8_t DMR_SYNC_BYTES_MASK[] = { 0x0FU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xF0U };
const uint8_t DMR_START_SYNC = 0x5FU; const uint8_t DMR_START_SYNC = 0x5FU;
@ -94,12 +94,24 @@ namespace dmr
const uint64_t DMR_MS_VOICE_SYNC_BITS = 0x00007F7D5DD57DFDU; const uint64_t DMR_MS_VOICE_SYNC_BITS = 0x00007F7D5DD57DFDU;
const uint64_t DMR_BS_DATA_SYNC_BITS = 0x0000DFF57D75DF5DU; const uint64_t DMR_BS_DATA_SYNC_BITS = 0x0000DFF57D75DF5DU;
const uint64_t DMR_BS_VOICE_SYNC_BITS = 0x0000755FD7DF75F7U; const uint64_t DMR_BS_VOICE_SYNC_BITS = 0x0000755FD7DF75F7U;
const uint64_t DMR_S1_DATA_SYNC_BITS = 0x0000F7FDD5DDFD55U;
const uint64_t DMR_S1_VOICE_SYNC_BITS = 0x00005D577F7757FFU;
const uint64_t DMR_S2_DATA_SYNC_BITS = 0x0000D7557F5FF7F5U;
const uint64_t DMR_S2_VOICE_SYNC_BITS = 0x00007DFFD5F55D5FU;
const uint64_t DMR_SYNC_BITS_MASK = 0x0000FFFFFFFFFFFFU; const uint64_t DMR_SYNC_BITS_MASK = 0x0000FFFFFFFFFFFFU;
const uint32_t DMR_MS_DATA_SYNC_SYMBOLS = 0x0076286EU; const uint32_t DMR_MS_DATA_SYNC_SYMBOLS = 0x0076286EU;
const uint32_t DMR_MS_VOICE_SYNC_SYMBOLS = 0x0089D791U; const uint32_t DMR_MS_VOICE_SYNC_SYMBOLS = 0x0089D791U;
const uint32_t DMR_BS_DATA_SYNC_SYMBOLS = 0x00439B4DU; const uint32_t DMR_BS_DATA_SYNC_SYMBOLS = 0x00439B4DU;
const uint32_t DMR_BS_VOICE_SYNC_SYMBOLS = 0x00BC64B2U; const uint32_t DMR_BS_VOICE_SYNC_SYMBOLS = 0x00BC64B2U;
const uint32_t DMR_S1_DATA_SYNC_SYMBOLS = 0x0021751FU;
const uint32_t DMR_S1_VOICE_SYNC_SYMBOLS = 0x00DE8AE0U;
const uint32_t DMR_S2_DATA_SYNC_SYMBOLS = 0x006F8C23U;
const uint32_t DMR_S2_VOICE_SYNC_SYMBOLS = 0x009073DCU;
const uint32_t DMR_SYNC_SYMBOLS_MASK = 0x00FFFFFFU; const uint32_t DMR_SYNC_SYMBOLS_MASK = 0x00FFFFFFU;
// D 5 D 7 F 7 7 F D 7 5 7 // D 5 D 7 F 7 7 F D 7 5 7

@ -67,12 +67,12 @@ void DMRRX::databit(bool bit, const uint8_t control)
{ {
bool dcd1 = false; bool dcd1 = false;
bool dcd2 = false; bool dcd2 = false;
switch (control) { switch (control) {
case MARK_SLOT1: case CONTROL_SLOT1:
m_slot1RX.start(); m_slot1RX.start();
break; break;
case MARK_SLOT2: case CONTROL_SLOT2:
m_slot2RX.start(); m_slot2RX.start();
break; break;
default: default:

@ -286,12 +286,6 @@ void DMRSlotRX::setRxDelay(uint8_t delay)
/// <param name="first"></param> /// <param name="first"></param>
void DMRSlotRX::correlateSync() void DMRSlotRX::correlateSync()
{ {
uint8_t errs = countBits32((m_bitBuffer & DMR_SYNC_BITS_MASK) ^ DMR_MS_DATA_SYNC_BITS);
// The voice sync is the complement of the data sync
bool data = (errs <= MAX_SYNC_BYTES_ERRS);
bool voice = (errs >= (DMR_SYNC_LENGTH_SYMBOLS - MAX_SYNC_BYTES_ERRS));
// unpack sync bytes // unpack sync bytes
uint8_t sync[DMR_SYNC_BYTES_LENGTH]; uint8_t sync[DMR_SYNC_BYTES_LENGTH];
sync[0U] = (uint8_t)((m_bitBuffer >> 48) & 0xFFU); sync[0U] = (uint8_t)((m_bitBuffer >> 48) & 0xFFU);
@ -302,57 +296,52 @@ void DMRSlotRX::correlateSync()
sync[5U] = (uint8_t)((m_bitBuffer >> 8) & 0xFFU); sync[5U] = (uint8_t)((m_bitBuffer >> 8) & 0xFFU);
sync[6U] = (uint8_t)((m_bitBuffer >> 0) & 0xFFU); sync[6U] = (uint8_t)((m_bitBuffer >> 0) & 0xFFU);
if (data) { if (countBits64((m_bitBuffer & DMR_SYNC_BITS_MASK) ^ DMR_MS_DATA_SYNC_BITS) <= MAX_SYNC_BYTES_ERRS) {
uint8_t errs = 0U; uint8_t errs = 0U;
for (uint8_t i = 0U; i < DMR_SYNC_BYTES_LENGTH; i++) for (uint8_t i = 0U; i < DMR_SYNC_BYTES_LENGTH; i++)
errs += countBits8((sync[i] & DMR_SYNC_BYTES_MASK[i]) ^ DMR_MS_DATA_SYNC_BYTES[i]); errs += countBits8((sync[i] & DMR_SYNC_BYTES_MASK[i]) ^ DMR_MS_DATA_SYNC_BYTES[i]);
if (errs <= MAX_SYNC_BYTES_ERRS) { DEBUG2("DMRSlotRX: correlateSync(): correlateSync errs", errs);
DEBUG3("DMRSlotRX: correlateSync(): correlateSync slot/errs", m_slot ? 2U : 1U, errs);
DEBUG4("DMRSlotRX: correlateSync(): sync [b0 - b2]", sync[0], sync[1], sync[2]); DEBUG4("DMRSlotRX: correlateSync(): sync [b0 - b2]", sync[0], sync[1], sync[2]);
DEBUG4("DMRSlotRX: correlateSync(): sync [b3 - b5]", sync[3], sync[4], sync[5]); DEBUG4("DMRSlotRX: correlateSync(): sync [b3 - b5]", sync[3], sync[4], sync[5]);
DEBUG2("DMRSlotRX: correlateSync(): sync [b6]", sync[6]); DEBUG2("DMRSlotRX: correlateSync(): sync [b6]", sync[6]);
m_control = CONTROL_DATA; m_control = CONTROL_DATA;
m_syncPtr = m_dataPtr; m_syncPtr = m_dataPtr;
m_startPtr = m_dataPtr + DMR_BUFFER_LENGTH_BITS - DMR_SLOT_TYPE_LENGTH_BITS / 2U - DMR_INFO_LENGTH_BITS / 2U - DMR_SYNC_LENGTH_BITS + 1; m_startPtr = m_dataPtr + DMR_BUFFER_LENGTH_BITS - DMR_SLOT_TYPE_LENGTH_BITS / 2U - DMR_INFO_LENGTH_BITS / 2U - DMR_SYNC_LENGTH_BITS + 1;
if (m_startPtr >= DMR_BUFFER_LENGTH_BITS) if (m_startPtr >= DMR_BUFFER_LENGTH_BITS)
m_startPtr -= DMR_BUFFER_LENGTH_BITS; m_startPtr -= DMR_BUFFER_LENGTH_BITS;
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;
if (m_endPtr >= DMR_BUFFER_LENGTH_BITS) if (m_endPtr >= DMR_BUFFER_LENGTH_BITS)
m_endPtr -= DMR_BUFFER_LENGTH_BITS; m_endPtr -= DMR_BUFFER_LENGTH_BITS;
DEBUG4("DMRSlotRX: correlateSync(): dataPtr/startPtr/endPtr", m_dataPtr, m_startPtr, m_endPtr); DEBUG4("DMRSlotRX: correlateSync(): dataPtr/startPtr/endPtr", m_dataPtr, m_startPtr, m_endPtr);
} } else if (countBits64((m_bitBuffer & DMR_SYNC_BITS_MASK) ^ DMR_MS_VOICE_SYNC_BITS) <= MAX_SYNC_BYTES_ERRS) {
}
else {
uint8_t errs = 0U; uint8_t errs = 0U;
for (uint8_t i = 0U; i < DMR_SYNC_BYTES_LENGTH; i++) for (uint8_t i = 0U; i < DMR_SYNC_BYTES_LENGTH; i++)
errs += countBits8((sync[i] & DMR_SYNC_BYTES_MASK[i]) ^ DMR_MS_VOICE_SYNC_BYTES[i]); errs += countBits8((sync[i] & DMR_SYNC_BYTES_MASK[i]) ^ DMR_MS_VOICE_SYNC_BYTES[i]);
if (errs <= MAX_SYNC_BYTES_ERRS) { DEBUG2("DMRSlotRX: correlateSync(): correlateSync errs", errs);
DEBUG3("DMRSlotRX: correlateSync(): correlateSync slot/errs", m_slot ? 2U : 1U, errs);
DEBUG4("DMRSlotRX: correlateSync(): sync [b0 - b2]", sync[0], sync[1], sync[2]); DEBUG4("DMRSlotRX: correlateSync(): sync [b0 - b2]", sync[0], sync[1], sync[2]);
DEBUG4("DMRSlotRX: correlateSync(): sync [b3 - b5]", sync[3], sync[4], sync[5]); DEBUG4("DMRSlotRX: correlateSync(): sync [b3 - b5]", sync[3], sync[4], sync[5]);
DEBUG2("DMRSlotRX: correlateSync(): sync [b6]", sync[6]); DEBUG2("DMRSlotRX: correlateSync(): sync [b6]", sync[6]);
m_control = CONTROL_VOICE; m_control = CONTROL_VOICE;
m_syncPtr = m_dataPtr; m_syncPtr = m_dataPtr;
m_startPtr = m_dataPtr + DMR_BUFFER_LENGTH_BITS - DMR_SLOT_TYPE_LENGTH_BITS / 2U - DMR_INFO_LENGTH_BITS / 2U - DMR_SYNC_LENGTH_BITS + 1; m_startPtr = m_dataPtr + DMR_BUFFER_LENGTH_BITS - DMR_SLOT_TYPE_LENGTH_BITS / 2U - DMR_INFO_LENGTH_BITS / 2U - DMR_SYNC_LENGTH_BITS + 1;
if (m_startPtr >= DMR_BUFFER_LENGTH_BITS) if (m_startPtr >= DMR_BUFFER_LENGTH_BITS)
m_startPtr -= DMR_BUFFER_LENGTH_BITS; m_startPtr -= DMR_BUFFER_LENGTH_BITS;
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;
if (m_endPtr >= DMR_BUFFER_LENGTH_BITS) if (m_endPtr >= DMR_BUFFER_LENGTH_BITS)
m_endPtr -= DMR_BUFFER_LENGTH_BITS; m_endPtr -= DMR_BUFFER_LENGTH_BITS;
DEBUG4("DMRSlotRX: correlateSync(): dataPtr/startPtr/endPtr", m_dataPtr, m_startPtr, m_endPtr); DEBUG4("DMRSlotRX: correlateSync(): dataPtr/startPtr/endPtr", m_dataPtr, m_startPtr, m_endPtr);
}
} }
} }
@ -415,16 +404,10 @@ void DMRSlotRX::bitsToBytes(uint16_t start, uint8_t count, uint8_t* buffer)
void DMRSlotRX::writeRSSIData(uint8_t* frame) void DMRSlotRX::writeRSSIData(uint8_t* frame)
{ {
#if defined(SEND_RSSI_DATA) #if defined(SEND_RSSI_DATA)
// Calculate RSSI average over a burst period. We don't take into account 2.5 ms at the beginning and 2.5 ms at the end uint16_t rssi = io.readRSSI();
uint16_t start = m_startPtr + DMR_SYNC_LENGTH_SAMPLES / 2U;
uint32_t accum = 0U;
for (uint16_t i = 0U; i < (DMR_FRAME_LENGTH_SAMPLES - DMR_SYNC_LENGTH_SAMPLES); i++)
accum += m_rssi[start++];
uint16_t avg = accum / (DMR_FRAME_LENGTH_SAMPLES - DMR_SYNC_LENGTH_SAMPLES); frame[34U] = (rssi >> 8) & 0xFFU;
frame[34U] = (avg >> 8) & 0xFFU; frame[35U] = (rssi >> 0) & 0xFFU;
frame[35U] = (avg >> 0) & 0xFFU;
serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 3U); serial.writeDMRData(m_slot, frame, DMR_FRAME_LENGTH_BYTES + 3U);
#else #else

@ -79,7 +79,7 @@ DMRTX::DMRTX() :
m_frameCount(0U), m_frameCount(0U),
m_abortCount(), m_abortCount(),
m_abort(), m_abort(),
m_control_old(0U) m_controlPrev(MARK_NONE)
{ {
::memcpy(m_newShortLC, EMPTY_SHORT_LC, 12U); ::memcpy(m_newShortLC, EMPTY_SHORT_LC, 12U);
::memcpy(m_shortLC, EMPTY_SHORT_LC, 12U); ::memcpy(m_shortLC, EMPTY_SHORT_LC, 12U);
@ -476,7 +476,7 @@ void DMRTX::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 = m_control_old; uint8_t controlToWrite = m_controlPrev;
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)
@ -486,13 +486,13 @@ void DMRTX::writeByte(uint8_t c, uint8_t control)
if (i == 7U) { if (i == 7U) {
if (control == MARK_SLOT2) if (control == MARK_SLOT2)
control_tmp = true; controlToWrite = true;
else if (control == MARK_SLOT1) else if (control == MARK_SLOT1)
control_tmp = false; controlToWrite = false;
m_control_old = control_tmp; m_controlPrev = controlToWrite;
} }
io.write(&bit, 1, &control_tmp); io.write(&bit, 1, &controlToWrite);
} }
} }

@ -116,7 +116,7 @@ namespace dmr
uint32_t m_abortCount[2U]; uint32_t m_abortCount[2U];
bool m_abort[2U]; bool m_abort[2U];
uint8_t m_control_old; uint8_t m_controlPrev;
/// <summary></summary> /// <summary></summary>
void createData(uint8_t slotIndex); void createData(uint8_t slotIndex);

Loading…
Cancel
Save

Powered by TurnKey Linux.