tinyfpga / TinyFPGA-BX

Other
268 stars 96 forks source link

Problem updating the bootloader on a TinyFPGA-BX #33

Open kyledmajor opened 2 years ago

kyledmajor commented 2 years ago

I have a TinyFPGA BX board that is connected to a Mac (Big Sur) I am trying to upload a new bootloader to this board using tinyprog (https://pypi.org/project/tinyprog/). I am running this with

>>>from tinyprog import *
  >>>from tinyprog.__main__ import perform_bootloader_update
  >>>tinyport=get_ports('1d50:6130')
  >>>perform_bootloader_update(tinyport[0])

The result of this is:


    The following update:

        New Version: 1.0.1
        Notes: Updates USB VID:PID to fix issues with APIO not recognizing the board.

    is available for this board:

        USB 20.3: TinyFPGA BX 1.0.0
            UUID: cfaef439-1b38-4576-b1bc-970b9f5d5ee1
            FPGA: ice40lp8k-cm81

    Would you like to perform the update? [y/N] y
    Fetching stage one...
    Programming stage one...

    Erasing: 100%|████████████████████████████| 135k/135k [00:00<00:00, 175kB/s]
    Writing: 100%|████████████████████████████| 135k/135k [00:00<00:00, 163kB/s]
    Reading: 100%|████████████████████████████| 135k/135k [00:00<00:00, 344kB/s]

---------------------------------------------------------------------------
USBError                                  Traceback (most recent call last)
/var/folders/n5/kk2vsh296_s0w454yrchd3f00000gn/T/ipykernel_13323/2827260816.py in <module>
----> 1 perform_bootloader_update(tinyport[0])

/opt/anaconda3/envs/verilogenv38/lib/python3.8/site-packages/tinyprog/__main__.py in perform_bootloader_update(port)
    149             userimage_addr = p.meta.userimage_addr_range()[0]
    150             if p.program_bitstream(userimage_addr, bitstream):
--> 151                 p.boot()
    152                 print("    ...Success!")
    153             else:

/opt/anaconda3/envs/verilogenv38/lib/python3.8/site-packages/tinyprog/__init__.py in boot(self)
    386     def boot(self):
    387         try:
--> 388             self.ser.write(b"\x00")
    389             self.ser.flush()
    390         except SerialTimeoutException as e:

/opt/anaconda3/envs/verilogenv38/lib/python3.8/site-packages/tinyprog/__init__.py in write(self, data)
     90 
     91     def write(self, data):
---> 92         self.OUT.write(data)
     93 
     94     def flush(self):

/opt/anaconda3/envs/verilogenv38/lib/python3.8/site-packages/usb/core.py in write(self, data, timeout)
    406         For details, see the Device.write() method.
    407         """
--> 408         return self.device.write(self, data, timeout)
    409 
    410     def read(self, size_or_buffer, timeout = None):

/opt/anaconda3/envs/verilogenv38/lib/python3.8/site-packages/usb/core.py in write(self, endpoint, data, timeout)
    987         fn = fn_map[util.endpoint_type(ep.bmAttributes)]
    988 
--> 989         return fn(
    990                 self._ctx.handle,
    991                 ep.bEndpointAddress,

/opt/anaconda3/envs/verilogenv38/lib/python3.8/site-packages/usb/backend/libusb1.py in bulk_write(self, dev_handle, ep, intf, data, timeout)
    835     @methodtrace(_logger)
    836     def bulk_write(self, dev_handle, ep, intf, data, timeout):
--> 837         return self.__write(self.lib.libusb_bulk_transfer,
    838                             dev_handle,
    839                             ep,

/opt/anaconda3/envs/verilogenv38/lib/python3.8/site-packages/usb/backend/libusb1.py in __write(self, fn, dev_handle, ep, intf, data, timeout)
    936         # do not assume LIBUSB_ERROR_TIMEOUT means no I/O.
    937         if not (transferred.value and retval == LIBUSB_ERROR_TIMEOUT):
--> 938             _check(retval)
    939 
    940         return transferred.value

/opt/anaconda3/envs/verilogenv38/lib/python3.8/site-packages/usb/backend/libusb1.py in _check(ret)
    602             raise USBTimeoutError(_strerror(ret), ret, _libusb_errno[ret])
    603         else:
--> 604             raise USBError(_strerror(ret), ret, _libusb_errno[ret])
    605 
    606     return ret

USBError: [Errno 5] Input/Output Error

My understanding of this is that the board is able to be updated but then tinyprog is trying to boot the board and this is failing. I am able to access this USB device just using pyusb but again when I try to write with ser.write in pyusb I get the same error.

Is this a problem with the board itself or is this the tinyprog not working properly?

bmentink commented 1 year ago

I am having similar issues with tinyprog and macos. It seems that tinyprog serial rate over USB is too high for macos, especially on the M1 via DisplayPort adapters. It would be good if there could be an option to throttle the serial data rate, I think that would fix a lot of issues on macos.

(Other dev boards I have programmed on the M1 have needed to be throttled to 600Kbaud ..)