Browse Source

Merge pull request #310 from KurtE/T4_HardwareSerial

T4 - Hardware Serial - Pass 1
teensy4-core
Paul Stoffregen 6 years ago
parent
commit
575c90cb68
No account linked to committer's email address
2 changed files with 523 additions and 429 deletions
  1. +440
    -47
      teensy4/HardwareSerial.cpp
  2. +83
    -382
      teensy4/HardwareSerial.h

+ 440
- 47
teensy4/HardwareSerial.cpp View File

@@ -1,7 +1,8 @@

#include "HardwareSerial.h"

#include "debug/printf.h"
#include "core_pins.h"
#include "Arduino.h"
//#include "debug/printf.h"

/*typedef struct {
const uint32_t VERID;
@@ -20,6 +21,64 @@

#define UART_CLOCK 24000000

#ifndef SERIAL1_TX_BUFFER_SIZE
#define SERIAL1_TX_BUFFER_SIZE 64 // number of outgoing bytes to buffer
#endif
#ifndef SERIAL1_RX_BUFFER_SIZE
#define SERIAL1_RX_BUFFER_SIZE 64 // number of incoming bytes to buffer
#endif

#ifndef SERIAL2_TX_BUFFER_SIZE
#define SERIAL2_TX_BUFFER_SIZE 40 // number of outgoing bytes to buffer
#endif
#ifndef SERIAL2_RX_BUFFER_SIZE
#define SERIAL2_RX_BUFFER_SIZE 64 // number of incoming bytes to buffer
#endif
#ifndef SERIAL3_TX_BUFFER_SIZE
#define SERIAL3_TX_BUFFER_SIZE 40 // number of outgoing bytes to buffer
#endif
#ifndef SERIAL3_RX_BUFFER_SIZE
#define SERIAL3_RX_BUFFER_SIZE 64 // number of incoming bytes to buffer
#endif
#ifndef SERIAL4_TX_BUFFER_SIZE
#define SERIAL4_TX_BUFFER_SIZE 40 // number of outgoing bytes to buffer
#endif
#ifndef SERIAL4_RX_BUFFER_SIZE
#define SERIAL4_RX_BUFFER_SIZE 64 // number of incoming bytes to buffer
#endif

#ifndef SERIAL5_TX_BUFFER_SIZE
#define SERIAL5_TX_BUFFER_SIZE 40 // number of outgoing bytes to buffer
#endif
#ifndef SERIAL5_RX_BUFFER_SIZE
#define SERIAL5_RX_BUFFER_SIZE 64 // number of incoming bytes to buffer
#endif
#ifndef SERIAL6_TX_BUFFER_SIZE
#define SERIAL6_TX_BUFFER_SIZE 40 // number of outgoing bytes to buffer
#endif
#ifndef SERIAL6_RX_BUFFER_SIZE
#define SERIAL6_RX_BUFFER_SIZE 64 // number of incoming bytes to buffer
#endif
#ifndef SERIAL7_TX_BUFFER_SIZE
#define SERIAL7_TX_BUFFER_SIZE 40 // number of outgoing bytes to buffer
#endif
#ifndef SERIAL7_RX_BUFFER_SIZE
#define SERIAL7_RX_BUFFER_SIZE 64 // number of incoming bytes to buffer
#endif
#ifndef SERIAL8_TX_BUFFER_SIZE
#define SERIAL8_TX_BUFFER_SIZE 40 // number of outgoing bytes to buffer
#endif
#ifndef SERIAL8_RX_BUFFER_SIZE
#define SERIAL8_RX_BUFFER_SIZE 64 // number of incoming bytes to buffer
#endif

#define IRQ_PRIORITY 64 // 0 = highest priority, 255 = lowest

#define CTRL_ENABLE (LPUART_CTRL_TE | LPUART_CTRL_RE | LPUART_CTRL_RIE)
#define CTRL_TX_ACTIVE (CTRL_ENABLE | LPUART_CTRL_TIE)
#define CTRL_TX_COMPLETING (CTRL_ENABLE | LPUART_CTRL_TCIE)
#define CTRL_TX_INACTIVE CTRL_ENABLE

void HardwareSerial::begin(uint32_t baud, uint8_t format)
{
//printf("HardwareSerial begin\n");
@@ -41,119 +100,453 @@ void HardwareSerial::begin(uint32_t baud, uint8_t format)
}
}
//printf(" baud %d: osr=%d, div=%d\n", baud, bestosr, bestdiv);
rx_buffer_head_ = 0;
rx_buffer_tail_ = 0;
tx_buffer_head_ = 0;
tx_buffer_tail_ = 0;
transmitting_ = 0;

hardware->ccm_register |= hardware->ccm_value;
hardware->rx_mux_register = hardware->rx_mux_val;
hardware->tx_mux_register = hardware->tx_mux_val;

uint32_t fastio = IOMUXC_PAD_SRE | IOMUXC_PAD_DSE(3) | IOMUXC_PAD_SPEED(3);
*(portControlRegister(hardware->rx_pin)) = fastio;
*(portControlRegister(hardware->tx_pin)) = fastio;

*(portConfigRegister(hardware->rx_pin)) = hardware->rx_mux_val;
*(portConfigRegister(hardware->tx_pin)) = hardware->tx_mux_val;

//hardware->rx_mux_register = hardware->rx_mux_val;
//hardware->tx_mux_register = hardware->tx_mux_val;
hardware->rx_select_input_register = hardware->rx_select_val;

port->BAUD = LPUART_BAUD_OSR(bestosr - 1) | LPUART_BAUD_SBR(bestdiv);
port->CTRL = LPUART_CTRL_TE | LPUART_CTRL_RE;
port->PINCFG = 0;

// Enable the transmitter, receiver and enable receiver interrupt
attachInterruptVector(hardware->irq, hardware->irq_handler);
NVIC_SET_PRIORITY(hardware->irq, IRQ_PRIORITY); // maybe should put into hardware...
NVIC_ENABLE_IRQ(hardware->irq);
uint16_t tx_fifo_size = (((port->FIFO >> 4) & 0x7) << 2);
uint8_t tx_water = (tx_fifo_size < 16) ? tx_fifo_size >> 1 : 7;
uint16_t rx_fifo_size = (((port->FIFO >> 0) & 0x7) << 2);
uint8_t rx_water = (rx_fifo_size < 16) ? rx_fifo_size >> 1 : 7;
/*
Serial.printf("SerialX::begin stat:%x ctrl:%x fifo:%x water:%x\n", port->STAT, port->CTRL, port->FIFO, port->WATER );
Serial.printf(" FIFO sizes: tx:%d rx:%d\n",tx_fifo_size, rx_fifo_size);
Serial.printf(" Watermark tx:%d, rx: %d\n", tx_water, rx_water);
*/
port->WATER = LPUART_WATER_RXWATER(rx_water) | LPUART_WATER_TXWATER(tx_water);
port->FIFO |= LPUART_FIFO_TXFE | LPUART_FIFO_RXFE;
port->CTRL = CTRL_TX_INACTIVE;
//Serial.printf(" stat:%x ctrl:%x fifo:%x water:%x\n", port->STAT, port->CTRL, port->FIFO, port->WATER );
};

