#roloFlash 2, v07+

! ***************************************************************************
! *
! *  Sample script for ST Microelectronics
! *  STM32WB Controllers
! *
! *  Task: Erase chip, then write to flash memory via SWD
! *
! *  Copyright (C) 2009-2025 by halec embedded solutions
! *
! ***************************************************************************


! 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! ***


targetName = "STM32WB55RG"! Take exact name from manual, chapter
                            ! "Specifications"
flashFile  = "FLASH.HEX"    ! Specify "", if not needed
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. If
                            ! it is known that the target CPU clock is higher,
                            ! the bus speed can be increased appropriately.
roloFlashHiSpeedMode = 0    ! 0 (false): ca. 20mA@3.3V, is slower
                            ! 1 (true):  ca. 80mA@3.3V, is faster

! Green running light from LED 1 to LED 4 -> symbolizes script processing
! (Data transfer direction: write)
! (LED 5 is kept free for display of "Done")
led_runningLight 1, 4, COLOR_GREEN, 200


! ---- 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/STM32/STM32_WB/SWD/erase-and-flash/ ...\r\n"


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


! ---- Access to roloFlash's internal target database ----
dbHandle = db_getHandle(targetName)


! ---- Scan SWD bus ----
print "Scanning SWD bus ...\r\n"
busHandle = bus_open(SWD, 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 SWD device has been found, abort ---
if size(devices) < 1
  print "ERROR: Wrong number of SWD devices found:", size(devices)
  throw USEREXCEPTION + 1
endif


! ---- Access to target ----
print "Connecting to target ...\r\n"
family       = db_get(dbHandle, DB_FAMILY)
targetHandle = target_open(busHandle, 0, family)
target_setMode targetHandle, PROGRAMMODE


! ---- Check device IDs ----
print "Checking Device IDs ...\r\n"
expectedCoreIDCODE = db_get(dbHandle, db_coreIDCODE) and $0fffffff
print "expectedCoreIDCODE: ", expectedCoreIDCODE, "\r\n"
if ((devices[0] and $0fff0fff) <> (expectedCoreIDCODE and $0fff0fff))
  print "ERROR: Wrong controller detected\r\n"
  ! Abort
  throw USEREXCEPTION + 2
endif


! ---- Get target memory parameters from target database ----
print "Getting target memory parameters from database ...\r\n"
flashSize  = db_get(dbHandle, DB_FLASHSIZE)
print "  Target flashSize [bytes]: ", flashSize, "\r\n"


! ---- Erase target ----
print "Erasing flash ...\r\n"

! we have to stop the second CPU 
! otherwise it may disturb our flash accesses
! read pwr_cr4 register, delete bit 8 and write back
pwr_cr4 = $5800040C
value = target_read(targetHandle, READMEMORY, pwr_cr4, 4)
print "first read of pwr_cr4:\r\n"
for i = 0 to 3
  print "value[]=", value[i], "\r\n"
next
value[1] = value[1] and $7f
print "first write to pwr_cr4:\r\n"
for i = 0 to 3
  print "value[]=", value[i], "\r\n"
next
target_write targetHandle, value, RAM, WRITEONLY, pwr_cr4

! read out, how many flash-pages are unsecured
flash_sfr = $58004080
pageSize = 4096
value = target_read(targetHandle, READMEMORY, flash_sfr, 4)
print "read of flash_sfr:\r\n"
for i = 0 to 3
  print "value[]=", value[i], "\r\n"
next

! if bit 0 is set, chip is not secured
if (value[1] and 1) = 1
  print "flash is not secured: erase all pages\r\n"
  num = db_get(dbHandle1, db_flashsize) div pageSize
else
  print "flash is secured: erase only unsecured pages\r\n"
  num = value[0] - 1
endif

! Sanity check fuer unser Hardware: da sind 202 Pages unsecure
if num <> 202
  print "wrong number of Pages unsecured pages, should be 202, found:", num, "\r\n"
  throw userException + 3
endif

! do a reset to start the target software  
target_close targetHandle
handle = GPIO_open(GPIO_RST, PIN_PUSHPULL, 0)
delay 100
bus_close handle
targetHandle = target_open(busHandle, 0, family)
target_setMode targetHandle, PROGRAMMODE
! Now we can erase all unsecured pages
print "Number of last page to delete: ", num, "\r\n"
for i = 0 to num
  target_erase targetHandle, FLASH, PAGE, i
next

print "Flash erased\r\n"



! ---- Write to target flash ----
if flashFile <> ""
  print "Loader usage: ", target_getLoaderUsage(targetHandle), "\r\n"
  print "Programming flash file ", flashFile, " ...\r\n"
  target_writeFromFile targetHandle, 0, flashFile, HEX, FLASH, WRITEVERIFY
else
  print "Flash programming skipped (no flash file specified)\r\n"
endif


! ---- Postprocessing ----
target_close targetHandle
bus_close busHandle


! Do a reset to start the target software
print "Resetting target ...\r\n"
handle = GPIO_open(GPIO_RST, PIN_PUSHPULL, 0)
delay 100
bus_close handle


! ---- Check for possibly occurred exceptions, write           ----
! ---- evaluation to log file and signal it via LEDs           ----
catch exception
print "Duration [ms]: ", sys_getSystemTime(), "\r\n"
catch dummyException  ! If the last print throws an exception
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
