Deutsch English

Branching to different scripts for various microcontrollers (JTAG / SWD)

Prerequisites for this quick guide:

roloFlash can detect which microcontrollers are connected and branch to different scripts accordingly.
This short guide demonstrates the procedure for SWD and JTAG.
The following can be done with the script presented here:

1. Prepare a script to distinguish the various MCUs

Use the template BRANCH.BAS, which you can adapt for your MCU. Near the beginning of the file, you will find the following section:

! *** Please adapt to your requirements! ***

! List of names of targets of interest, for example:
dbNames = vari("STM32F103RB", "STM32WB55RG")  

! List of corresponding device identifiers in the DBGMCU register for STM32
! devices, otherwise type 0 as a value. Must correspond to the list of dbNames,
! for example:
identifiers = long($410, $495)


! Corresponding list of scripts to chain to
scripts = vari("F103RB.BIN", "WB55RG.BIN")

busSpeed   = 100000         ! Bus speed in Hertz. 100 kHz are a conservative
                            ! choice, to ensure reliable operation at a low
                            ! target CPU clock or low roloFlash CPU clock.
                            ! The scripts we will chain to, will reopen with
                            ! an individual speed.
busType = JTAG              ! Choose between SWD and JTAG
roloFlashHiSpeedMode = 0    ! 0 (false): ca. 20mA@3.3V, is slower
                            ! 1 (true):  ca. 80mA@3.3V, is faster

The MCUs to be detected are specified in this example script by the identifiers "STM32F103RB" and "STM32WB55RG" and stored in the list dbNames. Use a list here with identifiers for the MCUs you want to differentiate. The identifiers used here must exactly match those given in the manual in the chapter “IX Specifications”:

dbNames = vari("STM32F103RB", "STM32WB55RG")

For STM32 MCUs, there is a DBGMCU register containing a 12-bit device identifier. This can be additionally checked. The fixed values defined by ST Microelectronics can be found in the respective manufacturer’s manual. A value of 0 means that this check should not be performed.

It is important that the elements of the list identifiers must correspond to the list dbNames. Therefore, both lists must have exactly the same number of elements.

! List of corresponding device identifiers in the DBGMCU register for STM32
! devices, otherwise type 0 as a value. Must correspond to the list of dbNames,
! for example:
identifiers = long($410, $495)

The scripts to be called are specified in another list scripts. This list must also exactly match the list dbNames:

scripts = vari("F103RB.BIN", "WB55RG.BIN")

Furthermore, settings for the bus clock, the bus type used (JTAG or SWD), and the speed mode for the roloFlash are needed.

busSpeed   = 100000         ! Bus speed in Hertz. 100 kHz is a conservative
                            ! choice to ensure reliable operation at a low
                            ! target CPU clock or low roloFlash CPU clock.
                            ! The scripts we will chain to will reopen with
                            ! an individual speed.
busType = JTAG              ! Choose between SWD and JTAG
roloFlashHiSpeedMode = 0    ! 0 (false): approx. 20mA@3.3V, slower
                            ! 1 (true):  approx. 80mA@3.3V, faster

Adjust all these values and parameters appropriately for your project, and rename the script file to RUN_V07.BAS. (Uppercase must be observed!) Compile this file by running compile.bat into the file RUN_V07.BIN, copy it to the SD card if necessary, and insert it into the roloFlash.

2. Testing the script

For testing, we recommend first having no other scripts on the SD card. This way you can test each of your MCUs individually. Although an exception will be raised and the roloFlash will blink red after execution because the subsequent script does not exist, you can check in LOG.TXT whether the correct script would have been called.

An output might look like this:

target STM32F103RB found, chain to F103RB.BIN

Once your tests are complete, proceed with the next chapter.

3. Creating the individual scripts

For the individual scripts for the different MCUs, we recommend selecting and adapting a suitable template from the examples. Further information can be found in the quick guide “Using roloFlash with SD card”.

Choose the filenames as you entered them in the scripts array. Call the compiler rbc_v07.exe with the name of the script you want to translate, for example:

rbc_v07.exe F103RB.BAS

You will then receive the file F103RB.BIN, which you referenced in your scripts array.

Appendix: Example script for chaining (JTAG/SWD)

You can also find this script here as BRANCH.BAS.

#roloFlash 2, v07+

! ***************************************************************************
! *
! *  Sample script for JTAG or SWD determine which target is conneced:
! *  - via IDCODE
! *  - in case of STM32, if wanted: additionally via device identifiers in
! *                                 the DBGMCU register
! *  - in case of JTAG and STM32:   additionally via IDCODE of secondary
! *                                 JTAG-device (boundary scan controller)
! *
! *  Task: Read the IDCODE via JTAG or SWD and then chain to the corresponding
! *  script
! *
! *  Copyright (C) 2009-2025 by halec embedded solutions, https://www.halec.de
! *
! ***************************************************************************


! For all files on the microSD card, the following applies:
!  - File name has to be in 8.3 format
!  - File name must contain only CAPITAL LETTERS
!  - (see manual, chapter "Files")


! *** Please adapt to your requirements! ***

! List of names of targets of interest, for example:
dbNames = vari("STM32F103RB", "STM32WB55RG")  

! List of corresponding device identifiers in the DBGMCU register for STM32
! devices, otherwise type 0 as a value. Must correspond to the list of dbNames,
! for example:
identifiers = long($410, $495)