void HardwareSerial::end(void)
{

}

void HardwareSerial::transmitterEnable(uint8_t pin)
{
while (transmitting_) ;
pinMode(pin, OUTPUT);
digitalWrite(pin, LOW);
transmit_pin_ = pin; // BUGBUG - Faster way?

}

void HardwareSerial::setRX(uint8_t pin)
{
// BUGBUG Implement
//Serial.printf("SerialX TX(%d) param:%x stat:%x ctrl:%x fifo:%x water:%x\n", hardware->tx_pin, port->PARAM, port->STAT, port->CTRL, port->FIFO, port->WATER );

}

void HardwareSerial::setTX(uint8_t pin, bool opendrain)
{
// BUGBUG Implement
}

bool HardwareSerial::attachRts(uint8_t pin)
{
// BUGBUG Implement
return false;
}

bool HardwareSerial::attachCts(uint8_t pin)
{
// BUGBUG Implement
return false;
}

void HardwareSerial::clear(void)
{
// BUGBUG:: deal with FIFO
rx_buffer_head_ = rx_buffer_tail_;
//if (rts_pin_) rts_assert();
}

int HardwareSerial::availableForWrite(void)
{
uint32_t head, tail;

head = tx_buffer_head_;
tail = tx_buffer_tail_;
if (head >= tail) return tx_buffer_total_size_ - 1 - head + tail;
return tail - head - 1;
}

size_t HardwareSerial::write9bit(uint32_t c)
{
return 0;
}




int HardwareSerial::available(void)
{
return -1;
uint32_t head, tail;

head = rx_buffer_head_;
tail = rx_buffer_tail_;
if (head >= tail) return head - tail;
return rx_buffer_total_size_ + head - tail;
}

int HardwareSerial::peek(void)
{
return -1;
uint32_t head, tail;

head = rx_buffer_head_;
tail = rx_buffer_tail_;
if (head == tail) return -1;
if (++tail >= rx_buffer_total_size_) tail = 0;
if (tail < rx_buffer_size_) {
return rx_buffer_[tail];
} else {
return rx_buffer_storage_[tail-rx_buffer_size_];
}
}

int HardwareSerial::read(void)
{
return -1;
}
uint32_t head, tail;
int c;

head = rx_buffer_head_;
tail = rx_buffer_tail_;
if (head == tail) return -1;
if (++tail >= rx_buffer_total_size_) tail = 0;
if (tail < rx_buffer_size_) {
c = rx_buffer_[tail];
} else {
c = rx_buffer_storage_[tail-rx_buffer_size_];
}
rx_buffer_tail_ = tail;
if (rts_pin_) {
uint32_t avail;
if (head >= tail) avail = head - tail;
else avail = rx_buffer_total_size_ + head - tail;
/*
if (avail <= rts_low_watermark_) rts_assert();
*/
}
return c;
}

void HardwareSerial::flush(void)
{
while (transmitting_) yield(); // wait
}

