mirror of https://github.com/g4klx/MMDVM.git
Try and build under PlatformIO
This commit is contained in:
parent
9e7f1040f8
commit
81b0ce126d
|
@ -3,3 +3,5 @@ obj/
|
||||||
bin/
|
bin/
|
||||||
GitVersion.h
|
GitVersion.h
|
||||||
build/
|
build/
|
||||||
|
.vscode
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -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_a = (m_a ^ m_c ^ m_x);
|
||||||
m_b = (m_b + m_a);
|
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()
|
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_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_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
|
return uint8_t(m_c); //low order bits of other variables
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -19,24 +19,8 @@
|
||||||
#if !defined(GLOBALS_H)
|
#if !defined(GLOBALS_H)
|
||||||
#define GLOBALS_H
|
#define GLOBALS_H
|
||||||
|
|
||||||
#if defined(STM32F4XX)
|
|
||||||
#include "stm32f4xx.h"
|
|
||||||
#elif defined(STM32F7XX)
|
|
||||||
#include "stm32f7xx.h"
|
|
||||||
#else
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#undef PI //Undefine PI to get rid of annoying warning as it is also defined in arm_math.h.
|
#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 <arm_math.h>
|
#include <arm_math.h>
|
||||||
|
|
||||||
|
|
32
src/IO.cpp
32
src/IO.cpp
|
@ -237,7 +237,7 @@ void CIO::selfTest()
|
||||||
setFMInt(ledValue);
|
setFMInt(ledValue);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
delayInt(250);
|
::delay(250);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(MODE_LEDS)
|
#if defined(MODE_LEDS)
|
||||||
|
@ -259,63 +259,63 @@ void CIO::selfTest()
|
||||||
#endif
|
#endif
|
||||||
setDStarInt(true);
|
setDStarInt(true);
|
||||||
|
|
||||||
delayInt(250);
|
::delay(250);
|
||||||
setDMRInt(true);
|
setDMRInt(true);
|
||||||
|
|
||||||
delayInt(250);
|
::delay(250);
|
||||||
setYSFInt(true);
|
setYSFInt(true);
|
||||||
|
|
||||||
delayInt(250);
|
::delay(250);
|
||||||
setP25Int(true);
|
setP25Int(true);
|
||||||
|
|
||||||
#if !defined(USE_ALTERNATE_NXDN_LEDS)
|
#if !defined(USE_ALTERNATE_NXDN_LEDS)
|
||||||
delayInt(250);
|
::delay(250);
|
||||||
setNXDNInt(true);
|
setNXDNInt(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(USE_ALTERNATE_M17_LEDS)
|
#if !defined(USE_ALTERNATE_M17_LEDS)
|
||||||
delayInt(250);
|
::delay(250);
|
||||||
setM17Int(true);
|
setM17Int(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(USE_ALTERNATE_POCSAG_LEDS)
|
#if !defined(USE_ALTERNATE_POCSAG_LEDS)
|
||||||
delayInt(250);
|
::delay(250);
|
||||||
setPOCSAGInt(true);
|
setPOCSAGInt(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(USE_ALTERNATE_FM_LEDS)
|
#if !defined(USE_ALTERNATE_FM_LEDS)
|
||||||
delayInt(250);
|
::delay(250);
|
||||||
setFMInt(true);
|
setFMInt(true);
|
||||||
|
|
||||||
delayInt(250);
|
::delay(250);
|
||||||
setFMInt(false);
|
setFMInt(false);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(USE_ALTERNATE_POCSAG_LEDS)
|
#if !defined(USE_ALTERNATE_POCSAG_LEDS)
|
||||||
delayInt(250);
|
::delay(250);
|
||||||
setPOCSAGInt(false);
|
setPOCSAGInt(false);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(USE_ALTERNATE_M17_LEDS)
|
#if !defined(USE_ALTERNATE_M17_LEDS)
|
||||||
delayInt(250);
|
::delay(250);
|
||||||
setM17Int(false);
|
setM17Int(false);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(USE_ALTERNATE_NXDN_LEDS)
|
#if !defined(USE_ALTERNATE_NXDN_LEDS)
|
||||||
delayInt(250);
|
::delay(250);
|
||||||
setNXDNInt(false);
|
setNXDNInt(false);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
delayInt(250);
|
::delay(250);
|
||||||
setP25Int(false);
|
setP25Int(false);
|
||||||
|
|
||||||
delayInt(250);
|
::delay(250);
|
||||||
setYSFInt(false);
|
setYSFInt(false);
|
||||||
|
|
||||||
delayInt(250);
|
::delay(250);
|
||||||
setDMRInt(false);
|
setDMRInt(false);
|
||||||
|
|
||||||
delayInt(250);
|
::delay(250);
|
||||||
setDStarInt(false);
|
setDStarInt(false);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
2
src/IO.h
2
src/IO.h
|
@ -161,8 +161,6 @@ private:
|
||||||
void setPOCSAGInt(bool on);
|
void setPOCSAGInt(bool on);
|
||||||
void setM17Int(bool on);
|
void setM17Int(bool on);
|
||||||
void setFMInt(bool on);
|
void setFMInt(bool on);
|
||||||
|
|
||||||
void delayInt(unsigned int dly);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
323
src/IODue.cpp
323
src/IODue.cpp
|
@ -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
|
|
||||||
|
|
565
src/IOSTM.cpp
565
src/IOSTM.cpp
|
@ -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
|
|
||||||
|
|
289
src/IOTeensy.cpp
289
src/IOTeensy.cpp
|
@ -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
|
|
||||||
|
|
|
@ -18,8 +18,6 @@
|
||||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(STM32F4XX) || defined(STM32F7XX)
|
|
||||||
|
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
|
|
||||||
|
@ -207,13 +205,3 @@ void loop()
|
||||||
if (m_modemState == STATE_IDLE)
|
if (m_modemState == STATE_IDLE)
|
||||||
cwIdTX.process();
|
cwIdTX.process();
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
|
||||||
{
|
|
||||||
setup();
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
loop();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -78,7 +78,7 @@ void CP25TX::process()
|
||||||
for (uint16_t i = 0U; i < m_txDelay; i++)
|
for (uint16_t i = 0U; i < m_txDelay; i++)
|
||||||
m_poBuffer[m_poLen++] = P25_START_SYNC;
|
m_poBuffer[m_poLen++] = P25_START_SYNC;
|
||||||
} else {
|
} else {
|
||||||
uint8_t length;
|
uint8_t length = 0U;
|
||||||
m_buffer.get(length);
|
m_buffer.get(length);
|
||||||
for (uint8_t i = 0U; i < length; i++) {
|
for (uint8_t i = 0U; i < length; i++) {
|
||||||
uint8_t c = 0U;
|
uint8_t c = 0U;
|
||||||
|
|
|
@ -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
|
* Copyright (C) 2020 by Geoffrey Merck F4FXL - KC3FRA
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -20,24 +20,8 @@
|
||||||
#if !defined(RINGBUFFER_H)
|
#if !defined(RINGBUFFER_H)
|
||||||
#define RINGBUFFER_H
|
#define RINGBUFFER_H
|
||||||
|
|
||||||
#if defined(STM32F4XX)
|
|
||||||
#include "stm32f4xx.h"
|
|
||||||
#elif defined(STM32F7XX)
|
|
||||||
#include "stm32f7xx.h"
|
|
||||||
#else
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#undef PI
|
#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 <arm_math.h>
|
#include <arm_math.h>
|
||||||
|
|
||||||
|
|
|
@ -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 <stdint.h>
|
|
||||||
|
|
||||||
/* 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
|
|
100
src/STMUART.cpp
100
src/STMUART.cpp
|
@ -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
|
|
|
@ -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
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
|
@ -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 <i2c_t3.h> //available here https://github.com/nox771/i2c_t3 or maybe the normal wire will work #include <wire.h> 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
|
|
Loading…
Reference in New Issue