Browse Source

initial commit

main
John Robinson 3 years ago
commit
4aaa09bd80
No known key found for this signature in database
100 changed files with 32184 additions and 0 deletions
  1. +12
    -0
      .piopm
  2. +1569
    -0
      boards.txt
  3. +2
    -0
      cores/teensy/Arduino.h
  4. +29
    -0
      cores/teensy/Client.h
  5. +231
    -0
      cores/teensy/HardwareSerial.cpp
  6. +32
    -0
      cores/teensy/HardwareSerial.h
  7. +88
    -0
      cores/teensy/IPAddress.cpp
  8. +86
    -0
      cores/teensy/IPAddress.h
  9. +1
    -0
      cores/teensy/Keyboard.h
  10. +53
    -0
      cores/teensy/MIDIUSB.h
  11. +1
    -0
      cores/teensy/Mouse.h
  12. +397
    -0
      cores/teensy/Print.cpp
  13. +118
    -0
      cores/teensy/Print.h
  14. +43
    -0
      cores/teensy/Printable.h
  15. +2
    -0
      cores/teensy/SPIFIFO.h
  16. +12
    -0
      cores/teensy/Server.h
  17. +310
    -0
      cores/teensy/Stream.cpp
  18. +66
    -0
      cores/teensy/Stream.h
  19. +269
    -0
      cores/teensy/Tone.cpp
  20. +92
    -0
      cores/teensy/Udp.h
  21. +168
    -0
      cores/teensy/WCharacter.h
  22. +1
    -0
      cores/teensy/WConstants.h
  23. +132
    -0
      cores/teensy/WInterrupts.c
  24. +60
    -0
      cores/teensy/WMath.cpp
  25. +48
    -0
      cores/teensy/WProgram.h
  26. +761
    -0
      cores/teensy/WString.cpp
  27. +216
    -0
      cores/teensy/WString.h
  28. +515
    -0
      cores/teensy/binary.h
  29. +18
    -0
      cores/teensy/core_id.h
  30. +2453
    -0
      cores/teensy/core_pins.h
  31. +81
    -0
      cores/teensy/elapsedMillis.h
  32. +66
    -0
      cores/teensy/keylayouts.c
  33. +5789
    -0
      cores/teensy/keylayouts.h
  34. +14
    -0
      cores/teensy/main.cpp
  35. +1
    -0
      cores/teensy/main.cxx
  36. +388
    -0
      cores/teensy/malloc.c
  37. +28
    -0
      cores/teensy/new.cpp
  38. +26
    -0
      cores/teensy/new.h
  39. +2
    -0
      cores/teensy/pgmspace.h
  40. +164
    -0
      cores/teensy/pins_arduino.h
  41. +1897
    -0
      cores/teensy/pins_teensy.c
  42. +15
    -0
      cores/teensy/usb.c
  43. +15
    -0
      cores/teensy/usb_api.cpp
  44. +15
    -0
      cores/teensy/usb_api.h
  45. +153
    -0
      cores/teensy/usb_common.h
  46. +15
    -0
      cores/teensy/usb_private.h
  47. +80
    -0
      cores/teensy/wiring.c
  48. +110
    -0
      cores/teensy/wiring.h
  49. +72
    -0
      cores/teensy/wiring_private.h
  50. +46
    -0
      cores/teensy/yield.cpp
  51. +9
    -0
      cores/teensy3/Arduino.h
  52. +352
    -0
      cores/teensy3/AudioStream.cpp
  53. +192
    -0
      cores/teensy3/AudioStream.h
  54. +48
    -0
      cores/teensy3/Client.h
  55. +233
    -0
      cores/teensy3/DMAChannel.cpp
  56. +1107
    -0
      cores/teensy3/DMAChannel.h
  57. +355
    -0
      cores/teensy3/EventResponder.cpp
  58. +279
    -0
      cores/teensy3/EventResponder.h
  59. +72
    -0
      cores/teensy3/FS.h
  60. +45
    -0
      cores/teensy3/HardwareSerial.cpp
  61. +506
    -0
      cores/teensy3/HardwareSerial.h
  62. +43
    -0
      cores/teensy3/HardwareSerial1.cpp
  63. +40
    -0
      cores/teensy3/HardwareSerial2.cpp
  64. +41
    -0
      cores/teensy3/HardwareSerial3.cpp
  65. +45
    -0
      cores/teensy3/HardwareSerial4.cpp
  66. +45
    -0
      cores/teensy3/HardwareSerial5.cpp
  67. +49
    -0
      cores/teensy3/HardwareSerial6.cpp
  68. +65
    -0
      cores/teensy3/IPAddress.cpp
  69. +125
    -0
      cores/teensy3/IPAddress.h
  70. +145
    -0
      cores/teensy3/IntervalTimer.cpp
  71. +147
    -0
      cores/teensy3/IntervalTimer.h
  72. +3
    -0
      cores/teensy3/Keyboard.h
  73. +56
    -0
      cores/teensy3/MIDIUSB.h
  74. +147
    -0
      cores/teensy3/Makefile
  75. +3
    -0
      cores/teensy3/Mouse.h
  76. +337
    -0
      cores/teensy3/Print.cpp
  77. +132
    -0
      cores/teensy3/Print.h
  78. +42
    -0
      cores/teensy3/Printable.h
  79. +346
    -0
      cores/teensy3/SPIFIFO.h
  80. +33
    -0
      cores/teensy3/Server.h
  81. +292
    -0
      cores/teensy3/Stream.cpp
  82. +73
    -0
      cores/teensy3/Stream.h
  83. +152
    -0
      cores/teensy3/Tone.cpp
  84. +92
    -0
      cores/teensy3/Udp.h
  85. +168
    -0
      cores/teensy3/WCharacter.h
  86. +3
    -0
      cores/teensy3/WConstants.h
  87. +66
    -0
      cores/teensy3/WMath.cpp
  88. +108
    -0
      cores/teensy3/WProgram.h
  89. +736
    -0
      cores/teensy3/WString.cpp
  90. +227
    -0
      cores/teensy3/WString.h
  91. +579
    -0
      cores/teensy3/analog.c
  92. +38
    -0
      cores/teensy3/arm_common_tables.h
  93. +7574
    -0
      cores/teensy3/arm_math.h
  94. +44
    -0
      cores/teensy3/avr/eeprom.h
  95. +1
    -0
      cores/teensy3/avr/interrupt.h
  96. +23
    -0
      cores/teensy3/avr/io.h
  97. +132
    -0
      cores/teensy3/avr/pgmspace.h
  98. +26
    -0
      cores/teensy3/avr/power.h
  99. +46
    -0
      cores/teensy3/avr/sleep.h
  100. +0
    -0
      cores/teensy3/avr/wdt.h

+ 12
- 0
.piopm View File

@@ -0,0 +1,12 @@
{
"type": "tool",
"name": "framework-arduinoteensy-cxx17",
"version": "0.1.0",
"spec": {
"owner": "skepto",
"id": 99999,
"name": "framework-arduinoteensy-cxx17",
"requirements": null,
"url": null
}
}

+ 1569
- 0
boards.txt
File diff suppressed because it is too large
View File


+ 2
- 0
cores/teensy/Arduino.h View File

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

+ 29
- 0
cores/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

+ 231
- 0
cores/teensy/HardwareSerial.cpp View File

@@ -0,0 +1,231 @@
/* 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"
#include "wiring_private.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;
}

void HardwareSerial::transmitterEnable(uint8_t pin)
{
while (transmitting) ;
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
tx_enable_pin = pin;
}

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::availableForWrite(void)
{
uint8_t head, tail;

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

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;
uint8_t status;

if (!(UCSR1B & (1<<TXEN1))) {
#if ARDUINO >= 100
setWriteError();
return 0;
#else
return;
#endif
}
if (tx_enable_pin < 255 && !transmitting) {
digitalWrite(tx_enable_pin, HIGH);
}
// If the buffer and the data register is empty, just write the byte
// to the data register and be done. This shortcut helps
// significantly improve the effective datarate at high (>
// 500kbit/s) bitrates, where interrupt overhead becomes a slowdown.
if ((tx_buffer_head == tx_buffer_tail) && (UCSR1A & (1<<UDRE1))) {
status = SREG;
cli();
UDR1 = c;
transmitting = 1;
SREG = status;
return 1;
}

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);
sbi(UCSR1B, 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);
cbi(UCSR1B, UDRIE1);
} 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;




+ 32
- 0
cores/teensy/HardwareSerial.h View File

@@ -0,0 +1,32 @@
#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);
void transmitterEnable(uint8_t pin);
virtual int available(void);
virtual int peek(void);
virtual int read(void);
virtual void flush(void);
int availableForWrite(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

+ 88
- 0
cores/teensy/IPAddress.cpp View File

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

IPAddress::IPAddress()
{
_address.dword = 0;
}

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

IPAddress::IPAddress(uint32_t address)
{
_address.dword = address;
}

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

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

IPAddress& IPAddress::operator=(uint32_t address)
{
_address.dword = address;
return *this;
}

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

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

bool IPAddress::fromString(const char *address)
{
uint16_t acc = 0; // Accumulator
uint8_t dots = 0;

while (*address) {
char c = *address++;
if (c >= '0' && c <= '9') {
acc = acc * 10 + (c - '0');
if (acc > 255) {
// Value out of [0..255] range
return false;
}
} else if (c == '.') {
if (dots == 3) {
// Too much dots (there must be 3 dots)
return false;
}
_address.bytes[dots++] = acc;
acc = 0;
} else {
// Invalid char
return false;
}
}
if (dots != 3) {
// Too few dots (there must be 3 dots)
return false;
}
_address.bytes[3] = acc;
return true;
}

#endif

+ 86
- 0
cores/teensy/IPAddress.h View File

@@ -0,0 +1,86 @@
/*
*
* 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:
union {
uint8_t bytes[4]; // IPv4 address
uint32_t dword;
} _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.bytes; };

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

bool fromString(const char *address);
bool fromString(const String &address) {
return fromString(address.c_str());
}

// 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.dword; };
bool operator==(const IPAddress& addr) { return _address.dword == addr._address.dword; };
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.bytes[index]; };
uint8_t& operator[](int index) { return _address.bytes[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

+ 1
- 0
cores/teensy/Keyboard.h View File

@@ -0,0 +1 @@
// empty Keyboard.h file, for compability with Arduino's Keyboard examples

+ 53
- 0
cores/teensy/MIDIUSB.h View File

@@ -0,0 +1,53 @@
#ifndef MIDIUSB_h
#define MIDIUSB_h

// For compatibility with Arduino's MIDIUSB library

#ifdef __cplusplus
#if !defined(USB_MIDI)
#error "Please select MIDI in Tools > USB Type to use MIDIUSB.h"
#endif

#include "usb_api.h"

typedef struct {
struct {
uint8_t header;
uint8_t byte1;
uint8_t byte2;
uint8_t byte3;
};
} midiEventPacket_t;


class MIDI_
{
public:
constexpr MIDI_(void) { }
uint32_t available(void) {
return usbMIDI.midiusb_available();
}
midiEventPacket_t read(void) {
midiEventPacket_t event;
usbMIDI.midiusb_read((uint8_t *)&event);
return event;
}
void flush(void) {
usbMIDI.send_now();
}
void sendMIDI(midiEventPacket_t event) {
usbMIDI.send_raw(event.header, event.byte1, event.byte2, event.byte3);
}
size_t write(const uint8_t *buffer, size_t size) {
// TODO - is this really needed?
return 0;
}
operator bool() {
// TODO - is this really needed?
return true;
}
};
extern MIDI_ MidiUSB;

#endif // __cplusplus
#endif // MIDIUSB_h

+ 1
- 0
cores/teensy/Mouse.h View File

@@ -0,0 +1 @@
// empty Mouse.h file, for compability with Arduino's Mouse examples

+ 397
- 0
cores/teensy/Print.cpp View File

@@ -0,0 +1,397 @@
/*
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(const __FlashStringHelper *ifsh)
{
uint8_t buffer[32];
size_t count = 0;
const char *p = (const char *)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;
}

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

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

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

static int printf_putchar(char c, FILE *fp)
{
((class Print *)(fdev_get_udata(fp)))->write((uint8_t)c);
return 0;
}

int Print::printf(const char *format, ...)
{
FILE f;
va_list ap;

fdev_setup_stream(&f, printf_putchar, NULL, _FDEV_SETUP_WRITE);
fdev_set_udata(&f, this);
va_start(ap, format);
return vfprintf(&f, format, ap);
}

int Print::printf(const __FlashStringHelper *format, ...)
{
FILE f;
va_list ap;

fdev_setup_stream(&f, printf_putchar, NULL, _FDEV_SETUP_WRITE);
fdev_set_udata(&f, this);
va_start(ap, format);
return vfprintf_P(&f, (const char *)format, ap);
}


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


size_t Print::printNumberDec(unsigned long n, uint8_t sign)
{
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));
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
return write(p, sizeof(buf) - (p - buf));
}

size_t Print::printNumberHex(unsigned long n)
{
uint8_t digit, buf[8], *p;

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

size_t Print::printNumberBin(unsigned long n)
{
uint8_t buf[32], *p;

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

size_t Print::printNumberAny(unsigned long n, uint8_t base)
{
uint8_t digit, buf[21], *p;
uint32_t tmp;
//uint32_t usec;

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

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, sign, 10);

// 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;
}


+ 118
- 0
cores/teensy/Print.h View File

@@ -0,0 +1,118 @@
/*
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 <stdarg.h>
#include "core_id.h"
#include "WString.h"
#include "Printable.h"

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

// BYTE was defined in very old versions of Arduino
// maybe this now causes more trouble than it's worth?
//#ifndef BYTE
//#define BYTE 0
//#endif

class __FlashStringHelper;

class Print
{
public:
constexpr 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);
virtual int availableForWrite(void) { return 0; }
virtual void flush() { }
size_t write(const char *buffer, size_t size) { return write((const uint8_t *)buffer, 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); }
int printf(const char *format, ...);
int printf(const __FlashStringHelper *format, ...);
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);
};


#endif

+ 43
- 0
cores/teensy/Printable.h View File

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

#ifdef __cplusplus

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

+ 2
- 0
cores/teensy/SPIFIFO.h View File

@@ -0,0 +1,2 @@
// Teensy 2.0 does not have SPIFIFO. This file exists so libraries
// may use #include "SPIFIFO.h", and then test for HAS_SPIFIFO

+ 12
- 0
cores/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
cores/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(const 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(const 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(const 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(const 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;
}



























+ 66
- 0
cores/teensy/Stream.h View File

@@ -0,0 +1,66 @@
/*
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(const char *target);
bool find(const uint8_t *target) { return find ((const char *)target); }
bool find(const char *target, size_t length);
bool find(const uint8_t *target, size_t length) { return find ((const char *)target, length); }
bool findUntil(const char *target, char *terminator);
bool findUntil(const uint8_t *target, char *terminator) { return findUntil((const char *)target, terminator); }
bool findUntil(const char *target, size_t targetLen, char *terminate, size_t termLen);
bool findUntil(const uint8_t *target, size_t targetLen, char *terminate, size_t termLen) {return findUntil((const char *)target, targetLen, terminate, termLen); }
long parseInt();
long parseInt(char skipChar);
float parseFloat();
float parseFloat(char skipChar);
size_t readBytes(char *buffer, size_t length);
size_t readBytes( uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); }
size_t readBytesUntil(char terminator, char *buffer, size_t length);
size_t readBytesUntil(char terminator, uint8_t *buffer, size_t length) { return readBytesUntil(terminator, (char *)buffer, 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
cores/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;
}
}
}
}



+ 92
- 0
cores/teensy/Udp.h View File

@@ -0,0 +1,92 @@
/*
* 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 uint8_t beginMulticast(IPAddress, uint16_t) { return 0; }
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
cores/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
cores/teensy/WConstants.h View File

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

+ 132
- 0
cores/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
cores/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
cores/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

+ 761
- 0
cores/teensy/WString.cpp View File

@@ -0,0 +1,761 @@
/*
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(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
cores/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
cores/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
cores/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

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


+ 81
- 0
cores/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
cores/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) & KEYCODE_MASK)

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


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


+ 14
- 0
cores/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
cores/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
cores/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=NULL, *sfp2=NULL;
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;
}


+ 28
- 0
cores/teensy/new.cpp View File

@@ -0,0 +1,28 @@
#include "new.h"

void * operator new(size_t size)
{
return malloc(size);
}

void * operator new[](size_t size)
{
return malloc(size);
}

void operator delete(void * ptr)
{
free(ptr);
}

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) {};


+ 26
- 0
cores/teensy/new.h View File

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

#ifdef __cplusplus

#include <stdlib.h>

void * operator new(size_t size);
void * operator new[](size_t size);
void operator delete(void * ptr);
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 // __cplusplus

#endif

+ 2
- 0
cores/teensy/pgmspace.h View File

@@ -0,0 +1,2 @@
// For compatibility with some ESP8266 programs
#include <avr/pgmspace.h>

+ 164
- 0
cores/teensy/pins_arduino.h View File

@@ -0,0 +1,164 @@
#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

// default CS pin to use for Ethernet library
#if defined(__AVR_ATmega32U4__)
#define PIN_SPI_SS_ETHERNET_LIB 0
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
#define PIN_SPI_SS_ETHERNET_LIB 20
#endif

// 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 NOT_AN_INTERRUPT -1

#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)
#define digitalPinToInterrupt(p) (((p) <= 3 || (p) == 6 || (p) == 8) ? (p) : ((p) == 4 ? 5 : ((p) == 16 ? 4 : -1)))
#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)
#define digitalPinToInterrupt(p) (((p) >= 5 && (p) <= 8) ? (p) - 5 : -1)
#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)
#define digitalPinToInterrupt(p) ((p) <= 3 ? (p) : (((p) == 36 || (p) == 37) ? (p) - 32 : (((p) == 18 || (p) == 19) ? (p) - 12 : -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;
}
}

#define SERIAL_PORT_MONITOR Serial
#define SERIAL_PORT_USBVIRTUAL Serial
#define SERIAL_PORT_HARDWARE Serial1
#define SERIAL_PORT_HARDWARE_OPEN Serial1

#define SerialUSB Serial

#endif

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


+ 15
- 0
cores/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
cores/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
cores/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
cores/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
cores/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
cores/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();
}



+ 110
- 0
cores/teensy/wiring.h View File

@@ -0,0 +1,110 @@
/*
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 <stdbool.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 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 bool 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
cores/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

+ 46
- 0
cores/teensy/yield.cpp View File

@@ -0,0 +1,46 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2014 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"

void yield(void) __attribute__ ((weak));
void yield(void)
{
//static uint8_t running=0;

//if (running) return; // TODO: does this need to be atomic?
//running = 1;
//if (Serial.available()) serialEvent();
//if (Serial1.available()) serialEvent1();
//if (Serial2.available()) serialEvent2();
//if (Serial3.available()) serialEvent3();
//running = 0;
};

+ 9
- 0
cores/teensy3/Arduino.h View File

@@ -0,0 +1,9 @@
// This header file is in the public domain.

#ifndef Arduino_h
#define Arduino_h

#include "WProgram.h"
#include "pins_arduino.h"

#endif

+ 352
- 0
cores/teensy3/AudioStream.cpp View File

@@ -0,0 +1,352 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2017 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 <Arduino.h>
#include "AudioStream.h"

#if defined(__MKL26Z64__)
#define MAX_AUDIO_MEMORY 6144
#elif defined(__MK20DX128__)
#define MAX_AUDIO_MEMORY 12288
#elif defined(__MK20DX256__)
#define MAX_AUDIO_MEMORY 49152
#elif defined(__MK64FX512__)
#define MAX_AUDIO_MEMORY 163840
#elif defined(__MK66FX1M0__)
#define MAX_AUDIO_MEMORY 229376
#endif

#define NUM_MASKS (((MAX_AUDIO_MEMORY / AUDIO_BLOCK_SAMPLES / 2) + 31) / 32)

audio_block_t * AudioStream::memory_pool;
uint32_t AudioStream::memory_pool_available_mask[NUM_MASKS];
uint16_t AudioStream::memory_pool_first_mask;

uint16_t AudioStream::cpu_cycles_total = 0;
uint16_t AudioStream::cpu_cycles_total_max = 0;
uint16_t AudioStream::memory_used = 0;
uint16_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)
{
unsigned int i;
unsigned int maxnum = MAX_AUDIO_MEMORY / AUDIO_BLOCK_SAMPLES / 2;

//Serial.println("AudioStream initialize_memory");
//delay(10);
if (num > maxnum) num = maxnum;
__disable_irq();
memory_pool = data;
memory_pool_first_mask = 0;
for (i=0; i < NUM_MASKS; i++) {
memory_pool_available_mask[i] = 0;
}
for (i=0; i < num; i++) {
memory_pool_available_mask[i >> 5] |= (1 << (i & 0x1F));
}
for (i=0; i < num; i++) {
data[i].memory_pool_index = i;
}
__enable_irq();

}

// 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, index, avail;
uint32_t *p, *end;
audio_block_t *block;
uint32_t used;

p = memory_pool_available_mask;
end = p + NUM_MASKS;
__disable_irq();
index = memory_pool_first_mask;
p += index;
while (1) {
if (p >= end) {
__enable_irq();
//Serial.println("alloc:null");
return NULL;
}
avail = *p;
if (avail) break;
index++;
p++;
}
n = __builtin_clz(avail);
avail &= ~(0x80000000 >> n);
*p = avail;
if (!avail) index++;
memory_pool_first_mask = index;
used = memory_used + 1;
memory_used = used;
__enable_irq();
index = p - memory_pool_available_mask;
block = memory_pool + ((index << 5) + (31 - n));
block->ref_count = 1;
if (used > memory_used_max) memory_used_max = used;
//Serial.print("alloc:");
//Serial.println((uint32_t)block, HEX);
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)
{
//if (block == NULL) return;
uint32_t mask = (0x80000000 >> (31 - (block->memory_pool_index & 0x1F)));
uint32_t index = block->memory_pool_index >> 5;

__disable_irq();
if (block->ref_count > 1) {
block->ref_count--;
} else {
//Serial.print("reles:");
//Serial.println((uint32_t)block, HEX);
memory_pool_available_mask[index] |= mask;
if (index < memory_pool_first_mask) memory_pool_first_mask = index;
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 must be released
// by the caller after it's transmitted. This allows the
// caller to transmit to same block to more than 1 output,
// and then release it once after all transmit calls.
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 (isConnected) return;
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) {
if (&p->src == &this->src && &p->dst == &this->dst
&& p->src_index == this->src_index && p->dest_index == this->dest_index) {
//Source and destination already connected through another connection, abort
__enable_irq();
return;
}
p = p->next_dest;
}
p->next_dest = this;
}
this->next_dest = NULL;
src.numConnections++;
src.active = true;

dst.numConnections++;
dst.active = true;

isConnected = true;

__enable_irq();
}

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

if (!isConnected) return;
if (dest_index > dst.num_inputs) return;
__disable_irq();
// Remove destination from source list
p = src.destination_list;
if (p == NULL) {
//>>> PAH re-enable the IRQ
__enable_irq();
return;
} else if (p == this) {
if (p->next_dest) {
src.destination_list = next_dest;
} else {
src.destination_list = NULL;
}
} else {
while (p) {
if (p == this) {
if (p->next_dest) {
p = next_dest;
break;
} else {
p = NULL;
break;
}
}
p = p->next_dest;
}
}
//>>> PAH release the audio buffer properly
//Remove possible pending src block from destination
if(dst.inputQueue[dest_index] != NULL) {
AudioStream::release(dst.inputQueue[dest_index]);
// release() re-enables the IRQ. Need it to be disabled a little longer
__disable_irq();
dst.inputQueue[dest_index] = NULL;
}

//Check if the disconnected AudioStream objects should still be active
src.numConnections--;
if (src.numConnections == 0) {
src.active = false;
}

dst.numConnections--;
if (dst.numConnections == 0) {
dst.active = false;
}

isConnected = false;

__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, 208); // 255 = lowest priority
NVIC_ENABLE_IRQ(IRQ_SOFTWARE);
update_scheduled = true;
return true;
}

void AudioStream::update_stop(void)
{
NVIC_DISABLE_IRQ(IRQ_SOFTWARE);
update_scheduled = false;
}

AudioStream * AudioStream::first_update = NULL;

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

#if defined(KINETISK)
ARM_DEMCR |= ARM_DEMCR_TRCENA;
ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;
uint32_t totalcycles = ARM_DWT_CYCCNT;
#elif defined(KINETISL)
uint32_t totalcycles = micros();
#endif
//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);
#if defined(KINETISK)
totalcycles = (ARM_DWT_CYCCNT - totalcycles) >> 4;
#elif defined(KINETISL)
totalcycles = micros() - totalcycles;
#endif
AudioStream::cpu_cycles_total = totalcycles;
if (totalcycles > AudioStream::cpu_cycles_total_max)
AudioStream::cpu_cycles_total_max = totalcycles;
}


+ 192
- 0
cores/teensy3/AudioStream.h View File

@@ -0,0 +1,192 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2017 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

#ifndef __ASSEMBLER__
#include <stdio.h> // for NULL
#include <string.h> // for memcpy
#include "kinetis.h"
#endif

// AUDIO_BLOCK_SAMPLES determines how many samples the audio library processes
// per update. It may be reduced to achieve lower latency response to events,
// at the expense of higher interrupt and DMA setup overhead.
//
// Less than 32 may not work with some input & output objects. Multiples of 16
// should be used, since some synthesis objects generate 16 samples per loop.
//
// Some parts of the audio library may have hard-coded dependency on 128 samples.
// Please report these on the forum with reproducible test cases.

#ifndef AUDIO_BLOCK_SAMPLES
#if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
#define AUDIO_BLOCK_SAMPLES 128
#elif defined(__MKL26Z64__)
#define AUDIO_BLOCK_SAMPLES 64
#endif
#endif

#ifndef AUDIO_SAMPLE_RATE_EXACT
#if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
#define AUDIO_SAMPLE_RATE_EXACT 44117.64706 // 48 MHz / 1088, or 96 MHz * 2 / 17 / 256
#elif defined(__MKL26Z64__)
//#define AUDIO_SAMPLE_RATE_EXACT 22058.82353 // 48 MHz / 2176, or 96 MHz * 1 / 17 / 256
#define AUDIO_SAMPLE_RATE_EXACT 44117.64706
#endif
#endif

#define AUDIO_SAMPLE_RATE AUDIO_SAMPLE_RATE_EXACT

#ifndef __ASSEMBLER__
class AudioStream;
class AudioConnection;

typedef struct audio_block_struct {
uint8_t ref_count;
uint8_t reserved1;
uint16_t 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)
{ isConnected = false;
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)
{ isConnected = false;
connect(); }
friend class AudioStream;
~AudioConnection() {
disconnect();
}
void disconnect(void);
void connect(void);
protected:
AudioStream &src;
AudioStream &dst;
unsigned char src_index;
unsigned char dest_index;
AudioConnection *next_dest;
bool isConnected;
};


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

#if defined(KINETISK)
#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))
#elif defined(KINETISL)
#define CYCLE_COUNTER_APPROX_PERCENT(n) ((n) * (int)(AUDIO_SAMPLE_RATE) + (int)(AUDIO_SAMPLE_RATE/2)) / (AUDIO_BLOCK_SAMPLES * 10000)
#endif

#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;
numConnections = 0;
}
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; }
bool isActive(void) { return active; }
uint16_t cpu_cycles;
uint16_t cpu_cycles_max;
static uint16_t cpu_cycles_total;
static uint16_t cpu_cycles_total_max;
static uint16_t memory_used;
static uint16_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_stop(void);
static void update_all(void) { NVIC_SET_PENDING(IRQ_SOFTWARE); }
friend void software_isr(void);
friend class AudioConnection;
uint8_t numConnections;
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 uint32_t memory_pool_available_mask[];
static uint16_t memory_pool_first_mask;
};

#endif
#endif

+ 48
- 0
cores/teensy3/Client.h View File

@@ -0,0 +1,48 @@
/*
Client.h - Base class that provides Client
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 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

+ 233
- 0
cores/teensy3/DMAChannel.cpp View File

@@ -0,0 +1,233 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2017 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 "DMAChannel.h"

#if DMA_NUM_CHANNELS <= 16
#define DMA_MAX_CHANNELS DMA_NUM_CHANNELS
#else
#define DMA_MAX_CHANNELS 16
#endif


// The channel allocation bitmask is accessible from "C" namespace,
// so C-only code can reserve DMA channels
uint16_t dma_channel_allocated_mask = 0;



/****************************************************************/
/** Teensy 3.0 & 3.1 **/
/****************************************************************/
#if defined(KINETISK)