! Corresponding list of scripts to chain to
scripts = vari("F103RB.BIN", "WB55RG.BIN")

busSpeed   = 100000         ! Bus speed in Hertz. 100 kHz are a conservative
                            ! choice, to ensure reliable operation at a low
                            ! target CPU clock or low roloFlash CPU clock.
                            ! The scripts we will chain to, will reopen with
                            ! an individual speed.
busType = JTAG              ! Choose between SWD and JTAG
roloFlashHiSpeedMode = 0    ! 0 (false): ca. 20mA@3.3V, is slower
                            ! 1 (true):  ca. 80mA@3.3V, is faster

! Set LED 1 to green -> symbolizes script starting
led_on 1, COLOR_GREEN


! ---- Preparations ----
! Delete old log file, if present
f = "LOG.TXT"
if fs_fileExists(0, f)
  fs_remove 0, f
endif


! Write software version of roloFlash and script name to LOG.TXT
print "softwareVersion=", sys_softwareVersion, "\r\n"
print "Running script copied from scripts/???/ ...\r\n"


! If roloFlashHiSpeedMode has been selected, set CPU clock of roloFlash to
! the maximum
if roloFlashHiSpeedMode
  sys_setCpuClock CPU_CLOCKMAX
endif



! ---- Scan JTAG / SWD bus ----
if busType = JTAG
  print "Scanning JTAG bus ...\r\n"
else
  print "Scanning SWD bus ...\r\n"
endif  

busHandle = bus_open(busType, 0, busSpeed)
devices = bus_scan(busHandle)
print "Number of devices:", size(devices), "\r\n"
for i = 0 to size(devices) - 1
  print "  Found device: id=", devices[i], "\r\n"
next

! ---- If no JTAG / SWD device has been found, abort ----
if size(devices) < 1
  print "ERROR: no device found!\r}n"
  throw USEREXCEPTION + 1
endif

print "Checking MCUs ...\r\n"
for i = 0 to size(dbNames) - 1
  ! ---- Compare the idcode with the idcode of the MCUs in the list ----
  dbHandle = db_getHandle(dbNames[i])
  expectedCoreIDCODE = db_get(dbHandle, db_coreIDCODE)
  print "expectedCoreIDCODE: ", expectedCoreIDCODE, "\r\n"
  if busType = JTAG
    mask = $0fffffff
  else
    mask = $0fff0fff
  endif  
  if ((devices[0] and mask) = (expectedCoreIDCODE and mask))
    print "idcode cpu ok..\r\n"
    ! ---- idcode match: ----
    ! JTAG: STM32 devices adds a second device on the bus, the 
    ! boundaryscan controller
    catch exceptionOld
    if (exceptionOld = 0) and (busType = JTAG)
      expectedBoundaryScanIDCODE = db_get(dbHandle, db_boundaryScanIDCODE)
    endif
    catch exceptionNew ! no boundaryScanIDCODE in the database
    if exceptionOld
      throw exceptionOld
    endif  
    if (expectedBoundaryScanIDCODE = 0) xor (size(devices) = 2)
      match = 1
      if size(devices)
        if((devices[1] and mask) <> (expectedBoundaryScanIDCODE and mask))
          print "idcode bs nok..\r\n"
          match = 0
        endif  
      endif
      if match and (identifiers[i] <> 0)   
        print "check device identifier..\r\n"
        ! ---- Read the DBGMCU from the target and get the lowest 12 bits for
        ! ---- the device identifier
        targetHandle = target_open(busHandle, 0, DB_get(dbHandle, db_family))
        target_setMode targetHandle, PROGRAMMODE
        dbgmcu = target_read(targetHandle, readMemory , $E0042000, 4) ! $E0042000: DBGMCU register
        target_close targetHandle
        identifier = (dbgmcu[0] + dbgmcu[1] * 256) and ((1 << 12) - 1)
        ! ---- Compare the device identifier with the list ----
        match = (identifier = identifiers[i])
      endif
      if match      
        print "MATCH..\r\n"
        ! ---- idcode and device identifier match:                        ----
        ! ---- Prepare and chain to the corresponding  script in the list ---- 
        bus_close busHandle
        print "target ", dbNames[i], " found, chain to ", scripts[i], "..\r\n"
        sys_setLogMode LOGMODE_IMMEDIATE
        sys_setLogMode LOGMODE_NORMAL
        sys_setCpuClock CPU_CLOCKMIN
        chain SDCARD,scripts[i]
      endif  
    endif      
  endif
next
bus_close busHandle
! ---- device is not in the list of expected devices ----
throw USEREXCEPTION + 900 ! avoid collisions with other user exceptions

! ---- Postprocessing ----

! ---- Check for possibly occurred exceptions, write           ----
! ---- evaluation to log file and signal it via LEDs           ----
catch exception
print "Duration [ms]: ", sys_getSystemTime(), "\r\n"
if exception <> 0
  ! There has been an error, record the error in  LOG.TXT
  print "ERROR: Exception ", exception
  ! Throw exception again, after it has been caught. As a result, the number
  ! of the exception gets displayed via LED blink codes. The blink codes
  ! are documented in the manual, chapter "Meaning of LED Codes", subchapter
  ! "Exception has Occurred"
  throw exception
else
  ! No errors: write to log file and switch LED 5 to green
  print "Script ran successfully.\r\n"
  led_on 5, COLOR_GREEN
endif