+proc program {filename args} {
+ set exit 0
+ set needsflash 1
+
+ foreach arg $args {
+ if {[string equal $arg "preverify"]} {
+ set preverify 1
+ } elseif {[string equal $arg "verify"]} {
+ set verify 1
+ } elseif {[string equal $arg "reset"]} {
+ set reset 1
+ } elseif {[string equal $arg "exit"]} {
+ set exit 1
+ } else {
+ set address $arg
+ }
+ }
+
+ # Set variables
+ set filename \{$filename\}
+ if {[info exists address]} {
+ set flash_args "$filename $address"
+ } else {
+ set flash_args "$filename"
+ }
+
+
+ # make sure init is called
+ if {[catch {init}] != 0} {
+ program_error "** OpenOCD init failed **" 1
+ }
+
+ # reset target and call any init scripts
+ if {[catch {reset init}] != 0} {
+ program_error "** Unable to reset target **" $exit
+ }
+
+ # Check whether programming is needed
+ if {[info exists preverify]} {
+ echo "**pre-verifying**"
+ if {[catch {eval verify_image $flash_args}] == 0} {
+ echo "**Verified OK - No flashing**"
+ set needsflash 0
+ }
+ }
+
+ # start programming phase
+ if {$needsflash == 1} {
+ echo "** Programming Started **"
+
+ if {[catch {eval flash write_image erase $flash_args}] == 0} {
+ echo "** Programming Finished **"
+ if {[info exists verify]} {
+ # verify phase
+ echo "** Verify Started **"
+ if {[catch {eval verify_image $flash_args}] == 0} {
+ echo "** Verified OK **"
+ } else {
+ program_error "** Verify Failed **" $exit
+ }
+ }
+ } else {
+ program_error "** Programming Failed **" $exit
+ }
+ }
+
+ if {[info exists reset]} {
+ # reset target if requested
+ if {$exit == 1} {
+ # also disable target polling, we are shutting down anyway
+ poll off
+ }
+ echo "** Resetting Target **"
+ reset run
+ }
+
+
+ if {$exit == 1} {
+ shutdown
+ }
+ return