switch to setup for Arduino Boards Manager

This commit is contained in:
Erik Tylek Kettenburg
2015-06-23 12:42:35 -07:00
parent bc55c9bb45
commit 6ca6b114d5
3581 changed files with 93 additions and 51 deletions

View File

@@ -0,0 +1,6 @@
#ifndef Arduino_h
#define Arduino_h
#include <WProgram.h>
#endif

View File

@@ -0,0 +1,308 @@
/*
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 28 September 2010 by Mark Sproul
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include "core_build_options.h"
#include "wiring.h"
#include "wiring_private.h"
// this next line disables the entire HardwareSerial.cpp,
// this is so I can support Attiny series and any other chip without a uart
#if defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H)
#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.
#if (RAMEND < 1000)
#define RX_BUFFER_SIZE 32
#else
#define RX_BUFFER_SIZE 128
#endif
struct ring_buffer
{
unsigned char buffer[RX_BUFFER_SIZE];
int head;
int tail;
};
#if defined(UBRRH) || defined(UBRR0H)
ring_buffer rx_buffer = { { 0 }, 0, 0 };
#endif
#if defined(UBRR1H)
ring_buffer rx_buffer1 = { { 0 }, 0, 0 };
#endif
#if defined(UBRR2H)
ring_buffer rx_buffer2 = { { 0 }, 0, 0 };
#endif
#if defined(UBRR3H)
ring_buffer rx_buffer3 = { { 0 }, 0, 0 };
#endif
inline void store_char(unsigned char c, ring_buffer *rx_buffer)
{
int i = (unsigned int)(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(USART_RX_vect)
SIGNAL(USART_RX_vect)
{
#if defined(UDR0)
unsigned char c = UDR0;
#elif defined(UDR)
unsigned char c = UDR; // atmega8535
#else
#error UDR not defined
#endif
store_char(c, &rx_buffer);
}
#elif defined(SIG_USART0_RECV) && defined(UDR0)
SIGNAL(SIG_USART0_RECV)
{
unsigned char c = UDR0;
store_char(c, &rx_buffer);
}
#elif defined(SIG_UART0_RECV) && defined(UDR0)
SIGNAL(SIG_UART0_RECV)
{
unsigned char c = UDR0;
store_char(c, &rx_buffer);
}
//#elif defined(SIG_USART_RECV)
#elif defined(USART0_RX_vect)
// fixed by Mark Sproul this is on the 644/644p
//SIGNAL(SIG_USART_RECV)
SIGNAL(USART0_RX_vect)
{
#if defined(UDR0)
unsigned char c = UDR0;
#elif defined(UDR)
unsigned char c = UDR; // atmega8, atmega32
#else
#error UDR not defined
#endif
store_char(c, &rx_buffer);
}
#elif defined(SIG_UART_RECV)
// this is for atmega8
SIGNAL(SIG_UART_RECV)
{
#if defined(UDR0)
unsigned char c = UDR0; // atmega645
#elif defined(UDR)
unsigned char c = UDR; // atmega8
#endif
store_char(c, &rx_buffer);
}
#elif defined(USBCON)
#warning No interrupt handler for usart 0
#warning Serial(0) is on USB interface
#else
#error No interrupt handler for usart 0
#endif
//#if defined(SIG_USART1_RECV)
#if defined(USART1_RX_vect)
//SIGNAL(SIG_USART1_RECV)
SIGNAL(USART1_RX_vect)
{
unsigned char c = UDR1;
store_char(c, &rx_buffer1);
}
#elif defined(SIG_USART1_RECV)
#error SIG_USART1_RECV
#endif
#if defined(USART2_RX_vect) && defined(UDR2)
SIGNAL(USART2_RX_vect)
{
unsigned char c = UDR2;
store_char(c, &rx_buffer2);
}
#elif defined(SIG_USART2_RECV)
#error SIG_USART2_RECV
#endif
#if defined(USART3_RX_vect) && defined(UDR3)
SIGNAL(USART3_RX_vect)
{
unsigned char c = UDR3;
store_char(c, &rx_buffer3);
}
#elif defined(SIG_USART3_RECV)
#error SIG_USART3_RECV
#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, uint8_t u2x)
{
_rx_buffer = rx_buffer;
_ubrrh = ubrrh;
_ubrrl = ubrrl;
_ucsra = ucsra;
_ucsrb = ucsrb;
_udr = udr;
_rxen = rxen;
_txen = txen;
_rxcie = rxcie;
_udre = udre;
_u2x = u2x;
}
// Public Methods //////////////////////////////////////////////////////////////
void HardwareSerial::begin(long baud)
{
uint16_t baud_setting;
bool use_u2x = true;
#if F_CPU == 16000000UL
// hardcoded exception for compatibility with the bootloader shipped
// with the Duemilanove and previous boards and the firmware on the 8U2
// on the Uno and Mega 2560.
if (baud == 57600) {
use_u2x = false;
}
#endif
if (use_u2x) {
*_ucsra = 1 << _u2x;
baud_setting = (F_CPU / 4 / baud - 1) / 2;
} else {
*_ucsra = 0;
baud_setting = (F_CPU / 8 / baud - 1) / 2;
}
// assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register)
*_ubrrh = baud_setting >> 8;
*_ubrrl = baud_setting;
sbi(*_ucsrb, _rxen);
sbi(*_ucsrb, _txen);
sbi(*_ucsrb, _rxcie);
}
void HardwareSerial::end()
{
cbi(*_ucsrb, _rxen);
cbi(*_ucsrb, _txen);
cbi(*_ucsrb, _rxcie);
}
int HardwareSerial::available(void)
{
return (unsigned int)(RX_BUFFER_SIZE + _rx_buffer->head - _rx_buffer->tail) % RX_BUFFER_SIZE;
}
int HardwareSerial::peek(void)
{
if (_rx_buffer->head == _rx_buffer->tail) {
return -1;
} else {
return _rx_buffer->buffer[_rx_buffer->tail];
}
}
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 = (unsigned int)(_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;
}
size_t HardwareSerial::write(uint8_t c)
{
while (!((*_ucsra) & (1 << _udre)))
;
*_udr = c;
return( 1 );
}
// Preinstantiate Objects //////////////////////////////////////////////////////
#if ! DEFAULT_TO_TINY_DEBUG_SERIAL
#if defined(UBRRH) && defined(UBRRL)
HardwareSerial Serial(&rx_buffer, &UBRRH, &UBRRL, &UCSRA, &UCSRB, &UDR, RXEN, TXEN, RXCIE, UDRE, U2X);
#elif defined(UBRR0H) && defined(UBRR0L)
HardwareSerial Serial(&rx_buffer, &UBRR0H, &UBRR0L, &UCSR0A, &UCSR0B, &UDR0, RXEN0, TXEN0, RXCIE0, UDRE0, U2X0);
#elif defined(USBCON)
#warning no serial port defined (port 0)
#else
#error no serial port defined (port 0)
#endif
#endif
#if defined(UBRR1H)
HardwareSerial Serial1(&rx_buffer1, &UBRR1H, &UBRR1L, &UCSR1A, &UCSR1B, &UDR1, RXEN1, TXEN1, RXCIE1, UDRE1, U2X1);
#endif
#if defined(UBRR2H)
HardwareSerial Serial2(&rx_buffer2, &UBRR2H, &UBRR2L, &UCSR2A, &UCSR2B, &UDR2, RXEN2, TXEN2, RXCIE2, UDRE2, U2X2);
#endif
#if defined(UBRR3H)
HardwareSerial Serial3(&rx_buffer3, &UBRR3H, &UBRR3L, &UCSR3A, &UCSR3B, &UDR3, RXEN3, TXEN3, RXCIE3, UDRE3, U2X3);
#endif
#endif // whole file

View File

@@ -0,0 +1,77 @@
/*
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
Modified 28 September 2010 by Mark Sproul
*/
#ifndef HardwareSerial_h
#define HardwareSerial_h
#include <inttypes.h>
#include "core_build_options.h"
#include "Stream.h"
struct ring_buffer;
class HardwareSerial : public Stream
{
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;
uint8_t _u2x;
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, uint8_t u2x);
void begin(long);
void end();
virtual int available(void);
virtual int peek(void);
virtual int read(void);
virtual void flush(void);
virtual size_t write(uint8_t);
using Print::write; // pull in write(str) and write(buf, size) from Print
};
#if (defined(UBRRH) || defined(UBRR0H)) && ! DEFAULT_TO_TINY_DEBUG_SERIAL
extern HardwareSerial Serial;
#elif defined(USBCON)
#include "usb_api.h"
#endif
#if defined(UBRR1H)
extern HardwareSerial Serial1;
#endif
#if defined(UBRR2H)
extern HardwareSerial Serial2;
#endif
#if defined(UBRR3H)
extern HardwareSerial Serial3;
#endif
#endif

View File

@@ -0,0 +1,247 @@
/*
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 <stdlib.h>
#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(const String &s)
{
for (int i = 0; i < s.length(); i++) {
write(s[i]);
}
}
void Print::print(const char str[])
{
write(str);
}
void Print::print(char c, int base)
{
print((long) c, base);
}
void Print::print(unsigned char b, int base)
{
print((unsigned long) b, base);
}
void Print::print(int n, int base)
{
print((long) n, base);
}
void Print::print(unsigned int n, int base)
{
print((unsigned long) n, base);
}
void Print::print(long n, int base)
{
if (base == 0) {
write(n);
} else if (base == 10) {
if (n < 0) {
print('-');
n = -n;
}
printNumber(n, 10);
} else {
printNumber(n, base);
}
}
void Print::print(unsigned long n, int base)
{
if (base == 0) write(n);
else printNumber(n, base);
}
void Print::print(double n, int digits)
{
printFloat(n, digits);
}
int Print::print( fstr_t* s )
{
int rv;
char ch;
rv = 0;
ch = pgm_read_byte( s );
while ( ch != 0 )
{
write( ch );
++s;
++rv;
ch = pgm_read_byte( s );
}
return( rv );
}
int Print::println(void)
{
print('\r');
print('\n');
return( 2 );
}
void Print::println(const String &s)
{
print(s);
println();
}
void Print::println(const char c[])
{
print(c);
println();
}
void Print::println(char c, int base)
{
print(c, base);
println();
}
void Print::println(unsigned char b, int base)
{
print(b, base);
println();
}
void Print::println(int n, int base)
{
print(n, base);
println();
}
void Print::println(unsigned int n, int base)
{
print(n, base);
println();
}
void Print::println(long n, int base)
{
print(n, base);
println();
}
void Print::println(unsigned long n, int base)
{
print(n, base);
println();
}
void Print::println(double n, int digits)
{
print(n, digits);
println();
}
int Print::println( fstr_t* s )
{
int rv;
rv = print( s );
rv += println();
return( rv );
}
// 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;
}
}

View File

@@ -0,0 +1,108 @@
/*
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
Modified 20-11-2010 by B.Cook ...
http://arduiniana.org/libraries/flash/
Printable support thanks to Mikal Hart
*/
#ifndef Print_h
#define Print_h
#include <inttypes.h>
#include <stdio.h> // for size_t
#include <avr/pgmspace.h>
#include "WString.h"
#define DEC 10
#define HEX 16
#define OCT 8
#define BIN 2
#define BYTE 0
#define ARDUINO_CORE_PRINTABLE_SUPPORT
class Print;
/* Printable...*/
class _Printable
{
public:
virtual void print(Print &stream) const = 0;
};
/* ...Printable */
typedef struct
{
char c;
}
fstr_t;
/* rmv: Use the macro below in preparation for the next Arduino release.
# define FSTR(s) ((fstr_t*)PSTR(s))
*/
# define F(s) ((fstr_t*)PSTR(s))
class Print
{
private:
void printNumber(unsigned long, uint8_t);
void printFloat(double, uint8_t);
protected:
void setWriteError(int err = 1) { /*write_error = err;*/ }
public:
virtual size_t write(uint8_t) = 0;
virtual void write(const char *str);
virtual void write(const uint8_t *buffer, size_t size);
void print(const String &);
void print(const char[]);
void print(char, int = BYTE);
void print(unsigned char, int = BYTE);
void print(int, int = DEC);
void print(unsigned int, int = DEC);
void print(long, int = DEC);
void print(unsigned long, int = DEC);
void print(double, int = 2);
int print( fstr_t* );
void println(const String &s);
void println(const char[]);
void println(char, int = BYTE);
void println(unsigned char, int = BYTE);
void println(int, int = DEC);
void println(unsigned int, int = DEC);
void println(long, int = DEC);
void println(unsigned long, int = DEC);
void println(double, int = 2);
int println( fstr_t* );
int println(void);
public:
/* Printable...*/
void println(const _Printable &obj)
{ obj.print(*this); println(); }
void print(const _Printable &obj)
{ obj.print(*this); };
/* ...Printable */
};
#endif

View File

@@ -0,0 +1,65 @@
/*==============================================================================
PwmTimer.h - Veneer for the PWM timers.
Copyright 2010 Rowdy Dog Software.
This file is part of Arduino-Tiny.
Arduino-Tiny 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 3 of the License, or (at your
option) any later version.
Arduino-Tiny 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 Arduino-Tiny. If not, see <http://www.gnu.org/licenses/>.
==============================================================================*/
#ifndef PwmTimer_h
#define PwmTimer_h
#include "core_pins.h"
#include "core_timers.h"
#define PwmTimer3_(t,f,c) TIMER_PASTE_CHANNEL_A( Timer, t, f, c )
#define PwmTimer2_(t,f) TIMER_PASTE_A( Timer, t, f )
#if CORE_PWM_COUNT >= 1
#define Pwm0_SetCompareOutputMode PwmTimer3_( CORE_PWM0_TIMER, SetCompareOutputMode, CORE_PWM0_CHANNEL )
#define Pwm0_Disconnected PwmTimer2_( CORE_PWM0_TIMER, Disconnected )
#define Pwm0_Clear PwmTimer2_( CORE_PWM0_TIMER, Clear )
#define Pwm0_SetOutputCompareMatch PwmTimer3_( CORE_PWM0_TIMER, SetOutputCompareMatch, CORE_PWM0_CHANNEL )
#endif
#if CORE_PWM_COUNT >= 2
#define Pwm1_SetCompareOutputMode PwmTimer3_( CORE_PWM1_TIMER, SetCompareOutputMode, CORE_PWM1_CHANNEL )
#define Pwm1_Disconnected PwmTimer2_( CORE_PWM1_TIMER, Disconnected )
#define Pwm1_Clear PwmTimer2_( CORE_PWM1_TIMER, Clear )
#define Pwm1_SetOutputCompareMatch PwmTimer3_( CORE_PWM1_TIMER, SetOutputCompareMatch, CORE_PWM1_CHANNEL )
#endif
#if CORE_PWM_COUNT >= 3
#define Pwm2_SetCompareOutputMode PwmTimer3_( CORE_PWM2_TIMER, SetCompareOutputMode, CORE_PWM2_CHANNEL )
#define Pwm2_Disconnected PwmTimer2_( CORE_PWM2_TIMER, Disconnected )
#define Pwm2_Clear PwmTimer2_( CORE_PWM2_TIMER, Clear )
#define Pwm2_SetOutputCompareMatch PwmTimer3_( CORE_PWM2_TIMER, SetOutputCompareMatch, CORE_PWM2_CHANNEL )
#endif
#if CORE_PWM_COUNT >= 4
#define Pwm3_SetCompareOutputMode PwmTimer3_( CORE_PWM3_TIMER, SetCompareOutputMode, CORE_PWM3_CHANNEL )
#define Pwm3_Disconnected PwmTimer2_( CORE_PWM3_TIMER, Disconnected )
#define Pwm3_Clear PwmTimer2_( CORE_PWM3_TIMER, Clear )
#define Pwm3_SetOutputCompareMatch PwmTimer3_( CORE_PWM3_TIMER, SetOutputCompareMatch, CORE_PWM3_CHANNEL )
#endif
#if CORE_PWM_COUNT >= 5
#error Only 4 pins PWM are supported. Add more macro defintions.
#endif
#endif

View File

@@ -0,0 +1,35 @@
/*
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

View File

@@ -0,0 +1,42 @@
/*==============================================================================
TinyDebugSerial.cpp - Tiny write-only software serial.
Copyright 2010 Rowdy Dog Software.
This file is part of Arduino-Tiny.
Arduino-Tiny 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 3 of the License, or (at your
option) any later version.
Arduino-Tiny 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 Arduino-Tiny. If not, see <http://www.gnu.org/licenses/>.
==============================================================================*/
#include "core_build_options.h"
#include "TinyDebugSerial.h"
static TinyDebugSerialWriter stub;
void TinyDebugSerial::useStub( void )
{
_writer = &stub;
_writer->init();
}
TinyDebugSerial::TinyDebugSerial( void )
{
useStub();
}
#if defined( DEFAULT_TO_TINY_DEBUG_SERIAL ) && DEFAULT_TO_TINY_DEBUG_SERIAL
TinyDebugSerial Serial;
#endif

View File