size_t HardwareSerial::write(uint8_t c)
{
while (!(port->STAT & LPUART_STAT_TDRE)) ; // wait
port->DATA = c;
uint32_t head, n;
//digitalWrite(3, HIGH);
//digitalWrite(5, HIGH);
// if (transmit_pin_) transmit_assert();
head = tx_buffer_head_;
if (++head >= tx_buffer_total_size_) head = 0;
while (tx_buffer_tail_ == head) {
/*
int priority = nvic_execution_priority();
if (priority <= IRQ_PRIORITY) {
if ((port->STAT & LPUART_STAT_TDRE)) {
uint32_t tail = tx_buffer_tail_;
if (++tail >= tx_buffer_total_size_) tail = 0;
if (tail < tx_buffer_size_) {
n = tx_buffer_[tail];
} else {
n = tx_buffer_storage_[tail-tx_buffer_size_];
}
port->DATA = n;
tx_buffer_tail_ = tail;
}
} else if (priority >= 256)
*/
{
yield(); // wait
}
}
//digitalWrite(5, LOW);
//Serial.printf("WR %x %d %d %d %x %x\n", c, head, tx_buffer_size_, tx_buffer_total_size_, (uint32_t)tx_buffer_, (uint32_t)tx_buffer_storage_);
if (head < tx_buffer_size_) {
tx_buffer_[head] = c;
} else {
tx_buffer_storage_[head - tx_buffer_size_] = c;
}
transmitting_ = 1;
tx_buffer_head_ = head;
port->CTRL |= LPUART_CTRL_TIE; // (may need to handle this issue)BITBAND_SET_BIT(LPUART0_CTRL, TIE_BIT);
//digitalWrite(3, LOW);
return 1;
}

__attribute__((section(".progmem")))
void HardwareSerial::IRQHandler()
{
//digitalWrite(4, HIGH);
uint32_t head, tail, n;
uint32_t ctrl;

// See if we have stuff to read in.
if (port->STAT & LPUART_STAT_RDRF) {
//digitalWrite(5, HIGH);
#if 1
n = port->DATA; // get the byte...
#else
if (use9Bits_ && (port().C3 & 0x80)) {
n = port().D | 0x100;
} else {
n = port().D;
}
#endif
head = rx_buffer_head_ + 1;
if (head >= rx_buffer_total_size_) head = 0;
if (head != rx_buffer_tail_) {
if (head < rx_buffer_size_) {
rx_buffer_[head] = n;
} else {
rx_buffer_storage_[head-rx_buffer_size_] = n;
}
rx_buffer_head_ = head;
}
//digitalWrite(5, LOW);
}


// See if we are transmitting and room in buffer.
ctrl = port->CTRL;
if ((ctrl & LPUART_CTRL_TIE) && (port->STAT & LPUART_STAT_TDRE))
{
//digitalWrite(3, HIGH);

head = tx_buffer_head_;
tail = tx_buffer_tail_;
do {
if (head == tail) break;
if (++tail >= tx_buffer_total_size_) tail = 0;
if (tail < tx_buffer_size_) {
n = tx_buffer_[tail];
} else {
n = tx_buffer_storage_[tail-tx_buffer_size_];
}
//if (use9Bits_) port().C3 = (port().C3 & ~0x40) | ((n & 0x100) >> 2);
port->DATA = n;
} while (((port->WATER >> 8) & 0x7) < 4); // need to computer properly
tx_buffer_tail_ = tail;
if (head == tail) port->CTRL = CTRL_TX_COMPLETING;
//digitalWrite(3, LOW);
}

if ((ctrl & LPUART_CTRL_TCIE) && (port->STAT & LPUART_STAT_TDRE))
{
transmitting_ = 0;
//if (transmit_pin_) transmit_deassert();
port->CTRL = CTRL_TX_INACTIVE;
}
//digitalWrite(4, LOW);
}

void IRQHandler_Serial1()
{
Serial1.IRQHandler();
}

void IRQHandler_Serial2()
{
Serial2.IRQHandler();
}

void IRQHandler_Serial3()
{
Serial3.IRQHandler();
}

void IRQHandler_Serial4()
{
Serial4.IRQHandler();
}

void IRQHandler_Serial5()
{
Serial5.IRQHandler();
}

void IRQHandler_Serial6()
{
Serial6.IRQHandler();
}

void IRQHandler_Serial7()
{
Serial7.IRQHandler();
}

void IRQHandler_Serial8()
{
Serial8.IRQHandler();
}




// Serial1
static BUFTYPE tx_buffer1[SERIAL1_TX_BUFFER_SIZE];
static BUFTYPE rx_buffer1[SERIAL1_RX_BUFFER_SIZE];

const HardwareSerial::hardware_t UART6_Hardware = {
IRQ_LPUART6,
IRQ_LPUART6, &IRQHandler_Serial1,
CCM_CCGR3, CCM_CCGR3_LPUART6(CCM_CCGR_ON),
IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_03, // pin 0
IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_02, // pin 1
0, //IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_03, // pin 0
1, //IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_02, // pin 1
IOMUXC_LPUART6_RX_SELECT_INPUT,
2, // page 473
2, // page 472
1, // page 861
};
HardwareSerial Serial1(&IMXRT_LPUART6, &UART6_Hardware);
HardwareSerial Serial1(&IMXRT_LPUART6, &UART6_Hardware, tx_buffer1, SERIAL1_TX_BUFFER_SIZE,
rx_buffer1, SERIAL1_RX_BUFFER_SIZE);

// Serial2
static BUFTYPE tx_buffer2[SERIAL2_TX_BUFFER_SIZE];
static BUFTYPE rx_buffer2[SERIAL2_RX_BUFFER_SIZE];

static HardwareSerial::hardware_t UART4_Hardware = {
IRQ_LPUART4,
IRQ_LPUART4, &IRQHandler_Serial2,
CCM_CCGR1, CCM_CCGR1_LPUART4(CCM_CCGR_ON),
IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_01, // pin 6
IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_00, // pin 7
6, //IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_01, // pin 6
7, // IOMUXC_SW_MUX_CTL_PAD_GPIO_B1_00, // pin 7
IOMUXC_LPUART4_RX_SELECT_INPUT,
2, // page 521
2, // page 520
2, // page 858
};
HardwareSerial Serial2(&IMXRT_LPUART4, &UART4_Hardware);
HardwareSerial Serial2(&IMXRT_LPUART4, &UART4_Hardware, tx_buffer2, SERIAL2_TX_BUFFER_SIZE,
rx_buffer2, SERIAL2_RX_BUFFER_SIZE);

