// Tunable parameters (relatively safe to edit these numbers) | // 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 | #define IRQ_PRIORITY 64 // 0 = highest priority, 255 = lowest | ||||
//////////////////////////////////////////////////////////////// | //////////////////////////////////////////////////////////////// | ||||
static volatile uint8_t *transmit_pin=NULL; | static volatile uint8_t *transmit_pin=NULL; | ||||
#define transmit_assert() *transmit_pin = 1 | #define transmit_assert() *transmit_pin = 1 | ||||
#define transmit_deassert() *transmit_pin = 0 | #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) | #elif defined(KINETISL) | ||||
static volatile uint8_t *transmit_pin=NULL; | static volatile uint8_t *transmit_pin=NULL; | ||||
static uint8_t transmit_mask=0; | static uint8_t transmit_mask=0; | ||||
#define transmit_assert() *(transmit_pin+4) = transmit_mask; | #define transmit_assert() *(transmit_pin+4) = transmit_mask; | ||||
#define transmit_deassert() *(transmit_pin+8) = 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 | #endif | ||||
#if TX_BUFFER_SIZE > 255 | #if TX_BUFFER_SIZE > 255 | ||||
static volatile uint16_t tx_buffer_head = 0; | static volatile uint16_t tx_buffer_head = 0; | ||||
CORE_PIN10_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1); | CORE_PIN10_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1); | ||||
rx_buffer_head = 0; | rx_buffer_head = 0; | ||||
rx_buffer_tail = 0; | rx_buffer_tail = 0; | ||||
if (rts_pin) rts_deassert(); | |||||
} | } | ||||
void serial2_set_transmit_pin(uint8_t pin) | void serial2_set_transmit_pin(uint8_t pin) | ||||
int serial2_set_rts(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 (!(SIM_SCGC4 & SIM_SCGC4_UART1)) return 0; | ||||
if (pin == 22) { | if (pin == 22) { | ||||
CORE_PIN22_CONFIG = PORT_PCR_MUX(3); | CORE_PIN22_CONFIG = PORT_PCR_MUX(3); | ||||
return 0; | return 0; | ||||
} | } | ||||
UART1_MODEM |= UART_MODEM_RXRTSE; | UART1_MODEM |= UART_MODEM_RXRTSE; | ||||
*/ | |||||
return 1; | return 1; | ||||
} | } | ||||
{ | { | ||||
if (!(SIM_SCGC4 & SIM_SCGC4_UART1)) return 0; | if (!(SIM_SCGC4 & SIM_SCGC4_UART1)) return 0; | ||||
if (pin == 23) { | 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 { | } else { | ||||
UART1_MODEM &= ~UART_MODEM_TXCTSE; | UART1_MODEM &= ~UART_MODEM_TXCTSE; | ||||
return 0; | return 0; | ||||
if (++tail >= RX_BUFFER_SIZE) tail = 0; | if (++tail >= RX_BUFFER_SIZE) tail = 0; | ||||
c = rx_buffer[tail]; | c = rx_buffer[tail]; | ||||
rx_buffer_tail = 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; | return c; | ||||
} | } | ||||
UART1_C2 |= (UART_C2_RE | UART_C2_RIE | UART_C2_ILIE); | UART1_C2 |= (UART_C2_RE | UART_C2_RIE | UART_C2_ILIE); | ||||
#endif | #endif | ||||
rx_buffer_head = rx_buffer_tail; | rx_buffer_head = rx_buffer_tail; | ||||
if (rts_pin) rts_assert(); | |||||
} | } | ||||
// status interrupt combines | // status interrupt combines | ||||
} | } | ||||
} while (--avail > 0); | } while (--avail > 0); | ||||
rx_buffer_head = head; | 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; | c = UART1_C2; |
// Tunable parameters (relatively safe to edit these numbers) | // 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 | #define IRQ_PRIORITY 64 // 0 = highest priority, 255 = lowest | ||||
static volatile uint8_t *transmit_pin=NULL; | static volatile uint8_t *transmit_pin=NULL; | ||||
#define transmit_assert() *transmit_pin = 1 | #define transmit_assert() *transmit_pin = 1 | ||||
#define transmit_deassert() *transmit_pin = 0 | #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) | #elif defined(KINETISL) | ||||
static volatile uint8_t *transmit_pin=NULL; | static volatile uint8_t *transmit_pin=NULL; | ||||
static uint8_t transmit_mask=0; | static uint8_t transmit_mask=0; | ||||
#define transmit_assert() *(transmit_pin+4) = transmit_mask; | #define transmit_assert() *(transmit_pin+4) = transmit_mask; | ||||
#define transmit_deassert() *(transmit_pin+8) = 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 | #endif | ||||
#if TX_BUFFER_SIZE > 255 | #if TX_BUFFER_SIZE > 255 | ||||
static volatile uint16_t tx_buffer_head = 0; | static volatile uint16_t tx_buffer_head = 0; | ||||
CORE_PIN8_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1); | CORE_PIN8_CONFIG = PORT_PCR_PE | PORT_PCR_PS | PORT_PCR_MUX(1); | ||||
rx_buffer_head = 0; | rx_buffer_head = 0; | ||||
rx_buffer_tail = 0; | rx_buffer_tail = 0; | ||||
if (rts_pin) rts_deassert(); | |||||
} | } | ||||
void serial3_set_transmit_pin(uint8_t pin) | void serial3_set_transmit_pin(uint8_t pin) | ||||
int serial3_set_rts(uint8_t pin) | int serial3_set_rts(uint8_t pin) | ||||
{ | { | ||||
if (!(SIM_SCGC4 & SIM_SCGC4_UART2)) return 0; | 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) { | if (pin == 2) { | ||||
CORE_PIN2_CONFIG = PORT_PCR_MUX(3); | CORE_PIN2_CONFIG = PORT_PCR_MUX(3); | ||||
} else { | } else { | ||||
return 0; | return 0; | ||||
} | } | ||||
UART2_MODEM |= UART_MODEM_RXRTSE; | UART2_MODEM |= UART_MODEM_RXRTSE; | ||||
*/ | |||||
return 1; | return 1; | ||||
} | } | ||||
{ | { | ||||
if (!(SIM_SCGC4 & SIM_SCGC4_UART2)) return 0; | if (!(SIM_SCGC4 & SIM_SCGC4_UART2)) return 0; | ||||
if (pin == 14) { | 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 { | } else { | ||||
UART2_MODEM &= ~UART_MODEM_TXCTSE; | UART2_MODEM &= ~UART_MODEM_TXCTSE; | ||||
return 0; | return 0; | ||||
if (++tail >= RX_BUFFER_SIZE) tail = 0; | if (++tail >= RX_BUFFER_SIZE) tail = 0; | ||||
c = rx_buffer[tail]; | c = rx_buffer[tail]; | ||||
rx_buffer_tail = 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; | return c; | ||||
} | } | ||||
void serial3_clear(void) | void serial3_clear(void) | ||||
{ | { | ||||
rx_buffer_head = rx_buffer_tail; | rx_buffer_head = rx_buffer_tail; | ||||
if (rts_pin) rts_assert(); | |||||
} | } | ||||
// status interrupt combines | // status interrupt combines | ||||
rx_buffer[head] = n; | rx_buffer[head] = n; | ||||
rx_buffer_head = head; | 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; | c = UART2_C2; | ||||
if ((c & UART_C2_TIE) && (UART2_S1 & UART_S1_TDRE)) { | if ((c & UART_C2_TIE) && (UART2_S1 & UART_S1_TDRE)) { |