Full Serial Port Driver
Kye
Posts: 2,200
Hey guys,
I just* finished a new full serial port driver.
So, it can:
The driver is pretty robust and has been fully optimized (with a bit of padding) and works really good at lower baud rates. Increasing the baud speed by alot makes the noise found in the lines alot more visible so be aware. 19200 BPS is the sweet spot.
You will also need to change the I/O lines within the file to match your setup. I have however also supplied some SPIN code that will transmit and receive for you in the COM rx and tx functions that use pin 31 and 30.The spin code used in those functions is alot better than the simple serial code produced by parallax so feel free to used that code in any other file.
Note that all the pins are driven through open drain outputs·so you need to the pull up·resistors refrenced in the file.
I've also included information about·the stack size for each function (using the information Chip Gracey gave in the web-seminars) and if the functions return value should be ignored.
Anyway, enjoy.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
Post Edited (Kye) : 5/8/2009 10:38:25 PM GMT
I just* finished a new full serial port driver.
So, it can:
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Serial Engine │ │ │ │ Author: Kwabena W. Agyeman │ │ Updated: 4/14/2009 │ │ Designed For: P8X32A │ │ │ │ Copyright (c) 2009 Kwabena W. Agyeman │ │ See end of file for terms of use. │ │ │ │ Driver Info: │ │ │ │ The serial engine runs a UART driver in the next free cog on the propeller chip when called. │ │ │ │ The driver, is only guaranteed and tested to work at an 80Mhz system clock or higher. The driver is designed for the P8X32A │ │ so port B will not be operational. │ │ │ │ Nyamekye, │ └─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ Object "serialEngine" Interface: PUB generateEvenParity(value) PUB generateOddParity(value) PUB generateMarkParity(value) PUB generateSpaceParity(value) PUB checkEvenParity(value) PUB checkOddParity(value) PUB checkMarkParity(value) PUB checkSpaceParity(value) PUB setDTR(state) PUB getDSR PUB getDCD PUB getRI PUB receiveCharacter PUB receiveNumber PUB receiverFull PUB receiverFlush PUB receiveCheck(character) PUB transmitCharacter(character) PUB transmitCharacters(characters) PUB transmiterFlush PUB COMReceiveCharacter(baudBitRate) : temp PUB COMTransmitCharacter(character, baudBitRate) PUB COMTransmitCharacters(charactersToSend, baudBitRate) PUB changeSettings(baudRateSetting, flowControlSetting, stopBitsSetting) PUB serialEngine(baudRateSetting, flowControlSetting, stopBitsSetting) Program: 212 Longs Variable: 132 Longs ______________________________ PUB generateEvenParity(value) 8 Stack Longs ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Generates an even parity for a value. │ │ │ │ Returns that value with the parity. │ │ │ │ Value = A byte whoose MSB parity bit will be changed. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ _____________________________ PUB generateOddParity(value) 8 Stack Longs ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Generates an odd parity for a value. │ │ │ │ Returns that value with the parity. │ │ │ │ Value = A byte whoose MSB parity bit will be changed. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ ______________________________ PUB generateMarkParity(value) 4 Stack Longs ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Generates a mark parity for a value. │ │ │ │ Returns that value with the parity. │ │ │ │ Value = A byte whoose MSB parity bit will be changed. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ _______________________________ PUB generateSpaceParity(value) 4 Stack Longs ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Generates a space parity for a value. │ │ │ │ Returns that value with the parity. │ │ │ │ Value = A byte whoose MSB parity bit will be changed. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ ___________________________ PUB checkEvenParity(value) 8 Stack Longs ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Returns true if the parity is correct and false if not. │ │ │ │ Value = A byte whoose parity will be checked to be even. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ __________________________ PUB checkOddParity(value) 8 Stack Longs ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Returns true if the parity is correct and false if not. │ │ │ │ Value = A byte whoose parity will be checked to be odd. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ ___________________________ PUB checkMarkParity(value) 4 Stack Longs ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Returns true if the parity is correct and false if not. │ │ │ │ Value = A byte whoose parity will be checked to be mark. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ ____________________________ PUB checkSpaceParity(value) 4 Stack Longs ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Returns true if the parity is correct and false if not. │ │ │ │ Value = A byte whoose parity will be checked to be space. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ __________________ PUB setDTR(state) 4 Stack Longs - Ignore Return Value ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Changes the state of the DTR line. │ │ │ │ State = The new state of the DTR line. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ ___________ PUB getDSR 3 Stack Longs ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Returns the state of the DSR line. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ ___________ PUB getDCD 3 Stack Longs ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Returns the state of the DCD line. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ __________ PUB getRI 3 Stack Longs ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Returns the state of the RI line. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ _____________________ PUB receiveCharacter 11 Stack Longs ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Returns the first character in the receiver buffer or zero if empty. Use "receiveNumber" to check for characters. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ __________________ PUB receiveNumber 8 Stack Longs ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Returns the number of characters in the receiver buffer. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ _________________ PUB receiverFull 11 Stack Longs ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Returns true if the receiver buffer is full and false if not. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ __________________ PUB receiverFlush 3 Stack Longs - Ignore Return Value ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Flushes (empties) the receiver buffer. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ ____________________________ PUB receiveCheck(character) 12 Stack Longs ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Compares the last character in the receiver buffer with the specified character. │ │ │ │ Returns true if they are equal and false otherwise. │ │ │ │ Character - Character to compare the last received character with for equality. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ _________________________________ PUB transmitCharacter(character) 9 Stack Longs ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Transmits a character. │ │ │ │ Returns true on sucess and false of failure. │ │ │ │ Character - Character to transmit. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ ___________________________________ PUB transmitCharacters(characters) 13 Stack Longs ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Transmits a strings characters. │ │ │ │ Returns true on sucess and false of failure. │ │ │ │ Characters - A pointer to the string of characters to transmit. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ ____________________ PUB transmiterFlush 3 Stack Longs - Ignore Return Value ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Flushes (empties) the transmiter buffer. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ ____________________________________________ PUB COMReceiveCharacter(baudBitRate) : temp 5 Stack Longs ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Receives a character on the communications port. Pauses code execution indefinitely until the character is received. │ │ │ │ Returns the received character. │ │ │ │ BaudBitRate - Baud rate to receive the character at between 19200 BPS and 300 BPS. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ _________________________________________________ PUB COMTransmitCharacter(character, baudBitRate) 5 Stack Longs - Ignore Return Value ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Transmits a character on the communications port. Pauses code execution indefinitely until the character is transmited. │ │ │ │ Character - Character to transmit. │ │ BaudBitRate - Baud rate to transmit the character at between 19200 BPS and 300 BPS. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ _________________________________________________________ PUB COMTransmitCharacters(charactersToSend, baudBitRate) 10 Stack Longs - Ignore Return Value ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Transmits a string of characters on the communications port. Pauses code execution indefinitely until the string of │ │ characters are transmited. │ │ │ │ CharactersToSend - A pointer to the string of characters to transmit. │ │ BaudBitRate - Baud rate to transmit the string of characters at between 19200 BPS and 300 BPS. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ _________________________________________________________________________ PUB changeSettings(baudRateSetting, flowControlSetting, stopBitsSetting) 6 Stack Longs - Ignore Return Value ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Changes the current uart settings. │ │ │ │ BaudRateSetting - Baud rate to transmit and receive at - between 300 BPS and 115200 BPS. │ │ FlowControlSetting - Logical on or off of flow control - true for on and false for off. │ │ StopBitsSetting - Number of stop bits to transmit - between 1 and 23. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘ _______________________________________________________________________ PUB serialEngine(baudRateSetting, flowControlSetting, stopBitsSetting) 12 Stack Longs ┌──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ Initializes the UART driver to run on a new cog. │ │ │ │ Returns the new cog's ID on sucess or -1 on failure. │ │ │ │ BaudRateSetting - Baud rate to transmit and receive at - between 300 BPS and 115200 BPS. │ │ FlowControlSetting - Logical on or off of flow control - true for on and false for off. │ │ StopBitsSetting - Number of stop bits to transmit - between 1 and 23. │ └──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
The driver is pretty robust and has been fully optimized (with a bit of padding) and works really good at lower baud rates. Increasing the baud speed by alot makes the noise found in the lines alot more visible so be aware. 19200 BPS is the sweet spot.
You will also need to change the I/O lines within the file to match your setup. I have however also supplied some SPIN code that will transmit and receive for you in the COM rx and tx functions that use pin 31 and 30.The spin code used in those functions is alot better than the simple serial code produced by parallax so feel free to used that code in any other file.
Note that all the pins are driven through open drain outputs·so you need to the pull up·resistors refrenced in the file.
I've also included information about·the stack size for each function (using the information Chip Gracey gave in the web-seminars) and if the functions return value should be ignored.
Anyway, enjoy.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
Post Edited (Kye) : 5/8/2009 10:38:25 PM GMT
Comments
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
Propalyzer: Propeller PC Logic Analyzer
http://forums.parallax.com/showthread.php?p=788230
Lite version now in the obex - replaces the 256 byte fifo buffered serial driver.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
Post Edited (Kye) : 5/10/2009 3:48:47 PM GMT
So why use that, well - what if you want to disable a pin?
Pin 32 doesn't exist so there's how.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
Propalyzer: Propeller PC Logic Analyzer
http://forums.parallax.com/showthread.php?p=788230
As long as it's wrapped in constant() it doesn't matter.
As for using "dira[noparse][[/noparse] i] or dira[noparse][[/noparse] i + 32n]" in a constant statement... well, I wasn't using that...
I believe the (1 << ((pin <# 32) #> 0)) gets the job done well enough. No reason to change it since its doesn't matter.
...
If there are any problems with the actual operation of the driver please speak up, thanks.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
How can you wrap anything with a variable in it in constant() ??? Maybe I missed something.
It was nice of you to offer your code review. As you probably know, this kind of discussion happens
all the time in a professional setting where there are many potential users in the software team.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
Propalyzer: Propeller PC Logic Analyzer
http://forums.parallax.com/showthread.php?p=788230
DTR_Pin is a constant. What I meant was that the above expression uses up the same space as
Either way, I still don't see the point of the range check as any number used as a dira & Co index is ANDed with $1F before it's applied. Also (1 << 32) == 1 in PASM and SPIN.
What I'm trying to understand is how this magic pin 32 can be used to disable a pin when it ends up as pin 0?
Post Edited (kuroneko) : 5/11/2009 6:17:50 AM GMT
Great work on turbulence by the way ....
It is not clear at all what dira[noparse][[/noparse]32] := 1 would do. It might translate to dira[noparse][[/noparse]0] if dira spin uses 1 << 32 as you suggest.
But either (pin <# 32) or (pin & $1f) construct would yield a potentially undesirable result in any event.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
--Steve
Propalyzer: Propeller PC Logic Analyzer
http://forums.parallax.com/showthread.php?p=788230
But, yes I see what you are refering to. I forgot about that part in spin. I was onlying thinking about the asm part.
...
Okay, so how should I change it so you can disable the pin without any extra code?
Or, should I just change the range to valid numbers?
...
I'll just change the range to valid numbers for now.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nyamekye,
Post Edited (Kye) : 5/12/2009 1:22:05 PM GMT
The code does what you expect it to do.
If I need to optimize for speed and use unexpected syntax, I carefully explain in comments the reasoning for the unexpected.
Regardless, good job...
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
JMH