@@ -0,0 +1,749 @@
/*==============================================================================
TinyDebugSerial.h - Tiny write-only software serial.
Copyright 2010 Rowdy Dog Software.
This file is part of Arduino-Tiny.
Arduino-Tiny 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 3 of the License, or (at your
option) any later version.
Arduino-Tiny 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 Arduino-Tiny. If not, see <http://www.gnu.org/licenses/>.
==============================================================================*/
#ifndef TinyDebugSerial_h
#define TinyDebugSerial_h
#include <inttypes.h>
#include "binary.h"
#include "core_build_options.h"
#include "Stream.h"
class TinyDebugSerialWriter;
class TinyDebugSerial;
class TinyDebugSerialWriter
{
protected:
virtual void init( void )
{
}
virtual void write( uint8_t )
{
}
friend class TinyDebugSerial;
};
void TinyDebugSerialWriterInternalBug( void ) __attribute__((error("Serial (TinyDebugSerial) has an internal problem. Contact the developer.")));
__attribute__((always_inline, unused)) static inline void TinyDebugSerialWriterBangOneByte( uint8_t value, uint8_t SER_REG, uint8_t SER_BIT, uint8_t lom, uint8_t him, uint8_t oloops, uint8_t iloops, uint8_t nops )
{
if ( __builtin_constant_p( SER_REG )
&& __builtin_constant_p( SER_BIT )
&& __builtin_constant_p( lom )
&& __builtin_constant_p( him )
&& __builtin_constant_p( oloops )
&& __builtin_constant_p( iloops )
&& __builtin_constant_p( nops ) )
{
uint8_t i;
uint8_t j;
uint8_t ol;
uint8_t il;
uint8_t b; // Initialized to the low bits
uint8_t hib;
uint8_t m;
b = ((value << 1) & 0x1F);
hib = ((value >> 4) & 0x1F) | 0x10;
asm volatile
(
"ldi %[j], 2" "\n\t"
"ldi %[i], 5" "\n\t"
"ldi %[m], %[lom]" "\n\t"
// Note: 8 MHz, 9600 baud ---> disabling interrupts does not appear to be necessary
"cli" "\n\t"
"rjmp L%=ntop" "\n\t"
"L%=btop: "
"nop" "\n\t" // ---> 7
"nop" "\n\t" //
"nop" "\n\t" //
"nop" "\n\t" //
"nop" "\n\t" //
"nop" "\n\t" //
"nop" "\n\t" //
"L%=ntop: "
"ror %[b]" "\n\t" // ---> 1
"brcs L%=bxh" "\n\t" // 1 (not taken)
"cbi %[serreg], %[serbit]" "\n\t" // 2
"rjmp L%=bxz" "\n\t" // 2
"L%=bxh: " // 2 (taken)
"sbi %[serreg], %[serbit]" "\n\t" // 2
"nop" "\n\t" // 1
// ---> 5
"L%=bxz: "
"ror %[m]" "\n\t" // ---> 3 or 4
"brcc L%=bnoe" "\n\t" //
"nop" "\n\t" //
"nop" "\n\t" //
"L%=bnoe: "
// ---> 1
".if %[oloops] >= 1" "\n\t" // if oloops >= 1 then...
"ldi %[ol], %[oloops]" "\n\t" // 4*oloops + oloops*(3*iloops) or oloops*((3*iloops)+4)
"L%=odelay: " "\n\t"
".endif" "\n\t"
"ldi %[il], %[iloops]" "\n\t" // if oloops == 0 then...
"L%=idelay: " "\n\t" // (3*iloops)
"dec %[il]" "\n\t"
"brne L%=idelay" "\n\t"
"nop" "\n\t"
".if %[oloops] >= 1" "\n\t"
"dec %[ol]" "\n\t"
"brne L%=odelay" "\n\t"
"nop" "\n\t"
".endif" "\n\t"
".if %[nops] >= 1" "\n\t"
"nop" "\n\t" //
".endif" "\n\t"
".if %[nops] >= 2" "\n\t"
"nop" "\n\t" //
".endif" "\n\t"
"dec %[i]" "\n\t" // ---> 3
"brne L%=btop" "\n\t" //
"nop" "\n\t" //
"dec %[j]" "\n\t" // ---> 7
"breq L%=bfin" "\n\t" //
"ldi %[i], 5" "\n\t" //
"mov %[b], %[hib]" "\n\t" //
"ldi %[m], %[him]" "\n\t" //
"rjmp L%=ntop" "\n\t" //
"L%=bfin: "
"sei" "\n\t"
:
[i] "=&r" ( i ),
[j] "=&r" ( j ),
[ol] "=&r" ( ol ),
[il] "=&r" ( il ),
[m] "=&r" ( m )
:
[b] "r" ( b ),
[hib] "r" ( hib ),
[serreg] "I" ( SER_REG ),
[serbit] "M" ( SER_BIT ),
[lom] "M" ( lom ),
[him] "M" ( him ),
[oloops] "M" ( oloops ),
[iloops] "M" ( iloops ),
[nops] "M" ( nops )
:
"r31",
"r30"
);
}
else
{
TinyDebugSerialWriterInternalBug();
}
}
template
<
uint8_t SER_REG,
uint8_t SER_BIT
>
class TinyDebugSerialWriter_1_9600 : public TinyDebugSerialWriter
{
protected:
virtual void init( void )
{
asm volatile
(
"sbi %[serreg]-1, %[serbit]" "\n\t"
"sbi %[serreg], %[serbit]" "\n\t"
:
:
[serreg] "I" ( SER_REG ),
[serbit] "I" ( SER_BIT )
:
);
}
virtual void write( uint8_t value )
{
TinyDebugSerialWriterBangOneByte( value, SER_REG, SER_BIT, B00100, B00010, 0, 28, 2 );
}
};
template
<
uint8_t SER_REG,
uint8_t SER_BIT
>
class TinyDebugSerialWriter_1_38400 : public TinyDebugSerialWriter
{
protected:
virtual void init( void )
{
asm volatile
(
"sbi %[serreg]-1, %[serbit]" "\n\t"
"sbi %[serreg], %[serbit]" "\n\t"
:
:
[serreg] "I" ( SER_REG ),
[serbit] "I" ( SER_BIT )
:
);
}
virtual void write( uint8_t value )
{
TinyDebugSerialWriterBangOneByte( value, SER_REG, SER_BIT, B00000, B00000, 0, 2, 0 );
}
};
template
<
uint8_t SER_REG,
uint8_t SER_BIT
>
class TinyDebugSerialWriter_1_115200 : public TinyDebugSerialWriter
{
protected:
virtual void init( void )
{
asm volatile
(
"sbi %[serreg]-1, %[serbit]" "\n\t"
"sbi %[serreg], %[serbit]" "\n\t"
:
:
[serreg] "I" ( SER_REG ),
[serbit] "I" ( SER_BIT )
:
);
}
virtual void write( uint8_t value )
{
asm volatile
(
"cli" "\n\t"
"cbi %[serreg], %[serbit]" "\n\t" /* 2 <--- 0 */
"ror %[value]" "\n\t" /* 1 */
"nop" "\n\t" /* 1 */
"nop" "\n\t" /* 1 */
"nop" "\n\t" /* 1 */
"nop" "\n\t" /* 1 */
"brcs L%=b0h" "\n\t" /* 1 (not taken) */
"nop" "\n\t" /* 1 */
"cbi %[serreg], %[serbit]" "\n\t" /* 2 <--- st is 9 cycles */
"rjmp L%=b0z" "\n\t" /* 2 */
"L%=b0h: " /* 2 (taken) */
"sbi %[serreg], %[serbit]" "\n\t" /* 2 <--- st is 9 cycles */
"nop" "\n\t" /* 1 */
"nop" "\n\t" /* 1 */
"L%=b0z: "
"ror %[value]" "\n\t" /* 1 */
"nop" "\n\t" /* 1 */
"brcs L%=b1h" "\n\t" /* 1 (not taken) */
"nop" "\n\t" /* 1 */
"cbi %[serreg], %[serbit]" "\n\t" /* 2 <--- b0 is 8 cycles */
"rjmp L%=b1z" "\n\t" /* 2 */
"L%=b1h: " /* 2 (taken) */
"sbi %[serreg], %[serbit]" "\n\t" /* 2 <--- b0 is 8 cycles */
"nop" "\n\t" /* 1 */
"nop" "\n\t" /* 1 */
"L%=b1z: "
"ror %[value]" "\n\t" /* 1 */
"nop" "\n\t" /* 1 */
"nop" "\n\t" /* 1 */
"brcs L%=b2h" "\n\t" /* 1 (not taken) */
"nop" "\n\t" /* 1 */
"cbi %[serreg], %[serbit]" "\n\t" /* 2 <--- b1 is 9 cycles */
"rjmp L%=b2z" "\n\t" /* 2 */
"L%=b2h: " /* 2 (taken) */
"sbi %[serreg], %[serbit]" "\n\t" /* 2 <--- b1 is 9 cycles */
"nop" "\n\t" /* 1 */
"nop" "\n\t" /* 1 */
"L%=b2z: "
"ror %[value]" "\n\t" /* 1 */
"nop" "\n\t" /* 1 */
"nop" "\n\t" /* 1 */
"brcs L%=b3h" "\n\t" /* 1 (not taken) */
"nop" "\n\t" /* 1 */
"cbi %[serreg], %[serbit]" "\n\t" /* 2 <--- b2 is 9 cycles */
"rjmp L%=b3z" "\n\t" /* 2 */
"L%=b3h: " /* 2 (taken) */
"sbi %[serreg], %[serbit]" "\n\t" /* 2 <--- b2 is 9 cycles */
"nop" "\n\t" /* 1 */
"nop" "\n\t" /* 1 */
"L%=b3z: "
"ror %[value]" "\n\t" /* 1 */
"nop" "\n\t" /* 1 */
"brcs L%=b4h" "\n\t" /* 1 (not taken) */
"nop" "\n\t" /* 1 */
"cbi %[serreg], %[serbit]" "\n\t" /* 2 <--- b3 is 8 cycles */
"rjmp L%=b4z" "\n\t" /* 2 */
"L%=b4h: " /* 2 (taken) */
"sbi %[serreg], %[serbit]" "\n\t" /* 2 <--- b3 is 8 cycles */
"nop" "\n\t" /* 1 */
"nop" "\n\t" /* 1 */
"L%=b4z: "
"ror %[value]" "\n\t" /* 1 */
"nop" "\n\t" /* 1 */
"nop" "\n\t" /* 1 */
"brcs L%=b5h" "\n\t" /* 1 (not taken) */
"nop" "\n\t" /* 1 */
"cbi %[serreg], %[serbit]" "\n\t" /* 2 <--- b4 is 9 cycles */
"rjmp L%=b5z" "\n\t" /* 2 */
"L%=b5h: " /* 2 (taken) */
"sbi %[serreg], %[serbit]" "\n\t" /* 2 <--- b4 is 9 cycles */
"nop" "\n\t" /* 1 */
"nop" "\n\t" /* 1 */
"L%=b5z: "
"ror %[value]" "\n\t" /* 1 */
"nop" "\n\t" /* 1 */
"nop" "\n\t" /* 1 */
"brcs L%=b6h" "\n\t" /* 1 (not taken) */
"nop" "\n\t" /* 1 */
"cbi %[serreg], %[serbit]" "\n\t" /* 2 <--- b5 is 9 cycles */
"rjmp L%=b6z" "\n\t" /* 2 */
"L%=b6h: " /* 2 (taken) */
"sbi %[serreg], %[serbit]" "\n\t" /* 2 <--- b5 is 9 cycles */
"nop" "\n\t" /* 1 */
"nop" "\n\t" /* 1 */
"L%=b6z: "
"ror %[value]" "\n\t" /* 1 */
"nop" "\n\t" /* 1 */
"brcs L%=b7h" "\n\t" /* 1 (not taken) */
"nop" "\n\t" /* 1 */
"cbi %[serreg], %[serbit]" "\n\t" /* 2 <--- b6 is 8 cycles */
"rjmp L%=b7z" "\n\t" /* 2 */
"L%=b7h: " /* 2 (taken) */
"sbi %[serreg], %[serbit]" "\n\t" /* 2 <--- b6 is 8 cycles */
"nop" "\n\t" /* 1 */
"nop" "\n\t" /* 1 */
"L%=b7z: "
"nop" "\n\t" /* 1 */
"nop" "\n\t" /* 1 */
"nop" "\n\t" /* 1 */
"nop" "\n\t" /* 1 */
"nop" "\n\t" /* 1 */
"sbi %[serreg], %[serbit]" "\n\t" /* 2 <--- b7 is 9 cycles */
"nop" "\n\t" /* 1 */
"nop" "\n\t" /* 1 */
"nop" "\n\t" /* 1 */
"nop" "\n\t" /* 1 */
"nop" "\n\t" /* 1 */
"nop" "\n\t" /* 1 */
"nop" "\n\t" /* 1 */
/* <---sp is 9 cycles */
"sei" "\n\t"
:
:
[value] "r" ( value ),
[serreg] "I" ( SER_REG ),
[serbit] "I" ( SER_BIT )
);
}
};
template
<
uint8_t SER_REG,
uint8_t SER_BIT
>
class TinyDebugSerialWriter_8_9600 : public TinyDebugSerialWriter
{
protected:
virtual void init( void )
{
asm volatile
(
"sbi %[serreg]-1, %[serbit]" "\n\t"
"sbi %[serreg], %[serbit]" "\n\t"
:
:
[serreg] "I" ( SER_REG ),
[serbit] "I" ( SER_BIT )
:
);
}
virtual void write( uint8_t value )
{
TinyDebugSerialWriterBangOneByte( value, SER_REG, SER_BIT, B01001, B00100, 3, 89, 0 );
}
};
template
<
uint8_t SER_REG,
uint8_t SER_BIT
>
class TinyDebugSerialWriter_8_38400 : public TinyDebugSerialWriter
{
protected:
virtual void init( void )
{
asm volatile
(
"sbi %[serreg]-1, %[serbit]" "\n\t"
"sbi %[serreg], %[serbit]" "\n\t"
:
:
[serreg] "I" ( SER_REG ),
[serbit] "I" ( SER_BIT )
:
);
}
virtual void write( uint8_t value )
{
TinyDebugSerialWriterBangOneByte( value, SER_REG, SER_BIT, B01001, B00100, 0, 62, 2 );
}
};
template
<
uint8_t SER_REG,
uint8_t SER_BIT
>
class TinyDebugSerialWriter_8_115200 : public TinyDebugSerialWriter
{
protected:
virtual void init( void )
{
asm volatile
(
"sbi %[serreg]-1, %[serbit]" "\n\t"
"sbi %[serreg], %[serbit]" "\n\t"
:
:
[serreg] "I" ( SER_REG ),
[serbit] "I" ( SER_BIT )
:
);
}
virtual void write( uint8_t value )
{
TinyDebugSerialWriterBangOneByte( value, SER_REG, SER_BIT, B01010, B10100, 0, 16, 1 );
}
};
template
<
uint8_t SER_REG,
uint8_t SER_BIT
>
class TinyDebugSerialWriter_16_9600 : public TinyDebugSerialWriter
{
protected:
virtual void init( void )
{
asm volatile
(
"sbi %[serreg]-1, %[serbit]" "\n\t"
"sbi %[serreg], %[serbit]" "\n\t"
:
:
[serreg] "I" ( SER_REG ),
[serbit] "I" ( SER_BIT )
:
);
}
virtual void write( uint8_t value )
{
TinyDebugSerialWriterBangOneByte( value, SER_REG, SER_BIT, B10110, B11011, 6, 90, 2 );
}
};
template
<
uint8_t SER_REG,
uint8_t SER_BIT
>
class TinyDebugSerialWriter_16_38400 : public TinyDebugSerialWriter
{
protected:
virtual void init( void )
{
asm volatile
(
"sbi %[serreg]-1, %[serbit]" "\n\t"
"sbi %[serreg], %[serbit]" "\n\t"
:
:
[serreg] "I" ( SER_REG ),
[serbit] "I" ( SER_BIT )
:
);
}
virtual void write( uint8_t value )
{
TinyDebugSerialWriterBangOneByte( value, SER_REG, SER_BIT, B10110, B11011, 5, 25, 1 );
}
};
template
<
uint8_t SER_REG,
uint8_t SER_BIT
>
class TinyDebugSerialWriter_16_115200 : public TinyDebugSerialWriter
{
protected:
virtual void init( void )
{
asm volatile
(
"sbi %[serreg]-1, %[serbit]" "\n\t"
"sbi %[serreg], %[serbit]" "\n\t"
:
:
[serreg] "I" ( SER_REG ),
[serbit] "I" ( SER_BIT )
:
);
}
virtual void write( uint8_t value )
{
TinyDebugSerialWriterBangOneByte( value, SER_REG, SER_BIT, B11110, B11111, 0, 39, 1 );
}
};
#if defined( __AVR_ATtinyX313__ )
#define TINY_DEBUG_SERIAL_REGISTER 0x1B
#define TINY_DEBUG_SERIAL_BIT 1
#elif defined( __AVR_ATtinyX4__ )
#if F_CPU <= 8000000L
// port B bit 0 (PB0)
#define TINY_DEBUG_SERIAL_REGISTER 0x18
#define TINY_DEBUG_SERIAL_BIT 0
#else
// port A bit 0 (PA0)
#define TINY_DEBUG_SERIAL_REGISTER 0x1B
#define TINY_DEBUG_SERIAL_BIT 0
#endif
#elif defined( __AVR_ATtinyX5__ )
#if F_CPU <= 8000000L
// port B bit 3 (PB3)
#define TINY_DEBUG_SERIAL_REGISTER 0x18
#define TINY_DEBUG_SERIAL_BIT 3
#else
// port B bit 2 (PB2)
#define TINY_DEBUG_SERIAL_REGISTER 0x18
#define TINY_DEBUG_SERIAL_BIT 2
#endif
#endif
#if F_CPU == 1000000L
typedef TinyDebugSerialWriter_1_9600<TINY_DEBUG_SERIAL_REGISTER,TINY_DEBUG_SERIAL_BIT> TinyDebugSerialWriter_9600;
typedef TinyDebugSerialWriter_1_38400<TINY_DEBUG_SERIAL_REGISTER,TINY_DEBUG_SERIAL_BIT> TinyDebugSerialWriter_38400;
typedef TinyDebugSerialWriter_1_115200<TINY_DEBUG_SERIAL_REGISTER,TINY_DEBUG_SERIAL_BIT> TinyDebugSerialWriter_115200;
#define TINY_DEBUG_SERIAL_SUPPORTED 1
#elif F_CPU == 8000000L
typedef TinyDebugSerialWriter_8_9600<TINY_DEBUG_SERIAL_REGISTER,TINY_DEBUG_SERIAL_BIT> TinyDebugSerialWriter_9600;
typedef TinyDebugSerialWriter_8_38400<TINY_DEBUG_SERIAL_REGISTER,TINY_DEBUG_SERIAL_BIT> TinyDebugSerialWriter_38400;
typedef TinyDebugSerialWriter_8_115200<TINY_DEBUG_SERIAL_REGISTER,TINY_DEBUG_SERIAL_BIT> TinyDebugSerialWriter_115200;
#define TINY_DEBUG_SERIAL_SUPPORTED 1
#elif F_CPU == 16000000L
typedef TinyDebugSerialWriter_16_9600<TINY_DEBUG_SERIAL_REGISTER,TINY_DEBUG_SERIAL_BIT> TinyDebugSerialWriter_9600;
typedef TinyDebugSerialWriter_16_38400<TINY_DEBUG_SERIAL_REGISTER,TINY_DEBUG_SERIAL_BIT> TinyDebugSerialWriter_38400;
typedef TinyDebugSerialWriter_16_115200<TINY_DEBUG_SERIAL_REGISTER,TINY_DEBUG_SERIAL_BIT> TinyDebugSerialWriter_115200;
#define TINY_DEBUG_SERIAL_SUPPORTED 1
#elif F_CPU == 16500000L
typedef TinyDebugSerialWriter_16_9600<TINY_DEBUG_SERIAL_REGISTER,TINY_DEBUG_SERIAL_BIT> TinyDebugSerialWriter_9600;
typedef TinyDebugSerialWriter_16_38400<TINY_DEBUG_SERIAL_REGISTER,TINY_DEBUG_SERIAL_BIT> TinyDebugSerialWriter_38400;
typedef TinyDebugSerialWriter_16_115200<TINY_DEBUG_SERIAL_REGISTER,TINY_DEBUG_SERIAL_BIT> TinyDebugSerialWriter_115200;
#define TINY_DEBUG_SERIAL_SUPPORTED 1
/*
9600...
6, 90, 2
7, 77, 1
38400...
1, 130, 2
5, 25, 1
18, 6, 0
115200...
0, 39, 1
1, 38, 0
2, 18, 2
9, 3, 1
*/
#endif
#if TINY_DEBUG_SERIAL_SUPPORTED
extern TinyDebugSerialWriter_9600 tdsw9600;
extern TinyDebugSerialWriter_38400 tdsw38400;
extern TinyDebugSerialWriter_115200 tdsw115200;
void TinyDebugSerialBadBaud( void ) __attribute__((error("Serial (TinyDebugSerial) supports three baud rates: 9600, 38400, or 115200.")));
void TinyDebugSerialBaudMustBeConstant( void ) __attribute__((error("The baud rate for Serial (TinyDebugSerial) cannot be changed at run-time. Use 9600, 38400, or 115200.")));
class TinyDebugSerial : public Stream
{
protected:
TinyDebugSerialWriter* _writer;
void useStub( void );
public:
TinyDebugSerial( void );
inline void begin( long baud )
{
if ( __builtin_constant_p( baud ) )
{
if ( baud == 9600 )
{
_writer = &tdsw9600;
}
else if ( baud == 38400 )
{
_writer = &tdsw38400;
}
else if ( baud == 115200 )
{
_writer = &tdsw115200;
}
else
{
TinyDebugSerialBadBaud();
}
}
else
{
TinyDebugSerialBaudMustBeConstant();
}
_writer->init();
}
void end( void )
{
useStub();
}
virtual int available( void )
{
return( 0 );
}
virtual int peek( void )
{
return( -1 );
}
virtual int read( void )
{
return( -1 );
}
virtual void flush( void )
{
}
virtual size_t write( uint8_t c )
{
_writer->write( c );
return( 1 );
}
using Print::write; // pull in write(str) and write(buf, size) from Print
};
#if DEFAULT_TO_TINY_DEBUG_SERIAL
extern TinyDebugSerial Serial;
#endif
#endif
#endif

View File

@@ -0,0 +1,26 @@
/*==============================================================================
TinyDebugSerial.cpp - Tiny write-only software serial.
Copyright 2010 Rowdy Dog Software.
This file is part of Arduino-Tiny.
Arduino-Tiny 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 3 of the License, or (at your
option) any later version.
Arduino-Tiny 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 Arduino-Tiny. If not, see <http://www.gnu.org/licenses/>.
==============================================================================*/
#include "TinyDebugSerial.h"
TinyDebugSerialWriter_115200 tdsw115200;

View File

@@ -0,0 +1,26 @@
/*==============================================================================
TinyDebugSerial.cpp - Tiny write-only software serial.
Copyright 2010 Rowdy Dog Software.
This file is part of Arduino-Tiny.
Arduino-Tiny 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 3 of the License, or (at your
option) any later version.
Arduino-Tiny 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 Arduino-Tiny. If not, see <http://www.gnu.org/licenses/>.
==============================================================================*/
#include "TinyDebugSerial.h"
TinyDebugSerialWriter_38400 tdsw38400;

View File

@@ -0,0 +1,26 @@
/*==============================================================================
TinyDebugSerial.cpp - Tiny write-only software serial.
Copyright 2010 Rowdy Dog Software.
This file is part of Arduino-Tiny.
Arduino-Tiny 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 3 of the License, or (at your
option) any later version.
Arduino-Tiny 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 Arduino-Tiny. If not, see <http://www.gnu.org/licenses/>.
==============================================================================*/
#include "TinyDebugSerial.h"
TinyDebugSerialWriter_9600 tdsw9600;

View File

@@ -0,0 +1,28 @@
/*==============================================================================
TinyDebugSerial.cpp - Tiny write-only software serial.
Copyright 2010 Rowdy Dog Software.
This file is part of Arduino-Tiny.
Arduino-Tiny 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 3 of the License, or (at your
option) any later version.
Arduino-Tiny 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 Arduino-Tiny. If not, see <http://www.gnu.org/licenses/>.
==============================================================================*/
#include "TinyDebugSerial.h"
void TinyDebugSerialWriterInternalBug( void ) { }
void TinyDebugSerialBadBaud( void ) { }
void TinyDebugSerialBaudMustBeConstant( void ) { }

View File

