Commit 9c4cc683 authored by Hermann Mayer's avatar Hermann Mayer

Moved vendors out of src to the project root. Updated variable lenght buffering.

parent 40d0c4a9
......@@ -9,7 +9,7 @@ SET(CSTANDARD "-std=gnu99")
SET(CWARN "-Wall -Wstrict-prototypes")
SET(CTUNING "-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums")
SET(COPT "-Os")
SET(CINCS "-I${CMAKE_SOURCE_DIR}/src/vendor/arduino")
SET(CINCS "-I${CMAKE_SOURCE_DIR}/vendor/arduino")
SET(CMCU "-mmcu=atmega328p")
SET(CDEFS "-DF_CPU=16000000")
SET(CFLAGS "${CMCU} ${CDEBUG} ${CDEFS} ${CINCS} ${COPT} ${CWARN} ${CSTANDARD} ${CEXTRA} ${CTUNING}")
......@@ -20,7 +20,7 @@ SET(CXXSTANDARD "")
SET(CXXWARN "-Wall")
SET(CXXTUNING "-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -ffunction-sections -fdata-sections -Wl,--gc-sections -fno-exceptions --pedantic")
SET(CXXOPT "-Os")
SET(CXXINCS "-I${CMAKE_SOURCE_DIR}/src/vendor/arduino")
SET(CXXINCS "-I${CMAKE_SOURCE_DIR}/vendor/arduino")
SET(CXXMCU "-mmcu=atmega328p")
SET(CXXDEFS "-DF_CPU=16000000")
SET(CXXFLAGS "${CXXMCU} ${CXXDEBUG} ${CXXDEFS} ${CXXINCS} ${CXXOPT} ${CXXWARN} ${CXXSTANDARD} ${CXXEXTRA} ${CXXTUNING}")
......
......@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 2.6)
Project(Slave-Stack)
add_subdirectory(src/vendor/arduino)
add_subdirectory(src/vendor/rfm70)
add_subdirectory(vendor/arduino)
add_subdirectory(vendor/rfm70)
add_subdirectory(src/lib)
add_subdirectory(src)
/*
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
*/
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include "wiring.h"
#include "wiring_private.h"
#include "HardwareSerial.h"
// Define constants and variables for buffering incoming serial data. We're
// using a ring buffer (I think), in which rx_buffer_head is the index of the
// location to which to write the next incoming character and rx_buffer_tail
// is the index of the location from which to read.
#define RX_BUFFER_SIZE 128
struct ring_buffer {
unsigned char buffer[RX_BUFFER_SIZE];
int head;
int tail;
};
ring_buffer rx_buffer = { { 0 }, 0, 0 };
#if defined(__AVR_ATmega1280__)
ring_buffer rx_buffer1 = { { 0 }, 0, 0 };
ring_buffer rx_buffer2 = { { 0 }, 0, 0 };
ring_buffer rx_buffer3 = { { 0 }, 0, 0 };
#endif
inline void store_char(unsigned char c, ring_buffer *rx_buffer)
{
int i = (rx_buffer->head + 1) % RX_BUFFER_SIZE;
// if we should be storing the received character into the location
// just before the tail (meaning that the head would advance to the
// current location of the tail), we're about to overflow the buffer
// and so we don't write the character or advance the head.
if (i != rx_buffer->tail) {
rx_buffer->buffer[rx_buffer->head] = c;
rx_buffer->head = i;
}
}
#if defined(__AVR_ATmega1280__)
SIGNAL(SIG_USART0_RECV)
{
unsigned char c = UDR0;
store_char(c, &rx_buffer);
}
SIGNAL(SIG_USART1_RECV)
{
unsigned char c = UDR1;
store_char(c, &rx_buffer1);
}
SIGNAL(SIG_USART2_RECV)
{
unsigned char c = UDR2;
store_char(c, &rx_buffer2);
}
SIGNAL(SIG_USART3_RECV)
{
unsigned char c = UDR3;
store_char(c, &rx_buffer3);
}
#else
#if defined(__AVR_ATmega8__)
SIGNAL(SIG_UART_RECV)
#else
SIGNAL(USART_RX_vect)
#endif
{
#if defined(__AVR_ATmega8__)
unsigned char c = UDR;
#else
unsigned char c = UDR0;
#endif
store_char(c, &rx_buffer);
}
#endif
// Constructors ////////////////////////////////////////////////////////////////
HardwareSerial::HardwareSerial(ring_buffer *rx_buffer,
volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
volatile uint8_t *ucsra, volatile uint8_t *ucsrb,
volatile uint8_t *udr,
uint8_t rxen, uint8_t txen, uint8_t rxcie, uint8_t udre)
{
_rx_buffer = rx_buffer;
_ubrrh = ubrrh;
_ubrrl = ubrrl;
_ucsra = ucsra;
_ucsrb = ucsrb;
_udr = udr;
_rxen = rxen;
_txen = txen;
_rxcie = rxcie;
_udre = udre;
}
// Public Methods //////////////////////////////////////////////////////////////
void HardwareSerial::begin(long speed)
{
*_ubrrh = ((F_CPU / 16 + speed / 2) / speed - 1) >> 8;
*_ubrrl = ((F_CPU / 16 + speed / 2) / speed - 1);
sbi(*_ucsrb, _rxen);
sbi(*_ucsrb, _txen);
sbi(*_ucsrb, _rxcie);
}
uint8_t HardwareSerial::available(void)
{
return (RX_BUFFER_SIZE + _rx_buffer->head - _rx_buffer->tail) % RX_BUFFER_SIZE;
}
int HardwareSerial::read(void)
{
// if the head isn't ahead of the tail, we don't have any characters
if (_rx_buffer->head == _rx_buffer->tail) {
return -1;
} else {
unsigned char c = _rx_buffer->buffer[_rx_buffer->tail];
_rx_buffer->tail = (_rx_buffer->tail + 1) % RX_BUFFER_SIZE;
return c;
}
}
void HardwareSerial::flush()
{
// don't reverse this or there may be problems if the RX interrupt
// occurs after reading the value of rx_buffer_head but before writing
// the value to rx_buffer_tail; the previous value of rx_buffer_head
// may be written to rx_buffer_tail, making it appear as if the buffer
// don't reverse this or there may be problems if the RX interrupt
// occurs after reading the value of rx_buffer_head but before writing
// the value to rx_buffer_tail; the previous value of rx_buffer_head
// may be written to rx_buffer_tail, making it appear as if the buffer
// were full, not empty.
_rx_buffer->head = _rx_buffer->tail;
}
void HardwareSerial::write(uint8_t c)
{
while (!((*_ucsra) & (1 << _udre)))
;
*_udr = c;
}
// Preinstantiate Objects //////////////////////////////////////////////////////
#if defined(__AVR_ATmega8__)
HardwareSerial Serial(&rx_buffer, &UBRRH, &UBRRL, &UCSRA, &UCSRB, &UDR, RXEN, TXEN, RXCIE, UDRE);
#else
HardwareSerial Serial(&rx_buffer, &UBRR0H, &UBRR0L, &UCSR0A, &UCSR0B, &UDR0, RXEN0, TXEN0, RXCIE0, UDRE0);
#endif
#if defined(__AVR_ATmega1280__)
HardwareSerial Serial1(&rx_buffer1, &UBRR1H, &UBRR1L, &UCSR1A, &UCSR1B, &UDR1, RXEN1, TXEN1, RXCIE1, UDRE1);
HardwareSerial Serial2(&rx_buffer2, &UBRR2H, &UBRR2L, &UCSR2A, &UCSR2B, &UDR2, RXEN2, TXEN2, RXCIE2, UDRE2);
HardwareSerial Serial3(&rx_buffer3, &UBRR3H, &UBRR3L, &UCSR3A, &UCSR3B, &UDR3, RXEN3, TXEN3, RXCIE3, UDRE3);
#endif
/*
HardwareSerial.h - 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
*/
#ifndef HardwareSerial_h
#define HardwareSerial_h
#include <inttypes.h>
#include "Print.h"
struct ring_buffer;
class HardwareSerial : public Print
{
private:
ring_buffer *_rx_buffer;
volatile uint8_t *_ubrrh;
volatile uint8_t *_ubrrl;
volatile uint8_t *_ucsra;
volatile uint8_t *_ucsrb;
volatile uint8_t *_udr;
uint8_t _rxen;
uint8_t _txen;
uint8_t _rxcie;
uint8_t _udre;
public:
HardwareSerial(ring_buffer *rx_buffer,
volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
volatile uint8_t *ucsra, volatile uint8_t *ucsrb,
volatile uint8_t *udr,
uint8_t rxen, uint8_t txen, uint8_t rxcie, uint8_t udre);
void begin(long);
uint8_t available(void);
int read(void);
void flush(void);
virtual void write(uint8_t);
using Print::write; // pull in write(str) and write(buf, size) from Print
};
extern HardwareSerial Serial;
#if defined(__AVR_ATmega1280__)
extern HardwareSerial Serial1;
extern HardwareSerial Serial2;
extern HardwareSerial Serial3;
#endif
#endif
/*
Print.cpp - Base class that provides print() and println()
Copyright (c) 2008 David A. Mellis. 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
*/
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "wiring.h"
#include "Print.h"
// Public Methods //////////////////////////////////////////////////////////////
/* default implementation: may be overridden */
void Print::write(const char *str)
{
while (*str)
write(*str++);
}
/* default implementation: may be overridden */
void Print::write(const uint8_t *buffer, size_t size)
{
while (size--)
write(*buffer++);
}
void Print::print(uint8_t b)
{
this->write(b);
}
void Print::print(char c)
{
print((byte) c);
}
void Print::print(const char str[])
{
write(str);
}
void Print::print(int n)
{
print((long) n);
}
void Print::print(unsigned int n)
{
print((unsigned long) n);
}
void Print::print(long n)
{
if (n < 0) {
print('-');
n = -n;
}
printNumber(n, 10);
}
void Print::print(unsigned long n)
{
printNumber(n, 10);
}
void Print::print(long n, int base)
{
if (base == 0)
print((char) n);
else if (base == 10)
print(n);
else
printNumber(n, base);
}
void Print::print(double n)
{
printFloat(n, 2);
}
void Print::println(void)
{
print('\r');
print('\n');
}
void Print::println(char c)
{
print(c);
println();
}
void Print::println(const char c[])
{
print(c);
println();
}
void Print::println(uint8_t b)
{
print(b);
println();
}
void Print::println(int n)
{
print(n);
println();
}
void Print::println(unsigned int n)
{
print(n);
println();
}
void Print::println(long n)
{
print(n);
println();
}
void Print::println(unsigned long n)
{
print(n);
println();
}
void Print::println(long n, int base)
{
print(n, base);
println();
}
void Print::println(double n)
{
print(n);
println();
}
// Private Methods /////////////////////////////////////////////////////////////
void Print::printNumber(unsigned long n, uint8_t base)
{
unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars.
unsigned long i = 0;
if (n == 0) {
print('0');
return;
}
while (n > 0) {
buf[i++] = n % base;
n /= base;
}
for (; i > 0; i--)
print((char) (buf[i - 1] < 10 ?
'0' + buf[i - 1] :
'A' + buf[i - 1] - 10));
}
void Print::printFloat(double number, uint8_t digits)
{
// Handle negative numbers
if (number < 0.0)
{
print('-');
number = -number;
}
// Round correctly so that print(1.999, 2) prints as "2.00"
double rounding = 0.5;
for (uint8_t i=0; i<digits; ++i)
rounding /= 10.0;
number += rounding;
// Extract the integer part of the number and print it
unsigned long int_part = (unsigned long)number;
double remainder = number - (double)int_part;
print(int_part);
// Print the decimal point, but only if there are digits beyond
if (digits > 0)
print(".");
// Extract digits from the remainder one at a time
while (digits-- > 0)
{
remainder *= 10.0;
int toPrint = int(remainder);
print(toPrint);
remainder -= toPrint;
}
}
/*
Print.h - Base class that provides print() and println()
Copyright (c) 2008 David A. Mellis. 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
*/
#ifndef Print_h
#define Print_h
#include <inttypes.h>
#include <stdio.h> // for size_t
#define DEC 10
#define HEX 16
#define OCT 8
#define BIN 2
#define BYTE 0
class Print
{
private:
void printNumber(unsigned long, uint8_t);
void printFloat(double, uint8_t);
public:
virtual void write(uint8_t) = 0;
virtual void write(const char *str);
virtual void write(const uint8_t *buffer, size_t size);
void print(char);
void print(const char[]);
void print(uint8_t);
void print(int);
void print(unsigned int);
void print(long);
void print(unsigned long);
void print(long, int);
void print(double);
void println(void);
void println(char);
void println(const char[]);
void println(uint8_t);
void println(int);
void println(unsigned int);
void println(long);
void println(unsigned long);
void println(long, int);
void println(double);
};
#endif
/*
Stream.h - base class for character-based streams.
Copyright (c) 2010 David A. Mellis. 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
*/
#ifndef Stream_h
#define Stream_h
#include <inttypes.h>
#include "Print.h"
class Stream : public Print
{
public:
virtual int available() = 0;
virtual int read() = 0;
virtual int peek() = 0;
virtual void flush() = 0;
};
#endif
/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
Part of the Wiring project - http://wiring.uniandes.edu.co
Copyright (c) 2004-05 Hernando Barragan
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., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
Modified 24 November 2006 by David A. Mellis
*/
#include <inttypes.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <stdio.h>
#include "WConstants.h"
#include "wiring_private.h"
volatile static voidFuncPtr intFunc[EXTERNAL_NUM_INTERRUPTS];
// volatile static voidFuncPtr twiIntFunc;
#if defined(__AVR_ATmega8__)
#define EICRA MCUCR
#define EIMSK GICR
#endif
void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode) {
if(interruptNum < EXTERNAL_NUM_INTERRUPTS) {
intFunc[interruptNum] = userFunc;
// Configure the interrupt mode (trigger on low input, any change, rising
// edge, or falling edge). The mode constants were chosen to correspond
// to the configuration bits in the hardware register, so we simply shift
// the mode into place.
// Enable the interrupt.
switch (interruptNum) {
#if defined(__AVR_ATmega1280__)
case 2:
EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
EIMSK |= (1 << INT0);
break;
case 3:
EICRA = (EICRA & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10);
EIMSK |= (1 << INT1);
break;
case 4:
EICRA = (EICRA & ~((1 << ISC20) | (1 << ISC21))) | (mode << ISC20);
EIMSK |= (1 << INT2);
break;
case 5:
EICRA = (EICRA & ~((1 << ISC30) | (1 << ISC31))) | (mode << ISC30);
EIMSK |= (1 << INT3);
break;
case 0:
EICRB = (EICRB & ~((1 << ISC40) | (1 << ISC41))) | (mode << ISC40);
EIMSK |= (1 << INT4);
break;
case 1:
EICRB = (EICRB & ~((1 << ISC50) | (1 << ISC51))) | (mode << ISC50);
EIMSK |= (1 << INT5);
break;
case 6:
EICRB = (EICRB & ~((1 << ISC60) | (1 << ISC61))) | (mode << ISC60);
EIMSK |= (1 << INT6);
break;
case 7:
EICRB = (EICRB & ~((1 << ISC70) | (1 << ISC71))) | (mode << ISC70);
EIMSK |= (1 << INT7);
break;
#else
case 0:
EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
EIMSK |= (1 << INT0);
break;