mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-12-23 12:51:24 +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;
|
||||
}
|
||||
|
||||
int current=progDriver->getCurrentRawInInterrupt();
|
||||
int current=progDriver->getCurrentRaw(true); // true means "from interrupt"
|
||||
numAckSamples++;
|
||||
if (current > ackMaxCurrent) ackMaxCurrent=current;
|
||||
// An ACK is a pulse lasting between minAckPulseDuration and maxAckPulseDuration uSecs (refer @haba)
|
||||
|
@ -95,8 +95,12 @@ private:
|
||||
|
||||
class Adc {
|
||||
public:
|
||||
static void reg(uint8_t pin);
|
||||
static int read(uint8_t pin);
|
||||
// On architectures that use the analog read during DCC waveform
|
||||
// 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:
|
||||
static void scan();
|
||||
static void begin();
|
||||
|
@ -129,19 +129,26 @@ int * Adc::analogvals = NULL;
|
||||
|
||||
/*
|
||||
* 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;
|
||||
if (id > NUM_ADC_INPUTS)
|
||||
return;
|
||||
return -1023;
|
||||
pinMode(pin, INPUT);
|
||||
int value = analogRead(pin);
|
||||
if (analogvals == NULL)
|
||||
analogvals = (int *)calloc(NUM_ADC_INPUTS+1, sizeof(int));
|
||||
analogvals[id] = value;
|
||||
usedpins |= (1<<id);
|
||||
return value;
|
||||
}
|
||||
/*
|
||||
* 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;
|
||||
if ((usedpins & (1<<id) ) == 0)
|
||||
return -1023;
|
||||
|
@ -78,6 +78,23 @@ int DCCTimer::freeMemory() {
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#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"
|
||||
INTERRUPT_CALLBACK interruptHandler=0;
|
||||
@ -133,5 +150,26 @@ int DCCTimer::freeMemory() {
|
||||
void DCCTimer::reset() {
|
||||
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) {
|
||||
interruptHandler=callback;
|
||||
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
|
||||
REG_GCLK_GENDIV = GCLK_GENDIV_DIV(1) | // Divide 48MHz by 1
|
||||
GCLK_GENDIV_ID(4); // Apply to GCLK4
|
||||
@ -173,4 +155,43 @@ void DCCTimer::reset() {
|
||||
while(true) {};
|
||||
}
|
||||
|
||||
#endif
|
||||
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
|
||||
|
@ -82,10 +82,8 @@ void DCCWaveform::interruptHandler() {
|
||||
TrackManager::setDCCSignal(sigMain);
|
||||
TrackManager::setPROGSignal(sigProg);
|
||||
|
||||
#ifdef ANALOG_READ_INTERRUPT
|
||||
//TrackManager::sampleCurrent();
|
||||
// Refresh the values in the Adc object buffering the values of the ADC HW
|
||||
Adc::scan();
|
||||
#endif
|
||||
|
||||
// Move on in the state engine
|
||||
mainTrack.state=stateTransform[mainTrack.state];
|
||||
|
@ -30,24 +30,6 @@
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
#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
|
||||
|
||||
bool MotorDriver::commonFaultPin=false;
|
||||
@ -110,18 +92,7 @@ MotorDriver::MotorDriver(int16_t power_pin, byte signal_pin, byte signal_pin2, i
|
||||
|
||||
currentPin=current_pin;
|
||||
if (currentPin!=UNUSED_PIN) {
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
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
|
||||
senseOffset = Adc::init(currentPin);
|
||||
}
|
||||
|
||||
faultPin=fault_pin;
|
||||
@ -223,20 +194,7 @@ int MotorDriver::getCurrentRaw(bool fromISR) {
|
||||
(void)fromISR;
|
||||
if (currentPin==UNUSED_PIN) return 0;
|
||||
int current;
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
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
|
||||
current = Adc::read(currentPin, fromISR)-senseOffset;
|
||||
if (current<0) current=0-current;
|
||||
if ((faultPin != UNUSED_PIN) && isLOW(fastFaultPin) && powerMode==POWERMODE::ON)
|
||||
return (current == 0 ? -1 : -current);
|
||||
|
@ -153,12 +153,7 @@ class MotorDriver {
|
||||
setDCSignal(128);
|
||||
#endif
|
||||
};
|
||||
int getCurrentRaw() {
|
||||
return getCurrentRaw(false);
|
||||
}
|
||||
int getCurrentRawInInterrupt() {
|
||||
return getCurrentRaw(true);
|
||||
};
|
||||
int getCurrentRaw(bool fromISR=false);
|
||||
unsigned int raw2mA( int raw);
|
||||
unsigned int mA2raw( unsigned int mA);
|
||||
inline bool brakeCanPWM() {
|
||||
@ -192,7 +187,6 @@ class MotorDriver {
|
||||
void startCurrentFromHW();
|
||||
#endif
|
||||
private:
|
||||
int getCurrentRaw(bool fromISR);
|
||||
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, FASTPIN & result) {
|
||||
|
@ -43,11 +43,6 @@
|
||||
#undef USB_SERIAL // Teensy has this defined by default...
|
||||
#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)
|
||||
#define ARDUINO_TYPE "UNO"
|
||||
#undef HAS_ENOUGH_MEMORY
|
||||
|
Loading…
Reference in New Issue
Block a user