diff --git a/IOPins.h b/IOPins.h index 77e3bdc..fe0fea4 100644 --- a/IOPins.h +++ b/IOPins.h @@ -62,6 +62,9 @@ #elif defined(DRCC_DVM_NQF) #include "pins/pins_f4_drcc_nqf.h" +#elif defined(DRCC_DVM_HHP446) + #include "pins/pins_f4_drcc_hhp446.h" + #elif defined(STM32F4_EDA_405) || defined(STM32F4_EDA_446) #include "pins/pins_f4_stm32eda.h" diff --git a/M17RX.cpp b/M17RX.cpp index b5abe42..23fd22a 100644 --- a/M17RX.cpp +++ b/M17RX.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009-2017,2020 by Jonathan Naylor G4KLX + * Copyright (C) 2009-2017,2020,2021 by Jonathan Naylor G4KLX * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -105,8 +105,11 @@ void CM17RX::samples(const q15_t* samples, uint16_t* rssi, uint8_t length) case M17RXS_HEADER: processHeader(sample); break; - case M17RXS_DATA: - processData(sample); + case M17RXS_STREAM: + processStream(sample); + break; + case M17RXS_PACKET: + processPacket(sample); break; default: processNone(sample); @@ -127,8 +130,9 @@ void CM17RX::processNone(q15_t sample) { bool ret1 = correlateSync(M17_LINK_SETUP_SYNC_SYMBOLS, M17_LINK_SETUP_SYNC_SYMBOLS_VALUES, M17_LINK_SETUP_SYNC_BYTES); bool ret2 = correlateSync(M17_STREAM_SYNC_SYMBOLS, M17_STREAM_SYNC_SYMBOLS_VALUES, M17_STREAM_SYNC_BYTES); + bool ret3 = correlateSync(M17_PACKET_SYNC_SYMBOLS, M17_PACKET_SYNC_SYMBOLS_VALUES, M17_PACKET_SYNC_BYTES); - if (ret1 || ret2) { + if (ret1 || ret2 || ret3) { // On the first sync, start the countdown to the state change if (m_countdown == 0U) { m_rssiAccum = 0U; @@ -141,7 +145,9 @@ void CM17RX::processNone(q15_t sample) m_countdown = 5U; - m_nextState = ret1 ? M17RXS_HEADER : M17RXS_DATA; + if (ret1) m_nextState = M17RXS_HEADER; + if (ret2) m_nextState = M17RXS_STREAM; + if (ret3) m_nextState = M17RXS_PACKET; } } @@ -191,12 +197,12 @@ void CM17RX::processHeader(q15_t sample) m_lostCount--; frame[0U] = 0x01U; writeRSSIHeader(frame); - m_state = M17RXS_DATA; + m_state = M17RXS_NONE; m_maxCorr = 0; } } -void CM17RX::processData(q15_t sample) +void CM17RX::processStream(q15_t sample) { if (m_minSyncPtr < m_maxSyncPtr) { if (m_dataPtr >= m_minSyncPtr && m_dataPtr <= m_maxSyncPtr) @@ -220,15 +226,15 @@ void CM17RX::processData(q15_t sample) calculateLevels(m_startPtr, M17_FRAME_LENGTH_SYMBOLS); - DEBUG4("M17RX: data sync found pos/centre/threshold", m_syncPtr, m_centreVal, m_thresholdVal); + DEBUG4("M17RX: stream sync found pos/centre/threshold", m_syncPtr, m_centreVal, m_thresholdVal); uint8_t frame[M17_FRAME_LENGTH_BYTES + 3U]; samplesToBits(m_startPtr, M17_FRAME_LENGTH_SYMBOLS, frame, 8U, m_centreVal, m_thresholdVal); - // We've not seen a data sync for too long, signal RXLOST and change to RX_NONE + // We've not seen a stream sync for too long, signal RXLOST and change to RX_NONE m_lostCount--; if (m_lostCount == 0U) { - DEBUG1("M17RX: sync timed out, lost lock"); + DEBUG1("M17RX: stream sync timed out, lost lock"); io.setDecode(false); io.setADCDetection(false); @@ -242,7 +248,62 @@ void CM17RX::processData(q15_t sample) m_nextState = M17RXS_NONE; m_maxCorr = 0; } else { - frame[0U] = m_lostCount == (MAX_SYNC_FRAMES - 1U) ? 0x01U : 0x00U; + frame[0U] = 0x00U; + frame[0U] |= m_lostCount == (MAX_SYNC_FRAMES - 1U) ? 0x01U : 0x00U; + writeRSSIData(frame); + m_maxCorr = 0; + } + } +} + +void CM17RX::processPacket(q15_t sample) +{ + if (m_minSyncPtr < m_maxSyncPtr) { + if (m_dataPtr >= m_minSyncPtr && m_dataPtr <= m_maxSyncPtr) + correlateSync(M17_PACKET_SYNC_SYMBOLS, M17_PACKET_SYNC_SYMBOLS_VALUES, M17_PACKET_SYNC_BYTES); + } else { + if (m_dataPtr >= m_minSyncPtr || m_dataPtr <= m_maxSyncPtr) + correlateSync(M17_PACKET_SYNC_SYMBOLS, M17_PACKET_SYNC_SYMBOLS_VALUES, M17_PACKET_SYNC_BYTES); + } + + if (m_dataPtr == m_endPtr) { + // Only update the centre and threshold if they are from a good sync + if (m_lostCount == MAX_SYNC_FRAMES) { + m_minSyncPtr = m_syncPtr + M17_FRAME_LENGTH_SAMPLES - 1U; + if (m_minSyncPtr >= M17_FRAME_LENGTH_SAMPLES) + m_minSyncPtr -= M17_FRAME_LENGTH_SAMPLES; + + m_maxSyncPtr = m_syncPtr + 1U; + if (m_maxSyncPtr >= M17_FRAME_LENGTH_SAMPLES) + m_maxSyncPtr -= M17_FRAME_LENGTH_SAMPLES; + } + + calculateLevels(m_startPtr, M17_FRAME_LENGTH_SYMBOLS); + + DEBUG4("M17RX: packet sync found pos/centre/threshold", m_syncPtr, m_centreVal, m_thresholdVal); + + uint8_t frame[M17_FRAME_LENGTH_BYTES + 3U]; + samplesToBits(m_startPtr, M17_FRAME_LENGTH_SYMBOLS, frame, 8U, m_centreVal, m_thresholdVal); + + // We've not seen a packet sync for too long, signal RXLOST and change to RX_NONE + m_lostCount--; + if (m_lostCount == 0U) { + DEBUG1("M17RX: packet sync timed out, lost lock"); + + io.setDecode(false); + io.setADCDetection(false); + + serial.writeM17Lost(); + + m_state = M17RXS_NONE; + m_endPtr = NOENDPTR; + m_averagePtr = NOAVEPTR; + m_countdown = 0U; + m_nextState = M17RXS_NONE; + m_maxCorr = 0; + } else { + frame[0U] = 0x02U; + frame[0U] |= m_lostCount == (MAX_SYNC_FRAMES - 1U) ? 0x01U : 0x00U; writeRSSIData(frame); m_maxCorr = 0; } diff --git a/M17RX.h b/M17RX.h index 5700d54..b2ca363 100644 --- a/M17RX.h +++ b/M17RX.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015,2016,2017,2020 by Jonathan Naylor G4KLX + * Copyright (C) 2015,2016,2017,2020,2021 by Jonathan Naylor G4KLX * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -28,7 +28,8 @@ enum M17RX_STATE { M17RXS_NONE, M17RXS_HEADER, - M17RXS_DATA + M17RXS_STREAM, + M17RXS_PACKET }; class CM17RX { @@ -64,7 +65,8 @@ private: void processNone(q15_t sample); void processHeader(q15_t sample); - void processData(q15_t sample); + void processStream(q15_t sample); + void processPacket(q15_t sample); bool correlateSync(uint8_t syncSymbols, const int8_t* syncSymbolValues, const uint8_t* syncBytes); void calculateLevels(uint16_t start, uint16_t count); void samplesToBits(uint16_t start, uint16_t count, uint8_t* buffer, uint16_t offset, q15_t centre, q15_t threshold); diff --git a/Makefile b/Makefile index a0f1a29..131b990 100644 --- a/Makefile +++ b/Makefile @@ -233,6 +233,12 @@ drcc_nqf: CXXFLAGS+=$(CXXFLAGS_F4) $(DEFS_DRCC_DVM) -DDRCC_DVM_NQF drcc_nqf: LDFLAGS+=$(LDFLAGS_F4) drcc_nqf: release_f4 +hhp446: GitVersion.h +hhp446: CFLAGS+=$(CFLAGS_F4) $(DEFS_DRCC_DVM) -DDRCC_DVM_HHP446 +hhp446: CXXFLAGS+=$(CXXFLAGS_F4) $(DEFS_DRCC_DVM) -DDRCC_DVM_HHP446 +hhp446: LDFLAGS+=$(LDFLAGS_F4) +hhp446: release_f4 + eda405: GitVersion.h eda405: CFLAGS+=$(CFLAGS_F4) $(DEFS_EDA_405) eda405: CXXFLAGS+=$(CXXFLAGS_F4) $(DEFS_EDA_405) diff --git a/SerialPort.cpp b/SerialPort.cpp index 8a94236..dc8c48c 100644 --- a/SerialPort.cpp +++ b/SerialPort.cpp @@ -108,8 +108,8 @@ const uint8_t MMDVM_DEBUG5 = 0xF5U; #if defined(DRCC_DVM_NQF) #define HW_TYPE "MMDVM DRCC_DVM_NQF" -#elif defined(STM32F4_RPT_HAT_TGO) -#define HW_TYPE "MMDVM RPT_HAT_TGO" +#elif defined(DRCC_DVM_HHP446) +#define HW_TYPE "MMDVM DRCC_DVM_HHP(446)" #else #define HW_TYPE "MMDVM" #endif diff --git a/Version.h b/Version.h index b1be557..1eaa844 100644 --- a/Version.h +++ b/Version.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 by Jonathan Naylor G4KLX + * Copyright (C) 2020,2021 by Jonathan Naylor G4KLX * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,6 +19,6 @@ #if !defined(VERSION_H) #define VERSION_H -#define VERSION "20201226" +#define VERSION "20210101" #endif diff --git a/pins/pins_f4_drcc_hhp446.h b/pins/pins_f4_drcc_hhp446.h new file mode 100644 index 0000000..feb99e6 --- /dev/null +++ b/pins/pins_f4_drcc_hhp446.h @@ -0,0 +1,143 @@ +/* + * Copyright (C) 2019,2020 by BG5HHP + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _PINS_F4_DRCC_HHP446_H +#define _PINS_F4_DRCC_HHP446_H + +/* +Pin definitions for DRCC_DVM BG5HHP F446 board rev1 + +TX/PTT_LED PB12 output +RX/COS_LED PB5 output +STATUS_LED PB10 output + +COS_IN PB13 input + +DSTAR N/A +DMR N/A +YSF N/A +P25 N/A +NXDN N/A +POCSAG N/A + +MDMR/BIT0 PB8 output +MYSF/BIT1 PB9 output +MDSTAR/BIT2 PB14 output +MP25/BIT3 PB15 output Generic Mode Pins +MNXDN N/A +MPOCSAG N/A + +RX PA0 analog input +RSSI PA1 analog input +TX PA4 analog output + +EXT_CLK N/A + +UART1_TX PA9 output +UART1_RX PA10 output Host Data Communication + +UART2_TX PA2 output +UART2_RX PA3 output Nextion Data Communication + +I2C1_SCL PB6 output +I2C1_SDA PB7 output OLED Data Communication as master + +*/ + +#define PIN_COS GPIO_Pin_13 +#define PORT_COS GPIOB +#define RCC_Per_COS RCC_AHB1Periph_GPIOB + +#define PIN_PTT GPIO_Pin_12 +#define PORT_PTT GPIOB +#define RCC_Per_PTT RCC_AHB1Periph_GPIOB + +#define PIN_COSLED GPIO_Pin_5 +#define PORT_COSLED GPIOB +#define RCC_Per_COSLED RCC_AHB1Periph_GPIOB + +#define PIN_LED GPIO_Pin_10 +#define PORT_LED GPIOB +#define RCC_Per_LED RCC_AHB1Periph_GPIOB + +#define PIN_TXLED GPIO_Pin_4 +#define PORT_TXLED GPIOB +#define RCC_Per_TXLED RCC_AHB1Periph_GPIOB + +// #define PIN_P25 GPIO_Pin_3 +// #define PORT_P25 GPIOB +// #define RCC_Per_P25 RCC_AHB1Periph_GPIOB + +// #define PIN_NXDN GPIO_Pin_10 +// #define PORT_NXDN GPIOA +// #define RCC_Per_NXDN RCC_AHB1Periph_GPIOA + +// #define PIN_POCSAG GPIO_Pin_12 +// #define PORT_POCSAG GPIOB +// #define RCC_Per_POCSAG RCC_AHB1Periph_GPIOB + +// #define PIN_DSTAR GPIO_Pin_10 +// #define PORT_DSTAR GPIOB +// #define RCC_Per_DSTAR RCC_AHB1Periph_GPIOB + +// #define PIN_DMR GPIO_Pin_4 +// #define PORT_DMR GPIOB +// #define RCC_Per_DMR RCC_AHB1Periph_GPIOB + +// #define PIN_YSF GPIO_Pin_5 +// #define PORT_YSF GPIOB +// #define RCC_Per_YSF RCC_AHB1Periph_GPIOB + +#if defined(MODE_PINS) +#define PIN_MP25 GPIO_Pin_15 +#define PORT_MP25 GPIOB +#define RCC_Per_MP25 RCC_AHB1Periph_GPIOB + +#define PIN_MDSTAR GPIO_Pin_9 +#define PORT_MDSTAR GPIOB +#define RCC_Per_MDSTAR RCC_AHB1Periph_GPIOB + +#define PIN_MDMR GPIO_Pin_8 +#define PORT_MDMR GPIOB +#define RCC_Per_MDMR RCC_AHB1Periph_GPIOB + +#define PIN_MYSF GPIO_Pin_14 +#define PORT_MYSF GPIOB +#define RCC_Per_MYSF RCC_AHB1Periph_GPIOB +#endif + +#define PIN_EXT_CLK GPIO_Pin_15 +#define SRC_EXT_CLK GPIO_PinSource15 +#define PORT_EXT_CLK GPIOA + +#define PIN_RX GPIO_Pin_0 +#define PIN_RX_CH ADC_Channel_0 +#define PORT_RX GPIOA +#define RCC_Per_RX RCC_AHB1Periph_GPIOA + +#define PIN_RSSI GPIO_Pin_1 +#define PIN_RSSI_CH ADC_Channel_1 +#define PORT_RSSI GPIOA +#define RCC_Per_RSSI RCC_AHB1Periph_GPIOA + +#define PIN_TX GPIO_Pin_4 +#define PIN_TX_CH DAC_Channel_1 +#define PORT_TX GPIOA +#define RCC_Per_TX RCC_AHB1Periph_GPIOA + +#endif \ No newline at end of file