diff --git a/scripts/stm32/openocd/flash.sh b/scripts/stm32/openocd/flash.sh new file mode 100755 index 00000000..a5843af4 --- /dev/null +++ b/scripts/stm32/openocd/flash.sh @@ -0,0 +1,94 @@ +#!/bin/bash + +target="None" +offset=0x08000000 +filename=$1 +interface=$2 +echo "Filename arg: $filename" +prnt_path=$(dirname $(dirname "$BASH_SOURCE")) + +# check f interface was passed +if [ -z "$interface" ]; then + if [ -f "/proc/device-tree/model" ]; then + model=$(cat /proc/device-tree/model) + echo "$model" + if [[ $model == *"Raspberry Pi 5"* ]]; then + interface="raspberrypi5-gpiod" + elif [[ $model == *"Raspberry Pi 4"* ]]; then + interface="raspberrypi4-native" + elif [[ $model == *"Raspberry Pi 2"* ]]; then + interface="raspberrypi2-native" + else + echo "raspberrypi-native" + fi + else + interface="stlink" + fi + echo "Using $interface" +fi +# check if interface is stlink, then flash via st-flash +if [ "$interface" == "stlink" ]; then + ./${prnt_path}/flash.sh $filename + exit +fi + +check_chip(){ + # Run OpenOCD and capture the output + output=$(openocd -c "source [find interface/${interface}.cfg] + swd newdap chip cpu -enable + dap create chip.dap -chain-position chip.cpu + target create chip.cpu cortex_m -dap chip.dap + + init + dap info + shutdown + ") + + # Extract the processor name using grep and awk + processor_name=$(echo "$output" | awk '/chip.cpu/ {print}' | awk 'NR == 1 {print $4}') + echo "output: $output" + # Print the processor name + echo "Detected Processor: $processor_name" + + # Optionally, detect STM32 family based on the processor name + case "$processor_name" in + "Cortex-M0+") + echo "Detected STM32 Family: STM32G0" + target="stm32g0x" + ;; + "Cortex-M3") + echo "Detected STM32 Family: STM32F103" + target="stm32f1x" + ;; + *) + echo "Unknown Processor or Family" + exit 1 + ;; + esac + +} + +check_chip +echo "$target" +flash_size_str="" +if [ "$target" == "stm32f1x" ]; then + flash_size_str="set FLASH_SIZE 0x00020000" +fi + +echo $(openocd -c " +source [find interface/${interface}.cfg] +set CHIPNAME ${target} +source [find target/${target}.cfg] + +reset_config srst_nogate +init +targets +reset halt + +${flash_size_str} +${target} mass_erase 0 +flash write_image erase $filename $offset +flash verify_image $filename $offset +reset run +exit +") diff --git a/src/raccoonlab_tools/common/firmware_manager.py b/src/raccoonlab_tools/common/firmware_manager.py index dbfbc830..2e227db6 100755 --- a/src/raccoonlab_tools/common/firmware_manager.py +++ b/src/raccoonlab_tools/common/firmware_manager.py @@ -24,7 +24,10 @@ def upload_firmware(binary_path): if system == "Windows": ProgrammerWindows.upload_firmware(binary_path) elif system == "Linux": - StlinkLinux.upload_firmware(binary_path) + if (os.path.exists("/proc/device-tree/model")): + OpenocdLinux.upload_firmware(binary_path) + else: + StlinkLinux.upload_firmware(binary_path) elif system == "Darwin": print("MacOS is not supported yet.") else: @@ -141,6 +144,60 @@ def execute(cmd): for path in execute(cmd): print(path, end="") +class OpenocdLinux: + @staticmethod + def upload_firmware(binary_path : str): + interface = "stlink" + if (os.path.exists("/proc/device-tree/model")): + rpi_model = os.popen('cat /proc/device-tree/model').read() + print(rpi_model) + if "Raspberry Pi 5" in rpi_model: + interface = "raspberrypi5-gpiod" + if "Raspberry Pi 4" in rpi_model: + interface = "raspberrypi4-native" + elif "Raspberry Pi 2" in rpi_model: + interface="raspberrypi2-native" + elif "Raspberry Pi 3" in rpi_model: + print("Raspberry Pi 3 is not supported yet") + return + else: + print("Unknown RaspberryPi model") + interface = "raspberrypi-native" + print(f"Using {interface} interface") + + target = OpenocdLinux.get_target(interface) + cmd = ["openocd", "-c", f'source [find interface/{interface}.cfg];\ + set CHIPNAME {target};\ + source [find target/{target}.cfg];\ + program {binary_path} verify reset exit;'] + process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + process.wait() + _, stdout = process.communicate() + print(stdout.decode()) + + @staticmethod + def get_target(interface : str): + cmd = ["openocd", "-c", f"source [find interface/{interface}.cfg];\ + swd newdap chip cpu -enable; dap create chip.dap -chain-position chip.cpu;\ + target create chip.cpu cortex_m -dap chip.dap;\ + init;\ + dap info;\ + exit;\ + shutdown"] + process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + process.wait() + _, stdout = process.communicate() + + lines = stdout.decode() + if "Cortex-M3" in lines: + print("Detected: stm32f1x") + return "stm32f1x" + elif "Cortex-M0+" in lines: + print("Detected: stm32g0x") + return "stm32g0x" + else: + print("Unknown target") + raise RuntimeError("Unknown target") # Just for test purposes if __name__ == '__main__': diff --git a/src/raccoonlab_tools/scripts/common/upload_firmware.py b/src/raccoonlab_tools/scripts/common/upload_firmware.py index 9a6028c4..352823b0 100755 --- a/src/raccoonlab_tools/scripts/common/upload_firmware.py +++ b/src/raccoonlab_tools/scripts/common/upload_firmware.py @@ -7,6 +7,7 @@ import yaml from raccoonlab_tools.common.firmware_manager import FirmwareManager from raccoonlab_tools.common.device_manager import DeviceManager +import os def main(): parser = argparse.ArgumentParser() @@ -22,8 +23,11 @@ def main(): elif args.binary: binary_path = args.binary - # Just to check that the programmer is avaliable - DeviceManager.get_programmer() + if (os.path.exists("/proc/device-tree/model")): + print("I'm rpi") + else: + # Just to check that the programmer is avaliable + DeviceManager.get_programmer() FirmwareManager.upload_firmware(binary_path)