void DMAChannel::begin(bool force_initialization)
{
uint32_t ch = 0;

__disable_irq();
if (!force_initialization && TCD && channel < DMA_MAX_CHANNELS
&& (dma_channel_allocated_mask & (1 << channel))
&& (uint32_t)TCD == (uint32_t)(0x40009000 + channel * 32)) {
// DMA channel already allocated
__enable_irq();
return;
}
while (1) {
if (!(dma_channel_allocated_mask & (1 << ch))) {
dma_channel_allocated_mask |= (1 << ch);
__enable_irq();
break;
}
if (++ch >= DMA_MAX_CHANNELS) {
__enable_irq();
TCD = (TCD_t *)0;
channel = DMA_MAX_CHANNELS;
return; // no more channels available
// attempts to use this object will hardfault
}
}
channel = ch;
SIM_SCGC7 |= SIM_SCGC7_DMA;
SIM_SCGC6 |= SIM_SCGC6_DMAMUX;
#if DMA_NUM_CHANNELS <= 16
DMA_CR = DMA_CR_EMLM | DMA_CR_EDBG; // minor loop mapping is available
#else
DMA_CR = DMA_CR_GRP1PRI| DMA_CR_EMLM | DMA_CR_EDBG;
#endif
DMA_CERQ = ch;
DMA_CERR = ch;
DMA_CEEI = ch;
DMA_CINT = ch;
TCD = (TCD_t *)(0x40009000 + ch * 32);
uint32_t *p = (uint32_t *)TCD;
*p++ = 0;
*p++ = 0;
*p++ = 0;
*p++ = 0;
*p++ = 0;
*p++ = 0;
*p++ = 0;
*p++ = 0;
}

void DMAChannel::release(void)
{
if (channel >= DMA_MAX_CHANNELS) return;
DMA_CERQ = channel;
__disable_irq();
dma_channel_allocated_mask &= ~(1 << channel);
__enable_irq();
channel = DMA_MAX_CHANNELS;
TCD = (TCD_t *)0;
}

static uint32_t priority(const DMAChannel &c)
{
uint32_t n;
n = *(uint32_t *)((uint32_t)&DMA_DCHPRI3 + (c.channel & 0xFC));
n = __builtin_bswap32(n);
return (n >> ((c.channel & 0x03) << 3)) & 0x0F;
}

static void swap(DMAChannel &c1, DMAChannel &c2)
{
uint8_t c;
DMABaseClass::TCD_t *t;

c = c1.channel;
c1.channel = c2.channel;
c2.channel = c;
t = c1.TCD;
c1.TCD = c2.TCD;
c2.TCD = t;
}

/****************************************************************/
/** Teensy-LC **/
/****************************************************************/
#elif defined(KINETISL)


void DMAChannel::begin(bool force_initialization)
{
uint32_t ch = 0;

__disable_irq();
if (!force_initialization && CFG && channel < DMA_MAX_CHANNELS
&& (dma_channel_allocated_mask & (1 << channel))
&& (uint32_t)CFG == (uint32_t)(0x40008100 + channel * 16)) {
// DMA channel already allocated
__enable_irq();
return;
}
while (1) {
if (!(dma_channel_allocated_mask & (1 << ch))) {
dma_channel_allocated_mask |= (1 << ch);
__enable_irq();
break;
}
if (++ch >= DMA_MAX_CHANNELS) {
__enable_irq();
CFG = (CFG_t *)0;
channel = DMA_MAX_CHANNELS;
return; // no more channels available
// attempts to use this object will hardfault
}
}
channel = ch;
SIM_SCGC7 |= SIM_SCGC7_DMA;
SIM_SCGC6 |= SIM_SCGC6_DMAMUX;
CFG = (CFG_t *)(0x40008100 + ch * 16);
CFG->DSR_BCR = DMA_DSR_BCR_DONE;
CFG->DCR = DMA_DCR_CS;
CFG->SAR = NULL;
CFG->DAR = NULL;
}

void DMAChannel::release(void)
{
if (channel >= DMA_MAX_CHANNELS) return;
CFG->DSR_BCR = DMA_DSR_BCR_DONE;
__disable_irq();
dma_channel_allocated_mask &= ~(1 << channel);
__enable_irq();
channel = 16;
CFG = (CFG_t *)0;
}

static uint32_t priority(const DMAChannel &c)
{
return 3 - c.channel;
}

static void swap(DMAChannel &c1, DMAChannel &c2)
{
uint8_t c;
DMABaseClass::CFG_t *t;

c = c1.channel;
c1.channel = c2.channel;
c2.channel = c;
t = c1.CFG;
c1.CFG = c2.CFG;
c2.CFG = t;
}




#endif




void DMAPriorityOrder(DMAChannel &ch1, DMAChannel &ch2)
{
if (priority(ch1) < priority(ch2)) swap(ch1, ch2);
}

void DMAPriorityOrder(DMAChannel &ch1, DMAChannel &ch2, DMAChannel &ch3)
{
if (priority(ch2) < priority(ch3)) swap(ch2, ch3);
if (priority(ch1) < priority(ch2)) swap(ch1, ch2);
if (priority(ch2) < priority(ch3)) swap(ch2, ch3);
}

void DMAPriorityOrder(DMAChannel &ch1, DMAChannel &ch2, DMAChannel &ch3, DMAChannel &ch4)
{
if (priority(ch3) < priority(ch4)) swap(ch3, ch4);
if (priority(ch2) < priority(ch3)) swap(ch2, ch3);
if (priority(ch1) < priority(ch2)) swap(ch1, ch2);
if (priority(ch3) < priority(ch4)) swap(ch2, ch3);
if (priority(ch2) < priority(ch3)) swap(ch1, ch2);
if (priority(ch3) < priority(ch4)) swap(ch2, ch3);
}


+ 1107
- 0
cores/teensy3/DMAChannel.h
File diff suppressed because it is too large
View File


+ 355
- 0
cores/teensy3/EventResponder.cpp View File

@@ -0,0 +1,355 @@
/* EventResponder - Simple event-based programming for Arduino
* Copyright 2017 Paul Stoffregen
*
* 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.
*/

/* EventResponder is an experimental API, almost certain to
* incompatibly change as it develops. Please understand any
* programs you write now using EventResponder may need to be
* updated as EventResponder develops.
*
* Please post EventResponder post your feedback here:
* https://forum.pjrc.com/threads/44723-Arduino-Events
*/

#include <Arduino.h>
#include "EventResponder.h"

EventResponder * EventResponder::firstYield = nullptr;
EventResponder * EventResponder::lastYield = nullptr;
EventResponder * EventResponder::firstInterrupt = nullptr;
EventResponder * EventResponder::lastInterrupt = nullptr;
bool EventResponder::runningFromYield = false;

// TODO: interrupt disable/enable needed in many places!!!
// BUGBUG: See if file name order makes difference?
uint8_t _serialEvent_default __attribute__((weak)) PROGMEM = 0 ;
uint8_t _serialEventUSB1_default __attribute__((weak)) PROGMEM = 0 ;
uint8_t _serialEventUSB2_default __attribute__((weak)) PROGMEM = 0 ;

void EventResponder::triggerEventNotImmediate()
{
bool irq = disableInterrupts();
if (_triggered == false) {
// not already triggered
if (_type == EventTypeYield) {
// normal type, called from yield()
if (firstYield == nullptr) {
_next = nullptr;
_prev = nullptr;
firstYield = this;
lastYield = this;
} else {
_next = nullptr;
_prev = lastYield;
_prev->_next = this;
lastYield = this;
}
} else if (_type == EventTypeInterrupt) {
// interrupt, called from software interrupt
if (firstInterrupt == nullptr) {
_next = nullptr;
_prev = nullptr;
firstInterrupt = this;
lastInterrupt = this;
} else {
_next = nullptr;
_prev = lastInterrupt;
_prev->_next = this;
lastInterrupt = this;
}
SCB_ICSR = SCB_ICSR_PENDSVSET; // set PendSV interrupt
} else {
// detached, easy :-)
}
_triggered = true;
}
enableInterrupts(irq);
}

void pendablesrvreq_isr(void)
{
EventResponder::runFromInterrupt();
}

void EventResponder::runFromInterrupt()
{
while (1) {
bool irq = disableInterrupts();
EventResponder *first = firstInterrupt;
if (first) {
firstInterrupt = first->_next;
if (firstInterrupt) {
firstInterrupt->_prev = nullptr;
} else {
lastInterrupt = nullptr;
}
enableInterrupts(irq);
first->_triggered = false;
(*(first->_function))(*first);
} else {
enableInterrupts(irq);
break;
}
}
}

bool EventResponder::clearEvent()
{
bool ret = false;
bool irq = disableInterrupts();
if (_triggered) {
if (_type == EventTypeYield) {
if (_prev) {
_prev->_next = _next;
} else {
firstYield = _next;
}
if (_next) {
_next->_prev = _prev;
} else {
lastYield = _prev;
}
} else if (_type == EventTypeInterrupt) {
if (_prev) {
_prev->_next = _next;
} else {
firstInterrupt = _next;
}
if (_next) {
_next->_prev = _prev;
} else {
lastInterrupt = _prev;
}
}
_triggered = false;
ret = true;
}
enableInterrupts(irq);
return ret;
}

// this detach must be called with interrupts disabled
void EventResponder::detachNoInterrupts()
{
if (_type == EventTypeYield) {
if (_triggered) {
if (_prev) {
_prev->_next = _next;
} else {
firstYield = _next;
}
if (_next) {
_next->_prev = _prev;
} else {
lastYield = _prev;
}
}
_type = EventTypeDetached;
} else if (_type == EventTypeInterrupt) {
if (_triggered) {
if (_prev) {
_prev->_next = _next;
} else {
firstInterrupt = _next;
}
if (_next) {
_next->_prev = _prev;
} else {
lastInterrupt = _prev;
}
}
_type = EventTypeDetached;
}
}


