kaluma-project / kaluma

A tiny JavaScript runtime for RP2040 (Raspberry Pi Pico)
https://kalumajs.org
Apache License 2.0
632 stars 38 forks source link

StateMachine ASM Change Pin #638

Open DoofyAss opened 6 months ago

DoofyAss commented 6 months ago

How can I change pin?

this.asm = new ASM({ sideset: 1 })

this.sm = new StateMachine(
StateMachine.getAvailableId(), this.asm, {

    freq: 8000000,
    pullThreshold: 24,
    autopull: true,
    sidesetBase: this.pin,
    fifoJoin: PIO.FIFO_JOIN_TX,
    outShiftDir: PIO.SHIFT_LEFT,
})

How does work this.sm.setPins()?

communix commented 6 months ago

this.sm.setPins() function is the same as pio_sm_set_pins_with_mask() function of Raspberrypi-pico API. Please refer this function.

void pio_sm_set_pins_with_mask (PIO pio, uint sm, uint32_t pin_values, uint32_t pin_mask)

Use a state machine to set a value on multiple pins for the PIO instance.

DoofyAss commented 6 months ago

Is it possible set multiple pins for multiple led strips? I was trying change pins after create a sm object.

this.sm.setPins(1 | 2)

did not produce results.

communix commented 6 months ago

this.sm.setPins(1 | 2 ) is the same as this.sm.setPins( 3, 0xFFFFFFFF) because the default value of the pin_mask is 0xFFFFFFFF. So I think this command can set multiple pins. Could you please try this.sm.setPins(1 | 2, 1 | 2 ) ?

DoofyAss commented 6 months ago
this.sm.setPins(1 | 2, 1 | 2 )

Not working 🥺

DoofyAss commented 6 months ago

strip.js


const { PIO, ASM, StateMachine } = require('rp2')

const clamp = (value, min, max) => Math.min(Math.max(value, min), max)

class Strip {

    constructor(option) {

        this.pin = option.pin
        this.num = option.num
        this.b = option.brightness * 0.01 || 1.0

        this.buffer = new Uint32Array(this.num)
        this.buffer.fill(0)

        this.asm = new ASM({ sideset: 1 })

        this.asm
        .label("bitloop").out("x", 1).side(0).delay(2)
        .jmp("!x", "do_zero").side(1).delay(1)
        .label("do_one").jmp("bitloop").side(1).delay(4)
        .label("do_zero").nop().side(0).delay(4)

        this.sm = new StateMachine(
        StateMachine.getAvailableId(),
        this.asm, {

            freq: 8000000,
            pullThreshold: 24,
            autopull: true,
            sidesetBase: this.pin,
            fifoJoin: PIO.FIFO_JOIN_TX,
            outShiftDir: PIO.SHIFT_LEFT,
        })

        this.sm.active(true)
        this.sm.put(this.buffer)
    }

    color(dec) {

        let hex = this.buffer[i]
        return [ hex >> 24 & 255, hex >> 16 & 255, hex >> 8 & 255 ]
    }

    decimal(r, g, b, a) {

        let A = a == undefined ? this.b : a * 0.01
        A = clamp(A, 0.0, 1.0)

        r = clamp(r, 0, 255)
        g = clamp(g, 0, 255)
        b = clamp(b, 0, 255)

        let G = parseInt(g * A) << 24
        let R = parseInt(r * A) << 16
        let B = parseInt(b * A) << 8

        return G | R | B
    }

    clear() { this.buffer.fill(0) }

    show() { this.sm.put(this.buffer) }

    brightness(p) { this.b = p * 0.01 }

    rgb(i, r, g, b, a) { this.buffer[i] = this.decimal(r, g, b, a) }

}

module.exports = { Strip }

index.js

const { Strip } = require('./module/strip')

const strip = new Strip({ pin: 0, num: 5, brightness: 5 })

strip.pin = 1
strip.sm.setPins(1, 1)

for (let i=0; i<strip.num; i++)
strip.rgb(i, 255, 255, 255)

strip.show()
DoofyAss commented 6 months ago

I had to use a multiplexer, but I would like to know if it is possible to change the pin after create a StateMachine photo_2024-02-23_09-43-27

communix commented 5 months ago

@DoofyAss Sorry I don't fully understand PIO operation. I think it's better for you to ask it Raspberry Pi Forum.