@@ -0,0 +1,504 @@
/* Tone.cpp
A Tone Generator Library
Written by Brett Hagman
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
Version Modified By Date Comments
------- ----------- -------- --------
0001 B Hagman 09/08/02 Initial coding
0002 B Hagman 09/08/18 Multiple pins
0003 B Hagman 09/08/18 Moved initialization from constructor to begin()
0004 B Hagman 09/09/26 Fixed problems with ATmega8
0005 B Hagman 09/11/23 Scanned prescalars for best fit on 8 bit timers
09/11/25 Changed pin toggle method to XOR
09/11/25 Fixed timer0 from being excluded
0006 D Mellis 09/12/29 Replaced objects with functions
0007 B Cook 10/05/03 Rewritten to only work with Timer1 and support direct hardware output
0008 B Cook 10/05/03 Rewritten so the timer can be selected at compile time
*************************************************/
#define DEBUG_TONE 0
#include <avr/interrupt.h>
#include "core_build_options.h"
#include "ToneTimer.h"
#include "pins_arduino.h"
#include "wiring.h"
#if (TONETIMER_NUMBER_PRESCALERS != 5) && (TONETIMER_NUMBER_PRESCALERS != 15)
#error Only five or fifteen prescalers are supported. Update the code to support the number of actual prescalers.
#endif
#if TONETIMER_NUMBER_PRESCALERS == 15
#define TONETIMER_MAXIMUM_DIVISOR ( (unsigned long)(TONETIMER_(PRESCALER_VALUE_15)) * (1L + (unsigned long)(TONETIMER_(MAXIMUM_OCR))) )
#endif
#if TONETIMER_NUMBER_PRESCALERS == 5
#define TONETIMER_MAXIMUM_DIVISOR ( (unsigned long)(TONETIMER_(PRESCALER_VALUE_5)) * (1L + (unsigned long)(TONETIMER_(MAXIMUM_OCR))) )
#endif
const unsigned int Tone_Lowest_Frequency = (F_CPU + (2L * TONETIMER_MAXIMUM_DIVISOR - 1L)) / (2L * TONETIMER_MAXIMUM_DIVISOR);
#if (TONETIMER_(MAXIMUM_OCR) == 65535) && (TONETIMER_(PRESCALE_SET) == 1)
#if F_CPU <= 1000000
#define TONE_FREQUENCY_CUTOFF_2 (7)
#define TONE_FREQUENCY_CUTOFF_1 (65535)
#elif F_CPU <= 8000000
#define TONE_FREQUENCY_CUTOFF_3 (7)
#define TONE_FREQUENCY_CUTOFF_2 (61)
#define TONE_FREQUENCY_CUTOFF_1 (65535)
#elif F_CPU <= 16000000
#define TONE_FREQUENCY_CUTOFF_4 (1)
#define TONE_FREQUENCY_CUTOFF_3 (15)
#define TONE_FREQUENCY_CUTOFF_2 (122)
#define TONE_FREQUENCY_CUTOFF_1 (65535)
#elif F_CPU <= 16500000
#define TONE_FREQUENCY_CUTOFF_4 (1)
#define TONE_FREQUENCY_CUTOFF_3 (15)
#define TONE_FREQUENCY_CUTOFF_2 (122)
#define TONE_FREQUENCY_CUTOFF_1 (65535)
#endif
#endif
#if (TONETIMER_(MAXIMUM_OCR) == 255) && (TONETIMER_(PRESCALE_SET) == 1)
#if F_CPU <= 1000000
#define TONE_FREQUENCY_CUTOFF_5 (7)
#define TONE_FREQUENCY_CUTOFF_4 (30)
#define TONE_FREQUENCY_CUTOFF_3 (243)
#define TONE_FREQUENCY_CUTOFF_2 (1949)
#define TONE_FREQUENCY_CUTOFF_1 (65535)
#elif F_CPU <= 8000000
#define TONE_FREQUENCY_CUTOFF_5 (60)
#define TONE_FREQUENCY_CUTOFF_4 (243)
#define TONE_FREQUENCY_CUTOFF_3 (1949)
#define TONE_FREQUENCY_CUTOFF_2 (15594)
#define TONE_FREQUENCY_CUTOFF_1 (65535)
#elif F_CPU <= 16000000
#define TONE_FREQUENCY_CUTOFF_5 (121)
#define TONE_FREQUENCY_CUTOFF_4 (487)
#define TONE_FREQUENCY_CUTOFF_3 (3898)
#define TONE_FREQUENCY_CUTOFF_2 (31189)
#define TONE_FREQUENCY_CUTOFF_1 (65535)
#elif F_CPU <= 16500000
#define TONE_FREQUENCY_CUTOFF_5 (121)
#define TONE_FREQUENCY_CUTOFF_4 (487)
#define TONE_FREQUENCY_CUTOFF_3 (3898)
#define TONE_FREQUENCY_CUTOFF_2 (31189)
#define TONE_FREQUENCY_CUTOFF_1 (65535)
#endif
#endif
#if (TONETIMER_(MAXIMUM_OCR) == 255) && (TONETIMER_(PRESCALE_SET) == 2)
#if F_CPU <= 1000000
#define TONE_FREQUENCY_CUTOFF_12 (1)
#define TONE_FREQUENCY_CUTOFF_11 (3)
#define TONE_FREQUENCY_CUTOFF_10 (7)
#define TONE_FREQUENCY_CUTOFF_9 (15)
#define TONE_FREQUENCY_CUTOFF_8 (30)
#define TONE_FREQUENCY_CUTOFF_7 (60)
#define TONE_FREQUENCY_CUTOFF_6 (121)
#define TONE_FREQUENCY_CUTOFF_5 (243)
#define TONE_FREQUENCY_CUTOFF_4 (487)
#define TONE_FREQUENCY_CUTOFF_3 (974)
#define TONE_FREQUENCY_CUTOFF_2 (1949)
#define TONE_FREQUENCY_CUTOFF_1 (65535)
#elif F_CPU <= 8000000
#define TONE_FREQUENCY_CUTOFF_15 (1)
#define TONE_FREQUENCY_CUTOFF_14 (3)
#define TONE_FREQUENCY_CUTOFF_13 (7)
#define TONE_FREQUENCY_CUTOFF_12 (15)
#define TONE_FREQUENCY_CUTOFF_11 (30)
#define TONE_FREQUENCY_CUTOFF_10 (60)
#define TONE_FREQUENCY_CUTOFF_9 (121)
#define TONE_FREQUENCY_CUTOFF_8 (243)
#define TONE_FREQUENCY_CUTOFF_7 (487)
#define TONE_FREQUENCY_CUTOFF_6 (974)
#define TONE_FREQUENCY_CUTOFF_5 (1949)
#define TONE_FREQUENCY_CUTOFF_4 (3898)
#define TONE_FREQUENCY_CUTOFF_3 (7797)
#define TONE_FREQUENCY_CUTOFF_2 (15594)
#define TONE_FREQUENCY_CUTOFF_1 (65535)
#elif F_CPU <= 16000000
#define TONE_FREQUENCY_CUTOFF_15 (3)
#define TONE_FREQUENCY_CUTOFF_14 (7)
#define TONE_FREQUENCY_CUTOFF_13 (15)
#define TONE_FREQUENCY_CUTOFF_12 (30)
#define TONE_FREQUENCY_CUTOFF_11 (60)
#define TONE_FREQUENCY_CUTOFF_10 (121)
#define TONE_FREQUENCY_CUTOFF_9 (243)
#define TONE_FREQUENCY_CUTOFF_8 (487)
#define TONE_FREQUENCY_CUTOFF_7 (974)
#define TONE_FREQUENCY_CUTOFF_6 (1949)
#define TONE_FREQUENCY_CUTOFF_5 (3898)
#define TONE_FREQUENCY_CUTOFF_4 (7797)
#define TONE_FREQUENCY_CUTOFF_3 (15594)
#define TONE_FREQUENCY_CUTOFF_2 (31189)
#define TONE_FREQUENCY_CUTOFF_1 (65535)
#elif F_CPU <= 16500000
#define TONE_FREQUENCY_CUTOFF_15 (3)
#define TONE_FREQUENCY_CUTOFF_14 (7)
#define TONE_FREQUENCY_CUTOFF_13 (15)
#define TONE_FREQUENCY_CUTOFF_12 (30)
#define TONE_FREQUENCY_CUTOFF_11 (60)
#define TONE_FREQUENCY_CUTOFF_10 (121)
#define TONE_FREQUENCY_CUTOFF_9 (243)
#define TONE_FREQUENCY_CUTOFF_8 (487)
#define TONE_FREQUENCY_CUTOFF_7 (974)
#define TONE_FREQUENCY_CUTOFF_6 (1949)
#define TONE_FREQUENCY_CUTOFF_5 (3898)
#define TONE_FREQUENCY_CUTOFF_4 (7797)
#define TONE_FREQUENCY_CUTOFF_3 (15594)
#define TONE_FREQUENCY_CUTOFF_2 (31189)
#define TONE_FREQUENCY_CUTOFF_1 (65535)
#endif
#endif
#if DEBUG_TONE
uint16_t debug_tone_last_OCRxA;
uint16_t debug_tone_last_CSV;
#endif
// timerx_toggle_count:
// > 0 - duration specified
// = 0 - stopped
// < 0 - infinitely (until stop() method called, or new play() called)
static volatile long tone_timer_toggle_count;
static volatile uint8_t *tone_timer_pin_register;
static volatile uint8_t tone_timer_pin_mask;
static uint8_t tone_pin = 255;
void tone( uint8_t _pin, unsigned int frequency, unsigned long duration )
{
tonetimer_(ocr_t) ocr;
tonetimer_(prescale_value_t) csv;
tonetimer_(cs_t) csi;
if ( tone_pin == 255 )
{
/* Set the timer to power-up conditions so we start from a known state */
ToneTimer_SetToPowerup();
/*
Compare Output Mode = Normal port operation, OCxA/OCxB disconnected.
Waveform Generation Mode = 4; 0100; CTC; (Clear Timer on Compare); OCR1A; Immediate; MAX
Clock Select = No clock source (Timer/Counter stopped).
Note: Turn off the clock first to avoid ticks and scratches.
*/
ToneTimer_SetWaveformGenerationMode( ToneTimer_(CTC_OCR) );
/* If the tone pin can be driven directly from the timer */
if ( (_pin == ToneTimer_OutputComparePinA) || (_pin == ToneTimer_OutputComparePinB) )
{
/* Pin toggling is handled by the hardware */
tone_timer_pin_register = NULL;
tone_timer_pin_mask = 0;
if ( _pin == ToneTimer_OutputComparePinA )
{
/* Compare Output Mode = Toggle OCxA on Compare Match. */
ToneTimer_SetCompareOutputModeA( ToneTimer_(Toggle) );
}
else // if ( _pin == ToneTimer_OutputComparePinB )
{
/* Compare Output Mode = Toggle OCxA on Compare Match. */
ToneTimer_SetCompareOutputModeB( ToneTimer_(Toggle) );
}
}
else
{
/* Save information needed by the interrupt service routine */
tone_timer_pin_register = portOutputRegister( digitalPinToPort( _pin ) );
tone_timer_pin_mask = digitalPinToBitMask( _pin );
/* Compare Output Mode = Normal port operation, OCxA disconnected. */
ToneTimer_DisconnectOutputs();
}
/* Ensure the pin is configured for output */
pinMode( _pin, OUTPUT );
tone_pin = _pin;
}
if ( tone_pin == _pin )
{
/* Stop the clock while we make changes. */
ToneTimer_ClockSelect( ToneTimer_(Stopped) );
/* Start the counter at zero to reduce ticks and scratches. */
ToneTimer_SetCount( 0 );
if ( frequency > 0 )
{
if ( frequency < Tone_Lowest_Frequency )
{
frequency = Tone_Lowest_Frequency;
}
/* Determine which prescaler to use */
/* Set the Output Compare Register (rounding up) */
#if defined( TONE_FREQUENCY_CUTOFF_15 )
if ( frequency <= TONE_FREQUENCY_CUTOFF_15 )
{
csv = TONETIMER_(PRESCALER_VALUE_15);
csi = ToneTimer_(Prescale_Index_15);
}
else
#endif
#if defined( TONE_FREQUENCY_CUTOFF_14 )
if ( frequency <= TONE_FREQUENCY_CUTOFF_14 )
{
csv = TONETIMER_(PRESCALER_VALUE_14);
csi = ToneTimer_(Prescale_Index_14);
}
else
#endif
#if defined( TONE_FREQUENCY_CUTOFF_13 )
if ( frequency <= TONE_FREQUENCY_CUTOFF_13 )
{
csv = TONETIMER_(PRESCALER_VALUE_13);
csi = ToneTimer_(Prescale_Index_13);
}
else
#endif
#if defined( TONE_FREQUENCY_CUTOFF_12 )
if ( frequency <= TONE_FREQUENCY_CUTOFF_12 )
{
csv = TONETIMER_(PRESCALER_VALUE_12);
csi = ToneTimer_(Prescale_Index_12);
}
else
#endif
#if defined( TONE_FREQUENCY_CUTOFF_11 )
if ( frequency <= TONE_FREQUENCY_CUTOFF_11 )
{
csv = TONETIMER_(PRESCALER_VALUE_11);
csi = ToneTimer_(Prescale_Index_11);
}
else
#endif
#if defined( TONE_FREQUENCY_CUTOFF_10 )
if ( frequency <= TONE_FREQUENCY_CUTOFF_10 )
{
csv = TONETIMER_(PRESCALER_VALUE_10);
csi = ToneTimer_(Prescale_Index_10);
}
else
#endif
#if defined( TONE_FREQUENCY_CUTOFF_9 )
if ( frequency <= TONE_FREQUENCY_CUTOFF_9 )
{
csv = TONETIMER_(PRESCALER_VALUE_9);
csi = ToneTimer_(Prescale_Index_9);
}
else
#endif
#if defined( TONE_FREQUENCY_CUTOFF_8 )
if ( frequency <= TONE_FREQUENCY_CUTOFF_8 )
{
csv = TONETIMER_(PRESCALER_VALUE_8);
csi = ToneTimer_(Prescale_Index_8);
}
else
#endif
#if defined( TONE_FREQUENCY_CUTOFF_7 )
if ( frequency <= TONE_FREQUENCY_CUTOFF_7 )
{
csv = TONETIMER_(PRESCALER_VALUE_7);
csi = ToneTimer_(Prescale_Index_7);
}
else
#endif
#if defined( TONE_FREQUENCY_CUTOFF_6 )
if ( frequency <= TONE_FREQUENCY_CUTOFF_6 )
{
csv = TONETIMER_(PRESCALER_VALUE_6);
csi = ToneTimer_(Prescale_Index_6);
}
else
#endif
#if defined( TONE_FREQUENCY_CUTOFF_5 )
if ( frequency <= TONE_FREQUENCY_CUTOFF_5 )
{
csv = TONETIMER_(PRESCALER_VALUE_5);
csi = ToneTimer_(Prescale_Index_5);
}
else
#endif
#if defined( TONE_FREQUENCY_CUTOFF_4 )
if ( frequency <= TONE_FREQUENCY_CUTOFF_4 )
{
csv = TONETIMER_(PRESCALER_VALUE_4);
csi = ToneTimer_(Prescale_Index_4);
}
else
#endif
#if defined( TONE_FREQUENCY_CUTOFF_3 )
if ( frequency <= TONE_FREQUENCY_CUTOFF_3 )
{
csv = TONETIMER_(PRESCALER_VALUE_3);
csi = ToneTimer_(Prescale_Index_3);
}
else
#endif
if ( frequency <= TONE_FREQUENCY_CUTOFF_2 )
{
csv = TONETIMER_(PRESCALER_VALUE_2);
csi = ToneTimer_(Prescale_Index_2);
}
else // if ( frequency <= TONE_FREQUENCY_CUTOFF_1 )
{
csv = TONETIMER_(PRESCALER_VALUE_1);
csi = ToneTimer_(Prescale_Index_1);
}
ocr = ( (2L * F_CPU) / (frequency * 2L * csv) + 1L ) / 2L - 1L;
ToneTimer_SetOutputCompareMatchAndClear( ocr );
#if DEBUG_TONE
debug_tone_last_OCRxA = ocr;
debug_tone_last_CSV = csv;
#endif
/* Does the caller want a specific duration? */
if ( duration > 0 )
{
/* Determine how many times the value toggles */
tone_timer_toggle_count = (2 * frequency * duration) / 1000;
/* Output Compare A Match Interrupt Enable */
ToneTimer_EnableOutputCompareInterruptA();
}
else
{
/* Indicate to the interrupt service routine that we'll be running until further notice */
tone_timer_toggle_count = -1;
/* All pins but the OCxA / OCxB pins have to be driven by software */
if ( (_pin != ToneTimer_OutputComparePinA) && (_pin != ToneTimer_OutputComparePinB) )
{
/* Output Compare A Match Interrupt Enable */
ToneTimer_EnableOutputCompareInterruptA();
}
}
/* Start the clock... */
ToneTimer_ClockSelect( csi );
}
else
{
/* To be on the safe side, turn off all interrupts */
ToneTimer_InterruptsOff();
/* Clock is stopped. Counter is zero. The only thing left to do is turn off the output. */
digitalWrite( _pin, 0 );
}
}
}
void noTone( uint8_t _pin )
{
if ( (tone_pin != 255)
&& ((tone_pin == _pin) || (_pin == 255)) )
{
// Turn off all interrupts
ToneTimer_InterruptsOff();
// Stop the clock while we make changes.
ToneTimer_ClockSelect( ToneTimer_(Stopped) );
// Set the Tone Timer exactly the same as init did...
initToneTimer();
//rmv ToneTimer_SetToPowerup();
/* rmv
// put timer 1 in 8-bit phase correct pwm mode
TCCR1A = (0<<COM1A1)|(0<<COM1A0) | (0<<COM1B1)|(0<<COM1B0) | (0<<WGM11)|(1<<WGM10);
// set timer 1 prescale factor to 64
// and start the timer
TCCR1B = (0<<ICNC1) | (0<<ICES1) | (0<<WGM13)|(0<<WGM12) | (0<<CS12)|(1<<CS11)|(1<<CS10);
*/
// Set the output low
if ( tone_timer_pin_register != NULL )
{
*tone_timer_pin_register &= ~(tone_timer_pin_mask);
}
else
{
digitalWrite( tone_pin, LOW );
}
tone_pin = 255;
}
}
ISR( TONETIMER_COMPA_vect, ISR_NOBLOCK )
{
if ( tone_timer_toggle_count != 0 )
{
if ( tone_timer_toggle_count > 0 )
{
--tone_timer_toggle_count;
if ( tone_timer_toggle_count == 0 )
{
// Shutdown the hardware
noTone( 255 );
// Skip the rest. We're finished.
return;
}
}
*tone_timer_pin_register ^= tone_timer_pin_mask;
}
else
{
// Shutdown the hardware
noTone( 255 );
}
}

View File

@@ -0,0 +1,50 @@
/*==============================================================================
ToneTimer.h - Veneer for the Tone Timer.
Copyright 2010 Rowdy Dog Software.
This file is part of Arduino-Tiny.
Arduino-Tiny 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 3 of the License, or (at your
option) any later version.
Arduino-Tiny 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 Arduino-Tiny. If not, see <http://www.gnu.org/licenses/>.
==============================================================================*/
#ifndef ToneTimer_h
#define ToneTimer_h
#include "core_build_options.h"
#include "core_timers.h"
#define tonetimer_(t) TIMER_PASTE_A( timer, TIMER_TO_USE_FOR_TONE, t )
#define ToneTimer_(f) TIMER_PASTE_A( Timer, TIMER_TO_USE_FOR_TONE, f )
#define TONETIMER_(c) TIMER_PASTE_A( TIMER, TIMER_TO_USE_FOR_TONE, c )
#define ToneTimer_SetToPowerup ToneTimer_(SetToPowerup)
#define ToneTimer_SetWaveformGenerationMode ToneTimer_(SetWaveformGenerationMode)
#define ToneTimer_OutputComparePinA ToneTimer_(OutputComparePinA)
#define ToneTimer_OutputComparePinB ToneTimer_(OutputComparePinB)
#define ToneTimer_SetCompareOutputModeA ToneTimer_(SetCompareOutputModeA)
#define ToneTimer_SetCompareOutputModeB ToneTimer_(SetCompareOutputModeB)
#define ToneTimer_DisconnectOutputs ToneTimer_(DisconnectOutputs)
#define ToneTimer_ClockSelect ToneTimer_(ClockSelect)
#define ToneTimer_SetCount ToneTimer_(SetCount)
#define TONETIMER_NUMBER_PRESCALERS TONETIMER_(NUMBER_PRESCALERS)
#define ToneTimer_SetOutputCompareMatchAndClear ToneTimer_(SetOutputCompareMatchAndClear)
#define ToneTimer_InterruptsOff ToneTimer_(InterruptsOff)
#define ToneTimer_EnableOutputCompareInterruptA ToneTimer_(EnableOutputCompareInterruptA)
#define TONETIMER_COMPA_vect TONETIMER_(COMPA_vect)
#define TONETIMER_SUPPORTS_PHASE_CORRECT_PWM TONETIMER_(SUPPORTS_PHASE_CORRECT_PWM)
#endif

View File

