Initial commit, version 1.17-rc1
This commit is contained in:
commit
5cecdee933
170 changed files with 59857 additions and 0 deletions
9
README.md
Normal file
9
README.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
Teensy 2.0 and 3.0 core libraries for Arduino.
|
||||
|
||||
The latest stable version of Teensy's core library is always available in the Teensyduino installer, at this page:
|
||||
|
||||
http://www.pjrc.com/teensy/td_download.html
|
||||
|
||||
|
||||
This github repository contains work-in-progress code, which may not be stable. It is not recommended for use in actual projects.
|
||||
|
||||
2
teensy/Arduino.h
Normal file
2
teensy/Arduino.h
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#include "WProgram.h"
|
||||
#include "pins_arduino.h"
|
||||
29
teensy/Client.h
Normal file
29
teensy/Client.h
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#if ARDUINO >= 100
|
||||
|
||||
#ifndef client_h
|
||||
#define client_h
|
||||
#include "Print.h"
|
||||
#include "Stream.h"
|
||||
#include "IPAddress.h"
|
||||
|
||||
class Client : public Stream {
|
||||
|
||||
public:
|
||||
virtual int connect(IPAddress ip, uint16_t port) =0;
|
||||
virtual int connect(const char *host, uint16_t port) =0;
|
||||
virtual size_t write(uint8_t) =0;
|
||||
virtual size_t write(const uint8_t *buf, size_t size) =0;
|
||||
virtual int available() = 0;
|
||||
virtual int read() = 0;
|
||||
virtual int read(uint8_t *buf, size_t size) = 0;
|
||||
virtual int peek() = 0;
|
||||
virtual void flush() = 0;
|
||||
virtual void stop() = 0;
|
||||
virtual uint8_t connected() = 0;
|
||||
virtual operator bool() = 0;
|
||||
protected:
|
||||
uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); };
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
195
teensy/HardwareSerial.cpp
Normal file
195
teensy/HardwareSerial.cpp
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
/* UART (hardware serial) for Teensy & Teensy++
|
||||
* http://www.pjrc.com/teensy/
|
||||
* Copyright (c) 2008 PJRC.COM, LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include "core_pins.h"
|
||||
#include "HardwareSerial.h"
|
||||
|
||||
#define RX_BUFFER_SIZE 64
|
||||
static volatile uint8_t rx_buffer[RX_BUFFER_SIZE];
|
||||
static volatile uint8_t rx_buffer_head = 0;
|
||||
static volatile uint8_t rx_buffer_tail = 0;
|
||||
|
||||
#define TX_BUFFER_SIZE 40
|
||||
static volatile uint8_t tx_buffer[TX_BUFFER_SIZE];
|
||||
static volatile uint8_t tx_buffer_head = 0;
|
||||
static volatile uint8_t tx_buffer_tail = 0;
|
||||
static volatile uint8_t transmitting = 0;
|
||||
static volatile uint8_t tx_enable_pin = 255;
|
||||
|
||||
// Public Methods //////////////////////////////////////////////////////////////
|
||||
|
||||
void HardwareSerial::_begin(uint16_t baud_count, uint8_t txen_pin)
|
||||
{
|
||||
tx_enable_pin = txen_pin;
|
||||
if (txen_pin < 255) {
|
||||
pinMode(txen_pin, OUTPUT);
|
||||
digitalWrite(txen_pin, LOW);
|
||||
}
|
||||
if ((baud_count & 1) && baud_count <= 4096) {
|
||||
UCSR1A = (1<<U2X1);
|
||||
UBRR1 = baud_count - 1;
|
||||
} else {
|
||||
UCSR1A = 0;
|
||||
UBRR1 = (baud_count >> 1) - 1;
|
||||
}
|
||||
if (!(UCSR1B & (1<<TXEN1))) {
|
||||
rx_buffer_head = 0;
|
||||
rx_buffer_tail = 0;
|
||||
tx_buffer_head = 0;
|
||||
tx_buffer_tail = 0;
|
||||
transmitting = 0;
|
||||
UCSR1C = (1<<UCSZ11) | (1<<UCSZ10);
|
||||
UCSR1B = (1<<RXEN1) | (1<<TXCIE1) | (1<<TXEN1) | (1<<RXCIE1);
|
||||
}
|
||||
}
|
||||
|
||||
void HardwareSerial::end(void)
|
||||
{
|
||||
while (transmitting) ; // wait for buffered data to send
|
||||
UCSR1B = 0;
|
||||
rx_buffer_head = 0;
|
||||
rx_buffer_tail = 0;
|
||||
}
|
||||
|
||||
int HardwareSerial::available(void)
|
||||
{
|
||||
uint8_t head, tail;
|
||||
|
||||
head = rx_buffer_head;
|
||||
tail = rx_buffer_tail;
|
||||
if (head >= tail) return head - tail;
|
||||
return RX_BUFFER_SIZE + head - tail;
|
||||
}
|
||||
|
||||
int HardwareSerial::peek(void)
|
||||
{
|
||||
uint8_t head, tail;
|
||||
|
||||
head = rx_buffer_head;
|
||||
tail = rx_buffer_tail;
|
||||
if (head == tail) return -1;
|
||||
if (++tail >= RX_BUFFER_SIZE) tail = 0;
|
||||
return rx_buffer[tail];
|
||||
}
|
||||
|
||||
int HardwareSerial::read(void)
|
||||
{
|
||||
uint8_t c, i;
|
||||
|
||||
if (rx_buffer_head == rx_buffer_tail) return -1;
|
||||
i = rx_buffer_tail + 1;
|
||||
if (i >= RX_BUFFER_SIZE) i = 0;
|
||||
c = rx_buffer[i];
|
||||
rx_buffer_tail = i;
|
||||
return c;
|
||||
}
|
||||
|
||||
void HardwareSerial::flush()
|
||||
{
|
||||
#if ARDUINO >= 100
|
||||
while (transmitting) ; // wait for buffered data to send
|
||||
#else
|
||||
rx_buffer_head = rx_buffer_tail;
|
||||
#endif
|
||||
}
|
||||
|
||||
void HardwareSerial::clear()
|
||||
{
|
||||
rx_buffer_head = rx_buffer_tail;
|
||||
}
|
||||
|
||||
#if ARDUINO >= 100
|
||||
size_t HardwareSerial::write(uint8_t c)
|
||||
#else
|
||||
void HardwareSerial::write(uint8_t c)
|
||||
#endif
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
if (!(UCSR1B & (1<<TXEN1))) {
|
||||
#if ARDUINO >= 100
|
||||
setWriteError();
|
||||
return 0;
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
if (tx_enable_pin < 255 && !transmitting) {
|
||||
digitalWrite(tx_enable_pin, HIGH);
|
||||
}
|
||||
i = tx_buffer_head + 1;
|
||||
if (i >= TX_BUFFER_SIZE) i = 0;
|
||||
while (tx_buffer_tail == i) ; // wait until space in buffer
|
||||
tx_buffer[i] = c;
|
||||
transmitting = 1;
|
||||
tx_buffer_head = i;
|
||||
UCSR1B = (1<<RXEN1) | (1<<TXCIE1) | (1<<TXEN1) | (1<<RXCIE1) | (1<<UDRIE1);
|
||||
#if ARDUINO >= 100
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
ISR(USART1_RX_vect)
|
||||
{
|
||||
uint8_t c, i;
|
||||
|
||||
c = UDR1;
|
||||
i = rx_buffer_head + 1;
|
||||
if (i >= RX_BUFFER_SIZE) i = 0;
|
||||
if (i != rx_buffer_tail) {
|
||||
rx_buffer[i] = c;
|
||||
rx_buffer_head = i;
|
||||
}
|
||||
}
|
||||
|
||||
ISR(USART1_UDRE_vect)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
if (tx_buffer_head == tx_buffer_tail) {
|
||||
// buffer is empty, disable transmit interrupt
|
||||
UCSR1B = (1<<RXEN1) | (1<<TXCIE1) | (1<<TXEN1) | (1<<RXCIE1);
|
||||
} else {
|
||||
i = tx_buffer_tail + 1;
|
||||
if (i >= TX_BUFFER_SIZE) i = 0;
|
||||
UDR1 = tx_buffer[i];
|
||||
tx_buffer_tail = i;
|
||||
}
|
||||
}
|
||||
|
||||
ISR(USART1_TX_vect)
|
||||
{
|
||||
transmitting = 0;
|
||||
if (tx_enable_pin < 255) {
|
||||
digitalWrite(tx_enable_pin, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
// Preinstantiate Objects //////////////////////////////////////////////////////
|
||||
|
||||
HardwareSerial Serial1;
|
||||
|
||||
|
||||
|
||||
30
teensy/HardwareSerial.h
Normal file
30
teensy/HardwareSerial.h
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef HardwareSerial_h
|
||||
#define HardwareSerial_h
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "Stream.h"
|
||||
|
||||
class HardwareSerial : public Stream
|
||||
{
|
||||
public:
|
||||
inline void begin(uint32_t baud, uint8_t txen_pin=255) {
|
||||
_begin(((F_CPU / 8) + (baud / 2)) / baud, txen_pin);
|
||||
}
|
||||
void _begin(uint16_t baud_count, uint8_t pin);
|
||||
void end(void);
|
||||
virtual int available(void);
|
||||
virtual int peek(void);
|
||||
virtual int read(void);
|
||||
virtual void flush(void);
|
||||
void clear(void);
|
||||
#if ARDUINO >= 100
|
||||
virtual size_t write(uint8_t);
|
||||
#else
|
||||
virtual void write(uint8_t);
|
||||
#endif
|
||||
using Print::write;
|
||||
};
|
||||
|
||||
extern HardwareSerial Serial1;
|
||||
|
||||
#endif
|
||||
57
teensy/IPAddress.cpp
Normal file
57
teensy/IPAddress.cpp
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
#if ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
#include "IPAddress.h"
|
||||
|
||||
IPAddress::IPAddress()
|
||||
{
|
||||
memset(_address, 0, sizeof(_address));
|
||||
}
|
||||
|
||||
IPAddress::IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet)
|
||||
{
|
||||
_address[0] = first_octet;
|
||||
_address[1] = second_octet;
|
||||
_address[2] = third_octet;
|
||||
_address[3] = fourth_octet;
|
||||
}
|
||||
|
||||
IPAddress::IPAddress(uint32_t address)
|
||||
{
|
||||
memcpy(_address, &address, sizeof(_address));
|
||||
}
|
||||
|
||||
IPAddress::IPAddress(const uint8_t *address)
|
||||
{
|
||||
memcpy(_address, address, sizeof(_address));
|
||||
}
|
||||
|
||||
IPAddress& IPAddress::operator=(const uint8_t *address)
|
||||
{
|
||||
memcpy(_address, address, sizeof(_address));
|
||||
return *this;
|
||||
}
|
||||
|
||||
IPAddress& IPAddress::operator=(uint32_t address)
|
||||
{
|
||||
memcpy(_address, (const uint8_t *)&address, sizeof(_address));
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool IPAddress::operator==(const uint8_t* addr)
|
||||
{
|
||||
return memcmp(addr, _address, sizeof(_address)) == 0;
|
||||
}
|
||||
|
||||
size_t IPAddress::printTo(Print& p) const
|
||||
{
|
||||
size_t n = 0;
|
||||
for (int i =0; i < 3; i++)
|
||||
{
|
||||
n += p.print(_address[i], DEC);
|
||||
n += p.print('.');
|
||||
}
|
||||
n += p.print(_address[3], DEC);
|
||||
return n;
|
||||
}
|
||||
|
||||
#endif
|
||||
78
teensy/IPAddress.h
Normal file
78
teensy/IPAddress.h
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
*
|
||||
* MIT License:
|
||||
* Copyright (c) 2011 Adrian McEwen
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* adrianm@mcqn.com 1/1/2011
|
||||
*/
|
||||
|
||||
#if ARDUINO >= 100
|
||||
#ifndef IPAddress_h
|
||||
#define IPAddress_h
|
||||
|
||||
#include <Printable.h>
|
||||
|
||||
// A class to make it easier to handle and pass around IP addresses
|
||||
|
||||
class IPAddress : public Printable {
|
||||
private:
|
||||
uint8_t _address[4]; // IPv4 address
|
||||
// Access the raw byte array containing the address. Because this returns a pointer
|
||||
// to the internal structure rather than a copy of the address this function should only
|
||||
// be used when you know that the usage of the returned uint8_t* will be transient and not
|
||||
// stored.
|
||||
uint8_t* raw_address() { return _address; };
|
||||
|
||||
public:
|
||||
// Constructors
|
||||
IPAddress();
|
||||
IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet);
|
||||
IPAddress(uint32_t address);
|
||||
IPAddress(const uint8_t *address);
|
||||
|
||||
// Overloaded cast operator to allow IPAddress objects to be used where a pointer
|
||||
// to a four-byte uint8_t array is expected
|
||||
operator uint32_t() { return *((uint32_t*)_address); };
|
||||
bool operator==(const IPAddress& addr) { return (*((uint32_t*)_address)) == (*((uint32_t*)addr._address)); };
|
||||
bool operator==(const uint8_t* addr);
|
||||
|
||||
// Overloaded index operator to allow getting and setting individual octets of the address
|
||||
uint8_t operator[](int index) const { return _address[index]; };
|
||||
uint8_t& operator[](int index) { return _address[index]; };
|
||||
|
||||
// Overloaded copy operators to allow initialisation of IPAddress objects from other types
|
||||
IPAddress& operator=(const uint8_t *address);
|
||||
IPAddress& operator=(uint32_t address);
|
||||
|
||||
virtual size_t printTo(Print& p) const;
|
||||
|
||||
friend class EthernetClass;
|
||||
friend class UDP;
|
||||
friend class Client;
|
||||
friend class Server;
|
||||
friend class DhcpClass;
|
||||
friend class DNSClient;
|
||||
};
|
||||
|
||||
const IPAddress INADDR_NONE(0,0,0,0);
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
484
teensy/Print.cpp
Normal file
484
teensy/Print.cpp
Normal file
|
|
@ -0,0 +1,484 @@
|
|||
/*
|
||||
Print.cpp - Base class that provides print() and println()
|
||||
Copyright (c) 2008 David A. Mellis. All right reserved.
|
||||
many modifications, by Paul Stoffregen <paul@pjrc.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Modified 23 November 2006 by David A. Mellis
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <math.h>
|
||||
#include <avr/pgmspace.h>
|
||||
#include "wiring.h"
|
||||
|
||||
#include "Print.h"
|
||||
|
||||
|
||||
#if ARDUINO >= 100
|
||||
#else
|
||||
void Print::write(const char *str)
|
||||
{
|
||||
write((const uint8_t *)str, strlen(str));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if ARDUINO >= 100
|
||||
size_t Print::write(const uint8_t *buffer, size_t size)
|
||||
{
|
||||
size_t count = 0;
|
||||
while (size--) count += write(*buffer++);
|
||||
return count;
|
||||
}
|
||||
#else
|
||||
void Print::write(const uint8_t *buffer, size_t size)
|
||||
{
|
||||
while (size--) write(*buffer++);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if ARDUINO >= 100
|
||||
size_t Print::print(const String &s)
|
||||
{
|
||||
uint8_t buffer[33];
|
||||
size_t count = 0;
|
||||
unsigned int index = 0;
|
||||
unsigned int len = s.length();
|
||||
while (len > 0) {
|
||||
s.getBytes(buffer, sizeof(buffer), index);
|
||||
unsigned int nbytes = len;
|
||||
if (nbytes > sizeof(buffer)-1) nbytes = sizeof(buffer)-1;
|
||||
index += nbytes;
|
||||
len -= nbytes;
|
||||
count += write(buffer, nbytes);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
#else
|
||||
void Print::print(const String &s)
|
||||
{
|
||||
unsigned int len = s.length();
|
||||
for (unsigned int i=0; i < len; i++) {
|
||||
write(s[i]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if ARDUINO >= 100
|
||||
size_t Print::print(const __FlashStringHelper *ifsh)
|
||||
{
|
||||
uint8_t buffer[32];
|
||||
size_t count = 0;
|
||||
const char PROGMEM *p = (const char PROGMEM *)ifsh;
|
||||
unsigned int len = strlen_P(p);
|
||||
while (len > 0) {
|
||||
unsigned int nbytes = len;
|
||||
if (nbytes > sizeof(buffer)) nbytes = sizeof(buffer);
|
||||
memcpy_P(buffer, p, nbytes);
|
||||
p += nbytes;
|
||||
len -= nbytes;
|
||||
count += write(buffer, nbytes);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
#else
|
||||
void Print::print(const __FlashStringHelper *ifsh)
|
||||
{
|
||||
const char PROGMEM *p = (const char PROGMEM *)ifsh;
|
||||
while (1) {
|
||||
unsigned char c = pgm_read_byte(p++);
|
||||
if (c == 0) return;
|
||||
write(c);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if ARDUINO >= 100
|
||||
size_t Print::print(long n)
|
||||
{
|
||||
uint8_t sign=0;
|
||||
|
||||
if (n < 0) {
|
||||
sign = 1;
|
||||
n = -n;
|
||||
}
|
||||
return printNumber(n, sign, 10);
|
||||
}
|
||||
#else
|
||||
void Print::print(long n)
|
||||
{
|
||||
uint8_t sign=0;
|
||||
|
||||
if (n < 0) {
|
||||
sign = 1;
|
||||
n = -n;
|
||||
}
|
||||
printNumber(n, sign, 10);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if ARDUINO >= 100
|
||||
size_t Print::println(void)
|
||||
{
|
||||
uint8_t buf[2]={'\r', '\n'};
|
||||
return write(buf, 2);
|
||||
}
|
||||
#else
|
||||
void Print::println(void)
|
||||
{
|
||||
uint8_t buf[2]={'\r', '\n'};
|
||||
write(buf, 2);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
//#define USE_HACKER_DELIGHT_OPTIMIZATION
|
||||
#define USE_STIMMER_OPTIMIZATION
|
||||
//#define USE_BENCHMARK_CODE
|
||||
|
||||
|
||||
#ifdef USE_HACKER_DELIGHT_OPTIMIZATION
|
||||
// Adapted from Hacker's Delight (Henry Warren, ISBN 0321842685) www.hackersdelight.org
|
||||
// by Rob Tillaart, Tom Carpenter, "genom2" with input from others...
|
||||
// http://forum.arduino.cc/index.php?topic=167414.0
|
||||
//
|
||||
#define divmod10_asm(in32, tmp32, mod8) \
|
||||
asm volatile ( \
|
||||
"mov %2, %A0 \n\t" /* mod = in */ \
|
||||
"ori %A0, 1 \n\t" /* q = in | 1 */ \
|
||||
"movw %A1, %A0 \n\t" /* x = q */ \
|
||||
"movw %C1, %C0 \n\t" \
|
||||
"lsr %D1 \n\t" /* x = x >> 2 */ \
|
||||
"ror %C1 \n\t" \
|
||||
"ror %B1 \n\t" \
|
||||
"ror %A1 \n\t" \
|
||||
"lsr %D1 \n\t" \
|
||||
"ror %C1 \n\t" \
|
||||
"ror %B1 \n\t" \
|
||||
"ror %A1 \n\t" \
|
||||
"sub %A0, %A1 \n\t" /* q = q - x */ \
|
||||
"sbc %B0, %B1 \n\t" \
|
||||
"sbc %C0, %C1 \n\t" \
|
||||
"sbc %D0, %D1 \n\t" \
|
||||
"movw %A1, %A0 \n\t" /* x = q */ \
|
||||
"movw %C1, %C0 \n\t" \
|
||||
"lsr %D1 \n\t" /* x = x >> 4 */ \
|
||||
"ror %C1 \n\t" \
|
||||
"ror %B1 \n\t" \
|
||||
"ror %A1 \n\t" \
|
||||
"lsr %D1 \n\t" \
|
||||
"ror %C1 \n\t" \
|
||||
"ror %B1 \n\t" \
|
||||
"ror %A1 \n\t" \
|
||||
"lsr %D1 \n\t" \
|
||||
"ror %C1 \n\t" \
|
||||
"ror %B1 \n\t" \
|
||||
"ror %A1 \n\t" \
|
||||
"lsr %D1 \n\t" \
|
||||
"ror %C1 \n\t" \
|
||||
"ror %B1 \n\t" \
|
||||
"ror %A1 \n\t" \
|
||||
"add %A1, %A0 \n\t" /* x = x + q */ \
|
||||
"adc %B1, %B0 \n\t" \
|
||||
"adc %C1, %C0 \n\t" \
|
||||
"adc %D1, %D0 \n\t" \
|
||||
"movw %A0, %A1 \n\t" /* q = x */ \
|
||||
"movw %C0, %C1 \n\t" \
|
||||
"add %A0, %B1 \n\t" /* q = q + (x >> 8) */ \
|
||||
"adc %B0, %C1 \n\t" \
|
||||
"adc %C0, %D1 \n\t" \
|
||||
"adc %D0, r1 \n\t" \
|
||||
"mov %A0, %B0 \n\t" /* q = q >> 8 */ \
|
||||
"mov %B0, %C0 \n\t" \
|
||||
"mov %C0, %D0 \n\t" \
|
||||
"eor %D0, %D0 \n\t" \
|
||||
"add %A0, %A1 \n\t" /* q = q + x */ \
|
||||
"adc %B0, %B1 \n\t" \
|
||||
"adc %C0, %C1 \n\t" \
|
||||
"adc %D0, %D1 \n\t" \
|
||||
"mov %A0, %B0 \n\t" /* q = q >> 8 */ \
|
||||
"mov %B0, %C0 \n\t" \
|
||||
"mov %C0, %D0 \n\t" \
|
||||
"eor %D0, %D0 \n\t" \
|
||||
"add %A0, %A1 \n\t" /* q = q + x */ \
|
||||
"adc %B0, %B1 \n\t" \
|
||||
"adc %C0, %C1 \n\t" \
|
||||
"adc %D0, %D1 \n\t" \
|
||||
"mov %A0, %B0 \n\t" /* q = q >> 8 */ \
|
||||
"mov %B0, %C0 \n\t" \
|
||||
"mov %C0, %D0 \n\t" \
|
||||
"eor %D0, %D0 \n\t" \
|
||||
"add %A0, %A1 \n\t" /* q = q + x */ \
|
||||
"adc %B0, %B1 \n\t" \
|
||||
"adc %C0, %C1 \n\t" \
|
||||
"adc %D0, %D1 \n\t" \
|
||||
"andi %A0, 0xF8 \n\t" /* q = q & ~0x7 */ \
|
||||
"sub %2, %A0 \n\t" /* mod = mod - q */ \
|
||||
"lsr %D0 \n\t" /* q = q >> 2 */ \
|
||||
"ror %C0 \n\t" \
|
||||
"ror %B0 \n\t" \
|
||||
"ror %A0 \n\t" \
|
||||
"lsr %D0 \n\t" \
|
||||
"ror %C0 \n\t" \
|
||||
"ror %B0 \n\t" \
|
||||
"ror %A0 \n\t" \
|
||||
"sub %2, %A0 \n\t" /* mod = mod - q */ \
|
||||
"lsr %D0 \n\t" /* q = q >> 1 */ \
|
||||
"ror %C0 \n\t" \
|
||||
"ror %B0 \n\t" \
|
||||
"ror %A0 \n\t" \
|
||||
: "+d" (in32), "=r" (tmp32), "=r" (mod8) : : "r0" \
|
||||
)
|
||||
#endif // USE_HACKER_DELIGHT_OPTIMIZATION
|
||||
|
||||
#ifdef USE_STIMMER_OPTIMIZATION
|
||||
// http://forum.arduino.cc/index.php?topic=167414.msg1293679#msg1293679
|
||||
// http://forum.arduino.cc/index.php?topic=167414.msg1309482#msg1309482
|
||||
// equivelant code:
|
||||
// mod8 = in32 % 10;
|
||||
// in32 = in32 / 10;
|
||||
// tmp8 = 10;
|
||||
#define divmod10_asm(in32, mod8, tmp8) \
|
||||
asm volatile ( \
|
||||
" ldi %2,51 \n\t" \
|
||||
" mul %A0,%2 \n\t" \
|
||||
" clr %A0 \n\t" \
|
||||
" add r0,%2 \n\t" \
|
||||
" adc %A0,r1 \n\t" \
|
||||
" mov %1,r0 \n\t" \
|
||||
" mul %B0,%2 \n\t" \
|
||||
" clr %B0 \n\t" \
|
||||
" add %A0,r0 \n\t" \
|
||||
" adc %B0,r1 \n\t" \
|
||||
" mul %C0,%2 \n\t" \
|
||||
" clr %C0 \n\t" \
|
||||
" add %B0,r0 \n\t" \
|
||||
" adc %C0,r1 \n\t" \
|
||||
" mul %D0,%2 \n\t" \
|
||||
" clr %D0 \n\t" \
|
||||
" add %C0,r0 \n\t" \
|
||||
" adc %D0,r1 \n\t" \
|
||||
" clr r1 \n\t" \
|
||||
" add %1,%A0 \n\t" \
|
||||
" adc %A0,%B0 \n\t" \
|
||||
" adc %B0,%C0 \n\t" \
|
||||
" adc %C0,%D0 \n\t" \
|
||||
" adc %D0,r1 \n\t" \
|
||||
" add %1,%B0 \n\t" \
|
||||
" adc %A0,%C0 \n\t" \
|
||||
" adc %B0,%D0 \n\t" \
|
||||
" adc %C0,r1 \n\t" \
|
||||
" adc %D0,r1 \n\t" \
|
||||
" add %1,%D0 \n\t" \
|
||||
" adc %A0,r1 \n\t" \
|
||||
" adc %B0,r1 \n\t" \
|
||||
" adc %C0,r1 \n\t" \
|
||||
" adc %D0,r1 \n\t" \
|
||||
" lsr %D0 \n\t" \
|
||||
" ror %C0 \n\t" \
|
||||
" ror %B0 \n\t" \
|
||||
" ror %A0 \n\t" \
|
||||
" ror %1 \n\t" \
|
||||
" ldi %2,10 \n\t" \
|
||||
" mul %1,%2 \n\t" \
|
||||
" mov %1,r1 \n\t" \
|
||||
" clr r1 \n\t" \
|
||||
:"+r"(in32),"=d"(mod8),"=d"(tmp8) : : "r0")
|
||||
#endif // USE_STIMMER_OPTIMIZATION
|
||||
|
||||
|
||||
|
||||
#ifdef USE_BENCHMARK_CODE
|
||||
uint32_t usec_print = 0;
|
||||
#endif
|
||||
|
||||
|
||||
#if ARDUINO >= 100
|
||||
size_t Print::printNumberDec(unsigned long n, uint8_t sign)
|
||||
#else
|
||||
void Print::printNumberDec(unsigned long n, uint8_t sign)
|
||||
#endif
|
||||
{
|
||||
uint8_t digit, buf[11], *p;
|
||||
#if defined(USE_HACKER_DELIGHT_OPTIMIZATION)
|
||||
uint32_t tmp32;
|
||||
#elif defined(USE_STIMMER_OPTIMIZATION)
|
||||
uint8_t tmp8;
|
||||
#endif
|
||||
|
||||
#ifdef USE_BENCHMARK_CODE
|
||||
uint32_t usec = micros();
|
||||
#endif
|
||||
p = buf + (sizeof(buf)-1);
|
||||
do {
|
||||
#if defined(USE_HACKER_DELIGHT_OPTIMIZATION)
|
||||
divmod10_asm(n, tmp32, digit);
|
||||
#elif defined(USE_STIMMER_OPTIMIZATION)
|
||||
divmod10_asm(n, digit, tmp8);
|
||||
#else
|
||||
tmp32 = n;
|
||||
n = n / 10;
|
||||
digit = tmp32 - n * 10;
|
||||
#endif
|
||||
*--p = digit + '0';
|
||||
} while (n);
|
||||
if (sign) *--p = '-';
|
||||
#ifdef USE_BENCHMARK_CODE
|
||||
usec_print += micros() - usec;
|
||||
#endif
|
||||
#if ARDUINO >= 100
|
||||
return write(p, sizeof(buf)-1 - (p - buf));
|
||||
#else
|
||||
write(p, sizeof(buf)-1 - (p - buf));
|
||||
#endif
|
||||
}
|
||||
|
||||
#if ARDUINO >= 100
|
||||
size_t Print::printNumberHex(unsigned long n)
|
||||
#else
|
||||
void Print::printNumberHex(unsigned long n)
|
||||
#endif
|
||||
{
|
||||
uint8_t digit, buf[8], *p;
|
||||
|
||||
p = buf + (sizeof(buf)-1);
|
||||
do {
|
||||
digit = n & 15;
|
||||
*--p = (digit < 10) ? '0' + digit : 'A' + digit - 10;
|
||||
n >>= 4;
|
||||
} while (n);
|
||||
#if ARDUINO >= 100
|
||||
return write(p, sizeof(buf)-1 - (p - buf));
|
||||
#else
|
||||
write(p, sizeof(buf)-1 - (p - buf));
|
||||
#endif
|
||||
}
|
||||
|
||||
#if ARDUINO >= 100
|
||||
size_t Print::printNumberBin(unsigned long n)
|
||||
#else
|
||||
void Print::printNumberBin(unsigned long n)
|
||||
#endif
|
||||
{
|
||||
uint8_t buf[32], *p;
|
||||
|
||||
p = buf + (sizeof(buf)-1);
|
||||
do {
|
||||
*--p = '0' + ((uint8_t)n & 1);
|
||||
n >>= 1;
|
||||
} while (n);
|
||||
#if ARDUINO >= 100
|
||||
return write(p, sizeof(buf)-1 - (p - buf));
|
||||
#else
|
||||
write(p, sizeof(buf)-1 - (p - buf));
|
||||
#endif
|
||||
}
|
||||
|
||||
#if ARDUINO >= 100
|
||||
size_t Print::printNumberAny(unsigned long n, uint8_t base)
|
||||
#else
|
||||
void Print::printNumberAny(unsigned long n, uint8_t base)
|
||||
#endif
|
||||
{
|
||||
uint8_t digit, buf[21], *p;
|
||||
uint32_t tmp;
|
||||
//uint32_t usec;
|
||||
|
||||
//usec = micros();
|
||||
p = buf + (sizeof(buf)-1);
|
||||
do {
|
||||
tmp = n;
|
||||
n = n / base;
|
||||
digit = tmp - n * base;
|
||||
*--p = (digit < 10) ? '0' + digit : 'A' + digit - 10;
|
||||
} while (n);
|
||||
//usec_print += micros() - usec;
|
||||
#if ARDUINO >= 100
|
||||
return write(p, sizeof(buf)-1 - (p - buf));
|
||||
#else
|
||||
write(p, sizeof(buf)-1 - (p - buf));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#if ARDUINO >= 100
|
||||
size_t Print::printFloat(double number, uint8_t digits)
|
||||
#else
|
||||
void Print::printFloat(double number, uint8_t digits)
|
||||
#endif
|
||||
{
|
||||
uint8_t sign=0;
|
||||
#if ARDUINO >= 100
|
||||
size_t count=0;
|
||||
#endif
|
||||
|
||||
// Handle negative numbers
|
||||
if (number < 0.0) {
|
||||
sign = 1;
|
||||
number = -number;
|
||||
}
|
||||
|
||||
// Round correctly so that print(1.999, 2) prints as "2.00"
|
||||
double rounding = 0.5;
|
||||
for (uint8_t i=0; i<digits; ++i) {
|
||||
rounding *= 0.1;
|
||||
}
|
||||
number += rounding;
|
||||
|
||||
// Extract the integer part of the number and print it
|
||||
unsigned long int_part = (unsigned long)number;
|
||||
double remainder = number - (double)int_part;
|
||||
#if ARDUINO >= 100
|
||||
count += printNumber(int_part, sign, 10);
|
||||
#else
|
||||
printNumber(int_part, sign, 10);
|
||||
#endif
|
||||
|
||||
// Print the decimal point, but only if there are digits beyond
|
||||
if (digits > 0) {
|
||||
uint8_t n, buf[8], count=1;
|
||||
buf[0] = '.';
|
||||
|
||||
// Extract digits from the remainder one at a time
|
||||
if (digits > sizeof(buf) - 1) digits = sizeof(buf) - 1;
|
||||
|
||||
while (digits-- > 0) {
|
||||
remainder *= 10.0;
|
||||
n = (uint8_t)(remainder);
|
||||
buf[count++] = '0' + n;
|
||||
remainder -= n;
|
||||
}
|
||||
#if ARDUINO >= 100
|
||||
count += write(buf, count);
|
||||
#else
|
||||
write(buf, count);
|
||||
#endif
|
||||
}
|
||||
#if ARDUINO >= 100
|
||||
return count;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
167
teensy/Print.h
Normal file
167
teensy/Print.h
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
Print.h - Base class that provides print() and println()
|
||||
Copyright (c) 2008 David A. Mellis. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef Print_h
|
||||
#define Print_h
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h> // for size_t
|
||||
#include "core_id.h"
|
||||
#include "WString.h"
|
||||
#include "Printable.h"
|
||||
|
||||
#define DEC 10
|
||||
#define HEX 16
|
||||
#define OCT 8
|
||||
#define BIN 2
|
||||
#define BYTE 0
|
||||
|
||||
class __FlashStringHelper;
|
||||
|
||||
#if ARDUINO >= 100
|
||||
class Print
|
||||
{
|
||||
public:
|
||||
Print() : write_error(0) {}
|
||||
virtual size_t write(uint8_t b);
|
||||
size_t write(const char *str) { return write((const uint8_t *)str, strlen(str)); }
|
||||
virtual size_t write(const uint8_t *buffer, size_t size);
|
||||
size_t print(const String &s);
|
||||
size_t print(char c) { return write((uint8_t)c); }
|
||||
size_t print(const char s[]) { return write(s); }
|
||||
size_t print(const __FlashStringHelper *f);
|
||||
|
||||
size_t print(uint8_t b) { return printNumber(b, 0, 10); }
|
||||
size_t print(int n) { return print((long)n); }
|
||||
size_t print(unsigned int n) { return printNumber(n, 0, 10); }
|
||||
size_t print(long n);
|
||||
size_t print(unsigned long n) { return printNumber(n, 0, 10); }
|
||||
|
||||
size_t print(unsigned char n, int base) { return printNumber(n, 0, base); }
|
||||
size_t print(int n, int base) { return (base == 10) ? print(n) : printNumber(n, 0, base); }
|
||||
size_t print(unsigned int n, int base) { return printNumber(n, 0, base); }
|
||||
size_t print(long n, int base) { return (base == 10) ? print(n) : printNumber(n, 0, base); }
|
||||
size_t print(unsigned long n, int base) { return printNumber(n, 0, base); }
|
||||
|
||||
size_t print(double n, int digits = 2) { return printFloat(n, digits); }
|
||||
size_t print(const Printable &obj) { return obj.printTo(*this); }
|
||||
size_t println(void);
|
||||
size_t println(const String &s) { return print(s) + println(); }
|
||||
size_t println(char c) { return print(c) + println(); }
|
||||
size_t println(const char s[]) { return print(s) + println(); }
|
||||
size_t println(const __FlashStringHelper *f) { return print(f) + println(); }
|
||||
|
||||
size_t println(uint8_t b) { return print(b) + println(); }
|
||||
size_t println(int n) { return print(n) + println(); }
|
||||
size_t println(unsigned int n) { return print(n) + println(); }
|
||||
size_t println(long n) { return print(n) + println(); }
|
||||
size_t println(unsigned long n) { return print(n) + println(); }
|
||||
|
||||
size_t println(unsigned char n, int base) { return print(n, base) + println(); }
|
||||
size_t println(int n, int base) { return print(n, base) + println(); }
|
||||
size_t println(unsigned int n, int base) { return print(n, base) + println(); }
|
||||
size_t println(long n, int base) { return print(n, base) + println(); }
|
||||
size_t println(unsigned long n, int base) { return print(n, base) + println(); }
|
||||
|
||||
size_t println(double n, int digits = 2) { return print(n, digits) + println(); }
|
||||
size_t println(const Printable &obj) { return obj.printTo(*this) + println(); }
|
||||
int getWriteError() { return write_error; }
|
||||
void clearWriteError() { setWriteError(0); }
|
||||
protected:
|
||||
void setWriteError(int err = 1) { write_error = err; }
|
||||
private:
|
||||
char write_error;
|
||||
size_t printNumberDec(unsigned long n, uint8_t sign);
|
||||
size_t printNumberHex(unsigned long n);
|
||||
size_t printNumberBin(unsigned long n);
|
||||
size_t printNumberAny(unsigned long n, uint8_t base);
|
||||
inline size_t printNumber(unsigned long n, uint8_t sign, uint8_t base) __attribute__((always_inline)) {
|
||||
// when "base" is a constant (pretty much always), the
|
||||
// compiler optimizes this to a single function call.
|
||||
if (base == 0) return write((uint8_t)n);
|
||||
if (base == 10 || base < 2) return printNumberDec(n, sign);
|
||||
//if (base == 10 || base < 2) return printNumberAny(n, 10); // testing only
|
||||
if (base == 16) return printNumberHex(n);
|
||||
if (base == 2) return printNumberBin(n);
|
||||
return printNumberAny(n, base);
|
||||
}
|
||||
size_t printFloat(double n, uint8_t digits);
|
||||
};
|
||||
|
||||
#else
|
||||
class Print
|
||||
{
|
||||
public:
|
||||
virtual void write(uint8_t);
|
||||
virtual void write(const char *str);
|
||||
virtual void write(const uint8_t *buffer, size_t size);
|
||||
void print(const String &s);
|
||||
void print(char c) { write((uint8_t)c); }
|
||||
void print(const char s[]) { write(s); }
|
||||
void print(const __FlashStringHelper *f);
|
||||
|
||||
void print(uint8_t b) { write(b); }
|
||||
void print(int n) { print((long)n); }
|
||||
void print(unsigned int n) { printNumber(n, 0, 10); }
|
||||
void print(long n);
|
||||
void print(unsigned long n) { printNumber(n, 0, 10); }
|
||||
|
||||
void print(unsigned char n, int base) { printNumber(n, 0, base); }
|
||||
void print(int n, int base) { (base == 10) ? print(n) : printNumber(n, 0, base); }
|
||||
void print(unsigned int n, int base) { printNumber(n, 0, base); }
|
||||
void print(long n, int base) { (base == 10) ? print(n) : printNumber(n, 0, base); }
|
||||
void print(unsigned long n, int base) { printNumber(n, 0, base); }
|
||||
|
||||
void print(double n, int digits = 2) { printFloat(n, digits); }
|
||||
void println(void);
|
||||
void println(const String &s) { print(s); println(); }
|
||||
void println(char c) { print(c); println(); }
|
||||
void println(const char s[]) { print(s); println(); }
|
||||
void println(const __FlashStringHelper *f) { print(f); println(); }
|
||||
void println(uint8_t b) { print(b); println(); }
|
||||
void println(int n) { print(n); println(); }
|
||||
void println(unsigned int n) { print(n); println(); }
|
||||
void println(long n) { print(n); println(); }
|
||||
void println(unsigned long n) { print(n); println(); }
|
||||
|
||||
void println(unsigned char n, int base) { print(n, base); println(); }
|
||||
void println(int n, int base) { print(n, base); println(); }
|
||||
void println(unsigned int n, int base) { print(n, base); println(); }
|
||||
void println(long n, int base) { print(n, base); println(); }
|
||||
void println(unsigned long n, int base) { print(n, base); println(); }
|
||||
|
||||
void println(double n, int digits = 2) { print(n, digits); println(); }
|
||||
private:
|
||||
void printNumberDec(unsigned long n, uint8_t sign);
|
||||
void printNumberHex(unsigned long n);
|
||||
void printNumberBin(unsigned long n);
|
||||
void printNumberAny(unsigned long n, uint8_t base);
|
||||
inline size_t printNumber(unsigned long n, uint8_t sign, uint8_t base) __attribute__((always_inline)) {
|
||||
if (base == 0) { write((uint8_t)n); return; }
|
||||
if (base == 10 || base < 2) { printNumberDec(n, sign); return; }
|
||||
if (base == 16) { printNumberHex(n); return; }
|
||||
if (base == 2) { printNumberBin(n); return; }
|
||||
printNumberAny(n, base);
|
||||
}
|
||||
void printFloat(double n, uint8_t digits);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
40
teensy/Printable.h
Normal file
40
teensy/Printable.h
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
Printable.h - Interface class that allows printing of complex types
|
||||
Copyright (c) 2011 Adrian McEwen. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#if ARDUINO >= 100
|
||||
#ifndef Printable_h
|
||||
#define Printable_h
|
||||
|
||||
#include "new.h"
|
||||
|
||||
class Print;
|
||||
|
||||
/** The Printable class provides a way for new classes to allow themselves to be printed.
|
||||
By deriving from Printable and implementing the printTo method, it will then be possible
|
||||
for users to print out instances of this class by passing them into the usual
|
||||
Print::print and Print::println methods.
|
||||
*/
|
||||
class Printable
|
||||
{
|
||||
public:
|
||||
virtual size_t printTo(Print& p) const = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
12
teensy/Server.h
Normal file
12
teensy/Server.h
Normal 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
teensy/Stream.cpp
Normal file
310
teensy/Stream.cpp
Normal file
|
|
@ -0,0 +1,310 @@
|
|||
/*
|
||||
Stream.cpp - adds parsing methods to Stream class
|
||||
Copyright (c) 2008 David A. Mellis. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Created July 2011
|
||||
parsing functions based on TextFinder library by Michael Margolis
|
||||
*/
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "Stream.h"
|
||||
|
||||
#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait
|
||||
#define NO_SKIP_CHAR 1 // a magic char not found in a valid ASCII numeric field
|
||||
|
||||
// private method to read stream with timeout
|
||||
int Stream::timedRead()
|
||||
{
|
||||
int c;
|
||||
unsigned long startMillis = millis();
|
||||
do {
|
||||
c = read();
|
||||
if (c >= 0) return c;
|
||||
} while(millis() - startMillis < _timeout);
|
||||
return -1; // -1 indicates timeout
|
||||
}
|
||||
|
||||
// private method to peek stream with timeout
|
||||
int Stream::timedPeek()
|
||||
{
|
||||
int c;
|
||||
unsigned long startMillis = millis();
|
||||
do {
|
||||
c = peek();
|
||||
if (c >= 0) return c;
|
||||
} while(millis() - startMillis < _timeout);
|
||||
return -1; // -1 indicates timeout
|
||||
}
|
||||
|
||||
// returns peek of the next digit in the stream or -1 if timeout
|
||||
// discards non-numeric characters
|
||||
int Stream::peekNextDigit()
|
||||
{
|
||||
int c;
|
||||
while (1) {
|
||||
c = timedPeek();
|
||||
if (c < 0) return c; // timeout
|
||||
if (c == '-') return c;
|
||||
if (c >= '0' && c <= '9') return c;
|
||||
read(); // discard non-numeric
|
||||
}
|
||||
}
|
||||
|
||||
// Public Methods
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait
|
||||
{
|
||||
_timeout = timeout;
|
||||
}
|
||||
|
||||
// find returns true if the target string is found
|
||||
bool Stream::find(char *target)
|
||||
{
|
||||
return findUntil(target, NULL);
|
||||
}
|
||||
|
||||
// reads data from the stream until the target string of given length is found
|
||||
// returns true if target string is found, false if timed out
|
||||
bool Stream::find(char *target, size_t length)
|
||||
{
|
||||
return findUntil(target, length, NULL, 0);
|
||||
}
|
||||
|
||||
// as find but search ends if the terminator string is found
|
||||
bool Stream::findUntil(char *target, char *terminator)
|
||||
{
|
||||
return findUntil(target, strlen(target), terminator, strlen(terminator));
|
||||
}
|
||||
|
||||
// reads data from the stream until the target string of the given length is found
|
||||
// search terminated if the terminator string is found
|
||||
// returns true if target string is found, false if terminated or timed out
|
||||
bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen)
|
||||
{
|
||||
size_t index = 0; // maximum target string length is 64k bytes!
|
||||
size_t termIndex = 0;
|
||||
int c;
|
||||
|
||||
if( *target == 0)
|
||||
return true; // return true if target is a null string
|
||||
while( (c = timedRead()) > 0){
|
||||
if( c == target[index]){
|
||||
//////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1);
|
||||
if(++index >= targetLen){ // return true if all chars in the target match
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else{
|
||||
index = 0; // reset index if any char does not match
|
||||
}
|
||||
if(termLen > 0 && c == terminator[termIndex]){
|
||||
if(++termIndex >= termLen)
|
||||
return false; // return false if terminate string found before target string
|
||||
}
|
||||
else
|
||||
termIndex = 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// returns the first valid (long) integer value from the current position.
|
||||
// initial characters that are not digits (or the minus sign) are skipped
|
||||
// function is terminated by the first character that is not a digit.
|
||||
long Stream::parseInt()
|
||||
{
|
||||
return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout)
|
||||
}
|
||||
|
||||
// as above but a given skipChar is ignored
|
||||
// this allows format characters (typically commas) in values to be ignored
|
||||
long Stream::parseInt(char skipChar)
|
||||
{
|
||||
boolean isNegative = false;
|
||||
long value = 0;
|
||||
int c;
|
||||
|
||||
c = peekNextDigit();
|
||||
// ignore non numeric leading characters
|
||||
if(c < 0)
|
||||
return 0; // zero returned if timeout
|
||||
|
||||
do{
|
||||
if(c == skipChar)
|
||||
; // ignore this charactor
|
||||
else if(c == '-')
|
||||
isNegative = true;
|
||||
else if(c >= '0' && c <= '9') // is c a digit?
|
||||
value = value * 10 + c - '0';
|
||||
read(); // consume the character we got with peek
|
||||
c = timedPeek();
|
||||
}
|
||||
while( (c >= '0' && c <= '9') || c == skipChar );
|
||||
|
||||
if(isNegative)
|
||||
value = -value;
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
// as parseInt but returns a floating point value
|
||||
float Stream::parseFloat()
|
||||
{
|
||||
return parseFloat(NO_SKIP_CHAR);
|
||||
}
|
||||
|
||||
// as above but the given skipChar is ignored
|
||||
// this allows format characters (typically commas) in values to be ignored
|
||||
float Stream::parseFloat(char skipChar){
|
||||
boolean isNegative = false;
|
||||
boolean isFraction = false;
|
||||
long value = 0;
|
||||
char c;
|
||||
float fraction = 1.0;
|
||||
|
||||
c = peekNextDigit();
|
||||
// ignore non numeric leading characters
|
||||
if(c < 0)
|
||||
return 0; // zero returned if timeout
|
||||
|
||||
do{
|
||||
if(c == skipChar)
|
||||
; // ignore
|
||||
else if(c == '-')
|
||||
isNegative = true;
|
||||
else if (c == '.')
|
||||
isFraction = true;
|
||||
else if(c >= '0' && c <= '9') { // is c a digit?
|
||||
value = value * 10 + c - '0';
|
||||
if(isFraction)
|
||||
fraction *= 0.1;
|
||||
}
|
||||
read(); // consume the character we got with peek
|
||||
c = timedPeek();
|
||||
}
|
||||
while( (c >= '0' && c <= '9') || c == '.' || c == skipChar );
|
||||
|
||||
if(isNegative)
|
||||
value = -value;
|
||||
if(isFraction)
|
||||
return value * fraction;
|
||||
else
|
||||
return value;
|
||||
}
|
||||
|
||||
// read characters from stream into buffer
|
||||
// terminates if length characters have been read, or timeout (see setTimeout)
|
||||
// returns the number of characters placed in the buffer
|
||||
// the buffer is NOT null terminated.
|
||||
//
|
||||
size_t Stream::readBytes(char *buffer, size_t length)
|
||||
{
|
||||
size_t count = 0;
|
||||
while (count < length) {
|
||||
int c = timedRead();
|
||||
if (c < 0) {
|
||||
setReadError();
|
||||
break;
|
||||
}
|
||||
*buffer++ = (char)c;
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
// as readBytes with terminator character
|
||||
// terminates if length characters have been read, timeout, or if the terminator character detected
|
||||
// returns the number of characters placed in the buffer (0 means no valid data found)
|
||||
|
||||
size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length)
|
||||
{
|
||||
if (length < 1) return 0;
|
||||
length--;
|
||||
size_t index = 0;
|
||||
while (index < length) {
|
||||
int c = timedRead();
|
||||
if (c == terminator) break;
|
||||
if (c < 0) {
|
||||
setReadError();
|
||||
break;
|
||||
}
|
||||
*buffer++ = (char)c;
|
||||
index++;
|
||||
}
|
||||
*buffer = 0;
|
||||
return index; // return number of characters, not including null terminator
|
||||
}
|
||||
|
||||
String Stream::readString(size_t max)
|
||||
{
|
||||
String str;
|
||||
size_t length = str.length();
|
||||
while (length < max) {
|
||||
int c = timedRead();
|
||||
if (c < 0) {
|
||||
setReadError();
|
||||
break; // timeout
|
||||
}
|
||||
if (c == 0) break;
|
||||
str += (char)c;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
String Stream::readStringUntil(char terminator, size_t max)
|
||||
{
|
||||
String str;
|
||||
size_t length = str.length();
|
||||
while (length < max) {
|
||||
int c = timedRead();
|
||||
if (c < 0) {
|
||||
setReadError();
|
||||
break; // timeout
|
||||
}
|
||||
if (c == 0 || c == terminator) break;
|
||||
str += (char)c;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
60
teensy/Stream.h
Normal file
60
teensy/Stream.h
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
Stream.h - base class for character-based streams.
|
||||
Copyright (c) 2010 David A. Mellis. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef Stream_h
|
||||
#define Stream_h
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "Print.h"
|
||||
|
||||
class Stream : public Print
|
||||
{
|
||||
public:
|
||||
Stream() : _timeout(1000), read_error(0) {}
|
||||
virtual int available() = 0;
|
||||
virtual int read() = 0;
|
||||
virtual int peek() = 0;
|
||||
virtual void flush() = 0;
|
||||
|
||||
void setTimeout(unsigned long timeout);
|
||||
bool find(char *target);
|
||||
bool find(char *target, size_t length);
|
||||
bool findUntil(char *target, char *terminator);
|
||||
bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen);
|
||||
long parseInt();
|
||||
long parseInt(char skipChar);
|
||||
float parseFloat();
|
||||
float parseFloat(char skipChar);
|
||||
size_t readBytes(char *buffer, size_t length);
|
||||
size_t readBytesUntil(char terminator, char *buffer, size_t length);
|
||||
String readString(size_t max = 120);
|
||||
String readStringUntil(char terminator, size_t max = 120);
|
||||
int getReadError() { return read_error; }
|
||||
void clearReadError() { setReadError(0); }
|
||||
protected:
|
||||
void setReadError(int err = 1) { read_error = err; }
|
||||
unsigned long _timeout;
|
||||
private:
|
||||
char read_error;
|
||||
int timedRead();
|
||||
int timedPeek();
|
||||
int peekNextDigit();
|
||||
};
|
||||
|
||||
#endif
|
||||
269
teensy/Tone.cpp
Normal file
269
teensy/Tone.cpp
Normal file
|
|
@ -0,0 +1,269 @@
|
|||
/* Tone generation for the Teensy and Teensy++
|
||||
* http://www.pjrc.com/teensy/
|
||||
* Copyright (c) 2010 PJRC.COM, LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <avr/interrupt.h>
|
||||
#include "wiring.h"
|
||||
#include "core_pins.h"
|
||||
#include "pins_arduino.h"
|
||||
|
||||
static uint8_t timer_acquired = 0;
|
||||
|
||||
static uint8_t *tone1_reg = (uint8_t *)0;
|
||||
static uint8_t tone1_mask = 0;
|
||||
static uint16_t tone1_inc = 0;
|
||||
static uint32_t tone1_count = 0;
|
||||
|
||||
static uint8_t *tone2_reg = (uint8_t *)0;
|
||||
static uint8_t tone2_mask = 0;
|
||||
static uint16_t tone2_inc = 0;
|
||||
static uint32_t tone2_count = 0;
|
||||
|
||||
static uint8_t *tone3_reg = (uint8_t *)0;
|
||||
static uint8_t tone3_mask = 0;
|
||||
static uint16_t tone3_inc = 0;
|
||||
static uint32_t tone3_count = 0;
|
||||
|
||||
#define MAX_FREQ (F_CPU / 16 / 25)
|
||||
#define MIN_FREQ (F_CPU / 16 / 65535 + 1)
|
||||
|
||||
|
||||
|
||||
#define PIN_REG_AND_MASK_LOOKUP(pin, reg, mask) \
|
||||
asm volatile( \
|
||||
"lsl %2" "\n\t" \
|
||||
"add %A3, %2" "\n\t" \
|
||||
"adc %B3, __zero_reg__" "\n\n" \
|
||||
"lpm %1, Z+" "\n\t" \
|
||||
"lpm %A0, Z" "\n\t" \
|
||||
"ldi %B0, 0" "\n" \
|
||||
: "=z" (reg), "=r" (mask), "+r" (pin) \
|
||||
: "z" (digital_pin_table_PGM), "2" (pin))
|
||||
|
||||
#if defined(__AVR_ATmega32U4__)
|
||||
//#define TONE_USE_TIMER1
|
||||
#define TONE_USE_TIMER3
|
||||
#elif defined(__AVR_AT90USB1286__)
|
||||
//#define TONE_USE_TIMER1
|
||||
#define TONE_USE_TIMER3
|
||||
#elif defined(__AVR_AT90USB162__)
|
||||
#define TONE_USE_TIMER1
|
||||
#elif defined(__AVR_AT90USB646__)
|
||||
//#define TONE_USE_TIMER1
|
||||
#define TONE_USE_TIMER3
|
||||
#endif
|
||||
|
||||
#ifdef TONE_USE_TIMER3
|
||||
#define TIMSKx TIMSK3
|
||||
#define OCIExA OCIE3A
|
||||
#define OCIExB OCIE3B
|
||||
#define OCIExC OCIE3C
|
||||
#define TCCRxA TCCR3A
|
||||
#define WGMx0 WGM30
|
||||
#define TCCRxB TCCR3B
|
||||
#define CSx1 CS31
|
||||
#define TCNTx TCNT3
|
||||
#define OCRxA OCR3A
|
||||
#define OCRxB OCR3B
|
||||
#define OCRxC OCR3C
|
||||
#define TIFRx TIFR3
|
||||
#define OCFxA OCF3A
|
||||
#define OCFxB OCF3B
|
||||
#define OCFxC OCF3C
|
||||
#define VECTxA TIMER3_COMPA_vect
|
||||
#define VECTxB TIMER3_COMPB_vect
|
||||
#define VECTxC TIMER3_COMPC_vect
|
||||
#endif
|
||||
#ifdef TONE_USE_TIMER1
|
||||
#define TIMSKx TIMSK1
|
||||
#define OCIExA OCIE1A
|
||||
#define OCIExB OCIE1B
|
||||
#define OCIExC OCIE1C
|
||||
#define TCCRxA TCCR1A
|
||||
#define WGMx0 WGM10
|
||||
#define TCCRxB TCCR1B
|
||||
#define CSx1 CS11
|
||||
#define TCNTx TCNT1
|
||||
#define OCRxA OCR1A
|
||||
#define OCRxB OCR1B
|
||||
#define OCRxC OCR1C
|
||||
#define TIFRx TIFR1
|
||||
#define OCFxA OCF1A
|
||||
#define OCFxB OCF1B
|
||||
#define OCFxC OCF1C
|
||||
#define VECTxA TIMER1_COMPA_vect
|
||||
#define VECTxB TIMER1_COMPB_vect
|
||||
#define VECTxC TIMER1_COMPC_vect
|
||||
#endif
|
||||
|
||||
|
||||
void tone(uint8_t pin, uint16_t frequency, uint32_t duration)
|
||||
{
|
||||
uint8_t *reg;
|
||||
uint8_t mask;
|
||||
uint16_t inc;
|
||||
uint32_t count;
|
||||
|
||||
if (pin >= CORE_NUM_TOTAL_PINS) return;
|
||||
if (frequency < MIN_FREQ) {
|
||||
frequency = MIN_FREQ;
|
||||
} else if (frequency > MAX_FREQ) {
|
||||
frequency = MAX_FREQ;
|
||||
}
|
||||
inc = (F_CPU / 16 + frequency / 2) / frequency;
|
||||
if (duration) {
|
||||
count = duration * frequency / 500;
|
||||
} else {
|
||||
count = 0;
|
||||
}
|
||||
if (!timer_acquired) {
|
||||
TIMSKx = 0; // disable all interrupts
|
||||
TCCRxA = 0;
|
||||
TCCRxB = (1<<CSx1); // normal mode, div8 prescale
|
||||
timer_acquired = 1;
|
||||
}
|
||||
PIN_REG_AND_MASK_LOOKUP(pin, reg, mask);
|
||||
|
||||
if (!tone1_mask || (tone1_mask == mask && tone1_reg == reg)) {
|
||||
TIMSKx &= ~(1<<OCIExA); // disable compare interrupt
|
||||
tone1_reg = reg;
|
||||
tone1_mask = mask;
|
||||
tone1_count = count;
|
||||
tone1_inc = inc;
|
||||
cli();
|
||||
*(reg + 2) &= ~mask; // clear pin
|
||||
*(reg + 1) |= mask; // output mode
|
||||
OCRxA = TCNTx + inc;
|
||||
TIFRx |= (1<<OCFxA); // clear any pending compare match
|
||||
sei();
|
||||
TIMSKx |= (1<<OCIExA); // enable compare interrupt
|
||||
return;
|
||||
}
|
||||
if (!tone2_mask || (tone2_mask == mask && tone2_reg == reg)) {
|
||||
TIMSKx &= ~(1<<OCIExB); // disable compare interrupt
|
||||
tone2_reg = reg;
|
||||
tone2_mask = mask;
|
||||
tone2_count = count;
|
||||
tone2_inc = inc;
|
||||
cli();
|
||||
*(reg + 2) &= ~mask; // clear pin
|
||||
*(reg + 1) |= mask; // output mode
|
||||
OCRxB = TCNTx + inc;
|
||||
TIFRx |= (1<<OCFxB); // clear any pending compare match
|
||||
sei();
|
||||
TIMSKx |= (1<<OCIExB); // enable compare interrupt
|
||||
return;
|
||||
}
|
||||
if (!tone3_mask || (tone3_mask == mask && tone3_reg == reg)) {
|
||||
TIMSKx &= ~(1<<OCIExC); // disable compare interrupt
|
||||
tone3_reg = reg;
|
||||
tone3_mask = mask;
|
||||
tone3_count = count;
|
||||
tone3_inc = inc;
|
||||
cli();
|
||||
*(reg + 2) &= ~mask; // clear pin
|
||||
*(reg + 1) |= mask; // output mode
|
||||
OCRxC = TCNTx + inc;
|
||||
TIFRx |= (1<<OCFxC); // clear any pending compare match
|
||||
sei();
|
||||
TIMSKx |= (1<<OCIExC); // enable compare interrupt
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void noTone(uint8_t pin)
|
||||
{
|
||||
uint8_t *reg;
|
||||
uint8_t mask;
|
||||
|
||||
if (pin >= CORE_NUM_TOTAL_PINS) return;
|
||||
PIN_REG_AND_MASK_LOOKUP(pin, reg, mask);
|
||||
|
||||
if (tone1_mask == mask && tone1_reg == reg) {
|
||||
TIMSKx &= ~(1<<OCIExA);
|
||||
tone1_mask = 0;
|
||||
} else if (tone2_mask == mask && tone2_reg == reg) {
|
||||
TIMSKx &= ~(1<<OCIExB);
|
||||
tone2_mask = 0;
|
||||
} else if (tone3_mask == mask && tone3_reg == reg) {
|
||||
TIMSKx &= ~(1<<OCIExC);
|
||||
tone3_mask = 0;
|
||||
}
|
||||
if (!tone1_mask && !tone2_mask && !tone3_mask) {
|
||||
TCCRxA = (1<<WGMx0); // restore timer
|
||||
timer_acquired = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ISR(VECTxA)
|
||||
{
|
||||
OCRxA += tone1_inc;
|
||||
*(tone1_reg) = tone1_mask;
|
||||
if (tone1_count > 0) {
|
||||
if ((--tone1_count) == 0) {
|
||||
*(tone1_reg + 2) &= ~tone1_mask;
|
||||
TIMSKx &= ~(1<<OCIExA);
|
||||
tone1_mask = 0;
|
||||
if (!tone2_mask && !tone3_mask) {
|
||||
TCCRxA = (1<<WGMx0);
|
||||
timer_acquired = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ISR(VECTxB)
|
||||
{
|
||||
OCRxB += tone2_inc;
|
||||
*(tone2_reg) = tone2_mask;
|
||||
if (tone2_count > 0) {
|
||||
if ((--tone2_count) == 0) {
|
||||
*(tone2_reg + 2) &= ~tone2_mask;
|
||||
TIMSKx &= ~(1<<OCIExB);
|
||||
tone2_mask = 0;
|
||||
if (!tone1_mask && !tone3_mask) {
|
||||
TCCRxA = (1<<WGMx0);
|
||||
timer_acquired = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ISR(VECTxC)
|
||||
{
|
||||
OCRxC += tone3_inc;
|
||||
*(tone3_reg) = tone3_mask;
|
||||
if (tone3_count > 0) {
|
||||
if ((--tone3_count) == 0) {
|
||||
*(tone3_reg + 2) &= ~tone3_mask;
|
||||
TIMSKx &= ~(1<<OCIExC);
|
||||
tone3_mask = 0;
|
||||
if (!tone1_mask && !tone2_mask) {
|
||||
TCCRxA = (1<<WGMx0);
|
||||
timer_acquired = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
91
teensy/Udp.h
Normal file
91
teensy/Udp.h
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Udp.cpp: Library to send/receive UDP packets.
|
||||
*
|
||||
* NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these)
|
||||
* 1) UDP does not guarantee the order in which assembled UDP packets are received. This
|
||||
* might not happen often in practice, but in larger network topologies, a UDP
|
||||
* packet can be received out of sequence.
|
||||
* 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being
|
||||
* aware of it. Again, this may not be a concern in practice on small local networks.
|
||||
* For more information, see http://www.cafeaulait.org/course/week12/35.html
|
||||
*
|
||||
* MIT License:
|
||||
* Copyright (c) 2008 Bjoern Hartmann
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* bjoern@cs.stanford.edu 12/30/2008
|
||||
*/
|
||||
|
||||
#if ARDUINO >= 100
|
||||
|
||||
#ifndef udp_h
|
||||
#define udp_h
|
||||
|
||||
#include <Stream.h>
|
||||
#include <IPAddress.h>
|
||||
|
||||
class UDP : public Stream {
|
||||
|
||||
public:
|
||||
virtual uint8_t begin(uint16_t) =0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
|
||||
virtual void stop() =0; // Finish with the UDP socket
|
||||
|
||||
// Sending UDP packets
|
||||
|
||||
// Start building up a packet to send to the remote host specific in ip and port
|
||||
// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
|
||||
virtual int beginPacket(IPAddress ip, uint16_t port) =0;
|
||||
// Start building up a packet to send to the remote host specific in host and port
|
||||
// Returns 1 if successful, 0 if there was a problem resolving the hostname or port
|
||||
virtual int beginPacket(const char *host, uint16_t port) =0;
|
||||
// Finish off this packet and send it
|
||||
// Returns 1 if the packet was sent successfully, 0 if there was an error
|
||||
virtual int endPacket() =0;
|
||||
// Write a single byte into the packet
|
||||
virtual size_t write(uint8_t) =0;
|
||||
// Write size bytes from buffer into the packet
|
||||
virtual size_t write(const uint8_t *buffer, size_t size) =0;
|
||||
|
||||
// Start processing the next available incoming packet
|
||||
// Returns the size of the packet in bytes, or 0 if no packets are available
|
||||
virtual int parsePacket() =0;
|
||||
// Number of bytes remaining in the current packet
|
||||
virtual int available() =0;
|
||||
// Read a single byte from the current packet
|
||||
virtual int read() =0;
|
||||
// Read up to len bytes from the current packet and place them into buffer
|
||||
// Returns the number of bytes read, or 0 if none are available
|
||||
virtual int read(unsigned char* buffer, size_t len) =0;
|
||||
// Read up to len characters from the current packet and place them into buffer
|
||||
// Returns the number of characters read, or 0 if none are available
|
||||
virtual int read(char* buffer, size_t len) =0;
|
||||
// Return the next byte from the current packet without moving on to the next byte
|
||||
virtual int peek() =0;
|
||||
virtual void flush() =0; // Finish reading the current packet
|
||||
|
||||
// Return the IP address of the host who sent the current incoming packet
|
||||
virtual IPAddress remoteIP() =0;
|
||||
// Return the port of the host who sent the current incoming packet
|
||||
virtual uint16_t remotePort() =0;
|
||||
protected:
|
||||
uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); };
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
168
teensy/WCharacter.h
Normal file
168
teensy/WCharacter.h
Normal 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
teensy/WConstants.h
Normal file
1
teensy/WConstants.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
#include "wiring.h"
|
||||
132
teensy/WInterrupts.c
Normal file
132
teensy/WInterrupts.c
Normal 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
teensy/WMath.cpp
Normal file
60
teensy/WMath.cpp
Normal 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
teensy/WProgram.h
Normal file
48
teensy/WProgram.h
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
#ifndef WProgram_h
|
||||
#define WProgram_h
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifdef GCC_VERSION
|
||||
#if (GCC_VERSION < 40300)
|
||||
#warning "Your avr-gcc and avr-libc are too old, please upgrade"
|
||||
#endif
|
||||
#if (GCC_VERSION >= 40300) && (GCC_VERSION < 40302)
|
||||
// gcc 4.3.0 fails to save context for some interrupt routines - very ugly
|
||||
#warning "Buggy GCC 4.3.0 compiler, please upgrade!"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <avr/interrupt.h>
|
||||
#include "wiring.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#include "usb_api.h"
|
||||
#include "WCharacter.h"
|
||||
#include "WString.h"
|
||||
#include "HardwareSerial.h"
|
||||
#include "elapsedMillis.h"
|
||||
|
||||
uint16_t makeWord(uint16_t w);
|
||||
uint16_t makeWord(byte h, byte l);
|
||||
|
||||
#define word(...) makeWord(__VA_ARGS__)
|
||||
|
||||
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
|
||||
|
||||
void tone(uint8_t pin, uint16_t frequency, uint32_t duration = 0);
|
||||
void noTone(uint8_t pin);
|
||||
|
||||
// WMath prototypes
|
||||
long random(long);
|
||||
long random(long, long);
|
||||
void randomSeed(unsigned int);
|
||||
long map(long, long, long, long, long);
|
||||
|
||||
#include "pins_arduino.h"
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // WProgram_h
|
||||
759
teensy/WString.cpp
Normal file
759
teensy/WString.cpp
Normal file
|
|
@ -0,0 +1,759 @@
|
|||
/*
|
||||
WString.cpp - String library for Wiring & Arduino
|
||||
...mostly rewritten by Paul Stoffregen...
|
||||
Copyright (c) 2009-10 Hernando Barragan. All rights reserved.
|
||||
Copyright 2011, Paul Stoffregen, paul@pjrc.com
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "WString.h"
|
||||
|
||||
|
||||
/*********************************************/
|
||||
/* Constructors */
|
||||
/*********************************************/
|
||||
|
||||
String::String(const char *cstr)
|
||||
{
|
||||
init();
|
||||
if (cstr) copy(cstr, strlen(cstr));
|
||||
}
|
||||
|
||||
String::String(const __FlashStringHelper *pgmstr)
|
||||
{
|
||||
init();
|
||||
*this = pgmstr;
|
||||
}
|
||||
|
||||
String::String(const String &value)
|
||||
{
|
||||
init();
|
||||
*this = value;
|
||||
}
|
||||
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
String::String(String &&rval)
|
||||
{
|
||||
init();
|
||||
move(rval);
|
||||
}
|
||||
String::String(StringSumHelper &&rval)
|
||||
{
|
||||
init();
|
||||
move(rval);
|
||||
}
|
||||
#endif
|
||||
|
||||
String::String(char c)
|
||||
{
|
||||
init();
|
||||
*this = c;
|
||||
}
|
||||
|
||||
String::String(unsigned char c)
|
||||
{
|
||||
init();
|
||||
*this = (char)c;
|
||||
}
|
||||
|
||||
String::String(const int value, unsigned char base)
|
||||
{
|
||||
init();
|
||||
char buf[18];
|
||||
itoa(value, buf, base);
|
||||
*this = buf;
|
||||
}
|
||||
|
||||
String::String(unsigned int value, unsigned char base)
|
||||
{
|
||||
init();
|
||||
char buf[17];
|
||||
utoa(value, buf, base);
|
||||
*this = buf;
|
||||
}
|
||||
|
||||
String::String(long value, unsigned char base)
|
||||
{
|
||||
init();
|
||||
char buf[34];
|
||||
ltoa(value, buf, base);
|
||||
*this = buf;
|
||||
}
|
||||
|
||||
String::String(unsigned long value, unsigned char base)
|
||||
{
|
||||
init();
|
||||
char buf[33];
|
||||
ultoa(value, buf, base);
|
||||
*this = buf;
|
||||
}
|
||||
|
||||
String::String(float num, unsigned char digits)
|
||||
{
|
||||
init();
|
||||
char buf[40];
|
||||
*this = dtostrf(num, digits + 2, digits, buf);
|
||||
}
|
||||
|
||||
String::String(double num, unsigned char digits)
|
||||
{
|
||||
init();
|
||||
char buf[40];
|
||||
*this = dtostrf(num, digits + 2, digits, buf);
|
||||
}
|
||||
|
||||
String::~String()
|
||||
{
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
/* Memory Management */
|
||||
/*********************************************/
|
||||
|
||||
inline void String::init(void)
|
||||
{
|
||||
buffer = NULL;
|
||||
capacity = 0;
|
||||
len = 0;
|
||||
flags = 0;
|
||||
}
|
||||
|
||||
unsigned char String::reserve(unsigned int size)
|
||||
{
|
||||
if (capacity >= size) return 1;
|
||||
if (changeBuffer(size)) {
|
||||
if (len == 0) buffer[0] = 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned char String::changeBuffer(unsigned int maxStrLen)
|
||||
{
|
||||
char *newbuffer = (char *)realloc(buffer, maxStrLen + 1);
|
||||
if (newbuffer) {
|
||||
buffer = newbuffer;
|
||||
capacity = maxStrLen;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
/* Copy and Move */
|
||||
/*********************************************/
|
||||
|
||||
String & String::copy(const char *cstr, unsigned int length)
|
||||
{
|
||||
if (length == 0) {
|
||||
if (buffer) buffer[0] = 0;
|
||||
len = 0;
|
||||
return *this;
|
||||
}
|
||||
if (!reserve(length)) {
|
||||
if (buffer) {
|
||||
free(buffer);
|
||||
buffer = NULL;
|
||||
}
|
||||
len = capacity = 0;
|
||||
return *this;
|
||||
}
|
||||
len = length;
|
||||
strcpy(buffer, cstr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::copy(const __FlashStringHelper *pgmstr)
|
||||
{
|
||||
unsigned int length = strlen_P((const char PROGMEM *)pgmstr);
|
||||
if (!reserve(length)) {
|
||||
if (buffer) {
|
||||
free(buffer);
|
||||
buffer = NULL;
|
||||
}
|
||||
len = capacity = 0;
|
||||
return *this;
|
||||
}
|
||||
len = length;
|
||||
strcpy_P(buffer, (const char PROGMEM *)pgmstr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void String::move(String &rhs)
|
||||
{
|
||||
if (buffer) {
|
||||
if (capacity >= rhs.len) {
|
||||
strcpy(buffer, rhs.buffer);
|
||||
len = rhs.len;
|
||||
rhs.len = 0;
|
||||
return;
|
||||
} else {
|
||||
free(buffer);
|
||||
}
|
||||
}
|
||||
buffer = rhs.buffer;
|
||||
capacity = rhs.capacity;
|
||||
len = rhs.len;
|
||||
rhs.buffer = NULL;
|
||||
rhs.capacity = 0;
|
||||
rhs.len = 0;
|
||||
}
|
||||
|
||||
String & String::operator = (const String &rhs)
|
||||
{
|
||||
if (this == &rhs) return *this;
|
||||
return copy(rhs.buffer, rhs.len);
|
||||
}
|
||||
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
String & String::operator = (String &&rval)
|
||||
{
|
||||
if (this != &rval) move(rval);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::operator = (StringSumHelper &&rval)
|
||||
{
|
||||
if (this != &rval) move(rval);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
String & String::operator = (const char *cstr)
|
||||
{
|
||||
if (cstr) {
|
||||
copy(cstr, strlen(cstr));
|
||||
} else {
|
||||
len = 0;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::operator = (const __FlashStringHelper *pgmstr)
|
||||
{
|
||||
copy(pgmstr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::operator = (char c)
|
||||
{
|
||||
char buf[2];
|
||||
buf[0] = c;
|
||||
buf[1] = 0;
|
||||
return copy(buf, 1);
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
/* Append */
|
||||
/*********************************************/
|
||||
|
||||
String & String::append(const String &s)
|
||||
{
|
||||
return append(s.buffer, s.len);
|
||||
}
|
||||
|
||||
String & String::append(const char *cstr, unsigned int length)
|
||||
{
|
||||
unsigned int newlen = len + length;
|
||||
if (length == 0 || !reserve(newlen)) return *this;
|
||||
strcpy(buffer + len, cstr);
|
||||
len = newlen;
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::append(const char *cstr)
|
||||
{
|
||||
if (cstr) append(cstr, strlen(cstr));
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::append(const __FlashStringHelper *pgmstr)
|
||||
{
|
||||
unsigned int length = strlen_P((const char PROGMEM *)pgmstr);
|
||||
unsigned int newlen = len + length;
|
||||
if (length == 0 || !reserve(newlen)) return *this;
|
||||
strcpy_P(buffer + len, (const char PROGMEM *)pgmstr);
|
||||
len = newlen;
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::append(char c)
|
||||
{
|
||||
char buf[2];
|
||||
buf[0] = c;
|
||||
buf[1] = 0;
|
||||
append(buf, 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::append(int num)
|
||||
{
|
||||
char buf[7];
|
||||
itoa(num, buf, 10);
|
||||
append(buf, strlen(buf));
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::append(unsigned int num)
|
||||
{
|
||||
char buf[6];
|
||||
utoa(num, buf, 10);
|
||||
append(buf, strlen(buf));
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::append(long num)
|
||||
{
|
||||
char buf[12];
|
||||
ltoa(num, buf, 10);
|
||||
append(buf, strlen(buf));
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::append(unsigned long num)
|
||||
{
|
||||
char buf[11];
|
||||
ultoa(num, buf, 10);
|
||||
append(buf, strlen(buf));
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::append(float num)
|
||||
{
|
||||
char buf[30];
|
||||
dtostrf(num, 4, 2, buf);
|
||||
append(buf, strlen(buf));
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
/* Concatenate */
|
||||
/*********************************************/
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
a.append(rhs.buffer, rhs.len);
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
if (cstr) a.append(cstr, strlen(cstr));
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *pgmstr)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
a.append(pgmstr);
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, char c)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
a.append(c);
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char c)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
a.append(c);
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, int num)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
a.append(num);
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
a.append(num);
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, long num)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
a.append(num);
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
a.append(num);
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, float num)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
a.append(num);
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, double num)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
a.append(num);
|
||||
return a;
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
/* Comparison */
|
||||
/*********************************************/
|
||||
|
||||
int String::compareTo(const String &s) const
|
||||
{
|
||||
if (!buffer || !s.buffer) {
|
||||
if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer;
|
||||
if (buffer && len > 0) return *(unsigned char *)buffer;
|
||||
return 0;
|
||||
}
|
||||
return strcmp(buffer, s.buffer);
|
||||
}
|
||||
|
||||
unsigned char String::equals(const String &s2) const
|
||||
{
|
||||
return (len == s2.len && compareTo(s2) == 0);
|
||||
}
|
||||
|
||||
unsigned char String::equals(const char *cstr) const
|
||||
{
|
||||
if (len == 0) return (cstr == NULL || *cstr == 0);
|
||||
if (cstr == NULL) return buffer[0] == 0;
|
||||
return strcmp(buffer, cstr) == 0;
|
||||
}
|
||||
|
||||
unsigned char String::equals(const __FlashStringHelper *pgmstr) const
|
||||
{
|
||||
if (len == 0) return pgm_read_byte(pgmstr) == 0;
|
||||
return strcmp_P(buffer, (const char PROGMEM *)pgmstr) == 0;
|
||||
}
|
||||
|
||||
unsigned char String::operator<(const String &rhs) const
|
||||
{
|
||||
return compareTo(rhs) < 0;
|
||||
}
|
||||
|
||||
unsigned char String::operator>(const String &rhs) const
|
||||
{
|
||||
return compareTo(rhs) > 0;
|
||||
}
|
||||
|
||||
unsigned char String::operator<=(const String &rhs) const
|
||||
{
|
||||
return compareTo(rhs) <= 0;
|
||||
}
|
||||
|
||||
unsigned char String::operator>=(const String &rhs) const
|
||||
{
|
||||
return compareTo(rhs) >= 0;
|
||||
}
|
||||
|
||||
unsigned char String::equalsIgnoreCase( const String &s2 ) const
|
||||
{
|
||||
if (this == &s2) return 1;
|
||||
if (len != s2.len) return 0;
|
||||
if (len == 0) return 1;
|
||||
const char *p1 = buffer;
|
||||
const char *p2 = s2.buffer;
|
||||
while (*p1) {
|
||||
if (tolower(*p1++) != tolower(*p2++)) return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned char String::startsWith( const String &s2 ) const
|
||||
{
|
||||
if (len < s2.len) return 0;
|
||||
return startsWith(s2, 0);
|
||||
}
|
||||
|
||||
unsigned char String::startsWith( const String &s2, unsigned int offset ) const
|
||||
{
|
||||
if (offset > len - s2.len || !buffer || !s2.buffer) return 0;
|
||||
return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0;
|
||||
}
|
||||
|
||||
unsigned char String::endsWith( const String &s2 ) const
|
||||
{
|
||||
if ( len < s2.len || !buffer || !s2.buffer) return 0;
|
||||
return strcmp(&buffer[len - s2.len], s2.buffer) == 0;
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
/* Character Access */
|
||||
/*********************************************/
|
||||
|
||||
char String::charAt(unsigned int loc) const
|
||||
{
|
||||
return operator[](loc);
|
||||
}
|
||||
|
||||
void String::setCharAt(unsigned int loc, char c)
|
||||
{
|
||||
if (loc < len) buffer[loc] = c;
|
||||
}
|
||||
|
||||
char & String::operator[](unsigned int index)
|
||||
{
|
||||
static char dummy_writable_char;
|
||||
if (index >= len || !buffer) {
|
||||
dummy_writable_char = 0;
|
||||
return dummy_writable_char;
|
||||
}
|
||||
return buffer[index];
|
||||
}
|
||||
|
||||
char String::operator[]( unsigned int index ) const
|
||||
{
|
||||
if (index >= len || !buffer) return 0;
|
||||
return buffer[index];
|
||||
}
|
||||
|
||||
void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const
|
||||
{
|
||||
if (!bufsize || !buf) return;
|
||||
if (index >= len) {
|
||||
buf[0] = 0;
|
||||
return;
|
||||
}
|
||||
unsigned int n = bufsize - 1;
|
||||
if (n > len - index) n = len - index;
|
||||
strncpy((char *)buf, buffer + index, n);
|
||||
buf[n] = 0;
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
/* Search */
|
||||
/*********************************************/
|
||||
|
||||
int String::indexOf(char c) const
|
||||
{
|
||||
return indexOf(c, 0);
|
||||
}
|
||||
|
||||
int String::indexOf( char ch, unsigned int fromIndex ) const
|
||||
{
|
||||
if (fromIndex >= len) return -1;
|
||||
const char* temp = strchr(buffer + fromIndex, ch);
|
||||
if (temp == NULL) return -1;
|
||||
return temp - buffer;
|
||||
}
|
||||
|
||||
int String::indexOf(const String &s2) const
|
||||
{
|
||||
return indexOf(s2, 0);
|
||||
}
|
||||
|
||||
int String::indexOf(const String &s2, unsigned int fromIndex) const
|
||||
{
|
||||
if (fromIndex >= len) return -1;
|
||||
const char *found = strstr(buffer + fromIndex, s2.buffer);
|
||||
if (found == NULL) return -1;
|
||||
return found - buffer;
|
||||
}
|
||||
|
||||
int String::lastIndexOf( char theChar ) const
|
||||
{
|
||||
return lastIndexOf(theChar, len - 1);
|
||||
}
|
||||
|
||||
int String::lastIndexOf(char ch, unsigned int fromIndex) const
|
||||
{
|
||||
if (fromIndex >= len || fromIndex < 0) return -1;
|
||||
char tempchar = buffer[fromIndex + 1];
|
||||
buffer[fromIndex + 1] = '\0';
|
||||
char* temp = strrchr( buffer, ch );
|
||||
buffer[fromIndex + 1] = tempchar;
|
||||
if (temp == NULL) return -1;
|
||||
return temp - buffer;
|
||||
}
|
||||
|
||||
int String::lastIndexOf(const String &s2) const
|
||||
{
|
||||
return lastIndexOf(s2, len - s2.len);
|
||||
}
|
||||
|
||||
int String::lastIndexOf(const String &s2, unsigned int fromIndex) const
|
||||
{
|
||||
if (s2.len == 0 || len == 0 || s2.len > len || fromIndex < 0) return -1;
|
||||
if (fromIndex >= len) fromIndex = len - 1;
|
||||
int found = -1;
|
||||
for (char *p = buffer; p <= buffer + fromIndex; p++) {
|
||||
p = strstr(p, s2.buffer);
|
||||
if (!p) break;
|
||||
if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
String String::substring( unsigned int left ) const
|
||||
{
|
||||
return substring(left, len);
|
||||
}
|
||||
|
||||
String String::substring(unsigned int left, unsigned int right) const
|
||||
{
|
||||
if (left > right) {
|
||||
unsigned int temp = right;
|
||||
right = left;
|
||||
left = temp;
|
||||
}
|
||||
String out;
|
||||
if (left > len) return out;
|
||||
if (right > len) right = len;
|
||||
char temp = buffer[right]; // save the replaced character
|
||||
buffer[right] = '\0';
|
||||
out = buffer + left; // pointer arithmetic
|
||||
buffer[right] = temp; //restore character
|
||||
return out;
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
/* Modification */
|
||||
/*********************************************/
|
||||
|
||||
String & String::replace(char find, char replace)
|
||||
{
|
||||
if (!buffer) return *this;
|
||||
for (char *p = buffer; *p; p++) {
|
||||
if (*p == find) *p = replace;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::replace(const String& find, const String& replace)
|
||||
{
|
||||
if (len == 0 || find.len == 0) return *this;
|
||||
int diff = replace.len - find.len;
|
||||
char *readFrom = buffer;
|
||||
char *foundAt;
|
||||
if (diff == 0) {
|
||||
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
|
||||
memcpy(foundAt, replace.buffer, replace.len);
|
||||
readFrom = foundAt + replace.len;
|
||||
}
|
||||
} else if (diff < 0) {
|
||||
char *writeTo = buffer;
|
||||
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
|
||||
unsigned int n = foundAt - readFrom;
|
||||
memcpy(writeTo, readFrom, n);
|
||||
writeTo += n;
|
||||
memcpy(writeTo, replace.buffer, replace.len);
|
||||
writeTo += replace.len;
|
||||
readFrom = foundAt + find.len;
|
||||
len += diff;
|
||||
}
|
||||
strcpy(writeTo, readFrom);
|
||||
} else {
|
||||
unsigned int size = len; // compute size needed for result
|
||||
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
|
||||
readFrom = foundAt + find.len;
|
||||
size += diff;
|
||||
}
|
||||
if (size == len) return *this;
|
||||
if (size > capacity && !changeBuffer(size)) return *this;
|
||||
int index = len - 1;
|
||||
while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) {
|
||||
readFrom = buffer + index + find.len;
|
||||
memmove(readFrom + diff, readFrom, len - (readFrom - buffer));
|
||||
len += diff;
|
||||
buffer[len] = 0;
|
||||
memcpy(buffer + index, replace.buffer, replace.len);
|
||||
index--;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::remove(unsigned int index)
|
||||
{
|
||||
if (index < len) {
|
||||
len = index;
|
||||
buffer[len] = 0;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::remove(unsigned int index, unsigned int count)
|
||||
{
|
||||
if (index < len && count > 0) {
|
||||
if (index + count > len) count = len - index;
|
||||
len = len - count;
|
||||
memmove(buffer + index, buffer + index + count, len - index);
|
||||
buffer[len] = 0;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::toLowerCase(void)
|
||||
{
|
||||
if (!buffer) return *this;
|
||||
for (char *p = buffer; *p; p++) {
|
||||
*p = tolower(*p);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::toUpperCase(void)
|
||||
{
|
||||
if (!buffer) return *this;
|
||||
for (char *p = buffer; *p; p++) {
|
||||
*p = toupper(*p);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::trim(void)
|
||||
{
|
||||
if (!buffer || len == 0) return *this;
|
||||
char *begin = buffer;
|
||||
while (isspace(*begin)) begin++;
|
||||
char *end = buffer + len - 1;
|
||||
while (isspace(*end) && end >= begin) end--;
|
||||
len = end + 1 - begin;
|
||||
if (begin > buffer) memcpy(buffer, begin, len);
|
||||
buffer[len] = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
/* Parsing / Conversion */
|
||||
/*********************************************/
|
||||
|
||||
long String::toInt(void) const
|
||||
{
|
||||
if (buffer) return atol(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
float String::toFloat(void) const
|
||||
{
|
||||
if (buffer) return atof(buffer);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
216
teensy/WString.h
Normal file
216
teensy/WString.h
Normal 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
teensy/binary.h
Normal file
515
teensy/binary.h
Normal 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
teensy/core_id.h
Normal file
18
teensy/core_id.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#ifndef CORE_TEENSY
|
||||
#define CORE_TEENSY
|
||||
#if defined(USB_SERIAL)
|
||||
#include "../usb_serial/core_id.h"
|
||||
#elif defined(USB_HID)
|
||||
#include "../usb_hid/core_id.h"
|
||||
#elif defined(USB_SERIAL_HID)
|
||||
#include "../usb_serial_hid/core_id.h"
|
||||
#elif defined(USB_DISK) || defined(USB_DISK_SDFLASH)
|
||||
#include "../usb_disk/core_id.h"
|
||||
#elif defined(USB_MIDI)
|
||||
#include "../usb_midi/core_id.h"
|
||||
#elif defined(USB_RAWHID)
|
||||
#include "../usb_rawhid/core_id.h"
|
||||
#elif defined(USB_FLIGHTSIM)
|
||||
#include "../usb_flightsim/core_id.h"
|
||||
#endif
|
||||
#endif
|
||||
1987
teensy/core_pins.h
Normal file
1987
teensy/core_pins.h
Normal file
File diff suppressed because it is too large
Load diff
81
teensy/elapsedMillis.h
Normal file
81
teensy/elapsedMillis.h
Normal 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
teensy/keylayouts.c
Normal file
66
teensy/keylayouts.c
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
#include <avr/pgmspace.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "keylayouts.h"
|
||||
|
||||
#ifdef M
|
||||
#undef M
|
||||
#endif
|
||||
#define M(n) ((n) & 0x3FFF)
|
||||
|
||||
const KEYCODE_TYPE PROGMEM keycodes_ascii[] = {
|
||||
M(ASCII_20), M(ASCII_21), M(ASCII_22), M(ASCII_23),
|
||||
M(ASCII_24), M(ASCII_25), M(ASCII_26), M(ASCII_27),
|
||||
M(ASCII_28), M(ASCII_29), M(ASCII_2A), M(ASCII_2B),
|
||||
M(ASCII_2C), M(ASCII_2D), M(ASCII_2E), M(ASCII_2F),
|
||||
M(ASCII_30), M(ASCII_31), M(ASCII_32), M(ASCII_33),
|
||||
M(ASCII_34), M(ASCII_35), M(ASCII_36), M(ASCII_37),
|
||||
M(ASCII_38), M(ASCII_39), M(ASCII_3A), M(ASCII_3B),
|
||||
M(ASCII_3C), M(ASCII_3D), M(ASCII_3E), M(ASCII_3F),
|
||||
M(ASCII_40), M(ASCII_41), M(ASCII_42), M(ASCII_43),
|
||||
M(ASCII_44), M(ASCII_45), M(ASCII_46), M(ASCII_47),
|
||||
M(ASCII_48), M(ASCII_49), M(ASCII_4A), M(ASCII_4B),
|
||||
M(ASCII_4C), M(ASCII_4D), M(ASCII_4E), M(ASCII_4F),
|
||||
M(ASCII_50), M(ASCII_51), M(ASCII_52), M(ASCII_53),
|
||||
M(ASCII_54), M(ASCII_55), M(ASCII_56), M(ASCII_57),
|
||||
M(ASCII_58), M(ASCII_59), M(ASCII_5A), M(ASCII_5B),
|
||||
M(ASCII_5C), M(ASCII_5D), M(ASCII_5E), M(ASCII_5F),
|
||||
M(ASCII_60), M(ASCII_61), M(ASCII_62), M(ASCII_63),
|
||||
M(ASCII_64), M(ASCII_65), M(ASCII_66), M(ASCII_67),
|
||||
M(ASCII_68), M(ASCII_69), M(ASCII_6A), M(ASCII_6B),
|
||||
M(ASCII_6C), M(ASCII_6D), M(ASCII_6E), M(ASCII_6F),
|
||||
M(ASCII_70), M(ASCII_71), M(ASCII_72), M(ASCII_73),
|
||||
M(ASCII_74), M(ASCII_75), M(ASCII_76), M(ASCII_77),
|
||||
M(ASCII_78), M(ASCII_79), M(ASCII_7A), M(ASCII_7B),
|
||||
M(ASCII_7C), M(ASCII_7D), M(ASCII_7E), M(ASCII_7F)
|
||||
};
|
||||
|
||||
#ifdef ISO_8859_1_A0
|
||||
const KEYCODE_TYPE PROGMEM keycodes_iso_8859_1[] = {
|
||||
M(ISO_8859_1_A0), M(ISO_8859_1_A1), M(ISO_8859_1_A2), M(ISO_8859_1_A3),
|
||||
M(ISO_8859_1_A4), M(ISO_8859_1_A5), M(ISO_8859_1_A6), M(ISO_8859_1_A7),
|
||||
M(ISO_8859_1_A8), M(ISO_8859_1_A9), M(ISO_8859_1_AA), M(ISO_8859_1_AB),
|
||||
M(ISO_8859_1_AC), M(ISO_8859_1_AD), M(ISO_8859_1_AE), M(ISO_8859_1_AF),
|
||||
M(ISO_8859_1_B0), M(ISO_8859_1_B1), M(ISO_8859_1_B2), M(ISO_8859_1_B3),
|
||||
M(ISO_8859_1_B4), M(ISO_8859_1_B5), M(ISO_8859_1_B6), M(ISO_8859_1_B7),
|
||||
M(ISO_8859_1_B8), M(ISO_8859_1_B9), M(ISO_8859_1_BA), M(ISO_8859_1_BB),
|
||||
M(ISO_8859_1_BC), M(ISO_8859_1_BD), M(ISO_8859_1_BE), M(ISO_8859_1_BF),
|
||||
M(ISO_8859_1_C0), M(ISO_8859_1_C1), M(ISO_8859_1_C2), M(ISO_8859_1_C3),
|
||||
M(ISO_8859_1_C4), M(ISO_8859_1_C5), M(ISO_8859_1_C6), M(ISO_8859_1_C7),
|
||||
M(ISO_8859_1_C8), M(ISO_8859_1_C9), M(ISO_8859_1_CA), M(ISO_8859_1_CB),
|
||||
M(ISO_8859_1_CC), M(ISO_8859_1_CD), M(ISO_8859_1_CE), M(ISO_8859_1_CF),
|
||||
M(ISO_8859_1_D0), M(ISO_8859_1_D1), M(ISO_8859_1_D2), M(ISO_8859_1_D3),
|
||||
M(ISO_8859_1_D4), M(ISO_8859_1_D5), M(ISO_8859_1_D6), M(ISO_8859_1_D7),
|
||||
M(ISO_8859_1_D8), M(ISO_8859_1_D9), M(ISO_8859_1_DA), M(ISO_8859_1_DB),
|
||||
M(ISO_8859_1_DC), M(ISO_8859_1_DD), M(ISO_8859_1_DE), M(ISO_8859_1_DF),
|
||||
M(ISO_8859_1_E0), M(ISO_8859_1_E1), M(ISO_8859_1_E2), M(ISO_8859_1_E3),
|
||||
M(ISO_8859_1_E4), M(ISO_8859_1_E5), M(ISO_8859_1_E6), M(ISO_8859_1_E7),
|
||||
M(ISO_8859_1_E8), M(ISO_8859_1_E9), M(ISO_8859_1_EA), M(ISO_8859_1_EB),
|
||||
M(ISO_8859_1_EC), M(ISO_8859_1_ED), M(ISO_8859_1_EE), M(ISO_8859_1_EF),
|
||||
M(ISO_8859_1_F0), M(ISO_8859_1_F1), M(ISO_8859_1_F2), M(ISO_8859_1_F3),
|
||||
M(ISO_8859_1_F4), M(ISO_8859_1_F5), M(ISO_8859_1_F6), M(ISO_8859_1_F7),
|
||||
M(ISO_8859_1_F8), M(ISO_8859_1_F9), M(ISO_8859_1_FA), M(ISO_8859_1_FB),
|
||||
M(ISO_8859_1_FC), M(ISO_8859_1_FD), M(ISO_8859_1_FE), M(ISO_8859_1_FF)
|
||||
};
|
||||
#endif // ISO_8859_1_A0
|
||||
|
||||
5173
teensy/keylayouts.h
Normal file
5173
teensy/keylayouts.h
Normal file
File diff suppressed because it is too large
Load diff
14
teensy/main.cpp
Normal file
14
teensy/main.cpp
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
#include <WProgram.h>
|
||||
|
||||
//int main(void) __attribute__((noreturn));
|
||||
int main(void)
|
||||
{
|
||||
_init_Teensyduino_internal_();
|
||||
|
||||
setup();
|
||||
|
||||
while (1) {
|
||||
loop();
|
||||
}
|
||||
}
|
||||
|
||||
1
teensy/main.cxx
Normal file
1
teensy/main.cxx
Normal file
|
|
@ -0,0 +1 @@
|
|||
// the main function is now built into core.a and linked into the final executable
|
||||
388
teensy/malloc.c
Normal file
388
teensy/malloc.c
Normal file
|
|
@ -0,0 +1,388 @@
|
|||
/* Copyright (c) 2002, 2004, 2010 Joerg Wunsch
|
||||
Copyright (c) 2010 Gerben van den Broeke
|
||||
All rights reserved.
|
||||
|
||||
malloc, free, realloc from avr-libc 1.7.0
|
||||
with minor modifications, by Paul Stoffregen
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
* Neither the name of the copyright holders nor the names of
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <avr/io.h>
|
||||
|
||||
extern char __heap_start;
|
||||
extern char __heap_end;
|
||||
#define STACK_POINTER() ((char *)AVR_STACK_POINTER_REG)
|
||||
|
||||
struct __freelist {
|
||||
size_t sz;
|
||||
struct __freelist *nx;
|
||||
};
|
||||
|
||||
/*
|
||||
* Exported interface:
|
||||
*
|
||||
* When extending the data segment, the allocator will not try to go
|
||||
* beyond the current stack limit, decreased by __malloc_margin bytes.
|
||||
* Thus, all possible stack frames of interrupt routines that could
|
||||
* interrupt the current function, plus all further nested function
|
||||
* calls must not require more stack space, or they'll risk to collide
|
||||
* with the data segment.
|
||||
*/
|
||||
|
||||
size_t __malloc_margin = 128;
|
||||
char *__malloc_heap_start = &__heap_start;
|
||||
char *__malloc_heap_end = &__heap_end;
|
||||
|
||||
char *__brkval = NULL; // first location not yet allocated
|
||||
struct __freelist *__flp; // freelist pointer (head of freelist)
|
||||
|
||||
// this is useful for tracking the worst case memory allocation
|
||||
//char *__brkval_maximum = 0;
|
||||
|
||||
|
||||
void *
|
||||
malloc(size_t len)
|
||||
{
|
||||
struct __freelist *fp1, *fp2, *sfp1, *sfp2;
|
||||
char *cp;
|
||||
size_t s, avail;
|
||||
|
||||
/*
|
||||
* Our minimum chunk size is the size of a pointer (plus the
|
||||
* size of the "sz" field, but we don't need to account for
|
||||
* this), otherwise we could not possibly fit a freelist entry
|
||||
* into the chunk later.
|
||||
*/
|
||||
if (len < sizeof(struct __freelist) - sizeof(size_t))
|
||||
len = sizeof(struct __freelist) - sizeof(size_t);
|
||||
|
||||
/*
|
||||
* First, walk the free list and try finding a chunk that
|
||||
* would match exactly. If we found one, we are done. While
|
||||
* walking, note down the smallest chunk we found that would
|
||||
* still fit the request -- we need it for step 2.
|
||||
*
|
||||
*/
|
||||
for (s = 0, fp1 = __flp, fp2 = 0;
|
||||
fp1;
|
||||
fp2 = fp1, fp1 = fp1->nx) {
|
||||
if (fp1->sz < len)
|
||||
continue;
|
||||
if (fp1->sz == len) {
|
||||
/*
|
||||
* Found it. Disconnect the chunk from the
|
||||
* freelist, and return it.
|
||||
*/
|
||||
if (fp2)
|
||||
fp2->nx = fp1->nx;
|
||||
else
|
||||
__flp = fp1->nx;
|
||||
return &(fp1->nx);
|
||||
}
|
||||
else {
|
||||
if (s == 0 || fp1->sz < s) {
|
||||
/* this is the smallest chunk found so far */
|
||||
s = fp1->sz;
|
||||
sfp1 = fp1;
|
||||
sfp2 = fp2;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Step 2: If we found a chunk on the freelist that would fit
|
||||
* (but was too large), look it up again and use it, since it
|
||||
* is our closest match now. Since the freelist entry needs
|
||||
* to be split into two entries then, watch out that the
|
||||
* difference between the requested size and the size of the
|
||||
* chunk found is large enough for another freelist entry; if
|
||||
* not, just enlarge the request size to what we have found,
|
||||
* and use the entire chunk.
|
||||
*/
|
||||
if (s) {
|
||||
if (s - len < sizeof(struct __freelist)) {
|
||||
/* Disconnect it from freelist and return it. */
|
||||
if (sfp2)
|
||||
sfp2->nx = sfp1->nx;
|
||||
else
|
||||
__flp = sfp1->nx;
|
||||
return &(sfp1->nx);
|
||||
}
|
||||
/*
|
||||
* Split them up. Note that we leave the first part
|
||||
* as the new (smaller) freelist entry, and return the
|
||||
* upper portion to the caller. This saves us the
|
||||
* work to fix up the freelist chain; we just need to
|
||||
* fixup the size of the current entry, and note down
|
||||
* the size of the new chunk before returning it to
|
||||
* the caller.
|
||||
*/
|
||||
cp = (char *)sfp1;
|
||||
s -= len;
|
||||
cp += s;
|
||||
sfp2 = (struct __freelist *)cp;
|
||||
sfp2->sz = len;
|
||||
sfp1->sz = s - sizeof(size_t);
|
||||
return &(sfp2->nx);
|
||||
}
|
||||
/*
|
||||
* Step 3: If the request could not be satisfied from a
|
||||
* freelist entry, just prepare a new chunk. This means we
|
||||
* need to obtain more memory first. The largest address just
|
||||
* not allocated so far is remembered in the brkval variable.
|
||||
* Under Unix, the "break value" was the end of the data
|
||||
* segment as dynamically requested from the operating system.
|
||||
* Since we don't have an operating system, just make sure
|
||||
* that we don't collide with the stack.
|
||||
*/
|
||||
if (__brkval == 0)
|
||||
__brkval = __malloc_heap_start;
|
||||
cp = __malloc_heap_end;
|
||||
if (cp == 0)
|
||||
cp = STACK_POINTER() - __malloc_margin;
|
||||
if (cp <= __brkval)
|
||||
/*
|
||||
* Memory exhausted.
|
||||
*/
|
||||
return 0;
|
||||
avail = cp - __brkval;
|
||||
/*
|
||||
* Both tests below are needed to catch the case len >= 0xfffe.
|
||||
*/
|
||||
if (avail >= len && avail >= len + sizeof(size_t)) {
|
||||
fp1 = (struct __freelist *)__brkval;
|
||||
__brkval += len + sizeof(size_t);
|
||||
//__brkval_maximum = __brkval;
|
||||
fp1->sz = len;
|
||||
return &(fp1->nx);
|
||||
}
|
||||
/*
|
||||
* Step 4: There's no help, just fail. :-/
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
free(void *p)
|
||||
{
|
||||
struct __freelist *fp1, *fp2, *fpnew;
|
||||
char *cp1, *cp2, *cpnew;
|
||||
|
||||
/* ISO C says free(NULL) must be a no-op */
|
||||
if (p == 0)
|
||||
return;
|
||||
|
||||
cpnew = p;
|
||||
cpnew -= sizeof(size_t);
|
||||
fpnew = (struct __freelist *)cpnew;
|
||||
fpnew->nx = 0;
|
||||
|
||||
/*
|
||||
* Trivial case first: if there's no freelist yet, our entry
|
||||
* will be the only one on it. If this is the last entry, we
|
||||
* can reduce __brkval instead.
|
||||
*/
|
||||
if (__flp == 0) {
|
||||
if ((char *)p + fpnew->sz == __brkval)
|
||||
__brkval = cpnew;
|
||||
else
|
||||
__flp = fpnew;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now, find the position where our new entry belongs onto the
|
||||
* freelist. Try to aggregate the chunk with adjacent chunks
|
||||
* if possible.
|
||||
*/
|
||||
for (fp1 = __flp, fp2 = 0;
|
||||
fp1;
|
||||
fp2 = fp1, fp1 = fp1->nx) {
|
||||
if (fp1 < fpnew)
|
||||
continue;
|
||||
cp1 = (char *)fp1;
|
||||
fpnew->nx = fp1;
|
||||
if ((char *)&(fpnew->nx) + fpnew->sz == cp1) {
|
||||
/* upper chunk adjacent, assimilate it */
|
||||
fpnew->sz += fp1->sz + sizeof(size_t);
|
||||
fpnew->nx = fp1->nx;
|
||||
}
|
||||
if (fp2 == 0) {
|
||||
/* new head of freelist */
|
||||
__flp = fpnew;
|
||||
return;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Note that we get here either if we hit the "break" above,
|
||||
* or if we fell off the end of the loop. The latter means
|
||||
* we've got a new topmost chunk. Either way, try aggregating
|
||||
* with the lower chunk if possible.
|
||||
*/
|
||||
fp2->nx = fpnew;
|
||||
cp2 = (char *)&(fp2->nx);
|
||||
if (cp2 + fp2->sz == cpnew) {
|
||||
/* lower junk adjacent, merge */
|
||||
fp2->sz += fpnew->sz + sizeof(size_t);
|
||||
fp2->nx = fpnew->nx;
|
||||
}
|
||||
/*
|
||||
* If there's a new topmost chunk, lower __brkval instead.
|
||||
*/
|
||||
for (fp1 = __flp, fp2 = 0;
|
||||
fp1->nx != 0;
|
||||
fp2 = fp1, fp1 = fp1->nx)
|
||||
/* advance to entry just before end of list */;
|
||||
cp2 = (char *)&(fp1->nx);
|
||||
if (cp2 + fp1->sz == __brkval) {
|
||||
if (fp2 == NULL)
|
||||
/* Freelist is empty now. */
|
||||
__flp = NULL;
|
||||
else
|
||||
fp2->nx = NULL;
|
||||
__brkval = cp2 - sizeof(size_t);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void *
|
||||
realloc(void *ptr, size_t len)
|
||||
{
|
||||
struct __freelist *fp1, *fp2, *fp3, *ofp3;
|
||||
char *cp, *cp1;
|
||||
void *memp;
|
||||
size_t s, incr;
|
||||
|
||||
/* Trivial case, required by C standard. */
|
||||
if (ptr == 0)
|
||||
return malloc(len);
|
||||
|
||||
cp1 = (char *)ptr;
|
||||
cp1 -= sizeof(size_t);
|
||||
fp1 = (struct __freelist *)cp1;
|
||||
|
||||
cp = (char *)ptr + len; /* new next pointer */
|
||||
if (cp < cp1)
|
||||
/* Pointer wrapped across top of RAM, fail. */
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* See whether we are growing or shrinking. When shrinking,
|
||||
* we split off a chunk for the released portion, and call
|
||||
* free() on it. Therefore, we can only shrink if the new
|
||||
* size is at least sizeof(struct __freelist) smaller than the
|
||||
* previous size.
|
||||
*/
|
||||
if (len <= fp1->sz) {
|
||||
/* The first test catches a possible unsigned int
|
||||
* rollover condition. */
|
||||
if (fp1->sz <= sizeof(struct __freelist) ||
|
||||
len > fp1->sz - sizeof(struct __freelist))
|
||||
return ptr;
|
||||
fp2 = (struct __freelist *)cp;
|
||||
fp2->sz = fp1->sz - len - sizeof(size_t);
|
||||
fp1->sz = len;
|
||||
free(&(fp2->nx));
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we get here, we are growing. First, see whether there
|
||||
* is space in the free list on top of our current chunk.
|
||||
*/
|
||||
incr = len - fp1->sz;
|
||||
cp = (char *)ptr + fp1->sz;
|
||||
fp2 = (struct __freelist *)cp;
|
||||
for (s = 0, ofp3 = 0, fp3 = __flp;
|
||||
fp3;
|
||||
ofp3 = fp3, fp3 = fp3->nx) {
|
||||
if (fp3 == fp2 && fp3->sz + sizeof(size_t) >= incr) {
|
||||
/* found something that fits */
|
||||
if (fp3->sz + sizeof(size_t) - incr > sizeof(struct __freelist)) {
|
||||
/* split off a new freelist entry */
|
||||
cp = (char *)ptr + len;
|
||||
fp2 = (struct __freelist *)cp;
|
||||
fp2->nx = fp3->nx;
|
||||
fp2->sz = fp3->sz - incr;
|
||||
fp1->sz = len;
|
||||
} else {
|
||||
/* it just fits, so use it entirely */
|
||||
fp1->sz += fp3->sz + sizeof(size_t);
|
||||
fp2 = fp3->nx;
|
||||
}
|
||||
if (ofp3)
|
||||
ofp3->nx = fp2;
|
||||
else
|
||||
__flp = fp2;
|
||||
return ptr;
|
||||
}
|
||||
/*
|
||||
* Find the largest chunk on the freelist while
|
||||
* walking it.
|
||||
*/
|
||||
if (fp3->sz > s)
|
||||
s = fp3->sz;
|
||||
}
|
||||
/*
|
||||
* If we are the topmost chunk in memory, and there was no
|
||||
* large enough chunk on the freelist that could be re-used
|
||||
* (by a call to malloc() below), quickly extend the
|
||||
* allocation area if possible, without need to copy the old
|
||||
* data.
|
||||
*/
|
||||
if (__brkval == (char *)ptr + fp1->sz && len > s) {
|
||||
cp = (char *)ptr + len;
|
||||
cp1 = STACK_POINTER() - __malloc_margin;
|
||||
if (cp < cp1) {
|
||||
__brkval = cp;
|
||||
//__brkval_maximum = cp;
|
||||
fp1->sz = len;
|
||||
return ptr;
|
||||
}
|
||||
/* If that failed, we are out of luck. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Call malloc() for a new chunk, then copy over the data, and
|
||||
* release the old region.
|
||||
*/
|
||||
if ((memp = malloc(len)) == 0)
|
||||
return 0;
|
||||
memcpy(memp, ptr, fp1->sz);
|
||||
free(ptr);
|
||||
return memp;
|
||||
}
|
||||
|
||||
18
teensy/new.cpp
Normal file
18
teensy/new.cpp
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#include <new.h>
|
||||
|
||||
void * operator new(size_t size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void operator delete(void * ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
int __cxa_guard_acquire(__guard *g) {return !*(char *)(g);};
|
||||
void __cxa_guard_release (__guard *g) {*(char *)g = 1;};
|
||||
void __cxa_guard_abort (__guard *) {};
|
||||
|
||||
void __cxa_pure_virtual(void) {};
|
||||
|
||||
22
teensy/new.h
Normal file
22
teensy/new.h
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
/* Header to define new/delete operators as they aren't provided by avr-gcc by default
|
||||
Taken from http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=59453
|
||||
*/
|
||||
|
||||
#ifndef NEW_H
|
||||
#define NEW_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
void * operator new(size_t size);
|
||||
void operator delete(void * ptr);
|
||||
|
||||
__extension__ typedef int __guard __attribute__((mode (__DI__)));
|
||||
|
||||
extern "C" int __cxa_guard_acquire(__guard *);
|
||||
extern "C" void __cxa_guard_release (__guard *);
|
||||
extern "C" void __cxa_guard_abort (__guard *);
|
||||
|
||||
extern "C" void __cxa_pure_virtual(void);
|
||||
|
||||
#endif
|
||||
|
||||
147
teensy/pins_arduino.h
Normal file
147
teensy/pins_arduino.h
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
#ifndef pins_macros_for_arduino_compatibility_h
|
||||
#define pins_macros_for_arduino_compatibility_h
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
#include "core_pins.h"
|
||||
|
||||
#if defined(__AVR_ATmega32U4__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
|
||||
const static uint8_t A0 = CORE_ANALOG0_PIN;
|
||||
const static uint8_t A1 = CORE_ANALOG1_PIN;
|
||||
const static uint8_t A2 = CORE_ANALOG2_PIN;
|
||||
const static uint8_t A3 = CORE_ANALOG3_PIN;
|
||||
const static uint8_t A4 = CORE_ANALOG4_PIN;
|
||||
const static uint8_t A5 = CORE_ANALOG5_PIN;
|
||||
const static uint8_t A6 = CORE_ANALOG6_PIN;
|
||||
const static uint8_t A7 = CORE_ANALOG7_PIN;
|
||||
#if defined(__AVR_ATmega32U4__)
|
||||
const static uint8_t A8 = CORE_ANALOG8_PIN;
|
||||
const static uint8_t A9 = CORE_ANALOG9_PIN;
|
||||
const static uint8_t A10 = 10;
|
||||
const static uint8_t A11 = CORE_ANALOG11_PIN;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
const static uint8_t SS = CORE_SS0_PIN;
|
||||
const static uint8_t MOSI = CORE_MOSI0_PIN;
|
||||
const static uint8_t MISO = CORE_MISO0_PIN;
|
||||
const static uint8_t SCK = CORE_SCLK0_PIN;
|
||||
const static uint8_t LED_BUILTIN = CORE_LED0_PIN;
|
||||
#if defined(CORE_SDA0_PIN)
|
||||
const static uint8_t SDA = CORE_SDA0_PIN;
|
||||
#endif
|
||||
#if defined(CORE_SCL0_PIN)
|
||||
const static uint8_t SCL = CORE_SCL0_PIN;
|
||||
#endif
|
||||
|
||||
#define NUM_DIGITAL_PINS CORE_NUM_TOTAL_PINS
|
||||
#define NUM_ANALOG_INPUTS CORE_NUM_ANALOG
|
||||
|
||||
|
||||
// This allows CapSense to work. Do any libraries
|
||||
// depend on these to be zero?
|
||||
#define NOT_A_PORT 127
|
||||
#define NOT_A_PIN 127
|
||||
|
||||
#define digitalPinToPort(P) (P)
|
||||
#define portInputRegister(P) ((volatile uint8_t *)((int)pgm_read_byte(digital_pin_table_PGM+(P)*2+1)))
|
||||
#define portModeRegister(P) (portInputRegister(P) + 1)
|
||||
#define portOutputRegister(P) (portInputRegister(P) + 2)
|
||||
#define digitalPinToBitMask(P) (pgm_read_byte(digital_pin_table_PGM+(P)*2))
|
||||
extern const uint8_t PROGMEM digital_pin_table_PGM[];
|
||||
|
||||
#if defined(__AVR_AT90USB162__)
|
||||
#define analogInputToDigitalPin(ch) (-1)
|
||||
#define digitalPinHasPWM(p) ((p) == 0 || (p) == 15 || (p) == 17 || (p) == 18)
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
#define analogInputToDigitalPin(ch) ((ch) <= 10 ? 21 - (ch) : ((ch) == 11 ? 22 : -1))
|
||||
#define digitalPinHasPWM(p) ((p) == 4 || (p) == 5 || (p) == 9 || (p) == 10 || (p) == 12 || (p) == 14 || (p) == 15)
|
||||
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
|
||||
#define analogInputToDigitalPin(ch) ((ch) <= 7 ? (ch) + 38 : -1)
|
||||
#define digitalPinHasPWM(p) (((p) >= 14 && (p) <= 16) || ((p) >= 24 && (p) <= 27) || (p) == 0 || (p) == 1)
|
||||
#endif
|
||||
|
||||
#if defined(__AVR_AT90USB162__)
|
||||
#define digitalPinToPortReg(p) (((p) <= 7) ? &PORTD : (((p) <= 15) ? &PORTB : &PORTC))
|
||||
#define digitalPinToBit(p) \
|
||||
(((p) <= 7) ? (p) : (((p) <= 15) ? (p) - 8 : (((p) <= 19) ? 23 - (p) : 2)))
|
||||
#define digitalPinToPCICR(p) \
|
||||
((((p) >= 8 && (p) <= 15) || ((p) >= 17 && (p) <= 20) || (p) == 5) ? &PCICR : NULL)
|
||||
#define digitalPinToPCICRbit(p) (((p) >= 8 && (p) <= 15) ? 0 : 1)
|
||||
#define digitalPinToPCIFR(p) \
|
||||
((((p) >= 8 && (p) <= 15) || ((p) >= 17 && (p) <= 20) || (p) == 5) ? &PCIFR : NULL)
|
||||
#define digitalPinToPCIFRbit(p) (((p) >= 8 && (p) <= 15) ? 0 : 1)
|
||||
#define digitalPinToPCMSK(p) \
|
||||
(((p) >= 8 && (p) <= 15) ? &PCMSK0 : ((((p) >= 17 && (p) <= 20) || (p) == 5) ? &PCMSK1 : NULL))
|
||||
#define digitalPinToPCMSKbit(p) \
|
||||
(((p) >= 8 && (p) <= 15) ? (p) - 8 : (((p) >= 17 && (p) <= 20) ? (p) - 17 : 4))
|
||||
|
||||
#elif defined(__AVR_ATmega32U4__)
|
||||
#define digitalPinToPortReg(p) \
|
||||
(((p) <= 4) ? &PORTB : (((p) <= 8) ? &PORTD : (((p) <= 10) ? &PORTC : (((p) <= 12) ? &PORTD : \
|
||||
(((p) <= 15) ? &PORTB : (((p) <= 21) ? &PORTF : (((p) <= 23) ? &PORTD : &PORTE)))))))
|
||||
#define digitalPinToBit(p) \
|
||||
(((p) <= 3) ? (p) : (((p) == 4) ? 7 : (((p) <= 8) ? (p) - 5 : (((p) <= 10) ? (p) - 3 : \
|
||||
(((p) <= 12) ? (p) - 5 : (((p) <= 15) ? (p) - 9 : (((p) <= 19) ? 23 - (p) : \
|
||||
(((p) <= 21) ? 21 - (p) : (((p) <= 23) ? (p) - 18 : 6)))))))))
|
||||
#define digitalPinToPCICR(p) ((((p) >= 0 && (p) <= 4) || ((p) >= 13 && (p) <= 15)) ? &PCICR : NULL)
|
||||
#define digitalPinToPCICRbit(p) (0)
|
||||
#define digitalPinToPCIFR(p) ((((p) >= 0 && (p) <= 4) || ((p) >= 13 && (p) <= 15)) ? &PCIFR : NULL)
|
||||
#define digitalPinToPCIFRbit(p) (0)
|
||||
#define digitalPinToPCMSK(p) ((((p) >= 0 && (p) <= 4) || ((p) >= 13 && (p) <= 15)) ? &PCMSK0 : NULL)
|
||||
#define digitalPinToPCMSKbit(p) \
|
||||
(((p) >= 0 && (p) <= 3) ? (p) : (((p) >= 13 && (p) <= 15) ? (p) - 9 : 7))
|
||||
|
||||
#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)
|
||||
#define digitalPinToPortReg(p) \
|
||||
(((p) >= 0 && (p) <= 7) ? &PORTD : (((p) >= 10 && (p) <= 17) ? &PORTC : \
|
||||
(((p) >= 20 && (p) <= 27) ? &PORTB : (((p) >= 28 && (p) <= 35) ? &PORTA : \
|
||||
(((p) >= 38 && (p) <= 45) ? &PORTF : &PORTE)))))
|
||||
#define digitalPinToBit(p) \
|
||||
(((p) <= 7) ? (p) : (((p) <= 9) ? (p) - 8 : (((p) <= 17) ? (p) - 10 : \
|
||||
(((p) <= 19) ? (p) - 12 : (((p) <= 27) ? (p) - 20 : (((p) <= 35) ? (p) - 28 : \
|
||||
(((p) <= 37) ? (p) - 32 : (((p) <= 45) ? (p) - 38 : 2))))))))
|
||||
#define digitalPinToPCICR(p) (((p) >= 20 && (p) <= 27) ? &PCICR : NULL)
|
||||
#define digitalPinToPCICRbit(p) (0)
|
||||
#define digitalPinToPCIFR(p) (((p) >= 20 && (p) <= 27) ? &PCIFR : NULL)
|
||||
#define digitalPinToPCIFRbit(p) (0)
|
||||
#define digitalPinToPCMSK(p) (((p) >= 20 && (p) <= 27) ? &PCMSK0 : NULL)
|
||||
#define digitalPinToPCMSKbit(p) (((p) - 20) & 7)
|
||||
#endif
|
||||
|
||||
#define NOT_ON_TIMER 0
|
||||
static inline uint8_t digitalPinToTimer(uint8_t) __attribute__((always_inline, unused));
|
||||
static inline uint8_t digitalPinToTimer(uint8_t pin)
|
||||
{
|
||||
switch (pin) {
|
||||
#ifdef CORE_PWM0_PIN
|
||||
case CORE_PWM0_PIN: return 1;
|
||||
#endif
|
||||
#ifdef CORE_PWM1_PIN
|
||||
case CORE_PWM1_PIN: return 2;
|
||||
#endif
|
||||
#ifdef CORE_PWM2_PIN
|
||||
case CORE_PWM2_PIN: return 3;
|
||||
#endif
|
||||
#ifdef CORE_PWM3_PIN
|
||||
case CORE_PWM3_PIN: return 4;
|
||||
#endif
|
||||
#ifdef CORE_PWM4_PIN
|
||||
case CORE_PWM4_PIN: return 5;
|
||||
#endif
|
||||
#ifdef CORE_PWM5_PIN
|
||||
case CORE_PWM5_PIN: return 6;
|
||||
#endif
|
||||
#ifdef CORE_PWM6_PIN
|
||||
case CORE_PWM6_PIN: return 7;
|
||||
#endif
|
||||
#ifdef CORE_PWM7_PIN
|
||||
case CORE_PWM7_PIN: return 8;
|
||||
#endif
|
||||
#ifdef CORE_PWM8_PIN
|
||||
case CORE_PWM8_PIN: return 9;
|
||||
#endif
|
||||
default: return NOT_ON_TIMER;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
1890
teensy/pins_teensy.c
Normal file
1890
teensy/pins_teensy.c
Normal file
File diff suppressed because it is too large
Load diff
15
teensy/usb.c
Normal file
15
teensy/usb.c
Normal 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
teensy/usb_api.cpp
Normal file
15
teensy/usb_api.cpp
Normal 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
teensy/usb_api.h
Normal file
15
teensy/usb_api.h
Normal 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
teensy/usb_common.h
Normal file
153
teensy/usb_common.h
Normal 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)(®)) )
|
||||
#define read_word_msbfirst(val, reg) \
|
||||
asm volatile( \
|
||||
"lds %B0, %1\n\tlds %A0, %1\n" \
|
||||
: "=r" (val) : "M" ((int)(®)) )
|
||||
#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)(®)) )
|
||||
#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)(®)) )
|
||||
|
||||
#define write_word_lsbfirst(val, reg) \
|
||||
asm volatile( \
|
||||
"sts %1, %A0\n\tsts %1, %B0\n" \
|
||||
: : "r" (val) , "M" ((int)(®)) )
|
||||
#define write_word_msbfirst(val, reg) \
|
||||
asm volatile( \
|
||||
"sts %1, %B0\n\tsts %1, %A0\n" \
|
||||
: : "r" (val) , "M" ((int)(®)) )
|
||||
#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)(®)) )
|
||||
#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)(®)) )
|
||||
|
||||
#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
teensy/usb_private.h
Normal file
15
teensy/usb_private.h
Normal 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
teensy/wiring.c
Normal file
80
teensy/wiring.c
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
wiring.c - Partial implementation of the Wiring API for the ATmega8.
|
||||
Part of Arduino - http://www.arduino.cc/
|
||||
|
||||
Copyright (c) 2005-2006 David A. Mellis
|
||||
|
||||
Modified for Teensyduino by Paul Stoffregen, paul@pjrc.com
|
||||
http://www.pjrc.com/teensy/teensyduino.html
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General
|
||||
Public License along with this library; if not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "wiring_private.h"
|
||||
#include "pins_arduino.h"
|
||||
#include "core_pins.h"
|
||||
|
||||
|
||||
#define PULSEIN_CYCLES_PER_LOOP 21
|
||||
#define PULSEIN_CYCLES_LATENCY 11
|
||||
|
||||
/* Measures the length (in microseconds) of a pulse on the pin; state is HIGH
|
||||
* or LOW, the type of pulse to measure. Works on pulses from 2-3 microseconds
|
||||
* to 3 minutes in length, but must be called at least a few dozen microseconds
|
||||
* before the start of the pulse. */
|
||||
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout)
|
||||
{
|
||||
// cache the port and bit of the pin in order to speed up the
|
||||
// pulse width measuring loop and achieve finer resolution. calling
|
||||
// digitalRead() instead yields much coarser resolution.
|
||||
uint8_t bit = digitalPinToBitMask(pin);
|
||||
volatile uint8_t *reg = portInputRegister(digitalPinToPort(pin));
|
||||
uint8_t stateMask = (state ? bit : 0);
|
||||
unsigned long width = 0; // keep initialization out of time critical area
|
||||
|
||||
// convert the timeout from microseconds to a number of times through
|
||||
// the initial loop
|
||||
unsigned long numloops = 0;
|
||||
//unsigned long maxloops = microsecondsToClockCycles(timeout) / PULSEIN_CYCLES_PER_LOOP;
|
||||
unsigned long maxloops = timeout * clockCyclesPerMicrosecond() / PULSEIN_CYCLES_PER_LOOP;
|
||||
|
||||
// wait for any previous pulse to end
|
||||
while ((*reg & bit) == stateMask)
|
||||
if (numloops++ == maxloops)
|
||||
return 0;
|
||||
|
||||
// wait for the pulse to start
|
||||
while ((*reg & bit) != stateMask)
|
||||
if (numloops++ == maxloops)
|
||||
return 0;
|
||||
|
||||
// wait for the pulse to stop
|
||||
while ((*reg & bit) == stateMask) {
|
||||
width++;
|
||||
if (numloops++ == maxloops)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// convert the reading to microseconds. The loop has been determined
|
||||
// to be PULSEIN_CYCLES_LATENCY clock cycles long and have about
|
||||
// PULSEIN_CYCLES_PER_LOOP clocks between the edge and the start of
|
||||
// the loop. There will be some error introduced by the interrupt
|
||||
// handlers.
|
||||
//return clockCyclesToMicroseconds(PULSEIN_CYCLES_PER_LOOP * width + PULSEIN_CYCLES_LATENCY);
|
||||
return (width * PULSEIN_CYCLES_PER_LOOP + PULSEIN_CYCLES_LATENCY + (clockCyclesPerMicrosecond() / 2)) / clockCyclesPerMicrosecond();
|
||||
}
|
||||
|
||||
|
||||
112
teensy/wiring.h
Normal file
112
teensy/wiring.h
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
wiring.h - Partial implementation of the Wiring API for the ATmega8.
|
||||
Part of Arduino - http://www.arduino.cc/
|
||||
|
||||
Copyright (c) 2005-2006 David A. Mellis
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General
|
||||
Public License along with this library; if not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
|
||||
$Id: wiring.h 387 2008-03-08 21:30:00Z mellis $
|
||||
*/
|
||||
|
||||
#ifndef Wiring_h
|
||||
#define Wiring_h
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "binary.h"
|
||||
#include "core_id.h"
|
||||
#include "core_pins.h"
|
||||
#ifdef ID
|
||||
#undef ID // ID bit in USBSTA conflicts with user's code
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
#define PI 3.1415926535897932384626433832795
|
||||
#define HALF_PI 1.5707963267948966192313216916398
|
||||
#define TWO_PI 6.283185307179586476925286766559
|
||||
#define DEG_TO_RAD 0.017453292519943295769236907684886
|
||||
#define RAD_TO_DEG 57.295779513082320876798154814105
|
||||
|
||||
#define SERIAL 0
|
||||
#define DISPLAY 1
|
||||
|
||||
#define CHANGE 1
|
||||
#define FALLING 2
|
||||
#define RISING 3
|
||||
|
||||
#define INTERNAL 3
|
||||
#define INTERNAL2V56 3
|
||||
#define DEFAULT 1
|
||||
#define EXTERNAL 0
|
||||
|
||||
// undefine stdlib's abs if encountered
|
||||
#ifdef abs
|
||||
#undef abs
|
||||
#endif
|
||||
|
||||
#define min(a,b) ((a)<(b)?(a):(b))
|
||||
#define max(a,b) ((a)>(b)?(a):(b))
|
||||
#define abs(x) ((x)>0?(x):-(x))
|
||||
#define constrain(amt,low,high) ((amt)<(low)?(low):((amt)>(high)?(high):(amt)))
|
||||
#define round(x) ((x)>=0?(long)((x)+0.5):(long)((x)-0.5))
|
||||
#define radians(deg) ((deg)*DEG_TO_RAD)
|
||||
#define degrees(rad) ((rad)*RAD_TO_DEG)
|
||||
#define sq(x) ((x)*(x))
|
||||
|
||||
#define interrupts() sei()
|
||||
#define noInterrupts() cli()
|
||||
|
||||
#define clockCyclesPerMicrosecond() ( F_CPU / 1000000L )
|
||||
#define clockCyclesToMicroseconds(a) ( (a) / clockCyclesPerMicrosecond() )
|
||||
#define microsecondsToClockCycles(a) ( (a) * clockCyclesPerMicrosecond() )
|
||||
|
||||
#define lowByte(w) ((uint8_t)((w) & 0xFF))
|
||||
#define highByte(w) ((uint8_t)((w) >> 8))
|
||||
|
||||
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
|
||||
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
|
||||
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
|
||||
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
|
||||
|
||||
typedef unsigned int word;
|
||||
|
||||
#define bit(b) (1UL << (b))
|
||||
|
||||
typedef uint8_t boolean;
|
||||
typedef uint8_t byte;
|
||||
|
||||
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout);
|
||||
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, byte val);
|
||||
|
||||
void attachInterrupt(uint8_t, void (*)(void), uint8_t mode);
|
||||
void detachInterrupt(uint8_t);
|
||||
|
||||
void setup(void);
|
||||
void loop(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
72
teensy/wiring_private.h
Normal file
72
teensy/wiring_private.h
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
wiring_private.h - Internal header file.
|
||||
Part of Arduino - http://www.arduino.cc/
|
||||
|
||||
Copyright (c) 2005-2006 David A. Mellis
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General
|
||||
Public License along with this library; if not, write to the
|
||||
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
|
||||
$Id: wiring.h 239 2007-01-12 17:58:39Z mellis $
|
||||
*/
|
||||
|
||||
#ifndef WiringPrivate_h
|
||||
#define WiringPrivate_h
|
||||
|
||||
#include <avr/io.h>
|
||||
#include <avr/interrupt.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "wiring.h"
|
||||
|
||||
#if F_CPU == 16000000L
|
||||
#define ADC_PRESCALER 0x07
|
||||
#define CPU_PRESCALER 0x00
|
||||
#elif F_CPU == 8000000L
|
||||
#define ADC_PRESCALER 0x06
|
||||
#define CPU_PRESCALER 0x01
|
||||
#elif F_CPU == 4000000L
|
||||
#define ADC_PRESCALER 0x05
|
||||
#define CPU_PRESCALER 0x02
|
||||
#elif F_CPU == 2000000L
|
||||
#define ADC_PRESCALER 0x04
|
||||
#define CPU_PRESCALER 0x03
|
||||
#elif F_CPU == 1000000L
|
||||
#define ADC_PRESCALER 0x03
|
||||
#define CPU_PRESCALER 0x04
|
||||
#else
|
||||
#error "Teensyduino only supports 16, 8, 4, 2, 1 MHz. Please edit boards.txt"
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
#ifndef cbi
|
||||
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
|
||||
#endif
|
||||
#ifndef sbi
|
||||
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
|
||||
#endif
|
||||
|
||||
typedef void (*voidFuncPtr)(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
2
teensy3/Arduino.h
Normal file
2
teensy3/Arduino.h
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
#include "WProgram.h"
|
||||
#include "pins_arduino.h"
|
||||
213
teensy3/AudioStream.cpp
Normal file
213
teensy3/AudioStream.cpp
Normal file
|
|
@ -0,0 +1,213 @@
|
|||
/* Teensyduino Core Library
|
||||
* http://www.pjrc.com/teensy/
|
||||
* Copyright (c) 2013 PJRC.COM, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* 1. The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* 2. If the Software is incorporated into a build system that allows
|
||||
* selection among a list of target devices, then similar target
|
||||
* devices manufactured by PJRC.COM must be included in the list of
|
||||
* target devices and selectable in the same manner.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#include "AudioStream.h"
|
||||
|
||||
|
||||
audio_block_t * AudioStream::memory_pool;
|
||||
uint8_t AudioStream::memory_pool_size = 0;
|
||||
uint32_t AudioStream::memory_pool_available_mask;
|
||||
|
||||
uint16_t AudioStream::cpu_cycles_total = 0;
|
||||
uint16_t AudioStream::cpu_cycles_total_max = 0;
|
||||
uint8_t AudioStream::memory_used = 0;
|
||||
uint8_t AudioStream::memory_used_max = 0;
|
||||
|
||||
|
||||
|
||||
// Set up the pool of audio data blocks
|
||||
// placing them all onto the free list
|
||||
void AudioStream::initialize_memory(audio_block_t *data, unsigned int num)
|
||||
{
|
||||
//Serial.println("AudioStream initialize_memory");
|
||||
memory_pool = data;
|
||||
if (num > 31) num = 31;
|
||||
memory_pool_size = num;
|
||||
memory_pool_available_mask = 0xFFFFFFFF;
|
||||
for (unsigned int i=0; i < num; i++) {
|
||||
data[i].memory_pool_index = i;
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate 1 audio data block. If successful
|
||||
// the caller is the only owner of this new block
|
||||
audio_block_t * AudioStream::allocate(void)
|
||||
{
|
||||
uint32_t n, avail;
|
||||
audio_block_t *block;
|
||||
uint8_t used;
|
||||
|
||||
__disable_irq();
|
||||
avail = memory_pool_available_mask;
|
||||
n = __builtin_clz(avail);
|
||||
if (n >= memory_pool_size) {
|
||||
__enable_irq();
|
||||
return NULL;
|
||||
}
|
||||
memory_pool_available_mask = avail & ~(0x80000000 >> n);
|
||||
used = memory_used + 1;
|
||||
memory_used = used;
|
||||
__enable_irq();
|
||||
block = memory_pool + n;
|
||||
block->ref_count = 1;
|
||||
if (used > memory_used_max) memory_used_max = used;
|
||||
return block;
|
||||
}
|
||||
|
||||
// Release ownership of a data block. If no
|
||||
// other streams have ownership, the block is
|
||||
// returned to the free pool
|
||||
void AudioStream::release(audio_block_t *block)
|
||||
{
|
||||
uint32_t mask = (0x80000000 >> block->memory_pool_index);
|
||||
__disable_irq();
|
||||
if (block->ref_count > 1) {
|
||||
block->ref_count--;
|
||||
} else {
|
||||
memory_pool_available_mask |= mask;
|
||||
memory_used--;
|
||||
}
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
// Transmit an audio data block
|
||||
// to all streams that connect to an output. The block
|
||||
// becomes owned by all the recepients, but also is still
|
||||
// owned by this object. Normally, a block is released
|
||||
// after it's transmitted.
|
||||
void AudioStream::transmit(audio_block_t *block, unsigned char index)
|
||||
{
|
||||
for (AudioConnection *c = destination_list; c != NULL; c = c->next_dest) {
|
||||
if (c->src_index == index) {
|
||||
if (c->dst.inputQueue[c->dest_index] == NULL) {
|
||||
c->dst.inputQueue[c->dest_index] = block;
|
||||
block->ref_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Receive block from an input. The block's data
|
||||
// may be shared with other streams, so it must not be written
|
||||
audio_block_t * AudioStream::receiveReadOnly(unsigned int index)
|
||||
{
|
||||
audio_block_t *in;
|
||||
|
||||
if (index >= num_inputs) return NULL;
|
||||
in = inputQueue[index];
|
||||
inputQueue[index] = NULL;
|
||||
return in;
|
||||
}
|
||||
|
||||
// Receive block from an input. The block will not
|
||||
// be shared, so its contents may be changed.
|
||||
audio_block_t * AudioStream::receiveWritable(unsigned int index)
|
||||
{
|
||||
audio_block_t *in, *p;
|
||||
|
||||
if (index >= num_inputs) return NULL;
|
||||
in = inputQueue[index];
|
||||
inputQueue[index] = NULL;
|
||||
if (in && in->ref_count > 1) {
|
||||
p = allocate();
|
||||
if (p) memcpy(p->data, in->data, sizeof(p->data));
|
||||
in->ref_count--;
|
||||
in = p;
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
|
||||
void AudioConnection::connect(void)
|
||||
{
|
||||
AudioConnection *p;
|
||||
|
||||
if (dest_index > dst.num_inputs) return;
|
||||
__disable_irq();
|
||||
p = src.destination_list;
|
||||
if (p == NULL) {
|
||||
src.destination_list = this;
|
||||
} else {
|
||||
while (p->next_dest) p = p->next_dest;
|
||||
p->next_dest = this;
|
||||
}
|
||||
src.active = true;
|
||||
dst.active = true;
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// When an object has taken responsibility for calling update_all()
|
||||
// at each block interval (approx 2.9ms), this variable is set to
|
||||
// true. Objects that are capable of calling update_all(), typically
|
||||
// input and output based on interrupts, must check this variable in
|
||||
// their constructors.
|
||||
bool AudioStream::update_scheduled = false;
|
||||
|
||||
bool AudioStream::update_setup(void)
|
||||
{
|
||||
if (update_scheduled) return false;
|
||||
NVIC_SET_PRIORITY(IRQ_SOFTWARE, 0xFF); // 0xFF = lowest priority
|
||||
NVIC_ENABLE_IRQ(IRQ_SOFTWARE);
|
||||
update_scheduled = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
AudioStream * AudioStream::first_update = NULL;
|
||||
|
||||
void software_isr(void) // AudioStream::update_all()
|
||||
{
|
||||
AudioStream *p;
|
||||
|
||||
ARM_DEMCR |= ARM_DEMCR_TRCENA;
|
||||
ARM_DWT_CTRL |= ARM_DWT_CTRL_CYCCNTENA;
|
||||
uint32_t totalcycles = ARM_DWT_CYCCNT;
|
||||
//digitalWriteFast(2, HIGH);
|
||||
for (p = AudioStream::first_update; p; p = p->next_update) {
|
||||
if (p->active) {
|
||||
uint32_t cycles = ARM_DWT_CYCCNT;
|
||||
p->update();
|
||||
// TODO: traverse inputQueueArray and release
|
||||
// any input blocks that weren't consumed?
|
||||
cycles = (ARM_DWT_CYCCNT - cycles) >> 4;
|
||||
p->cpu_cycles = cycles;
|
||||
if (cycles > p->cpu_cycles_max) p->cpu_cycles_max = cycles;
|
||||
}
|
||||
}
|
||||
//digitalWriteFast(2, LOW);
|
||||
totalcycles = (ARM_DWT_CYCCNT - totalcycles) >> 4;;
|
||||
AudioStream::cpu_cycles_total = totalcycles;
|
||||
if (totalcycles > AudioStream::cpu_cycles_total_max)
|
||||
AudioStream::cpu_cycles_total_max = totalcycles;
|
||||
}
|
||||
|
||||
147
teensy3/AudioStream.h
Normal file
147
teensy3/AudioStream.h
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
/* Teensyduino Core Library
|
||||
* http://www.pjrc.com/teensy/
|
||||
* Copyright (c) 2013 PJRC.COM, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* 1. The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* 2. If the Software is incorporated into a build system that allows
|
||||
* selection among a list of target devices, then similar target
|
||||
* devices manufactured by PJRC.COM must be included in the list of
|
||||
* target devices and selectable in the same manner.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef AudioStream_h
|
||||
#define AudioStream_h
|
||||
|
||||
#include "Arduino.h"
|
||||
|
||||
#define AUDIO_BLOCK_SAMPLES 128
|
||||
#define AUDIO_SAMPLE_RATE 44100
|
||||
#define AUDIO_SAMPLE_RATE_EXACT 44117.64706 // 48 MHz / 1088, or 96 MHz * 2 / 17 / 256
|
||||
|
||||
class AudioStream;
|
||||
class AudioConnection;
|
||||
|
||||
typedef struct audio_block_struct {
|
||||
unsigned char ref_count;
|
||||
unsigned char memory_pool_index;
|
||||
int16_t data[AUDIO_BLOCK_SAMPLES];
|
||||
} audio_block_t;
|
||||
|
||||
|
||||
class AudioConnection
|
||||
{
|
||||
public:
|
||||
AudioConnection(AudioStream &source, AudioStream &destination) :
|
||||
src(source), dst(destination), src_index(0), dest_index(0),
|
||||
next_dest(NULL)
|
||||
{ connect(); }
|
||||
AudioConnection(AudioStream &source, unsigned char sourceOutput,
|
||||
AudioStream &destination, unsigned char destinationInput) :
|
||||
src(source), dst(destination),
|
||||
src_index(sourceOutput), dest_index(destinationInput),
|
||||
next_dest(NULL)
|
||||
{ connect(); }
|
||||
friend class AudioStream;
|
||||
protected:
|
||||
void connect(void);
|
||||
AudioStream &src;
|
||||
AudioStream &dst;
|
||||
unsigned char src_index;
|
||||
unsigned char dest_index;
|
||||
AudioConnection *next_dest;
|
||||
};
|
||||
|
||||
|
||||
#define AudioMemory(num) ({ \
|
||||
static DMAMEM audio_block_t data[num]; \
|
||||
AudioStream::initialize_memory(data, num); \
|
||||
})
|
||||
|
||||
#define CYCLE_COUNTER_APPROX_PERCENT(n) (((n) + (F_CPU / 32 / AUDIO_SAMPLE_RATE * AUDIO_BLOCK_SAMPLES / 100)) / (F_CPU / 16 / AUDIO_SAMPLE_RATE * AUDIO_BLOCK_SAMPLES / 100))
|
||||
|
||||
#define AudioProcessorUsage() (CYCLE_COUNTER_APPROX_PERCENT(AudioStream::cpu_cycles_total))
|
||||
#define AudioProcessorUsageMax() (CYCLE_COUNTER_APPROX_PERCENT(AudioStream::cpu_cycles_total_max))
|
||||
#define AudioProcessorUsageMaxReset() (AudioStream::cpu_cycles_total_max = AudioStream::cpu_cycles_total)
|
||||
#define AudioMemoryUsage() (AudioStream::memory_used)
|
||||
#define AudioMemoryUsageMax() (AudioStream::memory_used_max)
|
||||
#define AudioMemoryUsageMaxReset() (AudioStream::memory_used_max = AudioStream::memory_used)
|
||||
|
||||
class AudioStream
|
||||
{
|
||||
public:
|
||||
AudioStream(unsigned char ninput, audio_block_t **iqueue) :
|
||||
num_inputs(ninput), inputQueue(iqueue) {
|
||||
active = false;
|
||||
destination_list = NULL;
|
||||
for (int i=0; i < num_inputs; i++) {
|
||||
inputQueue[i] = NULL;
|
||||
}
|
||||
// add to a simple list, for update_all
|
||||
// TODO: replace with a proper data flow analysis in update_all
|
||||
if (first_update == NULL) {
|
||||
first_update = this;
|
||||
} else {
|
||||
AudioStream *p;
|
||||
for (p=first_update; p->next_update; p = p->next_update) ;
|
||||
p->next_update = this;
|
||||
}
|
||||
next_update = NULL;
|
||||
cpu_cycles = 0;
|
||||
cpu_cycles_max = 0;
|
||||
}
|
||||
void connect(AudioStream &dest, unsigned char dest_index = 0, unsigned int src_index = 0);
|
||||
void disconnect(void);
|
||||
static void initialize_memory(audio_block_t *data, unsigned int num);
|
||||
int processorUsage(void) { return CYCLE_COUNTER_APPROX_PERCENT(cpu_cycles); }
|
||||
int processorUsageMax(void) { return CYCLE_COUNTER_APPROX_PERCENT(cpu_cycles_max); }
|
||||
void processorUsageMaxReset(void) { cpu_cycles_max = cpu_cycles; }
|
||||
uint16_t cpu_cycles;
|
||||
uint16_t cpu_cycles_max;
|
||||
static uint16_t cpu_cycles_total;
|
||||
static uint16_t cpu_cycles_total_max;
|
||||
static uint8_t memory_used;
|
||||
static uint8_t memory_used_max;
|
||||
protected:
|
||||
bool active;
|
||||
unsigned char num_inputs;
|
||||
static audio_block_t * allocate(void);
|
||||
static void release(audio_block_t * block);
|
||||
void transmit(audio_block_t *block, unsigned char index = 0);
|
||||
audio_block_t * receiveReadOnly(unsigned int index = 0);
|
||||
audio_block_t * receiveWritable(unsigned int index = 0);
|
||||
static bool update_setup(void);
|
||||
static void update_all(void) { NVIC_SET_PENDING(IRQ_SOFTWARE); }
|
||||
friend void software_isr(void);
|
||||
friend class AudioConnection;
|
||||
private:
|
||||
AudioConnection *destination_list;
|
||||
audio_block_t **inputQueue;
|
||||
static bool update_scheduled;
|
||||
virtual void update(void) = 0;
|
||||
static AudioStream *first_update; // for update_all
|
||||
AudioStream *next_update; // for update_all
|
||||
static audio_block_t *memory_pool;
|
||||
static uint8_t memory_pool_size;
|
||||
static uint32_t memory_pool_available_mask;
|
||||
};
|
||||
|
||||
#endif
|
||||
29
teensy3/Client.h
Normal file
29
teensy3/Client.h
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#if ARDUINO >= 100
|
||||
|
||||
#ifndef client_h
|
||||
#define client_h
|
||||
#include "Print.h"
|
||||
#include "Stream.h"
|
||||
#include "IPAddress.h"
|
||||
|
||||
class Client : public Stream {
|
||||
|
||||
public:
|
||||
virtual int connect(IPAddress ip, uint16_t port) =0;
|
||||
virtual int connect(const char *host, uint16_t port) =0;
|
||||
virtual size_t write(uint8_t) =0;
|
||||
virtual size_t write(const uint8_t *buf, size_t size) =0;
|
||||
virtual int available() = 0;
|
||||
virtual int read() = 0;
|
||||
virtual int read(uint8_t *buf, size_t size) = 0;
|
||||
virtual int peek() = 0;
|
||||
virtual void flush() = 0;
|
||||
virtual void stop() = 0;
|
||||
virtual uint8_t connected() = 0;
|
||||
virtual operator bool() = 0;
|
||||
protected:
|
||||
uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); };
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
158
teensy3/HardwareSerial.h
Normal file
158
teensy3/HardwareSerial.h
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
/* Teensyduino Core Library
|
||||
* http://www.pjrc.com/teensy/
|
||||
* Copyright (c) 2013 PJRC.COM, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* 1. The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* 2. If the Software is incorporated into a build system that allows
|
||||
* selection among a list of target devices, then similar target
|
||||
* devices manufactured by PJRC.COM must be included in the list of
|
||||
* target devices and selectable in the same manner.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef HardwareSerial_h
|
||||
#define HardwareSerial_h
|
||||
|
||||
#include "mk20dx128.h"
|
||||
#include <inttypes.h>
|
||||
|
||||
#define BAUD2DIV(baud) (((F_CPU * 2) + ((baud) >> 1)) / (baud))
|
||||
#define BAUD2DIV3(baud) (((F_BUS * 2) + ((baud) >> 1)) / (baud))
|
||||
|
||||
// C language implementation
|
||||
//
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void serial_begin(uint32_t divisor);
|
||||
void serial_end(void);
|
||||
void serial_putchar(uint8_t c);
|
||||
void serial_write(const void *buf, unsigned int count);
|
||||
void serial_flush(void);
|
||||
int serial_available(void);
|
||||
int serial_getchar(void);
|
||||
int serial_peek(void);
|
||||
void serial_clear(void);
|
||||
void serial_print(const char *p);
|
||||
void serial_phex(uint32_t n);
|
||||
void serial_phex16(uint32_t n);
|
||||
void serial_phex32(uint32_t n);
|
||||
|
||||
void serial2_begin(uint32_t divisor);
|
||||
void serial2_end(void);
|
||||
void serial2_putchar(uint8_t c);
|
||||
void serial2_write(const void *buf, unsigned int count);
|
||||
void serial2_flush(void);
|
||||
int serial2_available(void);
|
||||
int serial2_getchar(void);
|
||||
int serial2_peek(void);
|
||||
void serial2_clear(void);
|
||||
|
||||
void serial3_begin(uint32_t divisor);
|
||||
void serial3_end(void);
|
||||
void serial3_putchar(uint8_t c);
|
||||
void serial3_write(const void *buf, unsigned int count);
|
||||
void serial3_flush(void);
|
||||
int serial3_available(void);
|
||||
int serial3_getchar(void);
|
||||
int serial3_peek(void);
|
||||
void serial3_clear(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// C++ interface
|
||||
//
|
||||
#ifdef __cplusplus
|
||||
#include "Stream.h"
|
||||
class HardwareSerial : public Stream
|
||||
{
|
||||
public:
|
||||
void begin(uint32_t baud) { serial_begin(BAUD2DIV(baud)); }
|
||||
void end(void) { serial_end(); }
|
||||
virtual int available(void) { return serial_available(); }
|
||||
virtual int peek(void) { return serial_peek(); }
|
||||
virtual int read(void) { return serial_getchar(); }
|
||||
virtual void flush(void) { serial_flush(); }
|
||||
void clear(void) { serial_clear(); }
|
||||
virtual size_t write(uint8_t c) { serial_putchar(c); return 1; }
|
||||
size_t write(unsigned long n) { return write((uint8_t)n); }
|
||||
size_t write(long n) { return write((uint8_t)n); }
|
||||
size_t write(unsigned int n) { return write((uint8_t)n); }
|
||||
size_t write(int n) { return write((uint8_t)n); }
|
||||
virtual size_t write(const uint8_t *buffer, size_t size)
|
||||
{ serial_write(buffer, size); return size; }
|
||||
size_t write(const char *str) { size_t len = strlen(str);
|
||||
serial_write((const uint8_t *)str, len);
|
||||
return len; }
|
||||
};
|
||||
extern HardwareSerial Serial1;
|
||||
|
||||
class HardwareSerial2 : public HardwareSerial
|
||||
{
|
||||
public:
|
||||
void begin(uint32_t baud) { serial2_begin(BAUD2DIV(baud)); }
|
||||
void end(void) { serial2_end(); }
|
||||
virtual int available(void) { return serial2_available(); }
|
||||
virtual int peek(void) { return serial2_peek(); }
|
||||
virtual int read(void) { return serial2_getchar(); }
|
||||
virtual void flush(void) { serial2_flush(); }
|
||||
void clear(void) { serial2_clear(); }
|
||||
virtual size_t write(uint8_t c) { serial2_putchar(c); return 1; }
|
||||
size_t write(unsigned long n) { return write((uint8_t)n); }
|
||||
size_t write(long n) { return write((uint8_t)n); }
|
||||
size_t write(unsigned int n) { return write((uint8_t)n); }
|
||||
size_t write(int n) { return write((uint8_t)n); }
|
||||
virtual size_t write(const uint8_t *buffer, size_t size)
|
||||
{ serial2_write(buffer, size); return size; }
|
||||
size_t write(const char *str) { size_t len = strlen(str);
|
||||
serial2_write((const uint8_t *)str, len);
|
||||
return len; }
|
||||
};
|
||||
extern HardwareSerial2 Serial2;
|
||||
|
||||
class HardwareSerial3 : public HardwareSerial
|
||||
{
|
||||
public:
|
||||
void begin(uint32_t baud) { serial3_begin(BAUD2DIV3(baud)); }
|
||||
void end(void) { serial3_end(); }
|
||||
virtual int available(void) { return serial3_available(); }
|
||||
virtual int peek(void) { return serial3_peek(); }
|
||||
virtual int read(void) { return serial3_getchar(); }
|
||||
virtual void flush(void) { serial3_flush(); }
|
||||
void clear(void) { serial3_clear(); }
|
||||
virtual size_t write(uint8_t c) { serial3_putchar(c); return 1; }
|
||||
size_t write(unsigned long n) { return write((uint8_t)n); }
|
||||
size_t write(long n) { return write((uint8_t)n); }
|
||||
size_t write(unsigned int n) { return write((uint8_t)n); }
|
||||
size_t write(int n) { return write((uint8_t)n); }
|
||||
virtual size_t write(const uint8_t *buffer, size_t size)
|
||||
{ serial3_write(buffer, size); return size; }
|
||||
size_t write(const char *str) { size_t len = strlen(str);
|
||||
serial3_write((const uint8_t *)str, len);
|
||||
return len; }
|
||||
};
|
||||
extern HardwareSerial3 Serial3;
|
||||
|
||||
#endif
|
||||
#endif
|
||||
4
teensy3/HardwareSerial1.cpp
Normal file
4
teensy3/HardwareSerial1.cpp
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#include "HardwareSerial.h"
|
||||
|
||||
HardwareSerial Serial1;
|
||||
|
||||
4
teensy3/HardwareSerial2.cpp
Normal file
4
teensy3/HardwareSerial2.cpp
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#include "HardwareSerial.h"
|
||||
|
||||
HardwareSerial2 Serial2;
|
||||
|
||||
4
teensy3/HardwareSerial3.cpp
Normal file
4
teensy3/HardwareSerial3.cpp
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#include "HardwareSerial.h"
|
||||
|
||||
HardwareSerial3 Serial3;
|
||||
|
||||
57
teensy3/IPAddress.cpp
Normal file
57
teensy3/IPAddress.cpp
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
#if ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
#include "IPAddress.h"
|
||||
|
||||
IPAddress::IPAddress()
|
||||
{
|
||||
memset(_address, 0, sizeof(_address));
|
||||
}
|
||||
|
||||
IPAddress::IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet)
|
||||
{
|
||||
_address[0] = first_octet;
|
||||
_address[1] = second_octet;
|
||||
_address[2] = third_octet;
|
||||
_address[3] = fourth_octet;
|
||||
}
|
||||
|
||||
IPAddress::IPAddress(uint32_t address)
|
||||
{
|
||||
memcpy(_address, &address, sizeof(_address));
|
||||
}
|
||||
|
||||
IPAddress::IPAddress(const uint8_t *address)
|
||||
{
|
||||
memcpy(_address, address, sizeof(_address));
|
||||
}
|
||||
|
||||
IPAddress& IPAddress::operator=(const uint8_t *address)
|
||||
{
|
||||
memcpy(_address, address, sizeof(_address));
|
||||
return *this;
|
||||
}
|
||||
|
||||
IPAddress& IPAddress::operator=(uint32_t address)
|
||||
{
|
||||
memcpy(_address, (const uint8_t *)&address, sizeof(_address));
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool IPAddress::operator==(const uint8_t* addr)
|
||||
{
|
||||
return memcmp(addr, _address, sizeof(_address)) == 0;
|
||||
}
|
||||
|
||||
size_t IPAddress::printTo(Print& p) const
|
||||
{
|
||||
size_t n = 0;
|
||||
for (int i =0; i < 3; i++)
|
||||
{
|
||||
n += p.print(_address[i], DEC);
|
||||
n += p.print('.');
|
||||
}
|
||||
n += p.print(_address[3], DEC);
|
||||
return n;
|
||||
}
|
||||
|
||||
#endif
|
||||
82
teensy3/IPAddress.h
Normal file
82
teensy3/IPAddress.h
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
*
|
||||
* MIT License:
|
||||
* Copyright (c) 2011 Adrian McEwen
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* adrianm@mcqn.com 1/1/2011
|
||||
*/
|
||||
|
||||
#if ARDUINO >= 100
|
||||
#ifndef IPAddress_h
|
||||
#define IPAddress_h
|
||||
|
||||
#include <Printable.h>
|
||||
|
||||
// A class to make it easier to handle and pass around IP addresses
|
||||
|
||||
class IPAddress : public Printable {
|
||||
private:
|
||||
uint8_t _address[4]; // IPv4 address
|
||||
// Access the raw byte array containing the address. Because this returns a pointer
|
||||
// to the internal structure rather than a copy of the address this function should only
|
||||
// be used when you know that the usage of the returned uint8_t* will be transient and not
|
||||
// stored.
|
||||
uint8_t* raw_address() { return _address; };
|
||||
|
||||
public:
|
||||
// Constructors
|
||||
IPAddress();
|
||||
IPAddress(uint8_t first_octet, uint8_t second_octet, uint8_t third_octet, uint8_t fourth_octet);
|
||||
IPAddress(uint32_t address);
|
||||
IPAddress(const uint8_t *address);
|
||||
|
||||
// Overloaded cast operator to allow IPAddress objects to be used where a pointer
|
||||
// to a four-byte uint8_t array is expected
|
||||
operator uint32_t () { return _address[0] | (_address[1] << 8)
|
||||
| (_address[2] << 16) | (_address[3] << 24); }
|
||||
bool operator==(const IPAddress& addr) { return _address[0] == addr._address[0]
|
||||
&& _address[1] == addr._address[1]
|
||||
&& _address[2] == addr._address[2]
|
||||
&& _address[3] == addr._address[3]; }
|
||||
bool operator==(const uint8_t* addr);
|
||||
|
||||
// Overloaded index operator to allow getting and setting individual octets of the address
|
||||
uint8_t operator[](int index) const { return _address[index]; };
|
||||
uint8_t& operator[](int index) { return _address[index]; };
|
||||
|
||||
// Overloaded copy operators to allow initialisation of IPAddress objects from other types
|
||||
IPAddress& operator=(const uint8_t *address);
|
||||
IPAddress& operator=(uint32_t address);
|
||||
|
||||
virtual size_t printTo(Print& p) const;
|
||||
|
||||
friend class EthernetClass;
|
||||
friend class UDP;
|
||||
friend class Client;
|
||||
friend class Server;
|
||||
friend class DhcpClass;
|
||||
friend class DNSClient;
|
||||
};
|
||||
|
||||
const IPAddress INADDR_NONE(0,0,0,0);
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
185
teensy3/IntervalTimer.cpp
Normal file
185
teensy3/IntervalTimer.cpp
Normal file
|
|
@ -0,0 +1,185 @@
|
|||
/* Copyright (c) 2013 Daniel Gilbert, loglow@gmail.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
|
||||
|
||||
#include "IntervalTimer.h"
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// static class variables need to be reiterated here before use
|
||||
// ------------------------------------------------------------
|
||||
bool IntervalTimer::PIT_enabled;
|
||||
bool IntervalTimer::PIT_used[];
|
||||
IntervalTimer::ISR IntervalTimer::PIT_ISR[];
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// these are the ISRs (Interrupt Service Routines) that get
|
||||
// called by each PIT timer when it fires. they're defined here
|
||||
// so that they can auto-clear themselves and so the user can
|
||||
// specify a custom ISR and reassign it as needed
|
||||
// ------------------------------------------------------------
|
||||
void pit0_isr() { PIT_TFLG0 = 1; IntervalTimer::PIT_ISR[0](); }
|
||||
void pit1_isr() { PIT_TFLG1 = 1; IntervalTimer::PIT_ISR[1](); }
|
||||
void pit2_isr() { PIT_TFLG2 = 1; IntervalTimer::PIT_ISR[2](); }
|
||||
void pit3_isr() { PIT_TFLG3 = 1; IntervalTimer::PIT_ISR[3](); }
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// this function inits and starts the timer, using the specified
|
||||
// function as a callback and the period provided. must be passed
|
||||
// the name of a function taking no arguments and returning void.
|
||||
// make sure this function can complete within the time allowed.
|
||||
// attempts to allocate a timer using available resources,
|
||||
// returning true on success or false in case of failure.
|
||||
// period is specified as number of bus cycles
|
||||
// ------------------------------------------------------------
|
||||
bool IntervalTimer::beginCycles(ISR newISR, uint32_t newValue) {
|
||||
|
||||
// if this interval timer is already running, stop it
|
||||
if (status == TIMER_PIT) {
|
||||
stop_PIT();
|
||||
status = TIMER_OFF;
|
||||
}
|
||||
// store callback pointer
|
||||
myISR = newISR;
|
||||
|
||||
// attempt to allocate this timer
|
||||
if (allocate_PIT(newValue)) status = TIMER_PIT;
|
||||
else status = TIMER_OFF;
|
||||
|
||||
// check for success and return
|
||||
if (status != TIMER_OFF) return true;
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// stop the timer if it's currently running, using its status
|
||||
// to determine what hardware resources the timer may be using
|
||||
// ------------------------------------------------------------
|
||||
void IntervalTimer::end() {
|
||||
if (status == TIMER_PIT) stop_PIT();
|
||||
status = TIMER_OFF;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// enables the PIT clock bit, the master PIT reg, and sets flag
|
||||
// ------------------------------------------------------------
|
||||
void IntervalTimer::enable_PIT() {
|
||||
SIM_SCGC6 |= SIM_SCGC6_PIT;
|
||||
PIT_MCR = 0;
|
||||
PIT_enabled = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// disables the master PIT reg, the PIT clock bit, and unsets flag
|
||||
// ------------------------------------------------------------
|
||||
void IntervalTimer::disable_PIT() {
|
||||
PIT_MCR = 1;
|
||||
SIM_SCGC6 &= ~SIM_SCGC6_PIT;
|
||||
PIT_enabled = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// enables the PIT clock if not already enabled, then checks to
|
||||
// see if any PITs are available for use. if one is available,
|
||||
// it's initialized and started with the specified value, and
|
||||
// the function returns true, otherwise it returns false
|
||||
// ------------------------------------------------------------
|
||||
bool IntervalTimer::allocate_PIT(uint32_t newValue) {
|
||||
|
||||
// enable clock to the PIT module if necessary
|
||||
if (!PIT_enabled) enable_PIT();
|
||||
|
||||
// check for an available PIT, and if so, start it
|
||||
for (uint8_t id = 0; id < NUM_PIT; id++) {
|
||||
if (!PIT_used[id]) {
|
||||
PIT_id = id;
|
||||
start_PIT(newValue);
|
||||
PIT_used[id] = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// no PIT available
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// configuters a PIT's registers, function pointer, and enables
|
||||
// interrupts, effectively starting the timer upon completion
|
||||
// ------------------------------------------------------------
|
||||
void IntervalTimer::start_PIT(uint32_t newValue) {
|
||||
|
||||
// point to the correct registers
|
||||
PIT_LDVAL = &PIT_LDVAL0 + PIT_id * 4;
|
||||
PIT_TCTRL = &PIT_TCTRL0 + PIT_id * 4;
|
||||
IRQ_PIT_CH = IRQ_PIT_CH0 + PIT_id;
|
||||
|
||||
// point to the correct PIT ISR
|
||||
PIT_ISR[PIT_id] = myISR;
|
||||
|
||||
// write value to register and enable interrupt
|
||||
*PIT_TCTRL = 0;
|
||||
*PIT_LDVAL = newValue;
|
||||
*PIT_TCTRL = 3;
|
||||
NVIC_ENABLE_IRQ(IRQ_PIT_CH);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// stops an active PIT by disabling its interrupt, writing to
|
||||
// its control register, and freeing up its state for future use.
|
||||
// also, if no PITs remain in use, disables the core PIT clock
|
||||
// ------------------------------------------------------------
|
||||
void IntervalTimer::stop_PIT() {
|
||||
|
||||
// disable interrupt and PIT
|
||||
NVIC_DISABLE_IRQ(IRQ_PIT_CH);
|
||||
*PIT_TCTRL = 0;
|
||||
|
||||
// free PIT for future use
|
||||
PIT_used[PIT_id] = false;
|
||||
|
||||
// check if we're still using any PIT
|
||||
for (uint8_t id = 0; id < NUM_PIT; id++) {
|
||||
if (PIT_used[id]) return;
|
||||
}
|
||||
|
||||
// none used, disable PIT clock
|
||||
disable_PIT();
|
||||
|
||||
}
|
||||
|
||||
|
||||
88
teensy3/IntervalTimer.h
Normal file
88
teensy3/IntervalTimer.h
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/* Copyright (c) 2013 Daniel Gilbert, loglow@gmail.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in the
|
||||
Software without restriction, including without limitation the rights to use, copy,
|
||||
modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
and to permit persons to whom the Software is furnished to do so, subject to the
|
||||
following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
|
||||
|
||||
#ifndef __INTERVALTIMER_H__
|
||||
#define __INTERVALTIMER_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "mk20dx128.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
class IntervalTimer {
|
||||
private:
|
||||
typedef void (*ISR)();
|
||||
typedef volatile uint32_t* reg;
|
||||
enum {TIMER_OFF, TIMER_PIT};
|
||||
static const uint8_t NUM_PIT = 4;
|
||||
static const uint32_t MAX_PERIOD = UINT32_MAX / (F_BUS / 1000000.0);
|
||||
static void enable_PIT();
|
||||
static void disable_PIT();
|
||||
static bool PIT_enabled;
|
||||
static bool PIT_used[NUM_PIT];
|
||||
bool allocate_PIT(uint32_t newValue);
|
||||
void start_PIT(uint32_t newValue);
|
||||
void stop_PIT();
|
||||
bool status;
|
||||
uint8_t PIT_id;
|
||||
reg PIT_LDVAL;
|
||||
reg PIT_TCTRL;
|
||||
uint8_t IRQ_PIT_CH;
|
||||
ISR myISR;
|
||||
bool beginCycles(ISR newISR, uint32_t cycles);
|
||||
public:
|
||||
IntervalTimer() { status = TIMER_OFF; }
|
||||
~IntervalTimer() { end(); }
|
||||
bool begin(ISR newISR, unsigned int newPeriod) {
|
||||
if (newPeriod == 0 || newPeriod > MAX_PERIOD) return false;
|
||||
uint32_t newValue = (F_BUS / 1000000) * newPeriod - 1;
|
||||
return beginCycles(newISR, newValue);
|
||||
}
|
||||
bool begin(ISR newISR, int newPeriod) {
|
||||
if (newPeriod < 0) return false;
|
||||
return begin(newISR, (unsigned int)newPeriod);
|
||||
}
|
||||
bool begin(ISR newISR, unsigned long newPeriod) {
|
||||
return begin(newISR, (unsigned int)newPeriod);
|
||||
}
|
||||
bool begin(ISR newISR, long newPeriod) {
|
||||
return begin(newISR, (int)newPeriod);
|
||||
}
|
||||
bool begin(ISR newISR, float newPeriod) {
|
||||
if (newPeriod <= 0 || newPeriod > MAX_PERIOD) return false;
|
||||
uint32_t newValue = (float)(F_BUS / 1000000) * newPeriod + 0.5;
|
||||
if (newValue < 40) return false;
|
||||
return beginCycles(newISR, newValue);
|
||||
}
|
||||
bool begin(ISR newISR, double newPeriod) {
|
||||
return begin(newISR, (float)newPeriod);
|
||||
}
|
||||
void end();
|
||||
static ISR PIT_ISR[NUM_PIT];
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
81
teensy3/Makefile
Normal file
81
teensy3/Makefile
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
|
||||
# The name of your project (used to name the compiled .hex file)
|
||||
TARGET = main
|
||||
|
||||
# configurable options
|
||||
OPTIONS = -DF_CPU=48000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH
|
||||
|
||||
# options needed by many Arduino libraries to configure for Teensy 3.0
|
||||
OPTIONS += -D__MK20DX128__ -DARDUIO=104
|
||||
|
||||
|
||||
#************************************************************************
|
||||
# Location of Teensyduino utilities, Toolchain, and Arduino Libraries.
|
||||
# To use this makefile without Arduino, copy the resources from these
|
||||
# locations and edit the pathnames. The rest of Arduino is not needed.
|
||||
#************************************************************************
|
||||
|
||||
# path location for Teensy Loader, teensy_post_compile and teensy_reboot
|
||||
TOOLSPATH = ../../../tools # on Linux
|
||||
#TOOLSPATH = ../../../tools/avr/bin # on Mac or Windows
|
||||
|
||||
# path location for Arduino libraries (currently not used)
|
||||
LIBRARYPATH = ../../../../libraries
|
||||
|
||||
# path location for the arm-none-eabi compiler
|
||||
COMPILERPATH = ../../../tools/arm-none-eabi/bin
|
||||
|
||||
#************************************************************************
|
||||
# Settings below this point usually do not need to be edited
|
||||
#************************************************************************
|
||||
|
||||
# CPPFLAGS = compiler options for C and C++
|
||||
CPPFLAGS = -Wall -g -Os -mcpu=cortex-m4 -mthumb -nostdlib -MMD $(OPTIONS) -I.
|
||||
|
||||
# compiler options for C++ only
|
||||
CXXFLAGS = -std=gnu++0x -felide-constructors -fno-exceptions -fno-rtti
|
||||
|
||||
# compiler options for C only
|
||||
CFLAGS =
|
||||
|
||||
# linker options
|
||||
LDFLAGS = -Os -Wl,--gc-sections -mcpu=cortex-m4 -mthumb -Tmk20dx128.ld
|
||||
|
||||
# additional libraries to link
|
||||
LIBS = -lm
|
||||
|
||||
|
||||
# names for the compiler programs
|
||||
CC = $(abspath $(COMPILERPATH))/arm-none-eabi-gcc
|
||||
CXX = $(abspath $(COMPILERPATH))/arm-none-eabi-g++
|
||||
OBJCOPY = $(abspath $(COMPILERPATH))/arm-none-eabi-objcopy
|
||||
SIZE = $(abspath $(COMPILERPATH))/arm-none-eabi-size
|
||||
|
||||
# automatically create lists of the sources and objects
|
||||
# TODO: this does not handle Arduino libraries yet...
|
||||
C_FILES := $(wildcard *.c)
|
||||
CPP_FILES := $(wildcard *.cpp)
|
||||
OBJS := $(C_FILES:.c=.o) $(CPP_FILES:.cpp=.o)
|
||||
|
||||
|
||||
# the actual makefile rules (all .o files built by GNU make's default implicit rules)
|
||||
|
||||
all: $(TARGET).hex
|
||||
|
||||
$(TARGET).elf: $(OBJS) mk20dx128.ld
|
||||
$(CC) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
|
||||
|
||||
%.hex: %.elf
|
||||
$(SIZE) $<
|
||||
$(OBJCOPY) -O ihex -R .eeprom $< $@
|
||||
$(abspath $(TOOLSPATH))/teensy_post_compile -file=$(basename $@) -path=$(shell pwd) -tools=$(abspath $(TOOLSPATH))
|
||||
-$(abspath $(TOOLSPATH))/teensy_reboot
|
||||
|
||||
|
||||
# compiler generated dependency info
|
||||
-include $(OBJS:.o=.d)
|
||||
|
||||
clean:
|
||||
rm -f *.o *.d $(TARGET).elf $(TARGET).hex
|
||||
|
||||
|
||||
157
teensy3/Print.cpp
Normal file
157
teensy3/Print.cpp
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
Print.cpp - Base class that provides print() and println()
|
||||
Copyright (c) 2008 David A. Mellis. All right reserved.
|
||||
many modifications, by Paul Stoffregen <paul@pjrc.com>
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Modified 23 November 2006 by David A. Mellis
|
||||
*/
|
||||
|
||||
//#include <stdio.h>
|
||||
//#include <string.h>
|
||||
#include <inttypes.h>
|
||||
//#include <math.h>
|
||||
//#include <avr/pgmspace.h>
|
||||
//#include "wiring.h"
|
||||
|
||||
#include "Print.h"
|
||||
|
||||
|
||||
|
||||
size_t Print::write(const uint8_t *buffer, size_t size)
|
||||
{
|
||||
size_t count = 0;
|
||||
while (size--) count += write(*buffer++);
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
size_t Print::print(const String &s)
|
||||
{
|
||||
uint8_t buffer[33];
|
||||
size_t count = 0;
|
||||
unsigned int index = 0;
|
||||
unsigned int len = s.length();
|
||||
while (len > 0) {
|
||||
s.getBytes(buffer, sizeof(buffer), index);
|
||||
unsigned int nbytes = len;
|
||||
if (nbytes > sizeof(buffer)-1) nbytes = sizeof(buffer)-1;
|
||||
index += nbytes;
|
||||
len -= nbytes;
|
||||
count += write(buffer, nbytes);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
size_t Print::print(long n)
|
||||
{
|
||||
uint8_t sign=0;
|
||||
|
||||
if (n < 0) {
|
||||
sign = '-';
|
||||
n = -n;
|
||||
}
|
||||
return printNumber(n, 10, sign);
|
||||
}
|
||||
|
||||
|
||||
size_t Print::println(void)
|
||||
{
|
||||
uint8_t buf[2]={'\r', '\n'};
|
||||
return write(buf, 2);
|
||||
}
|
||||
|
||||
|
||||
size_t Print::printNumber(unsigned long n, uint8_t base, uint8_t sign)
|
||||
{
|
||||
uint8_t buf[34];
|
||||
uint8_t digit, i;
|
||||
|
||||
// TODO: make these checks as inline, since base is
|
||||
// almost always a constant. base = 0 (BYTE) should
|
||||
// inline as a call directly to write()
|
||||
if (base == 0) {
|
||||
return write((uint8_t)n);
|
||||
} else if (base == 1) {
|
||||
base = 10;
|
||||
}
|
||||
|
||||
|
||||
if (n == 0) {
|
||||
buf[sizeof(buf) - 1] = '0';
|
||||
i = sizeof(buf) - 1;
|
||||
} else {
|
||||
i = sizeof(buf) - 1;
|
||||
while (1) {
|
||||
digit = n % base;
|
||||
buf[i] = ((digit < 10) ? '0' + digit : 'A' + digit - 10);
|
||||
n /= base;
|
||||
if (n == 0) break;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
if (sign) {
|
||||
i--;
|
||||
buf[i] = '-';
|
||||
}
|
||||
return write(buf + i, sizeof(buf) - i);
|
||||
}
|
||||
|
||||
|
||||
size_t Print::printFloat(double number, uint8_t digits)
|
||||
{
|
||||
uint8_t sign=0;
|
||||
size_t count=0;
|
||||
|
||||
// Handle negative numbers
|
||||
if (number < 0.0) {
|
||||
sign = 1;
|
||||
number = -number;
|
||||
}
|
||||
|
||||
// Round correctly so that print(1.999, 2) prints as "2.00"
|
||||
double rounding = 0.5;
|
||||
for (uint8_t i=0; i<digits; ++i) {
|
||||
rounding *= 0.1;
|
||||
}
|
||||
number += rounding;
|
||||
|
||||
// Extract the integer part of the number and print it
|
||||
unsigned long int_part = (unsigned long)number;
|
||||
double remainder = number - (double)int_part;
|
||||
count += printNumber(int_part, 10, sign);
|
||||
|
||||
// Print the decimal point, but only if there are digits beyond
|
||||
if (digits > 0) {
|
||||
uint8_t n, buf[8], count=1;
|
||||
buf[0] = '.';
|
||||
|
||||
// Extract digits from the remainder one at a time
|
||||
if (digits > sizeof(buf) - 1) digits = sizeof(buf) - 1;
|
||||
|
||||
while (digits-- > 0) {
|
||||
remainder *= 10.0;
|
||||
n = (uint8_t)(remainder);
|
||||
buf[count++] = '0' + n;
|
||||
remainder -= n;
|
||||
}
|
||||
count += write(buf, count);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
105
teensy3/Print.h
Normal file
105
teensy3/Print.h
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
/* Teensyduino Core Library
|
||||
* http://www.pjrc.com/teensy/
|
||||
* Copyright (c) 2013 PJRC.COM, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* 1. The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* 2. If the Software is incorporated into a build system that allows
|
||||
* selection among a list of target devices, then similar target
|
||||
* devices manufactured by PJRC.COM must be included in the list of
|
||||
* target devices and selectable in the same manner.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef Print_h
|
||||
#define Print_h
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h> // for size_t - gives sprintf and other stuff to all sketches & libs
|
||||
#include "core_id.h"
|
||||
#include "WString.h"
|
||||
#include "Printable.h"
|
||||
|
||||
#define DEC 10
|
||||
#define HEX 16
|
||||
#define OCT 8
|
||||
#define BIN 2
|
||||
#define BYTE 0
|
||||
|
||||
class __FlashStringHelper;
|
||||
|
||||
class Print
|
||||
{
|
||||
public:
|
||||
Print() : write_error(0) {}
|
||||
virtual size_t write(uint8_t b) = 0;
|
||||
size_t write(const char *str) { return write((const uint8_t *)str, strlen(str)); }
|
||||
virtual size_t write(const uint8_t *buffer, size_t size);
|
||||
size_t print(const String &s);
|
||||
size_t print(char c) { return write((uint8_t)c); }
|
||||
size_t print(const char s[]) { return write(s); }
|
||||
size_t print(const __FlashStringHelper *f) { return write((const char *)f); }
|
||||
|
||||
size_t print(uint8_t b) { return printNumber(b, 10, 0); }
|
||||
size_t print(int n) { return print((long)n); }
|
||||
size_t print(unsigned int n) { return printNumber(n, 10, 0); }
|
||||
size_t print(long n);
|
||||
size_t print(unsigned long n) { return printNumber(n, 10, 0); }
|
||||
|
||||
size_t print(unsigned char n, int base) { return printNumber(n, base, 0); }
|
||||
size_t print(int n, int base) { return (base == 10) ? print(n) : printNumber(n, base, 0); }
|
||||
size_t print(unsigned int n, int base) { return printNumber(n, base, 0); }
|
||||
size_t print(long n, int base) { return (base == 10) ? print(n) : printNumber(n, base, 0); }
|
||||
size_t print(unsigned long n, int base) { return printNumber(n, base, 0); }
|
||||
|
||||
size_t print(double n, int digits = 2) { return printFloat(n, digits); }
|
||||
size_t print(const Printable &obj) { return obj.printTo(*this); }
|
||||
size_t println(void);
|
||||
size_t println(const String &s) { return print(s) + println(); }
|
||||
size_t println(char c) { return print(c) + println(); }
|
||||
size_t println(const char s[]) { return print(s) + println(); }
|
||||
size_t println(const __FlashStringHelper *f) { return print(f) + println(); }
|
||||
|
||||
size_t println(uint8_t b) { return print(b) + println(); }
|
||||
size_t println(int n) { return print(n) + println(); }
|
||||
size_t println(unsigned int n) { return print(n) + println(); }
|
||||
size_t println(long n) { return print(n) + println(); }
|
||||
size_t println(unsigned long n) { return print(n) + println(); }
|
||||
|
||||
size_t println(unsigned char n, int base) { return print(n, base) + println(); }
|
||||
size_t println(int n, int base) { return print(n, base) + println(); }
|
||||
size_t println(unsigned int n, int base) { return print(n, base) + println(); }
|
||||
size_t println(long n, int base) { return print(n, base) + println(); }
|
||||
size_t println(unsigned long n, int base) { return print(n, base) + println(); }
|
||||
|
||||
size_t println(double n, int digits = 2) { return print(n, digits) + println(); }
|
||||
size_t println(const Printable &obj) { return obj.printTo(*this) + println(); }
|
||||
int getWriteError() { return write_error; }
|
||||
void clearWriteError() { setWriteError(0); }
|
||||
size_t printNumber(unsigned long n, uint8_t base, uint8_t sign);
|
||||
protected:
|
||||
void setWriteError(int err = 1) { write_error = err; }
|
||||
private:
|
||||
char write_error;
|
||||
size_t printFloat(double n, uint8_t digits);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
55
teensy3/Printable.h
Normal file
55
teensy3/Printable.h
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
Printable.h - Interface class that allows printing of complex types
|
||||
Copyright (c) 2011 Adrian McEwen. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef Printable_h
|
||||
#define Printable_h
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
inline void * operator new(unsigned int size) __attribute__((always_inline, unused));
|
||||
inline void * operator new(unsigned int size)
|
||||
{
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
inline void operator delete(void * ptr) __attribute__((always_inline, unused));
|
||||
inline void operator delete(void * ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
|
||||
class Print;
|
||||
|
||||
/** The Printable class provides a way for new classes to allow themselves to be printed.
|
||||
By deriving from Printable and implementing the printTo method, it will then be possible
|
||||
for users to print out instances of this class by passing them into the usual
|
||||
Print::print and Print::println methods.
|
||||
*/
|
||||
class Printable
|
||||
{
|
||||
public:
|
||||
virtual size_t printTo(Print& p) const = 0;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
#endif
|
||||
12
teensy3/Server.h
Normal file
12
teensy3/Server.h
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#if ARDUINO >= 100
|
||||
|
||||
#ifndef server_h
|
||||
#define server_h
|
||||
|
||||
class Server : public Print {
|
||||
public:
|
||||
virtual void begin() =0;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
312
teensy3/Stream.cpp
Normal file
312
teensy3/Stream.cpp
Normal file
|
|
@ -0,0 +1,312 @@
|
|||
/*
|
||||
Stream.cpp - adds parsing methods to Stream class
|
||||
Copyright (c) 2008 David A. Mellis. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Created July 2011
|
||||
parsing functions based on TextFinder library by Michael Margolis
|
||||
*/
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "Stream.h"
|
||||
|
||||
#define PARSE_TIMEOUT 1000 // default number of milli-seconds to wait
|
||||
#define NO_SKIP_CHAR 1 // a magic char not found in a valid ASCII numeric field
|
||||
|
||||
// private method to read stream with timeout
|
||||
int Stream::timedRead()
|
||||
{
|
||||
int c;
|
||||
unsigned long startMillis = millis();
|
||||
do {
|
||||
c = read();
|
||||
if (c >= 0) return c;
|
||||
yield();
|
||||
} while(millis() - startMillis < _timeout);
|
||||
return -1; // -1 indicates timeout
|
||||
}
|
||||
|
||||
// private method to peek stream with timeout
|
||||
int Stream::timedPeek()
|
||||
{
|
||||
int c;
|
||||
unsigned long startMillis = millis();
|
||||
do {
|
||||
c = peek();
|
||||
if (c >= 0) return c;
|
||||
yield();
|
||||
} while(millis() - startMillis < _timeout);
|
||||
return -1; // -1 indicates timeout
|
||||
}
|
||||
|
||||
// returns peek of the next digit in the stream or -1 if timeout
|
||||
// discards non-numeric characters
|
||||
int Stream::peekNextDigit()
|
||||
{
|
||||
int c;
|
||||
while (1) {
|
||||
c = timedPeek();
|
||||
if (c < 0) return c; // timeout
|
||||
if (c == '-') return c;
|
||||
if (c >= '0' && c <= '9') return c;
|
||||
read(); // discard non-numeric
|
||||
}
|
||||
}
|
||||
|
||||
// Public Methods
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
void Stream::setTimeout(unsigned long timeout) // sets the maximum number of milliseconds to wait
|
||||
{
|
||||
_timeout = timeout;
|
||||
}
|
||||
|
||||
// find returns true if the target string is found
|
||||
bool Stream::find(char *target)
|
||||
{
|
||||
return findUntil(target, NULL);
|
||||
}
|
||||
|
||||
// reads data from the stream until the target string of given length is found
|
||||
// returns true if target string is found, false if timed out
|
||||
bool Stream::find(char *target, size_t length)
|
||||
{
|
||||
return findUntil(target, length, NULL, 0);
|
||||
}
|
||||
|
||||
// as find but search ends if the terminator string is found
|
||||
bool Stream::findUntil(char *target, char *terminator)
|
||||
{
|
||||
return findUntil(target, strlen(target), terminator, strlen(terminator));
|
||||
}
|
||||
|
||||
// reads data from the stream until the target string of the given length is found
|
||||
// search terminated if the terminator string is found
|
||||
// returns true if target string is found, false if terminated or timed out
|
||||
bool Stream::findUntil(char *target, size_t targetLen, char *terminator, size_t termLen)
|
||||
{
|
||||
size_t index = 0; // maximum target string length is 64k bytes!
|
||||
size_t termIndex = 0;
|
||||
int c;
|
||||
|
||||
if( *target == 0)
|
||||
return true; // return true if target is a null string
|
||||
while( (c = timedRead()) > 0){
|
||||
if( c == target[index]){
|
||||
//////Serial.print("found "); Serial.write(c); Serial.print("index now"); Serial.println(index+1);
|
||||
if(++index >= targetLen){ // return true if all chars in the target match
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else{
|
||||
index = 0; // reset index if any char does not match
|
||||
}
|
||||
if(termLen > 0 && c == terminator[termIndex]){
|
||||
if(++termIndex >= termLen)
|
||||
return false; // return false if terminate string found before target string
|
||||
}
|
||||
else
|
||||
termIndex = 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// returns the first valid (long) integer value from the current position.
|
||||
// initial characters that are not digits (or the minus sign) are skipped
|
||||
// function is terminated by the first character that is not a digit.
|
||||
long Stream::parseInt()
|
||||
{
|
||||
return parseInt(NO_SKIP_CHAR); // terminate on first non-digit character (or timeout)
|
||||
}
|
||||
|
||||
// as above but a given skipChar is ignored
|
||||
// this allows format characters (typically commas) in values to be ignored
|
||||
long Stream::parseInt(char skipChar)
|
||||
{
|
||||
boolean isNegative = false;
|
||||
long value = 0;
|
||||
int c;
|
||||
|
||||
c = peekNextDigit();
|
||||
// ignore non numeric leading characters
|
||||
if(c < 0)
|
||||
return 0; // zero returned if timeout
|
||||
|
||||
do{
|
||||
if(c == skipChar)
|
||||
; // ignore this charactor
|
||||
else if(c == '-')
|
||||
isNegative = true;
|
||||
else if(c >= '0' && c <= '9') // is c a digit?
|
||||
value = value * 10 + c - '0';
|
||||
read(); // consume the character we got with peek
|
||||
c = timedPeek();
|
||||
}
|
||||
while( (c >= '0' && c <= '9') || c == skipChar );
|
||||
|
||||
if(isNegative)
|
||||
value = -value;
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
// as parseInt but returns a floating point value
|
||||
float Stream::parseFloat()
|
||||
{
|
||||
return parseFloat(NO_SKIP_CHAR);
|
||||
}
|
||||
|
||||
// as above but the given skipChar is ignored
|
||||
// this allows format characters (typically commas) in values to be ignored
|
||||
float Stream::parseFloat(char skipChar){
|
||||
boolean isNegative = false;
|
||||
boolean isFraction = false;
|
||||
long value = 0;
|
||||
char c;
|
||||
float fraction = 1.0;
|
||||
|
||||
c = peekNextDigit();
|
||||
// ignore non numeric leading characters
|
||||
if(c < 0)
|
||||
return 0; // zero returned if timeout
|
||||
|
||||
do{
|
||||
if(c == skipChar)
|
||||
; // ignore
|
||||
else if(c == '-')
|
||||
isNegative = true;
|
||||
else if (c == '.')
|
||||
isFraction = true;
|
||||
else if(c >= '0' && c <= '9') { // is c a digit?
|
||||
value = value * 10 + c - '0';
|
||||
if(isFraction)
|
||||
fraction *= 0.1;
|
||||
}
|
||||
read(); // consume the character we got with peek
|
||||
c = timedPeek();
|
||||
}
|
||||
while( (c >= '0' && c <= '9') || c == '.' || c == skipChar );
|
||||
|
||||
if(isNegative)
|
||||
value = -value;
|
||||
if(isFraction)
|
||||
return value * fraction;
|
||||
else
|
||||
return value;
|
||||
}
|
||||
|
||||
// read characters from stream into buffer
|
||||
// terminates if length characters have been read, or timeout (see setTimeout)
|
||||
// returns the number of characters placed in the buffer
|
||||
// the buffer is NOT null terminated.
|
||||
//
|
||||
size_t Stream::readBytes(char *buffer, size_t length)
|
||||
{
|
||||
size_t count = 0;
|
||||
while (count < length) {
|
||||
int c = timedRead();
|
||||
if (c < 0) {
|
||||
setReadError();
|
||||
break;
|
||||
}
|
||||
*buffer++ = (char)c;
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
// as readBytes with terminator character
|
||||
// terminates if length characters have been read, timeout, or if the terminator character detected
|
||||
// returns the number of characters placed in the buffer (0 means no valid data found)
|
||||
|
||||
size_t Stream::readBytesUntil(char terminator, char *buffer, size_t length)
|
||||
{
|
||||
if (length < 1) return 0;
|
||||
length--;
|
||||
size_t index = 0;
|
||||
while (index < length) {
|
||||
int c = timedRead();
|
||||
if (c == terminator) break;
|
||||
if (c < 0) {
|
||||
setReadError();
|
||||
break;
|
||||
}
|
||||
*buffer++ = (char)c;
|
||||
index++;
|
||||
}
|
||||
*buffer = 0;
|
||||
return index; // return number of characters, not including null terminator
|
||||
}
|
||||
|
||||
String Stream::readString(size_t max)
|
||||
{
|
||||
String str;
|
||||
size_t length = str.length();
|
||||
while (length < max) {
|
||||
int c = timedRead();
|
||||
if (c < 0) {
|
||||
setReadError();
|
||||
break; // timeout
|
||||
}
|
||||
if (c == 0) break;
|
||||
str += (char)c;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
String Stream::readStringUntil(char terminator, size_t max)
|
||||
{
|
||||
String str;
|
||||
size_t length = str.length();
|
||||
while (length < max) {
|
||||
int c = timedRead();
|
||||
if (c < 0) {
|
||||
setReadError();
|
||||
break; // timeout
|
||||
}
|
||||
if (c == 0 || c == terminator) break;
|
||||
str += (char)c;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
60
teensy3/Stream.h
Normal file
60
teensy3/Stream.h
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
Stream.h - base class for character-based streams.
|
||||
Copyright (c) 2010 David A. Mellis. All right reserved.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef Stream_h
|
||||
#define Stream_h
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "Print.h"
|
||||
|
||||
class Stream : public Print
|
||||
{
|
||||
public:
|
||||
Stream() : _timeout(1000), read_error(0) {}
|
||||
virtual int available() = 0;
|
||||
virtual int read() = 0;
|
||||
virtual int peek() = 0;
|
||||
virtual void flush() = 0;
|
||||
|
||||
void setTimeout(unsigned long timeout);
|
||||
bool find(char *target);
|
||||
bool find(char *target, size_t length);
|
||||
bool findUntil(char *target, char *terminator);
|
||||
bool findUntil(char *target, size_t targetLen, char *terminate, size_t termLen);
|
||||
long parseInt();
|
||||
long parseInt(char skipChar);
|
||||
float parseFloat();
|
||||
float parseFloat(char skipChar);
|
||||
size_t readBytes(char *buffer, size_t length);
|
||||
size_t readBytesUntil(char terminator, char *buffer, size_t length);
|
||||
String readString(size_t max = 120);
|
||||
String readStringUntil(char terminator, size_t max = 120);
|
||||
int getReadError() { return read_error; }
|
||||
void clearReadError() { setReadError(0); }
|
||||
protected:
|
||||
void setReadError(int err = 1) { read_error = err; }
|
||||
unsigned long _timeout;
|
||||
private:
|
||||
char read_error;
|
||||
int timedRead();
|
||||
int timedPeek();
|
||||
int peekNextDigit();
|
||||
};
|
||||
|
||||
#endif
|
||||
214
teensy3/Tone.cpp
Normal file
214
teensy3/Tone.cpp
Normal file
|
|
@ -0,0 +1,214 @@
|
|||
/* Teensyduino Core Library
|
||||
* http://www.pjrc.com/teensy/
|
||||
* Copyright (c) 2013 PJRC.COM, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* 1. The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* 2. If the Software is incorporated into a build system that allows
|
||||
* selection among a list of target devices, then similar target
|
||||
* devices manufactured by PJRC.COM must be included in the list of
|
||||
* target devices and selectable in the same manner.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "core_pins.h"
|
||||
#include "pins_arduino.h"
|
||||
#include "HardwareSerial.h"
|
||||
#include "IntervalTimer.h"
|
||||
|
||||
#if 1
|
||||
// IntervalTimer based tone. This allows tone() to share the timers with other
|
||||
// libraries, rather than permanently hogging one PIT timer even for projects
|
||||
// which never use tone(). Someday this single-tone implementation might be
|
||||
// changed to allow multiple simultaneous tones.
|
||||
|
||||
static uint32_t tone_toggle_count;
|
||||
static volatile uint8_t *tone_reg;
|
||||
static uint8_t tone_pin=255;
|
||||
static uint16_t tone_frequency=0;
|
||||
IntervalTimer tone_timer;
|
||||
|
||||
void tone_interrupt(void);
|
||||
|
||||
void tone(uint8_t pin, uint16_t frequency, uint32_t duration)
|
||||
{
|
||||
uint32_t count;
|
||||
volatile uint32_t *config;
|
||||
float usec;
|
||||
|
||||
if (pin >= CORE_NUM_DIGITAL) return;
|
||||
if (duration) {
|
||||
count = (frequency * duration / 1000) * 2;
|
||||
} else {
|
||||
count = 0xFFFFFFFF;
|
||||
}
|
||||
usec = (float)500000.0 / (float)frequency;
|
||||
config = portConfigRegister(pin);
|
||||
|
||||
// TODO: IntervalTimer really needs an API to disable and enable
|
||||
// the interrupt on a single timer.
|
||||
__disable_irq();
|
||||
if (pin == tone_pin) {
|
||||
if (frequency == tone_frequency) {
|
||||
// same pin, same frequency, so just update the
|
||||
// duration. Users will call repetitively call
|
||||
// tone() with the same setting, expecting a
|
||||
// continuous output with no glitches or phase
|
||||
// changes or jitter at each call.
|
||||
tone_toggle_count = count;
|
||||
} else {
|
||||
// same pin, but a new frequency.
|
||||
tone_reg[0] = 1; // clear pin
|
||||
tone_timer.begin(tone_interrupt, usec);
|
||||
}
|
||||
} else {
|
||||
if (tone_pin < CORE_NUM_DIGITAL) {
|
||||
tone_reg[0] = 1; // clear pin
|
||||
}
|
||||
tone_pin = pin;
|
||||
tone_reg = portClearRegister(pin);
|
||||
tone_reg[0] = 1; // clear pin
|
||||
tone_reg[384] = 1; // output mode;
|
||||
*config = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
|
||||
tone_toggle_count = count;
|
||||
tone_timer.begin(tone_interrupt, usec);
|
||||
}
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
|
||||
void tone_interrupt(void)
|
||||
{
|
||||
if (tone_toggle_count) {
|
||||
tone_reg[128] = 1; // toggle
|
||||
if (tone_toggle_count < 0xFFFFFFFF) tone_toggle_count--;
|
||||
} else {
|
||||
tone_timer.end();
|
||||
tone_reg[0] = 0; // clear
|
||||
tone_pin = 255;
|
||||
tone_frequency = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void noTone(uint8_t pin)
|
||||
{
|
||||
if (pin >= CORE_NUM_DIGITAL) return;
|
||||
__disable_irq();
|
||||
if (pin == tone_pin) {
|
||||
tone_timer.end();
|
||||
tone_reg[0] = 0; // clear
|
||||
tone_pin = 255;
|
||||
tone_frequency = 0;
|
||||
}
|
||||
__enable_irq();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
// Old PIT timer based tone(). This implementation is slightly more efficient,
|
||||
// but it consumes one of the PIT timers, even for projects which never use tone().
|
||||
|
||||
static uint32_t tone_toggle_count;
|
||||
static volatile uint8_t *tone_reg;
|
||||
static uint8_t tone_pin;
|
||||
|
||||
void init_tone(void)
|
||||
{
|
||||
if (SIM_SCGC6 & SIM_SCGC6_PIT) return;
|
||||
SIM_SCGC6 |= SIM_SCGC6_PIT; // TODO: use bitband for atomic read-mod-write
|
||||
PIT_MCR = 0;
|
||||
PIT_TCTRL3 = 0; // disabled
|
||||
tone_pin = 255;
|
||||
NVIC_ENABLE_IRQ(IRQ_PIT_CH3);
|
||||
}
|
||||
|
||||
void tone(uint8_t pin, uint16_t frequency, uint32_t duration)
|
||||
{
|
||||
uint32_t count, load;
|
||||
volatile uint32_t *config;
|
||||
|
||||
init_tone();
|
||||
if (pin >= CORE_NUM_DIGITAL) return;
|
||||
if (duration) {
|
||||
count = (frequency * duration / 1000) * 2;
|
||||
} else {
|
||||
count = 0xFFFFFFFF;
|
||||
}
|
||||
load = (F_BUS / 2) / frequency;
|
||||
config = portConfigRegister(pin);
|
||||
__disable_irq();
|
||||
if (pin != tone_pin) {
|
||||
if (tone_pin < CORE_NUM_DIGITAL) {
|
||||
tone_reg[0] = 1; // clear pin
|
||||
}
|
||||
tone_pin = pin;
|
||||
tone_reg = portClearRegister(pin);
|
||||
tone_reg[0] = 1; // clear pin
|
||||
tone_reg[384] = 1; // output mode;
|
||||
*config = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
|
||||
}
|
||||
tone_toggle_count = count;
|
||||
if (PIT_LDVAL3 != load) {
|
||||
PIT_TCTRL3 = 0;
|
||||
PIT_LDVAL3 = load;
|
||||
PIT_TCTRL3 = 3;
|
||||
}
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
void pit3_isr(void)
|
||||
{
|
||||
PIT_TFLG3 = 1;
|
||||
|
||||
if (tone_toggle_count) {
|
||||
tone_reg[128] = 1; // toggle
|
||||
if (tone_toggle_count < 0xFFFFFFFF) tone_toggle_count--;
|
||||
} else {
|
||||
PIT_TCTRL3 = 0;
|
||||
PIT_LDVAL3 = 0;
|
||||
tone_reg[0] = 0; // clear
|
||||
tone_pin = 255;
|
||||
}
|
||||
}
|
||||
|
||||
void noTone(uint8_t pin)
|
||||
{
|
||||
if (pin >= CORE_NUM_DIGITAL) return;
|
||||
__disable_irq();
|
||||
if (pin == tone_pin) {
|
||||
PIT_TCTRL3 = 0;
|
||||
PIT_LDVAL3 = 0;
|
||||
tone_reg[0] = 0; // clear
|
||||
tone_pin = 255;
|
||||
}
|
||||
__enable_irq();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
91
teensy3/Udp.h
Normal file
91
teensy3/Udp.h
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Udp.cpp: Library to send/receive UDP packets.
|
||||
*
|
||||
* NOTE: UDP is fast, but has some important limitations (thanks to Warren Gray for mentioning these)
|
||||
* 1) UDP does not guarantee the order in which assembled UDP packets are received. This
|
||||
* might not happen often in practice, but in larger network topologies, a UDP
|
||||
* packet can be received out of sequence.
|
||||
* 2) UDP does not guard against lost packets - so packets *can* disappear without the sender being
|
||||
* aware of it. Again, this may not be a concern in practice on small local networks.
|
||||
* For more information, see http://www.cafeaulait.org/course/week12/35.html
|
||||
*
|
||||
* MIT License:
|
||||
* Copyright (c) 2008 Bjoern Hartmann
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
* bjoern@cs.stanford.edu 12/30/2008
|
||||
*/
|
||||
|
||||
#if ARDUINO >= 100
|
||||
|
||||
#ifndef udp_h
|
||||
#define udp_h
|
||||
|
||||
#include <Stream.h>
|
||||
#include <IPAddress.h>
|
||||
|
||||
class UDP : public Stream {
|
||||
|
||||
public:
|
||||
virtual uint8_t begin(uint16_t) =0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use
|
||||
virtual void stop() =0; // Finish with the UDP socket
|
||||
|
||||
// Sending UDP packets
|
||||
|
||||
// Start building up a packet to send to the remote host specific in ip and port
|
||||
// Returns 1 if successful, 0 if there was a problem with the supplied IP address or port
|
||||
virtual int beginPacket(IPAddress ip, uint16_t port) =0;
|
||||
// Start building up a packet to send to the remote host specific in host and port
|
||||
// Returns 1 if successful, 0 if there was a problem resolving the hostname or port
|
||||
virtual int beginPacket(const char *host, uint16_t port) =0;
|
||||
// Finish off this packet and send it
|
||||
// Returns 1 if the packet was sent successfully, 0 if there was an error
|
||||
virtual int endPacket() =0;
|
||||
// Write a single byte into the packet
|
||||
virtual size_t write(uint8_t) =0;
|
||||
// Write size bytes from buffer into the packet
|
||||
virtual size_t write(const uint8_t *buffer, size_t size) =0;
|
||||
|
||||
// Start processing the next available incoming packet
|
||||
// Returns the size of the packet in bytes, or 0 if no packets are available
|
||||
virtual int parsePacket() =0;
|
||||
// Number of bytes remaining in the current packet
|
||||
virtual int available() =0;
|
||||
// Read a single byte from the current packet
|
||||
virtual int read() =0;
|
||||
// Read up to len bytes from the current packet and place them into buffer
|
||||
// Returns the number of bytes read, or 0 if none are available
|
||||
virtual int read(unsigned char* buffer, size_t len) =0;
|
||||
// Read up to len characters from the current packet and place them into buffer
|
||||
// Returns the number of characters read, or 0 if none are available
|
||||
virtual int read(char* buffer, size_t len) =0;
|
||||
// Return the next byte from the current packet without moving on to the next byte
|
||||
virtual int peek() =0;
|
||||
virtual void flush() =0; // Finish reading the current packet
|
||||
|
||||
// Return the IP address of the host who sent the current incoming packet
|
||||
virtual IPAddress remoteIP() =0;
|
||||
// Return the port of the host who sent the current incoming packet
|
||||
virtual uint16_t remotePort() =0;
|
||||
protected:
|
||||
uint8_t* rawIPAddress(IPAddress& addr) { return addr.raw_address(); };
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
168
teensy3/WCharacter.h
Normal file
168
teensy3/WCharacter.h
Normal 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
teensy3/WConstants.h
Normal file
1
teensy3/WConstants.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
#include "wiring.h"
|
||||
50
teensy3/WMath.cpp
Normal file
50
teensy3/WMath.cpp
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
#include <stdint.h>
|
||||
|
||||
static uint32_t seed;
|
||||
|
||||
void randomSeed(uint32_t newseed)
|
||||
{
|
||||
if (newseed > 0) seed = newseed;
|
||||
}
|
||||
|
||||
void srandom(uint32_t newseed)
|
||||
{
|
||||
seed = newseed;
|
||||
}
|
||||
|
||||
uint32_t random(void)
|
||||
{
|
||||
int32_t hi, lo, x;
|
||||
|
||||
// the algorithm used in avr-libc 1.6.4
|
||||
x = seed;
|
||||
if (x == 0) x = 123459876;
|
||||
hi = x / 127773;
|
||||
lo = x % 127773;
|
||||
x = 16807 * lo - 2836 * hi;
|
||||
if (x < 0) x += 0x7FFFFFFF;
|
||||
seed = x;
|
||||
return x;
|
||||
}
|
||||
|
||||
uint32_t random(uint32_t howbig)
|
||||
{
|
||||
if (howbig == 0) return 0;
|
||||
return random() % howbig;
|
||||
}
|
||||
|
||||
int32_t random(int32_t howsmall, int32_t howbig)
|
||||
{
|
||||
if (howsmall >= howbig) return howsmall;
|
||||
int32_t diff = howbig - howsmall;
|
||||
return random(diff) + howsmall;
|
||||
}
|
||||
|
||||
long map(long x, long in_min, long in_max, long out_min, long out_max)
|
||||
{
|
||||
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
|
||||
}
|
||||
|
||||
unsigned int makeWord(unsigned int w) { return w; }
|
||||
unsigned int makeWord(unsigned char h, unsigned char l) { return (h << 8) | l; }
|
||||
|
||||
59
teensy3/WProgram.h
Normal file
59
teensy3/WProgram.h
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
#ifndef WProgram_h
|
||||
#define WProgram_h
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
// some libraries and sketches depend on this
|
||||
// AVR stuff, assuming Arduino.h or WProgram.h
|
||||
// automatically includes it...
|
||||
#include <avr/pgmspace.h>
|
||||
#include <avr/interrupt.h>
|
||||
|
||||
#include "avr_functions.h"
|
||||
#include "wiring.h"
|
||||
#include "HardwareSerial.h"
|
||||
|
||||
#define DMAMEM __attribute__ ((section(".dmabuffers"), used))
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "avr_emulation.h"
|
||||
#include "usb_serial.h"
|
||||
#include "usb_seremu.h"
|
||||
#include "usb_keyboard.h"
|
||||
#include "usb_mouse.h"
|
||||
#include "usb_joystick.h"
|
||||
#include "usb_midi.h"
|
||||
#include "usb_rawhid.h"
|
||||
#include "usb_flightsim.h"
|
||||
|
||||
//#include "WCharacter.h"
|
||||
#include "WString.h"
|
||||
#include "elapsedMillis.h"
|
||||
#include "IntervalTimer.h"
|
||||
|
||||
uint16_t makeWord(uint16_t w);
|
||||
uint16_t makeWord(byte h, byte l);
|
||||
|
||||
#define word(...) makeWord(__VA_ARGS__)
|
||||
|
||||
unsigned long pulseIn(uint8_t pin, uint8_t state, unsigned long timeout = 1000000L);
|
||||
|
||||
void tone(uint8_t pin, uint16_t frequency, uint32_t duration = 0);
|
||||
void noTone(uint8_t pin);
|
||||
|
||||
// WMath prototypes
|
||||
uint32_t random(void);
|
||||
uint32_t random(uint32_t howbig);
|
||||
int32_t random(int32_t howsmall, int32_t howbig);
|
||||
void randomSeed(uint32_t newseed);
|
||||
void srandom(uint32_t newseed);
|
||||
long map(long, long, long, long, long);
|
||||
|
||||
#include "pins_arduino.h"
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // WProgram_h
|
||||
725
teensy3/WString.cpp
Normal file
725
teensy3/WString.cpp
Normal file
|
|
@ -0,0 +1,725 @@
|
|||
/*
|
||||
WString.cpp - String library for Wiring & Arduino
|
||||
...mostly rewritten by Paul Stoffregen...
|
||||
Copyright (c) 2009-10 Hernando Barragan. All rights reserved.
|
||||
Copyright 2011, Paul Stoffregen, paul@pjrc.com
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "WString.h"
|
||||
|
||||
|
||||
/*********************************************/
|
||||
/* Constructors */
|
||||
/*********************************************/
|
||||
|
||||
String::String(const char *cstr)
|
||||
{
|
||||
init();
|
||||
if (cstr) copy(cstr, strlen(cstr));
|
||||
}
|
||||
|
||||
String::String(const __FlashStringHelper *pgmstr)
|
||||
{
|
||||
init();
|
||||
*this = pgmstr;
|
||||
}
|
||||
|
||||
String::String(const String &value)
|
||||
{
|
||||
init();
|
||||
*this = value;
|
||||
}
|
||||
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
String::String(String &&rval)
|
||||
{
|
||||
init();
|
||||
move(rval);
|
||||
}
|
||||
String::String(StringSumHelper &&rval)
|
||||
{
|
||||
init();
|
||||
move(rval);
|
||||
}
|
||||
#endif
|
||||
|
||||
String::String(char c)
|
||||
{
|
||||
init();
|
||||
*this = c;
|
||||
}
|
||||
|
||||
String::String(unsigned char c)
|
||||
{
|
||||
init();
|
||||
char buf[4];
|
||||
utoa(c, buf, 10);
|
||||
*this = buf;
|
||||
}
|
||||
|
||||
String::String(const int value, unsigned char base)
|
||||
{
|
||||
init();
|
||||
char buf[18];
|
||||
itoa(value, buf, base);
|
||||
*this = buf;
|
||||
}
|
||||
|
||||
String::String(unsigned int value, unsigned char base)
|
||||
{
|
||||
init();
|
||||
char buf[17];
|
||||
utoa(value, buf, base);
|
||||
*this = buf;
|
||||
}
|
||||
|
||||
String::String(long value, unsigned char base)
|
||||
{
|
||||
init();
|
||||
char buf[34];
|
||||
ltoa(value, buf, base);
|
||||
*this = buf;
|
||||
}
|
||||
|
||||
String::String(unsigned long value, unsigned char base)
|
||||
{
|
||||
init();
|
||||
char buf[33];
|
||||
ultoa(value, buf, base);
|
||||
*this = buf;
|
||||
}
|
||||
|
||||
String::String(float num, unsigned char digits)
|
||||
{
|
||||
init();
|
||||
char buf[40];
|
||||
*this = dtostrf(num, digits + 2, digits, buf);
|
||||
}
|
||||
|
||||
String::~String()
|
||||
{
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
/* Memory Management */
|
||||
/*********************************************/
|
||||
|
||||
inline void String::init(void)
|
||||
{
|
||||
buffer = NULL;
|
||||
capacity = 0;
|
||||
len = 0;
|
||||
flags = 0;
|
||||
}
|
||||
|
||||
unsigned char String::reserve(unsigned int size)
|
||||
{
|
||||
if (capacity >= size) return 1;
|
||||
if (changeBuffer(size)) {
|
||||
if (len == 0) buffer[0] = 0;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned char String::changeBuffer(unsigned int maxStrLen)
|
||||
{
|
||||
char *newbuffer = (char *)realloc(buffer, maxStrLen + 1);
|
||||
if (newbuffer) {
|
||||
buffer = newbuffer;
|
||||
capacity = maxStrLen;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
/* Copy and Move */
|
||||
/*********************************************/
|
||||
|
||||
String & String::copy(const char *cstr, unsigned int length)
|
||||
{
|
||||
if (length == 0) {
|
||||
if (buffer) buffer[0] = 0;
|
||||
len = 0;
|
||||
return *this;
|
||||
}
|
||||
if (!reserve(length)) {
|
||||
if (buffer) {
|
||||
free(buffer);
|
||||
buffer = NULL;
|
||||
}
|
||||
len = capacity = 0;
|
||||
return *this;
|
||||
}
|
||||
len = length;
|
||||
strcpy(buffer, cstr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void String::move(String &rhs)
|
||||
{
|
||||
if (buffer) {
|
||||
if (capacity >= rhs.len) {
|
||||
strcpy(buffer, rhs.buffer);
|
||||
len = rhs.len;
|
||||
rhs.len = 0;
|
||||
return;
|
||||
} else {
|
||||
free(buffer);
|
||||
}
|
||||
}
|
||||
buffer = rhs.buffer;
|
||||
capacity = rhs.capacity;
|
||||
len = rhs.len;
|
||||
rhs.buffer = NULL;
|
||||
rhs.capacity = 0;
|
||||
rhs.len = 0;
|
||||
}
|
||||
|
||||
String & String::operator = (const String &rhs)
|
||||
{
|
||||
if (this == &rhs) return *this;
|
||||
return copy(rhs.buffer, rhs.len);
|
||||
}
|
||||
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
String & String::operator = (String &&rval)
|
||||
{
|
||||
if (this != &rval) move(rval);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::operator = (StringSumHelper &&rval)
|
||||
{
|
||||
if (this != &rval) move(rval);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
String & String::operator = (const char *cstr)
|
||||
{
|
||||
if (cstr) {
|
||||
copy(cstr, strlen(cstr));
|
||||
} else {
|
||||
len = 0;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::operator = (const __FlashStringHelper *pgmstr)
|
||||
{
|
||||
copy(pgmstr);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::operator = (char c)
|
||||
{
|
||||
char buf[2];
|
||||
buf[0] = c;
|
||||
buf[1] = 0;
|
||||
return copy(buf, 1);
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
/* Append */
|
||||
/*********************************************/
|
||||
|
||||
String & String::append(const String &s)
|
||||
{
|
||||
return append(s.buffer, s.len);
|
||||
}
|
||||
|
||||
String & String::append(const char *cstr, unsigned int length)
|
||||
{
|
||||
unsigned int newlen = len + length;
|
||||
if (length == 0 || !reserve(newlen)) return *this;
|
||||
strcpy(buffer + len, cstr);
|
||||
len = newlen;
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::append(const char *cstr)
|
||||
{
|
||||
if (cstr) append(cstr, strlen(cstr));
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::append(char c)
|
||||
{
|
||||
char buf[2];
|
||||
buf[0] = c;
|
||||
buf[1] = 0;
|
||||
append(buf, 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::append(int num)
|
||||
{
|
||||
char buf[12];
|
||||
ltoa((long)num, buf, 10);
|
||||
append(buf, strlen(buf));
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::append(unsigned int num)
|
||||
{
|
||||
char buf[11];
|
||||
ultoa((unsigned long)num, buf, 10);
|
||||
append(buf, strlen(buf));
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::append(long num)
|
||||
{
|
||||
char buf[12];
|
||||
ltoa(num, buf, 10);
|
||||
append(buf, strlen(buf));
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::append(unsigned long num)
|
||||
{
|
||||
char buf[11];
|
||||
ultoa(num, buf, 10);
|
||||
append(buf, strlen(buf));
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::append(float num)
|
||||
{
|
||||
char buf[30];
|
||||
dtostrf(num, 4, 2, buf);
|
||||
append(buf, strlen(buf));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
/*********************************************/
|
||||
/* Concatenate */
|
||||
/*********************************************/
|
||||
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
a.append(rhs.buffer, rhs.len);
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
if (cstr) a.append(cstr, strlen(cstr));
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *pgmstr)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
a.append(pgmstr);
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, char c)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
a.append(c);
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char c)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
a.append(c);
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, int num)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
a.append((long)num);
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
a.append((unsigned long)num);
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, long num)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
a.append(num);
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
a.append(num);
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, float num)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
a.append(num);
|
||||
return a;
|
||||
}
|
||||
|
||||
StringSumHelper & operator + (const StringSumHelper &lhs, double num)
|
||||
{
|
||||
StringSumHelper &a = const_cast<StringSumHelper&>(lhs);
|
||||
a.append(num);
|
||||
return a;
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
/* Comparison */
|
||||
/*********************************************/
|
||||
|
||||
int String::compareTo(const String &s) const
|
||||
{
|
||||
if (!buffer || !s.buffer) {
|
||||
if (s.buffer && s.len > 0) return 0 - *(unsigned char *)s.buffer;
|
||||
if (buffer && len > 0) return *(unsigned char *)buffer;
|
||||
return 0;
|
||||
}
|
||||
return strcmp(buffer, s.buffer);
|
||||
}
|
||||
|
||||
unsigned char String::equals(const String &s2) const
|
||||
{
|
||||
return (len == s2.len && compareTo(s2) == 0);
|
||||
}
|
||||
|
||||
unsigned char String::equals(const char *cstr) const
|
||||
{
|
||||
if (len == 0) return (cstr == NULL || *cstr == 0);
|
||||
if (cstr == NULL) return buffer[0] == 0;
|
||||
return strcmp(buffer, cstr) == 0;
|
||||
}
|
||||
|
||||
unsigned char String::operator<(const String &rhs) const
|
||||
{
|
||||
return compareTo(rhs) < 0;
|
||||
}
|
||||
|
||||
unsigned char String::operator>(const String &rhs) const
|
||||
{
|
||||
return compareTo(rhs) > 0;
|
||||
}
|
||||
|
||||
unsigned char String::operator<=(const String &rhs) const
|
||||
{
|
||||
return compareTo(rhs) <= 0;
|
||||
}
|
||||
|
||||
unsigned char String::operator>=(const String &rhs) const
|
||||
{
|
||||
return compareTo(rhs) >= 0;
|
||||
}
|
||||
|
||||
unsigned char String::equalsIgnoreCase( const String &s2 ) const
|
||||
{
|
||||
if (this == &s2) return 1;
|
||||
if (len != s2.len) return 0;
|
||||
if (len == 0) return 1;
|
||||
const char *p1 = buffer;
|
||||
const char *p2 = s2.buffer;
|
||||
while (*p1) {
|
||||
if (tolower(*p1++) != tolower(*p2++)) return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
unsigned char String::startsWith( const String &s2 ) const
|
||||
{
|
||||
if (len < s2.len) return 0;
|
||||
return startsWith(s2, 0);
|
||||
}
|
||||
|
||||
unsigned char String::startsWith( const String &s2, unsigned int offset ) const
|
||||
{
|
||||
if (offset > len - s2.len || !buffer || !s2.buffer) return 0;
|
||||
return strncmp( &buffer[offset], s2.buffer, s2.len ) == 0;
|
||||
}
|
||||
|
||||
unsigned char String::endsWith( const String &s2 ) const
|
||||
{
|
||||
if ( len < s2.len || !buffer || !s2.buffer) return 0;
|
||||
return strcmp(&buffer[len - s2.len], s2.buffer) == 0;
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
/* Character Access */
|
||||
/*********************************************/
|
||||
|
||||
char String::charAt(unsigned int loc) const
|
||||
{
|
||||
return operator[](loc);
|
||||
}
|
||||
|
||||
void String::setCharAt(unsigned int loc, char c)
|
||||
{
|
||||
if (loc < len) buffer[loc] = c;
|
||||
}
|
||||
|
||||
char & String::operator[](unsigned int index)
|
||||
{
|
||||
static char dummy_writable_char;
|
||||
if (index >= len || !buffer) {
|
||||
dummy_writable_char = 0;
|
||||
return dummy_writable_char;
|
||||
}
|
||||
return buffer[index];
|
||||
}
|
||||
|
||||
char String::operator[]( unsigned int index ) const
|
||||
{
|
||||
if (index >= len || !buffer) return 0;
|
||||
return buffer[index];
|
||||
}
|
||||
|
||||
void String::getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index) const
|
||||
{
|
||||
if (!bufsize || !buf) return;
|
||||
if (index >= len) {
|
||||
buf[0] = 0;
|
||||
return;
|
||||
}
|
||||
unsigned int n = bufsize - 1;
|
||||
if (n > len - index) n = len - index;
|
||||
strncpy((char *)buf, buffer + index, n);
|
||||
buf[n] = 0;
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
/* Search */
|
||||
/*********************************************/
|
||||
|
||||
int String::indexOf(char c) const
|
||||
{
|
||||
return indexOf(c, 0);
|
||||
}
|
||||
|
||||
int String::indexOf( char ch, unsigned int fromIndex ) const
|
||||
{
|
||||
if (fromIndex >= len) return -1;
|
||||
const char* temp = strchr(buffer + fromIndex, ch);
|
||||
if (temp == NULL) return -1;
|
||||
return temp - buffer;
|
||||
}
|
||||
|
||||
int String::indexOf(const String &s2) const
|
||||
{
|
||||
return indexOf(s2, 0);
|
||||
}
|
||||
|
||||
int String::indexOf(const String &s2, unsigned int fromIndex) const
|
||||
{
|
||||
if (fromIndex >= len) return -1;
|
||||
const char *found = strstr(buffer + fromIndex, s2.buffer);
|
||||
if (found == NULL) return -1;
|
||||
return found - buffer;
|
||||
}
|
||||
|
||||
int String::lastIndexOf( char theChar ) const
|
||||
{
|
||||
return lastIndexOf(theChar, len - 1);
|
||||
}
|
||||
|
||||
int String::lastIndexOf(char ch, unsigned int fromIndex) const
|
||||
{
|
||||
if (fromIndex >= len || fromIndex < 0) return -1;
|
||||
char tempchar = buffer[fromIndex + 1];
|
||||
buffer[fromIndex + 1] = '\0';
|
||||
char* temp = strrchr( buffer, ch );
|
||||
buffer[fromIndex + 1] = tempchar;
|
||||
if (temp == NULL) return -1;
|
||||
return temp - buffer;
|
||||
}
|
||||
|
||||
int String::lastIndexOf(const String &s2) const
|
||||
{
|
||||
return lastIndexOf(s2, len - s2.len);
|
||||
}
|
||||
|
||||
int String::lastIndexOf(const String &s2, unsigned int fromIndex) const
|
||||
{
|
||||
if (s2.len == 0 || len == 0 || s2.len > len || fromIndex < 0) return -1;
|
||||
if (fromIndex >= len) fromIndex = len - 1;
|
||||
int found = -1;
|
||||
for (char *p = buffer; p <= buffer + fromIndex; p++) {
|
||||
p = strstr(p, s2.buffer);
|
||||
if (!p) break;
|
||||
if ((unsigned int)(p - buffer) <= fromIndex) found = p - buffer;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
String String::substring( unsigned int left ) const
|
||||
{
|
||||
return substring(left, len);
|
||||
}
|
||||
|
||||
String String::substring(unsigned int left, unsigned int right) const
|
||||
{
|
||||
if (left > right) {
|
||||
unsigned int temp = right;
|
||||
right = left;
|
||||
left = temp;
|
||||
}
|
||||
String out;
|
||||
if (left > len) return out;
|
||||
if (right > len) right = len;
|
||||
char temp = buffer[right]; // save the replaced character
|
||||
buffer[right] = '\0';
|
||||
out = buffer + left; // pointer arithmetic
|
||||
buffer[right] = temp; //restore character
|
||||
return out;
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
/* Modification */
|
||||
/*********************************************/
|
||||
|
||||
String & String::replace(char find, char replace)
|
||||
{
|
||||
if (!buffer) return *this;
|
||||
for (char *p = buffer; *p; p++) {
|
||||
if (*p == find) *p = replace;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::replace(const String& find, const String& replace)
|
||||
{
|
||||
if (len == 0 || find.len == 0) return *this;
|
||||
int diff = replace.len - find.len;
|
||||
char *readFrom = buffer;
|
||||
char *foundAt;
|
||||
if (diff == 0) {
|
||||
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
|
||||
memcpy(foundAt, replace.buffer, replace.len);
|
||||
readFrom = foundAt + replace.len;
|
||||
}
|
||||
} else if (diff < 0) {
|
||||
char *writeTo = buffer;
|
||||
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
|
||||
unsigned int n = foundAt - readFrom;
|
||||
memcpy(writeTo, readFrom, n);
|
||||
writeTo += n;
|
||||
memcpy(writeTo, replace.buffer, replace.len);
|
||||
writeTo += replace.len;
|
||||
readFrom = foundAt + find.len;
|
||||
len += diff;
|
||||
}
|
||||
strcpy(writeTo, readFrom);
|
||||
} else {
|
||||
unsigned int size = len; // compute size needed for result
|
||||
while ((foundAt = strstr(readFrom, find.buffer)) != NULL) {
|
||||
readFrom = foundAt + find.len;
|
||||
size += diff;
|
||||
}
|
||||
if (size == len) return *this;
|
||||
if (size > capacity && !changeBuffer(size)) return *this;
|
||||
int index = len - 1;
|
||||
while (index >= 0 && (index = lastIndexOf(find, index)) >= 0) {
|
||||
readFrom = buffer + index + find.len;
|
||||
memmove(readFrom + diff, readFrom, len - (readFrom - buffer));
|
||||
len += diff;
|
||||
buffer[len] = 0;
|
||||
memcpy(buffer + index, replace.buffer, replace.len);
|
||||
index--;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::remove(unsigned int index)
|
||||
{
|
||||
if (index < len) {
|
||||
len = index;
|
||||
buffer[len] = 0;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::remove(unsigned int index, unsigned int count)
|
||||
{
|
||||
if (index < len && count > 0) {
|
||||
if (index + count > len) count = len - index;
|
||||
len = len - count;
|
||||
memmove(buffer + index, buffer + index + count, len - index);
|
||||
buffer[len] = 0;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::toLowerCase(void)
|
||||
{
|
||||
if (!buffer) return *this;
|
||||
for (char *p = buffer; *p; p++) {
|
||||
*p = tolower(*p);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::toUpperCase(void)
|
||||
{
|
||||
if (!buffer) return *this;
|
||||
for (char *p = buffer; *p; p++) {
|
||||
*p = toupper(*p);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
String & String::trim(void)
|
||||
{
|
||||
if (!buffer || len == 0) return *this;
|
||||
char *begin = buffer;
|
||||
while (isspace(*begin)) begin++;
|
||||
char *end = buffer + len - 1;
|
||||
while (isspace(*end) && end >= begin) end--;
|
||||
len = end + 1 - begin;
|
||||
if (begin > buffer) memcpy(buffer, begin, len);
|
||||
buffer[len] = 0;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/*********************************************/
|
||||
/* Parsing / Conversion */
|
||||
/*********************************************/
|
||||
|
||||
long String::toInt(void) const
|
||||
{
|
||||
if (buffer) return atol(buffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
float String::toFloat(void) const
|
||||
{
|
||||
if (buffer) return strtof(buffer, (char **)NULL);
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
|
||||
216
teensy3/WString.h
Normal file
216
teensy3/WString.h
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
WString.h - String library for Wiring & Arduino
|
||||
...mostly rewritten by Paul Stoffregen...
|
||||
Copyright (c) 2009-10 Hernando Barragan. All right reserved.
|
||||
Copyright 2011, Paul Stoffregen, paul@pjrc.com
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef String_class_h
|
||||
#define String_class_h
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "avr_functions.h"
|
||||
|
||||
// When compiling programs with this class, the following gcc parameters
|
||||
// dramatically increase performance and memory (RAM) efficiency, typically
|
||||
// with little or no increase in code size.
|
||||
// -felide-constructors
|
||||
// -std=c++0x
|
||||
|
||||
// Brian Cook's "no overhead" Flash String type (message on Dec 14, 2010)
|
||||
// modified by Mikal Hart for his FlashString library
|
||||
class __FlashStringHelper;
|
||||
#ifndef F
|
||||
#define F(string_literal) ((const __FlashStringHelper *)(string_literal))
|
||||
#endif
|
||||
|
||||
// An inherited class for holding the result of a concatenation. These
|
||||
// result objects are assumed to be writable by subsequent concatenations.
|
||||
class StringSumHelper;
|
||||
|
||||
// The string class
|
||||
class String
|
||||
{
|
||||
public:
|
||||
// constructors
|
||||
String(const char *cstr = (const char *)NULL);
|
||||
String(const __FlashStringHelper *pgmstr);
|
||||
String(const String &str);
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
String(String &&rval);
|
||||
String(StringSumHelper &&rval);
|
||||
#endif
|
||||
String(char c);
|
||||
String(unsigned char c);
|
||||
String(int, unsigned char base=10);
|
||||
String(unsigned int, unsigned char base=10);
|
||||
String(long, unsigned char base=10);
|
||||
String(unsigned long, unsigned char base=10);
|
||||
String(float num, unsigned char digits=2);
|
||||
String(double num, unsigned char digits=2) : String((float)num, digits) {}
|
||||
~String(void);
|
||||
|
||||
// memory management
|
||||
unsigned char reserve(unsigned int size);
|
||||
inline unsigned int length(void) const {return len;}
|
||||
|
||||
// copy and move
|
||||
String & copy(const char *cstr, unsigned int length);
|
||||
String & copy(const __FlashStringHelper *s) { return copy((const char *)s, strlen((const char *)s)); }
|
||||
void move(String &rhs);
|
||||
String & operator = (const String &rhs);
|
||||
String & operator = (const char *cstr);
|
||||
String & operator = (const __FlashStringHelper *pgmstr);
|
||||
#ifdef __GXX_EXPERIMENTAL_CXX0X__
|
||||
String & operator = (String &&rval);
|
||||
String & operator = (StringSumHelper &&rval);
|
||||
#endif
|
||||
String & operator = (char c);
|
||||
|
||||
// append
|
||||
String & append(const String &str);
|
||||
String & append(const char *cstr);
|
||||
String & append(const __FlashStringHelper *s) {return append((const char *)s, strlen((const char *)s)); }
|
||||
String & append(char c);
|
||||
String & append(unsigned char c) {return append((int)c);}
|
||||
String & append(int num);
|
||||
String & append(unsigned int num);
|
||||
String & append(long num);
|
||||
String & append(unsigned long num);
|
||||
String & append(float num);
|
||||
String & append(double num) {return append((float)num);}
|
||||
String & operator += (const String &rhs) {return append(rhs);}
|
||||
String & operator += (const char *cstr) {return append(cstr);}
|
||||
String & operator += (const __FlashStringHelper *pgmstr) {return append(pgmstr);}
|
||||
String & operator += (char c) {return append(c);}
|
||||
String & operator += (unsigned char c) {return append((int)c);}
|
||||
String & operator += (int num) {return append(num);}
|
||||
String & operator += (unsigned int num) {return append(num);}
|
||||
String & operator += (long num) {return append(num);}
|
||||
String & operator += (unsigned long num) {return append(num);}
|
||||
String & operator += (float num) {return append(num);}
|
||||
String & operator += (double num) {return append(num);}
|
||||
|
||||
// concatenate
|
||||
friend StringSumHelper & operator + (const StringSumHelper &lhs, const String &rhs);
|
||||
friend StringSumHelper & operator + (const StringSumHelper &lhs, const char *cstr);
|
||||
friend StringSumHelper & operator + (const StringSumHelper &lhs, const __FlashStringHelper *pgmstr);
|
||||
friend StringSumHelper & operator + (const StringSumHelper &lhs, char c);
|
||||
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned char c);
|
||||
friend StringSumHelper & operator + (const StringSumHelper &lhs, int num);
|
||||
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned int num);
|
||||
friend StringSumHelper & operator + (const StringSumHelper &lhs, long num);
|
||||
friend StringSumHelper & operator + (const StringSumHelper &lhs, unsigned long num);
|
||||
friend StringSumHelper & operator + (const StringSumHelper &lhs, float num);
|
||||
friend StringSumHelper & operator + (const StringSumHelper &lhs, double num);
|
||||
String & concat(const String &str) {return append(str);}
|
||||
String & concat(const char *cstr) {return append(cstr);}
|
||||
String & concat(const __FlashStringHelper *pgmstr) {return append(pgmstr);}
|
||||
String & concat(char c) {return append(c);}
|
||||
String & concat(unsigned char c) {return append((int)c);}
|
||||
String & concat(int num) {return append(num);}
|
||||
String & concat(unsigned int num) {return append(num);}
|
||||
String & concat(long num) {return append(num);}
|
||||
String & concat(unsigned long num) {return append(num);}
|
||||
String & concat(float num) {return append(num);}
|
||||
String & concat(double num) {return append(num);}
|
||||
|
||||
// comparison
|
||||
int compareTo(const String &s) const;
|
||||
unsigned char equals(const String &s) const;
|
||||
unsigned char equals(const char *cstr) const;
|
||||
//unsigned char equals(const __FlashStringHelper *pgmstr) const;
|
||||
unsigned char operator == (const String &rhs) const {return equals(rhs);}
|
||||
unsigned char operator == (const char *cstr) const {return equals(cstr);}
|
||||
unsigned char operator == (const __FlashStringHelper *s) const {return equals((const char *)s);}
|
||||
unsigned char operator != (const String &rhs) const {return !equals(rhs);}
|
||||
unsigned char operator != (const char *cstr) const {return !equals(cstr);}
|
||||
unsigned char operator != (const __FlashStringHelper *s) const {return !equals(s);}
|
||||
unsigned char operator < (const String &rhs) const;
|
||||
unsigned char operator > (const String &rhs) const;
|
||||
unsigned char operator <= (const String &rhs) const;
|
||||
unsigned char operator >= (const String &rhs) const;
|
||||
unsigned char equalsIgnoreCase(const String &s) const;
|
||||
unsigned char startsWith( const String &prefix) const;
|
||||
unsigned char startsWith(const String &prefix, unsigned int offset) const;
|
||||
unsigned char endsWith(const String &suffix) const;
|
||||
|
||||
// character acccess
|
||||
char charAt(unsigned int index) const;
|
||||
void setCharAt(unsigned int index, char c);
|
||||
char operator [] (unsigned int index) const;
|
||||
char& operator [] (unsigned int index);
|
||||
void getBytes(unsigned char *buf, unsigned int bufsize, unsigned int index=0) const;
|
||||
void toCharArray(char *buf, unsigned int bufsize, unsigned int index=0) const
|
||||
{getBytes((unsigned char *)buf, bufsize, index);}
|
||||
const char * c_str() const { return buffer; }
|
||||
|
||||
// search
|
||||
int indexOf( char ch ) const;
|
||||
int indexOf( char ch, unsigned int fromIndex ) const;
|
||||
int indexOf( const String &str ) const;
|
||||
int indexOf( const String &str, unsigned int fromIndex ) const;
|
||||
int lastIndexOf( char ch ) const;
|
||||
int lastIndexOf( char ch, unsigned int fromIndex ) const;
|
||||
int lastIndexOf( const String &str ) const;
|
||||
int lastIndexOf( const String &str, unsigned int fromIndex ) const;
|
||||
String substring( unsigned int beginIndex ) const;
|
||||
String substring( unsigned int beginIndex, unsigned int endIndex ) const;
|
||||
|
||||
// modification
|
||||
String & replace(char find, char replace);
|
||||
String & replace(const String& find, const String& replace);
|
||||
String & remove(unsigned int index);
|
||||
String & remove(unsigned int index, unsigned int count);
|
||||
String & toLowerCase(void);
|
||||
String & toUpperCase(void);
|
||||
String & trim(void);
|
||||
|
||||
// parsing/conversion
|
||||
long toInt(void) const;
|
||||
float toFloat(void) const;
|
||||
|
||||
protected:
|
||||
char *buffer; // the actual char array
|
||||
unsigned int capacity; // the array length minus one (for the '\0')
|
||||
unsigned int len; // the String length (not counting the '\0')
|
||||
unsigned char flags; // unused, for future features
|
||||
protected:
|
||||
void init(void);
|
||||
unsigned char changeBuffer(unsigned int maxStrLen);
|
||||
String & append(const char *cstr, unsigned int length);
|
||||
};
|
||||
|
||||
class StringSumHelper : public String
|
||||
{
|
||||
public:
|
||||
StringSumHelper(const String &s) : String(s) {}
|
||||
StringSumHelper(const char *p) : String(p) {}
|
||||
StringSumHelper(const __FlashStringHelper *pgmstr) : String(pgmstr) {}
|
||||
StringSumHelper(char c) : String(c) {}
|
||||
StringSumHelper(unsigned char c) : String(c) {}
|
||||
StringSumHelper(int num) : String(num, 10) {}
|
||||
StringSumHelper(unsigned int num) : String(num, 10) {}
|
||||
StringSumHelper(long num) : String(num, 10) {}
|
||||
StringSumHelper(unsigned long num) : String(num, 10) {}
|
||||
};
|
||||
|
||||
#endif // __cplusplus
|
||||
#endif // String_class_h
|
||||
287
teensy3/analog.c
Normal file
287
teensy3/analog.c
Normal file
|
|
@ -0,0 +1,287 @@
|
|||
/* Teensyduino Core Library
|
||||
* http://www.pjrc.com/teensy/
|
||||
* Copyright (c) 2013 PJRC.COM, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* 1. The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* 2. If the Software is incorporated into a build system that allows
|
||||
* selection among a list of target devices, then similar target
|
||||
* devices manufactured by PJRC.COM must be included in the list of
|
||||
* target devices and selectable in the same manner.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "core_pins.h"
|
||||
//#include "HardwareSerial.h"
|
||||
|
||||
static uint8_t calibrating;
|
||||
static uint8_t analog_right_shift = 0;
|
||||
static uint8_t analog_config_bits = 10;
|
||||
static uint8_t analog_num_average = 4;
|
||||
static uint8_t analog_reference_internal = 0;
|
||||
|
||||
// the alternate clock is connected to OSCERCLK (16 MHz).
|
||||
// datasheet says ADC clock should be 2 to 12 MHz for 16 bit mode
|
||||
// datasheet says ADC clock should be 1 to 18 MHz for 8-12 bit mode
|
||||
|
||||
#if F_BUS == 48000000
|
||||
#define ADC0_CFG1_6MHZ ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(1)
|
||||
#define ADC0_CFG1_12MHZ ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(1)
|
||||
#define ADC0_CFG1_24MHZ ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(1)
|
||||
#elif F_BUS == 24000000
|
||||
#define ADC0_CFG1_6MHZ ADC_CFG1_ADIV(2) + ADC_CFG1_ADICLK(0)
|
||||
#define ADC0_CFG1_12MHZ ADC_CFG1_ADIV(1) + ADC_CFG1_ADICLK(0)
|
||||
#define ADC0_CFG1_24MHZ ADC_CFG1_ADIV(0) + ADC_CFG1_ADICLK(0)
|
||||
#else
|
||||
#error
|
||||
#endif
|
||||
|
||||
void analog_init(void)
|
||||
{
|
||||
uint32_t num;
|
||||
|
||||
VREF_TRM = 0x60;
|
||||
VREF_SC = 0xE1; // enable 1.2 volt ref
|
||||
|
||||
if (analog_config_bits == 8) {
|
||||
ADC0_CFG1 = ADC0_CFG1_24MHZ + ADC_CFG1_MODE(0);
|
||||
ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(3);
|
||||
} else if (analog_config_bits == 10) {
|
||||
ADC0_CFG1 = ADC0_CFG1_12MHZ + ADC_CFG1_MODE(2) + ADC_CFG1_ADLSMP;
|
||||
ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(3);
|
||||
} else if (analog_config_bits == 12) {
|
||||
ADC0_CFG1 = ADC0_CFG1_12MHZ + ADC_CFG1_MODE(1) + ADC_CFG1_ADLSMP;
|
||||
ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(2);
|
||||
} else {
|
||||
ADC0_CFG1 = ADC0_CFG1_12MHZ + ADC_CFG1_MODE(3) + ADC_CFG1_ADLSMP;
|
||||
ADC0_CFG2 = ADC_CFG2_MUXSEL + ADC_CFG2_ADLSTS(2);
|
||||
}
|
||||
|
||||
if (analog_reference_internal) {
|
||||
ADC0_SC2 = ADC_SC2_REFSEL(1); // 1.2V ref
|
||||
} else {
|
||||
ADC0_SC2 = ADC_SC2_REFSEL(0); // vcc/ext ref
|
||||
}
|
||||
|
||||
num = analog_num_average;
|
||||
if (num <= 1) {
|
||||
ADC0_SC3 = ADC_SC3_CAL; // begin cal
|
||||
} else if (num <= 4) {
|
||||
ADC0_SC3 = ADC_SC3_CAL + ADC_SC3_AVGE + ADC_SC3_AVGS(0);
|
||||
} else if (num <= 8) {
|
||||
ADC0_SC3 = ADC_SC3_CAL + ADC_SC3_AVGE + ADC_SC3_AVGS(1);
|
||||
} else if (num <= 16) {
|
||||
ADC0_SC3 = ADC_SC3_CAL + ADC_SC3_AVGE + ADC_SC3_AVGS(2);
|
||||
} else {
|
||||
ADC0_SC3 = ADC_SC3_CAL + ADC_SC3_AVGE + ADC_SC3_AVGS(3);
|
||||
}
|
||||
calibrating = 1;
|
||||
}
|
||||
|
||||
static void wait_for_cal(void)
|
||||
{
|
||||
uint16_t sum;
|
||||
|
||||
//serial_print("wait_for_cal\n");
|
||||
while (ADC0_SC3 & ADC_SC3_CAL) {
|
||||
// wait
|
||||
//serial_print(".");
|
||||
}
|
||||
__disable_irq();
|
||||
if (calibrating) {
|
||||
//serial_print("\n");
|
||||
sum = ADC0_CLPS + ADC0_CLP4 + ADC0_CLP3 + ADC0_CLP2 + ADC0_CLP1 + ADC0_CLP0;
|
||||
sum = (sum / 2) | 0x8000;
|
||||
ADC0_PG = sum;
|
||||
//serial_print("ADC0_PG = ");
|
||||
//serial_phex16(sum);
|
||||
//serial_print("\n");
|
||||
sum = ADC0_CLMS + ADC0_CLM4 + ADC0_CLM3 + ADC0_CLM2 + ADC0_CLM1 + ADC0_CLM0;
|
||||
sum = (sum / 2) | 0x8000;
|
||||
ADC0_MG = sum;
|
||||
//serial_print("ADC0_MG = ");
|
||||
//serial_phex16(sum);
|
||||
//serial_print("\n");
|
||||
calibrating = 0;
|
||||
}
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
// ADCx_SC2[REFSEL] bit selects the voltage reference sources for ADC.
|
||||
// VREFH/VREFL - connected as the primary reference option
|
||||
// 1.2 V VREF_OUT - connected as the VALT reference option
|
||||
|
||||
|
||||
#define DEFAULT 0
|
||||
#define INTERNAL 2
|
||||
#define INTERNAL1V2 2
|
||||
#define INTERNAL1V1 2
|
||||
#define EXTERNAL 0
|
||||
|
||||
void analogReference(uint8_t type)
|
||||
{
|
||||
if (type) {
|
||||
// internal reference requested
|
||||
if (!analog_reference_internal) {
|
||||
analog_reference_internal = 1;
|
||||
if (calibrating) ADC0_SC3 = 0; // cancel cal
|
||||
analog_init();
|
||||
}
|
||||
} else {
|
||||
// vcc or external reference requested
|
||||
if (analog_reference_internal) {
|
||||
analog_reference_internal = 0;
|
||||
if (calibrating) ADC0_SC3 = 0; // cancel cal
|
||||
analog_init();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void analogReadRes(unsigned int bits)
|
||||
{
|
||||
unsigned int config;
|
||||
|
||||
if (bits >= 13) {
|
||||
if (bits > 16) bits = 16;
|
||||
config = 16;
|
||||
} else if (bits >= 11) {
|
||||
config = 12;
|
||||
} else if (bits >= 9) {
|
||||
config = 10;
|
||||
} else {
|
||||
config = 8;
|
||||
}
|
||||
analog_right_shift = config - bits;
|
||||
if (config != analog_config_bits) {
|
||||
analog_config_bits = config;
|
||||
if (calibrating) ADC0_SC3 = 0; // cancel cal
|
||||
analog_init();
|
||||
}
|
||||
}
|
||||
|
||||
void analogReadAveraging(unsigned int num)
|
||||
{
|
||||
|
||||
if (calibrating) wait_for_cal();
|
||||
if (num <= 1) {
|
||||
num = 0;
|
||||
ADC0_SC3 = 0;
|
||||
} else if (num <= 4) {
|
||||
num = 4;
|
||||
ADC0_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(0);
|
||||
} else if (num <= 8) {
|
||||
num = 8;
|
||||
ADC0_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(1);
|
||||
} else if (num <= 16) {
|
||||
num = 16;
|
||||
ADC0_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(2);
|
||||
} else {
|
||||
num = 32;
|
||||
ADC0_SC3 = ADC_SC3_AVGE + ADC_SC3_AVGS(3);
|
||||
}
|
||||
analog_num_average = num;
|
||||
}
|
||||
|
||||
// The SC1A register is used for both software and hardware trigger modes of operation.
|
||||
|
||||
|
||||
static const uint8_t channel2sc1a[] = {
|
||||
5, 14, 8, 9, 13, 12, 6, 7, 15, 4,
|
||||
0, 19, 3, 21, 26, 22
|
||||
};
|
||||
|
||||
// TODO: perhaps this should store the NVIC priority, so it works recursively?
|
||||
static volatile uint8_t analogReadBusy = 0;
|
||||
|
||||
int analogRead(uint8_t pin)
|
||||
{
|
||||
int result;
|
||||
|
||||
if (pin >= 14) {
|
||||
if (pin <= 23) {
|
||||
pin -= 14; // 14-23 are A0-A9
|
||||
} else if (pin >= 34 && pin <= 39) {
|
||||
pin -= 24; // 34-37 are A10-A13, 38 is temp sensor, 39 is vref
|
||||
} else {
|
||||
return 0; // all others are invalid
|
||||
}
|
||||
}
|
||||
//serial_print("analogRead");
|
||||
//return 0;
|
||||
if (calibrating) wait_for_cal();
|
||||
//pin = 5; // PTD1/SE5b, pin 14, analog 0
|
||||
|
||||
__disable_irq();
|
||||
start: ADC0_SC1A = channel2sc1a[pin];
|
||||
analogReadBusy = 1;
|
||||
__enable_irq();
|
||||
while (1) {
|
||||
__disable_irq();
|
||||
if ((ADC0_SC1A & ADC_SC1_COCO)) {
|
||||
result = ADC0_RA;
|
||||
analogReadBusy = 0;
|
||||
__enable_irq();
|
||||
result >>= analog_right_shift;
|
||||
return result;
|
||||
}
|
||||
// detect if analogRead was used from an interrupt
|
||||
// if so, our analogRead got canceled, so it must
|
||||
// be restarted.
|
||||
if (!analogReadBusy) goto start;
|
||||
__enable_irq();
|
||||
yield();
|
||||
}
|
||||
#if 0
|
||||
ADC0_SC1A = channel2sc1a[pin];
|
||||
while ((ADC0_SC1A & ADC_SC1_COCO) == 0) {
|
||||
yield();
|
||||
// wait
|
||||
//serial_print(".");
|
||||
}
|
||||
//serial_print("\n");
|
||||
result = ADC0_RA >> analog_right_shift;
|
||||
//serial_phex16(result >> 3);
|
||||
//serial_print("\n");
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
38
teensy3/arm_common_tables.h
Normal file
38
teensy3/arm_common_tables.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 11. November 2010
|
||||
* $Revision: V1.0.2
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
* Title: arm_common_tables.h
|
||||
*
|
||||
* Description: This file has extern declaration for common tables like Bitreverse, reciprocal etc which are used across different functions
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3
|
||||
*
|
||||
* Version 1.0.2 2010/11/11
|
||||
* Documentation updated.
|
||||
*
|
||||
* Version 1.0.1 2010/10/05
|
||||
* Production release and review comments incorporated.
|
||||
*
|
||||
* Version 1.0.0 2010/09/20
|
||||
* Production release and review comments incorporated.
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
#ifndef _ARM_COMMON_TABLES_H
|
||||
#define _ARM_COMMON_TABLES_H
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
extern const uint16_t armBitRevTable[1024];
|
||||
extern const q15_t armRecipTableQ15[64];
|
||||
extern const q31_t armRecipTableQ31[64];
|
||||
extern const q31_t realCoefAQ31[1024];
|
||||
extern const q31_t realCoefBQ31[1024];
|
||||
extern const float32_t twiddleCoef[6144];
|
||||
extern const q31_t twiddleCoefQ31[6144];
|
||||
extern const q15_t twiddleCoefQ15[6144];
|
||||
|
||||
#endif /* ARM_COMMON_TABLES_H */
|
||||
7571
teensy3/arm_math.h
Normal file
7571
teensy3/arm_math.h
Normal file
File diff suppressed because it is too large
Load diff
9
teensy3/avr/eeprom.h
Normal file
9
teensy3/avr/eeprom.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef _AVR_EEPROM_H_
|
||||
#define _AVR_EEPROM_H_ 1
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define E2END 0x80
|
||||
|
||||
#endif
|
||||
0
teensy3/avr/interrupt.h
Normal file
0
teensy3/avr/interrupt.h
Normal file
1
teensy3/avr/io.h
Normal file
1
teensy3/avr/io.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
#include "../avr_emulation.h"
|
||||
46
teensy3/avr/pgmspace.h
Normal file
46
teensy3/avr/pgmspace.h
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
#ifndef __PGMSPACE_H_
|
||||
#define __PGMSPACE_H_ 1
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#define PROGMEM
|
||||
#define PGM_P const char *
|
||||
#define PSTR(str) (str)
|
||||
|
||||
#define _SFR_BYTE(n) (n)
|
||||
|
||||
typedef void prog_void;
|
||||
typedef char prog_char;
|
||||
typedef unsigned char prog_uchar;
|
||||
typedef int8_t prog_int8_t;
|
||||
typedef uint8_t prog_uint8_t;
|
||||
typedef int16_t prog_int16_t;
|
||||
typedef uint16_t prog_uint16_t;
|
||||
typedef int32_t prog_int32_t;
|
||||
typedef uint32_t prog_uint32_t;
|
||||
|
||||
#define memcpy_P(dest, src, num) memcpy((dest), (src), (num))
|
||||
#define strcpy_P(dest, src) strcpy((dest), (src))
|
||||
#define strcat_P(dest, src) strcat((dest), (src))
|
||||
#define strcmp_P(a, b) strcmp((a), (b))
|
||||
#define strstr_P(a, b) strstr((a), (b))
|
||||
#define strlen_P(s) strlen((const char *)(s))
|
||||
#define strncmp_P(a, b, n) strncmp((a), (b), (n))
|
||||
#define strncpy_P(a, b, n) strncmp((a), (b), (n))
|
||||
#define sprintf_P(s, f, ...) sprintf((s), (f), __VA_ARGS__)
|
||||
|
||||
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
|
||||
#define pgm_read_word(addr) (*(const unsigned short *)(addr))
|
||||
#define pgm_read_dword(addr) (*(const unsigned long *)(addr))
|
||||
#define pgm_read_float(addr) (*(const float *)(addr))
|
||||
|
||||
#define pgm_read_byte_near(addr) pgm_read_byte(addr)
|
||||
#define pgm_read_word_near(addr) pgm_read_word(addr)
|
||||
#define pgm_read_dword_near(addr) pgm_read_dword(addr)
|
||||
#define pgm_read_float_near(addr) pgm_read_float(addr)
|
||||
#define pgm_read_byte_far(addr) pgm_read_byte(addr)
|
||||
#define pgm_read_word_far(addr) pgm_read_word(addr)
|
||||
#define pgm_read_dword_far(addr) pgm_read_dword(addr)
|
||||
#define pgm_read_float_far(addr) pgm_read_float(addr)
|
||||
|
||||
#endif
|
||||
34
teensy3/avr_emulation.cpp
Normal file
34
teensy3/avr_emulation.cpp
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/* Teensyduino Core Library
|
||||
* http://www.pjrc.com/teensy/
|
||||
* Copyright (c) 2013 PJRC.COM, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* 1. The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* 2. If the Software is incorporated into a build system that allows
|
||||
* selection among a list of target devices, then similar target
|
||||
* devices manufactured by PJRC.COM must be included in the list of
|
||||
* target devices and selectable in the same manner.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
|
||||
#include "avr_emulation.h"
|
||||
|
||||
uint8_t SPCRemulation::pinout = 0;
|
||||
1150
teensy3/avr_emulation.h
Normal file
1150
teensy3/avr_emulation.h
Normal file
File diff suppressed because it is too large
Load diff
105
teensy3/avr_functions.h
Normal file
105
teensy3/avr_functions.h
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
/* Teensyduino Core Library
|
||||
* http://www.pjrc.com/teensy/
|
||||
* Copyright (c) 2013 PJRC.COM, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* 1. The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* 2. If the Software is incorporated into a build system that allows
|
||||
* selection among a list of target devices, then similar target
|
||||
* devices manufactured by PJRC.COM must be included in the list of
|
||||
* target devices and selectable in the same manner.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _avr_functions_h_
|
||||
#define _avr_functions_h_
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void eeprom_initialize(void);
|
||||
uint8_t eeprom_read_byte(const uint8_t *addr) __attribute__ ((pure));
|
||||
uint16_t eeprom_read_word(const uint16_t *addr) __attribute__ ((pure));
|
||||
uint32_t eeprom_read_dword(const uint32_t *addr) __attribute__ ((pure));
|
||||
void eeprom_read_block(void *buf, const void *addr, uint32_t len);
|
||||
void eeprom_write_byte(uint8_t *addr, uint8_t value);
|
||||
void eeprom_write_word(uint16_t *addr, uint16_t value);
|
||||
void eeprom_write_dword(uint32_t *addr, uint32_t value);
|
||||
void eeprom_write_block(const void *buf, void *addr, uint32_t len);
|
||||
|
||||
static inline float eeprom_read_float(const float *addr) __attribute__((pure, always_inline, unused));
|
||||
static inline float eeprom_read_float(const float *addr)
|
||||
{
|
||||
union {float f; uint32_t u32;} u;
|
||||
u.u32 = eeprom_read_dword((const uint32_t *)addr);
|
||||
return u.f;
|
||||
}
|
||||
static inline void eeprom_write_float(float *addr, float value) __attribute__((always_inline, unused));
|
||||
static inline void eeprom_write_float(float *addr, float value)
|
||||
{
|
||||
union {float f; uint32_t u32;} u;
|
||||
u.f = value;
|
||||
eeprom_write_dword((uint32_t *)addr, u.u32);
|
||||
}
|
||||
static inline void eeprom_update_byte(uint8_t *addr, uint8_t value) __attribute__((always_inline, unused));
|
||||
static inline void eeprom_update_byte(uint8_t *addr, uint8_t value)
|
||||
{
|
||||
eeprom_write_byte(addr, value);
|
||||
}
|
||||
static inline void eeprom_update_word(uint16_t *addr, uint16_t value) __attribute__((always_inline, unused));
|
||||
static inline void eeprom_update_word(uint16_t *addr, uint16_t value)
|
||||
{
|
||||
eeprom_write_word(addr, value);
|
||||
}
|
||||
static inline void eeprom_update_dword(uint32_t *addr, uint32_t value) __attribute__((always_inline, unused));
|
||||
static inline void eeprom_update_dword(uint32_t *addr, uint32_t value)
|
||||
{
|
||||
eeprom_write_dword(addr, value);
|
||||
}
|
||||
static inline void eeprom_update_float(float *addr, float value) __attribute__((always_inline, unused));
|
||||
static inline void eeprom_update_float(float *addr, float value)
|
||||
{
|
||||
union {float f; uint32_t u32;} u;
|
||||
u.f = value;
|
||||
eeprom_write_dword((uint32_t *)addr, u.u32);
|
||||
}
|
||||
static inline void eeprom_update_block(const void *buf, void *addr, uint32_t len) __attribute__((always_inline, unused));
|
||||
static inline void eeprom_update_block(const void *buf, void *addr, uint32_t len)
|
||||
{
|
||||
eeprom_write_block(buf, addr, len);
|
||||
}
|
||||
|
||||
|
||||
char * ultoa(unsigned long val, char *buf, int radix);
|
||||
char * ltoa(long val, char *buf, int radix);
|
||||
static inline char * utoa(unsigned int val, char *buf, int radix) __attribute__((always_inline, unused));
|
||||
static inline char * utoa(unsigned int val, char *buf, int radix) { return ultoa(val, buf, radix); }
|
||||
static inline char * itoa(int val, char *buf, int radix) __attribute__((always_inline, unused));
|
||||
static inline char * itoa(int val, char *buf, int radix) { return ltoa(val, buf, radix); }
|
||||
char * dtostrf(float val, int width, unsigned int precision, char *buf);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
515
teensy3/binary.h
Normal file
515
teensy3/binary.h
Normal file
|
|
@ -0,0 +1,515 @@
|
|||
#ifndef Binary_h
|
||||
#define Binary_h
|
||||
|
||||
#define B0 0
|
||||
#define B00 0
|
||||
#define B000 0
|
||||
#define B0000 0
|
||||
#define B00000 0
|
||||
#define B000000 0
|
||||
#define B0000000 0
|
||||
#define B00000000 0
|
||||
#define B1 1
|
||||
#define B01 1
|
||||
#define B001 1
|
||||
#define B0001 1
|
||||
#define B00001 1
|
||||
#define B000001 1
|
||||
#define B0000001 1
|
||||
#define B00000001 1
|
||||
#define B10 2
|
||||
#define B010 2
|
||||
#define B0010 2
|
||||
#define B00010 2
|
||||
#define B000010 2
|
||||
#define B0000010 2
|
||||
#define B00000010 2
|
||||
#define B11 3
|
||||
#define B011 3
|
||||
#define B0011 3
|
||||
#define B00011 3
|
||||
#define B000011 3
|
||||
#define B0000011 3
|
||||
#define B00000011 3
|
||||
#define B100 4
|
||||
#define B0100 4
|
||||
#define B00100 4
|
||||
#define B000100 4
|
||||
#define B0000100 4
|
||||
#define B00000100 4
|
||||
#define B101 5
|
||||
#define B0101 5
|
||||
#define B00101 5
|
||||
#define B000101 5
|
||||
#define B0000101 5
|
||||
#define B00000101 5
|
||||
#define B110 6
|
||||
#define B0110 6
|
||||
#define B00110 6
|
||||
#define B000110 6
|
||||
#define B0000110 6
|
||||
#define B00000110 6
|
||||
#define B111 7
|
||||
#define B0111 7
|
||||
#define B00111 7
|
||||
#define B000111 7
|
||||
#define B0000111 7
|
||||
#define B00000111 7
|
||||
#define B1000 8
|
||||
#define B01000 8
|
||||
#define B001000 8
|
||||
#define B0001000 8
|
||||
#define B00001000 8
|
||||
#define B1001 9
|
||||
#define B01001 9
|
||||
#define B001001 9
|
||||
#define B0001001 9
|
||||
#define B00001001 9
|
||||
#define B1010 10
|
||||
#define B01010 10
|
||||
#define B001010 10
|
||||
#define B0001010 10
|
||||
#define B00001010 10
|
||||
#define B1011 11
|
||||
#define B01011 11
|
||||
#define B001011 11
|
||||
#define B0001011 11
|
||||
#define B00001011 11
|
||||
#define B1100 12
|
||||
#define B01100 12
|
||||
#define B001100 12
|
||||
#define B0001100 12
|
||||
#define B00001100 12
|
||||
#define B1101 13
|
||||
#define B01101 13
|
||||
#define B001101 13
|
||||
#define B0001101 13
|
||||
#define B00001101 13
|
||||
#define B1110 14
|
||||
#define B01110 14
|
||||
#define B001110 14
|
||||
#define B0001110 14
|
||||
#define B00001110 14
|
||||
#define B1111 15
|
||||
#define B01111 15
|
||||
#define B001111 15
|
||||
#define B0001111 15
|
||||
#define B00001111 15
|
||||
#define B10000 16
|
||||
#define B010000 16
|
||||
#define B0010000 16
|
||||
#define B00010000 16
|
||||
#define B10001 17
|
||||
#define B010001 17
|
||||
#define B0010001 17
|
||||
#define B00010001 17
|
||||
#define B10010 18
|
||||
#define B010010 18
|
||||
#define B0010010 18
|
||||
#define B00010010 18
|
||||
#define B10011 19
|
||||
#define B010011 19
|
||||
#define B0010011 19
|
||||
#define B00010011 19
|
||||
#define B10100 20
|
||||
#define B010100 20
|
||||
#define B0010100 20
|
||||
#define B00010100 20
|
||||
#define B10101 21
|
||||
#define B010101 21
|
||||
#define B0010101 21
|
||||
#define B00010101 21
|
||||
#define B10110 22
|
||||
#define B010110 22
|
||||
#define B0010110 22
|
||||
#define B00010110 22
|
||||
#define B10111 23
|
||||
#define B010111 23
|
||||
#define B0010111 23
|
||||
#define B00010111 23
|
||||
#define B11000 24
|
||||
#define B011000 24
|
||||
#define B0011000 24
|
||||
#define B00011000 24
|
||||
#define B11001 25
|
||||
#define B011001 25
|
||||
#define B0011001 25
|
||||
#define B00011001 25
|
||||
#define B11010 26
|
||||
#define B011010 26
|
||||
#define B0011010 26
|
||||
#define B00011010 26
|
||||
#define B11011 27
|
||||
#define B011011 27
|
||||
#define B0011011 27
|
||||
#define B00011011 27
|
||||
#define B11100 28
|
||||
#define B011100 28
|
||||
#define B0011100 28
|
||||
#define B00011100 28
|
||||
#define B11101 29
|
||||
#define B011101 29
|
||||
#define B0011101 29
|
||||
#define B00011101 29
|
||||
#define B11110 30
|
||||
#define B011110 30
|
||||
#define B0011110 30
|
||||
#define B00011110 30
|
||||
#define B11111 31
|
||||
#define B011111 31
|
||||
#define B0011111 31
|
||||
#define B00011111 31
|
||||
#define B100000 32
|
||||
#define B0100000 32
|
||||
#define B00100000 32
|
||||
#define B100001 33
|
||||
#define B0100001 33
|
||||
#define B00100001 33
|
||||
#define B100010 34
|
||||
#define B0100010 34
|
||||
#define B00100010 34
|
||||
#define B100011 35
|
||||
#define B0100011 35
|
||||
#define B00100011 35
|
||||
#define B100100 36
|
||||
#define B0100100 36
|
||||
#define B00100100 36
|
||||
#define B100101 37
|
||||
#define B0100101 37
|
||||
#define B00100101 37
|
||||
#define B100110 38
|
||||
#define B0100110 38
|
||||
#define B00100110 38
|
||||
#define B100111 39
|
||||
#define B0100111 39
|
||||
#define B00100111 39
|
||||
#define B101000 40
|
||||
#define B0101000 40
|
||||
#define B00101000 40
|
||||
#define B101001 41
|
||||
#define B0101001 41
|
||||
#define B00101001 41
|
||||
#define B101010 42
|
||||
#define B0101010 42
|
||||
#define B00101010 42
|
||||
#define B101011 43
|
||||
#define B0101011 43
|
||||
#define B00101011 43
|
||||
#define B101100 44
|
||||
#define B0101100 44
|
||||
#define B00101100 44
|
||||
#define B101101 45
|
||||
#define B0101101 45
|
||||
#define B00101101 45
|
||||
#define B101110 46
|
||||
#define B0101110 46
|
||||
#define B00101110 46
|
||||
#define B101111 47
|
||||
#define B0101111 47
|
||||
#define B00101111 47
|
||||
#define B110000 48
|
||||
#define B0110000 48
|
||||
#define B00110000 48
|
||||
#define B110001 49
|
||||
#define B0110001 49
|
||||
#define B00110001 49
|
||||
#define B110010 50
|
||||
#define B0110010 50
|
||||
#define B00110010 50
|
||||
#define B110011 51
|
||||
#define B0110011 51
|
||||
#define B00110011 51
|
||||
#define B110100 52
|
||||
#define B0110100 52
|
||||
#define B00110100 52
|
||||
#define B110101 53
|
||||
#define B0110101 53
|
||||
#define B00110101 53
|
||||
#define B110110 54
|
||||
#define B0110110 54
|
||||
#define B00110110 54
|
||||
#define B110111 55
|
||||
#define B0110111 55
|
||||
#define B00110111 55
|
||||
#define B111000 56
|
||||
#define B0111000 56
|
||||
#define B00111000 56
|
||||
#define B111001 57
|
||||
#define B0111001 57
|
||||
#define B00111001 57
|
||||
#define B111010 58
|
||||
#define B0111010 58
|
||||
#define B00111010 58
|
||||
#define B111011 59
|
||||
#define B0111011 59
|
||||
#define B00111011 59
|
||||
#define B111100 60
|
||||
#define B0111100 60
|
||||
#define B00111100 60
|
||||
#define B111101 61
|
||||
#define B0111101 61
|
||||
#define B00111101 61
|
||||
#define B111110 62
|
||||
#define B0111110 62
|
||||
#define B00111110 62
|
||||
#define B111111 63
|
||||
#define B0111111 63
|
||||
#define B00111111 63
|
||||
#define B1000000 64
|
||||
#define B01000000 64
|
||||
#define B1000001 65
|
||||
#define B01000001 65
|
||||
#define B1000010 66
|
||||
#define B01000010 66
|
||||
#define B1000011 67
|
||||
#define B01000011 67
|
||||
#define B1000100 68
|
||||
#define B01000100 68
|
||||
#define B1000101 69
|
||||
#define B01000101 69
|
||||
#define B1000110 70
|
||||
#define B01000110 70
|
||||
#define B1000111 71
|
||||
#define B01000111 71
|
||||
#define B1001000 72
|
||||
#define B01001000 72
|
||||
#define B1001001 73
|
||||
#define B01001001 73
|
||||
#define B1001010 74
|
||||
#define B01001010 74
|
||||
#define B1001011 75
|
||||
#define B01001011 75
|
||||
#define B1001100 76
|
||||
#define B01001100 76
|
||||
#define B1001101 77
|
||||
#define B01001101 77
|
||||
#define B1001110 78
|
||||
#define B01001110 78
|
||||
#define B1001111 79
|
||||
#define B01001111 79
|
||||
#define B1010000 80
|
||||
#define B01010000 80
|
||||
#define B1010001 81
|
||||
#define B01010001 81
|
||||
#define B1010010 82
|
||||
#define B01010010 82
|
||||
#define B1010011 83
|
||||
#define B01010011 83
|
||||
#define B1010100 84
|
||||
#define B01010100 84
|
||||
#define B1010101 85
|
||||
#define B01010101 85
|
||||
#define B1010110 86
|
||||
#define B01010110 86
|
||||
#define B1010111 87
|
||||
#define B01010111 87
|
||||
#define B1011000 88
|
||||
#define B01011000 88
|
||||
#define B1011001 89
|
||||
#define B01011001 89
|
||||
#define B1011010 90
|
||||
#define B01011010 90
|
||||
#define B1011011 91
|
||||
#define B01011011 91
|
||||
#define B1011100 92
|
||||
#define B01011100 92
|
||||
#define B1011101 93
|
||||
#define B01011101 93
|
||||
#define B1011110 94
|
||||
#define B01011110 94
|
||||
#define B1011111 95
|
||||
#define B01011111 95
|
||||
#define B1100000 96
|
||||
#define B01100000 96
|
||||
#define B1100001 97
|
||||
#define B01100001 97
|
||||
#define B1100010 98
|
||||
#define B01100010 98
|
||||
#define B1100011 99
|
||||
#define B01100011 99
|
||||
#define B1100100 100
|
||||
#define B01100100 100
|
||||
#define B1100101 101
|
||||
#define B01100101 101
|
||||
#define B1100110 102
|
||||
#define B01100110 102
|
||||
#define B1100111 103
|
||||
#define B01100111 103
|
||||
#define B1101000 104
|
||||
#define B01101000 104
|
||||
#define B1101001 105
|
||||
#define B01101001 105
|
||||
#define B1101010 106
|
||||
#define B01101010 106
|
||||
#define B1101011 107
|
||||
#define B01101011 107
|
||||
#define B1101100 108
|
||||
#define B01101100 108
|
||||
#define B1101101 109
|
||||
#define B01101101 109
|
||||
#define B1101110 110
|
||||
#define B01101110 110
|
||||
#define B1101111 111
|
||||
#define B01101111 111
|
||||
#define B1110000 112
|
||||
#define B01110000 112
|
||||
#define B1110001 113
|
||||
#define B01110001 113
|
||||
#define B1110010 114
|
||||
#define B01110010 114
|
||||
#define B1110011 115
|
||||
#define B01110011 115
|
||||
#define B1110100 116
|
||||
#define B01110100 116
|
||||
#define B1110101 117
|
||||
#define B01110101 117
|
||||
#define B1110110 118
|
||||
#define B01110110 118
|
||||
#define B1110111 119
|
||||
#define B01110111 119
|
||||
#define B1111000 120
|
||||
#define B01111000 120
|
||||
#define B1111001 121
|
||||
#define B01111001 121
|
||||
#define B1111010 122
|
||||
#define B01111010 122
|
||||
#define B1111011 123
|
||||
#define B01111011 123
|
||||
#define B1111100 124
|
||||
#define B01111100 124
|
||||
#define B1111101 125
|
||||
#define B01111101 125
|
||||
#define B1111110 126
|
||||
#define B01111110 126
|
||||
#define B1111111 127
|
||||
#define B01111111 127
|
||||
#define B10000000 128
|
||||
#define B10000001 129
|
||||
#define B10000010 130
|
||||
#define B10000011 131
|
||||
#define B10000100 132
|
||||
#define B10000101 133
|
||||
#define B10000110 134
|
||||
#define B10000111 135
|
||||
#define B10001000 136
|
||||
#define B10001001 137
|
||||
#define B10001010 138
|
||||
#define B10001011 139
|
||||
#define B10001100 140
|
||||
#define B10001101 141
|
||||
#define B10001110 142
|
||||
#define B10001111 143
|
||||
#define B10010000 144
|
||||
#define B10010001 145
|
||||
#define B10010010 146
|
||||
#define B10010011 147
|
||||
#define B10010100 148
|
||||
#define B10010101 149
|
||||
#define B10010110 150
|
||||
#define B10010111 151
|
||||
#define B10011000 152
|
||||
#define B10011001 153
|
||||
#define B10011010 154
|
||||
#define B10011011 155
|
||||
#define B10011100 156
|
||||
#define B10011101 157
|
||||
#define B10011110 158
|
||||
#define B10011111 159
|
||||
#define B10100000 160
|
||||
#define B10100001 161
|
||||
#define B10100010 162
|
||||
#define B10100011 163
|
||||
#define B10100100 164
|
||||
#define B10100101 165
|
||||
#define B10100110 166
|
||||
#define B10100111 167
|
||||
#define B10101000 168
|
||||
#define B10101001 169
|
||||
#define B10101010 170
|
||||
#define B10101011 171
|
||||
#define B10101100 172
|
||||
#define B10101101 173
|
||||
#define B10101110 174
|
||||
#define B10101111 175
|
||||
#define B10110000 176
|
||||
#define B10110001 177
|
||||
#define B10110010 178
|
||||
#define B10110011 179
|
||||
#define B10110100 180
|
||||
#define B10110101 181
|
||||
#define B10110110 182
|
||||
#define B10110111 183
|
||||
#define B10111000 184
|
||||
#define B10111001 185
|
||||
#define B10111010 186
|
||||
#define B10111011 187
|
||||
#define B10111100 188
|
||||
#define B10111101 189
|
||||
#define B10111110 190
|
||||
#define B10111111 191
|
||||
#define B11000000 192
|
||||
#define B11000001 193
|
||||
#define B11000010 194
|
||||
#define B11000011 195
|
||||
#define B11000100 196
|
||||
#define B11000101 197
|
||||
#define B11000110 198
|
||||
#define B11000111 199
|
||||
#define B11001000 200
|
||||
#define B11001001 201
|
||||
#define B11001010 202
|
||||
#define B11001011 203
|
||||
#define B11001100 204
|
||||
#define B11001101 205
|
||||
#define B11001110 206
|
||||
#define B11001111 207
|
||||
#define B11010000 208
|
||||
#define B11010001 209
|
||||
#define B11010010 210
|
||||
#define B11010011 211
|
||||
#define B11010100 212
|
||||
#define B11010101 213
|
||||
#define B11010110 214
|
||||
#define B11010111 215
|
||||
#define B11011000 216
|
||||
#define B11011001 217
|
||||
#define B11011010 218
|
||||
#define B11011011 219
|
||||
#define B11011100 220
|
||||
#define B11011101 221
|
||||
#define B11011110 222
|
||||
#define B11011111 223
|
||||
#define B11100000 224
|
||||
#define B11100001 225
|
||||
#define B11100010 226
|
||||
#define B11100011 227
|
||||
#define B11100100 228
|
||||
#define B11100101 229
|
||||
#define B11100110 230
|
||||
#define B11100111 231
|
||||
#define B11101000 232
|
||||
#define B11101001 233
|
||||
#define B11101010 234
|
||||
#define B11101011 235
|
||||
#define B11101100 236
|
||||
#define B11101101 237
|
||||
#define B11101110 238
|
||||
#define B11101111 239
|
||||
#define B11110000 240
|
||||
#define B11110001 241
|
||||
#define B11110010 242
|
||||
#define B11110011 243
|
||||
#define B11110100 244
|
||||
#define B11110101 245
|
||||
#define B11110110 246
|
||||
#define B11110111 247
|
||||
#define B11111000 248
|
||||
#define B11111001 249
|
||||
#define B11111010 250
|
||||
#define B11111011 251
|
||||
#define B11111100 252
|
||||
#define B11111101 253
|
||||
#define B11111110 254
|
||||
#define B11111111 255
|
||||
|
||||
#endif
|
||||
1757
teensy3/core_cm4.h
Normal file
1757
teensy3/core_cm4.h
Normal file
File diff suppressed because it is too large
Load diff
541
teensy3/core_cm4_simd.h
Normal file
541
teensy3/core_cm4_simd.h
Normal file
|
|
@ -0,0 +1,541 @@
|
|||
/**************************************************************************//**
|
||||
* @file core_cm4_simd.h
|
||||
* @brief CMSIS Cortex-M4 SIMD Header File
|
||||
* @version V3.01
|
||||
* @date 06. March 2012
|
||||
*
|
||||
* @note
|
||||
* Copyright (C) 2010-2012 ARM Limited. All rights reserved.
|
||||
*
|
||||
* @par
|
||||
* ARM Limited (ARM) is supplying this software for use with Cortex-M
|
||||
* processor based microcontrollers. This file can be freely distributed
|
||||
* within development tools that are supporting such ARM based processors.
|
||||
*
|
||||
* @par
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
|
||||
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
|
||||
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
|
||||
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef __CORE_CM4_SIMD_H
|
||||
#define __CORE_CM4_SIMD_H
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Hardware Abstraction Layer
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/* ################### Compiler specific Intrinsics ########################### */
|
||||
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
|
||||
Access to dedicated SIMD instructions
|
||||
@{
|
||||
*/
|
||||
|
||||
|
||||
#if defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
|
||||
/* GNU gcc specific functions */
|
||||
|
||||
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
#define __SSAT16(ARG1,ARG2) \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1); \
|
||||
__ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
#define __USAT16(ARG1,ARG2) \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1); \
|
||||
__ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1));
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1));
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
#define __SMLALD(ARG1,ARG2,ARG3) \
|
||||
({ \
|
||||
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \
|
||||
__ASM volatile ("smlald %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
|
||||
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
|
||||
})
|
||||
|
||||
#define __SMLALDX(ARG1,ARG2,ARG3) \
|
||||
({ \
|
||||
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \
|
||||
__ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
|
||||
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
|
||||
})
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
#define __SMLSLD(ARG1,ARG2,ARG3) \
|
||||
({ \
|
||||
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \
|
||||
__ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
|
||||
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
|
||||
})
|
||||
|
||||
#define __SMLSLDX(ARG1,ARG2,ARG3) \
|
||||
({ \
|
||||
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \
|
||||
__ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
|
||||
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
|
||||
})
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
#define __PKHBT(ARG1,ARG2,ARG3) \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
|
||||
__ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
#define __PKHTB(ARG1,ARG2,ARG3) \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
|
||||
if (ARG3 == 0) \
|
||||
__ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \
|
||||
else \
|
||||
__ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
|
||||
|
||||
#endif /* __GNUC__ */
|
||||
|
||||
#endif /* __CORE_CM4_SIMD_H */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
374
teensy3/core_cmInstr.h
Normal file
374
teensy3/core_cmInstr.h
Normal file
|
|
@ -0,0 +1,374 @@
|
|||
/**************************************************************************//**
|
||||
* @file core_cmInstr.h
|
||||
* @brief CMSIS Cortex-M Core Instruction Access Header File
|
||||
* @version V3.01
|
||||
* @date 06. March 2012
|
||||
*
|
||||
* @note
|
||||
* Copyright (C) 2009-2012 ARM Limited. All rights reserved.
|
||||
*
|
||||
* @par
|
||||
* ARM Limited (ARM) is supplying this software for use with Cortex-M
|
||||
* processor based microcontrollers. This file can be freely distributed
|
||||
* within development tools that are supporting such ARM based processors.
|
||||
*
|
||||
* @par
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
|
||||
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
|
||||
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
|
||||
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __CORE_CMINSTR_H
|
||||
#define __CORE_CMINSTR_H
|
||||
|
||||
|
||||
/* ########################## Core Instruction Access ######################### */
|
||||
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
|
||||
Access to dedicated instructions
|
||||
@{
|
||||
*/
|
||||
|
||||
|
||||
#if defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
|
||||
/* GNU gcc specific functions */
|
||||
|
||||
/** \brief No Operation
|
||||
|
||||
No Operation does nothing. This instruction can be used for code alignment purposes.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __NOP(void)
|
||||
{
|
||||
__ASM volatile ("nop");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Wait For Interrupt
|
||||
|
||||
Wait For Interrupt is a hint instruction that suspends execution
|
||||
until one of a number of events occurs.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFI(void)
|
||||
{
|
||||
__ASM volatile ("wfi");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Wait For Event
|
||||
|
||||
Wait For Event is a hint instruction that permits the processor to enter
|
||||
a low-power state until one of a number of events occurs.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFE(void)
|
||||
{
|
||||
__ASM volatile ("wfe");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Send Event
|
||||
|
||||
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __SEV(void)
|
||||
{
|
||||
__ASM volatile ("sev");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Instruction Synchronization Barrier
|
||||
|
||||
Instruction Synchronization Barrier flushes the pipeline in the processor,
|
||||
so that all instructions following the ISB are fetched from cache or
|
||||
memory, after the instruction has been completed.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __ISB(void)
|
||||
{
|
||||
__ASM volatile ("isb");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Data Synchronization Barrier
|
||||
|
||||
This function acts as a special kind of Data Memory Barrier.
|
||||
It completes when all explicit memory accesses before this instruction complete.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __DSB(void)
|
||||
{
|
||||
__ASM volatile ("dsb");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Data Memory Barrier
|
||||
|
||||
This function ensures the apparent order of the explicit memory operations before
|
||||
and after the instruction, without ensuring their completion.
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __DMB(void)
|
||||
{
|
||||
__ASM volatile ("dmb");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Reverse byte order (32 bit)
|
||||
|
||||
This function reverses the byte order in integer value.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Reverse byte order (16 bit)
|
||||
|
||||
This function reverses the byte order in two unsigned short values.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV16(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Reverse byte order in signed short value
|
||||
|
||||
This function reverses the byte order in a signed short value with sign extension to integer.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __REVSH(int32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Rotate Right in unsigned value (32 bit)
|
||||
|
||||
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
|
||||
|
||||
\param [in] value Value to rotate
|
||||
\param [in] value Number of Bits to rotate
|
||||
\return Rotated value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
|
||||
__ASM volatile ("ror %0, %0, %1" : "+r" (op1) : "r" (op2) );
|
||||
return(op1);
|
||||
}
|
||||
|
||||
|
||||
#if (__CORTEX_M >= 0x03)
|
||||
|
||||
/** \brief Reverse bit order of value
|
||||
|
||||
This function reverses the bit order of the given value.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (8 bit)
|
||||
|
||||
This function performs a exclusive LDR command for 8 bit value.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint8_t at (*ptr)
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr)
|
||||
{
|
||||
uint8_t result;
|
||||
|
||||
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (16 bit)
|
||||
|
||||
This function performs a exclusive LDR command for 16 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint16_t at (*ptr)
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr)
|
||||
{
|
||||
uint16_t result;
|
||||
|
||||
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (32 bit)
|
||||
|
||||
This function performs a exclusive LDR command for 32 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint32_t at (*ptr)
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief STR Exclusive (8 bit)
|
||||
|
||||
This function performs a exclusive STR command for 8 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("strexb %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief STR Exclusive (16 bit)
|
||||
|
||||
This function performs a exclusive STR command for 16 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("strexh %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief STR Exclusive (32 bit)
|
||||
|
||||
This function performs a exclusive STR command for 32 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("strex %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Remove the exclusive lock
|
||||
|
||||
This function removes the exclusive lock which is created by LDREX.
|
||||
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE void __CLREX(void)
|
||||
{
|
||||
__ASM volatile ("clrex");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Signed Saturate
|
||||
|
||||
This function saturates a signed value.
|
||||
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (1..32)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __SSAT(ARG1,ARG2) \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1); \
|
||||
__ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
|
||||
/** \brief Unsigned Saturate
|
||||
|
||||
This function saturates an unsigned value.
|
||||
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (0..31)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __USAT(ARG1,ARG2) \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1); \
|
||||
__ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
|
||||
/** \brief Count leading zeros
|
||||
|
||||
This function counts the number of leading zeros of a data value.
|
||||
|
||||
\param [in] value Value to count the leading zeros
|
||||
\return number of leading zeros in value
|
||||
*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __CLZ(uint32_t value)
|
||||
{
|
||||
uint8_t result;
|
||||
|
||||
__ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
#endif /* (__CORTEX_M >= 0x03) */
|
||||
|
||||
|
||||
|
||||
|
||||
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
|
||||
/* TASKING carm specific functions */
|
||||
|
||||
/*
|
||||
* The CMSIS functions have been implemented as intrinsics in the compiler.
|
||||
* Please use "carm -?i" to get an up to date list of all intrinsics,
|
||||
* Including the CMSIS ones.
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
|
||||
|
||||
#endif /* __CORE_CMINSTR_H */
|
||||
3
teensy3/core_id.h
Normal file
3
teensy3/core_id.h
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
#ifndef CORE_TEENSY
|
||||
#define CORE_TEENSY
|
||||
#endif
|
||||
815
teensy3/core_pins.h
Normal file
815
teensy3/core_pins.h
Normal file
|
|
@ -0,0 +1,815 @@
|
|||
/* Teensyduino Core Library
|
||||
* http://www.pjrc.com/teensy/
|
||||
* Copyright (c) 2013 PJRC.COM, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* 1. The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* 2. If the Software is incorporated into a build system that allows
|
||||
* selection among a list of target devices, then similar target
|
||||
* devices manufactured by PJRC.COM must be included in the list of
|
||||
* target devices and selectable in the same manner.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _core_pins_h_
|
||||
#define _core_pins_h_
|
||||
|
||||
#include "mk20dx128.h"
|
||||
#include "pins_arduino.h"
|
||||
|
||||
|
||||
#define HIGH 1
|
||||
#define LOW 0
|
||||
#define INPUT 0
|
||||
#define OUTPUT 1
|
||||
#define INPUT_PULLUP 2
|
||||
#define LSBFIRST 0
|
||||
#define MSBFIRST 1
|
||||
#define _BV(n) (1<<(n))
|
||||
#define CHANGE 4
|
||||
#define FALLING 2
|
||||
#define RISING 3
|
||||
|
||||
// Pin Arduino
|
||||
// 0 B16 RXD
|
||||
// 1 B17 TXD
|
||||
// 2 D0
|
||||
// 3 A12 FTM1_CH0
|
||||
// 4 A13 FTM1_CH1
|
||||
// 5 D7 FTM0_CH7 OC0B/T1
|
||||
// 6 D4 FTM0_CH4 OC0A
|
||||
// 7 D2
|
||||
// 8 D3 ICP1
|
||||
// 9 C3 FTM0_CH2 OC1A
|
||||
// 10 C4 FTM0_CH3 SS/OC1B
|
||||
// 11 C6 MOSI/OC2A
|
||||
// 12 C7 MISO
|
||||
// 13 C5 SCK
|
||||
// 14 D1
|
||||
// 15 C0
|
||||
// 16 B0 (FTM1_CH0)
|
||||
// 17 B1 (FTM1_CH1)
|
||||
// 18 B3 SDA
|
||||
// 19 B2 SCL
|
||||
// 20 D5 FTM0_CH5
|
||||
// 21 D6 FTM0_CH6
|
||||
// 22 C1 FTM0_CH0
|
||||
// 23 C2 FTM0_CH1
|
||||
// 24 A5 (FTM0_CH2)
|
||||
// 25 B19
|
||||
// 26 E1
|
||||
// 27 C9
|
||||
// 28 C8
|
||||
// 29 C10
|
||||
// 30 C11
|
||||
// 31 E0
|
||||
// 32 B18
|
||||
// 33 A4 (FTM0_CH1)
|
||||
// (34) analog only
|
||||
// (35) analog only
|
||||
// (36) analog only
|
||||
// (37) analog only
|
||||
|
||||
// not available to user:
|
||||
// A0 FTM0_CH5 SWD Clock
|
||||
// A1 FTM0_CH6 USB ID
|
||||
// A2 FTM0_CH7 SWD Trace
|
||||
// A3 FTM0_CH0 SWD Data
|
||||
|
||||
#define CORE_NUM_TOTAL_PINS 34
|
||||
#define CORE_NUM_DIGITAL 34
|
||||
#define CORE_NUM_ANALOG 14
|
||||
#define CORE_NUM_PWM 10
|
||||
#define CORE_NUM_INTERRUPT 34
|
||||
|
||||
#define CORE_PIN0_BIT 16
|
||||
#define CORE_PIN1_BIT 17
|
||||
#define CORE_PIN2_BIT 0
|
||||
#define CORE_PIN3_BIT 12
|
||||
#define CORE_PIN4_BIT 13
|
||||
#define CORE_PIN5_BIT 7
|
||||
#define CORE_PIN6_BIT 4
|
||||
#define CORE_PIN7_BIT 2
|
||||
#define CORE_PIN8_BIT 3
|
||||
#define CORE_PIN9_BIT 3
|
||||
#define CORE_PIN10_BIT 4
|
||||
#define CORE_PIN11_BIT 6
|
||||
#define CORE_PIN12_BIT 7
|
||||
#define CORE_PIN13_BIT 5
|
||||
#define CORE_PIN14_BIT 1
|
||||
#define CORE_PIN15_BIT 0
|
||||
#define CORE_PIN16_BIT 0
|
||||
#define CORE_PIN17_BIT 1
|
||||
#define CORE_PIN18_BIT 3
|
||||
#define CORE_PIN19_BIT 2
|
||||
#define CORE_PIN20_BIT 5
|
||||
#define CORE_PIN21_BIT 6
|
||||
#define CORE_PIN22_BIT 1
|
||||
#define CORE_PIN23_BIT 2
|
||||
#define CORE_PIN24_BIT 5
|
||||
#define CORE_PIN25_BIT 19
|
||||
#define CORE_PIN26_BIT 1
|
||||
#define CORE_PIN27_BIT 9
|
||||
#define CORE_PIN28_BIT 8
|
||||
#define CORE_PIN29_BIT 10
|
||||
#define CORE_PIN30_BIT 11
|
||||
#define CORE_PIN31_BIT 0
|
||||
#define CORE_PIN32_BIT 18
|
||||
#define CORE_PIN33_BIT 4
|
||||
|
||||
#define CORE_PIN0_BITMASK (1<<(CORE_PIN0_BIT))
|
||||
#define CORE_PIN1_BITMASK (1<<(CORE_PIN1_BIT))
|
||||
#define CORE_PIN2_BITMASK (1<<(CORE_PIN2_BIT))
|
||||
#define CORE_PIN3_BITMASK (1<<(CORE_PIN3_BIT))
|
||||
#define CORE_PIN4_BITMASK (1<<(CORE_PIN4_BIT))
|
||||
#define CORE_PIN5_BITMASK (1<<(CORE_PIN5_BIT))
|
||||
#define CORE_PIN6_BITMASK (1<<(CORE_PIN6_BIT))
|
||||
#define CORE_PIN7_BITMASK (1<<(CORE_PIN7_BIT))
|
||||
#define CORE_PIN8_BITMASK (1<<(CORE_PIN8_BIT))
|
||||
#define CORE_PIN9_BITMASK (1<<(CORE_PIN9_BIT))
|
||||
#define CORE_PIN10_BITMASK (1<<(CORE_PIN10_BIT))
|
||||
#define CORE_PIN11_BITMASK (1<<(CORE_PIN11_BIT))
|
||||
#define CORE_PIN12_BITMASK (1<<(CORE_PIN12_BIT))
|
||||
#define CORE_PIN13_BITMASK (1<<(CORE_PIN13_BIT))
|
||||
#define CORE_PIN14_BITMASK (1<<(CORE_PIN14_BIT))
|
||||
#define CORE_PIN15_BITMASK (1<<(CORE_PIN15_BIT))
|
||||
#define CORE_PIN16_BITMASK (1<<(CORE_PIN16_BIT))
|
||||
#define CORE_PIN17_BITMASK (1<<(CORE_PIN17_BIT))
|
||||
#define CORE_PIN18_BITMASK (1<<(CORE_PIN18_BIT))
|
||||
#define CORE_PIN19_BITMASK (1<<(CORE_PIN19_BIT))
|
||||
#define CORE_PIN20_BITMASK (1<<(CORE_PIN20_BIT))
|
||||
#define CORE_PIN21_BITMASK (1<<(CORE_PIN21_BIT))
|
||||
#define CORE_PIN22_BITMASK (1<<(CORE_PIN22_BIT))
|
||||
#define CORE_PIN23_BITMASK (1<<(CORE_PIN23_BIT))
|
||||
#define CORE_PIN24_BITMASK (1<<(CORE_PIN24_BIT))
|
||||
#define CORE_PIN25_BITMASK (1<<(CORE_PIN25_BIT))
|
||||
#define CORE_PIN26_BITMASK (1<<(CORE_PIN26_BIT))
|
||||
#define CORE_PIN27_BITMASK (1<<(CORE_PIN27_BIT))
|
||||
#define CORE_PIN28_BITMASK (1<<(CORE_PIN28_BIT))
|
||||
#define CORE_PIN29_BITMASK (1<<(CORE_PIN29_BIT))
|
||||
#define CORE_PIN30_BITMASK (1<<(CORE_PIN30_BIT))
|
||||
#define CORE_PIN31_BITMASK (1<<(CORE_PIN31_BIT))
|
||||
#define CORE_PIN32_BITMASK (1<<(CORE_PIN32_BIT))
|
||||
#define CORE_PIN33_BITMASK (1<<(CORE_PIN33_BIT))
|
||||
|
||||
#define CORE_PIN0_PORTREG GPIOB_PDOR
|
||||
#define CORE_PIN1_PORTREG GPIOB_PDOR
|
||||
#define CORE_PIN2_PORTREG GPIOD_PDOR
|
||||
#define CORE_PIN3_PORTREG GPIOA_PDOR
|
||||
#define CORE_PIN4_PORTREG GPIOA_PDOR
|
||||
#define CORE_PIN5_PORTREG GPIOD_PDOR
|
||||
#define CORE_PIN6_PORTREG GPIOD_PDOR
|
||||
#define CORE_PIN7_PORTREG GPIOD_PDOR
|
||||
#define CORE_PIN8_PORTREG GPIOD_PDOR
|
||||
#define CORE_PIN9_PORTREG GPIOC_PDOR
|
||||
#define CORE_PIN10_PORTREG GPIOC_PDOR
|
||||
#define CORE_PIN11_PORTREG GPIOC_PDOR
|
||||
#define CORE_PIN12_PORTREG GPIOC_PDOR
|
||||
#define CORE_PIN13_PORTREG GPIOC_PDOR
|
||||
#define CORE_PIN14_PORTREG GPIOD_PDOR
|
||||
#define CORE_PIN15_PORTREG GPIOC_PDOR
|
||||
#define CORE_PIN16_PORTREG GPIOB_PDOR
|
||||
#define CORE_PIN17_PORTREG GPIOB_PDOR
|
||||
#define CORE_PIN18_PORTREG GPIOB_PDOR
|
||||
#define CORE_PIN19_PORTREG GPIOB_PDOR
|
||||
#define CORE_PIN20_PORTREG GPIOD_PDOR
|
||||
#define CORE_PIN21_PORTREG GPIOD_PDOR
|
||||
#define CORE_PIN22_PORTREG GPIOC_PDOR
|
||||
#define CORE_PIN23_PORTREG GPIOC_PDOR
|
||||
#define CORE_PIN24_PORTREG GPIOA_PDOR
|
||||
#define CORE_PIN25_PORTREG GPIOB_PDOR
|
||||
#define CORE_PIN26_PORTREG GPIOE_PDOR
|
||||
#define CORE_PIN27_PORTREG GPIOC_PDOR
|
||||
#define CORE_PIN28_PORTREG GPIOC_PDOR
|
||||
#define CORE_PIN29_PORTREG GPIOC_PDOR
|
||||
#define CORE_PIN30_PORTREG GPIOC_PDOR
|
||||
#define CORE_PIN31_PORTREG GPIOE_PDOR
|
||||
#define CORE_PIN32_PORTREG GPIOB_PDOR
|
||||
#define CORE_PIN33_PORTREG GPIOA_PDOR
|
||||
|
||||
#define CORE_PIN0_PORTSET GPIOB_PSOR
|
||||
#define CORE_PIN1_PORTSET GPIOB_PSOR
|
||||
#define CORE_PIN2_PORTSET GPIOD_PSOR
|
||||
#define CORE_PIN3_PORTSET GPIOA_PSOR
|
||||
#define CORE_PIN4_PORTSET GPIOA_PSOR
|
||||
#define CORE_PIN5_PORTSET GPIOD_PSOR
|
||||
#define CORE_PIN6_PORTSET GPIOD_PSOR
|
||||
#define CORE_PIN7_PORTSET GPIOD_PSOR
|
||||
#define CORE_PIN8_PORTSET GPIOD_PSOR
|
||||
#define CORE_PIN9_PORTSET GPIOC_PSOR
|
||||
#define CORE_PIN10_PORTSET GPIOC_PSOR
|
||||
#define CORE_PIN11_PORTSET GPIOC_PSOR
|
||||
#define CORE_PIN12_PORTSET GPIOC_PSOR
|
||||
#define CORE_PIN13_PORTSET GPIOC_PSOR
|
||||
#define CORE_PIN14_PORTSET GPIOD_PSOR
|
||||
#define CORE_PIN15_PORTSET GPIOC_PSOR
|
||||
#define CORE_PIN16_PORTSET GPIOB_PSOR
|
||||
#define CORE_PIN17_PORTSET GPIOB_PSOR
|
||||
#define CORE_PIN18_PORTSET GPIOB_PSOR
|
||||
#define CORE_PIN19_PORTSET GPIOB_PSOR
|
||||
#define CORE_PIN20_PORTSET GPIOD_PSOR
|
||||
#define CORE_PIN21_PORTSET GPIOD_PSOR
|
||||
#define CORE_PIN22_PORTSET GPIOC_PSOR
|
||||
#define CORE_PIN23_PORTSET GPIOC_PSOR
|
||||
#define CORE_PIN24_PORTSET GPIOA_PSOR
|
||||
#define CORE_PIN25_PORTSET GPIOB_PSOR
|
||||
#define CORE_PIN26_PORTSET GPIOE_PSOR
|
||||
#define CORE_PIN27_PORTSET GPIOC_PSOR
|
||||
#define CORE_PIN28_PORTSET GPIOC_PSOR
|
||||
#define CORE_PIN29_PORTSET GPIOC_PSOR
|
||||
#define CORE_PIN30_PORTSET GPIOC_PSOR
|
||||
#define CORE_PIN31_PORTSET GPIOE_PSOR
|
||||
#define CORE_PIN32_PORTSET GPIOB_PSOR
|
||||
#define CORE_PIN33_PORTSET GPIOA_PSOR
|
||||
|
||||
#define CORE_PIN0_PORTCLEAR GPIOB_PCOR
|
||||
#define CORE_PIN1_PORTCLEAR GPIOB_PCOR
|
||||
#define CORE_PIN2_PORTCLEAR GPIOD_PCOR
|
||||
#define CORE_PIN3_PORTCLEAR GPIOA_PCOR
|
||||
#define CORE_PIN4_PORTCLEAR GPIOA_PCOR
|
||||
#define CORE_PIN5_PORTCLEAR GPIOD_PCOR
|
||||
#define CORE_PIN6_PORTCLEAR GPIOD_PCOR
|
||||
#define CORE_PIN7_PORTCLEAR GPIOD_PCOR
|
||||
#define CORE_PIN8_PORTCLEAR GPIOD_PCOR
|
||||
#define CORE_PIN9_PORTCLEAR GPIOC_PCOR
|
||||
#define CORE_PIN10_PORTCLEAR GPIOC_PCOR
|
||||
#define CORE_PIN11_PORTCLEAR GPIOC_PCOR
|
||||
#define CORE_PIN12_PORTCLEAR GPIOC_PCOR
|
||||
#define CORE_PIN13_PORTCLEAR GPIOC_PCOR
|
||||
#define CORE_PIN14_PORTCLEAR GPIOD_PCOR
|
||||
#define CORE_PIN15_PORTCLEAR GPIOC_PCOR
|
||||
#define CORE_PIN16_PORTCLEAR GPIOB_PCOR
|
||||
#define CORE_PIN17_PORTCLEAR GPIOB_PCOR
|
||||
#define CORE_PIN18_PORTCLEAR GPIOB_PCOR
|
||||
#define CORE_PIN19_PORTCLEAR GPIOB_PCOR
|
||||
#define CORE_PIN20_PORTCLEAR GPIOD_PCOR
|
||||
#define CORE_PIN21_PORTCLEAR GPIOD_PCOR
|
||||
#define CORE_PIN22_PORTCLEAR GPIOC_PCOR
|
||||
#define CORE_PIN23_PORTCLEAR GPIOC_PCOR
|
||||
#define CORE_PIN24_PORTCLEAR GPIOA_PCOR
|
||||
#define CORE_PIN25_PORTCLEAR GPIOB_PCOR
|
||||
#define CORE_PIN26_PORTCLEAR GPIOE_PCOR
|
||||
#define CORE_PIN27_PORTCLEAR GPIOC_PCOR
|
||||
#define CORE_PIN28_PORTCLEAR GPIOC_PCOR
|
||||
#define CORE_PIN29_PORTCLEAR GPIOC_PCOR
|
||||
#define CORE_PIN30_PORTCLEAR GPIOC_PCOR
|
||||
#define CORE_PIN31_PORTCLEAR GPIOE_PCOR
|
||||
#define CORE_PIN32_PORTCLEAR GPIOB_PCOR
|
||||
#define CORE_PIN33_PORTCLEAR GPIOA_PCOR
|
||||
|
||||
#define CORE_PIN0_DDRREG GPIOB_PDDR
|
||||
#define CORE_PIN1_DDRREG GPIOB_PDDR
|
||||
#define CORE_PIN2_DDRREG GPIOD_PDDR
|
||||
#define CORE_PIN3_DDRREG GPIOA_PDDR
|
||||
#define CORE_PIN4_DDRREG GPIOA_PDDR
|
||||
#define CORE_PIN5_DDRREG GPIOD_PDDR
|
||||
#define CORE_PIN6_DDRREG GPIOD_PDDR
|
||||
#define CORE_PIN7_DDRREG GPIOD_PDDR
|
||||
#define CORE_PIN8_DDRREG GPIOD_PDDR
|
||||
#define CORE_PIN9_DDRREG GPIOC_PDDR
|
||||
#define CORE_PIN10_DDRREG GPIOC_PDDR
|
||||
#define CORE_PIN11_DDRREG GPIOC_PDDR
|
||||
#define CORE_PIN12_DDRREG GPIOC_PDDR
|
||||
#define CORE_PIN13_DDRREG GPIOC_PDDR
|
||||
#define CORE_PIN14_DDRREG GPIOD_PDDR
|
||||
#define CORE_PIN15_DDRREG GPIOC_PDDR
|
||||
#define CORE_PIN16_DDRREG GPIOB_PDDR
|
||||
#define CORE_PIN17_DDRREG GPIOB_PDDR
|
||||
#define CORE_PIN18_DDRREG GPIOB_PDDR
|
||||
#define CORE_PIN19_DDRREG GPIOB_PDDR
|
||||
#define CORE_PIN20_DDRREG GPIOD_PDDR
|
||||
#define CORE_PIN21_DDRREG GPIOD_PDDR
|
||||
#define CORE_PIN22_DDRREG GPIOC_PDDR
|
||||
#define CORE_PIN23_DDRREG GPIOC_PDDR
|
||||
#define CORE_PIN24_DDRREG GPIOA_PDDR
|
||||
#define CORE_PIN25_DDRREG GPIOB_PDDR
|
||||
#define CORE_PIN26_DDRREG GPIOE_PDDR
|
||||
#define CORE_PIN27_DDRREG GPIOC_PDDR
|
||||
#define CORE_PIN28_DDRREG GPIOC_PDDR
|
||||
#define CORE_PIN29_DDRREG GPIOC_PDDR
|
||||
#define CORE_PIN30_DDRREG GPIOC_PDDR
|
||||
#define CORE_PIN31_DDRREG GPIOE_PDDR
|
||||
#define CORE_PIN32_DDRREG GPIOB_PDDR
|
||||
#define CORE_PIN33_DDRREG GPIOA_PDDR
|
||||
|
||||
#define CORE_PIN0_PINREG GPIOB_PDIR
|
||||
#define CORE_PIN1_PINREG GPIOB_PDIR
|
||||
#define CORE_PIN2_PINREG GPIOD_PDIR
|
||||
#define CORE_PIN3_PINREG GPIOA_PDIR
|
||||
#define CORE_PIN4_PINREG GPIOA_PDIR
|
||||
#define CORE_PIN5_PINREG GPIOD_PDIR
|
||||
#define CORE_PIN6_PINREG GPIOD_PDIR
|
||||
#define CORE_PIN7_PINREG GPIOD_PDIR
|
||||
#define CORE_PIN8_PINREG GPIOD_PDIR
|
||||
#define CORE_PIN9_PINREG GPIOC_PDIR
|
||||
#define CORE_PIN10_PINREG GPIOC_PDIR
|
||||
#define CORE_PIN11_PINREG GPIOC_PDIR
|
||||
#define CORE_PIN12_PINREG GPIOC_PDIR
|
||||
#define CORE_PIN13_PINREG GPIOC_PDIR
|
||||
#define CORE_PIN14_PINREG GPIOD_PDIR
|
||||
#define CORE_PIN15_PINREG GPIOC_PDIR
|
||||
#define CORE_PIN16_PINREG GPIOB_PDIR
|
||||
#define CORE_PIN17_PINREG GPIOB_PDIR
|
||||
#define CORE_PIN18_PINREG GPIOB_PDIR
|
||||
#define CORE_PIN19_PINREG GPIOB_PDIR
|
||||
#define CORE_PIN20_PINREG GPIOD_PDIR
|
||||
#define CORE_PIN21_PINREG GPIOD_PDIR
|
||||
#define CORE_PIN22_PINREG GPIOC_PDIR
|
||||
#define CORE_PIN23_PINREG GPIOC_PDIR
|
||||
#define CORE_PIN24_PINREG GPIOA_PDIR
|
||||
#define CORE_PIN25_PINREG GPIOB_PDIR
|
||||
#define CORE_PIN26_PINREG GPIOE_PDIR
|
||||
#define CORE_PIN27_PINREG GPIOC_PDIR
|
||||
#define CORE_PIN28_PINREG GPIOC_PDIR
|
||||
#define CORE_PIN29_PINREG GPIOC_PDIR
|
||||
#define CORE_PIN30_PINREG GPIOC_PDIR
|
||||
#define CORE_PIN31_PINREG GPIOE_PDIR
|
||||
#define CORE_PIN32_PINREG GPIOB_PDIR
|
||||
#define CORE_PIN33_PINREG GPIOA_PDIR
|
||||
|
||||
#define CORE_PIN0_CONFIG PORTB_PCR16
|
||||
#define CORE_PIN1_CONFIG PORTB_PCR17
|
||||
#define CORE_PIN2_CONFIG PORTD_PCR0
|
||||
#define CORE_PIN3_CONFIG PORTA_PCR12
|
||||
#define CORE_PIN4_CONFIG PORTA_PCR13
|
||||
#define CORE_PIN5_CONFIG PORTD_PCR7
|
||||
#define CORE_PIN6_CONFIG PORTD_PCR4
|
||||
#define CORE_PIN7_CONFIG PORTD_PCR2
|
||||
#define CORE_PIN8_CONFIG PORTD_PCR3
|
||||
#define CORE_PIN9_CONFIG PORTC_PCR3
|
||||
#define CORE_PIN10_CONFIG PORTC_PCR4
|
||||
#define CORE_PIN11_CONFIG PORTC_PCR6
|
||||
#define CORE_PIN12_CONFIG PORTC_PCR7
|
||||
#define CORE_PIN13_CONFIG PORTC_PCR5
|
||||
#define CORE_PIN14_CONFIG PORTD_PCR1
|
||||
#define CORE_PIN15_CONFIG PORTC_PCR0
|
||||
#define CORE_PIN16_CONFIG PORTB_PCR0
|
||||
#define CORE_PIN17_CONFIG PORTB_PCR1
|
||||
#define CORE_PIN18_CONFIG PORTB_PCR3
|
||||
#define CORE_PIN19_CONFIG PORTB_PCR2
|
||||
#define CORE_PIN20_CONFIG PORTD_PCR5
|
||||
#define CORE_PIN21_CONFIG PORTD_PCR6
|
||||
#define CORE_PIN22_CONFIG PORTC_PCR1
|
||||
#define CORE_PIN23_CONFIG PORTC_PCR2
|
||||
#define CORE_PIN24_CONFIG PORTA_PCR5
|
||||
#define CORE_PIN25_CONFIG PORTB_PCR19
|
||||
#define CORE_PIN26_CONFIG PORTE_PCR1
|
||||
#define CORE_PIN27_CONFIG PORTC_PCR9
|
||||
#define CORE_PIN28_CONFIG PORTC_PCR8
|
||||
#define CORE_PIN29_CONFIG PORTC_PCR10
|
||||
#define CORE_PIN30_CONFIG PORTC_PCR11
|
||||
#define CORE_PIN31_CONFIG PORTE_PCR0
|
||||
#define CORE_PIN32_CONFIG PORTB_PCR18
|
||||
#define CORE_PIN33_CONFIG PORTA_PCR4
|
||||
|
||||
#define CORE_ADC0_PIN 14
|
||||
#define CORE_ADC1_PIN 15
|
||||
#define CORE_ADC2_PIN 16
|
||||
#define CORE_ADC3_PIN 17
|
||||
#define CORE_ADC4_PIN 18
|
||||
#define CORE_ADC5_PIN 19
|
||||
#define CORE_ADC6_PIN 20
|
||||
#define CORE_ADC7_PIN 21
|
||||
#define CORE_ADC8_PIN 22
|
||||
#define CORE_ADC9_PIN 23
|
||||
#define CORE_ADC10_PIN 34
|
||||
#define CORE_ADC11_PIN 35
|
||||
#define CORE_ADC12_PIN 36
|
||||
#define CORE_ADC13_PIN 37
|
||||
|
||||
#define CORE_RXD0_PIN 0
|
||||
#define CORE_TXD0_PIN 1
|
||||
#define CORE_RXD1_PIN 9
|
||||
#define CORE_TXD1_PIN 10
|
||||
#define CORE_RXD2_PIN 7
|
||||
#define CORE_TXD2_PIN 8
|
||||
|
||||
#define CORE_INT0_PIN 0
|
||||
#define CORE_INT1_PIN 1
|
||||
#define CORE_INT2_PIN 2
|
||||
#define CORE_INT3_PIN 3
|
||||
#define CORE_INT4_PIN 4
|
||||
#define CORE_INT5_PIN 5
|
||||
#define CORE_INT6_PIN 6
|
||||
#define CORE_INT7_PIN 7
|
||||
#define CORE_INT8_PIN 8
|
||||
#define CORE_INT9_PIN 9
|
||||
#define CORE_INT10_PIN 10
|
||||
#define CORE_INT11_PIN 11
|
||||
#define CORE_INT12_PIN 12
|
||||
#define CORE_INT13_PIN 13
|
||||
#define CORE_INT14_PIN 14
|
||||
#define CORE_INT15_PIN 15
|
||||
#define CORE_INT16_PIN 16
|
||||
#define CORE_INT17_PIN 17
|
||||
#define CORE_INT18_PIN 18
|
||||
#define CORE_INT19_PIN 19
|
||||
#define CORE_INT20_PIN 20
|
||||
#define CORE_INT21_PIN 21
|
||||
#define CORE_INT22_PIN 22
|
||||
#define CORE_INT23_PIN 23
|
||||
#define CORE_INT24_PIN 24
|
||||
#define CORE_INT25_PIN 25
|
||||
#define CORE_INT26_PIN 26
|
||||
#define CORE_INT27_PIN 27
|
||||
#define CORE_INT28_PIN 28
|
||||
#define CORE_INT29_PIN 29
|
||||
#define CORE_INT30_PIN 30
|
||||
#define CORE_INT31_PIN 31
|
||||
#define CORE_INT32_PIN 32
|
||||
#define CORE_INT33_PIN 33
|
||||
#define CORE_INT_EVERY_PIN 1
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void digitalWrite(uint8_t pin, uint8_t val);
|
||||
static inline void digitalWriteFast(uint8_t pin, uint8_t val) __attribute__((always_inline, unused));
|
||||
static inline void digitalWriteFast(uint8_t pin, uint8_t val)
|
||||
{
|
||||
if (__builtin_constant_p(pin)) {
|
||||
if (val) {
|
||||
if (pin == 0) {
|
||||
CORE_PIN0_PORTSET = CORE_PIN0_BITMASK;
|
||||
} else if (pin == 1) {
|
||||
CORE_PIN1_PORTSET = CORE_PIN1_BITMASK;
|
||||
} else if (pin == 2) {
|
||||
CORE_PIN2_PORTSET = CORE_PIN2_BITMASK;
|
||||
} else if (pin == 3) {
|
||||
CORE_PIN3_PORTSET = CORE_PIN3_BITMASK;
|
||||
} else if (pin == 4) {
|
||||
CORE_PIN4_PORTSET = CORE_PIN4_BITMASK;
|
||||
} else if (pin == 5) {
|
||||
CORE_PIN5_PORTSET = CORE_PIN5_BITMASK;
|
||||
} else if (pin == 6) {
|
||||
CORE_PIN6_PORTSET = CORE_PIN6_BITMASK;
|
||||
} else if (pin == 7) {
|
||||
CORE_PIN7_PORTSET = CORE_PIN7_BITMASK;
|
||||
} else if (pin == 8) {
|
||||
CORE_PIN8_PORTSET = CORE_PIN8_BITMASK;
|
||||
} else if (pin == 9) {
|
||||
CORE_PIN9_PORTSET = CORE_PIN9_BITMASK;
|
||||
} else if (pin == 10) {
|
||||
CORE_PIN10_PORTSET = CORE_PIN10_BITMASK;
|
||||
} else if (pin == 11) {
|
||||
CORE_PIN11_PORTSET = CORE_PIN11_BITMASK;
|
||||
} else if (pin == 12) {
|
||||
CORE_PIN12_PORTSET = CORE_PIN12_BITMASK;
|
||||
} else if (pin == 13) {
|
||||
CORE_PIN13_PORTSET = CORE_PIN13_BITMASK;
|
||||
} else if (pin == 14) {
|
||||
CORE_PIN14_PORTSET = CORE_PIN14_BITMASK;
|
||||
} else if (pin == 15) {
|
||||
CORE_PIN15_PORTSET = CORE_PIN15_BITMASK;
|
||||
} else if (pin == 16) {
|
||||
CORE_PIN16_PORTSET = CORE_PIN16_BITMASK;
|
||||
} else if (pin == 17) {
|
||||
CORE_PIN17_PORTSET = CORE_PIN17_BITMASK;
|
||||
} else if (pin == 18) {
|
||||
CORE_PIN18_PORTSET = CORE_PIN18_BITMASK;
|
||||
} else if (pin == 19) {
|
||||
CORE_PIN19_PORTSET = CORE_PIN19_BITMASK;
|
||||
} else if (pin == 20) {
|
||||
CORE_PIN20_PORTSET = CORE_PIN20_BITMASK;
|
||||
} else if (pin == 21) {
|
||||
CORE_PIN21_PORTSET = CORE_PIN21_BITMASK;
|
||||
} else if (pin == 22) {
|
||||
CORE_PIN22_PORTSET = CORE_PIN22_BITMASK;
|
||||
} else if (pin == 23) {
|
||||
CORE_PIN23_PORTSET = CORE_PIN23_BITMASK;
|
||||
} else if (pin == 24) {
|
||||
CORE_PIN24_PORTSET = CORE_PIN24_BITMASK;
|
||||
} else if (pin == 25) {
|
||||
CORE_PIN25_PORTSET = CORE_PIN25_BITMASK;
|
||||
} else if (pin == 26) {
|
||||
CORE_PIN26_PORTSET = CORE_PIN26_BITMASK;
|
||||
} else if (pin == 27) {
|
||||
CORE_PIN27_PORTSET = CORE_PIN27_BITMASK;
|
||||
} else if (pin == 28) {
|
||||
CORE_PIN28_PORTSET = CORE_PIN28_BITMASK;
|
||||
} else if (pin == 29) {
|
||||
CORE_PIN29_PORTSET = CORE_PIN29_BITMASK;
|
||||
} else if (pin == 30) {
|
||||
CORE_PIN30_PORTSET = CORE_PIN30_BITMASK;
|
||||
} else if (pin == 31) {
|
||||
CORE_PIN31_PORTSET = CORE_PIN31_BITMASK;
|
||||
} else if (pin == 32) {
|
||||
CORE_PIN32_PORTSET = CORE_PIN32_BITMASK;
|
||||
} else if (pin == 33) {
|
||||
CORE_PIN33_PORTSET = CORE_PIN33_BITMASK;
|
||||
}
|
||||
} else {
|
||||
if (pin == 0) {
|
||||
CORE_PIN0_PORTCLEAR = CORE_PIN0_BITMASK;
|
||||
} else if (pin == 1) {
|
||||
CORE_PIN1_PORTCLEAR = CORE_PIN1_BITMASK;
|
||||
} else if (pin == 2) {
|
||||
CORE_PIN2_PORTCLEAR = CORE_PIN2_BITMASK;
|
||||
} else if (pin == 3) {
|
||||
CORE_PIN3_PORTCLEAR = CORE_PIN3_BITMASK;
|
||||
} else if (pin == 4) {
|
||||
CORE_PIN4_PORTCLEAR = CORE_PIN4_BITMASK;
|
||||
} else if (pin == 5) {
|
||||
CORE_PIN5_PORTCLEAR = CORE_PIN5_BITMASK;
|
||||
} else if (pin == 6) {
|
||||
CORE_PIN6_PORTCLEAR = CORE_PIN6_BITMASK;
|
||||
} else if (pin == 7) {
|
||||
CORE_PIN7_PORTCLEAR = CORE_PIN7_BITMASK;
|
||||
} else if (pin == 8) {
|
||||
CORE_PIN8_PORTCLEAR = CORE_PIN8_BITMASK;
|
||||
} else if (pin == 9) {
|
||||
CORE_PIN9_PORTCLEAR = CORE_PIN9_BITMASK;
|
||||
} else if (pin == 10) {
|
||||
CORE_PIN10_PORTCLEAR = CORE_PIN10_BITMASK;
|
||||
} else if (pin == 11) {
|
||||
CORE_PIN11_PORTCLEAR = CORE_PIN11_BITMASK;
|
||||
} else if (pin == 12) {
|
||||
CORE_PIN12_PORTCLEAR = CORE_PIN12_BITMASK;
|
||||
} else if (pin == 13) {
|
||||
CORE_PIN13_PORTCLEAR = CORE_PIN13_BITMASK;
|
||||
} else if (pin == 14) {
|
||||
CORE_PIN14_PORTCLEAR = CORE_PIN14_BITMASK;
|
||||
} else if (pin == 15) {
|
||||
CORE_PIN15_PORTCLEAR = CORE_PIN15_BITMASK;
|
||||
} else if (pin == 16) {
|
||||
CORE_PIN16_PORTCLEAR = CORE_PIN16_BITMASK;
|
||||
} else if (pin == 17) {
|
||||
CORE_PIN17_PORTCLEAR = CORE_PIN17_BITMASK;
|
||||
} else if (pin == 18) {
|
||||
CORE_PIN18_PORTCLEAR = CORE_PIN18_BITMASK;
|
||||
} else if (pin == 19) {
|
||||
CORE_PIN19_PORTCLEAR = CORE_PIN19_BITMASK;
|
||||
} else if (pin == 20) {
|
||||
CORE_PIN20_PORTCLEAR = CORE_PIN20_BITMASK;
|
||||
} else if (pin == 21) {
|
||||
CORE_PIN21_PORTCLEAR = CORE_PIN21_BITMASK;
|
||||
} else if (pin == 22) {
|
||||
CORE_PIN22_PORTCLEAR = CORE_PIN22_BITMASK;
|
||||
} else if (pin == 23) {
|
||||
CORE_PIN23_PORTCLEAR = CORE_PIN23_BITMASK;
|
||||
} else if (pin == 24) {
|
||||
CORE_PIN24_PORTCLEAR = CORE_PIN24_BITMASK;
|
||||
} else if (pin == 25) {
|
||||
CORE_PIN25_PORTCLEAR = CORE_PIN25_BITMASK;
|
||||
} else if (pin == 26) {
|
||||
CORE_PIN26_PORTCLEAR = CORE_PIN26_BITMASK;
|
||||
} else if (pin == 27) {
|
||||
CORE_PIN27_PORTCLEAR = CORE_PIN27_BITMASK;
|
||||
} else if (pin == 28) {
|
||||
CORE_PIN28_PORTCLEAR = CORE_PIN28_BITMASK;
|
||||
} else if (pin == 29) {
|
||||
CORE_PIN29_PORTCLEAR = CORE_PIN29_BITMASK;
|
||||
} else if (pin == 30) {
|
||||
CORE_PIN30_PORTCLEAR = CORE_PIN30_BITMASK;
|
||||
} else if (pin == 31) {
|
||||
CORE_PIN31_PORTCLEAR = CORE_PIN31_BITMASK;
|
||||
} else if (pin == 32) {
|
||||
CORE_PIN32_PORTCLEAR = CORE_PIN32_BITMASK;
|
||||
} else if (pin == 33) {
|
||||
CORE_PIN33_PORTCLEAR = CORE_PIN33_BITMASK;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (val) {
|
||||
*portSetRegister(pin) = 1;
|
||||
} else {
|
||||
*portClearRegister(pin) = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t digitalRead(uint8_t pin);
|
||||
static inline uint8_t digitalReadFast(uint8_t pin) __attribute__((always_inline, unused));
|
||||
static inline uint8_t digitalReadFast(uint8_t pin)
|
||||
{
|
||||
if (__builtin_constant_p(pin)) {
|
||||
if (pin == 0) {
|
||||
return (CORE_PIN0_PINREG & CORE_PIN0_BITMASK) ? 1 : 0;
|
||||
} else if (pin == 1) {
|
||||
return (CORE_PIN1_PINREG & CORE_PIN1_BITMASK) ? 1 : 0;
|
||||
} else if (pin == 2) {
|
||||
return (CORE_PIN2_PINREG & CORE_PIN2_BITMASK) ? 1 : 0;
|
||||
} else if (pin == 3) {
|
||||
return (CORE_PIN3_PINREG & CORE_PIN3_BITMASK) ? 1 : 0;
|
||||
} else if (pin == 4) {
|
||||
return (CORE_PIN4_PINREG & CORE_PIN4_BITMASK) ? 1 : 0;
|
||||
} else if (pin == 5) {
|
||||
return (CORE_PIN5_PINREG & CORE_PIN5_BITMASK) ? 1 : 0;
|
||||
} else if (pin == 6) {
|
||||
return (CORE_PIN6_PINREG & CORE_PIN6_BITMASK) ? 1 : 0;
|
||||
} else if (pin == 7) {
|
||||
return (CORE_PIN7_PINREG & CORE_PIN7_BITMASK) ? 1 : 0;
|
||||
} else if (pin == 8) {
|
||||
return (CORE_PIN8_PINREG & CORE_PIN8_BITMASK) ? 1 : 0;
|
||||
} else if (pin == 9) {
|
||||
return (CORE_PIN9_PINREG & CORE_PIN9_BITMASK) ? 1 : 0;
|
||||
} else if (pin == 10) {
|
||||
return (CORE_PIN10_PINREG & CORE_PIN10_BITMASK) ? 1 : 0;
|
||||
} else if (pin == 11) {
|
||||
return (CORE_PIN11_PINREG & CORE_PIN11_BITMASK) ? 1 : 0;
|
||||
} else if (pin == 12) {
|
||||
return (CORE_PIN12_PINREG & CORE_PIN12_BITMASK) ? 1 : 0;
|
||||
} else if (pin == 13) {
|
||||
return (CORE_PIN13_PINREG & CORE_PIN13_BITMASK) ? 1 : 0;
|
||||
} else if (pin == 14) {
|
||||
return (CORE_PIN14_PINREG & CORE_PIN14_BITMASK) ? 1 : 0;
|
||||
} else if (pin == 15) {
|
||||
return (CORE_PIN15_PINREG & CORE_PIN15_BITMASK) ? 1 : 0;
|
||||
} else if (pin == 16) {
|
||||
return (CORE_PIN16_PINREG & CORE_PIN16_BITMASK) ? 1 : 0;
|
||||
} else if (pin == 17) {
|
||||
return (CORE_PIN17_PINREG & CORE_PIN17_BITMASK) ? 1 : 0;
|
||||
} else if (pin == 18) {
|
||||
return (CORE_PIN18_PINREG & CORE_PIN18_BITMASK) ? 1 : 0;
|
||||
} else if (pin == 19) {
|
||||
return (CORE_PIN19_PINREG & CORE_PIN19_BITMASK) ? 1 : 0;
|
||||
} else if (pin == 20) {
|
||||
return (CORE_PIN20_PINREG & CORE_PIN20_BITMASK) ? 1 : 0;
|
||||
} else if (pin == 21) {
|
||||
return (CORE_PIN21_PINREG & CORE_PIN21_BITMASK) ? 1 : 0;
|
||||
} else if (pin == 22) {
|
||||
return (CORE_PIN22_PINREG & CORE_PIN22_BITMASK) ? 1 : 0;
|
||||
} else if (pin == 23) {
|
||||
return (CORE_PIN23_PINREG & CORE_PIN23_BITMASK) ? 1 : 0;
|
||||
} else if (pin == 24) {
|
||||
return (CORE_PIN24_PINREG & CORE_PIN24_BITMASK) ? 1 : 0;
|
||||
} else if (pin == 25) {
|
||||
return (CORE_PIN25_PINREG & CORE_PIN25_BITMASK) ? 1 : 0;
|
||||
} else if (pin == 26) {
|
||||
return (CORE_PIN26_PINREG & CORE_PIN26_BITMASK) ? 1 : 0;
|
||||
} else if (pin == 27) {
|
||||
return (CORE_PIN27_PINREG & CORE_PIN27_BITMASK) ? 1 : 0;
|
||||
} else if (pin == 28) {
|
||||
return (CORE_PIN28_PINREG & CORE_PIN28_BITMASK) ? 1 : 0;
|
||||
} else if (pin == 29) {
|
||||
return (CORE_PIN29_PINREG & CORE_PIN29_BITMASK) ? 1 : 0;
|
||||
} else if (pin == 30) {
|
||||
return (CORE_PIN30_PINREG & CORE_PIN30_BITMASK) ? 1 : 0;
|
||||
} else if (pin == 31) {
|
||||
return (CORE_PIN31_PINREG & CORE_PIN31_BITMASK) ? 1 : 0;
|
||||
} else if (pin == 32) {
|
||||
return (CORE_PIN32_PINREG & CORE_PIN32_BITMASK) ? 1 : 0;
|
||||
} else if (pin == 33) {
|
||||
return (CORE_PIN33_PINREG & CORE_PIN33_BITMASK) ? 1 : 0;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return *portInputRegister(pin);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void pinMode(uint8_t pin, uint8_t mode);
|
||||
void init_pins(void);
|
||||
void analogWrite(uint8_t pin, int val);
|
||||
void analogWriteRes(uint32_t bits);
|
||||
static inline void analogWriteResolution(uint32_t bits) { analogWriteRes(bits); }
|
||||
void analogWriteFrequency(uint8_t pin, uint32_t frequency);
|
||||
void attachInterrupt(uint8_t pin, void (*function)(void), int mode);
|
||||
void detachInterrupt(uint8_t pin);
|
||||
void _init_Teensyduino_internal_(void);
|
||||
|
||||
int analogRead(uint8_t pin);
|
||||
void analogReference(uint8_t type);
|
||||
void analogReadRes(unsigned int bits);
|
||||
static inline void analogReadResolution(unsigned int bits) { analogReadRes(bits); }
|
||||
void analogReadAveraging(unsigned int num);
|
||||
void analog_init(void);
|
||||
|
||||
#define DEFAULT 0
|
||||
#define INTERNAL 2
|
||||
#define INTERNAL1V2 2
|
||||
#define INTERNAL1V1 2
|
||||
#define EXTERNAL 0
|
||||
|
||||
int touchRead(uint8_t pin);
|
||||
|
||||
|
||||
static inline void shiftOut(uint8_t, uint8_t, uint8_t, uint8_t) __attribute__((always_inline, unused));
|
||||
extern void _shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t value) __attribute__((noinline));
|
||||
extern void shiftOut_lsbFirst(uint8_t dataPin, uint8_t clockPin, uint8_t value) __attribute__((noinline));
|
||||
extern void shiftOut_msbFirst(uint8_t dataPin, uint8_t clockPin, uint8_t value) __attribute__((noinline));
|
||||
|
||||
static inline void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t value)
|
||||
{
|
||||
if (__builtin_constant_p(bitOrder)) {
|
||||
if (bitOrder == LSBFIRST) {
|
||||
shiftOut_lsbFirst(dataPin, clockPin, value);
|
||||
} else {
|
||||
shiftOut_msbFirst(dataPin, clockPin, value);
|
||||
}
|
||||
} else {
|
||||
_shiftOut(dataPin, clockPin, bitOrder, value);
|
||||
}
|
||||
}
|
||||
|
||||
static inline uint8_t shiftIn(uint8_t, uint8_t, uint8_t) __attribute__((always_inline, unused));
|
||||
extern uint8_t _shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder) __attribute__((noinline));
|
||||
extern uint8_t shiftIn_lsbFirst(uint8_t dataPin, uint8_t clockPin) __attribute__((noinline));
|
||||
extern uint8_t shiftIn_msbFirst(uint8_t dataPin, uint8_t clockPin) __attribute__((noinline));
|
||||
|
||||
static inline uint8_t shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder)
|
||||
{
|
||||
if (__builtin_constant_p(bitOrder)) {
|
||||
if (bitOrder == LSBFIRST) {
|
||||
return shiftIn_lsbFirst(dataPin, clockPin);
|
||||
} else {
|
||||
return shiftIn_msbFirst(dataPin, clockPin);
|
||||
}
|
||||
} else {
|
||||
return _shiftIn(dataPin, clockPin, bitOrder);
|
||||
}
|
||||
}
|
||||
|
||||
void _reboot_Teensyduino_(void) __attribute__((noreturn));
|
||||
void _restart_Teensyduino_(void) __attribute__((noreturn));
|
||||
|
||||
void yield(void);
|
||||
|
||||
void delay(uint32_t msec);
|
||||
|
||||
extern volatile uint32_t systick_millis_count;
|
||||
|
||||
static inline uint32_t millis(void) __attribute__((always_inline, unused));
|
||||
static inline uint32_t millis(void)
|
||||
{
|
||||
volatile uint32_t ret = systick_millis_count; // single aligned 32 bit is atomic;
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t micros(void);
|
||||
|
||||
static inline void delayMicroseconds(uint32_t) __attribute__((always_inline, unused));
|
||||
static inline void delayMicroseconds(uint32_t usec)
|
||||
{
|
||||
#if F_CPU == 96000000
|
||||
uint32_t n = usec << 5;
|
||||
#elif F_CPU == 48000000
|
||||
uint32_t n = usec << 4;
|
||||
#elif F_CPU == 24000000
|
||||
uint32_t n = usec << 3;
|
||||
#endif
|
||||
if (usec == 0) return;
|
||||
asm volatile(
|
||||
"L_%=_delayMicroseconds:" "\n\t"
|
||||
"subs %0, #1" "\n\t"
|
||||
"bne L_%=_delayMicroseconds" "\n"
|
||||
: "+r" (n) :
|
||||
);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
unsigned long rtc_get(void);
|
||||
void rtc_set(unsigned long t);
|
||||
void rtc_compensate(int adjust);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
class teensy3_clock_class
|
||||
{
|
||||
public:
|
||||
static unsigned long get(void) __attribute__((always_inline)) { return rtc_get(); }
|
||||
static void set(unsigned long t) __attribute__((always_inline)) { rtc_set(t); }
|
||||
static void compensate(int adj) __attribute__((always_inline)) { rtc_compensate(adj); }
|
||||
};
|
||||
extern teensy3_clock_class Teensy3Clock;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
294
teensy3/eeprom.c
Normal file
294
teensy3/eeprom.c
Normal file
|
|
@ -0,0 +1,294 @@
|
|||
/* Teensyduino Core Library
|
||||
* http://www.pjrc.com/teensy/
|
||||
* Copyright (c) 2013 PJRC.COM, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* 1. The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* 2. If the Software is incorporated into a build system that allows
|
||||
* selection among a list of target devices, then similar target
|
||||
* devices manufactured by PJRC.COM must be included in the list of
|
||||
* target devices and selectable in the same manner.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "mk20dx128.h"
|
||||
#include <stdint.h>
|
||||
//#include "HardwareSerial.h"
|
||||
|
||||
// The EEPROM is really RAM with a hardware-based backup system to
|
||||
// flash memory. Selecting a smaller size EEPROM allows more wear
|
||||
// leveling, for higher write endurance. If you edit this file,
|
||||
// set this to the smallest size your application can use. Also,
|
||||
// due to Freescale's implementation, writing 16 or 32 bit words
|
||||
// (aligned to 2 or 4 byte boundaries) has twice the endurance
|
||||
// compared to writing 8 bit bytes.
|
||||
//
|
||||
#define EEPROM_SIZE 2048
|
||||
|
||||
// Writing unaligned 16 or 32 bit data is handled automatically when
|
||||
// this is defined, but at a cost of extra code size. Without this,
|
||||
// any unaligned write will cause a hard fault exception! If you're
|
||||
// absolutely sure all 16 and 32 bit writes will be aligned, you can
|
||||
// remove the extra unnecessary code.
|
||||
//
|
||||
#define HANDLE_UNALIGNED_WRITES
|
||||
|
||||
// Minimum EEPROM Endurance
|
||||
// ------------------------
|
||||
#if (EEPROM_SIZE == 2048) // 35000 writes/byte or 70000 writes/word
|
||||
#define EEESIZE 0x33
|
||||
#elif (EEPROM_SIZE == 1024) // 75000 writes/byte or 150000 writes/word
|
||||
#define EEESIZE 0x34
|
||||
#elif (EEPROM_SIZE == 512) // 155000 writes/byte or 310000 writes/word
|
||||
#define EEESIZE 0x35
|
||||
#elif (EEPROM_SIZE == 256) // 315000 writes/byte or 630000 writes/word
|
||||
#define EEESIZE 0x36
|
||||
#elif (EEPROM_SIZE == 128) // 635000 writes/byte or 1270000 writes/word
|
||||
#define EEESIZE 0x37
|
||||
#elif (EEPROM_SIZE == 64) // 1275000 writes/byte or 2550000 writes/word
|
||||
#define EEESIZE 0x38
|
||||
#elif (EEPROM_SIZE == 32) // 2555000 writes/byte or 5110000 writes/word
|
||||
#define EEESIZE 0x39
|
||||
#endif
|
||||
|
||||
void eeprom_initialize(void)
|
||||
{
|
||||
uint32_t count=0;
|
||||
uint16_t do_flash_cmd[] = {
|
||||
0xf06f, 0x037f, 0x7003, 0x7803,
|
||||
0xf013, 0x0f80, 0xd0fb, 0x4770};
|
||||
uint8_t status;
|
||||
|
||||
if (FTFL_FCNFG & FTFL_FCNFG_RAMRDY) {
|
||||
// FlexRAM is configured as traditional RAM
|
||||
// We need to reconfigure for EEPROM usage
|
||||
FTFL_FCCOB0 = 0x80; // PGMPART = Program Partition Command
|
||||
FTFL_FCCOB4 = EEESIZE; // EEPROM Size
|
||||
FTFL_FCCOB5 = 0x03; // 0K for Dataflash, 32K for EEPROM backup
|
||||
__disable_irq();
|
||||
// do_flash_cmd() must execute from RAM. Luckily the C syntax is simple...
|
||||
(*((void (*)(volatile uint8_t *))((uint32_t)do_flash_cmd | 1)))(&FTFL_FSTAT);
|
||||
__enable_irq();
|
||||
status = FTFL_FSTAT;
|
||||
if (status & 0x70) {
|
||||
FTFL_FSTAT = (status & 0x70);
|
||||
return; // error
|
||||
}
|
||||
}
|
||||
// wait for eeprom to become ready (is this really necessary?)
|
||||
while (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) {
|
||||
if (++count > 20000) break;
|
||||
}
|
||||
}
|
||||
|
||||
#define FlexRAM ((uint8_t *)0x14000000)
|
||||
|
||||
uint8_t eeprom_read_byte(const uint8_t *addr)
|
||||
{
|
||||
uint32_t offset = (uint32_t)addr;
|
||||
if (offset >= EEPROM_SIZE) return 0;
|
||||
if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
|
||||
return FlexRAM[offset];
|
||||
}
|
||||
|
||||
uint16_t eeprom_read_word(const uint16_t *addr)
|
||||
{
|
||||
uint32_t offset = (uint32_t)addr;
|
||||
if (offset >= EEPROM_SIZE-1) return 0;
|
||||
if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
|
||||
return *(uint16_t *)(&FlexRAM[offset]);
|
||||
}
|
||||
|
||||
uint32_t eeprom_read_dword(const uint32_t *addr)
|
||||
{
|
||||
uint32_t offset = (uint32_t)addr;
|
||||
if (offset >= EEPROM_SIZE-3) return 0;
|
||||
if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
|
||||
return *(uint32_t *)(&FlexRAM[offset]);
|
||||
}
|
||||
|
||||
void eeprom_read_block(void *buf, const void *addr, uint32_t len)
|
||||
{
|
||||
uint32_t offset = (uint32_t)addr;
|
||||
uint8_t *dest = (uint8_t *)buf;
|
||||
uint32_t end = offset + len;
|
||||
|
||||
if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
|
||||
if (end > EEPROM_SIZE) end = EEPROM_SIZE;
|
||||
while (offset < end) {
|
||||
*dest++ = FlexRAM[offset++];
|
||||
}
|
||||
}
|
||||
|
||||
static void flexram_wait(void)
|
||||
{
|
||||
while (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) {
|
||||
// TODO: timeout
|
||||
}
|
||||
}
|
||||
|
||||
void eeprom_write_byte(uint8_t *addr, uint8_t value)
|
||||
{
|
||||
uint32_t offset = (uint32_t)addr;
|
||||
|
||||
if (offset >= EEPROM_SIZE) return;
|
||||
if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
|
||||
if (FlexRAM[offset] != value) {
|
||||
FlexRAM[offset] = value;
|
||||
flexram_wait();
|
||||
}
|
||||
}
|
||||
|
||||
void eeprom_write_word(uint16_t *addr, uint16_t value)
|
||||
{
|
||||
uint32_t offset = (uint32_t)addr;
|
||||
|
||||
if (offset >= EEPROM_SIZE-1) return;
|
||||
if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
|
||||
#ifdef HANDLE_UNALIGNED_WRITES
|
||||
if ((offset & 1) == 0) {
|
||||
#endif
|
||||
if (*(uint16_t *)(&FlexRAM[offset]) != value) {
|
||||
*(uint16_t *)(&FlexRAM[offset]) = value;
|
||||
flexram_wait();
|
||||
}
|
||||
#ifdef HANDLE_UNALIGNED_WRITES
|
||||
} else {
|
||||
if (FlexRAM[offset] != value) {
|
||||
FlexRAM[offset] = value;
|
||||
flexram_wait();
|
||||
}
|
||||
if (FlexRAM[offset + 1] != (value >> 8)) {
|
||||
FlexRAM[offset + 1] = value >> 8;
|
||||
flexram_wait();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void eeprom_write_dword(uint32_t *addr, uint32_t value)
|
||||
{
|
||||
uint32_t offset = (uint32_t)addr;
|
||||
|
||||
if (offset >= EEPROM_SIZE-3) return;
|
||||
if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
|
||||
#ifdef HANDLE_UNALIGNED_WRITES
|
||||
switch (offset & 3) {
|
||||
case 0:
|
||||
#endif
|
||||
if (*(uint32_t *)(&FlexRAM[offset]) != value) {
|
||||
*(uint32_t *)(&FlexRAM[offset]) = value;
|
||||
flexram_wait();
|
||||
}
|
||||
return;
|
||||
#ifdef HANDLE_UNALIGNED_WRITES
|
||||
case 2:
|
||||
if (*(uint16_t *)(&FlexRAM[offset]) != value) {
|
||||
*(uint16_t *)(&FlexRAM[offset]) = value;
|
||||
flexram_wait();
|
||||
}
|
||||
if (*(uint16_t *)(&FlexRAM[offset + 2]) != (value >> 16)) {
|
||||
*(uint16_t *)(&FlexRAM[offset + 2]) = value >> 16;
|
||||
flexram_wait();
|
||||
}
|
||||
return;
|
||||
default:
|
||||
if (FlexRAM[offset] != value) {
|
||||
FlexRAM[offset] = value;
|
||||
flexram_wait();
|
||||
}
|
||||
if (*(uint16_t *)(&FlexRAM[offset + 1]) != (value >> 8)) {
|
||||
*(uint16_t *)(&FlexRAM[offset + 1]) = value >> 8;
|
||||
flexram_wait();
|
||||
}
|
||||
if (FlexRAM[offset + 3] != (value >> 24)) {
|
||||
FlexRAM[offset + 3] = value >> 24;
|
||||
flexram_wait();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void eeprom_write_block(const void *buf, void *addr, uint32_t len)
|
||||
{
|
||||
uint32_t offset = (uint32_t)addr;
|
||||
const uint8_t *src = (const uint8_t *)buf;
|
||||
|
||||
if (offset >= EEPROM_SIZE) return;
|
||||
if (!(FTFL_FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize();
|
||||
if (len >= EEPROM_SIZE) len = EEPROM_SIZE;
|
||||
if (offset + len >= EEPROM_SIZE) len = EEPROM_SIZE - offset;
|
||||
while (len > 0) {
|
||||
uint32_t lsb = offset & 3;
|
||||
if (lsb == 0 && len >= 4) {
|
||||
// write aligned 32 bits
|
||||
uint32_t val32;
|
||||
val32 = *src++;
|
||||
val32 |= (*src++ << 8);
|
||||
val32 |= (*src++ << 16);
|
||||
val32 |= (*src++ << 24);
|
||||
if (*(uint32_t *)(&FlexRAM[offset]) != val32) {
|
||||
*(uint32_t *)(&FlexRAM[offset]) = val32;
|
||||
flexram_wait();
|
||||
}
|
||||
offset += 4;
|
||||
len -= 4;
|
||||
} else if ((lsb == 0 || lsb == 2) && len >= 2) {
|
||||
// write aligned 16 bits
|
||||
uint16_t val16;
|
||||
val16 = *src++;
|
||||
val16 |= (*src++ << 8);
|
||||
if (*(uint16_t *)(&FlexRAM[offset]) != val16) {
|
||||
*(uint16_t *)(&FlexRAM[offset]) = val16;
|
||||
flexram_wait();
|
||||
}
|
||||
offset += 2;
|
||||
len -= 2;
|
||||
} else {
|
||||
// write 8 bits
|
||||
uint8_t val8 = *src++;
|
||||
if (FlexRAM[offset] != val8) {
|
||||
FlexRAM[offset] = val8;
|
||||
flexram_wait();
|
||||
}
|
||||
offset++;
|
||||
len--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
void do_flash_cmd(volatile uint8_t *fstat)
|
||||
{
|
||||
*fstat = 0x80;
|
||||
while ((*fstat & 0x80) == 0) ; // wait
|
||||
}
|
||||
00000000 <do_flash_cmd>:
|
||||
0: f06f 037f mvn.w r3, #127 ; 0x7f
|
||||
4: 7003 strb r3, [r0, #0]
|
||||
6: 7803 ldrb r3, [r0, #0]
|
||||
8: f013 0f80 tst.w r3, #128 ; 0x80
|
||||
c: d0fb beq.n 6 <do_flash_cmd+0x6>
|
||||
e: 4770 bx lr
|
||||
*/
|
||||
|
||||
81
teensy3/elapsedMillis.h
Normal file
81
teensy3/elapsedMillis.h
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/* Elapsed time types - for easy-to-use measurements of elapsed time
|
||||
* http://www.pjrc.com/teensy/
|
||||
* Copyright (c) 2011 PJRC.COM, LLC
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef elapsedMillis_h
|
||||
#define elapsedMillis_h
|
||||
#ifdef __cplusplus
|
||||
|
||||
#if ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
class elapsedMillis
|
||||
{
|
||||
private:
|
||||
unsigned long ms;
|
||||
public:
|
||||
elapsedMillis(void) { ms = millis(); }
|
||||
elapsedMillis(unsigned long val) { ms = millis() - val; }
|
||||
elapsedMillis(const elapsedMillis &orig) { ms = orig.ms; }
|
||||
operator unsigned long () const { return millis() - ms; }
|
||||
elapsedMillis & operator = (const elapsedMillis &rhs) { ms = rhs.ms; return *this; }
|
||||
elapsedMillis & operator = (unsigned long val) { ms = millis() - val; return *this; }
|
||||
elapsedMillis & operator -= (unsigned long val) { ms += val ; return *this; }
|
||||
elapsedMillis & operator += (unsigned long val) { ms -= val ; return *this; }
|
||||
elapsedMillis operator - (int val) const { elapsedMillis r(*this); r.ms += val; return r; }
|
||||
elapsedMillis operator - (unsigned int val) const { elapsedMillis r(*this); r.ms += val; return r; }
|
||||
elapsedMillis operator - (long val) const { elapsedMillis r(*this); r.ms += val; return r; }
|
||||
elapsedMillis operator - (unsigned long val) const { elapsedMillis r(*this); r.ms += val; return r; }
|
||||
elapsedMillis operator + (int val) const { elapsedMillis r(*this); r.ms -= val; return r; }
|
||||
elapsedMillis operator + (unsigned int val) const { elapsedMillis r(*this); r.ms -= val; return r; }
|
||||
elapsedMillis operator + (long val) const { elapsedMillis r(*this); r.ms -= val; return r; }
|
||||
elapsedMillis operator + (unsigned long val) const { elapsedMillis r(*this); r.ms -= val; return r; }
|
||||
};
|
||||
|
||||
class elapsedMicros
|
||||
{
|
||||
private:
|
||||
unsigned long us;
|
||||
public:
|
||||
elapsedMicros(void) { us = micros(); }
|
||||
elapsedMicros(unsigned long val) { us = micros() - val; }
|
||||
elapsedMicros(const elapsedMicros &orig) { us = orig.us; }
|
||||
operator unsigned long () const { return micros() - us; }
|
||||
elapsedMicros & operator = (const elapsedMicros &rhs) { us = rhs.us; return *this; }
|
||||
elapsedMicros & operator = (unsigned long val) { us = micros() - val; return *this; }
|
||||
elapsedMicros & operator -= (unsigned long val) { us += val ; return *this; }
|
||||
elapsedMicros & operator += (unsigned long val) { us -= val ; return *this; }
|
||||
elapsedMicros operator - (int val) const { elapsedMicros r(*this); r.us += val; return r; }
|
||||
elapsedMicros operator - (unsigned int val) const { elapsedMicros r(*this); r.us += val; return r; }
|
||||
elapsedMicros operator - (long val) const { elapsedMicros r(*this); r.us += val; return r; }
|
||||
elapsedMicros operator - (unsigned long val) const { elapsedMicros r(*this); r.us += val; return r; }
|
||||
elapsedMicros operator + (int val) const { elapsedMicros r(*this); r.us -= val; return r; }
|
||||
elapsedMicros operator + (unsigned int val) const { elapsedMicros r(*this); r.us -= val; return r; }
|
||||
elapsedMicros operator + (long val) const { elapsedMicros r(*this); r.us -= val; return r; }
|
||||
elapsedMicros operator + (unsigned long val) const { elapsedMicros r(*this); r.us -= val; return r; }
|
||||
};
|
||||
|
||||
#endif // __cplusplus
|
||||
#endif // elapsedMillis_h
|
||||
96
teensy3/keylayouts.c
Normal file
96
teensy3/keylayouts.c
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
/* Teensyduino Core Library
|
||||
* http://www.pjrc.com/teensy/
|
||||
* Copyright (c) 2013 PJRC.COM, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* 1. The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* 2. If the Software is incorporated into a build system that allows
|
||||
* selection among a list of target devices, then similar target
|
||||
* devices manufactured by PJRC.COM must be included in the list of
|
||||
* target devices and selectable in the same manner.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <avr/pgmspace.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "keylayouts.h"
|
||||
|
||||
#ifdef M
|
||||
#undef M
|
||||
#endif
|
||||
#define M(n) ((n) & 0x3FFF)
|
||||
|
||||
const KEYCODE_TYPE keycodes_ascii[] = {
|
||||
M(ASCII_20), M(ASCII_21), M(ASCII_22), M(ASCII_23),
|
||||
M(ASCII_24), M(ASCII_25), M(ASCII_26), M(ASCII_27),
|
||||
M(ASCII_28), M(ASCII_29), M(ASCII_2A), M(ASCII_2B),
|
||||
M(ASCII_2C), M(ASCII_2D), M(ASCII_2E), M(ASCII_2F),
|
||||
M(ASCII_30), M(ASCII_31), M(ASCII_32), M(ASCII_33),
|
||||
M(ASCII_34), M(ASCII_35), M(ASCII_36), M(ASCII_37),
|
||||
M(ASCII_38), M(ASCII_39), M(ASCII_3A), M(ASCII_3B),
|
||||
M(ASCII_3C), M(ASCII_3D), M(ASCII_3E), M(ASCII_3F),
|
||||
M(ASCII_40), M(ASCII_41), M(ASCII_42), M(ASCII_43),
|
||||
M(ASCII_44), M(ASCII_45), M(ASCII_46), M(ASCII_47),
|
||||
M(ASCII_48), M(ASCII_49), M(ASCII_4A), M(ASCII_4B),
|
||||
M(ASCII_4C), M(ASCII_4D), M(ASCII_4E), M(ASCII_4F),
|
||||
M(ASCII_50), M(ASCII_51), M(ASCII_52), M(ASCII_53),
|
||||
M(ASCII_54), M(ASCII_55), M(ASCII_56), M(ASCII_57),
|
||||
M(ASCII_58), M(ASCII_59), M(ASCII_5A), M(ASCII_5B),
|
||||
M(ASCII_5C), M(ASCII_5D), M(ASCII_5E), M(ASCII_5F),
|
||||
M(ASCII_60), M(ASCII_61), M(ASCII_62), M(ASCII_63),
|
||||
M(ASCII_64), M(ASCII_65), M(ASCII_66), M(ASCII_67),
|
||||
M(ASCII_68), M(ASCII_69), M(ASCII_6A), M(ASCII_6B),
|
||||
M(ASCII_6C), M(ASCII_6D), M(ASCII_6E), M(ASCII_6F),
|
||||
M(ASCII_70), M(ASCII_71), M(ASCII_72), M(ASCII_73),
|
||||
M(ASCII_74), M(ASCII_75), M(ASCII_76), M(ASCII_77),
|
||||
M(ASCII_78), M(ASCII_79), M(ASCII_7A), M(ASCII_7B),
|
||||
M(ASCII_7C), M(ASCII_7D), M(ASCII_7E), M(ASCII_7F)
|
||||
};
|
||||
|
||||
#ifdef ISO_8859_1_A0
|
||||
const KEYCODE_TYPE keycodes_iso_8859_1[] = {
|
||||
M(ISO_8859_1_A0), M(ISO_8859_1_A1), M(ISO_8859_1_A2), M(ISO_8859_1_A3),
|
||||
M(ISO_8859_1_A4), M(ISO_8859_1_A5), M(ISO_8859_1_A6), M(ISO_8859_1_A7),
|
||||
M(ISO_8859_1_A8), M(ISO_8859_1_A9), M(ISO_8859_1_AA), M(ISO_8859_1_AB),
|
||||
M(ISO_8859_1_AC), M(ISO_8859_1_AD), M(ISO_8859_1_AE), M(ISO_8859_1_AF),
|
||||
M(ISO_8859_1_B0), M(ISO_8859_1_B1), M(ISO_8859_1_B2), M(ISO_8859_1_B3),
|
||||
M(ISO_8859_1_B4), M(ISO_8859_1_B5), M(ISO_8859_1_B6), M(ISO_8859_1_B7),
|
||||
M(ISO_8859_1_B8), M(ISO_8859_1_B9), M(ISO_8859_1_BA), M(ISO_8859_1_BB),
|
||||
M(ISO_8859_1_BC), M(ISO_8859_1_BD), M(ISO_8859_1_BE), M(ISO_8859_1_BF),
|
||||
M(ISO_8859_1_C0), M(ISO_8859_1_C1), M(ISO_8859_1_C2), M(ISO_8859_1_C3),
|
||||
M(ISO_8859_1_C4), M(ISO_8859_1_C5), M(ISO_8859_1_C6), M(ISO_8859_1_C7),
|
||||
M(ISO_8859_1_C8), M(ISO_8859_1_C9), M(ISO_8859_1_CA), M(ISO_8859_1_CB),
|
||||
M(ISO_8859_1_CC), M(ISO_8859_1_CD), M(ISO_8859_1_CE), M(ISO_8859_1_CF),
|
||||
M(ISO_8859_1_D0), M(ISO_8859_1_D1), M(ISO_8859_1_D2), M(ISO_8859_1_D3),
|
||||
M(ISO_8859_1_D4), M(ISO_8859_1_D5), M(ISO_8859_1_D6), M(ISO_8859_1_D7),
|
||||
M(ISO_8859_1_D8), M(ISO_8859_1_D9), M(ISO_8859_1_DA), M(ISO_8859_1_DB),
|
||||
M(ISO_8859_1_DC), M(ISO_8859_1_DD), M(ISO_8859_1_DE), M(ISO_8859_1_DF),
|
||||
M(ISO_8859_1_E0), M(ISO_8859_1_E1), M(ISO_8859_1_E2), M(ISO_8859_1_E3),
|
||||
M(ISO_8859_1_E4), M(ISO_8859_1_E5), M(ISO_8859_1_E6), M(ISO_8859_1_E7),
|
||||
M(ISO_8859_1_E8), M(ISO_8859_1_E9), M(ISO_8859_1_EA), M(ISO_8859_1_EB),
|
||||
M(ISO_8859_1_EC), M(ISO_8859_1_ED), M(ISO_8859_1_EE), M(ISO_8859_1_EF),
|
||||
M(ISO_8859_1_F0), M(ISO_8859_1_F1), M(ISO_8859_1_F2), M(ISO_8859_1_F3),
|
||||
M(ISO_8859_1_F4), M(ISO_8859_1_F5), M(ISO_8859_1_F6), M(ISO_8859_1_F7),
|
||||
M(ISO_8859_1_F8), M(ISO_8859_1_F9), M(ISO_8859_1_FA), M(ISO_8859_1_FB),
|
||||
M(ISO_8859_1_FC), M(ISO_8859_1_FD), M(ISO_8859_1_FE), M(ISO_8859_1_FF)
|
||||
};
|
||||
#endif // ISO_8859_1_A0
|
||||
|
||||
5173
teensy3/keylayouts.h
Normal file
5173
teensy3/keylayouts.h
Normal file
File diff suppressed because it is too large
Load diff
28
teensy3/main.cpp
Normal file
28
teensy3/main.cpp
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
#include "WProgram.h"
|
||||
|
||||
extern "C" int main(void)
|
||||
{
|
||||
#if !defined(ARDUINO)
|
||||
|
||||
// To use Teensy 3.0 without Arduino, simply put your code here.
|
||||
// For example:
|
||||
|
||||
pinMode(13, OUTPUT);
|
||||
while (1) {
|
||||
digitalWriteFast(13, HIGH);
|
||||
delay(500);
|
||||
digitalWriteFast(13, LOW);
|
||||
delay(500);
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
// Arduino's main() function just calls setup() and loop()....
|
||||
setup();
|
||||
while (1) {
|
||||
loop();
|
||||
yield();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
447
teensy3/math_helper.c
Normal file
447
teensy3/math_helper.c
Normal file
|
|
@ -0,0 +1,447 @@
|
|||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 29. November 2010
|
||||
* $Revision: V1.0.3
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
*
|
||||
* Title: math_helper.c
|
||||
*
|
||||
* Description: Definition of all helper functions required.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3
|
||||
*
|
||||
* Version 1.0.3 2010/11/29
|
||||
* Re-organized the CMSIS folders and updated documentation.
|
||||
*
|
||||
* Version 1.0.2 2010/11/11
|
||||
* Documentation updated.
|
||||
*
|
||||
* Version 1.0.1 2010/10/05
|
||||
* Production release and review comments incorporated.
|
||||
*
|
||||
* Version 1.0.0 2010/09/20
|
||||
* Production release and review comments incorporated.
|
||||
*
|
||||
* Version 0.0.7 2010/06/10
|
||||
* Misra-C changes done
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Include standard header files
|
||||
* -------------------------------------------------------------------- */
|
||||
#include<math.h>
|
||||
|
||||
/* ----------------------------------------------------------------------
|
||||
* Include project header files
|
||||
* -------------------------------------------------------------------- */
|
||||
#include "math_helper.h"
|
||||
|
||||
/**
|
||||
* @brief Caluclation of SNR
|
||||
* @param float* Pointer to the reference buffer
|
||||
* @param float* Pointer to the test buffer
|
||||
* @param uint32_t total number of samples
|
||||
* @return float SNR
|
||||
* The function Caluclates signal to noise ratio for the reference output
|
||||
* and test output
|
||||
*/
|
||||
|
||||
float arm_snr_f32(float *pRef, float *pTest, uint32_t buffSize)
|
||||
{
|
||||
float EnergySignal = 0.0, EnergyError = 0.0;
|
||||
uint32_t i;
|
||||
float SNR;
|
||||
int temp;
|
||||
int *test;
|
||||
|
||||
for (i = 0; i < buffSize; i++)
|
||||
{
|
||||
/* Checking for a NAN value in pRef array */
|
||||
test = (int *)(&pRef[i]);
|
||||
temp = *test;
|
||||
|
||||
if(temp == 0x7FC00000)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* Checking for a NAN value in pTest array */
|
||||
test = (int *)(&pTest[i]);
|
||||
temp = *test;
|
||||
|
||||
if(temp == 0x7FC00000)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
EnergySignal += pRef[i] * pRef[i];
|
||||
EnergyError += (pRef[i] - pTest[i]) * (pRef[i] - pTest[i]);
|
||||
}
|
||||
|
||||
/* Checking for a NAN value in EnergyError */
|
||||
test = (int *)(&EnergyError);
|
||||
temp = *test;
|
||||
|
||||
if(temp == 0x7FC00000)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
SNR = 10 * log10 (EnergySignal / EnergyError);
|
||||
|
||||
return (SNR);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Provide guard bits for Input buffer
|
||||
* @param q15_t* Pointer to input buffer
|
||||
* @param uint32_t blockSize
|
||||
* @param uint32_t guard_bits
|
||||
* @return none
|
||||
* The function Provides the guard bits for the buffer
|
||||
* to avoid overflow
|
||||
*/
|
||||
|
||||
void arm_provide_guard_bits_q15 (q15_t * input_buf, uint32_t blockSize,
|
||||
uint32_t guard_bits)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < blockSize; i++)
|
||||
{
|
||||
input_buf[i] = input_buf[i] >> guard_bits;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts float to fixed in q12.20 format
|
||||
* @param uint32_t number of samples in the buffer
|
||||
* @return none
|
||||
* The function converts floating point values to fixed point(q12.20) values
|
||||
*/
|
||||
|
||||
void arm_float_to_q12_20(float *pIn, q31_t * pOut, uint32_t numSamples)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < numSamples; i++)
|
||||
{
|
||||
/* 1048576.0f corresponds to pow(2, 20) */
|
||||
pOut[i] = (q31_t) (pIn[i] * 1048576.0f);
|
||||
|
||||
pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
|
||||
|
||||
if (pIn[i] == (float) 1.0)
|
||||
{
|
||||
pOut[i] = 0x000FFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Compare MATLAB Reference Output and ARM Test output
|
||||
* @param q15_t* Pointer to Ref buffer
|
||||
* @param q15_t* Pointer to Test buffer
|
||||
* @param uint32_t number of samples in the buffer
|
||||
* @return none
|
||||
*/
|
||||
|
||||
uint32_t arm_compare_fixed_q15(q15_t *pIn, q15_t * pOut, uint32_t numSamples)
|
||||
{
|
||||
uint32_t i;
|
||||
int32_t diff, diffCrnt = 0;
|
||||
uint32_t maxDiff = 0;
|
||||
|
||||
for (i = 0; i < numSamples; i++)
|
||||
{
|
||||
diff = pIn[i] - pOut[i];
|
||||
diffCrnt = (diff > 0) ? diff : -diff;
|
||||
|
||||
if(diffCrnt > maxDiff)
|
||||
{
|
||||
maxDiff = diffCrnt;
|
||||
}
|
||||
}
|
||||
|
||||
return(maxDiff);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Compare MATLAB Reference Output and ARM Test output
|
||||
* @param q31_t* Pointer to Ref buffer
|
||||
* @param q31_t* Pointer to Test buffer
|
||||
* @param uint32_t number of samples in the buffer
|
||||
* @return none
|
||||
*/
|
||||
|
||||
uint32_t arm_compare_fixed_q31(q31_t *pIn, q31_t * pOut, uint32_t numSamples)
|
||||
{
|
||||
uint32_t i;
|
||||
int32_t diff, diffCrnt = 0;
|
||||
uint32_t maxDiff = 0;
|
||||
|
||||
for (i = 0; i < numSamples; i++)
|
||||
{
|
||||
diff = pIn[i] - pOut[i];
|
||||
diffCrnt = (diff > 0) ? diff : -diff;
|
||||
|
||||
if(diffCrnt > maxDiff)
|
||||
{
|
||||
maxDiff = diffCrnt;
|
||||
}
|
||||
}
|
||||
|
||||
return(maxDiff);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Provide guard bits for Input buffer
|
||||
* @param q31_t* Pointer to input buffer
|
||||
* @param uint32_t blockSize
|
||||
* @param uint32_t guard_bits
|
||||
* @return none
|
||||
* The function Provides the guard bits for the buffer
|
||||
* to avoid overflow
|
||||
*/
|
||||
|
||||
void arm_provide_guard_bits_q31 (q31_t * input_buf,
|
||||
uint32_t blockSize,
|
||||
uint32_t guard_bits)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < blockSize; i++)
|
||||
{
|
||||
input_buf[i] = input_buf[i] >> guard_bits;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Provide guard bits for Input buffer
|
||||
* @param q31_t* Pointer to input buffer
|
||||
* @param uint32_t blockSize
|
||||
* @param uint32_t guard_bits
|
||||
* @return none
|
||||
* The function Provides the guard bits for the buffer
|
||||
* to avoid overflow
|
||||
*/
|
||||
|
||||
void arm_provide_guard_bits_q7 (q7_t * input_buf,
|
||||
uint32_t blockSize,
|
||||
uint32_t guard_bits)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < blockSize; i++)
|
||||
{
|
||||
input_buf[i] = input_buf[i] >> guard_bits;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Caluclates number of guard bits
|
||||
* @param uint32_t number of additions
|
||||
* @return none
|
||||
* The function Caluclates the number of guard bits
|
||||
* depending on the numtaps
|
||||
*/
|
||||
|
||||
uint32_t arm_calc_guard_bits (uint32_t num_adds)
|
||||
{
|
||||
uint32_t i = 1, j = 0;
|
||||
|
||||
if (num_adds == 1)
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
while (i < num_adds)
|
||||
{
|
||||
i = i * 2;
|
||||
j++;
|
||||
}
|
||||
|
||||
return (j);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts Q15 to floating-point
|
||||
* @param uint32_t number of samples in the buffer
|
||||
* @return none
|
||||
*/
|
||||
|
||||
void arm_apply_guard_bits (float32_t * pIn,
|
||||
uint32_t numSamples,
|
||||
uint32_t guard_bits)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < numSamples; i++)
|
||||
{
|
||||
pIn[i] = pIn[i] * arm_calc_2pow(guard_bits);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculates pow(2, numShifts)
|
||||
* @param uint32_t number of shifts
|
||||
* @return pow(2, numShifts)
|
||||
*/
|
||||
uint32_t arm_calc_2pow(uint32_t numShifts)
|
||||
{
|
||||
|
||||
uint32_t i, val = 1;
|
||||
|
||||
for (i = 0; i < numShifts; i++)
|
||||
{
|
||||
val = val * 2;
|
||||
}
|
||||
|
||||
return(val);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Converts float to fixed q14
|
||||
* @param uint32_t number of samples in the buffer
|
||||
* @return none
|
||||
* The function converts floating point values to fixed point values
|
||||
*/
|
||||
|
||||
void arm_float_to_q14 (float *pIn, q15_t * pOut,
|
||||
uint32_t numSamples)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < numSamples; i++)
|
||||
{
|
||||
/* 16384.0f corresponds to pow(2, 14) */
|
||||
pOut[i] = (q15_t) (pIn[i] * 16384.0f);
|
||||
|
||||
pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
|
||||
|
||||
if (pIn[i] == (float) 2.0)
|
||||
{
|
||||
pOut[i] = 0x7FFF;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Converts float to fixed q30 format
|
||||
* @param uint32_t number of samples in the buffer
|
||||
* @return none
|
||||
* The function converts floating point values to fixed point values
|
||||
*/
|
||||
|
||||
void arm_float_to_q30 (float *pIn, q31_t * pOut,
|
||||
uint32_t numSamples)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < numSamples; i++)
|
||||
{
|
||||
/* 1073741824.0f corresponds to pow(2, 30) */
|
||||
pOut[i] = (q31_t) (pIn[i] * 1073741824.0f);
|
||||
|
||||
pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
|
||||
|
||||
if (pIn[i] == (float) 2.0)
|
||||
{
|
||||
pOut[i] = 0x7FFFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converts float to fixed q30 format
|
||||
* @param uint32_t number of samples in the buffer
|
||||
* @return none
|
||||
* The function converts floating point values to fixed point values
|
||||
*/
|
||||
|
||||
void arm_float_to_q29 (float *pIn, q31_t * pOut,
|
||||
uint32_t numSamples)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < numSamples; i++)
|
||||
{
|
||||
/* 1073741824.0f corresponds to pow(2, 30) */
|
||||
pOut[i] = (q31_t) (pIn[i] * 536870912.0f);
|
||||
|
||||
pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
|
||||
|
||||
if (pIn[i] == (float) 4.0)
|
||||
{
|
||||
pOut[i] = 0x7FFFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Converts float to fixed q28 format
|
||||
* @param uint32_t number of samples in the buffer
|
||||
* @return none
|
||||
* The function converts floating point values to fixed point values
|
||||
*/
|
||||
|
||||
void arm_float_to_q28 (float *pIn, q31_t * pOut,
|
||||
uint32_t numSamples)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < numSamples; i++)
|
||||
{
|
||||
/* 268435456.0f corresponds to pow(2, 28) */
|
||||
pOut[i] = (q31_t) (pIn[i] * 268435456.0f);
|
||||
|
||||
pOut[i] += pIn[i] > 0 ? 0.5 : -0.5;
|
||||
|
||||
if (pIn[i] == (float) 8.0)
|
||||
{
|
||||
pOut[i] = 0x7FFFFFFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clip the float values to +/- 1
|
||||
* @param pIn input buffer
|
||||
* @param numSamples number of samples in the buffer
|
||||
* @return none
|
||||
* The function converts floating point values to fixed point values
|
||||
*/
|
||||
|
||||
void arm_clip_f32 (float *pIn, uint32_t numSamples)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < numSamples; i++)
|
||||
{
|
||||
if(pIn[i] > 1.0f)
|
||||
{
|
||||
pIn[i] = 1.0;
|
||||
}
|
||||
else if( pIn[i] < -1.0f)
|
||||
{
|
||||
pIn[i] = -1.0;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
63
teensy3/math_helper.h
Normal file
63
teensy3/math_helper.h
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
/* ----------------------------------------------------------------------
|
||||
* Copyright (C) 2010 ARM Limited. All rights reserved.
|
||||
*
|
||||
* $Date: 29. November 2010
|
||||
* $Revision: V1.0.3
|
||||
*
|
||||
* Project: CMSIS DSP Library
|
||||
*
|
||||
* Title: math_helper.h
|
||||
*
|
||||
*
|
||||
* Description: Prototypes of all helper functions required.
|
||||
*
|
||||
* Target Processor: Cortex-M4/Cortex-M3
|
||||
*
|
||||
* Version 1.0.3 2010/11/29
|
||||
* Re-organized the CMSIS folders and updated documentation.
|
||||
*
|
||||
* Version 1.0.2 2010/11/11
|
||||
* Documentation updated.
|
||||
*
|
||||
* Version 1.0.1 2010/10/05
|
||||
* Production release and review comments incorporated.
|
||||
*
|
||||
* Version 1.0.0 2010/09/20
|
||||
* Production release and review comments incorporated.
|
||||
*
|
||||
* Version 0.0.7 2010/06/10
|
||||
* Misra-C changes done
|
||||
* -------------------------------------------------------------------- */
|
||||
|
||||
|
||||
#include "arm_math.h"
|
||||
|
||||
#ifndef MATH_HELPER_H
|
||||
#define MATH_HELPER_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
float arm_snr_f32(float *pRef, float *pTest, uint32_t buffSize);
|
||||
void arm_float_to_q12_20(float *pIn, q31_t * pOut, uint32_t numSamples);
|
||||
void arm_provide_guard_bits_q15(q15_t *input_buf, uint32_t blockSize, uint32_t guard_bits);
|
||||
void arm_provide_guard_bits_q31(q31_t *input_buf, uint32_t blockSize, uint32_t guard_bits);
|
||||
void arm_float_to_q14(float *pIn, q15_t *pOut, uint32_t numSamples);
|
||||
void arm_float_to_q29(float *pIn, q31_t *pOut, uint32_t numSamples);
|
||||
void arm_float_to_q28(float *pIn, q31_t *pOut, uint32_t numSamples);
|
||||
void arm_float_to_q30(float *pIn, q31_t *pOut, uint32_t numSamples);
|
||||
void arm_clip_f32(float *pIn, uint32_t numSamples);
|
||||
uint32_t arm_calc_guard_bits(uint32_t num_adds);
|
||||
void arm_apply_guard_bits (float32_t * pIn, uint32_t numSamples, uint32_t guard_bits);
|
||||
uint32_t arm_compare_fixed_q15(q15_t *pIn, q15_t * pOut, uint32_t numSamples);
|
||||
uint32_t arm_compare_fixed_q31(q31_t *pIn, q31_t *pOut, uint32_t numSamples);
|
||||
uint32_t arm_calc_2pow(uint32_t guard_bits);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
382
teensy3/mk20dx128.c
Normal file
382
teensy3/mk20dx128.c
Normal file
|
|
@ -0,0 +1,382 @@
|
|||
/* Teensyduino Core Library
|
||||
* http://www.pjrc.com/teensy/
|
||||
* Copyright (c) 2013 PJRC.COM, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* 1. The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* 2. If the Software is incorporated into a build system that allows
|
||||
* selection among a list of target devices, then similar target
|
||||
* devices manufactured by PJRC.COM must be included in the list of
|
||||
* target devices and selectable in the same manner.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "mk20dx128.h"
|
||||
|
||||
|
||||
extern unsigned long _stext;
|
||||
extern unsigned long _etext;
|
||||
extern unsigned long _sdata;
|
||||
extern unsigned long _edata;
|
||||
extern unsigned long _sbss;
|
||||
extern unsigned long _ebss;
|
||||
extern unsigned long _estack;
|
||||
//extern void __init_array_start(void);
|
||||
//extern void __init_array_end(void);
|
||||
extern int main (void);
|
||||
void ResetHandler(void);
|
||||
void _init_Teensyduino_internal_(void);
|
||||
void __libc_init_array(void);
|
||||
|
||||
|
||||
void fault_isr(void)
|
||||
{
|
||||
while (1) {
|
||||
// keep polling some communication while in fault
|
||||
// mode, so we don't completely die.
|
||||
if (SIM_SCGC4 & SIM_SCGC4_USBOTG) usb_isr();
|
||||
if (SIM_SCGC4 & SIM_SCGC4_UART0) uart0_status_isr();
|
||||
if (SIM_SCGC4 & SIM_SCGC4_UART1) uart1_status_isr();
|
||||
if (SIM_SCGC4 & SIM_SCGC4_UART2) uart2_status_isr();
|
||||
}
|
||||
}
|
||||
|
||||
void unused_isr(void)
|
||||
{
|
||||
fault_isr();
|
||||
}
|
||||
|
||||
extern volatile uint32_t systick_millis_count;
|
||||
void systick_default_isr(void)
|
||||
{
|
||||
systick_millis_count++;
|
||||
}
|
||||
|
||||
void nmi_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void hard_fault_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void memmanage_fault_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void bus_fault_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void usage_fault_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void svcall_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void debugmonitor_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void pendablesrvreq_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void systick_isr(void) __attribute__ ((weak, alias("systick_default_isr")));
|
||||
|
||||
void dma_ch0_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void dma_ch1_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void dma_ch2_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void dma_ch3_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void dma_error_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void flash_cmd_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void flash_error_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void low_voltage_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void wakeup_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void watchdog_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void i2c0_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void spi0_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void i2s0_tx_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void i2s0_rx_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void uart0_lon_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void uart0_status_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void uart0_error_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void uart1_status_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void uart1_error_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void uart2_status_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void uart2_error_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void adc0_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void cmp0_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void cmp1_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void ftm0_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void ftm1_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void cmt_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void rtc_alarm_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void rtc_seconds_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void pit0_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void pit1_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void pit2_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void pit3_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void pdb_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void usb_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void usb_charge_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void tsi0_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void mcg_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void lptmr_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void porta_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void portb_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void portc_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void portd_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void porte_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
void software_isr(void) __attribute__ ((weak, alias("unused_isr")));
|
||||
|
||||
|
||||
// TODO: create AVR-stype ISR() macro, with default linkage to undefined handler
|
||||
//
|
||||
__attribute__ ((section(".vectors"), used))
|
||||
void (* const gVectors[])(void) =
|
||||
{
|
||||
(void (*)(void))((unsigned long)&_estack), // 0 ARM: Initial Stack Pointer
|
||||
ResetHandler, // 1 ARM: Initial Program Counter
|
||||
nmi_isr, // 2 ARM: Non-maskable Interrupt (NMI)
|
||||
hard_fault_isr, // 3 ARM: Hard Fault
|
||||
memmanage_fault_isr, // 4 ARM: MemManage Fault
|
||||
bus_fault_isr, // 5 ARM: Bus Fault
|
||||
usage_fault_isr, // 6 ARM: Usage Fault
|
||||
fault_isr, // 7 --
|
||||
fault_isr, // 8 --
|
||||
fault_isr, // 9 --
|
||||
fault_isr, // 10 --
|
||||
svcall_isr, // 11 ARM: Supervisor call (SVCall)
|
||||
debugmonitor_isr, // 12 ARM: Debug Monitor
|
||||
fault_isr, // 13 --
|
||||
pendablesrvreq_isr, // 14 ARM: Pendable req serv(PendableSrvReq)
|
||||
systick_isr, // 15 ARM: System tick timer (SysTick)
|
||||
dma_ch0_isr, // 16 DMA channel 0 transfer complete
|
||||
dma_ch1_isr, // 17 DMA channel 1 transfer complete
|
||||
dma_ch2_isr, // 18 DMA channel 2 transfer complete
|
||||
dma_ch3_isr, // 19 DMA channel 3 transfer complete
|
||||
dma_error_isr, // 20 DMA error interrupt channel
|
||||
unused_isr, // 21 DMA --
|
||||
flash_cmd_isr, // 22 Flash Memory Command complete
|
||||
flash_error_isr, // 23 Flash Read collision
|
||||
low_voltage_isr, // 24 Low-voltage detect/warning
|
||||
wakeup_isr, // 25 Low Leakage Wakeup
|
||||
watchdog_isr, // 26 Both EWM and WDOG interrupt
|
||||
i2c0_isr, // 27 I2C0
|
||||
spi0_isr, // 28 SPI0
|
||||
i2s0_tx_isr, // 29 I2S0 Transmit
|
||||
i2s0_rx_isr, // 30 I2S0 Receive
|
||||
uart0_lon_isr, // 31 UART0 CEA709.1-B (LON) status
|
||||
uart0_status_isr, // 32 UART0 status
|
||||
uart0_error_isr, // 33 UART0 error
|
||||
uart1_status_isr, // 34 UART1 status
|
||||
uart1_error_isr, // 35 UART1 error
|
||||
uart2_status_isr, // 36 UART2 status
|
||||
uart2_error_isr, // 37 UART2 error
|
||||
adc0_isr, // 38 ADC0
|
||||
cmp0_isr, // 39 CMP0
|
||||
cmp1_isr, // 40 CMP1
|
||||
ftm0_isr, // 41 FTM0
|
||||
ftm1_isr, // 42 FTM1
|
||||
cmt_isr, // 43 CMT
|
||||
rtc_alarm_isr, // 44 RTC Alarm interrupt
|
||||
rtc_seconds_isr, // 45 RTC Seconds interrupt
|
||||
pit0_isr, // 46 PIT Channel 0
|
||||
pit1_isr, // 47 PIT Channel 1
|
||||
pit2_isr, // 48 PIT Channel 2
|
||||
pit3_isr, // 49 PIT Channel 3
|
||||
pdb_isr, // 50 PDB Programmable Delay Block
|
||||
usb_isr, // 51 USB OTG
|
||||
usb_charge_isr, // 52 USB Charger Detect
|
||||
tsi0_isr, // 53 TSI0
|
||||
mcg_isr, // 54 MCG
|
||||
lptmr_isr, // 55 Low Power Timer
|
||||
porta_isr, // 56 Pin detect (Port A)
|
||||
portb_isr, // 57 Pin detect (Port B)
|
||||
portc_isr, // 58 Pin detect (Port C)
|
||||
portd_isr, // 59 Pin detect (Port D)
|
||||
porte_isr, // 60 Pin detect (Port E)
|
||||
software_isr, // 61 Software interrupt
|
||||
};
|
||||
|
||||
//void usb_isr(void)
|
||||
//{
|
||||
//}
|
||||
|
||||
__attribute__ ((section(".flashconfig"), used))
|
||||
const uint8_t flashconfigbytes[16] = {
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF
|
||||
};
|
||||
|
||||
|
||||
// Automatically initialize the RTC. When the build defines the compile
|
||||
// time, and the user has added a crystal, the RTC will automatically
|
||||
// begin at the time of the first upload.
|
||||
#ifndef TIME_T
|
||||
#define TIME_T 1349049600 // default 1 Oct 2012 (never used, Arduino sets this)
|
||||
#endif
|
||||
extern void rtc_set(unsigned long t);
|
||||
|
||||
|
||||
|
||||
static void startup_unused_hook(void) {}
|
||||
void startup_early_hook(void) __attribute__ ((weak, alias("startup_unused_hook")));
|
||||
void startup_late_hook(void) __attribute__ ((weak, alias("startup_unused_hook")));
|
||||
|
||||
|
||||
__attribute__ ((section(".startup")))
|
||||
void ResetHandler(void)
|
||||
{
|
||||
uint32_t *src = &_etext;
|
||||
uint32_t *dest = &_sdata;
|
||||
unsigned int i;
|
||||
|
||||
WDOG_UNLOCK = WDOG_UNLOCK_SEQ1;
|
||||
WDOG_UNLOCK = WDOG_UNLOCK_SEQ2;
|
||||
WDOG_STCTRLH = WDOG_STCTRLH_ALLOWUPDATE;
|
||||
startup_early_hook();
|
||||
|
||||
// enable clocks to always-used peripherals
|
||||
SIM_SCGC5 = 0x00043F82; // clocks active to all GPIO
|
||||
SIM_SCGC6 = SIM_SCGC6_RTC | SIM_SCGC6_FTM0 | SIM_SCGC6_FTM1 | SIM_SCGC6_ADC0 | SIM_SCGC6_FTFL;
|
||||
// if the RTC oscillator isn't enabled, get it started early
|
||||
if (!(RTC_CR & RTC_CR_OSCE)) {
|
||||
RTC_SR = 0;
|
||||
RTC_CR = RTC_CR_SC16P | RTC_CR_SC4P | RTC_CR_OSCE;
|
||||
}
|
||||
|
||||
// release I/O pins hold, if we woke up from VLLS mode
|
||||
if (PMC_REGSC & PMC_REGSC_ACKISO) PMC_REGSC |= PMC_REGSC_ACKISO;
|
||||
|
||||
// TODO: do this while the PLL is waiting to lock....
|
||||
while (dest < &_edata) *dest++ = *src++;
|
||||
dest = &_sbss;
|
||||
while (dest < &_ebss) *dest++ = 0;
|
||||
SCB_VTOR = 0; // use vector table in flash
|
||||
|
||||
// default all interrupts to medium priority level
|
||||
for (i=0; i < NVIC_NUM_INTERRUPTS; i++) NVIC_SET_PRIORITY(i, 128);
|
||||
|
||||
// start in FEI mode
|
||||
// enable capacitors for crystal
|
||||
OSC0_CR = OSC_SC8P | OSC_SC2P;
|
||||
// enable osc, 8-32 MHz range, low power mode
|
||||
MCG_C2 = MCG_C2_RANGE0(2) | MCG_C2_EREFS;
|
||||
// switch to crystal as clock source, FLL input = 16 MHz / 512
|
||||
MCG_C1 = MCG_C1_CLKS(2) | MCG_C1_FRDIV(4);
|
||||
// wait for crystal oscillator to begin
|
||||
while ((MCG_S & MCG_S_OSCINIT0) == 0) ;
|
||||
// wait for FLL to use oscillator
|
||||
while ((MCG_S & MCG_S_IREFST) != 0) ;
|
||||
// wait for MCGOUT to use oscillator
|
||||
while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(2)) ;
|
||||
// now we're in FBE mode
|
||||
// config PLL input for 16 MHz Crystal / 4 = 4 MHz
|
||||
MCG_C5 = MCG_C5_PRDIV0(3);
|
||||
// config PLL for 96 MHz output
|
||||
MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0(0);
|
||||
// wait for PLL to start using xtal as its input
|
||||
while (!(MCG_S & MCG_S_PLLST)) ;
|
||||
// wait for PLL to lock
|
||||
while (!(MCG_S & MCG_S_LOCK0)) ;
|
||||
// now we're in PBE mode
|
||||
#if F_CPU == 96000000
|
||||
// config divisors: 96 MHz core, 48 MHz bus, 24 MHz flash
|
||||
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(0) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV4(3);
|
||||
#elif F_CPU == 48000000
|
||||
// config divisors: 48 MHz core, 48 MHz bus, 24 MHz flash
|
||||
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(1) | SIM_CLKDIV1_OUTDIV2(1) | SIM_CLKDIV1_OUTDIV4(3);
|
||||
#elif F_CPU == 24000000
|
||||
// config divisors: 24 MHz core, 24 MHz bus, 24 MHz flash
|
||||
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV1(3) | SIM_CLKDIV1_OUTDIV2(3) | SIM_CLKDIV1_OUTDIV4(3);
|
||||
#else
|
||||
#error "Error, F_CPU must be 96000000, 48000000, or 24000000"
|
||||
#endif
|
||||
// switch to PLL as clock source, FLL input = 16 MHz / 512
|
||||
MCG_C1 = MCG_C1_CLKS(0) | MCG_C1_FRDIV(4);
|
||||
// wait for PLL clock to be used
|
||||
while ((MCG_S & MCG_S_CLKST_MASK) != MCG_S_CLKST(3)) ;
|
||||
// now we're in PEE mode
|
||||
// configure USB for 48 MHz clock
|
||||
SIM_CLKDIV2 = SIM_CLKDIV2_USBDIV(1); // USB = 96 MHz PLL / 2
|
||||
// USB uses PLL clock, trace is CPU clock, CLKOUT=OSCERCLK0
|
||||
SIM_SOPT2 = SIM_SOPT2_USBSRC | SIM_SOPT2_PLLFLLSEL | SIM_SOPT2_TRACECLKSEL | SIM_SOPT2_CLKOUTSEL(6);
|
||||
|
||||
// initialize the SysTick counter
|
||||
SYST_RVR = (F_CPU / 1000) - 1;
|
||||
SYST_CSR = SYST_CSR_CLKSOURCE | SYST_CSR_TICKINT | SYST_CSR_ENABLE;
|
||||
|
||||
//init_pins();
|
||||
__enable_irq();
|
||||
|
||||
_init_Teensyduino_internal_();
|
||||
if (RTC_SR & RTC_SR_TIF) rtc_set(TIME_T);
|
||||
|
||||
__libc_init_array();
|
||||
|
||||
/*
|
||||
for (ptr = &__init_array_start; ptr < &__init_array_end; ptr++) {
|
||||
(*ptr)();
|
||||
}
|
||||
*/
|
||||
startup_late_hook();
|
||||
main();
|
||||
while (1) ;
|
||||
}
|
||||
|
||||
// TODO: is this needed for c++ and where does it come from?
|
||||
/*
|
||||
void _init(void)
|
||||
{
|
||||
}
|
||||
*/
|
||||
|
||||
char *__brkval = (char *)&_ebss;
|
||||
|
||||
void * _sbrk(int incr)
|
||||
{
|
||||
//static char *heap_end = (char *)&_ebss;
|
||||
//char *prev = heap_end;
|
||||
//heap_end += incr;
|
||||
|
||||
char *prev = __brkval;
|
||||
__brkval += incr;
|
||||
return prev;
|
||||
}
|
||||
|
||||
int _read(int file, char *ptr, int len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _write(int file, char *ptr, int len)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int _close(int fd)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int _lseek(int fd, long long offset, int whence)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
void _exit(int status)
|
||||
{
|
||||
while (1);
|
||||
}
|
||||
|
||||
void __cxa_pure_virtual()
|
||||
{
|
||||
while (1);
|
||||
}
|
||||
|
||||
int __cxa_guard_acquire (int *g)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void __cxa_guard_release(int *g)
|
||||
{
|
||||
}
|
||||
|
||||
1768
teensy3/mk20dx128.h
Normal file
1768
teensy3/mk20dx128.h
Normal file
File diff suppressed because it is too large
Load diff
109
teensy3/mk20dx128.ld
Normal file
109
teensy3/mk20dx128.ld
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
/* Teensyduino Core Library
|
||||
* http://www.pjrc.com/teensy/
|
||||
* Copyright (c) 2013 PJRC.COM, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* 1. The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* 2. If the Software is incorporated into a build system that allows
|
||||
* selection among a list of target devices, then similar target
|
||||
* devices manufactured by PJRC.COM must be included in the list of
|
||||
* target devices and selectable in the same manner.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 128K
|
||||
RAM (rwx) : ORIGIN = 0x1FFFE000, LENGTH = 16K
|
||||
}
|
||||
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text : {
|
||||
. = 0;
|
||||
KEEP(*(.vectors))
|
||||
*(.startup*)
|
||||
/* TODO: does linker detect startup overflow onto flashconfig? */
|
||||
. = 0x400;
|
||||
KEEP(*(.flashconfig*))
|
||||
*(.text*)
|
||||
*(.rodata*)
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.init))
|
||||
. = ALIGN(4);
|
||||
__preinit_array_start = .;
|
||||
KEEP (*(.preinit_array))
|
||||
__preinit_array_end = .;
|
||||
__init_array_start = .;
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array))
|
||||
__init_array_end = .;
|
||||
} > FLASH = 0xFF
|
||||
|
||||
.ARM.exidx : {
|
||||
__exidx_start = .;
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
__exidx_end = .;
|
||||
} > FLASH
|
||||
_etext = .;
|
||||
|
||||
.usbdescriptortable (NOLOAD) : {
|
||||
/* . = ORIGIN(RAM); */
|
||||
. = ALIGN(512);
|
||||
*(.usbdescriptortable*)
|
||||
} > RAM
|
||||
|
||||
.dmabuffers (NOLOAD) : {
|
||||
. = ALIGN(4);
|
||||
*(.dmabuffers*)
|
||||
} > RAM
|
||||
|
||||
.usbbuffers (NOLOAD) : {
|
||||
. = ALIGN(4);
|
||||
*(.usbbuffers*)
|
||||
} > RAM
|
||||
|
||||
.data : AT (_etext) {
|
||||
. = ALIGN(4);
|
||||
_sdata = .;
|
||||
*(.data*)
|
||||
. = ALIGN(4);
|
||||
_edata = .;
|
||||
} > RAM
|
||||
|
||||
.noinit (NOLOAD) : {
|
||||
*(.noinit*)
|
||||
} > RAM
|
||||
|
||||
.bss : {
|
||||
. = ALIGN(4);
|
||||
_sbss = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
_ebss = .;
|
||||
__bss_end = .;
|
||||
} > RAM
|
||||
|
||||
_estack = ORIGIN(RAM) + LENGTH(RAM);
|
||||
}
|
||||
|
||||
|
||||
85
teensy3/nonstd.c
Normal file
85
teensy3/nonstd.c
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/* Teensyduino Core Library
|
||||
* http://www.pjrc.com/teensy/
|
||||
* Copyright (c) 2013 PJRC.COM, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* 1. The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* 2. If the Software is incorporated into a build system that allows
|
||||
* selection among a list of target devices, then similar target
|
||||
* devices manufactured by PJRC.COM must be included in the list of
|
||||
* target devices and selectable in the same manner.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "avr_functions.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
size_t strlen(const char *s)
|
||||
{
|
||||
size_t n=0;
|
||||
|
||||
while (*s++) n++;
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
char * ultoa(unsigned long val, char *buf, int radix)
|
||||
{
|
||||
unsigned digit;
|
||||
int i=0, j;
|
||||
char t;
|
||||
|
||||
while (1) {
|
||||
digit = val % radix;
|
||||
buf[i] = ((digit < 10) ? '0' + digit : 'A' + digit - 10);
|
||||
val /= radix;
|
||||
if (val == 0) break;
|
||||
i++;
|
||||
}
|
||||
buf[i + 1] = 0;
|
||||
for (j=0; j < i; j++, i--) {
|
||||
t = buf[j];
|
||||
buf[j] = buf[i];
|
||||
buf[i] = t;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
char * ltoa(long val, char *buf, int radix)
|
||||
{
|
||||
if (val >= 0) {
|
||||
return ultoa(val, buf, radix);
|
||||
} else {
|
||||
buf[0] = '-';
|
||||
ultoa(-val, buf + 1, radix);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: actually write an efficient dtostrf()....
|
||||
char * dtostrf(float val, int width, unsigned int precision, char *buf)
|
||||
{
|
||||
char format[20];
|
||||
sprintf(format, "%%%d.%df", width, precision);
|
||||
sprintf(buf, format, val);
|
||||
return buf;
|
||||
}
|
||||
|
||||
102
teensy3/pins_arduino.h
Normal file
102
teensy3/pins_arduino.h
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/* Teensyduino Core Library
|
||||
* http://www.pjrc.com/teensy/
|
||||
* Copyright (c) 2013 PJRC.COM, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* 1. The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* 2. If the Software is incorporated into a build system that allows
|
||||
* selection among a list of target devices, then similar target
|
||||
* devices manufactured by PJRC.COM must be included in the list of
|
||||
* target devices and selectable in the same manner.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef pins_macros_for_arduino_compatibility_h
|
||||
#define pins_macros_for_arduino_compatibility_h
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
const static uint8_t A0 = 14;
|
||||
const static uint8_t A1 = 15;
|
||||
const static uint8_t A2 = 16;
|
||||
const static uint8_t A3 = 17;
|
||||
const static uint8_t A4 = 18;
|
||||
const static uint8_t A5 = 19;
|
||||
const static uint8_t A6 = 20;
|
||||
const static uint8_t A7 = 21;
|
||||
const static uint8_t A8 = 22;
|
||||
const static uint8_t A9 = 23;
|
||||
const static uint8_t A10 = 34;
|
||||
const static uint8_t A11 = 35;
|
||||
const static uint8_t A12 = 36;
|
||||
const static uint8_t A13 = 37;
|
||||
|
||||
const static uint8_t SS = 10;
|
||||
const static uint8_t MOSI = 11;
|
||||
const static uint8_t MISO = 12;
|
||||
const static uint8_t SCK = 13;
|
||||
const static uint8_t LED_BUILTIN = 13;
|
||||
const static uint8_t SDA = 18;
|
||||
const static uint8_t SCL = 19;
|
||||
|
||||
|
||||
#define NUM_DIGITAL_PINS 34
|
||||
#define NUM_ANALOG_INPUTS 14
|
||||
|
||||
#define analogInputToDigitalPin(p) (((p) < 10) ? (p) + 14 : -1)
|
||||
#define digitalPinHasPWM(p) (((p) >= 3 && (p) <= 6) || (p) == 9 || (p) == 10 || ((p) >= 20 && (p) <= 23))
|
||||
|
||||
|
||||
struct digital_pin_bitband_and_config_table_struct {
|
||||
volatile uint32_t *reg;
|
||||
volatile uint32_t *config;
|
||||
};
|
||||
extern const struct digital_pin_bitband_and_config_table_struct digital_pin_to_info_PGM[];
|
||||
|
||||
// compatibility macros
|
||||
#define digitalPinToPort(pin) (pin)
|
||||
#define digitalPinToBitMask(pin) (1)
|
||||
#define portOutputRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 0))
|
||||
#define portSetRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 32))
|
||||
#define portClearRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 64))
|
||||
#define portToggleRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 96))
|
||||
#define portInputRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 128))
|
||||
#define portModeRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 160))
|
||||
#define portConfigRegister(pin) ((volatile uint32_t *)(digital_pin_to_info_PGM[(pin)].config))
|
||||
|
||||
|
||||
#define digitalPinToPortReg(pin) (portOutputRegister(pin))
|
||||
#define digitalPinToBit(pin) (1)
|
||||
|
||||
|
||||
#define NOT_ON_TIMER 0
|
||||
static inline uint8_t digitalPinToTimer(uint8_t) __attribute__((always_inline, unused));
|
||||
static inline uint8_t digitalPinToTimer(uint8_t pin)
|
||||
{
|
||||
if (pin >= 3 && pin <= 6) return pin - 2;
|
||||
if (pin >= 9 && pin <= 10) return pin - 4;
|
||||
if (pin >= 20 && pin <= 23) return pin - 13;
|
||||
return NOT_ON_TIMER;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
746
teensy3/pins_teensy.c
Normal file
746
teensy3/pins_teensy.c
Normal file
|
|
@ -0,0 +1,746 @@
|
|||
/* Teensyduino Core Library
|
||||
* http://www.pjrc.com/teensy/
|
||||
* Copyright (c) 2013 PJRC.COM, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* 1. The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* 2. If the Software is incorporated into a build system that allows
|
||||
* selection among a list of target devices, then similar target
|
||||
* devices manufactured by PJRC.COM must be included in the list of
|
||||
* target devices and selectable in the same manner.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "core_pins.h"
|
||||
#include "pins_arduino.h"
|
||||
#include "HardwareSerial.h"
|
||||
|
||||
#if 0
|
||||
// moved to pins_arduino.h
|
||||
struct digital_pin_bitband_and_config_table_struct {
|
||||
volatile uint32_t *reg;
|
||||
volatile uint32_t *config;
|
||||
};
|
||||
const struct digital_pin_bitband_and_config_table_struct digital_pin_to_info_PGM[];
|
||||
|
||||
// compatibility macros
|
||||
#define digitalPinToPort(pin) (pin)
|
||||
#define digitalPinToBitMask(pin) (1)
|
||||
#define portOutputRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 0))
|
||||
#define portSetRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 32))
|
||||
#define portClearRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 64))
|
||||
#define portToggleRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 96))
|
||||
#define portInputRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 128))
|
||||
#define portModeRegister(pin) ((volatile uint8_t *)(digital_pin_to_info_PGM[(pin)].reg + 160))
|
||||
#define portConfigRegister(pin) ((volatile uint32_t *)(digital_pin_to_info_PGM[(pin)].config))
|
||||
#endif
|
||||
|
||||
//#define digitalPinToTimer(P) ( pgm_read_byte( digital_pin_to_timer_PGM + (P) ) )
|
||||
//#define analogInPinToBit(P) (P)
|
||||
|
||||
#define GPIO_BITBAND_ADDR(reg, bit) (((uint32_t)&(reg) - 0x40000000) * 32 + (bit) * 4 + 0x42000000)
|
||||
#define GPIO_BITBAND_PTR(reg, bit) ((uint32_t *)GPIO_BITBAND_ADDR((reg), (bit)))
|
||||
//#define GPIO_SET_BIT(reg, bit) (*GPIO_BITBAND_PTR((reg), (bit)) = 1)
|
||||
//#define GPIO_CLR_BIT(reg, bit) (*GPIO_BITBAND_PTR((reg), (bit)) = 0)
|
||||
|
||||
const struct digital_pin_bitband_and_config_table_struct digital_pin_to_info_PGM[] = {
|
||||
{GPIO_BITBAND_PTR(CORE_PIN0_PORTREG, CORE_PIN0_BIT), &CORE_PIN0_CONFIG},
|
||||
{GPIO_BITBAND_PTR(CORE_PIN1_PORTREG, CORE_PIN1_BIT), &CORE_PIN1_CONFIG},
|
||||
{GPIO_BITBAND_PTR(CORE_PIN2_PORTREG, CORE_PIN2_BIT), &CORE_PIN2_CONFIG},
|
||||
{GPIO_BITBAND_PTR(CORE_PIN3_PORTREG, CORE_PIN3_BIT), &CORE_PIN3_CONFIG},
|
||||
{GPIO_BITBAND_PTR(CORE_PIN4_PORTREG, CORE_PIN4_BIT), &CORE_PIN4_CONFIG},
|
||||
{GPIO_BITBAND_PTR(CORE_PIN5_PORTREG, CORE_PIN5_BIT), &CORE_PIN5_CONFIG},
|
||||
{GPIO_BITBAND_PTR(CORE_PIN6_PORTREG, CORE_PIN6_BIT), &CORE_PIN6_CONFIG},
|
||||
{GPIO_BITBAND_PTR(CORE_PIN7_PORTREG, CORE_PIN7_BIT), &CORE_PIN7_CONFIG},
|
||||
{GPIO_BITBAND_PTR(CORE_PIN8_PORTREG, CORE_PIN8_BIT), &CORE_PIN8_CONFIG},
|
||||
{GPIO_BITBAND_PTR(CORE_PIN9_PORTREG, CORE_PIN9_BIT), &CORE_PIN9_CONFIG},
|
||||
{GPIO_BITBAND_PTR(CORE_PIN10_PORTREG, CORE_PIN10_BIT), &CORE_PIN10_CONFIG},
|
||||
{GPIO_BITBAND_PTR(CORE_PIN11_PORTREG, CORE_PIN11_BIT), &CORE_PIN11_CONFIG},
|
||||
{GPIO_BITBAND_PTR(CORE_PIN12_PORTREG, CORE_PIN12_BIT), &CORE_PIN12_CONFIG},
|
||||
{GPIO_BITBAND_PTR(CORE_PIN13_PORTREG, CORE_PIN13_BIT), &CORE_PIN13_CONFIG},
|
||||
{GPIO_BITBAND_PTR(CORE_PIN14_PORTREG, CORE_PIN14_BIT), &CORE_PIN14_CONFIG},
|
||||
{GPIO_BITBAND_PTR(CORE_PIN15_PORTREG, CORE_PIN15_BIT), &CORE_PIN15_CONFIG},
|
||||
{GPIO_BITBAND_PTR(CORE_PIN16_PORTREG, CORE_PIN16_BIT), &CORE_PIN16_CONFIG},
|
||||
{GPIO_BITBAND_PTR(CORE_PIN17_PORTREG, CORE_PIN17_BIT), &CORE_PIN17_CONFIG},
|
||||
{GPIO_BITBAND_PTR(CORE_PIN18_PORTREG, CORE_PIN18_BIT), &CORE_PIN18_CONFIG},
|
||||
{GPIO_BITBAND_PTR(CORE_PIN19_PORTREG, CORE_PIN19_BIT), &CORE_PIN19_CONFIG},
|
||||
{GPIO_BITBAND_PTR(CORE_PIN20_PORTREG, CORE_PIN20_BIT), &CORE_PIN20_CONFIG},
|
||||
{GPIO_BITBAND_PTR(CORE_PIN21_PORTREG, CORE_PIN21_BIT), &CORE_PIN21_CONFIG},
|
||||
{GPIO_BITBAND_PTR(CORE_PIN22_PORTREG, CORE_PIN22_BIT), &CORE_PIN22_CONFIG},
|
||||
{GPIO_BITBAND_PTR(CORE_PIN23_PORTREG, CORE_PIN23_BIT), &CORE_PIN23_CONFIG},
|
||||
{GPIO_BITBAND_PTR(CORE_PIN24_PORTREG, CORE_PIN24_BIT), &CORE_PIN24_CONFIG},
|
||||
{GPIO_BITBAND_PTR(CORE_PIN25_PORTREG, CORE_PIN25_BIT), &CORE_PIN25_CONFIG},
|
||||
{GPIO_BITBAND_PTR(CORE_PIN26_PORTREG, CORE_PIN26_BIT), &CORE_PIN26_CONFIG},
|
||||
{GPIO_BITBAND_PTR(CORE_PIN27_PORTREG, CORE_PIN27_BIT), &CORE_PIN27_CONFIG},
|
||||
{GPIO_BITBAND_PTR(CORE_PIN28_PORTREG, CORE_PIN28_BIT), &CORE_PIN28_CONFIG},
|
||||
{GPIO_BITBAND_PTR(CORE_PIN29_PORTREG, CORE_PIN29_BIT), &CORE_PIN29_CONFIG},
|
||||
{GPIO_BITBAND_PTR(CORE_PIN30_PORTREG, CORE_PIN30_BIT), &CORE_PIN30_CONFIG},
|
||||
{GPIO_BITBAND_PTR(CORE_PIN31_PORTREG, CORE_PIN31_BIT), &CORE_PIN31_CONFIG},
|
||||
{GPIO_BITBAND_PTR(CORE_PIN32_PORTREG, CORE_PIN32_BIT), &CORE_PIN32_CONFIG},
|
||||
{GPIO_BITBAND_PTR(CORE_PIN33_PORTREG, CORE_PIN33_BIT), &CORE_PIN33_CONFIG}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
typedef void (*voidFuncPtr)(void);
|
||||
volatile static voidFuncPtr intFunc[CORE_NUM_DIGITAL];
|
||||
|
||||
void init_pin_interrupts(void)
|
||||
{
|
||||
//SIM_SCGC5 = 0x00043F82; // clocks active to all GPIO
|
||||
NVIC_ENABLE_IRQ(IRQ_PORTA);
|
||||
NVIC_ENABLE_IRQ(IRQ_PORTB);
|
||||
NVIC_ENABLE_IRQ(IRQ_PORTC);
|
||||
NVIC_ENABLE_IRQ(IRQ_PORTD);
|
||||
NVIC_ENABLE_IRQ(IRQ_PORTE);
|
||||
// TODO: maybe these should be set to a lower priority
|
||||
// so if the user puts lots of slow code on attachInterrupt
|
||||
// fast interrupts will still be serviced quickly?
|
||||
}
|
||||
|
||||
void attachInterrupt(uint8_t pin, void (*function)(void), int mode)
|
||||
{
|
||||
volatile uint32_t *config;
|
||||
uint32_t cfg, mask;
|
||||
|
||||
if (pin >= CORE_NUM_DIGITAL) return;
|
||||
switch (mode) {
|
||||
case CHANGE: mask = 0x0B; break;
|
||||
case RISING: mask = 0x09; break;
|
||||
case FALLING: mask = 0x0A; break;
|
||||
case LOW: mask = 0x08; break;
|
||||
case HIGH: mask = 0x0C; break;
|
||||
default: return;
|
||||
}
|
||||
mask = (mask << 16) | 0x01000000;
|
||||
config = portConfigRegister(pin);
|
||||
|
||||
__disable_irq();
|
||||
cfg = *config;
|
||||
cfg &= ~0x000F0000; // disable any previous interrupt
|
||||
*config = cfg;
|
||||
intFunc[pin] = function; // set the function pointer
|
||||
cfg |= mask;
|
||||
*config = cfg; // enable the new interrupt
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
void detachInterrupt(uint8_t pin)
|
||||
{
|
||||
volatile uint32_t *config;
|
||||
|
||||
config = portConfigRegister(pin);
|
||||
__disable_irq();
|
||||
*config = ((*config & ~0x000F0000) | 0x01000000);
|
||||
intFunc[pin] = NULL;
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
|
||||
void porta_isr(void)
|
||||
{
|
||||
uint32_t isfr = PORTA_ISFR;
|
||||
PORTA_ISFR = isfr;
|
||||
if ((isfr & CORE_PIN3_BITMASK) && intFunc[3]) intFunc[3]();
|
||||
if ((isfr & CORE_PIN4_BITMASK) && intFunc[4]) intFunc[4]();
|
||||
if ((isfr & CORE_PIN24_BITMASK) && intFunc[24]) intFunc[24]();
|
||||
if ((isfr & CORE_PIN33_BITMASK) && intFunc[33]) intFunc[33]();
|
||||
}
|
||||
|
||||
void portb_isr(void)
|
||||
{
|
||||
uint32_t isfr = PORTB_ISFR;
|
||||
PORTB_ISFR = isfr;
|
||||
if ((isfr & CORE_PIN0_BITMASK) && intFunc[0]) intFunc[0]();
|
||||
if ((isfr & CORE_PIN1_BITMASK) && intFunc[1]) intFunc[1]();
|
||||
if ((isfr & CORE_PIN16_BITMASK) && intFunc[16]) intFunc[16]();
|
||||
if ((isfr & CORE_PIN17_BITMASK) && intFunc[17]) intFunc[17]();
|
||||
if ((isfr & CORE_PIN18_BITMASK) && intFunc[18]) intFunc[18]();
|
||||
if ((isfr & CORE_PIN19_BITMASK) && intFunc[19]) intFunc[19]();
|
||||
if ((isfr & CORE_PIN25_BITMASK) && intFunc[25]) intFunc[25]();
|
||||
if ((isfr & CORE_PIN32_BITMASK) && intFunc[32]) intFunc[32]();
|
||||
}
|
||||
|
||||
void portc_isr(void)
|
||||
{
|
||||
// TODO: these are inefficent. Use CLZ somehow....
|
||||
uint32_t isfr = PORTC_ISFR;
|
||||
PORTC_ISFR = isfr;
|
||||
if ((isfr & CORE_PIN9_BITMASK) && intFunc[9]) intFunc[9]();
|
||||
if ((isfr & CORE_PIN10_BITMASK) && intFunc[10]) intFunc[10]();
|
||||
if ((isfr & CORE_PIN11_BITMASK) && intFunc[11]) intFunc[11]();
|
||||
if ((isfr & CORE_PIN12_BITMASK) && intFunc[12]) intFunc[12]();
|
||||
if ((isfr & CORE_PIN13_BITMASK) && intFunc[13]) intFunc[13]();
|
||||
if ((isfr & CORE_PIN15_BITMASK) && intFunc[15]) intFunc[15]();
|
||||
if ((isfr & CORE_PIN22_BITMASK) && intFunc[22]) intFunc[22]();
|
||||
if ((isfr & CORE_PIN23_BITMASK) && intFunc[23]) intFunc[23]();
|
||||
if ((isfr & CORE_PIN27_BITMASK) && intFunc[27]) intFunc[27]();
|
||||
if ((isfr & CORE_PIN28_BITMASK) && intFunc[28]) intFunc[28]();
|
||||
if ((isfr & CORE_PIN29_BITMASK) && intFunc[29]) intFunc[29]();
|
||||
if ((isfr & CORE_PIN30_BITMASK) && intFunc[30]) intFunc[30]();
|
||||
}
|
||||
|
||||
void portd_isr(void)
|
||||
{
|
||||
uint32_t isfr = PORTD_ISFR;
|
||||
PORTD_ISFR = isfr;
|
||||
if ((isfr & CORE_PIN2_BITMASK) && intFunc[2]) intFunc[2]();
|
||||
if ((isfr & CORE_PIN5_BITMASK) && intFunc[5]) intFunc[5]();
|
||||
if ((isfr & CORE_PIN6_BITMASK) && intFunc[6]) intFunc[6]();
|
||||
if ((isfr & CORE_PIN7_BITMASK) && intFunc[7]) intFunc[7]();
|
||||
if ((isfr & CORE_PIN8_BITMASK) && intFunc[8]) intFunc[8]();
|
||||
if ((isfr & CORE_PIN14_BITMASK) && intFunc[14]) intFunc[14]();
|
||||
if ((isfr & CORE_PIN20_BITMASK) && intFunc[20]) intFunc[20]();
|
||||
if ((isfr & CORE_PIN21_BITMASK) && intFunc[21]) intFunc[21]();
|
||||
}
|
||||
|
||||
void porte_isr(void)
|
||||
{
|
||||
uint32_t isfr = PORTE_ISFR;
|
||||
PORTE_ISFR = isfr;
|
||||
if ((isfr & CORE_PIN26_BITMASK) && intFunc[26]) intFunc[26]();
|
||||
if ((isfr & CORE_PIN31_BITMASK) && intFunc[31]) intFunc[31]();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
unsigned long rtc_get(void)
|
||||
{
|
||||
return RTC_TSR;
|
||||
}
|
||||
|
||||
void rtc_set(unsigned long t)
|
||||
{
|
||||
RTC_SR = 0;
|
||||
RTC_TPR = 0;
|
||||
RTC_TSR = t;
|
||||
RTC_SR = RTC_SR_TCE;
|
||||
}
|
||||
|
||||
|
||||
// adjust is the amount of crystal error to compensate, 1 = 0.1192 ppm
|
||||
// For example, adjust = -100 is slows the clock by 11.92 ppm
|
||||
//
|
||||
void rtc_compensate(int adjust)
|
||||
{
|
||||
uint32_t comp, interval, tcr;
|
||||
|
||||
// This simple approach tries to maximize the interval.
|
||||
// Perhaps minimizing TCR would be better, so the
|
||||
// compensation is distributed more evenly across
|
||||
// many seconds, rather than saving it all up and then
|
||||
// altering one second up to +/- 0.38%
|
||||
if (adjust >= 0) {
|
||||
comp = adjust;
|
||||
interval = 256;
|
||||
while (1) {
|
||||
tcr = comp * interval;
|
||||
if (tcr < 128*256) break;
|
||||
if (--interval == 1) break;
|
||||
}
|
||||
tcr = tcr >> 8;
|
||||
} else {
|
||||
comp = -adjust;
|
||||
interval = 256;
|
||||
while (1) {
|
||||
tcr = comp * interval;
|
||||
if (tcr < 129*256) break;
|
||||
if (--interval == 1) break;
|
||||
}
|
||||
tcr = tcr >> 8;
|
||||
tcr = 256 - tcr;
|
||||
}
|
||||
RTC_TCR = ((interval - 1) << 8) | tcr;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// TODO: build system should define this
|
||||
// so RTC is automatically initialized to approx correct time
|
||||
// at least when the program begins running right after upload
|
||||
#ifndef TIME_T
|
||||
#define TIME_T 1350160272
|
||||
#endif
|
||||
|
||||
void init_rtc(void)
|
||||
{
|
||||
serial_print("init_rtc\n");
|
||||
//SIM_SCGC6 |= SIM_SCGC6_RTC;
|
||||
|
||||
// enable the RTC crystal oscillator, for approx 12pf crystal
|
||||
if (!(RTC_CR & RTC_CR_OSCE)) {
|
||||
serial_print("start RTC oscillator\n");
|
||||
RTC_SR = 0;
|
||||
RTC_CR = RTC_CR_SC16P | RTC_CR_SC4P | RTC_CR_OSCE;
|
||||
}
|
||||
// should wait for crystal to stabilize.....
|
||||
|
||||
serial_print("SR=");
|
||||
serial_phex32(RTC_SR);
|
||||
serial_print("\n");
|
||||
serial_print("CR=");
|
||||
serial_phex32(RTC_CR);
|
||||
serial_print("\n");
|
||||
serial_print("TSR=");
|
||||
serial_phex32(RTC_TSR);
|
||||
serial_print("\n");
|
||||
serial_print("TCR=");
|
||||
serial_phex32(RTC_TCR);
|
||||
serial_print("\n");
|
||||
|
||||
if (RTC_SR & RTC_SR_TIF) {
|
||||
// enable the RTC
|
||||
RTC_SR = 0;
|
||||
RTC_TPR = 0;
|
||||
RTC_TSR = TIME_T;
|
||||
RTC_SR = RTC_SR_TCE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
extern void usb_init(void);
|
||||
|
||||
|
||||
// create a default PWM at the same 488.28 Hz as Arduino Uno
|
||||
#if F_BUS == 48000000
|
||||
#define DEFAULT_FTM_MOD (49152 - 1)
|
||||
#define DEFAULT_FTM_PRESCALE 1
|
||||
#else
|
||||
#define DEFAULT_FTM_MOD (49152 - 1)
|
||||
#define DEFAULT_FTM_PRESCALE 0
|
||||
#endif
|
||||
|
||||
//void init_pins(void)
|
||||
void _init_Teensyduino_internal_(void)
|
||||
{
|
||||
init_pin_interrupts();
|
||||
|
||||
//SIM_SCGC6 |= SIM_SCGC6_FTM0; // TODO: use bitband for atomic read-mod-write
|
||||
//SIM_SCGC6 |= SIM_SCGC6_FTM1;
|
||||
FTM0_CNT = 0;
|
||||
FTM0_MOD = DEFAULT_FTM_MOD;
|
||||
FTM0_C0SC = 0x28; // MSnB:MSnA = 10, ELSnB:ELSnA = 10
|
||||
FTM0_C1SC = 0x28;
|
||||
FTM0_C2SC = 0x28;
|
||||
FTM0_C3SC = 0x28;
|
||||
FTM0_C4SC = 0x28;
|
||||
FTM0_C5SC = 0x28;
|
||||
FTM0_C6SC = 0x28;
|
||||
FTM0_C7SC = 0x28;
|
||||
FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS(DEFAULT_FTM_PRESCALE);
|
||||
FTM1_CNT = 0;
|
||||
FTM1_MOD = DEFAULT_FTM_MOD;
|
||||
FTM1_C0SC = 0x28;
|
||||
FTM1_C1SC = 0x28;
|
||||
FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(DEFAULT_FTM_PRESCALE);
|
||||
|
||||
analog_init();
|
||||
//delay(100); // TODO: this is not necessary, right?
|
||||
usb_init();
|
||||
}
|
||||
|
||||
|
||||
|
||||
// SOPT4 is SIM select clocks?
|
||||
// FTM is clocked by the bus clock, either 24 or 48 MHz
|
||||
// input capture can be FTM1_CH0, CMP0 or CMP1 or USB start of frame
|
||||
// 24 MHz with reload 49152 to match Arduino's speed = 488.28125 Hz
|
||||
|
||||
static uint8_t analog_write_res = 8;
|
||||
|
||||
void analogWrite(uint8_t pin, int val)
|
||||
{
|
||||
uint32_t cval, max;
|
||||
|
||||
max = 1 << analog_write_res;
|
||||
if (val <= 0) {
|
||||
digitalWrite(pin, LOW);
|
||||
pinMode(pin, OUTPUT); // TODO: implement OUTPUT_LOW
|
||||
return;
|
||||
} else if (val >= max) {
|
||||
digitalWrite(pin, HIGH);
|
||||
pinMode(pin, OUTPUT); // TODO: implement OUTPUT_HIGH
|
||||
return;
|
||||
}
|
||||
|
||||
//serial_print("analogWrite\n");
|
||||
//serial_print("val = ");
|
||||
//serial_phex32(val);
|
||||
//serial_print("\n");
|
||||
//serial_print("analog_write_res = ");
|
||||
//serial_phex(analog_write_res);
|
||||
//serial_print("\n");
|
||||
if (pin == 3 || pin == 4) {
|
||||
cval = ((uint32_t)val * (uint32_t)(FTM1_MOD + 1)) >> analog_write_res;
|
||||
//serial_print("FTM1_MOD = ");
|
||||
//serial_phex32(FTM1_MOD);
|
||||
//serial_print("\n");
|
||||
} else {
|
||||
cval = ((uint32_t)val * (uint32_t)(FTM0_MOD + 1)) >> analog_write_res;
|
||||
//serial_print("FTM0_MOD = ");
|
||||
//serial_phex32(FTM0_MOD);
|
||||
//serial_print("\n");
|
||||
}
|
||||
//serial_print("cval = ");
|
||||
//serial_phex32(cval);
|
||||
//serial_print("\n");
|
||||
switch (pin) {
|
||||
case 3: // PTA12, FTM1_CH0
|
||||
FTM1_C0V = cval;
|
||||
CORE_PIN3_CONFIG = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
|
||||
break;
|
||||
case 4: // PTA13, FTM1_CH1
|
||||
FTM1_C1V = cval;
|
||||
CORE_PIN4_CONFIG = PORT_PCR_MUX(3) | PORT_PCR_DSE | PORT_PCR_SRE;
|
||||
break;
|
||||
case 5: // PTD7, FTM0_CH7
|
||||
FTM0_C7V = cval;
|
||||
CORE_PIN5_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
|
||||
break;
|
||||
case 6: // PTD4, FTM0_CH4
|
||||
FTM0_C4V = cval;
|
||||
CORE_PIN6_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
|
||||
break;
|
||||
case 9: // PTC3, FTM0_CH2
|
||||
FTM0_C2V = cval;
|
||||
CORE_PIN9_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
|
||||
break;
|
||||
case 10: // PTC4, FTM0_CH3
|
||||
FTM0_C3V = cval;
|
||||
CORE_PIN10_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
|
||||
break;
|
||||
case 20: // PTD5, FTM0_CH5
|
||||
FTM0_C5V = cval;
|
||||
CORE_PIN20_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
|
||||
break;
|
||||
case 21: // PTD6, FTM0_CH6
|
||||
FTM0_C6V = cval;
|
||||
CORE_PIN21_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
|
||||
break;
|
||||
case 22: // PTC1, FTM0_CH0
|
||||
FTM0_C0V = cval;
|
||||
CORE_PIN22_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
|
||||
break;
|
||||
case 23: // PTC2, FTM0_CH1
|
||||
FTM0_C1V = cval;
|
||||
CORE_PIN23_CONFIG = PORT_PCR_MUX(4) | PORT_PCR_DSE | PORT_PCR_SRE;
|
||||
break;
|
||||
default:
|
||||
digitalWrite(pin, (val > 127) ? HIGH : LOW);
|
||||
pinMode(pin, OUTPUT);
|
||||
}
|
||||
}
|
||||
|
||||
void analogWriteRes(uint32_t bits)
|
||||
{
|
||||
if (bits < 1) {
|
||||
bits = 1;
|
||||
} else if (bits > 16) {
|
||||
bits = 16;
|
||||
}
|
||||
analog_write_res = bits;
|
||||
}
|
||||
|
||||
void analogWriteFrequency(uint8_t pin, uint32_t frequency)
|
||||
{
|
||||
uint32_t minfreq, prescale, mod;
|
||||
|
||||
//serial_print("analogWriteFrequency: pin = ");
|
||||
//serial_phex(pin);
|
||||
//serial_print(", freq = ");
|
||||
//serial_phex32(frequency);
|
||||
//serial_print("\n");
|
||||
for (prescale = 0; prescale < 7; prescale++) {
|
||||
minfreq = (F_BUS >> 16) >> prescale;
|
||||
if (frequency > minfreq) break;
|
||||
}
|
||||
//serial_print("F_BUS = ");
|
||||
//serial_phex32(F_BUS >> prescale);
|
||||
//serial_print("\n");
|
||||
//serial_print("prescale = ");
|
||||
//serial_phex(prescale);
|
||||
//serial_print("\n");
|
||||
//mod = ((F_BUS >> prescale) / frequency) - 1;
|
||||
mod = (((F_BUS >> prescale) + (frequency >> 1)) / frequency) - 1;
|
||||
if (mod > 65535) mod = 65535;
|
||||
//serial_print("mod = ");
|
||||
//serial_phex32(mod);
|
||||
//serial_print("\n");
|
||||
if (pin == 3 || pin == 4) {
|
||||
FTM1_SC = 0;
|
||||
FTM1_CNT = 0;
|
||||
FTM1_MOD = mod;
|
||||
FTM1_SC = FTM_SC_CLKS(1) | FTM_SC_PS(prescale);
|
||||
} else if (pin == 5 || pin == 6 || pin == 9 || pin == 10 ||
|
||||
(pin >= 20 && pin <= 23)) {
|
||||
FTM0_SC = 0;
|
||||
FTM0_CNT = 0;
|
||||
FTM0_MOD = mod;
|
||||
FTM0_SC = FTM_SC_CLKS(1) | FTM_SC_PS(prescale);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// TODO: startup code needs to initialize all pins to GPIO mode, input by default
|
||||
|
||||
void digitalWrite(uint8_t pin, uint8_t val)
|
||||
{
|
||||
if (pin >= CORE_NUM_DIGITAL) return;
|
||||
if (*portModeRegister(pin)) {
|
||||
if (val) {
|
||||
*portSetRegister(pin) = 1;
|
||||
} else {
|
||||
*portClearRegister(pin) = 1;
|
||||
}
|
||||
} else {
|
||||
volatile uint32_t *config = portConfigRegister(pin);
|
||||
if (val) {
|
||||
// TODO use bitband for atomic read-mod-write
|
||||
*config |= (PORT_PCR_PE | PORT_PCR_PS);
|
||||
//*config = PORT_PCR_MUX(1) | PORT_PCR_PE | PORT_PCR_PS;
|
||||
} else {
|
||||
// TODO use bitband for atomic read-mod-write
|
||||
*config &= ~(PORT_PCR_PE);
|
||||
//*config = PORT_PCR_MUX(1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
uint8_t digitalRead(uint8_t pin)
|
||||
{
|
||||
if (pin >= CORE_NUM_DIGITAL) return 0;
|
||||
return *portInputRegister(pin);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void pinMode(uint8_t pin, uint8_t mode)
|
||||
{
|
||||
volatile uint32_t *config;
|
||||
|
||||
if (pin >= CORE_NUM_DIGITAL) return;
|
||||
config = portConfigRegister(pin);
|
||||
|
||||
if (mode == OUTPUT) {
|
||||
*portModeRegister(pin) = 1;
|
||||
*config = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1);
|
||||
} else {
|
||||
*portModeRegister(pin) = 0;
|
||||
if (mode == INPUT) {
|
||||
*config = PORT_PCR_MUX(1);
|
||||
} else {
|
||||
*config = PORT_PCR_MUX(1) | PORT_PCR_PE | PORT_PCR_PS; // pullup
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void _shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t value)
|
||||
{
|
||||
if (bitOrder == LSBFIRST) {
|
||||
shiftOut_lsbFirst(dataPin, clockPin, value);
|
||||
} else {
|
||||
shiftOut_msbFirst(dataPin, clockPin, value);
|
||||
}
|
||||
}
|
||||
|
||||
void shiftOut_lsbFirst(uint8_t dataPin, uint8_t clockPin, uint8_t value)
|
||||
{
|
||||
uint8_t mask;
|
||||
for (mask=0x01; mask; mask <<= 1) {
|
||||
digitalWrite(dataPin, value & mask);
|
||||
digitalWrite(clockPin, HIGH);
|
||||
digitalWrite(clockPin, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
void shiftOut_msbFirst(uint8_t dataPin, uint8_t clockPin, uint8_t value)
|
||||
{
|
||||
uint8_t mask;
|
||||
for (mask=0x80; mask; mask >>= 1) {
|
||||
digitalWrite(dataPin, value & mask);
|
||||
digitalWrite(clockPin, HIGH);
|
||||
digitalWrite(clockPin, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t _shiftIn(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder)
|
||||
{
|
||||
if (bitOrder == LSBFIRST) {
|
||||
return shiftIn_lsbFirst(dataPin, clockPin);
|
||||
} else {
|
||||
return shiftIn_msbFirst(dataPin, clockPin);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t shiftIn_lsbFirst(uint8_t dataPin, uint8_t clockPin)
|
||||
{
|
||||
uint8_t mask, value=0;
|
||||
for (mask=0x01; mask; mask <<= 1) {
|
||||
digitalWrite(clockPin, HIGH);
|
||||
if (digitalRead(dataPin)) value |= mask;
|
||||
digitalWrite(clockPin, LOW);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
uint8_t shiftIn_msbFirst(uint8_t dataPin, uint8_t clockPin)
|
||||
{
|
||||
uint8_t mask, value=0;
|
||||
for (mask=0x80; mask; mask >>= 1) {
|
||||
digitalWrite(clockPin, HIGH);
|
||||
if (digitalRead(dataPin)) value |= mask;
|
||||
digitalWrite(clockPin, LOW);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// the systick interrupt is supposed to increment this at 1 kHz rate
|
||||
volatile uint32_t systick_millis_count = 0;
|
||||
|
||||
//uint32_t systick_current, systick_count, systick_istatus; // testing only
|
||||
|
||||
uint32_t micros(void)
|
||||
{
|
||||
uint32_t count, current, istatus;
|
||||
|
||||
__disable_irq();
|
||||
current = SYST_CVR;
|
||||
count = systick_millis_count;
|
||||
istatus = SCB_ICSR; // bit 26 indicates if systick exception pending
|
||||
__enable_irq();
|
||||
//systick_current = current;
|
||||
//systick_count = count;
|
||||
//systick_istatus = istatus & SCB_ICSR_PENDSTSET ? 1 : 0;
|
||||
if ((istatus & SCB_ICSR_PENDSTSET) && current > 50) count++;
|
||||
current = ((F_CPU / 1000) - 1) - current;
|
||||
return count * 1000 + current / (F_CPU / 1000000);
|
||||
}
|
||||
|
||||
void delay(uint32_t ms)
|
||||
{
|
||||
uint32_t start = micros();
|
||||
|
||||
if (ms > 0) {
|
||||
while (1) {
|
||||
if ((micros() - start) >= 1000) {
|
||||
ms--;
|
||||
if (ms == 0) return;
|
||||
start += 1000;
|
||||
}
|
||||
yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if F_CPU == 96000000
|
||||
#define PULSEIN_LOOPS_PER_USEC 14
|
||||
#elif F_CPU == 48000000
|
||||
#define PULSEIN_LOOPS_PER_USEC 7
|
||||
#elif F_CPU == 24000000
|
||||
#define PULSEIN_LOOPS_PER_USEC 4
|
||||
#endif
|
||||
|
||||
|
||||
uint32_t pulseIn_high(volatile uint8_t *reg, uint32_t timeout)
|
||||
{
|
||||
uint32_t timeout_count = timeout * PULSEIN_LOOPS_PER_USEC;
|
||||
uint32_t usec_start, usec_stop;
|
||||
|
||||
// wait for any previous pulse to end
|
||||
while (*reg) {
|
||||
if (--timeout_count == 0) return 0;
|
||||
}
|
||||
// wait for the pulse to start
|
||||
while (!*reg) {
|
||||
if (--timeout_count == 0) return 0;
|
||||
}
|
||||
usec_start = micros();
|
||||
// wait for the pulse to stop
|
||||
while (*reg) {
|
||||
if (--timeout_count == 0) return 0;
|
||||
}
|
||||
usec_stop = micros();
|
||||
return usec_stop - usec_start;
|
||||
}
|
||||
|
||||
uint32_t pulseIn_low(volatile uint8_t *reg, uint32_t timeout)
|
||||
{
|
||||
uint32_t timeout_count = timeout * PULSEIN_LOOPS_PER_USEC;
|
||||
uint32_t usec_start, usec_stop;
|
||||
|
||||
// wait for any previous pulse to end
|
||||
while (!*reg) {
|
||||
if (--timeout_count == 0) return 0;
|
||||
}
|
||||
// wait for the pulse to start
|
||||
while (*reg) {
|
||||
if (--timeout_count == 0) return 0;
|
||||
}
|
||||
usec_start = micros();
|
||||
// wait for the pulse to stop
|
||||
while (!*reg) {
|
||||
if (--timeout_count == 0) return 0;
|
||||
}
|
||||
usec_stop = micros();
|
||||
return usec_stop - usec_start;
|
||||
}
|
||||
|
||||
// TODO: an inline version should handle the common case where state is const
|
||||
uint32_t pulseIn(uint8_t pin, uint8_t state, uint32_t timeout)
|
||||
{
|
||||
if (pin >= CORE_NUM_DIGITAL) return 0;
|
||||
if (state) return pulseIn_high(portInputRegister(pin), timeout);
|
||||
return pulseIn_low(portInputRegister(pin), timeout);;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
348
teensy3/serial1.c
Normal file
348
teensy3/serial1.c
Normal file
|
|
@ -0,0 +1,348 @@
|
|||
/* Teensyduino Core Library
|
||||
* http://www.pjrc.com/teensy/
|
||||
* Copyright (c) 2013 PJRC.COM, LLC.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* 1. The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* 2. If the Software is incorporated into a build system that allows
|
||||
* selection among a list of target devices, then similar target
|
||||
* devices manufactured by PJRC.COM must be included in the list of
|
||||
* target devices and selectable in the same manner.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "mk20dx128.h"
|
||||
#include "core_pins.h"
|
||||
#include "HardwareSerial.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// Tunable parameters (relatively safe to edit these numbers)
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
#define TX_BUFFER_SIZE 64 // number of outgoing bytes to buffer
|
||||
#define RX_BUFFER_SIZE 64 // number of incoming bytes to buffer
|
||||
#define IRQ_PRIORITY 64 // 0 = highest priority, 255 = lowest
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// changes not recommended below this point....
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
static volatile uint8_t tx_buffer[TX_BUFFER_SIZE];
|
||||
static volatile uint8_t rx_buffer[RX_BUFFER_SIZE];
|
||||
static volatile uint8_t transmitting = 0;
|
||||
#if TX_BUFFER_SIZE > 255
|
||||
static volatile uint16_t tx_buffer_head = 0;
|
||||
static volatile uint16_t tx_buffer_tail = 0;
|
||||
#else
|
||||
static volatile uint8_t tx_buffer_head = 0;
|
||||
static volatile uint8_t tx_buffer_tail = 0;
|
||||
#endif
|
||||
#if RX_BUFFER_SIZE > 255
|
||||
static volatile uint16_t rx_buffer_head = 0;
|
||||
static volatile uint16_t rx_buffer_tail = 0;
|
||||
#else
|
||||
static volatile uint8_t rx_buffer_head = 0;
|
||||
static volatile uint8_t rx_buffer_tail = 0;
|
||||
#endif
|
||||
|
||||
// UART0 and UART1 are clocked by F_CPU, UART2 is clocked by F_BUS
|
||||
// UART0 has 8 byte fifo, UART1 and UART2 have 1 byte buffer
|
||||
|
||||
#define C2_ENABLE UART_C2_TE | UART_C2_RE | UART_C2_RIE | UART_C2_ILIE
|
||||
#define C2_TX_ACTIVE C2_ENABLE | UART_C2_TIE
|
||||
#define C2_TX_COMPLETING C2_ENABLE | UART_C2_TCIE
|
||||
#define C2_TX_INACTIVE C2_ENABLE
|
||||
|
||||
void serial_begin(uint32_t divisor)
|
||||
{
|
||||
SIM_SCGC4 |= SIM_SCGC4_UART0; // turn on clock, TODO: use bitband
|
||||
rx_buffer_head = 0;
|
||||
rx_buffer_tail = 0;
|
||||
tx_buffer_head = 0;
|
||||
tx_buffer_tail = 0;
|
||||
transmitting = 0;
|
||||
CORE_PIN0_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_PFE | PORT_PCR_MUX(3);
|
||||
CORE_PIN1_CONFIG = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(3);
|
||||
UART0_BDH = (divisor >> 13) & 0x1F;
|
||||
UART0_BDL = (divisor >> 5) & 0xFF;
|
||||
UART0_C4 = divisor & 0x1F;
|
||||
//UART0_C1 = 0;
|
||||
UART0_C1 = UART_C1_ILT;
|
||||
UART0_TWFIFO = 2; // tx watermark, causes S1_TDRE to set
|
||||
UART0_RWFIFO = 4; // rx watermark, causes S1_RDRF to set
|
||||
UART0_PFIFO = UART_PFIFO_TXFE | UART_PFIFO_RXFE;
|
||||
UART0_C2 = C2_TX_INACTIVE;
|
||||
NVIC_SET_PRIORITY(IRQ_UART0_STATUS, IRQ_PRIORITY);
|
||||
NVIC_ENABLE_IRQ(IRQ_UART0_STATUS);
|
||||
}
|
||||
|
||||
void serial_end(void)
|
||||
{
|
||||
if (!(SIM_SCGC4 & SIM_SCGC4_UART0)) return;
|
||||
while (transmitting) yield(); // wait for buffered data to send
|
||||
NVIC_DISABLE_IRQ(IRQ_UART0_STATUS);
|
||||
UART0_C2 = 0;
|
||||
CORE_PIN0_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1);
|
||||
CORE_PIN1_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1);
|
||||
rx_buffer_head = 0;
|
||||
rx_buffer_tail = 0;
|
||||
}
|
||||
|
||||
|
||||
static int get_nvic_execution_priority(void)
|
||||
{
|
||||
int priority=256;
|
||||
uint32_t primask, faultmask, basepri, ipsr;
|
||||
|
||||
// full algorithm in ARM DDI0403D, page B1-639
|
||||
// this isn't quite complete, but hopefully good enough
|
||||
asm volatile("mrs %0, faultmask\n" : "=r" (faultmask)::);
|
||||
if (faultmask) return -1;
|
||||
asm volatile("mrs %0, primask\n" : "=r" (primask)::);
|
||||
if (primask) return 0;
|
||||
asm volatile("mrs %0, ipsr\n" : "=r" (ipsr)::);
|
||||
if (ipsr) {
|
||||
if (ipsr < 16) priority = 0; // could be non-zero
|
||||
else priority = NVIC_GET_PRIORITY(ipsr - 16);
|
||||
}
|
||||
asm volatile("mrs %0, basepri\n" : "=r" (basepri)::);
|
||||
if (basepri > 0 && basepri < priority) priority = basepri;
|
||||
return priority;
|
||||
}
|
||||
|
||||
|
||||
void serial_putchar(uint8_t c)
|
||||
{
|
||||
uint32_t head;
|
||||
|
||||
if (!(SIM_SCGC4 & SIM_SCGC4_UART0)) return;
|
||||
head = tx_buffer_head;
|
||||
if (++head >= TX_BUFFER_SIZE) head = 0;
|
||||
while (tx_buffer_tail == head) {
|
||||
if (get_nvic_execution_priority() <= IRQ_PRIORITY) {
|
||||
if ((UART0_S1 & UART_S1_TDRE)) {
|
||||
uint32_t tail = tx_buffer_tail;
|
||||
if (++tail >= TX_BUFFER_SIZE) tail = 0;
|
||||
UART0_D = tx_buffer[tail];
|
||||
tx_buffer_tail = tail;
|
||||
}
|
||||
} else {
|
||||
yield();
|
||||
}
|
||||
}
|
||||
tx_buffer[head] = c;
|
||||
transmitting = 1;
|
||||
tx_buffer_head = head;
|
||||
UART0_C2 = C2_TX_ACTIVE;
|
||||
}
|
||||
|
||||
void serial_write(const void *buf, unsigned int count)
|
||||
{
|
||||
const uint8_t *p = (const uint8_t *)buf;
|
||||
const uint8_t *end = p + count;
|
||||
uint32_t head;
|
||||
|
||||
if (!(SIM_SCGC4 & SIM_SCGC4_UART0)) return;
|
||||
while (p < end) {
|
||||
head = tx_buffer_head;
|
||||
if (++head >= TX_BUFFER_SIZE) head = 0;
|
||||
if (tx_buffer_tail == head) {
|
||||
UART0_C2 = C2_TX_ACTIVE;
|
||||
do {
|
||||
if (get_nvic_execution_priority() <= IRQ_PRIORITY) {
|
||||
if ((UART0_S1 & UART_S1_TDRE)) {
|
||||
uint32_t tail = tx_buffer_tail;
|
||||
if (++tail >= TX_BUFFER_SIZE) tail = 0;
|
||||
UART0_D = tx_buffer[tail];
|
||||
tx_buffer_tail = tail;
|
||||
}
|
||||
} else {
|
||||
yield();
|
||||
}
|
||||
} while (tx_buffer_tail == head);
|
||||
}
|
||||
tx_buffer[head] = *p++;
|
||||
transmitting = 1;
|
||||
tx_buffer_head = head;
|
||||
}
|
||||
UART0_C2 = C2_TX_ACTIVE;
|
||||
}
|
||||
|
||||
void serial_flush(void)
|
||||
{
|
||||
while (transmitting) yield(); // wait
|
||||
}
|
||||
|
||||
int serial_available(void)
|
||||
{
|
||||
uint32_t head, tail;
|
||||
|
||||
head = rx_buffer_head;
|
||||
tail = rx_buffer_tail;
|
||||
if (head >= tail) return head - tail;
|
||||
return RX_BUFFER_SIZE + head - tail;
|
||||
}
|
||||
|
||||
int serial_getchar(void)
|
||||
{
|
||||
uint32_t head, tail;
|
||||
int c;
|
||||
|
||||
head = rx_buffer_head;
|
||||
tail = rx_buffer_tail;
|
||||
if (head == tail) return -1;
|
||||
if (++tail >= RX_BUFFER_SIZE) tail = 0;
|
||||
c = rx_buffer[tail];
|
||||
rx_buffer_tail = tail;
|
||||
return c;
|
||||
}
|
||||
|
||||
int serial_peek(void)
|
||||
{
|
||||
uint32_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];
|
||||
}
|
||||
|
||||
void serial_clear(void)
|
||||
{
|
||||
if (!(SIM_SCGC4 & SIM_SCGC4_UART0)) return;
|
||||
UART0_C2 &= ~(UART_C2_RE | UART_C2_RIE | UART_C2_ILIE);
|
||||
UART0_CFIFO = UART_CFIFO_RXFLUSH;
|
||||
UART0_C2 |= (UART_C2_RE | UART_C2_RIE | UART_C2_ILIE);
|
||||
rx_buffer_head = rx_buffer_tail;
|
||||
}
|
||||
|
||||
// status interrupt combines
|
||||
// Transmit data below watermark UART_S1_TDRE
|
||||
// Transmit complete UART_S1_TC
|
||||
// Idle line UART_S1_IDLE
|
||||
// Receive data above watermark UART_S1_RDRF
|
||||
// LIN break detect UART_S2_LBKDIF
|
||||
// RxD pin active edge UART_S2_RXEDGIF
|
||||
|
||||
void uart0_status_isr(void)
|
||||
{
|
||||
uint32_t head, newhead, tail;
|
||||
uint8_t avail, c;
|
||||
|
||||
if (UART0_S1 & (UART_S1_RDRF | UART_S1_IDLE)) {
|
||||
__disable_irq();
|
||||
avail = UART0_RCFIFO;
|
||||
if (avail == 0) {
|
||||
// The only way to clear the IDLE interrupt flag is
|
||||
// to read the data register. But reading with no
|
||||
// data causes a FIFO underrun, which causes the
|
||||
// FIFO to return corrupted data. If anyone from
|
||||
// Freescale reads this, what a poor design! There
|
||||
// write should be a write-1-to-clear for IDLE.
|
||||
c = UART0_D;
|
||||
// flushing the fifo recovers from the underrun,
|
||||
// but there's a possible race condition where a
|
||||
// new character could be received between reading
|
||||
// RCFIFO == 0 and flushing the FIFO. To minimize
|
||||
// the chance, interrupts are disabled so a higher
|
||||
// priority interrupt (hopefully) doesn't delay.
|
||||
// TODO: change this to disabling the IDLE interrupt
|
||||
// which won't be simple, since we already manage
|
||||
// which transmit interrupts are enabled.
|
||||
UART0_CFIFO = UART_CFIFO_RXFLUSH;
|
||||
__enable_irq();
|
||||
} else {
|
||||
__enable_irq();
|
||||
head = rx_buffer_head;
|
||||
tail = rx_buffer_tail;
|
||||
do {
|
||||
c = UART0_D;
|
||||
newhead = head + 1;
|
||||
if (newhead >= RX_BUFFER_SIZE) newhead = 0;
|
||||
if (newhead != tail) {
|
||||
head = newhead;
|
||||
rx_buffer[head] = c;
|
||||
}
|
||||
} while (--avail > 0);
|
||||
rx_buffer_head = head;
|
||||
}
|
||||
}
|
||||
c = UART0_C2;
|
||||
if ((c & UART_C2_TIE) && (UART0_S1 & UART_S1_TDRE)) {
|
||||
head = tx_buffer_head;
|
||||
tail = tx_buffer_tail;
|
||||
do {
|
||||
if (tail == head) break;
|
||||
if (++tail >= TX_BUFFER_SIZE) tail = 0;
|
||||
avail = UART0_S1;
|
||||
UART0_D = tx_buffer[tail];
|
||||
} while (UART0_TCFIFO < 8);
|
||||
tx_buffer_tail = tail;
|
||||
if (UART0_S1 & UART_S1_TDRE) UART0_C2 = C2_TX_COMPLETING;
|
||||
}
|
||||
if ((c & UART_C2_TCIE) && (UART0_S1 & UART_S1_TC)) {
|
||||
transmitting = 0;
|
||||
UART0_C2 = C2_TX_INACTIVE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void serial_print(const char *p)
|
||||
{
|
||||
while (*p) {
|
||||
char c = *p++;
|
||||
if (c == '\n') serial_putchar('\r');
|
||||
serial_putchar(c);
|
||||
}
|
||||
}
|
||||
|
||||
static void serial_phex1(uint32_t n)
|
||||
{
|
||||
n &= 15;
|
||||
if (n < 10) {
|
||||
serial_putchar('0' + n);
|
||||
} else {
|
||||
serial_putchar('A' - 10 + n);
|
||||
}
|
||||
}
|
||||
|
||||
void serial_phex(uint32_t n)
|
||||
{
|
||||
serial_phex1(n >> 4);
|
||||
serial_phex1(n);
|
||||
}
|
||||
|
||||
void serial_phex16(uint32_t n)
|
||||
{
|
||||
serial_phex(n >> 8);
|
||||
serial_phex(n);
|
||||
}
|
||||
|
||||
void serial_phex32(uint32_t n)
|
||||
{
|
||||
serial_phex(n >> 24);
|
||||
serial_phex(n >> 16);
|
||||
serial_phex(n >> 8);
|
||||
serial_phex(n);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue