Browse Source

T3.x/LC-SerialX addMemoryFor...

An experiement to see how much work again it would take to add the T4 methods to allow user sketches to increase the size of Serial ports RX and TX buffers, without having to edit the Source code which does it then for all sketches.

T3.x SerialN Add extra memory capabilities for Serial1-6

Also

Fixed serialEventX yield handling when you call begin multiple times

There is an issue that if you are not using the serialEvent type code and you call SerialX.begin multiple times, it will add that item to the process list multiple times, which can overrun the memory and cause crash or the like.

Fix was to check the list first and see if we are already in the list.
main
Kurt Eckhardt 4 years ago
parent
commit
d48359fc2c
10 changed files with 592 additions and 141 deletions
  1. +4
    -0
      teensy3/HardwareSerial.cpp
  2. +25
    -0
      teensy3/HardwareSerial.h
  3. +97
    -26
      teensy3/serial1.c
  4. +97
    -26
      teensy3/serial2.c
  5. +73
    -18
      teensy3/serial3.c
  6. +74
    -18
      teensy3/serial4.c
  7. +75
    -18
      teensy3/serial5.c
  8. +75
    -18
      teensy3/serial6.c
  9. +69
    -17
      teensy3/serial6_lpuart.c
  10. +3
    -0
      teensy4/HardwareSerial.cpp

+ 4
- 0
teensy3/HardwareSerial.cpp View File

@@ -39,6 +39,10 @@ uint8_t HardwareSerial::s_count_serials_with_serial_events = 0;
// simple helper function that add us to the list of Serial ports that have
// their own serialEvent code defined that needs to be called at yield.
void HardwareSerial::addToSerialEventsList() {
for (uint8_t i = 0; i < s_count_serials_with_serial_events; i++) {
if (s_serials_with_serial_events[i] == this) return; // already in the list.
}

s_serials_with_serial_events[s_count_serials_with_serial_events++] = this;
yield_active_check_flags |= YIELD_CHECK_HARDWARE_SERIAL;
}

+ 25
- 0
teensy3/HardwareSerial.h View File

@@ -32,6 +32,7 @@
#define HardwareSerial_h

#include "kinetis.h"
#include <stddef.h>

// Uncomment to enable 9 bit formats. These are default disabled to save memory.
//#define SERIAL_9BIT_SUPPORT
@@ -147,6 +148,8 @@ void serial_putchar(uint32_t c);
void serial_write(const void *buf, unsigned int count);
void serial_flush(void);
int serial_write_buffer_free(void);
void serial_add_memory_for_read(void *buffer, size_t length);
void serial_add_memory_for_write(void *buffer, size_t length);
int serial_available(void);
int serial_getchar(void);
int serial_peek(void);
@@ -168,6 +171,8 @@ void serial2_putchar(uint32_t c);
void serial2_write(const void *buf, unsigned int count);
void serial2_flush(void);
int serial2_write_buffer_free(void);
void serial2_add_memory_for_read(void *buffer, size_t length);
void serial2_add_memory_for_write(void *buffer, size_t length);
int serial2_available(void);
int serial2_getchar(void);
int serial2_peek(void);
@@ -185,6 +190,8 @@ void serial3_putchar(uint32_t c);
void serial3_write(const void *buf, unsigned int count);
void serial3_flush(void);
int serial3_write_buffer_free(void);
void serial3_add_memory_for_read(void *buffer, size_t length);
void serial3_add_memory_for_write(void *buffer, size_t length);
int serial3_available(void);
int serial3_getchar(void);
int serial3_peek(void);
@@ -202,6 +209,8 @@ void serial4_putchar(uint32_t c);
void serial4_write(const void *buf, unsigned int count);
void serial4_flush(void);
int serial4_write_buffer_free(void);
void serial4_add_memory_for_read(void *buffer, size_t length);
void serial4_add_memory_for_write(void *buffer, size_t length);
int serial4_available(void);
int serial4_getchar(void);
int serial4_peek(void);
@@ -219,6 +228,8 @@ void serial5_putchar(uint32_t c);
void serial5_write(const void *buf, unsigned int count);
void serial5_flush(void);
int serial5_write_buffer_free(void);
void serial5_add_memory_for_read(void *buffer, size_t length);
void serial5_add_memory_for_write(void *buffer, size_t length);
int serial5_available(void);
int serial5_getchar(void);
int serial5_peek(void);
@@ -236,6 +247,8 @@ void serial6_putchar(uint32_t c);
void serial6_write(const void *buf, unsigned int count);
void serial6_flush(void);
int serial6_write_buffer_free(void);
void serial6_add_memory_for_read(void *buffer, size_t length);
void serial6_add_memory_for_write(void *buffer, size_t length);
int serial6_available(void);
int serial6_getchar(void);
int serial6_peek(void);
@@ -275,6 +288,8 @@ public:
virtual void flush(void) { serial_flush(); }
virtual void clear(void) { serial_clear(); }
virtual int availableForWrite(void) { return serial_write_buffer_free(); }
virtual void addMemoryForRead(void *buffer, size_t length) {serial_add_memory_for_read(buffer, length);}
virtual void addMemoryForWrite(void *buffer, size_t length){serial_add_memory_for_write(buffer, length);}
using Print::write;
virtual size_t write(uint8_t c) { serial_putchar(c); return 1; }
virtual size_t write(unsigned long n) { return write((uint8_t)n); }
@@ -327,6 +342,8 @@ public:
virtual void flush(void) { serial2_flush(); }
virtual void clear(void) { serial2_clear(); }
virtual int availableForWrite(void) { return serial2_write_buffer_free(); }
virtual void addMemoryForRead(void *buffer, size_t length) {serial2_add_memory_for_read(buffer, length);}
virtual void addMemoryForWrite(void *buffer, size_t length){serial2_add_memory_for_write(buffer, length);}
using Print::write;
virtual size_t write(uint8_t c) { serial2_putchar(c); return 1; }
virtual size_t write(unsigned long n) { return write((uint8_t)n); }
@@ -364,6 +381,8 @@ public:
virtual void flush(void) { serial3_flush(); }
virtual void clear(void) { serial3_clear(); }
virtual int availableForWrite(void) { return serial3_write_buffer_free(); }
virtual void addMemoryForRead(void *buffer, size_t length) {serial3_add_memory_for_read(buffer, length);}
virtual void addMemoryForWrite(void *buffer, size_t length){serial3_add_memory_for_write(buffer, length);}
using Print::write;
virtual size_t write(uint8_t c) { serial3_putchar(c); return 1; }
virtual size_t write(unsigned long n) { return write((uint8_t)n); }
@@ -401,6 +420,8 @@ public:
virtual void flush(void) { serial4_flush(); }
virtual void clear(void) { serial4_clear(); }
virtual int availableForWrite(void) { return serial4_write_buffer_free(); }
virtual void addMemoryForRead(void *buffer, size_t length) {serial4_add_memory_for_read(buffer, length);}
virtual void addMemoryForWrite(void *buffer, size_t length){serial4_add_memory_for_write(buffer, length);}
using Print::write;
virtual size_t write(uint8_t c) { serial4_putchar(c); return 1; }
virtual size_t write(unsigned long n) { return write((uint8_t)n); }
@@ -438,6 +459,8 @@ public:
virtual void flush(void) { serial5_flush(); }
virtual void clear(void) { serial5_clear(); }
virtual int availableForWrite(void) { return serial5_write_buffer_free(); }
virtual void addMemoryForRead(void *buffer, size_t length) {serial5_add_memory_for_read(buffer, length);}
virtual void addMemoryForWrite(void *buffer, size_t length){serial5_add_memory_for_write(buffer, length);}
using Print::write;
virtual size_t write(uint8_t c) { serial5_putchar(c); return 1; }
virtual size_t write(unsigned long n) { return write((uint8_t)n); }
@@ -482,6 +505,8 @@ public:
virtual void flush(void) { serial6_flush(); }
virtual void clear(void) { serial6_clear(); }
virtual int availableForWrite(void) { return serial6_write_buffer_free(); }
virtual void addMemoryForRead(void *buffer, size_t length) {serial6_add_memory_for_read(buffer, length);}
virtual void addMemoryForWrite(void *buffer, size_t length){serial6_add_memory_for_write(buffer, length);}
using Print::write;
virtual size_t write(uint8_t c) { serial6_putchar(c); return 1; }
virtual size_t write(unsigned long n) { return write((uint8_t)n); }

+ 97
- 26
teensy3/serial1.c View File

@@ -31,6 +31,7 @@
#include "kinetis.h"
#include "core_pins.h"
#include "HardwareSerial.h"
#include <stddef.h>