@@ -0,0 +1,78 @@
/*==============================================================================
UserTimer.h - Veneer for the User Timer (same timer as the one used for
Tone)
Copyright 2010 Rowdy Dog Software.
This file is part of Arduino-Tiny.
Arduino-Tiny 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 3 of the License, or (at your
option) any later version.
Arduino-Tiny 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 Arduino-Tiny. If not, see <http://www.gnu.org/licenses/>.
==============================================================================*/
#ifndef UserTimer_h
#define UserTimer_h
#include "core_build_options.h"
#include "core_timers.h"
/*=============================================================================
Assume there are only two timers. One for millis and one for everything
else.
=============================================================================*/
#if TIMER_TO_USE_FOR_MILLIS == 0
#define TIMER_TO_USE_FOR_USER 1
#elif TIMER_TO_USE_FOR_MILLIS == 1
#define TIMER_TO_USE_FOR_USER 0
#else
#error Unexpected condition in UserTimer.h.
#endif
/*=============================================================================
Macros to help generate the macros below
=============================================================================*/
#define usertimer_(t) TIMER_PASTE_A( timer, TIMER_TO_USE_FOR_USER, t )
#define UserTimer_(f) TIMER_PASTE_A( Timer, TIMER_TO_USE_FOR_USER, f )
#define USERTIMER_(c) TIMER_PASTE_A( TIMER, TIMER_TO_USE_FOR_USER, c )
/*=============================================================================
Macros to provide a veneer over the data-types, functions, and constants in
core_timers.h
=============================================================================*/
#define UserTimer_SetToPowerup UserTimer_(SetToPowerup)
#define UserTimer_InterruptsOff UserTimer_(InterruptsOff)
#define UserTimer_ClockSelect UserTimer_(ClockSelect)
#define UserTimer_SetWaveformGenerationMode UserTimer_(SetWaveformGenerationMode)
#define UserTimer_SetCompareOutputModeA UserTimer_(SetCompareOutputModeA)
#define UserTimer_SetCompareOutputModeB UserTimer_(SetCompareOutputModeB)
#define UserTimer_SetOutputCompareMatchAndClear UserTimer_(SetOutputCompareMatchAndClear)
#define UserTimer_EnableOutputCompareInterruptA UserTimer_(EnableOutputCompareInterruptA)
#define UserTimer_EnableOverflowInterrupt UserTimer_(EnableOverflowInterrupt)
#define UserTimer_GetCount UserTimer_(GetCount)
#define UserTimer_SetCount UserTimer_(SetCount)
#define UserTimer_IsOverflowSet UserTimer_(IsOverflowSet)
#define USERTIMER_OVF_vect USERTIMER_(OVF_vect)
#define USERTIMER_COMPA_vect USERTIMER_(COMPA_vect)
#define USERTIMER_COMPB_vect USERTIMER_(COMPB_vect)
#endif

View File

@@ -0,0 +1,168 @@
/*
WCharacter.h - Character utility functions for Wiring & Arduino
Copyright (c) 2010 Hernando Barragan. 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 Character_h
#define Character_h
#include <ctype.h>
// WCharacter.h prototypes
inline boolean isAlphaNumeric(int c) __attribute__((always_inline));
inline boolean isAlpha(int c) __attribute__((always_inline));
inline boolean isAscii(int c) __attribute__((always_inline));
inline boolean isWhitespace(int c) __attribute__((always_inline));
inline boolean isControl(int c) __attribute__((always_inline));
inline boolean isDigit(int c) __attribute__((always_inline));
inline boolean isGraph(int c) __attribute__((always_inline));
inline boolean isLowerCase(int c) __attribute__((always_inline));
inline boolean isPrintable(int c) __attribute__((always_inline));
inline boolean isPunct(int c) __attribute__((always_inline));
inline boolean isSpace(int c) __attribute__((always_inline));
inline boolean isUpperCase(int c) __attribute__((always_inline));
inline boolean isHexadecimalDigit(int c) __attribute__((always_inline));
inline int toAscii(int c) __attribute__((always_inline));
inline int toLowerCase(int c) __attribute__((always_inline));
inline int toUpperCase(int c)__attribute__((always_inline));
// Checks for an alphanumeric character.
// It is equivalent to (isalpha(c) || isdigit(c)).
inline boolean isAlphaNumeric(int c)
{
return ( isalnum(c) == 0 ? false : true);
}
// Checks for an alphabetic character.
// It is equivalent to (isupper(c) || islower(c)).
inline boolean isAlpha(int c)
{
return ( isalpha(c) == 0 ? false : true);
}
// Checks whether c is a 7-bit unsigned char value
// that fits into the ASCII character set.
inline boolean isAscii(int c)
{
return ( isascii (c) == 0 ? false : true);
}
// Checks for a blank character, that is, a space or a tab.
inline boolean isWhitespace(int c)
{
return ( isblank (c) == 0 ? false : true);
}
// Checks for a control character.
inline boolean isControl(int c)
{
return ( iscntrl (c) == 0 ? false : true);
}
// Checks for a digit (0 through 9).
inline boolean isDigit(int c)
{
return ( isdigit (c) == 0 ? false : true);
}
// Checks for any printable character except space.
inline boolean isGraph(int c)
{
return ( isgraph (c) == 0 ? false : true);
}
// Checks for a lower-case character.
inline boolean isLowerCase(int c)
{
return (islower (c) == 0 ? false : true);
}
// Checks for any printable character including space.
inline boolean isPrintable(int c)
{
return ( isprint (c) == 0 ? false : true);
}
// Checks for any printable character which is not a space
// or an alphanumeric character.
inline boolean isPunct(int c)
{
return ( ispunct (c) == 0 ? false : true);
}
// Checks for white-space characters. For the avr-libc library,
// these are: space, formfeed ('\f'), newline ('\n'), carriage
// return ('\r'), horizontal tab ('\t'), and vertical tab ('\v').
inline boolean isSpace(int c)
{
return ( isspace (c) == 0 ? false : true);
}
// Checks for an uppercase letter.
inline boolean isUpperCase(int c)
{
return ( isupper (c) == 0 ? false : true);
}
// Checks for a hexadecimal digits, i.e. one of 0 1 2 3 4 5 6 7
// 8 9 a b c d e f A B C D E F.
inline boolean isHexadecimalDigit(int c)
{
return ( isxdigit (c) == 0 ? false : true);
}
// Converts c to a 7-bit unsigned char value that fits into the
// ASCII character set, by clearing the high-order bits.
inline int toAscii(int c)
{
return toascii (c);
}
// Warning:
// Many people will be unhappy if you use this function.
// This function will convert accented letters into random
// characters.
// Converts the letter c to lower case, if possible.
inline int toLowerCase(int c)
{
return tolower (c);
}
// Converts the letter c to upper case, if possible.
inline int toUpperCase(int c)
{
return toupper (c);
}
#endif

View File

@@ -0,0 +1 @@
#include "wiring.h"

View File

@@ -0,0 +1,148 @@
/* -*- 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
Modified 28-08-2009 for attiny84 R.Wiersma
Modified 09-10-2009 for attiny45 A.Saporetti
Modified 20-11-2010 - B.Cook - Correct a minor bug in attachInterrupt
*/
#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[NUMBER_EXTERNAL_INTERRUPTS];
#if defined( MCUCR ) && ! defined( EICRA )
#define EICRA MCUCR
#endif
#if defined( GIMSK ) && ! defined( EIMSK )
#define EIMSK GIMSK
#endif
void attachInterrupt(uint8_t interruptNum, void (*userFunc)(void), int mode)
{
if ( interruptNum < NUMBER_EXTERNAL_INTERRUPTS )
{
/*
If attachInterrupt is called in succession for the same
interruptNum but a different userFunc then the following line
is not safe. Changing intFunc is not atomic.
intFunc[interruptNum] = userFunc;
*/
{
// save interrupt flag
uint8_t SaveSREG = SREG;
// disable interrupts
cli();
// access the shared data
intFunc[interruptNum] = userFunc;
// restore the interrupt flag
SREG = SaveSREG;
}
// 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 NUMBER_EXTERNAL_INTERRUPTS >= 1
case EXTERNAL_INTERRUPT_0:
EICRA = (EICRA & ~((1 << ISC00) | (1 << ISC01))) | (mode << ISC00);
EIMSK |= (1 << INT0);
break;
#endif
#if NUMBER_EXTERNAL_INTERRUPTS >= 2
case EXTERNAL_INTERRUPT_1:
EICRA = (EICRA & ~((1 << ISC10) | (1 << ISC11))) | (mode << ISC10);
EIMSK |= (1 << INT1);
break;
#endif
#if NUMBER_EXTERNAL_INTERRUPTS > 2
#error Add handlers for the additional interrupts.
#endif
}
}
}
void detachInterrupt(uint8_t interruptNum)
{
if ( interruptNum < NUMBER_EXTERNAL_INTERRUPTS )
{
// Disable the interrupt. (We can't assume that interruptNum is equal
// to the number of the EIMSK bit to clear, as this isn't true on the
// ATmega8. There, INT0 is 6 and INT1 is 7.)
switch (interruptNum)
{
#if NUMBER_EXTERNAL_INTERRUPTS >= 1
case EXTERNAL_INTERRUPT_0:
EIMSK &= ~(1 << INT0);
break;;
#endif
#if NUMBER_EXTERNAL_INTERRUPTS >= 2
case EXTERNAL_INTERRUPT_1:
EIMSK &= ~(1 << INT1);
break;;
#endif
#if NUMBER_EXTERNAL_INTERRUPTS > 2
#error Add handlers for the additional interrupts.
#endif
}
intFunc[interruptNum] = 0;
}
}
#if NUMBER_EXTERNAL_INTERRUPTS >= 1
ISR(EXTERNAL_INTERRUPT_0_vect, ISR_NOBLOCK)
{
if(intFunc[EXTERNAL_INTERRUPT_0])
intFunc[EXTERNAL_INTERRUPT_0]();
}
#endif
#if NUMBER_EXTERNAL_INTERRUPTS >= 2
ISR(EXTERNAL_INTERRUPT_1_vect, ISR_NOBLOCK)
{
if(intFunc[EXTERNAL_INTERRUPT_1])
intFunc[EXTERNAL_INTERRUPT_1]();
}
#endif
#if NUMBER_EXTERNAL_INTERRUPTS > 2
#error Add handlers for the additional interrupts.
#endif

View File

