From 11136a55fdf5d3554f879e7786c9bbeb241f83e2 Mon Sep 17 00:00:00 2001 From: C-Glick <colton.glick@gmail.com> Date: Thu, 10 Feb 2022 20:55:24 -0600 Subject: [PATCH] Cleaned up python dfu flasher, added to make file fully working with 'make flash_dfu' --- .../crazyflie-firmware-2021.06/Makefile | 3 +- .../src/hal/src/usb.c | 5 +- .../tools/make/flash_dfu/cfusb.py | 201 ------------------ .../tools/make/flash_dfu/testdfu.py | 6 - .../tools/make/usb-bootloader.py | 21 ++ 5 files changed, 25 insertions(+), 211 deletions(-) delete mode 100644 crazyflie_software/crazyflie-firmware-2021.06/tools/make/flash_dfu/cfusb.py delete mode 100644 crazyflie_software/crazyflie-firmware-2021.06/tools/make/flash_dfu/testdfu.py create mode 100644 crazyflie_software/crazyflie-firmware-2021.06/tools/make/usb-bootloader.py diff --git a/crazyflie_software/crazyflie-firmware-2021.06/Makefile b/crazyflie_software/crazyflie-firmware-2021.06/Makefile index 92c3c0f3a..d8b4140c1 100644 --- a/crazyflie_software/crazyflie-firmware-2021.06/Makefile +++ b/crazyflie_software/crazyflie-firmware-2021.06/Makefile @@ -454,7 +454,8 @@ flash_verify: -c "verify_image $(PROG).bin $(LOAD_ADDRESS) bin" -c "reset run" -c shutdown flash_dfu: - $(DFU_UTIL) -a 0 -D $(PROG).dfu + $(PYTHON) tools/make/usb-bootloader.py + $(DFU_UTIL) -d 0483:df11 -a 0 -D $(PROG).dfu -s :leave #STM utility targets halt: diff --git a/crazyflie_software/crazyflie-firmware-2021.06/src/hal/src/usb.c b/crazyflie_software/crazyflie-firmware-2021.06/src/hal/src/usb.c index ff8ccc7cd..5b6c8f5a9 100644 --- a/crazyflie_software/crazyflie-firmware-2021.06/src/hal/src/usb.c +++ b/crazyflie_software/crazyflie-firmware-2021.06/src/hal/src/usb.c @@ -184,17 +184,16 @@ static uint8_t usbd_cf_Setup(void *pdev , USB_SETUP_REQ *req) } else if(command == 0x02){ //restart system and transition to DFU bootloader mode + //enter bootloader specific to STM32f4xx enter_bootloader(0, 0x00000000); - while(1); - + } else { crtpSetLink(radiolinkGetLink()); } - DEBUG_PRINT("USB setup request: %d, %d, %d, %d, %d ",req->bmRequest, req->bRequest, req->wValue, req->wIndex, req->wLength); return USBD_OK; } diff --git a/crazyflie_software/crazyflie-firmware-2021.06/tools/make/flash_dfu/cfusb.py b/crazyflie_software/crazyflie-firmware-2021.06/tools/make/flash_dfu/cfusb.py deleted file mode 100644 index 349c212cc..000000000 --- a/crazyflie_software/crazyflie-firmware-2021.06/tools/make/flash_dfu/cfusb.py +++ /dev/null @@ -1,201 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# || ____ _ __ -# +------+ / __ )(_) /_______________ _____ ___ -# | 0xBC | / __ / / __/ ___/ ___/ __ `/_ / / _ \ -# +------+ / /_/ / / /_/ /__/ / / /_/ / / /_/ __/ -# || || /_____/_/\__/\___/_/ \__,_/ /___/\___/ -# -# Copyright (C) 2011-2013 Bitcraze AB -# -# Crazyflie Nano Quadcopter Client -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, -# MA 02110-1301, USA. -""" -USB driver for the Crazyflie. -""" -import logging -import os - -import usb - -__author__ = 'Bitcraze AB' -__all__ = ['CfUsb'] - -logger = logging.getLogger(__name__) - -USB_VID = 0x0483 -USB_PID = 0x5740 - -try: - import usb.core - - pyusb_backend = None - if os.name == 'nt': - import usb.backend.libusb0 as libusb0 - - pyusb_backend = libusb0.get_backend() - pyusb1 = True - -except Exception: - pyusb1 = False - - -def _find_devices(): - """ - Returns a list of CrazyRadio devices currently connected to the computer - """ - ret = [] - - logger.info('Looking for devices....') - - if pyusb1: - for d in usb.core.find(idVendor=USB_VID, idProduct=USB_PID, find_all=1, - backend=pyusb_backend): - if d.manufacturer == 'Bitcraze AB': - ret.append(d) - else: - busses = usb.busses() - for bus in busses: - for device in bus.devices: - if device.idVendor == USB_VID: - if device.idProduct == USB_PID: - ret += [device, ] - - return ret - - -class CfUsb: - """ Used for communication with the Crazyradio USB dongle """ - - def __init__(self, device=None, devid=0): - """ Create object and scan for USB dongle if no device is supplied """ - self.dev = None - self.handle = None - self._last_write = 0 - self._last_read = 0 - - if device is None: - devices = _find_devices() - try: - self.dev = devices[devid] - except Exception: - self.dev = None - - if self.dev: - if (pyusb1 is True): - self.dev.set_configuration(1) - self.handle = self.dev - self.version = float( - '{0:x}.{1:x}'.format(self.dev.bcdDevice >> 8, - self.dev.bcdDevice & 0x0FF)) - else: - self.handle = self.dev.open() - self.handle.setConfiguration(1) - self.handle.claimInterface(0) - self.version = float(self.dev.deviceVersion) - - def get_serial(self): - # The signature for get_string has changed between versions to 1.0.0b1, - # 1.0.0b2 and 1.0.0. Try the old signature first, if that fails try - # the newer one. - try: - return usb.util.get_string(self.dev, 255, self.dev.iSerialNumber) - except (usb.core.USBError, ValueError): - return usb.util.get_string(self.dev, self.dev.iSerialNumber) - - def close(self): - if (pyusb1 is False): - if self.handle: - self.handle.releaseInterface() - else: - if self.dev: - usb.util.dispose_resources(self.dev) - - self.handle = None - self.dev = None - - def scan(self): - # TODO: Currently only supports one device - if self.dev: - return [('usb://0', '')] - return [] - - def set_crtp_to_usb(self, crtp_to_usb): - if crtp_to_usb: - _send_vendor_setup(self.handle, 0x01, 0x01, 1, ()) - else: - _send_vendor_setup(self.handle, 0x01, 0x01, 0, ()) - - def set_cf_to_dfu(self): - _send_vendor_setup(self.handle, 0x01, 0x01, 2, ()) - - - # Data transfers - def send_packet(self, dataOut): - """ Send a packet and receive the ack from the radio dongle - The ack contains information about the packet transmission - and a data payload if the ack packet contained any """ - try: - if (pyusb1 is False): - self.handle.bulkWrite(1, dataOut, 20) - else: - self.handle.write(endpoint=1, data=dataOut, timeout=20) - except usb.USBError: - pass - - def receive_packet(self): - dataIn = () - try: - if (pyusb1 is False): - dataIn = self.handle.bulkRead(0x81, 64, 20) - else: - dataIn = self.handle.read(0x81, 64, timeout=20) - except usb.USBError as e: - try: - if e.backend_error_code == -7 or e.backend_error_code == -116: - # Normal, the read was empty - pass - else: - raise IOError('Crazyflie disconnected') - except AttributeError: - # pyusb < 1.0 doesn't implement getting the underlying error - # number and it seems as if it's not possible to detect - # if the cable is disconnected. So this detection is not - # supported, but the "normal" case will work. - pass - - return dataIn - - -# Private utility functions -def _send_vendor_setup(handle, request, value, index, data): - if pyusb1: - handle.ctrl_transfer(usb.TYPE_VENDOR, request, wValue=value, - wIndex=index, timeout=1000, data_or_wLength=data) - else: - handle.controlMsg(usb.TYPE_VENDOR, request, data, value=value, - index=index, timeout=1000) - - -def _get_vendor_setup(handle, request, value, index, length): - if pyusb1: - return handle.ctrl_transfer(usb.TYPE_VENDOR | 0x80, request, - wValue=value, wIndex=index, timeout=1000, - data_or_wLength=length) - else: - return handle.controlMsg(usb.TYPE_VENDOR | 0x80, request, length, - value=value, index=index, timeout=1000) diff --git a/crazyflie_software/crazyflie-firmware-2021.06/tools/make/flash_dfu/testdfu.py b/crazyflie_software/crazyflie-firmware-2021.06/tools/make/flash_dfu/testdfu.py deleted file mode 100644 index a40eef753..000000000 --- a/crazyflie_software/crazyflie-firmware-2021.06/tools/make/flash_dfu/testdfu.py +++ /dev/null @@ -1,6 +0,0 @@ -from cfusb import CfUsb - -#TODO this devieid might need to be dynamic? -cfusb = CfUsb(devid=int(0)) - -cfusb.set_cf_to_dfu() \ No newline at end of file diff --git a/crazyflie_software/crazyflie-firmware-2021.06/tools/make/usb-bootloader.py b/crazyflie_software/crazyflie-firmware-2021.06/tools/make/usb-bootloader.py new file mode 100644 index 000000000..0e4ef2626 --- /dev/null +++ b/crazyflie_software/crazyflie-firmware-2021.06/tools/make/usb-bootloader.py @@ -0,0 +1,21 @@ +#send a USB request to the crazyflie, causing it to enter DFU mode (bootloader) to automatically +#flash new firmware using 'make flash_dfu' + +from time import sleep +import usb +import usb.core + +#find connected crazyflie, usb vendor and product id = 0483:5740 +dev = usb.core.find(idVendor=0x0483, idProduct=0x5740) +if dev is None: + raise ValueError('Could not find any USB connected crazyflie') + +#send signal to enter bootloader +try: + dev.ctrl_transfer(bmRequestType=usb.TYPE_VENDOR, + bRequest=0x01, wValue=0x01, wIndex=2) +except IOError: + #io error expected because the crazyflie will not respond to USB request as it resets into the bootloader + #TODO usbd_cf_Setup function in firmware needs to return USBD_OK before rebooting to fix this + #sleep to allow time for crazyflie to get into DFU mode + sleep(0.5) \ No newline at end of file -- GitLab