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!