//-------------------------------------------------------------


MillisTimer * MillisTimer::listWaiting = nullptr;
MillisTimer * MillisTimer::listActive = nullptr;

void MillisTimer::begin(unsigned long milliseconds, EventResponderRef event)
{
if (_state != TimerOff) end();
if (!milliseconds) return;
_event = &event;
_ms = (milliseconds > 2)? milliseconds-2 : 0;
_reload = 0;
addToWaitingList();
}

void MillisTimer::beginRepeating(unsigned long milliseconds, EventResponderRef event)
{
if (_state != TimerOff) end();
if (!milliseconds) return;
_event = &event;
_ms = (milliseconds > 2)? milliseconds-2 : 0;
_reload = milliseconds;
addToWaitingList();
}

void MillisTimer::addToWaitingList()
{
_prev = nullptr;
bool irq = disableTimerInterrupt();
_next = listWaiting;
listWaiting = this; // TODO: use STREX to avoid interrupt disable
_state = TimerWaiting;
enableTimerInterrupt(irq);
}

void MillisTimer::addToActiveList() // only called by runFromTimer()
{
if (listActive == nullptr) {
// list is empty, easy case
_next = nullptr;
_prev = nullptr;
listActive = this;
} else if (_ms < listActive->_ms) {
// this timer triggers before any on the list
_next = listActive;
_prev = nullptr;
listActive->_prev = this;
// Decrement the next items wait time be our wait time as to properly handle waits for all other items...
listActive->_ms -= _ms;
listActive = this;
} else {
// add this timer somewhere after the first already on the list
MillisTimer *timer = listActive;
while (timer->_next) {
_ms -= timer->_ms;
timer = timer->_next;
if (_ms < timer->_ms) {
// found the right place in the middle of list
_next = timer;
_prev = timer->_prev;
timer->_prev = this;
_prev->_next = this;
timer->_ms -= _ms;
_state = TimerActive;
return;
}
}
// add this time at the end of the list
_ms -= timer->_ms;
_next = nullptr;
_prev = timer;
timer->_next = this;
}
_state = TimerActive;
}

void MillisTimer::end()
{
bool irq = disableTimerInterrupt();
TimerStateType s = _state;
if (s == TimerActive) {
if (_next) {
_next->_prev = _prev;
_next->_ms += _ms; // add in the rest of our timing to next entry...
}
if (_prev) {
_prev->_next = _next;
} else {
listActive = _next;
}
_state = TimerOff;
} else if (s == TimerWaiting) {
if (listWaiting == this) {
listWaiting = _next;
} else {
MillisTimer *timer = listWaiting;
while (timer) {
if (timer->_next == this) {
timer->_next = _next;
break;
}
timer = timer->_next;
}
}
_state = TimerOff;
}
enableTimerInterrupt(irq);
}

void MillisTimer::runFromTimer()
{
MillisTimer *timer = listActive;
while (timer) {
if (timer->_ms > 0) {
timer->_ms--;
break;
} else {
MillisTimer *next = timer->_next;
if (next) next->_prev = nullptr;
listActive = next;
timer->_state = TimerOff;
EventResponderRef event = *(timer->_event);
event.triggerEvent(0, timer);
if (timer->_reload) {
timer->_ms = timer->_reload;
timer->addToActiveList();
}
timer = listActive;
}
}
bool irq = disableTimerInterrupt();
MillisTimer *waiting = listWaiting;
listWaiting = nullptr; // TODO: use STREX to avoid interrupt disable
enableTimerInterrupt(irq);
while (waiting) {
MillisTimer *next = waiting->_next;
waiting->addToActiveList();
waiting = next;
}
}

// Long ago you could install your own systick interrupt handler by just
// creating your own systick_isr() function. No longer. But if you
// *really* want to commandeer systick, you can still do so by writing
// your function into the RAM-based vector table.
//
// _VectorsRam[15] = my_systick_function;
//
// However, for long-term portability, use a MillisTimer object to
// generate an event every millisecond, and attach your function to
// its EventResponder. You can attach as a software interrupt, so your
// code will run at lower interrupt priority for better compatibility
// with libraries using mid-to-high priority interrupts.

extern "C" volatile uint32_t systick_millis_count;

void systick_isr(void)
{
systick_millis_count++;
}

extern "C" void systick_isr_with_timer_events(void)
{
systick_millis_count++;
MillisTimer::runFromTimer();
}




+ 279
- 0
cores/teensy3/EventResponder.h View File

@@ -0,0 +1,279 @@
/* EventResponder - Simple event-based programming for Arduino
* Copyright 2017 Paul Stoffregen
*
* 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.
*/

/* EventResponder is an experimental API, almost certain to
* incompatibly change as it develops. Please understand any
* programs you write now using EventResponder may need to be
* updated as EventResponder develops.
*
* Please post your EventResponder feedback here:
* https://forum.pjrc.com/threads/44723-Arduino-Events
*/

#if !defined(EventResponder_h) && defined(__cplusplus)
#define EventResponder_h

#include <Arduino.h>

/* EventResponder lets you control how your program responds to an event.
* Imagine a basketball or football (American soccer) player who gets the
* ball. Usually they will pass to another player who has the best
* opportunity to score. Similarly in Arduino programming, events are
* often triggered within interrupts or other timing sensitive code.
* EventResponder can call your function a short time later, giving you
* the ability to use Arduino functions and libraries which would not
* be safe to use from an interrupt. However, some situations do call
* for the most immediate response, even if doing so is more difficult.
* EventResponder lets you choose how your function will be called,
* without editing the timers or libraries which trigger the events.
*
* Event handling functions called by EventResponder should complete
* their work quickly. Avoid delays or operations which may take
* substantial time. While your function runs, no other event functions
* (attached the same way) are able to run.
*
* If your EventResponder is triggered more than once before your
* function can run, only the last trigger is used. Prior triggering,
* including the status integer and data pointer, are overwritten and
* your function is called only one time, based on the last trigger
* event.
*/
extern "C" void systick_isr_with_timer_events(void);

class EventResponder;
typedef EventResponder& EventResponderRef;
typedef void (*EventResponderFunction)(EventResponderRef);
class EventResponder
{
public:
constexpr EventResponder() {
}
~EventResponder() {
detach();
}
enum EventType { // these are not meant for public consumption...
EventTypeDetached = 0, // no function is called
EventTypeYield, // function is called from yield()
EventTypeImmediate, // function is called immediately
EventTypeInterrupt, // function is called from interrupt
EventTypeThread // function is run as a new thread
};

// Attach a function to be called from yield(). This should be the
// default way to use EventResponder. Calls from yield() allow use
// of Arduino libraries, String, Serial, etc.
void attach(EventResponderFunction function, uint8_t priority=128) {
bool irq = disableInterrupts();
detachNoInterrupts();
_function = function;
_type = EventTypeYield;
yield_active_check_flags |= YIELD_CHECK_EVENT_RESPONDER; // user setup a yield type...
enableInterrupts(irq);
}

// Attach a function to be called immediately. This provides the
// fastest possible response, but your function must be carefully
// designed.
void attachImmediate(EventResponderFunction function) {
bool irq = disableInterrupts();
detachNoInterrupts();
_function = function;
_type = EventTypeImmediate;
enableInterrupts(irq);
}

// Attach a function to be called from a low priority interrupt.
// Boards not supporting software triggered interrupts will implement
// this as attachImmediate. On ARM and other platforms with software
// interrupts, this allow fast interrupt-based response, but with less
// disruption to other libraries requiring their own interrupts.
void attachInterrupt(EventResponderFunction function, uint8_t priority=128) {
bool irq = disableInterrupts();
detachNoInterrupts();
_function = function;
_type = EventTypeInterrupt;
SCB_SHPR3 |= 0x00FF0000; // configure PendSV, lowest priority
// Make sure we are using the systic ISR that process this
_VectorsRam[15] = systick_isr_with_timer_events;
enableInterrupts(irq);
}

// Attach a function to be called as its own thread. Boards not running
// a RTOS or pre-emptive scheduler shall implement this as attach().
void attachThread(EventResponderFunction function, void *param=nullptr) {
attach(function); // for non-RTOS usage, compile as default attach
}

// Do not call any function. The user's program must occasionally check
// whether the event has occurred, or use one of the wait functions.
void detach() {
bool irq = disableInterrupts();
detachNoInterrupts();
enableInterrupts(irq);
}

// Trigger the event. An optional status code and data may be provided.
// The code triggering the event does NOT control which of the above
// response methods will be used.
virtual void triggerEvent(int status=0, void *data=nullptr) {
_status = status;
_data = data;
if (_type == EventTypeImmediate) {
(*_function)(*this);
} else {
triggerEventNotImmediate();
}
}
// Clear an event which has been triggered, but has not yet caused a
// function to be called.
bool clearEvent();

// Get the event's status code. Typically this will indicate if the event was
// triggered due to successful completion, or how much data was successfully
// processed (positive numbers) or an error (negative numbers). The
// exact meaning of this status code depends on the code or library which
// triggers the event.
int getStatus() { return _status; }

// Get the optional data pointer associated with the event. Often this
// will be NULL, or will be the object instance which triggered the event.
// Some libraries may use this to pass data associated with the event.
void * getData() { return _data; }

// An optional "context" may be associated with each EventResponder.
// When more than one EventResponder has the same function attached, these
// may be used to allow the function to obtain extra information needed
// depending on which EventResponder called it.
void setContext(void *context) { _context = context; }
void * getContext() { return _context; }

// Wait for event(s) to occur. These are most likely to be useful when
// used with a scheduler or RTOS.
bool waitForEvent(EventResponderRef event, int timeout);
EventResponder * waitForEvent(EventResponder *list, int listsize, int timeout);

static void runFromYield() {
if (!firstYield) return;
// First, check if yield was called from an interrupt
// never call normal handler functions from any interrupt context
uint32_t ipsr;
__asm__ volatile("mrs %0, ipsr\n" : "=r" (ipsr)::);
if (ipsr != 0) return;
// Next, check if any events have been triggered
bool irq = disableInterrupts();
EventResponder *first = firstYield;
if (first == nullptr) {
enableInterrupts(irq);
return;
}
// Finally, make sure we're not being recursively called,
// which can happen if the user's function does anything
// that calls yield.
if (runningFromYield) {
enableInterrupts(irq);
return;
}
// Ok, update the runningFromYield flag and process event
runningFromYield = true;
firstYield = first->_next;
if (firstYield) {
firstYield->_prev = nullptr;
} else {
lastYield = nullptr;
}
enableInterrupts(irq);
first->_triggered = false;
(*(first->_function))(*first);
runningFromYield = false;
}
static void runFromInterrupt();
operator bool() { return _triggered; }
protected:
void triggerEventNotImmediate();
void detachNoInterrupts();
int _status = 0;
EventResponderFunction _function = nullptr;
void *_data = nullptr;
void *_context = nullptr;
EventResponder *_next = nullptr;
EventResponder *_prev = nullptr;
EventType _type = EventTypeDetached;
bool _triggered = false;
static EventResponder *firstYield;
static EventResponder *lastYield;
static EventResponder *firstInterrupt;
static EventResponder *lastInterrupt;
static bool runningFromYield;
private:
static bool disableInterrupts() {
uint32_t primask;
__asm__ volatile("mrs %0, primask\n" : "=r" (primask)::);
__disable_irq();
return (primask == 0) ? true : false;
}
static void enableInterrupts(bool doit) {
if (doit) __enable_irq();
}
};

class MillisTimer
{
public:
constexpr MillisTimer() {
}
~MillisTimer() {
end();
}
void begin(unsigned long milliseconds, EventResponderRef event);
void beginRepeating(unsigned long milliseconds, EventResponderRef event);
void end();
static void runFromTimer();
private:
void addToWaitingList();
void addToActiveList();
unsigned long _ms = 0;
unsigned long _reload = 0;
MillisTimer *_next = nullptr;
MillisTimer *_prev = nullptr;
EventResponder *_event = nullptr;
enum TimerStateType {
TimerOff = 0,
TimerWaiting,
TimerActive
};
volatile TimerStateType _state = TimerOff;
static MillisTimer *listWaiting; // single linked list of waiting to start timers
static MillisTimer *listActive; // double linked list of running timers
static bool disableTimerInterrupt() {
uint32_t primask;
__asm__ volatile("mrs %0, primask\n" : "=r" (primask)::);
__disable_irq();
return (primask == 0) ? true : false;
}
static void enableTimerInterrupt(bool doit) {
if (doit) __enable_irq();
}
};

#endif

+ 72
- 0
cores/teensy3/FS.h View File

@@ -0,0 +1,72 @@
/* Experimental File & Dir base classes. VERY experimental!

These are intended to someday allow libraries using files,
such as a JPEG decoder, to accept a File object from SD,
Bridge, USB Host, ESP SPIFFS, and others. Perhaps only a
distant dream at this point, but maybe someday....
*/


#ifndef FS_H
#define FS_H
#ifdef __cplusplus

#include "Stream.h"
#include "WString.h"

class File : public Stream {
public:
constexpr File() {}
enum SeekMode {
SeekSet = 0,
SeekCur = 1,
SeekEnd = 2
};
virtual size_t read(void *buf, size_t nbyte);
virtual size_t write(const void *buf, size_t size);
virtual int available();
virtual int read();
virtual int peek();
virtual void flush();
virtual bool seek(uint32_t pos, int mode);
virtual uint32_t position() const;
virtual uint32_t size() const;
virtual void close();
virtual operator bool() const;
//virtual const char* name() const; // why does ESP have this in File?

bool seek(uint32_t pos) {
return seek(pos, SeekSet);
}
size_t write(uint8_t b) {
return write(&b, 1);
}
size_t write(const char *str) {
return write(str, strlen(str));
}
size_t readBytes(char *buffer, size_t length) {
return read(buffer, length);
}

// needed for compatiblity with Arduino's SD & Bridge libs
virtual const char* name();
virtual bool isDirectory();
virtual File openNextFile(uint8_t mode=0);
virtual void rewindDirectory(void);
};

class Dir {
public:
constexpr Dir() {}
virtual const char *name(); // from SD's File (and ESP's File)
virtual uint32_t fileSize();
virtual bool isDirectory(); // from SD, not in ESP
virtual File openFile(const char *mode);
virtual bool next();
String fileName() {
return String(name());
}
};

#endif // __cplusplus
#endif // FS_H

+ 45
- 0
cores/teensy3/HardwareSerial.cpp View File

@@ -0,0 +1,45 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2019 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 "HardwareSerial.h"
#include "core_pins.h"
#include "Arduino.h"

// define our static objects
HardwareSerial *HardwareSerial::s_serials_with_serial_events[CNT_HARDWARE_SERIAL];
uint8_t HardwareSerial::s_count_serials_with_serial_events = 0;

// simple helper function that add us to the list of Serial ports that have
// their own serialEvent code defined that needs to be called at yield.
void HardwareSerial::addToSerialEventsList() {
s_serials_with_serial_events[s_count_serials_with_serial_events++] = this;
yield_active_check_flags |= YIELD_CHECK_HARDWARE_SERIAL;
}


+ 506
- 0
cores/teensy3/HardwareSerial.h View File

@@ -0,0 +1,506 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2017 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 "kinetis.h"

// Uncomment to enable 9 bit formats. These are default disabled to save memory.
//#define SERIAL_9BIT_SUPPORT
//
// On Windows & Linux, this file is in Arduino's hardware/teensy/avr/cores/teensy3
// folder. The Windows installer puts Arduino in C:\Program Files (x86)\Arduino
// On Macintosh, you must control-click Arduino and select "Show Package Contents", then
// look in Contents/Java/hardware/teensy/avr/cores/teensy3 to find this file.
//
// Teensy 3.x boards support 9 bit mode on all their serial ports
// Teensy LC only supports 9 bit mode on Serial1. Serial2 & Serial3 can't use 9 bits.


#define SERIAL_7E1 0x02
#define SERIAL_7O1 0x03
#define SERIAL_8N1 0x00
#define SERIAL_8E1 0x06
#define SERIAL_8O1 0x07
#define SERIAL_7E1_RXINV 0x12
#define SERIAL_7O1_RXINV 0x13
#define SERIAL_8N1_RXINV 0x10
#define SERIAL_8E1_RXINV 0x16
#define SERIAL_8O1_RXINV 0x17
#define SERIAL_7E1_TXINV 0x22
#define SERIAL_7O1_TXINV 0x23
#define SERIAL_8N1_TXINV 0x20
#define SERIAL_8E1_TXINV 0x26
#define SERIAL_8O1_TXINV 0x27
#define SERIAL_7E1_RXINV_TXINV 0x32
#define SERIAL_7O1_RXINV_TXINV 0x33
#define SERIAL_8N1_RXINV_TXINV 0x30
#define SERIAL_8E1_RXINV_TXINV 0x36
#define SERIAL_8O1_RXINV_TXINV 0x37
#ifdef SERIAL_9BIT_SUPPORT
#define SERIAL_9N1 0x84
#define SERIAL_9E1 0x8E
#define SERIAL_9O1 0x8F
#define SERIAL_9N1_RXINV 0x94
#define SERIAL_9E1_RXINV 0x9E
#define SERIAL_9O1_RXINV 0x9F
#define SERIAL_9N1_TXINV 0xA4
#define SERIAL_9E1_TXINV 0xAE
#define SERIAL_9O1_TXINV 0xAF
#define SERIAL_9N1_RXINV_TXINV 0xB4
#define SERIAL_9E1_RXINV_TXINV 0xBE
#define SERIAL_9O1_RXINV_TXINV 0xBF
#endif
// Teensy LC and 3.5 and 3.6 Uarts have 1/2 bit stop setting
#if defined(__MK64FX512__) || defined(__MK66FX1M0__) || defined(KINETISL)
#define SERIAL_2STOP_BITS 0x100
#define SERIAL_8E2 (SERIAL_8E1 | SERIAL_2STOP_BITS)
#define SERIAL_8O2 (SERIAL_8O1 | SERIAL_2STOP_BITS)
#define SERIAL_8E2_RXINV (SERIAL_8E1_RXINV | SERIAL_2STOP_BITS)
#define SERIAL_8O2_RXINV (SERIAL_8O1_RXINV | SERIAL_2STOP_BITS)
#define SERIAL_8E2_TXINV (SERIAL_8E1_TXINV | SERIAL_2STOP_BITS)
#define SERIAL_8O2_TXINV (SERIAL_8O1_TXINV | SERIAL_2STOP_BITS)
#define SERIAL_8E2_RXINV_TXINV (SERIAL_8E1_RXINV_TXINV | SERIAL_2STOP_BITS)
#define SERIAL_8O2_RXINV_TXINV (SERIAL_8O1_RXINV_TXINV | SERIAL_2STOP_BITS)
#define SERIAL_8N2 (SERIAL_8N1 | SERIAL_2STOP_BITS)
#define SERIAL_8N2_RXINV (SERIAL_8N1_RXINV | SERIAL_2STOP_BITS)
#define SERIAL_8N2_TXINV (SERIAL_8N1_TXINV | SERIAL_2STOP_BITS)
#define SERIAL_8N2_RXINV_TXINV (SERIAL_8N1_RXINV_TXINV | SERIAL_2STOP_BITS)
#else
// for Teensy 3.0-3.2 we can fake 2 stop bits by using 9 bit mode
#define SERIAL_8N2 0x04
#define SERIAL_8N2_RXINV 0x14
#define SERIAL_8N2_TXINV 0x24
#define SERIAL_8N2_RXINV_TXINV 0x34
#endif
// bit0: parity, 0=even, 1=odd
// bit1: parity, 0=disable, 1=enable
// bit2: mode, 1=9bit, 0=8bit
// bit3: mode10: 1=10bit, 0=8bit
// bit4: rxinv, 0=normal, 1=inverted
// bit5: txinv, 0=normal, 1=inverted
// bit6: unused
// bit7: actual data goes into 9th bit


