Digital output

Finally, digital output is accomplished by:

void
pcl711_write_digital_bit (pcl711_t *pcl, int bitnum, int bitval)
{
  bitnum &= 15;       // guarantee range

  if (bitval) {
    pcl -> dout |= bits [bitnum];
  } else {
    pcl -> dout &= ~bits [bitnum];
  }

  if (bitnum < 8) {     // 0 .. 7 are in the first byte
    out8 (pcl -> port + PCL711_DO_LOW, pcl -> dout & 0xff);
  } else {
    out8 (pcl -> port + PCL711_DO_HIGH, pcl -> dout >> 8);
  }
}

Digital output is a little bit trickier, because the hardware wants to be written to one byte at a time, rather than one bit at a time. We manage this by maintaining a shadow, called dout, in the extended attributes structure. This shadow contains the currently written value of the digital output port. When we wish to set or clear a particular bit, the first if in the function updates the shadow register to reflect the about-to-be-written value. Next, we determine whether the bit is in the HIGH or LOW portion of the word, then write out the entire 8-bit byte to the port.