@@ -0,0 +1,60 @@
/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
/*
Part of the Wiring project - http://wiring.org.co
Copyright (c) 2004-06 Hernando Barragan
Modified 13 August 2006, David A. Mellis for Arduino - http://www.arduino.cc/
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
$Id$
*/
extern "C" {
#include "stdlib.h"
}
void randomSeed(unsigned int seed)
{
if (seed != 0) {
srandom(seed);
}
}
long random(long howbig)
{
if (howbig == 0) {
return 0;
}
return random() % howbig;
}
long random(long howsmall, long howbig)
{
if (howsmall >= howbig) {
return howsmall;
}
long diff = howbig - howsmall;
return random(diff) + howsmall;
}
long map(long x, long in_min, long in_max, long out_min, long out_max)
{
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
unsigned int makeWord(unsigned int w) { return w; }
unsigned int makeWord(unsigned char h, unsigned char l) { return (h << 8) | l; }

View File

@@ -0,0 +1,83 @@
#ifndef WProgram_h
#define WProgram_h
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <avr/interrupt.h>
#include "core_build_options.h"
#include "core_pins.h"
#include "wiring.h"
#include "pins_arduino.h"
#ifdef __cplusplus
#include "WCharacter.h"
#include "WString.h"
#include "TinyDebugSerial.h"
#include "HardwareSerial.h"
uint16_t makeWord(uint16_t w);
uint16_t makeWord(byte h, byte l);
#define word(...) makeWord(__VA_ARGS__)
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
void tone(uint8_t _pin, unsigned int frequency, unsigned long duration = 0);
void noTone(uint8_t _pin = 255);
// WMath prototypes
long random(long);
long random(long, long);
void randomSeed(unsigned int);
long map(long, long, long, long, long);
/*
fix? On the Mega processors, the analogs are also "extended" digital pins.
To (sort of) work the same way with this core, the following constants
would have to be valid arguments to digitalRead, digitalWrite, and pinMode
("the digitals"). Which means the digitals would have to check for pins
over A0 and then subtract A0. The current plan is to wait until someone
wants this feature.
*/
#if CORE_ANALOG_COUNT >= 1
const static uint8_t A0 = CORE_ANALOG_FIRST + 0;
#endif
#if CORE_ANALOG_COUNT >= 2
const static uint8_t A1 = CORE_ANALOG_FIRST + 1;
#endif
#if CORE_ANALOG_COUNT >= 3
const static uint8_t A2 = CORE_ANALOG_FIRST + 2;
#endif
#if CORE_ANALOG_COUNT >= 4
const static uint8_t A3 = CORE_ANALOG_FIRST + 3;
#endif
#if CORE_ANALOG_COUNT >= 5
const static uint8_t A4 = CORE_ANALOG_FIRST + 4;
#endif
#if CORE_ANALOG_COUNT >= 6
const static uint8_t A5 = CORE_ANALOG_FIRST + 5;
#endif
#if CORE_ANALOG_COUNT >= 7
const static uint8_t A6 = CORE_ANALOG_FIRST + 6;
#endif
#if CORE_ANALOG_COUNT >= 8
const static uint8_t A7 = CORE_ANALOG_FIRST + 7;
#endif
#if CORE_ANALOG_COUNT >= 9
#error Update the A* definitions for the selected processor.
#endif
#endif
#endif

View File

@@ -0,0 +1,443 @@
/*
WString.cpp - String library for Wiring & Arduino
Copyright (c) 2009-10 Hernando Barragan. All rights 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
*/
#include <stdlib.h>
#include "WProgram.h"
#include "WString.h"
String::String( const char *value )
{
if ( value == NULL )
value = "";
getBuffer( _length = strlen( value ) );
if ( _buffer != NULL )
strcpy( _buffer, value );
}
String::String( const String &value )
{
getBuffer( _length = value._length );
if ( _buffer != NULL )
strcpy( _buffer, value._buffer );
}
String::String( const char value )
{
_length = 1;
getBuffer(1);
if ( _buffer != NULL ) {
_buffer[0] = value;
_buffer[1] = 0;
}
}
String::String( const unsigned char value )
{
_length = 1;
getBuffer(1);
if ( _buffer != NULL) {
_buffer[0] = value;
_buffer[1] = 0;
}
}
String::String( const int value, const int base )
{
char buf[33];
itoa((signed long)value, buf, base);
getBuffer( _length = strlen(buf) );
if ( _buffer != NULL )
strcpy( _buffer, buf );
}
String::String( const unsigned int value, const int base )
{
char buf[33];
ultoa((unsigned long)value, buf, base);
getBuffer( _length = strlen(buf) );
if ( _buffer != NULL )
strcpy( _buffer, buf );
}
String::String( const long value, const int base )
{
char buf[33];
ltoa(value, buf, base);
getBuffer( _length = strlen(buf) );
if ( _buffer != NULL )
strcpy( _buffer, buf );
}
String::String( const unsigned long value, const int base )
{
char buf[33];
ultoa(value, buf, 10);
getBuffer( _length = strlen(buf) );
if ( _buffer != NULL )
strcpy( _buffer, buf );
}
char String::charAt( unsigned int loc ) const
{
return operator[]( loc );
}
void String::setCharAt( unsigned int loc, const char aChar )
{
if(_buffer == NULL) return;
if(_length > loc) {
_buffer[loc] = aChar;
}
}
int String::compareTo( const String &s2 ) const
{
return strcmp( _buffer, s2._buffer );
}
const String & String::concat( const String &s2 )
{
return (*this) += s2;
}
const String & String::operator=( const String &rhs )
{
if ( this == &rhs )
return *this;
if ( rhs._length > _length )
{
free(_buffer);
getBuffer( rhs._length );
}
if ( _buffer != NULL ) {
_length = rhs._length;
strcpy( _buffer, rhs._buffer );
}
return *this;
}
//const String & String::operator+=( const char aChar )
//{
// if ( _length == _capacity )
// doubleBuffer();
//
// _buffer[ _length++ ] = aChar;
// _buffer[ _length ] = '\0';
// return *this;
//}
const String & String::operator+=( const String &other )
{
_length += other._length;
if ( _length > _capacity )
{
char *temp = (char *)realloc(_buffer, _length + 1);
if ( temp != NULL ) {
_buffer = temp;
_capacity = _length;
} else {
_length -= other._length;
return *this;
}
}
strcat( _buffer, other._buffer );
return *this;
}
int String::operator==( const String &rhs ) const
{
return ( _length == rhs._length && strcmp( _buffer, rhs._buffer ) == 0 );
}
int String::operator!=( const String &rhs ) const
{
return ( _length != rhs.length() || strcmp( _buffer, rhs._buffer ) != 0 );
}
int String::operator<( const String &rhs ) const
{
return strcmp( _buffer, rhs._buffer ) < 0;
}
int String::operator>( const String &rhs ) const
{
return strcmp( _buffer, rhs._buffer ) > 0;
}
int String::operator<=( const String &rhs ) const
{
return strcmp( _buffer, rhs._buffer ) <= 0;
}
int String::operator>=( const String & rhs ) const
{
return strcmp( _buffer, rhs._buffer ) >= 0;
}
char & String::operator[]( unsigned int index )
{
static char dummy_writable_char;
if (index >= _length || !_buffer) {
dummy_writable_char = 0;
return dummy_writable_char;
}
return _buffer[ index ];
}
char String::operator[]( unsigned int index ) const
{
// need to check for valid index, to do later
return _buffer[ index ];
}
boolean String::endsWith( const String &s2 ) const
{
if ( _length < s2._length )
return 0;
return strcmp( &_buffer[ _length - s2._length], s2._buffer ) == 0;
}
boolean String::equals( const String &s2 ) const
{
return ( _length == s2._length && strcmp( _buffer,s2._buffer ) == 0 );
}
boolean String::equalsIgnoreCase( const String &s2 ) const
{
if ( this == &s2 )
return true; //1;
else if ( _length != s2._length )
return false; //0;
return strcmp(toLowerCase()._buffer, s2.toLowerCase()._buffer) == 0;
}
String String::replace( char findChar, char replaceChar )
{
if ( _buffer == NULL ) return *this;
String theReturn = _buffer;
char* temp = theReturn._buffer;
while( (temp = strchr( temp, findChar )) != 0 )
*temp = replaceChar;
return theReturn;
}
String String::replace( const String& match, const String& replace )
{
if ( _buffer == NULL ) return *this;
String temp = _buffer, newString;
int loc;
while ( (loc = temp.indexOf( match )) != -1 )
{
newString += temp.substring( 0, loc );
newString += replace;
temp = temp.substring( loc + match._length );
}
newString += temp;
return newString;
}
int String::indexOf( char temp ) const
{
return indexOf( temp, 0 );
}
int String::indexOf( char ch, unsigned int fromIndex ) const
{
if ( fromIndex >= _length )
return -1;
const char* temp = strchr( &_buffer[fromIndex], ch );
if ( temp == NULL )
return -1;
return temp - _buffer;
}
int String::indexOf( const String &s2 ) const
{
return indexOf( s2, 0 );
}
int String::indexOf( const String &s2, unsigned int fromIndex ) const
{
if ( fromIndex >= _length )
return -1;
const char *theFind = strstr( &_buffer[ fromIndex ], s2._buffer );
if ( theFind == NULL )
return -1;
return theFind - _buffer; // pointer subtraction
}
int String::lastIndexOf( char theChar ) const
{
return lastIndexOf( theChar, _length - 1 );
}
int String::lastIndexOf( char ch, unsigned int fromIndex ) const
{
if ( fromIndex >= _length )
return -1;
char tempchar = _buffer[fromIndex + 1];
_buffer[fromIndex + 1] = '\0';
char* temp = strrchr( _buffer, ch );
_buffer[fromIndex + 1] = tempchar;
if ( temp == NULL )
return -1;
return temp - _buffer;
}
int String::lastIndexOf( const String &s2 ) const
{
return lastIndexOf( s2, _length - s2._length );
}
int String::lastIndexOf( const String &s2, unsigned int fromIndex ) const
{
// check for empty strings
if ( s2._length == 0 || s2._length - 1 > fromIndex || fromIndex >= _length )
return -1;
// matching first character
char temp = s2[ 0 ];
for ( int i = fromIndex; i >= 0; i-- )
{
if ( _buffer[ i ] == temp && (*this).substring( i, i + s2._length ).equals( s2 ) )
return i;
}
return -1;
}
boolean String::startsWith( const String &s2 ) const
{
if ( _length < s2._length )
return 0;
return startsWith( s2, 0 );
}
boolean String::startsWith( const String &s2, unsigned int offset ) const
{
if ( offset > _length - s2._length )
return 0;
return strncmp( &_buffer[offset], s2._buffer, s2._length ) == 0;
}
String String::substring( unsigned int left ) const
{
return substring( left, _length );
}
String String::substring( unsigned int left, unsigned int right ) const
{
if ( left > right )
{
int temp = right;
right = left;
left = temp;
}
if ( right > _length )
{
right = _length;
}
char temp = _buffer[ right ]; // save the replaced character
_buffer[ right ] = '\0';
String outPut = ( _buffer + left ); // pointer arithmetic
_buffer[ right ] = temp; //restore character
return outPut;
}
String String::toLowerCase() const
{
String temp = _buffer;
for ( unsigned int i = 0; i < _length; i++ )
temp._buffer[ i ] = (char)tolower( temp._buffer[ i ] );
return temp;
}
String String::toUpperCase() const
{
String temp = _buffer;
for ( unsigned int i = 0; i < _length; i++ )
temp._buffer[ i ] = (char)toupper( temp._buffer[ i ] );
return temp;
}
String String::trim() const
{
if ( _buffer == NULL ) return *this;
String temp = _buffer;
unsigned int i,j;
for ( i = 0; i < _length; i++ )
{
if ( !isspace(_buffer[i]) )
break;
}
for ( j = temp._length - 1; j > i; j-- )
{
if ( !isspace(_buffer[j]) )
break;
}
return temp.substring( i, j + 1);
}
void String::getBytes(unsigned char *buf, unsigned int bufsize)
{
if (!bufsize || !buf) return;
unsigned int len = bufsize - 1;
if (len > _length) len = _length;
strncpy((char *)buf, _buffer, len);
buf[len] = 0;
}
void String::toCharArray(char *buf, unsigned int bufsize)
{
if (!bufsize || !buf) return;
unsigned int len = bufsize - 1;
if (len > _length) len = _length;
strncpy(buf, _buffer, len);
buf[len] = 0;
}
long String::toInt() {
return atol(_buffer);
}

View File

@@ -0,0 +1,112 @@
/*
WString.h - String library for Wiring & Arduino
Copyright (c) 2009-10 Hernando Barragan. 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 String_h
#define String_h
//#include "WProgram.h"
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
class String
{
public:
// constructors
String( const char *value = "" );
String( const String &value );
String( const char );
String( const unsigned char );
String( const int, const int base=10);
String( const unsigned int, const int base=10 );
String( const long, const int base=10 );
String( const unsigned long, const int base=10 );
~String() { free(_buffer); _length = _capacity = 0;} //added _length = _capacity = 0;
// operators
const String & operator = ( const String &rhs );
const String & operator +=( const String &rhs );
//const String & operator +=( const char );
int operator ==( const String &rhs ) const;
int operator !=( const String &rhs ) const;
int operator < ( const String &rhs ) const;
int operator > ( const String &rhs ) const;
int operator <=( const String &rhs ) const;
int operator >=( const String &rhs ) const;
char operator []( unsigned int index ) const;
char& operator []( unsigned int index );
//operator const char *() const { return _buffer; }
// general methods
char charAt( unsigned int index ) const;
int compareTo( const String &anotherString ) const;
unsigned char endsWith( const String &suffix ) const;
unsigned char equals( const String &anObject ) const;
unsigned char equalsIgnoreCase( const String &anotherString ) const;
int indexOf( char ch ) const;
int indexOf( char ch, unsigned int fromIndex ) const;
int indexOf( const String &str ) const;
int indexOf( const String &str, unsigned int fromIndex ) const;
int lastIndexOf( char ch ) const;
int lastIndexOf( char ch, unsigned int fromIndex ) const;
int lastIndexOf( const String &str ) const;
int lastIndexOf( const String &str, unsigned int fromIndex ) const;
const unsigned int length( ) const { return _length; }
void setCharAt(unsigned int index, const char ch);
unsigned char startsWith( const String &prefix ) const;
unsigned char startsWith( const String &prefix, unsigned int toffset ) const;
String substring( unsigned int beginIndex ) const;
String substring( unsigned int beginIndex, unsigned int endIndex ) const;
String toLowerCase( ) const;
String toUpperCase( ) const;
String trim( ) const;
void getBytes(unsigned char *buf, unsigned int bufsize);
void toCharArray(char *buf, unsigned int bufsize);
long toInt( );
const String& concat( const String &str );
String replace( char oldChar, char newChar );
String replace( const String& match, const String& replace );
friend String operator + ( String lhs, const String &rhs );
protected:
char *_buffer; // the actual char array
unsigned int _capacity; // the array length minus one (for the '\0')
unsigned int _length; // the String length (not counting the '\0')
void getBuffer(unsigned int maxStrLen);
private:
};
// allocate buffer space
inline void String::getBuffer(unsigned int maxStrLen)
{
_capacity = maxStrLen;
_buffer = (char *) malloc(_capacity + 1);
if (_buffer == NULL) _length = _capacity = 0;
}
inline String operator+( String lhs, const String &rhs )
{
return lhs += rhs;
}
#endif

View File

@@ -0,0 +1,515 @@
#ifndef Binary_h
#define Binary_h
#define B0 0
#define B00 0
#define B000 0
#define B0000 0
#define B00000 0
#define B000000 0
#define B0000000 0
#define B00000000 0
#define B1 1
#define B01 1
#define B001 1
#define B0001 1
#define B00001 1
#define B000001 1
#define B0000001 1
#define B00000001 1
#define B10 2
#define B010 2
#define B0010 2
#define B00010 2
#define B000010 2
#define B0000010 2
#define B00000010 2
#define B11 3
#define B011 3
#define B0011 3
#define B00011 3
#define B000011 3
#define B0000011 3
#define B00000011 3
#define B100 4
#define B0100 4
#define B00100 4
#define B000100 4
#define B0000100 4
#define B00000100 4
#define B101 5
#define B0101 5
#define B00101 5
#define B000101 5
#define B0000101 5
#define B00000101 5
#define B110 6
#define B0110 6
#define B00110 6
#define B000110 6
#define B0000110 6
#define B00000110 6
#define B111 7
#define B0111 7
#define B00111 7
#define B000111 7
#define B0000111 7
#define B00000111 7
#define B1000 8
#define B01000 8
#define B001000 8
#define B0001000 8
#define B00001000 8
#define B1001 9
#define B01001 9
#define B001001 9
#define B0001001 9
#define B00001001 9
#define B1010 10
#define B01010 10
#define B001010 10
#define B0001010 10
#define B00001010 10
#define B1011 11
#define B01011 11
#define B001011 11
#define B0001011 11
#define B00001011 11
#define B1100 12
#define B01100 12
#define B001100 12
#define B0001100 12
#define B00001100 12
#define B1101 13
#define B01101 13
#define B001101 13
#define B0001101 13
#define B00001101 13
#define B1110 14
#define B01110 14
#define B001110 14
#define B0001110 14
#define B00001110 14
#define B1111 15
#define B01111 15
#define B001111 15
#define B0001111 15
#define B00001111 15
#define B10000 16
#define B010000 16
#define B0010000 16
#define B00010000 16
#define B10001 17
#define B010001 17
#define B0010001 17
#define B00010001 17
#define B10010 18
#define B010010 18
#define B0010010 18
#define B00010010 18
#define B10011 19
#define B010011 19
#define B0010011 19
#define B00010011 19
#define B10100 20
#define B010100 20
#define B0010100 20
#define B00010100 20
#define B10101 21
#define B010101 21
#define B0010101 21
#define B00010101 21
#define B10110 22
#define B010110 22
#define B0010110 22
#define B00010110 22
#define B10111 23
#define B010111 23
#define B0010111 23
#define B00010111 23
#define B11000 24
#define B011000 24
#define B0011000 24
#define B00011000 24
#define B11001 25
#define B011001 25
#define B0011001 25
#define B00011001 25
#define B11010 26
#define B011010 26
#define B0011010 26
#define B00011010 26
#define B11011 27
#define B011011 27
#define B0011011 27
#define B00011011 27
#define B11100 28
#define B011100 28
#define B0011100 28
#define B00011100 28
#define B11101 29
#define B011101 29
#define B0011101 29
#define B00011101 29
#define B11110 30
#define B011110 30
#define B0011110 30
#define B00011110 30
#define B11111 31
#define B011111 31
#define B0011111 31
#define B00011111 31
#define B100000 32
#define B0100000 32
#define B00100000 32
#define B100001 33
#define B0100001 33
#define B00100001 33
#define B100010 34
#define B0100010 34
#define B00100010 34
#define B100011 35
#define B0100011 35
#define B00100011 35
#define B100100 36
#define B0100100 36
#define B00100100 36
#define B100101 37
#define B0100101 37
#define B00100101 37
#define B100110 38
#define B0100110 38
#define B00100110 38
#define B100111 39
#define B0100111 39
#define B00100111 39
#define B101000 40
#define B0101000 40
#define B00101000 40
#define B101001 41
#define B0101001 41
#define B00101001 41
#define B101010 42
#define B0101010 42
#define B00101010 42
#define B101011 43
#define B0101011 43
#define B00101011 43
#define B101100 44
#define B0101100 44
#define B00101100 44
#define B101101 45
#define B0101101 45
#define B00101101 45
#define B101110 46
#define B0101110 46
#define B00101110 46
#define B101111 47
#define B0101111 47
#define B00101111 47
#define B110000 48
#define B0110000 48
#define B00110000 48
#define B110001 49
#define B0110001 49
#define B00110001 49
#define B110010 50
#define B0110010 50
#define B00110010 50
#define B110011 51
#define B0110011 51
#define B00110011 51
#define B110100 52
#define B0110100 52
#define B00110100 52
#define B110101 53
#define B0110101 53
#define B00110101 53
#define B110110 54
#define B0110110 54
#define B00110110 54
#define B110111 55
#define B0110111 55
#define B00110111 55
#define B111000 56
#define B0111000 56
#define B00111000 56
#define B111001 57
#define B0111001 57
#define B00111001 57
#define B111010 58
#define B0111010 58
#define B00111010 58
#define B111011 59
#define B0111011 59
#define B00111011 59
#define B111100 60
#define B0111100 60
#define B00111100 60
#define B111101 61
#define B0111101 61
#define B00111101 61
#define B111110 62
#define B0111110 62
#define B00111110 62
#define B111111 63
#define B0111111 63
#define B00111111 63
#define B1000000 64
#define B01000000 64
#define B1000001 65
#define B01000001 65
#define B1000010 66
#define B01000010 66
#define B1000011 67
#define B01000011 67
#define B1000100 68
#define B01000100 68
#define B1000101 69
#define B01000101 69
#define B1000110 70
#define B01000110 70
#define B1000111 71
#define B01000111 71
#define B1001000 72
#define B01001000 72
#define B1001001 73
#define B01001001 73
#define B1001010 74
#define B01001010 74
#define B1001011 75
#define B01001011 75
#define B1001100 76
#define B01001100 76
#define B1001101 77
#define B01001101 77
#define B1001110 78
#define B01001110 78
#define B1001111 79
#define B01001111 79
#define B1010000 80
#define B01010000 80
#define B1010001 81
#define B01010001 81
#define B1010010 82
#define B01010010 82
#define B1010011 83
#define B01010011 83
#define B1010100 84
#define B01010100 84
#define B1010101 85
#define B01010101 85
#define B1010110 86
#define B01010110 86
#define B1010111 87
#define B01010111 87
#define B1011000 88
#define B01011000 88
#define B1011001 89
#define B01011001 89
#define B1011010 90
#define B01011010 90
#define B1011011 91
#define B01011011 91
#define B1011100 92
#define B01011100 92
#define B1011101 93
#define B01011101 93
#define B1011110 94
#define B01011110 94
#define B1011111 95
#define B01011111 95
#define B1100000 96
#define B01100000 96
#define B1100001 97
#define B01100001 97
#define B1100010 98
#define B01100010 98
#define B1100011 99
#define B01100011 99
#define B1100100 100
#define B01100100 100
#define B1100101 101
#define B01100101 101
#define B1100110 102
#define B01100110 102
#define B1100111 103
#define B01100111 103
#define B1101000 104
#define B01101000 104
#define B1101001 105
#define B01101001 105
#define B1101010 106
#define B01101010 106
#define B1101011 107
#define B01101011 107
#define B1101100 108
#define B01101100 108
#define B1101101 109
#define B01101101 109
#define B1101110 110
#define B01101110 110
#define B1101111 111
#define B01101111 111
#define B1110000 112
#define B01110000 112
#define B1110001 113
#define B01110001 113
#define B1110010 114
#define B01110010 114
#define B1110011 115
#define B01110011 115
#define B1110100 116
#define B01110100 116
#define B1110101 117
#define B01110101 117
#define B1110110 118
#define B01110110 118
#define B1110111 119
#define B01110111 119
#define B1111000 120
#define B01111000 120
#define B1111001 121
#define B01111001 121
#define B1111010 122
#define B01111010 122
#define B1111011 123
#define B01111011 123
#define B1111100 124
#define B01111100 124
#define B1111101 125
#define B01111101 125
#define B1111110 126
#define B01111110 126
#define B1111111 127
#define B01111111 127
#define B10000000 128
#define B10000001 129
#define B10000010 130
#define B10000011 131
#define B10000100 132
#define B10000101 133
#define B10000110 134
#define B10000111 135
#define B10001000 136
#define B10001001 137
#define B10001010 138
#define B10001011 139
#define B10001100 140
#define B10001101 141
#define B10001110 142
#define B10001111 143
#define B10010000 144
#define B10010001 145
#define B10010010 146
#define B10010011 147
#define B10010100 148
#define B10010101 149
#define B10010110 150
#define B10010111 151
#define B10011000 152
#define B10011001 153
#define B10011010 154
#define B10011011 155
#define B10011100 156
#define B10011101 157
#define B10011110 158
#define B10011111 159
#define B10100000 160
#define B10100001 161
#define B10100010 162
#define B10100011 163
#define B10100100 164
#define B10100101 165
#define B10100110 166
#define B10100111 167
#define B10101000 168
#define B10101001 169
#define B10101010 170
#define B10101011 171
#define B10101100 172
#define B10101101 173
#define B10101110 174
#define B10101111 175
#define B10110000 176
#define B10110001 177
#define B10110010 178
#define B10110011 179
#define B10110100 180
#define B10110101 181
#define B10110110 182
#define B10110111 183
#define B10111000 184
#define B10111001 185
#define B10111010 186
#define B10111011 187
#define B10111100 188
#define B10111101 189
#define B10111110 190
#define B10111111 191
#define B11000000 192
#define B11000001 193
#define B11000010 194
#define B11000011 195
#define B11000100 196
#define B11000101 197
#define B11000110 198
#define B11000111 199
#define B11001000 200
#define B11001001 201
#define B11001010 202
#define B11001011 203
#define B11001100 204
#define B11001101 205
#define B11001110 206
#define B11001111 207
#define B11010000 208
#define B11010001 209
#define B11010010 210
#define B11010011 211
#define B11010100 212
#define B11010101 213
#define B11010110 214
#define B11010111 215
#define B11011000 216
#define B11011001 217
#define B11011010 218
#define B11011011 219
#define B11011100 220
#define B11011101 221
#define B11011110 222
#define B11011111 223
#define B11100000 224
#define B11100001 225
#define B11100010 226
#define B11100011 227
#define B11100100 228
#define B11100101 229
#define B11100110 230
#define B11100111 231
#define B11101000 232
#define B11101001 233
#define B11101010 234
#define B11101011 235
#define B11101100 236
#define B11101101 237
#define B11101110 238
#define B11101111 239
#define B11110000 240
#define B11110001 241
#define B11110010 242
#define B11110011 243
#define B11110100 244
#define B11110101 245
#define B11110110 246
#define B11110111 247
#define B11111000 248
#define B11111001 249
#define B11111010 250
#define B11111011 251
#define B11111100 252
#define B11111101 253
#define B11111110 254
#define B11111111 255
#endif

View File

@@ -0,0 +1,320 @@
/*==============================================================================
core_adc.h - Veneer for the analog-to-digital converter.
Copyright 2010 Rowdy Dog Software.
This file is part of Arduino-Tiny.
Arduino-Tiny 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 3 of the License, or (at your
option) any later version.
Arduino-Tiny 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 Arduino-Tiny. If not, see <http://www.gnu.org/licenses/>.
==============================================================================*/
#ifndef core_adc_h
#define core_adc_h
#include <avr/io.h>
#include <binary.h>
#include "core_build_options.h"
#include "core_macros.h"
/*=============================================================================
Some common things
=============================================================================*/
#if defined( __AVR_ATtinyX4__ ) || defined( __AVR_ATtinyX5__ )
/*
From the '84 and '85 datasheets... By default, the successive approximation
circuitry requires an input clock frequency between 50 kHz and 200 kHz to
get maximum resolution.
*/
#if F_CPU == 16000000
// 16 MHz / 128 = 125 KHz
#define ADC_ARDUINO_PRESCALER ADC_Prescaler_Value_128
#elif F_CPU == 16500000
// 8 MHz / 64 = 125 KHz
#define ADC_ARDUINO_PRESCALER ADC_Prescaler_Value_128
#elif F_CPU == 8000000
// 8 MHz / 64 = 125 KHz
#define ADC_ARDUINO_PRESCALER ADC_Prescaler_Value_64
#elif F_CPU == 1000000
// 1 MHz / 8 = 125 KHz
#define ADC_ARDUINO_PRESCALER ADC_Prescaler_Value_8
#else
#error Add an entry for the selected processor speed.
#endif
typedef enum
{
ADC_Prescaler_Value_2 = B001,
ADC_Prescaler_Value_4 = B010,
ADC_Prescaler_Value_8 = B011,
ADC_Prescaler_Value_16 = B100,
ADC_Prescaler_Value_32 = B101,
ADC_Prescaler_Value_64 = B110,
ADC_Prescaler_Value_128 = B111,
ADC_Prescaler_Index_1 = B001,
ADC_Prescaler_Index_2 = B010,
ADC_Prescaler_Index_3 = B011,
ADC_Prescaler_Index_4 = B100,
ADC_Prescaler_Index_5 = B101,
ADC_Prescaler_Index_6 = B110,
ADC_Prescaler_Index_7 = B111
}
adc_ps_t;
__attribute__((always_inline)) static inline void ADC_PrescalerSelect( adc_ps_t ps )
{
ADCSRA = (ADCSRA & ~MASK3(ADPS2,ADPS1,ADPS0)) | (ps << ADPS0);
}
__attribute__((always_inline)) static inline void ADC_Enable( void )
{
ADCSRA |= MASK1( ADEN );
}
#endif
/*=============================================================================
Veneer for the ATtiny84 ADC
=============================================================================*/
#if defined( __AVR_ATtinyX4__ )
typedef enum
{
ADC_Reference_VCC = B00,
ADC_Reference_External = B01,
ADC_Reference_Internal_1p1 = B10,
ADC_Reference_Reserved_1 = B11
}
adc_vr_t;
__attribute__((always_inline)) static inline void ADC_SetVoltageReference( adc_vr_t vr )
{
ADMUX = (ADMUX & ~MASK2(REFS1,REFS0)) | (((vr & B11) >> 0) << REFS0);
}
typedef enum
{
ADC_Input_ADC0 = B000000,
ADC_Input_ADC1 = B000001,
ADC_Input_ADC2 = B000010,
ADC_Input_ADC3 = B000011,
ADC_Input_ADC4 = B000100,
ADC_Input_ADC5 = B000101,
ADC_Input_ADC6 = B000110,
ADC_Input_ADC7 = B000111,
ADC_Input_GND = B100000, // 0V (AGND)
ADC_Input_1p1 = B100001, // 1.1V (I Ref)
ADC_Input_ADC8 = B100010, // For temperature sensor.
ADC_Input_Pos0_Neg0_20x = B100011, // For offset calibration, only.
ADC_Input_Pos0_Neg1_1x = B001000,
ADC_Input_Pos0_Neg1_20x = B001001,
ADC_Input_Pos0_Neg3_1x = B001010,
ADC_Input_Pos0_Neg3_20x = B001011,
ADC_Input_Pos1_Neg0_1x = B101000,
ADC_Input_Pos1_Neg0_20x = B101001,
ADC_Input_Pos1_Neg2_1x = B001100,
ADC_Input_Pos1_Neg2_20x = B001101,
ADC_Input_Pos1_Neg3_1x = B001110,
ADC_Input_Pos1_Neg3_20x = B001111,
ADC_Input_Pos2_Neg1_1x = B101100,
ADC_Input_Pos2_Neg1_20x = B101101,
ADC_Input_Pos2_Neg3_1x = B010000,
ADC_Input_Pos2_Neg3_20x = B010001,
ADC_Input_Pos3_Neg0_1x = B101010,
ADC_Input_Pos3_Neg0_20x = B101011,
ADC_Input_Pos3_Neg1_1x = B101110,
ADC_Input_Pos3_Neg1_20x = B101111,
ADC_Input_Pos3_Neg2_1x = B110000,
ADC_Input_Pos3_Neg2_20x = B110001,
ADC_Input_Pos3_Neg3_1x = B100100, // For offset calibration, only.
ADC_Input_Pos3_Neg3_20x = B100101, // For offset calibration, only.
ADC_Input_Pos3_Neg4_1x = B010010,
ADC_Input_Pos3_Neg4_20x = B010011,
ADC_Input_Pos3_Neg5_1x = B010100,
ADC_Input_Pos3_Neg5_20x = B010101,
ADC_Input_Pos3_Neg6_1x = B010110,
ADC_Input_Pos3_Neg6_20x = B010111,
ADC_Input_Pos3_Neg7_1x = B011000,
ADC_Input_Pos3_Neg7_20x = B011001,
ADC_Input_Pos4_Neg3_1x = B110010,
ADC_Input_Pos4_Neg3_20x = B110011,
ADC_Input_Pos4_Neg5_1x = B011010,
ADC_Input_Pos4_Neg5_20x = B011011,
ADC_Input_Pos5_Neg3_1x = B110100,
ADC_Input_Pos5_Neg3_20x = B110101,
ADC_Input_Pos5_Neg4_1x = B111010,
ADC_Input_Pos5_Neg4_20x = B111011,
ADC_Input_Pos5_Neg6_1x = B011100,
ADC_Input_Pos5_Neg6_20x = B011101,
ADC_Input_Pos6_Neg3_1x = B110110,
ADC_Input_Pos6_Neg3_20x = B110111,
ADC_Input_Pos6_Neg5_1x = B111100,
ADC_Input_Pos6_Neg5_20x = B111101,
ADC_Input_Pos6_Neg7_1x = B011110,
ADC_Input_Pos6_Neg7_20x = B011111,
ADC_Input_Pos7_Neg3_1x = B111000,
ADC_Input_Pos7_Neg3_20x = B111001,
ADC_Input_Pos7_Neg6_1x = B111110,
ADC_Input_Pos7_Neg6_20x = B111111,
ADC_Input_Pos7_Neg7_1x = B100110, // For offset calibration, only.
ADC_Input_Pos7_Neg7_20x = B100111 // For offset calibration, only.
}
adc_ic_t;
__attribute__((always_inline)) static inline void ADC_SetInputChannel( adc_ic_t ic )
{
ADMUX = (ADMUX & ~MASK6(MUX5,MUX4,MUX3,MUX2,MUX1,MUX0)) | (ic << MUX0);
}
__attribute__((always_inline)) static inline void ADC_StartConversion( void )
{
ADCSRA |= MASK1( ADSC );
}
__attribute__((always_inline)) static inline uint8_t ADC_ConversionInProgress( void )
{
return( (ADCSRA & (1<<ADSC)) != 0 );
}
__attribute__((always_inline)) static inline uint16_t ADC_GetDataRegister( void )
{
return( ADC );
}
#endif
/*=============================================================================
Veneer for the ATtiny85 ADC
=============================================================================*/
#if defined( __AVR_ATtinyX5__ )
typedef enum
{
ADC_Reference_VCC = B000,
ADC_Reference_External = B001,
ADC_Reference_Internal_1p1 = B010,
ADC_Reference_Reserved_1 = B011,
ADC_Reference_Internal_2p56 = B110,
ADC_Reference_Internal_2p56_Bypass_Capacitor = B111
}
adc_vr_t;
__attribute__((always_inline)) static inline void ADC_SetVoltageReference( adc_vr_t vr )
{
ADMUX = (ADMUX & ~MASK3(REFS1,REFS0,REFS2))
| (((vr & B011) >> 0) << REFS0)
| (((vr & B100) >> 2) << REFS2);
}
typedef enum
{
ADC_Input_ADC0 = B0000,
ADC_Input_ADC1 = B0001,
ADC_Input_ADC2 = B0010,
ADC_Input_ADC3 = B0011,
ADC_Input_Pos2_Neg2_1x = B0100, // For offset calibration, only.
ADC_Input_Pos2_Neg2_20x = B0101, // For offset calibration, only.
ADC_Input_Pos2_Neg3_1x = B0110,
ADC_Input_Pos2_Neg3_20x = B0111,
ADC_Input_Pos0_Neg0_1x = B1000,
ADC_Input_Pos0_Neg0_20x = B1001,
ADC_Input_Pos0_Neg1_1x = B1010,
ADC_Input_Pos0_Neg1_20x = B1011,
ADC_Input_VBG = B1100,
ADC_Input_GND = B1101,
ADC_Input_NA = B1110,
ADC_Input_ADC4 = B1111 // For temperature sensor.
}
adc_ic_t;
__attribute__((always_inline)) static inline void ADC_SetInputChannel( adc_ic_t ic )
{
ADMUX = (ADMUX & ~MASK4(MUX3,MUX2,MUX1,MUX0)) | (ic << MUX0);
}
__attribute__((always_inline)) static inline void ADC_StartConversion( void )
{
ADCSRA |= MASK1( ADSC );
}
__attribute__((always_inline)) static inline uint8_t ADC_ConversionInProgress( void )
{
return( (ADCSRA & (1<<ADSC)) != 0 );
}
__attribute__((always_inline)) static inline uint16_t ADC_GetDataRegister( void )
{
return( ADC );
}
#endif
/*=============================================================================
Veneer for the (non-existant) ATtinyX313 ADC
=============================================================================*/
#if defined( __AVR_ATtinyX313__ )
typedef enum
{
ADC_No_Reference = 0
}
adc_vr_t;
__attribute__((always_inline)) static inline void ADC_SetVoltageReference( adc_vr_t vr )
{
}
typedef enum
{
ADC_No_Input = 0
}
adc_ic_t;
__attribute__((always_inline)) static inline void ADC_SetInputChannel( adc_ic_t ic )
{
}
__attribute__((always_inline)) static inline void ADC_StartConversion( void )
{
}
__attribute__((always_inline)) static inline uint8_t ADC_ConversionInProgress( void )
{
return( 0 );
}
__attribute__((always_inline)) static inline uint16_t ADC_GetDataRegister( void )
{
return( 0 );
}
#endif
#endif

View File

@@ -0,0 +1,174 @@
/*==============================================================================
core_build_options.h - Various options for mapping functionality to hardware.
Copyright 2010 Rowdy Dog Software.
This file is part of Arduino-Tiny.
Arduino-Tiny 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 3 of the License, or (at your
option) any later version.
Arduino-Tiny 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 Arduino-Tiny. If not, see <http://www.gnu.org/licenses/>.
==============================================================================*/
#ifndef core_build_options_h
#define core_build_options_h
/*=============================================================================
Low power / smaller code options
=============================================================================*/
#define INITIALIZE_ANALOG_TO_DIGITAL_CONVERTER 1
#define INITIALIZE_SECONDARY_TIMERS 1
/*=============================================================================
Build options for the ATtinyX313 processor
=============================================================================*/
#if defined( __AVR_ATtiny2313__ ) || defined( __AVR_ATtiny4313__ )
#define __AVR_ATtinyX313__
#endif
#if defined( __AVR_ATtinyX313__ )
/*
The old standby ... millis on Timer 0.
*/
#define TIMER_TO_USE_FOR_MILLIS 0
/*
Tone goes on whichever timer was not used for millis.
*/
#if TIMER_TO_USE_FOR_MILLIS == 1
#define TIMER_TO_USE_FOR_TONE 0
#else
#define TIMER_TO_USE_FOR_TONE 1
#endif
#define HAVE_ADC 0
#define DEFAULT_TO_TINY_DEBUG_SERIAL 0
#endif
/*=============================================================================
Build options for the ATtiny84 processor
=============================================================================*/
#if defined( __AVR_ATtiny24__ ) || defined( __AVR_ATtiny44__ ) || defined( __AVR_ATtiny84__ )
#define __AVR_ATtinyX4__
#endif
#if defined( __AVR_ATtinyX4__ )
/*
The old standby ... millis on Timer 0.
*/
#define TIMER_TO_USE_FOR_MILLIS 0
/*
Tone goes on whichever timer was not used for millis.
*/
#if TIMER_TO_USE_FOR_MILLIS == 1
#define TIMER_TO_USE_FOR_TONE 0
#else
#define TIMER_TO_USE_FOR_TONE 1
#endif
#define HAVE_ADC 1
#define DEFAULT_TO_TINY_DEBUG_SERIAL 1
#endif
/*=============================================================================
Build options for the ATtiny85 processor
=============================================================================*/
#if defined( __AVR_ATtiny25__ ) || defined( __AVR_ATtiny45__ ) || defined( __AVR_ATtiny85__ )
#define __AVR_ATtinyX5__
#endif
#if defined( __AVR_ATtinyX5__ )
/*
For various reasons, Timer 1 is a better choice for the millis timer on the
'85 processor.
*/
#define TIMER_TO_USE_FOR_MILLIS 1
/*
If the following is true (non-zero) there will be two phase-correct PWM
pins and one fast PWM pin. If false there will be one phase-correct PWM
pin and two fast PWM pins.
*/
#define FAVOR_PHASE_CORRECT_PWM 1
/*
Tone goes on whichever timer was not used for millis.
*/
#if TIMER_TO_USE_FOR_MILLIS == 1
#define TIMER_TO_USE_FOR_TONE 0
#else
#define TIMER_TO_USE_FOR_TONE 1
#endif
#define HAVE_ADC 1
#define DEFAULT_TO_TINY_DEBUG_SERIAL 1
#endif
/*=============================================================================
There doesn't seem to be many people using a bootloader so we'll assume
there isn't one. If the following is true (non-zero), the timers are
reinitialized to their power-up state in init just in case the bootloader
left them in a bad way.
=============================================================================*/
#define HAVE_BOOTLOADER 0
/*=============================================================================
Allow the ADC to be optional for low-power applications
=============================================================================*/
#if ! defined( HAVE_ADC )
#define HAVE_ADC 0
#endif
#if ! HAVE_ADC
#undef INITIALIZE_ANALOG_TO_DIGITAL_CONVERTER
#define INITIALIZE_ANALOG_TO_DIGITAL_CONVERTER 0
#else
#if ! defined( INITIALIZE_ANALOG_TO_DIGITAL_CONVERTER )
#define INITIALIZE_ANALOG_TO_DIGITAL_CONVERTER 1
#endif
#endif
/*=============================================================================
Allow the "secondary timers" to be optional for low-power applications
=============================================================================*/
#if ! defined( INITIALIZE_SECONDARY_TIMERS )
#define INITIALIZE_SECONDARY_TIMERS 1
#endif
#endif

View File

@@ -0,0 +1,42 @@
/*==============================================================================
core_macros.h - Simple but handy macros.
Copyright 2010 Rowdy Dog Software.
This file is part of Arduino-Tiny.
Arduino-Tiny 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 3 of the License, or (at your
option) any later version.
Arduino-Tiny 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 Arduino-Tiny. If not, see <http://www.gnu.org/licenses/>.
==============================================================================*/
#ifndef core_macros_h
#define core_macros_h
/*=============================================================================
Bitmask macros
=============================================================================*/
#define MASK1(b1) ( (1<<b1) )
#define MASK2(b1,b2) ( (1<<b1) | (1<<b2) )
#define MASK3(b1,b2,b3) ( (1<<b1) | (1<<b2) | (1<<b3) )
#define MASK4(b1,b2,b3,b4) ( (1<<b1) | (1<<b2) | (1<<b3) | (1<<b4) )
#define MASK5(b1,b2,b3,b4,b5) ( (1<<b1) | (1<<b2) | (1<<b3) | (1<<b4) | (1<<b5) )
#define MASK6(b1,b2,b3,b4,b5,b6) ( (1<<b1) | (1<<b2) | (1<<b3) | (1<<b4) | (1<<b5) | (1<<b6) )
#define MASK7(b1,b2,b3,b4,b5,b6,b7) ( (1<<b1) | (1<<b2) | (1<<b3) | (1<<b4) | (1<<b5) | (1<<b6) | (1<<b7) )
#define MASK8(b1,b2,b3,b4,b5,b6,b7,b8) ( (1<<b1) | (1<<b2) | (1<<b3) | (1<<b4) | (1<<b5) | (1<<b6) | (1<<b7) | (1<<b8) )
#endif

View File

@@ -0,0 +1,204 @@
/*==============================================================================
core_pins.h - Pin definitions.
Copyright 2010 Rowdy Dog Software.
This file is part of Arduino-Tiny.
Arduino-Tiny 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 3 of the License, or (at your
option) any later version.
Arduino-Tiny 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 Arduino-Tiny. If not, see <http://www.gnu.org/licenses/>.
==============================================================================*/
#ifndef core_pins_h
#define core_pins_h
#include "core_build_options.h"
/*=============================================================================
Pin definitions for the ATtinyX313
=============================================================================*/
#if defined( __AVR_ATtinyX313__ )
#define PIN_D0 ( 0)
#define PIN_D1 ( 1)
#define PIN_A1 ( 2)
#define PIN_A0 ( 3)
#define PIN_D2 ( 4)
#define PIN_D3 ( 5)
#define PIN_D4 ( 6)
#define PIN_D5 ( 7)
#define PIN_D6 ( 8)
#define PIN_B0 ( 9)
#define PIN_B1 (10)
#define PIN_B2 (11)
#define PIN_B3 (12)
#define PIN_B4 (13)
#define PIN_B5 (14)
#define PIN_B6 (15)
#define PIN_B7 (16)
#define PIN_A2 (17) /* RESET */
#define CORE_DIGITAL_FIRST (0)
#define CORE_DIGITAL_LAST (17)
#define CORE_DIGITAL_COUNT (CORE_DIGITAL_LAST-CORE_DIGITAL_FIRST+1)
#define CORE_RESET_INCLUDED (1)
#define CORE_ANALOG_COUNT (0)
#define CORE_INT0_PIN PIN_D2
#define CORE_INT1_PIN PIN_D3
#define CORE_OC0A_PIN PIN_B2
#define CORE_OC0B_PIN PIN_D5
#define CORE_OC1A_PIN PIN_B3
#define CORE_OC1B_PIN PIN_B4
#define CORE_PWM0_PIN CORE_OC0A_PIN
#define CORE_PWM0_TIMER 0
#define CORE_PWM0_CHANNEL A
#define CORE_PWM1_PIN CORE_OC0B_PIN
#define CORE_PWM1_TIMER 0
#define CORE_PWM1_CHANNEL B
#define CORE_PWM2_PIN CORE_OC1A_PIN
#define CORE_PWM2_TIMER 1
#define CORE_PWM2_CHANNEL A
#define CORE_PWM3_PIN CORE_OC1B_PIN
#define CORE_PWM3_TIMER 1
#define CORE_PWM3_CHANNEL B
#define CORE_PWM_COUNT (4)
#endif
/*=============================================================================
Pin definitions for the ATtiny84
=============================================================================*/
#if defined( __AVR_ATtinyX4__ )
#define PIN_A0 (10)
#define PIN_A1 ( 9)
#define PIN_A2 ( 8)
#define PIN_A3 ( 7)
#define PIN_A4 ( 6)
#define PIN_A5 ( 5)
#define PIN_A6 ( 4)
#define PIN_A7 ( 3)
#define PIN_B0 ( 0)
#define PIN_B1 ( 1)
#define PIN_B2 ( 2)
#define PIN_B3 (11) /* RESET */
#define CORE_DIGITAL_FIRST (0)
#define CORE_DIGITAL_LAST (11)
#define CORE_DIGITAL_COUNT (CORE_DIGITAL_LAST-CORE_DIGITAL_FIRST+1)
#define CORE_RESET_INCLUDED (1)
#define CORE_ANALOG_FIRST (CORE_DIGITAL_LAST+1)
#define CORE_ANALOG_COUNT (8)
#define CORE_ANALOG_LAST (CORE_ANALOG_FIRST+CORE_ANALOG_COUNT-1)
#define CORE_INT0_PIN PIN_B2
#define CORE_OC0A_PIN PIN_B2
#define CORE_OC0B_PIN PIN_A7
#define CORE_OC1A_PIN PIN_A6
#define CORE_OC1B_PIN PIN_A5
#define CORE_PWM0_PIN CORE_OC0A_PIN
#define CORE_PWM0_TIMER 0
#define CORE_PWM0_CHANNEL A
#define CORE_PWM1_PIN CORE_OC0B_PIN
#define CORE_PWM1_TIMER 0
#define CORE_PWM1_CHANNEL B
#define CORE_PWM2_PIN CORE_OC1A_PIN
#define CORE_PWM2_TIMER 1
#define CORE_PWM2_CHANNEL A
#define CORE_PWM3_PIN CORE_OC1B_PIN
#define CORE_PWM3_TIMER 1
#define CORE_PWM3_CHANNEL B
#define CORE_PWM_COUNT (4)
#endif
/*=============================================================================
Pin definitions for the ATtiny85
=============================================================================*/
#if defined( __AVR_ATtinyX5__ )
#define PIN_B0 ( 0)
#define PIN_B1 ( 1)
#define PIN_B2 ( 2)
#define PIN_B3 ( 3)
#define PIN_B4 ( 4)
#define PIN_B5 ( 5) /* RESET */
#define CORE_DIGITAL_FIRST (0)
#define CORE_DIGITAL_LAST (5)
#define CORE_DIGITAL_COUNT (CORE_DIGITAL_LAST-CORE_DIGITAL_FIRST+1)
#define CORE_RESET_INCLUDED (1)
#define CORE_ANALOG_FIRST (CORE_DIGITAL_LAST+1)
#define CORE_ANALOG_COUNT (4)
#define CORE_ANALOG_LAST (CORE_ANALOG_FIRST+CORE_ANALOG_COUNT-1)
#define CORE_INT0_PIN PIN_B2
#define CORE_OC0A_PIN PIN_B0
#define CORE_OC0B_PIN PIN_B1
#define CORE_OC1A_PIN PIN_B1
#define CORE_OC1B_PIN PIN_B4
/* Note: By default, CORE_OC1A_PIN is not used for PWM. It overlaps with
CORE_OC0B_PIN. CORE_OC0B_PIN was used because it supports phase-correct PWM.
There is a build option in "core_build_options.h" to determine which channel
to use */
#define CORE_PWM0_PIN CORE_OC0A_PIN
#define CORE_PWM0_TIMER 0
#define CORE_PWM0_CHANNEL A
#if FAVOR_PHASE_CORRECT_PWM
#define CORE_PWM1_PIN CORE_OC0B_PIN
#define CORE_PWM1_TIMER 0
#define CORE_PWM1_CHANNEL B
#else
#define CORE_PWM1_PIN CORE_OC1A_PIN
#define CORE_PWM1_TIMER 1
#define CORE_PWM1_CHANNEL A
#endif
#define CORE_PWM2_PIN CORE_OC1B_PIN
#define CORE_PWM2_TIMER 1
#define CORE_PWM2_CHANNEL B
#define CORE_PWM_COUNT (3)
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,14 @@
#include <WProgram.h>
int main(void)
{
init();
setup();
for (;;)
loop();
return 0;
}

View File

@@ -0,0 +1,18 @@
#include <new.h>
void * operator new(size_t size)
{
return malloc(size);
}
void operator delete(void * ptr)
{
free(ptr);
}
int __cxa_guard_acquire(__guard *g) {return !*(char *)(g);};
void __cxa_guard_release (__guard *g) {*(char *)g = 1;};
void __cxa_guard_abort (__guard *) {};
void __cxa_pure_virtual(void) {};

View File

@@ -0,0 +1,22 @@
/* Header to define new/delete operators as they aren't provided by avr-gcc by default
Taken from http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=59453
*/
#ifndef NEW_H
#define NEW_H
#include <stdlib.h>
void * operator new(size_t size);
void operator delete(void * ptr);
__extension__ typedef int __guard __attribute__((mode (__DI__)));
extern "C" int __cxa_guard_acquire(__guard *);
extern "C" void __cxa_guard_release (__guard *);
extern "C" void __cxa_guard_abort (__guard *);
extern "C" void __cxa_pure_virtual(void);
#endif

View File

@@ -0,0 +1,321 @@
/*
pins_arduino.c - pin definitions for the Arduino board
Part of Arduino / Wiring Lite
Copyright (c) 2005 David A. Mellis
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
$Id: pins_arduino.c 565 2009-03-25 10:50:00Z dmellis $
Modified 28-08-2009 for attiny84 R.Wiersma
Modified 09-10-2009 for attiny45 A.Saporetti
Modified for Atmel ATTiny2313 mcu by Ren<65> Bohne
Corrected 17-05-2010 for ATtiny84 B.Cook ...
The default analog_reference leaves chip pin 13 (digital pin 10; PA0)
unconnected. So the pin can be set to a non-floating state and so the
pin can be used as another digital pin, support for digital pin 10 was
added.
*/
#include <avr/io.h>
#include "pins_arduino.h"
#include "wiring_private.h"
#if defined( __AVR_ATtinyX313__ )
// On the Arduino board, digital pins are also used
// for the analog output (software PWM). Analog input
// pins are a separate set.
// ATMEL ATTINY2313
//
// +-\/-+
// (D 17) PA2 1| |29 VCC
// RX (D 0) PD0 2| |19 PB7 (D 16)
// TX (D 1) PD1 3| |18 PB6 (D 15)
// (D 2) PA1 4| |17 PB5 (D 14)
// (D 3) PA0 5| |16 PB4 (D 13)*
// INT0 (D 4) PD2 6| |15 PB3 (D 12)*
// INT1 (D 5) PD3 7| |14 PB2 (D 11)*
// (D 6) PD4 8| |13 PB1 (D 10)
// *(D 7) PD5 9| |12 PB0 (D 9)
// GND 10| |11 PD6 (D 8)
// +----+
//
// * indicates PWM port
// these arrays map port names (e.g. port B) to the
// appropriate addresses for various functions (e.g. reading
// and writing)
const uint8_t PROGMEM port_to_mode_PGM[] =
{
NOT_A_PORT,
&DDRA,
&DDRB,
NOT_A_PORT,
&DDRD,
};
const uint8_t PROGMEM port_to_output_PGM[] =
{
NOT_A_PORT,
&PORTA,
&PORTB,
NOT_A_PORT,
&PORTD,
};
const uint8_t PROGMEM port_to_input_PGM[] =
{
NOT_A_PORT,
&PINA,
&PINB,
NOT_A_PORT,
&PIND,
};
const uint8_t PROGMEM digital_pin_to_port_PGM[] =
{
PORT_D_ID, /* 0 */
PORT_D_ID,
PORT_A_ID,
PORT_A_ID,
PORT_D_ID,
PORT_D_ID,
PORT_D_ID,
PORT_D_ID,
PORT_D_ID, /* 8 */
PORT_B_ID,
PORT_B_ID,
PORT_B_ID,
PORT_B_ID,
PORT_B_ID,
PORT_B_ID, /* 14 */
PORT_B_ID,
PORT_B_ID,
PORT_A_ID,
};
const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] =
{
_BV(0), /* 0 */
_BV(1),
_BV(1),
_BV(0),
_BV(2),
_BV(3),
_BV(4),
_BV(5),
_BV(6), /* 8 */
_BV(0),
_BV(1),
_BV(2),
_BV(3),
_BV(4),
_BV(5), /* 14 */
_BV(6),
_BV(7),
_BV(2),
};
const uint8_t PROGMEM digital_pin_to_timer_PGM[] =
{
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
TIMER0B,
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
TIMER0A,
TIMER1A,
TIMER1B,
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
};
#endif
#if defined( __AVR_ATtinyX4__ )
// ATMEL ATTINY84 / ARDUINO
//
// +-\/-+
// VCC 1| |14 GND
// (D 0) PB0 2| |13 AREF (D 10)
// (D 1) PB1 3| |12 PA1 (D 9)
// PB3 4| |11 PA2 (D 8)
// PWM INT0 (D 2) PB2 5| |10 PA3 (D 7)
// PWM (D 3) PA7 6| |9 PA4 (D 6)
// PWM (D 4) PA6 7| |8 PA5 (D 5) PWM
// +----+
// these arrays map port names (e.g. port B) to the
// appropriate addresses for various functions (e.g. reading
// and writing)
const uint8_t PROGMEM port_to_mode_PGM[] =
{
NOT_A_PORT,
&DDRA,
&DDRB,
};
const uint8_t PROGMEM port_to_output_PGM[] =
{
NOT_A_PORT,
&PORTA,
&PORTB,
};
const uint8_t PROGMEM port_to_input_PGM[] =
{
NOT_A_PORT,
&PINA,
&PINB,
};
const uint8_t PROGMEM port_to_pcmask_PGM[] =
{
NOT_A_PORT,
&PCMSK0,
&PCMSK1,
};
const uint8_t PROGMEM digital_pin_to_port_PGM[] =
{
PORT_B_ID, /* 0 */
PORT_B_ID,
PORT_B_ID,
PORT_A_ID,
PORT_A_ID,
PORT_A_ID,
PORT_A_ID,
PORT_A_ID,
PORT_A_ID, /* 8 */
PORT_A_ID,
PORT_A_ID,
};
const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] =
{
_BV(0), /* 0, port B */
_BV(1),
_BV(2),
_BV(7), /* 3 port B */
_BV(6),
_BV(5),
_BV(4),
_BV(3),
_BV(2),
_BV(1),
_BV(0),
};
const uint8_t PROGMEM digital_pin_to_timer_PGM[] =
{
NOT_ON_TIMER,
NOT_ON_TIMER,
TIMER0A, /* OC0A */
TIMER0B, /* OC0B */
TIMER1A, /* OC1A */
TIMER1B, /* OC1B */
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
};
#endif
#if defined( __AVR_ATtinyX5__ )
// ATMEL ATTINY45 / ARDUINO
//
// +-\/-+
// Ain0 (D 5) PB5 1| |8 VCC
// Ain3 (D 3) PB3 2| |7 PB2 (D 2) INT0 Ain1
// Ain2 (D 4) PB4 3| |6 PB1 (D 1) pwm1
// GND 4| |5 PB0 (D 0) pwm0
// +----+
// these arrays map port names (e.g. port B) to the
// appropriate addresses for various functions (e.g. reading
// and writing) tiny45 only port B
const uint8_t PROGMEM port_to_mode_PGM[] =
{
NOT_A_PORT,
&DDRB,
};
const uint8_t PROGMEM port_to_output_PGM[] =
{
NOT_A_PORT,
&PORTB,
};
const uint8_t PROGMEM port_to_input_PGM[] =
{
NOT_A_PIN,
&PINB,
};
const uint8_t PROGMEM digital_pin_to_port_PGM[] =
{
PORT_B_ID, /* 0 */
PORT_B_ID,
PORT_B_ID,
PORT_B_ID,
PORT_B_ID,
PORT_B_ID, /* 5 */
};
const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] =
{
_BV(0), /* 0, port B */
_BV(1),
_BV(2),
_BV(3), /* 3 port B */
_BV(4),
_BV(5),
};
const uint8_t PROGMEM digital_pin_to_timer_PGM[] =
{
TIMER0A, /* OC0A */
TIMER1A, /* OC1A? */
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
NOT_ON_TIMER,
};
#endif

