titxt.tcl

#

Copyright 2017, Erik N. Johnson

FILENAME: titxt.tcl

AUTHOR: erik.johnson@jogle.us

DESCRIPTION: titxt.tcl is part of the binconvert package. binconvert is a package that reads & writes EEPROM memory files in multiple formats. It converts the data to & from a Tcl representation as a list of data segments, which is available for processing.

titxt.tcl contains all the support procs for the format generated by TI's Code Composer tools and used by TI's MSP430 programmer.

This package documentation is auto-generated with Pycco: https://pycco-docs.github.io/pycco/

Use "pycco filename" to re-generate HTML documentation in ./docs .

#

ProcessTitxtLine is the parser for the readline proc. Since TI-TXT is a very simple format, and since the line types do not have a common format, we don't bother using a regexp to parse it.

N.B. that there are no checksums or CRCs, and thus no way of detecting a corrupted file unless the corruption makes a line not interpretable.

proc ::binconvert::ProcessTitxtLine {line} {
#

If the line starts with "@", it's an address. Address lines are reported as segment addresses.

    if {[string range $line 0 0] eq "@"} {
        set ::binconvert::TitxtLineAddr 0
        set segAddr [expr {[format "0x%s" [string range $line 1 end]]}]
        return [list SEGADDR $segAddr]
#

If the line is "q", it's the file terminator, reported as EOF.

    } elseif {([string range $line 0 0] eq "q") && ([string length $line] == 1)} {
        return {"EOF" {} }
#

Otherwise, the line should have 1-16 two-digit hexadecimal numbers, each representing one byte, separated by spaces. Data lines keep a running count of bytes processed since the last segment, to be used as a line address.

    }
    try {
        foreach databyte [split $line " "] {
            lappend dataL [expr {[format "0x%s" $databyte] % 256}]
        }
    } on error {result} {
        set errMsg "binconvert: ValidateTitxtLine: Input file syntax error: \
                    could not parse line: $line"
        log::error $errMsg
        puts $result
        puts $::errorCode
        puts $::errorInfo
        error $errMsg
    }
    if {[llength $dataL] > 16} {
        set errMsg "binconvert: ValidateTitxtLine: Input file syntax error: \
                    data line too long (>16 bytes): $line"
        log::error $errMsg
        error $errMsg
    }
    set addr $::binconvert::TitxtLineAddr
    incr ::binconvert::TitxtLineAddr [llength $dataL]
    return [list DATA $addr $dataL]
}
#

WriteTitxtFile

#

WriteTitxtFile iterates over the segments of the segment list.

proc ::binconvert::WriteTitxtFile {segmentList outchan} {
    foreach {addr dataL} $segmentList {
#

TI Text format can't express header or execution address segments.

        if {($addr eq "HEADER") || ($addr eq "STARTADDR")} { continue }
#

For each data segment, write the address as an address line (e.g., @5C00).

        puts $outchan [format "\@%X" $addr]
#

The address is followed by the data in lines of 16 bytes, with any short line at the end. Each byte is represented by two hex digits, separated by a space.

        set outS ""
        foreach databyte $dataL {
            append outS [format "%02X " $databyte]
            if {[string length $outS] > 45} {
                puts $outchan [string trimright $outS]
                set outS ""
            }
        }
        if {[string length $outS] > 0} {
            puts $outchan [string trimright $outS]
        }
    }
#

After all segments are written out, write the "q" line and end.

    puts $outchan "q"
}