#if defined(KINETISK)
#define BAUD2DIV(baud) (((F_CPU * 2) + ((baud) >> 1)) / (baud))
#define BAUD2DIV2(baud) (((F_CPU * 2) + ((baud) >> 1)) / (baud))
#define BAUD2DIV3(baud) (((F_BUS * 2) + ((baud) >> 1)) / (baud))
#elif defined(KINETISL)

#if F_CPU <= 2000000
#define BAUD2DIV(baud) (((F_PLL / 16 ) + ((baud) >> 1)) / (baud))
#elif F_CPU <= 16000000
#define BAUD2DIV(baud) (((F_PLL / (F_PLL / 1000000)) + ((baud) >> 1)) / (baud))
#else
#define BAUD2DIV(baud) (((F_PLL / 2 / 16) + ((baud) >> 1)) / (baud))
#endif

#define BAUD2DIV2(baud) (((F_BUS / 16) + ((baud) >> 1)) / (baud))
#define BAUD2DIV3(baud) (((F_BUS / 16) + ((baud) >> 1)) / (baud))
#endif


// C language implementation
//
#ifdef __cplusplus
extern "C" {
#endif
void serial_begin(uint32_t divisor);
void serial_format(uint32_t format);
void serial_end(void);
void serial_set_transmit_pin(uint8_t pin);
void serial_set_rx(uint8_t pin);
void serial_set_tx(uint8_t pin, uint8_t opendrain);
int serial_set_rts(uint8_t pin);
int serial_set_cts(uint8_t pin);
void serial_putchar(uint32_t c);
void serial_write(const void *buf, unsigned int count);
void serial_flush(void);
int serial_write_buffer_free(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_format(uint32_t format);
void serial2_end(void);
void serial2_set_transmit_pin(uint8_t pin);
void serial2_set_rx(uint8_t pin);
void serial2_set_tx(uint8_t pin, uint8_t opendrain);
int serial2_set_rts(uint8_t pin);
int serial2_set_cts(uint8_t pin);
void serial2_putchar(uint32_t c);
void serial2_write(const void *buf, unsigned int count);
void serial2_flush(void);
int serial2_write_buffer_free(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_format(uint32_t format);
void serial3_end(void);
void serial3_set_transmit_pin(uint8_t pin);
void serial3_set_rx(uint8_t pin);
void serial3_set_tx(uint8_t pin, uint8_t opendrain);
int serial3_set_rts(uint8_t pin);
int serial3_set_cts(uint8_t pin);
void serial3_putchar(uint32_t c);
void serial3_write(const void *buf, unsigned int count);
void serial3_flush(void);
int serial3_write_buffer_free(void);
int serial3_available(void);
int serial3_getchar(void);
int serial3_peek(void);
void serial3_clear(void);

void serial4_begin(uint32_t divisor);
void serial4_format(uint32_t format);
void serial4_end(void);
void serial4_set_transmit_pin(uint8_t pin);
void serial4_set_rx(uint8_t pin);
void serial4_set_tx(uint8_t pin, uint8_t opendrain);
int serial4_set_rts(uint8_t pin);
int serial4_set_cts(uint8_t pin);
void serial4_putchar(uint32_t c);
void serial4_write(const void *buf, unsigned int count);
void serial4_flush(void);
int serial4_write_buffer_free(void);
int serial4_available(void);
int serial4_getchar(void);
int serial4_peek(void);
void serial4_clear(void);

void serial5_begin(uint32_t divisor);
void serial5_format(uint32_t format);
void serial5_end(void);
void serial5_set_transmit_pin(uint8_t pin);
void serial5_set_rx(uint8_t pin);
void serial5_set_tx(uint8_t pin, uint8_t opendrain);
int serial5_set_rts(uint8_t pin);
int serial5_set_cts(uint8_t pin);
void serial5_putchar(uint32_t c);
void serial5_write(const void *buf, unsigned int count);
void serial5_flush(void);
int serial5_write_buffer_free(void);
int serial5_available(void);
int serial5_getchar(void);
int serial5_peek(void);
void serial5_clear(void);

void serial6_begin(uint32_t divisor);
void serial6_format(uint32_t format);
void serial6_end(void);
void serial6_set_transmit_pin(uint8_t pin);
void serial6_set_rx(uint8_t pin);
void serial6_set_tx(uint8_t pin, uint8_t opendrain);
int serial6_set_rts(uint8_t pin);
int serial6_set_cts(uint8_t pin);
void serial6_putchar(uint32_t c);
void serial6_write(const void *buf, unsigned int count);
void serial6_flush(void);
int serial6_write_buffer_free(void);
int serial6_available(void);
int serial6_getchar(void);
int serial6_peek(void);
void serial6_clear(void);

#ifdef __cplusplus
}
#endif


// C++ interface
//
#ifdef __cplusplus
#include "Stream.h"
class HardwareSerial : public Stream
{
public:
constexpr HardwareSerial(void (* const se)()) : _serialEvent(se) {}
#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
enum {CNT_HARDWARE_SERIAL = 6};
#else //(__MK64FX512__) || defined(__MK66FX1M0__)
enum {CNT_HARDWARE_SERIAL = 3};
#endif
virtual void begin(uint32_t baud);
virtual void begin(uint32_t baud, uint32_t format) {
serial_begin(BAUD2DIV(baud));
serial_format(format); }
virtual void end(void) { serial_end(); }
virtual void transmitterEnable(uint8_t pin) { serial_set_transmit_pin(pin); }
virtual void setRX(uint8_t pin) { serial_set_rx(pin); }
virtual void setTX(uint8_t pin, bool opendrain=false) { serial_set_tx(pin, opendrain); }
virtual bool attachRts(uint8_t pin) { return serial_set_rts(pin); }
virtual bool attachCts(uint8_t pin) { return serial_set_cts(pin); }
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(); }
virtual void clear(void) { serial_clear(); }
virtual int availableForWrite(void) { return serial_write_buffer_free(); }
using Print::write;
virtual size_t write(uint8_t c) { serial_putchar(c); return 1; }
virtual size_t write(unsigned long n) { return write((uint8_t)n); }
virtual size_t write(long n) { return write((uint8_t)n); }
virtual size_t write(unsigned int n) { return write((uint8_t)n); }
virtual 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; }
virtual size_t write(const char *str) { size_t len = strlen(str);
serial_write((const uint8_t *)str, len);
return len; }
virtual size_t write9bit(uint32_t c) { serial_putchar(c); return 1; }
operator bool() { return true; }

static inline void processSerialEventsList() {
for (uint8_t i = 0; i < s_count_serials_with_serial_events; i++) {
s_serials_with_serial_events[i]->doYieldCode();
}
}
protected:
static HardwareSerial *s_serials_with_serial_events[CNT_HARDWARE_SERIAL];
static uint8_t s_count_serials_with_serial_events;
void (* const _serialEvent)();
void addToSerialEventsList();
inline void doYieldCode() {
if (available()) (*_serialEvent)();
}

};
extern HardwareSerial Serial1;
extern void serialEvent1(void);

class HardwareSerial2 : public HardwareSerial
{
public:
constexpr HardwareSerial2(void (* const se)()) : HardwareSerial(se) {}
virtual void begin(uint32_t baud);
virtual void begin(uint32_t baud, uint32_t format) {
serial2_begin(BAUD2DIV2(baud));
serial2_format(format); }
virtual void end(void) { serial2_end(); }
virtual void transmitterEnable(uint8_t pin) { serial2_set_transmit_pin(pin); }
virtual void setRX(uint8_t pin) { serial2_set_rx(pin); }
virtual void setTX(uint8_t pin, bool opendrain=false) { serial2_set_tx(pin, opendrain); }
virtual bool attachRts(uint8_t pin) { return serial2_set_rts(pin); }
virtual bool attachCts(uint8_t pin) { return serial2_set_cts(pin); }
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(); }
virtual void clear(void) { serial2_clear(); }
virtual int availableForWrite(void) { return serial2_write_buffer_free(); }
using Print::write;
virtual size_t write(uint8_t c) { serial2_putchar(c); return 1; }
virtual size_t write(unsigned long n) { return write((uint8_t)n); }
virtual size_t write(long n) { return write((uint8_t)n); }
virtual size_t write(unsigned int n) { return write((uint8_t)n); }
virtual 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; }
virtual size_t write(const char *str) { size_t len = strlen(str);
serial2_write((const uint8_t *)str, len);
return len; }
virtual size_t write9bit(uint32_t c) { serial2_putchar(c); return 1; }
operator bool() { return true; }
};
extern HardwareSerial2 Serial2;
extern void serialEvent2(void);

class HardwareSerial3 : public HardwareSerial
{
public:
constexpr HardwareSerial3(void (* const se)()) : HardwareSerial(se) {}
virtual void begin(uint32_t baud);
virtual void begin(uint32_t baud, uint32_t format) {
serial3_begin(BAUD2DIV3(baud));
serial3_format(format); }
virtual void end(void) { serial3_end(); }
virtual void transmitterEnable(uint8_t pin) { serial3_set_transmit_pin(pin); }
virtual void setRX(uint8_t pin) { serial3_set_rx(pin); }
virtual void setTX(uint8_t pin, bool opendrain=false) { serial3_set_tx(pin, opendrain); }
virtual bool attachRts(uint8_t pin) { return serial3_set_rts(pin); }
virtual bool attachCts(uint8_t pin) { return serial3_set_cts(pin); }
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(); }
virtual void clear(void) { serial3_clear(); }
virtual int availableForWrite(void) { return serial3_write_buffer_free(); }
using Print::write;
virtual size_t write(uint8_t c) { serial3_putchar(c); return 1; }
virtual size_t write(unsigned long n) { return write((uint8_t)n); }
virtual size_t write(long n) { return write((uint8_t)n); }
virtual size_t write(unsigned int n) { return write((uint8_t)n); }
virtual 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; }
virtual size_t write(const char *str) { size_t len = strlen(str);
serial3_write((const uint8_t *)str, len);
return len; }
virtual size_t write9bit(uint32_t c) { serial3_putchar(c); return 1; }
operator bool() { return true; }
};
extern HardwareSerial3 Serial3;
extern void serialEvent3(void);

class HardwareSerial4 : public HardwareSerial
{
public:
constexpr HardwareSerial4(void (* const se)()) : HardwareSerial(se) {}
virtual void begin(uint32_t baud);
virtual void begin(uint32_t baud, uint32_t format) {
serial4_begin(BAUD2DIV3(baud));
serial4_format(format); }
virtual void end(void) { serial4_end(); }
virtual void transmitterEnable(uint8_t pin) { serial4_set_transmit_pin(pin); }
virtual void setRX(uint8_t pin) { serial4_set_rx(pin); }
virtual void setTX(uint8_t pin, bool opendrain=false) { serial4_set_tx(pin, opendrain); }
virtual bool attachRts(uint8_t pin) { return serial4_set_rts(pin); }
virtual bool attachCts(uint8_t pin) { return serial4_set_cts(pin); }
virtual int available(void) { return serial4_available(); }
virtual int peek(void) { return serial4_peek(); }
virtual int read(void) { return serial4_getchar(); }
virtual void flush(void) { serial4_flush(); }
virtual void clear(void) { serial4_clear(); }
virtual int availableForWrite(void) { return serial4_write_buffer_free(); }
using Print::write;
virtual size_t write(uint8_t c) { serial4_putchar(c); return 1; }
virtual size_t write(unsigned long n) { return write((uint8_t)n); }
virtual size_t write(long n) { return write((uint8_t)n); }
virtual size_t write(unsigned int n) { return write((uint8_t)n); }
virtual size_t write(int n) { return write((uint8_t)n); }
virtual size_t write(const uint8_t *buffer, size_t size)
{ serial4_write(buffer, size); return size; }
virtual size_t write(const char *str) { size_t len = strlen(str);
serial4_write((const uint8_t *)str, len);
return len; }
virtual size_t write9bit(uint32_t c) { serial4_putchar(c); return 1; }
operator bool() { return true; }
};
extern HardwareSerial4 Serial4;
extern void serialEvent4(void);

class HardwareSerial5 : public HardwareSerial
{
public:
constexpr HardwareSerial5(void (* const se)()) : HardwareSerial(se) {}
virtual void begin(uint32_t baud);
virtual void begin(uint32_t baud, uint32_t format) {
serial5_begin(BAUD2DIV3(baud));
serial5_format(format); }
virtual void end(void) { serial5_end(); }
virtual void transmitterEnable(uint8_t pin) { serial5_set_transmit_pin(pin); }
virtual void setRX(uint8_t pin) { serial5_set_rx(pin); }
virtual void setTX(uint8_t pin, bool opendrain=false) { serial5_set_tx(pin, opendrain); }
virtual bool attachRts(uint8_t pin) { return serial5_set_rts(pin); }
virtual bool attachCts(uint8_t pin) { return serial5_set_cts(pin); }
virtual int available(void) { return serial5_available(); }
virtual int peek(void) { return serial5_peek(); }
virtual int read(void) { return serial5_getchar(); }
virtual void flush(void) { serial5_flush(); }
virtual void clear(void) { serial5_clear(); }
virtual int availableForWrite(void) { return serial5_write_buffer_free(); }
using Print::write;
virtual size_t write(uint8_t c) { serial5_putchar(c); return 1; }
virtual size_t write(unsigned long n) { return write((uint8_t)n); }
virtual size_t write(long n) { return write((uint8_t)n); }
virtual size_t write(unsigned int n) { return write((uint8_t)n); }
virtual size_t write(int n) { return write((uint8_t)n); }
virtual size_t write(const uint8_t *buffer, size_t size)
{ serial5_write(buffer, size); return size; }
virtual size_t write(const char *str) { size_t len = strlen(str);
serial5_write((const uint8_t *)str, len);
return len; }
virtual size_t write9bit(uint32_t c) { serial5_putchar(c); return 1; }
operator bool() { return true; }
};
extern HardwareSerial5 Serial5;
extern void serialEvent5(void);

class HardwareSerial6 : public HardwareSerial
{
public:
constexpr HardwareSerial6(void (* const se)()) : HardwareSerial(se) {}
#if defined(__MK66FX1M0__) // For LPUART just pass baud straight in.
virtual void begin(uint32_t baud);
virtual void begin(uint32_t baud, uint32_t format) {
serial6_begin(baud);
serial6_format(format); }
#else
virtual void begin(uint32_t baud);
virtual void begin(uint32_t baud, uint32_t format) {
serial6_begin(BAUD2DIV3(baud));
serial6_format(format); }
#endif
virtual void end(void) { serial6_end(); }
virtual void transmitterEnable(uint8_t pin) { serial6_set_transmit_pin(pin); }
virtual void setRX(uint8_t pin) { serial6_set_rx(pin); }
virtual void setTX(uint8_t pin, bool opendrain=false) { serial6_set_tx(pin, opendrain); }
virtual bool attachRts(uint8_t pin) { return serial6_set_rts(pin); }
virtual bool attachCts(uint8_t pin) { return serial6_set_cts(pin); }
virtual int available(void) { return serial6_available(); }
virtual int peek(void) { return serial6_peek(); }
virtual int read(void) { return serial6_getchar(); }
virtual void flush(void) { serial6_flush(); }
virtual void clear(void) { serial6_clear(); }
virtual int availableForWrite(void) { return serial6_write_buffer_free(); }
using Print::write;
virtual size_t write(uint8_t c) { serial6_putchar(c); return 1; }
virtual size_t write(unsigned long n) { return write((uint8_t)n); }
virtual size_t write(long n) { return write((uint8_t)n); }
virtual size_t write(unsigned int n) { return write((uint8_t)n); }
virtual size_t write(int n) { return write((uint8_t)n); }
virtual size_t write(const uint8_t *buffer, size_t size)
{ serial6_write(buffer, size); return size; }
virtual size_t write(const char *str) { size_t len = strlen(str);
serial6_write((const uint8_t *)str, len);
return len; }
virtual size_t write9bit(uint32_t c) { serial6_putchar(c); return 1; }
operator bool() { return true; }
};
extern HardwareSerial6 Serial6;
extern void serialEvent6(void);




#endif
#endif

+ 43
- 0
cores/teensy3/HardwareSerial1.cpp View File

@@ -0,0 +1,43 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2017 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 <Arduino.h>
#include "HardwareSerial.h"


uint8_t _serialEvent1_default __attribute__((weak)) PROGMEM = 0 ;

HardwareSerial Serial1(&serialEvent1);

void HardwareSerial::begin(uint32_t baud) {
serial_begin(BAUD2DIV(baud));
if (!_serialEvent1_default) addToSerialEventsList();
}


+ 40
- 0
cores/teensy3/HardwareSerial2.cpp View File

@@ -0,0 +1,40 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2017 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 <Arduino.h>
#include "HardwareSerial.h"

HardwareSerial2 Serial2(&serialEvent2);

uint8_t _serialEvent2_default __attribute__((weak)) PROGMEM = 0 ;

void HardwareSerial2::begin(uint32_t baud) {
serial2_begin(BAUD2DIV2(baud));
if (!_serialEvent2_default) addToSerialEventsList();
}

+ 41
- 0
cores/teensy3/HardwareSerial3.cpp View File

@@ -0,0 +1,41 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2017 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 <Arduino.h>
#include "HardwareSerial.h"

HardwareSerial3 Serial3(&serialEvent3);

uint8_t _serialEvent3_default __attribute__((weak)) PROGMEM = 0 ;

void HardwareSerial3::begin(uint32_t baud) {
serial3_begin(BAUD2DIV3(baud));
if (!_serialEvent3_default) addToSerialEventsList();
}

+ 45
- 0
cores/teensy3/HardwareSerial4.cpp View File

@@ -0,0 +1,45 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2017 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 <Arduino.h>
#include "HardwareSerial.h"

#ifdef HAS_KINETISK_UART3

HardwareSerial4 Serial4(&serialEvent4);

uint8_t _serialEvent4_default __attribute__((weak)) PROGMEM = 0 ;

void HardwareSerial4::begin(uint32_t baud) {
serial4_begin(BAUD2DIV3(baud));
if (!_serialEvent4_default) addToSerialEventsList();
}

#endif

+ 45
- 0
cores/teensy3/HardwareSerial5.cpp View File

@@ -0,0 +1,45 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2017 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 <Arduino.h>
#include "HardwareSerial.h"

#ifdef HAS_KINETISK_UART4

HardwareSerial5 Serial5(&serialEvent5);

uint8_t _serialEvent5_default __attribute__((weak)) PROGMEM = 0 ;

void HardwareSerial5::begin(uint32_t baud) {
serial5_begin(BAUD2DIV3(baud));
if (!_serialEvent5_default) addToSerialEventsList();
}

