Browse Source

Initial commit, version 1.17-rc1

teensy4-core
PaulStoffregen 11 years ago
commit
5cecdee933
100 changed files with 39913 additions and 0 deletions
  1. +9
    -0
      README.md
  2. +2
    -0
      teensy/Arduino.h
  3. +29
    -0
      teensy/Client.h
  4. +195
    -0
      teensy/HardwareSerial.cpp
  5. +30
    -0
      teensy/HardwareSerial.h
  6. +57
    -0
      teensy/IPAddress.cpp
  7. +78
    -0
      teensy/IPAddress.h
  8. +484
    -0
      teensy/Print.cpp
  9. +167
    -0
      teensy/Print.h
  10. +40
    -0
      teensy/Printable.h
  11. +12
    -0
      teensy/Server.h
  12. +310
    -0
      teensy/Stream.cpp
  13. +60
    -0
      teensy/Stream.h
  14. +269
    -0
      teensy/Tone.cpp
  15. +91
    -0
      teensy/Udp.h
  16. +168
    -0
      teensy/WCharacter.h
  17. +1
    -0
      teensy/WConstants.h
  18. +132
    -0
      teensy/WInterrupts.c
  19. +60
    -0
      teensy/WMath.cpp
  20. +48
    -0
      teensy/WProgram.h
  21. +759
    -0
      teensy/WString.cpp
  22. +216
    -0
      teensy/WString.h
  23. +515
    -0
      teensy/binary.h
  24. +18
    -0
      teensy/core_id.h
  25. +1987
    -0
      teensy/core_pins.h
  26. +81
    -0
      teensy/elapsedMillis.h
  27. +66
    -0
      teensy/keylayouts.c
  28. +5173
    -0
      teensy/keylayouts.h
  29. +14
    -0
      teensy/main.cpp
  30. +1
    -0
      teensy/main.cxx
  31. +388
    -0
      teensy/malloc.c
  32. +18
    -0
      teensy/new.cpp
  33. +22
    -0
      teensy/new.h
  34. +147
    -0
      teensy/pins_arduino.h
  35. +1890
    -0
      teensy/pins_teensy.c
  36. +15
    -0
      teensy/usb.c
  37. +15
    -0
      teensy/usb_api.cpp
  38. +15
    -0
      teensy/usb_api.h
  39. +153
    -0
      teensy/usb_common.h
  40. +15
    -0
      teensy/usb_private.h
  41. +80
    -0
      teensy/wiring.c
  42. +112
    -0
      teensy/wiring.h
  43. +72
    -0
      teensy/wiring_private.h
  44. +2
    -0
      teensy3/Arduino.h
  45. +213
    -0
      teensy3/AudioStream.cpp
  46. +147
    -0
      teensy3/AudioStream.h
  47. +29
    -0
      teensy3/Client.h
  48. +158
    -0
      teensy3/HardwareSerial.h
  49. +4
    -0
      teensy3/HardwareSerial1.cpp
  50. +4
    -0
      teensy3/HardwareSerial2.cpp
  51. +4
    -0
      teensy3/HardwareSerial3.cpp
  52. +57
    -0
      teensy3/IPAddress.cpp
  53. +82
    -0
      teensy3/IPAddress.h
  54. +185
    -0
      teensy3/IntervalTimer.cpp
  55. +88
    -0
      teensy3/IntervalTimer.h
  56. +81
    -0
      teensy3/Makefile
  57. +157
    -0
      teensy3/Print.cpp
  58. +105
    -0
      teensy3/Print.h
  59. +55
    -0
      teensy3/Printable.h
  60. +12
    -0
      teensy3/Server.h
  61. +312
    -0
      teensy3/Stream.cpp
  62. +60
    -0
      teensy3/Stream.h
  63. +214
    -0
      teensy3/Tone.cpp
  64. +91
    -0
      teensy3/Udp.h
  65. +168
    -0
      teensy3/WCharacter.h
  66. +1
    -0
      teensy3/WConstants.h
  67. +50
    -0
      teensy3/WMath.cpp
  68. +59
    -0
      teensy3/WProgram.h
  69. +725
    -0
      teensy3/WString.cpp
  70. +216
    -0
      teensy3/WString.h
  71. +287
    -0
      teensy3/analog.c
  72. +38
    -0
      teensy3/arm_common_tables.h
  73. +7571
    -0
      teensy3/arm_math.h
  74. +9
    -0
      teensy3/avr/eeprom.h
  75. +0
    -0
      teensy3/avr/interrupt.h
  76. +1
    -0
      teensy3/avr/io.h
  77. +46
    -0
      teensy3/avr/pgmspace.h
  78. +34
    -0
      teensy3/avr_emulation.cpp
  79. +1150
    -0
      teensy3/avr_emulation.h
  80. +105
    -0
      teensy3/avr_functions.h
  81. +515
    -0
      teensy3/binary.h
  82. +1757
    -0
      teensy3/core_cm4.h
  83. +541
    -0
      teensy3/core_cm4_simd.h
  84. +374
    -0
      teensy3/core_cmInstr.h
  85. +3
    -0
      teensy3/core_id.h
  86. +815
    -0
      teensy3/core_pins.h
  87. +294
    -0
      teensy3/eeprom.c
  88. +81
    -0
      teensy3/elapsedMillis.h
  89. +96
    -0
      teensy3/keylayouts.c
  90. +5173
    -0
      teensy3/keylayouts.h
  91. +28
    -0
      teensy3/main.cpp
  92. +447
    -0
      teensy3/math_helper.c
  93. +63
    -0
      teensy3/math_helper.h
  94. +382
    -0
      teensy3/mk20dx128.c
  95. +1768
    -0
      teensy3/mk20dx128.h
  96. +109
    -0
      teensy3/mk20dx128.ld
  97. +85
    -0
      teensy3/nonstd.c
  98. +102
    -0
      teensy3/pins_arduino.h
  99. +746
    -0
      teensy3/pins_teensy.c
  100. +0
    -0
      teensy3/serial1.c

+ 9
- 0
README.md View File

@@ -0,0 +1,9 @@
Teensy 2.0 and 3.0 core libraries for Arduino.

The latest stable version of Teensy's core library is always available in the Teensyduino installer, at this page:

http://www.pjrc.com/teensy/td_download.html


This github repository contains work-in-progress code, which may not be stable. It is not recommended for use in actual projects.


+ 2
- 0
teensy/Arduino.h View File

@@ -0,0 +1,2 @@
#include "WProgram.h"
#include "pins_arduino.h"

+ 29
- 0
teensy/Client.h View File

@@ -0,0 +1,29 @@
#if ARDUINO >= 100

#ifndef client_h
#define client_h
#include "Print.h"
#include "Stream.h"
#include "IPAddress.h"

class Client : public Stream {

public:
virtual int connect(IPAddress ip, uint16_t port) =0;
virtual int connect(const char *host, uint16_t port) =0;
virtual size_t write(uint8_t) =0;
virtual size_t write(const uint8_t *buf, size_t size) =0;
virtual int available() = 0;
virtual int read() = 0;
virtual int read(uint8_t *buf, size_t size) = 0;
virtual int peek() = 0;
virtual void flush() = 0;
virtual void stop() = 0;
virtual uint8_t connected() = 0;
virtual operator bool() = 0;
protected:
uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); };
};

#endif
#endif

+ 195
- 0
teensy/HardwareSerial.cpp View File

@@ -0,0 +1,195 @@
/* UART (hardware serial) for Teensy & Teensy++
* http://www.pjrc.com/teensy/
* Copyright (c) 2008 PJRC.COM, LLC
*
* 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.
*/

#include <avr/io.h>
#include <avr/interrupt.h>
#include "core_pins.h"
#include "HardwareSerial.h"

#define RX_BUFFER_SIZE 64
static volatile uint8_t rx_buffer[RX_BUFFER_SIZE];
static volatile uint8_t rx_buffer_head = 0;
static volatile uint8_t rx_buffer_tail = 0;

#define TX_BUFFER_SIZE 40
static volatile uint8_t tx_buffer[TX_BUFFER_SIZE];
static volatile uint8_t tx_buffer_head = 0;
static volatile uint8_t tx_buffer_tail = 0;
static volatile uint8_t transmitting = 0;
static volatile uint8_t tx_enable_pin = 255;

// Public Methods //////////////////////////////////////////////////////////////

void HardwareSerial::_begin(uint16_t baud_count, uint8_t txen_pin)
{
tx_enable_pin = txen_pin;
if (txen_pin < 255) {
pinMode(txen_pin, OUTPUT);
digitalWrite(txen_pin, LOW);
}
if ((baud_count & 1) && baud_count <= 4096) {
UCSR1A = (1<<U2X1);
UBRR1 = baud_count - 1;
} else {
UCSR1A = 0;
UBRR1 = (baud_count >> 1) - 1;
}
if (!(UCSR1B & (1<<TXEN1))) {
rx_buffer_head = 0;
rx_buffer_tail = 0;
tx_buffer_head = 0;
tx_buffer_tail = 0;
transmitting = 0;
UCSR1C = (1<<UCSZ11) | (1<<UCSZ10);
UCSR1B = (1<<RXEN1) | (1<<TXCIE1) | (1<<TXEN1) | (1<<RXCIE1);
}
}

void HardwareSerial::end(void)
{
while (transmitting) ; // wait for buffered data to send
UCSR1B = 0;
rx_buffer_head = 0;
rx_buffer_tail = 0;
}

int HardwareSerial::available(void)
{
uint8_t head, tail;

head = rx_buffer_head;
tail = rx_buffer_tail;
if (head >= tail) return head - tail;
return RX_BUFFER_SIZE + head - tail;
}

int HardwareSerial::peek(void)
{
uint8_t head, tail;

head = rx_buffer_head;
tail = rx_buffer_tail;
if (head == tail) return -1;
if (++tail >= RX_BUFFER_SIZE) tail = 0;
return rx_buffer[tail];
}

int HardwareSerial::read(void)
{
uint8_t c, i;

if (rx_buffer_head == rx_buffer_tail) return -1;
i = rx_buffer_tail + 1;
if (i >= RX_BUFFER_SIZE) i = 0;
c = rx_buffer[i];
rx_buffer_tail = i;
return c;
}

void HardwareSerial::flush()
{
#if ARDUINO >= 100
while (transmitting) ; // wait for buffered data to send
#else
rx_buffer_head = rx_buffer_tail;
#endif
}

void HardwareSerial::clear()
{
rx_buffer_head = rx_buffer_tail;
}

#if ARDUINO >= 100
size_t HardwareSerial::write(uint8_t c)
#else
void HardwareSerial::write(uint8_t c)
#endif
{
uint8_t i;

if (!(UCSR1B & (1<<TXEN1))) {
#if ARDUINO >= 100
setWriteError();
return 0;
#else
return;
#endif
}
if (tx_enable_pin < 255 && !transmitting) {
digitalWrite(tx_enable_pin, HIGH);
}
i = tx_buffer_head + 1;
if (i >= TX_BUFFER_SIZE) i = 0;
while (tx_buffer_tail == i) ; // wait until space in buffer
tx_buffer[i] = c;
transmitting = 1;
tx_buffer_head = i;
UCSR1B = (1<<RXEN1) | (1<<TXCIE1) | (1<<TXEN1) | (1<<RXCIE1) | (1<<UDRIE1);
#if ARDUINO >= 100
return 1;
#endif
}

ISR(USART1_RX_vect)
{
uint8_t c, i;

c = UDR1;
i = rx_buffer_head + 1;
if (i >= RX_BUFFER_SIZE) i = 0;
if (i != rx_buffer_tail) {
rx_buffer[i] = c;
rx_buffer_head = i;
}
}

ISR(USART1_UDRE_vect)
{
uint8_t i;

if (tx_buffer_head == tx_buffer_tail) {
// buffer is empty, disable transmit interrupt
UCSR1B = (1<<RXEN1) | (1<<TXCIE1) | (1<<TXEN1) | (1<<RXCIE1);
} else {
i = tx_buffer_tail + 1;
if (i >= TX_BUFFER_SIZE) i = 0;
UDR1 = tx_buffer[i];
tx_buffer_tail = i;
}
}

ISR(USART1_TX_vect)
{
transmitting = 0;
if (tx_enable_pin < 255) {
digitalWrite(tx_enable_pin, LOW);
}
}

// Preinstantiate Objects //////////////////////////////////////////////////////

HardwareSerial Serial1;




+ 30
- 0
teensy/HardwareSerial.h View File

@@ -0,0 +1,30 @@
#ifndef HardwareSerial_h
#define HardwareSerial_h

#include <inttypes.h>
#include "Stream.h"

class HardwareSerial : public Stream
{
public:
inline void begin(uint32_t baud, uint8_t txen_pin=255) {
_begin(((F_CPU / 8) + (baud / 2)) / baud, txen_pin);
}
void _begin(uint16_t baud_count, uint8_t pin);
void end(void);
virtual int available(void);
virtual int peek(void);
virtual int read(void);
virtual void flush(void);
void clear(void);
#if ARDUINO >= 100
virtual size_t write(uint8_t);
#else
virtual void write(uint8_t);
#endif
using Print::write;
};

extern HardwareSerial Serial1;

#endif

+ 57
- 0
teensy/IPAddress.cpp View File

@@ -0,0 +1,57 @@
#if ARDUINO >= 100
#include "Arduino.h"
#include "IPAddress.h"

IPAddress::IPAddress()
{
memset(_address, 0, sizeof(_address));
}

IPAddress::IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet)
{
_address[0] = first_octet;
_address[1] = second_octet;
_address[2] = third_octet;
_address[3] = fourth_octet;
}

IPAddress::IPAddress(uint32_t address)
{
memcpy(_address, &address, sizeof(_address));
}

IPAddress::IPAddress(const uint8_t *address)
{
memcpy(_address, address, sizeof(_address));
}

IPAddress& IPAddress::operator=(const uint8_t *address)
{
memcpy(_address, address, sizeof(_address));
return *this;
}

IPAddress& IPAddress::operator=(uint32_t address)
{
memcpy(_address, (const uint8_t *)&address, sizeof(_address));
return *this;
}

bool IPAddress::operator==(const uint8_t* addr)
{
return memcmp(addr, _address, sizeof(_address)) == 0;
}

size_t IPAddress::printTo(Print& p) const
{
size_t n = 0;
for (int i =0; i < 3; i++)
{
n += p.print(_address[i], DEC);
n += p.print('.');
}
n += p.print(_address[3], DEC);
return n;
}

#endif

+ 78
- 0
teensy/IPAddress.h View File

@@ -0,0 +1,78 @@
/*
*
* MIT License:
* Copyright (c) 2011 Adrian McEwen
* 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.
*
* adrianm@mcqn.com 1/1/2011
*/

#if ARDUINO >= 100
#ifndef IPAddress_h
#define IPAddress_h

#include <Printable.h>

// A class to make it easier to handle and pass around IP addresses

class IPAddress : public Printable {
private:
uint8_t _address[4]; // IPv4 address
// Access the raw byte array containing the address. Because this returns a pointer
// to the internal structure rather than a copy of the address this function should only
// be used when you know that the usage of the returned uint8_t* will be transient and not
// stored.
uint8_t* raw_address() { return _address; };

public:
// Constructors
IPAddress();
IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet);
IPAddress(uint32_t address);
IPAddress(const uint8_t *address);

// Overloaded cast operator to allow IPAddress objects to be used where a pointer
// to a four-byte uint8_t array is expected
operator uint32_t() { return *((uint32_t*)_address); };
bool operator==(const IPAddress& addr) { return (*((uint32_t*)_address)) == (*((uint32_t*)addr._address)); };
bool operator==(const uint8_t* addr);

// Overloaded index operator to allow getting and setting individual octets of the address
uint8_t operator[](int index) const { return _address[index]; };
uint8_t& operator[](int index) { return _address[index]; };

// Overloaded copy operators to allow initialisation of IPAddress objects from other types
IPAddress& operator=(const uint8_t *address);
IPAddress& operator=(uint32_t address);

virtual size_t printTo(Print& p) const;

friend class EthernetClass;
friend class UDP;
friend class Client;
friend class Server;
friend class DhcpClass;
friend class DNSClient;
};

const IPAddress INADDR_NONE(0,0,0,0);


#endif
#endif

+ 484
- 0
teensy/Print.cpp View File

@@ -0,0 +1,484 @@
/*
Print.cpp - Base class that provides print() and println()
Copyright (c) 2008 David A. Mellis. All right reserved.
many modifications, by Paul Stoffregen <paul@pjrc.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Modified 23 November 2006 by David A. Mellis
*/

#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <math.h>
#include <avr/pgmspace.h>
#include "wiring.h"

#include "Print.h"


#if ARDUINO >= 100
#else
void Print::write(const char *str)
{
write((const uint8_t *)str, strlen(str));
}
#endif


#if ARDUINO >= 100
size_t Print::write(const uint8_t *buffer, size_t size)
{
size_t count = 0;
while (size--) count += write(*buffer++);
return count;
}
#else
void Print::write(const uint8_t *buffer, size_t size)
{
while (size--) write(*buffer++);
}
#endif


#if ARDUINO >= 100
size_t Print::print(const String &s)
{
uint8_t buffer[33];
size_t count = 0;
unsigned int index = 0;
unsigned int len = s.length();
while (len > 0) {
s.getBytes(buffer, sizeof(buffer), index);
unsigned int nbytes = len;
if (nbytes > sizeof(buffer)-1) nbytes = sizeof(buffer)-1;
index += nbytes;
len -= nbytes;
count += write(buffer, nbytes);
}
return count;
}
#else
void Print::print(const String &s)
{
unsigned int len = s.length();
for (unsigned int i=0; i < len; i++) {
write(s[i]);
}
}
#endif


#if ARDUINO >= 100
size_t Print::print(const __FlashStringHelper *ifsh)
{
uint8_t buffer[32];
size_t count = 0;
const char PROGMEM *p = (const char PROGMEM *)ifsh;
unsigned int len = strlen_P(p);
while (len > 0) {
unsigned int nbytes = len;
if (nbytes > sizeof(buffer)) nbytes = sizeof(buffer);
memcpy_P(buffer, p, nbytes);
p += nbytes;
len -= nbytes;
count += write(buffer, nbytes);
}
return count;
}
#else
void Print::print(const __FlashStringHelper *ifsh)
{
const char PROGMEM *p = (const char PROGMEM *)ifsh;
while (1) {
unsigned char c = pgm_read_byte(p++);
if (c == 0) return;
write(c);
}
}
#endif


#if ARDUINO >= 100
size_t Print::print(long n)
{
uint8_t sign=0;

if (n < 0) {
sign = 1;
n = -n;
}
return printNumber(n, sign, 10);
}
#else
void Print::print(long n)
{
uint8_t sign=0;

if (n < 0) {
sign = 1;
n = -n;
}
printNumber(n, sign, 10);
}
#endif


#if ARDUINO >= 100
size_t Print::println(void)
{
uint8_t buf[2]={'\r', '\n'};
return write(buf, 2);
}
#else
void Print::println(void)
{
uint8_t buf[2]={'\r', '\n'};
write(buf, 2);
}
#endif


//#define USE_HACKER_DELIGHT_OPTIMIZATION
#define USE_STIMMER_OPTIMIZATION
//#define USE_BENCHMARK_CODE


#ifdef USE_HACKER_DELIGHT_OPTIMIZATION
// Adapted from Hacker's Delight (Henry Warren, ISBN 0321842685) www.hackersdelight.org
// by Rob Tillaart, Tom Carpenter, "genom2" with input from others...
// http://forum.arduino.cc/index.php?topic=167414.0
//
#define divmod10_asm(in32, tmp32, mod8) \
asm volatile ( \
"mov %2, %A0 \n\t" /* mod = in */ \
"ori %A0, 1 \n\t" /* q = in | 1 */ \
"movw %A1, %A0 \n\t" /* x = q */ \
"movw %C1, %C0 \n\t" \
"lsr %D1 \n\t" /* x = x >> 2 */ \
"ror %C1 \n\t" \
"ror %B1 \n\t" \
"ror %A1 \n\t" \
"lsr %D1 \n\t" \
"ror %C1 \n\t" \
"ror %B1 \n\t" \
"ror %A1 \n\t" \
"sub %A0, %A1 \n\t" /* q = q - x */ \
"sbc %B0, %B1 \n\t" \
"sbc %C0, %C1 \n\t" \
"sbc %D0, %D1 \n\t" \
"movw %A1, %A0 \n\t" /* x = q */ \
"movw %C1, %C0 \n\t" \
"lsr %D1 \n\t" /* x = x >> 4 */ \
"ror %C1 \n\t" \
"ror %B1 \n\t" \
"ror %A1 \n\t" \
"lsr %D1 \n\t" \
"ror %C1 \n\t" \
"ror %B1 \n\t" \
"ror %A1 \n\t" \
"lsr %D1 \n\t" \
"ror %C1 \n\t" \
"ror %B1 \n\t" \
"ror %A1 \n\t" \
"lsr %D1 \n\t" \
"ror %C1 \n\t" \
"ror %B1 \n\t" \
"ror %A1 \n\t" \
"add %A1, %A0 \n\t" /* x = x + q */ \
"adc %B1, %B0 \n\t" \
"adc %C1, %C0 \n\t" \
"adc %D1, %D0 \n\t" \
"movw %A0, %A1 \n\t" /* q = x */ \
"movw %C0, %C1 \n\t" \
"add %A0, %B1 \n\t" /* q = q + (x >> 8) */ \
"adc %B0, %C1 \n\t" \
"adc %C0, %D1 \n\t" \
"adc %D0, r1 \n\t" \
"mov %A0, %B0 \n\t" /* q = q >> 8 */ \
"mov %B0, %C0 \n\t" \
"mov %C0, %D0 \n\t" \
"eor %D0, %D0 \n\t" \
"add %A0, %A1 \n\t" /* q = q + x */ \
"adc %B0, %B1 \n\t" \
"adc %C0, %C1 \n\t" \
"adc %D0, %D1 \n\t" \
"mov %A0, %B0 \n\t" /* q = q >> 8 */ \
"mov %B0, %C0 \n\t" \
"mov %C0, %D0 \n\t" \
"eor %D0, %D0 \n\t" \
"add %A0, %A1 \n\t" /* q = q + x */ \
"adc %B0, %B1 \n\t" \
"adc %C0, %C1 \n\t" \
"adc %D0, %D1 \n\t" \
"mov %A0, %B0 \n\t" /* q = q >> 8 */ \
"mov %B0, %C0 \n\t" \
"mov %C0, %D0 \n\t" \
"eor %D0, %D0 \n\t" \
"add %A0, %A1 \n\t" /* q = q + x */ \
"adc %B0, %B1 \n\t" \
"adc %C0, %C1 \n\t" \
"adc %D0, %D1 \n\t" \
"andi %A0, 0xF8 \n\t" /* q = q & ~0x7 */ \
"sub %2, %A0 \n\t" /* mod = mod - q */ \
"lsr %D0 \n\t" /* q = q >> 2 */ \
"ror %C0 \n\t" \
"ror %B0 \n\t" \
"ror %A0 \n\t" \
"lsr %D0 \n\t" \
"ror %C0 \n\t" \
"ror %B0 \n\t" \
"ror %A0 \n\t" \
"sub %2, %A0 \n\t" /* mod = mod - q */ \
"lsr %D0 \n\t" /* q = q >> 1 */ \
"ror %C0 \n\t" \
"ror %B0 \n\t" \
"ror %A0 \n\t" \
: "+d" (in32), "=r" (tmp32), "=r" (mod8) : : "r0" \
)
#endif // USE_HACKER_DELIGHT_OPTIMIZATION

#ifdef USE_STIMMER_OPTIMIZATION
// http://forum.arduino.cc/index.php?topic=167414.msg1293679#msg1293679
// http://forum.arduino.cc/index.php?topic=167414.msg1309482#msg1309482
// equivelant code:
// mod8 = in32 % 10;
// in32 = in32 / 10;
// tmp8 = 10;
#define divmod10_asm(in32, mod8, tmp8) \
asm volatile ( \
" ldi %2,51 \n\t" \
" mul %A0,%2 \n\t" \
" clr %A0 \n\t" \
" add r0,%2 \n\t" \
" adc %A0,r1 \n\t" \
" mov %1,r0 \n\t" \
" mul %B0,%2 \n\t" \
" clr %B0 \n\t" \
" add %A0,r0 \n\t" \
" adc %B0,r1 \n\t" \
" mul %C0,%2 \n\t" \
" clr %C0 \n\t" \
" add %B0,r0 \n\t" \
" adc %C0,r1 \n\t" \
" mul %D0,%2 \n\t" \
" clr %D0 \n\t" \
" add %C0,r0 \n\t" \
" adc %D0,r1 \n\t" \
" clr r1 \n\t" \
" add %1,%A0 \n\t" \
" adc %A0,%B0 \n\t" \
" adc %B0,%C0 \n\t" \
" adc %C0,%D0 \n\t" \
" adc %D0,r1 \n\t" \
" add %1,%B0 \n\t" \
" adc %A0,%C0 \n\t" \
" adc %B0,%D0 \n\t" \
" adc %C0,r1 \n\t" \
" adc %D0,r1 \n\t" \
" add %1,%D0 \n\t" \
" adc %A0,r1 \n\t" \
" adc %B0,r1 \n\t" \
" adc %C0,r1 \n\t" \
" adc %D0,r1 \n\t" \
" lsr %D0 \n\t" \
" ror %C0 \n\t" \
" ror %B0 \n\t" \
" ror %A0 \n\t" \
" ror %1 \n\t" \
" ldi %2,10 \n\t" \
" mul %1,%2 \n\t" \
" mov %1,r1 \n\t" \
" clr r1 \n\t" \
:"+r"(in32),"=d"(mod8),"=d"(tmp8) : : "r0")
#endif // USE_STIMMER_OPTIMIZATION



#ifdef USE_BENCHMARK_CODE
uint32_t usec_print = 0;
#endif


#if ARDUINO >= 100
size_t Print::printNumberDec(unsigned long n, uint8_t sign)
#else
void Print::printNumberDec(unsigned long n, uint8_t sign)
#endif
{
uint8_t digit, buf[11], *p;
#if defined(USE_HACKER_DELIGHT_OPTIMIZATION)
uint32_t tmp32;
#elif defined(USE_STIMMER_OPTIMIZATION)
uint8_t tmp8;
#endif

#ifdef USE_BENCHMARK_CODE
uint32_t usec = micros();
#endif
p = buf + (sizeof(buf)-1);
do {
#if defined(USE_HACKER_DELIGHT_OPTIMIZATION)
divmod10_asm(n, tmp32, digit);
#elif defined(USE_STIMMER_OPTIMIZATION)
divmod10_asm(n, digit, tmp8);
#else
tmp32 = n;
n = n / 10;
digit = tmp32 - n * 10;
#endif
*--p = digit + '0';
} while (n);
if (sign) *--p = '-';
#ifdef USE_BENCHMARK_CODE
usec_print += micros() - usec;
#endif
#if ARDUINO >= 100
return write(p, sizeof(buf)-1 - (p - buf));
#else
write(p, sizeof(buf)-1 - (p - buf));
#endif
}

#if ARDUINO >= 100
size_t Print::printNumberHex(unsigned long n)
#else
void Print::printNumberHex(unsigned long n)
#endif
{
uint8_t digit, buf[8], *p;

p = buf + (sizeof(buf)-1);
do {
digit = n & 15;
*--p = (digit < 10) ? '0' + digit : 'A' + digit - 10;
n >>= 4;
} while (n);
#if ARDUINO >= 100
return write(p, sizeof(buf)-1 - (p - buf));
#else
write(p, sizeof(buf)-1 - (p - buf));
#endif
}

#if ARDUINO >= 100
size_t Print::printNumberBin(unsigned long n)
#else
void Print::printNumberBin(unsigned long n)
#endif
{
uint8_t buf[32], *p;

p = buf + (sizeof(buf)-1);
do {
*--p = '0' + ((uint8_t)n & 1);
n >>= 1;
} while (n);
#if ARDUINO >= 100
return write(p, sizeof(buf)-1 - (p - buf));
#else
write(p, sizeof(buf)-1 - (p - buf));
#endif
}

#if ARDUINO >= 100
size_t Print::printNumberAny(unsigned long n, uint8_t base)
#else
void Print::printNumberAny(unsigned long n, uint8_t base)
#endif
{
uint8_t digit, buf[21], *p;
uint32_t tmp;
//uint32_t usec;

//usec = micros();
p = buf + (sizeof(buf)-1);
do {
tmp = n;
n = n / base;
digit = tmp - n * base;
*--p = (digit < 10) ? '0' + digit : 'A' + digit - 10;
} while (n);
//usec_print += micros() - usec;
#if ARDUINO >= 100
return write(p, sizeof(buf)-1 - (p - buf));
#else
write(p, sizeof(buf)-1 - (p - buf));
#endif
}




#if ARDUINO >= 100
size_t Print::printFloat(double number, uint8_t digits)
#else
void Print::printFloat(double number, uint8_t digits)
#endif
{
uint8_t sign=0;
#if ARDUINO >= 100
size_t count=0;
#endif

// Handle negative numbers
if (number < 0.0) {
sign = 1;
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 *= 0.1;
}
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;
#if ARDUINO >= 100
count += printNumber(int_part, sign, 10);
#else
printNumber(int_part, sign, 10);
#endif

// Print the decimal point, but only if there are digits beyond
if (digits > 0) {
uint8_t n, buf[8], count=1;
buf[0] = '.';

// Extract digits from the remainder one at a time
if (digits > sizeof(buf) - 1) digits = sizeof(buf) - 1;

while (digits-- > 0) {
remainder *= 10.0;
n = (uint8_t)(remainder);
buf[count++] = '0' + n;
remainder -= n;
}
#if ARDUINO >= 100
count += write(buf, count);
#else
write(buf, count);
#endif
}
#if ARDUINO >= 100
return count;
#endif
}



+ 167
- 0
teensy/Print.h View File

@@ -0,0 +1,167 @@
/*
Print.h - Base class that provides print() and println()
Copyright (c) 2008 David A. Mellis. All right reserved.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#ifndef Print_h
#define Print_h

#include <inttypes.h>
#include <stdio.h> // for size_t
#include "core_id.h"
#include "WString.h"
#include "Printable.h"

#define DEC 10
#define HEX 16
#define OCT 8
#define BIN 2
#define BYTE 0

class __FlashStringHelper;

#if ARDUINO >= 100
class Print
{
public:
Print() : write_error(0) {}
virtual size_t write(uint8_t b);
size_t write(const char *str) { return write((const uint8_t *)str, strlen(str)); }
virtual size_t write(const uint8_t *buffer, size_t size);
size_t print(const String &s);
size_t print(char c) { return write((uint8_t)c); }
size_t print(const char s[]) { return write(s); }
size_t print(const __FlashStringHelper *f);

size_t print(uint8_t b) { return printNumber(b, 0, 10); }
size_t print(int n) { return print((long)n); }
size_t print(unsigned int n) { return printNumber(n, 0, 10); }
size_t print(long n);
size_t print(unsigned long n) { return printNumber(n, 0, 10); }

size_t print(unsigned char n, int base) { return printNumber(n, 0, base); }
size_t print(int n, int base) { return (base == 10) ? print(n) : printNumber(n, 0, base); }
size_t print(unsigned int n, int base) { return printNumber(n, 0, base); }
size_t print(long n, int base) { return (base == 10) ? print(n) : printNumber(n, 0, base); }
size_t print(unsigned long n, int base) { return printNumber(n, 0, base); }

size_t print(double n, int digits = 2) { return printFloat(n, digits); }
size_t print(const Printable &obj) { return obj.printTo(*this); }
size_t println(void);
size_t println(const String &s) { return print(s) + println(); }
size_t println(char c) { return print(c) + println(); }
size_t println(const char s[]) { return print(s) + println(); }
size_t println(const __FlashStringHelper *f) { return print(f) + println(); }

size_t println(uint8_t b) { return print(b) + println(); }
size_t println(int n) { return print(n) + println(); }
size_t println(unsigned int n) { return print(n) + println(); }
size_t println(long n) { return print(n) + println(); }
size_t println(unsigned long n) { return print(n) + println(); }

size_t println(unsigned char n, int base) { return print(n, base) + println(); }
size_t println(int n, int base) { return print(n, base) + println(); }
size_t println(unsigned int n, int base) { return print(n, base) + println(); }
size_t println(long n, int base) { return print(n, base) + println(); }
size_t println(unsigned long n, int base) { return print(n, base) + println(); }

size_t println(double n, int digits = 2) { return print(n, digits) + println(); }
size_t println(const Printable &obj) { return obj.printTo(*this) + println(); }
int getWriteError() { return write_error; }
void clearWriteError() { setWriteError(0); }
protected:
void setWriteError(int err = 1) { write_error = err; }
private:
char write_error;
size_t printNumberDec(unsigned long n, uint8_t sign);
size_t printNumberHex(unsigned long n);
size_t printNumberBin(unsigned long n);
size_t printNumberAny(unsigned long n, uint8_t base);
inline size_t printNumber(unsigned long n, uint8_t sign, uint8_t base) __attribute__((always_inline)) {
// when "base" is a constant (pretty much always), the
// compiler optimizes this to a single function call.
if (base == 0) return write((uint8_t)n);
if (base == 10 || base < 2) return printNumberDec(n, sign);
//if (base == 10 || base < 2) return printNumberAny(n, 10); // testing only
if (base == 16) return printNumberHex(n);
if (base == 2) return printNumberBin(n);
return printNumberAny(n, base);
}
size_t printFloat(double n, uint8_t digits);
};

#else
class Print
{
public:
virtual void write(uint8_t);
virtual void write(const char *str);
virtual void write(const uint8_t *buffer, size_t size);
void print(const String &s);
void print(char c) { write((uint8_t)c); }
void print(const char s[]) { write(s); }
void print(const __FlashStringHelper *f);

void print(uint8_t b) { write(b); }
void print(int n) { print((long)n); }
void print(unsigned int n) { printNumber(n, 0, 10); }
void print(long n);
void print(unsigned long n) { printNumber(n, 0, 10); }

void print(unsigned char n, int base) { printNumber(n, 0, base); }
void print(int n, int base) { (base == 10) ? print(n) : printNumber(n, 0, base); }
void print(unsigned int n, int base) { printNumber(n, 0, base); }
void print(long n, int base) { (base == 10) ? print(n) : printNumber(n, 0, base); }
void print(unsigned long n, int base) { printNumber(n, 0, base); }

void print(double n, int digits = 2) { printFloat(n, digits); }
void println(void);
void println(const String &s) { print(s); println(); }
void println(char c) { print(c); println(); }
void println(const char s[]) { print(s); println(); }
void println(const __FlashStringHelper *f) { print(f); println(); }
void println(uint8_t b) { print(b); println(); }
void println(int n) { print(n); println(); }
void println(unsigned int n) { print(n); println(); }
void println(long n) { print(n); println(); }
void println(unsigned long n) { print(n); println(); }

void println(unsigned char n, int base) { print(n, base); println(); }
void println(int n, int base) { print(n, base); println(); }
void println(unsigned int n, int base) { print(n, base); println(); }
void println(long n, int base) { print(n, base); println(); }
void println(unsigned long n, int base) { print(n, base); println(); }

void println(double n, int digits = 2) { print(n, digits); println(); }
private:
void printNumberDec(unsigned long n, uint8_t sign);
void printNumberHex(unsigned long n);
void printNumberBin(unsigned long n);
void printNumberAny(unsigned long n, uint8_t base);
inline size_t printNumber(unsigned long n, uint8_t sign, uint8_t base) __attribute__((always_inline)) {
if (base == 0) { write((uint8_t)n); return; }
if (base == 10 || base < 2) { printNumberDec(n, sign); return; }
if (base == 16) { printNumberHex(n); return; }
if (base == 2) { printNumberBin(n); return; }
printNumberAny(n, base);
}
void printFloat(double n, uint8_t digits);
};
#endif


#endif

+ 40
- 0
teensy/Printable.h View File

@@ -0,0 +1,40 @@
/*
Printable.h - Interface class that allows printing of complex types
Copyright (c) 2011 Adrian McEwen. 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
*/

#if ARDUINO >= 100
#ifndef Printable_h
#define Printable_h

#include "new.h"

class Print;

/** The Printable class provides a way for new classes to allow themselves to be printed.
By deriving from Printable and implementing the printTo method, it will then be possible
for users to print out instances of this class by passing them into the usual
Print::print and Print::println methods.
*/
class Printable
{
public:
virtual size_t printTo(Print& p) const = 0;
};

#endif
#endif

+ 12
- 0
teensy/Server.h View File

@@ -0,0 +1,12 @@
#if ARDUINO >= 100

#ifndef server_h
#define server_h

class Server : public Print {
public:
virtual void begin() =0;
};

#endif
#endif

+ 310
- 0
teensy/Stream.cpp View File

@@ -0,0 +1,310 @@
/*
Stream.cpp - adds parsing methods to Stream class
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

Created July 2011
parsing functions based on TextFinder library by Michael Margolis
*/

#include "Arduino.h"
#include "Stream.h"

#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait
#define NO_SKIP_CHAR 1 // a magic char not found in a valid ASCII numeric field

// private method to read stream with timeout
int Stream::timedRead()
{
int c;
unsigned long startMillis = millis();
do {
c = read();
if (c >= 0) return c;
} while(millis() - startMillis < _timeout);
return -1; // -1 indicates timeout
}

// private method to peek stream with timeout
int Stream::timedPeek()
{
int c;
unsigned long startMillis = millis();
do {
c = peek();
if (c >= 0) return c;
} while(millis() - startMillis < _timeout);
return -1; // -1 indicates timeout
}

// returns peek of the next digit in the stream or -1 if timeout
// discards non-numeric characters
int Stream::peekNextDigit()
{
int c;
while (1) {
c = timedPeek();
if (c < 0) return c; // timeout
if (c == '-') return c;
if (c >= '0' && c <= '9') return c;
read(); // discard non-numeric
}
}

// Public Methods
//////////////////////////////////////////////////////////////

void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait
{
_timeout = timeout;
}

// find returns true if the target string is found
bool Stream::find(char *target)
{
return findUntil(target, NULL);
}

// reads data from the stream until the target string of given length is found
// returns true if target string is found, false if timed out
bool Stream::find(char *target, size_t length)
{
return findUntil(target, length, NULL, 0);
}

// as find but search ends if the terminator string is found
bool Stream::findUntil(char *target, char *terminator)
{
return findUntil(target, strlen(target), terminator, strlen(terminator));
}

// reads data from the stream until the target string of the given length is found
// search terminated if the terminator string is found
// returns true if target string is found, false if terminated or timed out
bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen)
{
size_t index = 0; // maximum target string length is 64k bytes!
size_t termIndex = 0;
int c;

if( *target == 0)
return true; // return true if target is a null string
while( (c = timedRead()) > 0){
if( c == target[index]){
//////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1);
if(++index >= targetLen){ // return true if all chars in the target match
return true;
}
}
else{
index = 0; // reset index if any char does not match
}
if(termLen > 0 && c == terminator[termIndex]){
if(++termIndex >= termLen)
return false; // return false if terminate string found before target string
}
else
termIndex = 0;
}
return false;
}


// returns the first valid (long) integer value from the current position.
// initial characters that are not digits (or the minus sign) are skipped
// function is terminated by the first character that is not a digit.
long Stream::parseInt()
{
return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout)
}

// as above but a given skipChar is ignored
// this allows format characters (typically commas) in values to be ignored
long Stream::parseInt(char skipChar)
{
boolean isNegative = false;
long value = 0;
int c;

c = peekNextDigit();
// ignore non numeric leading characters
if(c < 0)
return 0; // zero returned if timeout

do{
if(c == skipChar)
; // ignore this charactor
else if(c == '-')
isNegative = true;
else if(c >= '0' && c <= '9') // is c a digit?
value = value * 10 + c - '0';
read(); // consume the character we got with peek
c = timedPeek();
}
while( (c >= '0' && c <= '9') || c == skipChar );

if(isNegative)
value = -value;
return value;
}


// as parseInt but returns a floating point value
float Stream::parseFloat()
{
return parseFloat(NO_SKIP_CHAR);
}

// as above but the given skipChar is ignored
// this allows format characters (typically commas) in values to be ignored
float Stream::parseFloat(char skipChar){
boolean isNegative = false;
boolean isFraction = false;
long value = 0;
char c;
float fraction = 1.0;

c = peekNextDigit();
// ignore non numeric leading characters
if(c < 0)
return 0; // zero returned if timeout

do{
if(c == skipChar)
; // ignore
else if(c == '-')
isNegative = true;
else if (c == '.')
isFraction = true;
else if(c >= '0' && c <= '9') { // is c a digit?
value = value * 10 + c - '0';
if(isFraction)
fraction *= 0.1;
}
read(); // consume the character we got with peek
c = timedPeek();
}
while( (c >= '0' && c <= '9') || c == '.' || c == skipChar );

if(isNegative)
value = -value;
if(isFraction)
return value * fraction;
else
return value;
}

// read characters from stream into buffer
// terminates if length characters have been read, or timeout (see setTimeout)
// returns the number of characters placed in the buffer
// the buffer is NOT null terminated.
//
size_t Stream::readBytes(char *buffer, size_t length)
{
size_t count = 0;
while (count < length) {
int c = timedRead();
if (c < 0) {
setReadError();
break;
}
*buffer++ = (char)c;
count++;
}
return count;
}


// as readBytes with terminator character
// terminates if length characters have been read, timeout, or if the terminator character detected
// returns the number of characters placed in the buffer (0 means no valid data found)

size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length)
{
if (length < 1) return 0;
length--;
size_t index = 0;
while (index < length) {
int c = timedRead();
if (c == terminator) break;
if (c < 0) {
setReadError();
break;
}
*buffer++ = (char)c;
index++;
}
*buffer = 0;
return index; // return number of characters, not including null terminator
}

String Stream::readString(size_t max)
{
String str;
size_t length = str.length();
while (length < max) {
int c = timedRead();
if (c < 0) {
setReadError();
break; // timeout
}
if (c == 0) break;
str += (char)c;
}
return str;
}

String Stream::readStringUntil(char terminator, size_t max)
{
String str;
size_t length = str.length();
while (length < max) {
int c = timedRead();
if (c < 0) {
setReadError();
break; // timeout
}
if (c == 0 || c == terminator) break;
str += (char)c;
}
return str;
}



























+ 60
- 0
teensy/Stream.h View File

@@ -0,0 +1,60 @@
/*
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:
Stream() : _timeout(1000), read_error(0) {}
virtual int available() = 0;
virtual int read() = 0;
virtual int peek() = 0;
virtual void flush() = 0;

void setTimeout(unsigned long timeout);
bool find(char *target);
bool find(char *target, size_t length);
bool findUntil(char *target, char *terminator);
bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen);
long parseInt();
long parseInt(char skipChar);
float parseFloat();
float parseFloat(char skipChar);
size_t readBytes(char *buffer, size_t length);
size_t readBytesUntil(char terminator, char *buffer, size_t length);
String readString(size_t max = 120);
String readStringUntil(char terminator, size_t max = 120);
int getReadError() { return read_error; }
void clearReadError() { setReadError(0); }
protected:
void setReadError(int err = 1) { read_error = err; }
unsigned long _timeout;
private:
char read_error;
int timedRead();
int timedPeek();
int peekNextDigit();
};

#endif

+ 269
- 0
teensy/Tone.cpp View File

@@ -0,0 +1,269 @@
/* Tone generation for the Teensy and Teensy++
* http://www.pjrc.com/teensy/
* Copyright (c) 2010 PJRC.COM, LLC
*
* 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.
*/

#include <avr/interrupt.h>
#include "wiring.h"
#include "core_pins.h"
#include "pins_arduino.h"

static uint8_t timer_acquired = 0;

static uint8_t *tone1_reg = (uint8_t *)0;
static uint8_t tone1_mask = 0;
static uint16_t tone1_inc = 0;
static uint32_t tone1_count = 0;

static uint8_t *tone2_reg = (uint8_t *)0;
static uint8_t tone2_mask = 0;
static uint16_t tone2_inc = 0;
static uint32_t tone2_count = 0;

static uint8_t *tone3_reg = (uint8_t *)0;
static uint8_t tone3_mask = 0;
static uint16_t tone3_inc = 0;
static uint32_t tone3_count = 0;

#define MAX_FREQ (F_CPU / 16 / 25)
#define MIN_FREQ (F_CPU / 16 / 65535 + 1)



#define PIN_REG_AND_MASK_LOOKUP(pin, reg, mask) \
asm volatile( \
"lsl %2" "\n\t" \
"add %A3, %2" "\n\t" \
"adc %B3, __zero_reg__" "\n\n" \
"lpm %1, Z+" "\n\t" \
"lpm %A0, Z" "\n\t" \
"ldi %B0, 0" "\n" \
: "=z" (reg), "=r" (mask), "+r" (pin) \
: "z" (digital_pin_table_PGM), "2" (pin))

#if defined(__AVR_ATmega32U4__)
//#define TONE_USE_TIMER1
#define TONE_USE_TIMER3
#elif defined(__AVR_AT90USB1286__)
//#define TONE_USE_TIMER1
#define TONE_USE_TIMER3
#elif defined(__AVR_AT90USB162__)
#define TONE_USE_TIMER1
#elif defined(__AVR_AT90USB646__)
//#define TONE_USE_TIMER1
#define TONE_USE_TIMER3
#endif

#ifdef TONE_USE_TIMER3
#define TIMSKx TIMSK3
#define OCIExA OCIE3A
#define OCIExB OCIE3B
#define OCIExC OCIE3C
#define TCCRxA TCCR3A
#define WGMx0 WGM30
#define TCCRxB TCCR3B
#define CSx1 CS31
#define TCNTx TCNT3
#define OCRxA OCR3A
#define OCRxB OCR3B
#define OCRxC OCR3C
#define TIFRx TIFR3
#define OCFxA OCF3A
#define OCFxB OCF3B
#define OCFxC OCF3C
#define VECTxA TIMER3_COMPA_vect
#define VECTxB TIMER3_COMPB_vect
#define VECTxC TIMER3_COMPC_vect
#endif
#ifdef TONE_USE_TIMER1
#define TIMSKx TIMSK1
#define OCIExA OCIE1A
#define OCIExB OCIE1B
#define OCIExC OCIE1C
#define TCCRxA TCCR1A
#define WGMx0 WGM10
#define TCCRxB TCCR1B
#define CSx1 CS11
#define TCNTx TCNT1
#define OCRxA OCR1A
#define OCRxB OCR1B
#define OCRxC OCR1C
#define TIFRx TIFR1
#define OCFxA OCF1A
#define OCFxB OCF1B
#define OCFxC OCF1C
#define VECTxA TIMER1_COMPA_vect
#define VECTxB TIMER1_COMPB_vect
#define VECTxC TIMER1_COMPC_vect
#endif


void tone(uint8_t pin, uint16_t frequency, uint32_t duration)
{
uint8_t *reg;
uint8_t mask;
uint16_t inc;
uint32_t count;

if (pin >= CORE_NUM_TOTAL_PINS) return;
if (frequency < MIN_FREQ) {
frequency = MIN_FREQ;
} else if (frequency > MAX_FREQ) {
frequency = MAX_FREQ;
}
inc = (F_CPU / 16 + frequency / 2) / frequency;
if (duration) {
count = duration * frequency / 500;
} else {
count = 0;
}
if (!timer_acquired) {
TIMSKx = 0; // disable all interrupts
TCCRxA = 0;
TCCRxB = (1<<CSx1); // normal mode, div8 prescale
timer_acquired = 1;
}
PIN_REG_AND_MASK_LOOKUP(pin, reg, mask);

if (!tone1_mask || (tone1_mask == mask && tone1_reg == reg)) {
TIMSKx &= ~(1<<OCIExA); // disable compare interrupt
tone1_reg = reg;
tone1_mask = mask;
tone1_count = count;
tone1_inc = inc;
cli();
*(reg + 2) &= ~mask; // clear pin
*(reg + 1) |= mask; // output mode
OCRxA = TCNTx + inc;
TIFRx |= (1<<OCFxA); // clear any pending compare match
sei();
TIMSKx |= (1<<OCIExA); // enable compare interrupt
return;
}
if (!tone2_mask || (tone2_mask == mask && tone2_reg == reg)) {
TIMSKx &= ~(1<<OCIExB); // disable compare interrupt
tone2_reg = reg;
tone2_mask = mask;
tone2_count = count;
tone2_inc = inc;
cli();
*(reg + 2) &= ~mask; // clear pin
*(reg + 1) |= mask; // output mode
OCRxB = TCNTx + inc;
TIFRx |= (1<<OCFxB); // clear any pending compare match
sei();
TIMSKx |= (1<<OCIExB); // enable compare interrupt
return;
}
if (!tone3_mask || (tone3_mask == mask && tone3_reg == reg)) {
TIMSKx &= ~(1<<OCIExC); // disable compare interrupt
tone3_reg = reg;
tone3_mask = mask;
tone3_count = count;
tone3_inc = inc;
cli();
*(reg + 2) &= ~mask; // clear pin
*(reg + 1) |= mask; // output mode
OCRxC = TCNTx + inc;
TIFRx |= (1<<OCFxC); // clear any pending compare match
sei();
TIMSKx |= (1<<OCIExC); // enable compare interrupt
return;
}
}

void noTone(uint8_t pin)
{
uint8_t *reg;
uint8_t mask;

if (pin >= CORE_NUM_TOTAL_PINS) return;
PIN_REG_AND_MASK_LOOKUP(pin, reg, mask);

if (tone1_mask == mask && tone1_reg == reg) {
TIMSKx &= ~(1<<OCIExA);
tone1_mask = 0;
} else if (tone2_mask == mask && tone2_reg == reg) {
TIMSKx &= ~(1<<OCIExB);
tone2_mask = 0;
} else if (tone3_mask == mask && tone3_reg == reg) {
TIMSKx &= ~(1<<OCIExC);
tone3_mask = 0;
}
if (!tone1_mask && !tone2_mask && !tone3_mask) {
TCCRxA = (1<<WGMx0); // restore timer
timer_acquired = 0;
}
}


ISR(VECTxA)
{
OCRxA += tone1_inc;
*(tone1_reg) = tone1_mask;
if (tone1_count > 0) {
if ((--tone1_count) == 0) {
*(tone1_reg + 2) &= ~tone1_mask;
TIMSKx &= ~(1<<OCIExA);
tone1_mask = 0;
if (!tone2_mask && !tone3_mask) {
TCCRxA = (1<<WGMx0);
timer_acquired = 0;
}
}
}
}

ISR(VECTxB)
{
OCRxB += tone2_inc;
*(tone2_reg) = tone2_mask;
if (tone2_count > 0) {
if ((--tone2_count) == 0) {
*(tone2_reg + 2) &= ~tone2_mask;
TIMSKx &= ~(1<<OCIExB);
tone2_mask = 0;
if (!tone1_mask && !tone3_mask) {
TCCRxA = (1<<WGMx0);
timer_acquired = 0;
}
}
}
}

ISR(VECTxC)
{
OCRxC += tone3_inc;
*(tone3_reg) = tone3_mask;
if (tone3_count > 0) {
if ((--tone3_count) == 0) {
*(tone3_reg + 2) &= ~tone3_mask;
TIMSKx &= ~(1<<OCIExC);
tone3_mask = 0;
if (!tone1_mask && !tone2_mask) {
TCCRxA = (1<<WGMx0);
timer_acquired = 0;
}
}
}
}



+ 91
- 0
teensy/Udp.h View File

@@ -0,0 +1,91 @@
/*
* Udp.cpp: Library to send/receive UDP packets.
*
* NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these)
* 1) UDP does not guarantee the order in which assembled UDP packets are received. This
* might not happen often in practice, but in larger network topologies, a UDP
* packet can be received out of sequence.
* 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being
* aware of it. Again, this may not be a concern in practice on small local networks.
* For more information, see http://www.cafeaulait.org/course/week12/35.html
*
* MIT License:
* Copyright (c) 2008 Bjoern Hartmann
* 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.
*
* bjoern@cs.stanford.edu 12/30/2008
*/

#if ARDUINO >= 100

#ifndef udp_h
#define udp_h

#include <Stream.h>
#include <IPAddress.h>

class UDP : public Stream {

public:
virtual uint8_t begin(uint16_t) =0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
virtual void stop() =0; // Finish with the UDP socket

// Sending UDP packets
// Start building up a packet to send to the remote host specific in ip and port
// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
virtual int beginPacket(IPAddress ip, uint16_t port) =0;
// Start building up a packet to send to the remote host specific in host and port
// Returns 1 if successful, 0 if there was a problem resolving the hostname or port
virtual int beginPacket(const char *host, uint16_t port) =0;
// Finish off this packet and send it
// Returns 1 if the packet was sent successfully, 0 if there was an error
virtual int endPacket() =0;
// Write a single byte into the packet
virtual size_t write(uint8_t) =0;
// Write size bytes from buffer into the packet
virtual size_t write(const uint8_t *buffer, size_t size) =0;

// Start processing the next available incoming packet
// Returns the size of the packet in bytes, or 0 if no packets are available
virtual int parsePacket() =0;
// Number of bytes remaining in the current packet
virtual int available() =0;
// Read a single byte from the current packet
virtual int read() =0;
// Read up to len bytes from the current packet and place them into buffer
// Returns the number of bytes read, or 0 if none are available
virtual int read(unsigned char* buffer, size_t len) =0;
// Read up to len characters from the current packet and place them into buffer
// Returns the number of characters read, or 0 if none are available
virtual int read(char* buffer, size_t len) =0;
// Return the next byte from the current packet without moving on to the next byte
virtual int peek() =0;
virtual void flush() =0; // Finish reading the current packet

// Return the IP address of the host who sent the current incoming packet
virtual IPAddress remoteIP() =0;
// Return the port of the host who sent the current incoming packet
virtual uint16_t remotePort() =0;
protected:
uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); };
};

#endif
#endif

+ 168
- 0
teensy/WCharacter.h 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

+ 1
- 0
teensy/WConstants.h View File

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

+ 132
- 0
teensy/WInterrupts.c View File

@@ -0,0 +1,132 @@
/* Interrupt functions for the Teensy and Teensy++
* http://www.pjrc.com/teensy/
* Copyright (c) 2008-2010 PJRC.COM, LLC
*
* 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.
*/

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <stdint.h>

#include "wiring.h"
#include "wiring_private.h"

#if defined(__AVR_ATmega32U4__)
#define NUM_INTERRUPT 4
#else
#define NUM_INTERRUPT 8
#endif

volatile static voidFuncPtr intFunc[NUM_INTERRUPT];

static const uint8_t PROGMEM interrupt_mode_mask[] = {0xFC, 0xF3, 0xCF, 0x3F};

static uint8_t pin2int(uint8_t pin)
{
switch (pin) {
case CORE_INT0_PIN: return 0;
case CORE_INT1_PIN: return 1;
case CORE_INT2_PIN: return 2;
case CORE_INT3_PIN: return 3;
#if !defined(__AVR_ATmega32U4__)
case CORE_INT4_PIN: return 4;
case CORE_INT5_PIN: return 5;
case CORE_INT6_PIN: return 6;
case CORE_INT7_PIN: return 7;
#endif
default: return 255;
}
}

#if defined(__AVR_ATmega32U4__)
void attachInterrupt(uint8_t inum, void (*userFunc)(void), uint8_t mode)
{
uint8_t mask;

if (inum >= NUM_INTERRUPT) {
inum = pin2int(inum);
if (inum >= NUM_INTERRUPT) return;
}
intFunc[inum] = userFunc;
mask = pgm_read_byte(interrupt_mode_mask + inum);
mode &= 0x03;
EICRA = (EICRA & mask) | (mode << (inum * 2));
EIMSK |= (1 << inum);
}
#else
void attachInterrupt(uint8_t inum, void (*userFunc)(void), uint8_t mode)
{
uint8_t mask, index;

if (inum >= NUM_INTERRUPT) {
inum = pin2int(inum);
if (inum >= NUM_INTERRUPT) return;
}
intFunc[inum] = userFunc;
index = inum & 3;
mask = pgm_read_byte(interrupt_mode_mask + index);
mode &= 0x03;
if (inum & 4) {
EICRB = (EICRB & mask) | (mode << (index * 2));
} else {
EICRA = (EICRA & mask) | (mode << (index * 2));
}
EIMSK |= (1 << inum);
}
#endif

void detachInterrupt(uint8_t inum)
{
if (inum >= NUM_INTERRUPT) {
inum = pin2int(inum);
if (inum >= NUM_INTERRUPT) return;
}
EIMSK &= ~(1 << inum);
intFunc[inum] = 0;
}

SIGNAL(INT0_vect) {
if (intFunc[0]) intFunc[0](); // INT0 is pin 0 (PD0)
}
SIGNAL(INT1_vect) {
if (intFunc[1]) intFunc[1](); // INT1 is pin 1 (PD1)
}
SIGNAL(INT2_vect) {
if (intFunc[2]) intFunc[2](); // INT2 is pin 2 (PD2) (also Serial RX)
}
SIGNAL(INT3_vect) {
if (intFunc[3]) intFunc[3](); // INT3 is pin 3 (PD3) (also Serial TX)
}
#if !defined(__AVR_ATmega32U4__)
SIGNAL(INT4_vect) {
if (intFunc[4]) intFunc[4](); // INT4 is pin 20 (PC7)
}
SIGNAL(INT5_vect) {
if (intFunc[5]) intFunc[5](); // INT5 is pin 4 (PD4)
}
SIGNAL(INT6_vect) {
if (intFunc[6]) intFunc[6](); // INT6 is pin 6 (PD6)
}
SIGNAL(INT7_vect) {
if (intFunc[7]) intFunc[7](); // INT7 is pin 7 (PD7)
}
#endif


+ 60
- 0
teensy/WMath.cpp 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; }

+ 48
- 0
teensy/WProgram.h View File

@@ -0,0 +1,48 @@
#ifndef WProgram_h
#define WProgram_h

#include <stdlib.h>
#include <string.h>
#include <math.h>

#ifdef GCC_VERSION
#if (GCC_VERSION < 40300)
#warning "Your avr-gcc and avr-libc are too old, please upgrade"
#endif
#if (GCC_VERSION >= 40300) && (GCC_VERSION < 40302)
// gcc 4.3.0 fails to save context for some interrupt routines - very ugly
#warning "Buggy GCC 4.3.0 compiler, please upgrade!"
#endif
#endif

#include <avr/interrupt.h>
#include "wiring.h"

#ifdef __cplusplus
#include "usb_api.h"
#include "WCharacter.h"
#include "WString.h"
#include "HardwareSerial.h"
#include "elapsedMillis.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, uint16_t frequency, uint32_t duration = 0);
void noTone(uint8_t pin);

// WMath prototypes
long random(long);
long random(long, long);
void randomSeed(unsigned int);
long map(long, long, long, long, long);

#include "pins_arduino.h"

#endif // __cplusplus

#endif // WProgram_h

+ 759
- 0
teensy/WString.cpp View File

@@ -0,0 +1,759 @@
/*
WString.cpp - String library for Wiring & Arduino
...mostly rewritten by Paul Stoffregen...
Copyright (c) 2009-10 Hernando Barragan. All rights reserved.
Copyright 2011, Paul Stoffregen, paul@pjrc.com

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 "WString.h"


/*********************************************/
/* Constructors */
/*********************************************/

String::String(const char *cstr)
{
init();
if (cstr) copy(cstr, strlen(cstr));
}

String::String(const __FlashStringHelper *pgmstr)
{
init();
*this = pgmstr;
}

String::String(const String &value)
{
init();
*this = value;
}

#ifdef __GXX_EXPERIMENTAL_CXX0X__
String::String(String &&rval)
{
init();
move(rval);
}
String::String(StringSumHelper &&rval)
{
init();
move(rval);
}
#endif

String::String(char c)
{
init();
*this = c;
}

String::String(unsigned char c)
{
init();
*this = (char)c;
}

String::String(const int value, unsigned char base)
{
init();
char buf[18];
itoa(value, buf, base);
*this = buf;
}

String::String(unsigned int value, unsigned char base)
{
init();
char buf[17];
utoa(value, buf, base);
*this = buf;
}

String::String(long value, unsigned char base)
{
init();
char buf[34];
ltoa(value, buf, base);
*this = buf;
}

String::String(unsigned long value, unsigned char base)
{
init();
char buf[33];
ultoa(value, buf, base);
*this = buf;
}

String::String(float num, unsigned char digits)
{
init();
char buf[40];
*this = dtostrf(num, digits + 2, digits, buf);
}

String::String(double num, unsigned char digits)
{
init();
char buf[40];
*this = dtostrf(num, digits + 2, digits, buf);
}

String::~String()
{
free(buffer);
}

/*********************************************/
/* Memory Management */
/*********************************************/

inline void String::init(void)
{
buffer = NULL;
capacity = 0;
len = 0;
flags = 0;
}

unsigned char String::reserve(unsigned int size)
{
if (capacity >= size) return 1;
if (changeBuffer(size)) {
if (len == 0) buffer[0] = 0;
return 1;
}
return 0;
}

unsigned char String::changeBuffer(unsigned int maxStrLen)
{
char *newbuffer = (char *)realloc(buffer, maxStrLen + 1);
if (newbuffer) {
buffer = newbuffer;
capacity = maxStrLen;
return 1;
}
return 0;
}

/*********************************************/
/* Copy and Move */
/*********************************************/

String & String::copy(const char *cstr, unsigned int length)
{
if (length == 0) {
if (buffer) buffer[0] = 0;
len = 0;
return *this;
}
if (!reserve(length)) {
if (buffer) {
free(buffer);
buffer = NULL;
}
len = capacity = 0;
return *this;
}
len = length;
strcpy(buffer, cstr);
return *this;
}

String & String::copy(const __FlashStringHelper *pgmstr)
{
unsigned int length = strlen_P((const char PROGMEM *)pgmstr);
if (!reserve(length)) {
if (buffer) {
free(buffer);
buffer = NULL;
}
len = capacity = 0;
return *this;
}
len = length;
strcpy_P(buffer, (const char PROGMEM *)pgmstr);
return *this;
}

void String::move(String &rhs)
{
if (buffer) {
if (capacity >= rhs.len) {
strcpy(buffer, rhs.buffer);
len = rhs.len;
rhs.len = 0;
return;
} else {
free(buffer);
}
}
buffer = rhs.buffer;
capacity = rhs.capacity;
len = rhs.len;
rhs.buffer = NULL;
rhs.capacity = 0;
rhs.len = 0;
}

String & String::operator = (const String &rhs)
{
if (this == &rhs) return *this;
return copy(rhs.buffer, rhs.len);
}

#ifdef __GXX_EXPERIMENTAL_CXX0X__
String & String::operator = (String &&rval)
{
if (this != &rval) move(rval);
return *this;
}

String & String::operator = (StringSumHelper &&rval)
{
if (this != &rval) move(rval);
return *this;
}
#endif

String & String::operator = (const char *cstr)
{
if (cstr) {
copy(cstr, strlen(cstr));
} else {
len = 0;
}
return *this;
}

String & String::operator = (const __FlashStringHelper *pgmstr)
{
copy(pgmstr);
return *this;
}

String & String::operator = (char c)
{
char buf[2];
buf[0] = c;
buf[1] = 0;
return copy(buf, 1);
}

/*********************************************/
/* Append */
/*********************************************/

String & String::append(const String &s)
{
return append(s.buffer, s.len);
}

String & String::append(const char *cstr, unsigned int length)
{
unsigned int newlen = len + length;
if (length == 0 || !reserve(newlen)) return *this;
strcpy(buffer + len, cstr);
len = newlen;
return *this;
}

String & String::append(const char *cstr)
{
if (cstr) append(cstr, strlen(cstr));
return *this;
}

String & String::append(const __FlashStringHelper *pgmstr)
{
unsigned int length = strlen_P((const char PROGMEM *)pgmstr);
unsigned int newlen = len + length;
if (length == 0 || !reserve(newlen)) return *this;
strcpy_P(buffer + len, (const char PROGMEM *)pgmstr);
len = newlen;
return *this;
}

String & String::append(char c)
{
char buf[2];
buf[0] = c;
buf[1] = 0;
append(buf, 1);
return *this;
}

String & String::append(int num)
{
char buf[7];
itoa(num, buf, 10);
append(buf, strlen(buf));
return *this;
}

String & String::append(unsigned int num)
{
char buf[6];
utoa(num, buf, 10);
append(buf, strlen(buf));
return *this;
}

String & String::append(long num)
{
char buf[12];
ltoa(num, buf, 10);
append(buf, strlen(buf));
return *this;
}

String & String::append(unsigned long num)
{
char buf[11];
ultoa(num, buf, 10);
append(buf, strlen(buf));
return *this;
}

String & String::append(float num)
{
char buf[30];
dtostrf(num, 4, 2, buf);
append(buf, strlen(buf));
return *this;
}

/*********************************************/
/* Concatenate */
/*********************************************/

StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
a.append(rhs.buffer, rhs.len);
return a;
}

StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (cstr) a.append(cstr, strlen(cstr));
return a;
}

StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *pgmstr)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
a.append(pgmstr);
return a;
}

StringSumHelper & operator + (const StringSumHelper &lhs, char c)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
a.append(c);
return a;
}

StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char c)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
a.append(c);
return a;
}

StringSumHelper & operator + (const StringSumHelper &lhs, int num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
a.append(num);
return a;
}

StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
a.append(num);
return a;
}

StringSumHelper & operator + (const StringSumHelper &lhs, long num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
a.append(num);
return a;
}

StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
a.append(num);
return a;
}

StringSumHelper & operator + (const StringSumHelper &lhs, float num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
a.append(num);
return a;
}

StringSumHelper & operator + (const StringSumHelper &lhs, double num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
a.append(num);
return a;
}

/*********************************************/
/* Comparison */
/*********************************************/

int String::compareTo(const String &s) const
{
if (!buffer || !s.buffer) {
if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer;
if (buffer && len > 0) return *(unsigned char *)buffer;
return 0;
}
return strcmp(buffer, s.buffer);
}

unsigned char String::equals(const String &s2) const
{
return (len == s2.len && compareTo(s2) == 0);
}

unsigned char String::equals(const char *cstr) const
{
if (len == 0) return (cstr == NULL || *cstr == 0);
if (cstr == NULL) return buffer[0] == 0;
return strcmp(buffer, cstr) == 0;
}

unsigned char String::equals(const __FlashStringHelper *pgmstr) const
{
if (len == 0) return pgm_read_byte(pgmstr) == 0;
return strcmp_P(buffer, (const char PROGMEM *)pgmstr) == 0;
}

unsigned char String::operator<(const String &rhs) const
{
return compareTo(rhs) < 0;
}

unsigned char String::operator>(const String &rhs) const
{
return compareTo(rhs) > 0;
}

unsigned char String::operator<=(const String &rhs) const
{
return compareTo(rhs) <= 0;
}

unsigned char String::operator>=(const String &rhs) const
{
return compareTo(rhs) >= 0;
}

unsigned char String::equalsIgnoreCase( const String &s2 ) const
{
if (this == &s2) return 1;
if (len != s2.len) return 0;
if (len == 0) return 1;
const char *p1 = buffer;
const char *p2 = s2.buffer;
while (*p1) {
if (tolower(*p1++) != tolower(*p2++)) return 0;
}
return 1;
}

unsigned char String::startsWith( const String &s2 ) const
{
if (len < s2.len) return 0;
return startsWith(s2, 0);
}

unsigned char String::startsWith( const String &s2, unsigned int offset ) const
{
if (offset > len - s2.len || !buffer || !s2.buffer) return 0;
return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0;
}

unsigned char String::endsWith( const String &s2 ) const
{
if ( len < s2.len || !buffer || !s2.buffer) return 0;
return strcmp(&buffer[len - s2.len], s2.buffer) == 0;
}

/*********************************************/
/* Character Access */
/*********************************************/

char String::charAt(unsigned int loc) const
{
return operator[](loc);
}

void String::setCharAt(unsigned int loc, char c)
{
if (loc < len) buffer[loc] = c;
}

char & String::operator[](unsigned int index)
{
static char dummy_writable_char;
if (index >= len || !buffer) {
dummy_writable_char = 0;
return dummy_writable_char;
}
return buffer[index];
}

char String::operator[]( unsigned int index ) const
{
if (index >= len || !buffer) return 0;
return buffer[index];
}

void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const
{
if (!bufsize || !buf) return;
if (index >= len) {
buf[0] = 0;
return;
}
unsigned int n = bufsize - 1;
if (n > len - index) n = len - index;
strncpy((char *)buf, buffer + index, n);
buf[n] = 0;
}

/*********************************************/
/* Search */
/*********************************************/

int String::indexOf(char c) const
{
return indexOf(c, 0);
}

int String::indexOf( char ch, unsigned int fromIndex ) const
{
if (fromIndex >= len) 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 >= len) return -1;
const char *found = strstr(buffer + fromIndex, s2.buffer);
if (found == NULL) return -1;
return found - buffer;
}

int String::lastIndexOf( char theChar ) const
{
return lastIndexOf(theChar, len - 1);
}

int String::lastIndexOf(char ch, unsigned int fromIndex) const
{
if (fromIndex >= len || fromIndex < 0) 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, len - s2.len);
}

int String::lastIndexOf(const String &s2, unsigned int fromIndex) const
{
if (s2.len == 0 || len == 0 || s2.len > len || fromIndex < 0) return -1;
if (fromIndex >= len) fromIndex = len - 1;
int found = -1;
for (char *p = buffer; p <= buffer + fromIndex; p++) {
p = strstr(p, s2.buffer);
if (!p) break;
if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer;
}
return found;
}

String String::substring( unsigned int left ) const
{
return substring(left, len);
}

String String::substring(unsigned int left, unsigned int right) const
{
if (left > right) {
unsigned int temp = right;
right = left;
left = temp;
}
String out;
if (left > len) return out;
if (right > len) right = len;
char temp = buffer[right]; // save the replaced character
buffer[right] = '\0';
out = buffer + left; // pointer arithmetic
buffer[right] = temp; //restore character
return out;
}

/*********************************************/
/* Modification */
/*********************************************/

String & String::replace(char find, char replace)
{
if (!buffer) return *this;
for (char *p = buffer; *p; p++) {
if (*p == find) *p = replace;
}
return *this;
}

String & String::replace(const String& find, const String& replace)
{
if (len == 0 || find.len == 0) return *this;
int diff = replace.len - find.len;
char *readFrom = buffer;
char *foundAt;
if (diff == 0) {
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
memcpy(foundAt, replace.buffer, replace.len);
readFrom = foundAt + replace.len;
}
} else if (diff < 0) {
char *writeTo = buffer;
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
unsigned int n = foundAt - readFrom;
memcpy(writeTo, readFrom, n);
writeTo += n;
memcpy(writeTo, replace.buffer, replace.len);
writeTo += replace.len;
readFrom = foundAt + find.len;
len += diff;
}
strcpy(writeTo, readFrom);
} else {
unsigned int size = len; // compute size needed for result
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
readFrom = foundAt + find.len;
size += diff;
}
if (size == len) return *this;
if (size > capacity && !changeBuffer(size)) return *this;
int index = len - 1;
while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) {
readFrom = buffer + index + find.len;
memmove(readFrom + diff, readFrom, len - (readFrom - buffer));
len += diff;
buffer[len] = 0;
memcpy(buffer + index, replace.buffer, replace.len);
index--;
}
}
return *this;
}

String & String::remove(unsigned int index)
{
if (index < len) {
len = index;
buffer[len] = 0;
}
return *this;
}

String & String::remove(unsigned int index, unsigned int count)
{
if (index < len && count > 0) {
if (index + count > len) count = len - index;
len = len - count;
memmove(buffer + index, buffer + index + count, len - index);
buffer[len] = 0;
}
return *this;
}

String & String::toLowerCase(void)
{
if (!buffer) return *this;
for (char *p = buffer; *p; p++) {
*p = tolower(*p);
}
return *this;
}

String & String::toUpperCase(void)
{
if (!buffer) return *this;
for (char *p = buffer; *p; p++) {
*p = toupper(*p);
}
return *this;
}

String & String::trim(void)
{
if (!buffer || len == 0) return *this;
char *begin = buffer;
while (isspace(*begin)) begin++;
char *end = buffer + len - 1;
while (isspace(*end) && end >= begin) end--;
len = end + 1 - begin;
if (begin > buffer) memcpy(buffer, begin, len);
buffer[len] = 0;
return *this;
}

/*********************************************/
/* Parsing / Conversion */
/*********************************************/

long String::toInt(void) const
{
if (buffer) return atol(buffer);
return 0;
}

float String::toFloat(void) const
{
if (buffer) return atof(buffer);
return 0.0;
}


+ 216
- 0
teensy/WString.h View File

@@ -0,0 +1,216 @@
/*
WString.h - String library for Wiring & Arduino
...mostly rewritten by Paul Stoffregen...
Copyright (c) 2009-10 Hernando Barragan. All right reserved.
Copyright 2011, Paul Stoffregen, paul@pjrc.com

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_class_h
#define String_class_h
#ifdef __cplusplus

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <avr/pgmspace.h>

// When compiling programs with this class, the following gcc parameters
// dramatically increase performance and memory (RAM) efficiency, typically
// with little or no increase in code size.
// -felide-constructors
// -std=c++0x

// Brian Cook's "no overhead" Flash String type (message on Dec 14, 2010)
// modified by Mikal Hart for his FlashString library
class __FlashStringHelper;
#ifndef F
#define F(string_literal) ((const __FlashStringHelper *)(PSTR(string_literal)))
#endif

// An inherited class for holding the result of a concatenation. These
// result objects are assumed to be writable by subsequent concatenations.
class StringSumHelper;

// The string class
class String
{
public:
// constructors
String(const char *cstr = NULL);
String(const __FlashStringHelper *pgmstr);
String(const String &str);
#ifdef __GXX_EXPERIMENTAL_CXX0X__
String(String &&rval);
String(StringSumHelper &&rval);
#endif
String(char c);
String(unsigned char c);
String(int, unsigned char base=10);
String(unsigned int, unsigned char base=10);
String(long, unsigned char base=10);
String(unsigned long, unsigned char base=10);
String(float num, unsigned char digits=2);
String(double num, unsigned char digits=2);
~String(void);

// memory management
unsigned char reserve(unsigned int size);
inline unsigned int length(void) const {return len;}

// copy and move
String & copy(const char *cstr, unsigned int length);
String & copy(const __FlashStringHelper *pgmstr);
void move(String &rhs);
String & operator = (const String &rhs);
String & operator = (const char *cstr);
String & operator = (const __FlashStringHelper *pgmstr);
#ifdef __GXX_EXPERIMENTAL_CXX0X__
String & operator = (String &&rval);
String & operator = (StringSumHelper &&rval);
#endif
String & operator = (char c);

// append
String & append(const String &str);
String & append(const char *cstr);
String & append(const __FlashStringHelper *pgmstr);
String & append(char c);
String & append(unsigned char c) {return append((int)c);}
String & append(int num);
String & append(unsigned int num);
String & append(long num);
String & append(unsigned long num);
String & append(float num);
String & append(double num) {return append((float)num);}
String & operator += (const String &rhs) {return append(rhs);}
String & operator += (const char *cstr) {return append(cstr);}
String & operator += (const __FlashStringHelper *pgmstr) {return append(pgmstr);}
String & operator += (char c) {return append(c);}
String & operator += (unsigned char c) {return append((int)c);}
String & operator += (int num) {return append(num);}
String & operator += (unsigned int num) {return append(num);}
String & operator += (long num) {return append(num);}
String & operator += (unsigned long num) {return append(num);}
String & operator += (float num) {return append(num);}
String & operator += (double num) {return append(num);}

// concatenate
friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs);
friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr);
friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *pgmstr);
friend StringSumHelper & operator + (const StringSumHelper &lhs, char c);
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char c);
friend StringSumHelper & operator + (const StringSumHelper &lhs, int num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, long num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, float num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, double num);
String & concat(const String &str) {return append(str);}
String & concat(const char *cstr) {return append(cstr);}
String & concat(const __FlashStringHelper *pgmstr) {return append(pgmstr);}
String & concat(char c) {return append(c);}
String & concat(unsigned char c) {return append((int)c);}
String & concat(int num) {return append(num);}
String & concat(unsigned int num) {return append(num);}
String & concat(long num) {return append(num);}
String & concat(unsigned long num) {return append(num);}
String & concat(float num) {return append(num);}
String & concat(double num) {return append(num);}

// comparison
int compareTo(const String &s) const;
unsigned char equals(const String &s) const;
unsigned char equals(const char *cstr) const;
unsigned char equals(const __FlashStringHelper *pgmstr) const;
unsigned char operator == (const String &rhs) const {return equals(rhs);}
unsigned char operator == (const char *cstr) const {return equals(cstr);}
unsigned char operator == (const __FlashStringHelper *pgmstr) const {return equals(pgmstr);}
unsigned char operator != (const String &rhs) const {return !equals(rhs);}
unsigned char operator != (const char *cstr) const {return !equals(cstr);}
unsigned char operator != (const __FlashStringHelper *pgmstr) const {return !equals(pgmstr);}
unsigned char operator < (const String &rhs) const;
unsigned char operator > (const String &rhs) const;
unsigned char operator <= (const String &rhs) const;
unsigned char operator >= (const String &rhs) const;
unsigned char equalsIgnoreCase(const String &s) const;
unsigned char startsWith( const String &prefix) const;
unsigned char startsWith(const String &prefix, unsigned int offset) const;
unsigned char endsWith(const String &suffix) const;

// character acccess
char charAt(unsigned int index) const;
void setCharAt(unsigned int index, char c);
char operator [] (unsigned int index) const;
char& operator [] (unsigned int index);
void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const;
void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const
{getBytes((unsigned char *)buf, bufsize, index);}
const char * c_str() const { return buffer; }

// search
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;
String substring( unsigned int beginIndex ) const;
String substring( unsigned int beginIndex, unsigned int endIndex ) const;

// modification
String & replace(char find, char replace);
String & replace(const String& find, const String& replace);
String & remove(unsigned int index);
String & remove(unsigned int index, unsigned int count);
String & toLowerCase(void);
String & toUpperCase(void);
String & trim(void);

// parsing/conversion
long toInt(void) const;
float toFloat(void) const;

protected:
char *buffer; // the actual char array
unsigned int capacity; // the array length minus one (for the '\0')
unsigned int len; // the String length (not counting the '\0')
unsigned char flags; // unused, for future features
protected:
void init(void);
unsigned char changeBuffer(unsigned int maxStrLen);
String & append(const char *cstr, unsigned int length);
};

class StringSumHelper : public String
{
public:
StringSumHelper(const String &s) : String(s) {}
StringSumHelper(const char *p) : String(p) {}
StringSumHelper(const __FlashStringHelper *pgmstr) : String(pgmstr) {}
StringSumHelper(char c) : String(c) {}
StringSumHelper(unsigned char c) : String(c) {}
StringSumHelper(int num) : String(num, 10) {}
StringSumHelper(unsigned int num) : String(num, 10) {}
StringSumHelper(long num) : String(num, 10) {}
StringSumHelper(unsigned long num) : String(num, 10) {}
};

#endif // __cplusplus
#endif // String_class_h

+ 515
- 0
teensy/binary.h 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

+ 18
- 0
teensy/core_id.h View File

@@ -0,0 +1,18 @@
#ifndef CORE_TEENSY
#define CORE_TEENSY
#if defined(USB_SERIAL)
#include "../usb_serial/core_id.h"
#elif defined(USB_HID)
#include "../usb_hid/core_id.h"
#elif defined(USB_SERIAL_HID)
#include "../usb_serial_hid/core_id.h"
#elif defined(USB_DISK) || defined(USB_DISK_SDFLASH)
#include "../usb_disk/core_id.h"
#elif defined(USB_MIDI)
#include "../usb_midi/core_id.h"
#elif defined(USB_RAWHID)
#include "../usb_rawhid/core_id.h"
#elif defined(USB_FLIGHTSIM)
#include "../usb_flightsim/core_id.h"
#endif
#endif

+ 1987
- 0
teensy/core_pins.h
File diff suppressed because it is too large
View File


+ 81
- 0
teensy/elapsedMillis.h View File

@@ -0,0 +1,81 @@
/* Elapsed time types - for easy-to-use measurements of elapsed time
* http://www.pjrc.com/teensy/
* Copyright (c) 2011 PJRC.COM, LLC
*
* 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.
*/

#ifndef elapsedMillis_h
#define elapsedMillis_h
#ifdef __cplusplus

#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

class elapsedMillis
{
private:
unsigned long ms;
public:
elapsedMillis(void) { ms = millis(); }
elapsedMillis(unsigned long val) { ms = millis() - val; }
elapsedMillis(const elapsedMillis &orig) { ms = orig.ms; }
operator unsigned long () const { return millis() - ms; }
elapsedMillis & operator = (const elapsedMillis &rhs) { ms = rhs.ms; return *this; }
elapsedMillis & operator = (unsigned long val) { ms = millis() - val; return *this; }
elapsedMillis & operator -= (unsigned long val) { ms += val ; return *this; }
elapsedMillis & operator += (unsigned long val) { ms -= val ; return *this; }
elapsedMillis operator - (int val) const { elapsedMillis r(*this); r.ms += val; return r; }
elapsedMillis operator - (unsigned int val) const { elapsedMillis r(*this); r.ms += val; return r; }
elapsedMillis operator - (long val) const { elapsedMillis r(*this); r.ms += val; return r; }
elapsedMillis operator - (unsigned long val) const { elapsedMillis r(*this); r.ms += val; return r; }
elapsedMillis operator + (int val) const { elapsedMillis r(*this); r.ms -= val; return r; }
elapsedMillis operator + (unsigned int val) const { elapsedMillis r(*this); r.ms -= val; return r; }
elapsedMillis operator + (long val) const { elapsedMillis r(*this); r.ms -= val; return r; }
elapsedMillis operator + (unsigned long val) const { elapsedMillis r(*this); r.ms -= val; return r; }
};

class elapsedMicros
{
private:
unsigned long us;
public:
elapsedMicros(void) { us = micros(); }
elapsedMicros(unsigned long val) { us = micros() - val; }
elapsedMicros(const elapsedMicros &orig) { us = orig.us; }
operator unsigned long () const { return micros() - us; }
elapsedMicros & operator = (const elapsedMicros &rhs) { us = rhs.us; return *this; }
elapsedMicros & operator = (unsigned long val) { us = micros() - val; return *this; }
elapsedMicros & operator -= (unsigned long val) { us += val ; return *this; }
elapsedMicros & operator += (unsigned long val) { us -= val ; return *this; }
elapsedMicros operator - (int val) const { elapsedMicros r(*this); r.us += val; return r; }
elapsedMicros operator - (unsigned int val) const { elapsedMicros r(*this); r.us += val; return r; }
elapsedMicros operator - (long val) const { elapsedMicros r(*this); r.us += val; return r; }
elapsedMicros operator - (unsigned long val) const { elapsedMicros r(*this); r.us += val; return r; }
elapsedMicros operator + (int val) const { elapsedMicros r(*this); r.us -= val; return r; }
elapsedMicros operator + (unsigned int val) const { elapsedMicros r(*this); r.us -= val; return r; }
elapsedMicros operator + (long val) const { elapsedMicros r(*this); r.us -= val; return r; }
elapsedMicros operator + (unsigned long val) const { elapsedMicros r(*this); r.us -= val; return r; }
};

#endif // __cplusplus
#endif // elapsedMillis_h

+ 66
- 0
teensy/keylayouts.c View File

@@ -0,0 +1,66 @@
#include <avr/pgmspace.h>
#include <stdint.h>

#include "keylayouts.h"

#ifdef M
#undef M
#endif
#define M(n) ((n) & 0x3FFF)

const KEYCODE_TYPE PROGMEM keycodes_ascii[] = {
M(ASCII_20), M(ASCII_21), M(ASCII_22), M(ASCII_23),
M(ASCII_24), M(ASCII_25), M(ASCII_26), M(ASCII_27),
M(ASCII_28), M(ASCII_29), M(ASCII_2A), M(ASCII_2B),
M(ASCII_2C), M(ASCII_2D), M(ASCII_2E), M(ASCII_2F),
M(ASCII_30), M(ASCII_31), M(ASCII_32), M(ASCII_33),
M(ASCII_34), M(ASCII_35), M(ASCII_36), M(ASCII_37),
M(ASCII_38), M(ASCII_39), M(ASCII_3A), M(ASCII_3B),
M(ASCII_3C), M(ASCII_3D), M(ASCII_3E), M(ASCII_3F),
M(ASCII_40), M(ASCII_41), M(ASCII_42), M(ASCII_43),
M(ASCII_44), M(ASCII_45), M(ASCII_46), M(ASCII_47),
M(ASCII_48), M(ASCII_49), M(ASCII_4A), M(ASCII_4B),
M(ASCII_4C), M(ASCII_4D), M(ASCII_4E), M(ASCII_4F),
M(ASCII_50), M(ASCII_51), M(ASCII_52), M(ASCII_53),
M(ASCII_54), M(ASCII_55), M(ASCII_56), M(ASCII_57),
M(ASCII_58), M(ASCII_59), M(ASCII_5A), M(ASCII_5B),
M(ASCII_5C), M(ASCII_5D), M(ASCII_5E), M(ASCII_5F),
M(ASCII_60), M(ASCII_61), M(ASCII_62), M(ASCII_63),
M(ASCII_64), M(ASCII_65), M(ASCII_66), M(ASCII_67),
M(ASCII_68), M(ASCII_69), M(ASCII_6A), M(ASCII_6B),
M(ASCII_6C), M(ASCII_6D), M(ASCII_6E), M(ASCII_6F),
M(ASCII_70), M(ASCII_71), M(ASCII_72), M(ASCII_73),
M(ASCII_74), M(ASCII_75), M(ASCII_76), M(ASCII_77),
M(ASCII_78), M(ASCII_79), M(ASCII_7A), M(ASCII_7B),
M(ASCII_7C), M(ASCII_7D), M(ASCII_7E), M(ASCII_7F)
};

#ifdef ISO_8859_1_A0
const KEYCODE_TYPE PROGMEM keycodes_iso_8859_1[] = {
M(ISO_8859_1_A0), M(ISO_8859_1_A1), M(ISO_8859_1_A2), M(ISO_8859_1_A3),
M(ISO_8859_1_A4), M(ISO_8859_1_A5), M(ISO_8859_1_A6), M(ISO_8859_1_A7),
M(ISO_8859_1_A8), M(ISO_8859_1_A9), M(ISO_8859_1_AA), M(ISO_8859_1_AB),
M(ISO_8859_1_AC), M(ISO_8859_1_AD), M(ISO_8859_1_AE), M(ISO_8859_1_AF),
M(ISO_8859_1_B0), M(ISO_8859_1_B1), M(ISO_8859_1_B2), M(ISO_8859_1_B3),
M(ISO_8859_1_B4), M(ISO_8859_1_B5), M(ISO_8859_1_B6), M(ISO_8859_1_B7),
M(ISO_8859_1_B8), M(ISO_8859_1_B9), M(ISO_8859_1_BA), M(ISO_8859_1_BB),
M(ISO_8859_1_BC), M(ISO_8859_1_BD), M(ISO_8859_1_BE), M(ISO_8859_1_BF),
M(ISO_8859_1_C0), M(ISO_8859_1_C1), M(ISO_8859_1_C2), M(ISO_8859_1_C3),
M(ISO_8859_1_C4), M(ISO_8859_1_C5), M(ISO_8859_1_C6), M(ISO_8859_1_C7),
M(ISO_8859_1_C8), M(ISO_8859_1_C9), M(ISO_8859_1_CA), M(ISO_8859_1_CB),
M(ISO_8859_1_CC), M(ISO_8859_1_CD), M(ISO_8859_1_CE), M(ISO_8859_1_CF),
M(ISO_8859_1_D0), M(ISO_8859_1_D1), M(ISO_8859_1_D2), M(ISO_8859_1_D3),
M(ISO_8859_1_D4), M(ISO_8859_1_D5), M(ISO_8859_1_D6), M(ISO_8859_1_D7),
M(ISO_8859_1_D8), M(ISO_8859_1_D9), M(ISO_8859_1_DA), M(ISO_8859_1_DB),
M(ISO_8859_1_DC), M(ISO_8859_1_DD), M(ISO_8859_1_DE), M(ISO_8859_1_DF),
M(ISO_8859_1_E0), M(ISO_8859_1_E1), M(ISO_8859_1_E2), M(ISO_8859_1_E3),
M(ISO_8859_1_E4), M(ISO_8859_1_E5), M(ISO_8859_1_E6), M(ISO_8859_1_E7),
M(ISO_8859_1_E8), M(ISO_8859_1_E9), M(ISO_8859_1_EA), M(ISO_8859_1_EB),
M(ISO_8859_1_EC), M(ISO_8859_1_ED), M(ISO_8859_1_EE), M(ISO_8859_1_EF),
M(ISO_8859_1_F0), M(ISO_8859_1_F1), M(ISO_8859_1_F2), M(ISO_8859_1_F3),
M(ISO_8859_1_F4), M(ISO_8859_1_F5), M(ISO_8859_1_F6), M(ISO_8859_1_F7),
M(ISO_8859_1_F8), M(ISO_8859_1_F9), M(ISO_8859_1_FA), M(ISO_8859_1_FB),
M(ISO_8859_1_FC), M(ISO_8859_1_FD), M(ISO_8859_1_FE), M(ISO_8859_1_FF)
};
#endif // ISO_8859_1_A0


+ 5173
- 0
teensy/keylayouts.h
File diff suppressed because it is too large
View File


+ 14
- 0
teensy/main.cpp View File

@@ -0,0 +1,14 @@
#include <WProgram.h>

//int main(void) __attribute__((noreturn));
int main(void)
{
_init_Teensyduino_internal_();

setup();
while (1) {
loop();
}
}


+ 1
- 0
teensy/main.cxx View File

@@ -0,0 +1 @@
// the main function is now built into core.a and linked into the final executable

+ 388
- 0
teensy/malloc.c View File

@@ -0,0 +1,388 @@
/* Copyright (c) 2002, 2004, 2010 Joerg Wunsch
Copyright (c) 2010 Gerben van den Broeke
All rights reserved.

malloc, free, realloc from avr-libc 1.7.0
with minor modifications, by Paul Stoffregen

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.

* Neither the name of the copyright holders nor the names of
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/

#include <stdlib.h>
#include <inttypes.h>
#include <string.h>
#include <avr/io.h>

extern char __heap_start;
extern char __heap_end;
#define STACK_POINTER() ((char *)AVR_STACK_POINTER_REG)

struct __freelist {
size_t sz;
struct __freelist *nx;
};

/*
* Exported interface:
*
* When extending the data segment, the allocator will not try to go
* beyond the current stack limit, decreased by __malloc_margin bytes.
* Thus, all possible stack frames of interrupt routines that could
* interrupt the current function, plus all further nested function
* calls must not require more stack space, or they'll risk to collide
* with the data segment.
*/
size_t __malloc_margin = 128;
char *__malloc_heap_start = &__heap_start;
char *__malloc_heap_end = &__heap_end;

char *__brkval = NULL; // first location not yet allocated
struct __freelist *__flp; // freelist pointer (head of freelist)

// this is useful for tracking the worst case memory allocation
//char *__brkval_maximum = 0;


void *
malloc(size_t len)
{
struct __freelist *fp1, *fp2, *sfp1, *sfp2;
char *cp;
size_t s, avail;

/*
* Our minimum chunk size is the size of a pointer (plus the
* size of the "sz" field, but we don't need to account for
* this), otherwise we could not possibly fit a freelist entry
* into the chunk later.
*/
if (len < sizeof(struct __freelist) - sizeof(size_t))
len = sizeof(struct __freelist) - sizeof(size_t);

/*
* First, walk the free list and try finding a chunk that
* would match exactly. If we found one, we are done. While
* walking, note down the smallest chunk we found that would
* still fit the request -- we need it for step 2.
*
*/
for (s = 0, fp1 = __flp, fp2 = 0;
fp1;
fp2 = fp1, fp1 = fp1->nx) {
if (fp1->sz < len)
continue;
if (fp1->sz == len) {
/*
* Found it. Disconnect the chunk from the
* freelist, and return it.
*/
if (fp2)
fp2->nx = fp1->nx;
else
__flp = fp1->nx;
return &(fp1->nx);
}
else {
if (s == 0 || fp1->sz < s) {
/* this is the smallest chunk found so far */
s = fp1->sz;
sfp1 = fp1;
sfp2 = fp2;
}
}
}
/*
* Step 2: If we found a chunk on the freelist that would fit
* (but was too large), look it up again and use it, since it
* is our closest match now. Since the freelist entry needs
* to be split into two entries then, watch out that the
* difference between the requested size and the size of the
* chunk found is large enough for another freelist entry; if
* not, just enlarge the request size to what we have found,
* and use the entire chunk.
*/
if (s) {
if (s - len < sizeof(struct __freelist)) {
/* Disconnect it from freelist and return it. */
if (sfp2)
sfp2->nx = sfp1->nx;
else
__flp = sfp1->nx;
return &(sfp1->nx);
}
/*
* Split them up. Note that we leave the first part
* as the new (smaller) freelist entry, and return the
* upper portion to the caller. This saves us the
* work to fix up the freelist chain; we just need to
* fixup the size of the current entry, and note down
* the size of the new chunk before returning it to
* the caller.
*/
cp = (char *)sfp1;
s -= len;
cp += s;
sfp2 = (struct __freelist *)cp;
sfp2->sz = len;
sfp1->sz = s - sizeof(size_t);
return &(sfp2->nx);
}
/*
* Step 3: If the request could not be satisfied from a
* freelist entry, just prepare a new chunk. This means we
* need to obtain more memory first. The largest address just
* not allocated so far is remembered in the brkval variable.
* Under Unix, the "break value" was the end of the data
* segment as dynamically requested from the operating system.
* Since we don't have an operating system, just make sure
* that we don't collide with the stack.
*/
if (__brkval == 0)
__brkval = __malloc_heap_start;
cp = __malloc_heap_end;
if (cp == 0)
cp = STACK_POINTER() - __malloc_margin;
if (cp <= __brkval)
/*
* Memory exhausted.
*/
return 0;
avail = cp - __brkval;
/*
* Both tests below are needed to catch the case len >= 0xfffe.
*/
if (avail >= len && avail >= len + sizeof(size_t)) {
fp1 = (struct __freelist *)__brkval;
__brkval += len + sizeof(size_t);
//__brkval_maximum = __brkval;
fp1->sz = len;
return &(fp1->nx);
}
/*
* Step 4: There's no help, just fail. :-/
*/
return 0;
}


void
free(void *p)
{
struct __freelist *fp1, *fp2, *fpnew;
char *cp1, *cp2, *cpnew;

/* ISO C says free(NULL) must be a no-op */
if (p == 0)
return;

cpnew = p;
cpnew -= sizeof(size_t);
fpnew = (struct __freelist *)cpnew;
fpnew->nx = 0;

/*
* Trivial case first: if there's no freelist yet, our entry
* will be the only one on it. If this is the last entry, we
* can reduce __brkval instead.
*/
if (__flp == 0) {
if ((char *)p + fpnew->sz == __brkval)
__brkval = cpnew;
else
__flp = fpnew;
return;
}

/*
* Now, find the position where our new entry belongs onto the
* freelist. Try to aggregate the chunk with adjacent chunks
* if possible.
*/
for (fp1 = __flp, fp2 = 0;
fp1;
fp2 = fp1, fp1 = fp1->nx) {
if (fp1 < fpnew)
continue;
cp1 = (char *)fp1;
fpnew->nx = fp1;
if ((char *)&(fpnew->nx) + fpnew->sz == cp1) {
/* upper chunk adjacent, assimilate it */
fpnew->sz += fp1->sz + sizeof(size_t);
fpnew->nx = fp1->nx;
}
if (fp2 == 0) {
/* new head of freelist */
__flp = fpnew;
return;
}
break;
}
/*
* Note that we get here either if we hit the "break" above,
* or if we fell off the end of the loop. The latter means
* we've got a new topmost chunk. Either way, try aggregating
* with the lower chunk if possible.
*/
fp2->nx = fpnew;
cp2 = (char *)&(fp2->nx);
if (cp2 + fp2->sz == cpnew) {
/* lower junk adjacent, merge */
fp2->sz += fpnew->sz + sizeof(size_t);
fp2->nx = fpnew->nx;
}
/*
* If there's a new topmost chunk, lower __brkval instead.
*/
for (fp1 = __flp, fp2 = 0;
fp1->nx != 0;
fp2 = fp1, fp1 = fp1->nx)
/* advance to entry just before end of list */;
cp2 = (char *)&(fp1->nx);
if (cp2 + fp1->sz == __brkval) {
if (fp2 == NULL)
/* Freelist is empty now. */
__flp = NULL;
else
fp2->nx = NULL;
__brkval = cp2 - sizeof(size_t);
}
}



void *
realloc(void *ptr, size_t len)
{
struct __freelist *fp1, *fp2, *fp3, *ofp3;
char *cp, *cp1;
void *memp;
size_t s, incr;

/* Trivial case, required by C standard. */
if (ptr == 0)
return malloc(len);

cp1 = (char *)ptr;
cp1 -= sizeof(size_t);
fp1 = (struct __freelist *)cp1;

cp = (char *)ptr + len; /* new next pointer */
if (cp < cp1)
/* Pointer wrapped across top of RAM, fail. */
return 0;

/*
* See whether we are growing or shrinking. When shrinking,
* we split off a chunk for the released portion, and call
* free() on it. Therefore, we can only shrink if the new
* size is at least sizeof(struct __freelist) smaller than the
* previous size.
*/
if (len <= fp1->sz) {
/* The first test catches a possible unsigned int
* rollover condition. */
if (fp1->sz <= sizeof(struct __freelist) ||
len > fp1->sz - sizeof(struct __freelist))
return ptr;
fp2 = (struct __freelist *)cp;
fp2->sz = fp1->sz - len - sizeof(size_t);
fp1->sz = len;
free(&(fp2->nx));
return ptr;
}

/*
* If we get here, we are growing. First, see whether there
* is space in the free list on top of our current chunk.
*/
incr = len - fp1->sz;
cp = (char *)ptr + fp1->sz;
fp2 = (struct __freelist *)cp;
for (s = 0, ofp3 = 0, fp3 = __flp;
fp3;
ofp3 = fp3, fp3 = fp3->nx) {
if (fp3 == fp2 && fp3->sz + sizeof(size_t) >= incr) {
/* found something that fits */
if (fp3->sz + sizeof(size_t) - incr > sizeof(struct __freelist)) {
/* split off a new freelist entry */
cp = (char *)ptr + len;
fp2 = (struct __freelist *)cp;
fp2->nx = fp3->nx;
fp2->sz = fp3->sz - incr;
fp1->sz = len;
} else {
/* it just fits, so use it entirely */
fp1->sz += fp3->sz + sizeof(size_t);
fp2 = fp3->nx;
}
if (ofp3)
ofp3->nx = fp2;
else
__flp = fp2;
return ptr;
}
/*
* Find the largest chunk on the freelist while
* walking it.
*/
if (fp3->sz > s)
s = fp3->sz;
}
/*
* If we are the topmost chunk in memory, and there was no
* large enough chunk on the freelist that could be re-used
* (by a call to malloc() below), quickly extend the
* allocation area if possible, without need to copy the old
* data.
*/
if (__brkval == (char *)ptr + fp1->sz && len > s) {
cp = (char *)ptr + len;
cp1 = STACK_POINTER() - __malloc_margin;
if (cp < cp1) {
__brkval = cp;
//__brkval_maximum = cp;
fp1->sz = len;
return ptr;
}
/* If that failed, we are out of luck. */
return 0;
}

/*
* Call malloc() for a new chunk, then copy over the data, and
* release the old region.
*/
if ((memp = malloc(len)) == 0)
return 0;
memcpy(memp, ptr, fp1->sz);
free(ptr);
return memp;
}


+ 18
- 0
teensy/new.cpp 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) {};


+ 22
- 0
teensy/new.h 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


+ 147
- 0
teensy/pins_arduino.h View File

@@ -0,0 +1,147 @@
#ifndef pins_macros_for_arduino_compatibility_h
#define pins_macros_for_arduino_compatibility_h

#include <avr/pgmspace.h>
#include "core_pins.h"

#if defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
const static uint8_t A0 = CORE_ANALOG0_PIN;
const static uint8_t A1 = CORE_ANALOG1_PIN;
const static uint8_t A2 = CORE_ANALOG2_PIN;
const static uint8_t A3 = CORE_ANALOG3_PIN;
const static uint8_t A4 = CORE_ANALOG4_PIN;
const static uint8_t A5 = CORE_ANALOG5_PIN;
const static uint8_t A6 = CORE_ANALOG6_PIN;
const static uint8_t A7 = CORE_ANALOG7_PIN;
#if defined(__AVR_ATmega32U4__)
const static uint8_t A8 = CORE_ANALOG8_PIN;
const static uint8_t A9 = CORE_ANALOG9_PIN;
const static uint8_t A10 = 10;
const static uint8_t A11 = CORE_ANALOG11_PIN;
#endif
#endif

const static uint8_t SS = CORE_SS0_PIN;
const static uint8_t MOSI = CORE_MOSI0_PIN;
const static uint8_t MISO = CORE_MISO0_PIN;
const static uint8_t SCK = CORE_SCLK0_PIN;
const static uint8_t LED_BUILTIN = CORE_LED0_PIN;
#if defined(CORE_SDA0_PIN)
const static uint8_t SDA = CORE_SDA0_PIN;
#endif
#if defined(CORE_SCL0_PIN)
const static uint8_t SCL = CORE_SCL0_PIN;
#endif

#define NUM_DIGITAL_PINS CORE_NUM_TOTAL_PINS
#define NUM_ANALOG_INPUTS CORE_NUM_ANALOG


// This allows CapSense to work. Do any libraries
// depend on these to be zero?
#define NOT_A_PORT 127
#define NOT_A_PIN 127

#define digitalPinToPort(P) (P)
#define portInputRegister(P) ((volatile uint8_t *)((int)pgm_read_byte(digital_pin_table_PGM+(P)*2+1)))
#define portModeRegister(P) (portInputRegister(P) + 1)
#define portOutputRegister(P) (portInputRegister(P) + 2)
#define digitalPinToBitMask(P) (pgm_read_byte(digital_pin_table_PGM+(P)*2))
extern const uint8_t PROGMEM digital_pin_table_PGM[];

#if defined(__AVR_AT90USB162__)
#define analogInputToDigitalPin(ch) (-1)
#define digitalPinHasPWM(p) ((p) == 0 || (p) == 15 || (p) == 17 || (p) == 18)
#elif defined(__AVR_ATmega32U4__)
#define analogInputToDigitalPin(ch) ((ch) <= 10 ? 21 - (ch) : ((ch) == 11 ? 22 : -1))
#define digitalPinHasPWM(p) ((p) == 4 || (p) == 5 || (p) == 9 || (p) == 10 || (p) == 12 || (p) == 14 || (p) == 15)
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
#define analogInputToDigitalPin(ch) ((ch) <= 7 ? (ch) + 38 : -1)
#define digitalPinHasPWM(p) (((p) >= 14 && (p) <= 16) || ((p) >= 24 && (p) <= 27) || (p) == 0 || (p) == 1)
#endif

#if defined(__AVR_AT90USB162__)
#define digitalPinToPortReg(p) (((p) <= 7) ? &PORTD : (((p) <= 15) ? &PORTB : &PORTC))
#define digitalPinToBit(p) \
(((p) <= 7) ? (p) : (((p) <= 15) ? (p) - 8 : (((p) <= 19) ? 23 - (p) : 2)))
#define digitalPinToPCICR(p) \
((((p) >= 8 && (p) <= 15) || ((p) >= 17 && (p) <= 20) || (p) == 5) ? &PCICR : NULL)
#define digitalPinToPCICRbit(p) (((p) >= 8 && (p) <= 15) ? 0 : 1)
#define digitalPinToPCIFR(p) \
((((p) >= 8 && (p) <= 15) || ((p) >= 17 && (p) <= 20) || (p) == 5) ? &PCIFR : NULL)
#define digitalPinToPCIFRbit(p) (((p) >= 8 && (p) <= 15) ? 0 : 1)
#define digitalPinToPCMSK(p) \
(((p) >= 8 && (p) <= 15) ? &PCMSK0 : ((((p) >= 17 && (p) <= 20) || (p) == 5) ? &PCMSK1 : NULL))
#define digitalPinToPCMSKbit(p) \
(((p) >= 8 && (p) <= 15) ? (p) - 8 : (((p) >= 17 && (p) <= 20) ? (p) - 17 : 4))

#elif defined(__AVR_ATmega32U4__)
#define digitalPinToPortReg(p) \
(((p) <= 4) ? &PORTB : (((p) <= 8) ? &PORTD : (((p) <= 10) ? &PORTC : (((p) <= 12) ? &PORTD : \
(((p) <= 15) ? &PORTB : (((p) <= 21) ? &PORTF : (((p) <= 23) ? &PORTD : &PORTE)))))))
#define digitalPinToBit(p) \
(((p) <= 3) ? (p) : (((p) == 4) ? 7 : (((p) <= 8) ? (p) - 5 : (((p) <= 10) ? (p) - 3 : \
(((p) <= 12) ? (p) - 5 : (((p) <= 15) ? (p) - 9 : (((p) <= 19) ? 23 - (p) : \
(((p) <= 21) ? 21 - (p) : (((p) <= 23) ? (p) - 18 : 6)))))))))
#define digitalPinToPCICR(p) ((((p) >= 0 && (p) <= 4) || ((p) >= 13 && (p) <= 15)) ? &PCICR : NULL)
#define digitalPinToPCICRbit(p) (0)
#define digitalPinToPCIFR(p) ((((p) >= 0 && (p) <= 4) || ((p) >= 13 && (p) <= 15)) ? &PCIFR : NULL)
#define digitalPinToPCIFRbit(p) (0)
#define digitalPinToPCMSK(p) ((((p) >= 0 && (p) <= 4) || ((p) >= 13 && (p) <= 15)) ? &PCMSK0 : NULL)
#define digitalPinToPCMSKbit(p) \
(((p) >= 0 && (p) <= 3) ? (p) : (((p) >= 13 && (p) <= 15) ? (p) - 9 : 7))

#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
#define digitalPinToPortReg(p) \
(((p) >= 0 && (p) <= 7) ? &PORTD : (((p) >= 10 && (p) <= 17) ? &PORTC : \
(((p) >= 20 && (p) <= 27) ? &PORTB : (((p) >= 28 && (p) <= 35) ? &PORTA : \
(((p) >= 38 && (p) <= 45) ? &PORTF : &PORTE)))))
#define digitalPinToBit(p) \
(((p) <= 7) ? (p) : (((p) <= 9) ? (p) - 8 : (((p) <= 17) ? (p) - 10 : \
(((p) <= 19) ? (p) - 12 : (((p) <= 27) ? (p) - 20 : (((p) <= 35) ? (p) - 28 : \
(((p) <= 37) ? (p) - 32 : (((p) <= 45) ? (p) - 38 : 2))))))))
#define digitalPinToPCICR(p) (((p) >= 20 && (p) <= 27) ? &PCICR : NULL)
#define digitalPinToPCICRbit(p) (0)
#define digitalPinToPCIFR(p) (((p) >= 20 && (p) <= 27) ? &PCIFR : NULL)
#define digitalPinToPCIFRbit(p) (0)
#define digitalPinToPCMSK(p) (((p) >= 20 && (p) <= 27) ? &PCMSK0 : NULL)
#define digitalPinToPCMSKbit(p) (((p) - 20) & 7)
#endif

#define NOT_ON_TIMER 0
static inline uint8_t digitalPinToTimer(uint8_t) __attribute__((always_inline, unused));
static inline uint8_t digitalPinToTimer(uint8_t pin)
{
switch (pin) {
#ifdef CORE_PWM0_PIN
case CORE_PWM0_PIN: return 1;
#endif
#ifdef CORE_PWM1_PIN
case CORE_PWM1_PIN: return 2;
#endif
#ifdef CORE_PWM2_PIN
case CORE_PWM2_PIN: return 3;
#endif
#ifdef CORE_PWM3_PIN
case CORE_PWM3_PIN: return 4;
#endif
#ifdef CORE_PWM4_PIN
case CORE_PWM4_PIN: return 5;
#endif
#ifdef CORE_PWM5_PIN
case CORE_PWM5_PIN: return 6;
#endif
#ifdef CORE_PWM6_PIN
case CORE_PWM6_PIN: return 7;
#endif
#ifdef CORE_PWM7_PIN
case CORE_PWM7_PIN: return 8;
#endif
#ifdef CORE_PWM8_PIN
case CORE_PWM8_PIN: return 9;
#endif
default: return NOT_ON_TIMER;
}
}

#endif

+ 1890
- 0
teensy/pins_teensy.c
File diff suppressed because it is too large
View File


+ 15
- 0
teensy/usb.c View File

@@ -0,0 +1,15 @@
#if defined(USB_SERIAL)
#include "../usb_serial/usb.c"
#elif defined(USB_HID)
#include "../usb_hid/usb.c"
#elif defined(USB_SERIAL_HID)
#include "../usb_serial_hid/usb.c"
#elif defined(USB_DISK) || defined(USB_DISK_SDFLASH)
#include "../usb_disk/usb.c"
#elif defined(USB_MIDI)
#include "../usb_midi/usb.c"
#elif defined(USB_RAWHID)
#include "../usb_rawhid/usb.c"
#elif defined(USB_FLIGHTSIM)
#include "../usb_flightsim/usb.c"
#endif

+ 15
- 0
teensy/usb_api.cpp View File

@@ -0,0 +1,15 @@
#if defined(USB_SERIAL)
#include "../usb_serial/usb_api.cpp"
#elif defined(USB_HID)
#include "../usb_hid/usb_api.cpp"
#elif defined(USB_SERIAL_HID)
#include "../usb_serial_hid/usb_api.cpp"
#elif defined(USB_DISK) || defined(USB_DISK_SDFLASH)
#include "../usb_disk/usb_api.cpp"
#elif defined(USB_MIDI)
#include "../usb_midi/usb_api.cpp"
#elif defined(USB_RAWHID)
#include "../usb_rawhid/usb_api.cpp"
#elif defined(USB_FLIGHTSIM)
#include "../usb_flightsim/usb_api.cpp"
#endif

+ 15
- 0
teensy/usb_api.h View File

@@ -0,0 +1,15 @@
#if defined(USB_SERIAL)
#include "../usb_serial/usb_api.h"
#elif defined(USB_HID)
#include "../usb_hid/usb_api.h"
#elif defined(USB_SERIAL_HID)
#include "../usb_serial_hid/usb_api.h"
#elif defined(USB_DISK) || defined(USB_DISK_SDFLASH)
#include "../usb_disk/usb_api.h"
#elif defined(USB_MIDI)
#include "../usb_midi/usb_api.h"
#elif defined(USB_RAWHID)
#include "../usb_rawhid/usb_api.h"
#elif defined(USB_FLIGHTSIM)
#include "../usb_flightsim/usb_api.h"
#endif

+ 153
- 0
teensy/usb_common.h View File

@@ -0,0 +1,153 @@
#ifndef usb_common_h__
#define usb_common_h__

#include <stdint.h>
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>

#ifdef __cplusplus
extern "C"{
#endif

#define MAX_ENDPOINT 6

#define LSB(n) (n & 255)
#define MSB(n) ((n >> 8) & 255)


// constants corresponding to the various serial parameters
#define USB_SERIAL_DTR 0x01
#define USB_SERIAL_RTS 0x02
#define USB_SERIAL_1_STOP 0
#define USB_SERIAL_1_5_STOP 1
#define USB_SERIAL_2_STOP 2
#define USB_SERIAL_PARITY_NONE 0
#define USB_SERIAL_PARITY_ODD 1
#define USB_SERIAL_PARITY_EVEN 2
#define USB_SERIAL_PARITY_MARK 3
#define USB_SERIAL_PARITY_SPACE 4
#define USB_SERIAL_DCD 0x01
#define USB_SERIAL_DSR 0x02
#define USB_SERIAL_BREAK 0x04
#define USB_SERIAL_RI 0x08
#define USB_SERIAL_FRAME_ERR 0x10
#define USB_SERIAL_PARITY_ERR 0x20
#define USB_SERIAL_OVERRUN_ERR 0x40

#define EP_TYPE_CONTROL 0x00
#define EP_TYPE_BULK_IN 0x81
#define EP_TYPE_BULK_OUT 0x80
#define EP_TYPE_INTERRUPT_IN 0xC1
#define EP_TYPE_INTERRUPT_OUT 0xC0
#define EP_TYPE_ISOCHRONOUS_IN 0x41
#define EP_TYPE_ISOCHRONOUS_OUT 0x40
#define EP_SINGLE_BUFFER 0x02
#define EP_DOUBLE_BUFFER 0x06
#define EP_SIZE(s) ((s) == 64 ? 0x30 : \
((s) == 32 ? 0x20 : \
((s) == 16 ? 0x10 : \
0x00)))

#if defined(__AVR_AT90USB162__)
#define HW_CONFIG()
#define PLL_CONFIG() (PLLCSR = ((1<<PLLE)|(1<<PLLP0)))
#define USB_CONFIG() (USBCON = (1<<USBE))
#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
#elif defined(__AVR_ATmega32U4__)
#define HW_CONFIG() (UHWCON = 0x01)
#define PLL_CONFIG() (PLLCSR = 0x12)
#define USB_CONFIG() (USBCON = ((1<<USBE)|(1<<OTGPADE)))
#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
#elif defined(__AVR_AT90USB646__)
#define HW_CONFIG() (UHWCON = 0x81)
#define PLL_CONFIG() (PLLCSR = 0x1A)
#define USB_CONFIG() (USBCON = ((1<<USBE)|(1<<OTGPADE)))
#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
#elif defined(__AVR_AT90USB1286__)
#define HW_CONFIG() (UHWCON = 0x81)
#define PLL_CONFIG() (PLLCSR = 0x16)
#define USB_CONFIG() (USBCON = ((1<<USBE)|(1<<OTGPADE)))
#define USB_FREEZE() (USBCON = ((1<<USBE)|(1<<FRZCLK)))
#endif

// standard control endpoint request types
#define GET_STATUS 0
#define CLEAR_FEATURE 1
#define SET_FEATURE 3
#define SET_ADDRESS 5
#define GET_DESCRIPTOR 6
#define GET_CONFIGURATION 8
#define SET_CONFIGURATION 9
#define GET_INTERFACE 10
#define SET_INTERFACE 11
// CDC (communication class device)
#define CDC_SET_LINE_CODING 0x20
#define CDC_GET_LINE_CODING 0x21
#define CDC_SET_CONTROL_LINE_STATE 0x22
#define CDC_SEND_BREAK 0x23
// HID (human interface device)
#define HID_GET_REPORT 1
#define HID_GET_IDLE 2
#define HID_GET_PROTOCOL 3
#define HID_SET_REPORT 9
#define HID_SET_IDLE 10
#define HID_SET_PROTOCOL 11
// Mass Storage
#define MS_BULK_ONLY_RESET 0xFF
#define MS_GET_MAX_LUN 0xFE /* stall = 0 */


#define pgm_read_byte_postinc(val, addr) \
asm ("lpm %0, Z+\n" : "=r" (val), "+z" (addr) : )
#define pgm_read_word_postinc(val, addr) \
asm ("lpm %A0, Z+\n\tlpm %B0, Z+\n" : "=r" (val), "+z" (addr) : )

#define read_word_lsbfirst(val, reg) \
asm volatile( \
"lds %A0, %1\n\tlds %B0, %1\n" \
: "=r" (val) : "M" ((int)(&reg)) )
#define read_word_msbfirst(val, reg) \
asm volatile( \
"lds %B0, %1\n\tlds %A0, %1\n" \
: "=r" (val) : "M" ((int)(&reg)) )
#define read_dword_lsbfirst(val, reg) \
asm volatile( \
"lds %A0, %1\n\tlds %B0, %1\n\t" \
"lds %C0, %1\n\tlds %D0, %1\n" \
: "=r" (val) : "M" ((int)(&reg)) )
#define read_dword_msbfirst(val, reg) \
asm volatile( \
"lds %D0, %1\n\tlds %C0, %1\n\t" \
"lds %B0, %1\n\tlds %A0, %1\n" \
: "=r" (val) : "M" ((int)(&reg)) )

#define write_word_lsbfirst(val, reg) \
asm volatile( \
"sts %1, %A0\n\tsts %1, %B0\n" \
: : "r" (val) , "M" ((int)(&reg)) )
#define write_word_msbfirst(val, reg) \
asm volatile( \
"sts %1, %B0\n\tsts %1, %A0\n" \
: : "r" (val) , "M" ((int)(&reg)) )
#define write_dword_lsbfirst(val, reg) \
asm volatile( \
"sts %1, %A0\n\tsts %1, %B0\n\t" \
"sts %1, %C0\n\tsts %1, %D0\n" \
: : "r" (val) , "M" ((int)(&reg)) )
#define write_dword_msbfirst(val, reg) \
asm volatile( \
"sts %1, %D0\n\tsts %1, %C0\n\t" \
"sts %1, %B0\n\tsts %1, %A0\n" \
: : "r" (val) , "M" ((int)(&reg)) )

#define USBSTATE __attribute__ ((section (".noinit")))

extern void _reboot_Teensyduino_(void) __attribute__((noreturn));
extern void _restart_Teensyduino_(void) __attribute__((noreturn));

#ifdef __cplusplus
} // extern "C"
#endif
#endif


+ 15
- 0
teensy/usb_private.h View File

@@ -0,0 +1,15 @@
#if defined(USB_SERIAL)
#include "../usb_serial/usb_private.h"
#elif defined(USB_HID)
#include "../usb_hid/usb_private.h"
#elif defined(USB_SERIAL_HID)
#include "../usb_serial_hid/usb_private.h"
#elif defined(USB_DISK) || defined(USB_DISK_SDFLASH)
#include "../usb_disk/usb_private.h"
#elif defined(USB_MIDI)
#include "../usb_midi/usb_private.h"
#elif defined(USB_RAWHID)
#include "../usb_rawhid/usb_private.h"
#elif defined(USB_FLIGHTSIM)
#include "../usb_flightsim/usb_private.h"
#endif

+ 80
- 0
teensy/wiring.c View File

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

Modified for Teensyduino by Paul Stoffregen, paul@pjrc.com
http://www.pjrc.com/teensy/teensyduino.html

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
*/

#include "wiring_private.h"
#include "pins_arduino.h"
#include "core_pins.h"


#define PULSEIN_CYCLES_PER_LOOP 21
#define PULSEIN_CYCLES_LATENCY 11

/* 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);
volatile uint8_t *reg = portInputRegister(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
unsigned long numloops = 0;
//unsigned long maxloops = microsecondsToClockCycles(timeout) / PULSEIN_CYCLES_PER_LOOP;
unsigned long maxloops = timeout * clockCyclesPerMicrosecond() / PULSEIN_CYCLES_PER_LOOP;

// wait for any previous pulse to end
while ((*reg & bit) == stateMask)
if (numloops++ == maxloops)
return 0;
// wait for the pulse to start
while ((*reg & bit) != stateMask)
if (numloops++ == maxloops)
return 0;
// wait for the pulse to stop
while ((*reg & bit) == stateMask) {
width++;
if (numloops++ == maxloops)
return 0;
}

// convert the reading to microseconds. The loop has been determined
// to be PULSEIN_CYCLES_LATENCY clock cycles long and have about
// PULSEIN_CYCLES_PER_LOOP clocks between the edge and the start of
// the loop. There will be some error introduced by the interrupt
// handlers.
//return clockCyclesToMicroseconds(PULSEIN_CYCLES_PER_LOOP * width + PULSEIN_CYCLES_LATENCY);
return (width * PULSEIN_CYCLES_PER_LOOP + PULSEIN_CYCLES_LATENCY + (clockCyclesPerMicrosecond() / 2)) / clockCyclesPerMicrosecond();
}



+ 112
- 0
teensy/wiring.h View File

@@ -0,0 +1,112 @@
/*
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 387 2008-03-08 21:30:00Z mellis $
*/

#ifndef Wiring_h
#define Wiring_h

#include <avr/io.h>
#include <stdlib.h>
#include <math.h>
#include "binary.h"
#include "core_id.h"
#include "core_pins.h"
#ifdef ID
#undef ID // ID bit in USBSTA conflicts with user's code
#endif

#ifdef __cplusplus
extern "C"{
#endif

#define true 1
#define false 0

#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 0
#define DISPLAY 1

#define CHANGE 1
#define FALLING 2
#define RISING 3

#define INTERNAL 3
#define INTERNAL2V56 3
#define DEFAULT 1
#define EXTERNAL 0

// 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)))
#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
#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) / clockCyclesPerMicrosecond() )
#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() )

#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;

unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout);
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, byte val);

void attachInterrupt(uint8_t, void (*)(void), uint8_t mode);
void detachInterrupt(uint8_t);

void setup(void);
void loop(void);

#ifdef __cplusplus
} // extern "C"
#endif

#endif

+ 72
- 0
teensy/wiring_private.h View File

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

#ifndef WiringPrivate_h
#define WiringPrivate_h

#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdio.h>
#include <stdarg.h>

#include "wiring.h"

#if F_CPU == 16000000L
#define ADC_PRESCALER 0x07
#define CPU_PRESCALER 0x00
#elif F_CPU == 8000000L
#define ADC_PRESCALER 0x06
#define CPU_PRESCALER 0x01
#elif F_CPU == 4000000L
#define ADC_PRESCALER 0x05
#define CPU_PRESCALER 0x02
#elif F_CPU == 2000000L
#define ADC_PRESCALER 0x04
#define CPU_PRESCALER 0x03
#elif F_CPU == 1000000L
#define ADC_PRESCALER 0x03
#define CPU_PRESCALER 0x04
#else
#error "Teensyduino only supports 16, 8, 4, 2, 1 MHz. Please edit boards.txt"
#endif


#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

typedef void (*voidFuncPtr)(void);

#ifdef __cplusplus
} // extern "C"
#endif

#endif

+ 2
- 0
teensy3/Arduino.h View File

@@ -0,0 +1,2 @@
#include "WProgram.h"
#include "pins_arduino.h"

+ 213
- 0
teensy3/AudioStream.cpp View File

@@ -0,0 +1,213 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2013 PJRC.COM, LLC.
*
* 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:
*
* 1. The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* 2. If the Software is incorporated into a build system that allows
* selection among a list of target devices, then similar target
* devices manufactured by PJRC.COM must be included in the list of
* target devices and selectable in the same manner.
*
* 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.
*/


#include "AudioStream.h"


audio_block_t * AudioStream::memory_pool;
uint8_t AudioStream::memory_pool_size = 0;
uint32_t AudioStream::memory_pool_available_mask;

uint16_t AudioStream::cpu_cycles_total = 0;
uint16_t AudioStream::cpu_cycles_total_max = 0;
uint8_t AudioStream::memory_used = 0;
uint8_t AudioStream::memory_used_max = 0;



// Set up the pool of audio data blocks
// placing them all onto the free list
void AudioStream::initialize_memory(audio_block_t *data, unsigned int num)
{
//Serial.println("AudioStream initialize_memory");
memory_pool = data;
if (num > 31) num = 31;
memory_pool_size = num;
memory_pool_available_mask = 0xFFFFFFFF;
for (unsigned int i=0; i < num; i++) {
data[i].memory_pool_index = i;
}
}

// Allocate 1 audio data block. If successful
// the caller is the only owner of this new block
audio_block_t * AudioStream::allocate(void)
{
uint32_t n, avail;
audio_block_t *block;
uint8_t used;

__disable_irq();
avail = memory_pool_available_mask;
n = __builtin_clz(avail);
if (n >= memory_pool_size) {
__enable_irq();
return NULL;
}
memory_pool_available_mask = avail & ~(0x80000000 >> n);
used = memory_used + 1;
memory_used = used;
__enable_irq();
block = memory_pool + n;
block->ref_count = 1;
if (used > memory_used_max) memory_used_max = used;
return block;
}

// Release ownership of a data block. If no
// other streams have ownership, the block is
// returned to the free pool
void AudioStream::release(audio_block_t *block)
{
uint32_t mask = (0x80000000 >> block->memory_pool_index);
__disable_irq();
if (block->ref_count > 1) {
block->ref_count--;
} else {
memory_pool_available_mask |= mask;
memory_used--;
}
__enable_irq();
}

// Transmit an audio data block
// to all streams that connect to an output. The block
// becomes owned by all the recepients, but also is still
// owned by this object. Normally, a block is released
// after it's transmitted.
void AudioStream::transmit(audio_block_t *block, unsigned char index)
{
for (AudioConnection *c = destination_list; c != NULL; c = c->next_dest) {
if (c->src_index == index) {
if (c->dst.inputQueue[c->dest_index] == NULL) {
c->dst.inputQueue[c->dest_index] = block;
block->ref_count++;
}
}
}
}


// Receive block from an input. The block's data
// may be shared with other streams, so it must not be written
audio_block_t * AudioStream::receiveReadOnly(unsigned int index)
{
audio_block_t *in;

if (index >= num_inputs) return NULL;
in = inputQueue[index];
inputQueue[index] = NULL;
return in;
}

// Receive block from an input. The block will not
// be shared, so its contents may be changed.
audio_block_t * AudioStream::receiveWritable(unsigned int index)
{
audio_block_t *in, *p;

if (index >= num_inputs) return NULL;
in = inputQueue[index];
inputQueue[index] = NULL;
if (in && in->ref_count > 1) {
p = allocate();
if (p) memcpy(p->data, in->data, sizeof(p->data));
in->ref_count--;
in = p;
}
return in;
}


void AudioConnection::connect(void)
{
AudioConnection *p;

if (dest_index > dst.num_inputs) return;
__disable_irq();
p = src.destination_list;
if (p == NULL) {
src.destination_list = this;
} else {
while (p->next_dest) p = p->next_dest;
p->next_dest = this;
}
src.active = true;
dst.active = true;
__enable_irq();
}



// When an object has taken responsibility for calling update_all()
// at each block interval (approx 2.9ms), this variable is set to
// true. Objects that are capable of calling update_all(), typically
// input and output based on interrupts, must check this variable in
// their constructors.
bool AudioStream::update_scheduled = false;

bool AudioStream::update_setup(void)
{
if (update_scheduled) return false;
NVIC_SET_PRIORITY(IRQ_SOFTWARE, 0xFF); // 0xFF = lowest priority
NVIC_ENABLE_IRQ(IRQ_SOFTWARE);
update_scheduled = true;
return true;
}

AudioStream * AudioStream::first_update = NULL;

void software_isr(void) // AudioStream::update_all()
{
AudioStream *p;

ARM_DEMCR |= ARM_DEMCR_TRCENA;
ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;
uint32_t totalcycles = ARM_DWT_CYCCNT;
//digitalWriteFast(2, HIGH);
for (p = AudioStream::first_update; p; p = p->next_update) {
if (p->active) {
uint32_t cycles = ARM_DWT_CYCCNT;
p->update();
// TODO: traverse inputQueueArray and release
// any input blocks that weren't consumed?
cycles = (ARM_DWT_CYCCNT - cycles) >> 4;
p->cpu_cycles = cycles;
if (cycles > p->cpu_cycles_max) p->cpu_cycles_max = cycles;
}
}
//digitalWriteFast(2, LOW);
totalcycles = (ARM_DWT_CYCCNT - totalcycles) >> 4;;
AudioStream::cpu_cycles_total = totalcycles;
if (totalcycles > AudioStream::cpu_cycles_total_max)
AudioStream::cpu_cycles_total_max = totalcycles;
}


+ 147
- 0
teensy3/AudioStream.h View File

@@ -0,0 +1,147 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2013 PJRC.COM, LLC.
*
* 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:
*
* 1. The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* 2. If the Software is incorporated into a build system that allows
* selection among a list of target devices, then similar target
* devices manufactured by PJRC.COM must be included in the list of
* target devices and selectable in the same manner.
*
* 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.
*/

#ifndef AudioStream_h
#define AudioStream_h

#include "Arduino.h"

#define AUDIO_BLOCK_SAMPLES 128
#define AUDIO_SAMPLE_RATE 44100
#define AUDIO_SAMPLE_RATE_EXACT 44117.64706 // 48 MHz / 1088, or 96 MHz * 2 / 17 / 256

class AudioStream;
class AudioConnection;

typedef struct audio_block_struct {
unsigned char ref_count;
unsigned char memory_pool_index;
int16_t data[AUDIO_BLOCK_SAMPLES];
} audio_block_t;


class AudioConnection
{
public:
AudioConnection(AudioStream &source, AudioStream &destination) :
src(source), dst(destination), src_index(0), dest_index(0),
next_dest(NULL)
{ connect(); }
AudioConnection(AudioStream &source, unsigned char sourceOutput,
AudioStream &destination, unsigned char destinationInput) :
src(source), dst(destination),
src_index(sourceOutput), dest_index(destinationInput),
next_dest(NULL)
{ connect(); }
friend class AudioStream;
protected:
void connect(void);
AudioStream &src;
AudioStream &dst;
unsigned char src_index;
unsigned char dest_index;
AudioConnection *next_dest;
};


#define AudioMemory(num) ({ \
static DMAMEM audio_block_t data[num]; \
AudioStream::initialize_memory(data, num); \
})

#define CYCLE_COUNTER_APPROX_PERCENT(n) (((n) + (F_CPU / 32 / AUDIO_SAMPLE_RATE * AUDIO_BLOCK_SAMPLES / 100)) / (F_CPU / 16 / AUDIO_SAMPLE_RATE * AUDIO_BLOCK_SAMPLES / 100))

#define AudioProcessorUsage() (CYCLE_COUNTER_APPROX_PERCENT(AudioStream::cpu_cycles_total))
#define AudioProcessorUsageMax() (CYCLE_COUNTER_APPROX_PERCENT(AudioStream::cpu_cycles_total_max))
#define AudioProcessorUsageMaxReset() (AudioStream::cpu_cycles_total_max = AudioStream::cpu_cycles_total)
#define AudioMemoryUsage() (AudioStream::memory_used)
#define AudioMemoryUsageMax() (AudioStream::memory_used_max)
#define AudioMemoryUsageMaxReset() (AudioStream::memory_used_max = AudioStream::memory_used)

class AudioStream
{
public:
AudioStream(unsigned char ninput, audio_block_t **iqueue) :
num_inputs(ninput), inputQueue(iqueue) {
active = false;
destination_list = NULL;
for (int i=0; i < num_inputs; i++) {
inputQueue[i] = NULL;
}
// add to a simple list, for update_all
// TODO: replace with a proper data flow analysis in update_all
if (first_update == NULL) {
first_update = this;
} else {
AudioStream *p;
for (p=first_update; p->next_update; p = p->next_update) ;
p->next_update = this;
}
next_update = NULL;
cpu_cycles = 0;
cpu_cycles_max = 0;
}
void connect(AudioStream &dest, unsigned char dest_index = 0, unsigned int src_index = 0);
void disconnect(void);
static void initialize_memory(audio_block_t *data, unsigned int num);
int processorUsage(void) { return CYCLE_COUNTER_APPROX_PERCENT(cpu_cycles); }
int processorUsageMax(void) { return CYCLE_COUNTER_APPROX_PERCENT(cpu_cycles_max); }
void processorUsageMaxReset(void) { cpu_cycles_max = cpu_cycles; }
uint16_t cpu_cycles;
uint16_t cpu_cycles_max;
static uint16_t cpu_cycles_total;
static uint16_t cpu_cycles_total_max;
static uint8_t memory_used;
static uint8_t memory_used_max;
protected:
bool active;
unsigned char num_inputs;
static audio_block_t * allocate(void);
static void release(audio_block_t * block);
void transmit(audio_block_t *block, unsigned char index = 0);
audio_block_t * receiveReadOnly(unsigned int index = 0);
audio_block_t * receiveWritable(unsigned int index = 0);
static bool update_setup(void);
static void update_all(void) { NVIC_SET_PENDING(IRQ_SOFTWARE); }
friend void software_isr(void);
friend class AudioConnection;
private:
AudioConnection *destination_list;
audio_block_t **inputQueue;
static bool update_scheduled;
virtual void update(void) = 0;
static AudioStream *first_update; // for update_all
AudioStream *next_update; // for update_all
static audio_block_t *memory_pool;
static uint8_t memory_pool_size;
static uint32_t memory_pool_available_mask;
};

#endif

+ 29
- 0
teensy3/Client.h View File

@@ -0,0 +1,29 @@
#if ARDUINO >= 100

#ifndef client_h
#define client_h
#include "Print.h"
#include "Stream.h"
#include "IPAddress.h"

class Client : public Stream {

public:
virtual int connect(IPAddress ip, uint16_t port) =0;
virtual int connect(const char *host, uint16_t port) =0;
virtual size_t write(uint8_t) =0;
virtual size_t write(const uint8_t *buf, size_t size) =0;
virtual int available() = 0;
virtual int read() = 0;
virtual int read(uint8_t *buf, size_t size) = 0;
virtual int peek() = 0;
virtual void flush() = 0;
virtual void stop() = 0;
virtual uint8_t connected() = 0;
virtual operator bool() = 0;
protected:
uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); };
};

#endif
#endif

+ 158
- 0
teensy3/HardwareSerial.h View File

@@ -0,0 +1,158 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2013 PJRC.COM, LLC.
*
* 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:
*
* 1. The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* 2. If the Software is incorporated into a build system that allows
* selection among a list of target devices, then similar target
* devices manufactured by PJRC.COM must be included in the list of
* target devices and selectable in the same manner.
*
* 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.
*/

#ifndef HardwareSerial_h
#define HardwareSerial_h

#include "mk20dx128.h"
#include <inttypes.h>

#define BAUD2DIV(baud) (((F_CPU * 2) + ((baud) >> 1)) / (baud))
#define BAUD2DIV3(baud) (((F_BUS * 2) + ((baud) >> 1)) / (baud))

// C language implementation
//
#ifdef __cplusplus
extern "C" {
#endif
void serial_begin(uint32_t divisor);
void serial_end(void);
void serial_putchar(uint8_t c);
void serial_write(const void *buf, unsigned int count);
void serial_flush(void);
int serial_available(void);
int serial_getchar(void);
int serial_peek(void);
void serial_clear(void);
void serial_print(const char *p);
void serial_phex(uint32_t n);
void serial_phex16(uint32_t n);
void serial_phex32(uint32_t n);

void serial2_begin(uint32_t divisor);
void serial2_end(void);
void serial2_putchar(uint8_t c);
void serial2_write(const void *buf, unsigned int count);
void serial2_flush(void);
int serial2_available(void);
int serial2_getchar(void);
int serial2_peek(void);
void serial2_clear(void);

void serial3_begin(uint32_t divisor);
void serial3_end(void);
void serial3_putchar(uint8_t c);
void serial3_write(const void *buf, unsigned int count);
void serial3_flush(void);
int serial3_available(void);
int serial3_getchar(void);
int serial3_peek(void);
void serial3_clear(void);

#ifdef __cplusplus
}
#endif


// C++ interface
//
#ifdef __cplusplus
#include "Stream.h"
class HardwareSerial : public Stream
{
public:
void begin(uint32_t baud) { serial_begin(BAUD2DIV(baud)); }
void end(void) { serial_end(); }
virtual int available(void) { return serial_available(); }
virtual int peek(void) { return serial_peek(); }
virtual int read(void) { return serial_getchar(); }
virtual void flush(void) { serial_flush(); }
void clear(void) { serial_clear(); }
virtual size_t write(uint8_t c) { serial_putchar(c); return 1; }
size_t write(unsigned long n) { return write((uint8_t)n); }
size_t write(long n) { return write((uint8_t)n); }
size_t write(unsigned int n) { return write((uint8_t)n); }
size_t write(int n) { return write((uint8_t)n); }
virtual size_t write(const uint8_t *buffer, size_t size)
{ serial_write(buffer, size); return size; }
size_t write(const char *str) { size_t len = strlen(str);
serial_write((const uint8_t *)str, len);
return len; }
};
extern HardwareSerial Serial1;

class HardwareSerial2 : public HardwareSerial
{
public:
void begin(uint32_t baud) { serial2_begin(BAUD2DIV(baud)); }
void end(void) { serial2_end(); }
virtual int available(void) { return serial2_available(); }
virtual int peek(void) { return serial2_peek(); }
virtual int read(void) { return serial2_getchar(); }
virtual void flush(void) { serial2_flush(); }
void clear(void) { serial2_clear(); }
virtual size_t write(uint8_t c) { serial2_putchar(c); return 1; }
size_t write(unsigned long n) { return write((uint8_t)n); }
size_t write(long n) { return write((uint8_t)n); }
size_t write(unsigned int n) { return write((uint8_t)n); }
size_t write(int n) { return write((uint8_t)n); }
virtual size_t write(const uint8_t *buffer, size_t size)
{ serial2_write(buffer, size); return size; }
size_t write(const char *str) { size_t len = strlen(str);
serial2_write((const uint8_t *)str, len);
return len; }
};
extern HardwareSerial2 Serial2;

class HardwareSerial3 : public HardwareSerial
{
public:
void begin(uint32_t baud) { serial3_begin(BAUD2DIV3(baud)); }
void end(void) { serial3_end(); }
virtual int available(void) { return serial3_available(); }
virtual int peek(void) { return serial3_peek(); }
virtual int read(void) { return serial3_getchar(); }
virtual void flush(void) { serial3_flush(); }
void clear(void) { serial3_clear(); }
virtual size_t write(uint8_t c) { serial3_putchar(c); return 1; }
size_t write(unsigned long n) { return write((uint8_t)n); }
size_t write(long n) { return write((uint8_t)n); }
size_t write(unsigned int n) { return write((uint8_t)n); }
size_t write(int n) { return write((uint8_t)n); }
virtual size_t write(const uint8_t *buffer, size_t size)
{ serial3_write(buffer, size); return size; }
size_t write(const char *str) { size_t len = strlen(str);
serial3_write((const uint8_t *)str, len);
return len; }
};
extern HardwareSerial3 Serial3;

#endif
#endif

+ 4
- 0
teensy3/HardwareSerial1.cpp View File

@@ -0,0 +1,4 @@
#include "HardwareSerial.h"

HardwareSerial Serial1;


+ 4
- 0
teensy3/HardwareSerial2.cpp View File

@@ -0,0 +1,4 @@
#include "HardwareSerial.h"

HardwareSerial2 Serial2;


+ 4
- 0
teensy3/HardwareSerial3.cpp View File

@@ -0,0 +1,4 @@
#include "HardwareSerial.h"

HardwareSerial3 Serial3;


+ 57
- 0
teensy3/IPAddress.cpp View File

@@ -0,0 +1,57 @@
#if ARDUINO >= 100
#include "Arduino.h"
#include "IPAddress.h"

IPAddress::IPAddress()
{
memset(_address, 0, sizeof(_address));
}

IPAddress::IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet)
{
_address[0] = first_octet;
_address[1] = second_octet;
_address[2] = third_octet;
_address[3] = fourth_octet;
}

IPAddress::IPAddress(uint32_t address)
{
memcpy(_address, &address, sizeof(_address));
}

IPAddress::IPAddress(const uint8_t *address)
{
memcpy(_address, address, sizeof(_address));
}

IPAddress& IPAddress::operator=(const uint8_t *address)
{
memcpy(_address, address, sizeof(_address));
return *this;
}

IPAddress& IPAddress::operator=(uint32_t address)
{
memcpy(_address, (const uint8_t *)&address, sizeof(_address));
return *this;
}

bool IPAddress::operator==(const uint8_t* addr)
{
return memcmp(addr, _address, sizeof(_address)) == 0;
}

size_t IPAddress::printTo(Print& p) const
{
size_t n = 0;
for (int i =0; i < 3; i++)
{
n += p.print(_address[i], DEC);
n += p.print('.');
}
n += p.print(_address[3], DEC);
return n;
}

#endif

+ 82
- 0
teensy3/IPAddress.h View File

@@ -0,0 +1,82 @@
/*
*
* MIT License:
* Copyright (c) 2011 Adrian McEwen
* 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.
*
* adrianm@mcqn.com 1/1/2011
*/

#if ARDUINO >= 100
#ifndef IPAddress_h
#define IPAddress_h

#include <Printable.h>

// A class to make it easier to handle and pass around IP addresses

class IPAddress : public Printable {
private:
uint8_t _address[4]; // IPv4 address
// Access the raw byte array containing the address. Because this returns a pointer
// to the internal structure rather than a copy of the address this function should only
// be used when you know that the usage of the returned uint8_t* will be transient and not
// stored.
uint8_t* raw_address() { return _address; };

public:
// Constructors
IPAddress();
IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet);
IPAddress(uint32_t address);
IPAddress(const uint8_t *address);

// Overloaded cast operator to allow IPAddress objects to be used where a pointer
// to a four-byte uint8_t array is expected
operator uint32_t () { return _address[0] | (_address[1] << 8)
| (_address[2] << 16) | (_address[3] << 24); }
bool operator==(const IPAddress& addr) { return _address[0] == addr._address[0]
&& _address[1] == addr._address[1]
&& _address[2] == addr._address[2]
&& _address[3] == addr._address[3]; }
bool operator==(const uint8_t* addr);

// Overloaded index operator to allow getting and setting individual octets of the address
uint8_t operator[](int index) const { return _address[index]; };
uint8_t& operator[](int index) { return _address[index]; };

// Overloaded copy operators to allow initialisation of IPAddress objects from other types
IPAddress& operator=(const uint8_t *address);
IPAddress& operator=(uint32_t address);

virtual size_t printTo(Print& p) const;

friend class EthernetClass;
friend class UDP;
friend class Client;
friend class Server;
friend class DhcpClass;
friend class DNSClient;
};

const IPAddress INADDR_NONE(0,0,0,0);


#endif
#endif

+ 185
- 0
teensy3/IntervalTimer.cpp View File

@@ -0,0 +1,185 @@
/* Copyright (c) 2013 Daniel Gilbert, loglow@gmail.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. */


#include "IntervalTimer.h"


// ------------------------------------------------------------
// static class variables need to be reiterated here before use
// ------------------------------------------------------------
bool IntervalTimer::PIT_enabled;
bool IntervalTimer::PIT_used[];
IntervalTimer::ISR IntervalTimer::PIT_ISR[];



// ------------------------------------------------------------
// these are the ISRs (Interrupt Service Routines) that get
// called by each PIT timer when it fires. they're defined here
// so that they can auto-clear themselves and so the user can
// specify a custom ISR and reassign it as needed
// ------------------------------------------------------------
void pit0_isr() { PIT_TFLG0 = 1; IntervalTimer::PIT_ISR[0](); }
void pit1_isr() { PIT_TFLG1 = 1; IntervalTimer::PIT_ISR[1](); }
void pit2_isr() { PIT_TFLG2 = 1; IntervalTimer::PIT_ISR[2](); }
void pit3_isr() { PIT_TFLG3 = 1; IntervalTimer::PIT_ISR[3](); }



// ------------------------------------------------------------
// this function inits and starts the timer, using the specified
// function as a callback and the period provided. must be passed
// the name of a function taking no arguments and returning void.
// make sure this function can complete within the time allowed.
// attempts to allocate a timer using available resources,
// returning true on success or false in case of failure.
// period is specified as number of bus cycles
// ------------------------------------------------------------
bool IntervalTimer::beginCycles(ISR newISR, uint32_t newValue) {

// if this interval timer is already running, stop it
if (status == TIMER_PIT) {
stop_PIT();
status = TIMER_OFF;
}
// store callback pointer
myISR = newISR;
// attempt to allocate this timer
if (allocate_PIT(newValue)) status = TIMER_PIT;
else status = TIMER_OFF;
// check for success and return
if (status != TIMER_OFF) return true;
return false;
}


// ------------------------------------------------------------
// stop the timer if it's currently running, using its status
// to determine what hardware resources the timer may be using
// ------------------------------------------------------------
void IntervalTimer::end() {
if (status == TIMER_PIT) stop_PIT();
status = TIMER_OFF;
}



// ------------------------------------------------------------
// enables the PIT clock bit, the master PIT reg, and sets flag
// ------------------------------------------------------------
void IntervalTimer::enable_PIT() {
SIM_SCGC6 |= SIM_SCGC6_PIT;
PIT_MCR = 0;
PIT_enabled = true;
}



// ------------------------------------------------------------
// disables the master PIT reg, the PIT clock bit, and unsets flag
// ------------------------------------------------------------
void IntervalTimer::disable_PIT() {
PIT_MCR = 1;
SIM_SCGC6 &= ~SIM_SCGC6_PIT;
PIT_enabled = false;
}



// ------------------------------------------------------------
// enables the PIT clock if not already enabled, then checks to
// see if any PITs are available for use. if one is available,
// it's initialized and started with the specified value, and
// the function returns true, otherwise it returns false
// ------------------------------------------------------------
bool IntervalTimer::allocate_PIT(uint32_t newValue) {
// enable clock to the PIT module if necessary
if (!PIT_enabled) enable_PIT();
// check for an available PIT, and if so, start it
for (uint8_t id = 0; id < NUM_PIT; id++) {
if (!PIT_used[id]) {
PIT_id = id;
start_PIT(newValue);
PIT_used[id] = true;
return true;
}
}
// no PIT available
return false;
}



// ------------------------------------------------------------
// configuters a PIT's registers, function pointer, and enables
// interrupts, effectively starting the timer upon completion
// ------------------------------------------------------------
void IntervalTimer::start_PIT(uint32_t newValue) {
// point to the correct registers
PIT_LDVAL = &PIT_LDVAL0 + PIT_id * 4;
PIT_TCTRL = &PIT_TCTRL0 + PIT_id * 4;
IRQ_PIT_CH = IRQ_PIT_CH0 + PIT_id;
// point to the correct PIT ISR
PIT_ISR[PIT_id] = myISR;
// write value to register and enable interrupt
*PIT_TCTRL = 0;
*PIT_LDVAL = newValue;
*PIT_TCTRL = 3;
NVIC_ENABLE_IRQ(IRQ_PIT_CH);

}



// ------------------------------------------------------------
// stops an active PIT by disabling its interrupt, writing to
// its control register, and freeing up its state for future use.
// also, if no PITs remain in use, disables the core PIT clock
// ------------------------------------------------------------
void IntervalTimer::stop_PIT() {
// disable interrupt and PIT
NVIC_DISABLE_IRQ(IRQ_PIT_CH);
*PIT_TCTRL = 0;
// free PIT for future use
PIT_used[PIT_id] = false;
// check if we're still using any PIT
for (uint8_t id = 0; id < NUM_PIT; id++) {
if (PIT_used[id]) return;
}
// none used, disable PIT clock
disable_PIT();
}



+ 88
- 0
teensy3/IntervalTimer.h View File

@@ -0,0 +1,88 @@
/* Copyright (c) 2013 Daniel Gilbert, loglow@gmail.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. */


#ifndef __INTERVALTIMER_H__
#define __INTERVALTIMER_H__

#include <stdint.h>
#include "mk20dx128.h"

#ifdef __cplusplus
extern "C" {
#endif

class IntervalTimer {
private:
typedef void (*ISR)();
typedef volatile uint32_t* reg;
enum {TIMER_OFF, TIMER_PIT};
static const uint8_t NUM_PIT = 4;
static const uint32_t MAX_PERIOD = UINT32_MAX / (F_BUS / 1000000.0);
static void enable_PIT();
static void disable_PIT();
static bool PIT_enabled;
static bool PIT_used[NUM_PIT];
bool allocate_PIT(uint32_t newValue);
void start_PIT(uint32_t newValue);
void stop_PIT();
bool status;
uint8_t PIT_id;
reg PIT_LDVAL;
reg PIT_TCTRL;
uint8_t IRQ_PIT_CH;
ISR myISR;
bool beginCycles(ISR newISR, uint32_t cycles);
public:
IntervalTimer() { status = TIMER_OFF; }
~IntervalTimer() { end(); }
bool begin(ISR newISR, unsigned int newPeriod) {
if (newPeriod == 0 || newPeriod > MAX_PERIOD) return false;
uint32_t newValue = (F_BUS / 1000000) * newPeriod - 1;
return beginCycles(newISR, newValue);
}
bool begin(ISR newISR, int newPeriod) {
if (newPeriod < 0) return false;
return begin(newISR, (unsigned int)newPeriod);
}
bool begin(ISR newISR, unsigned long newPeriod) {
return begin(newISR, (unsigned int)newPeriod);
}
bool begin(ISR newISR, long newPeriod) {
return begin(newISR, (int)newPeriod);
}
bool begin(ISR newISR, float newPeriod) {
if (newPeriod <= 0 || newPeriod > MAX_PERIOD) return false;
uint32_t newValue = (float)(F_BUS / 1000000) * newPeriod + 0.5;
if (newValue < 40) return false;
return beginCycles(newISR, newValue);
}
bool begin(ISR newISR, double newPeriod) {
return begin(newISR, (float)newPeriod);
}
void end();
static ISR PIT_ISR[NUM_PIT];
};


#ifdef __cplusplus
}
#endif

#endif

+ 81
- 0
teensy3/Makefile View File

@@ -0,0 +1,81 @@

# The name of your project (used to name the compiled .hex file)
TARGET = main

# configurable options
OPTIONS = -DF_CPU=48000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH

# options needed by many Arduino libraries to configure for Teensy 3.0
OPTIONS += -D__MK20DX128__ -DARDUIO=104


#************************************************************************
# Location of Teensyduino utilities, Toolchain, and Arduino Libraries.
# To use this makefile without Arduino, copy the resources from these
# locations and edit the pathnames. The rest of Arduino is not needed.
#************************************************************************

# path location for Teensy Loader, teensy_post_compile and teensy_reboot
TOOLSPATH = ../../../tools # on Linux
#TOOLSPATH = ../../../tools/avr/bin # on Mac or Windows

# path location for Arduino libraries (currently not used)
LIBRARYPATH = ../../../../libraries

# path location for the arm-none-eabi compiler
COMPILERPATH = ../../../tools/arm-none-eabi/bin

#************************************************************************
# Settings below this point usually do not need to be edited
#************************************************************************

# CPPFLAGS = compiler options for C and C++
CPPFLAGS = -Wall -g -Os -mcpu=cortex-m4 -mthumb -nostdlib -MMD $(OPTIONS) -I.

# compiler options for C++ only
CXXFLAGS = -std=gnu++0x -felide-constructors -fno-exceptions -fno-rtti

# compiler options for C only
CFLAGS =

# linker options
LDFLAGS = -Os -Wl,--gc-sections -mcpu=cortex-m4 -mthumb -Tmk20dx128.ld

# additional libraries to link
LIBS = -lm


# names for the compiler programs
CC = $(abspath $(COMPILERPATH))/arm-none-eabi-gcc
CXX = $(abspath $(COMPILERPATH))/arm-none-eabi-g++
OBJCOPY = $(abspath $(COMPILERPATH))/arm-none-eabi-objcopy
SIZE = $(abspath $(COMPILERPATH))/arm-none-eabi-size

# automatically create lists of the sources and objects
# TODO: this does not handle Arduino libraries yet...
C_FILES := $(wildcard *.c)
CPP_FILES := $(wildcard *.cpp)
OBJS := $(C_FILES:.c=.o) $(CPP_FILES:.cpp=.o)


# the actual makefile rules (all .o files built by GNU make's default implicit rules)

all: $(TARGET).hex

$(TARGET).elf: $(OBJS) mk20dx128.ld
$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)

%.hex: %.elf
$(SIZE) $<
$(OBJCOPY) -O ihex -R .eeprom $< $@
$(abspath $(TOOLSPATH))/teensy_post_compile -file=$(basename $@) -path=$(shell pwd) -tools=$(abspath $(TOOLSPATH))
-$(abspath $(TOOLSPATH))/teensy_reboot


# compiler generated dependency info
-include $(OBJS:.o=.d)

clean:
rm -f *.o *.d $(TARGET).elf $(TARGET).hex



+ 157
- 0
teensy3/Print.cpp View File

@@ -0,0 +1,157 @@
/*
Print.cpp - Base class that provides print() and println()
Copyright (c) 2008 David A. Mellis. All right reserved.
many modifications, by Paul Stoffregen <paul@pjrc.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Modified 23 November 2006 by David A. Mellis
*/

//#include <stdio.h>
//#include <string.h>
#include <inttypes.h>
//#include <math.h>
//#include <avr/pgmspace.h>
//#include "wiring.h"

#include "Print.h"



size_t Print::write(const uint8_t *buffer, size_t size)
{
size_t count = 0;
while (size--) count += write(*buffer++);
return count;
}


size_t Print::print(const String &s)
{
uint8_t buffer[33];
size_t count = 0;
unsigned int index = 0;
unsigned int len = s.length();
while (len > 0) {
s.getBytes(buffer, sizeof(buffer), index);
unsigned int nbytes = len;
if (nbytes > sizeof(buffer)-1) nbytes = sizeof(buffer)-1;
index += nbytes;
len -= nbytes;
count += write(buffer, nbytes);
}
return count;
}


size_t Print::print(long n)
{
uint8_t sign=0;

if (n < 0) {
sign = '-';
n = -n;
}
return printNumber(n, 10, sign);
}


size_t Print::println(void)
{
uint8_t buf[2]={'\r', '\n'};
return write(buf, 2);
}


size_t Print::printNumber(unsigned long n, uint8_t base, uint8_t sign)
{
uint8_t buf[34];
uint8_t digit, i;

// TODO: make these checks as inline, since base is
// almost always a constant. base = 0 (BYTE) should
// inline as a call directly to write()
if (base == 0) {
return write((uint8_t)n);
} else if (base == 1) {
base = 10;
}


if (n == 0) {
buf[sizeof(buf) - 1] = '0';
i = sizeof(buf) - 1;
} else {
i = sizeof(buf) - 1;
while (1) {
digit = n % base;
buf[i] = ((digit < 10) ? '0' + digit : 'A' + digit - 10);
n /= base;
if (n == 0) break;
i--;
}
}
if (sign) {
i--;
buf[i] = '-';
}
return write(buf + i, sizeof(buf) - i);
}


size_t Print::printFloat(double number, uint8_t digits)
{
uint8_t sign=0;
size_t count=0;

// Handle negative numbers
if (number < 0.0) {
sign = 1;
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 *= 0.1;
}
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;
count += printNumber(int_part, 10, sign);

// Print the decimal point, but only if there are digits beyond
if (digits > 0) {
uint8_t n, buf[8], count=1;
buf[0] = '.';

// Extract digits from the remainder one at a time
if (digits > sizeof(buf) - 1) digits = sizeof(buf) - 1;

while (digits-- > 0) {
remainder *= 10.0;
n = (uint8_t)(remainder);
buf[count++] = '0' + n;
remainder -= n;
}
count += write(buf, count);
}
return count;
}



+ 105
- 0
teensy3/Print.h View File

@@ -0,0 +1,105 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2013 PJRC.COM, LLC.
*
* 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:
*
* 1. The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* 2. If the Software is incorporated into a build system that allows
* selection among a list of target devices, then similar target
* devices manufactured by PJRC.COM must be included in the list of
* target devices and selectable in the same manner.
*
* 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.
*/

#ifndef Print_h
#define Print_h

#include <inttypes.h>
#include <stdio.h> // for size_t - gives sprintf and other stuff to all sketches & libs
#include "core_id.h"
#include "WString.h"
#include "Printable.h"

#define DEC 10
#define HEX 16
#define OCT 8
#define BIN 2
#define BYTE 0

class __FlashStringHelper;

class Print
{
public:
Print() : write_error(0) {}
virtual size_t write(uint8_t b) = 0;
size_t write(const char *str) { return write((const uint8_t *)str, strlen(str)); }
virtual size_t write(const uint8_t *buffer, size_t size);
size_t print(const String &s);
size_t print(char c) { return write((uint8_t)c); }
size_t print(const char s[]) { return write(s); }
size_t print(const __FlashStringHelper *f) { return write((const char *)f); }

size_t print(uint8_t b) { return printNumber(b, 10, 0); }
size_t print(int n) { return print((long)n); }
size_t print(unsigned int n) { return printNumber(n, 10, 0); }
size_t print(long n);
size_t print(unsigned long n) { return printNumber(n, 10, 0); }

size_t print(unsigned char n, int base) { return printNumber(n, base, 0); }
size_t print(int n, int base) { return (base == 10) ? print(n) : printNumber(n, base, 0); }
size_t print(unsigned int n, int base) { return printNumber(n, base, 0); }
size_t print(long n, int base) { return (base == 10) ? print(n) : printNumber(n, base, 0); }
size_t print(unsigned long n, int base) { return printNumber(n, base, 0); }

size_t print(double n, int digits = 2) { return printFloat(n, digits); }
size_t print(const Printable &obj) { return obj.printTo(*this); }
size_t println(void);
size_t println(const String &s) { return print(s) + println(); }
size_t println(char c) { return print(c) + println(); }
size_t println(const char s[]) { return print(s) + println(); }
size_t println(const __FlashStringHelper *f) { return print(f) + println(); }

size_t println(uint8_t b) { return print(b) + println(); }
size_t println(int n) { return print(n) + println(); }
size_t println(unsigned int n) { return print(n) + println(); }
size_t println(long n) { return print(n) + println(); }
size_t println(unsigned long n) { return print(n) + println(); }

size_t println(unsigned char n, int base) { return print(n, base) + println(); }
size_t println(int n, int base) { return print(n, base) + println(); }
size_t println(unsigned int n, int base) { return print(n, base) + println(); }
size_t println(long n, int base) { return print(n, base) + println(); }
size_t println(unsigned long n, int base) { return print(n, base) + println(); }

size_t println(double n, int digits = 2) { return print(n, digits) + println(); }
size_t println(const Printable &obj) { return obj.printTo(*this) + println(); }
int getWriteError() { return write_error; }
void clearWriteError() { setWriteError(0); }
size_t printNumber(unsigned long n, uint8_t base, uint8_t sign);
protected:
void setWriteError(int err = 1) { write_error = err; }
private:
char write_error;
size_t printFloat(double n, uint8_t digits);
};


#endif

+ 55
- 0
teensy3/Printable.h View File

@@ -0,0 +1,55 @@
/*
Printable.h - Interface class that allows printing of complex types
Copyright (c) 2011 Adrian McEwen. 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 Printable_h
#define Printable_h

#ifdef __cplusplus

#include <stdlib.h>

inline void * operator new(unsigned int size) __attribute__((always_inline, unused));
inline void * operator new(unsigned int size)
{
return malloc(size);
}

inline void operator delete(void * ptr) __attribute__((always_inline, unused));
inline void operator delete(void * ptr)
{
free(ptr);
}


class Print;

/** The Printable class provides a way for new classes to allow themselves to be printed.
By deriving from Printable and implementing the printTo method, it will then be possible
for users to print out instances of this class by passing them into the usual
Print::print and Print::println methods.
*/
class Printable
{
public:
virtual size_t printTo(Print& p) const = 0;
};


#endif
#endif

+ 12
- 0
teensy3/Server.h View File

@@ -0,0 +1,12 @@
#if ARDUINO >= 100

#ifndef server_h
#define server_h

class Server : public Print {
public:
virtual void begin() =0;
};

#endif
#endif

+ 312
- 0
teensy3/Stream.cpp View File

@@ -0,0 +1,312 @@
/*
Stream.cpp - adds parsing methods to Stream class
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

Created July 2011
parsing functions based on TextFinder library by Michael Margolis
*/

#include "Arduino.h"
#include "Stream.h"

#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait
#define NO_SKIP_CHAR 1 // a magic char not found in a valid ASCII numeric field

// private method to read stream with timeout
int Stream::timedRead()
{
int c;
unsigned long startMillis = millis();
do {
c = read();
if (c >= 0) return c;
yield();
} while(millis() - startMillis < _timeout);
return -1; // -1 indicates timeout
}

// private method to peek stream with timeout
int Stream::timedPeek()
{
int c;
unsigned long startMillis = millis();
do {
c = peek();
if (c >= 0) return c;
yield();
} while(millis() - startMillis < _timeout);
return -1; // -1 indicates timeout
}

// returns peek of the next digit in the stream or -1 if timeout
// discards non-numeric characters
int Stream::peekNextDigit()
{
int c;
while (1) {
c = timedPeek();
if (c < 0) return c; // timeout
if (c == '-') return c;
if (c >= '0' && c <= '9') return c;
read(); // discard non-numeric
}
}

// Public Methods
//////////////////////////////////////////////////////////////

void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait
{
_timeout = timeout;
}

// find returns true if the target string is found
bool Stream::find(char *target)
{
return findUntil(target, NULL);
}

// reads data from the stream until the target string of given length is found
// returns true if target string is found, false if timed out
bool Stream::find(char *target, size_t length)
{
return findUntil(target, length, NULL, 0);
}

// as find but search ends if the terminator string is found
bool Stream::findUntil(char *target, char *terminator)
{
return findUntil(target, strlen(target), terminator, strlen(terminator));
}

// reads data from the stream until the target string of the given length is found
// search terminated if the terminator string is found
// returns true if target string is found, false if terminated or timed out
bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen)
{
size_t index = 0; // maximum target string length is 64k bytes!
size_t termIndex = 0;
int c;

if( *target == 0)
return true; // return true if target is a null string
while( (c = timedRead()) > 0){
if( c == target[index]){
//////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1);
if(++index >= targetLen){ // return true if all chars in the target match
return true;
}
}
else{
index = 0; // reset index if any char does not match
}
if(termLen > 0 && c == terminator[termIndex]){
if(++termIndex >= termLen)
return false; // return false if terminate string found before target string
}
else
termIndex = 0;
}
return false;
}


// returns the first valid (long) integer value from the current position.
// initial characters that are not digits (or the minus sign) are skipped
// function is terminated by the first character that is not a digit.
long Stream::parseInt()
{
return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout)
}

// as above but a given skipChar is ignored
// this allows format characters (typically commas) in values to be ignored
long Stream::parseInt(char skipChar)
{
boolean isNegative = false;
long value = 0;
int c;

c = peekNextDigit();
// ignore non numeric leading characters
if(c < 0)
return 0; // zero returned if timeout

do{
if(c == skipChar)
; // ignore this charactor
else if(c == '-')
isNegative = true;
else if(c >= '0' && c <= '9') // is c a digit?
value = value * 10 + c - '0';
read(); // consume the character we got with peek
c = timedPeek();
}
while( (c >= '0' && c <= '9') || c == skipChar );

if(isNegative)
value = -value;
return value;
}


// as parseInt but returns a floating point value
float Stream::parseFloat()
{
return parseFloat(NO_SKIP_CHAR);
}

// as above but the given skipChar is ignored
// this allows format characters (typically commas) in values to be ignored
float Stream::parseFloat(char skipChar){
boolean isNegative = false;
boolean isFraction = false;
long value = 0;
char c;
float fraction = 1.0;

c = peekNextDigit();
// ignore non numeric leading characters
if(c < 0)
return 0; // zero returned if timeout

do{
if(c == skipChar)
; // ignore
else if(c == '-')
isNegative = true;
else if (c == '.')
isFraction = true;
else if(c >= '0' && c <= '9') { // is c a digit?
value = value * 10 + c - '0';
if(isFraction)
fraction *= 0.1;
}
read(); // consume the character we got with peek
c = timedPeek();
}
while( (c >= '0' && c <= '9') || c == '.' || c == skipChar );

if(isNegative)
value = -value;
if(isFraction)
return value * fraction;
else
return value;
}

// read characters from stream into buffer
// terminates if length characters have been read, or timeout (see setTimeout)
// returns the number of characters placed in the buffer
// the buffer is NOT null terminated.
//
size_t Stream::readBytes(char *buffer, size_t length)
{
size_t count = 0;
while (count < length) {
int c = timedRead();
if (c < 0) {
setReadError();
break;
}
*buffer++ = (char)c;
count++;
}
return count;
}


// as readBytes with terminator character
// terminates if length characters have been read, timeout, or if the terminator character detected
// returns the number of characters placed in the buffer (0 means no valid data found)

size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length)
{
if (length < 1) return 0;
length--;
size_t index = 0;
while (index < length) {
int c = timedRead();
if (c == terminator) break;
if (c < 0) {
setReadError();
break;
}
*buffer++ = (char)c;
index++;
}
*buffer = 0;
return index; // return number of characters, not including null terminator
}

String Stream::readString(size_t max)
{
String str;
size_t length = str.length();
while (length < max) {
int c = timedRead();
if (c < 0) {
setReadError();
break; // timeout
}
if (c == 0) break;
str += (char)c;
}
return str;
}

String Stream::readStringUntil(char terminator, size_t max)
{
String str;
size_t length = str.length();
while (length < max) {
int c = timedRead();
if (c < 0) {
setReadError();
break; // timeout
}
if (c == 0 || c == terminator) break;
str += (char)c;
}
return str;
}



























+ 60
- 0
teensy3/Stream.h View File

@@ -0,0 +1,60 @@
/*
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:
Stream() : _timeout(1000), read_error(0) {}
virtual int available() = 0;
virtual int read() = 0;
virtual int peek() = 0;
virtual void flush() = 0;

void setTimeout(unsigned long timeout);
bool find(char *target);
bool find(char *target, size_t length);
bool findUntil(char *target, char *terminator);
bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen);
long parseInt();
long parseInt(char skipChar);
float parseFloat();
float parseFloat(char skipChar);
size_t readBytes(char *buffer, size_t length);
size_t readBytesUntil(char terminator, char *buffer, size_t length);
String readString(size_t max = 120);
String readStringUntil(char terminator, size_t max = 120);
int getReadError() { return read_error; }
void clearReadError() { setReadError(0); }
protected:
void setReadError(int err = 1) { read_error = err; }
unsigned long _timeout;
private:
char read_error;
int timedRead();
int timedPeek();
int peekNextDigit();
};

#endif

+ 214
- 0
teensy3/Tone.cpp View File

@@ -0,0 +1,214 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2013 PJRC.COM, LLC.
*
* 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:
*
* 1. The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* 2. If the Software is incorporated into a build system that allows
* selection among a list of target devices, then similar target
* devices manufactured by PJRC.COM must be included in the list of
* target devices and selectable in the same manner.
*
* 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.
*/

#include "core_pins.h"
#include "pins_arduino.h"
#include "HardwareSerial.h"
#include "IntervalTimer.h"

#if 1
// IntervalTimer based tone. This allows tone() to share the timers with other
// libraries, rather than permanently hogging one PIT timer even for projects
// which never use tone(). Someday this single-tone implementation might be
// changed to allow multiple simultaneous tones.

static uint32_t tone_toggle_count;
static volatile uint8_t *tone_reg;
static uint8_t tone_pin=255;
static uint16_t tone_frequency=0;
IntervalTimer tone_timer;

void tone_interrupt(void);

void tone(uint8_t pin, uint16_t frequency, uint32_t duration)
{
uint32_t count;
volatile uint32_t *config;
float usec;

if (pin >= CORE_NUM_DIGITAL) return;
if (duration) {
count = (frequency * duration / 1000) * 2;
} else {
count = 0xFFFFFFFF;
}
usec = (float)500000.0 / (float)frequency;
config = portConfigRegister(pin);

// TODO: IntervalTimer really needs an API to disable and enable
// the interrupt on a single timer.
__disable_irq();
if (pin == tone_pin) {
if (frequency == tone_frequency) {
// same pin, same frequency, so just update the
// duration. Users will call repetitively call
// tone() with the same setting, expecting a
// continuous output with no glitches or phase
// changes or jitter at each call.
tone_toggle_count = count;
} else {
// same pin, but a new frequency.
tone_reg[0] = 1; // clear pin
tone_timer.begin(tone_interrupt, usec);
}
} else {
if (tone_pin < CORE_NUM_DIGITAL) {
tone_reg[0] = 1; // clear pin
}
tone_pin = pin;
tone_reg = portClearRegister(pin);
tone_reg[0] = 1; // clear pin
tone_reg[384] = 1; // output mode;
*config = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
tone_toggle_count = count;
tone_timer.begin(tone_interrupt, usec);
}
__enable_irq();
}


void tone_interrupt(void)
{
if (tone_toggle_count) {
tone_reg[128] = 1; // toggle
if (tone_toggle_count < 0xFFFFFFFF) tone_toggle_count--;
} else {
tone_timer.end();
tone_reg[0] = 0; // clear
tone_pin = 255;
tone_frequency = 0;
}
}

void noTone(uint8_t pin)
{
if (pin >= CORE_NUM_DIGITAL) return;
__disable_irq();
if (pin == tone_pin) {
tone_timer.end();
tone_reg[0] = 0; // clear
tone_pin = 255;
tone_frequency = 0;
}
__enable_irq();
}
#endif



#if 0
// Old PIT timer based tone(). This implementation is slightly more efficient,
// but it consumes one of the PIT timers, even for projects which never use tone().

static uint32_t tone_toggle_count;
static volatile uint8_t *tone_reg;
static uint8_t tone_pin;

void init_tone(void)
{
if (SIM_SCGC6 & SIM_SCGC6_PIT) return;
SIM_SCGC6 |= SIM_SCGC6_PIT; // TODO: use bitband for atomic read-mod-write
PIT_MCR = 0;
PIT_TCTRL3 = 0; // disabled
tone_pin = 255;
NVIC_ENABLE_IRQ(IRQ_PIT_CH3);
}

void tone(uint8_t pin, uint16_t frequency, uint32_t duration)
{
uint32_t count, load;
volatile uint32_t *config;

init_tone();
if (pin >= CORE_NUM_DIGITAL) return;
if (duration) {
count = (frequency * duration / 1000) * 2;
} else {
count = 0xFFFFFFFF;
}
load = (F_BUS / 2) / frequency;
config = portConfigRegister(pin);
__disable_irq();
if (pin != tone_pin) {
if (tone_pin < CORE_NUM_DIGITAL) {
tone_reg[0] = 1; // clear pin
}
tone_pin = pin;
tone_reg = portClearRegister(pin);
tone_reg[0] = 1; // clear pin
tone_reg[384] = 1; // output mode;
*config = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
}
tone_toggle_count = count;
if (PIT_LDVAL3 != load) {
PIT_TCTRL3 = 0;
PIT_LDVAL3 = load;
PIT_TCTRL3 = 3;
}
__enable_irq();
}

void pit3_isr(void)
{
PIT_TFLG3 = 1;

if (tone_toggle_count) {
tone_reg[128] = 1; // toggle
if (tone_toggle_count < 0xFFFFFFFF) tone_toggle_count--;
} else {
PIT_TCTRL3 = 0;
PIT_LDVAL3 = 0;
tone_reg[0] = 0; // clear
tone_pin = 255;
}
}

void noTone(uint8_t pin)
{
if (pin >= CORE_NUM_DIGITAL) return;
__disable_irq();
if (pin == tone_pin) {
PIT_TCTRL3 = 0;
PIT_LDVAL3 = 0;
tone_reg[0] = 0; // clear
tone_pin = 255;
}
__enable_irq();
}
#endif










+ 91
- 0
teensy3/Udp.h View File

@@ -0,0 +1,91 @@
/*
* Udp.cpp: Library to send/receive UDP packets.
*
* NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these)
* 1) UDP does not guarantee the order in which assembled UDP packets are received. This
* might not happen often in practice, but in larger network topologies, a UDP
* packet can be received out of sequence.
* 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being
* aware of it. Again, this may not be a concern in practice on small local networks.
* For more information, see http://www.cafeaulait.org/course/week12/35.html
*
* MIT License:
* Copyright (c) 2008 Bjoern Hartmann
* 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.
*
* bjoern@cs.stanford.edu 12/30/2008
*/

#if ARDUINO >= 100

#ifndef udp_h
#define udp_h

#include <Stream.h>
#include <IPAddress.h>

class UDP : public Stream {

public:
virtual uint8_t begin(uint16_t) =0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
virtual void stop() =0; // Finish with the UDP socket

// Sending UDP packets
// Start building up a packet to send to the remote host specific in ip and port
// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
virtual int beginPacket(IPAddress ip, uint16_t port) =0;
// Start building up a packet to send to the remote host specific in host and port
// Returns 1 if successful, 0 if there was a problem resolving the hostname or port
virtual int beginPacket(const char *host, uint16_t port) =0;
// Finish off this packet and send it
// Returns 1 if the packet was sent successfully, 0 if there was an error
virtual int endPacket() =0;
// Write a single byte into the packet
virtual size_t write(uint8_t) =0;
// Write size bytes from buffer into the packet
virtual size_t write(const uint8_t *buffer, size_t size) =0;

// Start processing the next available incoming packet
// Returns the size of the packet in bytes, or 0 if no packets are available
virtual int parsePacket() =0;
// Number of bytes remaining in the current packet
virtual int available() =0;
// Read a single byte from the current packet
virtual int read() =0;
// Read up to len bytes from the current packet and place them into buffer
// Returns the number of bytes read, or 0 if none are available
virtual int read(unsigned char* buffer, size_t len) =0;
// Read up to len characters from the current packet and place them into buffer
// Returns the number of characters read, or 0 if none are available
virtual int read(char* buffer, size_t len) =0;
// Return the next byte from the current packet without moving on to the next byte
virtual int peek() =0;
virtual void flush() =0; // Finish reading the current packet

// Return the IP address of the host who sent the current incoming packet
virtual IPAddress remoteIP() =0;
// Return the port of the host who sent the current incoming packet
virtual uint16_t remotePort() =0;
protected:
uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); };
};

#endif
#endif

+ 168
- 0
teensy3/WCharacter.h 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

+ 1
- 0
teensy3/WConstants.h View File

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

+ 50
- 0
teensy3/WMath.cpp View File

@@ -0,0 +1,50 @@
#include <stdint.h>

static uint32_t seed;

void randomSeed(uint32_t newseed)
{
if (newseed > 0) seed = newseed;
}

void srandom(uint32_t newseed)
{
seed = newseed;
}

uint32_t random(void)
{
int32_t hi, lo, x;

// the algorithm used in avr-libc 1.6.4
x = seed;
if (x == 0) x = 123459876;
hi = x / 127773;
lo = x % 127773;
x = 16807 * lo - 2836 * hi;
if (x < 0) x += 0x7FFFFFFF;
seed = x;
return x;
}

uint32_t random(uint32_t howbig)
{
if (howbig == 0) return 0;
return random() % howbig;
}

int32_t random(int32_t howsmall, int32_t howbig)
{
if (howsmall >= howbig) return howsmall;
int32_t 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; }


+ 59
- 0
teensy3/WProgram.h View File

@@ -0,0 +1,59 @@
#ifndef WProgram_h
#define WProgram_h

#include <stdlib.h>
#include <string.h>
#include <math.h>

// some libraries and sketches depend on this
// AVR stuff, assuming Arduino.h or WProgram.h
// automatically includes it...
#include <avr/pgmspace.h>
#include <avr/interrupt.h>

#include "avr_functions.h"
#include "wiring.h"
#include "HardwareSerial.h"

#define DMAMEM __attribute__ ((section(".dmabuffers"), used))

#ifdef __cplusplus

#include "avr_emulation.h"
#include "usb_serial.h"
#include "usb_seremu.h"
#include "usb_keyboard.h"
#include "usb_mouse.h"
#include "usb_joystick.h"
#include "usb_midi.h"
#include "usb_rawhid.h"
#include "usb_flightsim.h"

//#include "WCharacter.h"
#include "WString.h"
#include "elapsedMillis.h"
#include "IntervalTimer.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, uint16_t frequency, uint32_t duration = 0);
void noTone(uint8_t pin);

// WMath prototypes
uint32_t random(void);
uint32_t random(uint32_t howbig);
int32_t random(int32_t howsmall, int32_t howbig);
void randomSeed(uint32_t newseed);
void srandom(uint32_t newseed);
long map(long, long, long, long, long);

#include "pins_arduino.h"

#endif // __cplusplus

#endif // WProgram_h

+ 725
- 0
teensy3/WString.cpp View File

@@ -0,0 +1,725 @@
/*
WString.cpp - String library for Wiring & Arduino
...mostly rewritten by Paul Stoffregen...
Copyright (c) 2009-10 Hernando Barragan. All rights reserved.
Copyright 2011, Paul Stoffregen, paul@pjrc.com

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 "WString.h"


/*********************************************/
/* Constructors */
/*********************************************/

String::String(const char *cstr)
{
init();
if (cstr) copy(cstr, strlen(cstr));
}

String::String(const __FlashStringHelper *pgmstr)
{
init();
*this = pgmstr;
}

String::String(const String &value)
{
init();
*this = value;
}

#ifdef __GXX_EXPERIMENTAL_CXX0X__
String::String(String &&rval)
{
init();
move(rval);
}
String::String(StringSumHelper &&rval)
{
init();
move(rval);
}
#endif

String::String(char c)
{
init();
*this = c;
}

String::String(unsigned char c)
{
init();
char buf[4];
utoa(c, buf, 10);
*this = buf;
}

String::String(const int value, unsigned char base)
{
init();
char buf[18];
itoa(value, buf, base);
*this = buf;
}

String::String(unsigned int value, unsigned char base)
{
init();
char buf[17];
utoa(value, buf, base);
*this = buf;
}

String::String(long value, unsigned char base)
{
init();
char buf[34];
ltoa(value, buf, base);
*this = buf;
}

String::String(unsigned long value, unsigned char base)
{
init();
char buf[33];
ultoa(value, buf, base);
*this = buf;
}

String::String(float num, unsigned char digits)
{
init();
char buf[40];
*this = dtostrf(num, digits + 2, digits, buf);
}

String::~String()
{
free(buffer);
}

/*********************************************/
/* Memory Management */
/*********************************************/

inline void String::init(void)
{
buffer = NULL;
capacity = 0;
len = 0;
flags = 0;
}

unsigned char String::reserve(unsigned int size)
{
if (capacity >= size) return 1;
if (changeBuffer(size)) {
if (len == 0) buffer[0] = 0;
return 1;
}
return 0;
}

unsigned char String::changeBuffer(unsigned int maxStrLen)
{
char *newbuffer = (char *)realloc(buffer, maxStrLen + 1);
if (newbuffer) {
buffer = newbuffer;
capacity = maxStrLen;
return 1;
}
return 0;
}

/*********************************************/
/* Copy and Move */
/*********************************************/

String & String::copy(const char *cstr, unsigned int length)
{
if (length == 0) {
if (buffer) buffer[0] = 0;
len = 0;
return *this;
}
if (!reserve(length)) {
if (buffer) {
free(buffer);
buffer = NULL;
}
len = capacity = 0;
return *this;
}
len = length;
strcpy(buffer, cstr);
return *this;
}

void String::move(String &rhs)
{
if (buffer) {
if (capacity >= rhs.len) {
strcpy(buffer, rhs.buffer);
len = rhs.len;
rhs.len = 0;
return;
} else {
free(buffer);
}
}
buffer = rhs.buffer;
capacity = rhs.capacity;
len = rhs.len;
rhs.buffer = NULL;
rhs.capacity = 0;
rhs.len = 0;
}

String & String::operator = (const String &rhs)
{
if (this == &rhs) return *this;
return copy(rhs.buffer, rhs.len);
}

#ifdef __GXX_EXPERIMENTAL_CXX0X__
String & String::operator = (String &&rval)
{
if (this != &rval) move(rval);
return *this;
}

String & String::operator = (StringSumHelper &&rval)
{
if (this != &rval) move(rval);
return *this;
}
#endif

String & String::operator = (const char *cstr)
{
if (cstr) {
copy(cstr, strlen(cstr));
} else {
len = 0;
}
return *this;
}

String & String::operator = (const __FlashStringHelper *pgmstr)
{
copy(pgmstr);
return *this;
}

String & String::operator = (char c)
{
char buf[2];
buf[0] = c;
buf[1] = 0;
return copy(buf, 1);
}

/*********************************************/
/* Append */
/*********************************************/

String & String::append(const String &s)
{
return append(s.buffer, s.len);
}

String & String::append(const char *cstr, unsigned int length)
{
unsigned int newlen = len + length;
if (length == 0 || !reserve(newlen)) return *this;
strcpy(buffer + len, cstr);
len = newlen;
return *this;
}

String & String::append(const char *cstr)
{
if (cstr) append(cstr, strlen(cstr));
return *this;
}

String & String::append(char c)
{
char buf[2];
buf[0] = c;
buf[1] = 0;
append(buf, 1);
return *this;
}

String & String::append(int num)
{
char buf[12];
ltoa((long)num, buf, 10);
append(buf, strlen(buf));
return *this;
}

String & String::append(unsigned int num)
{
char buf[11];
ultoa((unsigned long)num, buf, 10);
append(buf, strlen(buf));
return *this;
}

String & String::append(long num)
{
char buf[12];
ltoa(num, buf, 10);
append(buf, strlen(buf));
return *this;
}

String & String::append(unsigned long num)
{
char buf[11];
ultoa(num, buf, 10);
append(buf, strlen(buf));
return *this;
}

String & String::append(float num)
{
char buf[30];
dtostrf(num, 4, 2, buf);
append(buf, strlen(buf));
return *this;
}


/*********************************************/
/* Concatenate */
/*********************************************/


StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
a.append(rhs.buffer, rhs.len);
return a;
}

StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
if (cstr) a.append(cstr, strlen(cstr));
return a;
}

StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *pgmstr)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
a.append(pgmstr);
return a;
}

StringSumHelper & operator + (const StringSumHelper &lhs, char c)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
a.append(c);
return a;
}

StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char c)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
a.append(c);
return a;
}

StringSumHelper & operator + (const StringSumHelper &lhs, int num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
a.append((long)num);
return a;
}

StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
a.append((unsigned long)num);
return a;
}

StringSumHelper & operator + (const StringSumHelper &lhs, long num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
a.append(num);
return a;
}

StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
a.append(num);
return a;
}

StringSumHelper & operator + (const StringSumHelper &lhs, float num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
a.append(num);
return a;
}

StringSumHelper & operator + (const StringSumHelper &lhs, double num)
{
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
a.append(num);
return a;
}

/*********************************************/
/* Comparison */
/*********************************************/

int String::compareTo(const String &s) const
{
if (!buffer || !s.buffer) {
if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer;
if (buffer && len > 0) return *(unsigned char *)buffer;
return 0;
}
return strcmp(buffer, s.buffer);
}

unsigned char String::equals(const String &s2) const
{
return (len == s2.len && compareTo(s2) == 0);
}

unsigned char String::equals(const char *cstr) const
{
if (len == 0) return (cstr == NULL || *cstr == 0);
if (cstr == NULL) return buffer[0] == 0;
return strcmp(buffer, cstr) == 0;
}

unsigned char String::operator<(const String &rhs) const
{
return compareTo(rhs) < 0;
}

unsigned char String::operator>(const String &rhs) const
{
return compareTo(rhs) > 0;
}

unsigned char String::operator<=(const String &rhs) const
{
return compareTo(rhs) <= 0;
}

unsigned char String::operator>=(const String &rhs) const
{
return compareTo(rhs) >= 0;
}

unsigned char String::equalsIgnoreCase( const String &s2 ) const
{
if (this == &s2) return 1;
if (len != s2.len) return 0;
if (len == 0) return 1;
const char *p1 = buffer;
const char *p2 = s2.buffer;
while (*p1) {
if (tolower(*p1++) != tolower(*p2++)) return 0;
}
return 1;
}

unsigned char String::startsWith( const String &s2 ) const
{
if (len < s2.len) return 0;
return startsWith(s2, 0);
}

unsigned char String::startsWith( const String &s2, unsigned int offset ) const
{
if (offset > len - s2.len || !buffer || !s2.buffer) return 0;
return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0;
}

unsigned char String::endsWith( const String &s2 ) const
{
if ( len < s2.len || !buffer || !s2.buffer) return 0;
return strcmp(&buffer[len - s2.len], s2.buffer) == 0;
}

/*********************************************/
/* Character Access */
/*********************************************/

char String::charAt(unsigned int loc) const
{
return operator[](loc);
}

void String::setCharAt(unsigned int loc, char c)
{
if (loc < len) buffer[loc] = c;
}

char & String::operator[](unsigned int index)
{
static char dummy_writable_char;
if (index >= len || !buffer) {
dummy_writable_char = 0;
return dummy_writable_char;
}
return buffer[index];
}

char String::operator[]( unsigned int index ) const
{
if (index >= len || !buffer) return 0;
return buffer[index];
}

void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const
{
if (!bufsize || !buf) return;
if (index >= len) {
buf[0] = 0;
return;
}
unsigned int n = bufsize - 1;
if (n > len - index) n = len - index;
strncpy((char *)buf, buffer + index, n);
buf[n] = 0;
}

/*********************************************/
/* Search */
/*********************************************/

int String::indexOf(char c) const
{
return indexOf(c, 0);
}

int String::indexOf( char ch, unsigned int fromIndex ) const
{
if (fromIndex >= len) 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 >= len) return -1;
const char *found = strstr(buffer + fromIndex, s2.buffer);
if (found == NULL) return -1;
return found - buffer;
}

int String::lastIndexOf( char theChar ) const
{
return lastIndexOf(theChar, len - 1);
}

int String::lastIndexOf(char ch, unsigned int fromIndex) const
{
if (fromIndex >= len || fromIndex < 0) 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, len - s2.len);
}

int String::lastIndexOf(const String &s2, unsigned int fromIndex) const
{
if (s2.len == 0 || len == 0 || s2.len > len || fromIndex < 0) return -1;
if (fromIndex >= len) fromIndex = len - 1;
int found = -1;
for (char *p = buffer; p <= buffer + fromIndex; p++) {
p = strstr(p, s2.buffer);
if (!p) break;
if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer;
}
return found;
}

String String::substring( unsigned int left ) const
{
return substring(left, len);
}

String String::substring(unsigned int left, unsigned int right) const
{
if (left > right) {
unsigned int temp = right;
right = left;
left = temp;
}
String out;
if (left > len) return out;
if (right > len) right = len;
char temp = buffer[right]; // save the replaced character
buffer[right] = '\0';
out = buffer + left; // pointer arithmetic
buffer[right] = temp; //restore character
return out;
}

/*********************************************/
/* Modification */
/*********************************************/

String & String::replace(char find, char replace)
{
if (!buffer) return *this;
for (char *p = buffer; *p; p++) {
if (*p == find) *p = replace;
}
return *this;
}

String & String::replace(const String& find, const String& replace)
{
if (len == 0 || find.len == 0) return *this;
int diff = replace.len - find.len;
char *readFrom = buffer;
char *foundAt;
if (diff == 0) {
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
memcpy(foundAt, replace.buffer, replace.len);
readFrom = foundAt + replace.len;
}
} else if (diff < 0) {
char *writeTo = buffer;
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
unsigned int n = foundAt - readFrom;
memcpy(writeTo, readFrom, n);
writeTo += n;
memcpy(writeTo, replace.buffer, replace.len);
writeTo += replace.len;
readFrom = foundAt + find.len;
len += diff;
}
strcpy(writeTo, readFrom);
} else {
unsigned int size = len; // compute size needed for result
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
readFrom = foundAt + find.len;
size += diff;
}
if (size == len) return *this;
if (size > capacity && !changeBuffer(size)) return *this;
int index = len - 1;
while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) {
readFrom = buffer + index + find.len;
memmove(readFrom + diff, readFrom, len - (readFrom - buffer));
len += diff;
buffer[len] = 0;
memcpy(buffer + index, replace.buffer, replace.len);
index--;
}
}
return *this;
}

String & String::remove(unsigned int index)
{
if (index < len) {
len = index;
buffer[len] = 0;
}
return *this;
}

String & String::remove(unsigned int index, unsigned int count)
{
if (index < len && count > 0) {
if (index + count > len) count = len - index;
len = len - count;
memmove(buffer + index, buffer + index + count, len - index);
buffer[len] = 0;
}
return *this;
}

String & String::toLowerCase(void)
{
if (!buffer) return *this;
for (char *p = buffer; *p; p++) {
*p = tolower(*p);
}
return *this;
}

String & String::toUpperCase(void)
{
if (!buffer) return *this;
for (char *p = buffer; *p; p++) {
*p = toupper(*p);
}
return *this;
}

String & String::trim(void)
{
if (!buffer || len == 0) return *this;
char *begin = buffer;
while (isspace(*begin)) begin++;
char *end = buffer + len - 1;
while (isspace(*end) && end >= begin) end--;
len = end + 1 - begin;
if (begin > buffer) memcpy(buffer, begin, len);
buffer[len] = 0;
return *this;
}

/*********************************************/
/* Parsing / Conversion */
/*********************************************/

long String::toInt(void) const
{
if (buffer) return atol(buffer);
return 0;
}

float String::toFloat(void) const
{
if (buffer) return strtof(buffer, (char **)NULL);
return 0.0;
}



+ 216
- 0
teensy3/WString.h View File

@@ -0,0 +1,216 @@
/*
WString.h - String library for Wiring & Arduino
...mostly rewritten by Paul Stoffregen...
Copyright (c) 2009-10 Hernando Barragan. All right reserved.
Copyright 2011, Paul Stoffregen, paul@pjrc.com

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_class_h
#define String_class_h
#ifdef __cplusplus

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "avr_functions.h"

// When compiling programs with this class, the following gcc parameters
// dramatically increase performance and memory (RAM) efficiency, typically
// with little or no increase in code size.
// -felide-constructors
// -std=c++0x

// Brian Cook's "no overhead" Flash String type (message on Dec 14, 2010)
// modified by Mikal Hart for his FlashString library
class __FlashStringHelper;
#ifndef F
#define F(string_literal) ((const __FlashStringHelper *)(string_literal))
#endif

// An inherited class for holding the result of a concatenation. These
// result objects are assumed to be writable by subsequent concatenations.
class StringSumHelper;

// The string class
class String
{
public:
// constructors
String(const char *cstr = (const char *)NULL);
String(const __FlashStringHelper *pgmstr);
String(const String &str);
#ifdef __GXX_EXPERIMENTAL_CXX0X__
String(String &&rval);
String(StringSumHelper &&rval);
#endif
String(char c);
String(unsigned char c);
String(int, unsigned char base=10);
String(unsigned int, unsigned char base=10);
String(long, unsigned char base=10);
String(unsigned long, unsigned char base=10);
String(float num, unsigned char digits=2);
String(double num, unsigned char digits=2) : String((float)num, digits) {}
~String(void);

// memory management
unsigned char reserve(unsigned int size);
inline unsigned int length(void) const {return len;}

// copy and move
String & copy(const char *cstr, unsigned int length);
String & copy(const __FlashStringHelper *s) { return copy((const char *)s, strlen((const char *)s)); }
void move(String &rhs);
String & operator = (const String &rhs);
String & operator = (const char *cstr);
String & operator = (const __FlashStringHelper *pgmstr);
#ifdef __GXX_EXPERIMENTAL_CXX0X__
String & operator = (String &&rval);
String & operator = (StringSumHelper &&rval);
#endif
String & operator = (char c);

// append
String & append(const String &str);
String & append(const char *cstr);
String & append(const __FlashStringHelper *s) {return append((const char *)s, strlen((const char *)s)); }
String & append(char c);
String & append(unsigned char c) {return append((int)c);}
String & append(int num);
String & append(unsigned int num);
String & append(long num);
String & append(unsigned long num);
String & append(float num);
String & append(double num) {return append((float)num);}
String & operator += (const String &rhs) {return append(rhs);}
String & operator += (const char *cstr) {return append(cstr);}
String & operator += (const __FlashStringHelper *pgmstr) {return append(pgmstr);}
String & operator += (char c) {return append(c);}
String & operator += (unsigned char c) {return append((int)c);}
String & operator += (int num) {return append(num);}
String & operator += (unsigned int num) {return append(num);}
String & operator += (long num) {return append(num);}
String & operator += (unsigned long num) {return append(num);}
String & operator += (float num) {return append(num);}
String & operator += (double num) {return append(num);}

// concatenate
friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs);
friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr);
friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *pgmstr);
friend StringSumHelper & operator + (const StringSumHelper &lhs, char c);
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char c);
friend StringSumHelper & operator + (const StringSumHelper &lhs, int num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, long num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, float num);
friend StringSumHelper & operator + (const StringSumHelper &lhs, double num);
String & concat(const String &str) {return append(str);}
String & concat(const char *cstr) {return append(cstr);}
String & concat(const __FlashStringHelper *pgmstr) {return append(pgmstr);}
String & concat(char c) {return append(c);}
String & concat(unsigned char c) {return append((int)c);}
String & concat(int num) {return append(num);}
String & concat(unsigned int num) {return append(num);}
String & concat(long num) {return append(num);}
String & concat(unsigned long num) {return append(num);}
String & concat(float num) {return append(num);}
String & concat(double num) {return append(num);}

// comparison
int compareTo(const String &s) const;
unsigned char equals(const String &s) const;
unsigned char equals(const char *cstr) const;
//unsigned char equals(const __FlashStringHelper *pgmstr) const;
unsigned char operator == (const String &rhs) const {return equals(rhs);}
unsigned char operator == (const char *cstr) const {return equals(cstr);}
unsigned char operator == (const __FlashStringHelper *s) const {return equals((const char *)s);}
unsigned char operator != (const String &rhs) const {return !equals(rhs);}
unsigned char operator != (const char *cstr) const {return !equals(cstr);}
unsigned char operator != (const __FlashStringHelper *s) const {return !equals(s);}
unsigned char operator < (const String &rhs) const;
unsigned char operator > (const String &rhs) const;
unsigned char operator <= (const String &rhs) const;
unsigned char operator >= (const String &rhs) const;
unsigned char equalsIgnoreCase(const String &s) const;
unsigned char startsWith( const String &prefix) const;
unsigned char startsWith(const String &prefix, unsigned int offset) const;
unsigned char endsWith(const String &suffix) const;

// character acccess
char charAt(unsigned int index) const;
void setCharAt(unsigned int index, char c);
char operator [] (unsigned int index) const;
char& operator [] (unsigned int index);
void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const;
void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const
{getBytes((unsigned char *)buf, bufsize, index);}
const char * c_str() const { return buffer; }

// search
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;
String substring( unsigned int beginIndex ) const;
String substring( unsigned int beginIndex, unsigned int endIndex ) const;

// modification
String & replace(char find, char replace);
String & replace(const String& find, const String& replace);
String & remove(unsigned int index);
String & remove(unsigned int index, unsigned int count);
String & toLowerCase(void);
String & toUpperCase(void);
String & trim(void);

// parsing/conversion
long toInt(void) const;
float toFloat(void) const;

protected:
char *buffer; // the actual char array
unsigned int capacity; // the array length minus one (for the '\0')
unsigned int len; // the String length (not counting the '\0')
unsigned char flags; // unused, for future features
protected:
void init(void);
unsigned char changeBuffer(unsigned int maxStrLen);
String & append(const char *cstr, unsigned int length);
};

class StringSumHelper : public String
{
public:
StringSumHelper(const String &s) : String(s) {}
StringSumHelper(const char *p) : String(p) {}
StringSumHelper(const __FlashStringHelper *pgmstr) : String(pgmstr) {}
StringSumHelper(char c) : String(c) {}
StringSumHelper(unsigned char c) : String(c) {}
StringSumHelper(int num) : String(num, 10) {}
StringSumHelper(unsigned int num) : String(num, 10) {}
StringSumHelper(long num) : String(num, 10) {}
StringSumHelper(unsigned long num) : String(num, 10) {}
};

#endif // __cplusplus
#endif // String_class_h

+ 287
- 0
teensy3/analog.c View File

@@ -0,0 +1,287 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2013 PJRC.COM, LLC.
*
* 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:
*
* 1. The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* 2. If the Software is incorporated into a build system that allows
* selection among a list of target devices, then similar target
* devices manufactured by PJRC.COM must be included in the list of
* target devices and selectable in the same manner.
*
* 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.
*/

#include "core_pins.h"
//#include "HardwareSerial.h"

static uint8_t calibrating;
static uint8_t analog_right_shift = 0;
static uint8_t analog_config_bits = 10;
static uint8_t analog_num_average = 4;
static uint8_t analog_reference_internal = 0;

// the alternate clock is connected to OSCERCLK (16 MHz).
// datasheet says ADC clock should be 2 to 12 MHz for 16 bit mode
// datasheet says ADC clock should be 1 to 18 MHz for 8-12 bit mode

#if F_BUS == 48000000
#define ADC0_CFG1_6MHZ ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1)
#define ADC0_CFG1_12MHZ ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1)
#define ADC0_CFG1_24MHZ ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(1)
#elif F_BUS == 24000000
#define ADC0_CFG1_6MHZ ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(0)
#define ADC0_CFG1_12MHZ ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(0)
#define ADC0_CFG1_24MHZ ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0)
#else
#error
#endif

void analog_init(void)
{
uint32_t num;

VREF_TRM = 0x60;
VREF_SC = 0xE1; // enable 1.2 volt ref

if (analog_config_bits == 8) {
ADC0_CFG1 = ADC0_CFG1_24MHZ + ADC_CFG1_MODE(0);
ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(3);
} else if (analog_config_bits == 10) {
ADC0_CFG1 = ADC0_CFG1_12MHZ + ADC_CFG1_MODE(2) + ADC_CFG1_ADLSMP;
ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(3);
} else if (analog_config_bits == 12) {
ADC0_CFG1 = ADC0_CFG1_12MHZ + ADC_CFG1_MODE(1) + ADC_CFG1_ADLSMP;
ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(2);
} else {
ADC0_CFG1 = ADC0_CFG1_12MHZ + ADC_CFG1_MODE(3) + ADC_CFG1_ADLSMP;
ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(2);
}

if (analog_reference_internal) {
ADC0_SC2 = ADC_SC2_REFSEL(1); // 1.2V ref
} else {
ADC0_SC2 = ADC_SC2_REFSEL(0); // vcc/ext ref
}

num = analog_num_average;
if (num <= 1) {
ADC0_SC3 = ADC_SC3_CAL; // begin cal
} else if (num <= 4) {
ADC0_SC3 = ADC_SC3_CAL + ADC_SC3_AVGE + ADC_SC3_AVGS(0);
} else if (num <= 8) {
ADC0_SC3 = ADC_SC3_CAL + ADC_SC3_AVGE + ADC_SC3_AVGS(1);
} else if (num <= 16) {
ADC0_SC3 = ADC_SC3_CAL + ADC_SC3_AVGE + ADC_SC3_AVGS(2);
} else {
ADC0_SC3 = ADC_SC3_CAL + ADC_SC3_AVGE + ADC_SC3_AVGS(3);
}
calibrating = 1;
}

static void wait_for_cal(void)
{
uint16_t sum;

//serial_print("wait_for_cal\n");
while (ADC0_SC3 & ADC_SC3_CAL) {
// wait
//serial_print(".");
}
__disable_irq();
if (calibrating) {
//serial_print("\n");
sum = ADC0_CLPS + ADC0_CLP4 + ADC0_CLP3 + ADC0_CLP2 + ADC0_CLP1 + ADC0_CLP0;
sum = (sum / 2) | 0x8000;
ADC0_PG = sum;
//serial_print("ADC0_PG = ");
//serial_phex16(sum);
//serial_print("\n");
sum = ADC0_CLMS + ADC0_CLM4 + ADC0_CLM3 + ADC0_CLM2 + ADC0_CLM1 + ADC0_CLM0;
sum = (sum / 2) | 0x8000;
ADC0_MG = sum;
//serial_print("ADC0_MG = ");
//serial_phex16(sum);
//serial_print("\n");
calibrating = 0;
}
__enable_irq();
}

// ADCx_SC2[REFSEL] bit selects the voltage reference sources for ADC.
// VREFH/VREFL - connected as the primary reference option
// 1.2 V VREF_OUT - connected as the VALT reference option


#define DEFAULT 0
#define INTERNAL 2
#define INTERNAL1V2 2
#define INTERNAL1V1 2
#define EXTERNAL 0

void analogReference(uint8_t type)
{
if (type) {
// internal reference requested
if (!analog_reference_internal) {
analog_reference_internal = 1;
if (calibrating) ADC0_SC3 = 0; // cancel cal
analog_init();
}
} else {
// vcc or external reference requested
if (analog_reference_internal) {
analog_reference_internal = 0;
if (calibrating) ADC0_SC3 = 0; // cancel cal
analog_init();
}
}
}


void analogReadRes(unsigned int bits)
{
unsigned int config;

if (bits >= 13) {
if (bits > 16) bits = 16;
config = 16;
} else if (bits >= 11) {
config = 12;
} else if (bits >= 9) {
config = 10;
} else {
config = 8;
}
analog_right_shift = config - bits;
if (config != analog_config_bits) {
analog_config_bits = config;
if (calibrating) ADC0_SC3 = 0; // cancel cal
analog_init();
}
}

void analogReadAveraging(unsigned int num)
{

if (calibrating) wait_for_cal();
if (num <= 1) {
num = 0;
ADC0_SC3 = 0;
} else if (num <= 4) {
num = 4;
ADC0_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(0);
} else if (num <= 8) {
num = 8;
ADC0_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(1);
} else if (num <= 16) {
num = 16;
ADC0_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(2);
} else {
num = 32;
ADC0_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(3);
}
analog_num_average = num;
}

// The SC1A register is used for both software and hardware trigger modes of operation.


static const uint8_t channel2sc1a[] = {
5, 14, 8, 9, 13, 12, 6, 7, 15, 4,
0, 19, 3, 21, 26, 22
};

// TODO: perhaps this should store the NVIC priority, so it works recursively?
static volatile uint8_t analogReadBusy = 0;

int analogRead(uint8_t pin)
{
int result;

if (pin >= 14) {
if (pin <= 23) {
pin -= 14; // 14-23 are A0-A9
} else if (pin >= 34 && pin <= 39) {
pin -= 24; // 34-37 are A10-A13, 38 is temp sensor, 39 is vref
} else {
return 0; // all others are invalid
}
}
//serial_print("analogRead");
//return 0;
if (calibrating) wait_for_cal();
//pin = 5; // PTD1/SE5b, pin 14, analog 0

__disable_irq();
start: ADC0_SC1A = channel2sc1a[pin];
analogReadBusy = 1;
__enable_irq();
while (1) {
__disable_irq();
if ((ADC0_SC1A & ADC_SC1_COCO)) {
result = ADC0_RA;
analogReadBusy = 0;
__enable_irq();
result >>= analog_right_shift;
return result;
}
// detect if analogRead was used from an interrupt
// if so, our analogRead got canceled, so it must
// be restarted.
if (!analogReadBusy) goto start;
__enable_irq();
yield();
}
#if 0
ADC0_SC1A = channel2sc1a[pin];
while ((ADC0_SC1A & ADC_SC1_COCO) == 0) {
yield();
// wait
//serial_print(".");
}
//serial_print("\n");
result = ADC0_RA >> analog_right_shift;
//serial_phex16(result >> 3);
//serial_print("\n");
return result;
#endif
}























+ 38
- 0
teensy3/arm_common_tables.h View File

@@ -0,0 +1,38 @@
/* ----------------------------------------------------------------------
* Copyright (C) 2010 ARM Limited. All rights reserved.
*
* $Date: 11. November 2010
* $Revision: V1.0.2
*
* Project: CMSIS DSP Library
* Title: arm_common_tables.h
*
* Description: This file has extern declaration for common tables like Bitreverse, reciprocal etc which are used across different functions
*
* Target Processor: Cortex-M4/Cortex-M3
*
* Version 1.0.2 2010/11/11
* Documentation updated.
*
* Version 1.0.1 2010/10/05
* Production release and review comments incorporated.
*
* Version 1.0.0 2010/09/20
* Production release and review comments incorporated.
* -------------------------------------------------------------------- */

#ifndef _ARM_COMMON_TABLES_H
#define _ARM_COMMON_TABLES_H

#include "arm_math.h"

extern const uint16_t armBitRevTable[1024];
extern const q15_t armRecipTableQ15[64];
extern const q31_t armRecipTableQ31[64];
extern const q31_t realCoefAQ31[1024];
extern const q31_t realCoefBQ31[1024];
extern const float32_t twiddleCoef[6144];
extern const q31_t twiddleCoefQ31[6144];
extern const q15_t twiddleCoefQ15[6144];

#endif /* ARM_COMMON_TABLES_H */

+ 7571
- 0
teensy3/arm_math.h
File diff suppressed because it is too large
View File


+ 9
- 0
teensy3/avr/eeprom.h View File

@@ -0,0 +1,9 @@
#ifndef _AVR_EEPROM_H_
#define _AVR_EEPROM_H_ 1

#include <stddef.h>
#include <stdint.h>

#define E2END 0x80

#endif

+ 0
- 0
teensy3/avr/interrupt.h View File


+ 1
- 0
teensy3/avr/io.h View File

@@ -0,0 +1 @@
#include "../avr_emulation.h"

+ 46
- 0
teensy3/avr/pgmspace.h View File

@@ -0,0 +1,46 @@
#ifndef __PGMSPACE_H_
#define __PGMSPACE_H_ 1

#include <inttypes.h>

#define PROGMEM
#define PGM_P const char *
#define PSTR(str) (str)

#define _SFR_BYTE(n) (n)

typedef void prog_void;
typedef char prog_char;
typedef unsigned char prog_uchar;
typedef int8_t prog_int8_t;
typedef uint8_t prog_uint8_t;
typedef int16_t prog_int16_t;
typedef uint16_t prog_uint16_t;
typedef int32_t prog_int32_t;
typedef uint32_t prog_uint32_t;

#define memcpy_P(dest, src, num) memcpy((dest), (src), (num))
#define strcpy_P(dest, src) strcpy((dest), (src))
#define strcat_P(dest, src) strcat((dest), (src))
#define strcmp_P(a, b) strcmp((a), (b))
#define strstr_P(a, b) strstr((a), (b))
#define strlen_P(s) strlen((const char *)(s))
#define strncmp_P(a, b, n) strncmp((a), (b), (n))
#define strncpy_P(a, b, n) strncmp((a), (b), (n))
#define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__)

#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
#define pgm_read_word(addr) (*(const unsigned short *)(addr))
#define pgm_read_dword(addr) (*(const unsigned long *)(addr))
#define pgm_read_float(addr) (*(const float *)(addr))

#define pgm_read_byte_near(addr) pgm_read_byte(addr)
#define pgm_read_word_near(addr) pgm_read_word(addr)
#define pgm_read_dword_near(addr) pgm_read_dword(addr)
#define pgm_read_float_near(addr) pgm_read_float(addr)
#define pgm_read_byte_far(addr) pgm_read_byte(addr)
#define pgm_read_word_far(addr) pgm_read_word(addr)
#define pgm_read_dword_far(addr) pgm_read_dword(addr)
#define pgm_read_float_far(addr) pgm_read_float(addr)

#endif

+ 34
- 0
teensy3/avr_emulation.cpp View File

@@ -0,0 +1,34 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2013 PJRC.COM, LLC.
*
* 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:
*
* 1. The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* 2. If the Software is incorporated into a build system that allows
* selection among a list of target devices, then similar target
* devices manufactured by PJRC.COM must be included in the list of
* target devices and selectable in the same manner.
*
* 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.
*/


#include "avr_emulation.h"

uint8_t SPCRemulation::pinout = 0;

+ 1150
- 0
teensy3/avr_emulation.h
File diff suppressed because it is too large
View File


+ 105
- 0
teensy3/avr_functions.h View File

@@ -0,0 +1,105 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2013 PJRC.COM, LLC.
*
* 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:
*
* 1. The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* 2. If the Software is incorporated into a build system that allows
* selection among a list of target devices, then similar target
* devices manufactured by PJRC.COM must be included in the list of
* target devices and selectable in the same manner.
*
* 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.
*/

#ifndef _avr_functions_h_
#define _avr_functions_h_

#include <inttypes.h>

#ifdef __cplusplus
extern "C" {
#endif

void eeprom_initialize(void);
uint8_t eeprom_read_byte(const uint8_t *addr) __attribute__ ((pure));
uint16_t eeprom_read_word(const uint16_t *addr) __attribute__ ((pure));
uint32_t eeprom_read_dword(const uint32_t *addr) __attribute__ ((pure));
void eeprom_read_block(void *buf, const void *addr, uint32_t len);
void eeprom_write_byte(uint8_t *addr, uint8_t value);
void eeprom_write_word(uint16_t *addr, uint16_t value);
void eeprom_write_dword(uint32_t *addr, uint32_t value);
void eeprom_write_block(const void *buf, void *addr, uint32_t len);

static inline float eeprom_read_float(const float *addr) __attribute__((pure, always_inline, unused));
static inline float eeprom_read_float(const float *addr)
{
union {float f; uint32_t u32;} u;
u.u32 = eeprom_read_dword((const uint32_t *)addr);
return u.f;
}
static inline void eeprom_write_float(float *addr, float value) __attribute__((always_inline, unused));
static inline void eeprom_write_float(float *addr, float value)
{
union {float f; uint32_t u32;} u;
u.f = value;
eeprom_write_dword((uint32_t *)addr, u.u32);
}
static inline void eeprom_update_byte(uint8_t *addr, uint8_t value) __attribute__((always_inline, unused));
static inline void eeprom_update_byte(uint8_t *addr, uint8_t value)
{
eeprom_write_byte(addr, value);
}
static inline void eeprom_update_word(uint16_t *addr, uint16_t value) __attribute__((always_inline, unused));
static inline void eeprom_update_word(uint16_t *addr, uint16_t value)
{
eeprom_write_word(addr, value);
}
static inline void eeprom_update_dword(uint32_t *addr, uint32_t value) __attribute__((always_inline, unused));
static inline void eeprom_update_dword(uint32_t *addr, uint32_t value)
{
eeprom_write_dword(addr, value);
}
static inline void eeprom_update_float(float *addr, float value) __attribute__((always_inline, unused));
static inline void eeprom_update_float(float *addr, float value)
{
union {float f; uint32_t u32;} u;
u.f = value;
eeprom_write_dword((uint32_t *)addr, u.u32);
}
static inline void eeprom_update_block(const void *buf, void *addr, uint32_t len) __attribute__((always_inline, unused));
static inline void eeprom_update_block(const void *buf, void *addr, uint32_t len)
{
eeprom_write_block(buf, addr, len);
}


char * ultoa(unsigned long val, char *buf, int radix);
char * ltoa(long val, char *buf, int radix);
static inline char * utoa(unsigned int val, char *buf, int radix) __attribute__((always_inline, unused));
static inline char * utoa(unsigned int val, char *buf, int radix) { return ultoa(val, buf, radix); }
static inline char * itoa(int val, char *buf, int radix) __attribute__((always_inline, unused));
static inline char * itoa(int val, char *buf, int radix) { return ltoa(val, buf, radix); }
char * dtostrf(float val, int width, unsigned int precision, char *buf);


#ifdef __cplusplus
}
#endif
#endif

+ 515
- 0
teensy3/binary.h 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

+ 1757
- 0
teensy3/core_cm4.h
File diff suppressed because it is too large
View File


+ 541
- 0
teensy3/core_cm4_simd.h View File

@@ -0,0 +1,541 @@
/**************************************************************************//**
* @file core_cm4_simd.h
* @brief CMSIS Cortex-M4 SIMD Header File
* @version V3.01
* @date 06. March 2012
*
* @note
* Copyright (C) 2010-2012 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/

#ifdef __cplusplus
extern "C" {
#endif

#ifndef __CORE_CM4_SIMD_H
#define __CORE_CM4_SIMD_H


/*******************************************************************************
* Hardware Abstraction Layer
******************************************************************************/


/* ################### Compiler specific Intrinsics ########################### */
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
Access to dedicated SIMD instructions
@{
*/


#if defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */

/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}


__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}


__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;

__ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}

#define __SSAT16(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})

#define __USAT16(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1)
{
uint32_t result;

__ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1));
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1)
{
uint32_t result;

__ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1));
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;

__ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;

__ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}

#define __SMLALD(ARG1,ARG2,ARG3) \
({ \
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \
__ASM volatile ("smlald %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
})

#define __SMLALDX(ARG1,ARG2,ARG3) \
({ \
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \
__ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
})

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;

__ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3)
{
uint32_t result;

__ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
return(result);
}

#define __SMLSLD(ARG1,ARG2,ARG3) \
({ \
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \
__ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
})

#define __SMLSLDX(ARG1,ARG2,ARG3) \
({ \
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \
__ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
})

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB(uint32_t op1, uint32_t op2)
{
uint32_t result;

__ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
return(result);
}

#define __PKHBT(ARG1,ARG2,ARG3) \
({ \
uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
__ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
__RES; \
})

#define __PKHTB(ARG1,ARG2,ARG3) \
({ \
uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
if (ARG3 == 0) \
__ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \
else \
__ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
__RES; \
})

/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/

#endif /* __GNUC__ */

#endif /* __CORE_CM4_SIMD_H */

#ifdef __cplusplus
}
#endif

+ 374
- 0
teensy3/core_cmInstr.h View File

@@ -0,0 +1,374 @@
/**************************************************************************//**
* @file core_cmInstr.h
* @brief CMSIS Cortex-M Core Instruction Access Header File
* @version V3.01
* @date 06. March 2012
*
* @note
* Copyright (C) 2009-2012 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/

#ifndef __CORE_CMINSTR_H
#define __CORE_CMINSTR_H


/* ########################## Core Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
Access to dedicated instructions
@{
*/


#if defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */

/** \brief No Operation

No Operation does nothing. This instruction can be used for code alignment purposes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __NOP(void)
{
__ASM volatile ("nop");
}


/** \brief Wait For Interrupt

Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFI(void)
{
__ASM volatile ("wfi");
}


/** \brief Wait For Event

Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFE(void)
{
__ASM volatile ("wfe");
}


/** \brief Send Event

Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __SEV(void)
{
__ASM volatile ("sev");
}


/** \brief Instruction Synchronization Barrier

Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or
memory, after the instruction has been completed.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __ISB(void)
{
__ASM volatile ("isb");
}


/** \brief Data Synchronization Barrier

This function acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __DSB(void)
{
__ASM volatile ("dsb");
}


/** \brief Data Memory Barrier

This function ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __DMB(void)
{
__ASM volatile ("dmb");
}


/** \brief Reverse byte order (32 bit)

This function reverses the byte order in integer value.

\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV(uint32_t value)
{
uint32_t result;

__ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );
return(result);
}


/** \brief Reverse byte order (16 bit)

This function reverses the byte order in two unsigned short values.

\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV16(uint32_t value)
{
uint32_t result;

__ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) );
return(result);
}


/** \brief Reverse byte order in signed short value

This function reverses the byte order in a signed short value with sign extension to integer.

\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __REVSH(int32_t value)
{
uint32_t result;

__ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );
return(result);
}


/** \brief Rotate Right in unsigned value (32 bit)

This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.

\param [in] value Value to rotate
\param [in] value Number of Bits to rotate
\return Rotated value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
{

__ASM volatile ("ror %0, %0, %1" : "+r" (op1) : "r" (op2) );
return(op1);
}


#if (__CORTEX_M >= 0x03)

/** \brief Reverse bit order of value

This function reverses the bit order of the given value.

\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
{
uint32_t result;

__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
return(result);
}


/** \brief LDR Exclusive (8 bit)

This function performs a exclusive LDR command for 8 bit value.

\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr)
{
uint8_t result;

__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}


/** \brief LDR Exclusive (16 bit)

This function performs a exclusive LDR command for 16 bit values.

\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr)
{
uint16_t result;

__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}


/** \brief LDR Exclusive (32 bit)

This function performs a exclusive LDR command for 32 bit values.

\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr)
{
uint32_t result;

__ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) );
return(result);
}


/** \brief STR Exclusive (8 bit)

This function performs a exclusive STR command for 8 bit values.

\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
{
uint32_t result;

__ASM volatile ("strexb %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
return(result);
}


/** \brief STR Exclusive (16 bit)

This function performs a exclusive STR command for 16 bit values.

\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
{
uint32_t result;

__ASM volatile ("strexh %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
return(result);
}


/** \brief STR Exclusive (32 bit)

This function performs a exclusive STR command for 32 bit values.

\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
{
uint32_t result;

__ASM volatile ("strex %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
return(result);
}


/** \brief Remove the exclusive lock

This function removes the exclusive lock which is created by LDREX.

*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __CLREX(void)
{
__ASM volatile ("clrex");
}


/** \brief Signed Saturate

This function saturates a signed value.

\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})


/** \brief Unsigned Saturate

This function saturates an unsigned value.

\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})


/** \brief Count leading zeros

This function counts the number of leading zeros of a data value.

\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __CLZ(uint32_t value)
{
uint8_t result;

__ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) );
return(result);
}

#endif /* (__CORTEX_M >= 0x03) */




#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
/* TASKING carm specific functions */

/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/

#endif

/*@}*/ /* end of group CMSIS_Core_InstructionInterface */

#endif /* __CORE_CMINSTR_H */

+ 3
- 0
teensy3/core_id.h View File

@@ -0,0 +1,3 @@
#ifndef CORE_TEENSY
#define CORE_TEENSY
#endif

+ 815
- 0
teensy3/core_pins.h View File

@@ -0,0 +1,815 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2013 PJRC.COM, LLC.
*
* 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:
*
* 1. The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* 2. If the Software is incorporated into a build system that allows
* selection among a list of target devices, then similar target
* devices manufactured by PJRC.COM must be included in the list of
* target devices and selectable in the same manner.
*
* 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.
*/

#ifndef _core_pins_h_
#define _core_pins_h_

#include "mk20dx128.h"
#include "pins_arduino.h"


#define HIGH 1
#define LOW 0
#define INPUT 0
#define OUTPUT 1
#define INPUT_PULLUP 2
#define LSBFIRST 0
#define MSBFIRST 1
#define _BV(n) (1<<(n))
#define CHANGE 4
#define FALLING 2
#define RISING 3

// Pin Arduino
// 0 B16 RXD
// 1 B17 TXD
// 2 D0
// 3 A12 FTM1_CH0
// 4 A13 FTM1_CH1
// 5 D7 FTM0_CH7 OC0B/T1
// 6 D4 FTM0_CH4 OC0A
// 7 D2
// 8 D3 ICP1
// 9 C3 FTM0_CH2 OC1A
// 10 C4 FTM0_CH3 SS/OC1B
// 11 C6 MOSI/OC2A
// 12 C7 MISO
// 13 C5 SCK
// 14 D1
// 15 C0
// 16 B0 (FTM1_CH0)
// 17 B1 (FTM1_CH1)
// 18 B3 SDA
// 19 B2 SCL
// 20 D5 FTM0_CH5
// 21 D6 FTM0_CH6
// 22 C1 FTM0_CH0
// 23 C2 FTM0_CH1
// 24 A5 (FTM0_CH2)
// 25 B19
// 26 E1
// 27 C9
// 28 C8
// 29 C10
// 30 C11
// 31 E0
// 32 B18
// 33 A4 (FTM0_CH1)
// (34) analog only
// (35) analog only
// (36) analog only
// (37) analog only

// not available to user:
// A0 FTM0_CH5 SWD Clock
// A1 FTM0_CH6 USB ID
// A2 FTM0_CH7 SWD Trace
// A3 FTM0_CH0 SWD Data

#define CORE_NUM_TOTAL_PINS 34
#define CORE_NUM_DIGITAL 34
#define CORE_NUM_ANALOG 14
#define CORE_NUM_PWM 10
#define CORE_NUM_INTERRUPT 34

#define CORE_PIN0_BIT 16
#define CORE_PIN1_BIT 17
#define CORE_PIN2_BIT 0
#define CORE_PIN3_BIT 12
#define CORE_PIN4_BIT 13
#define CORE_PIN5_BIT 7
#define CORE_PIN6_BIT 4
#define CORE_PIN7_BIT 2
#define CORE_PIN8_BIT 3
#define CORE_PIN9_BIT 3
#define CORE_PIN10_BIT 4
#define CORE_PIN11_BIT 6
#define CORE_PIN12_BIT 7
#define CORE_PIN13_BIT 5
#define CORE_PIN14_BIT 1
#define CORE_PIN15_BIT 0
#define CORE_PIN16_BIT 0
#define CORE_PIN17_BIT 1
#define CORE_PIN18_BIT 3
#define CORE_PIN19_BIT 2
#define CORE_PIN20_BIT 5
#define CORE_PIN21_BIT 6
#define CORE_PIN22_BIT 1
#define CORE_PIN23_BIT 2
#define CORE_PIN24_BIT 5
#define CORE_PIN25_BIT 19
#define CORE_PIN26_BIT 1
#define CORE_PIN27_BIT 9
#define CORE_PIN28_BIT 8
#define CORE_PIN29_BIT 10
#define CORE_PIN30_BIT 11
#define CORE_PIN31_BIT 0
#define CORE_PIN32_BIT 18
#define CORE_PIN33_BIT 4

#define CORE_PIN0_BITMASK (1<<(CORE_PIN0_BIT))
#define CORE_PIN1_BITMASK (1<<(CORE_PIN1_BIT))
#define CORE_PIN2_BITMASK (1<<(CORE_PIN2_BIT))
#define CORE_PIN3_BITMASK (1<<(CORE_PIN3_BIT))
#define CORE_PIN4_BITMASK (1<<(CORE_PIN4_BIT))
#define CORE_PIN5_BITMASK (1<<(CORE_PIN5_BIT))
#define CORE_PIN6_BITMASK (1<<(CORE_PIN6_BIT))
#define CORE_PIN7_BITMASK (1<<(CORE_PIN7_BIT))
#define CORE_PIN8_BITMASK (1<<(CORE_PIN8_BIT))
#define CORE_PIN9_BITMASK (1<<(CORE_PIN9_BIT))
#define CORE_PIN10_BITMASK (1<<(CORE_PIN10_BIT))
#define CORE_PIN11_BITMASK (1<<(CORE_PIN11_BIT))
#define CORE_PIN12_BITMASK (1<<(CORE_PIN12_BIT))
#define CORE_PIN13_BITMASK (1<<(CORE_PIN13_BIT))
#define CORE_PIN14_BITMASK (1<<(CORE_PIN14_BIT))
#define CORE_PIN15_BITMASK (1<<(CORE_PIN15_BIT))
#define CORE_PIN16_BITMASK (1<<(CORE_PIN16_BIT))
#define CORE_PIN17_BITMASK (1<<(CORE_PIN17_BIT))
#define CORE_PIN18_BITMASK (1<<(CORE_PIN18_BIT))
#define CORE_PIN19_BITMASK (1<<(CORE_PIN19_BIT))
#define CORE_PIN20_BITMASK (1<<(CORE_PIN20_BIT))
#define CORE_PIN21_BITMASK (1<<(CORE_PIN21_BIT))
#define CORE_PIN22_BITMASK (1<<(CORE_PIN22_BIT))
#define CORE_PIN23_BITMASK (1<<(CORE_PIN23_BIT))
#define CORE_PIN24_BITMASK (1<<(CORE_PIN24_BIT))
#define CORE_PIN25_BITMASK (1<<(CORE_PIN25_BIT))
#define CORE_PIN26_BITMASK (1<<(CORE_PIN26_BIT))
#define CORE_PIN27_BITMASK (1<<(CORE_PIN27_BIT))
#define CORE_PIN28_BITMASK (1<<(CORE_PIN28_BIT))
#define CORE_PIN29_BITMASK (1<<(CORE_PIN29_BIT))
#define CORE_PIN30_BITMASK (1<<(CORE_PIN30_BIT))
#define CORE_PIN31_BITMASK (1<<(CORE_PIN31_BIT))
#define CORE_PIN32_BITMASK (1<<(CORE_PIN32_BIT))
#define CORE_PIN33_BITMASK (1<<(CORE_PIN33_BIT))

#define CORE_PIN0_PORTREG GPIOB_PDOR
#define CORE_PIN1_PORTREG GPIOB_PDOR
#define CORE_PIN2_PORTREG GPIOD_PDOR
#define CORE_PIN3_PORTREG GPIOA_PDOR
#define CORE_PIN4_PORTREG GPIOA_PDOR
#define CORE_PIN5_PORTREG GPIOD_PDOR
#define CORE_PIN6_PORTREG GPIOD_PDOR
#define CORE_PIN7_PORTREG GPIOD_PDOR
#define CORE_PIN8_PORTREG GPIOD_PDOR
#define CORE_PIN9_PORTREG GPIOC_PDOR
#define CORE_PIN10_PORTREG GPIOC_PDOR
#define CORE_PIN11_PORTREG GPIOC_PDOR
#define CORE_PIN12_PORTREG GPIOC_PDOR
#define CORE_PIN13_PORTREG GPIOC_PDOR
#define CORE_PIN14_PORTREG GPIOD_PDOR
#define CORE_PIN15_PORTREG GPIOC_PDOR
#define CORE_PIN16_PORTREG GPIOB_PDOR
#define CORE_PIN17_PORTREG GPIOB_PDOR
#define CORE_PIN18_PORTREG GPIOB_PDOR
#define CORE_PIN19_PORTREG GPIOB_PDOR
#define CORE_PIN20_PORTREG GPIOD_PDOR
#define CORE_PIN21_PORTREG GPIOD_PDOR
#define CORE_PIN22_PORTREG GPIOC_PDOR
#define CORE_PIN23_PORTREG GPIOC_PDOR
#define CORE_PIN24_PORTREG GPIOA_PDOR
#define CORE_PIN25_PORTREG GPIOB_PDOR
#define CORE_PIN26_PORTREG GPIOE_PDOR
#define CORE_PIN27_PORTREG GPIOC_PDOR
#define CORE_PIN28_PORTREG GPIOC_PDOR
#define CORE_PIN29_PORTREG GPIOC_PDOR
#define CORE_PIN30_PORTREG GPIOC_PDOR
#define CORE_PIN31_PORTREG GPIOE_PDOR
#define CORE_PIN32_PORTREG GPIOB_PDOR
#define CORE_PIN33_PORTREG GPIOA_PDOR

#define CORE_PIN0_PORTSET GPIOB_PSOR
#define CORE_PIN1_PORTSET GPIOB_PSOR
#define CORE_PIN2_PORTSET GPIOD_PSOR
#define CORE_PIN3_PORTSET GPIOA_PSOR
#define CORE_PIN4_PORTSET GPIOA_PSOR
#define CORE_PIN5_PORTSET GPIOD_PSOR
#define CORE_PIN6_PORTSET GPIOD_PSOR
#define CORE_PIN7_PORTSET GPIOD_PSOR
#define CORE_PIN8_PORTSET GPIOD_PSOR
#define CORE_PIN9_PORTSET GPIOC_PSOR
#define CORE_PIN10_PORTSET GPIOC_PSOR
#define CORE_PIN11_PORTSET GPIOC_PSOR
#define CORE_PIN12_PORTSET GPIOC_PSOR
#define CORE_PIN13_PORTSET GPIOC_PSOR
#define CORE_PIN14_PORTSET GPIOD_PSOR
#define CORE_PIN15_PORTSET GPIOC_PSOR
#define CORE_PIN16_PORTSET GPIOB_PSOR
#define CORE_PIN17_PORTSET GPIOB_PSOR
#define CORE_PIN18_PORTSET GPIOB_PSOR
#define CORE_PIN19_PORTSET GPIOB_PSOR
#define CORE_PIN20_PORTSET GPIOD_PSOR
#define CORE_PIN21_PORTSET GPIOD_PSOR
#define CORE_PIN22_PORTSET GPIOC_PSOR
#define CORE_PIN23_PORTSET GPIOC_PSOR
#define CORE_PIN24_PORTSET GPIOA_PSOR
#define CORE_PIN25_PORTSET GPIOB_PSOR
#define CORE_PIN26_PORTSET GPIOE_PSOR
#define CORE_PIN27_PORTSET GPIOC_PSOR
#define CORE_PIN28_PORTSET GPIOC_PSOR
#define CORE_PIN29_PORTSET GPIOC_PSOR
#define CORE_PIN30_PORTSET GPIOC_PSOR
#define CORE_PIN31_PORTSET GPIOE_PSOR
#define CORE_PIN32_PORTSET GPIOB_PSOR
#define CORE_PIN33_PORTSET GPIOA_PSOR

#define CORE_PIN0_PORTCLEAR GPIOB_PCOR
#define CORE_PIN1_PORTCLEAR GPIOB_PCOR
#define CORE_PIN2_PORTCLEAR GPIOD_PCOR
#define CORE_PIN3_PORTCLEAR GPIOA_PCOR
#define CORE_PIN4_PORTCLEAR GPIOA_PCOR
#define CORE_PIN5_PORTCLEAR GPIOD_PCOR
#define CORE_PIN6_PORTCLEAR GPIOD_PCOR
#define CORE_PIN7_PORTCLEAR GPIOD_PCOR
#define CORE_PIN8_PORTCLEAR GPIOD_PCOR
#define CORE_PIN9_PORTCLEAR GPIOC_PCOR
#define CORE_PIN10_PORTCLEAR GPIOC_PCOR
#define CORE_PIN11_PORTCLEAR GPIOC_PCOR
#define CORE_PIN12_PORTCLEAR GPIOC_PCOR
#define CORE_PIN13_PORTCLEAR GPIOC_PCOR
#define CORE_PIN14_PORTCLEAR GPIOD_PCOR
#define CORE_PIN15_PORTCLEAR GPIOC_PCOR
#define CORE_PIN16_PORTCLEAR GPIOB_PCOR
#define CORE_PIN17_PORTCLEAR GPIOB_PCOR
#define CORE_PIN18_PORTCLEAR GPIOB_PCOR
#define CORE_PIN19_PORTCLEAR GPIOB_PCOR
#define CORE_PIN20_PORTCLEAR GPIOD_PCOR
#define CORE_PIN21_PORTCLEAR GPIOD_PCOR
#define CORE_PIN22_PORTCLEAR GPIOC_PCOR
#define CORE_PIN23_PORTCLEAR GPIOC_PCOR
#define CORE_PIN24_PORTCLEAR GPIOA_PCOR
#define CORE_PIN25_PORTCLEAR GPIOB_PCOR
#define CORE_PIN26_PORTCLEAR GPIOE_PCOR
#define CORE_PIN27_PORTCLEAR GPIOC_PCOR
#define CORE_PIN28_PORTCLEAR GPIOC_PCOR
#define CORE_PIN29_PORTCLEAR GPIOC_PCOR
#define CORE_PIN30_PORTCLEAR GPIOC_PCOR
#define CORE_PIN31_PORTCLEAR GPIOE_PCOR
#define CORE_PIN32_PORTCLEAR GPIOB_PCOR
#define CORE_PIN33_PORTCLEAR GPIOA_PCOR

#define CORE_PIN0_DDRREG GPIOB_PDDR
#define CORE_PIN1_DDRREG GPIOB_PDDR
#define CORE_PIN2_DDRREG GPIOD_PDDR
#define CORE_PIN3_DDRREG GPIOA_PDDR
#define CORE_PIN4_DDRREG GPIOA_PDDR
#define CORE_PIN5_DDRREG GPIOD_PDDR
#define CORE_PIN6_DDRREG GPIOD_PDDR
#define CORE_PIN7_DDRREG GPIOD_PDDR
#define CORE_PIN8_DDRREG GPIOD_PDDR
#define CORE_PIN9_DDRREG GPIOC_PDDR
#define CORE_PIN10_DDRREG GPIOC_PDDR
#define CORE_PIN11_DDRREG GPIOC_PDDR
#define CORE_PIN12_DDRREG GPIOC_PDDR
#define CORE_PIN13_DDRREG GPIOC_PDDR
#define CORE_PIN14_DDRREG GPIOD_PDDR
#define CORE_PIN15_DDRREG GPIOC_PDDR
#define CORE_PIN16_DDRREG GPIOB_PDDR
#define CORE_PIN17_DDRREG GPIOB_PDDR
#define CORE_PIN18_DDRREG GPIOB_PDDR
#define CORE_PIN19_DDRREG GPIOB_PDDR
#define CORE_PIN20_DDRREG GPIOD_PDDR
#define CORE_PIN21_DDRREG GPIOD_PDDR
#define CORE_PIN22_DDRREG GPIOC_PDDR
#define CORE_PIN23_DDRREG GPIOC_PDDR
#define CORE_PIN24_DDRREG GPIOA_PDDR
#define CORE_PIN25_DDRREG GPIOB_PDDR
#define CORE_PIN26_DDRREG GPIOE_PDDR
#define CORE_PIN27_DDRREG GPIOC_PDDR
#define CORE_PIN28_DDRREG GPIOC_PDDR
#define CORE_PIN29_DDRREG GPIOC_PDDR
#define CORE_PIN30_DDRREG GPIOC_PDDR
#define CORE_PIN31_DDRREG GPIOE_PDDR
#define CORE_PIN32_DDRREG GPIOB_PDDR
#define CORE_PIN33_DDRREG GPIOA_PDDR

#define CORE_PIN0_PINREG GPIOB_PDIR
#define CORE_PIN1_PINREG GPIOB_PDIR
#define CORE_PIN2_PINREG GPIOD_PDIR
#define CORE_PIN3_PINREG GPIOA_PDIR
#define CORE_PIN4_PINREG GPIOA_PDIR
#define CORE_PIN5_PINREG GPIOD_PDIR
#define CORE_PIN6_PINREG GPIOD_PDIR
#define CORE_PIN7_PINREG GPIOD_PDIR
#define CORE_PIN8_PINREG GPIOD_PDIR
#define CORE_PIN9_PINREG GPIOC_PDIR
#define CORE_PIN10_PINREG GPIOC_PDIR
#define CORE_PIN11_PINREG GPIOC_PDIR
#define CORE_PIN12_PINREG GPIOC_PDIR
#define CORE_PIN13_PINREG GPIOC_PDIR
#define CORE_PIN14_PINREG GPIOD_PDIR
#define CORE_PIN15_PINREG GPIOC_PDIR
#define CORE_PIN16_PINREG GPIOB_PDIR
#define CORE_PIN17_PINREG GPIOB_PDIR
#define CORE_PIN18_PINREG GPIOB_PDIR
#define CORE_PIN19_PINREG GPIOB_PDIR
#define CORE_PIN20_PINREG GPIOD_PDIR
#define CORE_PIN21_PINREG GPIOD_PDIR
#define CORE_PIN22_PINREG GPIOC_PDIR
#define CORE_PIN23_PINREG GPIOC_PDIR
#define CORE_PIN24_PINREG GPIOA_PDIR
#define CORE_PIN25_PINREG GPIOB_PDIR
#define CORE_PIN26_PINREG GPIOE_PDIR
#define CORE_PIN27_PINREG GPIOC_PDIR
#define CORE_PIN28_PINREG GPIOC_PDIR
#define CORE_PIN29_PINREG GPIOC_PDIR
#define CORE_PIN30_PINREG GPIOC_PDIR
#define CORE_PIN31_PINREG GPIOE_PDIR
#define CORE_PIN32_PINREG GPIOB_PDIR
#define CORE_PIN33_PINREG GPIOA_PDIR

#define CORE_PIN0_CONFIG PORTB_PCR16
#define CORE_PIN1_CONFIG PORTB_PCR17
#define CORE_PIN2_CONFIG PORTD_PCR0
#define CORE_PIN3_CONFIG PORTA_PCR12
#define CORE_PIN4_CONFIG PORTA_PCR13
#define CORE_PIN5_CONFIG PORTD_PCR7
#define CORE_PIN6_CONFIG PORTD_PCR4
#define CORE_PIN7_CONFIG PORTD_PCR2
#define CORE_PIN8_CONFIG PORTD_PCR3
#define CORE_PIN9_CONFIG PORTC_PCR3
#define CORE_PIN10_CONFIG PORTC_PCR4
#define CORE_PIN11_CONFIG PORTC_PCR6
#define CORE_PIN12_CONFIG PORTC_PCR7
#define CORE_PIN13_CONFIG PORTC_PCR5
#define CORE_PIN14_CONFIG PORTD_PCR1
#define CORE_PIN15_CONFIG PORTC_PCR0
#define CORE_PIN16_CONFIG PORTB_PCR0
#define CORE_PIN17_CONFIG PORTB_PCR1
#define CORE_PIN18_CONFIG PORTB_PCR3
#define CORE_PIN19_CONFIG PORTB_PCR2
#define CORE_PIN20_CONFIG PORTD_PCR5
#define CORE_PIN21_CONFIG PORTD_PCR6
#define CORE_PIN22_CONFIG PORTC_PCR1
#define CORE_PIN23_CONFIG PORTC_PCR2
#define CORE_PIN24_CONFIG PORTA_PCR5
#define CORE_PIN25_CONFIG PORTB_PCR19
#define CORE_PIN26_CONFIG PORTE_PCR1
#define CORE_PIN27_CONFIG PORTC_PCR9
#define CORE_PIN28_CONFIG PORTC_PCR8
#define CORE_PIN29_CONFIG PORTC_PCR10
#define CORE_PIN30_CONFIG PORTC_PCR11
#define CORE_PIN31_CONFIG PORTE_PCR0
#define CORE_PIN32_CONFIG PORTB_PCR18
#define CORE_PIN33_CONFIG PORTA_PCR4

#define CORE_ADC0_PIN 14
#define CORE_ADC1_PIN 15
#define CORE_ADC2_PIN 16
#define CORE_ADC3_PIN 17
#define CORE_ADC4_PIN 18
#define CORE_ADC5_PIN 19
#define CORE_ADC6_PIN 20
#define CORE_ADC7_PIN 21
#define CORE_ADC8_PIN 22
#define CORE_ADC9_PIN 23
#define CORE_ADC10_PIN 34
#define CORE_ADC11_PIN 35
#define CORE_ADC12_PIN 36
#define CORE_ADC13_PIN 37

#define CORE_RXD0_PIN 0
#define CORE_TXD0_PIN 1
#define CORE_RXD1_PIN 9
#define CORE_TXD1_PIN 10
#define CORE_RXD2_PIN 7
#define CORE_TXD2_PIN 8

#define CORE_INT0_PIN 0
#define CORE_INT1_PIN 1
#define CORE_INT2_PIN 2
#define CORE_INT3_PIN 3
#define CORE_INT4_PIN 4
#define CORE_INT5_PIN 5
#define CORE_INT6_PIN 6
#define CORE_INT7_PIN 7
#define CORE_INT8_PIN 8
#define CORE_INT9_PIN 9
#define CORE_INT10_PIN 10
#define CORE_INT11_PIN 11
#define CORE_INT12_PIN 12
#define CORE_INT13_PIN 13
#define CORE_INT14_PIN 14
#define CORE_INT15_PIN 15
#define CORE_INT16_PIN 16
#define CORE_INT17_PIN 17
#define CORE_INT18_PIN 18
#define CORE_INT19_PIN 19
#define CORE_INT20_PIN 20
#define CORE_INT21_PIN 21
#define CORE_INT22_PIN 22
#define CORE_INT23_PIN 23
#define CORE_INT24_PIN 24
#define CORE_INT25_PIN 25
#define CORE_INT26_PIN 26
#define CORE_INT27_PIN 27
#define CORE_INT28_PIN 28
#define CORE_INT29_PIN 29
#define CORE_INT30_PIN 30
#define CORE_INT31_PIN 31
#define CORE_INT32_PIN 32
#define CORE_INT33_PIN 33
#define CORE_INT_EVERY_PIN 1




#ifdef __cplusplus
extern "C" {
#endif

void digitalWrite(uint8_t pin, uint8_t val);
static inline void digitalWriteFast(uint8_t pin, uint8_t val) __attribute__((always_inline, unused));
static inline void digitalWriteFast(uint8_t pin, uint8_t val)
{
if (__builtin_constant_p(pin)) {
if (val) {
if (pin == 0) {
CORE_PIN0_PORTSET = CORE_PIN0_BITMASK;
} else if (pin == 1) {
CORE_PIN1_PORTSET = CORE_PIN1_BITMASK;
} else if (pin == 2) {
CORE_PIN2_PORTSET = CORE_PIN2_BITMASK;
} else if (pin == 3) {
CORE_PIN3_PORTSET = CORE_PIN3_BITMASK;
} else if (pin == 4) {
CORE_PIN4_PORTSET = CORE_PIN4_BITMASK;
} else if (pin == 5) {
CORE_PIN5_PORTSET = CORE_PIN5_BITMASK;
} else if (pin == 6) {
CORE_PIN6_PORTSET = CORE_PIN6_BITMASK;
} else if (pin == 7) {
CORE_PIN7_PORTSET = CORE_PIN7_BITMASK;
} else if (pin == 8) {
CORE_PIN8_PORTSET = CORE_PIN8_BITMASK;
} else if (pin == 9) {
CORE_PIN9_PORTSET = CORE_PIN9_BITMASK;
} else if (pin == 10) {
CORE_PIN10_PORTSET = CORE_PIN10_BITMASK;
} else if (pin == 11) {
CORE_PIN11_PORTSET = CORE_PIN11_BITMASK;
} else if (pin == 12) {
CORE_PIN12_PORTSET = CORE_PIN12_BITMASK;
} else if (pin == 13) {
CORE_PIN13_PORTSET = CORE_PIN13_BITMASK;
} else if (pin == 14) {
CORE_PIN14_PORTSET = CORE_PIN14_BITMASK;
} else if (pin == 15) {
CORE_PIN15_PORTSET = CORE_PIN15_BITMASK;
} else if (pin == 16) {
CORE_PIN16_PORTSET = CORE_PIN16_BITMASK;
} else if (pin == 17) {
CORE_PIN17_PORTSET = CORE_PIN17_BITMASK;
} else if (pin == 18) {
CORE_PIN18_PORTSET = CORE_PIN18_BITMASK;
} else if (pin == 19) {
CORE_PIN19_PORTSET = CORE_PIN19_BITMASK;
} else if (pin == 20) {
CORE_PIN20_PORTSET = CORE_PIN20_BITMASK;
} else if (pin == 21) {
CORE_PIN21_PORTSET = CORE_PIN21_BITMASK;
} else if (pin == 22) {
CORE_PIN22_PORTSET = CORE_PIN22_BITMASK;
} else if (pin == 23) {
CORE_PIN23_PORTSET = CORE_PIN23_BITMASK;
} else if (pin == 24) {
CORE_PIN24_PORTSET = CORE_PIN24_BITMASK;
} else if (pin == 25) {
CORE_PIN25_PORTSET = CORE_PIN25_BITMASK;
} else if (pin == 26) {
CORE_PIN26_PORTSET = CORE_PIN26_BITMASK;
} else if (pin == 27) {
CORE_PIN27_PORTSET = CORE_PIN27_BITMASK;
} else if (pin == 28) {
CORE_PIN28_PORTSET = CORE_PIN28_BITMASK;
} else if (pin == 29) {
CORE_PIN29_PORTSET = CORE_PIN29_BITMASK;
} else if (pin == 30) {
CORE_PIN30_PORTSET = CORE_PIN30_BITMASK;
} else if (pin == 31) {
CORE_PIN31_PORTSET = CORE_PIN31_BITMASK;
} else if (pin == 32) {
CORE_PIN32_PORTSET = CORE_PIN32_BITMASK;
} else if (pin == 33) {
CORE_PIN33_PORTSET = CORE_PIN33_BITMASK;
}
} else {
if (pin == 0) {
CORE_PIN0_PORTCLEAR = CORE_PIN0_BITMASK;
} else if (pin == 1) {
CORE_PIN1_PORTCLEAR = CORE_PIN1_BITMASK;
} else if (pin == 2) {
CORE_PIN2_PORTCLEAR = CORE_PIN2_BITMASK;
} else if (pin == 3) {
CORE_PIN3_PORTCLEAR = CORE_PIN3_BITMASK;
} else if (pin == 4) {
CORE_PIN4_PORTCLEAR = CORE_PIN4_BITMASK;
} else if (pin == 5) {
CORE_PIN5_PORTCLEAR = CORE_PIN5_BITMASK;
} else if (pin == 6) {
CORE_PIN6_PORTCLEAR = CORE_PIN6_BITMASK;
} else if (pin == 7) {
CORE_PIN7_PORTCLEAR = CORE_PIN7_BITMASK;
} else if (pin == 8) {
CORE_PIN8_PORTCLEAR = CORE_PIN8_BITMASK;
} else if (pin == 9) {
CORE_PIN9_PORTCLEAR = CORE_PIN9_BITMASK;
} else if (pin == 10) {
CORE_PIN10_PORTCLEAR = CORE_PIN10_BITMASK;
} else if (pin == 11) {
CORE_PIN11_PORTCLEAR = CORE_PIN11_BITMASK;
} else if (pin == 12) {
CORE_PIN12_PORTCLEAR = CORE_PIN12_BITMASK;
} else if (pin == 13) {
CORE_PIN13_PORTCLEAR = CORE_PIN13_BITMASK;
} else if (pin == 14) {
CORE_PIN14_PORTCLEAR = CORE_PIN14_BITMASK;
} else if (pin == 15) {
CORE_PIN15_PORTCLEAR = CORE_PIN15_BITMASK;
} else if (pin == 16) {
CORE_PIN16_PORTCLEAR = CORE_PIN16_BITMASK;
} else if (pin == 17) {
CORE_PIN17_PORTCLEAR = CORE_PIN17_BITMASK;
} else if (pin == 18) {
CORE_PIN18_PORTCLEAR = CORE_PIN18_BITMASK;
} else if (pin == 19) {
CORE_PIN19_PORTCLEAR = CORE_PIN19_BITMASK;
} else if (pin == 20) {
CORE_PIN20_PORTCLEAR = CORE_PIN20_BITMASK;
} else if (pin == 21) {
CORE_PIN21_PORTCLEAR = CORE_PIN21_BITMASK;
} else if (pin == 22) {
CORE_PIN22_PORTCLEAR = CORE_PIN22_BITMASK;
} else if (pin == 23) {
CORE_PIN23_PORTCLEAR = CORE_PIN23_BITMASK;
} else if (pin == 24) {
CORE_PIN24_PORTCLEAR = CORE_PIN24_BITMASK;
} else if (pin == 25) {
CORE_PIN25_PORTCLEAR = CORE_PIN25_BITMASK;
} else if (pin == 26) {
CORE_PIN26_PORTCLEAR = CORE_PIN26_BITMASK;
} else if (pin == 27) {
CORE_PIN27_PORTCLEAR = CORE_PIN27_BITMASK;
} else if (pin == 28) {
CORE_PIN28_PORTCLEAR = CORE_PIN28_BITMASK;
} else if (pin == 29) {
CORE_PIN29_PORTCLEAR = CORE_PIN29_BITMASK;
} else if (pin == 30) {
CORE_PIN30_PORTCLEAR = CORE_PIN30_BITMASK;
} else if (pin == 31) {
CORE_PIN31_PORTCLEAR = CORE_PIN31_BITMASK;
} else if (pin == 32) {
CORE_PIN32_PORTCLEAR = CORE_PIN32_BITMASK;
} else if (pin == 33) {
CORE_PIN33_PORTCLEAR = CORE_PIN33_BITMASK;
}
}
} else {
if (val) {
*portSetRegister(pin) = 1;
} else {
*portClearRegister(pin) = 1;
}
}
}

uint8_t digitalRead(uint8_t pin);
static inline uint8_t digitalReadFast(uint8_t pin) __attribute__((always_inline, unused));
static inline uint8_t digitalReadFast(uint8_t pin)
{
if (__builtin_constant_p(pin)) {
if (pin == 0) {
return (CORE_PIN0_PINREG & CORE_PIN0_BITMASK) ? 1 : 0;
} else if (pin == 1) {
return (CORE_PIN1_PINREG & CORE_PIN1_BITMASK) ? 1 : 0;
} else if (pin == 2) {
return (CORE_PIN2_PINREG & CORE_PIN2_BITMASK) ? 1 : 0;
} else if (pin == 3) {
return (CORE_PIN3_PINREG & CORE_PIN3_BITMASK) ? 1 : 0;
} else if (pin == 4) {
return (CORE_PIN4_PINREG & CORE_PIN4_BITMASK) ? 1 : 0;
} else if (pin == 5) {
return (CORE_PIN5_PINREG & CORE_PIN5_BITMASK) ? 1 : 0;
} else if (pin == 6) {
return (CORE_PIN6_PINREG & CORE_PIN6_BITMASK) ? 1 : 0;
} else if (pin == 7) {
return (CORE_PIN7_PINREG & CORE_PIN7_BITMASK) ? 1 : 0;
} else if (pin == 8) {
return (CORE_PIN8_PINREG & CORE_PIN8_BITMASK) ? 1 : 0;
} else if (pin == 9) {
return (CORE_PIN9_PINREG & CORE_PIN9_BITMASK) ? 1 : 0;
} else if (pin == 10) {
return (CORE_PIN10_PINREG & CORE_PIN10_BITMASK) ? 1 : 0;
} else if (pin == 11) {
return (CORE_PIN11_PINREG & CORE_PIN11_BITMASK) ? 1 : 0;
} else if (pin == 12) {
return (CORE_PIN12_PINREG & CORE_PIN12_BITMASK) ? 1 : 0;
} else if (pin == 13) {
return (CORE_PIN13_PINREG & CORE_PIN13_BITMASK) ? 1 : 0;
} else if (pin == 14) {
return (CORE_PIN14_PINREG & CORE_PIN14_BITMASK) ? 1 : 0;
} else if (pin == 15) {
return (CORE_PIN15_PINREG & CORE_PIN15_BITMASK) ? 1 : 0;
} else if (pin == 16) {
return (CORE_PIN16_PINREG & CORE_PIN16_BITMASK) ? 1 : 0;
} else if (pin == 17) {
return (CORE_PIN17_PINREG & CORE_PIN17_BITMASK) ? 1 : 0;
} else if (pin == 18) {
return (CORE_PIN18_PINREG & CORE_PIN18_BITMASK) ? 1 : 0;
} else if (pin == 19) {
return (CORE_PIN19_PINREG & CORE_PIN19_BITMASK) ? 1 : 0;
} else if (pin == 20) {
return (CORE_PIN20_PINREG & CORE_PIN20_BITMASK) ? 1 : 0;
} else if (pin == 21) {
return (CORE_PIN21_PINREG & CORE_PIN21_BITMASK) ? 1 : 0;
} else if (pin == 22) {
return (CORE_PIN22_PINREG & CORE_PIN22_BITMASK) ? 1 : 0;
} else if (pin == 23) {
return (CORE_PIN23_PINREG & CORE_PIN23_BITMASK) ? 1 : 0;
} else if (pin == 24) {
return (CORE_PIN24_PINREG & CORE_PIN24_BITMASK) ? 1 : 0;
} else if (pin == 25) {
return (CORE_PIN25_PINREG & CORE_PIN25_BITMASK) ? 1 : 0;
} else if (pin == 26) {
return (CORE_PIN26_PINREG & CORE_PIN26_BITMASK) ? 1 : 0;
} else if (pin == 27) {
return (CORE_PIN27_PINREG & CORE_PIN27_BITMASK) ? 1 : 0;
} else if (pin == 28) {
return (CORE_PIN28_PINREG & CORE_PIN28_BITMASK) ? 1 : 0;
} else if (pin == 29) {
return (CORE_PIN29_PINREG & CORE_PIN29_BITMASK) ? 1 : 0;
} else if (pin == 30) {
return (CORE_PIN30_PINREG & CORE_PIN30_BITMASK) ? 1 : 0;
} else if (pin == 31) {
return (CORE_PIN31_PINREG & CORE_PIN31_BITMASK) ? 1 : 0;
} else if (pin == 32) {
return (CORE_PIN32_PINREG & CORE_PIN32_BITMASK) ? 1 : 0;
} else if (pin == 33) {
return (CORE_PIN33_PINREG & CORE_PIN33_BITMASK) ? 1 : 0;
} else {
return 0;
}
} else {
return *portInputRegister(pin);
}
}


void pinMode(uint8_t pin, uint8_t mode);
void init_pins(void);
void analogWrite(uint8_t pin, int val);
void analogWriteRes(uint32_t bits);
static inline void analogWriteResolution(uint32_t bits) { analogWriteRes(bits); }
void analogWriteFrequency(uint8_t pin, uint32_t frequency);
void attachInterrupt(uint8_t pin, void (*function)(void), int mode);
void detachInterrupt(uint8_t pin);
void _init_Teensyduino_internal_(void);

int analogRead(uint8_t pin);
void analogReference(uint8_t type);
void analogReadRes(unsigned int bits);
static inline void analogReadResolution(unsigned int bits) { analogReadRes(bits); }
void analogReadAveraging(unsigned int num);
void analog_init(void);

#define DEFAULT 0
#define INTERNAL 2
#define INTERNAL1V2 2
#define INTERNAL1V1 2
#define EXTERNAL 0

int touchRead(uint8_t pin);


static inline void shiftOut(uint8_t, uint8_t, uint8_t, uint8_t) __attribute__((always_inline, unused));
extern void _shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t value) __attribute__((noinline));
extern void shiftOut_lsbFirst(uint8_t dataPin, uint8_t clockPin, uint8_t value) __attribute__((noinline));
extern void shiftOut_msbFirst(uint8_t dataPin, uint8_t clockPin, uint8_t value) __attribute__((noinline));

static inline void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t value)
{
if (__builtin_constant_p(bitOrder)) {
if (bitOrder == LSBFIRST) {
shiftOut_lsbFirst(dataPin, clockPin, value);
} else {
shiftOut_msbFirst(dataPin, clockPin, value);
}
} else {
_shiftOut(dataPin, clockPin, bitOrder, value);
}
}

static inline uint8_t shiftIn(uint8_t, uint8_t, uint8_t) __attribute__((always_inline, unused));
extern uint8_t _shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder) __attribute__((noinline));
extern uint8_t shiftIn_lsbFirst(uint8_t dataPin, uint8_t clockPin) __attribute__((noinline));
extern uint8_t shiftIn_msbFirst(uint8_t dataPin, uint8_t clockPin) __attribute__((noinline));

static inline uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder)
{
if (__builtin_constant_p(bitOrder)) {
if (bitOrder == LSBFIRST) {
return shiftIn_lsbFirst(dataPin, clockPin);
} else {
return shiftIn_msbFirst(dataPin, clockPin);
}
} else {
return _shiftIn(dataPin, clockPin, bitOrder);
}
}

void _reboot_Teensyduino_(void) __attribute__((noreturn));
void _restart_Teensyduino_(void) __attribute__((noreturn));

void yield(void);

void delay(uint32_t msec);

extern volatile uint32_t systick_millis_count;

static inline uint32_t millis(void) __attribute__((always_inline, unused));
static inline uint32_t millis(void)
{
volatile uint32_t ret = systick_millis_count; // single aligned 32 bit is atomic;
return ret;
}

uint32_t micros(void);

static inline void delayMicroseconds(uint32_t) __attribute__((always_inline, unused));
static inline void delayMicroseconds(uint32_t usec)
{
#if F_CPU == 96000000
uint32_t n = usec << 5;
#elif F_CPU == 48000000
uint32_t n = usec << 4;
#elif F_CPU == 24000000
uint32_t n = usec << 3;
#endif
if (usec == 0) return;
asm volatile(
"L_%=_delayMicroseconds:" "\n\t"
"subs %0, #1" "\n\t"
"bne L_%=_delayMicroseconds" "\n"
: "+r" (n) :
);
}

#ifdef __cplusplus
}
#endif








#ifdef __cplusplus
extern "C" {
#endif
unsigned long rtc_get(void);
void rtc_set(unsigned long t);
void rtc_compensate(int adjust);
#ifdef __cplusplus
}
class teensy3_clock_class
{
public:
static unsigned long get(void) __attribute__((always_inline)) { return rtc_get(); }
static void set(unsigned long t) __attribute__((always_inline)) { rtc_set(t); }
static void compensate(int adj) __attribute__((always_inline)) { rtc_compensate(adj); }
};
extern teensy3_clock_class Teensy3Clock;
#endif




#endif

+ 294
- 0
teensy3/eeprom.c View File

@@ -0,0 +1,294 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2013 PJRC.COM, LLC.
*
* 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:
*
* 1. The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* 2. If the Software is incorporated into a build system that allows
* selection among a list of target devices, then similar target
* devices manufactured by PJRC.COM must be included in the list of
* target devices and selectable in the same manner.
*
* 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.
*/

#include "mk20dx128.h"
#include <stdint.h>
//#include "HardwareSerial.h"

// The EEPROM is really RAM with a hardware-based backup system to
// flash memory. Selecting a smaller size EEPROM allows more wear
// leveling, for higher write endurance. If you edit this file,
// set this to the smallest size your application can use. Also,
// due to Freescale's implementation, writing 16 or 32 bit words
// (aligned to 2 or 4 byte boundaries) has twice the endurance
// compared to writing 8 bit bytes.
//
#define EEPROM_SIZE 2048

// Writing unaligned 16 or 32 bit data is handled automatically when
// this is defined, but at a cost of extra code size. Without this,
// any unaligned write will cause a hard fault exception! If you're
// absolutely sure all 16 and 32 bit writes will be aligned, you can
// remove the extra unnecessary code.
//
#define HANDLE_UNALIGNED_WRITES

// Minimum EEPROM Endurance
// ------------------------
#if (EEPROM_SIZE == 2048) // 35000 writes/byte or 70000 writes/word
#define EEESIZE 0x33
#elif (EEPROM_SIZE == 1024) // 75000 writes/byte or 150000 writes/word
#define EEESIZE 0x34
#elif (EEPROM_SIZE == 512) // 155000 writes/byte or 310000 writes/word
#define EEESIZE 0x35
#elif (EEPROM_SIZE == 256) // 315000 writes/byte or 630000 writes/word
#define EEESIZE 0x36
#elif (EEPROM_SIZE == 128) // 635000 writes/byte or 1270000 writes/word
#define EEESIZE 0x37
#elif (EEPROM_SIZE == 64) // 1275000 writes/byte or 2550000 writes/word
#define EEESIZE 0x38
#elif (EEPROM_SIZE == 32) // 2555000 writes/byte or 5110000 writes/word
#define EEESIZE 0x39
#endif

void eeprom_initialize(void)
{
uint32_t count=0;
uint16_t do_flash_cmd[] = {
0xf06f, 0x037f, 0x7003, 0x7803,
0xf013, 0x0f80, 0xd0fb, 0x4770};
uint8_t status;

if (FTFL_FCNFG & FTFL_FCNFG_RAMRDY) {
// FlexRAM is configured as traditional RAM
// We need to reconfigure for EEPROM usage
FTFL_FCCOB0 = 0x80; // PGMPART = Program Partition Command
FTFL_FCCOB4 = EEESIZE; // EEPROM Size
FTFL_FCCOB5 = 0x03; // 0K for Dataflash, 32K for EEPROM backup
__disable_irq();
// do_flash_cmd() must execute from RAM. Luckily the C syntax is simple...
(*((void (*)(volatile uint8_t *))((uint32_t)do_flash_cmd | 1)))(&FTFL_FSTAT);
__enable_irq();
status = FTFL_FSTAT;
if (status & 0x70) {
FTFL_FSTAT = (status & 0x70);
return; // error
}
}
// wait for eeprom to become ready (is this really necessary?)
while (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) {
if (++count > 20000) break;
}
}

#define FlexRAM ((uint8_t *)0x14000000)

uint8_t eeprom_read_byte(const uint8_t *addr)
{
uint32_t offset = (uint32_t)addr;
if (offset >= EEPROM_SIZE) return 0;
if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
return FlexRAM[offset];
}

uint16_t eeprom_read_word(const uint16_t *addr)
{
uint32_t offset = (uint32_t)addr;
if (offset >= EEPROM_SIZE-1) return 0;
if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
return *(uint16_t *)(&FlexRAM[offset]);
}

uint32_t eeprom_read_dword(const uint32_t *addr)
{
uint32_t offset = (uint32_t)addr;
if (offset >= EEPROM_SIZE-3) return 0;
if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
return *(uint32_t *)(&FlexRAM[offset]);
}

void eeprom_read_block(void *buf, const void *addr, uint32_t len)
{
uint32_t offset = (uint32_t)addr;
uint8_t *dest = (uint8_t *)buf;
uint32_t end = offset + len;
if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
if (end > EEPROM_SIZE) end = EEPROM_SIZE;
while (offset < end) {
*dest++ = FlexRAM[offset++];
}
}

static void flexram_wait(void)
{
while (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) {
// TODO: timeout
}
}

void eeprom_write_byte(uint8_t *addr, uint8_t value)
{
uint32_t offset = (uint32_t)addr;

if (offset >= EEPROM_SIZE) return;
if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
if (FlexRAM[offset] != value) {
FlexRAM[offset] = value;
flexram_wait();
}
}

void eeprom_write_word(uint16_t *addr, uint16_t value)
{
uint32_t offset = (uint32_t)addr;

if (offset >= EEPROM_SIZE-1) return;
if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
#ifdef HANDLE_UNALIGNED_WRITES
if ((offset & 1) == 0) {
#endif
if (*(uint16_t *)(&FlexRAM[offset]) != value) {
*(uint16_t *)(&FlexRAM[offset]) = value;
flexram_wait();
}
#ifdef HANDLE_UNALIGNED_WRITES
} else {
if (FlexRAM[offset] != value) {
FlexRAM[offset] = value;
flexram_wait();
}
if (FlexRAM[offset + 1] != (value >> 8)) {
FlexRAM[offset + 1] = value >> 8;
flexram_wait();
}
}
#endif
}

void eeprom_write_dword(uint32_t *addr, uint32_t value)
{
uint32_t offset = (uint32_t)addr;

if (offset >= EEPROM_SIZE-3) return;
if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
#ifdef HANDLE_UNALIGNED_WRITES
switch (offset & 3) {
case 0:
#endif
if (*(uint32_t *)(&FlexRAM[offset]) != value) {
*(uint32_t *)(&FlexRAM[offset]) = value;
flexram_wait();
}
return;
#ifdef HANDLE_UNALIGNED_WRITES
case 2:
if (*(uint16_t *)(&FlexRAM[offset]) != value) {
*(uint16_t *)(&FlexRAM[offset]) = value;
flexram_wait();
}
if (*(uint16_t *)(&FlexRAM[offset + 2]) != (value >> 16)) {
*(uint16_t *)(&FlexRAM[offset + 2]) = value >> 16;
flexram_wait();
}
return;
default:
if (FlexRAM[offset] != value) {
FlexRAM[offset] = value;
flexram_wait();
}
if (*(uint16_t *)(&FlexRAM[offset + 1]) != (value >> 8)) {
*(uint16_t *)(&FlexRAM[offset + 1]) = value >> 8;
flexram_wait();
}
if (FlexRAM[offset + 3] != (value >> 24)) {
FlexRAM[offset + 3] = value >> 24;
flexram_wait();
}
}
#endif
}

void eeprom_write_block(const void *buf, void *addr, uint32_t len)
{
uint32_t offset = (uint32_t)addr;
const uint8_t *src = (const uint8_t *)buf;

if (offset >= EEPROM_SIZE) return;
if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
if (len >= EEPROM_SIZE) len = EEPROM_SIZE;
if (offset + len >= EEPROM_SIZE) len = EEPROM_SIZE - offset;
while (len > 0) {
uint32_t lsb = offset & 3;
if (lsb == 0 && len >= 4) {
// write aligned 32 bits
uint32_t val32;
val32 = *src++;
val32 |= (*src++ << 8);
val32 |= (*src++ << 16);
val32 |= (*src++ << 24);
if (*(uint32_t *)(&FlexRAM[offset]) != val32) {
*(uint32_t *)(&FlexRAM[offset]) = val32;
flexram_wait();
}
offset += 4;
len -= 4;
} else if ((lsb == 0 || lsb == 2) && len >= 2) {
// write aligned 16 bits
uint16_t val16;
val16 = *src++;
val16 |= (*src++ << 8);
if (*(uint16_t *)(&FlexRAM[offset]) != val16) {
*(uint16_t *)(&FlexRAM[offset]) = val16;
flexram_wait();
}
offset += 2;
len -= 2;
} else {
// write 8 bits
uint8_t val8 = *src++;
if (FlexRAM[offset] != val8) {
FlexRAM[offset] = val8;
flexram_wait();
}
offset++;
len--;
}
}
}




/*
void do_flash_cmd(volatile uint8_t *fstat)
{
*fstat = 0x80;
while ((*fstat & 0x80) == 0) ; // wait
}
00000000 <do_flash_cmd>:
0: f06f 037f mvn.w r3, #127 ; 0x7f
4: 7003 strb r3, [r0, #0]
6: 7803 ldrb r3, [r0, #0]
8: f013 0f80 tst.w r3, #128 ; 0x80
c: d0fb beq.n 6 <do_flash_cmd+0x6>
e: 4770 bx lr
*/


+ 81
- 0
teensy3/elapsedMillis.h View File

@@ -0,0 +1,81 @@
/* Elapsed time types - for easy-to-use measurements of elapsed time
* http://www.pjrc.com/teensy/
* Copyright (c) 2011 PJRC.COM, LLC
*
* 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.
*/

#ifndef elapsedMillis_h
#define elapsedMillis_h
#ifdef __cplusplus

#if ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

class elapsedMillis
{
private:
unsigned long ms;
public:
elapsedMillis(void) { ms = millis(); }
elapsedMillis(unsigned long val) { ms = millis() - val; }
elapsedMillis(const elapsedMillis &orig) { ms = orig.ms; }
operator unsigned long () const { return millis() - ms; }
elapsedMillis & operator = (const elapsedMillis &rhs) { ms = rhs.ms; return *this; }
elapsedMillis & operator = (unsigned long val) { ms = millis() - val; return *this; }
elapsedMillis & operator -= (unsigned long val) { ms += val ; return *this; }
elapsedMillis & operator += (unsigned long val) { ms -= val ; return *this; }
elapsedMillis operator - (int val) const { elapsedMillis r(*this); r.ms += val; return r; }
elapsedMillis operator - (unsigned int val) const { elapsedMillis r(*this); r.ms += val; return r; }
elapsedMillis operator - (long val) const { elapsedMillis r(*this); r.ms += val; return r; }
elapsedMillis operator - (unsigned long val) const { elapsedMillis r(*this); r.ms += val; return r; }
elapsedMillis operator + (int val) const { elapsedMillis r(*this); r.ms -= val; return r; }
elapsedMillis operator + (unsigned int val) const { elapsedMillis r(*this); r.ms -= val; return r; }
elapsedMillis operator + (long val) const { elapsedMillis r(*this); r.ms -= val; return r; }
elapsedMillis operator + (unsigned long val) const { elapsedMillis r(*this); r.ms -= val; return r; }
};

class elapsedMicros
{
private:
unsigned long us;
public:
elapsedMicros(void) { us = micros(); }
elapsedMicros(unsigned long val) { us = micros() - val; }
elapsedMicros(const elapsedMicros &orig) { us = orig.us; }
operator unsigned long () const { return micros() - us; }
elapsedMicros & operator = (const elapsedMicros &rhs) { us = rhs.us; return *this; }
elapsedMicros & operator = (unsigned long val) { us = micros() - val; return *this; }
elapsedMicros & operator -= (unsigned long val) { us += val ; return *this; }
elapsedMicros & operator += (unsigned long val) { us -= val ; return *this; }
elapsedMicros operator - (int val) const { elapsedMicros r(*this); r.us += val; return r; }
elapsedMicros operator - (unsigned int val) const { elapsedMicros r(*this); r.us += val; return r; }
elapsedMicros operator - (long val) const { elapsedMicros r(*this); r.us += val; return r; }
elapsedMicros operator - (unsigned long val) const { elapsedMicros r(*this); r.us += val; return r; }
elapsedMicros operator + (int val) const { elapsedMicros r(*this); r.us -= val; return r; }
elapsedMicros operator + (unsigned int val) const { elapsedMicros r(*this); r.us -= val; return r; }
elapsedMicros operator + (long val) const { elapsedMicros r(*this); r.us -= val; return r; }
elapsedMicros operator + (unsigned long val) const { elapsedMicros r(*this); r.us -= val; return r; }
};

#endif // __cplusplus
#endif // elapsedMillis_h

+ 96
- 0
teensy3/keylayouts.c View File

@@ -0,0 +1,96 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2013 PJRC.COM, LLC.
*
* 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:
*
* 1. The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* 2. If the Software is incorporated into a build system that allows
* selection among a list of target devices, then similar target
* devices manufactured by PJRC.COM must be included in the list of
* target devices and selectable in the same manner.
*
* 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.
*/

#include <avr/pgmspace.h>
#include <stdint.h>

#include "keylayouts.h"

#ifdef M
#undef M
#endif
#define M(n) ((n) & 0x3FFF)

const KEYCODE_TYPE keycodes_ascii[] = {
M(ASCII_20), M(ASCII_21), M(ASCII_22), M(ASCII_23),
M(ASCII_24), M(ASCII_25), M(ASCII_26), M(ASCII_27),
M(ASCII_28), M(ASCII_29), M(ASCII_2A), M(ASCII_2B),
M(ASCII_2C), M(ASCII_2D), M(ASCII_2E), M(ASCII_2F),
M(ASCII_30), M(ASCII_31), M(ASCII_32), M(ASCII_33),
M(ASCII_34), M(ASCII_35), M(ASCII_36), M(ASCII_37),
M(ASCII_38), M(ASCII_39), M(ASCII_3A), M(ASCII_3B),
M(ASCII_3C), M(ASCII_3D), M(ASCII_3E), M(ASCII_3F),
M(ASCII_40), M(ASCII_41), M(ASCII_42), M(ASCII_43),
M(ASCII_44), M(ASCII_45), M(ASCII_46), M(ASCII_47),
M(ASCII_48), M(ASCII_49), M(ASCII_4A), M(ASCII_4B),
M(ASCII_4C), M(ASCII_4D), M(ASCII_4E), M(ASCII_4F),
M(ASCII_50), M(ASCII_51), M(ASCII_52), M(ASCII_53),
M(ASCII_54), M(ASCII_55), M(ASCII_56), M(ASCII_57),
M(ASCII_58), M(ASCII_59), M(ASCII_5A), M(ASCII_5B),
M(ASCII_5C), M(ASCII_5D), M(ASCII_5E), M(ASCII_5F),
M(ASCII_60), M(ASCII_61), M(ASCII_62), M(ASCII_63),
M(ASCII_64), M(ASCII_65), M(ASCII_66), M(ASCII_67),
M(ASCII_68), M(ASCII_69), M(ASCII_6A), M(ASCII_6B),
M(ASCII_6C), M(ASCII_6D), M(ASCII_6E), M(ASCII_6F),
M(ASCII_70), M(ASCII_71), M(ASCII_72), M(ASCII_73),
M(ASCII_74), M(ASCII_75), M(ASCII_76), M(ASCII_77),
M(ASCII_78), M(ASCII_79), M(ASCII_7A), M(ASCII_7B),
M(ASCII_7C), M(ASCII_7D), M(ASCII_7E), M(ASCII_7F)
};

#ifdef ISO_8859_1_A0
const KEYCODE_TYPE keycodes_iso_8859_1[] = {
M(ISO_8859_1_A0), M(ISO_8859_1_A1), M(ISO_8859_1_A2), M(ISO_8859_1_A3),
M(ISO_8859_1_A4), M(ISO_8859_1_A5), M(ISO_8859_1_A6), M(ISO_8859_1_A7),
M(ISO_8859_1_A8), M(ISO_8859_1_A9), M(ISO_8859_1_AA), M(ISO_8859_1_AB),
M(ISO_8859_1_AC), M(ISO_8859_1_AD), M(ISO_8859_1_AE), M(ISO_8859_1_AF),
M(ISO_8859_1_B0), M(ISO_8859_1_B1), M(ISO_8859_1_B2), M(ISO_8859_1_B3),
M(ISO_8859_1_B4), M(ISO_8859_1_B5), M(ISO_8859_1_B6), M(ISO_8859_1_B7),
M(ISO_8859_1_B8), M(ISO_8859_1_B9), M(ISO_8859_1_BA), M(ISO_8859_1_BB),
M(ISO_8859_1_BC), M(ISO_8859_1_BD), M(ISO_8859_1_BE), M(ISO_8859_1_BF),
M(ISO_8859_1_C0), M(ISO_8859_1_C1), M(ISO_8859_1_C2), M(ISO_8859_1_C3),
M(ISO_8859_1_C4), M(ISO_8859_1_C5), M(ISO_8859_1_C6), M(ISO_8859_1_C7),
M(ISO_8859_1_C8), M(ISO_8859_1_C9), M(ISO_8859_1_CA), M(ISO_8859_1_CB),
M(ISO_8859_1_CC), M(ISO_8859_1_CD), M(ISO_8859_1_CE), M(ISO_8859_1_CF),
M(ISO_8859_1_D0), M(ISO_8859_1_D1), M(ISO_8859_1_D2), M(ISO_8859_1_D3),
M(ISO_8859_1_D4), M(ISO_8859_1_D5), M(ISO_8859_1_D6), M(ISO_8859_1_D7),
M(ISO_8859_1_D8), M(ISO_8859_1_D9), M(ISO_8859_1_DA), M(ISO_8859_1_DB),
M(ISO_8859_1_DC), M(ISO_8859_1_DD), M(ISO_8859_1_DE), M(ISO_8859_1_DF),
M(ISO_8859_1_E0), M(ISO_8859_1_E1), M(ISO_8859_1_E2), M(ISO_8859_1_E3),
M(ISO_8859_1_E4), M(ISO_8859_1_E5), M(ISO_8859_1_E6), M(ISO_8859_1_E7),
M(ISO_8859_1_E8), M(ISO_8859_1_E9), M(ISO_8859_1_EA), M(ISO_8859_1_EB),
M(ISO_8859_1_EC), M(ISO_8859_1_ED), M(ISO_8859_1_EE), M(ISO_8859_1_EF),
M(ISO_8859_1_F0), M(ISO_8859_1_F1), M(ISO_8859_1_F2), M(ISO_8859_1_F3),
M(ISO_8859_1_F4), M(ISO_8859_1_F5), M(ISO_8859_1_F6), M(ISO_8859_1_F7),
M(ISO_8859_1_F8), M(ISO_8859_1_F9), M(ISO_8859_1_FA), M(ISO_8859_1_FB),
M(ISO_8859_1_FC), M(ISO_8859_1_FD), M(ISO_8859_1_FE), M(ISO_8859_1_FF)
};
#endif // ISO_8859_1_A0


+ 5173
- 0
teensy3/keylayouts.h
File diff suppressed because it is too large
View File


+ 28
- 0
teensy3/main.cpp View File

@@ -0,0 +1,28 @@
#include "WProgram.h"

extern "C" int main(void)
{
#if !defined(ARDUINO)

// To use Teensy 3.0 without Arduino, simply put your code here.
// For example:

pinMode(13, OUTPUT);
while (1) {
digitalWriteFast(13, HIGH);
delay(500);
digitalWriteFast(13, LOW);
delay(500);
}


#else
// Arduino's main() function just calls setup() and loop()....
setup();
while (1) {
loop();
yield();
}
#endif
}


+ 447
- 0
teensy3/math_helper.c View File

@@ -0,0 +1,447 @@
/* ----------------------------------------------------------------------
* Copyright (C) 2010 ARM Limited. All rights reserved.
*
* $Date: 29. November 2010
* $Revision: V1.0.3
*
* Project: CMSIS DSP Library
*
* Title: math_helper.c
*
* Description: Definition of all helper functions required.
*
* Target Processor: Cortex-M4/Cortex-M3
*
* Version 1.0.3 2010/11/29
* Re-organized the CMSIS folders and updated documentation.
*
* Version 1.0.2 2010/11/11
* Documentation updated.
*
* Version 1.0.1 2010/10/05
* Production release and review comments incorporated.
*
* Version 1.0.0 2010/09/20
* Production release and review comments incorporated.
*
* Version 0.0.7 2010/06/10
* Misra-C changes done
* -------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
* Include standard header files
* -------------------------------------------------------------------- */
#include<math.h>
/* ----------------------------------------------------------------------
* Include project header files
* -------------------------------------------------------------------- */
#include "math_helper.h"
/**
* @brief Caluclation of SNR
* @param float* Pointer to the reference buffer
* @param float* Pointer to the test buffer
* @param uint32_t total number of samples
* @return float SNR
* The function Caluclates signal to noise ratio for the reference output
* and test output
*/
float arm_snr_f32(float *pRef, float *pTest, uint32_t buffSize)
{
float EnergySignal = 0.0, EnergyError = 0.0;
uint32_t i;
float SNR;
int temp;
int *test;
for (i = 0; i < buffSize; i++)
{
/* Checking for a NAN value in pRef array */
test = (int *)(&pRef[i]);
temp = *test;
if(temp == 0x7FC00000)
{
return(0);
}
/* Checking for a NAN value in pTest array */
test = (int *)(&pTest[i]);
temp = *test;
if(temp == 0x7FC00000)
{
return(0);
}
EnergySignal += pRef[i] * pRef[i];
EnergyError += (pRef[i] - pTest[i]) * (pRef[i] - pTest[i]);
}
/* Checking for a NAN value in EnergyError */
test = (int *)(&EnergyError);
temp = *test;
if(temp == 0x7FC00000)
{
return(0);
}
SNR = 10 * log10 (EnergySignal / EnergyError);
return (SNR);
}
/**
* @brief Provide guard bits for Input buffer
* @param q15_t* Pointer to input buffer
* @param uint32_t blockSize
* @param uint32_t guard_bits
* @return none
* The function Provides the guard bits for the buffer
* to avoid overflow
*/
void arm_provide_guard_bits_q15 (q15_t * input_buf, uint32_t blockSize,
uint32_t guard_bits)
{
uint32_t i;
for (i = 0; i < blockSize; i++)
{
input_buf[i] = input_buf[i] >> guard_bits;
}
}
/**
* @brief Converts float to fixed in q12.20 format
* @param uint32_t number of samples in the buffer
* @return none
* The function converts floating point values to fixed point(q12.20) values
*/
void arm_float_to_q12_20(float *pIn, q31_t * pOut, uint32_t numSamples)
{
uint32_t i;
for (i = 0; i < numSamples; i++)
{
/* 1048576.0f corresponds to pow(2, 20) */
pOut[i] = (q31_t) (pIn[i] * 1048576.0f);
pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
if (pIn[i] == (float) 1.0)
{
pOut[i] = 0x000FFFFF;
}
}
}
/**
* @brief Compare MATLAB Reference Output and ARM Test output
* @param q15_t* Pointer to Ref buffer
* @param q15_t* Pointer to Test buffer
* @param uint32_t number of samples in the buffer
* @return none
*/
uint32_t arm_compare_fixed_q15(q15_t *pIn, q15_t * pOut, uint32_t numSamples)
{
uint32_t i;
int32_t diff, diffCrnt = 0;
uint32_t maxDiff = 0;
for (i = 0; i < numSamples; i++)
{
diff = pIn[i] - pOut[i];
diffCrnt = (diff > 0) ? diff : -diff;
if(diffCrnt > maxDiff)
{
maxDiff = diffCrnt;
}
}
return(maxDiff);
}
/**
* @brief Compare MATLAB Reference Output and ARM Test output
* @param q31_t* Pointer to Ref buffer
* @param q31_t* Pointer to Test buffer
* @param uint32_t number of samples in the buffer
* @return none
*/
uint32_t arm_compare_fixed_q31(q31_t *pIn, q31_t * pOut, uint32_t numSamples)
{
uint32_t i;
int32_t diff, diffCrnt = 0;
uint32_t maxDiff = 0;
for (i = 0; i < numSamples; i++)
{
diff = pIn[i] - pOut[i];
diffCrnt = (diff > 0) ? diff : -diff;
if(diffCrnt > maxDiff)
{
maxDiff = diffCrnt;
}
}
return(maxDiff);
}
/**
* @brief Provide guard bits for Input buffer
* @param q31_t* Pointer to input buffer
* @param uint32_t blockSize
* @param uint32_t guard_bits
* @return none
* The function Provides the guard bits for the buffer
* to avoid overflow
*/
void arm_provide_guard_bits_q31 (q31_t * input_buf,
uint32_t blockSize,
uint32_t guard_bits)
{
uint32_t i;
for (i = 0; i < blockSize; i++)
{
input_buf[i] = input_buf[i] >> guard_bits;
}
}
/**
* @brief Provide guard bits for Input buffer
* @param q31_t* Pointer to input buffer
* @param uint32_t blockSize
* @param uint32_t guard_bits
* @return none
* The function Provides the guard bits for the buffer
* to avoid overflow
*/
void arm_provide_guard_bits_q7 (q7_t * input_buf,
uint32_t blockSize,
uint32_t guard_bits)
{
uint32_t i;
for (i = 0; i < blockSize; i++)
{
input_buf[i] = input_buf[i] >> guard_bits;
}
}
/**
* @brief Caluclates number of guard bits
* @param uint32_t number of additions
* @return none
* The function Caluclates the number of guard bits
* depending on the numtaps
*/
uint32_t arm_calc_guard_bits (uint32_t num_adds)
{
uint32_t i = 1, j = 0;
if (num_adds == 1)
{
return (0);
}
while (i < num_adds)
{
i = i * 2;
j++;
}
return (j);
}
/**
* @brief Converts Q15 to floating-point
* @param uint32_t number of samples in the buffer
* @return none
*/
void arm_apply_guard_bits (float32_t * pIn,
uint32_t numSamples,
uint32_t guard_bits)
{
uint32_t i;
for (i = 0; i < numSamples; i++)
{
pIn[i] = pIn[i] * arm_calc_2pow(guard_bits);
}
}
/**
* @brief Calculates pow(2, numShifts)
* @param uint32_t number of shifts
* @return pow(2, numShifts)
*/
uint32_t arm_calc_2pow(uint32_t numShifts)
{
uint32_t i, val = 1;
for (i = 0; i < numShifts; i++)
{
val = val * 2;
}
return(val);
}
/**
* @brief Converts float to fixed q14
* @param uint32_t number of samples in the buffer
* @return none
* The function converts floating point values to fixed point values
*/
void arm_float_to_q14 (float *pIn, q15_t * pOut,
uint32_t numSamples)
{
uint32_t i;
for (i = 0; i < numSamples; i++)
{
/* 16384.0f corresponds to pow(2, 14) */
pOut[i] = (q15_t) (pIn[i] * 16384.0f);
pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
if (pIn[i] == (float) 2.0)
{
pOut[i] = 0x7FFF;
}
}
}
/**
* @brief Converts float to fixed q30 format
* @param uint32_t number of samples in the buffer
* @return none
* The function converts floating point values to fixed point values
*/
void arm_float_to_q30 (float *pIn, q31_t * pOut,
uint32_t numSamples)
{
uint32_t i;
for (i = 0; i < numSamples; i++)
{
/* 1073741824.0f corresponds to pow(2, 30) */
pOut[i] = (q31_t) (pIn[i] * 1073741824.0f);
pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
if (pIn[i] == (float) 2.0)
{
pOut[i] = 0x7FFFFFFF;
}
}
}
/**
* @brief Converts float to fixed q30 format
* @param uint32_t number of samples in the buffer
* @return none
* The function converts floating point values to fixed point values
*/
void arm_float_to_q29 (float *pIn, q31_t * pOut,
uint32_t numSamples)
{
uint32_t i;
for (i = 0; i < numSamples; i++)
{
/* 1073741824.0f corresponds to pow(2, 30) */
pOut[i] = (q31_t) (pIn[i] * 536870912.0f);
pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
if (pIn[i] == (float) 4.0)
{
pOut[i] = 0x7FFFFFFF;
}
}
}
/**
* @brief Converts float to fixed q28 format
* @param uint32_t number of samples in the buffer
* @return none
* The function converts floating point values to fixed point values
*/
void arm_float_to_q28 (float *pIn, q31_t * pOut,
uint32_t numSamples)
{
uint32_t i;
for (i = 0; i < numSamples; i++)
{
/* 268435456.0f corresponds to pow(2, 28) */
pOut[i] = (q31_t) (pIn[i] * 268435456.0f);
pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
if (pIn[i] == (float) 8.0)
{
pOut[i] = 0x7FFFFFFF;
}
}
}
/**
* @brief Clip the float values to +/- 1
* @param pIn input buffer
* @param numSamples number of samples in the buffer
* @return none
* The function converts floating point values to fixed point values
*/
void arm_clip_f32 (float *pIn, uint32_t numSamples)
{
uint32_t i;
for (i = 0; i < numSamples; i++)
{
if(pIn[i] > 1.0f)
{
pIn[i] = 1.0;
}
else if( pIn[i] < -1.0f)
{
pIn[i] = -1.0;
}
}
}

+ 63
- 0
teensy3/math_helper.h View File

@@ -0,0 +1,63 @@
/* ----------------------------------------------------------------------
* Copyright (C) 2010 ARM Limited. All rights reserved.
*
* $Date: 29. November 2010
* $Revision: V1.0.3
*
* Project: CMSIS DSP Library
*
* Title: math_helper.h
*
*
* Description: Prototypes of all helper functions required.
*
* Target Processor: Cortex-M4/Cortex-M3
*
* Version 1.0.3 2010/11/29
* Re-organized the CMSIS folders and updated documentation.
*
* Version 1.0.2 2010/11/11
* Documentation updated.
*
* Version 1.0.1 2010/10/05
* Production release and review comments incorporated.
*
* Version 1.0.0 2010/09/20
* Production release and review comments incorporated.
*
* Version 0.0.7 2010/06/10
* Misra-C changes done
* -------------------------------------------------------------------- */


#include "arm_math.h"

#ifndef MATH_HELPER_H
#define MATH_HELPER_H

#ifdef __cplusplus
extern "C"
{
#endif

float arm_snr_f32(float *pRef, float *pTest, uint32_t buffSize);
void arm_float_to_q12_20(float *pIn, q31_t * pOut, uint32_t numSamples);
void arm_provide_guard_bits_q15(q15_t *input_buf, uint32_t blockSize, uint32_t guard_bits);
void arm_provide_guard_bits_q31(q31_t *input_buf, uint32_t blockSize, uint32_t guard_bits);
void arm_float_to_q14(float *pIn, q15_t *pOut, uint32_t numSamples);
void arm_float_to_q29(float *pIn, q31_t *pOut, uint32_t numSamples);
void arm_float_to_q28(float *pIn, q31_t *pOut, uint32_t numSamples);
void arm_float_to_q30(float *pIn, q31_t *pOut, uint32_t numSamples);
void arm_clip_f32(float *pIn, uint32_t numSamples);
uint32_t arm_calc_guard_bits(uint32_t num_adds);
void arm_apply_guard_bits (float32_t * pIn, uint32_t numSamples, uint32_t guard_bits);
uint32_t arm_compare_fixed_q15(q15_t *pIn, q15_t * pOut, uint32_t numSamples);
uint32_t arm_compare_fixed_q31(q31_t *pIn, q31_t *pOut, uint32_t numSamples);
uint32_t arm_calc_2pow(uint32_t guard_bits);

#ifdef __cplusplus
}
#endif

#endif


+ 382
- 0
teensy3/mk20dx128.c View File

@@ -0,0 +1,382 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2013 PJRC.COM, LLC.
*
* 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:
*
* 1. The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* 2. If the Software is incorporated into a build system that allows
* selection among a list of target devices, then similar target
* devices manufactured by PJRC.COM must be included in the list of
* target devices and selectable in the same manner.
*
* 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.
*/

#include "mk20dx128.h"


extern unsigned long _stext;
extern unsigned long _etext;
extern unsigned long _sdata;
extern unsigned long _edata;
extern unsigned long _sbss;
extern unsigned long _ebss;
extern unsigned long _estack;
//extern void __init_array_start(void);
//extern void __init_array_end(void);
extern int main (void);
void ResetHandler(void);
void _init_Teensyduino_internal_(void);
void __libc_init_array(void);


void fault_isr(void)
{
while (1) {
// keep polling some communication while in fault
// mode, so we don't completely die.
if (SIM_SCGC4 & SIM_SCGC4_USBOTG) usb_isr();
if (SIM_SCGC4 & SIM_SCGC4_UART0) uart0_status_isr();
if (SIM_SCGC4 & SIM_SCGC4_UART1) uart1_status_isr();
if (SIM_SCGC4 & SIM_SCGC4_UART2) uart2_status_isr();
}
}

void unused_isr(void)
{
fault_isr();
}

extern volatile uint32_t systick_millis_count;
void systick_default_isr(void)
{
systick_millis_count++;
}

void nmi_isr(void) __attribute__ ((weak, alias("unused_isr")));
void hard_fault_isr(void) __attribute__ ((weak, alias("unused_isr")));
void memmanage_fault_isr(void) __attribute__ ((weak, alias("unused_isr")));
void bus_fault_isr(void) __attribute__ ((weak, alias("unused_isr")));
void usage_fault_isr(void) __attribute__ ((weak, alias("unused_isr")));
void svcall_isr(void) __attribute__ ((weak, alias("unused_isr")));
void debugmonitor_isr(void) __attribute__ ((weak, alias("unused_isr")));
void pendablesrvreq_isr(void) __attribute__ ((weak, alias("unused_isr")));
void systick_isr(void) __attribute__ ((weak, alias("systick_default_isr")));

void dma_ch0_isr(void) __attribute__ ((weak, alias("unused_isr")));
void dma_ch1_isr(void) __attribute__ ((weak, alias("unused_isr")));
void dma_ch2_isr(void) __attribute__ ((weak, alias("unused_isr")));
void dma_ch3_isr(void) __attribute__ ((weak, alias("unused_isr")));
void dma_error_isr(void) __attribute__ ((weak, alias("unused_isr")));
void flash_cmd_isr(void) __attribute__ ((weak, alias("unused_isr")));
void flash_error_isr(void) __attribute__ ((weak, alias("unused_isr")));
void low_voltage_isr(void) __attribute__ ((weak, alias("unused_isr")));
void wakeup_isr(void) __attribute__ ((weak, alias("unused_isr")));
void watchdog_isr(void) __attribute__ ((weak, alias("unused_isr")));
void i2c0_isr(void) __attribute__ ((weak, alias("unused_isr")));
void spi0_isr(void) __attribute__ ((weak, alias("unused_isr")));
void i2s0_tx_isr(void) __attribute__ ((weak, alias("unused_isr")));
void i2s0_rx_isr(void) __attribute__ ((weak, alias("unused_isr")));
void uart0_lon_isr(void) __attribute__ ((weak, alias("unused_isr")));
void uart0_status_isr(void) __attribute__ ((weak, alias("unused_isr")));
void uart0_error_isr(void) __attribute__ ((weak, alias("unused_isr")));
void uart1_status_isr(void) __attribute__ ((weak, alias("unused_isr")));
void uart1_error_isr(void) __attribute__ ((weak, alias("unused_isr")));
void uart2_status_isr(void) __attribute__ ((weak, alias("unused_isr")));
void uart2_error_isr(void) __attribute__ ((weak, alias("unused_isr")));
void adc0_isr(void) __attribute__ ((weak, alias("unused_isr")));
void cmp0_isr(void) __attribute__ ((weak, alias("unused_isr")));
void cmp1_isr(void) __attribute__ ((weak, alias("unused_isr")));
void ftm0_isr(void) __attribute__ ((weak, alias("unused_isr")));
void ftm1_isr(void) __attribute__ ((weak, alias("unused_isr")));
void cmt_isr(void) __attribute__ ((weak, alias("unused_isr")));
void rtc_alarm_isr(void) __attribute__ ((weak, alias("unused_isr")));
void rtc_seconds_isr(void) __attribute__ ((weak, alias("unused_isr")));
void pit0_isr(void) __attribute__ ((weak, alias("unused_isr")));
void pit1_isr(void) __attribute__ ((weak, alias("unused_isr")));
void pit2_isr(void) __attribute__ ((weak, alias("unused_isr")));
void pit3_isr(void) __attribute__ ((weak, alias("unused_isr")));
void pdb_isr(void) __attribute__ ((weak, alias("unused_isr")));
void usb_isr(void) __attribute__ ((weak, alias("unused_isr")));
void usb_charge_isr(void) __attribute__ ((weak, alias("unused_isr")));
void tsi0_isr(void) __attribute__ ((weak, alias("unused_isr")));
void mcg_isr(void) __attribute__ ((weak, alias("unused_isr")));
void lptmr_isr(void) __attribute__ ((weak, alias("unused_isr")));
void porta_isr(void) __attribute__ ((weak, alias("unused_isr")));
void portb_isr(void) __attribute__ ((weak, alias("unused_isr")));
void portc_isr(void) __attribute__ ((weak, alias("unused_isr")));
void portd_isr(void) __attribute__ ((weak, alias("unused_isr")));
void porte_isr(void) __attribute__ ((weak, alias("unused_isr")));
void software_isr(void) __attribute__ ((weak, alias("unused_isr")));


// TODO: create AVR-stype ISR() macro, with default linkage to undefined handler
//
__attribute__ ((section(".vectors"), used))
void (* const gVectors[])(void) =
{
(void (*)(void))((unsigned long)&_estack), // 0 ARM: Initial Stack Pointer
ResetHandler, // 1 ARM: Initial Program Counter
nmi_isr, // 2 ARM: Non-maskable Interrupt (NMI)
hard_fault_isr, // 3 ARM: Hard Fault
memmanage_fault_isr, // 4 ARM: MemManage Fault
bus_fault_isr, // 5 ARM: Bus Fault
usage_fault_isr, // 6 ARM: Usage Fault
fault_isr, // 7 --
fault_isr, // 8 --
fault_isr, // 9 --
fault_isr, // 10 --
svcall_isr, // 11 ARM: Supervisor call (SVCall)
debugmonitor_isr, // 12 ARM: Debug Monitor
fault_isr, // 13 --
pendablesrvreq_isr, // 14 ARM: Pendable req serv(PendableSrvReq)
systick_isr, // 15 ARM: System tick timer (SysTick)
dma_ch0_isr, // 16 DMA channel 0 transfer complete
dma_ch1_isr, // 17 DMA channel 1 transfer complete
dma_ch2_isr, // 18 DMA channel 2 transfer complete
dma_ch3_isr, // 19 DMA channel 3 transfer complete
dma_error_isr, // 20 DMA error interrupt channel
unused_isr, // 21 DMA --
flash_cmd_isr, // 22 Flash Memory Command complete
flash_error_isr, // 23 Flash Read collision
low_voltage_isr, // 24 Low-voltage detect/warning
wakeup_isr, // 25 Low Leakage Wakeup
watchdog_isr, // 26 Both EWM and WDOG interrupt
i2c0_isr, // 27 I2C0
spi0_isr, // 28 SPI0
i2s0_tx_isr, // 29 I2S0 Transmit
i2s0_rx_isr, // 30 I2S0 Receive
uart0_lon_isr, // 31 UART0 CEA709.1-B (LON) status
uart0_status_isr, // 32 UART0 status
uart0_error_isr, // 33 UART0 error
uart1_status_isr, // 34 UART1 status
uart1_error_isr, // 35 UART1 error
uart2_status_isr, // 36 UART2 status
uart2_error_isr, // 37 UART2 error
adc0_isr, // 38 ADC0
cmp0_isr, // 39 CMP0
cmp1_isr, // 40 CMP1
ftm0_isr, // 41 FTM0
ftm1_isr, // 42 FTM1
cmt_isr, // 43 CMT
rtc_alarm_isr, // 44 RTC Alarm interrupt
rtc_seconds_isr, // 45 RTC Seconds interrupt
pit0_isr, // 46 PIT Channel 0
pit1_isr, // 47 PIT Channel 1
pit2_isr, // 48 PIT Channel 2
pit3_isr, // 49 PIT Channel 3
pdb_isr, // 50 PDB Programmable Delay Block
usb_isr, // 51 USB OTG
usb_charge_isr, // 52 USB Charger Detect
tsi0_isr, // 53 TSI0
mcg_isr, // 54 MCG
lptmr_isr, // 55 Low Power Timer
porta_isr, // 56 Pin detect (Port A)
portb_isr, // 57 Pin detect (Port B)
portc_isr, // 58 Pin detect (Port C)
portd_isr, // 59 Pin detect (Port D)
porte_isr, // 60 Pin detect (Port E)
software_isr, // 61 Software interrupt
};

//void usb_isr(void)
//{
//}

__attribute__ ((section(".flashconfig"), used))
const uint8_t flashconfigbytes[16] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF
};


// Automatically initialize the RTC. When the build defines the compile
// time, and the user has added a crystal, the RTC will automatically
// begin at the time of the first upload.
#ifndef TIME_T
#define TIME_T 1349049600 // default 1 Oct 2012 (never used, Arduino sets this)
#endif
extern void rtc_set(unsigned long t);



static void startup_unused_hook(void) {}
void startup_early_hook(void) __attribute__ ((weak, alias("startup_unused_hook")));
void startup_late_hook(void) __attribute__ ((weak, alias("startup_unused_hook")));


__attribute__ ((section(".startup")))
void ResetHandler(void)
{
uint32_t *src = &_etext;
uint32_t *dest = &_sdata;
unsigned int i;

WDOG_UNLOCK = WDOG_UNLOCK_SEQ1;
WDOG_UNLOCK = WDOG_UNLOCK_SEQ2;
WDOG_STCTRLH = WDOG_STCTRLH_ALLOWUPDATE;
startup_early_hook();

// enable clocks to always-used peripherals
SIM_SCGC5 = 0x00043F82; // clocks active to all GPIO
SIM_SCGC6 = SIM_SCGC6_RTC | SIM_SCGC6_FTM0 | SIM_SCGC6_FTM1 | SIM_SCGC6_ADC0 | SIM_SCGC6_FTFL;
// if the RTC oscillator isn't enabled, get it started early
if (!(RTC_CR & RTC_CR_OSCE)) {
RTC_SR = 0;
RTC_CR = RTC_CR_SC16P | RTC_CR_SC4P | RTC_CR_OSCE;
}

// release I/O pins hold, if we woke up from VLLS mode
if (PMC_REGSC & PMC_REGSC_ACKISO) PMC_REGSC |= PMC_REGSC_ACKISO;

// TODO: do this while the PLL is waiting to lock....
while (dest < &_edata) *dest++ = *src++;
dest = &_sbss;
while (dest < &_ebss) *dest++ = 0;
SCB_VTOR = 0; // use vector table in flash

// default all interrupts to medium priority level
for (i=0; i < NVIC_NUM_INTERRUPTS; i++) NVIC_SET_PRIORITY(i, 128);

// start in FEI mode
// enable capacitors for crystal
OSC0_CR = OSC_SC8P | OSC_SC2P;
// enable osc, 8-32 MHz range, low power mode
MCG_C2 = MCG_C2_RANGE0(2) | MCG_C2_EREFS;
// switch to crystal as clock source, FLL input = 16 MHz / 512
MCG_C1 = MCG_C1_CLKS(2) | MCG_C1_FRDIV(4);
// wait for crystal oscillator to begin
while ((MCG_S & MCG_S_OSCINIT0) == 0) ;
// wait for FLL to use oscillator
while ((MCG_S & MCG_S_IREFST) != 0) ;
// wait for MCGOUT to use oscillator
while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(2)) ;
// now we're in FBE mode
// config PLL input for 16 MHz Crystal / 4 = 4 MHz
MCG_C5 = MCG_C5_PRDIV0(3);
// config PLL for 96 MHz output
MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0(0);
// wait for PLL to start using xtal as its input
while (!(MCG_S & MCG_S_PLLST)) ;
// wait for PLL to lock
while (!(MCG_S & MCG_S_LOCK0)) ;
// now we're in PBE mode
#if F_CPU == 96000000
// config divisors: 96 MHz core, 48 MHz bus, 24 MHz flash
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV4(3);
#elif F_CPU == 48000000
// config divisors: 48 MHz core, 48 MHz bus, 24 MHz flash
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(1) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV4(3);
#elif F_CPU == 24000000
// config divisors: 24 MHz core, 24 MHz bus, 24 MHz flash
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(3) | SIM_CLKDIV1_OUTDIV2(3) | SIM_CLKDIV1_OUTDIV4(3);
#else
#error "Error, F_CPU must be 96000000, 48000000, or 24000000"
#endif
// switch to PLL as clock source, FLL input = 16 MHz / 512
MCG_C1 = MCG_C1_CLKS(0) | MCG_C1_FRDIV(4);
// wait for PLL clock to be used
while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(3)) ;
// now we're in PEE mode
// configure USB for 48 MHz clock
SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(1); // USB = 96 MHz PLL / 2
// USB uses PLL clock, trace is CPU clock, CLKOUT=OSCERCLK0
SIM_SOPT2 = SIM_SOPT2_USBSRC | SIM_SOPT2_PLLFLLSEL | SIM_SOPT2_TRACECLKSEL | SIM_SOPT2_CLKOUTSEL(6);

// initialize the SysTick counter
SYST_RVR = (F_CPU / 1000) - 1;
SYST_CSR = SYST_CSR_CLKSOURCE | SYST_CSR_TICKINT | SYST_CSR_ENABLE;

//init_pins();
__enable_irq();

_init_Teensyduino_internal_();
if (RTC_SR & RTC_SR_TIF) rtc_set(TIME_T);

__libc_init_array();

/*
for (ptr = &__init_array_start; ptr < &__init_array_end; ptr++) {
(*ptr)();
}
*/
startup_late_hook();
main();
while (1) ;
}

// TODO: is this needed for c++ and where does it come from?
/*
void _init(void)
{
}
*/

char *__brkval = (char *)&_ebss;

void * _sbrk(int incr)
{
//static char *heap_end = (char *)&_ebss;
//char *prev = heap_end;
//heap_end += incr;

char *prev = __brkval;
__brkval += incr;
return prev;
}

int _read(int file, char *ptr, int len)
{
return 0;
}

int _write(int file, char *ptr, int len)
{
return 0;
}

int _close(int fd)
{
return -1;
}

int _lseek(int fd, long long offset, int whence)
{
return -1;
}

void _exit(int status)
{
while (1);
}

void __cxa_pure_virtual()
{
while (1);
}

int __cxa_guard_acquire (int *g)
{
return 1;
}

void __cxa_guard_release(int *g)
{
}


+ 1768
- 0
teensy3/mk20dx128.h
File diff suppressed because it is too large
View File


+ 109
- 0
teensy3/mk20dx128.ld View File

@@ -0,0 +1,109 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2013 PJRC.COM, LLC.
*
* 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:
*
* 1. The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* 2. If the Software is incorporated into a build system that allows
* selection among a list of target devices, then similar target
* devices manufactured by PJRC.COM must be included in the list of
* target devices and selectable in the same manner.
*
* 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.
*/

MEMORY
{
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 128K
RAM (rwx) : ORIGIN = 0x1FFFE000, LENGTH = 16K
}


SECTIONS
{
.text : {
. = 0;
KEEP(*(.vectors))
*(.startup*)
/* TODO: does linker detect startup overflow onto flashconfig? */
. = 0x400;
KEEP(*(.flashconfig*))
*(.text*)
*(.rodata*)
. = ALIGN(4);
KEEP(*(.init))
. = ALIGN(4);
__preinit_array_start = .;
KEEP (*(.preinit_array))
__preinit_array_end = .;
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
} > FLASH = 0xFF

.ARM.exidx : {
__exidx_start = .;
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
__exidx_end = .;
} > FLASH
_etext = .;

.usbdescriptortable (NOLOAD) : {
/* . = ORIGIN(RAM); */
. = ALIGN(512);
*(.usbdescriptortable*)
} > RAM

.dmabuffers (NOLOAD) : {
. = ALIGN(4);
*(.dmabuffers*)
} > RAM

.usbbuffers (NOLOAD) : {
. = ALIGN(4);
*(.usbbuffers*)
} > RAM

.data : AT (_etext) {
. = ALIGN(4);
_sdata = .;
*(.data*)
. = ALIGN(4);
_edata = .;
} > RAM

.noinit (NOLOAD) : {
*(.noinit*)
} > RAM

.bss : {
. = ALIGN(4);
_sbss = .;
*(.bss*)
*(COMMON)
. = ALIGN(4);
_ebss = .;
__bss_end = .;
} > RAM

_estack = ORIGIN(RAM) + LENGTH(RAM);
}



+ 85
- 0
teensy3/nonstd.c View File

@@ -0,0 +1,85 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2013 PJRC.COM, LLC.
*
* 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:
*
* 1. The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* 2. If the Software is incorporated into a build system that allows
* selection among a list of target devices, then similar target
* devices manufactured by PJRC.COM must be included in the list of
* target devices and selectable in the same manner.
*
* 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.
*/

#include "avr_functions.h"
#include <string.h>
#include <stdio.h>

size_t strlen(const char *s)
{
size_t n=0;

while (*s++) n++;
return n;
}


char * ultoa(unsigned long val, char *buf, int radix)
{
unsigned digit;
int i=0, j;
char t;

while (1) {
digit = val % radix;
buf[i] = ((digit < 10) ? '0' + digit : 'A' + digit - 10);
val /= radix;
if (val == 0) break;
i++;
}
buf[i + 1] = 0;
for (j=0; j < i; j++, i--) {
t = buf[j];
buf[j] = buf[i];
buf[i] = t;
}
return buf;
}

char * ltoa(long val, char *buf, int radix)
{
if (val >= 0) {
return ultoa(val, buf, radix);
} else {
buf[0] = '-';
ultoa(-val, buf + 1, radix);
return buf;
}
}

// TODO: actually write an efficient dtostrf()....
char * dtostrf(float val, int width, unsigned int precision, char *buf)
{
char format[20];
sprintf(format, "%%%d.%df", width, precision);
sprintf(buf, format, val);
return buf;
}


+ 102
- 0
teensy3/pins_arduino.h View File

@@ -0,0 +1,102 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2013 PJRC.COM, LLC.
*
* 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:
*
* 1. The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* 2. If the Software is incorporated into a build system that allows
* selection among a list of target devices, then similar target
* devices manufactured by PJRC.COM must be included in the list of
* target devices and selectable in the same manner.
*
* 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.
*/

#ifndef pins_macros_for_arduino_compatibility_h
#define pins_macros_for_arduino_compatibility_h

#include <stdint.h>

const static uint8_t A0 = 14;
const static uint8_t A1 = 15;
const static uint8_t A2 = 16;
const static uint8_t A3 = 17;
const static uint8_t A4 = 18;
const static uint8_t A5 = 19;
const static uint8_t A6 = 20;
const static uint8_t A7 = 21;
const static uint8_t A8 = 22;
const static uint8_t A9 = 23;
const static uint8_t A10 = 34;
const static uint8_t A11 = 35;
const static uint8_t A12 = 36;
const static uint8_t A13 = 37;

const static uint8_t SS = 10;
const static uint8_t MOSI = 11;
const static uint8_t MISO = 12;
const static uint8_t SCK = 13;
const static uint8_t LED_BUILTIN = 13;
const static uint8_t SDA = 18;
const static uint8_t SCL = 19;


#define NUM_DIGITAL_PINS 34
#define NUM_ANALOG_INPUTS 14

#define analogInputToDigitalPin(p) (((p) < 10) ? (p) + 14 : -1)
#define digitalPinHasPWM(p) (((p) >= 3 && (p) <= 6) || (p) == 9 || (p) == 10 || ((p) >= 20 && (p) <= 23))


struct digital_pin_bitband_and_config_table_struct {
volatile uint32_t *reg;
volatile uint32_t *config;
};
extern const struct digital_pin_bitband_and_config_table_struct digital_pin_to_info_PGM[];

// compatibility macros
#define digitalPinToPort(pin) (pin)
#define digitalPinToBitMask(pin) (1)
#define portOutputRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 0))
#define portSetRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 32))
#define portClearRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 64))
#define portToggleRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 96))
#define portInputRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 128))
#define portModeRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 160))
#define portConfigRegister(pin) ((volatile uint32_t *)(digital_pin_to_info_PGM[(pin)].config))


#define digitalPinToPortReg(pin) (portOutputRegister(pin))
#define digitalPinToBit(pin) (1)


#define NOT_ON_TIMER 0
static inline uint8_t digitalPinToTimer(uint8_t) __attribute__((always_inline, unused));
static inline uint8_t digitalPinToTimer(uint8_t pin)
{
if (pin >= 3 && pin <= 6) return pin - 2;
if (pin >= 9 && pin <= 10) return pin - 4;
if (pin >= 20 && pin <= 23) return pin - 13;
return NOT_ON_TIMER;
}




#endif

+ 746
- 0
teensy3/pins_teensy.c View File

@@ -0,0 +1,746 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2013 PJRC.COM, LLC.
*
* 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:
*
* 1. The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* 2. If the Software is incorporated into a build system that allows
* selection among a list of target devices, then similar target
* devices manufactured by PJRC.COM must be included in the list of
* target devices and selectable in the same manner.
*
* 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.
*/

#include "core_pins.h"
#include "pins_arduino.h"
#include "HardwareSerial.h"

#if 0
// moved to pins_arduino.h
struct digital_pin_bitband_and_config_table_struct {
volatile uint32_t *reg;
volatile uint32_t *config;
};
const struct digital_pin_bitband_and_config_table_struct digital_pin_to_info_PGM[];

// compatibility macros
#define digitalPinToPort(pin) (pin)
#define digitalPinToBitMask(pin) (1)
#define portOutputRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 0))
#define portSetRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 32))
#define portClearRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 64))
#define portToggleRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 96))
#define portInputRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 128))
#define portModeRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 160))
#define portConfigRegister(pin) ((volatile uint32_t *)(digital_pin_to_info_PGM[(pin)].config))
#endif

//#define digitalPinToTimer(P) ( pgm_read_byte( digital_pin_to_timer_PGM + (P) ) )
//#define analogInPinToBit(P) (P)

#define GPIO_BITBAND_ADDR(reg, bit) (((uint32_t)&(reg) - 0x40000000) * 32 + (bit) * 4 + 0x42000000)
#define GPIO_BITBAND_PTR(reg, bit) ((uint32_t *)GPIO_BITBAND_ADDR((reg), (bit)))
//#define GPIO_SET_BIT(reg, bit) (*GPIO_BITBAND_PTR((reg), (bit)) = 1)
//#define GPIO_CLR_BIT(reg, bit) (*GPIO_BITBAND_PTR((reg), (bit)) = 0)

const struct digital_pin_bitband_and_config_table_struct digital_pin_to_info_PGM[] = {
{GPIO_BITBAND_PTR(CORE_PIN0_PORTREG, CORE_PIN0_BIT), &CORE_PIN0_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN1_PORTREG, CORE_PIN1_BIT), &CORE_PIN1_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN2_PORTREG, CORE_PIN2_BIT), &CORE_PIN2_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN3_PORTREG, CORE_PIN3_BIT), &CORE_PIN3_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN4_PORTREG, CORE_PIN4_BIT), &CORE_PIN4_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN5_PORTREG, CORE_PIN5_BIT), &CORE_PIN5_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN6_PORTREG, CORE_PIN6_BIT), &CORE_PIN6_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN7_PORTREG, CORE_PIN7_BIT), &CORE_PIN7_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN8_PORTREG, CORE_PIN8_BIT), &CORE_PIN8_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN9_PORTREG, CORE_PIN9_BIT), &CORE_PIN9_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN10_PORTREG, CORE_PIN10_BIT), &CORE_PIN10_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN11_PORTREG, CORE_PIN11_BIT), &CORE_PIN11_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN12_PORTREG, CORE_PIN12_BIT), &CORE_PIN12_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN13_PORTREG, CORE_PIN13_BIT), &CORE_PIN13_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN14_PORTREG, CORE_PIN14_BIT), &CORE_PIN14_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN15_PORTREG, CORE_PIN15_BIT), &CORE_PIN15_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN16_PORTREG, CORE_PIN16_BIT), &CORE_PIN16_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN17_PORTREG, CORE_PIN17_BIT), &CORE_PIN17_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN18_PORTREG, CORE_PIN18_BIT), &CORE_PIN18_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN19_PORTREG, CORE_PIN19_BIT), &CORE_PIN19_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN20_PORTREG, CORE_PIN20_BIT), &CORE_PIN20_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN21_PORTREG, CORE_PIN21_BIT), &CORE_PIN21_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN22_PORTREG, CORE_PIN22_BIT), &CORE_PIN22_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN23_PORTREG, CORE_PIN23_BIT), &CORE_PIN23_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN24_PORTREG, CORE_PIN24_BIT), &CORE_PIN24_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN25_PORTREG, CORE_PIN25_BIT), &CORE_PIN25_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN26_PORTREG, CORE_PIN26_BIT), &CORE_PIN26_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN27_PORTREG, CORE_PIN27_BIT), &CORE_PIN27_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN28_PORTREG, CORE_PIN28_BIT), &CORE_PIN28_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN29_PORTREG, CORE_PIN29_BIT), &CORE_PIN29_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN30_PORTREG, CORE_PIN30_BIT), &CORE_PIN30_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN31_PORTREG, CORE_PIN31_BIT), &CORE_PIN31_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN32_PORTREG, CORE_PIN32_BIT), &CORE_PIN32_CONFIG},
{GPIO_BITBAND_PTR(CORE_PIN33_PORTREG, CORE_PIN33_BIT), &CORE_PIN33_CONFIG}
};




typedef void (*voidFuncPtr)(void);
volatile static voidFuncPtr intFunc[CORE_NUM_DIGITAL];

void init_pin_interrupts(void)
{
//SIM_SCGC5 = 0x00043F82; // clocks active to all GPIO
NVIC_ENABLE_IRQ(IRQ_PORTA);
NVIC_ENABLE_IRQ(IRQ_PORTB);
NVIC_ENABLE_IRQ(IRQ_PORTC);
NVIC_ENABLE_IRQ(IRQ_PORTD);
NVIC_ENABLE_IRQ(IRQ_PORTE);
// TODO: maybe these should be set to a lower priority
// so if the user puts lots of slow code on attachInterrupt
// fast interrupts will still be serviced quickly?
}

void attachInterrupt(uint8_t pin, void (*function)(void), int mode)
{
volatile uint32_t *config;
uint32_t cfg, mask;

if (pin >= CORE_NUM_DIGITAL) return;
switch (mode) {
case CHANGE: mask = 0x0B; break;
case RISING: mask = 0x09; break;
case FALLING: mask = 0x0A; break;
case LOW: mask = 0x08; break;
case HIGH: mask = 0x0C; break;
default: return;
}
mask = (mask << 16) | 0x01000000;
config = portConfigRegister(pin);

__disable_irq();
cfg = *config;
cfg &= ~0x000F0000; // disable any previous interrupt
*config = cfg;
intFunc[pin] = function; // set the function pointer
cfg |= mask;
*config = cfg; // enable the new interrupt
__enable_irq();
}

void detachInterrupt(uint8_t pin)
{
volatile uint32_t *config;

config = portConfigRegister(pin);
__disable_irq();
*config = ((*config & ~0x000F0000) | 0x01000000);
intFunc[pin] = NULL;
__enable_irq();
}


void porta_isr(void)
{
uint32_t isfr = PORTA_ISFR;
PORTA_ISFR = isfr;
if ((isfr & CORE_PIN3_BITMASK) && intFunc[3]) intFunc[3]();
if ((isfr & CORE_PIN4_BITMASK) && intFunc[4]) intFunc[4]();
if ((isfr & CORE_PIN24_BITMASK) && intFunc[24]) intFunc[24]();
if ((isfr & CORE_PIN33_BITMASK) && intFunc[33]) intFunc[33]();
}

void portb_isr(void)
{
uint32_t isfr = PORTB_ISFR;
PORTB_ISFR = isfr;
if ((isfr & CORE_PIN0_BITMASK) && intFunc[0]) intFunc[0]();
if ((isfr & CORE_PIN1_BITMASK) && intFunc[1]) intFunc[1]();
if ((isfr & CORE_PIN16_BITMASK) && intFunc[16]) intFunc[16]();
if ((isfr & CORE_PIN17_BITMASK) && intFunc[17]) intFunc[17]();
if ((isfr & CORE_PIN18_BITMASK) && intFunc[18]) intFunc[18]();
if ((isfr & CORE_PIN19_BITMASK) && intFunc[19]) intFunc[19]();
if ((isfr & CORE_PIN25_BITMASK) && intFunc[25]) intFunc[25]();
if ((isfr & CORE_PIN32_BITMASK) && intFunc[32]) intFunc[32]();
}

void portc_isr(void)
{
// TODO: these are inefficent. Use CLZ somehow....
uint32_t isfr = PORTC_ISFR;
PORTC_ISFR = isfr;
if ((isfr & CORE_PIN9_BITMASK) && intFunc[9]) intFunc[9]();
if ((isfr & CORE_PIN10_BITMASK) && intFunc[10]) intFunc[10]();
if ((isfr & CORE_PIN11_BITMASK) && intFunc[11]) intFunc[11]();
if ((isfr & CORE_PIN12_BITMASK) && intFunc[12]) intFunc[12]();
if ((isfr & CORE_PIN13_BITMASK) && intFunc[13]) intFunc[13]();
if ((isfr & CORE_PIN15_BITMASK) && intFunc[15]) intFunc[15]();
if ((isfr & CORE_PIN22_BITMASK) && intFunc[22]) intFunc[22]();
if ((isfr & CORE_PIN23_BITMASK) && intFunc[23]) intFunc[23]();
if ((isfr & CORE_PIN27_BITMASK) && intFunc[27]) intFunc[27]();
if ((isfr & CORE_PIN28_BITMASK) && intFunc[28]) intFunc[28]();
if ((isfr & CORE_PIN29_BITMASK) && intFunc[29]) intFunc[29]();
if ((isfr & CORE_PIN30_BITMASK) && intFunc[30]) intFunc[30]();
}

void portd_isr(void)
{
uint32_t isfr = PORTD_ISFR;
PORTD_ISFR = isfr;
if ((isfr & CORE_PIN2_BITMASK) && intFunc[2]) intFunc[2]();
if ((isfr & CORE_PIN5_BITMASK) && intFunc[5]) intFunc[5]();
if ((isfr & CORE_PIN6_BITMASK) && intFunc[6]) intFunc[6]();
if ((isfr & CORE_PIN7_BITMASK) && intFunc[7]) intFunc[7]();
if ((isfr & CORE_PIN8_BITMASK) && intFunc[8]) intFunc[8]();
if ((isfr & CORE_PIN14_BITMASK) && intFunc[14]) intFunc[14]();
if ((isfr & CORE_PIN20_BITMASK) && intFunc[20]) intFunc[20]();
if ((isfr & CORE_PIN21_BITMASK) && intFunc[21]) intFunc[21]();
}

void porte_isr(void)
{
uint32_t isfr = PORTE_ISFR;
PORTE_ISFR = isfr;
if ((isfr & CORE_PIN26_BITMASK) && intFunc[26]) intFunc[26]();
if ((isfr & CORE_PIN31_BITMASK) && intFunc[31]) intFunc[31]();
}




unsigned long rtc_get(void)
{
return RTC_TSR;
}

void rtc_set(unsigned long t)
{
RTC_SR = 0;
RTC_TPR = 0;
RTC_TSR = t;
RTC_SR = RTC_SR_TCE;
}


// adjust is the amount of crystal error to compensate, 1 = 0.1192 ppm
// For example, adjust = -100 is slows the clock by 11.92 ppm
//
void rtc_compensate(int adjust)
{
uint32_t comp, interval, tcr;

// This simple approach tries to maximize the interval.
// Perhaps minimizing TCR would be better, so the
// compensation is distributed more evenly across
// many seconds, rather than saving it all up and then
// altering one second up to +/- 0.38%
if (adjust >= 0) {
comp = adjust;
interval = 256;
while (1) {
tcr = comp * interval;
if (tcr < 128*256) break;
if (--interval == 1) break;
}
tcr = tcr >> 8;
} else {
comp = -adjust;
interval = 256;
while (1) {
tcr = comp * interval;
if (tcr < 129*256) break;
if (--interval == 1) break;
}
tcr = tcr >> 8;
tcr = 256 - tcr;
}
RTC_TCR = ((interval - 1) << 8) | tcr;
}

#if 0
// TODO: build system should define this
// so RTC is automatically initialized to approx correct time
// at least when the program begins running right after upload
#ifndef TIME_T
#define TIME_T 1350160272
#endif

void init_rtc(void)
{
serial_print("init_rtc\n");
//SIM_SCGC6 |= SIM_SCGC6_RTC;

// enable the RTC crystal oscillator, for approx 12pf crystal
if (!(RTC_CR & RTC_CR_OSCE)) {
serial_print("start RTC oscillator\n");
RTC_SR = 0;
RTC_CR = RTC_CR_SC16P | RTC_CR_SC4P | RTC_CR_OSCE;
}
// should wait for crystal to stabilize.....

serial_print("SR=");
serial_phex32(RTC_SR);
serial_print("\n");
serial_print("CR=");
serial_phex32(RTC_CR);
serial_print("\n");
serial_print("TSR=");
serial_phex32(RTC_TSR);
serial_print("\n");
serial_print("TCR=");
serial_phex32(RTC_TCR);
serial_print("\n");

if (RTC_SR & RTC_SR_TIF) {
// enable the RTC
RTC_SR = 0;
RTC_TPR = 0;
RTC_TSR = TIME_T;
RTC_SR = RTC_SR_TCE;
}
}
#endif

extern void usb_init(void);


// create a default PWM at the same 488.28 Hz as Arduino Uno
#if F_BUS == 48000000
#define DEFAULT_FTM_MOD (49152 - 1)
#define DEFAULT_FTM_PRESCALE 1
#else
#define DEFAULT_FTM_MOD (49152 - 1)
#define DEFAULT_FTM_PRESCALE 0
#endif

//void init_pins(void)
void _init_Teensyduino_internal_(void)
{
init_pin_interrupts();

//SIM_SCGC6 |= SIM_SCGC6_FTM0; // TODO: use bitband for atomic read-mod-write
//SIM_SCGC6 |= SIM_SCGC6_FTM1;
FTM0_CNT = 0;
FTM0_MOD = DEFAULT_FTM_MOD;
FTM0_C0SC = 0x28; // MSnB:MSnA = 10, ELSnB:ELSnA = 10
FTM0_C1SC = 0x28;
FTM0_C2SC = 0x28;
FTM0_C3SC = 0x28;
FTM0_C4SC = 0x28;
FTM0_C5SC = 0x28;
FTM0_C6SC = 0x28;
FTM0_C7SC = 0x28;
FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS(DEFAULT_FTM_PRESCALE);
FTM1_CNT = 0;
FTM1_MOD = DEFAULT_FTM_MOD;
FTM1_C0SC = 0x28;
FTM1_C1SC = 0x28;
FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(DEFAULT_FTM_PRESCALE);

analog_init();
//delay(100); // TODO: this is not necessary, right?
usb_init();
}



// SOPT4 is SIM select clocks?
// FTM is clocked by the bus clock, either 24 or 48 MHz
// input capture can be FTM1_CH0, CMP0 or CMP1 or USB start of frame
// 24 MHz with reload 49152 to match Arduino's speed = 488.28125 Hz

static uint8_t analog_write_res = 8;

void analogWrite(uint8_t pin, int val)
{
uint32_t cval, max;

max = 1 << analog_write_res;
if (val <= 0) {
digitalWrite(pin, LOW);
pinMode(pin, OUTPUT); // TODO: implement OUTPUT_LOW
return;
} else if (val >= max) {
digitalWrite(pin, HIGH);
pinMode(pin, OUTPUT); // TODO: implement OUTPUT_HIGH
return;
}

//serial_print("analogWrite\n");
//serial_print("val = ");
//serial_phex32(val);
//serial_print("\n");
//serial_print("analog_write_res = ");
//serial_phex(analog_write_res);
//serial_print("\n");
if (pin == 3 || pin == 4) {
cval = ((uint32_t)val * (uint32_t)(FTM1_MOD + 1)) >> analog_write_res;
//serial_print("FTM1_MOD = ");
//serial_phex32(FTM1_MOD);
//serial_print("\n");
} else {
cval = ((uint32_t)val * (uint32_t)(FTM0_MOD + 1)) >> analog_write_res;
//serial_print("FTM0_MOD = ");
//serial_phex32(FTM0_MOD);
//serial_print("\n");
}
//serial_print("cval = ");
//serial_phex32(cval);
//serial_print("\n");
switch (pin) {
case 3: // PTA12, FTM1_CH0
FTM1_C0V = cval;
CORE_PIN3_CONFIG = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
break;
case 4: // PTA13, FTM1_CH1
FTM1_C1V = cval;
CORE_PIN4_CONFIG = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
break;
case 5: // PTD7, FTM0_CH7
FTM0_C7V = cval;
CORE_PIN5_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
break;
case 6: // PTD4, FTM0_CH4
FTM0_C4V = cval;
CORE_PIN6_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
break;
case 9: // PTC3, FTM0_CH2
FTM0_C2V = cval;
CORE_PIN9_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
break;
case 10: // PTC4, FTM0_CH3
FTM0_C3V = cval;
CORE_PIN10_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
break;
case 20: // PTD5, FTM0_CH5
FTM0_C5V = cval;
CORE_PIN20_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
break;
case 21: // PTD6, FTM0_CH6
FTM0_C6V = cval;
CORE_PIN21_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
break;
case 22: // PTC1, FTM0_CH0
FTM0_C0V = cval;
CORE_PIN22_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
break;
case 23: // PTC2, FTM0_CH1
FTM0_C1V = cval;
CORE_PIN23_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
break;
default:
digitalWrite(pin, (val > 127) ? HIGH : LOW);
pinMode(pin, OUTPUT);
}
}

void analogWriteRes(uint32_t bits)
{
if (bits < 1) {
bits = 1;
} else if (bits > 16) {
bits = 16;
}
analog_write_res = bits;
}

void analogWriteFrequency(uint8_t pin, uint32_t frequency)
{
uint32_t minfreq, prescale, mod;

//serial_print("analogWriteFrequency: pin = ");
//serial_phex(pin);
//serial_print(", freq = ");
//serial_phex32(frequency);
//serial_print("\n");
for (prescale = 0; prescale < 7; prescale++) {
minfreq = (F_BUS >> 16) >> prescale;
if (frequency > minfreq) break;
}
//serial_print("F_BUS = ");
//serial_phex32(F_BUS >> prescale);
//serial_print("\n");
//serial_print("prescale = ");
//serial_phex(prescale);
//serial_print("\n");
//mod = ((F_BUS >> prescale) / frequency) - 1;
mod = (((F_BUS >> prescale) + (frequency >> 1)) / frequency) - 1;
if (mod > 65535) mod = 65535;
//serial_print("mod = ");
//serial_phex32(mod);
//serial_print("\n");
if (pin == 3 || pin == 4) {
FTM1_SC = 0;
FTM1_CNT = 0;
FTM1_MOD = mod;
FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(prescale);
} else if (pin == 5 || pin == 6 || pin == 9 || pin == 10 ||
(pin >= 20 && pin <= 23)) {
FTM0_SC = 0;
FTM0_CNT = 0;
FTM0_MOD = mod;
FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS(prescale);
}
}




// TODO: startup code needs to initialize all pins to GPIO mode, input by default

void digitalWrite(uint8_t pin, uint8_t val)
{
if (pin >= CORE_NUM_DIGITAL) return;
if (*portModeRegister(pin)) {
if (val) {
*portSetRegister(pin) = 1;
} else {
*portClearRegister(pin) = 1;
}
} else {
volatile uint32_t *config = portConfigRegister(pin);
if (val) {
// TODO use bitband for atomic read-mod-write
*config |= (PORT_PCR_PE | PORT_PCR_PS);
//*config = PORT_PCR_MUX(1) | PORT_PCR_PE | PORT_PCR_PS;
} else {
// TODO use bitband for atomic read-mod-write
*config &= ~(PORT_PCR_PE);
//*config = PORT_PCR_MUX(1);
}
}

}

uint8_t digitalRead(uint8_t pin)
{
if (pin >= CORE_NUM_DIGITAL) return 0;
return *portInputRegister(pin);
}



void pinMode(uint8_t pin, uint8_t mode)
{
volatile uint32_t *config;

if (pin >= CORE_NUM_DIGITAL) return;
config = portConfigRegister(pin);

if (mode == OUTPUT) {
*portModeRegister(pin) = 1;
*config = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
} else {
*portModeRegister(pin) = 0;
if (mode == INPUT) {
*config = PORT_PCR_MUX(1);
} else {
*config = PORT_PCR_MUX(1) | PORT_PCR_PE | PORT_PCR_PS; // pullup
}
}
}


void _shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t value)
{
if (bitOrder == LSBFIRST) {
shiftOut_lsbFirst(dataPin, clockPin, value);
} else {
shiftOut_msbFirst(dataPin, clockPin, value);
}
}

void shiftOut_lsbFirst(uint8_t dataPin, uint8_t clockPin, uint8_t value)
{
uint8_t mask;
for (mask=0x01; mask; mask <<= 1) {
digitalWrite(dataPin, value & mask);
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
}
}

void shiftOut_msbFirst(uint8_t dataPin, uint8_t clockPin, uint8_t value)
{
uint8_t mask;
for (mask=0x80; mask; mask >>= 1) {
digitalWrite(dataPin, value & mask);
digitalWrite(clockPin, HIGH);
digitalWrite(clockPin, LOW);
}
}

uint8_t _shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder)
{
if (bitOrder == LSBFIRST) {
return shiftIn_lsbFirst(dataPin, clockPin);
} else {
return shiftIn_msbFirst(dataPin, clockPin);
}
}

uint8_t shiftIn_lsbFirst(uint8_t dataPin, uint8_t clockPin)
{
uint8_t mask, value=0;
for (mask=0x01; mask; mask <<= 1) {
digitalWrite(clockPin, HIGH);
if (digitalRead(dataPin)) value |= mask;
digitalWrite(clockPin, LOW);
}
return value;
}

uint8_t shiftIn_msbFirst(uint8_t dataPin, uint8_t clockPin)
{
uint8_t mask, value=0;
for (mask=0x80; mask; mask >>= 1) {
digitalWrite(clockPin, HIGH);
if (digitalRead(dataPin)) value |= mask;
digitalWrite(clockPin, LOW);
}
return value;
}



// the systick interrupt is supposed to increment this at 1 kHz rate
volatile uint32_t systick_millis_count = 0;

//uint32_t systick_current, systick_count, systick_istatus; // testing only

uint32_t micros(void)
{
uint32_t count, current, istatus;

__disable_irq();
current = SYST_CVR;
count = systick_millis_count;
istatus = SCB_ICSR; // bit 26 indicates if systick exception pending
__enable_irq();
//systick_current = current;
//systick_count = count;
//systick_istatus = istatus & SCB_ICSR_PENDSTSET ? 1 : 0;
if ((istatus & SCB_ICSR_PENDSTSET) && current > 50) count++;
current = ((F_CPU / 1000) - 1) - current;
return count * 1000 + current / (F_CPU / 1000000);
}

void delay(uint32_t ms)
{
uint32_t start = micros();

if (ms > 0) {
while (1) {
if ((micros() - start) >= 1000) {
ms--;
if (ms == 0) return;
start += 1000;
}
yield();
}
}
}

#if F_CPU == 96000000
#define PULSEIN_LOOPS_PER_USEC 14
#elif F_CPU == 48000000
#define PULSEIN_LOOPS_PER_USEC 7
#elif F_CPU == 24000000
#define PULSEIN_LOOPS_PER_USEC 4
#endif


uint32_t pulseIn_high(volatile uint8_t *reg, uint32_t timeout)
{
uint32_t timeout_count = timeout * PULSEIN_LOOPS_PER_USEC;
uint32_t usec_start, usec_stop;
// wait for any previous pulse to end
while (*reg) {
if (--timeout_count == 0) return 0;
}
// wait for the pulse to start
while (!*reg) {
if (--timeout_count == 0) return 0;
}
usec_start = micros();
// wait for the pulse to stop
while (*reg) {
if (--timeout_count == 0) return 0;
}
usec_stop = micros();
return usec_stop - usec_start;
}

uint32_t pulseIn_low(volatile uint8_t *reg, uint32_t timeout)
{
uint32_t timeout_count = timeout * PULSEIN_LOOPS_PER_USEC;
uint32_t usec_start, usec_stop;
// wait for any previous pulse to end
while (!*reg) {
if (--timeout_count == 0) return 0;
}
// wait for the pulse to start
while (*reg) {
if (--timeout_count == 0) return 0;
}
usec_start = micros();
// wait for the pulse to stop
while (!*reg) {
if (--timeout_count == 0) return 0;
}
usec_stop = micros();
return usec_stop - usec_start;
}

// TODO: an inline version should handle the common case where state is const
uint32_t pulseIn(uint8_t pin, uint8_t state, uint32_t timeout)
{
if (pin >= CORE_NUM_DIGITAL) return 0;
if (state) return pulseIn_high(portInputRegister(pin), timeout);
return pulseIn_low(portInputRegister(pin), timeout);;
}





























+ 0
- 0
teensy3/serial1.c View File


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save