' ' buffered smart pin serial object for P2 Eval board, buffering rx/tx in the Cog, supporting 2 full-duplex connrction ' CON _txmode = %0000_0000_000_0000000000000_01_11110_0 'async tx mode, output enabled for smart output _rxmode = %0000_0000_000_0000000000000_00_11111_0 'async rx mode, input enabled for smart input OBJ serpasm: "cogserialpasm.spin2" 'this is the PASM2 COG doing all the work ' '----------------------------------------------------------------------- ' VAR long rx1_cmd, rx1_param, tx1_cmd, tx1_param, rx2_cmd, rx2_param, tx2_cmd, tx2_param 'mailbox of this instance 8 longs DAT outchar byte "H",0,0,0 ' '----------------------------------------------------------------------- 'stop pasm cog if already running '----------------------------------------------------------------------- ' PUB stop serpasm.stop ' '----------------------------------------------------------------------- 'return parameter address of instance '----------------------------------------------------------------------- ' PUB mailboxaddress RETURN @rx1_cmd ' '----------------------------------------------------------------------- 'use this to start a 1 port driver with 255 bytes buffer each channel '----------------------------------------------------------------------- ' PUB start(rxpin = 63, txpin = 62, mode = -1, baudrate = 230_400) | bitrate bitrate := 7 + ((CLKFREQ / baudrate) << 16) RETURN startpasm(@rx1_cmd, rxpin, bitrate, _rxmode, 0, $FF, txpin, bitrate, _txmode, $100, $FF, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 100) ' '----------------------------------------------------------------------- 'use this to start a 2 port driver with 128 bytes buffer each channel '----------------------------------------------------------------------- ' PUB start2(rxpin1, txpin1, mode1, baudrate1, rxpin2, txpin2, mode2, baudrate2) | bitrate1, bitrate2 bitrate1 := 7 + ((CLKFREQ / baudrate1) << 16) bitrate2 := 7 + ((CLKFREQ / baudrate2) << 16) RETURN startpasm(@rx1_cmd, rxpin1, bitrate1, _rxmode, 0, $7F, txpin1, bitrate1, _txmode, $80, $7F, rxpin2, bitrate2, _rxmode, $100, $7F, txpin2, bitrate2, _txmode, $180, $7F, 100) ' '----------------------------------------------------------------------- 'use this to start whatever combination you want '----------------------------------------------------------------------- ' PUB startExt(rxpin1, txpin1, rxbaudrate1, txbaudrate1, rxmode1, txmode1, rxlutstart1, rxlutsize1, txlutstart1, txlutsize1, rxpin2, txpin2, rxbaudrate2, txbaudrate2, rxmode2, txmode2, rxlutstart2, rxlutsize2, txlutstart2, txlutsize2, txclocks) | rxbitrate1, txbitrate1, rxbitrate2, txbitrate2 rxbitrate1 := 7 + ((CLKFREQ / rxbaudrate1) << 16) txbitrate1 := 7 + ((CLKFREQ / txbaudrate1) << 16) rxbitrate2 := 7 + ((CLKFREQ / rxbaudrate2) << 16) txbitrate2 := 7 + ((CLKFREQ / txbaudrate2) << 16) RETURN startpasm(@rx1_cmd, rxpin1, rxbitrate1, rxmode1, rxlutstart1, rxlutsize1, txpin1, txbitrate1, txmode1, txlutstart1, txlutsize1, rxpin2, rxbitrate2, rxmode2, rxlutstart2, rxlutsize2, txpin2, txbitrate2, txmode2, txlutstart2, txlutsize2, txclocks) ' '----------------------------------------------------------------------- 'this provides the parameter array needed to start the pasm cog on the stack '----------------------------------------------------------------------- ' PRI startpasm(mailboxaddress, rxpin1, rxbitrate1, rxmode1, rxlutstart1, rxlutsize1, txpin1, txbitrate1, txmode1, txlutstart1, txlutsize1, rxpin2, rxbitrate2, rxmode2, rxlutstart2, rxlutsize2, txpin2, txbitrate2, txmode2, txlutstart2, txlutsize2, txclocks) RETURN serpasm.start(@mailboxaddress) ' '----------------------------------------------------------------------- 'these routines need a port value, 0 for rx1 and tx1, 1 for rx2 and tx2 'if you don't provide a port value fastspin will use 0 using rx1 and tx1 '----------------------------------------------------------------------- ' ' check if byte received (never waits) ' returns -1 if no byte, otherwise byte ' PUB rxcheck(port) RESULT := 0 'result not zero on entry? RETURN rxread(0, -2, port) ' ' receive a byte (waits until done) ' returns received byte ' PUB rx(port) RESULT := 0 'result not zero on entry? rxread(@RESULT, 1, port) ' ' receive a block from serial to memory of given size in bytes (waits until done) ' PUB rxread(hubaddress, size, port) rxread_async(hubaddress, size, port) RETURN wait_rxready(port, -1) ' ' receive a block from serial to memory of given size in bytes (does not wait for completion - you may need to check rxX_cmd for -1 [done] or not later in your code) ' PUB rxread_async(hubaddress, size, port) wait_rxready(port, -1) if port rx2_param := hubaddress rx2_cmd := size else rx1_param := hubaddress rx1_cmd := size ' ' waits until rx port cmd = -1, signaling completion of last cmd or being ready for next cmd ' PUB wait_rxready(port, timeout) RESULT := -2 if port if timeout > 0 repeat timeout-- if rx2_cmd == -1 RESULT := rx2_param timeout := -10 until timeout < 0 if timeout > -10 rx2_cmd := -1 rx2_param := -1 else repeat until rx2_cmd == -1 RESULT := rx2_param else if timeout > 0 repeat timeout-- if rx1_cmd == -1 RESULT := rx1_param timeout := -10 until timeout < 0 if timeout > -10 rx1_cmd := -1 rx1_param := -1 else repeat until rx1_cmd == -1 RESULT := rx1_param ' ' returns size of receive buffer in bytes ' PUB rxsize(port) RETURN rxread(0, -4, port) ' ' returns number of bytes waiting in receive buffer ' PUB rxcount(port) RETURN rxread(0, -3, port) ' ' check if byte can be send (never waits) ' returns -1 if no space in buffer otherwise number of bytes waiting in send buffer ' PUB txcheck(port) RETURN txwrite(0, -2, port) ' ' sends a byte (waits until done) ' PUB tx(val, port) | sendbyte, rparam 'sendbyte := val '<<(32-8) 'outchar := val 'str(@outchar, port) rparam := txwrite(@val,1, port) RETURN rparam ' ' sends a byte (does not wait for completion - you may need to check tx1_cmd if done or not later in your code) ' PUB tx_async(val, port) txwrite_async(@val,1, port) ' ' sends a block from memory to serial of given size in bytes (waits until done) ' PUB txwrite(hubaddress, size, port) txwrite_async(hubaddress, size, port) RETURN wait_txready(port) ' ' sends a block from memory to serial of given size in bytes (does not wait for completion - you may need to check tx1_cmd if done or not later in your code) ' PUB txwrite_async(hubaddress, size, port) wait_txready(port) if port tx2_param := hubaddress tx2_cmd := size else tx1_param := hubaddress tx1_cmd := size ' ' waits until tx port cmd = -1, signaling completion of last cmd or being ready for next cmd ' PUB wait_txready(port) if port repeat until tx2_cmd == -1 RESULT := tx2_param else repeat until tx1_cmd == -1 RESULT := tx1_param ' ' returns number of bytes waiting in send buffer ' PUB txcount(port) RETURN txwrite(0, -3, port) ' ' returns size of send buffer in bytes ' PUB txsize(port) RETURN txwrite(0, -4, port) ' ' transmit a string (waits until done) ' PUB str(s, port) txwrite(s, -5, port) ' ' transmit a string (does not wait for completion - you may need to check tx1_cmd if done or not later in your code) ' PUB str_async(s, port) txwrite_async(s, -5, port) ' ' transmit a long as hex ' PUB hex(value, digits, leadingzero, port) if leadingzero txwrite(value, -((digits<<8)+9), port) else txwrite(value, -((digits<<8)+8), port) ' ' transmit a long as decimal ' PUB dec(value, digits, leadingzero, port) if leadingzero txwrite(value, -((digits<<8)+7), port) else txwrite(value, -((digits<<8)+6), port)