Full Duplex Serial Port Driver

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
Request group membership
By: Kwabena W. Agyeman, created: 2013-04-09 | updated: 2013-05-20

A full duplex serial port driver that runs on one cog. The code has been fully optimized with a super simple spin interface for maximum speed and is also fully commented.

Provides full support for:

  • Receiving bytes,
  • Receiving words,
  • Receiving longs,
  • Receiving strings,
  • Transmitting bytes,
  • Transmitting words,
  • Transmitting longs,
  • Transmitting strings,
  • Getting the number of bytes in the RX buffer.
  • Getting the number of bytes in the TX buffer.
  • Checking if the RX buffer is empty or full.
  • Checking if the TX buffer is empty or full.
  • Flushing the RX buffer.
  • Filling the TX buffer.
  • Live baud rate changing.
  • Live stop bit changing.

Baud Rate from 1 BPS to 250,000 BPS @ 96 MHz - Full Duplex

This driver has a 256 byte receiving FIFO buffer.This driver has a 256 byte transmitting FIFO buffer.


Original File Upload
Package icon Full-Duplex_Tester_7.zip8.94 KB


[originally posted by Anonymous on 2010-10-27 00:53:50] This object only includes a byte receive function with waiting? Is it possible to make it compatible with FullDuplexSerial?

[originally posted by Anonymous on 2011-02-04 22:42:30] 
This is great -- faster & smaller than fullduplexserial. I took the liberty to modify it so that it's compatible with fullduplexserial. Leave the Assembly code alone and replace the Spin code with this: PUB rx '' 6 Stack Longs repeat until(available) return inputBuffer[inputTail++] PUB available '' 3 Stack Longs return ((inputHead - inputTail) & $FF) PUB rxfull '' 6 Stack Longs return (available == $FF) PUB rxflush '' 3 Stack Longs inputTail := inputHead PUB tx(character) '' 4 Stack Longs repeat until(outputTail <> ((outputHead + 1) & $FF)) outputBuffer[outputHead++] := character PUB str(StringAddr) '' 8 Stack Longs repeat strsize(StringAddr) tx(byte[StringAddr++]) PUB rxcheck : rxbyte if (available) return inputBuffer[inputTail++] return -1 PUB rxtime(ms) : t '' Wait ms milliseconds for a byte to be received '' returns -1 if no byte received, $00..$FF if byte t := cnt repeat if (cnt - t) / (clkfreq / 1000) > ms return -1 until available return inputBuffer[inputTail++] pub start (rp,tp,f,b) ' for compatibility with fullduplexserial: flags are not actually read return init(rp,tp,b) PUB init(receiverPin, transmitterPin, baudRate) '' 9 Stack Longs stop baudRateSetup := ((clkfreq / ((baudRate <# (clkfreq / constant(80_000_000 / 250_000))) #> 1)) / 4) baudRate := ((transmitterPin <# 31) #> 0) counterModeSetup := (baudRate + constant(%0_0100 << 26)) RXPin := ((|<((receiverPin <# 31) #> 0)) & (receiverPin <> -1)) TXPin := ((|<baudRate) & (transmitterPin <> -1)) inputHeadAddress := @inputHead inputTailAddress := @inputTail outputHeadAddress := @outputHead outputTailAddress := @outputTail inputBufferAddress := @inputBuffer outputBufferAddress := @outputBuffer cog := cognew(@initialization[0], @cog[0]) result or= ++cog PUB stop '' 3 Stack Longs if(cog) cogstop(-1 + cog~) 'mkb@libero.it
[originally posted by Anonymous on 2011-05-11 17:54:44] Warning, this driver (rev 1.6) suffers from occasional data corruption. The author is aware of that fact. For details check this thread in the forum http://forums.parallax.com/showthread.php?129764-Key-File-System-Driver-...
[originally posted by Anonymous on 2011-05-16 01:51:57] This driver does not attempt to sample close to the center of the bit and quite often samples close to bit transitions. It therefore is unreliable even when the two systems that are communicating have tight clock tolerances. It appears from previous comments that the author has known about this bug for a few months but has failed to do the right thing and fix the issue. I personally spent 2 solid days debugging my system and ultimately replacing the driver completely. How many other folks have paid this price I wonder? 
[originally posted by Kwabena W. Agyeman on 2011-07-30 02:55:20] Sorry, guys - I've been busy working on a bunch of other projects that have taken my time away from this. I've updated the driver now and you should no longer have any problems. To above anonymous - I assumed people would stop using it until I could get arround to fixing it. Thanks,