void CIO::process() { m_ledCount++; if (m_started) { // Two seconds timeout if (m_watchdog >= 48000U) { if (m_modemState == STATE_DSTAR || m_modemState == STATE_DMR || m_modemState == STATE_YSF) { if (m_modemState == STATE_DMR && m_tx) dmrTX.setStart(false); m_modemState = STATE_IDLE; setMode(); } m_watchdog = 0U; } if (m_ledCount >= 24000U) { m_ledCount = 0U; m_ledValue = !m_ledValue; #if defined(__MBED__) m_pinLED.write(m_ledValue ? 1 : 0); #else digitalWrite(PIN_LED, m_ledValue ? HIGH : LOW); #endif } } else { if (m_ledCount >= 240000U) { m_ledCount = 0U; m_ledValue = !m_ledValue; #if defined(__MBED__) m_pinLED.write(m_ledValue ? 1 : 0); #else digitalWrite(PIN_LED, m_ledValue ? HIGH : LOW); #endif } return; } #if defined(USE_COS_AS_LOCKOUT) #if defined(__MBED__) m_lockout = m_pinCOS.read() == 1; #else m_lockout = digitalRead(PIN_COS) == HIGH; #endif #endif // Switch off the transmitter if needed if (m_txBuffer.getData() == 0U && m_tx) { m_tx = false; #if defined(__MBED__) m_pinPTT.write(m_pttInvert ? 1 : 0); #else digitalWrite(PIN_PTT, m_pttInvert ? HIGH : LOW); #endif } if (m_rxBuffer.getData() >= RX_BLOCK_SIZE) { q15_t samples[RX_BLOCK_SIZE + 1U]; uint8_t control[RX_BLOCK_SIZE + 1U]; uint8_t blockSize = RX_BLOCK_SIZE; for (uint16_t i = 0U; i < RX_BLOCK_SIZE; i++) { uint16_t sample; m_rxBuffer.get(sample, control[i]); // Detect ADC overflow if (m_detect && (sample == 0U || sample == 4095U)) m_adcOverflow++; q15_t res1 = q15_t(sample) - DC_OFFSET; q31_t res2 = res1 * m_rxLevel; samples[i] = q15_t(__SSAT((res2 >> 15), 16)); } // Handle the case of the oscillator not being accurate enough if (m_sampleCount > 0U) { m_count += RX_BLOCK_SIZE; if (m_count >= m_sampleCount) { if (m_sampleInsert) { blockSize++; samples[RX_BLOCK_SIZE] = 0; for (int8_t i = RX_BLOCK_SIZE - 1; i >= 0; i--) control[i + 1] = control[i]; } else { blockSize--; for (uint8_t i = 0U; i < (RX_BLOCK_SIZE - 1U); i++) control[i] = control[i + 1U]; } m_count -= m_sampleCount; } } if (m_lockout) return; if (m_modemState == STATE_IDLE) { if (m_dstarEnable) { q15_t GMSKVals[RX_BLOCK_SIZE + 1U]; ::arm_fir_fast_q15(&m_GMSKFilter, samples, GMSKVals, blockSize); dstarRX.samples(GMSKVals, blockSize); } if (m_dmrEnable || m_ysfEnable) { q15_t C4FSKVals[RX_BLOCK_SIZE + 1U]; ::arm_fir_fast_q15(&m_C4FSKFilter, samples, C4FSKVals, blockSize); if (m_dmrEnable) dmrIdleRX.samples(C4FSKVals, blockSize); if (m_ysfEnable) ysfRX.samples(C4FSKVals, blockSize); } } else if (m_modemState == STATE_DSTAR) { if (m_dstarEnable) { q15_t GMSKVals[RX_BLOCK_SIZE + 1U]; ::arm_fir_fast_q15(&m_GMSKFilter, samples, GMSKVals, blockSize); dstarRX.samples(GMSKVals, blockSize); } } else if (m_modemState == STATE_DMR) { if (m_dmrEnable) { q15_t C4FSKVals[RX_BLOCK_SIZE + 1U]; ::arm_fir_fast_q15(&m_C4FSKFilter, samples, C4FSKVals, blockSize); // If the transmitter isn't on, use the DMR idle RX to detect the wakeup CSBKs if (m_tx) dmrRX.samples(C4FSKVals, control, blockSize); else dmrIdleRX.samples(C4FSKVals, blockSize); } } else if (m_modemState == STATE_YSF) { if (m_ysfEnable) { q15_t C4FSKVals[RX_BLOCK_SIZE + 1U]; ::arm_fir_fast_q15(&m_C4FSKFilter, samples, C4FSKVals, blockSize); ysfRX.samples(C4FSKVals, blockSize); } } else if (m_modemState == STATE_DSTARCAL) { q15_t GMSKVals[RX_BLOCK_SIZE + 1U]; ::arm_fir_fast_q15(&m_GMSKFilter, samples, GMSKVals, blockSize); calDStarRX.samples(GMSKVals, blockSize); } }
void CIO::process() { m_ledCount++; if (m_started) { if (m_ledCount >= 24000U) { m_ledCount = 0U; m_ledValue = !m_ledValue; #if defined(__MBED__) m_pinLED.write(m_ledValue ? 1 : 0); #else digitalWrite(PIN_LED, m_ledValue ? HIGH : LOW); #endif } } else { if (m_ledCount >= 240000U) { m_ledCount = 0U; m_ledValue = !m_ledValue; #if defined(__MBED__) m_pinLED.write(m_ledValue ? 1 : 0); #else digitalWrite(PIN_LED, m_ledValue ? HIGH : LOW); #endif } return; } // Switch off the transmitter if needed if (m_txBuffer.getData() == 0U && m_tx) { m_tx = false; #if defined(__MBED__) m_pinPTT.write(m_pttInvert ? 1 : 0); #else digitalWrite(PIN_PTT, m_pttInvert ? HIGH : LOW); #endif } if (m_rxBuffer.getData() >= RX_BLOCK_SIZE) { q15_t samples[RX_BLOCK_SIZE]; uint8_t control[RX_BLOCK_SIZE]; for (uint16_t i = 0U; i < RX_BLOCK_SIZE; i++) { uint16_t sample; m_rxBuffer.get(sample, control[i]); // Detect ADC overflow if (m_dcd && (sample == 0U || sample == 4095U)) m_overflow++; m_overcount++; q15_t res1 = q15_t(sample) - DC_OFFSET; q31_t res2 = res1 * m_rxLevel; samples[i] = q15_t(__SSAT((res2 >> 15), 16)); } if (m_modemState == STATE_IDLE) { if (m_dstarEnable) { q15_t GMSKVals[RX_BLOCK_SIZE]; ::arm_fir_fast_q15(&m_GMSKFilter, samples, GMSKVals, RX_BLOCK_SIZE); dstarRX.samples(GMSKVals, RX_BLOCK_SIZE); } if (m_dmrEnable || m_ysfEnable) { q15_t C4FSKVals[RX_BLOCK_SIZE]; ::arm_fir_fast_q15(&m_C4FSKFilter, samples, C4FSKVals, RX_BLOCK_SIZE); if (m_dmrEnable) dmrIdleRX.samples(C4FSKVals, RX_BLOCK_SIZE); if (m_ysfEnable) ysfRX.samples(C4FSKVals, RX_BLOCK_SIZE); } } else if (m_modemState == STATE_DSTAR) { if (m_dstarEnable) { q15_t GMSKVals[RX_BLOCK_SIZE]; ::arm_fir_fast_q15(&m_GMSKFilter, samples, GMSKVals, RX_BLOCK_SIZE); dstarRX.samples(GMSKVals, RX_BLOCK_SIZE); } } else if (m_modemState == STATE_DMR) { if (m_dmrEnable) { q15_t C4FSKVals[RX_BLOCK_SIZE]; ::arm_fir_fast_q15(&m_C4FSKFilter, samples, C4FSKVals, RX_BLOCK_SIZE); // If the transmitter isn't on, use the DMR idle RX to detect the wakeup CSBKs if (m_tx) dmrRX.samples(C4FSKVals, control, RX_BLOCK_SIZE); else dmrIdleRX.samples(C4FSKVals, RX_BLOCK_SIZE); } } else if (m_modemState == STATE_YSF) { if (m_ysfEnable) { q15_t C4FSKVals[RX_BLOCK_SIZE]; ::arm_fir_fast_q15(&m_C4FSKFilter, samples, C4FSKVals, RX_BLOCK_SIZE); ysfRX.samples(C4FSKVals, RX_BLOCK_SIZE); } } else if (m_modemState == STATE_CALIBRATE) { q15_t GMSKVals[RX_BLOCK_SIZE]; ::arm_fir_fast_q15(&m_GMSKFilter, samples, GMSKVals, RX_BLOCK_SIZE); calRX.samples(GMSKVals, RX_BLOCK_SIZE); } }