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.