Compare commits

..

11 commits

Author SHA1 Message Date
c32c022d95 Updated copyright headers. 2016-02-07 05:35:08 -08:00
44f7a7ae2b serial: update the comments to reflect the LPC810. 2016-02-07 05:31:40 -08:00
8d5d6b3024 ser2neo: remap the UART pins on start.
This fixes a problem where the chip only seems to work after programming.
2016-02-07 05:30:10 -08:00
c26f3a3d19 neopixel: always write to all LEDs. 2016-02-07 05:28:11 -08:00
4ecf66daa5 build: build with LTO. Emit a mapfile. 2016-02-07 05:27:38 -08:00
ab1e6ceb2c Add a LPC81x fork using the SPI encoding idea from http://jeelabs.org/book/1450d/index.html. 2016-02-01 13:14:11 -08:00
10733b27a7 Add the LPC81x submodules. 2016-02-01 13:13:46 -08:00
612a1c082b Use the first USB COM port instead of hard coding.
Also escape '?' which is the special bootloader character.
2016-02-01 13:13:01 -08:00
Michael Hope
3ae845f68d Revert "Added the LPC810 submodules."
This reverts commit db92dbc3fb.
2016-02-01 12:12:58 -08:00
Michael Hope
db92dbc3fb Added the LPC810 submodules. 2016-02-01 12:12:09 -08:00
Michael Hope
f5f5af221a Removed the ATTINY Makefiles. 2016-02-01 12:11:59 -08:00
20 changed files with 254 additions and 299 deletions

6
.gitmodules vendored Normal file
View file

@ -0,0 +1,6 @@
[submodule "third_party/mbed"]
path = third_party/mbed
url = https://github.com/mbedmicro/mbed.git
[submodule "third_party/lpcopen"]
path = third_party/lpcopen
url = juju:~/p/git/lpcopen2

74
CMakeLists.txt Normal file
View file

@ -0,0 +1,74 @@
# Copyright 2015 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
cmake_minimum_required(VERSION 3.2)
project(ser2neo C CXX ASM)
set(LPCOPEN third_party/lpcopen)
add_library(
lpcopen
${LPCOPEN}/lpc_chip_8xx/src/acmp_8xx.c
${LPCOPEN}/lpc_chip_8xx/src/chip_8xx.c
${LPCOPEN}/lpc_chip_8xx/src/clock_8xx.c
${LPCOPEN}/lpc_chip_8xx/src/crc_8xx.c
${LPCOPEN}/lpc_chip_8xx/src/gpio_8xx.c
${LPCOPEN}/lpc_chip_8xx/src/i2c_common_8xx.c
${LPCOPEN}/lpc_chip_8xx/src/i2cm_8xx.c
${LPCOPEN}/lpc_chip_8xx/src/i2cs_8xx.c
${LPCOPEN}/lpc_chip_8xx/src/iap.c
${LPCOPEN}/lpc_chip_8xx/src/iocon_8xx.c
${LPCOPEN}/lpc_chip_8xx/src/irc_8xx.c
${LPCOPEN}/lpc_chip_8xx/src/pinint_8xx.c
${LPCOPEN}/lpc_chip_8xx/src/pmu_8xx.c
${LPCOPEN}/lpc_chip_8xx/src/ring_buffer.c
${LPCOPEN}/lpc_chip_8xx/src/sct_8xx.c
${LPCOPEN}/lpc_chip_8xx/src/sct_pwm_8xx.c
${LPCOPEN}/lpc_chip_8xx/src/spi_8xx.c
${LPCOPEN}/lpc_chip_8xx/src/spim_8xx.c
${LPCOPEN}/lpc_chip_8xx/src/spis_8xx.c
${LPCOPEN}/lpc_chip_8xx/src/stopwatch_8xx.c
${LPCOPEN}/lpc_chip_8xx/src/swm_8xx.c
${LPCOPEN}/lpc_chip_8xx/src/syscon_8xx.c
${LPCOPEN}/lpc_chip_8xx/src/sysinit_8xx.c
${LPCOPEN}/lpc_chip_8xx/src/uart_8xx.c
${LPCOPEN}/lpc_chip_8xx/src/wkt_8xx.c
${LPCOPEN}/lpc_chip_8xx/src/wwdt_8xx.c
)
set(MBED_LPC81X third_party/mbed/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC81X)
set(STARTUP ${MBED_LPC81X}/TOOLCHAIN_GCC_ARM/startup_LPC81X.S)
set(LDSCRIPT ${MBED_LPC81X}/TARGET_LPC810/TOOLCHAIN_GCC_ARM/LPC810.ld)
include_directories(
${LPCOPEN}
${LPCOPEN}/lpc_chip_8xx/inc
.
)
add_executable(
ser2neo
ser2neo.cc
serial.cc
neopixel.cc
retarget.cc
${STARTUP}
)
target_link_libraries(ser2neo lpcopen)
set(EXTRA_FLAGS "-Wall -Os -flto --specs=nano.specs --specs=nosys.specs -DCORE_M0PLUS -Wl,-T${CMAKE_SOURCE_DIR}/${LDSCRIPT},-gc-sections -fno-builtin-printf -fno-builtin-putchar -fno-builtin-puts -Wl,-Map,ser2neo.map,--cref")
set(CMAKE_C_FLAGS "${COMMON_FLAGS} ${RUNTIME_FLAGS} ${EXTRA_FLAGS} -Wno-incompatible-pointer-types")
set(CMAKE_CXX_FLAGS "${COMMON_FLAGS} ${RUNTIME_FLAGS} ${EXTRA_FLAGS} -fno-exceptions -fno-rtti -std=gnu++14 -save-temps=obj")

