diff options
Diffstat (limited to 'extra/usb_spi/stm32spi.py')
-rwxr-xr-x | extra/usb_spi/stm32spi.py | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/extra/usb_spi/stm32spi.py b/extra/usb_spi/stm32spi.py new file mode 100755 index 0000000000..ecd4edb8e9 --- /dev/null +++ b/extra/usb_spi/stm32spi.py @@ -0,0 +1,140 @@ +#!/usr/bin/python2 +# Copyright 2016 The Chromium OS Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + + +# Test program to access SPI via stm32 raiden debug spi. + +import usb +import usb.core +import usb.util + +class SSpiBus(object): + """SPI bus class to access devices on the bus. + + Usage: + bus = SSpiBus() + # read 1 byte from register(0x16) + bus.wr_rd([0x16], 1) + # write 2 bytes to register(0x20) + bus.wr_rd([0x20, 0x01, 0x02]) + + Instance Variables: + _dev: pyUSB device object + _read_ep: pyUSB read endpoint for this interface + _write_ep: pyUSB write endpoint for this interface + """ + def __init__(self, vendor=0x18d1, + product=0x501a, interface=2, serialname=None): + # Find the stm32. + dev = usb.core.find(idVendor=vendor, idProduct=product) + if dev is None: + raise Exception("SPI", "USB device not found") + + print "Found stm32: %04x:%04x" % (vendor, product) + self._dev = dev + + # Get an endpoint instance. + cfg = dev.get_active_configuration() + intf = usb.util.find_descriptor(cfg, bInterfaceNumber=interface) + self._intf = intf + print "InterfaceNumber: %s" % intf.bInterfaceNumber + + read_ep = usb.util.find_descriptor( + intf, + # match the first IN endpoint + custom_match=\ + lambda e: \ + usb.util.endpoint_direction(e.bEndpointAddress) == \ + usb.util.ENDPOINT_IN + ) + + self._read_ep = read_ep + print "Reader endpoint: 0x%x" % read_ep.bEndpointAddress + + write_ep = usb.util.find_descriptor( + intf, + # match the first OUT endpoint + custom_match=\ + lambda e: \ + usb.util.endpoint_direction(e.bEndpointAddress) == \ + usb.util.ENDPOINT_OUT + ) + + self._write_ep = write_ep + print "Writer endpoint: 0x%x" % write_ep.bEndpointAddress + + self.enable(True) + print "Set up stm32 spi" + + def enable(self, enable): + # USB_RIR_OUT = 0 | USB_TYPE_VENDOR = (0x02 << 5) | + # USB_RECIP_INTERFACE = 0x01 + bmRequestType = 0x41 + # USB_SPI_REQ_ENABLE = 0x0000, USB_SPI_REQ_DISABLE = 0x0001 + if enable: + bmRequest = 0x0 + else: + bmRequest = 0x1 + + print "ctrl_transfer(0x%x, 0x%x, 0, 0x%x, null)" % ( + bmRequestType, bmRequest, self._intf.bInterfaceNumber) + ret = self._dev.ctrl_transfer( + bmRequestType, bmRequest, 0, self._intf.bInterfaceNumber, '') + print "ctrl_transfer ret - %s" % ret + + + + + def wr_rd(self, write_list, read_count=None): + """Implements hdctools wr_rd() interface. + + This function writes byte values list to I2C device, then reads + byte values from the same device. + + Args: + write_list: list of output byte values [0~255]. + read_count: number of byte values to read from device. + + Interface: + write: [write_count, read_count, data ... ] + read: [data .. ] + """ + print "SSpi.wr_rd(write_list=%s, read_count=%s)" % ( + write_list, read_count) + + # Clean up args from python style to correct types. + write_length = 0 + if write_list: + write_length = len(write_list) + if not read_count: + read_count = 0 + + # Send wr_rd command to stm32. + cmd = [write_length, read_count] + write_list + print "WR: %s" % cmd + ret = self._write_ep.write(cmd, 100) + + print "RET: %s " % ret + + # Read back response if necessary. + bytesread = self._read_ep.read(read_count + 2, 1000) + print "BYTES: %s " % bytesread + + if len(bytesread) < 2: + raise Exception("SPI", "Read status failed.") + + print "STATUS: 0x%02x%02x" % (int(bytesread[1]), int(bytesread[0])) + return bytesread[2:] + + +def main(): + bus = SSpiBus() + # write 2 bytes to register(0x20) + bus.wr_rd([0x90, 0x00, 0x00, 0x00], 2) + # read 1 byte from register(0x16) + bus.wr_rd([0x9f], 3) + +if __name__ == "__main__": + main() |