raspberrypi/pico-micropython-examples

Possible Issue with pio/pio_spi.py

Joel05 opened this issue · 1 comments

Joel05 commented

Could it be that there is an issue somewhere in the code for the pio_spi. For me i only get MOSI getting pulled low trying to send something. It could also well be, that i am using it wrong, since there is no example given, and im completely new to PIO. Anyway here is my code:

import rp2
from machine import Pin
import time

@rp2.asm_pio(out_shiftdir=0, autopull=True, pull_thresh=8, autopush=True, push_thresh=8, sideset_init=(rp2.PIO.OUT_LOW, rp2.PIO.OUT_HIGH), out_init=rp2.PIO.OUT_LOW)
def spi_cpha0():
    # Note X must be preinitialised by setup code before first byte, we reload after sending each byte
    # Would normally do this via exec() but in this case it's in the instruction memory and is only run once
    set(x, 6)
    # Actual program body follows
    wrap_target()
    pull(ifempty)            .side(0x2)   [1]
    label("bitloop")
    out(pins, 1)             .side(0x0)   [1]
    in_(pins, 1)             .side(0x1)
    jmp(x_dec, "bitloop")    .side(0x1)

    out(pins, 1)             .side(0x0)
    set(x, 6)                .side(0x0) # Note this could be replaced with mov x, y for programmable frame size
    in_(pins, 1)             .side(0x1)
    jmp(not_osre, "bitloop") .side(0x1) # Fallthru if TXF empties

    nop()                    .side(0x0)   [1] # CSn back porch
    wrap()


class PIOSPI:

    def __init__(self, sm_id, pin_mosi, pin_miso, pin_sck, cpha=False, cpol=False, freq=1000000):
        assert(not(cpol or cpha))
        self._sm = rp2.StateMachine(sm_id, spi_cpha0, freq=4*freq, sideset_base=Pin(pin_sck), out_base=Pin(pin_mosi), in_base=Pin(pin_sck))
        self._sm.active(1)
        self._sm.exec("set(x,6)")

    # Note this code will die spectacularly cause we're not draining the RX FIFO
    def write_blocking(self, wdata):
        for b in wdata:
            self._sm.put(b << 24)

    def read_blocking(self, n):
        data = []
        for i in range(n):
            data.append(self._sm.get() & 0xff)
        return data

    def write_read_blocking(self, wdata):
        rdata = []
        for b in wdata:
            self._sm.put(b << 24)
            rdata.append(self._sm.get() & 0xff)
        return rdata



spi = PIOSPI(0,19, 16, 18)
cs_pin = machine.Pin(2, machine.Pin.OUT)

def set_voltage(voltage):
    global spi
    global cs_pin
    
    # Calculate the 10-bit digital value for the given voltage
    digital_value = int(voltage / 2.048 * 1023)
    
    # Calculate the configuration bits for output voltage range and power-down mode
    config_bits = 0b00110000  # 0b001 for full-scale output voltage range, 0b0 for normal mode
    
    # Send the configuration bits and digital value to the MCP4812 via SPI
    cs_pin.value(0)  # Activate chip select
    spi.write_blocking(bytes([(config_bits | ((digital_value >> 6) & 0xFF))]))
    spi.write_blocking(bytes([((digital_value & 0x3F) << 2)]))
    cs_pin.value(1)  # Deactivate chip select
    spi.read_blocking(2)

while True:
    set_voltage(1.23)
    print("1.23")
    time.sleep(1)
lurch commented

This is probably fixed by #63 ?