@@ -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; |
@@ -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)) { |