AVR Emulation on teensy 3.0

Status
Not open for further replies.

JMS

New member
I am trying to use a tft with 8 bit data on a teensy 3.0. The AVR emulation that is provided with the teensy 3.0 seems to be ideal for this situation. However the AVR emulation seems to be missing the DDRx register. What is the best way to add an emulation of this register in the avr_emulation.h file ?

Kind Regards,

Jehudi
 
Fully emulating the AVR DDR register is difficult.

There's 2 main problems.

First, on Teensy 3.0 there's actually 2 registers that configure the pin, not 1. There's pin config register that assigns the pin to the GPIO controller. Then when the GPIO is controlling the pin, it has registers that control input vs output. So it's not a simple 1-to-1 register mapping.

Second, the pullup resistor on AVR is controlled by the output register when DDR is in input mode. On Teensy 3.0, the pullup register is controlled very differently, using the pin config register. If the pullup resistor is to be included in the DDR emulation, it greatly complicates (and slows) the code.
 
Paul, that is exactly what I found out. Firstly, in answer to JMS, here is my exact workaround:

This was my original code. Note that "mode" is my own variable, not a processor thing...

if_bitIsClear(mode,ioPort_modeBit_inputOnly)
{
// Port is output. First, tell hardware about it.
DDRB |= selectedPort_bitMaskHigh; DDRD |= selectedPort_bitMaskLow;
}
else
{
// Input. Tell hardware about it
DDRB &= selectedPort_notBitMaskHigh; DDRD &= selectedPort_notBitMaskLow;
// And select pull-up if desired
if_bitIsSet(mode,ioPort_modeBit_pullup) { PORTB |= selectedPort_bitMaskHigh; PORTD |= selectedPort_bitMaskLow; }
#endif

This did not compile on Teensy3. I changed the code to the following to make it work. This compiles but has not been tested!

if_bitIsClear(mode,ioPort_modeBit_inputOnly)
{
// Port is output. First, tell hardware about it.
#if (config_hardwareType_arduino == 1)
DDRB |= selectedPort_bitMaskHigh; DDRD |= selectedPort_bitMaskLow;
#ef (config_hardwareType_arduino == 3) // 3 is for teensy-3. There is no 2!
pinMode(selectedPort_num,OUTPUT);
#endif
}
else
{
// Input. Tell hardware about it
#if (config_hardwareType_arduino == 1)
DDRB &= selectedPort_notBitMaskHigh; DDRD &= selectedPort_notBitMaskLow;
if_bitIsSet(mode,ioPort_modeBit_pullup) { PORTB |= selectedPort_bitMaskHigh; PORTD |= selectedPort_bitMaskLow; }
#ef (WIZ_config_hardwareType_arduino == 3)
if_bitIsSet(mode,ioPort_modeBit_pullup)
{ pinMode(selectedPort_num,INPUT_PULLUP); } else { pinMode(selectedPort_num,INPUT); }
#endif

I don't mind using the "pinMode" calls here because it is not a highly traveled path for my system, so speed is not critical.

However, the following first line of code, which DID compile and does execute fine, is *extremely* speed critical:

currentDataBits = (PINB<<8) | PIND;
if (currentDataBits != previousDataBits) { etc; etc; }

Paul, I see your implementation of PINB/D in avr_emulation.h, OMG! No wonder my code got WAY slow! 25x slower!! On Arduino Nano that 1st line takes 2 clock cycles or 0.125 usec. On Teensy 3.0 it took 1.09 usec at 48 MHz, 52 cycles! Now I see why!!! (This was the first detail I benchmarked as it is most critical to me!)

I might get some improvement to remove my shift <<8 and do all 13 digitalReadFast's in a single 16 bit int, but that would be very slight I suspect.

Ouch. I'd like to see digitalWriteFast but I can't find it in the files. Can u tell me where it is? Any other ideas? I guess I need to go read in detail the underlying hardware... Are the groups of bits not in a single hardware register like PINB/D??

Thanks muchly!
 
Status
Not open for further replies.
Back
Top