// Serial3
static BUFTYPE tx_buffer3[SERIAL3_TX_BUFFER_SIZE];
static BUFTYPE rx_buffer3[SERIAL3_RX_BUFFER_SIZE];

static HardwareSerial::hardware_t UART2_Hardware = {
IRQ_LPUART2,
IRQ_LPUART2, &IRQHandler_Serial3,
CCM_CCGR0, CCM_CCGR0_LPUART2(CCM_CCGR_ON),
IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_03, // pin 15
IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_02, // pin 14
15, //IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_03, // pin 15
14, //IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_02, // pin 14
IOMUXC_LPUART2_RX_SELECT_INPUT,
2, // page 491
2, // page 490
1, // Page 855
};
HardwareSerial Serial3(&IMXRT_LPUART2, &UART2_Hardware);
HardwareSerial Serial3(&IMXRT_LPUART2, &UART2_Hardware,tx_buffer3, SERIAL3_TX_BUFFER_SIZE,
rx_buffer3, SERIAL3_RX_BUFFER_SIZE);

// Serial4
static BUFTYPE tx_buffer4[SERIAL4_TX_BUFFER_SIZE];
static BUFTYPE rx_buffer4[SERIAL4_RX_BUFFER_SIZE];

static HardwareSerial::hardware_t UART3_Hardware = {
IRQ_LPUART3,
IRQ_LPUART3, &IRQHandler_Serial4,
CCM_CCGR0, CCM_CCGR0_LPUART3(CCM_CCGR_ON),
IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_07, // pin 16
IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_06, // pin 17
16, //IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_07, // pin 16
17, //IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_06, // pin 17
IOMUXC_LPUART3_RX_SELECT_INPUT,
2, // page 495
2, // page 494
0, // Page 857
};
HardwareSerial Serial4(&IMXRT_LPUART3, &UART3_Hardware);
HardwareSerial Serial4(&IMXRT_LPUART3, &UART3_Hardware, tx_buffer4, SERIAL4_TX_BUFFER_SIZE,
rx_buffer4, SERIAL4_RX_BUFFER_SIZE);

// Serial5
static BUFTYPE tx_buffer5[SERIAL5_TX_BUFFER_SIZE];
static BUFTYPE rx_buffer5[SERIAL5_RX_BUFFER_SIZE];

static HardwareSerial::hardware_t UART8_Hardware = {
IRQ_LPUART8,
IRQ_LPUART8, &IRQHandler_Serial5,
CCM_CCGR6, CCM_CCGR6_LPUART8(CCM_CCGR_ON),
IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_11, // pin 21
IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_10, // pin 20
21, //IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_11, // pin 21
20, //IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B1_10, // pin 20
IOMUXC_LPUART8_RX_SELECT_INPUT,
2, // page 499
2, // page 498
1, // Page 864-5
};
HardwareSerial Serial5(&IMXRT_LPUART8, &UART8_Hardware);
HardwareSerial Serial5(&IMXRT_LPUART8, &UART8_Hardware, tx_buffer5, SERIAL5_TX_BUFFER_SIZE,
rx_buffer5, SERIAL5_RX_BUFFER_SIZE);

// Serial6
static BUFTYPE tx_buffer6[SERIAL6_TX_BUFFER_SIZE];
static BUFTYPE rx_buffer6[SERIAL6_RX_BUFFER_SIZE];
uint32_t IOMUXC_LPUART1_RX_SELECT_INPUT; // bugbug - does not exist so hack

static HardwareSerial::hardware_t UART1_Hardware = {
IRQ_LPUART1,
IRQ_LPUART1, &IRQHandler_Serial6,
CCM_CCGR5, CCM_CCGR5_LPUART1(CCM_CCGR_ON),
IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_13, // pin 25
IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_12, // pin 24
25, //IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_13, // pin 25
24, //IOMUXC_SW_MUX_CTL_PAD_GPIO_AD_B0_12, // pin 24
IOMUXC_LPUART1_RX_SELECT_INPUT,
2, // page 486
2, // page 485
0, // ??? Does not have one ???

};
HardwareSerial Serial6(&IMXRT_LPUART1, &UART1_Hardware);
HardwareSerial Serial6(&IMXRT_LPUART1, &UART1_Hardware, tx_buffer6, SERIAL6_TX_BUFFER_SIZE,
rx_buffer6, SERIAL6_RX_BUFFER_SIZE);

// Serial7
static BUFTYPE tx_buffer7[SERIAL7_TX_BUFFER_SIZE];
static BUFTYPE rx_buffer7[SERIAL7_RX_BUFFER_SIZE];

static HardwareSerial::hardware_t UART7_Hardware = {
IRQ_LPUART7,
IRQ_LPUART7, &IRQHandler_Serial7,
CCM_CCGR5, CCM_CCGR5_LPUART7(CCM_CCGR_ON),
IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_32, // pin 28
IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_31, // pin 29
28, //IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_32, // pin 28
29, //IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_31, // pin 29
IOMUXC_LPUART7_RX_SELECT_INPUT,
2, // page 458
2, // page 457
1, // Page 863

};
HardwareSerial Serial7(&IMXRT_LPUART7, &UART7_Hardware);
HardwareSerial Serial7(&IMXRT_LPUART7, &UART7_Hardware, tx_buffer7, SERIAL7_TX_BUFFER_SIZE,
rx_buffer7, SERIAL7_RX_BUFFER_SIZE);