View File

@@ -0,0 +1,115 @@
/*
pins_arduino.h - Pin definition functions for Arduino
Part of Arduino - http://www.arduino.cc/
Copyright (c) 2007 David A. Mellis
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
$Id: wiring.h 249 2007-02-03 16:52:51Z mellis $
Modified 28-08-2009 for attiny84 R.Wiersma
Modified 14-10-2009 for attiny45 Saposoft
*/
#ifndef Pins_Arduino_h
#define Pins_Arduino_h
#include <avr/pgmspace.h>
#include "core_build_options.h"
#if defined( __AVR_ATtinyX313__ )
#define PORT_A_ID 1
#define PORT_B_ID 2
#define PORT_D_ID 4
#endif
#if defined( __AVR_ATtinyX4__ )
#define PORT_A_ID 1
#define PORT_B_ID 2
#endif
#if defined( __AVR_ATtinyX5__ )
#define PORT_B_ID 1
#endif
#define NOT_A_PIN 0
#define NOT_A_PORT 0
#define NOT_ON_TIMER 0
#define TIMER0A 1
#define TIMER0B 2
#define TIMER1A 3
#define TIMER1B 4
//changed it to uint16_t to uint8_t
extern const uint8_t PROGMEM port_to_mode_PGM[];
extern const uint8_t PROGMEM port_to_input_PGM[];
extern const uint8_t PROGMEM port_to_output_PGM[];
extern const uint8_t PROGMEM port_to_pcmask_PGM[];
extern const uint8_t PROGMEM digital_pin_to_port_PGM[];
// extern const uint8_t PROGMEM digital_pin_to_bit_PGM[];
extern const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[];
extern const uint8_t PROGMEM digital_pin_to_timer_PGM[];
// Get the bit location within the hardware port of the given virtual pin.
// This comes from the pins_*.c file for the active board configuration.
//
// These perform slightly better as macros compared to inline functions
//
#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )
#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) )
#define digitalPinToTimer(P) ( pgm_read_byte( digital_pin_to_timer_PGM + (P) ) )
#define analogInPinToBit(P) (P)
// in the following lines modified pgm_read_word in pgm_read_byte, word doesn't work on attiny45
#define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_byte( port_to_output_PGM + (P))) )
#define portInputRegister(P) ( (volatile uint8_t *)( pgm_read_byte( port_to_input_PGM + (P))) )
#define portModeRegister(P) ( (volatile uint8_t *)( pgm_read_byte( port_to_mode_PGM + (P))) )
#define portPcMaskRegister(P) ( (volatile uint8_t *)( pgm_read_byte( port_to_pcmask_PGM + (P))) )
#if defined(__AVR_ATtinyX5__)
#define digitalPinToPCICR(p) (((p) >= 0 && (p) <= 5) ? (&GIMSK) : ((uint8_t *)NULL))
#define digitalPinToPCICRbit(p) (PCIE)
#define digitalPinToPCMSK(p) (((p) >= 0 && (p) <= 5) ? (&PCMSK) : ((uint8_t *)NULL))
#define digitalPinToPCMSKbit(p) (p)
#endif
#if defined(__AVR_ATtinyX4__)
#define digitalPinToPCICR(p) (((p) >= 0 && (p) <= 10) ? (&GIMSK) : ((uint8_t *)NULL))
#define digitalPinToPCICRbit(p) (((p) <= 2) ? PCIE1 : PCIE0)
#define digitalPinToPCMSK(p) (((p) <= 2) ? (&PCMSK1) : (((p) <= 10) ? (&PCMSK0) : ((uint8_t *)NULL)))
#define digitalPinToPCMSKbit(p) (((p) <= 2) ? (p) : (10 - (p)))
#endif
#if defined(__AVR_ATtiny4313__)
#define digitalPinToPCX(p,s1,s2,s3,s4,s5) \
(((p) >= 0) \
? (((p) <= 1) ? (s1) /* 0 - 1 ==> D0 - D1 */ \
: (((p) <= 3) ? (s2) /* 2 - 3 ==> A1 - A0 */ \
: (((p) <= 8) ? (s3) /* 4 - 8 ==> D2 - D6 */ \
: (((p) <= 16) ? (s4) /* 9 - 16 ==> B0 - B7 */ \
: (s5))))) \
: (s5))
// s1 D s2 A s3 D s4 B
#define digitalPinToPCICR(p) digitalPinToPCX( p, &GIMSK, &GIMSK, &GIMSK, &GIMSK, NULL )
#define digitalPinToPCICRbit(p) digitalPinToPCX( p, PCIE2, PCIE1, PCIE2, PCIE0, 0 )
#define digitalPinToPCMSK(p) digitalPinToPCX( p, &PCMSK2, &PCMSK1, &PCMSK2, &PCMSK0, NULL )
#define digitalPinToPCMSKbit(p) digitalPinToPCX( p, p, 3-p, p-2, p-9, 0 )
#endif
#endif