////////////////////////////////////////////////////////////////
// Tunable parameters (relatively safe to edit these numbers)
@@ -61,6 +62,14 @@ static uint8_t use9Bits = 0;

static volatile BUFTYPE tx_buffer[SERIAL1_TX_BUFFER_SIZE];
static volatile BUFTYPE rx_buffer[SERIAL1_RX_BUFFER_SIZE];
static volatile BUFTYPE *rx_buffer_storage_ = NULL;
static volatile BUFTYPE *tx_buffer_storage_ = NULL;

static size_t tx_buffer_total_size_ = SERIAL1_TX_BUFFER_SIZE;
static size_t rx_buffer_total_size_ = SERIAL1_RX_BUFFER_SIZE;
static size_t rts_low_watermark_ = RTS_LOW_WATERMARK;
static size_t rts_high_watermark_ = RTS_HIGH_WATERMARK;

static volatile uint8_t transmitting = 0;
#if defined(KINETISK)
static volatile uint8_t *transmit_pin=NULL;
@@ -370,14 +379,18 @@ void serial_putchar(uint32_t c)
if (!(SIM_SCGC4 & SIM_SCGC4_UART0)) return;
if (transmit_pin) transmit_assert();
head = tx_buffer_head;
if (++head >= SERIAL1_TX_BUFFER_SIZE) head = 0;
if (++head >= tx_buffer_total_size_) head = 0;
while (tx_buffer_tail == head) {
int priority = nvic_execution_priority();
if (priority <= IRQ_PRIORITY) {
if ((UART0_S1 & UART_S1_TDRE)) {
uint32_t tail = tx_buffer_tail;
if (++tail >= SERIAL1_TX_BUFFER_SIZE) tail = 0;
n = tx_buffer[tail];
if (++tail >= tx_buffer_total_size_) tail = 0;
if (tail < SERIAL1_TX_BUFFER_SIZE) {
n = tx_buffer[tail];
} else {
n = tx_buffer_storage_[tail-SERIAL1_TX_BUFFER_SIZE];
}
if (use9Bits) UART0_C3 = (UART0_C3 & ~0x40) | ((n & 0x100) >> 2);
UART0_D = n;
tx_buffer_tail = tail;
@@ -386,7 +399,11 @@ void serial_putchar(uint32_t c)
yield();
}
}
tx_buffer[head] = c;
if (head < SERIAL1_TX_BUFFER_SIZE) {
tx_buffer[head] = c;
} else {
tx_buffer_storage_[head - SERIAL1_TX_BUFFER_SIZE] = c;
}
transmitting = 1;
tx_buffer_head = head;
UART0_C2 = C2_TX_ACTIVE;
@@ -403,7 +420,7 @@ void serial_write(const void *buf, unsigned int count)
if (transmit_pin) transmit_assert();
while (p < end) {
head = tx_buffer_head;
if (++head >= SERIAL1_TX_BUFFER_SIZE) head = 0;
if (++head >= tx_buffer_total_size_) head = 0;
if (tx_buffer_tail == head) {
UART0_C2 = C2_TX_ACTIVE;
do {
@@ -411,8 +428,12 @@ void serial_write(const void *buf, unsigned int count)
if (priority <= IRQ_PRIORITY) {
if ((UART0_S1 & UART_S1_TDRE)) {
uint32_t tail = tx_buffer_tail;
if (++tail >= SERIAL1_TX_BUFFER_SIZE) tail = 0;
n = tx_buffer[tail];
if (++tail >= tx_buffer_total_size_) tail = 0;
if (tail < SERIAL1_TX_BUFFER_SIZE) {
n = tx_buffer[tail];
} else {
n = tx_buffer_storage_[tail-SERIAL1_TX_BUFFER_SIZE];
}
if (use9Bits) UART0_C3 = (UART0_C3 & ~0x40) | ((n & 0x100) >> 2);
UART0_D = n;
tx_buffer_tail = tail;
@@ -422,7 +443,11 @@ void serial_write(const void *buf, unsigned int count)
}
} while (tx_buffer_tail == head);
}
tx_buffer[head] = *p++;
if (head < SERIAL1_TX_BUFFER_SIZE) {
tx_buffer[head] = *p++;
} else {
tx_buffer_storage_[head - SERIAL1_TX_BUFFER_SIZE] = *p++;
}
transmitting = 1;
tx_buffer_head = head;
}
@@ -447,7 +472,7 @@ int serial_write_buffer_free(void)

head = tx_buffer_head;
tail = tx_buffer_tail;
if (head >= tail) return SERIAL1_TX_BUFFER_SIZE - 1 - head + tail;
if (head >= tail) return tx_buffer_total_size_ - 1 - head + tail;
return tail - head - 1;
}

@@ -458,7 +483,7 @@ int serial_available(void)
head = rx_buffer_head;
tail = rx_buffer_tail;
if (head >= tail) return head - tail;
return SERIAL1_RX_BUFFER_SIZE + head - tail;
return rx_buffer_total_size_ + head - tail;
}

int serial_getchar(void)
@@ -469,14 +494,18 @@ int serial_getchar(void)
head = rx_buffer_head;
tail = rx_buffer_tail;
if (head == tail) return -1;
if (++tail >= SERIAL1_RX_BUFFER_SIZE) tail = 0;
c = rx_buffer[tail];
if (++tail >= rx_buffer_total_size_) tail = 0;
if (tail < SERIAL1_RX_BUFFER_SIZE) {
c = rx_buffer[tail];
} else {
c = rx_buffer_storage_[tail-SERIAL1_RX_BUFFER_SIZE];
}
rx_buffer_tail = tail;
if (rts_pin) {
int avail;
if (head >= tail) avail = head - tail;
else avail = SERIAL1_RX_BUFFER_SIZE + head - tail;
if (avail <= RTS_LOW_WATERMARK) rts_assert();
else avail = rx_buffer_total_size_ + head - tail;
if (avail <= rts_low_watermark_) rts_assert();
}
return c;
}
@@ -488,8 +517,11 @@ int serial_peek(void)
head = rx_buffer_head;
tail = rx_buffer_tail;
if (head == tail) return -1;
if (++tail >= SERIAL1_RX_BUFFER_SIZE) tail = 0;
return rx_buffer[tail];
if (++tail >= rx_buffer_total_size_) tail = 0;
if (tail < SERIAL1_RX_BUFFER_SIZE) {
return rx_buffer[tail];
}
return rx_buffer_storage_[tail-SERIAL1_RX_BUFFER_SIZE];
}

void serial_clear(void)
@@ -553,18 +585,22 @@ void uart0_status_isr(void)
n = UART0_D;
}
newhead = head + 1;
if (newhead >= SERIAL1_RX_BUFFER_SIZE) newhead = 0;
if (newhead >= rx_buffer_total_size_) newhead = 0;
if (newhead != tail) {
head = newhead;
rx_buffer[head] = n;
if (newhead < SERIAL1_RX_BUFFER_SIZE) {
rx_buffer[head] = n;
} else {
rx_buffer_storage_[head-SERIAL1_RX_BUFFER_SIZE] = n;
}
}
} while (--avail > 0);
rx_buffer_head = head;
if (rts_pin) {
int avail;
if (head >= tail) avail = head - tail;
else avail = SERIAL1_RX_BUFFER_SIZE + head - tail;
if (avail >= RTS_HIGH_WATERMARK) rts_deassert();
else avail = rx_buffer_total_size_ + head - tail;
if (avail >= rts_high_watermark_) rts_deassert();
}
}
}
@@ -574,9 +610,13 @@ void uart0_status_isr(void)
tail = tx_buffer_tail;
do {
if (tail == head) break;
if (++tail >= SERIAL1_TX_BUFFER_SIZE) tail = 0;
if (++tail >= tx_buffer_total_size_) tail = 0;
avail = UART0_S1;
n = tx_buffer[tail];
if (tail < SERIAL1_TX_BUFFER_SIZE) {
n = tx_buffer[tail];
} else {
n = tx_buffer_storage_[tail-SERIAL1_TX_BUFFER_SIZE];
}
if (use9Bits) UART0_C3 = (UART0_C3 & ~0x40) | ((n & 0x100) >> 2);
UART0_D = n;
} while (UART0_TCFIFO < 8);
@@ -591,9 +631,14 @@ void uart0_status_isr(void)
n = UART0_D;
}
head = rx_buffer_head + 1;
if (head >= SERIAL1_RX_BUFFER_SIZE) head = 0;
if (head >= rx_buffer_total_size_) head = 0;
if (head != rx_buffer_tail) {
rx_buffer[head] = n;
if (head < SERIAL1_RX_BUFFER_SIZE) {
rx_buffer[head] = n;
} else {
rx_buffer_storage_[head-SERIAL1_RX_BUFFER_SIZE] = n;
}

rx_buffer_head = head;
}
}
@@ -604,8 +649,12 @@ void uart0_status_isr(void)
if (head == tail) {
UART0_C2 = C2_TX_COMPLETING;
} else {
if (++tail >= SERIAL1_TX_BUFFER_SIZE) tail = 0;
n = tx_buffer[tail];
if (++tail >= tx_buffer_total_size_) tail = 0;
if (tail < SERIAL1_TX_BUFFER_SIZE) {
n = tx_buffer[tail];
} else {
n = tx_buffer_storage_[tail-SERIAL1_TX_BUFFER_SIZE];
}
if (use9Bits) UART0_C3 = (UART0_C3 & ~0x40) | ((n & 0x100) >> 2);
UART0_D = n;
tx_buffer_tail = tail;
@@ -660,3 +709,25 @@ void serial_phex32(uint32_t n)
serial_phex(n);
}

