Skip to content

Commit bb8ed20

Browse files
author
Bogdan Marinescu
committed
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
1 parent c3d4d30 commit bb8ed20

File tree

3 files changed

+19
-24
lines changed

3 files changed

+19
-24
lines changed

libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X/serial_api.c

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,15 @@ static const PinMap PinMap_UART_CTS[] = {
6868
#define UART_MCR_CTSEN_MASK (1 << 7)
6969
#define UART_MCR_FLOWCTRL_MASK (UART_MCR_RTSEN_MASK | UART_MCR_CTSEN_MASK)
7070

71-
static uint32_t serial_irq_ids[UART_NUM] = {0};
7271
static uart_irq_handler irq_handler;
7372

7473
int stdio_uart_inited = 0;
7574
serial_t stdio_uart;
7675

7776
struct serial_global_data_s {
77+
uint32_t serial_irq_id;
7878
gpio_t sw_rts, sw_cts;
79-
uint8_t count, initialized, rx_irq_set_flow, rx_irq_set_api;
79+
uint8_t rx_irq_set_flow, rx_irq_set_api;
8080
};
8181

8282
static struct serial_global_data_s uart_data[UART_NUM];
@@ -130,11 +130,9 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
130130
case UART_2: obj->index = 2; break;
131131
case UART_3: obj->index = 3; break;
132132
}
133-
if (!uart_data[obj->index].initialized) {
134-
uart_data[obj->index].sw_rts.pin = NC;
135-
uart_data[obj->index].sw_cts.pin = NC;
136-
uart_data[obj->index].initialized = 1;
137-
}
133+
uart_data[obj->index].sw_rts.pin = NC;
134+
uart_data[obj->index].sw_cts.pin = NC;
135+
serial_set_flow_control(obj, FlowControlNone, NC, NC);
138136

139137
is_stdio_uart = (uart == STDIO_UART) ? (1) : (0);
140138

@@ -145,7 +143,7 @@ void serial_init(serial_t *obj, PinName tx, PinName rx) {
145143
}
146144

147145
void serial_free(serial_t *obj) {
148-
serial_irq_ids[obj->index] = 0;
146+
uart_data[obj->index].serial_irq_id = 0;
149147
}
150148

151149
// serial_baud
@@ -262,15 +260,15 @@ static inline void uart_irq(uint32_t iir, uint32_t index, LPC_UART_TypeDef *puar
262260
case 2: irq_type = RxIrq; break;
263261
default: return;
264262
}
265-
266263
if ((RxIrq == irq_type) && (NC != uart_data[index].sw_rts.pin)) {
267264
gpio_write(&uart_data[index].sw_rts, 1);
268265
// Disable interrupt if it wasn't enabled by other part of the application
269266
if (!uart_data[index].rx_irq_set_api)
270267
puart->IER &= ~(1 << RxIrq);
271268
}
272-
if (serial_irq_ids[index] != 0)
273-
irq_handler(serial_irq_ids[index], irq_type);
269+
if (uart_data[index].serial_irq_id != 0)
270+
if ((irq_type != RxIrq) || (uart_data[index].rx_irq_set_api))
271+
irq_handler(uart_data[index].serial_irq_id, irq_type);
274272
}
275273

276274
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
280278

281279
void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) {
282280
irq_handler = handler;
283-
serial_irq_ids[obj->index] = id;
281+
uart_data[obj->index].serial_irq_id = id;
284282
}
285283

286284
static void serial_irq_set_internal(serial_t *obj, SerialIrq irq, uint32_t enable) {
@@ -334,7 +332,6 @@ int serial_getc(serial_t *obj) {
334332
void serial_putc(serial_t *obj, int c) {
335333
while (!serial_writable(obj));
336334
obj->uart->THR = c;
337-
uart_data[obj->index].count++;
338335
}
339336

340337
int serial_readable(serial_t *obj) {
@@ -345,12 +342,8 @@ int serial_writable(serial_t *obj) {
345342
int isWritable = 1;
346343
if (NC != uart_data[obj->index].sw_cts.pin)
347344
isWritable = gpio_read(&uart_data[obj->index].sw_cts) == 0;
348-
if (isWritable) {
349-
if (obj->uart->LSR & 0x20)
350-
uart_data[obj->index].count = 0;
351-
else if (uart_data[obj->index].count >= 16)
352-
isWritable = 0;
353-
}
345+
if (isWritable)
346+
isWritable = obj->uart->LSR & 0x40;
354347
return isWritable;
355348
}
356349

@@ -393,6 +386,7 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, Pi
393386
if ((UART_1 == uart_cts) && (NULL != uart1)) {
394387
// Enable auto-CTS mode
395388
uart1->MCR |= UART_MCR_CTSEN_MASK;
389+
pinmap_pinout(txflow, PinMap_UART_CTS);
396390
} else {
397391
// Can't enable in hardware, use software emulation
398392
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
408402
if ((UART_1 == uart_rts) && (NULL != uart1)) {
409403
// Enable auto-RTS mode
410404
uart1->MCR |= UART_MCR_RTSEN_MASK;
405+
pinmap_pinout(rxflow, PinMap_UART_RTS);
411406
} else { // can't enable in hardware, use software emulation
412407
gpio_init(&uart_data[index].sw_rts, rxflow, PIN_OUTPUT);
413408
gpio_write(&uart_data[index].sw_rts, 0);

libraries/tests/mbed/echo_flow_control/main.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
#include "mbed.h"
22

33
#if defined(TARGET_LPC1768)
4-
#define UART_TX p9
5-
#define UART_RX p10
6-
#define FLOW_CONTROL_RTS p11
4+
#define UART_TX p13
5+
#define UART_RX p14
6+
#define FLOW_CONTROL_RTS p30
77
#define FLOW_CONTROL_CTS p12
8-
#define RTS_CHECK_PIN p13
8+
#define RTS_CHECK_PIN p15
99
#else
1010
#error This test is not supported on this target
1111
#endif

workspace_tools/build.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
# Be sure that the tools directory is in the search path
2525
ROOT = abspath(join(dirname(__file__), ".."))
26-
sys.path.append(ROOT)
26+
sys.path.insert(0, ROOT)
2727

2828
from workspace_tools.toolchains import TOOLCHAINS
2929
from workspace_tools.targets import TARGET_NAMES, TARGET_MAP

0 commit comments

Comments
 (0)