// Serial8
static BUFTYPE tx_buffer8[SERIAL8_TX_BUFFER_SIZE];
static BUFTYPE rx_buffer8[SERIAL8_RX_BUFFER_SIZE];

static HardwareSerial::hardware_t UART5_Hardware = {
IRQ_LPUART5,
IRQ_LPUART5, &IRQHandler_Serial8,
CCM_CCGR3, CCM_CCGR3_LPUART5(CCM_CCGR_ON),
IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_24, // pin 30
IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_23, // pin 31
30, //IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_24, // pin 30
31, // IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_23, // pin 31
IOMUXC_LPUART5_RX_SELECT_INPUT,
2, // page 450
2, // page 449
0,
};
HardwareSerial Serial8(&IMXRT_LPUART5, &UART5_Hardware);



HardwareSerial Serial8(&IMXRT_LPUART5, &UART5_Hardware, tx_buffer8, SERIAL8_TX_BUFFER_SIZE,
rx_buffer8, SERIAL8_RX_BUFFER_SIZE);


+ 83
- 382
teensy4/HardwareSerial.h View File

@@ -35,61 +35,117 @@

#ifdef __cplusplus
#include "Stream.h"
#include "core_pins.h"

#ifdef SERIAL_9BIT_SUPPORT
#define BUFTYPE uint16_t
#else
#define BUFTYPE uint8_t
#endif

extern "C" {
extern void IRQHandler_Serial1();
extern void IRQHandler_Serial2();
extern void IRQHandler_Serial3();
extern void IRQHandler_Serial4();
extern void IRQHandler_Serial5();
extern void IRQHandler_Serial6();
extern void IRQHandler_Serial7();
extern void IRQHandler_Serial8();
}

class HardwareSerial : public Stream
{
public:
typedef struct {
IRQ_NUMBER_t irq;
void (*irq_handler)(void);
volatile uint32_t &ccm_register;
const uint32_t ccm_value;
volatile uint32_t &rx_mux_register;
volatile uint32_t &tx_mux_register;
const uint8_t rx_pin;
const uint8_t tx_pin;
//volatile uint32_t &rx_mux_register;
//volatile uint32_t &tx_mux_register;
volatile uint32_t &rx_select_input_register;
const uint8_t rx_mux_val;
const uint8_t tx_mux_val;
const uint8_t rx_select_val;
} hardware_t;
public:
constexpr HardwareSerial(IMXRT_LPUART_t *myport, const hardware_t *myhardware) :
port(myport), hardware(myhardware) {
constexpr HardwareSerial(IMXRT_LPUART_t *myport, const hardware_t *myhardware,
volatile BUFTYPE *_tx_buffer, size_t _tx_buffer_size,
volatile BUFTYPE *_rx_buffer, size_t _rx_buffer_size) :
port(myport), hardware(myhardware),
tx_buffer_(_tx_buffer), rx_buffer_(_rx_buffer), tx_buffer_size_(_tx_buffer_size), rx_buffer_size_(_rx_buffer_size),
tx_buffer_total_size_(_tx_buffer_size), rx_buffer_total_size_(_rx_buffer_size) {
}
void begin(uint32_t baud, uint8_t format=0);
void end(void);

virtual int available(void);
virtual int peek(void);
virtual void flush(void);
virtual size_t write(uint8_t c);
virtual int read(void);
using Print::write;

/*
void transmitterEnable(uint8_t pin);
void setRX(uint8_t pin);
void setTX(uint8_t pin, bool opendrain=false);
bool attachRts(uint8_t pin);
bool attachCts(uint8_t pin);
void clear(void);
int availableForWrite(void);
size_t write9bit(uint32_t c);

using Print::write;
// Only overwrite some of the virtualWrite functions if we are going to optimize them over Print version

/*
virtual void begin(uint32_t baud) { serial_begin(BAUD2DIV(baud)); }
virtual void begin(uint32_t baud, uint32_t format) {
serial_begin(BAUD2DIV(baud));
serial_format(format); }
virtual void end(void) { serial_end(); }
virtual void transmitterEnable(uint8_t pin) { serial_set_transmit_pin(pin); }
virtual void setRX(uint8_t pin) { serial_set_rx(pin); }
virtual void setTX(uint8_t pin, bool opendrain=false) { serial_set_tx(pin, opendrain); }
virtual bool attachRts(uint8_t pin) { return serial_set_rts(pin); }
virtual bool attachCts(uint8_t pin) { return serial_set_cts(pin); }
virtual void clear(void) { serial_clear(); }
virtual int availableForWrite(void) { return serial_write_buffer_free(); }
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); }
virtual size_t write(long n) { return write((uint8_t)n); }
virtual size_t write(unsigned int n) { return write((uint8_t)n); }
virtual size_t write(int n) { return write((uint8_t)n); }
virtual size_t write(const uint8_t *buffer, size_t size)
{ serial_write(buffer, size); return size; }
virtual size_t write(const char *str) { size_t len = strlen(str);
serial_write((const uint8_t *)str, len);
return len; }
virtual size_t write9bit(uint32_t c) { serial_putchar(c); return 1; }
*/
*/

operator bool() { return true; }
private:
IMXRT_LPUART_t * const port;
const hardware_t * const hardware;

volatile BUFTYPE *tx_buffer_;
volatile BUFTYPE *rx_buffer_;
volatile BUFTYPE *rx_buffer_storage_ = nullptr;
volatile BUFTYPE *tx_buffer_storage_ = nullptr;
size_t tx_buffer_size_;
size_t rx_buffer_size_;
size_t tx_buffer_total_size_;
size_t rx_buffer_total_size_;
volatile uint8_t transmitting_ = 0;
volatile uint16_t tx_buffer_head_ = 0;
volatile uint16_t tx_buffer_tail_ = 0;
volatile uint16_t rx_buffer_head_ = 0;
volatile uint16_t rx_buffer_tail_ = 0;

// Currently using digitalWWrite...
int transmit_pin_=-1;
int rts_pin_=-1;

inline void transmit_assert() {digitalWrite(transmit_pin_, 1);}
inline void transmit_deassert() {digitalWrite(transmit_pin_, 0);}
inline void rts_assert() {digitalWrite(rts_pin_ , 0); }
inline void rts_deassert() {digitalWrite(rts_pin_ , 1); }

void IRQHandler();
friend void IRQHandler_Serial1();
friend void IRQHandler_Serial2();
friend void IRQHandler_Serial3();
friend void IRQHandler_Serial4();
friend void IRQHandler_Serial5();
friend void IRQHandler_Serial6();
friend void IRQHandler_Serial7();
friend void IRQHandler_Serial8();


};
extern HardwareSerial Serial1;
extern HardwareSerial Serial2;
@@ -205,360 +261,5 @@ extern HardwareSerial Serial8;
#define BAUD2DIV3(baud) (((F_BUS / 16) + ((baud) >> 1)) / (baud))
#endif
*/
#if 0

// C language implementation
//
#ifdef __cplusplus
extern "C" {
#endif
void serial_begin(uint32_t divisor);
void serial_format(uint32_t format);
void serial_end(void);
void serial_set_transmit_pin(uint8_t pin);
void serial_set_rx(uint8_t pin);
void serial_set_tx(uint8_t pin, uint8_t opendrain);
int serial_set_rts(uint8_t pin);
int serial_set_cts(uint8_t pin);
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);
int serial_available(void);
int serial_getchar(void);
int serial_peek(void);
void serial_clear(void);
void serial_print(const char *p);
void serial_phex(uint32_t n);
void serial_phex16(uint32_t n);
void serial_phex32(uint32_t n);

void serial2_begin(uint32_t divisor);
void serial2_format(uint32_t format);
void serial2_end(void);
void serial2_set_transmit_pin(uint8_t pin);
void serial2_set_rx(uint8_t pin);
void serial2_set_tx(uint8_t pin, uint8_t opendrain);
int serial2_set_rts(uint8_t pin);
int serial2_set_cts(uint8_t pin);
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);
int serial2_available(void);
int serial2_getchar(void);
int serial2_peek(void);
void serial2_clear(void);