void serial_add_memory_for_read(void *buffer, size_t length)
{
rx_buffer_storage_ = (BUFTYPE*)buffer;
if (buffer) {
rx_buffer_total_size_ = SERIAL1_RX_BUFFER_SIZE + length;
} else {
rx_buffer_total_size_ = SERIAL1_RX_BUFFER_SIZE;
}

rts_low_watermark_ = RTS_LOW_WATERMARK + length;
rts_high_watermark_ = RTS_HIGH_WATERMARK + length;
}

void serial_add_memory_for_write(void *buffer, size_t length)
{
tx_buffer_storage_ = (BUFTYPE*)buffer;
if (buffer) {
tx_buffer_total_size_ = SERIAL1_TX_BUFFER_SIZE + length;
} else {
tx_buffer_total_size_ = SERIAL1_TX_BUFFER_SIZE;
}
}

+ 97
- 26
teensy3/serial2.c View File

@@ -31,6 +31,7 @@
#include "kinetis.h"
#include "core_pins.h"
#include "HardwareSerial.h"
#include <stddef.h>

////////////////////////////////////////////////////////////////
// Tunable parameters (relatively safe to edit these numbers)
@@ -60,6 +61,14 @@ static uint8_t use9Bits = 0;

static volatile BUFTYPE tx_buffer[SERIAL2_TX_BUFFER_SIZE];
static volatile BUFTYPE rx_buffer[SERIAL2_RX_BUFFER_SIZE];
static volatile BUFTYPE *rx_buffer_storage_ = NULL;
static volatile BUFTYPE *tx_buffer_storage_ = NULL;

static size_t tx_buffer_total_size_ = SERIAL2_TX_BUFFER_SIZE;
static size_t rx_buffer_total_size_ = SERIAL2_RX_BUFFER_SIZE;
static size_t rts_low_watermark_ = RTS_LOW_WATERMARK;
static size_t rts_high_watermark_ = RTS_HIGH_WATERMARK;

static volatile uint8_t transmitting = 0;
#if defined(KINETISK)
static volatile uint8_t *transmit_pin=NULL;
@@ -360,14 +369,18 @@ void serial2_putchar(uint32_t c)
if (!(SIM_SCGC4 & SIM_SCGC4_UART1)) return;
if (transmit_pin) transmit_assert();
head = tx_buffer_head;
if (++head >= SERIAL2_TX_BUFFER_SIZE) head = 0;
if (++head >= tx_buffer_total_size_) head = 0;
while (tx_buffer_tail == head) {
int priority = nvic_execution_priority();
if (priority <= IRQ_PRIORITY) {
if ((UART1_S1 & UART_S1_TDRE)) {
uint32_t tail = tx_buffer_tail;
if (++tail >= SERIAL2_TX_BUFFER_SIZE) tail = 0;
n = tx_buffer[tail];
if (++tail >= tx_buffer_total_size_) tail = 0;
if (tail < SERIAL2_TX_BUFFER_SIZE) {
n = tx_buffer[tail];
} else {
n = tx_buffer_storage_[tail-SERIAL2_TX_BUFFER_SIZE];
}
if (use9Bits) UART1_C3 = (UART1_C3 & ~0x40) | ((n & 0x100) >> 2);
UART1_D = n;
tx_buffer_tail = tail;
@@ -376,7 +389,11 @@ void serial2_putchar(uint32_t c)
yield(); // wait
}
}
tx_buffer[head] = c;
if (head < SERIAL2_TX_BUFFER_SIZE) {
tx_buffer[head] = c;
} else {
tx_buffer_storage_[head - SERIAL2_TX_BUFFER_SIZE] = c;
}
transmitting = 1;
tx_buffer_head = head;
UART1_C2 = C2_TX_ACTIVE;
@@ -393,7 +410,7 @@ void serial2_write(const void *buf, unsigned int count)
if (transmit_pin) transmit_assert();
while (p < end) {
head = tx_buffer_head;
if (++head >= SERIAL2_TX_BUFFER_SIZE) head = 0;
if (++head >= tx_buffer_total_size_) head = 0;
if (tx_buffer_tail == head) {
UART1_C2 = C2_TX_ACTIVE;
do {
@@ -401,8 +418,12 @@ void serial2_write(const void *buf, unsigned int count)
if (priority <= IRQ_PRIORITY) {
if ((UART1_S1 & UART_S1_TDRE)) {
uint32_t tail = tx_buffer_tail;
if (++tail >= SERIAL2_TX_BUFFER_SIZE) tail = 0;
n = tx_buffer[tail];
if (++tail >= tx_buffer_total_size_) tail = 0;
if (tail < SERIAL2_TX_BUFFER_SIZE) {
n = tx_buffer[tail];
} else {
n = tx_buffer_storage_[tail-SERIAL2_TX_BUFFER_SIZE];
}
if (use9Bits) UART1_C3 = (UART1_C3 & ~0x40) | ((n & 0x100) >> 2);
UART1_D = n;
tx_buffer_tail = tail;
@@ -412,7 +433,11 @@ void serial2_write(const void *buf, unsigned int count)
}
} while (tx_buffer_tail == head);
}
tx_buffer[head] = *p++;
if (head < SERIAL2_TX_BUFFER_SIZE) {
tx_buffer[head] = *p++;
} else {
tx_buffer_storage_[head - SERIAL2_TX_BUFFER_SIZE] = *p++;
}
transmitting = 1;
tx_buffer_head = head;
}
@@ -437,7 +462,7 @@ int serial2_write_buffer_free(void)

head = tx_buffer_head;
tail = tx_buffer_tail;
if (head >= tail) return SERIAL2_TX_BUFFER_SIZE - 1 - head + tail;
if (head >= tail) return tx_buffer_total_size_ - 1 - head + tail;
return tail - head - 1;
}

@@ -448,7 +473,7 @@ int serial2_available(void)
head = rx_buffer_head;
tail = rx_buffer_tail;
if (head >= tail) return head - tail;
return SERIAL2_RX_BUFFER_SIZE + head - tail;
return rx_buffer_total_size_ + head - tail;
}

int serial2_getchar(void)
@@ -459,14 +484,18 @@ int serial2_getchar(void)
head = rx_buffer_head;
tail = rx_buffer_tail;
if (head == tail) return -1;
if (++tail >= SERIAL2_RX_BUFFER_SIZE) tail = 0;
c = rx_buffer[tail];
if (++tail >= rx_buffer_total_size_) tail = 0;
if (tail < SERIAL2_RX_BUFFER_SIZE) {
c = rx_buffer[tail];
} else {
c = rx_buffer_storage_[tail-SERIAL2_RX_BUFFER_SIZE];
}
rx_buffer_tail = tail;
if (rts_pin) {
int avail;
if (head >= tail) avail = head - tail;
else avail = SERIAL2_RX_BUFFER_SIZE + head - tail;
if (avail <= RTS_LOW_WATERMARK) rts_assert();
else avail = rx_buffer_total_size_ + head - tail;
if (avail <= rts_low_watermark_) rts_assert();
}
return c;
}
@@ -478,8 +507,11 @@ int serial2_peek(void)
head = rx_buffer_head;
tail = rx_buffer_tail;
if (head == tail) return -1;
if (++tail >= SERIAL2_RX_BUFFER_SIZE) tail = 0;
return rx_buffer[tail];
if (++tail >= rx_buffer_total_size_) tail = 0;
if (tail < SERIAL2_RX_BUFFER_SIZE) {
return rx_buffer[tail];
}
return rx_buffer_storage_[tail-SERIAL2_RX_BUFFER_SIZE];
}

