Skip to content

Instantly share code, notes, and snippets.

@0x3333
Created July 24, 2020 11:46
Show Gist options
  • Select an option

  • Save 0x3333/0c8ce649fb716b81be00c7ebfedfbf7d to your computer and use it in GitHub Desktop.

Select an option

Save 0x3333/0c8ce649fb716b81be00c7ebfedfbf7d to your computer and use it in GitHub Desktop.

Revisions

  1. 0x3333 created this gist Jul 24, 2020.
    9 changes: 9 additions & 0 deletions README.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,9 @@
    This is a simple example on how to interface with a `TLC5973` IC to dim LEDs in Raspberry Pi.

    It uses SPI to generate a pulse train with precise timing.

    In Raspberry Pi, the SPI may have some inter-byte delay, which makes this useless. More here: https://www.raspberrypi.org/forums/viewtopic.php?t=211152

    I'm using `go-rpio` to manage the SPI device.

    The idea to use SPI came from this repo: https://github.com/mik4el/cc1350-swim-thermo/blob/b2fdb54a940e18911959a5e1778ca7fc06915a11/software/tlc5973_spimaster_CC1350_SWIMTHERMO_tirtos_ccs/spimaster.c
    73 changes: 73 additions & 0 deletions tlc5973.go
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,73 @@
    package core

    import (
    "github.com/stianeikeland/go-rpio"
    )

    func setLed(intensity int) bool {
    if err := rpio.Open(); err != nil {
    fmt.Println("Could not open SPI device")
    return false
    }
    defer rpio.Close()

    // TLC5973 Board, using SPI comm

    spiDev := rpio.Spi0
    switch led.DevID {
    case 0:
    spiDev = rpio.Spi0
    case 1:
    spiDev = rpio.Spi1
    case 2:
    spiDev = rpio.Spi2
    default:
    fmt.Println("Using default SPI device")
    spiDev = rpio.Spi0
    }
    if err := rpio.SpiBegin(spiDev); err != nil {
    fmt.Println("Could not begin SPI device")
    return false
    }
    rpio.SpiSpeed(500000)
    rpio.SpiTransmit(generateTlcPayload(intensity)...)
    rpio.SpiEnd(rpio.Spi0)

    return true
    }

    func generateTlcPayload(intensity int) (out []byte) {
    const (
    ONE byte = 0xA // 0b1010
    ZERO byte = 0x8 // 0b1000
    NONE byte = 0x0 // 0b0000
    )

    out = []byte{NONE, NONE, NONE, NONE}

    intensity = intensity & 0xFFF

    buf := []int16{0x3AA, intensity, intensity, intensity}

    for _, rawWord := range buf {
    for b := 0; b < 6; b++ {
    var word byte = ZERO
    if rawWord&0x800 > 0 {
    word = ONE
    }
    rawWord <<= 1
    word <<= 4
    word |= ZERO
    if rawWord&0x800 > 0 {
    word |= ONE
    }
    rawWord <<= 1
    out = append(out, word)
    }
    }
    out = append(out, NONE)
    out = append(out, NONE)
    out = append(out, NONE)
    out = append(out, NONE)
    return
    }