void serial3_begin(uint32_t divisor);
void serial3_format(uint32_t format);
void serial3_end(void);
void serial3_set_transmit_pin(uint8_t pin);
void serial3_set_rx(uint8_t pin);
void serial3_set_tx(uint8_t pin, uint8_t opendrain);
int serial3_set_rts(uint8_t pin);
int serial3_set_cts(uint8_t pin);
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);
int serial3_available(void);
int serial3_getchar(void);
int serial3_peek(void);
void serial3_clear(void);

void serial4_begin(uint32_t divisor);
void serial4_format(uint32_t format);
void serial4_end(void);
void serial4_set_transmit_pin(uint8_t pin);
void serial4_set_rx(uint8_t pin);
void serial4_set_tx(uint8_t pin, uint8_t opendrain);
int serial4_set_rts(uint8_t pin);
int serial4_set_cts(uint8_t pin);
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);
int serial4_available(void);
int serial4_getchar(void);
int serial4_peek(void);
void serial4_clear(void);

void serial5_begin(uint32_t divisor);
void serial5_format(uint32_t format);
void serial5_end(void);
void serial5_set_transmit_pin(uint8_t pin);
void serial5_set_rx(uint8_t pin);
void serial5_set_tx(uint8_t pin, uint8_t opendrain);
int serial5_set_rts(uint8_t pin);
int serial5_set_cts(uint8_t pin);
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);
int serial5_available(void);
int serial5_getchar(void);
int serial5_peek(void);
void serial5_clear(void);

void serial6_begin(uint32_t divisor);
void serial6_format(uint32_t format);
void serial6_end(void);
void serial6_set_transmit_pin(uint8_t pin);
void serial6_set_rx(uint8_t pin);
void serial6_set_tx(uint8_t pin, uint8_t opendrain);
int serial6_set_rts(uint8_t pin);
int serial6_set_cts(uint8_t pin);
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);
int serial6_available(void);
int serial6_getchar(void);
int serial6_peek(void);
void serial6_clear(void);

#ifdef __cplusplus
}
#endif


