mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-27 01:56:14 +01:00
make the Adc class functions the normal code path
This commit is contained in:
parent
367d2dfe20
commit
ee568fcd11
|
@ -425,7 +425,7 @@ void DCCACK::checkAck(byte sentResetsSincePacket) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int current=progDriver->getCurrentRawInInterrupt();
|
int current=progDriver->getCurrentRaw(true); // true means "from interrupt"
|
||||||
numAckSamples++;
|
numAckSamples++;
|
||||||
if (current > ackMaxCurrent) ackMaxCurrent=current;
|
if (current > ackMaxCurrent) ackMaxCurrent=current;
|
||||||
// An ACK is a pulse lasting between minAckPulseDuration and maxAckPulseDuration uSecs (refer @haba)
|
// An ACK is a pulse lasting between minAckPulseDuration and maxAckPulseDuration uSecs (refer @haba)
|
||||||
|
|
|
@ -95,8 +95,12 @@ private:
|
||||||
|
|
||||||
class Adc {
|
class Adc {
|
||||||
public:
|
public:
|
||||||
static void reg(uint8_t pin);
|
// On architectures that use the analog read during DCC waveform
|
||||||
static int read(uint8_t pin);
|
// with specially configured ADC, for example AVR, init must be
|
||||||
|
// called PRIOR to the start of the waveform. It returns the
|
||||||
|
// current value so that an offset can be initialized.
|
||||||
|
static int init(uint8_t pin);
|
||||||
|
static int read(uint8_t pin, bool fromISR);
|
||||||
private:
|
private:
|
||||||
static void scan();
|
static void scan();
|
||||||
static void begin();
|
static void begin();
|
||||||
|
|
|
@ -129,19 +129,26 @@ int * Adc::analogvals = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Register a new pin to be scanned
|
* Register a new pin to be scanned
|
||||||
|
* Returns current reading of pin and
|
||||||
|
* stores that as well
|
||||||
*/
|
*/
|
||||||
void Adc::reg(uint8_t pin) {
|
int Adc::init(uint8_t pin) {
|
||||||
uint8_t id = pin - A0;
|
uint8_t id = pin - A0;
|
||||||
if (id > NUM_ADC_INPUTS)
|
if (id > NUM_ADC_INPUTS)
|
||||||
return;
|
return -1023;
|
||||||
|
pinMode(pin, INPUT);
|
||||||
|
int value = analogRead(pin);
|
||||||
if (analogvals == NULL)
|
if (analogvals == NULL)
|
||||||
analogvals = (int *)calloc(NUM_ADC_INPUTS+1, sizeof(int));
|
analogvals = (int *)calloc(NUM_ADC_INPUTS+1, sizeof(int));
|
||||||
|
analogvals[id] = value;
|
||||||
usedpins |= (1<<id);
|
usedpins |= (1<<id);
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Read function Adc::read(pin) to get value instead of analogRead(pin)
|
* Read function Adc::read(pin) to get value instead of analogRead(pin)
|
||||||
*/
|
*/
|
||||||
int Adc::read(uint8_t pin) {
|
int Adc::read(uint8_t pin, bool fromISR) {
|
||||||
|
(void)fromISR; // AVR does ignore this arg
|
||||||
uint8_t id = pin - A0;
|
uint8_t id = pin - A0;
|
||||||
if ((usedpins & (1<<id) ) == 0)
|
if ((usedpins & (1<<id) ) == 0)
|
||||||
return -1023;
|
return -1023;
|
||||||
|
|
|
@ -78,6 +78,23 @@ int DCCTimer::freeMemory() {
|
||||||
////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
#ifdef ARDUINO_ARCH_ESP32
|
||||||
|
#include <driver/adc.h>
|
||||||
|
#include <soc/sens_reg.h>
|
||||||
|
#include <soc/sens_struct.h>
|
||||||
|
#undef ADC_INPUT_MAX_VALUE
|
||||||
|
#define ADC_INPUT_MAX_VALUE 4095 // 12 bit ADC
|
||||||
|
#define pinToADC1Channel(X) (adc1_channel_t)(((X) > 35) ? (X)-36 : (X)-28)
|
||||||
|
|
||||||
|
int IRAM_ATTR local_adc1_get_raw(int channel) {
|
||||||
|
uint16_t adc_value;
|
||||||
|
SENS.sar_meas_start1.sar1_en_pad = (1 << channel); // only one channel is selected
|
||||||
|
while (SENS.sar_slave_addr1.meas_status != 0);
|
||||||
|
SENS.sar_meas_start1.meas1_start_sar = 0;
|
||||||
|
SENS.sar_meas_start1.meas1_start_sar = 1;
|
||||||
|
while (SENS.sar_meas_start1.meas1_done_sar == 0);
|
||||||
|
adc_value = SENS.sar_meas_start1.meas1_data_sar;
|
||||||
|
return adc_value;
|
||||||
|
}
|
||||||
|
|
||||||
#include "DCCTimer.h"
|
#include "DCCTimer.h"
|
||||||
INTERRUPT_CALLBACK interruptHandler=0;
|
INTERRUPT_CALLBACK interruptHandler=0;
|
||||||
|
@ -133,5 +150,26 @@ int DCCTimer::freeMemory() {
|
||||||
void DCCTimer::reset() {
|
void DCCTimer::reset() {
|
||||||
ESP.restart();
|
ESP.restart();
|
||||||
}
|
}
|
||||||
#endif
|
int Adc::init(uint8_t pin) {
|
||||||
|
pinMode(pin, ANALOG);
|
||||||
|
adc1_config_channel_atten(pinToADC1Channel(pin),ADC_ATTEN_DB_11);
|
||||||
|
return local_adc1_get_raw(pinToADC1Channel(pin));
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Read function Adc::read(pin) to get value instead of analogRead(pin)
|
||||||
|
*/
|
||||||
|
int Adc::read(uint8_t pin, bool fromISR) {
|
||||||
|
return local_adc1_get_raw(pinToADC1Channel(pin));
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Scan function that is called from interrupt
|
||||||
|
*/
|
||||||
|
void Adc::scan() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void Adc::begin() {
|
||||||
|
adc1_config_width(ADC_WIDTH_BIT_12);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //ESP32
|
||||||
|
|
||||||
|
|
|
@ -37,24 +37,6 @@ INTERRUPT_CALLBACK interruptHandler=0;
|
||||||
void DCCTimer::begin(INTERRUPT_CALLBACK callback) {
|
void DCCTimer::begin(INTERRUPT_CALLBACK callback) {
|
||||||
interruptHandler=callback;
|
interruptHandler=callback;
|
||||||
noInterrupts();
|
noInterrupts();
|
||||||
|
|
||||||
// Set up ADC to do faster reads... default for Arduino Zero platform configs is 436uS,
|
|
||||||
// and we need sub-100uS. This code sets it to a read speed of around 21uS, and for now
|
|
||||||
// enables 10-bit mode, although 12-bit is possible
|
|
||||||
ADC->CTRLA.bit.ENABLE = 0; // disable ADC
|
|
||||||
while( ADC->STATUS.bit.SYNCBUSY == 1 ); // wait for synchronization
|
|
||||||
|
|
||||||
ADC->CTRLB.reg &= 0b1111100011111111; // mask PRESCALER bits
|
|
||||||
ADC->CTRLB.reg |= ADC_CTRLB_PRESCALER_DIV64 | // divide Clock by 64
|
|
||||||
ADC_CTRLB_RESSEL_10BIT; // Result on 10 bits default, 12 bits possible
|
|
||||||
|
|
||||||
ADC->AVGCTRL.reg = ADC_AVGCTRL_SAMPLENUM_1 | // take 1 sample at a time
|
|
||||||
ADC_AVGCTRL_ADJRES(0x00ul); // adjusting result by 0
|
|
||||||
ADC->SAMPCTRL.reg = 0x00; // sampling Time Length = 0
|
|
||||||
|
|
||||||
ADC->CTRLA.bit.ENABLE = 1; // enable ADC
|
|
||||||
while(ADC->STATUS.bit.SYNCBUSY == 1); // wait for synchronization
|
|
||||||
|
|
||||||
// Timer setup - setup clock sources first
|
// Timer setup - setup clock sources first
|
||||||
REG_GCLK_GENDIV = GCLK_GENDIV_DIV(1) | // Divide 48MHz by 1
|
REG_GCLK_GENDIV = GCLK_GENDIV_DIV(1) | // Divide 48MHz by 1
|
||||||
GCLK_GENDIV_ID(4); // Apply to GCLK4
|
GCLK_GENDIV_ID(4); // Apply to GCLK4
|
||||||
|
@ -173,4 +155,43 @@ void DCCTimer::reset() {
|
||||||
while(true) {};
|
while(true) {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Adc::init(uint8_t pin) {
|
||||||
|
return analogRead(pin);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Read function Adc::read(pin) to get value instead of analogRead(pin)
|
||||||
|
*/
|
||||||
|
int Adc::read(uint8_t pin, bool fromISR) {
|
||||||
|
int current;
|
||||||
|
if (!fromISR) noInterrupts();
|
||||||
|
current = analogRead(pin);
|
||||||
|
if (!fromISR) interrupts();
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Scan function that is called from interrupt
|
||||||
|
*/
|
||||||
|
void Adc::scan() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void Adc::begin() {
|
||||||
|
noInterrupts();
|
||||||
|
// Set up ADC to do faster reads... default for Arduino Zero platform configs is 436uS,
|
||||||
|
// and we need sub-100uS. This code sets it to a read speed of around 21uS, and for now
|
||||||
|
// enables 10-bit mode, although 12-bit is possible
|
||||||
|
ADC->CTRLA.bit.ENABLE = 0; // disable ADC
|
||||||
|
while( ADC->STATUS.bit.SYNCBUSY == 1 ); // wait for synchronization
|
||||||
|
|
||||||
|
ADC->CTRLB.reg &= 0b1111100011111111; // mask PRESCALER bits
|
||||||
|
ADC->CTRLB.reg |= ADC_CTRLB_PRESCALER_DIV64 | // divide Clock by 64
|
||||||
|
ADC_CTRLB_RESSEL_10BIT; // Result on 10 bits default, 12 bits possible
|
||||||
|
|
||||||
|
ADC->AVGCTRL.reg = ADC_AVGCTRL_SAMPLENUM_1 | // take 1 sample at a time
|
||||||
|
ADC_AVGCTRL_ADJRES(0x00ul); // adjusting result by 0
|
||||||
|
ADC->SAMPCTRL.reg = 0x00; // sampling Time Length = 0
|
||||||
|
|
||||||
|
ADC->CTRLA.bit.ENABLE = 1; // enable ADC
|
||||||
|
while(ADC->STATUS.bit.SYNCBUSY == 1); // wait for synchronization
|
||||||
|
interrupts();
|
||||||
|
}
|
||||||
#endif
|
#endif
|
|
@ -82,10 +82,8 @@ void DCCWaveform::interruptHandler() {
|
||||||
TrackManager::setDCCSignal(sigMain);
|
TrackManager::setDCCSignal(sigMain);
|
||||||
TrackManager::setPROGSignal(sigProg);
|
TrackManager::setPROGSignal(sigProg);
|
||||||
|
|
||||||
#ifdef ANALOG_READ_INTERRUPT
|
// Refresh the values in the Adc object buffering the values of the ADC HW
|
||||||
//TrackManager::sampleCurrent();
|
|
||||||
Adc::scan();
|
Adc::scan();
|
||||||
#endif
|
|
||||||
|
|
||||||
// Move on in the state engine
|
// Move on in the state engine
|
||||||
mainTrack.state=stateTransform[mainTrack.state];
|
mainTrack.state=stateTransform[mainTrack.state];
|
||||||
|
|
|
@ -30,24 +30,6 @@
|
||||||
|
|
||||||
#if defined(ARDUINO_ARCH_ESP32)
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
#include "ESP32-fixes.h"
|
#include "ESP32-fixes.h"
|
||||||
#include <driver/adc.h>
|
|
||||||
#include <soc/sens_reg.h>
|
|
||||||
#include <soc/sens_struct.h>
|
|
||||||
#undef ADC_INPUT_MAX_VALUE
|
|
||||||
#define ADC_INPUT_MAX_VALUE 4095 // 12 bit ADC
|
|
||||||
#define pinToADC1Channel(X) (adc1_channel_t)(((X) > 35) ? (X)-36 : (X)-28)
|
|
||||||
|
|
||||||
int IRAM_ATTR local_adc1_get_raw(int channel) {
|
|
||||||
uint16_t adc_value;
|
|
||||||
SENS.sar_meas_start1.sar1_en_pad = (1 << channel); // only one channel is selected
|
|
||||||
while (SENS.sar_slave_addr1.meas_status != 0);
|
|
||||||
SENS.sar_meas_start1.meas1_start_sar = 0;
|
|
||||||
SENS.sar_meas_start1.meas1_start_sar = 1;
|
|
||||||
while (SENS.sar_meas_start1.meas1_done_sar == 0);
|
|
||||||
adc_value = SENS.sar_meas_start1.meas1_data_sar;
|
|
||||||
return adc_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool MotorDriver::commonFaultPin=false;
|
bool MotorDriver::commonFaultPin=false;
|
||||||
|
@ -110,18 +92,7 @@ MotorDriver::MotorDriver(int16_t power_pin, byte signal_pin, byte signal_pin2, i
|
||||||
|
|
||||||
currentPin=current_pin;
|
currentPin=current_pin;
|
||||||
if (currentPin!=UNUSED_PIN) {
|
if (currentPin!=UNUSED_PIN) {
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
senseOffset = Adc::init(currentPin);
|
||||||
pinMode(currentPin, ANALOG);
|
|
||||||
adc1_config_width(ADC_WIDTH_BIT_12);
|
|
||||||
adc1_config_channel_atten(pinToADC1Channel(currentPin),ADC_ATTEN_DB_11);
|
|
||||||
senseOffset = adc1_get_raw(pinToADC1Channel(currentPin));
|
|
||||||
#else
|
|
||||||
pinMode(currentPin, INPUT);
|
|
||||||
Adc::reg(currentPin);
|
|
||||||
// run analogRead as Adc::read() does not have any values before
|
|
||||||
// the waveform has been started.
|
|
||||||
senseOffset=analogRead(currentPin); // value of sensor at zero current
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
faultPin=fault_pin;
|
faultPin=fault_pin;
|
||||||
|
@ -223,20 +194,7 @@ int MotorDriver::getCurrentRaw(bool fromISR) {
|
||||||
(void)fromISR;
|
(void)fromISR;
|
||||||
if (currentPin==UNUSED_PIN) return 0;
|
if (currentPin==UNUSED_PIN) return 0;
|
||||||
int current;
|
int current;
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
current = Adc::read(currentPin, fromISR)-senseOffset;
|
||||||
current = local_adc1_get_raw(pinToADC1Channel(currentPin))-senseOffset;
|
|
||||||
#else
|
|
||||||
#ifdef ANALOG_READ_INTERRUPT
|
|
||||||
current = Adc::read(currentPin)-senseOffset;
|
|
||||||
//current = sampleCurrent-senseOffset;
|
|
||||||
//if ((millis() - sampleCurrentTimestamp) > 3)
|
|
||||||
// DIAG(F("Current sample old %d"), millis() - sampleCurrentTimestamp);
|
|
||||||
#else
|
|
||||||
if (!fromISR) noInterrupts();
|
|
||||||
current = analogRead(currentPin)-senseOffset;
|
|
||||||
if (!fromISR) interrupts();
|
|
||||||
#endif //ANALOG_READ_INTERRUPT
|
|
||||||
#endif //ARDUINO_ARCH_ESP32
|
|
||||||
if (current<0) current=0-current;
|
if (current<0) current=0-current;
|
||||||
if ((faultPin != UNUSED_PIN) && isLOW(fastFaultPin) && powerMode==POWERMODE::ON)
|
if ((faultPin != UNUSED_PIN) && isLOW(fastFaultPin) && powerMode==POWERMODE::ON)
|
||||||
return (current == 0 ? -1 : -current);
|
return (current == 0 ? -1 : -current);
|
||||||
|
|
|
@ -153,12 +153,7 @@ class MotorDriver {
|
||||||
setDCSignal(128);
|
setDCSignal(128);
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
int getCurrentRaw() {
|
int getCurrentRaw(bool fromISR=false);
|
||||||
return getCurrentRaw(false);
|
|
||||||
}
|
|
||||||
int getCurrentRawInInterrupt() {
|
|
||||||
return getCurrentRaw(true);
|
|
||||||
};
|
|
||||||
unsigned int raw2mA( int raw);
|
unsigned int raw2mA( int raw);
|
||||||
unsigned int mA2raw( unsigned int mA);
|
unsigned int mA2raw( unsigned int mA);
|
||||||
inline bool brakeCanPWM() {
|
inline bool brakeCanPWM() {
|
||||||
|
@ -192,7 +187,6 @@ class MotorDriver {
|
||||||
void startCurrentFromHW();
|
void startCurrentFromHW();
|
||||||
#endif
|
#endif
|
||||||
private:
|
private:
|
||||||
int getCurrentRaw(bool fromISR);
|
|
||||||
bool isProgTrack = false; // tells us if this is a prog track
|
bool isProgTrack = false; // tells us if this is a prog track
|
||||||
void getFastPin(const FSH* type,int pin, bool input, FASTPIN & result);
|
void getFastPin(const FSH* type,int pin, bool input, FASTPIN & result);
|
||||||
void getFastPin(const FSH* type,int pin, FASTPIN & result) {
|
void getFastPin(const FSH* type,int pin, FASTPIN & result) {
|
||||||
|
|
|
@ -43,11 +43,6 @@
|
||||||
#undef USB_SERIAL // Teensy has this defined by default...
|
#undef USB_SERIAL // Teensy has this defined by default...
|
||||||
#define USB_SERIAL Serial
|
#define USB_SERIAL Serial
|
||||||
|
|
||||||
// All AVRs must read analog values from the DCC timer interrupt
|
|
||||||
#ifdef ARDUINO_ARCH_AVR
|
|
||||||
#define ANALOG_READ_INTERRUPT
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(ARDUINO_AVR_UNO)
|
#if defined(ARDUINO_AVR_UNO)
|
||||||
#define ARDUINO_TYPE "UNO"
|
#define ARDUINO_TYPE "UNO"
|
||||||
#undef HAS_ENOUGH_MEMORY
|
#undef HAS_ENOUGH_MEMORY
|
||||||
|
|
Loading…
Reference in New Issue
Block a user