FULLDUPLEXSERIAL_RR004
Table of Contents
Preface
Introduction Connection Diagram Global CONstants Global VARiables PUBlic Spin Methods Start and Stop Stop Start Basic send/receive... Extended send/receive... Generic Interface...
I_ReadByteCheck
Assembly Cog I_ReadByte I_WriteByte I_ReadWord I_WriteWord I_ReadLong I_WriteLong I_ReadString I_WriteString I_ReadBlock I_WriteBlock License |
FullDuplexSerial Object Version rr004
IntroductionThis driver, once started, implements a serial port in one cog.
Global CONstantsSOURCE CODE... bufsiz = 256 '16 'buffer size (16, 32, 64, 128, 256, 512) must be factor of 2, max is 512 bufmsk = bufsiz - 1 'buffer mask used for wrap-around ($00F, $01F, $03F, $07F, $0FF, $1FF) here you find CONstants used for the mode-parameter of the Start-method of this object. These constants can be added to be combined. for example serial#OCTX+serial#NOECHO SOURCE CODE... DEFAULTMODE = %000000 ' default mode INVERTRX = %000001 ' mode bit 0 = invert rx INVERTTX = %000010 ' mode bit 1 = invert tx OCTX = %000100 ' mode bit 2 = open-drain/source tx NOECHO = %001000 ' mode bit 3 = ignore tx echo on rx NOMODE = %000000 ' depreciated (msrobots/kurenko) Global VARiablesSOURCE CODE... long cog 'cog flag/id long rx_head '9 contiguous longs long rx_tail long tx_head long tx_tail long rx_pin long tx_pin long rxtx_mode long bit_ticks long buffer_ptr byte rx_buffer[bufsiz] 'transmit and receive buffers byte tx_buffer[bufsiz] PUBlic Spin MethodsStart and StopStart and Stop methods are used for starting and stopping this object. This uses/frees one cog and the rx/tx-pins used.StopStop serial driver - frees a cogSOURCE CODE... PUB Stop if cog cogstop(cog~ - 1) longfill(@rx_head, 0, 9) Start(rxpin, txpin, mode, baudrate)Start serial driver - starts a cogreturns false if no cog available mode bit 0 = invert rx mode bit 1 = invert tx mode bit 2 = open-drain/source tx mode bit 3 = ignore tx echo on rx SOURCE CODE... PUB Start(rxpin, txpin, mode, baudrate) : okay stop longfill(@rx_head, 0, 4) longmove(@rx_pin, @rxpin, 3) bit_ticks := clkfreq / baudrate buffer_ptr := @rx_buffer okay := cog := cognew(@entry, @rx_head) + 1 Basic send/receiveHere you find basic send/receive-methods for single bytes.RxFlushFlush receive bufferSOURCE CODE... PUB RxFlush repeat while rxcheck => 0 RxAvailCheck if byte(s) availablereturns true (-1) if bytes available SOURCE CODE... PUB RxAvail : truefalse truefalse := rx_tail <> rx_head RxCheckCheck if byte received (never waits)returns -1 if no byte received, $00..$FF if byte SOURCE CODE... PUB RxCheck : rxbyte rxbyte-- if rx_tail <> rx_head rxbyte := rx_buffer[rx_tail] rx_tail := (rx_tail + 1) & bufmsk RxTime(ms)Wait ms milliseconds for a byte to be receivedreturns -1 if no byte received, $00..$FF if byte SOURCE CODE... PUB RxTime(ms) : rxbyte | t t := cnt repeat until (rxbyte := rxcheck) => 0 or (cnt - t) / (clkfreq / 1000) > ms RxReceive byte (may wait for byte)returns $00..$FF SOURCE CODE... PUB Rx : rxbyte repeat while (rxbyte := rxcheck) < 0 Tx(txbyte)Send byte (may wait for room in buffer)SOURCE CODE... PUB Tx(txbyte) repeat until (tx_tail <> (tx_head + 1) & bufmsk) tx_buffer[tx_head] := txbyte tx_head := (tx_head + 1) & bufmsk if rxtx_mode & %1000 rx Extended send/receiveHere you find extended send/receive-methods. This serial object has just extended send-methods.You can use them for formatted output of numbers and strings. Str(stringptr)Send stringSOURCE CODE... PUB Str(stringptr) repeat strsize(stringptr) tx(byte[stringptr++]) Dec(value)Print a decimal numberSOURCE CODE... PUB Dec(value) | i, x x := value == NEGX 'Check for max negative if value < 0 value := ||(value+x) 'If negative, make positive; adjust for max negative tx("-") 'and output sign i := 1_000_000_000 'Initialize divisor repeat 10 'Loop for 10 digits if value => i tx(value / i + "0" + x*(i == 1)) 'If non-zero digit, output digit; adjust for max negative value //= i 'and digit from value result~~ 'flag non-zero found elseif result or i == 1 tx("0") 'If zero digit (or only digit) output it i /= 10 'Update divisor Hex(value, digits)Print a hexadecimal numberSOURCE CODE... PUB Hex(value, digits) value <<= (8 - digits) << 2 repeat digits tx(lookupz((value <-= 4) & $F : "0".."9", "A".."F")) Bin(value, digits)Print a binary numberSOURCE CODE... PUB Bin(value, digits) value <<= 32 - digits repeat digits tx((value <-= 1) & 1 + "0") Generic Interfacethis Interface provides generic access with different objects.I_ReadByteCheckCheck if a byte is waiting in the receive buffer and return the byte if one is there, does NOT block (never waits). return: If no byte, then return(-1). If byte, then return(byte). SOURCE CODE... PUB I_ReadByteCheck RETURN RxCheck I_ReadBytereads a byteSOURCE CODE... PUB I_ReadByte RETURN Rx I_WriteByte(outByte)writes a byteSOURCE CODE... PUB I_WriteByte(outByte) RETURN Tx(outByte.Byte[0]) I_ReadWordreads a wordSOURCE CODE... PUB I_ReadWord RESULT.Byte[0]:=Rx RESULT.Byte[1]:=Rx I_WriteWord(outWord)writes a wordSOURCE CODE... PUB I_WriteWord(outWord) Tx(outWord.Byte[0]) RETURN Tx(outWord.Byte[1]) I_ReadLongreads a longSOURCE CODE... PUB I_ReadLong RESULT.Byte[0]:=Rx RESULT.Byte[1]:=Rx RESULT.Byte[2]:=Rx RESULT.Byte[3]:=Rx I_WriteLong(outLong)writes a longSOURCE CODE... PUB I_WriteLong(outLong) Tx(outLong.Byte[0]) Tx(outLong.Byte[1]) Tx(outLong.Byte[2]) RETURN Tx(outLong.Byte[3]) I_ReadString(addressToPut, terminator)reads a string terminated by terminator to addressToPut - terminator not added - returns bytes readSOURCE CODE... PUB I_ReadString(addressToPut, terminator) | inByte repeat while ((inByte:=Rx)<>terminator) byte[addressToPut++]:=inByte RESULT++ I_WriteString(addressToGet, terminator)writes a string terminated by terminator from addressToGet - terminator not added - returns bytes writtenSOURCE CODE... PUB I_WriteString(addressToGet, terminator) | outByte repeat while ((outByte:=byte[addressToGet++])<>terminator) Tx(outByte) RESULT++ I_ReadBlock(addressToPut, count)reads count bytes to addressToPut - returns bytes readSOURCE CODE... PUB I_ReadBlock(addressToPut, count) repeat count byte[addressToPut++]:=Rx RETURN count I_WriteBlock(addressToGet, count)writes count bytes from addressToGet- returns bytes writtenSOURCE CODE... PUB I_WriteBlock(addressToGet, count) repeat count Tx(byte[addressToGet++]) RETURN count Assembly CogSOURCE CODE... '*********************************** '* Assembly language serial driver * '*********************************** org 0 ' ' ' Entry ' entry mov t1,par 'get structure address add t1,#4 << 2 'skip past heads and tails rdlong t2,t1 'get rx_pin mov rxmask,#1 shl rxmask,t2 add t1,#4 'get tx_pin rdlong t2,t1 mov txmask,#1 shl txmask,t2 add t1,#4 'get rxtx_mode rdlong rxtxmode,t1 add t1,#4 'get bit_ticks rdlong bitticks,t1 add t1,#4 'get buffer_ptr rdlong rxbuff,t1 mov txbuff,rxbuff add txbuff,#bufsiz test rxtxmode,#%100 wz 'init tx pin according to mode test rxtxmode,#%010 wc if_z_ne_c or outa,txmask if_z or dira,txmask mov txcode,#transmit 'initialize ping-pong multitasking ' ' ' Receive ' receive jmpret rxcode,txcode 'run a chunk of transmit code, then return test rxtxmode,#%001 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 mov rxcnt,bitticks shr rxcnt,#1 add rxcnt,cnt :bit add rxcnt,bitticks 'ready next bit period :wait jmpret rxcode,txcode 'run a chuck of transmit code, then return 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-9 'justify and trim received byte and rxdata,#$FF test rxtxmode,#%001 wz 'if rx inverted, invert byte if_nz xor rxdata,#$FF rdlong t2,par 'save received byte and inc head add t2,rxbuff wrbyte rxdata,t2 sub t2,rxbuff add t2,#1 and t2,#bufmsk wrlong t2,par jmp #receive 'byte done, receive next byte ' ' ' Transmit ' transmit jmpret txcode,rxcode 'run a chunk of receive code, then return mov t1,par 'check for head <> tail add t1,#2 << 2 rdlong t2,t1 add t1,#1 << 2 rdlong t3,t1 cmp t2,t3 wz if_z jmp #transmit add t3,txbuff 'get byte and inc tail rdbyte txdata,t3 sub t3,txbuff add t3,#1 and t3,#bufmsk wrlong t3,t1 or txdata,#$100 'ready byte to transmit shl txdata,#2 or txdata,#1 mov txbits,#11 mov txcnt,cnt :bit test rxtxmode,#%100 wz 'output bit on tx pin according to mode test rxtxmode,#%010 wc if_z_and_c xor txdata,#1 shr txdata,#1 wc if_z muxc outa,txmask if_nz muxnc dira,txmask add txcnt,bitticks 'ready next cnt :wait jmpret txcode,rxcode 'run a chunk of receive code, then return mov t1,txcnt 'check if bit transmit period done sub t1,cnt cmps t1,#0 wc if_nc jmp #:wait djnz txbits,#:bit 'another bit to transmit? jmp #transmit 'byte done, transmit next byte ' ' ' Uninitialized data ' t1 res 1 t2 res 1 t3 res 1 rxtxmode res 1 bitticks res 1 rxmask res 1 rxbuff res 1 rxdata res 1 rxbits res 1 rxcnt res 1 rxcode res 1 txmask res 1 txbuff res 1 txdata res 1 txbits res 1 txcnt res 1 txcode res 1 License┌──────────────────────────────────────────────────────────────────────────────────────┐ │ TERMS OF USE: MIT License │ ├──────────────────────────────────────────────────────────────────────────────────────┤ │Permission is hereby granted, free of charge, to any person obtaining a copy of this │ │software and associated documentation files (the "Software"), to deal in the Software │ │without restriction, including without limitation the rights to use, copy, modify, │ │merge, publish, distribute, sublicense, and/or sell copies of the Software, and to │ │permit persons to whom the Software is furnished to do so, subject to the following │ │conditions: │ │ │ │The above copyright notice and this permission notice shall be included in all copies │ │or substantial portions of the Software. │ │ │ │THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, │ │INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A │ │PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT │ │HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF │ │CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE │ │OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │ └──────────────────────────────────────────────────────────────────────────────────────┘ |