while'd version of u8vector-append replaced back with tail recursion version
[mot-flash.git] / common.scm
blobc37c26ca1554199616a8168dc93ee95317fe4a14
1 (display "Loading flash iface client...")
2 (newline)
4 (use-modules (srfi srfi-1) (ice-9 format) (ice-9 rw))
6 (define STX-s  (string #\stx))
7 (define RS-s  (string #\rs))
8 (define ETX-s  (string #\etx))
10 (define STX-i (char->integer #\stx))
11 (define RS-i (char->integer #\rs))
12 (define ETX-i (char->integer #\etx))
14 (define STX-u8v (make-u8vector 1 STX-i))
15 (define RS-u8v (make-u8vector 1 RS-i))
16 (define ETX-u8v (make-u8vector 1 ETX-i))
18 (define SENDBUF-SIZE 2048)
20 (define (list-ref-with-default lst n def)
21   (if (< n (length lst))
22     (list-ref lst n)
23     def)
24   )
26 (define (string->u8vector s)
27   (let ((result (make-u8vector (string-length s))))
28     (array-map! result char->integer s)
29     result)
30   )
32 (define (u8vector->string v)
33   (let ((result (make-string (u8vector-length v))))
34     (array-map! result integer->char v)
35     result)
36   )
38 (define (integer->u8vector i)
39   (make-u8vector 1 i)
40   )
42 (define (char->u8vector c)
43   (integer->u8vector (char->integer c))
44   )
46 ;(define (uniform-vector-append! dst . srcs)
47 ;  (define dst-len (uniform-vector-length dst))
48 ;  (define (do-uniform-vector-append!)
49 ;    (let ((new-index 0)
50 ;         (rest srcs))
51 ;      (while (and (not (null? rest)) (< new-index dst-len))
52 ;            (let ((current-item (car rest))
53 ;                  (current-length (uniform-vector-length (car rest))))
54 ;              (uniform-vector-move! current-item 0 (min current-length (- dst-len new-index)) dst new-index)
55 ;              (set! new-index (+ new-index current-length))
56 ;              )
57 ;            (set! rest (cdr rest))
58 ;            )
59 ;      )
60 ;    )
61 ;  (do-uniform-vector-append!)
62 ;  )
64 (define (uniform-vector-append! dst . srcs)
65   (define dst-len (uniform-vector-length dst))
66   (define (do-uniform-vector-append! new-index rest)
67     (if (and (not (null? rest)) (< new-index dst-len))
68       (let ((current-item (car rest))
69             (current-length (uniform-vector-length (car rest))))
70         (uniform-vector-move! current-item 0 (min current-length (- dst-len new-index)) dst new-index)
71         (do-uniform-vector-append! (+ new-index current-length) (cdr rest)))
72       )
73     )
74   (do-uniform-vector-append! 0 srcs)
75   )
77 (define (u8vector-append . srcs)
78   (let ((res (make-u8vector (fold (lambda (v1 sum) (+ (uniform-vector-length v1) sum)) 0 srcs))))
79     (apply uniform-vector-append! (cons res srcs))
80     res
81     )
82   )
84 (define (parse-command cmd)
85   (define cmd-len (u8vector-length cmd))
86   (define (find-rs-idx idx)
87     (if (< idx cmd-len)
88       (if (equal? RS-i (u8vector-ref cmd idx))
89         idx
90         (find-rs-idx (1+ idx)))
91       #f)
92     )
93   (define (sub-vector v s cnt)
94     (make-shared-array v (lambda (i) (cons (+ s i) '())) cnt)
95     )
97   (if (and (equal? (u8vector-ref cmd 0) STX-i) (equal? (u8vector-ref cmd (1- cmd-len)) ETX-i))
98     (let ((rs-idx (find-rs-idx 0)))
99       (if (equal? rs-idx #f)
100         (cons (u8vector->string (sub-vector cmd 1 (- cmd-len 2))) '())
101         (cons (u8vector->string (sub-vector cmd 1 (1- rs-idx))) (sub-vector cmd (1+ rs-idx) (- cmd-len (1+ rs-idx) 1)))))
102       (throw 'protocol-error "invalid phone answer"))
103   )
105 (define (create-command cmd . args)
106   (let ((par (list-ref-with-default args 0 #f)))
107     (u8vector-append STX-u8v (string->u8vector cmd)
108                      (if (eq? par #f)
109                        #u8()
110                        (u8vector-append RS-u8v par)
111                        )
112                      ETX-u8v
113                      )
114     )
115   )
118 (define (checksum lst)
119   (modulo (fold (lambda (c sum) (+ sum c)) 0 lst)
120           256)
121   )
122 (define (checksum-u8vector v)
123   (checksum (u8vector->list v))
124   )
126 (define (checksum-string s)
127   (checksum (map char->integer (string->list s)))
128   )
130 (define (addr-with-checksum addr)
131   (let ((str-addr (format #f "~:@(~8,'0X~)" addr)))
132     (format #f "~:@(~A~2,'0X~)" str-addr (checksum-string str-addr))
133     )
134   )
136 (define (create-addr-command addr)
137   (create-command "ADDR" (string->u8vector (addr-with-checksum addr)))
138   )
140 (define (create-jump-command addr)
141   (create-command "JUMP" (string->u8vector (addr-with-checksum addr)))
142   )
144 (define (create-bin-command block size)
145   (create-command "BIN" (u8vector-append
146                           (list->u8vector (map (lambda (fun) (fun size 256)) (list quotient remainder)))
147                           block
148                           (integer->u8vector (checksum-u8vector block))
149                           )
150                   )
151   )
153 (define (send-recv-command iface cmd)
154   (begin
155     (write-flash-iface iface cmd)
156     (read-flash-iface iface)
157     )
158   )
160 (define (send-block iface block size addr)
161   (begin
162     (send-recv-command iface (create-addr-command addr))
163     (send-recv-command iface (create-bin-command (make-shared-array block list size) size))
164    )
168 (define (send-data-from-port iface addr)
169   (define (do-send-data-from-port addr buf)
170     (let ((ret (uniform-vector-read! buf)))
171       (if (or (equal? ret 0) (equal? ret #f))
172         addr
173         (begin
174           (send-block iface buf ret addr)
175           (do-send-data-from-port (+ addr ret) buf)
176           )
177         )
178       )
179     )
180   (- (do-send-data-from-port addr (make-u8vector SENDBUF-SIZE)) addr)
181   )
183 (define (send-loader-from-port iface addr jaddr)
184   (begin
185     (send-data-from-port iface addr)
186     (send-recv-command iface (create-jump-command jaddr))
187     )
188   )
190 (define (send-loader-from-file iface fname addr jaddr)
191   (with-input-from-file fname (lambda () (send-loader-from-port iface addr jaddr)))
192   )
194 (display "Done.")
195 (newline)