URL
https://opencores.org/ocsvn/openmsp430/openmsp430/trunk
Subversion Repositories openmsp430
Compare Revisions
- This comparison shows the changes necessary to convert path
/openmsp430/trunk/tools/lib
- from Rev 133 to Rev 158
- ↔ Reverse comparison
Rev 133 → Rev 158
/tcl-lib/dbg_uart.tcl
File deleted
\ No newline at end of file
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: tcl-lib/dbg_i2c_usb-iss.tcl
===================================================================
--- tcl-lib/dbg_i2c_usb-iss.tcl (nonexistent)
+++ 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]
+ }
+
+}
tcl-lib/dbg_i2c_usb-iss.tcl
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Index: tcl-lib/dbg_uart_generic.tcl
===================================================================
--- tcl-lib/dbg_uart_generic.tcl (nonexistent)
+++ 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
+ }
+
+}
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: tcl-lib/dbg_functions.tcl
===================================================================
--- tcl-lib/dbg_functions.tcl (revision 133)
+++ 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 ""
}
/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 |
} |
|
} |
tcl-lib/dbg_utils.tcl
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property