''************************************* ''* Receive only Serial Driver v0.9 * ''************************************* ' made by Andy Schenk ' based on the FullDuplexSerial from Parallax VAR long cog 'cog flag/id long rx_head '6 contiguous longs long rx_tail long rx_pin long rx_mode long bit_ticks long buffer_ptr byte rx_buffer[16] 'receive buffer PUB start(pin, baudrate, mode) : okay '' Start serial driver - starts a cog '' returns false if no cog available '' '' mode bit 0: 0= 8 databits, 1= 9 databits '' bit 3: invert rx stop longfill(@rx_head, 0, 2) rx_pin := pin rx_mode := mode bit_ticks := clkfreq / baudrate buffer_ptr := @rx_buffer okay := cog := cognew(@entry, @rx_head) + 1 PUB stop '' Stop serial driver - frees a cog if cog cogstop(cog~ - 1) longfill(@rx_head, 0, 6) PUB rxflush '' Flush receive buffer repeat while rxcheck => 0 PUB rxcheck : rxbyte '' Check if byte received (never waits) '' returns -1 if no byte received, $00..$FF if byte rxbyte-- if rx_tail <> rx_head rxbyte := rx_buffer[rx_tail] rx_tail := (rx_tail + 1) & $F PUB rxtime(ms) : rxbyte | t '' Wait ms milliseconds for a byte to be received '' returns -1 if no byte received, $00..$FF if byte t := cnt repeat until (rxbyte := rxcheck) => 0 or (cnt - t) / (clkfreq / 1000) > ms PUB rx : rxbyte '' Receive byte (may wait for byte) '' returns $00..$FF repeat while (rxbyte := rxcheck) < 0 PUB rxempty : truefalse '' Check if receivebuffer empty (never waits) '' returns TRUE if empty (reads no byte) truefalse := rx_tail == rx_head DAT '*********************************** '* Assembly language serial driver * '*********************************** org ' entry mov t1,par 'get structure address add t1,#2 << 2 'skip past heads and tails rdlong t2,t1 'get rx_pin mov rxmask,#1 shl rxmask,t2 add t1,#4 'get rx_mode rdlong rxmode,t1 add t1,#4 'get bit_ticks rdlong bitticks,t1 add t1,#4 'get buffer_ptr rdlong rxbuff,t1 ' ' Receive ' receive test rxmode,#%1000 wz 'wait for start bit on rx pin test rxmask,ina wc if_z_eq_c jmp #receive mov rxbits,#9 'ready to receive byte test rxmode,#%1000 wz '8 or 9 databits? if_nz mov rxbits,#10 mov rxcnt,bitticks shr rxcnt,#1 add rxcnt,cnt :bit add rxcnt,bitticks 'ready next bit period :wait mov t1,rxcnt 'check if bit receive period done sub t1,cnt cmps t1,#0 wc if_nc jmp #:wait test rxmask,ina wc 'receive bit on rx pin rcr rxdata,#1 djnz rxbits,#:bit shr rxdata,#32-10 'justify and trim received byte and rxdata,#$1FF test rxmode,#%1000 wz 'if rx inverted, invert byte if_nz xor rxdata,#$1FF test rxmode,#%1000 wz '8 or 9 databits? if_z shr rxdata,#1 rdlong t2,par 'save received byte and inc head add t2,rxbuff wrbyte rxdata,t2 sub t2,rxbuff add t2,#1 and t2,#$0F wrlong t2,par jmp #receive 'byte done, receive next byte ' ' Uninitialized data ' t1 res 1 t2 res 1 rxmode res 1 bitticks res 1 rxmask res 1 rxbuff res 1 rxdata res 1 rxbits res 1 rxcnt res 1 rxcode res 1