1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-22 21:23:07 +03:00

Fix build errors

This commit is contained in:
Ivan Grokhotkov 2014-11-21 12:15:50 +03:00
parent 09e27637dc
commit 15b434f5e2
8 changed files with 335 additions and 434 deletions

View File

@ -138,27 +138,6 @@ void loop(void);
// greater than 255, so we can't store them in uint8_t's. // greater than 255, so we can't store them in uint8_t's.
#define PROGMEM #define PROGMEM
extern const uint16_t PROGMEM port_to_mode_PGM[];
extern const uint16_t PROGMEM port_to_input_PGM[];
extern const uint16_t PROGMEM port_to_output_PGM[];
extern const uint8_t PROGMEM digital_pin_to_port_PGM[];
// extern const uint8_t PROGMEM digital_pin_to_bit_PGM[];
extern const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[];
extern const uint8_t PROGMEM digital_pin_to_timer_PGM[];
// Get the bit location within the hardware port of the given virtual pin.
// This comes from the pins_*.c file for the active board configuration.
//
// These perform slightly better as macros compared to inline functions
//
#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )
#define digitalPinToBitMask(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM + (P) ) )
#define digitalPinToTimer(P) ( pgm_read_byte( digital_pin_to_timer_PGM + (P) ) )
#define analogInPinToBit(P) (P)
#define portOutputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_output_PGM + (P))) )
#define portInputRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_input_PGM + (P))) )
#define portModeRegister(P) ( (volatile uint8_t *)( pgm_read_word( port_to_mode_PGM + (P))) )
#define NOT_A_PIN 0 #define NOT_A_PIN 0
#define NOT_A_PORT 0 #define NOT_A_PORT 0
@ -208,14 +187,8 @@ extern const uint8_t PROGMEM digital_pin_to_timer_PGM[];
#include "WCharacter.h" #include "WCharacter.h"
#include "WString.h" #include "WString.h"
/*
#include "HardwareSerial.h"
#include "USBAPI.h" #include "HardwareSerial.h"
#if defined(HAVE_HWSERIAL0) && defined(HAVE_CDCSERIAL)
#error "Targets with both UART0 and CDC serial not supported"
#endif
*/
uint16_t makeWord(uint16_t w); uint16_t makeWord(uint16_t w);
uint16_t makeWord(byte h, byte l); uint16_t makeWord(byte h, byte l);

View File

