For a project of mine, I had to read an 8-bit DIP switch. Easy solution was to use 74HC165 but there I had a problem. Fully interfacing with it requires 4 lines: Shift/Load, Clock, Clock Inhibit, and Q7. However, I only had 3 lines available.
Obvious one was getting rid of Clock Inhibit as that one can be tied to low permanently. This leaves only 3 lines but with a slightly unclear handling as official datasheet uses Clock Inhibit in all examples.
After a few tests with chips from different manufacturers, I found the following code works with all.
bitbang_cp_low(); __delay_us(1); // bring clock down
bitbang_pl_low(); __delay_us(1); // perform Load
bitbang_pl_high(); __delay_us(1); // load done
uint8_t value = !bitbang_so_get(); // get the first bit as that one is already latched
for (uint8_t i = 0; i < 7; i++) { // do the next 7 bits
bitbang_cp_high(); __delay_us(1); // clock goes high
value <<= 1; // shift value 1 bit to have empty bit for the next load
if (!bitbang_so_get()) { value |= 0x01; } // read serial output
bitbang_cp_low(); __delay_us(1); // clock goes low for the next round
}
return value;
One can argue that 1µs delay is a bit too much but I actually found a few chips obtained from eBay that positively needed it to function properly. One could argue that those chips should be excluded as all reliable manufacturers specify it at 250ns or less. However, quadrupling that value in my use case (reading DIP switch on startup) wasn't that important.
Regardless, adjust overall code as needed.
Keep up the good work.