diff --git a/teensy3/Arduino.h b/teensy3/Arduino.h new file mode 100644 index 0000000000000000000000000000000000000000..298e0a2db85583c848e7eb314c759310fe4f7fe8 --- /dev/null +++ b/teensy3/Arduino.h @@ -0,0 +1,2 @@ +#include "WProgram.h" +#include "pins_arduino.h" diff --git a/teensy3/Client.h b/teensy3/Client.h new file mode 100644 index 0000000000000000000000000000000000000000..da8556a8c3cf7363554c83e856bfb68af7266aa1 --- /dev/null +++ b/teensy3/Client.h @@ -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 diff --git a/teensy3/HardwareSerial.h b/teensy3/HardwareSerial.h new file mode 100644 index 0000000000000000000000000000000000000000..1554cf109d9c5eede55eff4c329347c65764f490 --- /dev/null +++ b/teensy3/HardwareSerial.h @@ -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 diff --git a/teensy3/HardwareSerial1.cpp b/teensy3/HardwareSerial1.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9ac972ed68a7a8bbb503b3d3ad9fa9442acade00 --- /dev/null +++ b/teensy3/HardwareSerial1.cpp @@ -0,0 +1,4 @@ +#include "HardwareSerial.h" + +HardwareSerial Serial1; + diff --git a/teensy3/HardwareSerial2.cpp b/teensy3/HardwareSerial2.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d9fc3b87ff46d6f6ebaa08053ad692a6b46a812d --- /dev/null +++ b/teensy3/HardwareSerial2.cpp @@ -0,0 +1,4 @@ +#include "HardwareSerial.h" + +HardwareSerial2 Serial2; + diff --git a/teensy3/HardwareSerial3.cpp b/teensy3/HardwareSerial3.cpp new file mode 100644 index 0000000000000000000000000000000000000000..553b732748b698b754a293a71b151d5f9a0e9be3 --- /dev/null +++ b/teensy3/HardwareSerial3.cpp @@ -0,0 +1,4 @@ +#include "HardwareSerial.h" + +HardwareSerial3 Serial3; + diff --git a/teensy3/IPAddress.cpp b/teensy3/IPAddress.cpp new file mode 100644 index 0000000000000000000000000000000000000000..673ed8ceb8eb681feecefb575fa27baf72b76ce4 --- /dev/null +++ b/teensy3/IPAddress.cpp @@ -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 diff --git a/teensy3/IPAddress.h b/teensy3/IPAddress.h new file mode 100644 index 0000000000000000000000000000000000000000..7738eca8e6193ad3c066799cb8d87e17211b5c41 --- /dev/null +++ b/teensy3/IPAddress.h @@ -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 diff --git a/teensy3/IntervalTimer.cpp b/teensy3/IntervalTimer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6a0021a17b119220f1d2c3fcc6e88cff68a8b04a --- /dev/null +++ b/teensy3/IntervalTimer.cpp @@ -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(); + +} + + diff --git a/teensy3/IntervalTimer.h b/teensy3/IntervalTimer.h new file mode 100644 index 0000000000000000000000000000000000000000..fa5d4eeb9ce5dbfbf7de5412d75bf8027b974c43 --- /dev/null +++ b/teensy3/IntervalTimer.h @@ -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 diff --git a/teensy3/Makefile b/teensy3/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..5cc1efcea66039fddcfaa4b2276428b2303142c1 --- /dev/null +++ b/teensy3/Makefile @@ -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) + +%.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 + + diff --git a/teensy3/Print.cpp b/teensy3/Print.cpp new file mode 100644 index 0000000000000000000000000000000000000000..695d3a125294105a26d05c4ad2415308386b9a7f --- /dev/null +++ b/teensy3/Print.cpp @@ -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; +} + + diff --git a/teensy3/Print.h b/teensy3/Print.h new file mode 100644 index 0000000000000000000000000000000000000000..1f0a5506d5a8b04b1a71d2d17ba139bb083bdb27 --- /dev/null +++ b/teensy3/Print.h @@ -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 diff --git a/teensy3/Printable.h b/teensy3/Printable.h new file mode 100644 index 0000000000000000000000000000000000000000..2ac5117a7a59bb97325987974320d2ce6f59413e --- /dev/null +++ b/teensy3/Printable.h @@ -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 diff --git a/teensy3/Server.h b/teensy3/Server.h new file mode 100644 index 0000000000000000000000000000000000000000..167adacbf8269838b0f3102179c52bbafd852b09 --- /dev/null +++ b/teensy3/Server.h @@ -0,0 +1,12 @@ +#if ARDUINO >= 100 + +#ifndef server_h +#define server_h + +class Server : public Print { +public: + virtual void begin() =0; +}; + +#endif +#endif diff --git a/teensy3/Stream.cpp b/teensy3/Stream.cpp new file mode 100644 index 0000000000000000000000000000000000000000..186b60851abed35571627a712478d1aebcb97ee1 --- /dev/null +++ b/teensy3/Stream.cpp @@ -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; +} + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/teensy3/Stream.h b/teensy3/Stream.h new file mode 100644 index 0000000000000000000000000000000000000000..29d202016779bfd4dcc3805d67c32525488c1f08 --- /dev/null +++ b/teensy3/Stream.h @@ -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 diff --git a/teensy3/Tone.cpp b/teensy3/Tone.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a3b4bab999a6a20fab85ecac0950fa3f099a1bc6 --- /dev/null +++ b/teensy3/Tone.cpp @@ -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 + + + + + + + + + diff --git a/teensy3/Udp.h b/teensy3/Udp.h new file mode 100644 index 0000000000000000000000000000000000000000..15d821ae8b794f9c897cfab4ee90b9477467af2b --- /dev/null +++ b/teensy3/Udp.h @@ -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 diff --git a/teensy3/WCharacter.h b/teensy3/WCharacter.h new file mode 100644 index 0000000000000000000000000000000000000000..79733b50a535b2cc17119168acb51a92c37fa610 --- /dev/null +++ b/teensy3/WCharacter.h @@ -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 \ No newline at end of file diff --git a/teensy3/WConstants.h b/teensy3/WConstants.h new file mode 100644 index 0000000000000000000000000000000000000000..3e19ac44aac6f8327b75922c2396ea52001cf6b7 --- /dev/null +++ b/teensy3/WConstants.h @@ -0,0 +1 @@ +#include "wiring.h" diff --git a/teensy3/WMath.cpp b/teensy3/WMath.cpp new file mode 100644 index 0000000000000000000000000000000000000000..927633edefecab30952564901330cca1071fa96f --- /dev/null +++ b/teensy3/WMath.cpp @@ -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; } + diff --git a/teensy3/WProgram.h b/teensy3/WProgram.h new file mode 100644 index 0000000000000000000000000000000000000000..f1fe195d001a87eda74b892fabf840919479d166 --- /dev/null +++ b/teensy3/WProgram.h @@ -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 diff --git a/teensy3/WString.cpp b/teensy3/WString.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f18fa922004ec813433daa9f07b5ca9fba3624cb --- /dev/null +++ b/teensy3/WString.cpp @@ -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; +} + + diff --git a/teensy3/WString.h b/teensy3/WString.h new file mode 100644 index 0000000000000000000000000000000000000000..e979a8b617afed99b539a1cafa80e860d555dd19 --- /dev/null +++ b/teensy3/WString.h @@ -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 diff --git a/teensy3/analog.c b/teensy3/analog.c new file mode 100644 index 0000000000000000000000000000000000000000..f8d33b0fb5e163b38f9a01422c4b6e829d489acb --- /dev/null +++ b/teensy3/analog.c @@ -0,0 +1,258 @@ +/* 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("."); + } + //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; +} + +// 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 +}; + +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 + + 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; +} + + + + + + + + + + + + + + + + + + + + + + diff --git a/teensy3/arm_common_tables.h b/teensy3/arm_common_tables.h new file mode 100644 index 0000000000000000000000000000000000000000..8c35ef2bd516c3002ebfc44e1542f5dd0e44bbcb --- /dev/null +++ b/teensy3/arm_common_tables.h @@ -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 */ diff --git a/teensy3/arm_math.h b/teensy3/arm_math.h new file mode 100644 index 0000000000000000000000000000000000000000..8822dc8eb4649d9a4ccfbd58fde1e0c3215497a8 --- /dev/null +++ b/teensy3/arm_math.h @@ -0,0 +1,7571 @@ +/* ---------------------------------------------------------------------- + * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * + * $Date: 15. February 2012 + * $Revision: V1.1.0 + * + * Project: CMSIS DSP Library + * Title: arm_math.h + * + * Description: Public header file for CMSIS DSP Library + * + * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0 + * + * Version 1.1.0 2012/02/15 + * Updated with more optimizations, bug fixes and minor API changes. + * + * Version 1.0.10 2011/7/15 + * Big Endian support added and Merged M0 and M3/M4 Source code. + * + * 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. + * -------------------------------------------------------------------- */ + +/** + \mainpage CMSIS DSP Software Library + * + * <b>Introduction</b> + * + * This user manual describes the CMSIS DSP software library, + * a suite of common signal processing functions for use on Cortex-M processor based devices. + * + * The library is divided into a number of functions each covering a specific category: + * - Basic math functions + * - Fast math functions + * - Complex math functions + * - Filters + * - Matrix functions + * - Transforms + * - Motor control functions + * - Statistical functions + * - Support functions + * - Interpolation functions + * + * The library has separate functions for operating on 8-bit integers, 16-bit integers, + * 32-bit integer and 32-bit floating-point values. + * + * <b>Pre-processor Macros</b> + * + * Each library project have differant pre-processor macros. + * + * - UNALIGNED_SUPPORT_DISABLE: + * + * Define macro UNALIGNED_SUPPORT_DISABLE, If the silicon does not support unaligned memory access + * + * - ARM_MATH_BIG_ENDIAN: + * + * Define macro ARM_MATH_BIG_ENDIAN to build the library for big endian targets. By default library builds for little endian targets. + * + * - ARM_MATH_MATRIX_CHECK: + * + * Define macro ARM_MATH_MATRIX_CHECK for checking on the input and output sizes of matrices + * + * - ARM_MATH_ROUNDING: + * + * Define macro ARM_MATH_ROUNDING for rounding on support functions + * + * - ARM_MATH_CMx: + * + * Define macro ARM_MATH_CM4 for building the library on Cortex-M4 target, ARM_MATH_CM3 for building library on Cortex-M3 target + * and ARM_MATH_CM0 for building library on cortex-M0 target. + * + * - __FPU_PRESENT: + * + * Initialize macro __FPU_PRESENT = 1 when building on FPU supported Targets. Enable this macro for M4bf and M4lf libraries + * + * <b>Toolchain Support</b> + * + * The library has been developed and tested with MDK-ARM version 4.23. + * The library is being tested in GCC and IAR toolchains and updates on this activity will be made available shortly. + * + * <b>Using the Library</b> + * + * The library installer contains prebuilt versions of the libraries in the <code>Lib</code> folder. + * - arm_cortexM4lf_math.lib (Little endian and Floating Point Unit on Cortex-M4) + * - arm_cortexM4bf_math.lib (Big endian and Floating Point Unit on Cortex-M4) + * - arm_cortexM4l_math.lib (Little endian on Cortex-M4) + * - arm_cortexM4b_math.lib (Big endian on Cortex-M4) + * - arm_cortexM3l_math.lib (Little endian on Cortex-M3) + * - arm_cortexM3b_math.lib (Big endian on Cortex-M3) + * - arm_cortexM0l_math.lib (Little endian on Cortex-M0) + * - arm_cortexM0b_math.lib (Big endian on Cortex-M3) + * + * The library functions are declared in the public file <code>arm_math.h</code> which is placed in the <code>Include</code> folder. + * Simply include this file and link the appropriate library in the application and begin calling the library functions. The Library supports single + * public header file <code> arm_math.h</code> for Cortex-M4/M3/M0 with little endian and big endian. Same header file will be used for floating point unit(FPU) variants. + * Define the appropriate pre processor MACRO ARM_MATH_CM4 or ARM_MATH_CM3 or + * ARM_MATH_CM0 depending on the target processor in the application. + * + * <b>Examples</b> + * + * The library ships with a number of examples which demonstrate how to use the library functions. + * + * <b>Building the Library</b> + * + * The library installer contains project files to re build libraries on MDK Tool chain in the <code>CMSIS\\DSP_Lib\\Source\\ARM</code> folder. + * - arm_cortexM0b_math.uvproj + * - arm_cortexM0l_math.uvproj + * - arm_cortexM3b_math.uvproj + * - arm_cortexM3l_math.uvproj + * - arm_cortexM4b_math.uvproj + * - arm_cortexM4l_math.uvproj + * - arm_cortexM4bf_math.uvproj + * - arm_cortexM4lf_math.uvproj + * + * + * The project can be built by opening the appropriate project in MDK-ARM 4.23 chain and defining the optional pre processor MACROs detailed above. + * + * <b>Copyright Notice</b> + * + * Copyright (C) 2010 ARM Limited. All rights reserved. + */ + + +/** + * @defgroup groupMath Basic Math Functions + */ + +/** + * @defgroup groupFastMath Fast Math Functions + * This set of functions provides a fast approximation to sine, cosine, and square root. + * As compared to most of the other functions in the CMSIS math library, the fast math functions + * operate on individual values and not arrays. + * There are separate functions for Q15, Q31, and floating-point data. + * + */ + +/** + * @defgroup groupCmplxMath Complex Math Functions + * This set of functions operates on complex data vectors. + * The data in the complex arrays is stored in an interleaved fashion + * (real, imag, real, imag, ...). + * In the API functions, the number of samples in a complex array refers + * to the number of complex values; the array contains twice this number of + * real values. + */ + +/** + * @defgroup groupFilters Filtering Functions + */ + +/** + * @defgroup groupMatrix Matrix Functions + * + * This set of functions provides basic matrix math operations. + * The functions operate on matrix data structures. For example, + * the type + * definition for the floating-point matrix structure is shown + * below: + * <pre> + * typedef struct + * { + * uint16_t numRows; // number of rows of the matrix. + * uint16_t numCols; // number of columns of the matrix. + * float32_t *pData; // points to the data of the matrix. + * } arm_matrix_instance_f32; + * </pre> + * There are similar definitions for Q15 and Q31 data types. + * + * The structure specifies the size of the matrix and then points to + * an array of data. The array is of size <code>numRows X numCols</code> + * and the values are arranged in row order. That is, the + * matrix element (i, j) is stored at: + * <pre> + * pData[i*numCols + j] + * </pre> + * + * \par Init Functions + * There is an associated initialization function for each type of matrix + * data structure. + * The initialization function sets the values of the internal structure fields. + * Refer to the function <code>arm_mat_init_f32()</code>, <code>arm_mat_init_q31()</code> + * and <code>arm_mat_init_q15()</code> for floating-point, Q31 and Q15 types, respectively. + * + * \par + * Use of the initialization function is optional. However, if initialization function is used + * then the instance structure cannot be placed into a const data section. + * To place the instance structure in a const data + * section, manually initialize the data structure. For example: + * <pre> + * <code>arm_matrix_instance_f32 S = {nRows, nColumns, pData};</code> + * <code>arm_matrix_instance_q31 S = {nRows, nColumns, pData};</code> + * <code>arm_matrix_instance_q15 S = {nRows, nColumns, pData};</code> + * </pre> + * where <code>nRows</code> specifies the number of rows, <code>nColumns</code> + * specifies the number of columns, and <code>pData</code> points to the + * data array. + * + * \par Size Checking + * By default all of the matrix functions perform size checking on the input and + * output matrices. For example, the matrix addition function verifies that the + * two input matrices and the output matrix all have the same number of rows and + * columns. If the size check fails the functions return: + * <pre> + * ARM_MATH_SIZE_MISMATCH + * </pre> + * Otherwise the functions return + * <pre> + * ARM_MATH_SUCCESS + * </pre> + * There is some overhead associated with this matrix size checking. + * The matrix size checking is enabled via the \#define + * <pre> + * ARM_MATH_MATRIX_CHECK + * </pre> + * within the library project settings. By default this macro is defined + * and size checking is enabled. By changing the project settings and + * undefining this macro size checking is eliminated and the functions + * run a bit faster. With size checking disabled the functions always + * return <code>ARM_MATH_SUCCESS</code>. + */ + +/** + * @defgroup groupTransforms Transform Functions + */ + +/** + * @defgroup groupController Controller Functions + */ + +/** + * @defgroup groupStats Statistics Functions + */ +/** + * @defgroup groupSupport Support Functions + */ + +/** + * @defgroup groupInterpolation Interpolation Functions + * These functions perform 1- and 2-dimensional interpolation of data. + * Linear interpolation is used for 1-dimensional data and + * bilinear interpolation is used for 2-dimensional data. + */ + +/** + * @defgroup groupExamples Examples + */ +#ifndef _ARM_MATH_H +#define _ARM_MATH_H + +// Teensy 3.0 +#include <stdint.h> +#define __ASM __asm +#define __INLINE inline +#define __STATIC_INLINE static inline +#define __CORTEX_M 4 +#define __FPU_USED 0 +#define ARM_MATH_CM4 +#include "core_cmInstr.h" +#include "core_cm4_simd.h" + + +#if 0 +// generic for any board... +#define __CMSIS_GENERIC /* disable NVIC and Systick functions */ +#if defined (ARM_MATH_CM4) +#include "core_cm4.h" +#elif defined (ARM_MATH_CM3) +#include "core_cm3.h" +#elif defined (ARM_MATH_CM0) +#include "core_cm0.h" +#else +#include "ARMCM4.h" +#warning "Define either ARM_MATH_CM4 OR ARM_MATH_CM3...By Default building on ARM_MATH_CM4....." +#endif +#undef __CMSIS_GENERIC /* enable NVIC and Systick functions */ +#endif + +#include "string.h" +#include "math.h" +#ifdef __cplusplus +extern "C" +{ +#endif + + + /** + * @brief Macros required for reciprocal calculation in Normalized LMS + */ + +#define DELTA_Q31 (0x100) +#define DELTA_Q15 0x5 +#define INDEX_MASK 0x0000003F +#ifndef PI +#define PI 3.14159265358979f +#endif + + /** + * @brief Macros required for SINE and COSINE Fast math approximations + */ + +#define TABLE_SIZE 256 +#define TABLE_SPACING_Q31 0x800000 +#define TABLE_SPACING_Q15 0x80 + + /** + * @brief Macros required for SINE and COSINE Controller functions + */ + /* 1.31(q31) Fixed value of 2/360 */ + /* -1 to +1 is divided into 360 values so total spacing is (2/360) */ +#define INPUT_SPACING 0xB60B61 + + /** + * @brief Macro for Unaligned Support + */ +#ifndef UNALIGNED_SUPPORT_DISABLE + #define ALIGN4 +#else + #if defined (__GNUC__) + #define ALIGN4 __attribute__((aligned(4))) + #else + #define ALIGN4 __align(4) + #endif +#endif /* #ifndef UNALIGNED_SUPPORT_DISABLE */ + + /** + * @brief Error status returned by some functions in the library. + */ + + typedef enum + { + ARM_MATH_SUCCESS = 0, /**< No error */ + ARM_MATH_ARGUMENT_ERROR = -1, /**< One or more arguments are incorrect */ + ARM_MATH_LENGTH_ERROR = -2, /**< Length of data buffer is incorrect */ + ARM_MATH_SIZE_MISMATCH = -3, /**< Size of matrices is not compatible with the operation. */ + ARM_MATH_NANINF = -4, /**< Not-a-number (NaN) or infinity is generated */ + ARM_MATH_SINGULAR = -5, /**< Generated by matrix inversion if the input matrix is singular and cannot be inverted. */ + ARM_MATH_TEST_FAILURE = -6 /**< Test Failed */ + } arm_status; + + /** + * @brief 8-bit fractional data type in 1.7 format. + */ + typedef int8_t q7_t; + + /** + * @brief 16-bit fractional data type in 1.15 format. + */ + typedef int16_t q15_t; + + /** + * @brief 32-bit fractional data type in 1.31 format. + */ + typedef int32_t q31_t; + + /** + * @brief 64-bit fractional data type in 1.63 format. + */ + typedef int64_t q63_t; + + /** + * @brief 32-bit floating-point type definition. + */ + typedef float float32_t; + + /** + * @brief 64-bit floating-point type definition. + */ + typedef double float64_t; + + /** + * @brief definition to read/write two 16 bit values. + */ +#if defined (__GNUC__) + #define __SIMD32(addr) (*( int32_t **) & (addr)) + #define _SIMD32_OFFSET(addr) (*( int32_t * ) (addr)) +#else + #define __SIMD32(addr) (*(__packed int32_t **) & (addr)) + #define _SIMD32_OFFSET(addr) (*(__packed int32_t * ) (addr)) +#endif + + #define __SIMD64(addr) (*(int64_t **) & (addr)) + +#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0) + /** + * @brief definition to pack two 16 bit values. + */ +#define __PKHBT(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0x0000FFFF) | \ + (((int32_t)(ARG2) << ARG3) & (int32_t)0xFFFF0000) ) +#define __PKHTB(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0xFFFF0000) | \ + (((int32_t)(ARG2) >> ARG3) & (int32_t)0x0000FFFF) ) + +#endif + + + /** + * @brief definition to pack four 8 bit values. + */ +#ifndef ARM_MATH_BIG_ENDIAN + +#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v0) << 0) & (int32_t)0x000000FF) | \ + (((int32_t)(v1) << 8) & (int32_t)0x0000FF00) | \ + (((int32_t)(v2) << 16) & (int32_t)0x00FF0000) | \ + (((int32_t)(v3) << 24) & (int32_t)0xFF000000) ) +#else + +#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v3) << 0) & (int32_t)0x000000FF) | \ + (((int32_t)(v2) << 8) & (int32_t)0x0000FF00) | \ + (((int32_t)(v1) << 16) & (int32_t)0x00FF0000) | \ + (((int32_t)(v0) << 24) & (int32_t)0xFF000000) ) + +#endif + + + /** + * @brief Clips Q63 to Q31 values. + */ + __STATIC_INLINE q31_t clip_q63_to_q31( + q63_t x) + { + return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? + ((0x7FFFFFFF ^ ((q31_t) (x >> 63)))) : (q31_t) x; + } + + /** + * @brief Clips Q63 to Q15 values. + */ + __STATIC_INLINE q15_t clip_q63_to_q15( + q63_t x) + { + return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? + ((0x7FFF ^ ((q15_t) (x >> 63)))) : (q15_t) (x >> 15); + } + + /** + * @brief Clips Q31 to Q7 values. + */ + __STATIC_INLINE q7_t clip_q31_to_q7( + q31_t x) + { + return ((q31_t) (x >> 24) != ((q31_t) x >> 23)) ? + ((0x7F ^ ((q7_t) (x >> 31)))) : (q7_t) x; + } + + /** + * @brief Clips Q31 to Q15 values. + */ + __STATIC_INLINE q15_t clip_q31_to_q15( + q31_t x) + { + return ((q31_t) (x >> 16) != ((q31_t) x >> 15)) ? + ((0x7FFF ^ ((q15_t) (x >> 31)))) : (q15_t) x; + } + + /** + * @brief Multiplies 32 X 64 and returns 32 bit result in 2.30 format. + */ + + __STATIC_INLINE q63_t mult32x64( + q63_t x, + q31_t y) + { + return ((((q63_t) (x & 0x00000000FFFFFFFF) * y) >> 32) + + (((q63_t) (x >> 32) * y))); + } + + +#if defined (ARM_MATH_CM0) && defined ( __CC_ARM ) +#define __CLZ __clz +#endif + +#if defined (ARM_MATH_CM0) && defined ( __TASKING__ ) +/* No need to redefine __CLZ */ +#endif + +#if defined (ARM_MATH_CM0) && ((defined (__ICCARM__)) ||(defined (__GNUC__)) ) + + __STATIC_INLINE uint32_t __CLZ(q31_t data); + + + __STATIC_INLINE uint32_t __CLZ(q31_t data) + { + uint32_t count = 0; + uint32_t mask = 0x80000000; + + while((data & mask) == 0) + { + count += 1u; + mask = mask >> 1u; + } + + return (count); + + } + +#endif + + /** + * @brief Function to Calculates 1/in(reciprocal) value of Q31 Data type. + */ + + __STATIC_INLINE uint32_t arm_recip_q31( + q31_t in, + q31_t * dst, + q31_t * pRecipTable) + { + + uint32_t out, tempVal; + uint32_t index, i; + uint32_t signBits; + + if(in > 0) + { + signBits = __CLZ(in) - 1; + } + else + { + signBits = __CLZ(-in) - 1; + } + + /* Convert input sample to 1.31 format */ + in = in << signBits; + + /* calculation of index for initial approximated Val */ + index = (uint32_t) (in >> 24u); + index = (index & INDEX_MASK); + + /* 1.31 with exp 1 */ + out = pRecipTable[index]; + + /* calculation of reciprocal value */ + /* running approximation for two iterations */ + for (i = 0u; i < 2u; i++) + { + tempVal = (q31_t) (((q63_t) in * out) >> 31u); + tempVal = 0x7FFFFFFF - tempVal; + /* 1.31 with exp 1 */ + //out = (q31_t) (((q63_t) out * tempVal) >> 30u); + out = (q31_t) clip_q63_to_q31(((q63_t) out * tempVal) >> 30u); + } + + /* write output */ + *dst = out; + + /* return num of signbits of out = 1/in value */ + return (signBits + 1u); + + } + + /** + * @brief Function to Calculates 1/in(reciprocal) value of Q15 Data type. + */ + __STATIC_INLINE uint32_t arm_recip_q15( + q15_t in, + q15_t * dst, + q15_t * pRecipTable) + { + + uint32_t out = 0, tempVal = 0; + uint32_t index = 0, i = 0; + uint32_t signBits = 0; + + if(in > 0) + { + signBits = __CLZ(in) - 17; + } + else + { + signBits = __CLZ(-in) - 17; + } + + /* Convert input sample to 1.15 format */ + in = in << signBits; + + /* calculation of index for initial approximated Val */ + index = in >> 8; + index = (index & INDEX_MASK); + + /* 1.15 with exp 1 */ + out = pRecipTable[index]; + + /* calculation of reciprocal value */ + /* running approximation for two iterations */ + for (i = 0; i < 2; i++) + { + tempVal = (q15_t) (((q31_t) in * out) >> 15); + tempVal = 0x7FFF - tempVal; + /* 1.15 with exp 1 */ + out = (q15_t) (((q31_t) out * tempVal) >> 14); + } + + /* write output */ + *dst = out; + + /* return num of signbits of out = 1/in value */ + return (signBits + 1); + + } + + + /* + * @brief C custom defined intrinisic function for only M0 processors + */ +#if defined(ARM_MATH_CM0) + + __STATIC_INLINE q31_t __SSAT( + q31_t x, + uint32_t y) + { + int32_t posMax, negMin; + uint32_t i; + + posMax = 1; + for (i = 0; i < (y - 1); i++) + { + posMax = posMax * 2; + } + + if(x > 0) + { + posMax = (posMax - 1); + + if(x > posMax) + { + x = posMax; + } + } + else + { + negMin = -posMax; + + if(x < negMin) + { + x = negMin; + } + } + return (x); + + + } + +#endif /* end of ARM_MATH_CM0 */ + + + + /* + * @brief C custom defined intrinsic function for M3 and M0 processors + */ +#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0) + + /* + * @brief C custom defined QADD8 for M3 and M0 processors + */ + __STATIC_INLINE q31_t __QADD8( + q31_t x, + q31_t y) + { + + q31_t sum; + q7_t r, s, t, u; + + r = (q7_t) x; + s = (q7_t) y; + + r = __SSAT((q31_t) (r + s), 8); + s = __SSAT(((q31_t) (((x << 16) >> 24) + ((y << 16) >> 24))), 8); + t = __SSAT(((q31_t) (((x << 8) >> 24) + ((y << 8) >> 24))), 8); + u = __SSAT(((q31_t) ((x >> 24) + (y >> 24))), 8); + + sum = + (((q31_t) u << 24) & 0xFF000000) | (((q31_t) t << 16) & 0x00FF0000) | + (((q31_t) s << 8) & 0x0000FF00) | (r & 0x000000FF); + + return sum; + + } + + /* + * @brief C custom defined QSUB8 for M3 and M0 processors + */ + __STATIC_INLINE q31_t __QSUB8( + q31_t x, + q31_t y) + { + + q31_t sum; + q31_t r, s, t, u; + + r = (q7_t) x; + s = (q7_t) y; + + r = __SSAT((r - s), 8); + s = __SSAT(((q31_t) (((x << 16) >> 24) - ((y << 16) >> 24))), 8) << 8; + t = __SSAT(((q31_t) (((x << 8) >> 24) - ((y << 8) >> 24))), 8) << 16; + u = __SSAT(((q31_t) ((x >> 24) - (y >> 24))), 8) << 24; + + sum = + (u & 0xFF000000) | (t & 0x00FF0000) | (s & 0x0000FF00) | (r & + 0x000000FF); + + return sum; + } + + /* + * @brief C custom defined QADD16 for M3 and M0 processors + */ + + /* + * @brief C custom defined QADD16 for M3 and M0 processors + */ + __STATIC_INLINE q31_t __QADD16( + q31_t x, + q31_t y) + { + + q31_t sum; + q31_t r, s; + + r = (short) x; + s = (short) y; + + r = __SSAT(r + s, 16); + s = __SSAT(((q31_t) ((x >> 16) + (y >> 16))), 16) << 16; + + sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); + + return sum; + + } + + /* + * @brief C custom defined SHADD16 for M3 and M0 processors + */ + __STATIC_INLINE q31_t __SHADD16( + q31_t x, + q31_t y) + { + + q31_t sum; + q31_t r, s; + + r = (short) x; + s = (short) y; + + r = ((r >> 1) + (s >> 1)); + s = ((q31_t) ((x >> 17) + (y >> 17))) << 16; + + sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); + + return sum; + + } + + /* + * @brief C custom defined QSUB16 for M3 and M0 processors + */ + __STATIC_INLINE q31_t __QSUB16( + q31_t x, + q31_t y) + { + + q31_t sum; + q31_t r, s; + + r = (short) x; + s = (short) y; + + r = __SSAT(r - s, 16); + s = __SSAT(((q31_t) ((x >> 16) - (y >> 16))), 16) << 16; + + sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); + + return sum; + } + + /* + * @brief C custom defined SHSUB16 for M3 and M0 processors + */ + __STATIC_INLINE q31_t __SHSUB16( + q31_t x, + q31_t y) + { + + q31_t diff; + q31_t r, s; + + r = (short) x; + s = (short) y; + + r = ((r >> 1) - (s >> 1)); + s = (((x >> 17) - (y >> 17)) << 16); + + diff = (s & 0xFFFF0000) | (r & 0x0000FFFF); + + return diff; + } + + /* + * @brief C custom defined QASX for M3 and M0 processors + */ + __STATIC_INLINE q31_t __QASX( + q31_t x, + q31_t y) + { + + q31_t sum = 0; + + sum = + ((sum + + clip_q31_to_q15((q31_t) ((short) (x >> 16) + (short) y))) << 16) + + clip_q31_to_q15((q31_t) ((short) x - (short) (y >> 16))); + + return sum; + } + + /* + * @brief C custom defined SHASX for M3 and M0 processors + */ + __STATIC_INLINE q31_t __SHASX( + q31_t x, + q31_t y) + { + + q31_t sum; + q31_t r, s; + + r = (short) x; + s = (short) y; + + r = ((r >> 1) - (y >> 17)); + s = (((x >> 17) + (s >> 1)) << 16); + + sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); + + return sum; + } + + + /* + * @brief C custom defined QSAX for M3 and M0 processors + */ + __STATIC_INLINE q31_t __QSAX( + q31_t x, + q31_t y) + { + + q31_t sum = 0; + + sum = + ((sum + + clip_q31_to_q15((q31_t) ((short) (x >> 16) - (short) y))) << 16) + + clip_q31_to_q15((q31_t) ((short) x + (short) (y >> 16))); + + return sum; + } + + /* + * @brief C custom defined SHSAX for M3 and M0 processors + */ + __STATIC_INLINE q31_t __SHSAX( + q31_t x, + q31_t y) + { + + q31_t sum; + q31_t r, s; + + r = (short) x; + s = (short) y; + + r = ((r >> 1) + (y >> 17)); + s = (((x >> 17) - (s >> 1)) << 16); + + sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); + + return sum; + } + + /* + * @brief C custom defined SMUSDX for M3 and M0 processors + */ + __STATIC_INLINE q31_t __SMUSDX( + q31_t x, + q31_t y) + { + + return ((q31_t) (((short) x * (short) (y >> 16)) - + ((short) (x >> 16) * (short) y))); + } + + /* + * @brief C custom defined SMUADX for M3 and M0 processors + */ + __STATIC_INLINE q31_t __SMUADX( + q31_t x, + q31_t y) + { + + return ((q31_t) (((short) x * (short) (y >> 16)) + + ((short) (x >> 16) * (short) y))); + } + + /* + * @brief C custom defined QADD for M3 and M0 processors + */ + __STATIC_INLINE q31_t __QADD( + q31_t x, + q31_t y) + { + return clip_q63_to_q31((q63_t) x + y); + } + + /* + * @brief C custom defined QSUB for M3 and M0 processors + */ + __STATIC_INLINE q31_t __QSUB( + q31_t x, + q31_t y) + { + return clip_q63_to_q31((q63_t) x - y); + } + + /* + * @brief C custom defined SMLAD for M3 and M0 processors + */ + __STATIC_INLINE q31_t __SMLAD( + q31_t x, + q31_t y, + q31_t sum) + { + + return (sum + ((short) (x >> 16) * (short) (y >> 16)) + + ((short) x * (short) y)); + } + + /* + * @brief C custom defined SMLADX for M3 and M0 processors + */ + __STATIC_INLINE q31_t __SMLADX( + q31_t x, + q31_t y, + q31_t sum) + { + + return (sum + ((short) (x >> 16) * (short) (y)) + + ((short) x * (short) (y >> 16))); + } + + /* + * @brief C custom defined SMLSDX for M3 and M0 processors + */ + __STATIC_INLINE q31_t __SMLSDX( + q31_t x, + q31_t y, + q31_t sum) + { + + return (sum - ((short) (x >> 16) * (short) (y)) + + ((short) x * (short) (y >> 16))); + } + + /* + * @brief C custom defined SMLALD for M3 and M0 processors + */ + __STATIC_INLINE q63_t __SMLALD( + q31_t x, + q31_t y, + q63_t sum) + { + + return (sum + ((short) (x >> 16) * (short) (y >> 16)) + + ((short) x * (short) y)); + } + + /* + * @brief C custom defined SMLALDX for M3 and M0 processors + */ + __STATIC_INLINE q63_t __SMLALDX( + q31_t x, + q31_t y, + q63_t sum) + { + + return (sum + ((short) (x >> 16) * (short) y)) + + ((short) x * (short) (y >> 16)); + } + + /* + * @brief C custom defined SMUAD for M3 and M0 processors + */ + __STATIC_INLINE q31_t __SMUAD( + q31_t x, + q31_t y) + { + + return (((x >> 16) * (y >> 16)) + + (((x << 16) >> 16) * ((y << 16) >> 16))); + } + + /* + * @brief C custom defined SMUSD for M3 and M0 processors + */ + __STATIC_INLINE q31_t __SMUSD( + q31_t x, + q31_t y) + { + + return (-((x >> 16) * (y >> 16)) + + (((x << 16) >> 16) * ((y << 16) >> 16))); + } + + + /* + * @brief C custom defined SXTB16 for M3 and M0 processors + */ + __STATIC_INLINE q31_t __SXTB16( + q31_t x) + { + + return ((((x << 24) >> 24) & 0x0000FFFF) | + (((x << 8) >> 8) & 0xFFFF0000)); + } + + +#endif /* defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0) */ + + + /** + * @brief Instance structure for the Q7 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q7_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } arm_fir_instance_q7; + + /** + * @brief Instance structure for the Q15 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } arm_fir_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } arm_fir_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } arm_fir_instance_f32; + + + /** + * @brief Processing function for the Q7 FIR filter. + * @param[in] *S points to an instance of the Q7 FIR filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + void arm_fir_q7( + const arm_fir_instance_q7 * S, + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q7 FIR filter. + * @param[in,out] *S points to an instance of the Q7 FIR structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of samples that are processed. + * @return none + */ + void arm_fir_init_q7( + arm_fir_instance_q7 * S, + uint16_t numTaps, + q7_t * pCoeffs, + q7_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 FIR filter. + * @param[in] *S points to an instance of the Q15 FIR structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + void arm_fir_q15( + const arm_fir_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the fast Q15 FIR filter for Cortex-M3 and Cortex-M4. + * @param[in] *S points to an instance of the Q15 FIR filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + void arm_fir_fast_q15( + const arm_fir_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q15 FIR filter. + * @param[in,out] *S points to an instance of the Q15 FIR filter structure. + * @param[in] numTaps Number of filter coefficients in the filter. Must be even and greater than or equal to 4. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + * @return The function returns ARM_MATH_SUCCESS if initialization was successful or ARM_MATH_ARGUMENT_ERROR if + * <code>numTaps</code> is not a supported value. + */ + + arm_status arm_fir_init_q15( + arm_fir_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 FIR filter. + * @param[in] *S points to an instance of the Q31 FIR filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + void arm_fir_q31( + const arm_fir_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the fast Q31 FIR filter for Cortex-M3 and Cortex-M4. + * @param[in] *S points to an instance of the Q31 FIR structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + void arm_fir_fast_q31( + const arm_fir_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q31 FIR filter. + * @param[in,out] *S points to an instance of the Q31 FIR structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + * @return none. + */ + void arm_fir_init_q31( + arm_fir_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + /** + * @brief Processing function for the floating-point FIR filter. + * @param[in] *S points to an instance of the floating-point FIR structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + void arm_fir_f32( + const arm_fir_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the floating-point FIR filter. + * @param[in,out] *S points to an instance of the floating-point FIR filter structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + * @return none. + */ + void arm_fir_init_f32( + arm_fir_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 Biquad cascade filter. + */ + typedef struct + { + int8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q15_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + q15_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + int8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + + } arm_biquad_casd_df1_inst_q15; + + + /** + * @brief Instance structure for the Q31 Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q31_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + q31_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + + } arm_biquad_casd_df1_inst_q31; + + /** + * @brief Instance structure for the floating-point Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + float32_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + + + } arm_biquad_casd_df1_inst_f32; + + + + /** + * @brief Processing function for the Q15 Biquad cascade filter. + * @param[in] *S points to an instance of the Q15 Biquad cascade structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_biquad_cascade_df1_q15( + const arm_biquad_casd_df1_inst_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q15 Biquad cascade filter. + * @param[in,out] *S points to an instance of the Q15 Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format + * @return none + */ + + void arm_biquad_cascade_df1_init_q15( + arm_biquad_casd_df1_inst_q15 * S, + uint8_t numStages, + q15_t * pCoeffs, + q15_t * pState, + int8_t postShift); + + + /** + * @brief Fast but less precise processing function for the Q15 Biquad cascade filter for Cortex-M3 and Cortex-M4. + * @param[in] *S points to an instance of the Q15 Biquad cascade structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_biquad_cascade_df1_fast_q15( + const arm_biquad_casd_df1_inst_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 Biquad cascade filter + * @param[in] *S points to an instance of the Q31 Biquad cascade structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_biquad_cascade_df1_q31( + const arm_biquad_casd_df1_inst_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Fast but less precise processing function for the Q31 Biquad cascade filter for Cortex-M3 and Cortex-M4. + * @param[in] *S points to an instance of the Q31 Biquad cascade structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_biquad_cascade_df1_fast_q31( + const arm_biquad_casd_df1_inst_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q31 Biquad cascade filter. + * @param[in,out] *S points to an instance of the Q31 Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format + * @return none + */ + + void arm_biquad_cascade_df1_init_q31( + arm_biquad_casd_df1_inst_q31 * S, + uint8_t numStages, + q31_t * pCoeffs, + q31_t * pState, + int8_t postShift); + + /** + * @brief Processing function for the floating-point Biquad cascade filter. + * @param[in] *S points to an instance of the floating-point Biquad cascade structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_biquad_cascade_df1_f32( + const arm_biquad_casd_df1_inst_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the floating-point Biquad cascade filter. + * @param[in,out] *S points to an instance of the floating-point Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @return none + */ + + void arm_biquad_cascade_df1_init_f32( + arm_biquad_casd_df1_inst_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Instance structure for the floating-point matrix structure. + */ + + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + float32_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_f32; + + /** + * @brief Instance structure for the Q15 matrix structure. + */ + + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q15_t *pData; /**< points to the data of the matrix. */ + + } arm_matrix_instance_q15; + + /** + * @brief Instance structure for the Q31 matrix structure. + */ + + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q31_t *pData; /**< points to the data of the matrix. */ + + } arm_matrix_instance_q31; + + + + /** + * @brief Floating-point matrix addition. + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking. + */ + + arm_status arm_mat_add_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix addition. + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking. + */ + + arm_status arm_mat_add_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst); + + /** + * @brief Q31 matrix addition. + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking. + */ + + arm_status arm_mat_add_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix transpose. + * @param[in] *pSrc points to the input matrix + * @param[out] *pDst points to the output matrix + * @return The function returns either <code>ARM_MATH_SIZE_MISMATCH</code> + * or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking. + */ + + arm_status arm_mat_trans_f32( + const arm_matrix_instance_f32 * pSrc, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix transpose. + * @param[in] *pSrc points to the input matrix + * @param[out] *pDst points to the output matrix + * @return The function returns either <code>ARM_MATH_SIZE_MISMATCH</code> + * or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking. + */ + + arm_status arm_mat_trans_q15( + const arm_matrix_instance_q15 * pSrc, + arm_matrix_instance_q15 * pDst); + + /** + * @brief Q31 matrix transpose. + * @param[in] *pSrc points to the input matrix + * @param[out] *pDst points to the output matrix + * @return The function returns either <code>ARM_MATH_SIZE_MISMATCH</code> + * or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking. + */ + + arm_status arm_mat_trans_q31( + const arm_matrix_instance_q31 * pSrc, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix multiplication + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking. + */ + + arm_status arm_mat_mult_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix multiplication + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking. + */ + + arm_status arm_mat_mult_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pState); + + /** + * @brief Q15 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @param[in] *pState points to the array for storing intermediate results + * @return The function returns either + * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking. + */ + + arm_status arm_mat_mult_fast_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pState); + + /** + * @brief Q31 matrix multiplication + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking. + */ + + arm_status arm_mat_mult_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Q31 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking. + */ + + arm_status arm_mat_mult_fast_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix subtraction + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking. + */ + + arm_status arm_mat_sub_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix subtraction + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking. + */ + + arm_status arm_mat_sub_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst); + + /** + * @brief Q31 matrix subtraction + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking. + */ + + arm_status arm_mat_sub_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Floating-point matrix scaling. + * @param[in] *pSrc points to the input matrix + * @param[in] scale scale factor + * @param[out] *pDst points to the output matrix + * @return The function returns either + * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking. + */ + + arm_status arm_mat_scale_f32( + const arm_matrix_instance_f32 * pSrc, + float32_t scale, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix scaling. + * @param[in] *pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] *pDst points to output matrix + * @return The function returns either + * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking. + */ + + arm_status arm_mat_scale_q15( + const arm_matrix_instance_q15 * pSrc, + q15_t scaleFract, + int32_t shift, + arm_matrix_instance_q15 * pDst); + + /** + * @brief Q31 matrix scaling. + * @param[in] *pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * <code>ARM_MATH_SIZE_MISMATCH</code> or <code>ARM_MATH_SUCCESS</code> based on the outcome of size checking. + */ + + arm_status arm_mat_scale_q31( + const arm_matrix_instance_q31 * pSrc, + q31_t scaleFract, + int32_t shift, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Q31 matrix initialization. + * @param[in,out] *S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] *pData points to the matrix data array. + * @return none + */ + + void arm_mat_init_q31( + arm_matrix_instance_q31 * S, + uint16_t nRows, + uint16_t nColumns, + q31_t * pData); + + /** + * @brief Q15 matrix initialization. + * @param[in,out] *S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] *pData points to the matrix data array. + * @return none + */ + + void arm_mat_init_q15( + arm_matrix_instance_q15 * S, + uint16_t nRows, + uint16_t nColumns, + q15_t * pData); + + /** + * @brief Floating-point matrix initialization. + * @param[in,out] *S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] *pData points to the matrix data array. + * @return none + */ + + void arm_mat_init_f32( + arm_matrix_instance_f32 * S, + uint16_t nRows, + uint16_t nColumns, + float32_t * pData); + + + + /** + * @brief Instance structure for the Q15 PID Control. + */ + typedef struct + { + q15_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ +#ifdef ARM_MATH_CM0 + q15_t A1; + q15_t A2; +#else + q31_t A1; /**< The derived gain A1 = -Kp - 2Kd | Kd.*/ +#endif + q15_t state[3]; /**< The state array of length 3. */ + q15_t Kp; /**< The proportional gain. */ + q15_t Ki; /**< The integral gain. */ + q15_t Kd; /**< The derivative gain. */ + } arm_pid_instance_q15; + + /** + * @brief Instance structure for the Q31 PID Control. + */ + typedef struct + { + q31_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + q31_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + q31_t A2; /**< The derived gain, A2 = Kd . */ + q31_t state[3]; /**< The state array of length 3. */ + q31_t Kp; /**< The proportional gain. */ + q31_t Ki; /**< The integral gain. */ + q31_t Kd; /**< The derivative gain. */ + + } arm_pid_instance_q31; + + /** + * @brief Instance structure for the floating-point PID Control. + */ + typedef struct + { + float32_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + float32_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + float32_t A2; /**< The derived gain, A2 = Kd . */ + float32_t state[3]; /**< The state array of length 3. */ + float32_t Kp; /**< The proportional gain. */ + float32_t Ki; /**< The integral gain. */ + float32_t Kd; /**< The derivative gain. */ + } arm_pid_instance_f32; + + + + /** + * @brief Initialization function for the floating-point PID Control. + * @param[in,out] *S points to an instance of the PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + * @return none. + */ + void arm_pid_init_f32( + arm_pid_instance_f32 * S, + int32_t resetStateFlag); + + /** + * @brief Reset function for the floating-point PID Control. + * @param[in,out] *S is an instance of the floating-point PID Control structure + * @return none + */ + void arm_pid_reset_f32( + arm_pid_instance_f32 * S); + + + /** + * @brief Initialization function for the Q31 PID Control. + * @param[in,out] *S points to an instance of the Q15 PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + * @return none. + */ + void arm_pid_init_q31( + arm_pid_instance_q31 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the Q31 PID Control. + * @param[in,out] *S points to an instance of the Q31 PID Control structure + * @return none + */ + + void arm_pid_reset_q31( + arm_pid_instance_q31 * S); + + /** + * @brief Initialization function for the Q15 PID Control. + * @param[in,out] *S points to an instance of the Q15 PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + * @return none. + */ + void arm_pid_init_q15( + arm_pid_instance_q15 * S, + int32_t resetStateFlag); + + /** + * @brief Reset function for the Q15 PID Control. + * @param[in,out] *S points to an instance of the q15 PID Control structure + * @return none + */ + void arm_pid_reset_q15( + arm_pid_instance_q15 * S); + + + /** + * @brief Instance structure for the floating-point Linear Interpolate function. + */ + typedef struct + { + uint32_t nValues; /**< nValues */ + float32_t x1; /**< x1 */ + float32_t xSpacing; /**< xSpacing */ + float32_t *pYData; /**< pointer to the table of Y values */ + } arm_linear_interp_instance_f32; + + /** + * @brief Instance structure for the floating-point bilinear interpolation function. + */ + + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + float32_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_f32; + + /** + * @brief Instance structure for the Q31 bilinear interpolation function. + */ + + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q31_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q31; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q15_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q15; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q7_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q7; + + + /** + * @brief Q7 vector multiplication. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_mult_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Q15 vector multiplication. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_mult_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Q31 vector multiplication. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_mult_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Floating-point vector multiplication. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_mult_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q15_t *pTwiddle; /**< points to the twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix4_instance_q15; + + /** + * @brief Instance structure for the Q31 CFFT/CIFFT function. + */ + + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q31_t *pTwiddle; /**< points to the twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix4_instance_q31; + + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + float32_t *pTwiddle; /**< points to the twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } arm_cfft_radix4_instance_f32; + + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q15_t *pTwiddle; /**< points to the Sin twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix2_instance_q15; + + /** + * @brief Instance structure for the Radix-2 Q31 CFFT/CIFFT function. + */ + + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q31_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix2_instance_q31; + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + float32_t *pTwiddle; /**< points to the Twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } arm_cfft_radix2_instance_f32; + + + /** + * @brief Processing function for the Q15 CFFT/CIFFT. + * @param[in] *S points to an instance of the Q15 CFFT/CIFFT structure. + * @param[in, out] *pSrc points to the complex data buffer. Processing occurs in-place. + * @return none. + */ + + void arm_cfft_radix4_q15( + const arm_cfft_radix4_instance_q15 * S, + q15_t * pSrc); + + /** + * @brief Processing function for the Q15 CFFT/CIFFT. + * @param[in] *S points to an instance of the Q15 CFFT/CIFFT structure. + * @param[in, out] *pSrc points to the complex data buffer. Processing occurs in-place. + * @return none. + */ + + void arm_cfft_radix2_q15( + const arm_cfft_radix2_instance_q15 * S, + q15_t * pSrc); + + /** + * @brief Initialization function for the Q15 CFFT/CIFFT. + * @param[in,out] *S points to an instance of the Q15 CFFT/CIFFT structure. + * @param[in] fftLen length of the FFT. + * @param[in] ifftFlag flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. + * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if <code>fftLen</code> is not a supported value. + */ + + arm_status arm_cfft_radix4_init_q15( + arm_cfft_radix4_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Initialization function for the Q15 CFFT/CIFFT. + * @param[in,out] *S points to an instance of the Q15 CFFT/CIFFT structure. + * @param[in] fftLen length of the FFT. + * @param[in] ifftFlag flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. + * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if <code>fftLen</code> is not a supported value. + */ + + arm_status arm_cfft_radix2_init_q15( + arm_cfft_radix2_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Processing function for the Q31 CFFT/CIFFT. + * @param[in] *S points to an instance of the Q31 CFFT/CIFFT structure. + * @param[in, out] *pSrc points to the complex data buffer. Processing occurs in-place. + * @return none. + */ + + void arm_cfft_radix4_q31( + const arm_cfft_radix4_instance_q31 * S, + q31_t * pSrc); + + /** + * @brief Initialization function for the Q31 CFFT/CIFFT. + * @param[in,out] *S points to an instance of the Q31 CFFT/CIFFT structure. + * @param[in] fftLen length of the FFT. + * @param[in] ifftFlag flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. + * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if <code>fftLen</code> is not a supported value. + */ + + arm_status arm_cfft_radix4_init_q31( + arm_cfft_radix4_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Processing function for the Radix-2 Q31 CFFT/CIFFT. + * @param[in] *S points to an instance of the Radix-2 Q31 CFFT/CIFFT structure. + * @param[in, out] *pSrc points to the complex data buffer. Processing occurs in-place. + * @return none. + */ + + void arm_cfft_radix2_q31( + const arm_cfft_radix2_instance_q31 * S, + q31_t * pSrc); + + /** + * @brief Initialization function for the Radix-2 Q31 CFFT/CIFFT. + * @param[in,out] *S points to an instance of the Radix-2 Q31 CFFT/CIFFT structure. + * @param[in] fftLen length of the FFT. + * @param[in] ifftFlag flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. + * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if <code>fftLen</code> is not a supported value. + */ + + arm_status arm_cfft_radix2_init_q31( + arm_cfft_radix2_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + + + /** + * @brief Processing function for the floating-point CFFT/CIFFT. + * @param[in] *S points to an instance of the floating-point CFFT/CIFFT structure. + * @param[in, out] *pSrc points to the complex data buffer. Processing occurs in-place. + * @return none. + */ + + void arm_cfft_radix2_f32( + const arm_cfft_radix2_instance_f32 * S, + float32_t * pSrc); + + /** + * @brief Initialization function for the floating-point CFFT/CIFFT. + * @param[in,out] *S points to an instance of the floating-point CFFT/CIFFT structure. + * @param[in] fftLen length of the FFT. + * @param[in] ifftFlag flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. + * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if <code>fftLen</code> is not a supported value. + */ + + arm_status arm_cfft_radix2_init_f32( + arm_cfft_radix2_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Processing function for the floating-point CFFT/CIFFT. + * @param[in] *S points to an instance of the floating-point CFFT/CIFFT structure. + * @param[in, out] *pSrc points to the complex data buffer. Processing occurs in-place. + * @return none. + */ + + void arm_cfft_radix4_f32( + const arm_cfft_radix4_instance_f32 * S, + float32_t * pSrc); + + /** + * @brief Initialization function for the floating-point CFFT/CIFFT. + * @param[in,out] *S points to an instance of the floating-point CFFT/CIFFT structure. + * @param[in] fftLen length of the FFT. + * @param[in] ifftFlag flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. + * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if <code>fftLen</code> is not a supported value. + */ + + arm_status arm_cfft_radix4_init_f32( + arm_cfft_radix4_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + + + /*---------------------------------------------------------------------- + * Internal functions prototypes FFT function + ----------------------------------------------------------------------*/ + + /** + * @brief Core function for the floating-point CFFT butterfly process. + * @param[in, out] *pSrc points to the in-place buffer of floating-point data type. + * @param[in] fftLen length of the FFT. + * @param[in] *pCoef points to the twiddle coefficient buffer. + * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + * @return none. + */ + + void arm_radix4_butterfly_f32( + float32_t * pSrc, + uint16_t fftLen, + float32_t * pCoef, + uint16_t twidCoefModifier); + + /** + * @brief Core function for the floating-point CIFFT butterfly process. + * @param[in, out] *pSrc points to the in-place buffer of floating-point data type. + * @param[in] fftLen length of the FFT. + * @param[in] *pCoef points to twiddle coefficient buffer. + * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + * @param[in] onebyfftLen value of 1/fftLen. + * @return none. + */ + + void arm_radix4_butterfly_inverse_f32( + float32_t * pSrc, + uint16_t fftLen, + float32_t * pCoef, + uint16_t twidCoefModifier, + float32_t onebyfftLen); + + /** + * @brief In-place bit reversal function. + * @param[in, out] *pSrc points to the in-place buffer of floating-point data type. + * @param[in] fftSize length of the FFT. + * @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table. + * @param[in] *pBitRevTab points to the bit reversal table. + * @return none. + */ + + void arm_bitreversal_f32( + float32_t * pSrc, + uint16_t fftSize, + uint16_t bitRevFactor, + uint16_t * pBitRevTab); + + /** + * @brief Core function for the Q31 CFFT butterfly process. + * @param[in, out] *pSrc points to the in-place buffer of Q31 data type. + * @param[in] fftLen length of the FFT. + * @param[in] *pCoef points to Twiddle coefficient buffer. + * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + * @return none. + */ + + void arm_radix4_butterfly_q31( + q31_t * pSrc, + uint32_t fftLen, + q31_t * pCoef, + uint32_t twidCoefModifier); + + /** + * @brief Core function for the f32 FFT butterfly process. + * @param[in, out] *pSrc points to the in-place buffer of f32 data type. + * @param[in] fftLen length of the FFT. + * @param[in] *pCoef points to Twiddle coefficient buffer. + * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + * @return none. + */ + + void arm_radix2_butterfly_f32( + float32_t * pSrc, + uint32_t fftLen, + float32_t * pCoef, + uint16_t twidCoefModifier); + + /** + * @brief Core function for the Radix-2 Q31 CFFT butterfly process. + * @param[in, out] *pSrc points to the in-place buffer of Q31 data type. + * @param[in] fftLen length of the FFT. + * @param[in] *pCoef points to Twiddle coefficient buffer. + * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + * @return none. + */ + + void arm_radix2_butterfly_q31( + q31_t * pSrc, + uint32_t fftLen, + q31_t * pCoef, + uint16_t twidCoefModifier); + + /** + * @brief Core function for the Radix-2 Q15 CFFT butterfly process. + * @param[in, out] *pSrc points to the in-place buffer of Q15 data type. + * @param[in] fftLen length of the FFT. + * @param[in] *pCoef points to Twiddle coefficient buffer. + * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + * @return none. + */ + + void arm_radix2_butterfly_q15( + q15_t * pSrc, + uint32_t fftLen, + q15_t * pCoef, + uint16_t twidCoefModifier); + + /** + * @brief Core function for the Radix-2 Q15 CFFT Inverse butterfly process. + * @param[in, out] *pSrc points to the in-place buffer of Q15 data type. + * @param[in] fftLen length of the FFT. + * @param[in] *pCoef points to Twiddle coefficient buffer. + * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + * @return none. + */ + + void arm_radix2_butterfly_inverse_q15( + q15_t * pSrc, + uint32_t fftLen, + q15_t * pCoef, + uint16_t twidCoefModifier); + + /** + * @brief Core function for the Radix-2 Q31 CFFT Inverse butterfly process. + * @param[in, out] *pSrc points to the in-place buffer of Q31 data type. + * @param[in] fftLen length of the FFT. + * @param[in] *pCoef points to Twiddle coefficient buffer. + * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + * @return none. + */ + + void arm_radix2_butterfly_inverse_q31( + q31_t * pSrc, + uint32_t fftLen, + q31_t * pCoef, + uint16_t twidCoefModifier); + + /** + * @brief Core function for the f32 IFFT butterfly process. + * @param[in, out] *pSrc points to the in-place buffer of f32 data type. + * @param[in] fftLen length of the FFT. + * @param[in] *pCoef points to Twiddle coefficient buffer. + * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + * @param[in] onebyfftLen 1/fftLenfth + * @return none. + */ + + void arm_radix2_butterfly_inverse_f32( + float32_t * pSrc, + uint32_t fftLen, + float32_t * pCoef, + uint16_t twidCoefModifier, + float32_t onebyfftLen); + + /** + * @brief Core function for the Q31 CIFFT butterfly process. + * @param[in, out] *pSrc points to the in-place buffer of Q31 data type. + * @param[in] fftLen length of the FFT. + * @param[in] *pCoef points to twiddle coefficient buffer. + * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + * @return none. + */ + + void arm_radix4_butterfly_inverse_q31( + q31_t * pSrc, + uint32_t fftLen, + q31_t * pCoef, + uint32_t twidCoefModifier); + + /** + * @brief In-place bit reversal function. + * @param[in, out] *pSrc points to the in-place buffer of Q31 data type. + * @param[in] fftLen length of the FFT. + * @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table + * @param[in] *pBitRevTab points to bit reversal table. + * @return none. + */ + + void arm_bitreversal_q31( + q31_t * pSrc, + uint32_t fftLen, + uint16_t bitRevFactor, + uint16_t * pBitRevTab); + + /** + * @brief Core function for the Q15 CFFT butterfly process. + * @param[in, out] *pSrc16 points to the in-place buffer of Q15 data type. + * @param[in] fftLen length of the FFT. + * @param[in] *pCoef16 points to twiddle coefficient buffer. + * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + * @return none. + */ + + void arm_radix4_butterfly_q15( + q15_t * pSrc16, + uint32_t fftLen, + q15_t * pCoef16, + uint32_t twidCoefModifier); + + + /** + * @brief Core function for the Q15 CIFFT butterfly process. + * @param[in, out] *pSrc16 points to the in-place buffer of Q15 data type. + * @param[in] fftLen length of the FFT. + * @param[in] *pCoef16 points to twiddle coefficient buffer. + * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + * @return none. + */ + + void arm_radix4_butterfly_inverse_q15( + q15_t * pSrc16, + uint32_t fftLen, + q15_t * pCoef16, + uint32_t twidCoefModifier); + + /** + * @brief In-place bit reversal function. + * @param[in, out] *pSrc points to the in-place buffer of Q15 data type. + * @param[in] fftLen length of the FFT. + * @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table + * @param[in] *pBitRevTab points to bit reversal table. + * @return none. + */ + + void arm_bitreversal_q15( + q15_t * pSrc, + uint32_t fftLen, + uint16_t bitRevFactor, + uint16_t * pBitRevTab); + + + /** + * @brief Instance structure for the Q15 RFFT/RIFFT function. + */ + + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint32_t fftLenBy2; /**< length of the complex FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + q15_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + q15_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_q15; + + /** + * @brief Instance structure for the Q31 RFFT/RIFFT function. + */ + + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint32_t fftLenBy2; /**< length of the complex FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + q31_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + q31_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_q31; + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ + + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint16_t fftLenBy2; /**< length of the complex FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + float32_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + float32_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_f32; + + /** + * @brief Processing function for the Q15 RFFT/RIFFT. + * @param[in] *S points to an instance of the Q15 RFFT/RIFFT structure. + * @param[in] *pSrc points to the input buffer. + * @param[out] *pDst points to the output buffer. + * @return none. + */ + + void arm_rfft_q15( + const arm_rfft_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst); + + /** + * @brief Initialization function for the Q15 RFFT/RIFFT. + * @param[in, out] *S points to an instance of the Q15 RFFT/RIFFT structure. + * @param[in] *S_CFFT points to an instance of the Q15 CFFT/CIFFT structure. + * @param[in] fftLenReal length of the FFT. + * @param[in] ifftFlagR flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. + * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if <code>fftLenReal</code> is not a supported value. + */ + + arm_status arm_rfft_init_q15( + arm_rfft_instance_q15 * S, + arm_cfft_radix4_instance_q15 * S_CFFT, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + /** + * @brief Processing function for the Q31 RFFT/RIFFT. + * @param[in] *S points to an instance of the Q31 RFFT/RIFFT structure. + * @param[in] *pSrc points to the input buffer. + * @param[out] *pDst points to the output buffer. + * @return none. + */ + + void arm_rfft_q31( + const arm_rfft_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst); + + /** + * @brief Initialization function for the Q31 RFFT/RIFFT. + * @param[in, out] *S points to an instance of the Q31 RFFT/RIFFT structure. + * @param[in, out] *S_CFFT points to an instance of the Q31 CFFT/CIFFT structure. + * @param[in] fftLenReal length of the FFT. + * @param[in] ifftFlagR flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. + * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if <code>fftLenReal</code> is not a supported value. + */ + + arm_status arm_rfft_init_q31( + arm_rfft_instance_q31 * S, + arm_cfft_radix4_instance_q31 * S_CFFT, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + /** + * @brief Initialization function for the floating-point RFFT/RIFFT. + * @param[in,out] *S points to an instance of the floating-point RFFT/RIFFT structure. + * @param[in,out] *S_CFFT points to an instance of the floating-point CFFT/CIFFT structure. + * @param[in] fftLenReal length of the FFT. + * @param[in] ifftFlagR flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. + * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if <code>fftLenReal</code> is not a supported value. + */ + + arm_status arm_rfft_init_f32( + arm_rfft_instance_f32 * S, + arm_cfft_radix4_instance_f32 * S_CFFT, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + /** + * @brief Processing function for the floating-point RFFT/RIFFT. + * @param[in] *S points to an instance of the floating-point RFFT/RIFFT structure. + * @param[in] *pSrc points to the input buffer. + * @param[out] *pDst points to the output buffer. + * @return none. + */ + + void arm_rfft_f32( + const arm_rfft_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst); + + /** + * @brief Instance structure for the floating-point DCT4/IDCT4 function. + */ + + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + float32_t normalize; /**< normalizing factor. */ + float32_t *pTwiddle; /**< points to the twiddle factor table. */ + float32_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_f32 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_f32; + + /** + * @brief Initialization function for the floating-point DCT4/IDCT4. + * @param[in,out] *S points to an instance of floating-point DCT4/IDCT4 structure. + * @param[in] *S_RFFT points to an instance of floating-point RFFT/RIFFT structure. + * @param[in] *S_CFFT points to an instance of floating-point CFFT/CIFFT structure. + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if <code>fftLenReal</code> is not a supported transform length. + */ + + arm_status arm_dct4_init_f32( + arm_dct4_instance_f32 * S, + arm_rfft_instance_f32 * S_RFFT, + arm_cfft_radix4_instance_f32 * S_CFFT, + uint16_t N, + uint16_t Nby2, + float32_t normalize); + + /** + * @brief Processing function for the floating-point DCT4/IDCT4. + * @param[in] *S points to an instance of the floating-point DCT4/IDCT4 structure. + * @param[in] *pState points to state buffer. + * @param[in,out] *pInlineBuffer points to the in-place input and output buffer. + * @return none. + */ + + void arm_dct4_f32( + const arm_dct4_instance_f32 * S, + float32_t * pState, + float32_t * pInlineBuffer); + + /** + * @brief Instance structure for the Q31 DCT4/IDCT4 function. + */ + + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q31_t normalize; /**< normalizing factor. */ + q31_t *pTwiddle; /**< points to the twiddle factor table. */ + q31_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_q31 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_q31; + + /** + * @brief Initialization function for the Q31 DCT4/IDCT4. + * @param[in,out] *S points to an instance of Q31 DCT4/IDCT4 structure. + * @param[in] *S_RFFT points to an instance of Q31 RFFT/RIFFT structure + * @param[in] *S_CFFT points to an instance of Q31 CFFT/CIFFT structure + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if <code>N</code> is not a supported transform length. + */ + + arm_status arm_dct4_init_q31( + arm_dct4_instance_q31 * S, + arm_rfft_instance_q31 * S_RFFT, + arm_cfft_radix4_instance_q31 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q31_t normalize); + + /** + * @brief Processing function for the Q31 DCT4/IDCT4. + * @param[in] *S points to an instance of the Q31 DCT4 structure. + * @param[in] *pState points to state buffer. + * @param[in,out] *pInlineBuffer points to the in-place input and output buffer. + * @return none. + */ + + void arm_dct4_q31( + const arm_dct4_instance_q31 * S, + q31_t * pState, + q31_t * pInlineBuffer); + + /** + * @brief Instance structure for the Q15 DCT4/IDCT4 function. + */ + + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q15_t normalize; /**< normalizing factor. */ + q15_t *pTwiddle; /**< points to the twiddle factor table. */ + q15_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_q15 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_q15; + + /** + * @brief Initialization function for the Q15 DCT4/IDCT4. + * @param[in,out] *S points to an instance of Q15 DCT4/IDCT4 structure. + * @param[in] *S_RFFT points to an instance of Q15 RFFT/RIFFT structure. + * @param[in] *S_CFFT points to an instance of Q15 CFFT/CIFFT structure. + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if <code>N</code> is not a supported transform length. + */ + + arm_status arm_dct4_init_q15( + arm_dct4_instance_q15 * S, + arm_rfft_instance_q15 * S_RFFT, + arm_cfft_radix4_instance_q15 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q15_t normalize); + + /** + * @brief Processing function for the Q15 DCT4/IDCT4. + * @param[in] *S points to an instance of the Q15 DCT4 structure. + * @param[in] *pState points to state buffer. + * @param[in,out] *pInlineBuffer points to the in-place input and output buffer. + * @return none. + */ + + void arm_dct4_q15( + const arm_dct4_instance_q15 * S, + q15_t * pState, + q15_t * pInlineBuffer); + + /** + * @brief Floating-point vector addition. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_add_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Q7 vector addition. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_add_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Q15 vector addition. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_add_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Q31 vector addition. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_add_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Floating-point vector subtraction. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_sub_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Q7 vector subtraction. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_sub_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Q15 vector subtraction. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_sub_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Q31 vector subtraction. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_sub_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Multiplies a floating-point vector by a scalar. + * @param[in] *pSrc points to the input vector + * @param[in] scale scale factor to be applied + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_scale_f32( + float32_t * pSrc, + float32_t scale, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Multiplies a Q7 vector by a scalar. + * @param[in] *pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_scale_q7( + q7_t * pSrc, + q7_t scaleFract, + int8_t shift, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Multiplies a Q15 vector by a scalar. + * @param[in] *pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_scale_q15( + q15_t * pSrc, + q15_t scaleFract, + int8_t shift, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Multiplies a Q31 vector by a scalar. + * @param[in] *pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_scale_q31( + q31_t * pSrc, + q31_t scaleFract, + int8_t shift, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Q7 vector absolute value. + * @param[in] *pSrc points to the input buffer + * @param[out] *pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_abs_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Floating-point vector absolute value. + * @param[in] *pSrc points to the input buffer + * @param[out] *pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_abs_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Q15 vector absolute value. + * @param[in] *pSrc points to the input buffer + * @param[out] *pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_abs_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Q31 vector absolute value. + * @param[in] *pSrc points to the input buffer + * @param[out] *pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_abs_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Dot product of floating-point vectors. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] *result output result returned here + * @return none. + */ + + void arm_dot_prod_f32( + float32_t * pSrcA, + float32_t * pSrcB, + uint32_t blockSize, + float32_t * result); + + /** + * @brief Dot product of Q7 vectors. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] *result output result returned here + * @return none. + */ + + void arm_dot_prod_q7( + q7_t * pSrcA, + q7_t * pSrcB, + uint32_t blockSize, + q31_t * result); + + /** + * @brief Dot product of Q15 vectors. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] *result output result returned here + * @return none. + */ + + void arm_dot_prod_q15( + q15_t * pSrcA, + q15_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + /** + * @brief Dot product of Q31 vectors. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] *result output result returned here + * @return none. + */ + + void arm_dot_prod_q31( + q31_t * pSrcA, + q31_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + /** + * @brief Shifts the elements of a Q7 vector a specified number of bits. + * @param[in] *pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_shift_q7( + q7_t * pSrc, + int8_t shiftBits, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Shifts the elements of a Q15 vector a specified number of bits. + * @param[in] *pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_shift_q15( + q15_t * pSrc, + int8_t shiftBits, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Shifts the elements of a Q31 vector a specified number of bits. + * @param[in] *pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_shift_q31( + q31_t * pSrc, + int8_t shiftBits, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Adds a constant offset to a floating-point vector. + * @param[in] *pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_offset_f32( + float32_t * pSrc, + float32_t offset, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Adds a constant offset to a Q7 vector. + * @param[in] *pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_offset_q7( + q7_t * pSrc, + q7_t offset, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Adds a constant offset to a Q15 vector. + * @param[in] *pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_offset_q15( + q15_t * pSrc, + q15_t offset, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Adds a constant offset to a Q31 vector. + * @param[in] *pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_offset_q31( + q31_t * pSrc, + q31_t offset, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Negates the elements of a floating-point vector. + * @param[in] *pSrc points to the input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_negate_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Negates the elements of a Q7 vector. + * @param[in] *pSrc points to the input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_negate_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Negates the elements of a Q15 vector. + * @param[in] *pSrc points to the input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_negate_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Negates the elements of a Q31 vector. + * @param[in] *pSrc points to the input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_negate_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + /** + * @brief Copies the elements of a floating-point vector. + * @param[in] *pSrc input pointer + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_copy_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Copies the elements of a Q7 vector. + * @param[in] *pSrc input pointer + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_copy_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Copies the elements of a Q15 vector. + * @param[in] *pSrc input pointer + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_copy_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Copies the elements of a Q31 vector. + * @param[in] *pSrc input pointer + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_copy_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + /** + * @brief Fills a constant value into a floating-point vector. + * @param[in] value input value to be filled + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_fill_f32( + float32_t value, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Fills a constant value into a Q7 vector. + * @param[in] value input value to be filled + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_fill_q7( + q7_t value, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Fills a constant value into a Q15 vector. + * @param[in] value input value to be filled + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_fill_q15( + q15_t value, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Fills a constant value into a Q31 vector. + * @param[in] value input value to be filled + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_fill_q31( + q31_t value, + q31_t * pDst, + uint32_t blockSize); + +/** + * @brief Convolution of floating-point sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the location where the output result is written. Length srcALen+srcBLen-1. + * @return none. + */ + + void arm_conv_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + + /** + * @brief Convolution of Q15 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] *pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] *pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return none. + */ + + + void arm_conv_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Convolution of Q15 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the location where the output result is written. Length srcALen+srcBLen-1. + * @return none. + */ + + void arm_conv_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + /** + * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. + * @return none. + */ + + void arm_conv_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + /** + * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] *pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] *pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return none. + */ + + void arm_conv_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + + /** + * @brief Convolution of Q31 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. + * @return none. + */ + + void arm_conv_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + /** + * @brief Convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. + * @return none. + */ + + void arm_conv_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + /** + * @brief Convolution of Q7 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. + * @param[in] *pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] *pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + * @return none. + */ + + void arm_conv_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + + /** + * @brief Convolution of Q7 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. + * @return none. + */ + + void arm_conv_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + + /** + * @brief Partial convolution of floating-point sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + + arm_status arm_conv_partial_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + /** + * @brief Partial convolution of Q15 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] * pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] * pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + + arm_status arm_conv_partial_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Partial convolution of Q15 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + + arm_status arm_conv_partial_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + /** + * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + + arm_status arm_conv_partial_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] * pScratch1 points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] * pScratch2 points to scratch buffer of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + + arm_status arm_conv_partial_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Partial convolution of Q31 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + + arm_status arm_conv_partial_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + + arm_status arm_conv_partial_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q7 sequences + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @param[in] *pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] *pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + + arm_status arm_conv_partial_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints, + q15_t * pScratch1, + q15_t * pScratch2); + + +/** + * @brief Partial convolution of Q7 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + + arm_status arm_conv_partial_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + + /** + * @brief Instance structure for the Q15 FIR decimator. + */ + + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR decimator. + */ + + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + + } arm_fir_decimate_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR decimator. + */ + + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + + } arm_fir_decimate_instance_f32; + + + + /** + * @brief Processing function for the floating-point FIR decimator. + * @param[in] *S points to an instance of the floating-point FIR decimator structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + * @return none + */ + + void arm_fir_decimate_f32( + const arm_fir_decimate_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point FIR decimator. + * @param[in,out] *S points to an instance of the floating-point FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * <code>blockSize</code> is not a multiple of <code>M</code>. + */ + + arm_status arm_fir_decimate_init_f32( + arm_fir_decimate_instance_f32 * S, + uint16_t numTaps, + uint8_t M, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + /** + * @brief Processing function for the Q15 FIR decimator. + * @param[in] *S points to an instance of the Q15 FIR decimator structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + * @return none + */ + + void arm_fir_decimate_q15( + const arm_fir_decimate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the Q15 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. + * @param[in] *S points to an instance of the Q15 FIR decimator structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + * @return none + */ + + void arm_fir_decimate_fast_q15( + const arm_fir_decimate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + + /** + * @brief Initialization function for the Q15 FIR decimator. + * @param[in,out] *S points to an instance of the Q15 FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * <code>blockSize</code> is not a multiple of <code>M</code>. + */ + + arm_status arm_fir_decimate_init_q15( + arm_fir_decimate_instance_q15 * S, + uint16_t numTaps, + uint8_t M, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 FIR decimator. + * @param[in] *S points to an instance of the Q31 FIR decimator structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + * @return none + */ + + void arm_fir_decimate_q31( + const arm_fir_decimate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. + * @param[in] *S points to an instance of the Q31 FIR decimator structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + * @return none + */ + + void arm_fir_decimate_fast_q31( + arm_fir_decimate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR decimator. + * @param[in,out] *S points to an instance of the Q31 FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * <code>blockSize</code> is not a multiple of <code>M</code>. + */ + + arm_status arm_fir_decimate_init_q31( + arm_fir_decimate_instance_q31 * S, + uint16_t numTaps, + uint8_t M, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + + /** + * @brief Instance structure for the Q15 FIR interpolator. + */ + + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q15_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + } arm_fir_interpolate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR interpolator. + */ + + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q31_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + } arm_fir_interpolate_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR interpolator. + */ + + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + float32_t *pState; /**< points to the state variable array. The array is of length phaseLength+numTaps-1. */ + } arm_fir_interpolate_instance_f32; + + + /** + * @brief Processing function for the Q15 FIR interpolator. + * @param[in] *S points to an instance of the Q15 FIR interpolator structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + * @return none. + */ + + void arm_fir_interpolate_q15( + const arm_fir_interpolate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 FIR interpolator. + * @param[in,out] *S points to an instance of the Q15 FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] *pCoeffs points to the filter coefficient buffer. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length <code>numTaps</code> is not a multiple of the interpolation factor <code>L</code>. + */ + + arm_status arm_fir_interpolate_init_q15( + arm_fir_interpolate_instance_q15 * S, + uint8_t L, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 FIR interpolator. + * @param[in] *S points to an instance of the Q15 FIR interpolator structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + * @return none. + */ + + void arm_fir_interpolate_q31( + const arm_fir_interpolate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q31 FIR interpolator. + * @param[in,out] *S points to an instance of the Q31 FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] *pCoeffs points to the filter coefficient buffer. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length <code>numTaps</code> is not a multiple of the interpolation factor <code>L</code>. + */ + + arm_status arm_fir_interpolate_init_q31( + arm_fir_interpolate_instance_q31 * S, + uint8_t L, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point FIR interpolator. + * @param[in] *S points to an instance of the floating-point FIR interpolator structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + * @return none. + */ + + void arm_fir_interpolate_f32( + const arm_fir_interpolate_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the floating-point FIR interpolator. + * @param[in,out] *S points to an instance of the floating-point FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] *pCoeffs points to the filter coefficient buffer. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length <code>numTaps</code> is not a multiple of the interpolation factor <code>L</code>. + */ + + arm_status arm_fir_interpolate_init_f32( + arm_fir_interpolate_instance_f32 * S, + uint8_t L, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + /** + * @brief Instance structure for the high precision Q31 Biquad cascade filter. + */ + + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q63_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ + q31_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< additional shift, in bits, applied to each output sample. */ + + } arm_biquad_cas_df1_32x64_ins_q31; + + + /** + * @param[in] *S points to an instance of the high precision Q31 Biquad cascade filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_biquad_cas_df1_32x64_q31( + const arm_biquad_cas_df1_32x64_ins_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @param[in,out] *S points to an instance of the high precision Q31 Biquad cascade filter structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] postShift shift to be applied to the output. Varies according to the coefficients format + * @return none + */ + + void arm_biquad_cas_df1_32x64_init_q31( + arm_biquad_cas_df1_32x64_ins_q31 * S, + uint8_t numStages, + q31_t * pCoeffs, + q63_t * pState, + uint8_t postShift); + + + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ + float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_df2T_instance_f32; + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in] *S points to an instance of the filter data structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_biquad_cascade_df2T_f32( + const arm_biquad_cascade_df2T_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] *S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @return none + */ + + void arm_biquad_cascade_df2T_init_f32( + arm_biquad_cascade_df2T_instance_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + + /** + * @brief Instance structure for the Q15 FIR lattice filter. + */ + + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR lattice filter. + */ + + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR lattice filter. + */ + + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_f32; + + /** + * @brief Initialization function for the Q15 FIR lattice filter. + * @param[in] *S points to an instance of the Q15 FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] *pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] *pState points to the state buffer. The array is of length numStages. + * @return none. + */ + + void arm_fir_lattice_init_q15( + arm_fir_lattice_instance_q15 * S, + uint16_t numStages, + q15_t * pCoeffs, + q15_t * pState); + + + /** + * @brief Processing function for the Q15 FIR lattice filter. + * @param[in] *S points to an instance of the Q15 FIR lattice structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + void arm_fir_lattice_q15( + const arm_fir_lattice_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q31 FIR lattice filter. + * @param[in] *S points to an instance of the Q31 FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] *pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] *pState points to the state buffer. The array is of length numStages. + * @return none. + */ + + void arm_fir_lattice_init_q31( + arm_fir_lattice_instance_q31 * S, + uint16_t numStages, + q31_t * pCoeffs, + q31_t * pState); + + + /** + * @brief Processing function for the Q31 FIR lattice filter. + * @param[in] *S points to an instance of the Q31 FIR lattice structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_fir_lattice_q31( + const arm_fir_lattice_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + +/** + * @brief Initialization function for the floating-point FIR lattice filter. + * @param[in] *S points to an instance of the floating-point FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] *pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] *pState points to the state buffer. The array is of length numStages. + * @return none. + */ + + void arm_fir_lattice_init_f32( + arm_fir_lattice_instance_f32 * S, + uint16_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + /** + * @brief Processing function for the floating-point FIR lattice filter. + * @param[in] *S points to an instance of the floating-point FIR lattice structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_fir_lattice_f32( + const arm_fir_lattice_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Instance structure for the Q15 IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q15_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q15_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q31_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q31_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + float32_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + float32_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_f32; + + /** + * @brief Processing function for the floating-point IIR lattice filter. + * @param[in] *S points to an instance of the floating-point IIR lattice structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_iir_lattice_f32( + const arm_iir_lattice_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the floating-point IIR lattice filter. + * @param[in] *S points to an instance of the floating-point IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] *pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. + * @param[in] *pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. + * @param[in] *pState points to the state buffer. The array is of length numStages+blockSize-1. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_iir_lattice_init_f32( + arm_iir_lattice_instance_f32 * S, + uint16_t numStages, + float32_t * pkCoeffs, + float32_t * pvCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 IIR lattice filter. + * @param[in] *S points to an instance of the Q31 IIR lattice structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_iir_lattice_q31( + const arm_iir_lattice_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 IIR lattice filter. + * @param[in] *S points to an instance of the Q31 IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] *pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. + * @param[in] *pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. + * @param[in] *pState points to the state buffer. The array is of length numStages+blockSize. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_iir_lattice_init_q31( + arm_iir_lattice_instance_q31 * S, + uint16_t numStages, + q31_t * pkCoeffs, + q31_t * pvCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 IIR lattice filter. + * @param[in] *S points to an instance of the Q15 IIR lattice structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_iir_lattice_q15( + const arm_iir_lattice_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the Q15 IIR lattice filter. + * @param[in] *S points to an instance of the fixed-point Q15 IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] *pkCoeffs points to reflection coefficient buffer. The array is of length numStages. + * @param[in] *pvCoeffs points to ladder coefficient buffer. The array is of length numStages+1. + * @param[in] *pState points to state buffer. The array is of length numStages+blockSize. + * @param[in] blockSize number of samples to process per call. + * @return none. + */ + + void arm_iir_lattice_init_q15( + arm_iir_lattice_instance_q15 * S, + uint16_t numStages, + q15_t * pkCoeffs, + q15_t * pvCoeffs, + q15_t * pState, + uint32_t blockSize); + + /** + * @brief Instance structure for the floating-point LMS filter. + */ + + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that controls filter coefficient updates. */ + } arm_lms_instance_f32; + + /** + * @brief Processing function for floating-point LMS filter. + * @param[in] *S points to an instance of the floating-point LMS filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[in] *pRef points to the block of reference data. + * @param[out] *pOut points to the block of output data. + * @param[out] *pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_lms_f32( + const arm_lms_instance_f32 * S, + float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + /** + * @brief Initialization function for floating-point LMS filter. + * @param[in] *S points to an instance of the floating-point LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] *pCoeffs points to the coefficient buffer. + * @param[in] *pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_lms_init_f32( + arm_lms_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + /** + * @brief Instance structure for the Q15 LMS filter. + */ + + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ + } arm_lms_instance_q15; + + + /** + * @brief Initialization function for the Q15 LMS filter. + * @param[in] *S points to an instance of the Q15 LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] *pCoeffs points to the coefficient buffer. + * @param[in] *pState points to the state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + * @return none. + */ + + void arm_lms_init_q15( + arm_lms_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint32_t postShift); + + /** + * @brief Processing function for Q15 LMS filter. + * @param[in] *S points to an instance of the Q15 LMS filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[in] *pRef points to the block of reference data. + * @param[out] *pOut points to the block of output data. + * @param[out] *pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_lms_q15( + const arm_lms_instance_q15 * S, + q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 LMS filter. + */ + + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ + + } arm_lms_instance_q31; + + /** + * @brief Processing function for Q31 LMS filter. + * @param[in] *S points to an instance of the Q15 LMS filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[in] *pRef points to the block of reference data. + * @param[out] *pOut points to the block of output data. + * @param[out] *pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_lms_q31( + const arm_lms_instance_q31 * S, + q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + /** + * @brief Initialization function for Q31 LMS filter. + * @param[in] *S points to an instance of the Q31 LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] *pCoeffs points to coefficient buffer. + * @param[in] *pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + * @return none. + */ + + void arm_lms_init_q31( + arm_lms_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint32_t postShift); + + /** + * @brief Instance structure for the floating-point normalized LMS filter. + */ + + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that control filter coefficient updates. */ + float32_t energy; /**< saves previous frame energy. */ + float32_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_f32; + + /** + * @brief Processing function for floating-point normalized LMS filter. + * @param[in] *S points to an instance of the floating-point normalized LMS filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[in] *pRef points to the block of reference data. + * @param[out] *pOut points to the block of output data. + * @param[out] *pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_lms_norm_f32( + arm_lms_norm_instance_f32 * S, + float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + /** + * @brief Initialization function for floating-point normalized LMS filter. + * @param[in] *S points to an instance of the floating-point LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] *pCoeffs points to coefficient buffer. + * @param[in] *pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_lms_norm_init_f32( + arm_lms_norm_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + q31_t *recipTable; /**< points to the reciprocal initial value table. */ + q31_t energy; /**< saves previous frame energy. */ + q31_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_q31; + + /** + * @brief Processing function for Q31 normalized LMS filter. + * @param[in] *S points to an instance of the Q31 normalized LMS filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[in] *pRef points to the block of reference data. + * @param[out] *pOut points to the block of output data. + * @param[out] *pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_lms_norm_q31( + arm_lms_norm_instance_q31 * S, + q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + /** + * @brief Initialization function for Q31 normalized LMS filter. + * @param[in] *S points to an instance of the Q31 normalized LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] *pCoeffs points to coefficient buffer. + * @param[in] *pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + * @return none. + */ + + void arm_lms_norm_init_q31( + arm_lms_norm_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint8_t postShift); + + /** + * @brief Instance structure for the Q15 normalized LMS filter. + */ + + typedef struct + { + uint16_t numTaps; /**< Number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + q15_t *recipTable; /**< Points to the reciprocal initial value table. */ + q15_t energy; /**< saves previous frame energy. */ + q15_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_q15; + + /** + * @brief Processing function for Q15 normalized LMS filter. + * @param[in] *S points to an instance of the Q15 normalized LMS filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[in] *pRef points to the block of reference data. + * @param[out] *pOut points to the block of output data. + * @param[out] *pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_lms_norm_q15( + arm_lms_norm_instance_q15 * S, + q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q15 normalized LMS filter. + * @param[in] *S points to an instance of the Q15 normalized LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] *pCoeffs points to coefficient buffer. + * @param[in] *pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + * @return none. + */ + + void arm_lms_norm_init_q15( + arm_lms_norm_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint8_t postShift); + + /** + * @brief Correlation of floating-point sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @return none. + */ + + void arm_correlate_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + + /** + * @brief Correlation of Q15 sequences + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] *pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @return none. + */ + void arm_correlate_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + + /** + * @brief Correlation of Q15 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @return none. + */ + + void arm_correlate_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + /** + * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @return none. + */ + + void arm_correlate_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + + + /** + * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] *pScratch points to scratch buffer of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @return none. + */ + + void arm_correlate_fast_opt_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + q15_t * pScratch); + + /** + * @brief Correlation of Q31 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @return none. + */ + + void arm_correlate_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + /** + * @brief Correlation of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @return none. + */ + + void arm_correlate_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + + + /** + * @brief Correlation of Q7 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @param[in] *pScratch1 points to scratch buffer(of type q15_t) of size max(srcALen, srcBLen) + 2*min(srcALen, srcBLen) - 2. + * @param[in] *pScratch2 points to scratch buffer (of type q15_t) of size min(srcALen, srcBLen). + * @return none. + */ + + void arm_correlate_opt_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + q15_t * pScratch1, + q15_t * pScratch2); + + + /** + * @brief Correlation of Q7 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @return none. + */ + + void arm_correlate_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + + /** + * @brief Instance structure for the floating-point sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + float32_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_f32; + + /** + * @brief Instance structure for the Q31 sparse FIR filter. + */ + + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q31_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q31; + + /** + * @brief Instance structure for the Q15 sparse FIR filter. + */ + + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q15_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q15; + + /** + * @brief Instance structure for the Q7 sparse FIR filter. + */ + + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q7_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q7; + + /** + * @brief Processing function for the floating-point sparse FIR filter. + * @param[in] *S points to an instance of the floating-point sparse FIR structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] *pScratchIn points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + * @return none. + */ + + void arm_fir_sparse_f32( + arm_fir_sparse_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + float32_t * pScratchIn, + uint32_t blockSize); + + /** + * @brief Initialization function for the floating-point sparse FIR filter. + * @param[in,out] *S points to an instance of the floating-point sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] *pCoeffs points to the array of filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] *pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + * @return none + */ + + void arm_fir_sparse_init_f32( + arm_fir_sparse_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 sparse FIR filter. + * @param[in] *S points to an instance of the Q31 sparse FIR structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] *pScratchIn points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + * @return none. + */ + + void arm_fir_sparse_q31( + arm_fir_sparse_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + q31_t * pScratchIn, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q31 sparse FIR filter. + * @param[in,out] *S points to an instance of the Q31 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] *pCoeffs points to the array of filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] *pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + * @return none + */ + + void arm_fir_sparse_init_q31( + arm_fir_sparse_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + /** + * @brief Processing function for the Q15 sparse FIR filter. + * @param[in] *S points to an instance of the Q15 sparse FIR structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] *pScratchIn points to a temporary buffer of size blockSize. + * @param[in] *pScratchOut points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + * @return none. + */ + + void arm_fir_sparse_q15( + arm_fir_sparse_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + q15_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 sparse FIR filter. + * @param[in,out] *S points to an instance of the Q15 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] *pCoeffs points to the array of filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] *pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + * @return none + */ + + void arm_fir_sparse_init_q15( + arm_fir_sparse_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + /** + * @brief Processing function for the Q7 sparse FIR filter. + * @param[in] *S points to an instance of the Q7 sparse FIR structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] *pScratchIn points to a temporary buffer of size blockSize. + * @param[in] *pScratchOut points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + * @return none. + */ + + void arm_fir_sparse_q7( + arm_fir_sparse_instance_q7 * S, + q7_t * pSrc, + q7_t * pDst, + q7_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q7 sparse FIR filter. + * @param[in,out] *S points to an instance of the Q7 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] *pCoeffs points to the array of filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] *pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + * @return none + */ + + void arm_fir_sparse_init_q7( + arm_fir_sparse_instance_q7 * S, + uint16_t numTaps, + q7_t * pCoeffs, + q7_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /* + * @brief Floating-point sin_cos function. + * @param[in] theta input value in degrees + * @param[out] *pSinVal points to the processed sine output. + * @param[out] *pCosVal points to the processed cos output. + * @return none. + */ + + void arm_sin_cos_f32( + float32_t theta, + float32_t * pSinVal, + float32_t * pCcosVal); + + /* + * @brief Q31 sin_cos function. + * @param[in] theta scaled input value in degrees + * @param[out] *pSinVal points to the processed sine output. + * @param[out] *pCosVal points to the processed cosine output. + * @return none. + */ + + void arm_sin_cos_q31( + q31_t theta, + q31_t * pSinVal, + q31_t * pCosVal); + + + /** + * @brief Floating-point complex conjugate. + * @param[in] *pSrc points to the input vector + * @param[out] *pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + * @return none. + */ + + void arm_cmplx_conj_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + /** + * @brief Q31 complex conjugate. + * @param[in] *pSrc points to the input vector + * @param[out] *pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + * @return none. + */ + + void arm_cmplx_conj_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + /** + * @brief Q15 complex conjugate. + * @param[in] *pSrc points to the input vector + * @param[out] *pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + * @return none. + */ + + void arm_cmplx_conj_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + + /** + * @brief Floating-point complex magnitude squared + * @param[in] *pSrc points to the complex input vector + * @param[out] *pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + * @return none. + */ + + void arm_cmplx_mag_squared_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + /** + * @brief Q31 complex magnitude squared + * @param[in] *pSrc points to the complex input vector + * @param[out] *pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + * @return none. + */ + + void arm_cmplx_mag_squared_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + /** + * @brief Q15 complex magnitude squared + * @param[in] *pSrc points to the complex input vector + * @param[out] *pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + * @return none. + */ + + void arm_cmplx_mag_squared_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @ingroup groupController + */ + + /** + * @defgroup PID PID Motor Control + * + * A Proportional Integral Derivative (PID) controller is a generic feedback control + * loop mechanism widely used in industrial control systems. + * A PID controller is the most commonly used type of feedback controller. + * + * This set of functions implements (PID) controllers + * for Q15, Q31, and floating-point data types. The functions operate on a single sample + * of data and each call to the function returns a single processed value. + * <code>S</code> points to an instance of the PID control data structure. <code>in</code> + * is the input sample value. The functions return the output value. + * + * \par Algorithm: + * <pre> + * y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2] + * A0 = Kp + Ki + Kd + * A1 = (-Kp ) - (2 * Kd ) + * A2 = Kd </pre> + * + * \par + * where \c Kp is proportional constant, \c Ki is Integral constant and \c Kd is Derivative constant + * + * \par + * \image html PID.gif "Proportional Integral Derivative Controller" + * + * \par + * The PID controller calculates an "error" value as the difference between + * the measured output and the reference input. + * The controller attempts to minimize the error by adjusting the process control inputs. + * The proportional value determines the reaction to the current error, + * the integral value determines the reaction based on the sum of recent errors, + * and the derivative value determines the reaction based on the rate at which the error has been changing. + * + * \par Instance Structure + * The Gains A0, A1, A2 and state variables for a PID controller are stored together in an instance data structure. + * A separate instance structure must be defined for each PID Controller. + * There are separate instance structure declarations for each of the 3 supported data types. + * + * \par Reset Functions + * There is also an associated reset function for each data type which clears the state array. + * + * \par Initialization Functions + * There is also an associated initialization function for each data type. + * The initialization function performs the following operations: + * - Initializes the Gains A0, A1, A2 from Kp,Ki, Kd gains. + * - Zeros out the values in the state buffer. + * + * \par + * Instance structure cannot be placed into a const data section and it is recommended to use the initialization function. + * + * \par Fixed-Point Behavior + * Care must be taken when using the fixed-point versions of the PID Controller functions. + * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup PID + * @{ + */ + + /** + * @brief Process function for the floating-point PID Control. + * @param[in,out] *S is an instance of the floating-point PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + */ + + + __STATIC_INLINE float32_t arm_pid_f32( + arm_pid_instance_f32 * S, + float32_t in) + { + float32_t out; + + /* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2] */ + out = (S->A0 * in) + + (S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]); + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + + } + + /** + * @brief Process function for the Q31 PID Control. + * @param[in,out] *S points to an instance of the Q31 PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + * + * <b>Scaling and Overflow Behavior:</b> + * \par + * The function is implemented using an internal 64-bit accumulator. + * The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit. + * Thus, if the accumulator result overflows it wraps around rather than clip. + * In order to avoid overflows completely the input signal must be scaled down by 2 bits as there are four additions. + * After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format. + */ + + __STATIC_INLINE q31_t arm_pid_q31( + arm_pid_instance_q31 * S, + q31_t in) + { + q63_t acc; + q31_t out; + + /* acc = A0 * x[n] */ + acc = (q63_t) S->A0 * in; + + /* acc += A1 * x[n-1] */ + acc += (q63_t) S->A1 * S->state[0]; + + /* acc += A2 * x[n-2] */ + acc += (q63_t) S->A2 * S->state[1]; + + /* convert output to 1.31 format to add y[n-1] */ + out = (q31_t) (acc >> 31u); + + /* out += y[n-1] */ + out += S->state[2]; + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + + } + + /** + * @brief Process function for the Q15 PID Control. + * @param[in,out] *S points to an instance of the Q15 PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + * + * <b>Scaling and Overflow Behavior:</b> + * \par + * The function is implemented using a 64-bit internal accumulator. + * Both Gains and state variables are represented in 1.15 format and multiplications yield a 2.30 result. + * The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format. + * There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved. + * After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits. + * Lastly, the accumulator is saturated to yield a result in 1.15 format. + */ + + __STATIC_INLINE q15_t arm_pid_q15( + arm_pid_instance_q15 * S, + q15_t in) + { + q63_t acc; + q15_t out; + + /* Implementation of PID controller */ + +#ifdef ARM_MATH_CM0 + + /* acc = A0 * x[n] */ + acc = ((q31_t) S->A0) * in; + +#else + + /* acc = A0 * x[n] */ + acc = (q31_t) __SMUAD(S->A0, in); + +#endif + +#ifdef ARM_MATH_CM0 + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + acc += (q31_t) S->A1 * S->state[0]; + acc += (q31_t) S->A2 * S->state[1]; + +#else + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + acc = __SMLALD(S->A1, (q31_t) __SIMD32(S->state), acc); + +#endif + + /* acc += y[n-1] */ + acc += (q31_t) S->state[2] << 15; + + /* saturate the output */ + out = (q15_t) (__SSAT((acc >> 15), 16)); + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + + } + + /** + * @} end of PID group + */ + + + /** + * @brief Floating-point matrix inverse. + * @param[in] *src points to the instance of the input floating-point matrix structure. + * @param[out] *dst points to the instance of the output floating-point matrix structure. + * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. + * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. + */ + + arm_status arm_mat_inverse_f32( + const arm_matrix_instance_f32 * src, + arm_matrix_instance_f32 * dst); + + + + /** + * @ingroup groupController + */ + + + /** + * @defgroup clarke Vector Clarke Transform + * Forward Clarke transform converts the instantaneous stator phases into a two-coordinate time invariant vector. + * Generally the Clarke transform uses three-phase currents <code>Ia, Ib and Ic</code> to calculate currents + * in the two-phase orthogonal stator axis <code>Ialpha</code> and <code>Ibeta</code>. + * When <code>Ialpha</code> is superposed with <code>Ia</code> as shown in the figure below + * \image html clarke.gif Stator current space vector and its components in (a,b). + * and <code>Ia + Ib + Ic = 0</code>, in this condition <code>Ialpha</code> and <code>Ibeta</code> + * can be calculated using only <code>Ia</code> and <code>Ib</code>. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeFormula.gif + * where <code>Ia</code> and <code>Ib</code> are the instantaneous stator phases and + * <code>pIalpha</code> and <code>pIbeta</code> are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup clarke + * @{ + */ + + /** + * + * @brief Floating-point Clarke transform + * @param[in] Ia input three-phase coordinate <code>a</code> + * @param[in] Ib input three-phase coordinate <code>b</code> + * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta + * @return none. + */ + + __STATIC_INLINE void arm_clarke_f32( + float32_t Ia, + float32_t Ib, + float32_t * pIalpha, + float32_t * pIbeta) + { + /* Calculate pIalpha using the equation, pIalpha = Ia */ + *pIalpha = Ia; + + /* Calculate pIbeta using the equation, pIbeta = (1/sqrt(3)) * Ia + (2/sqrt(3)) * Ib */ + *pIbeta = + ((float32_t) 0.57735026919 * Ia + (float32_t) 1.15470053838 * Ib); + + } + + /** + * @brief Clarke transform for Q31 version + * @param[in] Ia input three-phase coordinate <code>a</code> + * @param[in] Ib input three-phase coordinate <code>b</code> + * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta + * @return none. + * + * <b>Scaling and Overflow Behavior:</b> + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition, hence there is no risk of overflow. + */ + + __STATIC_INLINE void arm_clarke_q31( + q31_t Ia, + q31_t Ib, + q31_t * pIalpha, + q31_t * pIbeta) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + + /* Calculating pIalpha from Ia by equation pIalpha = Ia */ + *pIalpha = Ia; + + /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) Ia * 0x24F34E8B) >> 30); + + /* Intermediate product is calculated by (2/sqrt(3) * Ib) */ + product2 = (q31_t) (((q63_t) Ib * 0x49E69D16) >> 30); + + /* pIbeta is calculated by adding the intermediate products */ + *pIbeta = __QADD(product1, product2); + } + + /** + * @} end of clarke group + */ + + /** + * @brief Converts the elements of the Q7 vector to Q31 vector. + * @param[in] *pSrc input pointer + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_q7_to_q31( + q7_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup inv_clarke Vector Inverse Clarke Transform + * Inverse Clarke transform converts the two-coordinate time invariant vector into instantaneous stator phases. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeInvFormula.gif + * where <code>pIa</code> and <code>pIb</code> are the instantaneous stator phases and + * <code>Ialpha</code> and <code>Ibeta</code> are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup inv_clarke + * @{ + */ + + /** + * @brief Floating-point Inverse Clarke transform + * @param[in] Ialpha input two-phase orthogonal vector axis alpha + * @param[in] Ibeta input two-phase orthogonal vector axis beta + * @param[out] *pIa points to output three-phase coordinate <code>a</code> + * @param[out] *pIb points to output three-phase coordinate <code>b</code> + * @return none. + */ + + + __STATIC_INLINE void arm_inv_clarke_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pIa, + float32_t * pIb) + { + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + + /* Calculating pIb from Ialpha and Ibeta by equation pIb = -(1/2) * Ialpha + (sqrt(3)/2) * Ibeta */ + *pIb = -0.5 * Ialpha + (float32_t) 0.8660254039 *Ibeta; + + } + + /** + * @brief Inverse Clarke transform for Q31 version + * @param[in] Ialpha input two-phase orthogonal vector axis alpha + * @param[in] Ibeta input two-phase orthogonal vector axis beta + * @param[out] *pIa points to output three-phase coordinate <code>a</code> + * @param[out] *pIb points to output three-phase coordinate <code>b</code> + * @return none. + * + * <b>Scaling and Overflow Behavior:</b> + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the subtraction, hence there is no risk of overflow. + */ + + __STATIC_INLINE void arm_inv_clarke_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pIa, + q31_t * pIb) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + + /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) (Ialpha) * (0x40000000)) >> 31); + + /* Intermediate product is calculated by (1/sqrt(3) * pIb) */ + product2 = (q31_t) (((q63_t) (Ibeta) * (0x6ED9EBA1)) >> 31); + + /* pIb is calculated by subtracting the products */ + *pIb = __QSUB(product2, product1); + + } + + /** + * @} end of inv_clarke group + */ + + /** + * @brief Converts the elements of the Q7 vector to Q15 vector. + * @param[in] *pSrc input pointer + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_q7_to_q15( + q7_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup park Vector Park Transform + * + * Forward Park transform converts the input two-coordinate vector to flux and torque components. + * The Park transform can be used to realize the transformation of the <code>Ialpha</code> and the <code>Ibeta</code> currents + * from the stationary to the moving reference frame and control the spatial relationship between + * the stator vector current and rotor flux vector. + * If we consider the d axis aligned with the rotor flux, the diagram below shows the + * current vector and the relationship from the two reference frames: + * \image html park.gif "Stator current space vector and its component in (a,b) and in the d,q rotating reference frame" + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkFormula.gif + * where <code>Ialpha</code> and <code>Ibeta</code> are the stator vector components, + * <code>pId</code> and <code>pIq</code> are rotor vector components and <code>cosVal</code> and <code>sinVal</code> are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup park + * @{ + */ + + /** + * @brief Floating-point Park transform + * @param[in] Ialpha input two-phase vector coordinate alpha + * @param[in] Ibeta input two-phase vector coordinate beta + * @param[out] *pId points to output rotor reference frame d + * @param[out] *pIq points to output rotor reference frame q + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * @return none. + * + * The function implements the forward Park transform. + * + */ + + __STATIC_INLINE void arm_park_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pId, + float32_t * pIq, + float32_t sinVal, + float32_t cosVal) + { + /* Calculate pId using the equation, pId = Ialpha * cosVal + Ibeta * sinVal */ + *pId = Ialpha * cosVal + Ibeta * sinVal; + + /* Calculate pIq using the equation, pIq = - Ialpha * sinVal + Ibeta * cosVal */ + *pIq = -Ialpha * sinVal + Ibeta * cosVal; + + } + + /** + * @brief Park transform for Q31 version + * @param[in] Ialpha input two-phase vector coordinate alpha + * @param[in] Ibeta input two-phase vector coordinate beta + * @param[out] *pId points to output rotor reference frame d + * @param[out] *pIq points to output rotor reference frame q + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * @return none. + * + * <b>Scaling and Overflow Behavior:</b> + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition and subtraction, hence there is no risk of overflow. + */ + + + __STATIC_INLINE void arm_park_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pId, + q31_t * pIq, + q31_t sinVal, + q31_t cosVal) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + + /* Intermediate product is calculated by (Ialpha * cosVal) */ + product1 = (q31_t) (((q63_t) (Ialpha) * (cosVal)) >> 31); + + /* Intermediate product is calculated by (Ibeta * sinVal) */ + product2 = (q31_t) (((q63_t) (Ibeta) * (sinVal)) >> 31); + + + /* Intermediate product is calculated by (Ialpha * sinVal) */ + product3 = (q31_t) (((q63_t) (Ialpha) * (sinVal)) >> 31); + + /* Intermediate product is calculated by (Ibeta * cosVal) */ + product4 = (q31_t) (((q63_t) (Ibeta) * (cosVal)) >> 31); + + /* Calculate pId by adding the two intermediate products 1 and 2 */ + *pId = __QADD(product1, product2); + + /* Calculate pIq by subtracting the two intermediate products 3 from 4 */ + *pIq = __QSUB(product4, product3); + } + + /** + * @} end of park group + */ + + /** + * @brief Converts the elements of the Q7 vector to floating-point vector. + * @param[in] *pSrc is input pointer + * @param[out] *pDst is output pointer + * @param[in] blockSize is the number of samples to process + * @return none. + */ + void arm_q7_to_float( + q7_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @ingroup groupController + */ + + /** + * @defgroup inv_park Vector Inverse Park transform + * Inverse Park transform converts the input flux and torque components to two-coordinate vector. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkInvFormula.gif + * where <code>pIalpha</code> and <code>pIbeta</code> are the stator vector components, + * <code>Id</code> and <code>Iq</code> are rotor vector components and <code>cosVal</code> and <code>sinVal</code> are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup inv_park + * @{ + */ + + /** + * @brief Floating-point Inverse Park transform + * @param[in] Id input coordinate of rotor reference frame d + * @param[in] Iq input coordinate of rotor reference frame q + * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * @return none. + */ + + __STATIC_INLINE void arm_inv_park_f32( + float32_t Id, + float32_t Iq, + float32_t * pIalpha, + float32_t * pIbeta, + float32_t sinVal, + float32_t cosVal) + { + /* Calculate pIalpha using the equation, pIalpha = Id * cosVal - Iq * sinVal */ + *pIalpha = Id * cosVal - Iq * sinVal; + + /* Calculate pIbeta using the equation, pIbeta = Id * sinVal + Iq * cosVal */ + *pIbeta = Id * sinVal + Iq * cosVal; + + } + + + /** + * @brief Inverse Park transform for Q31 version + * @param[in] Id input coordinate of rotor reference frame d + * @param[in] Iq input coordinate of rotor reference frame q + * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * @return none. + * + * <b>Scaling and Overflow Behavior:</b> + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition, hence there is no risk of overflow. + */ + + + __STATIC_INLINE void arm_inv_park_q31( + q31_t Id, + q31_t Iq, + q31_t * pIalpha, + q31_t * pIbeta, + q31_t sinVal, + q31_t cosVal) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + + /* Intermediate product is calculated by (Id * cosVal) */ + product1 = (q31_t) (((q63_t) (Id) * (cosVal)) >> 31); + + /* Intermediate product is calculated by (Iq * sinVal) */ + product2 = (q31_t) (((q63_t) (Iq) * (sinVal)) >> 31); + + + /* Intermediate product is calculated by (Id * sinVal) */ + product3 = (q31_t) (((q63_t) (Id) * (sinVal)) >> 31); + + /* Intermediate product is calculated by (Iq * cosVal) */ + product4 = (q31_t) (((q63_t) (Iq) * (cosVal)) >> 31); + + /* Calculate pIalpha by using the two intermediate products 1 and 2 */ + *pIalpha = __QSUB(product1, product2); + + /* Calculate pIbeta by using the two intermediate products 3 and 4 */ + *pIbeta = __QADD(product4, product3); + + } + + /** + * @} end of Inverse park group + */ + + + /** + * @brief Converts the elements of the Q31 vector to floating-point vector. + * @param[in] *pSrc is input pointer + * @param[out] *pDst is output pointer + * @param[in] blockSize is the number of samples to process + * @return none. + */ + void arm_q31_to_float( + q31_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @ingroup groupInterpolation + */ + + /** + * @defgroup LinearInterpolate Linear Interpolation + * + * Linear interpolation is a method of curve fitting using linear polynomials. + * Linear interpolation works by effectively drawing a straight line between two neighboring samples and returning the appropriate point along that line + * + * \par + * \image html LinearInterp.gif "Linear interpolation" + * + * \par + * A Linear Interpolate function calculates an output value(y), for the input(x) + * using linear interpolation of the input values x0, x1( nearest input values) and the output values y0 and y1(nearest output values) + * + * \par Algorithm: + * <pre> + * y = y0 + (x - x0) * ((y1 - y0)/(x1-x0)) + * where x0, x1 are nearest values of input x + * y0, y1 are nearest values to output y + * </pre> + * + * \par + * This set of functions implements Linear interpolation process + * for Q7, Q15, Q31, and floating-point data types. The functions operate on a single + * sample of data and each call to the function returns a single processed value. + * <code>S</code> points to an instance of the Linear Interpolate function data structure. + * <code>x</code> is the input sample value. The functions returns the output value. + * + * \par + * if x is outside of the table boundary, Linear interpolation returns first value of the table + * if x is below input range and returns last value of table if x is above range. + */ + + /** + * @addtogroup LinearInterpolate + * @{ + */ + + /** + * @brief Process function for the floating-point Linear Interpolation Function. + * @param[in,out] *S is an instance of the floating-point Linear Interpolation structure + * @param[in] x input sample to process + * @return y processed output sample. + * + */ + + __STATIC_INLINE float32_t arm_linear_interp_f32( + arm_linear_interp_instance_f32 * S, + float32_t x) + { + + float32_t y; + float32_t x0, x1; /* Nearest input values */ + float32_t y0, y1; /* Nearest output values */ + float32_t xSpacing = S->xSpacing; /* spacing between input values */ + int32_t i; /* Index variable */ + float32_t *pYData = S->pYData; /* pointer to output table */ + + /* Calculation of index */ + i = (x - S->x1) / xSpacing; + + if(i < 0) + { + /* Iniatilize output for below specified range as least output value of table */ + y = pYData[0]; + } + else if(i >= S->nValues) + { + /* Iniatilize output for above specified range as last output value of table */ + y = pYData[S->nValues - 1]; + } + else + { + /* Calculation of nearest input values */ + x0 = S->x1 + i * xSpacing; + x1 = S->x1 + (i + 1) * xSpacing; + + /* Read of nearest output values */ + y0 = pYData[i]; + y1 = pYData[i + 1]; + + /* Calculation of output */ + y = y0 + (x - x0) * ((y1 - y0) / (x1 - x0)); + + } + + /* returns output value */ + return (y); + } + + /** + * + * @brief Process function for the Q31 Linear Interpolation Function. + * @param[in] *pYData pointer to Q31 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample <code>x</code> is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ + + + __STATIC_INLINE q31_t arm_linear_interp_q31( + q31_t * pYData, + q31_t x, + uint32_t nValues) + { + q31_t y; /* output */ + q31_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & 0xFFF00000) >> 20); + + if(index >= (nValues - 1)) + { + return (pYData[nValues - 1]); + } + else if(index < 0) + { + return (pYData[0]); + } + else + { + + /* 20 bits for the fractional part */ + /* shift left by 11 to keep fract in 1.31 format */ + fract = (x & 0x000FFFFF) << 11; + + /* Read two nearest output values from the index in 1.31(q31) format */ + y0 = pYData[index]; + y1 = pYData[index + 1u]; + + /* Calculation of y0 * (1-fract) and y is in 2.30 format */ + y = ((q31_t) ((q63_t) y0 * (0x7FFFFFFF - fract) >> 32)); + + /* Calculation of y0 * (1-fract) + y1 *fract and y is in 2.30 format */ + y += ((q31_t) (((q63_t) y1 * fract) >> 32)); + + /* Convert y to 1.31 format */ + return (y << 1u); + + } + + } + + /** + * + * @brief Process function for the Q15 Linear Interpolation Function. + * @param[in] *pYData pointer to Q15 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample <code>x</code> is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ + + + __STATIC_INLINE q15_t arm_linear_interp_q15( + q15_t * pYData, + q31_t x, + uint32_t nValues) + { + q63_t y; /* output */ + q15_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & 0xFFF00000) >> 20u); + + if(index >= (nValues - 1)) + { + return (pYData[nValues - 1]); + } + else if(index < 0) + { + return (pYData[0]); + } + else + { + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y0 = pYData[index]; + y1 = pYData[index + 1u]; + + /* Calculation of y0 * (1-fract) and y is in 13.35 format */ + y = ((q63_t) y0 * (0xFFFFF - fract)); + + /* Calculation of (y0 * (1-fract) + y1 * fract) and y is in 13.35 format */ + y += ((q63_t) y1 * (fract)); + + /* convert y to 1.15 format */ + return (y >> 20); + } + + + } + + /** + * + * @brief Process function for the Q7 Linear Interpolation Function. + * @param[in] *pYData pointer to Q7 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample <code>x</code> is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + */ + + + __STATIC_INLINE q7_t arm_linear_interp_q7( + q7_t * pYData, + q31_t x, + uint32_t nValues) + { + q31_t y; /* output */ + q7_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & 0xFFF00000) >> 20u); + + + if(index >= (nValues - 1)) + { + return (pYData[nValues - 1]); + } + else if(index < 0) + { + return (pYData[0]); + } + else + { + + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + + /* Read two nearest output values from the index and are in 1.7(q7) format */ + y0 = pYData[index]; + y1 = pYData[index + 1u]; + + /* Calculation of y0 * (1-fract ) and y is in 13.27(q27) format */ + y = ((y0 * (0xFFFFF - fract))); + + /* Calculation of y1 * fract + y0 * (1-fract) and y is in 13.27(q27) format */ + y += (y1 * fract); + + /* convert y to 1.7(q7) format */ + return (y >> 20u); + + } + + } + /** + * @} end of LinearInterpolate group + */ + + /** + * @brief Fast approximation to the trigonometric sine function for floating-point data. + * @param[in] x input value in radians. + * @return sin(x). + */ + + float32_t arm_sin_f32( + float32_t x); + + /** + * @brief Fast approximation to the trigonometric sine function for Q31 data. + * @param[in] x Scaled input value in radians. + * @return sin(x). + */ + + q31_t arm_sin_q31( + q31_t x); + + /** + * @brief Fast approximation to the trigonometric sine function for Q15 data. + * @param[in] x Scaled input value in radians. + * @return sin(x). + */ + + q15_t arm_sin_q15( + q15_t x); + + /** + * @brief Fast approximation to the trigonometric cosine function for floating-point data. + * @param[in] x input value in radians. + * @return cos(x). + */ + + float32_t arm_cos_f32( + float32_t x); + + /** + * @brief Fast approximation to the trigonometric cosine function for Q31 data. + * @param[in] x Scaled input value in radians. + * @return cos(x). + */ + + q31_t arm_cos_q31( + q31_t x); + + /** + * @brief Fast approximation to the trigonometric cosine function for Q15 data. + * @param[in] x Scaled input value in radians. + * @return cos(x). + */ + + q15_t arm_cos_q15( + q15_t x); + + + /** + * @ingroup groupFastMath + */ + + + /** + * @defgroup SQRT Square Root + * + * Computes the square root of a number. + * There are separate functions for Q15, Q31, and floating-point data types. + * The square root function is computed using the Newton-Raphson algorithm. + * This is an iterative algorithm of the form: + * <pre> + * x1 = x0 - f(x0)/f'(x0) + * </pre> + * where <code>x1</code> is the current estimate, + * <code>x0</code> is the previous estimate and + * <code>f'(x0)</code> is the derivative of <code>f()</code> evaluated at <code>x0</code>. + * For the square root function, the algorithm reduces to: + * <pre> + * x0 = in/2 [initial guess] + * x1 = 1/2 * ( x0 + in / x0) [each iteration] + * </pre> + */ + + + /** + * @addtogroup SQRT + * @{ + */ + + /** + * @brief Floating-point square root function. + * @param[in] in input value. + * @param[out] *pOut square root of input value. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * <code>in</code> is negative value and returns zero output for negative values. + */ + + __STATIC_INLINE arm_status arm_sqrt_f32( + float32_t in, + float32_t * pOut) + { + if(in > 0) + { + +// #if __FPU_USED + #if (__FPU_USED == 1) && defined ( __CC_ARM ) + *pOut = __sqrtf(in); + #elif (__FPU_USED == 1) && defined ( __TMS_740 ) + *pOut = __builtin_sqrtf(in); + #else + *pOut = sqrtf(in); + #endif + + return (ARM_MATH_SUCCESS); + } + else + { + *pOut = 0.0f; + return (ARM_MATH_ARGUMENT_ERROR); + } + + } + + + /** + * @brief Q31 square root function. + * @param[in] in input value. The range of the input value is [0 +1) or 0x00000000 to 0x7FFFFFFF. + * @param[out] *pOut square root of input value. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * <code>in</code> is negative value and returns zero output for negative values. + */ + arm_status arm_sqrt_q31( + q31_t in, + q31_t * pOut); + + /** + * @brief Q15 square root function. + * @param[in] in input value. The range of the input value is [0 +1) or 0x0000 to 0x7FFF. + * @param[out] *pOut square root of input value. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * <code>in</code> is negative value and returns zero output for negative values. + */ + arm_status arm_sqrt_q15( + q15_t in, + q15_t * pOut); + + /** + * @} end of SQRT group + */ + + + + + + + /** + * @brief floating-point Circular write function. + */ + + __STATIC_INLINE void arm_circularWrite_f32( + int32_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const int32_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if(wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = wOffset; + } + + + + /** + * @brief floating-point Circular Read function. + */ + __STATIC_INLINE void arm_circularRead_f32( + int32_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + int32_t * dst, + int32_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t rOffset, dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + dst_end = (int32_t) (dst_base + dst_length); + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if(dst == (int32_t *) dst_end) + { + dst = dst_base; + } + + /* Circularly update rOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if(rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + /** + * @brief Q15 Circular write function. + */ + + __STATIC_INLINE void arm_circularWrite_q15( + q15_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const q15_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if(wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = wOffset; + } + + + + /** + * @brief Q15 Circular Read function. + */ + __STATIC_INLINE void arm_circularRead_q15( + q15_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + q15_t * dst, + q15_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0; + int32_t rOffset, dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + + dst_end = (int32_t) (dst_base + dst_length); + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if(dst == (q15_t *) dst_end) + { + dst = dst_base; + } + + /* Circularly update wOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if(rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Q7 Circular write function. + */ + + __STATIC_INLINE void arm_circularWrite_q7( + q7_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const q7_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if(wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = wOffset; + } + + + + /** + * @brief Q7 Circular Read function. + */ + __STATIC_INLINE void arm_circularRead_q7( + q7_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + q7_t * dst, + q7_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0; + int32_t rOffset, dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + + dst_end = (int32_t) (dst_base + dst_length); + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if(dst == (q7_t *) dst_end) + { + dst = dst_base; + } + + /* Circularly update rOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if(rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Sum of the squares of the elements of a Q31 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_power_q31( + q31_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + /** + * @brief Sum of the squares of the elements of a floating-point vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_power_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + /** + * @brief Sum of the squares of the elements of a Q15 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_power_q15( + q15_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + /** + * @brief Sum of the squares of the elements of a Q7 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_power_q7( + q7_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + /** + * @brief Mean value of a Q7 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_mean_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult); + + /** + * @brief Mean value of a Q15 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + void arm_mean_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + /** + * @brief Mean value of a Q31 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + void arm_mean_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + /** + * @brief Mean value of a floating-point vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + void arm_mean_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + /** + * @brief Variance of the elements of a floating-point vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_var_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + /** + * @brief Variance of the elements of a Q31 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_var_q31( + q31_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + /** + * @brief Variance of the elements of a Q15 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_var_q15( + q15_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + /** + * @brief Root Mean Square of the elements of a floating-point vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_rms_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + /** + * @brief Root Mean Square of the elements of a Q31 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_rms_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + /** + * @brief Root Mean Square of the elements of a Q15 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_rms_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + /** + * @brief Standard deviation of the elements of a floating-point vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_std_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + /** + * @brief Standard deviation of the elements of a Q31 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_std_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + /** + * @brief Standard deviation of the elements of a Q15 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_std_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + /** + * @brief Floating-point complex magnitude + * @param[in] *pSrc points to the complex input vector + * @param[out] *pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + * @return none. + */ + + void arm_cmplx_mag_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + /** + * @brief Q31 complex magnitude + * @param[in] *pSrc points to the complex input vector + * @param[out] *pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + * @return none. + */ + + void arm_cmplx_mag_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + /** + * @brief Q15 complex magnitude + * @param[in] *pSrc points to the complex input vector + * @param[out] *pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + * @return none. + */ + + void arm_cmplx_mag_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + /** + * @brief Q15 complex dot product + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] *realResult real part of the result returned here + * @param[out] *imagResult imaginary part of the result returned here + * @return none. + */ + + void arm_cmplx_dot_prod_q15( + q15_t * pSrcA, + q15_t * pSrcB, + uint32_t numSamples, + q31_t * realResult, + q31_t * imagResult); + + /** + * @brief Q31 complex dot product + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] *realResult real part of the result returned here + * @param[out] *imagResult imaginary part of the result returned here + * @return none. + */ + + void arm_cmplx_dot_prod_q31( + q31_t * pSrcA, + q31_t * pSrcB, + uint32_t numSamples, + q63_t * realResult, + q63_t * imagResult); + + /** + * @brief Floating-point complex dot product + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] *realResult real part of the result returned here + * @param[out] *imagResult imaginary part of the result returned here + * @return none. + */ + + void arm_cmplx_dot_prod_f32( + float32_t * pSrcA, + float32_t * pSrcB, + uint32_t numSamples, + float32_t * realResult, + float32_t * imagResult); + + /** + * @brief Q15 complex-by-real multiplication + * @param[in] *pSrcCmplx points to the complex input vector + * @param[in] *pSrcReal points to the real input vector + * @param[out] *pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + * @return none. + */ + + void arm_cmplx_mult_real_q15( + q15_t * pSrcCmplx, + q15_t * pSrcReal, + q15_t * pCmplxDst, + uint32_t numSamples); + + /** + * @brief Q31 complex-by-real multiplication + * @param[in] *pSrcCmplx points to the complex input vector + * @param[in] *pSrcReal points to the real input vector + * @param[out] *pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + * @return none. + */ + + void arm_cmplx_mult_real_q31( + q31_t * pSrcCmplx, + q31_t * pSrcReal, + q31_t * pCmplxDst, + uint32_t numSamples); + + /** + * @brief Floating-point complex-by-real multiplication + * @param[in] *pSrcCmplx points to the complex input vector + * @param[in] *pSrcReal points to the real input vector + * @param[out] *pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + * @return none. + */ + + void arm_cmplx_mult_real_f32( + float32_t * pSrcCmplx, + float32_t * pSrcReal, + float32_t * pCmplxDst, + uint32_t numSamples); + + /** + * @brief Minimum value of a Q7 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *result is output pointer + * @param[in] index is the array index of the minimum value in the input buffer. + * @return none. + */ + + void arm_min_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * result, + uint32_t * index); + + /** + * @brief Minimum value of a Q15 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output pointer + * @param[in] *pIndex is the array index of the minimum value in the input buffer. + * @return none. + */ + + void arm_min_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + + /** + * @brief Minimum value of a Q31 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output pointer + * @param[out] *pIndex is the array index of the minimum value in the input buffer. + * @return none. + */ + void arm_min_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + + /** + * @brief Minimum value of a floating-point vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output pointer + * @param[out] *pIndex is the array index of the minimum value in the input buffer. + * @return none. + */ + + void arm_min_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + +/** + * @brief Maximum value of a Q7 vector. + * @param[in] *pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] *pResult maximum value returned here + * @param[out] *pIndex index of maximum value returned here + * @return none. + */ + + void arm_max_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult, + uint32_t * pIndex); + +/** + * @brief Maximum value of a Q15 vector. + * @param[in] *pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] *pResult maximum value returned here + * @param[out] *pIndex index of maximum value returned here + * @return none. + */ + + void arm_max_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + +/** + * @brief Maximum value of a Q31 vector. + * @param[in] *pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] *pResult maximum value returned here + * @param[out] *pIndex index of maximum value returned here + * @return none. + */ + + void arm_max_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + +/** + * @brief Maximum value of a floating-point vector. + * @param[in] *pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] *pResult maximum value returned here + * @param[out] *pIndex index of maximum value returned here + * @return none. + */ + + void arm_max_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + + /** + * @brief Q15 complex-by-complex multiplication + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + * @return none. + */ + + void arm_cmplx_mult_cmplx_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t numSamples); + + /** + * @brief Q31 complex-by-complex multiplication + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + * @return none. + */ + + void arm_cmplx_mult_cmplx_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t numSamples); + + /** + * @brief Floating-point complex-by-complex multiplication + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + * @return none. + */ + + void arm_cmplx_mult_cmplx_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t numSamples); + + /** + * @brief Converts the elements of the floating-point vector to Q31 vector. + * @param[in] *pSrc points to the floating-point input vector + * @param[out] *pDst points to the Q31 output vector + * @param[in] blockSize length of the input vector + * @return none. + */ + void arm_float_to_q31( + float32_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Converts the elements of the floating-point vector to Q15 vector. + * @param[in] *pSrc points to the floating-point input vector + * @param[out] *pDst points to the Q15 output vector + * @param[in] blockSize length of the input vector + * @return none + */ + void arm_float_to_q15( + float32_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Converts the elements of the floating-point vector to Q7 vector. + * @param[in] *pSrc points to the floating-point input vector + * @param[out] *pDst points to the Q7 output vector + * @param[in] blockSize length of the input vector + * @return none + */ + void arm_float_to_q7( + float32_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q31 vector to Q15 vector. + * @param[in] *pSrc is input pointer + * @param[out] *pDst is output pointer + * @param[in] blockSize is the number of samples to process + * @return none. + */ + void arm_q31_to_q15( + q31_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Converts the elements of the Q31 vector to Q7 vector. + * @param[in] *pSrc is input pointer + * @param[out] *pDst is output pointer + * @param[in] blockSize is the number of samples to process + * @return none. + */ + void arm_q31_to_q7( + q31_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Converts the elements of the Q15 vector to floating-point vector. + * @param[in] *pSrc is input pointer + * @param[out] *pDst is output pointer + * @param[in] blockSize is the number of samples to process + * @return none. + */ + void arm_q15_to_float( + q15_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to Q31 vector. + * @param[in] *pSrc is input pointer + * @param[out] *pDst is output pointer + * @param[in] blockSize is the number of samples to process + * @return none. + */ + void arm_q15_to_q31( + q15_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to Q7 vector. + * @param[in] *pSrc is input pointer + * @param[out] *pDst is output pointer + * @param[in] blockSize is the number of samples to process + * @return none. + */ + void arm_q15_to_q7( + q15_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @ingroup groupInterpolation + */ + + /** + * @defgroup BilinearInterpolate Bilinear Interpolation + * + * Bilinear interpolation is an extension of linear interpolation applied to a two dimensional grid. + * The underlying function <code>f(x, y)</code> is sampled on a regular grid and the interpolation process + * determines values between the grid points. + * Bilinear interpolation is equivalent to two step linear interpolation, first in the x-dimension and then in the y-dimension. + * Bilinear interpolation is often used in image processing to rescale images. + * The CMSIS DSP library provides bilinear interpolation functions for Q7, Q15, Q31, and floating-point data types. + * + * <b>Algorithm</b> + * \par + * The instance structure used by the bilinear interpolation functions describes a two dimensional data table. + * For floating-point, the instance structure is defined as: + * <pre> + * typedef struct + * { + * uint16_t numRows; + * uint16_t numCols; + * float32_t *pData; + * } arm_bilinear_interp_instance_f32; + * </pre> + * + * \par + * where <code>numRows</code> specifies the number of rows in the table; + * <code>numCols</code> specifies the number of columns in the table; + * and <code>pData</code> points to an array of size <code>numRows*numCols</code> values. + * The data table <code>pTable</code> is organized in row order and the supplied data values fall on integer indexes. + * That is, table element (x,y) is located at <code>pTable[x + y*numCols]</code> where x and y are integers. + * + * \par + * Let <code>(x, y)</code> specify the desired interpolation point. Then define: + * <pre> + * XF = floor(x) + * YF = floor(y) + * </pre> + * \par + * The interpolated output point is computed as: + * <pre> + * f(x, y) = f(XF, YF) * (1-(x-XF)) * (1-(y-YF)) + * + f(XF+1, YF) * (x-XF)*(1-(y-YF)) + * + f(XF, YF+1) * (1-(x-XF))*(y-YF) + * + f(XF+1, YF+1) * (x-XF)*(y-YF) + * </pre> + * Note that the coordinates (x, y) contain integer and fractional components. + * The integer components specify which portion of the table to use while the + * fractional components control the interpolation processor. + * + * \par + * if (x,y) are outside of the table boundary, Bilinear interpolation returns zero output. + */ + + /** + * @addtogroup BilinearInterpolate + * @{ + */ + + /** + * + * @brief Floating-point bilinear interpolation. + * @param[in,out] *S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate. + * @param[in] Y interpolation coordinate. + * @return out interpolated value. + */ + + + __STATIC_INLINE float32_t arm_bilinear_interp_f32( + const arm_bilinear_interp_instance_f32 * S, + float32_t X, + float32_t Y) + { + float32_t out; + float32_t f00, f01, f10, f11; + float32_t *pData = S->pData; + int32_t xIndex, yIndex, index; + float32_t xdiff, ydiff; + float32_t b1, b2, b3, b4; + + xIndex = (int32_t) X; + yIndex = (int32_t) Y; + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if(xIndex < 0 || xIndex > (S->numRows - 1) || yIndex < 0 + || yIndex > (S->numCols - 1)) + { + return (0); + } + + /* Calculation of index for two nearest points in X-direction */ + index = (xIndex - 1) + (yIndex - 1) * S->numCols; + + + /* Read two nearest points in X-direction */ + f00 = pData[index]; + f01 = pData[index + 1]; + + /* Calculation of index for two nearest points in Y-direction */ + index = (xIndex - 1) + (yIndex) * S->numCols; + + + /* Read two nearest points in Y-direction */ + f10 = pData[index]; + f11 = pData[index + 1]; + + /* Calculation of intermediate values */ + b1 = f00; + b2 = f01 - f00; + b3 = f10 - f00; + b4 = f00 - f01 - f10 + f11; + + /* Calculation of fractional part in X */ + xdiff = X - xIndex; + + /* Calculation of fractional part in Y */ + ydiff = Y - yIndex; + + /* Calculation of bi-linear interpolated output */ + out = b1 + b2 * xdiff + b3 * ydiff + b4 * xdiff * ydiff; + + /* return to application */ + return (out); + + } + + /** + * + * @brief Q31 bilinear interpolation. + * @param[in,out] *S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + + __STATIC_INLINE q31_t arm_bilinear_interp_q31( + arm_bilinear_interp_instance_q31 * S, + q31_t X, + q31_t Y) + { + q31_t out; /* Temporary output */ + q31_t acc = 0; /* output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q31_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q31_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & 0xFFF00000) >> 20u); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & 0xFFF00000) >> 20u); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* shift left xfract by 11 to keep 1.31 format */ + xfract = (X & 0x000FFFFF) << 11u; + + /* Read two nearest output values from the index */ + x1 = pYData[(rI) + nCols * (cI)]; + x2 = pYData[(rI) + nCols * (cI) + 1u]; + + /* 20 bits for the fractional part */ + /* shift left yfract by 11 to keep 1.31 format */ + yfract = (Y & 0x000FFFFF) << 11u; + + /* Read two nearest output values from the index */ + y1 = pYData[(rI) + nCols * (cI + 1)]; + y2 = pYData[(rI) + nCols * (cI + 1) + 1u]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 3.29(q29) format */ + out = ((q31_t) (((q63_t) x1 * (0x7FFFFFFF - xfract)) >> 32)); + acc = ((q31_t) (((q63_t) out * (0x7FFFFFFF - yfract)) >> 32)); + + /* x2 * (xfract) * (1-yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) x2 * (0x7FFFFFFF - yfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (xfract) >> 32)); + + /* y1 * (1 - xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y1 * (0x7FFFFFFF - xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); + + /* y2 * (xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y2 * (xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); + + /* Convert acc to 1.31(q31) format */ + return (acc << 2u); + + } + + /** + * @brief Q15 bilinear interpolation. + * @param[in,out] *S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + + __STATIC_INLINE q15_t arm_bilinear_interp_q15( + arm_bilinear_interp_instance_q15 * S, + q31_t X, + q31_t Y) + { + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q15_t x1, x2, y1, y2; /* Nearest output values */ + q31_t xfract, yfract; /* X, Y fractional parts */ + int32_t rI, cI; /* Row and column indices */ + q15_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & 0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & 0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & 0x000FFFFF); + + /* Read two nearest output values from the index */ + x1 = pYData[(rI) + nCols * (cI)]; + x2 = pYData[(rI) + nCols * (cI) + 1u]; + + + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y1 = pYData[(rI) + nCols * (cI + 1)]; + y2 = pYData[(rI) + nCols * (cI + 1) + 1u]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 13.51 format */ + + /* x1 is in 1.15(q15), xfract in 12.20 format and out is in 13.35 format */ + /* convert 13.35 to 13.31 by right shifting and out is in 1.31 */ + out = (q31_t) (((q63_t) x1 * (0xFFFFF - xfract)) >> 4u); + acc = ((q63_t) out * (0xFFFFF - yfract)); + + /* x2 * (xfract) * (1-yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) x2 * (0xFFFFF - yfract)) >> 4u); + acc += ((q63_t) out * (xfract)); + + /* y1 * (1 - xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y1 * (0xFFFFF - xfract)) >> 4u); + acc += ((q63_t) out * (yfract)); + + /* y2 * (xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y2 * (xfract)) >> 4u); + acc += ((q63_t) out * (yfract)); + + /* acc is in 13.51 format and down shift acc by 36 times */ + /* Convert out to 1.15 format */ + return (acc >> 36); + + } + + /** + * @brief Q7 bilinear interpolation. + * @param[in,out] *S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + + __STATIC_INLINE q7_t arm_bilinear_interp_q7( + arm_bilinear_interp_instance_q7 * S, + q31_t X, + q31_t Y) + { + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q7_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q7_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & 0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & 0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if(rI < 0 || rI > (S->numRows - 1) || cI < 0 || cI > (S->numCols - 1)) + { + return (0); + } + + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & 0x000FFFFF); + + /* Read two nearest output values from the index */ + x1 = pYData[(rI) + nCols * (cI)]; + x2 = pYData[(rI) + nCols * (cI) + 1u]; + + + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y1 = pYData[(rI) + nCols * (cI + 1)]; + y2 = pYData[(rI) + nCols * (cI + 1) + 1u]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 16.47 format */ + out = ((x1 * (0xFFFFF - xfract))); + acc = (((q63_t) out * (0xFFFFF - yfract))); + + /* x2 * (xfract) * (1-yfract) in 2.22 and adding to acc */ + out = ((x2 * (0xFFFFF - yfract))); + acc += (((q63_t) out * (xfract))); + + /* y1 * (1 - xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y1 * (0xFFFFF - xfract))); + acc += (((q63_t) out * (yfract))); + + /* y2 * (xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y2 * (yfract))); + acc += (((q63_t) out * (xfract))); + + /* acc in 16.47 format and down shift by 40 to convert to 1.7 format */ + return (acc >> 40); + + } + + /** + * @} end of BilinearInterpolate group + */ + + + + + + +#ifdef __cplusplus +} +#endif + + +#endif /* _ARM_MATH_H */ + + +/** + * + * End of file. + */ diff --git a/teensy3/avr/eeprom.h b/teensy3/avr/eeprom.h new file mode 100644 index 0000000000000000000000000000000000000000..d63ec09216cb7d079d77c6c37742a88081f39748 --- /dev/null +++ b/teensy3/avr/eeprom.h @@ -0,0 +1,9 @@ +#ifndef _AVR_EEPROM_H_ +#define _AVR_EEPROM_H_ 1 + +#include <stddef.h> +#include <stdint.h> + +#define E2END 0x80 + +#endif diff --git a/teensy3/avr/interrupt.h b/teensy3/avr/interrupt.h new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/teensy3/avr/io.h b/teensy3/avr/io.h new file mode 100644 index 0000000000000000000000000000000000000000..489948146bf84d6cb93992d4971ee8585418a8e1 --- /dev/null +++ b/teensy3/avr/io.h @@ -0,0 +1 @@ +#include "../avr_emulation.h" diff --git a/teensy3/avr/pgmspace.h b/teensy3/avr/pgmspace.h new file mode 100644 index 0000000000000000000000000000000000000000..7594d6dfbcfff0afd1fe892388a5503d3eadd6bb --- /dev/null +++ b/teensy3/avr/pgmspace.h @@ -0,0 +1,44 @@ +#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 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 diff --git a/teensy3/avr_emulation.h b/teensy3/avr_emulation.h new file mode 100644 index 0000000000000000000000000000000000000000..98cf9e10f0aacfde3bd46e1dc3347588fedf380d --- /dev/null +++ b/teensy3/avr_emulation.h @@ -0,0 +1,1125 @@ +/* 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_emulation_h_ +#define _avr_emulation_h_ + +#include "mk20dx128.h" +#include "core_pins.h" +#include "pins_arduino.h" + +#ifdef __cplusplus + +#define GPIO_BITBAND_ADDR(reg, bit) (((uint32_t)&(reg) - 0x40000000) * 32 + (bit) * 4 + 0x42000000) +#define GPIO_BITBAND(reg, bit) (*(uint32_t *)GPIO_BITBAND_ADDR((reg), (bit))) +#define CONFIG_PULLUP (PORT_PCR_MUX(1) | PORT_PCR_PE | PORT_PCR_PS) +#define CONFIG_NOPULLUP (PORT_PCR_MUX(1)) + +class PORTDemulation +{ +public: + inline PORTDemulation & operator = (int val) __attribute__((always_inline)) { + digitalWriteFast(0, (val & (1<<0))); + if (!(CORE_PIN0_DDRREG & CORE_PIN0_BIT)) + CORE_PIN0_CONFIG = ((val & (1<<0)) ? CONFIG_PULLUP : CONFIG_NOPULLUP); + digitalWriteFast(1, (val & (1<<1))); + if (!(CORE_PIN1_DDRREG & CORE_PIN1_BIT)) + CORE_PIN1_CONFIG = ((val & (1<<1)) ? CONFIG_PULLUP : CONFIG_NOPULLUP); + digitalWriteFast(2, (val & (1<<2))); + if (!(CORE_PIN2_DDRREG & CORE_PIN2_BIT)) + CORE_PIN2_CONFIG = ((val & (1<<2)) ? CONFIG_PULLUP : CONFIG_NOPULLUP); + digitalWriteFast(3, (val & (1<<3))); + if (!(CORE_PIN3_DDRREG & CORE_PIN3_BIT)) + CORE_PIN3_CONFIG = ((val & (1<<3)) ? CONFIG_PULLUP : CONFIG_NOPULLUP); + digitalWriteFast(4, (val & (1<<4))); + if (!(CORE_PIN4_DDRREG & CORE_PIN4_BIT)) + CORE_PIN4_CONFIG = ((val & (1<<4)) ? CONFIG_PULLUP : CONFIG_NOPULLUP); + digitalWriteFast(5, (val & (1<<5))); + if (!(CORE_PIN5_DDRREG & CORE_PIN5_BIT)) + CORE_PIN5_CONFIG = ((val & (1<<5)) ? CONFIG_PULLUP : CONFIG_NOPULLUP); + digitalWriteFast(6, (val & (1<<6))); + if (!(CORE_PIN6_DDRREG & CORE_PIN6_BIT)) + CORE_PIN6_CONFIG = ((val & (1<<6)) ? CONFIG_PULLUP : CONFIG_NOPULLUP); + digitalWriteFast(7, (val & (1<<7))); + if (!(CORE_PIN7_DDRREG & CORE_PIN7_BIT)) + CORE_PIN7_CONFIG = ((val & (1<<7)) ? CONFIG_PULLUP : CONFIG_NOPULLUP); + return *this; + } + inline PORTDemulation & operator |= (int val) __attribute__((always_inline)) { + if (val & (1<<0)) { + digitalWriteFast(0, HIGH); + if (!(CORE_PIN0_DDRREG & CORE_PIN0_BIT)) CORE_PIN0_CONFIG = CONFIG_PULLUP; + } + if (val & (1<<1)) { + digitalWriteFast(1, HIGH); + if (!(CORE_PIN1_DDRREG & CORE_PIN1_BIT)) CORE_PIN1_CONFIG = CONFIG_PULLUP; + } + if (val & (1<<2)) { + digitalWriteFast(2, HIGH); + if (!(CORE_PIN2_DDRREG & CORE_PIN2_BIT)) CORE_PIN2_CONFIG = CONFIG_PULLUP; + } + if (val & (1<<3)) { + digitalWriteFast(3, HIGH); + if (!(CORE_PIN3_DDRREG & CORE_PIN3_BIT)) CORE_PIN3_CONFIG = CONFIG_PULLUP; + } + if (val & (1<<4)) { + digitalWriteFast(4, HIGH); + if (!(CORE_PIN4_DDRREG & CORE_PIN4_BIT)) CORE_PIN4_CONFIG = CONFIG_PULLUP; + } + if (val & (1<<5)) { + digitalWriteFast(5, HIGH); + if (!(CORE_PIN5_DDRREG & CORE_PIN5_BIT)) CORE_PIN5_CONFIG = CONFIG_PULLUP; + } + if (val & (1<<6)) { + digitalWriteFast(6, HIGH); + if (!(CORE_PIN6_DDRREG & CORE_PIN6_BIT)) CORE_PIN6_CONFIG = CONFIG_PULLUP; + } + if (val & (1<<7)) { + digitalWriteFast(7, HIGH); + if (!(CORE_PIN7_DDRREG & CORE_PIN7_BIT)) CORE_PIN7_CONFIG = CONFIG_PULLUP; + } + return *this; + } + inline PORTDemulation & operator &= (int val) __attribute__((always_inline)) { + if (!(val & (1<<0))) { + digitalWriteFast(0, LOW); + if (!(CORE_PIN0_DDRREG & CORE_PIN0_BIT)) CORE_PIN0_CONFIG = CONFIG_NOPULLUP; + } + if (!(val & (1<<1))) { + digitalWriteFast(1, LOW); + if (!(CORE_PIN1_DDRREG & CORE_PIN1_BIT)) CORE_PIN1_CONFIG = CONFIG_NOPULLUP; + } + if (!(val & (1<<2))) { + digitalWriteFast(2, LOW); + if (!(CORE_PIN2_DDRREG & CORE_PIN2_BIT)) CORE_PIN2_CONFIG = CONFIG_NOPULLUP; + } + if (!(val & (1<<3))) { + digitalWriteFast(3, LOW); + if (!(CORE_PIN3_DDRREG & CORE_PIN3_BIT)) CORE_PIN3_CONFIG = CONFIG_NOPULLUP; + } + if (!(val & (1<<4))) { + digitalWriteFast(4, LOW); + if (!(CORE_PIN4_DDRREG & CORE_PIN4_BIT)) CORE_PIN4_CONFIG = CONFIG_NOPULLUP; + } + if (!(val & (1<<5))) { + digitalWriteFast(5, LOW); + if (!(CORE_PIN5_DDRREG & CORE_PIN5_BIT)) CORE_PIN5_CONFIG = CONFIG_NOPULLUP; + } + if (!(val & (1<<6))) { + digitalWriteFast(6, LOW); + if (!(CORE_PIN6_DDRREG & CORE_PIN6_BIT)) CORE_PIN6_CONFIG = CONFIG_NOPULLUP; + } + if (!(val & (1<<7))) { + digitalWriteFast(7, LOW); + if (!(CORE_PIN7_DDRREG & CORE_PIN7_BIT)) CORE_PIN7_CONFIG = CONFIG_NOPULLUP; + } + return *this; + } +}; +extern PORTDemulation PORTD; + +class PINDemulation +{ +public: + inline int operator & (int val) const __attribute__((always_inline)) { + int ret = 0; + if ((val & (1<<0)) && digitalReadFast(0)) ret |= (1<<0); + if ((val & (1<<1)) && digitalReadFast(1)) ret |= (1<<1); + if ((val & (1<<2)) && digitalReadFast(2)) ret |= (1<<2); + if ((val & (1<<3)) && digitalReadFast(3)) ret |= (1<<3); + if ((val & (1<<4)) && digitalReadFast(4)) ret |= (1<<4); + if ((val & (1<<5)) && digitalReadFast(5)) ret |= (1<<5); + if ((val & (1<<6)) && digitalReadFast(6)) ret |= (1<<6); + if ((val & (1<<7)) && digitalReadFast(7)) ret |= (1<<7); + return ret; + } + operator int () const __attribute__((always_inline)) { + int ret = 0; + if (digitalReadFast(0)) ret |= (1<<0); + if (digitalReadFast(1)) ret |= (1<<1); + if (digitalReadFast(2)) ret |= (1<<2); + if (digitalReadFast(3)) ret |= (1<<3); + if (digitalReadFast(4)) ret |= (1<<4); + if (digitalReadFast(5)) ret |= (1<<5); + if (digitalReadFast(6)) ret |= (1<<6); + if (digitalReadFast(7)) ret |= (1<<7); + return ret; + } +}; +extern PINDemulation PIND; + +class DDRDemulation +{ +public: + inline DDRDemulation & operator = (int val) __attribute__((always_inline)) { + if (val & (1<<0)) set0(); else clr0(); + if (val & (1<<1)) set1(); else clr1(); + if (val & (1<<2)) set2(); else clr2(); + if (val & (1<<3)) set3(); else clr3(); + if (val & (1<<4)) set4(); else clr4(); + if (val & (1<<5)) set5(); else clr5(); + if (val & (1<<6)) set6(); else clr6(); + if (val & (1<<7)) set7(); else clr7(); + return *this; + } + inline DDRDemulation & operator |= (int val) __attribute__((always_inline)) { + if (val & (1<<0)) set0(); + if (val & (1<<1)) set1(); + if (val & (1<<2)) set2(); + if (val & (1<<3)) set3(); + if (val & (1<<4)) set4(); + if (val & (1<<5)) set5(); + if (val & (1<<6)) set6(); + if (val & (1<<7)) set7(); + return *this; + } + inline DDRDemulation & operator &= (int val) __attribute__((always_inline)) { + if (!(val & (1<<0))) clr0(); + if (!(val & (1<<1))) clr1(); + if (!(val & (1<<2))) clr2(); + if (!(val & (1<<3))) clr3(); + if (!(val & (1<<4))) clr4(); + if (!(val & (1<<5))) clr5(); + if (!(val & (1<<6))) clr6(); + if (!(val & (1<<7))) clr7(); + return *this; + } +private: + inline void set0() __attribute__((always_inline)) { + GPIO_BITBAND(CORE_PIN0_DDRREG, CORE_PIN0_BIT) = 1; + CORE_PIN0_CONFIG = CONFIG_PULLUP; + } + inline void set1() __attribute__((always_inline)) { + GPIO_BITBAND(CORE_PIN1_DDRREG, CORE_PIN1_BIT) = 1; + CORE_PIN1_CONFIG = CONFIG_PULLUP; + } + inline void set2() __attribute__((always_inline)) { + GPIO_BITBAND(CORE_PIN2_DDRREG, CORE_PIN2_BIT) = 1; + CORE_PIN2_CONFIG = CONFIG_PULLUP; + } + inline void set3() __attribute__((always_inline)) { + GPIO_BITBAND(CORE_PIN3_DDRREG, CORE_PIN3_BIT) = 1; + CORE_PIN3_CONFIG = CONFIG_PULLUP; + } + inline void set4() __attribute__((always_inline)) { + GPIO_BITBAND(CORE_PIN4_DDRREG, CORE_PIN4_BIT) = 1; + CORE_PIN4_CONFIG = CONFIG_PULLUP; + } + inline void set5() __attribute__((always_inline)) { + GPIO_BITBAND(CORE_PIN5_DDRREG, CORE_PIN5_BIT) = 1; + CORE_PIN5_CONFIG = CONFIG_PULLUP; + } + inline void set6() __attribute__((always_inline)) { + GPIO_BITBAND(CORE_PIN6_DDRREG, CORE_PIN6_BIT) = 1; + CORE_PIN6_CONFIG = CONFIG_PULLUP; + } + inline void set7() __attribute__((always_inline)) { + GPIO_BITBAND(CORE_PIN7_DDRREG, CORE_PIN7_BIT) = 1; + CORE_PIN7_CONFIG = CONFIG_PULLUP; + } + inline void clr0() __attribute__((always_inline)) { + CORE_PIN0_CONFIG = ((CORE_PIN0_PORTREG & CORE_PIN0_BITMASK) + ? CONFIG_PULLUP : CONFIG_NOPULLUP); + GPIO_BITBAND(CORE_PIN0_DDRREG, CORE_PIN0_BIT) = 0; + } + inline void clr1() __attribute__((always_inline)) { + CORE_PIN1_CONFIG = ((CORE_PIN1_PORTREG & CORE_PIN1_BITMASK) + ? CONFIG_PULLUP : CONFIG_NOPULLUP); + GPIO_BITBAND(CORE_PIN1_DDRREG, CORE_PIN1_BIT) = 0; + } + inline void clr2() __attribute__((always_inline)) { + CORE_PIN2_CONFIG = ((CORE_PIN2_PORTREG & CORE_PIN2_BITMASK) + ? CONFIG_PULLUP : CONFIG_NOPULLUP); + GPIO_BITBAND(CORE_PIN2_DDRREG, CORE_PIN2_BIT) = 0; + } + inline void clr3() __attribute__((always_inline)) { + CORE_PIN3_CONFIG = ((CORE_PIN3_PORTREG & CORE_PIN3_BITMASK) + ? CONFIG_PULLUP : CONFIG_NOPULLUP); + GPIO_BITBAND(CORE_PIN3_DDRREG, CORE_PIN3_BIT) = 0; + } + inline void clr4() __attribute__((always_inline)) { + CORE_PIN4_CONFIG = ((CORE_PIN4_PORTREG & CORE_PIN4_BITMASK) + ? CONFIG_PULLUP : CONFIG_NOPULLUP); + GPIO_BITBAND(CORE_PIN4_DDRREG, CORE_PIN4_BIT) = 0; + } + inline void clr5() __attribute__((always_inline)) { + CORE_PIN5_CONFIG = ((CORE_PIN5_PORTREG & CORE_PIN5_BITMASK) + ? CONFIG_PULLUP : CONFIG_NOPULLUP); + GPIO_BITBAND(CORE_PIN5_DDRREG, CORE_PIN5_BIT) = 0; + } + inline void clr6() __attribute__((always_inline)) { + CORE_PIN6_CONFIG = ((CORE_PIN6_PORTREG & CORE_PIN6_BITMASK) + ? CONFIG_PULLUP : CONFIG_NOPULLUP); + GPIO_BITBAND(CORE_PIN6_DDRREG, CORE_PIN6_BIT) = 0; + } + inline void clr7() __attribute__((always_inline)) { + CORE_PIN7_CONFIG = ((CORE_PIN7_PORTREG & CORE_PIN7_BITMASK) + ? CONFIG_PULLUP : CONFIG_NOPULLUP); + GPIO_BITBAND(CORE_PIN7_DDRREG, CORE_PIN7_BIT) = 0; + } +}; + +extern DDRDemulation DDRD; + + + + + + +class PORTBemulation +{ +public: + inline PORTBemulation & operator = (int val) __attribute__((always_inline)) { + digitalWriteFast(8, (val & (1<<0))); + if (!(CORE_PIN8_DDRREG & CORE_PIN8_BIT)) + CORE_PIN8_CONFIG = ((val & (1<<0)) ? CONFIG_PULLUP : CONFIG_NOPULLUP); + digitalWriteFast(9, (val & (1<<1))); + if (!(CORE_PIN9_DDRREG & CORE_PIN9_BIT)) + CORE_PIN9_CONFIG = ((val & (1<<1)) ? CONFIG_PULLUP : CONFIG_NOPULLUP); + digitalWriteFast(10, (val & (1<<2))); + if (!(CORE_PIN10_DDRREG & CORE_PIN10_BIT)) + CORE_PIN10_CONFIG = ((val & (1<<2)) ? CONFIG_PULLUP : CONFIG_NOPULLUP); + digitalWriteFast(11, (val & (1<<3))); + if (!(CORE_PIN11_DDRREG & CORE_PIN11_BIT)) + CORE_PIN11_CONFIG = ((val & (1<<3)) ? CONFIG_PULLUP : CONFIG_NOPULLUP); + digitalWriteFast(12, (val & (1<<4))); + if (!(CORE_PIN12_DDRREG & CORE_PIN12_BIT)) + CORE_PIN12_CONFIG = ((val & (1<<4)) ? CONFIG_PULLUP : CONFIG_NOPULLUP); + digitalWriteFast(13, (val & (1<<5))); + if (!(CORE_PIN13_DDRREG & CORE_PIN13_BIT)) + CORE_PIN13_CONFIG = ((val & (1<<5)) ? CONFIG_PULLUP : CONFIG_NOPULLUP); + return *this; + } + inline PORTBemulation & operator |= (int val) __attribute__((always_inline)) { + if (val & (1<<0)) { + digitalWriteFast(8, HIGH); + if (!(CORE_PIN7_DDRREG & CORE_PIN7_BIT)) CORE_PIN8_CONFIG = CONFIG_PULLUP; + } + if (val & (1<<1)) { + digitalWriteFast(9, HIGH); + if (!(CORE_PIN7_DDRREG & CORE_PIN7_BIT)) CORE_PIN9_CONFIG = CONFIG_PULLUP; + } + if (val & (1<<2)) { + digitalWriteFast(10, HIGH); + if (!(CORE_PIN10_DDRREG & CORE_PIN10_BIT)) CORE_PIN10_CONFIG = CONFIG_PULLUP; + } + if (val & (1<<3)) { + digitalWriteFast(11, HIGH); + if (!(CORE_PIN11_DDRREG & CORE_PIN11_BIT)) CORE_PIN11_CONFIG = CONFIG_PULLUP; + } + if (val & (1<<4)) { + digitalWriteFast(12, HIGH); + if (!(CORE_PIN12_DDRREG & CORE_PIN12_BIT)) CORE_PIN12_CONFIG = CONFIG_PULLUP; + } + if (val & (1<<5)) { + digitalWriteFast(13, HIGH); + if (!(CORE_PIN13_DDRREG & CORE_PIN13_BIT)) CORE_PIN13_CONFIG = CONFIG_PULLUP; + } + return *this; + } + inline PORTBemulation & operator &= (int val) __attribute__((always_inline)) { + if (!(val & (1<<0))) { + digitalWriteFast(8, LOW); + if (!(CORE_PIN8_DDRREG & CORE_PIN8_BIT)) CORE_PIN8_CONFIG = CONFIG_NOPULLUP; + } + if (!(val & (1<<1))) { + digitalWriteFast(9, LOW); + if (!(CORE_PIN9_DDRREG & CORE_PIN9_BIT)) CORE_PIN9_CONFIG = CONFIG_NOPULLUP; + } + if (!(val & (1<<2))) { + digitalWriteFast(10, LOW); + if (!(CORE_PIN10_DDRREG & CORE_PIN10_BIT)) CORE_PIN10_CONFIG = CONFIG_NOPULLUP; + } + if (!(val & (1<<3))) { + digitalWriteFast(11, LOW); + if (!(CORE_PIN11_DDRREG & CORE_PIN11_BIT)) CORE_PIN11_CONFIG = CONFIG_NOPULLUP; + } + if (!(val & (1<<4))) { + digitalWriteFast(12, LOW); + if (!(CORE_PIN12_DDRREG & CORE_PIN12_BIT)) CORE_PIN12_CONFIG = CONFIG_NOPULLUP; + } + if (!(val & (1<<5))) { + digitalWriteFast(13, LOW); + if (!(CORE_PIN13_DDRREG & CORE_PIN13_BIT)) CORE_PIN13_CONFIG = CONFIG_NOPULLUP; + } + return *this; + } +}; +extern PORTBemulation PORTB; + +class PINBemulation +{ +public: + inline int operator & (int val) const __attribute__((always_inline)) { + int ret = 0; + if ((val & (1<<0)) && digitalReadFast(8)) ret |= (1<<0); + if ((val & (1<<1)) && digitalReadFast(9)) ret |= (1<<1); + if ((val & (1<<2)) && digitalReadFast(10)) ret |= (1<<2); + if ((val & (1<<3)) && digitalReadFast(11)) ret |= (1<<3); + if ((val & (1<<4)) && digitalReadFast(12)) ret |= (1<<4); + if ((val & (1<<5)) && digitalReadFast(13)) ret |= (1<<5); + return ret; + } + operator int () const __attribute__((always_inline)) { + int ret = 0; + if (digitalReadFast(8)) ret |= (1<<0); + if (digitalReadFast(9)) ret |= (1<<1); + if (digitalReadFast(10)) ret |= (1<<2); + if (digitalReadFast(11)) ret |= (1<<3); + if (digitalReadFast(12)) ret |= (1<<4); + if (digitalReadFast(13)) ret |= (1<<5); + return ret; + } +}; +extern PINBemulation PINB; + +class DDRBemulation +{ +public: + inline DDRBemulation & operator = (int val) __attribute__((always_inline)) { + if (val & (1<<0)) set0(); else clr0(); + if (val & (1<<1)) set1(); else clr1(); + if (val & (1<<2)) set2(); else clr2(); + if (val & (1<<3)) set3(); else clr3(); + if (val & (1<<4)) set4(); else clr4(); + if (val & (1<<5)) set5(); else clr5(); + return *this; + } + inline DDRBemulation & operator |= (int val) __attribute__((always_inline)) { + if (val & (1<<0)) set0(); + if (val & (1<<1)) set1(); + if (val & (1<<2)) set2(); + if (val & (1<<3)) set3(); + if (val & (1<<4)) set4(); + if (val & (1<<5)) set5(); + return *this; + } + inline DDRBemulation & operator &= (int val) __attribute__((always_inline)) { + if (!(val & (1<<0))) clr0(); + if (!(val & (1<<1))) clr1(); + if (!(val & (1<<2))) clr2(); + if (!(val & (1<<3))) clr3(); + if (!(val & (1<<4))) clr4(); + if (!(val & (1<<5))) clr5(); + return *this; + } +private: + inline void set0() __attribute__((always_inline)) { + GPIO_BITBAND(CORE_PIN8_DDRREG, CORE_PIN8_BIT) = 1; + CORE_PIN8_CONFIG = CONFIG_PULLUP; + } + inline void set1() __attribute__((always_inline)) { + GPIO_BITBAND(CORE_PIN9_DDRREG, CORE_PIN9_BIT) = 1; + CORE_PIN9_CONFIG = CONFIG_PULLUP; + } + inline void set2() __attribute__((always_inline)) { + GPIO_BITBAND(CORE_PIN10_DDRREG, CORE_PIN10_BIT) = 1; + CORE_PIN10_CONFIG = CONFIG_PULLUP; + } + inline void set3() __attribute__((always_inline)) { + GPIO_BITBAND(CORE_PIN11_DDRREG, CORE_PIN11_BIT) = 1; + CORE_PIN11_CONFIG = CONFIG_PULLUP; + } + inline void set4() __attribute__((always_inline)) { + GPIO_BITBAND(CORE_PIN12_DDRREG, CORE_PIN12_BIT) = 1; + CORE_PIN12_CONFIG = CONFIG_PULLUP; + } + inline void set5() __attribute__((always_inline)) { + GPIO_BITBAND(CORE_PIN13_DDRREG, CORE_PIN13_BIT) = 1; + CORE_PIN13_CONFIG = CONFIG_PULLUP; + } + inline void clr0() __attribute__((always_inline)) { + CORE_PIN8_CONFIG = ((CORE_PIN8_PORTREG & CORE_PIN8_BITMASK) + ? CONFIG_PULLUP : CONFIG_NOPULLUP); + GPIO_BITBAND(CORE_PIN8_DDRREG, CORE_PIN8_BIT) = 0; + } + inline void clr1() __attribute__((always_inline)) { + CORE_PIN9_CONFIG = ((CORE_PIN9_PORTREG & CORE_PIN9_BITMASK) + ? CONFIG_PULLUP : CONFIG_NOPULLUP); + GPIO_BITBAND(CORE_PIN9_DDRREG, CORE_PIN9_BIT) = 0; + } + inline void clr2() __attribute__((always_inline)) { + CORE_PIN10_CONFIG = ((CORE_PIN10_PORTREG & CORE_PIN10_BITMASK) + ? CONFIG_PULLUP : CONFIG_NOPULLUP); + GPIO_BITBAND(CORE_PIN10_DDRREG, CORE_PIN10_BIT) = 0; + } + inline void clr3() __attribute__((always_inline)) { + CORE_PIN11_CONFIG = ((CORE_PIN11_PORTREG & CORE_PIN11_BITMASK) + ? CONFIG_PULLUP : CONFIG_NOPULLUP); + GPIO_BITBAND(CORE_PIN11_DDRREG, CORE_PIN11_BIT) = 0; + } + inline void clr4() __attribute__((always_inline)) { + CORE_PIN12_CONFIG = ((CORE_PIN12_PORTREG & CORE_PIN12_BITMASK) + ? CONFIG_PULLUP : CONFIG_NOPULLUP); + GPIO_BITBAND(CORE_PIN12_DDRREG, CORE_PIN12_BIT) = 0; + } + inline void clr5() __attribute__((always_inline)) { + CORE_PIN13_CONFIG = ((CORE_PIN13_PORTREG & CORE_PIN13_BITMASK) + ? CONFIG_PULLUP : CONFIG_NOPULLUP); + GPIO_BITBAND(CORE_PIN13_DDRREG, CORE_PIN13_BIT) = 0; + } +}; + +extern DDRBemulation DDRB; + + + + + + +class PORTCemulation +{ +public: + inline PORTCemulation & operator = (int val) __attribute__((always_inline)) { + digitalWriteFast(14, (val & (1<<0))); + if (!(CORE_PIN14_DDRREG & CORE_PIN14_BIT)) + CORE_PIN14_CONFIG = ((val & (1<<0)) ? CONFIG_PULLUP : CONFIG_NOPULLUP); + digitalWriteFast(15, (val & (1<<1))); + if (!(CORE_PIN15_DDRREG & CORE_PIN15_BIT)) + CORE_PIN15_CONFIG = ((val & (1<<1)) ? CONFIG_PULLUP : CONFIG_NOPULLUP); + digitalWriteFast(16, (val & (1<<2))); + if (!(CORE_PIN16_DDRREG & CORE_PIN16_BIT)) + CORE_PIN16_CONFIG = ((val & (1<<2)) ? CONFIG_PULLUP : CONFIG_NOPULLUP); + digitalWriteFast(17, (val & (1<<3))); + if (!(CORE_PIN17_DDRREG & CORE_PIN17_BIT)) + CORE_PIN17_CONFIG = ((val & (1<<3)) ? CONFIG_PULLUP : CONFIG_NOPULLUP); + digitalWriteFast(18, (val & (1<<4))); + if (!(CORE_PIN18_DDRREG & CORE_PIN18_BIT)) + CORE_PIN18_CONFIG = ((val & (1<<4)) ? CONFIG_PULLUP : CONFIG_NOPULLUP); + digitalWriteFast(19, (val & (1<<5))); + if (!(CORE_PIN19_DDRREG & CORE_PIN19_BIT)) + CORE_PIN19_CONFIG = ((val & (1<<5)) ? CONFIG_PULLUP : CONFIG_NOPULLUP); + return *this; + } + inline PORTCemulation & operator |= (int val) __attribute__((always_inline)) { + if (val & (1<<0)) { + digitalWriteFast(14, HIGH); + if (!(CORE_PIN14_DDRREG & CORE_PIN14_BIT)) CORE_PIN14_CONFIG = CONFIG_PULLUP; + } + if (val & (1<<1)) { + digitalWriteFast(15, HIGH); + if (!(CORE_PIN15_DDRREG & CORE_PIN15_BIT)) CORE_PIN15_CONFIG = CONFIG_PULLUP; + } + if (val & (1<<2)) { + digitalWriteFast(16, HIGH); + if (!(CORE_PIN16_DDRREG & CORE_PIN16_BIT)) CORE_PIN16_CONFIG = CONFIG_PULLUP; + } + if (val & (1<<3)) { + digitalWriteFast(17, HIGH); + if (!(CORE_PIN17_DDRREG & CORE_PIN17_BIT)) CORE_PIN17_CONFIG = CONFIG_PULLUP; + } + if (val & (1<<4)) { + digitalWriteFast(18, HIGH); + if (!(CORE_PIN18_DDRREG & CORE_PIN18_BIT)) CORE_PIN18_CONFIG = CONFIG_PULLUP; + } + if (val & (1<<5)) { + digitalWriteFast(19, HIGH); + if (!(CORE_PIN19_DDRREG & CORE_PIN19_BIT)) CORE_PIN19_CONFIG = CONFIG_PULLUP; + } + return *this; + } + inline PORTCemulation & operator &= (int val) __attribute__((always_inline)) { + if (!(val & (1<<0))) { + digitalWriteFast(14, LOW); + if (!(CORE_PIN14_DDRREG & CORE_PIN14_BIT)) CORE_PIN14_CONFIG = CONFIG_NOPULLUP; + } + if (!(val & (1<<1))) { + digitalWriteFast(15, LOW); + if (!(CORE_PIN15_DDRREG & CORE_PIN15_BIT)) CORE_PIN15_CONFIG = CONFIG_NOPULLUP; + } + if (!(val & (1<<2))) { + digitalWriteFast(16, LOW); + if (!(CORE_PIN16_DDRREG & CORE_PIN16_BIT)) CORE_PIN16_CONFIG = CONFIG_NOPULLUP; + } + if (!(val & (1<<3))) { + digitalWriteFast(17, LOW); + if (!(CORE_PIN17_DDRREG & CORE_PIN17_BIT)) CORE_PIN17_CONFIG = CONFIG_NOPULLUP; + } + if (!(val & (1<<4))) { + digitalWriteFast(18, LOW); + if (!(CORE_PIN18_DDRREG & CORE_PIN18_BIT)) CORE_PIN18_CONFIG = CONFIG_NOPULLUP; + } + if (!(val & (1<<5))) { + digitalWriteFast(19, LOW); + if (!(CORE_PIN19_DDRREG & CORE_PIN19_BIT)) CORE_PIN19_CONFIG = CONFIG_NOPULLUP; + } + return *this; + } +}; +extern PORTCemulation PORTC; + +class PINCemulation +{ +public: + inline int operator & (int val) const __attribute__((always_inline)) { + int ret = 0; + if ((val & (1<<0)) && digitalReadFast(8)) ret |= (1<<0); + if ((val & (1<<1)) && digitalReadFast(9)) ret |= (1<<1); + if ((val & (1<<2)) && digitalReadFast(10)) ret |= (1<<2); + if ((val & (1<<3)) && digitalReadFast(11)) ret |= (1<<3); + if ((val & (1<<4)) && digitalReadFast(12)) ret |= (1<<4); + if ((val & (1<<5)) && digitalReadFast(13)) ret |= (1<<5); + return ret; + } + operator int () const __attribute__((always_inline)) { + int ret = 0; + if (digitalReadFast(8)) ret |= (1<<0); + if (digitalReadFast(9)) ret |= (1<<1); + if (digitalReadFast(10)) ret |= (1<<2); + if (digitalReadFast(11)) ret |= (1<<3); + if (digitalReadFast(12)) ret |= (1<<4); + if (digitalReadFast(13)) ret |= (1<<5); + return ret; + } +}; +extern PINCemulation PINC; + +class DDRCemulation +{ +public: + inline DDRCemulation & operator = (int val) __attribute__((always_inline)) { + if (val & (1<<0)) set0(); else clr0(); + if (val & (1<<1)) set1(); else clr1(); + if (val & (1<<2)) set2(); else clr2(); + if (val & (1<<3)) set3(); else clr3(); + if (val & (1<<4)) set4(); else clr4(); + if (val & (1<<5)) set5(); else clr5(); + return *this; + } + inline DDRCemulation & operator |= (int val) __attribute__((always_inline)) { + if (val & (1<<0)) set0(); + if (val & (1<<1)) set1(); + if (val & (1<<2)) set2(); + if (val & (1<<3)) set3(); + if (val & (1<<4)) set4(); + if (val & (1<<5)) set5(); + return *this; + } + inline DDRCemulation & operator &= (int val) __attribute__((always_inline)) { + if (!(val & (1<<0))) clr0(); + if (!(val & (1<<1))) clr1(); + if (!(val & (1<<2))) clr2(); + if (!(val & (1<<3))) clr3(); + if (!(val & (1<<4))) clr4(); + if (!(val & (1<<5))) clr5(); + return *this; + } +private: + inline void set0() __attribute__((always_inline)) { + GPIO_BITBAND(CORE_PIN14_DDRREG, CORE_PIN14_BIT) = 1; + CORE_PIN14_CONFIG = CONFIG_PULLUP; + } + inline void set1() __attribute__((always_inline)) { + GPIO_BITBAND(CORE_PIN15_DDRREG, CORE_PIN15_BIT) = 1; + CORE_PIN15_CONFIG = CONFIG_PULLUP; + } + inline void set2() __attribute__((always_inline)) { + GPIO_BITBAND(CORE_PIN16_DDRREG, CORE_PIN16_BIT) = 1; + CORE_PIN16_CONFIG = CONFIG_PULLUP; + } + inline void set3() __attribute__((always_inline)) { + GPIO_BITBAND(CORE_PIN17_DDRREG, CORE_PIN17_BIT) = 1; + CORE_PIN17_CONFIG = CONFIG_PULLUP; + } + inline void set4() __attribute__((always_inline)) { + GPIO_BITBAND(CORE_PIN18_DDRREG, CORE_PIN18_BIT) = 1; + CORE_PIN18_CONFIG = CONFIG_PULLUP; + } + inline void set5() __attribute__((always_inline)) { + GPIO_BITBAND(CORE_PIN19_DDRREG, CORE_PIN19_BIT) = 1; + CORE_PIN19_CONFIG = CONFIG_PULLUP; + } + inline void clr0() __attribute__((always_inline)) { + CORE_PIN14_CONFIG = ((CORE_PIN14_PORTREG & CORE_PIN14_BITMASK) + ? CONFIG_PULLUP : CONFIG_NOPULLUP); + GPIO_BITBAND(CORE_PIN14_DDRREG, CORE_PIN14_BIT) = 0; + } + inline void clr1() __attribute__((always_inline)) { + CORE_PIN15_CONFIG = ((CORE_PIN15_PORTREG & CORE_PIN15_BITMASK) + ? CONFIG_PULLUP : CONFIG_NOPULLUP); + GPIO_BITBAND(CORE_PIN15_DDRREG, CORE_PIN15_BIT) = 0; + } + inline void clr2() __attribute__((always_inline)) { + CORE_PIN16_CONFIG = ((CORE_PIN16_PORTREG & CORE_PIN16_BITMASK) + ? CONFIG_PULLUP : CONFIG_NOPULLUP); + GPIO_BITBAND(CORE_PIN16_DDRREG, CORE_PIN16_BIT) = 0; + } + inline void clr3() __attribute__((always_inline)) { + CORE_PIN17_CONFIG = ((CORE_PIN17_PORTREG & CORE_PIN17_BITMASK) + ? CONFIG_PULLUP : CONFIG_NOPULLUP); + GPIO_BITBAND(CORE_PIN17_DDRREG, CORE_PIN17_BIT) = 0; + } + inline void clr4() __attribute__((always_inline)) { + CORE_PIN18_CONFIG = ((CORE_PIN18_PORTREG & CORE_PIN18_BITMASK) + ? CONFIG_PULLUP : CONFIG_NOPULLUP); + GPIO_BITBAND(CORE_PIN18_DDRREG, CORE_PIN18_BIT) = 0; + } + inline void clr5() __attribute__((always_inline)) { + CORE_PIN19_CONFIG = ((CORE_PIN19_PORTREG & CORE_PIN19_BITMASK) + ? CONFIG_PULLUP : CONFIG_NOPULLUP); + GPIO_BITBAND(CORE_PIN19_DDRREG, CORE_PIN19_BIT) = 0; + } +}; + +extern DDRCemulation DDRC; + + +#define PINB0 0 +#define PINB1 1 +#define PINB2 2 +#define PINB3 3 +#define PINB4 4 +#define PINB5 5 +#define PINB6 6 +#define PINB7 7 +#define DDB0 0 +#define DDB1 1 +#define DDB2 2 +#define DDB3 3 +#define DDB4 4 +#define DDB5 5 +#define DDB6 6 +#define DDB7 7 +#define PORTB0 0 +#define PORTB1 1 +#define PORTB2 2 +#define PORTB3 3 +#define PORTB4 4 +#define PORTB5 5 +#define PORTB6 6 +#define PORTB7 7 +#define PINC0 0 +#define PINC1 1 +#define PINC2 2 +#define PINC3 3 +#define PINC4 4 +#define PINC5 5 +#define PINC6 6 +#define DDC0 0 +#define DDC1 1 +#define DDC2 2 +#define DDC3 3 +#define DDC4 4 +#define DDC5 5 +#define DDC6 6 +#define PORTC0 0 +#define PORTC1 1 +#define PORTC2 2 +#define PORTC3 3 +#define PORTC4 4 +#define PORTC5 5 +#define PORTC6 6 +#define PIND0 0 +#define PIND1 1 +#define PIND2 2 +#define PIND3 3 +#define PIND4 4 +#define PIND5 5 +#define PIND6 6 +#define PIND7 7 +#define DDD0 0 +#define DDD1 1 +#define DDD2 2 +#define DDD3 3 +#define DDD4 4 +#define DDD5 5 +#define DDD6 6 +#define DDD7 7 +#define PORTD0 0 +#define PORTD1 1 +#define PORTD2 2 +#define PORTD3 3 +#define PORTD4 4 +#define PORTD5 5 +#define PORTD6 6 +#define PORTD7 7 + + + + + +#if 0 +extern "C" { +void serial_print(const char *p); +void serial_phex(uint32_t n); +void serial_phex16(uint32_t n); +void serial_phex32(uint32_t n); +} +#endif + + +// SPI Control Register  SPCR +#define SPIE 7 // SPI Interrupt Enable - not supported +#define SPE 6 // SPI Enable +#define DORD 5 // DORD: Data Order +#define MSTR 4 // MSTR: Master/Slave Select +#define CPOL 3 // CPOL: Clock Polarity +#define CPHA 2 // CPHA: Clock Phase +#define SPR1 1 // Clock: 3 = 125 kHz, 2 = 250 kHz, 1 = 1 MHz, 0->4 MHz +#define SPR0 0 +// SPI Status Register  SPSR +#define SPIF 7 // SPIF: SPI Interrupt Flag +#define WCOL 6 // WCOL: Write COLlision Flag - not implemented +#define SPI2X 0 // SPI2X: Double SPI Speed Bit +// SPI Data Register  SPDR + +class SPCRemulation; +class SPSRemulation; +class SPDRemulation; + +class SPCRemulation +{ +public: + inline SPCRemulation & operator = (int val) __attribute__((always_inline)) { + uint32_t ctar, mcr, sim6; + //serial_print("SPCR="); + //serial_phex(val); + //serial_print("\n"); + sim6 = SIM_SCGC6; + if (!(sim6 & SIM_SCGC6_SPI0)) { + //serial_print("init1\n"); + SIM_SCGC6 = sim6 | SIM_SCGC6_SPI0; + SPI0_CTAR0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(1) | SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1); + } + if (!(val & (1<<SPE))) { + SPI0_MCR |= SPI_MCR_MDIS; // TODO: use bitband for atomic access + } + ctar = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(1); + if (val & (1<<DORD)) ctar |= SPI_CTAR_LSBFE; + if (val & (1<<CPOL)) ctar |= SPI_CTAR_CPOL; + if (val & (1<<CPHA)) { + ctar |= SPI_CTAR_CPHA; + if ((val & 3) == 0) { + ctar |= SPI_CTAR_BR(1) | SPI_CTAR_ASC(1); + } else if ((val & 3) == 1) { + ctar |= SPI_CTAR_BR(4) | SPI_CTAR_ASC(4); + } else if ((val & 3) == 2) { + ctar |= SPI_CTAR_BR(6) | SPI_CTAR_ASC(6); + } else { + ctar |= SPI_CTAR_BR(7) | SPI_CTAR_ASC(7); + } + } else { + if ((val & 3) == 0) { + ctar |= SPI_CTAR_BR(1) | SPI_CTAR_CSSCK(1); + } else if ((val & 3) == 1) { + ctar |= SPI_CTAR_BR(4) | SPI_CTAR_CSSCK(4); + } else if ((val & 3) == 2) { + ctar |= SPI_CTAR_BR(6) | SPI_CTAR_CSSCK(6); + } else { + ctar |= SPI_CTAR_BR(7) | SPI_CTAR_CSSCK(7); + } + } + ctar |= (SPI0_CTAR0 & SPI_CTAR_DBR); + update_ctar(ctar); + mcr = SPI_MCR_DCONF(0); + if (val & (1<<MSTR)) mcr |= SPI_MCR_MSTR; + if (val & (1<<SPE)) { + mcr &= ~(SPI_MCR_MDIS | SPI_MCR_HALT); + SPI0_MCR = mcr; + enable_pins(); + } else { + mcr |= (SPI_MCR_MDIS | SPI_MCR_HALT); + SPI0_MCR = mcr; + disable_pins(); + } + //serial_print("MCR:"); + //serial_phex32(SPI0_MCR); + //serial_print(", CTAR0:"); + //serial_phex32(SPI0_CTAR0); + //serial_print("\n"); + return *this; + } + inline SPCRemulation & operator |= (int val) __attribute__((always_inline)) { + uint32_t sim6; + //serial_print("SPCR |= "); + //serial_phex(val); + //serial_print("\n"); + sim6 = SIM_SCGC6; + if (!(sim6 & SIM_SCGC6_SPI0)) { + //serial_print("init2\n"); + SIM_SCGC6 = sim6 | SIM_SCGC6_SPI0; + SPI0_CTAR0 = SPI_CTAR_FMSZ(7) | SPI_CTAR_PBR(1) | SPI_CTAR_BR(1); + } + if (val & ((1<<DORD)|(1<<CPOL)|(1<<CPHA)|3)) { + uint32_t ctar = SPI0_CTAR0; + if (val & (1<<DORD)) ctar |= SPI_CTAR_LSBFE; // TODO: use bitband + if (val & (1<<CPOL)) ctar |= SPI_CTAR_CPOL; + if ((val & 3) == 1) { + // TODO: implement - is this ever really needed + } else if ((val & 3) == 2) { + // TODO: implement - is this ever really needed + } else if ((val & 3) == 3) { + // TODO: implement - is this ever really needed + } + if (val & (1<<CPHA) && !(ctar & SPI_CTAR_CPHA)) { + ctar |= SPI_CTAR_CPHA; + // TODO: clear SPI_CTAR_CSSCK, set SPI_CTAR_ASC + } + update_ctar(ctar); + } + if (val & (1<<MSTR)) SPI0_MCR |= SPI_MCR_MSTR; + if (val & (1<<SPE)) { + SPI0_MCR &= ~(SPI_MCR_MDIS | SPI_MCR_HALT); + enable_pins(); + } + //serial_print("MCR:"); + //serial_phex32(SPI0_MCR); + //serial_print(", CTAR0:"); + //serial_phex32(SPI0_CTAR0); + //serial_print("\n"); + return *this; + } + inline SPCRemulation & operator &= (int val) __attribute__((always_inline)) { + //serial_print("SPCR &= "); + //serial_phex(val); + //serial_print("\n"); + SIM_SCGC6 |= SIM_SCGC6_SPI0; + if (!(val & (1<<SPE))) { + SPI0_MCR |= (SPI_MCR_MDIS | SPI_MCR_HALT); + disable_pins(); + } + if ((val & ((1<<DORD)|(1<<CPOL)|(1<<CPHA)|3)) != ((1<<DORD)|(1<<CPOL)|(1<<CPHA)|3)) { + uint32_t ctar = SPI0_CTAR0; + if (!(val & (1<<DORD))) ctar &= ~SPI_CTAR_LSBFE; // TODO: use bitband + if (!(val & (1<<CPOL))) ctar &= ~SPI_CTAR_CPOL; + if ((val & 3) == 0) { + // TODO: implement - is this ever really needed + } else if ((val & 3) == 1) { + // TODO: implement - is this ever really needed + } else if ((val & 3) == 2) { + // TODO: implement - is this ever really needed + } + if (!(val & (1<<CPHA)) && (ctar & SPI_CTAR_CPHA)) { + ctar &= ~SPI_CTAR_CPHA; + // TODO: set SPI_CTAR_ASC, clear SPI_CTAR_CSSCK + } + update_ctar(ctar); + } + if (!(val & (1<<MSTR))) SPI0_MCR &= ~SPI_MCR_MSTR; + return *this; + } + inline int operator & (int val) const __attribute__((always_inline)) { + int ret = 0; + //serial_print("SPCR & "); + //serial_phex(val); + //serial_print("\n"); + if ((val & (1<<DORD)) && (SPI0_CTAR0 & SPI_CTAR_LSBFE)) ret |= (1<<DORD); + if ((val & (1<<CPOL)) && (SPI0_CTAR0 & SPI_CTAR_CPOL)) ret |= (1<<CPOL); + if ((val & (1<<CPHA)) && (SPI0_CTAR0 & SPI_CTAR_CPHA)) ret |= (1<<CPHA); + if ((val & 3) == 3) { + uint32_t dbr = SPI0_CTAR0 & 15; + if (dbr <= 1) { + } else if (dbr <= 4) { + ret |= (1<<SPR0); + } else if (dbr <= 6) { + ret |= (1<<SPR1); + } else { + ret |= (1<<SPR1)|(1<<SPR0); + } + } else if ((val & 3) == 1) { + // TODO: implement - is this ever really needed + } else if ((val & 3) == 2) { + // TODO: implement - is this ever really needed + } + if (val & (1<<SPE) && (!(SPI0_MCR & SPI_MCR_MDIS))) ret |= (1<<SPE); + if (val & (1<<MSTR) && (SPI0_MCR & SPI_MCR_MSTR)) ret |= (1<<MSTR); + //serial_print("ret = "); + //serial_phex(ret); + //serial_print("\n"); + return ret; + } + operator int () const __attribute__((always_inline)) { + int ret = 0; + if ((SIM_SCGC6 & SIM_SCGC6_SPI0)) { + int ctar = SPI0_CTAR0; + if (ctar & SPI_CTAR_LSBFE) ret |= (1<<DORD); + if (ctar & SPI_CTAR_CPOL) ret |= (1<<CPOL); + if (ctar & SPI_CTAR_CPHA) ret |= (1<<CPHA); + ctar &= 15; + if (ctar <= 1) { + } else if (ctar <= 4) { + ret |= (1<<SPR0); + } else if (ctar <= 6) { + ret |= (1<<SPR1); + } else { + ret |= (1<<SPR1)|(1<<SPR0); + } + int mcr = SPI0_MCR; + if (!(mcr & SPI_MCR_MDIS)) ret |= (1<<SPE); + if (mcr & SPI_MCR_MSTR) ret |= (1<<MSTR); + } + return ret; + } + friend class SPSRemulation; +private: + static inline void update_ctar(uint32_t ctar) __attribute__((always_inline)) { + if (SPI0_CTAR0 == ctar) return; + uint32_t mcr = SPI0_MCR; + if (mcr & SPI_MCR_MDIS) { + SPI0_CTAR0 = ctar; + } else { + SPI0_MCR = mcr | SPI_MCR_MDIS | SPI_MCR_HALT; + SPI0_CTAR0 = ctar; + SPI0_MCR = mcr; + } + } + inline void enable_pins(void) __attribute__((always_inline)) { + //serial_print("enable_pins\n"); + CORE_PIN11_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); + CORE_PIN12_CONFIG = PORT_PCR_MUX(2); + CORE_PIN13_CONFIG = PORT_PCR_DSE | PORT_PCR_MUX(2); + } + inline void disable_pins(void) __attribute__((always_inline)) { + //serial_print("disable_pins\n"); + CORE_PIN11_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); + CORE_PIN12_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); + CORE_PIN13_CONFIG = PORT_PCR_SRE | PORT_PCR_DSE | PORT_PCR_MUX(1); + } +}; +extern SPCRemulation SPCR; + +class SPSRemulation +{ +public: + inline SPSRemulation & operator = (int val) __attribute__((always_inline)) { + //serial_print("SPSR="); + //serial_phex(val); + //serial_print("\n"); + uint32_t ctar = SPI0_CTAR0; + if (val & (1<<SPI2X)) { + ctar |= SPI_CTAR_DBR; + } else { + ctar &= ~SPI_CTAR_DBR; + } + SPCRemulation::update_ctar(ctar); + //serial_print("MCR:"); + //serial_phex32(SPI0_MCR); + //serial_print(", CTAR0:"); + //serial_phex32(SPI0_CTAR0); + //serial_print("\n"); + return *this; + } + inline SPSRemulation & operator |= (int val) __attribute__((always_inline)) { + //serial_print("SPSR |= "); + //serial_phex(val); + //serial_print("\n"); + if (val & (1<<SPI2X)) SPCRemulation::update_ctar(SPI0_CTAR0 |= SPI_CTAR_DBR); + return *this; + } + inline SPSRemulation & operator &= (int val) __attribute__((always_inline)) { + //serial_print("SPSR &= "); + //serial_phex(val); + //serial_print("\n"); + if (!(val & (1<<SPI2X))) SPCRemulation::update_ctar(SPI0_CTAR0 &= ~SPI_CTAR_DBR); + return *this; + } + inline int operator & (int val) const __attribute__((always_inline)) { + int ret = 0; + //serial_print("SPSR & "); + //serial_phex(val); + //serial_print("\n"); + // TODO: using SPI_SR_TCF isn't quite right. Control returns to the + // caller after the final edge that captures data, which is 1/2 cycle + // sooner than AVR returns. At 500 kHz and slower SPI, this can make + // a difference when digitalWrite is used to manually control the CS + // pin, and perhaps it could matter at high clocks if faster register + // access is used? But does it really matter? Do any SPI chips in + // practice really perform differently if CS negates early, after the + // final bit is clocked, but before the end of the whole clock cycle? + if ((val & (1<<SPIF)) && (SPI0_SR & SPI_SR_TCF)) ret = (1<<SPIF); + if ((val & (1<<SPI2X)) && (SPI0_CTAR0 & SPI_CTAR_DBR)) ret |= (1<<SPI2X); + //delayMicroseconds(50000); + return ret; + } + operator int () const __attribute__((always_inline)) { + int ret = 0; + //serial_print("SPSR (int)\n"); + if (SPI0_SR & SPI_SR_TCF) ret = (1<<SPIF); + if (SPI0_CTAR0 & SPI_CTAR_DBR) ret |= (1<<SPI2X); + return ret; + } +}; +extern SPSRemulation SPSR; + +class SPDRemulation +{ +public: + inline SPDRemulation & operator = (int val) __attribute__((always_inline)) { + //serial_print("SPDR = "); + //serial_phex(val); + //serial_print("\n"); + SPI0_MCR |= SPI_MCR_CLR_RXF; // discard any received data + SPI0_SR = SPI_SR_TCF; + //SPI0_SR = SPI_SR_EOQF; + //SPI0_PUSHR = (val & 255) | SPI0_PUSHR_EOQ; + SPI0_PUSHR = (val & 255); + return *this; + } + operator int () const __attribute__((always_inline)) { + uint32_t val; + val = SPI0_POPR & 255; + //serial_print("SPDR (int) "); + //serial_phex(val); + //serial_print("\n"); + return val; + } +}; +extern SPDRemulation SPDR; + + +class SREGemulation +{ +public: + operator int () const __attribute__((always_inline)) { + uint32_t primask; + asm volatile("mrs %0, primask\n" : "=r" (primask)::); + if (primask) return 0; + return (1<<7); + } + inline SREGemulation & operator = (int val) __attribute__((always_inline)) { + if (val & (1<<7)) { + __enable_irq(); + } else { + __disable_irq(); + } + return *this; + } +}; +extern SREGemulation SREG; + +// these are not intended for public consumption... +#undef GPIO_BITBAND_ADDR +#undef GPIO_BITBAND +#undef CONFIG_PULLUP +#undef CONFIG_NOPULLUP + +#endif // __cplusplus + +#endif diff --git a/teensy3/avr_functions.h b/teensy3/avr_functions.h new file mode 100644 index 0000000000000000000000000000000000000000..8e752541185e00b24b402707b99abd060dbfed94 --- /dev/null +++ b/teensy3/avr_functions.h @@ -0,0 +1,69 @@ +/* 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)); +float eeprom_read_float(const float *addr) __attribute__ ((pure)); +void eeprom_read_block(void *buf, const void *addr, uint32_t len); // TODO: implement +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_float(float *addr, float value); // TODO: inline call +void eeprom_write_block(const void *buf, void *addr, uint32_t len); // TODO: implement +void eeprom_update_byte(uint8_t *addrp, uint8_t value); // TODO: inline call +void eeprom_update_word(uint16_t *addrp, uint16_t value); // TODO: inline call +void eeprom_update_dword(uint32_t *addrp, uint32_t value); // TODO: inline call +void eeprom_update_float(float *addr, float __value); // TODO: inline call +void eeprom_update_block(const void *buf, void *addr, uint32_t len); // TODO: inline call + +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 diff --git a/teensy3/binary.h b/teensy3/binary.h new file mode 100644 index 0000000000000000000000000000000000000000..af1498033ab2fcabf7d8cbb7b241a82ba5e091f0 --- /dev/null +++ b/teensy3/binary.h @@ -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 diff --git a/teensy3/core_cm4.h b/teensy3/core_cm4.h new file mode 100644 index 0000000000000000000000000000000000000000..024302e4a67a47884a961dd6ef057c2f84d4aa9c --- /dev/null +++ b/teensy3/core_cm4.h @@ -0,0 +1,1757 @@ +/**************************************************************************//** + * @file core_cm4.h + * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File + * @version V3.01 + * @date 22. 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. + * + ******************************************************************************/ +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef __CORE_CM4_H_GENERIC +#define __CORE_CM4_H_GENERIC + +/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.<br> + Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br> + Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.<br> + Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** \ingroup Cortex_M4 + @{ + */ + +/* CMSIS CM4 definitions */ +#define __CM4_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */ +#define __CM4_CMSIS_VERSION_SUB (0x01) /*!< [15:0] CMSIS HAL sub version */ +#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16) | \ + __CM4_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x04) /*!< Cortex-M Core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + #define __STATIC_INLINE static inline + +#elif defined ( __TMS470__ ) + #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + #define __STATIC_INLINE static inline + +#endif + +/** __FPU_USED indicates whether an FPU is used or not. For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI_VFP_SUPPORT__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif +#endif + +#include <stdint.h> /* standard types definitions */ +#include <core_cmInstr.h> /* Core Instruction Access */ +#include <core_cmFunc.h> /* Core Function Access */ +#include <core_cm4_simd.h> /* Compiler specific SIMD Intrinsics */ + +#endif /* __CORE_CM4_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM4_H_DEPENDANT +#define __CORE_CM4_H_DEPENDANT + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM4_REV + #define __CM4_REV 0x0000 + #warning "__CM4_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0 + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0 + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 4 + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0 + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + <strong>IO Type Qualifiers</strong> are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/*@} end of group Cortex_M4 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU Register + ******************************************************************************/ +/** \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ +#else + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ +#endif + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + + +/** \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + + +/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ +#else + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ +#endif + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + + +/** \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/*@} end of group CMSIS_CORE */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IO uint32_t ISER[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24]; + __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24]; + __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24]; + __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24]; + __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56]; + __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644]; + __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0 /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL << NVIC_STIR_INTID_Pos) /*!< STIR: INTLINESNUM Mask */ + +/*@} end of group CMSIS_NVIC */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5]; + __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_RETTOBASE_Pos 11 /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */ + +/* SCB Vector Table Offset Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +#define SCB_AIRCR_VECTRESET_Pos 0 /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL << SCB_AIRCR_VECTRESET_Pos) /*!< SCB AIRCR: VECTRESET Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_BFHFNMIGN_Pos 8 /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4 /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +#define SCB_CCR_USERSETMPEND_Pos 1 /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0 /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL << SCB_CCR_NONBASETHRDENA_Pos) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18 /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17 /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16 /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14 /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13 /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12 /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11 /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10 /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8 /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7 /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3 /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1 /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0 /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL << SCB_SHCSR_MEMFAULTACT_Pos) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Registers Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16 /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8 /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0 /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL << SCB_CFSR_MEMFAULTSR_Pos) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* SCB Hard Fault Status Registers Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31 /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30 /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1 /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4 /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL << SCB_DFSR_HALTED_Pos) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1]; + __I uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IO uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0 /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL << SCnSCB_ICTR_INTLINESNUM_Pos) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISOOFP_Pos 9 /*!< ACTLR: DISOOFP Position */ +#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ + +#define SCnSCB_ACTLR_DISFPCA_Pos 8 /*!< ACTLR: DISFPCA Position */ +#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2 /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1 /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0 /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL << SCnSCB_ACTLR_DISMCYCINT_Pos) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __O union + { + __O uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __O uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __O uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864]; + __IO uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15]; + __IO uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15]; + __IO uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ + uint32_t RESERVED3[29]; + __O uint32_t IWR; /*!< Offset: 0xEF8 ( /W) ITM Integration Write Register */ + __I uint32_t IRR; /*!< Offset: 0xEFC (R/ ) ITM Integration Read Register */ + __IO uint32_t IMCR; /*!< Offset: 0xF00 (R/W) ITM Integration Mode Control Register */ + uint32_t RESERVED4[43]; + __O uint32_t LAR; /*!< Offset: 0xFB0 ( /W) ITM Lock Access Register */ + __I uint32_t LSR; /*!< Offset: 0xFB4 (R/ ) ITM Lock Status Register */ + uint32_t RESERVED5[6]; + __I uint32_t PID4; /*!< Offset: 0xFD0 (R/ ) ITM Peripheral Identification Register #4 */ + __I uint32_t PID5; /*!< Offset: 0xFD4 (R/ ) ITM Peripheral Identification Register #5 */ + __I uint32_t PID6; /*!< Offset: 0xFD8 (R/ ) ITM Peripheral Identification Register #6 */ + __I uint32_t PID7; /*!< Offset: 0xFDC (R/ ) ITM Peripheral Identification Register #7 */ + __I uint32_t PID0; /*!< Offset: 0xFE0 (R/ ) ITM Peripheral Identification Register #0 */ + __I uint32_t PID1; /*!< Offset: 0xFE4 (R/ ) ITM Peripheral Identification Register #1 */ + __I uint32_t PID2; /*!< Offset: 0xFE8 (R/ ) ITM Peripheral Identification Register #2 */ + __I uint32_t PID3; /*!< Offset: 0xFEC (R/ ) ITM Peripheral Identification Register #3 */ + __I uint32_t CID0; /*!< Offset: 0xFF0 (R/ ) ITM Component Identification Register #0 */ + __I uint32_t CID1; /*!< Offset: 0xFF4 (R/ ) ITM Component Identification Register #1 */ + __I uint32_t CID2; /*!< Offset: 0xFF8 (R/ ) ITM Component Identification Register #2 */ + __I uint32_t CID3; /*!< Offset: 0xFFC (R/ ) ITM Component Identification Register #3 */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL << ITM_TPR_PRIVMASK_Pos) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23 /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16 /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10 /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8 /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4 /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_DWTENA_Pos 3 /*!< ITM TCR: DWTENA Position */ +#define ITM_TCR_DWTENA_Msk (1UL << ITM_TCR_DWTENA_Pos) /*!< ITM TCR: DWTENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2 /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1 /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0 /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL << ITM_TCR_ITMENA_Pos) /*!< ITM TCR: ITM Enable bit Mask */ + +/* ITM Integration Write Register Definitions */ +#define ITM_IWR_ATVALIDM_Pos 0 /*!< ITM IWR: ATVALIDM Position */ +#define ITM_IWR_ATVALIDM_Msk (1UL << ITM_IWR_ATVALIDM_Pos) /*!< ITM IWR: ATVALIDM Mask */ + +/* ITM Integration Read Register Definitions */ +#define ITM_IRR_ATREADYM_Pos 0 /*!< ITM IRR: ATREADYM Position */ +#define ITM_IRR_ATREADYM_Msk (1UL << ITM_IRR_ATREADYM_Pos) /*!< ITM IRR: ATREADYM Mask */ + +/* ITM Integration Mode Control Register Definitions */ +#define ITM_IMCR_INTEGRATION_Pos 0 /*!< ITM IMCR: INTEGRATION Position */ +#define ITM_IMCR_INTEGRATION_Msk (1UL << ITM_IMCR_INTEGRATION_Pos) /*!< ITM IMCR: INTEGRATION Mask */ + +/* ITM Lock Status Register Definitions */ +#define ITM_LSR_ByteAcc_Pos 2 /*!< ITM LSR: ByteAcc Position */ +#define ITM_LSR_ByteAcc_Msk (1UL << ITM_LSR_ByteAcc_Pos) /*!< ITM LSR: ByteAcc Mask */ + +#define ITM_LSR_Access_Pos 1 /*!< ITM LSR: Access Position */ +#define ITM_LSR_Access_Msk (1UL << ITM_LSR_Access_Pos) /*!< ITM LSR: Access Mask */ + +#define ITM_LSR_Present_Pos 0 /*!< ITM LSR: Present Position */ +#define ITM_LSR_Present_Msk (1UL << ITM_LSR_Present_Pos) /*!< ITM LSR: Present Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IO uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IO uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IO uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IO uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IO uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IO uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __I uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IO uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IO uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IO uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1]; + __IO uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IO uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IO uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1]; + __IO uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IO uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IO uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1]; + __IO uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IO uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IO uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28 /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27 /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26 /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25 /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24 /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22 /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21 /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20 /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19 /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18 /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17 /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16 /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12 /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10 /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9 /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5 /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1 /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0 /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL << DWT_CTRL_CYCCNTENA_Pos) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0 /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL << DWT_CPICNT_CPICNT_Pos) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0 /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL << DWT_EXCCNT_EXCCNT_Pos) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0 /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL << DWT_SLEEPCNT_SLEEPCNT_Pos) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0 /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL << DWT_LSUCNT_LSUCNT_Pos) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0 /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL << DWT_FOLDCNT_FOLDCNT_Pos) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0 /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL << DWT_MASK_MASK_Pos) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24 /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16 /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12 /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10 /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9 /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8 /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7 /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5 /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0 /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL << DWT_FUNCTION_FUNCTION_Pos) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IO uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IO uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2]; + __IO uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55]; + __IO uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131]; + __I uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IO uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __I uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759]; + __I uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __I uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __I uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1]; + __I uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __I uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IO uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39]; + __IO uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IO uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8]; + __I uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __I uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0 /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL << TPI_ACPR_PRESCALER_Pos) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0 /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL << TPI_SPPR_TXMODE_Pos) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3 /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2 /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1 /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0 /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL << TPI_FFSR_FlInProg_Pos) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8 /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1 /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0 /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL << TPI_TRIGGER_TRIGGER_Pos) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29 /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27 /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26 /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24 /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16 /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8 /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0 /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL << TPI_FIFO0_ETM0_Pos) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0 /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL << TPI_ITATBCTR2_ATREADY_Pos) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29 /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27 /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26 /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24 /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16 /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8 /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0 /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL << TPI_FIFO1_ITM0_Pos) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0 /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL << TPI_ITATBCTR0_ATREADY_Pos) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0 /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL << TPI_ITCTRL_Mode_Pos) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11 /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10 /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9 /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6 /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5 /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0 /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL << TPI_DEVID_NrTraceInput_Pos) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 0 /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL << TPI_DEVTYPE_SubType_Pos) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 4 /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#if (__MPU_PRESENT == 1) +/** \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ + __IO uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IO uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IO uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IO uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IO uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IO uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register */ +#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register */ +#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register */ +#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register */ +#define MPU_RBAR_ADDR_Pos 5 /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register */ +#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18 /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17 /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16 /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL << MPU_RASR_ENABLE_Pos) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +#if (__FPU_PRESENT == 1) +/** \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1]; + __IO uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IO uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IO uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __I uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __I uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ +} FPU_Type; + +/* Floating-Point Context Control Register */ +#define FPU_FPCCR_ASPEN_Pos 31 /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30 /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8 /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6 /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5 /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4 /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3 /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_USER_Pos 1 /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0 /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL << FPU_FPCCR_LSPACT_Pos) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register */ +#define FPU_FPCAR_ADDRESS_Pos 3 /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register */ +#define FPU_FPDSCR_AHP_Pos 26 /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25 /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24 /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22 /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28 /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24 /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20 /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16 /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12 /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8 /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4 /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0 /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL << FPU_MVFR0_A_SIMD_registers_Pos) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28 /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24 /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4 /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0 /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL << FPU_MVFR1_FtZ_mode_Pos) /*!< MVFR1: FtZ mode bits Mask */ + +/*@} end of group CMSIS_FPU */ +#endif + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5 /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL << CoreDebug_DHCSR_C_DEBUGEN_Pos) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register */ +#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL << CoreDebug_DCRSR_REGSEL_Pos) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register */ +#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19 /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18 /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17 /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16 /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9 /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8 /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7 /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6 /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5 /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4 /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL << CoreDebug_DEMCR_VC_CORERESET_Pos) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} end of group CMSIS_CoreDebug */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Cortex-M4 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug configuration struct */ + +#if (__MPU_PRESENT == 1) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +#if (__FPU_PRESENT == 1) + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug Functions + - Core Register Access Functions + ******************************************************************************/ +/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +/** \brief Set Priority Grouping + + The function sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8)); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** \brief Get Priority Grouping + + The function reads the priority grouping field from the NVIC Interrupt Controller. + + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void) +{ + return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos); /* read priority grouping field */ +} + + +/** \brief Enable External Interrupt + + The function enables a device-specific interrupt in the NVIC interrupt controller. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ +/* NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); enable interrupt */ + NVIC->ISER[(uint32_t)((int32_t)IRQn) >> 5] = (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F)); /* enable interrupt */ +} + + +/** \brief Disable External Interrupt + + The function disables a device-specific interrupt in the NVIC interrupt controller. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */ +} + + +/** \brief Get Pending Interrupt + + The function reads the pending register in the NVIC and returns the pending bit + for the specified interrupt. + + \param [in] IRQn Interrupt number. + + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t) ((NVIC->ISPR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 0 */ +} + + +/** \brief Set Pending Interrupt + + The function sets the pending bit of an external interrupt. + + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */ +} + + +/** \brief Clear Pending Interrupt + + The function clears the pending bit of an external interrupt. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ +} + + +/** \brief Get Active Interrupt + + The function reads the active register in NVIC and returns the active bit. + + \param [in] IRQn Interrupt number. + + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + */ +__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) +{ + return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */ +} + + +/** \brief Set Interrupt Priority + + The function sets the priority of an interrupt. + + \note The priority cannot be set for every core interrupt. + + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if(IRQn < 0) { + SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M System Interrupts */ + else { + NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */ +} + + +/** \brief Get Interrupt Priority + + The function reads the priority of an interrupt. The interrupt + number can be positive to specify an external (device specific) + interrupt, or negative to specify an internal (core) interrupt. + + + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented + priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if(IRQn < 0) { + return((uint32_t)(SCB->SHP[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M system interrupts */ + else { + return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ +} + + +/** \brief Encode Priority + + The function encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the samllest possible priority group is set. + + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + return ( + ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) | + ((SubPriority & ((1 << (SubPriorityBits )) - 1))) + ); +} + + +/** \brief Decode Priority + + The function decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set. + + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1); + *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1); +} + + +/** \brief System Reset + + The function initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */ + __DSB(); /* Ensure completion of memory access */ + while(1); /* wait until reset */ +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if (__Vendor_SysTickConfig == 0) + +/** \brief System Tick Configuration + + The function initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + + \param [in] ticks Number of ticks between two interrupts. + + \return 0 Function succeeded. + \return 1 Function failed. + + \note When the variable <b>__Vendor_SysTickConfig</b> is set to 1, then the + function <b>SysTick_Config</b> is not included. In this case, the file <b><i>device</i>.h</b> + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ + + SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** \brief ITM Send Character + + The function transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + + \param [in] ch Character to transmit. + + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if ((ITM->TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */ + (ITM->TER & (1UL << 0) ) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0].u32 == 0); + ITM->PORT[0].u8 = (uint8_t) ch; + } + return (ch); +} + + +/** \brief ITM Receive Character + + The function inputs a character via the external variable \ref ITM_RxBuffer. + + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) { + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** \brief ITM Check Character + + The function checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) { + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { + return (0); /* no character available */ + } else { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + +#endif /* __CORE_CM4_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ + +#ifdef __cplusplus +} +#endif diff --git a/teensy3/core_cm4_simd.h b/teensy3/core_cm4_simd.h new file mode 100644 index 0000000000000000000000000000000000000000..66c99397d7d687742eca43fbbfc08c6eb87ef0ad --- /dev/null +++ b/teensy3/core_cm4_simd.h @@ -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 diff --git a/teensy3/core_cmInstr.h b/teensy3/core_cmInstr.h new file mode 100644 index 0000000000000000000000000000000000000000..971ae7e9bdb01efb284987c05a813e8a8ce72c9b --- /dev/null +++ b/teensy3/core_cmInstr.h @@ -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 */ diff --git a/teensy3/core_id.h b/teensy3/core_id.h new file mode 100644 index 0000000000000000000000000000000000000000..a64f940f735f0edb466f137ed321cbc6878d7145 --- /dev/null +++ b/teensy3/core_id.h @@ -0,0 +1,3 @@ +#ifndef CORE_TEENSY +#define CORE_TEENSY +#endif diff --git a/teensy3/core_pins.h b/teensy3/core_pins.h new file mode 100644 index 0000000000000000000000000000000000000000..8c2240fc1005b45df4df9c3094da4567dd9ef735 --- /dev/null +++ b/teensy3/core_pins.h @@ -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 diff --git a/teensy3/eeprom.c b/teensy3/eeprom.c new file mode 100644 index 0000000000000000000000000000000000000000..848c7a4bb4eaa9ca6a9f34cf597e4dff59e8648d --- /dev/null +++ b/teensy3/eeprom.c @@ -0,0 +1,226 @@ +/* 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; + 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; + 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; + return *(uint32_t *)(&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 (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; +#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; +#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 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 +*/ + diff --git a/teensy3/elapsedMillis.h b/teensy3/elapsedMillis.h new file mode 100644 index 0000000000000000000000000000000000000000..a014f5040a1ddf2eac567ddbb628476bb16071ba --- /dev/null +++ b/teensy3/elapsedMillis.h @@ -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 diff --git a/teensy3/keylayouts.c b/teensy3/keylayouts.c new file mode 100644 index 0000000000000000000000000000000000000000..4bf543a4abbb21df9dfdc29ba39689b03c420a0e --- /dev/null +++ b/teensy3/keylayouts.c @@ -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 + diff --git a/teensy3/keylayouts.h b/teensy3/keylayouts.h new file mode 100644 index 0000000000000000000000000000000000000000..0956bf6eaf190de9096d36cf55107636949976ed --- /dev/null +++ b/teensy3/keylayouts.h @@ -0,0 +1,5173 @@ +/* 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 KEYLAYOUTS_H__ +#define KEYLAYOUTS_H__ + +#include <stdint.h> +#include <avr/pgmspace.h> + +#ifdef __cplusplus +extern "C"{ +#endif + +//#define LAYOUT_US_ENGLISH +//#define LAYOUT_CANADIAN_FRENCH +//#define LAYOUT_CANADIAN_MULTILINGUAL +//#define LAYOUT_DANISH +//#define LAYOUT_FINNISH +//#define LAYOUT_FRENCH +//#define LAYOUT_FRENCH_BELGIAN +//#define LAYOUT_FRENCH_SWISS +//#define LAYOUT_GERMAN +//#define LAYOUT_GERMAN_MAC +//#define LAYOUT_GERMAN_SWISS +//#define LAYOUT_ICELANDIC +//#define LAYOUT_IRISH +//#define LAYOUT_ITALIAN +//#define LAYOUT_NORWEGIAN +//#define LAYOUT_PORTUGUESE +//#define LAYOUT_PORTUGUESE_BRAZILIAN +//#define LAYOUT_SPANISH +//#define LAYOUT_SPANISH_LATIN_AMERICA +//#define LAYOUT_SWEDISH +//#define LAYOUT_TURKISH +//#define LAYOUT_UNITED_KINGDOM +//#define LAYOUT_US_INTERNATIONAL + + + +// http://en.wikipedia.org/wiki/Keyboard_layout + + +#define MODIFIERKEY_CTRL ( 0x01 | 0x8000 ) +#define MODIFIERKEY_SHIFT ( 0x02 | 0x8000 ) +#define MODIFIERKEY_ALT ( 0x04 | 0x8000 ) +#define MODIFIERKEY_GUI ( 0x08 | 0x8000 ) +#define MODIFIERKEY_LEFT_CTRL ( 0x01 | 0x8000 ) +#define MODIFIERKEY_LEFT_SHIFT ( 0x02 | 0x8000 ) +#define MODIFIERKEY_LEFT_ALT ( 0x04 | 0x8000 ) +#define MODIFIERKEY_LEFT_GUI ( 0x08 | 0x8000 ) +#define MODIFIERKEY_RIGHT_CTRL ( 0x10 | 0x8000 ) +#define MODIFIERKEY_RIGHT_SHIFT ( 0x20 | 0x8000 ) +#define MODIFIERKEY_RIGHT_ALT ( 0x40 | 0x8000 ) +#define MODIFIERKEY_RIGHT_GUI ( 0x80 | 0x8000 ) + +#define KEY_MEDIA_VOLUME_INC 0x01 +#define KEY_MEDIA_VOLUME_DEC 0x02 +#define KEY_MEDIA_MUTE 0x04 +#define KEY_MEDIA_PLAY_PAUSE 0x08 +#define KEY_MEDIA_NEXT_TRACK 0x10 +#define KEY_MEDIA_PREV_TRACK 0x20 +#define KEY_MEDIA_STOP 0x40 +#define KEY_MEDIA_EJECT 0x80 + +#define KEY_A ( 4 | 0x4000 ) +#define KEY_B ( 5 | 0x4000 ) +#define KEY_C ( 6 | 0x4000 ) +#define KEY_D ( 7 | 0x4000 ) +#define KEY_E ( 8 | 0x4000 ) +#define KEY_F ( 9 | 0x4000 ) +#define KEY_G ( 10 | 0x4000 ) +#define KEY_H ( 11 | 0x4000 ) +#define KEY_I ( 12 | 0x4000 ) +#define KEY_J ( 13 | 0x4000 ) +#define KEY_K ( 14 | 0x4000 ) +#define KEY_L ( 15 | 0x4000 ) +#define KEY_M ( 16 | 0x4000 ) +#define KEY_N ( 17 | 0x4000 ) +#define KEY_O ( 18 | 0x4000 ) +#define KEY_P ( 19 | 0x4000 ) +#define KEY_Q ( 20 | 0x4000 ) +#define KEY_R ( 21 | 0x4000 ) +#define KEY_S ( 22 | 0x4000 ) +#define KEY_T ( 23 | 0x4000 ) +#define KEY_U ( 24 | 0x4000 ) +#define KEY_V ( 25 | 0x4000 ) +#define KEY_W ( 26 | 0x4000 ) +#define KEY_X ( 27 | 0x4000 ) +#define KEY_Y ( 28 | 0x4000 ) +#define KEY_Z ( 29 | 0x4000 ) +#define KEY_1 ( 30 | 0x4000 ) +#define KEY_2 ( 31 | 0x4000 ) +#define KEY_3 ( 32 | 0x4000 ) +#define KEY_4 ( 33 | 0x4000 ) +#define KEY_5 ( 34 | 0x4000 ) +#define KEY_6 ( 35 | 0x4000 ) +#define KEY_7 ( 36 | 0x4000 ) +#define KEY_8 ( 37 | 0x4000 ) +#define KEY_9 ( 38 | 0x4000 ) +#define KEY_0 ( 39 | 0x4000 ) +#define KEY_ENTER ( 40 | 0x4000 ) +#define KEY_ESC ( 41 | 0x4000 ) +#define KEY_BACKSPACE ( 42 | 0x4000 ) +#define KEY_TAB ( 43 | 0x4000 ) +#define KEY_SPACE ( 44 | 0x4000 ) +#define KEY_MINUS ( 45 | 0x4000 ) +#define KEY_EQUAL ( 46 | 0x4000 ) +#define KEY_LEFT_BRACE ( 47 | 0x4000 ) +#define KEY_RIGHT_BRACE ( 48 | 0x4000 ) +#define KEY_BACKSLASH ( 49 | 0x4000 ) +#define KEY_NON_US_NUM ( 50 | 0x4000 ) +#define KEY_SEMICOLON ( 51 | 0x4000 ) +#define KEY_QUOTE ( 52 | 0x4000 ) +#define KEY_TILDE ( 53 | 0x4000 ) +#define KEY_COMMA ( 54 | 0x4000 ) +#define KEY_PERIOD ( 55 | 0x4000 ) +#define KEY_SLASH ( 56 | 0x4000 ) +#define KEY_CAPS_LOCK ( 57 | 0x4000 ) +#define KEY_F1 ( 58 | 0x4000 ) +#define KEY_F2 ( 59 | 0x4000 ) +#define KEY_F3 ( 60 | 0x4000 ) +#define KEY_F4 ( 61 | 0x4000 ) +#define KEY_F5 ( 62 | 0x4000 ) +#define KEY_F6 ( 63 | 0x4000 ) +#define KEY_F7 ( 64 | 0x4000 ) +#define KEY_F8 ( 65 | 0x4000 ) +#define KEY_F9 ( 66 | 0x4000 ) +#define KEY_F10 ( 67 | 0x4000 ) +#define KEY_F11 ( 68 | 0x4000 ) +#define KEY_F12 ( 69 | 0x4000 ) +#define KEY_PRINTSCREEN ( 70 | 0x4000 ) +#define KEY_SCROLL_LOCK ( 71 | 0x4000 ) +#define KEY_PAUSE ( 72 | 0x4000 ) +#define KEY_INSERT ( 73 | 0x4000 ) +#define KEY_HOME ( 74 | 0x4000 ) +#define KEY_PAGE_UP ( 75 | 0x4000 ) +#define KEY_DELETE ( 76 | 0x4000 ) +#define KEY_END ( 77 | 0x4000 ) +#define KEY_PAGE_DOWN ( 78 | 0x4000 ) +#define KEY_RIGHT ( 79 | 0x4000 ) +#define KEY_LEFT ( 80 | 0x4000 ) +#define KEY_DOWN ( 81 | 0x4000 ) +#define KEY_UP ( 82 | 0x4000 ) +#define KEY_NUM_LOCK ( 83 | 0x4000 ) +#define KEYPAD_SLASH ( 84 | 0x4000 ) +#define KEYPAD_ASTERIX ( 85 | 0x4000 ) +#define KEYPAD_MINUS ( 86 | 0x4000 ) +#define KEYPAD_PLUS ( 87 | 0x4000 ) +#define KEYPAD_ENTER ( 88 | 0x4000 ) +#define KEYPAD_1 ( 89 | 0x4000 ) +#define KEYPAD_2 ( 90 | 0x4000 ) +#define KEYPAD_3 ( 91 | 0x4000 ) +#define KEYPAD_4 ( 92 | 0x4000 ) +#define KEYPAD_5 ( 93 | 0x4000 ) +#define KEYPAD_6 ( 94 | 0x4000 ) +#define KEYPAD_7 ( 95 | 0x4000 ) +#define KEYPAD_8 ( 96 | 0x4000 ) +#define KEYPAD_9 ( 97 | 0x4000 ) +#define KEYPAD_0 ( 98 | 0x4000 ) +#define KEYPAD_PERIOD ( 99 | 0x4000 ) +#define KEY_MENU ( 101 | 0x4000 ) +#define KEY_F13 ( 104 | 0x4000 ) +#define KEY_F14 ( 105 | 0x4000 ) +#define KEY_F15 ( 106 | 0x4000 ) +#define KEY_F16 ( 107 | 0x4000 ) +#define KEY_F17 ( 108 | 0x4000 ) +#define KEY_F18 ( 109 | 0x4000 ) +#define KEY_F19 ( 110 | 0x4000 ) +#define KEY_F20 ( 111 | 0x4000 ) +#define KEY_F21 ( 112 | 0x4000 ) +#define KEY_F22 ( 113 | 0x4000 ) +#define KEY_F23 ( 114 | 0x4000 ) +#define KEY_F24 ( 115 | 0x4000 ) + + +// for compatibility with Leonardo's slightly different names +#define KEY_UP_ARROW KEY_UP +#define KEY_DOWN_ARROW KEY_DOWN +#define KEY_LEFT_ARROW KEY_LEFT +#define KEY_RIGHT_ARROW KEY_RIGHT +#define KEY_RETURN KEY_ENTER +#define KEY_LEFT_CTRL MODIFIERKEY_LEFT_CTRL +#define KEY_LEFT_SHIFT MODIFIERKEY_LEFT_SHIFT +#define KEY_LEFT_ALT MODIFIERKEY_LEFT_ALT +#define KEY_LEFT_GUI MODIFIERKEY_LEFT_GUI +#define KEY_RIGHT_CTRL MODIFIERKEY_RIGHT_CTRL +#define KEY_RIGHT_SHIFT MODIFIERKEY_RIGHT_SHIFT +#define KEY_RIGHT_ALT MODIFIERKEY_RIGHT_ALT +#define KEY_RIGHT_GUI MODIFIERKEY_RIGHT_GUI + + +// Everything below this line is not intended for use in "normal" programs. +// These private symbols populate lookup tables, which are used to translate +// ascii and UTF8 unicode into keystroke sequences. + + +#ifdef LAYOUT_US_ENGLISH + +#define SHIFT_MASK 0x40 +#define KEYCODE_TYPE uint8_t + +#define ASCII_20 KEY_SPACE // 32 +#define ASCII_21 KEY_1 + SHIFT_MASK // 33 ! +#define ASCII_22 KEY_QUOTE + SHIFT_MASK // 34 " +#define ASCII_23 KEY_3 + SHIFT_MASK // 35 # +#define ASCII_24 KEY_4 + SHIFT_MASK // 36 $ +#define ASCII_25 KEY_5 + SHIFT_MASK // 37 % +#define ASCII_26 KEY_7 + SHIFT_MASK // 38 & +#define ASCII_27 KEY_QUOTE // 39 ' +#define ASCII_28 KEY_9 + SHIFT_MASK // 40 ( +#define ASCII_29 KEY_0 + SHIFT_MASK // 41 ) +#define ASCII_2A KEY_8 + SHIFT_MASK // 42 * +#define ASCII_2B KEY_EQUAL + SHIFT_MASK // 43 + +#define ASCII_2C KEY_COMMA // 44 , +#define ASCII_2D KEY_MINUS // 45 - +#define ASCII_2E KEY_PERIOD // 46 . +#define ASCII_2F KEY_SLASH // 47 / +#define ASCII_30 KEY_0 // 48 0 +#define ASCII_31 KEY_1 // 49 1 +#define ASCII_32 KEY_2 // 50 2 +#define ASCII_33 KEY_3 // 51 3 +#define ASCII_34 KEY_4 // 52 4 +#define ASCII_35 KEY_5 // 53 5 +#define ASCII_36 KEY_6 // 54 6 +#define ASCII_37 KEY_7 // 55 7 +#define ASCII_38 KEY_8 // 55 8 +#define ASCII_39 KEY_9 // 57 9 +#define ASCII_3A KEY_SEMICOLON + SHIFT_MASK // 58 : +#define ASCII_3B KEY_SEMICOLON // 59 ; +#define ASCII_3C KEY_COMMA + SHIFT_MASK // 60 < +#define ASCII_3D KEY_EQUAL // 61 = +#define ASCII_3E KEY_PERIOD + SHIFT_MASK // 62 > +#define ASCII_3F KEY_SLASH + SHIFT_MASK // 63 ? +#define ASCII_40 KEY_2 + SHIFT_MASK // 64 @ +#define ASCII_41 KEY_A + SHIFT_MASK // 65 A +#define ASCII_42 KEY_B + SHIFT_MASK // 66 B +#define ASCII_43 KEY_C + SHIFT_MASK // 67 C +#define ASCII_44 KEY_D + SHIFT_MASK // 68 D +#define ASCII_45 KEY_E + SHIFT_MASK // 69 E +#define ASCII_46 KEY_F + SHIFT_MASK // 70 F +#define ASCII_47 KEY_G + SHIFT_MASK // 71 G +#define ASCII_48 KEY_H + SHIFT_MASK // 72 H +#define ASCII_49 KEY_I + SHIFT_MASK // 73 I +#define ASCII_4A KEY_J + SHIFT_MASK // 74 J +#define ASCII_4B KEY_K + SHIFT_MASK // 75 K +#define ASCII_4C KEY_L + SHIFT_MASK // 76 L +#define ASCII_4D KEY_M + SHIFT_MASK // 77 M +#define ASCII_4E KEY_N + SHIFT_MASK // 78 N +#define ASCII_4F KEY_O + SHIFT_MASK // 79 O +#define ASCII_50 KEY_P + SHIFT_MASK // 80 P +#define ASCII_51 KEY_Q + SHIFT_MASK // 81 Q +#define ASCII_52 KEY_R + SHIFT_MASK // 82 R +#define ASCII_53 KEY_S + SHIFT_MASK // 83 S +#define ASCII_54 KEY_T + SHIFT_MASK // 84 T +#define ASCII_55 KEY_U + SHIFT_MASK // 85 U +#define ASCII_56 KEY_V + SHIFT_MASK // 86 V +#define ASCII_57 KEY_W + SHIFT_MASK // 87 W +#define ASCII_58 KEY_X + SHIFT_MASK // 88 X +#define ASCII_59 KEY_Y + SHIFT_MASK // 89 Y +#define ASCII_5A KEY_Z + SHIFT_MASK // 90 Z +#define ASCII_5B KEY_LEFT_BRACE // 91 [ +#define ASCII_5C KEY_BACKSLASH // 92 +#define ASCII_5D KEY_RIGHT_BRACE // 93 ] +#define ASCII_5E KEY_6 + SHIFT_MASK // 94 ^ +#define ASCII_5F KEY_MINUS + SHIFT_MASK // 95 _ +#define ASCII_60 KEY_TILDE // 96 ` +#define ASCII_61 KEY_A // 97 a +#define ASCII_62 KEY_B // 98 b +#define ASCII_63 KEY_C // 99 c +#define ASCII_64 KEY_D // 100 d +#define ASCII_65 KEY_E // 101 e +#define ASCII_66 KEY_F // 102 f +#define ASCII_67 KEY_G // 103 g +#define ASCII_68 KEY_H // 104 h +#define ASCII_69 KEY_I // 105 i +#define ASCII_6A KEY_J // 106 j +#define ASCII_6B KEY_K // 107 k +#define ASCII_6C KEY_L // 108 l +#define ASCII_6D KEY_M // 109 m +#define ASCII_6E KEY_N // 110 n +#define ASCII_6F KEY_O // 111 o +#define ASCII_70 KEY_P // 112 p +#define ASCII_71 KEY_Q // 113 q +#define ASCII_72 KEY_R // 114 r +#define ASCII_73 KEY_S // 115 s +#define ASCII_74 KEY_T // 116 t +#define ASCII_75 KEY_U // 117 u +#define ASCII_76 KEY_V // 118 v +#define ASCII_77 KEY_W // 119 w +#define ASCII_78 KEY_X // 120 x +#define ASCII_79 KEY_Y // 121 y +#define ASCII_7A KEY_Z // 122 z +#define ASCII_7B KEY_LEFT_BRACE + SHIFT_MASK // 123 { +#define ASCII_7C KEY_BACKSLASH + SHIFT_MASK // 124 | +#define ASCII_7D KEY_RIGHT_BRACE + SHIFT_MASK // 125 } +#define ASCII_7E KEY_TILDE + SHIFT_MASK // 126 ~ +#define ASCII_7F KEY_BACKSPACE // 127 + +#endif // LAYOUT_US_ENGLISH + + + + +#ifdef LAYOUT_US_INTERNATIONAL + +#define SHIFT_MASK 0x0040 +#define ALTGR_MASK 0x0080 +#define DEADKEYS_MASK 0x0700 +#define CIRCUMFLEX_BITS 0x0100 +#define ACUTE_ACCENT_BITS 0x0200 +#define GRAVE_ACCENT_BITS 0x0300 +#define TILDE_BITS 0x0400 +#define DIAERESIS_BITS 0x0500 +#define KEYCODE_TYPE uint16_t +#define DEADKEY_CIRCUMFLEX KEY_6 + SHIFT_MASK +#define DEADKEY_ACUTE_ACCENT KEY_QUOTE +#define DEADKEY_GRAVE_ACCENT KEY_TILDE +#define DEADKEY_TILDE KEY_TILDE + SHIFT_MASK +#define DEADKEY_DIAERESIS KEY_QUOTE + SHIFT_MASK + +#define ASCII_20 KEY_SPACE // 32 +#define ASCII_21 KEY_1 + SHIFT_MASK // 33 ! +#define ASCII_22 DIAERESIS_BITS + KEY_SPACE // 34 " +#define ASCII_23 KEY_3 + SHIFT_MASK // 35 # +#define ASCII_24 KEY_4 + SHIFT_MASK // 36 $ +#define ASCII_25 KEY_5 + SHIFT_MASK // 37 % +#define ASCII_26 KEY_7 + SHIFT_MASK // 38 & +#define ASCII_27 ACUTE_ACCENT_BITS + KEY_SPACE // 39 ' +#define ASCII_28 KEY_9 + SHIFT_MASK // 40 ( +#define ASCII_29 KEY_0 + SHIFT_MASK // 41 ) +#define ASCII_2A KEY_8 + SHIFT_MASK // 42 * +#define ASCII_2B KEY_EQUAL + SHIFT_MASK // 43 + +#define ASCII_2C KEY_COMMA // 44 , +#define ASCII_2D KEY_MINUS // 45 - +#define ASCII_2E KEY_PERIOD // 46 . +#define ASCII_2F KEY_SLASH // 47 / +#define ASCII_30 KEY_0 // 48 0 +#define ASCII_31 KEY_1 // 49 1 +#define ASCII_32 KEY_2 // 50 2 +#define ASCII_33 KEY_3 // 51 3 +#define ASCII_34 KEY_4 // 52 4 +#define ASCII_35 KEY_5 // 53 5 +#define ASCII_36 KEY_6 // 54 6 +#define ASCII_37 KEY_7 // 55 7 +#define ASCII_38 KEY_8 // 55 8 +#define ASCII_39 KEY_9 // 57 9 +#define ASCII_3A KEY_SEMICOLON + SHIFT_MASK // 58 : +#define ASCII_3B KEY_SEMICOLON // 59 ; +#define ASCII_3C KEY_COMMA + SHIFT_MASK // 60 < +#define ASCII_3D KEY_EQUAL // 61 = +#define ASCII_3E KEY_PERIOD + SHIFT_MASK // 62 > +#define ASCII_3F KEY_SLASH + SHIFT_MASK // 63 ? +#define ASCII_40 KEY_2 + SHIFT_MASK // 64 @ +#define ASCII_41 KEY_A + SHIFT_MASK // 65 A +#define ASCII_42 KEY_B + SHIFT_MASK // 66 B +#define ASCII_43 KEY_C + SHIFT_MASK // 67 C +#define ASCII_44 KEY_D + SHIFT_MASK // 68 D +#define ASCII_45 KEY_E + SHIFT_MASK // 69 E +#define ASCII_46 KEY_F + SHIFT_MASK // 70 F +#define ASCII_47 KEY_G + SHIFT_MASK // 71 G +#define ASCII_48 KEY_H + SHIFT_MASK // 72 H +#define ASCII_49 KEY_I + SHIFT_MASK // 73 I +#define ASCII_4A KEY_J + SHIFT_MASK // 74 J +#define ASCII_4B KEY_K + SHIFT_MASK // 75 K +#define ASCII_4C KEY_L + SHIFT_MASK // 76 L +#define ASCII_4D KEY_M + SHIFT_MASK // 77 M +#define ASCII_4E KEY_N + SHIFT_MASK // 78 N +#define ASCII_4F KEY_O + SHIFT_MASK // 79 O +#define ASCII_50 KEY_P + SHIFT_MASK // 80 P +#define ASCII_51 KEY_Q + SHIFT_MASK // 81 Q +#define ASCII_52 KEY_R + SHIFT_MASK // 82 R +#define ASCII_53 KEY_S + SHIFT_MASK // 83 S +#define ASCII_54 KEY_T + SHIFT_MASK // 84 T +#define ASCII_55 KEY_U + SHIFT_MASK // 85 U +#define ASCII_56 KEY_V + SHIFT_MASK // 86 V +#define ASCII_57 KEY_W + SHIFT_MASK // 87 W +#define ASCII_58 KEY_X + SHIFT_MASK // 88 X +#define ASCII_59 KEY_Y + SHIFT_MASK // 89 Y +#define ASCII_5A KEY_Z + SHIFT_MASK // 90 Z +#define ASCII_5B KEY_LEFT_BRACE // 91 [ +#define ASCII_5C KEY_BACKSLASH // 92 +#define ASCII_5D KEY_RIGHT_BRACE // 93 ] +#define ASCII_5E CIRCUMFLEX_BITS + KEY_SPACE // 94 ^ +#define ASCII_5F KEY_MINUS + SHIFT_MASK // 95 _ +#define ASCII_60 GRAVE_ACCENT_BITS + KEY_SPACE // 96 ` +#define ASCII_61 KEY_A // 97 a +#define ASCII_62 KEY_B // 98 b +#define ASCII_63 KEY_C // 99 c +#define ASCII_64 KEY_D // 100 d +#define ASCII_65 KEY_E // 101 e +#define ASCII_66 KEY_F // 102 f +#define ASCII_67 KEY_G // 103 g +#define ASCII_68 KEY_H // 104 h +#define ASCII_69 KEY_I // 105 i +#define ASCII_6A KEY_J // 106 j +#define ASCII_6B KEY_K // 107 k +#define ASCII_6C KEY_L // 108 l +#define ASCII_6D KEY_M // 109 m +#define ASCII_6E KEY_N // 110 n +#define ASCII_6F KEY_O // 111 o +#define ASCII_70 KEY_P // 112 p +#define ASCII_71 KEY_Q // 113 q +#define ASCII_72 KEY_R // 114 r +#define ASCII_73 KEY_S // 115 s +#define ASCII_74 KEY_T // 116 t +#define ASCII_75 KEY_U // 117 u +#define ASCII_76 KEY_V // 118 v +#define ASCII_77 KEY_W // 119 w +#define ASCII_78 KEY_X // 120 x +#define ASCII_79 KEY_Y // 121 y +#define ASCII_7A KEY_Z // 122 z +#define ASCII_7B KEY_LEFT_BRACE + SHIFT_MASK // 123 { +#define ASCII_7C KEY_BACKSLASH + SHIFT_MASK // 124 | +#define ASCII_7D KEY_RIGHT_BRACE + SHIFT_MASK // 125 } +#define ASCII_7E TILDE_BITS + KEY_SPACE // 126 ~ +#define ASCII_7F KEY_BACKSPACE // 127 +#define ISO_8859_1_A0 KEY_SPACE // 160 Nonbreakng Space +#define ISO_8859_1_A1 KEY_1 + ALTGR_MASK // 161 ¡ Inverted Exclamation +#define ISO_8859_1_A2 KEY_C + ALTGR_MASK + SHIFT_MASK // 162 ¢ Cent SIGN +#define ISO_8859_1_A3 KEY_4 + ALTGR_MASK + SHIFT_MASK // 163 £ Pound Sign +#define ISO_8859_1_A4 KEY_4 + ALTGR_MASK // 164 ¤ Currency or Euro Sign +#define ISO_8859_1_A5 KEY_MINUS + ALTGR_MASK // 165 ¥ YEN SIGN +#define ISO_8859_1_A6 KEY_BACKSLASH + ALTGR_MASK + SHIFT_MASK // 166 ¦ BROKEN BAR ?? +#define ISO_8859_1_A7 KEY_S + ALTGR_MASK + SHIFT_MASK // 167 § SECTION SIGN +#define ISO_8859_1_A8 KEY_QUOTE + ALTGR_MASK + SHIFT_MASK // 168 ¨ DIAERESIS +#define ISO_8859_1_A9 KEY_C + ALTGR_MASK // 169 © COPYRIGHT SIGN +#define ISO_8859_1_AA 0 // 170 ª FEMININE ORDINAL +#define ISO_8859_1_AB KEY_LEFT_BRACE + ALTGR_MASK // 171 « LEFT DOUBLE ANGLE QUOTE +#define ISO_8859_1_AC KEY_BACKSLASH + ALTGR_MASK // 172 ¬ NOT SIGN ?? +#define ISO_8859_1_AD 0 // 173 SOFT HYPHEN +#define ISO_8859_1_AE KEY_R + ALTGR_MASK // 174 ® REGISTERED SIGN +#define ISO_8859_1_AF 0 // 175 ¯ MACRON +#define ISO_8859_1_B0 KEY_SEMICOLON + ALTGR_MASK + SHIFT_MASK // 176 ° DEGREE SIGN +#define ISO_8859_1_B1 0 // 177 ± PLUS-MINUS SIGN +#define ISO_8859_1_B2 KEY_2 + ALTGR_MASK // 178 ² SUPERSCRIPT TWO +#define ISO_8859_1_B3 KEY_3 + ALTGR_MASK // 179 ³ SUPERSCRIPT THREE +#define ISO_8859_1_B4 KEY_QUOTE + ALTGR_MASK // 180 ´ ACUTE ACCENT +#define ISO_8859_1_B5 KEY_M + ALTGR_MASK // 181 µ MICRO SIGN +#define ISO_8859_1_B6 KEY_SEMICOLON + ALTGR_MASK // 182 ¶ PILCROW SIGN +#define ISO_8859_1_B7 0 // 183 · MIDDLE DOT +#define ISO_8859_1_B8 0 // 184 ¸ CEDILLA +#define ISO_8859_1_B9 KEY_1 + ALTGR_MASK + SHIFT_MASK // 185 ¹ SUPERSCRIPT ONE +#define ISO_8859_1_BA 0 // 186 º MASCULINE ORDINAL +#define ISO_8859_1_BB KEY_RIGHT_BRACE + ALTGR_MASK // 187 » RIGHT DOUBLE ANGLE QUOTE +#define ISO_8859_1_BC KEY_6 + ALTGR_MASK // 188 ¼ FRACTION ONE QUARTER +#define ISO_8859_1_BD KEY_7 + ALTGR_MASK // 189 ½ FRACTION ONE HALF +#define ISO_8859_1_BE KEY_8 + ALTGR_MASK // 190 ¾ FRACTION THREE QUARTERS +#define ISO_8859_1_BF KEY_SLASH + ALTGR_MASK // 191 ¿ INVERTED QUESTION MARK +#define ISO_8859_1_C0 GRAVE_ACCENT_BITS + KEY_A + SHIFT_MASK // 192 À A GRAVE +#define ISO_8859_1_C1 KEY_A + ALTGR_MASK + SHIFT_MASK // 193 à A ACUTE +#define ISO_8859_1_C2 CIRCUMFLEX_BITS + KEY_A + SHIFT_MASK // 194 Â A CIRCUMFLEX +#define ISO_8859_1_C3 TILDE_BITS + KEY_A + SHIFT_MASK // 195 Ã A TILDE +#define ISO_8859_1_C4 KEY_Q + ALTGR_MASK + SHIFT_MASK // 196 Ä A DIAERESIS +#define ISO_8859_1_C5 KEY_W + ALTGR_MASK + SHIFT_MASK // 197 Å A RING ABOVE +#define ISO_8859_1_C6 KEY_Z + ALTGR_MASK + SHIFT_MASK // 198 Æ AE +#define ISO_8859_1_C7 KEY_COMMA + ALTGR_MASK + SHIFT_MASK // 199 Ç C CEDILLA +#define ISO_8859_1_C8 GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK // 200 È E GRAVE +#define ISO_8859_1_C9 KEY_E + ALTGR_MASK + SHIFT_MASK // 201 É E ACUTE +#define ISO_8859_1_CA CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK // 202 Ê E CIRCUMFLEX +#define ISO_8859_1_CB DIAERESIS_BITS + KEY_E + SHIFT_MASK // 203 Ë E DIAERESIS +#define ISO_8859_1_CC GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK // 204 Ì I GRAVE +#define ISO_8859_1_CD KEY_I + ALTGR_MASK + SHIFT_MASK // 205 à I ACUTE +#define ISO_8859_1_CE CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK // 206 Î I CIRCUMFLEX +#define ISO_8859_1_CF DIAERESIS_BITS + KEY_I + SHIFT_MASK // 207 à I DIAERESIS +#define ISO_8859_1_D0 KEY_D + ALTGR_MASK + SHIFT_MASK // 208 à ETH +#define ISO_8859_1_D1 KEY_N + ALTGR_MASK + SHIFT_MASK // 209 Ñ N TILDE +#define ISO_8859_1_D2 GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK // 210 Ò O GRAVE +#define ISO_8859_1_D3 KEY_O + ALTGR_MASK + SHIFT_MASK // 211 Ó O ACUTE +#define ISO_8859_1_D4 CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK // 212 Ô O CIRCUMFLEX +#define ISO_8859_1_D5 TILDE_BITS + KEY_O + SHIFT_MASK // 213 Õ O TILDE +#define ISO_8859_1_D6 KEY_P + ALTGR_MASK + SHIFT_MASK // 214 Ö O DIAERESIS +#define ISO_8859_1_D7 KEY_EQUAL + ALTGR_MASK // 215 × MULTIPLICATION +#define ISO_8859_1_D8 KEY_L + ALTGR_MASK + SHIFT_MASK // 216 Ø O STROKE +#define ISO_8859_1_D9 GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK // 217 Ù U GRAVE +#define ISO_8859_1_DA KEY_U + ALTGR_MASK + SHIFT_MASK // 218 Ú U ACUTE +#define ISO_8859_1_DB CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK // 219 Û U CIRCUMFLEX +#define ISO_8859_1_DC KEY_Y + ALTGR_MASK + SHIFT_MASK // 220 Ü U DIAERESIS +#define ISO_8859_1_DD ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK // 221 à Y ACUTE +#define ISO_8859_1_DE KEY_T + ALTGR_MASK + SHIFT_MASK // 222 Þ THORN +#define ISO_8859_1_DF KEY_S + ALTGR_MASK // 223 ß SHARP S +#define ISO_8859_1_E0 GRAVE_ACCENT_BITS + KEY_A // 224 à a GRAVE +#define ISO_8859_1_E1 KEY_A + ALTGR_MASK // 225 á a ACUTE +#define ISO_8859_1_E2 CIRCUMFLEX_BITS + KEY_A // 226 â a CIRCUMFLEX +#define ISO_8859_1_E3 TILDE_BITS + KEY_A // 227 ã a TILDE +#define ISO_8859_1_E4 DIAERESIS_BITS + KEY_A // 228 ä a DIAERESIS +#define ISO_8859_1_E5 KEY_W + ALTGR_MASK // 229 å a RING ABOVE +#define ISO_8859_1_E6 KEY_Z + ALTGR_MASK // 230 æ ae +#define ISO_8859_1_E7 KEY_COMMA + ALTGR_MASK // 231 ç c CEDILLA +#define ISO_8859_1_E8 GRAVE_ACCENT_BITS + KEY_E // 232 è e GRAVE +#define ISO_8859_1_E9 ACUTE_ACCENT_BITS + KEY_E // 233 é e ACUTE +#define ISO_8859_1_EA CIRCUMFLEX_BITS + KEY_E // 234 ê e CIRCUMFLEX +#define ISO_8859_1_EB DIAERESIS_BITS + KEY_E // 235 ë e DIAERESIS +#define ISO_8859_1_EC GRAVE_ACCENT_BITS + KEY_I // 236 ì i GRAVE +#define ISO_8859_1_ED KEY_I + ALTGR_MASK // 237 à i ACUTE +#define ISO_8859_1_EE CIRCUMFLEX_BITS + KEY_I // 238 î i CIRCUMFLEX +#define ISO_8859_1_EF DIAERESIS_BITS + KEY_I // 239 ï i DIAERESIS +#define ISO_8859_1_F0 KEY_D + ALTGR_MASK // 240 ð ETH +#define ISO_8859_1_F1 KEY_N + ALTGR_MASK // 241 ñ n TILDE +#define ISO_8859_1_F2 GRAVE_ACCENT_BITS + KEY_O // 242 ò o GRAVE +#define ISO_8859_1_F3 KEY_O + ALTGR_MASK // 243 ó o ACUTE +#define ISO_8859_1_F4 CIRCUMFLEX_BITS + KEY_O // 244 ô o CIRCUMFLEX +#define ISO_8859_1_F5 TILDE_BITS + KEY_O // 245 õ o TILDE +#define ISO_8859_1_F6 KEY_P + ALTGR_MASK // 246 ö o DIAERESIS +#define ISO_8859_1_F7 KEY_EQUAL + ALTGR_MASK + SHIFT_MASK // 247 ÷ DIVISION +#define ISO_8859_1_F8 KEY_L + ALTGR_MASK // 248 ø o STROKE +#define ISO_8859_1_F9 GRAVE_ACCENT_BITS + KEY_U // 249 ù u GRAVE +#define ISO_8859_1_FA KEY_U + ALTGR_MASK // 250 ú u ACUTE +#define ISO_8859_1_FB CIRCUMFLEX_BITS + KEY_U // 251 û u CIRCUMFLEX +#define ISO_8859_1_FC KEY_Y + ALTGR_MASK // 252 ü u DIAERESIS +#define ISO_8859_1_FD ACUTE_ACCENT_BITS + KEY_Y // 253 ý y ACUTE +#define ISO_8859_1_FE KEY_T + ALTGR_MASK // 254 þ THORN +#define ISO_8859_1_FF DIAERESIS_BITS + KEY_Y // 255 ÿ y DIAERESIS +#define UNICODE_20AC KEY_5 + ALTGR_MASK // € Euro Sign +// not yet implemented +#define UNICODE_EXTRA00 0x20AC +#define KEYCODE_EXTRA00 KEY_5 + ALTGR_MASK // 20AC € Euro Sign + +#endif // LAYOUT_US_INTERNATIONAL + + + +#ifdef LAYOUT_GERMAN + +#define SHIFT_MASK 0x0040 +#define ALTGR_MASK 0x0080 +#define DEADKEYS_MASK 0x0700 +#define SHIFT_MASK 0x0100 +#define ALTGR_MASK 0x0200 +#define CIRCUMFLEX_BITS 0x0300 +#define ACUTE_ACCENT_BITS 0x0400 +#define GRAVE_ACCENT_BITS 0x0500 +#define KEYCODE_TYPE uint16_t +#define DEADKEY_CIRCUMFLEX KEY_TILDE +//#define DEADKEY_CIRCUMFLEX KEY_NON_US_100 +#define DEADKEY_ACUTE_ACCENT KEY_EQUAL +#define DEADKEY_GRAVE_ACCENT KEY_EQUAL + SHIFT_MASK +#define KEY_NON_US_100 63 + +#define ASCII_20 KEY_SPACE // 32 +#define ASCII_21 KEY_1 + SHIFT_MASK // 33 ! +#define ASCII_22 KEY_2 + SHIFT_MASK // 34 " +#define ASCII_23 KEY_BACKSLASH // 35 # ?? +#define ASCII_24 KEY_4 + SHIFT_MASK // 36 $ +#define ASCII_25 KEY_5 + SHIFT_MASK // 37 % +#define ASCII_26 KEY_6 + SHIFT_MASK // 38 & +#define ASCII_27 KEY_BACKSLASH + SHIFT_MASK // 39 ' +#define ASCII_28 KEY_8 + SHIFT_MASK // 40 ( +#define ASCII_29 KEY_9 + SHIFT_MASK // 41 ) +#define ASCII_2A KEY_RIGHT_BRACE + SHIFT_MASK // 42 * +#define ASCII_2B KEY_RIGHT_BRACE // 43 + +#define ASCII_2C KEY_COMMA // 44 , +#define ASCII_2D KEY_SLASH // 45 - +#define ASCII_2E KEY_PERIOD // 46 . +#define ASCII_2F KEY_7 + SHIFT_MASK // 47 / +#define ASCII_30 KEY_0 // 48 0 +#define ASCII_31 KEY_1 // 49 1 +#define ASCII_32 KEY_2 // 50 2 +#define ASCII_33 KEY_3 // 51 3 +#define ASCII_34 KEY_4 // 52 4 +#define ASCII_35 KEY_5 // 53 5 +#define ASCII_36 KEY_6 // 54 6 +#define ASCII_37 KEY_7 // 55 7 +#define ASCII_38 KEY_8 // 55 8 +#define ASCII_39 KEY_9 // 57 9 +#define ASCII_3A KEY_PERIOD + SHIFT_MASK // 58 : +#define ASCII_3B KEY_COMMA + SHIFT_MASK // 59 ; +#define ASCII_3C KEY_NON_US_100 // 60 < +#define ASCII_3D KEY_0 + SHIFT_MASK // 61 = +#define ASCII_3E KEY_NON_US_100 + SHIFT_MASK // 62 > +#define ASCII_3F KEY_MINUS + SHIFT_MASK // 63 ? +#define ASCII_40 KEY_Q + ALTGR_MASK // 64 @ +#define ASCII_41 KEY_A + SHIFT_MASK // 65 A +#define ASCII_42 KEY_B + SHIFT_MASK // 66 B +#define ASCII_43 KEY_C + SHIFT_MASK // 67 C +#define ASCII_44 KEY_D + SHIFT_MASK // 68 D +#define ASCII_45 KEY_E + SHIFT_MASK // 69 E +#define ASCII_46 KEY_F + SHIFT_MASK // 70 F +#define ASCII_47 KEY_G + SHIFT_MASK // 71 G +#define ASCII_48 KEY_H + SHIFT_MASK // 72 H +#define ASCII_49 KEY_I + SHIFT_MASK // 73 I +#define ASCII_4A KEY_J + SHIFT_MASK // 74 J +#define ASCII_4B KEY_K + SHIFT_MASK // 75 K +#define ASCII_4C KEY_L + SHIFT_MASK // 76 L +#define ASCII_4D KEY_M + SHIFT_MASK // 77 M +#define ASCII_4E KEY_N + SHIFT_MASK // 78 N +#define ASCII_4F KEY_O + SHIFT_MASK // 79 O +#define ASCII_50 KEY_P + SHIFT_MASK // 80 P +#define ASCII_51 KEY_Q + SHIFT_MASK // 81 Q +#define ASCII_52 KEY_R + SHIFT_MASK // 82 R +#define ASCII_53 KEY_S + SHIFT_MASK // 83 S +#define ASCII_54 KEY_T + SHIFT_MASK // 84 T +#define ASCII_55 KEY_U + SHIFT_MASK // 85 U +#define ASCII_56 KEY_V + SHIFT_MASK // 86 V +#define ASCII_57 KEY_W + SHIFT_MASK // 87 W +#define ASCII_58 KEY_X + SHIFT_MASK // 88 X +#define ASCII_59 KEY_Z + SHIFT_MASK // 89 Y +#define ASCII_5A KEY_Y + SHIFT_MASK // 90 Z +#define ASCII_5B KEY_8 + ALTGR_MASK // 91 [ +#define ASCII_5C KEY_MINUS + ALTGR_MASK // 92 +#define ASCII_5D KEY_9 + ALTGR_MASK // 93 ] +#define ASCII_5E CIRCUMFLEX_BITS + KEY_SPACE // 94 ^ +#define ASCII_5F KEY_SLASH + SHIFT_MASK // 95 _ +#define ASCII_60 GRAVE_ACCENT_BITS + KEY_SPACE // 96 ` +#define ASCII_61 KEY_A // 97 a +#define ASCII_62 KEY_B // 98 b +#define ASCII_63 KEY_C // 99 c +#define ASCII_64 KEY_D // 100 d +#define ASCII_65 KEY_E // 101 e +#define ASCII_66 KEY_F // 102 f +#define ASCII_67 KEY_G // 103 g +#define ASCII_68 KEY_H // 104 h +#define ASCII_69 KEY_I // 105 i +#define ASCII_6A KEY_J // 106 j +#define ASCII_6B KEY_K // 107 k +#define ASCII_6C KEY_L // 108 l +#define ASCII_6D KEY_M // 109 m +#define ASCII_6E KEY_N // 110 n +#define ASCII_6F KEY_O // 111 o +#define ASCII_70 KEY_P // 112 p +#define ASCII_71 KEY_Q // 113 q +#define ASCII_72 KEY_R // 114 r +#define ASCII_73 KEY_S // 115 s +#define ASCII_74 KEY_T // 116 t +#define ASCII_75 KEY_U // 117 u +#define ASCII_76 KEY_V // 118 v +#define ASCII_77 KEY_W // 119 w +#define ASCII_78 KEY_X // 120 x +#define ASCII_79 KEY_Z // 121 y +#define ASCII_7A KEY_Y // 122 z +#define ASCII_7B KEY_7 + ALTGR_MASK // 123 { +#define ASCII_7C KEY_NON_US_100 + ALTGR_MASK // 124 | +#define ASCII_7D KEY_0 + ALTGR_MASK // 125 } +#define ASCII_7E KEY_RIGHT_BRACE + ALTGR_MASK // 126 ~ +#define ASCII_7F KEY_BACKSPACE // 127 +#define ISO_8859_1_A0 KEY_SPACE // 160 Nonbreakng Space +#define ISO_8859_1_A1 0 // 161 ¡ Inverted Exclamation +#define ISO_8859_1_A2 0 // 162 ¢ Cent Sign +#define ISO_8859_1_A3 0 // 163 £ Pound Sign +#define ISO_8859_1_A4 KEY_E + ALTGR_MASK // 164 ¤ Currency Sign +#define ISO_8859_1_A5 0 // 165 ¥ YEN SIGN +#define ISO_8859_1_A6 0 // 166 ¦ BROKEN BAR +#define ISO_8859_1_A7 KEY_3 + SHIFT_MASK // 167 § SECTION SIGN +#define ISO_8859_1_A8 0 // 168 ¨ DIAERESIS +#define ISO_8859_1_A9 0 // 169 © COPYRIGHT SIGN +#define ISO_8859_1_AA 0 // 170 ª FEMININE ORDINAL +#define ISO_8859_1_AB 0 // 171 « LEFT DOUBLE ANGLE QUOTE +#define ISO_8859_1_AC 0 // 172 ¬ NOT SIGN +#define ISO_8859_1_AD 0 // 173 SOFT HYPHEN +#define ISO_8859_1_AE 0 // 174 ® REGISTERED SIGN +#define ISO_8859_1_AF 0 // 175 ¯ MACRON +#define ISO_8859_1_B0 KEY_TILDE + SHIFT_MASK // 176 ° DEGREE SIGN +#define ISO_8859_1_B1 0 // 177 ± PLUS-MINUS SIGN +#define ISO_8859_1_B2 KEY_2 + ALTGR_MASK // 178 ² SUPERSCRIPT TWO +#define ISO_8859_1_B3 KEY_3 + ALTGR_MASK // 179 ³ SUPERSCRIPT THREE +#define ISO_8859_1_B4 0 // 180 ´ ACUTE ACCENT +#define ISO_8859_1_B5 KEY_M + ALTGR_MASK // 181 µ MICRO SIGN +#define ISO_8859_1_B6 0 // 182 ¶ PILCROW SIGN +#define ISO_8859_1_B7 0 // 183 · MIDDLE DOT +#define ISO_8859_1_B8 0 // 184 ¸ CEDILLA +#define ISO_8859_1_B9 0 // 185 ¹ SUPERSCRIPT ONE +#define ISO_8859_1_BA 0 // 186 º MASCULINE ORDINAL +#define ISO_8859_1_BB 0 // 187 » RIGHT DOUBLE ANGLE QUOTE +#define ISO_8859_1_BC 0 // 188 ¼ FRACTION ONE QUARTER +#define ISO_8859_1_BD 0 // 189 ½ FRACTION ONE HALF +#define ISO_8859_1_BE 0 // 190 ¾ FRACTION THREE QUARTERS +#define ISO_8859_1_BF 0 // 191 ¿ INVERTED QUESTION MARK +#define ISO_8859_1_C0 GRAVE_ACCENT_BITS + KEY_A + SHIFT_MASK // 192 À A GRAVE +#define ISO_8859_1_C1 ACUTE_ACCENT_BITS + KEY_A + SHIFT_MASK // 193 à A ACUTE +#define ISO_8859_1_C2 CIRCUMFLEX_BITS + KEY_A + SHIFT_MASK // 194 Â A CIRCUMFLEX +#define ISO_8859_1_C3 0 // 195 Ã A TILDE +#define ISO_8859_1_C4 KEY_QUOTE + SHIFT_MASK // 196 Ä A DIAERESIS +#define ISO_8859_1_C5 0 // 197 Å A RING ABOVE +#define ISO_8859_1_C6 0 // 198 Æ AE +#define ISO_8859_1_C7 0 // 199 Ç C CEDILLA +#define ISO_8859_1_C8 GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK // 200 È E GRAVE +#define ISO_8859_1_C9 ACUTE_ACCENT_BITS + KEY_E + SHIFT_MASK // 201 É E ACUTE +#define ISO_8859_1_CA CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK // 202 Ê E CIRCUMFLEX +#define ISO_8859_1_CB 0 // 203 Ë E DIAERESIS +#define ISO_8859_1_CC GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK // 204 Ì I GRAVE +#define ISO_8859_1_CD ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK // 205 à I ACUTE +#define ISO_8859_1_CE CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK // 206 Î I CIRCUMFLEX +#define ISO_8859_1_CF 0 // 207 à I DIAERESIS +#define ISO_8859_1_D0 0 // 208 à ETH +#define ISO_8859_1_D1 0 // 209 Ñ N TILDE +#define ISO_8859_1_D2 GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK // 210 Ò O GRAVE +#define ISO_8859_1_D3 ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK // 211 Ó O ACUTE +#define ISO_8859_1_D4 CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK // 212 Ô O CIRCUMFLEX +#define ISO_8859_1_D5 0 // 213 Õ O TILDE +#define ISO_8859_1_D6 KEY_SEMICOLON + SHIFT_MASK // 214 Ö O DIAERESIS +#define ISO_8859_1_D7 0 // 215 × MULTIPLICATION +#define ISO_8859_1_D8 0 // 216 Ø O STROKE +#define ISO_8859_1_D9 GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK // 217 Ù U GRAVE +#define ISO_8859_1_DA ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK // 218 Ú U ACUTE +#define ISO_8859_1_DB CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK // 219 Û U CIRCUMFLEX +#define ISO_8859_1_DC KEY_LEFT_BRACE + SHIFT_MASK // 220 Ü U DIAERESIS +#define ISO_8859_1_DD ACUTE_ACCENT_BITS + KEY_Z + SHIFT_MASK // 221 à Y ACUTE +#define ISO_8859_1_DE 0 // 222 Þ THORN +#define ISO_8859_1_DF KEY_MINUS // 223 ß SHARP S +#define ISO_8859_1_E0 GRAVE_ACCENT_BITS + KEY_A // 224 à a GRAVE +#define ISO_8859_1_E1 ACUTE_ACCENT_BITS + KEY_A // 225 á a ACUTE +#define ISO_8859_1_E2 CIRCUMFLEX_BITS + KEY_A // 226 â a CIRCUMFLEX +#define ISO_8859_1_E3 0 // 227 ã a TILDE +#define ISO_8859_1_E4 KEY_QUOTE // 228 ä a DIAERESIS +#define ISO_8859_1_E5 0 // 229 å a RING ABOVE +#define ISO_8859_1_E6 0 // 230 æ ae +#define ISO_8859_1_E7 0 // 231 ç c CEDILLA +#define ISO_8859_1_E8 GRAVE_ACCENT_BITS + KEY_E // 232 è e GRAVE +#define ISO_8859_1_E9 ACUTE_ACCENT_BITS + KEY_E // 233 é e ACUTE +#define ISO_8859_1_EA CIRCUMFLEX_BITS + KEY_E // 234 ê e CIRCUMFLEX +#define ISO_8859_1_EB 0 // 235 ë e DIAERESIS +#define ISO_8859_1_EC GRAVE_ACCENT_BITS + KEY_I // 236 ì i GRAVE +#define ISO_8859_1_ED ACUTE_ACCENT_BITS + KEY_I // 237 à i ACUTE +#define ISO_8859_1_EE CIRCUMFLEX_BITS + KEY_I // 238 î i CIRCUMFLEX +#define ISO_8859_1_EF 0 // 239 ï i DIAERESIS +#define ISO_8859_1_F0 0 // 240 ð ETH +#define ISO_8859_1_F1 0 // 241 ñ n TILDE +#define ISO_8859_1_F2 GRAVE_ACCENT_BITS + KEY_O // 242 ò o GRAVE +#define ISO_8859_1_F3 ACUTE_ACCENT_BITS + KEY_O // 243 ó o ACUTE +#define ISO_8859_1_F4 CIRCUMFLEX_BITS + KEY_O // 244 ô o CIRCUMFLEX +#define ISO_8859_1_F5 0 // 245 õ o TILDE +#define ISO_8859_1_F6 KEY_SEMICOLON // 246 ö o DIAERESIS +#define ISO_8859_1_F7 0 // 247 ÷ DIVISION +#define ISO_8859_1_F8 0 // 248 ø o STROKE +#define ISO_8859_1_F9 GRAVE_ACCENT_BITS + KEY_U // 249 ù u GRAVE +#define ISO_8859_1_FA ACUTE_ACCENT_BITS + KEY_U // 250 ú u ACUTE +#define ISO_8859_1_FB CIRCUMFLEX_BITS + KEY_U // 251 û u CIRCUMFLEX +#define ISO_8859_1_FC KEY_LEFT_BRACE // 252 ü u DIAERESIS +#define ISO_8859_1_FD ACUTE_ACCENT_BITS + KEY_Z // 253 ý y ACUTE +#define ISO_8859_1_FE 0 // 254 þ THORN +#define ISO_8859_1_FF 0 // 255 ÿ y DIAERESIS +#define UNICODE_20AC KEY_E + ALTGR_MASK // € Euro Sign +// not yet implemented +#define UNICODE_EXTRA00 0x20AC +#define KEYCODE_EXTRA00 KEY_E + ALTGR_MASK // 20AC € Euro Sign + +#endif // LAYOUT_GERMAN + + + +#ifdef LAYOUT_GERMAN_MAC + +#define SHIFT_MASK 0x0040 +#define ALTGR_MASK 0x0080 +#define DEADKEYS_MASK 0x0700 +#define ACUTE_ACCENT_BITS 0x0100 +#define GRAVE_ACCENT_BITS 0x0200 +#define CIRCUMFLEX_BITS 0x0300 +#define DIAERESIS_BITS 0x0400 +#define TILDE_BITS 0x0500 +#define KEYCODE_TYPE uint16_t +#define DEADKEY_ACUTE_ACCENT KEY_EQUAL +#define DEADKEY_GRAVE_ACCENT KEY_EQUAL + SHIFT_MASK +#define DEADKEY_CIRCUMFLEX KEY_6 + SHIFT_MASK + ALTGR_MASK +#define DEADKEY_DIAERESIS KEY_U + ALTGR_MASK +#define DEADKEY_TILDE KEY_N + ALTGR_MASK +#define KEY_NON_US_100 63 + +#define ASCII_20 KEY_SPACE // 32 +#define ASCII_21 KEY_1 + SHIFT_MASK // 33 ! +#define ASCII_22 KEY_2 + SHIFT_MASK // 34 " +#define ASCII_23 KEY_BACKSLASH // 35 # ?? +#define ASCII_24 KEY_4 + SHIFT_MASK // 36 $ +#define ASCII_25 KEY_5 + SHIFT_MASK // 37 % +#define ASCII_26 KEY_6 + SHIFT_MASK // 38 & +#define ASCII_27 KEY_BACKSLASH + SHIFT_MASK // 39 ' +#define ASCII_28 KEY_8 + SHIFT_MASK // 40 ( +#define ASCII_29 KEY_9 + SHIFT_MASK // 41 ) +#define ASCII_2A KEY_RIGHT_BRACE + SHIFT_MASK // 42 * +#define ASCII_2B KEY_RIGHT_BRACE // 43 + +#define ASCII_2C KEY_COMMA // 44 , +#define ASCII_2D KEY_SLASH // 45 - +#define ASCII_2E KEY_PERIOD // 46 . +#define ASCII_2F KEY_7 + SHIFT_MASK // 47 / +#define ASCII_30 KEY_0 // 48 0 +#define ASCII_31 KEY_1 // 49 1 +#define ASCII_32 KEY_2 // 50 2 +#define ASCII_33 KEY_3 // 51 3 +#define ASCII_34 KEY_4 // 52 4 +#define ASCII_35 KEY_5 // 53 5 +#define ASCII_36 KEY_6 // 54 6 +#define ASCII_37 KEY_7 // 55 7 +#define ASCII_38 KEY_8 // 55 8 +#define ASCII_39 KEY_9 // 57 9 +#define ASCII_3A KEY_PERIOD + SHIFT_MASK // 58 : +#define ASCII_3B KEY_COMMA + SHIFT_MASK // 59 ; +#define ASCII_3C KEY_TILDE // 60 < +#define ASCII_3D KEY_0 + SHIFT_MASK // 61 = +#define ASCII_3E KEY_TILDE + SHIFT_MASK // 62 > +#define ASCII_3F KEY_MINUS + SHIFT_MASK // 63 ? +#define ASCII_40 KEY_Q + ALTGR_MASK // 64 @ +#define ASCII_41 KEY_A + SHIFT_MASK // 65 A +#define ASCII_42 KEY_B + SHIFT_MASK // 66 B +#define ASCII_43 KEY_C + SHIFT_MASK // 67 C +#define ASCII_44 KEY_D + SHIFT_MASK // 68 D +#define ASCII_45 KEY_E + SHIFT_MASK // 69 E +#define ASCII_46 KEY_F + SHIFT_MASK // 70 F +#define ASCII_47 KEY_G + SHIFT_MASK // 71 G +#define ASCII_48 KEY_H + SHIFT_MASK // 72 H +#define ASCII_49 KEY_I + SHIFT_MASK // 73 I +#define ASCII_4A KEY_J + SHIFT_MASK // 74 J +#define ASCII_4B KEY_K + SHIFT_MASK // 75 K +#define ASCII_4C KEY_L + SHIFT_MASK // 76 L +#define ASCII_4D KEY_M + SHIFT_MASK // 77 M +#define ASCII_4E KEY_N + SHIFT_MASK // 78 N +#define ASCII_4F KEY_O + SHIFT_MASK // 79 O +#define ASCII_50 KEY_P + SHIFT_MASK // 80 P +#define ASCII_51 KEY_Q + SHIFT_MASK // 81 Q +#define ASCII_52 KEY_R + SHIFT_MASK // 82 R +#define ASCII_53 KEY_S + SHIFT_MASK // 83 S +#define ASCII_54 KEY_T + SHIFT_MASK // 84 T +#define ASCII_55 KEY_U + SHIFT_MASK // 85 U +#define ASCII_56 KEY_V + SHIFT_MASK // 86 V +#define ASCII_57 KEY_W + SHIFT_MASK // 87 W +#define ASCII_58 KEY_X + SHIFT_MASK // 88 X +#define ASCII_59 KEY_Z + SHIFT_MASK // 89 Y +#define ASCII_5A KEY_Y + SHIFT_MASK // 90 Z +#define ASCII_5B KEY_5 + ALTGR_MASK // 91 [ +#define ASCII_5C KEY_7 + ALTGR_MASK + SHIFT_MASK // 92 +#define ASCII_5D KEY_6 + ALTGR_MASK // 93 ] +#define ASCII_5E CIRCUMFLEX_BITS + KEY_SPACE // 94 ^ +#define ASCII_5F KEY_SLASH + SHIFT_MASK // 95 _ +#define ASCII_60 GRAVE_ACCENT_BITS + KEY_SPACE // 96 ` +#define ASCII_61 KEY_A // 97 a +#define ASCII_62 KEY_B // 98 b +#define ASCII_63 KEY_C // 99 c +#define ASCII_64 KEY_D // 100 d +#define ASCII_65 KEY_E // 101 e +#define ASCII_66 KEY_F // 102 f +#define ASCII_67 KEY_G // 103 g +#define ASCII_68 KEY_H // 104 h +#define ASCII_69 KEY_I // 105 i +#define ASCII_6A KEY_J // 106 j +#define ASCII_6B KEY_K // 107 k +#define ASCII_6C KEY_L // 108 l +#define ASCII_6D KEY_M // 109 m +#define ASCII_6E KEY_N // 110 n +#define ASCII_6F KEY_O // 111 o +#define ASCII_70 KEY_P // 112 p +#define ASCII_71 KEY_Q // 113 q +#define ASCII_72 KEY_R // 114 r +#define ASCII_73 KEY_S // 115 s +#define ASCII_74 KEY_T // 116 t +#define ASCII_75 KEY_U // 117 u +#define ASCII_76 KEY_V // 118 v +#define ASCII_77 KEY_W // 119 w +#define ASCII_78 KEY_X // 120 x +#define ASCII_79 KEY_Z // 121 y +#define ASCII_7A KEY_Y // 122 z +#define ASCII_7B KEY_8 + ALTGR_MASK // 123 { +#define ASCII_7C KEY_7 + ALTGR_MASK // 124 | +#define ASCII_7D KEY_9 + ALTGR_MASK // 125 } +#define ASCII_7E TILDE_BITS + KEY_SPACE // 126 ~ +#define ASCII_7F KEY_BACKSPACE // 127 +#define ISO_8859_1_A0 KEY_SPACE // 160 Nonbreakng Space +#define ISO_8859_1_A1 KEY_1 + ALTGR_MASK // 161 ¡ Inverted Exclamation +#define ISO_8859_1_A2 KEY_4 + ALTGR_MASK // 162 ¢ Cent Sign +#define ISO_8859_1_A3 KEY_4 + SHIFT_MASK + ALTGR_MASK // 163 £ Pound Sign +#define ISO_8859_1_A4 KEY_E + ALTGR_MASK // 164 ¤ Currency Sign +#define ISO_8859_1_A5 KEY_Z + ALTGR_MASK // 165 ¥ YEN SIGN +#define ISO_8859_1_A6 0 // 166 ¦ BROKEN BAR +#define ISO_8859_1_A7 KEY_3 + SHIFT_MASK // 167 § SECTION SIGN +#define ISO_8859_1_A8 DIAERESIS_BITS + KEY_SPACE // 168 ¨ DIAERESIS +#define ISO_8859_1_A9 KEY_G + ALTGR_MASK // 169 © COPYRIGHT SIGN +#define ISO_8859_1_AA KEY_H + ALTGR_MASK // 170 ª FEMININE ORDINAL +#define ISO_8859_1_AB KEY_Q + ALTGR_MASK // 171 « LEFT DOUBLE ANGLE QUOTE +#define ISO_8859_1_AC 0 // 172 ¬ NOT SIGN +#define ISO_8859_1_AD 0 // 173 SOFT HYPHEN +#define ISO_8859_1_AE KEY_R + ALTGR_MASK // 174 ® REGISTERED SIGN +#define ISO_8859_1_AF KEY_0 + SHIFT_MASK + ALTGR_MASK // 175 ¯ MACRON +#define ISO_8859_1_B0 KEY_LEFT_BRACE + ALTGR_MASK + SHIFT_MASK// 176 ° DEGREE SIGN +#define ISO_8859_1_B1 KEY_RIGHT_BRACE + ALTGR_MASK // 177 ± PLUS-MINUS SIGN +#define ISO_8859_1_B2 0 // 178 ² SUPERSCRIPT TWO +#define ISO_8859_1_B3 0 // 179 ³ SUPERSCRIPT THREE +#define ISO_8859_1_B4 ACUTE_ACCENT_BITS + KEY_SPACE // 180 ´ ACUTE ACCENT +#define ISO_8859_1_B5 KEY_M + ALTGR_MASK // 181 µ MICRO SIGN +#define ISO_8859_1_B6 KEY_3 + ALTGR_MASK // 182 ¶ PILCROW SIGN +#define ISO_8859_1_B7 KEY_9 + SHIFT_MASK + ALTGR_MASK // 183 · MIDDLE DOT +#define ISO_8859_1_B8 0 // 184 ¸ CEDILLA +#define ISO_8859_1_B9 0 // 185 ¹ SUPERSCRIPT ONE +#define ISO_8859_1_BA KEY_J + ALTGR_MASK // 186 º MASCULINE ORDINAL +#define ISO_8859_1_BB KEY_Q + SHIFT_MASK + ALTGR_MASK // 187 » RIGHT DOUBLE ANGLE QUOTE +#define ISO_8859_1_BC 0 // 188 ¼ FRACTION ONE QUARTER +#define ISO_8859_1_BD 0 // 189 ½ FRACTION ONE HALF +#define ISO_8859_1_BE 0 // 190 ¾ FRACTION THREE QUARTERS +#define ISO_8859_1_BF KEY_MINUS + ALTGR_MASK // 191 ¿ INVERTED QUESTION MARK +#define ISO_8859_1_C0 GRAVE_ACCENT_BITS + KEY_A + SHIFT_MASK // 192 À A GRAVE +#define ISO_8859_1_C1 ACUTE_ACCENT_BITS + KEY_A + SHIFT_MASK // 193 à A ACUTE +#define ISO_8859_1_C2 CIRCUMFLEX_BITS + KEY_A + SHIFT_MASK // 194 Â A CIRCUMFLEX +#define ISO_8859_1_C3 TILDE_BITS + KEY_A + SHIFT_MASK // 195 Ã A TILDE +#define ISO_8859_1_C4 KEY_QUOTE + SHIFT_MASK // 196 Ä A DIAERESIS +#define ISO_8859_1_C5 KEY_A + ALTGR_MASK + SHIFT_MASK // 197 Å A RING ABOVE +#define ISO_8859_1_C6 KEY_QUOTE + ALTGR_MASK + SHIFT_MASK // 198 Æ AE +#define ISO_8859_1_C7 KEY_C + ALTGR_MASK + SHIFT_MASK // 199 Ç C CEDILLA +#define ISO_8859_1_C8 GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK // 200 È E GRAVE +#define ISO_8859_1_C9 ACUTE_ACCENT_BITS + KEY_E + SHIFT_MASK // 201 É E ACUTE +#define ISO_8859_1_CA CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK // 202 Ê E CIRCUMFLEX +#define ISO_8859_1_CB DIAERESIS_BITS + KEY_E + SHIFT_MASK // 203 Ë E DIAERESIS +#define ISO_8859_1_CC GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK // 204 Ì I GRAVE +#define ISO_8859_1_CD ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK // 205 à I ACUTE +#define ISO_8859_1_CE CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK // 206 Î I CIRCUMFLEX +#define ISO_8859_1_CF DIAERESIS_BITS + KEY_I + SHIFT_MASK // 207 à I DIAERESIS +#define ISO_8859_1_D0 0 // 208 à ETH +#define ISO_8859_1_D1 TILDE_BITS + KEY_N + SHIFT_MASK // 209 Ñ N TILDE +#define ISO_8859_1_D2 GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK // 210 Ò O GRAVE +#define ISO_8859_1_D3 ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK // 211 Ó O ACUTE +#define ISO_8859_1_D4 CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK // 212 Ô O CIRCUMFLEX +#define ISO_8859_1_D5 TILDE_BITS + KEY_O + SHIFT_MASK // 213 Õ O TILDE +#define ISO_8859_1_D6 KEY_SEMICOLON + SHIFT_MASK // 214 Ö O DIAERESIS +#define ISO_8859_1_D7 0 // 215 × MULTIPLICATION +#define ISO_8859_1_D8 KEY_O + ALTGR_MASK + SHIFT_MASK // 216 Ø O STROKE +#define ISO_8859_1_D9 GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK // 217 Ù U GRAVE +#define ISO_8859_1_DA ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK // 218 Ú U ACUTE +#define ISO_8859_1_DB CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK // 219 Û U CIRCUMFLEX +#define ISO_8859_1_DC KEY_LEFT_BRACE + SHIFT_MASK // 220 Ü U DIAERESIS +#define ISO_8859_1_DD ACUTE_ACCENT_BITS + KEY_Z + SHIFT_MASK // 221 à Y ACUTE +#define ISO_8859_1_DE 0 // 222 Þ THORN +#define ISO_8859_1_DF KEY_MINUS // 223 ß SHARP S +#define ISO_8859_1_E0 GRAVE_ACCENT_BITS + KEY_A // 224 à a GRAVE +#define ISO_8859_1_E1 ACUTE_ACCENT_BITS + KEY_A // 225 á a ACUTE +#define ISO_8859_1_E2 CIRCUMFLEX_BITS + KEY_A // 226 â a CIRCUMFLEX +#define ISO_8859_1_E3 TILDE_BITS + KEY_A // 227 ã a TILDE +#define ISO_8859_1_E4 KEY_QUOTE // 228 ä a DIAERESIS +#define ISO_8859_1_E5 KEY_A + ALTGR_MASK // 229 å a RING ABOVE +#define ISO_8859_1_E6 KEY_QUOTE + ALTGR_MASK // 230 æ ae +#define ISO_8859_1_E7 KEY_C + ALTGR_MASK // 231 ç c CEDILLA +#define ISO_8859_1_E8 GRAVE_ACCENT_BITS + KEY_E // 232 è e GRAVE +#define ISO_8859_1_E9 ACUTE_ACCENT_BITS + KEY_E // 233 é e ACUTE +#define ISO_8859_1_EA CIRCUMFLEX_BITS + KEY_E // 234 ê e CIRCUMFLEX +#define ISO_8859_1_EB DIAERESIS_BITS + KEY_E // 235 ë e DIAERESIS +#define ISO_8859_1_EC GRAVE_ACCENT_BITS + KEY_I // 236 ì i GRAVE +#define ISO_8859_1_ED ACUTE_ACCENT_BITS + KEY_I // 237 à i ACUTE +#define ISO_8859_1_EE CIRCUMFLEX_BITS + KEY_I // 238 î i CIRCUMFLEX +#define ISO_8859_1_EF DIAERESIS_BITS + KEY_I // 239 ï i DIAERESIS +#define ISO_8859_1_F0 0 // 240 ð ETH +#define ISO_8859_1_F1 TILDE_BITS + KEY_N // 241 ñ n TILDE +#define ISO_8859_1_F2 GRAVE_ACCENT_BITS + KEY_O // 242 ò o GRAVE +#define ISO_8859_1_F3 ACUTE_ACCENT_BITS + KEY_O // 243 ó o ACUTE +#define ISO_8859_1_F4 CIRCUMFLEX_BITS + KEY_O // 244 ô o CIRCUMFLEX +#define ISO_8859_1_F5 TILDE_BITS + KEY_O // 245 õ o TILDE +#define ISO_8859_1_F6 KEY_SEMICOLON // 246 ö o DIAERESIS +#define ISO_8859_1_F7 0 // 247 ÷ DIVISION +#define ISO_8859_1_F8 KEY_O + ALTGR_MASK // 248 ø o STROKE +#define ISO_8859_1_F9 GRAVE_ACCENT_BITS + KEY_U // 249 ù u GRAVE +#define ISO_8859_1_FA ACUTE_ACCENT_BITS + KEY_U // 250 ú u ACUTE +#define ISO_8859_1_FB CIRCUMFLEX_BITS + KEY_U // 251 û u CIRCUMFLEX +#define ISO_8859_1_FC KEY_LEFT_BRACE // 252 ü u DIAERESIS +#define ISO_8859_1_FD ACUTE_ACCENT_BITS + KEY_Z // 253 ý y ACUTE +#define ISO_8859_1_FE 0 // 254 þ THORN +#define ISO_8859_1_FF DIAERESIS_BITS + KEY_Z // 255 ÿ y DIAERESIS +#define UNICODE_20AC KEY_E + ALTGR_MASK // € Euro Sign +// not yet implemented +#define UNICODE_EXTRA00 0x20AC +#define KEYCODE_EXTRA00 KEY_E + ALTGR_MASK // 20AC € Euro Sign + +#endif // LAYOUT_GERMAN_MAC + + + + + + +#ifdef LAYOUT_CANADIAN_FRENCH + +#define SHIFT_MASK 0x0040 +#define ALTGR_MASK 0x0080 +#define DEADKEYS_MASK 0x0700 +#define CIRCUMFLEX_BITS 0x0100 +#define ACUTE_ACCENT_BITS 0x0200 +#define GRAVE_ACCENT_BITS 0x0300 +#define DIAERESIS_BITS 0x0400 +#define CEDILLA_BITS 0x0500 + +#define KEYCODE_TYPE uint16_t +#define DEADKEY_CIRCUMFLEX KEY_LEFT_BRACE +#define DEADKEY_ACUTE_ACCENT KEY_SLASH + ALTGR_MASK +#define DEADKEY_GRAVE_ACCENT KEY_QUOTE +#define DEADKEY_DIAERESIS KEY_RIGHT_BRACE + SHIFT_MASK +#define DEADKEY_CEDILLA KEY_RIGHT_BRACE +#define KEY_NON_US_100 63 + +#define ASCII_20 KEY_SPACE // 32 +#define ASCII_21 KEY_1 + SHIFT_MASK // 33 ! +#define ASCII_22 KEY_2 + SHIFT_MASK // 34 " +#define ASCII_23 KEY_TILDE + SHIFT_MASK // 35 # +#define ASCII_24 KEY_4 + SHIFT_MASK // 36 $ +#define ASCII_25 KEY_5 + SHIFT_MASK // 37 % +#define ASCII_26 KEY_7 + SHIFT_MASK // 38 & +#define ASCII_27 KEY_COMMA + SHIFT_MASK // 39 ' +#define ASCII_27 ACUTE_ACCENT_BITS + KEY_SPACE // 39 ' +#define ASCII_28 KEY_9 + SHIFT_MASK // 40 ( +#define ASCII_29 KEY_0 + SHIFT_MASK // 41 ) +#define ASCII_2A KEY_8 + SHIFT_MASK // 42 * +#define ASCII_2B KEY_EQUAL + SHIFT_MASK // 43 + +#define ASCII_2C KEY_COMMA // 44 , +#define ASCII_2D KEY_MINUS // 45 - +#define ASCII_2E KEY_PERIOD // 46 . +#define ASCII_2F KEY_3 + SHIFT_MASK // 47 / +#define ASCII_30 KEY_0 // 48 0 +#define ASCII_31 KEY_1 // 49 1 +#define ASCII_32 KEY_2 // 50 2 +#define ASCII_33 KEY_3 // 51 3 +#define ASCII_34 KEY_4 // 52 4 +#define ASCII_35 KEY_5 // 53 5 +#define ASCII_36 KEY_6 // 54 6 +#define ASCII_37 KEY_7 // 55 7 +#define ASCII_38 KEY_8 // 55 8 +#define ASCII_39 KEY_9 // 57 9 +#define ASCII_3A KEY_SEMICOLON + SHIFT_MASK // 58 : +#define ASCII_3B KEY_SEMICOLON // 59 ; +#define ASCII_3C KEY_BACKSLASH // 60 < +#define ASCII_3D KEY_EQUAL // 61 = +#define ASCII_3E KEY_BACKSLASH + SHIFT_MASK // 62 > +#define ASCII_3F KEY_6 + SHIFT_MASK // 63 ? +#define ASCII_40 KEY_2 + ALTGR_MASK // 64 @ +#define ASCII_41 KEY_A + SHIFT_MASK // 65 A +#define ASCII_42 KEY_B + SHIFT_MASK // 66 B +#define ASCII_43 KEY_C + SHIFT_MASK // 67 C +#define ASCII_44 KEY_D + SHIFT_MASK // 68 D +#define ASCII_45 KEY_E + SHIFT_MASK // 69 E +#define ASCII_46 KEY_F + SHIFT_MASK // 70 F +#define ASCII_47 KEY_G + SHIFT_MASK // 71 G +#define ASCII_48 KEY_H + SHIFT_MASK // 72 H +#define ASCII_49 KEY_I + SHIFT_MASK // 73 I +#define ASCII_4A KEY_J + SHIFT_MASK // 74 J +#define ASCII_4B KEY_K + SHIFT_MASK // 75 K +#define ASCII_4C KEY_L + SHIFT_MASK // 76 L +#define ASCII_4D KEY_M + SHIFT_MASK // 77 M +#define ASCII_4E KEY_N + SHIFT_MASK // 78 N +#define ASCII_4F KEY_O + SHIFT_MASK // 79 O +#define ASCII_50 KEY_P + SHIFT_MASK // 80 P +#define ASCII_51 KEY_Q + SHIFT_MASK // 81 Q +#define ASCII_52 KEY_R + SHIFT_MASK // 82 R +#define ASCII_53 KEY_S + SHIFT_MASK // 83 S +#define ASCII_54 KEY_T + SHIFT_MASK // 84 T +#define ASCII_55 KEY_U + SHIFT_MASK // 85 U +#define ASCII_56 KEY_V + SHIFT_MASK // 86 V +#define ASCII_57 KEY_W + SHIFT_MASK // 87 W +#define ASCII_58 KEY_X + SHIFT_MASK // 88 X +#define ASCII_59 KEY_Y + SHIFT_MASK // 89 Y +#define ASCII_5A KEY_Z + SHIFT_MASK // 90 Z +#define ASCII_5B KEY_LEFT_BRACE + ALTGR_MASK // 91 [ +#define ASCII_5C KEY_TILDE + ALTGR_MASK // 92 +#define ASCII_5D KEY_RIGHT_BRACE + ALTGR_MASK // 93 ] +#define ASCII_5E CIRCUMFLEX_BITS + KEY_SPACE // 94 ^ +#define ASCII_5F KEY_MINUS + SHIFT_MASK // 95 _ +#define ASCII_60 GRAVE_ACCENT_BITS + KEY_SPACE // 96 ` +#define ASCII_61 KEY_A // 97 a +#define ASCII_62 KEY_B // 98 b +#define ASCII_63 KEY_C // 99 c +#define ASCII_64 KEY_D // 100 d +#define ASCII_65 KEY_E // 101 e +#define ASCII_66 KEY_F // 102 f +#define ASCII_67 KEY_G // 103 g +#define ASCII_68 KEY_H // 104 h +#define ASCII_69 KEY_I // 105 i +#define ASCII_6A KEY_J // 106 j +#define ASCII_6B KEY_K // 107 k +#define ASCII_6C KEY_L // 108 l +#define ASCII_6D KEY_M // 109 m +#define ASCII_6E KEY_N // 110 n +#define ASCII_6F KEY_O // 111 o +#define ASCII_70 KEY_P // 112 p +#define ASCII_71 KEY_Q // 113 q +#define ASCII_72 KEY_R // 114 r +#define ASCII_73 KEY_S // 115 s +#define ASCII_74 KEY_T // 116 t +#define ASCII_75 KEY_U // 117 u +#define ASCII_76 KEY_V // 118 v +#define ASCII_77 KEY_W // 119 w +#define ASCII_78 KEY_X // 120 x +#define ASCII_79 KEY_Y // 121 y +#define ASCII_7A KEY_Z // 122 z +#define ASCII_7B KEY_QUOTE + ALTGR_MASK // 123 { +#define ASCII_7C KEY_TILDE + SHIFT_MASK // 124 | +#define ASCII_7D KEY_BACKSLASH + ALTGR_MASK // 125 } +#define ASCII_7E KEY_SEMICOLON + ALTGR_MASK // 126 ~ +#define ASCII_7F KEY_BACKSPACE // 127 +#define ISO_8859_1_A0 KEY_SPACE // 160 Nonbreakng Space +#define ISO_8859_1_A1 0 // 161 ¡ Inverted Exclamation +#define ISO_8859_1_A2 KEY_4 + ALTGR_MASK // 162 ¢ Cent SIGN +#define ISO_8859_1_A3 KEY_3 + ALTGR_MASK // 163 £ Pound Sign +#define ISO_8859_1_A4 KEY_5 + ALTGR_MASK // 164 ¤ Currency or Euro Sign +#define ISO_8859_1_A5 0 // 165 ¥ YEN SIGN +#define ISO_8859_1_A6 KEY_7 + ALTGR_MASK // 166 ¦ BROKEN BAR +#define ISO_8859_1_A7 KEY_O + ALTGR_MASK // 167 § SECTION SIGN +#define ISO_8859_1_A8 0 // 168 ¨ DIAERESIS +#define ISO_8859_1_A9 0 // 169 © COPYRIGHT SIGN +#define ISO_8859_1_AA 0 // 170 ª FEMININE ORDINAL +#define ISO_8859_1_AB KEY_NON_US_100 // 171 « LEFT DOUBLE ANGLE QUOTE +#define ISO_8859_1_AC KEY_6 + ALTGR_MASK // 172 ¬ NOT SIGN +#define ISO_8859_1_AD KEY_PERIOD + ALTGR_MASK // 173 SOFT HYPHEN +#define ISO_8859_1_AE 0 // 174 ® REGISTERED SIGN +#define ISO_8859_1_AF KEY_COMMA + ALTGR_MASK // 175 ¯ MACRON +#define ISO_8859_1_B0 KEY_NON_US_100 + ALTGR_MASK // 176 ° DEGREE SIGN +#define ISO_8859_1_B1 KEY_1 + ALTGR_MASK // 177 ± PLUS-MINUS SIGN +#define ISO_8859_1_B2 KEY_8 + ALTGR_MASK // 178 ² SUPERSCRIPT TWO +#define ISO_8859_1_B3 KEY_9 + ALTGR_MASK // 179 ³ SUPERSCRIPT THREE +#define ISO_8859_1_B4 0 // 180 ´ ACUTE ACCENT +#define ISO_8859_1_B5 KEY_M + ALTGR_MASK // 181 µ MICRO SIGN +#define ISO_8859_1_B6 KEY_P + ALTGR_MASK // 182 ¶ PILCROW SIGN +#define ISO_8859_1_B7 0 // 183 · MIDDLE DOT +#define ISO_8859_1_B8 0 // 184 ¸ CEDILLA +#define ISO_8859_1_B9 0 // 185 ¹ SUPERSCRIPT ONE +#define ISO_8859_1_BA 0 // 186 º MASCULINE ORDINAL +#define ISO_8859_1_BB KEY_NON_US_100 + SHIFT_MASK // 187 » RIGHT DOUBLE ANGLE QUOTE +#define ISO_8859_1_BC KEY_0 + ALTGR_MASK // 188 ¼ FRACTION ONE QUARTER +#define ISO_8859_1_BD KEY_MINUS + ALTGR_MASK // 189 ½ FRACTION ONE HALF +#define ISO_8859_1_BE KEY_EQUAL + ALTGR_MASK // 190 ¾ FRACTION THREE QUARTERS +#define ISO_8859_1_BF 0 // 191 ¿ INVERTED QUESTION MARK +#define ISO_8859_1_C0 GRAVE_ACCENT_BITS + KEY_A + SHIFT_MASK // 192 À A GRAVE +#define ISO_8859_1_C1 ACUTE_ACCENT_BITS + KEY_A + SHIFT_MASK // 193 à A ACUTE +#define ISO_8859_1_C2 CIRCUMFLEX_BITS + KEY_A + SHIFT_MASK // 194 Â A CIRCUMFLEX +#define ISO_8859_1_C3 0 // 195 Ã A TILDE +#define ISO_8859_1_C4 DIAERESIS_BITS + KEY_A + SHIFT_MASK // 196 Ä A DIAERESIS +#define ISO_8859_1_C5 0 // 197 Å A RING ABOVE +#define ISO_8859_1_C6 0 // 198 Æ AE +#define ISO_8859_1_C7 CEDILLA_BITS + KEY_C + SHIFT_MASK // 199 Ç C CEDILLA +#define ISO_8859_1_C8 GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK // 200 È E GRAVE +#define ISO_8859_1_C9 KEY_SLASH + SHIFT_MASK // 201 É E ACUTE +#define ISO_8859_1_CA CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK // 202 Ê E CIRCUMFLEX +#define ISO_8859_1_CB DIAERESIS_BITS + KEY_E + SHIFT_MASK // 203 Ë E DIAERESIS +#define ISO_8859_1_CC GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK // 204 Ì I GRAVE +#define ISO_8859_1_CD ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK // 205 à I ACUTE +#define ISO_8859_1_CE CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK // 206 Î I CIRCUMFLEX +#define ISO_8859_1_CF DIAERESIS_BITS + KEY_I + SHIFT_MASK // 207 à I DIAERESIS +#define ISO_8859_1_D0 0 // 208 à ETH +#define ISO_8859_1_D1 0 // 209 Ñ N TILDE +#define ISO_8859_1_D2 GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK // 210 Ò O GRAVE +#define ISO_8859_1_D3 ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK // 211 Ó O ACUTE +#define ISO_8859_1_D4 CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK // 212 Ô O CIRCUMFLEX +#define ISO_8859_1_D5 0 // 213 Õ O TILDE +#define ISO_8859_1_D6 DIAERESIS_BITS + KEY_O + SHIFT_MASK // 214 Ö O DIAERESIS +#define ISO_8859_1_D7 0 // 215 × MULTIPLICATION +#define ISO_8859_1_D8 0 // 216 Ø O STROKE +#define ISO_8859_1_D9 GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK // 217 Ù U GRAVE +#define ISO_8859_1_DA ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK // 218 Ú U ACUTE +#define ISO_8859_1_DB CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK // 219 Û U CIRCUMFLEX +#define ISO_8859_1_DC DIAERESIS_BITS + KEY_U // 220 Ü U DIAERESIS +#define ISO_8859_1_DD ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK // 221 à Y ACUTE +#define ISO_8859_1_DE 0 // 222 Þ THORN +#define ISO_8859_1_DF 0 // 223 ß SHARP S +#define ISO_8859_1_E0 GRAVE_ACCENT_BITS + KEY_A // 224 à a GRAVE +#define ISO_8859_1_E1 ACUTE_ACCENT_BITS + KEY_A // 225 á a ACUTE +#define ISO_8859_1_E2 CIRCUMFLEX_BITS + KEY_A // 226 â a CIRCUMFLEX +#define ISO_8859_1_E3 0 // 227 ã a TILDE +#define ISO_8859_1_E4 DIAERESIS_BITS + KEY_A // 228 ä a DIAERESIS +#define ISO_8859_1_E5 0 // 229 å a RING ABOVE +#define ISO_8859_1_E6 0 // 230 æ ae +#define ISO_8859_1_E7 CEDILLA_BITS + KEY_C // 231 ç c CEDILLA +#define ISO_8859_1_E8 GRAVE_ACCENT_BITS + KEY_E // 232 è e GRAVE +#define ISO_8859_1_E9 KEY_SLASH // 233 é e ACUTE +#define ISO_8859_1_EA CIRCUMFLEX_BITS + KEY_E // 234 ê e CIRCUMFLEX +#define ISO_8859_1_EB DIAERESIS_BITS + KEY_E // 235 ë e DIAERESIS +#define ISO_8859_1_EC GRAVE_ACCENT_BITS + KEY_I // 236 ì i GRAVE +#define ISO_8859_1_ED ACUTE_ACCENT_BITS + KEY_I // 237 à i ACUTE +#define ISO_8859_1_EE CIRCUMFLEX_BITS + KEY_I // 238 î i CIRCUMFLEX +#define ISO_8859_1_EF DIAERESIS_BITS + KEY_I // 239 ï i DIAERESIS +#define ISO_8859_1_F0 0 // 240 ð ETH +#define ISO_8859_1_F1 0 // 241 ñ n TILDE +#define ISO_8859_1_F2 GRAVE_ACCENT_BITS + KEY_O // 242 ò o GRAVE +#define ISO_8859_1_F3 ACUTE_ACCENT_BITS + KEY_O // 243 ó o ACUTE +#define ISO_8859_1_F4 CIRCUMFLEX_BITS + KEY_O // 244 ô o CIRCUMFLEX +#define ISO_8859_1_F5 0 // 245 õ o TILDE +#define ISO_8859_1_F6 DIAERESIS_BITS + KEY_O // 246 ö o DIAERESIS +#define ISO_8859_1_F7 0 // 247 ÷ DIVISION +#define ISO_8859_1_F8 0 // 248 ø o STROKE +#define ISO_8859_1_F9 GRAVE_ACCENT_BITS + KEY_U // 249 ù u GRAVE +#define ISO_8859_1_FA ACUTE_ACCENT_BITS + KEY_U // 250 ú u ACUTE +#define ISO_8859_1_FB CIRCUMFLEX_BITS + KEY_U // 251 û u CIRCUMFLEX +#define ISO_8859_1_FC DIAERESIS_BITS + KEY_U // 252 ü u DIAERESIS +#define ISO_8859_1_FD ACUTE_ACCENT_BITS + KEY_Y // 253 ý y ACUTE +#define ISO_8859_1_FE 0 // 254 þ THORN +#define ISO_8859_1_FF DIAERESIS_BITS + KEY_Y // 255 ÿ y DIAERESIS + +#endif // LAYOUT_CANADIAN_FRENCH + + + +#ifdef LAYOUT_CANADIAN_MULTILINGUAL + +#define SHIFT_MASK 0x0040 +#define ALTGR_MASK 0x0080 +#define RCTRL_MASK 0x0800 +#define DEADKEYS_MASK 0x0700 +#define CIRCUMFLEX_BITS 0x0100 +#define DIAERESIS_BITS 0x0200 +#define ACUTE_ACCENT_BITS 0x0300 +#define CEDILLA_BITS 0x0400 +#define GRAVE_ACCENT_BITS 0x0500 +#define TILDE_BITS 0x0600 +#define RING_ABOVE_BITS 0x0700 +#define KEYCODE_TYPE uint16_t +#define DEADKEY_CIRCUMFLEX KEY_LEFT_BRACE +#define DEADKEY_DIAERESIS KEY_LEFT_BRACE + SHIFT_MASK +#define DEADKEY_ACUTE_ACCENT KEY_SEMICOLON + RCTRL_MASK +#define DEADKEY_CEDILLA KEY_EQUAL + RCTRL_MASK +#define DEADKEY_GRAVE_ACCENT KEY_LEFT_BRACE + ALTGR_MASK +#define DEADKEY_TILDE KEY_RIGHT_BRACE + ALTGR_MASK +#define DEADKEY_RING_ABOVE KEY_LEFT_BRACE + SHIFT_MASK + RCTRL_MASK +#define KEY_NON_US_100 63 + +#define ASCII_20 KEY_SPACE // 32 +#define ASCII_21 KEY_1 + SHIFT_MASK // 33 ! +#define ASCII_22 KEY_PERIOD + SHIFT_MASK // 34 " +#define ASCII_23 KEY_3 + SHIFT_MASK // 35 # +#define ASCII_24 KEY_4 + SHIFT_MASK // 36 $ +#define ASCII_25 KEY_5 + SHIFT_MASK // 37 % +#define ASCII_26 KEY_7 + SHIFT_MASK // 38 & +#define ASCII_27 KEY_COMMA + SHIFT_MASK // 39 ' +#define ASCII_28 KEY_9 + SHIFT_MASK // 40 ( +#define ASCII_29 KEY_0 + SHIFT_MASK // 41 ) +#define ASCII_2A KEY_8 + SHIFT_MASK // 42 * +#define ASCII_2B KEY_EQUAL + SHIFT_MASK // 43 + +#define ASCII_2C KEY_COMMA // 44 , +#define ASCII_2D KEY_MINUS // 45 - +#define ASCII_2E KEY_PERIOD // 46 . +#define ASCII_2F KEY_TILDE // 47 / +#define ASCII_30 KEY_0 // 48 0 +#define ASCII_31 KEY_1 // 49 1 +#define ASCII_32 KEY_2 // 50 2 +#define ASCII_33 KEY_3 // 51 3 +#define ASCII_34 KEY_4 // 52 4 +#define ASCII_35 KEY_5 // 53 5 +#define ASCII_36 KEY_6 // 54 6 +#define ASCII_37 KEY_7 // 55 7 +#define ASCII_38 KEY_8 // 55 8 +#define ASCII_39 KEY_9 // 57 9 +#define ASCII_3A KEY_SEMICOLON + SHIFT_MASK // 58 : +#define ASCII_3B KEY_SEMICOLON // 59 ; +#define ASCII_3C KEY_COMMA + ALTGR_MASK // 60 < +#define ASCII_3D KEY_EQUAL // 61 = +#define ASCII_3E KEY_PERIOD + ALTGR_MASK // 62 > +#define ASCII_3F KEY_6 + SHIFT_MASK // 63 ? +#define ASCII_40 KEY_2 + SHIFT_MASK // 64 @ +#define ASCII_41 KEY_A + SHIFT_MASK // 65 A +#define ASCII_42 KEY_B + SHIFT_MASK // 66 B +#define ASCII_43 KEY_C + SHIFT_MASK // 67 C +#define ASCII_44 KEY_D + SHIFT_MASK // 68 D +#define ASCII_45 KEY_E + SHIFT_MASK // 69 E +#define ASCII_46 KEY_F + SHIFT_MASK // 70 F +#define ASCII_47 KEY_G + SHIFT_MASK // 71 G +#define ASCII_48 KEY_H + SHIFT_MASK // 72 H +#define ASCII_49 KEY_I + SHIFT_MASK // 73 I +#define ASCII_4A KEY_J + SHIFT_MASK // 74 J +#define ASCII_4B KEY_K + SHIFT_MASK // 75 K +#define ASCII_4C KEY_L + SHIFT_MASK // 76 L +#define ASCII_4D KEY_M + SHIFT_MASK // 77 M +#define ASCII_4E KEY_N + SHIFT_MASK // 78 N +#define ASCII_4F KEY_O + SHIFT_MASK // 79 O +#define ASCII_50 KEY_P + SHIFT_MASK // 80 P +#define ASCII_51 KEY_Q + SHIFT_MASK // 81 Q +#define ASCII_52 KEY_R + SHIFT_MASK // 82 R +#define ASCII_53 KEY_S + SHIFT_MASK // 83 S +#define ASCII_54 KEY_T + SHIFT_MASK // 84 T +#define ASCII_55 KEY_U + SHIFT_MASK // 85 U +#define ASCII_56 KEY_V + SHIFT_MASK // 86 V +#define ASCII_57 KEY_W + SHIFT_MASK // 87 W +#define ASCII_58 KEY_X + SHIFT_MASK // 88 X +#define ASCII_59 KEY_Y + SHIFT_MASK // 89 Y +#define ASCII_5A KEY_Z + SHIFT_MASK // 90 Z +#define ASCII_5B KEY_9 + ALTGR_MASK // 91 [ +#define ASCII_5C KEY_TILDE + SHIFT_MASK // 92 +#define ASCII_5D KEY_0 + ALTGR_MASK // 93 ] +#define ASCII_5E CIRCUMFLEX_BITS + KEY_SPACE // 94 ^ +#define ASCII_5F KEY_MINUS + SHIFT_MASK // 95 _ +#define ASCII_60 GRAVE_ACCENT_BITS + KEY_SPACE // 96 ` +#define ASCII_61 KEY_A // 97 a +#define ASCII_62 KEY_B // 98 b +#define ASCII_63 KEY_C // 99 c +#define ASCII_64 KEY_D // 100 d +#define ASCII_65 KEY_E // 101 e +#define ASCII_66 KEY_F // 102 f +#define ASCII_67 KEY_G // 103 g +#define ASCII_68 KEY_H // 104 h +#define ASCII_69 KEY_I // 105 i +#define ASCII_6A KEY_J // 106 j +#define ASCII_6B KEY_K // 107 k +#define ASCII_6C KEY_L // 108 l +#define ASCII_6D KEY_M // 109 m +#define ASCII_6E KEY_N // 110 n +#define ASCII_6F KEY_O // 111 o +#define ASCII_70 KEY_P // 112 p +#define ASCII_71 KEY_Q // 113 q +#define ASCII_72 KEY_R // 114 r +#define ASCII_73 KEY_S // 115 s +#define ASCII_74 KEY_T // 116 t +#define ASCII_75 KEY_U // 117 u +#define ASCII_76 KEY_V // 118 v +#define ASCII_77 KEY_W // 119 w +#define ASCII_78 KEY_X // 120 x +#define ASCII_79 KEY_Y // 121 y +#define ASCII_7A KEY_Z // 122 z +#define ASCII_7B KEY_7 + ALTGR_MASK // 123 { +#define ASCII_7C KEY_TILDE + ALTGR_MASK // 124 | +#define ASCII_7D KEY_8 + ALTGR_MASK // 125 } +#define ASCII_7E KEY_RIGHT_BRACE + RCTRL_MASK // 126 ~ +#define ASCII_7F KEY_BACKSPACE // 127 +#define ISO_8859_1_A0 KEY_SPACE + ALTGR_MASK // 160 Nonbreakng Space +#define ISO_8859_1_A1 KEY_1 + SHIFT_MASK + RCTRL_MASK // 161 ¡ Inverted Exclamation +#define ISO_8859_1_A2 KEY_C + RCTRL_MASK // 162 ¢ Cent SIGN +#define ISO_8859_1_A3 KEY_3 + SHIFT_MASK + RCTRL_MASK // 163 £ Pound Sign +#define ISO_8859_1_A4 KEY_4 + SHIFT_MASK + RCTRL_MASK // 164 ¤ Currency or Euro Sign +#define ISO_8859_1_A5 KEY_Y + SHIFT_MASK + RCTRL_MASK // 165 ¥ YEN SIGN +#define ISO_8859_1_A6 KEY_NON_US_100 + SHIFT_MASK + RCTRL_MASK// 166 ¦ BROKEN BAR +#define ISO_8859_1_A7 KEY_S + SHIFT_MASK + RCTRL_MASK // 167 § SECTION SIGN +#define ISO_8859_1_A8 DIAERESIS_BITS + KEY_SPACE // 168 ¨ DIAERESIS +#define ISO_8859_1_A9 KEY_C + SHIFT_MASK + RCTRL_MASK // 169 © COPYRIGHT SIGN +#define ISO_8859_1_AA KEY_F + SHIFT_MASK + RCTRL_MASK // 170 ª FEMININE ORDINAL +#define ISO_8859_1_AB KEY_Z + ALTGR_MASK // 171 « LEFT DOUBLE ANGLE QUOTE +#define ISO_8859_1_AC KEY_EQUAL + ALTGR_MASK // 172 ¬ NOT SIGN +#define ISO_8859_1_AD KEY_TILDE + SHIFT_MASK + RCTRL_MASK // 173 SOFT HYPHEN +#define ISO_8859_1_AE KEY_R + SHIFT_MASK + RCTRL_MASK // 174 ® REGISTERED SIGN +#define ISO_8859_1_AF 0 // special dead key - no implemented // 175 ¯ MACRON +#define ISO_8859_1_B0 KEY_SEMICOLON + ALTGR_MASK // 176 ° DEGREE SIGN +#define ISO_8859_1_B1 KEY_9 + SHIFT_MASK + RCTRL_MASK // 177 ± PLUS-MINUS SIGN +#define ISO_8859_1_B2 KEY_2 + RCTRL_MASK // 178 ² SUPERSCRIPT TWO +#define ISO_8859_1_B3 KEY_3 + RCTRL_MASK // 179 ³ SUPERSCRIPT THREE +#define ISO_8859_1_B4 ACUTE_ACCENT_BITS + KEY_SPACE // 180 ´ ACUTE ACCENT +#define ISO_8859_1_B5 KEY_M + RCTRL_MASK // 181 µ MICRO SIGN +#define ISO_8859_1_B6 KEY_R + RCTRL_MASK // 182 ¶ PILCROW SIGN +#define ISO_8859_1_B7 0 // 183 · MIDDLE DOT +#define ISO_8859_1_B8 CEDILLA_BITS + KEY_SPACE // 184 ¸ CEDILLA +#define ISO_8859_1_B9 KEY_1 + RCTRL_MASK // 185 ¹ SUPERSCRIPT ONE +#define ISO_8859_1_BA KEY_M + SHIFT_MASK + RCTRL_MASK // 186 º MASCULINE ORDINAL +#define ISO_8859_1_BB KEY_X + ALTGR_MASK // 187 » RIGHT DOUBLE ANGLE QUOTE +#define ISO_8859_1_BC KEY_4 + RCTRL_MASK // 188 ¼ FRACTION ONE QUARTER +#define ISO_8859_1_BD KEY_5 + RCTRL_MASK // 189 ½ FRACTION ONE HALF +#define ISO_8859_1_BE KEY_6 + RCTRL_MASK // 190 ¾ FRACTION THREE QUARTERS +#define ISO_8859_1_BF KEY_MINUS + SHIFT_MASK + RCTRL_MASK // 191 ¿ INVERTED QUESTION MARK +#define ISO_8859_1_C0 KEY_BACKSLASH + SHIFT_MASK // 192 À A GRAVE +#define ISO_8859_1_C1 ACUTE_ACCENT_BITS + KEY_A + SHIFT_MASK // 193 à A ACUTE +#define ISO_8859_1_C2 CIRCUMFLEX_BITS + KEY_A + SHIFT_MASK // 194 Â A CIRCUMFLEX +#define ISO_8859_1_C3 TILDE_BITS + KEY_A + SHIFT_MASK // 195 Ã A TILDE +#define ISO_8859_1_C4 DIAERESIS_BITS + KEY_A + SHIFT_MASK // 196 Ä A DIAERESIS +#define ISO_8859_1_C5 RING_ABOVE_BITS + KEY_A + SHIFT_MASK // 197 Å A RING ABOVE +#define ISO_8859_1_C6 KEY_A + SHIFT_MASK + RCTRL_MASK // 198 Æ AE +#define ISO_8859_1_C7 KEY_RIGHT_BRACE + SHIFT_MASK // 199 Ç C CEDILLA +#define ISO_8859_1_C8 KEY_QUOTE + SHIFT_MASK // 200 È E GRAVE +#define ISO_8859_1_C9 KEY_SLASH + SHIFT_MASK // 201 É E ACUTE +#define ISO_8859_1_CA CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK // 202 Ê E CIRCUMFLEX +#define ISO_8859_1_CB DIAERESIS_BITS + KEY_E + SHIFT_MASK // 203 Ë E DIAERESIS +#define ISO_8859_1_CC GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK // 204 Ì I GRAVE +#define ISO_8859_1_CD ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK // 205 à I ACUTE +#define ISO_8859_1_CE CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK // 206 Î I CIRCUMFLEX +#define ISO_8859_1_CF DIAERESIS_BITS + KEY_I + SHIFT_MASK // 207 à I DIAERESIS +#define ISO_8859_1_D0 KEY_D + SHIFT_MASK + RCTRL_MASK // 208 à ETH +#define ISO_8859_1_D1 TILDE_BITS + KEY_N + SHIFT_MASK // 209 Ñ N TILDE +#define ISO_8859_1_D2 GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK // 210 Ò O GRAVE +#define ISO_8859_1_D3 ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK // 211 Ó O ACUTE +#define ISO_8859_1_D4 CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK // 212 Ô O CIRCUMFLEX +#define ISO_8859_1_D5 TILDE_BITS + KEY_O + SHIFT_MASK // 213 Õ O TILDE +#define ISO_8859_1_D6 DIAERESIS_BITS + KEY_O + SHIFT_MASK // 214 Ö O DIAERESIS +#define ISO_8859_1_D7 KEY_COMMA + SHIFT_MASK + RCTRL_MASK // 215 × MULTIPLICATION +#define ISO_8859_1_D8 KEY_O + SHIFT_MASK + RCTRL_MASK // 216 Ø O STROKE +#define ISO_8859_1_D9 KEY_NON_US_100 + SHIFT_MASK // 217 Ù U GRAVE +#define ISO_8859_1_DA ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK // 218 Ú U ACUTE +#define ISO_8859_1_DB CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK // 219 Û U CIRCUMFLEX +#define ISO_8859_1_DC DIAERESIS_BITS + KEY_U // 220 Ü U DIAERESIS +#define ISO_8859_1_DD ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK // 221 à Y ACUTE +#define ISO_8859_1_DE KEY_P + RCTRL_MASK + SHIFT_MASK // 222 Þ THORN +#define ISO_8859_1_DF KEY_S + RCTRL_MASK // 223 ß SHARP S +#define ISO_8859_1_E0 KEY_BACKSLASH // 224 à a GRAVE +#define ISO_8859_1_E1 ACUTE_ACCENT_BITS + KEY_A // 225 á a ACUTE +#define ISO_8859_1_E2 CIRCUMFLEX_BITS + KEY_A // 226 â a CIRCUMFLEX +#define ISO_8859_1_E3 TILDE_BITS + KEY_A // 227 ã a TILDE +#define ISO_8859_1_E4 DIAERESIS_BITS + KEY_A // 228 ä a DIAERESIS +#define ISO_8859_1_E5 RING_ABOVE_BITS + KEY_A // 229 å a RING ABOVE +#define ISO_8859_1_E6 KEY_A + RCTRL_MASK // 230 æ ae +#define ISO_8859_1_E7 KEY_RIGHT_BRACE // 231 ç c CEDILLA +#define ISO_8859_1_E8 KEY_QUOTE // 232 è e GRAVE +#define ISO_8859_1_E9 KEY_SLASH // 233 é e ACUTE +#define ISO_8859_1_EA CIRCUMFLEX_BITS + KEY_E // 234 ê e CIRCUMFLEX +#define ISO_8859_1_EB DIAERESIS_BITS + KEY_E // 235 ë e DIAERESIS +#define ISO_8859_1_EC GRAVE_ACCENT_BITS + KEY_I // 236 ì i GRAVE +#define ISO_8859_1_ED ACUTE_ACCENT_BITS + KEY_I // 237 à i ACUTE +#define ISO_8859_1_EE CIRCUMFLEX_BITS + KEY_I // 238 î i CIRCUMFLEX +#define ISO_8859_1_EF DIAERESIS_BITS + KEY_I // 239 ï i DIAERESIS +#define ISO_8859_1_F0 KEY_D + RCTRL_MASK // 240 ð ETH +#define ISO_8859_1_F1 TILDE_BITS + KEY_N // 241 ñ n TILDE +#define ISO_8859_1_F2 GRAVE_ACCENT_BITS + KEY_O // 242 ò o GRAVE +#define ISO_8859_1_F3 ACUTE_ACCENT_BITS + KEY_O // 243 ó o ACUTE +#define ISO_8859_1_F4 CIRCUMFLEX_BITS + KEY_O // 244 ô o CIRCUMFLEX +#define ISO_8859_1_F5 TILDE_BITS + KEY_O // 245 õ o TILDE +#define ISO_8859_1_F6 DIAERESIS_BITS + KEY_O // 246 ö o DIAERESIS +#define ISO_8859_1_F7 KEY_PERIOD + SHIFT_MASK + RCTRL_MASK // 247 ÷ DIVISION +#define ISO_8859_1_F8 KEY_O + RCTRL_MASK // 248 ø o STROKE +#define ISO_8859_1_F9 KEY_NON_US_100 // 249 ù u GRAVE +#define ISO_8859_1_FA ACUTE_ACCENT_BITS + KEY_U // 250 ú u ACUTE +#define ISO_8859_1_FB CIRCUMFLEX_BITS + KEY_U // 251 û u CIRCUMFLEX +#define ISO_8859_1_FC DIAERESIS_BITS + KEY_U // 252 ü u DIAERESIS +#define ISO_8859_1_FD ACUTE_ACCENT_BITS + KEY_Y // 253 ý y ACUTE +#define ISO_8859_1_FE KEY_P + RCTRL_MASK // 254 þ THORN +#define ISO_8859_1_FF DIAERESIS_BITS + KEY_Y // 255 ÿ y DIAERESIS + +#endif // LAYOUT_CANADIAN_MULTILINGUAL + + + + + + +#ifdef LAYOUT_UNITED_KINGDOM + +#define SHIFT_MASK 0x0040 +#define ALTGR_MASK 0x0080 +#define KEYCODE_TYPE uint8_t +#define KEY_NON_US_100 63 + +#define ASCII_20 KEY_SPACE // 32 +#define ASCII_21 KEY_1 + SHIFT_MASK // 33 ! +#define ASCII_22 KEY_2 + SHIFT_MASK // 34 " +#define ASCII_23 KEY_BACKSPACE // 35 # +#define ASCII_24 KEY_4 + SHIFT_MASK // 36 $ +#define ASCII_25 KEY_5 + SHIFT_MASK // 37 % +#define ASCII_26 KEY_7 + SHIFT_MASK // 38 & +#define ASCII_27 KEY_QUOTE // 39 ' +#define ASCII_28 KEY_9 + SHIFT_MASK // 40 ( +#define ASCII_29 KEY_0 + SHIFT_MASK // 41 ) +#define ASCII_2A KEY_8 + SHIFT_MASK // 42 * +#define ASCII_2B KEY_EQUAL + SHIFT_MASK // 43 + +#define ASCII_2C KEY_COMMA // 44 , +#define ASCII_2D KEY_MINUS // 45 - +#define ASCII_2E KEY_PERIOD // 46 . +#define ASCII_2F KEY_SLASH // 47 / +#define ASCII_30 KEY_0 // 48 0 +#define ASCII_31 KEY_1 // 49 1 +#define ASCII_32 KEY_2 // 50 2 +#define ASCII_33 KEY_3 // 51 3 +#define ASCII_34 KEY_4 // 52 4 +#define ASCII_35 KEY_5 // 53 5 +#define ASCII_36 KEY_6 // 54 6 +#define ASCII_37 KEY_7 // 55 7 +#define ASCII_38 KEY_8 // 55 8 +#define ASCII_39 KEY_9 // 57 9 +#define ASCII_3A KEY_SEMICOLON + SHIFT_MASK // 58 : +#define ASCII_3B KEY_SEMICOLON // 59 ; +#define ASCII_3C KEY_COMMA + SHIFT_MASK // 60 < +#define ASCII_3D KEY_EQUAL // 61 = +#define ASCII_3E KEY_PERIOD + SHIFT_MASK // 62 > +#define ASCII_3F KEY_SLASH + SHIFT_MASK // 63 ? +#define ASCII_40 KEY_QUOTE + SHIFT_MASK // 64 @ +#define ASCII_41 KEY_A + SHIFT_MASK // 65 A +#define ASCII_42 KEY_B + SHIFT_MASK // 66 B +#define ASCII_43 KEY_C + SHIFT_MASK // 67 C +#define ASCII_44 KEY_D + SHIFT_MASK // 68 D +#define ASCII_45 KEY_E + SHIFT_MASK // 69 E +#define ASCII_46 KEY_F + SHIFT_MASK // 70 F +#define ASCII_47 KEY_G + SHIFT_MASK // 71 G +#define ASCII_48 KEY_H + SHIFT_MASK // 72 H +#define ASCII_49 KEY_I + SHIFT_MASK // 73 I +#define ASCII_4A KEY_J + SHIFT_MASK // 74 J +#define ASCII_4B KEY_K + SHIFT_MASK // 75 K +#define ASCII_4C KEY_L + SHIFT_MASK // 76 L +#define ASCII_4D KEY_M + SHIFT_MASK // 77 M +#define ASCII_4E KEY_N + SHIFT_MASK // 78 N +#define ASCII_4F KEY_O + SHIFT_MASK // 79 O +#define ASCII_50 KEY_P + SHIFT_MASK // 80 P +#define ASCII_51 KEY_Q + SHIFT_MASK // 81 Q +#define ASCII_52 KEY_R + SHIFT_MASK // 82 R +#define ASCII_53 KEY_S + SHIFT_MASK // 83 S +#define ASCII_54 KEY_T + SHIFT_MASK // 84 T +#define ASCII_55 KEY_U + SHIFT_MASK // 85 U +#define ASCII_56 KEY_V + SHIFT_MASK // 86 V +#define ASCII_57 KEY_W + SHIFT_MASK // 87 W +#define ASCII_58 KEY_X + SHIFT_MASK // 88 X +#define ASCII_59 KEY_Y + SHIFT_MASK // 89 Y +#define ASCII_5A KEY_Z + SHIFT_MASK // 90 Z +#define ASCII_5B KEY_LEFT_BRACE // 91 [ +#define ASCII_5C KEY_NON_US_100 // 92 +#define ASCII_5D KEY_RIGHT_BRACE // 93 ] +#define ASCII_5E KEY_6 + SHIFT_MASK // 94 ^ +#define ASCII_5F KEY_MINUS + SHIFT_MASK // 95 _ +#define ASCII_60 KEY_TILDE // 96 ` +#define ASCII_61 KEY_A // 97 a +#define ASCII_62 KEY_B // 98 b +#define ASCII_63 KEY_C // 99 c +#define ASCII_64 KEY_D // 100 d +#define ASCII_65 KEY_E // 101 e +#define ASCII_66 KEY_F // 102 f +#define ASCII_67 KEY_G // 103 g +#define ASCII_68 KEY_H // 104 h +#define ASCII_69 KEY_I // 105 i +#define ASCII_6A KEY_J // 106 j +#define ASCII_6B KEY_K // 107 k +#define ASCII_6C KEY_L // 108 l +#define ASCII_6D KEY_M // 109 m +#define ASCII_6E KEY_N // 110 n +#define ASCII_6F KEY_O // 111 o +#define ASCII_70 KEY_P // 112 p +#define ASCII_71 KEY_Q // 113 q +#define ASCII_72 KEY_R // 114 r +#define ASCII_73 KEY_S // 115 s +#define ASCII_74 KEY_T // 116 t +#define ASCII_75 KEY_U // 117 u +#define ASCII_76 KEY_V // 118 v +#define ASCII_77 KEY_W // 119 w +#define ASCII_78 KEY_X // 120 x +#define ASCII_79 KEY_Y // 121 y +#define ASCII_7A KEY_Z // 122 z +#define ASCII_7B KEY_LEFT_BRACE + SHIFT_MASK // 123 { +#define ASCII_7C KEY_NON_US_100 + SHIFT_MASK // 124 | +#define ASCII_7D KEY_RIGHT_BRACE + SHIFT_MASK // 125 } +#define ASCII_7E KEY_BACKSLASH + SHIFT_MASK // 126 ~ +#define ASCII_7F KEY_BACKSPACE // 127 + +#define ISO_8859_1_A0 KEY_SPACE // 160 Nonbreakng Space +#define ISO_8859_1_A1 0 // 161 ¡ Inverted Exclamation +#define ISO_8859_1_A2 0 // 162 ¢ Cent SIGN +#define ISO_8859_1_A3 KEY_3 + SHIFT_MASK // 163 £ Pound Sign +#define ISO_8859_1_A4 0 // 164 ¤ Currency or Euro Sign +#define ISO_8859_1_A5 0 // 165 ¥ YEN SIGN +#define ISO_8859_1_A6 KEY_TILDE + ALTGR_MASK // 166 ¦ BROKEN BAR +#define ISO_8859_1_A7 0 // 167 § SECTION SIGN +#define ISO_8859_1_A8 0 // 168 ¨ DIAERESIS +#define ISO_8859_1_A9 0 // 169 © COPYRIGHT SIGN +#define ISO_8859_1_AA 0 // 170 ª FEMININE ORDINAL +#define ISO_8859_1_AB 0 // 171 « LEFT DOUBLE ANGLE QUOTE +#define ISO_8859_1_AC KEY_TILDE + SHIFT_MASK // 172 ¬ NOT SIGN +#define ISO_8859_1_AD 0 // 173 SOFT HYPHEN +#define ISO_8859_1_AE 0 // 174 ® REGISTERED SIGN +#define ISO_8859_1_AF 0 // 175 ¯ MACRON +#define ISO_8859_1_B0 0 // 176 ° DEGREE SIGN +#define ISO_8859_1_B1 0 // 177 ± PLUS-MINUS SIGN +#define ISO_8859_1_B2 0 // 178 ² SUPERSCRIPT TWO +#define ISO_8859_1_B3 0 // 179 ³ SUPERSCRIPT THREE +#define ISO_8859_1_B4 0 // 180 ´ ACUTE ACCENT +#define ISO_8859_1_B5 0 // 181 µ MICRO SIGN +#define ISO_8859_1_B6 0 // 182 ¶ PILCROW SIGN +#define ISO_8859_1_B7 0 // 183 · MIDDLE DOT +#define ISO_8859_1_B8 0 // 184 ¸ CEDILLA +#define ISO_8859_1_B9 0 // 185 ¹ SUPERSCRIPT ONE +#define ISO_8859_1_BA 0 // 186 º MASCULINE ORDINAL +#define ISO_8859_1_BB 0 // 187 » RIGHT DOUBLE ANGLE QUOTE +#define ISO_8859_1_BC 0 // 188 ¼ FRACTION ONE QUARTER +#define ISO_8859_1_BD 0 // 189 ½ FRACTION ONE HALF +#define ISO_8859_1_BE 0 // 190 ¾ FRACTION THREE QUARTERS +#define ISO_8859_1_BF 0 // 191 ¿ INVERTED QUESTION MARK +#define ISO_8859_1_C0 0 // 192 À A GRAVE +#define ISO_8859_1_C1 KEY_A + ALTGR_MASK + SHIFT_MASK // 193 à A ACUTE +#define ISO_8859_1_C2 0 // 194 Â A CIRCUMFLEX +#define ISO_8859_1_C3 0 // 195 Ã A TILDE +#define ISO_8859_1_C4 0 // 196 Ä A DIAERESIS +#define ISO_8859_1_C5 0 // 197 Å A RING ABOVE +#define ISO_8859_1_C6 0 // 198 Æ AE +#define ISO_8859_1_C7 0 // 199 Ç C CEDILLA +#define ISO_8859_1_C8 0 // 200 È E GRAVE +#define ISO_8859_1_C9 KEY_E + ALTGR_MASK + SHIFT_MASK // 201 É E ACUTE +#define ISO_8859_1_CA 0 // 202 Ê E CIRCUMFLEX +#define ISO_8859_1_CB 0 // 203 Ë E DIAERESIS +#define ISO_8859_1_CC 0 // 204 Ì I GRAVE +#define ISO_8859_1_CD KEY_I + ALTGR_MASK + SHIFT_MASK // 205 à I ACUTE +#define ISO_8859_1_CE 0 // 206 Î I CIRCUMFLEX +#define ISO_8859_1_CF 0 // 207 à I DIAERESIS +#define ISO_8859_1_D0 0 // 208 à ETH +#define ISO_8859_1_D1 0 // 209 Ñ N TILDE +#define ISO_8859_1_D2 0 // 210 Ò O GRAVE +#define ISO_8859_1_D3 KEY_O + ALTGR_MASK + SHIFT_MASK // 211 Ó O ACUTE +#define ISO_8859_1_D4 0 // 212 Ô O CIRCUMFLEX +#define ISO_8859_1_D5 0 // 213 Õ O TILDE +#define ISO_8859_1_D6 0 // 214 Ö O DIAERESIS +#define ISO_8859_1_D7 0 // 215 × MULTIPLICATION +#define ISO_8859_1_D8 0 // 216 Ø O STROKE +#define ISO_8859_1_D9 0 // 217 Ù U GRAVE +#define ISO_8859_1_DA KEY_U + ALTGR_MASK + SHIFT_MASK // 218 Ú U ACUTE +#define ISO_8859_1_DB 0 // 219 Û U CIRCUMFLEX +#define ISO_8859_1_DC 0 // 220 Ü U DIAERESIS +#define ISO_8859_1_DD 0 // 221 à Y ACUTE +#define ISO_8859_1_DE 0 // 222 Þ THORN +#define ISO_8859_1_DF 0 // 223 ß SHARP S +#define ISO_8859_1_E0 0 // 224 à a GRAVE +#define ISO_8859_1_E1 KEY_A + ALTGR_MASK // 225 á a ACUTE +#define ISO_8859_1_E2 0 // 226 â a CIRCUMFLEX +#define ISO_8859_1_E3 0 // 227 ã a TILDE +#define ISO_8859_1_E4 0 // 228 ä a DIAERESIS +#define ISO_8859_1_E5 0 // 229 å a RING ABOVE +#define ISO_8859_1_E6 0 // 230 æ ae +#define ISO_8859_1_E7 0 // 231 ç c CEDILLA +#define ISO_8859_1_E8 0 // 232 è e GRAVE +#define ISO_8859_1_E9 KEY_E + ALTGR_MASK // 233 é e ACUTE +#define ISO_8859_1_EA 0 // 234 ê e CIRCUMFLEX +#define ISO_8859_1_EB 0 // 235 ë e DIAERESIS +#define ISO_8859_1_EC 0 // 236 ì i GRAVE +#define ISO_8859_1_ED KEY_I + ALTGR_MASK // 237 à i ACUTE +#define ISO_8859_1_EE 0 // 238 î i CIRCUMFLEX +#define ISO_8859_1_EF 0 // 239 ï i DIAERESIS +#define ISO_8859_1_F0 0 // 240 ð ETH +#define ISO_8859_1_F1 0 // 241 ñ n TILDE +#define ISO_8859_1_F2 0 // 242 ò o GRAVE +#define ISO_8859_1_F3 KEY_O + ALTGR_MASK // 243 ó o ACUTE +#define ISO_8859_1_F4 0 // 244 ô o CIRCUMFLEX +#define ISO_8859_1_F5 0 // 245 õ o TILDE +#define ISO_8859_1_F6 0 // 246 ö o DIAERESIS +#define ISO_8859_1_F7 0 // 247 ÷ DIVISION +#define ISO_8859_1_F8 0 // 248 ø o STROKE +#define ISO_8859_1_F9 0 // 249 ù u GRAVE +#define ISO_8859_1_FA KEY_U + ALTGR_MASK // 250 ú u ACUTE +#define ISO_8859_1_FB 0 // 251 û u CIRCUMFLEX +#define ISO_8859_1_FC 0 // 252 ü u DIAERESIS +#define ISO_8859_1_FD 0 // 253 ý y ACUTE +#define ISO_8859_1_FE 0 // 254 þ THORN +#define ISO_8859_1_FF 0 // 255 ÿ y DIAERESIS +#define UNICODE_20AC KEY_4 + ALTGR_MASK // € Euro Sign +// not yet implemented +#define UNICODE_EXTRA00 0x20AC +#define KEYCODE_EXTRA00 KEY_4 + ALTGR_MASK // 20AC € Euro Sign + +#endif // LAYOUT_UNITED_KINGDOM + + + +#ifdef LAYOUT_FINNISH + +#define SHIFT_MASK 0x0040 +#define ALTGR_MASK 0x0080 +#define DEADKEYS_MASK 0x0700 +#define CIRCUMFLEX_BITS 0x0100 +#define ACUTE_ACCENT_BITS 0x0200 +#define GRAVE_ACCENT_BITS 0x0300 +#define TILDE_BITS 0x0400 +#define DIAERESIS_BITS 0x0500 +#define KEYCODE_TYPE uint16_t +#define DEADKEY_CIRCUMFLEX KEY_RIGHT_BRACE + SHIFT_MASK +#define DEADKEY_ACUTE_ACCENT KEY_EQUAL +#define DEADKEY_GRAVE_ACCENT KEY_EQUAL + SHIFT_MASK +#define DEADKEY_TILDE KEY_RIGHT_BRACE + ALTGR_MASK +#define DEADKEY_DIAERESIS KEY_RIGHT_BRACE +#define KEY_NON_US_100 63 + +#define ASCII_20 KEY_SPACE // 32 +#define ASCII_21 KEY_1 + SHIFT_MASK // 33 ! +#define ASCII_22 KEY_2 + SHIFT_MASK // 34 " +#define ASCII_23 KEY_3 + SHIFT_MASK // 35 # +#define ASCII_24 KEY_4 + ALTGR_MASK // 36 $ +#define ASCII_25 KEY_5 + SHIFT_MASK // 37 % +#define ASCII_26 KEY_6 + SHIFT_MASK // 38 & +#define ASCII_27 KEY_BACKSLASH // 39 ' +#define ASCII_28 KEY_8 + SHIFT_MASK // 40 ( +#define ASCII_29 KEY_9 + SHIFT_MASK // 41 ) +#define ASCII_2A KEY_BACKSLASH + SHIFT_MASK // 42 * +#define ASCII_2B KEY_MINUS // 43 + +#define ASCII_2C KEY_COMMA // 44 , +#define ASCII_2D KEY_SLASH // 45 - +#define ASCII_2E KEY_PERIOD // 46 . +#define ASCII_2F KEY_7 + SHIFT_MASK // 47 / +#define ASCII_30 KEY_0 // 48 0 +#define ASCII_31 KEY_1 // 49 1 +#define ASCII_32 KEY_2 // 50 2 +#define ASCII_33 KEY_3 // 51 3 +#define ASCII_34 KEY_4 // 52 4 +#define ASCII_35 KEY_5 // 53 5 +#define ASCII_36 KEY_6 // 54 6 +#define ASCII_37 KEY_7 // 55 7 +#define ASCII_38 KEY_8 // 55 8 +#define ASCII_39 KEY_9 // 57 9 +#define ASCII_3A KEY_PERIOD + SHIFT_MASK // 58 : +#define ASCII_3B KEY_COMMA + SHIFT_MASK // 59 ; +#define ASCII_3C KEY_NON_US_100 // 60 < +#define ASCII_3D KEY_0 + SHIFT_MASK // 61 = +#define ASCII_3E KEY_NON_US_100 + SHIFT_MASK // 62 > +#define ASCII_3F KEY_MINUS + SHIFT_MASK // 63 ? +#define ASCII_40 KEY_2 + ALTGR_MASK // 64 @ +#define ASCII_41 KEY_A + SHIFT_MASK // 65 A +#define ASCII_42 KEY_B + SHIFT_MASK // 66 B +#define ASCII_43 KEY_C + SHIFT_MASK // 67 C +#define ASCII_44 KEY_D + SHIFT_MASK // 68 D +#define ASCII_45 KEY_E + SHIFT_MASK // 69 E +#define ASCII_46 KEY_F + SHIFT_MASK // 70 F +#define ASCII_47 KEY_G + SHIFT_MASK // 71 G +#define ASCII_48 KEY_H + SHIFT_MASK // 72 H +#define ASCII_49 KEY_I + SHIFT_MASK // 73 I +#define ASCII_4A KEY_J + SHIFT_MASK // 74 J +#define ASCII_4B KEY_K + SHIFT_MASK // 75 K +#define ASCII_4C KEY_L + SHIFT_MASK // 76 L +#define ASCII_4D KEY_M + SHIFT_MASK // 77 M +#define ASCII_4E KEY_N + SHIFT_MASK // 78 N +#define ASCII_4F KEY_O + SHIFT_MASK // 79 O +#define ASCII_50 KEY_P + SHIFT_MASK // 80 P +#define ASCII_51 KEY_Q + SHIFT_MASK // 81 Q +#define ASCII_52 KEY_R + SHIFT_MASK // 82 R +#define ASCII_53 KEY_S + SHIFT_MASK // 83 S +#define ASCII_54 KEY_T + SHIFT_MASK // 84 T +#define ASCII_55 KEY_U + SHIFT_MASK // 85 U +#define ASCII_56 KEY_V + SHIFT_MASK // 86 V +#define ASCII_57 KEY_W + SHIFT_MASK // 87 W +#define ASCII_58 KEY_X + SHIFT_MASK // 88 X +#define ASCII_59 KEY_Y + SHIFT_MASK // 89 Y +#define ASCII_5A KEY_Z + SHIFT_MASK // 90 Z +#define ASCII_5B KEY_8 + ALTGR_MASK // 91 [ +#define ASCII_5C KEY_MINUS + ALTGR_MASK // 92 +#define ASCII_5D KEY_9 + ALTGR_MASK // 93 ] +#define ASCII_5E CIRCUMFLEX_BITS + KEY_SPACE // 94 ^ +#define ASCII_5F KEY_SLASH + SHIFT_MASK // 95 _ +#define ASCII_60 GRAVE_ACCENT_BITS + KEY_SPACE // 96 ` +#define ASCII_61 KEY_A // 97 a +#define ASCII_62 KEY_B // 98 b +#define ASCII_63 KEY_C // 99 c +#define ASCII_64 KEY_D // 100 d +#define ASCII_65 KEY_E // 101 e +#define ASCII_66 KEY_F // 102 f +#define ASCII_67 KEY_G // 103 g +#define ASCII_68 KEY_H // 104 h +#define ASCII_69 KEY_I // 105 i +#define ASCII_6A KEY_J // 106 j +#define ASCII_6B KEY_K // 107 k +#define ASCII_6C KEY_L // 108 l +#define ASCII_6D KEY_M // 109 m +#define ASCII_6E KEY_N // 110 n +#define ASCII_6F KEY_O // 111 o +#define ASCII_70 KEY_P // 112 p +#define ASCII_71 KEY_Q // 113 q +#define ASCII_72 KEY_R // 114 r +#define ASCII_73 KEY_S // 115 s +#define ASCII_74 KEY_T // 116 t +#define ASCII_75 KEY_U // 117 u +#define ASCII_76 KEY_V // 118 v +#define ASCII_77 KEY_W // 119 w +#define ASCII_78 KEY_X // 120 x +#define ASCII_79 KEY_Y // 121 y +#define ASCII_7A KEY_Z // 122 z +#define ASCII_7B KEY_7 + ALTGR_MASK // 123 { +#define ASCII_7C KEY_NON_US_100 + ALTGR_MASK // 124 | +#define ASCII_7D KEY_0 + ALTGR_MASK // 125 } +#define ASCII_7E TILDE_BITS + KEY_SPACE // 126 ~ +#define ASCII_7F KEY_BACKSPACE // 127 +#define ISO_8859_1_A0 KEY_SPACE + ALTGR_MASK // 160 Nonbreakng Space +#define ISO_8859_1_A1 KEY_1 + SHIFT_MASK + ALTGR_MASK // 161 ¡ Inverted Exclamation +#define ISO_8859_1_A2 0 // 162 ¢ Cent SIGN +#define ISO_8859_1_A3 KEY_3 + ALTGR_MASK // 163 £ Pound Sign +#define ISO_8859_1_A4 KEY_4 + SHIFT_MASK // 164 ¤ Currency or Euro Sign +#define ISO_8859_1_A5 0 // 165 ¥ YEN SIGN +#define ISO_8859_1_A6 0 // 166 ¦ BROKEN BAR +#define ISO_8859_1_A7 KEY_TILDE // 167 § SECTION SIGN +#define ISO_8859_1_A8 DIAERESIS_BITS + KEY_SPACE // 168 ¨ DIAERESIS +#define ISO_8859_1_A9 0 // 169 © COPYRIGHT SIGN +#define ISO_8859_1_AA 0 // 170 ª FEMININE ORDINAL +#define ISO_8859_1_AB KEY_4 + ALTGR_MASK + SHIFT_MASK // 171 « LEFT DOUBLE ANGLE QUOTE +#define ISO_8859_1_AC 0 // 172 ¬ NOT SIGN +#define ISO_8859_1_AD KEY_SLASH + ALTGR_MASK // 173 SOFT HYPHEN +#define ISO_8859_1_AE 0 // 174 ® REGISTERED SIGN +#define ISO_8859_1_AF 0 // 175 ¯ MACRON +#define ISO_8859_1_B0 KEY_0 + ALTGR_MASK + SHIFT_MASK // 176 ° DEGREE SIGN +#define ISO_8859_1_B1 0 // 177 ± PLUS-MINUS SIGN +#define ISO_8859_1_B2 0 // 178 ² SUPERSCRIPT TWO +#define ISO_8859_1_B3 0 // 179 ³ SUPERSCRIPT THREE +#define ISO_8859_1_B4 ACUTE_ACCENT_BITS + KEY_SPACE // 180 ´ ACUTE ACCENT +#define ISO_8859_1_B5 KEY_M + ALTGR_MASK // 181 µ MICRO SIGN +#define ISO_8859_1_B6 0 // 182 ¶ PILCROW SIGN +#define ISO_8859_1_B7 KEY_X + ALTGR_MASK + SHIFT_MASK // 183 · MIDDLE DOT +#define ISO_8859_1_B8 0 // 184 ¸ CEDILLA +#define ISO_8859_1_B9 0 // 185 ¹ SUPERSCRIPT ONE +#define ISO_8859_1_BA 0 // 186 º MASCULINE ORDINAL +#define ISO_8859_1_BB KEY_3 + ALTGR_MASK + SHIFT_MASK // 187 » RIGHT DOUBLE ANGLE QUOTE +#define ISO_8859_1_BC 0 // 188 ¼ FRACTION ONE QUARTER +#define ISO_8859_1_BD KEY_TILDE + SHIFT_MASK // 189 ½ FRACTION ONE HALF +#define ISO_8859_1_BE 0 // 190 ¾ FRACTION THREE QUARTERS +#define ISO_8859_1_BF KEY_MINUS + ALTGR_MASK + SHIFT_MASK // 191 ¿ INVERTED QUESTION MARK +#define ISO_8859_1_C0 GRAVE_ACCENT_BITS + KEY_A + SHIFT_MASK // 192 À A GRAVE +#define ISO_8859_1_C1 ACUTE_ACCENT_BITS + KEY_A + SHIFT_MASK // 193 à A ACUTE +#define ISO_8859_1_C2 CIRCUMFLEX_BITS + KEY_A + SHIFT_MASK // 194 Â A CIRCUMFLEX +#define ISO_8859_1_C3 TILDE_BITS + KEY_A + SHIFT_MASK // 195 Ã A TILDE +#define ISO_8859_1_C4 KEY_QUOTE + SHIFT_MASK // 196 Ä A DIAERESIS +#define ISO_8859_1_C5 KEY_LEFT_BRACE + SHIFT_MASK // 197 Å A RING ABOVE +#define ISO_8859_1_C6 KEY_QUOTE + ALTGR_MASK + SHIFT_MASK // 198 Æ AE +#define ISO_8859_1_C7 0 // 199 Ç C CEDILLA +#define ISO_8859_1_C8 GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK // 200 È E GRAVE +#define ISO_8859_1_C9 ACUTE_ACCENT_BITS + KEY_E + SHIFT_MASK // 201 É E ACUTE +#define ISO_8859_1_CA CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK // 202 Ê E CIRCUMFLEX +#define ISO_8859_1_CB DIAERESIS_BITS + KEY_E + SHIFT_MASK // 203 Ë E DIAERESIS +#define ISO_8859_1_CC GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK // 204 Ì I GRAVE +#define ISO_8859_1_CD ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK // 205 à I ACUTE +#define ISO_8859_1_CE CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK // 206 Î I CIRCUMFLEX +#define ISO_8859_1_CF DIAERESIS_BITS + KEY_I + SHIFT_MASK // 207 à I DIAERESIS +#define ISO_8859_1_D0 KEY_D + ALTGR_MASK + SHIFT_MASK // 208 à ETH +#define ISO_8859_1_D1 TILDE_BITS + KEY_N + SHIFT_MASK // 209 Ñ N TILDE +#define ISO_8859_1_D2 GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK // 210 Ò O GRAVE +#define ISO_8859_1_D3 ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK // 211 Ó O ACUTE +#define ISO_8859_1_D4 CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK // 212 Ô O CIRCUMFLEX +#define ISO_8859_1_D5 TILDE_BITS + KEY_O + SHIFT_MASK // 213 Õ O TILDE +#define ISO_8859_1_D6 KEY_SEMICOLON + SHIFT_MASK // 214 Ö O DIAERESIS +#define ISO_8859_1_D7 KEY_X + ALTGR_MASK // 215 × MULTIPLICATION +#define ISO_8859_1_D8 KEY_SEMICOLON + ALTGR_MASK + SHIFT_MASK // 216 Ø O STROKE +#define ISO_8859_1_D9 GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK // 217 Ù U GRAVE +#define ISO_8859_1_DA ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK // 218 Ú U ACUTE +#define ISO_8859_1_DB CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK // 219 Û U CIRCUMFLEX +#define ISO_8859_1_DC DIAERESIS_BITS + KEY_U + SHIFT_MASK // 220 Ü U DIAERESIS +#define ISO_8859_1_DD ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK // 221 à Y ACUTE +#define ISO_8859_1_DE KEY_T + ALTGR_MASK + SHIFT_MASK // 222 Þ THORN +#define ISO_8859_1_DF KEY_S + ALTGR_MASK // 223 ß SHARP S +#define ISO_8859_1_E0 GRAVE_ACCENT_BITS + KEY_A // 224 à a GRAVE +#define ISO_8859_1_E1 ACUTE_ACCENT_BITS + KEY_A // 225 á a ACUTE +#define ISO_8859_1_E2 CIRCUMFLEX_BITS + KEY_A // 226 â a CIRCUMFLEX +#define ISO_8859_1_E3 TILDE_BITS + KEY_A // 227 ã a TILDE +#define ISO_8859_1_E4 KEY_QUOTE // 228 ä a DIAERESIS +#define ISO_8859_1_E5 KEY_LEFT_BRACE // 229 å a RING ABOVE +#define ISO_8859_1_E6 KEY_QUOTE + ALTGR_MASK // 230 æ ae +#define ISO_8859_1_E7 0 // 231 ç c CEDILLA +#define ISO_8859_1_E8 GRAVE_ACCENT_BITS + KEY_E // 232 è e GRAVE +#define ISO_8859_1_E9 ACUTE_ACCENT_BITS + KEY_E // 233 é e ACUTE +#define ISO_8859_1_EA CIRCUMFLEX_BITS + KEY_E // 234 ê e CIRCUMFLEX +#define ISO_8859_1_EB DIAERESIS_BITS + KEY_E // 235 ë e DIAERESIS +#define ISO_8859_1_EC GRAVE_ACCENT_BITS + KEY_I // 236 ì i GRAVE +#define ISO_8859_1_ED ACUTE_ACCENT_BITS + KEY_I // 237 à i ACUTE +#define ISO_8859_1_EE CIRCUMFLEX_BITS + KEY_I // 238 î i CIRCUMFLEX +#define ISO_8859_1_EF DIAERESIS_BITS + KEY_I // 239 ï i DIAERESIS +#define ISO_8859_1_F0 KEY_D + ALTGR_MASK // 240 ð ETH +#define ISO_8859_1_F1 TILDE_BITS + KEY_N // 241 ñ n TILDE +#define ISO_8859_1_F2 GRAVE_ACCENT_BITS + KEY_O // 242 ò o GRAVE +#define ISO_8859_1_F3 ACUTE_ACCENT_BITS + KEY_O // 243 ó o ACUTE +#define ISO_8859_1_F4 CIRCUMFLEX_BITS + KEY_O // 244 ô o CIRCUMFLEX +#define ISO_8859_1_F5 TILDE_BITS + KEY_O // 245 õ o TILDE +#define ISO_8859_1_F6 KEY_SEMICOLON // 246 ö o DIAERESIS +#define ISO_8859_1_F7 0 // 247 ÷ DIVISION +#define ISO_8859_1_F8 KEY_SEMICOLON + ALTGR_MASK // 248 ø o STROKE +#define ISO_8859_1_F9 GRAVE_ACCENT_BITS + KEY_U // 249 ù u GRAVE +#define ISO_8859_1_FA ACUTE_ACCENT_BITS + KEY_U // 250 ú u ACUTE +#define ISO_8859_1_FB CIRCUMFLEX_BITS + KEY_U // 251 û u CIRCUMFLEX +#define ISO_8859_1_FC DIAERESIS_BITS + KEY_U // 252 ü u DIAERESIS +#define ISO_8859_1_FD ACUTE_ACCENT_BITS + KEY_Y // 253 ý y ACUTE +#define ISO_8859_1_FE KEY_T + ALTGR_MASK // 254 þ THORN +#define ISO_8859_1_FF DIAERESIS_BITS + KEY_Y // 255 ÿ y DIAERESIS +#define UNICODE_20AC KEY_E + ALTGR_MASK // € Euro Sign +// not yet implemented +#define UNICODE_EXTRA00 0x20AC +#define KEYCODE_EXTRA00 KEY_E + ALTGR_MASK // 20AC € Euro Sign +// TODO: Finnish Multilingual layout can type many more glyphs +// but we currently don't have tables tables to store them... + +#endif // LAYOUT_FINNISH + + + + + + + +#ifdef LAYOUT_FRENCH + +#define SHIFT_MASK 0x0040 +#define ALTGR_MASK 0x0080 +#define DEADKEYS_MASK 0x0700 +#define CIRCUMFLEX_BITS 0x0100 +#define GRAVE_ACCENT_BITS 0x0200 +#define DIAERESIS_BITS 0x0300 +#define TILDE_BITS 0x0400 +#define KEYCODE_TYPE uint16_t +#define DEADKEY_CIRCUMFLEX KEY_LEFT_BRACE +#define DEADKEY_GRAVE_ACCENT KEY_7 + ALTGR_MASK +#define DEADKEY_DIAERESIS KEY_LEFT_BRACE + SHIFT_MASK +#define DEADKEY_TILDE KEY_2 + ALTGR_MASK +#define KEY_NON_US_100 63 + +#define ASCII_20 KEY_SPACE // 32 +#define ASCII_21 KEY_SLASH // 33 ! +#define ASCII_22 KEY_3 // 34 " +#define ASCII_23 KEY_3 + ALTGR_MASK // 35 # +#define ASCII_24 KEY_RIGHT_BRACE // 36 $ +#define ASCII_25 KEY_QUOTE + SHIFT_MASK // 37 % +#define ASCII_26 KEY_1 // 38 & +#define ASCII_27 KEY_4 // 39 ' +#define ASCII_28 KEY_5 // 40 ( +#define ASCII_29 KEY_MINUS // 41 ) +#define ASCII_2A KEY_BACKSLASH // 42 * +#define ASCII_2B KEY_EQUAL + SHIFT_MASK // 43 + +#define ASCII_2C KEY_M // 44 , +#define ASCII_2D KEY_6 // 45 - +#define ASCII_2E KEY_COMMA + SHIFT_MASK // 46 . +#define ASCII_2F KEY_PERIOD + SHIFT_MASK // 47 / +#define ASCII_30 KEY_0 + SHIFT_MASK // 48 0 +#define ASCII_31 KEY_1 + SHIFT_MASK // 49 1 +#define ASCII_32 KEY_2 + SHIFT_MASK // 50 2 +#define ASCII_33 KEY_3 + SHIFT_MASK // 51 3 +#define ASCII_34 KEY_4 + SHIFT_MASK // 52 4 +#define ASCII_35 KEY_5 + SHIFT_MASK // 53 5 +#define ASCII_36 KEY_6 + SHIFT_MASK // 54 6 +#define ASCII_37 KEY_7 + SHIFT_MASK // 55 7 +#define ASCII_38 KEY_8 + SHIFT_MASK // 55 8 +#define ASCII_39 KEY_9 + SHIFT_MASK // 57 9 +#define ASCII_3A KEY_PERIOD // 58 : +#define ASCII_3B KEY_COMMA // 59 ; +#define ASCII_3C KEY_NON_US_100 // 60 < +#define ASCII_3D KEY_EQUAL // 61 = +#define ASCII_3E KEY_NON_US_100 + SHIFT_MASK // 62 > +#define ASCII_3F KEY_M + SHIFT_MASK // 63 ? +#define ASCII_40 KEY_0 + ALTGR_MASK // 64 @ +#define ASCII_41 KEY_Q + SHIFT_MASK // 65 A +#define ASCII_42 KEY_B + SHIFT_MASK // 66 B +#define ASCII_43 KEY_C + SHIFT_MASK // 67 C +#define ASCII_44 KEY_D + SHIFT_MASK // 68 D +#define ASCII_45 KEY_E + SHIFT_MASK // 69 E +#define ASCII_46 KEY_F + SHIFT_MASK // 70 F +#define ASCII_47 KEY_G + SHIFT_MASK // 71 G +#define ASCII_48 KEY_H + SHIFT_MASK // 72 H +#define ASCII_49 KEY_I + SHIFT_MASK // 73 I +#define ASCII_4A KEY_J + SHIFT_MASK // 74 J +#define ASCII_4B KEY_K + SHIFT_MASK // 75 K +#define ASCII_4C KEY_L + SHIFT_MASK // 76 L +#define ASCII_4D KEY_SEMICOLON + SHIFT_MASK // 77 M +#define ASCII_4E KEY_N + SHIFT_MASK // 78 N +#define ASCII_4F KEY_O + SHIFT_MASK // 79 O +#define ASCII_50 KEY_P + SHIFT_MASK // 80 P +#define ASCII_51 KEY_A + SHIFT_MASK // 81 Q +#define ASCII_52 KEY_R + SHIFT_MASK // 82 R +#define ASCII_53 KEY_S + SHIFT_MASK // 83 S +#define ASCII_54 KEY_T + SHIFT_MASK // 84 T +#define ASCII_55 KEY_U + SHIFT_MASK // 85 U +#define ASCII_56 KEY_V + SHIFT_MASK // 86 V +#define ASCII_57 KEY_Z + SHIFT_MASK // 87 W +#define ASCII_58 KEY_X + SHIFT_MASK // 88 X +#define ASCII_59 KEY_Y + SHIFT_MASK // 89 Y +#define ASCII_5A KEY_W + SHIFT_MASK // 90 Z +#define ASCII_5B KEY_5 + ALTGR_MASK // 91 [ +#define ASCII_5C KEY_8 + ALTGR_MASK // 92 +#define ASCII_5D KEY_MINUS + ALTGR_MASK // 93 ] +#define ASCII_5E KEY_9 + ALTGR_MASK // 94 ^ +#define ASCII_5F KEY_8 // 95 _ +#define ASCII_60 GRAVE_ACCENT_BITS + KEY_SPACE // 96 ` +#define ASCII_61 KEY_Q // 97 a +#define ASCII_62 KEY_B // 98 b +#define ASCII_63 KEY_C // 99 c +#define ASCII_64 KEY_D // 100 d +#define ASCII_65 KEY_E // 101 e +#define ASCII_66 KEY_F // 102 f +#define ASCII_67 KEY_G // 103 g +#define ASCII_68 KEY_H // 104 h +#define ASCII_69 KEY_I // 105 i +#define ASCII_6A KEY_J // 106 j +#define ASCII_6B KEY_K // 107 k +#define ASCII_6C KEY_L // 108 l +#define ASCII_6D KEY_SEMICOLON // 109 m +#define ASCII_6E KEY_N // 110 n +#define ASCII_6F KEY_O // 111 o +#define ASCII_70 KEY_P // 112 p +#define ASCII_71 KEY_A // 113 q +#define ASCII_72 KEY_R // 114 r +#define ASCII_73 KEY_S // 115 s +#define ASCII_74 KEY_T // 116 t +#define ASCII_75 KEY_U // 117 u +#define ASCII_76 KEY_V // 118 v +#define ASCII_77 KEY_Z // 119 w +#define ASCII_78 KEY_X // 120 x +#define ASCII_79 KEY_Y // 121 y +#define ASCII_7A KEY_W // 122 z +#define ASCII_7B KEY_4 + ALTGR_MASK // 123 { +#define ASCII_7C KEY_6 + ALTGR_MASK // 124 | +#define ASCII_7D KEY_EQUAL + ALTGR_MASK // 125 } +#define ASCII_7E TILDE_BITS + KEY_SPACE // 126 ~ +#define ASCII_7F KEY_BACKSPACE // 127 +#define ISO_8859_1_A0 KEY_SPACE // 160 Nonbreakng Space +#define ISO_8859_1_A1 0 // 161 ¡ Inverted Exclamation +#define ISO_8859_1_A2 0 // 162 ¢ Cent SIGN +#define ISO_8859_1_A3 KEY_RIGHT_BRACE + SHIFT_MASK // 163 £ Pound Sign +#define ISO_8859_1_A4 KEY_RIGHT_BRACE + ALTGR_MASK // 164 ¤ Currency or Euro Sign +#define ISO_8859_1_A5 0 // 165 ¥ YEN SIGN +#define ISO_8859_1_A6 0 // 166 ¦ BROKEN BAR +#define ISO_8859_1_A7 KEY_SLASH + SHIFT_MASK // 167 § SECTION SIGN +#define ISO_8859_1_A8 DIAERESIS_BITS + KEY_SPACE // 168 ¨ DIAERESIS +#define ISO_8859_1_A9 0 // 169 © COPYRIGHT SIGN +#define ISO_8859_1_AA 0 // 170 ª FEMININE ORDINAL +#define ISO_8859_1_AB 0 // 171 « LEFT DOUBLE ANGLE QUOTE +#define ISO_8859_1_AC 0 // 172 ¬ NOT SIGN +#define ISO_8859_1_AD 0 // 173 SOFT HYPHEN +#define ISO_8859_1_AE 0 // 174 ® REGISTERED SIGN +#define ISO_8859_1_AF 0 // 175 ¯ MACRON +#define ISO_8859_1_B0 KEY_MINUS + SHIFT_MASK // 176 ° DEGREE SIGN +#define ISO_8859_1_B1 0 // 177 ± PLUS-MINUS SIGN +#define ISO_8859_1_B2 KEY_TILDE // 178 ² SUPERSCRIPT TWO +#define ISO_8859_1_B3 0 // 179 ³ SUPERSCRIPT THREE +#define ISO_8859_1_B4 0 // 180 ´ ACUTE ACCENT +#define ISO_8859_1_B5 KEY_BACKSLASH + SHIFT_MASK // 181 µ MICRO SIGN +#define ISO_8859_1_B6 0 // 182 ¶ PILCROW SIGN +#define ISO_8859_1_B7 0 // 183 · MIDDLE DOT +#define ISO_8859_1_B8 0 // 184 ¸ CEDILLA +#define ISO_8859_1_B9 0 // 185 ¹ SUPERSCRIPT ONE +#define ISO_8859_1_BA 0 // 186 º MASCULINE ORDINAL +#define ISO_8859_1_BB 0 // 187 » RIGHT DOUBLE ANGLE QUOTE +#define ISO_8859_1_BC 0 // 188 ¼ FRACTION ONE QUARTER +#define ISO_8859_1_BD 0 // 189 ½ FRACTION ONE HALF +#define ISO_8859_1_BE 0 // 190 ¾ FRACTION THREE QUARTERS +#define ISO_8859_1_BF 0 // 191 ¿ INVERTED QUESTION MARK +#define ISO_8859_1_C0 GRAVE_ACCENT_BITS + KEY_Q + SHIFT_MASK // 192 À A GRAVE +#define ISO_8859_1_C1 0 // 193 à A ACUTE +#define ISO_8859_1_C2 CIRCUMFLEX_BITS + KEY_Q + SHIFT_MASK // 194 Â A CIRCUMFLEX +#define ISO_8859_1_C3 TILDE_BITS + KEY_Q + SHIFT_MASK // 195 Ã A TILDE +#define ISO_8859_1_C4 DIAERESIS_BITS + KEY_Q + SHIFT_MASK // 196 Ä A DIAERESIS +#define ISO_8859_1_C5 0 // 197 Å A RING ABOVE +#define ISO_8859_1_C6 0 // 198 Æ AE +#define ISO_8859_1_C7 0 // 199 Ç C CEDILLA +#define ISO_8859_1_C8 GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK // 200 È E GRAVE +#define ISO_8859_1_C9 0 // 201 É E ACUTE +#define ISO_8859_1_CA CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK // 202 Ê E CIRCUMFLEX +#define ISO_8859_1_CB DIAERESIS_BITS + KEY_E + SHIFT_MASK // 203 Ë E DIAERESIS +#define ISO_8859_1_CC GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK // 204 Ì I GRAVE +#define ISO_8859_1_CD 0 // 205 à I ACUTE +#define ISO_8859_1_CE CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK // 206 Î I CIRCUMFLEX +#define ISO_8859_1_CF DIAERESIS_BITS + KEY_I + SHIFT_MASK // 207 à I DIAERESIS +#define ISO_8859_1_D0 0 // 208 à ETH +#define ISO_8859_1_D1 TILDE_BITS + KEY_N + SHIFT_MASK // 209 Ñ N TILDE +#define ISO_8859_1_D2 GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK // 210 Ò O GRAVE +#define ISO_8859_1_D3 0 // 211 Ó O ACUTE +#define ISO_8859_1_D4 CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK // 212 Ô O CIRCUMFLEX +#define ISO_8859_1_D5 TILDE_BITS + KEY_O + SHIFT_MASK // 213 Õ O TILDE +#define ISO_8859_1_D6 DIAERESIS_BITS + KEY_O + SHIFT_MASK // 214 Ö O DIAERESIS +#define ISO_8859_1_D7 0 // 215 × MULTIPLICATION +#define ISO_8859_1_D8 0 // 216 Ø O STROKE +#define ISO_8859_1_D9 GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK // 217 Ù U GRAVE +#define ISO_8859_1_DA 0 // 218 Ú U ACUTE +#define ISO_8859_1_DB CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK // 219 Û U CIRCUMFLEX +#define ISO_8859_1_DC DIAERESIS_BITS + KEY_U // 220 Ü U DIAERESIS +#define ISO_8859_1_DD 0 // 221 à Y ACUTE +#define ISO_8859_1_DE 0 // 222 Þ THORN +#define ISO_8859_1_DF 0 // 223 ß SHARP S +#define ISO_8859_1_E0 KEY_0 // 224 à a GRAVE +#define ISO_8859_1_E1 0 // 225 á a ACUTE +#define ISO_8859_1_E2 CIRCUMFLEX_BITS + KEY_Q // 226 â a CIRCUMFLEX +#define ISO_8859_1_E3 TILDE_BITS + KEY_Q // 227 ã a TILDE +#define ISO_8859_1_E4 DIAERESIS_BITS + KEY_Q // 228 ä a DIAERESIS +#define ISO_8859_1_E5 0 // 229 å a RING ABOVE +#define ISO_8859_1_E6 0 // 230 æ ae +#define ISO_8859_1_E7 KEY_9 // 231 ç c CEDILLA +#define ISO_8859_1_E8 KEY_7 // 232 è e GRAVE +#define ISO_8859_1_E9 KEY_2 // 233 é e ACUTE +#define ISO_8859_1_EA CIRCUMFLEX_BITS + KEY_E // 234 ê e CIRCUMFLEX +#define ISO_8859_1_EB DIAERESIS_BITS + KEY_E // 235 ë e DIAERESIS +#define ISO_8859_1_EC GRAVE_ACCENT_BITS + KEY_I // 236 ì i GRAVE +#define ISO_8859_1_ED 0 // 237 à i ACUTE +#define ISO_8859_1_EE CIRCUMFLEX_BITS + KEY_I // 238 î i CIRCUMFLEX +#define ISO_8859_1_EF DIAERESIS_BITS + KEY_I // 239 ï i DIAERESIS +#define ISO_8859_1_F0 0 // 240 ð ETH +#define ISO_8859_1_F1 TILDE_BITS + KEY_N // 241 ñ n TILDE +#define ISO_8859_1_F2 GRAVE_ACCENT_BITS + KEY_O // 242 ò o GRAVE +#define ISO_8859_1_F3 0 // 243 ó o ACUTE +#define ISO_8859_1_F4 CIRCUMFLEX_BITS + KEY_O // 244 ô o CIRCUMFLEX +#define ISO_8859_1_F5 TILDE_BITS + KEY_O // 245 õ o TILDE +#define ISO_8859_1_F6 DIAERESIS_BITS + KEY_O // 246 ö o DIAERESIS +#define ISO_8859_1_F7 0 // 247 ÷ DIVISION +#define ISO_8859_1_F8 0 // 248 ø o STROKE +#define ISO_8859_1_F9 KEY_SEMICOLON // 249 ù u GRAVE +#define ISO_8859_1_FA 0 // 250 ú u ACUTE +#define ISO_8859_1_FB CIRCUMFLEX_BITS + KEY_U // 251 û u CIRCUMFLEX +#define ISO_8859_1_FC DIAERESIS_BITS + KEY_U // 252 ü u DIAERESIS +#define ISO_8859_1_FD 0 // 253 ý y ACUTE +#define ISO_8859_1_FE 0 // 254 þ THORN +#define ISO_8859_1_FF DIAERESIS_BITS + KEY_Y // 255 ÿ y DIAERESIS +#define UNICODE_20AC KEY_E + ALTGR_MASK // € Euro Sign +// not yet implemented +#define UNICODE_EXTRA00 0x20AC +#define KEYCODE_EXTRA00 KEY_E + ALTGR_MASK // 20AC € Euro Sign + +#endif // LAYOUT_FRENCH + + + + + +#ifdef LAYOUT_DANISH + +#define SHIFT_MASK 0x0040 +#define ALTGR_MASK 0x0080 +#define DEADKEYS_MASK 0x0700 +#define CIRCUMFLEX_BITS 0x0100 +#define ACUTE_ACCENT_BITS 0x0200 +#define GRAVE_ACCENT_BITS 0x0300 +#define TILDE_BITS 0x0400 +#define DIAERESIS_BITS 0x0500 +#define KEYCODE_TYPE uint16_t +#define DEADKEY_CIRCUMFLEX KEY_RIGHT_BRACE + SHIFT_MASK +#define DEADKEY_ACUTE_ACCENT KEY_EQUAL +#define DEADKEY_GRAVE_ACCENT KEY_EQUAL + SHIFT_MASK +#define DEADKEY_TILDE KEY_RIGHT_BRACE + ALTGR_MASK +#define DEADKEY_DIAERESIS KEY_RIGHT_BRACE +#define KEY_NON_US_100 63 + +#define ASCII_20 KEY_SPACE // 32 +#define ASCII_21 KEY_1 + SHIFT_MASK // 33 ! +#define ASCII_22 KEY_2 + SHIFT_MASK // 34 " +#define ASCII_23 KEY_3 + SHIFT_MASK // 35 # +#define ASCII_24 KEY_4 + ALTGR_MASK // 36 $ +#define ASCII_25 KEY_5 + SHIFT_MASK // 37 % +#define ASCII_26 KEY_6 + SHIFT_MASK // 38 & +#define ASCII_27 KEY_BACKSLASH // 39 ' +#define ASCII_28 KEY_8 + SHIFT_MASK // 40 ( +#define ASCII_29 KEY_9 + SHIFT_MASK // 41 ) +#define ASCII_2A KEY_BACKSLASH + SHIFT_MASK // 42 * +#define ASCII_2B KEY_MINUS // 43 + +#define ASCII_2C KEY_COMMA // 44 , +#define ASCII_2D KEY_SLASH // 45 - +#define ASCII_2E KEY_PERIOD // 46 . +#define ASCII_2F KEY_7 + SHIFT_MASK // 47 / +#define ASCII_30 KEY_0 // 48 0 +#define ASCII_31 KEY_1 // 49 1 +#define ASCII_32 KEY_2 // 50 2 +#define ASCII_33 KEY_3 // 51 3 +#define ASCII_34 KEY_4 // 52 4 +#define ASCII_35 KEY_5 // 53 5 +#define ASCII_36 KEY_6 // 54 6 +#define ASCII_37 KEY_7 // 55 7 +#define ASCII_38 KEY_8 // 55 8 +#define ASCII_39 KEY_9 // 57 9 +#define ASCII_3A KEY_PERIOD + SHIFT_MASK // 58 : +#define ASCII_3B KEY_COMMA + SHIFT_MASK // 59 ; +#define ASCII_3C KEY_NON_US_100 // 60 < +#define ASCII_3D KEY_0 + SHIFT_MASK // 61 = +#define ASCII_3E KEY_NON_US_100 + SHIFT_MASK // 62 > +#define ASCII_3F KEY_MINUS + SHIFT_MASK // 63 ? +#define ASCII_40 KEY_2 + ALTGR_MASK // 64 @ +#define ASCII_41 KEY_A + SHIFT_MASK // 65 A +#define ASCII_42 KEY_B + SHIFT_MASK // 66 B +#define ASCII_43 KEY_C + SHIFT_MASK // 67 C +#define ASCII_44 KEY_D + SHIFT_MASK // 68 D +#define ASCII_45 KEY_E + SHIFT_MASK // 69 E +#define ASCII_46 KEY_F + SHIFT_MASK // 70 F +#define ASCII_47 KEY_G + SHIFT_MASK // 71 G +#define ASCII_48 KEY_H + SHIFT_MASK // 72 H +#define ASCII_49 KEY_I + SHIFT_MASK // 73 I +#define ASCII_4A KEY_J + SHIFT_MASK // 74 J +#define ASCII_4B KEY_K + SHIFT_MASK // 75 K +#define ASCII_4C KEY_L + SHIFT_MASK // 76 L +#define ASCII_4D KEY_M + SHIFT_MASK // 77 M +#define ASCII_4E KEY_N + SHIFT_MASK // 78 N +#define ASCII_4F KEY_O + SHIFT_MASK // 79 O +#define ASCII_50 KEY_P + SHIFT_MASK // 80 P +#define ASCII_51 KEY_Q + SHIFT_MASK // 81 Q +#define ASCII_52 KEY_R + SHIFT_MASK // 82 R +#define ASCII_53 KEY_S + SHIFT_MASK // 83 S +#define ASCII_54 KEY_T + SHIFT_MASK // 84 T +#define ASCII_55 KEY_U + SHIFT_MASK // 85 U +#define ASCII_56 KEY_V + SHIFT_MASK // 86 V +#define ASCII_57 KEY_W + SHIFT_MASK // 87 W +#define ASCII_58 KEY_X + SHIFT_MASK // 88 X +#define ASCII_59 KEY_Y + SHIFT_MASK // 89 Y +#define ASCII_5A KEY_Z + SHIFT_MASK // 90 Z +#define ASCII_5B KEY_8 + ALTGR_MASK // 91 [ +#define ASCII_5C KEY_NON_US_100 + ALTGR_MASK // 92 +#define ASCII_5D KEY_9 + ALTGR_MASK // 93 ] +#define ASCII_5E CIRCUMFLEX_BITS + KEY_SPACE // 94 ^ +#define ASCII_5F KEY_SLASH + SHIFT_MASK // 95 _ +#define ASCII_60 GRAVE_ACCENT_BITS + KEY_SPACE // 96 ` +#define ASCII_61 KEY_A // 97 a +#define ASCII_62 KEY_B // 98 b +#define ASCII_63 KEY_C // 99 c +#define ASCII_64 KEY_D // 100 d +#define ASCII_65 KEY_E // 101 e +#define ASCII_66 KEY_F // 102 f +#define ASCII_67 KEY_G // 103 g +#define ASCII_68 KEY_H // 104 h +#define ASCII_69 KEY_I // 105 i +#define ASCII_6A KEY_J // 106 j +#define ASCII_6B KEY_K // 107 k +#define ASCII_6C KEY_L // 108 l +#define ASCII_6D KEY_M // 109 m +#define ASCII_6E KEY_N // 110 n +#define ASCII_6F KEY_O // 111 o +#define ASCII_70 KEY_P // 112 p +#define ASCII_71 KEY_Q // 113 q +#define ASCII_72 KEY_R // 114 r +#define ASCII_73 KEY_S // 115 s +#define ASCII_74 KEY_T // 116 t +#define ASCII_75 KEY_U // 117 u +#define ASCII_76 KEY_V // 118 v +#define ASCII_77 KEY_W // 119 w +#define ASCII_78 KEY_X // 120 x +#define ASCII_79 KEY_Y // 121 y +#define ASCII_7A KEY_Z // 122 z +#define ASCII_7B KEY_7 + ALTGR_MASK // 123 { +#define ASCII_7C KEY_EQUAL + ALTGR_MASK // 124 | +#define ASCII_7D KEY_0 + ALTGR_MASK // 125 } +#define ASCII_7E TILDE_BITS + KEY_SPACE // 126 ~ +#define ASCII_7F KEY_BACKSPACE // 127 + +#define ISO_8859_1_A0 KEY_SPACE // 160 Nonbreakng Space +#define ISO_8859_1_A1 0 // 161 ¡ Inverted Exclamation +#define ISO_8859_1_A2 0 // 162 ¢ Cent SIGN +#define ISO_8859_1_A3 KEY_3 + ALTGR_MASK // 163 £ Pound Sign +#define ISO_8859_1_A4 KEY_4 + SHIFT_MASK // 164 ¤ Currency Sign +#define ISO_8859_1_A5 0 // 165 ¥ YEN SIGN +#define ISO_8859_1_A6 0 // 166 ¦ BROKEN BAR +#define ISO_8859_1_A7 KEY_TILDE + SHIFT_MASK // 167 § SECTION SIGN +#define ISO_8859_1_A8 DIAERESIS_BITS + KEY_SPACE // 168 ¨ DIAERESIS +#define ISO_8859_1_A9 0 // 169 © COPYRIGHT SIGN +#define ISO_8859_1_AA 0 // 170 ª FEMININE ORDINAL +#define ISO_8859_1_AB KEY_4 // 171 « LEFT DOUBLE ANGLE QUOTE +#define ISO_8859_1_AC 0 // 172 ¬ NOT SIGN +#define ISO_8859_1_AD 0 // 173 SOFT HYPHEN +#define ISO_8859_1_AE 0 // 174 ® REGISTERED SIGN +#define ISO_8859_1_AF 0 // 175 ¯ MACRON +#define ISO_8859_1_B0 0 // 176 ° DEGREE SIGN +#define ISO_8859_1_B1 0 // 177 ± PLUS-MINUS SIGN +#define ISO_8859_1_B2 0 // 178 ² SUPERSCRIPT TWO +#define ISO_8859_1_B3 0 // 179 ³ SUPERSCRIPT THREE +#define ISO_8859_1_B4 ACUTE_ACCENT_BITS + KEY_SPACE // 180 ´ ACUTE ACCENT +#define ISO_8859_1_B5 KEY_M + ALTGR_MASK // 181 µ MICRO SIGN +#define ISO_8859_1_B6 0 // 182 ¶ PILCROW SIGN +#define ISO_8859_1_B7 0 // 183 · MIDDLE DOT +#define ISO_8859_1_B8 0 // 184 ¸ CEDILLA +#define ISO_8859_1_B9 0 // 185 ¹ SUPERSCRIPT ONE +#define ISO_8859_1_BA 0 // 186 º MASCULINE ORDINAL +#define ISO_8859_1_BB 0 // 187 » RIGHT DOUBLE ANGLE QUOTE +#define ISO_8859_1_BC 0 // 188 ¼ FRACTION ONE QUARTER +#define ISO_8859_1_BD KEY_TILDE // 189 ½ FRACTION ONE HALF +#define ISO_8859_1_BE 0 // 190 ¾ FRACTION THREE QUARTERS +#define ISO_8859_1_BF 0 // 191 ¿ INVERTED QUESTION MARK +#define ISO_8859_1_C0 GRAVE_ACCENT_BITS + KEY_A + SHIFT_MASK // 192 À A GRAVE +#define ISO_8859_1_C1 ACUTE_ACCENT_BITS + KEY_A + SHIFT_MASK // 193 à A ACUTE +#define ISO_8859_1_C2 CIRCUMFLEX_BITS + KEY_A + SHIFT_MASK // 194 Â A CIRCUMFLEX +#define ISO_8859_1_C3 TILDE_BITS + KEY_A + SHIFT_MASK // 195 Ã A TILDE +#define ISO_8859_1_C4 DIAERESIS_BITS + KEY_A + SHIFT_MASK // 196 Ä A DIAERESIS +#define ISO_8859_1_C5 KEY_LEFT_BRACE + SHIFT_MASK // 197 Å A RING ABOVE +#define ISO_8859_1_C6 KEY_SEMICOLON + SHIFT_MASK // 198 Æ AE +#define ISO_8859_1_C7 0 // 199 Ç C CEDILLA +#define ISO_8859_1_C8 GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK // 200 È E GRAVE +#define ISO_8859_1_C9 ACUTE_ACCENT_BITS + KEY_E + SHIFT_MASK // 201 É E ACUTE +#define ISO_8859_1_CA CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK // 202 Ê E CIRCUMFLEX +#define ISO_8859_1_CB DIAERESIS_BITS + KEY_E + SHIFT_MASK // 203 Ë E DIAERESIS +#define ISO_8859_1_CC GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK // 204 Ì I GRAVE +#define ISO_8859_1_CD ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK // 205 à I ACUTE +#define ISO_8859_1_CE CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK // 206 Î I CIRCUMFLEX +#define ISO_8859_1_CF DIAERESIS_BITS + KEY_I + SHIFT_MASK // 207 à I DIAERESIS +#define ISO_8859_1_D0 KEY_D + ALTGR_MASK + SHIFT_MASK // 208 à ETH +#define ISO_8859_1_D1 TILDE_BITS + KEY_N + SHIFT_MASK // 209 Ñ N TILDE +#define ISO_8859_1_D2 GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK // 210 Ò O GRAVE +#define ISO_8859_1_D3 ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK // 211 Ó O ACUTE +#define ISO_8859_1_D4 CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK // 212 Ô O CIRCUMFLEX +#define ISO_8859_1_D5 TILDE_BITS + KEY_O + SHIFT_MASK // 213 Õ O TILDE +#define ISO_8859_1_D6 DIAERESIS_BITS + KEY_O + SHIFT_MASK // 214 Ö O DIAERESIS +#define ISO_8859_1_D7 0 // 215 × MULTIPLICATION +#define ISO_8859_1_D8 KEY_QUOTE + SHIFT_MASK // 216 Ø O STROKE +#define ISO_8859_1_D9 GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK // 217 Ù U GRAVE +#define ISO_8859_1_DA ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK // 218 Ú U ACUTE +#define ISO_8859_1_DB CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK // 219 Û U CIRCUMFLEX +#define ISO_8859_1_DC DIAERESIS_BITS + KEY_U + SHIFT_MASK // 220 Ü U DIAERESIS +#define ISO_8859_1_DD ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK // 221 à Y ACUTE +#define ISO_8859_1_DE KEY_T + ALTGR_MASK + SHIFT_MASK // 222 Þ THORN +#define ISO_8859_1_DF KEY_S + ALTGR_MASK // 223 ß SHARP S +#define ISO_8859_1_E0 GRAVE_ACCENT_BITS + KEY_A // 224 à a GRAVE +#define ISO_8859_1_E1 ACUTE_ACCENT_BITS + KEY_A // 225 á a ACUTE +#define ISO_8859_1_E2 CIRCUMFLEX_BITS + KEY_A // 226 â a CIRCUMFLEX +#define ISO_8859_1_E3 TILDE_BITS + KEY_A // 227 ã a TILDE +#define ISO_8859_1_E4 DIAERESIS_BITS + KEY_A // 228 ä a DIAERESIS +#define ISO_8859_1_E5 KEY_LEFT_BRACE // 229 å a RING ABOVE +#define ISO_8859_1_E6 KEY_SEMICOLON // 230 æ ae +#define ISO_8859_1_E7 0 // 231 ç c CEDILLA +#define ISO_8859_1_E8 GRAVE_ACCENT_BITS + KEY_E // 232 è e GRAVE +#define ISO_8859_1_E9 ACUTE_ACCENT_BITS + KEY_E // 233 é e ACUTE +#define ISO_8859_1_EA CIRCUMFLEX_BITS + KEY_E // 234 ê e CIRCUMFLEX +#define ISO_8859_1_EB DIAERESIS_BITS + KEY_E // 235 ë e DIAERESIS +#define ISO_8859_1_EC GRAVE_ACCENT_BITS + KEY_I // 236 ì i GRAVE +#define ISO_8859_1_ED ACUTE_ACCENT_BITS + KEY_I // 237 à i ACUTE +#define ISO_8859_1_EE CIRCUMFLEX_BITS + KEY_I // 238 î i CIRCUMFLEX +#define ISO_8859_1_EF DIAERESIS_BITS + KEY_I // 239 ï i DIAERESIS +#define ISO_8859_1_F0 KEY_D + ALTGR_MASK // 240 ð ETH +#define ISO_8859_1_F1 TILDE_BITS + KEY_N // 241 ñ n TILDE +#define ISO_8859_1_F2 GRAVE_ACCENT_BITS + KEY_O // 242 ò o GRAVE +#define ISO_8859_1_F3 ACUTE_ACCENT_BITS + KEY_O // 243 ó o ACUTE +#define ISO_8859_1_F4 CIRCUMFLEX_BITS + KEY_O // 244 ô o CIRCUMFLEX +#define ISO_8859_1_F5 TILDE_BITS + KEY_O // 245 õ o TILDE +#define ISO_8859_1_F6 DIAERESIS_BITS + KEY_O // 246 ö o DIAERESIS +#define ISO_8859_1_F7 0 // 247 ÷ DIVISION +#define ISO_8859_1_F8 KEY_QUOTE // 248 ø o STROKE +#define ISO_8859_1_F9 GRAVE_ACCENT_BITS + KEY_U // 249 ù u GRAVE +#define ISO_8859_1_FA ACUTE_ACCENT_BITS + KEY_U // 250 ú u ACUTE +#define ISO_8859_1_FB CIRCUMFLEX_BITS + KEY_U // 251 û u CIRCUMFLEX +#define ISO_8859_1_FC DIAERESIS_BITS + KEY_U // 252 ü u DIAERESIS +#define ISO_8859_1_FD ACUTE_ACCENT_BITS + KEY_Y // 253 ý y ACUTE +#define ISO_8859_1_FE KEY_T + ALTGR_MASK // 254 þ THORN +#define ISO_8859_1_FF DIAERESIS_BITS + KEY_Y // 255 ÿ y DIAERESIS +#define UNICODE_20AC KEY_E + ALTGR_MASK // € Euro Sign +// not yet implemented +#define UNICODE_EXTRA00 0x20AC +#define KEYCODE_EXTRA00 KEY_E + ALTGR_MASK // 20AC € Euro Sign + +#endif // LAYOUT_DANISH + + + + + +#ifdef LAYOUT_NORWEGIAN + +#define SHIFT_MASK 0x0040 +#define ALTGR_MASK 0x0080 +#define DEADKEYS_MASK 0x0700 +#define CIRCUMFLEX_BITS 0x0100 +#define ACUTE_ACCENT_BITS 0x0200 +#define GRAVE_ACCENT_BITS 0x0300 +#define TILDE_BITS 0x0400 +#define DIAERESIS_BITS 0x0500 +#define KEYCODE_TYPE uint16_t +#define DEADKEY_CIRCUMFLEX KEY_RIGHT_BRACE + SHIFT_MASK +#define DEADKEY_ACUTE_ACCENT KEY_EQUAL + ALTGR_MASK +#define DEADKEY_GRAVE_ACCENT KEY_EQUAL + SHIFT_MASK +#define DEADKEY_TILDE KEY_RIGHT_BRACE + ALTGR_MASK +#define DEADKEY_DIAERESIS KEY_RIGHT_BRACE +#define KEY_NON_US_100 63 + +#define ASCII_20 KEY_SPACE // 32 +#define ASCII_21 KEY_1 + SHIFT_MASK // 33 ! +#define ASCII_22 KEY_2 + SHIFT_MASK // 34 " +#define ASCII_23 KEY_3 + SHIFT_MASK // 35 # +#define ASCII_24 KEY_4 + ALTGR_MASK // 36 $ +#define ASCII_25 KEY_5 + SHIFT_MASK // 37 % +#define ASCII_26 KEY_6 + SHIFT_MASK // 38 & +#define ASCII_27 KEY_BACKSLASH // 39 ' +#define ASCII_28 KEY_8 + SHIFT_MASK // 40 ( +#define ASCII_29 KEY_9 + SHIFT_MASK // 41 ) +#define ASCII_2A KEY_BACKSLASH + SHIFT_MASK // 42 * +#define ASCII_2B KEY_MINUS // 43 + +#define ASCII_2C KEY_COMMA // 44 , +#define ASCII_2D KEY_SLASH // 45 - +#define ASCII_2E KEY_PERIOD // 46 . +#define ASCII_2F KEY_7 + SHIFT_MASK // 47 / +#define ASCII_30 KEY_0 // 48 0 +#define ASCII_31 KEY_1 // 49 1 +#define ASCII_32 KEY_2 // 50 2 +#define ASCII_33 KEY_3 // 51 3 +#define ASCII_34 KEY_4 // 52 4 +#define ASCII_35 KEY_5 // 53 5 +#define ASCII_36 KEY_6 // 54 6 +#define ASCII_37 KEY_7 // 55 7 +#define ASCII_38 KEY_8 // 55 8 +#define ASCII_39 KEY_9 // 57 9 +#define ASCII_3A KEY_PERIOD + SHIFT_MASK // 58 : +#define ASCII_3B KEY_COMMA + SHIFT_MASK // 59 ; +#define ASCII_3C KEY_NON_US_100 // 60 < +#define ASCII_3D KEY_0 + SHIFT_MASK // 61 = +#define ASCII_3E KEY_NON_US_100 + SHIFT_MASK // 62 > +#define ASCII_3F KEY_MINUS + SHIFT_MASK // 63 ? +#define ASCII_40 KEY_2 + ALTGR_MASK // 64 @ +#define ASCII_41 KEY_A + SHIFT_MASK // 65 A +#define ASCII_42 KEY_B + SHIFT_MASK // 66 B +#define ASCII_43 KEY_C + SHIFT_MASK // 67 C +#define ASCII_44 KEY_D + SHIFT_MASK // 68 D +#define ASCII_45 KEY_E + SHIFT_MASK // 69 E +#define ASCII_46 KEY_F + SHIFT_MASK // 70 F +#define ASCII_47 KEY_G + SHIFT_MASK // 71 G +#define ASCII_48 KEY_H + SHIFT_MASK // 72 H +#define ASCII_49 KEY_I + SHIFT_MASK // 73 I +#define ASCII_4A KEY_J + SHIFT_MASK // 74 J +#define ASCII_4B KEY_K + SHIFT_MASK // 75 K +#define ASCII_4C KEY_L + SHIFT_MASK // 76 L +#define ASCII_4D KEY_M + SHIFT_MASK // 77 M +#define ASCII_4E KEY_N + SHIFT_MASK // 78 N +#define ASCII_4F KEY_O + SHIFT_MASK // 79 O +#define ASCII_50 KEY_P + SHIFT_MASK // 80 P +#define ASCII_51 KEY_Q + SHIFT_MASK // 81 Q +#define ASCII_52 KEY_R + SHIFT_MASK // 82 R +#define ASCII_53 KEY_S + SHIFT_MASK // 83 S +#define ASCII_54 KEY_T + SHIFT_MASK // 84 T +#define ASCII_55 KEY_U + SHIFT_MASK // 85 U +#define ASCII_56 KEY_V + SHIFT_MASK // 86 V +#define ASCII_57 KEY_W + SHIFT_MASK // 87 W +#define ASCII_58 KEY_X + SHIFT_MASK // 88 X +#define ASCII_59 KEY_Y + SHIFT_MASK // 89 Y +#define ASCII_5A KEY_Z + SHIFT_MASK // 90 Z +#define ASCII_5B KEY_8 + ALTGR_MASK // 91 [ +#define ASCII_5C KEY_EQUAL // 92 +#define ASCII_5D KEY_9 + ALTGR_MASK // 93 ] +#define ASCII_5E CIRCUMFLEX_BITS + KEY_SPACE // 94 ^ +#define ASCII_5F KEY_SLASH + SHIFT_MASK // 95 _ +#define ASCII_60 GRAVE_ACCENT_BITS + KEY_SPACE // 96 ` +#define ASCII_61 KEY_A // 97 a +#define ASCII_62 KEY_B // 98 b +#define ASCII_63 KEY_C // 99 c +#define ASCII_64 KEY_D // 100 d +#define ASCII_65 KEY_E // 101 e +#define ASCII_66 KEY_F // 102 f +#define ASCII_67 KEY_G // 103 g +#define ASCII_68 KEY_H // 104 h +#define ASCII_69 KEY_I // 105 i +#define ASCII_6A KEY_J // 106 j +#define ASCII_6B KEY_K // 107 k +#define ASCII_6C KEY_L // 108 l +#define ASCII_6D KEY_M // 109 m +#define ASCII_6E KEY_N // 110 n +#define ASCII_6F KEY_O // 111 o +#define ASCII_70 KEY_P // 112 p +#define ASCII_71 KEY_Q // 113 q +#define ASCII_72 KEY_R // 114 r +#define ASCII_73 KEY_S // 115 s +#define ASCII_74 KEY_T // 116 t +#define ASCII_75 KEY_U // 117 u +#define ASCII_76 KEY_V // 118 v +#define ASCII_77 KEY_W // 119 w +#define ASCII_78 KEY_X // 120 x +#define ASCII_79 KEY_Y // 121 y +#define ASCII_7A KEY_Z // 122 z +#define ASCII_7B KEY_7 + ALTGR_MASK // 123 { +#define ASCII_7C KEY_TILDE // 124 | +#define ASCII_7D KEY_0 + ALTGR_MASK // 125 } +#define ASCII_7E TILDE_BITS + KEY_SPACE // 126 ~ +#define ASCII_7F KEY_BACKSPACE // 127 + +#define ISO_8859_1_A0 KEY_SPACE // 160 Nonbreakng Space +#define ISO_8859_1_A1 0 // 161 ¡ Inverted Exclamation +#define ISO_8859_1_A2 0 // 162 ¢ Cent SIGN +#define ISO_8859_1_A3 KEY_3 + ALTGR_MASK // 163 £ Pound Sign +#define ISO_8859_1_A4 KEY_4 + SHIFT_MASK // 164 ¤ Currency Sign +#define ISO_8859_1_A5 0 // 165 ¥ YEN SIGN +#define ISO_8859_1_A6 0 // 166 ¦ BROKEN BAR +#define ISO_8859_1_A7 KEY_TILDE + SHIFT_MASK // 167 § SECTION SIGN +#define ISO_8859_1_A8 DIAERESIS_BITS + KEY_SPACE // 168 ¨ DIAERESIS +#define ISO_8859_1_A9 0 // 169 © COPYRIGHT SIGN +#define ISO_8859_1_AA 0 // 170 ª FEMININE ORDINAL +#define ISO_8859_1_AB KEY_4 // 171 « LEFT DOUBLE ANGLE QUOTE +#define ISO_8859_1_AC 0 // 172 ¬ NOT SIGN +#define ISO_8859_1_AD 0 // 173 SOFT HYPHEN +#define ISO_8859_1_AE 0 // 174 ® REGISTERED SIGN +#define ISO_8859_1_AF 0 // 175 ¯ MACRON +#define ISO_8859_1_B0 0 // 176 ° DEGREE SIGN +#define ISO_8859_1_B1 0 // 177 ± PLUS-MINUS SIGN +#define ISO_8859_1_B2 0 // 178 ² SUPERSCRIPT TWO +#define ISO_8859_1_B3 0 // 179 ³ SUPERSCRIPT THREE +#define ISO_8859_1_B4 ACUTE_ACCENT_BITS + KEY_SPACE // 180 ´ ACUTE ACCENT +#define ISO_8859_1_B5 KEY_M + ALTGR_MASK // 181 µ MICRO SIGN +#define ISO_8859_1_B6 0 // 182 ¶ PILCROW SIGN +#define ISO_8859_1_B7 0 // 183 · MIDDLE DOT +#define ISO_8859_1_B8 0 // 184 ¸ CEDILLA +#define ISO_8859_1_B9 0 // 185 ¹ SUPERSCRIPT ONE +#define ISO_8859_1_BA 0 // 186 º MASCULINE ORDINAL +#define ISO_8859_1_BB 0 // 187 » RIGHT DOUBLE ANGLE QUOTE +#define ISO_8859_1_BC 0 // 188 ¼ FRACTION ONE QUARTER +#define ISO_8859_1_BD KEY_TILDE // 189 ½ FRACTION ONE HALF +#define ISO_8859_1_BE 0 // 190 ¾ FRACTION THREE QUARTERS +#define ISO_8859_1_BF 0 // 191 ¿ INVERTED QUESTION MARK +#define ISO_8859_1_C0 GRAVE_ACCENT_BITS + KEY_A + SHIFT_MASK // 192 À A GRAVE +#define ISO_8859_1_C1 ACUTE_ACCENT_BITS + KEY_A + SHIFT_MASK // 193 à A ACUTE +#define ISO_8859_1_C2 CIRCUMFLEX_BITS + KEY_A + SHIFT_MASK // 194 Â A CIRCUMFLEX +#define ISO_8859_1_C3 TILDE_BITS + KEY_A + SHIFT_MASK // 195 Ã A TILDE +#define ISO_8859_1_C4 DIAERESIS_BITS + KEY_A + SHIFT_MASK // 196 Ä A DIAERESIS +#define ISO_8859_1_C5 KEY_LEFT_BRACE + SHIFT_MASK // 197 Å A RING ABOVE +#define ISO_8859_1_C6 KEY_QUOTE + SHIFT_MASK // 198 Æ AE +#define ISO_8859_1_C7 0 // 199 Ç C CEDILLA +#define ISO_8859_1_C8 GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK // 200 È E GRAVE +#define ISO_8859_1_C9 ACUTE_ACCENT_BITS + KEY_E + SHIFT_MASK // 201 É E ACUTE +#define ISO_8859_1_CA CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK // 202 Ê E CIRCUMFLEX +#define ISO_8859_1_CB DIAERESIS_BITS + KEY_E + SHIFT_MASK // 203 Ë E DIAERESIS +#define ISO_8859_1_CC GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK // 204 Ì I GRAVE +#define ISO_8859_1_CD ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK // 205 à I ACUTE +#define ISO_8859_1_CE CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK // 206 Î I CIRCUMFLEX +#define ISO_8859_1_CF DIAERESIS_BITS + KEY_I + SHIFT_MASK // 207 à I DIAERESIS +#define ISO_8859_1_D0 KEY_D + ALTGR_MASK + SHIFT_MASK // 208 à ETH +#define ISO_8859_1_D1 TILDE_BITS + KEY_N + SHIFT_MASK // 209 Ñ N TILDE +#define ISO_8859_1_D2 GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK // 210 Ò O GRAVE +#define ISO_8859_1_D3 ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK // 211 Ó O ACUTE +#define ISO_8859_1_D4 CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK // 212 Ô O CIRCUMFLEX +#define ISO_8859_1_D5 TILDE_BITS + KEY_O + SHIFT_MASK // 213 Õ O TILDE +#define ISO_8859_1_D6 DIAERESIS_BITS + KEY_O + SHIFT_MASK // 214 Ö O DIAERESIS +#define ISO_8859_1_D7 0 // 215 × MULTIPLICATION +#define ISO_8859_1_D8 KEY_SEMICOLON + SHIFT_MASK // 216 Ø O STROKE +#define ISO_8859_1_D9 GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK // 217 Ù U GRAVE +#define ISO_8859_1_DA ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK // 218 Ú U ACUTE +#define ISO_8859_1_DB CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK // 219 Û U CIRCUMFLEX +#define ISO_8859_1_DC DIAERESIS_BITS + KEY_U + SHIFT_MASK // 220 Ü U DIAERESIS +#define ISO_8859_1_DD ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK // 221 à Y ACUTE +#define ISO_8859_1_DE KEY_T + ALTGR_MASK + SHIFT_MASK // 222 Þ THORN +#define ISO_8859_1_DF KEY_S + ALTGR_MASK // 223 ß SHARP S +#define ISO_8859_1_E0 GRAVE_ACCENT_BITS + KEY_A // 224 à a GRAVE +#define ISO_8859_1_E1 ACUTE_ACCENT_BITS + KEY_A // 225 á a ACUTE +#define ISO_8859_1_E2 CIRCUMFLEX_BITS + KEY_A // 226 â a CIRCUMFLEX +#define ISO_8859_1_E3 TILDE_BITS + KEY_A // 227 ã a TILDE +#define ISO_8859_1_E4 DIAERESIS_BITS + KEY_A // 228 ä a DIAERESIS +#define ISO_8859_1_E5 KEY_LEFT_BRACE // 229 å a RING ABOVE +#define ISO_8859_1_E6 KEY_QUOTE // 230 æ ae +#define ISO_8859_1_E7 0 // 231 ç c CEDILLA +#define ISO_8859_1_E8 GRAVE_ACCENT_BITS + KEY_E // 232 è e GRAVE +#define ISO_8859_1_E9 ACUTE_ACCENT_BITS + KEY_E // 233 é e ACUTE +#define ISO_8859_1_EA CIRCUMFLEX_BITS + KEY_E // 234 ê e CIRCUMFLEX +#define ISO_8859_1_EB DIAERESIS_BITS + KEY_E // 235 ë e DIAERESIS +#define ISO_8859_1_EC GRAVE_ACCENT_BITS + KEY_I // 236 ì i GRAVE +#define ISO_8859_1_ED ACUTE_ACCENT_BITS + KEY_I // 237 à i ACUTE +#define ISO_8859_1_EE CIRCUMFLEX_BITS + KEY_I // 238 î i CIRCUMFLEX +#define ISO_8859_1_EF DIAERESIS_BITS + KEY_I // 239 ï i DIAERESIS +#define ISO_8859_1_F0 KEY_D + ALTGR_MASK // 240 ð ETH +#define ISO_8859_1_F1 TILDE_BITS + KEY_N // 241 ñ n TILDE +#define ISO_8859_1_F2 GRAVE_ACCENT_BITS + KEY_O // 242 ò o GRAVE +#define ISO_8859_1_F3 ACUTE_ACCENT_BITS + KEY_O // 243 ó o ACUTE +#define ISO_8859_1_F4 CIRCUMFLEX_BITS + KEY_O // 244 ô o CIRCUMFLEX +#define ISO_8859_1_F5 TILDE_BITS + KEY_O // 245 õ o TILDE +#define ISO_8859_1_F6 DIAERESIS_BITS + KEY_O // 246 ö o DIAERESIS +#define ISO_8859_1_F7 0 // 247 ÷ DIVISION +#define ISO_8859_1_F8 KEY_SEMICOLON // 248 ø o STROKE +#define ISO_8859_1_F9 GRAVE_ACCENT_BITS + KEY_U // 249 ù u GRAVE +#define ISO_8859_1_FA ACUTE_ACCENT_BITS + KEY_U // 250 ú u ACUTE +#define ISO_8859_1_FB CIRCUMFLEX_BITS + KEY_U // 251 û u CIRCUMFLEX +#define ISO_8859_1_FC DIAERESIS_BITS + KEY_U // 252 ü u DIAERESIS +#define ISO_8859_1_FD ACUTE_ACCENT_BITS + KEY_Y // 253 ý y ACUTE +#define ISO_8859_1_FE KEY_T + ALTGR_MASK // 254 þ THORN +#define ISO_8859_1_FF DIAERESIS_BITS + KEY_Y // 255 ÿ y DIAERESIS +#define UNICODE_20AC KEY_E + ALTGR_MASK // € Euro Sign +// not yet implemented +#define UNICODE_EXTRA00 0x20AC +#define KEYCODE_EXTRA00 KEY_E + ALTGR_MASK // 20AC € Euro Sign + +#endif // LAYOUT_NORWEGIAN + + + + + + +#ifdef LAYOUT_SWEDISH + +#define SHIFT_MASK 0x0040 +#define ALTGR_MASK 0x0080 +#define DEADKEYS_MASK 0x0700 +#define CIRCUMFLEX_BITS 0x0100 +#define ACUTE_ACCENT_BITS 0x0200 +#define GRAVE_ACCENT_BITS 0x0300 +#define TILDE_BITS 0x0400 +#define DIAERESIS_BITS 0x0500 +#define KEYCODE_TYPE uint16_t +#define DEADKEY_CIRCUMFLEX KEY_RIGHT_BRACE + SHIFT_MASK +#define DEADKEY_ACUTE_ACCENT KEY_EQUAL +#define DEADKEY_GRAVE_ACCENT KEY_EQUAL + SHIFT_MASK +#define DEADKEY_TILDE KEY_RIGHT_BRACE + ALTGR_MASK +#define DEADKEY_DIAERESIS KEY_RIGHT_BRACE +#define KEY_NON_US_100 63 + +#define ASCII_20 KEY_SPACE // 32 +#define ASCII_21 KEY_1 + SHIFT_MASK // 33 ! +#define ASCII_22 KEY_2 + SHIFT_MASK // 34 " +#define ASCII_23 KEY_3 + SHIFT_MASK // 35 # +#define ASCII_24 KEY_4 + ALTGR_MASK // 36 $ +#define ASCII_25 KEY_5 + SHIFT_MASK // 37 % +#define ASCII_26 KEY_6 + SHIFT_MASK // 38 & +#define ASCII_27 KEY_BACKSLASH // 39 ' +#define ASCII_28 KEY_8 + SHIFT_MASK // 40 ( +#define ASCII_29 KEY_9 + SHIFT_MASK // 41 ) +#define ASCII_2A KEY_BACKSLASH + SHIFT_MASK // 42 * +#define ASCII_2B KEY_MINUS // 43 + +#define ASCII_2C KEY_COMMA // 44 , +#define ASCII_2D KEY_SLASH // 45 - +#define ASCII_2E KEY_PERIOD // 46 . +#define ASCII_2F KEY_7 + SHIFT_MASK // 47 / +#define ASCII_30 KEY_0 // 48 0 +#define ASCII_31 KEY_1 // 49 1 +#define ASCII_32 KEY_2 // 50 2 +#define ASCII_33 KEY_3 // 51 3 +#define ASCII_34 KEY_4 // 52 4 +#define ASCII_35 KEY_5 // 53 5 +#define ASCII_36 KEY_6 // 54 6 +#define ASCII_37 KEY_7 // 55 7 +#define ASCII_38 KEY_8 // 55 8 +#define ASCII_39 KEY_9 // 57 9 +#define ASCII_3A KEY_PERIOD + SHIFT_MASK // 58 : +#define ASCII_3B KEY_COMMA + SHIFT_MASK // 59 ; +#define ASCII_3C KEY_NON_US_100 // 60 < +#define ASCII_3D KEY_0 + SHIFT_MASK // 61 = +#define ASCII_3E KEY_NON_US_100 + SHIFT_MASK // 62 > +#define ASCII_3F KEY_MINUS + SHIFT_MASK // 63 ? +#define ASCII_40 KEY_2 + ALTGR_MASK // 64 @ +#define ASCII_41 KEY_A + SHIFT_MASK // 65 A +#define ASCII_42 KEY_B + SHIFT_MASK // 66 B +#define ASCII_43 KEY_C + SHIFT_MASK // 67 C +#define ASCII_44 KEY_D + SHIFT_MASK // 68 D +#define ASCII_45 KEY_E + SHIFT_MASK // 69 E +#define ASCII_46 KEY_F + SHIFT_MASK // 70 F +#define ASCII_47 KEY_G + SHIFT_MASK // 71 G +#define ASCII_48 KEY_H + SHIFT_MASK // 72 H +#define ASCII_49 KEY_I + SHIFT_MASK // 73 I +#define ASCII_4A KEY_J + SHIFT_MASK // 74 J +#define ASCII_4B KEY_K + SHIFT_MASK // 75 K +#define ASCII_4C KEY_L + SHIFT_MASK // 76 L +#define ASCII_4D KEY_M + SHIFT_MASK // 77 M +#define ASCII_4E KEY_N + SHIFT_MASK // 78 N +#define ASCII_4F KEY_O + SHIFT_MASK // 79 O +#define ASCII_50 KEY_P + SHIFT_MASK // 80 P +#define ASCII_51 KEY_Q + SHIFT_MASK // 81 Q +#define ASCII_52 KEY_R + SHIFT_MASK // 82 R +#define ASCII_53 KEY_S + SHIFT_MASK // 83 S +#define ASCII_54 KEY_T + SHIFT_MASK // 84 T +#define ASCII_55 KEY_U + SHIFT_MASK // 85 U +#define ASCII_56 KEY_V + SHIFT_MASK // 86 V +#define ASCII_57 KEY_W + SHIFT_MASK // 87 W +#define ASCII_58 KEY_X + SHIFT_MASK // 88 X +#define ASCII_59 KEY_Y + SHIFT_MASK // 89 Y +#define ASCII_5A KEY_Z + SHIFT_MASK // 90 Z +#define ASCII_5B KEY_8 + ALTGR_MASK // 91 [ +#define ASCII_5C KEY_MINUS + ALTGR_MASK // 92 +#define ASCII_5D KEY_9 + ALTGR_MASK // 93 ] +#define ASCII_5E CIRCUMFLEX_BITS + KEY_SPACE // 94 ^ +#define ASCII_5F KEY_SLASH + SHIFT_MASK // 95 _ +#define ASCII_60 GRAVE_ACCENT_BITS + KEY_SPACE // 96 ` +#define ASCII_61 KEY_A // 97 a +#define ASCII_62 KEY_B // 98 b +#define ASCII_63 KEY_C // 99 c +#define ASCII_64 KEY_D // 100 d +#define ASCII_65 KEY_E // 101 e +#define ASCII_66 KEY_F // 102 f +#define ASCII_67 KEY_G // 103 g +#define ASCII_68 KEY_H // 104 h +#define ASCII_69 KEY_I // 105 i +#define ASCII_6A KEY_J // 106 j +#define ASCII_6B KEY_K // 107 k +#define ASCII_6C KEY_L // 108 l +#define ASCII_6D KEY_M // 109 m +#define ASCII_6E KEY_N // 110 n +#define ASCII_6F KEY_O // 111 o +#define ASCII_70 KEY_P // 112 p +#define ASCII_71 KEY_Q // 113 q +#define ASCII_72 KEY_R // 114 r +#define ASCII_73 KEY_S // 115 s +#define ASCII_74 KEY_T // 116 t +#define ASCII_75 KEY_U // 117 u +#define ASCII_76 KEY_V // 118 v +#define ASCII_77 KEY_W // 119 w +#define ASCII_78 KEY_X // 120 x +#define ASCII_79 KEY_Y // 121 y +#define ASCII_7A KEY_Z // 122 z +#define ASCII_7B KEY_7 + ALTGR_MASK // 123 { +#define ASCII_7C KEY_NON_US_100 + ALTGR_MASK // 124 | +#define ASCII_7D KEY_0 + ALTGR_MASK // 125 } +#define ASCII_7E TILDE_BITS + KEY_SPACE // 126 ~ +#define ASCII_7F KEY_BACKSPACE // 127 + +#define ISO_8859_1_A0 KEY_SPACE // 160 Nonbreakng Space +#define ISO_8859_1_A1 0 // 161 ¡ Inverted Exclamation +#define ISO_8859_1_A2 0 // 162 ¢ Cent SIGN +#define ISO_8859_1_A3 KEY_3 + ALTGR_MASK // 163 £ Pound Sign +#define ISO_8859_1_A4 KEY_4 + SHIFT_MASK // 164 ¤ Currency Sign +#define ISO_8859_1_A5 0 // 165 ¥ YEN SIGN +#define ISO_8859_1_A6 0 // 166 ¦ BROKEN BAR +#define ISO_8859_1_A7 KEY_TILDE // 167 § SECTION SIGN +#define ISO_8859_1_A8 DIAERESIS_BITS + KEY_SPACE // 168 ¨ DIAERESIS +#define ISO_8859_1_A9 0 // 169 © COPYRIGHT SIGN +#define ISO_8859_1_AA 0 // 170 ª FEMININE ORDINAL +#define ISO_8859_1_AB KEY_4 // 171 « LEFT DOUBLE ANGLE QUOTE +#define ISO_8859_1_AC 0 // 172 ¬ NOT SIGN +#define ISO_8859_1_AD 0 // 173 SOFT HYPHEN +#define ISO_8859_1_AE 0 // 174 ® REGISTERED SIGN +#define ISO_8859_1_AF 0 // 175 ¯ MACRON +#define ISO_8859_1_B0 0 // 176 ° DEGREE SIGN +#define ISO_8859_1_B1 0 // 177 ± PLUS-MINUS SIGN +#define ISO_8859_1_B2 0 // 178 ² SUPERSCRIPT TWO +#define ISO_8859_1_B3 0 // 179 ³ SUPERSCRIPT THREE +#define ISO_8859_1_B4 ACUTE_ACCENT_BITS + KEY_SPACE // 180 ´ ACUTE ACCENT +#define ISO_8859_1_B5 KEY_M + ALTGR_MASK // 181 µ MICRO SIGN +#define ISO_8859_1_B6 0 // 182 ¶ PILCROW SIGN +#define ISO_8859_1_B7 0 // 183 · MIDDLE DOT +#define ISO_8859_1_B8 0 // 184 ¸ CEDILLA +#define ISO_8859_1_B9 0 // 185 ¹ SUPERSCRIPT ONE +#define ISO_8859_1_BA 0 // 186 º MASCULINE ORDINAL +#define ISO_8859_1_BB 0 // 187 » RIGHT DOUBLE ANGLE QUOTE +#define ISO_8859_1_BC 0 // 188 ¼ FRACTION ONE QUARTER +#define ISO_8859_1_BD KEY_TILDE + SHIFT_MASK // 189 ½ FRACTION ONE HALF +#define ISO_8859_1_BE 0 // 190 ¾ FRACTION THREE QUARTERS +#define ISO_8859_1_BF 0 // 191 ¿ INVERTED QUESTION MARK +#define ISO_8859_1_C0 GRAVE_ACCENT_BITS + KEY_A + SHIFT_MASK // 192 À A GRAVE +#define ISO_8859_1_C1 ACUTE_ACCENT_BITS + KEY_A + SHIFT_MASK // 193 à A ACUTE +#define ISO_8859_1_C2 CIRCUMFLEX_BITS + KEY_A + SHIFT_MASK // 194 Â A CIRCUMFLEX +#define ISO_8859_1_C3 TILDE_BITS + KEY_A + SHIFT_MASK // 195 Ã A TILDE +#define ISO_8859_1_C4 KEY_QUOTE + SHIFT_MASK // 196 Ä A DIAERESIS +#define ISO_8859_1_C5 KEY_LEFT_BRACE + SHIFT_MASK // 197 Å A RING ABOVE +#define ISO_8859_1_C6 0 // 198 Æ AE +#define ISO_8859_1_C7 0 // 199 Ç C CEDILLA +#define ISO_8859_1_C8 GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK // 200 È E GRAVE +#define ISO_8859_1_C9 ACUTE_ACCENT_BITS + KEY_E + SHIFT_MASK // 201 É E ACUTE +#define ISO_8859_1_CA CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK // 202 Ê E CIRCUMFLEX +#define ISO_8859_1_CB DIAERESIS_BITS + KEY_E + SHIFT_MASK // 203 Ë E DIAERESIS +#define ISO_8859_1_CC GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK // 204 Ì I GRAVE +#define ISO_8859_1_CD ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK // 205 à I ACUTE +#define ISO_8859_1_CE CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK // 206 Î I CIRCUMFLEX +#define ISO_8859_1_CF DIAERESIS_BITS + KEY_I + SHIFT_MASK // 207 à I DIAERESIS +#define ISO_8859_1_D0 KEY_D + ALTGR_MASK + SHIFT_MASK // 208 à ETH +#define ISO_8859_1_D1 TILDE_BITS + KEY_N + SHIFT_MASK // 209 Ñ N TILDE +#define ISO_8859_1_D2 GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK // 210 Ò O GRAVE +#define ISO_8859_1_D3 ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK // 211 Ó O ACUTE +#define ISO_8859_1_D4 CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK // 212 Ô O CIRCUMFLEX +#define ISO_8859_1_D5 TILDE_BITS + KEY_O + SHIFT_MASK // 213 Õ O TILDE +#define ISO_8859_1_D6 KEY_SEMICOLON + SHIFT_MASK // 214 Ö O DIAERESIS +#define ISO_8859_1_D7 0 // 215 × MULTIPLICATION +#define ISO_8859_1_D8 0 // 216 Ø O STROKE +#define ISO_8859_1_D9 GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK // 217 Ù U GRAVE +#define ISO_8859_1_DA ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK // 218 Ú U ACUTE +#define ISO_8859_1_DB CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK // 219 Û U CIRCUMFLEX +#define ISO_8859_1_DC DIAERESIS_BITS + KEY_U + SHIFT_MASK // 220 Ü U DIAERESIS +#define ISO_8859_1_DD ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK // 221 à Y ACUTE +#define ISO_8859_1_DE KEY_T + ALTGR_MASK + SHIFT_MASK // 222 Þ THORN +#define ISO_8859_1_DF KEY_S + ALTGR_MASK // 223 ß SHARP S +#define ISO_8859_1_E0 GRAVE_ACCENT_BITS + KEY_A // 224 à a GRAVE +#define ISO_8859_1_E1 ACUTE_ACCENT_BITS + KEY_A // 225 á a ACUTE +#define ISO_8859_1_E2 CIRCUMFLEX_BITS + KEY_A // 226 â a CIRCUMFLEX +#define ISO_8859_1_E3 TILDE_BITS + KEY_A // 227 ã a TILDE +#define ISO_8859_1_E4 KEY_QUOTE // 228 ä a DIAERESIS +#define ISO_8859_1_E5 KEY_LEFT_BRACE // 229 å a RING ABOVE +#define ISO_8859_1_E6 0 // 230 æ ae +#define ISO_8859_1_E7 0 // 231 ç c CEDILLA +#define ISO_8859_1_E8 GRAVE_ACCENT_BITS + KEY_E // 232 è e GRAVE +#define ISO_8859_1_E9 ACUTE_ACCENT_BITS + KEY_E // 233 é e ACUTE +#define ISO_8859_1_EA CIRCUMFLEX_BITS + KEY_E // 234 ê e CIRCUMFLEX +#define ISO_8859_1_EB DIAERESIS_BITS + KEY_E // 235 ë e DIAERESIS +#define ISO_8859_1_EC GRAVE_ACCENT_BITS + KEY_I // 236 ì i GRAVE +#define ISO_8859_1_ED ACUTE_ACCENT_BITS + KEY_I // 237 à i ACUTE +#define ISO_8859_1_EE CIRCUMFLEX_BITS + KEY_I // 238 î i CIRCUMFLEX +#define ISO_8859_1_EF DIAERESIS_BITS + KEY_I // 239 ï i DIAERESIS +#define ISO_8859_1_F0 KEY_D + ALTGR_MASK // 240 ð ETH +#define ISO_8859_1_F1 TILDE_BITS + KEY_N // 241 ñ n TILDE +#define ISO_8859_1_F2 GRAVE_ACCENT_BITS + KEY_O // 242 ò o GRAVE +#define ISO_8859_1_F3 ACUTE_ACCENT_BITS + KEY_O // 243 ó o ACUTE +#define ISO_8859_1_F4 CIRCUMFLEX_BITS + KEY_O // 244 ô o CIRCUMFLEX +#define ISO_8859_1_F5 TILDE_BITS + KEY_O // 245 õ o TILDE +#define ISO_8859_1_F6 KEY_SEMICOLON // 246 ö o DIAERESIS +#define ISO_8859_1_F7 0 // 247 ÷ DIVISION +#define ISO_8859_1_F8 0 // 248 ø o STROKE +#define ISO_8859_1_F9 GRAVE_ACCENT_BITS + KEY_U // 249 ù u GRAVE +#define ISO_8859_1_FA ACUTE_ACCENT_BITS + KEY_U // 250 ú u ACUTE +#define ISO_8859_1_FB CIRCUMFLEX_BITS + KEY_U // 251 û u CIRCUMFLEX +#define ISO_8859_1_FC DIAERESIS_BITS + KEY_U // 252 ü u DIAERESIS +#define ISO_8859_1_FD ACUTE_ACCENT_BITS + KEY_Y // 253 ý y ACUTE +#define ISO_8859_1_FE KEY_T + ALTGR_MASK // 254 þ THORN +#define ISO_8859_1_FF DIAERESIS_BITS + KEY_Y // 255 ÿ y DIAERESIS +#define UNICODE_20AC KEY_E + ALTGR_MASK // € Euro Sign +// not yet implemented +#define UNICODE_EXTRA00 0x20AC +#define KEYCODE_EXTRA00 KEY_E + ALTGR_MASK // 20AC € Euro Sign + +#endif // LAYOUT_SWEDISH + + + + + + +#ifdef LAYOUT_SPANISH + +#define SHIFT_MASK 0x0040 +#define ALTGR_MASK 0x0080 +#define DEADKEYS_MASK 0x0700 +#define CIRCUMFLEX_BITS 0x0100 +#define ACUTE_ACCENT_BITS 0x0200 +#define GRAVE_ACCENT_BITS 0x0300 +#define TILDE_BITS 0x0400 +#define DIAERESIS_BITS 0x0500 +#define KEYCODE_TYPE uint16_t +#define DEADKEY_CIRCUMFLEX KEY_LEFT_BRACE + SHIFT_MASK +#define DEADKEY_ACUTE_ACCENT KEY_QUOTE +#define DEADKEY_GRAVE_ACCENT KEY_LEFT_BRACE +#define DEADKEY_TILDE KEY_4 + ALTGR_MASK +#define DEADKEY_DIAERESIS KEY_QUOTE + SHIFT_MASK +#define KEY_NON_US_100 63 + +#define ASCII_20 KEY_SPACE // 32 +#define ASCII_21 KEY_1 + SHIFT_MASK // 33 ! +#define ASCII_22 KEY_2 + SHIFT_MASK // 34 " +#define ASCII_23 KEY_3 + ALTGR_MASK // 35 # +#define ASCII_24 KEY_4 + SHIFT_MASK // 36 $ +#define ASCII_25 KEY_5 + SHIFT_MASK // 37 % +#define ASCII_26 KEY_6 + SHIFT_MASK // 38 & +#define ASCII_27 KEY_MINUS // 39 ' +#define ASCII_28 KEY_8 + SHIFT_MASK // 40 ( +#define ASCII_29 KEY_9 + SHIFT_MASK // 41 ) +#define ASCII_2A KEY_RIGHT_BRACE + SHIFT_MASK // 42 * +#define ASCII_2B KEY_RIGHT_BRACE // 43 + +#define ASCII_2C KEY_COMMA // 44 , +#define ASCII_2D KEY_SLASH // 45 - +#define ASCII_2E KEY_PERIOD // 46 . +#define ASCII_2F KEY_7 + SHIFT_MASK // 47 / +#define ASCII_30 KEY_0 // 48 0 +#define ASCII_31 KEY_1 // 49 1 +#define ASCII_32 KEY_2 // 50 2 +#define ASCII_33 KEY_3 // 51 3 +#define ASCII_34 KEY_4 // 52 4 +#define ASCII_35 KEY_5 // 53 5 +#define ASCII_36 KEY_6 // 54 6 +#define ASCII_37 KEY_7 // 55 7 +#define ASCII_38 KEY_8 // 55 8 +#define ASCII_39 KEY_9 // 57 9 +#define ASCII_3A KEY_PERIOD + SHIFT_MASK // 58 : +#define ASCII_3B KEY_COMMA + SHIFT_MASK // 59 ; +#define ASCII_3C KEY_NON_US_100 // 60 < +#define ASCII_3D KEY_0 + SHIFT_MASK // 61 = +#define ASCII_3E KEY_NON_US_100 + SHIFT_MASK // 62 > +#define ASCII_3F KEY_MINUS + SHIFT_MASK // 63 ? +#define ASCII_40 KEY_2 + ALTGR_MASK // 64 @ +#define ASCII_41 KEY_A + SHIFT_MASK // 65 A +#define ASCII_42 KEY_B + SHIFT_MASK // 66 B +#define ASCII_43 KEY_C + SHIFT_MASK // 67 C +#define ASCII_44 KEY_D + SHIFT_MASK // 68 D +#define ASCII_45 KEY_E + SHIFT_MASK // 69 E +#define ASCII_46 KEY_F + SHIFT_MASK // 70 F +#define ASCII_47 KEY_G + SHIFT_MASK // 71 G +#define ASCII_48 KEY_H + SHIFT_MASK // 72 H +#define ASCII_49 KEY_I + SHIFT_MASK // 73 I +#define ASCII_4A KEY_J + SHIFT_MASK // 74 J +#define ASCII_4B KEY_K + SHIFT_MASK // 75 K +#define ASCII_4C KEY_L + SHIFT_MASK // 76 L +#define ASCII_4D KEY_M + SHIFT_MASK // 77 M +#define ASCII_4E KEY_N + SHIFT_MASK // 78 N +#define ASCII_4F KEY_O + SHIFT_MASK // 79 O +#define ASCII_50 KEY_P + SHIFT_MASK // 80 P +#define ASCII_51 KEY_Q + SHIFT_MASK // 81 Q +#define ASCII_52 KEY_R + SHIFT_MASK // 82 R +#define ASCII_53 KEY_S + SHIFT_MASK // 83 S +#define ASCII_54 KEY_T + SHIFT_MASK // 84 T +#define ASCII_55 KEY_U + SHIFT_MASK // 85 U +#define ASCII_56 KEY_V + SHIFT_MASK // 86 V +#define ASCII_57 KEY_W + SHIFT_MASK // 87 W +#define ASCII_58 KEY_X + SHIFT_MASK // 88 X +#define ASCII_59 KEY_Y + SHIFT_MASK // 89 Y +#define ASCII_5A KEY_Z + SHIFT_MASK // 90 Z +#define ASCII_5B KEY_LEFT_BRACE + ALTGR_MASK // 91 [ +#define ASCII_5C KEY_TILDE + ALTGR_MASK // 92 +#define ASCII_5D KEY_RIGHT_BRACE + ALTGR_MASK // 93 ] +#define ASCII_5E CIRCUMFLEX_BITS + KEY_SPACE // 94 ^ +#define ASCII_5F KEY_SLASH + SHIFT_MASK // 95 _ +#define ASCII_60 GRAVE_ACCENT_BITS + KEY_SPACE // 96 ` +#define ASCII_61 KEY_A // 97 a +#define ASCII_62 KEY_B // 98 b +#define ASCII_63 KEY_C // 99 c +#define ASCII_64 KEY_D // 100 d +#define ASCII_65 KEY_E // 101 e +#define ASCII_66 KEY_F // 102 f +#define ASCII_67 KEY_G // 103 g +#define ASCII_68 KEY_H // 104 h +#define ASCII_69 KEY_I // 105 i +#define ASCII_6A KEY_J // 106 j +#define ASCII_6B KEY_K // 107 k +#define ASCII_6C KEY_L // 108 l +#define ASCII_6D KEY_M // 109 m +#define ASCII_6E KEY_N // 110 n +#define ASCII_6F KEY_O // 111 o +#define ASCII_70 KEY_P // 112 p +#define ASCII_71 KEY_Q // 113 q +#define ASCII_72 KEY_R // 114 r +#define ASCII_73 KEY_S // 115 s +#define ASCII_74 KEY_T // 116 t +#define ASCII_75 KEY_U // 117 u +#define ASCII_76 KEY_V // 118 v +#define ASCII_77 KEY_W // 119 w +#define ASCII_78 KEY_X // 120 x +#define ASCII_79 KEY_Y // 121 y +#define ASCII_7A KEY_Z // 122 z +#define ASCII_7B KEY_QUOTE + ALTGR_MASK // 123 { +#define ASCII_7C KEY_1 + ALTGR_MASK // 124 | +#define ASCII_7D KEY_BACKSLASH + ALTGR_MASK // 125 } +#define ASCII_7E TILDE_BITS + KEY_SPACE // 126 ~ +#define ASCII_7F KEY_BACKSPACE // 127 + +#define ISO_8859_1_A0 KEY_SPACE // 160 Nonbreakng Space +#define ISO_8859_1_A1 KEY_EQUAL // 161 ¡ Inverted Exclamation +#define ISO_8859_1_A2 0 // 162 ¢ Cent SIGN +#define ISO_8859_1_A3 0 // 163 £ Pound Sign +#define ISO_8859_1_A4 0 // 164 ¤ Currency Sign +#define ISO_8859_1_A5 0 // 165 ¥ YEN SIGN +#define ISO_8859_1_A6 0 // 166 ¦ BROKEN BAR +#define ISO_8859_1_A7 0 // 167 § SECTION SIGN +#define ISO_8859_1_A8 DIAERESIS_BITS + KEY_SPACE // 168 ¨ DIAERESIS +#define ISO_8859_1_A9 0 // 169 © COPYRIGHT SIGN +#define ISO_8859_1_AA KEY_TILDE + SHIFT_MASK // 170 ª FEMININE ORDINAL +#define ISO_8859_1_AB 0 // 171 « LEFT DOUBLE ANGLE QUOTE +#define ISO_8859_1_AC KEY_6 + ALTGR_MASK // 172 ¬ NOT SIGN +#define ISO_8859_1_AD 0 // 173 SOFT HYPHEN +#define ISO_8859_1_AE 0 // 174 ® REGISTERED SIGN +#define ISO_8859_1_AF 0 // 175 ¯ MACRON +#define ISO_8859_1_B0 0 // 176 ° DEGREE SIGN +#define ISO_8859_1_B1 0 // 177 ± PLUS-MINUS SIGN +#define ISO_8859_1_B2 0 // 178 ² SUPERSCRIPT TWO +#define ISO_8859_1_B3 0 // 179 ³ SUPERSCRIPT THREE +#define ISO_8859_1_B4 ACUTE_ACCENT_BITS + KEY_SPACE // 180 ´ ACUTE ACCENT +#define ISO_8859_1_B5 0 // 181 µ MICRO SIGN +#define ISO_8859_1_B6 0 // 182 ¶ PILCROW SIGN +#define ISO_8859_1_B7 KEY_3 + SHIFT_MASK // 183 · MIDDLE DOT +#define ISO_8859_1_B8 0 // 184 ¸ CEDILLA +#define ISO_8859_1_B9 0 // 185 ¹ SUPERSCRIPT ONE +#define ISO_8859_1_BA KEY_TILDE // 186 º MASCULINE ORDINAL +#define ISO_8859_1_BB 0 // 187 » RIGHT DOUBLE ANGLE QUOTE +#define ISO_8859_1_BC 0 // 188 ¼ FRACTION ONE QUARTER +#define ISO_8859_1_BD 0 // 189 ½ FRACTION ONE HALF +#define ISO_8859_1_BE 0 // 190 ¾ FRACTION THREE QUARTERS +#define ISO_8859_1_BF KEY_EQUAL // 191 ¿ INVERTED QUESTION MARK +#define ISO_8859_1_C0 GRAVE_ACCENT_BITS + KEY_A + SHIFT_MASK // 192 À A GRAVE +#define ISO_8859_1_C1 ACUTE_ACCENT_BITS + KEY_A + SHIFT_MASK // 193 à A ACUTE +#define ISO_8859_1_C2 CIRCUMFLEX_BITS + KEY_A + SHIFT_MASK // 194 Â A CIRCUMFLEX +#define ISO_8859_1_C3 TILDE_BITS + KEY_A + SHIFT_MASK // 195 Ã A TILDE +#define ISO_8859_1_C4 DIAERESIS_BITS + KEY_A + SHIFT_MASK // 196 Ä A DIAERESIS +#define ISO_8859_1_C5 0 // 197 Å A RING ABOVE +#define ISO_8859_1_C6 0 // 198 Æ AE +#define ISO_8859_1_C7 KEY_BACKSLASH + SHIFT_MASK // 199 Ç C CEDILLA +#define ISO_8859_1_C8 GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK // 200 È E GRAVE +#define ISO_8859_1_C9 ACUTE_ACCENT_BITS + KEY_E + SHIFT_MASK // 201 É E ACUTE +#define ISO_8859_1_CA CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK // 202 Ê E CIRCUMFLEX +#define ISO_8859_1_CB DIAERESIS_BITS + KEY_E + SHIFT_MASK // 203 Ë E DIAERESIS +#define ISO_8859_1_CC GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK // 204 Ì I GRAVE +#define ISO_8859_1_CD ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK // 205 à I ACUTE +#define ISO_8859_1_CE CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK // 206 Î I CIRCUMFLEX +#define ISO_8859_1_CF DIAERESIS_BITS + KEY_I + SHIFT_MASK // 207 à I DIAERESIS +#define ISO_8859_1_D0 0 // 208 à ETH +#define ISO_8859_1_D1 KEY_SEMICOLON + SHIFT_MASK // 209 Ñ N TILDE +#define ISO_8859_1_D2 GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK // 210 Ò O GRAVE +#define ISO_8859_1_D3 ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK // 211 Ó O ACUTE +#define ISO_8859_1_D4 CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK // 212 Ô O CIRCUMFLEX +#define ISO_8859_1_D5 TILDE_BITS + KEY_O + SHIFT_MASK // 213 Õ O TILDE +#define ISO_8859_1_D6 DIAERESIS_BITS + KEY_O + SHIFT_MASK // 214 Ö O DIAERESIS +#define ISO_8859_1_D7 0 // 215 × MULTIPLICATION +#define ISO_8859_1_D8 0 // 216 Ø O STROKE +#define ISO_8859_1_D9 GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK // 217 Ù U GRAVE +#define ISO_8859_1_DA ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK // 218 Ú U ACUTE +#define ISO_8859_1_DB CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK // 219 Û U CIRCUMFLEX +#define ISO_8859_1_DC DIAERESIS_BITS + KEY_U + SHIFT_MASK // 220 Ü U DIAERESIS +#define ISO_8859_1_DD ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK // 221 à Y ACUTE +#define ISO_8859_1_DE 0 // 222 Þ THORN +#define ISO_8859_1_DF 0 // 223 ß SHARP S +#define ISO_8859_1_E0 GRAVE_ACCENT_BITS + KEY_A // 224 à a GRAVE +#define ISO_8859_1_E1 ACUTE_ACCENT_BITS + KEY_A // 225 á a ACUTE +#define ISO_8859_1_E2 CIRCUMFLEX_BITS + KEY_A // 226 â a CIRCUMFLEX +#define ISO_8859_1_E3 TILDE_BITS + KEY_A // 227 ã a TILDE +#define ISO_8859_1_E4 DIAERESIS_BITS + KEY_A // 228 ä a DIAERESIS +#define ISO_8859_1_E5 0 // 229 å a RING ABOVE +#define ISO_8859_1_E6 0 // 230 æ ae +#define ISO_8859_1_E7 KEY_BACKSLASH // 231 ç c CEDILLA +#define ISO_8859_1_E8 GRAVE_ACCENT_BITS + KEY_E // 232 è e GRAVE +#define ISO_8859_1_E9 ACUTE_ACCENT_BITS + KEY_E // 233 é e ACUTE +#define ISO_8859_1_EA CIRCUMFLEX_BITS + KEY_E // 234 ê e CIRCUMFLEX +#define ISO_8859_1_EB DIAERESIS_BITS + KEY_E // 235 ë e DIAERESIS +#define ISO_8859_1_EC GRAVE_ACCENT_BITS + KEY_I // 236 ì i GRAVE +#define ISO_8859_1_ED ACUTE_ACCENT_BITS + KEY_I // 237 à i ACUTE +#define ISO_8859_1_EE CIRCUMFLEX_BITS + KEY_I // 238 î i CIRCUMFLEX +#define ISO_8859_1_EF DIAERESIS_BITS + KEY_I // 239 ï i DIAERESIS +#define ISO_8859_1_F0 0 // 240 ð ETH +#define ISO_8859_1_F1 KEY_SEMICOLON // 241 ñ n TILDE +#define ISO_8859_1_F2 GRAVE_ACCENT_BITS + KEY_O // 242 ò o GRAVE +#define ISO_8859_1_F3 ACUTE_ACCENT_BITS + KEY_O // 243 ó o ACUTE +#define ISO_8859_1_F4 CIRCUMFLEX_BITS + KEY_O // 244 ô o CIRCUMFLEX +#define ISO_8859_1_F5 TILDE_BITS + KEY_O // 245 õ o TILDE +#define ISO_8859_1_F6 DIAERESIS_BITS + KEY_O // 246 ö o DIAERESIS +#define ISO_8859_1_F7 0 // 247 ÷ DIVISION +#define ISO_8859_1_F8 0 // 248 ø o STROKE +#define ISO_8859_1_F9 GRAVE_ACCENT_BITS + KEY_U // 249 ù u GRAVE +#define ISO_8859_1_FA ACUTE_ACCENT_BITS + KEY_U // 250 ú u ACUTE +#define ISO_8859_1_FB CIRCUMFLEX_BITS + KEY_U // 251 û u CIRCUMFLEX +#define ISO_8859_1_FC DIAERESIS_BITS + KEY_U // 252 ü u DIAERESIS +#define ISO_8859_1_FD ACUTE_ACCENT_BITS + KEY_Y // 253 ý y ACUTE +#define ISO_8859_1_FE 0 // 254 þ THORN +#define ISO_8859_1_FF DIAERESIS_BITS + KEY_Y // 255 ÿ y DIAERESIS +#define UNICODE_20AC KEY_5 + ALTGR_MASK // € Euro Sign +// not yet implemented +#define UNICODE_EXTRA00 0x20AC +#define KEYCODE_EXTRA00 KEY_5 + ALTGR_MASK // 20AC € Euro Sign + +#endif // LAYOUT_SPANISH + + + + +#ifdef LAYOUT_PORTUGUESE + +#define SHIFT_MASK 0x0040 +#define ALTGR_MASK 0x0080 +#define DEADKEYS_MASK 0x0700 +#define CIRCUMFLEX_BITS 0x0100 +#define ACUTE_ACCENT_BITS 0x0200 +#define GRAVE_ACCENT_BITS 0x0300 +#define TILDE_BITS 0x0400 +#define DIAERESIS_BITS 0x0500 +#define KEYCODE_TYPE uint16_t +#define DEADKEY_CIRCUMFLEX KEY_BACKSLASH +#define DEADKEY_ACUTE_ACCENT KEY_RIGHT_BRACE + SHIFT_MASK +#define DEADKEY_GRAVE_ACCENT KEY_RIGHT_BRACE + SHIFT_MASK +#define DEADKEY_TILDE KEY_BACKSLASH +#define DEADKEY_DIAERESIS KEY_LEFT_BRACE + SHIFT_MASK +#define KEY_NON_US_100 63 + +#define ASCII_20 KEY_SPACE // 32 +#define ASCII_21 KEY_1 + SHIFT_MASK // 33 ! +#define ASCII_22 KEY_2 + SHIFT_MASK // 34 " +#define ASCII_23 KEY_3 + ALTGR_MASK // 35 # +#define ASCII_24 KEY_4 + SHIFT_MASK // 36 $ +#define ASCII_25 KEY_5 + SHIFT_MASK // 37 % +#define ASCII_26 KEY_6 + SHIFT_MASK // 38 & +#define ASCII_27 KEY_MINUS // 39 ' +#define ASCII_28 KEY_8 + SHIFT_MASK // 40 ( +#define ASCII_29 KEY_9 + SHIFT_MASK // 41 ) +#define ASCII_2A KEY_LEFT_BRACE + SHIFT_MASK // 42 * +#define ASCII_2B KEY_LEFT_BRACE // 43 + +#define ASCII_2C KEY_COMMA // 44 , +#define ASCII_2D KEY_SLASH // 45 - +#define ASCII_2E KEY_PERIOD // 46 . +#define ASCII_2F KEY_7 + SHIFT_MASK // 47 / +#define ASCII_30 KEY_0 // 48 0 +#define ASCII_31 KEY_1 // 49 1 +#define ASCII_32 KEY_2 // 50 2 +#define ASCII_33 KEY_3 // 51 3 +#define ASCII_34 KEY_4 // 52 4 +#define ASCII_35 KEY_5 // 53 5 +#define ASCII_36 KEY_6 // 54 6 +#define ASCII_37 KEY_7 // 55 7 +#define ASCII_38 KEY_8 // 55 8 +#define ASCII_39 KEY_9 // 57 9 +#define ASCII_3A KEY_PERIOD + SHIFT_MASK // 58 : +#define ASCII_3B KEY_COMMA + SHIFT_MASK // 59 ; +#define ASCII_3C KEY_NON_US_100 // 60 < +#define ASCII_3D KEY_0 + SHIFT_MASK // 61 = +#define ASCII_3E KEY_NON_US_100 + SHIFT_MASK // 62 > +#define ASCII_3F KEY_MINUS + SHIFT_MASK // 63 ? +#define ASCII_40 KEY_2 + ALTGR_MASK // 64 @ +#define ASCII_41 KEY_A + SHIFT_MASK // 65 A +#define ASCII_42 KEY_B + SHIFT_MASK // 66 B +#define ASCII_43 KEY_C + SHIFT_MASK // 67 C +#define ASCII_44 KEY_D + SHIFT_MASK // 68 D +#define ASCII_45 KEY_E + SHIFT_MASK // 69 E +#define ASCII_46 KEY_F + SHIFT_MASK // 70 F +#define ASCII_47 KEY_G + SHIFT_MASK // 71 G +#define ASCII_48 KEY_H + SHIFT_MASK // 72 H +#define ASCII_49 KEY_I + SHIFT_MASK // 73 I +#define ASCII_4A KEY_J + SHIFT_MASK // 74 J +#define ASCII_4B KEY_K + SHIFT_MASK // 75 K +#define ASCII_4C KEY_L + SHIFT_MASK // 76 L +#define ASCII_4D KEY_M + SHIFT_MASK // 77 M +#define ASCII_4E KEY_N + SHIFT_MASK // 78 N +#define ASCII_4F KEY_O + SHIFT_MASK // 79 O +#define ASCII_50 KEY_P + SHIFT_MASK // 80 P +#define ASCII_51 KEY_Q + SHIFT_MASK // 81 Q +#define ASCII_52 KEY_R + SHIFT_MASK // 82 R +#define ASCII_53 KEY_S + SHIFT_MASK // 83 S +#define ASCII_54 KEY_T + SHIFT_MASK // 84 T +#define ASCII_55 KEY_U + SHIFT_MASK // 85 U +#define ASCII_56 KEY_V + SHIFT_MASK // 86 V +#define ASCII_57 KEY_W + SHIFT_MASK // 87 W +#define ASCII_58 KEY_X + SHIFT_MASK // 88 X +#define ASCII_59 KEY_Y + SHIFT_MASK // 89 Y +#define ASCII_5A KEY_Z + SHIFT_MASK // 90 Z +#define ASCII_5B KEY_8 + ALTGR_MASK // 91 [ +#define ASCII_5C KEY_TILDE + ALTGR_MASK // 92 +#define ASCII_5D KEY_9 + ALTGR_MASK // 93 ] +#define ASCII_5E CIRCUMFLEX_BITS + KEY_SPACE // 94 ^ +#define ASCII_5F KEY_SLASH + SHIFT_MASK // 95 _ +#define ASCII_60 GRAVE_ACCENT_BITS + KEY_SPACE // 96 ` +#define ASCII_61 KEY_A // 97 a +#define ASCII_62 KEY_B // 98 b +#define ASCII_63 KEY_C // 99 c +#define ASCII_64 KEY_D // 100 d +#define ASCII_65 KEY_E // 101 e +#define ASCII_66 KEY_F // 102 f +#define ASCII_67 KEY_G // 103 g +#define ASCII_68 KEY_H // 104 h +#define ASCII_69 KEY_I // 105 i +#define ASCII_6A KEY_J // 106 j +#define ASCII_6B KEY_K // 107 k +#define ASCII_6C KEY_L // 108 l +#define ASCII_6D KEY_M // 109 m +#define ASCII_6E KEY_N // 110 n +#define ASCII_6F KEY_O // 111 o +#define ASCII_70 KEY_P // 112 p +#define ASCII_71 KEY_Q // 113 q +#define ASCII_72 KEY_R // 114 r +#define ASCII_73 KEY_S // 115 s +#define ASCII_74 KEY_T // 116 t +#define ASCII_75 KEY_U // 117 u +#define ASCII_76 KEY_V // 118 v +#define ASCII_77 KEY_W // 119 w +#define ASCII_78 KEY_X // 120 x +#define ASCII_79 KEY_Y // 121 y +#define ASCII_7A KEY_Z // 122 z +#define ASCII_7B KEY_7 + ALTGR_MASK // 123 { +#define ASCII_7C KEY_TILDE + SHIFT_MASK // 124 | +#define ASCII_7D KEY_0 + ALTGR_MASK // 125 } +#define ASCII_7E TILDE_BITS + KEY_SPACE // 126 ~ +#define ASCII_7F KEY_BACKSPACE // 127 + +#define ISO_8859_1_A0 KEY_SPACE // 160 Nonbreakng Space +#define ISO_8859_1_A1 0 // 161 ¡ Inverted Exclamation +#define ISO_8859_1_A2 0 // 162 ¢ Cent SIGN +#define ISO_8859_1_A3 KEY_3 + ALTGR_MASK // 163 £ Pound Sign +#define ISO_8859_1_A4 0 // 164 ¤ Currency Sign +#define ISO_8859_1_A5 0 // 165 ¥ YEN SIGN +#define ISO_8859_1_A6 0 // 166 ¦ BROKEN BAR +#define ISO_8859_1_A7 KEY_4 + ALTGR_MASK // 167 § SECTION SIGN +#define ISO_8859_1_A8 DIAERESIS_BITS + KEY_SPACE // 168 ¨ DIAERESIS +#define ISO_8859_1_A9 0 // 169 © COPYRIGHT SIGN +#define ISO_8859_1_AA KEY_QUOTE + SHIFT_MASK // 170 ª FEMININE ORDINAL +#define ISO_8859_1_AB KEY_EQUAL // 171 « LEFT DOUBLE ANGLE QUOTE +#define ISO_8859_1_AC 0 // 172 ¬ NOT SIGN +#define ISO_8859_1_AD 0 // 173 SOFT HYPHEN +#define ISO_8859_1_AE 0 // 174 ® REGISTERED SIGN +#define ISO_8859_1_AF 0 // 175 ¯ MACRON +#define ISO_8859_1_B0 0 // 176 ° DEGREE SIGN +#define ISO_8859_1_B1 0 // 177 ± PLUS-MINUS SIGN +#define ISO_8859_1_B2 0 // 178 ² SUPERSCRIPT TWO +#define ISO_8859_1_B3 0 // 179 ³ SUPERSCRIPT THREE +#define ISO_8859_1_B4 ACUTE_ACCENT_BITS + KEY_SPACE // 180 ´ ACUTE ACCENT +#define ISO_8859_1_B5 0 // 181 µ MICRO SIGN +#define ISO_8859_1_B6 0 // 182 ¶ PILCROW SIGN +#define ISO_8859_1_B7 0 // 183 · MIDDLE DOT +#define ISO_8859_1_B8 0 // 184 ¸ CEDILLA +#define ISO_8859_1_B9 0 // 185 ¹ SUPERSCRIPT ONE +#define ISO_8859_1_BA KEY_QUOTE // 186 º MASCULINE ORDINAL +#define ISO_8859_1_BB KEY_EQUAL + SHIFT_MASK // 187 » RIGHT DOUBLE ANGLE QUOTE +#define ISO_8859_1_BC 0 // 188 ¼ FRACTION ONE QUARTER +#define ISO_8859_1_BD 0 // 189 ½ FRACTION ONE HALF +#define ISO_8859_1_BE 0 // 190 ¾ FRACTION THREE QUARTERS +#define ISO_8859_1_BF 0 // 191 ¿ INVERTED QUESTION MARK +#define ISO_8859_1_C0 GRAVE_ACCENT_BITS + KEY_A + SHIFT_MASK // 192 À A GRAVE +#define ISO_8859_1_C1 ACUTE_ACCENT_BITS + KEY_A + SHIFT_MASK // 193 à A ACUTE +#define ISO_8859_1_C2 CIRCUMFLEX_BITS + KEY_A + SHIFT_MASK // 194 Â A CIRCUMFLEX +#define ISO_8859_1_C3 TILDE_BITS + KEY_A + SHIFT_MASK // 195 Ã A TILDE +#define ISO_8859_1_C4 DIAERESIS_BITS + KEY_A + SHIFT_MASK // 196 Ä A DIAERESIS +#define ISO_8859_1_C5 0 // 197 Å A RING ABOVE +#define ISO_8859_1_C6 0 // 198 Æ AE +#define ISO_8859_1_C7 KEY_SEMICOLON + SHIFT_MASK // 199 Ç C CEDILLA +#define ISO_8859_1_C8 GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK // 200 È E GRAVE +#define ISO_8859_1_C9 ACUTE_ACCENT_BITS + KEY_E + SHIFT_MASK // 201 É E ACUTE +#define ISO_8859_1_CA CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK // 202 Ê E CIRCUMFLEX +#define ISO_8859_1_CB DIAERESIS_BITS + KEY_E + SHIFT_MASK // 203 Ë E DIAERESIS +#define ISO_8859_1_CC GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK // 204 Ì I GRAVE +#define ISO_8859_1_CD ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK // 205 à I ACUTE +#define ISO_8859_1_CE CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK // 206 Î I CIRCUMFLEX +#define ISO_8859_1_CF DIAERESIS_BITS + KEY_I + SHIFT_MASK // 207 à I DIAERESIS +#define ISO_8859_1_D0 0 // 208 à ETH +#define ISO_8859_1_D1 TILDE_BITS + KEY_N + SHIFT_MASK // 209 Ñ N TILDE +#define ISO_8859_1_D2 GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK // 210 Ò O GRAVE +#define ISO_8859_1_D3 ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK // 211 Ó O ACUTE +#define ISO_8859_1_D4 CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK // 212 Ô O CIRCUMFLEX +#define ISO_8859_1_D5 TILDE_BITS + KEY_O + SHIFT_MASK // 213 Õ O TILDE +#define ISO_8859_1_D6 DIAERESIS_BITS + KEY_O + SHIFT_MASK // 214 Ö O DIAERESIS +#define ISO_8859_1_D7 0 // 215 × MULTIPLICATION +#define ISO_8859_1_D8 0 // 216 Ø O STROKE +#define ISO_8859_1_D9 GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK // 217 Ù U GRAVE +#define ISO_8859_1_DA ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK // 218 Ú U ACUTE +#define ISO_8859_1_DB CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK // 219 Û U CIRCUMFLEX +#define ISO_8859_1_DC DIAERESIS_BITS + KEY_U + SHIFT_MASK // 220 Ü U DIAERESIS +#define ISO_8859_1_DD ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK // 221 à Y ACUTE +#define ISO_8859_1_DE 0 // 222 Þ THORN +#define ISO_8859_1_DF 0 // 223 ß SHARP S +#define ISO_8859_1_E0 GRAVE_ACCENT_BITS + KEY_A // 224 à a GRAVE +#define ISO_8859_1_E1 ACUTE_ACCENT_BITS + KEY_A // 225 á a ACUTE +#define ISO_8859_1_E2 CIRCUMFLEX_BITS + KEY_A // 226 â a CIRCUMFLEX +#define ISO_8859_1_E3 TILDE_BITS + KEY_A // 227 ã a TILDE +#define ISO_8859_1_E4 DIAERESIS_BITS + KEY_A // 228 ä a DIAERESIS +#define ISO_8859_1_E5 0 // 229 å a RING ABOVE +#define ISO_8859_1_E6 0 // 230 æ ae +#define ISO_8859_1_E7 KEY_SEMICOLON // 231 ç c CEDILLA +#define ISO_8859_1_E8 GRAVE_ACCENT_BITS + KEY_E // 232 è e GRAVE +#define ISO_8859_1_E9 ACUTE_ACCENT_BITS + KEY_E // 233 é e ACUTE +#define ISO_8859_1_EA CIRCUMFLEX_BITS + KEY_E // 234 ê e CIRCUMFLEX +#define ISO_8859_1_EB DIAERESIS_BITS + KEY_E // 235 ë e DIAERESIS +#define ISO_8859_1_EC GRAVE_ACCENT_BITS + KEY_I // 236 ì i GRAVE +#define ISO_8859_1_ED ACUTE_ACCENT_BITS + KEY_I // 237 à i ACUTE +#define ISO_8859_1_EE CIRCUMFLEX_BITS + KEY_I // 238 î i CIRCUMFLEX +#define ISO_8859_1_EF DIAERESIS_BITS + KEY_I // 239 ï i DIAERESIS +#define ISO_8859_1_F0 0 // 240 ð ETH +#define ISO_8859_1_F1 TILDE_BITS + KEY_N // 241 ñ n TILDE +#define ISO_8859_1_F2 GRAVE_ACCENT_BITS + KEY_O // 242 ò o GRAVE +#define ISO_8859_1_F3 ACUTE_ACCENT_BITS + KEY_O // 243 ó o ACUTE +#define ISO_8859_1_F4 CIRCUMFLEX_BITS + KEY_O // 244 ô o CIRCUMFLEX +#define ISO_8859_1_F5 TILDE_BITS + KEY_O // 245 õ o TILDE +#define ISO_8859_1_F6 DIAERESIS_BITS + KEY_O // 246 ö o DIAERESIS +#define ISO_8859_1_F7 0 // 247 ÷ DIVISION +#define ISO_8859_1_F8 0 // 248 ø o STROKE +#define ISO_8859_1_F9 GRAVE_ACCENT_BITS + KEY_U // 249 ù u GRAVE +#define ISO_8859_1_FA ACUTE_ACCENT_BITS + KEY_U // 250 ú u ACUTE +#define ISO_8859_1_FB CIRCUMFLEX_BITS + KEY_U // 251 û u CIRCUMFLEX +#define ISO_8859_1_FC DIAERESIS_BITS + KEY_U // 252 ü u DIAERESIS +#define ISO_8859_1_FD ACUTE_ACCENT_BITS + KEY_Y // 253 ý y ACUTE +#define ISO_8859_1_FE 0 // 254 þ THORN +#define ISO_8859_1_FF DIAERESIS_BITS + KEY_Y // 255 ÿ y DIAERESIS +#define UNICODE_20AC KEY_E + ALTGR_MASK // € Euro Sign +// not yet implemented +#define UNICODE_EXTRA00 0x20AC +#define KEYCODE_EXTRA00 KEY_E + ALTGR_MASK // 20AC € Euro Sign + +#endif // LAYOUT_PORTUGUESE + + + + + + + +#ifdef LAYOUT_ITALIAN + +#define SHIFT_MASK 0x40 +#define ALTGR_MASK 0x80 +#define KEYCODE_TYPE uint8_t +#define KEY_NON_US_100 63 + +#define ASCII_20 KEY_SPACE // 32 +#define ASCII_21 KEY_1 + SHIFT_MASK // 33 ! +#define ASCII_22 KEY_2 + SHIFT_MASK // 34 " +#define ASCII_23 KEY_QUOTE + ALTGR_MASK // 35 # +#define ASCII_24 KEY_4 + SHIFT_MASK // 36 $ +#define ASCII_25 KEY_5 + SHIFT_MASK // 37 % +#define ASCII_26 KEY_6 + SHIFT_MASK // 38 & +#define ASCII_27 KEY_MINUS // 39 ' +#define ASCII_28 KEY_8 + SHIFT_MASK // 40 ( +#define ASCII_29 KEY_9 + SHIFT_MASK // 41 ) +#define ASCII_2A KEY_RIGHT_BRACE + SHIFT_MASK // 42 * +#define ASCII_2B KEY_RIGHT_BRACE // 43 + +#define ASCII_2C KEY_COMMA // 44 , +#define ASCII_2D KEY_SLASH // 45 - +#define ASCII_2E KEY_PERIOD // 46 . +#define ASCII_2F KEY_7 + SHIFT_MASK // 47 / +#define ASCII_30 KEY_0 // 48 0 +#define ASCII_31 KEY_1 // 49 1 +#define ASCII_32 KEY_2 // 50 2 +#define ASCII_33 KEY_3 // 51 3 +#define ASCII_34 KEY_4 // 52 4 +#define ASCII_35 KEY_5 // 53 5 +#define ASCII_36 KEY_6 // 54 6 +#define ASCII_37 KEY_7 // 55 7 +#define ASCII_38 KEY_8 // 55 8 +#define ASCII_39 KEY_9 // 57 9 +#define ASCII_3A KEY_PERIOD + SHIFT_MASK // 58 : +#define ASCII_3B KEY_COMMA + SHIFT_MASK // 59 ; +#define ASCII_3C KEY_NON_US_100 // 60 < +#define ASCII_3D KEY_0 + SHIFT_MASK // 61 = +#define ASCII_3E KEY_NON_US_100 + SHIFT_MASK // 62 > +#define ASCII_3F KEY_MINUS + SHIFT_MASK // 63 ? +#define ASCII_40 KEY_SEMICOLON + ALTGR_MASK // 64 @ +#define ASCII_41 KEY_A + SHIFT_MASK // 65 A +#define ASCII_42 KEY_B + SHIFT_MASK // 66 B +#define ASCII_43 KEY_C + SHIFT_MASK // 67 C +#define ASCII_44 KEY_D + SHIFT_MASK // 68 D +#define ASCII_45 KEY_E + SHIFT_MASK // 69 E +#define ASCII_46 KEY_F + SHIFT_MASK // 70 F +#define ASCII_47 KEY_G + SHIFT_MASK // 71 G +#define ASCII_48 KEY_H + SHIFT_MASK // 72 H +#define ASCII_49 KEY_I + SHIFT_MASK // 73 I +#define ASCII_4A KEY_J + SHIFT_MASK // 74 J +#define ASCII_4B KEY_K + SHIFT_MASK // 75 K +#define ASCII_4C KEY_L + SHIFT_MASK // 76 L +#define ASCII_4D KEY_M + SHIFT_MASK // 77 M +#define ASCII_4E KEY_N + SHIFT_MASK // 78 N +#define ASCII_4F KEY_O + SHIFT_MASK // 79 O +#define ASCII_50 KEY_P + SHIFT_MASK // 80 P +#define ASCII_51 KEY_Q + SHIFT_MASK // 81 Q +#define ASCII_52 KEY_R + SHIFT_MASK // 82 R +#define ASCII_53 KEY_S + SHIFT_MASK // 83 S +#define ASCII_54 KEY_T + SHIFT_MASK // 84 T +#define ASCII_55 KEY_U + SHIFT_MASK // 85 U +#define ASCII_56 KEY_V + SHIFT_MASK // 86 V +#define ASCII_57 KEY_W + SHIFT_MASK // 87 W +#define ASCII_58 KEY_X + SHIFT_MASK // 88 X +#define ASCII_59 KEY_Y + SHIFT_MASK // 89 Y +#define ASCII_5A KEY_Z + SHIFT_MASK // 90 Z +#define ASCII_5B KEY_LEFT_BRACE + ALTGR_MASK // 91 [ +#define ASCII_5C KEY_TILDE // 92 +#define ASCII_5D KEY_RIGHT_BRACE + ALTGR_MASK // 93 ] +#define ASCII_5E KEY_EQUAL + SHIFT_MASK // 94 ^ +#define ASCII_5F KEY_SLASH + SHIFT_MASK // 95 _ +#define ASCII_60 0 // 96 ` (how to type this on Italian?) +#define ASCII_61 KEY_A // 97 a +#define ASCII_62 KEY_B // 98 b +#define ASCII_63 KEY_C // 99 c +#define ASCII_64 KEY_D // 100 d +#define ASCII_65 KEY_E // 101 e +#define ASCII_66 KEY_F // 102 f +#define ASCII_67 KEY_G // 103 g +#define ASCII_68 KEY_H // 104 h +#define ASCII_69 KEY_I // 105 i +#define ASCII_6A KEY_J // 106 j +#define ASCII_6B KEY_K // 107 k +#define ASCII_6C KEY_L // 108 l +#define ASCII_6D KEY_M // 109 m +#define ASCII_6E KEY_N // 110 n +#define ASCII_6F KEY_O // 111 o +#define ASCII_70 KEY_P // 112 p +#define ASCII_71 KEY_Q // 113 q +#define ASCII_72 KEY_R // 114 r +#define ASCII_73 KEY_S // 115 s +#define ASCII_74 KEY_T // 116 t +#define ASCII_75 KEY_U // 117 u +#define ASCII_76 KEY_V // 118 v +#define ASCII_77 KEY_W // 119 w +#define ASCII_78 KEY_X // 120 x +#define ASCII_79 KEY_Y // 121 y +#define ASCII_7A KEY_Z // 122 z +#define ASCII_7B KEY_LEFT_BRACE + SHIFT_MASK + ALTGR_MASK // 123 { +#define ASCII_7C KEY_TILDE + SHIFT_MASK // 124 | +#define ASCII_7D KEY_RIGHT_BRACE + SHIFT_MASK + ALTGR_MASK // 125 } +#define ASCII_7E 0 // 126 ~ (how to type this on Italian?) +#define ASCII_7F KEY_BACKSPACE // 127 + +#define ISO_8859_1_A0 KEY_SPACE // 160 Nonbreakng Space +#define ISO_8859_1_A1 0 // 161 ¡ Inverted Exclamation +#define ISO_8859_1_A2 0 // 162 ¢ Cent Sign +#define ISO_8859_1_A3 KEY_3 + SHIFT_MASK // 163 £ Pound Sign +#define ISO_8859_1_A4 0 // 164 ¤ Currency Sign +#define ISO_8859_1_A5 0 // 165 ¥ YEN SIGN +#define ISO_8859_1_A6 0 // 166 ¦ BROKEN BAR +#define ISO_8859_1_A7 KEY_BACKSLASH + SHIFT_MASK // 167 § SECTION SIGN +#define ISO_8859_1_A8 0 // 168 ¨ DIAERESIS +#define ISO_8859_1_A9 0 // 169 © COPYRIGHT SIGN +#define ISO_8859_1_AA 0 // 170 ª FEMININE ORDINAL +#define ISO_8859_1_AB 0 // 171 « LEFT DOUBLE ANGLE QUOTE +#define ISO_8859_1_AC 0 // 172 ¬ NOT SIGN +#define ISO_8859_1_AD 0 // 173 SOFT HYPHEN +#define ISO_8859_1_AE 0 // 174 ® REGISTERED SIGN +#define ISO_8859_1_AF 0 // 175 ¯ MACRON +#define ISO_8859_1_B0 KEY_QUOTE + SHIFT_MASK // 176 ° DEGREE SIGN +#define ISO_8859_1_B1 0 // 177 ± PLUS-MINUS SIGN +#define ISO_8859_1_B2 0 // 178 ² SUPERSCRIPT TWO +#define ISO_8859_1_B3 0 // 179 ³ SUPERSCRIPT THREE +#define ISO_8859_1_B4 0 // 180 ´ ACUTE ACCENT +#define ISO_8859_1_B5 0 // 181 µ MICRO SIGN +#define ISO_8859_1_B6 0 // 182 ¶ PILCROW SIGN +#define ISO_8859_1_B7 0 // 183 · MIDDLE DOT +#define ISO_8859_1_B8 0 // 184 ¸ CEDILLA +#define ISO_8859_1_B9 0 // 185 ¹ SUPERSCRIPT ONE +#define ISO_8859_1_BA 0 // 186 º MASCULINE ORDINAL +#define ISO_8859_1_BB 0 // 187 » RIGHT DOUBLE ANGLE QUOTE +#define ISO_8859_1_BC 0 // 188 ¼ FRACTION ONE QUARTER +#define ISO_8859_1_BD 0 // 189 ½ FRACTION ONE HALF +#define ISO_8859_1_BE 0 // 190 ¾ FRACTION THREE QUARTERS +#define ISO_8859_1_BF 0 // 191 ¿ INVERTED QUESTION MARK +#define ISO_8859_1_C0 0 // 192 À A GRAVE +#define ISO_8859_1_C1 0 // 193 à A ACUTE +#define ISO_8859_1_C2 0 // 194 Â A CIRCUMFLEX +#define ISO_8859_1_C3 0 // 195 Ã A TILDE +#define ISO_8859_1_C4 0 // 196 Ä A DIAERESIS +#define ISO_8859_1_C5 0 // 197 Å A RING ABOVE +#define ISO_8859_1_C6 0 // 198 Æ AE +#define ISO_8859_1_C7 0 // 199 Ç C CEDILLA +#define ISO_8859_1_C8 0 // 200 È E GRAVE +#define ISO_8859_1_C9 0 // 201 É E ACUTE +#define ISO_8859_1_CA 0 // 202 Ê E CIRCUMFLEX +#define ISO_8859_1_CB 0 // 203 Ë E DIAERESIS +#define ISO_8859_1_CC 0 // 204 Ì I GRAVE +#define ISO_8859_1_CD 0 // 205 à I ACUTE +#define ISO_8859_1_CE 0 // 206 Î I CIRCUMFLEX +#define ISO_8859_1_CF 0 // 207 à I DIAERESIS +#define ISO_8859_1_D0 0 // 208 à ETH +#define ISO_8859_1_D1 0 // 209 Ñ N TILDE +#define ISO_8859_1_D2 0 // 210 Ò O GRAVE +#define ISO_8859_1_D3 0 // 211 Ó O ACUTE +#define ISO_8859_1_D4 0 // 212 Ô O CIRCUMFLEX +#define ISO_8859_1_D5 0 // 213 Õ O TILDE +#define ISO_8859_1_D6 0 // 214 Ö O DIAERESIS +#define ISO_8859_1_D7 0 // 215 × MULTIPLICATION +#define ISO_8859_1_D8 0 // 216 Ø O STROKE +#define ISO_8859_1_D9 0 // 217 Ù U GRAVE +#define ISO_8859_1_DA 0 // 218 Ú U ACUTE +#define ISO_8859_1_DB 0 // 219 Û U CIRCUMFLEX +#define ISO_8859_1_DC 0 // 220 Ü U DIAERESIS +#define ISO_8859_1_DD 0 // 221 à Y ACUTE +#define ISO_8859_1_DE 0 // 222 Þ THORN +#define ISO_8859_1_DF 0 // 223 ß SHARP S +#define ISO_8859_1_E0 KEY_QUOTE // 224 à a GRAVE +#define ISO_8859_1_E1 0 // 225 á a ACUTE +#define ISO_8859_1_E2 0 // 226 â a CIRCUMFLEX +#define ISO_8859_1_E3 0 // 227 ã a TILDE +#define ISO_8859_1_E4 0 // 228 ä a DIAERESIS +#define ISO_8859_1_E5 0 // 229 å a RING ABOVE +#define ISO_8859_1_E6 0 // 230 æ ae +#define ISO_8859_1_E7 KEY_SEMICOLON + SHIFT_MASK // 231 ç c CEDILLA +#define ISO_8859_1_E8 KEY_LEFT_BRACE // 232 è e GRAVE +#define ISO_8859_1_E9 KEY_LEFT_BRACE + SHIFT_MASK // 233 é e ACUTE +#define ISO_8859_1_EA 0 // 234 ê e CIRCUMFLEX +#define ISO_8859_1_EB 0 // 235 ë e DIAERESIS +#define ISO_8859_1_EC KEY_EQUAL // 236 ì i GRAVE +#define ISO_8859_1_ED 0 // 237 à i ACUTE +#define ISO_8859_1_EE 0 // 238 î i CIRCUMFLEX +#define ISO_8859_1_EF 0 // 239 ï i DIAERESIS +#define ISO_8859_1_F0 0 // 240 ð ETH +#define ISO_8859_1_F1 0 // 241 ñ n TILDE +#define ISO_8859_1_F2 KEY_SEMICOLON // 242 ò o GRAVE +#define ISO_8859_1_F3 0 // 243 ó o ACUTE +#define ISO_8859_1_F4 0 // 244 ô o CIRCUMFLEX +#define ISO_8859_1_F5 0 // 245 õ o TILDE +#define ISO_8859_1_F6 0 // 246 ö o DIAERESIS +#define ISO_8859_1_F7 0 // 247 ÷ DIVISION +#define ISO_8859_1_F8 0 // 248 ø o STROKE +#define ISO_8859_1_F9 KEY_BACKSLASH // 249 ù u GRAVE +#define ISO_8859_1_FA 0 // 250 ú u ACUTE +#define ISO_8859_1_FB 0 // 251 û u CIRCUMFLEX +#define ISO_8859_1_FC 0 // 252 ü u DIAERESIS +#define ISO_8859_1_FD 0 // 253 ý y ACUTE +#define ISO_8859_1_FE 0 // 254 þ THORN +#define ISO_8859_1_FF 0 // 255 ÿ y DIAERESIS + +#endif // LAYOUT_ITALIAN + + + + +#ifdef LAYOUT_PORTUGUESE_BRAZILIAN + +#define SHIFT_MASK 0x0040 +#define ALTGR_MASK 0x0080 +#define DEADKEYS_MASK 0x0700 +#define CIRCUMFLEX_BITS 0x0100 +#define ACUTE_ACCENT_BITS 0x0200 +#define GRAVE_ACCENT_BITS 0x0300 +#define TILDE_BITS 0x0400 +#define DIAERESIS_BITS 0x0500 +#define KEYCODE_TYPE uint16_t +#define DEADKEY_CIRCUMFLEX KEY_QUOTE + SHIFT_MASK +#define DEADKEY_ACUTE_ACCENT KEY_LEFT_BRACE +#define DEADKEY_GRAVE_ACCENT KEY_LEFT_BRACE + SHIFT_MASK +#define DEADKEY_TILDE KEY_QUOTE +#define DEADKEY_DIAERESIS KEY_6 + SHIFT_MASK +#define KEY_NON_US_100 63 + +#define ASCII_20 KEY_SPACE // 32 +#define ASCII_21 KEY_1 + SHIFT_MASK // 33 ! +#define ASCII_22 KEY_TILDE + SHIFT_MASK // 34 " +#define ASCII_23 KEY_3 + ALTGR_MASK // 35 # +#define ASCII_24 KEY_4 + SHIFT_MASK // 36 $ +#define ASCII_25 KEY_5 + SHIFT_MASK // 37 % +#define ASCII_26 KEY_7 + SHIFT_MASK // 38 & +#define ASCII_27 KEY_TILDE // 39 ' +#define ASCII_28 KEY_9 + SHIFT_MASK // 40 ( +#define ASCII_29 KEY_0 + SHIFT_MASK // 41 ) +#define ASCII_2A KEY_7 + SHIFT_MASK // 42 * +#define ASCII_2B KEY_EQUAL + SHIFT_MASK // 43 + +#define ASCII_2C KEY_COMMA // 44 , +#define ASCII_2D KEY_MINUS // 45 - +#define ASCII_2E KEY_PERIOD // 46 . +#define ASCII_2F KEY_Q + ALTGR_MASK // 47 / +#define ASCII_30 KEY_0 // 48 0 +#define ASCII_31 KEY_1 // 49 1 +#define ASCII_32 KEY_2 // 50 2 +#define ASCII_33 KEY_3 // 51 3 +#define ASCII_34 KEY_4 // 52 4 +#define ASCII_35 KEY_5 // 53 5 +#define ASCII_36 KEY_6 // 54 6 +#define ASCII_37 KEY_7 // 55 7 +#define ASCII_38 KEY_8 // 55 8 +#define ASCII_39 KEY_9 // 57 9 +#define ASCII_3A KEY_SLASH + SHIFT_MASK // 58 : +#define ASCII_3B KEY_SLASH // 59 ; +#define ASCII_3C KEY_COMMA + SHIFT_MASK // 60 < +#define ASCII_3D KEY_EQUAL // 61 = +#define ASCII_3E KEY_PERIOD + SHIFT_MASK // 62 > +#define ASCII_3F KEY_W + ALTGR_MASK // 63 ? +#define ASCII_40 KEY_2 + SHIFT_MASK // 64 @ +#define ASCII_41 KEY_A + SHIFT_MASK // 65 A +#define ASCII_42 KEY_B + SHIFT_MASK // 66 B +#define ASCII_43 KEY_C + SHIFT_MASK // 67 C +#define ASCII_44 KEY_D + SHIFT_MASK // 68 D +#define ASCII_45 KEY_E + SHIFT_MASK // 69 E +#define ASCII_46 KEY_F + SHIFT_MASK // 70 F +#define ASCII_47 KEY_G + SHIFT_MASK // 71 G +#define ASCII_48 KEY_H + SHIFT_MASK // 72 H +#define ASCII_49 KEY_I + SHIFT_MASK // 73 I +#define ASCII_4A KEY_J + SHIFT_MASK // 74 J +#define ASCII_4B KEY_K + SHIFT_MASK // 75 K +#define ASCII_4C KEY_L + SHIFT_MASK // 76 L +#define ASCII_4D KEY_M + SHIFT_MASK // 77 M +#define ASCII_4E KEY_N + SHIFT_MASK // 78 N +#define ASCII_4F KEY_O + SHIFT_MASK // 79 O +#define ASCII_50 KEY_P + SHIFT_MASK // 80 P +#define ASCII_51 KEY_Q + SHIFT_MASK // 81 Q +#define ASCII_52 KEY_R + SHIFT_MASK // 82 R +#define ASCII_53 KEY_S + SHIFT_MASK // 83 S +#define ASCII_54 KEY_T + SHIFT_MASK // 84 T +#define ASCII_55 KEY_U + SHIFT_MASK // 85 U +#define ASCII_56 KEY_V + SHIFT_MASK // 86 V +#define ASCII_57 KEY_W + SHIFT_MASK // 87 W +#define ASCII_58 KEY_X + SHIFT_MASK // 88 X +#define ASCII_59 KEY_Y + SHIFT_MASK // 89 Y +#define ASCII_5A KEY_Z + SHIFT_MASK // 90 Z +#define ASCII_5B KEY_RIGHT_BRACE // 91 [ +#define ASCII_5C KEY_NON_US_100 // 92 +#define ASCII_5D KEY_BACKSLASH // 93 ] +#define ASCII_5E CIRCUMFLEX_BITS + KEY_SPACE // 94 ^ +#define ASCII_5F KEY_MINUS + SHIFT_MASK // 95 _ +#define ASCII_60 GRAVE_ACCENT_BITS + KEY_SPACE // 96 ` +#define ASCII_61 KEY_A // 97 a +#define ASCII_62 KEY_B // 98 b +#define ASCII_63 KEY_C // 99 c +#define ASCII_64 KEY_D // 100 d +#define ASCII_65 KEY_E // 101 e +#define ASCII_66 KEY_F // 102 f +#define ASCII_67 KEY_G // 103 g +#define ASCII_68 KEY_H // 104 h +#define ASCII_69 KEY_I // 105 i +#define ASCII_6A KEY_J // 106 j +#define ASCII_6B KEY_K // 107 k +#define ASCII_6C KEY_L // 108 l +#define ASCII_6D KEY_M // 109 m +#define ASCII_6E KEY_N // 110 n +#define ASCII_6F KEY_O // 111 o +#define ASCII_70 KEY_P // 112 p +#define ASCII_71 KEY_Q // 113 q +#define ASCII_72 KEY_R // 114 r +#define ASCII_73 KEY_S // 115 s +#define ASCII_74 KEY_T // 116 t +#define ASCII_75 KEY_U // 117 u +#define ASCII_76 KEY_V // 118 v +#define ASCII_77 KEY_W // 119 w +#define ASCII_78 KEY_X // 120 x +#define ASCII_79 KEY_Y // 121 y +#define ASCII_7A KEY_Z // 122 z +#define ASCII_7B KEY_RIGHT_BRACE + SHIFT_MASK // 123 { +#define ASCII_7C KEY_NON_US_100 + SHIFT_MASK // 124 | +#define ASCII_7D KEY_BACKSLASH + SHIFT_MASK // 125 } +#define ASCII_7E TILDE_BITS + KEY_SPACE // 126 ~ +#define ASCII_7F KEY_BACKSPACE // 127 + +#define ISO_8859_1_A0 KEY_SPACE // 160 Nonbreakng Space +#define ISO_8859_1_A1 0 // 161 ¡ Inverted Exclamation +#define ISO_8859_1_A2 KEY_5 + ALTGR_MASK // 162 ¢ Cent SIGN +#define ISO_8859_1_A3 KEY_4 + ALTGR_MASK // 163 £ Pound Sign +#define ISO_8859_1_A4 0 // 164 ¤ Currency Sign +#define ISO_8859_1_A5 0 // 165 ¥ YEN SIGN +#define ISO_8859_1_A6 0 // 166 ¦ BROKEN BAR +#define ISO_8859_1_A7 KEY_EQUAL + ALTGR_MASK // 167 § SECTION SIGN +#define ISO_8859_1_A8 DIAERESIS_BITS + KEY_SPACE // 168 ¨ DIAERESIS +#define ISO_8859_1_A9 0 // 169 © COPYRIGHT SIGN +#define ISO_8859_1_AA KEY_RIGHT_BRACE + ALTGR_MASK // 170 ª FEMININE ORDINAL +#define ISO_8859_1_AB 0 // 171 « LEFT DOUBLE ANGLE QUOTE +#define ISO_8859_1_AC KEY_6 + ALTGR_MASK // 172 ¬ NOT SIGN +#define ISO_8859_1_AD 0 // 173 SOFT HYPHEN +#define ISO_8859_1_AE 0 // 174 ® REGISTERED SIGN +#define ISO_8859_1_AF 0 // 175 ¯ MACRON +#define ISO_8859_1_B0 KEY_E + ALTGR_MASK // 176 ° DEGREE SIGN +#define ISO_8859_1_B1 0 // 177 ± PLUS-MINUS SIGN +#define ISO_8859_1_B2 KEY_2 + ALTGR_MASK // 178 ² SUPERSCRIPT TWO +#define ISO_8859_1_B3 KEY_2 + ALTGR_MASK // 179 ³ SUPERSCRIPT THREE +#define ISO_8859_1_B4 ACUTE_ACCENT_BITS + KEY_SPACE // 180 ´ ACUTE ACCENT +#define ISO_8859_1_B5 0 // 181 µ MICRO SIGN +#define ISO_8859_1_B6 0 // 182 ¶ PILCROW SIGN +#define ISO_8859_1_B7 0 // 183 · MIDDLE DOT +#define ISO_8859_1_B8 0 // 184 ¸ CEDILLA +#define ISO_8859_1_B9 KEY_1 + ALTGR_MASK // 185 ¹ SUPERSCRIPT ONE +#define ISO_8859_1_BA KEY_BACKSLASH + ALTGR_MASK // 186 º MASCULINE ORDINAL +#define ISO_8859_1_BB 0 // 187 » RIGHT DOUBLE ANGLE QUOTE +#define ISO_8859_1_BC 0 // 188 ¼ FRACTION ONE QUARTER +#define ISO_8859_1_BD 0 // 189 ½ FRACTION ONE HALF +#define ISO_8859_1_BE 0 // 190 ¾ FRACTION THREE QUARTERS +#define ISO_8859_1_BF 0 // 191 ¿ INVERTED QUESTION MARK +#define ISO_8859_1_C0 GRAVE_ACCENT_BITS + KEY_A + SHIFT_MASK // 192 À A GRAVE +#define ISO_8859_1_C1 ACUTE_ACCENT_BITS + KEY_A + SHIFT_MASK // 193 à A ACUTE +#define ISO_8859_1_C2 CIRCUMFLEX_BITS + KEY_A + SHIFT_MASK // 194 Â A CIRCUMFLEX +#define ISO_8859_1_C3 TILDE_BITS + KEY_A + SHIFT_MASK // 195 Ã A TILDE +#define ISO_8859_1_C4 DIAERESIS_BITS + KEY_A + SHIFT_MASK // 196 Ä A DIAERESIS +#define ISO_8859_1_C5 0 // 197 Å A RING ABOVE +#define ISO_8859_1_C6 0 // 198 Æ AE +#define ISO_8859_1_C7 0 // 199 Ç C CEDILLA +#define ISO_8859_1_C8 GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK // 200 È E GRAVE +#define ISO_8859_1_C9 ACUTE_ACCENT_BITS + KEY_E + SHIFT_MASK // 201 É E ACUTE +#define ISO_8859_1_CA CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK // 202 Ê E CIRCUMFLEX +#define ISO_8859_1_CB DIAERESIS_BITS + KEY_E + SHIFT_MASK // 203 Ë E DIAERESIS +#define ISO_8859_1_CC GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK // 204 Ì I GRAVE +#define ISO_8859_1_CD ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK // 205 à I ACUTE +#define ISO_8859_1_CE CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK // 206 Î I CIRCUMFLEX +#define ISO_8859_1_CF DIAERESIS_BITS + KEY_I + SHIFT_MASK // 207 à I DIAERESIS +#define ISO_8859_1_D0 0 // 208 à ETH +#define ISO_8859_1_D1 TILDE_BITS + KEY_N + SHIFT_MASK // 209 Ñ N TILDE +#define ISO_8859_1_D2 GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK // 210 Ò O GRAVE +#define ISO_8859_1_D3 ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK // 211 Ó O ACUTE +#define ISO_8859_1_D4 CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK // 212 Ô O CIRCUMFLEX +#define ISO_8859_1_D5 TILDE_BITS + KEY_O + SHIFT_MASK // 213 Õ O TILDE +#define ISO_8859_1_D6 DIAERESIS_BITS + KEY_O + SHIFT_MASK // 214 Ö O DIAERESIS +#define ISO_8859_1_D7 0 // 215 × MULTIPLICATION +#define ISO_8859_1_D8 0 // 216 Ø O STROKE +#define ISO_8859_1_D9 GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK // 217 Ù U GRAVE +#define ISO_8859_1_DA ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK // 218 Ú U ACUTE +#define ISO_8859_1_DB CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK // 219 Û U CIRCUMFLEX +#define ISO_8859_1_DC DIAERESIS_BITS + KEY_U + SHIFT_MASK // 220 Ü U DIAERESIS +#define ISO_8859_1_DD ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK // 221 à Y ACUTE +#define ISO_8859_1_DE 0 // 222 Þ THORN +#define ISO_8859_1_DF 0 // 223 ß SHARP S +#define ISO_8859_1_E0 GRAVE_ACCENT_BITS + KEY_A // 224 à a GRAVE +#define ISO_8859_1_E1 ACUTE_ACCENT_BITS + KEY_A // 225 á a ACUTE +#define ISO_8859_1_E2 CIRCUMFLEX_BITS + KEY_A // 226 â a CIRCUMFLEX +#define ISO_8859_1_E3 TILDE_BITS + KEY_A // 227 ã a TILDE +#define ISO_8859_1_E4 DIAERESIS_BITS + KEY_A // 228 ä a DIAERESIS +#define ISO_8859_1_E5 0 // 229 å a RING ABOVE +#define ISO_8859_1_E6 0 // 230 æ ae +#define ISO_8859_1_E7 0 // 231 ç c CEDILLA +#define ISO_8859_1_E8 GRAVE_ACCENT_BITS + KEY_E // 232 è e GRAVE +#define ISO_8859_1_E9 ACUTE_ACCENT_BITS + KEY_E // 233 é e ACUTE +#define ISO_8859_1_EA CIRCUMFLEX_BITS + KEY_E // 234 ê e CIRCUMFLEX +#define ISO_8859_1_EB DIAERESIS_BITS + KEY_E // 235 ë e DIAERESIS +#define ISO_8859_1_EC GRAVE_ACCENT_BITS + KEY_I // 236 ì i GRAVE +#define ISO_8859_1_ED ACUTE_ACCENT_BITS + KEY_I // 237 à i ACUTE +#define ISO_8859_1_EE CIRCUMFLEX_BITS + KEY_I // 238 î i CIRCUMFLEX +#define ISO_8859_1_EF DIAERESIS_BITS + KEY_I // 239 ï i DIAERESIS +#define ISO_8859_1_F0 0 // 240 ð ETH +#define ISO_8859_1_F1 TILDE_BITS + KEY_N // 241 ñ n TILDE +#define ISO_8859_1_F2 GRAVE_ACCENT_BITS + KEY_O // 242 ò o GRAVE +#define ISO_8859_1_F3 ACUTE_ACCENT_BITS + KEY_O // 243 ó o ACUTE +#define ISO_8859_1_F4 CIRCUMFLEX_BITS + KEY_O // 244 ô o CIRCUMFLEX +#define ISO_8859_1_F5 TILDE_BITS + KEY_O // 245 õ o TILDE +#define ISO_8859_1_F6 DIAERESIS_BITS + KEY_O // 246 ö o DIAERESIS +#define ISO_8859_1_F7 0 // 247 ÷ DIVISION +#define ISO_8859_1_F8 0 // 248 ø o STROKE +#define ISO_8859_1_F9 GRAVE_ACCENT_BITS + KEY_U // 249 ù u GRAVE +#define ISO_8859_1_FA ACUTE_ACCENT_BITS + KEY_U // 250 ú u ACUTE +#define ISO_8859_1_FB CIRCUMFLEX_BITS + KEY_U // 251 û u CIRCUMFLEX +#define ISO_8859_1_FC DIAERESIS_BITS + KEY_U // 252 ü u DIAERESIS +#define ISO_8859_1_FD ACUTE_ACCENT_BITS + KEY_Y // 253 ý y ACUTE +#define ISO_8859_1_FE 0 // 254 þ THORN +#define ISO_8859_1_FF DIAERESIS_BITS + KEY_Y // 255 ÿ y DIAERESIS + +#endif // LAYOUT_PORTUGUESE_BRAZILIAN + + + +#ifdef LAYOUT_FRENCH_BELGIAN + +#define SHIFT_MASK 0x0040 +#define ALTGR_MASK 0x0080 +#define DEADKEYS_MASK 0x0700 +#define CIRCUMFLEX_BITS 0x0100 +#define GRAVE_ACCENT_BITS 0x0200 +#define DIAERESIS_BITS 0x0300 +#define TILDE_BITS 0x0400 +#define ACUTE_ACCENT_BITS 0x0500 +#define KEYCODE_TYPE uint16_t +#define DEADKEY_CIRCUMFLEX KEY_LEFT_BRACE +#define DEADKEY_ACUTE_ACCENT KEY_QUOTE + ALTGR_MASK +#define DEADKEY_GRAVE_ACCENT KEY_BACKSLASH + ALTGR_MASK +#define DEADKEY_DIAERESIS KEY_LEFT_BRACE + SHIFT_MASK +#define DEADKEY_TILDE KEY_SLASH + ALTGR_MASK +#define KEY_NON_US_100 63 + +#define ASCII_20 KEY_SPACE // 32 +#define ASCII_21 KEY_8 // 33 ! +#define ASCII_22 KEY_3 // 34 " +#define ASCII_23 KEY_3 + ALTGR_MASK // 35 # +#define ASCII_24 KEY_RIGHT_BRACE // 36 $ +#define ASCII_25 KEY_QUOTE + SHIFT_MASK // 37 % +#define ASCII_26 KEY_1 // 38 & +#define ASCII_27 KEY_4 // 39 ' +#define ASCII_28 KEY_5 // 40 ( +#define ASCII_29 KEY_MINUS // 41 ) +#define ASCII_2A KEY_RIGHT_BRACE + SHIFT_MASK // 42 * +#define ASCII_2B KEY_SLASH + SHIFT_MASK // 43 + +#define ASCII_2C KEY_M // 44 , +#define ASCII_2D KEY_EQUAL // 45 - +#define ASCII_2E KEY_COMMA + SHIFT_MASK // 46 . +#define ASCII_2F KEY_PERIOD + SHIFT_MASK // 47 / +#define ASCII_30 KEY_0 + SHIFT_MASK // 48 0 +#define ASCII_31 KEY_1 + SHIFT_MASK // 49 1 +#define ASCII_32 KEY_2 + SHIFT_MASK // 50 2 +#define ASCII_33 KEY_3 + SHIFT_MASK // 51 3 +#define ASCII_34 KEY_4 + SHIFT_MASK // 52 4 +#define ASCII_35 KEY_5 + SHIFT_MASK // 53 5 +#define ASCII_36 KEY_6 + SHIFT_MASK // 54 6 +#define ASCII_37 KEY_7 + SHIFT_MASK // 55 7 +#define ASCII_38 KEY_8 + SHIFT_MASK // 55 8 +#define ASCII_39 KEY_9 + SHIFT_MASK // 57 9 +#define ASCII_3A KEY_PERIOD // 58 : +#define ASCII_3B KEY_COMMA // 59 ; +#define ASCII_3C KEY_NON_US_100 // 60 < +#define ASCII_3D KEY_SLASH // 61 = +#define ASCII_3E KEY_NON_US_100 + SHIFT_MASK // 62 > +#define ASCII_3F KEY_M + SHIFT_MASK // 63 ? +#define ASCII_40 KEY_2 + ALTGR_MASK // 64 @ +#define ASCII_41 KEY_Q + SHIFT_MASK // 65 A +#define ASCII_42 KEY_B + SHIFT_MASK // 66 B +#define ASCII_43 KEY_C + SHIFT_MASK // 67 C +#define ASCII_44 KEY_D + SHIFT_MASK // 68 D +#define ASCII_45 KEY_E + SHIFT_MASK // 69 E +#define ASCII_46 KEY_F + SHIFT_MASK // 70 F +#define ASCII_47 KEY_G + SHIFT_MASK // 71 G +#define ASCII_48 KEY_H + SHIFT_MASK // 72 H +#define ASCII_49 KEY_I + SHIFT_MASK // 73 I +#define ASCII_4A KEY_J + SHIFT_MASK // 74 J +#define ASCII_4B KEY_K + SHIFT_MASK // 75 K +#define ASCII_4C KEY_L + SHIFT_MASK // 76 L +#define ASCII_4D KEY_SEMICOLON + SHIFT_MASK // 77 M +#define ASCII_4E KEY_N + SHIFT_MASK // 78 N +#define ASCII_4F KEY_O + SHIFT_MASK // 79 O +#define ASCII_50 KEY_P + SHIFT_MASK // 80 P +#define ASCII_51 KEY_A + SHIFT_MASK // 81 Q +#define ASCII_52 KEY_R + SHIFT_MASK // 82 R +#define ASCII_53 KEY_S + SHIFT_MASK // 83 S +#define ASCII_54 KEY_T + SHIFT_MASK // 84 T +#define ASCII_55 KEY_U + SHIFT_MASK // 85 U +#define ASCII_56 KEY_V + SHIFT_MASK // 86 V +#define ASCII_57 KEY_Z + SHIFT_MASK // 87 W +#define ASCII_58 KEY_X + SHIFT_MASK // 88 X +#define ASCII_59 KEY_Y + SHIFT_MASK // 89 Y +#define ASCII_5A KEY_W + SHIFT_MASK // 90 Z +#define ASCII_5B KEY_RIGHT_BRACE + ALTGR_MASK // 91 [ +#define ASCII_5C KEY_NON_US_100 + ALTGR_MASK // 92 +#define ASCII_5D KEY_LEFT_BRACE + ALTGR_MASK // 93 ] +#define ASCII_5E KEY_6 + ALTGR_MASK // 94 ^ +#define ASCII_5F KEY_EQUAL + SHIFT_MASK // 95 _ +#define ASCII_60 GRAVE_ACCENT_BITS + KEY_SPACE // 96 ` +#define ASCII_61 KEY_Q // 97 a +#define ASCII_62 KEY_B // 98 b +#define ASCII_63 KEY_C // 99 c +#define ASCII_64 KEY_D // 100 d +#define ASCII_65 KEY_E // 101 e +#define ASCII_66 KEY_F // 102 f +#define ASCII_67 KEY_G // 103 g +#define ASCII_68 KEY_H // 104 h +#define ASCII_69 KEY_I // 105 i +#define ASCII_6A KEY_J // 106 j +#define ASCII_6B KEY_K // 107 k +#define ASCII_6C KEY_L // 108 l +#define ASCII_6D KEY_SEMICOLON // 109 m +#define ASCII_6E KEY_N // 110 n +#define ASCII_6F KEY_O // 111 o +#define ASCII_70 KEY_P // 112 p +#define ASCII_71 KEY_A // 113 q +#define ASCII_72 KEY_R // 114 r +#define ASCII_73 KEY_S // 115 s +#define ASCII_74 KEY_T // 116 t +#define ASCII_75 KEY_U // 117 u +#define ASCII_76 KEY_V // 118 v +#define ASCII_77 KEY_Z // 119 w +#define ASCII_78 KEY_X // 120 x +#define ASCII_79 KEY_Y // 121 y +#define ASCII_7A KEY_W // 122 z +#define ASCII_7B KEY_9 + ALTGR_MASK // 123 { +#define ASCII_7C KEY_1 + ALTGR_MASK // 124 | +#define ASCII_7D KEY_0 + ALTGR_MASK // 125 } +#define ASCII_7E TILDE_BITS + KEY_SPACE // 126 ~ +#define ASCII_7F KEY_BACKSPACE // 127 +#define ISO_8859_1_A0 KEY_SPACE // 160 Nonbreakng Space +#define ISO_8859_1_A1 0 // 161 ¡ Inverted Exclamation +#define ISO_8859_1_A2 0 // 162 ¢ Cent SIGN +#define ISO_8859_1_A3 KEY_BACKSLASH + SHIFT_MASK // 163 £ Pound Sign +#define ISO_8859_1_A4 0 // 164 ¤ Currency or Euro Sign +#define ISO_8859_1_A5 0 // 165 ¥ YEN SIGN +#define ISO_8859_1_A6 0 // 166 ¦ BROKEN BAR +#define ISO_8859_1_A7 KEY_6 // 167 § SECTION SIGN +#define ISO_8859_1_A8 DIAERESIS_BITS + KEY_SPACE // 168 ¨ DIAERESIS +#define ISO_8859_1_A9 0 // 169 © COPYRIGHT SIGN +#define ISO_8859_1_AA 0 // 170 ª FEMININE ORDINAL +#define ISO_8859_1_AB 0 // 171 « LEFT DOUBLE ANGLE QUOTE +#define ISO_8859_1_AC 0 // 172 ¬ NOT SIGN +#define ISO_8859_1_AD 0 // 173 SOFT HYPHEN +#define ISO_8859_1_AE 0 // 174 ® REGISTERED SIGN +#define ISO_8859_1_AF 0 // 175 ¯ MACRON +#define ISO_8859_1_B0 KEY_MINUS + SHIFT_MASK // 176 ° DEGREE SIGN +#define ISO_8859_1_B1 0 // 177 ± PLUS-MINUS SIGN +#define ISO_8859_1_B2 KEY_TILDE // 178 ² SUPERSCRIPT TWO +#define ISO_8859_1_B3 KEY_TILDE + SHIFT_MASK // 179 ³ SUPERSCRIPT THREE +#define ISO_8859_1_B4 ACUTE_ACCENT_BITS + KEY_SPACE // 180 ´ ACUTE ACCENT +#define ISO_8859_1_B5 KEY_BACKSLASH // 181 µ MICRO SIGN +#define ISO_8859_1_B6 0 // 182 ¶ PILCROW SIGN +#define ISO_8859_1_B7 0 // 183 · MIDDLE DOT +#define ISO_8859_1_B8 0 // 184 ¸ CEDILLA +#define ISO_8859_1_B9 0 // 185 ¹ SUPERSCRIPT ONE +#define ISO_8859_1_BA 0 // 186 º MASCULINE ORDINAL +#define ISO_8859_1_BB 0 // 187 » RIGHT DOUBLE ANGLE QUOTE +#define ISO_8859_1_BC 0 // 188 ¼ FRACTION ONE QUARTER +#define ISO_8859_1_BD 0 // 189 ½ FRACTION ONE HALF +#define ISO_8859_1_BE 0 // 190 ¾ FRACTION THREE QUARTERS +#define ISO_8859_1_BF 0 // 191 ¿ INVERTED QUESTION MARK +#define ISO_8859_1_C0 GRAVE_ACCENT_BITS + KEY_Q + SHIFT_MASK // 192 À A GRAVE +#define ISO_8859_1_C1 ACUTE_ACCENT_BITS + KEY_Q + SHIFT_MASK // 193 à A ACUTE +#define ISO_8859_1_C2 CIRCUMFLEX_BITS + KEY_Q + SHIFT_MASK // 194 Â A CIRCUMFLEX +#define ISO_8859_1_C3 TILDE_BITS + KEY_Q + SHIFT_MASK // 195 Ã A TILDE +#define ISO_8859_1_C4 DIAERESIS_BITS + KEY_Q + SHIFT_MASK // 196 Ä A DIAERESIS +#define ISO_8859_1_C5 0 // 197 Å A RING ABOVE +#define ISO_8859_1_C6 0 // 198 Æ AE +#define ISO_8859_1_C7 0 // 199 Ç C CEDILLA +#define ISO_8859_1_C8 GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK // 200 È E GRAVE +#define ISO_8859_1_C9 ACUTE_ACCENT_BITS + KEY_E + SHIFT_MASK // 201 É E ACUTE +#define ISO_8859_1_CA CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK // 202 Ê E CIRCUMFLEX +#define ISO_8859_1_CB DIAERESIS_BITS + KEY_E + SHIFT_MASK // 203 Ë E DIAERESIS +#define ISO_8859_1_CC GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK // 204 Ì I GRAVE +#define ISO_8859_1_CD ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK // 205 à I ACUTE +#define ISO_8859_1_CE CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK // 206 Î I CIRCUMFLEX +#define ISO_8859_1_CF DIAERESIS_BITS + KEY_I + SHIFT_MASK // 207 à I DIAERESIS +#define ISO_8859_1_D0 0 // 208 à ETH +#define ISO_8859_1_D1 TILDE_BITS + KEY_N + SHIFT_MASK // 209 Ñ N TILDE +#define ISO_8859_1_D2 GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK // 210 Ò O GRAVE +#define ISO_8859_1_D3 ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK // 211 Ó O ACUTE +#define ISO_8859_1_D4 CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK // 212 Ô O CIRCUMFLEX +#define ISO_8859_1_D5 TILDE_BITS + KEY_O + SHIFT_MASK // 213 Õ O TILDE +#define ISO_8859_1_D6 DIAERESIS_BITS + KEY_O + SHIFT_MASK // 214 Ö O DIAERESIS +#define ISO_8859_1_D7 0 // 215 × MULTIPLICATION +#define ISO_8859_1_D8 0 // 216 Ø O STROKE +#define ISO_8859_1_D9 GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK // 217 Ù U GRAVE +#define ISO_8859_1_DA ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK // 218 Ú U ACUTE +#define ISO_8859_1_DB CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK // 219 Û U CIRCUMFLEX +#define ISO_8859_1_DC DIAERESIS_BITS + KEY_U // 220 Ü U DIAERESIS +#define ISO_8859_1_DD ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK // 221 à Y ACUTE +#define ISO_8859_1_DE 0 // 222 Þ THORN +#define ISO_8859_1_DF 0 // 223 ß SHARP S +#define ISO_8859_1_E0 KEY_0 // 224 à a GRAVE +#define ISO_8859_1_E1 ACUTE_ACCENT_BITS + KEY_Q // 225 á a ACUTE +#define ISO_8859_1_E2 CIRCUMFLEX_BITS + KEY_Q // 226 â a CIRCUMFLEX +#define ISO_8859_1_E3 TILDE_BITS + KEY_Q // 227 ã a TILDE +#define ISO_8859_1_E4 DIAERESIS_BITS + KEY_Q // 228 ä a DIAERESIS +#define ISO_8859_1_E5 0 // 229 å a RING ABOVE +#define ISO_8859_1_E6 0 // 230 æ ae +#define ISO_8859_1_E7 KEY_9 // 231 ç c CEDILLA +#define ISO_8859_1_E8 KEY_7 // 232 è e GRAVE +#define ISO_8859_1_E9 KEY_2 // 233 é e ACUTE +#define ISO_8859_1_EA CIRCUMFLEX_BITS + KEY_E // 234 ê e CIRCUMFLEX +#define ISO_8859_1_EB DIAERESIS_BITS + KEY_E // 235 ë e DIAERESIS +#define ISO_8859_1_EC GRAVE_ACCENT_BITS + KEY_I // 236 ì i GRAVE +#define ISO_8859_1_ED ACUTE_ACCENT_BITS + KEY_I // 237 à i ACUTE +#define ISO_8859_1_EE CIRCUMFLEX_BITS + KEY_I // 238 î i CIRCUMFLEX +#define ISO_8859_1_EF DIAERESIS_BITS + KEY_I // 239 ï i DIAERESIS +#define ISO_8859_1_F0 0 // 240 ð ETH +#define ISO_8859_1_F1 TILDE_BITS + KEY_N // 241 ñ n TILDE +#define ISO_8859_1_F2 GRAVE_ACCENT_BITS + KEY_O // 242 ò o GRAVE +#define ISO_8859_1_F3 ACUTE_ACCENT_BITS + KEY_O // 243 ó o ACUTE +#define ISO_8859_1_F4 CIRCUMFLEX_BITS + KEY_O // 244 ô o CIRCUMFLEX +#define ISO_8859_1_F5 TILDE_BITS + KEY_O // 245 õ o TILDE +#define ISO_8859_1_F6 DIAERESIS_BITS + KEY_O // 246 ö o DIAERESIS +#define ISO_8859_1_F7 0 // 247 ÷ DIVISION +#define ISO_8859_1_F8 0 // 248 ø o STROKE +#define ISO_8859_1_F9 KEY_QUOTE // 249 ù u GRAVE - TODO; check FRENCH +#define ISO_8859_1_FA ACUTE_ACCENT_BITS + KEY_U // 250 ú u ACUTE +#define ISO_8859_1_FB CIRCUMFLEX_BITS + KEY_U // 251 û u CIRCUMFLEX +#define ISO_8859_1_FC DIAERESIS_BITS + KEY_U // 252 ü u DIAERESIS +#define ISO_8859_1_FD ACUTE_ACCENT_BITS + KEY_Y // 253 ý y ACUTE +#define ISO_8859_1_FE 0 // 254 þ THORN +#define ISO_8859_1_FF DIAERESIS_BITS + KEY_Y // 255 ÿ y DIAERESIS +#define UNICODE_20AC KEY_E + ALTGR_MASK // € Euro Sign +// not yet implemented +#define UNICODE_EXTRA00 0x20AC +#define KEYCODE_EXTRA00 KEY_E + ALTGR_MASK // 20AC € Euro Sign + +#endif // LAYOUT_FRENCH_BELGIAN + + + + +#ifdef LAYOUT_GERMAN_SWISS + +#define SHIFT_MASK 0x0040 +#define ALTGR_MASK 0x0080 +#define DEADKEYS_MASK 0x0700 +#define CIRCUMFLEX_BITS 0x0100 +#define GRAVE_ACCENT_BITS 0x0200 +#define DIAERESIS_BITS 0x0300 +#define TILDE_BITS 0x0400 +#define ACUTE_ACCENT_BITS 0x0500 +#define KEYCODE_TYPE uint16_t +#define DEADKEY_CIRCUMFLEX KEY_EQUAL +#define DEADKEY_ACUTE_ACCENT KEY_MINUS + ALTGR_MASK +#define DEADKEY_GRAVE_ACCENT KEY_EQUAL + SHIFT_MASK +#define DEADKEY_DIAERESIS KEY_RIGHT_BRACE +#define DEADKEY_TILDE KEY_EQUAL + ALTGR_MASK +#define KEY_NON_US_100 63 + +#define ASCII_20 KEY_SPACE // 32 +#define ASCII_21 KEY_RIGHT_BRACE + SHIFT_MASK // 33 ! +#define ASCII_22 KEY_2 + SHIFT_MASK // 34 " +#define ASCII_23 KEY_3 + ALTGR_MASK // 35 # +#define ASCII_24 KEY_BACKSLASH // 36 $ +#define ASCII_25 KEY_5 + SHIFT_MASK // 37 % +#define ASCII_26 KEY_6 + SHIFT_MASK // 38 & +#define ASCII_27 KEY_MINUS // 39 ' +#define ASCII_28 KEY_8 + SHIFT_MASK // 40 ( +#define ASCII_29 KEY_9 + SHIFT_MASK // 41 ) +#define ASCII_2A KEY_3 + SHIFT_MASK // 42 * +#define ASCII_2B KEY_1 + SHIFT_MASK // 43 + +#define ASCII_2C KEY_COMMA // 44 , +#define ASCII_2D KEY_SLASH // 45 - +#define ASCII_2E KEY_PERIOD // 46 . +#define ASCII_2F KEY_7 + SHIFT_MASK // 47 / +#define ASCII_30 KEY_0 // 48 0 +#define ASCII_31 KEY_1 // 49 1 +#define ASCII_32 KEY_2 // 50 2 +#define ASCII_33 KEY_3 // 51 3 +#define ASCII_34 KEY_4 // 52 4 +#define ASCII_35 KEY_5 // 53 5 +#define ASCII_36 KEY_6 // 54 6 +#define ASCII_37 KEY_7 // 55 7 +#define ASCII_38 KEY_8 // 55 8 +#define ASCII_39 KEY_9 // 57 9 +#define ASCII_3A KEY_PERIOD + SHIFT_MASK // 58 : +#define ASCII_3B KEY_COMMA + SHIFT_MASK // 59 ; +#define ASCII_3C KEY_NON_US_100 // 60 < +#define ASCII_3D KEY_0 + SHIFT_MASK // 61 = +#define ASCII_3E KEY_NON_US_100 + SHIFT_MASK // 62 > +#define ASCII_3F KEY_MINUS + SHIFT_MASK // 63 ? +#define ASCII_40 KEY_2 + ALTGR_MASK // 64 @ +#define ASCII_41 KEY_A + SHIFT_MASK // 65 A +#define ASCII_42 KEY_B + SHIFT_MASK // 66 B +#define ASCII_43 KEY_C + SHIFT_MASK // 67 C +#define ASCII_44 KEY_D + SHIFT_MASK // 68 D +#define ASCII_45 KEY_E + SHIFT_MASK // 69 E +#define ASCII_46 KEY_F + SHIFT_MASK // 70 F +#define ASCII_47 KEY_G + SHIFT_MASK // 71 G +#define ASCII_48 KEY_H + SHIFT_MASK // 72 H +#define ASCII_49 KEY_I + SHIFT_MASK // 73 I +#define ASCII_4A KEY_J + SHIFT_MASK // 74 J +#define ASCII_4B KEY_K + SHIFT_MASK // 75 K +#define ASCII_4C KEY_L + SHIFT_MASK // 76 L +#define ASCII_4D KEY_M + SHIFT_MASK // 77 M +#define ASCII_4E KEY_N + SHIFT_MASK // 78 N +#define ASCII_4F KEY_O + SHIFT_MASK // 79 O +#define ASCII_50 KEY_P + SHIFT_MASK // 80 P +#define ASCII_51 KEY_Q + SHIFT_MASK // 81 Q +#define ASCII_52 KEY_R + SHIFT_MASK // 82 R +#define ASCII_53 KEY_S + SHIFT_MASK // 83 S +#define ASCII_54 KEY_T + SHIFT_MASK // 84 T +#define ASCII_55 KEY_U + SHIFT_MASK // 85 U +#define ASCII_56 KEY_V + SHIFT_MASK // 86 V +#define ASCII_57 KEY_W + SHIFT_MASK // 87 W +#define ASCII_58 KEY_X + SHIFT_MASK // 88 X +#define ASCII_59 KEY_Z + SHIFT_MASK // 89 Y +#define ASCII_5A KEY_Y + SHIFT_MASK // 90 Z +#define ASCII_5B KEY_LEFT_BRACE + ALTGR_MASK // 91 [ +#define ASCII_5C KEY_NON_US_100 + ALTGR_MASK // 92 +#define ASCII_5D KEY_RIGHT_BRACE + ALTGR_MASK // 93 ] +#define ASCII_5E CIRCUMFLEX_BITS + KEY_SPACE // 94 ^ +#define ASCII_5F KEY_SLASH + SHIFT_MASK // 95 _ +#define ASCII_60 GRAVE_ACCENT_BITS + KEY_SPACE // 96 ` +#define ASCII_61 KEY_A // 97 a +#define ASCII_62 KEY_B // 98 b +#define ASCII_63 KEY_C // 99 c +#define ASCII_64 KEY_D // 100 d +#define ASCII_65 KEY_E // 101 e +#define ASCII_66 KEY_F // 102 f +#define ASCII_67 KEY_G // 103 g +#define ASCII_68 KEY_H // 104 h +#define ASCII_69 KEY_I // 105 i +#define ASCII_6A KEY_J // 106 j +#define ASCII_6B KEY_K // 107 k +#define ASCII_6C KEY_L // 108 l +#define ASCII_6D KEY_M // 109 m +#define ASCII_6E KEY_N // 110 n +#define ASCII_6F KEY_O // 111 o +#define ASCII_70 KEY_P // 112 p +#define ASCII_71 KEY_Q // 113 q +#define ASCII_72 KEY_R // 114 r +#define ASCII_73 KEY_S // 115 s +#define ASCII_74 KEY_T // 116 t +#define ASCII_75 KEY_U // 117 u +#define ASCII_76 KEY_V // 118 v +#define ASCII_77 KEY_W // 119 w +#define ASCII_78 KEY_X // 120 x +#define ASCII_79 KEY_Z // 121 y +#define ASCII_7A KEY_Y // 122 z +#define ASCII_7B KEY_QUOTE + ALTGR_MASK // 123 { +#define ASCII_7C KEY_7 + ALTGR_MASK // 124 | +#define ASCII_7D KEY_BACKSLASH + ALTGR_MASK // 125 } +#define ASCII_7E TILDE_BITS + KEY_SPACE // 126 ~ +#define ASCII_7F KEY_BACKSPACE // 127 +#define ISO_8859_1_A0 KEY_SPACE // 160 Nonbreakng Space +#define ISO_8859_1_A1 0 // 161 ¡ Inverted Exclamation +#define ISO_8859_1_A2 KEY_8 + ALTGR_MASK // 162 ¢ Cent Sign +#define ISO_8859_1_A3 KEY_BACKSLASH + SHIFT_MASK // 163 £ Pound Sign +#define ISO_8859_1_A4 0 // 164 ¤ Currency Sign +#define ISO_8859_1_A5 0 // 165 ¥ YEN SIGN +#define ISO_8859_1_A6 KEY_1 + ALTGR_MASK // 166 ¦ BROKEN BAR +#define ISO_8859_1_A7 KEY_5 + ALTGR_MASK // 167 § SECTION SIGN +#define ISO_8859_1_A8 DIAERESIS_BITS + KEY_SPACE // 168 ¨ DIAERESIS +#define ISO_8859_1_A9 0 // 169 © COPYRIGHT SIGN +#define ISO_8859_1_AA 0 // 170 ª FEMININE ORDINAL +#define ISO_8859_1_AB 0 // 171 « LEFT DOUBLE ANGLE QUOTE +#define ISO_8859_1_AC KEY_6 + ALTGR_MASK // 172 ¬ NOT SIGN +#define ISO_8859_1_AD 0 // 173 SOFT HYPHEN +#define ISO_8859_1_AE 0 // 174 ® REGISTERED SIGN +#define ISO_8859_1_AF 0 // 175 ¯ MACRON +#define ISO_8859_1_B0 KEY_4 + ALTGR_MASK // 176 ° DEGREE SIGN +#define ISO_8859_1_B1 0 // 177 ± PLUS-MINUS SIGN +#define ISO_8859_1_B2 0 // 178 ² SUPERSCRIPT TWO +#define ISO_8859_1_B3 0 // 179 ³ SUPERSCRIPT THREE +#define ISO_8859_1_B4 ACUTE_ACCENT_BITS + KEY_SPACE // 180 ´ ACUTE ACCENT +#define ISO_8859_1_B5 0 // 181 µ MICRO SIGN +#define ISO_8859_1_B6 0 // 182 ¶ PILCROW SIGN +#define ISO_8859_1_B7 0 // 183 · MIDDLE DOT +#define ISO_8859_1_B8 0 // 184 ¸ CEDILLA +#define ISO_8859_1_B9 0 // 185 ¹ SUPERSCRIPT ONE +#define ISO_8859_1_BA 0 // 186 º MASCULINE ORDINAL +#define ISO_8859_1_BB 0 // 187 » RIGHT DOUBLE ANGLE QUOTE +#define ISO_8859_1_BC 0 // 188 ¼ FRACTION ONE QUARTER +#define ISO_8859_1_BD 0 // 189 ½ FRACTION ONE HALF +#define ISO_8859_1_BE 0 // 190 ¾ FRACTION THREE QUARTERS +#define ISO_8859_1_BF 0 // 191 ¿ INVERTED QUESTION MARK +#define ISO_8859_1_C0 GRAVE_ACCENT_BITS + KEY_A + SHIFT_MASK // 192 À A GRAVE +#define ISO_8859_1_C1 ACUTE_ACCENT_BITS + KEY_A + SHIFT_MASK // 193 à A ACUTE +#define ISO_8859_1_C2 CIRCUMFLEX_BITS + KEY_A + SHIFT_MASK // 194 Â A CIRCUMFLEX +#define ISO_8859_1_C3 TILDE_BITS + KEY_A + SHIFT_MASK // 195 Ã A TILDE +#define ISO_8859_1_C4 DIAERESIS_BITS + KEY_A + SHIFT_MASK // 196 Ä A DIAERESIS +#define ISO_8859_1_C5 0 // 197 Å A RING ABOVE +#define ISO_8859_1_C6 0 // 198 Æ AE +#define ISO_8859_1_C7 0 // 199 Ç C CEDILLA +#define ISO_8859_1_C8 GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK // 200 È E GRAVE +#define ISO_8859_1_C9 ACUTE_ACCENT_BITS + KEY_E + SHIFT_MASK // 201 É E ACUTE +#define ISO_8859_1_CA CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK // 202 Ê E CIRCUMFLEX +#define ISO_8859_1_CB DIAERESIS_BITS + KEY_E + SHIFT_MASK // 203 Ë E DIAERESIS +#define ISO_8859_1_CC GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK // 204 Ì I GRAVE +#define ISO_8859_1_CD ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK // 205 à I ACUTE +#define ISO_8859_1_CE CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK // 206 Î I CIRCUMFLEX +#define ISO_8859_1_CF DIAERESIS_BITS + KEY_I + SHIFT_MASK // 207 à I DIAERESIS +#define ISO_8859_1_D0 0 // 208 à ETH +#define ISO_8859_1_D1 TILDE_BITS + KEY_N + SHIFT_MASK // 209 Ñ N TILDE +#define ISO_8859_1_D2 GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK // 210 Ò O GRAVE +#define ISO_8859_1_D3 ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK // 211 Ó O ACUTE +#define ISO_8859_1_D4 CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK // 212 Ô O CIRCUMFLEX +#define ISO_8859_1_D5 TILDE_BITS + KEY_O + SHIFT_MASK // 213 Õ O TILDE +#define ISO_8859_1_D6 DIAERESIS_BITS + KEY_O + SHIFT_MASK // 214 Ö O DIAERESIS +#define ISO_8859_1_D7 0 // 215 × MULTIPLICATION +#define ISO_8859_1_D8 0 // 216 Ø O STROKE +#define ISO_8859_1_D9 GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK // 217 Ù U GRAVE +#define ISO_8859_1_DA ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK // 218 Ú U ACUTE +#define ISO_8859_1_DB CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK // 219 Û U CIRCUMFLEX +#define ISO_8859_1_DC DIAERESIS_BITS + KEY_U + SHIFT_MASK // 220 Ü U DIAERESIS +#define ISO_8859_1_DD ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK // 221 à Y ACUTE +#define ISO_8859_1_DE 0 // 222 Þ THORN +#define ISO_8859_1_DF 0 // 223 ß SHARP S +#define ISO_8859_1_E0 KEY_QUOTE + SHIFT_MASK // 224 à a GRAVE +#define ISO_8859_1_E1 ACUTE_ACCENT_BITS + KEY_A // 225 á a ACUTE +#define ISO_8859_1_E2 CIRCUMFLEX_BITS + KEY_A // 226 â a CIRCUMFLEX +#define ISO_8859_1_E3 TILDE_BITS + KEY_A // 227 ã a TILDE +#define ISO_8859_1_E4 KEY_QUOTE // 228 ä a DIAERESIS +#define ISO_8859_1_E5 0 // 229 å a RING ABOVE +#define ISO_8859_1_E6 0 // 230 æ ae +#define ISO_8859_1_E7 KEY_4 + SHIFT_MASK // 231 ç c CEDILLA +#define ISO_8859_1_E8 KEY_LEFT_BRACE + SHIFT_MASK // 232 è e GRAVE +#define ISO_8859_1_E9 KEY_SEMICOLON + SHIFT_MASK // 233 é e ACUTE +#define ISO_8859_1_EA CIRCUMFLEX_BITS + KEY_E // 234 ê e CIRCUMFLEX +#define ISO_8859_1_EB DIAERESIS_BITS + KEY_E // 235 ë e DIAERESIS TODO: check this +#define ISO_8859_1_EC GRAVE_ACCENT_BITS + KEY_I // 236 ì i GRAVE +#define ISO_8859_1_ED ACUTE_ACCENT_BITS + KEY_I // 237 à i ACUTE +#define ISO_8859_1_EE CIRCUMFLEX_BITS + KEY_I // 238 î i CIRCUMFLEX +#define ISO_8859_1_EF DIAERESIS_BITS + KEY_I // 239 ï i DIAERESIS +#define ISO_8859_1_F0 0 // 240 ð ETH +#define ISO_8859_1_F1 TILDE_BITS + KEY_N // 241 ñ n TILDE +#define ISO_8859_1_F2 GRAVE_ACCENT_BITS + KEY_O // 242 ò o GRAVE +#define ISO_8859_1_F3 ACUTE_ACCENT_BITS + KEY_O // 243 ó o ACUTE +#define ISO_8859_1_F4 CIRCUMFLEX_BITS + KEY_O // 244 ô o CIRCUMFLEX +#define ISO_8859_1_F5 TILDE_BITS + KEY_O // 245 õ o TILDE +#define ISO_8859_1_F6 KEY_SEMICOLON // 246 ö o DIAERESIS +#define ISO_8859_1_F7 0 // 247 ÷ DIVISION +#define ISO_8859_1_F8 0 // 248 ø o STROKE +#define ISO_8859_1_F9 GRAVE_ACCENT_BITS + KEY_U // 249 ù u GRAVE +#define ISO_8859_1_FA ACUTE_ACCENT_BITS + KEY_U // 250 ú u ACUTE +#define ISO_8859_1_FB CIRCUMFLEX_BITS + KEY_U // 251 û u CIRCUMFLEX +#define ISO_8859_1_FC KEY_LEFT_BRACE // 252 ü u DIAERESIS +#define ISO_8859_1_FD ACUTE_ACCENT_BITS + KEY_Y // 253 ý y ACUTE +#define ISO_8859_1_FE 0 // 254 þ THORN +#define ISO_8859_1_FF DIAERESIS_BITS + KEY_Y // 255 ÿ y DIAERESIS +#define UNICODE_20AC KEY_E + ALTGR_MASK // € Euro Sign +// not yet implemented +#define UNICODE_EXTRA00 0x20AC +#define KEYCODE_EXTRA00 KEY_E + ALTGR_MASK // 20AC € Euro Sign + +#endif // LAYOUT_GERMAN_SWISS + + + + +#ifdef LAYOUT_FRENCH_SWISS + +#define SHIFT_MASK 0x0040 +#define ALTGR_MASK 0x0080 +#define DEADKEYS_MASK 0x0700 +#define CIRCUMFLEX_BITS 0x0100 +#define GRAVE_ACCENT_BITS 0x0200 +#define DIAERESIS_BITS 0x0300 +#define TILDE_BITS 0x0400 +#define ACUTE_ACCENT_BITS 0x0500 +#define KEYCODE_TYPE uint16_t +#define DEADKEY_CIRCUMFLEX KEY_EQUAL +#define DEADKEY_ACUTE_ACCENT KEY_MINUS + ALTGR_MASK +#define DEADKEY_GRAVE_ACCENT KEY_EQUAL + SHIFT_MASK +#define DEADKEY_DIAERESIS KEY_RIGHT_BRACE +#define DEADKEY_TILDE KEY_EQUAL + ALTGR_MASK +#define KEY_NON_US_100 63 + +#define ASCII_20 KEY_SPACE // 32 +#define ASCII_21 KEY_RIGHT_BRACE + SHIFT_MASK // 33 ! +#define ASCII_22 KEY_2 + SHIFT_MASK // 34 " +#define ASCII_23 KEY_3 + ALTGR_MASK // 35 # +#define ASCII_24 KEY_BACKSLASH // 36 $ +#define ASCII_25 KEY_5 + SHIFT_MASK // 37 % +#define ASCII_26 KEY_6 + SHIFT_MASK // 38 & +#define ASCII_27 KEY_MINUS // 39 ' +#define ASCII_28 KEY_8 + SHIFT_MASK // 40 ( +#define ASCII_29 KEY_9 + SHIFT_MASK // 41 ) +#define ASCII_2A KEY_3 + SHIFT_MASK // 42 * +#define ASCII_2B KEY_1 + SHIFT_MASK // 43 + +#define ASCII_2C KEY_COMMA // 44 , +#define ASCII_2D KEY_SLASH // 45 - +#define ASCII_2E KEY_PERIOD // 46 . +#define ASCII_2F KEY_7 + SHIFT_MASK // 47 / +#define ASCII_30 KEY_0 // 48 0 +#define ASCII_31 KEY_1 // 49 1 +#define ASCII_32 KEY_2 // 50 2 +#define ASCII_33 KEY_3 // 51 3 +#define ASCII_34 KEY_4 // 52 4 +#define ASCII_35 KEY_5 // 53 5 +#define ASCII_36 KEY_6 // 54 6 +#define ASCII_37 KEY_7 // 55 7 +#define ASCII_38 KEY_8 // 55 8 +#define ASCII_39 KEY_9 // 57 9 +#define ASCII_3A KEY_PERIOD + SHIFT_MASK // 58 : +#define ASCII_3B KEY_COMMA + SHIFT_MASK // 59 ; +#define ASCII_3C KEY_NON_US_100 // 60 < +#define ASCII_3D KEY_0 + SHIFT_MASK // 61 = +#define ASCII_3E KEY_NON_US_100 + SHIFT_MASK // 62 > +#define ASCII_3F KEY_MINUS + SHIFT_MASK // 63 ? +#define ASCII_40 KEY_2 + ALTGR_MASK // 64 @ +#define ASCII_41 KEY_A + SHIFT_MASK // 65 A +#define ASCII_42 KEY_B + SHIFT_MASK // 66 B +#define ASCII_43 KEY_C + SHIFT_MASK // 67 C +#define ASCII_44 KEY_D + SHIFT_MASK // 68 D +#define ASCII_45 KEY_E + SHIFT_MASK // 69 E +#define ASCII_46 KEY_F + SHIFT_MASK // 70 F +#define ASCII_47 KEY_G + SHIFT_MASK // 71 G +#define ASCII_48 KEY_H + SHIFT_MASK // 72 H +#define ASCII_49 KEY_I + SHIFT_MASK // 73 I +#define ASCII_4A KEY_J + SHIFT_MASK // 74 J +#define ASCII_4B KEY_K + SHIFT_MASK // 75 K +#define ASCII_4C KEY_L + SHIFT_MASK // 76 L +#define ASCII_4D KEY_M + SHIFT_MASK // 77 M +#define ASCII_4E KEY_N + SHIFT_MASK // 78 N +#define ASCII_4F KEY_O + SHIFT_MASK // 79 O +#define ASCII_50 KEY_P + SHIFT_MASK // 80 P +#define ASCII_51 KEY_Q + SHIFT_MASK // 81 Q +#define ASCII_52 KEY_R + SHIFT_MASK // 82 R +#define ASCII_53 KEY_S + SHIFT_MASK // 83 S +#define ASCII_54 KEY_T + SHIFT_MASK // 84 T +#define ASCII_55 KEY_U + SHIFT_MASK // 85 U +#define ASCII_56 KEY_V + SHIFT_MASK // 86 V +#define ASCII_57 KEY_W + SHIFT_MASK // 87 W +#define ASCII_58 KEY_X + SHIFT_MASK // 88 X +#define ASCII_59 KEY_Z + SHIFT_MASK // 89 Y +#define ASCII_5A KEY_Y + SHIFT_MASK // 90 Z +#define ASCII_5B KEY_LEFT_BRACE + ALTGR_MASK // 91 [ +#define ASCII_5C KEY_NON_US_100 + ALTGR_MASK // 92 +#define ASCII_5D KEY_RIGHT_BRACE + ALTGR_MASK // 93 ] +#define ASCII_5E CIRCUMFLEX_BITS + KEY_SPACE // 94 ^ +#define ASCII_5F KEY_SLASH + SHIFT_MASK // 95 _ +#define ASCII_60 GRAVE_ACCENT_BITS + KEY_SPACE // 96 ` +#define ASCII_61 KEY_A // 97 a +#define ASCII_62 KEY_B // 98 b +#define ASCII_63 KEY_C // 99 c +#define ASCII_64 KEY_D // 100 d +#define ASCII_65 KEY_E // 101 e +#define ASCII_66 KEY_F // 102 f +#define ASCII_67 KEY_G // 103 g +#define ASCII_68 KEY_H // 104 h +#define ASCII_69 KEY_I // 105 i +#define ASCII_6A KEY_J // 106 j +#define ASCII_6B KEY_K // 107 k +#define ASCII_6C KEY_L // 108 l +#define ASCII_6D KEY_M // 109 m +#define ASCII_6E KEY_N // 110 n +#define ASCII_6F KEY_O // 111 o +#define ASCII_70 KEY_P // 112 p +#define ASCII_71 KEY_Q // 113 q +#define ASCII_72 KEY_R // 114 r +#define ASCII_73 KEY_S // 115 s +#define ASCII_74 KEY_T // 116 t +#define ASCII_75 KEY_U // 117 u +#define ASCII_76 KEY_V // 118 v +#define ASCII_77 KEY_W // 119 w +#define ASCII_78 KEY_X // 120 x +#define ASCII_79 KEY_Z // 121 y +#define ASCII_7A KEY_Y // 122 z +#define ASCII_7B KEY_QUOTE + ALTGR_MASK // 123 { +#define ASCII_7C KEY_7 + ALTGR_MASK // 124 | +#define ASCII_7D KEY_BACKSLASH + ALTGR_MASK // 125 } +#define ASCII_7E TILDE_BITS + KEY_SPACE // 126 ~ +#define ASCII_7F KEY_BACKSPACE // 127 +#define ISO_8859_1_A0 KEY_SPACE // 160 Nonbreakng Space +#define ISO_8859_1_A1 0 // 161 ¡ Inverted Exclamation +#define ISO_8859_1_A2 KEY_8 + ALTGR_MASK // 162 ¢ Cent Sign +#define ISO_8859_1_A3 KEY_BACKSLASH + SHIFT_MASK // 163 £ Pound Sign +#define ISO_8859_1_A4 0 // 164 ¤ Currency Sign +#define ISO_8859_1_A5 0 // 165 ¥ YEN SIGN +#define ISO_8859_1_A6 KEY_1 + ALTGR_MASK // 166 ¦ BROKEN BAR +#define ISO_8859_1_A7 KEY_5 + ALTGR_MASK // 167 § SECTION SIGN +#define ISO_8859_1_A8 DIAERESIS_BITS + KEY_SPACE // 168 ¨ DIAERESIS +#define ISO_8859_1_A9 0 // 169 © COPYRIGHT SIGN +#define ISO_8859_1_AA 0 // 170 ª FEMININE ORDINAL +#define ISO_8859_1_AB 0 // 171 « LEFT DOUBLE ANGLE QUOTE +#define ISO_8859_1_AC KEY_6 + ALTGR_MASK // 172 ¬ NOT SIGN +#define ISO_8859_1_AD 0 // 173 SOFT HYPHEN +#define ISO_8859_1_AE 0 // 174 ® REGISTERED SIGN +#define ISO_8859_1_AF 0 // 175 ¯ MACRON +#define ISO_8859_1_B0 KEY_4 + ALTGR_MASK // 176 ° DEGREE SIGN +#define ISO_8859_1_B1 0 // 177 ± PLUS-MINUS SIGN +#define ISO_8859_1_B2 0 // 178 ² SUPERSCRIPT TWO +#define ISO_8859_1_B3 0 // 179 ³ SUPERSCRIPT THREE +#define ISO_8859_1_B4 ACUTE_ACCENT_BITS + KEY_SPACE // 180 ´ ACUTE ACCENT +#define ISO_8859_1_B5 0 // 181 µ MICRO SIGN +#define ISO_8859_1_B6 0 // 182 ¶ PILCROW SIGN +#define ISO_8859_1_B7 0 // 183 · MIDDLE DOT +#define ISO_8859_1_B8 0 // 184 ¸ CEDILLA +#define ISO_8859_1_B9 0 // 185 ¹ SUPERSCRIPT ONE +#define ISO_8859_1_BA 0 // 186 º MASCULINE ORDINAL +#define ISO_8859_1_BB 0 // 187 » RIGHT DOUBLE ANGLE QUOTE +#define ISO_8859_1_BC 0 // 188 ¼ FRACTION ONE QUARTER +#define ISO_8859_1_BD 0 // 189 ½ FRACTION ONE HALF +#define ISO_8859_1_BE 0 // 190 ¾ FRACTION THREE QUARTERS +#define ISO_8859_1_BF 0 // 191 ¿ INVERTED QUESTION MARK +#define ISO_8859_1_C0 GRAVE_ACCENT_BITS + KEY_A + SHIFT_MASK // 192 À A GRAVE +#define ISO_8859_1_C1 ACUTE_ACCENT_BITS + KEY_A + SHIFT_MASK // 193 à A ACUTE +#define ISO_8859_1_C2 CIRCUMFLEX_BITS + KEY_A + SHIFT_MASK // 194 Â A CIRCUMFLEX +#define ISO_8859_1_C3 TILDE_BITS + KEY_A + SHIFT_MASK // 195 Ã A TILDE +#define ISO_8859_1_C4 DIAERESIS_BITS + KEY_A + SHIFT_MASK // 196 Ä A DIAERESIS +#define ISO_8859_1_C5 0 // 197 Å A RING ABOVE +#define ISO_8859_1_C6 0 // 198 Æ AE +#define ISO_8859_1_C7 0 // 199 Ç C CEDILLA +#define ISO_8859_1_C8 GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK // 200 È E GRAVE +#define ISO_8859_1_C9 ACUTE_ACCENT_BITS + KEY_E + SHIFT_MASK // 201 É E ACUTE +#define ISO_8859_1_CA CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK // 202 Ê E CIRCUMFLEX +#define ISO_8859_1_CB DIAERESIS_BITS + KEY_E + SHIFT_MASK // 203 Ë E DIAERESIS +#define ISO_8859_1_CC GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK // 204 Ì I GRAVE +#define ISO_8859_1_CD ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK // 205 à I ACUTE +#define ISO_8859_1_CE CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK // 206 Î I CIRCUMFLEX +#define ISO_8859_1_CF DIAERESIS_BITS + KEY_I + SHIFT_MASK // 207 à I DIAERESIS +#define ISO_8859_1_D0 0 // 208 à ETH +#define ISO_8859_1_D1 TILDE_BITS + KEY_N + SHIFT_MASK // 209 Ñ N TILDE +#define ISO_8859_1_D2 GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK // 210 Ò O GRAVE +#define ISO_8859_1_D3 ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK // 211 Ó O ACUTE +#define ISO_8859_1_D4 CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK // 212 Ô O CIRCUMFLEX +#define ISO_8859_1_D5 TILDE_BITS + KEY_O + SHIFT_MASK // 213 Õ O TILDE +#define ISO_8859_1_D6 DIAERESIS_BITS + KEY_O + SHIFT_MASK // 214 Ö O DIAERESIS +#define ISO_8859_1_D7 0 // 215 × MULTIPLICATION +#define ISO_8859_1_D8 0 // 216 Ø O STROKE +#define ISO_8859_1_D9 GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK // 217 Ù U GRAVE +#define ISO_8859_1_DA ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK // 218 Ú U ACUTE +#define ISO_8859_1_DB CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK // 219 Û U CIRCUMFLEX +#define ISO_8859_1_DC DIAERESIS_BITS + KEY_U + SHIFT_MASK // 220 Ü U DIAERESIS +#define ISO_8859_1_DD ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK // 221 à Y ACUTE +#define ISO_8859_1_DE 0 // 222 Þ THORN +#define ISO_8859_1_DF 0 // 223 ß SHARP S +#define ISO_8859_1_E0 KEY_QUOTE // 224 à a GRAVE +#define ISO_8859_1_E1 ACUTE_ACCENT_BITS + KEY_A // 225 á a ACUTE +#define ISO_8859_1_E2 CIRCUMFLEX_BITS + KEY_A // 226 â a CIRCUMFLEX +#define ISO_8859_1_E3 TILDE_BITS + KEY_A // 227 ã a TILDE +#define ISO_8859_1_E4 KEY_QUOTE + SHIFT_MASK // 228 ä a DIAERESIS +#define ISO_8859_1_E5 0 // 229 å a RING ABOVE +#define ISO_8859_1_E6 0 // 230 æ ae +#define ISO_8859_1_E7 KEY_4 + SHIFT_MASK // 231 ç c CEDILLA +#define ISO_8859_1_E8 KEY_LEFT_BRACE // 232 è e GRAVE +#define ISO_8859_1_E9 KEY_SEMICOLON // 233 é e ACUTE +#define ISO_8859_1_EA CIRCUMFLEX_BITS + KEY_E // 234 ê e CIRCUMFLEX +#define ISO_8859_1_EB DIAERESIS_BITS + KEY_E // 235 ë e DIAERESIS +#define ISO_8859_1_EC GRAVE_ACCENT_BITS + KEY_I // 236 ì i GRAVE +#define ISO_8859_1_ED ACUTE_ACCENT_BITS + KEY_I // 237 à i ACUTE +#define ISO_8859_1_EE CIRCUMFLEX_BITS + KEY_I // 238 î i CIRCUMFLEX +#define ISO_8859_1_EF DIAERESIS_BITS + KEY_I // 239 ï i DIAERESIS +#define ISO_8859_1_F0 0 // 240 ð ETH +#define ISO_8859_1_F1 TILDE_BITS + KEY_N // 241 ñ n TILDE +#define ISO_8859_1_F2 GRAVE_ACCENT_BITS + KEY_O // 242 ò o GRAVE +#define ISO_8859_1_F3 ACUTE_ACCENT_BITS + KEY_O // 243 ó o ACUTE +#define ISO_8859_1_F4 CIRCUMFLEX_BITS + KEY_O // 244 ô o CIRCUMFLEX +#define ISO_8859_1_F5 TILDE_BITS + KEY_O // 245 õ o TILDE +#define ISO_8859_1_F6 KEY_SEMICOLON + SHIFT_MASK // 246 ö o DIAERESIS +#define ISO_8859_1_F7 0 // 247 ÷ DIVISION +#define ISO_8859_1_F8 0 // 248 ø o STROKE +#define ISO_8859_1_F9 GRAVE_ACCENT_BITS + KEY_U // 249 ù u GRAVE +#define ISO_8859_1_FA ACUTE_ACCENT_BITS + KEY_U // 250 ú u ACUTE +#define ISO_8859_1_FB CIRCUMFLEX_BITS + KEY_U // 251 û u CIRCUMFLEX +#define ISO_8859_1_FC KEY_LEFT_BRACE + SHIFT_MASK // 252 ü u DIAERESIS +#define ISO_8859_1_FD ACUTE_ACCENT_BITS + KEY_Y // 253 ý y ACUTE +#define ISO_8859_1_FE 0 // 254 þ THORN +#define ISO_8859_1_FF DIAERESIS_BITS + KEY_Y // 255 ÿ y DIAERESIS +#define UNICODE_20AC KEY_E + ALTGR_MASK // € Euro Sign +// not yet implemented +#define UNICODE_EXTRA00 0x20AC +#define KEYCODE_EXTRA00 KEY_E + ALTGR_MASK // 20AC € Euro Sign + +#endif // LAYOUT_FRENCH_SWISS + + + + + +#ifdef LAYOUT_SPANISH_LATIN_AMERICA + +#define SHIFT_MASK 0x0040 +#define ALTGR_MASK 0x0080 +#define DEADKEYS_MASK 0x0700 +#define CIRCUMFLEX_BITS 0x0100 +#define ACUTE_ACCENT_BITS 0x0200 +#define GRAVE_ACCENT_BITS 0x0300 +#define DIAERESIS_BITS 0x0400 +#define KEYCODE_TYPE uint16_t +#define DEADKEY_CIRCUMFLEX KEY_QUOTE + ALTGR_MASK +#define DEADKEY_ACUTE_ACCENT KEY_LEFT_BRACE +#define DEADKEY_GRAVE_ACCENT KEY_BACKSLASH + ALTGR_MASK +#define DEADKEY_DIAERESIS KEY_LEFT_BRACE + SHIFT_MASK +#define KEY_NON_US_100 63 + +#define ASCII_20 KEY_SPACE // 32 +#define ASCII_21 KEY_1 + SHIFT_MASK // 33 ! +#define ASCII_22 KEY_2 + SHIFT_MASK // 34 " +#define ASCII_23 KEY_3 + ALTGR_MASK // 35 # +#define ASCII_24 KEY_4 + SHIFT_MASK // 36 $ +#define ASCII_25 KEY_5 + SHIFT_MASK // 37 % +#define ASCII_26 KEY_6 + SHIFT_MASK // 38 & +#define ASCII_27 KEY_MINUS // 39 ' +#define ASCII_28 KEY_8 + SHIFT_MASK // 40 ( +#define ASCII_29 KEY_9 + SHIFT_MASK // 41 ) +#define ASCII_2A KEY_RIGHT_BRACE + SHIFT_MASK // 42 * +#define ASCII_2B KEY_RIGHT_BRACE // 43 + +#define ASCII_2C KEY_COMMA // 44 , +#define ASCII_2D KEY_SLASH // 45 - +#define ASCII_2E KEY_PERIOD // 46 . +#define ASCII_2F KEY_7 + SHIFT_MASK // 47 / +#define ASCII_30 KEY_0 // 48 0 +#define ASCII_31 KEY_1 // 49 1 +#define ASCII_32 KEY_2 // 50 2 +#define ASCII_33 KEY_3 // 51 3 +#define ASCII_34 KEY_4 // 52 4 +#define ASCII_35 KEY_5 // 53 5 +#define ASCII_36 KEY_6 // 54 6 +#define ASCII_37 KEY_7 // 55 7 +#define ASCII_38 KEY_8 // 55 8 +#define ASCII_39 KEY_9 // 57 9 +#define ASCII_3A KEY_PERIOD + SHIFT_MASK // 58 : +#define ASCII_3B KEY_COMMA + SHIFT_MASK // 59 ; +#define ASCII_3C KEY_NON_US_100 // 60 < +#define ASCII_3D KEY_0 + SHIFT_MASK // 61 = +#define ASCII_3E KEY_NON_US_100 + SHIFT_MASK // 62 > +#define ASCII_3F KEY_MINUS + SHIFT_MASK // 63 ? +#define ASCII_40 KEY_Q + ALTGR_MASK // 64 @ +#define ASCII_41 KEY_A + SHIFT_MASK // 65 A +#define ASCII_42 KEY_B + SHIFT_MASK // 66 B +#define ASCII_43 KEY_C + SHIFT_MASK // 67 C +#define ASCII_44 KEY_D + SHIFT_MASK // 68 D +#define ASCII_45 KEY_E + SHIFT_MASK // 69 E +#define ASCII_46 KEY_F + SHIFT_MASK // 70 F +#define ASCII_47 KEY_G + SHIFT_MASK // 71 G +#define ASCII_48 KEY_H + SHIFT_MASK // 72 H +#define ASCII_49 KEY_I + SHIFT_MASK // 73 I +#define ASCII_4A KEY_J + SHIFT_MASK // 74 J +#define ASCII_4B KEY_K + SHIFT_MASK // 75 K +#define ASCII_4C KEY_L + SHIFT_MASK // 76 L +#define ASCII_4D KEY_M + SHIFT_MASK // 77 M +#define ASCII_4E KEY_N + SHIFT_MASK // 78 N +#define ASCII_4F KEY_O + SHIFT_MASK // 79 O +#define ASCII_50 KEY_P + SHIFT_MASK // 80 P +#define ASCII_51 KEY_Q + SHIFT_MASK // 81 Q +#define ASCII_52 KEY_R + SHIFT_MASK // 82 R +#define ASCII_53 KEY_S + SHIFT_MASK // 83 S +#define ASCII_54 KEY_T + SHIFT_MASK // 84 T +#define ASCII_55 KEY_U + SHIFT_MASK // 85 U +#define ASCII_56 KEY_V + SHIFT_MASK // 86 V +#define ASCII_57 KEY_W + SHIFT_MASK // 87 W +#define ASCII_58 KEY_X + SHIFT_MASK // 88 X +#define ASCII_59 KEY_Y + SHIFT_MASK // 89 Y +#define ASCII_5A KEY_Z + SHIFT_MASK // 90 Z +#define ASCII_5B KEY_QUOTE + SHIFT_MASK // 91 [ +#define ASCII_5C KEY_MINUS + ALTGR_MASK // 92 +#define ASCII_5D KEY_BACKSLASH + SHIFT_MASK // 93 ] +#define ASCII_5E CIRCUMFLEX_BITS + KEY_SPACE // 94 ^ +#define ASCII_5F KEY_SLASH + SHIFT_MASK // 95 _ +#define ASCII_60 GRAVE_ACCENT_BITS + KEY_SPACE // 96 ` +#define ASCII_61 KEY_A // 97 a +#define ASCII_62 KEY_B // 98 b +#define ASCII_63 KEY_C // 99 c +#define ASCII_64 KEY_D // 100 d +#define ASCII_65 KEY_E // 101 e +#define ASCII_66 KEY_F // 102 f +#define ASCII_67 KEY_G // 103 g +#define ASCII_68 KEY_H // 104 h +#define ASCII_69 KEY_I // 105 i +#define ASCII_6A KEY_J // 106 j +#define ASCII_6B KEY_K // 107 k +#define ASCII_6C KEY_L // 108 l +#define ASCII_6D KEY_M // 109 m +#define ASCII_6E KEY_N // 110 n +#define ASCII_6F KEY_O // 111 o +#define ASCII_70 KEY_P // 112 p +#define ASCII_71 KEY_Q // 113 q +#define ASCII_72 KEY_R // 114 r +#define ASCII_73 KEY_S // 115 s +#define ASCII_74 KEY_T // 116 t +#define ASCII_75 KEY_U // 117 u +#define ASCII_76 KEY_V // 118 v +#define ASCII_77 KEY_W // 119 w +#define ASCII_78 KEY_X // 120 x +#define ASCII_79 KEY_Y // 121 y +#define ASCII_7A KEY_Z // 122 z +#define ASCII_7B KEY_QUOTE // 123 { +#define ASCII_7C KEY_TILDE // 124 | +#define ASCII_7D KEY_BACKSLASH // 125 } +#define ASCII_7E KEY_RIGHT_BRACE + ALTGR_MASK // 126 ~ +#define ASCII_7F KEY_BACKSPACE // 127 + +#define ISO_8859_1_A0 KEY_SPACE // 160 Nonbreakng Space +#define ISO_8859_1_A1 KEY_EQUAL + SHIFT_MASK // 161 ¡ Inverted Exclamation +#define ISO_8859_1_A2 0 // 162 ¢ Cent SIGN +#define ISO_8859_1_A3 0 // 163 £ Pound Sign +#define ISO_8859_1_A4 0 // 164 ¤ Currency Sign +#define ISO_8859_1_A5 0 // 165 ¥ YEN SIGN +#define ISO_8859_1_A6 0 // 166 ¦ BROKEN BAR +#define ISO_8859_1_A7 0 // 167 § SECTION SIGN +#define ISO_8859_1_A8 DIAERESIS_BITS + KEY_SPACE // 168 ¨ DIAERESIS +#define ISO_8859_1_A9 0 // 169 © COPYRIGHT SIGN +#define ISO_8859_1_AA 0 // 170 ª FEMININE ORDINAL +#define ISO_8859_1_AB 0 // 171 « LEFT DOUBLE ANGLE QUOTE +#define ISO_8859_1_AC KEY_TILDE + ALTGR_MASK // 172 ¬ NOT SIGN +#define ISO_8859_1_AD 0 // 173 SOFT HYPHEN +#define ISO_8859_1_AE 0 // 174 ® REGISTERED SIGN +#define ISO_8859_1_AF 0 // 175 ¯ MACRON +#define ISO_8859_1_B0 KEY_TILDE + SHIFT_MASK // 176 ° DEGREE SIGN +#define ISO_8859_1_B1 0 // 177 ± PLUS-MINUS SIGN +#define ISO_8859_1_B2 0 // 178 ² SUPERSCRIPT TWO +#define ISO_8859_1_B3 0 // 179 ³ SUPERSCRIPT THREE +#define ISO_8859_1_B4 ACUTE_ACCENT_BITS + KEY_SPACE // 180 ´ ACUTE ACCENT +#define ISO_8859_1_B5 0 // 181 µ MICRO SIGN +#define ISO_8859_1_B6 0 // 182 ¶ PILCROW SIGN +#define ISO_8859_1_B7 0 // 183 · MIDDLE DOT +#define ISO_8859_1_B8 0 // 184 ¸ CEDILLA +#define ISO_8859_1_B9 0 // 185 ¹ SUPERSCRIPT ONE +#define ISO_8859_1_BA 0 // 186 º MASCULINE ORDINAL +#define ISO_8859_1_BB 0 // 187 » RIGHT DOUBLE ANGLE QUOTE +#define ISO_8859_1_BC 0 // 188 ¼ FRACTION ONE QUARTER +#define ISO_8859_1_BD 0 // 189 ½ FRACTION ONE HALF +#define ISO_8859_1_BE 0 // 190 ¾ FRACTION THREE QUARTERS +#define ISO_8859_1_BF KEY_EQUAL // 191 ¿ INVERTED QUESTION MARK +#define ISO_8859_1_C0 GRAVE_ACCENT_BITS + KEY_A + SHIFT_MASK // 192 À A GRAVE +#define ISO_8859_1_C1 ACUTE_ACCENT_BITS + KEY_A + SHIFT_MASK // 193 à A ACUTE +#define ISO_8859_1_C2 CIRCUMFLEX_BITS + KEY_A + SHIFT_MASK // 194 Â A CIRCUMFLEX +#define ISO_8859_1_C3 0 // 195 Ã A TILDE +#define ISO_8859_1_C4 DIAERESIS_BITS + KEY_A + SHIFT_MASK // 196 Ä A DIAERESIS +#define ISO_8859_1_C5 0 // 197 Å A RING ABOVE +#define ISO_8859_1_C6 0 // 198 Æ AE +#define ISO_8859_1_C7 0 // 199 Ç C CEDILLA +#define ISO_8859_1_C8 GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK // 200 È E GRAVE +#define ISO_8859_1_C9 ACUTE_ACCENT_BITS + KEY_E + SHIFT_MASK // 201 É E ACUTE +#define ISO_8859_1_CA CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK // 202 Ê E CIRCUMFLEX +#define ISO_8859_1_CB DIAERESIS_BITS + KEY_E + SHIFT_MASK // 203 Ë E DIAERESIS +#define ISO_8859_1_CC GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK // 204 Ì I GRAVE +#define ISO_8859_1_CD ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK // 205 à I ACUTE +#define ISO_8859_1_CE CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK // 206 Î I CIRCUMFLEX +#define ISO_8859_1_CF DIAERESIS_BITS + KEY_I + SHIFT_MASK // 207 à I DIAERESIS +#define ISO_8859_1_D0 0 // 208 à ETH +#define ISO_8859_1_D1 KEY_SEMICOLON + SHIFT_MASK // 209 Ñ N TILDE +#define ISO_8859_1_D2 GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK // 210 Ò O GRAVE +#define ISO_8859_1_D3 ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK // 211 Ó O ACUTE +#define ISO_8859_1_D4 CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK // 212 Ô O CIRCUMFLEX +#define ISO_8859_1_D5 0 // 213 Õ O TILDE +#define ISO_8859_1_D6 DIAERESIS_BITS + KEY_O + SHIFT_MASK // 214 Ö O DIAERESIS +#define ISO_8859_1_D7 0 // 215 × MULTIPLICATION +#define ISO_8859_1_D8 0 // 216 Ø O STROKE +#define ISO_8859_1_D9 GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK // 217 Ù U GRAVE +#define ISO_8859_1_DA ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK // 218 Ú U ACUTE +#define ISO_8859_1_DB CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK // 219 Û U CIRCUMFLEX +#define ISO_8859_1_DC DIAERESIS_BITS + KEY_U + SHIFT_MASK // 220 Ü U DIAERESIS +#define ISO_8859_1_DD ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK // 221 à Y ACUTE +#define ISO_8859_1_DE 0 // 222 Þ THORN +#define ISO_8859_1_DF 0 // 223 ß SHARP S +#define ISO_8859_1_E0 GRAVE_ACCENT_BITS + KEY_A // 224 à a GRAVE +#define ISO_8859_1_E1 ACUTE_ACCENT_BITS + KEY_A // 225 á a ACUTE +#define ISO_8859_1_E2 CIRCUMFLEX_BITS + KEY_A // 226 â a CIRCUMFLEX +#define ISO_8859_1_E3 0 // 227 ã a TILDE +#define ISO_8859_1_E4 DIAERESIS_BITS + KEY_A // 228 ä a DIAERESIS +#define ISO_8859_1_E5 0 // 229 å a RING ABOVE +#define ISO_8859_1_E6 0 // 230 æ ae +#define ISO_8859_1_E7 0 // 231 ç c CEDILLA +#define ISO_8859_1_E8 GRAVE_ACCENT_BITS + KEY_E // 232 è e GRAVE +#define ISO_8859_1_E9 ACUTE_ACCENT_BITS + KEY_E // 233 é e ACUTE +#define ISO_8859_1_EA CIRCUMFLEX_BITS + KEY_E // 234 ê e CIRCUMFLEX +#define ISO_8859_1_EB DIAERESIS_BITS + KEY_E // 235 ë e DIAERESIS +#define ISO_8859_1_EC GRAVE_ACCENT_BITS + KEY_I // 236 ì i GRAVE +#define ISO_8859_1_ED ACUTE_ACCENT_BITS + KEY_I // 237 à i ACUTE +#define ISO_8859_1_EE CIRCUMFLEX_BITS + KEY_I // 238 î i CIRCUMFLEX +#define ISO_8859_1_EF DIAERESIS_BITS + KEY_I // 239 ï i DIAERESIS +#define ISO_8859_1_F0 0 // 240 ð ETH +#define ISO_8859_1_F1 KEY_SEMICOLON // 241 ñ n TILDE +#define ISO_8859_1_F2 GRAVE_ACCENT_BITS + KEY_O // 242 ò o GRAVE +#define ISO_8859_1_F3 ACUTE_ACCENT_BITS + KEY_O // 243 ó o ACUTE +#define ISO_8859_1_F4 CIRCUMFLEX_BITS + KEY_O // 244 ô o CIRCUMFLEX +#define ISO_8859_1_F5 0 // 245 õ o TILDE +#define ISO_8859_1_F6 DIAERESIS_BITS + KEY_O // 246 ö o DIAERESIS +#define ISO_8859_1_F7 0 // 247 ÷ DIVISION +#define ISO_8859_1_F8 0 // 248 ø o STROKE +#define ISO_8859_1_F9 GRAVE_ACCENT_BITS + KEY_U // 249 ù u GRAVE +#define ISO_8859_1_FA ACUTE_ACCENT_BITS + KEY_U // 250 ú u ACUTE +#define ISO_8859_1_FB CIRCUMFLEX_BITS + KEY_U // 251 û u CIRCUMFLEX +#define ISO_8859_1_FC DIAERESIS_BITS + KEY_U // 252 ü u DIAERESIS +#define ISO_8859_1_FD ACUTE_ACCENT_BITS + KEY_Y // 253 ý y ACUTE +#define ISO_8859_1_FE 0 // 254 þ THORN +#define ISO_8859_1_FF DIAERESIS_BITS + KEY_Y // 255 ÿ y DIAERESIS + +#endif // LAYOUT_SPANISH_LATIN_AMERICA + + + +#ifdef LAYOUT_IRISH + +#define SHIFT_MASK 0x0040 +#define ALTGR_MASK 0x0080 +#define DEADKEYS_MASK 0x0300 +#define GRAVE_ACCENT_BITS 0x0100 +#define ACUTE_ACCENT_BITS 0x0200 +#define KEYCODE_TYPE uint16_t +#define DEADKEY_ACUTE_ACCENT KEY_QUOTE + ALTGR_MASK +#define DEADKEY_GRAVE_ACCENT KEY_TILDE +#define KEY_NON_US_100 63 + +#define ASCII_20 KEY_SPACE // 32 +#define ASCII_21 KEY_1 + SHIFT_MASK // 33 ! +#define ASCII_22 KEY_2 + SHIFT_MASK // 34 " +#define ASCII_23 KEY_BACKSPACE // 35 # +#define ASCII_24 KEY_4 + SHIFT_MASK // 36 $ +#define ASCII_25 KEY_5 + SHIFT_MASK // 37 % +#define ASCII_26 KEY_7 + SHIFT_MASK // 38 & +#define ASCII_27 KEY_QUOTE // 39 ' +#define ASCII_28 KEY_9 + SHIFT_MASK // 40 ( +#define ASCII_29 KEY_0 + SHIFT_MASK // 41 ) +#define ASCII_2A KEY_8 + SHIFT_MASK // 42 * +#define ASCII_2B KEY_EQUAL + SHIFT_MASK // 43 + +#define ASCII_2C KEY_COMMA // 44 , +#define ASCII_2D KEY_MINUS // 45 - +#define ASCII_2E KEY_PERIOD // 46 . +#define ASCII_2F KEY_SLASH // 47 / +#define ASCII_30 KEY_0 // 48 0 +#define ASCII_31 KEY_1 // 49 1 +#define ASCII_32 KEY_2 // 50 2 +#define ASCII_33 KEY_3 // 51 3 +#define ASCII_34 KEY_4 // 52 4 +#define ASCII_35 KEY_5 // 53 5 +#define ASCII_36 KEY_6 // 54 6 +#define ASCII_37 KEY_7 // 55 7 +#define ASCII_38 KEY_8 // 55 8 +#define ASCII_39 KEY_9 // 57 9 +#define ASCII_3A KEY_SEMICOLON + SHIFT_MASK // 58 : +#define ASCII_3B KEY_SEMICOLON // 59 ; +#define ASCII_3C KEY_COMMA + SHIFT_MASK // 60 < +#define ASCII_3D KEY_EQUAL // 61 = +#define ASCII_3E KEY_PERIOD + SHIFT_MASK // 62 > +#define ASCII_3F KEY_SLASH + SHIFT_MASK // 63 ? +#define ASCII_40 KEY_QUOTE + SHIFT_MASK // 64 @ +#define ASCII_41 KEY_A + SHIFT_MASK // 65 A +#define ASCII_42 KEY_B + SHIFT_MASK // 66 B +#define ASCII_43 KEY_C + SHIFT_MASK // 67 C +#define ASCII_44 KEY_D + SHIFT_MASK // 68 D +#define ASCII_45 KEY_E + SHIFT_MASK // 69 E +#define ASCII_46 KEY_F + SHIFT_MASK // 70 F +#define ASCII_47 KEY_G + SHIFT_MASK // 71 G +#define ASCII_48 KEY_H + SHIFT_MASK // 72 H +#define ASCII_49 KEY_I + SHIFT_MASK // 73 I +#define ASCII_4A KEY_J + SHIFT_MASK // 74 J +#define ASCII_4B KEY_K + SHIFT_MASK // 75 K +#define ASCII_4C KEY_L + SHIFT_MASK // 76 L +#define ASCII_4D KEY_M + SHIFT_MASK // 77 M +#define ASCII_4E KEY_N + SHIFT_MASK // 78 N +#define ASCII_4F KEY_O + SHIFT_MASK // 79 O +#define ASCII_50 KEY_P + SHIFT_MASK // 80 P +#define ASCII_51 KEY_Q + SHIFT_MASK // 81 Q +#define ASCII_52 KEY_R + SHIFT_MASK // 82 R +#define ASCII_53 KEY_S + SHIFT_MASK // 83 S +#define ASCII_54 KEY_T + SHIFT_MASK // 84 T +#define ASCII_55 KEY_U + SHIFT_MASK // 85 U +#define ASCII_56 KEY_V + SHIFT_MASK // 86 V +#define ASCII_57 KEY_W + SHIFT_MASK // 87 W +#define ASCII_58 KEY_X + SHIFT_MASK // 88 X +#define ASCII_59 KEY_Y + SHIFT_MASK // 89 Y +#define ASCII_5A KEY_Z + SHIFT_MASK // 90 Z +#define ASCII_5B KEY_LEFT_BRACE // 91 [ +#define ASCII_5C KEY_NON_US_100 // 92 +#define ASCII_5D KEY_RIGHT_BRACE // 93 ] +#define ASCII_5E KEY_6 + SHIFT_MASK // 94 ^ +#define ASCII_5F KEY_MINUS + SHIFT_MASK // 95 _ +#define ASCII_60 KEY_QUOTE + SHIFT_MASK + ALTGR_MASK // 96 ` +#define ASCII_61 KEY_A // 97 a +#define ASCII_62 KEY_B // 98 b +#define ASCII_63 KEY_C // 99 c +#define ASCII_64 KEY_D // 100 d +#define ASCII_65 KEY_E // 101 e +#define ASCII_66 KEY_F // 102 f +#define ASCII_67 KEY_G // 103 g +#define ASCII_68 KEY_H // 104 h +#define ASCII_69 KEY_I // 105 i +#define ASCII_6A KEY_J // 106 j +#define ASCII_6B KEY_K // 107 k +#define ASCII_6C KEY_L // 108 l +#define ASCII_6D KEY_M // 109 m +#define ASCII_6E KEY_N // 110 n +#define ASCII_6F KEY_O // 111 o +#define ASCII_70 KEY_P // 112 p +#define ASCII_71 KEY_Q // 113 q +#define ASCII_72 KEY_R // 114 r +#define ASCII_73 KEY_S // 115 s +#define ASCII_74 KEY_T // 116 t +#define ASCII_75 KEY_U // 117 u +#define ASCII_76 KEY_V // 118 v +#define ASCII_77 KEY_W // 119 w +#define ASCII_78 KEY_X // 120 x +#define ASCII_79 KEY_Y // 121 y +#define ASCII_7A KEY_Z // 122 z +#define ASCII_7B KEY_LEFT_BRACE + SHIFT_MASK // 123 { +#define ASCII_7C KEY_NON_US_100 + SHIFT_MASK // 124 | +#define ASCII_7D KEY_RIGHT_BRACE + SHIFT_MASK // 125 } +#define ASCII_7E KEY_BACKSLASH + SHIFT_MASK // 126 ~ +#define ASCII_7F KEY_BACKSPACE // 127 + +#define ISO_8859_1_A0 KEY_SPACE // 160 Nonbreakng Space +#define ISO_8859_1_A1 0 // 161 ¡ Inverted Exclamation +#define ISO_8859_1_A2 0 // 162 ¢ Cent SIGN +#define ISO_8859_1_A3 KEY_3 + SHIFT_MASK // 163 £ Pound Sign +#define ISO_8859_1_A4 0 // 164 ¤ Currency or Euro Sign +#define ISO_8859_1_A5 0 // 165 ¥ YEN SIGN +#define ISO_8859_1_A6 KEY_TILDE + ALTGR_MASK // 166 ¦ BROKEN BAR +#define ISO_8859_1_A7 0 // 167 § SECTION SIGN +#define ISO_8859_1_A8 0 // 168 ¨ DIAERESIS +#define ISO_8859_1_A9 0 // 169 © COPYRIGHT SIGN +#define ISO_8859_1_AA 0 // 170 ª FEMININE ORDINAL +#define ISO_8859_1_AB 0 // 171 « LEFT DOUBLE ANGLE QUOTE +#define ISO_8859_1_AC KEY_TILDE + SHIFT_MASK // 172 ¬ NOT SIGN +#define ISO_8859_1_AD 0 // 173 SOFT HYPHEN +#define ISO_8859_1_AE 0 // 174 ® REGISTERED SIGN +#define ISO_8859_1_AF 0 // 175 ¯ MACRON +#define ISO_8859_1_B0 0 // 176 ° DEGREE SIGN +#define ISO_8859_1_B1 0 // 177 ± PLUS-MINUS SIGN +#define ISO_8859_1_B2 0 // 178 ² SUPERSCRIPT TWO +#define ISO_8859_1_B3 0 // 179 ³ SUPERSCRIPT THREE +#define ISO_8859_1_B4 0 // 180 ´ ACUTE ACCENT +#define ISO_8859_1_B5 0 // 181 µ MICRO SIGN +#define ISO_8859_1_B6 0 // 182 ¶ PILCROW SIGN +#define ISO_8859_1_B7 0 // 183 · MIDDLE DOT +#define ISO_8859_1_B8 0 // 184 ¸ CEDILLA +#define ISO_8859_1_B9 0 // 185 ¹ SUPERSCRIPT ONE +#define ISO_8859_1_BA 0 // 186 º MASCULINE ORDINAL +#define ISO_8859_1_BB 0 // 187 » RIGHT DOUBLE ANGLE QUOTE +#define ISO_8859_1_BC 0 // 188 ¼ FRACTION ONE QUARTER +#define ISO_8859_1_BD 0 // 189 ½ FRACTION ONE HALF +#define ISO_8859_1_BE 0 // 190 ¾ FRACTION THREE QUARTERS +#define ISO_8859_1_BF 0 // 191 ¿ INVERTED QUESTION MARK +#define ISO_8859_1_C0 GRAVE_ACCENT_BITS + KEY_A // 192 À A GRAVE +#define ISO_8859_1_C1 KEY_A + ALTGR_MASK + SHIFT_MASK // 193 à A ACUTE +#define ISO_8859_1_C2 0 // 194 Â A CIRCUMFLEX +#define ISO_8859_1_C3 0 // 195 Ã A TILDE +#define ISO_8859_1_C4 0 // 196 Ä A DIAERESIS +#define ISO_8859_1_C5 0 // 197 Å A RING ABOVE +#define ISO_8859_1_C6 0 // 198 Æ AE +#define ISO_8859_1_C7 0 // 199 Ç C CEDILLA +#define ISO_8859_1_C8 GRAVE_ACCENT_BITS + KEY_E // 200 È E GRAVE +#define ISO_8859_1_C9 KEY_E + ALTGR_MASK + SHIFT_MASK // 201 É E ACUTE +#define ISO_8859_1_CA 0 // 202 Ê E CIRCUMFLEX +#define ISO_8859_1_CB 0 // 203 Ë E DIAERESIS +#define ISO_8859_1_CC GRAVE_ACCENT_BITS + KEY_I // 204 Ì I GRAVE +#define ISO_8859_1_CD KEY_I + ALTGR_MASK + SHIFT_MASK // 205 à I ACUTE +#define ISO_8859_1_CE 0 // 206 Î I CIRCUMFLEX +#define ISO_8859_1_CF 0 // 207 à I DIAERESIS +#define ISO_8859_1_D0 0 // 208 à ETH +#define ISO_8859_1_D1 0 // 209 Ñ N TILDE +#define ISO_8859_1_D2 GRAVE_ACCENT_BITS + KEY_O // 210 Ò O GRAVE +#define ISO_8859_1_D3 KEY_O + ALTGR_MASK + SHIFT_MASK // 211 Ó O ACUTE +#define ISO_8859_1_D4 0 // 212 Ô O CIRCUMFLEX +#define ISO_8859_1_D5 0 // 213 Õ O TILDE +#define ISO_8859_1_D6 0 // 214 Ö O DIAERESIS +#define ISO_8859_1_D7 0 // 215 × MULTIPLICATION +#define ISO_8859_1_D8 0 // 216 Ø O STROKE +#define ISO_8859_1_D9 GRAVE_ACCENT_BITS + KEY_U // 217 Ù U GRAVE +#define ISO_8859_1_DA KEY_U + ALTGR_MASK + SHIFT_MASK // 218 Ú U ACUTE +#define ISO_8859_1_DB 0 // 219 Û U CIRCUMFLEX +#define ISO_8859_1_DC 0 // 220 Ü U DIAERESIS +#define ISO_8859_1_DD ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK // 221 à Y ACUTE +#define ISO_8859_1_DE 0 // 222 Þ THORN +#define ISO_8859_1_DF 0 // 223 ß SHARP S +#define ISO_8859_1_E0 GRAVE_ACCENT_BITS + KEY_A // 224 à a GRAVE +#define ISO_8859_1_E1 KEY_A + ALTGR_MASK // 225 á a ACUTE +#define ISO_8859_1_E2 0 // 226 â a CIRCUMFLEX +#define ISO_8859_1_E3 0 // 227 ã a TILDE +#define ISO_8859_1_E4 0 // 228 ä a DIAERESIS +#define ISO_8859_1_E5 0 // 229 å a RING ABOVE +#define ISO_8859_1_E6 0 // 230 æ ae +#define ISO_8859_1_E7 0 // 231 ç c CEDILLA +#define ISO_8859_1_E8 GRAVE_ACCENT_BITS + KEY_E // 232 è e GRAVE +#define ISO_8859_1_E9 KEY_E + ALTGR_MASK // 233 é e ACUTE +#define ISO_8859_1_EA 0 // 234 ê e CIRCUMFLEX +#define ISO_8859_1_EB 0 // 235 ë e DIAERESIS +#define ISO_8859_1_EC GRAVE_ACCENT_BITS + KEY_I // 236 ì i GRAVE +#define ISO_8859_1_ED KEY_I + ALTGR_MASK // 237 à i ACUTE +#define ISO_8859_1_EE 0 // 238 î i CIRCUMFLEX +#define ISO_8859_1_EF 0 // 239 ï i DIAERESIS +#define ISO_8859_1_F0 0 // 240 ð ETH +#define ISO_8859_1_F1 0 // 241 ñ n TILDE +#define ISO_8859_1_F2 GRAVE_ACCENT_BITS + KEY_O // 242 ò o GRAVE +#define ISO_8859_1_F3 KEY_O + ALTGR_MASK // 243 ó o ACUTE +#define ISO_8859_1_F4 0 // 244 ô o CIRCUMFLEX +#define ISO_8859_1_F5 0 // 245 õ o TILDE +#define ISO_8859_1_F6 0 // 246 ö o DIAERESIS +#define ISO_8859_1_F7 0 // 247 ÷ DIVISION +#define ISO_8859_1_F8 0 // 248 ø o STROKE +#define ISO_8859_1_F9 GRAVE_ACCENT_BITS + KEY_U // 249 ù u GRAVE +#define ISO_8859_1_FA KEY_U + ALTGR_MASK // 250 ú u ACUTE +#define ISO_8859_1_FB 0 // 251 û u CIRCUMFLEX +#define ISO_8859_1_FC 0 // 252 ü u DIAERESIS +#define ISO_8859_1_FD ACUTE_ACCENT_BITS + KEY_Y // 253 ý y ACUTE +#define ISO_8859_1_FE 0 // 254 þ THORN +#define ISO_8859_1_FF 0 // 255 ÿ y DIAERESIS +#define UNICODE_20AC KEY_4 + ALTGR_MASK // € Euro Sign +// not yet implemented +#define UNICODE_EXTRA00 0x20AC +#define KEYCODE_EXTRA00 KEY_4 + ALTGR_MASK // 20AC € Euro Sign + +#endif // LAYOUT_IRISH + + + + +#ifdef LAYOUT_ICELANDIC + +#define SHIFT_MASK 0x0040 +#define ALTGR_MASK 0x0080 +#define DEADKEYS_MASK 0x0700 +#define CIRCUMFLEX_BITS 0x0100 +#define ACUTE_ACCENT_BITS 0x0200 +#define GRAVE_ACCENT_BITS 0x0300 +#define DIAERESIS_BITS 0x0400 +#define RING_ABOVE_BITS 0x0500 +#define KEYCODE_TYPE uint16_t +#define DEADKEY_CIRCUMFLEX KEY_QUOTE + ALTGR_MASK +#define DEADKEY_ACUTE_ACCENT KEY_QUOTE +#define DEADKEY_GRAVE_ACCENT KEY_BACKSLASH + ALTGR_MASK +#define DEADKEY_DIAERESIS KEY_TILDE + SHIFT_MASK +#define DEADKEY_RING_ABOVE KEY_TILDE +#define KEY_NON_US_100 63 + +#define ASCII_20 KEY_SPACE // 32 +#define ASCII_21 KEY_1 + SHIFT_MASK // 33 ! +#define ASCII_22 KEY_2 + SHIFT_MASK // 34 " +#define ASCII_23 KEY_3 + SHIFT_MASK // 35 # +#define ASCII_24 KEY_4 + SHIFT_MASK // 36 $ +#define ASCII_25 KEY_5 + SHIFT_MASK // 37 % +#define ASCII_26 KEY_6 + SHIFT_MASK // 38 & +#define ASCII_27 KEY_QUOTE + SHIFT_MASK // 39 ' +#define ASCII_28 KEY_8 + SHIFT_MASK // 40 ( +#define ASCII_29 KEY_9 + SHIFT_MASK // 41 ) +#define ASCII_2A KEY_BACKSLASH + SHIFT_MASK // 42 * +#define ASCII_2B KEY_BACKSLASH // 43 + +#define ASCII_2C KEY_COMMA // 44 , +#define ASCII_2D KEY_EQUAL // 45 - +#define ASCII_2E KEY_PERIOD // 46 . +#define ASCII_2F KEY_7 + SHIFT_MASK // 47 / +#define ASCII_30 KEY_0 // 48 0 +#define ASCII_31 KEY_1 // 49 1 +#define ASCII_32 KEY_2 // 50 2 +#define ASCII_33 KEY_3 // 51 3 +#define ASCII_34 KEY_4 // 52 4 +#define ASCII_35 KEY_5 // 53 5 +#define ASCII_36 KEY_6 // 54 6 +#define ASCII_37 KEY_7 // 55 7 +#define ASCII_38 KEY_8 // 55 8 +#define ASCII_39 KEY_9 // 57 9 +#define ASCII_3A KEY_PERIOD + SHIFT_MASK // 58 : +#define ASCII_3B KEY_COMMA + SHIFT_MASK // 59 ; +#define ASCII_3C KEY_NON_US_100 // 60 < +#define ASCII_3D KEY_0 + SHIFT_MASK // 61 = +#define ASCII_3E KEY_NON_US_100 + SHIFT_MASK // 62 > +#define ASCII_3F KEY_RIGHT_BRACE + SHIFT_MASK // 63 ? +#define ASCII_40 KEY_Q + ALTGR_MASK // 64 @ +#define ASCII_41 KEY_A + SHIFT_MASK // 65 A +#define ASCII_42 KEY_B + SHIFT_MASK // 66 B +#define ASCII_43 KEY_C + SHIFT_MASK // 67 C +#define ASCII_44 KEY_D + SHIFT_MASK // 68 D +#define ASCII_45 KEY_E + SHIFT_MASK // 69 E +#define ASCII_46 KEY_F + SHIFT_MASK // 70 F +#define ASCII_47 KEY_G + SHIFT_MASK // 71 G +#define ASCII_48 KEY_H + SHIFT_MASK // 72 H +#define ASCII_49 KEY_I + SHIFT_MASK // 73 I +#define ASCII_4A KEY_J + SHIFT_MASK // 74 J +#define ASCII_4B KEY_K + SHIFT_MASK // 75 K +#define ASCII_4C KEY_L + SHIFT_MASK // 76 L +#define ASCII_4D KEY_M + SHIFT_MASK // 77 M +#define ASCII_4E KEY_N + SHIFT_MASK // 78 N +#define ASCII_4F KEY_O + SHIFT_MASK // 79 O +#define ASCII_50 KEY_P + SHIFT_MASK // 80 P +#define ASCII_51 KEY_Q + SHIFT_MASK // 81 Q +#define ASCII_52 KEY_R + SHIFT_MASK // 82 R +#define ASCII_53 KEY_S + SHIFT_MASK // 83 S +#define ASCII_54 KEY_T + SHIFT_MASK // 84 T +#define ASCII_55 KEY_U + SHIFT_MASK // 85 U +#define ASCII_56 KEY_V + SHIFT_MASK // 86 V +#define ASCII_57 KEY_W + SHIFT_MASK // 87 W +#define ASCII_58 KEY_X + SHIFT_MASK // 88 X +#define ASCII_59 KEY_Y + SHIFT_MASK // 89 Y +#define ASCII_5A KEY_Z + SHIFT_MASK // 90 Z +#define ASCII_5B KEY_8 + ALTGR_MASK // 91 [ +#define ASCII_5C KEY_MINUS + ALTGR_MASK // 92 +#define ASCII_5D KEY_9 + ALTGR_MASK // 93 ] +#define ASCII_5E CIRCUMFLEX_BITS + KEY_SPACE // 94 ^ +#define ASCII_5F KEY_EQUAL + SHIFT_MASK // 95 _ +#define ASCII_60 GRAVE_ACCENT_BITS + KEY_SPACE // 96 ` +#define ASCII_61 KEY_A // 97 a +#define ASCII_62 KEY_B // 98 b +#define ASCII_63 KEY_C // 99 c +#define ASCII_64 KEY_D // 100 d +#define ASCII_65 KEY_E // 101 e +#define ASCII_66 KEY_F // 102 f +#define ASCII_67 KEY_G // 103 g +#define ASCII_68 KEY_H // 104 h +#define ASCII_69 KEY_I // 105 i +#define ASCII_6A KEY_J // 106 j +#define ASCII_6B KEY_K // 107 k +#define ASCII_6C KEY_L // 108 l +#define ASCII_6D KEY_M // 109 m +#define ASCII_6E KEY_N // 110 n +#define ASCII_6F KEY_O // 111 o +#define ASCII_70 KEY_P // 112 p +#define ASCII_71 KEY_Q // 113 q +#define ASCII_72 KEY_R // 114 r +#define ASCII_73 KEY_S // 115 s +#define ASCII_74 KEY_T // 116 t +#define ASCII_75 KEY_U // 117 u +#define ASCII_76 KEY_V // 118 v +#define ASCII_77 KEY_W // 119 w +#define ASCII_78 KEY_X // 120 x +#define ASCII_79 KEY_Y // 121 y +#define ASCII_7A KEY_Z // 122 z +#define ASCII_7B KEY_7 + ALTGR_MASK // 123 { +#define ASCII_7C KEY_NON_US_100 + ALTGR_MASK // 124 | +#define ASCII_7D KEY_0 + ALTGR_MASK // 125 } +#define ASCII_7E KEY_RIGHT_BRACE + ALTGR_MASK // 126 ~ +#define ASCII_7F KEY_BACKSPACE // 127 + +#define ISO_8859_1_A0 KEY_SPACE // 160 Nonbreakng Space +#define ISO_8859_1_A1 0 // 161 ¡ Inverted Exclamation +#define ISO_8859_1_A2 0 // 162 ¢ Cent SIGN +#define ISO_8859_1_A3 0 // 163 £ Pound Sign +#define ISO_8859_1_A4 0 // 164 ¤ Currency or Euro Sign +#define ISO_8859_1_A5 0 // 165 ¥ YEN SIGN +#define ISO_8859_1_A6 0 // 166 ¦ BROKEN BAR ?? +#define ISO_8859_1_A7 0 // 167 § SECTION SIGN +#define ISO_8859_1_A8 DIAERESIS_BITS + KEY_SPACE // 168 ¨ DIAERESIS +#define ISO_8859_1_A9 0 // 169 © COPYRIGHT SIGN +#define ISO_8859_1_AA 0 // 170 ª FEMININE ORDINAL +#define ISO_8859_1_AB 0 // 171 « LEFT DOUBLE ANGLE QUOTE +#define ISO_8859_1_AC 0 // 172 ¬ NOT SIGN ?? +#define ISO_8859_1_AD 0 // 173 SOFT HYPHEN +#define ISO_8859_1_AE 0 // 174 ® REGISTERED SIGN +#define ISO_8859_1_AF 0 // 175 ¯ MACRON +#define ISO_8859_1_B0 KEY_TILDE + ALTGR_MASK // 176 ° DEGREE SIGN +#define ISO_8859_1_B1 0 // 177 ± PLUS-MINUS SIGN +#define ISO_8859_1_B2 0 // 178 ² SUPERSCRIPT TWO +#define ISO_8859_1_B3 0 // 179 ³ SUPERSCRIPT THREE +#define ISO_8859_1_B4 ACUTE_ACCENT_BITS + KEY_SPACE // 180 ´ ACUTE ACCENT +#define ISO_8859_1_B5 KEY_M + ALTGR_MASK // 181 µ MICRO SIGN +#define ISO_8859_1_B6 0 // 182 ¶ PILCROW SIGN +#define ISO_8859_1_B7 0 // 183 · MIDDLE DOT +#define ISO_8859_1_B8 0 // 184 ¸ CEDILLA +#define ISO_8859_1_B9 0 // 185 ¹ SUPERSCRIPT ONE +#define ISO_8859_1_BA 0 // 186 º MASCULINE ORDINAL +#define ISO_8859_1_BB 0 // 187 » RIGHT DOUBLE ANGLE QUOTE +#define ISO_8859_1_BC 0 // 188 ¼ FRACTION ONE QUARTER +#define ISO_8859_1_BD 0 // 189 ½ FRACTION ONE HALF +#define ISO_8859_1_BE 0 // 190 ¾ FRACTION THREE QUARTERS +#define ISO_8859_1_BF 0 // 191 ¿ INVERTED QUESTION MARK +#define ISO_8859_1_C0 GRAVE_ACCENT_BITS + KEY_A + SHIFT_MASK // 192 À A GRAVE +#define ISO_8859_1_C1 ACUTE_ACCENT_BITS + KEY_A + ALTGR_MASK // 193 à A ACUTE +#define ISO_8859_1_C2 CIRCUMFLEX_BITS + KEY_A + SHIFT_MASK // 194 Â A CIRCUMFLEX +#define ISO_8859_1_C3 0 // 195 Ã A TILDE +#define ISO_8859_1_C4 DIAERESIS_BITS + KEY_A + SHIFT_MASK // 196 Ä A DIAERESIS +#define ISO_8859_1_C5 RING_ABOVE_BITS + KEY_A + SHIFT_MASK // 197 Å A RING ABOVE +#define ISO_8859_1_C6 KEY_SEMICOLON + SHIFT_MASK // 198 Æ AE +#define ISO_8859_1_C7 0 // 199 Ç C CEDILLA +#define ISO_8859_1_C8 GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK // 200 È E GRAVE +#define ISO_8859_1_C9 ACUTE_ACCENT_BITS + KEY_E + SHIFT_MASK // 201 É E ACUTE +#define ISO_8859_1_CA CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK // 202 Ê E CIRCUMFLEX +#define ISO_8859_1_CB DIAERESIS_BITS + KEY_E + SHIFT_MASK // 203 Ë E DIAERESIS +#define ISO_8859_1_CC GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK // 204 Ì I GRAVE +#define ISO_8859_1_CD ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK // 205 à I ACUTE +#define ISO_8859_1_CE CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK // 206 Î I CIRCUMFLEX +#define ISO_8859_1_CF DIAERESIS_BITS + KEY_I + SHIFT_MASK // 207 à I DIAERESIS +#define ISO_8859_1_D0 KEY_LEFT_BRACE + SHIFT_MASK // 208 à ETH +#define ISO_8859_1_D1 0 // 209 Ñ N TILDE +#define ISO_8859_1_D2 GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK // 210 Ò O GRAVE +#define ISO_8859_1_D3 ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK // 211 Ó O ACUTE +#define ISO_8859_1_D4 CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK // 212 Ô O CIRCUMFLEX +#define ISO_8859_1_D5 0 // 213 Õ O TILDE +#define ISO_8859_1_D6 DIAERESIS_BITS + KEY_O + SHIFT_MASK // 214 Ö O DIAERESIS +#define ISO_8859_1_D7 0 // 215 × MULTIPLICATION +#define ISO_8859_1_D8 0 // 216 Ø O STROKE +#define ISO_8859_1_D9 GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK // 217 Ù U GRAVE +#define ISO_8859_1_DA ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK // 218 Ú U ACUTE +#define ISO_8859_1_DB CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK // 219 Û U CIRCUMFLEX +#define ISO_8859_1_DC DIAERESIS_BITS + KEY_U + SHIFT_MASK // 220 Ü U DIAERESIS +#define ISO_8859_1_DD ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK // 221 à Y ACUTE +#define ISO_8859_1_DE KEY_SLASH + SHIFT_MASK // 222 Þ THORN +#define ISO_8859_1_DF 0 // 223 ß SHARP S +#define ISO_8859_1_E0 GRAVE_ACCENT_BITS + KEY_A // 224 à a GRAVE +#define ISO_8859_1_E1 ACUTE_ACCENT_BITS + KEY_A // 225 á a ACUTE +#define ISO_8859_1_E2 CIRCUMFLEX_BITS + KEY_A // 226 â a CIRCUMFLEX +#define ISO_8859_1_E3 0 // 227 ã a TILDE +#define ISO_8859_1_E4 DIAERESIS_BITS + KEY_A // 228 ä a DIAERESIS +#define ISO_8859_1_E5 RING_ABOVE_BITS + KEY_A // 229 å a RING ABOVE +#define ISO_8859_1_E6 KEY_SEMICOLON // 230 æ ae +#define ISO_8859_1_E7 0 // 231 ç c CEDILLA +#define ISO_8859_1_E8 GRAVE_ACCENT_BITS + KEY_E // 232 è e GRAVE +#define ISO_8859_1_E9 ACUTE_ACCENT_BITS + KEY_E // 233 é e ACUTE +#define ISO_8859_1_EA CIRCUMFLEX_BITS + KEY_E // 234 ê e CIRCUMFLEX +#define ISO_8859_1_EB DIAERESIS_BITS + KEY_E // 235 ë e DIAERESIS +#define ISO_8859_1_EC GRAVE_ACCENT_BITS + KEY_I // 236 ì i GRAVE +#define ISO_8859_1_ED ACUTE_ACCENT_BITS + KEY_I // 237 à i ACUTE +#define ISO_8859_1_EE CIRCUMFLEX_BITS + KEY_I // 238 î i CIRCUMFLEX +#define ISO_8859_1_EF DIAERESIS_BITS + KEY_I // 239 ï i DIAERESIS +#define ISO_8859_1_F0 KEY_LEFT_BRACE // 240 ð ETH +#define ISO_8859_1_F1 0 // 241 ñ n TILDE +#define ISO_8859_1_F2 GRAVE_ACCENT_BITS + KEY_O // 242 ò o GRAVE +#define ISO_8859_1_F3 ACUTE_ACCENT_BITS + KEY_O // 243 ó o ACUTE +#define ISO_8859_1_F4 CIRCUMFLEX_BITS + KEY_O // 244 ô o CIRCUMFLEX +#define ISO_8859_1_F5 0 // 245 õ o TILDE +#define ISO_8859_1_F6 DIAERESIS_BITS + KEY_O // 246 ö o DIAERESIS +#define ISO_8859_1_F7 0 // 247 ÷ DIVISION +#define ISO_8859_1_F8 0 // 248 ø o STROKE +#define ISO_8859_1_F9 GRAVE_ACCENT_BITS + KEY_U // 249 ù u GRAVE +#define ISO_8859_1_FA ACUTE_ACCENT_BITS + KEY_U // 250 ú u ACUTE +#define ISO_8859_1_FB CIRCUMFLEX_BITS + KEY_U // 251 û u CIRCUMFLEX +#define ISO_8859_1_FC DIAERESIS_BITS + KEY_U // 252 ü u DIAERESIS +#define ISO_8859_1_FD ACUTE_ACCENT_BITS + KEY_Y // 253 ý y ACUTE +#define ISO_8859_1_FE KEY_SLASH // 254 þ THORN +#define ISO_8859_1_FF DIAERESIS_BITS + KEY_Y // 255 ÿ y DIAERESIS +#define UNICODE_20AC KEY_5 + ALTGR_MASK // € Euro Sign +// not yet implemented +#define UNICODE_EXTRA00 0x20AC +#define KEYCODE_EXTRA00 KEY_5 + ALTGR_MASK // 20AC € Euro Sign + +#endif // LAYOUT_ICELANDIC + + + +#ifdef LAYOUT_TURKISH +// http://forum.pjrc.com/threads/18781-Turkish-Language-Support + +#define SHIFT_MASK 0x0040 +#define ALTGR_MASK 0x0080 +#define DEADKEYS_MASK 0x0700 +#define CIRCUMFLEX_BITS 0x0100 +#define ACUTE_ACCENT_BITS 0x0200 +#define GRAVE_ACCENT_BITS 0x0300 +#define TILDE_BITS 0x0400 +#define DIAERESIS_BITS 0x0500 +#define KEYCODE_TYPE uint16_t +#define DEADKEY_CIRCUMFLEX KEY_3 + SHIFT_MASK +#define DEADKEY_ACUTE_ACCENT KEY_SEMICOLON + ALTGR_MASK +#define DEADKEY_GRAVE_ACCENT KEY_BACKSLASH + ALTGR_MASK +#define DEADKEY_TILDE KEY_RIGHT_BRACE + ALTGR_MASK +#define DEADKEY_DIAERESIS KEY_LEFT_BRACE + ALTGR_MASK + +#define ASCII_20 KEY_SPACE // 32 +#define ASCII_21 KEY_1 + SHIFT_MASK // 33 ! +#define ASCII_22 KEY_TILDE // 34 " +#define ASCII_23 KEY_3 + ALTGR_MASK // 35 # +#define ASCII_24 KEY_4 + ALTGR_MASK // 36 $ +#define ASCII_25 KEY_5 + SHIFT_MASK // 37 % +#define ASCII_26 KEY_6 + SHIFT_MASK // 38 & +#define ASCII_27 KEY_2 + SHIFT_MASK // 39 ' +#define ASCII_28 KEY_8 + SHIFT_MASK // 40 ( +#define ASCII_29 KEY_9 + SHIFT_MASK // 41 ) +#define ASCII_2A KEY_MINUS // 42 * +#define ASCII_2B KEY_4 + SHIFT_MASK // 43 + +#define ASCII_2C KEY_BACKSLASH // 44 , +#define ASCII_2D KEY_EQUAL // 45 - +#define ASCII_2E KEY_SLASH // 46 . +#define ASCII_2F KEY_7 + SHIFT_MASK // 47 / +#define ASCII_30 KEY_0 // 48 0 +#define ASCII_31 KEY_1 // 49 1 +#define ASCII_32 KEY_2 // 50 2 +#define ASCII_33 KEY_3 // 51 3 +#define ASCII_34 KEY_4 // 52 4 +#define ASCII_35 KEY_5 // 53 5 +#define ASCII_36 KEY_6 // 54 6 +#define ASCII_37 KEY_7 // 55 7 +#define ASCII_38 KEY_8 // 55 8 +#define ASCII_39 KEY_9 // 57 9 +#define ASCII_3A KEY_SLASH + SHIFT_MASK // 58 : +#define ASCII_3B KEY_BACKSLASH + SHIFT_MASK // 59 ; +#define ASCII_3C KEY_TILDE + ALTGR_MASK // 60 < +#define ASCII_3D KEY_0 + SHIFT_MASK // 61 = +#define ASCII_3E KEY_1 + ALTGR_MASK // 62 > +#define ASCII_3F KEY_MINUS + SHIFT_MASK // 63 ? +#define ASCII_40 KEY_Q + ALTGR_MASK // 64 @ +#define ASCII_41 KEY_A + SHIFT_MASK // 65 A +#define ASCII_42 KEY_B + SHIFT_MASK // 66 B +#define ASCII_43 KEY_C + SHIFT_MASK // 67 C +#define ASCII_44 KEY_D + SHIFT_MASK // 68 D +#define ASCII_45 KEY_E + SHIFT_MASK // 69 E +#define ASCII_46 KEY_F + SHIFT_MASK // 70 F +#define ASCII_47 KEY_G + SHIFT_MASK // 71 G +#define ASCII_48 KEY_H + SHIFT_MASK // 72 H +#define ASCII_49 KEY_I + SHIFT_MASK // 73 I +#define ASCII_4A KEY_J + SHIFT_MASK // 74 J +#define ASCII_4B KEY_K + SHIFT_MASK // 75 K +#define ASCII_4C KEY_L + SHIFT_MASK // 76 L +#define ASCII_4D KEY_M + SHIFT_MASK // 77 M +#define ASCII_4E KEY_N + SHIFT_MASK // 78 N +#define ASCII_4F KEY_O + SHIFT_MASK // 79 O +#define ASCII_50 KEY_P + SHIFT_MASK // 80 P +#define ASCII_51 KEY_Q + SHIFT_MASK // 81 Q +#define ASCII_52 KEY_R + SHIFT_MASK // 82 R +#define ASCII_53 KEY_S + SHIFT_MASK // 83 S +#define ASCII_54 KEY_T + SHIFT_MASK // 84 T +#define ASCII_55 KEY_U + SHIFT_MASK // 85 U +#define ASCII_56 KEY_V + SHIFT_MASK // 86 V +#define ASCII_57 KEY_W + SHIFT_MASK // 87 W +#define ASCII_58 KEY_X + SHIFT_MASK // 88 X +#define ASCII_59 KEY_Y + SHIFT_MASK // 89 Y +#define ASCII_5A KEY_Z + SHIFT_MASK // 90 Z +#define ASCII_5B KEY_8 + ALTGR_MASK // 91 [ +#define ASCII_5C KEY_MINUS + ALTGR_MASK // 92 +#define ASCII_5D KEY_9 + ALTGR_MASK // 93 ] +#define ASCII_5E CIRCUMFLEX_BITS + KEY_SPACE // 94 ^ +#define ASCII_5F KEY_EQUAL + SHIFT_MASK // 95 _ +#define ASCII_60 GRAVE_ACCENT_BITS + KEY_SPACE // 96 ` +#define ASCII_61 KEY_A // 97 a +#define ASCII_62 KEY_B // 98 b +#define ASCII_63 KEY_C // 99 c +#define ASCII_64 KEY_D // 100 d +#define ASCII_65 KEY_E // 101 e +#define ASCII_66 KEY_F // 102 f +#define ASCII_67 KEY_G // 103 g +#define ASCII_68 KEY_H // 104 h +#define ASCII_69 KEY_QUOTE // 105 i +#define ASCII_6A KEY_J // 106 j +#define ASCII_6B KEY_K // 107 k +#define ASCII_6C KEY_L // 108 l +#define ASCII_6D KEY_M // 109 m +#define ASCII_6E KEY_N // 110 n +#define ASCII_6F KEY_O // 111 o +#define ASCII_70 KEY_P // 112 p +#define ASCII_71 KEY_Q // 113 q +#define ASCII_72 KEY_R // 114 r +#define ASCII_73 KEY_S // 115 s +#define ASCII_74 KEY_T // 116 t +#define ASCII_75 KEY_U // 117 u +#define ASCII_76 KEY_V // 118 v +#define ASCII_77 KEY_W // 119 w +#define ASCII_78 KEY_X // 120 x +#define ASCII_79 KEY_Y // 121 y +#define ASCII_7A KEY_Z // 122 z +#define ASCII_7B KEY_7 + ALTGR_MASK // 123 { +#define ASCII_7C KEY_EQUAL + ALTGR_MASK // 124 | +#define ASCII_7D KEY_0 + ALTGR_MASK // 125 } +#define ASCII_7E TILDE_BITS + KEY_SPACE // 126 ~ +#define ASCII_7F KEY_BACKSPACE // 127 + +#define ISO_8859_1_A0 KEY_SPACE // 160 Nonbreakng Space +#define ISO_8859_1_A1 0 // 161 ¡ Inverted Exclamation +#define ISO_8859_1_A2 0 // 162 ¢ Cent SIGN +#define ISO_8859_1_A3 KEY_2 + ALTGR_MASK // 163 £ Pound Sign +#define ISO_8859_1_A4 0 // 164 ¤ Currency or Euro Sign +#define ISO_8859_1_A5 0 // 165 ¥ YEN SIGN +#define ISO_8859_1_A6 0 // 166 ¦ BROKEN BAR ?? +#define ISO_8859_1_A7 0 // 167 § SECTION SIGN +#define ISO_8859_1_A8 DIAERESIS_BITS + KEY_SPACE // 168 ¨ DIAERESIS +#define ISO_8859_1_A9 0 // 169 © COPYRIGHT SIGN +#define ISO_8859_1_AA 0 // 170 ª FEMININE ORDINAL +#define ISO_8859_1_AB 0 // 171 « LEFT DOUBLE ANGLE QUOTE +#define ISO_8859_1_AC 0 // 172 ¬ NOT SIGN ?? +#define ISO_8859_1_AD 0 // 173 SOFT HYPHEN +#define ISO_8859_1_AE 0 // 174 ® REGISTERED SIGN +#define ISO_8859_1_AF 0 // 175 ¯ MACRON +#define ISO_8859_1_B0 0 // 176 ° DEGREE SIGN +#define ISO_8859_1_B1 0 // 177 ± PLUS-MINUS SIGN +#define ISO_8859_1_B2 0 // 178 ² SUPERSCRIPT TWO +#define ISO_8859_1_B3 0 // 179 ³ SUPERSCRIPT THREE +#define ISO_8859_1_B4 ACUTE_ACCENT_BITS + KEY_SPACE // 180 ´ ACUTE ACCENT +#define ISO_8859_1_B5 0 // 181 µ MICRO SIGN +#define ISO_8859_1_B6 0 // 182 ¶ PILCROW SIGN +#define ISO_8859_1_B7 0 // 183 · MIDDLE DOT +#define ISO_8859_1_B8 0 // 184 ¸ CEDILLA +#define ISO_8859_1_B9 0 // 185 ¹ SUPERSCRIPT ONE +#define ISO_8859_1_BA 0 // 186 º MASCULINE ORDINAL +#define ISO_8859_1_BB 0 // 187 » RIGHT DOUBLE ANGLE QUOTE +#define ISO_8859_1_BC 0 // 188 ¼ FRACTION ONE QUARTER +#define ISO_8859_1_BD KEY_5 + ALTGR_MASK // 189 ½ FRACTION ONE HALF +#define ISO_8859_1_BE 0 // 190 ¾ FRACTION THREE QUARTERS +#define ISO_8859_1_BF 0 // 191 ¿ INVERTED QUESTION MARK +#define ISO_8859_1_C0 GRAVE_ACCENT_BITS + KEY_A + SHIFT_MASK // 192 À A GRAVE +#define ISO_8859_1_C1 ACUTE_ACCENT_BITS + KEY_A + SHIFT_MASK // 193 à A ACUTE +#define ISO_8859_1_C2 CIRCUMFLEX_BITS + KEY_A + SHIFT_MASK // 194 Â A CIRCUMFLEX +#define ISO_8859_1_C3 TILDE_BITS + KEY_A + SHIFT_MASK // 195 Ã A TILDE +#define ISO_8859_1_C4 DIAERESIS_BITS + KEY_A + SHIFT_MASK // 196 Ä A DIAERESIS +#define ISO_8859_1_C5 0 // 197 Å A RING ABOVE +#define ISO_8859_1_C6 KEY_A + ALTGR_MASK // 198 Æ AE +#define ISO_8859_1_C7 KEY_PERIOD + SHIFT_MASK // 199 Ç C CEDILLA +#define ISO_8859_1_C8 GRAVE_ACCENT_BITS + KEY_E + SHIFT_MASK // 200 È E GRAVE +#define ISO_8859_1_C9 ACUTE_ACCENT_BITS + KEY_E + SHIFT_MASK // 201 É E ACUTE +#define ISO_8859_1_CA CIRCUMFLEX_BITS + KEY_E + SHIFT_MASK // 202 Ê E CIRCUMFLEX +#define ISO_8859_1_CB DIAERESIS_BITS + KEY_E + SHIFT_MASK // 203 Ë E DIAERESIS +#define ISO_8859_1_CC GRAVE_ACCENT_BITS + KEY_I + SHIFT_MASK // 204 Ì I GRAVE +#define ISO_8859_1_CD ACUTE_ACCENT_BITS + KEY_I + SHIFT_MASK // 205 à I ACUTE +#define ISO_8859_1_CE CIRCUMFLEX_BITS + KEY_I + SHIFT_MASK // 206 Î I CIRCUMFLEX +#define ISO_8859_1_CF DIAERESIS_BITS + KEY_I + SHIFT_MASK // 207 à I DIAERESIS +#define ISO_8859_1_D0 0 // 208 à ETH +#define ISO_8859_1_D1 TILDE_BITS + KEY_N + SHIFT_MASK // 209 Ñ N TILDE +#define ISO_8859_1_D2 GRAVE_ACCENT_BITS + KEY_O + SHIFT_MASK // 210 Ò O GRAVE +#define ISO_8859_1_D3 ACUTE_ACCENT_BITS + KEY_O + SHIFT_MASK // 211 Ó O ACUTE +#define ISO_8859_1_D4 CIRCUMFLEX_BITS + KEY_O + SHIFT_MASK // 212 Ô O CIRCUMFLEX +#define ISO_8859_1_D5 TILDE_BITS + KEY_O + SHIFT_MASK // 213 Õ O TILDE +#define ISO_8859_1_D6 KEY_COMMA + SHIFT_MASK // 214 Ö O DIAERESIS +#define ISO_8859_1_D7 0 // 215 × MULTIPLICATION +#define ISO_8859_1_D8 0 // 216 Ø O STROKE +#define ISO_8859_1_D9 GRAVE_ACCENT_BITS + KEY_U + SHIFT_MASK // 217 Ù U GRAVE +#define ISO_8859_1_DA ACUTE_ACCENT_BITS + KEY_U + SHIFT_MASK // 218 Ú U ACUTE +#define ISO_8859_1_DB CIRCUMFLEX_BITS + KEY_U + SHIFT_MASK // 219 Û U CIRCUMFLEX +#define ISO_8859_1_DC KEY_RIGHT_BRACE + SHIFT_MASK // 220 Ü U DIAERESIS +#define ISO_8859_1_DD ACUTE_ACCENT_BITS + KEY_Y + SHIFT_MASK // 221 à Y ACUTE +#define ISO_8859_1_DE 0 // 222 Þ THORN +#define ISO_8859_1_DF KEY_S + ALTGR_MASK // 223 ß SHARP S +#define ISO_8859_1_E0 GRAVE_ACCENT_BITS + KEY_A // 224 à a GRAVE +#define ISO_8859_1_E1 ACUTE_ACCENT_BITS + KEY_A // 225 á a ACUTE +#define ISO_8859_1_E2 CIRCUMFLEX_BITS + KEY_A // 226 â a CIRCUMFLEX +#define ISO_8859_1_E3 TILDE_BITS + KEY_A // 227 ã a TILDE +#define ISO_8859_1_E4 DIAERESIS_BITS + KEY_A // 228 ä a DIAERESIS +#define ISO_8859_1_E5 0 // 229 å a RING ABOVE +#define ISO_8859_1_E6 0 // 230 æ ae +#define ISO_8859_1_E7 KEY_PERIOD // 231 ç c CEDILLA +#define ISO_8859_1_E8 GRAVE_ACCENT_BITS + KEY_E // 232 è e GRAVE +#define ISO_8859_1_E9 KEY_TILDE + SHIFT_MASK // 233 é e ACUTE +#define ISO_8859_1_EA CIRCUMFLEX_BITS + KEY_E // 234 ê e CIRCUMFLEX +#define ISO_8859_1_EB DIAERESIS_BITS + KEY_E // 235 ë e DIAERESIS +#define ISO_8859_1_EC GRAVE_ACCENT_BITS + KEY_I // 236 ì i GRAVE +#define ISO_8859_1_ED ACUTE_ACCENT_BITS + KEY_I // 237 à i ACUTE +#define ISO_8859_1_EE CIRCUMFLEX_BITS + KEY_I // 238 î i CIRCUMFLEX +#define ISO_8859_1_EF DIAERESIS_BITS + KEY_I // 239 ï i DIAERESIS +#define ISO_8859_1_F0 0 // 240 ð ETH +#define ISO_8859_1_F1 TILDE_BITS + KEY_N // 241 ñ n TILDE +#define ISO_8859_1_F2 GRAVE_ACCENT_BITS + KEY_O // 242 ò o GRAVE +#define ISO_8859_1_F3 ACUTE_ACCENT_BITS + KEY_O // 243 ó o ACUTE +#define ISO_8859_1_F4 CIRCUMFLEX_BITS + KEY_O // 244 ô o CIRCUMFLEX +#define ISO_8859_1_F5 TILDE_BITS + KEY_O // 245 õ o TILDE +#define ISO_8859_1_F6 KEY_COMMA // 246 ö o DIAERESIS +#define ISO_8859_1_F7 0 // 247 ÷ DIVISION +#define ISO_8859_1_F8 0 // 248 ø o STROKE +#define ISO_8859_1_F9 GRAVE_ACCENT_BITS + KEY_U // 249 ù u GRAVE +#define ISO_8859_1_FA ACUTE_ACCENT_BITS + KEY_U // 250 ú u ACUTE +#define ISO_8859_1_FB CIRCUMFLEX_BITS + KEY_U // 251 û u CIRCUMFLEX +#define ISO_8859_1_FC KEY_RIGHT_BRACE // 252 ü u DIAERESIS +#define ISO_8859_1_FD ACUTE_ACCENT_BITS + KEY_Y // 253 ý y ACUTE +#define ISO_8859_1_FE 0 // 254 þ THORN +#define ISO_8859_1_FF DIAERESIS_BITS + KEY_Y // 255 ÿ y DIAERESIS +#define UNICODE_20AC KEY_E + ALTGR_MASK // € Euro Sign + +// not yet implemented +#define UNICODE_EXTRA00 0x20AC +#define KEYCODE_EXTRA00 KEY_E + ALTGR_MASK // 20AC € Euro Sign +#define UNICODE_EXTRA01 0x011E +#define KEYCODE_EXTRA01 KEY_LEFT_BRACE + SHIFT_MASK // 011E Ğ Latin capital letter G with breve +#define UNICODE_EXTRA02 0x011F +#define KEYCODE_EXTRA02 KEY_LEFT_BRACE // 011F ğ Latin small letter g with breve +#define UNICODE_EXTRA03 0x0130 +#define KEYCODE_EXTRA03 KEY_QUOTE + SHIFT_MASK // 0130 İ Latin captial letter I with dot above +#define UNICODE_EXTRA04 0x0131 +#define KEYCODE_EXTRA04 KEY_I // 0131 ı Latin small letter dotless i +#define UNICODE_EXTRA05 0x015E +#define KEYCODE_EXTRA05 KEY_SEMICOLON + SHIFT_MASK // 015E Ş Latin capital letter S with cedilla +#define UNICODE_EXTRA06 0x0151 +#define KEYCODE_EXTRA06 KEY_SEMICOLON // 0151 ş Latin small letter s with cedilla + +#endif // LAYOUT_TURKISH + + + + + + + + + +extern const KEYCODE_TYPE keycodes_ascii[]; +extern const KEYCODE_TYPE keycodes_iso_8859_1[]; + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif diff --git a/teensy3/main.cpp b/teensy3/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a67502a4c70cd189132adf693b9541c1f212fc0e --- /dev/null +++ b/teensy3/main.cpp @@ -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 +} + diff --git a/teensy3/math_helper.c b/teensy3/math_helper.c new file mode 100644 index 0000000000000000000000000000000000000000..976ca2d3fa5b097b26af88890afc4f9ff7c1ba56 --- /dev/null +++ b/teensy3/math_helper.c @@ -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; + } + + } +} + + + + diff --git a/teensy3/math_helper.h b/teensy3/math_helper.h new file mode 100644 index 0000000000000000000000000000000000000000..934a75d45cfdcc40a4996073147f07f76200c09b --- /dev/null +++ b/teensy3/math_helper.h @@ -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 + diff --git a/teensy3/mk20dx128.c b/teensy3/mk20dx128.c new file mode 100644 index 0000000000000000000000000000000000000000..348050ccbca3eb536d5f4bf5534f594e9ef34c72 --- /dev/null +++ b/teensy3/mk20dx128.c @@ -0,0 +1,371 @@ +/* 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); // die +} + +void unused_isr(void) +{ + while (1); // die +} + +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; + + 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 + + // 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) +{ +} + diff --git a/teensy3/mk20dx128.h b/teensy3/mk20dx128.h new file mode 100644 index 0000000000000000000000000000000000000000..95af88e7d9c59e0227ca34e46df71359d4352746 --- /dev/null +++ b/teensy3/mk20dx128.h @@ -0,0 +1,1613 @@ +/* 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 _mk20dx128_h_ +#define _mk20dx128_h_ + +//#define F_CPU 96000000 +//#define F_CPU 48000000 +//#define F_CPU 24000000 +//#define F_BUS 48000000 +//#define F_BUS 24000000 +//#define F_MEM 24000000 + +#if (F_CPU == 96000000) + #define F_BUS 48000000 + #define F_MEM 24000000 +#elif (F_CPU == 48000000) + #define F_BUS 48000000 + #define F_MEM 24000000 +#elif (F_CPU == 24000000) + #define F_BUS 24000000 + #define F_MEM 24000000 +#endif + + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#include <stdint.h> +#ifdef __cplusplus +extern "C" { +#endif + +// chapter 11: Port control and interrupts (PORT) +#define PORTA_PCR0 *(volatile uint32_t *)0x40049000 // Pin Control Register n +#define PORT_PCR_ISF (uint32_t)0x01000000 // Interrupt Status Flag +#define PORT_PCR_IRQC(n) (uint32_t)(((n) & 15) << 16) // Interrupt Configuration +#define PORT_PCR_IRQC_MASK (uint32_t)0x000F0000 +#define PORT_PCR_LK (uint32_t)0x00008000 // Lock Register +#define PORT_PCR_MUX(n) (uint32_t)(((n) & 7) << 8) // Pin Mux Control +#define PORT_PCR_MUX_MASK (uint32_t)0x00000700 +#define PORT_PCR_DSE (uint32_t)0x00000040 // Drive Strength Enable +#define PORT_PCR_ODE (uint32_t)0x00000020 // Open Drain Enable +#define PORT_PCR_PFE (uint32_t)0x00000010 // Passive Filter Enable +#define PORT_PCR_SRE (uint32_t)0x00000004 // Slew Rate Enable +#define PORT_PCR_PE (uint32_t)0x00000002 // Pull Enable +#define PORT_PCR_PS (uint32_t)0x00000001 // Pull Select +#define PORTA_PCR1 *(volatile uint32_t *)0x40049004 // Pin Control Register n +#define PORTA_PCR2 *(volatile uint32_t *)0x40049008 // Pin Control Register n +#define PORTA_PCR3 *(volatile uint32_t *)0x4004900C // Pin Control Register n +#define PORTA_PCR4 *(volatile uint32_t *)0x40049010 // Pin Control Register n +#define PORTA_PCR5 *(volatile uint32_t *)0x40049014 // Pin Control Register n +#define PORTA_PCR6 *(volatile uint32_t *)0x40049018 // Pin Control Register n +#define PORTA_PCR7 *(volatile uint32_t *)0x4004901C // Pin Control Register n +#define PORTA_PCR8 *(volatile uint32_t *)0x40049020 // Pin Control Register n +#define PORTA_PCR9 *(volatile uint32_t *)0x40049024 // Pin Control Register n +#define PORTA_PCR10 *(volatile uint32_t *)0x40049028 // Pin Control Register n +#define PORTA_PCR11 *(volatile uint32_t *)0x4004902C // Pin Control Register n +#define PORTA_PCR12 *(volatile uint32_t *)0x40049030 // Pin Control Register n +#define PORTA_PCR13 *(volatile uint32_t *)0x40049034 // Pin Control Register n +#define PORTA_PCR14 *(volatile uint32_t *)0x40049038 // Pin Control Register n +#define PORTA_PCR15 *(volatile uint32_t *)0x4004903C // Pin Control Register n +#define PORTA_PCR16 *(volatile uint32_t *)0x40049040 // Pin Control Register n +#define PORTA_PCR17 *(volatile uint32_t *)0x40049044 // Pin Control Register n +#define PORTA_PCR18 *(volatile uint32_t *)0x40049048 // Pin Control Register n +#define PORTA_PCR19 *(volatile uint32_t *)0x4004904C // Pin Control Register n +#define PORTA_PCR20 *(volatile uint32_t *)0x40049050 // Pin Control Register n +#define PORTA_PCR21 *(volatile uint32_t *)0x40049054 // Pin Control Register n +#define PORTA_PCR22 *(volatile uint32_t *)0x40049058 // Pin Control Register n +#define PORTA_PCR23 *(volatile uint32_t *)0x4004905C // Pin Control Register n +#define PORTA_PCR24 *(volatile uint32_t *)0x40049060 // Pin Control Register n +#define PORTA_PCR25 *(volatile uint32_t *)0x40049064 // Pin Control Register n +#define PORTA_PCR26 *(volatile uint32_t *)0x40049068 // Pin Control Register n +#define PORTA_PCR27 *(volatile uint32_t *)0x4004906C // Pin Control Register n +#define PORTA_PCR28 *(volatile uint32_t *)0x40049070 // Pin Control Register n +#define PORTA_PCR29 *(volatile uint32_t *)0x40049074 // Pin Control Register n +#define PORTA_PCR30 *(volatile uint32_t *)0x40049078 // Pin Control Register n +#define PORTA_PCR31 *(volatile uint32_t *)0x4004907C // Pin Control Register n +#define PORTA_GPCLR *(volatile uint32_t *)0x40049080 // Global Pin Control Low Register +#define PORTA_GPCHR *(volatile uint32_t *)0x40049084 // Global Pin Control High Register +#define PORTA_ISFR *(volatile uint32_t *)0x400490A0 // Interrupt Status Flag Register +#define PORTB_PCR0 *(volatile uint32_t *)0x4004A000 // Pin Control Register n +#define PORTB_PCR1 *(volatile uint32_t *)0x4004A004 // Pin Control Register n +#define PORTB_PCR2 *(volatile uint32_t *)0x4004A008 // Pin Control Register n +#define PORTB_PCR3 *(volatile uint32_t *)0x4004A00C // Pin Control Register n +#define PORTB_PCR4 *(volatile uint32_t *)0x4004A010 // Pin Control Register n +#define PORTB_PCR5 *(volatile uint32_t *)0x4004A014 // Pin Control Register n +#define PORTB_PCR6 *(volatile uint32_t *)0x4004A018 // Pin Control Register n +#define PORTB_PCR7 *(volatile uint32_t *)0x4004A01C // Pin Control Register n +#define PORTB_PCR8 *(volatile uint32_t *)0x4004A020 // Pin Control Register n +#define PORTB_PCR9 *(volatile uint32_t *)0x4004A024 // Pin Control Register n +#define PORTB_PCR10 *(volatile uint32_t *)0x4004A028 // Pin Control Register n +#define PORTB_PCR11 *(volatile uint32_t *)0x4004A02C // Pin Control Register n +#define PORTB_PCR12 *(volatile uint32_t *)0x4004A030 // Pin Control Register n +#define PORTB_PCR13 *(volatile uint32_t *)0x4004A034 // Pin Control Register n +#define PORTB_PCR14 *(volatile uint32_t *)0x4004A038 // Pin Control Register n +#define PORTB_PCR15 *(volatile uint32_t *)0x4004A03C // Pin Control Register n +#define PORTB_PCR16 *(volatile uint32_t *)0x4004A040 // Pin Control Register n +#define PORTB_PCR17 *(volatile uint32_t *)0x4004A044 // Pin Control Register n +#define PORTB_PCR18 *(volatile uint32_t *)0x4004A048 // Pin Control Register n +#define PORTB_PCR19 *(volatile uint32_t *)0x4004A04C // Pin Control Register n +#define PORTB_PCR20 *(volatile uint32_t *)0x4004A050 // Pin Control Register n +#define PORTB_PCR21 *(volatile uint32_t *)0x4004A054 // Pin Control Register n +#define PORTB_PCR22 *(volatile uint32_t *)0x4004A058 // Pin Control Register n +#define PORTB_PCR23 *(volatile uint32_t *)0x4004A05C // Pin Control Register n +#define PORTB_PCR24 *(volatile uint32_t *)0x4004A060 // Pin Control Register n +#define PORTB_PCR25 *(volatile uint32_t *)0x4004A064 // Pin Control Register n +#define PORTB_PCR26 *(volatile uint32_t *)0x4004A068 // Pin Control Register n +#define PORTB_PCR27 *(volatile uint32_t *)0x4004A06C // Pin Control Register n +#define PORTB_PCR28 *(volatile uint32_t *)0x4004A070 // Pin Control Register n +#define PORTB_PCR29 *(volatile uint32_t *)0x4004A074 // Pin Control Register n +#define PORTB_PCR30 *(volatile uint32_t *)0x4004A078 // Pin Control Register n +#define PORTB_PCR31 *(volatile uint32_t *)0x4004A07C // Pin Control Register n +#define PORTB_GPCLR *(volatile uint32_t *)0x4004A080 // Global Pin Control Low Register +#define PORTB_GPCHR *(volatile uint32_t *)0x4004A084 // Global Pin Control High Register +#define PORTB_ISFR *(volatile uint32_t *)0x4004A0A0 // Interrupt Status Flag Register +#define PORTC_PCR0 *(volatile uint32_t *)0x4004B000 // Pin Control Register n +#define PORTC_PCR1 *(volatile uint32_t *)0x4004B004 // Pin Control Register n +#define PORTC_PCR2 *(volatile uint32_t *)0x4004B008 // Pin Control Register n +#define PORTC_PCR3 *(volatile uint32_t *)0x4004B00C // Pin Control Register n +#define PORTC_PCR4 *(volatile uint32_t *)0x4004B010 // Pin Control Register n +#define PORTC_PCR5 *(volatile uint32_t *)0x4004B014 // Pin Control Register n +#define PORTC_PCR6 *(volatile uint32_t *)0x4004B018 // Pin Control Register n +#define PORTC_PCR7 *(volatile uint32_t *)0x4004B01C // Pin Control Register n +#define PORTC_PCR8 *(volatile uint32_t *)0x4004B020 // Pin Control Register n +#define PORTC_PCR9 *(volatile uint32_t *)0x4004B024 // Pin Control Register n +#define PORTC_PCR10 *(volatile uint32_t *)0x4004B028 // Pin Control Register n +#define PORTC_PCR11 *(volatile uint32_t *)0x4004B02C // Pin Control Register n +#define PORTC_PCR12 *(volatile uint32_t *)0x4004B030 // Pin Control Register n +#define PORTC_PCR13 *(volatile uint32_t *)0x4004B034 // Pin Control Register n +#define PORTC_PCR14 *(volatile uint32_t *)0x4004B038 // Pin Control Register n +#define PORTC_PCR15 *(volatile uint32_t *)0x4004B03C // Pin Control Register n +#define PORTC_PCR16 *(volatile uint32_t *)0x4004B040 // Pin Control Register n +#define PORTC_PCR17 *(volatile uint32_t *)0x4004B044 // Pin Control Register n +#define PORTC_PCR18 *(volatile uint32_t *)0x4004B048 // Pin Control Register n +#define PORTC_PCR19 *(volatile uint32_t *)0x4004B04C // Pin Control Register n +#define PORTC_PCR20 *(volatile uint32_t *)0x4004B050 // Pin Control Register n +#define PORTC_PCR21 *(volatile uint32_t *)0x4004B054 // Pin Control Register n +#define PORTC_PCR22 *(volatile uint32_t *)0x4004B058 // Pin Control Register n +#define PORTC_PCR23 *(volatile uint32_t *)0x4004B05C // Pin Control Register n +#define PORTC_PCR24 *(volatile uint32_t *)0x4004B060 // Pin Control Register n +#define PORTC_PCR25 *(volatile uint32_t *)0x4004B064 // Pin Control Register n +#define PORTC_PCR26 *(volatile uint32_t *)0x4004B068 // Pin Control Register n +#define PORTC_PCR27 *(volatile uint32_t *)0x4004B06C // Pin Control Register n +#define PORTC_PCR28 *(volatile uint32_t *)0x4004B070 // Pin Control Register n +#define PORTC_PCR29 *(volatile uint32_t *)0x4004B074 // Pin Control Register n +#define PORTC_PCR30 *(volatile uint32_t *)0x4004B078 // Pin Control Register n +#define PORTC_PCR31 *(volatile uint32_t *)0x4004B07C // Pin Control Register n +#define PORTC_GPCLR *(volatile uint32_t *)0x4004B080 // Global Pin Control Low Register +#define PORTC_GPCHR *(volatile uint32_t *)0x4004B084 // Global Pin Control High Register +#define PORTC_ISFR *(volatile uint32_t *)0x4004B0A0 // Interrupt Status Flag Register +#define PORTD_PCR0 *(volatile uint32_t *)0x4004C000 // Pin Control Register n +#define PORTD_PCR1 *(volatile uint32_t *)0x4004C004 // Pin Control Register n +#define PORTD_PCR2 *(volatile uint32_t *)0x4004C008 // Pin Control Register n +#define PORTD_PCR3 *(volatile uint32_t *)0x4004C00C // Pin Control Register n +#define PORTD_PCR4 *(volatile uint32_t *)0x4004C010 // Pin Control Register n +#define PORTD_PCR5 *(volatile uint32_t *)0x4004C014 // Pin Control Register n +#define PORTD_PCR6 *(volatile uint32_t *)0x4004C018 // Pin Control Register n +#define PORTD_PCR7 *(volatile uint32_t *)0x4004C01C // Pin Control Register n +#define PORTD_PCR8 *(volatile uint32_t *)0x4004C020 // Pin Control Register n +#define PORTD_PCR9 *(volatile uint32_t *)0x4004C024 // Pin Control Register n +#define PORTD_PCR10 *(volatile uint32_t *)0x4004C028 // Pin Control Register n +#define PORTD_PCR11 *(volatile uint32_t *)0x4004C02C // Pin Control Register n +#define PORTD_PCR12 *(volatile uint32_t *)0x4004C030 // Pin Control Register n +#define PORTD_PCR13 *(volatile uint32_t *)0x4004C034 // Pin Control Register n +#define PORTD_PCR14 *(volatile uint32_t *)0x4004C038 // Pin Control Register n +#define PORTD_PCR15 *(volatile uint32_t *)0x4004C03C // Pin Control Register n +#define PORTD_PCR16 *(volatile uint32_t *)0x4004C040 // Pin Control Register n +#define PORTD_PCR17 *(volatile uint32_t *)0x4004C044 // Pin Control Register n +#define PORTD_PCR18 *(volatile uint32_t *)0x4004C048 // Pin Control Register n +#define PORTD_PCR19 *(volatile uint32_t *)0x4004C04C // Pin Control Register n +#define PORTD_PCR20 *(volatile uint32_t *)0x4004C050 // Pin Control Register n +#define PORTD_PCR21 *(volatile uint32_t *)0x4004C054 // Pin Control Register n +#define PORTD_PCR22 *(volatile uint32_t *)0x4004C058 // Pin Control Register n +#define PORTD_PCR23 *(volatile uint32_t *)0x4004C05C // Pin Control Register n +#define PORTD_PCR24 *(volatile uint32_t *)0x4004C060 // Pin Control Register n +#define PORTD_PCR25 *(volatile uint32_t *)0x4004C064 // Pin Control Register n +#define PORTD_PCR26 *(volatile uint32_t *)0x4004C068 // Pin Control Register n +#define PORTD_PCR27 *(volatile uint32_t *)0x4004C06C // Pin Control Register n +#define PORTD_PCR28 *(volatile uint32_t *)0x4004C070 // Pin Control Register n +#define PORTD_PCR29 *(volatile uint32_t *)0x4004C074 // Pin Control Register n +#define PORTD_PCR30 *(volatile uint32_t *)0x4004C078 // Pin Control Register n +#define PORTD_PCR31 *(volatile uint32_t *)0x4004C07C // Pin Control Register n +#define PORTD_GPCLR *(volatile uint32_t *)0x4004C080 // Global Pin Control Low Register +#define PORTD_GPCHR *(volatile uint32_t *)0x4004C084 // Global Pin Control High Register +#define PORTD_ISFR *(volatile uint32_t *)0x4004C0A0 // Interrupt Status Flag Register +#define PORTE_PCR0 *(volatile uint32_t *)0x4004D000 // Pin Control Register n +#define PORTE_PCR1 *(volatile uint32_t *)0x4004D004 // Pin Control Register n +#define PORTE_PCR2 *(volatile uint32_t *)0x4004D008 // Pin Control Register n +#define PORTE_PCR3 *(volatile uint32_t *)0x4004D00C // Pin Control Register n +#define PORTE_PCR4 *(volatile uint32_t *)0x4004D010 // Pin Control Register n +#define PORTE_PCR5 *(volatile uint32_t *)0x4004D014 // Pin Control Register n +#define PORTE_PCR6 *(volatile uint32_t *)0x4004D018 // Pin Control Register n +#define PORTE_PCR7 *(volatile uint32_t *)0x4004D01C // Pin Control Register n +#define PORTE_PCR8 *(volatile uint32_t *)0x4004D020 // Pin Control Register n +#define PORTE_PCR9 *(volatile uint32_t *)0x4004D024 // Pin Control Register n +#define PORTE_PCR10 *(volatile uint32_t *)0x4004D028 // Pin Control Register n +#define PORTE_PCR11 *(volatile uint32_t *)0x4004D02C // Pin Control Register n +#define PORTE_PCR12 *(volatile uint32_t *)0x4004D030 // Pin Control Register n +#define PORTE_PCR13 *(volatile uint32_t *)0x4004D034 // Pin Control Register n +#define PORTE_PCR14 *(volatile uint32_t *)0x4004D038 // Pin Control Register n +#define PORTE_PCR15 *(volatile uint32_t *)0x4004D03C // Pin Control Register n +#define PORTE_PCR16 *(volatile uint32_t *)0x4004D040 // Pin Control Register n +#define PORTE_PCR17 *(volatile uint32_t *)0x4004D044 // Pin Control Register n +#define PORTE_PCR18 *(volatile uint32_t *)0x4004D048 // Pin Control Register n +#define PORTE_PCR19 *(volatile uint32_t *)0x4004D04C // Pin Control Register n +#define PORTE_PCR20 *(volatile uint32_t *)0x4004D050 // Pin Control Register n +#define PORTE_PCR21 *(volatile uint32_t *)0x4004D054 // Pin Control Register n +#define PORTE_PCR22 *(volatile uint32_t *)0x4004D058 // Pin Control Register n +#define PORTE_PCR23 *(volatile uint32_t *)0x4004D05C // Pin Control Register n +#define PORTE_PCR24 *(volatile uint32_t *)0x4004D060 // Pin Control Register n +#define PORTE_PCR25 *(volatile uint32_t *)0x4004D064 // Pin Control Register n +#define PORTE_PCR26 *(volatile uint32_t *)0x4004D068 // Pin Control Register n +#define PORTE_PCR27 *(volatile uint32_t *)0x4004D06C // Pin Control Register n +#define PORTE_PCR28 *(volatile uint32_t *)0x4004D070 // Pin Control Register n +#define PORTE_PCR29 *(volatile uint32_t *)0x4004D074 // Pin Control Register n +#define PORTE_PCR30 *(volatile uint32_t *)0x4004D078 // Pin Control Register n +#define PORTE_PCR31 *(volatile uint32_t *)0x4004D07C // Pin Control Register n +#define PORTE_GPCLR *(volatile uint32_t *)0x4004D080 // Global Pin Control Low Register +#define PORTE_GPCHR *(volatile uint32_t *)0x4004D084 // Global Pin Control High Register +#define PORTE_ISFR *(volatile uint32_t *)0x4004D0A0 // Interrupt Status Flag Register + +// Chapter 12: System Integration Module (SIM) +#define SIM_SOPT1 *(volatile uint32_t *)0x40047000 // System Options Register 1 +#define SIM_SOPT1CFG *(volatile uint32_t *)0x40047004 // SOPT1 Configuration Register +#define SIM_SOPT2 *(volatile uint32_t *)0x40048004 // System Options Register 2 +#define SIM_SOPT2_USBSRC (uint32_t)0x00040000 // 0=USB_CLKIN, 1=FFL/PLL +#define SIM_SOPT2_PLLFLLSEL (uint32_t)0x00010000 // 0=FLL, 1=PLL +#define SIM_SOPT2_TRACECLKSEL (uint32_t)0x00001000 // 0=MCGOUTCLK, 1=CPU +#define SIM_SOPT2_PTD7PAD (uint32_t)0x00000800 // 0=normal, 1=double drive PTD7 +#define SIM_SOPT2_CLKOUTSEL(n) (uint32_t)(((n) & 7) << 5) // Selects the clock to output on the CLKOUT pin. +#define SIM_SOPT2_RTCCLKOUTSEL (uint32_t)0x00000010 // RTC clock out select +#define SIM_SOPT4 *(volatile uint32_t *)0x4004800C // System Options Register 4 +#define SIM_SOPT5 *(volatile uint32_t *)0x40048010 // System Options Register 5 +#define SIM_SOPT7 *(volatile uint32_t *)0x40048018 // System Options Register 7 +#define SIM_SDID *(const uint32_t *)0x40048024 // System Device Identification Register +#define SIM_SCGC4 *(volatile uint32_t *)0x40048034 // System Clock Gating Control Register 4 +#define SIM_SCGC4_VREF (uint32_t)0x00100000 // VREF Clock Gate Control +#define SIM_SCGC4_CMP (uint32_t)0x00080000 // Comparator Clock Gate Control +#define SIM_SCGC4_USBOTG (uint32_t)0x00040000 // USB Clock Gate Control +#define SIM_SCGC4_UART2 (uint32_t)0x00001000 // UART2 Clock Gate Control +#define SIM_SCGC4_UART1 (uint32_t)0x00000800 // UART1 Clock Gate Control +#define SIM_SCGC4_UART0 (uint32_t)0x00000400 // UART0 Clock Gate Control +#define SIM_SCGC4_I2C0 (uint32_t)0x00000040 // I2C0 Clock Gate Control +#define SIM_SCGC4_CMT (uint32_t)0x00000004 // CMT Clock Gate Control +#define SIM_SCGC4_EWM (uint32_t)0x00000002 // EWM Clock Gate Control +#define SIM_SCGC5 *(volatile uint32_t *)0x40048038 // System Clock Gating Control Register 5 +#define SIM_SCGC5_PORTE (uint32_t)0x00002000 // Port E Clock Gate Control +#define SIM_SCGC5_PORTD (uint32_t)0x00001000 // Port D Clock Gate Control +#define SIM_SCGC5_PORTC (uint32_t)0x00000800 // Port C Clock Gate Control +#define SIM_SCGC5_PORTB (uint32_t)0x00000400 // Port B Clock Gate Control +#define SIM_SCGC5_PORTA (uint32_t)0x00000200 // Port A Clock Gate Control +#define SIM_SCGC5_TSI (uint32_t)0x00000020 // Touch Sense Input TSI Clock Gate Control +#define SIM_SCGC5_LPTIMER (uint32_t)0x00000001 // Low Power Timer Access Control +#define SIM_SCGC6 *(volatile uint32_t *)0x4004803C // System Clock Gating Control Register 6 +#define SIM_SCGC6_RTC (uint32_t)0x20000000 // RTC Access +#define SIM_SCGC6_ADC0 (uint32_t)0x08000000 // ADC0 Clock Gate Control +#define SIM_SCGC6_FTM1 (uint32_t)0x02000000 // FTM1 Clock Gate Control +#define SIM_SCGC6_FTM0 (uint32_t)0x01000000 // FTM0 Clock Gate Control +#define SIM_SCGC6_PIT (uint32_t)0x00800000 // PIT Clock Gate Control +#define SIM_SCGC6_PDB (uint32_t)0x00400000 // PDB Clock Gate Control +#define SIM_SCGC6_USBDCD (uint32_t)0x00200000 // USB DCD Clock Gate Control +#define SIM_SCGC6_CRC (uint32_t)0x00040000 // CRC Clock Gate Control +#define SIM_SCGC6_I2S (uint32_t)0x00008000 // I2S Clock Gate Control +#define SIM_SCGC6_SPI0 (uint32_t)0x00001000 // SPI0 Clock Gate Control +#define SIM_SCGC6_DMAMUX (uint32_t)0x00000002 // DMA Mux Clock Gate Control +#define SIM_SCGC6_FTFL (uint32_t)0x00000001 // Flash Memory Clock Gate Control +#define SIM_SCGC7 *(volatile uint32_t *)0x40048040 // System Clock Gating Control Register 7 +#define SIM_SCGC7_DMA (uint32_t)0x00000020 // DMA Clock Gate Control +#define SIM_CLKDIV1 *(volatile uint32_t *)0x40048044 // System Clock Divider Register 1 +#define SIM_CLKDIV1_OUTDIV1(n) (uint32_t)(((n) & 0x0F) << 28) // divide value for the core/system clock +#define SIM_CLKDIV1_OUTDIV2(n) (uint32_t)(((n) & 0x0F) << 24) // divide value for the peripheral clock +#define SIM_CLKDIV1_OUTDIV4(n) (uint32_t)(((n) & 0x0F) << 16) // divide value for the flash clock +#define SIM_CLKDIV2 *(volatile uint32_t *)0x40048048 // System Clock Divider Register 2 +#define SIM_CLKDIV2_USBDIV(n) (uint32_t)(((n) & 0x07) << 1) +#define SIM_CLKDIV2_USBFRAC (uint32_t)0x01 +#define SIM_FCFG1 *(const uint32_t *)0x4004804C // Flash Configuration Register 1 +#define SIM_FCFG2 *(const uint32_t *)0x40048050 // Flash Configuration Register 2 +#define SIM_UIDH *(const uint32_t *)0x40048054 // Unique Identification Register High +#define SIM_UIDMH *(const uint32_t *)0x40048058 // Unique Identification Register Mid-High +#define SIM_UIDML *(const uint32_t *)0x4004805C // Unique Identification Register Mid Low +#define SIM_UIDL *(const uint32_t *)0x40048060 // Unique Identification Register Low + +// Chapter 13: Reset Control Module (RCM) +#define RCM_SRS0 *(volatile uint8_t *)0x4007F000 // System Reset Status Register 0 +#define RCM_SRS1 *(volatile uint8_t *)0x4007F001 // System Reset Status Register 1 +#define RCM_RPFC *(volatile uint8_t *)0x4007F004 // Reset Pin Filter Control Register +#define RCM_RPFW *(volatile uint8_t *)0x4007F005 // Reset Pin Filter Width Register +#define RCM_MR *(volatile uint8_t *)0x4007F007 // Mode Register + +// Chapter 14: System Mode Controller +#define SMC_PMPROT *(volatile uint8_t *)0x4007E000 // Power Mode Protection Register +#define SMC_PMPROT_AVLP (uint8_t)0x20 // Allow very low power modes +#define SMC_PMPROT_ALLS (uint8_t)0x08 // Allow low leakage stop mode +#define SMC_PMPROT_AVLLS (uint8_t)0x02 // Allow very low leakage stop mode +#define SMC_PMCTRL *(volatile uint8_t *)0x4007E001 // Power Mode Control Register +#define SMC_PMCTRL_LPWUI (uint8_t)0x80 // Low Power Wake Up on Interrupt +#define SMC_PMCTRL_RUNM(n) (uint8_t)(((n) & 0x03) << 5) // Run Mode Control +#define SMC_PMCTRL_STOPA (uint8_t)0x08 // Stop Aborted +#define SMC_PMCTRL_STOPM(n) (uint8_t)((n) & 0x07) // Stop Mode Control +#define SMC_VLLSCTRL *(volatile uint8_t *)0x4007E002 // VLLS Control Register +#define SMC_VLLSCTRL_PORPO (uint8_t)0x20 // POR Power Option +#define SMC_VLLSCTRL_VLLSM(n) (uint8_t)((n) & 0x07) // VLLS Mode Control +#define SMC_PMSTAT *(volatile uint8_t *)0x4007E003 // Power Mode Status Register +#define SMC_PMSTAT_RUN (uint8_t)0x01 // Current power mode is RUN +#define SMC_PMSTAT_STOP (uint8_t)0x02 // Current power mode is STOP +#define SMC_PMSTAT_VLPR (uint8_t)0x04 // Current power mode is VLPR +#define SMC_PMSTAT_VLPW (uint8_t)0x08 // Current power mode is VLPW +#define SMC_PMSTAT_VLPS (uint8_t)0x10 // Current power mode is VLPS +#define SMC_PMSTAT_LLS (uint8_t)0x20 // Current power mode is LLS +#define SMC_PMSTAT_VLLS (uint8_t)0x40 // Current power mode is VLLS + +// Chapter 15: Power Management Controller +#define PMC_LVDSC1 *(volatile uint8_t *)0x4007D000 // Low Voltage Detect Status And Control 1 register +#define PMC_LVDSC1_LVDF (uint8_t)0x80 // Low-Voltage Detect Flag +#define PMC_LVDSC1_LVDACK (uint8_t)0x40 // Low-Voltage Detect Acknowledge +#define PMC_LVDSC1_LVDIE (uint8_t)0x20 // Low-Voltage Detect Interrupt Enable +#define PMC_LVDSC1_LVDRE (uint8_t)0x10 // Low-Voltage Detect Reset Enable +#define PMC_LVDSC1_LVDV(n) (uint8_t)((n) & 0x03) // Low-Voltage Detect Voltage Select +#define PMC_LVDSC2 *(volatile uint8_t *)0x4007D001 // Low Voltage Detect Status And Control 2 register +#define PMC_LVDSC2_LVWF (uint8_t)0x80 // Low-Voltage Warning Flag +#define PMC_LVDSC2_LVWACK (uint8_t)0x40 // Low-Voltage Warning Acknowledge +#define PMC_LVDSC2_LVWIE (uint8_t)0x20 // Low-Voltage Warning Interrupt Enable +#define PMC_LVDSC2_LVWV(n) (uint8_t)((n) & 0x03) // Low-Voltage Warning Voltage Select +#define PMC_REGSC *(volatile uint8_t *)0x4007D002 // Regulator Status And Control register +#define PMC_REGSC_BGEN (uint8_t)0x10 // Bandgap Enable In VLPx Operation +#define PMC_REGSC_ACKISO (uint8_t)0x08 // Acknowledge Isolation +#define PMC_REGSC_REGONS (uint8_t)0x04 // Regulator In Run Regulation Status +#define PMC_REGSC_BGBE (uint8_t)0x01 // Bandgap Buffer Enable + +// Chapter 16: Low-Leakage Wakeup Unit (LLWU) +#define LLWU_PE1 *(volatile uint8_t *)0x4007C000 // LLWU Pin Enable 1 register +#define LLWU_PE2 *(volatile uint8_t *)0x4007C001 // LLWU Pin Enable 2 register +#define LLWU_PE3 *(volatile uint8_t *)0x4007C002 // LLWU Pin Enable 3 register +#define LLWU_PE4 *(volatile uint8_t *)0x4007C003 // LLWU Pin Enable 4 register +#define LLWU_ME *(volatile uint8_t *)0x4007C004 // LLWU Module Enable register +#define LLWU_F1 *(volatile uint8_t *)0x4007C005 // LLWU Flag 1 register +#define LLWU_F2 *(volatile uint8_t *)0x4007C006 // LLWU Flag 2 register +#define LLWU_F3 *(volatile uint8_t *)0x4007C007 // LLWU Flag 3 register +#define LLWU_FILT1 *(volatile uint8_t *)0x4007C008 // LLWU Pin Filter 1 register +#define LLWU_FILT2 *(volatile uint8_t *)0x4007C009 // LLWU Pin Filter 2 register +#define LLWU_RST *(volatile uint8_t *)0x4007C00A // LLWU Reset Enable register + +// Chapter 17: Miscellaneous Control Module (MCM) +#define MCM_PLASC *(volatile uint16_t *)0xE0080008 // Crossbar Switch (AXBS) Slave Configuration +#define MCM_PLAMC *(volatile uint16_t *)0xE008000A // Crossbar Switch (AXBS) Master Configuration +#define MCM_PLACR *(volatile uint32_t *)0xE008000C // Crossbar Switch (AXBS) Control Register + +// Chapter 20: Direct Memory Access Multiplexer (DMAMUX) +#define DMAMUX0_CHCFG0 *(volatile uint8_t *)0x40021000 // Channel Configuration register +#define DMAMUX0_CHCFG1 *(volatile uint8_t *)0x40021001 // Channel Configuration register +#define DMAMUX0_CHCFG2 *(volatile uint8_t *)0x40021002 // Channel Configuration register +#define DMAMUX0_CHCFG3 *(volatile uint8_t *)0x40021003 // Channel Configuration register +#define DMAMUX0_CHCFG4 *(volatile uint8_t *)0x40021004 // Channel Configuration register +#define DMAMUX0_CHCFG5 *(volatile uint8_t *)0x40021005 // Channel Configuration register +#define DMAMUX0_CHCFG6 *(volatile uint8_t *)0x40021006 // Channel Configuration register +#define DMAMUX0_CHCFG7 *(volatile uint8_t *)0x40021007 // Channel Configuration register +#define DMAMUX0_CHCFG8 *(volatile uint8_t *)0x40021008 // Channel Configuration register +#define DMAMUX0_CHCFG9 *(volatile uint8_t *)0x40021009 // Channel Configuration register +#define DMAMUX0_CHCFG10 *(volatile uint8_t *)0x4002100A // Channel Configuration register +#define DMAMUX0_CHCFG11 *(volatile uint8_t *)0x4002100B // Channel Configuration register +#define DMAMUX0_CHCFG12 *(volatile uint8_t *)0x4002100C // Channel Configuration register +#define DMAMUX0_CHCFG13 *(volatile uint8_t *)0x4002100D // Channel Configuration register +#define DMAMUX0_CHCFG14 *(volatile uint8_t *)0x4002100E // Channel Configuration register +#define DMAMUX0_CHCFG15 *(volatile uint8_t *)0x4002100F // Channel Configuration register +#define DMAMUX_DISABLE 0 +#define DMAMUX_TRIG 64 +#define DMAMUX_ENABLE 128 +#define DMAMUX_SOURCE_UART0_RX 2 +#define DMAMUX_SOURCE_UART0_TX 3 +#define DMAMUX_SOURCE_UART1_RX 4 +#define DMAMUX_SOURCE_UART1_TX 5 +#define DMAMUX_SOURCE_UART2_RX 6 +#define DMAMUX_SOURCE_UART2_TX 7 +#define DMAMUX_SOURCE_I2S0_RX 14 +#define DMAMUX_SOURCE_I2S0_TX 15 +#define DMAMUX_SOURCE_SPI0_RX 16 +#define DMAMUX_SOURCE_SPI0_TX 17 +#define DMAMUX_SOURCE_I2C0 22 +#define DMAMUX_SOURCE_FTM0_CH0 24 +#define DMAMUX_SOURCE_FTM0_CH1 25 +#define DMAMUX_SOURCE_FTM0_CH2 26 +#define DMAMUX_SOURCE_FTM0_CH3 27 +#define DMAMUX_SOURCE_FTM0_CH4 28 +#define DMAMUX_SOURCE_FTM0_CH5 29 +#define DMAMUX_SOURCE_FTM0_CH6 30 +#define DMAMUX_SOURCE_FTM0_CH7 31 +#define DMAMUX_SOURCE_FTM1_CH0 32 +#define DMAMUX_SOURCE_FTM1_CH1 33 +#define DMAMUX_SOURCE_ADC0 40 +#define DMAMUX_SOURCE_CMP0 42 +#define DMAMUX_SOURCE_CMP1 43 +#define DMAMUX_SOURCE_CMT 47 +#define DMAMUX_SOURCE_PDB 48 +#define DMAMUX_SOURCE_PORTA 49 +#define DMAMUX_SOURCE_PORTB 50 +#define DMAMUX_SOURCE_PORTC 51 +#define DMAMUX_SOURCE_PORTD 52 +#define DMAMUX_SOURCE_PORTE 53 +#define DMAMUX_SOURCE_ALWAYS0 54 +#define DMAMUX_SOURCE_ALWAYS1 55 +#define DMAMUX_SOURCE_ALWAYS2 56 +#define DMAMUX_SOURCE_ALWAYS3 57 +#define DMAMUX_SOURCE_ALWAYS4 58 +#define DMAMUX_SOURCE_ALWAYS5 59 +#define DMAMUX_SOURCE_ALWAYS6 60 +#define DMAMUX_SOURCE_ALWAYS7 61 +#define DMAMUX_SOURCE_ALWAYS8 62 +#define DMAMUX_SOURCE_ALWAYS9 63 + +// Chapter 21: Direct Memory Access Controller (eDMA) +#define DMA_CR *(volatile uint32_t *)0x40008000 // Control Register +#define DMA_ES *(volatile uint32_t *)0x40008004 // Error Status Register +#define DMA_ERQ *(volatile uint32_t *)0x4000800C // Enable Request Register +#define DMA_EEI *(volatile uint32_t *)0x40008014 // Enable Error Interrupt Register +#define DMA_CEEI *(volatile uint8_t *)0x40008018 // Clear Enable Error Interrupt Register +#define DMA_SEEI *(volatile uint8_t *)0x40008019 // Set Enable Error Interrupt Register +#define DMA_CERQ *(volatile uint8_t *)0x4000801A // Clear Enable Request Register +#define DMA_SERQ *(volatile uint8_t *)0x4000801B // Set Enable Request Register +#define DMA_CDNE *(volatile uint8_t *)0x4000801C // Clear DONE Status Bit Register +#define DMA_SSRT *(volatile uint8_t *)0x4000801D // Set START Bit Register +#define DMA_CERR *(volatile uint8_t *)0x4000801E // Clear Error Register +#define DMA_CINT *(volatile uint8_t *)0x4000801F // Clear Interrupt Request Register +#define DMA_INT *(volatile uint32_t *)0x40008024 // Interrupt Request Register +#define DMA_ERR *(volatile uint32_t *)0x4000802C // Error Register +#define DMA_HRS *(volatile uint32_t *)0x40008034 // Hardware Request Status Register +#define DMA_DCHPRI3 *(volatile uint8_t *)0x40008100 // Channel n Priority Register +#define DMA_DCHPRI2 *(volatile uint8_t *)0x40008101 // Channel n Priority Register +#define DMA_DCHPRI1 *(volatile uint8_t *)0x40008102 // Channel n Priority Register +#define DMA_DCHPRI0 *(volatile uint8_t *)0x40008103 // Channel n Priority Register + +#define DMA_TCD_ATTR_SMOD(n) (((n) & 0x1F) << 11) +#define DMA_TCD_ATTR_SSIZE(n) (((n) & 0x7) << 8) +#define DMA_TCD_ATTR_DMOD(n) (((n) & 0x1F) << 3) +#define DMA_TCD_ATTR_DSIZE(n) (((n) & 0x7) << 0) +#define DMA_TCD_ATTR_SIZE_8BIT 0 +#define DMA_TCD_ATTR_SIZE_16BIT 1 +#define DMA_TCD_ATTR_SIZE_32BIT 2 +#define DMA_TCD_ATTR_SIZE_16BYTE 4 +#define DMA_TCD_ATTR_SIZE_32BYTE 5 +#define DMA_TCD_CSR_BWC(n) (((n) & 0x3) << 14) +#define DMA_TCD_CSR_MAJORLINKCH(n) (((n) & 0x3) << 8) +#define DMA_TCD_CSR_DONE 0x0080 +#define DMA_TCD_CSR_ACTIVE 0x0040 +#define DMA_TCD_CSR_MAJORELINK 0x0020 +#define DMA_TCD_CSR_ESG 0x0010 +#define DMA_TCD_CSR_DREQ 0x0008 +#define DMA_TCD_CSR_INTHALF 0x0004 +#define DMA_TCD_CSR_INTMAJOR 0x0002 +#define DMA_TCD_CSR_START 0x0001 + +#define DMA_TCD0_SADDR *(volatile const void * volatile *)0x40009000 // TCD Source Address +#define DMA_TCD0_SOFF *(volatile int16_t *)0x40009004 // TCD Signed Source Address Offset +#define DMA_TCD0_ATTR *(volatile uint16_t *)0x40009006 // TCD Transfer Attributes +#define DMA_TCD0_NBYTES_MLNO *(volatile uint32_t *)0x40009008 // TCD Minor Byte Count (Minor Loop Disabled) +#define DMA_TCD0_NBYTES_MLOFFNO *(volatile uint32_t *)0x40009008 // TCD Signed Minor Loop Offset (Minor Loop Enabled and Offset Disabled) +#define DMA_TCD0_NBYTES_MLOFFYES *(volatile uint32_t *)0x40009008 // TCD Signed Minor Loop Offset (Minor Loop and Offset Enabled) +#define DMA_TCD0_SLAST *(volatile int32_t *)0x4000900C // TCD Last Source Address Adjustment +#define DMA_TCD0_DADDR *(volatile void * volatile *)0x40009010 // TCD Destination Address +#define DMA_TCD0_DOFF *(volatile int16_t *)0x40009014 // TCD Signed Destination Address Offset +#define DMA_TCD0_CITER_ELINKYES *(volatile uint16_t *)0x40009016 // TCD Current Minor Loop Link, Major Loop Count, Channel Linking Enabled +#define DMA_TCD0_CITER_ELINKNO *(volatile uint16_t *)0x40009016 // ?? +#define DMA_TCD0_DLASTSGA *(volatile int32_t *)0x40009018 // TCD Last Destination Address Adjustment/Scatter Gather Address +#define DMA_TCD0_CSR *(volatile uint16_t *)0x4000901C // TCD Control and Status +#define DMA_TCD0_BITER_ELINKYES *(volatile uint16_t *)0x4000901E // TCD Beginning Minor Loop Link, Major Loop Count, Channel Linking Enabled +#define DMA_TCD0_BITER_ELINKNO *(volatile uint16_t *)0x4000901E // TCD Beginning Minor Loop Link, Major Loop Count, Channel Linking Disabled + +#define DMA_TCD1_SADDR *(volatile const void * volatile *)0x40009020 // TCD Source Address +#define DMA_TCD1_SOFF *(volatile int16_t *)0x40009024 // TCD Signed Source Address Offset +#define DMA_TCD1_ATTR *(volatile uint16_t *)0x40009026 // TCD Transfer Attributes +#define DMA_TCD1_NBYTES_MLNO *(volatile uint32_t *)0x40009028 // TCD Minor Byte Count, Minor Loop Disabled +#define DMA_TCD1_NBYTES_MLOFFNO *(volatile uint32_t *)0x40009028 // TCD Signed Minor Loop Offset, Minor Loop Enabled and Offset Disabled +#define DMA_TCD1_NBYTES_MLOFFYES *(volatile uint32_t *)0x40009028 // TCD Signed Minor Loop Offset, Minor Loop and Offset Enabled +#define DMA_TCD1_SLAST *(volatile int32_t *)0x4000902C // TCD Last Source Address Adjustment +#define DMA_TCD1_DADDR *(volatile void * volatile *)0x40009030 // TCD Destination Address +#define DMA_TCD1_DOFF *(volatile int16_t *)0x40009034 // TCD Signed Destination Address Offset +#define DMA_TCD1_CITER_ELINKYES *(volatile uint16_t *)0x40009036 // TCD Current Minor Loop Link, Major Loop Count, Channel Linking Enabled +#define DMA_TCD1_CITER_ELINKNO *(volatile uint16_t *)0x40009036 // ?? +#define DMA_TCD1_DLASTSGA *(volatile int32_t *)0x40009038 // TCD Last Destination Address Adjustment/Scatter Gather Address +#define DMA_TCD1_CSR *(volatile uint16_t *)0x4000903C // TCD Control and Status +#define DMA_TCD1_BITER_ELINKYES *(volatile uint16_t *)0x4000903E // TCD Beginning Minor Loop Link, Major Loop Count Channel Linking Enabled +#define DMA_TCD1_BITER_ELINKNO *(volatile uint16_t *)0x4000903E // TCD Beginning Minor Loop Link, Major Loop Count, Channel Linking Disabled + +#define DMA_TCD2_SADDR *(volatile const void * volatile *)0x40009040 // TCD Source Address +#define DMA_TCD2_SOFF *(volatile int16_t *)0x40009044 // TCD Signed Source Address Offset +#define DMA_TCD2_ATTR *(volatile uint16_t *)0x40009046 // TCD Transfer Attributes +#define DMA_TCD2_NBYTES_MLNO *(volatile uint32_t *)0x40009048 // TCD Minor Byte Count, Minor Loop Disabled +#define DMA_TCD2_NBYTES_MLOFFNO *(volatile uint32_t *)0x40009048 // TCD Signed Minor Loop Offset, Minor Loop Enabled and Offset Disabled +#define DMA_TCD2_NBYTES_MLOFFYES *(volatile uint32_t *)0x40009048 // TCD Signed Minor Loop Offset, Minor Loop and Offset Enabled +#define DMA_TCD2_SLAST *(volatile int32_t *)0x4000904C // TCD Last Source Address Adjustment +#define DMA_TCD2_DADDR *(volatile void * volatile *)0x40009050 // TCD Destination Address +#define DMA_TCD2_DOFF *(volatile int16_t *)0x40009054 // TCD Signed Destination Address Offset +#define DMA_TCD2_CITER_ELINKYES *(volatile uint16_t *)0x40009056 // TCD Current Minor Loop Link, Major Loop Count, Channel Linking Enabled +#define DMA_TCD2_CITER_ELINKNO *(volatile uint16_t *)0x40009056 // ?? +#define DMA_TCD2_DLASTSGA *(volatile int32_t *)0x40009058 // TCD Last Destination Address Adjustment/Scatter Gather Address +#define DMA_TCD2_CSR *(volatile uint16_t *)0x4000905C // TCD Control and Status +#define DMA_TCD2_BITER_ELINKYES *(volatile uint16_t *)0x4000905E // TCD Beginning Minor Loop Link, Major Loop Count, Channel Linking Enabled +#define DMA_TCD2_BITER_ELINKNO *(volatile uint16_t *)0x4000905E // TCD Beginning Minor Loop Link, Major Loop Count, Channel Linking Disabled + +#define DMA_TCD3_SADDR *(volatile const void * volatile *)0x40009060 // TCD Source Address +#define DMA_TCD3_SOFF *(volatile int16_t *)0x40009064 // TCD Signed Source Address Offset +#define DMA_TCD3_ATTR *(volatile uint16_t *)0x40009066 // TCD Transfer Attributes +#define DMA_TCD3_NBYTES_MLNO *(volatile uint32_t *)0x40009068 // TCD Minor Byte Count, Minor Loop Disabled +#define DMA_TCD3_NBYTES_MLOFFNO *(volatile uint32_t *)0x40009068 // TCD Signed Minor Loop Offset, Minor Loop Enabled and Offset Disabled +#define DMA_TCD3_NBYTES_MLOFFYES *(volatile uint32_t *)0x40009068 // TCD Signed Minor Loop Offset, Minor Loop and Offset Enabled +#define DMA_TCD3_SLAST *(volatile int32_t *)0x4000906C // TCD Last Source Address Adjustment +#define DMA_TCD3_DADDR *(volatile void * volatile *)0x40009070 // TCD Destination Address +#define DMA_TCD3_DOFF *(volatile int16_t *)0x40009074 // TCD Signed Destination Address Offset +#define DMA_TCD3_CITER_ELINKYES *(volatile uint16_t *)0x40009076 // TCD Current Minor Loop Link, Major Loop Count, Channel Linking Enabled +#define DMA_TCD3_CITER_ELINKNO *(volatile uint16_t *)0x40009076 // ?? +#define DMA_TCD3_DLASTSGA *(volatile int32_t *)0x40009078 // TCD Last Destination Address Adjustment/Scatter Gather Address +#define DMA_TCD3_CSR *(volatile uint16_t *)0x4000907C // TCD Control and Status +#define DMA_TCD3_BITER_ELINKYES *(volatile uint16_t *)0x4000907E // TCD Beginning Minor Loop Link, Major Loop Count ,Channel Linking Enabled +#define DMA_TCD3_BITER_ELINKNO *(volatile uint16_t *)0x4000907E // TCD Beginning Minor Loop Link, Major Loop Count ,Channel Linking Disabled + +// Chapter 22: External Watchdog Monitor (EWM) +#define EWM_CTRL *(volatile uint8_t *)0x40061000 // Control Register +#define EWM_SERV *(volatile uint8_t *)0x40061001 // Service Register +#define EWM_CMPL *(volatile uint8_t *)0x40061002 // Compare Low Register +#define EWM_CMPH *(volatile uint8_t *)0x40061003 // Compare High Register + +// Chapter 23: Watchdog Timer (WDOG) +#define WDOG_STCTRLH *(volatile uint16_t *)0x40052000 // Watchdog Status and Control Register High +#define WDOG_STCTRLH_DISTESTWDOG (uint16_t)0x4000 // Allows the WDOG's functional test mode to be disabled permanently. +#define WDOG_STCTRLH_BYTESEL(n) (uint16_t)(((n) & 3) << 12) // selects the byte to be tested when the watchdog is in the byte test mode. +#define WDOG_STCTRLH_TESTSEL (uint16_t)0x0800 +#define WDOG_STCTRLH_TESTWDOG (uint16_t)0x0400 +#define WDOG_STCTRLH_WAITEN (uint16_t)0x0080 +#define WDOG_STCTRLH_STOPEN (uint16_t)0x0040 +#define WDOG_STCTRLH_DBGEN (uint16_t)0x0020 +#define WDOG_STCTRLH_ALLOWUPDATE (uint16_t)0x0010 +#define WDOG_STCTRLH_WINEN (uint16_t)0x0008 +#define WDOG_STCTRLH_IRQRSTEN (uint16_t)0x0004 +#define WDOG_STCTRLH_CLKSRC (uint16_t)0x0002 +#define WDOG_STCTRLH_WDOGEN (uint16_t)0x0001 +#define WDOG_STCTRLL *(volatile uint16_t *)0x40052002 // Watchdog Status and Control Register Low +#define WDOG_TOVALH *(volatile uint16_t *)0x40052004 // Watchdog Time-out Value Register High +#define WDOG_TOVALL *(volatile uint16_t *)0x40052006 // Watchdog Time-out Value Register Low +#define WDOG_WINH *(volatile uint16_t *)0x40052008 // Watchdog Window Register High +#define WDOG_WINL *(volatile uint16_t *)0x4005200A // Watchdog Window Register Low +#define WDOG_REFRESH *(volatile uint16_t *)0x4005200C // Watchdog Refresh register +#define WDOG_UNLOCK *(volatile uint16_t *)0x4005200E // Watchdog Unlock register +#define WDOG_UNLOCK_SEQ1 (uint16_t)0xC520 +#define WDOG_UNLOCK_SEQ2 (uint16_t)0xD928 +#define WDOG_TMROUTH *(volatile uint16_t *)0x40052010 // Watchdog Timer Output Register High +#define WDOG_TMROUTL *(volatile uint16_t *)0x40052012 // Watchdog Timer Output Register Low +#define WDOG_RSTCNT *(volatile uint16_t *)0x40052014 // Watchdog Reset Count register +#define WDOG_PRESC *(volatile uint16_t *)0x40052016 // Watchdog Prescaler register + +// Chapter 24: Multipurpose Clock Generator (MCG) +#define MCG_C1 *(volatile uint8_t *)0x40064000 // MCG Control 1 Register +#define MCG_C1_IREFSTEN (uint8_t)0x01 // Internal Reference Stop Enable, Controls whether or not the internal reference clock remains enabled when the MCG enters Stop mode. +#define MCG_C1_IRCLKEN (uint8_t)0x02 // Internal Reference Clock Enable, Enables the internal reference clock for use as MCGIRCLK. +#define MCG_C1_IREFS (uint8_t)0x04 // Internal Reference Select, Selects the reference clock source for the FLL. +#define MCG_C1_FRDIV(n) (uint8_t)(((n) & 0x07) << 3) // FLL External Reference Divider, Selects the amount to divide down the external reference clock for the FLL +#define MCG_C1_CLKS(n) (uint8_t)(((n) & 0x03) << 6) // Clock Source Select, Selects the clock source for MCGOUTCLK +#define MCG_C2 *(volatile uint8_t *)0x40064001 // MCG Control 2 Register +#define MCG_C2_IRCS (uint8_t)0x01 // Internal Reference Clock Select, Selects between the fast or slow internal reference clock source. +#define MCG_C2_LP (uint8_t)0x02 // Low Power Select, Controls whether the FLL or PLL is disabled in BLPI and BLPE modes. +#define MCG_C2_EREFS (uint8_t)0x04 // External Reference Select, Selects the source for the external reference clock. +#define MCG_C2_HGO0 (uint8_t)0x08 // High Gain Oscillator Select, Controls the crystal oscillator mode of operation +#define MCG_C2_RANGE0(n) (uint8_t)(((n) & 0x03) << 4) // Frequency Range Select, Selects the frequency range for the crystal oscillator +#define MCG_C2_LOCRE0 (uint8_t)0x80 // Loss of Clock Reset Enable, Determines whether an interrupt or a reset request is made following a loss of OSC0 +#define MCG_C3 *(volatile uint8_t *)0x40064002 // MCG Control 3 Register +#define MCG_C3_SCTRIM(n) (uint8_t)(n) // Slow Internal Reference Clock Trim Setting +#define MCG_C4 *(volatile uint8_t *)0x40064003 // MCG Control 4 Register +#define MCG_C4_SCFTRIM (uint8_t)0x01 // Slow Internal Reference Clock Fine Trim +#define MCG_C4_FCTRIM(n) (uint8_t)(((n) & 0x0F) << 1) // Fast Internal Reference Clock Trim Setting +#define MCG_C4_DRST_DRS(n) (uint8_t)(((n) & 0x03) << 5) // DCO Range Select +#define MCG_C4_DMX32 (uint8_t)0x80 // DCO Maximum Frequency with 32.768 kHz Reference, controls whether the DCO frequency range is narrowed +#define MCG_C5 *(volatile uint8_t *)0x40064004 // MCG Control 5 Register +#define MCG_C5_PRDIV0(n) (uint8_t)((n) & 0x1F) // PLL External Reference Divider +#define MCG_C5_PLLSTEN0 (uint8_t)0x20 // PLL Stop Enable +#define MCG_C5_PLLCLKEN0 (uint8_t)0x40 // PLL Clock Enable +#define MCG_C6 *(volatile uint8_t *)0x40064005 // MCG Control 6 Register +#define MCG_C6_VDIV0(n) (uint8_t)((n) & 0x1F) // VCO 0 Divider +#define MCG_C6_CME0 (uint8_t)0x20 // Clock Monitor Enable +#define MCG_C6_PLLS (uint8_t)0x40 // PLL Select, Controls whether the PLL or FLL output is selected as the MCG source when CLKS[1:0]=00. +#define MCG_C6_LOLIE0 (uint8_t)0x80 // Loss of Lock Interrrupt Enable +#define MCG_S *(volatile uint8_t *)0x40064006 // MCG Status Register +#define MCG_S_IRCST (uint8_t)0x01 // Internal Reference Clock Status +#define MCG_S_OSCINIT0 (uint8_t)0x02 // OSC Initialization, resets to 0, is set to 1 after the initialization cycles of the crystal oscillator +#define MCG_S_CLKST(n) (uint8_t)(((n) & 0x03) << 2) // Clock Mode Status, 0=FLL is selected, 1= Internal ref, 2=External ref, 3=PLL +#define MCG_S_CLKST_MASK (uint8_t)0x0C +#define MCG_S_IREFST (uint8_t)0x10 // Internal Reference Status +#define MCG_S_PLLST (uint8_t)0x20 // PLL Select Status +#define MCG_S_LOCK0 (uint8_t)0x40 // Lock Status, 0=PLL Unlocked, 1=PLL Locked +#define MCG_S_LOLS0 (uint8_t)0x80 // Loss of Lock Status +#define MCG_SC *(volatile uint8_t *)0x40064008 // MCG Status and Control Register +#define MCG_SC_LOCS0 (uint8_t)0x01 // OSC0 Loss of Clock Status +#define MCG_SC_FCRDIV(n) (uint8_t)(((n) & 0x07) << 1) // Fast Clock Internal Reference Divider +#define MCG_SC_FLTPRSRV (uint8_t)0x10 // FLL Filter Preserve Enable +#define MCG_SC_ATMF (uint8_t)0x20 // Automatic Trim Machine Fail Flag +#define MCG_SC_ATMS (uint8_t)0x40 // Automatic Trim Machine Select +#define MCG_SC_ATME (uint8_t)0x80 // Automatic Trim Machine Enable +#define MCG_ATCVH *(volatile uint8_t *)0x4006400A // MCG Auto Trim Compare Value High Register +#define MCG_ATCVL *(volatile uint8_t *)0x4006400B // MCG Auto Trim Compare Value Low Register +#define MCG_C7 *(volatile uint8_t *)0x4006400C // MCG Control 7 Register +#define MCG_C8 *(volatile uint8_t *)0x4006400D // MCG Control 8 Register + +// Chapter 25: Oscillator (OSC) +#define OSC0_CR *(volatile uint8_t *)0x40065000 // OSC Control Register +#define OSC_SC16P (uint8_t)0x01 // Oscillator 16 pF Capacitor Load Configure +#define OSC_SC8P (uint8_t)0x02 // Oscillator 8 pF Capacitor Load Configure +#define OSC_SC4P (uint8_t)0x04 // Oscillator 4 pF Capacitor Load Configure +#define OSC_SC2P (uint8_t)0x08 // Oscillator 2 pF Capacitor Load Configure +#define OSC_EREFSTEN (uint8_t)0x20 // External Reference Stop Enable, Controls whether or not the external reference clock (OSCERCLK) remains enabled when MCU enters Stop mode. +#define OSC_ERCLKEN (uint8_t)0x80 // External Reference Enable, Enables external reference clock (OSCERCLK). + +// Chapter 27: Flash Memory Controller (FMC) +#define FMC_PFAPR *(volatile uint32_t *)0x4001F000 // Flash Access Protection +#define FMC_PFB0CR *(volatile uint32_t *)0x4001F004 // Flash Control +#define FMC_TAGVDW0S0 *(volatile uint32_t *)0x4001F100 // Cache Tag Storage +#define FMC_TAGVDW0S1 *(volatile uint32_t *)0x4001F104 // Cache Tag Storage +#define FMC_TAGVDW1S0 *(volatile uint32_t *)0x4001F108 // Cache Tag Storage +#define FMC_TAGVDW1S1 *(volatile uint32_t *)0x4001F10C // Cache Tag Storage +#define FMC_TAGVDW2S0 *(volatile uint32_t *)0x4001F110 // Cache Tag Storage +#define FMC_TAGVDW2S1 *(volatile uint32_t *)0x4001F114 // Cache Tag Storage +#define FMC_TAGVDW3S0 *(volatile uint32_t *)0x4001F118 // Cache Tag Storage +#define FMC_TAGVDW3S1 *(volatile uint32_t *)0x4001F11C // Cache Tag Storage +#define FMC_DATAW0S0 *(volatile uint32_t *)0x4001F200 // Cache Data Storage +#define FMC_DATAW0S1 *(volatile uint32_t *)0x4001F204 // Cache Data Storage +#define FMC_DATAW1S0 *(volatile uint32_t *)0x4001F208 // Cache Data Storage +#define FMC_DATAW1S1 *(volatile uint32_t *)0x4001F20C // Cache Data Storage +#define FMC_DATAW2S0 *(volatile uint32_t *)0x4001F210 // Cache Data Storage +#define FMC_DATAW2S1 *(volatile uint32_t *)0x4001F214 // Cache Data Storage +#define FMC_DATAW3S0 *(volatile uint32_t *)0x4001F218 // Cache Data Storage +#define FMC_DATAW3S1 *(volatile uint32_t *)0x4001F21C // Cache Data Storage + +// Chapter 28: Flash Memory Module (FTFL) +#define FTFL_FSTAT *(volatile uint8_t *)0x40020000 // Flash Status Register +#define FTFL_FSTAT_CCIF (uint8_t)0x80 // Command Complete Interrupt Flag +#define FTFL_FSTAT_RDCOLERR (uint8_t)0x40 // Flash Read Collision Error Flag +#define FTFL_FSTAT_ACCERR (uint8_t)0x20 // Flash Access Error Flag +#define FTFL_FSTAT_FPVIOL (uint8_t)0x10 // Flash Protection Violation Flag +#define FTFL_FSTAT_MGSTAT0 (uint8_t)0x01 // Memory Controller Command Completion Status Flag +#define FTFL_FCNFG *(volatile uint8_t *)0x40020001 // Flash Configuration Register +#define FTFL_FCNFG_CCIE (uint8_t)0x80 // Command Complete Interrupt Enable +#define FTFL_FCNFG_RDCOLLIE (uint8_t)0x40 // Read Collision Error Interrupt Enable +#define FTFL_FCNFG_ERSAREQ (uint8_t)0x20 // Erase All Request +#define FTFL_FCNFG_ERSSUSP (uint8_t)0x10 // Erase Suspend +#define FTFL_FCNFG_PFLSH (uint8_t)0x04 // Flash memory configuration +#define FTFL_FCNFG_RAMRDY (uint8_t)0x02 // RAM Ready +#define FTFL_FCNFG_EEERDY (uint8_t)0x01 // EEPROM Ready +#define FTFL_FSEC *(const uint8_t *)0x40020002 // Flash Security Register +#define FTFL_FOPT *(const uint8_t *)0x40020003 // Flash Option Register +#define FTFL_FCCOB3 *(volatile uint8_t *)0x40020004 // Flash Common Command Object Registers +#define FTFL_FCCOB2 *(volatile uint8_t *)0x40020005 +#define FTFL_FCCOB1 *(volatile uint8_t *)0x40020006 +#define FTFL_FCCOB0 *(volatile uint8_t *)0x40020007 +#define FTFL_FCCOB7 *(volatile uint8_t *)0x40020008 +#define FTFL_FCCOB6 *(volatile uint8_t *)0x40020009 +#define FTFL_FCCOB5 *(volatile uint8_t *)0x4002000A +#define FTFL_FCCOB4 *(volatile uint8_t *)0x4002000B +#define FTFL_FCCOBB *(volatile uint8_t *)0x4002000C +#define FTFL_FCCOBA *(volatile uint8_t *)0x4002000D +#define FTFL_FCCOB9 *(volatile uint8_t *)0x4002000E +#define FTFL_FCCOB8 *(volatile uint8_t *)0x4002000F +#define FTFL_FPROT3 *(volatile uint8_t *)0x40020010 // Program Flash Protection Registers +#define FTFL_FPROT2 *(volatile uint8_t *)0x40020011 // Program Flash Protection Registers +#define FTFL_FPROT1 *(volatile uint8_t *)0x40020012 // Program Flash Protection Registers +#define FTFL_FPROT0 *(volatile uint8_t *)0x40020013 // Program Flash Protection Registers +#define FTFL_FEPROT *(volatile uint8_t *)0x40020016 // EEPROM Protection Register +#define FTFL_FDPROT *(volatile uint8_t *)0x40020017 // Data Flash Protection Register + +// Chapter 30: Cyclic Redundancy Check (CRC) +#define CRC_CRC *(volatile uint32_t *)0x40032000 // CRC Data register +#define CRC_GPOLY *(volatile uint32_t *)0x40032004 // CRC Polynomial register +#define CRC_CTRL *(volatile uint32_t *)0x40032008 // CRC Control register + +// Chapter 31: Analog-to-Digital Converter (ADC) +#define ADC0_SC1A *(volatile uint32_t *)0x4003B000 // ADC status and control registers 1 +#define ADC0_SC1B *(volatile uint32_t *)0x4003B004 // ADC status and control registers 1 +#define ADC_SC1_COCO (uint32_t)0x80 // Conversion complete flag +#define ADC_SC1_AIEN (uint32_t)0x40 // Interrupt enable +#define ADC_SC1_DIFF (uint32_t)0x20 // Differential mode enable +#define ADC_SC1_ADCH(n) (uint32_t)((n) & 0x1F) // Input channel select +#define ADC0_CFG1 *(volatile uint32_t *)0x4003B008 // ADC configuration register 1 +#define ADC_CFG1_ADLPC (uint32_t)0x80 // Low-power configuration +#define ADC_CFG1_ADIV(n) (uint32_t)(((n) & 3) << 5) // Clock divide select, 0=direct, 1=div2, 2=div4, 3=div8 +#define ADC_CFG1_ADLSMP (uint32_t)0x10 // Sample time configuration, 0=Short, 1=Long +#define ADC_CFG1_MODE(n) (uint32_t)(((n) & 3) << 2) // Conversion mode, 0=8 bit, 1=12 bit, 2=10 bit, 3=16 bit +#define ADC_CFG1_ADICLK(n) (uint32_t)(((n) & 3) << 0) // Input clock, 0=bus, 1=bus/2, 2=OSCERCLK, 3=async +#define ADC0_CFG2 *(volatile uint32_t *)0x4003B00C // Configuration register 2 +#define ADC_CFG2_MUXSEL (uint32_t)0x10 // 0=a channels, 1=b channels +#define ADC_CFG2_ADACKEN (uint32_t)0x08 // async clock enable +#define ADC_CFG2_ADHSC (uint32_t)0x04 // High speed configuration +#define ADC_CFG2_ADLSTS(n) (uint32_t)(((n) & 3) << 0) // Sample time, 0=24 cycles, 1=12 cycles, 2=6 cycles, 3=2 cycles +#define ADC0_RA *(volatile uint32_t *)0x4003B010 // ADC data result register +#define ADC0_RB *(volatile uint32_t *)0x4003B014 // ADC data result register +#define ADC0_CV1 *(volatile uint32_t *)0x4003B018 // Compare value registers +#define ADC0_CV2 *(volatile uint32_t *)0x4003B01C // Compare value registers +#define ADC0_SC2 *(volatile uint32_t *)0x4003B020 // Status and control register 2 +#define ADC_SC2_ADACT (uint32_t)0x80 // Conversion active +#define ADC_SC2_ADTRG (uint32_t)0x40 // Conversion trigger select, 0=software, 1=hardware +#define ADC_SC2_ACFE (uint32_t)0x20 // Compare function enable +#define ADC_SC2_ACFGT (uint32_t)0x10 // Compare function greater than enable +#define ADC_SC2_ACREN (uint32_t)0x08 // Compare function range enable +#define ADC_SC2_DMAEN (uint32_t)0x04 // DMA enable +#define ADC_SC2_REFSEL(n) (uint32_t)(((n) & 3) << 0) // Voltage reference, 0=vcc/external, 1=1.2 volts +#define ADC0_SC3 *(volatile uint32_t *)0x4003B024 // Status and control register 3 +#define ADC_SC3_CAL (uint32_t)0x80 // Calibration, 1=begin, stays set while cal in progress +#define ADC_SC3_CALF (uint32_t)0x40 // Calibration failed flag +#define ADC_SC3_ADCO (uint32_t)0x08 // Continuous conversion enable +#define ADC_SC3_AVGE (uint32_t)0x04 // Hardware average enable +#define ADC_SC3_AVGS(n) (uint32_t)(((n) & 3) << 0) // avg select, 0=4 samples, 1=8 samples, 2=16 samples, 3=32 samples +#define ADC0_OFS *(volatile uint32_t *)0x4003B028 // ADC offset correction register +#define ADC0_PG *(volatile uint32_t *)0x4003B02C // ADC plus-side gain register +#define ADC0_MG *(volatile uint32_t *)0x4003B030 // ADC minus-side gain register +#define ADC0_CLPD *(volatile uint32_t *)0x4003B034 // ADC plus-side general calibration value register +#define ADC0_CLPS *(volatile uint32_t *)0x4003B038 // ADC plus-side general calibration value register +#define ADC0_CLP4 *(volatile uint32_t *)0x4003B03C // ADC plus-side general calibration value register +#define ADC0_CLP3 *(volatile uint32_t *)0x4003B040 // ADC plus-side general calibration value register +#define ADC0_CLP2 *(volatile uint32_t *)0x4003B044 // ADC plus-side general calibration value register +#define ADC0_CLP1 *(volatile uint32_t *)0x4003B048 // ADC plus-side general calibration value register +#define ADC0_CLP0 *(volatile uint32_t *)0x4003B04C // ADC plus-side general calibration value register +#define ADC0_CLMD *(volatile uint32_t *)0x4003B054 // ADC minus-side general calibration value register +#define ADC0_CLMS *(volatile uint32_t *)0x4003B058 // ADC minus-side general calibration value register +#define ADC0_CLM4 *(volatile uint32_t *)0x4003B05C // ADC minus-side general calibration value register +#define ADC0_CLM3 *(volatile uint32_t *)0x4003B060 // ADC minus-side general calibration value register +#define ADC0_CLM2 *(volatile uint32_t *)0x4003B064 // ADC minus-side general calibration value register +#define ADC0_CLM1 *(volatile uint32_t *)0x4003B068 // ADC minus-side general calibration value register +#define ADC0_CLM0 *(volatile uint32_t *)0x4003B06C // ADC minus-side general calibration value register +//#define MCG_C2_RANGE0(n) (uint8_t)(((n) & 0x03) << 4) // Frequency Range Select, Selects the frequency range for the crystal oscillator +//#define MCG_C2_LOCRE0 (uint8_t)0x80 // Loss of Clock Reset Enable, Determines whether an interrupt or a reset request is made following a loss of OSC0 + +// Chapter 32: Comparator (CMP) +#define CMP0_CR0 *(volatile uint8_t *)0x40073000 // CMP Control Register 0 +#define CMP0_CR1 *(volatile uint8_t *)0x40073001 // CMP Control Register 1 +#define CMP0_FPR *(volatile uint8_t *)0x40073002 // CMP Filter Period Register +#define CMP0_SCR *(volatile uint8_t *)0x40073003 // CMP Status and Control Register +#define CMP0_DACCR *(volatile uint8_t *)0x40073004 // DAC Control Register +#define CMP0_MUXCR *(volatile uint8_t *)0x40073005 // MUX Control Register +#define CMP1_CR0 *(volatile uint8_t *)0x40073008 // CMP Control Register 0 +#define CMP1_CR1 *(volatile uint8_t *)0x40073009 // CMP Control Register 1 +#define CMP1_FPR *(volatile uint8_t *)0x4007300A // CMP Filter Period Register +#define CMP1_SCR *(volatile uint8_t *)0x4007300B // CMP Status and Control Register +#define CMP1_DACCR *(volatile uint8_t *)0x4007300C // DAC Control Register +#define CMP1_MUXCR *(volatile uint8_t *)0x4007300D // MUX Control Register + +// Chapter 33: Voltage Reference (VREFV1) +#define VREF_TRM *(volatile uint8_t *)0x40074000 // VREF Trim Register +#define VREF_SC *(volatile uint8_t *)0x40074001 // VREF Status and Control Register + +// Chapter 34: Programmable Delay Block (PDB) +#define PDB0_SC *(volatile uint32_t *)0x40036000 // Status and Control Register +#define PDB_SC_LDMOD(n) (((n) & 3) << 18) // Load Mode Select +#define PDB_SC_PDBEIE 0x00020000 // Sequence Error Interrupt Enable +#define PDB_SC_SWTRIG 0x00010000 // Software Trigger +#define PDB_SC_DMAEN 0x00008000 // DMA Enable +#define PDB_SC_PRESCALER(n) (((n) & 7) << 12) // Prescaler Divider Select +#define PDB_SC_TRGSEL(n) (((n) & 15) << 8) // Trigger Input Source Select +#define PDB_SC_PDBEN 0x00000080 // PDB Enable +#define PDB_SC_PDBIF 0x00000040 // PDB Interrupt Flag +#define PDB_SC_PDBIE 0x00000020 // PDB Interrupt Enable. +#define PDB_SC_MULT(n) (((n) & 3) << 2) // Multiplication Factor +#define PDB_SC_CONT 0x00000002 // Continuous Mode Enable +#define PDB_SC_LDOK 0x00000001 // Load OK +#define PDB0_MOD *(volatile uint32_t *)0x40036004 // Modulus Register +#define PDB0_CNT *(volatile uint32_t *)0x40036008 // Counter Register +#define PDB0_IDLY *(volatile uint32_t *)0x4003600C // Interrupt Delay Register +#define PDB0_CH0C1 *(volatile uint32_t *)0x40036010 // Channel n Control Register 1 +#define PDB0_CH0S *(volatile uint32_t *)0x40036014 // Channel n Status Register +#define PDB0_CH0DLY0 *(volatile uint32_t *)0x40036018 // Channel n Delay 0 Register +#define PDB0_CH0DLY1 *(volatile uint32_t *)0x4003601C // Channel n Delay 1 Register +#define PDB0_POEN *(volatile uint32_t *)0x40036190 // Pulse-Out n Enable Register +#define PDB0_PO0DLY *(volatile uint32_t *)0x40036194 // Pulse-Out n Delay Register +#define PDB0_PO1DLY *(volatile uint32_t *)0x40036198 // Pulse-Out n Delay Register + +// Chapter 35: FlexTimer Module (FTM) +#define FTM0_SC *(volatile uint32_t *)0x40038000 // Status And Control +#define FTM_SC_TOF 0x80 // Timer Overflow Flag +#define FTM_SC_TOIE 0x40 // Timer Overflow Interrupt Enable +#define FTM_SC_CPWMS 0x20 // Center-Aligned PWM Select +#define FTM_SC_CLKS(n) (((n) & 3) << 3) // Clock Source Selection +#define FTM_SC_PS(n) (((n) & 7) << 0) // Prescale Factor Selection +#define FTM0_CNT *(volatile uint32_t *)0x40038004 // Counter +#define FTM0_MOD *(volatile uint32_t *)0x40038008 // Modulo +#define FTM0_C0SC *(volatile uint32_t *)0x4003800C // Channel 0 Status And Control +#define FTM0_C0V *(volatile uint32_t *)0x40038010 // Channel 0 Value +#define FTM0_C1SC *(volatile uint32_t *)0x40038014 // Channel 1 Status And Control +#define FTM0_C1V *(volatile uint32_t *)0x40038018 // Channel 1 Value +#define FTM0_C2SC *(volatile uint32_t *)0x4003801C // Channel 2 Status And Control +#define FTM0_C2V *(volatile uint32_t *)0x40038020 // Channel 2 Value +#define FTM0_C3SC *(volatile uint32_t *)0x40038024 // Channel 3 Status And Control +#define FTM0_C3V *(volatile uint32_t *)0x40038028 // Channel 3 Value +#define FTM0_C4SC *(volatile uint32_t *)0x4003802C // Channel 4 Status And Control +#define FTM0_C4V *(volatile uint32_t *)0x40038030 // Channel 4 Value +#define FTM0_C5SC *(volatile uint32_t *)0x40038034 // Channel 5 Status And Control +#define FTM0_C5V *(volatile uint32_t *)0x40038038 // Channel 5 Value +#define FTM0_C6SC *(volatile uint32_t *)0x4003803C // Channel 6 Status And Control +#define FTM0_C6V *(volatile uint32_t *)0x40038040 // Channel 6 Value +#define FTM0_C7SC *(volatile uint32_t *)0x40038044 // Channel 7 Status And Control +#define FTM0_C7V *(volatile uint32_t *)0x40038048 // Channel 7 Value +#define FTM0_CNTIN *(volatile uint32_t *)0x4003804C // Counter Initial Value +#define FTM0_STATUS *(volatile uint32_t *)0x40038050 // Capture And Compare Status +#define FTM0_MODE *(volatile uint32_t *)0x40038054 // Features Mode Selection +#define FTM_MODE_FAULTIE 0x80 // Fault Interrupt Enable +#define FTM_MODE_FAULTM(n) (((n) & 3) << 5) // Fault Control Mode +#define FTM_MODE_CAPTEST 0x10 // Capture Test Mode Enable +#define FTM_MODE_PWMSYNC 0x08 // PWM Synchronization Mode +#define FTM_MODE_WPDIS 0x04 // Write Protection Disable +#define FTM_MODE_INIT 0x02 // Initialize The Channels Output +#define FTM_MODE_FTMEN 0x01 // FTM Enable +#define FTM0_SYNC *(volatile uint32_t *)0x40038058 // Synchronization +#define FTM_SYNC_SWSYNC 0x80 // +#define FTM_SYNC_TRIG2 0x40 // +#define FTM_SYNC_TRIG1 0x20 // +#define FTM_SYNC_TRIG0 0x10 // +#define FTM_SYNC_SYNCHOM 0x08 // +#define FTM_SYNC_REINIT 0x04 // +#define FTM_SYNC_CNTMAX 0x02 // +#define FTM_SYNC_CNTMIN 0x01 // +#define FTM0_OUTINIT *(volatile uint32_t *)0x4003805C // Initial State For Channels Output +#define FTM0_OUTMASK *(volatile uint32_t *)0x40038060 // Output Mask +#define FTM0_COMBINE *(volatile uint32_t *)0x40038064 // Function For Linked Channels +#define FTM0_DEADTIME *(volatile uint32_t *)0x40038068 // Deadtime Insertion Control +#define FTM0_EXTTRIG *(volatile uint32_t *)0x4003806C // FTM External Trigger +#define FTM0_POL *(volatile uint32_t *)0x40038070 // Channels Polarity +#define FTM0_FMS *(volatile uint32_t *)0x40038074 // Fault Mode Status +#define FTM0_FILTER *(volatile uint32_t *)0x40038078 // Input Capture Filter Control +#define FTM0_FLTCTRL *(volatile uint32_t *)0x4003807C // Fault Control +#define FTM0_QDCTRL *(volatile uint32_t *)0x40038080 // Quadrature Decoder Control And Status +#define FTM0_CONF *(volatile uint32_t *)0x40038084 // Configuration +#define FTM0_FLTPOL *(volatile uint32_t *)0x40038088 // FTM Fault Input Polarity +#define FTM0_SYNCONF *(volatile uint32_t *)0x4003808C // Synchronization Configuration +#define FTM0_INVCTRL *(volatile uint32_t *)0x40038090 // FTM Inverting Control +#define FTM0_SWOCTRL *(volatile uint32_t *)0x40038094 // FTM Software Output Control +#define FTM0_PWMLOAD *(volatile uint32_t *)0x40038098 // FTM PWM Load +#define FTM1_SC *(volatile uint32_t *)0x40039000 // Status And Control +#define FTM1_CNT *(volatile uint32_t *)0x40039004 // Counter +#define FTM1_MOD *(volatile uint32_t *)0x40039008 // Modulo +#define FTM1_C0SC *(volatile uint32_t *)0x4003900C // Channel 0 Status And Control +#define FTM1_C0V *(volatile uint32_t *)0x40039010 // Channel 0 Value +#define FTM1_C1SC *(volatile uint32_t *)0x40039014 // Channel 1 Status And Control +#define FTM1_C1V *(volatile uint32_t *)0x40039018 // Channel 1 Value +#define FTM1_CNTIN *(volatile uint32_t *)0x4003904C // Counter Initial Value +#define FTM1_STATUS *(volatile uint32_t *)0x40039050 // Capture And Compare Status +#define FTM1_MODE *(volatile uint32_t *)0x40039054 // Features Mode Selection +#define FTM1_SYNC *(volatile uint32_t *)0x40039058 // Synchronization +#define FTM1_OUTINIT *(volatile uint32_t *)0x4003905C // Initial State For Channels Output +#define FTM1_OUTMASK *(volatile uint32_t *)0x40039060 // Output Mask +#define FTM1_COMBINE *(volatile uint32_t *)0x40039064 // Function For Linked Channels +#define FTM1_DEADTIME *(volatile uint32_t *)0x40039068 // Deadtime Insertion Control +#define FTM1_EXTTRIG *(volatile uint32_t *)0x4003906C // FTM External Trigger +#define FTM1_POL *(volatile uint32_t *)0x40039070 // Channels Polarity +#define FTM1_FMS *(volatile uint32_t *)0x40039074 // Fault Mode Status +#define FTM1_FILTER *(volatile uint32_t *)0x40039078 // Input Capture Filter Control +#define FTM1_FLTCTRL *(volatile uint32_t *)0x4003907C // Fault Control +#define FTM1_QDCTRL *(volatile uint32_t *)0x40039080 // Quadrature Decoder Control And Status +#define FTM1_CONF *(volatile uint32_t *)0x40039084 // Configuration +#define FTM1_FLTPOL *(volatile uint32_t *)0x40039088 // FTM Fault Input Polarity +#define FTM1_SYNCONF *(volatile uint32_t *)0x4003908C // Synchronization Configuration +#define FTM1_INVCTRL *(volatile uint32_t *)0x40039090 // FTM Inverting Control +#define FTM1_SWOCTRL *(volatile uint32_t *)0x40039094 // FTM Software Output Control +#define FTM1_PWMLOAD *(volatile uint32_t *)0x40039098 // FTM PWM Load + +// Chapter 36: Periodic Interrupt Timer (PIT) +#define PIT_MCR *(volatile uint32_t *)0x40037000 // PIT Module Control Register +#define PIT_LDVAL0 *(volatile uint32_t *)0x40037100 // Timer Load Value Register +#define PIT_CVAL0 *(volatile uint32_t *)0x40037104 // Current Timer Value Register +#define PIT_TCTRL0 *(volatile uint32_t *)0x40037108 // Timer Control Register +#define PIT_TFLG0 *(volatile uint32_t *)0x4003710C // Timer Flag Register +#define PIT_LDVAL1 *(volatile uint32_t *)0x40037110 // Timer Load Value Register +#define PIT_CVAL1 *(volatile uint32_t *)0x40037114 // Current Timer Value Register +#define PIT_TCTRL1 *(volatile uint32_t *)0x40037118 // Timer Control Register +#define PIT_TFLG1 *(volatile uint32_t *)0x4003711C // Timer Flag Register +#define PIT_LDVAL2 *(volatile uint32_t *)0x40037120 // Timer Load Value Register +#define PIT_CVAL2 *(volatile uint32_t *)0x40037124 // Current Timer Value Register +#define PIT_TCTRL2 *(volatile uint32_t *)0x40037128 // Timer Control Register +#define PIT_TFLG2 *(volatile uint32_t *)0x4003712C // Timer Flag Register +#define PIT_LDVAL3 *(volatile uint32_t *)0x40037130 // Timer Load Value Register +#define PIT_CVAL3 *(volatile uint32_t *)0x40037134 // Current Timer Value Register +#define PIT_TCTRL3 *(volatile uint32_t *)0x40037138 // Timer Control Register +#define PIT_TFLG3 *(volatile uint32_t *)0x4003713C // Timer Flag Register + +// Chapter 37: Low-Power Timer (LPTMR) +#define LPTMR0_CSR *(volatile uint32_t *)0x40040000 // Low Power Timer Control Status Register +#define LPTMR0_PSR *(volatile uint32_t *)0x40040004 // Low Power Timer Prescale Register +#define LPTMR0_CMR *(volatile uint32_t *)0x40040008 // Low Power Timer Compare Register +#define LPTMR0_CNR *(volatile uint32_t *)0x4004000C // Low Power Timer Counter Register + +// Chapter 38: Carrier Modulator Transmitter (CMT) +#define CMT_CGH1 *(volatile uint8_t *)0x40062000 // CMT Carrier Generator High Data Register 1 +#define CMT_CGL1 *(volatile uint8_t *)0x40062001 // CMT Carrier Generator Low Data Register 1 +#define CMT_CGH2 *(volatile uint8_t *)0x40062002 // CMT Carrier Generator High Data Register 2 +#define CMT_CGL2 *(volatile uint8_t *)0x40062003 // CMT Carrier Generator Low Data Register 2 +#define CMT_OC *(volatile uint8_t *)0x40062004 // CMT Output Control Register +#define CMT_MSC *(volatile uint8_t *)0x40062005 // CMT Modulator Status and Control Register +#define CMT_CMD1 *(volatile uint8_t *)0x40062006 // CMT Modulator Data Register Mark High +#define CMT_CMD2 *(volatile uint8_t *)0x40062007 // CMT Modulator Data Register Mark Low +#define CMT_CMD3 *(volatile uint8_t *)0x40062008 // CMT Modulator Data Register Space High +#define CMT_CMD4 *(volatile uint8_t *)0x40062009 // CMT Modulator Data Register Space Low +#define CMT_PPS *(volatile uint8_t *)0x4006200A // CMT Primary Prescaler Register +#define CMT_DMA *(volatile uint8_t *)0x4006200B // CMT Direct Memory Access Register + +// Chapter 39: Real Time Clock (RTC) +#define RTC_TSR *(volatile uint32_t *)0x4003D000 // RTC Time Seconds Register +#define RTC_TPR *(volatile uint32_t *)0x4003D004 // RTC Time Prescaler Register +#define RTC_TAR *(volatile uint32_t *)0x4003D008 // RTC Time Alarm Register +#define RTC_TCR *(volatile uint32_t *)0x4003D00C // RTC Time Compensation Register +#define RTC_TCR_CIC(n) (((n) & 255) << 24) // Compensation Interval Counter +#define RTC_TCR_TCV(n) (((n) & 255) << 16) // Time Compensation Value +#define RTC_TCR_CIR(n) (((n) & 255) << 8) // Compensation Interval Register +#define RTC_TCR_TCR(n) (((n) & 255) << 0) // Time Compensation Register +#define RTC_CR *(volatile uint32_t *)0x4003D010 // RTC Control Register +#define RTC_CR_SC2P (uint32_t)0x00002000 // +#define RTC_CR_SC4P (uint32_t)0x00001000 // +#define RTC_CR_SC8P (uint32_t)0x00000800 // +#define RTC_CR_SC16P (uint32_t)0x00000400 // +#define RTC_CR_CLKO (uint32_t)0x00000200 // +#define RTC_CR_OSCE (uint32_t)0x00000100 // +#define RTC_CR_UM (uint32_t)0x00000008 // +#define RTC_CR_SUP (uint32_t)0x00000004 // +#define RTC_CR_WPE (uint32_t)0x00000002 // +#define RTC_CR_SWR (uint32_t)0x00000001 // +#define RTC_SR *(volatile uint32_t *)0x4003D014 // RTC Status Register +#define RTC_SR_TCE (uint32_t)0x00000010 // +#define RTC_SR_TAF (uint32_t)0x00000004 // +#define RTC_SR_TOF (uint32_t)0x00000002 // +#define RTC_SR_TIF (uint32_t)0x00000001 // +#define RTC_LR *(volatile uint32_t *)0x4003D018 // RTC Lock Register +#define RTC_IER *(volatile uint32_t *)0x4003D01C // RTC Interrupt Enable Register +#define RTC_WAR *(volatile uint32_t *)0x4003D800 // RTC Write Access Register +#define RTC_RAR *(volatile uint32_t *)0x4003D804 // RTC Read Access Register + +// Chapter 40: Universal Serial Bus OTG Controller (USBOTG) +#define USB0_PERID *(const uint8_t *)0x40072000 // Peripheral ID register +#define USB0_IDCOMP *(const uint8_t *)0x40072004 // Peripheral ID Complement register +#define USB0_REV *(const uint8_t *)0x40072008 // Peripheral Revision register +#define USB0_ADDINFO *(volatile uint8_t *)0x4007200C // Peripheral Additional Info register +#define USB0_OTGISTAT *(volatile uint8_t *)0x40072010 // OTG Interrupt Status register +#define USB_OTGISTAT_IDCHG (uint8_t)0x80 // +#define USB_OTGISTAT_ONEMSEC (uint8_t)0x40 // +#define USB_OTGISTAT_LINE_STATE_CHG (uint8_t)0x20 // +#define USB_OTGISTAT_SESSVLDCHG (uint8_t)0x08 // +#define USB_OTGISTAT_B_SESS_CHG (uint8_t)0x04 // +#define USB_OTGISTAT_AVBUSCHG (uint8_t)0x01 // +#define USB0_OTGICR *(volatile uint8_t *)0x40072014 // OTG Interrupt Control Register +#define USB_OTGICR_IDEN (uint8_t)0x80 // +#define USB_OTGICR_ONEMSECEN (uint8_t)0x40 // +#define USB_OTGICR_LINESTATEEN (uint8_t)0x20 // +#define USB_OTGICR_SESSVLDEN (uint8_t)0x08 // +#define USB_OTGICR_BSESSEN (uint8_t)0x04 // +#define USB_OTGICR_AVBUSEN (uint8_t)0x01 // +#define USB0_OTGSTAT *(volatile uint8_t *)0x40072018 // OTG Status register +#define USB_OTGSTAT_ID (uint8_t)0x80 // +#define USB_OTGSTAT_ONEMSECEN (uint8_t)0x40 // +#define USB_OTGSTAT_LINESTATESTABLE (uint8_t)0x20 // +#define USB_OTGSTAT_SESS_VLD (uint8_t)0x08 // +#define USB_OTGSTAT_BSESSEND (uint8_t)0x04 // +#define USB_OTGSTAT_AVBUSVLD (uint8_t)0x01 // +#define USB0_OTGCTL *(volatile uint8_t *)0x4007201C // OTG Control Register +#define USB_OTGCTL_DPHIGH (uint8_t)0x80 // +#define USB_OTGCTL_DPLOW (uint8_t)0x20 // +#define USB_OTGCTL_DMLOW (uint8_t)0x10 // +#define USB_OTGCTL_OTGEN (uint8_t)0x04 // +#define USB0_ISTAT *(volatile uint8_t *)0x40072080 // Interrupt Status Register +#define USB_ISTAT_STALL (uint8_t)0x80 // +#define USB_ISTAT_ATTACH (uint8_t)0x40 // +#define USB_ISTAT_RESUME (uint8_t)0x20 // +#define USB_ISTAT_SLEEP (uint8_t)0x10 // +#define USB_ISTAT_TOKDNE (uint8_t)0x08 // +#define USB_ISTAT_SOFTOK (uint8_t)0x04 // +#define USB_ISTAT_ERROR (uint8_t)0x02 // +#define USB_ISTAT_USBRST (uint8_t)0x01 // +#define USB0_INTEN *(volatile uint8_t *)0x40072084 // Interrupt Enable Register +#define USB_INTEN_STALLEN (uint8_t)0x80 // +#define USB_INTEN_ATTACHEN (uint8_t)0x40 // +#define USB_INTEN_RESUMEEN (uint8_t)0x20 // +#define USB_INTEN_SLEEPEN (uint8_t)0x10 // +#define USB_INTEN_TOKDNEEN (uint8_t)0x08 // +#define USB_INTEN_SOFTOKEN (uint8_t)0x04 // +#define USB_INTEN_ERROREN (uint8_t)0x02 // +#define USB_INTEN_USBRSTEN (uint8_t)0x01 // +#define USB0_ERRSTAT *(volatile uint8_t *)0x40072088 // Error Interrupt Status Register +#define USB_ERRSTAT_BTSERR (uint8_t)0x80 // +#define USB_ERRSTAT_DMAERR (uint8_t)0x20 // +#define USB_ERRSTAT_BTOERR (uint8_t)0x10 // +#define USB_ERRSTAT_DFN8 (uint8_t)0x08 // +#define USB_ERRSTAT_CRC16 (uint8_t)0x04 // +#define USB_ERRSTAT_CRC5EOF (uint8_t)0x02 // +#define USB_ERRSTAT_PIDERR (uint8_t)0x01 // +#define USB0_ERREN *(volatile uint8_t *)0x4007208C // Error Interrupt Enable Register +#define USB_ERREN_BTSERREN (uint8_t)0x80 // +#define USB_ERREN_DMAERREN (uint8_t)0x20 // +#define USB_ERREN_BTOERREN (uint8_t)0x10 // +#define USB_ERREN_DFN8EN (uint8_t)0x08 // +#define USB_ERREN_CRC16EN (uint8_t)0x04 // +#define USB_ERREN_CRC5EOFEN (uint8_t)0x02 // +#define USB_ERREN_PIDERREN (uint8_t)0x01 // +#define USB0_STAT *(volatile uint8_t *)0x40072090 // Status Register +#define USB_STAT_TX (uint8_t)0x08 // +#define USB_STAT_ODD (uint8_t)0x04 // +#define USB_STAT_ENDP(n) (uint8_t)((n) >> 4) // +#define USB0_CTL *(volatile uint8_t *)0x40072094 // Control Register +#define USB_CTL_JSTATE (uint8_t)0x80 // +#define USB_CTL_SE0 (uint8_t)0x40 // +#define USB_CTL_TXSUSPENDTOKENBUSY (uint8_t)0x20 // +#define USB_CTL_RESET (uint8_t)0x10 // +#define USB_CTL_HOSTMODEEN (uint8_t)0x08 // +#define USB_CTL_RESUME (uint8_t)0x04 // +#define USB_CTL_ODDRST (uint8_t)0x02 // +#define USB_CTL_USBENSOFEN (uint8_t)0x01 // +#define USB0_ADDR *(volatile uint8_t *)0x40072098 // Address Register +#define USB0_BDTPAGE1 *(volatile uint8_t *)0x4007209C // BDT Page Register 1 +#define USB0_FRMNUML *(volatile uint8_t *)0x400720A0 // Frame Number Register Low +#define USB0_FRMNUMH *(volatile uint8_t *)0x400720A4 // Frame Number Register High +#define USB0_TOKEN *(volatile uint8_t *)0x400720A8 // Token Register +#define USB0_SOFTHLD *(volatile uint8_t *)0x400720AC // SOF Threshold Register +#define USB0_BDTPAGE2 *(volatile uint8_t *)0x400720B0 // BDT Page Register 2 +#define USB0_BDTPAGE3 *(volatile uint8_t *)0x400720B4 // BDT Page Register 3 +#define USB0_ENDPT0 *(volatile uint8_t *)0x400720C0 // Endpoint Control Register +#define USB_ENDPT_HOSTWOHUB (uint8_t)0x80 // host only, enable low speed +#define USB_ENDPT_RETRYDIS (uint8_t)0x40 // host only, set to disable NAK retry +#define USB_ENDPT_EPCTLDIS (uint8_t)0x10 // 0=control, 1=bulk, interrupt, isync +#define USB_ENDPT_EPRXEN (uint8_t)0x08 // enables the endpoint for RX transfers. +#define USB_ENDPT_EPTXEN (uint8_t)0x04 // enables the endpoint for TX transfers. +#define USB_ENDPT_EPSTALL (uint8_t)0x02 // set to stall endpoint +#define USB_ENDPT_EPHSHK (uint8_t)0x01 // enable handshaking during a transaction, generally set unless Isochronous +#define USB0_ENDPT1 *(volatile uint8_t *)0x400720C4 // Endpoint Control Register +#define USB0_ENDPT2 *(volatile uint8_t *)0x400720C8 // Endpoint Control Register +#define USB0_ENDPT3 *(volatile uint8_t *)0x400720CC // Endpoint Control Register +#define USB0_ENDPT4 *(volatile uint8_t *)0x400720D0 // Endpoint Control Register +#define USB0_ENDPT5 *(volatile uint8_t *)0x400720D4 // Endpoint Control Register +#define USB0_ENDPT6 *(volatile uint8_t *)0x400720D8 // Endpoint Control Register +#define USB0_ENDPT7 *(volatile uint8_t *)0x400720DC // Endpoint Control Register +#define USB0_ENDPT8 *(volatile uint8_t *)0x400720E0 // Endpoint Control Register +#define USB0_ENDPT9 *(volatile uint8_t *)0x400720E4 // Endpoint Control Register +#define USB0_ENDPT10 *(volatile uint8_t *)0x400720E8 // Endpoint Control Register +#define USB0_ENDPT11 *(volatile uint8_t *)0x400720EC // Endpoint Control Register +#define USB0_ENDPT12 *(volatile uint8_t *)0x400720F0 // Endpoint Control Register +#define USB0_ENDPT13 *(volatile uint8_t *)0x400720F4 // Endpoint Control Register +#define USB0_ENDPT14 *(volatile uint8_t *)0x400720F8 // Endpoint Control Register +#define USB0_ENDPT15 *(volatile uint8_t *)0x400720FC // Endpoint Control Register +#define USB0_USBCTRL *(volatile uint8_t *)0x40072100 // USB Control Register +#define USB_USBCTRL_SUSP (uint8_t)0x80 // Places the USB transceiver into the suspend state. +#define USB_USBCTRL_PDE (uint8_t)0x40 // Enables the weak pulldowns on the USB transceiver. +#define USB0_OBSERVE *(volatile uint8_t *)0x40072104 // USB OTG Observe Register +#define USB_OBSERVE_DPPU (uint8_t)0x80 // +#define USB_OBSERVE_DPPD (uint8_t)0x40 // +#define USB_OBSERVE_DMPD (uint8_t)0x10 // +#define USB0_CONTROL *(volatile uint8_t *)0x40072108 // USB OTG Control Register +#define USB_CONTROL_DPPULLUPNONOTG (uint8_t)0x10 // Provides control of the DP PULLUP in the USB OTG module, if USB is configured in non-OTG device mode. +#define USB0_USBTRC0 *(volatile uint8_t *)0x4007210C // USB Transceiver Control Register 0 +#define USB_USBTRC_USBRESET (uint8_t)0x80 // +#define USB_USBTRC_USBRESMEN (uint8_t)0x20 // +#define USB_USBTRC_SYNC_DET (uint8_t)0x02 // +#define USB_USBTRC_USB_RESUME_INT (uint8_t)0x01 // +#define USB0_USBFRMADJUST *(volatile uint8_t *)0x40072114 // Frame Adjust Register + +// Chapter 41: USB Device Charger Detection Module (USBDCD) +#define USBDCD_CONTROL *(volatile uint32_t *)0x40035000 // Control register +#define USBDCD_CLOCK *(volatile uint32_t *)0x40035004 // Clock register +#define USBDCD_STATUS *(volatile uint32_t *)0x40035008 // Status register +#define USBDCD_TIMER0 *(volatile uint32_t *)0x40035010 // TIMER0 register +#define USBDCD_TIMER1 *(volatile uint32_t *)0x40035014 // TIMER1 register +#define USBDCD_TIMER2 *(volatile uint32_t *)0x40035018 // TIMER2 register + +// Chapter 43: SPI (DSPI) +#define SPI0_MCR *(volatile uint32_t *)0x4002C000 // DSPI Module Configuration Register +#define SPI_MCR_MSTR (uint32_t)0x80000000 // Master/Slave Mode Select +#define SPI_MCR_CONT_SCKE (uint32_t)0x40000000 // +#define SPI_MCR_DCONF(n) (((n) & 3) << 28) // +#define SPI_MCR_FRZ (uint32_t)0x08000000 // +#define SPI_MCR_MTFE (uint32_t)0x04000000 // +#define SPI_MCR_ROOE (uint32_t)0x01000000 // +#define SPI_MCR_PCSIS(n) (((n) & 0x1F) << 16) // +#define SPI_MCR_DOZE (uint32_t)0x00008000 // +#define SPI_MCR_MDIS (uint32_t)0x00004000 // +#define SPI_MCR_DIS_TXF (uint32_t)0x00002000 // +#define SPI_MCR_DIS_RXF (uint32_t)0x00001000 // +#define SPI_MCR_CLR_TXF (uint32_t)0x00000800 // +#define SPI_MCR_CLR_RXF (uint32_t)0x00000400 // +#define SPI_MCR_SMPL_PT(n) (((n) & 3) << 8) // +#define SPI_MCR_HALT (uint32_t)0x00000001 // +#define SPI0_TCR *(volatile uint32_t *)0x4002C008 // DSPI Transfer Count Register +#define SPI0_CTAR0 *(volatile uint32_t *)0x4002C00C // DSPI Clock and Transfer Attributes Register, In Master Mode +#define SPI_CTAR_DBR (uint32_t)0x80000000 // Double Baud Rate +#define SPI_CTAR_FMSZ(n) (((n) & 15) << 27) // Frame Size (+1) +#define SPI_CTAR_CPOL (uint32_t)0x04000000 // Clock Polarity +#define SPI_CTAR_CPHA (uint32_t)0x02000000 // Clock Phase +#define SPI_CTAR_LSBFE (uint32_t)0x01000000 // LSB First +#define SPI_CTAR_PCSSCK(n) (((n) & 3) << 22) // PCS to SCK Delay Prescaler +#define SPI_CTAR_PASC(n) (((n) & 3) << 20) // After SCK Delay Prescaler +#define SPI_CTAR_PDT(n) (((n) & 3) << 18) // Delay after Transfer Prescaler +#define SPI_CTAR_PBR(n) (((n) & 3) << 16) // Baud Rate Prescaler +#define SPI_CTAR_CSSCK(n) (((n) & 15) << 12) // PCS to SCK Delay Scaler +#define SPI_CTAR_ASC(n) (((n) & 15) << 8) // After SCK Delay Scaler +#define SPI_CTAR_DT(n) (((n) & 15) << 4) // Delay After Transfer Scaler +#define SPI_CTAR_BR(n) (((n) & 15) << 0) // Baud Rate Scaler +#define SPI0_CTAR0_SLAVE *(volatile uint32_t *)0x4002C00C // DSPI Clock and Transfer Attributes Register, In Slave Mode +#define SPI0_CTAR1 *(volatile uint32_t *)0x4002C010 // DSPI Clock and Transfer Attributes Register, In Master Mode +#define SPI0_SR *(volatile uint32_t *)0x4002C02C // DSPI Status Register +#define SPI_SR_TCF (uint32_t)0x80000000 // Transfer Complete Flag +#define SPI_SR_TXRXS (uint32_t)0x40000000 // TX and RX Status +#define SPI_SR_EOQF (uint32_t)0x10000000 // End of Queue Flag +#define SPI_SR_TFUF (uint32_t)0x08000000 // Transmit FIFO Underflow Flag +#define SPI_SR_TFFF (uint32_t)0x02000000 // Transmit FIFO Fill Flag +#define SPI_SR_RFOF (uint32_t)0x00080000 // Receive FIFO Overflow Flag +#define SPI_SR_RFDF (uint32_t)0x00020000 // Receive FIFO Drain Flag +#define SPI0_RSER *(volatile uint32_t *)0x4002C030 // DSPI DMA/Interrupt Request Select and Enable Register +#define SPI0_PUSHR *(volatile uint32_t *)0x4002C034 // DSPI PUSH TX FIFO Register In Master Mode +#define SPI_PUSHR_CONT (uint32_t)0x80000000 // +#define SPI_PUSHR_CTAS(n) (((n) & 7) << 28) // +#define SPI_PUSHR_EOQ (uint32_t)0x08000000 // +#define SPI_PUSHR_CTCNT (uint32_t)0x04000000 // +#define SPI_PUSHR_PCS(n) (((n) & 31) << 16) // +#define SPI0_PUSHR_SLAVE *(volatile uint32_t *)0x4002C034 // DSPI PUSH TX FIFO Register In Slave Mode +#define SPI0_POPR *(volatile uint32_t *)0x4002C038 // DSPI POP RX FIFO Register +#define SPI0_TXFR0 *(volatile uint32_t *)0x4002C03C // DSPI Transmit FIFO Registers +#define SPI0_TXFR1 *(volatile uint32_t *)0x4002C040 // DSPI Transmit FIFO Registers +#define SPI0_TXFR2 *(volatile uint32_t *)0x4002C044 // DSPI Transmit FIFO Registers +#define SPI0_TXFR3 *(volatile uint32_t *)0x4002C048 // DSPI Transmit FIFO Registers +#define SPI0_RXFR0 *(volatile uint32_t *)0x4002C07C // DSPI Receive FIFO Registers +#define SPI0_RXFR1 *(volatile uint32_t *)0x4002C080 // DSPI Receive FIFO Registers +#define SPI0_RXFR2 *(volatile uint32_t *)0x4002C084 // DSPI Receive FIFO Registers +#define SPI0_RXFR3 *(volatile uint32_t *)0x4002C088 // DSPI Receive FIFO Registers + +// Chapter 44: Inter-Integrated Circuit (I2C) +#define I2C0_A1 *(volatile uint8_t *)0x40066000 // I2C Address Register 1 +#define I2C0_F *(volatile uint8_t *)0x40066001 // I2C Frequency Divider register +#define I2C0_C1 *(volatile uint8_t *)0x40066002 // I2C Control Register 1 +#define I2C_C1_IICEN (uint8_t)0x80 // I2C Enable +#define I2C_C1_IICIE (uint8_t)0x40 // I2C Interrupt Enable +#define I2C_C1_MST (uint8_t)0x20 // Master Mode Select +#define I2C_C1_TX (uint8_t)0x10 // Transmit Mode Select +#define I2C_C1_TXAK (uint8_t)0x08 // Transmit Acknowledge Enable +#define I2C_C1_RSTA (uint8_t)0x04 // Repeat START +#define I2C_C1_WUEN (uint8_t)0x02 // Wakeup Enable +#define I2C_C1_DMAEN (uint8_t)0x01 // DMA Enable +#define I2C0_S *(volatile uint8_t *)0x40066003 // I2C Status register +#define I2C_S_TCF (uint8_t)0x80 // Transfer Complete Flag +#define I2C_S_IAAS (uint8_t)0x40 // Addressed As A Slave +#define I2C_S_BUSY (uint8_t)0x20 // Bus Busy +#define I2C_S_ARBL (uint8_t)0x10 // Arbitration Lost +#define I2C_S_RAM (uint8_t)0x08 // Range Address Match +#define I2C_S_SRW (uint8_t)0x04 // Slave Read/Write +#define I2C_S_IICIF (uint8_t)0x02 // Interrupt Flag +#define I2C_S_RXAK (uint8_t)0x01 // Receive Acknowledge +#define I2C0_D *(volatile uint8_t *)0x40066004 // I2C Data I/O register +#define I2C0_C2 *(volatile uint8_t *)0x40066005 // I2C Control Register 2 +#define I2C_C2_GCAEN (uint8_t)0x80 // General Call Address Enable +#define I2C_C2_ADEXT (uint8_t)0x40 // Address Extension +#define I2C_C2_HDRS (uint8_t)0x20 // High Drive Select +#define I2C_C2_SBRC (uint8_t)0x10 // Slave Baud Rate Control +#define I2C_C2_RMEN (uint8_t)0x08 // Range Address Matching Enable +#define I2C_C2_AD(n) ((n) & 7) // Slave Address, upper 3 bits +#define I2C0_FLT *(volatile uint8_t *)0x40066006 // I2C Programmable Input Glitch Filter register +#define I2C0_RA *(volatile uint8_t *)0x40066007 // I2C Range Address register +#define I2C0_SMB *(volatile uint8_t *)0x40066008 // I2C SMBus Control and Status register +#define I2C0_A2 *(volatile uint8_t *)0x40066009 // I2C Address Register 2 +#define I2C0_SLTH *(volatile uint8_t *)0x4006600A // I2C SCL Low Timeout Register High +#define I2C0_SLTL *(volatile uint8_t *)0x4006600B // I2C SCL Low Timeout Register Low + +// Chapter 45: Universal Asynchronous Receiver/Transmitter (UART) +#define UART0_BDH *(volatile uint8_t *)0x4006A000 // UART Baud Rate Registers: High +#define UART0_BDL *(volatile uint8_t *)0x4006A001 // UART Baud Rate Registers: Low +#define UART0_C1 *(volatile uint8_t *)0x4006A002 // UART Control Register 1 +#define UART_C1_LOOPS (uint8_t)0x80 // When LOOPS is set, the RxD pin is disconnected from the UART and the transmitter output is internally connected to the receiver input +#define UART_C1_UARTSWAI (uint8_t)0x40 // UART Stops in Wait Mode +#define UART_C1_RSRC (uint8_t)0x20 // When LOOPS is set, the RSRC field determines the source for the receiver shift register input +#define UART_C1_M (uint8_t)0x10 // 9-bit or 8-bit Mode Select +#define UART_C1_WAKE (uint8_t)0x08 // Determines which condition wakes the UART +#define UART_C1_ILT (uint8_t)0x04 // Idle Line Type Select +#define UART_C1_PE (uint8_t)0x02 // Parity Enable +#define UART_C1_PT (uint8_t)0x01 // Parity Type, 0=even, 1=odd +#define UART0_C2 *(volatile uint8_t *)0x4006A003 // UART Control Register 2 +#define UART_C2_TIE (uint8_t)0x80 // Transmitter Interrupt or DMA Transfer Enable. +#define UART_C2_TCIE (uint8_t)0x40 // Transmission Complete Interrupt Enable +#define UART_C2_RIE (uint8_t)0x20 // Receiver Full Interrupt or DMA Transfer Enable +#define UART_C2_ILIE (uint8_t)0x10 // Idle Line Interrupt Enable +#define UART_C2_TE (uint8_t)0x08 // Transmitter Enable +#define UART_C2_RE (uint8_t)0x04 // Receiver Enable +#define UART_C2_RWU (uint8_t)0x02 // Receiver Wakeup Control +#define UART_C2_SBK (uint8_t)0x01 // Send Break +#define UART0_S1 *(volatile uint8_t *)0x4006A004 // UART Status Register 1 +#define UART_S1_TDRE (uint8_t)0x80 // Transmit Data Register Empty Flag +#define UART_S1_TC (uint8_t)0x40 // Transmit Complete Flag +#define UART_S1_RDRF (uint8_t)0x20 // Receive Data Register Full Flag +#define UART_S1_IDLE (uint8_t)0x10 // Idle Line Flag +#define UART_S1_OR (uint8_t)0x08 // Receiver Overrun Flag +#define UART_S1_NF (uint8_t)0x04 // Noise Flag +#define UART_S1_FE (uint8_t)0x02 // Framing Error Flag +#define UART_S1_PF (uint8_t)0x01 // Parity Error Flag +#define UART0_S2 *(volatile uint8_t *)0x4006A005 // UART Status Register 2 +#define UART0_C3 *(volatile uint8_t *)0x4006A006 // UART Control Register 3 +#define UART0_D *(volatile uint8_t *)0x4006A007 // UART Data Register +#define UART0_MA1 *(volatile uint8_t *)0x4006A008 // UART Match Address Registers 1 +#define UART0_MA2 *(volatile uint8_t *)0x4006A009 // UART Match Address Registers 2 +#define UART0_C4 *(volatile uint8_t *)0x4006A00A // UART Control Register 4 +#define UART0_C5 *(volatile uint8_t *)0x4006A00B // UART Control Register 5 +#define UART0_ED *(volatile uint8_t *)0x4006A00C // UART Extended Data Register +#define UART0_MODEM *(volatile uint8_t *)0x4006A00D // UART Modem Register +#define UART0_IR *(volatile uint8_t *)0x4006A00E // UART Infrared Register +#define UART0_PFIFO *(volatile uint8_t *)0x4006A010 // UART FIFO Parameters +#define UART_PFIFO_TXFE (uint8_t)0x80 +#define UART_PFIFO_RXFE (uint8_t)0x08 +#define UART0_CFIFO *(volatile uint8_t *)0x4006A011 // UART FIFO Control Register +#define UART_CFIFO_TXFLUSH (uint8_t)0x80 // +#define UART_CFIFO_RXFLUSH (uint8_t)0x40 // +#define UART_CFIFO_RXOFE (uint8_t)0x04 // +#define UART_CFIFO_TXOFE (uint8_t)0x02 // +#define UART_CFIFO_RXUFE (uint8_t)0x01 // +#define UART0_SFIFO *(volatile uint8_t *)0x4006A012 // UART FIFO Status Register +#define UART_SFIFO_TXEMPT (uint8_t)0x80 +#define UART_SFIFO_RXEMPT (uint8_t)0x40 +#define UART_SFIFO_RXOF (uint8_t)0x04 +#define UART_SFIFO_TXOF (uint8_t)0x02 +#define UART_SFIFO_RXUF (uint8_t)0x01 +#define UART0_TWFIFO *(volatile uint8_t *)0x4006A013 // UART FIFO Transmit Watermark +#define UART0_TCFIFO *(volatile uint8_t *)0x4006A014 // UART FIFO Transmit Count +#define UART0_RWFIFO *(volatile uint8_t *)0x4006A015 // UART FIFO Receive Watermark +#define UART0_RCFIFO *(volatile uint8_t *)0x4006A016 // UART FIFO Receive Count +#define UART0_C7816 *(volatile uint8_t *)0x4006A018 // UART 7816 Control Register +#define UART0_IE7816 *(volatile uint8_t *)0x4006A019 // UART 7816 Interrupt Enable Register +#define UART0_IS7816 *(volatile uint8_t *)0x4006A01A // UART 7816 Interrupt Status Register +#define UART0_WP7816T0 *(volatile uint8_t *)0x4006A01B // UART 7816 Wait Parameter Register +#define UART0_WP7816T1 *(volatile uint8_t *)0x4006A01B // UART 7816 Wait Parameter Register +#define UART0_WN7816 *(volatile uint8_t *)0x4006A01C // UART 7816 Wait N Register +#define UART0_WF7816 *(volatile uint8_t *)0x4006A01D // UART 7816 Wait FD Register +#define UART0_ET7816 *(volatile uint8_t *)0x4006A01E // UART 7816 Error Threshold Register +#define UART0_TL7816 *(volatile uint8_t *)0x4006A01F // UART 7816 Transmit Length Register +#define UART0_C6 *(volatile uint8_t *)0x4006A021 // UART CEA709.1-B Control Register 6 +#define UART0_PCTH *(volatile uint8_t *)0x4006A022 // UART CEA709.1-B Packet Cycle Time Counter High +#define UART0_PCTL *(volatile uint8_t *)0x4006A023 // UART CEA709.1-B Packet Cycle Time Counter Low +#define UART0_B1T *(volatile uint8_t *)0x4006A024 // UART CEA709.1-B Beta1 Timer +#define UART0_SDTH *(volatile uint8_t *)0x4006A025 // UART CEA709.1-B Secondary Delay Timer High +#define UART0_SDTL *(volatile uint8_t *)0x4006A026 // UART CEA709.1-B Secondary Delay Timer Low +#define UART0_PRE *(volatile uint8_t *)0x4006A027 // UART CEA709.1-B Preamble +#define UART0_TPL *(volatile uint8_t *)0x4006A028 // UART CEA709.1-B Transmit Packet Length +#define UART0_IE *(volatile uint8_t *)0x4006A029 // UART CEA709.1-B Interrupt Enable Register +#define UART0_WB *(volatile uint8_t *)0x4006A02A // UART CEA709.1-B WBASE +#define UART0_S3 *(volatile uint8_t *)0x4006A02B // UART CEA709.1-B Status Register +#define UART0_S4 *(volatile uint8_t *)0x4006A02C // UART CEA709.1-B Status Register +#define UART0_RPL *(volatile uint8_t *)0x4006A02D // UART CEA709.1-B Received Packet Length +#define UART0_RPREL *(volatile uint8_t *)0x4006A02E // UART CEA709.1-B Received Preamble Length +#define UART0_CPW *(volatile uint8_t *)0x4006A02F // UART CEA709.1-B Collision Pulse Width +#define UART0_RIDT *(volatile uint8_t *)0x4006A030 // UART CEA709.1-B Receive Indeterminate Time +#define UART0_TIDT *(volatile uint8_t *)0x4006A031 // UART CEA709.1-B Transmit Indeterminate Time +#define UART1_BDH *(volatile uint8_t *)0x4006B000 // UART Baud Rate Registers: High +#define UART1_BDL *(volatile uint8_t *)0x4006B001 // UART Baud Rate Registers: Low +#define UART1_C1 *(volatile uint8_t *)0x4006B002 // UART Control Register 1 +#define UART1_C2 *(volatile uint8_t *)0x4006B003 // UART Control Register 2 +#define UART1_S1 *(volatile uint8_t *)0x4006B004 // UART Status Register 1 +#define UART1_S2 *(volatile uint8_t *)0x4006B005 // UART Status Register 2 +#define UART1_C3 *(volatile uint8_t *)0x4006B006 // UART Control Register 3 +#define UART1_D *(volatile uint8_t *)0x4006B007 // UART Data Register +#define UART1_MA1 *(volatile uint8_t *)0x4006B008 // UART Match Address Registers 1 +#define UART1_MA2 *(volatile uint8_t *)0x4006B009 // UART Match Address Registers 2 +#define UART1_C4 *(volatile uint8_t *)0x4006B00A // UART Control Register 4 +#define UART1_C5 *(volatile uint8_t *)0x4006B00B // UART Control Register 5 +#define UART1_ED *(volatile uint8_t *)0x4006B00C // UART Extended Data Register +#define UART1_MODEM *(volatile uint8_t *)0x4006B00D // UART Modem Register +#define UART1_IR *(volatile uint8_t *)0x4006B00E // UART Infrared Register +#define UART1_PFIFO *(volatile uint8_t *)0x4006B010 // UART FIFO Parameters +#define UART1_CFIFO *(volatile uint8_t *)0x4006B011 // UART FIFO Control Register +#define UART1_SFIFO *(volatile uint8_t *)0x4006B012 // UART FIFO Status Register +#define UART1_TWFIFO *(volatile uint8_t *)0x4006B013 // UART FIFO Transmit Watermark +#define UART1_TCFIFO *(volatile uint8_t *)0x4006B014 // UART FIFO Transmit Count +#define UART1_RWFIFO *(volatile uint8_t *)0x4006B015 // UART FIFO Receive Watermark +#define UART1_RCFIFO *(volatile uint8_t *)0x4006B016 // UART FIFO Receive Count +#define UART1_C7816 *(volatile uint8_t *)0x4006B018 // UART 7816 Control Register +#define UART1_IE7816 *(volatile uint8_t *)0x4006B019 // UART 7816 Interrupt Enable Register +#define UART1_IS7816 *(volatile uint8_t *)0x4006B01A // UART 7816 Interrupt Status Register +#define UART1_WP7816T0 *(volatile uint8_t *)0x4006B01B // UART 7816 Wait Parameter Register +#define UART1_WP7816T1 *(volatile uint8_t *)0x4006B01B // UART 7816 Wait Parameter Register +#define UART1_WN7816 *(volatile uint8_t *)0x4006B01C // UART 7816 Wait N Register +#define UART1_WF7816 *(volatile uint8_t *)0x4006B01D // UART 7816 Wait FD Register +#define UART1_ET7816 *(volatile uint8_t *)0x4006B01E // UART 7816 Error Threshold Register +#define UART1_TL7816 *(volatile uint8_t *)0x4006B01F // UART 7816 Transmit Length Register +#define UART1_C6 *(volatile uint8_t *)0x4006B021 // UART CEA709.1-B Control Register 6 +#define UART1_PCTH *(volatile uint8_t *)0x4006B022 // UART CEA709.1-B Packet Cycle Time Counter High +#define UART1_PCTL *(volatile uint8_t *)0x4006B023 // UART CEA709.1-B Packet Cycle Time Counter Low +#define UART1_B1T *(volatile uint8_t *)0x4006B024 // UART CEA709.1-B Beta1 Timer +#define UART1_SDTH *(volatile uint8_t *)0x4006B025 // UART CEA709.1-B Secondary Delay Timer High +#define UART1_SDTL *(volatile uint8_t *)0x4006B026 // UART CEA709.1-B Secondary Delay Timer Low +#define UART1_PRE *(volatile uint8_t *)0x4006B027 // UART CEA709.1-B Preamble +#define UART1_TPL *(volatile uint8_t *)0x4006B028 // UART CEA709.1-B Transmit Packet Length +#define UART1_IE *(volatile uint8_t *)0x4006B029 // UART CEA709.1-B Interrupt Enable Register +#define UART1_WB *(volatile uint8_t *)0x4006B02A // UART CEA709.1-B WBASE +#define UART1_S3 *(volatile uint8_t *)0x4006B02B // UART CEA709.1-B Status Register +#define UART1_S4 *(volatile uint8_t *)0x4006B02C // UART CEA709.1-B Status Register +#define UART1_RPL *(volatile uint8_t *)0x4006B02D // UART CEA709.1-B Received Packet Length +#define UART1_RPREL *(volatile uint8_t *)0x4006B02E // UART CEA709.1-B Received Preamble Length +#define UART1_CPW *(volatile uint8_t *)0x4006B02F // UART CEA709.1-B Collision Pulse Width +#define UART1_RIDT *(volatile uint8_t *)0x4006B030 // UART CEA709.1-B Receive Indeterminate Time +#define UART1_TIDT *(volatile uint8_t *)0x4006B031 // UART CEA709.1-B Transmit Indeterminate Time +#define UART2_BDH *(volatile uint8_t *)0x4006C000 // UART Baud Rate Registers: High +#define UART2_BDL *(volatile uint8_t *)0x4006C001 // UART Baud Rate Registers: Low +#define UART2_C1 *(volatile uint8_t *)0x4006C002 // UART Control Register 1 +#define UART2_C2 *(volatile uint8_t *)0x4006C003 // UART Control Register 2 +#define UART2_S1 *(volatile uint8_t *)0x4006C004 // UART Status Register 1 +#define UART2_S2 *(volatile uint8_t *)0x4006C005 // UART Status Register 2 +#define UART2_C3 *(volatile uint8_t *)0x4006C006 // UART Control Register 3 +#define UART2_D *(volatile uint8_t *)0x4006C007 // UART Data Register +#define UART2_MA1 *(volatile uint8_t *)0x4006C008 // UART Match Address Registers 1 +#define UART2_MA2 *(volatile uint8_t *)0x4006C009 // UART Match Address Registers 2 +#define UART2_C4 *(volatile uint8_t *)0x4006C00A // UART Control Register 4 +#define UART2_C5 *(volatile uint8_t *)0x4006C00B // UART Control Register 5 +#define UART2_ED *(volatile uint8_t *)0x4006C00C // UART Extended Data Register +#define UART2_MODEM *(volatile uint8_t *)0x4006C00D // UART Modem Register +#define UART2_IR *(volatile uint8_t *)0x4006C00E // UART Infrared Register +#define UART2_PFIFO *(volatile uint8_t *)0x4006C010 // UART FIFO Parameters +#define UART2_CFIFO *(volatile uint8_t *)0x4006C011 // UART FIFO Control Register +#define UART2_SFIFO *(volatile uint8_t *)0x4006C012 // UART FIFO Status Register +#define UART2_TWFIFO *(volatile uint8_t *)0x4006C013 // UART FIFO Transmit Watermark +#define UART2_TCFIFO *(volatile uint8_t *)0x4006C014 // UART FIFO Transmit Count +#define UART2_RWFIFO *(volatile uint8_t *)0x4006C015 // UART FIFO Receive Watermark +#define UART2_RCFIFO *(volatile uint8_t *)0x4006C016 // UART FIFO Receive Count +#define UART2_C7816 *(volatile uint8_t *)0x4006C018 // UART 7816 Control Register +#define UART2_IE7816 *(volatile uint8_t *)0x4006C019 // UART 7816 Interrupt Enable Register +#define UART2_IS7816 *(volatile uint8_t *)0x4006C01A // UART 7816 Interrupt Status Register +#define UART2_WP7816T0 *(volatile uint8_t *)0x4006C01B // UART 7816 Wait Parameter Register +#define UART2_WP7816T1 *(volatile uint8_t *)0x4006C01B // UART 7816 Wait Parameter Register +#define UART2_WN7816 *(volatile uint8_t *)0x4006C01C // UART 7816 Wait N Register +#define UART2_WF7816 *(volatile uint8_t *)0x4006C01D // UART 7816 Wait FD Register +#define UART2_ET7816 *(volatile uint8_t *)0x4006C01E // UART 7816 Error Threshold Register +#define UART2_TL7816 *(volatile uint8_t *)0x4006C01F // UART 7816 Transmit Length Register +#define UART2_C6 *(volatile uint8_t *)0x4006C021 // UART CEA709.1-B Control Register 6 +#define UART2_PCTH *(volatile uint8_t *)0x4006C022 // UART CEA709.1-B Packet Cycle Time Counter High +#define UART2_PCTL *(volatile uint8_t *)0x4006C023 // UART CEA709.1-B Packet Cycle Time Counter Low +#define UART2_B1T *(volatile uint8_t *)0x4006C024 // UART CEA709.1-B Beta1 Timer +#define UART2_SDTH *(volatile uint8_t *)0x4006C025 // UART CEA709.1-B Secondary Delay Timer High +#define UART2_SDTL *(volatile uint8_t *)0x4006C026 // UART CEA709.1-B Secondary Delay Timer Low +#define UART2_PRE *(volatile uint8_t *)0x4006C027 // UART CEA709.1-B Preamble +#define UART2_TPL *(volatile uint8_t *)0x4006C028 // UART CEA709.1-B Transmit Packet Length +#define UART2_IE *(volatile uint8_t *)0x4006C029 // UART CEA709.1-B Interrupt Enable Register +#define UART2_WB *(volatile uint8_t *)0x4006C02A // UART CEA709.1-B WBASE +#define UART2_S3 *(volatile uint8_t *)0x4006C02B // UART CEA709.1-B Status Register +#define UART2_S4 *(volatile uint8_t *)0x4006C02C // UART CEA709.1-B Status Register +#define UART2_RPL *(volatile uint8_t *)0x4006C02D // UART CEA709.1-B Received Packet Length +#define UART2_RPREL *(volatile uint8_t *)0x4006C02E // UART CEA709.1-B Received Preamble Length +#define UART2_CPW *(volatile uint8_t *)0x4006C02F // UART CEA709.1-B Collision Pulse Width +#define UART2_RIDT *(volatile uint8_t *)0x4006C030 // UART CEA709.1-B Receive Indeterminate Time +#define UART2_TIDT *(volatile uint8_t *)0x4006C031 // UART CEA709.1-B Transmit Indeterminate Time + +// Chapter 46: Synchronous Audio Interface (SAI) +#define I2S0_TCSR *(volatile uint32_t *)0x4002F000 // SAI Transmit Control Register +#define I2S0_TCR1 *(volatile uint32_t *)0x4002F004 // SAI Transmit Configuration 1 Register +#define I2S0_TCR2 *(volatile uint32_t *)0x4002F008 // SAI Transmit Configuration 2 Register +#define I2S0_TCR3 *(volatile uint32_t *)0x4002F00C // SAI Transmit Configuration 3 Register +#define I2S0_TCR4 *(volatile uint32_t *)0x4002F010 // SAI Transmit Configuration 4 Register +#define I2S0_TCR5 *(volatile uint32_t *)0x4002F014 // SAI Transmit Configuration 5 Register +#define I2S0_TDR0 *(volatile uint32_t *)0x4002F020 // SAI Transmit Data Register +#define I2S0_TFR0 *(volatile uint32_t *)0x4002F040 // SAI Transmit FIFO Register +#define I2S0_TMR *(volatile uint32_t *)0x4002F060 // SAI Transmit Mask Register +#define I2S0_RCSR *(volatile uint32_t *)0x4002F080 // SAI Receive Control Register +#define I2S0_RCR1 *(volatile uint32_t *)0x4002F084 // SAI Receive Configuration 1 Register +#define I2S0_RCR2 *(volatile uint32_t *)0x4002F088 // SAI Receive Configuration 2 Register +#define I2S0_RCR3 *(volatile uint32_t *)0x4002F08C // SAI Receive Configuration 3 Register +#define I2S0_RCR4 *(volatile uint32_t *)0x4002F090 // SAI Receive Configuration 4 Register +#define I2S0_RCR5 *(volatile uint32_t *)0x4002F094 // SAI Receive Configuration 5 Register +#define I2S0_RDR0 *(volatile uint32_t *)0x4002F0A0 // SAI Receive Data Register +#define I2S0_RFR0 *(volatile uint32_t *)0x4002F0C0 // SAI Receive FIFO Register +#define I2S0_RMR *(volatile uint32_t *)0x4002F0E0 // SAI Receive Mask Register +#define I2S0_MCR *(volatile uint32_t *)0x4002F100 // SAI MCLK Control Register +#define I2S0_MDR *(volatile uint32_t *)0x4002F104 // SAI MCLK Divide Register + +// Chapter 47: General-Purpose Input/Output (GPIO) +#define GPIOA_PDOR *(volatile uint32_t *)0x400FF000 // Port Data Output Register +#define GPIOA_PSOR *(volatile uint32_t *)0x400FF004 // Port Set Output Register +#define GPIOA_PCOR *(volatile uint32_t *)0x400FF008 // Port Clear Output Register +#define GPIOA_PTOR *(volatile uint32_t *)0x400FF00C // Port Toggle Output Register +#define GPIOA_PDIR *(volatile uint32_t *)0x400FF010 // Port Data Input Register +#define GPIOA_PDDR *(volatile uint32_t *)0x400FF014 // Port Data Direction Register +#define GPIOB_PDOR *(volatile uint32_t *)0x400FF040 // Port Data Output Register +#define GPIOB_PSOR *(volatile uint32_t *)0x400FF044 // Port Set Output Register +#define GPIOB_PCOR *(volatile uint32_t *)0x400FF048 // Port Clear Output Register +#define GPIOB_PTOR *(volatile uint32_t *)0x400FF04C // Port Toggle Output Register +#define GPIOB_PDIR *(volatile uint32_t *)0x400FF050 // Port Data Input Register +#define GPIOB_PDDR *(volatile uint32_t *)0x400FF054 // Port Data Direction Register +#define GPIOC_PDOR *(volatile uint32_t *)0x400FF080 // Port Data Output Register +#define GPIOC_PSOR *(volatile uint32_t *)0x400FF084 // Port Set Output Register +#define GPIOC_PCOR *(volatile uint32_t *)0x400FF088 // Port Clear Output Register +#define GPIOC_PTOR *(volatile uint32_t *)0x400FF08C // Port Toggle Output Register +#define GPIOC_PDIR *(volatile uint32_t *)0x400FF090 // Port Data Input Register +#define GPIOC_PDDR *(volatile uint32_t *)0x400FF094 // Port Data Direction Register +#define GPIOD_PDOR *(volatile uint32_t *)0x400FF0C0 // Port Data Output Register +#define GPIOD_PSOR *(volatile uint32_t *)0x400FF0C4 // Port Set Output Register +#define GPIOD_PCOR *(volatile uint32_t *)0x400FF0C8 // Port Clear Output Register +#define GPIOD_PTOR *(volatile uint32_t *)0x400FF0CC // Port Toggle Output Register +#define GPIOD_PDIR *(volatile uint32_t *)0x400FF0D0 // Port Data Input Register +#define GPIOD_PDDR *(volatile uint32_t *)0x400FF0D4 // Port Data Direction Register +#define GPIOE_PDOR *(volatile uint32_t *)0x400FF100 // Port Data Output Register +#define GPIOE_PSOR *(volatile uint32_t *)0x400FF104 // Port Set Output Register +#define GPIOE_PCOR *(volatile uint32_t *)0x400FF108 // Port Clear Output Register +#define GPIOE_PTOR *(volatile uint32_t *)0x400FF10C // Port Toggle Output Register +#define GPIOE_PDIR *(volatile uint32_t *)0x400FF110 // Port Data Input Register +#define GPIOE_PDDR *(volatile uint32_t *)0x400FF114 // Port Data Direction Register + +// Chapter 48: Touch sense input (TSI) +#define TSI0_GENCS *(volatile uint32_t *)0x40045000 // General Control and Status Register +#define TSI_GENCS_LPCLKS (uint32_t)0x10000000 // +#define TSI_GENCS_LPSCNITV(n) (((n) & 15) << 24) // +#define TSI_GENCS_NSCN(n) (((n) & 31) << 19) // +#define TSI_GENCS_PS(n) (((n) & 7) << 16) // +#define TSI_GENCS_EOSF (uint32_t)0x00008000 // +#define TSI_GENCS_OUTRGF (uint32_t)0x00004000 // +#define TSI_GENCS_EXTERF (uint32_t)0x00002000 // +#define TSI_GENCS_OVRF (uint32_t)0x00001000 // +#define TSI_GENCS_SCNIP (uint32_t)0x00000200 // +#define TSI_GENCS_SWTS (uint32_t)0x00000100 // +#define TSI_GENCS_TSIEN (uint32_t)0x00000080 // +#define TSI_GENCS_TSIIE (uint32_t)0x00000040 // +#define TSI_GENCS_ERIE (uint32_t)0x00000020 // +#define TSI_GENCS_ESOR (uint32_t)0x00000010 // +#define TSI_GENCS_STM (uint32_t)0x00000002 // +#define TSI_GENCS_STPE (uint32_t)0x00000001 // +#define TSI0_SCANC *(volatile uint32_t *)0x40045004 // SCAN Control Register +#define TSI_SCANC_REFCHRG(n) (((n) & 15) << 24) // +#define TSI_SCANC_EXTCHRG(n) (((n) & 7) << 16) // +#define TSI_SCANC_SMOD(n) (((n) & 255) << 8) // +#define TSI_SCANC_AMCLKS(n) (((n) & 3) << 3) // +#define TSI_SCANC_AMPSC(n) (((n) & 7) << 0) // +#define TSI0_PEN *(volatile uint32_t *)0x40045008 // Pin Enable Register +#define TSI0_WUCNTR *(volatile uint32_t *)0x4004500C // Wake-Up Channel Counter Register +#define TSI0_CNTR1 *(volatile uint32_t *)0x40045100 // Counter Register +#define TSI0_CNTR3 *(volatile uint32_t *)0x40045104 // Counter Register +#define TSI0_CNTR5 *(volatile uint32_t *)0x40045108 // Counter Register +#define TSI0_CNTR7 *(volatile uint32_t *)0x4004510C // Counter Register +#define TSI0_CNTR9 *(volatile uint32_t *)0x40045110 // Counter Register +#define TSI0_CNTR11 *(volatile uint32_t *)0x40045114 // Counter Register +#define TSI0_CNTR13 *(volatile uint32_t *)0x40045118 // Counter Register +#define TSI0_CNTR15 *(volatile uint32_t *)0x4004511C // Counter Register +#define TSI0_THRESHOLD *(volatile uint32_t *)0x40045120 // Low Power Channel Threshold Register + +// Nested Vectored Interrupt Controller, Table 3-4 & ARMv7 ref, appendix B3.4 (page 750) +#define NVIC_ENABLE_IRQ(n) (*((volatile uint32_t *)0xE000E100 + (n >> 5)) = (1 << (n & 31))) +#define NVIC_DISABLE_IRQ(n) (*((volatile uint32_t *)0xE000E180 + (n >> 5)) = (1 << (n & 31))) +#define NVIC_SET_PENDING(n) (*((volatile uint32_t *)0xE000E200 + (n >> 5)) = (1 << (n & 31))) +#define NVIC_CLEAR_PENDING(n) (*((volatile uint32_t *)0xE000E280 + (n >> 5)) = (1 << (n & 31))) + +#define NVIC_ISER0 *(volatile uint32_t *)0xE000E100 +#define NVIC_ISER1 *(volatile uint32_t *)0xE000E104 +#define NVIC_ICER0 *(volatile uint32_t *)0xE000E180 +#define NVIC_ICER1 *(volatile uint32_t *)0xE000E184 + +//#define NVIC_SET_PRIORITY(n, p) +#define IRQ_DMA_CH0 0 +#define IRQ_DMA_CH1 1 +#define IRQ_DMA_CH2 2 +#define IRQ_DMA_CH3 3 +#define IRQ_DMA_ERROR 4 +#define IRQ_FTFL_COMPLETE 6 +#define IRQ_FTFL_COLLISION 7 +#define IRQ_LOW_VOLTAGE 8 +#define IRQ_LLWU 9 +#define IRQ_WDOG 10 +#define IRQ_I2C0 11 +#define IRQ_SPI0 12 +#define IRQ_I2S0_TX 13 +#define IRQ_I2S0_RX 14 +#define IRQ_UART0_LON 15 +#define IRQ_UART0_STATUS 16 +#define IRQ_UART0_ERROR 17 +#define IRQ_UART1_STATUS 18 +#define IRQ_UART1_ERROR 19 +#define IRQ_UART2_STATUS 20 +#define IRQ_UART2_ERROR 21 +#define IRQ_ADC0 22 +#define IRQ_CMP0 23 +#define IRQ_CMP1 24 +#define IRQ_FTM0 25 +#define IRQ_FTM1 26 +#define IRQ_CMT 27 +#define IRQ_RTC_ALARM 28 +#define IRQ_RTC_SECOND 29 +#define IRQ_PIT_CH0 30 +#define IRQ_PIT_CH1 31 +#define IRQ_PIT_CH2 32 +#define IRQ_PIT_CH3 33 +#define IRQ_PDB 34 +#define IRQ_USBOTG 35 +#define IRQ_USBDCD 36 +#define IRQ_TSI 37 +#define IRQ_MCG 38 +#define IRQ_LPTMR 39 +#define IRQ_PORTA 40 +#define IRQ_PORTB 41 +#define IRQ_PORTC 42 +#define IRQ_PORTD 43 +#define IRQ_PORTE 44 +#define IRQ_SOFTWARE 45 + + +#define __disable_irq() asm volatile("CPSID i"); +#define __enable_irq() asm volatile("CPSIE i"); + +// System Control Space (SCS), ARMv7 ref manual, B3.2, page 708 +#define SCB_CPUID *(const uint32_t *)0xE000ED00 // CPUID Base Register +#define SCB_ICSR *(volatile uint32_t *)0xE000ED04 // Interrupt Control and State +#define SCB_ICSR_PENDSTSET (uint32_t)0x04000000 +#define SCB_VTOR *(volatile uint32_t *)0xE000ED08 // Vector Table Offset +#define SCB_AIRCR *(volatile uint32_t *)0xE000ED0C // Application Interrupt and Reset Control +#define SCB_SCR *(volatile uint32_t *)0xE000ED10 // System Control Register +#define SCB_CCR *(volatile uint32_t *)0xE000ED14 // Configuration and Control +#define SCB_SHPR1 *(volatile uint32_t *)0xE000ED18 // System Handler Priority Register 1 +#define SCB_SHPR2 *(volatile uint32_t *)0xE000ED1C // System Handler Priority Register 2 +#define SCB_SHPR3 *(volatile uint32_t *)0xE000ED20 // System Handler Priority Register 3 +#define SCB_SHCSR *(volatile uint32_t *)0xE000ED24 // System Handler Control and State +#define SCB_CFSR *(volatile uint32_t *)0xE000ED28 // Configurable Fault Status Register +#define SCB_HFSR *(volatile uint32_t *)0xE000ED2C // HardFault Status +#define SCB_DFSR *(volatile uint32_t *)0xE000ED30 // Debug Fault Status +#define SCB_MMFAR *(volatile uint32_t *)0xE000ED34 // MemManage Fault Address + +#define SYST_CSR *(volatile uint32_t *)0xE000E010 // SysTick Control and Status +#define SYST_CSR_COUNTFLAG (uint32_t)0x00010000 +#define SYST_CSR_CLKSOURCE (uint32_t)0x00000004 +#define SYST_CSR_TICKINT (uint32_t)0x00000002 +#define SYST_CSR_ENABLE (uint32_t)0x00000001 +#define SYST_RVR *(volatile uint32_t *)0xE000E014 // SysTick Reload Value Register +#define SYST_CVR *(volatile uint32_t *)0xE000E018 // SysTick Current Value Register +#define SYST_CALIB *(const uint32_t *)0xE000E01C // SysTick Calibration Value + + +#define ARM_DEMCR *(volatile uint32_t *)0xE000EDFC // Debug Exception and Monitor Control +#define ARM_DEMCR_TRCENA (1 << 24) // Enable debugging & monitoring blocks +#define ARM_DWT_CTRL *(volatile uint32_t *)0xE0001000 // DWT control register +#define ARM_DWT_CTRL_CYCCNTENA (1 << 0) // Enable cycle count +#define ARM_DWT_CYCCNT *(volatile uint32_t *)0xE0001004 // Cycle count register + + +extern void nmi_isr(void); +extern void hard_fault_isr(void); +extern void memmanage_fault_isr(void); +extern void bus_fault_isr(void); +extern void usage_fault_isr(void); +extern void svcall_isr(void); +extern void debugmonitor_isr(void); +extern void pendablesrvreq_isr(void); +extern void systick_isr(void); +extern void dma_ch0_isr(void); +extern void dma_ch1_isr(void); +extern void dma_ch2_isr(void); +extern void dma_ch3_isr(void); +extern void dma_error_isr(void); +extern void flash_cmd_isr(void); +extern void flash_error_isr(void); +extern void low_voltage_isr(void); +extern void wakeup_isr(void); +extern void watchdog_isr(void); +extern void i2c0_isr(void); +extern void spi0_isr(void); +extern void i2s0_tx_isr(void); +extern void i2s0_rx_isr(void); +extern void uart0_lon_isr(void); +extern void uart0_status_isr(void); +extern void uart0_error_isr(void); +extern void uart1_status_isr(void); +extern void uart1_error_isr(void); +extern void uart2_status_isr(void); +extern void uart2_error_isr(void); +extern void adc0_isr(void); +extern void cmp0_isr(void); +extern void cmp1_isr(void); +extern void ftm0_isr(void); +extern void ftm1_isr(void); +extern void cmt_isr(void); +extern void rtc_alarm_isr(void); +extern void rtc_seconds_isr(void); +extern void pit0_isr(void); +extern void pit1_isr(void); +extern void pit2_isr(void); +extern void pit3_isr(void); +extern void pdb_isr(void); +extern void usb_isr(void); +extern void usb_charge_isr(void); +extern void tsi0_isr(void); +extern void mcg_isr(void); +extern void lptmr_isr(void); +extern void porta_isr(void); +extern void portb_isr(void); +extern void portc_isr(void); +extern void portd_isr(void); +extern void porte_isr(void); +extern void software_isr(void); + + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/teensy3/mk20dx128.ld b/teensy3/mk20dx128.ld new file mode 100644 index 0000000000000000000000000000000000000000..a838f85deba42b36d4636eb67abc95d559798cb7 --- /dev/null +++ b/teensy3/mk20dx128.ld @@ -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); +} + + diff --git a/teensy3/nonstd.c b/teensy3/nonstd.c new file mode 100644 index 0000000000000000000000000000000000000000..39009e3325989ffcad0c6bfe3c85b2ea3b1f459e --- /dev/null +++ b/teensy3/nonstd.c @@ -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; +} + diff --git a/teensy3/pins_arduino.h b/teensy3/pins_arduino.h new file mode 100644 index 0000000000000000000000000000000000000000..0b0c356f82ac70ad485ce8afe13c90059627723b --- /dev/null +++ b/teensy3/pins_arduino.h @@ -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 diff --git a/teensy3/pins_teensy.c b/teensy3/pins_teensy.c new file mode 100644 index 0000000000000000000000000000000000000000..329269f518086d5ff70ddfd153c5d3edfea45782 --- /dev/null +++ b/teensy3/pins_teensy.c @@ -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);; +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/teensy3/serial1.c b/teensy3/serial1.c new file mode 100644 index 0000000000000000000000000000000000000000..846d7d6f60f6ab3c67b08a4d1a26327f62495df7 --- /dev/null +++ b/teensy3/serial1.c @@ -0,0 +1,285 @@ +/* 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" + +// 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 TX_BUFFER_SIZE 64 +//#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; + +#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 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_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; +} + +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) { + yield(); // wait + } + 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 { + yield(); // wait + } 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) +{ + 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 serial_getchar(void) +{ + uint8_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) +{ + uint8_t head, tail; + + head = rx_buffer_head; + tail = rx_buffer_tail; + if (head == tail) return -1; + 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) +{ + uint8_t avail, head, newhead, tail, 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); +} + diff --git a/teensy3/serial2.c b/teensy3/serial2.c new file mode 100644 index 0000000000000000000000000000000000000000..f87ddae78359ae38598e0bfcc85472e85095378c --- /dev/null +++ b/teensy3/serial2.c @@ -0,0 +1,196 @@ +/* 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" + +// 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 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; + +#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 C2_ENABLE UART_C2_TE | UART_C2_RE | UART_C2_RIE +#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 serial2_begin(uint32_t divisor) +{ + SIM_SCGC4 |= SIM_SCGC4_UART1; // 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_PIN9_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_PFE | PORT_PCR_MUX(3); + CORE_PIN10_CONFIG = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(3); + UART1_BDH = (divisor >> 13) & 0x1F; + UART1_BDL = (divisor >> 5) & 0xFF; + UART1_C4 = divisor & 0x1F; + UART1_C1 = 0; + UART1_PFIFO = 0; + UART1_C2 = C2_TX_INACTIVE; + NVIC_ENABLE_IRQ(IRQ_UART1_STATUS); +} + +void serial2_end(void) +{ + if (!(SIM_SCGC4 & SIM_SCGC4_UART1)) return; + while (transmitting) yield(); // wait for buffered data to send + NVIC_DISABLE_IRQ(IRQ_UART1_STATUS); + UART1_C2 = 0; + CORE_PIN9_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1); + CORE_PIN10_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1); + rx_buffer_head = 0; + rx_buffer_tail = 0; +} + +void serial2_putchar(uint8_t c) +{ + uint32_t head; + + if (!(SIM_SCGC4 & SIM_SCGC4_UART1)) return; + head = tx_buffer_head; + if (++head >= TX_BUFFER_SIZE) head = 0; + while (tx_buffer_tail == head) { + yield(); // wait + } + tx_buffer[head] = c; + transmitting = 1; + tx_buffer_head = head; + UART1_C2 = C2_TX_ACTIVE; +} + +void serial2_write(const void *buf, unsigned int count) +{ + const uint8_t *p = (const uint8_t *)buf; + while (count-- > 0) serial2_putchar(*p++); +} + +void serial2_flush(void) +{ + while (transmitting) yield(); // wait +} + +int serial2_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 serial2_getchar(void) +{ + uint8_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 serial2_peek(void) +{ + uint8_t head, tail; + + head = rx_buffer_head; + tail = rx_buffer_tail; + if (head == tail) return -1; + return rx_buffer[tail]; +} + +void serial2_clear(void) +{ + 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 uart1_status_isr(void) +{ + uint8_t head, tail, c; + + //digitalWriteFast(4, HIGH); + if (UART1_S1 & UART_S1_RDRF) { + //digitalWriteFast(5, HIGH); + c = UART1_D; + head = rx_buffer_head + 1; + if (head >= RX_BUFFER_SIZE) head = 0; + if (head != rx_buffer_tail) { + rx_buffer[head] = c; + rx_buffer_head = head; + } + //digitalWriteFast(5, LOW); + } + c = UART1_C2; + if ((c & UART_C2_TIE) && (UART1_S1 & UART_S1_TDRE)) { + //digitalWriteFast(5, HIGH); + head = tx_buffer_head; + tail = tx_buffer_tail; + if (head == tail) { + UART1_C2 = C2_TX_COMPLETING; + } else { + if (++tail >= TX_BUFFER_SIZE) tail = 0; + UART1_D = tx_buffer[tail]; + tx_buffer_tail = tail; + } + //digitalWriteFast(5, LOW); + } + if ((c & UART_C2_TCIE) && (UART1_S1 & UART_S1_TC)) { + transmitting = 0; + UART1_C2 = C2_TX_INACTIVE; + } + //digitalWriteFast(4, LOW); +} + + diff --git a/teensy3/serial3.c b/teensy3/serial3.c new file mode 100644 index 0000000000000000000000000000000000000000..16907f8c9af10f25ea1813234becbbba2c32493f --- /dev/null +++ b/teensy3/serial3.c @@ -0,0 +1,196 @@ +/* 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" + +// 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 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; + +#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 C2_ENABLE UART_C2_TE | UART_C2_RE | UART_C2_RIE +#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 serial3_begin(uint32_t divisor) +{ + SIM_SCGC4 |= SIM_SCGC4_UART2; // 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_PIN7_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_PFE | PORT_PCR_MUX(3); + CORE_PIN8_CONFIG = PORT_PCR_DSE | PORT_PCR_SRE | PORT_PCR_MUX(3); + UART2_BDH = (divisor >> 13) & 0x1F; + UART2_BDL = (divisor >> 5) & 0xFF; + UART2_C4 = divisor & 0x1F; + UART2_C1 = 0; + UART2_PFIFO = 0; + UART2_C2 = C2_TX_INACTIVE; + NVIC_ENABLE_IRQ(IRQ_UART2_STATUS); +} + +void serial3_end(void) +{ + if (!(SIM_SCGC4 & SIM_SCGC4_UART2)) return; + while (transmitting) yield(); // wait for buffered data to send + NVIC_DISABLE_IRQ(IRQ_UART2_STATUS); + UART2_C2 = 0; + CORE_PIN7_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1); + CORE_PIN8_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1); + rx_buffer_head = 0; + rx_buffer_tail = 0; +} + +void serial3_putchar(uint8_t c) +{ + uint32_t head; + + if (!(SIM_SCGC4 & SIM_SCGC4_UART2)) return; + head = tx_buffer_head; + if (++head >= TX_BUFFER_SIZE) head = 0; + while (tx_buffer_tail == head) { + yield(); // wait + } + tx_buffer[head] = c; + transmitting = 1; + tx_buffer_head = head; + UART2_C2 = C2_TX_ACTIVE; +} + +void serial3_write(const void *buf, unsigned int count) +{ + const uint8_t *p = (const uint8_t *)buf; + while (count-- > 0) serial3_putchar(*p++); +} + +void serial3_flush(void) +{ + while (transmitting) yield(); // wait +} + +int serial3_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 serial3_getchar(void) +{ + uint8_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 serial3_peek(void) +{ + uint8_t head, tail; + + head = rx_buffer_head; + tail = rx_buffer_tail; + if (head == tail) return -1; + return rx_buffer[tail]; +} + +void serial3_clear(void) +{ + 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 uart2_status_isr(void) +{ + uint8_t head, tail, c; + + //digitalWriteFast(4, HIGH); + if (UART2_S1 & UART_S1_RDRF) { + //digitalWriteFast(5, HIGH); + c = UART2_D; + head = rx_buffer_head + 1; + if (head >= RX_BUFFER_SIZE) head = 0; + if (head != rx_buffer_tail) { + rx_buffer[head] = c; + rx_buffer_head = head; + } + //digitalWriteFast(5, LOW); + } + c = UART2_C2; + if ((c & UART_C2_TIE) && (UART2_S1 & UART_S1_TDRE)) { + //digitalWriteFast(5, HIGH); + head = tx_buffer_head; + tail = tx_buffer_tail; + if (head == tail) { + UART2_C2 = C2_TX_COMPLETING; + } else { + if (++tail >= TX_BUFFER_SIZE) tail = 0; + UART2_D = tx_buffer[tail]; + tx_buffer_tail = tail; + } + //digitalWriteFast(5, LOW); + } + if ((c & UART_C2_TCIE) && (UART2_S1 & UART_S1_TC)) { + transmitting = 0; + UART2_C2 = C2_TX_INACTIVE; + } + //digitalWriteFast(4, LOW); +} + + diff --git a/teensy3/touch.c b/teensy3/touch.c new file mode 100644 index 0000000000000000000000000000000000000000..02b8f4f6293b8ae972f10ae2ec04bd596257bc45 --- /dev/null +++ b/teensy3/touch.c @@ -0,0 +1,77 @@ +/* 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 const uint8_t pin2tsi[] = { +//0 1 2 3 4 5 6 7 8 9 + 9, 10, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 13, 0, 6, 8, 7, +255, 255, 14, 15, 255, 12, 255, 255, 255, 255, +255, 255, 11, 5 +}; + +// These settings give approx 0.02 pF sensitivity and 1200 pF range +// Lower current, higher number of scans, and higher prescaler +// increase sensitivity, but the trade-off is longer measurement +// time and decreased range. +#define CURRENT 2 // 0 to 15 - current to use, value is 2*(current+1) +#define NSCAN 9 // number of times to scan, 0 to 31, value is nscan+1 +#define PRESCALE 2 // prescaler, 0 to 7 - value is 2^(prescaler+1) + + +// output is approx pF * 50 +// time to measure 33 pF is approx 0.25 ms +// time to measure 1000 pF is approx 4.5 ms + +int touchRead(uint8_t pin) +{ + uint32_t ch; + + if (pin >= NUM_DIGITAL_PINS) return 0; + ch = pin2tsi[pin]; + if (ch == 255) return 0; + + *portConfigRegister(pin) = PORT_PCR_MUX(0); + SIM_SCGC5 |= SIM_SCGC5_TSI; + TSI0_GENCS = 0; + TSI0_PEN = (1 << ch); + TSI0_SCANC = TSI_SCANC_REFCHRG(3) | TSI_SCANC_EXTCHRG(CURRENT); + TSI0_GENCS = TSI_GENCS_NSCN(NSCAN) | TSI_GENCS_PS(PRESCALE) | TSI_GENCS_TSIEN | TSI_GENCS_SWTS; + delayMicroseconds(10); + while (TSI0_GENCS & TSI_GENCS_SCNIP) ; // wait + delayMicroseconds(1); + return *((volatile uint16_t *)(&TSI0_CNTR1) + ch); +} + + + + diff --git a/teensy3/usb_desc.c b/teensy3/usb_desc.c new file mode 100644 index 0000000000000000000000000000000000000000..778e0657ba823ecc5869c83b55d364380a6f687d --- /dev/null +++ b/teensy3/usb_desc.c @@ -0,0 +1,882 @@ +/* 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 "usb_desc.h" +#include "usb_names.h" +#include "mk20dx128.h" +#include "avr_functions.h" + +// USB Descriptors are binary data which the USB host reads to +// automatically detect a USB device's capabilities. The format +// and meaning of every field is documented in numerous USB +// standards. When working with USB descriptors, despite the +// complexity of the standards and poor writing quality in many +// of those documents, remember descriptors are nothing more +// than constant binary data that tells the USB host what the +// device can do. Computers will load drivers based on this data. +// Those drivers then communicate on the endpoints specified by +// the descriptors. + +// To configure a new combination of interfaces or make minor +// changes to existing configuration (eg, change the name or ID +// numbers), usually you would edit "usb_desc.h". This file +// is meant to be configured by the header, so generally it is +// only edited to add completely new USB interfaces or features. + + + +// ************************************************************** +// USB Device +// ************************************************************** + +#define LSB(n) ((n) & 255) +#define MSB(n) (((n) >> 8) & 255) + +// USB Device Descriptor. The USB host reads this first, to learn +// what type of device is connected. +static uint8_t device_descriptor[] = { + 18, // bLength + 1, // bDescriptorType + 0x00, 0x02, // bcdUSB +#ifdef DEVICE_CLASS + DEVICE_CLASS, // bDeviceClass +#else + 0, +#endif +#ifdef DEVICE_SUBCLASS + DEVICE_SUBCLASS, // bDeviceSubClass +#else + 0, +#endif +#ifdef DEVICE_PROTOCOL + DEVICE_PROTOCOL, // bDeviceProtocol +#else + 0, +#endif + EP0_SIZE, // bMaxPacketSize0 + LSB(VENDOR_ID), MSB(VENDOR_ID), // idVendor + LSB(PRODUCT_ID), MSB(PRODUCT_ID), // idProduct + 0x00, 0x01, // bcdDevice + 1, // iManufacturer + 2, // iProduct + 3, // iSerialNumber + 1 // bNumConfigurations +}; + +// These descriptors must NOT be "const", because the USB DMA +// has trouble accessing flash memory with enough bandwidth +// while the processor is executing from flash. + + + +// ************************************************************** +// HID Report Descriptors +// ************************************************************** + +// Each HID interface needs a special report descriptor that tells +// the meaning and format of the data. + +#ifdef KEYBOARD_INTERFACE +// Keyboard Protocol 1, HID 1.11 spec, Appendix B, page 59-60 +static uint8_t keyboard_report_desc[] = { + 0x05, 0x01, // Usage Page (Generic Desktop), + 0x09, 0x06, // Usage (Keyboard), + 0xA1, 0x01, // Collection (Application), + 0x75, 0x01, // Report Size (1), + 0x95, 0x08, // Report Count (8), + 0x05, 0x07, // Usage Page (Key Codes), + 0x19, 0xE0, // Usage Minimum (224), + 0x29, 0xE7, // Usage Maximum (231), + 0x15, 0x00, // Logical Minimum (0), + 0x25, 0x01, // Logical Maximum (1), + 0x81, 0x02, // Input (Data, Variable, Absolute), ;Modifier byte + 0x95, 0x08, // Report Count (8), + 0x75, 0x01, // Report Size (1), + 0x15, 0x00, // Logical Minimum (0), + 0x25, 0x01, // Logical Maximum (1), + 0x05, 0x0C, // Usage Page (Consumer), + 0x09, 0xE9, // Usage (Volume Increment), + 0x09, 0xEA, // Usage (Volume Decrement), + 0x09, 0xE2, // Usage (Mute), + 0x09, 0xCD, // Usage (Play/Pause), + 0x09, 0xB5, // Usage (Scan Next Track), + 0x09, 0xB6, // Usage (Scan Previous Track), + 0x09, 0xB7, // Usage (Stop), + 0x09, 0xB8, // Usage (Eject), + 0x81, 0x02, // Input (Data, Variable, Absolute), ;Media keys + 0x95, 0x05, // Report Count (5), + 0x75, 0x01, // Report Size (1), + 0x05, 0x08, // Usage Page (LEDs), + 0x19, 0x01, // Usage Minimum (1), + 0x29, 0x05, // Usage Maximum (5), + 0x91, 0x02, // Output (Data, Variable, Absolute), ;LED report + 0x95, 0x01, // Report Count (1), + 0x75, 0x03, // Report Size (3), + 0x91, 0x03, // Output (Constant), ;LED report padding + 0x95, 0x06, // Report Count (6), + 0x75, 0x08, // Report Size (8), + 0x15, 0x00, // Logical Minimum (0), + 0x25, 0x7F, // Logical Maximum(104), + 0x05, 0x07, // Usage Page (Key Codes), + 0x19, 0x00, // Usage Minimum (0), + 0x29, 0x7F, // Usage Maximum (104), + 0x81, 0x00, // Input (Data, Array), ;Normal keys + 0xc0 // End Collection +}; +#endif + +#ifdef MOUSE_INTERFACE +// Mouse Protocol 1, HID 1.11 spec, Appendix B, page 59-60, with wheel extension +static uint8_t mouse_report_desc[] = { + 0x05, 0x01, // Usage Page (Generic Desktop) + 0x09, 0x02, // Usage (Mouse) + 0xA1, 0x01, // Collection (Application) + 0x05, 0x09, // Usage Page (Button) + 0x19, 0x01, // Usage Minimum (Button #1) + 0x29, 0x03, // Usage Maximum (Button #3) + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x01, // Logical Maximum (1) + 0x95, 0x03, // Report Count (3) + 0x75, 0x01, // Report Size (1) + 0x81, 0x02, // Input (Data, Variable, Absolute) + 0x95, 0x01, // Report Count (1) + 0x75, 0x05, // Report Size (5) + 0x81, 0x03, // Input (Constant) + 0x05, 0x01, // Usage Page (Generic Desktop) + 0x09, 0x30, // Usage (X) + 0x09, 0x31, // Usage (Y) + 0x15, 0x81, // Logical Minimum (-127) + 0x25, 0x7F, // Logical Maximum (127) + 0x75, 0x08, // Report Size (8), + 0x95, 0x02, // Report Count (2), + 0x81, 0x06, // Input (Data, Variable, Relative) + 0x09, 0x38, // Usage (Wheel) + 0x95, 0x01, // Report Count (1), + 0x81, 0x06, // Input (Data, Variable, Relative) + 0xC0 // End Collection +}; +#endif + +#ifdef JOYSTICK_INTERFACE +static uint8_t joystick_report_desc[] = { + 0x05, 0x01, // Usage Page (Generic Desktop) + 0x09, 0x04, // Usage (Joystick) + 0xA1, 0x01, // Collection (Application) + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x01, // Logical Maximum (1) + 0x75, 0x01, // Report Size (1) + 0x95, 0x20, // Report Count (32) + 0x05, 0x09, // Usage Page (Button) + 0x19, 0x01, // Usage Minimum (Button #1) + 0x29, 0x20, // Usage Maximum (Button #32) + 0x81, 0x02, // Input (variable,absolute) + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x07, // Logical Maximum (7) + 0x35, 0x00, // Physical Minimum (0) + 0x46, 0x3B, 0x01, // Physical Maximum (315) + 0x75, 0x04, // Report Size (4) + 0x95, 0x01, // Report Count (1) + 0x65, 0x14, // Unit (20) + 0x05, 0x01, // Usage Page (Generic Desktop) + 0x09, 0x39, // Usage (Hat switch) + 0x81, 0x42, // Input (variable,absolute,null_state) + 0x05, 0x01, // Usage Page (Generic Desktop) + 0x09, 0x01, // Usage (Pointer) + 0xA1, 0x00, // Collection () + 0x15, 0x00, // Logical Minimum (0) + 0x26, 0xFF, 0x03, // Logical Maximum (1023) + 0x75, 0x0A, // Report Size (10) + 0x95, 0x04, // Report Count (4) + 0x09, 0x30, // Usage (X) + 0x09, 0x31, // Usage (Y) + 0x09, 0x32, // Usage (Z) + 0x09, 0x35, // Usage (Rz) + 0x81, 0x02, // Input (variable,absolute) + 0xC0, // End Collection + 0x15, 0x00, // Logical Minimum (0) + 0x26, 0xFF, 0x03, // Logical Maximum (1023) + 0x75, 0x0A, // Report Size (10) + 0x95, 0x02, // Report Count (2) + 0x09, 0x36, // Usage (Slider) + 0x09, 0x36, // Usage (Slider) + 0x81, 0x02, // Input (variable,absolute) + 0xC0 // End Collection +}; +#endif + +#ifdef SEREMU_INTERFACE +static uint8_t seremu_report_desc[] = { + 0x06, 0xC9, 0xFF, // Usage Page 0xFFC9 (vendor defined) + 0x09, 0x04, // Usage 0x04 + 0xA1, 0x5C, // Collection 0x5C + 0x75, 0x08, // report size = 8 bits (global) + 0x15, 0x00, // logical minimum = 0 (global) + 0x26, 0xFF, 0x00, // logical maximum = 255 (global) + 0x95, SEREMU_TX_SIZE, // report count (global) + 0x09, 0x75, // usage (local) + 0x81, 0x02, // Input + 0x95, SEREMU_RX_SIZE, // report count (global) + 0x09, 0x76, // usage (local) + 0x91, 0x02, // Output + 0x95, 0x04, // report count (global) + 0x09, 0x76, // usage (local) + 0xB1, 0x02, // Feature + 0xC0 // end collection +}; +#endif + +#ifdef RAWHID_INTERFACE +static uint8_t rawhid_report_desc[] = { + 0x06, LSB(RAWHID_USAGE_PAGE), MSB(RAWHID_USAGE_PAGE), + 0x0A, LSB(RAWHID_USAGE), MSB(RAWHID_USAGE), + 0xA1, 0x01, // Collection 0x01 + 0x75, 0x08, // report size = 8 bits + 0x15, 0x00, // logical minimum = 0 + 0x26, 0xFF, 0x00, // logical maximum = 255 + 0x95, RAWHID_TX_SIZE, // report count + 0x09, 0x01, // usage + 0x81, 0x02, // Input (array) + 0x95, RAWHID_RX_SIZE, // report count + 0x09, 0x02, // usage + 0x91, 0x02, // Output (array) + 0xC0 // end collection +}; +#endif + +#ifdef FLIGHTSIM_INTERFACE +static uint8_t flightsim_report_desc[] = { + 0x06, 0x1C, 0xFF, // Usage page = 0xFF1C + 0x0A, 0x39, 0xA7, // Usage = 0xA739 + 0xA1, 0x01, // Collection 0x01 + 0x75, 0x08, // report size = 8 bits + 0x15, 0x00, // logical minimum = 0 + 0x26, 0xFF, 0x00, // logical maximum = 255 + 0x95, FLIGHTSIM_TX_SIZE, // report count + 0x09, 0x01, // usage + 0x81, 0x02, // Input (array) + 0x95, FLIGHTSIM_RX_SIZE, // report count + 0x09, 0x02, // usage + 0x91, 0x02, // Output (array) + 0xC0 // end collection +}; +#endif + + + +// ************************************************************** +// USB Configuration +// ************************************************************** + +// USB Configuration Descriptor. This huge descriptor tells all +// of the devices capbilities. +static uint8_t config_descriptor[CONFIG_DESC_SIZE] = { + // configuration descriptor, USB spec 9.6.3, page 264-266, Table 9-10 + 9, // bLength; + 2, // bDescriptorType; + LSB(CONFIG_DESC_SIZE), // wTotalLength + MSB(CONFIG_DESC_SIZE), + NUM_INTERFACE, // bNumInterfaces + 1, // bConfigurationValue + 0, // iConfiguration + 0xC0, // bmAttributes + 50, // bMaxPower + +#ifdef CDC_IAD_DESCRIPTOR + // interface association descriptor, USB ECN, Table 9-Z + 8, // bLength + 11, // bDescriptorType + CDC_STATUS_INTERFACE, // bFirstInterface + 2, // bInterfaceCount + 0x02, // bFunctionClass + 0x02, // bFunctionSubClass + 0x01, // bFunctionProtocol + 4, // iFunction +#endif + +#ifdef CDC_DATA_INTERFACE + // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 + 9, // bLength + 4, // bDescriptorType + CDC_STATUS_INTERFACE, // bInterfaceNumber + 0, // bAlternateSetting + 1, // bNumEndpoints + 0x02, // bInterfaceClass + 0x02, // bInterfaceSubClass + 0x01, // bInterfaceProtocol + 0, // iInterface + // CDC Header Functional Descriptor, CDC Spec 5.2.3.1, Table 26 + 5, // bFunctionLength + 0x24, // bDescriptorType + 0x00, // bDescriptorSubtype + 0x10, 0x01, // bcdCDC + // Call Management Functional Descriptor, CDC Spec 5.2.3.2, Table 27 + 5, // bFunctionLength + 0x24, // bDescriptorType + 0x01, // bDescriptorSubtype + 0x01, // bmCapabilities + 1, // bDataInterface + // Abstract Control Management Functional Descriptor, CDC Spec 5.2.3.3, Table 28 + 4, // bFunctionLength + 0x24, // bDescriptorType + 0x02, // bDescriptorSubtype + 0x06, // bmCapabilities + // Union Functional Descriptor, CDC Spec 5.2.3.8, Table 33 + 5, // bFunctionLength + 0x24, // bDescriptorType + 0x06, // bDescriptorSubtype + CDC_STATUS_INTERFACE, // bMasterInterface + CDC_DATA_INTERFACE, // bSlaveInterface0 + // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 + 7, // bLength + 5, // bDescriptorType + CDC_ACM_ENDPOINT | 0x80, // bEndpointAddress + 0x03, // bmAttributes (0x03=intr) + CDC_ACM_SIZE, 0, // wMaxPacketSize + 64, // bInterval + // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 + 9, // bLength + 4, // bDescriptorType + CDC_DATA_INTERFACE, // bInterfaceNumber + 0, // bAlternateSetting + 2, // bNumEndpoints + 0x0A, // bInterfaceClass + 0x00, // bInterfaceSubClass + 0x00, // bInterfaceProtocol + 0, // iInterface + // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 + 7, // bLength + 5, // bDescriptorType + CDC_RX_ENDPOINT, // bEndpointAddress + 0x02, // bmAttributes (0x02=bulk) + CDC_RX_SIZE, 0, // wMaxPacketSize + 0, // bInterval + // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 + 7, // bLength + 5, // bDescriptorType + CDC_TX_ENDPOINT | 0x80, // bEndpointAddress + 0x02, // bmAttributes (0x02=bulk) + CDC_TX_SIZE, 0, // wMaxPacketSize + 0, // bInterval +#endif // CDC_DATA_INTERFACE + +#ifdef MIDI_INTERFACE + // Standard MS Interface Descriptor, + 9, // bLength + 4, // bDescriptorType + MIDI_INTERFACE, // bInterfaceNumber + 0, // bAlternateSetting + 2, // bNumEndpoints + 0x01, // bInterfaceClass (0x01 = Audio) + 0x03, // bInterfaceSubClass (0x03 = MIDI) + 0x00, // bInterfaceProtocol (unused for MIDI) + 0, // iInterface + // MIDI MS Interface Header, USB MIDI 6.1.2.1, page 21, Table 6-2 + 7, // bLength + 0x24, // bDescriptorType = CS_INTERFACE + 0x01, // bDescriptorSubtype = MS_HEADER + 0x00, 0x01, // bcdMSC = revision 01.00 + 0x41, 0x00, // wTotalLength + // MIDI IN Jack Descriptor, B.4.3, Table B-7 (embedded), page 40 + 6, // bLength + 0x24, // bDescriptorType = CS_INTERFACE + 0x02, // bDescriptorSubtype = MIDI_IN_JACK + 0x01, // bJackType = EMBEDDED + 1, // bJackID, ID = 1 + 0, // iJack + // MIDI IN Jack Descriptor, B.4.3, Table B-8 (external), page 40 + 6, // bLength + 0x24, // bDescriptorType = CS_INTERFACE + 0x02, // bDescriptorSubtype = MIDI_IN_JACK + 0x02, // bJackType = EXTERNAL + 2, // bJackID, ID = 2 + 0, // iJack + // MIDI OUT Jack Descriptor, B.4.4, Table B-9, page 41 + 9, + 0x24, // bDescriptorType = CS_INTERFACE + 0x03, // bDescriptorSubtype = MIDI_OUT_JACK + 0x01, // bJackType = EMBEDDED + 3, // bJackID, ID = 3 + 1, // bNrInputPins = 1 pin + 2, // BaSourceID(1) = 2 + 1, // BaSourcePin(1) = first pin + 0, // iJack + // MIDI OUT Jack Descriptor, B.4.4, Table B-10, page 41 + 9, + 0x24, // bDescriptorType = CS_INTERFACE + 0x03, // bDescriptorSubtype = MIDI_OUT_JACK + 0x02, // bJackType = EXTERNAL + 4, // bJackID, ID = 4 + 1, // bNrInputPins = 1 pin + 1, // BaSourceID(1) = 1 + 1, // BaSourcePin(1) = first pin + 0, // iJack + // Standard Bulk OUT Endpoint Descriptor, B.5.1, Table B-11, pae 42 + 9, // bLength + 5, // bDescriptorType = ENDPOINT + MIDI_RX_ENDPOINT, // bEndpointAddress + 0x02, // bmAttributes (0x02=bulk) + MIDI_RX_SIZE, 0, // wMaxPacketSize + 0, // bInterval + 0, // bRefresh + 0, // bSynchAddress + // Class-specific MS Bulk OUT Endpoint Descriptor, B.5.2, Table B-12, page 42 + 5, // bLength + 0x25, // bDescriptorSubtype = CS_ENDPOINT + 0x01, // bJackType = MS_GENERAL + 1, // bNumEmbMIDIJack = 1 jack + 1, // BaAssocJackID(1) = jack ID #1 + // Standard Bulk IN Endpoint Descriptor, B.5.1, Table B-11, pae 42 + 9, // bLength + 5, // bDescriptorType = ENDPOINT + MIDI_TX_ENDPOINT | 0x80, // bEndpointAddress + 0x02, // bmAttributes (0x02=bulk) + MIDI_TX_SIZE, 0, // wMaxPacketSize + 0, // bInterval + 0, // bRefresh + 0, // bSynchAddress + // Class-specific MS Bulk IN Endpoint Descriptor, B.5.2, Table B-12, page 42 + 5, // bLength + 0x25, // bDescriptorSubtype = CS_ENDPOINT + 0x01, // bJackType = MS_GENERAL + 1, // bNumEmbMIDIJack = 1 jack + 3, // BaAssocJackID(1) = jack ID #3 +#endif // MIDI_INTERFACE + +#ifdef KEYBOARD_INTERFACE + // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 + 9, // bLength + 4, // bDescriptorType + KEYBOARD_INTERFACE, // bInterfaceNumber + 0, // bAlternateSetting + 1, // bNumEndpoints + 0x03, // bInterfaceClass (0x03 = HID) + 0x01, // bInterfaceSubClass (0x01 = Boot) + 0x01, // bInterfaceProtocol (0x01 = Keyboard) + 0, // iInterface + // HID interface descriptor, HID 1.11 spec, section 6.2.1 + 9, // bLength + 0x21, // bDescriptorType + 0x11, 0x01, // bcdHID + 0, // bCountryCode + 1, // bNumDescriptors + 0x22, // bDescriptorType + LSB(sizeof(keyboard_report_desc)), // wDescriptorLength + MSB(sizeof(keyboard_report_desc)), + // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 + 7, // bLength + 5, // bDescriptorType + KEYBOARD_ENDPOINT | 0x80, // bEndpointAddress + 0x03, // bmAttributes (0x03=intr) + KEYBOARD_SIZE, 0, // wMaxPacketSize + KEYBOARD_INTERVAL, // bInterval +#endif // KEYBOARD_INTERFACE + +#ifdef MOUSE_INTERFACE + // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 + 9, // bLength + 4, // bDescriptorType + MOUSE_INTERFACE, // bInterfaceNumber + 0, // bAlternateSetting + 1, // bNumEndpoints + 0x03, // bInterfaceClass (0x03 = HID) + 0x01, // bInterfaceSubClass (0x01 = Boot) + 0x02, // bInterfaceProtocol (0x02 = Mouse) + 0, // iInterface + // HID interface descriptor, HID 1.11 spec, section 6.2.1 + 9, // bLength + 0x21, // bDescriptorType + 0x11, 0x01, // bcdHID + 0, // bCountryCode + 1, // bNumDescriptors + 0x22, // bDescriptorType + LSB(sizeof(mouse_report_desc)), // wDescriptorLength + MSB(sizeof(mouse_report_desc)), + // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 + 7, // bLength + 5, // bDescriptorType + MOUSE_ENDPOINT | 0x80, // bEndpointAddress + 0x03, // bmAttributes (0x03=intr) + MOUSE_SIZE, 0, // wMaxPacketSize + MOUSE_INTERVAL, // bInterval +#endif // MOUSE_INTERFACE + +#ifdef RAWHID_INTERFACE + // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 + 9, // bLength + 4, // bDescriptorType + RAWHID_INTERFACE, // bInterfaceNumber + 0, // bAlternateSetting + 2, // bNumEndpoints + 0x03, // bInterfaceClass (0x03 = HID) + 0x00, // bInterfaceSubClass + 0x00, // bInterfaceProtocol + 0, // iInterface + // HID interface descriptor, HID 1.11 spec, section 6.2.1 + 9, // bLength + 0x21, // bDescriptorType + 0x11, 0x01, // bcdHID + 0, // bCountryCode + 1, // bNumDescriptors + 0x22, // bDescriptorType + LSB(sizeof(rawhid_report_desc)), // wDescriptorLength + MSB(sizeof(rawhid_report_desc)), + // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 + 7, // bLength + 5, // bDescriptorType + RAWHID_TX_ENDPOINT | 0x80, // bEndpointAddress + 0x03, // bmAttributes (0x03=intr) + RAWHID_TX_SIZE, 0, // wMaxPacketSize + RAWHID_TX_INTERVAL, // bInterval + // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 + 7, // bLength + 5, // bDescriptorType + RAWHID_RX_ENDPOINT, // bEndpointAddress + 0x03, // bmAttributes (0x03=intr) + RAWHID_RX_SIZE, 0, // wMaxPacketSize + RAWHID_RX_INTERVAL, // bInterval +#endif // RAWHID_INTERFACE + +#ifdef FLIGHTSIM_INTERFACE + // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 + 9, // bLength + 4, // bDescriptorType + FLIGHTSIM_INTERFACE, // bInterfaceNumber + 0, // bAlternateSetting + 2, // bNumEndpoints + 0x03, // bInterfaceClass (0x03 = HID) + 0x00, // bInterfaceSubClass + 0x00, // bInterfaceProtocol + 0, // iInterface + // HID interface descriptor, HID 1.11 spec, section 6.2.1 + 9, // bLength + 0x21, // bDescriptorType + 0x11, 0x01, // bcdHID + 0, // bCountryCode + 1, // bNumDescriptors + 0x22, // bDescriptorType + LSB(sizeof(flightsim_report_desc)), // wDescriptorLength + MSB(sizeof(flightsim_report_desc)), + // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 + 7, // bLength + 5, // bDescriptorType + FLIGHTSIM_TX_ENDPOINT | 0x80, // bEndpointAddress + 0x03, // bmAttributes (0x03=intr) + FLIGHTSIM_TX_SIZE, 0, // wMaxPacketSize + FLIGHTSIM_TX_INTERVAL, // bInterval + // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 + 7, // bLength + 5, // bDescriptorType + FLIGHTSIM_RX_ENDPOINT, // bEndpointAddress + 0x03, // bmAttributes (0x03=intr) + FLIGHTSIM_RX_SIZE, 0, // wMaxPacketSize + FLIGHTSIM_RX_INTERVAL, // bInterval +#endif // FLIGHTSIM_INTERFACE + +#ifdef SEREMU_INTERFACE + // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 + 9, // bLength + 4, // bDescriptorType + SEREMU_INTERFACE, // bInterfaceNumber + 0, // bAlternateSetting + 2, // bNumEndpoints + 0x03, // bInterfaceClass (0x03 = HID) + 0x00, // bInterfaceSubClass + 0x00, // bInterfaceProtocol + 0, // iInterface + // HID interface descriptor, HID 1.11 spec, section 6.2.1 + 9, // bLength + 0x21, // bDescriptorType + 0x11, 0x01, // bcdHID + 0, // bCountryCode + 1, // bNumDescriptors + 0x22, // bDescriptorType + LSB(sizeof(seremu_report_desc)), // wDescriptorLength + MSB(sizeof(seremu_report_desc)), + // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 + 7, // bLength + 5, // bDescriptorType + SEREMU_TX_ENDPOINT | 0x80, // bEndpointAddress + 0x03, // bmAttributes (0x03=intr) + SEREMU_TX_SIZE, 0, // wMaxPacketSize + SEREMU_TX_INTERVAL, // bInterval + // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 + 7, // bLength + 5, // bDescriptorType + SEREMU_RX_ENDPOINT, // bEndpointAddress + 0x03, // bmAttributes (0x03=intr) + SEREMU_RX_SIZE, 0, // wMaxPacketSize + SEREMU_RX_INTERVAL, // bInterval +#endif // SEREMU_INTERFACE + +#ifdef JOYSTICK_INTERFACE + // interface descriptor, USB spec 9.6.5, page 267-269, Table 9-12 + 9, // bLength + 4, // bDescriptorType + JOYSTICK_INTERFACE, // bInterfaceNumber + 0, // bAlternateSetting + 1, // bNumEndpoints + 0x03, // bInterfaceClass (0x03 = HID) + 0x00, // bInterfaceSubClass + 0x00, // bInterfaceProtocol + 0, // iInterface + // HID interface descriptor, HID 1.11 spec, section 6.2.1 + 9, // bLength + 0x21, // bDescriptorType + 0x11, 0x01, // bcdHID + 0, // bCountryCode + 1, // bNumDescriptors + 0x22, // bDescriptorType + LSB(sizeof(joystick_report_desc)), // wDescriptorLength + MSB(sizeof(joystick_report_desc)), + // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 + 7, // bLength + 5, // bDescriptorType + JOYSTICK_ENDPOINT | 0x80, // bEndpointAddress + 0x03, // bmAttributes (0x03=intr) + JOYSTICK_SIZE, 0, // wMaxPacketSize + JOYSTICK_INTERVAL, // bInterval +#endif // JOYSTICK_INTERFACE + +}; + + +// ************************************************************** +// String Descriptors +// ************************************************************** + +// The descriptors above can provide human readable strings, +// referenced by index numbers. These descriptors are the +// actual string data + +/* defined in usb_names.h +struct usb_string_descriptor_struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t wString[]; +}; +*/ + +extern struct usb_string_descriptor_struct usb_string_manufacturer_name + __attribute__ ((weak, alias("usb_string_manufacturer_name_default"))); +extern struct usb_string_descriptor_struct usb_string_product_name + __attribute__ ((weak, alias("usb_string_product_name_default"))); +extern struct usb_string_descriptor_struct usb_string_serial_number + __attribute__ ((weak, alias("usb_string_serial_number_default"))); + +struct usb_string_descriptor_struct string0 = { + 4, + 3, + {0x0409} +}; + +struct usb_string_descriptor_struct usb_string_manufacturer_name_default = { + 2 + MANUFACTURER_NAME_LEN * 2, + 3, + MANUFACTURER_NAME +}; +struct usb_string_descriptor_struct usb_string_product_name_default = { + 2 + PRODUCT_NAME_LEN * 2, + 3, + PRODUCT_NAME +}; +struct usb_string_descriptor_struct usb_string_serial_number_default = { + 12, + 3, + {0,0,0,0,0,0,0,0,0,0} +}; + +void usb_init_serialnumber(void) +{ + char buf[11]; + uint32_t i, num; + + __disable_irq(); + FTFL_FSTAT = FTFL_FSTAT_RDCOLERR | FTFL_FSTAT_ACCERR | FTFL_FSTAT_FPVIOL; + FTFL_FCCOB0 = 0x41; + FTFL_FCCOB1 = 15; + FTFL_FSTAT = FTFL_FSTAT_CCIF; + while (!(FTFL_FSTAT & FTFL_FSTAT_CCIF)) ; // wait + num = *(uint32_t *)&FTFL_FCCOB7; + __enable_irq(); + ultoa(num, buf, 10); + for (i=0; i<10; i++) { + char c = buf[i]; + if (!c) break; + usb_string_serial_number_default.wString[i] = c; + } + usb_string_serial_number_default.bLength = i * 2 + 2; +} + + +// ************************************************************** +// Descriptors List +// ************************************************************** + +// This table provides access to all the descriptor data above. + +const usb_descriptor_list_t usb_descriptor_list[] = { + //wValue, wIndex, address, length + {0x0100, 0x0000, device_descriptor, sizeof(device_descriptor)}, + {0x0200, 0x0000, config_descriptor, sizeof(config_descriptor)}, +#ifdef SEREMU_INTERFACE + {0x2200, SEREMU_INTERFACE, seremu_report_desc, sizeof(seremu_report_desc)}, + {0x2100, SEREMU_INTERFACE, config_descriptor+SEREMU_DESC_OFFSET, 9}, +#endif +#ifdef KEYBOARD_INTERFACE + {0x2200, KEYBOARD_INTERFACE, keyboard_report_desc, sizeof(keyboard_report_desc)}, + {0x2100, KEYBOARD_INTERFACE, config_descriptor+KEYBOARD_DESC_OFFSET, 9}, +#endif +#ifdef MOUSE_INTERFACE + {0x2200, MOUSE_INTERFACE, mouse_report_desc, sizeof(mouse_report_desc)}, + {0x2100, MOUSE_INTERFACE, config_descriptor+MOUSE_DESC_OFFSET, 9}, +#endif +#ifdef JOYSTICK_INTERFACE + {0x2200, JOYSTICK_INTERFACE, joystick_report_desc, sizeof(joystick_report_desc)}, + {0x2100, JOYSTICK_INTERFACE, config_descriptor+JOYSTICK_DESC_OFFSET, 9}, +#endif +#ifdef RAWHID_INTERFACE + {0x2200, RAWHID_INTERFACE, rawhid_report_desc, sizeof(rawhid_report_desc)}, + {0x2100, RAWHID_INTERFACE, config_descriptor+RAWHID_DESC_OFFSET, 9}, +#endif +#ifdef FLIGHTSIM_INTERFACE + {0x2200, FLIGHTSIM_INTERFACE, flightsim_report_desc, sizeof(flightsim_report_desc)}, + {0x2100, FLIGHTSIM_INTERFACE, config_descriptor+FLIGHTSIM_DESC_OFFSET, 9}, +#endif + {0x0300, 0x0000, (const uint8_t *)&string0, 0}, + {0x0301, 0x0409, (const uint8_t *)&usb_string_manufacturer_name, 0}, + {0x0302, 0x0409, (const uint8_t *)&usb_string_product_name, 0}, + {0x0303, 0x0409, (const uint8_t *)&usb_string_serial_number, 0}, + //{0x0301, 0x0409, (const uint8_t *)&string1, 0}, + //{0x0302, 0x0409, (const uint8_t *)&string2, 0}, + //{0x0303, 0x0409, (const uint8_t *)&string3, 0}, + {0, 0, NULL, 0} +}; + + +// ************************************************************** +// Endpoint Configuration +// ************************************************************** + +#if 0 +// 0x00 = not used +// 0x19 = Recieve only +// 0x15 = Transmit only +// 0x1D = Transmit & Recieve +// +const uint8_t usb_endpoint_config_table[NUM_ENDPOINTS] = +{ + 0x00, 0x15, 0x19, 0x15, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; +#endif + + +const uint8_t usb_endpoint_config_table[NUM_ENDPOINTS] = +{ +#if (defined(ENDPOINT1_CONFIG) && NUM_ENDPOINTS >= 1) + ENDPOINT1_CONFIG, +#elif (NUM_ENDPOINTS >= 1) + ENDPOINT_UNUSED, +#endif +#if (defined(ENDPOINT2_CONFIG) && NUM_ENDPOINTS >= 2) + ENDPOINT2_CONFIG, +#elif (NUM_ENDPOINTS >= 2) + ENDPOINT_UNUSED, +#endif +#if (defined(ENDPOINT3_CONFIG) && NUM_ENDPOINTS >= 3) + ENDPOINT3_CONFIG, +#elif (NUM_ENDPOINTS >= 3) + ENDPOINT_UNUSED, +#endif +#if (defined(ENDPOINT4_CONFIG) && NUM_ENDPOINTS >= 4) + ENDPOINT4_CONFIG, +#elif (NUM_ENDPOINTS >= 4) + ENDPOINT_UNUSED, +#endif +#if (defined(ENDPOINT5_CONFIG) && NUM_ENDPOINTS >= 5) + ENDPOINT5_CONFIG, +#elif (NUM_ENDPOINTS >= 5) + ENDPOINT_UNUSED, +#endif +#if (defined(ENDPOINT6_CONFIG) && NUM_ENDPOINTS >= 6) + ENDPOINT6_CONFIG, +#elif (NUM_ENDPOINTS >= 6) + ENDPOINT_UNUSED, +#endif +#if (defined(ENDPOINT7_CONFIG) && NUM_ENDPOINTS >= 7) + ENDPOINT7_CONFIG, +#elif (NUM_ENDPOINTS >= 7) + ENDPOINT_UNUSED, +#endif +#if (defined(ENDPOINT8_CONFIG) && NUM_ENDPOINTS >= 8) + ENDPOINT8_CONFIG, +#elif (NUM_ENDPOINTS >= 8) + ENDPOINT_UNUSED, +#endif +#if (defined(ENDPOINT9_CONFIG) && NUM_ENDPOINTS >= 9) + ENDPOINT9_CONFIG, +#elif (NUM_ENDPOINTS >= 9) + ENDPOINT_UNUSED, +#endif +#if (defined(ENDPOINT10_CONFIG) && NUM_ENDPOINTS >= 10) + ENDPOINT10_CONFIG, +#elif (NUM_ENDPOINTS >= 10) + ENDPOINT_UNUSED, +#endif +#if (defined(ENDPOINT11_CONFIG) && NUM_ENDPOINTS >= 11) + ENDPOINT11_CONFIG, +#elif (NUM_ENDPOINTS >= 11) + ENDPOINT_UNUSED, +#endif +#if (defined(ENDPOINT12_CONFIG) && NUM_ENDPOINTS >= 12) + ENDPOINT12_CONFIG, +#elif (NUM_ENDPOINTS >= 12) + ENDPOINT_UNUSED, +#endif +#if (defined(ENDPOINT13_CONFIG) && NUM_ENDPOINTS >= 13) + ENDPOINT13_CONFIG, +#elif (NUM_ENDPOINTS >= 13) + ENDPOINT_UNUSED, +#endif +#if (defined(ENDPOINT14_CONFIG) && NUM_ENDPOINTS >= 14) + ENDPOINT14_CONFIG, +#elif (NUM_ENDPOINTS >= 14) + ENDPOINT_UNUSED, +#endif +#if (defined(ENDPOINT15_CONFIG) && NUM_ENDPOINTS >= 15) + ENDPOINT15_CONFIG, +#elif (NUM_ENDPOINTS >= 15) + ENDPOINT_UNUSED, +#endif +}; + + + + diff --git a/teensy3/usb_desc.h b/teensy3/usb_desc.h new file mode 100644 index 0000000000000000000000000000000000000000..958ca36d6c32de316a02711639618438f24440b8 --- /dev/null +++ b/teensy3/usb_desc.h @@ -0,0 +1,309 @@ +/* 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 _usb_desc_h_ +#define _usb_desc_h_ + +// This header is NOT meant to be included when compiling +// user sketches in Arduino. The low-level functions +// provided by usb_dev.c are meant to be called only by +// code which provides higher-level interfaces to the user. + +#include <stdint.h> +#include <stddef.h> + +#define ENDPOINT_UNUSED 0x00 +#define ENDPOINT_TRANSIMIT_ONLY 0x15 +#define ENDPOINT_RECEIVE_ONLY 0x19 +#define ENDPOINT_TRANSMIT_AND_RECEIVE 0x1D + +/* +To modify a USB Type to have different interfaces, start in this +file. Delete the XYZ_INTERFACE lines for any interfaces you +wish to remove, and copy them from another USB Type for any you +want to add. + +Give each interface a unique number, and edit NUM_INTERFACE to +reflect the number of interfaces. + +Within each interface, make sure it uses a unique set of endpoints. +Edit NUM_ENDPOINTS to be at least the largest endpoint number used. +Then edit the ENDPOINT*_CONFIG lines so each endpoint is configured +the proper way (transmit, receive, or both). + +The CONFIG_DESC_SIZE and any XYZ_DESC_OFFSET numbers must be +edited to the correct sizes. See usb_desc.c for the giant array +of bytes. Someday these may be done automatically..... (but how?) + +If you are using existing interfaces, the code in each file should +automatically adapt to the changes you specify. If you need to +create a new type of interface, you'll need to write the code which +sends and receives packets, and presents an API to the user. + +Finally, edit usb_inst.cpp, which creats instances of the C++ +objects for each combination. + +Some operating systems, especially Windows, may cache USB device +info. Changes to the device name may not update on the same +computer unless the vendor or product ID numbers change, or the +"bcdDevice" revision code is increased. + +If these instructions are missing steps or could be improved, please +let me know? http://forum.pjrc.com/forums/4-Suggestions-amp-Bug-Reports +*/ + + + +#if defined(USB_SERIAL) + #define VENDOR_ID 0x16C0 + #define PRODUCT_ID 0x0483 + #define DEVICE_CLASS 2 // 2 = Communication Class + #define MANUFACTURER_NAME {'T','e','e','n','s','y','d','u','i','n','o'} + #define MANUFACTURER_NAME_LEN 11 + #define PRODUCT_NAME {'U','S','B',' ','S','e','r','i','a','l'} + #define PRODUCT_NAME_LEN 10 + #define EP0_SIZE 64 + #define NUM_ENDPOINTS 4 + #define NUM_USB_BUFFERS 12 + #define NUM_INTERFACE 2 + #define CDC_STATUS_INTERFACE 0 + #define CDC_DATA_INTERFACE 1 + #define CDC_ACM_ENDPOINT 2 + #define CDC_RX_ENDPOINT 3 + #define CDC_TX_ENDPOINT 4 + #define CDC_ACM_SIZE 16 + #define CDC_RX_SIZE 64 + #define CDC_TX_SIZE 64 + #define CONFIG_DESC_SIZE (9+9+5+5+4+5+7+9+7+7) + #define ENDPOINT2_CONFIG ENDPOINT_TRANSIMIT_ONLY + #define ENDPOINT3_CONFIG ENDPOINT_RECEIVE_ONLY + #define ENDPOINT4_CONFIG ENDPOINT_TRANSIMIT_ONLY + +#elif defined(USB_HID) + #define VENDOR_ID 0x16C0 + #define PRODUCT_ID 0x0482 + #define MANUFACTURER_NAME {'T','e','e','n','s','y','d','u','i','n','o'} + #define MANUFACTURER_NAME_LEN 11 + #define PRODUCT_NAME {'K','e','y','b','o','a','r','d','/','M','o','u','s','e','/','J','o','y','s','t','i','c','k'} + #define PRODUCT_NAME_LEN 23 + #define EP0_SIZE 64 + #define NUM_ENDPOINTS 5 + #define NUM_USB_BUFFERS 24 + #define NUM_INTERFACE 4 + #define SEREMU_INTERFACE 2 // Serial emulation + #define SEREMU_TX_ENDPOINT 1 + #define SEREMU_TX_SIZE 64 + #define SEREMU_TX_INTERVAL 1 + #define SEREMU_RX_ENDPOINT 2 + #define SEREMU_RX_SIZE 32 + #define SEREMU_RX_INTERVAL 2 + #define KEYBOARD_INTERFACE 0 // Keyboard + #define KEYBOARD_ENDPOINT 3 + #define KEYBOARD_SIZE 8 + #define KEYBOARD_INTERVAL 1 + #define MOUSE_INTERFACE 1 // Mouse + #define MOUSE_ENDPOINT 5 + #define MOUSE_SIZE 8 + #define MOUSE_INTERVAL 1 + #define JOYSTICK_INTERFACE 3 // Joystick + #define JOYSTICK_ENDPOINT 4 + #define JOYSTICK_SIZE 16 + #define JOYSTICK_INTERVAL 2 + #define KEYBOARD_DESC_OFFSET (9 + 9) + #define MOUSE_DESC_OFFSET (9 + 9+9+7 + 9) + #define SEREMU_DESC_OFFSET (9 + 9+9+7 + 9+9+7 + 9) + #define JOYSTICK_DESC_OFFSET (9 + 9+9+7 + 9+9+7 + 9+9+7+7 + 9) + #define CONFIG_DESC_SIZE (9 + 9+9+7 + 9+9+7 + 9+9+7+7 + 9+9+7) + #define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY + #define ENDPOINT2_CONFIG ENDPOINT_RECEIVE_ONLY + #define ENDPOINT3_CONFIG ENDPOINT_TRANSIMIT_ONLY + #define ENDPOINT4_CONFIG ENDPOINT_TRANSIMIT_ONLY + #define ENDPOINT5_CONFIG ENDPOINT_TRANSIMIT_ONLY + +#elif defined(USB_SERIAL_HID) + #define VENDOR_ID 0x16C0 + #define PRODUCT_ID 0x0487 + #define DEVICE_CLASS 0xEF + #define DEVICE_SUBCLASS 0x02 + #define DEVICE_PROTOCOL 0x01 + #define MANUFACTURER_NAME {'T','e','e','n','s','y','d','u','i','n','o'} + #define MANUFACTURER_NAME_LEN 11 + #define PRODUCT_NAME {'S','e','r','i','a','l','/','K','e','y','b','o','a','r','d','/','M','o','u','s','e','/','J','o','y','s','t','i','c','k'} + #define PRODUCT_NAME_LEN 30 + #define EP0_SIZE 64 + #define NUM_ENDPOINTS 6 + #define NUM_USB_BUFFERS 30 + #define NUM_INTERFACE 5 + #define CDC_IAD_DESCRIPTOR 1 + #define CDC_STATUS_INTERFACE 0 + #define CDC_DATA_INTERFACE 1 // Serial + #define CDC_ACM_ENDPOINT 2 + #define CDC_RX_ENDPOINT 3 + #define CDC_TX_ENDPOINT 4 + #define CDC_ACM_SIZE 16 + #define CDC_RX_SIZE 64 + #define CDC_TX_SIZE 64 + #define KEYBOARD_INTERFACE 2 // Keyboard + #define KEYBOARD_ENDPOINT 1 + #define KEYBOARD_SIZE 8 + #define KEYBOARD_INTERVAL 1 + #define MOUSE_INTERFACE 3 // Mouse + #define MOUSE_ENDPOINT 5 + #define MOUSE_SIZE 8 + #define MOUSE_INTERVAL 2 + #define JOYSTICK_INTERFACE 4 // Joystick + #define JOYSTICK_ENDPOINT 6 + #define JOYSTICK_SIZE 16 + #define JOYSTICK_INTERVAL 1 + #define KEYBOARD_DESC_OFFSET (9+8 + 9+5+5+4+5+7+9+7+7 + 9) + #define MOUSE_DESC_OFFSET (9+8 + 9+5+5+4+5+7+9+7+7 + 9+9+7 + 9) + #define JOYSTICK_DESC_OFFSET (9+8 + 9+5+5+4+5+7+9+7+7 + 9+9+7 + 9+9+7 + 9) + #define CONFIG_DESC_SIZE (9+8 + 9+5+5+4+5+7+9+7+7 + 9+9+7 + 9+9+7 + 9+9+7) + #define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY + #define ENDPOINT2_CONFIG ENDPOINT_TRANSIMIT_ONLY + #define ENDPOINT3_CONFIG ENDPOINT_RECEIVE_ONLY + #define ENDPOINT4_CONFIG ENDPOINT_TRANSIMIT_ONLY + #define ENDPOINT5_CONFIG ENDPOINT_TRANSIMIT_ONLY + #define ENDPOINT6_CONFIG ENDPOINT_TRANSIMIT_ONLY + +#elif defined(USB_MIDI) + #define VENDOR_ID 0x16C0 + #define PRODUCT_ID 0x0485 + #define MANUFACTURER_NAME {'T','e','e','n','s','y','d','u','i','n','o'} + #define MANUFACTURER_NAME_LEN 11 + #define PRODUCT_NAME {'T','e','e','n','s','y',' ','M','I','D','I'} + #define PRODUCT_NAME_LEN 11 + #define EP0_SIZE 64 + #define NUM_ENDPOINTS 4 + #define NUM_USB_BUFFERS 16 + #define NUM_INTERFACE 2 + #define SEREMU_INTERFACE 1 // Serial emulation + #define SEREMU_TX_ENDPOINT 1 + #define SEREMU_TX_SIZE 64 + #define SEREMU_TX_INTERVAL 1 + #define SEREMU_RX_ENDPOINT 2 + #define SEREMU_RX_SIZE 32 + #define SEREMU_RX_INTERVAL 2 + #define MIDI_INTERFACE 0 // MIDI + #define MIDI_TX_ENDPOINT 3 + #define MIDI_TX_SIZE 64 + #define MIDI_RX_ENDPOINT 4 + #define MIDI_RX_SIZE 64 + #define SEREMU_DESC_OFFSET (9 + 9+7+6+6+9+9+9+5+9+5 + 9) + #define CONFIG_DESC_SIZE (9 + 9+7+6+6+9+9+9+5+9+5 + 9+9+7+7) + #define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY + #define ENDPOINT2_CONFIG ENDPOINT_RECEIVE_ONLY + #define ENDPOINT3_CONFIG ENDPOINT_TRANSIMIT_ONLY + #define ENDPOINT4_CONFIG ENDPOINT_RECEIVE_ONLY + +#elif defined(USB_RAWHID) + #define VENDOR_ID 0x16C0 + #define PRODUCT_ID 0x0486 + #define RAWHID_USAGE_PAGE 0xFFAB // recommended: 0xFF00 to 0xFFFF + #define RAWHID_USAGE 0x0200 // recommended: 0x0100 to 0xFFFF + #define MANUFACTURER_NAME {'T','e','e','n','s','y','d','u','i','n','o'} + #define MANUFACTURER_NAME_LEN 11 + #define PRODUCT_NAME {'T','e','e','n','s','y','d','u','i','n','o',' ','R','a','w','H','I','D'} + #define PRODUCT_NAME_LEN 18 + #define EP0_SIZE 64 + #define NUM_ENDPOINTS 6 + #define NUM_USB_BUFFERS 12 + #define NUM_INTERFACE 2 + #define RAWHID_INTERFACE 0 // RawHID + #define RAWHID_TX_ENDPOINT 3 + #define RAWHID_TX_SIZE 64 + #define RAWHID_TX_INTERVAL 1 + #define RAWHID_RX_ENDPOINT 4 + #define RAWHID_RX_SIZE 64 + #define RAWHID_RX_INTERVAL 1 + #define SEREMU_INTERFACE 1 // Serial emulation + #define SEREMU_TX_ENDPOINT 1 + #define SEREMU_TX_SIZE 64 + #define SEREMU_TX_INTERVAL 1 + #define SEREMU_RX_ENDPOINT 2 + #define SEREMU_RX_SIZE 32 + #define SEREMU_RX_INTERVAL 2 + #define RAWHID_DESC_OFFSET (9 + 9) + #define SEREMU_DESC_OFFSET (9 + 9+9+7+7 + 9) + #define CONFIG_DESC_SIZE (9 + 9+9+7+7 + 9+9+7+7) + #define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY + #define ENDPOINT2_CONFIG ENDPOINT_RECEIVE_ONLY + #define ENDPOINT3_CONFIG ENDPOINT_TRANSIMIT_ONLY + #define ENDPOINT4_CONFIG ENDPOINT_RECEIVE_ONLY + +#elif defined(USB_FLIGHTSIM) + #define VENDOR_ID 0x16C0 + #define PRODUCT_ID 0x0488 + #define MANUFACTURER_NAME {'T','e','e','n','s','y','d','u','i','n','o'} + #define MANUFACTURER_NAME_LEN 11 + #define PRODUCT_NAME {'T','e','e','n','s','y',' ','F','l','i','g','h','t',' ','S','i','m',' ','C','o','n','t','r','o','l','s'} + #define PRODUCT_NAME_LEN 26 + #define EP0_SIZE 64 + #define NUM_ENDPOINTS 4 + #define NUM_USB_BUFFERS 20 + #define NUM_INTERFACE 2 + #define FLIGHTSIM_INTERFACE 0 // Flight Sim Control + #define FLIGHTSIM_TX_ENDPOINT 3 + #define FLIGHTSIM_TX_SIZE 64 + #define FLIGHTSIM_TX_INTERVAL 1 + #define FLIGHTSIM_RX_ENDPOINT 4 + #define FLIGHTSIM_RX_SIZE 64 + #define FLIGHTSIM_RX_INTERVAL 1 + #define SEREMU_INTERFACE 1 // Serial emulation + #define SEREMU_TX_ENDPOINT 1 + #define SEREMU_TX_SIZE 64 + #define SEREMU_TX_INTERVAL 1 + #define SEREMU_RX_ENDPOINT 2 + #define SEREMU_RX_SIZE 32 + #define SEREMU_RX_INTERVAL 2 + #define FLIGHTSIM_DESC_OFFSET (9 + 9) + #define SEREMU_DESC_OFFSET (9 + 9+9+7+7 + 9) + #define CONFIG_DESC_SIZE (9 + 9+9+7+7 + 9+9+7+7) + #define ENDPOINT1_CONFIG ENDPOINT_TRANSIMIT_ONLY + #define ENDPOINT2_CONFIG ENDPOINT_RECEIVE_ONLY + #define ENDPOINT3_CONFIG ENDPOINT_TRANSIMIT_ONLY + #define ENDPOINT4_CONFIG ENDPOINT_RECEIVE_ONLY + +#endif + +// NUM_ENDPOINTS = number of non-zero endpoints (0 to 15) +extern const uint8_t usb_endpoint_config_table[NUM_ENDPOINTS]; + +typedef struct { + uint16_t wValue; + uint16_t wIndex; + const uint8_t *addr; + uint16_t length; +} usb_descriptor_list_t; + +extern const usb_descriptor_list_t usb_descriptor_list[]; + + +#endif diff --git a/teensy3/usb_dev.c b/teensy3/usb_dev.c new file mode 100644 index 0000000000000000000000000000000000000000..af99e9136a98fa64f1863c4caa333a50238f3a26 --- /dev/null +++ b/teensy3/usb_dev.c @@ -0,0 +1,968 @@ +/* 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 "HardwareSerial.h" +#include "usb_dev.h" +#include "usb_mem.h" + +// buffer descriptor table + +typedef struct { + uint32_t desc; + void * addr; +} bdt_t; + +__attribute__ ((section(".usbdescriptortable"), used)) +static bdt_t table[(NUM_ENDPOINTS+1)*4]; + +static usb_packet_t *rx_first[NUM_ENDPOINTS]; +static usb_packet_t *rx_last[NUM_ENDPOINTS]; +static usb_packet_t *tx_first[NUM_ENDPOINTS]; +static usb_packet_t *tx_last[NUM_ENDPOINTS]; +uint16_t usb_rx_byte_count_data[NUM_ENDPOINTS]; + +static uint8_t tx_state[NUM_ENDPOINTS]; +#define TX_STATE_BOTH_FREE_EVEN_FIRST 0 +#define TX_STATE_BOTH_FREE_ODD_FIRST 1 +#define TX_STATE_EVEN_FREE 2 +#define TX_STATE_ODD_FREE 3 +#define TX_STATE_NONE_FREE_EVEN_FIRST 4 +#define TX_STATE_NONE_FREE_ODD_FIRST 5 + +#define BDT_OWN 0x80 +#define BDT_DATA1 0x40 +#define BDT_DATA0 0x00 +#define BDT_DTS 0x08 +#define BDT_STALL 0x04 +#define BDT_PID(n) (((n) >> 2) & 15) + +#define BDT_DESC(count, data) (BDT_OWN | BDT_DTS \ + | ((data) ? BDT_DATA1 : BDT_DATA0) \ + | ((count) << 16)) + +#define TX 1 +#define RX 0 +#define ODD 1 +#define EVEN 0 +#define DATA0 0 +#define DATA1 1 +#define index(endpoint, tx, odd) (((endpoint) << 2) | ((tx) << 1) | (odd)) +#define stat2bufferdescriptor(stat) (table + ((stat) >> 2)) + + +static union { + struct { + union { + struct { + uint8_t bmRequestType; + uint8_t bRequest; + }; + uint16_t wRequestAndType; + }; + uint16_t wValue; + uint16_t wIndex; + uint16_t wLength; + }; + struct { + uint32_t word1; + uint32_t word2; + }; +} setup; + + +#define GET_STATUS 0 +#define CLEAR_FEATURE 1 +#define SET_FEATURE 3 +#define SET_ADDRESS 5 +#define GET_DESCRIPTOR 6 +#define SET_DESCRIPTOR 7 +#define GET_CONFIGURATION 8 +#define SET_CONFIGURATION 9 +#define GET_INTERFACE 10 +#define SET_INTERFACE 11 +#define SYNCH_FRAME 12 + +// SETUP always uses a DATA0 PID for the data field of the SETUP transaction. +// transactions in the data phase start with DATA1 and toggle (figure 8-12, USB1.1) +// Status stage uses a DATA1 PID. + +static uint8_t ep0_rx0_buf[EP0_SIZE] __attribute__ ((aligned (4))); +static uint8_t ep0_rx1_buf[EP0_SIZE] __attribute__ ((aligned (4))); +static const uint8_t *ep0_tx_ptr = NULL; +static uint16_t ep0_tx_len; +static uint8_t ep0_tx_bdt_bank = 0; +static uint8_t ep0_tx_data_toggle = 0; +uint8_t usb_rx_memory_needed = 0; + +volatile uint8_t usb_configuration = 0; +volatile uint8_t usb_reboot_timer = 0; + + +static void endpoint0_stall(void) +{ + USB0_ENDPT0 = USB_ENDPT_EPSTALL | USB_ENDPT_EPRXEN | USB_ENDPT_EPTXEN | USB_ENDPT_EPHSHK; +} + + +static void endpoint0_transmit(const void *data, uint32_t len) +{ +#if 0 + serial_print("tx0:"); + serial_phex32((uint32_t)data); + serial_print(","); + serial_phex16(len); + serial_print(ep0_tx_bdt_bank ? ", odd" : ", even"); + serial_print(ep0_tx_data_toggle ? ", d1\n" : ", d0\n"); +#endif + table[index(0, TX, ep0_tx_bdt_bank)].addr = (void *)data; + table[index(0, TX, ep0_tx_bdt_bank)].desc = BDT_DESC(len, ep0_tx_data_toggle); + ep0_tx_data_toggle ^= 1; + ep0_tx_bdt_bank ^= 1; +} + +static uint8_t reply_buffer[8]; + +static void usb_setup(void) +{ + const uint8_t *data = NULL; + uint32_t datalen = 0; + const usb_descriptor_list_t *list; + uint32_t size; + volatile uint8_t *reg; + uint8_t epconf; + const uint8_t *cfg; + int i; + + switch (setup.wRequestAndType) { + case 0x0500: // SET_ADDRESS + break; + case 0x0900: // SET_CONFIGURATION + //serial_print("configure\n"); + usb_configuration = setup.wValue; + reg = &USB0_ENDPT1; + cfg = usb_endpoint_config_table; + // clear all BDT entries, free any allocated memory... + for (i=4; i <= NUM_ENDPOINTS*4; i++) { + if (table[i].desc & BDT_OWN) { + usb_free((usb_packet_t *)((uint8_t *)(table[i].addr) - 8)); + } + } + // free all queued packets + for (i=0; i < NUM_ENDPOINTS; i++) { + usb_packet_t *p, *n; + p = rx_first[i]; + while (p) { + n = p->next; + usb_free(p); + p = n; + } + rx_first[i] = NULL; + rx_last[i] = NULL; + p = tx_first[i]; + while (p) { + n = p->next; + usb_free(p); + p = n; + } + tx_first[i] = NULL; + tx_last[i] = NULL; + usb_rx_byte_count_data[i] = 0; + switch (tx_state[i]) { + case TX_STATE_EVEN_FREE: + case TX_STATE_NONE_FREE_EVEN_FIRST: + tx_state[i] = TX_STATE_BOTH_FREE_EVEN_FIRST; + break; + case TX_STATE_ODD_FREE: + case TX_STATE_NONE_FREE_ODD_FIRST: + tx_state[i] = TX_STATE_BOTH_FREE_ODD_FIRST; + break; + default: + break; + } + } + usb_rx_memory_needed = 0; + for (i=1; i <= NUM_ENDPOINTS; i++) { + epconf = *cfg++; + *reg = epconf; + reg += 4; + if (epconf & USB_ENDPT_EPRXEN) { + usb_packet_t *p; + p = usb_malloc(); + if (p) { + table[index(i, RX, EVEN)].addr = p->buf; + table[index(i, RX, EVEN)].desc = BDT_DESC(64, 0); + } else { + table[index(i, RX, EVEN)].desc = 0; + usb_rx_memory_needed++; + } + p = usb_malloc(); + if (p) { + table[index(i, RX, ODD)].addr = p->buf; + table[index(i, RX, ODD)].desc = BDT_DESC(64, 1); + } else { + table[index(i, RX, ODD)].desc = 0; + usb_rx_memory_needed++; + } + } + table[index(i, TX, EVEN)].desc = 0; + table[index(i, TX, ODD)].desc = 0; + } + break; + case 0x0880: // GET_CONFIGURATION + reply_buffer[0] = usb_configuration; + datalen = 1; + data = reply_buffer; + break; + case 0x0080: // GET_STATUS (device) + reply_buffer[0] = 0; + reply_buffer[1] = 0; + datalen = 2; + data = reply_buffer; + break; + case 0x0082: // GET_STATUS (endpoint) + if (setup.wIndex > NUM_ENDPOINTS) { + // TODO: do we need to handle IN vs OUT here? + endpoint0_stall(); + return; + } + reply_buffer[0] = 0; + reply_buffer[1] = 0; + if (*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4) & 0x02) reply_buffer[0] = 1; + data = reply_buffer; + datalen = 2; + break; + case 0x0102: // CLEAR_FEATURE (endpoint) + i = setup.wIndex & 0x7F; + if (i > NUM_ENDPOINTS || setup.wValue != 0) { + // TODO: do we need to handle IN vs OUT here? + endpoint0_stall(); + return; + } + (*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4)) &= ~0x02; + // TODO: do we need to clear the data toggle here? + break; + case 0x0302: // SET_FEATURE (endpoint) + i = setup.wIndex & 0x7F; + if (i > NUM_ENDPOINTS || setup.wValue != 0) { + // TODO: do we need to handle IN vs OUT here? + endpoint0_stall(); + return; + } + (*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4)) |= 0x02; + // TODO: do we need to clear the data toggle here? + break; + case 0x0680: // GET_DESCRIPTOR + case 0x0681: + //serial_print("desc:"); + //serial_phex16(setup.wValue); + //serial_print("\n"); + for (list = usb_descriptor_list; 1; list++) { + if (list->addr == NULL) break; + //if (setup.wValue == list->wValue && + //(setup.wIndex == list->wIndex) || ((setup.wValue >> 8) == 3)) { + if (setup.wValue == list->wValue && setup.wIndex == list->wIndex) { + data = list->addr; + if ((setup.wValue >> 8) == 3) { + // for string descriptors, use the descriptor's + // length field, allowing runtime configured + // length. + datalen = *(list->addr); + } else { + datalen = list->length; + } +#if 0 + serial_print("Desc found, "); + serial_phex32((uint32_t)data); + serial_print(","); + serial_phex16(datalen); + serial_print(","); + serial_phex(data[0]); + serial_phex(data[1]); + serial_phex(data[2]); + serial_phex(data[3]); + serial_phex(data[4]); + serial_phex(data[5]); + serial_print("\n"); +#endif + goto send; + } + } + //serial_print("desc: not found\n"); + endpoint0_stall(); + return; +#if defined(CDC_STATUS_INTERFACE) + case 0x2221: // CDC_SET_CONTROL_LINE_STATE + usb_cdc_line_rtsdtr = setup.wValue; + //serial_print("set control line state\n"); + break; + case 0x2021: // CDC_SET_LINE_CODING + //serial_print("set coding, waiting...\n"); + return; +#endif + +// TODO: this does not work... why? +#if defined(SEREMU_INTERFACE) || defined(KEYBOARD_INTERFACE) + case 0x0921: // HID SET_REPORT + //serial_print(":)\n"); + return; + case 0x0A21: // HID SET_IDLE + break; + // case 0xC940: +#endif + default: + endpoint0_stall(); + return; + } + send: + //serial_print("setup send "); + //serial_phex32(data); + //serial_print(","); + //serial_phex16(datalen); + //serial_print("\n"); + + if (datalen > setup.wLength) datalen = setup.wLength; + size = datalen; + if (size > EP0_SIZE) size = EP0_SIZE; + endpoint0_transmit(data, size); + data += size; + datalen -= size; + if (datalen == 0 && size < EP0_SIZE) return; + + size = datalen; + if (size > EP0_SIZE) size = EP0_SIZE; + endpoint0_transmit(data, size); + data += size; + datalen -= size; + if (datalen == 0 && size < EP0_SIZE) return; + + ep0_tx_ptr = data; + ep0_tx_len = datalen; +} + + + +//A bulk endpoint's toggle sequence is initialized to DATA0 when the endpoint +//experiences any configuration event (configuration events are explained in +//Sections 9.1.1.5 and 9.4.5). + +//Configuring a device or changing an alternate setting causes all of the status +//and configuration values associated with endpoints in the affected interfaces +//to be set to their default values. This includes setting the data toggle of +//any endpoint using data toggles to the value DATA0. + +//For endpoints using data toggle, regardless of whether an endpoint has the +//Halt feature set, a ClearFeature(ENDPOINT_HALT) request always results in the +//data toggle being reinitialized to DATA0. + + + +// #define stat2bufferdescriptor(stat) (table + ((stat) >> 2)) + +static void usb_control(uint32_t stat) +{ + bdt_t *b; + uint32_t pid, size; + uint8_t *buf; + const uint8_t *data; + + b = stat2bufferdescriptor(stat); + pid = BDT_PID(b->desc); + //count = b->desc >> 16; + buf = b->addr; + //serial_print("pid:"); + //serial_phex(pid); + //serial_print(", count:"); + //serial_phex(count); + //serial_print("\n"); + + switch (pid) { + case 0x0D: // Setup received from host + //serial_print("PID=Setup\n"); + //if (count != 8) ; // panic? + // grab the 8 byte setup info + setup.word1 = *(uint32_t *)(buf); + setup.word2 = *(uint32_t *)(buf + 4); + + // give the buffer back + b->desc = BDT_DESC(EP0_SIZE, DATA1); + //table[index(0, RX, EVEN)].desc = BDT_DESC(EP0_SIZE, 1); + //table[index(0, RX, ODD)].desc = BDT_DESC(EP0_SIZE, 1); + + // clear any leftover pending IN transactions + ep0_tx_ptr = NULL; + if (ep0_tx_data_toggle) { + } + //if (table[index(0, TX, EVEN)].desc & 0x80) { + //serial_print("leftover tx even\n"); + //} + //if (table[index(0, TX, ODD)].desc & 0x80) { + //serial_print("leftover tx odd\n"); + //} + table[index(0, TX, EVEN)].desc = 0; + table[index(0, TX, ODD)].desc = 0; + // first IN after Setup is always DATA1 + ep0_tx_data_toggle = 1; + +#if 0 + serial_print("bmRequestType:"); + serial_phex(setup.bmRequestType); + serial_print(", bRequest:"); + serial_phex(setup.bRequest); + serial_print(", wValue:"); + serial_phex16(setup.wValue); + serial_print(", wIndex:"); + serial_phex16(setup.wIndex); + serial_print(", len:"); + serial_phex16(setup.wLength); + serial_print("\n"); +#endif + // actually "do" the setup request + usb_setup(); + // unfreeze the USB, now that we're ready + USB0_CTL = USB_CTL_USBENSOFEN; // clear TXSUSPENDTOKENBUSY bit + break; + case 0x01: // OUT transaction received from host + case 0x02: + //serial_print("PID=OUT\n"); +#ifdef CDC_STATUS_INTERFACE + if (setup.wRequestAndType == 0x2021 /*CDC_SET_LINE_CODING*/) { + int i; + uint8_t *dst = (uint8_t *)usb_cdc_line_coding; + //serial_print("set line coding "); + for (i=0; i<7; i++) { + //serial_phex(*buf); + *dst++ = *buf++; + } + //serial_phex32(usb_cdc_line_coding[0]); + //serial_print("\n"); + if (usb_cdc_line_coding[0] == 134) usb_reboot_timer = 15; + endpoint0_transmit(NULL, 0); + } +#endif +#ifdef KEYBOARD_INTERFACE + if (setup.word1 == 0x02000921 && setup.word2 == ((1<<16)|KEYBOARD_INTERFACE)) { + keyboard_leds = buf[0]; + endpoint0_transmit(NULL, 0); + } +#endif +#ifdef SEREMU_INTERFACE + if (setup.word1 == 0x03000921 && setup.word2 == ((4<<16)|SEREMU_INTERFACE) + && buf[0] == 0xA9 && buf[1] == 0x45 && buf[2] == 0xC2 && buf[3] == 0x6B) { + usb_reboot_timer = 5; + endpoint0_transmit(NULL, 0); + } +#endif + // give the buffer back + b->desc = BDT_DESC(EP0_SIZE, DATA1); + break; + + case 0x09: // IN transaction completed to host + //serial_print("PID=IN:"); + //serial_phex(stat); + //serial_print("\n"); + + // send remaining data, if any... + data = ep0_tx_ptr; + if (data) { + size = ep0_tx_len; + if (size > EP0_SIZE) size = EP0_SIZE; + endpoint0_transmit(data, size); + data += size; + ep0_tx_len -= size; + ep0_tx_ptr = (ep0_tx_len > 0 || size == EP0_SIZE) ? data : NULL; + } + + if (setup.bRequest == 5 && setup.bmRequestType == 0) { + setup.bRequest = 0; + //serial_print("set address: "); + //serial_phex16(setup.wValue); + //serial_print("\n"); + USB0_ADDR = setup.wValue; + } + + break; + //default: + //serial_print("PID=unknown:"); + //serial_phex(pid); + //serial_print("\n"); + } + USB0_CTL = USB_CTL_USBENSOFEN; // clear TXSUSPENDTOKENBUSY bit +} + + + + + + +usb_packet_t *usb_rx(uint32_t endpoint) +{ + usb_packet_t *ret; + endpoint--; + if (endpoint >= NUM_ENDPOINTS) return NULL; + __disable_irq(); + ret = rx_first[endpoint]; + if (ret) rx_first[endpoint] = ret->next; + usb_rx_byte_count_data[endpoint] -= ret->len; + __enable_irq(); + //serial_print("rx, epidx="); + //serial_phex(endpoint); + //serial_print(", packet="); + //serial_phex32(ret); + //serial_print("\n"); + return ret; +} + +static uint32_t usb_queue_byte_count(const usb_packet_t *p) +{ + uint32_t count=0; + + __disable_irq(); + for ( ; p; p = p->next) { + count += p->len; + } + __enable_irq(); + return count; +} + +// TODO: make this an inline function... +/* +uint32_t usb_rx_byte_count(uint32_t endpoint) +{ + endpoint--; + if (endpoint >= NUM_ENDPOINTS) return 0; + return usb_rx_byte_count_data[endpoint]; + //return usb_queue_byte_count(rx_first[endpoint]); +} +*/ + +uint32_t usb_tx_byte_count(uint32_t endpoint) +{ + endpoint--; + if (endpoint >= NUM_ENDPOINTS) return 0; + return usb_queue_byte_count(tx_first[endpoint]); +} + +uint32_t usb_tx_packet_count(uint32_t endpoint) +{ + const usb_packet_t *p; + uint32_t count=0; + + endpoint--; + if (endpoint >= NUM_ENDPOINTS) return 0; + p = tx_first[endpoint]; + __disable_irq(); + for ( ; p; p = p->next) count++; + __enable_irq(); + return count; +} + + +// Called from usb_free, but only when usb_rx_memory_needed > 0, indicating +// receive endpoints are starving for memory. The intention is to give +// endpoints needing receive memory priority over the user's code, which is +// likely calling usb_malloc to obtain memory for transmitting. When the +// user is creating data very quickly, their consumption could starve reception +// without this prioritization. The packet buffer (input) is assigned to the +// first endpoint needing memory. +// +void usb_rx_memory(usb_packet_t *packet) +{ + unsigned int i; + const uint8_t *cfg; + + cfg = usb_endpoint_config_table; + //serial_print("rx_mem:"); + __disable_irq(); + for (i=1; i <= NUM_ENDPOINTS; i++) { + if (*cfg++ & USB_ENDPT_EPRXEN) { + if (table[index(i, RX, EVEN)].desc == 0) { + table[index(i, RX, EVEN)].addr = packet->buf; + table[index(i, RX, EVEN)].desc = BDT_DESC(64, 0); + usb_rx_memory_needed--; + __enable_irq(); + //serial_phex(i); + //serial_print(",even\n"); + return; + } + if (table[index(i, RX, ODD)].desc == 0) { + table[index(i, RX, ODD)].addr = packet->buf; + table[index(i, RX, ODD)].desc = BDT_DESC(64, 1); + usb_rx_memory_needed--; + __enable_irq(); + //serial_phex(i); + //serial_print(",odd\n"); + return; + } + } + } + __enable_irq(); + // we should never reach this point. If we get here, it means + // usb_rx_memory_needed was set greater than zero, but no memory + // was actually needed. + usb_rx_memory_needed = 0; + usb_free(packet); + return; +} + +//#define index(endpoint, tx, odd) (((endpoint) << 2) | ((tx) << 1) | (odd)) +//#define stat2bufferdescriptor(stat) (table + ((stat) >> 2)) + +void usb_tx(uint32_t endpoint, usb_packet_t *packet) +{ + bdt_t *b = &table[index(endpoint, TX, EVEN)]; + uint8_t next; + + endpoint--; + if (endpoint >= NUM_ENDPOINTS) return; + __disable_irq(); + //serial_print("txstate="); + //serial_phex(tx_state[endpoint]); + //serial_print("\n"); + switch (tx_state[endpoint]) { + case TX_STATE_BOTH_FREE_EVEN_FIRST: + next = TX_STATE_ODD_FREE; + break; + case TX_STATE_BOTH_FREE_ODD_FIRST: + b++; + next = TX_STATE_EVEN_FREE; + break; + case TX_STATE_EVEN_FREE: + next = TX_STATE_NONE_FREE_ODD_FIRST; + break; + case TX_STATE_ODD_FREE: + b++; + next = TX_STATE_NONE_FREE_EVEN_FIRST; + break; + default: + if (tx_first[endpoint] == NULL) { + tx_first[endpoint] = packet; + } else { + tx_last[endpoint]->next = packet; + } + tx_last[endpoint] = packet; + __enable_irq(); + return; + } + tx_state[endpoint] = next; + b->addr = packet->buf; + b->desc = BDT_DESC(packet->len, ((uint32_t)b & 8) ? DATA1 : DATA0); + __enable_irq(); +} + + + + + + +void _reboot_Teensyduino_(void) +{ + // TODO: initialize R0 with a code.... + asm volatile("bkpt"); +} + + + +void usb_isr(void) +{ + uint8_t status, stat, t; + + //serial_print("isr"); + //status = USB0_ISTAT; + //serial_phex(status); + //serial_print("\n"); + restart: + status = USB0_ISTAT; + + if ((status & USB_INTEN_SOFTOKEN /* 04 */ )) { + if (usb_configuration) { + t = usb_reboot_timer; + if (t) { + usb_reboot_timer = --t; + if (!t) _reboot_Teensyduino_(); + } +#ifdef CDC_DATA_INTERFACE + t = usb_cdc_transmit_flush_timer; + if (t) { + usb_cdc_transmit_flush_timer = --t; + if (t == 0) usb_serial_flush_callback(); + } +#endif +#ifdef SEREMU_INTERFACE + t = usb_seremu_transmit_flush_timer; + if (t) { + usb_seremu_transmit_flush_timer = --t; + if (t == 0) usb_seremu_flush_callback(); + } +#endif +#ifdef MIDI_INTERFACE + usb_midi_flush_output(); +#endif +#ifdef FLIGHTSIM_INTERFACE + usb_flightsim_flush_callback(); +#endif + } + USB0_ISTAT = USB_INTEN_SOFTOKEN; + } + + if ((status & USB_ISTAT_TOKDNE /* 08 */ )) { + uint8_t endpoint; + stat = USB0_STAT; + //serial_print("token: ep="); + //serial_phex(stat >> 4); + //serial_print(stat & 0x08 ? ",tx" : ",rx"); + //serial_print(stat & 0x04 ? ",odd\n" : ",even\n"); + endpoint = stat >> 4; + if (endpoint == 0) { + usb_control(stat); + } else { + bdt_t *b = stat2bufferdescriptor(stat); + usb_packet_t *packet = (usb_packet_t *)((uint8_t *)(b->addr) - 8); +#if 0 + serial_print("ep:"); + serial_phex(endpoint); + serial_print(", pid:"); + serial_phex(BDT_PID(b->desc)); + serial_print(((uint32_t)b & 8) ? ", odd" : ", even"); + serial_print(", count:"); + serial_phex(b->desc >> 16); + serial_print("\n"); +#endif + endpoint--; // endpoint is index to zero-based arrays + + if (stat & 0x08) { // transmit + usb_free(packet); + packet = tx_first[endpoint]; + if (packet) { + //serial_print("tx packet\n"); + tx_first[endpoint] = packet->next; + b->addr = packet->buf; + switch (tx_state[endpoint]) { + case TX_STATE_BOTH_FREE_EVEN_FIRST: + tx_state[endpoint] = TX_STATE_ODD_FREE; + break; + case TX_STATE_BOTH_FREE_ODD_FIRST: + tx_state[endpoint] = TX_STATE_EVEN_FREE; + break; + case TX_STATE_EVEN_FREE: + tx_state[endpoint] = TX_STATE_NONE_FREE_ODD_FIRST; + break; + case TX_STATE_ODD_FREE: + tx_state[endpoint] = TX_STATE_NONE_FREE_EVEN_FIRST; + break; + default: + break; + } + b->desc = BDT_DESC(packet->len, ((uint32_t)b & 8) ? DATA1 : DATA0); + } else { + //serial_print("tx no packet\n"); + switch (tx_state[endpoint]) { + case TX_STATE_BOTH_FREE_EVEN_FIRST: + case TX_STATE_BOTH_FREE_ODD_FIRST: + break; + case TX_STATE_EVEN_FREE: + tx_state[endpoint] = TX_STATE_BOTH_FREE_EVEN_FIRST; + break; + case TX_STATE_ODD_FREE: + tx_state[endpoint] = TX_STATE_BOTH_FREE_ODD_FIRST; + break; + default: + tx_state[endpoint] = ((uint32_t)b & 8) ? + TX_STATE_ODD_FREE : TX_STATE_EVEN_FREE; + break; + } + } + } else { // receive + packet->len = b->desc >> 16; + if (packet->len > 0) { + packet->index = 0; + packet->next = NULL; + if (rx_first[endpoint] == NULL) { + //serial_print("rx 1st, epidx="); + //serial_phex(endpoint); + //serial_print(", packet="); + //serial_phex32((uint32_t)packet); + //serial_print("\n"); + rx_first[endpoint] = packet; + } else { + //serial_print("rx Nth, epidx="); + //serial_phex(endpoint); + //serial_print(", packet="); + //serial_phex32((uint32_t)packet); + //serial_print("\n"); + rx_last[endpoint]->next = packet; + } + rx_last[endpoint] = packet; + usb_rx_byte_count_data[endpoint] += packet->len; + // TODO: implement a per-endpoint maximum # of allocated packets + // so a flood of incoming data on 1 endpoint doesn't starve + // the others if the user isn't reading it regularly + packet = usb_malloc(); + if (packet) { + b->addr = packet->buf; + b->desc = BDT_DESC(64, ((uint32_t)b & 8) ? DATA1 : DATA0); + } else { + //serial_print("starving "); + //serial_phex(endpoint + 1); + //serial_print(((uint32_t)b & 8) ? ",odd\n" : ",even\n"); + b->desc = 0; + usb_rx_memory_needed++; + } + } else { + b->desc = BDT_DESC(64, ((uint32_t)b & 8) ? DATA1 : DATA0); + } + } + + + + + } + USB0_ISTAT = USB_ISTAT_TOKDNE; + goto restart; + } + + + + if (status & USB_ISTAT_USBRST /* 01 */ ) { + //serial_print("reset\n"); + + // initialize BDT toggle bits + USB0_CTL = USB_CTL_ODDRST; + ep0_tx_bdt_bank = 0; + + // set up buffers to receive Setup and OUT packets + table[index(0, RX, EVEN)].desc = BDT_DESC(EP0_SIZE, 0); + table[index(0, RX, EVEN)].addr = ep0_rx0_buf; + table[index(0, RX, ODD)].desc = BDT_DESC(EP0_SIZE, 0); + table[index(0, RX, ODD)].addr = ep0_rx1_buf; + table[index(0, TX, EVEN)].desc = 0; + table[index(0, TX, ODD)].desc = 0; + + // activate endpoint 0 + USB0_ENDPT0 = USB_ENDPT_EPRXEN | USB_ENDPT_EPTXEN | USB_ENDPT_EPHSHK; + + // clear all ending interrupts + USB0_ERRSTAT = 0xFF; + USB0_ISTAT = 0xFF; + + // set the address to zero during enumeration + USB0_ADDR = 0; + + // enable other interrupts + USB0_ERREN = 0xFF; + USB0_INTEN = USB_INTEN_TOKDNEEN | + USB_INTEN_SOFTOKEN | + USB_INTEN_STALLEN | + USB_INTEN_ERROREN | + USB_INTEN_USBRSTEN | + USB_INTEN_SLEEPEN; + + // is this necessary? + USB0_CTL = USB_CTL_USBENSOFEN; + return; + } + + + if ((status & USB_ISTAT_STALL /* 80 */ )) { + //serial_print("stall:\n"); + USB0_ENDPT0 = USB_ENDPT_EPRXEN | USB_ENDPT_EPTXEN | USB_ENDPT_EPHSHK; + USB0_ISTAT = USB_ISTAT_STALL; + } + if ((status & USB_ISTAT_ERROR /* 02 */ )) { + uint8_t err = USB0_ERRSTAT; + USB0_ERRSTAT = err; + //serial_print("err:"); + //serial_phex(err); + //serial_print("\n"); + USB0_ISTAT = USB_ISTAT_ERROR; + } + + if ((status & USB_ISTAT_SLEEP /* 10 */ )) { + //serial_print("sleep\n"); + USB0_ISTAT = USB_ISTAT_SLEEP; + } + +} + + + +void usb_init(void) +{ + int i; + + //serial_begin(BAUD2DIV(115200)); + //serial_print("usb_init\n"); + + usb_init_serialnumber(); + + for (i=0; i <= NUM_ENDPOINTS*4; i++) { + table[i].desc = 0; + table[i].addr = 0; + } + + // this basically follows the flowchart in the Kinetis + // Quick Reference User Guide, Rev. 1, 03/2012, page 141 + + // assume 48 MHz clock already running + // SIM - enable clock + SIM_SCGC4 |= SIM_SCGC4_USBOTG; + + // reset USB module + USB0_USBTRC0 = USB_USBTRC_USBRESET; + while ((USB0_USBTRC0 & USB_USBTRC_USBRESET) != 0) ; // wait for reset to end + + // set desc table base addr + USB0_BDTPAGE1 = ((uint32_t)table) >> 8; + USB0_BDTPAGE2 = ((uint32_t)table) >> 16; + USB0_BDTPAGE3 = ((uint32_t)table) >> 24; + + // clear all ISR flags + USB0_ISTAT = 0xFF; + USB0_ERRSTAT = 0xFF; + USB0_OTGISTAT = 0xFF; + + USB0_USBTRC0 |= 0x40; // undocumented bit + + // enable USB + USB0_CTL = USB_CTL_USBENSOFEN; + USB0_USBCTRL = 0; + + // enable reset interrupt + USB0_INTEN = USB_INTEN_USBRSTEN; + + // enable interrupt in NVIC... + NVIC_ENABLE_IRQ(IRQ_USBOTG); + + // enable d+ pullup + USB0_CONTROL = USB_CONTROL_DPPULLUPNONOTG; +} + + + diff --git a/teensy3/usb_dev.h b/teensy3/usb_dev.h new file mode 100644 index 0000000000000000000000000000000000000000..eca9775524c9e84d1a821f01d8f463f5a44ffa05 --- /dev/null +++ b/teensy3/usb_dev.h @@ -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 _usb_dev_h_ +#define _usb_dev_h_ + +// This header is NOT meant to be included when compiling +// user sketches in Arduino. The low-level functions +// provided by usb_dev.c are meant to be called only by +// code which provides higher-level interfaces to the user. + +#include "usb_mem.h" +#include "usb_desc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void usb_init(void); +void usb_init_serialnumber(void); +void usb_isr(void); +usb_packet_t *usb_rx(uint32_t endpoint); +uint32_t usb_tx_byte_count(uint32_t endpoint); +uint32_t usb_tx_packet_count(uint32_t endpoint); +void usb_tx(uint32_t endpoint, usb_packet_t *packet); +void usb_tx_isr(uint32_t endpoint, usb_packet_t *packet); + +extern volatile uint8_t usb_configuration; + +extern uint16_t usb_rx_byte_count_data[NUM_ENDPOINTS]; +static inline uint32_t usb_rx_byte_count(uint32_t endpoint) __attribute__((always_inline)); +static inline uint32_t usb_rx_byte_count(uint32_t endpoint) +{ + endpoint--; + if (endpoint >= NUM_ENDPOINTS) return 0; + return usb_rx_byte_count_data[endpoint]; +} + +#ifdef CDC_DATA_INTERFACE +extern uint32_t usb_cdc_line_coding[2]; +extern volatile uint8_t usb_cdc_line_rtsdtr; +extern volatile uint8_t usb_cdc_transmit_flush_timer; +extern void usb_serial_flush_callback(void); +#endif + +#ifdef SEREMU_INTERFACE +extern volatile uint8_t usb_seremu_transmit_flush_timer; +extern void usb_seremu_flush_callback(void); +#endif + +#ifdef KEYBOARD_INTERFACE +extern uint8_t keyboard_modifier_keys; +extern uint8_t keyboard_keys[6]; +extern uint8_t keyboard_protocol; +extern uint8_t keyboard_idle_config; +extern uint8_t keyboard_idle_count; +extern volatile uint8_t keyboard_leds; +#endif + +#ifdef MIDI_INTERFACE +extern void usb_midi_flush_output(void); +#endif + +#ifdef FLIGHTSIM_INTERFACE +extern void usb_flightsim_flush_callback(void); +#endif + + + + + +#ifdef __cplusplus +} +#endif + + + +#endif diff --git a/teensy3/usb_flightsim.cpp b/teensy3/usb_flightsim.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b02fc9e496c6c1ab4ee371cafa612e17d4f1f34d --- /dev/null +++ b/teensy3/usb_flightsim.cpp @@ -0,0 +1,367 @@ +/* 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 "usb_dev.h" +#include "usb_flightsim.h" +#include "core_pins.h" // for yield(), millis() +#include <string.h> // for memcpy() + +#ifdef FLIGHTSIM_INTERFACE // defined by usb_dev.h -> usb_desc.h + +FlightSimCommand * FlightSimCommand::first = NULL; +FlightSimCommand * FlightSimCommand::last = NULL; +FlightSimInteger * FlightSimInteger::first = NULL; +FlightSimInteger * FlightSimInteger::last = NULL; +FlightSimFloat * FlightSimFloat::first = NULL; +FlightSimFloat * FlightSimFloat::last = NULL; + +uint8_t FlightSimClass::enabled = 0; +uint8_t FlightSimClass::request_id_messages = 0; +unsigned long FlightSimClass::frameCount = 0; +elapsedMillis FlightSimClass::enableTimeout; + +static unsigned int unassigned_id = 1; // TODO: move into FlightSimClass + + +FlightSimCommand::FlightSimCommand() +{ + id = unassigned_id++; + if (!first) { + first = this; + } else { + last->next = this; + } + last = this; + name = NULL; + next = NULL; + FlightSimClass::request_id_messages = 1; +} + +void FlightSimCommand::identify(void) +{ + uint8_t len, buf[6]; + + if (!FlightSim.enabled || !name) return; + len = strlen((const char *)name); + buf[0] = len + 6; + buf[1] = 1; + buf[2] = id; + buf[3] = id >> 8; + buf[4] = 0; + buf[5] = 0; + FlightSimClass::xmit(buf, 6, name, len); +} + +void FlightSimCommand::sendcmd(uint8_t n) +{ + uint8_t buf[4]; + + if (!FlightSim.enabled || !name) return; + buf[0] = 4; + buf[1] = n; + buf[2] = id; + buf[3] = id >> 8; + FlightSimClass::xmit(buf, 4, NULL, 0); +} + + +FlightSimInteger::FlightSimInteger() +{ + id = unassigned_id++; + if (!first) { + first = this; + } else { + last->next = this; + } + last = this; + name = NULL; + next = NULL; + value = 0; + change_callback = NULL; + FlightSimClass::request_id_messages = 1; +} + +void FlightSimInteger::identify(void) +{ + uint8_t len, buf[6]; + + if (!FlightSim.enabled || !name) return; + len = strlen((const char *)name); + buf[0] = len + 6; + buf[1] = 1; + buf[2] = id; + buf[3] = id >> 8; + buf[4] = 1; + buf[5] = 0; + FlightSimClass::xmit(buf, 6, name, len); +} + +void FlightSimInteger::write(long val) +{ + uint8_t buf[6]; + + value = val; + if (!FlightSim.enabled || !name) return; // TODO: mark as dirty + buf[0] = 10; + buf[1] = 2; + buf[2] = id; + buf[3] = id >> 8; + buf[4] = 1; + buf[5] = 0; + FlightSimClass::xmit(buf, 6, (uint8_t *)&value, 4); +} + +void FlightSimInteger::update(long val) +{ + value = val; + if (change_callback) (*change_callback)(val); +} + +FlightSimInteger * FlightSimInteger::find(unsigned int n) +{ + for (FlightSimInteger *p = first; p; p = p->next) { + if (p->id == n) return p; + } + return NULL; +} + + + + +FlightSimFloat::FlightSimFloat() +{ + id = unassigned_id++; + if (!first) { + first = this; + } else { + last->next = this; + } + last = this; + name = NULL; + next = NULL; + value = 0; + change_callback = NULL; + FlightSimClass::request_id_messages = 1; +} + +void FlightSimFloat::identify(void) +{ + uint8_t len, buf[6]; + + if (!FlightSim.enabled || !name) return; + len = strlen((const char *)name); + buf[0] = len + 6; + buf[1] = 1; + buf[2] = id; + buf[3] = id >> 8; + buf[4] = 2; + buf[5] = 0; + FlightSimClass::xmit(buf, 6, name, len); +} + +void FlightSimFloat::write(float val) +{ + uint8_t buf[6]; + + value = val; + if (!FlightSim.enabled || !name) return; // TODO: mark as dirty + buf[0] = 10; + buf[1] = 2; + buf[2] = id; + buf[3] = id >> 8; + buf[4] = 2; + buf[5] = 0; + FlightSimClass::xmit(buf, 6, (uint8_t *)&value, 4); +} + +void FlightSimFloat::update(float val) +{ + value = val; + if (change_callback) (*change_callback)(val); +} + +FlightSimFloat * FlightSimFloat::find(unsigned int n) +{ + for (FlightSimFloat *p = first; p; p = p->next) { + if (p->id == n) return p; + } + return NULL; +} + + + + + + +FlightSimClass::FlightSimClass() +{ +} + +void FlightSimClass::update(void) +{ + uint8_t len, maxlen, type, *p, *end; + usb_packet_t *rx_packet; + uint16_t id; + + while (1) { + if (!usb_configuration) break; + rx_packet = usb_rx(FLIGHTSIM_RX_ENDPOINT); + if (!rx_packet) break; + p = rx_packet->buf; + end = p + 64; + maxlen = 64; + do { + len = p[0]; + if (len < 2 || len > maxlen) break; + switch (p[1]) { + case 0x02: // write data + if (len < 10) break; + id = p[2] | (p[3] << 8); + type = p[4]; + if (type == 1) { + FlightSimInteger *item = FlightSimInteger::find(id); + if (!item) break; + item->update(*(long *)(p + 6)); + } else if (type == 2) { + FlightSimFloat *item = FlightSimFloat::find(id); + if (!item) break; + item->update(*(float *)(p + 6)); + } + break; + case 0x03: // enable/disable + if (len < 4) break; + switch (p[2]) { + case 1: + request_id_messages = 1; + case 2: + enable(); + frameCount++; + break; + case 3: + disable(); + } + } + p += len; + maxlen -= len; + } while (p < end); + usb_free(rx_packet); + } + if (enabled && request_id_messages) { + request_id_messages = 0; + for (FlightSimCommand *p = FlightSimCommand::first; p; p = p->next) { + p->identify(); + } + for (FlightSimInteger *p = FlightSimInteger::first; p; p = p->next) { + p->identify(); + // TODO: send any dirty data + } + for (FlightSimFloat *p = FlightSimFloat::first; p; p = p->next) { + p->identify(); + // TODO: send any dirty data + } + } +} + + +bool FlightSimClass::isEnabled(void) +{ + if (!usb_configuration) return false; + if (!enabled) return false; + if (enableTimeout > 1500) return false; + return true; +} + + +// Maximum number of transmit packets to queue so we don't starve other endpoints for memory +#define TX_PACKET_LIMIT 8 + +static usb_packet_t *tx_packet=NULL; +static volatile uint8_t tx_noautoflush=0; + +void FlightSimClass::xmit(const void *p1, uint8_t n1, const void *p2, uint8_t n2) +{ + uint8_t total; + + total = n1 + n2; + if (total > FLIGHTSIM_TX_SIZE) return; + if (!enabled || !usb_configuration) return; + tx_noautoflush = 1; + if (tx_packet) { + if (total <= FLIGHTSIM_TX_SIZE - tx_packet->index) goto send; + for (int i = tx_packet->index; i < FLIGHTSIM_TX_SIZE; i++) { + tx_packet->buf[i] = 0; + } + tx_packet->len = FLIGHTSIM_TX_SIZE; + usb_tx(FLIGHTSIM_TX_ENDPOINT, tx_packet); + tx_packet = NULL; + } + while (1) { + if (usb_tx_packet_count(FLIGHTSIM_TX_ENDPOINT) < TX_PACKET_LIMIT) { + tx_packet = usb_malloc(); + if (tx_packet) break; + } + if (!enabled || !usb_configuration) { + tx_noautoflush = 0; + return; + } + tx_noautoflush = 0; + yield(); + tx_noautoflush = 1; + } +send: + memcpy(tx_packet->buf + tx_packet->index, p1, n1); + tx_packet->index += n1; + if (n2 > 0) { + memcpy(tx_packet->buf + tx_packet->index, p2, n2); + tx_packet->index += n2; + } + if (tx_packet->index >= FLIGHTSIM_TX_SIZE) { + tx_packet->len = FLIGHTSIM_TX_SIZE; + usb_tx(FLIGHTSIM_TX_ENDPOINT, tx_packet); + tx_packet = NULL; + } + tx_noautoflush = 0; +} + + +extern "C" { +void usb_flightsim_flush_callback(void) +{ + if (tx_noautoflush || !tx_packet || tx_packet->index == 0) return; + for (int i=tx_packet->index; i < FLIGHTSIM_TX_ENDPOINT; i++) { + tx_packet->buf[i] = 0; + } + tx_packet->len = FLIGHTSIM_TX_SIZE; + usb_tx(FLIGHTSIM_TX_ENDPOINT, tx_packet); + tx_packet = NULL; +} +} + +#endif // FLIGHTSIM_INTERFACE diff --git a/teensy3/usb_flightsim.h b/teensy3/usb_flightsim.h new file mode 100644 index 0000000000000000000000000000000000000000..8ac115f26170cf0f76ef6ccc6ad637c4745c776f --- /dev/null +++ b/teensy3/usb_flightsim.h @@ -0,0 +1,185 @@ +/* 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 USBflightsim_h_ +#define USBflightsim_h_ + +#if defined(USB_FLIGHTSIM) && defined(__cplusplus) + +#include <inttypes.h> +#include "elapsedMillis.h" + +class FlightSimClass; +class FlightSimCommand; +class FlightSimInteger; + +class _XpRefStr_; +#define XPlaneRef(str) ((const _XpRefStr_ *)(str)) + +class FlightSimClass +{ +public: + FlightSimClass(); + static void update(void); + static bool isEnabled(void); + static unsigned long getFrameCount(void) { return frameCount; } +private: + static uint8_t request_id_messages; + static uint8_t enabled; + static elapsedMillis enableTimeout; + static unsigned long frameCount; + static void enable(void) { enabled = 1; enableTimeout = 0; } + static void disable(void) { enabled = 0; } + static void xmit(const void *p1, uint8_t n1, const void *p2, uint8_t n2); + friend class FlightSimCommand; + friend class FlightSimInteger; + friend class FlightSimFloat; +}; + + +class FlightSimCommand +{ +public: + FlightSimCommand(); + void assign(const _XpRefStr_ *s) { name = s; if (FlightSimClass::enabled) identify(); } + FlightSimCommand & operator = (const _XpRefStr_ *s) { assign(s); return *this; } + void begin(void) { sendcmd(4); } + void end(void) { sendcmd(5); } + FlightSimCommand & operator = (int n) { sendcmd((n) ? 4 : 5); return *this; } + void once(void) { sendcmd(6); } + void identify(void); +private: + unsigned int id; + const _XpRefStr_ *name; + void sendcmd(uint8_t n); + FlightSimCommand *next; + static FlightSimCommand *first; + static FlightSimCommand *last; + friend class FlightSimClass; +}; + + +class FlightSimInteger +{ +public: + FlightSimInteger(); + void assign(const _XpRefStr_ *s) { name = s; if (FlightSimClass::enabled) identify(); } + FlightSimInteger & operator = (const _XpRefStr_ *s) { assign(s); return *this; } + void write(long val); + FlightSimInteger & operator = (char n) { write((long)n); return *this; } + FlightSimInteger & operator = (int n) { write((long)n); return *this; } + FlightSimInteger & operator = (long n) { write(n); return *this; } + FlightSimInteger & operator = (unsigned char n) { write((long)n); return *this; } + FlightSimInteger & operator = (unsigned int n) { write((long)n); return *this; } + FlightSimInteger & operator = (unsigned long n) { write((long)n); return *this; } + FlightSimInteger & operator = (float n) { write((long)n); return *this; } + FlightSimInteger & operator = (double n) { write((long)n); return *this; } + long read(void) const { return value; } + operator long () const { return value; } + void identify(void); + void update(long val); + static FlightSimInteger * find(unsigned int n); + void onChange(void (*fptr)(long)) { change_callback = fptr; } + // TODO: math operators.... + - * / % ++ -- +private: + unsigned int id; + const _XpRefStr_ *name; + long value; + void (*change_callback)(long); + FlightSimInteger *next; + static FlightSimInteger *first; + static FlightSimInteger *last; + friend class FlightSimClass; +}; + + +class FlightSimFloat +{ +public: + FlightSimFloat(); + void assign(const _XpRefStr_ *s) { name = s; if (FlightSimClass::enabled) identify(); } + FlightSimFloat & operator = (const _XpRefStr_ *s) { assign(s); return *this; } + void write(float val); + FlightSimFloat & operator = (char n) { write((float)n); return *this; } + FlightSimFloat & operator = (int n) { write((float)n); return *this; } + FlightSimFloat & operator = (long n) { write((float)n); return *this; } + FlightSimFloat & operator = (unsigned char n) { write((float)n); return *this; } + FlightSimFloat & operator = (unsigned int n) { write((float)n); return *this; } + FlightSimFloat & operator = (unsigned long n) { write((float)n); return *this; } + FlightSimFloat & operator = (float n) { write(n); return *this; } + FlightSimFloat & operator = (double n) { write((float)n); return *this; } + float read(void) const { return value; } + operator float () const { return value; } + void identify(void); + void update(float val); + static FlightSimFloat * find(unsigned int n); + void onChange(void (*fptr)(float)) { change_callback = fptr; } + // TODO: math operators.... + - * / % ++ -- +private: + unsigned int id; + const _XpRefStr_ *name; + float value; + void (*change_callback)(float); + FlightSimFloat *next; + static FlightSimFloat *first; + static FlightSimFloat *last; + friend class FlightSimClass; +}; + + +class FlightSimElapsedFrames +{ +private: + unsigned long count; +public: + FlightSimElapsedFrames(void) { count = FlightSimClass::getFrameCount(); } + FlightSimElapsedFrames(unsigned long val) { count = FlightSimClass::getFrameCount() - val; } + FlightSimElapsedFrames(const FlightSimElapsedFrames &orig) { count = orig.count; } + operator unsigned long () const { return FlightSimClass::getFrameCount() - count; } + FlightSimElapsedFrames & operator = (const FlightSimElapsedFrames &rhs) { count = rhs.count; return *this; } + FlightSimElapsedFrames & operator = (unsigned long val) { count = FlightSimClass::getFrameCount() - val; return *this; } + FlightSimElapsedFrames & operator -= (unsigned long val) { count += val; return *this; } + FlightSimElapsedFrames & operator += (unsigned long val) { count -= val; return *this; } + FlightSimElapsedFrames operator - (int val) const { FlightSimElapsedFrames r(*this); r.count += val; return r; } + FlightSimElapsedFrames operator - (unsigned int val) const { FlightSimElapsedFrames r(*this); r.count += val; return r; } + FlightSimElapsedFrames operator - (long val) const { FlightSimElapsedFrames r(*this); r.count += val; return r; } + FlightSimElapsedFrames operator - (unsigned long val) const { FlightSimElapsedFrames r(*this); r.count += val; return r; } + FlightSimElapsedFrames operator + (int val) const { FlightSimElapsedFrames r(*this); r.count -= val; return r; } + FlightSimElapsedFrames operator + (unsigned int val) const { FlightSimElapsedFrames r(*this); r.count -= val; return r; } + FlightSimElapsedFrames operator + (long val) const { FlightSimElapsedFrames r(*this); r.count -= val; return r; } + FlightSimElapsedFrames operator + (unsigned long val) const { FlightSimElapsedFrames r(*this); r.count -= val; return r; } +}; + + +extern FlightSimClass FlightSim; + + +#endif +#endif diff --git a/teensy3/usb_inst.cpp b/teensy3/usb_inst.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dc340eea0f337c13a303e20873e26d58c4c6238d --- /dev/null +++ b/teensy3/usb_inst.cpp @@ -0,0 +1,67 @@ +/* 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 "WProgram.h" + +#ifdef USB_SERIAL +usb_serial_class Serial; +#endif + +#ifdef USB_HID +usb_keyboard_class Keyboard; +usb_mouse_class Mouse; +usb_joystick_class Joystick; +uint8_t usb_joystick_class::manual_mode = 0; +usb_seremu_class Serial; +#endif + +#ifdef USB_SERIAL_HID +usb_serial_class Serial; +usb_keyboard_class Keyboard; +usb_mouse_class Mouse; +usb_joystick_class Joystick; +uint8_t usb_joystick_class::manual_mode = 0; +#endif + +#ifdef USB_MIDI +usb_midi_class usbMIDI; +usb_seremu_class Serial; +#endif + +#ifdef USB_RAWHID +usb_rawhid_class RawHID; +usb_seremu_class Serial; +#endif + +#ifdef USB_FLIGHTSIM +FlightSimClass FlightSim; +usb_seremu_class Serial; +#endif + diff --git a/teensy3/usb_joystick.c b/teensy3/usb_joystick.c new file mode 100644 index 0000000000000000000000000000000000000000..78818b20280d15c1cc5b4d904eedacc7bd8ef5e8 --- /dev/null +++ b/teensy3/usb_joystick.c @@ -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 "usb_dev.h" +#include "usb_joystick.h" +#include "core_pins.h" // for yield() +#include "HardwareSerial.h" +#include <string.h> // for memcpy() + +#ifdef JOYSTICK_INTERFACE // defined by usb_dev.h -> usb_desc.h + + +uint32_t usb_joystick_data[3]; + + +// Maximum number of transmit packets to queue so we don't starve other endpoints for memory +#define TX_PACKET_LIMIT 3 + +static uint8_t transmit_previous_timeout=0; + +// When the PC isn't listening, how long do we wait before discarding data? +#define TX_TIMEOUT_MSEC 30 + +#if F_CPU == 96000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 596) +#elif F_CPU == 48000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 428) +#elif F_CPU == 24000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 262) +#endif + + + + +int usb_joystick_send(void) +{ + uint32_t wait_count=0; + usb_packet_t *tx_packet; + + //serial_print("send"); + //serial_print("\n"); + while (1) { + if (!usb_configuration) { + //serial_print("error1\n"); + return -1; + } + if (usb_tx_packet_count(JOYSTICK_ENDPOINT) < TX_PACKET_LIMIT) { + tx_packet = usb_malloc(); + if (tx_packet) break; + } + if (++wait_count > TX_TIMEOUT || transmit_previous_timeout) { + transmit_previous_timeout = 1; + //serial_print("error2\n"); + return -1; + } + yield(); + } + transmit_previous_timeout = 0; + memcpy(tx_packet->buf, usb_joystick_data, 12); + tx_packet->len = 12; + usb_tx(JOYSTICK_ENDPOINT, tx_packet); + //serial_print("ok\n"); + return 0; +} + + + + +#endif // JOYSTICK_INTERFACE diff --git a/teensy3/usb_joystick.h b/teensy3/usb_joystick.h new file mode 100644 index 0000000000000000000000000000000000000000..12bb0d3f6e3a56e89796912965859137167649ca --- /dev/null +++ b/teensy3/usb_joystick.h @@ -0,0 +1,134 @@ +/* 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 USBjoystick_h_ +#define USBjoystick_h_ + +#if defined(USB_HID) || defined(USB_SERIAL_HID) + +#include <inttypes.h> + +// C language implementation +#ifdef __cplusplus +extern "C" { +#endif +int usb_joystick_send(void); +extern uint32_t usb_joystick_data[3]; +#ifdef __cplusplus +} +#endif + +// C++ interface +#ifdef __cplusplus +class usb_joystick_class +{ + public: + void begin(void) { } + void end(void) { } + void button(uint8_t button, bool val) { + if (--button >= 32) return; + if (val) usb_joystick_data[0] |= (1 << button); + else usb_joystick_data[0] &= ~(1 << button); + if (!manual_mode) usb_joystick_send(); + } + void X(unsigned int val) { + if (val > 1023) val = 1023; + usb_joystick_data[1] = (usb_joystick_data[1] & 0xFFFFC00F) | (val << 4); + if (!manual_mode) usb_joystick_send(); + } + void Y(unsigned int val) { + if (val > 1023) val = 1023; + usb_joystick_data[1] = (usb_joystick_data[1] & 0xFF003FFF) | (val << 14); + if (!manual_mode) usb_joystick_send(); + } + void position(unsigned int x, unsigned int y) { + if (x > 1023) x = 1023; + if (y > 1023) y = 1023; + usb_joystick_data[1] = (usb_joystick_data[1] & 0xFFF00000) + | (x << 4) | (y << 14); + if (!manual_mode) usb_joystick_send(); + } + void Z(unsigned int val) { + if (val > 1023) val = 1023; + usb_joystick_data[1] = (usb_joystick_data[1] & 0x00FFFFFF) | (val << 24); + usb_joystick_data[2] = (usb_joystick_data[2] & 0xFFFFFFFC) | (val >> 8); + if (!manual_mode) usb_joystick_send(); + } + void Zrotate(unsigned int val) { + if (val > 1023) val = 1023; + usb_joystick_data[2] = (usb_joystick_data[2] & 0xFFFFF003) | (val << 2); + if (!manual_mode) usb_joystick_send(); + } + void sliderLeft(unsigned int val) { + if (val > 1023) val = 1023; + usb_joystick_data[2] = (usb_joystick_data[2] & 0xFFC00FFF) | (val << 12); + if (!manual_mode) usb_joystick_send(); + } + void sliderRight(unsigned int val) { + if (val > 1023) val = 1023; + usb_joystick_data[2] = (usb_joystick_data[2] & 0x003FFFFF) | (val << 22); + if (!manual_mode) usb_joystick_send(); + } + void slider(unsigned int val) { + if (val > 1023) val = 1023; + usb_joystick_data[2] = (usb_joystick_data[2] & 0x00000FFF) + | (val << 12) | (val << 22); + if (!manual_mode) usb_joystick_send(); + } + inline void hat(int dir) { + uint32_t val; + if (dir < 0) val = 15; + else if (dir < 23) val = 0; + else if (dir < 68) val = 1; + else if (dir < 113) val = 2; + else if (dir < 158) val = 3; + else if (dir < 203) val = 4; + else if (dir < 245) val = 5; + else if (dir < 293) val = 6; + else if (dir < 338) val = 7; + usb_joystick_data[1] = (usb_joystick_data[1] & 0xFFFFFFF0) | val; + if (!manual_mode) usb_joystick_send(); + } + void useManualSend(bool mode) { + manual_mode = mode; + } + void send_now(void) { + usb_joystick_send(); + } + private: + static uint8_t manual_mode; +}; +extern usb_joystick_class Joystick; + +#endif // __cplusplus + +#endif // USB_HID || USB_SERIAL_HID +#endif // USBjoystick_h_ + diff --git a/teensy3/usb_keyboard.c b/teensy3/usb_keyboard.c new file mode 100644 index 0000000000000000000000000000000000000000..90913c121e0c0c3bc348ea407d78a82d79affe71 --- /dev/null +++ b/teensy3/usb_keyboard.c @@ -0,0 +1,480 @@ +/* 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 "usb_dev.h" +#include "usb_keyboard.h" +#include "core_pins.h" // for yield() +#include "keylayouts.h" +//#include "HardwareSerial.h" +#include <string.h> // for memcpy() + +#ifdef KEYBOARD_INTERFACE // defined by usb_dev.h -> usb_desc.h + + +// which modifier keys are currently pressed +// 1=left ctrl, 2=left shift, 4=left alt, 8=left gui +// 16=right ctrl, 32=right shift, 64=right alt, 128=right gui +uint8_t keyboard_modifier_keys=0; + +// which keys are currently pressed, up to 6 keys may be down at once +uint8_t keyboard_keys[6]={0,0,0,0,0,0}; + +// protocol setting from the host. We use exactly the same report +// either way, so this variable only stores the setting since we +// are required to be able to report which setting is in use. +uint8_t keyboard_protocol=1; + +// the idle configuration, how often we send the report to the +// host (ms * 4) even when it hasn't changed +uint8_t keyboard_idle_config=125; + +// count until idle timeout +uint8_t keyboard_idle_count=0; + +// 1=num lock, 2=caps lock, 4=scroll lock, 8=compose, 16=kana +volatile uint8_t keyboard_leds=0; + + + +static KEYCODE_TYPE unicode_to_keycode(uint16_t cpoint); +static void write_key(KEYCODE_TYPE keycode); +static uint8_t keycode_to_modifier(KEYCODE_TYPE keycode); +static uint8_t keycode_to_key(KEYCODE_TYPE keycode); +static void usb_keyboard_press_key(uint8_t key, uint8_t modifier); +static void usb_keyboard_release_key(uint8_t key, uint8_t modifier); +#ifdef DEADKEYS_MASK +static KEYCODE_TYPE deadkey_to_keycode(KEYCODE_TYPE keycode); +#endif + + + +// Step #1, decode UTF8 to Unicode code points +// +void usb_keyboard_write(uint8_t c) +{ + static int utf8_state=0; + static uint16_t unicode_wchar=0; + + if (c < 0x80) { + // single byte encoded, 0x00 to 0x7F + utf8_state = 0; + usb_keyboard_write_unicode(c); + } else if (c < 0xC0) { + // 2nd, 3rd or 4th byte, 0x80 to 0xBF + c &= 0x3F; + if (utf8_state == 1) { + utf8_state = 0; + usb_keyboard_write_unicode(unicode_wchar | c); + } else if (utf8_state == 2) { + unicode_wchar |= ((uint16_t)c << 6); + utf8_state = 1; + } + } else if (c < 0xE0) { + // begin 2 byte sequence, 0xC2 to 0xDF + // or illegal 2 byte sequence, 0xC0 to 0xC1 + unicode_wchar = (uint16_t)(c & 0x1F) << 6; + utf8_state = 1; + } else if (c < 0xF0) { + // begin 3 byte sequence, 0xE0 to 0xEF + unicode_wchar = (uint16_t)(c & 0x0F) << 12; + utf8_state = 2; + } else { + // begin 4 byte sequence (not supported), 0xF0 to 0xF4 + // or illegal, 0xF5 to 0xFF + utf8_state = 255; + } +} + + +// Step #2: translate Unicode code point to keystroke sequence +// +static KEYCODE_TYPE unicode_to_keycode(uint16_t cpoint) +{ + // Unicode code points beyond U+FFFF are not supported + // technically this input should probably be called UCS-2 + if (cpoint < 32) { + if (cpoint == 10) return KEY_ENTER & 0x3FFF; + if (cpoint == 11) return KEY_TAB & 0x3FFF; + return 0; + } + if (cpoint < 128) { + return keycodes_ascii[cpoint - 0x20]; + } + #ifdef ISO_8859_1_A0 + if (cpoint >= 0xA0 && cpoint < 0x100) { + return keycodes_iso_8859_1[cpoint - 0xA0]; + } + #endif + //#ifdef UNICODE_20AC + //if (cpoint == 0x20AC) return UNICODE_20AC & 0x3FFF; + //#endif + #ifdef KEYCODE_EXTRA00 + if (cpoint == UNICODE_EXTRA00) return KEYCODE_EXTRA00 & 0x3FFF; + #endif + #ifdef KEYCODE_EXTRA01 + if (cpoint == UNICODE_EXTRA01) return KEYCODE_EXTRA01 & 0x3FFF; + #endif + #ifdef KEYCODE_EXTRA02 + if (cpoint == UNICODE_EXTRA02) return KEYCODE_EXTRA02 & 0x3FFF; + #endif + #ifdef KEYCODE_EXTRA03 + if (cpoint == UNICODE_EXTRA03) return KEYCODE_EXTRA03 & 0x3FFF; + #endif + #ifdef KEYCODE_EXTRA04 + if (cpoint == UNICODE_EXTRA04) return KEYCODE_EXTRA04 & 0x3FFF; + #endif + #ifdef KEYCODE_EXTRA05 + if (cpoint == UNICODE_EXTRA05) return KEYCODE_EXTRA05 & 0x3FFF; + #endif + #ifdef KEYCODE_EXTRA06 + if (cpoint == UNICODE_EXTRA06) return KEYCODE_EXTRA06 & 0x3FFF; + #endif + #ifdef KEYCODE_EXTRA07 + if (cpoint == UNICODE_EXTRA07) return KEYCODE_EXTRA07 & 0x3FFF; + #endif + #ifdef KEYCODE_EXTRA08 + if (cpoint == UNICODE_EXTRA08) return KEYCODE_EXTRA08 & 0x3FFF; + #endif + #ifdef KEYCODE_EXTRA09 + if (cpoint == UNICODE_EXTRA09) return KEYCODE_EXTRA09 & 0x3FFF; + #endif + return 0; +} + +// Step #3: execute keystroke sequence +// +#ifdef DEADKEYS_MASK +static KEYCODE_TYPE deadkey_to_keycode(KEYCODE_TYPE keycode) +{ + keycode &= DEADKEYS_MASK; + if (keycode == 0) return 0; + #ifdef ACUTE_ACCENT_BITS + if (keycode == ACUTE_ACCENT_BITS) return DEADKEY_ACUTE_ACCENT; + #endif + #ifdef CEDILLA_BITS + if (keycode == CEDILLA_BITS) return DEADKEY_CEDILLA; + #endif + #ifdef CIRCUMFLEX_BITS + if (keycode == CIRCUMFLEX_BITS) return DEADKEY_CIRCUMFLEX; + #endif + #ifdef DIAERESIS_BITS + if (keycode == DIAERESIS_BITS) return DEADKEY_DIAERESIS; + #endif + #ifdef GRAVE_ACCENT_BITS + if (keycode == GRAVE_ACCENT_BITS) return DEADKEY_GRAVE_ACCENT; + #endif + #ifdef TILDE_BITS + if (keycode == TILDE_BITS) return DEADKEY_TILDE; + #endif + #ifdef RING_ABOVE_BITS + if (keycode == RING_ABOVE_BITS) return DEADKEY_RING_ABOVE; + #endif + return 0; +} +#endif + +void usb_keyboard_write_unicode(uint16_t cpoint) +{ + KEYCODE_TYPE keycode; + #ifdef DEADKEYS_MASK + KEYCODE_TYPE deadkeycode; + #endif + + keycode = unicode_to_keycode(cpoint); + if (keycode) { + #ifdef DEADKEYS_MASK + KEYCODE_TYPE deadkeycode = deadkey_to_keycode(keycode); + if (deadkeycode) write_key(deadkeycode); + #endif + write_key(keycode); + } +} + + +// Step #4: do each keystroke +// +static void write_key(KEYCODE_TYPE keycode) +{ +/* + uint8_t key, modifier=0; + + #ifdef SHIFT_MASK + if (keycode & SHIFT_MASK) modifier |= MODIFIERKEY_SHIFT; + #endif + #ifdef ALTGR_MASK + if (keycode & ALTGR_MASK) modifier |= MODIFIERKEY_RIGHT_ALT; + #endif + #ifdef RCTRL_MASK + if (keycode & RCTRL_MASK) modifier |= MODIFIERKEY_RIGHT_CTRL; + #endif + key = keycode & 0x3F; + #ifdef KEY_NON_US_100 + if (key == KEY_NON_US_100) key = 100; + #endif + usb_keyboard_press(key, modifier); +*/ + usb_keyboard_press(keycode_to_key(keycode), keycode_to_modifier(keycode)); +} + +static uint8_t keycode_to_modifier(KEYCODE_TYPE keycode) +{ + uint8_t modifier=0; + + #ifdef SHIFT_MASK + if (keycode & SHIFT_MASK) modifier |= MODIFIERKEY_SHIFT; + #endif + #ifdef ALTGR_MASK + if (keycode & ALTGR_MASK) modifier |= MODIFIERKEY_RIGHT_ALT; + #endif + #ifdef RCTRL_MASK + if (keycode & RCTRL_MASK) modifier |= MODIFIERKEY_RIGHT_CTRL; + #endif + return modifier; +} + +static uint8_t keycode_to_key(KEYCODE_TYPE keycode) +{ + uint8_t key = keycode & 0x3F; + #ifdef KEY_NON_US_100 + if (key == KEY_NON_US_100) key = 100; + #endif + return key; +} + + + +void usb_keyboard_press_keycode(uint16_t n) +{ + uint8_t key, mod, msb, modrestore=0; + KEYCODE_TYPE keycode; + #ifdef DEADKEYS_MASK + KEYCODE_TYPE deadkeycode; + #endif + + msb = n >> 8; + if (msb >= 0xC2 && msb <= 0xDF) { + n = (n & 0x3F) | ((uint16_t)(msb & 0x1F) << 6); + } else + if (msb == 0x80) { + usb_keyboard_press_key(0, n); + return; + } else + if (msb == 0x40) { + usb_keyboard_press_key(n, 0); + return; + } + keycode = unicode_to_keycode(n); + if (!keycode) return; + #ifdef DEADKEYS_MASK + deadkeycode = deadkey_to_keycode(keycode); + if (deadkeycode) { + modrestore = keyboard_modifier_keys; + if (modrestore) { + keyboard_modifier_keys = 0; + send_now(); + } + // TODO: test if operating systems recognize + // deadkey sequences when other keys are held + mod = keycode_to_modifier(deadkeycode); + key = keycode_to_key(deadkeycode); + usb_keyboard_press_key(key, mod); + usb_keyboard_release_key(key, mod); + } + #endif + mod = keycode_to_modifier(keycode); + key = keycode_to_key(keycode); + usb_keyboard_press_key(key, mod | modrestore); +} + + +void usb_keyboard_release_keycode(uint16_t n) +{ + uint8_t key, mod, msb; + + msb = n >> 8; + if (msb >= 0xC2 && msb <= 0xDF) { + n = (n & 0x3F) | ((uint16_t)(msb & 0x1F) << 6); + } else + if (msb == 0x80) { + usb_keyboard_release_key(0, n); + return; + } else + if (msb == 0x40) { + usb_keyboard_release_key(n, 0); + return; + } + KEYCODE_TYPE keycode = unicode_to_keycode(n); + if (!keycode) return; + mod = keycode_to_modifier(keycode); + key = keycode_to_key(keycode); + usb_keyboard_release_key(key, mod); +} + + +static void usb_keyboard_press_key(uint8_t key, uint8_t modifier) +{ + int i, send_required = 0; + + if (modifier) { + if ((keyboard_modifier_keys & modifier) != modifier) { + keyboard_modifier_keys |= modifier; + send_required = 1; + } + } + if (key) { + for (i=0; i < 6; i++) { + if (keyboard_keys[i] == key) goto end; + } + for (i=0; i < 6; i++) { + if (keyboard_keys[i] == 0) { + keyboard_keys[i] = key; + send_required = 1; + goto end; + } + } + } + end: + if (send_required) usb_keyboard_send(); +} + + +static void usb_keyboard_release_key(uint8_t key, uint8_t modifier) +{ + int i, send_required = 0; + + if (modifier) { + if ((keyboard_modifier_keys & modifier) != 0) { + keyboard_modifier_keys &= ~modifier; + send_required = 1; + } + } + if (key) { + for (i=0; i < 6; i++) { + if (keyboard_keys[i] == key) { + keyboard_keys[i] = 0; + send_required = 1; + } + } + } + if (send_required) usb_keyboard_send(); +} + +void usb_keyboard_release_all(void) +{ + uint8_t i, anybits; + + anybits = keyboard_modifier_keys; + keyboard_modifier_keys = 0; + for (i=0; i < 6; i++) { + anybits |= keyboard_keys[i]; + keyboard_keys[i] = 0; + } + if (anybits) usb_keyboard_send(); +} + + +int usb_keyboard_press(uint8_t key, uint8_t modifier) +{ + int r; + keyboard_modifier_keys = modifier; + keyboard_keys[0] = key; + keyboard_keys[1] = 0; + keyboard_keys[2] = 0; + keyboard_keys[3] = 0; + keyboard_keys[4] = 0; + keyboard_keys[5] = 0; + r = usb_keyboard_send(); + if (r) return r; + keyboard_modifier_keys = 0; + keyboard_keys[0] = 0; + return usb_keyboard_send(); +} + + +// Maximum number of transmit packets to queue so we don't starve other endpoints for memory +#define TX_PACKET_LIMIT 4 + +static uint8_t transmit_previous_timeout=0; + +// When the PC isn't listening, how long do we wait before discarding data? +#define TX_TIMEOUT_MSEC 50 + +#if F_CPU == 96000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 596) +#elif F_CPU == 48000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 428) +#elif F_CPU == 24000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 262) +#endif + + +// send the contents of keyboard_keys and keyboard_modifier_keys +int usb_keyboard_send(void) +{ +#if 0 + serial_print("Send:"); + serial_phex(keyboard_modifier_keys); + serial_phex(keyboard_keys[0]); + serial_phex(keyboard_keys[1]); + serial_phex(keyboard_keys[2]); + serial_phex(keyboard_keys[3]); + serial_phex(keyboard_keys[4]); + serial_phex(keyboard_keys[5]); + serial_print("\n"); +#endif +#if 1 + uint32_t wait_count=0; + usb_packet_t *tx_packet; + + while (1) { + if (!usb_configuration) { + return -1; + } + if (usb_tx_packet_count(KEYBOARD_ENDPOINT) < TX_PACKET_LIMIT) { + tx_packet = usb_malloc(); + if (tx_packet) break; + } + if (++wait_count > TX_TIMEOUT || transmit_previous_timeout) { + transmit_previous_timeout = 1; + return -1; + } + yield(); + } + *(tx_packet->buf) = keyboard_modifier_keys; + *(tx_packet->buf + 1) = 0; + memcpy(tx_packet->buf + 2, keyboard_keys, 6); + tx_packet->len = 8; + usb_tx(KEYBOARD_ENDPOINT, tx_packet); +#endif + return 0; +} + + +#endif // KEYBOARD_INTERFACE diff --git a/teensy3/usb_keyboard.h b/teensy3/usb_keyboard.h new file mode 100644 index 0000000000000000000000000000000000000000..b8d28c7df814e4def7b758fe094fed79a1c4b988 --- /dev/null +++ b/teensy3/usb_keyboard.h @@ -0,0 +1,97 @@ +/* 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 USBkeyboard_h_ +#define USBkeyboard_h_ + +#include "keylayouts.h" + +#if defined(USB_HID) || defined(USB_SERIAL_HID) + +#include <inttypes.h> + +// C language implementation +#ifdef __cplusplus +extern "C" { +#endif +void usb_keyboard_write(uint8_t c); +void usb_keyboard_write_unicode(uint16_t cpoint); +void usb_keyboard_press_keycode(uint16_t n); +void usb_keyboard_release_keycode(uint16_t n); +void usb_keyboard_release_all(void); +int usb_keyboard_press(uint8_t key, uint8_t modifier); +int usb_keyboard_send(void); +extern uint8_t keyboard_modifier_keys; +extern uint8_t keyboard_keys[6]; +extern uint8_t keyboard_protocol; +extern uint8_t keyboard_idle_config; +extern uint8_t keyboard_idle_count; +extern volatile uint8_t keyboard_leds; +#ifdef __cplusplus +} +#endif + + + +// C++ interface +#ifdef __cplusplus +#include "Stream.h" +class usb_keyboard_class : public Print +{ +public: + void begin(void) { } + void end(void) { } + virtual size_t write(uint8_t c) { usb_keyboard_write(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); } + using Print::write; + void write_unicode(uint16_t n) { usb_keyboard_write_unicode(n); } + void set_modifier(uint8_t c) { keyboard_modifier_keys = c; } + void set_key1(uint8_t c) { keyboard_keys[0] = c; } + void set_key2(uint8_t c) { keyboard_keys[1] = c; } + void set_key3(uint8_t c) { keyboard_keys[2] = c; } + void set_key4(uint8_t c) { keyboard_keys[3] = c; } + void set_key5(uint8_t c) { keyboard_keys[4] = c; } + void set_key6(uint8_t c) { keyboard_keys[5] = c; } + void set_media(uint8_t c) { } + void send_now(void) { usb_keyboard_send(); } + void press(uint16_t n) { usb_keyboard_press_keycode(n); } + void release(uint16_t n) { usb_keyboard_release_keycode(n); } + void releaseAll(void); +}; + +extern usb_keyboard_class Keyboard; + +#endif // __cplusplus + +#endif // USB_HID || USB_SERIAL_HID +#endif // USBkeyboard_h_ diff --git a/teensy3/usb_mem.c b/teensy3/usb_mem.c new file mode 100644 index 0000000000000000000000000000000000000000..c6e902a80d96de843c941551be7c926294d9fac1 --- /dev/null +++ b/teensy3/usb_mem.c @@ -0,0 +1,106 @@ +/* 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 "HardwareSerial.h" +#include "usb_dev.h" +#include "usb_mem.h" + +__attribute__ ((section(".usbbuffers"), used)) +unsigned char usb_buffer_memory[NUM_USB_BUFFERS * sizeof(usb_packet_t)]; + +static uint32_t usb_buffer_available = 0xFFFFFFFF; + +// use bitmask and CLZ instruction to implement fast free list +// http://www.archivum.info/gnu.gcc.help/2006-08/00148/Re-GCC-Inline-Assembly.html +// http://gcc.gnu.org/ml/gcc/2012-06/msg00015.html +// __builtin_clz() + +usb_packet_t * usb_malloc(void) +{ + unsigned int n, avail; + uint8_t *p; + + __disable_irq(); + avail = usb_buffer_available; + n = __builtin_clz(avail); // clz = count leading zeros + if (n >= NUM_USB_BUFFERS) { + __enable_irq(); + return NULL; + } + //serial_print("malloc:"); + //serial_phex(n); + //serial_print("\n"); + + usb_buffer_available = avail & ~(0x80000000 >> n); + __enable_irq(); + p = usb_buffer_memory + (n * sizeof(usb_packet_t)); + //serial_print("malloc:"); + //serial_phex32((int)p); + //serial_print("\n"); + *(uint32_t *)p = 0; + *(uint32_t *)(p + 4) = 0; + return (usb_packet_t *)p; +} + +// for the receive endpoints to request memory +extern uint8_t usb_rx_memory_needed; +extern void usb_rx_memory(usb_packet_t *packet); + +void usb_free(usb_packet_t *p) +{ + unsigned int n, mask; + + //serial_print("free:"); + n = ((uint8_t *)p - usb_buffer_memory) / sizeof(usb_packet_t); + if (n >= NUM_USB_BUFFERS) return; + //serial_phex(n); + //serial_print("\n"); + + // if any endpoints are starving for memory to receive + // packets, give this memory to them immediately! + if (usb_rx_memory_needed && usb_configuration) { + //serial_print("give to rx:"); + //serial_phex32((int)p); + //serial_print("\n"); + usb_rx_memory(p); + return; + } + + mask = (0x80000000 >> n); + __disable_irq(); + usb_buffer_available |= mask; + __enable_irq(); + + //serial_print("free:"); + //serial_phex32((int)p); + //serial_print("\n"); +} + diff --git a/teensy3/usb_mem.h b/teensy3/usb_mem.h new file mode 100644 index 0000000000000000000000000000000000000000..5e50bf84dbd68162d60df89a92e0604368fd0ce2 --- /dev/null +++ b/teensy3/usb_mem.h @@ -0,0 +1,55 @@ +/* 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 _usb_mem_h_ +#define _usb_mem_h_ + +#include <stdint.h> + +typedef struct usb_packet_struct { + uint16_t len; + uint16_t index; + struct usb_packet_struct *next; + uint8_t buf[64]; +} usb_packet_t; + +#ifdef __cplusplus +extern "C" { +#endif + +usb_packet_t * usb_malloc(void); +void usb_free(usb_packet_t *p); + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/teensy3/usb_midi.c b/teensy3/usb_midi.c new file mode 100644 index 0000000000000000000000000000000000000000..b14869778f689b7dc6ded7b278f7554548ec8bc4 --- /dev/null +++ b/teensy3/usb_midi.c @@ -0,0 +1,264 @@ +/* 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 "usb_dev.h" +#include "usb_midi.h" +#include "core_pins.h" // for yield() +#include "HardwareSerial.h" + +#ifdef MIDI_INTERFACE // defined by usb_dev.h -> usb_desc.h + + +uint8_t usb_midi_msg_channel; +uint8_t usb_midi_msg_type; +uint8_t usb_midi_msg_data1; +uint8_t usb_midi_msg_data2; +uint8_t usb_midi_msg_sysex[USB_MIDI_SYSEX_MAX]; +uint8_t usb_midi_msg_sysex_len; +void (*usb_midi_handleNoteOff)(uint8_t ch, uint8_t note, uint8_t vel) = NULL; +void (*usb_midi_handleNoteOn)(uint8_t ch, uint8_t note, uint8_t vel) = NULL; +void (*usb_midi_handleVelocityChange)(uint8_t ch, uint8_t note, uint8_t vel) = NULL; +void (*usb_midi_handleControlChange)(uint8_t ch, uint8_t control, uint8_t value) = NULL; +void (*usb_midi_handleProgramChange)(uint8_t ch, uint8_t program) = NULL; +void (*usb_midi_handleAfterTouch)(uint8_t ch, uint8_t pressure) = NULL; +void (*usb_midi_handlePitchChange)(uint8_t ch, int pitch) = NULL; +void (*usb_midi_handleRealTimeSystem)(uint8_t rtb) = NULL; + +// Maximum number of transmit packets to queue so we don't starve other endpoints for memory +#define TX_PACKET_LIMIT 6 +static usb_packet_t *rx_packet=NULL; +static usb_packet_t *tx_packet=NULL; +static uint8_t transmit_previous_timeout=0; +static uint8_t tx_noautoflush=0; + + +// When the PC isn't listening, how long do we wait before discarding data? +#define TX_TIMEOUT_MSEC 40 + +#if F_CPU == 96000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 596) +#elif F_CPU == 48000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 428) +#elif F_CPU == 24000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 262) +#endif + + +void usb_midi_write_packed(uint32_t n) +{ + uint32_t index, wait_count=0; + + tx_noautoflush = 1; + if (!tx_packet) { + while (1) { + if (!usb_configuration) { + //serial_print("error1\n"); + return; + } + if (usb_tx_packet_count(MIDI_TX_ENDPOINT) < TX_PACKET_LIMIT) { + tx_packet = usb_malloc(); + if (tx_packet) break; + } + if (++wait_count > TX_TIMEOUT || transmit_previous_timeout) { + transmit_previous_timeout = 1; + //serial_print("error2\n"); + return; + } + yield(); + } + } + transmit_previous_timeout = 0; + index = tx_packet->index; + *((uint32_t *)(tx_packet->buf) + index++) = n; + if (index < MIDI_TX_SIZE/4) { + tx_packet->index = index; + } else { + tx_packet->len = MIDI_TX_SIZE; + usb_tx(MIDI_TX_ENDPOINT, tx_packet); + tx_packet = usb_malloc(); + } + tx_noautoflush = 0; +} + +void usb_midi_send_sysex(const uint8_t *data, uint32_t length) +{ + // TODO: MIDI 2.5 lib automatically adds start and stop bytes + while (length > 3) { + usb_midi_write_packed(0x04 | (data[0] << 8) | (data[1] << 16) | (data[2] << 24)); + data += 3; + length -= 3; + } + if (length == 3) { + usb_midi_write_packed(0x07 | (data[0] << 8) | (data[1] << 16) | (data[2] << 24)); + } else if (length == 2) { + usb_midi_write_packed(0x06 | (data[0] << 8) | (data[1] << 16)); + } else if (length == 1) { + usb_midi_write_packed(0x05 | (data[0] << 8)); + } +} + +void usb_midi_flush_output(void) +{ + if (tx_noautoflush == 0 && tx_packet && tx_packet->index > 0) { + tx_packet->len = tx_packet->index * 4; + usb_tx(MIDI_TX_ENDPOINT, tx_packet); + tx_packet = usb_malloc(); + } +} + +void static sysex_byte(uint8_t b) +{ + if (usb_midi_msg_sysex_len < USB_MIDI_SYSEX_MAX) { + usb_midi_msg_sysex[usb_midi_msg_sysex_len++] = b; + } +} + + +int usb_midi_read(uint32_t channel) +{ + uint32_t n, index, ch, type1, type2; + + if (!rx_packet) { + if (!usb_configuration) return 0; + rx_packet = usb_rx(MIDI_RX_ENDPOINT); + if (!rx_packet) return 0; + if (rx_packet->len == 0) { + usb_free(rx_packet); + rx_packet = NULL; + return 0; + } + } + index = rx_packet->index; + n = *(uint32_t *)(rx_packet->buf + index); + //serial_print("midi rx, n="); + //serial_phex32(n); + //serial_print("\n"); + index += 4; + if (index < rx_packet->len) { + rx_packet->index = index; + } else { + usb_free(rx_packet); + rx_packet = usb_rx(MIDI_RX_ENDPOINT); + } + type1 = n & 15; + type2 = (n >> 12) & 15; + ch = ((n >> 8) & 15) + 1; + if (type1 >= 0x08 && type1 <= 0x0E) { + if (channel && channel != ch) { + // ignore other channels when user wants single channel read + return 0; + } + if (type1 == 0x08 && type2 == 0x08) { + usb_midi_msg_type = 0; // 0 = Note off + if (usb_midi_handleNoteOff) + (*usb_midi_handleNoteOff)(ch, (n >> 16), (n >> 24)); + } else + if (type1 == 0x09 && type2 == 0x09) { + if ((n >> 24) > 0) { + usb_midi_msg_type = 1; // 1 = Note on + if (usb_midi_handleNoteOn) + (*usb_midi_handleNoteOn)(ch, (n >> 16), (n >> 24)); + } else { + usb_midi_msg_type = 0; // 0 = Note off + if (usb_midi_handleNoteOff) + (*usb_midi_handleNoteOff)(ch, (n >> 16), (n >> 24)); + } + } else + if (type1 == 0x0A && type2 == 0x0A) { + usb_midi_msg_type = 2; // 2 = Poly Pressure + if (usb_midi_handleVelocityChange) + (*usb_midi_handleVelocityChange)(ch, (n >> 16), (n >> 24)); + } else + if (type1 == 0x0B && type2 == 0x0B) { + usb_midi_msg_type = 3; // 3 = Control Change + if (usb_midi_handleControlChange) + (*usb_midi_handleControlChange)(ch, (n >> 16), (n >> 24)); + } else + if (type1 == 0x0C && type2 == 0x0C) { + usb_midi_msg_type = 4; // 4 = Program Change + if (usb_midi_handleProgramChange) + (*usb_midi_handleProgramChange)(ch, (n >> 16)); + } else + if (type1 == 0x0D && type2 == 0x0D) { + usb_midi_msg_type = 5; // 5 = After Touch + if (usb_midi_handleAfterTouch) + (*usb_midi_handleAfterTouch)(ch, (n >> 16)); + } else + if (type1 == 0x0E && type2 == 0x0E) { + usb_midi_msg_type = 6; // 6 = Pitch Bend + if (usb_midi_handlePitchChange) + (*usb_midi_handlePitchChange)(ch, + ((n >> 16) & 0x7F) | ((n >> 17) & 0x3F80)); + } else { + return 0; + } + return_message: + usb_midi_msg_channel = ch; + usb_midi_msg_data1 = (n >> 16); + usb_midi_msg_data2 = (n >> 24); + return 1; + } + if (type1 == 0x04) { + sysex_byte(n >> 8); + sysex_byte(n >> 16); + sysex_byte(n >> 24); + return 0; + } + if (type1 >= 0x05 && type1 <= 0x07) { + sysex_byte(n >> 8); + if (type1 >= 0x06) sysex_byte(n >> 16); + if (type1 == 0x07) sysex_byte(n >> 24); + usb_midi_msg_data1 = usb_midi_msg_sysex_len; + usb_midi_msg_sysex_len = 0; + usb_midi_msg_type = 7; // 7 = Sys Ex + return 1; + } + if (type1 == 0x0F) { + // TODO: does this need to be a full MIDI parser? + // What software actually uses this message type in practice? + if (usb_midi_msg_sysex_len > 0) { + // From David Sorlien, dsorlien at gmail.com, http://axe4live.wordpress.com + // OSX sometimes uses Single Byte Unparsed to + // send bytes in the middle of a SYSEX message. + sysex_byte(n >> 8); + } else { + // From Sebastian Tomczak, seb.tomczak at gmail.com + // http://little-scale.blogspot.com/2011/08/usb-midi-game-boy-sync-for-16.html + usb_midi_msg_type = 8; + if (usb_midi_handleRealTimeSystem) + (*usb_midi_handleRealTimeSystem)(n >> 8); + goto return_message; + } + } + return 0; +} + + +#endif // MIDI_INTERFACE diff --git a/teensy3/usb_midi.h b/teensy3/usb_midi.h new file mode 100644 index 0000000000000000000000000000000000000000..d1b24f15d0923b634e995354f6c4958add46ef4a --- /dev/null +++ b/teensy3/usb_midi.h @@ -0,0 +1,180 @@ +/* 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 USBmidi_h_ +#define USBmidi_h_ + +#if defined(USB_MIDI) + +#include <inttypes.h> + +/* +These were originally meant to allow programs written for +Francois Best's MIDI library to be easily used with +Teensy's usbMIDI which implements the same API. However, +the MIDI library definitions have changed, so these names +now conflict. They've never been documented (the PJRC web +page documents usbMIDI.getType() in numbers) so they are +now commented out so usbMIDI and the MIDI library can be +used together without conflict. +#define NoteOff 0 +#define NoteOn 1 +#define AfterTouchPoly 2 +#define ControlChange 3 +#define ProgramChange 4 +#define AfterTouchChannel 5 +#define PitchBend 6 +#define SystemExclusive 7 +*/ + +#define USB_MIDI_SYSEX_MAX 60 // maximum sysex length we can receive + +// C language implementation +#ifdef __cplusplus +extern "C" { +#endif +void usb_midi_write_packed(uint32_t n); +void usb_midi_send_sysex(const uint8_t *data, uint32_t length); +void usb_midi_flush_output(void); +int usb_midi_read(uint32_t channel); +extern uint8_t usb_midi_msg_channel; +extern uint8_t usb_midi_msg_type; +extern uint8_t usb_midi_msg_data1; +extern uint8_t usb_midi_msg_data2; +extern uint8_t usb_midi_msg_sysex[USB_MIDI_SYSEX_MAX]; +extern uint8_t usb_midi_msg_sysex_len; +extern void (*usb_midi_handleNoteOff)(uint8_t ch, uint8_t note, uint8_t vel); +extern void (*usb_midi_handleNoteOn)(uint8_t ch, uint8_t note, uint8_t vel); +extern void (*usb_midi_handleVelocityChange)(uint8_t ch, uint8_t note, uint8_t vel); +extern void (*usb_midi_handleControlChange)(uint8_t ch, uint8_t control, uint8_t value); +extern void (*usb_midi_handleProgramChange)(uint8_t ch, uint8_t program); +extern void (*usb_midi_handleAfterTouch)(uint8_t ch, uint8_t pressure); +extern void (*usb_midi_handlePitchChange)(uint8_t ch, int pitch); +extern void (*usb_midi_handleRealTimeSystem)(uint8_t rtb); + +#ifdef __cplusplus +} +#endif + +// C++ interface +#ifdef __cplusplus +class usb_midi_class +{ + public: + void begin(void) { } + void end(void) { } + void sendNoteOff(uint32_t note, uint32_t velocity, uint32_t channel) __attribute__((always_inline)) { + usb_midi_write_packed(0x8008 | (((channel - 1) & 0x0F) << 8) + | ((note & 0x7F) << 16) | ((velocity & 0x7F) << 24)); + } + void sendNoteOn(uint32_t note, uint32_t velocity, uint32_t channel) __attribute__((always_inline)) { + usb_midi_write_packed(0x9009 | (((channel - 1) & 0x0F) << 8) + | ((note & 0x7F) << 16) | ((velocity & 0x7F) << 24)); + } + void sendPolyPressure(uint32_t note, uint32_t pressure, uint32_t channel) __attribute__((always_inline)) { + usb_midi_write_packed(0xA00A | (((channel - 1) & 0x0F) << 8) + | ((note & 0x7F) << 16) | ((pressure & 0x7F) << 24)); + } + void sendControlChange(uint32_t control, uint32_t value, uint32_t channel) __attribute__((always_inline)) { + usb_midi_write_packed(0xB00B | (((channel - 1) & 0x0F) << 8) + | ((control & 0x7F) << 16) | ((value & 0x7F) << 24)); + } + void sendProgramChange(uint32_t program, uint32_t channel) __attribute__((always_inline)) { + usb_midi_write_packed(0xC00C | (((channel - 1) & 0x0F) << 8) + | ((program & 0x7F) << 16)); + } + void sendAfterTouch(uint32_t pressure, uint32_t channel) __attribute__((always_inline)) { + usb_midi_write_packed(0xD00D | (((channel - 1) & 0x0F) << 8) + | ((pressure & 0x7F) << 16)); + } + void sendPitchBend(uint32_t value, uint32_t channel) __attribute__((always_inline)) { + usb_midi_write_packed(0xE00E | (((channel - 1) & 0x0F) << 8) + | ((value & 0x7F) << 16) | ((value & 0x3F80) << 17)); + } + void sendSysEx(uint32_t length, const uint8_t *data) { + usb_midi_send_sysex(data, length); + } + void send_now(void) { + usb_midi_flush_output(); + } + uint8_t analog2velocity(uint16_t val, uint8_t range); + bool read(uint8_t channel=0) { + return usb_midi_read(channel); + } + inline uint8_t getType(void) { + return usb_midi_msg_type; + }; + inline uint8_t getChannel(void) { + return usb_midi_msg_channel; + }; + inline uint8_t getData1(void) { + return usb_midi_msg_data1; + }; + inline uint8_t getData2(void) { + return usb_midi_msg_data2; + }; + inline uint8_t * getSysExArray(void) { + return usb_midi_msg_sysex; + }; + inline void setHandleNoteOff(void (*fptr)(uint8_t channel, uint8_t note, uint8_t velocity)) { + usb_midi_handleNoteOff = fptr; + }; + inline void setHandleNoteOn(void (*fptr)(uint8_t channel, uint8_t note, uint8_t velocity)) { + usb_midi_handleNoteOn = fptr; + }; + inline void setHandleVelocityChange(void (*fptr)(uint8_t channel, uint8_t note, uint8_t velocity)) { + usb_midi_handleVelocityChange = fptr; + }; + inline void setHandleControlChange(void (*fptr)(uint8_t channel, uint8_t control, uint8_t value)) { + usb_midi_handleControlChange = fptr; + }; + inline void setHandleProgramChange(void (*fptr)(uint8_t channel, uint8_t program)) { + usb_midi_handleProgramChange = fptr; + }; + inline void setHandleAfterTouch(void (*fptr)(uint8_t channel, uint8_t pressure)) { + usb_midi_handleAfterTouch = fptr; + }; + inline void setHandlePitchChange(void (*fptr)(uint8_t channel, int pitch)) { + usb_midi_handlePitchChange = fptr; + }; + inline void setHandleRealTimeSystem(void (*fptr)(uint8_t realtimebyte)) { + usb_midi_handleRealTimeSystem = fptr; + }; + private: +}; + +extern usb_midi_class usbMIDI; + + +#endif // __cplusplus + +#endif // USB_MIDI +#endif // USBmidi_h_ + diff --git a/teensy3/usb_mouse.c b/teensy3/usb_mouse.c new file mode 100644 index 0000000000000000000000000000000000000000..ee1b944660e7e0103e57b67f50ddf897597b8d6d --- /dev/null +++ b/teensy3/usb_mouse.c @@ -0,0 +1,117 @@ +/* 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 "usb_dev.h" +#include "usb_mouse.h" +#include "core_pins.h" // for yield() +#include "HardwareSerial.h" +#include <string.h> // for memcpy() + +#ifdef MOUSE_INTERFACE // defined by usb_dev.h -> usb_desc.h + +// which buttons are currently pressed +uint8_t usb_mouse_buttons_state=0; + +// protocol setting from the host. We use exactly the same report +// either way, so this variable only stores the setting since we +// are required to be able to report which setting is in use. +uint8_t usb_mouse_protocol=1; + + +// Set the mouse buttons. To create a "click", 2 calls are needed, +// one to push the button down and the second to release it +int usb_mouse_buttons(uint8_t left, uint8_t middle, uint8_t right) +{ + uint8_t mask=0; + + if (left) mask |= 1; + if (middle) mask |= 4; + if (right) mask |= 2; + usb_mouse_buttons_state = mask; + return usb_mouse_move(0, 0, 0); +} + + +// Maximum number of transmit packets to queue so we don't starve other endpoints for memory +#define TX_PACKET_LIMIT 3 + +static uint8_t transmit_previous_timeout=0; + +// When the PC isn't listening, how long do we wait before discarding data? +#define TX_TIMEOUT_MSEC 30 + +#if F_CPU == 96000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 596) +#elif F_CPU == 48000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 428) +#elif F_CPU == 24000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 262) +#endif + + +// Move the mouse. x, y and wheel are -127 to 127. Use 0 for no movement. +int usb_mouse_move(int8_t x, int8_t y, int8_t wheel) +{ + uint32_t wait_count=0; + usb_packet_t *tx_packet; + + //serial_print("move"); + //serial_print("\n"); + if (x == -128) x = -127; + if (y == -128) y = -127; + if (wheel == -128) wheel = -127; + + while (1) { + if (!usb_configuration) { + return -1; + } + if (usb_tx_packet_count(MOUSE_ENDPOINT) < TX_PACKET_LIMIT) { + tx_packet = usb_malloc(); + if (tx_packet) break; + } + if (++wait_count > TX_TIMEOUT || transmit_previous_timeout) { + transmit_previous_timeout = 1; + return -1; + } + yield(); + } + transmit_previous_timeout = 0; + *(tx_packet->buf) = usb_mouse_buttons_state; + *(tx_packet->buf + 1) = x; + *(tx_packet->buf + 2) = y; + *(tx_packet->buf + 3) = wheel; + tx_packet->len = 4; + usb_tx(MOUSE_ENDPOINT, tx_packet); + return 0; +} + + + +#endif // MOUSE_INTERFACE diff --git a/teensy3/usb_mouse.h b/teensy3/usb_mouse.h new file mode 100644 index 0000000000000000000000000000000000000000..0c913522d6126eed6867f446df8bfdf227f23db9 --- /dev/null +++ b/teensy3/usb_mouse.h @@ -0,0 +1,98 @@ +/* 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 USBmouse_h_ +#define USBmouse_h_ + +#if defined(USB_HID) || defined(USB_SERIAL_HID) + +#include <inttypes.h> + +// C language implementation +#ifdef __cplusplus +extern "C" { +#endif +int usb_mouse_buttons(uint8_t left, uint8_t middle, uint8_t right); +int usb_mouse_move(int8_t x, int8_t y, int8_t wheel); +extern uint8_t usb_mouse_buttons_state; +extern uint8_t usb_mouse_protocol; +#ifdef __cplusplus +} +#endif + + +#define MOUSE_LEFT 1 +#define MOUSE_MIDDLE 4 +#define MOUSE_RIGHT 2 +#define MOUSE_ALL (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE) + +// C++ interface +#ifdef __cplusplus +class usb_mouse_class +{ + public: + void begin(void) { } + void end(void) { } + void move(int8_t x, int8_t y, int8_t wheel=0) { usb_mouse_move(x, y, wheel); } + void click(uint8_t b = MOUSE_LEFT) { + usb_mouse_buttons_state = b; + usb_mouse_move(0, 0, 0); + usb_mouse_buttons_state = 0; + usb_mouse_move(0, 0, 0); + } + void scroll(int8_t wheel) { usb_mouse_move(0, 0, wheel); } + void set_buttons(uint8_t left, uint8_t middle=0, uint8_t right=0) { + usb_mouse_buttons(left, middle, right); + } + void press(uint8_t b = MOUSE_LEFT) { + uint8_t buttons = usb_mouse_buttons_state | (b & MOUSE_ALL); + if (buttons != usb_mouse_buttons_state) { + usb_mouse_buttons_state = buttons; + usb_mouse_move(0, 0, 0); + } + } + void release(uint8_t b = MOUSE_LEFT) { + uint8_t buttons = usb_mouse_buttons_state & ~(b & MOUSE_ALL); + if (buttons != usb_mouse_buttons_state) { + usb_mouse_buttons_state = buttons; + usb_mouse_move(0, 0, 0); + } + } + bool isPressed(uint8_t b = MOUSE_ALL) { + return ((usb_mouse_buttons_state & (b & MOUSE_ALL)) != 0); + } +}; +extern usb_mouse_class Mouse; + +#endif // __cplusplus + +#endif // USB_HID || USB_SERIAL_HID +#endif // USBmouse_h_ + diff --git a/teensy3/usb_names.h b/teensy3/usb_names.h new file mode 100644 index 0000000000000000000000000000000000000000..0df3215133acc94e5ea76b63d3d5b6070505785c --- /dev/null +++ b/teensy3/usb_names.h @@ -0,0 +1,57 @@ +/* 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 _usb_names_h_ +#define _usb_names_h_ + +// These definitions are intended to allow users to override the default +// USB manufacturer, product and serial number strings. + +#include <stdint.h> + +#ifdef __cplusplus +extern "C" { +#endif + +struct usb_string_descriptor_struct { + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t wString[]; +}; + +extern struct usb_string_descriptor_struct usb_string_manufacturer_name; +extern struct usb_string_descriptor_struct usb_string_product_name; +extern struct usb_string_descriptor_struct usb_string_serial_number; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/teensy3/usb_rawhid.c b/teensy3/usb_rawhid.c new file mode 100644 index 0000000000000000000000000000000000000000..03210bb0a0e8f2131ce1826341ef45ec05a34dab --- /dev/null +++ b/teensy3/usb_rawhid.c @@ -0,0 +1,88 @@ +/* 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 "usb_dev.h" +#include "usb_rawhid.h" +#include "core_pins.h" // for yield(), millis() +#include <string.h> // for memcpy() +//#include "HardwareSerial.h" + +#ifdef RAWHID_INTERFACE // defined by usb_dev.h -> usb_desc.h + +int usb_rawhid_recv(void *buffer, uint32_t timeout) +{ + usb_packet_t *rx_packet; + uint32_t begin = millis(); + + while (1) { + if (!usb_configuration) return -1; + rx_packet = usb_rx(RAWHID_RX_ENDPOINT); + if (rx_packet) break; + if (millis() - begin > timeout || !timeout) return 0; + yield(); + } + memcpy(buffer, rx_packet->buf, RAWHID_RX_SIZE); + usb_free(rx_packet); + return RAWHID_RX_SIZE; +} + +int usb_rawhid_available(void) +{ + uint32_t count; + + if (!usb_configuration) return 0; + count = usb_rx_byte_count(RAWHID_RX_ENDPOINT); + return count; +} + +// Maximum number of transmit packets to queue so we don't starve other endpoints for memory +#define TX_PACKET_LIMIT 4 + +int usb_rawhid_send(const void *buffer, uint32_t timeout) +{ + usb_packet_t *tx_packet; + uint32_t begin = millis(); + + while (1) { + if (!usb_configuration) return -1; + if (usb_tx_packet_count(RAWHID_TX_ENDPOINT) < TX_PACKET_LIMIT) { + tx_packet = usb_malloc(); + if (tx_packet) break; + } + if (millis() - begin > timeout) return 0; + yield(); + } + memcpy(tx_packet->buf, buffer, RAWHID_TX_SIZE); + tx_packet->len = RAWHID_TX_SIZE; + usb_tx(RAWHID_TX_ENDPOINT, tx_packet); + return RAWHID_TX_SIZE; +} + +#endif // RAWHID_INTERFACE diff --git a/teensy3/usb_rawhid.h b/teensy3/usb_rawhid.h new file mode 100644 index 0000000000000000000000000000000000000000..d5fd5d8a13be67b3103cdd57f8b3052813a67531 --- /dev/null +++ b/teensy3/usb_rawhid.h @@ -0,0 +1,65 @@ +/* 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 USBrawhid_h_ +#define USBrawhid_h_ + +#if defined(USB_RAWHID) + +#include <inttypes.h> + +// C language implementation +#ifdef __cplusplus +extern "C" { +#endif +int usb_rawhid_recv(void *buffer, uint32_t timeout); +int usb_rawhid_available(void); +int usb_rawhid_send(const void *buffer, uint32_t timeout); +#ifdef __cplusplus +} +#endif + + +// C++ interface +#ifdef __cplusplus +class usb_rawhid_class +{ +public: + int available(void) {return usb_rawhid_available(); } + int recv(void *buffer, uint16_t timeout) { return usb_rawhid_recv(buffer, timeout); } + int send(const void *buffer, uint16_t timeout) { return usb_rawhid_send(buffer, timeout); } +}; + +extern usb_rawhid_class RawHID; + +#endif // __cplusplus + +#endif // USB_HID +#endif // USBrawhid_h_ diff --git a/teensy3/usb_seremu.c b/teensy3/usb_seremu.c new file mode 100644 index 0000000000000000000000000000000000000000..e4781e883e36715bd2af6305dac8d77eb4083501 --- /dev/null +++ b/teensy3/usb_seremu.c @@ -0,0 +1,249 @@ +/* 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 "usb_dev.h" +#include "usb_seremu.h" +#include "core_pins.h" // for yield() +//#include "HardwareSerial.h" + +#ifdef SEREMU_INTERFACE // defined by usb_dev.h -> usb_desc.h + +volatile uint8_t usb_seremu_transmit_flush_timer=0; + +static usb_packet_t *rx_packet=NULL; +static usb_packet_t *tx_packet=NULL; +static volatile uint8_t tx_noautoflush=0; + +#define TRANSMIT_FLUSH_TIMEOUT 5 /* in milliseconds */ + + +// get the next character, or -1 if nothing received +int usb_seremu_getchar(void) +{ + unsigned int i; + int c; + + while (1) { + if (!usb_configuration) return -1; + if (!rx_packet) rx_packet = usb_rx(SEREMU_RX_ENDPOINT); + if (!rx_packet) return -1; + i = rx_packet->index; + c = rx_packet->buf[i++]; + if (c) { + if (i >= rx_packet->len) { + usb_free(rx_packet); + rx_packet = NULL; + } else { + rx_packet->index = i; + } + return c; + } + usb_free(rx_packet); + rx_packet = NULL; + } +} + +// peek at the next character, or -1 if nothing received +int usb_seremu_peekchar(void) +{ + int c; + + while (1) { + if (!usb_configuration) return -1; + if (!rx_packet) rx_packet = usb_rx(SEREMU_RX_ENDPOINT); + if (!rx_packet) return -1; + c = rx_packet->buf[rx_packet->index]; + if (c) return c; + usb_free(rx_packet); + rx_packet = NULL; + } +} + +// number of bytes available in the receive buffer +int usb_seremu_available(void) +{ + int i, len, count; + + if (!rx_packet) { + if (usb_configuration) rx_packet = usb_rx(SEREMU_RX_ENDPOINT); + if (!rx_packet) return 0; + } + len = rx_packet->len; + i = rx_packet->index; + count = 0; + for (i = rx_packet->index; i < len; i++) { + if (rx_packet->buf[i] == 0) break; + count++; + } + if (count == 0) { + usb_free(rx_packet); + rx_packet = NULL; + } + return count; +} + + +// discard any buffered input +void usb_seremu_flush_input(void) +{ + usb_packet_t *rx; + + if (!usb_configuration) return; + if (rx_packet) { + usb_free(rx_packet); + rx_packet = NULL; + } + while (1) { + rx = usb_rx(SEREMU_RX_ENDPOINT); + if (!rx) break; + usb_free(rx); + } +} + + + +// Maximum number of transmit packets to queue so we don't starve other endpoints for memory +#define TX_PACKET_LIMIT 6 + +// When the PC isn't listening, how long do we wait before discarding data? If this is +// too short, we risk losing data during the stalls that are common with ordinary desktop +// software. If it's too long, we stall the user's program when no software is running. +#define TX_TIMEOUT_MSEC 30 + +#if F_CPU == 96000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 596) +#elif F_CPU == 48000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 428) +#elif F_CPU == 24000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 262) +#endif + +// When we've suffered the transmit timeout, don't wait again until the computer +// begins accepting data. If no software is running to receive, we'll just discard +// data as rapidly as Serial.print() can generate it, until there's something to +// actually receive it. +static uint8_t transmit_previous_timeout=0; + + +// transmit a character. 0 returned on success, -1 on error +int usb_seremu_putchar(uint8_t c) +{ + return usb_seremu_write(&c, 1); +} + + +int usb_seremu_write(const void *buffer, uint32_t size) +{ +#if 1 + uint32_t len; + uint32_t wait_count; + const uint8_t *src = (const uint8_t *)buffer; + uint8_t *dest; + + tx_noautoflush = 1; + while (size > 0) { + if (!tx_packet) { + wait_count = 0; + while (1) { + if (!usb_configuration) { + tx_noautoflush = 0; + return -1; + } + if (usb_tx_packet_count(SEREMU_TX_ENDPOINT) < TX_PACKET_LIMIT) { + tx_noautoflush = 1; + tx_packet = usb_malloc(); + if (tx_packet) break; + } + if (++wait_count > TX_TIMEOUT || transmit_previous_timeout) { + transmit_previous_timeout = 1; + tx_noautoflush = 0; + return -1; + } + tx_noautoflush = 0; + yield(); + tx_noautoflush = 1; + } + } + transmit_previous_timeout = 0; + len = SEREMU_TX_SIZE - tx_packet->index; + if (len > size) len = size; + dest = tx_packet->buf + tx_packet->index; + tx_packet->index += len; + size -= len; + while (len-- > 0) *dest++ = *src++; + if (tx_packet->index < SEREMU_TX_SIZE) { + usb_seremu_transmit_flush_timer = TRANSMIT_FLUSH_TIMEOUT; + } else { + tx_packet->len = SEREMU_TX_SIZE; + usb_seremu_transmit_flush_timer = 0; + usb_tx(SEREMU_TX_ENDPOINT, tx_packet); + tx_packet = NULL; + } + } + tx_noautoflush = 0; + return 0; +#endif +} + +void usb_seremu_flush_output(void) +{ + int i; + + if (!usb_configuration) return; + //serial_print("usb_serial_flush_output\n"); + if (tx_packet && tx_packet->index > 0) { + usb_seremu_transmit_flush_timer = 0; + for (i = tx_packet->index; i < SEREMU_TX_SIZE; i++) { + tx_packet->buf[i] = 0; + } + tx_packet->len = SEREMU_TX_SIZE; + usb_tx(SEREMU_TX_ENDPOINT, tx_packet); + tx_packet = NULL; + } + // while (usb_tx_byte_count(SEREMU_TX_ENDPOINT) > 0) ; // wait +} + +void usb_seremu_flush_callback(void) +{ + int i; + //serial_print("C"); + if (tx_noautoflush) return; + //serial_print("usb_flush_callback \n"); + for (i = tx_packet->index; i < SEREMU_TX_SIZE; i++) { + tx_packet->buf[i] = 0; + } + tx_packet->len = SEREMU_TX_SIZE; + usb_tx(SEREMU_TX_ENDPOINT, tx_packet); + tx_packet = NULL; + //serial_print("usb_flush_callback end\n"); +} + +#endif // SEREMU_INTERFACE diff --git a/teensy3/usb_seremu.h b/teensy3/usb_seremu.h new file mode 100644 index 0000000000000000000000000000000000000000..f3679c5cf935b55465bbfde66e55139e987ce57f --- /dev/null +++ b/teensy3/usb_seremu.h @@ -0,0 +1,91 @@ +/* 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 USBseremu_h_ +#define USBseremu_h_ + +#if defined(USB_HID) || defined(USB_MIDI) || defined(USB_RAWHID) || defined(USB_FLIGHTSIM) + +#include <inttypes.h> + +// C language implementation +#ifdef __cplusplus +extern "C" { +#endif +int usb_seremu_getchar(void); +int usb_seremu_peekchar(void); +int usb_seremu_available(void); +void usb_seremu_flush_input(void); +int usb_seremu_putchar(uint8_t c); +int usb_seremu_write(const void *buffer, uint32_t size); +void usb_seremu_flush_output(void); +void usb_seremu_flush_callback(void); +extern volatile uint8_t usb_seremu_transmit_flush_timer; +extern volatile uint8_t usb_configuration; +#ifdef __cplusplus +} +#endif + + +// C++ interface +#ifdef __cplusplus +#include "Stream.h" +class usb_seremu_class : public Stream +{ +public: + void begin(long) { /* TODO: call a function that tries to wait for enumeration */ }; + void end() { /* TODO: flush output and shut down USB port */ }; + virtual int available() { return usb_seremu_available(); } + virtual int read() { return usb_seremu_getchar(); } + virtual int peek() { return usb_seremu_peekchar(); } + virtual void flush() { usb_seremu_flush_output(); } + virtual size_t write(uint8_t c) { return usb_seremu_putchar(c); } + virtual size_t write(const uint8_t *buffer, size_t size) { return usb_seremu_write(buffer, size); } + 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); } + using Print::write; + void send_now(void) { usb_seremu_flush_output(); }; + uint32_t baud(void) { return 9600; } + uint8_t stopbits(void) { return 1; } + uint8_t paritytype(void) { return 0; } + uint8_t numbits(void) { return 8; } + uint8_t dtr(void) { return 1; } + uint8_t rts(void) { return 1; } + operator bool() { return usb_configuration; } +}; + +extern usb_seremu_class Serial; + +#endif // __cplusplus + +#endif // USB_HID +#endif // USBseremu_h_ diff --git a/teensy3/usb_serial.c b/teensy3/usb_serial.c new file mode 100644 index 0000000000000000000000000000000000000000..7b66d2b98db3a3edec0ec4755201f62b6e8c2236 --- /dev/null +++ b/teensy3/usb_serial.c @@ -0,0 +1,265 @@ +/* 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 "usb_dev.h" +#include "usb_serial.h" +#include "core_pins.h" // for yield() +//#include "HardwareSerial.h" +#include <string.h> // for memcpy() + +// defined by usb_dev.h -> usb_desc.h +#if defined(CDC_STATUS_INTERFACE) && defined(CDC_DATA_INTERFACE) + +uint32_t usb_cdc_line_coding[2]; +volatile uint8_t usb_cdc_line_rtsdtr=0; +volatile uint8_t usb_cdc_transmit_flush_timer=0; + +static usb_packet_t *rx_packet=NULL; +static usb_packet_t *tx_packet=NULL; +static volatile uint8_t tx_noautoflush=0; + +#define TRANSMIT_FLUSH_TIMEOUT 5 /* in milliseconds */ + +// get the next character, or -1 if nothing received +int usb_serial_getchar(void) +{ + unsigned int i; + int c; + + if (!rx_packet) { + if (!usb_configuration) return -1; + rx_packet = usb_rx(CDC_RX_ENDPOINT); + if (!rx_packet) return -1; + } + i = rx_packet->index; + c = rx_packet->buf[i++]; + if (i >= rx_packet->len) { + usb_free(rx_packet); + rx_packet = NULL; + } else { + rx_packet->index = i; + } + return c; +} + +// peek at the next character, or -1 if nothing received +int usb_serial_peekchar(void) +{ + if (!rx_packet) { + if (!usb_configuration) return -1; + rx_packet = usb_rx(CDC_RX_ENDPOINT); + if (!rx_packet) return -1; + } + if (!rx_packet) return -1; + return rx_packet->buf[rx_packet->index]; +} + +// number of bytes available in the receive buffer +int usb_serial_available(void) +{ + int count; + count = usb_rx_byte_count(CDC_RX_ENDPOINT); + if (rx_packet) count += rx_packet->len - rx_packet->index; + return count; +} + +// read a block of bytes to a buffer +int usb_serial_read(void *buffer, uint32_t size) +{ + uint8_t *p = (uint8_t *)buffer; + uint32_t qty, count=0; + + while (size) { + if (!usb_configuration) break; + if (!rx_packet) { + rx: + rx_packet = usb_rx(CDC_RX_ENDPOINT); + if (!rx_packet) break; + if (rx_packet->len == 0) { + usb_free(rx_packet); + goto rx; + } + } + qty = rx_packet->len - rx_packet->index; + if (qty > size) qty = size; + memcpy(p, rx_packet->buf + rx_packet->index, qty); + p += qty; + count += qty; + size -= qty; + rx_packet->index += qty; + if (rx_packet->index >= rx_packet->len) { + usb_free(rx_packet); + rx_packet = NULL; + } + } + return count; +} + +// discard any buffered input +void usb_serial_flush_input(void) +{ + usb_packet_t *rx; + + if (!usb_configuration) return; + if (rx_packet) { + usb_free(rx_packet); + rx_packet = NULL; + } + while (1) { + rx = usb_rx(CDC_RX_ENDPOINT); + if (!rx) break; + usb_free(rx); + } +} + +// Maximum number of transmit packets to queue so we don't starve other endpoints for memory +#define TX_PACKET_LIMIT 8 + +// When the PC isn't listening, how long do we wait before discarding data? If this is +// too short, we risk losing data during the stalls that are common with ordinary desktop +// software. If it's too long, we stall the user's program when no software is running. +#define TX_TIMEOUT_MSEC 70 + +#if F_CPU == 96000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 596) +#elif F_CPU == 48000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 428) +#elif F_CPU == 24000000 + #define TX_TIMEOUT (TX_TIMEOUT_MSEC * 262) +#endif + +// When we've suffered the transmit timeout, don't wait again until the computer +// begins accepting data. If no software is running to receive, we'll just discard +// data as rapidly as Serial.print() can generate it, until there's something to +// actually receive it. +static uint8_t transmit_previous_timeout=0; + + +// transmit a character. 0 returned on success, -1 on error +int usb_serial_putchar(uint8_t c) +{ + return usb_serial_write(&c, 1); +} + + +int usb_serial_write(const void *buffer, uint32_t size) +{ + uint32_t len; + uint32_t wait_count; + const uint8_t *src = (const uint8_t *)buffer; + uint8_t *dest; + + tx_noautoflush = 1; + while (size > 0) { + if (!tx_packet) { + wait_count = 0; + while (1) { + if (!usb_configuration) { + tx_noautoflush = 0; + return -1; + } + if (usb_tx_packet_count(CDC_TX_ENDPOINT) < TX_PACKET_LIMIT) { + tx_noautoflush = 1; + tx_packet = usb_malloc(); + if (tx_packet) break; + tx_noautoflush = 0; + } + if (++wait_count > TX_TIMEOUT || transmit_previous_timeout) { + transmit_previous_timeout = 1; + return -1; + } + yield(); + } + } + transmit_previous_timeout = 0; + len = CDC_TX_SIZE - tx_packet->index; + if (len > size) len = size; + dest = tx_packet->buf + tx_packet->index; + tx_packet->index += len; + size -= len; + while (len-- > 0) *dest++ = *src++; + if (tx_packet->index >= CDC_TX_SIZE) { + tx_packet->len = CDC_TX_SIZE; + usb_tx(CDC_TX_ENDPOINT, tx_packet); + tx_packet = NULL; + } + usb_cdc_transmit_flush_timer = TRANSMIT_FLUSH_TIMEOUT; + } + tx_noautoflush = 0; + return 0; +} + +void usb_serial_flush_output(void) +{ + if (!usb_configuration) return; + tx_noautoflush = 1; + if (tx_packet) { + usb_cdc_transmit_flush_timer = 0; + tx_packet->len = tx_packet->index; + usb_tx(CDC_TX_ENDPOINT, tx_packet); + tx_packet = NULL; + } else { + usb_packet_t *tx = usb_malloc(); + if (tx) { + usb_cdc_transmit_flush_timer = 0; + usb_tx(CDC_TX_ENDPOINT, tx); + } else { + usb_cdc_transmit_flush_timer = 1; + } + } + tx_noautoflush = 0; +} + +void usb_serial_flush_callback(void) +{ + if (tx_noautoflush) return; + if (tx_packet) { + tx_packet->len = tx_packet->index; + usb_tx(CDC_TX_ENDPOINT, tx_packet); + tx_packet = NULL; + } else { + usb_packet_t *tx = usb_malloc(); + if (tx) { + usb_tx(CDC_TX_ENDPOINT, tx); + } else { + usb_cdc_transmit_flush_timer = 1; + } + } +} + + + + + + + + + +#endif // CDC_STATUS_INTERFACE && CDC_DATA_INTERFACE diff --git a/teensy3/usb_serial.h b/teensy3/usb_serial.h new file mode 100644 index 0000000000000000000000000000000000000000..0b5c0c3048c06313e5863e4911ea3a9e5b8370c9 --- /dev/null +++ b/teensy3/usb_serial.h @@ -0,0 +1,107 @@ +/* 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 USBserial_h_ +#define USBserial_h_ + +#if defined(USB_SERIAL) || defined(USB_SERIAL_HID) + +#include <inttypes.h> + +// C language implementation +#ifdef __cplusplus +extern "C" { +#endif +int usb_serial_getchar(void); +int usb_serial_peekchar(void); +int usb_serial_available(void); +int usb_serial_read(void *buffer, uint32_t size); +void usb_serial_flush_input(void); +int usb_serial_putchar(uint8_t c); +int usb_serial_write(const void *buffer, uint32_t size); +void usb_serial_flush_output(void); +extern uint32_t usb_cdc_line_coding[2]; +extern volatile uint8_t usb_cdc_line_rtsdtr; +extern volatile uint8_t usb_cdc_transmit_flush_timer; +extern volatile uint8_t usb_configuration; +#ifdef __cplusplus +} +#endif + +#define USB_SERIAL_DTR 0x01 +#define USB_SERIAL_RTS 0x02 + + +// C++ interface +#ifdef __cplusplus +#include "Stream.h" +class usb_serial_class : public Stream +{ +public: + void begin(long) { /* TODO: call a function that tries to wait for enumeration */ }; + void end() { /* TODO: flush output and shut down USB port */ }; + virtual int available() { return usb_serial_available(); } + virtual int read() { return usb_serial_getchar(); } + virtual int peek() { return usb_serial_peekchar(); } + virtual void flush() { usb_serial_flush_output(); } // TODO: actually wait for data to leave USB... + virtual size_t write(uint8_t c) { return usb_serial_putchar(c); } + virtual size_t write(const uint8_t *buffer, size_t size) { return usb_serial_write(buffer, size); } + 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); } + using Print::write; + void send_now(void) { usb_serial_flush_output(); } + uint32_t baud(void) { return usb_cdc_line_coding[0]; } + uint8_t stopbits(void) { uint8_t b = usb_cdc_line_coding[1]; if (!b) b = 1; return b; } + uint8_t paritytype(void) { return usb_cdc_line_coding[1] >> 8; } // 0=none, 1=odd, 2=even + uint8_t numbits(void) { return usb_cdc_line_coding[1] >> 16; } + uint8_t dtr(void) { return (usb_cdc_line_rtsdtr & USB_SERIAL_DTR) ? 1 : 0; } + uint8_t rts(void) { return (usb_cdc_line_rtsdtr & USB_SERIAL_RTS) ? 1 : 0; } + operator bool() { return usb_configuration && (usb_cdc_line_rtsdtr & (USB_SERIAL_DTR | USB_SERIAL_RTS)); } + size_t readBytes(char *buffer, size_t length) { + size_t count=0; + unsigned long startMillis = millis(); + do { + count += usb_serial_read(buffer + count, length - count); + if (count >= length) return count; + } while(millis() - startMillis < _timeout); + setReadError(); + return count; + } + +}; + +extern usb_serial_class Serial; + +#endif // __cplusplus + +#endif // USB_SERIAL || USB_SERIAL_HID +#endif // USBserial_h_ diff --git a/teensy3/util/atomic.h b/teensy3/util/atomic.h new file mode 100644 index 0000000000000000000000000000000000000000..01921982751a341a02af3621a75a75ca935d3ff3 --- /dev/null +++ b/teensy3/util/atomic.h @@ -0,0 +1,71 @@ +/* +* This is port of Dean Camera's ATOMIC_BLOCK macros for AVR to ARM Cortex M3 +* v1.0 +* Mark Pendrith, Nov 27, 2012. +* +* From Mark: +* >When I ported the macros I emailed Dean to ask what attribution would be +* >appropriate, and here is his response: +* > +* >>Mark, +* >>I think it's great that you've ported the macros; consider them +* >>public domain, to do with whatever you wish. I hope you find them >useful . +* >> +* >>Cheers! +* >>- Dean +*/ + +#ifdef __arm__ +#ifndef _CORTEX_M3_ATOMIC_H_ +#define _CORTEX_M3_ATOMIC_H_ + +static __inline__ uint32_t __get_primask(void) \ +{ uint32_t primask = 0; \ + __asm__ volatile ("MRS %[result], PRIMASK\n\t":[result]"=r"(primask)::); \ + return primask; } // returns 0 if interrupts enabled, 1 if disabled + +static __inline__ void __set_primask(uint32_t setval) \ +{ __asm__ volatile ("MSR PRIMASK, %[value]\n\t""dmb\n\t""dsb\n\t""isb\n\t"::[value]"r"(setval):); + __asm__ volatile ("" ::: "memory");} + +static __inline__ uint32_t __iSeiRetVal(void) \ +{ __asm__ volatile ("CPSIE i\n\t""dmb\n\t""dsb\n\t""isb\n\t"); \ + __asm__ volatile ("" ::: "memory"); return 1; } + +static __inline__ uint32_t __iCliRetVal(void) \ +{ __asm__ volatile ("CPSID i\n\t""dmb\n\t""dsb\n\t""isb\n\t"); \ + __asm__ volatile ("" ::: "memory"); return 1; } + +static __inline__ void __iSeiParam(const uint32_t *__s) \ +{ __asm__ volatile ("CPSIE i\n\t""dmb\n\t""dsb\n\t""isb\n\t"); \ + __asm__ volatile ("" ::: "memory"); (void)__s; } + +static __inline__ void __iCliParam(const uint32_t *__s) \ +{ __asm__ volatile ("CPSID i\n\t""dmb\n\t""dsb\n\t""isb\n\t"); \ + __asm__ volatile ("" ::: "memory"); (void)__s; } + +static __inline__ void __iRestore(const uint32_t *__s) \ +{ __set_primask(*__s); __asm__ volatile ("dmb\n\t""dsb\n\t""isb\n\t"); \ + __asm__ volatile ("" ::: "memory"); } + + +#define ATOMIC_BLOCK(type) \ +for ( type, __ToDo = __iCliRetVal(); __ToDo ; __ToDo = 0 ) + +#define ATOMIC_RESTORESTATE \ +uint32_t primask_save __attribute__((__cleanup__(__iRestore))) = __get_primask() + +#define ATOMIC_FORCEON \ +uint32_t primask_save __attribute__((__cleanup__(__iSeiParam))) = 0 + +#define NONATOMIC_BLOCK(type) \ +for ( type, __ToDo = __iSeiRetVal(); __ToDo ; __ToDo = 0 ) + +#define NONATOMIC_RESTORESTATE \ +uint32_t primask_save __attribute__((__cleanup__(__iRestore))) = __get_primask() + +#define NONATOMIC_FORCEOFF \ +uint32_t primask_save __attribute__((__cleanup__(__iCliParam))) = 0 + +#endif +#endif diff --git a/teensy3/util/delay.h b/teensy3/util/delay.h new file mode 100644 index 0000000000000000000000000000000000000000..649885ebada3048a70489b963b18b881bcc0c910 --- /dev/null +++ b/teensy3/util/delay.h @@ -0,0 +1,3 @@ +#ifndef _delay_ms +#define _delay_ms(n) delay(n) +#endif diff --git a/teensy3/wiring.h b/teensy3/wiring.h new file mode 100644 index 0000000000000000000000000000000000000000..8ef6da97ad94c6ba6b3216308ee961406a4f973f --- /dev/null +++ b/teensy3/wiring.h @@ -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 <stdint.h> +#include <stdlib.h> +#include "binary.h" +#include "core_id.h" +#include "core_pins.h" + +#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 + +#ifndef M_PI +#define M_PI 3.1415926535897932384626433832795 +#endif +#ifndef M_SQRT2 +#define M_SQRT2 1.4142135623730950488016887 +#endif + +#define SERIAL 0 +#define DISPLAY 1 + +// 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 sei() __enable_irq() +#define cli() __disable_irq() +#define interrupts() __enable_irq() +#define noInterrupts() __disable_irq() + +#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; + +uint32_t pulseIn(uint8_t pin, uint8_t state, uint32_t timeout); +void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, byte val); + +//void tone(uint8_t pin, uint16_t frequency, uint32_t duration); +//void noTone(uint8_t pin); + +//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 diff --git a/teensy3/wiring_private.h b/teensy3/wiring_private.h new file mode 100644 index 0000000000000000000000000000000000000000..85d03c665e8ac12ea086727e472cd347eb7542f4 --- /dev/null +++ b/teensy3/wiring_private.h @@ -0,0 +1,20 @@ +#ifndef WiringPrivate_h +#define WiringPrivate_h + +#include <stdio.h> +#include <stdarg.h> + +#include "wiring.h" + +#ifndef cbi +#define cbi(sfr, bit) ((sfr) &= ~_BV(bit)) +#endif +#ifndef sbi +#define sbi(sfr, bit) ((sfr) |= _BV(bit)) +#endif + +typedef void (*voidFuncPtr)(void); + +#endif + + diff --git a/teensy3/yield.c b/teensy3/yield.c new file mode 100644 index 0000000000000000000000000000000000000000..06c741a6730808b943df0e0a2e6f3ae75c528b23 --- /dev/null +++ b/teensy3/yield.c @@ -0,0 +1,32 @@ +/* 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. + */ + +void yield(void) __attribute__ ((weak)); +void yield(void) {};