View File

@@ -0,0 +1,366 @@
/*
wiring.c - Partial implementation of the Wiring API for the ATmega8.
Part of Arduino - http://www.arduino.cc/
Copyright (c) 2005-2006 David A. Mellis
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
$Id: wiring.c 970 2010-05-25 20:16:15Z dmellis $
Modified 28-08-2009 for attiny84 R.Wiersma
Modified 14-10-2009 for attiny45 Saposoft
Modified 20-11-2010 - B.Cook - Rewritten to use the various Veneers.
*/
#include "core_build_options.h"
#include "core_adc.h"
#include "core_timers.h"
#include "wiring_private.h"
#include "ToneTimer.h"
#if F_CPU != 16500000L
#include <avr/boot.h>
#endif
#define millistimer_(t) TIMER_PASTE_A( timer, TIMER_TO_USE_FOR_MILLIS, t )
#define MillisTimer_(f) TIMER_PASTE_A( Timer, TIMER_TO_USE_FOR_MILLIS, f )
#define MILLISTIMER_(c) TIMER_PASTE_A( TIMER, TIMER_TO_USE_FOR_MILLIS, c )
#define MillisTimer_SetToPowerup MillisTimer_(SetToPowerup)
#define MillisTimer_SetWaveformGenerationMode MillisTimer_(SetWaveformGenerationMode)
#define MillisTimer_GetCount MillisTimer_(GetCount)
#define MillisTimer_IsOverflowSet MillisTimer_(IsOverflowSet)
#define MillisTimer_ClockSelect MillisTimer_(ClockSelect)
#define MillisTimer_EnableOverflowInterrupt MillisTimer_(EnableOverflowInterrupt)
#define MILLISTIMER_OVF_vect MILLISTIMER_(OVF_vect)
#define MS_TIMER_TICK_EVERY_X_CYCLES 64 /* Shall be a within 1, 8, 64, 256 or 1024. (default = 64) If set to 1, HW PWM is around 64.5KHz@16.5MHz with Digispark */
#if F_CPU >= 3000000L
#if !defined(MS_TIMER_TICK_EVERY_X_CYCLES)
#define MillisTimer_Prescale_Index MillisTimer_(Prescale_Value_64)
#define MillisTimer_Prescale_Value (64)
#define ToneTimer_Prescale_Index ToneTimer_(Prescale_Value_64)
#define ToneTimer_Prescale_Value (64)
#else
#define Prescaler_Value(Val) PRESCALER_VALUE(Val)
#define PRESCALER_VALUE(Val) Prescale_Value_##Val
#define MillisTimer_Prescale_Index MillisTimer_(Prescaler_Value(MS_TIMER_TICK_EVERY_X_CYCLES))
#define MillisTimer_Prescale_Value (MS_TIMER_TICK_EVERY_X_CYCLES)
#define ToneTimer_Prescale_Index ToneTimer_(Prescaler_Value(MS_TIMER_TICK_EVERY_X_CYCLES))
#define ToneTimer_Prescale_Value (MS_TIMER_TICK_EVERY_X_CYCLES)
#endif
#else
#define MillisTimer_Prescale_Index MillisTimer_(Prescale_Value_8)
#define MillisTimer_Prescale_Value (8)
#define ToneTimer_Prescale_Index ToneTimer_(Prescale_Value_8)
#define ToneTimer_Prescale_Value (8)
#endif
// the prescaler is set so that the millis timer ticks every MillisTimer_Prescale_Value (64) clock cycles, and the
// the overflow handler is called every 256 ticks.
#define MICROSECONDS_PER_MILLIS_OVERFLOW (clockCyclesToMicroseconds(MillisTimer_Prescale_Value * 256))
// the whole number of milliseconds per millis timer overflow
#define MILLIS_INC (MICROSECONDS_PER_MILLIS_OVERFLOW / 1000)
// the fractional number of milliseconds per millis timer overflow. we shift right
// by three to fit these numbers into a byte. (for the clock speeds we care
// about - 8 and 16 MHz - this doesn't lose precision.)
#define FRACT_INC ((MICROSECONDS_PER_MILLIS_OVERFLOW % 1000) >> 3)
#define FRACT_MAX (1000 >> 3)
volatile unsigned long millis_timer_overflow_count = 0;
volatile unsigned long millis_timer_millis = 0;
static unsigned char millis_timer_fract = 0;
// bluebie changed isr to noblock so it wouldn't mess up USB libraries
ISR(MILLISTIMER_OVF_vect, ISR_NOBLOCK)
{
// copy these to local variables so they can be stored in registers
// (volatile variables must be read from memory on every access)
unsigned long m = millis_timer_millis;
unsigned char f = millis_timer_fract;
/* rmv: The code below generates considerably less code (emtpy Sketch is 326 versus 304)...
m += MILLIS_INC;
f += FRACT_INC;
if (f >= FRACT_MAX) {
f -= FRACT_MAX;
m += 1;
}
...rmv */
f += FRACT_INC;
if (f >= FRACT_MAX)
{
f -= FRACT_MAX;
m = m + MILLIS_INC + 1;
}
else
{
m += MILLIS_INC;
}
millis_timer_fract = f;
millis_timer_millis = m;
millis_timer_overflow_count++;
}
unsigned long millis()
{
unsigned long m;
uint8_t oldSREG = SREG;
// disable interrupts while we read millis_timer_millis or we might get an
// inconsistent value (e.g. in the middle of a write to millis_timer_millis)
cli();
m = millis_timer_millis;
SREG = oldSREG;
return m;
}
unsigned long micros()
{
unsigned long m;
uint8_t oldSREG = SREG, t;
cli();
m = millis_timer_overflow_count;
t = MillisTimer_GetCount();
if (MillisTimer_IsOverflowSet() && (t < 255))
m++;
SREG = oldSREG;
#if (MillisTimer_Prescale_Value >= clockCyclesPerMicrosecond())
return ((m << 8) + t) * (MillisTimer_Prescale_Value / clockCyclesPerMicrosecond());
#else
return ((m << 8) + t) / (clockCyclesPerMicrosecond() / MillisTimer_Prescale_Value);
#endif
}
void delay(unsigned long ms)
{
uint16_t start = (uint16_t)micros();
while (ms > 0) {
if (((uint16_t)micros() - start) >= 1000) {
ms--;
start += 1000;
}
}
}
#if F_CPU == 16500000L
// optimised delay loop from Bluebie contributed to Digispark project
// deals accurately with half-mhz clock speed, but can only delay in increments of 2us rounded down
// this loop has been tuned empirically with an oscilloscope and works in avr-gcc 4.5.1
void delayMicroseconds(unsigned int us){
us &= ((unsigned int) 0) - ((unsigned int) 2); // remove least signifficant bit
while (us > 1) {
// 16 nops
asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");
asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");
// 11 nops
asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");asm("NOP");
asm("NOP");asm("NOP");asm("NOP");
us -= 2;
}
}
#else
/* Improved delayMicroseconds function
* Copyright (c) 2011, Paul Stoffregen, paul at pjrc dot com
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
// modified by Bluebie in 2013 for Digispark project
// #include <stdint.h>
// #include <avr/io.h>
void delayMicroseconds(uint16_t usec) {
asm volatile(
#if F_CPU == 16000000L
"sbiw %A0, 2" "\n\t" // 2
"brcs L_%=_end" "\n\t" // 1
"breq L_%=_end" "\n\t" // 1
"lsl %A0" "\n\t" // 1
"rol %B0" "\n\t" // 1
"lsl %A0" "\n\t" // 1
"rol %B0" "\n\t" // 1 overhead: (8)/4 = 2us
#elif F_CPU == 8000000L
"sbiw %A0, 3" "\n\t" // 2
"brcs L_%=_end" "\n\t" // 1
"breq L_%=_end" "\n\t" // 1
"lsl %A0" "\n\t" // 1
"rol %B0" "\n\t" // 1 overhead: (6)/2 = 3 us
#elif F_CPU == 4000000L
"sbiw %A0, 4" "\n\t" // 2
"brcs L_%=_end" "\n\t" // 1
"breq L_%=_end" "\n\t" // 1 overhead: (4) = 4 us
#elif F_CPU == 2000000L
"sbiw %A0, 12" "\n\t" // 2
"brcs L_%=_end" "\n\t" // 1
"breq L_%=_end" "\n\t" // 1
"lsr %B0" "\n\t" // 1
"ror %A0" "\n\t" // 1 overhead: (6)*2 = 12 us
#elif F_CPU == 1000000L
"sbiw %A0, 32" "\n\t" // 2
"brcs L_%=_end" "\n\t" // 1
"breq L_%=_end" "\n\t" // 1
"lsr %B0" "\n\t" // 1
"ror %A0" "\n\t" // 1
"lsr %B0" "\n\t" // 1
"ror %A0" "\n\t" // 1 overhead: (8)*4 = 32 us
#endif
"L_%=_loop:"
"sbiw %A0, 1" "\n\t" // 2
"brne L_%=_loop" "\n\t" // 2
"L_%=_end:"
: "+w" (usec)
: "0" (usec)
);
}
#endif
static void initToneTimerInternal(void)
{
// Stop the clock while we make changes
ToneTimer_ClockSelect( ToneTimer_(Stopped) );
// Set the timer to phase-correct PWM
#if defined( TONETIMER_SUPPORTS_PHASE_CORRECT_PWM ) && TONETIMER_SUPPORTS_PHASE_CORRECT_PWM
ToneTimer_SetWaveformGenerationMode( ToneTimer_(Phase_Correct_PWM_FF) );
#else
ToneTimer_SetWaveformGenerationMode( ToneTimer_(Fast_PWM_FF) );
#endif
// Timer is processor clock divided by ToneTimer_Prescale_Index (64)
ToneTimer_ClockSelect( ToneTimer_Prescale_Index );
}
void initToneTimer(void)
{
// Ensure the timer is in the same state as power-up
ToneTimer_SetToPowerup();
#if defined( INITIALIZE_SECONDARY_TIMERS ) && INITIALIZE_SECONDARY_TIMERS
// Prepare the timer for PWM
initToneTimerInternal();
#endif
}
#if F_CPU != 16500000L
// used to detect bootloader applying calibration in init
byte read_factory_calibration(void)
{
byte SIGRD = 5; // for some reason this isn't defined...
byte value = boot_signature_byte_get(1);
return value;
}
#endif
void init(void)
{
// clock calibration stuff
// recalibrate clock if it was calibrated by bootloader (like micronucleus)
#if F_CPU != 16500000L
if (OSCCAL != read_factory_calibration()) {
// adjust the calibration down from 16.5mhz to 16.0mhz
if (OSCCAL >= 128) {
// maybe 8 is better? oh well - only about 0.3% out anyway
OSCCAL -= 7;
} else {
OSCCAL -= 5;
}
}
#endif
// TODO: detect if fuses set to PLL, regular internal oscillator or external and change behaviour in this next section...
#if F_CPU < 16000000L
cli();
CLKPR = 0b10000000;
#if F_CPU == 8000000L
CLKPR = 1; // div 2
#elif F_CPU == 4000000L
CLKPR = 2 // div 4
#elif F_CPU == 2000000L
CLKPR = 3; // div 8
#elif F_CPU == 1000000L
CLKPR = 4; // div 16
#elif F_CPU == 500000L
CLKPR = 5; // div 32 = 500khz
#elif F_CPU == 250000L
CLKPR = 6; // div 64 = 250khz
#elif F_CPU == 125000L
CLKPR = 7; // div 128 = 125khz cpu clock
#else
#warning "Cannot prescale chip to specified F_CPU speed"
#endif
#endif
// this needs to be called before setup() or some functions won't work there
sei();
// In case the bootloader left our millis timer in a bad way
#if defined( HAVE_BOOTLOADER ) && HAVE_BOOTLOADER
MillisTimer_SetToPowerup();
#endif
// Use the Millis Timer for fast PWM
MillisTimer_SetWaveformGenerationMode( MillisTimer_(Fast_PWM_FF) );
// Millis timer is always processor clock divided by MillisTimer_Prescale_Value (64)
MillisTimer_ClockSelect( MillisTimer_Prescale_Index );
// Enable the overlow interrupt (this is the basic system tic-toc for millis)
MillisTimer_EnableOverflowInterrupt();
// Initialize the timer used for Tone
#if defined( INITIALIZE_SECONDARY_TIMERS ) && INITIALIZE_SECONDARY_TIMERS
initToneTimerInternal();
#endif
// Initialize the ADC
#if defined( INITIALIZE_ANALOG_TO_DIGITAL_CONVERTER ) && INITIALIZE_ANALOG_TO_DIGITAL_CONVERTER
ADC_PrescalerSelect( ADC_ARDUINO_PRESCALER );
ADC_Enable();
#endif
}

View File

@@ -0,0 +1,194 @@
/*
wiring.h - Partial implementation of the Wiring API for the ATmega8.
Part of Arduino - http://www.arduino.cc/
Copyright (c) 2005-2006 David A. Mellis
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
$Id: wiring.h 1073 2010-08-17 21:50:41Z dmellis $
Modified 28-08-2009 for attiny84 R.Wiersma
Modified 14-108-2009 for attiny45 Saposoft
*/
#ifndef Wiring_h
#define Wiring_h
#include <avr/io.h>
#include <stdlib.h>
#include "binary.h"
#include "core_build_options.h"
#ifdef __cplusplus
extern "C"{
#endif
#define HIGH 0x1
#define LOW 0x0
#define INPUT 0x0
#define OUTPUT 0x1
#define true 0x1
#define false 0x0
#define PI 3.1415926535897932384626433832795
#define HALF_PI 1.5707963267948966192313216916398
#define TWO_PI 6.283185307179586476925286766559
#define DEG_TO_RAD 0.017453292519943295769236907684886
#define RAD_TO_DEG 57.295779513082320876798154814105
#define SERIAL 0x0
#define DISPLAY 0x1
#define LSBFIRST 0
#define MSBFIRST 1
#define CHANGE 1
#define FALLING 2
#define RISING 3
/* rmv or fix
#if defined(__AVR_ATmega1280__)
#define INTERNAL1V1 2
#define INTERNAL2V56 3
#else
#define INTERNAL 3
#endif
#define DEFAULT 1
#define EXTERNAL 0
*/
/* rmv
analogReference constants for ATmega168. These are NOT correct for the ATtiny84 nor for the ATtiny85. The correct values are below.
// Internal 1.1V Voltage Reference with external capacitor at AREF pin
#define INTERNAL 3
// AVCC with external capacitor at AREF pin
#define DEFAULT 1
// AREF, Internal Vref turned off
#define EXTERNAL 0
*/
#if defined( __AVR_ATtinyX313__ )
#define DEFAULT (0)
#elif defined( __AVR_ATtinyX4__ )
// VCC used as analog reference, disconnected from PA0 (AREF)
#define DEFAULT (0)
// External voltage reference at PA0 (AREF) pin, internal reference turned off
#define EXTERNAL (1)
// Internal 1.1V voltage reference
#define INTERNAL (2)
#elif defined( __AVR_ATtinyX5__ )
// X 0 0 VCC used as Voltage Reference, disconnected from PB0 (AREF).
#define DEFAULT (0)
// X 0 1 External Voltage Reference at PB0 (AREF) pin, Internal Voltage Reference turned off.
#define EXTERNAL (1)
// 0 1 0 Internal 1.1V Voltage Reference.
#define INTERNAL (2)
#define INTERNAL1V1 INTERNAL
// 1 1 1 Internal 2.56V Voltage Reference with external bypass capacitor at PB0 (AREF) pin(1).
#define INTERNAL2V56 (7)
// An alternative for INTERNAL2V56 is (6) ...
// 1 1 0 Internal 2.56V Voltage Reference without external bypass capacitor, disconnected from PB0 (AREF)(1).
#endif
// undefine stdlib's abs if encountered
#ifdef abs
#undef abs
#endif
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
#if __AVR_LIBC_VERSION__ < 10701UL
#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
#endif
#define radians(deg) ((deg)*DEG_TO_RAD)
#define degrees(rad) ((rad)*RAD_TO_DEG)
#define sq(x) ((x)*(x))
#define interrupts() sei()
#define noInterrupts() cli()
#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
#define clockCyclesToMicroseconds(a) ( ((a) * 1000L) / (F_CPU / 1000L) )
#define microsecondsToClockCycles(a) ( ((a) * (F_CPU / 1000L)) / 1000L )
#define lowByte(w) ((uint8_t) ((w) & 0xff))
#define highByte(w) ((uint8_t) ((w) >> 8))
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
typedef unsigned int word;
#define bit(b) (1UL << (b))
typedef uint8_t boolean;
typedef uint8_t byte;
void initToneTimer(void);
void init(void);
void pinMode(uint8_t, uint8_t);
void digitalWrite(uint8_t, uint8_t);
int digitalRead(uint8_t);
int analogRead(uint8_t);
void analogReference(uint8_t mode);
void analogWrite(uint8_t, int);
unsigned long millis(void);
unsigned long micros(void);
void delay(unsigned long);
void delayMicroseconds(unsigned int us);
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout);
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val);
uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder);
void attachInterrupt(uint8_t, void (*)(void), int mode);
void detachInterrupt(uint8_t);
void setup(void);
void loop(void);
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@@ -0,0 +1,140 @@
/*
wiring_analog.c - analog input and output
Part of Arduino - http://www.arduino.cc/
Copyright (c) 2005-2006 David A. Mellis
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
$Id: wiring.c 248 2007-02-03 15:36:30Z mellis $
Modified 28-08-2009 for attiny84 R.Wiersma
Modified 14-10-2009 for attiny45 Saposoft
Corrected 17-05-2010 for ATtiny84 B.Cook
*/
#include "wiring_private.h"
#include "pins_arduino.h"
#include "core_adc.h"
#include "core_pins.h"
#include "core_timers.h"
#include "PwmTimer.h"
uint8_t analog_reference = DEFAULT;
void analogReference(uint8_t mode)
{
// can't actually set the register here because the default setting
// will connect AVCC and the AREF pin, which would cause a short if
// there's something connected to AREF.
// fix? Validate the mode?
analog_reference = mode;
}
int analogRead(uint8_t pin)
{
#if defined( CORE_ANALOG_FIRST )
if ( pin >= CORE_ANALOG_FIRST ) pin -= CORE_ANALOG_FIRST; // allow for channel or pin numbers
#endif
// fix? Validate pin?
ADC_SetVoltageReference( analog_reference );
ADC_SetInputChannel( pin );
ADC_StartConversion();
while( ADC_ConversionInProgress() );
return( ADC_GetDataRegister() );
}
// Right now, PWM output only works on the pins with
// hardware support. These are defined in the appropriate
// pins_*.c file. For the rest of the pins, we default
// to digital output.
void analogWrite(uint8_t pin, int val)
{
// We need to make sure the PWM output is enabled for those pins
// that support it, as we turn it off when digitally reading or
// writing with them. Also, make sure the pin is in output mode
// for consistenty with Wiring, which doesn't require a pinMode
// call for the analog output pins.
pinMode(pin, OUTPUT);
if (val <= 0)
{
digitalWrite(pin, LOW);
}
else if (val >= 255)
{
digitalWrite(pin, HIGH);
}
else
{
#if CORE_PWM_COUNT >= 1
if ( pin == CORE_PWM0_PIN )
{
Pwm0_SetCompareOutputMode( Pwm0_Clear );
Pwm0_SetOutputCompareMatch( val );
}
else
#endif
#if CORE_PWM_COUNT >= 2
if ( pin == CORE_PWM1_PIN )
{
Pwm1_SetCompareOutputMode( Pwm1_Clear );
Pwm1_SetOutputCompareMatch( val );
}
else
#endif
#if CORE_PWM_COUNT >= 3
if ( pin == CORE_PWM2_PIN )
{
Pwm2_SetCompareOutputMode( Pwm2_Clear );
Pwm2_SetOutputCompareMatch( val );
}
else
#endif
#if CORE_PWM_COUNT >= 4
if ( pin == CORE_PWM3_PIN )
{
Pwm3_SetCompareOutputMode( Pwm3_Clear );
Pwm3_SetOutputCompareMatch( val );
}
else
#endif
#if CORE_PWM_COUNT >= 5
#error Only 4 PWM pins are supported. Add more conditions.
#endif
{
if (val < 128)
{
digitalWrite(pin, LOW);
}
else
{
digitalWrite(pin, HIGH);
}
}
}
}