void serial2_clear(void)
@@ -543,18 +575,22 @@ void uart1_status_isr(void)
n = UART1_D;
}
newhead = head + 1;
if (newhead >= SERIAL2_RX_BUFFER_SIZE) newhead = 0;
if (newhead >= rx_buffer_total_size_) newhead = 0;
if (newhead != tail) {
head = newhead;
rx_buffer[head] = n;
if (newhead < SERIAL2_RX_BUFFER_SIZE) {
rx_buffer[head] = n;
} else {
rx_buffer_storage_[head-SERIAL2_RX_BUFFER_SIZE] = n;
}
}
} while (--avail > 0);
rx_buffer_head = head;
if (rts_pin) {
int avail;
if (head >= tail) avail = head - tail;
else avail = SERIAL2_RX_BUFFER_SIZE + head - tail;
if (avail >= RTS_HIGH_WATERMARK) rts_deassert();
else avail = rx_buffer_total_size_ + head - tail;
if (avail >= rts_high_watermark_) rts_deassert();
}
}
}
@@ -564,9 +600,13 @@ void uart1_status_isr(void)
tail = tx_buffer_tail;
do {
if (tail == head) break;
if (++tail >= SERIAL2_TX_BUFFER_SIZE) tail = 0;
if (++tail >= tx_buffer_total_size_) tail = 0;
avail = UART1_S1;
n = tx_buffer[tail];
if (tail < SERIAL2_TX_BUFFER_SIZE) {
n = tx_buffer[tail];
} else {
n = tx_buffer_storage_[tail-SERIAL2_TX_BUFFER_SIZE];
}
if (use9Bits) UART1_C3 = (UART1_C3 & ~0x40) | ((n & 0x100) >> 2);
UART1_D = n;
} while (UART1_TCFIFO < 8);
@@ -581,9 +621,14 @@ void uart1_status_isr(void)
n = UART1_D;
}
head = rx_buffer_head + 1;
if (head >= SERIAL2_RX_BUFFER_SIZE) head = 0;
if (head >= rx_buffer_total_size_) head = 0;
if (head != rx_buffer_tail) {
rx_buffer[head] = n;
if (head < SERIAL2_RX_BUFFER_SIZE) {
rx_buffer[head] = n;
} else {
rx_buffer_storage_[head-SERIAL2_RX_BUFFER_SIZE] = n;
}

rx_buffer_head = head;
}
}
@@ -594,8 +639,12 @@ void uart1_status_isr(void)
if (head == tail) {
UART1_C2 = C2_TX_COMPLETING;
} else {
if (++tail >= SERIAL2_TX_BUFFER_SIZE) tail = 0;
n = tx_buffer[tail];
if (++tail >= tx_buffer_total_size_) tail = 0;
if (tail < SERIAL2_TX_BUFFER_SIZE) {
n = tx_buffer[tail];
} else {
n = tx_buffer_storage_[tail-SERIAL2_TX_BUFFER_SIZE];
}
if (use9Bits) UART1_C3 = (UART1_C3 & ~0x40) | ((n & 0x100) >> 2);
UART1_D = n;
tx_buffer_tail = tail;
@@ -609,4 +658,26 @@ void uart1_status_isr(void)
}
}

void serial2_add_memory_for_read(void *buffer, size_t length)
{
rx_buffer_storage_ = (BUFTYPE*)buffer;
if (buffer) {
rx_buffer_total_size_ = SERIAL2_RX_BUFFER_SIZE + length;
} else {
rx_buffer_total_size_ = SERIAL2_RX_BUFFER_SIZE;
}

rts_low_watermark_ = RTS_LOW_WATERMARK + length;
rts_high_watermark_ = RTS_HIGH_WATERMARK + length;
}

void serial2_add_memory_for_write(void *buffer, size_t length)
{
tx_buffer_storage_ = (BUFTYPE*)buffer;
if (buffer) {
tx_buffer_total_size_ = SERIAL2_TX_BUFFER_SIZE + length;
} else {
tx_buffer_total_size_ = SERIAL2_TX_BUFFER_SIZE;
}
}


+ 73
- 18
teensy3/serial3.c View File

@@ -31,6 +31,7 @@
#include "kinetis.h"
#include "core_pins.h"
#include "HardwareSerial.h"
#include <stddef.h>

////////////////////////////////////////////////////////////////
// Tunable parameters (relatively safe to edit these numbers)
@@ -61,6 +62,14 @@ static uint8_t use9Bits = 0;

static volatile BUFTYPE tx_buffer[SERIAL3_TX_BUFFER_SIZE];
static volatile BUFTYPE rx_buffer[SERIAL3_RX_BUFFER_SIZE];
static volatile BUFTYPE *rx_buffer_storage_ = NULL;
static volatile BUFTYPE *tx_buffer_storage_ = NULL;

static size_t tx_buffer_total_size_ = SERIAL3_TX_BUFFER_SIZE;
static size_t rx_buffer_total_size_ = SERIAL3_RX_BUFFER_SIZE;
static size_t rts_low_watermark_ = RTS_LOW_WATERMARK;
static size_t rts_high_watermark_ = RTS_HIGH_WATERMARK;

static volatile uint8_t transmitting = 0;
#if defined(KINETISK)
static volatile uint8_t *transmit_pin=NULL;
@@ -316,14 +325,18 @@ void serial3_putchar(uint32_t c)
if (!(SIM_SCGC4 & SIM_SCGC4_UART2)) return;
if (transmit_pin) transmit_assert();
head = tx_buffer_head;
if (++head >= SERIAL3_TX_BUFFER_SIZE) head = 0;
if (++head >= tx_buffer_total_size_) head = 0;
while (tx_buffer_tail == head) {
int priority = nvic_execution_priority();
if (priority <= IRQ_PRIORITY) {
if ((UART2_S1 & UART_S1_TDRE)) {
uint32_t tail = tx_buffer_tail;
if (++tail >= SERIAL3_TX_BUFFER_SIZE) tail = 0;
n = tx_buffer[tail];
if (++tail >= tx_buffer_total_size_) tail = 0;
if (tail < SERIAL3_TX_BUFFER_SIZE) {
n = tx_buffer[tail];
} else {
n = tx_buffer_storage_[tail-SERIAL3_TX_BUFFER_SIZE];
}
if (use9Bits) UART2_C3 = (UART2_C3 & ~0x40) | ((n & 0x100) >> 2);
UART2_D = n;
tx_buffer_tail = tail;
@@ -332,7 +345,11 @@ void serial3_putchar(uint32_t c)
yield(); // wait
}
}
tx_buffer[head] = c;
if (head < SERIAL3_TX_BUFFER_SIZE) {
tx_buffer[head] = c;
} else {
tx_buffer_storage_[head - SERIAL3_TX_BUFFER_SIZE] = c;
}
transmitting = 1;
tx_buffer_head = head;
UART2_C2 = C2_TX_ACTIVE;
@@ -355,7 +372,7 @@ int serial3_write_buffer_free(void)

head = tx_buffer_head;
tail = tx_buffer_tail;
if (head >= tail) return SERIAL3_TX_BUFFER_SIZE - 1 - head + tail;
if (head >= tail) return tx_buffer_total_size_ - 1 - head + tail;
return tail - head - 1;
}

@@ -366,7 +383,7 @@ int serial3_available(void)
head = rx_buffer_head;
tail = rx_buffer_tail;
if (head >= tail) return head - tail;
return SERIAL3_RX_BUFFER_SIZE + head - tail;
return rx_buffer_total_size_ + head - tail;
}

int serial3_getchar(void)
@@ -377,14 +394,18 @@ int serial3_getchar(void)
head = rx_buffer_head;
tail = rx_buffer_tail;
if (head == tail) return -1;
if (++tail >= SERIAL3_RX_BUFFER_SIZE) tail = 0;
c = rx_buffer[tail];
if (++tail >= rx_buffer_total_size_) tail = 0;
if (tail < SERIAL3_RX_BUFFER_SIZE) {
c = rx_buffer[tail];
} else {
c = rx_buffer_storage_[tail-SERIAL3_RX_BUFFER_SIZE];
}
rx_buffer_tail = tail;
if (rts_pin) {
int avail;
if (head >= tail) avail = head - tail;
else avail = SERIAL3_RX_BUFFER_SIZE + head - tail;
if (avail <= RTS_LOW_WATERMARK) rts_assert();
else avail = rx_buffer_total_size_ + head - tail;
if (avail <= rts_low_watermark_) rts_assert();
}
return c;
}
@@ -396,8 +417,11 @@ int serial3_peek(void)
head = rx_buffer_head;
tail = rx_buffer_tail;
if (head == tail) return -1;
if (++tail >= SERIAL3_RX_BUFFER_SIZE) tail = 0;
return rx_buffer[tail];
if (++tail >= rx_buffer_total_size_) tail = 0;
if (tail < SERIAL3_RX_BUFFER_SIZE) {
return rx_buffer[tail];
}
return rx_buffer_storage_[tail-SERIAL3_RX_BUFFER_SIZE];
}