#endif

+ 49
- 0
cores/teensy3/HardwareSerial6.cpp View File

@@ -0,0 +1,49 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2017 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 <Arduino.h>
#include "HardwareSerial.h"

#if defined(HAS_KINETISK_UART5) || defined (HAS_KINETISK_LPUART0)

HardwareSerial6 Serial6(&serialEvent6);

uint8_t _serialEvent6_default __attribute__((weak)) PROGMEM = 0 ;

void HardwareSerial6::begin(uint32_t baud) {
#if defined(__MK66FX1M0__) // For LPUART just pass baud straight in.
serial6_begin(baud);
#else
serial6_begin(BAUD2DIV3(baud));
#endif
if (!_serialEvent6_default) addToSerialEventsList();
}

#endif

+ 65
- 0
cores/teensy3/IPAddress.cpp View File

@@ -0,0 +1,65 @@
/*
IPAddress.cpp - Base class that provides IPAddress
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
*/

#include <Arduino.h>
#include "IPAddress.h"

size_t IPAddress::printTo(Print& p) const
{
int i=0;
while (1) {
p.print(_address.bytes[i], DEC);
if (++i >= 4) return 4;
p.write('.');
}
}

bool IPAddress::fromString(const char *address)
{
unsigned int acc = 0; // Accumulator
unsigned int dots = 0;

while (*address) {
char c = *address++;
if (c >= '0' && c <= '9') {
acc = acc * 10 + (c - '0');
if (acc > 255) {
// Value out of [0..255] range
return false;
}
} else if (c == '.') {
if (dots == 3) {
// Too much dots (there must be 3 dots)
return false;
}
_address.bytes[dots++] = acc;
acc = 0;
} else {
// Invalid char
return false;
}
}
if (dots != 3) {
// Too few dots (there must be 3 dots)
return false;
}
_address.bytes[3] = acc;
return true;
}


+ 125
- 0
cores/teensy3/IPAddress.h View File

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

#ifndef IPAddress_h
#define IPAddress_h

#include <Printable.h>
#include <WString.h>

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

class IPAddress : public Printable {
private:
union {
uint8_t bytes[4]; // IPv4 address
uint32_t dword;
} _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.bytes; };

public:
// Constructors
IPAddress() {
_address.dword = 0;
}
IPAddress(uint8_t b1, uint8_t b2, uint8_t b3, uint8_t b4) {
_address.bytes[0] = b1;
_address.bytes[1] = b2;
_address.bytes[2] = b3;
_address.bytes[3] = b4;
}
IPAddress(uint32_t address) {
_address.dword = address;
}
IPAddress(const uint8_t *address) {
// TODO: use unaligned read on Cortex-M4
_address.bytes[0] = *address++;
_address.bytes[1] = *address++;
_address.bytes[2] = *address++;
_address.bytes[3] = *address++;
}

bool fromString(const char *address);
bool fromString(const String &address) {
return fromString(address.c_str());
}

// 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.dword;
}
bool operator==(const IPAddress& addr) {
return _address.dword == addr._address.dword;
}
bool operator==(const uint8_t* addr) {
// TODO: use unaligned read on Cortex-M4
return (_address.bytes[0] == addr[0]
&& _address.bytes[1] == addr[1]
&& _address.bytes[2] == addr[2]
&& _address.bytes[3] == addr[3]);
}

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

// Overloaded copy operators to allow initialisation of IPAddress objects from other types
IPAddress& operator=(const uint8_t *address) {
// TODO: use unaligned read on Cortex-M4
_address.bytes[0] = *address++;
_address.bytes[1] = *address++;
_address.bytes[2] = *address++;
_address.bytes[3] = *address++;
return *this;
}
IPAddress& operator=(uint32_t address) {
_address.dword = address;
return *this;
}

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((uint32_t)0);


#endif

+ 145
- 0
cores/teensy3/IntervalTimer.cpp View File

@@ -0,0 +1,145 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2017 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 "IntervalTimer.h"

static void dummy_funct(void);

#if defined(KINETISK)
#define NUM_CHANNELS 4
static void (*funct_table[4])(void) = {dummy_funct, dummy_funct, dummy_funct, dummy_funct};

#elif defined(KINETISL)
#define NUM_CHANNELS 2
static void (*funct_table[2])(void) = {dummy_funct, dummy_funct};
uint8_t IntervalTimer::nvic_priorites[2] = {255, 255};
#endif


bool IntervalTimer::beginCycles(void (*funct)(), uint32_t cycles)
{
if (channel) {
channel->TCTRL = 0;
channel->TFLG = 1;
} else {
SIM_SCGC6 |= SIM_SCGC6_PIT;
__asm__ volatile("nop"); // solves timing problem on Teensy 3.5
PIT_MCR = 1;
channel = KINETISK_PIT_CHANNELS;
while (1) {
if (channel->TCTRL == 0) break;
if (++channel >= KINETISK_PIT_CHANNELS + NUM_CHANNELS) {
channel = NULL;
return false;
}
}
}
int index = channel - KINETISK_PIT_CHANNELS;
funct_table[index] = funct;
channel->LDVAL = cycles;
channel->TCTRL = 3;
#if defined(KINETISK)
NVIC_SET_PRIORITY(IRQ_PIT_CH0 + index, nvic_priority);
NVIC_ENABLE_IRQ(IRQ_PIT_CH0 + index);
#elif defined(KINETISL)
nvic_priorites[index] = nvic_priority;
if (nvic_priorites[0] <= nvic_priorites[1]) {
NVIC_SET_PRIORITY(IRQ_PIT, nvic_priorites[0]);
} else {
NVIC_SET_PRIORITY(IRQ_PIT, nvic_priorites[1]);
}
NVIC_ENABLE_IRQ(IRQ_PIT);
#endif
return true;
}


void IntervalTimer::end() {
if (channel) {
int index = channel - KINETISK_PIT_CHANNELS;
#if defined(KINETISK)
NVIC_DISABLE_IRQ(IRQ_PIT_CH0 + index);
#elif defined(KINETISL)
// TODO: disable IRQ_PIT, but only if both instances ended
#endif
funct_table[index] = dummy_funct;
channel->TCTRL = 0;
#if defined(KINETISL)
nvic_priorites[index] = 255;
if (nvic_priorites[0] <= nvic_priorites[1]) {
NVIC_SET_PRIORITY(IRQ_PIT, nvic_priorites[0]);
} else {
NVIC_SET_PRIORITY(IRQ_PIT, nvic_priorites[1]);
}
#endif
channel = 0;
}
}


#if defined(KINETISK)
void pit0_isr()
{
PIT_TFLG0 = 1;
funct_table[0]();
}

void pit1_isr() {
PIT_TFLG1 = 1;
funct_table[1]();
}

void pit2_isr() {
PIT_TFLG2 = 1;
funct_table[2]();
}

void pit3_isr() {
PIT_TFLG3 = 1;
funct_table[3]();
}

#elif defined(KINETISL)
void pit_isr() {
if (PIT_TFLG0) {
PIT_TFLG0 = 1;
funct_table[0]();
}
if (PIT_TFLG1) {
PIT_TFLG1 = 1;
funct_table[1]();
}
}
#endif

static void dummy_funct(void)
{
}


+ 147
- 0
cores/teensy3/IntervalTimer.h View File

@@ -0,0 +1,147 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2017 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 __INTERVALTIMER_H__
#define __INTERVALTIMER_H__

#include "kinetis.h"

#ifdef __cplusplus
extern "C" {
#endif

class IntervalTimer {
private:
static const uint32_t MAX_PERIOD = UINT32_MAX / (F_BUS / 1000000.0);
public:
IntervalTimer() {
channel = NULL;
nvic_priority = 128;
}
~IntervalTimer() {
end();
}
bool begin(void (*funct)(), unsigned int microseconds) {
if (microseconds == 0 || microseconds > MAX_PERIOD) return false;
uint32_t cycles = (F_BUS / 1000000) * microseconds - 1;
if (cycles < 36) return false;
return beginCycles(funct, cycles);
}
bool begin(void (*funct)(), int microseconds) {
if (microseconds < 0) return false;
return begin(funct, (unsigned int)microseconds);
}
bool begin(void (*funct)(), unsigned long microseconds) {
return begin(funct, (unsigned int)microseconds);
}
bool begin(void (*funct)(), long microseconds) {
return begin(funct, (int)microseconds);
}
bool begin(void (*funct)(), float microseconds) {
if (microseconds <= 0 || microseconds > MAX_PERIOD) return false;
uint32_t cycles = (float)(F_BUS / 1000000) * microseconds - 0.5;
if (cycles < 36) return false;
return beginCycles(funct, cycles);
}
bool begin(void (*funct)(), double microseconds) {
return begin(funct, (float)microseconds);
}
void update(unsigned int microseconds) {
if (microseconds == 0 || microseconds > MAX_PERIOD) return;
uint32_t cycles = (F_BUS / 1000000) * microseconds - 1;
if (cycles < 36) return;
if (channel) channel->LDVAL = cycles;
}
void update(int microseconds) {
if (microseconds < 0) return;
return update((unsigned int)microseconds);
}
void update(unsigned long microseconds) {
return update((unsigned int)microseconds);
}
void update(long microseconds) {
return update((int)microseconds);
}
void update(float microseconds) {
if (microseconds <= 0 || microseconds > MAX_PERIOD) return;
uint32_t cycles = (float)(F_BUS / 1000000) * microseconds - 0.5;
if (cycles < 36) return;
if (channel) channel->LDVAL = cycles;
}
void update(double microseconds) {
return update((float)microseconds);
}
void end();
void priority(uint8_t n) {
nvic_priority = n;
#if defined(KINETISK)
if (channel) {
int index = channel - KINETISK_PIT_CHANNELS;
NVIC_SET_PRIORITY(IRQ_PIT_CH0 + index, nvic_priority);
}
#elif defined(KINETISL)
if (channel) {
int index = channel - KINETISK_PIT_CHANNELS;
nvic_priorites[index] = nvic_priority;
if (nvic_priorites[0] <= nvic_priorites[1]) {
NVIC_SET_PRIORITY(IRQ_PIT, nvic_priorites[0]);
} else {
NVIC_SET_PRIORITY(IRQ_PIT, nvic_priorites[1]);
}
}
#endif
}
operator IRQ_NUMBER_t() {
if (channel) {
#if defined(KINETISK)
int index = channel - KINETISK_PIT_CHANNELS;
return (IRQ_NUMBER_t)(IRQ_PIT_CH0 + index);
#elif defined(KINETISL)
return IRQ_PIT;
#endif
}
return (IRQ_NUMBER_t)NVIC_NUM_INTERRUPTS;
}
private:
KINETISK_PIT_CHANNEL_t *channel;
uint8_t nvic_priority;
#if defined(KINETISL)
static uint8_t nvic_priorites[2];
#endif
bool beginCycles(void (*funct)(), uint32_t cycles);

};


#ifdef __cplusplus
}
#endif

#endif

+ 3
- 0
cores/teensy3/Keyboard.h View File

@@ -0,0 +1,3 @@
// empty Keyboard.h file, for compability with Arduino's Keyboard examples

// This header file is in the public domain.

+ 56
- 0
cores/teensy3/MIDIUSB.h View File

@@ -0,0 +1,56 @@
#ifndef MIDIUSB_h
#define MIDIUSB_h

// For compatibility with Arduino's MIDIUSB library

#include "usb_midi.h"

#ifdef __cplusplus
#if !defined(USB_MIDI) && !defined(USB_MIDI4) && !defined(USB_MIDI16) && !defined(USB_MIDI_SERIAL) && !defined(USB_MIDI4_SERIAL) && !defined(USB_MIDI16_SERIAL) && !defined(USB_MIDI_AUDIO_SERIAL) && !defined(USB_MIDI16_AUDIO_SERIAL) && !defined(USB_EVERYTHING)
#error "Please select MIDI in Tools > USB Type to use MIDIUSB.h"
#endif

typedef struct {
union {
struct {
uint8_t header;
uint8_t byte1;
uint8_t byte2;
uint8_t byte3;
};
uint32_t word;
};
} midiEventPacket_t;


class MIDI_
{
public:
constexpr MIDI_(void) { }
uint32_t available(void) {
return usb_midi_available();
}
midiEventPacket_t read(void) {
midiEventPacket_t event;
event.word = usb_midi_read_message();
return event;
}
void flush(void) {
usb_midi_flush_output();
}
void sendMIDI(midiEventPacket_t event) {
usb_midi_write_packed(event.word);
}
size_t write(const uint8_t *buffer, size_t size) {
// TODO - is this really needed?
return 0;
}
operator bool() {
// TODO - is this really needed?
return true;
}
};
extern MIDI_ MidiUSB;

#endif // __cplusplus
#endif // MIDIUSB_h

+ 147
- 0
cores/teensy3/Makefile View File

@@ -0,0 +1,147 @@
# Teensyduino Core Library
# http://www.pjrc.com/teensy/
# Copyright (c) 2017 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.

# set your MCU type here, or make command line `make MCU=MK20DX256`
MCU=MK20DX256
#MCU=MKL26Z64
#MCU=MK64FX512
#MCU=MK66FX1M0

# make it lower case
LOWER_MCU := $(subst A,a,$(subst B,b,$(subst C,c,$(subst D,d,$(subst E,e,$(subst F,f,$(subst G,g,$(subst H,h,$(subst I,i,$(subst J,j,$(subst K,k,$(subst L,l,$(subst M,m,$(subst N,n,$(subst O,o,$(subst P,p,$(subst Q,q,$(subst R,r,$(subst S,s,$(subst T,t,$(subst U,u,$(subst V,v,$(subst W,w,$(subst X,x,$(subst Y,y,$(subst Z,z,$(MCU)))))))))))))))))))))))))))
MCU_LD = $(LOWER_MCU).ld

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

# Those that specify a NO_ARDUINO environment variable will
# be able to use this Makefile with no Arduino dependency.
# Please note that if ARDUINOPATH was set, it will override
# the NO_ARDUINO behaviour.
ifndef NO_ARDUINO
# Path to your arduino installation
ARDUINOPATH ?= ../../../../..
endif

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

# options needed by many Arduino libraries to configure for Teensy 3.x
OPTIONS += -D__$(MCU)__ -DARDUINO=10805 -DTEENSYDUINO=144

# use "cortex-m4" for Teensy 3.x
# use "cortex-m0plus" for Teensy LC
CPUARCH = cortex-m4
#CPUARCH = cortex-m0plus


# Other Makefiles and project templates for Teensy 3.x:
#
# https://github.com/apmorton/teensy-template
# https://github.com/xxxajk/Arduino_Makefile_master
# https://github.com/JonHylands/uCee


#************************************************************************
# 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.
#************************************************************************

ifdef ARDUINOPATH

# path location for Teensy Loader, teensy_post_compile and teensy_reboot (on Linux)
TOOLSPATH = $(abspath $(ARDUINOPATH)/hardware/tools)

# path location for Arduino libraries (currently not used)
LIBRARYPATH = $(abspath $(ARDUINOPATH)/libraries)

# path location for the arm-none-eabi compiler
COMPILERPATH = $(abspath $(ARDUINOPATH)/hardware/tools/arm/bin)

else
# Default to the normal GNU/Linux compiler path if NO_ARDUINO
# and ARDUINOPATH was not set.
COMPILERPATH ?= /usr/bin

endif

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

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

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

# compiler options for C only
CFLAGS =

# linker options
LDFLAGS = -Os -Wl,--gc-sections,--defsym=__rtc_localtime=0 --specs=nano.specs -mcpu=$(CPUARCH) -mthumb -T$(MCU_LD)

# additional libraries to link
LIBS = -lm


# names for the compiler programs
CC = $(COMPILERPATH)/arm-none-eabi-gcc
CXX = $(COMPILERPATH)/arm-none-eabi-g++
OBJCOPY = $(COMPILERPATH)/arm-none-eabi-objcopy
SIZE = $(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) $(MCU_LD)
$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)

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

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

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

+ 3
- 0
cores/teensy3/Mouse.h View File

@@ -0,0 +1,3 @@
// empty Mouse.h file, for compability with Arduino's Mouse examples

// This header file is in the public domain.

+ 337
- 0
cores/teensy3/Print.cpp View File

@@ -0,0 +1,337 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2017 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.
*/

// Long ago this file contained code from Arduino.cc, which was
// Copyright (c) 2008 David A. Mellis. No substantial portion of
// Arduino's original code remains. In fact, several improvements
// developed for Teensyduino have made their way back into
// Arduino's code base. :-)

#include <Arduino.h>


size_t Print::write(const uint8_t *buffer, size_t size)
{
if (buffer == nullptr) return 0;
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);
}

extern "C" {
__attribute__((weak))
int _write(int file, char *ptr, int len)
{
((class Print *)file)->write((uint8_t *)ptr, len);
return len;
}
}

int Print::printf(const char *format, ...)
{
va_list ap;
va_start(ap, format);
#ifdef __STRICT_ANSI__
return 0; // TODO: make this work with -std=c++0x
#else
return vdprintf((int)this, format, ap);
#endif
}

int Print::printf(const __FlashStringHelper *format, ...)
{
va_list ap;
va_start(ap, format);
#ifdef __STRICT_ANSI__
return 0;
#else
return vdprintf((int)this, (const char *)format, ap);
#endif
}

#ifdef __MKL26Z64__

// optimized code inspired by Stimmer's optimization
// obviously a dit different, adapted to 32 bit Cortex-M0+
// http://forum.arduino.cc/index.php?topic=167414.msg1293679#msg1293679
// http://forum.arduino.cc/index.php?topic=167414.msg1309482#msg1309482
// equivelant code:
// mod = div % 10;
// div = div / 10;
// tmp1 = {random};
// tmp2 = 10;
#if 1
// https://forum.pjrc.com/threads/28932-LC-is-10-9-times-slower-than-T3-1?p=76072&viewfull=1#post76072
void inline divmod10_v2(uint32_t n,uint32_t *div,uint32_t *mod) {
uint32_t p,q;
/* Using 32.16 fixed point representation p.q */
/* p.q = (n+1)/512 */
q = (n&0xFFFF) + 1;
p = (n>>16);
/* p.q = 51*(n+1)/512 */
q = 13107*q;
p = 13107*p;
/* p.q = (1+1/2^8+1/2^16+1/2^24)*51*(n+1)/512 */
q = q + (q>>16) + (p&0xFFFF);
p = p + (p>>16) + (q>>16);
/* divide by 2 */
p = p>>1;
*div = p;
*mod = n-10*p;
}
#define divmod10_asm(div, mod, tmp1, tmp2, const3333) \
divmod10_v2(div, &div, &mod);
/*
#define divmod10_asm(div, mod, tmp1, tmp2, const3333) \
asm ( \
" lsr %2, %0, #16" "\n\t" \
" mul %2, %4" "\n\t" \
" uxth %1, %0" "\n\t" \
" mul %1, %4" "\n\t" \
" add %1, #1" "\n\t" \
" lsr %0, %2, #16" "\n\t" \
" lsl %2, %2, #16" "\n\t" \
" add %1, %2" "\n\t" \
" mov %3, #0" "\n\t" \
" adc %0, %3" "\n\t" \
" lsl %0, %0, #15" "\n\t" \
" lsr %2, %1, #17" "\n\t" \
" orr %0, %2" "\n\t" \
" lsl %1, %1, #15" "\n\t" \
" lsr %2, %1, #16" "\n\t" \
" lsl %3, %0, #16" "\n\t" \
" orr %2, %3" "\n\t" \
" lsr %3, %0, #16" "\n\t" \
" add %1, %0" "\n\t" \
" adc %0, %1" "\n\t" \
" sub %0, %1" "\n\t" \
" add %1, %2" "\n\t" \
" adc %0, %3" "\n\t" \
" lsr %1, %1, #4" "\n\t" \
" mov %3, #10" "\n\t" \
" mul %1, %3" "\n\t" \
" lsr %1, %1, #28" "\n\t" \
: "+l" (div), \
"=&l" (mod), \
"=&l" (tmp1), \
"=&l" (tmp2) \
: "l" (const3333) \
: \
)
*/
#else
#define divmod10_asm(_div, _mod, _tmp1, _tmp2, _const3333) \
({ _tmp1 = _div; _div = _div / 10; _mod = _tmp1 - _div * 10; })
// ({_mod = _div % 10, _div = _div / 10; })
#endif


