OpenCores
URL https://opencores.org/ocsvn/openmsp430/openmsp430/trunk

Subversion Repositories openmsp430

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /openmsp430
    from Rev 157 to Rev 158
    Reverse comparison

Rev 157 → Rev 158

/trunk/tools/openmsp430-gdbproxy/commands.tcl
48,36 → 48,36
set cmd_tail [string range $rsp_cmd 1 [string length $rsp_cmd]]
 
switch -exact -- [string index $rsp_cmd 0] {
"!" {set rsp_answer "OK"}
"?" {set rsp_answer [rsp_stop_reply $sock "?"]}
"A" {}
"b" {}
"c" {set rsp_answer [rsp_c $sock $cmd_tail]}
"C" {set rsp_answer [rsp_c $sock $cmd_tail]}
"D" {}
"F" {}
"g" {set rsp_answer [rsp_g]}
"G" {set rsp_answer [rsp_G $cmd_tail]}
"H" {set rsp_answer ""}
"i" {}
"I" {}
"k" {set rsp_answer [rsp_k $cmd_tail]}
"m" {set rsp_answer [rsp_m $cmd_tail]}
"M" {set rsp_answer [rsp_M $cmd_tail]}
"p" {}
"P" {}
"q" {set rsp_answer [rsp_q $sock $cmd_tail]}
"Q" {}
"R" {}
"s" {set rsp_answer [rsp_s $sock $cmd_tail]}
"S" {set rsp_answer [rsp_s $sock $cmd_tail]}
"t" {}
"T" {}
"v" {}
"X" {}
"z" {set rsp_answer [rsp_z $sock $cmd_tail]}
"Z" {set rsp_answer [rsp_Z $sock $cmd_tail]}
default {}
"!" {set rsp_answer "OK"}
"?" {set rsp_answer [rsp_stop_reply $sock "?"]}
"A" {}
"b" {}
"c" {set rsp_answer [rsp_c $sock $cmd_tail]}
"C" {set rsp_answer [rsp_c $sock $cmd_tail]}
"D" {}
"F" {}
"g" {set rsp_answer [rsp_g]}
"G" {set rsp_answer [rsp_G $cmd_tail]}
"H" {set rsp_answer ""}
"i" {}
"I" {}
"k" {set rsp_answer [rsp_k $cmd_tail]}
"m" {set rsp_answer [rsp_m $cmd_tail]}
"M" {set rsp_answer [rsp_M $cmd_tail]}
"p" {}
"P" {}
"q" {set rsp_answer [rsp_q $sock $cmd_tail]}
"Q" {}
"R" {}
"s" {set rsp_answer [rsp_s $sock $cmd_tail]}
"S" {set rsp_answer [rsp_s $sock $cmd_tail]}
"t" {}
"T" {}
"v" {}
"X" {}
"z" {set rsp_answer [rsp_z $sock $cmd_tail]}
"Z" {set rsp_answer [rsp_Z $sock $cmd_tail]}
default {}
}
 
 
96,15 → 96,17
#-----------------------------------------------------------------------------#
proc rsp_g {} {
global CpuNr
 
# Read register value
set reg_val [ReadRegAll]
set reg_val [ReadRegAll $CpuNr]
 
# Format answer
set rsp_answer ""
for {set i 0} {$i < [llength $reg_val]} {incr i} {
 
regexp {0x(..)(..)} [lindex $reg_val $i] match msb lsb
append rsp_answer "$lsb$msb"
regexp {0x(..)(..)} [lindex $reg_val $i] match msb lsb
append rsp_answer "$lsb$msb"
}
 
return $rsp_answer
115,6 → 117,8
#-----------------------------------------------------------------------------#
proc rsp_G {cmd} {
global CpuNr
 
# Format register value
set num_reg [expr [string length $cmd]/4]
 
121,13 → 125,13
set reg_val ""
for {set i 0} {$i < $num_reg} {incr i} {
 
set lsb "[string index $cmd [expr $i*4+0]][string index $cmd [expr $i*4+1]]"
set msb "[string index $cmd [expr $i*4+2]][string index $cmd [expr $i*4+3]]"
lappend reg_val "0x$msb$lsb"
set lsb "[string index $cmd [expr $i*4+0]][string index $cmd [expr $i*4+1]]"
set msb "[string index $cmd [expr $i*4+2]][string index $cmd [expr $i*4+3]]"
lappend reg_val "0x$msb$lsb"
}
 
# Write registers
WriteRegAll $reg_val
WriteRegAll $CpuNr $reg_val
 
return "OK"
}
137,8 → 141,10
#-----------------------------------------------------------------------------#
proc rsp_k {cmd} {
global CpuNr
 
# Reset & Stop CPU
ExecutePOR_Halt
ExecutePOR_Halt $CpuNr
return "-1"
}
149,6 → 155,7
proc rsp_M {cmd} {
global mem_breakpoint
global CpuNr
# Parse command
regexp {(.*),(.*):(.*)} $cmd match addr length data
158,26 → 165,26
# Format data
set mem_val ""
for {set i 0} {$i<$length} {incr i} {
lappend mem_val "0x[string range $data [expr $i*2] [expr $i*2+1]]"
lappend mem_val "0x[string range $data [expr $i*2] [expr $i*2+1]]"
}
 
# Write memory
if {$length==2} {
regexp {(..)(..)} $data match data_lo data_hi
WriteMem 0 "0x$addr" "0x${data_hi}${data_lo}"
regexp {(..)(..)} $data match data_lo data_hi
WriteMem $CpuNr 0 "0x$addr" "0x${data_hi}${data_lo}"
} else {
WriteMemQuick8 "0x$addr" $mem_val
WriteMemQuick8 $CpuNr "0x$addr" $mem_val
}
 
# Eventually re-set the software breakpoints in case they have been overwritten
set addr_start [format %d "0x$addr"]
foreach {brk_addr brk_val} [array get mem_breakpoint] {
set brk_addr_dec [format %d "0x$brk_addr"]
set brk_addr_offset [expr $brk_addr_dec-$addr_start]
if {(0<=$brk_addr_offset) && ($brk_addr_offset<=$length)} {
set mem_breakpoint($brk_addr) [lindex $mem_val $brk_addr_offset]
WriteMem 0 "0x$brk_addr" 0x4343
}
set brk_addr_dec [format %d "0x$brk_addr"]
set brk_addr_offset [expr $brk_addr_dec-$addr_start]
if {(0<=$brk_addr_offset) && ($brk_addr_offset<=$length)} {
set mem_breakpoint($brk_addr) [lindex $mem_val $brk_addr_offset]
WriteMem $CpuNr 0 "0x$brk_addr" 0x4343
}
}
 
return "OK"
190,6 → 197,7
proc rsp_m {cmd} {
global mem_breakpoint
global CpuNr
 
# Parse command
regexp {(.*),(.*)} $cmd match addr length
197,17 → 205,17
set length [format %d "0x$length"]
 
# Read memory
set data [ReadMemQuick8 "0x$addr" $length]
set data [ReadMemQuick8 $CpuNr "0x$addr" $length]
 
# Eventually replace read data by the original software breakpoint value
set addr_start [format %d "0x$addr"]
foreach {brk_addr brk_val} [array get mem_breakpoint] {
set brk_addr_dec [format %d "0x$brk_addr"]
set brk_addr_offset [expr $brk_addr_dec-$addr_start]
if {(0<=$brk_addr_offset) && ($brk_addr_offset<=$length)} {
set data [lreplace $data $brk_addr_offset $brk_addr_offset "0x$mem_breakpoint($brk_addr)"]
}
set brk_addr_dec [format %d "0x$brk_addr"]
set brk_addr_offset [expr $brk_addr_dec-$addr_start]
if {(0<=$brk_addr_offset) && ($brk_addr_offset<=$length)} {
set data [lreplace $data $brk_addr_offset $brk_addr_offset "0x$mem_breakpoint($brk_addr)"]
}
}
 
# Format data
224,6 → 232,7
proc rsp_Z {sock cmd} {
 
global mem_breakpoint
global CpuNr
 
# Parse command
regexp {(.),(.*),(.*)} $cmd match type addr length
230,41 → 239,41
set addr [format %04x "0x$addr"]
 
switch -exact -- $type {
"0" {# Memory breakpoint
set mem_breakpoint($addr) [ReadMem 0 "0x$addr"]
WriteMem 0 "0x$addr" 0x4343
return "OK"
"0" {# Memory breakpoint
set mem_breakpoint($addr) [ReadMem $CpuNr 0 "0x$addr"]
WriteMem $CpuNr 0 "0x$addr" 0x4343
return "OK"
}
 
"1" {# Hardware breakpoint
if {[SetHWBreak 1 [format "0x%04x" 0x$addr] 1 0]} {
return "OK"
}
return ""
"1" {# Hardware breakpoint
if {[SetHWBreak $CpuNr 1 [format "0x%04x" 0x$addr] 1 0]} {
return "OK"
}
return ""
}
 
"2" {# Write watchpoint
if {[SetHWBreak 0 [format "0x%04x" 0x$addr] 0 1]} {
return "OK"
}
return ""
"2" {# Write watchpoint
if {[SetHWBreak $CpuNr 0 [format "0x%04x" 0x$addr] 0 1]} {
return "OK"
}
return ""
}
 
"3" {# Read watchpoint
if {[SetHWBreak 0 [format "0x%04x" 0x$addr] 1 0]} {
return "OK"
}
return ""
"3" {# Read watchpoint
if {[SetHWBreak $CpuNr 0 [format "0x%04x" 0x$addr] 1 0]} {
return "OK"
}
return ""
}
 
"4" {# Access watchpoint
if {[SetHWBreak 0 [format "0x%04x" 0x$addr] 1 1]} {
return "OK"
}
return ""
"4" {# Access watchpoint
if {[SetHWBreak $CpuNr 0 [format "0x%04x" 0x$addr] 1 1]} {
return "OK"
}
return ""
}
 
default {return ""}
default {return ""}
}
}
 
274,6 → 283,7
proc rsp_z {sock cmd} {
 
global mem_breakpoint
global CpuNr
 
# Parse command
regexp {(.),(.*),(.*)} $cmd match type addr length
280,41 → 290,41
set addr [format %04x "0x$addr"]
 
switch -exact -- $type {
"0" {# Memory breakpoint
WriteMem 0 "0x$addr" $mem_breakpoint($addr)
unset mem_breakpoint($addr)
return "OK"
"0" {# Memory breakpoint
WriteMem $CpuNr 0 "0x$addr" $mem_breakpoint($addr)
unset mem_breakpoint($addr)
return "OK"
}
 
"1" {# Hardware breakpoint
if {[ClearHWBreak 1 [format "0x%04x" 0x$addr]]} {
return "OK"
}
return ""
"1" {# Hardware breakpoint
if {[ClearHWBreak $CpuNr 1 [format "0x%04x" 0x$addr]]} {
return "OK"
}
return ""
}
 
"2" {# Write watchpoint
if {[ClearHWBreak 0 [format "0x%04x" 0x$addr]]} {
return "OK"
}
return ""
"2" {# Write watchpoint
if {[ClearHWBreak $CpuNr 0 [format "0x%04x" 0x$addr]]} {
return "OK"
}
return ""
}
 
"3" {# Read watchpoint
if {[ClearHWBreak 0 [format "0x%04x" 0x$addr]]} {
return "OK"
}
return ""
"3" {# Read watchpoint
if {[ClearHWBreak $CpuNr 0 [format "0x%04x" 0x$addr]]} {
return "OK"
}
return ""
}
 
"4" {# Access watchpoint
if {[ClearHWBreak 0 [format "0x%04x" 0x$addr]]} {
return "OK"
}
return ""
"4" {# Access watchpoint
if {[ClearHWBreak $CpuNr 0 [format "0x%04x" 0x$addr]]} {
return "OK"
}
return ""
}
 
default {return ""}
default {return ""}
}
}
 
323,17 → 333,19
#-----------------------------------------------------------------------------#
proc rsp_c {sock cmd} {
global CpuNr
 
# Set address if required
if {$cmd!=""} {
set cmd [format %04x "0x$cmd"]
SetPC "0x$cmd"
set cmd [format %04x "0x$cmd"]
SetPC $CpuNr "0x$cmd"
}
 
# Clear status
ClrStatus
ClrStatus $CpuNr
 
# Continue
ReleaseCPU
ReleaseCPU $CpuNr
 
 
return [rsp_stop_reply $sock "c"]
344,20 → 356,22
#-----------------------------------------------------------------------------#
proc rsp_s {sock cmd} {
global CpuNr
 
# Set address if required
if {$cmd!=""} {
set cmd [format %04x "0x$cmd"]
SetPC "0x$cmd"
set cmd [format %04x "0x$cmd"]
SetPC $CpuNr "0x$cmd"
}
 
# Clear status
ClrStatus
ClrStatus $CpuNr
 
# Read current PC value
set pc [ReadReg 0]
set pc [ReadReg $CpuNr 0]
 
# Incremental step
StepCPU
StepCPU $CpuNr
 
return [rsp_stop_reply $sock "s" $pc]
}
370,40 → 384,42
#-----------------------------------------------------------------------------#
proc rsp_stop_reply {sock cmd {opt_val "0"}} {
 
global CpuNr
 
# Wait until halted
while {![IsHalted]} {
while {![IsHalted $CpuNr]} {
 
# Wait a few milliseconds to prevent the gui from freezing
after 100 {set end 1}
vwait end
# Wait a few milliseconds to prevent the gui from freezing
after 100 {set end 1}
vwait end
 
# Check if we are interrupted by GDB
fconfigure $sock -blocking 0
set break_char [read -nonewline $sock]
fconfigure $sock -blocking 1
binary scan $break_char H* break_char
if {$break_char=="03"} {
putsVerbose "--> BREAK"
HaltCPU
}
# Check if we are interrupted by GDB
fconfigure $sock -blocking 0
set break_char [read -nonewline $sock]
fconfigure $sock -blocking 1
binary scan $break_char H* break_char
if {$break_char=="03"} {
putsVerbose "--> BREAK"
HaltCPU $CpuNr
}
}
 
# Read some important registers
set pc [ReadReg 0]
set pc [ReadReg $CpuNr 0]
regexp {0x(..)(..)} $pc match pc_hi pc_lo
set r4 [ReadReg 4]
set r4 [ReadReg $CpuNr 4]
regexp {0x(..)(..)} $r4 match r4_hi r4_lo
 
# In case of a single step command, make sure that the PC
# value changes. If not, return an error otherwise GDB will
# end-up in an infinite loop.
if {$cmd == "s"} {
if {$opt_val == $pc} {
return "E05"
}
}
#return "S05"
return "T0500:$pc_lo$pc_hi;04:$r4_lo$r4_hi;"
# In case of a single step command, make sure that the PC
# value changes. If not, return an error otherwise GDB will
# end-up in an infinite loop.
if {$cmd == "s"} {
if {$opt_val == $pc} {
return "E05"
}
}
#return "S05"
return "T0500:$pc_lo$pc_hi;04:$r4_lo$r4_hi;"
}
 
 
414,10 → 430,10
switch -regexp -- $cmd {
 
"C" {set rsp_answer ""}
"Offsets" {set rsp_answer "Text=0;Data=0;Bss=0"}
"Rcmd,.+" {set rsp_answer [rsp_qRcmd $sock $cmd]}
default {set rsp_answer ""}
"C" {set rsp_answer ""}
"Offsets" {set rsp_answer "Text=0;Data=0;Bss=0"}
"Rcmd,.+" {set rsp_answer [rsp_qRcmd $sock $cmd]}
default {set rsp_answer ""}
}
return $rsp_answer
}
433,20 → 449,22
#-----------------------------------------------------------------------------#
proc rsp_qRcmd {sock cmd} {
 
global CpuNr
 
regsub {^Rcmd,} $cmd {} cmd
set cmd [binary format H* $cmd]; # Convert hex to ascii
 
switch -exact -- $cmd {
"erase all" {;# Convert ascii to hex
binary scan "Erasing target program memory..." H* text1
binary scan " Erased OK\n" H* text2
;# Execute erase command
sendRSPpacket $sock "O$text1"
EraseROM
sendRSPpacket $sock "O$text2"
set rsp_answer "OK"
"erase all" {;# Convert ascii to hex
binary scan "Erasing target program memory..." H* text1
binary scan " Erased OK\n" H* text2
;# Execute erase command
sendRSPpacket $sock "O$text1"
EraseROM $CpuNr
sendRSPpacket $sock "O$text2"
set rsp_answer "OK"
}
default {set rsp_answer "OK"}
default {set rsp_answer "OK"}
}
 
return $rsp_answer
/trunk/tools/openmsp430-gdbproxy/server.tcl
48,38 → 48,40
 
global server
if {![info exists server(socket)]} {
putsLog "Open socket on port $server(port) ... " 1
if {[catch {socket -server clientAccept $server(port)} server(socket)]} {
putsLog "failed"
putsLog "ERROR: $server(socket)."
unset server(socket)
return 0
}
putsLog "done"
putsLog "INFO: Waiting on TCP port $server(port)"
putsLog "Open socket on port $server(port) ... " 1
if {[catch {socket -server clientAccept $server(port)} server(socket)]} {
putsLog "failed"
putsLog "ERROR: $server(socket)."
unset server(socket)
return 0
}
putsLog "done"
putsLog "INFO: Waiting on TCP port $server(port)"
} else {
putsLog "Server is already up."
putsLog "Server is already up."
}
return 1
}
 
proc stopServer { } {
global serial_status
global omsp_info
global server
global CpuNr
 
if {[info exists server(socket)]} {
set port [lindex [fconfigure $server(socket) -sockname] 2]
putsLog "Stop server (port $port)"
close $server(socket)
unset server(socket)
set port [lindex [fconfigure $server(socket) -sockname] 2]
putsLog "Stop server (port $port)"
close $server(socket)
unset server(socket)
}
if {$serial_status} {
ReleaseDevice 0xfffe
if {$omsp_info($CpuNr,connected)} {
ReleaseDevice $CpuNr 0xfffe
}
}
 
proc clientAccept {sock addr port} {
global clients
global CpuNr
 
putsLog "Accept client: $addr ($port)\n"
 
87,57 → 89,57
fconfigure $sock -buffering none
fileevent $sock readable [list receiveRSPpacket $sock]
 
InitBreakUnits
InitBreakUnits $CpuNr
}
 
proc startServerGUI { } {
global serial_device
global hw_break
global omsp_conf
global omsp_info
global CpuNr
 
# Connect to device
if {![GetDevice]} {
.info.cpu.con configure -text "Connection problem" -fg red
putsLog "ERROR: Could not open \"$serial_device\""
putsLog ""
putsLog " -------------------------------------------------------------"
putsLog " !!!! Please consider the following options: !!!!"
putsLog " !!!! !!!!"
putsLog " !!!! - check the physical connection to the board. !!!!"
putsLog " !!!! - adjust the serial connection baudrate. !!!!"
putsLog " !!!! - don't forget to reset the serial debug interface !!!!"
putsLog " !!!! between each attempt. !!!!"
putsLog " -------------------------------------------------------------"
putsLog ""
return 0
if {![GetDevice $CpuNr]} {
.info.cpu.con configure -text "Connection problem" -fg red
putsLog "ERROR: Could not open \"$omsp_conf(device)\""
putsLog ""
putsLog " -------------------------------------------------------------"
putsLog " !!!! Please consider the following options: !!!!"
putsLog " !!!! !!!!"
putsLog " !!!! - check the physical connection to the board. !!!!"
putsLog " !!!! - adjust the serial connection baudrate. !!!!"
putsLog " !!!! - don't forget to reset the serial debug interface !!!!"
putsLog " !!!! between each attempt. !!!!"
putsLog " -------------------------------------------------------------"
putsLog ""
return 0
}
 
if {$omsp_info(alias)==""} {
.info.cpu.con configure -text "Connected" -fg "\#00ae00"
if {$omsp_info($CpuNr,alias)==""} {
.info.cpu.con configure -text "Connected" -fg "\#00ae00"
} else {
.info.cpu.con configure -text "Connected to $omsp_info(alias)" -fg "\#00ae00"
.info.cpu.con configure -text "Connected to $omsp_info($CpuNr,alias)" -fg "\#00ae00"
}
 
# Display info
putsLog "INFO: Sucessfully connected with the openMSP430 target."
set sizes [GetCPU_ID_SIZE]
if {$omsp_info(asic)} {
putsLog "INFO: CPU Version - $omsp_info(cpu_ver) / ASIC"
set sizes [GetCPU_ID_SIZE $CpuNr]
if {$omsp_info($CpuNr,asic)} {
putsLog "INFO: CPU Version - $omsp_info($CpuNr,cpu_ver) / ASIC"
} else {
putsLog "INFO: CPU Version - $omsp_info(cpu_ver) / FPGA"
putsLog "INFO: CPU Version - $omsp_info($CpuNr,cpu_ver) / FPGA"
}
putsLog "INFO: User Version - $omsp_info(user_ver)"
if {$omsp_info(cpu_ver)==1} {
putsLog "INFO: Hardware Multiplier - --"
} elseif {$omsp_info(mpy)} {
putsLog "INFO: Hardware Multiplier - Yes"
putsLog "INFO: User Version - $omsp_info($CpuNr,user_ver)"
if {$omsp_info($CpuNr,cpu_ver)==1} {
putsLog "INFO: Hardware Multiplier - --"
} elseif {$omsp_info($CpuNr,mpy)} {
putsLog "INFO: Hardware Multiplier - Yes"
} else {
putsLog "INFO: Hardware Multiplier - No"
putsLog "INFO: Hardware Multiplier - No"
}
putsLog "INFO: Program Memory Size - $omsp_info(pmem_size) B"
putsLog "INFO: Data Memory Size - $omsp_info(dmem_size) B"
putsLog "INFO: Peripheral Address Space - $omsp_info(per_size) B"
putsLog "INFO: $hw_break(num) Hardware Break/Watch-point unit(s) detected"
putsLog "INFO: Program Memory Size - $omsp_info($CpuNr,pmem_size) B"
putsLog "INFO: Data Memory Size - $omsp_info($CpuNr,dmem_size) B"
putsLog "INFO: Peripheral Address Space - $omsp_info($CpuNr,per_size) B"
putsLog "INFO: $omsp_info($CpuNr,hw_break) Hardware Break/Watch-point unit(s) detected"
putsLog ""
 
# Activate Load TCL script section
150,20 → 152,29
.info.cpu.more configure -state normal
 
# Reset & Stop CPU
ExecutePOR_Halt
ExecutePOR_Halt $CpuNr
 
# Start server for GDB
if {![startServer]} {
.info.server.con configure -text "Connection problem" -fg red
return 0
.info.server.con configure -text "Connection problem" -fg red
return 0
}
.info.server.con configure -text "Running" -fg "\#00ae00"
 
# Disable gui entries
.connect.config.serial_port.p1 configure -state disabled
.connect.config.serial_baudrate.p2 configure -state disabled
.connect.config.server_port.p configure -state disabled
.connect.start.but configure -state disabled
.connect.cfg.if.config1.adapter.p1 configure -state disabled
.connect.cfg.if.config2.adapter.p2 configure -state disabled
.connect.cfg.if.config1.serial_port.p1 configure -state disabled
.connect.cfg.if.config2.serial_port.p2 configure -state disabled
.connect.cfg.ad.server_port.p0 configure -state disabled
.connect.cfg.ad.server_port.p1 configure -state disabled
.connect.cfg.ad.server_port.p2 configure -state disabled
.connect.cfg.ad.server_port.p3 configure -state disabled
.connect.cfg.ad.i2c_addr.s0 configure -state disabled
.connect.cfg.ad.i2c_addr.s1 configure -state disabled
.connect.cfg.ad.i2c_addr.s2 configure -state disabled
.connect.cfg.ad.i2c_addr.s3 configure -state disabled
.connect.cfg.ad.i2c_nr.s configure -state disabled
}
 
###############################################################################
174,6 → 185,8
 
proc receiveRSPpacket {sock} {
 
global CpuNr
 
# Get client info
set ip [lindex [fconfigure $sock -peername] 0]
set port [lindex [fconfigure $sock -peername] 2]
183,47 → 196,47
set rsp_cmd [getDebugChar $sock]
set rsp_sum ""
if {[string eq $rsp_cmd "\$"]} {
set rx_packet 1
set rsp_cmd ""
set rx_packet 1
set rsp_cmd ""
} else {
binary scan $rsp_cmd H* rsp_cmd
if {$rsp_cmd=="03"} {
putsVerbose "--> BREAK"
HaltCPU
}
binary scan $rsp_cmd H* rsp_cmd
if {$rsp_cmd=="03"} {
putsVerbose "--> BREAK"
HaltCPU $CpuNr
}
}
# Receive packet
while {$rx_packet} {
set char [getDebugChar $sock]
if {$char==-1} {
set rx_packet 0
} elseif {[string eq $char "\#"]} {
set rx_packet 0
set rsp_sum [getDebugChar $sock]
append rsp_sum [getDebugChar $sock]
set char [getDebugChar $sock]
if {$char==-1} {
set rx_packet 0
} elseif {[string eq $char "\#"]} {
set rx_packet 0
set rsp_sum [getDebugChar $sock]
append rsp_sum [getDebugChar $sock]
# Re-calculate the checksum
set tmp_sum [RSPcheckSum $rsp_cmd]
# Re-calculate the checksum
set tmp_sum [RSPcheckSum $rsp_cmd]
 
# Acknowledge and analyse the packet
if {[string eq $rsp_sum $tmp_sum]} {
putDebugChar $sock "+"
# Acknowledge and analyse the packet
if {[string eq $rsp_sum $tmp_sum]} {
putDebugChar $sock "+"
 
# Remove escape characters
set rsp_cmd [removeEscapeChar $rsp_cmd]
putsVerbose "+ w $rsp_cmd"
# Remove escape characters
set rsp_cmd [removeEscapeChar $rsp_cmd]
putsVerbose "+ w $rsp_cmd"
 
# Parse packet and send back the answer
set rsp_answer [rspParse $sock $rsp_cmd]
if {$rsp_answer != "-1"} {
sendRSPpacket $sock $rsp_answer
}
} else {
putDebugChar $sock "-"
}
} else {
append rsp_cmd $char
}
# Parse packet and send back the answer
set rsp_answer [rspParse $sock $rsp_cmd]
if {$rsp_answer != "-1"} {
sendRSPpacket $sock $rsp_answer
}
} else {
putDebugChar $sock "-"
}
} else {
append rsp_cmd $char
}
}
}
 
242,16 → 255,16
# Send the packet until the "+" aknowledge is received
set send_ok 0
while {!$send_ok} {
putDebugChar $sock "$rsp_packet"
set char [getDebugChar $sock]
putDebugChar $sock "$rsp_packet"
set char [getDebugChar $sock]
 
putsVerbose "$char r $rsp_cmd"
putsVerbose "$char r $rsp_cmd"
 
if {$char==-1} {
set send_ok 1
} elseif {[string eq $char "+"]} {
set send_ok 1
}
if {$char==-1} {
set send_ok 1
} elseif {[string eq $char "+"]} {
set send_ok 1
}
}
}
 
266,8 → 279,8
 
set rsp_sum 0
for {set i 0} {$i<[string length $rsp_cmd]} {incr i} {
scan [string index $rsp_cmd $i] "%c" char_val
set rsp_sum [expr $rsp_sum+$char_val]
scan [string index $rsp_cmd $i] "%c" char_val
set rsp_sum [expr $rsp_sum+$char_val]
}
set rsp_sum [format %02x [expr $rsp_sum%256]]
 
311,13 → 324,13
set port [lindex [fconfigure $sock -peername] 2]
 
if {[eof $sock] || [catch {set char [read $sock 1]}]} {
# end of file or abnormal connection drop
close $sock
putsLog "Connection closed: $ip ($port)\n"
unset clients(addr,$sock)
return -1
# end of file or abnormal connection drop
close $sock
putsLog "Connection closed: $ip ($port)\n"
unset clients(addr,$sock)
return -1
} else {
return $char
return $char
}
}
 
338,7 → 351,7
 
# Destroy windows if already existing
if {[lsearch -exact [winfo children .] .omsp_extra_info]!=-1} {
destroy .omsp_extra_info
destroy .omsp_extra_info
}
 
# Create master window
349,8 → 362,8
 
# Title
set title "openMSP430"
if {$omsp_info(alias)!=""} {
set title $omsp_info(alias)
if {$omsp_info($CpuNr,alias)!=""} {
set title $omsp_info($CpuNr,alias)
}
label .omsp_extra_info.title -text "$title" -anchor center -fg "\#00ae00" -font {-weight bold -size 16}
pack .omsp_extra_info.title -side top -padx {20 20} -pady {20 10}
371,45 → 384,45
# Fill the text widget will configuration info
.omsp_extra_info.extra.text tag configure bold -font {-family TkFixedFont -weight bold}
.omsp_extra_info.extra.text insert end "Configuration\n\n" bold
.omsp_extra_info.extra.text insert end [format "CPU Version : %5s\n" $omsp_info(cpu_ver)]
.omsp_extra_info.extra.text insert end [format "User Version : %5s\n" $omsp_info(user_ver)]
if {$omsp_info(cpu_ver)==1} {
.omsp_extra_info.extra.text insert end [format "CPU Version : %5s\n" $omsp_info($CpuNr,cpu_ver)]
.omsp_extra_info.extra.text insert end [format "User Version : %5s\n" $omsp_info($CpuNr,user_ver)]
if {$omsp_info($CpuNr,cpu_ver)==1} {
.omsp_extra_info.extra.text insert end [format "Implementation : %5s\n" --]
} elseif {$omsp_info(asic)==0} {
} elseif {$omsp_info($CpuNr,asic)==0} {
.omsp_extra_info.extra.text insert end [format "Implementation : %5s\n" FPGA]
} elseif {$omsp_info(asic)==1} {
} elseif {$omsp_info($CpuNr,asic)==1} {
.omsp_extra_info.extra.text insert end [format "Implementation : %5s\n" ASIC]
}
if {$omsp_info(mpy)==1} {
if {$omsp_info($CpuNr,mpy)==1} {
.omsp_extra_info.extra.text insert end [format "Hardware Multiplier support: %5s\n" Yes]
} elseif {$omsp_info(mpy)==0} {
} elseif {$omsp_info($CpuNr,mpy)==0} {
.omsp_extra_info.extra.text insert end [format "Hardware Multiplier support: %5s\n" No]
} else {
.omsp_extra_info.extra.text insert end [format "Hardware Multiplier support: %5s\n" --]
}
.omsp_extra_info.extra.text insert end [format "Program memory size : %5s B\n" $omsp_info(pmem_size)]
.omsp_extra_info.extra.text insert end [format "Data memory size : %5s B\n" $omsp_info(dmem_size)]
.omsp_extra_info.extra.text insert end [format "Peripheral address space : %5s B\n" $omsp_info(per_size)]
if {$omsp_info(alias)==""} {
.omsp_extra_info.extra.text insert end [format "Program memory size : %5s B\n" $omsp_info($CpuNr,pmem_size)]
.omsp_extra_info.extra.text insert end [format "Data memory size : %5s B\n" $omsp_info($CpuNr,dmem_size)]
.omsp_extra_info.extra.text insert end [format "Peripheral address space : %5s B\n" $omsp_info($CpuNr,per_size)]
if {$omsp_info($CpuNr,alias)==""} {
.omsp_extra_info.extra.text insert end [format "Alias : %5s\n\n\n" None]
} else {
.omsp_extra_info.extra.text insert end [format "Alias : %5s\n\n\n" $omsp_info(alias)]
.omsp_extra_info.extra.text insert end [format "Alias : %5s\n\n\n" $omsp_info($CpuNr,alias)]
}
 
.omsp_extra_info.extra.text insert end "Extra Info\n\n" bold
 
if {$omsp_info(alias)!=""} {
if {$omsp_info($CpuNr,alias)!=""} {
 
set aliasEXTRA [lsort -increasing [array names omsp_info -glob "extra,*"]]
if {[llength $aliasEXTRA]} {
set aliasEXTRA [lsort -increasing [array names omsp_info -glob "extra,*"]]
if {[llength $aliasEXTRA]} {
 
foreach currentEXTRA $aliasEXTRA {
regexp {^.+,.+,(.+)$} $currentEXTRA whole_match extraATTR
.omsp_extra_info.extra.text insert end [format "%-15s: %s\n" $extraATTR $omsp_info($currentEXTRA)]
}
.omsp_extra_info.extra.text insert end "\n\n"
}
foreach currentEXTRA $aliasEXTRA {
regexp {^.+,.+,(.+)$} $currentEXTRA whole_match extraATTR
.omsp_extra_info.extra.text insert end [format "%-15s: %s\n" $extraATTR $omsp_info($CpuNr,$currentEXTRA)]
}
.omsp_extra_info.extra.text insert end "\n\n"
}
} else {
.omsp_extra_info.extra.text insert end "No alias found in 'omsp_alias.xml' file"
.omsp_extra_info.extra.text insert end "No alias found in 'omsp_alias.xml' file"
}
}
/trunk/tools/lib/tcl-lib/dbg_uart.tcl File deleted \ No newline at end of file
trunk/tools/lib/tcl-lib/dbg_uart.tcl Property changes : Deleted: svn:eol-style ## -1 +0,0 ## -native \ No newline at end of property Deleted: svn:keywords ## -1 +0,0 ## -Date Revision Author \ No newline at end of property Index: trunk/tools/lib/tcl-lib/dbg_i2c_usb-iss.tcl =================================================================== --- trunk/tools/lib/tcl-lib/dbg_i2c_usb-iss.tcl (nonexistent) +++ trunk/tools/lib/tcl-lib/dbg_i2c_usb-iss.tcl (revision 158) @@ -0,0 +1,580 @@ +#---------------------------------------------------------------------------------- +# Copyright (C) 2001 Authors +# +# This source file may be used and distributed without restriction provided +# that this copyright statement is not removed from the file and that any +# derivative work contains the original copyright notice and the associated +# disclaimer. +# +# This source file is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. +# +# This source is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this source; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +#---------------------------------------------------------------------------------- +# +# File Name: dbg_uart_i2c-iss.tcl +# +# Author(s): +# - Olivier Girard, olgirard@gmail.com +# +#---------------------------------------------------------------------------------- +# $Rev: 133 $ +# $LastChangedBy: olivier.girard $ +# $LastChangedDate: 2012-03-22 21:28:26 +0100 (Thu, 22 Mar 2012) $ +#---------------------------------------------------------------------------------- +# +# Description: +# +# Some I2C utility functions for the openMSP430 serial debug interface +# using the USB-ISS adapter. +# +# Mandatory Public functions: +# +# - i2c_usb-iss::dbg_open (Device, OperatingMode) +# - i2c_usb-iss::dbg_connect (CpuAddr) +# - i2c_usb-iss::dbg_rd (CpuAddr, RegisterName) +# - i2c_usb-iss::dbg_wr (CpuAddr, RegisterName, Data) +# - i2c_usb-iss::dbg_burst_rx (CpuAddr, Format, Length) +# - i2c_usb-iss::dbg_burst_tx (CpuAddr, Format, DataList) +# - i2c_usb-iss::get_allowed_speeds () +# +# +# Private functions: +# +# - i2c_usb-iss::i2c_mode (OperatingMode) +# - i2c_usb-iss::dbg_format_cmd (RegisterName, Action) +# - i2c_usb-iss::ISS_VERSION () +# - i2c_usb-iss::GET_SER_NUM () +# - i2c_usb-iss::ISS_MODE (OperatingMode) +# - i2c_usb-iss::SETPINS (IO1, IO2, IO3, IO4) +# - i2c_usb-iss::GETPINS () +# +#---------------------------------------------------------------------------------- +namespace eval i2c_usb-iss { + + #=============================================================================# + # Source required libraries # + #=============================================================================# + + set scriptDir [file dirname [info script]] + source $scriptDir/dbg_utils.tcl + + + #=============================================================================# + # i2c_usb-iss::dbg_open (Device, Baudrate) # + #-----------------------------------------------------------------------------# + # Description: Open and configure the UART connection. # + # Attach and configure the USB-ISS adapter. # + # Arguments : Device - Serial port device (i.e. /dev/ttyS0 or COM2:) # + # OperatingMode - Name of the I2C operating mode. # + # Result : 0 if error, 1 otherwise. # + #=============================================================================# + proc dbg_open {Device OperatingMode} { + + # Open UART interface + if {![utils::uart_open $Device 0 115200]} { + return 0 + } + + # Check the ISS-VERSION command on the adapter + if {[lindex [ISS_VERSION] 0]=="0"} { + return 0 + } + + # Get operating mode value + set op_mode [i2c_mode $OperatingMode] + + # Configure the USB-ISS adaptor for I2C communication + # IO_MODE+I2C IO_TYPE + if {![ISS_MODE [list $op_mode 0x00]]} { + return 0 + } + + # Clear IO pins to make sure the Serial debug interface is under reset + SETPINS 0 0 0 0 + after 100 + + return 1 + } + + + #=============================================================================# + # i2c_usb-iss::dbg_connect (CpuAddr) # + #-----------------------------------------------------------------------------# + # Description: In case the serial debug interface enable signal is connected # + # to the I/O 1 or I/O 2 port, this function will enable it. # + # Arguments : CpuAddr - Unused argument. # + # Result : 0 if error, 1 otherwise. # + #=============================================================================# + proc dbg_connect {CpuAddr} { + + # Make sure the Serial debug interface is still under reset + SETPINS 0 0 0 0 + after 100 + + # Enable the Serial debug interface + SETPINS 1 1 1 1 + after 100 + + return 1 + } + + + #=============================================================================# + # i2c_usb-iss::dbg_rd (CpuAddr, RegisterName) # + #-----------------------------------------------------------------------------# + # Description: Read the specified debug register. # + # Arguments : CpuAddr - I2C address of the target CPU. # + # RegisterName - Name of the register to be read. # + # Result : Register content, in hexadecimal. # + #=============================================================================# + proc dbg_rd {CpuAddr RegisterName} { + + # Send command frame + set cmd [dbg_format_cmd $RegisterName RD] + + # Word or Byte register + set isByte [string eq [expr 0x40 & $cmd] 64] + + # Compute device frame (address+WR/RD) + set DeviceFrameWR [format "0x%02x" [expr $CpuAddr*2+0]] + set DeviceFrameRD [format "0x%02x" [expr $CpuAddr*2+1]] + + # Send command frame: I2C_DIRECT I2C_START I2C_WRITE2 DEVICE_ADDRESS+WR DATA STOP + utils::uart_tx [concat 0x57 0x01 0x31 $DeviceFrameWR $cmd 0x03] + + set response [utils::uart_rx 1 2] + if {[lindex $response 0] == 0x00} { + puts "I2C ERROR: $response" + return "0x" + } + + if {$isByte} { + # Read data: I2C_DIRECT I2C_START I2C_WRITE1 DEVICE_ADDRESS+RD NACK READ1 STOP + utils::uart_tx [concat 0x57 0x01 0x30 $DeviceFrameRD 0x04 0x20 0x03] + } else { + # Read data: I2C_DIRECT I2C_START I2C_WRITE1 DEVICE_ADDRESS+RD READ1 NACK READ1 STOP + utils::uart_tx [concat 0x57 0x01 0x30 $DeviceFrameRD 0x20 0x04 0x20 0x03] + } + set response [utils::uart_rx 1 2] + if {[lindex $response 0] == 0x00} { + puts "I2C ERROR: $response" + return "0x" + } + + # Compute size of data to be received + if {$isByte} { + set format 1 + set length 1 + } else { + set format 0 + set length 2 + } + + # Receive data + set rx_data [utils::uart_rx $format [expr $length]] + + return $rx_data + } + + #=============================================================================# + # i2c_usb-iss::dbg_wr (CpuAddr, RegisterName, Data) # + #-----------------------------------------------------------------------------# + # Description: Write to the specified debug register. # + # Arguments : CpuAddr - I2C address of the target CPU. # + # RegisterName - Name of the register to be written. # + # Data - Data to be written. # + # Result : 0 if error, 1 otherwise. # + #=============================================================================# + proc dbg_wr {CpuAddr RegisterName Data} { + + # Send command frame + set cmd [dbg_format_cmd $RegisterName WR] + + # Word or Byte register + set isByte [string eq [expr 0x40 & $cmd] 64] + + # Compute device frame (address+WR/RD) + set DeviceFrameWR [format "0x%02x" [expr $CpuAddr*2+0]] + set DeviceFrameRD [format "0x%02x" [expr $CpuAddr*2+1]] + + # Send command frame: I2C_DIRECT I2C_START I2C_WRITE2 DEVICE_ADDRESS+WR DATA STOP + utils::uart_tx [concat 0x57 0x01 0x31 $DeviceFrameWR $cmd 0x03] + + set response [utils::uart_rx 1 2] + if {[lindex $response 0] == 0x00} { + puts "I2C ERROR: $response" + return 0 + } + + # Format input data + if {![regexp {0x} $Data match]} { + set Data [format "0x%x" $Data] + } + set hex_val [format %04x $Data] + regexp {(..)(..)} $hex_val match hex_msb hex_lsb + + if {$isByte} { + # Read data: I2C_DIRECT I2C_START I2C_WRITE2 DEVICE_ADDRESS+WR DATA STOP + utils::uart_tx [concat 0x57 0x01 0x31 $DeviceFrameWR "0x$hex_lsb" 0x03] + } else { + # Read data: I2C_DIRECT I2C_START I2C_WRITE1 DEVICE_ADDRESS+WR DATA_LSB DATA_MSB STOP + utils::uart_tx [concat 0x57 0x01 0x32 $DeviceFrameWR "0x$hex_lsb" "0x$hex_msb" 0x03] + } + set response [utils::uart_rx 1 2] + if {[lindex $response 0] == 0x00} { + puts "I2C ERROR: $response" + return 0 + } + + return 1 + } + + #=============================================================================# + # i2c_usb-iss::dbg_burst_rx (CpuAddr, Format, Length) # + #-----------------------------------------------------------------------------# + # Description: Receive data list as burst from the serial debug interface. # + # Arguments : CpuAddr - I2C address of the target CPU. # + # Format - 0 format as 16 bit word, 1 format as 8 bit word. # + # Length - Number of byte to be received. # + # Result : 0 if error, 1 otherwise. # + #=============================================================================# + proc dbg_burst_rx {CpuAddr Format Length} { + + # Compute device frame (address+WR/RD) + set DeviceFrameWR [format "0x%02x" [expr $CpuAddr*2+0]] + set DeviceFrameRD [format "0x%02x" [expr $CpuAddr*2+1]] + + set rx_data "" + while { $Length > 0 } { + + # Maximum frame length is 16 bytes + if {$Length >= 16} {set rxLength 16 + } else {set rxLength $Length} + + # Compute I2C read command + set readCmd [format "0x%x" [expr $rxLength + 0x1f - 1]] + + if {$readCmd == "0x1f"} { + # Read data: I2C_DIRECT I2C_START I2C_WRITE1 DEVICE_ADDRESS+RD NACK READ1 STOP + utils::uart_tx [concat 0x57 0x01 0x30 $DeviceFrameRD 0x04 0x20 0x03] + } else { + # Read data: I2C_DIRECT I2C_START I2C_WRITE1 DEVICE_ADDRESS+RD READxx NACK READ1 STOP + utils::uart_tx [concat 0x57 0x01 0x30 $DeviceFrameRD $readCmd 0x04 0x20 0x03] + } + + set response [utils::uart_rx 1 2] + if {[lindex $response 0] == 0x00} { + puts "I2C ERROR: $response" + return 0 + } + + # Receive data + set rx_data [concat $rx_data [utils::uart_rx $Format [expr $rxLength]]] + + # Remaining bytes to be received + set Length [expr $Length - $rxLength] + } + + return $rx_data + } + + + #=============================================================================# + # i2c_usb-iss::dbg_burst_tx (CpuAddr, Format, DataList) # + #-----------------------------------------------------------------------------# + # Description: Transmit data list as burst to the serial debug interface. # + # Arguments : CpuAddr - I2C address of the target CPU. # + # Format - 0 format as 16 bit word, 1 format as 8 bit word. # + # DataList - List of data to be written (in hexadecimal). # + # Result : 0 if error, 1 otherwise. # + #=============================================================================# + proc dbg_burst_tx {CpuAddr Format DataList} { + + # Compute device frame (address+WR/RD) + set DeviceFrameWR [format "0x%02x" [expr $CpuAddr*2+0]] + set DeviceFrameRD [format "0x%02x" [expr $CpuAddr*2+1]] + + #---------------------------------------- + # Format the list of bytes to be sent + #---------------------------------------- + set tx_data "" + foreach data [split $DataList] { + + if {$Format==1} { #### 8-bit data format #### + # Format data + set data [format %02x $data] + + # Add data to list + set tx_data [concat $tx_data "0x$data"] + + } else { #### 16-bit data format #### + # Format data + set data [format %04x $data] + regexp {(..)(..)} $data match data_msb data_lsb + + # Add data to list + set tx_data [concat $tx_data "0x$data_lsb 0x$data_msb"] + } + } + + #---------------------------------------- + # Send the list of bytes over I2C + #---------------------------------------- + set Length [llength $tx_data] + + while { $Length > 0 } { + + # Maximum frame length is 16 bytes + if {$Length >= 16} {set txLength 16 + } else {set txLength $Length} + + # Compute I2C write command + set writeCmd [format "0x%x" [expr $txLength + 0x2f]] + + # Get the data from the list and remove it from there + set hex_data [lrange $tx_data 0 [expr $txLength-1]] + set tx_data [lreplace $tx_data 0 [expr $txLength-1]] + + # Read data: I2C_DIRECT I2C_START I2C_WRITE1 DEVICE_ADDRESS+WR WRITExx DATA STOP + utils::uart_tx [concat 0x57 0x01 0x30 $DeviceFrameWR $writeCmd $hex_data 0x03] + + set response [utils::uart_rx 1 2] + if {[lindex $response 0] == 0x00} { + puts "I2C ERROR: $response" + return 0 + } + + # Remaining bytes to be received + set Length [expr $Length - $txLength] + } + + } + + #=============================================================================# + # i2c_usb-iss::get_allowed_speeds () # + #-----------------------------------------------------------------------------# + # Description: Return the list of allowed I2C configuration modes. # + #=============================================================================# + proc get_allowed_speeds {} { + + # Not-Editable Default I2C-Operating-Modes + return [list 0 I2C_S_100KHZ [list I2C_S_20KHZ \ + I2C_S_50KHZ \ + I2C_S_100KHZ \ + I2C_S_400KHZ \ + I2C_H_100KHZ \ + I2C_H_400KHZ \ + I2C_H_1000KHZ] ] + } + +################################################################################################### +################################################################################################### +################################################################################################### +################################################################################################### +####### ####### +####### PRIVATE FUNCTIONS ####### +####### ####### +################################################################################################### +################################################################################################### +################################################################################################### +################################################################################################### + + #=============================================================================# + # i2c_usb-iss::i2c_mode (OperatingMode) # + #-----------------------------------------------------------------------------# + # Description: Get the correcponding hexadecimal value for a given I2C mode. # + # Arguments : OperatingMode - Name of the I2C operating mode. # + # Result : Command to be sent via UART. # + #=============================================================================# + proc i2c_mode {OperatingMode} { + + switch -exact $OperatingMode { + I2C_S_20KHZ {set op_mode "0x20"} + I2C_S_50KHZ {set op_mode "0x30"} + I2C_S_100KHZ {set op_mode "0x40"} + I2C_S_400KHZ {set op_mode "0x50"} + I2C_H_100KHZ {set op_mode "0x60"} + I2C_H_400KHZ {set op_mode "0x70"} + I2C_H_1000KHZ {set op_mode "0x80"} + default {set op_mode "0x40"} + } + + return $op_mode + } + + #=============================================================================# + # i2c_usb-iss::dbg_format_cmd (RegisterName, Action) # + #-----------------------------------------------------------------------------# + # Description: Get the correcponding UART command to a given debug register # + # access. # + # Arguments : RegisterName - Name of the register to be accessed. # + # Action - RD for read / WR for write. # + # Result : Command to be sent via UART. # + #=============================================================================# + proc dbg_format_cmd {RegisterName Action} { + + switch -exact $Action { + RD {set rd_wr "0x00"} + WR {set rd_wr "0x080"} + default {set rd_wr "0x00"} + } + + switch -exact $RegisterName { + CPU_ID_LO {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x00 | 0x00]]} + CPU_ID_HI {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x00 | 0x01]]} + CPU_CTL {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x40 | 0x02]]} + CPU_STAT {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x40 | 0x03]]} + MEM_CTL {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x40 | 0x04]]} + MEM_ADDR {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x00 | 0x05]]} + MEM_DATA {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x00 | 0x06]]} + MEM_CNT {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x00 | 0x07]]} + BRK0_CTL {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x40 | 0x08]]} + BRK0_STAT {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x40 | 0x09]]} + BRK0_ADDR0 {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x00 | 0x0A]]} + BRK0_ADDR1 {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x00 | 0x0B]]} + BRK1_CTL {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x40 | 0x0C]]} + BRK1_STAT {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x40 | 0x0D]]} + BRK1_ADDR0 {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x00 | 0x0E]]} + BRK1_ADDR1 {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x00 | 0x0F]]} + BRK2_CTL {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x40 | 0x10]]} + BRK2_STAT {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x40 | 0x11]]} + BRK2_ADDR0 {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x00 | 0x12]]} + BRK2_ADDR1 {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x00 | 0x13]]} + BRK3_CTL {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x40 | 0x14]]} + BRK3_STAT {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x40 | 0x15]]} + BRK3_ADDR0 {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x00 | 0x16]]} + BRK3_ADDR1 {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x00 | 0x17]]} + CPU_NR {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x00 | 0x18]]} + default {set uart_cmd "0x00"} + } + + return $uart_cmd + } + + + #=============================================================================# + # i2c_usb-iss::ISS_VERSION () # + #-----------------------------------------------------------------------------# + # Description: Will return three bytes. # + # The first is the Module ID, this will always be 7. # + # The second byte is the firmware revision number. # + # The third byte is the current operating mode. # + #=============================================================================# + proc ISS_VERSION {} { + + # Send ISS-VERSION command to the adapter + utils::uart_tx [list 0x5A 0x01] + + # Make sure 3 bytes are then received (the first one must be 0x07) + set iss_version [utils::uart_rx 1 3] + if {([lindex $iss_version 0] != "0x07") | + ([lindex $iss_version 1] == "0x") | + ([lindex $iss_version 2] == "0x")} { + return [list 0 0 0] + } + return $iss_version + } + + #=============================================================================# + # i2c_usb-iss::GET_SER_NUM () # + #-----------------------------------------------------------------------------# + # Description: Will return the modules unique 8 byte USB serial number. # + #=============================================================================# + proc GET_SER_NUM {} { + + # Send GET_SER_NUM command to the adapter + utils::uart_tx [list 0x5A 0x03] + + # Get the 8 bytes + set serial_number [utils::uart_rx 1 8] + + return $serial_number + } + + #=============================================================================# + # i2c_usb-iss::ISS_MODE (OperatingMode) # + #-----------------------------------------------------------------------------# + # Description: Sets the operating mode. # + # This sets up the modules I/O pins and hardware for the # + # required mode. # + # There are 4 operating modes (I2C, SPI, Serial and I/O) some # + # which can be combined. # + # See online documentation for more info: # + # http://www.robot-electronics.co.uk/htm/usb_iss_tech.htm # + #=============================================================================# + proc ISS_MODE {OperatingMode} { + + + # Send the ISS_MODE command: + # ISS_CMD ISS_MODE OPERATION_MODE+REMAINING + utils::uart_tx [concat [list 0x5A 0x02 ] $OperatingMode ] + + # Get the 2 byte response + set config_response [utils::uart_rx 1 2] + if {$config_response != [list 0xff 0x00]} { + return 0 + } + return 1 + } + + #=============================================================================# + # i2c_usb-iss::SETPINS (IO1, IO2, IO3, IO4) # + #-----------------------------------------------------------------------------# + # Description: The SETPINS command only operates on pins that have been set # + # as output pins. # + # Digital or analogue input pins, or pins that are used for I2C # + # or serial are not affected. # + #=============================================================================# + proc SETPINS {IO1 IO2 IO3 IO4} { + + # Get the hex value for IO configuration + set io_config [format "0x0%x" [expr $IO1+($IO2*2)+($IO3*4)+($IO4*8)]] + + # Send the SETPINS command to the adaptor + utils::uart_tx [list 0x63 $io_config] + + # Get the 1 byte response + set config_response [utils::uart_rx 1 1] + if {$config_response != "0xff"} { + return 0 + } + return 1 + } + + #=============================================================================# + # i2c_usb-iss::GETPINS () # + #-----------------------------------------------------------------------------# + # Description: This is used to get the current state of all digital I/O pins # + #=============================================================================# + proc GETPINS {} { + + # Send the GETPINS command to the adaptor + utils::uart_tx 0x64 + + # Get the 1 byte response + set config_response [utils::uart_rx 1 1] + if {$config_response == "0x"} { + return 0 + } + + # Get the hex value for IO configuration + set IO4 [expr ($config_response & 0x08)/8] + set IO3 [expr ($config_response & 0x04)/4] + set IO2 [expr ($config_response & 0x02)/2] + set IO1 [expr ($config_response & 0x01)/1] + + return [list $IO1 $IO2 $IO3 $IO4] + } + +}
trunk/tools/lib/tcl-lib/dbg_i2c_usb-iss.tcl Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: trunk/tools/lib/tcl-lib/dbg_uart_generic.tcl =================================================================== --- trunk/tools/lib/tcl-lib/dbg_uart_generic.tcl (nonexistent) +++ trunk/tools/lib/tcl-lib/dbg_uart_generic.tcl (revision 158) @@ -0,0 +1,304 @@ +#---------------------------------------------------------------------------------- +# Copyright (C) 2001 Authors +# +# This source file may be used and distributed without restriction provided +# that this copyright statement is not removed from the file and that any +# derivative work contains the original copyright notice and the associated +# disclaimer. +# +# This source file is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as published +# by the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. +# +# This source is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +# License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this source; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# +#---------------------------------------------------------------------------------- +# +# File Name: dbg_uart_generic.tcl +# +# Author(s): +# - Olivier Girard, olgirard@gmail.com +# +#---------------------------------------------------------------------------------- +# $Rev$ +# $LastChangedBy$ +# $LastChangedDate$ +#---------------------------------------------------------------------------------- +# +# Description: +# +# Generic UART utility functions for the openMSP430 serial debug interface. +# +# Mandatory Public functions: +# +# - uart_generic::dbg_open (Device, Baudrate) +# - uart_generic::dbg_connect (CpuAddr) +# - uart_generic::dbg_rd (CpuAddr, RegisterName) +# - uart_generic::dbg_wr (CpuAddr, RegisterName, Data) +# - uart_generic::dbg_burst_rx (CpuAddr, Format, Length) +# - uart_generic::dbg_burst_tx (CpuAddr, Format, DataList) +# - uart_generic::get_allowed_speeds () +# +# +# Private functions: +# +# - uart::dbg_format_cmd (RegisterName, Action) +# +#---------------------------------------------------------------------------------- +namespace eval uart_generic { + + #=============================================================================# + # Source required libraries # + #=============================================================================# + + set scriptDir [file dirname [info script]] + source $scriptDir/dbg_utils.tcl + + + #=============================================================================# + # uart_generic::dbg_open (Device, Baudrate) # + #-----------------------------------------------------------------------------# + # Description: Open and configure the UART connection. # + # Arguments : Device - Serial port device (i.e. /dev/ttyS0 or COM2:) # + # Baudrate - UART communication speed. # + # Result : 0 if error, 1 otherwise. # + #=============================================================================# + proc dbg_open {Device Baudrate} { + + # Open UART interface + if {![utils::uart_open $Device 1 $Baudrate]} { + return 0 + } + + return 1 + } + + + #=============================================================================# + # uart_generic::dbg_connect (CpuAddr) # + #-----------------------------------------------------------------------------# + # Description: Send the synchronization frame in order to connect with the # + # openMSP430 core. # + # Arguments : CpuAddr - Unused argument for the UART interface (I2C only). # + # Result : 0 if error, 1 otherwise. # + #=============================================================================# + proc dbg_connect {CpuAddr} { + + # Send synchronisation frame + utils::uart_tx {0x80} + after 100 + + # Send dummy frame in case the debug interface is already synchronized + utils::uart_tx {0xC0} + utils::uart_tx {0x00} + + return 1 + } + + + #=============================================================================# + # uart_generic::dbg_rd (CpuAddr, RegisterName) # + #-----------------------------------------------------------------------------# + # Description: Read the specified debug register. # + # Arguments : CpuAddr - Unused for the UART interface (I2C only). # + # RegisterName - Name of the register to be read. # + # Result : Register content, in hexadecimal. # + #=============================================================================# + proc dbg_rd {CpuAddr RegisterName} { + + # Send command frame + set cmd [dbg_format_cmd $RegisterName RD] + utils::uart_tx $cmd + + # Compute size of data to be received + if [string eq [expr 0x40 & $cmd] 64] { + set format 1 + set length 1 + } else { + set format 0 + set length 2 + } + + # Receive data + set rx_data [utils::uart_rx $format $length] + + return $rx_data + } + + #=============================================================================# + # uart_generic::dbg_wr (CpuAddr, RegisterName, Data) # + #-----------------------------------------------------------------------------# + # Description: Write to the specified debug register. # + # Arguments : CpuAddr - Unused for the UART interface (I2C only). # + # RegisterName - Name of the register to be written. # + # Data - Data to be written. # + # Result : 0 if error, 1 otherwise. # + #=============================================================================# + proc dbg_wr {CpuAddr RegisterName Data} { + + # Send command frame + set cmd [dbg_format_cmd $RegisterName WR] + utils::uart_tx $cmd + + # Format input data + if {![regexp {0x} $Data match]} { + set Data [format "0x%x" $Data] + } + set hex_val [format %04x $Data] + regexp {(..)(..)} $hex_val match hex_msb hex_lsb + + # Compute size of data to be sent + if [string eq [expr 0x40 & $cmd] 64] { + set size 1 + } else { + set size 2 + } + + # Send data + utils::uart_tx "0x$hex_lsb" + if {$size==2} { + utils::uart_tx "0x$hex_msb" + } + + return 1 + } + + #=============================================================================# + # uart_generic::dbg_burst_rx (CpuAddr, Format, Length) # + #-----------------------------------------------------------------------------# + # Description: Receive data list as burst from the serial debug interface. # + # Arguments : CpuAddr - Unused for the UART interface (I2C only). # + # Format - 0 format as 16 bit word, 1 format as 8 bit word. # + # Length - Number of byte to be received. # + # Result : 0 if error, 1 otherwise. # + #=============================================================================# + proc dbg_burst_rx {CpuAddr Format Length} { + + return [utils::uart_rx $Format $Length] + + } + + #=============================================================================# + # uart_generic::dbg_burst_tx (CpuAddr, Format, DataList) # + #-----------------------------------------------------------------------------# + # Description: Transmit data list as burst to the serial debug interface. # + # Arguments : CpuAddr - Unused for the UART interface (I2C only). # + # Format - 0 format as 16 bit word, 1 format as 8 bit word. # + # DataList - List of data to be written (in hexadecimal). # + # Result : 0 if error, 1 otherwise. # + #=============================================================================# + proc dbg_burst_tx {CpuAddr Format DataList} { + + foreach data [split $DataList] { + + if {$Format==1} { #### 8-bit data format #### + # Format data + set data [format %02x $data] + + # Send data + utils::uart_tx "0x$data" + + } else { #### 16-bit data format #### + # Format data + set data [format %04x $data] + regexp {(..)(..)} $data match data_msb data_lsb + + # Send data + utils::uart_tx "0x$data_lsb 0x$data_msb" + } + } + } + + #=============================================================================# + # uart_generic::get_allowed_speeds () # + #-----------------------------------------------------------------------------# + # Description: Return the list of allowed UART baudrates. # + #=============================================================================# + proc get_allowed_speeds {} { + + # Editable Default UART-Baudrates + return [list 1 115200 [list 9600 \ + 19200 \ + 38400 \ + 57600 \ + 115200 \ + 230400 \ + 460800 \ + 500000 \ + 576000 \ + 921600 \ + 1000000 \ + 1152000 \ + 2000000] ] + } + +################################################################################################### +################################################################################################### +################################################################################################### +################################################################################################### +####### ####### +####### PRIVATE FUNCTIONS ####### +####### ####### +################################################################################################### +################################################################################################### +################################################################################################### +################################################################################################### + + #=============================================================================# + # uart_generic::dbg_format_cmd (RegisterName, Action) # + #-----------------------------------------------------------------------------# + # Description: Get the correcponding UART command to a given debug register # + # access. # + # Arguments : RegisterName - Name of the register to be accessed. # + # Action - RD for read / WR for write. # + # Result : Command to be sent via UART. # + #=============================================================================# + proc dbg_format_cmd {RegisterName Action} { + + switch -exact $Action { + RD {set rd_wr "0x00"} + WR {set rd_wr "0x080"} + default {set rd_wr "0x00"} + } + + switch -exact $RegisterName { + CPU_ID_LO {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x00 | 0x00]]} + CPU_ID_HI {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x00 | 0x01]]} + CPU_CTL {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x40 | 0x02]]} + CPU_STAT {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x40 | 0x03]]} + MEM_CTL {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x40 | 0x04]]} + MEM_ADDR {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x00 | 0x05]]} + MEM_DATA {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x00 | 0x06]]} + MEM_CNT {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x00 | 0x07]]} + BRK0_CTL {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x40 | 0x08]]} + BRK0_STAT {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x40 | 0x09]]} + BRK0_ADDR0 {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x00 | 0x0A]]} + BRK0_ADDR1 {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x00 | 0x0B]]} + BRK1_CTL {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x40 | 0x0C]]} + BRK1_STAT {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x40 | 0x0D]]} + BRK1_ADDR0 {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x00 | 0x0E]]} + BRK1_ADDR1 {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x00 | 0x0F]]} + BRK2_CTL {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x40 | 0x10]]} + BRK2_STAT {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x40 | 0x11]]} + BRK2_ADDR0 {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x00 | 0x12]]} + BRK2_ADDR1 {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x00 | 0x13]]} + BRK3_CTL {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x40 | 0x14]]} + BRK3_STAT {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x40 | 0x15]]} + BRK3_ADDR0 {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x00 | 0x16]]} + BRK3_ADDR1 {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x00 | 0x17]]} + CPU_NR {set uart_cmd [format "0x%02x" [expr $rd_wr | 0x00 | 0x18]]} + default {set uart_cmd "0x00"} + } + + return $uart_cmd + } + +}
trunk/tools/lib/tcl-lib/dbg_uart_generic.tcl Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Date Revision Author \ No newline at end of property Index: trunk/tools/lib/tcl-lib/dbg_functions.tcl =================================================================== --- trunk/tools/lib/tcl-lib/dbg_functions.tcl (revision 157) +++ trunk/tools/lib/tcl-lib/dbg_functions.tcl (revision 158) @@ -1,4 +1,4 @@ -#------------------------------------------------------------------------------ +#----------------------------------------------------------------------------------------------------------- # Copyright (C) 2001 Authors # # This source file may be used and distributed without restriction provided @@ -20,7 +20,7 @@ # along with this source; if not, write to the Free Software Foundation, # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # -#------------------------------------------------------------------------------ +#----------------------------------------------------------------------------------------------------------- # # File Name: dbg_functions.tcl # @@ -27,11 +27,11 @@ # Author(s): # - Olivier Girard, olgirard@gmail.com # -#------------------------------------------------------------------------------ +#----------------------------------------------------------------------------------------------------------- # $Rev$ # $LastChangedBy$ # $LastChangedDate$ -#------------------------------------------------------------------------------ +#----------------------------------------------------------------------------------------------------------- # # Description: Main utility functions for the openMSP430 serial debug # interface. @@ -40,253 +40,360 @@ # application report from TI (Programming a Flash-Based MSP430 Using the # JTAG Interface): # -# - ExecutePOR () -# - SetPC (Addr) -# - HaltCPU () -# - ReleaseCPU () -# - GetDevice () -# - ReleaseDevice (Addr) -# - WriteMem (Format, Addr, Data) -# - WriteMemQuick (StartAddr, DataArray) -# - ReadMem (Format, Addr) -# - ReadMemQuick (StartAddr, Length) -# - VerifyMem (StartAddr, DataArray) +# - GetDevice (CpuNr) +# - ReleaseDevice (CpuNr, Addr) +# - ExecutePOR (CpuNr) +# - SetPC (CpuNr, Addr) +# - HaltCPU (CpuNr) +# - ReleaseCPU (CpuNr) +# - WriteMem (CpuNr, Format, Addr, Data) +# - WriteMemQuick (CpuNr, StartAddr, DataList) +# - ReadMem (CpuNr, Format, Addr) +# - ReadMemQuick (CpuNr, StartAddr, Length) +# - VerifyMem (CpuNr, StartAddr, DataList) # # # The following have been added: # -# - ExecutePOR_Halt () -# - GetCPU_ID () -# - GetCPU_ID_SIZE () -# - VerifyCPU_ID () -# - WriteReg (Addr, Data) -# - WriteRegAll (DataArray) -# - ReadReg (Addr) -# - ReadRegAll () -# - WriteMemQuick8 (StartAddr, DataArray) -# - ReadMemQuick8 (StartAddr, Length) -# - StepCPU () -# - EraseRAM () -# - EraseROM () -# - InitBreakUnits () -# - SetHWBreak (Type, Addr, Rd, Wr) -# - ClearHWBreak (Type, Addr) -# - IsHalted () -# - ClrStatus () -# - GetChipAlias () +# - ExecutePOR_Halt (CpuNr) +# - GetCPU_ID (CpuNr) +# - GetCPU_ID_SIZE (CpuNr) +# - VerifyCPU_ID (CpuNr) +# - WriteReg (CpuNr, Addr, Data) +# - WriteRegAll (CpuNr, DataList) +# - ReadReg (CpuNr, Addr) +# - ReadRegAll (CpuNr) +# - WriteMemQuick8 (CpuNr, StartAddr, DataList) +# - ReadMemQuick8 (CpuNr, StartAddr, Length) +# - StepCPU (CpuNr) +# - EraseRAM (CpuNr) +# - EraseROM (CpuNr) +# - InitBreakUnits (CpuNr) +# - SetHWBreak (CpuNr, Type, Addr, Rd, Wr) +# - ClearHWBreak (CpuNr, Type, Addr) +# - IsHalted (CpuNr) +# - ClrStatus (CpuNr) +# - GetChipAlias (CpuNr) +# - GetAllowedSpeeds() # -#------------------------------------------------------------------------------ +#----------------------------------------------------------------------------------------------------------- -# GLOBAL VARIABLES -global hw_break +#==========================================================================================================# +# GLOBAL VARIABLES: OMSP_CONF +#----------------------------------------------------------------------------------------------------------- +# +# The global conifugration array variable is meant to be initialized by the higher level +# programs prior the "GetDevice" call. +# +# omsp_conf(interface) -> Debug interface type: "uart" or "i2c_usb-iss" +# omsp_conf(device) -> Serial port device (i.e. /dev/ttyS0 or COM2:) +# omsp_conf(baudrate) -> UART communication speed +# omsp_conf(,cpuaddr) -> Address of the core (i.e. I2C device address) +# +#==========================================================================================================# +global omsp_conf + +# Initialize to default values +set omsp_conf(interface) uart_generic +set omsp_conf(device) /dev/ttyUSB0 +set omsp_conf(baudrate) 9600 +for {set i 0} {$i<128} {incr i} { + set omsp_conf($i,cpuaddr) 0 +} + + +#==========================================================================================================# +# GLOBAL VARIABLES: OMSP_INFO +#----------------------------------------------------------------------------------------------------------- +# +# This array variable is updated by the "GetDevice" procedure when the connection is built +# with the oMSP core. +# The array is structured as following: +# +# omsp_info(connected) -> Main Physical connection is active +# omsp_info(,connected) -> Connection to CPU is active +# omsp_info(,hw_break) -> Number of hardware breakpoints +# omsp_info(,cpu_ver) -> From CPU_ID : CPU Version +# omsp_info(,user_ver) -> From CPU_ID : User version +# omsp_info(,per_size) -> From CPU_ID : Peripheral address size +# omsp_info(,dmem_size) -> From CPU_ID : Data memory size +# omsp_info(,pmem_size) -> From CPU_ID : Program memory size +# omsp_info(,mpy) -> From CPU_ID : Hardware multiplier +# omsp_info(,asic) -> From CPU_ID : ASIC/FPGA version +# omsp_info(,inst_nr) -> From CPU_NR : current oMSP instance number +# omsp_info(,total_nr) -> From CPU_NR : totalnumber of oMSP instances-1 +# omsp_info(,alias) -> From XML File: Alias name +# omsp_info(,extra,0,Description) -> From XML File: Optional Description +# omsp_info(,extra,1,Contact) -> From XML File: Contact person +# omsp_info(,extra,2,Email) -> From XML File: Email of contact person +# omsp_info(,extra,3,URL) -> From XML File: URL of the project +# omsp_info(,extra,4,per_size) -> From XML File: Custom Peripheral address size +# omsp_info(,extra,5,dmem_size) -> From XML File: Custom Data memory size +# omsp_info(,extra,6,pmem_size) -> From XML File: Custom Program memory size +# omsp_info(,extra,?,????) -> From XML File: ... any extra stuff +# +#==========================================================================================================# global omsp_info + +# Initialize connection status set omsp_info(connected) 0 +# Support up to 128 multicore implementations +for {set i 0} {$i<128} {incr i} { + set omsp_info($i,connected) 0 +} + + +#==========================================================================================================# # SOURCE REQUIRED LIBRARIES +#==========================================================================================================# + set scriptDir [file dirname [info script]] -source $scriptDir/dbg_uart.tcl source $scriptDir/xml.tcl +source $scriptDir/dbg_uart_generic.tcl +source $scriptDir/dbg_uart_usb-iss.tcl +source $scriptDir/dbg_i2c_usb-iss.tcl +#==========================================================================================================# +# DEBUG PROCEDURES +#==========================================================================================================# + #=============================================================================# -# ExecutePOR () # +# GetDevice (CpuNr) # #-----------------------------------------------------------------------------# +# Description: Takes the target MSP430 device under UART/I2C control. # +# Enable the auto-freeze feature of timers when in the CPU is # +# stopped. This prevents an automatic watchdog reset condition. # +# Enables software breakpoints. # +# Arguments : CpuNr - oMSP device number to connect to. # +# Result : 0 if error, 1 otherwise. # +#=============================================================================# +proc GetDevice {CpuNr} { + + global omsp_conf + global omsp_info + + # Copy global variable to local for code readability + set if $omsp_conf(interface) + set device $omsp_conf(device) + set baudrate $omsp_conf(baudrate) + set cpuaddr $omsp_conf($CpuNr,cpuaddr) + + + # Open Physical connection (if not already open) + if {$omsp_info(connected)==0} { + + if {![${if}::dbg_open $device $baudrate]} { + return 0 + } + + # Physical connection is active + set omsp_info(connected) 1 + } + + + # Open Connection with the CPU + if {$omsp_info($CpuNr,connected)==0} { + + # Connect to the CPU + if {![${if}::dbg_connect $cpuaddr]} { + return 0 + } + + # Make sure the CPU_ID is correct + if {![VerifyCPU_ID $CpuNr]} { + return 0 + } + + # Enable auto-freeze & software breakpoints + ${if}::dbg_wr $cpuaddr CPU_CTL 0x0018 + + # Initialize the omsp_info global variable + GetCPU_ID $CpuNr + + # Get number of hardware breakpoints + set omsp_info($CpuNr,hw_break) [InitBreakUnits $CpuNr] + + # Connection with the CPU is now active + set omsp_info($CpuNr,connected) 1 + } + + return 1 +} + +#=============================================================================# +# ReleaseDevice (CpuNr, Addr) # +#-----------------------------------------------------------------------------# +# Description: Releases the target device from UART/I2C control; CPU starts # +# execution at the specified PC address. # +# Arguments : CpuNr - oMSP device number to be addressed. # +# Addr - 0xfffe: perform reset; # +# address at reset vector loaded into PC; # +# otherwise address specified by Addr loaded into PC. # +# Result : 0 if error, 1 otherwise. # +#=============================================================================# +proc ReleaseDevice {CpuNr Addr} { + + if {[expr $Addr]==[expr 0xfffe]} { + set result 1 + set result [expr $result+[ExecutePOR $CpuNr]] + set result [expr $result+[ReleaseCPU $CpuNr]] + } else { + set result 0 + set result [expr $result+[HaltCPU $CpuNr]] + set result [expr $result+[SetPC $CpuNr $Addr]] + set result [expr $result+[ReleaseCPU $CpuNr]] + } + + if {$result==3} { + return 1 + } else { + return 0 + } +} + +#=============================================================================# +# ExecutePOR (CpuNr) # +#-----------------------------------------------------------------------------# # Description: Executes a power-up clear (PUC) command. # -# Arguments : None. # +# Arguments : CpuNr - oMSP device number to be addressed. # # Result : 0 if error, 1 otherwise. # #=============================================================================# -proc ExecutePOR {} { +proc ExecutePOR {CpuNr} { + global omsp_conf + + # Copy global variable to local for code readability + set if $omsp_conf(interface) + set cpuaddr $omsp_conf($CpuNr,cpuaddr) + # Set PUC - set cpu_ctl_org [dbg_uart_rd CPU_CTL] + set cpu_ctl_org [${if}::dbg_rd $cpuaddr CPU_CTL] set cpu_ctl_new [expr 0x40 | $cpu_ctl_org] - dbg_uart_wr CPU_CTL $cpu_ctl_new + ${if}::dbg_wr $cpuaddr CPU_CTL $cpu_ctl_new # Remove PUC, clear break after reset set cpu_ctl_org [expr 0x5f & $cpu_ctl_org] - dbg_uart_wr CPU_CTL $cpu_ctl_org + ${if}::dbg_wr $cpuaddr CPU_CTL $cpu_ctl_org - # Check CPU ID - if {![VerifyCPU_ID]} { - return 0 - } - # Check status: make sure a PUC occured - set cpu_stat_val [dbg_uart_rd CPU_STAT] + set cpu_stat_val [${if}::dbg_rd $cpuaddr CPU_STAT] set puc_pnd [expr 0x04 & $cpu_stat_val] if {![string eq $puc_pnd 4]} { - return 0 + return 0 } # Clear PUC pending flag - dbg_uart_wr CPU_STAT 0x04 + ${if}::dbg_wr $cpuaddr CPU_STAT 0x04 return 1 } #=============================================================================# -# SetPC (Addr) # +# SetPC (CpuNr, Addr) # #-----------------------------------------------------------------------------# # Description: Loads the target device CPU's program counter (PC) with the # # desired 16-bit address. # -# Arguments : Addr - Desired 16-bit PC value (in hexadecimal). # +# Arguments : CpuNr - oMSP device number to be addressed. # +# Addr - Desired 16-bit PC value (in hexadecimal). # # Result : 0 if error, 1 otherwise. # #=============================================================================# -proc SetPC {Addr} { +proc SetPC {CpuNr Addr} { - return [WriteReg 0 $Addr] + return [WriteReg $CpuNr 0 $Addr] } #=============================================================================# -# HaltCPU () # +# HaltCPU (CpuNr) # #-----------------------------------------------------------------------------# # Description: Sends the target CPU into a controlled, stopped state. # -# Arguments : None. # +# Arguments : CpuNr - oMSP device number to be addressed. # # Result : 0 if error, 1 otherwise. # #=============================================================================# -proc HaltCPU {} { +proc HaltCPU {CpuNr} { - set result 1 + global omsp_conf + # Copy global variable to local for code readability + set if $omsp_conf(interface) + set cpuaddr $omsp_conf($CpuNr,cpuaddr) + # Stop CPU - set cpu_ctl_org [dbg_uart_rd CPU_CTL] + set cpu_ctl_org [${if}::dbg_rd $cpuaddr CPU_CTL] set cpu_ctl_new [expr 0x01 | $cpu_ctl_org] - dbg_uart_wr CPU_CTL $cpu_ctl_new + ${if}::dbg_wr $cpuaddr CPU_CTL $cpu_ctl_new # Check status: make sure the CPU halted - set cpu_stat_val [dbg_uart_rd CPU_STAT] + set cpu_stat_val [${if}::dbg_rd $cpuaddr CPU_STAT] set halted [expr 0x01 & $cpu_stat_val] if {![string eq $halted 1]} { - set result 0 + return 0 } - return $result + return 1 } #=============================================================================# -# ReleaseCPU () # +# ReleaseCPU (CpuNr) # #-----------------------------------------------------------------------------# # Description: Releases the target device's CPU from the controlled, stopped # # state. (Does not release the target device from debug control.)# -# Arguments : None. # +# Arguments : CpuNr - oMSP device number to be addressed. # # Result : 0 if error, 1 otherwise. # #=============================================================================# -proc ReleaseCPU {} { +proc ReleaseCPU {CpuNr} { - set result 1 + global omsp_conf + # Copy global variable to local for code readability + set if $omsp_conf(interface) + set cpuaddr $omsp_conf($CpuNr,cpuaddr) + # Start CPU - set cpu_ctl_org [dbg_uart_rd CPU_CTL] + set cpu_ctl_org [${if}::dbg_rd $cpuaddr CPU_CTL] set cpu_ctl_new [expr 0x02 | $cpu_ctl_org] - dbg_uart_wr CPU_CTL $cpu_ctl_new + ${if}::dbg_wr $cpuaddr CPU_CTL $cpu_ctl_new # Check status: make sure the CPU runs - set cpu_stat_val [dbg_uart_rd CPU_STAT] + set cpu_stat_val [${if}::dbg_rd $cpuaddr CPU_STAT] set halted [expr 0x01 & $cpu_stat_val] if {![string eq $halted 0]} { - set result 0 + return 0 } - return $result -} - -#=============================================================================# -# GetDevice () # -#-----------------------------------------------------------------------------# -# Description: Takes the target MSP430 device under JTAG control. # -# Enable the auto-freeze feature of timers when in the CPU is # -# stopped. This prevents an automatic watchdog reset condition. # -# Enables software breakpoints. # -# Arguments : None. # -# Result : 0 if error, 1 otherwise. # -#=============================================================================# -proc GetDevice {} { - - global hw_break - global omsp_info - - # Set UART global variables - if {![info exists ::serial_baudrate]} { - set ::serial_baudrate 9600 - } - if {![info exists ::serial_device]} { - set ::serial_device /dev/ttyUSB0 - } - - # Open connection - if {![dbg_uart_connect $::serial_device $::serial_baudrate]} { - return 0 - } - - if {[VerifyCPU_ID]} { - - # Enable auto-freeze & software breakpoints - dbg_uart_wr CPU_CTL 0x0018 - - # Initialize the omsp_info global variable - GetCPU_ID - set omsp_info(connected) 1 - - # Get number of hardware breakpoints - set hw_break(num) [InitBreakUnits] - set omsp_info(hw_break) $hw_break(num) - - return 1 - } else { - return 0 - } } #=============================================================================# -# ReleaseDevice (Addr) # +# WriteMem (CpuNr, Format, Addr, Data) # #-----------------------------------------------------------------------------# -# Description: Releases the target device from JTAG control; CPU starts # -# execution at the specified PC address. # -# Arguments : Addr - (0xfffe: perform reset; address at reset vector loaded # -# into PC; otherwise address specified by Addr loaded into PC # -# Result : 0 if error, 1 otherwise. # -#=============================================================================# -proc ReleaseDevice {Addr} { - - if {[expr $Addr]==[expr 0xfffe]} { - set result 1 - set result [expr $result+[ExecutePOR]] - set result [expr $result+[ReleaseCPU]] - } else { - set result 0 - set result [expr $result+[HaltCPU]] - set result [expr $result+[SetPC $Addr]] - set result [expr $result+[ReleaseCPU]] - } - - if {$result==3} { - return 1 - } else { - return 0 - } -} - -#=============================================================================# -# WriteMem (Format, Addr, Data) # -#-----------------------------------------------------------------------------# # Description: Write a single byte or word to a given address (RAM, ROM & # # Peripherals. # -# Arguments : Format - 0 to write a word, 1 to write a byte. # +# Arguments : CpuNr - oMSP device number to be addressed. # +# Format - 0 to write a word, 1 to write a byte. # # Addr - Destination address for data to be written. # # Data - Data value to be written. # # Result : 0 if error, 1 otherwise. # #=============================================================================# -proc WriteMem {Format Addr Data} { +proc WriteMem {CpuNr Format Addr Data} { - dbg_uart_wr MEM_CNT 0x0000 - dbg_uart_wr MEM_ADDR $Addr - dbg_uart_wr MEM_DATA $Data + global omsp_conf + # Copy global variable to local for code readability + set if $omsp_conf(interface) + set cpuaddr $omsp_conf($CpuNr,cpuaddr) + + # Configure memory transfer + #${if}::dbg_wr $cpuaddr MEM_CNT 0x0000 + ${if}::dbg_wr $cpuaddr MEM_ADDR $Addr + ${if}::dbg_wr $cpuaddr MEM_DATA $Data + + # Trigger transfer if {$Format==0} { - dbg_uart_wr MEM_CTL 0x0003 + ${if}::dbg_wr $cpuaddr MEM_CTL 0x0003 } else { - dbg_uart_wr MEM_CTL 0x000b + ${if}::dbg_wr $cpuaddr MEM_CTL 0x000b } return 1 @@ -293,57 +400,71 @@ } #=============================================================================# -# WriteMemQuick (StartAddr, DataArray) # +# WriteMemQuick (CpuNr, StartAddr, DataList) # #-----------------------------------------------------------------------------# -# Description: Writes an array of words into the target device memory (RAM, # +# Description: Writes a list of words into the target device memory (RAM, # # ROM & Peripherals. # -# Arguments : StartAddr - Start address of destination memory. # -# DataArray - List of data to be written (in hexadecimal). # +# Arguments : CpuNr - oMSP device number to be addressed. # +# StartAddr - Start address of destination memory. # +# DataList - List of data to be written (in hexadecimal). # # Result : 0 if error, 1 otherwise. # #=============================================================================# -proc WriteMemQuick {StartAddr DataArray} { +proc WriteMemQuick {CpuNr StartAddr DataList} { - if {[llength $DataArray]==1} { - WriteMem 0 $StartAddr $DataArray + global omsp_conf + + # Copy global variable to local for code readability + set if $omsp_conf(interface) + set cpuaddr $omsp_conf($CpuNr,cpuaddr) + + # Single data transfer + if {[llength $DataList]==1} { + WriteMem $CpuNr 0 $StartAddr $DataList + + # Burst data transfer } else { - dbg_uart_wr MEM_CNT [expr [llength $DataArray]-1] - dbg_uart_wr MEM_ADDR $StartAddr - dbg_uart_wr MEM_CTL 0x0003 + # Configure & trigger memory transfer + ${if}::dbg_wr $cpuaddr MEM_CNT [expr [llength $DataList]-1] + ${if}::dbg_wr $cpuaddr MEM_ADDR $StartAddr + ${if}::dbg_wr $cpuaddr MEM_CTL 0x0003 - foreach data [split $DataArray] { + # Send data list + ${if}::dbg_burst_tx $cpuaddr 0 $DataList - # Format data - set data [format %04x $data] - regexp {(..)(..)} $data match data_msb data_lsb - - # Send data - dbg_uart_tx "0x$data_lsb 0x$data_msb" } - } return 1 } #=============================================================================# -# ReadMem (Format, Addr) # +# ReadMem (CpuNr, Format, Addr) # #-----------------------------------------------------------------------------# # Description: Read one byte or word from a specified target memory address. # -# Arguments : Format - 0 to read a word, 1 to read a byte. # +# Arguments : CpuNr - oMSP device number to be addressed. # +# Format - 0 to read a word, 1 to read a byte. # # Addr - Target address for data to be read. # # Result : Data value stored in the target address memory location. # #=============================================================================# -proc ReadMem {Format Addr} { +proc ReadMem {CpuNr Format Addr} { - dbg_uart_wr MEM_CNT 0x0000 - dbg_uart_wr MEM_ADDR $Addr + global omsp_conf + # Copy global variable to local for code readability + set if $omsp_conf(interface) + set cpuaddr $omsp_conf($CpuNr,cpuaddr) + + # Single data transfer + #${if}::dbg_wr $cpuaddr MEM_CNT 0x0000 + ${if}::dbg_wr $cpuaddr MEM_ADDR $Addr + + # Trigger transfer if {$Format==0} { - dbg_uart_wr MEM_CTL 0x0001 - set mem_val [dbg_uart_rd MEM_DATA] + ${if}::dbg_wr $cpuaddr MEM_CTL 0x0001 + set mem_val [${if}::dbg_rd $cpuaddr MEM_DATA] } else { - dbg_uart_wr MEM_CTL 0x0009 - set mem_val [dbg_uart_rd MEM_DATA] - set mem_val [format "0x%02x" $mem_val] + ${if}::dbg_wr $cpuaddr MEM_CTL 0x0009 + set mem_val [${if}::dbg_rd $cpuaddr MEM_DATA] + set mem_val [format "0x%02x" $mem_val] } return $mem_val @@ -350,115 +471,138 @@ } #=============================================================================# -# ReadMemQuick (StartAddr, Length) # +# ReadMemQuick (CpuNr, StartAddr, Length) # #-----------------------------------------------------------------------------# -# Description: Reads an array of words from target memory. # -# Arguments : StartAddr - Start address of target memory to be read. # -# Length - Number of word to be read. # +# Description: Reads a list of words from target memory. # +# Arguments : CpuNr - oMSP device number to be addressed. # +# StartAddr - Start address of target memory to be read. # +# Length - Number of words to be read. # # Result : List of data values stored in the target memory. # #=============================================================================# -proc ReadMemQuick {StartAddr Length} { +proc ReadMemQuick {CpuNr StartAddr Length} { + global omsp_conf + + # Copy global variable to local for code readability + set if $omsp_conf(interface) + set cpuaddr $omsp_conf($CpuNr,cpuaddr) + + # Single data transfer if {$Length==1} { - set mem_val [ReadMem 0 $StartAddr] + set mem_val [ReadMem $CpuNr 0 $StartAddr] + + # Burst data transfer } else { - dbg_uart_wr MEM_CNT [expr $Length-1] - dbg_uart_wr MEM_ADDR $StartAddr - dbg_uart_wr MEM_CTL 0x0001 + # Configure & trigger memory transfer + ${if}::dbg_wr $cpuaddr MEM_CNT [expr $Length-1] + ${if}::dbg_wr $cpuaddr MEM_ADDR $StartAddr + ${if}::dbg_wr $cpuaddr MEM_CTL 0x0001 - set mem_val [dbg_uart_rx 0 [expr $Length*2]] + # Receive Data list + set mem_val [${if}::dbg_burst_rx $cpuaddr 0 [expr $Length*2]] } return $mem_val } #=============================================================================# -# VerifyMem (StartAddr, DataArray) # +# VerifyMem (CpuNr, StartAddr, DataList) # #-----------------------------------------------------------------------------# # Description: Performs a program verification over the given memory range. # -# Arguments : StartAddr - Start address of the memory to be verified. # -# DataArray - List of reference data (in hexadecimal). # +# Arguments : CpuNr - oMSP device number to be addressed. # +# StartAddr - Start address of the memory to be verified. # +# DataList - List of reference data (in hexadecimal). # # Result : 0 if error, 1 if verification was successful. # #=============================================================================# -proc VerifyMem {StartAddr DataArray {DumpOnError 0}} { +proc VerifyMem {CpuNr StartAddr DataList {DumpOnError 0}} { - dbg_uart_wr MEM_CNT [expr [llength $DataArray]-1] - dbg_uart_wr MEM_ADDR $StartAddr - dbg_uart_wr MEM_CTL 0x0001 + # Read memory content + set mem_val [ReadMemQuick $CpuNr $StartAddr [llength $DataList]] - set mem_val [dbg_uart_rx 0 [expr [llength $DataArray]*2]] + # Compare memory contents + set return_val [string equal $DataList $mem_val] - set return_val [string equal $DataArray $mem_val] + # Dump memory content in files for comparison + if {($return_val==0) && ($DumpOnError==1)} { - if {($return_val==0) && ($DumpOnError==1)} { - file delete -force openmsp430-verifymem-debug-original.mem - file delete -force openmsp430-verifymem-debug-dumped.mem - set fileId [open openmsp430-verifymem-debug-original.mem "w"] - foreach hexCode $DataArray { - puts $fileId $hexCode + # Delete old files + file delete -force openmsp430-verifymem-debug-expected.mem + file delete -force openmsp430-verifymem-debug-dumped.mem + + # Write expected memory content + set fileId [open openmsp430-verifymem-debug-expected.mem "w"] + foreach hexCode $DataList { + puts $fileId $hexCode + } + close $fileId + + # Dump read memory content + set fileId [open openmsp430-verifymem-debug-dumped.mem "w"] + foreach hexCode $mem_val { + puts $fileId $hexCode + } + close $fileId } - close $fileId - set fileId [open openmsp430-verifymem-debug-dumped.mem "w"] - foreach hexCode $mem_val { - puts $fileId $hexCode - } - close $fileId - } return $return_val } #=============================================================================# -# ExecutePOR_Halt () # +# ExecutePOR_Halt (CpuNr) # #-----------------------------------------------------------------------------# # Description: Same as ExecutePOR with the difference that the CPU # # automatically goes in Halt mode after reset. # -# Arguments : None. # +# Arguments : CpuNr - oMSP device number to be addressed. # # Result : 0 if error, 1 otherwise. # #=============================================================================# -proc ExecutePOR_Halt {} { +proc ExecutePOR_Halt {CpuNr} { - set result 1 + global omsp_conf + # Copy global variable to local for code readability + set if $omsp_conf(interface) + set cpuaddr $omsp_conf($CpuNr,cpuaddr) + # Perform PUC - set cpu_ctl_org [dbg_uart_rd CPU_CTL] + set cpu_ctl_org [${if}::dbg_rd $cpuaddr CPU_CTL] set cpu_ctl_new [expr 0x60 | $cpu_ctl_org] - dbg_uart_wr CPU_CTL $cpu_ctl_new - dbg_uart_wr CPU_CTL $cpu_ctl_org + ${if}::dbg_wr $cpuaddr CPU_CTL $cpu_ctl_new + ${if}::dbg_wr $cpuaddr CPU_CTL $cpu_ctl_org - # Check CPU ID - if {![VerifyCPU_ID]} { - set result 0 - } - # Check status: make sure a PUC occured and that the CPU is halted - set cpu_stat_val [dbg_uart_rd CPU_STAT] + set cpu_stat_val [${if}::dbg_rd $cpuaddr CPU_STAT] set puc_pnd [expr 0x05 & $cpu_stat_val] if {![string eq $puc_pnd 5]} { - set result 0 + return 0 } # Clear PUC pending flag - dbg_uart_wr CPU_STAT 0x04 + ${if}::dbg_wr $cpuaddr CPU_STAT 0x04 - return $result + return 1 } #=============================================================================# -# GetCPU_ID () # +# GetCPU_ID (CpuNr) # #-----------------------------------------------------------------------------# # Description: This function reads the CPU_ID from the target device, update # # the omsp_info global variable and return the raw CPU_ID value. # -# Arguments : None. # +# Arguments : CpuNr - oMSP device number to be addressed. # # Result : Return CPU_ID. # #=============================================================================# -proc GetCPU_ID { } { +proc GetCPU_ID {CpuNr} { + global omsp_conf global omsp_info - - # Retreive CPU_ID values - set cpu_id_lo [dbg_uart_rd CPU_ID_LO] - set cpu_id_hi [dbg_uart_rd CPU_ID_HI] + + # Copy global variable to local for code readability + set if $omsp_conf(interface) + set cpuaddr $omsp_conf($CpuNr,cpuaddr) + + # Retreive CPU_ID/CPU_NR values + set cpu_id_lo [${if}::dbg_rd $cpuaddr CPU_ID_LO] + set cpu_id_hi [${if}::dbg_rd $cpuaddr CPU_ID_HI] + set cpu_nr [${if}::dbg_rd $cpuaddr CPU_NR] # Check if value is valid if {[string eq "0x" $cpu_id_lo]} { @@ -467,6 +611,9 @@ if {[string eq "0x" $cpu_id_hi]} { set cpu_id_hi "0x0000" } + if {[string eq "0x" $cpu_nr]} { + set cpu_nr "0x0000" + } # Remove the "0x" prefix regsub {0x} $cpu_id_lo {} cpu_id_lo @@ -478,215 +625,292 @@ # Extract the omsp info depending on the CPU version - set omsp_info(cpu_ver) [expr ($cpu_id_lo & 0x0007)+1] - if {$omsp_info(cpu_ver)==1} { - set omsp_info(asic) 0 - set omsp_info(user_ver) -- - set omsp_info(per_size) 512 - set omsp_info(mpy) -- - set omsp_info(dmem_size) [expr $cpu_id_lo] - set omsp_info(pmem_size) [expr $cpu_id_hi] + set omsp_info($CpuNr,cpu_ver) [expr ($cpu_id_lo & 0x0007)+1] + if {$omsp_info($CpuNr,cpu_ver)==1} { + set omsp_info($CpuNr,user_ver) -- + set omsp_info($CpuNr,per_size) 512 + set omsp_info($CpuNr,dmem_size) [expr $cpu_id_lo] + set omsp_info($CpuNr,pmem_size) [expr $cpu_id_hi] + set omsp_info($CpuNr,mpy) -- + set omsp_info($CpuNr,asic) 0 } else { - set omsp_info(asic) [expr ($cpu_id_lo & 0x0008)/8] - set omsp_info(user_ver) [expr ($cpu_id_lo & 0x01f0)/9] - set omsp_info(per_size) [expr (($cpu_id_lo & 0xfe00)/512) * 512] - set omsp_info(mpy) [expr ($cpu_id_hi & 0x0001)/1] - set omsp_info(dmem_size) [expr (($cpu_id_hi & 0x03fe)/2) * 128] - set omsp_info(pmem_size) [expr (($cpu_id_hi & 0xfc00)/1024) * 1024] + set omsp_info($CpuNr,user_ver) [expr ($cpu_id_lo & 0x01f0)/16] + set omsp_info($CpuNr,per_size) [expr (($cpu_id_lo & 0xfe00)/512) * 512] + set omsp_info($CpuNr,dmem_size) [expr (($cpu_id_hi & 0x03fe)/2) * 128] + set omsp_info($CpuNr,pmem_size) [expr (($cpu_id_hi & 0xfc00)/1024) * 1024] + set omsp_info($CpuNr,mpy) [expr ($cpu_id_hi & 0x0001)/1] + set omsp_info($CpuNr,asic) [expr ($cpu_id_lo & 0x0008)/8] } - set omsp_info(alias) [GetChipAlias] + # Get the instance number + set omsp_info($CpuNr,inst_nr) [expr ($cpu_nr & 0x00ff)/1] + set omsp_info($CpuNr,total_nr) [expr ($cpu_nr & 0xff00)/256] + # Get alias from the XML file + set omsp_info($CpuNr,alias) [GetChipAlias $CpuNr] + return $cpu_id } #=============================================================================# -# GetCPU_ID_SIZE () # +# GetCPU_ID_SIZE (CpuNr) # #-----------------------------------------------------------------------------# # Description: Returns the Data and Program memory sizes of the connected # # device. # -# Arguments : None. # -# Result : Return "PMEM_SIZE DMEM_SIZE" in byte. # +# Arguments : CpuNr - oMSP device number to be addressed. # +# Result : Return "PMEM_SIZE DMEM_SIZE PER_SIZE" in byte. # #=============================================================================# -proc GetCPU_ID_SIZE {} { +proc GetCPU_ID_SIZE {CpuNr} { global omsp_info - if {[info exists omsp_info(pmem_size)]} { - set pmem_size $omsp_info(pmem_size) + # Check if custom sizes are available from the XML file + set custom_pmem [array names omsp_info -glob "$CpuNr,extra,*,pmem_size"] + set custom_dmem [array names omsp_info -glob "$CpuNr,extra,*,dmem_size"] + set custom_per [array names omsp_info -glob "$CpuNr,extra,*,per_size"] + + # Program memory size + if {$custom_pmem != ""} { + set pmem_size $omsp_info($custom_pmem) + } elseif {[info exists omsp_info($CpuNr,pmem_size)]} { + set pmem_size $omsp_info($CpuNr,pmem_size) } else { set pmem_size -1 } - if {[info exists omsp_info(dmem_size)]} { - set dmem_size $omsp_info(dmem_size) + + # Data memory size + if {$custom_dmem != ""} { + set dmem_size $omsp_info($custom_dmem) + } elseif {[info exists omsp_info($CpuNr,dmem_size)]} { + set dmem_size $omsp_info($CpuNr,dmem_size) } else { set dmem_size -1 } - return "$pmem_size $dmem_size" + # Peripheral address space size + if {$custom_per != ""} { + set per_size $omsp_info($custom_per) + } elseif {[info exists omsp_info($CpuNr,per_size)]} { + set per_size $omsp_info($CpuNr,per_size) + } else { + set per_size -1 + } + + return "$pmem_size $dmem_size $per_size" } #=============================================================================# -# VerifyCPU_ID () # +# VerifyCPU_ID (CpuNr) # #-----------------------------------------------------------------------------# # Description: Read and check the CPU_ID from the target device. # -# Arguments : None. # +# Arguments : CpuNr - oMSP device number to be addressed. # # Result : 0 if error, 1 otherwise. # #=============================================================================# -proc VerifyCPU_ID {} { +proc VerifyCPU_ID {CpuNr} { + global omsp_conf global omsp_info - set cpu_id_full [GetCPU_ID] + set cpu_id_full [GetCPU_ID $CpuNr] if {[string eq "0x00000000" $cpu_id_full] | - ([string length $cpu_id_full]!=10) | - ($omsp_info(cpu_ver) >3) } { - puts "\n" - puts "ERROR: cpu_id not valid: $cpu_id_full" - puts "" - puts " -------------------------------------------------------------" - puts " !!!! Make sure that you are properly connected to the board !!!!" - puts " !!!! or try reseting the serial debug interface (or CPU). !!!!" - puts " -------------------------------------------------------------" - puts "" - set result 0 - } else { - set result 1 + ([string length $cpu_id_full]!=10) | + ($omsp_info($CpuNr,cpu_ver) >3) } { + + puts "\n" + puts "ERROR: cpu_id not valid: $cpu_id_full" + puts "" + puts " --------------------------------------------------------------" + puts " !!!! What next: !!!!" + if {[regexp {i2c_} $omsp_conf(interface)]} { + puts " !!!! - double check the I2C address of the target core. !!!!" + } + puts " !!!! - check that you are properly connected to the board. !!!!" + puts " !!!! - try reseting the serial debug interface (or CPU). !!!!" + puts " --------------------------------------------------------------" + puts "" + + return 0 } - return $result + return 1 } #=============================================================================# -# WriteReg (Addr, Data) # +# WriteReg (CpuNr, Addr, Data) # #-----------------------------------------------------------------------------# # Description: Write a word to the the selected CPU register. # -# Arguments : Addr - Target CPU Register number. # -# Data - Data value to be written. # +# Arguments : CpuNr - oMSP device number to be addressed. # +# Addr - Target CPU Register number. # +# Data - Data value to be written. # # Result : 0 if error, 1 otherwise. # #=============================================================================# -proc WriteReg {Addr Data} { +proc WriteReg {CpuNr Addr Data} { - dbg_uart_wr MEM_CNT 0x0000 + global omsp_conf - dbg_uart_wr MEM_ADDR $Addr - dbg_uart_wr MEM_DATA $Data - dbg_uart_wr MEM_CTL 0x0007 + # Copy global variable to local for code readability + set if $omsp_conf(interface) + set cpuaddr $omsp_conf($CpuNr,cpuaddr) + # Configure memory transfer + #${if}::dbg_wr $cpuaddr MEM_CNT 0x0000 + ${if}::dbg_wr $cpuaddr MEM_ADDR $Addr + ${if}::dbg_wr $cpuaddr MEM_DATA $Data + + # Trigger transfer + ${if}::dbg_wr $cpuaddr MEM_CTL 0x0007 + return 1 } #=============================================================================# -# WriteRegAll (DataArray) # +# WriteRegAll (CpuNr, DataList) # #-----------------------------------------------------------------------------# # Description: Write all CPU registers. # -# Arguments : DataArray - Data values to be written. # +# Arguments : CpuNr - oMSP device number to be addressed. # +# DataList - Data values to be written. # # Result : 0 if error, 1 otherwise. # #=============================================================================# -proc WriteRegAll {DataArray} { +proc WriteRegAll {CpuNr DataList} { - dbg_uart_wr MEM_CNT [expr [llength $DataArray]-1] - dbg_uart_wr MEM_ADDR 0x0000 - dbg_uart_wr MEM_CTL 0x0007 + global omsp_conf - foreach data [split $DataArray] { + # Copy global variable to local for code readability + set if $omsp_conf(interface) + set cpuaddr $omsp_conf($CpuNr,cpuaddr) - # Format data - set data [format %04x $data] - regexp {(..)(..)} $data match data_msb data_lsb + # Configure & trigger memory transfer + ${if}::dbg_wr $cpuaddr MEM_CNT [expr [llength $DataList]-1] + ${if}::dbg_wr $cpuaddr MEM_ADDR 0x0000 + ${if}::dbg_wr $cpuaddr MEM_CTL 0x0007 - # Send data - dbg_uart_tx "0x$data_lsb 0x$data_msb" - } + # Send data list + ${if}::dbg_burst_tx $cpuaddr 0 $DataList return 1 } #=============================================================================# -# ReadReg (Addr) # +# ReadReg (CpuNr, Addr) # #-----------------------------------------------------------------------------# # Description: Read the value from the selected CPU register. # -# Arguments : Addr - Target CPU Register number. # +# Arguments : CpuNr - oMSP device number to be addressed. # +# Addr - Target CPU Register number. # # Result : Data value stored in the selected CPU register. # #=============================================================================# -proc ReadReg {Addr} { +proc ReadReg {CpuNr Addr} { - dbg_uart_wr MEM_CNT 0x0000 + global omsp_conf - dbg_uart_wr MEM_ADDR $Addr - dbg_uart_wr MEM_CTL 0x0005 - set reg_val [dbg_uart_rd MEM_DATA] + # Copy global variable to local for code readability + set if $omsp_conf(interface) + set cpuaddr $omsp_conf($CpuNr,cpuaddr) + # Single data transfer + ${if}::dbg_wr $cpuaddr MEM_CNT 0x0000 + ${if}::dbg_wr $cpuaddr MEM_ADDR $Addr + + # Trigger transfer + ${if}::dbg_wr $cpuaddr MEM_CTL 0x0005 + set reg_val [${if}::dbg_rd $cpuaddr MEM_DATA] + return $reg_val } #=============================================================================# -# ReadRegAll () # +# ReadRegAll (CpuNr) # #-----------------------------------------------------------------------------# # Description: Read all CPU registers. # -# Arguments : None. # +# Arguments : CpuNr - oMSP device number to be addressed. # # Result : Current values of all CPU registers. # #=============================================================================# -proc ReadRegAll {} { +proc ReadRegAll {CpuNr} { - dbg_uart_wr MEM_CNT 0x000f - dbg_uart_wr MEM_ADDR 0x0000 - dbg_uart_wr MEM_CTL 0x0005 + global omsp_conf - set reg_val [dbg_uart_rx 0 32] + # Copy global variable to local for code readability + set if $omsp_conf(interface) + set cpuaddr $omsp_conf($CpuNr,cpuaddr) + # Configure & trigger memory transfer + ${if}::dbg_wr $cpuaddr MEM_CNT 0x000f + ${if}::dbg_wr $cpuaddr MEM_ADDR 0x0000 + ${if}::dbg_wr $cpuaddr MEM_CTL 0x0005 + + # Receive Data list + set reg_val [${if}::dbg_burst_rx $cpuaddr 0 32] + return $reg_val } #=============================================================================# -# WriteMemQuick8 (StartAddr, DataArray) # +# WriteMemQuick8 (CpuNr, StartAddr, DataList) # #-----------------------------------------------------------------------------# -# Description: Writes an array of bytes into the target device memory (RAM, # +# Description: Writes a list of bytes into the target device memory (RAM, # # ROM & Peripherals. # -# Arguments : StartAddr - Start address of destination memory. # -# DataArray - List of data to be written (in hexadecimal). # +# Arguments : CpuNr - oMSP device number to be addressed. # +# StartAddr - Start address of destination memory. # +# DataList - List of data to be written (in hexadecimal). # # Result : 0 if error, 1 otherwise. # #=============================================================================# -proc WriteMemQuick8 {StartAddr DataArray} { +proc WriteMemQuick8 {CpuNr StartAddr DataList} { - if {[llength $DataArray]==1} { - WriteMem 1 $StartAddr $DataArray + global omsp_conf + + # Copy global variable to local for code readability + set if $omsp_conf(interface) + set cpuaddr $omsp_conf($CpuNr,cpuaddr) + + # Single data transfer + if {[llength $DataList]==1} { + WriteMem $CpuNr 1 $StartAddr $DataList + + # Burst data transfer } else { - dbg_uart_wr MEM_CNT [expr [llength $DataArray]-1] - dbg_uart_wr MEM_ADDR $StartAddr - dbg_uart_wr MEM_CTL 0x000b + # Configure & trigger memory transfer + ${if}::dbg_wr $cpuaddr MEM_CNT [expr [llength $DataList]-1] + ${if}::dbg_wr $cpuaddr MEM_ADDR $StartAddr + ${if}::dbg_wr $cpuaddr MEM_CTL 0x000b - foreach data [split $DataArray] { + # Send data list + ${if}::dbg_burst_tx $cpuaddr 1 $DataList - # Format data - set data [format %02x $data] - - # Send data - dbg_uart_tx "0x$data" } - } return 1 } #=============================================================================# -# ReadMemQuick8 (StartAddr, Length) # +# ReadMemQuick8 (CpuNr, StartAddr, Length) # #-----------------------------------------------------------------------------# -# Description: Reads an array of bytes from target memory. # -# Arguments : StartAddr - Start address of target memory to be read. # +# Description: Reads a list of bytes from target memory. # +# Arguments : CpuNr - oMSP device number to be addressed. # +# StartAddr - Start address of target memory to be read. # # Length - Number of bytes to be read. # # Result : List of data values stored in the target memory. # #=============================================================================# -proc ReadMemQuick8 {StartAddr Length} { +proc ReadMemQuick8 {CpuNr StartAddr Length} { + global omsp_conf + + # Copy global variable to local for code readability + set if $omsp_conf(interface) + set cpuaddr $omsp_conf($CpuNr,cpuaddr) + + # Single data transfer if {$Length==1} { - set mem_val [ReadMem 1 $StartAddr] + set mem_val [ReadMem $CpuNr 1 $StartAddr] + + # Burst data transfer } else { - dbg_uart_wr MEM_CNT [expr $Length-1] - dbg_uart_wr MEM_ADDR $StartAddr - dbg_uart_wr MEM_CTL 0x0009 - set mem_val [dbg_uart_rx 1 [expr $Length]] + # Configure & trigger memory transfer + ${if}::dbg_wr $cpuaddr MEM_CNT [expr $Length-1] + ${if}::dbg_wr $cpuaddr MEM_ADDR $StartAddr + ${if}::dbg_wr $cpuaddr MEM_CTL 0x0009 + + # Receive Data list + set mem_val [${if}::dbg_burst_rx $cpuaddr 1 $Length] } return $mem_val @@ -693,190 +917,230 @@ } #=============================================================================# -# StepCPU () # +# StepCPU (CpuNr) # #-----------------------------------------------------------------------------# # Description: Performs a CPU incremental step. # -# Arguments : None. # +# Arguments : CpuNr - oMSP device number to be addressed. # # Result : 0 if error, 1 otherwise. # #=============================================================================# -proc StepCPU {} { +proc StepCPU {CpuNr} { + global omsp_conf + + # Copy global variable to local for code readability + set if $omsp_conf(interface) + set cpuaddr $omsp_conf($CpuNr,cpuaddr) + # Check if the device is halted. If not, stop it. - set cpu_ctl_val [dbg_uart_rd CPU_CTL] + set cpu_ctl_val [${if}::dbg_rd $cpuaddr CPU_CTL] set cpu_ctl_new [expr 0x04 | $cpu_ctl_val] - dbg_uart_wr CPU_CTL $cpu_ctl_new + ${if}::dbg_wr $cpuaddr CPU_CTL $cpu_ctl_new return 1 } #=============================================================================# -# EraseRAM () # +# EraseRAM (CpuNr) # #-----------------------------------------------------------------------------# # Description: Erase RAM. # -# Arguments : None. # +# Arguments : CpuNr - oMSP device number to be addressed. # # Result : 0 if error, 1 otherwise. # #=============================================================================# -proc EraseRAM {} { +proc EraseRAM {CpuNr} { - set ram_size [lindex [GetCPU_ID_SIZE] 1] + global omsp_info + set ram_size [lindex [GetCPU_ID_SIZE $CpuNr] 1] + set per_size [lindex [GetCPU_ID_SIZE $CpuNr] 2] + if {$ram_size!=-1} { - set DataArray "" - for {set i 0} {$i<$ram_size} {incr i} { - lappend DataArray 0x00 - } - WriteMemQuick8 $0x0200 $DataArray + set DataList "" + for {set i 0} {$i<$ram_size} {incr i} { + lappend DataList 0x00 + } - return 1 + WriteMemQuick8 $CpuNr $per_size $DataList + + return 1 } return 0 } #=============================================================================# -# EraseROM () # +# EraseROM (CpuNr) # #-----------------------------------------------------------------------------# # Description: Erase ROM. # -# Arguments : None. # +# Arguments : CpuNr - oMSP device number to be addressed. # # Result : 0 if error, 1 otherwise. # #=============================================================================# -proc EraseROM {} { +proc EraseROM {CpuNr} { - set rom_size [lindex [GetCPU_ID_SIZE] 0] + set rom_size [lindex [GetCPU_ID_SIZE $CpuNr] 0] set rom_start [expr 0x10000-$rom_size] if {$rom_size!=-1} { - set DataArray "" - for {set i 0} {$i<$rom_size} {incr i} { - lappend DataArray 0x00 - } + set DataList "" + for {set i 0} {$i<$rom_size} {incr i} { + lappend DataList 0x00 + } - WriteMemQuick8 $rom_start $DataArray + WriteMemQuick8 $CpuNr $rom_start $DataList - return 1 + return 1 } return 0 } #=============================================================================# -# InitBreakUnits() # +# InitBreakUnits(CpuNr) # #-----------------------------------------------------------------------------# # Description: Initialize the hardware breakpoint units. # -# Arguments : None. # +# Arguments : CpuNr - oMSP device number to be addressed. # # Result : Number of hardware breakpoint units. # #=============================================================================# -proc InitBreakUnits {} { +proc InitBreakUnits {CpuNr} { + global omsp_conf + + # Copy global variable to local for code readability + set if $omsp_conf(interface) + set cpuaddr $omsp_conf($CpuNr,cpuaddr) + + # Initialize each hardware breakpoint unit and count how many of them + # are present in the current core set num_brk_units 0 for {set i 0} {$i<4} {incr i} { - dbg_uart_wr "BRK$i\_ADDR0" 0x1234 - set new_val [dbg_uart_rd "BRK$i\_ADDR0"] - if {$new_val=="0x1234"} { - incr num_brk_units - dbg_uart_wr "BRK$i\_CTL" 0x00 - dbg_uart_wr "BRK$i\_STAT" 0xff - dbg_uart_wr "BRK$i\_ADDR0" 0x0000 - dbg_uart_wr "BRK$i\_ADDR1" 0x0000 + ${if}::dbg_wr $cpuaddr "BRK$i\_ADDR0" 0x1234 + set new_val [${if}::dbg_rd $cpuaddr "BRK$i\_ADDR0"] + if {$new_val=="0x1234"} { + incr num_brk_units + ${if}::dbg_wr $cpuaddr "BRK$i\_CTL" 0x00 + ${if}::dbg_wr $cpuaddr "BRK$i\_STAT" 0xff + ${if}::dbg_wr $cpuaddr "BRK$i\_ADDR0" 0x0000 + ${if}::dbg_wr $cpuaddr "BRK$i\_ADDR1" 0x0000 + } } - } return $num_brk_units } #=============================================================================# -# SetHWBreak(Type, Addr, Rd, Wr) # +# SetHWBreak(CpuNr, Type, Addr, Rd, Wr) # #-----------------------------------------------------------------------------# # Description: Set data/instruction breakpoint on a given memory address. # -# Arguments : Type - 1 for instruction break, 0 for data break. # -# Addr - Memory address of the data breakpoint. # -# Rd - Breakpoint on read access. # -# Wr - Breakpoint on write access. # +# Arguments : CpuNr - oMSP device number to be addressed. # +# Type - 1 for instruction break, 0 for data break. # +# Addr - Memory address of the data breakpoint. # +# Rd - Breakpoint on read access. # +# Wr - Breakpoint on write access. # # Result : 0 if error, 1 otherwise. # #=============================================================================# -proc SetHWBreak {Type Addr Rd Wr} { - global hw_break +proc SetHWBreak {CpuNr Type Addr Rd Wr} { + global omsp_info + global omsp_conf + + # Copy global variable to local for code readability + set if $omsp_conf(interface) + set cpuaddr $omsp_conf($CpuNr,cpuaddr) + # Compute the BRKx_CTL corresponding value set brk_ctl_ref [format "0x02%x" [expr 8*$Type+4+2*$Wr+$Rd]] # First look for utilized units with correct BRKx_CTL attributes - for {set i 0} {$i<$hw_break(num)} {incr i} { - if {[string eq [dbg_uart_rd "BRK$i\_CTL"] $brk_ctl_ref]} { - # Look if there is an address free - set brk_addr0 [dbg_uart_rd "BRK$i\_ADDR0"] - set brk_addr1 [dbg_uart_rd "BRK$i\_ADDR1"] - if {[string eq $brk_addr0 $brk_addr1]} { - dbg_uart_wr "BRK$i\_ADDR1" $Addr - return 1 + for {set i 0} {$i<$omsp_info($CpuNr,hw_break)} {incr i} { + if {[string eq [${if}::dbg_rd $cpuaddr "BRK$i\_CTL"] $brk_ctl_ref]} { + + # Look if there is an address free + set brk_addr0 [${if}::dbg_rd $cpuaddr "BRK$i\_ADDR0"] + set brk_addr1 [${if}::dbg_rd $cpuaddr "BRK$i\_ADDR1"] + if {[string eq $brk_addr0 $brk_addr1]} { + ${if}::dbg_wr $cpuaddr "BRK$i\_ADDR1" $Addr + return 1 + } } } - } # Then look for a free unit - for {set i 0} {$i<$hw_break(num)} {incr i} { - if {[string eq [dbg_uart_rd "BRK$i\_CTL"] 0x00]} { - dbg_uart_wr "BRK$i\_ADDR0" $Addr - dbg_uart_wr "BRK$i\_ADDR1" $Addr - dbg_uart_wr "BRK$i\_CTL" $brk_ctl_ref - return 1 + for {set i 0} {$i<$omsp_info($CpuNr,hw_break)} {incr i} { + if {[string eq [${if}::dbg_rd $cpuaddr "BRK$i\_CTL"] 0x00]} { + ${if}::dbg_wr $cpuaddr "BRK$i\_ADDR0" $Addr + ${if}::dbg_wr $cpuaddr "BRK$i\_ADDR1" $Addr + ${if}::dbg_wr $cpuaddr "BRK$i\_CTL" $brk_ctl_ref + return 1 + } } - } return 0 } #=============================================================================# -# ClearHWBreak(Type, Addr) # +# ClearHWBreak(CpuNr, Type, Addr) # #-----------------------------------------------------------------------------# # Description: Clear the data/instruction breakpoint set on the provided # # memory address. # -# Arguments : Type - 1 for instruction break, 0 for data break. # -# Addr - Data address of the breakpoint to be cleared. # +# Arguments : CpuNr - oMSP device number to be addressed. # +# Type - 1 for instruction break, 0 for data break. # +# Addr - Data address of the breakpoint to be cleared. # # Result : 0 if error, 1 otherwise. # #=============================================================================# -proc ClearHWBreak {Type Addr} { - global hw_break +proc ClearHWBreak {CpuNr Type Addr} { - for {set i 0} {$i<$hw_break(num)} {incr i} { - # Check if the unit works on Data or Instructions) - set brk_ctl [dbg_uart_rd "BRK$i\_CTL"] - if {[expr $brk_ctl & 0x08]==[expr 8*$Type]} { + global omsp_info + global omsp_conf - # Look for the matching address - set brk_addr0 [dbg_uart_rd "BRK$i\_ADDR0"] - set brk_addr1 [dbg_uart_rd "BRK$i\_ADDR1"] + # Copy global variable to local for code readability + set if $omsp_conf(interface) + set cpuaddr $omsp_conf($CpuNr,cpuaddr) - if {[string eq $brk_addr0 $brk_addr1] && [string eq $brk_addr0 $Addr]} { - dbg_uart_wr "BRK$i\_CTL" 0x00 - dbg_uart_wr "BRK$i\_STAT" 0xff - dbg_uart_wr "BRK$i\_ADDR0" 0x0000 - dbg_uart_wr "BRK$i\_ADDR1" 0x0000 - return 1 + for {set i 0} {$i<$omsp_info($CpuNr,hw_break)} {incr i} { + + # Check if the unit works on Data or Instructions) + set brk_ctl [${if}::dbg_rd $cpuaddr "BRK$i\_CTL"] + if {[expr $brk_ctl & 0x08]==[expr 8*$Type]} { + + # Look for the matching address + set brk_addr0 [${if}::dbg_rd $cpuaddr "BRK$i\_ADDR0"] + set brk_addr1 [${if}::dbg_rd $cpuaddr "BRK$i\_ADDR1"] + + if {[string eq $brk_addr0 $brk_addr1] && [string eq $brk_addr0 $Addr]} { + ${if}::dbg_wr $cpuaddr "BRK$i\_CTL" 0x00 + ${if}::dbg_wr $cpuaddr "BRK$i\_STAT" 0xff + ${if}::dbg_wr $cpuaddr "BRK$i\_ADDR0" 0x0000 + ${if}::dbg_wr $cpuaddr "BRK$i\_ADDR1" 0x0000 + return 1 + } + if {[string eq $brk_addr0 $Addr]} { + ${if}::dbg_wr $cpuaddr "BRK$i\_ADDR0" $brk_addr1 + return 1 + } + if {[string eq $brk_addr1 $Addr]} { + ${if}::dbg_wr $cpuaddr "BRK$i\_ADDR1" $brk_addr0 + return 1 + } } - if {[string eq $brk_addr0 $Addr]} { - dbg_uart_wr "BRK$i\_ADDR0" $brk_addr1 - return 1 - } - if {[string eq $brk_addr1 $Addr]} { - dbg_uart_wr "BRK$i\_ADDR1" $brk_addr0 - return 1 - } } - } return 1 } #=============================================================================# -# IsHalted () # +# IsHalted (CpuNr) # #-----------------------------------------------------------------------------# # Description: Check if the CPU is currently stopped or not. # -# Arguments : None. # +# Arguments : CpuNr - oMSP device number to be addressed. # # Result : 0 if CPU is running, 1 if stopped. # #=============================================================================# -proc IsHalted {} { +proc IsHalted {CpuNr} { + global omsp_conf + + # Copy global variable to local for code readability + set if $omsp_conf(interface) + set cpuaddr $omsp_conf($CpuNr,cpuaddr) + # Check current target status - set cpu_stat_val [dbg_uart_rd CPU_STAT] + set cpu_stat_val [${if}::dbg_rd $cpuaddr CPU_STAT] set halted [expr 0x01 & $cpu_stat_val] return $halted @@ -883,50 +1147,75 @@ } #=============================================================================# -# ClrStatus () # +# ClrStatus (CpuNr) # #-----------------------------------------------------------------------------# # Description: Clear the status bit of the CPU_STAT register. # -# Arguments : None. # +# Arguments : CpuNr - oMSP device number to be addressed. # # Result : 0 if error, 1 otherwise. # #=============================================================================# -proc ClrStatus {} { +proc ClrStatus {CpuNr} { + global omsp_conf + + # Copy global variable to local for code readability + set if $omsp_conf(interface) + set cpuaddr $omsp_conf($CpuNr,cpuaddr) + # Clear status - dbg_uart_wr CPU_STAT 0xff - dbg_uart_wr BRK0_STAT 0xff - dbg_uart_wr BRK1_STAT 0xff - dbg_uart_wr BRK2_STAT 0xff - dbg_uart_wr BRK3_STAT 0xff + ${if}::dbg_wr $cpuaddr CPU_STAT 0xff + ${if}::dbg_wr $cpuaddr BRK0_STAT 0xff + ${if}::dbg_wr $cpuaddr BRK1_STAT 0xff + ${if}::dbg_wr $cpuaddr BRK2_STAT 0xff + ${if}::dbg_wr $cpuaddr BRK3_STAT 0xff return 1 } #=============================================================================# -# GetChipAlias () # +# GetAllowedSpeeds() # #-----------------------------------------------------------------------------# +# Description: Return the list of allowed speed configurations for the # +# selected adapter. # +# Arguments : None. # +# Result : list of modes. # +#=============================================================================# +proc GetAllowedSpeeds {} { + + global omsp_conf + + # Copy global variable to local for code readability + set if $omsp_conf(interface) + + # Return list of allowed speed configuration + return [${if}::get_allowed_speeds] +} + +#=============================================================================# +# GetChipAlias (CpuNr) # +#-----------------------------------------------------------------------------# # Description: Parse the chip alias XML file an return the alias name. # -# Arguments : None. # +# Arguments : CpuNr - oMSP device number to be addressed. # # Result : Chip Alias. # #=============================================================================# -proc GetChipAlias {} { +proc GetChipAlias {CpuNr} { global omsp_info # Set XML file name if {[info exists ::env(OMSP_XML_FILE)]} { - set xmlFile $::env(OMSP_XML_FILE) + set xmlFile $::env(OMSP_XML_FILE) } else { - set xmlFile [file normalize "$::scriptDir/../../omsp_alias.xml"] + set xmlFile [file normalize "$::scriptDir/../../omsp_alias.xml"] } # Read XML file if {[file exists $xmlFile]} { - set fp [open $xmlFile r] - set xmlData [read $fp] - close $fp + set fp [open $xmlFile r] + set xmlData [read $fp] + close $fp } else { - puts "WARNING: the XML alias file was not found - $xmlFile" - return "" + puts "WARNING: the XML alias file was not found - $xmlFile" + return "" } # Analyze XML file @@ -933,8 +1222,8 @@ ::XML::Init $xmlData set wellFormed [::XML::IsWellFormed] if {$wellFormed ne ""} { - puts "WARNING: the XML alias file is not well-formed - $xmlFile \n $wellFormed" - return "" + puts "WARNING: the XML alias file is not well-formed - $xmlFile \n $wellFormed" + return "" } #========================================================================# @@ -945,91 +1234,92 @@ set currentTYPE "" set currentTAG "" while {1} { - foreach {type val attr etype} [::XML::NextToken] break - if {$type == "EOF"} break + foreach {type val attr etype} [::XML::NextToken] break + if {$type == "EOF"} break - # Detect the start of a new alias description - if {($type == "XML") & ($val == "omsp:alias") & ($etype == "START")} { - set aliasName "" - regexp {val=\"(.*)\"} $attr whole_match aliasName - lappend aliasList $aliasName - set currentALIAS $aliasName - } + # Detect the start of a new alias description + if {($type == "XML") & ($val == "omsp:alias") & ($etype == "START")} { + set aliasName "" + regexp {val=\"(.*)\"} $attr whole_match aliasName + lappend aliasList $aliasName + set currentALIAS $aliasName + } - # Detect start and end of the configuration field - if {($type == "XML") & ($val == "omsp:configuration")} { + # Detect start and end of the configuration field + if {($type == "XML") & ($val == "omsp:configuration")} { - if {($etype == "START")} { - set currentTYPE "config" + if {($etype == "START")} { + set currentTYPE "config" - } elseif {($etype == "END")} { - set currentTYPE "" + } elseif {($etype == "END")} { + set currentTYPE "" + } } - } - # Detect start and end of the extra_info field - if {($type == "XML") & ($val == "omsp:extra_info")} { + # Detect start and end of the extra_info field + if {($type == "XML") & ($val == "omsp:extra_info")} { - if {($etype == "START")} { - set currentTYPE "extra_info" - set idx 0 + if {($etype == "START")} { + set currentTYPE "extra_info" + set idx 0 - } elseif {($etype == "END")} { - set currentTYPE "" + } elseif {($etype == "END")} { + set currentTYPE "" + } } - } + + # Detect the current TAG + if {($type == "XML") & ($etype == "START")} { + regsub {omsp:} $val {} val + set currentTAG $val + } - # Detect the current TAG - if {($type == "XML") & ($etype == "START")} { - regsub {omsp:} $val {} val - set currentTAG $val - } - - if {($type == "TXT")} { - if {$currentTYPE=="extra_info"} { - set alias($currentALIAS,$currentTYPE,$idx,$currentTAG) $val - incr idx - } else { - set alias($currentALIAS,$currentTYPE,$currentTAG) $val + if {($type == "TXT")} { + if {$currentTYPE=="extra_info"} { + set alias($currentALIAS,$currentTYPE,$idx,$currentTAG) $val + incr idx + } else { + set alias($currentALIAS,$currentTYPE,$currentTAG) $val + } } } - } #========================================================================# # Check if the current OMSP_INFO has an alias match # #========================================================================# foreach currentALIAS $aliasList { - set aliasCONFIG [array names alias -glob "$currentALIAS,config,*"] - set aliasEXTRA [lsort -increasing [array names alias -glob "$currentALIAS,extra_info,*"]] - #----------------------------------# - # Is current alias matching ? # - #----------------------------------# - set match 1 - set description "" - foreach currentCONFIG $aliasCONFIG { + set aliasCONFIG [array names alias -glob "$currentALIAS,config,*"] + set aliasEXTRA [lsort -increasing [array names alias -glob "$currentALIAS,extra_info,*"]] - regsub "$currentALIAS,config," $currentCONFIG {} configName + #----------------------------------# + # Is current alias matching ? # + #----------------------------------# + set match 1 + set description "" + foreach currentCONFIG $aliasCONFIG { - if {![string eq $omsp_info($configName) $alias($currentCONFIG)]} { - set match 0 + regsub "$currentALIAS,config," $currentCONFIG {} configName + + if {![string eq $omsp_info($CpuNr,$configName) $alias($currentCONFIG)]} { + set match 0 + } } - } - #----------------------------------# - # If matching, get the extra infos # - #----------------------------------# - if {$match} { + #----------------------------------# + # If matching, get the extra infos # + #----------------------------------# + if {$match} { - set idx 0 - foreach currentEXTRA $aliasEXTRA { - regsub "$currentALIAS,extra_info," $currentEXTRA {} extraName - set omsp_info(extra,$idx,$extraName) $alias($currentEXTRA) - incr idx + set idx 0 + foreach currentEXTRA $aliasEXTRA { + regsub "$currentALIAS,extra_info," $currentEXTRA {} extraName + set omsp_info($CpuNr,extra,$idx,$extraName) $alias($currentEXTRA) + incr idx + } + return $currentALIAS } - return $currentALIAS } - } return "" }
/trunk/tools/lib/tcl-lib/dbg_utils.tcl
0,0 → 1,201
#----------------------------------------------------------------------------------
# Copyright (C) 2001 Authors
#
# This source file may be used and distributed without restriction provided
# that this copyright statement is not removed from the file and that any
# derivative work contains the original copyright notice and the associated
# disclaimer.
#
# This source file is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
#
# This source is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
# License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this source; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#
#----------------------------------------------------------------------------------
#
# File Name: dbg_utils.tcl
#
# Author(s):
# - Olivier Girard, olgirard@gmail.com
#
#----------------------------------------------------------------------------------
# $Rev: 133 $
# $LastChangedBy: olivier.girard $
# $LastChangedDate: 2012-03-22 21:28:26 +0100 (Thu, 22 Mar 2012) $
#----------------------------------------------------------------------------------
#
# Description:
#
# Basic utility functions for UART communication.
#
# Public functions:
#
# - utils::uart_port_list ()
# - utils::uart_open (Device, Baudrate)
# - utils::uart_tx (Data)
# - utils::uart_rx (Format, Length)
#
#----------------------------------------------------------------------------------
namespace eval utils {
 
global serial_ch
 
#=============================================================================#
# utils::uart_port_list () #
#-----------------------------------------------------------------------------#
# Description: Return the available serial ports (works on both linux and #
# windows. #
# Arguments : None. #
# Result : List of the available serial ports. #
#=============================================================================#
proc uart_port_list {} {
 
set serial_ports ""
 
switch $::tcl_platform(os) {
{Linux} {
set dmesg ""
catch {exec dmesg} dmesg
while {[regexp {ttyS\d+?} $dmesg match]} {
regsub $match $dmesg {} dmesg
if { [lsearch -exact $serial_ports "/dev/$match"] == -1 } {
lappend serial_ports "/dev/$match"
}
}
while {[regexp {ttyACM\d+?} $dmesg match]} {
regsub $match $dmesg {} dmesg
if { [lsearch -exact $serial_ports "/dev/$match"] == -1 } {
lappend serial_ports "/dev/$match"
}
}
while {[regexp {ttyUSB\d+?} $dmesg match]} {
regsub $match $dmesg {} dmesg
if { [lsearch -exact $serial_ports "/dev/$match"] == -1 } {
lappend serial_ports "/dev/$match"
}
}
if {![llength $serial_ports]} {
set serial_ports [list /dev/ttyS0 /dev/ttyS1 /dev/ttyS2 /dev/ttyS3]
}
}
{Windows NT} {
package require registry
set serial_base "HKEY_LOCAL_MACHINE\\HARDWARE\\DEVICEMAP\\SERIALCOMM"
set values [registry values $serial_base]
foreach valueName $values {
lappend serial_ports "[registry get $serial_base $valueName]:"
}
}
default {set serial_ports ""}
}
 
return $serial_ports
}
 
#=============================================================================#
# utils::uart_open (Device, Baudrate) #
#-----------------------------------------------------------------------------#
# Description: Open and configure the UART connection. #
# Arguments : Device - Serial port device (i.e. /dev/ttyS0 or COM2:) #
# Configure - Configure serial communication (1:UART/0:I2C) #
# Baudrate - UART communication speed. #
# Result : 0 if error, 1 otherwise. #
#=============================================================================#
proc uart_open {Device Configure Baudrate} {
global serial_ch
 
# Open device for reading and writing
if {[catch {open $Device RDWR} serial_ch]} {
return 0
}
if {$Configure} {
# Setup the baud rate
fconfigure $serial_ch -mode "$Baudrate,n,8,1"
# Block on read, don't buffer output
fconfigure $serial_ch -blocking 1 -buffering none -translation binary -timeout 1000
 
} else {
fconfigure $serial_ch -translation binary
}
 
return 1
}
 
#=============================================================================#
# utils::uart_tx (Data) #
#-----------------------------------------------------------------------------#
# Description: Transmit data over the serial debug interface. #
# Arguments : Data - Data byte list to be sent. #
# Result : 0 if error, 1 otherwise. #
#=============================================================================#
proc uart_tx {Data} {
global serial_ch
set allchar ""
# Format data
foreach char [split $Data] {
append allchar [format %02x $char]
}
# Send data
# puts "TX: $allchar"
puts -nonewline $serial_ch [binary format H* $allchar]
flush $serial_ch
 
return 1
}
 
#=============================================================================#
# utils::uart_rx (Format, Length) #
#-----------------------------------------------------------------------------#
# Description: Receive data from the serial debug interface. #
# Arguments : Format - 0 format as 16 bit word, 1 format as 8 bit word. #
# Length - Number of bytes to be received. #
# Result : List of received values, in hexadecimal. #
#=============================================================================#
proc uart_rx {Format Length} {
global serial_ch
if { [catch {read $serial_ch $Length} rx_data] } {
set hex_data "0000"
} else {
set hex_data ""
foreach char [split $rx_data {}] {
binary scan $char H* hex_char
lappend hex_data $hex_char
}
}
# puts "RX: $hex_data"
# Format data
if {$Format==0} {
set num_byte 2
} else {
set num_byte 1
}
set formated_data ""
for {set i 0} {$i<[expr $Length/$num_byte]} {incr i} {
set data ""
for {set j $num_byte} {$j>0} {set j [expr $j-1]} {
append data [lindex $hex_data [expr ($i*$num_byte)+$j-1]]
}
lappend formated_data "0x$data"
}
 
return $formated_data
}
 
}
trunk/tools/lib/tcl-lib/dbg_utils.tcl Property changes : Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: trunk/tools/omsp_alias.xml =================================================================== --- trunk/tools/omsp_alias.xml (revision 157) +++ trunk/tools/omsp_alias.xml (revision 158) @@ -5,17 +5,17 @@ - + - + + 2 3 - 1 0 1 4096 @@ -27,7 +27,7 @@ - This is an example implementation of the openMSP430 core on a Xilinx Spartan3 FPGA + This is an example implementation of the openMSP430 core on a Xilinx Spartan6 FPGA Olivier GIRARD olgirard@googlemail.com http://opencores.org/project,openmsp430 @@ -38,21 +38,22 @@ - + - + - - - - - - + + + - 1 + 1 + 3 + 0 + 1 4096 1024 + 512 @@ -59,7 +60,7 @@ - This is an example implementation of the openMSP430 core on a Xilinx/Altera/Actel FPGA + This is an example implementation of the openMSP430 core on a Xilinx Spartan3 FPGA Olivier GIRARD olgirard@googlemail.com http://opencores.org/project,openmsp430
/trunk/tools/bin/openmsp430-gdbproxy.tcl
34,20 → 34,6
# $LastChangedDate$
#------------------------------------------------------------------------------
 
global serial_baudrate
global serial_device
global serial_status
global hw_break
global clients
global server
global verbose
global shell
global omsp_info
 
# Initializations
set serial_status 0
 
 
###############################################################################
# #
# SOURCE LIBRARIES #
63,6 → 49,7
 
# Source library
source $lib_path/dbg_functions.tcl
source $lib_path/dbg_utils.tcl
 
# Source remaining files
source [file dirname $current_file]/../openmsp430-gdbproxy/server.tcl
71,6 → 58,44
 
###############################################################################
# #
# GLOBAL VARIABLES #
# #
###############################################################################
 
global CpuNr
 
global omsp_conf
global omsp_info
 
global omsp_nr
 
global gui_dbg_if
global gui_adapter
global clients
global server
global verbose
global shell
 
# Initialize to default values
set CpuNr 0
set omsp_nr 1
set omsp_conf(interface) uart_generic
#set omsp_nr 4
#set omsp_conf(interface) i2c_usb-iss
set omsp_conf(device) [lindex [utils::uart_port_list] end]
set omsp_conf(baudrate) [lindex [GetAllowedSpeeds] 1]
set omsp_conf(0,cpuaddr) 50
set omsp_conf(1,cpuaddr) 51
set omsp_conf(2,cpuaddr) 52
set omsp_conf(3,cpuaddr) 53
 
set server(port) 2000
 
set shell 0
set verbose 0
 
###############################################################################
# #
# PARAMETER CHECK #
# #
###############################################################################
77,39 → 102,77
 
proc help {} {
puts ""
puts "USAGE : openmsp430-gdbproxy.tcl \[-device <communication device>\]"
puts " \[-baudrate <communication speed>\]"
puts "USAGE : openmsp430-gdbproxy.tcl \[-device <communication port>\]"
puts " \[-adaptor <adaptor type>\]"
puts " \[-speed <communication speed>\]"
puts " \[-i2c_addr <cpu address>\]"
puts " \[-port <server port>\]"
puts " \[-shell]"
puts " \[-verbose\]"
puts " \[-help\]"
puts ""
puts "Examples: openmsp430-gdbproxy.tcl -device /dev/ttyUSB0 -baudrate 9600 -port 2000"
puts " openmsp430-gdbproxy.tcl -device COM2: -baudrate 38400 -port 2000"
puts "Examples: openmsp430-gdbproxy.tcl -device /dev/ttyUSB0 -adaptor uart_generic -speed 115200 -port 2000"
puts " openmsp430-gdbproxy.tcl -device COM2: -adaptor i2c_usb-iss -speed I2C_S_100KHZ -i2c_addr 75 -port 2000"
puts ""
}
 
# Default values
set serial_device [lindex [dbg_list_uart] end]
set serial_baudrate 115200
set server(port) 2000
set shell 0
set verbose 0
 
# Parse arguments
for {set i 0} {$i < $argc} {incr i} {
switch -exact -- [lindex $argv $i] {
-device {set serial_device [lindex $argv [expr $i+1]]; incr i}
-baudrate {set serial_baudrate [lindex $argv [expr $i+1]]; incr i}
-port {set server(port) [lindex $argv [expr $i+1]]; incr i}
-shell {set shell 1}
-verbose {set verbose 1}
-h {help; exit 0}
-help {help; exit 0}
default {}
-device {set omsp_conf(device) [lindex $argv [expr $i+1]]; incr i}
-adaptor {set omsp_conf(interface) [lindex $argv [expr $i+1]]; incr i}
-speed {set omsp_conf(baudrate) [lindex $argv [expr $i+1]]; incr i}
-i2c_addr {set omsp_conf(0,cpuaddr) [lindex $argv [expr $i+1]]; incr i}
-port {set server(port) [lindex $argv [expr $i+1]]; incr i}
-shell {set shell 1}
-verbose {set verbose 1}
-h {help; exit 0}
-help {help; exit 0}
default {}
}
}
 
# Make sure the selected adptor is valid
if {![string eq $omsp_conf(interface) "uart_generic"] &
![string eq $omsp_conf(interface) "i2c_usb-iss"]} {
puts "\nERROR: Specified adaptor is not valid (should be \"uart_generic\" or \"i2c_usb-iss\")"
help
exit 1
}
 
# Make sure the I2C address is an integer
if {![string is integer $omsp_conf(0,cpuaddr)]} {
puts "\nERROR: Specified I2C address is not an integer"
help
exit 1
}
 
# Make sure the I2C address is valid
if {($omsp_conf(0,cpuaddr)<8) | ($omsp_conf(0,cpuaddr)>119)} {
puts "\nERROR: Specified I2C address should lay between 7 and 120"
help
exit 1
}
 
# If the selected interface is a UART, make sure the selected speed is an integer
if {[string eq $omsp_conf(interface) "uart_generic"]} {
if {![string is integer $omsp_conf(baudrate)]} {
puts "\nERROR: Specified UART communication speed is not an integer"
help
exit 1
}
} elseif {[string eq $omsp_conf(interface) "i2c_usb-iss"]} {
if {[lsearch [lindex [GetAllowedSpeeds] 2] $omsp_conf(baudrate)]==-1} {
puts "\nERROR: Specified I2C communication speed is not valid."
puts " Allowed values are:"
foreach allowedVal [lindex [GetAllowedSpeeds] 2] {
puts " - $allowedVal"
}
puts ""
exit 1
}
}
 
# Source additional library for graphical interface
if {!$shell} {
source $lib_path/combobox.tcl
122,24 → 185,24
global server
global shell
if {$shell} {
if {$nonewline} {
puts -nonewline $string
} else {
puts $string
}
if {$nonewline} {
puts -nonewline $string
} else {
puts $string
}
} else {
if {$nonewline} {
$server(log) insert end "$string"
} else {
$server(log) insert end "$string\n"
}
$server(log) see end
if {$nonewline} {
$server(log) insert end "$string"
} else {
$server(log) insert end "$string\n"
}
$server(log) see end
}
}
proc putsVerbose {string} {
global verbose
if {$verbose} {
putsLog "$string"
putsLog "$string"
}
}
 
149,53 → 212,167
if {$shell} {
 
# Connect to device
if {![GetDevice]} {
puts "ERROR: Could not open $serial_device"
puts "INFO: Available serial ports are:"
foreach port [dbg_list_uart] {
puts "INFO: - $port"
}
exit 1
if {![GetDevice $CpuNr]} {
puts "ERROR: Could not open $omsp_conf(device)
puts "INFO: Available serial ports are:"
foreach port [utils::uart_port_list] {
puts "INFO: - $port"
}
if {[string eq $omsp_conf(interface) "i2c_usb-iss"]} {
puts "\nMake sure the specified I2C device address is correct: $omsp_conf(0,cpuaddr)\n"
}
exit 1
}
 
# Display info
if {$omsp_info(alias)==""} {
puts "INFO: Sucessfully connected with the openMSP430 target."
if {$omsp_info($CpuNr,alias)==""} {
puts "INFO: Sucessfully connected with the openMSP430 target."
} else {
puts "INFO: Sucessfully connected with the openMSP430 target ($omsp_info(alias))."
puts "INFO: Sucessfully connected with the openMSP430 target ($omsp_info($CpuNr,alias))."
}
set sizes [GetCPU_ID_SIZE]
if {$omsp_info(asic)} {
puts "INFO: CPU Version - $omsp_info(cpu_ver) / ASIC"
set sizes [GetCPU_ID_SIZE $CpuNr]
if {$omsp_info($CpuNr,asic)} {
puts "INFO: CPU Version - $omsp_info($CpuNr,cpu_ver) / ASIC"
} else {
puts "INFO: CPU Version - $omsp_info(cpu_ver) / FPGA"
puts "INFO: CPU Version - $omsp_info($CpuNr,cpu_ver) / FPGA"
}
puts "INFO: User Version - $omsp_info(user_ver)"
if {$omsp_info(cpu_ver)==1} {
puts "INFO: Hardware Multiplier - --"
} elseif {$omsp_info(mpy)} {
puts "INFO: Hardware Multiplier - Yes"
puts "INFO: User Version - $omsp_info($CpuNr,user_ver)"
if {$omsp_info($CpuNr,cpu_ver)==1} {
puts "INFO: Hardware Multiplier - --"
} elseif {$omsp_info($CpuNr,mpy)} {
puts "INFO: Hardware Multiplier - Yes"
} else {
puts "INFO: Hardware Multiplier - No"
puts "INFO: Hardware Multiplier - No"
}
puts "INFO: Program Memory Size - $omsp_info(pmem_size) B"
puts "INFO: Data Memory Size - $omsp_info(dmem_size) B"
puts "INFO: Peripheral Address Space - $omsp_info(per_size) B"
puts "INFO: $hw_break(num) Hardware Brea/Watch-point unit(s) detected"
puts "INFO: Program Memory Size - $omsp_info($CpuNr,pmem_size) B"
puts "INFO: Data Memory Size - $omsp_info($CpuNr,dmem_size) B"
puts "INFO: Peripheral Address Space - $omsp_info($CpuNr,per_size) B"
puts "INFO: $omsp_info($CpuNr,hw_break) Hardware Brea/Watch-point unit(s) detected"
puts ""
 
# Reset & Stop CPU
ExecutePOR_Halt
ExecutePOR_Halt $CpuNr
 
# Start server for GDB
if {![startServer]} {
exit 1
exit 1
}
 
vwait forever
}
 
proc getConfiguration {} {
 
global gui_dbg_if
global gui_adapter
global omsp_conf
 
regexp {(.+)_(.+)} $omsp_conf(interface) whole_match tmp_if tmp_adapter
 
set gui_dbg_if [string toupper $tmp_if]
set gui_adapter [string toupper $tmp_adapter]
 
return 1
}
 
proc updateConfiguration {{w ""} {sel ""}} {
 
global gui_dbg_if
global gui_adapter
global omsp_conf
global omsp_nr
 
if {$sel=="UART"} {
eval .connect.cfg.if.config2.adapter.p2 list delete 0 end
eval .connect.cfg.if.config2.adapter.p2 list insert end [list "GENERIC"]
set gui_adapter "GENERIC"
set omsp_conf(interface) uart_generic
 
} elseif {$sel=="I2C"} {
 
eval .connect.cfg.if.config2.adapter.p2 list delete 0 end
eval .connect.cfg.if.config2.adapter.p2 list insert end [list "USB-ISS"]
set gui_adapter "USB-ISS"
set omsp_conf(interface) i2c_usb-iss
}
 
if {$gui_dbg_if=="UART"} {
set omsp_nr 1
.connect.cfg.ad.i2c_nr.l configure -state disabled
.connect.cfg.ad.i2c_nr.s configure -state disabled
.connect.cfg.ad.i2c_addr.l configure -state disabled
.connect.cfg.ad.i2c_addr.s0 configure -state disabled
.connect.cfg.ad.i2c_addr.s1 configure -state disabled
.connect.cfg.ad.i2c_addr.s2 configure -state disabled
.connect.cfg.ad.i2c_addr.s3 configure -state disabled
.connect.cfg.ad.arrow.l0 configure -state disabled
.connect.cfg.ad.arrow.l1 configure -state disabled
.connect.cfg.ad.arrow.l2 configure -state disabled
.connect.cfg.ad.arrow.l3 configure -state disabled
.connect.cfg.ad.server_port.p0 configure -state normal
.connect.cfg.ad.server_port.p1 configure -state disabled
.connect.cfg.ad.server_port.p2 configure -state disabled
.connect.cfg.ad.server_port.p3 configure -state disabled
.connect.cfg.ad.core_nr.l0 configure -state disabled
.connect.cfg.ad.core_nr.l1 configure -state disabled
.connect.cfg.ad.core_nr.l2 configure -state disabled
.connect.cfg.ad.core_nr.l3 configure -state disabled
} elseif {$gui_dbg_if=="I2C"} {
# .connect.cfg.ad.core_nr.l0 configure -state normal
# .connect.cfg.ad.i2c_nr.l configure -state normal
# .connect.cfg.ad.i2c_nr.s configure -state normal
.connect.cfg.ad.i2c_addr.l configure -state normal
.connect.cfg.ad.i2c_addr.s0 configure -state normal
.connect.cfg.ad.arrow.l0 configure -state normal
.connect.cfg.ad.server_port.p0 configure -state normal
# .connect.cfg.ad.core_nr.l0 configure -state normal
 
 
if {$omsp_nr < 2} {
.connect.cfg.ad.core_nr.l1 configure -state disabled
.connect.cfg.ad.server_port.p1 configure -state disabled
.connect.cfg.ad.arrow.l1 configure -state disabled
.connect.cfg.ad.i2c_addr.s1 configure -state disabled
} else {
.connect.cfg.ad.core_nr.l1 configure -state normal
.connect.cfg.ad.server_port.p1 configure -state normal
.connect.cfg.ad.arrow.l1 configure -state normal
.connect.cfg.ad.i2c_addr.s1 configure -state normal
}
if {$omsp_nr < 3} {
.connect.cfg.ad.core_nr.l2 configure -state disabled
.connect.cfg.ad.server_port.p2 configure -state disabled
.connect.cfg.ad.arrow.l2 configure -state disabled
.connect.cfg.ad.i2c_addr.s2 configure -state disabled
} else {
.connect.cfg.ad.core_nr.l2 configure -state normal
.connect.cfg.ad.server_port.p2 configure -state normal
.connect.cfg.ad.arrow.l2 configure -state normal
.connect.cfg.ad.i2c_addr.s2 configure -state normal
}
if {$omsp_nr < 4} {
.connect.cfg.ad.core_nr.l3 configure -state disabled
.connect.cfg.ad.server_port.p3 configure -state disabled
.connect.cfg.ad.arrow.l3 configure -state disabled
.connect.cfg.ad.i2c_addr.s3 configure -state disabled
} else {
.connect.cfg.ad.core_nr.l3 configure -state normal
.connect.cfg.ad.server_port.p3 configure -state normal
.connect.cfg.ad.arrow.l3 configure -state normal
.connect.cfg.ad.i2c_addr.s3 configure -state normal
}
}
 
.connect.cfg.if.config2.serial_port.p2 configure -editable 1
eval .connect.cfg.if.config2.serial_port.p2 list delete 0 end
eval .connect.cfg.if.config2.serial_port.p2 list insert end [lindex [GetAllowedSpeeds] 2]
set omsp_conf(baudrate) [lindex [GetAllowedSpeeds] 1];
.connect.cfg.if.config2.serial_port.p2 configure -editable [lindex [GetAllowedSpeeds] 0];
 
}
 
###############################################################################
# GUI MODE #
###############################################################################
241,44 → 418,116
pack .menu.omsp -side right -padx 20
 
# Create the Configuration, Start & Info frames
frame .connect.config
pack .connect.config -side left -padx 10 -pady 0 -fill x -expand true
getConfiguration
frame .connect.cfg
pack .connect.cfg -side left -padx 0 -pady 0 -fill x -expand true
frame .connect.cfg.if -bd 2 -relief ridge
pack .connect.cfg.if -side top -padx 10 -pady {10 0} -fill x -expand true
frame .connect.cfg.ad -bd 2 -relief ridge
pack .connect.cfg.ad -side top -padx 10 -pady 10 -fill both -expand true
frame .connect.start
pack .connect.start -side right -padx 10 -pady 0 -fill x -expand true
 
# Serial Port fields
set serial_device [lindex [dbg_list_uart] end]
frame .connect.config.serial_port
pack .connect.config.serial_port -side top -padx 5 -pady {10 0} -fill x
label .connect.config.serial_port.l1 -text "Serial Port:" -anchor w
pack .connect.config.serial_port.l1 -side left -padx 5
combobox .connect.config.serial_port.p1 -textvariable serial_device -editable true -width 20
eval .connect.config.serial_port.p1 list insert end [dbg_list_uart]
pack .connect.config.serial_port.p1 -side right -padx 20
frame .connect.cfg.if.config1
pack .connect.cfg.if.config1 -side left -padx 0 -pady 0 -fill x -expand true
frame .connect.cfg.if.config2
pack .connect.cfg.if.config2 -side left -padx 0 -pady 0 -fill x -expand true
 
# Serial Baudrate fields
set serial_baudrate 115200
frame .connect.config.serial_baudrate
pack .connect.config.serial_baudrate -side top -padx 5 -pady {5 0} -fill x
label .connect.config.serial_baudrate.l2 -text " Baudrate:" -anchor w
pack .connect.config.serial_baudrate.l2 -side left
combobox .connect.config.serial_baudrate.p2 -textvariable serial_baudrate -editable true -width 20
eval .connect.config.serial_baudrate.p2 list insert end [list 9600 19200 38400 57600 115200 \
230400 460800 500000 576000 921600 \
1000000 1152000]
pack .connect.config.serial_baudrate.p2 -side right -padx 20
# Interface & Adapter selection
frame .connect.cfg.if.config1.adapter
pack .connect.cfg.if.config1.adapter -side top -padx 5 -pady {10 0} -fill x
label .connect.cfg.if.config1.adapter.l1 -text "Serial Debug Interface:" -anchor w
pack .connect.cfg.if.config1.adapter.l1 -side left -padx 5
combobox .connect.cfg.if.config1.adapter.p1 -textvariable gui_dbg_if -editable false -width 15 -command {updateConfiguration}
eval .connect.cfg.if.config1.adapter.p1 list insert end [list "UART" "I2C"]
pack .connect.cfg.if.config1.adapter.p1 -side right -padx 10
 
# Server Port field
frame .connect.config.server_port
pack .connect.config.server_port -side top -padx 10 -pady {15 10} -fill x
label .connect.config.server_port.l1 -text "Proxy Server Port:" -anchor w
pack .connect.config.server_port.l1 -side left
entry .connect.config.server_port.p -textvariable server(port) -relief sunken -width 20
pack .connect.config.server_port.p -side right -padx 5 -padx 20
frame .connect.cfg.if.config2.adapter
pack .connect.cfg.if.config2.adapter -side top -padx 5 -pady {10 0} -fill x
label .connect.cfg.if.config2.adapter.l2 -text "Adapter selection:" -anchor w
pack .connect.cfg.if.config2.adapter.l2 -side left -padx 5
combobox .connect.cfg.if.config2.adapter.p2 -textvariable gui_adapter -editable false -width 15
eval .connect.cfg.if.config2.adapter.p2 list insert end [list "GENERIC"]
pack .connect.cfg.if.config2.adapter.p2 -side right -padx 5
 
# Device port & Speed selection
frame .connect.cfg.if.config1.serial_port
pack .connect.cfg.if.config1.serial_port -side top -padx 5 -pady {10 10} -fill x
label .connect.cfg.if.config1.serial_port.l1 -text "Device Port:" -anchor w
pack .connect.cfg.if.config1.serial_port.l1 -side left -padx 5
combobox .connect.cfg.if.config1.serial_port.p1 -textvariable omsp_conf(device) -editable true -width 15
eval .connect.cfg.if.config1.serial_port.p1 list insert end [utils::uart_port_list]
pack .connect.cfg.if.config1.serial_port.p1 -side right -padx 10
 
frame .connect.cfg.if.config2.serial_port
pack .connect.cfg.if.config2.serial_port -side top -padx 5 -pady {10 10} -fill x
label .connect.cfg.if.config2.serial_port.l2 -text "Speed:" -anchor w
pack .connect.cfg.if.config2.serial_port.l2 -side left -padx 5
combobox .connect.cfg.if.config2.serial_port.p2 -textvariable omsp_conf(baudrate) -editable [lindex [GetAllowedSpeeds] 0] -width 15
eval .connect.cfg.if.config2.serial_port.p2 list insert end [lindex [GetAllowedSpeeds] 2]
pack .connect.cfg.if.config2.serial_port.p2 -side right -padx 5
 
# Server Port field & I2C address selection
frame .connect.cfg.ad.core_nr
pack .connect.cfg.ad.core_nr -side left -padx 5 -fill y
label .connect.cfg.ad.core_nr.l3 -text "Core 3:" -anchor w
pack .connect.cfg.ad.core_nr.l3 -side bottom -padx {25 0} -pady {10 10}
label .connect.cfg.ad.core_nr.l2 -text "Core 2:" -anchor w
pack .connect.cfg.ad.core_nr.l2 -side bottom -padx {25 0} -pady {10 2}
label .connect.cfg.ad.core_nr.l1 -text "Core 1:" -anchor w
pack .connect.cfg.ad.core_nr.l1 -side bottom -padx {25 0} -pady {10 2}
label .connect.cfg.ad.core_nr.l0 -text "Core 0:" -anchor w
pack .connect.cfg.ad.core_nr.l0 -side bottom -padx {25 0} -pady {10 2}
 
frame .connect.cfg.ad.server_port
pack .connect.cfg.ad.server_port -side left -padx 5 -fill y
entry .connect.cfg.ad.server_port.p3 -textvariable server(port) -relief sunken -width 10
pack .connect.cfg.ad.server_port.p3 -side bottom -padx 5 -pady {10 10}
entry .connect.cfg.ad.server_port.p2 -textvariable server(port) -relief sunken -width 10
pack .connect.cfg.ad.server_port.p2 -side bottom -padx 5 -pady {10 0}
entry .connect.cfg.ad.server_port.p1 -textvariable server(port) -relief sunken -width 10
pack .connect.cfg.ad.server_port.p1 -side bottom -padx 5 -pady {10 0}
entry .connect.cfg.ad.server_port.p0 -textvariable server(port) -relief sunken -width 10
pack .connect.cfg.ad.server_port.p0 -side bottom -padx 5 -pady {10 0}
label .connect.cfg.ad.server_port.l -text "Proxy Server Port" -anchor w
pack .connect.cfg.ad.server_port.l -side bottom -padx 5 -pady {10 0}
 
frame .connect.cfg.ad.arrow
pack .connect.cfg.ad.arrow -side left -padx 5 -fill y
label .connect.cfg.ad.arrow.l3 -text "==>" -anchor w
pack .connect.cfg.ad.arrow.l3 -side bottom -padx 5 -pady {10 10}
label .connect.cfg.ad.arrow.l2 -text "==>" -anchor w
pack .connect.cfg.ad.arrow.l2 -side bottom -padx 5 -pady {10 2}
label .connect.cfg.ad.arrow.l1 -text "==>" -anchor w
pack .connect.cfg.ad.arrow.l1 -side bottom -padx 5 -pady {10 2}
label .connect.cfg.ad.arrow.l0 -text "==>" -anchor w
pack .connect.cfg.ad.arrow.l0 -side bottom -padx 5 -pady {10 2}
 
frame .connect.cfg.ad.i2c_addr
pack .connect.cfg.ad.i2c_addr -side left -padx 5 -fill y
spinbox .connect.cfg.ad.i2c_addr.s3 -from 8 -to 119 -textvariable omsp_conf(3,cpuaddr) -width 4
pack .connect.cfg.ad.i2c_addr.s3 -side bottom -padx 5 -pady {10 10}
spinbox .connect.cfg.ad.i2c_addr.s2 -from 8 -to 119 -textvariable omsp_conf(2,cpuaddr) -width 4
pack .connect.cfg.ad.i2c_addr.s2 -side bottom -padx 5 -pady {10 0}
spinbox .connect.cfg.ad.i2c_addr.s1 -from 8 -to 119 -textvariable omsp_conf(1,cpuaddr) -width 4
pack .connect.cfg.ad.i2c_addr.s1 -side bottom -padx 5 -pady {10 0}
spinbox .connect.cfg.ad.i2c_addr.s0 -from 8 -to 119 -textvariable omsp_conf(0,cpuaddr) -width 4
pack .connect.cfg.ad.i2c_addr.s0 -side bottom -padx 5 -pady {10 0}
label .connect.cfg.ad.i2c_addr.l -text "I2C Address" -anchor w
pack .connect.cfg.ad.i2c_addr.l -side bottom -padx 5 -pady {10 0}
 
frame .connect.cfg.ad.i2c_nr
pack .connect.cfg.ad.i2c_nr -side right -padx 5 -fill y
label .connect.cfg.ad.i2c_nr.l -text "Number of cores" -anchor w
pack .connect.cfg.ad.i2c_nr.l -side top -padx 50 -pady {10 0}
spinbox .connect.cfg.ad.i2c_nr.s -from 1 -to 4 -textvariable omsp_nr -state readonly -width 4 -command {updateConfiguration}
pack .connect.cfg.ad.i2c_nr.s -side top -padx 50 -pady {10 10}
 
# Update according to default values
updateConfiguration
 
# Connect to CPU & start proxy server
button .connect.start.but -text "Connect to CPU\n and \nStart Proxy Server" -command {startServerGUI}
button .connect.start.but -text "Connect to CPU(s)\n and \nStart Proxy Server(s)" -command {startServerGUI}
pack .connect.start.but -side right -padx 30
 
 
/trunk/tools/bin/openmsp430-minidebug.tcl
23,7 → 23,7
#
#------------------------------------------------------------------------------
#
# File Name: minidebug.tcl
# File Name: openmsp430-minidebug.tcl
#
# Author(s):
# - Olivier Girard, olgirard@gmail.com
36,14 → 36,40
 
###############################################################################
# #
# SOURCE LIBRARIES #
# #
###############################################################################
 
# Get library path
set current_file [info script]
if {[file type $current_file]=="link"} {
set current_file [file readlink $current_file]
}
set lib_path [file dirname $current_file]/../lib/tcl-lib
 
# Source library
source $lib_path/dbg_functions.tcl
source $lib_path/dbg_utils.tcl
source $lib_path/combobox.tcl
package require combobox 2.3
catch {namespace import combobox::*}
 
 
###############################################################################
# #
# GLOBAL VARIABLES #
# #
###############################################################################
 
global serial_baudrate
global serial_device
global serial_status
global CpuNr
 
global omsp_conf
global omsp_info
 
global omsp_nr
 
global current_file_name
global connection_status
global cpu_status
global reg
global mem
51,9 → 77,25
global sr
global codeSelect
global binFileType
global binFileName
global pmemIHEX
global isPmemRead
global brkpt
global color
 
# Initialize to default values
set CpuNr 0
set omsp_nr 1
set omsp_conf(interface) uart_generic
#set omsp_nr 4
#set omsp_conf(interface) i2c_usb-iss
set omsp_conf(device) [lindex [utils::uart_port_list] end]
set omsp_conf(baudrate) [lindex [GetAllowedSpeeds] 1]
set omsp_conf(0,cpuaddr) 50
set omsp_conf(1,cpuaddr) 51
set omsp_conf(2,cpuaddr) 52
set omsp_conf(3,cpuaddr) 53
 
# Color definitions
set color(PC) "\#c1ffc1"
set color(Brk0_active) "\#ba55d3"
64,8 → 106,13
set color(Brk2_disabled) "\#ffffe0"
 
# Initializations
set codeSelect 2
set serial_status 0
set codeSelect 2
set binFileType ""
set binFileName ""
set pmemIHEX ""
set mem_sizes ""
set isPmemRead 0
set connection_status 0
set cpu_status 1
for {set i 0} {$i<3} {incr i} {
set brkpt(addr_$i) 0x0000
77,27 → 124,11
set mem(address_$i) [format "0x%04x" [expr 0x0200+$i*2]]
set mem(data_$i) 0x0000
}
 
###############################################################################
# #
# SOURCE LIBRARIES #
# #
###############################################################################
 
# Get library path
set current_file [info script]
if {[file type $current_file]=="link"} {
set current_file [file readlink $current_file]
for {set i 0} {$i<3} {incr i} {
set backup($i,current_file_name) ""
}
set lib_path [file dirname $current_file]/../lib/tcl-lib
 
# Source library
source $lib_path/dbg_functions.tcl
source $lib_path/combobox.tcl
package require combobox 2.3
catch {namespace import combobox::*}
 
 
###############################################################################
# #
# FUNCTIONS #
105,112 → 136,137
###############################################################################
 
proc connect_openMSP430 {} {
global serial_status
global connection_status
global reg
global mem
global brkpt
global mem_sizes
global color
global omsp_conf
global omsp_info
global omsp_nr
global CpuNr
 
set serial_status [GetDevice]
set connection_status [GetDevice $CpuNr]
 
if {$serial_status} {
set mem_sizes [GetCPU_ID_SIZE]
if {$connection_status} {
set mem_sizes [GetCPU_ID_SIZE $CpuNr]
 
if {[lindex $mem_sizes 0]==-1 | [lindex $mem_sizes 1]==-1} {
.ctrl.connect.info.l1.con configure -text "Connection problem" -fg red
if {[lindex $mem_sizes 0]==-1 | [lindex $mem_sizes 1]==-1 | [lindex $mem_sizes 2]==-1} {
.ctrl.connect.info.l1.con configure -text "Connection problem" -fg red
 
} else {
} else {
# Update Core selection section
regexp {(.+)_(.+)} $omsp_conf(interface) whole_match interface adapter
set interface [string toupper $interface]
if {$interface=="I2C"} {
if {$omsp_nr>1} {
.menu.cpusel configure -state normal
.menu.cpu0 configure -state normal
.menu.cpu1 configure -state normal
}
if {$omsp_nr>2} {.menu.cpu2 configure -state normal}
if {$omsp_nr>3} {.menu.cpu3 configure -state normal}
}
 
# Disable connection section
.ctrl.connect.serial.p1 configure -state disabled
.ctrl.connect.serial.p2 configure -state disabled
.ctrl.connect.serial.connect configure -state disabled
if {$omsp_info(alias)==""} {
.ctrl.connect.info.l1.con configure -text "Connected" -fg "\#00ae00"
} else {
.ctrl.connect.info.l1.con configure -text "Connected to $omsp_info(alias)" -fg "\#00ae00"
}
.ctrl.connect.info.l1.more configure -state normal
# Disable connection section
.ctrl.connect.serial.p1 configure -state disabled
.ctrl.connect.serial.p2 configure -state disabled
.ctrl.connect.serial.connect configure -state disabled
 
# Activate ELF file section
.ctrl.load.ft.l configure -state normal
.ctrl.load.ft.file configure -state normal
.ctrl.load.ft.browse configure -state normal
.ctrl.load.fb.read configure -state normal
.ctrl.load.fb.l configure -state normal
if {$omsp_info($CpuNr,alias)==""} {
.ctrl.connect.info.l1.con configure -text "Connected" -fg "\#00ae00"
} else {
.ctrl.connect.info.l1.con configure -text "Connected to $omsp_info($CpuNr,alias)" -fg "\#00ae00"
}
.ctrl.connect.info.l1.more configure -state normal
 
# Activate CPU control section
.ctrl.cpu.cpu.l1 configure -state normal
.ctrl.cpu.cpu.reset configure -state normal
.ctrl.cpu.cpu.run configure -state normal
.ctrl.cpu.cpu.l2 configure -state normal
.ctrl.cpu.cpu.l3 configure -state normal
if {[IsHalted]} {
.ctrl.cpu.cpu.step configure -state normal
.ctrl.cpu.cpu.run configure -text "Run"
.ctrl.cpu.cpu.l3 configure -text "Stopped" -fg "\#cdad00"
set cpu_status 0
} else {
.ctrl.cpu.cpu.step configure -state disabled
.ctrl.cpu.cpu.run configure -text "Stop"
.ctrl.cpu.cpu.l3 configure -text "Running" -fg "\#00ae00"
set cpu_status 1
}
# Activate ELF file section
.ctrl.load.ft.l configure -state normal
.ctrl.load.ft.file configure -state normal
.ctrl.load.ft.browse configure -state normal
.ctrl.load.fb.load configure -state normal
.ctrl.load.fb.open configure -state normal
.ctrl.load.fb.readpmem configure -state normal
.ctrl.load.info.t configure -state normal
.ctrl.load.info.l configure -state normal
 
# Activate CPU Breakpoints section
.ctrl.cpu.brkpt.l1 configure -state normal
for {set i 0} {$i<3} {incr i} {
set brkpt(addr_$i) [format "0x%04x" [expr 0x10000-[lindex $mem_sizes 0]]]
.ctrl.cpu.brkpt.addr$i configure -state normal
.ctrl.cpu.brkpt.addr$i configure -bg $color(Brk$i\_disabled)
.ctrl.cpu.brkpt.addr$i configure -readonlybackground $color(Brk$i\_active)
.ctrl.cpu.brkpt.chk$i configure -state normal
}
# Activate CPU control section
.ctrl.cpu.cpu.l1 configure -state normal
.ctrl.cpu.cpu.reset configure -state normal
.ctrl.cpu.cpu.run configure -state normal
.ctrl.cpu.cpu.l2 configure -state normal
.ctrl.cpu.cpu.l3 configure -state normal
if {[IsHalted $CpuNr]} {
.ctrl.cpu.cpu.step configure -state normal
.ctrl.cpu.cpu.run configure -text "Run"
.ctrl.cpu.cpu.l3 configure -text "Stopped" -fg "\#cdad00"
set cpu_status 0
} else {
.ctrl.cpu.cpu.step configure -state disabled
.ctrl.cpu.cpu.run configure -text "Stop"
.ctrl.cpu.cpu.l3 configure -text "Running" -fg "\#00ae00"
set cpu_status 1
}
 
# Activate CPU status register section
.ctrl.cpu.reg_stat.l1 configure -state normal
.ctrl.cpu.reg_stat.v configure -state normal
.ctrl.cpu.reg_stat.scg1 configure -state normal
.ctrl.cpu.reg_stat.oscoff configure -state normal
.ctrl.cpu.reg_stat.cpuoff configure -state normal
.ctrl.cpu.reg_stat.gie configure -state normal
.ctrl.cpu.reg_stat.n configure -state normal
.ctrl.cpu.reg_stat.z configure -state normal
.ctrl.cpu.reg_stat.c configure -state normal
# Activate CPU Breakpoints section
.ctrl.cpu.brkpt.l1 configure -state normal
for {set i 0} {$i<3} {incr i} {
set brkpt(addr_$i) [format "0x%04x" [expr 0x10000-[lindex $mem_sizes 0]]]
.ctrl.cpu.brkpt.addr$i configure -state normal
.ctrl.cpu.brkpt.addr$i configure -bg $color(Brk$i\_disabled)
.ctrl.cpu.brkpt.addr$i configure -readonlybackground $color(Brk$i\_active)
.ctrl.cpu.brkpt.chk$i configure -state normal
}
 
# Activate CPU registers and memory section
.ctrl.cpu.reg_mem.reg.title.e configure -state normal
.ctrl.cpu.reg_mem.mem.title.l configure -state normal
.ctrl.cpu.reg_mem.mem.title.e configure -state normal
.ctrl.cpu.reg_mem.reg.refresh configure -state normal
.ctrl.cpu.reg_mem.mem.refresh configure -state normal
for {set i 0} {$i<16} {incr i} {
.ctrl.cpu.reg_mem.reg.f$i.l$i configure -state normal
.ctrl.cpu.reg_mem.reg.f$i.e$i configure -state normal
.ctrl.cpu.reg_mem.mem.f$i.addr_e$i configure -state normal
.ctrl.cpu.reg_mem.mem.f$i.data_e$i configure -state normal
}
.ctrl.cpu.reg_mem.reg.f0.e0 configure -bg $color(PC)
refreshReg
refreshMem
# Activate CPU status register section
.ctrl.cpu.reg_stat.l1 configure -state normal
.ctrl.cpu.reg_stat.v configure -state normal
.ctrl.cpu.reg_stat.scg1 configure -state normal
.ctrl.cpu.reg_stat.oscoff configure -state normal
.ctrl.cpu.reg_stat.cpuoff configure -state normal
.ctrl.cpu.reg_stat.gie configure -state normal
.ctrl.cpu.reg_stat.n configure -state normal
.ctrl.cpu.reg_stat.z configure -state normal
.ctrl.cpu.reg_stat.c configure -state normal
 
# Activate Load TCL script section
.ctrl.tclscript.ft.l configure -state normal
.ctrl.tclscript.ft.file configure -state normal
.ctrl.tclscript.ft.browse configure -state normal
.ctrl.tclscript.fb.read configure -state normal
# Activate the code debugger section
.code.rb.txt configure -state normal
.code.rb.none configure -state normal
.code.rb.asm configure -state normal
.code.rb.mix configure -state normal
}
# Activate CPU registers and memory section
.ctrl.cpu.reg_mem.reg.title.e configure -state normal
.ctrl.cpu.reg_mem.mem.title.l configure -state normal
.ctrl.cpu.reg_mem.mem.title.e configure -state normal
.ctrl.cpu.reg_mem.reg.refresh configure -state normal
.ctrl.cpu.reg_mem.mem.refresh configure -state normal
for {set i 0} {$i<16} {incr i} {
.ctrl.cpu.reg_mem.reg.f$i.l$i configure -state normal
.ctrl.cpu.reg_mem.reg.f$i.e$i configure -state normal
.ctrl.cpu.reg_mem.mem.f$i.addr_e$i configure -state normal
.ctrl.cpu.reg_mem.mem.f$i.data_e$i configure -state normal
}
.ctrl.cpu.reg_mem.reg.f0.e0 configure -bg $color(PC)
refreshReg
refreshMem
 
# Activate Load TCL script section
.ctrl.tclscript.ft.l configure -state normal
.ctrl.tclscript.ft.file configure -state normal
.ctrl.tclscript.ft.browse configure -state normal
.ctrl.tclscript.fb.read configure -state normal
# Activate the code debugger section
.code.rb.txt configure -state normal
.code.rb.none configure -state normal
.code.rb.asm configure -state normal
.code.rb.mix configure -state normal
 
# Initial context save for all CPUs
saveContext 0
saveContext 1
saveContext 2
saveContext 3
}
 
} else {
.ctrl.connect.info.l1.con configure -text "Connection problem" -fg red
.ctrl.connect.info.l1.con configure -text "Connection problem" -fg red
}
}
 
217,22 → 273,23
proc displayMore { } {
 
global omsp_info
global CpuNr
 
# Destroy windows if already existing
if {[lsearch -exact [winfo children .] .omsp_extra_info]!=-1} {
destroy .omsp_extra_info
destroy .omsp_extra_info
}
 
# Create master window
toplevel .omsp_extra_info
wm title .omsp_extra_info "openMSP430 extra info"
wm geometry .omsp_extra_info +380+200
toplevel .omsp_extra_info
wm title .omsp_extra_info "openMSP430 extra info"
wm geometry .omsp_extra_info +380+200
wm resizable .omsp_extra_info 0 0
 
# Title
set title "openMSP430"
if {$omsp_info(alias)!=""} {
set title $omsp_info(alias)
if {$omsp_info($CpuNr,alias)!=""} {
set title $omsp_info($CpuNr,alias)
}
label .omsp_extra_info.title -text "$title" -anchor center -fg "\#00ae00" -font {-weight bold -size 16}
pack .omsp_extra_info.title -side top -padx {20 20} -pady {20 10}
253,46 → 310,46
# Fill the text widget will configuration info
.omsp_extra_info.extra.text tag configure bold -font {-family TkFixedFont -weight bold}
.omsp_extra_info.extra.text insert end "Configuration\n\n" bold
.omsp_extra_info.extra.text insert end [format "CPU Version : %5s\n" $omsp_info(cpu_ver)]
.omsp_extra_info.extra.text insert end [format "User Version : %5s\n" $omsp_info(user_ver)]
if {$omsp_info(cpu_ver)==1} {
.omsp_extra_info.extra.text insert end [format "CPU Version : %5s\n" $omsp_info($CpuNr,cpu_ver)]
.omsp_extra_info.extra.text insert end [format "User Version : %5s\n" $omsp_info($CpuNr,user_ver)]
if {$omsp_info($CpuNr,cpu_ver)==1} {
.omsp_extra_info.extra.text insert end [format "Implementation : %5s\n" --]
} elseif {$omsp_info(asic)==0} {
} elseif {$omsp_info($CpuNr,asic)==0} {
.omsp_extra_info.extra.text insert end [format "Implementation : %5s\n" FPGA]
} elseif {$omsp_info(asic)==1} {
} elseif {$omsp_info($CpuNr,asic)==1} {
.omsp_extra_info.extra.text insert end [format "Implementation : %5s\n" ASIC]
}
if {$omsp_info(mpy)==1} {
if {$omsp_info($CpuNr,mpy)==1} {
.omsp_extra_info.extra.text insert end [format "Hardware Multiplier support: %5s\n" Yes]
} elseif {$omsp_info(mpy)==0} {
} elseif {$omsp_info($CpuNr,mpy)==0} {
.omsp_extra_info.extra.text insert end [format "Hardware Multiplier support: %5s\n" No]
} else {
.omsp_extra_info.extra.text insert end [format "Hardware Multiplier support: %5s\n" --]
}
.omsp_extra_info.extra.text insert end [format "Program memory size : %5s B\n" $omsp_info(pmem_size)]
.omsp_extra_info.extra.text insert end [format "Data memory size : %5s B\n" $omsp_info(dmem_size)]
.omsp_extra_info.extra.text insert end [format "Peripheral address space : %5s B\n" $omsp_info(per_size)]
if {$omsp_info(alias)==""} {
.omsp_extra_info.extra.text insert end [format "Program memory size : %5s B\n" $omsp_info($CpuNr,pmem_size)]
.omsp_extra_info.extra.text insert end [format "Data memory size : %5s B\n" $omsp_info($CpuNr,dmem_size)]
.omsp_extra_info.extra.text insert end [format "Peripheral address space : %5s B\n" $omsp_info($CpuNr,per_size)]
if {$omsp_info($CpuNr,alias)==""} {
.omsp_extra_info.extra.text insert end [format "Alias : %5s\n\n\n" None]
} else {
.omsp_extra_info.extra.text insert end [format "Alias : %5s\n\n\n" $omsp_info(alias)]
.omsp_extra_info.extra.text insert end [format "Alias : %5s\n\n\n" $omsp_info($CpuNr,alias)]
}
 
.omsp_extra_info.extra.text insert end "Extra Info\n\n" bold
 
if {$omsp_info(alias)!=""} {
if {$omsp_info($CpuNr,alias)!=""} {
 
set aliasEXTRA [lsort -increasing [array names omsp_info -glob "extra,*"]]
if {[llength $aliasEXTRA]} {
set aliasEXTRA [lsort -increasing [array names omsp_info -glob "$CpuNr,extra,*"]]
if {[llength $aliasEXTRA]} {
 
foreach currentEXTRA $aliasEXTRA {
regexp {^.+,.+,(.+)$} $currentEXTRA whole_match extraATTR
.omsp_extra_info.extra.text insert end [format "%-15s: %s\n" $extraATTR $omsp_info($currentEXTRA)]
}
.omsp_extra_info.extra.text insert end "\n\n"
}
foreach currentEXTRA $aliasEXTRA {
regexp {^.+,.+,(.+)$} $currentEXTRA whole_match extraATTR
.omsp_extra_info.extra.text insert end [format "%-15s: %s\n" $extraATTR $omsp_info($currentEXTRA)]
}
.omsp_extra_info.extra.text insert end "\n\n"
}
} else {
.omsp_extra_info.extra.text insert end "No alias found in 'omsp_alias.xml' file"
.omsp_extra_info.extra.text insert end "No alias found in 'omsp_alias.xml' file"
}
}
 
301,10 → 358,10
.code.text tag remove $tagNameNew 1.0 end
 
switch -exact -- $type {
"0" {.code.text tag add $tagNameNew $line.0 $line.4}
"1" {.code.text tag add $tagNameNew $line.2 $line.4}
"2" {.code.text tag add $tagNameNew $line.3 $line.4}
default {.code.text tag add $tagNameNew $line.4 [expr $line+1].0}
"0" {.code.text tag add $tagNameNew $line.0 $line.4}
"1" {.code.text tag add $tagNameNew $line.2 $line.4}
"2" {.code.text tag add $tagNameNew $line.3 $line.4}
default {.code.text tag add $tagNameNew $line.4 [expr $line+1].0}
}
}
 
315,139 → 372,297
global color
 
if {$codeSelect!=1} {
# Update PC
regsub {0x} $reg(0) {} pc_val
set code_match [.code.text search "$pc_val:" 1.0 end]
set code_line 1
regexp {(\d+).(\d+)} $code_match whole_match code_line code_column
highlightLine $code_line highlightPC highlightPC 3
.code.text see $code_line.0
# Update PC
regsub {0x} $reg(0) {} pc_val
set code_match [.code.text search "$pc_val:" 1.0 end]
set code_line 1
regexp {(\d+).(\d+)} $code_match whole_match code_line code_column
highlightLine $code_line highlightPC highlightPC 3
.code.text see $code_line.0
 
# Some pre-processing
set brkType(0) 0
if {$brkpt(addr_0)==$brkpt(addr_1)} {
set brkType(1) 1
} else {
set brkType(1) 0
}
if {$brkType(1)==1} {
if {$brkpt(addr_1)==$brkpt(addr_2)} {
set brkType(2) 2
} else {
set brkType(2) 0
}
} else {
if {$brkpt(addr_0)==$brkpt(addr_2)} {
set brkType(2) 1
} else {
if {$brkpt(addr_1)==$brkpt(addr_2)} {
set brkType(2) 1
} else {
set brkType(2) 0
}
}
}
# Some pre-processing
set brkType(0) 0
if {$brkpt(addr_0)==$brkpt(addr_1)} {
set brkType(1) 1
} else {
set brkType(1) 0
}
if {$brkType(1)==1} {
if {$brkpt(addr_1)==$brkpt(addr_2)} {
set brkType(2) 2
} else {
set brkType(2) 0
}
} else {
if {$brkpt(addr_0)==$brkpt(addr_2)} {
set brkType(2) 1
} else {
if {$brkpt(addr_1)==$brkpt(addr_2)} {
set brkType(2) 1
} else {
set brkType(2) 0
}
}
}
 
# Update Breakpoints if required
for {set i 0} {$i<3} {incr i} {
regsub {0x} $brkpt(addr_$i) {} brkpt_val
set code_match [.code.text search "$brkpt_val:" 1.0 end]
set code_line 1
regexp {(\d+).(\d+)} $code_match whole_match code_line code_column
if {$brkpt(en_$i)==1} {
highlightLine $code_line "highlightBRK${i}_ACT" "highlightBRK${i}_DIS" $brkType($i)
} else {
highlightLine $code_line "highlightBRK${i}_DIS" "highlightBRK${i}_ACT" $brkType($i)
}
}
# Update Breakpoints if required
for {set i 0} {$i<3} {incr i} {
regsub {0x} $brkpt(addr_$i) {} brkpt_val
set code_match [.code.text search "$brkpt_val:" 1.0 end]
set code_line 1
regexp {(\d+).(\d+)} $code_match whole_match code_line code_column
if {$brkpt(en_$i)==1} {
highlightLine $code_line "highlightBRK${i}_ACT" "highlightBRK${i}_DIS" $brkType($i)
} else {
highlightLine $code_line "highlightBRK${i}_DIS" "highlightBRK${i}_ACT" $brkType($i)
}
}
 
}
}
 
proc updateCodeView { bin_file_name } {
proc waitForFile {fileName} {
 
# Wait until file is present on the filesystem
set timeout 1000
for {set i 0} {$i <= $timeout} {incr i} {
after 50
if {[file exists $fileName]} {
return 1
}
}
return 0
}
 
proc updateCodeView {} {
global codeSelect
global reg
global binFileType
global binFileName
global pmemIHEX
global brkpt
global isPmemRead
 
set temp_elf_file "[clock clicks].elf"
if {[catch {exec msp430-objcopy -I $binFileType -O elf32-msp430 $bin_file_name $temp_elf_file} debug_info]} {
.ctrl.load.fb.l configure -text "$debug_info" -fg red
return 0
if {($binFileName!="") | ($isPmemRead==1)} {
 
if {$isPmemRead==1} {
 
set currentFileType ihex
set currentFileName "[expr [clock clicks] ^ 0xffffffff].ihex"
 
set fileId [open $currentFileName "w"]
puts -nonewline $fileId $pmemIHEX
close $fileId
if {![waitForFile $currentFileName]} {
.ctrl.load.info.l configure -text "Timeout: error writing temprary IHEX file" -fg red
return 0
}
 
} else {
set currentFileType $binFileType
set currentFileName $binFileName
}
 
set temp_elf_file "[clock clicks].elf"
set temp_ihex_file "[clock clicks].ihex"
if {[catch {exec msp430-objcopy -I $currentFileType -O elf32-msp430 $currentFileName $temp_elf_file} debug_info]} {
.ctrl.load.info.l configure -text "$debug_info" -fg red
return 0
}
if {![waitForFile $temp_elf_file]} {
.ctrl.load.info.l configure -text "Timeout: ELF file conversion problem with \"msp430-objcopy\" executable" -fg red
return 0
}
if {[string eq $currentFileType "ihex"]} {
set dumpOpt "-D"
} else {
set dumpOpt "-d"
}
 
if {$codeSelect==1} {
 
clearBreakpoints
for {set i 0} {$i<3} {incr i} {
set brkpt(en_$i) 0
.ctrl.cpu.brkpt.chk$i configure -state disable
updateBreakpoint $i
}
if {[catch {exec msp430-objcopy -I $currentFileType -O ihex $temp_elf_file $temp_ihex_file} debug_info]} {
.ctrl.load.info.l configure -text "$debug_info" -fg red
return 0
}
if {![waitForFile $temp_ihex_file]} {
.ctrl.load.info.l configure -text "Timeout: IHEX file conversion problem with \"msp430-objcopy\" executable" -fg red
return 0
}
set fp [open $temp_ihex_file r]
set debug_info [read $fp]
close $fp
file delete $temp_ihex_file
 
} elseif {$codeSelect==2} {
for {set i 0} {$i<3} {incr i} {
.ctrl.cpu.brkpt.chk$i configure -state normal
}
if {[catch {exec msp430-objdump $dumpOpt $temp_elf_file} debug_info]} {
.ctrl.load.info.l configure -text "$debug_info" -fg red
return 0
}
} elseif {$codeSelect==3} {
for {set i 0} {$i<3} {incr i} {
.ctrl.cpu.brkpt.chk$i configure -state normal
}
if {[catch {exec msp430-objdump $dumpOpt\S $temp_elf_file} debug_info]} {
.ctrl.load.info.l configure -text "$debug_info" -fg red
return 0
}
}
file delete $temp_elf_file
if {$isPmemRead==1} {
file delet $currentFileName
}
 
.code.text configure -state normal
.code.text delete 1.0 end
.code.text insert end $debug_info
highlightCode
.code.text configure -state disabled
return 1
}
if {[string eq $binFileType "ihex"]} {
set dumpOpt "-D"
} else {
set dumpOpt "-d"
}
}
 
if {$codeSelect==1} {
set debug_info ""
clearBreakpoints
for {set i 0} {$i<3} {incr i} {
set brkpt(en_$i) 0
updateBreakpoint $i
}
proc bin2ihex {startAddr binData } {
 
} elseif {$codeSelect==2} {
if {[catch {exec msp430-objdump $dumpOpt $temp_elf_file} debug_info]} {
.ctrl.load.fb.l configure -text "$debug_info" -fg red
return 0
}
} elseif {$codeSelect==3} {
if {[catch {exec msp430-objdump $dumpOpt\S $temp_elf_file} debug_info]} {
.ctrl.load.fb.l configure -text "$debug_info" -fg red
return 0
}
set full_line_size 16
set full_line_nr [expr [llength $binData] / $full_line_size]
set last_line_size [expr [llength $binData] -($full_line_size*$full_line_nr)]
set line_nr $full_line_nr
if {$last_line_size!=0} {incr line_nr}
 
set ihex ""
 
for {set ii 0} {$ii<$line_nr} {incr ii} {
 
set line_size $full_line_size
if {$ii==$full_line_nr} {
set line_size $last_line_size
}
 
set currentAddr [expr $startAddr+($full_line_size*$ii)]
set chksum $line_size
set chksum [expr $chksum+($currentAddr/256)+($currentAddr&255)]
append ihex ":"
append ihex [format "%02x" $line_size]
append ihex [format "%04x" $currentAddr]
append ihex "00"
for {set jj 0} {$jj<$line_size} {incr jj} {
set byte [lindex $binData [expr ($full_line_size*$ii)+$jj]]
set chksum [expr $chksum + $byte]
append ihex [format "%02x" $byte]
}
append ihex [format "%02x\n" [expr 255 & (0x100 - $chksum)]]
}
file delete $temp_elf_file
append ihex ":00000001FF\n"
set ihex [string toupper $ihex]
return $ihex
}
 
.code.text configure -state normal
.code.text delete 1.0 end
.code.text insert end $debug_info
highlightCode
.code.text configure -state disabled
return 1
proc readPmem {} {
 
global CpuNr
global pmemIHEX
global mem_sizes
global isPmemRead
# Get program memory start address
set startAddr [format "0x%04x" [expr 0x10000-[lindex $mem_sizes 0]]]
 
# Retrieve the program memory content
clearBreakpoints
set binData [ReadMemQuick8 $CpuNr $startAddr [lindex $mem_sizes 0]]
setBreakpoints
.ctrl.load.info.l configure -text "Program memory successfully read" -fg "\#00ae00"
 
# Update buttons
.ctrl.load.fb.load configure -fg "\#000000" -activeforeground "\#000000"
.ctrl.load.fb.open configure -fg "\#000000" -activeforeground "\#000000"
.ctrl.load.fb.readpmem configure -fg "\#909000" -activeforeground "\#909000"
update
 
# Convert the binary content into Intel-HEX format
set pmemIHEX [bin2ihex $startAddr $binData]
# Update debugger view
set isPmemRead 1
updateCodeView
 
}
 
proc loadProgram {bin_file_name} {
proc loadProgram {load} {
global current_file_name
global cpu_status
global reg
global mem
global mem_sizes
global binFileType
global binFileName
global brkpt
global CpuNr
global isPmemRead
global pmemIHEX
global backup
 
# Detect the file format depending on the fil extention
# Check if the file exists
#----------------------------------------
if {![file exists $current_file_name]} {
.ctrl.load.info.l configure -text "Specified file doesn't exists: \"$current_file_name\"" -fg red
return 0
}
 
# Eventually initialite other CPU path
for {set i 0} {$i<4} {incr i} {
if {$backup($i,current_file_name)==""} {
set backup($i,current_file_name) "[file dirname $current_file_name]/"
}
}
 
# Detect the file format depending on the file extention
#--------------------------------------------------------
set binFileType [file extension $bin_file_name]
set binFileType [file extension $current_file_name]
set binFileType [string tolower $binFileType]
regsub {\.} $binFileType {} binFileType
 
if {![string eq $binFileType "ihex"] & ![string eq $binFileType "hex"] & ![string eq $binFileType "elf"]} {
.ctrl.load.fb.l configure -text "[string toupper $binFileType] file format not supported\"" -fg red
return 0
.ctrl.load.info.l configure -text "[string toupper $binFileType] file format not supported\"" -fg red
return 0
}
 
# Check if the file exists
#----------------------------------------
if {![file exists $bin_file_name]} {
.ctrl.load.fb.l configure -text "[string toupper $binFileType] file doesn't exists: \"$bin_file_name\"" -fg red
return 0
}
if {[string eq $binFileType "hex"]} {
set binFileType "ihex"
set binFileType "ihex"
}
if {[string eq $binFileType "elf"]} {
set binFileType "elf32-msp430"
set binFileType "elf32-msp430"
}
 
 
# Create and read debug informations
#----------------------------------------
set binFileName $current_file_name
set isPmemRead 0
updateCodeView
 
updateCodeView $bin_file_name
# Update buttons
if {$load} {
.ctrl.load.fb.load configure -fg "\#909000" -activeforeground "\#909000"
.ctrl.load.fb.open configure -fg "\#000000" -activeforeground "\#000000"
} else {
.ctrl.load.fb.load configure -fg "\#000000" -activeforeground "\#000000"
.ctrl.load.fb.open configure -fg "\#909000" -activeforeground "\#909000"
}
.ctrl.load.fb.readpmem configure -fg "\#000000" -activeforeground "\#000000"
update
 
# Create and read binary executable file
#----------------------------------------
454,23 → 669,16
 
# Generate binary file
set bin_file "[clock clicks].bin"
if {[catch {exec msp430-objcopy -I $binFileType -O binary $bin_file_name $bin_file} errMsg]} {
.ctrl.load.fb.l configure -text "$errMsg" -fg red
return 0
if {[catch {exec msp430-objcopy -I $binFileType -O binary $binFileName $bin_file} errMsg]} {
.ctrl.load.info.l configure -text "$errMsg" -fg red
return 0
}
# Wait until bin file is present on the filesystem
set timeout 100
for {set i 0} {$i <= $timeout} {incr i} {
after 500
if {[file exists $bin_file]} {
break
}
if {![waitForFile $bin_file]} {
.ctrl.load.info.l configure -text "Timeout: ELF to BIN file conversion problem with \"msp430-objcopy\" executable" -fg red
return 0
}
if {$i>=$timeout} {
.ctrl.load.fb.l configure -text "Timeout: ELF to BIN file conversion problem with \"msp430-objcopy\" executable" -fg red
return 0
}
 
# Read file
set fp [open $bin_file r]
488,51 → 696,75
 
# Make sure ELF program size is the same as the available program memory
if {[lindex $mem_sizes 0] != [expr $hex_size/2]} {
.ctrl.load.fb.l configure -text "ERROR: ELF program size ([expr $hex_size/2] B) is different than the available program memory ([lindex $mem_sizes 0] B)" -fg red
return 0
.ctrl.load.info.l configure -text "ERROR: ELF program size ([expr $hex_size/2] B) is different than the available program memory ([lindex $mem_sizes 0] B)" -fg red
return 0
}
 
# Format data
for {set i 0} {$i < $hex_size} {set i [expr $i+4]} {
set hex_msb "[string index $hex_data [expr $i+2]][string index $hex_data [expr $i+3]]"
set hex_lsb "[string index $hex_data [expr $i+0]][string index $hex_data [expr $i+1]]"
lappend DataArray "0x$hex_msb$hex_lsb"
set hex_msb "[string index $hex_data [expr $i+2]][string index $hex_data [expr $i+3]]"
set hex_lsb "[string index $hex_data [expr $i+0]][string index $hex_data [expr $i+1]]"
lappend DataArray "0x$hex_msb$hex_lsb"
}
 
# Load program to openmsp430 target
#-----------------------------------
 
# Reset & Stop CPU
ExecutePOR_Halt
 
# Load Program Memory
# Get program memory start address
set StartAddr [format "0x%04x" [expr 0x10000-$byte_size]]
.ctrl.load.fb.l configure -text "Load..." -fg "\#cdad00"
update
WriteMemQuick $StartAddr $DataArray
 
# Clear active breakpoints
clearBreakpoints
 
if {$load==1} {
 
# Reset & Stop CPU
ExecutePOR_Halt $CpuNr
 
# Load Program Memory
.ctrl.load.info.l configure -text "Load..." -fg "\#cdad00"
update
WriteMemQuick $CpuNr $StartAddr $DataArray
}
 
# Verify program memory of the openmsp430 target
#------------------------------------------------
 
# Check Data
.ctrl.load.fb.l configure -text "Verify..." -fg "\#cdad00"
.ctrl.load.info.l configure -text "Verify..." -fg "\#cdad00"
update
if {[VerifyMem $StartAddr $DataArray 1]} {
.ctrl.load.fb.l configure -text "Done" -fg "\#00ae00"
} else {
.ctrl.load.fb.l configure -text "ERROR" -fg red
if {[VerifyMem $CpuNr $StartAddr $DataArray 1]} {
if {$load==1} {
.ctrl.load.info.l configure -text "Binary file successfully loaded" -fg "\#00ae00"
} else {
.ctrl.load.info.l configure -text "Binary file successfully opened" -fg "\#00ae00"
setBreakpoints
}
set pmemIHEX ""
} else {
if {$load==1} {
.ctrl.load.info.l configure -text "ERROR while loading the firmware " -fg red
} else {
.ctrl.load.info.l configure -text "ERROR: Specified binary file doesn't match the program memory content" -fg red
setBreakpoints
}
}
update
 
# Re-initialize breakpoints
for {set i 0} {$i<3} {incr i} {
.ctrl.cpu.brkpt.addr$i configure -state normal
set brkpt(en_$i) 0
if {$load==1} {
# Re-initialize breakpoints
for {set i 0} {$i<3} {incr i} {
.ctrl.cpu.brkpt.addr$i configure -state normal
set brkpt(en_$i) 0
}
 
# Reset & Stop CPU
ExecutePOR_Halt $CpuNr
.ctrl.cpu.cpu.step configure -state normal
.ctrl.cpu.cpu.run configure -text "Run"
.ctrl.cpu.cpu.l3 configure -text "Stopped" -fg "\#cdad00"
set cpu_status 0
}
 
# Reset & Stop CPU
ExecutePOR_Halt
.ctrl.cpu.cpu.step configure -state normal
.ctrl.cpu.cpu.run configure -text "Run"
.ctrl.cpu.cpu.l3 configure -text "Stopped" -fg "\#cdad00"
set cpu_status 0
refreshReg
refreshMem
}
541,22 → 773,23
global cpu_status
global reg
global mem
global CpuNr
 
if {$cpu_status} {
HaltCPU
.ctrl.cpu.cpu.step configure -state normal
.ctrl.cpu.cpu.run configure -text "Run"
.ctrl.cpu.cpu.l3 configure -text "Stopped" -fg "\#cdad00"
set cpu_status 0
HaltCPU $CpuNr
.ctrl.cpu.cpu.step configure -state normal
.ctrl.cpu.cpu.run configure -text "Run"
.ctrl.cpu.cpu.l3 configure -text "Stopped" -fg "\#cdad00"
set cpu_status 0
} else {
clearBreakpoints
StepCPU
setBreakpoints
ReleaseCPU
.ctrl.cpu.cpu.step configure -state disabled
.ctrl.cpu.cpu.run configure -text "Stop"
.ctrl.cpu.cpu.l3 configure -text "Running" -fg "\#00ae00"
set cpu_status 1
clearBreakpoints
StepCPU $CpuNr
setBreakpoints
ReleaseCPU $CpuNr
.ctrl.cpu.cpu.step configure -state disabled
.ctrl.cpu.cpu.run configure -text "Stop"
.ctrl.cpu.cpu.l3 configure -text "Running" -fg "\#00ae00"
set cpu_status 1
}
refreshReg
refreshMem
566,11 → 799,12
global cpu_status
global reg
global mem
global CpuNr
 
if {$cpu_status} {
ExecutePOR
ExecutePOR $CpuNr
} else {
ExecutePOR_Halt
ExecutePOR_Halt $CpuNr
}
refreshReg
refreshMem
580,11 → 814,12
global cpu_status
global reg
global mem
global CpuNr
 
if {$cpu_status==0} {
clearBreakpoints
StepCPU
setBreakpoints
clearBreakpoints
StepCPU $CpuNr
setBreakpoints
}
refreshReg
refreshMem
603,7 → 838,7
($sr(gie) * 0x0008) | \
($sr(n) * 0x0004) | \
($sr(z) * 0x0002) | \
($sr(c) * 0x0001)]
($sr(c) * 0x0001)]
 
set reg(2) [format "0x%04x" $tmp_reg]
 
615,11 → 850,12
global reg
global mem
global sr
global CpuNr
 
# Read register values
set new_vals [ReadRegAll]
set new_vals [ReadRegAll $CpuNr]
for {set i 0} {$i<16} {incr i} {
set reg($i) [lindex $new_vals $i]
set reg($i) [lindex $new_vals $i]
}
set sr(c) [expr $reg(2) & 0x0001]
set sr(z) [expr $reg(2) & 0x0002]
637,8 → 873,9
proc write2Reg {reg_num} {
global reg
global mem
global CpuNr
 
WriteReg $reg_num $reg($reg_num)
WriteReg $CpuNr $reg_num $reg($reg_num)
refreshReg
refreshMem
}
646,17 → 883,18
proc refreshMem {} {
global reg
global mem
global CpuNr
 
for {set i 0} {$i<16} {incr i} {
# Check if address lay in 16 or 8 bit space
if {[expr $mem(address_$i)]>=[expr 0x100]} {
set Format 0
} else {
set Format 1
}
# Check if address lay in 16 or 8 bit space
if {[expr $mem(address_$i)]>=[expr 0x100]} {
set Format 0
} else {
set Format 1
}
 
# Read data
set mem(data_$i) [ReadMem $Format $mem(address_$i)]
# Read data
set mem(data_$i) [ReadMem $CpuNr $Format $mem(address_$i)]
}
}
 
663,15 → 901,16
proc write2Mem {mem_num} {
global reg
global mem
global CpuNr
 
# Check if address lay in 16 or 8 bit space
if {[expr $mem(address_$mem_num)]>=[expr 0x100]} {
set Format 0
set Format 0
} else {
set Format 1
set Format 1
}
 
WriteMem $Format $mem(address_$mem_num) $mem(data_$mem_num)
WriteMem $CpuNr $Format $mem(address_$mem_num) $mem(data_$mem_num)
refreshReg
refreshMem
}
679,34 → 918,38
proc updateBreakpoint {brkpt_num} {
global brkpt
global mem_sizes
global CpuNr
 
# Set the breakpoint
if {$brkpt(en_$brkpt_num)==1} {
# Make sure the specified address is an opcode
regsub {0x} $brkpt(addr_$brkpt_num) {} brkpt_val
set code_match [.code.text search "$brkpt_val:" 1.0 end]
if {![string length $code_match]} {
.ctrl.cpu.brkpt.addr$brkpt_num configure -state normal
set brkpt(en_$brkpt_num) 0
# Make sure the specified address is an opcode
regsub {0x} $brkpt(addr_$brkpt_num) {} brkpt_val
set code_match [.code.text search "$brkpt_val:" 1.0 end]
if {![string length $code_match]} {
.ctrl.cpu.brkpt.addr$brkpt_num configure -state normal
set brkpt(en_$brkpt_num) 0
 
} else {
set brkpt(data_$brkpt_num) [ReadMem 0 $brkpt(addr_$brkpt_num)]
# Only set a breakpoint if there is not already one there :-P
if {$brkpt(data_$brkpt_num)=="0x4343"} {
.ctrl.cpu.brkpt.addr$brkpt_num configure -state normal
set brkpt(en_$brkpt_num) 0
} else {
.ctrl.cpu.brkpt.addr$brkpt_num configure -state readonly
WriteMem 0 $brkpt(addr_$brkpt_num) 0x4343
}
}
} else {
set brkpt(data_$brkpt_num) [ReadMem $CpuNr 0 $brkpt(addr_$brkpt_num)]
# Only set a breakpoint if there is not already one there :-P
if {$brkpt(data_$brkpt_num)=="0x4343"} {
.ctrl.cpu.brkpt.addr$brkpt_num configure -state normal
set brkpt(en_$brkpt_num) 0
} else {
.ctrl.cpu.brkpt.addr$brkpt_num configure -state readonly
WriteMem $CpuNr 0 $brkpt(addr_$brkpt_num) 0x4343
}
}
 
# Clear the breakpoint
} else {
.ctrl.cpu.brkpt.addr$brkpt_num configure -state normal
WriteMem 0 $brkpt(addr_$brkpt_num) $brkpt(data_$brkpt_num)
.ctrl.cpu.brkpt.addr$brkpt_num configure -state normal
set opcode [ReadMem $CpuNr 0 $brkpt(addr_$brkpt_num)]
if {$opcode=="0x4343"} {
WriteMem $CpuNr 0 $brkpt(addr_$brkpt_num) $brkpt(data_$brkpt_num)
}
}
 
highlightCode
713,13 → 956,17
}
 
proc clearBreakpoints {} {
global connection_status
global brkpt
global mem_sizes
global CpuNr
 
for {set i 0} {$i<3} {incr i} {
if {$brkpt(en_$i)==1} {
WriteMem 0 $brkpt(addr_$i) $brkpt(data_$i)
}
if {$connection_status} {
for {set i 0} {$i<3} {incr i} {
if {$brkpt(en_$i)==1} {
WriteMem $CpuNr 0 $brkpt(addr_$i) $brkpt(data_$i)
}
}
}
}
 
726,17 → 973,368
proc setBreakpoints {} {
global brkpt
global mem_sizes
global CpuNr
 
for {set i 0} {$i<3} {incr i} {
if {$brkpt(en_$i)==1} {
set brkpt(data_$i) [ReadMem 0 $brkpt(addr_$i)]
WriteMem 0 $brkpt(addr_$i) 0x4343
}
if {$brkpt(en_$i)==1} {
set brkpt(data_$i) [ReadMem $CpuNr 0 $brkpt(addr_$i)]
WriteMem $CpuNr 0 $brkpt(addr_$i) 0x4343
}
}
}
 
proc selectCPU {CpuNr_next} {
 
global CpuNr
 
# Read current font
set font [.menu.cpu1 cget -font]
set family [font actual $font -family];
set size [font actual $font -size];
set slant [font actual $font -slant];
set underline [font actual $font -underline];
set overstrike [font actual $font -overstrike];
 
# Create normal font
set font_normal "-family $family -size $size -weight normal -slant $slant -underline $underline -overstrike $overstrike"
 
# Create bold font
set font_bold "-family $family -size $size -weight bold -slant $slant -underline $underline -overstrike $overstrike"
 
if {$CpuNr_next==0} {
.menu.cpu0 configure -relief sunken -font $font_bold -fg "\#00ae00" -activeforeground "\#00ae00"
.menu.cpu1 configure -relief raised -font $font_normal -fg "\#000000" -activeforeground "\#000000"
.menu.cpu2 configure -relief raised -font $font_normal -fg "\#000000" -activeforeground "\#000000"
.menu.cpu3 configure -relief raised -font $font_normal -fg "\#000000" -activeforeground "\#000000"
 
} elseif {$CpuNr_next==1} {
.menu.cpu0 configure -relief raised -font $font_normal -fg "\#000000" -activeforeground "\#000000"
.menu.cpu1 configure -relief sunken -font $font_bold -fg "\#00ae00" -activeforeground "\#00ae00"
.menu.cpu2 configure -relief raised -font $font_normal -fg "\#000000" -activeforeground "\#000000"
.menu.cpu3 configure -relief raised -font $font_normal -fg "\#000000" -activeforeground "\#000000"
 
} elseif {$CpuNr_next==2} {
.menu.cpu0 configure -relief raised -font $font_normal -fg "\#000000" -activeforeground "\#000000"
.menu.cpu1 configure -relief raised -font $font_normal -fg "\#000000" -activeforeground "\#000000"
.menu.cpu2 configure -relief sunken -font $font_bold -fg "\#00ae00" -activeforeground "\#00ae00"
.menu.cpu3 configure -relief raised -font $font_normal -fg "\#000000" -activeforeground "\#000000"
 
} else {
.menu.cpu0 configure -relief raised -font $font_normal -fg "\#000000" -activeforeground "\#000000"
.menu.cpu1 configure -relief raised -font $font_normal -fg "\#000000" -activeforeground "\#000000"
.menu.cpu2 configure -relief raised -font $font_normal -fg "\#000000" -activeforeground "\#000000"
.menu.cpu3 configure -relief sunken -font $font_bold -fg "\#00ae00" -activeforeground "\#00ae00"
}
 
saveContext $CpuNr
set CpuNr $CpuNr_next
restoreContext $CpuNr
 
return 1
}
 
proc advancedConfiguration {} {
 
global omsp_info
global omsp_conf
global omsp_nr
 
# Initialize temp variables
global temp_nrcore
global temp_if
global temp_adapt
global temp_addr
regexp {(.+)_(.+)} $omsp_conf(interface) whole_match temp_if temp_adapt
set temp_if [string toupper $temp_if]
set temp_adapt [string toupper $temp_adapt]
set temp_nrcore $omsp_nr
set temp_addr(0) $omsp_conf(0,cpuaddr)
set temp_addr(1) $omsp_conf(1,cpuaddr)
set temp_addr(2) $omsp_conf(2,cpuaddr)
set temp_addr(3) $omsp_conf(3,cpuaddr)
 
# Destroy windows if already existing
if {[lsearch -exact [winfo children .] .omsp_adapt_config]!=-1} {
destroy .omsp_adapt_config
}
 
# Create master window
toplevel .omsp_adapt_config
wm title .omsp_adapt_config "Advanced configuration"
wm geometry .omsp_adapt_config +380+200
wm resizable .omsp_adapt_config 0 0
 
# Title
label .omsp_adapt_config.title -text "Advanced configuration" -anchor center -fg "\#ae0000" -font {-weight bold -size 16}
pack .omsp_adapt_config.title -side top -padx {20 20} -pady {20 10}
 
# Create the main configuration area
frame .omsp_adapt_config.main -bd 2
pack .omsp_adapt_config.main -side top -padx 10 -pady 10
 
# Create the ok/cancel area
frame .omsp_adapt_config.ok -bd 2
pack .omsp_adapt_config.ok -side top -padx 10 -pady 10
 
 
# Create the Adapter Menu
frame .omsp_adapt_config.main.adapter -bd 2 -relief ridge
pack .omsp_adapt_config.main.adapter -side left -padx 10 -pady 10 -fill both
 
# Create the I2C Menu
frame .omsp_adapt_config.main.i2c -bd 2 -relief ridge
pack .omsp_adapt_config.main.i2c -side right -padx 10 -pady 10 -fill both
 
 
# Adapter stuff
label .omsp_adapt_config.main.adapter.title -text "Adapter configuration" -anchor center -fg "\#000000" -font {-weight bold -size 12}
pack .omsp_adapt_config.main.adapter.title -side top -padx 10 -pady 10
frame .omsp_adapt_config.main.adapter.ser
pack .omsp_adapt_config.main.adapter.ser -side top -padx 10 -pady 10
 
label .omsp_adapt_config.main.adapter.ser.l -text "Serial Debug Interface:" -anchor center
pack .omsp_adapt_config.main.adapter.ser.l -side left
combobox .omsp_adapt_config.main.adapter.ser.p -textvariable temp_if -editable false -width 10 -command {updateAdvancedConfiguration}
eval .omsp_adapt_config.main.adapter.ser.p list insert end [list "UART" "I2C"]
pack .omsp_adapt_config.main.adapter.ser.p -side right -padx 5
 
frame .omsp_adapt_config.main.adapter.ada
pack .omsp_adapt_config.main.adapter.ada -side top -padx 10 -pady 10 -fill x
 
label .omsp_adapt_config.main.adapter.ada.l -text "Adapter selection:" -anchor w
pack .omsp_adapt_config.main.adapter.ada.l -side left
combobox .omsp_adapt_config.main.adapter.ada.p -textvariable temp_adapt -editable false -width 10
eval .omsp_adapt_config.main.adapter.ada.p list insert end [list "GENERIC"]
pack .omsp_adapt_config.main.adapter.ada.p -side right -padx 5
 
 
# I2C stuff
label .omsp_adapt_config.main.i2c.title -text "I2C configuration" -anchor center -fg "\#000000" -font {-weight bold -size 12}
pack .omsp_adapt_config.main.i2c.title -side top -padx 10 -pady 10
frame .omsp_adapt_config.main.i2c.cpunr
pack .omsp_adapt_config.main.i2c.cpunr -side top -padx 10 -pady 10 -fill x
label .omsp_adapt_config.main.i2c.cpunr.l -text "Number of cores:" -anchor w
pack .omsp_adapt_config.main.i2c.cpunr.l -side left -padx 5
spinbox .omsp_adapt_config.main.i2c.cpunr.s -from 1 -to 4 -textvariable temp_nrcore -state readonly -width 4 -command {updateAdvancedConfiguration}
pack .omsp_adapt_config.main.i2c.cpunr.s -side right -padx 5
 
frame .omsp_adapt_config.main.i2c.cpu0
pack .omsp_adapt_config.main.i2c.cpu0 -side top -padx 10 -pady 10 -fill x
label .omsp_adapt_config.main.i2c.cpu0.l -text "I2C Address (Core 0):" -anchor w
pack .omsp_adapt_config.main.i2c.cpu0.l -side left -padx 5
spinbox .omsp_adapt_config.main.i2c.cpu0.s -from 8 -to 119 -textvariable temp_addr(0) -width 4
pack .omsp_adapt_config.main.i2c.cpu0.s -side right -padx 5
 
frame .omsp_adapt_config.main.i2c.cpu1
pack .omsp_adapt_config.main.i2c.cpu1 -side top -padx 10 -pady 10 -fill x
label .omsp_adapt_config.main.i2c.cpu1.l -text "I2C Address (Core 1):" -anchor w
pack .omsp_adapt_config.main.i2c.cpu1.l -side left -padx 5
spinbox .omsp_adapt_config.main.i2c.cpu1.s -from 8 -to 119 -textvariable temp_addr(1) -width 4
pack .omsp_adapt_config.main.i2c.cpu1.s -side right -padx 5
 
frame .omsp_adapt_config.main.i2c.cpu2
pack .omsp_adapt_config.main.i2c.cpu2 -side top -padx 10 -pady 10 -fill x
label .omsp_adapt_config.main.i2c.cpu2.l -text "I2C Address (Core 2):" -anchor w
pack .omsp_adapt_config.main.i2c.cpu2.l -side left -padx 5
spinbox .omsp_adapt_config.main.i2c.cpu2.s -from 8 -to 119 -textvariable temp_addr(2) -width 4
pack .omsp_adapt_config.main.i2c.cpu2.s -side right -padx 5
 
frame .omsp_adapt_config.main.i2c.cpu3
pack .omsp_adapt_config.main.i2c.cpu3 -side top -padx 10 -pady 10 -fill x
label .omsp_adapt_config.main.i2c.cpu3.l -text "I2C Address (Core 3):" -anchor w
pack .omsp_adapt_config.main.i2c.cpu3.l -side left -padx 5
spinbox .omsp_adapt_config.main.i2c.cpu3.s -from 8 -to 119 -textvariable temp_addr(3) -width 4
pack .omsp_adapt_config.main.i2c.cpu3.s -side right -padx 5
 
 
# Create OK/Cancel button
button .omsp_adapt_config.ok.okay -text "OK" -command {set omsp_conf(interface) [string tolower "${temp_if}_${temp_adapt}"]
set omsp_nr $temp_nrcore;
set omsp_conf(0,cpuaddr) $temp_addr(0);
set omsp_conf(1,cpuaddr) $temp_addr(1);
set omsp_conf(2,cpuaddr) $temp_addr(2);
set omsp_conf(3,cpuaddr) $temp_addr(3);
.ctrl.connect.serial.p2 configure -editable 1;
eval .ctrl.connect.serial.p2 list delete 0 end;
eval .ctrl.connect.serial.p2 list insert end [lindex [GetAllowedSpeeds] 2];
set omsp_conf(baudrate) [lindex [GetAllowedSpeeds] 1];
.ctrl.connect.serial.p2 configure -editable [lindex [GetAllowedSpeeds] 0];
destroy .omsp_adapt_config}
pack .omsp_adapt_config.ok.okay -side bottom -side left -expand true -fill x -padx 5 -pady 10
button .omsp_adapt_config.ok.cancel -text "CANCEL" -command {destroy .omsp_adapt_config}
pack .omsp_adapt_config.ok.cancel -side bottom -side right -expand true -fill x -padx 5 -pady 10
 
updateAdvancedConfiguration
}
 
proc updateAdvancedConfiguration {{w ""} {sel ""}} {
 
global temp_if
global temp_adapt
global temp_nrcore
global connection_status
 
if {$connection_status} {
.omsp_adapt_config.main.adapter.ser.p configure -state disabled
.omsp_adapt_config.main.adapter.ada.p configure -state disabled
.omsp_adapt_config.main.i2c.cpunr.s configure -state disabled
.omsp_adapt_config.main.i2c.cpu0.s configure -state disabled
.omsp_adapt_config.main.i2c.cpu1.s configure -state disabled
.omsp_adapt_config.main.i2c.cpu2.s configure -state disabled
.omsp_adapt_config.main.i2c.cpu3.s configure -state disabled
 
} else {
if {$sel=="UART"} {
eval .omsp_adapt_config.main.adapter.ada.p list delete 0 end
eval .omsp_adapt_config.main.adapter.ada.p list insert end [list "GENERIC"]
set temp_adapt "GENERIC"
 
} elseif {$sel=="I2C"} {
 
eval .omsp_adapt_config.main.adapter.ada.p list delete 0 end
eval .omsp_adapt_config.main.adapter.ada.p list insert end [list "USB-ISS"]
set temp_adapt "USB-ISS"
 
}
 
if {$temp_if=="UART"} {
 
.omsp_adapt_config.main.i2c.cpunr.s configure -state disabled
.omsp_adapt_config.main.i2c.cpu0.s configure -state disabled
.omsp_adapt_config.main.i2c.cpu1.s configure -state disabled
.omsp_adapt_config.main.i2c.cpu2.s configure -state disabled
.omsp_adapt_config.main.i2c.cpu3.s configure -state disabled
 
} elseif {$temp_if=="I2C"} {
 
.omsp_adapt_config.main.i2c.cpunr.s configure -state disabled
# .omsp_adapt_config.main.i2c.cpunr.s configure -state normal
.omsp_adapt_config.main.i2c.cpu0.s configure -state normal
 
if {$temp_nrcore < 2} {.omsp_adapt_config.main.i2c.cpu1.s configure -state disabled
} else {.omsp_adapt_config.main.i2c.cpu1.s configure -state normal}
if {$temp_nrcore < 3} {.omsp_adapt_config.main.i2c.cpu2.s configure -state disabled
} else {.omsp_adapt_config.main.i2c.cpu2.s configure -state normal}
if {$temp_nrcore < 4} {.omsp_adapt_config.main.i2c.cpu3.s configure -state disabled
} else {.omsp_adapt_config.main.i2c.cpu3.s configure -state normal}
 
}
}
}
 
proc saveContext {CpuNr} {
 
global current_file_name
global brkpt
global mem
global mem_sizes
global codeSelect
global isPmemRead
global binFileType
global binFileName
global pmemIHEX
 
global backup
 
set backup($CpuNr,current_file_name) $current_file_name
 
set backup($CpuNr,load_color) [.ctrl.load.fb.load cget -fg]
set backup($CpuNr,open_color) [.ctrl.load.fb.open cget -fg]
set backup($CpuNr,readpmem_color) [.ctrl.load.fb.readpmem cget -fg]
 
set backup($CpuNr,info_text) [.ctrl.load.info.l cget -text]
set backup($CpuNr,info_color) [.ctrl.load.info.l cget -fg]
 
for {set i 0} {$i<3} {incr i} {
set backup($CpuNr,brkpt_addr_$i) $brkpt(addr_$i)
set backup($CpuNr,brkpt_en_$i) $brkpt(en_$i)
set backup($CpuNr,brkpt_readonly_$i) [.ctrl.cpu.brkpt.addr$i cget -state]
}
 
for {set i 0} {$i<16} {incr i} {
set backup($CpuNr,mem_addr_$i) $mem(address_$i)
}
set backup($CpuNr,mem_sizes) $mem_sizes
 
set backup($CpuNr,codeSelect) $codeSelect
set backup($CpuNr,isPmemRead) $isPmemRead
set backup($CpuNr,binFileType) $binFileType
set backup($CpuNr,binFileName) $binFileName
set backup($CpuNr,pmemIHEX) $pmemIHEX
 
return 1
}
 
proc restoreContext {CpuNr} {
 
global current_file_name
global brkpt
global mem
global mem_sizes
global codeSelect
global isPmemRead
global binFileType
global binFileName
global pmemIHEX
global cpu_status
global connection_status
 
global backup
 
set pmemIHEX $backup($CpuNr,pmemIHEX)
set binFileName $backup($CpuNr,binFileName)
set binFileType $backup($CpuNr,binFileType)
set isPmemRead $backup($CpuNr,isPmemRead)
set codeSelect $backup($CpuNr,codeSelect)
for {set i 0} {$i<16} {incr i} {
set mem(address_$i) $backup($CpuNr,mem_addr_$i)
}
set mem_sizes $backup($CpuNr,mem_sizes)
 
for {set i 0} {$i<3} {incr i} {
set brkpt(addr_$i) $backup($CpuNr,brkpt_addr_$i)
set brkpt(en_$i) $backup($CpuNr,brkpt_en_$i)
.ctrl.cpu.brkpt.addr$i configure -state $backup($CpuNr,brkpt_readonly_$i)
}
 
.ctrl.load.info.l configure -text $backup($CpuNr,info_text)
.ctrl.load.info.l configure -fg $backup($CpuNr,info_color)
 
.ctrl.load.fb.load configure -fg $backup($CpuNr,load_color) -activeforeground $backup($CpuNr,load_color)
.ctrl.load.fb.open configure -fg $backup($CpuNr,open_color) -activeforeground $backup($CpuNr,open_color)
.ctrl.load.fb.readpmem configure -fg $backup($CpuNr,readpmem_color) -activeforeground $backup($CpuNr,readpmem_color)
 
set current_file_name $backup($CpuNr,current_file_name)
 
update
 
if {$connection_status} {
if {[IsHalted $CpuNr]} {
.ctrl.cpu.cpu.step configure -state normal
.ctrl.cpu.cpu.run configure -text "Run"
.ctrl.cpu.cpu.l3 configure -text "Stopped" -fg "\#cdad00"
set cpu_status 0
} else {
.ctrl.cpu.cpu.step configure -state disabled
.ctrl.cpu.cpu.run configure -text "Stop"
.ctrl.cpu.cpu.l3 configure -text "Running" -fg "\#00ae00"
set cpu_status 1
}
refreshReg
refreshMem
.code.text configure -state normal
.code.text delete 1.0 end
.code.text configure -state disabled
updateCodeView
}
 
return 1
}
 
###############################################################################
# #
# CREATE GRAPHICAL INTERFACE #
752,61 → 1350,61
 
# Create the Main Menu
frame .menu
pack .menu -side top -padx 10 -pady 10 -fill x
pack .menu -side top -padx 10 -pady 10 -fill x
 
# Create the CPU Control field
frame .ctrl
pack .ctrl -side left -padx {5 0} -pady 10 -fill both
pack .ctrl -side left -padx {5 0} -pady 10 -fill both
 
# Create the Code text field
frame .code
pack .code -side right -padx 5 -pady 10 -fill both -expand true
pack .code -side right -padx 5 -pady 10 -fill both -expand true
frame .code.rb
pack .code.rb -side bottom -padx 10 -pady 10 -fill both
pack .code.rb -side bottom -padx 10 -pady 10 -fill both
 
# Create the connection frame
frame .ctrl.connect -bd 2 -relief ridge ;# solid
pack .ctrl.connect -side top -padx 10 -pady 0 -fill x
frame .ctrl.connect -bd 2 -relief ridge ;# solid
pack .ctrl.connect -side top -padx 10 -pady 0 -fill x
 
# Create the Serial Menu
frame .ctrl.connect.serial
pack .ctrl.connect.serial -side top -padx 10 -pady {10 0} -fill x
pack .ctrl.connect.serial -side top -padx 10 -pady {10 0} -fill x
 
# Create the memory size
frame .ctrl.connect.info
pack .ctrl.connect.info -side top -padx 10 -pady {10 10} -fill x
pack .ctrl.connect.info -side top -padx 10 -pady {10 10} -fill x
 
# Create the Load executable field
frame .ctrl.load -bd 2 -relief ridge ;# solid
pack .ctrl.load -side top -padx 10 -pady {10 10} -fill x
frame .ctrl.load -bd 2 -relief ridge ;# solid
pack .ctrl.load -side top -padx 10 -pady {10 10} -fill x
 
# Create the cpu field
frame .ctrl.cpu -bd 2 -relief ridge ;# solid
pack .ctrl.cpu -side top -padx 10 -pady {0 10} -fill x
frame .ctrl.cpu -bd 2 -relief ridge ;# solid
pack .ctrl.cpu -side top -padx 10 -pady {0 10} -fill x
 
# Create the cpu control field
frame .ctrl.cpu.cpu
pack .ctrl.cpu.cpu -side top -padx 10 -pady {20 10} -fill x
pack .ctrl.cpu.cpu -side top -padx 10 -pady {20 10} -fill x
 
# Create the breakpoint control field
frame .ctrl.cpu.brkpt
pack .ctrl.cpu.brkpt -side top -padx 10 -pady {10 20} -fill x
pack .ctrl.cpu.brkpt -side top -padx 10 -pady {10 20} -fill x
 
# Create the cpu status field
frame .ctrl.cpu.reg_stat
pack .ctrl.cpu.reg_stat -side top -padx 10 -pady {10 10} -fill x
pack .ctrl.cpu.reg_stat -side top -padx 10 -pady {10 10} -fill x
 
# Create the cpu registers/memory fields
frame .ctrl.cpu.reg_mem
pack .ctrl.cpu.reg_mem -side top -padx 10 -pady {5 10} -fill x
pack .ctrl.cpu.reg_mem -side top -padx 10 -pady {5 10} -fill x
frame .ctrl.cpu.reg_mem.reg
pack .ctrl.cpu.reg_mem.reg -side left -padx {10 30} -fill x
pack .ctrl.cpu.reg_mem.reg -side left -padx {10 30} -fill x
frame .ctrl.cpu.reg_mem.mem
pack .ctrl.cpu.reg_mem.mem -side left -padx {30 10} -fill x
pack .ctrl.cpu.reg_mem.mem -side left -padx {30 10} -fill x
 
# Create the TCL script field
frame .ctrl.tclscript -bd 2 -relief ridge ;# solid
pack .ctrl.tclscript -side top -padx 10 -pady {0 20} -fill x
frame .ctrl.tclscript -bd 2 -relief ridge ;# solid
pack .ctrl.tclscript -side top -padx 10 -pady {0 20} -fill x
 
 
####################################
814,43 → 1412,54
####################################
 
# Exit button
button .menu.exit -text "Exit" -command {exit 0}
button .menu.exit -text "Exit" -command {clearBreakpoints; exit 0}
pack .menu.exit -side left
 
# CPU selection buttons
label .menu.cpusel -text "oMSP core Selection:" -anchor w -state disabled
pack .menu.cpusel -side left -padx "100 0"
button .menu.cpu0 -text "Core 0" -command {selectCPU 0} -state disabled
pack .menu.cpu0 -side left -padx 10
button .menu.cpu1 -text "Core 1" -command {selectCPU 1} -state disabled
pack .menu.cpu1 -side left -padx 10
button .menu.cpu2 -text "Core 2" -command {selectCPU 2} -state disabled
pack .menu.cpu2 -side left -padx 10
button .menu.cpu3 -text "Core 3" -command {selectCPU 3} -state disabled
pack .menu.cpu3 -side left -padx 10
 
# openMSP430 label
label .menu.omsp -text "openMSP430 mini debugger" -anchor center -fg "\#6a5acd" -font {-weight bold -size 16}
pack .menu.omsp -side right -padx 20
 
# Serial Port fields
label .ctrl.connect.serial.l1 -text "Serial Port:" -anchor w
label .ctrl.connect.serial.l1 -text "Device Port:" -anchor w
pack .ctrl.connect.serial.l1 -side left
set serial_device [lindex [dbg_list_uart] end]
combobox .ctrl.connect.serial.p1 -textvariable serial_device -editable true
eval .ctrl.connect.serial.p1 list insert end [dbg_list_uart]
combobox .ctrl.connect.serial.p1 -textvariable omsp_conf(device) -width 15 -editable true
eval .ctrl.connect.serial.p1 list insert end [utils::uart_port_list]
pack .ctrl.connect.serial.p1 -side left -padx 5
 
label .ctrl.connect.serial.l2 -text " Baudrate:" -anchor w
label .ctrl.connect.serial.l2 -text " Speed:" -anchor w
pack .ctrl.connect.serial.l2 -side left
set serial_baudrate 115200
combobox .ctrl.connect.serial.p2 -textvariable serial_baudrate -editable true
eval .ctrl.connect.serial.p2 list insert end [list 9600 19200 38400 57600 115200 \
230400 460800 500000 576000 921600 \
1000000 1152000 2000000]
combobox .ctrl.connect.serial.p2 -textvariable omsp_conf(baudrate) -width 14 -editable [lindex [GetAllowedSpeeds] 0]
eval .ctrl.connect.serial.p2 list insert end [lindex [GetAllowedSpeeds] 2]
pack .ctrl.connect.serial.p2 -side left -padx 5
 
button .ctrl.connect.serial.connect -text "Connect" -width 9 -command {connect_openMSP430}
pack .ctrl.connect.serial.connect -side right -padx 5
 
button .ctrl.connect.serial.extra -text "Advanced..." -width 10 -command {advancedConfiguration}
pack .ctrl.connect.serial.extra -side left -padx 10
 
# CPU status & info
frame .ctrl.connect.info.l1
pack .ctrl.connect.info.l1 -side top -padx 0 -pady {0 0} -fill x
frame .ctrl.connect.info.l1
pack .ctrl.connect.info.l1 -side top -padx 0 -pady {0 0} -fill x
 
label .ctrl.connect.info.l1.cpu -text "CPU Info:" -anchor w
pack .ctrl.connect.info.l1.cpu -side left -padx "0 10"
label .ctrl.connect.info.l1.con -text "Disconnected" -anchor w -fg Red
pack .ctrl.connect.info.l1.con -side left
button .ctrl.connect.info.l1.more -text "More..." -width 9 -command {displayMore} -state disabled
pack .ctrl.connect.info.l1.more -side right -padx 5
label .ctrl.connect.info.l1.cpu -text "CPU Info:" -anchor w
pack .ctrl.connect.info.l1.cpu -side left -padx "0 10"
label .ctrl.connect.info.l1.con -text "Disconnected" -anchor w -fg Red
pack .ctrl.connect.info.l1.con -side left
button .ctrl.connect.info.l1.more -text "More..." -width 9 -command {displayMore} -state disabled
pack .ctrl.connect.info.l1.more -side right -padx 5
 
 
# Load ELF file fields
858,16 → 1467,24
pack .ctrl.load.ft -side top -fill x -padx "10 0" -pady "10 0"
label .ctrl.load.ft.l -text "ELF file:" -state disabled
pack .ctrl.load.ft.l -side left -padx "0 10"
entry .ctrl.load.ft.file -width 58 -relief sunken -textvariable bin_file_name -state disabled
entry .ctrl.load.ft.file -width 58 -relief sunken -textvariable current_file_name -state disabled
pack .ctrl.load.ft.file -side left -padx 10
button .ctrl.load.ft.browse -text "Browse" -width 9 -state disabled -command {set bin_file_name [tk_getOpenFile -filetypes {{{ELF/Intel-Hex Files} {.elf .ihex .hex}} {{All Files} *}}]}
button .ctrl.load.ft.browse -text "Browse" -width 9 -state disabled -command {set current_file_name [tk_getOpenFile -filetypes {{{ELF/Intel-Hex Files} {.elf .ihex .hex}} {{All Files} *}}]}
pack .ctrl.load.ft.browse -side right -padx {5 15}
frame .ctrl.load.fb
pack .ctrl.load.fb -side top -fill x -padx "10 0" -pady "5 10"
button .ctrl.load.fb.read -text "Load ELF File !" -state disabled -command {loadProgram $bin_file_name}
pack .ctrl.load.fb.read -side left -padx 5 -fill x
label .ctrl.load.fb.l -text "Not loaded" -anchor w -fg Red -state disabled
pack .ctrl.load.fb.l -side left
pack .ctrl.load.fb -side top -fill x -padx "10 0" -pady "5 5"
button .ctrl.load.fb.load -text "Load ELF File !" -state disabled -command {loadProgram 1}
pack .ctrl.load.fb.load -side left -padx 5 -fill x
button .ctrl.load.fb.open -text "Open ELF File !" -state disabled -command {loadProgram 0}
pack .ctrl.load.fb.open -side left -padx 5 -fill x
button .ctrl.load.fb.readpmem -text "Read Program Memory !" -state disabled -command {readPmem}
pack .ctrl.load.fb.readpmem -side left -padx 5 -fill x
frame .ctrl.load.info
pack .ctrl.load.info -side top -fill x -padx "10 0" -pady "5 10"
label .ctrl.load.info.t -text "Firmware info:" -anchor w -state disabled
pack .ctrl.load.info.t -side left -padx "0 10"
label .ctrl.load.info.l -text "No info available" -anchor w -fg Red -state disabled
pack .ctrl.load.info.l -side left
 
# CPU Control
label .ctrl.cpu.cpu.l1 -text "CPU Control:" -anchor w -state disabled
932,10 → 1549,10
pack .ctrl.cpu.reg_mem.reg.title.e -side left
for {set i 0} {$i<16} {incr i} {
switch $i {
{0} {set reg_label "r0 (pc):"}
{1} {set reg_label "r1 (sp):"}
{2} {set reg_label "r2 (sr):"}
default {set reg_label "r$i:"}
{0} {set reg_label "r0 (pc):"}
{1} {set reg_label "r1 (sp):"}
{2} {set reg_label "r2 (sr):"}
default {set reg_label "r$i:"}
}
frame .ctrl.cpu.reg_mem.reg.f$i
pack .ctrl.cpu.reg_mem.reg.f$i -side top
992,11 → 1609,11
 
label .code.rb.txt -text "Code View:" -anchor w -state disabled
pack .code.rb.txt -side left
radiobutton .code.rb.none -value "1" -text "None" -state disabled -variable codeSelect -command { updateCodeView $bin_file_name }
radiobutton .code.rb.none -value "1" -text "IHEX" -state disabled -variable codeSelect -command {updateCodeView}
pack .code.rb.none -side left
radiobutton .code.rb.asm -value "2" -text "Assembler" -state disabled -variable codeSelect -command { updateCodeView $bin_file_name }
radiobutton .code.rb.asm -value "2" -text "Assembler" -state disabled -variable codeSelect -command {updateCodeView}
pack .code.rb.asm -side left
radiobutton .code.rb.mix -value "3" -text "C & Assembler" -state disabled -variable codeSelect -command { updateCodeView $bin_file_name }
radiobutton .code.rb.mix -value "3" -text "C & Assembler" -state disabled -variable codeSelect -command {updateCodeView}
pack .code.rb.mix -side left
 
 
1022,6 → 1639,7
#######################################
# PERIODICALLY CHECK THE CPU STATUS #
#######################################
selectCPU 0
 
while 1 {
 
1031,17 → 1649,16
vwait refresh_flag
 
# Check CPU status
if {$serial_status} {
if {$cpu_status} {
if {[IsHalted]} {
.ctrl.cpu.cpu.step configure -state normal
.ctrl.cpu.cpu.run configure -text "Run"
.ctrl.cpu.cpu.l3 configure -text "Stopped" -fg "\#cdad00"
set cpu_status 0
refreshReg
refreshMem
}
}
if {$connection_status} {
if {$cpu_status} {
if {[IsHalted $CpuNr]} {
.ctrl.cpu.cpu.step configure -state normal
.ctrl.cpu.cpu.run configure -text "Run"
.ctrl.cpu.cpu.l3 configure -text "Stopped" -fg "\#cdad00"
set cpu_status 0
refreshReg
refreshMem
}
}
}
}
 
/trunk/tools/bin/openmsp430-loader.tcl
34,41 → 34,69
# $LastChangedDate$
#------------------------------------------------------------------------------
 
global serial_baudrate
global serial_device
global omsp_conf
global omsp_info
 
###############################################################################
# SOURCE LIBRARIES #
###############################################################################
 
# Get library path
set current_file [info script]
if {[file type $current_file]=="link"} {
set current_file [file readlink $current_file]
}
set lib_path [file dirname $current_file]/../lib/tcl-lib
 
# Source library
source $lib_path/dbg_functions.tcl
source $lib_path/dbg_utils.tcl
 
 
###############################################################################
# PARAMETER CHECK #
###############################################################################
#proc GetAllowedSpeeds
 
proc help {} {
puts ""
puts "USAGE : openmsp430-loader.tcl \[-device <communication device>\] \[-baudrate <communication speed>\] <elf/ihex-file>"
puts "USAGE : openmsp430-loader.tcl \[-device <communication port>\]"
puts " \[-adaptor <adaptor type>\]"
puts " \[-speed <communication speed>\]"
puts " \[-i2c_addr <cpu address>\] <elf/ihex-file>"
puts ""
puts "Examples: openmsp430-loader.tcl -device /dev/ttyUSB0 -baudrate 9600 leds.elf"
puts " openmsp430-loader.tcl -device COM2: -baudrate 38400 ta_uart.ihex"
puts "DEFAULT : <communication port> = /dev/ttyUSB0"
puts " <adaptor type> = uart_generic"
puts " <communication speed> = 115200 (for UART) / I2C_S_100KHZ (for I2C)"
puts " <core address> = 42"
puts ""
puts "EXAMPLES: openmsp430-loader.tcl -device /dev/ttyUSB0 -adaptor uart_generic -speed 9600 leds.elf"
puts " openmsp430-loader.tcl -device COM2: -adaptor i2c_usb-iss -speed I2C_S_100KHZ -i2c_addr 75 ta_uart.ihex"
puts ""
}
 
# Default values
set serial_device /dev/ttyUSB0
set serial_baudrate 115200
set elf_file -1
set bin_file "[clock clicks].bin"
set omsp_conf(interface) uart_generic
set omsp_conf(device) /dev/ttyUSB0
set omsp_conf(baudrate) [lindex [GetAllowedSpeeds] 1]
set omsp_conf(0,cpuaddr) 42
set elf_file -1
set bin_file "[clock clicks].bin"
 
# Parse arguments
for {set i 0} {$i < $argc} {incr i} {
switch -exact -- [lindex $argv $i] {
-device {set serial_device [lindex $argv [expr $i+1]]; incr i}
-baudrate {set serial_baudrate [lindex $argv [expr $i+1]]; incr i}
default {set elf_file [lindex $argv $i]}
-device {set omsp_conf(device) [lindex $argv [expr $i+1]]; incr i}
-adaptor {set omsp_conf(interface) [lindex $argv [expr $i+1]]; incr i}
-speed {set omsp_conf(baudrate) [lindex $argv [expr $i+1]]; incr i}
-i2c_addr {set omsp_conf(0,cpuaddr) [lindex $argv [expr $i+1]]; incr i}
default {set elf_file [lindex $argv $i]}
}
}
 
# Make sure arugments were specified
if {[string eq $elf_file -1]} {
puts "ERROR: ELF/IHEX file isn't specified"
puts "\nERROR: ELF/IHEX file isn't specified"
help
exit 1
}
75,25 → 103,51
 
# Make sure the elf file exists
if {![file exists $elf_file]} {
puts "ERROR: Specified ELF/IHEX file doesn't exist"
puts "\nERROR: Specified ELF/IHEX file doesn't exist"
help
exit 1
}
 
# Make sure the selected adptor is valid
if {![string eq $omsp_conf(interface) "uart_generic"] &
![string eq $omsp_conf(interface) "i2c_usb-iss"]} {
puts "\nERROR: Specified adaptor is not valid (should be \"uart_generic\" or \"i2c_usb-iss\")"
help
exit 1
}
 
###############################################################################
# SOURCE LIBRARIES #
###############################################################################
# Make sure the I2C address is an integer
if {![string is integer $omsp_conf(0,cpuaddr)]} {
puts "\nERROR: Specified I2C address is not an integer"
help
exit 1
}
 
# Get library path
set current_file [info script]
if {[file type $current_file]=="link"} {
set current_file [file readlink $current_file]
# Make sure the I2C address is valid
if {($omsp_conf(0,cpuaddr)<8) | ($omsp_conf(0,cpuaddr)>119)} {
puts "\nERROR: Specified I2C address should lay between 7 and 120"
help
exit 1
}
set lib_path [file dirname $current_file]/../lib/tcl-lib
 
# Source library
source $lib_path/dbg_functions.tcl
# If the selected interface is a UART, make sure the selected speed is an integer
if {[string eq $omsp_conf(interface) "uart_generic"]} {
if {![string is integer $omsp_conf(baudrate)]} {
puts "\nERROR: Specified UART communication speed is not an integer"
help
exit 1
}
} elseif {[string eq $omsp_conf(interface) "i2c_usb-iss"]} {
if {[lsearch [lindex [GetAllowedSpeeds] 2] $omsp_conf(baudrate)]==-1} {
puts "\nERROR: Specified I2C communication speed is not valid."
puts " Allowed values are:"
foreach allowedVal [lindex [GetAllowedSpeeds] 2] {
puts " - $allowedVal"
}
puts ""
exit 1
}
}
 
 
###############################################################################
105,7 → 159,7
set fileType [string tolower $fileType]
regsub {\.} $fileType {} fileType
if {![string eq $fileType "ihex"] & ![string eq $fileType "hex"] & ![string eq $fileType "elf"]} {
puts "ERROR: [string toupper $fileType] file format not supported"
puts "\nERROR: [string toupper $fileType] file format not supported"
return 0
}
if {[string eq $fileType "hex"]} {
126,11 → 180,11
for {set i 0} {$i <= $timeout} {incr i} {
after 500
if {[file exists $bin_file]} {
break
break
}
}
if {$i>=$timeout} {
puts "Timeout: ELF to BIN file conversion problem with \"msp430-objcopy\" executable"
puts "\nTimeout: ELF to BIN file conversion problem with \"msp430-objcopy\" executable"
puts "$errMsg"
exit 1
}
162,23 → 216,27
###############################################################################
 
# Connect to target and stop CPU
puts -nonewline "Connecting with the openMSP430 ($serial_device, $serial_baudrate\ bps)... "
puts ""
puts -nonewline "Connecting with the openMSP430 ($omsp_conf(device), $omsp_conf(baudrate)\ bps)... "
flush stdout
if {![GetDevice]} {
if {![GetDevice 0]} {
puts "failed"
puts "Could not open $serial_device"
puts "Could not open $omsp_conf(device)"
puts "Available serial ports are:"
foreach port [dbg_list_uart] {
foreach port [utils::uart_port_list] {
puts " - $port"
}
if {[string eq $omsp_conf(interface) "i2c_usb-iss"]} {
puts "\nMake sure the specified I2C device address is correct: $omsp_conf(0,cpuaddr)\n"
}
exit 1
}
ExecutePOR_Halt
ExecutePOR_Halt 0
puts "done"
set sizes [GetCPU_ID_SIZE]
set sizes [GetCPU_ID_SIZE 0]
 
if {$omsp_info(alias)!=""} {
puts "Connected: target device identified as $omsp_info(alias)."
if {$omsp_info(0,alias)!=""} {
puts "Connected: target device identified as $omsp_info(0,alias)."
}
puts "Connected: target device has [lindex $sizes 0]B Program Memory and [lindex $sizes 1]B Data Memory"
puts ""
193,17 → 251,19
set StartAddr [format "0x%04x" [expr 0x10000-$byte_size]]
puts -nonewline "Load Program Memory... "
flush stdout
WriteMemQuick $StartAddr $DataArray
WriteMemQuick 0 $StartAddr $DataArray
after 500
puts "done"
 
# Check Data
puts -nonewline "Verify Program Memory... "
flush stdout
if {[VerifyMem $StartAddr $DataArray 1]} {
if {[VerifyMem 0 $StartAddr $DataArray 1]} {
puts "done"
} else {
puts "ERROR"
exit 1
}
 
# Release device
ReleaseDevice 0xfffe
ReleaseDevice 0 0xfffe

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.