@ -1,25 +1,25 @@
/* /*
HardwareSerial.cpp - Hardware serial library for Wiring HardwareSerial.cpp - Hardware serial library for Wiring
Copyright (c) 2006 Nicholas Zambetti. All right reserved. Copyright (c) 2006 Nicholas Zambetti. All right reserved.
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version. 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, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details. Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Modified 23 November 2006 by David A. Mellis Modified 23 November 2006 by David A. Mellis
Modified 28 September 2010 by Mark Sproul Modified 28 September 2010 by Mark Sproul
Modified 14 August 2012 by Alarus Modified 14 August 2012 by Alarus
Modified 3 December 2013 by Matthijs Kooijman Modified 3 December 2013 by Matthijs Kooijman
*/ */
#include <stdlib.h> #include <stdlib.h>
@ -28,225 +28,305 @@
#include <inttypes.h> #include <inttypes.h>
#include "Arduino.h" #include "Arduino.h"
extern "C" {
#include "osapi.h"
#include "ets_sys.h"
#include "mem.h"
#include "uart_register.h"
#include "user_interface.h"
}
#include "HardwareSerial.h" #include "HardwareSerial.h"
#include "HardwareSerial_private.h"
// this next line disables the entire HardwareSerial.cpp, typedef void (*uart_rx_handler_t)(char);
// this is so I can support Attiny series and any other chip without a uart
#if defined(HAVE_HWSERIAL0) || defined(HAVE_HWSERIAL1) || defined(HAVE_HWSERIAL2) || defined(HAVE_HWSERIAL3)
// SerialEvent functions are weak, so when the user doesn't define them, uart_t* uart0_init(int baud_rate, uart_rx_handler_t rx_handler);
// the linker just sets their address to 0 (which is checked below). void uart0_set_baudrate(uart_t* uart, int baud_rate);
// The Serialx_available is just a wrapper around Serialx.available(), int uart0_get_baudrate(uart_t* uart);
// but we can refer to it weakly so we don't pull in the entire void uart0_uninit(uart_t* uart);
// HardwareSerial instance if the user doesn't also refer to it. void uart0_transmit(uart_t* uart, const char* buf, size_t size); // may block on TX fifo
#if defined(HAVE_HWSERIAL0) void uart0_wait_for_transmit(uart_t* uart);
void serialEvent() __attribute__((weak)); void uart0_transmit_char(uart_t* uart, char c); // does not block, but character will be lost if FIFO is full
bool Serial0_available() __attribute__((weak));
#endif
#if defined(HAVE_HWSERIAL1) void uart_set_debug(int enabled);
void serialEvent1() __attribute__((weak)); int uart_get_debug();
bool Serial1_available() __attribute__((weak));
#endif
#if defined(HAVE_HWSERIAL2) struct uart_
void serialEvent2() __attribute__((weak));
bool Serial2_available() __attribute__((weak));
#endif
#if defined(HAVE_HWSERIAL3)
void serialEvent3() __attribute__((weak));
bool Serial3_available() __attribute__((weak));
#endif
void serialEventRun(void)
{ {
#if defined(HAVE_HWSERIAL0) int baud_rate;
if (Serial0_available && serialEvent && Serial0_available()) serialEvent(); uart_rx_handler_t rx_handler;
#endif };
#if defined(HAVE_HWSERIAL1)
if (Serial1_available && serialEvent1 && Serial1_available()) serialEvent1();
#endif
#if defined(HAVE_HWSERIAL2) #define UART_TX_FIFO_SIZE 0x7f
if (Serial2_available && serialEvent2 && Serial2_available()) serialEvent2();
#endif void uart0_rx_handler(uart_t* uart)
#if defined(HAVE_HWSERIAL3) {
if (Serial3_available && serialEvent3 && Serial3_available()) serialEvent3(); if (READ_PERI_REG(UART_INT_ST(0)) & UART_RXFIFO_FULL_INT_ST)
#endif {
while(true)
{
int rx_count = (READ_PERI_REG(UART_STATUS(0)) >> UART_RXFIFO_CNT_S) & UART_RXFIFO_CNT;
if (!rx_count)
break;
for(int cnt = 0; cnt < rx_count; ++cnt)
{
char c = READ_PERI_REG(UART_FIFO(0)) & 0xFF;
(*uart->rx_handler)(c);
}
}
WRITE_PERI_REG(UART_INT_CLR(0), UART_RXFIFO_FULL_INT_CLR);
}
} }
// Actual interrupt handlers ////////////////////////////////////////////////////////////// void uart0_wait_for_tx_fifo(size_t size_needed)
void HardwareSerial::_tx_udr_empty_irq(void)
{ {
// If interrupts are enabled, there must be more data in the output while (true)
// buffer. Send the next byte {
unsigned char c = _tx_buffer[_tx_buffer_tail]; size_t tx_count = (READ_PERI_REG(UART_STATUS(0)) >> UART_TXFIFO_CNT_S) & UART_TXFIFO_CNT;
_tx_buffer_tail = (_tx_buffer_tail + 1) % SERIAL_TX_BUFFER_SIZE; if (tx_count <= (UART_TX_FIFO_SIZE - size_needed))
break;
*_udr = c; }
// clear the TXC bit -- "can be cleared by writing a one to its bit
// location". This makes sure flush() won't return until the bytes
// actually got written
sbi(*_ucsra, TXC0);
if (_tx_buffer_head == _tx_buffer_tail) {
// Buffer empty, so disable interrupts
cbi(*_ucsrb, UDRIE0);
}
} }
// Public Methods ////////////////////////////////////////////////////////////// void uart0_wait_for_transmit(uart_t* uart)
{
uart0_wait_for_tx_fifo(UART_TX_FIFO_SIZE);
}
void uart0_transmit_char(uart_t* uart, char c)
{
WRITE_PERI_REG(UART_FIFO(0), c);
}
void uart0_transmit(uart_t* uart, const char* buf, size_t size)
{
while (size)
{
size_t part_size = (size > UART_TX_FIFO_SIZE) ? UART_TX_FIFO_SIZE : size;
size -= part_size;
uart0_wait_for_tx_fifo(part_size);
for(;part_size;--part_size, ++buf)
WRITE_PERI_REG(UART_FIFO(0), *buf);
}
}
void uart0_flush(uart_t* uart)
{
SET_PERI_REG_MASK(UART_CONF0(0), UART_RXFIFO_RST | UART_TXFIFO_RST);
CLEAR_PERI_REG_MASK(UART_CONF0(0), UART_RXFIFO_RST | UART_TXFIFO_RST);
}
void uart0_interrupt_enable(uart_t* uart)
{
WRITE_PERI_REG(UART_INT_CLR(0), 0x1ff);
ETS_UART_INTR_ATTACH(&uart0_rx_handler, uart);
SET_PERI_REG_MASK(UART_INT_ENA(0), UART_RXFIFO_FULL_INT_ENA);
ETS_UART_INTR_ENABLE();
}
void uart0_interrupt_disable(uart_t* uart)
{
SET_PERI_REG_MASK(UART_INT_ENA(0), 0);
ETS_UART_INTR_DISABLE();
}
void uart0_set_baudrate(uart_t* uart, int baud_rate)
{
uart->baud_rate = baud_rate;
uart_div_modify(0, UART_CLK_FREQ / (uart->baud_rate));
}
int uart0_get_baudrate(uart_t* uart)
{
return uart->baud_rate;
}
uart_t* uart0_init(int baudrate, uart_rx_handler_t rx_handler)
{
uart_t* uart = (uart_t*) os_malloc(sizeof(uart_t));
uart->rx_handler = rx_handler;
PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U);
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD);
uart0_set_baudrate(uart, baudrate);
WRITE_PERI_REG(UART_CONF0(0), 0x3 << UART_BIT_NUM_S); // 8n1
uart0_flush(uart);
uart0_interrupt_enable(uart);
WRITE_PERI_REG(UART_CONF1(0), ((0x01 & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S));
return uart;
}
void uart0_uninit(uart_t* uart)
{
uart0_interrupt_disable(uart);
// TODO: revert pin functions
os_free(uart);
}
void
uart_ignore_char(char c)
{
}
void
uart_write_char(char c)
{
if (c == '\n')
WRITE_PERI_REG(UART_FIFO(0), '\r');
WRITE_PERI_REG(UART_FIFO(0), c);
}
int s_uart_debug_enabled = 1;
void uart_set_debug(int enabled)
{
s_uart_debug_enabled = enabled;
if (enabled)
ets_install_putc1((void *)&uart_write_char);
else
ets_install_putc1((void *)&uart_ignore_char);
}
int uart_get_debug()
{
return s_uart_debug_enabled;
}
HardwareSerial Serial;
void serial_rx_handler(char c)
{
Serial._rx_complete_irq(c);
}
void HardwareSerial::begin(unsigned long baud, byte config) void HardwareSerial::begin(unsigned long baud, byte config)
{ {
// Try u2x mode first _uart = uart0_init(baud, &serial_rx_handler);
uint16_t baud_setting = (F_CPU / 4 / baud - 1) / 2;
*_ucsra = 1 << U2X0;
// hardcoded exception for 57600 for compatibility with the bootloader
// shipped with the Duemilanove and previous boards and the firmware
// on the 8U2 on the Uno and Mega 2560. Also, The baud_setting cannot
// be > 4095, so switch back to non-u2x mode if the baud rate is too
// low.
if (((F_CPU == 16000000UL) && (baud == 57600)) || (baud_setting >4095))
{
*_ucsra = 0;
baud_setting = (F_CPU / 8 / baud - 1) / 2;
}
// assign the baud_setting, a.k.a. ubrr (USART Baud Rate Register)
*_ubrrh = baud_setting >> 8;
*_ubrrl = baud_setting;
_written = false;
//set the data bits, parity, and stop bits
#if defined(__AVR_ATmega8__)
config |= 0x80; // select UCSRC register (shared with UBRRH)
#endif
*_ucsrc = config;
sbi(*_ucsrb, RXEN0);
sbi(*_ucsrb, TXEN0);
sbi(*_ucsrb, RXCIE0);
cbi(*_ucsrb, UDRIE0);
} }
void HardwareSerial::end() void HardwareSerial::end()
{ {
// wait for transmission of outgoing data uart0_uninit(_uart);
while (_tx_buffer_head != _tx_buffer_tail)
;
cbi(*_ucsrb, RXEN0);
cbi(*_ucsrb, TXEN0);
cbi(*_ucsrb, RXCIE0);
cbi(*_ucsrb, UDRIE0);
// clear any received data
_rx_buffer_head = _rx_buffer_tail;
} }
int HardwareSerial::available(void) int HardwareSerial::available(void)
{ {
return ((unsigned int)(SERIAL_RX_BUFFER_SIZE + _rx_buffer_head - _rx_buffer_tail)) % SERIAL_RX_BUFFER_SIZE; return ((unsigned int)(SERIAL_RX_BUFFER_SIZE + _rx_buffer_head - _rx_buffer_tail)) % SERIAL_RX_BUFFER_SIZE;
} }
int HardwareSerial::peek(void) int HardwareSerial::peek(void)
{ {
if (_rx_buffer_head == _rx_buffer_tail) { if (_rx_buffer_head == _rx_buffer_tail) {
return -1; return -1;
} else { } else {
return _rx_buffer[_rx_buffer_tail]; return _rx_buffer[_rx_buffer_tail];
} }
} }
int HardwareSerial::read(void) int HardwareSerial::read(void)
{ {
// if the head isn't ahead of the tail, we don't have any characters // if the head isn't ahead of the tail, we don't have any characters
if (_rx_buffer_head == _rx_buffer_tail) { if (_rx_buffer_head == _rx_buffer_tail) {
return -1; return -1;
} else { } else {
unsigned char c = _rx_buffer[_rx_buffer_tail]; unsigned char c = _rx_buffer[_rx_buffer_tail];
_rx_buffer_tail = (rx_buffer_index_t)(_rx_buffer_tail + 1) % SERIAL_RX_BUFFER_SIZE; _rx_buffer_tail = (rx_buffer_index_t)(_rx_buffer_tail + 1) % SERIAL_RX_BUFFER_SIZE;
return c; return c;
} }
} }
int HardwareSerial::availableForWrite(void) int HardwareSerial::availableForWrite(void)
{ {
#if (SERIAL_TX_BUFFER_SIZE>256) tx_buffer_index_t head = _tx_buffer_head;
uint8_t oldSREG = SREG; tx_buffer_index_t tail = _tx_buffer_tail;
cli(); if (head >= tail) return SERIAL_TX_BUFFER_SIZE - 1 - head + tail;
#endif return tail - head - 1;
tx_buffer_index_t head = _tx_buffer_head;
tx_buffer_index_t tail = _tx_buffer_tail;
#if (SERIAL_TX_BUFFER_SIZE>256)
SREG = oldSREG;
#endif
if (head >= tail) return SERIAL_TX_BUFFER_SIZE - 1 - head + tail;
return tail - head - 1;
} }
void HardwareSerial::flush() void HardwareSerial::flush()
{ {
// If we have never written a byte, no need to flush. This special if (!_written)
// case is needed since there is no way to force the TXC (transmit return;
// complete) bit to 1 during initialization
if (!_written)
return;
while (bit_is_set(*_ucsrb, UDRIE0) || bit_is_clear(*_ucsra, TXC0)) {
if (bit_is_clear(SREG, SREG_I) && bit_is_set(*_ucsrb, UDRIE0))
// Interrupts are globally disabled, but the DR empty
// interrupt should be enabled, so poll the DR empty flag to
// prevent deadlock
if (bit_is_set(*_ucsra, UDRE0))
_tx_udr_empty_irq();
}
// If we get here, nothing is queued anymore (DRIE is disabled) and
// the hardware finished tranmission (TXC is set).
} }
size_t HardwareSerial::write(uint8_t c) size_t HardwareSerial::write(uint8_t c)
{ {
// If the buffer and the data register is empty, just write the byte WRITE_PERI_REG(UART_FIFO(0), c);
// to the data register and be done. This shortcut helps // // If the buffer and the data register is empty, just write the byte
// significantly improve the effective datarate at high (> // // to the data register and be done. This shortcut helps
// 500kbit/s) bitrates, where interrupt overhead becomes a slowdown. // // significantly improve the effective datarate at high (>
if (_tx_buffer_head == _tx_buffer_tail && bit_is_set(*_ucsra, UDRE0)) { // // 500kbit/s) bitrates, where interrupt overhead becomes a slowdown.
*_udr = c; // if (_tx_buffer_head == _tx_buffer_tail && bit_is_set(*_ucsra, UDRE0)) {
sbi(*_ucsra, TXC0); // *_udr = c;
return 1; // sbi(*_ucsra, TXC0);
} // return 1;
tx_buffer_index_t i = (_tx_buffer_head + 1) % SERIAL_TX_BUFFER_SIZE; // }
// tx_buffer_index_t i = (_tx_buffer_head + 1) % SERIAL_TX_BUFFER_SIZE;
// If the output buffer is full, there's nothing for it other than to // // If the output buffer is full, there's nothing for it other than to
// wait for the interrupt handler to empty it a bit // // wait for the interrupt handler to empty it a bit
while (i == _tx_buffer_tail) { // while (i == _tx_buffer_tail) {
if (bit_is_clear(SREG, SREG_I)) { // if (bit_is_clear(SREG, SREG_I)) {
// Interrupts are disabled, so we'll have to poll the data // // Interrupts are disabled, so we'll have to poll the data
// register empty flag ourselves. If it is set, pretend an // // register empty flag ourselves. If it is set, pretend an
// interrupt has happened and call the handler to free up // // interrupt has happened and call the handler to free up
// space for us. // // space for us.
if(bit_is_set(*_ucsra, UDRE0)) // if(bit_is_set(*_ucsra, UDRE0))
_tx_udr_empty_irq(); // _tx_udr_empty_irq();
} else { // } else {
// nop, the interrupt handler will free up space for us // // nop, the interrupt handler will free up space for us
// }
// }
// _tx_buffer[_tx_buffer_head] = c;
// _tx_buffer_head = i;
// sbi(*_ucsrb, UDRIE0);
// _written = true;
// return 1;
}
void HardwareSerial::_rx_complete_irq(char c)
{
rx_buffer_index_t i = (unsigned int)(_rx_buffer_head + 1) % SERIAL_RX_BUFFER_SIZE;
if (i != _rx_buffer_tail) {
_rx_buffer[_rx_buffer_head] = c;
_rx_buffer_head = i;
} }
}
_tx_buffer[_tx_buffer_head] = c;
_tx_buffer_head = i;
sbi(*_ucsrb, UDRIE0);
_written = true;
return 1;
} }
#endif // whole file // void HardwareSerial::_tx_udr_empty_irq(void)
// {
// // If interrupts are enabled, there must be more data in the output
// // buffer. Send the next byte
// unsigned char c = _tx_buffer[_tx_buffer_tail];
// _tx_buffer_tail = (_tx_buffer_tail + 1) % SERIAL_TX_BUFFER_SIZE;
// *_udr = c;
// // clear the TXC bit -- "can be cleared by writing a one to its bit
// // location". This makes sure flush() won't return until the bytes
// // actually got written
// sbi(*_ucsra, TXC0);
// if (_tx_buffer_head == _tx_buffer_tail) {
// // Buffer empty, so disable interrupts
// cbi(*_ucsrb, UDRIE0);
// }
// }