void serial3_clear(void)
@@ -426,17 +450,22 @@ void uart2_status_isr(void)
n = UART2_D;
}
head = rx_buffer_head + 1;
if (head >= SERIAL3_RX_BUFFER_SIZE) head = 0;
if (head >= rx_buffer_total_size_) head = 0;
if (head != rx_buffer_tail) {
rx_buffer[head] = n;
if (head < SERIAL3_RX_BUFFER_SIZE) {
rx_buffer[head] = n;
} else {
rx_buffer_storage_[head-SERIAL3_RX_BUFFER_SIZE] = n;
}

rx_buffer_head = head;
}
if (rts_pin) {
int avail;
tail = tx_buffer_tail;
if (head >= tail) avail = head - tail;
else avail = SERIAL3_RX_BUFFER_SIZE + head - tail;
if (avail >= RTS_HIGH_WATERMARK) rts_deassert();
else avail = rx_buffer_total_size_ + head - tail;
if (avail >= rts_high_watermark_) rts_deassert();
}
}
c = UART2_C2;
@@ -446,8 +475,12 @@ void uart2_status_isr(void)
if (head == tail) {
UART2_C2 = C2_TX_COMPLETING;
} else {
if (++tail >= SERIAL3_TX_BUFFER_SIZE) tail = 0;
n = tx_buffer[tail];
if (++tail >= tx_buffer_total_size_) tail = 0;
if (tail < SERIAL3_TX_BUFFER_SIZE) {
n = tx_buffer[tail];
} else {
n = tx_buffer_storage_[tail-SERIAL3_TX_BUFFER_SIZE];
}
if (use9Bits) UART2_C3 = (UART2_C3 & ~0x40) | ((n & 0x100) >> 2);
UART2_D = n;
tx_buffer_tail = tail;
@@ -460,4 +493,26 @@ void uart2_status_isr(void)
}
}

void serial3_add_memory_for_read(void *buffer, size_t length)
{
rx_buffer_storage_ = (BUFTYPE*)buffer;
if (buffer) {
rx_buffer_total_size_ = SERIAL3_RX_BUFFER_SIZE + length;
} else {
rx_buffer_total_size_ = SERIAL3_RX_BUFFER_SIZE;
}

rts_low_watermark_ = RTS_LOW_WATERMARK + length;
rts_high_watermark_ = RTS_HIGH_WATERMARK + length;
}

void serial3_add_memory_for_write(void *buffer, size_t length)
{
tx_buffer_storage_ = (BUFTYPE*)buffer;
if (buffer) {
tx_buffer_total_size_ = SERIAL3_TX_BUFFER_SIZE + length;
} else {
tx_buffer_total_size_ = SERIAL3_TX_BUFFER_SIZE;
}
}


+ 74
- 18
teensy3/serial4.c View File

@@ -31,6 +31,7 @@
#include "kinetis.h"
#include "core_pins.h"
#include "HardwareSerial.h"
#include <stddef.h>

#ifdef HAS_KINETISK_UART3

@@ -63,6 +64,13 @@ static uint8_t use9Bits = 0;

static volatile BUFTYPE tx_buffer[SERIAL4_TX_BUFFER_SIZE];
static volatile BUFTYPE rx_buffer[SERIAL4_RX_BUFFER_SIZE];
static volatile BUFTYPE *rx_buffer_storage_ = NULL;
static volatile BUFTYPE *tx_buffer_storage_ = NULL;

static size_t tx_buffer_total_size_ = SERIAL4_TX_BUFFER_SIZE;
static size_t rx_buffer_total_size_ = SERIAL4_RX_BUFFER_SIZE;
static size_t rts_low_watermark_ = RTS_LOW_WATERMARK;
static size_t rts_high_watermark_ = RTS_HIGH_WATERMARK;
static volatile uint8_t transmitting = 0;
static volatile uint8_t *transmit_pin=NULL;
#define transmit_assert() *transmit_pin = 1
@@ -256,14 +264,18 @@ void serial4_putchar(uint32_t c)
if (!(SIM_SCGC4 & SIM_SCGC4_UART3)) return;
if (transmit_pin) transmit_assert();
head = tx_buffer_head;
if (++head >= SERIAL4_TX_BUFFER_SIZE) head = 0;
if (++head >= tx_buffer_total_size_) head = 0;
while (tx_buffer_tail == head) {
int priority = nvic_execution_priority();
if (priority <= IRQ_PRIORITY) {
if ((UART3_S1 & UART_S1_TDRE)) {
uint32_t tail = tx_buffer_tail;
if (++tail >= SERIAL4_TX_BUFFER_SIZE) tail = 0;
n = tx_buffer[tail];
if (++tail >= tx_buffer_total_size_) tail = 0;
if (tail < SERIAL4_TX_BUFFER_SIZE) {
n = tx_buffer[tail];
} else {
n = tx_buffer_storage_[tail-SERIAL4_TX_BUFFER_SIZE];
}
if (use9Bits) UART3_C3 = (UART3_C3 & ~0x40) | ((n & 0x100) >> 2);
UART3_D = n;
tx_buffer_tail = tail;
@@ -272,7 +284,11 @@ void serial4_putchar(uint32_t c)
yield(); // wait
}
}
tx_buffer[head] = c;
if (head < SERIAL4_TX_BUFFER_SIZE) {
tx_buffer[head] = c;
} else {
tx_buffer_storage_[head - SERIAL4_TX_BUFFER_SIZE] = c;
}
transmitting = 1;
tx_buffer_head = head;
UART3_C2 = C2_TX_ACTIVE;
@@ -295,7 +311,7 @@ int serial4_write_buffer_free(void)

head = tx_buffer_head;
tail = tx_buffer_tail;
if (head >= tail) return SERIAL4_TX_BUFFER_SIZE - 1 - head + tail;
if (head >= tail) return tx_buffer_total_size_ - 1 - head + tail;
return tail - head - 1;
}

@@ -306,7 +322,7 @@ int serial4_available(void)
head = rx_buffer_head;
tail = rx_buffer_tail;
if (head >= tail) return head - tail;
return SERIAL4_RX_BUFFER_SIZE + head - tail;
return rx_buffer_total_size_ + head - tail;
}

int serial4_getchar(void)
@@ -317,14 +333,18 @@ int serial4_getchar(void)
head = rx_buffer_head;
tail = rx_buffer_tail;
if (head == tail) return -1;
if (++tail >= SERIAL4_RX_BUFFER_SIZE) tail = 0;
c = rx_buffer[tail];
if (++tail >= rx_buffer_total_size_) tail = 0;
if (tail < SERIAL4_RX_BUFFER_SIZE) {
c = rx_buffer[tail];
} else {
c = rx_buffer_storage_[tail-SERIAL4_RX_BUFFER_SIZE];
}
rx_buffer_tail = tail;
if (rts_pin) {
int avail;
if (head >= tail) avail = head - tail;
else avail = SERIAL4_RX_BUFFER_SIZE + head - tail;
if (avail <= RTS_LOW_WATERMARK) rts_assert();
else avail = rx_buffer_total_size_ + head - tail;
if (avail <= rts_low_watermark_) rts_assert();
}
return c;
}
@@ -336,8 +356,11 @@ int serial4_peek(void)
head = rx_buffer_head;
tail = rx_buffer_tail;
if (head == tail) return -1;
if (++tail >= SERIAL4_RX_BUFFER_SIZE) tail = 0;
return rx_buffer[tail];
if (++tail >= rx_buffer_total_size_) tail = 0;
if (tail < SERIAL4_RX_BUFFER_SIZE) {
return rx_buffer[tail];
}
return rx_buffer_storage_[tail-SERIAL4_RX_BUFFER_SIZE];
}