// C++ interface
//
#ifdef __cplusplus
#include "Stream.h"
class HardwareSerial : public Stream
{
public:
constexpr HardwareSerial() {}
virtual void begin(uint32_t baud) { serial_begin(BAUD2DIV(baud)); }
virtual void begin(uint32_t baud, uint32_t format) {
serial_begin(BAUD2DIV(baud));
serial_format(format); }
virtual void end(void) { serial_end(); }
virtual void transmitterEnable(uint8_t pin) { serial_set_transmit_pin(pin); }
virtual void setRX(uint8_t pin) { serial_set_rx(pin); }
virtual void setTX(uint8_t pin, bool opendrain=false) { serial_set_tx(pin, opendrain); }
virtual bool attachRts(uint8_t pin) { return serial_set_rts(pin); }
virtual bool attachCts(uint8_t pin) { return serial_set_cts(pin); }
virtual int available(void) { return serial_available(); }
virtual int peek(void) { return serial_peek(); }
virtual int read(void) { return serial_getchar(); }
virtual void flush(void) { serial_flush(); }
virtual void clear(void) { serial_clear(); }
virtual int availableForWrite(void) { return serial_write_buffer_free(); }
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); }
virtual size_t write(long n) { return write((uint8_t)n); }
virtual size_t write(unsigned int n) { return write((uint8_t)n); }
virtual size_t write(int n) { return write((uint8_t)n); }
virtual size_t write(const uint8_t *buffer, size_t size)
{ serial_write(buffer, size); return size; }
virtual size_t write(const char *str) { size_t len = strlen(str);
serial_write((const uint8_t *)str, len);
return len; }
virtual size_t write9bit(uint32_t c) { serial_putchar(c); return 1; }
operator bool() { return true; }
};
extern HardwareSerial Serial1;
extern void serialEvent1(void);

class HardwareSerial2 : public HardwareSerial
{
public:
constexpr HardwareSerial2() {}
virtual void begin(uint32_t baud) { serial2_begin(BAUD2DIV(baud)); }
virtual void begin(uint32_t baud, uint32_t format) {
serial2_begin(BAUD2DIV(baud));
serial2_format(format); }
virtual void end(void) { serial2_end(); }
virtual void transmitterEnable(uint8_t pin) { serial2_set_transmit_pin(pin); }
virtual void setRX(uint8_t pin) { serial2_set_rx(pin); }
virtual void setTX(uint8_t pin, bool opendrain=false) { serial2_set_tx(pin, opendrain); }
virtual bool attachRts(uint8_t pin) { return serial2_set_rts(pin); }
virtual bool attachCts(uint8_t pin) { return serial2_set_cts(pin); }
virtual int available(void) { return serial2_available(); }
virtual int peek(void) { return serial2_peek(); }
virtual int read(void) { return serial2_getchar(); }
virtual void flush(void) { serial2_flush(); }
virtual void clear(void) { serial2_clear(); }
virtual int availableForWrite(void) { return serial2_write_buffer_free(); }
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); }
virtual size_t write(long n) { return write((uint8_t)n); }
virtual size_t write(unsigned int n) { return write((uint8_t)n); }
virtual size_t write(int n) { return write((uint8_t)n); }
virtual size_t write(const uint8_t *buffer, size_t size)
{ serial2_write(buffer, size); return size; }
virtual size_t write(const char *str) { size_t len = strlen(str);
serial2_write((const uint8_t *)str, len);
return len; }
virtual size_t write9bit(uint32_t c) { serial2_putchar(c); return 1; }
operator bool() { return true; }
};
extern HardwareSerial2 Serial2;
extern void serialEvent2(void);

class HardwareSerial3 : public HardwareSerial
{
public:
constexpr HardwareSerial3() {}
virtual void begin(uint32_t baud) { serial3_begin(BAUD2DIV(baud)); }
virtual void begin(uint32_t baud, uint32_t format) {
serial3_begin(BAUD2DIV(baud));
serial3_format(format); }
virtual void end(void) { serial3_end(); }
virtual void transmitterEnable(uint8_t pin) { serial3_set_transmit_pin(pin); }
virtual void setRX(uint8_t pin) { serial3_set_rx(pin); }
virtual void setTX(uint8_t pin, bool opendrain=false) { serial3_set_tx(pin, opendrain); }
virtual bool attachRts(uint8_t pin) { return serial3_set_rts(pin); }
virtual bool attachCts(uint8_t pin) { return serial3_set_cts(pin); }
virtual int available(void) { return serial3_available(); }
virtual int peek(void) { return serial3_peek(); }
virtual int read(void) { return serial3_getchar(); }
virtual void flush(void) { serial3_flush(); }
virtual void clear(void) { serial3_clear(); }
virtual int availableForWrite(void) { return serial3_write_buffer_free(); }
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); }
virtual size_t write(long n) { return write((uint8_t)n); }
virtual size_t write(unsigned int n) { return write((uint8_t)n); }
virtual size_t write(int n) { return write((uint8_t)n); }
virtual size_t write(const uint8_t *buffer, size_t size)
{ serial3_write(buffer, size); return size; }
virtual size_t write(const char *str) { size_t len = strlen(str);
serial3_write((const uint8_t *)str, len);
return len; }
virtual size_t write9bit(uint32_t c) { serial3_putchar(c); return 1; }
operator bool() { return true; }
};
extern HardwareSerial3 Serial3;
extern void serialEvent3(void);