View File

@ -28,67 +28,46 @@
#include "Stream.h" #include "Stream.h"
// Define constants and variables for buffering incoming serial data. We're
// using a ring buffer (I think), in which head is the index of the location
// to which to write the next incoming character and tail is the index of the
// location from which to read.
// NOTE: a "power of 2" buffer size is reccomended to dramatically
// optimize all the modulo operations for ring buffers.
#if !(defined(SERIAL_TX_BUFFER_SIZE) && defined(SERIAL_RX_BUFFER_SIZE)) #if !(defined(SERIAL_TX_BUFFER_SIZE) && defined(SERIAL_RX_BUFFER_SIZE))
#if (RAMEND < 1000)
#define SERIAL_TX_BUFFER_SIZE 16
#define SERIAL_RX_BUFFER_SIZE 16
#else
#define SERIAL_TX_BUFFER_SIZE 64 #define SERIAL_TX_BUFFER_SIZE 64
#define SERIAL_RX_BUFFER_SIZE 64 #define SERIAL_RX_BUFFER_SIZE 64
#endif #endif
#endif
#if (SERIAL_TX_BUFFER_SIZE>256)
typedef uint16_t tx_buffer_index_t;
#else
typedef uint8_t tx_buffer_index_t;
#endif
#if (SERIAL_RX_BUFFER_SIZE>256)
typedef uint16_t rx_buffer_index_t;
#else
typedef uint8_t rx_buffer_index_t;
#endif
// Define config for Serial.begin(baud, config); typedef uint32_t tx_buffer_index_t;
#define SERIAL_5N1 0x00 typedef uint32_t rx_buffer_index_t;
#define SERIAL_6N1 0x02
#define SERIAL_7N1 0x04
#define SERIAL_8N1 0x06
#define SERIAL_5N2 0x08
#define SERIAL_6N2 0x0A
#define SERIAL_7N2 0x0C
#define SERIAL_8N2 0x0E
#define SERIAL_5E1 0x20
#define SERIAL_6E1 0x22
#define SERIAL_7E1 0x24
#define SERIAL_8E1 0x26
#define SERIAL_5E2 0x28
#define SERIAL_6E2 0x2A
#define SERIAL_7E2 0x2C
#define SERIAL_8E2 0x2E
#define SERIAL_5O1 0x30
#define SERIAL_6O1 0x32
#define SERIAL_7O1 0x34
#define SERIAL_8O1 0x36
#define SERIAL_5O2 0x38
#define SERIAL_6O2 0x3A
#define SERIAL_7O2 0x3C
#define SERIAL_8O2 0x3E
// // Define config for Serial.begin(baud, config);
// #define SERIAL_5N1 0x00
// #define SERIAL_6N1 0x02
// #define SERIAL_7N1 0x04
// #define SERIAL_8N1 0x06
// #define SERIAL_5N2 0x08
// #define SERIAL_6N2 0x0A
// #define SERIAL_7N2 0x0C
// #define SERIAL_8N2 0x0E
// #define SERIAL_5E1 0x20
// #define SERIAL_6E1 0x22
// #define SERIAL_7E1 0x24
// #define SERIAL_8E1 0x26
// #define SERIAL_5E2 0x28
// #define SERIAL_6E2 0x2A
// #define SERIAL_7E2 0x2C
// #define SERIAL_8E2 0x2E
// #define SERIAL_5O1 0x30
// #define SERIAL_6O1 0x32
// #define SERIAL_7O1 0x34
// #define SERIAL_8O1 0x36
// #define SERIAL_5O2 0x38
// #define SERIAL_6O2 0x3A
// #define SERIAL_7O2 0x3C
// #define SERIAL_8O2 0x3E
struct uart_;
typedef uart_ uart_t;
class HardwareSerial : public Stream class HardwareSerial : public Stream
{ {
protected: protected:
volatile uint8_t * const _ubrrh; uart_t* _uart;
volatile uint8_t * const _ubrrl;
volatile uint8_t * const _ucsra;
volatile uint8_t * const _ucsrb;
volatile uint8_t * const _ucsrc;
volatile uint8_t * const _udr;
// Has any byte been written to the UART since begin() // Has any byte been written to the UART since begin()
bool _written; bool _written;
@ -97,18 +76,13 @@ class HardwareSerial : public Stream
volatile tx_buffer_index_t _tx_buffer_head; volatile tx_buffer_index_t _tx_buffer_head;
volatile tx_buffer_index_t _tx_buffer_tail; volatile tx_buffer_index_t _tx_buffer_tail;
// Don't put any members after these buffers, since only the first
// 32 bytes of this struct can be accessed quickly using the ldd
// instruction.
unsigned char _rx_buffer[SERIAL_RX_BUFFER_SIZE]; unsigned char _rx_buffer[SERIAL_RX_BUFFER_SIZE];
unsigned char _tx_buffer[SERIAL_TX_BUFFER_SIZE]; unsigned char _tx_buffer[SERIAL_TX_BUFFER_SIZE];
public: public:
inline HardwareSerial( HardwareSerial() : _uart(0) { }
volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
volatile uint8_t *ucsra, volatile uint8_t *ucsrb, void begin(unsigned long baud) { begin(baud, 0); }
volatile uint8_t *ucsrc, volatile uint8_t *udr);
void begin(unsigned long baud) { begin(baud, SERIAL_8N1); }
void begin(unsigned long, uint8_t); void begin(unsigned long, uint8_t);
void end(); void end();
virtual int available(void); virtual int available(void);
@ -125,27 +99,10 @@ class HardwareSerial : public Stream
operator bool() { return true; } operator bool() { return true; }
// Interrupt handlers - Not intended to be called externally // Interrupt handlers - Not intended to be called externally
inline void _rx_complete_irq(void); void _rx_complete_irq(char c);
void _tx_udr_empty_irq(void); void _tx_udr_empty_irq(void);
}; };
#if defined(UBRRH) || defined(UBRR0H) extern HardwareSerial Serial;
extern HardwareSerial Serial;
#define HAVE_HWSERIAL0
#endif
#if defined(UBRR1H)
extern HardwareSerial Serial1;
#define HAVE_HWSERIAL1
#endif
#if defined(UBRR2H)
extern HardwareSerial Serial2;
#define HAVE_HWSERIAL2
#endif
#if defined(UBRR3H)
extern HardwareSerial Serial3;
#define HAVE_HWSERIAL3
#endif
extern void serialEventRun(void) __attribute__((weak));
#endif #endif

