diff --git a/.gitignore b/.gitignore index d68e462..09324b1 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ obj/ bin/ GitVersion.h build/ +.vscode + diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..8d426a2 --- /dev/null +++ b/platformio.ini @@ -0,0 +1,31 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:MMDVM] +platform = ststm32 +board = genericSTM32F446RE +framework = arduino, cmsis +build_unflags = -O0 +monitor_speed = 460800 +build_flags = + -O3 + -Wall + ; -D ARM_MATH_CM7 + ; -mfpu=fpv5-sp-d16 + -D ARM_MATH_CM4 + -mfpu=fpv4-sp-d16 + -mfloat-abi=hard + ; enable USB serial + -D PIO_FRAMEWORK_ARDUINO_USB_HIGHSPEED_FULLMODE + -D PIO_FRAMEWORK_ARDUINO_ENABLE_CDC + -D USBCON + ; increase the buffer sizes + -D SERIAL_RX_BUFFER_SIZE=1024 + -D SERIAL_TX_BUFFER_SIZE=1024 diff --git a/src/AX25RX.cpp b/src/AX25RX.cpp index eddac27..9297b2a 100644 --- a/src/AX25RX.cpp +++ b/src/AX25RX.cpp @@ -193,7 +193,7 @@ void CAX25RX::initRand() //Can also be used to seed the rng with more entropy du { m_a = (m_a ^ m_c ^ m_x); m_b = (m_b + m_a); - m_c = (m_c + (m_b >> 1) ^ m_a); + m_c = (m_c + ((m_b >> 1) ^ m_a)); } uint8_t CAX25RX::rand() @@ -202,7 +202,7 @@ uint8_t CAX25RX::rand() m_a = (m_a ^ m_c ^ m_x); //note the mix of addition and XOR m_b = (m_b + m_a); //And the use of very few instructions - m_c = (m_c + (m_b >> 1) ^ m_a); //the right shift is to ensure that high-order bits from b can affect + m_c = (m_c + ((m_b >> 1) ^ m_a)); //the right shift is to ensure that high-order bits from b can affect return uint8_t(m_c); //low order bits of other variables } diff --git a/src/Globals.h b/src/Globals.h index 33b7334..f1c2ca2 100644 --- a/src/Globals.h +++ b/src/Globals.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015,2016,2017,2018,2020,2021 by Jonathan Naylor G4KLX + * Copyright (C) 2015,2016,2017,2018,2020,2021,2024 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,24 +19,8 @@ #if !defined(GLOBALS_H) #define GLOBALS_H -#if defined(STM32F4XX) -#include "stm32f4xx.h" -#elif defined(STM32F7XX) -#include "stm32f7xx.h" -#else #include #undef PI //Undefine PI to get rid of annoying warning as it is also defined in arm_math.h. -#endif - -#if defined(__SAM3X8E__) -#define ARM_MATH_CM3 -#elif defined(STM32F7XX) -#define ARM_MATH_CM7 -#elif defined(STM32F4XX) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) -#define ARM_MATH_CM4 -#else -#error "Unknown processor type" -#endif #include diff --git a/src/IO.cpp b/src/IO.cpp index 4c973e4..5e29d81 100644 --- a/src/IO.cpp +++ b/src/IO.cpp @@ -237,7 +237,7 @@ void CIO::selfTest() setFMInt(ledValue); #endif #endif - delayInt(250); + ::delay(250); } #if defined(MODE_LEDS) @@ -259,63 +259,63 @@ void CIO::selfTest() #endif setDStarInt(true); - delayInt(250); + ::delay(250); setDMRInt(true); - delayInt(250); + ::delay(250); setYSFInt(true); - delayInt(250); + ::delay(250); setP25Int(true); #if !defined(USE_ALTERNATE_NXDN_LEDS) - delayInt(250); + ::delay(250); setNXDNInt(true); #endif #if !defined(USE_ALTERNATE_M17_LEDS) - delayInt(250); + ::delay(250); setM17Int(true); #endif #if !defined(USE_ALTERNATE_POCSAG_LEDS) - delayInt(250); + ::delay(250); setPOCSAGInt(true); #endif #if !defined(USE_ALTERNATE_FM_LEDS) - delayInt(250); + ::delay(250); setFMInt(true); - delayInt(250); + ::delay(250); setFMInt(false); #endif #if !defined(USE_ALTERNATE_POCSAG_LEDS) - delayInt(250); + ::delay(250); setPOCSAGInt(false); #endif #if !defined(USE_ALTERNATE_M17_LEDS) - delayInt(250); + ::delay(250); setM17Int(false); #endif #if !defined(USE_ALTERNATE_NXDN_LEDS) - delayInt(250); + ::delay(250); setNXDNInt(false); #endif - delayInt(250); + ::delay(250); setP25Int(false); - delayInt(250); + ::delay(250); setYSFInt(false); - delayInt(250); + ::delay(250); setDMRInt(false); - delayInt(250); + ::delay(250); setDStarInt(false); #endif } diff --git a/src/IO.h b/src/IO.h index b1cf1ab..f1eef3e 100644 --- a/src/IO.h +++ b/src/IO.h @@ -161,8 +161,6 @@ private: void setPOCSAGInt(bool on); void setM17Int(bool on); void setFMInt(bool on); - - void delayInt(unsigned int dly); }; #endif diff --git a/src/IODue.cpp b/src/IODue.cpp deleted file mode 100644 index f2e7b36..0000000 --- a/src/IODue.cpp +++ /dev/null @@ -1,323 +0,0 @@ -/* - * Copyright (C) 2015,2016,2017,2018,2020 by Jonathan Naylor G4KLX - * Copyright (C) 2015 by Jim Mclaughlin KI6ZUM - * Copyright (C) 2016 by Colin Durbridge G4EML - * - * 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. - */ - -#include "Config.h" -#include "Globals.h" -#include "IO.h" - -#if defined(__SAM3X8E__) - -// An Arduino Due -#if defined(ARDUINO_DUE_PAPA) -#define PIN_COS 7 -#define PIN_PTT 8 -#define PIN_COSLED 11 -#define PIN_DSTAR 16 -#define PIN_DMR 17 -#define PIN_YSF 18 -#define PIN_P25 19 -#define PIN_NXDN 20 -#define PIN_POCSAG 4 -#define PIN_FM 5 -#define ADC_CHER_Chan (1<<7) // ADC on Due pin A0 - Due AD7 - (1 << 7) -#define ADC_ISR_EOC_Chan ADC_ISR_EOC7 -#define ADC_CDR_Chan 7 -#define DACC_MR_USER_SEL_Chan DACC_MR_USER_SEL_CHANNEL0 // DAC on Due DAC0 -#define DACC_CHER_Chan DACC_CHER_CH0 -#elif defined(ARDUINO_DUE_ZUM_V10) -#define PIN_COS 52 -#define PIN_PTT 23 -#define PIN_COSLED 22 -#define PIN_DSTAR 9 -#define PIN_DMR 8 -#define PIN_YSF 7 -#define PIN_P25 6 -#define PIN_NXDN 5 -#define PIN_POCSAG 4 -#define PIN_FM 3 -#define ADC_CHER_Chan (1<<13) // ADC on Due pin A11 - Due AD13 - (1 << 13) -#define ADC_ISR_EOC_Chan ADC_ISR_EOC13 -#define ADC_CDR_Chan 13 -#define DACC_MR_USER_SEL_Chan DACC_MR_USER_SEL_CHANNEL1 // DAC on Due DAC1 -#define DACC_CHER_Chan DACC_CHER_CH1 -#define RSSI_CHER_Chan (1<<1) // ADC on Due pin A6 - Due AD1 - (1 << 1) -#define RSSI_CDR_Chan 1 -#elif defined(ARDUINO_DUE_NTH) -#define PIN_COS A7 -#define PIN_PTT A8 -#define PIN_COSLED A11 -#define PIN_DSTAR 9 -#define PIN_DMR 8 -#define PIN_YSF 7 -#define PIN_P25 6 -#define PIN_NXDN 5 -#define PIN_POCSAG 4 -#define PIN_FM 3 -#define ADC_CHER_Chan (1<<7) // ADC on Due pin A0 - Due AD7 - (1 << 7) -#define ADC_ISR_EOC_Chan ADC_ISR_EOC7 -#define ADC_CDR_Chan 7 -#define DACC_MR_USER_SEL_Chan DACC_MR_USER_SEL_CHANNEL0 // DAC on Due DAC0 -#define DACC_CHER_Chan DACC_CHER_CH0 -#define RSSI_CHER_Chan (1<<1) // ADC on Due pin A6 - Due AD1 - (1 << 1) -#define RSSI_CDR_Chan 1 -#else -#error "Either ARDUINO_DUE_PAPA, ARDUINO_DUE_ZUM_V10, or ARDUINO_DUE_NTH need to be defined" -#endif - -const uint16_t DC_OFFSET = 2048U; - -extern "C" { - void ADC_Handler() - { - io.interrupt(); - } -} - -void CIO::initInt() -{ - // Set up the TX, COS and LED pins - pinMode(PIN_PTT, OUTPUT); - pinMode(PIN_COSLED, OUTPUT); - pinMode(PIN_LED, OUTPUT); - pinMode(PIN_COS, INPUT); - -#if defined(MODE_LEDS) - // Set up the mode output pins - pinMode(PIN_DSTAR, OUTPUT); - pinMode(PIN_DMR, OUTPUT); - pinMode(PIN_YSF, OUTPUT); - pinMode(PIN_P25, OUTPUT); -#if !defined(USE_ALTERNATE_NXDN_LEDS) - pinMode(PIN_NXDN, OUTPUT); -#endif -#if !defined(USE_ALTERNATE_M17_LEDS) - pinMode(PIN_M17, OUTPUT); -#endif -#if !defined(USE_ALTERNATE_POCSAG_LEDS) - pinMode(PIN_POCSAG, OUTPUT); -#endif -#if !defined(USE_ALTERNATE_POCSAG_LEDS) - pinMode(PIN_FM, OUTPUT); -#endif -#endif -} - -void CIO::startInt() -{ - if (ADC->ADC_ISR & ADC_ISR_EOC_Chan) // Ensure there was an End-of-Conversion and we read the ISR reg - io.interrupt(); - - // Set up the ADC - NVIC_EnableIRQ(ADC_IRQn); // Enable ADC interrupt vector - ADC->ADC_IDR = 0xFFFFFFFF; // Disable interrupts - ADC->ADC_IER = ADC_CHER_Chan; // Enable End-Of-Conv interrupt - ADC->ADC_CHDR = 0xFFFF; // Disable all channels - ADC->ADC_CHER = ADC_CHER_Chan; // Enable rx input channel -#if defined(SEND_RSSI_DATA) - ADC->ADC_CHER |= RSSI_CHER_Chan; // and RSSI input -#endif - ADC->ADC_CGR = 0x15555555; // All gains set to x1 - ADC->ADC_COR = 0x00000000; // All offsets off - ADC->ADC_MR = (ADC->ADC_MR & 0xFFFFFFF0) | (1 << 1) | ADC_MR_TRGEN; // 1 = trig source TIO from TC0 - -#if defined(EXTERNAL_OSC) - // Set up the external clock input on PA4 = AI5 - REG_PIOA_ODR = 0x10; // Set pin as input - REG_PIOA_PDR = 0x10; // Disable PIO A bit 4 - REG_PIOA_ABSR &= ~0x10; // Select A peripheral = TCLK1 Input -#endif - - // Set up the timer - pmc_enable_periph_clk(TC_INTERFACE_ID + 0*3+0) ; // Clock the TC0 channel 0 - TcChannel* t = &(TC0->TC_CHANNEL)[0]; // Pointer to TC0 registers for its channel 0 - t->TC_CCR = TC_CCR_CLKDIS; // Disable internal clocking while setup regs - t->TC_IDR = 0xFFFFFFFF; // Disable interrupts - t->TC_SR; // Read int status reg to clear pending -#if defined(EXTERNAL_OSC) - t->TC_CMR = TC_CMR_TCCLKS_XC1 | // Use XC1 = TCLK1 external clock -#else - t->TC_CMR = TC_CMR_TCCLKS_TIMER_CLOCK1 | // Use TCLK1 (prescale by 2, = 42MHz) -#endif - TC_CMR_WAVE | // Waveform mode - TC_CMR_WAVSEL_UP_RC | // Count-up PWM using RC as threshold - TC_CMR_EEVT_XC0 | // Set external events from XC0 (this setup TIOB as output) - TC_CMR_ACPA_CLEAR | TC_CMR_ACPC_CLEAR | - TC_CMR_BCPB_CLEAR | TC_CMR_BCPC_CLEAR; -#if defined(EXTERNAL_OSC) - t->TC_RC = EXTERNAL_OSC / 24000; // Counter resets on RC, so sets period in terms of the external clock - t->TC_RA = EXTERNAL_OSC / 48000; // Roughly square wave -#else - t->TC_RC = 1750; // Counter resets on RC, so sets period in terms of 42MHz internal clock - t->TC_RA = 880; // Roughly square wave -#endif - t->TC_CMR = (t->TC_CMR & 0xFFF0FFFF) | TC_CMR_ACPA_CLEAR | TC_CMR_ACPC_SET; // Set clear and set from RA and RC compares - t->TC_CCR = TC_CCR_CLKEN | TC_CCR_SWTRG; // re-enable local clocking and switch to hardware trigger source. - - // Set up the DAC - pmc_enable_periph_clk(DACC_INTERFACE_ID); // Start clocking DAC - DACC->DACC_CR = DACC_CR_SWRST; // Reset DAC - DACC->DACC_MR = - DACC_MR_TRGEN_EN | DACC_MR_TRGSEL(1) | // Trigger 1 = TIO output of TC0 - DACC_MR_USER_SEL_Chan | // Select channel - (24 << DACC_MR_STARTUP_Pos); // 24 = 1536 cycles which I think is in range 23..45us since DAC clock = 42MHz - DACC->DACC_IDR = 0xFFFFFFFF; // No interrupts - DACC->DACC_CHER = DACC_CHER_Chan; // Enable channel - - digitalWrite(PIN_PTT, m_pttInvert ? HIGH : LOW); - digitalWrite(PIN_COSLED, LOW); - digitalWrite(PIN_LED, HIGH); -} - -void CIO::interrupt() -{ - if ((ADC->ADC_ISR & ADC_ISR_EOC_Chan) == ADC_ISR_EOC_Chan) { // Ensure there was an End-of-Conversion and we read the ISR reg - TSample sample = {DC_OFFSET, MARK_NONE}; - - m_txBuffer.get(sample); - DACC->DACC_CDR = sample.sample; - - sample.sample = ADC->ADC_CDR[ADC_CDR_Chan]; - m_rxBuffer.put(sample); - -#if defined(SEND_RSSI_DATA) - m_rssiBuffer.put(ADC->ADC_CDR[RSSI_CDR_Chan]); -#else - m_rssiBuffer.put(0U); -#endif - - m_watchdog++; - } -} - -bool CIO::getCOSInt() -{ - return digitalRead(PIN_COS) == HIGH; -} - -void CIO::setLEDInt(bool on) -{ - digitalWrite(PIN_LED, on ? HIGH : LOW); -} - -void CIO::setPTTInt(bool on) -{ - digitalWrite(PIN_PTT, on ? HIGH : LOW); -} - -void CIO::setCOSInt(bool on) -{ - digitalWrite(PIN_COSLED, on ? HIGH : LOW); -} - -void CIO::setDStarInt(bool on) -{ - digitalWrite(PIN_DSTAR, on ? HIGH : LOW); -} - -void CIO::setDMRInt(bool on) -{ - digitalWrite(PIN_DMR, on ? HIGH : LOW); -} - -void CIO::setYSFInt(bool on) -{ - digitalWrite(PIN_YSF, on ? HIGH : LOW); -} - -void CIO::setP25Int(bool on) -{ - digitalWrite(PIN_P25, on ? HIGH : LOW); -} - -void CIO::setNXDNInt(bool on) -{ -#if defined(USE_ALTERNATE_NXDN_LEDS) - digitalWrite(PIN_YSF, on ? HIGH : LOW); - digitalWrite(PIN_P25, on ? HIGH : LOW); -#else - digitalWrite(PIN_NXDN, on ? HIGH : LOW); -#endif -} - -void CIO::setM17Int(bool on) -{ -#if defined(USE_ALTERNATE_M17_LEDS) - digitalWrite(PIN_DSTAR, on ? HIGH : LOW); - digitalWrite(PIN_P25, on ? HIGH : LOW); -#else - digitalWrite(PIN_M17, on ? HIGH : LOW); -#endif -} - -void CIO::setPOCSAGInt(bool on) -{ -#if defined(USE_ALTERNATE_POCSAG_LEDS) - digitalWrite(PIN_DSTAR, on ? HIGH : LOW); - digitalWrite(PIN_DMR, on ? HIGH : LOW); -#else - digitalWrite(PIN_POCSAG, on ? HIGH : LOW); -#endif -} - -void CIO::setFMInt(bool on) -{ -#if defined(USE_ALTERNATE_FM_LEDS) - digitalWrite(PIN_DSTAR, on ? HIGH : LOW); - digitalWrite(PIN_YSF, on ? HIGH : LOW); -#else - digitalWrite(PIN_FM, on ? HIGH : LOW); -#endif -} - -void CIO::delayInt(unsigned int dly) -{ - delay(dly); -} - -uint8_t CIO::getCPU() const -{ - return 0U; -} - -// Code taken from https://github.com/emagii/at91sam3s/blob/master/examples/eefc_uniqueid/main.c -void CIO::getUDID(uint8_t* buffer) -{ - uint32_t status; - - EFC1->EEFC_FCR = (0x5A << 24) | EFC_FCMD_STUI; - do { - status = EFC1->EEFC_FSR; - } while ( (status & EEFC_FSR_FRDY) == EEFC_FSR_FRDY ); - - for (uint8_t i = 0; i < 16; i+=4) { - buffer[i + 0] = *(uint32_t *)(IFLASH1_ADDR + i) >> 24; - buffer[i + 1] = *(uint32_t *)(IFLASH1_ADDR + i) >> 16; - buffer[i + 2] = *(uint32_t *)(IFLASH1_ADDR + i) >> 8; - buffer[i + 3] = *(uint32_t *)(IFLASH1_ADDR + i) >> 0; - } - - EFC1->EEFC_FCR = (0x5A << 24) | EFC_FCMD_SPUI; - do { - status = EFC1->EEFC_FSR; - } while ( (status & EEFC_FSR_FRDY) != EEFC_FSR_FRDY ); -} - -#endif - diff --git a/src/IOSTM.cpp b/src/IOSTM.cpp deleted file mode 100644 index db87da0..0000000 --- a/src/IOSTM.cpp +++ /dev/null @@ -1,565 +0,0 @@ -/* - * Copyright (C) 2016 by Jim McLaughlin KI6ZUM - * Copyright (C) 2016,2017,2018 by Andy Uribe CA6JAU - * Copyright (C) 2017,2018,2020 by Jonathan Naylor G4KLX - * 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. - */ - -#include "Config.h" -#include "Globals.h" -#include "IO.h" - -#if defined(STM32F4XX) || defined(STM32F7XX) -#include "IOPins.h" - - -const uint16_t DC_OFFSET = 2048U; - -// Sampling frequency -#define SAMP_FREQ 24000 - -extern "C" { - void TIM2_IRQHandler() { - if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) { - TIM_ClearITPendingBit(TIM2, TIM_IT_Update); - io.interrupt(); - } - } -} - -void CIO::initInt() -{ - GPIO_InitTypeDef GPIO_InitStruct; - GPIO_StructInit(&GPIO_InitStruct); - GPIO_InitStruct.GPIO_Speed = GPIO_Fast_Speed; - GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; - GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN; - - // PTT pin - RCC_AHB1PeriphClockCmd(RCC_Per_PTT, ENABLE); - GPIO_InitStruct.GPIO_Pin = PIN_PTT; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; - GPIO_Init(PORT_PTT, &GPIO_InitStruct); - - // COSLED pin - RCC_AHB1PeriphClockCmd(RCC_Per_COSLED, ENABLE); - GPIO_InitStruct.GPIO_Pin = PIN_COSLED; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; - GPIO_Init(PORT_COSLED, &GPIO_InitStruct); - - // LED pin - RCC_AHB1PeriphClockCmd(RCC_Per_LED, ENABLE); - GPIO_InitStruct.GPIO_Pin = PIN_LED; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; - GPIO_Init(PORT_LED, &GPIO_InitStruct); - - // Init the input pins PIN_COS - RCC_AHB1PeriphClockCmd(RCC_Per_COS, ENABLE); - GPIO_InitStruct.GPIO_Pin = PIN_COS; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN; - GPIO_Init(PORT_COS, &GPIO_InitStruct); - -#if defined(MODE_LEDS) - // DSTAR pin - RCC_AHB1PeriphClockCmd(RCC_Per_DSTAR, ENABLE); - GPIO_InitStruct.GPIO_Pin = PIN_DSTAR; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; - GPIO_Init(PORT_DSTAR, &GPIO_InitStruct); - - // DMR pin - RCC_AHB1PeriphClockCmd(RCC_Per_DMR, ENABLE); - GPIO_InitStruct.GPIO_Pin = PIN_DMR; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; - GPIO_Init(PORT_DMR, &GPIO_InitStruct); - - // YSF pin - RCC_AHB1PeriphClockCmd(RCC_Per_YSF, ENABLE); - GPIO_InitStruct.GPIO_Pin = PIN_YSF; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; - GPIO_Init(PORT_YSF, &GPIO_InitStruct); - - // P25 pin - RCC_AHB1PeriphClockCmd(RCC_Per_P25, ENABLE); - GPIO_InitStruct.GPIO_Pin = PIN_P25; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; - GPIO_Init(PORT_P25, &GPIO_InitStruct); - -#if !defined(USE_ALTERNATE_NXDN_LEDS) - // NXDN pin - RCC_AHB1PeriphClockCmd(RCC_Per_NXDN, ENABLE); - GPIO_InitStruct.GPIO_Pin = PIN_NXDN; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; - GPIO_Init(PORT_NXDN, &GPIO_InitStruct); -#endif - -#if !defined(USE_ALTERNATE_M17_LEDS) - // M17 pin - RCC_AHB1PeriphClockCmd(RCC_Per_M17, ENABLE); - GPIO_InitStruct.GPIO_Pin = PIN_M17; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; - GPIO_Init(PORT_M17, &GPIO_InitStruct); -#endif - -#if !defined(USE_ALTERNATE_POCSAG_LEDS) - // POCSAG pin - RCC_AHB1PeriphClockCmd(RCC_Per_POCSAG, ENABLE); - GPIO_InitStruct.GPIO_Pin = PIN_POCSAG; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; - GPIO_Init(PORT_POCSAG, &GPIO_InitStruct); -#endif - -#if !defined(USE_ALTERNATE_FM_LEDS) - // FM pin - RCC_AHB1PeriphClockCmd(RCC_Per_FM, ENABLE); - GPIO_InitStruct.GPIO_Pin = PIN_FM; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; - GPIO_Init(PORT_FM, &GPIO_InitStruct); -#endif - -#endif - -#if defined(MODE_PINS) && defined(STM32F4_NUCLEO_MORPHO_HEADER) && (defined(STM32F4_NUCLEO) || defined(STM32F722_RPT_HAT)) - // DSTAR mode pin - RCC_AHB1PeriphClockCmd(RCC_Per_MDSTAR, ENABLE); - GPIO_InitStruct.GPIO_Pin = PIN_MDSTAR; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; - GPIO_Init(PORT_MDSTAR, &GPIO_InitStruct); - - // DMR mode pin - RCC_AHB1PeriphClockCmd(RCC_Per_MDMR, ENABLE); - GPIO_InitStruct.GPIO_Pin = PIN_MDMR; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; - GPIO_Init(PORT_MDMR, &GPIO_InitStruct); - - // YSF mode pin - RCC_AHB1PeriphClockCmd(RCC_Per_MYSF, ENABLE); - GPIO_InitStruct.GPIO_Pin = PIN_MYSF; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; - GPIO_Init(PORT_MYSF, &GPIO_InitStruct); - - // P25 mode pin - RCC_AHB1PeriphClockCmd(RCC_Per_MP25, ENABLE); - GPIO_InitStruct.GPIO_Pin = PIN_MP25; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; - GPIO_Init(PORT_MP25, &GPIO_InitStruct); - -#if !defined(USE_ALTERNATE_NXDN_LEDS) - // NXDN mode pin - RCC_AHB1PeriphClockCmd(RCC_Per_MNXDN, ENABLE); - GPIO_InitStruct.GPIO_Pin = PIN_MNXDN; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; - GPIO_Init(PORT_MNXDN, &GPIO_InitStruct); -#endif - -#if !defined(USE_ALTERNATE_M17_LEDS) - // M17 mode pin - RCC_AHB1PeriphClockCmd(RCC_Per_MM17, ENABLE); - GPIO_InitStruct.GPIO_Pin = PIN_MM17; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; - GPIO_Init(PORT_MM17, &GPIO_InitStruct); -#endif - -#if !defined(USE_ALTERNATE_POCSAG_LEDS) - // POCSAG mode pin - RCC_AHB1PeriphClockCmd(RCC_Per_MPOCSAG, ENABLE); - GPIO_InitStruct.GPIO_Pin = PIN_MPOCSAG; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; - GPIO_Init(PORT_MPOCSAG, &GPIO_InitStruct); -#endif - -#if !defined(USE_ALTERNATE_FM_LEDS) - // FM mode pin - RCC_AHB1PeriphClockCmd(RCC_Per_MFM, ENABLE); - GPIO_InitStruct.GPIO_Pin = PIN_MFM; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; - GPIO_Init(PORT_MFM, &GPIO_InitStruct); -#endif - -#endif -} - -void CIO::startInt() -{ - if ((ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) != RESET)) - io.interrupt(); - - // Init the ADC - GPIO_InitTypeDef GPIO_InitStruct; - ADC_InitTypeDef ADC_InitStructure; - ADC_CommonInitTypeDef ADC_CommonInitStructure; - - GPIO_StructInit(&GPIO_InitStruct); - ADC_CommonStructInit(&ADC_CommonInitStructure); - ADC_StructInit(&ADC_InitStructure); - - // Enable ADC1 clock - RCC_AHB1PeriphClockCmd(RCC_Per_RX, ENABLE); - RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); - // Enable ADC1 GPIO - GPIO_InitStruct.GPIO_Pin = PIN_RX; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN; - GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL ; - GPIO_Init(PORT_RX, &GPIO_InitStruct); - -#if defined(SEND_RSSI_DATA) - // Enable ADC2 clock - RCC_AHB1PeriphClockCmd(RCC_Per_RSSI, ENABLE); - RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2, ENABLE); - // Enable ADC2 GPIO - GPIO_InitStruct.GPIO_Pin = PIN_RSSI; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN; - GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL ; - GPIO_Init(PORT_RSSI, &GPIO_InitStruct); -#endif - - // Init ADCs in dual mode (RSSI), div clock by two -#if defined(SEND_RSSI_DATA) - ADC_CommonInitStructure.ADC_Mode = ADC_DualMode_RegSimult; -#else - ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; -#endif - ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2; - ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; - ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; - ADC_CommonInit(&ADC_CommonInitStructure); - - // Init ADC1 and ADC2: 12bit, single-conversion - ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; - ADC_InitStructure.ADC_ScanConvMode = DISABLE; - ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; - ADC_InitStructure.ADC_ExternalTrigConvEdge = 0; - ADC_InitStructure.ADC_ExternalTrigConv = 0; - ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; - ADC_InitStructure.ADC_NbrOfConversion = 1; - - ADC_Init(ADC1, &ADC_InitStructure); - - ADC_EOCOnEachRegularChannelCmd(ADC1, ENABLE); - ADC_RegularChannelConfig(ADC1, PIN_RX_CH, 1, ADC_SampleTime_3Cycles); - - // Enable ADC1 - ADC_Cmd(ADC1, ENABLE); - -#if defined(SEND_RSSI_DATA) - ADC_Init(ADC2, &ADC_InitStructure); - - ADC_EOCOnEachRegularChannelCmd(ADC2, ENABLE); - ADC_RegularChannelConfig(ADC2, PIN_RSSI_CH, 1, ADC_SampleTime_3Cycles); - - // Enable ADC2 - ADC_Cmd(ADC2, ENABLE); -#endif - - // Init the DAC - DAC_InitTypeDef DAC_InitStructure; - - GPIO_StructInit(&GPIO_InitStruct); - DAC_StructInit(&DAC_InitStructure); - - // GPIOA clock enable - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); - - // DAC Periph clock enable - RCC_APB1PeriphClockCmd(RCC_APB1Periph_DAC, ENABLE); - - // GPIO CONFIGURATION of DAC Pin - GPIO_InitStruct.GPIO_Pin = PIN_TX; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN; - GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL; - GPIO_Init(GPIOA, &GPIO_InitStruct); - - DAC_InitStructure.DAC_Trigger = DAC_Trigger_None; - DAC_InitStructure.DAC_WaveGeneration = DAC_WaveGeneration_None; - DAC_InitStructure.DAC_OutputBuffer = DAC_OutputBuffer_Enable; - DAC_Init(PIN_TX_CH, &DAC_InitStructure); - DAC_Cmd(PIN_TX_CH, ENABLE); - - // Init the timer - RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); - -#if defined(EXTERNAL_OSC) && !(defined(STM32F4_PI) || defined(STM32F722_PI)) - // Configure a GPIO as external TIM2 clock source - GPIO_PinAFConfig(PORT_EXT_CLK, SRC_EXT_CLK, GPIO_AF_TIM2); - GPIO_InitStruct.GPIO_Pin = PIN_EXT_CLK; - GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF; - GPIO_Init(PORT_EXT_CLK, &GPIO_InitStruct); -#endif - - TIM_TimeBaseInitTypeDef timerInitStructure; - TIM_TimeBaseStructInit (&timerInitStructure); - - // TIM2 output frequency -#if defined(EXTERNAL_OSC) && !(defined(STM32F4_PI) || defined(STM32F722_PI)) - timerInitStructure.TIM_Prescaler = (uint16_t) ((EXTERNAL_OSC/(2*SAMP_FREQ)) - 1); - timerInitStructure.TIM_Period = 1; -#else - timerInitStructure.TIM_Prescaler = (uint16_t) ((SystemCoreClock/(6*SAMP_FREQ)) - 1); - timerInitStructure.TIM_Period = 2; -#endif - - timerInitStructure.TIM_CounterMode = TIM_CounterMode_Up; - timerInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; - timerInitStructure.TIM_RepetitionCounter = 0; - TIM_TimeBaseInit(TIM2, &timerInitStructure); - -#if defined(EXTERNAL_OSC) && !(defined(STM32F4_PI) || defined(STM32F722_PI)) - // Enable external clock - TIM_ETRClockMode2Config(TIM2, TIM_ExtTRGPSC_OFF, TIM_ExtTRGPolarity_NonInverted, 0x00); -#else - // Enable internal clock - TIM_InternalClockConfig(TIM2); -#endif - - // Enable TIM2 - TIM_Cmd(TIM2, ENABLE); - // Enable TIM2 interrupt - TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE); - - NVIC_InitTypeDef nvicStructure; - nvicStructure.NVIC_IRQChannel = TIM2_IRQn; - nvicStructure.NVIC_IRQChannelPreemptionPriority = 0; - nvicStructure.NVIC_IRQChannelSubPriority = 1; - nvicStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&nvicStructure); - - GPIO_ResetBits(PORT_COSLED, PIN_COSLED); - GPIO_SetBits(PORT_LED, PIN_LED); -} - -void CIO::interrupt() -{ - TSample sample = {DC_OFFSET, MARK_NONE}; - uint16_t rawRSSI = 0U; - - m_txBuffer.get(sample); - - // Send the value to the DAC -#if defined(STM32F4_NUCLEO) && defined(STM32F4_NUCLEO_ARDUINO_HEADER) - DAC_SetChannel2Data(DAC_Align_12b_R, sample.sample); -#else - DAC_SetChannel1Data(DAC_Align_12b_R, sample.sample); -#endif - - // Read value from ADC1 and ADC2 - if ((ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET)) { - // shouldn't be still in reset at this point so null the sample value? - sample.sample = 0U; - } else { - sample.sample = ADC_GetConversionValue(ADC1); -#if defined(SEND_RSSI_DATA) - rawRSSI = ADC_GetConversionValue(ADC2); -#endif - } - - // trigger next ADC1 - ADC_ClearFlag(ADC1, ADC_FLAG_EOC); - ADC_SoftwareStartConv(ADC1); - - m_rxBuffer.put(sample); - m_rssiBuffer.put(rawRSSI); - - m_watchdog++; -} - -bool CIO::getCOSInt() -{ - return GPIO_ReadInputDataBit(PORT_COS, PIN_COS) == Bit_SET; -} - -void CIO::setLEDInt(bool on) -{ - GPIO_WriteBit(PORT_LED, PIN_LED, on ? Bit_SET : Bit_RESET); -} - -void CIO::setPTTInt(bool on) -{ - GPIO_WriteBit(PORT_PTT, PIN_PTT, on ? Bit_SET : Bit_RESET); -} - -void CIO::setCOSInt(bool on) -{ - GPIO_WriteBit(PORT_COSLED, PIN_COSLED, on ? Bit_SET : Bit_RESET); -} - -void CIO::setDStarInt(bool on) -{ -#if defined(MODE_LEDS) - GPIO_WriteBit(PORT_DSTAR, PIN_DSTAR, on ? Bit_SET : Bit_RESET); -#endif -#if defined(MODE_PINS) && defined(STM32F4_NUCLEO_MORPHO_HEADER) && (defined(STM32F4_NUCLEO) || defined(STM32F722_RPT_HAT)) - GPIO_WriteBit(PORT_MDSTAR, PIN_MDSTAR, on ? Bit_SET : Bit_RESET); -#endif -} - -void CIO::setDMRInt(bool on) -{ -#if defined(MODE_LEDS) - GPIO_WriteBit(PORT_DMR, PIN_DMR, on ? Bit_SET : Bit_RESET); -#endif -#if defined(MODE_PINS) && defined(STM32F4_NUCLEO_MORPHO_HEADER) && (defined(STM32F4_NUCLEO) || defined(STM32F722_RPT_HAT)) - GPIO_WriteBit(PORT_MDMR, PIN_MDMR, on ? Bit_SET : Bit_RESET); -#endif -} - -void CIO::setYSFInt(bool on) -{ -#if defined(MODE_LEDS) - GPIO_WriteBit(PORT_YSF, PIN_YSF, on ? Bit_SET : Bit_RESET); -#endif -#if defined(MODE_PINS) && defined(STM32F4_NUCLEO_MORPHO_HEADER) && (defined(STM32F4_NUCLEO) || defined(STM32F722_RPT_HAT)) - GPIO_WriteBit(PORT_MYSF, PIN_MYSF, on ? Bit_SET : Bit_RESET); -#endif -} - -void CIO::setP25Int(bool on) -{ -#if defined(MODE_LEDS) - GPIO_WriteBit(PORT_P25, PIN_P25, on ? Bit_SET : Bit_RESET); -#endif -#if defined(MODE_PINS) && defined(STM32F4_NUCLEO_MORPHO_HEADER) && (defined(STM32F4_NUCLEO) || defined(STM32F722_RPT_HAT)) - GPIO_WriteBit(PORT_MP25, PIN_MP25, on ? Bit_SET : Bit_RESET); -#endif -} - -void CIO::setNXDNInt(bool on) -{ -#if defined(MODE_LEDS) -#if defined(USE_ALTERNATE_NXDN_LEDS) - GPIO_WriteBit(PORT_YSF, PIN_YSF, on ? Bit_SET : Bit_RESET); - GPIO_WriteBit(PORT_P25, PIN_P25, on ? Bit_SET : Bit_RESET); -#else - GPIO_WriteBit(PORT_NXDN, PIN_NXDN, on ? Bit_SET : Bit_RESET); -#endif -#endif - -#if defined(MODE_PINS) && defined(STM32F4_NUCLEO_MORPHO_HEADER) && (defined(STM32F4_NUCLEO) || defined(STM32F722_RPT_HAT)) -#if defined(USE_ALTERNATE_NXDN_LEDS) - GPIO_WriteBit(PORT_MYSF, PIN_MYSF, on ? Bit_SET : Bit_RESET); - GPIO_WriteBit(PORT_MP25, PIN_MP25, on ? Bit_SET : Bit_RESET); -#else - GPIO_WriteBit(PORT_MNXDN, PIN_MNXDN, on ? Bit_SET : Bit_RESET); -#endif -#endif -} - -void CIO::setM17Int(bool on) -{ -#if defined(MODE_LEDS) -#if defined(USE_ALTERNATE_M17_LEDS) - GPIO_WriteBit(PORT_DSTAR, PIN_DSTAR, on ? Bit_SET : Bit_RESET); - GPIO_WriteBit(PORT_P25, PIN_P25, on ? Bit_SET : Bit_RESET); -#else - GPIO_WriteBit(PORT_M17, PIN_M17, on ? Bit_SET : Bit_RESET); -#endif -#endif - -#if defined(MODE_PINS) && defined(STM32F4_NUCLEO_MORPHO_HEADER) && (defined(STM32F4_NUCLEO) || defined(STM32F722_RPT_HAT)) -#if defined(USE_ALTERNATE_M17_LEDS) - GPIO_WriteBit(PORT_MDSTAR, PIN_MDSTAR, on ? Bit_SET : Bit_RESET); - GPIO_WriteBit(PORT_MP25, PIN_MP25, on ? Bit_SET : Bit_RESET); -#else - GPIO_WriteBit(PORT_MM17, PIN_MM17, on ? Bit_SET : Bit_RESET); -#endif -#endif -} - -void CIO::setPOCSAGInt(bool on) -{ -#if defined(MODE_LEDS) -#if defined(USE_ALTERNATE_POCSAG_LEDS) - GPIO_WriteBit(PORT_DSTAR, PIN_DSTAR, on ? Bit_SET : Bit_RESET); - GPIO_WriteBit(PORT_DMR, PIN_DMR, on ? Bit_SET : Bit_RESET); -#else - GPIO_WriteBit(PORT_POCSAG, PIN_POCSAG, on ? Bit_SET : Bit_RESET); -#endif -#endif - -#if defined(MODE_PINS) && defined(STM32F4_NUCLEO_MORPHO_HEADER) && (defined(STM32F4_NUCLEO) || defined(STM32F722_RPT_HAT)) -#if defined(USE_ALTERNATE_POCSAG_LEDS) - GPIO_WriteBit(PORT_MDSTAR, PIN_MDSTAR, on ? Bit_SET : Bit_RESET); - GPIO_WriteBit(PORT_MDMR, PIN_MDMR, on ? Bit_SET : Bit_RESET); -#else - GPIO_WriteBit(PORT_MPOCSAG, PIN_MPOCSAG, on ? Bit_SET : Bit_RESET); -#endif -#endif -} - -void CIO::setFMInt(bool on) -{ -#if defined(MODE_LEDS) -#if defined(USE_ALTERNATE_FM_LEDS) - GPIO_WriteBit(PORT_DSTAR, PIN_DSTAR, on ? Bit_SET : Bit_RESET); - GPIO_WriteBit(PORT_YSF, PIN_YSF, on ? Bit_SET : Bit_RESET); -#else - GPIO_WriteBit(PORT_FM, PIN_FM, on ? Bit_SET : Bit_RESET); -#endif -#endif - -#if defined(MODE_PINS) && defined(STM32F4_NUCLEO_MORPHO_HEADER) && (defined(STM32F4_NUCLEO) || defined(STM32F722_RPT_HAT)) -#if defined(USE_ALTERNATE_FM_LEDS) - GPIO_WriteBit(PORT_MDSTAR, PIN_MDSTAR, on ? Bit_SET : Bit_RESET); - GPIO_WriteBit(PORT_MYSF, PIN_MYSF, on ? Bit_SET : Bit_RESET); -#else - GPIO_WriteBit(PORT_MFM, PIN_MFM, on ? Bit_SET : Bit_RESET); -#endif -#endif -} - -// Simple delay function for STM32 -// Example from: http://thehackerworkshop.com/?p=1209 -void CIO::delayInt(unsigned int dly) -{ -#if defined(STM32F7XX) - unsigned int loopsPerMillisecond = (SystemCoreClock/1000); -#else - unsigned int loopsPerMillisecond = (SystemCoreClock/1000) / 3; -#endif - - for (; dly > 0; dly--) - { - asm volatile //this routine waits (approximately) one millisecond - ( - "mov r3, %[loopsPerMillisecond] \n\t" //load the initial loop counter - "loop: \n\t" - "subs r3, #1 \n\t" - "bne loop \n\t" - - : //empty output list - : [loopsPerMillisecond] "r" (loopsPerMillisecond) //input to the asm routine - : "r3", "cc" //clobber list - ); - } -} - -uint8_t CIO::getCPU() const -{ - return 2U; -} - -void CIO::getUDID(uint8_t* buffer) -{ -#if defined(STM32F4XX) - ::memcpy(buffer, (void *)0x1FFF7A10, 12U); -#elif defined(STM32F722xx) - ::memcpy(buffer, (void *)0x1FF07A10, 12U); -#elif defined(STM32F767xx) - ::memcpy(buffer, (void *)0x1FF0F420, 12U); -#endif -} - -#endif - diff --git a/src/IOTeensy.cpp b/src/IOTeensy.cpp deleted file mode 100644 index 5e1028d..0000000 --- a/src/IOTeensy.cpp +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Copyright (C) 2016,2017,2018,2020 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 - * 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. - */ - -#include "Config.h" -#include "Globals.h" -#include "IO.h" - -#if defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) - -#if defined(EXTERNAL_OSC) -#define PIN_LED 3 -#else -#define PIN_LED 13 -#endif -#define PIN_COS 4 -#define PIN_PTT 5 -#define PIN_COSLED 6 -#define PIN_DSTAR 9 -#define PIN_DMR 10 -#define PIN_YSF 11 -#define PIN_P25 12 -#if defined(__MK20DX256__) -#define PIN_NXDN 2 -#define PIN_POCSAG 3 -#define PIN_FM 4 -#else -#define PIN_NXDN 24 -#define PIN_POCSAG 25 -#define PIN_FM 26 -#endif -#define PIN_ADC 5 // A0, Pin 14 -#define PIN_RSSI 4 // Teensy 3.5/3.6, A16, Pin 35. Teensy 3.1/3.2, A17, Pin 28 - -#define PDB_CHnC1_TOS 0x0100 -#define PDB_CHnC1_EN 0x0001 - -const uint16_t DC_OFFSET = 2048U; - -extern "C" { - void adc0_isr() - { - io.interrupt(); - } -} - -void CIO::initInt() -{ - // Set up the TX, COS and LED pins - pinMode(PIN_PTT, OUTPUT); - pinMode(PIN_COSLED, OUTPUT); - pinMode(PIN_LED, OUTPUT); - pinMode(PIN_COS, INPUT); - -#if defined(MODE_LEDS) - // Set up the mode output pins - pinMode(PIN_DSTAR, OUTPUT); - pinMode(PIN_DMR, OUTPUT); - pinMode(PIN_YSF, OUTPUT); - pinMode(PIN_P25, OUTPUT); -#if !defined(USE_ALTERNATE_NXDN_LEDS) - pinMode(PIN_NXDN, OUTPUT); -#endif -#if !defined(USE_ALTERNATE_M17_LEDS) - pinMode(PIN_M17, OUTPUT); -#endif -#if !defined(USE_ALTERNATE_POCSAG_LEDS) - pinMode(PIN_POCSAG, OUTPUT); -#endif -#if !defined(USE_ALTERNATE_FM_LEDS) - pinMode(PIN_FM, OUTPUT); -#endif -#endif -} - -void CIO::startInt() -{ - // Initialise the DAC - SIM_SCGC2 |= SIM_SCGC2_DAC0; - DAC0_C0 = DAC_C0_DACEN | DAC_C0_DACRFS; // 3.3V VDDA is DACREF_2 - - // Initialise ADC0 - SIM_SCGC6 |= SIM_SCGC6_ADC0; - ADC0_CFG1 = ADC_CFG1_ADIV(1) | ADC_CFG1_ADICLK(1) | // Single-ended 12 bits, long sample time - ADC_CFG1_MODE(1) | ADC_CFG1_ADLSMP; - ADC0_CFG2 = ADC_CFG2_MUXSEL | ADC_CFG2_ADLSTS(2); // Select channels ADxxxb - ADC0_SC2 = ADC_SC2_REFSEL(0) | ADC_SC2_ADTRG; // Voltage ref external, hardware trigger - ADC0_SC3 = ADC_SC3_AVGE | ADC_SC3_AVGS(0); // Enable averaging, 4 samples - - ADC0_SC3 |= ADC_SC3_CAL; - while (ADC0_SC3 & ADC_SC3_CAL) // Wait for calibration - ; - - uint16_t sum0 = ADC0_CLPS + ADC0_CLP4 + ADC0_CLP3 + // Plus side gain - ADC0_CLP2 + ADC0_CLP1 + ADC0_CLP0; - sum0 = (sum0 / 2U) | 0x8000U; - ADC0_PG = sum0; - - ADC0_SC1A = ADC_SC1_AIEN | PIN_ADC; // Enable ADC interrupt, use A0 - NVIC_ENABLE_IRQ(IRQ_ADC0); - -#if defined(SEND_RSSI_DATA) - // Initialise ADC1 - SIM_SCGC3 |= SIM_SCGC3_ADC1; - ADC1_CFG1 = ADC_CFG1_ADIV(1) | ADC_CFG1_ADICLK(1) | // Single-ended 12 bits, long sample time - ADC_CFG1_MODE(1) | ADC_CFG1_ADLSMP; - ADC1_CFG2 = ADC_CFG2_MUXSEL | ADC_CFG2_ADLSTS(2); // Select channels ADxxxb - ADC1_SC2 = ADC_SC2_REFSEL(0); // Voltage ref external, software trigger - ADC1_SC3 = ADC_SC3_AVGE | ADC_SC3_AVGS(0); // Enable averaging, 4 samples - - ADC1_SC3 |= ADC_SC3_CAL; - while (ADC1_SC3 & ADC_SC3_CAL) // Wait for calibration - ; - - uint16_t sum1 = ADC1_CLPS + ADC1_CLP4 + ADC1_CLP3 + // Plus side gain - ADC1_CLP2 + ADC1_CLP1 + ADC1_CLP0; - sum1 = (sum1 / 2U) | 0x8000U; - ADC1_PG = sum1; -#endif - -#if defined(EXTERNAL_OSC) - // Set ADC0 to trigger from the LPTMR at 24 kHz - SIM_SOPT7 = SIM_SOPT7_ADC0ALTTRGEN | // Enable ADC0 alternate trigger - SIM_SOPT7_ADC0TRGSEL(14); // Trigger ADC0 by LPTMR0 - - CORE_PIN13_CONFIG = PORT_PCR_MUX(3); - - SIM_SCGC5 |= SIM_SCGC5_LPTIMER; // Enable Low Power Timer Access - LPTMR0_CSR = 0; // Disable - LPTMR0_PSR = LPTMR_PSR_PBYP; // Bypass prescaler/filter - LPTMR0_CMR = (EXTERNAL_OSC / 24000) - 1; // Frequency divided by CMR + 1 - LPTMR0_CSR = LPTMR_CSR_TPS(2) | // Pin: 0=CMP0, 1=xtal, 2=pin13 - LPTMR_CSR_TMS; // Mode Select, 0=timer, 1=counter - LPTMR0_CSR |= LPTMR_CSR_TEN; // Enable -#else - // Setup PDB for ADC0 at 24 kHz - SIM_SCGC6 |= SIM_SCGC6_PDB; // Enable PDB clock - PDB0_MOD = (F_BUS / 24000) - 1; // Timer period - 1 - PDB0_IDLY = 0; // Interrupt delay - PDB0_CH0C1 = PDB_CHnC1_TOS | PDB_CHnC1_EN; // Enable pre-trigger for ADC0 - PDB0_SC = PDB_SC_TRGSEL(15) | PDB_SC_PDBEN | // SW trigger, enable interrupts, continuous mode - PDB_SC_PDBIE | PDB_SC_CONT | PDB_SC_LDOK; // No prescaling - PDB0_SC |= PDB_SC_SWTRIG; // Software trigger (reset and restart counter) -#endif - - digitalWrite(PIN_PTT, m_pttInvert ? HIGH : LOW); - digitalWrite(PIN_COSLED, LOW); - digitalWrite(PIN_LED, HIGH); -} - -void CIO::interrupt() -{ - TSample sample = {DC_OFFSET, MARK_NONE}; - - m_txBuffer.get(sample); - *(int16_t *)&(DAC0_DAT0L) = sample.sample; - - if ((ADC0_SC1A & ADC_SC1_COCO) == ADC_SC1_COCO) { - sample.sample = ADC0_RA; - m_rxBuffer.put(sample); - } - -#if defined(SEND_RSSI_DATA) - if ((ADC1_SC1A & ADC_SC1_COCO) == ADC_SC1_COCO) { - uint16_t rssi = ADC1_RA; - m_rssiBuffer.put(rssi); - } else { - m_rssiBuffer.put(0U); - } - - ADC1_SC1A = PIN_RSSI; // Start the next RSSI conversion -#else - m_rssiBuffer.put(0U); -#endif - - m_watchdog++; -} - -bool CIO::getCOSInt() -{ - return digitalRead(PIN_COS) == HIGH; -} - -void CIO::setLEDInt(bool on) -{ - digitalWrite(PIN_LED, on ? HIGH : LOW); -} - -void CIO::setPTTInt(bool on) -{ - digitalWrite(PIN_PTT, on ? HIGH : LOW); -} - -void CIO::setCOSInt(bool on) -{ - digitalWrite(PIN_COSLED, on ? HIGH : LOW); -} - -void CIO::setDStarInt(bool on) -{ - digitalWrite(PIN_DSTAR, on ? HIGH : LOW); -} - -void CIO::setDMRInt(bool on) -{ - digitalWrite(PIN_DMR, on ? HIGH : LOW); -} - -void CIO::setYSFInt(bool on) -{ - digitalWrite(PIN_YSF, on ? HIGH : LOW); -} - -void CIO::setP25Int(bool on) -{ - digitalWrite(PIN_P25, on ? HIGH : LOW); -} - -void CIO::setNXDNInt(bool on) -{ -#if defined(USE_ALTERNATE_NXDN_LEDS) - digitalWrite(PIN_YSF, on ? HIGH : LOW); - digitalWrite(PIN_P25, on ? HIGH : LOW); -#else - digitalWrite(PIN_NXDN, on ? HIGH : LOW); -#endif -} - -void CIO::setM17Int(bool on) -{ -#if defined(USE_ALTERNATE_M17_LEDS) - digitalWrite(PIN_DSTAR, on ? HIGH : LOW); - digitalWrite(PIN_P25, on ? HIGH : LOW); -#else - digitalWrite(PIN_M17, on ? HIGH : LOW); -#endif -} - -void CIO::setPOCSAGInt(bool on) -{ -#if defined(USE_ALTERNATE_POCSAG_LEDS) - digitalWrite(PIN_DSTAR, on ? HIGH : LOW); - digitalWrite(PIN_DMR, on ? HIGH : LOW); -#else - digitalWrite(PIN_POCSAG, on ? HIGH : LOW); -#endif -} - -void CIO::setFMInt(bool on) -{ -#if defined(USE_ALTERNATE_FM_LEDS) - digitalWrite(PIN_DSTAR, on ? HIGH : LOW); - digitalWrite(PIN_YSF, on ? HIGH : LOW); -#else - digitalWrite(PIN_FM, on ? HIGH : LOW); -#endif -} - -void CIO::delayInt(unsigned int dly) -{ - delay(dly); -} - -uint8_t CIO::getCPU() const -{ - return 1U; -} - -void CIO::getUDID(uint8_t* buffer) -{ - ::memcpy(buffer, (void *)0x4058, 16U); -} - -#endif - diff --git a/src/MMDVM.cpp b/src/MMDVM.cpp index abc755b..3417191 100644 --- a/src/MMDVM.cpp +++ b/src/MMDVM.cpp @@ -18,8 +18,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#if defined(STM32F4XX) || defined(STM32F7XX) - #include "Config.h" #include "Globals.h" @@ -207,13 +205,3 @@ void loop() if (m_modemState == STATE_IDLE) cwIdTX.process(); } - -int main() -{ - setup(); - - for (;;) - loop(); -} - -#endif diff --git a/src/P25TX.cpp b/src/P25TX.cpp index 76aba0c..8e5ab1a 100644 --- a/src/P25TX.cpp +++ b/src/P25TX.cpp @@ -78,7 +78,7 @@ void CP25TX::process() for (uint16_t i = 0U; i < m_txDelay; i++) m_poBuffer[m_poLen++] = P25_START_SYNC; } else { - uint8_t length; + uint8_t length = 0U; m_buffer.get(length); for (uint8_t i = 0U; i < length; i++) { uint8_t c = 0U; diff --git a/src/RingBuffer.h b/src/RingBuffer.h index a76caf0..96254a9 100644 --- a/src/RingBuffer.h +++ b/src/RingBuffer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2020 by Jonathan Naylor G4KLX + * Copyright (C) 2020,2024 by Jonathan Naylor G4KLX * Copyright (C) 2020 by Geoffrey Merck F4FXL - KC3FRA * * This program is free software; you can redistribute it and/or modify @@ -20,24 +20,8 @@ #if !defined(RINGBUFFER_H) #define RINGBUFFER_H -#if defined(STM32F4XX) -#include "stm32f4xx.h" -#elif defined(STM32F7XX) -#include "stm32f7xx.h" -#else #include #undef PI -#endif - -#if defined(__SAM3X8E__) -#define ARM_MATH_CM3 -#elif defined(STM32F7XX) -#define ARM_MATH_CM7 -#elif defined(STM32F4XX) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) -#define ARM_MATH_CM4 -#else -#error "Unknown processor type" -#endif #include diff --git a/src/STM32Utils.h b/src/STM32Utils.h deleted file mode 100644 index e2f3cbb..0000000 --- a/src/STM32Utils.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2017 by Wojciech Krutnik N0CALL - * - * Source: http://mightydevices.com/?p=144 - * - * 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. - */ - -#if !defined(STM32UTILS_H) -#define STM32UTILS_H - -#include - -/* ram function */ -#define RAMFUNC __attribute__ ((long_call, section (".data"))) -/* eeprom data */ -/* for placing variables in eeprom memory */ -#define EEMEM __attribute__((section(".eeprom"))) - -/* bitband type */ -typedef volatile uint32_t * const bitband_t; - -/* base address for bit banding */ -#define BITBAND_SRAM_REF (0x20000000) -/* base address for bit banding */ -#define BITBAND_SRAM_BASE (0x22000000) -/* base address for bit banding */ -#define BITBAND_PERIPH_REF (0x40000000) -/* base address for bit banding */ -#define BITBAND_PERIPH_BASE (0x42000000) - -/* sram bit band */ -#define BITBAND_SRAM(address, bit) ((void*)(BITBAND_SRAM_BASE + \ - (((uint32_t)address) - BITBAND_SRAM_REF) * 32 + (bit) * 4)) - -/* periph bit band */ -#define BITBAND_PERIPH(address, bit) ((void *)(BITBAND_PERIPH_BASE + \ - (((uint32_t)address) - BITBAND_PERIPH_REF) * 32 + (bit) * 4)) - -#endif diff --git a/src/STMUART.cpp b/src/STMUART.cpp deleted file mode 100644 index c2e779d..0000000 --- a/src/STMUART.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (c) 2020 by Jonathan Naylor G4KLX - * Copyright (c) 2020 by Geoffrey Merck F4FXL - KC3FRA - * - * 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. - */ - -#if defined(STM32F4XX) || defined(STM32F7XX) - -#include "STMUART.h" - -CSTMUART::CSTMUART() : -m_usart(NULL) -{ - -} - -void CSTMUART::init(USART_TypeDef* usart) -{ - m_usart = usart; -} - -void CSTMUART::write(const uint8_t * data, uint16_t length) -{ - if(length == 0U || m_usart == NULL) - return; - - - m_txFifo.put(data[0]); - USART_ITConfig(m_usart, USART_IT_TXE, ENABLE);//switch TX IRQ is on - - for(uint16_t i = 1U; i < length; i++) { - m_txFifo.put(data[i]); - } - - USART_ITConfig(m_usart, USART_IT_TXE, ENABLE);//make sure TX IRQ is on -} - -uint8_t CSTMUART::read() -{ - return m_rxFifo.get(); -} - -void CSTMUART::handleIRQ() -{ - if(m_usart == NULL) - return; - - if (USART_GetITStatus(m_usart, USART_IT_RXNE)) { - if(!m_rxFifo.isFull()) - m_rxFifo.put((uint8_t) USART_ReceiveData(m_usart)); - USART_ClearITPendingBit(USART1, USART_IT_RXNE); - } - - if (USART_GetITStatus(m_usart, USART_IT_TXE)) { - if(!m_txFifo.isEmpty()) - USART_SendData(m_usart, m_txFifo.get()); - - USART_ClearITPendingBit(m_usart, USART_IT_TXE); - - if (m_txFifo.isEmpty()) // if there's no more data to transmit then turn off TX interrupts - USART_ITConfig(m_usart, USART_IT_TXE, DISABLE); - } -} - - // Flushes the transmit shift register -// warning: this call is blocking -void CSTMUART::flush() -{ - if(m_usart == NULL) - return; - - // wait until the TXE shows the shift register is empty - while (USART_GetITStatus(m_usart, USART_FLAG_TXE)) - ; -} - -uint16_t CSTMUART::available() -{ - return m_rxFifo.isEmpty() ? 0U : 1U; -} - -uint16_t CSTMUART::availableForWrite() -{ - return m_txFifo.isFull() ? 0U : 1U; -} - -#endif \ No newline at end of file diff --git a/src/STMUART.h b/src/STMUART.h deleted file mode 100644 index 8451aa2..0000000 --- a/src/STMUART.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2020 by Jonathan Naylor G4KLX - * Copyright (c) 2020 by Geoffrey Merck F4FXL - KC3FRA - * - * 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. - */ - -#if defined(STM32F4XX) || defined(STM32F7XX) -#if !defined(STMUART_H) -#define STMUART_H - -#if defined(STM32F4XX) -#include "stm32f4xx.h" -#elif defined(STM32F7XX) -#include "stm32f7xx.h" -#endif - -const uint16_t BUFFER_SIZE = 2048U; //needs to be a power of 2 ! -const uint16_t BUFFER_MASK = BUFFER_SIZE - 1; - -class CSTMUARTFIFO { -public: - CSTMUARTFIFO() : - m_head(0U), - m_tail(0U) - { - } - - void put(uint8_t data) - { - m_buffer[BUFFER_MASK & (m_head++)] = data; - } - - uint8_t get() - { - return m_buffer[BUFFER_MASK & (m_tail++)]; - } - - void reset() - { - m_tail = 0U; - m_head = 0U; - } - - bool isEmpty() - { - return m_tail == m_head; - } - - bool isFull() - { - return ((m_head + 1U) & BUFFER_MASK) == (m_tail & BUFFER_MASK); - } - -private: - volatile uint8_t m_buffer[BUFFER_SIZE]; - volatile uint16_t m_head; - volatile uint16_t m_tail; -}; - -class CSTMUART { -public: - CSTMUART(); - void init(USART_TypeDef* usart); - void write(const uint8_t * data, uint16_t length); - uint8_t read(); - void handleIRQ(); - void flush(); - uint16_t available(); - uint16_t availableForWrite(); - -private: - USART_TypeDef * m_usart; - CSTMUARTFIFO m_rxFifo; - CSTMUARTFIFO m_txFifo; -}; - -#endif -#endif \ No newline at end of file diff --git a/src/SerialArduino.cpp b/src/SerialArduino.cpp deleted file mode 100644 index 74fa70f..0000000 --- a/src/SerialArduino.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2016,2017 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 - * 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. - */ - -#include "Config.h" -#include "Globals.h" - -#include "SerialPort.h" - -#if defined(VK6MST_TEENSY_PI3_SHIELD_I2C) -//it will load I2CTeensy.cpp - -#elif defined(__SAM3X8E__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__) - -void CSerialPort::beginInt(uint8_t n, int speed) -{ - switch (n) { - case 1U: - Serial.begin(speed); - break; - case 2U: - Serial2.begin(speed); - break; - case 3U: - Serial3.begin(speed); - break; - default: - break; - } -} - -int CSerialPort::availableForReadInt(uint8_t n) -{ - switch (n) { - case 1U: - return Serial.available(); - case 2U: - return Serial2.available(); - case 3U: - return Serial3.available(); - default: - return false; - } -} - -int CSerialPort::availableForWriteInt(uint8_t n) -{ - switch (n) { - case 1U: - return Serial.availableForWrite(); - case 2U: - return Serial2.availableForWrite(); - case 3U: - return Serial3.availableForWrite(); - default: - return false; - } -} - -uint8_t CSerialPort::readInt(uint8_t n) -{ - switch (n) { - case 1U: - return Serial.read(); - case 2U: - return Serial2.read(); - case 3U: - return Serial3.read(); - default: - return 0U; - } -} - -void CSerialPort::writeInt(uint8_t n, const uint8_t* data, uint16_t length, bool flush) -{ - switch (n) { - case 1U: - Serial.write(data, length); - if (flush) - Serial.flush(); - break; - case 2U: - Serial2.write(data, length); - if (flush) - Serial2.flush(); - break; - case 3U: - Serial3.write(data, length); - if (flush) - Serial3.flush(); - break; - default: - break; - } -} - -#endif - diff --git a/src/SerialSTM.cpp b/src/SerialSTM.cpp deleted file mode 100644 index f423de7..0000000 --- a/src/SerialSTM.cpp +++ /dev/null @@ -1,451 +0,0 @@ -/* - * Copyright (C) 2016 by Jim McLaughlin KI6ZUM - * Copyright (C) 2016,2017,2018 by Andy Uribe CA6JAU - * Copyright (c) 2017 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 - * 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. - */ - -#include "Config.h" -#include "Globals.h" - -#include "SerialPort.h" - -/* -Pin definitions: - -- Host communication: -USART1 - TXD PA9 - RXD PA10 (MMDVM-Pi board, MMDVM-Pi F722 board, MMDVM-F4M board, STM32F722-F7M board, STM32F4-DVM board, STM32F7-DVM board) -USART2 - TXD PA2 - RXD PA3 (Nucleo64 F446RE board, Morpho or Arduino header, MMDVM_RPT_Hat BG4TGO/BG5HHP board) -USART3 - TXD PC10 - RXD PC11 (Discovery board) -USART3 - TXD PD8 - RXD PD9 (Nucleo144 F767ZI board) - -- Serial repeater: -USART1 - TXD PA9 - RXD PA10 (Nucleo with Arduino header) -UART5 - TXD PC12 - RXD PD2 (Discovery, MMDVM-Pi, MMDVM-Pi F722 board, MMDVM-F4M board, STM32F722-F7M board, STM32F4-DVM board, STM32F7-DVM board, Nucleo64 with Morpho header and Nucleo144 F767ZI, MMDVM_RPT_Hat BG4TGO/BG5HHP board) -*/ - -#if defined(STM32F4XX) || defined(STM32F7XX) - -#include "STMUART.h" -extern "C" { - void USART1_IRQHandler(); - void USART2_IRQHandler(); - void USART3_IRQHandler(); - void UART5_IRQHandler(); -} - -/* ************* USART1 ***************** */ -#if defined(STM32F4_PI) || defined(STM32F4_F4M) || defined(STM32F722_F7M) || defined(STM32F722_PI) || defined(STM32F722_RPT_HAT) || defined(STM32F4_DVM) || defined(STM32F7_DVM) || (defined(STM32F4_NUCLEO) && defined(STM32F4_NUCLEO_ARDUINO_HEADER)) || defined(DRCC_DVM) || defined(STM32F4_EDA_405) || defined(STM32F4_EDA_446) - - -static CSTMUART m_USART1; - -void USART1_IRQHandler() -{ - m_USART1.handleIRQ(); -} - -void InitUSART1(int speed) -{ - // USART1 - TXD PA9 - RXD PA10 - pins on mmdvm pi board - GPIO_InitTypeDef GPIO_InitStructure; - USART_InitTypeDef USART_InitStructure; - NVIC_InitTypeDef NVIC_InitStructure; - - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); - RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); - GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1); - GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1); - - // USART IRQ init - NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; - NVIC_Init(&NVIC_InitStructure); - - // Configure USART as alternate function - GPIO_StructInit(&GPIO_InitStructure); - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; // Tx | Rx - GPIO_InitStructure.GPIO_Speed = GPIO_Fast_Speed; - GPIO_Init(GPIOA, &GPIO_InitStructure); - - // Configure USART baud rate - USART_StructInit(&USART_InitStructure); - USART_InitStructure.USART_BaudRate = speed; - USART_InitStructure.USART_WordLength = USART_WordLength_8b; - USART_InitStructure.USART_StopBits = USART_StopBits_1; - USART_InitStructure.USART_Parity = USART_Parity_No; - USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; - USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; - USART_Init(USART1, &USART_InitStructure); - - USART_Cmd(USART1, ENABLE); - - USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); - - m_USART1.init(USART1); -} - -#endif - -/* ************* USART2 ***************** */ -#if defined(STM32F4_NUCLEO) || defined(STM32F4_RPT_HAT_TGO) || defined(DRCC_DVM) - -static CSTMUART m_USART2; - - -void USART2_IRQHandler() -{ - m_USART2.handleIRQ(); -} - -void InitUSART2(int speed) -{ - // USART2 - TXD PA2 - RXD PA3 - GPIO_InitTypeDef GPIO_InitStructure; - USART_InitTypeDef USART_InitStructure; - NVIC_InitTypeDef NVIC_InitStructure; - - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); - RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); - GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2); - GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2); - - // USART IRQ init - NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; - NVIC_Init(&NVIC_InitStructure); - - // Configure USART as alternate function - GPIO_StructInit(&GPIO_InitStructure); - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3; // Tx | Rx - GPIO_InitStructure.GPIO_Speed = GPIO_Fast_Speed; - GPIO_Init(GPIOA, &GPIO_InitStructure); - - // Configure USART baud rate - USART_StructInit(&USART_InitStructure); - USART_InitStructure.USART_BaudRate = speed; - USART_InitStructure.USART_WordLength = USART_WordLength_8b; - USART_InitStructure.USART_StopBits = USART_StopBits_1; - USART_InitStructure.USART_Parity = USART_Parity_No; - USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; - USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; - USART_Init(USART2, &USART_InitStructure); - - USART_Cmd(USART2, ENABLE); - - USART_ITConfig(USART2, USART_IT_RXNE, ENABLE); - - m_USART2.init(USART2); -} - -#endif - -/* ************* USART3 ***************** */ -#if defined(STM32F4_DISCOVERY) || defined(STM32F7_NUCLEO) - -static CSTMUART m_USART3; - -void USART3_IRQHandler() -{ - m_USART3.handleIRQ(); -} - -#if defined(STM32F7_NUCLEO) -// USART3 - TXD PD8 - RXD PD9 -#define USART3_GPIO_PinSource_TX GPIO_PinSource8 -#define USART3_GPIO_PinSource_RX GPIO_PinSource9 -#define USART3_GPIO_Pin_TX GPIO_Pin_8 -#define USART3_GPIO_Pin_RX GPIO_Pin_9 -#define USART3_GPIO_PORT GPIOD -#define USART3_RCC_Periph RCC_AHB1Periph_GPIOD -#else -// USART3 - TXD PC10 - RXD PC11 -#define USART3_GPIO_PinSource_TX GPIO_PinSource10 -#define USART3_GPIO_PinSource_RX GPIO_PinSource11 -#define USART3_GPIO_Pin_TX GPIO_Pin_10 -#define USART3_GPIO_Pin_RX GPIO_Pin_11 -#define USART3_GPIO_PORT GPIOC -#define USART3_RCC_Periph RCC_AHB1Periph_GPIOC -#endif - -void InitUSART3(int speed) -{ - GPIO_InitTypeDef GPIO_InitStructure; - USART_InitTypeDef USART_InitStructure; - NVIC_InitTypeDef NVIC_InitStructure; - - RCC_AHB1PeriphClockCmd(USART3_RCC_Periph, ENABLE); - RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE); - GPIO_PinAFConfig(USART3_GPIO_PORT, USART3_GPIO_PinSource_TX, GPIO_AF_USART3); - GPIO_PinAFConfig(USART3_GPIO_PORT, USART3_GPIO_PinSource_RX, GPIO_AF_USART3); - - // USART IRQ init - NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; - NVIC_Init(&NVIC_InitStructure); - - // Configure USART as alternate function - GPIO_StructInit(&GPIO_InitStructure); - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStructure.GPIO_Pin = USART3_GPIO_Pin_TX | USART3_GPIO_Pin_RX; // Tx | Rx - GPIO_InitStructure.GPIO_Speed = GPIO_Fast_Speed; - GPIO_Init(USART3_GPIO_PORT, &GPIO_InitStructure); - - // Configure USART baud rate - USART_StructInit(&USART_InitStructure); - USART_InitStructure.USART_BaudRate = speed; - USART_InitStructure.USART_WordLength = USART_WordLength_8b; - USART_InitStructure.USART_StopBits = USART_StopBits_1; - USART_InitStructure.USART_Parity = USART_Parity_No; - USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; - USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; - USART_Init(USART3, &USART_InitStructure); - - USART_Cmd(USART3, ENABLE); - - USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); - - m_USART3.init(USART3); -} - -#endif - -/* ************* UART5 ***************** */ -#if !(defined(STM32F4_NUCLEO) && defined(STM32F4_NUCLEO_ARDUINO_HEADER)) - -static CSTMUART m_UART5; - -void UART5_IRQHandler() -{ - m_UART5.handleIRQ(); -} - -void InitUART5(int speed) -{ - // UART5 - TXD PC12 - RXD PD2 - GPIO_InitTypeDef GPIO_InitStructure; - USART_InitTypeDef USART_InitStructure; - NVIC_InitTypeDef NVIC_InitStructure; - - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); - RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); - RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE); - GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_UART5); - GPIO_PinAFConfig(GPIOD, GPIO_PinSource2, GPIO_AF_UART5); - - // USART IRQ init - NVIC_InitStructure.NVIC_IRQChannel = UART5_IRQn; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; - NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; - NVIC_Init(&NVIC_InitStructure); - - // Configure USART as alternate function - GPIO_StructInit(&GPIO_InitStructure); - GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; - GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; - GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; // Tx - GPIO_InitStructure.GPIO_Speed = GPIO_Fast_Speed; - GPIO_Init(GPIOC, &GPIO_InitStructure); - - GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; // Rx - GPIO_Init(GPIOD, &GPIO_InitStructure); - - // Configure USART baud rate - USART_StructInit(&USART_InitStructure); - USART_InitStructure.USART_BaudRate = speed; - USART_InitStructure.USART_WordLength = USART_WordLength_8b; - USART_InitStructure.USART_StopBits = USART_StopBits_1; - USART_InitStructure.USART_Parity = USART_Parity_No; - USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None; - USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; - USART_Init(UART5, &USART_InitStructure); - - USART_Cmd(UART5, ENABLE); - - USART_ITConfig(UART5, USART_IT_RXNE, ENABLE); - - m_UART5.init(UART5); -} - -#endif -///////////////////////////////////////////////////////////////// - -void CSerialPort::beginInt(uint8_t n, int speed) -{ - switch (n) { - case 1U: - #if defined(STM32F4_DISCOVERY) || defined(STM32F7_NUCLEO) - InitUSART3(speed); - #elif defined(STM32F4_PI) || defined(STM32F4_F4M) || defined(STM32F722_PI) || defined(STM32F722_F7M) || defined(STM32F722_RPT_HAT) || defined(STM32F4_DVM) || defined(STM32F7_DVM) || defined(STM32F4_EDA_405) || defined(STM32F4_EDA_446) - InitUSART1(speed); - #elif defined(STM32F4_NUCLEO) || defined(STM32F4_RPT_HAT_TGO) - InitUSART2(speed); - #elif defined(DRCC_DVM) - InitUSART1(speed); - #endif - break; - case 3U: - #if defined(STM32F4_NUCLEO) && defined(STM32F4_NUCLEO_ARDUINO_HEADER) - InitUSART1(speed); - #elif defined(DRCC_DVM) - InitUSART2(speed); - #else - InitUART5(speed); - #endif - break; - default: - break; - } -} - -int CSerialPort::availableForReadInt(uint8_t n) -{ - switch (n) { - case 1U: - #if defined(STM32F4_DISCOVERY) || defined(STM32F7_NUCLEO) - return m_USART3.available();//AvailUSART3(); - #elif defined(STM32F4_PI) || defined(STM32F4_F4M) || defined(STM32F722_PI) || defined(STM32F722_F7M) || defined(STM32F722_RPT_HAT) || defined(STM32F4_DVM) || defined(STM32F7_DVM) || defined(STM32F4_EDA_405) || defined(STM32F4_EDA_446) - return m_USART1.available();//AvailUSART1(); - #elif defined(STM32F4_NUCLEO) || defined(STM32F4_RPT_HAT_TGO) - return m_USART2.available();//AvailUSART2(); - #elif defined(DRCC_DVM) - return m_USART1.available();//AvailUSART1(); - #endif - case 3U: - #if defined(STM32F4_NUCLEO) && defined(STM32F4_NUCLEO_ARDUINO_HEADER) - return m_USART1.available(); //AvailUSART1(); - #elif defined(DRCC_DVM) - return m_USART2.available(); //AvailUSART2(); - #else - return m_UART5.available();//AvailUART5(); - #endif - default: - return 0; - } -} - -int CSerialPort::availableForWriteInt(uint8_t n) -{ - switch (n) { - case 1U: - #if defined(STM32F4_DISCOVERY) || defined(STM32F7_NUCLEO) - return m_USART3.availableForWrite(); //AvailForWriteUSART3(); - #elif defined(STM32F4_PI) || defined(STM32F4_F4M) || defined(STM32F722_PI) || defined(STM32F722_F7M) || defined(STM32F722_RPT_HAT) || defined(STM32F4_DVM) || defined(STM32F7_DVM) || defined(STM32F4_EDA_405) || defined(STM32F4_EDA_446) - return m_USART1.availableForWrite(); //AvailForWriteUSART1(); - #elif defined(STM32F4_NUCLEO) || defined(STM32F4_RPT_HAT_TGO) - return m_USART2.availableForWrite();//AvailForWriteUSART2(); - #elif defined(DRCC_DVM) - return m_USART1.availableForWrite();//AvailForWriteUSART1(); - #endif - case 3U: - #if defined(STM32F4_NUCLEO) && defined(STM32F4_NUCLEO_ARDUINO_HEADER) - return m_USART1.availableForWrite(); //AvailForWriteUSART1(); - #elif defined(DRCC_DVM) - return m_USART2.availableForWrite();//AvailForWriteUSART2(); - #else - return m_UART5.availableForWrite();//AvailForWriteUART5(); - #endif - default: - return 0; - } -} - -uint8_t CSerialPort::readInt(uint8_t n) -{ - switch (n) { - case 1U: - #if defined(STM32F4_DISCOVERY) || defined(STM32F7_NUCLEO) - return m_USART3.read();//ReadUSART3(); - #elif defined(STM32F4_PI) || defined(STM32F4_F4M) || defined(STM32F722_PI) || defined(STM32F722_F7M) || defined(STM32F722_RPT_HAT) || defined(STM32F4_DVM) || defined(STM32F7_DVM) || defined(STM32F4_EDA_405) || defined(STM32F4_EDA_446) - return m_USART1.read();//ReadUSART1(); - #elif defined(STM32F4_NUCLEO) || defined(STM32F4_RPT_HAT_TGO) - return m_USART2.read();//ReadUSART2(); - #elif defined(DRCC_DVM) - return m_USART1.read();//ReadUSART1(); - #endif - case 3U: - #if defined(STM32F4_NUCLEO) && defined(STM32F4_NUCLEO_ARDUINO_HEADER) - return m_USART1.read();//ReadUSART1(); - #elif defined(DRCC_DVM) - return m_USART2.read();//ReadUSART2(); - #else - return m_UART5.read();//ReadUART5(); - #endif - default: - return 0U; - } -} - -void CSerialPort::writeInt(uint8_t n, const uint8_t* data, uint16_t length, bool flush) -{ - switch (n) { - case 1U: - #if defined(STM32F4_DISCOVERY) || defined(STM32F7_NUCLEO) - m_USART3.write(data, length); //WriteUSART3(data, length); - if (flush) - m_USART3.flush();//TXSerialFlush3(); - #elif defined(STM32F4_PI) || defined(STM32F4_F4M) || defined(STM32F722_PI) || defined(STM32F722_F7M) || defined(STM32F722_RPT_HAT) || defined(STM32F4_DVM) || defined(STM32F7_DVM) || defined(STM32F4_EDA_405) || defined(STM32F4_EDA_446) - m_USART1.write(data, length);//WriteUSART1(data, length); - if (flush) - m_USART1.flush();//TXSerialFlush1(); - #elif defined(STM32F4_NUCLEO) || defined(STM32F4_RPT_HAT_TGO) - m_USART2.write(data, length);//WriteUSART2(data, length); - if (flush) - m_USART2.flush();//TXSerialFlush2(); - #elif defined(DRCC_DVM) - m_USART1.write(data, length);//WriteUSART1(data, length); - if (flush) - m_USART1.flush();//TXSerialFlush1(); - #endif - break; - case 3U: - #if defined(STM32F4_NUCLEO) && defined(STM32F4_NUCLEO_ARDUINO_HEADER) - m_USART1.write(data, length); //WriteUSART1(data, length); - if (flush) - m_USART1.flush(); - #elif defined(DRCC_DVM) - m_USART2.write(data, length);//WriteUSART2(data, length); - if (flush) - m_USART2.flush();//TXSerialFlush2(); - #else - m_UART5.write(data, length);//WriteUART5(data, length); - if (flush) - m_UART5.flush();//TXSerialFlush5(); - #endif - break; - default: - break; - } -} - -#endif - diff --git a/src/SerialTeensy.cpp b/src/SerialTeensy.cpp deleted file mode 100644 index 2685151..0000000 --- a/src/SerialTeensy.cpp +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright (C) 2017 by Chris Huitema - * - * 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. - * - * 28-4-2017 Created for MMDVM Pi shield for Teensy by Chris Huitema - */ - -#include "Config.h" -#include "Globals.h" - -#if defined(VK6MST_TEENSY_PI3_SHIELD_I2C) - -#include //available here https://github.com/nox771/i2c_t3 or maybe the normal wire will work #include justs need to test i guess - -#define I2C_ADDRESS 0x22 -#define I2C_SPEED 100000 - -// Function prototypes -void receiveEvent(size_t count); -void requestEvent(void); - -#define TX_FIFO_SIZE 512U -#define RX_FIFO_SIZE 512U - -volatile uint8_t TXfifo[TX_FIFO_SIZE]; -volatile uint8_t RXfifo[RX_FIFO_SIZE]; -volatile uint16_t TXfifohead, TXfifotail; -volatile uint16_t RXfifohead, RXfifotail; - -// Init queues -void TXfifoinit(void) -{ - TXfifohead = 0U; - TXfifotail = 0U; -} - -void RXfifoinit() -{ - RXfifohead = 0U; - RXfifotail = 0U; -} - -// How full is queue - -uint16_t TXfifolevel(void) -{ - uint32_t tail = TXfifotail; - uint32_t head = TXfifohead; - - if (tail > head) - return TX_FIFO_SIZE + head - tail; - else - return head - tail; -} - -uint16_t RXfifolevel(void) -{ - uint32_t tail = RXfifotail; - uint32_t head = RXfifohead; - - if (tail > head) - return RX_FIFO_SIZE + head - tail; - else - return head - tail; -} - - -uint8_t TXfifoput(uint8_t next) -{ - if (TXfifolevel() < TX_FIFO_SIZE) { - TXfifo[TXfifohead] = next; - - TXfifohead++; - if (TXfifohead >= TX_FIFO_SIZE) - TXfifohead = 0U; - return 1U; - } else { - return 0U; // signal an overflow occurred by returning a zero count - } -} - -void I2Cbegin(void) -{ - // Setup for Slave mode, address 0x22, pins 18/19, external pullups, speed in hz - Wire.begin(I2C_SLAVE, I2C_ADDRESS, I2C_PINS_18_19, I2C_PULLUP_EXT, I2C_SPEED); - - // register events - Wire.onReceive(receiveEvent); - Wire.onRequest(requestEvent); - - // initialize the fifos - TXfifoinit(); - RXfifoinit(); -} - - -int I2Cavailable(void) -{ - if (RXfifolevel() > 0U) - return 1U; - else - return 0U; -} - - -uint8_t I2Cread(void) -{ - uint8_t data_c = RXfifo[RXfifotail]; - - RXfifotail++; - if (RXfifotail >= RX_FIFO_SIZE) - RXfifotail = 0U; - - return data_c; -} - - -void I2Cwrite(const uint8_t* data, uint16_t length) -{ - for (uint16_t i = 0U; i < length; i++) - TXfifoput(data[i]); //puts it in the fifo -} - -// -// handle Rx Event (incoming I2C data) -// -void receiveEvent(size_t count) -{ - for (uint16_t i = 0U; i < count; i++) - { - if (RXfifolevel() < RX_FIFO_SIZE) { - RXfifo[RXfifohead] = Wire.readByte(); - if (RXfifo[RXfifohead] != -1){ - RXfifohead++; - if (RXfifohead >= RX_FIFO_SIZE) RXfifohead = 0U; - } - } else { - Wire.readByte(); // drop data if mem full. - } - - } -} - -// -// handle Tx Event (outgoing I2C data) -// -void requestEvent(void) -{ - if (TXfifolevel() > 0) { - if (Wire.write(TXfifo[TXfifotail])){ //write to i2c - TXfifotail++; - if (TXfifotail >= TX_FIFO_SIZE) TXfifotail = 0U; - } - } -} - - - -/************************************/ - -void CSerialPort::beginInt(uint8_t n, int speed) -{ - switch (n) { - case 1U: - return I2Cbegin(); - case 3U: - Serial3.begin(speed); - break; - default: - break; - } -} - -int CSerialPort::availableForReadInt(uint8_t n) -{ - switch (n) { - case 1U: - return I2Cavailable(); - case 3U: - return Serial3.available(); - default: - return false; - } -} - -int CSerialPort::availableForWriteInt(uint8_t n) -{ - switch (n) { - case 3U: - return Serial3.availableForWrite(); - default: - return false; - } -} - -uint8_t CSerialPort::readInt(uint8_t n) -{ - switch (n) { - case 1U: - return I2Cread(); - case 3U: - return Serial3.read(); - default: - return 0U; - } -} - -void CSerialPort::writeInt(uint8_t n, const uint8_t* data, uint16_t length, bool flush) -{ - switch (n) { - case 1U: - I2Cwrite(data, length); - break; - case 3U: - Serial3.write(data, length); - if (flush) - Serial3.flush(); - break; - default: - break; - } -} - -#endif