>>Torretje/Projects/8255 speedup/

Speedup the Arduino 8255 interface(16X)

The first code I've written for the 8255 I'm using the digitalWrite() method which write a arduino port high or low.

This method is working fine but it seemed slow because of the writing of one bit a time.
I needed eight times digitalWrite to put one byte on the 8255 data lines.

So I have search the interwebs for a solution. And there's one! you can use the arduino port manipulation.

On arduino you have PORTB, PORTC and PORTD and you can put pins high or low to assign a byte like this PORTB=B10101010;

Later I came across this article about to use or not digitalWrite().

But there are some catches, when using the port commands you're bypassing all the system checks and write a byte(8 bits) in one time. So when writing the byte you should consider all the arduino pins because you could write a pin you don't want to. For example the pin 0 and 1 used for serial communication. It is less readable and that makes it difficult to program and debug. Also you lose flexibility when want use different pins you have to rewrite the code significant in the other example with digitalWrite you only have to redeclare the pin assignment at the top of the code.

Enough chitchat give me some code:

If you compare it with the "not optimised" example the setup and the setPort is different.

void setup() {     
  // initialise the digital pin as an output.
   //arduino d2 d3 d4 d5 d6 d7 =>8255 d0 t/m d5
  DDRD = DDRD | B11111100;
  //arduino d8, d9, d10 d11 d12 =>8255 d6 d7 wr rd cs
  DDRB = DDRB | B00011111;
  //arduino a0 a1 a2 =>8255 a0 a1 reset
  DDRC = DDRC | B00000111;
  
  pio8255init();
}

I use bitshifting to clear the previous set pins and preserve the pins I don't want to change. In this case the cs wr res a0 a1 pins on the 8255.

void setPort(byte data, char port){
  //With the char A|B|C you can set the according ports on the 8255 
  if('A'==port){
     PORTC&=B11111100;
  }else if('B'==port){
     byte shiftPortC=PORTC>>2;
    PORTC=shiftPortC<<2 | B00000001;
  }else if('C'==port){ 
    byte shiftPortC=PORTC>>2;
    PORTC=shiftPortC<<2 | B00000010;
  }
  
  //Chip handshaking Port cs->low wr->low 
  PORTB=PORTB & B11101011;
  
  /*
  Shift PORTD left 6 and then shift 6 right to clear the data and leave the two bits in place.
  then append the 6 bits form the byte with an OR.
  */
  byte shiftPortD=PORTD<<6;
  PORTD=shiftPortD>>6 | data<<2;
  /*
  Shift PORTB left 2 and then shift 2 right to clear the data and leave the six bits in place.
  then append the 2 bits form the byte with an OR.
  */
  byte shiftPortB=PORTB>>2;
  PORTB=shiftPortB<<2 | data>>6;
  
  //Chip handshaking Port cs->high wr->high 
  PORTB=PORTB | B00010100;
  //Chip handshaking Port a0->low a1->low
  PORTC=PORTC & B11111100;
}

Arduino file p8255optim.ino

After writing this article measured the speed difference writing continues 1 and 0 in the loop with setPort.
The results 6,212 KHz for not optimised 98.14KHz for optimised thats 16 times faster!