serdev.pwp


//
// PicoWeb Project File for "SerDev"
//
// Demonstrates connection to external device via the PicoWeb
// serial port.  The sample device is a Micromint Answer MAN Jr.
// The Answer MAN Jr. is a low-cost stand-alone data-acquisition
// and control module with a serial port for setup and/or data
// acquisition.  The project has one Web page which automatically
// reloads itself every few seconds, thus sending a command to the
// Answer MAN via the PicoWeb serial port, reading the single-line
// response back, and displaying the response as the Web page.
// The Answer MAN response line is normally terminated with a
// carriage-return and new-line.  If the Answer MAN fails to
// respond with a line-feed in a timely way, the PicoWeb CGI
// program will "timeout" and return a blank Web page.
//

#define EEPROM_IP                /* use file "ip" for IP address */
#define ENABLE_WATCHDOG
#undef DEBUGGER                 /* no debugger...we're using serial port */
#define SERIAL_BAUD_DIVISOR 51  /* serial port to 9600 baud @ 8Mhz */

// HTML and images
serdev.htm

// CGI routines
sertest.cgi             // iu00
answerman_all.cgi       // iu01

//------------------ included AVR assembly language follows ---------------
#avr_reset

#avr_slow

#avr_fast

#avr_asm

#define putchar_serial pmovbi putc_b,0
#define putchar_net    pmovbi putc_b,1
#define serial_binary  pser_mode 1
#define serial_normal  pser_mode 0
#define SER_TMO         15000
.dseg
old_putcok: .byte 1

;+
; **-sertest-serial I/O testor.
;-
#define SD_ADDR     buf
#define SD_LEN      buf+2
#define SD_CHAR     buf+4
#define SD_TEMP     buf+6
#define SD_LAST     buf+8
#define SD_TMO      SD_CHAR

.eseg
sertest:
    ppushn putcok,1                     ; save putchar enable state
    pmovbi putcok,0xff                  ; putchar is now OK
    putchar_serial                      ; switch putchar to serial port
    serial_binary                       ; put serial port in binary mode
    pmovwi SD_ADDR,[data_addr]          ; get data address
    paddwi SD_ADDR,10                   ; GET /iuNN?xxxxxxxxxxx
                                        ; 01234567890
    pmovwi SD_LEN,[data_len]
    psubwi SD_LEN,10                    ; bias length for GET /...? part
;
; note there is not a lot of checking on the format of the URL.  the first
; occurrence of '=' is interpreted as the start of the stuff to transmit
; to the serial port, and that continues until either '&' or ' ' is
; encountered.
;
    pmovwi SD_LAST,0               ; clear last character (both bytes!)
find_equal_next:
    pr2s SD_CHAR,[SD_ADDR],1       ; scan for '=' in Ethernet packet
    pincw SD_ADDR
    pdecw SD_LEN
    pcmpbi SD_CHAR,'='
    pjumpeq serdev_next
    pcmpwi SD_LEN,0
    pjumplo serial_done
    pjumpne find_equal_next
    pjump serial_done
;
; send stuff after "=" to serial port with %XX expansion until ' '.
;
serdev_next:
    pwdr                                ; reset hardware watchdog timer
    pr2s SD_CHAR,[SD_ADDR],1            ; get next byte
    pcmpbi SD_CHAR,' '                  ; the end?
    pjumpeq serial_done                 ; yes...we found a ' '
    pcmpbi SD_CHAR,'+'                  ; map '+' -> ' '
    pjumpne not_plus
    pmovbi SD_CHAR,' '
    pjump output_next_char
not_plus:
    pcmpbi SD_CHAR,'%'                  ; check for HTTP quoting char
    pjumpne output_next_char
;
; get next two chars from request.
;
    pincw SD_ADDR                       ; skip '%'
    pr2s SD_CHAR,[SD_ADDR],2            ; get XX of %XX
    paddwi SD_ADDR,1                    ; skip past it
    psubwi SD_LEN,2                     ; discount in length
;
; hex conversion of two chars in SD_CHAR, SD_CHAR+1.
;
    pmovb SD_TEMP,SD_CHAR               ; get first char
    pandwi SD_TEMP,0xff
    psubwi SD_TEMP,'0'                  ; convert to binary (maybe)
    pcmpwi SD_TEMP,10                   ; see if valid hex digit
    pjumplo do_upper_digit              ; yep - do upper one
    pandwi SD_TEMP,0xf                  ; 1-6
    paddwi SD_TEMP,9                    ; turn 1-6 into 10-15

do_upper_digit:
    pmovb SD_CHAR,SD_CHAR+1             ; get second digit
    pandwi SD_CHAR,0xff                 ; isolate it
    psubwi SD_CHAR,'0'                  ; convert to binary (maybe)
    pcmpwi SD_CHAR,10                   ; see if valid hex digit
    pjumplo merge_digits                ; yep - merge the two
    pandwi SD_CHAR,0xf
    paddwi SD_CHAR,9

merge_digits:
    pshnw SD_TEMP,4                     ; shift top bits into place
    paddwi SD_CHAR,[SD_TEMP]            ; SD_CHAR now has char

output_next_char:
    pandwi SD_CHAR,0xff                 ; isolate it
    pcmpwi SD_CHAR,0x5c                 ; back-slash?
    pjumpeq skip_output                 ; yes...don't output

    pcmpwi SD_LAST,0x5c                 ; last character a back-slash?
    pjumpne output_char_now             ; no...proceed as normal
    pcmpwi SD_CHAR,'r'                  ; got a \r?
    pjumpne not_CR                      ; no...skip ahead
    pmovbi SD_CHAR,0x0d                 ; yes...change it to CR
not_CR:
    pcmpwi SD_CHAR,'n'                  ; got \n?
    pjumpne not_LF                      ; no...
    pmovbi SD_CHAR,0x0a                 ; yes...change to LF
not_LF:

output_char_now:
    pputcb SD_CHAR
skip_output:
    pmovbi SD_LAST,[SD_CHAR]            ; save last character
    pincw SD_ADDR                       ; adjust pointer
    pdecw SD_LEN                        ; see if we're done
    pjumplo serial_done
    pjumpne serdev_next
serial_done:
    pmovwi SD_TMO,SER_TMO               ; select the timeout period
    putchar_net                         ; switch putchar back to 'net
    pcall serdev_copynet                ; copy serial port input to net
    ppopn putcok,1                      ; restore putchar enable state
    pret
;
; loop reading chars from the serial buffer and writing to 'net until
; LF encountered (or timeout)
;
; SD_TMO (word) = timeout loop count.
;
.cseg
serdev_nextchar:
    pser_getc SD_CHAR                   ; get a char into buf
    pjumpeq serdev_empty                ; no more chars!
    pputcb SD_CHAR                      ; put char to the net
    pcmpbi SD_CHAR,0x0a                 ; check for LF
    pjumpeq serdev_copydone
serdev_copynet:
    pmovwi SD_TEMP,[SD_TMO]             ; reset timeout
    pwdr                                ; reset hardware watchdog timer too
    pjump serdev_nextchar               ; go get another one
serdev_empty:
    psubwi SD_TEMP,1                    ; decrement timeout
    pjumpne serdev_nextchar             ; not yet timed out
serdev_copydone:
    pret

.eseg
answerman_all:
    ppushn putcok,1                     ; save putchar enable state
    pmovbi putcok,0xff                  ; putchar is now OK
    putchar_serial                      ; switch putchar to serial port
    serial_binary                       ; put serial port in binary mode
    pprint "\r! MAN0 QE\r"
    pjump serial_done


Back