diff --git a/.github/workflows/build-and-release.yml b/.github/workflows/build-and-release.yml index 019fa31..4aacdd1 100644 --- a/.github/workflows/build-and-release.yml +++ b/.github/workflows/build-and-release.yml @@ -55,7 +55,7 @@ jobs: run: ls -la - name: Publish Release - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@v2 with: files: | ${{ needs.call-macos-build.outputs.build-file }} diff --git a/.github/workflows/build-linux.yml b/.github/workflows/build-linux.yml index e72f7a9..d5407f1 100644 --- a/.github/workflows/build-linux.yml +++ b/.github/workflows/build-linux.yml @@ -25,10 +25,10 @@ jobs: # Steps represent a sequence of tasks that will be executed as part of the job steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: - python-version: '3.10' + python-version: '3.12' # Setup python - name: System Setup @@ -42,7 +42,7 @@ jobs: gzip ArtemisUploader mv ArtemisUploader.gz ArtemisUploader.linux.gz - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: ArtemisUploader.linux.gz path: ArtemisUploader.linux.gz diff --git a/.github/workflows/build-macos.yml b/.github/workflows/build-macos.yml index 894fba2..a6582fb 100644 --- a/.github/workflows/build-macos.yml +++ b/.github/workflows/build-macos.yml @@ -25,10 +25,10 @@ jobs: # Steps represent a sequence of tasks that will be executed as part of the job steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: - python-version: '3.10' + python-version: '3.12' # Setup python - name: System Setup @@ -44,7 +44,7 @@ jobs: mv "ArtemisUploader.app" "tmp/" create-dmg --volicon "artemis_uploader/resource/sparkdisk.icns" --background "artemis_uploader/resource/sfe_logo_med.png" --hide-extension "ArtemisUploader.app" --icon "ArtemisUploader.app" 100 100 --window-size 600 440 --app-drop-link 400 100 "ArtemisUploader.dmg" "tmp/" - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: ArtemisUploader.dmg path: ArtemisUploader.dmg diff --git a/.github/workflows/build-python.yml b/.github/workflows/build-python.yml index b5b6551..af09114 100644 --- a/.github/workflows/build-python.yml +++ b/.github/workflows/build-python.yml @@ -29,10 +29,10 @@ jobs: # Steps represent a sequence of tasks that will be executed as part of the job steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: - python-version: '3.10' + python-version: '3.12' # Setup python - name: System Setup @@ -44,7 +44,7 @@ jobs: run: | python setup.py sdist - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: python-install-package path: dist diff --git a/.github/workflows/build-windows.yml b/.github/workflows/build-windows.yml index ce74d7f..199e7a6 100644 --- a/.github/workflows/build-windows.yml +++ b/.github/workflows/build-windows.yml @@ -25,10 +25,10 @@ jobs: # Steps represent a sequence of tasks that will be executed as part of the job steps: # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v3 - - uses: actions/setup-python@v4 + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 with: - python-version: '3.10' + python-version: '3.12' # Setup python - name: System Setup @@ -50,7 +50,7 @@ jobs: } Compress-Archive @compress - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: ArtemisUploader.win.zip path: ArtemisUploader.win.zip diff --git a/README.md b/README.md index 9632755..d9f15b5 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ If you need to install the application, see the [Installation Section](#installa * Attach the Artemis target board over USB * Select the COM port from the dropdown menu * Adjust the Baud Rate as desired -* Click the ```Upload Firmware``` Button in the lower left of the app. +* Click the ```Upload Firmware``` Button in the lower right corner of the app. The selected firmware is then uploaded to the connected SparkFun Artemis product. Upload information and progress are displayed in the output portion of the interface. @@ -49,36 +49,70 @@ Installation binaries are available for all major platforms (macOS, Window, and ### Windows * Download the [github release](https://github.com/sparkfun/Artemis-Firmware-Upload-GUI/releases) zip file - *ArtemisUploader.win.zip* * Unzip the release file - *ArtemisUploader.zip* -* This results in the application executable, *ArtemisUploader.exe* +* This results in the application executable *ArtemisUploader.exe* * Double-click *ArtemisUploader.exe* to start the application +* The Windows EXE isn't signed, so you will see the following warning. Click **More info**: -![macOS Artemis Uploader](images/artemis-windows.png) +![Artemis Uploader on Windows - Warning 1](images/artemis-windows-1.png) + +* Click **Run anyway** to start the GUI: + +![Artemis Uploader on Windows - Warning 2](images/artemis-windows-2.png) + +![Artemis Uploader on Windows](images/artemis-windows.png) ### macOS + +* Check that you have the latest WCH drivers installed for the CH340 interface chip. + * Full instructions can be found in our [CH340 Tutorial](https://learn.sparkfun.com/tutorials/how-to-install-ch340-drivers/all#mac-osx) + * Here is a link to the WCH downloads page for the [CH340 / CH341 macOS driver](https://www.wch-ic.com/downloads/CH341SER_MAC_ZIP.html) + * The Zip file contains more instructions: CH34X_DRV_INSTAL_INSTRUCTIONS.pdf + * Download the [github release](https://github.com/sparkfun/Artemis-Firmware-Upload-GUI/releases) file - *ArtemisUploader.dmg* -* Double click on the file to unzip the file to *ArtemisUploader.dmg* -* Double click the *ArtemisUploader.dmg* file to mount the disk image. +* Click on the downloads icon +* Click the *ArtemisUploader.dmg* file to mount the disk image * The following Finder window, with the contents of the file will open ![Artemis Uploader macOS Finder](images/macos-finder.png) -* Install the *ArtemisUploader.app* by dragging it on the *Applications* in the ArtemisUploader Finder Window, or copying the file to a desired location. -* Once complete, unmount the ArtemisUploader disk image by right-clicking on the mounted disk in Finder and ejecting it. +* Install the *ArtemisUploader.app* by dragging it onto the *Applications* icon in the ArtemisUploader Finder Window, or copying the file to a desired location. +* Once complete, unmount the ArtemisUploader disk image by clicking on the disk eject in Finder. + +![Artemis Uploader macOS Finder](images/artemis-macos-install-1.png) To launch the Artemis Uploader application: + * Double-click ArtemisUploader.app to launch the application -* The ArtemisUploader.app isn't signed, so macOS won't run the application, and will display a warning dialog. Dismiss this dialog. -* To approve app execution bring up the macOS *System Preferences* and navigate to: *Security & Privacy > General*. -* On this page, select the *Open Anyway* button to launch the ArtemisUploader application. +![Artemis Uploader macOS Finder](images/artemis-macos-install-2.png) + +* The ArtemisUploader.app isn't signed, so macOS won't run the application, and will display a warning dialog. Click **Done**. + +![Artemis Uploader macOS Finder](images/artemis-macos-install-3.png) -![macOS Security](images/macos-security.png) +* To approve app execution bring up the macOS *System Settings* and navigate to *Privacy & Security*. +* On this page, select the **Open Anyway** button to launch the ArtemisUploader application. -* Once selected, macOS will present one last dialog. Select *Open* to run the application. The ArtemisUploader will now start. +![Artemis Uploader macOS System Settings](images/artemis-macos-install-4.png) -![macOS Artemis Uploader](images/artemis-macos.png) +* Once selected, macOS will present one last dialog. Select **Open Anyway** to run the application. + +![Artemis Uploader macOS System Settings](images/artemis-macos-install-5.png) + +* Enter your password and click The ArtemisUploader will now start. + +![Artemis Uploader macOS System Settings](images/artemis-macos-install-6.png) + +* Ensure you select the correct *COM Port*. The port name should begin with **cu.wchusbserial**. + +![macOS Artemis Uploader](images/artemis-macos-1.png) + +* When you select the *Firmware File*, click **Allow** to allow the app to open the file. + +![macOS Artemis Uploader](images/artemis-macos-2.png) ### Linux + * Download the [github release](https://github.com/sparkfun/Artemis-Firmware-Upload-GUI/releases) file - *ArtemisUploader.linux.gz* * Unzip the release file - *ArtemisUploader.linux.gz* * Un-gzip the file, either by double-clicking in on the desktop, or using the `gunzip` command in a terminal window. This results in the file *ArtemisUploader* @@ -87,7 +121,6 @@ To launch the Artemis Uploader application: ![Linux Artemis Uploader](images/artemis-linux.png) - ### Python Package The Artemis Uploader App is also provided as an installable Python package. This is advantageous for platforms that lack a pre-compiled application. diff --git a/artemis_uploader/artemis_svl.py b/artemis_uploader/artemis_svl.py index 6a623bc..5e89268 100644 --- a/artemis_uploader/artemis_svl.py +++ b/artemis_uploader/artemis_svl.py @@ -365,34 +365,50 @@ def upload_firmware(binfile, port, baud, timeout=0.5): bl_success = False entered_bootloader = False - for _ in range(num_tries): + # Instantiate ser here and set dtr and rts before opening the port + ser = serial.Serial() + ser.port = port + ser.baudrate = baud + ser.timeout = timeout - with serial.Serial(port, baud, timeout=timeout) as ser: + attempt = 0 - # startup time for Artemis bootloader (experimentally determined - 0.095 sec min delay) - t_su = 0.15 + while (attempt < num_tries) and (bl_success == False): - time.sleep(t_su) # Allow Artemis to come out of reset + # Set dtr and rts before opening the port + # https://community.sparkfun.com/t/unable-to-flash-artemis-thing-plus-on-macos-sequoia/60766/6 + ser.dtr=False + ser.rts=False - # Perform baud rate negotiation - entered_bootloader = phase_setup(ser) + ser.open() - if(entered_bootloader == True): - bl_success = phase_bootload(ser, binfile) - if(bl_success == True): # Bootload - #print("Bootload complete!") - break - else: - verboseprint("Failed to enter bootload phase") + ser.dtr=True # True sets the CH340 RTS pin low + ser.rts=True + # startup time for Artemis bootloader (experimentally determined - 0.095 sec min delay) + t_su = 0.15 + time.sleep(t_su) # Allow Artemis to come out of reset - if(bl_success == True): - break + ser.reset_input_buffer() # reset the input bufer to discard any UART traffic that the device may have generated - if(entered_bootloader == False): - print( - "Target failed to enter bootload mode. Verify the right COM port is selected and that your board has the SVL bootloader.") + # Perform baud rate negotiation + entered_bootloader = phase_setup(ser) + + if(entered_bootloader == True): + bl_success = phase_bootload(ser, binfile) + else: + verboseprint("Failed to enter bootload phase") + + ser.close() + attempt = attempt + 1 + + if (entered_bootloader == False): + print("Target failed to enter bootload mode. Verify the right COM port is selected and that your board has the SVL bootloader.") + elif (bl_success == False): + print("Target entered bootloader mode but firmware upload failed. Verify the right COM port is selected and that your board has the SVL bootloader.") + else: + print("Success!") except serial.SerialException: phase_serial_port_help(port) diff --git a/artemis_uploader/asb/asb.py b/artemis_uploader/asb/asb.py index 9f6bd1d..3851751 100644 --- a/artemis_uploader/asb/asb.py +++ b/artemis_uploader/asb/asb.py @@ -378,11 +378,17 @@ def upload(args, verboseprint): connection_timeout = 5 print('Connecting over serial port {}...'.format(args.port), flush=True) - print('Baud rate:',args.baud) + print('Requested baud rate:',args.baud) + + useBaud = int(args.baud) + if (useBaud > 115200): + print('Limiting baud rate to 115200') + useBaud = 115200 + useBaud = str(useBaud) #Check to see if the com port is available try: - with serial.Serial(args.port, args.baud, timeout=connection_timeout) as ser: + with serial.Serial(args.port, useBaud, timeout=connection_timeout) as ser: pass except: @@ -413,43 +419,56 @@ def upload(args, verboseprint): #fails to correctly catch the BOOT signal about 1 out of ten times. #Auto-retry this number of times before we give up. + # Instantiate ser here and set dtr and rts before opening the port + ser = serial.Serial() + ser.port = args.port + ser.baudrate = useBaud + ser.timeout = connection_timeout + loadTries = 0 while loadTries < 3: loadSuccess = False - with serial.Serial(args.port, args.baud, timeout=connection_timeout) as ser: - #DTR is driven low when serial port open. DTR has now pulled RST low. + # Set dtr and rts before opening the port + ser.dtr=True + ser.rts=True - time.sleep(0.01) #3ms and 10ms work well. Not 50, and not 0. + ser.open() - #Setting RTS/DTR high causes the bootload pin to go high, then fall across 100ms - ser.setDTR(0) #Set DTR high - ser.setRTS(0) #Set RTS high - support the CH340E + # RTS behaves differently on macOS. Use a double-reset + time.sleep(0.01) + ser.dtr=False # Set RTS and DTR high + ser.rts=False + time.sleep(0.01) + ser.dtr=True # Set RTS and DTR low + ser.rts=True - time.sleep(0.01) #A double-reset seems to work best on macOS - ser.setDTR(1) - ser.setRTS(1) + time.sleep(0.008) #3ms and 10ms work well. Not 50, and not 0. - time.sleep(0.01) - ser.setDTR(0) - ser.setRTS(0) + # Set RTS and DTR high + # This causes BOOT to go high - and then decay back to zero + ser.dtr=False + ser.rts=False - #Give bootloader a chance to run and check bootload pin before communication begins. But must initiate com before bootloader timeout of 250ms. - time.sleep(0.100) #100ms works well + #Give bootloader a chance to run and check BOOT pin before communication begins. But must initiate com before bootloader timeout of 250ms. + time.sleep(0.1) # 100ms works well - ser.reset_input_buffer() # reset the input bufer to discard any UART traffic that the device may have generated + ser.reset_input_buffer() # reset the input bufer to discard any UART traffic that the device may have generated - connect_device(ser, args, verboseprint) + connect_device(ser, args, verboseprint) - loadTries = loadTries + 1 - - if(loadSuccess == True): - print("Tries =", loadTries) - print('Upload complete') - exit() - else: - print("Fail") + loadTries = loadTries + 1 + + if(loadSuccess == True): + ser.close() + print("Tries =", loadTries) + print('Upload complete') + exit() + else: + print("Fail") + + ser.close() print("Tries =", loadTries) print("Upload failed") diff --git a/artemis_uploader/resource/_version.py b/artemis_uploader/resource/_version.py index 528787c..f5f41e5 100644 --- a/artemis_uploader/resource/_version.py +++ b/artemis_uploader/resource/_version.py @@ -1 +1 @@ -__version__ = "3.0.0" +__version__ = "3.1.0" diff --git a/images/artemis-macos-1.png b/images/artemis-macos-1.png new file mode 100644 index 0000000..820fd4c Binary files /dev/null and b/images/artemis-macos-1.png differ diff --git a/images/artemis-macos-2.png b/images/artemis-macos-2.png new file mode 100644 index 0000000..baac66b Binary files /dev/null and b/images/artemis-macos-2.png differ diff --git a/images/artemis-macos-install-1.png b/images/artemis-macos-install-1.png new file mode 100644 index 0000000..71f49cc Binary files /dev/null and b/images/artemis-macos-install-1.png differ diff --git a/images/artemis-macos-install-2.png b/images/artemis-macos-install-2.png new file mode 100644 index 0000000..1e1fbe9 Binary files /dev/null and b/images/artemis-macos-install-2.png differ diff --git a/images/artemis-macos-install-3.png b/images/artemis-macos-install-3.png new file mode 100644 index 0000000..3b0f6bf Binary files /dev/null and b/images/artemis-macos-install-3.png differ diff --git a/images/artemis-macos-install-4.png b/images/artemis-macos-install-4.png new file mode 100644 index 0000000..3b62cf5 Binary files /dev/null and b/images/artemis-macos-install-4.png differ diff --git a/images/artemis-macos-install-5.png b/images/artemis-macos-install-5.png new file mode 100644 index 0000000..605e637 Binary files /dev/null and b/images/artemis-macos-install-5.png differ diff --git a/images/artemis-macos-install-6.png b/images/artemis-macos-install-6.png new file mode 100644 index 0000000..acce00a Binary files /dev/null and b/images/artemis-macos-install-6.png differ diff --git a/images/artemis-macos.png b/images/artemis-macos.png deleted file mode 100644 index fb1429f..0000000 Binary files a/images/artemis-macos.png and /dev/null differ diff --git a/images/artemis-windows-1.png b/images/artemis-windows-1.png new file mode 100644 index 0000000..653d711 Binary files /dev/null and b/images/artemis-windows-1.png differ diff --git a/images/artemis-windows-2.png b/images/artemis-windows-2.png new file mode 100644 index 0000000..784332a Binary files /dev/null and b/images/artemis-windows-2.png differ diff --git a/images/artemis-windows.png b/images/artemis-windows.png index c3d006c..11bba4e 100644 Binary files a/images/artemis-windows.png and b/images/artemis-windows.png differ diff --git a/images/macos-security.png b/images/macos-security.png deleted file mode 100644 index 12a5a15..0000000 Binary files a/images/macos-security.png and /dev/null differ diff --git a/setup.py b/setup.py index 6570d78..a676ccc 100644 --- a/setup.py +++ b/setup.py @@ -128,6 +128,9 @@ def get_version(rel_path: str) -> str: 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', ],