MinXmodemRx.fth (7051B)
1 \ MinXmodemRx.fth - XMODEM file receive 2 3 (( 4 Copyright (c) 2001, 2002, 2004, 2005, 2010 5 MicroProcessor Engineering 6 133 Hill Lane 7 Southampton SO15 5AF 8 England 9 10 tel: +44 (0)23 8063 1441 11 fax: +44 (0)23 8033 9691 12 net: mpe@mpeforth.com 13 tech-support@mpeforth.com 14 web: www.mpeforth.com 15 16 From North America, our telephone and fax numbers are: 17 011 44 23 8063 1441 18 011 44 23 8033 9691 19 20 21 To do 22 ===== 23 24 Change history 25 ============== 26 20100203 MPE005 Recoded for CPUs with slow DO. 27 Reduced poll interval to 10us for CPUs without FIFOs. 28 20040209 SFP004 Modified for LPC2106 with 512 byte Flash writes, 29 Receive only. 30 20030924 SFP003 Overhauled receive code to make it minimal 31 for single chip Flash programmers. 32 20021014 SFP002 Modified for COMMON directory. 33 20010717 EJB000 First release 34 )) 35 36 37 \ ================== 38 \ *! minxmodemrx 39 \ *T XMODEM Receiver and Transmitter 40 \ ================== 41 \ *S Introduction 42 \ *P This file implements the XMODEM 128-byte checksum protocol 43 \ ** for receive only. 44 45 \ *P No test code is provided for this file as the system has 46 \ ** been tested by comparison of transferred binary files. 47 48 \ *************************** 49 \ *S Words in MinXmodemRx.fth 50 \ *************************** 51 52 decimal 53 54 55 \ ========================== 56 \ *N Constants and variables 57 \ ========================== 58 59 \ Characters 60 $001 equ START $001 equ SOH 61 $004 equ EOT 62 $006 equ ACK 63 $015 equ NAK 64 $018 equ CAN 65 66 \ Error codes 67 $0101 equ blkerror \ error codes 68 $0102 equ wrongblk 69 $0103 equ noreply 70 $0104 equ crcerror 71 $0105 equ overflow 72 73 $0100 equ maxerrs \ max errors before we bomb 74 75 \ Variables 76 cell buffer: BLK# \ Current Block No. 77 cell buffer: CUR-ADDRESS \ Current host address 78 cell buffer: LAST-BLOCK \ last block we can receive 79 cell buffer: rxerrcnt \ counter for rx errors 80 cell buffer: rxstatus \ receiver status 81 82 compiler 83 : X-buffer \ -- addr 84 Xbase 85 ; 86 target 87 88 89 \ =================== 90 \ *N XMODEM reception 91 \ =================== 92 \ *P This code is a much chopped-down version of that 93 \ ** provided in *\i{COMMON\XMODEMTXRX.FTH}. It is much smaller 94 \ ** and it is assumed that the word *\fo{TOFLASH ( src dest -- )} 95 \ ** is used to program each 128 byte block into Flash. 96 97 [undefined] ser-flush [if] 98 : ser-flush \ -- ; flush the link input 99 \ *G Flush all input characters from the host/target link. 100 begin 101 ser-key? 102 while 103 ser-key drop 104 repeat 105 ; 106 [then] 107 108 : send-ack \ -- ; send ACK 109 \ *G Transmit an ACK character. 110 ACK ser-emit 111 ; 112 113 : send-nak \ -- ; Transmit a NAK character 114 \ *G Transmit a NAK character. 115 NAK ser-emit 116 ; 117 118 : send-can \ -- ; send CAN character 119 \ *G Transmit a CAN character. 120 CAN ser-emit rxstatus on 121 ; 122 123 (( \ original 124 : TimedKey \ -- char|-1 125 \ *G As *\fo{KEY} but returns -1 on timeout 126 #800000 0 do \ approx 100ms 127 ser-key? 128 if ser-key unloop exit then 129 loop 130 -1 131 ; 132 )) 133 : TimedKey \ -- char|-1 134 \ *G As *\fo{KEY} but returns -1 on timeout. 135 $400000 begin \ approx 100ms 136 ser-key? 137 if ser-key nip exit then 138 1- dup 0= 139 until 140 drop -1 141 ; 142 143 (( \ original 144 : Get-BlockData \ -- cksum ; get block from host 145 \ *G Receive a 128 byte XMODEM data block from the host. 146 0 147 X-buffer #128 bounds do \ Get 128 byte Block 148 \ ser-key dup i c! \ save byte to buffer 149 TimedKey dup i c! \ save byte to buffer 150 + $0FF and \ Add to Check-Sum 151 loop 152 ; 153 )) 154 : Get-BlockData \ -- cksum ; get block from host 155 \ *G Receive a 128 byte XMODEM data block from the host. 156 0 X-buffer begin \ -- crc caddr 157 TimedKey 2dup swap c! \ -- crc addr char ; save byte to buffer 158 rot + $FF and swap 1+ \ -- crc' caddr' 159 dup X-buffer #128 + u>= 160 until 161 drop 162 ; 163 164 165 : CancelXfer \ -- 166 \ *G Cancel transfer by sending 2 CAN characters. 167 send-can send-can \ 2 CAN's aborts transfer 168 ; 169 170 : ?toomanyerrs \ -- 171 \ *G Cancel reception if too many errors have occurred. 172 ser-flush 173 1 rxerrcnt +! 174 rxerrcnt @ maxerrs > if 175 CancelXfer 176 else 177 send-nak 178 endif 179 ; 180 181 : From-Buffer \ -- ; copy 128 bytes from X-BUFFER 182 \ *G Move 128 bytes from *\fo{X-BUFFER} into the memory pointed to 183 \ ** by *\fo{CUR-ADDRESS}. The user must supply a routine *\fo{TOFLASH} 184 \ ** ( src dest -- ) which programs the data at src into Flash 185 \ ** at dest. 186 X-buffer cur-address @ toFlash \ program 128 bytes 187 #128 cur-address +! 188 ; 189 190 : Get-Block \ -- 191 \ *G Receive an XMODEM 128 byte data block from the host, processing 192 \ ** the header and checksum data. 193 TimedKey TimedKey \ get block and inverse 194 over + $0FF <> if 195 ?toomanyerrs send-can 196 drop exit \ lose incoming block number 197 endif 198 Blk# @ $00FF and <> if \ correct block? 199 ?toomanyerrs exit 200 endif 201 Get-BlockData \ get the data 202 Timedkey <> if \ get single cksum byte 203 ?toomanyerrs exit 204 endif 205 Blk# @ last-block @ > if 206 CancelXfer exit 207 endif 208 From-Buffer \ copy data to memory 209 send-ack \ all OK send ACK 210 1 Blk# +! \ bump for next block 211 rxerrcnt off \ clear error count again 212 ; 213 214 : key/1s \ -- flag 215 \ *G Waits for one second or until a key is pressed, 216 \ ** returning true if a key was pressed. 217 #100000 begin 218 ser-key? 0= over and 219 while 220 delay10us 1- 221 repeat 222 drop 223 ser-key? 224 ; 225 226 : waitforresponse \ -- ; wait for host to respond 227 \ *G Wait for the host to respond for up to 1 second. If the 228 \ ** host does not respond, a *\fo{NOREPLY} status is set in the 229 \ ** variable *\fo{RXSTATUS}. 230 key/1s 0= 231 if rxstatus on endif \ flag no response 232 ; 233 234 : Bin-Up \ addr len -- status ; status 0 = GOOD 235 \ *G Upload (receive) a block of data of the given size into memory 236 \ ** using the XMODEM 128 byte block protocol. An error status is 237 \ ** returned, 0 indicating success. 238 \ cr ." Start Xmodem transmitter on host" cr 239 rxstatus off \ start with good status 240 rxerrcnt off \ and no errors 241 ser-flush \ flush input 242 7 rshift last-block ! \ calculate last block number 243 CUR-ADDRESS ! \ Start from addr 244 1 BLK# ! \ first block number 245 246 NAK ser-emit \ NAK requests single byte checksum 247 begin \ wait for remote startup 248 key/1s 0= \ done if a reply within a second 249 while 250 NAK ser-emit \ then send NAK if still no key 251 repeat 252 253 begin \ outer loop handles blocks 254 waitforresponse \ check if we got a response 255 rxstatus @ 0= if 256 case ser-key \ get response 257 EOT of EOT rxstatus ! send-ack endof \ all finished 258 CAN of CAN rxstatus ! send-ack endof \ remote cancelled 259 SOH of Get-block endof \ start of data block 260 endcase 261 endif 262 rxstatus @ \ loop until all done 263 until 264 265 rxstatus @ dup EOT = if 266 drop 0 \ returns 0 for good transfer 267 endif 268 ; 269 270 (( 271 : gogo \ -- status ; for preliminary testing 272 $01A emit FlashBase /Flash Bin-up ; 273 )) 274 275 276 \ ====== 277 \ *> ### 278 \ ====== 279