View File

@ -1,123 +0,0 @@
/*
HardwareSerial_private.h - Hardware serial library for Wiring
Copyright (c) 2006 Nicholas Zambetti. 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
Modified 23 November 2006 by David A. Mellis
Modified 28 September 2010 by Mark Sproul
Modified 14 August 2012 by Alarus
*/
#include "wiring_private.h"
// this next line disables the entire HardwareSerial.cpp,
// this is so I can support Attiny series and any other chip without a uart
#if defined(HAVE_HWSERIAL0) || defined(HAVE_HWSERIAL1) || defined(HAVE_HWSERIAL2) || defined(HAVE_HWSERIAL3)
// Ensure that the various bit positions we use are available with a 0
// postfix, so we can always use the values for UART0 for all UARTs. The
// alternative, passing the various values for each UART to the
// HardwareSerial constructor also works, but makes the code bigger and
// slower.
#if !defined(TXC0)
#if defined(TXC)
// Some chips like ATmega8 don't have UPE, only PE. The other bits are
// named as expected.
#if !defined(UPE) && defined(PE)
#define UPE PE
#endif
// On ATmega8, the uart and its bits are not numbered, so there is no TXC0 etc.
#define TXC0 TXC
#define RXEN0 RXEN
#define TXEN0 TXEN
#define RXCIE0 RXCIE
#define UDRIE0 UDRIE
#define U2X0 U2X
#define UPE0 UPE
#define UDRE0 UDRE
#elif defined(TXC1)
// Some devices have uart1 but no uart0
#define TXC0 TXC1
#define RXEN0 RXEN1
#define TXEN0 TXEN1
#define RXCIE0 RXCIE1
#define UDRIE0 UDRIE1
#define U2X0 U2X1
#define UPE0 UPE1
#define UDRE0 UDRE1
#else
#error No UART found in HardwareSerial.cpp
#endif
#endif // !defined TXC0
// Check at compiletime that it is really ok to use the bit positions of
// UART0 for the other UARTs as well, in case these values ever get
// changed for future hardware.
#if defined(TXC1) && (TXC1 != TXC0 || RXEN1 != RXEN0 || RXCIE1 != RXCIE0 || \
UDRIE1 != UDRIE0 || U2X1 != U2X0 || UPE1 != UPE0 || \
UDRE1 != UDRE0)
#error "Not all bit positions for UART1 are the same as for UART0"
#endif
#if defined(TXC2) && (TXC2 != TXC0 || RXEN2 != RXEN0 || RXCIE2 != RXCIE0 || \
UDRIE2 != UDRIE0 || U2X2 != U2X0 || UPE2 != UPE0 || \
UDRE2 != UDRE0)
#error "Not all bit positions for UART2 are the same as for UART0"
#endif
#if defined(TXC3) && (TXC3 != TXC0 || RXEN3 != RXEN0 || RXCIE3 != RXCIE0 || \
UDRIE3 != UDRIE0 || U3X3 != U3X0 || UPE3 != UPE0 || \
UDRE3 != UDRE0)
#error "Not all bit positions for UART3 are the same as for UART0"
#endif
// Constructors ////////////////////////////////////////////////////////////////
HardwareSerial::HardwareSerial(
volatile uint8_t *ubrrh, volatile uint8_t *ubrrl,
volatile uint8_t *ucsra, volatile uint8_t *ucsrb,
volatile uint8_t *ucsrc, volatile uint8_t *udr) :
_ubrrh(ubrrh), _ubrrl(ubrrl),
_ucsra(ucsra), _ucsrb(ucsrb), _ucsrc(ucsrc),
_udr(udr),
_rx_buffer_head(0), _rx_buffer_tail(0),
_tx_buffer_head(0), _tx_buffer_tail(0)
{
}
// Actual interrupt handlers //////////////////////////////////////////////////////////////
void HardwareSerial::_rx_complete_irq(void)
{
if (bit_is_clear(*_ucsra, UPE0)) {
// No Parity error, read byte and store it in the buffer if there is
// room
unsigned char c = *_udr;
rx_buffer_index_t i = (unsigned int)(_rx_buffer_head + 1) % SERIAL_RX_BUFFER_SIZE;
// if we should be storing the received character into the location
// just before the tail (meaning that the head would advance to the
// current location of the tail), we're about to overflow the buffer
// and so we don't write the character or advance the head.
if (i != _rx_buffer_tail) {
_rx_buffer[_rx_buffer_head] = c;
_rx_buffer_head = i;
}
} else {
// Parity error, read byte but discard it
*_udr;
};
}
#endif // whole file

