Merge remote-tracking branch 'g4klx/master'

48kHz
Andy CA6JAU 2016-11-15 13:57:16 -03:00
commit 5cfd985569
3 changed files with 70 additions and 53 deletions

View File

@ -36,7 +36,7 @@
#if defined(__SAM3X8E__) #if defined(__SAM3X8E__)
#define ARM_MATH_CM3 #define ARM_MATH_CM3
#elif defined(STM32F4XX) || defined(STM32F4) || defined(__MK20DX256__) || defined(__MK66FX1M0__) #elif defined(STM32F4XX) || defined(STM32F4) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
#define ARM_MATH_CM4 #define ARM_MATH_CM4
#else #else
#error "Unknown processor type" #error "Unknown processor type"

View File

@ -20,10 +20,8 @@
#include "Globals.h" #include "Globals.h"
#include "IO.h" #include "IO.h"
#if defined(__MK20DX256__) || defined(__MK66FX1M0__) #if defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
// A Teensy 3.1/3.2
#if defined(__MK20DX256__)
#define PIN_LED 13 #define PIN_LED 13
#define PIN_COS 52 #define PIN_COS 52
#define PIN_PTT 23 #define PIN_PTT 23
@ -35,22 +33,8 @@
#define PIN_ADC 5 // A0 #define PIN_ADC 5 // A0
#define PIN_RSSI 8 // A2 #define PIN_RSSI 8 // A2
// A Teensy 3.6 #define PDB_CHnC1_TOS 0x0100
#elif defined(__MK66FX1M0__) #define PDB_CHnC1_EN 0x0001
#define PIN_LED 13
#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_ADC 5 // A0
#define PIN_RSSI 8 // A2
#endif
#define PDB_CH0C1_TOS 0x0100
#define PDB_CH0C1_EN 0x01
const uint16_t DC_OFFSET = 2048U; const uint16_t DC_OFFSET = 2048U;
@ -66,6 +50,21 @@ extern "C" {
io.interrupt(1U); io.interrupt(1U);
} }
#endif #endif
#if defined(EXTERNAL_OSC)
void ftm0_isr()
{
FTM0_CNT = 0; // Reset count value
if ((FTM0_SC & FTM_SC_TOF) == FTM_SC_TOF) // Read the timer overflow flag (TOF in FTM0_SC)
FTM0_SC &= ~FTM_SC_TOF; // If set, clear overflow flag
// Kick off the ADCs with interrupt at the end of conversion
ADC0_SC1A = ADC_SC1_AIEN | PIN_ADC;
#if defined(SEND_RSSI_DATA)
ADC1_SC1A = ADC_SC1_AIEN | PIN_RSSI;
#endif
}
#endif
} }
void CIO::initInt() void CIO::initInt()
@ -96,13 +95,17 @@ void CIO::startInt()
#endif #endif
// Initialise ADC0 // Initialise ADC0
SIM_SCGC6 |= SIM_SCGC6_ADC0;
ADC0_CFG1 = ADC_CFG1_ADIV(1) | ADC_CFG1_ADICLK(1) | ADC_CFG1_MODE(1) | ADC0_CFG1 = ADC_CFG1_ADIV(1) | ADC_CFG1_ADICLK(1) | ADC_CFG1_MODE(1) |
ADC_CFG1_ADLSMP; // Single-ended 12 bits, long sample time ADC_CFG1_ADLSMP; // Single-ended 12 bits, long sample time
ADC0_CFG2 = ADC_CFG2_MUXSEL | ADC_CFG2_ADLSTS(2); // Select channels ADxxxb ADC0_CFG2 = ADC_CFG2_MUXSEL | ADC_CFG2_ADLSTS(2); // Select channels ADxxxb
#if defined(EXTERNAL_OSC)
ADC0_SC2 = ADC_SC2_REFSEL(1); // Voltage ref internal, software trigger
#else
ADC0_SC2 = ADC_SC2_REFSEL(1) | ADC_SC2_ADTRG; // Voltage ref internal, hardware trigger ADC0_SC2 = ADC_SC2_REFSEL(1) | ADC_SC2_ADTRG; // Voltage ref internal, hardware trigger
ADC0_SC3 = ADC_SC3_AVGE | ADC_SC3_AVGS(0); // Enable averaging, 4 samples #endif
ADC0_SC3 = ADC_SC3_CAL | ADC_SC3_AVGE | ADC_SC3_AVGS(0); // Enable averaging, 4 samples
ADC0_SC3 = ADC_SC3_CAL; // Begin calibration
while ((ADC0_SC3 & ADC_SC3_CAL) == ADC_SC3_CAL) // Wait for calibration while ((ADC0_SC3 & ADC_SC3_CAL) == ADC_SC3_CAL) // Wait for calibration
; ;
@ -110,18 +113,25 @@ void CIO::startInt()
sum0 = (sum0 / 2U) | 0x8000U; sum0 = (sum0 / 2U) | 0x8000U;
ADC0_PG = sum0; ADC0_PG = sum0;
#if !defined(EXTERNAL_OSC)
ADC0_SC1A = ADC_SC1_AIEN | PIN_ADC; // Enable ADC interrupt, use A0 ADC0_SC1A = ADC_SC1_AIEN | PIN_ADC; // Enable ADC interrupt, use A0
#endif
NVIC_ENABLE_IRQ(IRQ_ADC0); NVIC_ENABLE_IRQ(IRQ_ADC0);
#if defined(SEND_RSSI_DATA) #if defined(SEND_RSSI_DATA)
// Initialise ADC1 // Initialise ADC1
SIM_SCGC3 |= SIM_SCGC3_ADC1;
ADC1_CFG1 = ADC_CFG1_ADIV(1) | ADC_CFG1_ADICLK(1) | ADC_CFG1_MODE(1) | ADC1_CFG1 = ADC_CFG1_ADIV(1) | ADC_CFG1_ADICLK(1) | ADC_CFG1_MODE(1) |
ADC_CFG1_ADLSMP; // Single-ended 12 bits, long sample time ADC_CFG1_ADLSMP; // Single-ended 12 bits, long sample time
ADC1_CFG2 = ADC_CFG2_MUXSEL | ADC_CFG2_ADLSTS(2); // Select channels ADxxxb ADC1_CFG2 = ADC_CFG2_MUXSEL | ADC_CFG2_ADLSTS(2); // Select channels ADxxxb
#if defined(EXTERNAL_OSC)
ADC1_SC2 = ADC_SC2_REFSEL(1); // Voltage ref internal, software trigger
#else
ADC1_SC2 = ADC_SC2_REFSEL(1) | ADC_SC2_ADTRG; // Voltage ref internal, hardware trigger ADC1_SC2 = ADC_SC2_REFSEL(1) | ADC_SC2_ADTRG; // Voltage ref internal, hardware trigger
ADC1_SC3 = ADC_SC3_AVGE | ADC_SC3_AVGS(0); // Enable averaging, 4 samples #endif
ADC1_SC3 = ADC_SC3_CAL | ADC_SC3_AVGE | ADC_SC3_AVGS(0); // Enable averaging, 4 samples
ADC1_SC3 = ADC_SC3_CAL; // Begin calibration
while ((ADC1_SC3 & ADC_SC3_CAL) == ADC_SC3_CAL) // Wait for calibration while ((ADC1_SC3 & ADC_SC3_CAL) == ADC_SC3_CAL) // Wait for calibration
; ;
@ -129,26 +139,34 @@ void CIO::startInt()
sum1 = (sum1 / 2U) | 0x8000U; sum1 = (sum1 / 2U) | 0x8000U;
ADC1_PG = sum1; ADC1_PG = sum1;
#if !defined(EXTERNAL_OSC)
ADC1_SC1A = ADC_SC1_AIEN | PIN_RSSI; // Enable ADC interrupt, use A2 ADC1_SC1A = ADC_SC1_AIEN | PIN_RSSI; // Enable ADC interrupt, use A2
#endif
NVIC_ENABLE_IRQ(IRQ_ADC1); NVIC_ENABLE_IRQ(IRQ_ADC1);
#endif #endif
// Setup PDB for ADC0 at 24 kHz #if defined(EXTERNAL_OSC)
SIM_SCGC6 |= SIM_SCGC6_PDB; // Enable PDB clock // Set up for an external oscillator input
#if F_BUS == 60000000 SIM_SCGC6 |= SIM_SCGC6_FTM0;
// 60 MHz for the Teensy 3.5/3.6 FTM0_MODE = FTM_MODE_WPDIS | FTM_MODE_FTMEN;
PDB0_MOD = 2500 - 1; // Timer period for 60 MHz bus FTM0_MOD = EXTERNAL_OSC / 24000;
FTM0_CNTIN = 0;
FTM0_SC = FTM_SC_TOIE | FTM_SC_CLKS(3); // External clock, overflow interrupts, no prescaling
NVIC_ENABLE_IRQ(IRQ_FTM0);
#else #else
// 48 MHz for the Teensy 3.1/3.2 // Setup PDB for ADC0 (and ADC1) at 24 kHz
PDB0_MOD = 2000 - 1; // Timer period for 48 MHz bus SIM_SCGC6 |= SIM_SCGC6_PDB; // Enable PDB clock
#endif PDB0_MOD = F_BUS / 24000; // Timer period
PDB0_IDLY = 0; // Interrupt delay PDB0_IDLY = 0; // Interrupt delay
PDB0_CH0C1 = PDB_CH0C1_TOS | PDB_CH0C1_EN; // Enable pre-trigger PDB0_CH0C1 = PDB_CHnC1_TOS | PDB_CHnC1_EN; // Enable pre-trigger for ADC0
PDB0_SC = PDB_SC_TRGSEL(15) | PDB_SC_PDBEN | PDB_SC_PDBIE | #if defined(SEND_RSSI_DATA)
PDB_SC_CONT | PDB_SC_PRESCALER(7) | PDB_SC_MULT(1) | PDB0_CH1C1 = PDB_CHnC1_TOS | PDB_CHnC1_EN; // Enable pre-t9rigger for ADC1
PDB_SC_LDOK; #endif
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) PDB0_SC |= PDB_SC_SWTRIG; // Software trigger (reset and restart counter)
NVIC_ENABLE_IRQ(IRQ_PDB); #endif
// Initialise the DAC // Initialise the DAC
SIM_SCGC2 |= SIM_SCGC2_DAC0; SIM_SCGC2 |= SIM_SCGC2_DAC0;
@ -231,4 +249,3 @@ void CIO::setP25Int(bool on)
} }
#endif #endif

View File

@ -1,7 +1,7 @@
This is the source code of the MMDVM firmware that supports D-Star, DMR, System Fusion and P25. This is the source code of the MMDVM firmware that supports D-Star, DMR, System Fusion and P25.
It runs on the Arduino Due, and the STM32F4xx platforms. Support for the Teensy (3.1/3.2 and 3.6) is being added. It runs on the Arduino Due and the ST-Micro STM32F4xx platforms. Support for the Teensy (3.1/3.2 and 3.5/3.6) is being added.
In order to build this software for the Arduino Due, you will need to edit a file within the Arduino GUI and that is detailed in the BUILD.txt file. In order to build this software for the Arduino Due, you will need to edit a file within the Arduino GUI and that is detailed in the BUILD.txt file. The STM32 support is being supplied via the Coocox IDE with ARM GCC. The Teensy support is via the latest beta of Teensyduino.
This software is licenced under the GPL v2 and is intended for amateur and educational use only. Use of this software for commercial purposes is strictly forbidden. This software is licenced under the GPL v2 and is intended for amateur and educational use only. Use of this software for commercial purposes is strictly forbidden.