LPC1768 flow control fixes

- Disable TX buffer, this isn't compatible with the software CTS implementation
- Properly set hardware RTS/CTS pins when possible
- Modified test to use hardware CTS and software RTS
pull/135/head
Bogdan Marinescu 2013-12-11 16:31:59 +02:00
parent c3d4d3079f
commit bb8ed20a47
3 changed files with 19 additions and 24 deletions

View File

@ -68,15 +68,15 @@ static const PinMap PinMap_UART_CTS[] = {
#define UART_MCR_CTSEN_MASK (1 << 7) #define UART_MCR_CTSEN_MASK (1 << 7)
#define UART_MCR_FLOWCTRL_MASK (UART_MCR_RTSEN_MASK | UART_MCR_CTSEN_MASK) #define UART_MCR_FLOWCTRL_MASK (UART_MCR_RTSEN_MASK | UART_MCR_CTSEN_MASK)
static uint32_t serial_irq_ids[UART_NUM] = {0};
static uart_irq_handler irq_handler; static uart_irq_handler irq_handler;
int stdio_uart_inited = 0; int stdio_uart_inited = 0;
serial_t stdio_uart; serial_t stdio_uart;
struct serial_global_data_s { struct serial_global_data_s {
uint32_t serial_irq_id;
gpio_t sw_rts, sw_cts; gpio_t sw_rts, sw_cts;
uint8_t count, initialized, rx_irq_set_flow, rx_irq_set_api; uint8_t rx_irq_set_flow, rx_irq_set_api;
}; };
static struct serial_global_data_s uart_data[UART_NUM]; static struct serial_global_data_s uart_data[UART_NUM];
@ -130,11 +130,9 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
case UART_2: obj->index = 2; break; case UART_2: obj->index = 2; break;
case UART_3: obj->index = 3; break; case UART_3: obj->index = 3; break;
} }
if (!uart_data[obj->index].initialized) {
uart_data[obj->index].sw_rts.pin = NC; uart_data[obj->index].sw_rts.pin = NC;
uart_data[obj->index].sw_cts.pin = NC; uart_data[obj->index].sw_cts.pin = NC;
uart_data[obj->index].initialized = 1; serial_set_flow_control(obj, FlowControlNone, NC, NC);
}
is_stdio_uart = (uart == STDIO_UART) ? (1) : (0); is_stdio_uart = (uart == STDIO_UART) ? (1) : (0);
@ -145,7 +143,7 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
} }
void serial_free(serial_t *obj) { void serial_free(serial_t *obj) {
serial_irq_ids[obj->index] = 0; uart_data[obj->index].serial_irq_id = 0;
} }
// serial_baud // serial_baud
@ -262,15 +260,15 @@ static inline void uart_irq(uint32_t iir, uint32_t index, LPC_UART_TypeDef *puar
case 2: irq_type = RxIrq; break; case 2: irq_type = RxIrq; break;
default: return; default: return;
} }
if ((RxIrq == irq_type) && (NC != uart_data[index].sw_rts.pin)) { if ((RxIrq == irq_type) && (NC != uart_data[index].sw_rts.pin)) {
gpio_write(&uart_data[index].sw_rts, 1); gpio_write(&uart_data[index].sw_rts, 1);
// Disable interrupt if it wasn't enabled by other part of the application // Disable interrupt if it wasn't enabled by other part of the application
if (!uart_data[index].rx_irq_set_api) if (!uart_data[index].rx_irq_set_api)
puart->IER &= ~(1 << RxIrq); puart->IER &= ~(1 << RxIrq);
} }
if (serial_irq_ids[index] != 0) if (uart_data[index].serial_irq_id != 0)
irq_handler(serial_irq_ids[index], irq_type); if ((irq_type != RxIrq) || (uart_data[index].rx_irq_set_api))
irq_handler(uart_data[index].serial_irq_id, irq_type);
} }
void uart0_irq() {uart_irq((LPC_UART0->IIR >> 1) & 0x7, 0, (LPC_UART_TypeDef*)LPC_UART0);} void uart0_irq() {uart_irq((LPC_UART0->IIR >> 1) & 0x7, 0, (LPC_UART_TypeDef*)LPC_UART0);}
@ -280,7 +278,7 @@ void uart3_irq() {uart_irq((LPC_UART3->IIR >> 1) & 0x7, 3, (LPC_UART_TypeDef*)LP
void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) { void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) {
irq_handler = handler; irq_handler = handler;
serial_irq_ids[obj->index] = id; uart_data[obj->index].serial_irq_id = id;
} }
static void serial_irq_set_internal(serial_t *obj, SerialIrq irq, uint32_t enable) { static void serial_irq_set_internal(serial_t *obj, SerialIrq irq, uint32_t enable) {
@ -334,7 +332,6 @@ int serial_getc(serial_t *obj) {
void serial_putc(serial_t *obj, int c) { void serial_putc(serial_t *obj, int c) {
while (!serial_writable(obj)); while (!serial_writable(obj));
obj->uart->THR = c; obj->uart->THR = c;
uart_data[obj->index].count++;
} }
int serial_readable(serial_t *obj) { int serial_readable(serial_t *obj) {
@ -345,12 +342,8 @@ int serial_writable(serial_t *obj) {
int isWritable = 1; int isWritable = 1;
if (NC != uart_data[obj->index].sw_cts.pin) if (NC != uart_data[obj->index].sw_cts.pin)
isWritable = gpio_read(&uart_data[obj->index].sw_cts) == 0; isWritable = gpio_read(&uart_data[obj->index].sw_cts) == 0;
if (isWritable) { if (isWritable)
if (obj->uart->LSR & 0x20) isWritable = obj->uart->LSR & 0x40;
uart_data[obj->index].count = 0;
else if (uart_data[obj->index].count >= 16)
isWritable = 0;
}
return isWritable; return isWritable;
} }
@ -393,6 +386,7 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, Pi
if ((UART_1 == uart_cts) && (NULL != uart1)) { if ((UART_1 == uart_cts) && (NULL != uart1)) {
// Enable auto-CTS mode // Enable auto-CTS mode
uart1->MCR |= UART_MCR_CTSEN_MASK; uart1->MCR |= UART_MCR_CTSEN_MASK;
pinmap_pinout(txflow, PinMap_UART_CTS);
} else { } else {
// Can't enable in hardware, use software emulation // Can't enable in hardware, use software emulation
gpio_init(&uart_data[index].sw_cts, txflow, PIN_INPUT); gpio_init(&uart_data[index].sw_cts, txflow, PIN_INPUT);
@ -408,6 +402,7 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, Pi
if ((UART_1 == uart_rts) && (NULL != uart1)) { if ((UART_1 == uart_rts) && (NULL != uart1)) {
// Enable auto-RTS mode // Enable auto-RTS mode
uart1->MCR |= UART_MCR_RTSEN_MASK; uart1->MCR |= UART_MCR_RTSEN_MASK;
pinmap_pinout(rxflow, PinMap_UART_RTS);
} else { // can't enable in hardware, use software emulation } else { // can't enable in hardware, use software emulation
gpio_init(&uart_data[index].sw_rts, rxflow, PIN_OUTPUT); gpio_init(&uart_data[index].sw_rts, rxflow, PIN_OUTPUT);
gpio_write(&uart_data[index].sw_rts, 0); gpio_write(&uart_data[index].sw_rts, 0);

View File

@ -1,11 +1,11 @@
#include "mbed.h" #include "mbed.h"
#if defined(TARGET_LPC1768) #if defined(TARGET_LPC1768)
#define UART_TX p9 #define UART_TX p13
#define UART_RX p10 #define UART_RX p14
#define FLOW_CONTROL_RTS p11 #define FLOW_CONTROL_RTS p30
#define FLOW_CONTROL_CTS p12 #define FLOW_CONTROL_CTS p12
#define RTS_CHECK_PIN p13 #define RTS_CHECK_PIN p15
#else #else
#error This test is not supported on this target #error This test is not supported on this target
#endif #endif

View File

@ -23,7 +23,7 @@ from os.path import join, abspath, dirname
# Be sure that the tools directory is in the search path # Be sure that the tools directory is in the search path
ROOT = abspath(join(dirname(__file__), "..")) ROOT = abspath(join(dirname(__file__), ".."))
sys.path.append(ROOT) sys.path.insert(0, ROOT)
from workspace_tools.toolchains import TOOLCHAINS from workspace_tools.toolchains import TOOLCHAINS
from workspace_tools.targets import TARGET_NAMES, TARGET_MAP from workspace_tools.targets import TARGET_NAMES, TARGET_MAP