| |
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
|
|
|