void serial4_clear(void)
@@ -366,17 +389,22 @@ void uart3_status_isr(void)
n = UART3_D;
}
head = rx_buffer_head + 1;
if (head >= SERIAL4_RX_BUFFER_SIZE) head = 0;
if (head >= rx_buffer_total_size_) head = 0;
if (head != rx_buffer_tail) {
rx_buffer[head] = n;
if (head < SERIAL4_RX_BUFFER_SIZE) {
rx_buffer[head] = n;
} else {
rx_buffer_storage_[head-SERIAL4_RX_BUFFER_SIZE] = n;
}

rx_buffer_head = head;
}
if (rts_pin) {
int avail;
tail = tx_buffer_tail;
if (head >= tail) avail = head - tail;
else avail = SERIAL4_RX_BUFFER_SIZE + head - tail;
if (avail >= RTS_HIGH_WATERMARK) rts_deassert();
else avail = rx_buffer_total_size_ + head - tail;
if (avail >= rts_high_watermark_) rts_deassert();
}
}
c = UART3_C2;
@@ -386,8 +414,12 @@ void uart3_status_isr(void)
if (head == tail) {
UART3_C2 = C2_TX_COMPLETING;
} else {
if (++tail >= SERIAL4_TX_BUFFER_SIZE) tail = 0;
n = tx_buffer[tail];
if (++tail >= tx_buffer_total_size_) tail = 0;
if (tail < SERIAL4_TX_BUFFER_SIZE) {
n = tx_buffer[tail];
} else {
n = tx_buffer_storage_[tail-SERIAL4_TX_BUFFER_SIZE];
}
if (use9Bits) UART3_C3 = (UART3_C3 & ~0x40) | ((n & 0x100) >> 2);
UART3_D = n;
tx_buffer_tail = tail;
@@ -400,4 +432,28 @@ void uart3_status_isr(void)
}
}

void serial4_add_memory_for_read(void *buffer, size_t length)
{
rx_buffer_storage_ = (BUFTYPE*)buffer;
if (buffer) {
rx_buffer_total_size_ = SERIAL4_RX_BUFFER_SIZE + length;
} else {
rx_buffer_total_size_ = SERIAL4_RX_BUFFER_SIZE;
}

rts_low_watermark_ = RTS_LOW_WATERMARK + length;
rts_high_watermark_ = RTS_HIGH_WATERMARK + length;
}

void serial4_add_memory_for_write(void *buffer, size_t length)
{
tx_buffer_storage_ = (BUFTYPE*)buffer;
if (buffer) {
tx_buffer_total_size_ = SERIAL4_TX_BUFFER_SIZE + length;
} else {
tx_buffer_total_size_ = SERIAL4_TX_BUFFER_SIZE;
}
}


#endif // HAS_KINETISK_UART3

+ 75
- 18
teensy3/serial5.c View File

@@ -31,6 +31,7 @@
#include "kinetis.h"
#include "core_pins.h"
#include "HardwareSerial.h"
#include <stddef.h>

#ifdef HAS_KINETISK_UART4

@@ -63,6 +64,14 @@ static uint8_t use9Bits = 0;

static volatile BUFTYPE tx_buffer[SERIAL5_TX_BUFFER_SIZE];
static volatile BUFTYPE rx_buffer[SERIAL5_RX_BUFFER_SIZE];
static volatile BUFTYPE *rx_buffer_storage_ = NULL;
static volatile BUFTYPE *tx_buffer_storage_ = NULL;

static size_t tx_buffer_total_size_ = SERIAL5_TX_BUFFER_SIZE;
static size_t rx_buffer_total_size_ = SERIAL5_RX_BUFFER_SIZE;
static size_t rts_low_watermark_ = RTS_LOW_WATERMARK;
static size_t rts_high_watermark_ = RTS_HIGH_WATERMARK;

static volatile uint8_t transmitting = 0;
static volatile uint8_t *transmit_pin=NULL;
#define transmit_assert() *transmit_pin = 1
@@ -234,14 +243,18 @@ void serial5_putchar(uint32_t c)
if (!(SIM_SCGC1 & SIM_SCGC1_UART4)) return;
if (transmit_pin) transmit_assert();
head = tx_buffer_head;
if (++head >= SERIAL5_TX_BUFFER_SIZE) head = 0;
if (++head >= tx_buffer_total_size_) head = 0;
while (tx_buffer_tail == head) {
int priority = nvic_execution_priority();
if (priority <= IRQ_PRIORITY) {
if ((UART4_S1 & UART_S1_TDRE)) {
uint32_t tail = tx_buffer_tail;
if (++tail >= SERIAL5_TX_BUFFER_SIZE) tail = 0;
n = tx_buffer[tail];
if (++tail >= tx_buffer_total_size_) tail = 0;
if (tail < SERIAL5_TX_BUFFER_SIZE) {
n = tx_buffer[tail];
} else {
n = tx_buffer_storage_[tail-SERIAL5_TX_BUFFER_SIZE];
}
if (use9Bits) UART4_C3 = (UART4_C3 & ~0x40) | ((n & 0x100) >> 2);
UART4_D = n;
tx_buffer_tail = tail;
@@ -250,7 +263,11 @@ void serial5_putchar(uint32_t c)
yield(); // wait
}
}
tx_buffer[head] = c;
if (head < SERIAL5_TX_BUFFER_SIZE) {
tx_buffer[head] = c;
} else {
tx_buffer_storage_[head - SERIAL5_TX_BUFFER_SIZE] = c;
}
transmitting = 1;
tx_buffer_head = head;
UART4_C2 = C2_TX_ACTIVE;
@@ -273,7 +290,7 @@ int serial5_write_buffer_free(void)

head = tx_buffer_head;
tail = tx_buffer_tail;
if (head >= tail) return SERIAL5_TX_BUFFER_SIZE - 1 - head + tail;
if (head >= tail) return tx_buffer_total_size_ - 1 - head + tail;
return tail - head - 1;
}

@@ -284,7 +301,7 @@ int serial5_available(void)
head = rx_buffer_head;
tail = rx_buffer_tail;
if (head >= tail) return head - tail;
return SERIAL5_RX_BUFFER_SIZE + head - tail;
return rx_buffer_total_size_ + head - tail;
}

int serial5_getchar(void)
@@ -295,14 +312,18 @@ int serial5_getchar(void)
head = rx_buffer_head;
tail = rx_buffer_tail;
if (head == tail) return -1;
if (++tail >= SERIAL5_RX_BUFFER_SIZE) tail = 0;
c = rx_buffer[tail];
if (++tail >= rx_buffer_total_size_) tail = 0;
if (tail < SERIAL5_RX_BUFFER_SIZE) {
c = rx_buffer[tail];
} else {
c = rx_buffer_storage_[tail-SERIAL5_RX_BUFFER_SIZE];
}
rx_buffer_tail = tail;
if (rts_pin) {
int avail;
if (head >= tail) avail = head - tail;
else avail = SERIAL5_RX_BUFFER_SIZE + head - tail;
if (avail <= RTS_LOW_WATERMARK) rts_assert();
else avail = rx_buffer_total_size_ + head - tail;
if (avail <= rts_low_watermark_) rts_assert();
}
return c;
}
@@ -314,8 +335,11 @@ int serial5_peek(void)
head = rx_buffer_head;
tail = rx_buffer_tail;
if (head == tail) return -1;
if (++tail >= SERIAL5_RX_BUFFER_SIZE) tail = 0;
return rx_buffer[tail];
if (++tail >= rx_buffer_total_size_) tail = 0;
if (tail < SERIAL5_RX_BUFFER_SIZE) {
return rx_buffer[tail];
}
return rx_buffer_storage_[tail-SERIAL5_RX_BUFFER_SIZE];
}

void serial5_clear(void)
@@ -344,17 +368,22 @@ void uart4_status_isr(void)
n = UART4_D;
}
head = rx_buffer_head + 1;
if (head >= SERIAL5_RX_BUFFER_SIZE) head = 0;
if (head >= rx_buffer_total_size_) head = 0;
if (head != rx_buffer_tail) {
rx_buffer[head] = n;
if (head < SERIAL5_RX_BUFFER_SIZE) {
rx_buffer[head] = n;
} else {
rx_buffer_storage_[head-SERIAL5_RX_BUFFER_SIZE] = n;
}

rx_buffer_head = head;
}
if (rts_pin) {
int avail;
tail = tx_buffer_tail;
if (head >= tail) avail = head - tail;
else avail = SERIAL5_RX_BUFFER_SIZE + head - tail;
if (avail >= RTS_HIGH_WATERMARK) rts_deassert();
else avail = rx_buffer_total_size_ + head - tail;
if (avail >= rts_high_watermark_) rts_deassert();
}
}
c = UART4_C2;
@@ -364,8 +393,12 @@ void uart4_status_isr(void)
if (head == tail) {
UART4_C2 = C2_TX_COMPLETING;
} else {
if (++tail >= SERIAL5_TX_BUFFER_SIZE) tail = 0;
n = tx_buffer[tail];
if (++tail >= tx_buffer_total_size_) tail = 0;
if (tail < SERIAL5_TX_BUFFER_SIZE) {
n = tx_buffer[tail];
} else {
n = tx_buffer_storage_[tail-SERIAL5_TX_BUFFER_SIZE];
}
if (use9Bits) UART4_C3 = (UART4_C3 & ~0x40) | ((n & 0x100) >> 2);
UART4_D = n;
tx_buffer_tail = tail;
@@ -378,4 +411,28 @@ void uart4_status_isr(void)
}
}