View file

@ -1,16 +0,0 @@
# Copyright 2015 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
include attiny85.mk
include avr.mk

View file

@ -1,16 +0,0 @@
# Copyright 2015 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
DEVICE = attiny85
CLOCK = 16500000

47
avr.mk
View file

@ -1,47 +0,0 @@
# Copyright 2015 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
APP ?= $(notdir $(PWD))
VERSION ?= $(shell date +%Y%m%d)+git$(shell git describe --always)
SRC = $(wildcard *.cc)
OBJ = $(SRC:%.cc=%.o)
CROSS_COMPILE = avr-
CC = $(CROSS_COMPILE)gcc
CXX = $(CROSS_COMPILE)g++
CFLAGS = -Os -DF_CPU=$(CLOCK) -mmcu=$(DEVICE) -Wall
CXXFLAGS = $(CFLAGS) -std=gnu++1y
all: $(APP).hex
usb-flash: $(APP).hex
sudo $(HOME)/bin/micronucleus --run $<
%.elf: $(OBJ)
$(CXX) $(CXXFLAGS) -o $@ $(OBJ)
$(CROSS_COMPILE)size -d $@
%.hex: %.elf
avr-objcopy -j .text -j .data -O ihex $< $@
clean:
rm -f $(APP).hex $(APP).elf $(OBJ) *~ *.ii
dist:
rm -rf tmp
mkdir tmp
git archive --prefix=$(APP)-$(VERSION)/ HEAD | gzip > tmp/$(APP)-$(VERSION).tar.gz
cd tmp && git clone $$(readlink -f ..) $(APP)
$(MAKE) -C tmp/$(APP)

19
board.h Normal file
View file

@ -0,0 +1,19 @@
// Copyright 2015 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#pragma once
#define CONFIG_MAIN_FREQ 12'000'000
#define CONFIG_SYS_FREQ 12'000'000

View file

@ -20,7 +20,7 @@ import colorsys
def main():
port = ser2neo.open_port('/dev/ttyUSB0')
port = ser2neo.open_port()
neo = ser2neo.NeoPixels(port)
offset = 0

