Merge branch 'flow_control'

Conflicts:
	workspace_tools/tests.py
pull/135/head
Bogdan Marinescu 2013-12-19 11:36:45 +02:00
commit 34a43eaa41
16 changed files with 329 additions and 37 deletions

View File

@ -51,6 +51,13 @@ public:
TxIrq TxIrq
}; };
enum Flow {
Disabled = 0,
RTS,
CTS,
RTSCTS
};
/** Set the transmission format used by the serial port /** Set the transmission format used by the serial port
* *
* @param bits The number of bits in a word (5-8; default = 8) * @param bits The number of bits in a word (5-8; default = 8)
@ -100,6 +107,16 @@ public:
*/ */
void send_break(); void send_break();
#if DEVICE_SERIAL_FC
/** Set the flow control type on the serial port
*
* @param type the flow control type (Disabled, RTS, CTS, RTSCTS)
* @param flow1 the first flow control pin (RTS for RTS or RTSCTS, CTS for CTS)
* @param flow2 the second flow control pin (CTS for RTSCTS)
*/
void set_flow_control(Flow type, PinName flow1=NC, PinName flow2=NC);
#endif
static void _irq_handler(uint32_t id, SerialIrq irq_type); static void _irq_handler(uint32_t id, SerialIrq irq_type);
protected: protected:

View File

@ -81,6 +81,28 @@ void SerialBase::send_break() {
serial_break_clear(&_serial); serial_break_clear(&_serial);
} }
#ifdef DEVICE_SERIAL_FC
void SerialBase::set_flow_control(Flow type, PinName flow1, PinName flow2) {
FlowControl flow_type = (FlowControl)type;
switch(type) {
case RTS:
serial_set_flow_control(&_serial, flow_type, flow1, NC);
break;
case CTS:
serial_set_flow_control(&_serial, flow_type, NC, flow1);
break;
case RTSCTS:
serial_set_flow_control(&_serial, flow_type, flow1, flow2);
break;
default:
break;
}
}
#endif
} // namespace mbed } // namespace mbed
#endif #endif

View File

@ -44,17 +44,22 @@ uint32_t pinmap_merge(uint32_t a, uint32_t b) {
return (uint32_t)NC; return (uint32_t)NC;
} }
uint32_t pinmap_peripheral(PinName pin, const PinMap* map) { uint32_t pinmap_find_peripheral(PinName pin, const PinMap* map) {
if (pin == (PinName)NC)
return (uint32_t)NC;
while (map->pin != NC) { while (map->pin != NC) {
if (map->pin == pin) if (map->pin == pin)
return map->peripheral; return map->peripheral;
map++; map++;
} }
// no mapping available
error("pinmap not found for peripheral");
return (uint32_t)NC; return (uint32_t)NC;
} }
uint32_t pinmap_peripheral(PinName pin, const PinMap* map) {
uint32_t peripheral = (uint32_t)NC;
if (pin == (PinName)NC)
return (uint32_t)NC;
peripheral = pinmap_find_peripheral(pin, map);
if ((uint32_t)NC == peripheral) // no mapping available
error("pinmap not found for peripheral");
return peripheral;
}

View File

@ -34,6 +34,7 @@ void pin_mode (PinName pin, PinMode mode);
uint32_t pinmap_peripheral(PinName pin, const PinMap* map); uint32_t pinmap_peripheral(PinName pin, const PinMap* map);
uint32_t pinmap_merge (uint32_t a, uint32_t b); uint32_t pinmap_merge (uint32_t a, uint32_t b);
void pinmap_pinout (PinName pin, const PinMap *map); void pinmap_pinout (PinName pin, const PinMap *map);
uint32_t pinmap_find_peripheral(PinName pin, const PinMap* map);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -37,6 +37,13 @@ typedef enum {
TxIrq TxIrq
} SerialIrq; } SerialIrq;
typedef enum {
FlowControlNone,
FlowControlRTS,
FlowControlCTS,
FlowControlRTSCTS
} FlowControl;
typedef void (*uart_irq_handler)(uint32_t id, SerialIrq event); typedef void (*uart_irq_handler)(uint32_t id, SerialIrq event);
typedef struct serial_s serial_t; typedef struct serial_s serial_t;
@ -60,6 +67,8 @@ void serial_break_clear(serial_t *obj);
void serial_pinout_tx(PinName tx); void serial_pinout_tx(PinName tx);
void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -26,6 +26,7 @@
#define DEVICE_ANALOGOUT 1 #define DEVICE_ANALOGOUT 1
#define DEVICE_SERIAL 1 #define DEVICE_SERIAL 1
#define DEVICE_SERIAL_FC 1
#define DEVICE_I2C 1 #define DEVICE_I2C 1
#define DEVICE_I2CSLAVE 1 #define DEVICE_I2CSLAVE 1

