Hi Guys,
I'm wanting add support for the Teensy 3.1 to an Arduino library I wrote based on AVRs that decodes the "Digital Command Control" (DCC) protocol used on Digital Model Railroads.
The library is here: https://github.com/mrrwa/NmraDcc
The AVR routine works by sensing the rising edge using the INTx input, which then grabs the current Timer0 Count, adds a count of 80us and sets the Timer0 CompareB value to that count and then uses the CompareB interrupt handler to sample the input to check if it is HIGH or LOW which corresponds to a bit value of 1 or 0.
For DCC a pulse width of 116us is a "1" and a pulse width of 56us is a "0", sampling the input 80us (or so) after the rising edge will let you sense the "1" or "0" values.
The ASCII Art diagram below should hopefully help describe the logic
I've used the AVRs for many years and am pretty familiar with their interrupts and timer peripherals, but I'm a total newbie to the Teensy 3.x chips, so I'm wondering how best to implement this type of logic using the ARM interrupts and timers?
With the reading I've done so far I wondered about using the attachInterrupt() to sense the rising edge and then attaching the IntervalTimer to delay the 80us before sampling the input to determine if I'm receiving a "1" or a "0".
However I'm wondering calling the IntervalTimer.begin() from the attachInterrupt() handler is going to be ok, and if I might run into issues with repeatedly doing the IntervalTimer begin/end for each rising edge.
I also see reference to a FlexTimer but not found any good descriptions for it yet so is there the equivalent of the AVRs ICP InputCapture on these Teensy 3.x devices that would capture the value of a Timer/Counter on a rising edge, fire an interrupt that lets me set a compare target value, then fire another interrupt on a compare match, so I can sample the input level?
Any suggestions or links for further reading would be greatly appreciated?
Regards
Alex Shepherd
I'm wanting add support for the Teensy 3.1 to an Arduino library I wrote based on AVRs that decodes the "Digital Command Control" (DCC) protocol used on Digital Model Railroads.
The library is here: https://github.com/mrrwa/NmraDcc
The AVR routine works by sensing the rising edge using the INTx input, which then grabs the current Timer0 Count, adds a count of 80us and sets the Timer0 CompareB value to that count and then uses the CompareB interrupt handler to sample the input to check if it is HIGH or LOW which corresponds to a bit value of 1 or 0.
For DCC a pulse width of 116us is a "1" and a pulse width of 56us is a "0", sampling the input 80us (or so) after the rising edge will let you sense the "1" or "0" values.
The ASCII Art diagram below should hopefully help describe the logic
Code:
//------------------------------------------------------------------------
// DCC Receive Routine
//
// Howto: uses two interrupts: a rising edge in DCC polarity triggers INTx
// in INTx handler, Timer0 CompareB with a delay of 80us is started.
// On Timer0 CompareB Match the level of DCC is evaluated and
// parsed.
//
// |<-----116us----->|
//
// DCC 1: _________XXXXXXXXX_________XXXXXXXXX_________
// ^-INTx
// |----87us--->|
// ^Timer-INT: reads zero
//
// DCC 0: _________XXXXXXXXXXXXXXXXXX__________________
// ^-INTx
// |----------->|
// ^Timer-INT: reads one
//
//------------------------------------------------------------------------
I've used the AVRs for many years and am pretty familiar with their interrupts and timer peripherals, but I'm a total newbie to the Teensy 3.x chips, so I'm wondering how best to implement this type of logic using the ARM interrupts and timers?
With the reading I've done so far I wondered about using the attachInterrupt() to sense the rising edge and then attaching the IntervalTimer to delay the 80us before sampling the input to determine if I'm receiving a "1" or a "0".
However I'm wondering calling the IntervalTimer.begin() from the attachInterrupt() handler is going to be ok, and if I might run into issues with repeatedly doing the IntervalTimer begin/end for each rising edge.
I also see reference to a FlexTimer but not found any good descriptions for it yet so is there the equivalent of the AVRs ICP InputCapture on these Teensy 3.x devices that would capture the value of a Timer/Counter on a rising edge, fire an interrupt that lets me set a compare target value, then fire another interrupt on a compare match, so I can sample the input level?
Any suggestions or links for further reading would be greatly appreciated?
Regards
Alex Shepherd