File: nmea.tcl

package info (click to toggle)
tcllib 1.10-dfsg-3
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 17,708 kB
  • ctags: 6,122
  • sloc: tcl: 106,354; ansic: 9,205; sh: 8,707; xml: 1,766; yacc: 753; makefile: 115; perl: 84; f90: 84; python: 33; ruby: 13; php: 11
file content (121 lines) | stat: -rwxr-xr-x 2,828 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# nmea.tcl --
#
# NMEA protocol implementation
#
# Copyright (c) 2006-2007 Aaron Faupell
#
# RCS: @(#) $Id: nmea.tcl,v 1.3 2007/08/20 21:55:27 andreas_kupries Exp $

package require Tcl 8.2
package provide nmea 0.1.1

namespace eval ::nmea {
    set ::nmea::nmea(checksum) 1
    set ::nmea::nmea(log) ""
}

proc ::nmea::open_port {port {speed 4800}} {
    variable nmea
    set nmea(fh) [open $port]
    fconfigure $nmea(fh) -mode $speed,n,8,1 -handshake xonxoff -buffering line -translation crlf
    fileevent $nmea(fh) readable [list ::nmea::read_port $nmea(fh)]
    return 1
}

proc ::nmea::open_file {file rate} {
    variable nmea
    set nmea(fh) [open $file]
    set nmea(rate) $rate
    fconfigure $nmea(fh) -buffering line -blocking 0 -translation auto
    if {$rate > 0} {
        after $rate [list ::nmea::read_file $nmea(fh)]
    }
}

proc ::nmea::configure_port {settings} {
    variable nmea
    fconfigure $nmea(fh) -mode $settings
}

proc ::nmea::close_port {} {
    variable nmea
    catch {close $nmea(fh)}
}

proc ::nmea::close_file {} {
    variable nmea
    catch {close $nmea(fh)}
}

proc ::nmea::read_port {f} {
    set line [gets $f]
    if {$::nmea::nmea(log) != ""} {
        puts $::nmea::nmea(log) $line
    }
    ::nmea::parse_nmea $line
}

proc ::nmea::read_file {f} {
    variable nmea
    if {![eof $f]} {
        set line [gets $f]
        if {[string match {$*} $line]} {
            ::nmea::parse_nmea $line
        } else {
            ::nmea::parse_nmea \$$line
        }
    }
    after $nmea(rate) [list ::nmea::read_file $f]
}

proc ::nmea::do_line {} {
    variable nmea
    if {![eof $nmea(fh)]} {
        set line [gets $nmea(fh)]
        if {[string match {$*} $line]} {
            ::nmea::parse_nmea $line
        } else {
            ::nmea::parse_nmea \$$line
        }
    }
}

proc ::nmea::log {file} {
    variable nmea
    if {$file != ""} {
        if {$nmea(log) != ""} { error "already logging to a file" }
        set nmea(log) [open $file a]
    } else {
        catch {close $nmea(log)}
        set nmea(log) ""
    }
}

proc ::nmea::parse_nmea {line} {
    set line [split $line \$*]
    set cksum [lindex $line 2]
    set line [lindex $line 1]
    if {$cksum == "" || !$::nmea::nmea(checksum) || [checksum $line] == $cksum} {
        set line [split $line ,]
        set sentence [lindex $line 0]
        set line [lrange $line 1 end]
        if {[info commands ::nmea::$sentence] != ""} {
            $sentence $line
        }
    }
}

proc ::nmea::checksum {line} {
    set sum 0
    binary scan $line c* line
    foreach char $line {
        set sum [expr {$sum ^ ($char % 128)}]
    }
    return [format %02X [expr {$sum % 256}]]
}

proc ::nmea::write {type args} {
    variable nmea
    set data $type,[join $args ,]
    puts $nmea(fh) \$$data*[checksum $data]
}