I am working on a project which includes 13 cascaded STMicroelectronics LED1642GWs. These LED drivers are essentially 16bit shift registers, whereby the buffered serial data can be loaded to a number of different registers dependant on the required function.
The function is selected through the use of "digital keys", which is selected by number of CLK cycles for which the LE (CS/SS) pin is HIGH. For example, LE being HIGH for 1-2 CLK cycles will switch the 16 outputs as per the buffered bits, whereas LE being HIGH for 3-4 CLK cycles will load the 16 bits to a brightness register.
Question
How can I toggle my LE/CS/SS pin for a specific number of SCLK cycles? I had intended to use the SPI Libary, however I'm not sure this can be supported.
Add a shift register that you fill with the key pattern and shift it out to the LE pin while outputting the data by SPI.
Add a presettable counter which you set to the desired number of pulses, connect its "32" (5th bit) output to LE and count up (or down) during the SPI transfer.
An internal timer/counter may serve that purpose as well?
Or find some easier controllable LED driver chip...
What I'd thought to do was use a DEMUX to switch my Arduino MOSI line to the LE line of the IC, then SPI out the corresponding byte(s) for the required function. For example 0x7 or 0xF for the key "Data Latch", being 2-3 Clock Cycles. This might need to be 0x70 or 0xF0 depending on endianness.
How fast do you need to transfer data? I would suggest coding it in software ("bit-banging"), using the standard digitalWrite(), >> bit-shifting etc. and get it working, even if it's not as fast as you would like. Then there are some tricks to get an extra turn off speed we can try. But don't go as far as direct port manipulation, because that ties you to the model of MCU, and you may ultimately need to upgrade to a faster MCU to get the speed you need.
For my application I'll be looking to write out 16 bits, to each of the 16 outputs, on my 13 drivers, at minimum 100Hz so... like 42kBps by my reckoning? As I understand that's well under the 8MHz SPI minimum of most Ardunios?
To be honest I've always assumed that you couldn't be sure on the accuracy of your timings with standard digitalWrite()s etc. Any examples or reference you might recommend?
void keyedShiftOut(
uint8_t dataPin,
uint8_t clockPin,
uint8_t latchPin,
uint8_t bitOrder,
uint16_t val,
uint16_t key)
{
uint8_t i;
for (i = 0; i < 16; i++) {
if (bitOrder == LSBFIRST) {
digitalWrite(dataPin, val & 1);
val >>= 1;
digitalWrite(latchPin, key & 1);
key >>= 1;
} else {
digitalWrite(dataPin, (val & 0x8000) != 0);
val <<= 1;
digitalWrite(latchPin, (key & 0x8000) != 0);
val <<= 1;
}
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
}
}
I used this to implement the sequence described within the data sheet (Figure 24. Brightness register setting) to set all of my 16 Brightness Registers to a half setting (0x7FFF) with a timed LE providing the digital key. This scoped out as: