Bläddra i källkod

T4 - Hardware Serial - Pass 1

This pass has some more support for using the Hardware Serial objects.

Including setting an ISR for doing both reads and writes,  sets up the FIFO,

Sitll lots more work to go.

Things like: fifo - need to better understand/set watermarks, also RX need to read in more than one byte if more available.

Also support fo r other features, like formats, 9 bit, ...

BUt at least you can do simple reads/writes
main
Kurt Eckhardt 5 år sedan
förälder
incheckning
361d842551
2 ändrade filer med 523 tillägg och 429 borttagningar
  1. +440
    -47
      teensy4/HardwareSerial.cpp
  2. +83
    -382
      teensy4/HardwareSerial.h

+ 440
- 47
teensy4/HardwareSerial.cpp Visa fil

@@ -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
0, // 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 Visa fil

@@ -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

Laddar…
Avbryt
Spara