From 4d8db1df0e7b6ed658ca9e2e1b798570b9f0b35d Mon Sep 17 00:00:00 2001 From: David Lechner Date: Sat, 15 May 2021 16:49:55 -0500 Subject: [PATCH] flash: additional work around for windows/city hub This addresses additional quirks seen on a specific Windows setup with the city hub. Issue: https://github.com/pybricks/support/issues/256 --- pybricksdev/flash.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/pybricksdev/flash.py b/pybricksdev/flash.py index 4988f6b..89dd6ee 100644 --- a/pybricksdev/flash.py +++ b/pybricksdev/flash.py @@ -7,6 +7,7 @@ import json import logging import os +import platform import struct import sys from typing import Dict, Tuple @@ -275,6 +276,7 @@ class BootloaderConnection(BLERequestsConnection): def __init__(self): """Initialize the BLE Connection for Bootloader service.""" super().__init__('00001626-1212-efde-1623-785feabcd123') + self.ignore_erase_reply = False async def bootloader_request(self, request, payload=None, timeout=None): """Sends a message to the bootloader and awaits corresponding reply.""" @@ -292,6 +294,9 @@ async def bootloader_request(self, request, payload=None, timeout=None): if request.reply_len > 0: logger.debug("Awaiting reply") reply = await self.wait_for_reply(timeout) + # Windows may receive reply from erase command at the wrong time + if self.ignore_erase_reply and reply[0] == 0x11: + reply = await self.wait_for_reply(timeout) return request.parse_reply(reply) async def flash(self, firmware, metadata): @@ -320,14 +325,19 @@ async def flash(self, firmware, metadata): # Erase existing firmware logger.debug("Erasing flash.") try: + # Windows sometimes doesn't receive the reply to this command at all + # or until another command is sent (buggy Bluetooth drivers?) so we + # have a few hacks to special case this. City hub further complicates + # things by having a buggy Bluetooth implementation in its bootloader. response = await self.bootloader_request( self.ERASE_FLASH_CITY_HUB - if info.type_id == HubTypeId.CITY_HUB + if info.type_id == HubTypeId.CITY_HUB and not platform.system() == "Windows" else self.ERASE_FLASH, timeout=5 ) logger.debug(response) except asyncio.TimeoutError: + self.ignore_erase_reply = True logger.info("did not receive erase reply, continuing anyway") # Get the bootloader ready to accept the firmware