Переглянути джерело

Use software-based RTS on Serial2 and Serial3

teensy4-core
PaulStoffregen 9 роки тому
джерело
коміт
6e0dd8ab39
2 змінених файлів з 80 додано та 6 видалено
  1. +40
    -3
      teensy3/serial2.c
  2. +40
    -3
      teensy3/serial3.c

+ 40
- 3
teensy3/serial2.c Переглянути файл

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

#define TX_BUFFER_SIZE 40
#define RX_BUFFER_SIZE 64
#define TX_BUFFER_SIZE 40 // 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

////////////////////////////////////////////////////////////////
@@ -59,11 +61,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;
@@ -164,6 +173,7 @@ void serial2_end(void)
CORE_PIN10_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 serial2_set_transmit_pin(uint8_t pin)
@@ -179,6 +189,19 @@ void serial2_set_transmit_pin(uint8_t pin)

int serial2_set_rts(uint8_t pin)
{
if (!(SIM_SCGC4 & SIM_SCGC4_UART1)) 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 (!(SIM_SCGC4 & SIM_SCGC4_UART1)) return 0;
if (pin == 22) {
CORE_PIN22_CONFIG = PORT_PCR_MUX(3);
@@ -187,6 +210,7 @@ int serial2_set_rts(uint8_t pin)
return 0;
}
UART1_MODEM |= UART_MODEM_RXRTSE;
*/
return 1;
}

@@ -194,7 +218,7 @@ int serial2_set_cts(uint8_t pin)
{
if (!(SIM_SCGC4 & SIM_SCGC4_UART1)) return 0;
if (pin == 23) {
CORE_PIN23_CONFIG = PORT_PCR_MUX(3); // TODO: weak pullup or pulldown?
CORE_PIN23_CONFIG = PORT_PCR_MUX(3) | PORT_PCR_PE; // weak pulldown
} else {
UART1_MODEM &= ~UART_MODEM_TXCTSE;
return 0;
@@ -312,6 +336,12 @@ int serial2_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;
}

@@ -335,6 +365,7 @@ void serial2_clear(void)
UART1_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
@@ -393,6 +424,12 @@ void uart1_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 = UART1_C2;

+ 40
- 3
teensy3/serial3.c Переглянути файл

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

#define TX_BUFFER_SIZE 40
#define RX_BUFFER_SIZE 64
#define TX_BUFFER_SIZE 40 // 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;
@@ -148,6 +157,7 @@ void serial3_end(void)
CORE_PIN8_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 serial3_set_transmit_pin(uint8_t pin)
@@ -164,6 +174,18 @@ void serial3_set_transmit_pin(uint8_t pin)
int serial3_set_rts(uint8_t pin)
{
if (!(SIM_SCGC4 & SIM_SCGC4_UART2)) 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 == 2) {
CORE_PIN2_CONFIG = PORT_PCR_MUX(3);
} else {
@@ -171,6 +193,7 @@ int serial3_set_rts(uint8_t pin)
return 0;
}
UART2_MODEM |= UART_MODEM_RXRTSE;
*/
return 1;
}

@@ -178,7 +201,7 @@ int serial3_set_cts(uint8_t pin)
{
if (!(SIM_SCGC4 & SIM_SCGC4_UART2)) return 0;
if (pin == 14) {
CORE_PIN14_CONFIG = PORT_PCR_MUX(3); // TODO: weak pullup or pulldown?
CORE_PIN14_CONFIG = PORT_PCR_MUX(3) | PORT_PCR_PE; // weak pulldown
} else {
UART2_MODEM &= ~UART_MODEM_TXCTSE;
return 0;
@@ -258,6 +281,12 @@ int serial3_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;
}

@@ -275,6 +304,7 @@ int serial3_peek(void)
void serial3_clear(void)
{
rx_buffer_head = rx_buffer_tail;
if (rts_pin) rts_assert();
}

// status interrupt combines
@@ -302,6 +332,13 @@ void uart2_status_isr(void)
rx_buffer[head] = n;
rx_buffer_head = head;
}
if (rts_pin) {
int avail;
tail = tx_buffer_tail;
if (head >= tail) avail = head - tail;
else avail = RX_BUFFER_SIZE + head - tail;
if (avail >= RTS_HIGH_WATERMARK) rts_deassert();
}
}
c = UART2_C2;
if ((c & UART_C2_TIE) && (UART2_S1 & UART_S1_TDRE)) {

Завантаження…
Відмінити
Зберегти