void serial5_add_memory_for_read(void *buffer, size_t length)
{
rx_buffer_storage_ = (BUFTYPE*)buffer;
if (buffer) {
rx_buffer_total_size_ = SERIAL5_RX_BUFFER_SIZE + length;
} else {
rx_buffer_total_size_ = SERIAL5_RX_BUFFER_SIZE;
}

rts_low_watermark_ = RTS_LOW_WATERMARK + length;
rts_high_watermark_ = RTS_HIGH_WATERMARK + length;
}

void serial5_add_memory_for_write(void *buffer, size_t length)
{
tx_buffer_storage_ = (BUFTYPE*)buffer;
if (buffer) {
tx_buffer_total_size_ = SERIAL5_TX_BUFFER_SIZE + length;
} else {
tx_buffer_total_size_ = SERIAL5_TX_BUFFER_SIZE;
}
}


#endif // HAS_KINETISK_UART4

+ 75
- 18
teensy3/serial6.c View File

@@ -31,6 +31,7 @@
#include "kinetis.h"
#include "core_pins.h"
#include "HardwareSerial.h"
#include <stddef.h>

#ifdef HAS_KINETISK_UART5

@@ -63,6 +64,14 @@ static uint8_t use9Bits = 0;

static volatile BUFTYPE tx_buffer[SERIAL6_TX_BUFFER_SIZE];
static volatile BUFTYPE rx_buffer[SERIAL6_RX_BUFFER_SIZE];
static volatile BUFTYPE *rx_buffer_storage_ = NULL;
static volatile BUFTYPE *tx_buffer_storage_ = NULL;

static size_t tx_buffer_total_size_ = SERIAL6_TX_BUFFER_SIZE;
static size_t rx_buffer_total_size_ = SERIAL6_RX_BUFFER_SIZE;
static size_t rts_low_watermark_ = RTS_LOW_WATERMARK;
static size_t rts_high_watermark_ = RTS_HIGH_WATERMARK;

static volatile uint8_t transmitting = 0;
static volatile uint8_t *transmit_pin=NULL;
#define transmit_assert() *transmit_pin = 1
@@ -234,14 +243,18 @@ void serial6_putchar(uint32_t c)
if (!(SIM_SCGC1 & SIM_SCGC1_UART5)) return;
if (transmit_pin) transmit_assert();
head = tx_buffer_head;
if (++head >= SERIAL6_TX_BUFFER_SIZE) head = 0;
if (++head >= tx_buffer_total_size_) head = 0;
while (tx_buffer_tail == head) {
int priority = nvic_execution_priority();
if (priority <= IRQ_PRIORITY) {
if ((UART5_S1 & UART_S1_TDRE)) {
uint32_t tail = tx_buffer_tail;
if (++tail >= SERIAL6_TX_BUFFER_SIZE) tail = 0;
n = tx_buffer[tail];
if (++tail >= tx_buffer_total_size_) tail = 0;
if (tail < SERIAL6_TX_BUFFER_SIZE) {
n = tx_buffer[tail];
} else {
n = tx_buffer_storage_[tail-SERIAL6_TX_BUFFER_SIZE];
}
if (use9Bits) UART5_C3 = (UART5_C3 & ~0x40) | ((n & 0x100) >> 2);
UART5_D = n;
tx_buffer_tail = tail;
@@ -250,7 +263,11 @@ void serial6_putchar(uint32_t c)
yield(); // wait
}
}
tx_buffer[head] = c;
if (head < SERIAL6_TX_BUFFER_SIZE) {
tx_buffer[head] = c;
} else {
tx_buffer_storage_[head - SERIAL6_TX_BUFFER_SIZE] = c;
}
transmitting = 1;
tx_buffer_head = head;
UART5_C2 = C2_TX_ACTIVE;
@@ -273,7 +290,7 @@ int serial6_write_buffer_free(void)

head = tx_buffer_head;
tail = tx_buffer_tail;
if (head >= tail) return SERIAL6_TX_BUFFER_SIZE - 1 - head + tail;
if (head >= tail) return tx_buffer_total_size_ - 1 - head + tail;
return tail - head - 1;
}

@@ -284,7 +301,7 @@ int serial6_available(void)
head = rx_buffer_head;
tail = rx_buffer_tail;
if (head >= tail) return head - tail;
return SERIAL6_RX_BUFFER_SIZE + head - tail;
return rx_buffer_total_size_ + head - tail;
}

int serial6_getchar(void)
@@ -295,14 +312,18 @@ int serial6_getchar(void)
head = rx_buffer_head;
tail = rx_buffer_tail;
if (head == tail) return -1;
if (++tail >= SERIAL6_RX_BUFFER_SIZE) tail = 0;
c = rx_buffer[tail];
if (++tail >= rx_buffer_total_size_) tail = 0;
if (tail < SERIAL6_RX_BUFFER_SIZE) {
c = rx_buffer[tail];
} else {
c = rx_buffer_storage_[tail-SERIAL6_RX_BUFFER_SIZE];
}
rx_buffer_tail = tail;
if (rts_pin) {
int avail;
if (head >= tail) avail = head - tail;
else avail = SERIAL6_RX_BUFFER_SIZE + head - tail;
if (avail <= RTS_LOW_WATERMARK) rts_assert();
else avail = rx_buffer_total_size_ + head - tail;
if (avail <= rts_low_watermark_) rts_assert();
}
return c;
}
@@ -314,8 +335,11 @@ int serial6_peek(void)
head = rx_buffer_head;
tail = rx_buffer_tail;
if (head == tail) return -1;
if (++tail >= SERIAL6_RX_BUFFER_SIZE) tail = 0;
return rx_buffer[tail];
if (++tail >= rx_buffer_total_size_) tail = 0;
if (tail < SERIAL6_RX_BUFFER_SIZE) {
return rx_buffer[tail];
}
return rx_buffer_storage_[tail-SERIAL6_RX_BUFFER_SIZE];
}

void serial6_clear(void)
@@ -344,17 +368,22 @@ void uart5_status_isr(void)
n = UART5_D;
}
head = rx_buffer_head + 1;
if (head >= SERIAL6_RX_BUFFER_SIZE) head = 0;
if (head >= rx_buffer_total_size_) head = 0;
if (head != rx_buffer_tail) {
rx_buffer[head] = n;
if (head < SERIAL6_RX_BUFFER_SIZE) {
rx_buffer[head] = n;
} else {
rx_buffer_storage_[head-SERIAL6_RX_BUFFER_SIZE] = n;
}

rx_buffer_head = head;
}
if (rts_pin) {
int avail;
tail = tx_buffer_tail;
if (head >= tail) avail = head - tail;
else avail = SERIAL6_RX_BUFFER_SIZE + head - tail;
if (avail >= RTS_HIGH_WATERMARK) rts_deassert();
else avail = rx_buffer_total_size_ + head - tail;
if (avail >= rts_high_watermark_) rts_deassert();
}
}
c = UART5_C2;
@@ -364,8 +393,12 @@ void uart5_status_isr(void)
if (head == tail) {
UART5_C2 = C2_TX_COMPLETING;
} else {
if (++tail >= SERIAL6_TX_BUFFER_SIZE) tail = 0;
n = tx_buffer[tail];
if (++tail >= tx_buffer_total_size_) tail = 0;
if (tail < SERIAL6_TX_BUFFER_SIZE) {
n = tx_buffer[tail];
} else {
n = tx_buffer_storage_[tail-SERIAL6_TX_BUFFER_SIZE];
}
if (use9Bits) UART5_C3 = (UART5_C3 & ~0x40) | ((n & 0x100) >> 2);
UART5_D = n;
tx_buffer_tail = tail;
@@ -378,4 +411,28 @@ void uart5_status_isr(void)
}
}