size_t Print::printNumberDec(unsigned long n, uint8_t sign)
{
uint8_t buf[11], *p;
uint32_t digit;
//uint32_t t1, t2, c3333=0x3333;

p = buf + (sizeof(buf));
do {
uint32_t div;
divmod10_v2(n, &div, &digit);
n = div;
//divmod10_asm(n, digit, t1, t2, c3333);
*--p = digit + '0';
} while (n);
if (sign) *--p = '-';
return write(p, sizeof(buf) - (p - buf));
}

size_t Print::printNumberHex(unsigned long n)
{
uint8_t digit, buf[8], *p;

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

size_t Print::printNumberBin(unsigned long n)
{
uint8_t buf[32], *p;

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

size_t Print::printNumberAny(unsigned long n, uint8_t base)
{
uint8_t digit, buf[21], *p;
uint32_t tmp;

p = buf + sizeof(buf);
do {
tmp = n;
n = n / base;
digit = tmp - n * base;
*--p = (digit < 10) ? '0' + digit : 'A' + digit - 10;
} while (n);
return write(p, sizeof(buf) - (p - buf));
}

#else

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);
}

#endif

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

if (isnan(number)) return print("nan");
if (isinf(number)) return print("inf");
if (number > 4294967040.0f) return print("ovf"); // constant determined empirically
if (number <-4294967040.0f) return print("ovf"); // constant determined empirically
// 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[16], 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;
}



+ 132
- 0
cores/teensy3/Print.h View File

@@ -0,0 +1,132 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2017 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 <stdarg.h>
#include "core_id.h"
#include "WString.h"
#include "Printable.h"

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

// BYTE was defined in very old versions of Arduino
// maybe this now causes more trouble than it's worth?
//#ifndef BYTE
//#define BYTE 0
//#endif

class __FlashStringHelper;

class Print
{
public:
constexpr 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);
virtual int availableForWrite(void) { return 0; }
virtual void flush() { }
size_t write(const char *buffer, size_t size) { return write((const uint8_t *)buffer, 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); }
int printf(const char *format, ...);
int printf(const __FlashStringHelper *format, ...);
protected:
void setWriteError(int err = 1) { write_error = err; }
private:
char write_error;
size_t printFloat(double n, uint8_t digits);
#ifdef __MKL26Z64__
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 base, uint8_t sign) __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 == 16) return printNumberHex(n);
if (base == 2) return printNumberBin(n);
return printNumberAny(n, base);
}
#else
size_t printNumber(unsigned long n, uint8_t base, uint8_t sign);
#endif
};


#endif

+ 42
- 0
cores/teensy3/Printable.h View File

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

+ 346
- 0
cores/teensy3/SPIFIFO.h View File

@@ -0,0 +1,346 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2017 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 _SPIFIFO_h_
#define _SPIFIFO_h_

#include "avr_emulation.h"

#ifdef KINETISK

// The preferred way to set SPI speed is with SPI.beginTransaction()

#if F_BUS == 128000000
#define HAS_SPIFIFO
#define SPI_CLOCK_24MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(0)) //(128 / 3) * ((1+0)/2) = 21.3MHz
#define SPI_CLOCK_16MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(2)) //(128 / 2) * ((1+0)/4)
#define SPI_CLOCK_12MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(2)) //(128 / 3) * ((1+0)/4) = 10.6 MHz
#define SPI_CLOCK_8MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(6)) //(128 / 2) * ((1+0)/8)
#define SPI_CLOCK_6MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(6)) //(128 / 3) * ((1+0)/8) = 5.3 MHz
#define SPI_CLOCK_4MHz (SPI_CTAR_PBR(3) | SPI_CTAR_BR(6)) //(128 / 5) * ((1+0)/8) = 3.2MHz

#elif F_BUS == 120000000
#define HAS_SPIFIFO
#define SPI_CLOCK_24MHz (SPI_CTAR_PBR(3) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(120 / 5) * ((1+1)/2)
#define SPI_CLOCK_16MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(2)) //(120 / 2) * ((1+0)/4) = 15 MHz
#define SPI_CLOCK_12MHz (SPI_CTAR_PBR(3) | SPI_CTAR_BR(0)) //(120 / 5) * ((1+0)/2)
#define SPI_CLOCK_8MHz (SPI_CTAR_PBR(3) | SPI_CTAR_BR(4) | SPI_CTAR_DBR) //(120 / 5) * ((1+1)/6)
#define SPI_CLOCK_6MHz (SPI_CTAR_PBR(3) | SPI_CTAR_BR(2)) //(120 / 5) * ((1+0)/4)
#define SPI_CLOCK_4MHz (SPI_CTAR_PBR(3) | SPI_CTAR_BR(4)) //(120 / 5) * ((1+0)/6)

#elif F_BUS == 108000000
#define HAS_SPIFIFO
#define SPI_CLOCK_24MHz (SPI_CTAR_PBR(3) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(108 / 5) * ((1+1)/2) = 21.6 MHz
#define SPI_CLOCK_16MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(2)) //(108 / 2) * ((1+0)/4) = 13.5 MHz
#define SPI_CLOCK_12MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(4) | SPI_CTAR_DBR) //(108 / 3) * ((1+1)/6)
#define SPI_CLOCK_8MHz (SPI_CTAR_PBR(3) | SPI_CTAR_BR(4) | SPI_CTAR_DBR) //(108 / 5) * ((1+1)/6) = 7.2 MHz
#define SPI_CLOCK_6MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(4)) //(108 / 3) * ((1+0)/6)
#define SPI_CLOCK_4MHz (SPI_CTAR_PBR(5) | SPI_CTAR_BR(2)) //(108 / 7) * ((1+0)/4) = 3.86 MHz

#elif F_BUS == 96000000
#define HAS_SPIFIFO
#define SPI_CLOCK_24MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0)) //(96 / 2) * ((1+0)/2)
#define SPI_CLOCK_16MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(4) | SPI_CTAR_DBR) //(96 / 2) * ((1+1)/6)
#define SPI_CLOCK_12MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(6) | SPI_CTAR_DBR) //(96 / 2) * ((1+1)/8)
#define SPI_CLOCK_8MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(2)) //(96 / 3) * ((1+0)/4)
#define SPI_CLOCK_6MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(6)) //(96 / 2) * ((1+0)/8)
#define SPI_CLOCK_4MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(6)) //(96 / 3) * ((1+0)/8)

#elif F_BUS == 90000000
#define HAS_SPIFIFO
#define SPI_CLOCK_24MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0)) //(90 / 2) * ((1+0)/2) = 22.5 MHz
#define SPI_CLOCK_16MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(4) | SPI_CTAR_DBR) //(90 / 2) * ((1+1)/6) = 15 MHz
#define SPI_CLOCK_12MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(6) | SPI_CTAR_DBR) //(90 / 2) * ((1+1)/8) = 11.25 MHz
#define SPI_CLOCK_8MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(4)) //(90 / 2) * ((1+0)/6) = 7.5 MHz
#define SPI_CLOCK_6MHz (SPI_CTAR_PBR(3) | SPI_CTAR_BR(4) | SPI_CTAR_DBR) //(90 / 5) * ((1+1)/6)
#define SPI_CLOCK_4MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(6)) //(90 / 3) * ((1+0)/8) = 3.75 MHz

#elif F_BUS == 80000000
#define HAS_SPIFIFO
#define SPI_CLOCK_24MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0)) //(80 / 2) * ((1+0)/2) = 20 MHz
#define SPI_CLOCK_16MHz (SPI_CTAR_PBR(3) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(80 / 5) * ((1+1)/2)
#define SPI_CLOCK_12MHz (SPI_CTAR_PBR(5) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(80 / 7) * ((1+1)/2) = 11.42 MHz
#define SPI_CLOCK_8MHz (SPI_CTAR_PBR(3) | SPI_CTAR_BR(0)) //(80 / 5) * ((1+0)/2)
#define SPI_CLOCK_6MHz (SPI_CTAR_PBR(5) | SPI_CTAR_BR(0)) //(80 / 7) * ((1+0)/2) = 5.7 MHz
#define SPI_CLOCK_4MHz (SPI_CTAR_PBR(3) | SPI_CTAR_BR(2)) //(80 / 5) * ((1+0)/4)

#elif F_BUS == 72000000
#define HAS_SPIFIFO
#define SPI_CLOCK_24MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(72 / 3) * ((1+1)/2)
#define SPI_CLOCK_16MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(4) | SPI_CTAR_DBR) //(72 / 2) * ((1+1)/6) = 12 MHz
#define SPI_CLOCK_12MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(4) | SPI_CTAR_DBR) //(72 / 2) * ((1+1)/6)
#define SPI_CLOCK_8MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(4) | SPI_CTAR_DBR) //(72 / 3) * ((1+1)/6)
#define SPI_CLOCK_6MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(4)) //(72 / 2) * ((1+0)/6)
#define SPI_CLOCK_4MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(4)) //(72 / 3) * ((1+0)/6)

#elif F_BUS == 64000000
#define HAS_SPIFIFO
#define SPI_CLOCK_24MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(64 / 3) * ((1+1)/2) = 21.3 MHz
#define SPI_CLOCK_16MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0)) //(64 / 2) * ((1+0)/2)
#define SPI_CLOCK_12MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(0)) //(64 / 3) * ((1+0)/2) = 10.67 MHz
#define SPI_CLOCK_8MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(2)) //(64 / 2) * ((1+0)/4)
#define SPI_CLOCK_6MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(4)) //(64 / 2) * ((1+0)/6) = 5.3 MHz
#define SPI_CLOCK_4MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(6)) //(64 / 2) * ((1+0)/8)

#elif F_BUS == 60000000
#define HAS_SPIFIFO
#define SPI_CLOCK_24MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(60 / 3) * ((1+1)/2) = 20 MHz
#define SPI_CLOCK_16MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0)) //(60 / 2) * ((1+0)/2) = 15 MHz
#define SPI_CLOCK_12MHz (SPI_CTAR_PBR(2) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(60 / 5) * ((1+1)/2)
#define SPI_CLOCK_8MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(1)) //(60 / 2) * ((1+0)/4) = 7.5 MHz
#define SPI_CLOCK_6MHz (SPI_CTAR_PBR(2) | SPI_CTAR_BR(0)) //(60 / 5) * ((1+0)/2)
#define SPI_CLOCK_4MHz (SPI_CTAR_PBR(2) | SPI_CTAR_BR(2) | SPI_CTAR_DBR) //(60 / 5) * ((1+1)/6)

#elif F_BUS == 56000000
#define HAS_SPIFIFO
#define SPI_CLOCK_24MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(56 / 3) * ((1+1)/2) = 18.67
#define SPI_CLOCK_16MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0)) //(56 / 2) * ((1+0)/2) = 14
#define SPI_CLOCK_12MHz (SPI_CTAR_PBR(2) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(56 / 5) * ((1+1)/2) = 11.2
#define SPI_CLOCK_8MHz (SPI_CTAR_PBR(3) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(56 / 7) * ((1+1)/2)
#define SPI_CLOCK_6MHz (SPI_CTAR_PBR(2) | SPI_CTAR_BR(0)) //(56 / 5) * ((1+0)/2)
#define SPI_CLOCK_4MHz (SPI_CTAR_PBR(3) | SPI_CTAR_BR(0)) //(56 / 7) * ((1+0)/2)

#elif F_BUS == 48000000
#define HAS_SPIFIFO
#define SPI_CLOCK_24MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(48 / 2) * ((1+1)/2)
#define SPI_CLOCK_16MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(48 / 3) * ((1+1)/2)
#define SPI_CLOCK_12MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0)) //(48 / 2) * ((1+0)/2)
#define SPI_CLOCK_8MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(2) | SPI_CTAR_DBR) //(48 / 2) * ((1+1)/6)
#define SPI_CLOCK_6MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(1)) //(48 / 2) * ((1+0)/4)
#define SPI_CLOCK_4MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(2)) //(48 / 2) * ((1+0)/6)

#elif F_BUS == 40000000
#define HAS_SPIFIFO
#define SPI_CLOCK_24MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(40 / 2) * ((1+1)/2) = 20
#define SPI_CLOCK_16MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(40 / 3) * ((1+1)/2) = 13.33
#define SPI_CLOCK_12MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0)) //(40 / 2) * ((1+0)/2) = 10
#define SPI_CLOCK_8MHz (SPI_CTAR_PBR(2) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(40 / 5) * ((1+1)/2)
#define SPI_CLOCK_6MHz (SPI_CTAR_PBR(3) | SPI_CTAR_BR(1) | SPI_CTAR_DBR) //(40 / 7) * ((1+1)/2) = 5.71
#define SPI_CLOCK_4MHz (SPI_CTAR_PBR(2) | SPI_CTAR_BR(1)) //(40 / 5) * ((1+0)/2)

#elif F_BUS == 36000000
#define HAS_SPIFIFO
#define SPI_CLOCK_24MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(36 / 2) * ((1+1)/2) = 18
#define SPI_CLOCK_16MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(36 / 3) * ((1+1)/2) = 12
#define SPI_CLOCK_12MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(36 / 3) * ((1+1)/2) = 12
#define SPI_CLOCK_8MHz (SPI_CTAR_PBR(2) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(36 / 5) * ((1+1)/2) = 7.2
#define SPI_CLOCK_6MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(2) | SPI_CTAR_DBR) //(36 / 2) * ((1+1)/6)
#define SPI_CLOCK_4MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(2) | SPI_CTAR_DBR) //(36 / 3) * ((1+1)/6)

#elif F_BUS == 24000000
#define HAS_SPIFIFO
#define SPI_CLOCK_24MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(24 / 2) * ((1+1)/2) 12 MHz
#define SPI_CLOCK_16MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(24 / 2) * ((1+1)/2) 12 MHz
#define SPI_CLOCK_12MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(24 / 2) * ((1+1)/2)
#define SPI_CLOCK_8MHz (SPI_CTAR_PBR(1) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(24 / 3) * ((1+1)/2)
#define SPI_CLOCK_6MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0)) //(24 / 2) * ((1+0)/2)
#define SPI_CLOCK_4MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(2) | SPI_CTAR_DBR) //(24 / 2) * ((1+1)/6)

#elif F_BUS == 16000000
#define HAS_SPIFIFO
#define SPI_CLOCK_24MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(3) | SPI_CTAR_DBR) //(16 / 2) * ((1+1)/8) = 2 MHz
#define SPI_CLOCK_16MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(3) | SPI_CTAR_DBR) //(16 / 2) * ((1+1)/8) = 2 MHz
#define SPI_CLOCK_12MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(3) | SPI_CTAR_DBR) //(16 / 2) * ((1+1)/8) = 2 MHz
#define SPI_CLOCK_8MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(3) | SPI_CTAR_DBR) //(16 / 2) * ((1+1)/8) = 2 MHz
#define SPI_CLOCK_6MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(3) | SPI_CTAR_DBR) //(16 / 2) * ((1+1)/8) = 2 MHz
#define SPI_CLOCK_4MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(3) | SPI_CTAR_DBR) //(16 / 2) * ((1+1)/8) = 2 MHz

#elif F_BUS == 8000000
#define HAS_SPIFIFO
#define SPI_CLOCK_24MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_DBR) //(8 / 2) * ((1+1)/4) = 2 MHz
#define SPI_CLOCK_16MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_DBR) //(8 / 2) * ((1+1)/4) = 2 MHz
#define SPI_CLOCK_12MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_DBR) //(8 / 2) * ((1+1)/4) = 2 MHz
#define SPI_CLOCK_8MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_DBR) //(8 / 2) * ((1+1)/4) = 2 MHz
#define SPI_CLOCK_6MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_DBR) //(8 / 2) * ((1+1)/4) = 2 MHz
#define SPI_CLOCK_4MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(1) | SPI_CTAR_DBR) //(8 / 2) * ((1+1)/4) = 2 MHz

#elif F_BUS == 4000000
#define HAS_SPIFIFO
#define SPI_CLOCK_24MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(4 / 2) * ((1+1)/2) = 2 MHz
#define SPI_CLOCK_16MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(4 / 2) * ((1+1)/2) = 2 MHz
#define SPI_CLOCK_12MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(4 / 2) * ((1+1)/2) = 2 MHz
#define SPI_CLOCK_8MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(4 / 2) * ((1+1)/2) = 2 MHz
#define SPI_CLOCK_6MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(4 / 2) * ((1+1)/2) = 2 MHz
#define SPI_CLOCK_4MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(4 / 2) * ((1+1)/2) = 2 MHz

#elif F_BUS == 2000000
#define HAS_SPIFIFO
#define SPI_CLOCK_24MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(4 / 2) * ((1+1)/2) = 1 MHz
#define SPI_CLOCK_16MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(4 / 2) * ((1+1)/2) = 1 MHz
#define SPI_CLOCK_12MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(4 / 2) * ((1+1)/2) = 1 MHz
#define SPI_CLOCK_8MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(4 / 2) * ((1+1)/2) = 1 MHz
#define SPI_CLOCK_6MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(4 / 2) * ((1+1)/2) = 1 MHz
#define SPI_CLOCK_4MHz (SPI_CTAR_PBR(0) | SPI_CTAR_BR(0) | SPI_CTAR_DBR) //(4 / 2) * ((1+1)/2) = 1 MHz

#endif // F_BUS

#endif // KINETISK

/*
#! /usr/bin/perl
$clock = 60;
for $i (2, 3, 5, 7) {
for $j (0, 1) {
for $k (2, 4, 6, 8, 16, 32) {
$out = $clock / $i * (1 + $j) / $k;
printf "%0.2f : ", $out;
print "$clock / $i * (1 + $j) / $k = $out\n";
}
}
}
*/

// sck = F_BUS / PBR * ((1+DBR)/BR)
// PBR = 2, 3, 5, 7
// DBR = 0, 1 -- zero preferred
// BR = 2, 4, 6, 8, 16, 32, 64, 128, 256, 512


#ifdef HAS_SPIFIFO

#ifndef SPI_MODE0
#define SPI_MODE0 0x00 // CPOL = 0, CPHA = 0
#define SPI_MODE1 0x04 // CPOL = 0, CPHA = 1
#define SPI_MODE2 0x08 // CPOL = 1, CPHA = 0
#define SPI_MODE3 0x0C // CPOL = 1, CPHA = 1
#endif

