Browse Source

RTS/CTS support for Serial1 on Teensy LC & 3.x (experimental)

teensy4-core
PaulStoffregen 9 years ago
parent
commit
2c726eae11
2 changed files with 46 additions and 4 deletions
  1. +6
    -0
      teensy3/HardwareSerial.h
  2. +40
    -4
      teensy3/serial1.c

+ 6
- 0
teensy3/HardwareSerial.h View File

@@ -176,6 +176,8 @@ public:
serial_format(format); }
virtual void end(void) { serial_end(); }
virtual void transmitterEnable(uint8_t pin) { serial_set_transmit_pin(pin); }
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(); }
@@ -207,6 +209,8 @@ public:
serial2_format(format); }
virtual void end(void) { serial2_end(); }
virtual void transmitterEnable(uint8_t pin) { serial2_set_transmit_pin(pin); }
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(); }
@@ -238,6 +242,8 @@ public:
serial3_format(format); }
virtual void end(void) { serial3_end(); }
virtual void transmitterEnable(uint8_t pin) { serial3_set_transmit_pin(pin); }
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(); }

+ 40
- 4
teensy3/serial1.c View File

@@ -36,8 +36,10 @@
// Tunable parameters (relatively safe to edit these numbers)
////////////////////////////////////////////////////////////////

#define TX_BUFFER_SIZE 64 // number of outgoing bytes to buffer
#define RX_BUFFER_SIZE 64 // number of incoming bytes to buffer
#define TX_BUFFER_SIZE 64 // number of outgoing bytes to buffer
#define RX_BUFFER_SIZE 64 // number of incoming bytes to buffer
#define RTS_HIGH_WATERMARK 40 // RTS requests sender to pause
#define RTS_LOW_WATERMARK 26 // RTS allows sender to resume
#define IRQ_PRIORITY 64 // 0 = highest priority, 255 = lowest


@@ -60,11 +62,18 @@ static volatile uint8_t transmitting = 0;
static volatile uint8_t *transmit_pin=NULL;
#define transmit_assert() *transmit_pin = 1
#define transmit_deassert() *transmit_pin = 0
static volatile uint8_t *rts_pin=NULL;
#define rts_assert() *rts_pin = 0
#define rts_deassert() *rts_pin = 1
#elif defined(KINETISL)
static volatile uint8_t *transmit_pin=NULL;
static uint8_t transmit_mask=0;
#define transmit_assert() *(transmit_pin+4) = transmit_mask;
#define transmit_deassert() *(transmit_pin+8) = transmit_mask;
static volatile uint8_t *rts_pin=NULL;
static uint8_t rts_mask=0;
#define rts_assert() *(rts_pin+8) = rts_mask;
#define rts_deassert() *(rts_pin+4) = rts_mask;
#endif
#if TX_BUFFER_SIZE > 255
static volatile uint16_t tx_buffer_head = 0;
@@ -159,6 +168,7 @@ void serial_end(void)
CORE_PIN1_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1);
rx_buffer_head = 0;
rx_buffer_tail = 0;
if (rts_pin) rts_deassert();
}

void serial_set_transmit_pin(uint8_t pin)
@@ -175,6 +185,18 @@ void serial_set_transmit_pin(uint8_t pin)
int serial_set_rts(uint8_t pin)
{
if (!(SIM_SCGC4 & SIM_SCGC4_UART0)) return 0;
if (pin < CORE_NUM_DIGITAL) {
rts_pin = portOutputRegister(pin);
#if defined(KINETISL)
rts_mask = digitalPinToBitMask(pin);
#endif
pinMode(pin, OUTPUT);
rts_assert();
} else {
rts_pin = NULL;
return 0;
}
/*
if (pin == 6) {
CORE_PIN6_CONFIG = PORT_PCR_MUX(3);
} else if (pin == 19) {
@@ -184,6 +206,7 @@ int serial_set_rts(uint8_t pin)
return 0;
}
UART0_MODEM |= UART_MODEM_RXRTSE;
*/
return 1;
}

@@ -191,9 +214,9 @@ int serial_set_cts(uint8_t pin)
{
if (!(SIM_SCGC4 & SIM_SCGC4_UART0)) return 0;
if (pin == 18) {
CORE_PIN18_CONFIG = PORT_PCR_MUX(3); // TODO: weak pullup or pulldown?
CORE_PIN18_CONFIG = PORT_PCR_MUX(3) | PORT_PCR_PE; // weak pulldown
} else if (pin == 20) {
CORE_PIN20_CONFIG = PORT_PCR_MUX(3); // TODO: weak pullup or pulldown?
CORE_PIN20_CONFIG = PORT_PCR_MUX(3) | PORT_PCR_PE; // weak pulldown
} else {
UART0_MODEM &= ~UART_MODEM_TXCTSE;
return 0;
@@ -311,6 +334,12 @@ int serial_getchar(void)
if (++tail >= RX_BUFFER_SIZE) tail = 0;
c = rx_buffer[tail];
rx_buffer_tail = tail;
if (rts_pin) {
int avail;
if (head >= tail) avail = head - tail;
else avail = RX_BUFFER_SIZE + head - tail;
if (avail <= RTS_LOW_WATERMARK) rts_assert();
}
return c;
}

@@ -334,6 +363,7 @@ void serial_clear(void)
UART0_C2 |= (UART_C2_RE | UART_C2_RIE | UART_C2_ILIE);
#endif
rx_buffer_head = rx_buffer_tail;
if (rts_pin) rts_assert();
}

// status interrupt combines
@@ -392,6 +422,12 @@ void uart0_status_isr(void)
}
} while (--avail > 0);
rx_buffer_head = head;
if (rts_pin) {
int avail;
if (head >= tail) avail = head - tail;
else avail = RX_BUFFER_SIZE + head - tail;
if (avail >= RTS_HIGH_WATERMARK) rts_deassert();
}
}
}
c = UART0_C2;

Loading…
Cancel
Save