Skip to content

Commit 2ac6c4c

Browse files
author
Bogdan Marinescu
committed
Fixed RTS/CTS bit-banging on LPC1768
1 parent fbeb52d commit 2ac6c4c

File tree

1 file changed

+24
-16
lines changed
  • libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC176X

1 file changed

+24
-16
lines changed

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

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ serial_t stdio_uart;
7676

7777
struct serial_global_data_s {
7878
gpio_t sw_rts, sw_cts;
79-
uint8_t count, initialized, irq_set_flow, irq_set_api;
79+
uint8_t count, initialized, rx_irq_set_flow, rx_irq_set_api;
8080
};
8181

8282
static struct serial_global_data_s uart_data[UART_NUM];
@@ -254,7 +254,7 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b
254254
/******************************************************************************
255255
* INTERRUPTS HANDLING
256256
******************************************************************************/
257-
static inline void uart_irq(uint32_t iir, uint32_t index) {
257+
static inline void uart_irq(uint32_t iir, uint32_t index, LPC_UART_TypeDef *puart) {
258258
// [Chapter 14] LPC17xx UART0/2/3: UARTn Interrupt Handling
259259
SerialIrq irq_type;
260260
switch (iir) {
@@ -263,16 +263,20 @@ static inline void uart_irq(uint32_t iir, uint32_t index) {
263263
default: return;
264264
}
265265

266-
if ((RxIrq == irq_type) && (uart_data[index].sw_rts.pin != NC))
266+
if ((RxIrq == irq_type) && (NC != uart_data[index].sw_rts.pin)) {
267267
gpio_write(&uart_data[index].sw_rts, 1);
268+
// Disable interrupt if it wasn't enabled by other part of the application
269+
if (!uart_data[index].rx_irq_set_api)
270+
puart->IER &= ~(1 << RxIrq);
271+
}
268272
if (serial_irq_ids[index] != 0)
269273
irq_handler(serial_irq_ids[index], irq_type);
270274
}
271275

272-
void uart0_irq() {uart_irq((LPC_UART0->IIR >> 1) & 0x7, 0);}
273-
void uart1_irq() {uart_irq((LPC_UART1->IIR >> 1) & 0x7, 1);}
274-
void uart2_irq() {uart_irq((LPC_UART2->IIR >> 1) & 0x7, 2);}
275-
void uart3_irq() {uart_irq((LPC_UART3->IIR >> 1) & 0x7, 3);}
276+
void uart0_irq() {uart_irq((LPC_UART0->IIR >> 1) & 0x7, 0, (LPC_UART_TypeDef*)LPC_UART0);}
277+
void uart1_irq() {uart_irq((LPC_UART1->IIR >> 1) & 0x7, 1, (LPC_UART_TypeDef*)LPC_UART1);}
278+
void uart2_irq() {uart_irq((LPC_UART2->IIR >> 1) & 0x7, 2, (LPC_UART_TypeDef*)LPC_UART2);}
279+
void uart3_irq() {uart_irq((LPC_UART3->IIR >> 1) & 0x7, 3, (LPC_UART_TypeDef*)LPC_UART3);}
276280

277281
void serial_irq_handler(serial_t *obj, uart_irq_handler handler, uint32_t id) {
278282
irq_handler = handler;
@@ -293,7 +297,7 @@ static void serial_irq_set_internal(serial_t *obj, SerialIrq irq, uint32_t enabl
293297
obj->uart->IER |= 1 << irq;
294298
NVIC_SetVector(irq_n, vector);
295299
NVIC_EnableIRQ(irq_n);
296-
} else if (uart_data[obj->index].irq_set_api + uart_data[obj->index].irq_set_flow == 0) { // disable
300+
} else if ((TxIrq == irq) || (uart_data[obj->index].rx_irq_set_api + uart_data[obj->index].rx_irq_set_flow == 0)) { // disable
297301
int all_disabled = 0;
298302
SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq);
299303
obj->uart->IER &= ~(1 << irq);
@@ -304,23 +308,27 @@ static void serial_irq_set_internal(serial_t *obj, SerialIrq irq, uint32_t enabl
304308
}
305309

306310
void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
307-
uart_data[obj->index].irq_set_api = enable;
311+
if (RxIrq == irq)
312+
uart_data[obj->index].rx_irq_set_api = enable;
308313
serial_irq_set_internal(obj, irq, enable);
309314
}
310315

311-
static void serial_flow_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
312-
uart_data[obj->index].irq_set_flow = enable;
313-
serial_irq_set_internal(obj, irq, enable);
316+
static void serial_flow_irq_set(serial_t *obj, uint32_t enable) {
317+
uart_data[obj->index].rx_irq_set_flow = enable;
318+
serial_irq_set_internal(obj, RxIrq, enable);
314319
}
315320

316321
/******************************************************************************
317322
* READ/WRITE
318323
******************************************************************************/
319324
int serial_getc(serial_t *obj) {
320325
while (!serial_readable(obj));
321-
if (NC != uart_data[obj->index].sw_rts.pin)
326+
int data = obj->uart->RBR;
327+
if (NC != uart_data[obj->index].sw_rts.pin) {
322328
gpio_write(&uart_data[obj->index].sw_rts, 0);
323-
return obj->uart->RBR;
329+
obj->uart->IER |= 1 << RxIrq;
330+
}
331+
return data;
324332
}
325333

326334
void serial_putc(serial_t *obj, int c) {
@@ -373,8 +381,8 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, Pi
373381
// First, disable flow control completely
374382
if (uart1)
375383
uart1->MCR = uart1->MCR & ~UART_MCR_FLOWCTRL_MASK;
376-
serial_flow_irq_set(obj, RxIrq, 0);
377384
uart_data[index].sw_rts.pin = uart_data[index].sw_cts.pin = NC;
385+
serial_flow_irq_set(obj, 0);
378386
if (FlowControlNone == type)
379387
return;
380388
// Check type(s) of flow control to use
@@ -404,7 +412,7 @@ void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, Pi
404412
gpio_init(&uart_data[index].sw_rts, rxflow, PIN_OUTPUT);
405413
gpio_write(&uart_data[index].sw_rts, 0);
406414
// Enable RX interrupt
407-
serial_flow_irq_set(obj, RxIrq, 1);
415+
serial_flow_irq_set(obj, 1);
408416
}
409417
}
410418
}

0 commit comments

Comments
 (0)