#define SPI_CONTINUE 1

class SPIFIFOclass
{
public:
inline void begin(uint8_t pin, uint32_t speed, uint32_t mode=SPI_MODE0) __attribute__((always_inline, deprecated)) {
uint32_t p, ctar = speed;
SIM_SCGC6 |= SIM_SCGC6_SPI0;

KINETISK_SPI0.MCR = SPI_MCR_MSTR | SPI_MCR_MDIS | SPI_MCR_HALT | SPI_MCR_PCSIS(0x1F);
if (mode & 0x08) ctar |= SPI_CTAR_CPOL;
if (mode & 0x04) {
ctar |= SPI_CTAR_CPHA;
ctar |= (ctar & 0x0F) << 8;
} else {
ctar |= (ctar & 0x0F) << 12;
}
KINETISK_SPI0.CTAR0 = ctar | SPI_CTAR_FMSZ(7);
KINETISK_SPI0.CTAR1 = ctar | SPI_CTAR_FMSZ(15);
if (pin == 10) { // PTC4
CORE_PIN10_CONFIG = PORT_PCR_MUX(2);
p = 0x01;
} else if (pin == 2) { // PTD0
CORE_PIN2_CONFIG = PORT_PCR_MUX(2);
p = 0x01;
} else if (pin == 9) { // PTC3
CORE_PIN9_CONFIG = PORT_PCR_MUX(2);
p = 0x02;
} else if (pin == 6) { // PTD4
CORE_PIN6_CONFIG = PORT_PCR_MUX(2);
p = 0x02;
} else if (pin == 20) { // PTD5
CORE_PIN20_CONFIG = PORT_PCR_MUX(2);
p = 0x04;
} else if (pin == 23) { // PTC2
CORE_PIN23_CONFIG = PORT_PCR_MUX(2);
p = 0x04;
} else if (pin == 21) { // PTD6
CORE_PIN21_CONFIG = PORT_PCR_MUX(2);
p = 0x08;
} else if (pin == 22) { // PTC1
CORE_PIN22_CONFIG = PORT_PCR_MUX(2);
p = 0x08;
} else if (pin == 15) { // PTC0
CORE_PIN15_CONFIG = PORT_PCR_MUX(2);
p = 0x10;
#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
} else if (pin == 26) {
CORE_PIN26_CONFIG = PORT_PCR_MUX(2);
p = 0x01;
#endif
} else {
reg = portOutputRegister(pin);
pinMode(pin, OUTPUT);
*reg = 1;
p = 0;
}
pcs = p;
clear();
SPCR.enable_pins();
}
inline void write(uint32_t b, uint32_t cont=0) __attribute__((always_inline)) {
uint32_t pcsbits = pcs << 16;
if (pcsbits) {
KINETISK_SPI0.PUSHR = (b & 0xFF) | pcsbits | (cont ? SPI_PUSHR_CONT : 0);
while (((KINETISK_SPI0.SR) & (15 << 12)) > (3 << 12)) ; // wait if FIFO full
} else {
*reg = 0;
KINETISK_SPI0.SR = SPI_SR_EOQF;
KINETISK_SPI0.PUSHR = (b & 0xFF) | (cont ? 0 : SPI_PUSHR_EOQ);
if (cont) {
while (((KINETISK_SPI0.SR) & (15 << 12)) > (3 << 12)) ;
} else {
while (!(KINETISK_SPI0.SR & SPI_SR_EOQF)) ;
*reg = 1;
}
}
}
inline void write16(uint32_t b, uint32_t cont=0) __attribute__((always_inline)) {
uint32_t pcsbits = pcs << 16;
if (pcsbits) {
KINETISK_SPI0.PUSHR = (b & 0xFFFF) | (pcs << 16) |
(cont ? SPI_PUSHR_CONT : 0) | SPI_PUSHR_CTAS(1);
while (((KINETISK_SPI0.SR) & (15 << 12)) > (3 << 12)) ;
} else {
*reg = 0;
KINETISK_SPI0.SR = SPI_SR_EOQF;
KINETISK_SPI0.PUSHR = (b & 0xFFFF) | (cont ? 0 : SPI_PUSHR_EOQ) | SPI_PUSHR_CTAS(1);
if (cont) {
while (((KINETISK_SPI0.SR) & (15 << 12)) > (3 << 12)) ;
} else {
while (!(KINETISK_SPI0.SR & SPI_SR_EOQF)) ;
*reg = 1;
}
}
}
inline uint32_t read(void) __attribute__((always_inline)) {
while ((KINETISK_SPI0.SR & (15 << 4)) == 0) ; // TODO, could wait forever
return KINETISK_SPI0.POPR;
}
inline void clear(void) __attribute__((always_inline)) {
KINETISK_SPI0.MCR = SPI_MCR_MSTR | SPI_MCR_PCSIS(0x1F) | SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF;
}
private:
static uint8_t pcs;
static volatile uint8_t *reg;
};
extern SPIFIFOclass SPIFIFO;

#endif // HAS_SPIFIFO

#endif

+ 33
- 0
cores/teensy3/Server.h View File

@@ -0,0 +1,33 @@
/*
Server.h - Base class that provides Server
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 server_h
#define server_h

#include "Print.h"

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

#endif
#endif

+ 292
- 0
cores/teensy3/Stream.cpp View File

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

#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(const 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(const 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(const char *target, const char *terminator)
{
if(target == nullptr) return true;
size_t tlen = (terminator==nullptr)?0:strlen(terminator);
return findUntil(target, strlen(target), terminator, tlen);
}

// 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(const char *target, size_t targetLen, const char *terminator, size_t termLen)
{
size_t index = 0; // maximum target string length is 64k bytes!
size_t termIndex = 0;
int c;
if( target == nullptr) return true;
if( *target == 0) return true; // return true if target is a null string
if (terminator == nullptr) termLen = 0;

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;
int 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)
{
if (buffer == nullptr) return 0;
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 (buffer == nullptr) return 0;
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 = 0;
while (length < max) {
int c = timedRead();
if (c < 0) {
setReadError();
break; // timeout
}
if (c == 0) break;
str += (char)c;
length++;
}
return str;
}

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

+ 73
- 0
cores/teensy3/Stream.h View File

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

void setTimeout(unsigned long timeout);
bool find(const char *target);
bool find(const uint8_t *target) { return find ((const char *)target); }
bool find(const String &target) { return find(target.c_str()); }
bool find(const char *target, size_t length);
bool find(const uint8_t *target, size_t length) { return find ((const char *)target, length); }
bool find(const String &target, size_t length) { return find(target.c_str(), length); }
bool findUntil(const char *target, const char *terminator);
bool findUntil(const uint8_t *target, const char *terminator) { return findUntil((const char *)target, terminator); }
bool findUntil(const String &target, const char *terminator) { return findUntil(target.c_str(), terminator); }
bool findUntil(const char *target, const String &terminator) { return findUntil(target, terminator.c_str()); }
bool findUntil(const String &target, const String &terminator) { return findUntil(target.c_str(), terminator.c_str()); }
bool findUntil(const char *target, size_t targetLen, const char *terminate, size_t termLen);
bool findUntil(const uint8_t *target, size_t targetLen, const char *terminate, size_t termLen) {return findUntil((const char *)target, targetLen, terminate, termLen); }
bool findUntil(const String &target, size_t targetLen, const char *terminate, size_t termLen);
bool findUntil(const char *target, size_t targetLen, const String &terminate, size_t termLen);
bool findUntil(const String &target, size_t targetLen, const String &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 readBytes(uint8_t *buffer, size_t length) { return readBytes((char *)buffer, length); }
size_t readBytesUntil(char terminator, char *buffer, size_t length);
size_t readBytesUntil(char terminator, uint8_t *buffer, size_t length) { return readBytesUntil(terminator, (char *)buffer, 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

+ 152
- 0
cores/teensy3/Tone.cpp View File

@@ -0,0 +1,152 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2017 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 <Arduino.h>

// 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 float tone_usec=0.0;
static uint32_t tone_new_count=0;
IntervalTimer tone_timer;

void tone_interrupt(void);

#if defined(KINETISK)
#define TONE_CLEAR_PIN tone_reg[0] = 1
#define TONE_TOGGLE_PIN tone_reg[128] = 1
#define TONE_OUTPUT_PIN tone_reg[384] = 1

#elif defined(KINETISL)
static uint8_t tone_mask;
#define TONE_CLEAR_PIN tone_reg[0] = tone_mask
#define TONE_TOGGLE_PIN tone_reg[4] = tone_mask
#define TONE_OUTPUT_PIN __disable_irq(); tone_reg[12] |= tone_mask; __enable_irq()

#endif

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;
if (!(count & 1)) count++; // always full waveform cycles
} else {
count = 0xFFFFFFFD;
}
if (frequency < 1) frequency = 1; // minimum is 1 Hz
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) {
// changing a pin which is already playing a tone
if (usec == tone_usec) {
// same frequency, so just change the duration
tone_toggle_count = (tone_toggle_count & 1) + count - 1;
} else {
// different frequency, reduce duration to only the
// remainder of its current cycle, and configure for
// the transition to the new frequency when the
// current cycle completes
tone_usec = usec;
tone_new_count = count;
tone_toggle_count = (tone_toggle_count & 1);
}
} else {
// if playing on a different pin, immediately stop, even mid-cycle :-(
if (tone_pin < CORE_NUM_DIGITAL) {
TONE_CLEAR_PIN; // clear pin
}
// configure the new tone to play
tone_pin = pin;
tone_reg = portClearRegister(pin);
#if defined(KINETISL)
tone_mask = digitalPinToBitMask(pin);
#endif
TONE_CLEAR_PIN; // clear pin
TONE_OUTPUT_PIN; // output mode;
*config = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
tone_toggle_count = count;
tone_usec = usec;
tone_timer.begin(tone_interrupt, usec);
}
__enable_irq();
}


void tone_interrupt(void)
{
if (tone_toggle_count) { // odd = rising edge, even = falling edge
// not the end
TONE_TOGGLE_PIN; // toggle
tone_toggle_count--;
if (tone_toggle_count == 0xFFFFFFFB) tone_toggle_count = 0xFFFFFFFD;
} else {
// this transition completes the tone
TONE_CLEAR_PIN; // clear
if (tone_new_count > 0) {
// begin playing a new tone
tone_timer.begin(tone_interrupt, tone_usec);
tone_toggle_count = tone_new_count;
tone_new_count = 0;
} else {
// finished playing
tone_timer.end();
tone_pin = 255;
}
}
}

void noTone(uint8_t pin)
{
if (pin >= CORE_NUM_DIGITAL) return;
__disable_irq();
if (pin == tone_pin) {
tone_timer.end();
TONE_CLEAR_PIN; // clear
tone_pin = 255;
}
__enable_irq();
}




+ 92
- 0
cores/teensy3/Udp.h View File

@@ -0,0 +1,92 @@
/*
* 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 uint8_t beginMulticast(IPAddress, uint16_t) { return 0; }
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
cores/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

+ 3
- 0
cores/teensy3/WConstants.h View File

@@ -0,0 +1,3 @@
// This header file is in the public domain.

#include "wiring.h"

+ 66
- 0
cores/teensy3/WMath.cpp View File

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

#include <stdint.h>

static uint32_t seed;

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

void srandom(unsigned int newseed)
{
seed = newseed;
}

int32_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;
}

unsigned int makeWord(unsigned int w) { return w; }
unsigned int makeWord(unsigned char h, unsigned char l) { return (h << 8) | l; }


+ 108
- 0
cores/teensy3/WProgram.h View File

@@ -0,0 +1,108 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2017 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 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))
#define FASTRUN __attribute__ ((section(".fastrun"), noinline, noclone ))

#ifdef __cplusplus

#include "avr_emulation.h"
#include "usb_serial.h"
#include "usb_serial2.h"
#include "usb_serial3.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 "usb_mtp.h"
#include "usb_audio.h"
#include "usb_touch.h"
#include "usb_undef.h" // do not allow usb_desc.h stuff to leak to user programs

#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
int32_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(unsigned int newseed);

#include "pins_arduino.h"

#endif // __cplusplus


// Fast memcpy
#if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
#ifdef __cplusplus
extern "C" {
extern void *memcpy (void *dst, const void *src, size_t count);
}
#else
extern void *memcpy (void *dst, const void *src, size_t count);
#endif
#endif


#endif // WProgram_h

+ 736
- 0
cores/teensy3/WString.cpp View File

@@ -0,0 +1,736 @@
/*
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 <Arduino.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;
}

#if __cplusplus >= 201103L || defined(__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);
}

#if __cplusplus >= 201103L || defined(__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;
bool self = false;
unsigned int buffer_offset;
if ( (cstr >= buffer) && (cstr < (buffer+len) ) ) {
self = true;
buffer_offset = (unsigned int)(cstr-buffer);
}
if (length == 0 || !reserve(newlen)) return *this;
if ( self ) {
memcpy(buffer + len, buffer+buffer_offset, length);
buffer[newlen] = 0;
}
else
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) 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) 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;
}



+ 227
- 0
cores/teensy3/WString.h View File

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

// Not needed here, but some libs assume WString.h or Print.h
// gives them PROGMEM and other AVR stuff.
#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 *)(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);
#if __cplusplus >= 201103L || defined(__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);
#if __cplusplus >= 201103L || defined(__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);
private:
// allow for "if (s)" without the complications of an operator bool().
// for more information http://www.artima.com/cppsource/safebool.html
typedef void (String::*StringIfHelperType)() const;
void StringIfHelper() const {}
public:
operator StringIfHelperType() const { return buffer ? &String::StringIfHelper : 0; }
};

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

+ 579
- 0
cores/teensy3/analog.c View File

@@ -0,0 +1,579 @@
/* Teensyduino Core Library
* http://www.pjrc.com/teensy/
* Copyright (c) 2017 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 == 128000000
#define ADC_CFG1_16BIT ADC_CFG1_ADIV(3) + ADC_CFG1_ADICLK(1) // 8 MHz
#define ADC_CFG1_12BIT ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1) // 16 MHz
#define ADC_CFG1_10BIT ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1) // 16 MHz
#define ADC_CFG1_8BIT ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1) // 16 MHz
#elif F_BUS == 120000000
#define ADC_CFG1_16BIT ADC_CFG1_ADIV(3) + ADC_CFG1_ADICLK(1) // 7.5 MHz
#define ADC_CFG1_12BIT ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1) // 15 MHz
#define ADC_CFG1_10BIT ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1) // 15 MHz
#define ADC_CFG1_8BIT ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1) // 15 MHz
#elif F_BUS == 108000000
#define ADC_CFG1_16BIT ADC_CFG1_ADIV(3) + ADC_CFG1_ADICLK(1) // 7 MHz
#define ADC_CFG1_12BIT ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1) // 14 MHz
#define ADC_CFG1_10BIT ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1) // 14 MHz
#define ADC_CFG1_8BIT ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1) // 14 MHz
#elif F_BUS == 96000000
#define ADC_CFG1_16BIT ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1) // 12 MHz
#define ADC_CFG1_12BIT ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1) // 12 MHz
#define ADC_CFG1_10BIT ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1) // 12 MHz
#define ADC_CFG1_8BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 24 MHz
#elif F_BUS == 90000000
#define ADC_CFG1_16BIT ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1) // 11.25 MHz
#define ADC_CFG1_12BIT ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1) // 11.25 MHz
#define ADC_CFG1_10BIT ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1) // 11.25 MHz
#define ADC_CFG1_8BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 22.5 MHz
#elif F_BUS == 80000000
#define ADC_CFG1_16BIT ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1) // 10 MHz
#define ADC_CFG1_12BIT ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1) // 10 MHz
#define ADC_CFG1_10BIT ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1) // 10 MHz
#define ADC_CFG1_8BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 20 MHz
#elif F_BUS == 72000000
#define ADC_CFG1_16BIT ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1) // 9 MHz
#define ADC_CFG1_12BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 18 MHz
#define ADC_CFG1_10BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 18 MHz
#define ADC_CFG1_8BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 18 MHz
#elif F_BUS == 64000000
#define ADC_CFG1_16BIT ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1) // 8 MHz
#define ADC_CFG1_12BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 16 MHz
#define ADC_CFG1_10BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 16 MHz
#define ADC_CFG1_8BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 16 MHz
#elif F_BUS == 60000000
#define ADC_CFG1_16BIT ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1) // 7.5 MHz
#define ADC_CFG1_12BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 15 MHz
#define ADC_CFG1_10BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 15 MHz
#define ADC_CFG1_8BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 15 MHz
#elif F_BUS == 56000000 || F_BUS == 54000000
#define ADC_CFG1_16BIT ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1) // 7 MHz
#define ADC_CFG1_12BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 14 MHz
#define ADC_CFG1_10BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 14 MHz
#define ADC_CFG1_8BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 14 MHz
#elif F_BUS == 48000000
#define ADC_CFG1_16BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 12 MHz
#define ADC_CFG1_12BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 12 MHz
#define ADC_CFG1_10BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 12 MHz
#define ADC_CFG1_8BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(1) // 24 MHz
#elif F_BUS == 40000000
#define ADC_CFG1_16BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 10 MHz
#define ADC_CFG1_12BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 10 MHz
#define ADC_CFG1_10BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 10 MHz
#define ADC_CFG1_8BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(1) // 20 MHz
#elif F_BUS == 36000000
#define ADC_CFG1_16BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1) // 9 MHz
#define ADC_CFG1_12BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(1) // 18 MHz
#define ADC_CFG1_10BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(1) // 18 MHz
#define ADC_CFG1_8BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(1) // 18 MHz
#elif F_BUS == 24000000
#define ADC_CFG1_16BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(0) // 12 MHz
#define ADC_CFG1_12BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(0) // 12 MHz
#define ADC_CFG1_10BIT ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(0) // 12 MHz
#define ADC_CFG1_8BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 24 MHz
#elif F_BUS == 16000000
#define ADC_CFG1_16BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 8 MHz
#define ADC_CFG1_12BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 8 MHz
#define ADC_CFG1_10BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 8 MHz
#define ADC_CFG1_8BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 16 MHz
#elif F_BUS == 8000000
#define ADC_CFG1_16BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 8 MHz
#define ADC_CFG1_12BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 8 MHz
#define ADC_CFG1_10BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 8 MHz
#define ADC_CFG1_8BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 8 MHz
#elif F_BUS == 4000000
#define ADC_CFG1_16BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 4 MHz
#define ADC_CFG1_12BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 4 MHz
#define ADC_CFG1_10BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 4 MHz
#define ADC_CFG1_8BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 4 MHz
#elif F_BUS == 2000000
#define ADC_CFG1_16BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 2 MHz
#define ADC_CFG1_12BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 2 MHz
#define ADC_CFG1_10BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 2 MHz
#define ADC_CFG1_8BIT ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0) // 2 MHz
#else
#error "F_BUS must be 128, 120, 108, 96, 90, 80, 72, 64, 60, 56, 54, 48, 40, 36, 24, 4 or 2 MHz"
#endif

void analog_init(void)
{
uint32_t num;

#if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
VREF_TRM = 0x60;
VREF_SC = 0xE1; // enable 1.2 volt ref
#endif

if (analog_config_bits == 8) {
ADC0_CFG1 = ADC_CFG1_8BIT + ADC_CFG1_MODE(0);
ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(3);
#ifdef HAS_KINETIS_ADC1
ADC1_CFG1 = ADC_CFG1_8BIT + ADC_CFG1_MODE(0);
ADC1_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(3);
#endif
} else if (analog_config_bits == 10) {
ADC0_CFG1 = ADC_CFG1_10BIT + ADC_CFG1_MODE(2) + ADC_CFG1_ADLSMP;
ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(3);
#ifdef HAS_KINETIS_ADC1
ADC1_CFG1 = ADC_CFG1_10BIT + ADC_CFG1_MODE(2) + ADC_CFG1_ADLSMP;
ADC1_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(3);
#endif
} else if (analog_config_bits == 12) {
ADC0_CFG1 = ADC_CFG1_12BIT + ADC_CFG1_MODE(1) + ADC_CFG1_ADLSMP;
ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(2);
#ifdef HAS_KINETIS_ADC1
ADC1_CFG1 = ADC_CFG1_12BIT + ADC_CFG1_MODE(1) + ADC_CFG1_ADLSMP;
ADC1_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(2);
#endif
} else {
ADC0_CFG1 = ADC_CFG1_16BIT + ADC_CFG1_MODE(3) + ADC_CFG1_ADLSMP;
ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(2);
#ifdef HAS_KINETIS_ADC1
ADC1_CFG1 = ADC_CFG1_16BIT + ADC_CFG1_MODE(3) + ADC_CFG1_ADLSMP;
ADC1_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(2);
#endif
}

#if defined(__MK20DX128__)
if (analog_reference_internal) {
ADC0_SC2 = ADC_SC2_REFSEL(1); // 1.2V ref
} else {
ADC0_SC2 = ADC_SC2_REFSEL(0); // vcc/ext ref
}
#elif defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
if (analog_reference_internal) {
ADC0_SC2 = ADC_SC2_REFSEL(1); // 1.2V ref
ADC1_SC2 = ADC_SC2_REFSEL(1); // 1.2V ref
} else {
ADC0_SC2 = ADC_SC2_REFSEL(0); // vcc/ext ref
ADC1_SC2 = ADC_SC2_REFSEL(0); // vcc/ext ref
}
#elif defined(__MKL26Z64__)
if (analog_reference_internal) {
ADC0_SC2 = ADC_SC2_REFSEL(0); // external AREF
} else {
ADC0_SC2 = ADC_SC2_REFSEL(1); // vcc
}
#endif

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

static void wait_for_cal(void)
{
uint16_t sum;

//serial_print("wait_for_cal\n");
#if defined(HAS_KINETIS_ADC0) && defined(HAS_KINETIS_ADC1)
while ((ADC0_SC3 & ADC_SC3_CAL) || (ADC1_SC3 & ADC_SC3_CAL)) {
// wait
}
#elif defined(HAS_KINETIS_ADC0)
while (ADC0_SC3 & ADC_SC3_CAL) {
// wait
}
#endif
__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");
#ifdef HAS_KINETIS_ADC1
sum = ADC1_CLPS + ADC1_CLP4 + ADC1_CLP3 + ADC1_CLP2 + ADC1_CLP1 + ADC1_CLP0;
sum = (sum / 2) | 0x8000;
ADC1_PG = sum;
sum = ADC1_CLMS + ADC1_CLM4 + ADC1_CLM3 + ADC1_CLM2 + ADC1_CLM1 + ADC1_CLM0;
sum = (sum / 2) | 0x8000;
ADC1_MG = sum;
#endif
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

#if defined(__MK20DX128__) || defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
#define DEFAULT 0
#define INTERNAL 2
#define INTERNAL1V2 2
#define INTERNAL1V1 2
#define EXTERNAL 0

#elif defined(__MKL26Z64__)
#define DEFAULT 0
#define INTERNAL 0
#define EXTERNAL 1
#endif

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
#ifdef HAS_KINETIS_ADC1
ADC1_SC3 = 0; // cancel cal
#endif
}
analog_init();
}
} else {
// vcc or external reference requested
if (analog_reference_internal) {
analog_reference_internal = 0;
if (calibrating) {
ADC0_SC3 = 0; // cancel cal
#ifdef HAS_KINETIS_ADC1
ADC1_SC3 = 0; // cancel cal
#endif
}
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
#ifdef HAS_KINETIS_ADC1
ADC1_SC3 = 0;
#endif
}
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);
#ifdef HAS_KINETIS_ADC1
ADC1_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(0);
#endif
} else if (num <= 8) {
num = 8;
ADC0_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(1);
#ifdef HAS_KINETIS_ADC1
ADC1_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(1);
#endif
} else if (num <= 16) {
num = 16;
ADC0_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(2);
#ifdef HAS_KINETIS_ADC1
ADC1_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(2);
#endif
} else {
num = 32;
ADC0_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(3);
#ifdef HAS_KINETIS_ADC1
ADC1_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(3);
#endif
}
analog_num_average = num;
}

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

#if defined(__MK20DX128__)
static const uint8_t pin2sc1a[] = {
5, 14, 8, 9, 13, 12, 6, 7, 15, 4, 0, 19, 3, 21, // 0-13 -> A0-A13
5, 14, 8, 9, 13, 12, 6, 7, 15, 4, // 14-23 are A0-A9
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 24-33 are digital only
0, 19, 3, 21, // 34-37 are A10-A13
26, // 38 is temp sensor
22, // 39 is vref
23 // 40 is unused analog pin
};
#elif defined(__MK20DX256__)
static const uint8_t pin2sc1a[] = {
5, 14, 8, 9, 13, 12, 6, 7, 15, 4, 0, 19, 3, 19+128, // 0-13 -> A0-A13
5, 14, 8, 9, 13, 12, 6, 7, 15, 4, // 14-23 are A0-A9
255, 255, // 24-25 are digital only
5+192, 5+128, 4+128, 6+128, 7+128, 4+192, // 26-31 are A15-A20
255, 255, // 32-33 are digital only
0, 19, 3, 19+128, // 34-37 are A10-A13
26, // 38 is temp sensor,
18+128, // 39 is vref
23 // 40 is A14
};
#elif defined(__MKL26Z64__)
static const uint8_t pin2sc1a[] = {
5, 14, 8, 9, 13, 12, 6, 7, 15, 11, 0, 4+64, 23, // 0-12 -> A0-A12
255, // 13 is digital only (no A13 alias)
5, 14, 8, 9, 13, 12, 6, 7, 15, 11, 0, 4+64, 23, // 14-26 are A0-A12
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, // 27-37 unused
26, // 38=temperature
27 // 39=bandgap ref (PMC_REGSC |= PMC_REGSC_BGBE)
};
#elif defined(__MK64FX512__) || defined(__MK66FX1M0__)
static const uint8_t pin2sc1a[] = {
5, 14, 8, 9, 13, 12, 6, 7, 15, 4, 3, 19+128, 14+128, 15+128, // 0-13 -> A0-A13
5, 14, 8, 9, 13, 12, 6, 7, 15, 4, // 14-23 are A0-A9
255, 255, 255, 255, 255, 255, 255, // 24-30 are digital only
14+128, 15+128, 17, 18, 4+128, 5+128, 6+128, 7+128, 17+128, // 31-39 are A12-A20
255, 255, 255, 255, 255, 255, 255, 255, 255, // 40-48 are digital only
10+128, 11+128, // 49-50 are A23-A24
255, 255, 255, 255, 255, 255, 255, // 51-57 are digital only
255, 255, 255, 255, 255, 255, // 58-63 (sd card pins) are digital only
3, 19+128, // 64-65 are A10-A11
23, 23+128,// 66-67 are A21-A22 (DAC pins)
1, 1+128, // 68-69 are A25-A26 (unused USB host port on Teensy 3.5)
26, // 70 is Temperature Sensor
18+128 // 71 is Vref
};
#endif



// TODO: perhaps this should store the NVIC priority, so it works recursively?
static volatile uint8_t analogReadBusyADC0 = 0;
#ifdef HAS_KINETIS_ADC1
static volatile uint8_t analogReadBusyADC1 = 0;
#endif

int analogRead(uint8_t pin)
{
int result;
uint8_t channel;

//serial_phex(pin);
//serial_print(" ");

if (pin >= sizeof(pin2sc1a)) return 0;
channel = pin2sc1a[pin];
if (channel == 255) return 0;

if (calibrating) wait_for_cal();

#ifdef HAS_KINETIS_ADC1
if (channel & 0x80) goto beginADC1;
#endif

__disable_irq();
startADC0:
//serial_print("startADC0\n");
#if defined(__MKL26Z64__)
if (channel & 0x40) {
ADC0_CFG2 &= ~ADC_CFG2_MUXSEL;
channel &= 0x3F;
} else {
ADC0_CFG2 |= ADC_CFG2_MUXSEL;
}
#endif
ADC0_SC1A = channel;
analogReadBusyADC0 = 1;
__enable_irq();
while (1) {
__disable_irq();
if ((ADC0_SC1A & ADC_SC1_COCO)) {
result = ADC0_RA;
analogReadBusyADC0 = 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 (!analogReadBusyADC0) goto startADC0;
__enable_irq();
yield();
}

#ifdef HAS_KINETIS_ADC1
beginADC1:
__disable_irq();
startADC1:
//serial_print("startADC1\n");
// ADC1_CFG2[MUXSEL] bit selects between ADCx_SEn channels a and b.
if (channel & 0x40) {
ADC1_CFG2 &= ~ADC_CFG2_MUXSEL;
} else {
ADC1_CFG2 |= ADC_CFG2_MUXSEL;
}
ADC1_SC1A = channel & 0x3F;
analogReadBusyADC1 = 1;
__enable_irq();
while (1) {
__disable_irq();
if ((ADC1_SC1A & ADC_SC1_COCO)) {
result = ADC1_RA;
analogReadBusyADC1 = 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 (!analogReadBusyADC1) goto startADC1;
__enable_irq();
yield();
}
#endif
}

typedef int16_t __attribute__((__may_alias__)) aliased_int16_t;

void analogWriteDAC0(int val)
{
#if defined(__MK20DX256__) || defined(__MK64FX512__) || defined(__MK66FX1M0__)
SIM_SCGC2 |= SIM_SCGC2_DAC0;
if (analog_reference_internal) {
DAC0_C0 = DAC_C0_DACEN; // 1.2V ref is DACREF_1
} else {
DAC0_C0 = DAC_C0_DACEN | DAC_C0_DACRFS; // 3.3V VDDA is DACREF_2
}
__asm__ ("usat %[value], #12, %[value]\n\t" : [value] "+r" (val)); // 0 <= val <= 4095

*(volatile aliased_int16_t *)&(DAC0_DAT0L) = val;
#elif defined(__MKL26Z64__)
SIM_SCGC6 |= SIM_SCGC6_DAC0;
if (analog_reference_internal == 0) {
// use 3.3V VDDA power as the reference (this is the default)
DAC0_C0 = DAC_C0_DACEN | DAC_C0_DACRFS | DAC_C0_DACSWTRG; // 3.3V VDDA
} else {
// use whatever voltage is on the AREF pin
DAC0_C0 = DAC_C0_DACEN | DAC_C0_DACSWTRG; // 3.3V VDDA
}
if (val < 0) val = 0;
else if (val > 4095) val = 4095;

*(volatile aliased_int16_t *)&(DAC0_DAT0L) = val;
#endif
}


#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
void analogWriteDAC1(int val)
{
SIM_SCGC2 |= SIM_SCGC2_DAC1;
if (analog_reference_internal) {
DAC1_C0 = DAC_C0_DACEN; // 1.2V ref is DACREF_1
} else {
DAC1_C0 = DAC_C0_DACEN | DAC_C0_DACRFS; // 3.3V VDDA is DACREF_2
}
__asm__ ("usat %[value], #12, %[value]\n\t" : [value] "+r" (val)); // 0 <= val <= 4095

*(volatile aliased_int16_t *)&(DAC1_DAT0L) = val;
}
#endif
















+ 38
- 0
cores/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 */

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