View file

@ -23,7 +23,7 @@ def angle2idx(neo, angle, limit):
def main():
port = ser2neo.open_port('/dev/ttyUSB0')
port = ser2neo.open_port()
neo = ser2neo.NeoPixels(port)
anim = ser2neo.Animator()

View file

@ -24,7 +24,7 @@ def angle2idx(neo, angle, limit):
def main():
port = ser2neo.open_port('/dev/ttyUSB0')
port = ser2neo.open_port()
neo = ser2neo.NeoPixels(port)
random.seed()

View file

@ -18,7 +18,7 @@ import time
def main():
port = ser2neo.open_port('/dev/ttyUSB0')
port = ser2neo.open_port()
neo = ser2neo.NeoPixels(port)
at = 0

View file

@ -16,6 +16,7 @@
from __future__ import division
import serial
import serial.tools.list_ports
import time
import struct
@ -33,18 +34,15 @@ class RGB:
def __add__(self, other):
"""Componentwise addition."""
return RGB(*list(
_clip(x + y) for x, y in zip(self.rgb, other.rgb)))
return RGB(*list(_clip(x + y) for x, y in zip(self.rgb, other.rgb)))
def __mul__(self, level):
"""Scalar multiplier."""
return RGB(*(
_clip(x * level) for x in self.rgb))
return RGB(*(_clip(x * level) for x in self.rgb))
def __truediv__(self, level):
"""Scalar division."""
return RGB(*(
_clip(x / level) for x in self.rgb))
return RGB(*(_clip(x / level) for x in self.rgb))
__div__ = __truediv__
@ -64,17 +62,28 @@ class Colour:
def _escape(buf):
EOL, ESC = ord('\r'), ord('+')
special = set((EOL, ESC, ord('?')))
for ch in buf:
if ch == EOL or ch == ESC:
if ch in special:
yield ESC
yield ch ^ ESC
else:
yield ch
def open_port(name):
def first_serial():
for info in serial.tools.list_ports.comports():
device = info[0]
if 'USB' in device or 'ACM' in device:
return device
return '/dev/ttyUSB0'
def open_port(name=None):
"""Open the serial connection to the adaptor."""
if name is None:
name = first_serial()
return serial.Serial(name, 57600, timeout=0.02)
@ -108,8 +117,7 @@ class NeoPixels:
buf = b'l'
for rgb in self.leds:
rgb = rgb * self.brightness
buf += struct.pack('BBB',
int(_clip(rgb.rgb[1] * 0xFF, 0xFF)),
buf += struct.pack('BBB', int(_clip(rgb.rgb[1] * 0xFF, 0xFF)),
int(_clip(rgb.rgb[0] * 0xFF, 0xFF)),
int(_clip(rgb.rgb[2] * 0xFF, 0xFF)))
if str == bytes:

View file

@ -17,7 +17,7 @@ import ser2neo
def main():
port = ser2neo.open_port('/dev/ttyUSB0')
port = ser2neo.open_port()
neo = ser2neo.NeoPixels(port)
p0 = 0

View file

@ -15,66 +15,82 @@
// limitations under the License.
//
#include "neopixel.h"
#include "serial.h"
#include "chip.h"
#include <avr/io.h>
#include <avr/interrupt.h>
#include <string.h>
#include <cstring>
#define CFG_ENABLE (1<<0)
#define CFG_MASTER (1<<2)
const uint16_t NeoPixel::bits_[] = {
0b100100100100,
0b100100100110,
0b100100110100,
0b100100110110,
0b100110100100,
0b100110100110,
0b100110110100,
0b100110110110,
0b110100100100,
0b110100100110,
0b110100110100,
0b110100110110,
0b110110100100,
0b110110100110,
0b110110110100,
0b110110110110,
};
extern Serial serial;
/// Initialise the hardware.
void NeoPixel::init() {
DDRB |= _BV(1);
TCCR0A = _BV(WGM01) | _BV(WGM00) | _BV(COM0B1) | _BV(COM0B0);
TCCR0B = _BV(WGM02) | _BV(CS00);
clear();
static_assert(Reload > 15, "Inter-bit time is probably too short.");
OCR0A = Reload;
OCR0B = Low;
LPC_FMC->FLASHCFG = 0; // 1 wait state instead of 1
LPC_SWM->PINENABLE0 |= 1<<2; // disable SWCLK
LPC_SWM->PINASSIGN[4] = 0xFFFFFF03UL; // SPI0_MOSI 3
/* Enable SPI0 clock */
LPC_SYSCON->SYSAHBCLKCTRL |= (1<<11);
LPC_SYSCON->PRESETCTRL &= ~(1<<0);
LPC_SYSCON->PRESETCTRL |= (1<<0);
// 2.4 MHz, i.e. 12 MHz / 5
LPC_SPI0->DIV = 4;
LPC_SPI0->DLY = 0;
LPC_SPI0->TXCTRL = SPI_TXDATCTL_FLEN(12-1) | SPI_TXDATCTL_RXIGNORE;
LPC_SPI0->CFG = CFG_MASTER;
LPC_SPI0->CFG |= CFG_ENABLE;
}
/// Set all the LEDs to off and restart at the first LED.
void NeoPixel::clear() {
p_ = bits_;
memset(bits_, Low, sizeof(bits_));
p_ = bytes_;
memset(bytes_, 0, sizeof(bytes_));
}
/// Append a byte to the stream.
void NeoPixel::append(uint8_t b) {
if (p_ <= (bits_ + sizeof(bits_) - Tail - BitsPerColour)) {
for (auto i = 0; i < BitsPerColour; i++) {
*p_++ = (b & 0x80) ? High : Low;
b <<= 1;
}
if (p_ <= (bytes_ + sizeof(bytes_))) {
*p_++ = b;
}
}
void NeoPixel::send(uint16_t cmd) {
while ((LPC_SPI0->STAT & SPI_STAT_TXRDY) == 0) {}
LPC_SPI0->TXDAT = cmd;
}
/// Write to the LEDs.
void NeoPixel::write() {
bits_[sizeof(bits_) - 1] = Stop;
uint8_t *p = bits_;
uint8_t *pend = bits_ + sizeof(bits_);
cli();
OCR0B = Stop;
TIFR |= _BV(OCF0A);
while (!(TIFR & _BV(OCF0A))) {
send(0);
send(0);
for (auto p = bytes_; p < bytes_ + sizeof(bytes_); p++) {
auto ch = *p;
send(bits_[ch >> 4]);
send(bits_[ch & 0xF]);
}
TIFR |= _BV(OCF0A);
while (!(TIFR & _BV(OCF0A))) {
}
OCR0B = *p++;
for (; p != pend; p++) {
while (!(TIFR & _BV(OCF0A))) {
}
OCR0B = *p;
TIFR |= _BV(OCF0A);
}
OCR0B = Stop;
sei();
}

View file

@ -35,15 +35,11 @@ class NeoPixel {
private:
static const int MaxLEDs = 16;
static const int BitsPerColour = 8;
static const int ColoursPerLED = 3;
static const int Tail = 2;
static const uint8_t Reload = F_CPU / 800000;
static const uint8_t Low = Reload * 2 / 3;
static const uint8_t High = Reload - Low;
static const uint8_t Stop = 0xFF;
void send(uint16_t ch);
uint8_t* p_;
uint8_t bits_[MaxLEDs * ColoursPerLED * BitsPerColour + Tail];
uint8_t bytes_[MaxLEDs * ColoursPerLED];
static const uint16_t bits_[];
};

21
retarget.cc Normal file
View file

@ -0,0 +1,21 @@
// Copyright 2015 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "chip.h"
extern "C" void _exit(int code) {
for (;;) {
__WFI();
}
}

View file

@ -14,7 +14,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include <avr/interrupt.h>
#include <string.h>
#include "neopixel.h"
@ -43,6 +42,22 @@ class Ser2Neo {
Serial serial;
};
extern "C" void SystemInit() {
Chip_SYSCTL_PowerUp(SYSCTL_SLPWAKE_IRC_PD);
Chip_Clock_SetSystemPLLSource(SYSCTL_PLLCLKSRC_IRC);
Chip_Clock_SetMainClockSource(SYSCTL_MAINCLKSRC_IRC);
Chip_FMC_SetFLASHAccess(FLASHTIM_20MHZ_CPU);
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_IOCON);
Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_SWM);
Chip_SWM_DisableFixedPin(SWM_FIXED_SWCLK);
Chip_SWM_DisableFixedPin(SWM_FIXED_SWDIO);
Chip_SWM_MovablePinAssign(SWM_U0_TXD_O, 4);
Chip_SWM_MovablePinAssign(SWM_U0_RXD_I, 0);
}
/// Initialise the hardware.
void Ser2Neo::init() {
leds.init();
@ -96,8 +111,6 @@ void Ser2Neo::send_ok(const char* msg) {
/// Run the main loop. Process and run commands.
void Ser2Neo::run() {
sei();
serial.putstr("READY\n");
for (;;) {
@ -123,11 +136,11 @@ void Ser2Neo::run() {
}
}
static Ser2Neo ser2led;
static Ser2Neo ser2neo;
int main() {
ser2led.init();
ser2led.run();
ser2neo.init();
ser2neo.run();
return 0;
}

124
serial.cc
View file

@ -1,4 +1,4 @@
// Half-duplex interrupt based serial port.
// Blocking serial port.
//
// Copyright 2015 Google Inc.
//
@ -16,107 +16,32 @@
//
#include "serial.h"
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
Serial* Serial::instance_;
#define _clear(port, pin) port &= ~_BV(pin)
#define _set(port, pin) port |= _BV(pin)
#include "board.h"
/// Initialise the hardware.
void Serial::init() {
state_ = Idle;
rx_full_ = false;
Chip_UART_Init(LPC_USART0);
Chip_Clock_SetUARTClockDiv(ClockDiv);
instance_ = this;
handle_ = LPC_UARTD_API->uart_setup(
LPC_USART0_BASE, static_cast<uint8_t*>(static_cast<void*>(mem_)));
// Set up the GPIOs.
_set(DDRB, TxPin);
_set(PORTB, TxPin);
_clear(DDRB, RxPin);
UART_CONFIG_T cfg = {
.sys_clk_in_hz = CONFIG_SYS_FREQ / ClockDiv,
.baudrate_in_hz = 115200,
.config = 1,
.sync_mod = 0,
.error_en = NO_ERR_EN,
};
// Set up the timer.
static_assert(BitTime > 50, "BitTime is too short");
static_assert(BitTime < 255*2/3, "BitTime may overflow");
OCR1C = BitTime;
TCCR1 = _BV(CTC1) | _BV(PWM1A);
static_assert(Prescale == 2, "Mismatched prescaler");
TCCR1 |= _BV(CS11);
// Set up the pin change interrupt.
PCMSK = _BV(RxPin);
_set(GIMSK, PCIE);
}
/// Handle the pin change interrupt by starting receive.
void Serial::pcint0() {
_clear(PCMSK, RxPin);
_clear(TIMSK, TOV1); // PENDING
OCR1C = (BitTime / 2 * 3) - (PCIntDelay / Prescale);
TCNT1 = 0;
_set(TIFR, TOV1);
state_ = Receive;
bits_ = 8;
_set(TIMSK, TOV1);
}
/// Handle the timer overflow interrupt by doing the next bit.
inline void Serial::timer1ovf() {
switch (state_) {
case Receive: {
auto got = PINB;
OCR1C = BitTime;
if (bits_ > 0) {
rxing_ >>= 1;
if (got & _BV(RxPin)) {
rxing_ |= 0x80;
}
bits_--;
} else {
state_ = Idle;
rxed_ = rxing_;
rx_full_ = true;
}
break;
}
case Transmit:
if (txing_ & 1) {
_set(PORTB, TxPin);
} else {
_clear(PORTB, TxPin);
}
txing_ >>= 1;
if (--bits_ == 0) {
state_ = Idle;
}
break;
default:
break;
}
if (state_ == Idle) {
_clear(TIMSK, TOV1);
_set(PCMSK, RxPin);
}
auto frg = LPC_UARTD_API->uart_init(handle_, &cfg);
Chip_SYSCTL_SetUSARTFRGDivider(0xFF);
Chip_SYSCTL_SetUSARTFRGMultiplier(frg);
}
/// Wait until the hardware is free then start the transmit.
void Serial::putch(uint8_t ch) {
while (state_ != Idle) {
sleep_cpu();
}
state_ = Transmit;
txing_ = (ch << 1) | 0xFE00;
bits_ = 10;
TCNT1 = 0;
_set(TIMSK, TOV1);
LPC_UARTD_API->uart_put_char(handle_, ch);
}
/// Send a string.
@ -128,18 +53,5 @@ void Serial::putstr(const char* str) {
/// Wait until a character is received, then return it.
uint8_t Serial::getch() {
while (!rx_full_) {
sleep_cpu();
}
uint8_t ch = rxed_;
rx_full_ = false;
return ch;
return LPC_UARTD_API->uart_get_char(handle_);
}
inline void Serial::pcint0_bounce() { instance_->pcint0(); }
inline void Serial::timer1ovf_bounce() { instance_->timer1ovf(); }
ISR(TIMER1_OVF_vect) { Serial::timer1ovf_bounce(); }
ISR(PCINT0_vect) { Serial::pcint0_bounce(); }

View file

@ -1,4 +1,4 @@
// Half-duplex interrupt based serial port.
// Blocking serial port.
//
// Copyright 2015 Google Inc.
//
@ -18,9 +18,9 @@
#include <stdint.h>
/// Half-duplex interrupt based serial port.
///
/// Loosely based on AVR304.
#include "chip.h"
/// Blocking serial port.
///
class Serial {
public:
@ -32,41 +32,8 @@ class Serial {
uint8_t getch();
private:
enum State : uint8_t {
Idle,
Receive,
Transmit,
};
static const int ClockDiv = 1;
// Note that these are all specific to an ATTINY85 USB board.
static const int RxPin = 0;
static const int TxPin = 2;
static const auto Prescale = 2;
static const auto Baud = 57600;
static const auto BitTime = F_CPU / Prescale / Baud - 1;
// Total number of clocks taken to service the pin change
// interrupt and start the receive. Use this to reduce the first
// bit-and-a-half time so sampling occurs half way through the
// first bit.
static const uint8_t PCIntDelay = 140;
void pcint0();
void timer1ovf();
volatile State state_;
uint8_t rxing_;
// Remaining number of bits to send or receive.
uint8_t bits_;
volatile uint8_t rxed_;
volatile bool rx_full_;
volatile uint16_t txing_;
static Serial* instance_;
public:
// Interrupt handler entry points.
static void pcint0_bounce();
static void timer1ovf_bounce();
uint32_t mem_[40 / sizeof(uint32_t)];
UART_HANDLE_T* handle_;
};

1
third_party/lpcopen vendored Submodule

@ -0,0 +1 @@
Subproject commit 478fc8fe6087ec8c9eebff491f0324c8dd38db87

1
third_party/mbed vendored Submodule

@ -0,0 +1 @@
Subproject commit 216fca1081a128e31a6a0b6683f6fe6f511ba647