Compare commits

..
4 Commits
Author SHA1 Message Date
Jonathan Naylor b971c5bc38 Add kerchunk TX. 2020-06-20 20:31:45 +01:00
Jonathan Naylor 598d32287d Add alternate FM LEDs for the POG board. 2020-06-01 16:55:13 +01:00
Jonathan Naylor 53d8cfa360 Revert IOSTM_CMSIS.cpp to 5c9abf2 2020-06-01 16:51:59 +01:00
Jonathan Naylor 7fabddd7f1 Update the README file. 2020-05-21 11:11:19 +01:00
7 changed files with 197 additions and 135 deletions
+27 -8
View File
@@ -34,6 +34,7 @@ m_callsignTimer(),
m_timeoutTimer(),
m_holdoffTimer(),
m_kerchunkTimer(),
m_kerchunkTX(true),
m_ackMinTimer(),
m_ackDelayTimer(),
m_hangTimer(),
@@ -183,7 +184,7 @@ uint8_t CFM::setAck(const char* rfAck, uint8_t speed, uint16_t frequency, uint8_
return m_rfAck.setParams(rfAck, speed, frequency, level, level);
}
uint8_t CFM::setMisc(uint16_t timeout, uint8_t timeoutLevel, uint8_t ctcssFrequency, uint8_t ctcssHighThreshold, uint8_t ctcssLowThreshold, uint8_t ctcssLevel, uint8_t kerchunkTime, uint8_t hangTime, bool useCOS, bool cosInvert, uint8_t rfAudioBoost, uint8_t maxDev, uint8_t rxLevel)
uint8_t CFM::setMisc(uint16_t timeout, uint8_t timeoutLevel, uint8_t ctcssFrequency, uint8_t ctcssHighThreshold, uint8_t ctcssLowThreshold, uint8_t ctcssLevel, uint8_t kerchunkTime, bool kerchunkTX, uint8_t hangTime, bool useCOS, bool cosInvert, uint8_t rfAudioBoost, uint8_t maxDev, uint8_t rxLevel)
{
m_useCOS = useCOS;
m_cosInvert = cosInvert;
@@ -191,7 +192,10 @@ uint8_t CFM::setMisc(uint16_t timeout, uint8_t timeoutLevel, uint8_t ctcssFreque
m_rfAudioBoost = q15_t(rfAudioBoost);
m_timeoutTimer.setTimeout(timeout, 0U);
m_kerchunkTimer.setTimeout(kerchunkTime, 0U);
m_kerchunkTX = kerchunkTX;
m_hangTimer.setTimeout(hangTime, 0U);
m_timeoutTone.setParams(timeoutLevel);
@@ -275,17 +279,19 @@ void CFM::listeningState(bool validSignal)
sendCallsign();
}
insertSilence(50U);
if (m_state == FS_RELAYING || (m_state == FS_KERCHUNK && m_kerchunkTX)) {
insertSilence(50U);
beginRelaying();
beginRelaying();
m_callsignTimer.start();
m_callsignTimer.start();
io.setDecode(true);
io.setADCDetection(true);
io.setDecode(true);
io.setADCDetection(true);
DEBUG1("Change to STATE_FM");
m_modemState = STATE_FM;
DEBUG1("Change to STATE_FM");
m_modemState = STATE_FM;
}
}
}
@@ -300,6 +306,19 @@ void CFM::kerchunkState(bool validSignal)
sendCallsign();
m_callsignTimer.start();
}
if (!m_kerchunkTX) {
insertSilence(50U);
beginRelaying();
m_callsignTimer.start();
io.setDecode(true);
io.setADCDetection(true);
DEBUG1("Change to STATE_FM");
m_modemState = STATE_FM;
}
}
} else {
io.setDecode(false);
+2 -1
View File
@@ -56,7 +56,7 @@ public:
uint8_t setCallsign(const char* callsign, uint8_t speed, uint16_t frequency, uint8_t time, uint8_t holdoff, uint8_t highLevel, uint8_t lowLevel, bool callsignAtStart, bool callsignAtEnd, bool callsignAtLatch);
uint8_t setAck(const char* rfAck, uint8_t speed, uint16_t frequency, uint8_t minTime, uint16_t delay, uint8_t level);
uint8_t setMisc(uint16_t timeout, uint8_t timeoutLevel, uint8_t ctcssFrequency, uint8_t ctcssHighThreshold, uint8_t ctcssLowThreshold, uint8_t ctcssLevel, uint8_t kerchunkTime, uint8_t hangTime, bool useCOS, bool cosInvert, uint8_t rfAudioBoost, uint8_t maxDev, uint8_t rxLevel);
uint8_t setMisc(uint16_t timeout, uint8_t timeoutLevel, uint8_t ctcssFrequency, uint8_t ctcssHighThreshold, uint8_t ctcssLowThreshold, uint8_t ctcssLevel, uint8_t kerchunkTime, bool kerchunkTX, uint8_t hangTime, bool useCOS, bool cosInvert, uint8_t rfAudioBoost, uint8_t maxDev, uint8_t rxLevel);
private:
CFMKeyer m_callsign;
@@ -72,6 +72,7 @@ private:
CFMTimer m_timeoutTimer;
CFMTimer m_holdoffTimer;
CFMTimer m_kerchunkTimer;
bool m_kerchunkTX;
CFMTimer m_ackMinTimer;
CFMTimer m_ackDelayTimer;
CFMTimer m_hangTimer;
+126 -70
View File
@@ -26,12 +26,31 @@
static q31_t DC_FILTER[] = {3367972, 0, 3367972, 0, 2140747704, 0}; // {b0, 0, b1, b2, -a1, -a2}
const uint32_t DC_FILTER_STAGES = 1U; // One Biquad stage
// One symbol boxcar filters
static q15_t BOXCAR5_FILTER[] = {12000, 12000, 12000, 12000, 12000, 0};
const uint16_t BOXCAR5_FILTER_LEN = 6U;
// Generated using rcosdesign(0.2, 8, 5, 'sqrt') in MATLAB
static q15_t RRC_0_2_FILTER[] = {401, 104, -340, -731, -847, -553, 112, 909, 1472, 1450, 683, -675, -2144, -3040, -2706, -770, 2667, 6995,
11237, 14331, 15464, 14331, 11237, 6995, 2667, -770, -2706, -3040, -2144, -675, 683, 1450, 1472, 909, 112,
-553, -847, -731, -340, 104, 401, 0};
const uint16_t RRC_0_2_FILTER_LEN = 42U;
static q15_t BOXCAR10_FILTER[] = {6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000, 6000};
const uint16_t BOXCAR10_FILTER_LEN = 10U;
// Generated using rcosdesign(0.2, 8, 10, 'sqrt') in MATLAB
static q15_t NXDN_0_2_FILTER[] = {284, 198, 73, -78, -240, -393, -517, -590, -599, -533, -391, -181, 79, 364, 643, 880, 1041, 1097, 1026, 819,
483, 39, -477, -1016, -1516, -1915, -2150, -2164, -1914, -1375, -545, 557, 1886, 3376, 4946, 6502, 7946, 9184,
10134, 10731, 10935, 10731, 10134, 9184, 7946, 6502, 4946, 3376, 1886, 557, -545, -1375, -1914, -2164, -2150,
-1915, -1516, -1016, -477, 39, 483, 819, 1026, 1097, 1041, 880, 643, 364, 79, -181, -391, -533, -599, -590,
-517, -393, -240, -78, 73, 198, 284, 0};
const uint16_t NXDN_0_2_FILTER_LEN = 82U;
static q15_t NXDN_ISINC_FILTER[] = {790, -1085, -1073, -553, 747, 2341, 3156, 2152, -893, -4915, -7834, -7536, -3102, 4441, 12354, 17394, 17394,
12354, 4441, -3102, -7536, -7834, -4915, -893, 2152, 3156, 2341, 747, -553, -1073, -1085, 790};
const uint16_t NXDN_ISINC_FILTER_LEN = 32U;
// Generated using gaussfir(0.5, 4, 5) in MATLAB
static q15_t GAUSSIAN_0_5_FILTER[] = {8, 104, 760, 3158, 7421, 9866, 7421, 3158, 760, 104, 8, 0};
const uint16_t GAUSSIAN_0_5_FILTER_LEN = 12U;
// One symbol boxcar filter
static q15_t BOXCAR_FILTER[] = {12000, 12000, 12000, 12000, 12000, 0};
const uint16_t BOXCAR_FILTER_LEN = 6U;
const uint16_t DC_OFFSET = 2048U;
@@ -42,10 +61,16 @@ m_txBuffer(TX_RINGBUFFER_SIZE),
m_rssiBuffer(RX_RINGBUFFER_SIZE),
m_dcFilter(),
m_dcState(),
m_boxcar5Filter(),
m_boxcar10Filter(),
m_boxcar5State(),
m_boxcar10State(),
m_rrcFilter(),
m_gaussianFilter(),
m_boxcarFilter(),
m_nxdnFilter(),
m_nxdnISincFilter(),
m_rrcState(),
m_gaussianState(),
m_boxcarState(),
m_nxdnState(),
m_nxdnISincState(),
m_pttInvert(false),
m_rxLevel(128 * 128),
m_cwIdTXLevel(128 * 128),
@@ -66,22 +91,37 @@ m_dacOverflow(0U),
m_watchdog(0U),
m_lockout(false)
{
::memset(m_boxcar5State, 0x00U, 30U * sizeof(q15_t));
::memset(m_boxcar10State, 0x00U, 40U * sizeof(q15_t));
::memset(m_dcState, 0x00U, 4U * sizeof(q31_t));
::memset(m_rrcState, 0x00U, 70U * sizeof(q15_t));
::memset(m_gaussianState, 0x00U, 40U * sizeof(q15_t));
::memset(m_boxcarState, 0x00U, 30U * sizeof(q15_t));
::memset(m_nxdnState, 0x00U, 110U * sizeof(q15_t));
::memset(m_nxdnISincState, 0x00U, 60U * sizeof(q15_t));
::memset(m_dcState, 0x00U, 4U * sizeof(q31_t));
m_dcFilter.numStages = DC_FILTER_STAGES;
m_dcFilter.pState = m_dcState;
m_dcFilter.pCoeffs = DC_FILTER;
m_dcFilter.postShift = 0;
m_boxcar5Filter.numTaps = BOXCAR5_FILTER_LEN;
m_boxcar5Filter.pState = m_boxcar5State;
m_boxcar5Filter.pCoeffs = BOXCAR5_FILTER;
m_rrcFilter.numTaps = RRC_0_2_FILTER_LEN;
m_rrcFilter.pState = m_rrcState;
m_rrcFilter.pCoeffs = RRC_0_2_FILTER;
m_boxcar10Filter.numTaps = BOXCAR10_FILTER_LEN;
m_boxcar10Filter.pState = m_boxcar10State;
m_boxcar10Filter.pCoeffs = BOXCAR10_FILTER;
m_gaussianFilter.numTaps = GAUSSIAN_0_5_FILTER_LEN;
m_gaussianFilter.pState = m_gaussianState;
m_gaussianFilter.pCoeffs = GAUSSIAN_0_5_FILTER;
m_boxcarFilter.numTaps = BOXCAR_FILTER_LEN;
m_boxcarFilter.pState = m_boxcarState;
m_boxcarFilter.pCoeffs = BOXCAR_FILTER;
m_nxdnFilter.numTaps = NXDN_0_2_FILTER_LEN;
m_nxdnFilter.pState = m_nxdnState;
m_nxdnFilter.pCoeffs = NXDN_0_2_FILTER;
m_nxdnISincFilter.numTaps = NXDN_ISINC_FILTER_LEN;
m_nxdnISincFilter.pState = m_nxdnISincState;
m_nxdnISincFilter.pCoeffs = NXDN_ISINC_FILTER;
initInt();
@@ -268,35 +308,52 @@ void CIO::process()
#endif
if (m_modemState == STATE_IDLE) {
if (m_dstarEnable || m_dmrEnable || m_ysfEnable || m_p25Enable) {
q15_t vals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_boxcar5Filter, samples, vals, RX_BLOCK_SIZE);
if (m_dstarEnable) {
q15_t GMSKVals[RX_BLOCK_SIZE];
#if defined(USE_DCBLOCKER)
::arm_fir_fast_q15(&m_gaussianFilter, dcSamples, GMSKVals, RX_BLOCK_SIZE);
#else
::arm_fir_fast_q15(&m_gaussianFilter, samples, GMSKVals, RX_BLOCK_SIZE);
#endif
dstarRX.samples(GMSKVals, rssi, RX_BLOCK_SIZE);
}
if (m_dstarEnable)
dstarRX.samples(vals, rssi, RX_BLOCK_SIZE);
if (m_p25Enable)
p25RX.samples(vals, rssi, RX_BLOCK_SIZE);
if (m_ysfEnable)
ysfRX.samples(vals, rssi, RX_BLOCK_SIZE);
if (m_dmrEnable) {
if (m_duplex)
dmrIdleRX.samples(vals, RX_BLOCK_SIZE);
else
dmrDMORX.samples(vals, rssi, RX_BLOCK_SIZE);
}
if (m_p25Enable) {
q15_t P25Vals[RX_BLOCK_SIZE];
#if defined(USE_DCBLOCKER)
::arm_fir_fast_q15(&m_boxcarFilter, dcSamples, P25Vals, RX_BLOCK_SIZE);
#else
::arm_fir_fast_q15(&m_boxcarFilter, samples, P25Vals, RX_BLOCK_SIZE);
#endif
p25RX.samples(P25Vals, rssi, RX_BLOCK_SIZE);
}
if (m_nxdnEnable) {
q15_t vals[RX_BLOCK_SIZE];
q15_t NXDNValsTmp[RX_BLOCK_SIZE];
#if defined(USE_DCBLOCKER)
::arm_fir_fast_q15(&m_boxcar10Filter, dcSamples, vals, RX_BLOCK_SIZE);
::arm_fir_fast_q15(&m_nxdnFilter, dcSamples, NXDNValsTmp, RX_BLOCK_SIZE);
#else
::arm_fir_fast_q15(&m_boxcar10Filter, samples, vals, RX_BLOCK_SIZE);
::arm_fir_fast_q15(&m_nxdnFilter, samples, NXDNValsTmp, RX_BLOCK_SIZE);
#endif
nxdnRX.samples(vals, rssi, RX_BLOCK_SIZE);
q15_t NXDNVals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_nxdnISincFilter, NXDNValsTmp, NXDNVals, RX_BLOCK_SIZE);
nxdnRX.samples(NXDNVals, rssi, RX_BLOCK_SIZE);
}
if (m_dmrEnable || m_ysfEnable) {
q15_t RRCVals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_rrcFilter, samples, RRCVals, RX_BLOCK_SIZE);
if (m_ysfEnable)
ysfRX.samples(RRCVals, rssi, RX_BLOCK_SIZE);
if (m_dmrEnable) {
if (m_duplex)
dmrIdleRX.samples(RRCVals, RX_BLOCK_SIZE);
else
dmrDMORX.samples(RRCVals, rssi, RX_BLOCK_SIZE);
}
}
if (m_fmEnable) {
@@ -309,59 +366,61 @@ void CIO::process()
}
} else if (m_modemState == STATE_DSTAR) {
if (m_dstarEnable) {
q15_t vals[RX_BLOCK_SIZE];
q15_t GMSKVals[RX_BLOCK_SIZE];
#if defined(USE_DCBLOCKER)
::arm_fir_fast_q15(&m_boxcar5Filter, dcSamples, vals, RX_BLOCK_SIZE);
::arm_fir_fast_q15(&m_gaussianFilter, dcSamples, GMSKVals, RX_BLOCK_SIZE);
#else
::arm_fir_fast_q15(&m_boxcar5Filter, samples, vals, RX_BLOCK_SIZE);
::arm_fir_fast_q15(&m_gaussianFilter, samples, GMSKVals, RX_BLOCK_SIZE);
#endif
dstarRX.samples(vals, rssi, RX_BLOCK_SIZE);
dstarRX.samples(GMSKVals, rssi, RX_BLOCK_SIZE);
}
} else if (m_modemState == STATE_DMR) {
if (m_dmrEnable) {
q15_t vals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_boxcar5Filter, samples, vals, RX_BLOCK_SIZE);
q15_t DMRVals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_rrcFilter, samples, DMRVals, RX_BLOCK_SIZE);
if (m_duplex) {
// If the transmitter isn't on, use the DMR idle RX to detect the wakeup CSBKs
if (m_tx)
dmrRX.samples(vals, rssi, control, RX_BLOCK_SIZE);
dmrRX.samples(DMRVals, rssi, control, RX_BLOCK_SIZE);
else
dmrIdleRX.samples(vals, RX_BLOCK_SIZE);
dmrIdleRX.samples(DMRVals, RX_BLOCK_SIZE);
} else {
dmrDMORX.samples(vals, rssi, RX_BLOCK_SIZE);
dmrDMORX.samples(DMRVals, rssi, RX_BLOCK_SIZE);
}
}
} else if (m_modemState == STATE_YSF) {
if (m_ysfEnable) {
q15_t vals[RX_BLOCK_SIZE];
q15_t YSFVals[RX_BLOCK_SIZE];
#if defined(USE_DCBLOCKER)
::arm_fir_fast_q15(&m_boxcar5Filter, dcSamples, vals, RX_BLOCK_SIZE);
::arm_fir_fast_q15(&m_rrcFilter, dcSamples, YSFVals, RX_BLOCK_SIZE);
#else
::arm_fir_fast_q15(&m_boxcar5Filter, samples, vals, RX_BLOCK_SIZE);
::arm_fir_fast_q15(&m_rrcFilter, samples, YSFVals, RX_BLOCK_SIZE);
#endif
ysfRX.samples(vals, rssi, RX_BLOCK_SIZE);
ysfRX.samples(YSFVals, rssi, RX_BLOCK_SIZE);
}
} else if (m_modemState == STATE_P25) {
if (m_p25Enable) {
q15_t vals[RX_BLOCK_SIZE];
q15_t P25Vals[RX_BLOCK_SIZE];
#if defined(USE_DCBLOCKER)
::arm_fir_fast_q15(&m_boxcar5Filter, dcSamples, vals, RX_BLOCK_SIZE);
::arm_fir_fast_q15(&m_boxcarFilter, dcSamples, P25Vals, RX_BLOCK_SIZE);
#else
::arm_fir_fast_q15(&m_boxcar5Filter, samples, vals, RX_BLOCK_SIZE);
::arm_fir_fast_q15(&m_boxcarFilter, samples, P25Vals, RX_BLOCK_SIZE);
#endif
p25RX.samples(vals, rssi, RX_BLOCK_SIZE);
p25RX.samples(P25Vals, rssi, RX_BLOCK_SIZE);
}
} else if (m_modemState == STATE_NXDN) {
} else if (m_modemState == STATE_NXDN) {
if (m_nxdnEnable) {
q15_t vals[RX_BLOCK_SIZE];
q15_t NXDNValsTmp[RX_BLOCK_SIZE];
#if defined(USE_DCBLOCKER)
::arm_fir_fast_q15(&m_boxcar10Filter, dcSamples, vals, RX_BLOCK_SIZE);
::arm_fir_fast_q15(&m_nxdnFilter, dcSamples, NXDNValsTmp, RX_BLOCK_SIZE);
#else
::arm_fir_fast_q15(&m_boxcar10Filter, samples, vals, RX_BLOCK_SIZE);
::arm_fir_fast_q15(&m_nxdnFilter, samples, NXDNValsTmp, RX_BLOCK_SIZE);
#endif
nxdnRX.samples(vals, rssi, RX_BLOCK_SIZE);
q15_t NXDNVals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_nxdnISincFilter, NXDNValsTmp, NXDNVals, RX_BLOCK_SIZE);
nxdnRX.samples(NXDNVals, rssi, RX_BLOCK_SIZE);
}
} else if (m_modemState == STATE_FM) {
bool cos = getCOSInt();
@@ -371,13 +430,10 @@ void CIO::process()
fm.samples(cos, samples, RX_BLOCK_SIZE);
#endif
} else if (m_modemState == STATE_DSTARCAL) {
q15_t vals[RX_BLOCK_SIZE];
#if defined(USE_DCBLOCKER)
::arm_fir_fast_q15(&m_boxcar5Filter, dcSamples, vals, RX_BLOCK_SIZE);
#else
::arm_fir_fast_q15(&m_boxcar5Filter, samples, vals, RX_BLOCK_SIZE);
#endif
calDStarRX.samples(vals, RX_BLOCK_SIZE);
q15_t GMSKVals[RX_BLOCK_SIZE];
::arm_fir_fast_q15(&m_gaussianFilter, samples, GMSKVals, RX_BLOCK_SIZE);
calDStarRX.samples(GMSKVals, RX_BLOCK_SIZE);
} else if (m_modemState == STATE_RSSICAL) {
calRSSI.samples(rssi, RX_BLOCK_SIZE);
}
+10 -4
View File
@@ -66,10 +66,16 @@ private:
arm_biquad_casd_df1_inst_q31 m_dcFilter;
q31_t m_dcState[4];
arm_fir_instance_q15 m_boxcar5Filter;
arm_fir_instance_q15 m_boxcar10Filter;
q15_t m_boxcar5State[30U]; // NoTaps + BlockSize - 1, 6 + 20 - 1 plus some spare
q15_t m_boxcar10State[40U]; // NoTaps + BlockSize - 1, 10 + 20 - 1 plus some spare
arm_fir_instance_q15 m_rrcFilter;
arm_fir_instance_q15 m_gaussianFilter;
arm_fir_instance_q15 m_boxcarFilter;
arm_fir_instance_q15 m_nxdnFilter;
arm_fir_instance_q15 m_nxdnISincFilter;
q15_t m_rrcState[70U]; // NoTaps + BlockSize - 1, 42 + 20 - 1 plus some spare
q15_t m_gaussianState[40U]; // NoTaps + BlockSize - 1, 12 + 20 - 1 plus some spare
q15_t m_boxcarState[30U]; // NoTaps + BlockSize - 1, 6 + 20 - 1 plus some spare
q15_t m_nxdnState[110U]; // NoTaps + BlockSize - 1, 82 + 20 - 1 plus some spare
q15_t m_nxdnISincState[60U]; // NoTaps + BlockSize - 1, 32 + 20 - 1 plus some spare
bool m_pttInvert;
q15_t m_rxLevel;
+13 -45
View File
@@ -41,7 +41,6 @@ YSF PB8 output
P25 PB9 output
NXDN PB10 output
POCSAG PB11 output
FM PB12 output
RX PB0 analog input (ADC1_8)
RSSI PB1 analog input (ADC2_9)
@@ -85,9 +84,6 @@ USART1_RXD PA10 input (AF)
#define PIN_POCSAG 11
#define PORT_POCSAG GPIOB
#define BB_POCSAG *((bitband_t)BITBAND_PERIPH(&PORT_POCSAG->ODR, PIN_POCSAG))
#define PIN_FM 14
#define PORT_FM GPIOB
#define BB_FM *((bitband_t)BITBAND_PERIPH(&PORT_FM->ODR, PIN_FM))
#define PIN_RX 0
#define PIN_RX_ADC_CH 8
@@ -158,35 +154,16 @@ void GPIOConfigPin(GPIO_TypeDef *port_ptr, uint32_t pin, uint32_t mode_cnf_value
#if defined(STM32F1_POG)
void FancyLEDEffect()
{
int ledCount = 10;
bitband_t foo[] = {&BB_LED, &BB_COSLED, &BB_PTT, &BB_DMR, &BB_DSTAR, &BB_YSF, &BB_P25,
#if defined(USE_ALTERNATE_NXDN_LEDS)
NULL,
#else
&BB_NXDN,
#endif
#if defined(USE_ALTERNATE_POCSAG_LEDS)
NULL,
#else
&BB_POCSAG,
#endif
#if defined(USE_ALTERNATE_FM_LEDS)
NULL};
#else
&BB_FM};
#endif
for(int i=0; i<ledCount; i++){
if(foo[i] != NULL)
*foo[i] = 0x01;
bitband_t foo[] = {&BB_LED, &BB_COSLED, &BB_PTT, &BB_DMR, &BB_DSTAR, &BB_YSF, &BB_P25};
for(int i=0; i<7; i++){
*foo[i] = 0x01;
}
GPIOConfigPin(PORT_USART1_TXD, PIN_USART1_TXD, GPIO_CRL_MODE0_1);
*((bitband_t)BITBAND_PERIPH(&PORT_USART1_TXD->ODR, PIN_USART1_TXD)) = 0x00;
delay(SystemCoreClock/1000*100);
for(int i=0; i<ledCount; i++){
if(foo[i] != NULL)
*foo[i] = 0x00;
for(int i=0; i<7; i++){
*foo[i] = 0x00;
}
*((bitband_t)BITBAND_PERIPH(&PORT_USART1_TXD->ODR, PIN_USART1_TXD)) = 0x01;
delay(SystemCoreClock/1000*20);
@@ -195,22 +172,18 @@ void FancyLEDEffect()
*((bitband_t)BITBAND_PERIPH(&PORT_USART1_TXD->ODR, PIN_USART1_TXD)) = 0x01;
*foo[0] = 0x01;
for(int i=1; i<ledCount; i++){
for(int i=1; i<7; i++){
delay(SystemCoreClock/1000*10);
if (foo[i-1] != NULL)
*foo[i-1] = 0x00;
if (foo[i] != NULL)
*foo[i] = 0x01;
*foo[i-1] = 0x00;
*foo[i] = 0x01;
}
for(int i=ledCount - 2; i>=0; i--) {
for(int i=5; i>=0; i--){
delay(SystemCoreClock/1000*10);
if (foo[i+1] != NULL)
*foo[i+1] = 0x00;
if (foo[i] != NULL)
*foo[i] = 0x01;
*foo[i+1] = 0x00;
*foo[i] = 0x01;
}
delay(SystemCoreClock/1000*10);
*foo[0] = 0x00;
*foo[5+1-6] = 0x00;
*((bitband_t)BITBAND_PERIPH(&PORT_USART1_TXD->ODR, PIN_USART1_TXD)) = 0x00;
delay(SystemCoreClock/1000*10);
*((bitband_t)BITBAND_PERIPH(&PORT_USART1_TXD->ODR, PIN_USART1_TXD)) = 0x01;
@@ -255,9 +228,6 @@ static inline void GPIOInit()
#if !defined(USE_ALTERNATE_POCSAG_LEDS)
GPIOConfigPin(PORT_POCSAG, PIN_POCSAG, GPIO_CRL_MODE0_1);
#endif
#if !defined(USE_ALTERNATE_FM_LEDS)
GPIOConfigPin(PORT_FM, PIN_FM, GPIO_CRL_MODE0_1);
#endif
GPIOConfigPin(PORT_RX, PIN_RX, 0);
#if defined(SEND_RSSI_DATA)
@@ -495,8 +465,6 @@ void CIO::setFMInt(bool on)
#if defined(USE_ALTERNATE_FM_LEDS)
BB_DSTAR = !!on;
BB_YSF = !!on;
#else
BB_FM = !!on;
#endif
}
+14 -4
View File
@@ -1,7 +1,17 @@
This is the source code of the MMDVM firmware that supports D-Star, DMR, System Fusion, P25, NXDN, and POCSAG modes.
This is the source code of the MMDVM firmware that supports D-Star, DMR,
System Fusion, P25, NXDN, POCSAG, and FM modes.
It runs on the Arduino Due, the ST-Micro STM32F1xxx, STM32F4xxx and STM32F7xxx processors, as well as the Teensy 3.1/3.2/3.5/3.6. What these platforms have in common is the use of an ARM Cortex-M3 or M4 processor with a clock speed greater than 70 MHz, and access to at least one analogue to digital converter and one digital to analogue converter.
It runs on the Arduino Due, the ST-Micro STM32F1xxx, STM32F4xxx and STM32F7xxx
processors, as well as the Teensy 3.1/3.2/3.5/3.6. What these platforms have in
common is the use of an ARM Cortex-M3, M4, or M7 processors with a clock speed
greater than 70 MHz, and access to at least one analogue to digital converter
and one digital to analogue converter.
In order to build this software for the Arduino Due, you will need to edit a file within the Arduino GUI and that is detailed in the BUILD.txt file. The STM32 support is being supplied via the Coocox IDE with ARM GCC. The Teensy support uses Teensyduino.
In order to build this software for the Arduino Due, you will need to edit a
file within the Arduino GUI and that is detailed in the BUILD.txt file. The
STM32 support is being supplied via the ARM GCC compiler. The Teensy support
uses Teensyduino.
This software is licenced under the GPL v2 and is intended for amateur and educational use only. Use of this software for commercial purposes is strictly forbidden.
This software is licenced under the GPL v2 and is intended for amateur and
educational use only. Use of this software for commercial purposes is strictly
forbidden.
+5 -3
View File
@@ -103,7 +103,7 @@ const uint8_t MMDVM_DEBUG5 = 0xF5U;
#define HW_TYPE "MMDVM"
#endif
#define DESCRIPTION "20200520 (D-Star/DMR/System Fusion/P25/NXDN/POCSAG/FM)"
#define DESCRIPTION "20200620 (D-Star/DMR/System Fusion/P25/NXDN/POCSAG/FM)"
#if defined(GITVERSION)
#define concat(h, a, b, c) h " " a " " b " GitID #" c ""
@@ -433,12 +433,13 @@ uint8_t CSerialPort::setFMParams3(const uint8_t* data, uint8_t length)
bool useCOS = (data[8U] & 0x01U) == 0x01U;
bool cosInvert = (data[8U] & 0x02U) == 0x02U;
bool kerchunkTX = (data[8U] & 0x04U) == 0x04U;
uint8_t rfAudioBoost = data[9U];
uint8_t maxDev = data[10U];
uint8_t rxLevel = data[11U];
return fm.setMisc(timeout, timeoutLevel, ctcssFrequency, ctcssHighThreshold, ctcssLowThreshold, ctcssLevel, kerchunkTime, hangTime, useCOS, cosInvert, rfAudioBoost, maxDev, rxLevel);
return fm.setMisc(timeout, timeoutLevel, ctcssFrequency, ctcssHighThreshold, ctcssLowThreshold, ctcssLevel, kerchunkTime, kerchunkTX, hangTime, useCOS, cosInvert, rfAudioBoost, maxDev, rxLevel);
}
uint8_t CSerialPort::setMode(const uint8_t* data, uint8_t length)
@@ -592,7 +593,8 @@ void CSerialPort::process()
m_buffer[0U] = c;
m_ptr = 1U;
m_len = 0U;
} else {
}
else {
m_ptr = 0U;
m_len = 0U;
}