+ 44
- 0
cores/teensy3/avr/eeprom.h View File

@@ -0,0 +1,44 @@
/* Simple compatibility headers for AVR code used with ARM chips
* Copyright (c) 2015 Paul Stoffregen <paul@pjrc.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.
*/

// Guidelines for editing this file:
// https://forum.pjrc.com/threads/34537-Teensy-LC-Increase-EEPROM-Size/page2

#ifndef _AVR_EEPROM_H_
#define _AVR_EEPROM_H_ 1

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

#include "avr_functions.h"

#if defined(__MK20DX128__) || defined(__MK20DX256__)
#define E2END 0x7FF
#elif defined(__MK64FX512__) || defined(__MK66FX1M0__)
#define E2END 0xFFF
#elif defined(__MKL26Z64__)
#define E2END 0x7F
#else
#define E2END 0
#endif

#endif

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

@@ -0,0 +1 @@
// This header file is in the public domain.

+ 23
- 0
cores/teensy3/avr/io.h View File

@@ -0,0 +1,23 @@
/* Simple compatibility headers for AVR code used with ARM chips
* Copyright (c) 2015 Paul Stoffregen <paul@pjrc.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 "../avr_emulation.h"

+ 132
- 0
cores/teensy3/avr/pgmspace.h View File

@@ -0,0 +1,132 @@
/* Simple compatibility headers for AVR code used with ARM chips
* Copyright (c) 2015 Paul Stoffregen <paul@pjrc.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 __PGMSPACE_H_
#define __PGMSPACE_H_ 1

#include <inttypes.h>

#define PROGMEM
#define FLASHMEM
#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;
typedef int64_t prog_int64_t;
typedef uint64_t prog_uint64_t;

#define memchr_P(str, c, len) memchr((str), (c), (len))
#define memcmp_P(a, b, n) memcmp((a), (b), (n))
#define memcpy_P(dest, src, num) memcpy((dest), (src), (num))
#define memmem_P(a, alen, b, blen) memmem((a), (alen), (b), (blen))
#define memrchr_P(str, val, len) memrchr((str), (val), (len))
#define strcat_P(dest, src) strcat((dest), (src))
#define strchr_P(str, c) strchr((str), (c))
#define strchrnul_P(str, c) strchrnul((str), (c))
#define strcmp_P(a, b) strcmp((a), (b))
#define strcpy_P(dest, src) strcpy((dest), (src))
#define strcasecmp_P(a, b) strcasecmp((a), (b))
#define strcasestr_P(a, b) strcasestr((a), (b))
#define strlcat_P(dest, src, len) strlcat((dest), (src), (len))
#define strlcpy_P(dest, src, len) strlcpy((dest), (src), (len))
#define strlen_P(s) strlen((const char *)(s))
#define strnlen_P(str, len) strnlen((str), (len))
#define strncmp_P(a, b, n) strncmp((a), (b), (n))
#define strncasecmp_P(a, b, n) strncasecmp((a), (b), (n))
#define strncat_P(a, b, n) strncat((a), (b), (n))
#define strncpy_P(a, b, n) strncpy((a), (b), (n))
#define strpbrk_P(str, chrs) strpbrk((str), (chrs))
#define strrchr_P(str, c) strrchr((str), (c))
#define strsep_P(strp, delim) strsep((strp), (delim))
#define strspn_P(str, chrs) strspn((str), (chrs))
#define strstr_P(a, b) strstr((a), (b))
#define sprintf_P(s, ...) sprintf((s), __VA_ARGS__)
#define vfprintf_P(fp, s, ...) vfprintf((fp), (s), __VA_ARGS__)
#define printf_P(...) printf(__VA_ARGS__)
#define snprintf_P(s, n, ...) snprintf((s), (n), __VA_ARGS__)
#define vsprintf_P(s, ...) vsprintf((s), __VA_ARGS__)
#define vsnprintf_P(s, n, ...) vsnprintf((s), (n), __VA_ARGS__)
#define fprintf_P(fp, ...) fprintf((fp), __VA_ARGS__)
#define strlen_PF(a) strlen((a))
#define strnlen_PF(src, len) strnlen((src), (len))
#define memcpy_PF(dest, src, len) memcpy((dest), (src), (len))
#define strcpy_PF(dest, src) strcpy((dest), (src))
#define strncpy_PF(dest, src, len) strncpy((dest), (src), (len))
#define strcat_PF(dest, src) strcat((dest), (src))
#define strlcat_PF(dest, src, len) strlcat((dest), (src), (len))
#define strncat_PF(dest, src, len) strncat((dest), (src), (len))
#define strcmp_PF(s1, s2) strcmp((s1), (s2))
#define strncmp_PF(s1, s2, n) strncmp((s1), (s2), (n))
#define strcasecmp_PF(s1, s2) strcasecmp((s1), (s2))
#define strncasecmp_PF(s1, s2, n) strncasecmp((s1), (s2), (n))
#define strstr_PF(s1, s2) strstr((s1), (s2))
#define strlcpy_PF(dest, src, n) strlcpy((dest), (src), (n))
#define memcmp_PF(s1, s2, n) memcmp((s1), (s2), (n))


#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
#if 0
#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))
#else
#define pgm_read_word(addr) ({ \
typeof(addr) _addr = (addr); \
*(const unsigned short *)(_addr); \
})
#define pgm_read_dword(addr) ({ \
typeof(addr) _addr = (addr); \
*(const unsigned long *)(_addr); \
})
#define pgm_read_float(addr) ({ \
typeof(addr) _addr = (addr); \
*(const float *)(_addr); \
})
#define pgm_read_ptr(addr) ({ \
typeof(addr) _addr = (addr); \
*(void * const *)(_addr); \
})
#endif


#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_ptr_near(addr) pgm_read_ptr(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)
#define pgm_read_ptr_far(addr) pgm_read_ptr(addr)

#endif

+ 26
- 0
cores/teensy3/avr/power.h View File

@@ -0,0 +1,26 @@
/* Simple compatibility headers for AVR code used with ARM chips
* Copyright (c) 2015 Paul Stoffregen <paul@pjrc.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 _AVR_POWER_H_
#define _AVR_POWER_H_ 1

#endif

+ 46
- 0
cores/teensy3/avr/sleep.h View File

@@ -0,0 +1,46 @@
/* Simple compatibility headers for AVR code used with ARM chips
* Copyright (c) 2015 Paul Stoffregen <paul@pjrc.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 _AVR_SLEEP_H_
#define _AVR_SLEEP_H_ 1

#define SLEEP_MODE_IDLE 0
#define SLEEP_MODE_ADC 0
#define SLEEP_MODE_PWR_DOWN 1
#define SLEEP_MODE_PWR_SAVE 1
#define SLEEP_MODE_STANDBY 1
#define SLEEP_MODE_EXT_STANDBY 1

#define set_sleep_mode(mode) // TODO: actually set the mode...
#define sleep_enable()
#define sleep_disable()
#define sleep_cpu() ({__asm__ volatile("wfi");})
#define sleep_bod_disable()
#define sleep_mode() ({__asm__ volatile("wfi");})

// workaround for early versions of Nordic's BLE library
// EIMSK moved to a dummy byte in avr_emulation...
//#if defined(HAL_ACI_TL_H__) && defined(PLATFORM_H__)
//#define EIMSK uint8_t EIMSKworkaround=0; EIMSKworkaround
//#endif

#endif

+ 0
- 0
cores/teensy3/avr/wdt.h View File


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save