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 96 to Rev 110
- ↔ Reverse comparison
Rev 96 → Rev 110
/tcl-lib/xml.tcl
0,0 → 1,198
############################################################################# |
# |
# xml.tcl -- Simple XML parser |
# by Keith Vetter, March 2004 |
# |
|
namespace eval ::XML { variable XML "" loc 0} |
|
proc ::XML::Init {xmlData} { |
variable XML |
variable loc |
|
set XML [string trim $xmlData]; |
regsub -all {<!--.*?-->} $XML {} XML ;# Remove all comments |
set loc 0 |
} |
|
# Returns {XML|TXT|EOF|PI value attributes START|END|EMPTY} |
proc ::XML::NextToken {{peek 0}} { |
variable XML |
variable loc |
|
set n [regexp -start $loc -indices {(.*?)\s*?<(/?)(.*?)(/?)>} \ |
$XML all txt stok tok etok] |
if {! $n} {return [list EOF]} |
foreach {all0 all1} $all {txt0 txt1} $txt \ |
{stok0 stok1} $stok {tok0 tok1} $tok {etok0 etok1} $etok break |
|
if {$txt1 >= $txt0} { ;# Got text |
set txt [string range $XML $txt0 $txt1] |
if {! $peek} {set loc [expr {$txt1 + 1}]} |
return [list TXT $txt] |
} |
|
set token [string range $XML $tok0 $tok1] ;# Got something in brackets |
if {! $peek} {set loc [expr {$all1 + 1}]} |
if {[regexp {^!\[CDATA\[(.*)\]\]} $token => txt]} { ;# Is it CDATA stuff? |
return [list TXT $txt] |
} |
|
# Check for Processing Instruction <?...?> |
set type XML |
if {[regexp {^\?(.*)\?$} $token => token]} { |
set type PI |
} |
set attr "" |
regexp {^(.*?)\s+(.*?)$} $token => token attr |
|
set etype START ;# Entity type |
if {$etok0 <= $etok1} { |
if {$stok0 <= $stok1} { set token "/$token"} ;# Bad XML |
set etype EMPTY |
} elseif {$stok0 <= $stok1} { |
set etype END |
} |
return [list $type $token $attr $etype] |
} |
# ::XML::IsWellFormed |
# checks if the XML is well-formed )http://www.w3.org/TR/1998/REC-xml-19980210) |
# |
# Returns "" if well-formed, error message otherwise |
# missing: |
# characters: doesn't check valid extended characters |
# attributes: doesn't check anything: quotes, equals, unique, etc. |
# text stuff: references, entities, parameters, etc. |
# doctype internal stuff |
# |
proc ::XML::IsWellFormed {} { |
set result [::XML::_IsWellFormed] |
set ::XML::loc 0 |
return $result |
} |
;proc ::XML::_IsWellFormed {} { |
array set emsg { |
XMLDECLFIRST "The XML declaration must come first" |
MULTIDOCTYPE "Only one DOCTYPE is allowed" |
INVALID "Invalid document structure" |
MISMATCH "Ending tag '$val' doesn't match starting tag" |
BADELEMENT "Bad element name '$val'" |
EOD "Only processing instructions allowed at end of document" |
BADNAME "Bad name '$val'" |
BADPI "No processing instruction starts with 'xml'" |
} |
|
# [1] document ::= prolog element Misc* |
# [22] prolog ::= XMLDecl? Misc* (doctypedecl Misc*)? |
# [27] Misc ::= Comment | PI | S |
# [28] doctypedecl ::= <!DOCTYPE...> |
# [16] PI ::= <? Name ...?> |
set seen 0 ;# 1 xml, 2 pi, 4 doctype |
while {1} { |
foreach {type val attr etype} [::XML::NextToken] break |
if {$type eq "PI"} { |
if {! [regexp {^[a-zA-Z_:][a-zA-Z0-9.-_:\xB7]+$} $val]} { |
return [subst $emsg(BADNAME)] |
} |
if {$val eq "xml"} { ;# XMLDecl |
if {$seen != 0} { return $emsg(XMLDECLFIRST) } |
# TODO: check version number exist and only encoding and |
# standalone attributes are allowed |
incr seen ;# Mark as seen XMLDecl |
continue |
} |
if {[string equal -nocase "xml" $val]} {return $emsg(BADPI)} |
set seen [expr {$seen | 2}] ;# Mark as seen PI |
continue |
} elseif {$type eq "XML" && $val eq "!DOCTYPE"} { ;# Doctype |
if {$seen & 4} { return $emsg(MULTIDOCTYPE) } |
set seen [expr {$seen | 4}] |
continue |
} |
break |
} |
|
# [39] element ::= EmptyElemTag | STag content ETag |
# [40] STag ::= < Name (S Attribute)* S? > |
# [42] ETag ::= </ Name S? > |
# [43] content ::= CharData? ((element | Reference | CDSect | PI | Comment) CharData?)* |
# [44] EmptyElemTag ::= < Name (S Attribute)* S? /> |
# |
|
set stack {} |
set first 1 |
while {1} { |
if {! $first} { ;# Skip first time in |
foreach {type val attr etype} [::XML::NextToken] break |
} else { |
if {$type ne "XML" && $type ne "EOF"} { return $emsg(INVALID) } |
set first 0 |
} |
|
if {$type eq "EOF"} break |
;# TODO: check attributes: quotes, equals and unique |
|
if {$type eq "TXT"} continue |
if {! [regexp {^[a-zA-Z_:][a-zA-Z0-9.-_:\xB7]+$} $val]} { |
return [subst $emsg(BADNAME)] |
} |
|
if {$type eq "PI"} { |
if {[string equal -nocase xml $val]} { return $emsg(BADPI) } |
continue |
} |
if {$etype eq "START"} { ;# Starting tag |
lappend stack $val |
} elseif {$etype eq "END"} { ;# </tag> |
if {$val ne [lindex $stack end]} { return [subst $emsg(MISMATCH)] } |
set stack [lrange $stack 0 end-1] |
if {[llength $stack] == 0} break ;# Empty stack |
} elseif {$etype eq "EMPTY"} { ;# <tag/> |
} |
} |
|
# End-of-Document can only contain processing instructions |
while {1} { |
foreach {type val attr etype} [::XML::NextToken] break |
if {$type eq "EOF"} break |
if {$type eq "PI"} { |
if {[string equal -nocase xml $val]} { return $emsg(BADPI) } |
continue |
} |
return $emsg(EOD) |
} |
return "" |
} |
|
################################################################ |
# |
# Demo code |
# |
#set xml {<?xml version="1.0" encoding="ISO-8859-1"?> |
# <loc version="1.0" src="Groundspeak"> |
# <waypoint> |
# <name id="GCGPXK"><![CDATA[Playing Poker with the Squirrels by Rino 'n Rinette]]></name> |
# <coord lat="40.1548166" lon="-82.5202833"/> |
# <type>Geocache</type> |
# <link text="Cache Details">http://www.geocaching.com/seek/cache_details.aspx?wp=GCGPXK</link> |
# </waypoint><waypoint> |
# <name id="GC19DF"><![CDATA[Great Playground Caper by Treasure Hunters Inc.]]></name> |
# <coord lat="40.0667166666667" lon="-82.5358"/> |
# <type>Geocache</type> |
# <link text="Cache Details">http://www.geocaching.com/seek/cache_details.aspx?wp=GC19DF</link> |
# </waypoint> |
# </loc> |
#} |
|
#::XML::Init $xml |
#set wellFormed [::XML::IsWellFormed] |
#if {$wellFormed ne ""} { |
# puts "The xml is not well-formed: $wellFormed" |
#} else { |
# puts "The xml is well-formed" |
# while {1} { |
# foreach {type val attr etype} [::XML::NextToken] break |
# puts "looking at: $type '$val' '$attr' '$etype'" |
# if {$type == "EOF"} break |
# } |
#} |
tcl-lib/xml.tcl
Property changes :
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Index: tcl-lib/dbg_functions.tcl
===================================================================
--- tcl-lib/dbg_functions.tcl (revision 96)
+++ tcl-lib/dbg_functions.tcl (revision 110)
@@ -73,15 +73,21 @@
# - ClearHWBreak (Type, Addr)
# - IsHalted ()
# - ClrStatus ()
+# - GetChipAlias ()
#
#------------------------------------------------------------------------------
# GLOBAL VARIABLES
global hw_break
+global omsp_info
+set omsp_info(connected) 0
# SOURCE REQUIRED LIBRARIES
-source [file dirname [info script]]/dbg_uart.tcl
+set scriptDir [file dirname [info script]]
+source $scriptDir/dbg_uart.tcl
+source $scriptDir/xml.tcl
+
#=============================================================================#
# ExecutePOR () #
#-----------------------------------------------------------------------------#
@@ -91,8 +97,6 @@
#=============================================================================#
proc ExecutePOR {} {
- set result 1
-
# Set PUC
set cpu_ctl_org [dbg_uart_rd CPU_CTL]
set cpu_ctl_new [expr 0x40 | $cpu_ctl_org]
@@ -104,7 +108,7 @@
# Check CPU ID
if {![VerifyCPU_ID]} {
- set result 0
+ return 0
}
# Check status: make sure a PUC occured
@@ -111,13 +115,13 @@
set cpu_stat_val [dbg_uart_rd CPU_STAT]
set puc_pnd [expr 0x04 & $cpu_stat_val]
if {![string eq $puc_pnd 4]} {
- set result 0
+ return 0
}
# Clear PUC pending flag
dbg_uart_wr CPU_STAT 0x04
- return $result
+ return 1
}
#=============================================================================#
@@ -199,6 +203,7 @@
proc GetDevice {} {
global hw_break
+ global omsp_info
# Set UART global variables
if {![info exists ::serial_baudrate]} {
@@ -213,14 +218,24 @@
return 0
}
- # Enable auto-freeze & software breakpoints
- dbg_uart_wr CPU_CTL 0x0018
+ if {[VerifyCPU_ID]} {
- # Get number of hardware breakpoints
- set hw_break(num) [InitBreakUnits]
+ # Enable auto-freeze & software breakpoints
+ dbg_uart_wr CPU_CTL 0x0018
- # Check CPU ID
- return [VerifyCPU_ID]
+ # 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
+ }
}
#=============================================================================#
@@ -432,42 +447,71 @@
#=============================================================================#
# GetCPU_ID () #
#-----------------------------------------------------------------------------#
-# Description: This function reads the CPU_ID from the target device. #
+# 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. #
# Result : Return CPU_ID. #
#=============================================================================#
proc GetCPU_ID { } {
+ global omsp_info
+
+ # Retreive CPU_ID values
regsub {0x} [dbg_uart_rd CPU_ID_LO] {} cpu_id_lo
regsub {0x} [dbg_uart_rd CPU_ID_HI] {} cpu_id_hi
- return "0x$cpu_id_hi$cpu_id_lo"
+ set cpu_id "0x$cpu_id_hi$cpu_id_lo"
+ set cpu_id_lo "0x$cpu_id_lo"
+ set cpu_id_hi "0x$cpu_id_hi"
+
+
+ # 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]
+ } 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(alias) [GetChipAlias]
+
+ return $cpu_id
}
#=============================================================================#
# GetCPU_ID_SIZE () #
#-----------------------------------------------------------------------------#
-# Description: Returns the ROM and RAM sizes of the connected device. #
+# Description: Returns the Data and Program memory sizes of the connected #
+# device. #
# Arguments : None. #
-# Result : Return "ROM_SIZE RAM_SIZE" in byte. #
+# Result : Return "PMEM_SIZE DMEM_SIZE" in byte. #
#=============================================================================#
proc GetCPU_ID_SIZE {} {
- set cpu_id_full [GetCPU_ID]
- regexp {(....)(....)$} $cpu_id_full match rom_size ram_size
+ global omsp_info
- if {[info exists rom_size]} {
- set rom_size [expr 0x$rom_size]
+ if {[info exists omsp_info(pmem_size)]} {
+ set pmem_size $omsp_info(pmem_size)
} else {
- set rom_size -1
+ set pmem_size -1
}
- if {[info exists ram_size]} {
- set ram_size [expr 0x$ram_size]
+ if {[info exists omsp_info(dmem_size)]} {
+ set dmem_size $omsp_info(dmem_size)
} else {
- set ram_size -1
+ set dmem_size -1
}
- return "$rom_size $ram_size"
+ return "$pmem_size $dmem_size"
}
#=============================================================================#
@@ -481,7 +525,8 @@
set cpu_id_full [GetCPU_ID]
- if {[string eq "0x00000000" $cpu_id_full] | [string eq "0x" $cpu_id_full]} {
+ if {[string eq "0x00000000" $cpu_id_full] |
+ ([string length $cpu_id_full]!=10)} {
set result 0
} else {
set result 1
@@ -832,3 +877,136 @@
return 1
}
+
+#=============================================================================#
+# GetChipAlias () #
+#-----------------------------------------------------------------------------#
+# Description: Parse the chip alias XML file an return the alias name. #
+# Arguments : None. #
+# Result : Chip Alias. #
+#=============================================================================#
+proc GetChipAlias {} {
+
+ global omsp_info
+
+ # Set XML file name
+ if {[info exists ::env(OMSP_XML_FILE)]} {
+ set xmlFile $::env(OMSP_XML_FILE)
+ } else {
+ 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
+ } else {
+ puts "WARNING: the XML alias file was not found - $xmlFile"
+ return ""
+ }
+
+ # Analyze XML file
+ ::XML::Init $xmlData
+ set wellFormed [::XML::IsWellFormed]
+ if {$wellFormed ne ""} {
+ puts "WARNING: the XML alias file is not well-formed - $xmlFile \n $wellFormed"
+ return ""
+ }
+
+ #========================================================================#
+ # Create list from XML file #
+ #========================================================================#
+ set aliasList ""
+ set currentALIAS ""
+ set currentTYPE ""
+ set currentTAG ""
+ while {1} {
+ 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 start and end of the configuration field
+ if {($type == "XML") & ($val == "omsp:configuration")} {
+
+ if {($etype == "START")} {
+ set currentTYPE "config"
+
+ } elseif {($etype == "END")} {
+ set currentTYPE ""
+ }
+ }
+
+ # 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
+
+ } elseif {($etype == "END")} {
+ set currentTYPE ""
+ }
+ }
+
+ # 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
+ }
+ }
+ }
+
+ #========================================================================#
+ # 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 {
+
+ regsub "$currentALIAS,config," $currentCONFIG {} configName
+
+ if {![string eq $omsp_info($configName) $alias($currentCONFIG)]} {
+ set match 0
+ }
+ }
+
+ #----------------------------------#
+ # 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
+ }
+ return $currentALIAS
+ }
+ }
+
+ return ""
+}