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.teensy4-core
// simple helper function that add us to the list of Serial ports that have | // 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. | // their own serialEvent code defined that needs to be called at yield. | ||||
void HardwareSerial::addToSerialEventsList() { | 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; | s_serials_with_serial_events[s_count_serials_with_serial_events++] = this; | ||||
yield_active_check_flags |= YIELD_CHECK_HARDWARE_SERIAL; | yield_active_check_flags |= YIELD_CHECK_HARDWARE_SERIAL; | ||||
} | } |
#define HardwareSerial_h | #define HardwareSerial_h | ||||
#include "kinetis.h" | #include "kinetis.h" | ||||
#include <stddef.h> | |||||
// Uncomment to enable 9 bit formats. These are default disabled to save memory. | // Uncomment to enable 9 bit formats. These are default disabled to save memory. | ||||
//#define SERIAL_9BIT_SUPPORT | //#define SERIAL_9BIT_SUPPORT | ||||
void serial_write(const void *buf, unsigned int count); | void serial_write(const void *buf, unsigned int count); | ||||
void serial_flush(void); | void serial_flush(void); | ||||
int serial_write_buffer_free(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_available(void); | ||||
int serial_getchar(void); | int serial_getchar(void); | ||||
int serial_peek(void); | int serial_peek(void); | ||||
void serial2_write(const void *buf, unsigned int count); | void serial2_write(const void *buf, unsigned int count); | ||||
void serial2_flush(void); | void serial2_flush(void); | ||||
int serial2_write_buffer_free(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_available(void); | ||||
int serial2_getchar(void); | int serial2_getchar(void); | ||||
int serial2_peek(void); | int serial2_peek(void); | ||||
void serial3_write(const void *buf, unsigned int count); | void serial3_write(const void *buf, unsigned int count); | ||||
void serial3_flush(void); | void serial3_flush(void); | ||||
int serial3_write_buffer_free(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_available(void); | ||||
int serial3_getchar(void); | int serial3_getchar(void); | ||||
int serial3_peek(void); | int serial3_peek(void); | ||||
void serial4_write(const void *buf, unsigned int count); | void serial4_write(const void *buf, unsigned int count); | ||||
void serial4_flush(void); | void serial4_flush(void); | ||||
int serial4_write_buffer_free(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_available(void); | ||||
int serial4_getchar(void); | int serial4_getchar(void); | ||||
int serial4_peek(void); | int serial4_peek(void); | ||||
void serial5_write(const void *buf, unsigned int count); | void serial5_write(const void *buf, unsigned int count); | ||||
void serial5_flush(void); | void serial5_flush(void); | ||||
int serial5_write_buffer_free(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_available(void); | ||||
int serial5_getchar(void); | int serial5_getchar(void); | ||||
int serial5_peek(void); | int serial5_peek(void); | ||||
void serial6_write(const void *buf, unsigned int count); | void serial6_write(const void *buf, unsigned int count); | ||||
void serial6_flush(void); | void serial6_flush(void); | ||||
int serial6_write_buffer_free(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_available(void); | ||||
int serial6_getchar(void); | int serial6_getchar(void); | ||||
int serial6_peek(void); | int serial6_peek(void); | ||||
virtual void flush(void) { serial_flush(); } | virtual void flush(void) { serial_flush(); } | ||||
virtual void clear(void) { serial_clear(); } | virtual void clear(void) { serial_clear(); } | ||||
virtual int availableForWrite(void) { return serial_write_buffer_free(); } | 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; | using Print::write; | ||||
virtual size_t write(uint8_t c) { serial_putchar(c); return 1; } | virtual size_t write(uint8_t c) { serial_putchar(c); return 1; } | ||||
virtual size_t write(unsigned long n) { return write((uint8_t)n); } | virtual size_t write(unsigned long n) { return write((uint8_t)n); } | ||||
virtual void flush(void) { serial2_flush(); } | virtual void flush(void) { serial2_flush(); } | ||||
virtual void clear(void) { serial2_clear(); } | virtual void clear(void) { serial2_clear(); } | ||||
virtual int availableForWrite(void) { return serial2_write_buffer_free(); } | 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; | using Print::write; | ||||
virtual size_t write(uint8_t c) { serial2_putchar(c); return 1; } | virtual size_t write(uint8_t c) { serial2_putchar(c); return 1; } | ||||
virtual size_t write(unsigned long n) { return write((uint8_t)n); } | virtual size_t write(unsigned long n) { return write((uint8_t)n); } | ||||
virtual void flush(void) { serial3_flush(); } | virtual void flush(void) { serial3_flush(); } | ||||
virtual void clear(void) { serial3_clear(); } | virtual void clear(void) { serial3_clear(); } | ||||
virtual int availableForWrite(void) { return serial3_write_buffer_free(); } | 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; | using Print::write; | ||||
virtual size_t write(uint8_t c) { serial3_putchar(c); return 1; } | virtual size_t write(uint8_t c) { serial3_putchar(c); return 1; } | ||||
virtual size_t write(unsigned long n) { return write((uint8_t)n); } | virtual size_t write(unsigned long n) { return write((uint8_t)n); } | ||||
virtual void flush(void) { serial4_flush(); } | virtual void flush(void) { serial4_flush(); } | ||||
virtual void clear(void) { serial4_clear(); } | virtual void clear(void) { serial4_clear(); } | ||||
virtual int availableForWrite(void) { return serial4_write_buffer_free(); } | 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; | using Print::write; | ||||
virtual size_t write(uint8_t c) { serial4_putchar(c); return 1; } | virtual size_t write(uint8_t c) { serial4_putchar(c); return 1; } | ||||
virtual size_t write(unsigned long n) { return write((uint8_t)n); } | virtual size_t write(unsigned long n) { return write((uint8_t)n); } | ||||
virtual void flush(void) { serial5_flush(); } | virtual void flush(void) { serial5_flush(); } | ||||
virtual void clear(void) { serial5_clear(); } | virtual void clear(void) { serial5_clear(); } | ||||
virtual int availableForWrite(void) { return serial5_write_buffer_free(); } | 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; | using Print::write; | ||||
virtual size_t write(uint8_t c) { serial5_putchar(c); return 1; } | virtual size_t write(uint8_t c) { serial5_putchar(c); return 1; } | ||||
virtual size_t write(unsigned long n) { return write((uint8_t)n); } | virtual size_t write(unsigned long n) { return write((uint8_t)n); } | ||||
virtual void flush(void) { serial6_flush(); } | virtual void flush(void) { serial6_flush(); } | ||||
virtual void clear(void) { serial6_clear(); } | virtual void clear(void) { serial6_clear(); } | ||||
virtual int availableForWrite(void) { return serial6_write_buffer_free(); } | 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; | using Print::write; | ||||
virtual size_t write(uint8_t c) { serial6_putchar(c); return 1; } | virtual size_t write(uint8_t c) { serial6_putchar(c); return 1; } | ||||
virtual size_t write(unsigned long n) { return write((uint8_t)n); } | virtual size_t write(unsigned long n) { return write((uint8_t)n); } |
#include "kinetis.h" | #include "kinetis.h" | ||||
#include "core_pins.h" | #include "core_pins.h" | ||||
#include "HardwareSerial.h" | #include "HardwareSerial.h" | ||||
#include <stddef.h> | |||||
//////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////// | ||||
// Tunable parameters (relatively safe to edit these numbers) | // Tunable parameters (relatively safe to edit these numbers) | ||||
static volatile BUFTYPE tx_buffer[SERIAL1_TX_BUFFER_SIZE]; | static volatile BUFTYPE tx_buffer[SERIAL1_TX_BUFFER_SIZE]; | ||||
static volatile BUFTYPE rx_buffer[SERIAL1_RX_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; | static volatile uint8_t transmitting = 0; | ||||
#if defined(KINETISK) | #if defined(KINETISK) | ||||
static volatile uint8_t *transmit_pin=NULL; | static volatile uint8_t *transmit_pin=NULL; | ||||
if (!(SIM_SCGC4 & SIM_SCGC4_UART0)) return; | if (!(SIM_SCGC4 & SIM_SCGC4_UART0)) return; | ||||
if (transmit_pin) transmit_assert(); | if (transmit_pin) transmit_assert(); | ||||
head = tx_buffer_head; | 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) { | while (tx_buffer_tail == head) { | ||||
int priority = nvic_execution_priority(); | int priority = nvic_execution_priority(); | ||||
if (priority <= IRQ_PRIORITY) { | if (priority <= IRQ_PRIORITY) { | ||||
if ((UART0_S1 & UART_S1_TDRE)) { | if ((UART0_S1 & UART_S1_TDRE)) { | ||||
uint32_t tail = tx_buffer_tail; | 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); | if (use9Bits) UART0_C3 = (UART0_C3 & ~0x40) | ((n & 0x100) >> 2); | ||||
UART0_D = n; | UART0_D = n; | ||||
tx_buffer_tail = tail; | tx_buffer_tail = tail; | ||||
yield(); | 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; | transmitting = 1; | ||||
tx_buffer_head = head; | tx_buffer_head = head; | ||||
UART0_C2 = C2_TX_ACTIVE; | UART0_C2 = C2_TX_ACTIVE; | ||||
if (transmit_pin) transmit_assert(); | if (transmit_pin) transmit_assert(); | ||||
while (p < end) { | while (p < end) { | ||||
head = tx_buffer_head; | 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) { | if (tx_buffer_tail == head) { | ||||
UART0_C2 = C2_TX_ACTIVE; | UART0_C2 = C2_TX_ACTIVE; | ||||
do { | do { | ||||
if (priority <= IRQ_PRIORITY) { | if (priority <= IRQ_PRIORITY) { | ||||
if ((UART0_S1 & UART_S1_TDRE)) { | if ((UART0_S1 & UART_S1_TDRE)) { | ||||
uint32_t tail = tx_buffer_tail; | 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); | if (use9Bits) UART0_C3 = (UART0_C3 & ~0x40) | ((n & 0x100) >> 2); | ||||
UART0_D = n; | UART0_D = n; | ||||
tx_buffer_tail = tail; | tx_buffer_tail = tail; | ||||
} | } | ||||
} while (tx_buffer_tail == head); | } 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; | transmitting = 1; | ||||
tx_buffer_head = head; | tx_buffer_head = head; | ||||
} | } | ||||
head = tx_buffer_head; | head = tx_buffer_head; | ||||
tail = tx_buffer_tail; | 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; | return tail - head - 1; | ||||
} | } | ||||
head = rx_buffer_head; | head = rx_buffer_head; | ||||
tail = rx_buffer_tail; | tail = rx_buffer_tail; | ||||
if (head >= tail) return head - 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) | int serial_getchar(void) | ||||
head = rx_buffer_head; | head = rx_buffer_head; | ||||
tail = rx_buffer_tail; | tail = rx_buffer_tail; | ||||
if (head == tail) return -1; | 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; | rx_buffer_tail = tail; | ||||
if (rts_pin) { | if (rts_pin) { | ||||
int avail; | int avail; | ||||
if (head >= tail) avail = head - tail; | 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; | return c; | ||||
} | } | ||||
head = rx_buffer_head; | head = rx_buffer_head; | ||||
tail = rx_buffer_tail; | tail = rx_buffer_tail; | ||||
if (head == tail) return -1; | 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) | void serial_clear(void) | ||||
n = UART0_D; | n = UART0_D; | ||||
} | } | ||||
newhead = head + 1; | newhead = head + 1; | ||||
if (newhead >= SERIAL1_RX_BUFFER_SIZE) newhead = 0; | |||||
if (newhead >= rx_buffer_total_size_) newhead = 0; | |||||
if (newhead != tail) { | if (newhead != tail) { | ||||
head = newhead; | 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); | } while (--avail > 0); | ||||
rx_buffer_head = head; | rx_buffer_head = head; | ||||
if (rts_pin) { | if (rts_pin) { | ||||
int avail; | int avail; | ||||
if (head >= tail) avail = head - tail; | 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(); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
tail = tx_buffer_tail; | tail = tx_buffer_tail; | ||||
do { | do { | ||||
if (tail == head) break; | if (tail == head) break; | ||||
if (++tail >= SERIAL1_TX_BUFFER_SIZE) tail = 0; | |||||
if (++tail >= tx_buffer_total_size_) tail = 0; | |||||
avail = UART0_S1; | 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); | if (use9Bits) UART0_C3 = (UART0_C3 & ~0x40) | ((n & 0x100) >> 2); | ||||
UART0_D = n; | UART0_D = n; | ||||
} while (UART0_TCFIFO < 8); | } while (UART0_TCFIFO < 8); | ||||
n = UART0_D; | n = UART0_D; | ||||
} | } | ||||
head = rx_buffer_head + 1; | 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) { | 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; | rx_buffer_head = head; | ||||
} | } | ||||
} | } | ||||
if (head == tail) { | if (head == tail) { | ||||
UART0_C2 = C2_TX_COMPLETING; | UART0_C2 = C2_TX_COMPLETING; | ||||
} else { | } 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); | if (use9Bits) UART0_C3 = (UART0_C3 & ~0x40) | ((n & 0x100) >> 2); | ||||
UART0_D = n; | UART0_D = n; | ||||
tx_buffer_tail = tail; | tx_buffer_tail = tail; | ||||
serial_phex(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; | |||||
} | |||||
} |
#include "kinetis.h" | #include "kinetis.h" | ||||
#include "core_pins.h" | #include "core_pins.h" | ||||
#include "HardwareSerial.h" | #include "HardwareSerial.h" | ||||
#include <stddef.h> | |||||
//////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////// | ||||
// Tunable parameters (relatively safe to edit these numbers) | // Tunable parameters (relatively safe to edit these numbers) | ||||
static volatile BUFTYPE tx_buffer[SERIAL2_TX_BUFFER_SIZE]; | static volatile BUFTYPE tx_buffer[SERIAL2_TX_BUFFER_SIZE]; | ||||
static volatile BUFTYPE rx_buffer[SERIAL2_RX_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; | static volatile uint8_t transmitting = 0; | ||||
#if defined(KINETISK) | #if defined(KINETISK) | ||||
static volatile uint8_t *transmit_pin=NULL; | static volatile uint8_t *transmit_pin=NULL; | ||||
if (!(SIM_SCGC4 & SIM_SCGC4_UART1)) return; | if (!(SIM_SCGC4 & SIM_SCGC4_UART1)) return; | ||||
if (transmit_pin) transmit_assert(); | if (transmit_pin) transmit_assert(); | ||||
head = tx_buffer_head; | 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) { | while (tx_buffer_tail == head) { | ||||
int priority = nvic_execution_priority(); | int priority = nvic_execution_priority(); | ||||
if (priority <= IRQ_PRIORITY) { | if (priority <= IRQ_PRIORITY) { | ||||
if ((UART1_S1 & UART_S1_TDRE)) { | if ((UART1_S1 & UART_S1_TDRE)) { | ||||
uint32_t tail = tx_buffer_tail; | 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); | if (use9Bits) UART1_C3 = (UART1_C3 & ~0x40) | ((n & 0x100) >> 2); | ||||
UART1_D = n; | UART1_D = n; | ||||
tx_buffer_tail = tail; | tx_buffer_tail = tail; | ||||
yield(); // wait | 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; | transmitting = 1; | ||||
tx_buffer_head = head; | tx_buffer_head = head; | ||||
UART1_C2 = C2_TX_ACTIVE; | UART1_C2 = C2_TX_ACTIVE; | ||||
if (transmit_pin) transmit_assert(); | if (transmit_pin) transmit_assert(); | ||||
while (p < end) { | while (p < end) { | ||||
head = tx_buffer_head; | 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) { | if (tx_buffer_tail == head) { | ||||
UART1_C2 = C2_TX_ACTIVE; | UART1_C2 = C2_TX_ACTIVE; | ||||
do { | do { | ||||
if (priority <= IRQ_PRIORITY) { | if (priority <= IRQ_PRIORITY) { | ||||
if ((UART1_S1 & UART_S1_TDRE)) { | if ((UART1_S1 & UART_S1_TDRE)) { | ||||
uint32_t tail = tx_buffer_tail; | 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); | if (use9Bits) UART1_C3 = (UART1_C3 & ~0x40) | ((n & 0x100) >> 2); | ||||
UART1_D = n; | UART1_D = n; | ||||
tx_buffer_tail = tail; | tx_buffer_tail = tail; | ||||
} | } | ||||
} while (tx_buffer_tail == head); | } 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; | transmitting = 1; | ||||
tx_buffer_head = head; | tx_buffer_head = head; | ||||
} | } | ||||
head = tx_buffer_head; | head = tx_buffer_head; | ||||
tail = tx_buffer_tail; | 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; | return tail - head - 1; | ||||
} | } | ||||
head = rx_buffer_head; | head = rx_buffer_head; | ||||
tail = rx_buffer_tail; | tail = rx_buffer_tail; | ||||
if (head >= tail) return head - 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) | int serial2_getchar(void) | ||||
head = rx_buffer_head; | head = rx_buffer_head; | ||||
tail = rx_buffer_tail; | tail = rx_buffer_tail; | ||||
if (head == tail) return -1; | 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; | rx_buffer_tail = tail; | ||||
if (rts_pin) { | if (rts_pin) { | ||||
int avail; | int avail; | ||||
if (head >= tail) avail = head - tail; | 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; | return c; | ||||
} | } | ||||
head = rx_buffer_head; | head = rx_buffer_head; | ||||
tail = rx_buffer_tail; | tail = rx_buffer_tail; | ||||
if (head == tail) return -1; | 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) | void serial2_clear(void) | ||||
n = UART1_D; | n = UART1_D; | ||||
} | } | ||||
newhead = head + 1; | newhead = head + 1; | ||||
if (newhead >= SERIAL2_RX_BUFFER_SIZE) newhead = 0; | |||||
if (newhead >= rx_buffer_total_size_) newhead = 0; | |||||
if (newhead != tail) { | if (newhead != tail) { | ||||
head = newhead; | 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); | } while (--avail > 0); | ||||
rx_buffer_head = head; | rx_buffer_head = head; | ||||
if (rts_pin) { | if (rts_pin) { | ||||
int avail; | int avail; | ||||
if (head >= tail) avail = head - tail; | 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(); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
tail = tx_buffer_tail; | tail = tx_buffer_tail; | ||||
do { | do { | ||||
if (tail == head) break; | if (tail == head) break; | ||||
if (++tail >= SERIAL2_TX_BUFFER_SIZE) tail = 0; | |||||
if (++tail >= tx_buffer_total_size_) tail = 0; | |||||
avail = UART1_S1; | 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); | if (use9Bits) UART1_C3 = (UART1_C3 & ~0x40) | ((n & 0x100) >> 2); | ||||
UART1_D = n; | UART1_D = n; | ||||
} while (UART1_TCFIFO < 8); | } while (UART1_TCFIFO < 8); | ||||
n = UART1_D; | n = UART1_D; | ||||
} | } | ||||
head = rx_buffer_head + 1; | 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) { | 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; | rx_buffer_head = head; | ||||
} | } | ||||
} | } | ||||
if (head == tail) { | if (head == tail) { | ||||
UART1_C2 = C2_TX_COMPLETING; | UART1_C2 = C2_TX_COMPLETING; | ||||
} else { | } 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); | if (use9Bits) UART1_C3 = (UART1_C3 & ~0x40) | ((n & 0x100) >> 2); | ||||
UART1_D = n; | UART1_D = n; | ||||
tx_buffer_tail = tail; | tx_buffer_tail = tail; | ||||
} | } | ||||
} | } | ||||
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; | |||||
} | |||||
} | |||||
#include "kinetis.h" | #include "kinetis.h" | ||||
#include "core_pins.h" | #include "core_pins.h" | ||||
#include "HardwareSerial.h" | #include "HardwareSerial.h" | ||||
#include <stddef.h> | |||||
//////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////// | ||||
// Tunable parameters (relatively safe to edit these numbers) | // Tunable parameters (relatively safe to edit these numbers) | ||||
static volatile BUFTYPE tx_buffer[SERIAL3_TX_BUFFER_SIZE]; | static volatile BUFTYPE tx_buffer[SERIAL3_TX_BUFFER_SIZE]; | ||||
static volatile BUFTYPE rx_buffer[SERIAL3_RX_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; | static volatile uint8_t transmitting = 0; | ||||
#if defined(KINETISK) | #if defined(KINETISK) | ||||
static volatile uint8_t *transmit_pin=NULL; | static volatile uint8_t *transmit_pin=NULL; | ||||
if (!(SIM_SCGC4 & SIM_SCGC4_UART2)) return; | if (!(SIM_SCGC4 & SIM_SCGC4_UART2)) return; | ||||
if (transmit_pin) transmit_assert(); | if (transmit_pin) transmit_assert(); | ||||
head = tx_buffer_head; | 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) { | while (tx_buffer_tail == head) { | ||||
int priority = nvic_execution_priority(); | int priority = nvic_execution_priority(); | ||||
if (priority <= IRQ_PRIORITY) { | if (priority <= IRQ_PRIORITY) { | ||||
if ((UART2_S1 & UART_S1_TDRE)) { | if ((UART2_S1 & UART_S1_TDRE)) { | ||||
uint32_t tail = tx_buffer_tail; | 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); | if (use9Bits) UART2_C3 = (UART2_C3 & ~0x40) | ((n & 0x100) >> 2); | ||||
UART2_D = n; | UART2_D = n; | ||||
tx_buffer_tail = tail; | tx_buffer_tail = tail; | ||||
yield(); // wait | 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; | transmitting = 1; | ||||
tx_buffer_head = head; | tx_buffer_head = head; | ||||
UART2_C2 = C2_TX_ACTIVE; | UART2_C2 = C2_TX_ACTIVE; | ||||
head = tx_buffer_head; | head = tx_buffer_head; | ||||
tail = tx_buffer_tail; | 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; | return tail - head - 1; | ||||
} | } | ||||
head = rx_buffer_head; | head = rx_buffer_head; | ||||
tail = rx_buffer_tail; | tail = rx_buffer_tail; | ||||
if (head >= tail) return head - 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) | int serial3_getchar(void) | ||||
head = rx_buffer_head; | head = rx_buffer_head; | ||||
tail = rx_buffer_tail; | tail = rx_buffer_tail; | ||||
if (head == tail) return -1; | 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; | rx_buffer_tail = tail; | ||||
if (rts_pin) { | if (rts_pin) { | ||||
int avail; | int avail; | ||||
if (head >= tail) avail = head - tail; | 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; | return c; | ||||
} | } | ||||
head = rx_buffer_head; | head = rx_buffer_head; | ||||
tail = rx_buffer_tail; | tail = rx_buffer_tail; | ||||
if (head == tail) return -1; | 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) | void serial3_clear(void) | ||||
n = UART2_D; | n = UART2_D; | ||||
} | } | ||||
head = rx_buffer_head + 1; | 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) { | 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; | rx_buffer_head = head; | ||||
} | } | ||||
if (rts_pin) { | if (rts_pin) { | ||||
int avail; | int avail; | ||||
tail = tx_buffer_tail; | tail = tx_buffer_tail; | ||||
if (head >= tail) avail = head - 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; | c = UART2_C2; | ||||
if (head == tail) { | if (head == tail) { | ||||
UART2_C2 = C2_TX_COMPLETING; | UART2_C2 = C2_TX_COMPLETING; | ||||
} else { | } 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); | if (use9Bits) UART2_C3 = (UART2_C3 & ~0x40) | ((n & 0x100) >> 2); | ||||
UART2_D = n; | UART2_D = n; | ||||
tx_buffer_tail = tail; | tx_buffer_tail = tail; | ||||
} | } | ||||
} | } | ||||
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; | |||||
} | |||||
} | |||||
#include "kinetis.h" | #include "kinetis.h" | ||||
#include "core_pins.h" | #include "core_pins.h" | ||||
#include "HardwareSerial.h" | #include "HardwareSerial.h" | ||||
#include <stddef.h> | |||||
#ifdef HAS_KINETISK_UART3 | #ifdef HAS_KINETISK_UART3 | ||||
static volatile BUFTYPE tx_buffer[SERIAL4_TX_BUFFER_SIZE]; | static volatile BUFTYPE tx_buffer[SERIAL4_TX_BUFFER_SIZE]; | ||||
static volatile BUFTYPE rx_buffer[SERIAL4_RX_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 transmitting = 0; | ||||
static volatile uint8_t *transmit_pin=NULL; | static volatile uint8_t *transmit_pin=NULL; | ||||
#define transmit_assert() *transmit_pin = 1 | #define transmit_assert() *transmit_pin = 1 | ||||
if (!(SIM_SCGC4 & SIM_SCGC4_UART3)) return; | if (!(SIM_SCGC4 & SIM_SCGC4_UART3)) return; | ||||
if (transmit_pin) transmit_assert(); | if (transmit_pin) transmit_assert(); | ||||
head = tx_buffer_head; | 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) { | while (tx_buffer_tail == head) { | ||||
int priority = nvic_execution_priority(); | int priority = nvic_execution_priority(); | ||||
if (priority <= IRQ_PRIORITY) { | if (priority <= IRQ_PRIORITY) { | ||||
if ((UART3_S1 & UART_S1_TDRE)) { | if ((UART3_S1 & UART_S1_TDRE)) { | ||||
uint32_t tail = tx_buffer_tail; | 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); | if (use9Bits) UART3_C3 = (UART3_C3 & ~0x40) | ((n & 0x100) >> 2); | ||||
UART3_D = n; | UART3_D = n; | ||||
tx_buffer_tail = tail; | tx_buffer_tail = tail; | ||||
yield(); // wait | 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; | transmitting = 1; | ||||
tx_buffer_head = head; | tx_buffer_head = head; | ||||
UART3_C2 = C2_TX_ACTIVE; | UART3_C2 = C2_TX_ACTIVE; | ||||
head = tx_buffer_head; | head = tx_buffer_head; | ||||
tail = tx_buffer_tail; | 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; | return tail - head - 1; | ||||
} | } | ||||
head = rx_buffer_head; | head = rx_buffer_head; | ||||
tail = rx_buffer_tail; | tail = rx_buffer_tail; | ||||
if (head >= tail) return head - 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) | int serial4_getchar(void) | ||||
head = rx_buffer_head; | head = rx_buffer_head; | ||||
tail = rx_buffer_tail; | tail = rx_buffer_tail; | ||||
if (head == tail) return -1; | 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; | rx_buffer_tail = tail; | ||||
if (rts_pin) { | if (rts_pin) { | ||||
int avail; | int avail; | ||||
if (head >= tail) avail = head - tail; | 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; | return c; | ||||
} | } | ||||
head = rx_buffer_head; | head = rx_buffer_head; | ||||
tail = rx_buffer_tail; | tail = rx_buffer_tail; | ||||
if (head == tail) return -1; | 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) | void serial4_clear(void) | ||||
n = UART3_D; | n = UART3_D; | ||||
} | } | ||||
head = rx_buffer_head + 1; | 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) { | 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; | rx_buffer_head = head; | ||||
} | } | ||||
if (rts_pin) { | if (rts_pin) { | ||||
int avail; | int avail; | ||||
tail = tx_buffer_tail; | tail = tx_buffer_tail; | ||||
if (head >= tail) avail = head - 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; | c = UART3_C2; | ||||
if (head == tail) { | if (head == tail) { | ||||
UART3_C2 = C2_TX_COMPLETING; | UART3_C2 = C2_TX_COMPLETING; | ||||
} else { | } 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); | if (use9Bits) UART3_C3 = (UART3_C3 & ~0x40) | ((n & 0x100) >> 2); | ||||
UART3_D = n; | UART3_D = n; | ||||
tx_buffer_tail = tail; | tx_buffer_tail = tail; | ||||
} | } | ||||
} | } | ||||
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 | #endif // HAS_KINETISK_UART3 |
#include "kinetis.h" | #include "kinetis.h" | ||||
#include "core_pins.h" | #include "core_pins.h" | ||||
#include "HardwareSerial.h" | #include "HardwareSerial.h" | ||||
#include <stddef.h> | |||||
#ifdef HAS_KINETISK_UART4 | #ifdef HAS_KINETISK_UART4 | ||||
static volatile BUFTYPE tx_buffer[SERIAL5_TX_BUFFER_SIZE]; | static volatile BUFTYPE tx_buffer[SERIAL5_TX_BUFFER_SIZE]; | ||||
static volatile BUFTYPE rx_buffer[SERIAL5_RX_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 transmitting = 0; | ||||
static volatile uint8_t *transmit_pin=NULL; | static volatile uint8_t *transmit_pin=NULL; | ||||
#define transmit_assert() *transmit_pin = 1 | #define transmit_assert() *transmit_pin = 1 | ||||
if (!(SIM_SCGC1 & SIM_SCGC1_UART4)) return; | if (!(SIM_SCGC1 & SIM_SCGC1_UART4)) return; | ||||
if (transmit_pin) transmit_assert(); | if (transmit_pin) transmit_assert(); | ||||
head = tx_buffer_head; | 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) { | while (tx_buffer_tail == head) { | ||||
int priority = nvic_execution_priority(); | int priority = nvic_execution_priority(); | ||||
if (priority <= IRQ_PRIORITY) { | if (priority <= IRQ_PRIORITY) { | ||||
if ((UART4_S1 & UART_S1_TDRE)) { | if ((UART4_S1 & UART_S1_TDRE)) { | ||||
uint32_t tail = tx_buffer_tail; | 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); | if (use9Bits) UART4_C3 = (UART4_C3 & ~0x40) | ((n & 0x100) >> 2); | ||||
UART4_D = n; | UART4_D = n; | ||||
tx_buffer_tail = tail; | tx_buffer_tail = tail; | ||||
yield(); // wait | 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; | transmitting = 1; | ||||
tx_buffer_head = head; | tx_buffer_head = head; | ||||
UART4_C2 = C2_TX_ACTIVE; | UART4_C2 = C2_TX_ACTIVE; | ||||
head = tx_buffer_head; | head = tx_buffer_head; | ||||
tail = tx_buffer_tail; | 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; | return tail - head - 1; | ||||
} | } | ||||
head = rx_buffer_head; | head = rx_buffer_head; | ||||
tail = rx_buffer_tail; | tail = rx_buffer_tail; | ||||
if (head >= tail) return head - 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) | int serial5_getchar(void) | ||||
head = rx_buffer_head; | head = rx_buffer_head; | ||||
tail = rx_buffer_tail; | tail = rx_buffer_tail; | ||||
if (head == tail) return -1; | 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; | rx_buffer_tail = tail; | ||||
if (rts_pin) { | if (rts_pin) { | ||||
int avail; | int avail; | ||||
if (head >= tail) avail = head - tail; | 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; | return c; | ||||
} | } | ||||
head = rx_buffer_head; | head = rx_buffer_head; | ||||
tail = rx_buffer_tail; | tail = rx_buffer_tail; | ||||
if (head == tail) return -1; | 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) | void serial5_clear(void) | ||||
n = UART4_D; | n = UART4_D; | ||||
} | } | ||||
head = rx_buffer_head + 1; | 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) { | 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; | rx_buffer_head = head; | ||||
} | } | ||||
if (rts_pin) { | if (rts_pin) { | ||||
int avail; | int avail; | ||||
tail = tx_buffer_tail; | tail = tx_buffer_tail; | ||||
if (head >= tail) avail = head - 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; | c = UART4_C2; | ||||
if (head == tail) { | if (head == tail) { | ||||
UART4_C2 = C2_TX_COMPLETING; | UART4_C2 = C2_TX_COMPLETING; | ||||
} else { | } 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); | if (use9Bits) UART4_C3 = (UART4_C3 & ~0x40) | ((n & 0x100) >> 2); | ||||
UART4_D = n; | UART4_D = n; | ||||
tx_buffer_tail = tail; | tx_buffer_tail = tail; | ||||
} | } | ||||
} | } | ||||
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 | #endif // HAS_KINETISK_UART4 |
#include "kinetis.h" | #include "kinetis.h" | ||||
#include "core_pins.h" | #include "core_pins.h" | ||||
#include "HardwareSerial.h" | #include "HardwareSerial.h" | ||||
#include <stddef.h> | |||||
#ifdef HAS_KINETISK_UART5 | #ifdef HAS_KINETISK_UART5 | ||||
static volatile BUFTYPE tx_buffer[SERIAL6_TX_BUFFER_SIZE]; | static volatile BUFTYPE tx_buffer[SERIAL6_TX_BUFFER_SIZE]; | ||||
static volatile BUFTYPE rx_buffer[SERIAL6_RX_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 transmitting = 0; | ||||
static volatile uint8_t *transmit_pin=NULL; | static volatile uint8_t *transmit_pin=NULL; | ||||
#define transmit_assert() *transmit_pin = 1 | #define transmit_assert() *transmit_pin = 1 | ||||
if (!(SIM_SCGC1 & SIM_SCGC1_UART5)) return; | if (!(SIM_SCGC1 & SIM_SCGC1_UART5)) return; | ||||
if (transmit_pin) transmit_assert(); | if (transmit_pin) transmit_assert(); | ||||
head = tx_buffer_head; | 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) { | while (tx_buffer_tail == head) { | ||||
int priority = nvic_execution_priority(); | int priority = nvic_execution_priority(); | ||||
if (priority <= IRQ_PRIORITY) { | if (priority <= IRQ_PRIORITY) { | ||||
if ((UART5_S1 & UART_S1_TDRE)) { | if ((UART5_S1 & UART_S1_TDRE)) { | ||||
uint32_t tail = tx_buffer_tail; | 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); | if (use9Bits) UART5_C3 = (UART5_C3 & ~0x40) | ((n & 0x100) >> 2); | ||||
UART5_D = n; | UART5_D = n; | ||||
tx_buffer_tail = tail; | tx_buffer_tail = tail; | ||||
yield(); // wait | 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; | transmitting = 1; | ||||
tx_buffer_head = head; | tx_buffer_head = head; | ||||
UART5_C2 = C2_TX_ACTIVE; | UART5_C2 = C2_TX_ACTIVE; | ||||
head = tx_buffer_head; | head = tx_buffer_head; | ||||
tail = tx_buffer_tail; | 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; | return tail - head - 1; | ||||
} | } | ||||
head = rx_buffer_head; | head = rx_buffer_head; | ||||
tail = rx_buffer_tail; | tail = rx_buffer_tail; | ||||
if (head >= tail) return head - 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) | int serial6_getchar(void) | ||||
head = rx_buffer_head; | head = rx_buffer_head; | ||||
tail = rx_buffer_tail; | tail = rx_buffer_tail; | ||||
if (head == tail) return -1; | 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; | rx_buffer_tail = tail; | ||||
if (rts_pin) { | if (rts_pin) { | ||||
int avail; | int avail; | ||||
if (head >= tail) avail = head - tail; | 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; | return c; | ||||
} | } | ||||
head = rx_buffer_head; | head = rx_buffer_head; | ||||
tail = rx_buffer_tail; | tail = rx_buffer_tail; | ||||
if (head == tail) return -1; | 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) | void serial6_clear(void) | ||||
n = UART5_D; | n = UART5_D; | ||||
} | } | ||||
head = rx_buffer_head + 1; | 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) { | 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; | rx_buffer_head = head; | ||||
} | } | ||||
if (rts_pin) { | if (rts_pin) { | ||||
int avail; | int avail; | ||||
tail = tx_buffer_tail; | tail = tx_buffer_tail; | ||||
if (head >= tail) avail = head - 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; | c = UART5_C2; | ||||
if (head == tail) { | if (head == tail) { | ||||
UART5_C2 = C2_TX_COMPLETING; | UART5_C2 = C2_TX_COMPLETING; | ||||
} else { | } 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); | if (use9Bits) UART5_C3 = (UART5_C3 & ~0x40) | ((n & 0x100) >> 2); | ||||
UART5_D = n; | UART5_D = n; | ||||
tx_buffer_tail = tail; | tx_buffer_tail = tail; | ||||
} | } | ||||
} | } | ||||
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 | #endif // HAS_KINETISK_UART5 |
static volatile BUFTYPE tx_buffer[SERIAL6_TX_BUFFER_SIZE]; | static volatile BUFTYPE tx_buffer[SERIAL6_TX_BUFFER_SIZE]; | ||||
static volatile BUFTYPE rx_buffer[SERIAL6_RX_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 transmitting = 0; | ||||
static volatile uint8_t *transmit_pin=NULL; | static volatile uint8_t *transmit_pin=NULL; | ||||
#define transmit_assert() *transmit_pin = 1 | #define transmit_assert() *transmit_pin = 1 | ||||
if (!(SIM_SCGC2 & SIM_SCGC2_LPUART0)) return; | if (!(SIM_SCGC2 & SIM_SCGC2_LPUART0)) return; | ||||
if (transmit_pin) transmit_assert(); | if (transmit_pin) transmit_assert(); | ||||
head = tx_buffer_head; | 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) { | while (tx_buffer_tail == head) { | ||||
int priority = nvic_execution_priority(); | int priority = nvic_execution_priority(); | ||||
if (priority <= IRQ_PRIORITY) { | if (priority <= IRQ_PRIORITY) { | ||||
if ((LPUART0_STAT & LPUART_STAT_TDRE)) { | if ((LPUART0_STAT & LPUART_STAT_TDRE)) { | ||||
uint32_t tail = tx_buffer_tail; | 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); | //if (use9Bits) UART5_C3 = (UART5_C3 & ~0x40) | ((n & 0x100) >> 2); | ||||
LPUART0_DATA = n; | LPUART0_DATA = n; | ||||
tx_buffer_tail = tail; | tx_buffer_tail = tail; | ||||
head = tx_buffer_head; | head = tx_buffer_head; | ||||
tail = tx_buffer_tail; | 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; | return tail - head - 1; | ||||
} | } | ||||
head = rx_buffer_head; | head = rx_buffer_head; | ||||
tail = rx_buffer_tail; | tail = rx_buffer_tail; | ||||
if (head >= tail) return head - 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) | int serial6_getchar(void) | ||||
head = rx_buffer_head; | head = rx_buffer_head; | ||||
tail = rx_buffer_tail; | tail = rx_buffer_tail; | ||||
if (head == tail) return -1; | 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; | rx_buffer_tail = tail; | ||||
if (rts_pin) { | if (rts_pin) { | ||||
int avail; | int avail; | ||||
if (head >= tail) avail = head - tail; | 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; | return c; | ||||
} | } | ||||
head = rx_buffer_head; | head = rx_buffer_head; | ||||
tail = rx_buffer_tail; | tail = rx_buffer_tail; | ||||
if (head == tail) return -1; | 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) | void serial6_clear(void) | ||||
// } | // } | ||||
n = LPUART0_DATA & 0x3ff; // use only the 10 data bits | n = LPUART0_DATA & 0x3ff; // use only the 10 data bits | ||||
head = rx_buffer_head + 1; | 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) { | 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; | rx_buffer_head = head; | ||||
} | } | ||||
if (rts_pin) { | if (rts_pin) { | ||||
int avail; | int avail; | ||||
tail = tx_buffer_tail; | tail = tx_buffer_tail; | ||||
if (head >= tail) avail = head - 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; | c = LPUART0_CTRL; | ||||
//LPUART0_CTRL &= ~LPUART_CTRL_TIE; | //LPUART0_CTRL &= ~LPUART_CTRL_TIE; | ||||
//LPUART0_CTRL |= LPUART_CTRL_TCIE; // Actually wondering if we can just leave this one on... | //LPUART0_CTRL |= LPUART_CTRL_TCIE; // Actually wondering if we can just leave this one on... | ||||
} else { | } 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); | //if (use9Bits) UART5_C3 = (UART5_C3 & ~0x40) | ((n & 0x100) >> 2); | ||||
LPUART0_DATA = n; | LPUART0_DATA = n; | ||||
tx_buffer_tail = tail; | tx_buffer_tail = tail; | ||||
} | } | ||||
} | } | ||||
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 | #endif // HAS_KINETISK_LPUART0 |
void HardwareSerial::addToSerialEventsList() { | 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; | s_serials_with_serial_events[s_count_serials_with_serial_events++] = this; | ||||
yield_active_check_flags |= YIELD_CHECK_HARDWARE_SERIAL; | yield_active_check_flags |= YIELD_CHECK_HARDWARE_SERIAL; | ||||
} | } |