1

Context

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.

Digital Keys

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.

Many Thanks!

3
  • SPI works on bytes not individual clock cycles. You will have to bit-bang your own protocol.
    – Majenko
    Commented Mar 5, 2022 at 11:32
  • Well it can still be write out as full bytes, "3-4 Clock Cycles" being written as 0x7 or 0xF for example (00000111 or 00001111). It's just writing out to LE which is the bit I can't figure. Commented Mar 5, 2022 at 13:52
  • 2
    Yeah, but you can only trigger your LE on multiples of 8 clock cycles. You will have to bit-bang your own protocol. It's not hard.
    – Majenko
    Commented Mar 5, 2022 at 14:22

1 Answer 1

4

I've achieve this by "bit-banging" via a modified shiftOut() of ArduinoCore-avr/cores/arduino/wiring_shift.c, essentially allowing for two data lines on the same clocking:

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);
            key <<= 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:

ScopeOutput

Running on my Arduino Nano 33 IoT this clocked at 150kHz which is sufficient for my application.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.