class HardwareSerial4 : public HardwareSerial
{
public:
constexpr HardwareSerial4() {}
virtual void begin(uint32_t baud) { serial4_begin(BAUD2DIV(baud)); }
virtual void begin(uint32_t baud, uint32_t format) {
serial4_begin(BAUD2DIV(baud));
serial4_format(format); }
virtual void end(void) { serial4_end(); }
virtual void transmitterEnable(uint8_t pin) { serial4_set_transmit_pin(pin); }
virtual void setRX(uint8_t pin) { serial4_set_rx(pin); }
virtual void setTX(uint8_t pin, bool opendrain=false) { serial4_set_tx(pin, opendrain); }
virtual bool attachRts(uint8_t pin) { return serial4_set_rts(pin); }
virtual bool attachCts(uint8_t pin) { return serial4_set_cts(pin); }
virtual int available(void) { return serial4_available(); }
virtual int peek(void) { return serial4_peek(); }
virtual int read(void) { return serial4_getchar(); }
virtual void flush(void) { serial4_flush(); }
virtual void clear(void) { serial4_clear(); }
virtual int availableForWrite(void) { return serial4_write_buffer_free(); }
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); }
virtual size_t write(long n) { return write((uint8_t)n); }
virtual size_t write(unsigned int n) { return write((uint8_t)n); }
virtual size_t write(int n) { return write((uint8_t)n); }
virtual size_t write(const uint8_t *buffer, size_t size)
{ serial4_write(buffer, size); return size; }
virtual size_t write(const char *str) { size_t len = strlen(str);
serial4_write((const uint8_t *)str, len);
return len; }
virtual size_t write9bit(uint32_t c) { serial4_putchar(c); return 1; }
operator bool() { return true; }
};
extern HardwareSerial4 Serial4;
extern void serialEvent4(void);

class HardwareSerial5 : public HardwareSerial
{
public:
constexpr HardwareSerial5() {}
virtual void begin(uint32_t baud) { serial5_begin(BAUD2DIV(baud)); }
virtual void begin(uint32_t baud, uint32_t format) {
serial5_begin(BAUD2DIV(baud));
serial5_format(format); }
virtual void end(void) { serial5_end(); }
virtual void transmitterEnable(uint8_t pin) { serial5_set_transmit_pin(pin); }
virtual void setRX(uint8_t pin) { serial5_set_rx(pin); }
virtual void setTX(uint8_t pin, bool opendrain=false) { serial5_set_tx(pin, opendrain); }
virtual bool attachRts(uint8_t pin) { return serial5_set_rts(pin); }
virtual bool attachCts(uint8_t pin) { return serial5_set_cts(pin); }
virtual int available(void) { return serial5_available(); }
virtual int peek(void) { return serial5_peek(); }
virtual int read(void) { return serial5_getchar(); }
virtual void flush(void) { serial5_flush(); }
virtual void clear(void) { serial5_clear(); }
virtual int availableForWrite(void) { return serial5_write_buffer_free(); }
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); }
virtual size_t write(long n) { return write((uint8_t)n); }
virtual size_t write(unsigned int n) { return write((uint8_t)n); }
virtual size_t write(int n) { return write((uint8_t)n); }
virtual size_t write(const uint8_t *buffer, size_t size)
{ serial5_write(buffer, size); return size; }
virtual size_t write(const char *str) { size_t len = strlen(str);
serial5_write((const uint8_t *)str, len);
return len; }
virtual size_t write9bit(uint32_t c) { serial5_putchar(c); return 1; }
operator bool() { return true; }
};
extern HardwareSerial5 Serial5;
extern void serialEvent5(void);

class HardwareSerial6 : public HardwareSerial
{
public:
constexpr HardwareSerial6() {}
#if defined(__MK66FX1M0__) // For LPUART just pass baud straight in.
virtual void begin(uint32_t baud) { serial6_begin(baud); }
virtual void begin(uint32_t baud, uint32_t format) {
serial6_begin(baud);
serial6_format(format); }
#else
virtual void begin(uint32_t baud) { serial6_begin(BAUD2DIV(baud)); }
virtual void begin(uint32_t baud, uint32_t format) {
serial6_begin(BAUD2DIV(baud));
serial6_format(format); }
#endif
virtual void end(void) { serial6_end(); }
virtual void transmitterEnable(uint8_t pin) { serial6_set_transmit_pin(pin); }
virtual void setRX(uint8_t pin) { serial6_set_rx(pin); }
virtual void setTX(uint8_t pin, bool opendrain=false) { serial6_set_tx(pin, opendrain); }
virtual bool attachRts(uint8_t pin) { return serial6_set_rts(pin); }
virtual bool attachCts(uint8_t pin) { return serial6_set_cts(pin); }
virtual int available(void) { return serial6_available(); }
virtual int peek(void) { return serial6_peek(); }
virtual int read(void) { return serial6_getchar(); }
virtual void flush(void) { serial6_flush(); }
virtual void clear(void) { serial6_clear(); }
virtual int availableForWrite(void) { return serial6_write_buffer_free(); }
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); }
virtual size_t write(long n) { return write((uint8_t)n); }
virtual size_t write(unsigned int n) { return write((uint8_t)n); }
virtual size_t write(int n) { return write((uint8_t)n); }
virtual size_t write(const uint8_t *buffer, size_t size)
{ serial6_write(buffer, size); return size; }
virtual size_t write(const char *str) { size_t len = strlen(str);
serial6_write((const uint8_t *)str, len);
return len; }
virtual size_t write9bit(uint32_t c) { serial6_putchar(c); return 1; }
operator bool() { return true; }
};
extern HardwareSerial6 Serial6;
extern void serialEvent6(void);



#endif

#endif
#endif

Loading…
Cancel
Save