STEVAL-DRONE01上の加速度センサはマイコンとSPI 3-Wireモードで接続されていてMicroPython上で利用可能な標準のSPIドライバでは制御できない*1。
泥臭いが、ビットバンギングでIOポートを上げ下げしてSPI 3-Wire相当のバスを作って加速度センサのレジスタを読んでみた。
結果、以下の通りで動いてそうな感じ。
>>> reg_dump() 00: 00 00 00 00 00 00 00 00 12 00 00 00 00 00 00 6a 10: 00 00 08 00 00 00 00 00 e0 00 00 00 00 00 00 c2 20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 30: 00 00 00 00 00 00 00 00 00 00 00 10 00 00 bb a8 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 50: 00 00 00 00 84 00 00 00 00 00 00 00 00 00 00 00 60: 00 00 00 00 00 bb 00 00 00 00 00 00 00 00 00 00 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80: 00 00 00 00 00 00 00 00 12 00 00 00 00 00 00 6a 90: 00 00 08 00 00 00 00 00 e0 00 00 00 00 00 00 c2 a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 b0: 00 00 00 00 00 00 00 00 00 00 00 10 00 00 bb a8 c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d0: 00 00 00 00 84 00 00 00 00 00 00 00 00 00 00 00 e0: 00 00 00 00 00 bb 00 00 00 00 00 00 00 00 00 00 f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
あたりまえだが、、ダンプさせるともっさり動いている。
SPI 3-Wireモードによる制御サンプルは以下
#----------------------------------------- from pyb import Pin # def for SPI SPI_READ_BIT = 0x80 CTRL3_C = 0x12 CTRL6_C = 0x15 SIM_3WIRE = 0x08 lsm6d_cs = None s2_clk = None s2_sda = None def reg_dump(): for addr in range(0xff+1): data = spi_read_reg(addr) if (addr % 16) == 0: print(f"\n{addr:02x}: ", end="") print(f"{data:02x} ", end="") print("") def spi_init(): global lsm6d_cs, s2_clk, s2_sda lsm6d_cs = Pin(Pin.cpu.A8, mode=Pin.OUT) s2_clk = Pin(Pin.cpu.B13, mode=Pin.OUT) s2_sda = Pin(Pin.cpu.B15, mode=Pin.OUT) def spi_write_reg(addr,data): global lsm6d_cs, s2_clk, s2_sda s2_sda = Pin(Pin.cpu.B15, mode=Pin.OUT) lsm6d_cs.high() spi_out(addr, no_ctrl_cs = True) spi_out(data, no_ctrl_cs = True) lsm6d_cs.low() def spi_read_reg(addr): global lsm6d_cs, s2_clk, s2_sda s2_sda = Pin(Pin.cpu.B15, mode=Pin.OUT) lsm6d_cs.high() spi_out(addr | SPI_READ_BIT, no_ctrl_cs = True) s2_sda = Pin(Pin.cpu.B15, mode=Pin.IN) data = spi_in(no_ctrl_cs = True) #print(f"{data:02x}") lsm6d_cs.low() return data def spi_out(data,no_ctrl_cs = False): global lsm6d_cs, s2_clk, s2_sda # setup SPI bus if not no_ctrl_cs: lsm6d_cs.high() s2_clk.high() s2_sda.high() lsm6d_cs.low() mask = 0x80 for i in range(8): s2_clk.low() #print("C_L ",end="") if data & mask: s2_sda.high() #print("D_H ",end="") else: s2_sda.low() #print("D_L ",end="") s2_clk.high() #print("C_H") mask >>= 1 if not no_ctrl_cs: lsm6d_cs.high() def spi_in(no_ctrl_cs = False): global lsm6d_cs, s2_clk, s2_sda # setup SPI bus if not no_ctrl_cs: lsm6d_cs.high() s2_clk.high() lsm6d_cs.low() data = 0 for i in range(8): data <<= 1 s2_clk.low() #print("C_L ",end="") s2_clk.high() #print("C_H ",end="") if s2_sda.value() == 1: #print("D_H") data |=1 else: pass #print("D_L") if not no_ctrl_cs: lsm6d_cs.high() return data #---------------------------------------------- spi_init() # set 3-wire mode addr = CTRL3_C data = SIM_3WIRE spi_write_reg(addr,data) data = spi_read_reg(addr) print(f"{data:02x}") reg_dump()
■追記
あらためて読み直すと、、以下のCS操作は逆ではなかろうか。
def spi_write_reg(addr,data): global lsm6d_cs, s2_clk, s2_sda s2_sda = Pin(Pin.cpu.B15, mode=Pin.OUT) lsm6d_cs.high() # not cs.high but cs.low ?? spi_out(addr, no_ctrl_cs = True) spi_out(data, no_ctrl_cs = True) lsm6d_cs.low() # not cs.low but cs.high ??