OpenCores
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

powered by: WebSVN 2.1.0

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