View File

@@ -0,0 +1,148 @@
/*
wiring_digital.c - digital input and output functions
Part of Arduino - http://www.arduino.cc/
Copyright (c) 2005-2006 David A. Mellis
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
$Id: wiring.c 248 2007-02-03 15:36:30Z mellis $
Modified 28-08-2009 for attiny84 R.Wiersma
Modified 14-10-2009 for attiny45 Saposoft
*/
#include "wiring_private.h"
#include "pins_arduino.h"
#include "core_pins.h"
#include "core_timers.h"
#include "PwmTimer.h"
void pinMode(uint8_t pin, uint8_t mode)
{
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
volatile uint8_t *reg;
if (port == NOT_A_PIN) return;
// JWS: can I let the optimizer do this?
reg = portModeRegister(port);
if (mode == INPUT) {
uint8_t oldSREG = SREG;
cli();
*reg &= ~bit;
SREG = oldSREG;
} else {
uint8_t oldSREG = SREG;
cli();
*reg |= bit;
SREG = oldSREG;
}
}
// Forcing this inline keeps the callers from having to push their own stuff
// on the stack. It is a good performance win and only takes 1 more byte per
// user than calling. (It will take more bytes on the 168.)
//
// But shouldn't this be moved into pinMode? Seems silly to check and do on
// each digitalread or write.
//
__attribute__((always_inline)) static inline void turnOffPWM( uint8_t pin )
{
#if CORE_PWM_COUNT >= 1
if ( pin == CORE_PWM0_PIN )
{
Pwm0_SetCompareOutputMode( Pwm0_Disconnected );
}
else
#endif
#if CORE_PWM_COUNT >= 2
if ( pin == CORE_PWM1_PIN )
{
Pwm1_SetCompareOutputMode( Pwm1_Disconnected );
}
else
#endif
#if CORE_PWM_COUNT >= 3
if ( pin == CORE_PWM2_PIN )
{
Pwm2_SetCompareOutputMode( Pwm2_Disconnected );
}
else
#endif
#if CORE_PWM_COUNT >= 4
if ( pin == CORE_PWM3_PIN )
{
Pwm3_SetCompareOutputMode( Pwm3_Disconnected );
}
else
#endif
#if CORE_PWM_COUNT >= 5
#error Only 4 PWM pins are supported. Add more conditions.
#endif
{
}
}
void digitalWrite(uint8_t pin, uint8_t val)
{
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
volatile uint8_t *out;
if (port == NOT_A_PIN) return;
// If the pin that support PWM output, we need to turn it off
// before doing a digital write.
turnOffPWM( pin );
out = portOutputRegister(port);
if (val == LOW) {
uint8_t oldSREG = SREG;
cli();
*out &= ~bit;
SREG = oldSREG;
} else {
uint8_t oldSREG = SREG;
cli();
*out |= bit;
SREG = oldSREG;
}
}
int digitalRead(uint8_t pin)
{
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
if (port == NOT_A_PIN) return LOW;
// If the pin that support PWM output, we need to turn it off
// before getting a digital reading.
turnOffPWM( pin );
if (*portInputRegister(port) & bit) return HIGH;
return LOW;
}

View File

@@ -0,0 +1,179 @@
/*
wiring_private.h - Internal header file.
Part of Arduino - http://www.arduino.cc/
Copyright (c) 2005-2006 David A. Mellis
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
$Id: wiring.h 239 2007-01-12 17:58:39Z mellis $
Modified 28-08-2009 for attiny84 R.Wiersma
*/
#ifndef WiringPrivate_h
#define WiringPrivate_h
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/delay.h>
#include <stdio.h>
#include <stdarg.h>
#include "wiring.h"
#ifdef __cplusplus
extern "C"{
#endif
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
#if defined( EXT_INT0_vect )
#define EXTERNAL_INTERRUPT_0_vect EXT_INT0_vect
#elif defined( INT0_vect )
#define EXTERNAL_INTERRUPT_0_vect INT0_vect
#endif
#if defined( EXT_INT1_vect )
#define EXTERNAL_INTERRUPT_1_vect EXT_INT1_vect
#elif defined( INT1_vect )
#define EXTERNAL_INTERRUPT_1_vect INT1_vect
#endif
#if defined( EXT_INT2_vect )
#define EXTERNAL_INTERRUPT_2_vect EXT_INT2_vect
#elif defined( INT2_vect )
#define EXTERNAL_INTERRUPT_2_vect INT2_vect
#endif
#if defined( EXT_INT3_vect )
#define EXTERNAL_INTERRUPT_3_vect EXT_INT3_vect
#elif defined( INT3_vect )
#define EXTERNAL_INTERRUPT_3_vect INT3_vect
#endif
#if defined( EXT_INT4_vect )
#define EXTERNAL_INTERRUPT_4_vect EXT_INT4_vect
#elif defined( INT4_vect )
#define EXTERNAL_INTERRUPT_4_vect INT4_vect
#endif
#if defined( EXT_INT5_vect )
#define EXTERNAL_INTERRUPT_5_vect EXT_INT5_vect
#elif defined( INT5_vect )
#define EXTERNAL_INTERRUPT_5_vect INT5_vect
#endif
#if defined( EXT_INT6_vect )
#define EXTERNAL_INTERRUPT_6_vect EXT_INT6_vect
#elif defined( INT6_vect )
#define EXTERNAL_INTERRUPT_6_vect INT6_vect
#endif
#if defined( EXT_INT7_vect )
#define EXTERNAL_INTERRUPT_7_vect EXT_INT7_vect
#elif defined( INT7_vect )
#define EXTERNAL_INTERRUPT_7_vect INT7_vect
#endif
#if defined( EXT_INT8_vect )
#define EXTERNAL_INTERRUPT_8_vect EXT_INT8_vect
#elif defined( INT8_vect )
#define EXTERNAL_INTERRUPT_8_vect INT8_vect
#endif
#if defined( EXT_INT9_vect )
#define EXTERNAL_INTERRUPT_9_vect EXT_INT9_vect
#elif defined( INT9_vect )
#define EXTERNAL_INTERRUPT_9_vect INT9_vect
#endif
#if defined( EXTERNAL_INTERRUPT_9_vect )
#define NUMBER_EXTERNAL_INTERRUPTS (10)
#elif defined( EXTERNAL_INTERRUPT_8_vect )
#define NUMBER_EXTERNAL_INTERRUPTS (9)
#elif defined( EXTERNAL_INTERRUPT_7_vect )
#define NUMBER_EXTERNAL_INTERRUPTS (8)
#elif defined( EXTERNAL_INTERRUPT_6_vect )
#define NUMBER_EXTERNAL_INTERRUPTS (7)
#elif defined( EXTERNAL_INTERRUPT_5_vect )
#define NUMBER_EXTERNAL_INTERRUPTS (6)
#elif defined( EXTERNAL_INTERRUPT_4_vect )
#define NUMBER_EXTERNAL_INTERRUPTS (5)
#elif defined( EXTERNAL_INTERRUPT_3_vect )
#define NUMBER_EXTERNAL_INTERRUPTS (4)
#elif defined( EXTERNAL_INTERRUPT_2_vect )
#define NUMBER_EXTERNAL_INTERRUPTS (3)
#elif defined( EXTERNAL_INTERRUPT_1_vect )
#define NUMBER_EXTERNAL_INTERRUPTS (2)
#elif defined( EXTERNAL_INTERRUPT_0_vect )
#define NUMBER_EXTERNAL_INTERRUPTS (1)
#else
#define NUMBER_EXTERNAL_INTERRUPTS (0)
#endif
#if NUMBER_EXTERNAL_INTERRUPTS >= 1
#define EXTERNAL_INTERRUPT_0 (0)
#endif
#if NUMBER_EXTERNAL_INTERRUPTS >= 2
#define EXTERNAL_INTERRUPT_1 (1)
#endif
#if NUMBER_EXTERNAL_INTERRUPTS >= 3
#define EXTERNAL_INTERRUPT_2 (2)
#endif
#if NUMBER_EXTERNAL_INTERRUPTS >= 4
#define EXTERNAL_INTERRUPT_3 (3)
#endif
#if NUMBER_EXTERNAL_INTERRUPTS >= 5
#define EXTERNAL_INTERRUPT_4 (4)
#endif
#if NUMBER_EXTERNAL_INTERRUPTS >= 6
#define EXTERNAL_INTERRUPT_5 (5)
#endif
#if NUMBER_EXTERNAL_INTERRUPTS >= 7
#define EXTERNAL_INTERRUPT_6 (6)
#endif
#if NUMBER_EXTERNAL_INTERRUPTS >= 8
#define EXTERNAL_INTERRUPT_7 (7)
#endif
#if NUMBER_EXTERNAL_INTERRUPTS >= 9
#define EXTERNAL_INTERRUPT_8 (8)
#endif
#if NUMBER_EXTERNAL_INTERRUPTS >= 10
#define EXTERNAL_INTERRUPT_9 (9)
#endif
typedef void (*voidFuncPtr)(void);
#ifdef __cplusplus
} // extern "C"
#endif
#endif

View File

@@ -0,0 +1,69 @@
/*
wiring_pulse.c - pulseIn() function
Part of Arduino - http://www.arduino.cc/
Copyright (c) 2005-2006 David A. Mellis
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
$Id: wiring.c 248 2007-02-03 15:36:30Z mellis $
*/
#include "wiring_private.h"
#include "pins_arduino.h"
/* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
* or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds
* to 3 minutes in length, but must be called at least a few dozen microseconds
* before the start of the pulse. */
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
{
// cache the port and bit of the pin in order to speed up the
// pulse width measuring loop and achieve finer resolution. calling
// digitalRead() instead yields much coarser resolution.
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
uint8_t stateMask = (state ? bit : 0);
unsigned long width = 0; // keep initialization out of time critical area
// convert the timeout from microseconds to a number of times through
// the initial loop; it takes 16 clock cycles per iteration.
unsigned long numloops = 0;
unsigned long maxloops = microsecondsToClockCycles(timeout) / 16;
// wait for any previous pulse to end
while ((*portInputRegister(port) & bit) == stateMask)
if (numloops++ == maxloops)
return 0;
// wait for the pulse to start
while ((*portInputRegister(port) & bit) != stateMask)
if (numloops++ == maxloops)
return 0;
// wait for the pulse to stop
while ((*portInputRegister(port) & bit) == stateMask) {
if (numloops++ == maxloops)
return 0;
width++;
}
// convert the reading to microseconds. The loop has been determined
// to be 20 clock cycles long and have about 16 clocks between the edge
// and the start of the loop. There will be some error introduced by
// the interrupt handlers.
return clockCyclesToMicroseconds(width * 21 + 16);
}

View File

@@ -0,0 +1,55 @@
/*
wiring_shift.c - shiftOut() function
Part of Arduino - http://www.arduino.cc/
Copyright (c) 2005-2006 David A. Mellis
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
$Id: wiring.c 248 2007-02-03 15:36:30Z mellis $
*/
#include "wiring_private.h"
uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder) {
uint8_t value = 0;
uint8_t i;
for (i = 0; i < 8; ++i) {
digitalWrite(clockPin, HIGH);
if (bitOrder == LSBFIRST)
value |= digitalRead(dataPin) << i;
else
value |= digitalRead(dataPin) << (7 - i);
digitalWrite(clockPin, LOW);
}
return value;
}
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val)
{
uint8_t i;
for (i = 0; i < 8; i++) {
if (bitOrder == LSBFIRST)
digitalWrite(dataPin, !!(val & (1 << i)));
else
digitalWrite(dataPin, !!(val & (1 << (7 - i))));
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
}
}