View File

@ -20,6 +20,7 @@
#include "PortNames.h" #include "PortNames.h"
#include "PeripheralNames.h" #include "PeripheralNames.h"
#include "PinNames.h" #include "PinNames.h"
#include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -47,7 +48,6 @@ struct pwmout_s {
struct serial_s { struct serial_s {
LPC_UART_TypeDef *uart; LPC_UART_TypeDef *uart;
int index; int index;
uint8_t count;
}; };
struct analogin_s { struct analogin_s {
@ -71,8 +71,6 @@ struct spi_s {
LPC_SSP_TypeDef *spi; LPC_SSP_TypeDef *spi;
}; };
#include "gpio_object.h"
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -21,6 +21,7 @@
#include "cmsis.h" #include "cmsis.h"
#include "pinmap.h" #include "pinmap.h"
#include "error.h" #include "error.h"
#include "gpio_api.h"
/****************************************************************************** /******************************************************************************
* INITIALIZATION * INITIALIZATION
@ -51,12 +52,35 @@ static const PinMap PinMap_UART_RX[] = {
{NC , NC , 0} {NC , NC , 0}
}; };
static uint32_t serial_irq_ids[UART_NUM] = {0}; static const PinMap PinMap_UART_RTS[] = {
{P0_22, UART_1, 1},
{P2_7, UART_1, 2},
{NC, NC, 0}
};
static const PinMap PinMap_UART_CTS[] = {
{P0_17, UART_1, 1},
{P2_2, UART_1, 2},
{NC, NC, 0}
};
#define UART_MCR_RTSEN_MASK (1 << 6)
#define UART_MCR_CTSEN_MASK (1 << 7)
#define UART_MCR_FLOWCTRL_MASK (UART_MCR_RTSEN_MASK | UART_MCR_CTSEN_MASK)
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 {
uint32_t serial_irq_id;
gpio_t sw_rts, sw_cts;
uint8_t rx_irq_set_flow, rx_irq_set_api;
};
static struct serial_global_data_s uart_data[UART_NUM];
void serial_init(serial_t *obj, PinName tx, PinName rx) { void serial_init(serial_t *obj, PinName tx, PinName rx) {
int is_stdio_uart = 0; int is_stdio_uart = 0;
@ -106,7 +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;
} }
obj->count = 0; uart_data[obj->index].sw_rts.pin = NC;
uart_data[obj->index].sw_cts.pin = NC;
serial_set_flow_control(obj, FlowControlNone, NC, NC);
is_stdio_uart = (uart == STDIO_UART) ? (1) : (0); is_stdio_uart = (uart == STDIO_UART) ? (1) : (0);
@ -117,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
@ -251,7 +277,7 @@ void serial_format(serial_t *obj, int data_bits, SerialParity parity, int stop_b
/****************************************************************************** /******************************************************************************
* INTERRUPTS HANDLING * INTERRUPTS HANDLING
******************************************************************************/ ******************************************************************************/
static inline void uart_irq(uint32_t iir, uint32_t index) { static inline void uart_irq(uint32_t iir, uint32_t index, LPC_UART_TypeDef *puart) {
// [Chapter 14] LPC17xx UART0/2/3: UARTn Interrupt Handling // [Chapter 14] LPC17xx UART0/2/3: UARTn Interrupt Handling
SerialIrq irq_type; SerialIrq irq_type;
switch (iir) { switch (iir) {
@ -259,22 +285,28 @@ static inline void uart_irq(uint32_t iir, uint32_t index) {
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 (serial_irq_ids[index] != 0) gpio_write(&uart_data[index].sw_rts, 1);
irq_handler(serial_irq_ids[index], irq_type); // Disable interrupt if it wasn't enabled by other part of the application
if (!uart_data[index].rx_irq_set_api)
puart->IER &= ~(1 << RxIrq);
}
if (uart_data[index].serial_irq_id != 0)
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);} void uart0_irq() {uart_irq((LPC_UART0->IIR >> 1) & 0x7, 0, (LPC_UART_TypeDef*)LPC_UART0);}
void uart1_irq() {uart_irq((LPC_UART1->IIR >> 1) & 0x7, 1);} void uart1_irq() {uart_irq((LPC_UART1->IIR >> 1) & 0x7, 1, (LPC_UART_TypeDef*)LPC_UART1);}
void uart2_irq() {uart_irq((LPC_UART2->IIR >> 1) & 0x7, 2);} void uart2_irq() {uart_irq((LPC_UART2->IIR >> 1) & 0x7, 2, (LPC_UART_TypeDef*)LPC_UART2);}
void uart3_irq() {uart_irq((LPC_UART3->IIR >> 1) & 0x7, 3);} void uart3_irq() {uart_irq((LPC_UART3->IIR >> 1) & 0x7, 3, (LPC_UART_TypeDef*)LPC_UART3);}
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;
} }
void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) { static void serial_irq_set_internal(serial_t *obj, SerialIrq irq, uint32_t enable) {
IRQn_Type irq_n = (IRQn_Type)0; IRQn_Type irq_n = (IRQn_Type)0;
uint32_t vector = 0; uint32_t vector = 0;
switch ((int)obj->uart) { switch ((int)obj->uart) {
@ -288,7 +320,7 @@ void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
obj->uart->IER |= 1 << irq; obj->uart->IER |= 1 << irq;
NVIC_SetVector(irq_n, vector); NVIC_SetVector(irq_n, vector);
NVIC_EnableIRQ(irq_n); NVIC_EnableIRQ(irq_n);
} else { // disable } else if ((TxIrq == irq) || (uart_data[obj->index].rx_irq_set_api + uart_data[obj->index].rx_irq_set_flow == 0)) { // disable
int all_disabled = 0; int all_disabled = 0;
SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq); SerialIrq other_irq = (irq == RxIrq) ? (TxIrq) : (RxIrq);
obj->uart->IER &= ~(1 << irq); obj->uart->IER &= ~(1 << irq);
@ -298,18 +330,33 @@ void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
} }
} }
void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) {
if (RxIrq == irq)
uart_data[obj->index].rx_irq_set_api = enable;
serial_irq_set_internal(obj, irq, enable);
}
static void serial_flow_irq_set(serial_t *obj, uint32_t enable) {
uart_data[obj->index].rx_irq_set_flow = enable;
serial_irq_set_internal(obj, RxIrq, enable);
}
/****************************************************************************** /******************************************************************************
* READ/WRITE * READ/WRITE
******************************************************************************/ ******************************************************************************/
int serial_getc(serial_t *obj) { int serial_getc(serial_t *obj) {
while (!serial_readable(obj)); while (!serial_readable(obj));
return obj->uart->RBR; int data = obj->uart->RBR;
if (NC != uart_data[obj->index].sw_rts.pin) {
gpio_write(&uart_data[obj->index].sw_rts, 0);
obj->uart->IER |= 1 << RxIrq;
}
return data;
} }
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;
obj->count++;
} }
int serial_readable(serial_t *obj) { int serial_readable(serial_t *obj) {
@ -318,11 +365,10 @@ int serial_readable(serial_t *obj) {
int serial_writable(serial_t *obj) { int serial_writable(serial_t *obj) {
int isWritable = 1; int isWritable = 1;
if (obj->uart->LSR & 0x20) if (NC != uart_data[obj->index].sw_cts.pin)
obj->count = 0; isWritable = gpio_read(&uart_data[obj->index].sw_cts) == 0;
else if (obj->count >= 16) if (isWritable)
isWritable = 0; isWritable = obj->uart->LSR & 0x40;
return isWritable; return isWritable;
} }
@ -345,3 +391,49 @@ void serial_break_clear(serial_t *obj) {
obj->uart->LCR &= ~(1 << 6); obj->uart->LCR &= ~(1 << 6);
} }
void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow) {
// Only UART1 has hardware flow control on LPC176x
LPC_UART1_TypeDef *uart1 = (uint32_t)obj->uart == (uint32_t)LPC_UART1 ? LPC_UART1 : NULL;
int index = obj->index;
// First, disable flow control completely
if (uart1)
uart1->MCR = uart1->MCR & ~UART_MCR_FLOWCTRL_MASK;
uart_data[index].sw_rts.pin = uart_data[index].sw_cts.pin = NC;
serial_flow_irq_set(obj, 0);
if (FlowControlNone == type)
return;
// Check type(s) of flow control to use
UARTName uart_rts = (UARTName)pinmap_find_peripheral(rxflow, PinMap_UART_RTS);
UARTName uart_cts = (UARTName)pinmap_find_peripheral(txflow, PinMap_UART_CTS);
if (((FlowControlCTS == type) || (FlowControlRTSCTS == type)) && (NC != txflow)) {
// Can this be enabled in hardware?
if ((UART_1 == uart_cts) && (NULL != uart1)) {
// Enable auto-CTS mode
uart1->MCR |= UART_MCR_CTSEN_MASK;
pinmap_pinout(txflow, PinMap_UART_CTS);
} else {
// Can't enable in hardware, use software emulation
gpio_init(&uart_data[index].sw_cts, txflow, PIN_INPUT);
}
}
if (((FlowControlRTS == type) || (FlowControlRTSCTS == type)) && (NC != rxflow)) {
// Enable FIFOs, trigger level of 1 char on RX FIFO
obj->uart->FCR = 1 << 0 // FIFO Enable - 0 = Disables, 1 = Enabled
| 1 << 1 // Rx Fifo Reset
| 1 << 2 // Tx Fifo Reset
| 0 << 6; // Rx irq trigger level - 0 = 1 char, 1 = 4 chars, 2 = 8 chars, 3 = 14 chars
// Can this be enabled in hardware?
if ((UART_1 == uart_rts) && (NULL != uart1)) {
// Enable auto-RTS mode
uart1->MCR |= UART_MCR_RTSEN_MASK;
pinmap_pinout(rxflow, PinMap_UART_RTS);
} else { // can't enable in hardware, use software emulation
gpio_init(&uart_data[index].sw_rts, rxflow, PIN_OUTPUT);
gpio_write(&uart_data[index].sw_rts, 0);
// Enable RX interrupt
serial_flow_irq_set(obj, 1);
}
}
}

View File

@ -26,6 +26,7 @@
#define DEVICE_ANALOGOUT 0 #define DEVICE_ANALOGOUT 0
#define DEVICE_SERIAL 1 #define DEVICE_SERIAL 1
#define DEVICE_SERIAL_FC 1
#define DEVICE_I2C 1 #define DEVICE_I2C 1
#define DEVICE_I2CSLAVE 0 #define DEVICE_I2CSLAVE 0

View File

@ -39,6 +39,18 @@ static const SWM_Map SWM_UART_RX[] = {
{2, 24}, {2, 24},
}; };
static const SWM_Map SWM_UART_RTS[] = {
{0, 16},
{1, 24},
{3, 0},
};
static const SWM_Map SWM_UART_CTS[] = {
{0, 24},
{2, 0},
{3, 8}
};
// bit flags for used UARTs // bit flags for used UARTs
static unsigned char uart_used = 0; static unsigned char uart_used = 0;
static int get_available_uart(void) { static int get_available_uart(void) {
@ -60,6 +72,7 @@ static int get_available_uart(void) {
#define TXRDY (0x01<<2) #define TXRDY (0x01<<2)
#define TXBRKEN (0x01<<1) #define TXBRKEN (0x01<<1)
#define CTSEN (0x01<<9)
static uint32_t UARTSysClk; static uint32_t UARTSysClk;
@ -278,3 +291,34 @@ void serial_break_clear(serial_t *obj) {
obj->uart->CTRL &= ~TXBRKEN; obj->uart->CTRL &= ~TXBRKEN;
} }
void serial_set_flow_control(serial_t *obj, FlowControl type, PinName rxflow, PinName txflow) {
const SWM_Map *swm_rts, *swm_cts;
uint32_t regVal_rts, regVal_cts;
swm_rts = &SWM_UART_RTS[obj->index];
swm_cts = &SWM_UART_CTS[obj->index];
regVal_rts = LPC_SWM->PINASSIGN[swm_rts->n] & ~(0xFF << swm_rts->offset);
regVal_cts = LPC_SWM->PINASSIGN[swm_cts->n] & ~(0xFF << swm_cts->offset);
if (FlowControlNone == type) {
LPC_SWM->PINASSIGN[swm_rts->n] = regVal_rts | (0xFF << swm_rts->offset);
LPC_SWM->PINASSIGN[swm_cts->n] = regVal_cts | (0xFF << swm_cts->offset);
obj->uart->CFG &= ~CTSEN;
return;
}
if ((FlowControlRTS == type || FlowControlRTSCTS == type) && (rxflow != NC)) {
LPC_SWM->PINASSIGN[swm_rts->n] = regVal_rts | (rxflow << swm_rts->offset);
if (FlowControlRTS == type) {
LPC_SWM->PINASSIGN[swm_cts->n] = regVal_cts | (0xFF << swm_cts->offset);
obj->uart->CFG &= ~CTSEN;
}
}
if ((FlowControlCTS == type || FlowControlRTSCTS == type) && (txflow != NC)) {
LPC_SWM->PINASSIGN[swm_cts->n] = regVal_cts | (txflow << swm_cts->offset);
obj->uart->CFG |= CTSEN;
if (FlowControlCTS == type) {
LPC_SWM->PINASSIGN[swm_rts->n] = regVal_rts | (0xFF << swm_rts->offset);
}
}
}

View File

@ -0,0 +1,34 @@
#include "mbed.h"
#if defined(TARGET_LPC1768)
#define UART_TX p13
#define UART_RX p14
#define FLOW_CONTROL_RTS p30
#define FLOW_CONTROL_CTS p12
#define RTS_CHECK_PIN p15
#else
#error This test is not supported on this target
#endif
Serial pc(UART_TX, UART_RX);
#ifdef RTS_CHECK_PIN
InterruptIn in(RTS_CHECK_PIN);
DigitalOut led(LED1);
static void checker(void) {
led = !led;
}
#endif
int main() {
char buf[256];
pc.set_flow_control(Serial::RTSCTS, FLOW_CONTROL_RTS, FLOW_CONTROL_CTS);
#ifdef RTS_CHECK_PIN
in.fall(checker);
#endif
while (1) {
pc.gets(buf, 256);
pc.printf("%s", buf);
}
}

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

View File

@ -0,0 +1,48 @@
"""
mbed SDK
Copyright (c) 2011-2013 ARM Limited
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
from host_test import Test
class EchoTest(Test):
def __init__(self):
Test.__init__(self)
self.mbed.init_serial()
self.mbed.extra_serial.rtscts = True
self.mbed.reset()
def test(self):
self.mbed.flush()
self.notify("Starting the ECHO test")
TEST="longer serial test"
check = True
for i in range(1, 100):
self.mbed.extra_serial.write(TEST + "\n")
l = self.mbed.extra_serial.readline().strip()
if not l: continue
if l != TEST:
check = False
self.notify('"%s" != "%s"' % (l, TEST))
else:
if (i % 10) == 0:
self.notify('.')
return check
if __name__ == '__main__':
EchoTest().run()

View File

@ -39,6 +39,9 @@ class Mbed:
parser.add_option("-t", "--timeout", dest="timeout", parser.add_option("-t", "--timeout", dest="timeout",
help="Timeout", metavar="TIMEOUT") help="Timeout", metavar="TIMEOUT")
parser.add_option("-e", "--extra", dest="extra",
help="Extra serial port (used by some tests)", metavar="EXTRA")
(self.options, _) = parser.parse_args() (self.options, _) = parser.parse_args()
if self.options.port is None: if self.options.port is None:
@ -46,14 +49,19 @@ class Mbed:
self.port = self.options.port self.port = self.options.port
self.disk = self.options.disk self.disk = self.options.disk
self.extra_port = self.options.extra
self.extra_serial = None
self.serial = None self.serial = None
self.timeout = 10 if self.options.timeout is None else self.options.timeout self.timeout = 10 if self.options.timeout is None else self.options.timeout
print 'Mbed: "%s" "%s"' % (self.port, self.disk) print 'Mbed: "%s" "%s"' % (self.port, self.disk)
def init_serial(self, baud=9600): def init_serial(self, baud=9600, extra_baud=9600):
self.serial = Serial(self.port, timeout = 1) self.serial = Serial(self.port, timeout = 1)
self.serial.setBaudrate(baud) self.serial.setBaudrate(baud)
if self.extra_port:
self.extra_serial = Serial(self.extra_port, timeout = 1)
self.extra_serial.setBaudrate(extra_baud)
self.flush() self.flush()
def reset(self): def reset(self):
@ -64,7 +72,9 @@ class Mbed:
def flush(self): def flush(self):
self.serial.flushInput() self.serial.flushInput()
self.serial.flushOutput() self.serial.flushOutput()
if self.extra_serial:
self.extra_serial.flushInput()
self.extra_serial.flushOutput()
class Test: class Test:
def __init__(self): def __init__(self):

View File

@ -57,9 +57,9 @@ class ProcessObserver(Thread):
pass pass
def run_host_test(client, name, disk, port, duration): def run_host_test(client, name, disk, port, duration, extra_serial):
print "{%s}" % name, print "{%s}" % name,
cmd = ["python", "%s.py" % name, '-p', port, '-d', disk, '-t', str(duration)] cmd = ["python", "%s.py" % name, '-p', port, '-d', disk, '-t', str(duration), "-e", extra_serial]
proc = Popen(cmd, stdout=PIPE, cwd=HOST_TESTS) proc = Popen(cmd, stdout=PIPE, cwd=HOST_TESTS)
obs = ProcessObserver(proc) obs = ProcessObserver(proc)
start = time() start = time()
@ -144,6 +144,7 @@ class Tester(BaseRequestHandler):
disk = mut['disk'] disk = mut['disk']
port = mut['port'] port = mut['port']
extra_serial = mut.get('extra_serial', "")
target = TARGET_MAP[mut['mcu']] target = TARGET_MAP[mut['mcu']]
# Program # Program
@ -169,7 +170,7 @@ class Tester(BaseRequestHandler):
# Host test # Host test
self.request.setblocking(0) self.request.setblocking(0)
result = run_host_test(self.request, test.host_test, disk, port, duration) result = run_host_test(self.request, test.host_test, disk, port, duration, extra_serial)
self.send_result(result) self.send_result(result)

View File

@ -219,6 +219,15 @@ TESTS = [
"automated": True, "automated": True,
"mcu": ["LPC4088"] "mcu": ["LPC4088"]
}, },
{
"id": "MBED_A24", "description": "Serial echo with RTS/CTS flow control",
"source_dir": join(TEST_DIR, "mbed", "echo_flow_control"),
"dependencies": [MBED_LIBRARIES],
"automated": "True",
"host_test": "echo_flow_control",
"mcu": ["LPC1768"],
"peripherals": ["extra_serial"]
},
# Size benchmarks # Size benchmarks
{ {