umouse

umouse.git
git clone git://git.lenczewski.org/umouse.git
Log | Files | Refs | Submodules | README

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