From 8111ed7c07a31dd99a323a0a29f9e99dd54c6d80 Mon Sep 17 00:00:00 2001 From: Yuval Adam Date: Wed, 15 May 2013 22:34:48 +0300 Subject: Lots of project tests --- demopal/lib/pollserial/pollserial.cpp | 139 ++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100755 demopal/lib/pollserial/pollserial.cpp (limited to 'demopal/lib/pollserial/pollserial.cpp') diff --git a/demopal/lib/pollserial/pollserial.cpp b/demopal/lib/pollserial/pollserial.cpp new file mode 100755 index 0000000..a417098 --- /dev/null +++ b/demopal/lib/pollserial/pollserial.cpp @@ -0,0 +1,139 @@ +/* + pollserial.cpp Heavily modified version of: + + HardwareSerial.cpp - Hardware serial library for Wiring + Copyright (c) 2006 Nicholas Zambetti. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + Modified 23 November 2006 by David A. Mellis + + Modified July 2010 by Myles D. Metzler +*/ + +#include +#include +#include "pollserial.h" + +#define BUFFER_SIZE 64 + +rbuffer rxbuffer = {0,0,0}; + +void USART_recieve() { +#if defined ( UDR0 ) + if( UCSR0A & _BV(RXC0)) { + uint8_t i = (rxbuffer.head + 1) & (BUFFER_SIZE - 1); + if ( i != rxbuffer.tail) { + rxbuffer.buffer[rxbuffer.head] = UDR0; + rxbuffer.head = i; + } + } +#else + if( UCSRA & _BV(RXC)) { + uint8_t i = (rxbuffer.head + 1) & (BUFFER_SIZE - 1); + if ( i != rxbuffer.tail) { + rxbuffer.buffer[rxbuffer.head] = UDR; + rxbuffer.head = i; + } + } +#endif +} + +pt2Funct pollserial::begin(long baud) { + uint16_t baud_setting; + bool use_u2x; + + rxbuffer.buffer = (unsigned char*)malloc(BUFFER_SIZE*sizeof(unsigned char)); + + // U2X mode is needed for baud rates higher than (CPU Hz / 16) + if (baud > F_CPU / 16) { + use_u2x = true; + } + else { + // figure out if U2X mode would allow for a better connection + + // calculate the percent difference between the baud-rate specified and + // the real baud rate for both U2X and non-U2X mode (0-255 error percent) + uint8_t nonu2x_baud_error = abs((int)(255-((F_CPU/(16*(((F_CPU/8/baud-1)/2)+1))*255)/baud))); + uint8_t u2x_baud_error = abs((int)(255-((F_CPU/(8*(((F_CPU/4/baud-1)/2)+1))*255)/baud))); + + // prefer non-U2X mode because it handles clock skew better + use_u2x = (nonu2x_baud_error > u2x_baud_error); + } + if (use_u2x) { +#if defined ( UDR0 ) + UCSR0A = _BV(U2X0); +#else + UCSRA = _BV(U2X); +#endif + baud_setting = (F_CPU / 4 / baud - 1) / 2; + } + else { +#if defined ( UDR0 ) + UCSR0A = 0; +#else + UCSRA = 0; +#endif + baud_setting = (F_CPU / 8 / baud - 1) / 2; + } + + // assign the baud_setting, a.k.a. (USART Baud Rate Register) +#if defined ( UDR0 ) + UBRR0 = baud_setting; + UCSR0B = _BV(RXEN0) | _BV(TXEN0); +#else + UBRR = baud_setting; + UCSRB = _BV(RXEN) | _BV(TXEN); +#endif + + return &USART_recieve; +} + +void pollserial::end() { + UCSR0B &= ~(_BV(RXEN0) | _BV(TXEN0)); + free(rxbuffer.buffer); +} + +uint8_t pollserial::available() { + return (BUFFER_SIZE + rxbuffer.head - rxbuffer.tail) & (BUFFER_SIZE-1); +} + +int pollserial::read() { + if (rxbuffer.head == rxbuffer.tail) + return -1; + else { + uint8_t c = rxbuffer.buffer[rxbuffer.tail]; + //tail = (tail + 1) & 63; + if (rxbuffer.tail == BUFFER_SIZE) + rxbuffer.tail = 0; + else + rxbuffer.tail++; + return c; + } +} + +void pollserial::flush() { + rxbuffer.head = rxbuffer.tail; +} + +size_t pollserial::write(uint8_t c) { +#if defined ( UDR0 ) + while (!((UCSR0A) & _BV(UDRE0))); + UDR0 = c; +#else + while (!((UCSRA) & _BV(UDRE))); + UDR = c; +#endif +} \ No newline at end of file -- cgit v1.3.1