1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2024-11-22 23:56:13 +01:00

first waveform on esp

This commit is contained in:
Harald Barth 2021-09-21 00:31:05 +02:00
parent f8fb08e331
commit 7397a4089b
8 changed files with 61 additions and 25 deletions

View File

@ -111,7 +111,6 @@ void loop()
// Responsibility 1: Handle DCC background processes // Responsibility 1: Handle DCC background processes
// (loco reminders and power checks) // (loco reminders and power checks)
DCC::loop(); DCC::loop();
// Responsibility 2: handle any incoming commands on USB connection // Responsibility 2: handle any incoming commands on USB connection
serialParser.loop(Serial); serialParser.loop(Serial);

24
DCC.cpp
View File

@ -304,14 +304,14 @@ const ackOp FLASH WRITE_BIT0_PROG[] = {
W0,WACK, W0,WACK,
V0, WACK, // validate bit is 0 V0, WACK, // validate bit is 0
ITC1, // if acked, callback(1) ITC1, // if acked, callback(1)
FAIL // callback (-1) CALLFAIL // callback (-1)
}; };
const ackOp FLASH WRITE_BIT1_PROG[] = { const ackOp FLASH WRITE_BIT1_PROG[] = {
BASELINE, BASELINE,
W1,WACK, W1,WACK,
V1, WACK, // validate bit is 1 V1, WACK, // validate bit is 1
ITC1, // if acked, callback(1) ITC1, // if acked, callback(1)
FAIL // callback (-1) CALLFAIL // callback (-1)
}; };
const ackOp FLASH VERIFY_BIT0_PROG[] = { const ackOp FLASH VERIFY_BIT0_PROG[] = {
@ -320,7 +320,7 @@ const ackOp FLASH VERIFY_BIT0_PROG[] = {
ITC0, // if acked, callback(0) ITC0, // if acked, callback(0)
V1, WACK, // validate bit is 1 V1, WACK, // validate bit is 1
ITC1, ITC1,
FAIL // callback (-1) CALLFAIL // callback (-1)
}; };
const ackOp FLASH VERIFY_BIT1_PROG[] = { const ackOp FLASH VERIFY_BIT1_PROG[] = {
BASELINE, BASELINE,
@ -328,7 +328,7 @@ const ackOp FLASH VERIFY_BIT1_PROG[] = {
ITC1, // if acked, callback(1) ITC1, // if acked, callback(1)
V0, WACK, V0, WACK,
ITC0, ITC0,
FAIL // callback (-1) CALLFAIL // callback (-1)
}; };
const ackOp FLASH READ_BIT_PROG[] = { const ackOp FLASH READ_BIT_PROG[] = {
@ -337,7 +337,7 @@ const ackOp FLASH READ_BIT_PROG[] = {
ITC1, // if acked, callback(1) ITC1, // if acked, callback(1)
V0, WACK, // validate bit is zero V0, WACK, // validate bit is zero
ITC0, // if acked callback 0 ITC0, // if acked callback 0
FAIL // bit not readable CALLFAIL // bit not readable
}; };
const ackOp FLASH WRITE_BYTE_PROG[] = { const ackOp FLASH WRITE_BYTE_PROG[] = {
@ -345,7 +345,7 @@ const ackOp FLASH WRITE_BYTE_PROG[] = {
WB,WACK,ITC1, // Write and callback(1) if ACK WB,WACK,ITC1, // Write and callback(1) if ACK
// handle decoders that dont ack a write // handle decoders that dont ack a write
VB,WACK,ITC1, // validate byte and callback(1) if correct VB,WACK,ITC1, // validate byte and callback(1) if correct
FAIL // callback (-1) CALLFAIL // callback (-1)
}; };
const ackOp FLASH VERIFY_BYTE_PROG[] = { const ackOp FLASH VERIFY_BYTE_PROG[] = {
@ -370,7 +370,7 @@ const ackOp FLASH VERIFY_BYTE_PROG[] = {
V0, WACK, MERGE, V0, WACK, MERGE,
V0, WACK, MERGE, V0, WACK, MERGE,
VB, WACK, ITCB, // verify merged byte and return it if acked ok VB, WACK, ITCB, // verify merged byte and return it if acked ok
FAIL }; CALLFAIL };
const ackOp FLASH READ_CV_PROG[] = { const ackOp FLASH READ_CV_PROG[] = {
@ -393,7 +393,7 @@ const ackOp FLASH READ_CV_PROG[] = {
V0, WACK, MERGE, V0, WACK, MERGE,
V0, WACK, MERGE, V0, WACK, MERGE,
VB, WACK, ITCB, // verify merged byte and return it if acked ok VB, WACK, ITCB, // verify merged byte and return it if acked ok
FAIL }; // verification failed CALLFAIL }; // verification failed
const ackOp FLASH LOCO_ID_PROG[] = { const ackOp FLASH LOCO_ID_PROG[] = {
@ -459,7 +459,7 @@ const ackOp FLASH LOCO_ID_PROG[] = {
V0, WACK, MERGE, V0, WACK, MERGE,
V0, WACK, MERGE, V0, WACK, MERGE,
VB, WACK, ITCB, // verify merged byte and callback VB, WACK, ITCB, // verify merged byte and callback
FAIL CALLFAIL
}; };
const ackOp FLASH SHORT_LOCO_ID_PROG[] = { const ackOp FLASH SHORT_LOCO_ID_PROG[] = {
@ -476,7 +476,7 @@ const ackOp FLASH SHORT_LOCO_ID_PROG[] = {
SETBYTEL, // low byte of word SETBYTEL, // low byte of word
WB,WACK, // some decoders don't ACK writes WB,WACK, // some decoders don't ACK writes
VB,WACK,ITCB, VB,WACK,ITCB,
FAIL CALLFAIL
}; };
const ackOp FLASH LONG_LOCO_ID_PROG[] = { const ackOp FLASH LONG_LOCO_ID_PROG[] = {
@ -500,7 +500,7 @@ const ackOp FLASH LONG_LOCO_ID_PROG[] = {
SETBYTEL, // low byte of word SETBYTEL, // low byte of word
WB,WACK, WB,WACK,
VB,WACK,ITC1, // callback(1) means Ok VB,WACK,ITC1, // callback(1) means Ok
FAIL CALLFAIL
}; };
void DCC::writeCVByte(int16_t cv, byte byteValue, ACK_CALLBACK callback) { void DCC::writeCVByte(int16_t cv, byte byteValue, ACK_CALLBACK callback) {
@ -828,7 +828,7 @@ void DCC::ackManagerLoop() {
} }
break; break;
case FAIL: // callback(-1) case CALLFAIL: // callback(-1)
callback(-1); callback(-1);
return; return;

4
DCC.h
View File

@ -40,7 +40,7 @@ enum ackOp : byte
ITCB, // If True callback(byte) ITCB, // If True callback(byte)
ITCB7, // If True callback(byte &0x7F) ITCB7, // If True callback(byte &0x7F)
NAKFAIL, // if false callback(-1) NAKFAIL, // if false callback(-1)
FAIL, // callback(-1) CALLFAIL, // callback(-1)
STARTMERGE, // Clear bit and byte settings ready for merge pass STARTMERGE, // Clear bit and byte settings ready for merge pass
MERGE, // Merge previous wack response with byte value and decrement bit number (use for readimng CV bytes) MERGE, // Merge previous wack response with byte value and decrement bit number (use for readimng CV bytes)
SETBIT, // sets bit number to next prog byte SETBIT, // sets bit number to next prog byte
@ -191,6 +191,8 @@ private:
#define ARDUINO_TYPE "TEENSY40" #define ARDUINO_TYPE "TEENSY40"
#elif defined(ARDUINO_TEENSY41) #elif defined(ARDUINO_TEENSY41)
#define ARDUINO_TYPE "TEENSY41" #define ARDUINO_TYPE "TEENSY41"
#elif defined(ARDUINO_ARCH_ESP8266)
#define ARDUINO_TYPE "ESP8266"
#else #else
#error CANNOT COMPILE - DCC++ EX ONLY WORKS WITH AN ARDUINO UNO, NANO 328, OR ARDUINO MEGA 1280/2560 #error CANNOT COMPILE - DCC++ EX ONLY WORKS WITH AN ARDUINO UNO, NANO 328, OR ARDUINO MEGA 1280/2560
#endif #endif

View File

@ -30,7 +30,7 @@
#include "EEStore.h" #include "EEStore.h"
#include "DIAG.h" #include "DIAG.h"
#include <avr/wdt.h> //#include <avr/wdt.h>
// These keywords are used in the <1> command. The number is what you get if you use the keyword as a parameter. // These keywords are used in the <1> command. The number is what you get if you use the keyword as a parameter.
// To discover new keyword numbers , use the <$ YOURKEYWORD> command // To discover new keyword numbers , use the <$ YOURKEYWORD> command

View File

@ -44,7 +44,7 @@
#include "DCCTimer.h" #include "DCCTimer.h"
const int DCC_SIGNAL_TIME=58; // this is the 58uS DCC 1-bit waveform half-cycle const int DCC_SIGNAL_TIME=58; // this is the 58uS DCC 1-bit waveform half-cycle
const long CLOCK_CYCLES=(F_CPU / 1000000 * DCC_SIGNAL_TIME) >>1; const long CLOCK_CYCLES=(F_CPU / 1000000 * DCC_SIGNAL_TIME);
INTERRUPT_CALLBACK interruptHandler=0; INTERRUPT_CALLBACK interruptHandler=0;
@ -53,11 +53,11 @@ INTERRUPT_CALLBACK interruptHandler=0;
void DCCTimer::begin(INTERRUPT_CALLBACK callback) { void DCCTimer::begin(INTERRUPT_CALLBACK callback) {
interruptHandler=callback; interruptHandler=callback;
noInterrupts(); noInterrupts();
ADC0.CTRLC = (ADC0.CTRLC & 0b00110000) | 0b01000011; // speed up analogRead sample time ADC0.CTRLC = (ADC0.CTRLC & 0b00110000) | 0b01000011; // speed up analogRead sample time
TCB0.CTRLB = TCB_CNTMODE_INT_gc & ~TCB_CCMPEN_bm; // timer compare mode with output disabled TCB0.CTRLB = TCB_CNTMODE_INT_gc & ~TCB_CCMPEN_bm; // timer compare mode with output disabled
TCB0.CTRLA = TCB_CLKSEL_CLKDIV2_gc; // 8 MHz ~ 0.125 us TCB0.CTRLA = TCB_CLKSEL_CLKDIV2_gc; // 8 MHz ~ 0.125 us
TCB0.CCMP = CLOCK_CYCLES -1; // 1 tick less for timer reset TCB0.CCMP = (CLOCK_CYCLES>>1) -1; // 1 tick less for timer reset
TCB0.INTFLAGS = TCB_CAPT_bm; // clear interrupt request flag TCB0.INTFLAGS = TCB_CAPT_bm; // clear interrupt request flag
TCB0.INTCTRL = TCB_CAPT_bm; // Enable the interrupt TCB0.INTCTRL = TCB_CAPT_bm; // Enable the interrupt
TCB0.CNT = 0; TCB0.CNT = 0;
@ -146,6 +146,24 @@ void DCCTimer::read(uint8_t word, uint8_t *mac, uint8_t offset) {
} }
#endif #endif
#elif defined(ARDUINO_ARCH_ESP8266)
// ESP8266 !!!!!!!!!!!!!!!!!!!!!
void DCCTimer::begin(INTERRUPT_CALLBACK callback) {
interruptHandler=callback;
noInterrupts();
timer1_attachInterrupt(interruptHandler);
timer1_write(CLOCK_CYCLES);
timer1_enable(TIM_DIV1, TIM_EDGE, TIM_LOOP);
interrupts();
}
bool DCCTimer::isPWMPin(byte pin) {
return false;
}
void DCCTimer::setPWM(byte pin, bool high) {
}
#else #else
// Arduino nano, uno, mega etc // Arduino nano, uno, mega etc
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
@ -159,10 +177,10 @@ void DCCTimer::read(uint8_t word, uint8_t *mac, uint8_t offset) {
void DCCTimer::begin(INTERRUPT_CALLBACK callback) { void DCCTimer::begin(INTERRUPT_CALLBACK callback) {
interruptHandler=callback; interruptHandler=callback;
noInterrupts(); noInterrupts();
ADCSRA = (ADCSRA & 0b11111000) | 0b00000100; // speed up analogRead sample time ADCSRA = (ADCSRA & 0b11111000) | 0b00000100; // speed up analogRead sample time
TCCR1A = 0; TCCR1A = 0;
ICR1 = CLOCK_CYCLES; ICR1 = CLOCK_CYCLES>>1;
TCNT1 = 0; TCNT1 = 0;
TCCR1B = _BV(WGM13) | _BV(CS10); // Mode 8, clock select 1 TCCR1B = _BV(WGM13) | _BV(CS10); // Mode 8, clock select 1
TIMSK1 = _BV(TOIE1); // Enable Software interrupt TIMSK1 = _BV(TOIE1); // Enable Software interrupt

View File

@ -176,13 +176,13 @@ int MotorDriver::mA2raw( unsigned int mA) {
void MotorDriver::getFastPin(const FSH* type,int pin, bool input, FASTPIN & result) { void MotorDriver::getFastPin(const FSH* type,int pin, bool input, FASTPIN & result) {
// DIAG(F("MotorDriver %S Pin=%d,"),type,pin); // DIAG(F("MotorDriver %S Pin=%d,"),type,pin);
(void) type; // avoid compiler warning if diag not used above. (void) type; // avoid compiler warning if diag not used above.
uint8_t port = digitalPinToPort(pin); PORTTYPE port = digitalPinToPort(pin);
if (input) if (input)
result.inout = portInputRegister(port); result.inout = portInputRegister(port);
else else
result.inout = portOutputRegister(port); result.inout = portOutputRegister(port);
result.maskHIGH = digitalPinToBitMask(pin); result.maskHIGH = digitalPinToBitMask(pin);
result.maskLOW = ~result.maskHIGH; result.maskLOW = ~result.maskHIGH;
// DIAG(F(" port=0x%x, inoutpin=0x%x, isinput=%d, mask=0x%x"),port, result.inout,input,result.maskHIGH); DIAG(F(" port=0x%x, inoutpin=0x%x, isinput=%d, mask=0x%x"),port, result.inout,input,result.maskHIGH);
} }

View File

@ -26,13 +26,15 @@
#define UNUSED_PIN 127 // inside int8_t #define UNUSED_PIN 127 // inside int8_t
#endif #endif
#if defined(__IMXRT1062__) #if defined(__IMXRT1062__) || defined (ARDUINO_ARCH_ESP8266)
typedef uint32_t PORTTYPE;
struct FASTPIN { struct FASTPIN {
volatile uint32_t *inout; volatile uint32_t *inout;
uint32_t maskHIGH; uint32_t maskHIGH;
uint32_t maskLOW; uint32_t maskLOW;
}; };
#else #else
typedef uint8_t PORTTYPE;
struct FASTPIN { struct FASTPIN {
volatile uint8_t *inout; volatile uint8_t *inout;
uint8_t maskHIGH; uint8_t maskHIGH;

View File

@ -27,6 +27,8 @@ extern "C" char* sbrk(int);
#elif defined(__AVR__) #elif defined(__AVR__)
extern char *__brkval; extern char *__brkval;
extern char *__malloc_heap_start; extern char *__malloc_heap_start;
#elif defined(ARDUINO_ARCH_ESP8266)
// fine as well
#else #else
#error Unsupported board type #error Unsupported board type
#endif #endif
@ -34,7 +36,7 @@ extern char *__malloc_heap_start;
static volatile int minimum_free_memory = __INT_MAX__; static volatile int minimum_free_memory = __INT_MAX__;
#if !defined(__IMXRT1062__) #if !defined(__IMXRT1062__) && !defined(ARDUINO_ARCH_ESP8266)
static inline int freeMemory() { static inline int freeMemory() {
char top; char top;
#if defined(__arm__) #if defined(__arm__)
@ -55,7 +57,20 @@ int minimumFreeMemory() {
return retval; return retval;
} }
#elif defined(ARDUINO_ARCH_ESP8266)
// ESP8266
static inline int freeMemory() {
return ESP.getFreeHeap();
}
// Return low memory value.
int minimumFreeMemory() {
noInterrupts(); // Disable interrupts
int retval = minimum_free_memory;
interrupts(); // interrupts
return retval;
}
#else #else
// All types of TEENSYs
#if defined(ARDUINO_TEENSY40) #if defined(ARDUINO_TEENSY40)
static const unsigned DTCM_START = 0x20000000UL; static const unsigned DTCM_START = 0x20000000UL;
static const unsigned OCRAM_START = 0x20200000UL; static const unsigned OCRAM_START = 0x20200000UL;