void serial6_add_memory_for_read(void *buffer, size_t length)
{
rx_buffer_storage_ = (BUFTYPE*)buffer;
if (buffer) {
rx_buffer_total_size_ = SERIAL6_RX_BUFFER_SIZE + length;
} else {
rx_buffer_total_size_ = SERIAL6_RX_BUFFER_SIZE;
}

rts_low_watermark_ = RTS_LOW_WATERMARK + length;
rts_high_watermark_ = RTS_HIGH_WATERMARK + length;
}

void serial6_add_memory_for_write(void *buffer, size_t length)
{
tx_buffer_storage_ = (BUFTYPE*)buffer;
if (buffer) {
tx_buffer_total_size_ = SERIAL6_TX_BUFFER_SIZE + length;
} else {
tx_buffer_total_size_ = SERIAL6_TX_BUFFER_SIZE;
}
}


#endif // HAS_KINETISK_UART5

+ 69
- 17
teensy3/serial6_lpuart.c View File

@@ -71,6 +71,14 @@ static uint8_t use9Bits = 0;

static volatile BUFTYPE tx_buffer[SERIAL6_TX_BUFFER_SIZE];
static volatile BUFTYPE rx_buffer[SERIAL6_RX_BUFFER_SIZE];
static volatile BUFTYPE *rx_buffer_storage_ = NULL;
static volatile BUFTYPE *tx_buffer_storage_ = NULL;

static size_t tx_buffer_total_size_ = SERIAL6_TX_BUFFER_SIZE;
static size_t rx_buffer_total_size_ = SERIAL6_RX_BUFFER_SIZE;
static size_t rts_low_watermark_ = RTS_LOW_WATERMARK;
static size_t rts_high_watermark_ = RTS_HIGH_WATERMARK;

static volatile uint8_t transmitting = 0;
static volatile uint8_t *transmit_pin=NULL;
#define transmit_assert() *transmit_pin = 1
@@ -308,14 +316,18 @@ void serial6_putchar(uint32_t c)
if (!(SIM_SCGC2 & SIM_SCGC2_LPUART0)) return;
if (transmit_pin) transmit_assert();
head = tx_buffer_head;
if (++head >= SERIAL6_TX_BUFFER_SIZE) head = 0;
if (++head >= tx_buffer_total_size_) head = 0;
while (tx_buffer_tail == head) {
int priority = nvic_execution_priority();
if (priority <= IRQ_PRIORITY) {
if ((LPUART0_STAT & LPUART_STAT_TDRE)) {
uint32_t tail = tx_buffer_tail;
if (++tail >= SERIAL6_TX_BUFFER_SIZE) tail = 0;
n = tx_buffer[tail];
if (++tail >= tx_buffer_total_size_) tail = 0;
if (tail < SERIAL6_TX_BUFFER_SIZE) {
n = tx_buffer[tail];
} else {
n = tx_buffer_storage_[tail-SERIAL6_TX_BUFFER_SIZE];
}
//if (use9Bits) UART5_C3 = (UART5_C3 & ~0x40) | ((n & 0x100) >> 2);
LPUART0_DATA = n;
tx_buffer_tail = tail;
@@ -350,7 +362,7 @@ int serial6_write_buffer_free(void)

head = tx_buffer_head;
tail = tx_buffer_tail;
if (head >= tail) return SERIAL6_TX_BUFFER_SIZE - 1 - head + tail;
if (head >= tail) return tx_buffer_total_size_ - 1 - head + tail;
return tail - head - 1;
}

@@ -361,7 +373,7 @@ int serial6_available(void)
head = rx_buffer_head;
tail = rx_buffer_tail;
if (head >= tail) return head - tail;
return SERIAL6_RX_BUFFER_SIZE + head - tail;
return rx_buffer_total_size_ + head - tail;
}

int serial6_getchar(void)
@@ -372,14 +384,18 @@ int serial6_getchar(void)
head = rx_buffer_head;
tail = rx_buffer_tail;
if (head == tail) return -1;
if (++tail >= SERIAL6_RX_BUFFER_SIZE) tail = 0;
c = rx_buffer[tail];
if (++tail >= rx_buffer_total_size_) tail = 0;
if (tail < SERIAL6_RX_BUFFER_SIZE) {
c = rx_buffer[tail];
} else {
c = rx_buffer_storage_[tail-SERIAL6_RX_BUFFER_SIZE];
}
rx_buffer_tail = tail;
if (rts_pin) {
int avail;
if (head >= tail) avail = head - tail;
else avail = SERIAL6_RX_BUFFER_SIZE + head - tail;
if (avail <= RTS_LOW_WATERMARK) rts_assert();
else avail = rx_buffer_total_size_ + head - tail;
if (avail <= rts_low_watermark_) rts_assert();
}
return c;
}
@@ -391,8 +407,11 @@ int serial6_peek(void)
head = rx_buffer_head;
tail = rx_buffer_tail;
if (head == tail) return -1;
if (++tail >= SERIAL6_RX_BUFFER_SIZE) tail = 0;
return rx_buffer[tail];
if (++tail >= rx_buffer_total_size_) tail = 0;
if (tail < SERIAL6_RX_BUFFER_SIZE) {
return rx_buffer[tail];
}
return rx_buffer_storage_[tail-SERIAL6_RX_BUFFER_SIZE];
}

void serial6_clear(void)
@@ -422,17 +441,22 @@ void lpuart0_status_isr(void)
// }
n = LPUART0_DATA & 0x3ff; // use only the 10 data bits
head = rx_buffer_head + 1;
if (head >= SERIAL6_RX_BUFFER_SIZE) head = 0;
if (head >= rx_buffer_total_size_) head = 0;
if (head != rx_buffer_tail) {
rx_buffer[head] = n;
if (head < SERIAL6_RX_BUFFER_SIZE) {
rx_buffer[head] = n;
} else {
rx_buffer_storage_[head-SERIAL6_RX_BUFFER_SIZE] = n;
}

rx_buffer_head = head;
}
if (rts_pin) {
int avail;
tail = tx_buffer_tail;
if (head >= tail) avail = head - tail;
else avail = SERIAL6_RX_BUFFER_SIZE + head - tail;
if (avail >= RTS_HIGH_WATERMARK) rts_deassert();
else avail = rx_buffer_total_size_ + head - tail;
if (avail >= rts_high_watermark_) rts_deassert();
}
}
c = LPUART0_CTRL;
@@ -445,8 +469,12 @@ void lpuart0_status_isr(void)
//LPUART0_CTRL &= ~LPUART_CTRL_TIE;
//LPUART0_CTRL |= LPUART_CTRL_TCIE; // Actually wondering if we can just leave this one on...
} else {
if (++tail >= SERIAL6_TX_BUFFER_SIZE) tail = 0;
n = tx_buffer[tail];
if (++tail >= tx_buffer_total_size_) tail = 0;
if (tail < SERIAL6_TX_BUFFER_SIZE) {
n = tx_buffer[tail];
} else {
n = tx_buffer_storage_[tail-SERIAL6_TX_BUFFER_SIZE];
}
//if (use9Bits) UART5_C3 = (UART5_C3 & ~0x40) | ((n & 0x100) >> 2);
LPUART0_DATA = n;
tx_buffer_tail = tail;
@@ -460,4 +488,28 @@ void lpuart0_status_isr(void)
}
}

void serial6_add_memory_for_read(void *buffer, size_t length)
{
rx_buffer_storage_ = (BUFTYPE*)buffer;
if (buffer) {
rx_buffer_total_size_ = SERIAL6_RX_BUFFER_SIZE + length;
} else {
rx_buffer_total_size_ = SERIAL6_RX_BUFFER_SIZE;
}

rts_low_watermark_ = RTS_LOW_WATERMARK + length;
rts_high_watermark_ = RTS_HIGH_WATERMARK + length;
}

void serial6_add_memory_for_write(void *buffer, size_t length)
{
tx_buffer_storage_ = (BUFTYPE*)buffer;
if (buffer) {
tx_buffer_total_size_ = SERIAL6_TX_BUFFER_SIZE + length;
} else {
tx_buffer_total_size_ = SERIAL6_TX_BUFFER_SIZE;
}
}


#endif // HAS_KINETISK_LPUART0

+ 3
- 0
teensy4/HardwareSerial.cpp View File

@@ -647,6 +647,9 @@ void HardwareSerial::IRQHandler()


void HardwareSerial::addToSerialEventsList() {
for (uint8_t i = 0; i < s_count_serials_with_serial_events; i++) {
if (s_serials_with_serial_events[i] == this) return; // already in the list.
}
s_serials_with_serial_events[s_count_serials_with_serial_events++] = this;
yield_active_check_flags |= YIELD_CHECK_HARDWARE_SERIAL;
}

Loading…
Cancel
Save