tinygo-org / drivers

TinyGo drivers for sensors, displays, wireless adaptors, and other devices that use I2C, SPI, GPIO, ADC, and UART interfaces.
https://tinygo.org
BSD 3-Clause "New" or "Revised" License
608 stars 192 forks source link

Add driver support for cd74hc4067 #585

Open scriptchildie opened 1 year ago

scriptchildie commented 1 year ago

Add support for cd74hc4067 https://www.sparkfun.com/datasheets/IC/CD74HC4067.pdf

Driver Code:


import (
    "fmt"
    "machine"
)

type Device struct {
    s0, s1, s2, s3, en machine.Pin
    sigADC             machine.ADC
}

// Returns a new Multiplex driver
func New(s0Pin, s1Pin, s2Pin, s3Pin, enPin machine.Pin, sigAdcPin machine.Pin) Device {
    return Device{
        s0: s0Pin,
        s1: s1Pin,
        s2: s2Pin,
        s3: s3Pin,
        en: enPin,
        sigADC: machine.ADC{
            sigAdcPin,
        },
    }
}

// Configure configures the Device.
func (d *Device) Configure() {
    d.s0.Configure(machine.PinConfig{Mode: machine.PinOutput})
    d.s1.Configure(machine.PinConfig{Mode: machine.PinOutput})
    d.s2.Configure(machine.PinConfig{Mode: machine.PinOutput})
    d.s3.Configure(machine.PinConfig{Mode: machine.PinOutput})
    d.en.Configure(machine.PinConfig{Mode: machine.PinOutput})

    machine.InitADC()
    d.sigADC.Configure(machine.ADCConfig{})

}

// Read ADC value from specific PIN
func (d *Device) ReadValue(pin int8) (uint16, error) {

    if pin > 15 {
        return 0, fmt.Errorf("Valid Input Values are 0-15")
    }
    binSlice := int8ToBoolSlice(pin)

    d.en.Low() // enabled on low
    d.s0.Set(binSlice[7])
    d.s1.Set(binSlice[6])
    d.s2.Set(binSlice[5])
    d.s3.Set(binSlice[4])

    return d.sigADC.Get(), nil
}

// Read all values and return a slice
func (d *Device) ReadAll() [16]uint16 {
    var result [16]uint16

    for i := 0; i < 16; i++ {
        result[i], _ = d.ReadValue(int8(i))
    }
    return result
}

// Select Channel None
func (d *Device) Disable() {
    d.en.High()
}

// Internal function to convert
// intiger to a binary slice to use
// in the ReadValue
func int8ToBoolSlice(num int8) [8]bool {
    var result [8]bool
    for i := 0; i < 8; i++ {
        bit := (num >> i) & 1
        result[7-i] = bit != 0
    }
    return result
}

Example Code:


import (
    "fmt"
    "machine"
    "time"

    "embedded/cd74hc4067"
)

func main() {
    mux := cd74hc4067.New(machine.GP21, machine.GP20, machine.GP19, machine.GP18, machine.GP22, machine.ADC0)
    mux.Configure()
    for {
        time.Sleep(2 * time.Second)
        fmt.Println(mux.ReadAll())

        val, _ := mux.ReadValue(0)
        fmt.Println(val)

    }

}