View File

@ -21,6 +21,9 @@
#define Character_h #define Character_h
#include <ctype.h> #include <ctype.h>
#define isascii(__c) ((unsigned)(__c)<=0177)
#define toascii(__c) ((__c)&0177)
// WCharacter.h prototypes // WCharacter.h prototypes
inline boolean isAlphaNumeric(int c) __attribute__((always_inline)); inline boolean isAlphaNumeric(int c) __attribute__((always_inline));

View File

@ -21,6 +21,12 @@
#include "WString.h" #include "WString.h"
#include "stdlib_noniso.h" #include "stdlib_noniso.h"
extern "C" {
#include "osapi.h"
#include "ets_sys.h"
#include "mem.h"
}
/*********************************************/ /*********************************************/
/* Constructors */ /* Constructors */
/*********************************************/ /*********************************************/
@ -115,7 +121,7 @@ String::String(double value, unsigned char decimalPlaces)
String::~String() String::~String()
{ {
free(buffer); os_free(buffer);
} }
/*********************************************/ /*********************************************/
@ -131,7 +137,7 @@ inline void String::init(void)
void String::invalidate(void) void String::invalidate(void)
{ {
if (buffer) free(buffer); if (buffer) os_free(buffer);
buffer = NULL; buffer = NULL;
capacity = len = 0; capacity = len = 0;
} }
@ -183,7 +189,7 @@ void String::move(String &rhs)
rhs.len = 0; rhs.len = 0;
return; return;
} else { } else {
free(buffer); os_free(buffer);
} }
} }
buffer = rhs.buffer; buffer = rhs.buffer;

View File

@ -24,12 +24,12 @@ extern "C" void __cxa_deleted_virtual(void) __attribute__ ((__noreturn__));
void __cxa_pure_virtual(void) { void __cxa_pure_virtual(void) {
// We might want to write some diagnostics to uart in this case // We might want to write some diagnostics to uart in this case
//std::terminate(); //std::terminate();
abort(); while(true) {}
} }
void __cxa_deleted_virtual(void) { void __cxa_deleted_virtual(void) {
// We might want to write some diagnostics to uart in this case // We might want to write some diagnostics to uart in this case
//std::terminate(); //std::terminate();
abort(); while(true) {}
} }

View File

@ -16,21 +16,26 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/ */
#include <stdlib.h> extern "C" {
#include "osapi.h"
#include "ets_sys.h"
#include "mem.h"
}
void *operator new(size_t size) { void *operator new(size_t size) {
return malloc(size); return os_malloc(size);
} }
void *operator new[](size_t size) { void *operator new[](size_t size) {
return malloc(size); return os_malloc(size);
} }
void operator delete(void * ptr) { void operator delete(void * ptr) {
free(ptr); os_free(ptr);
} }
void operator delete[](void * ptr) { void operator delete[](void * ptr) {
free(ptr); os_free(ptr);
} }