git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1539 35acf78f-673a-0410-8e92-d51de3d6d3f4

This commit is contained in:
gdisirio 2010-01-22 14:51:54 +00:00
parent 11a6a2bf64
commit 11215c3bcb
23 changed files with 421 additions and 703 deletions

View File

@ -96,7 +96,7 @@ static void termination_handler(eventid_t id) {
chThdSleepMilliseconds(10);
cputs("Init: shell on SD1 terminated");
chSysLock();
chOQResetI(&SD1.sd.oqueue);
chOQResetI(&SD1.oqueue);
chSysUnlock();
}
if (shelltp2 && chThdTerminated(shelltp2)) {
@ -105,7 +105,7 @@ static void termination_handler(eventid_t id) {
chThdSleepMilliseconds(10);
cputs("Init: shell on SD2 terminated");
chSysLock();
chOQResetI(&SD2.sd.oqueue);
chOQResetI(&SD2.oqueue);
chSysUnlock();
}
}
@ -128,7 +128,7 @@ static void sd1_handler(eventid_t id) {
if (flags & SD_DISCONNECTED) {
cputs("Init: disconnection on SD1");
chSysLock();
chIQResetI(&SD1.sd.iqueue);
chIQResetI(&SD1.iqueue);
chSysUnlock();
}
}
@ -151,7 +151,7 @@ static void sd2_handler(eventid_t id) {
if (flags & SD_DISCONNECTED) {
cputs("Init: disconnection on SD2");
chSysLock();
chIQResetI(&SD2.sd.iqueue);
chIQResetI(&SD2.iqueue);
chSysUnlock();
}
}
@ -202,10 +202,10 @@ int main(void) {
cputs("Shell service started on SD1, SD2");
cputs(" - Listening for connections on SD1");
(void) sdGetAndClearFlags(&SD1);
chEvtRegister(&SD1.sd.sevent, &sd1fel, 1);
chEvtRegister(&SD1.sevent, &sd1fel, 1);
cputs(" - Listening for connections on SD2");
(void) sdGetAndClearFlags(&SD2);
chEvtRegister(&SD2.sd.sevent, &sd2fel, 2);
chEvtRegister(&SD2.sevent, &sd2fel, 2);
/*
* Events servicing loop.
@ -216,7 +216,7 @@ int main(void) {
/*
* Clean simulator exit.
*/
chEvtUnregister(&SD1.sd.sevent, &sd1fel);
chEvtUnregister(&SD2.sd.sevent, &sd2fel);
chEvtUnregister(&SD1.sevent, &sd1fel);
chEvtUnregister(&SD2.sevent, &sd2fel);
return 0;
}

View File

@ -94,7 +94,7 @@ static void termination_handler(eventid_t id) {
chThdSleepMilliseconds(10);
cputs("Init: shell on SD1 terminated");
chSysLock();
chOQResetI(&SD1.sd.oqueue);
chOQResetI(&SD1.oqueue);
chSysUnlock();
}
if (shelltp2 && chThdTerminated(shelltp2)) {
@ -103,7 +103,7 @@ static void termination_handler(eventid_t id) {
chThdSleepMilliseconds(10);
cputs("Init: shell on SD2 terminated");
chSysLock();
chOQResetI(&SD2.sd.oqueue);
chOQResetI(&SD2.oqueue);
chSysUnlock();
}
}
@ -125,7 +125,7 @@ static void sd1_handler(eventid_t id) {
if (flags & SD_DISCONNECTED) {
cputs("Init: disconnection on SD1");
chSysLock();
chIQResetI(&SD1.sd.iqueue);
chIQResetI(&SD1.iqueue);
chSysUnlock();
}
}
@ -147,7 +147,7 @@ static void sd2_handler(eventid_t id) {
if (flags & SD_DISCONNECTED) {
cputs("Init: disconnection on SD2");
chSysLock();
chIQResetI(&SD2.sd.iqueue);
chIQResetI(&SD2.iqueue);
chSysUnlock();
}
}
@ -198,10 +198,10 @@ int main(void) {
cputs("Shell service started on SD1, SD2");
cputs(" - Listening for connections on SD1");
(void) sdGetAndClearFlags(&SD1);
chEvtRegister(&SD1.sd.sevent, &sd1fel, 1);
chEvtRegister(&SD1.sevent, &sd1fel, 1);
cputs(" - Listening for connections on SD2");
(void) sdGetAndClearFlags(&SD2);
chEvtRegister(&SD2.sd.sevent, &sd2fel, 2);
chEvtRegister(&SD2.sevent, &sd2fel, 2);
/*
* Events servicing loop.
@ -212,7 +212,7 @@ int main(void) {
/*
* Clean simulator exit.
*/
chEvtUnregister(&SD1.sd.sevent, &sd1fel);
chEvtUnregister(&SD2.sd.sevent, &sd2fel);
chEvtUnregister(&SD1.sevent, &sd1fel);
chEvtUnregister(&SD2.sevent, &sd2fel);
return 0;
}

View File

@ -104,29 +104,14 @@ typedef struct _SerialDriver SerialDriver;
/**
* @brief @p SerialDriver specific methods.
*/
struct _serial_driver_methods {
};
#define _serial_driver_methods \
_base_asynchronous_channel_methods
/**
* @brief @p SerialDriver virtual methods table.
*/
struct SerialDriverVMT {
/**
* @p BaseSequentialStream class inherited methods.
*/
struct _base_sequental_stream_methods bss;
/**
* @p BaseChannel class inherited methods.
*/
struct _base_channel_methods bc;
/**
* @p BaseAsynchronousChannel class inherited methods.
*/
struct _base_asynchronous_channel_methods bac;
/**
* @p SerialDriver specific methods.
*/
struct _serial_driver_methods sd;
_serial_driver_methods;
};
/**
@ -141,22 +126,7 @@ struct _SerialDriver {
* Virtual Methods Table.
*/
const struct SerialDriverVMT *vmt;
/**
* @p BaseSequentialStream class inherited data.
*/
struct _base_sequental_stream_data bss;
/**
* @p BaseChannel class inherited data.
*/
struct _base_channel_data bc;
/**
* @p BaseAsynchronousChannel class inherited data.
*/
struct _base_asynchronous_channel_data bac;
/**
* @p SerialDriver specific data.
*/
struct _serial_driver_data sd;
_serial_driver_data;
};
/*===========================================================================*/
@ -170,7 +140,7 @@ struct _SerialDriver {
* be used to check different channels implementations.
* @see chIOPutWouldBlock()
*/
#define sdPutWouldBlock(sdp) chOQIsFull(&(sdp)->sd.oqueue)
#define sdPutWouldBlock(sdp) chOQIsFull(&(sdp)->oqueue)
/**
* @brief Direct input check on a @p SerialDriver.
@ -179,7 +149,7 @@ struct _SerialDriver {
* be used to check different channels implementations.
* @see chIOGetWouldBlock()
*/
#define sdGetWouldBlock(sdp) chIQIsEmpty(&(sdp)->sd.iqueue)
#define sdGetWouldBlock(sdp) chIQIsEmpty(&(sdp)->iqueue)
/**
* @brief Direct write to a @p SerialDriver.
@ -188,7 +158,7 @@ struct _SerialDriver {
* be used to write to different channels implementations.
* @see chIOPut()
*/
#define sdPut(sdp, b) chOQPut(&(sdp)->sd.oqueue, b)
#define sdPut(sdp, b) chOQPut(&(sdp)->oqueue, b)
/**
* @brief Direct write to a @p SerialDriver with timeout specification.
@ -197,7 +167,7 @@ struct _SerialDriver {
* be used to write to different channels implementations.
* @see chIOPutTimeout()
*/
#define sdPutTimeout(sdp, b, t) chOQPutTimeout(&(sdp)->sd.iqueue, b, t)
#define sdPutTimeout(sdp, b, t) chOQPutTimeout(&(sdp)->iqueue, b, t)
/**
* @brief Direct read from a @p SerialDriver.
@ -206,7 +176,7 @@ struct _SerialDriver {
* be used to read from different channels implementations.
* @see chIOGet()
*/
#define sdGet(sdp) chIQGet(&(sdp)->sd.iqueue)
#define sdGet(sdp) chIQGet(&(sdp)->iqueue)
/**
* @brief Direct read from a @p SerialDriver with timeout specification.
@ -215,7 +185,7 @@ struct _SerialDriver {
* be used to read from different channels implementations.
* @see chIOGetTimeout()
*/
#define sdGetTimeout(sdp, t) chIQGetTimeout(&(sdp)->sd.iqueue, t)
#define sdGetTimeout(sdp, t) chIQGetTimeout(&(sdp)->iqueue, t)
/**
* @brief Direct blocking write to a @p SerialDriver.
@ -225,7 +195,7 @@ struct _SerialDriver {
* @see chIOWriteTimeout()
*/
#define sdWrite(sdp, b, n) \
chOQWriteTimeout(&(sdp)->sd.oqueue, b, n, TIME_INFINITE)
chOQWriteTimeout(&(sdp)->oqueue, b, n, TIME_INFINITE)
/**
* @brief Direct blocking write to a @p SerialDriver with timeout
@ -236,7 +206,7 @@ struct _SerialDriver {
* @see chIOWriteTimeout()
*/
#define sdWriteTimeout(sdp, b, n, t) \
chOQWriteTimeout(&(sdp)->sd.oqueue, b, n, t)
chOQWriteTimeout(&(sdp)->oqueue, b, n, t)
/**
* @brief Direct non-blocking write to a @p SerialDriver.
@ -246,7 +216,7 @@ struct _SerialDriver {
* @see chIOWriteTimeout()
*/
#define sdAsynchronousWrite(sdp, b, n) \
chOQWriteTimeout(&(sdp)->sd.oqueue, b, n, TIME_IMMEDIATE)
chOQWriteTimeout(&(sdp)->oqueue, b, n, TIME_IMMEDIATE)
/**
* @brief Direct blocking read from a @p SerialDriver.
@ -256,7 +226,7 @@ struct _SerialDriver {
* @see chIOReadTimeout()
*/
#define sdRead(sdp, b, n) \
chIQReadTimeout(&(sdp)->sd.iqueue, b, n, TIME_INFINITE)
chIQReadTimeout(&(sdp)->iqueue, b, n, TIME_INFINITE)
/**
* @brief Direct blocking read from a @p SerialDriver with timeout
@ -267,7 +237,7 @@ struct _SerialDriver {
* @see chIOReadTimeout()
*/
#define sdReadTimeout(sdp, b, n, t) \
chIQReadTimeout(&(sdp)->sd.iqueue, b, n, t)
chIQReadTimeout(&(sdp)->iqueue, b, n, t)
/**
* @brief Direct non-blocking read from a @p SerialDriver.
@ -277,7 +247,7 @@ struct _SerialDriver {
* @see chIOReadTimeout()
*/
#define sdAsynchronousRead(sdp, b, n) \
chIQReadTimeout(&(sdp)->sd.iqueue, b, n, TIME_IMMEDIATE)
chIQReadTimeout(&(sdp)->iqueue, b, n, TIME_IMMEDIATE)
/**
* @brief Returns the status change event source.
@ -288,7 +258,7 @@ struct _SerialDriver {
* @param[in] ip pointer to a @p SerialDriver object
* @return A pointer to an @p EventSource object.
*/
#define sdGetStatusChangeEventSource(ip) (&((ip)->vmt->sd.sevent))
#define sdGetStatusChangeEventSource(ip) (&((ip)->vmt->sevent))
/*===========================================================================*/
/* External declarations. */

View File

@ -82,18 +82,18 @@ static const SerialConfig default_config = {
* @param[in] sdp communication channel associated to the USART
*/
static void usart_init(SerialDriver *sdp) {
AT91PS_USART u = sdp->sd.usart;
AT91PS_USART u = sdp->usart;
/* Disables IRQ sources and stop operations.*/
u->US_IDR = 0xFFFFFFFF;
u->US_CR = AT91C_US_RSTRX | AT91C_US_RSTTX | AT91C_US_RSTSTA;
/* New parameters setup.*/
if (sdp->sd.config->sc_mr & AT91C_US_OVER)
u->US_BRGR = MCK / (sdp->sd.config->sc_speed * 8);
if (sdp->config->sc_mr & AT91C_US_OVER)
u->US_BRGR = MCK / (sdp->config->sc_speed * 8);
else
u->US_BRGR = MCK / (sdp->sd.config->sc_speed * 16);
u->US_MR = sdp->sd.config->sc_mr;
u->US_BRGR = MCK / (sdp->config->sc_speed * 16);
u->US_MR = sdp->config->sc_mr;
u->US_RTOR = 0;
u->US_TTGR = 0;
@ -148,7 +148,7 @@ __attribute__((noinline))
*/
static void serve_interrupt(SerialDriver *sdp) {
uint32_t csr;
AT91PS_USART u = sdp->sd.usart;
AT91PS_USART u = sdp->usart;
csr = u->US_CSR;
if (csr & AT91C_US_RXRDY) {
@ -160,9 +160,9 @@ static void serve_interrupt(SerialDriver *sdp) {
msg_t b;
chSysLockFromIsr();
b = chOQGetI(&sdp->sd.oqueue);
b = chOQGetI(&sdp->oqueue);
if (b < Q_OK) {
chEvtBroadcastI(&sdp->bac.oevent);
chEvtBroadcastI(&sdp->oevent);
u->US_IDR = AT91C_US_TXRDY;
}
else
@ -228,7 +228,7 @@ void sd_lld_init(void) {
#if USE_SAM7_USART0
sdObjectInit(&SD1, NULL, notify1);
SD1.sd.usart = AT91C_BASE_US0;
SD1.usart = AT91C_BASE_US0;
AT91C_BASE_PIOA->PIO_PDR = SAM7_USART0_RX | SAM7_USART0_TX;
AT91C_BASE_PIOA->PIO_ASR = SAM7_USART0_RX | SAM7_USART0_TX;
AT91C_BASE_PIOA->PIO_PPUDR = SAM7_USART0_RX | SAM7_USART0_TX;
@ -239,7 +239,7 @@ void sd_lld_init(void) {
#if USE_SAM7_USART1
sdObjectInit(&SD2, NULL, notify2);
SD2.sd.usart = AT91C_BASE_US1;
SD2.usart = AT91C_BASE_US1;
AT91C_BASE_PIOA->PIO_PDR = SAM7_USART1_RX | SAM7_USART1_TX;
AT91C_BASE_PIOA->PIO_ASR = SAM7_USART1_RX | SAM7_USART1_TX;
AT91C_BASE_PIOA->PIO_PPUDR = SAM7_USART1_RX | SAM7_USART1_TX;
@ -256,10 +256,10 @@ void sd_lld_init(void) {
*/
void sd_lld_start(SerialDriver *sdp) {
if (sdp->sd.config == NULL)
sdp->sd.config = &default_config;
if (sdp->config == NULL)
sdp->config = &default_config;
if (sdp->sd.state == SD_STOP) {
if (sdp->state == SD_STOP) {
#if USE_SAM7_USART0
if (&SD1 == sdp) {
/* Starts the clock and clears possible sources of immediate interrupts.*/
@ -289,8 +289,8 @@ void sd_lld_start(SerialDriver *sdp) {
*/
void sd_lld_stop(SerialDriver *sdp) {
if (sdp->sd.state == SD_READY) {
usart_deinit(sdp->sd.usart);
if (sdp->state == SD_READY) {
usart_deinit(sdp->usart);
#if USE_SAM7_USART0
if (&SD1 == sdp) {
AT91C_BASE_PMC->PMC_PCDR = (1 << AT91C_ID_US0);

View File

@ -101,48 +101,27 @@ typedef struct {
/**
* @brief @p SerialDriver specific data.
*/
struct _serial_driver_data {
/**
* @brief Driver state.
*/
sdstate_t state;
/**
* @brief Current configuration data.
*/
const SerialConfig *config;
/**
* @brief Input queue, incoming data can be read from this input queue by
* using the queues APIs.
*/
InputQueue iqueue;
/**
* @brief Output queue, outgoing data can be written to this output queue by
* using the queues APIs.
*/
OutputQueue oqueue;
/**
* @brief Status Change @p EventSource. This event is generated when one or
* more condition flags change.
*/
EventSource sevent;
/**
* @brief I/O driver status flags.
*/
sdflags_t flags;
/**
* @brief Input circular buffer.
*/
uint8_t ib[SERIAL_BUFFERS_SIZE];
/**
* @brief Output circular buffer.
*/
uint8_t ob[SERIAL_BUFFERS_SIZE];
/* End of the mandatory fields.*/
/**
* @brief Pointer to the USART registers block.
*/
AT91PS_USART usart;
};
#define _serial_driver_data \
_base_asynchronous_channel_data; \
/* Driver state.*/ \
sdstate_t state; \
/* Current configuration data.*/ \
const SerialConfig *config; \
/* Input queue.*/ \
InputQueue iqueue; \
/* Output queue.*/ \
OutputQueue oqueue; \
/* Status Change @p EventSource.*/ \
EventSource sevent; \
/* I/O driver status flags.*/ \
sdflags_t flags; \
/* Input circular buffer.*/ \
uint8_t ib[SERIAL_BUFFERS_SIZE]; \
/* Output circular buffer.*/ \
uint8_t ob[SERIAL_BUFFERS_SIZE]; \
/* End of the mandatory fields.*/ \
/* Pointer to the USART registers block.*/ \
AT91PS_USART usart
/*===========================================================================*/
/* Driver macros. */

View File

@ -235,18 +235,18 @@ void sd_lld_init(void) {
*/
void sd_lld_start(SerialDriver *sdp) {
if (sdp->sd.config == NULL)
sdp->sd.config = &default_config;
if (sdp->config == NULL)
sdp->config = &default_config;
#if USE_AVR_USART0
if (&SD1 == sdp) {
usart0_init(sdp->sd.config);
usart0_init(sdp->config);
return;
}
#endif
#if USE_AVR_USART1
if (&SD2 == sdp) {
usart1_init(sdp->sd.config);
usart1_init(sdp->config);
return;
}
#endif

View File

@ -87,44 +87,25 @@ typedef struct {
/**
* @brief @p SerialDriver specific data.
*/
struct _serial_driver_data {
/**
* @brief Driver state.
*/
sdstate_t state;
/**
* @brief Current configuration data.
*/
const SerialConfig *config;
/**
* @brief Input queue, incoming data can be read from this input queue by
* using the queues APIs.
*/
InputQueue iqueue;
/**
* @brief Output queue, outgoing data can be written to this output queue by
* using the queues APIs.
*/
OutputQueue oqueue;
/**
* @brief Status Change @p EventSource. This event is generated when one or
* more condition flags change.
*/
EventSource sevent;
/**
* @brief I/O driver status flags.
*/
sdflags_t flags;
/**
* @brief Input circular buffer.
*/
uint8_t ib[SERIAL_BUFFERS_SIZE];
/**
* @brief Output circular buffer.
*/
uint8_t ob[SERIAL_BUFFERS_SIZE];
#define _serial_driver_data \
_base_asynchronous_channel_data; \
/* Driver state.*/ \
sdstate_t state; \
/* Current configuration data.*/ \
const SerialConfig *config; \
/* Input queue.*/ \
InputQueue iqueue; \
/* Output queue.*/ \
OutputQueue oqueue; \
/* Status Change @p EventSource.*/ \
EventSource sevent; \
/* I/O driver status flags.*/ \
sdflags_t flags; \
/* Input circular buffer.*/ \
uint8_t ib[SERIAL_BUFFERS_SIZE]; \
/* Output circular buffer.*/ \
uint8_t ob[SERIAL_BUFFERS_SIZE]; \
/* End of the mandatory fields.*/
};
/*===========================================================================*/
/* Driver macros. */

View File

@ -64,14 +64,14 @@ static const SerialConfig default_config = {
* @param[in] sdp communication channel associated to the UART
*/
static void uart_init(SerialDriver *sdp) {
UART *u = sdp->sd.uart;
UART *u = sdp->uart;
uint32_t div = PCLK / (sdp->sd.config->sc_speed << 4);
u->UART_LCR = sdp->sd.config->sc_lcr | LCR_DLAB;
uint32_t div = PCLK / (sdp->config->sc_speed << 4);
u->UART_LCR = sdp->config->sc_lcr | LCR_DLAB;
u->UART_DLL = div;
u->UART_DLM = div >> 8;
u->UART_LCR = sdp->sd.config->sc_lcr;
u->UART_FCR = FCR_ENABLE | FCR_RXRESET | FCR_TXRESET | sdp->sd.config->sc_fcr;
u->UART_LCR = sdp->config->sc_lcr;
u->UART_FCR = FCR_ENABLE | FCR_RXRESET | FCR_TXRESET | sdp->config->sc_fcr;
u->UART_ACR = 0;
u->UART_FDR = 0x10;
u->UART_TER = TER_ENABLE;
@ -128,7 +128,7 @@ __attribute__((noinline))
* go through the whole ISR and have another interrupt soon after.
*/
static void serve_interrupt(SerialDriver *sdp) {
UART *u = sdp->sd.uart;
UART *u = sdp->uart;
while (TRUE) {
switch (u->UART_IIR & IIR_SRC_MASK) {
@ -140,12 +140,12 @@ static void serve_interrupt(SerialDriver *sdp) {
case IIR_SRC_TIMEOUT:
case IIR_SRC_RX:
chSysLockFromIsr();
if (chIQIsEmpty(&sdp->sd.iqueue))
chEvtBroadcastI(&sdp->bac.ievent);
if (chIQIsEmpty(&sdp->iqueue))
chEvtBroadcastI(&sdp->ievent);
chSysUnlockFromIsr();
while (u->UART_LSR & LSR_RBR_FULL) {
chSysLockFromIsr();
if (chIQPutI(&sdp->sd.iqueue, u->UART_RBR) < Q_OK)
if (chIQPutI(&sdp->iqueue, u->UART_RBR) < Q_OK)
sdAddFlagsI(sdp, SD_OVERRUN_ERROR);
chSysUnlockFromIsr();
}
@ -157,12 +157,12 @@ static void serve_interrupt(SerialDriver *sdp) {
msg_t b;
chSysLockFromIsr();
b = chOQGetI(&sdp->sd.oqueue);
b = chOQGetI(&sdp->oqueue);
chSysUnlockFromIsr();
if (b < Q_OK) {
u->UART_IER &= ~IER_THRE;
chSysLockFromIsr();
chEvtBroadcastI(&sdp->bac.oevent);
chEvtBroadcastI(&sdp->oevent);
chSysUnlockFromIsr();
break;
}
@ -181,14 +181,14 @@ static void serve_interrupt(SerialDriver *sdp) {
* @brief Attempts a TX FIFO preload.
*/
static void preload(SerialDriver *sdp) {
UART *u = sdp->sd.uart;
UART *u = sdp->uart;
if (u->UART_LSR & LSR_THRE) {
int i = LPC214x_UART_FIFO_PRELOAD;
do {
msg_t b = chOQGetI(&sdp->sd.oqueue);
msg_t b = chOQGetI(&sdp->oqueue);
if (b < Q_OK) {
chEvtBroadcastI(&sdp->bac.oevent);
chEvtBroadcastI(&sdp->oevent);
return;
}
u->UART_THR = b;
@ -265,12 +265,12 @@ void sd_lld_init(void) {
#if USE_LPC214x_UART0
sdObjectInit(&SD1, NULL, notify1);
SD1.sd.uart = U0Base;
SD1.uart = U0Base;
SetVICVector(UART0IrqHandler, LPC214x_UART1_PRIORITY, SOURCE_UART0);
#endif
#if USE_LPC214x_UART1
sdObjectInit(&SD2, NULL, notify2);
SD2.sd.uart = U1Base;
SD2.uart = U1Base;
SetVICVector(UART1IrqHandler, LPC214x_UART2_PRIORITY, SOURCE_UART1);
#endif
}
@ -282,10 +282,10 @@ void sd_lld_init(void) {
*/
void sd_lld_start(SerialDriver *sdp) {
if (sdp->sd.config == NULL)
sdp->sd.config = &default_config;
if (sdp->config == NULL)
sdp->config = &default_config;
if (sdp->sd.state == SD_STOP) {
if (sdp->state == SD_STOP) {
#if USE_LPC214x_UART1
if (&SD1 == sdp) {
PCONP = (PCONP & PCALL) | PCUART0;
@ -311,8 +311,8 @@ void sd_lld_start(SerialDriver *sdp) {
*/
void sd_lld_stop(SerialDriver *sdp) {
if (sdp->sd.state == SD_READY) {
uart_deinit(sdp->sd.uart);
if (sdp->state == SD_READY) {
uart_deinit(sdp->uart);
#if USE_LPC214x_UART1
if (&SD1 == sdp) {
PCONP = (PCONP & PCALL) & ~PCUART0;

View File

@ -122,48 +122,27 @@ typedef struct {
/**
* @brief @p SerialDriver specific data.
*/
struct _serial_driver_data {
/**
* @brief Driver state.
*/
sdstate_t state;
/**
* @brief Current configuration data.
*/
const SerialConfig *config;
/**
* @brief Input queue, incoming data can be read from this input queue by
* using the queues APIs.
*/
InputQueue iqueue;
/**
* @brief Output queue, outgoing data can be written to this output queue by
* using the queues APIs.
*/
OutputQueue oqueue;
/**
* @brief Status Change @p EventSource. This event is generated when one or
* more condition flags change.
*/
EventSource sevent;
/**
* @brief I/O driver status flags.
*/
sdflags_t flags;
/**
* @brief Input circular buffer.
*/
uint8_t ib[SERIAL_BUFFERS_SIZE];
/**
* @brief Output circular buffer.
*/
uint8_t ob[SERIAL_BUFFERS_SIZE];
/* End of the mandatory fields.*/
/**
* @brief Pointer to the USART registers block.
*/
UART *uart;
};
#define _serial_driver_data \
_base_asynchronous_channel_data; \
/* Driver state.*/ \
sdstate_t state; \
/* Current configuration data.*/ \
const SerialConfig *config; \
/* Input queue.*/ \
InputQueue iqueue; \
/* Output queue.*/ \
OutputQueue oqueue; \
/* Status Change @p EventSource.*/ \
EventSource sevent; \
/* I/O driver status flags.*/ \
sdflags_t flags; \
/* Input circular buffer.*/ \
uint8_t ib[SERIAL_BUFFERS_SIZE]; \
/* Output circular buffer.*/ \
uint8_t ob[SERIAL_BUFFERS_SIZE]; \
/* End of the mandatory fields.*/ \
/* Pointer to the USART registers block.*/ \
UART *uart
/*===========================================================================*/
/* Driver macros. */

View File

@ -68,18 +68,18 @@ static void init(SerialDriver *sdp, uint16_t port) {
struct protoent *prtp;
if ((prtp = getprotobyname("tcp")) == NULL) {
printf("%s: Error mapping protocol name to protocol number\n", sdp->sd.com_name);
printf("%s: Error mapping protocol name to protocol number\n", sdp->com_name);
goto abort;
}
sdp->sd.com_listen = socket(PF_INET, SOCK_STREAM, prtp->p_proto);
if (sdp->sd.com_listen == INVALID_SOCKET) {
printf("%s: Error creating simulator socket\n", sdp->sd.com_name);
sdp->com_listen = socket(PF_INET, SOCK_STREAM, prtp->p_proto);
if (sdp->com_listen == INVALID_SOCKET) {
printf("%s: Error creating simulator socket\n", sdp->com_name);
goto abort;
}
if (ioctl(sdp->sd.com_listen, FIONBIO, &nb) != 0) {
printf("%s: Unable to setup non blocking mode on socket\n", sdp->sd.com_name);
if (ioctl(sdp->com_listen, FIONBIO, &nb) != 0) {
printf("%s: Unable to setup non blocking mode on socket\n", sdp->com_name);
goto abort;
}
@ -87,35 +87,35 @@ static void init(SerialDriver *sdp, uint16_t port) {
sad.sin_family = AF_INET;
sad.sin_addr.s_addr = INADDR_ANY;
sad.sin_port = htons(port);
if (bind(sdp->sd.com_listen, (struct sockaddr *)&sad, sizeof(sad))) {
printf("%s: Error binding socket\n", sdp->sd.com_name);
if (bind(sdp->com_listen, (struct sockaddr *)&sad, sizeof(sad))) {
printf("%s: Error binding socket\n", sdp->com_name);
goto abort;
}
if (listen(sdp->sd.com_listen, 1) != 0) {
printf("%s: Error listening socket\n", sdp->sd.com_name);
if (listen(sdp->com_listen, 1) != 0) {
printf("%s: Error listening socket\n", sdp->com_name);
goto abort;
}
printf("Full Duplex Channel %s listening on port %d\n", sdp->sd.com_name, port);
printf("Full Duplex Channel %s listening on port %d\n", sdp->com_name, port);
return;
abort:
if (sdp->sd.com_listen != INVALID_SOCKET)
close(sdp->sd.com_listen);
if (sdp->com_listen != INVALID_SOCKET)
close(sdp->com_listen);
exit(1);
}
static bool_t connint(SerialDriver *sdp) {
if (sdp->sd.com_data == INVALID_SOCKET) {
if (sdp->com_data == INVALID_SOCKET) {
struct sockaddr addr;
socklen_t addrlen = sizeof(addr);
if ((sdp->sd.com_data = accept(sdp->sd.com_listen, &addr, &addrlen)) == INVALID_SOCKET)
if ((sdp->com_data = accept(sdp->com_listen, &addr, &addrlen)) == INVALID_SOCKET)
return FALSE;
if (ioctl(sdp->sd.com_data, FIONBIO, &nb) != 0) {
printf("%s: Unable to setup non blocking mode on data socket\n", sdp->sd.com_name);
if (ioctl(sdp->com_data, FIONBIO, &nb) != 0) {
printf("%s: Unable to setup non blocking mode on data socket\n", sdp->com_name);
goto abort;
}
sdAddFlagsI(sdp, SD_CONNECTED);
@ -123,34 +123,34 @@ static bool_t connint(SerialDriver *sdp) {
}
return FALSE;
abort:
if (sdp->sd.com_listen != INVALID_SOCKET)
close(sdp->sd.com_listen);
if (sdp->sd.com_data != INVALID_SOCKET)
close(sdp->sd.com_data);
if (sdp->com_listen != INVALID_SOCKET)
close(sdp->com_listen);
if (sdp->com_data != INVALID_SOCKET)
close(sdp->com_data);
exit(1);
}
static bool_t inint(SerialDriver *sdp) {
if (sdp->sd.com_data != INVALID_SOCKET) {
if (sdp->com_data != INVALID_SOCKET) {
int i;
uint8_t data[32];
/*
* Input.
*/
int n = recv(sdp->sd.com_data, data, sizeof(data), 0);
int n = recv(sdp->com_data, data, sizeof(data), 0);
switch (n) {
case 0:
close(sdp->sd.com_data);
sdp->sd.com_data = INVALID_SOCKET;
close(sdp->com_data);
sdp->com_data = INVALID_SOCKET;
sdAddFlagsI(sdp, SD_DISCONNECTED);
return FALSE;
case INVALID_SOCKET:
if (errno == EWOULDBLOCK)
return FALSE;
close(sdp->sd.com_data);
sdp->sd.com_data = INVALID_SOCKET;
close(sdp->com_data);
sdp->com_data = INVALID_SOCKET;
return FALSE;
}
for (i = 0; i < n; i++)
@ -162,7 +162,7 @@ static bool_t inint(SerialDriver *sdp) {
static bool_t outint(SerialDriver *sdp) {
if (sdp->sd.com_data != INVALID_SOCKET) {
if (sdp->com_data != INVALID_SOCKET) {
int n;
uint8_t data[1];
@ -173,18 +173,18 @@ static bool_t outint(SerialDriver *sdp) {
if (n < 0)
return FALSE;
data[0] = (uint8_t)n;
n = send(sdp->sd.com_data, data, sizeof(data), 0);
n = send(sdp->com_data, data, sizeof(data), 0);
switch (n) {
case 0:
close(sdp->sd.com_data);
sdp->sd.com_data = INVALID_SOCKET;
close(sdp->com_data);
sdp->com_data = INVALID_SOCKET;
sdAddFlagsI(sdp, SD_DISCONNECTED);
return FALSE;
case INVALID_SOCKET:
if (errno == EWOULDBLOCK)
return FALSE;
close(sdp->sd.com_data);
sdp->sd.com_data = INVALID_SOCKET;
close(sdp->com_data);
sdp->com_data = INVALID_SOCKET;
return FALSE;
}
return TRUE;
@ -207,16 +207,16 @@ void sd_lld_init(void) {
#if USE_SIM_SERIAL1
sdObjectInit(&SD1, NULL, NULL);
SD1.sd.com_listen = INVALID_SOCKET;
SD1.sd.com_data = INVALID_SOCKET;
SD1.sd.com_name = "SD1";
SD1.com_listen = INVALID_SOCKET;
SD1.com_data = INVALID_SOCKET;
SD1.com_name = "SD1";
#endif
#if USE_SIM_SERIAL2
sdObjectInit(&SD2, NULL, NULL);
SD2.sd.com_listen = INVALID_SOCKET;
SD2.sd.com_data = INVALID_SOCKET;
SD2.sd.com_name = "SD2";
SD2.com_listen = INVALID_SOCKET;
SD2.com_data = INVALID_SOCKET;
SD2.com_name = "SD2";
#endif
}
@ -227,8 +227,8 @@ void sd_lld_init(void) {
*/
void sd_lld_start(SerialDriver *sdp) {
if (sdp->sd.config == NULL)
sdp->sd.config = &default_config;
if (sdp->config == NULL)
sdp->config = &default_config;
#if USE_SIM_SERIAL1
if (sdp == &SD1)

View File

@ -106,56 +106,31 @@ typedef struct {
/**
* @brief @p SerialDriver specific data.
*/
struct _serial_driver_data {
/**
* @brief Driver state.
*/
sdstate_t state;
/**
* @brief Current configuration data.
*/
const SerialConfig *config;
/**
* @brief Input queue, incoming data can be read from this input queue by
* using the queues APIs.
*/
InputQueue iqueue;
/**
* @brief Output queue, outgoing data can be written to this output queue by
* using the queues APIs.
*/
OutputQueue oqueue;
/**
* @brief Status Change @p EventSource. This event is generated when one or
* more condition flags change.
*/
EventSource sevent;
/**
* @brief I/O driver status flags.
*/
sdflags_t flags;
/**
* @brief Input circular buffer.
*/
uint8_t ib[SERIAL_BUFFERS_SIZE];
/**
* @brief Output circular buffer.
*/
uint8_t ob[SERIAL_BUFFERS_SIZE];
/* End of the mandatory fields.*/
/**
* Listen socket for simulated serial port.
*/
SOCKET com_listen;
/**
* Data socket for simulated serial port.
*/
SOCKET com_data;
/**
* Port readable name.
*/
const char *com_name;
};
#define _serial_driver_data \
_base_asynchronous_channel_data; \
/* Driver state.*/ \
sdstate_t state; \
/* Current configuration data.*/ \
const SerialConfig *config; \
/* Input queue.*/ \
InputQueue iqueue; \
/* Output queue.*/ \
OutputQueue oqueue; \
/* Status Change @p EventSource.*/ \
EventSource sevent; \
/* I/O driver status flags.*/ \
sdflags_t flags; \
/* Input circular buffer.*/ \
uint8_t ib[SERIAL_BUFFERS_SIZE]; \
/* Output circular buffer.*/ \
uint8_t ob[SERIAL_BUFFERS_SIZE]; \
/* End of the mandatory fields.*/ \
/* Listen socket for simulated serial port.*/ \
SOCKET com_listen; \
/* Data socket for simulated serial port.*/ \
SOCKET com_data; \
/* Port readable name.*/ \
const char *com_name
/*===========================================================================*/
/* Driver macros. */

View File

@ -260,18 +260,18 @@ void sd_lld_init(void) {
*/
void sd_lld_start(SerialDriver *sdp) {
if (sdp->sd.config == NULL)
sdp->sd.config = &default_config;
if (sdp->config == NULL)
sdp->config = &default_config;
#if USE_MSP430_USART0
if (&SD1 == sdp) {
usart0_init(sdp->sd.config);
usart0_init(sdp->config);
return;
}
#endif
#if USE_MSP430_USART1
if (&SD2 == sdp) {
usart1_init(sdp->sd.config);
usart1_init(sdp->config);
return;
}
#endif

View File

@ -91,44 +91,25 @@ typedef struct {
/**
* @brief @p SerialDriver specific data.
*/
struct _serial_driver_data {
/**
* @brief Driver state.
*/
sdstate_t state;
/**
* @brief Current configuration data.
*/
const SerialConfig *config;
/**
* @brief Input queue, incoming data can be read from this input queue by
* using the queues APIs.
*/
InputQueue iqueue;
/**
* @brief Output queue, outgoing data can be written to this output queue by
* using the queues APIs.
*/
OutputQueue oqueue;
/**
* @brief Status Change @p EventSource. This event is generated when one or
* more condition flags change.
*/
EventSource sevent;
/**
* @brief I/O driver status flags.
*/
sdflags_t flags;
/**
* @brief Input circular buffer.
*/
uint8_t ib[SERIAL_BUFFERS_SIZE];
/**
* @brief Output circular buffer.
*/
uint8_t ob[SERIAL_BUFFERS_SIZE];
#define _serial_driver_data \
_base_asynchronous_channel_data; \
/* Driver state.*/ \
sdstate_t state; \
/* Current configuration data.*/ \
const SerialConfig *config; \
/* Input queue.*/ \
InputQueue iqueue; \
/* Output queue.*/ \
OutputQueue oqueue; \
/* Status Change @p EventSource.*/ \
EventSource sevent; \
/* I/O driver status flags.*/ \
sdflags_t flags; \
/* Input circular buffer.*/ \
uint8_t ib[SERIAL_BUFFERS_SIZE]; \
/* Output circular buffer.*/ \
uint8_t ob[SERIAL_BUFFERS_SIZE]; \
/* End of the mandatory fields.*/
};
/*===========================================================================*/
/* Driver macros. */

View File

@ -72,24 +72,24 @@ static const SerialConfig default_config =
* @param[in] sdp pointer to a @p SerialDriver object
*/
static void usart_init(SerialDriver *sdp) {
USART_TypeDef *u = sdp->sd.usart;
USART_TypeDef *u = sdp->usart;
/*
* Baud rate setting.
*/
if (sdp->sd.usart == USART1)
u->BRR = APB2CLK / sdp->sd.config->sc_speed;
if (sdp->usart == USART1)
u->BRR = APB2CLK / sdp->config->sc_speed;
else
u->BRR = APB1CLK / sdp->sd.config->sc_speed;
u->BRR = APB1CLK / sdp->config->sc_speed;
/*
* Note that some bits are enforced.
*/
u->CR1 = sdp->sd.config->sc_cr1 | USART_CR1_UE | USART_CR1_PEIE |
u->CR1 = sdp->config->sc_cr1 | USART_CR1_UE | USART_CR1_PEIE |
USART_CR1_RXNEIE | USART_CR1_TE |
USART_CR1_RE;
u->CR2 = sdp->sd.config->sc_cr2 | USART_CR2_LBDIE;
u->CR3 = sdp->sd.config->sc_cr3 | USART_CR3_EIE;
u->CR2 = sdp->config->sc_cr2 | USART_CR2_LBDIE;
u->CR3 = sdp->config->sc_cr3 | USART_CR3_EIE;
(void)u->SR; /* SR reset step 1.*/
(void)u->DR; /* SR reset step 2.*/
}
@ -137,7 +137,7 @@ static void set_error(SerialDriver *sdp, uint16_t sr) {
* @param[in] sdp communication channel associated to the USART
*/
static void serve_interrupt(SerialDriver *sdp) {
USART_TypeDef *u = sdp->sd.usart;
USART_TypeDef *u = sdp->usart;
uint16_t cr1 = u->CR1;
uint16_t sr = u->SR; /* SR reset step 1.*/
uint16_t dr = u->DR; /* SR reset step 2.*/
@ -155,9 +155,9 @@ static void serve_interrupt(SerialDriver *sdp) {
if ((cr1 & USART_CR1_TXEIE) && (sr & USART_SR_TXE)) {
msg_t b;
chSysLockFromIsr();
b = chOQGetI(&sdp->sd.oqueue);
b = chOQGetI(&sdp->oqueue);
if (b < Q_OK) {
chEvtBroadcastI(&sdp->bac.oevent);
chEvtBroadcastI(&sdp->oevent);
u->CR1 = cr1 & ~USART_CR1_TXEIE;
}
else
@ -235,17 +235,17 @@ void sd_lld_init(void) {
#if USE_STM32_USART1
sdObjectInit(&SD1, NULL, notify1);
SD1.sd.usart = USART1;
SD1.usart = USART1;
#endif
#if USE_STM32_USART2
sdObjectInit(&SD2, NULL, notify2);
SD2.sd.usart = USART2;
SD2.usart = USART2;
#endif
#if USE_STM32_USART3
sdObjectInit(&SD3, NULL, notify3);
SD3.sd.usart = USART3;
SD3.usart = USART3;
#endif
}
@ -256,10 +256,10 @@ void sd_lld_init(void) {
*/
void sd_lld_start(SerialDriver *sdp) {
if (sdp->sd.config == NULL)
sdp->sd.config = &default_config;
if (sdp->config == NULL)
sdp->config = &default_config;
if (sdp->sd.state == SD_STOP) {
if (sdp->state == SD_STOP) {
#if USE_STM32_USART1
if (&SD1 == sdp) {
RCC->APB2ENR |= RCC_APB2ENR_USART1EN;
@ -291,8 +291,8 @@ void sd_lld_start(SerialDriver *sdp) {
*/
void sd_lld_stop(SerialDriver *sdp) {
if (sdp->sd.state == SD_READY) {
usart_deinit(sdp->sd.usart);
if (sdp->state == SD_READY) {
usart_deinit(sdp->usart);
#if USE_STM32_USART1
if (&SD1 == sdp) {
RCC->APB2ENR &= ~RCC_APB2ENR_USART1EN;

View File

@ -132,48 +132,27 @@ typedef struct {
/**
* @brief @p SerialDriver specific data.
*/
struct _serial_driver_data {
/**
* @brief Driver state.
*/
sdstate_t state;
/**
* @brief Current configuration data.
*/
const SerialConfig *config;
/**
* @brief Input queue, incoming data can be read from this input queue by
* using the queues APIs.
*/
InputQueue iqueue;
/**
* @brief Output queue, outgoing data can be written to this output queue by
* using the queues APIs.
*/
OutputQueue oqueue;
/**
* @brief Status Change @p EventSource. This event is generated when one or
* more condition flags change.
*/
EventSource sevent;
/**
* @brief I/O driver status flags.
*/
sdflags_t flags;
/**
* @brief Input circular buffer.
*/
uint8_t ib[SERIAL_BUFFERS_SIZE];
/**
* @brief Output circular buffer.
*/
uint8_t ob[SERIAL_BUFFERS_SIZE];
/* End of the mandatory fields.*/
/**
* @brief Pointer to the USART registers block.
*/
USART_TypeDef *usart;
};
#define _serial_driver_data \
_base_asynchronous_channel_data; \
/* Driver state.*/ \
sdstate_t state; \
/* Current configuration data.*/ \
const SerialConfig *config; \
/* Input queue.*/ \
InputQueue iqueue; \
/* Output queue.*/ \
OutputQueue oqueue; \
/* Status Change @p EventSource.*/ \
EventSource sevent; \
/* I/O driver status flags.*/ \
sdflags_t flags; \
/* Input circular buffer.*/ \
uint8_t ib[SERIAL_BUFFERS_SIZE]; \
/* Output circular buffer.*/ \
uint8_t ob[SERIAL_BUFFERS_SIZE]; \
/* End of the mandatory fields.*/ \
/* Pointer to the USART registers block.*/ \
USART_TypeDef *usart
/*===========================================================================*/
/* Driver macros. */

View File

@ -61,18 +61,18 @@ static void init(SerialDriver *sdp, uint16_t port) {
struct protoent *prtp;
if ((prtp = getprotobyname("tcp")) == NULL) {
printf("%s: Error mapping protocol name to protocol number\n", sdp->sd.com_name);
printf("%s: Error mapping protocol name to protocol number\n", sdp->com_name);
goto abort;
}
sdp->sd.com_listen = socket(PF_INET, SOCK_STREAM, prtp->p_proto);
if (sdp->sd.com_listen == INVALID_SOCKET) {
printf("%s: Error creating simulator socket\n", sdp->sd.com_name);
sdp->com_listen = socket(PF_INET, SOCK_STREAM, prtp->p_proto);
if (sdp->com_listen == INVALID_SOCKET) {
printf("%s: Error creating simulator socket\n", sdp->com_name);
goto abort;
}
if (ioctlsocket(sdp->sd.com_listen, FIONBIO, &nb) != 0) {
printf("%s: Unable to setup non blocking mode on socket\n", sdp->sd.com_name);
if (ioctlsocket(sdp->com_listen, FIONBIO, &nb) != 0) {
printf("%s: Unable to setup non blocking mode on socket\n", sdp->com_name);
goto abort;
}
@ -80,36 +80,36 @@ static void init(SerialDriver *sdp, uint16_t port) {
sad.sin_family = AF_INET;
sad.sin_addr.s_addr = INADDR_ANY;
sad.sin_port = htons(port);
if (bind(sdp->sd.com_listen, (struct sockaddr *)&sad, sizeof(sad))) {
printf("%s: Error binding socket\n", sdp->sd.com_name);
if (bind(sdp->com_listen, (struct sockaddr *)&sad, sizeof(sad))) {
printf("%s: Error binding socket\n", sdp->com_name);
goto abort;
}
if (listen(sdp->sd.com_listen, 1) != 0) {
printf("%s: Error listening socket\n", sdp->sd.com_name);
if (listen(sdp->com_listen, 1) != 0) {
printf("%s: Error listening socket\n", sdp->com_name);
goto abort;
}
printf("Full Duplex Channel %s listening on port %d\n", sdp->sd.com_name, port);
printf("Full Duplex Channel %s listening on port %d\n", sdp->com_name, port);
return;
abort:
if (sdp->sd.com_listen != INVALID_SOCKET)
closesocket(sdp->sd.com_listen);
if (sdp->com_listen != INVALID_SOCKET)
closesocket(sdp->com_listen);
WSACleanup();
exit(1);
}
static bool_t connint(SerialDriver *sdp) {
if (sdp->sd.com_data == INVALID_SOCKET) {
if (sdp->com_data == INVALID_SOCKET) {
struct sockaddr addr;
int addrlen = sizeof(addr);
if ((sdp->sd.com_data = accept(sdp->sd.com_listen, &addr, &addrlen)) == INVALID_SOCKET)
if ((sdp->com_data = accept(sdp->com_listen, &addr, &addrlen)) == INVALID_SOCKET)
return FALSE;
if (ioctlsocket(sdp->sd.com_data, FIONBIO, &nb) != 0) {
printf("%s: Unable to setup non blocking mode on data socket\n", sdp->sd.com_name);
if (ioctlsocket(sdp->com_data, FIONBIO, &nb) != 0) {
printf("%s: Unable to setup non blocking mode on data socket\n", sdp->com_name);
goto abort;
}
sdAddFlagsI(sdp, SD_CONNECTED);
@ -117,35 +117,35 @@ static bool_t connint(SerialDriver *sdp) {
}
return FALSE;
abort:
if (sdp->sd.com_listen != INVALID_SOCKET)
closesocket(sdp->sd.com_listen);
if (sdp->sd.com_data != INVALID_SOCKET)
closesocket(sdp->sd.com_data);
if (sdp->com_listen != INVALID_SOCKET)
closesocket(sdp->com_listen);
if (sdp->com_data != INVALID_SOCKET)
closesocket(sdp->com_data);
WSACleanup();
exit(1);
}
static bool_t inint(SerialDriver *sdp) {
if (sdp->sd.com_data != INVALID_SOCKET) {
if (sdp->com_data != INVALID_SOCKET) {
int i;
uint8_t data[32];
/*
* Input.
*/
int n = recv(sdp->sd.com_data, data, sizeof(data), 0);
int n = recv(sdp->com_data, data, sizeof(data), 0);
switch (n) {
case 0:
closesocket(sdp->sd.com_data);
sdp->sd.com_data = INVALID_SOCKET;
closesocket(sdp->com_data);
sdp->com_data = INVALID_SOCKET;
sdAddFlagsI(sdp, SD_DISCONNECTED);
return FALSE;
case SOCKET_ERROR:
if (WSAGetLastError() == WSAEWOULDBLOCK)
return FALSE;
closesocket(sdp->sd.com_data);
sdp->sd.com_data = INVALID_SOCKET;
closesocket(sdp->com_data);
sdp->com_data = INVALID_SOCKET;
return FALSE;
}
for (i = 0; i < n; i++)
@ -157,7 +157,7 @@ static bool_t inint(SerialDriver *sdp) {
static bool_t outint(SerialDriver *sdp) {
if (sdp->sd.com_data != INVALID_SOCKET) {
if (sdp->com_data != INVALID_SOCKET) {
int n;
uint8_t data[1];
@ -168,18 +168,18 @@ static bool_t outint(SerialDriver *sdp) {
if (n < 0)
return FALSE;
data[0] = (uint8_t)n;
n = send(sdp->sd.com_data, data, sizeof(data), 0);
n = send(sdp->com_data, data, sizeof(data), 0);
switch (n) {
case 0:
closesocket(sdp->sd.com_data);
sdp->sd.com_data = INVALID_SOCKET;
closesocket(sdp->com_data);
sdp->com_data = INVALID_SOCKET;
sdAddFlagsI(sdp, SD_DISCONNECTED);
return FALSE;
case SOCKET_ERROR:
if (WSAGetLastError() == WSAEWOULDBLOCK)
return FALSE;
closesocket(sdp->sd.com_data);
sdp->sd.com_data = INVALID_SOCKET;
closesocket(sdp->com_data);
sdp->com_data = INVALID_SOCKET;
return FALSE;
}
return TRUE;
@ -202,16 +202,16 @@ void sd_lld_init(void) {
#if USE_WIN32_SERIAL1
sdObjectInit(&SD1, NULL, NULL);
SD1.sd.com_listen = INVALID_SOCKET;
SD1.sd.com_data = INVALID_SOCKET;
SD1.sd.com_name = "SD1";
SD1.com_listen = INVALID_SOCKET;
SD1.com_data = INVALID_SOCKET;
SD1.com_name = "SD1";
#endif
#if USE_WIN32_SERIAL1
sdObjectInit(&SD2, NULL, NULL);
SD2.sd.com_listen = INVALID_SOCKET;
SD2.sd.com_data = INVALID_SOCKET;
SD2.sd.com_name = "SD2";
SD2.com_listen = INVALID_SOCKET;
SD2.com_data = INVALID_SOCKET;
SD2.com_name = "SD2";
#endif
}
@ -222,8 +222,8 @@ void sd_lld_init(void) {
*/
void sd_lld_start(SerialDriver *sdp) {
if (sdp->sd.config == NULL)
sdp->sd.config = &default_config;
if (sdp->config == NULL)
sdp->config = &default_config;
#if USE_WIN32_SERIAL1
if (sdp == &SD1)

View File

@ -102,56 +102,31 @@ typedef struct {
/**
* @brief @p SerialDriver specific data.
*/
struct _serial_driver_data {
/**
* @brief Driver state.
*/
sdstate_t state;
/**
* @brief Current configuration data.
*/
const SerialConfig *config;
/**
* @brief Input queue, incoming data can be read from this input queue by
* using the queues APIs.
*/
InputQueue iqueue;
/**
* @brief Output queue, outgoing data can be written to this output queue by
* using the queues APIs.
*/
OutputQueue oqueue;
/**
* @brief Status Change @p EventSource. This event is generated when one or
* more condition flags change.
*/
EventSource sevent;
/**
* @brief I/O driver status flags.
*/
sdflags_t flags;
/**
* @brief Input circular buffer.
*/
uint8_t ib[SERIAL_BUFFERS_SIZE];
/**
* @brief Output circular buffer.
*/
uint8_t ob[SERIAL_BUFFERS_SIZE];
/* End of the mandatory fields.*/
/**
* Listen socket for simulated serial port.
*/
SOCKET com_listen;
/**
* Data socket for simulated serial port.
*/
SOCKET com_data;
/**
* Port readable name.
*/
const char *com_name;
};
#define _serial_driver_data \
_base_asynchronous_channel_data; \
/* Driver state.*/ \
sdstate_t state; \
/* Current configuration data.*/ \
const SerialConfig *config; \
/* Input queue.*/ \
InputQueue iqueue; \
/* Output queue.*/ \
OutputQueue oqueue; \
/* Status Change @p EventSource.*/ \
EventSource sevent; \
/* I/O driver status flags.*/ \
sdflags_t flags; \
/* Input circular buffer.*/ \
uint8_t ib[SERIAL_BUFFERS_SIZE]; \
/* Output circular buffer.*/ \
uint8_t ob[SERIAL_BUFFERS_SIZE]; \
/* End of the mandatory fields.*/ \
/* Listen socket for simulated serial port.*/ \
SOCKET com_listen; \
/* Data socket for simulated serial port.*/ \
SOCKET com_data; \
/* Port readable name.*/ \
const char *com_name
/*===========================================================================*/
/* External declarations. */

View File

@ -48,50 +48,48 @@
static size_t writes(void *ip, const uint8_t *bp, size_t n) {
return chOQWriteTimeout(&((SerialDriver *)ip)->sd.oqueue, bp,
return chOQWriteTimeout(&((SerialDriver *)ip)->oqueue, bp,
n, TIME_INFINITE);
}
static size_t reads(void *ip, uint8_t *bp, size_t n) {
return chIQReadTimeout(&((SerialDriver *)ip)->sd.iqueue, bp,
return chIQReadTimeout(&((SerialDriver *)ip)->iqueue, bp,
n, TIME_INFINITE);
}
static bool_t putwouldblock(void *ip) {
return chOQIsFull(&((SerialDriver *)ip)->sd.oqueue);
return chOQIsFull(&((SerialDriver *)ip)->oqueue);
}
static bool_t getwouldblock(void *ip) {
return chIQIsEmpty(&((SerialDriver *)ip)->sd.iqueue);
return chIQIsEmpty(&((SerialDriver *)ip)->iqueue);
}
static msg_t putt(void *ip, uint8_t b, systime_t timeout) {
return chOQPutTimeout(&((SerialDriver *)ip)->sd.oqueue, b, timeout);
return chOQPutTimeout(&((SerialDriver *)ip)->oqueue, b, timeout);
}
static msg_t gett(void *ip, systime_t timeout) {
return chIQGetTimeout(&((SerialDriver *)ip)->sd.iqueue, timeout);
return chIQGetTimeout(&((SerialDriver *)ip)->iqueue, timeout);
}
static size_t writet(void *ip, const uint8_t *bp, size_t n, systime_t time) {
return chOQWriteTimeout(&((SerialDriver *)ip)->sd.oqueue, bp, n, time);
return chOQWriteTimeout(&((SerialDriver *)ip)->oqueue, bp, n, time);
}
static size_t readt(void *ip, uint8_t *bp, size_t n, systime_t time) {
return chIQReadTimeout(&((SerialDriver *)ip)->sd.iqueue, bp, n, time);
return chIQReadTimeout(&((SerialDriver *)ip)->iqueue, bp, n, time);
}
static const struct SerialDriverVMT vmt = {
{writes, reads},
{putwouldblock, getwouldblock, putt, gett, writet, readt},
{}
writes, reads, putwouldblock, getwouldblock, putt, gett, writet, readt
};
/*===========================================================================*/
@ -122,13 +120,13 @@ void sdInit(void) {
void sdObjectInit(SerialDriver *sdp, qnotify_t inotify, qnotify_t onotify) {
sdp->vmt = &vmt;
chEvtInit(&sdp->bac.ievent);
chEvtInit(&sdp->bac.oevent);
chEvtInit(&sdp->sd.sevent);
sdp->sd.state = SD_STOP;
sdp->sd.flags = SD_NO_ERROR;
chIQInit(&sdp->sd.iqueue, sdp->sd.ib, SERIAL_BUFFERS_SIZE, inotify);
chOQInit(&sdp->sd.oqueue, sdp->sd.ob, SERIAL_BUFFERS_SIZE, onotify);
chEvtInit(&sdp->ievent);
chEvtInit(&sdp->oevent);
chEvtInit(&sdp->sevent);
sdp->state = SD_STOP;
sdp->flags = SD_NO_ERROR;
chIQInit(&sdp->iqueue, sdp->ib, SERIAL_BUFFERS_SIZE, inotify);
chOQInit(&sdp->oqueue, sdp->ob, SERIAL_BUFFERS_SIZE, onotify);
}
/**
@ -144,12 +142,12 @@ void sdStart(SerialDriver *sdp, const SerialConfig *config) {
chDbgCheck(sdp != NULL, "sdStart");
chSysLock();
chDbgAssert((sdp->sd.state == SD_STOP) || (sdp->sd.state == SD_READY),
chDbgAssert((sdp->state == SD_STOP) || (sdp->state == SD_READY),
"sdStart(), #1",
"invalid state");
sdp->sd.config = config;
sdp->config = config;
sd_lld_start(sdp);
sdp->sd.state = SD_READY;
sdp->state = SD_READY;
chSysUnlock();
}
@ -165,13 +163,13 @@ void sdStop(SerialDriver *sdp) {
chDbgCheck(sdp != NULL, "sdStop");
chSysLock();
chDbgAssert((sdp->sd.state == SD_STOP) || (sdp->sd.state == SD_READY),
chDbgAssert((sdp->state == SD_STOP) || (sdp->state == SD_READY),
"sdStop(), #1",
"invalid state");
sd_lld_stop(sdp);
sdp->sd.state = SD_STOP;
chOQResetI(&sdp->sd.oqueue);
chIQResetI(&sdp->sd.iqueue);
sdp->state = SD_STOP;
chOQResetI(&sdp->oqueue);
chIQResetI(&sdp->iqueue);
chSchRescheduleS();
chSysUnlock();
}
@ -194,9 +192,9 @@ void sdIncomingDataI(SerialDriver *sdp, uint8_t b) {
chDbgCheck(sdp != NULL, "sdIncomingDataI");
if (chIQIsEmpty(&sdp->sd.iqueue))
chEvtBroadcastI(&sdp->bac.ievent);
if (chIQPutI(&sdp->sd.iqueue, b) < Q_OK)
if (chIQIsEmpty(&sdp->iqueue))
chEvtBroadcastI(&sdp->ievent);
if (chIQPutI(&sdp->iqueue, b) < Q_OK)
sdAddFlagsI(sdp, SD_OVERRUN_ERROR);
}
@ -217,9 +215,9 @@ msg_t sdRequestDataI(SerialDriver *sdp) {
chDbgCheck(sdp != NULL, "sdRequestDataI");
msg_t b = chOQGetI(&sdp->sd.oqueue);
msg_t b = chOQGetI(&sdp->oqueue);
if (b < Q_OK)
chEvtBroadcastI(&sdp->bac.oevent);
chEvtBroadcastI(&sdp->oevent);
return b;
}
@ -235,8 +233,8 @@ void sdAddFlagsI(SerialDriver *sdp, sdflags_t mask) {
chDbgCheck(sdp != NULL, "sdAddFlagsI");
sdp->sd.flags |= mask;
chEvtBroadcastI(&sdp->sd.sevent);
sdp->flags |= mask;
chEvtBroadcastI(&sdp->sevent);
}
/**
@ -252,8 +250,8 @@ sdflags_t sdGetAndClearFlags(SerialDriver *sdp) {
chDbgCheck(sdp != NULL, "sdGetAndClearFlags");
chSysLock();
mask = sdp->sd.flags;
sdp->sd.flags = SD_NO_ERROR;
mask = sdp->flags;
sdp->flags = SD_NO_ERROR;
chSysUnlock();
return mask;
}

View File

@ -67,8 +67,8 @@ void sd_lld_init(void) {
*/
void sd_lld_start(SerialDriver *sdp) {
if (sdp->sd.config == NULL)
sdp->sd.config = &default_config;
if (sdp->config == NULL)
sdp->config = &default_config;
}

View File

@ -66,44 +66,25 @@ typedef struct {
/**
* @brief @p SerialDriver specific data.
*/
struct _serial_driver_data {
/**
* @brief Driver state.
*/
sdstate_t state;
/**
* @brief Current configuration data.
*/
const SerialConfig *config;
/**
* @brief Input queue, incoming data can be read from this input queue by
* using the queues APIs.
*/
InputQueue iqueue;
/**
* @brief Output queue, outgoing data can be written to this output queue by
* using the queues APIs.
*/
OutputQueue oqueue;
/**
* @brief Status Change @p EventSource. This event is generated when one or
* more condition flags change.
*/
EventSource sevent;
/**
* @brief I/O driver status flags.
*/
sdflags_t flags;
/**
* @brief Input circular buffer.
*/
uint8_t ib[SERIAL_BUFFERS_SIZE];
/**
* @brief Output circular buffer.
*/
uint8_t ob[SERIAL_BUFFERS_SIZE];
#define _serial_driver_data \
_base_asynchronous_channel_data; \
/* Driver state.*/ \
sdstate_t state; \
/* Current configuration data.*/ \
const SerialConfig *config; \
/* Input queue.*/ \
InputQueue iqueue; \
/* Output queue.*/ \
OutputQueue oqueue; \
/* Status Change @p EventSource.*/ \
EventSource sevent; \
/* I/O driver status flags.*/ \
sdflags_t flags; \
/* Input circular buffer.*/ \
uint8_t ib[SERIAL_BUFFERS_SIZE]; \
/* Output circular buffer.*/ \
uint8_t ob[SERIAL_BUFFERS_SIZE]; \
/* End of the mandatory fields.*/
};
/*===========================================================================*/
/* Driver macros. */

View File

@ -30,59 +30,29 @@
/**
* @brief @p BaseChannel specific methods.
*/
struct _base_channel_methods {
/**
* @brief Channel output check.
* @see chIOPutWouldBlock()
*/
bool_t (*putwouldblock)(void *instance);
/**
* @brief Channel input check.
* @see chIOGetWouldBlock()
*/
bool_t (*getwouldblock)(void *instance);
/**
* @brief Channel put method with timeout specification.
* @see chIOPut()
*/
msg_t (*put)(void *instance, uint8_t b, systime_t time);
/**
* @brief Channel get method with timeout specification.
* @see chIOGet()
*/
msg_t (*get)(void *instance, systime_t time);
/**
* @brief Channel write method with timeout specification.
* @see chIOWrite()
*/
size_t (*write)(void *instance, const uint8_t *bp, size_t n, systime_t time);
/**
* @brief Channel read method with timeout specification.
* @see chIORead()
*/
size_t (*read)(void *instance, uint8_t *bp, size_t n, systime_t time);
};
#define _base_channel_methods \
_base_sequental_stream_methods; \
bool_t (*putwouldblock)(void *instance); \
bool_t (*getwouldblock)(void *instance); \
msg_t (*put)(void *instance, uint8_t b, systime_t time); \
msg_t (*get)(void *instance, systime_t time); \
size_t (*writet)(void *instance, const uint8_t *bp, \
size_t n, systime_t time); \
size_t (*readt)(void *instance, uint8_t *bp, size_t n, systime_t time)
/**
* @brief @p BaseChannel specific data.
* @note It is empty because @p BaseChannel is only an interface without
* implementation.
*/
struct _base_channel_data {
};
#define _base_channel_data \
_base_sequental_stream_data
/**
* @brief @p BaseChannel virtual methods table.
*/
struct BaseChannelVMT {
/**
* @p BaseSequentialStream class inherited methods.
*/
struct _base_sequental_stream_methods bss;
/**
* @p BaseChannel class specific methods.
*/
struct _base_channel_methods bc;
struct BaseChannelVMT { \
_base_channel_methods; \
};
/**
@ -97,14 +67,7 @@ typedef struct {
* Virtual Methods Table.
*/
const struct BaseChannelVMT *vmt;
/**
* @p BaseSequentialStream class inherited data.
*/
struct _base_sequental_stream_data bss;
/**
* @p BaseChannel class specific data.
*/
struct _base_channel_data bc;
_base_channel_data;
} BaseChannel;
/**
@ -118,7 +81,7 @@ typedef struct {
* operation.
* @retval TRUE if the output queue is full and would block a write operation.
*/
#define chIOPutWouldBlock(ip) ((ip)->vmt->bc.putwouldblock(ip))
#define chIOPutWouldBlock(ip) ((ip)->vmt->putwouldblock(ip))
/**
* @brief Channel input check.
@ -131,7 +94,7 @@ typedef struct {
* operation.
* @retval TRUE if the input queue is empty and would block a read operation.
*/
#define chIOGetWouldBlock(ip) ((ip)->vmt->bc.getwouldblock(ip))
#define chIOGetWouldBlock(ip) ((ip)->vmt->getwouldblock(ip))
/**
* @brief Channel blocking byte write.
@ -144,7 +107,7 @@ typedef struct {
* @retval Q_OK if the operation succeeded.
* @retval Q_RESET if the channel associated queue (if any) was reset.
*/
#define chIOPut(ip, b) ((ip)->vmt->bc.put(ip, b, TIME_INFINITE))
#define chIOPut(ip, b) ((ip)->vmt->put(ip, b, TIME_INFINITE))
/**
* @brief Channel blocking byte write with timeout.
@ -163,7 +126,7 @@ typedef struct {
* @retval Q_TIMEOUT if the specified time expired.
* @retval Q_RESET if the channel associated queue (if any) was reset.
*/
#define chIOPutTimeout(ip, b, time) ((ip)->vmt->bc.put(ip, b, time))
#define chIOPutTimeout(ip, b, time) ((ip)->vmt->put(ip, b, time))
/**
* @brief Channel blocking byte read.
@ -174,7 +137,7 @@ typedef struct {
* @return A byte value from the queue or:
* @retval Q_RESET if the channel associated queue (if any) was reset.
*/
#define chIOGet(ip) ((ip)->vmt->bc.get(ip, TIME_INFINITE))
#define chIOGet(ip) ((ip)->vmt->get(ip, TIME_INFINITE))
/**
* @brief Channel blocking byte read with timeout.
@ -191,7 +154,7 @@ typedef struct {
* @retval Q_TIMEOUT if the specified time expired.
* @retval Q_RESET if the channel associated queue (if any) was reset.
*/
#define chIOGetTimeout(ip, time) ((ip)->vmt->bc.get(ip, time))
#define chIOGetTimeout(ip, time) ((ip)->vmt->get(ip, time))
/**
* @brief Channel blocking write with timeout.
@ -209,7 +172,7 @@ typedef struct {
* @return The number of bytes transferred.
*/
#define chIOWriteTimeout(ip, bp, n, time) \
((ip)->vmt->bac.write(ip, bp, n, time))
((ip)->vmt->write(ip, bp, n, time))
/**
* @brief Channel blocking read with timeout.
@ -227,47 +190,28 @@ typedef struct {
* @return The number of bytes transferred.
*/
#define chIOReadTimeout(ip, bp, n, time) \
((ip)->vmt->bac.read(ip, bp, n, time))
((ip)->vmt->read(ip, bp, n, time))
#if CH_USE_EVENTS
/**
* @brief @p BaseAsynchronousChannel specific methods.
*/
struct _base_asynchronous_channel_methods {
};
#define _base_asynchronous_channel_methods \
_base_channel_methods
/**
* @brief @p BaseAsynchronousChannel specific data.
*/
struct _base_asynchronous_channel_data {
/**
* Data Available @p EventSource. This event is generated when some incoming
* data is inserted in the input queue.
*/
EventSource ievent;
/**
* Data Transmitted @p EventSource. This event is generated when the
* output queue is empty.
*/
EventSource oevent;
};
#define _base_asynchronous_channel_data \
_base_channel_data; \
EventSource ievent; \
EventSource oevent
/**
* @brief @p BaseAsynchronousChannel virtual methods table.
*/
struct BaseAsynchronousChannelVMT {
/**
* @p BaseSequentialStream class inherited methods.
*/
struct _base_sequental_stream_methods bss;
/**
* @p BaseChannel class inherited methods.
*/
struct _base_channel_methods bc;
/**
* @p BaseAsynchronousChannel class specific methods.
*/
struct _base_asynchronous_channel_methods bac;
_base_asynchronous_channel_methods;
};
/**
@ -282,18 +226,7 @@ typedef struct {
* Virtual Methods Table.
*/
const struct BaseAsynchronousChannelVMT *vmt;
/**
* @p BaseSequentialStream class inherited data.
*/
struct _base_sequental_stream_data bss;
/**
* @p BaseChannel class inherited data.
*/
struct _base_channel_data bc;
/**
* @p BaseAsynchronousChannel class specific data.
*/
struct _base_asynchronous_channel_data bac;
_base_asynchronous_channel_data;
} BaseAsynchronousChannel;
/**
@ -304,7 +237,7 @@ typedef struct {
* @param[in] ip pointer to a @p BaseAsynchronousChannel or derived class
* @return A pointer to an @p EventSource object.
*/
#define chIOGetWriteEventSource(ip) (&((ip)->vmt->bac.oevent))
#define chIOGetWriteEventSource(ip) (&((ip)->vmt->oevent))
/**
* @brief Returns the read event source.
@ -314,7 +247,7 @@ typedef struct {
* @param[in] ip pointer to a @p BaseAsynchronousChannel or derived class
* @return A pointer to an @p EventSource object.
*/
#define chIOGetReadEventSource(ip) (&((ip)->vmt->bac.ievent))
#define chIOGetReadEventSource(ip) (&((ip)->vmt->ievent))
#endif /* CH_USE_EVENTS */

View File

@ -30,33 +30,22 @@
/**
* @brief BaseSequentialStream specific methods.
*/
struct _base_sequental_stream_methods {
/**
* @brief Stream write buffer method.
*/
size_t (*write)(void *instance, const uint8_t *bp, size_t n);
/**
* @brief Stream read buffer method.
*/
size_t (*read)(void *instance, uint8_t *bp, size_t n);
};
#define _base_sequental_stream_methods \
size_t (*write)(void *instance, const uint8_t *bp, size_t n); \
size_t (*read)(void *instance, uint8_t *bp, size_t n)
/**
* @brief @p BaseSequentialStream specific data.
* @note It is empty because @p BaseSequentialStream is only an interface
* without implementation.
*/
struct _base_sequental_stream_data {
};
#define _base_sequental_stream_data
/**
* @brief @p BaseSequentialStream virtual methods table.
*/
struct BaseSequentialStreamVMT {
/**
* @p BaseSequentialStream class specific methods.
*/
struct _base_sequental_stream_methods bss;
_base_sequental_stream_methods;
};
/**
@ -69,10 +58,7 @@ typedef struct {
* Virtual Methods Table.
*/
const struct BaseSequentialStreamVMT *vmt;
/**
* @p BaseSequentialStream class specific data.
*/
struct _base_sequental_stream_data bss;
_base_sequental_stream_data;
} BaseSequentialStream;
/**
@ -86,7 +72,7 @@ typedef struct {
* than the specified number of bytes if the stream reaches a
* physical end of file and cannot be extended.
*/
#define chSequentialStreamWrite(ip, bp, n) ((ip)->vmt->bss.write(ip, bp, n))
#define chSequentialStreamWrite(ip, bp, n) ((ip)->vmt->write(ip, bp, n))
/**
* @brief Sequential Stream read.
@ -99,7 +85,7 @@ typedef struct {
* than the specified number of bytes if the stream reaches the end
* of the available data.
*/
#define chSequentialStreamRead(ip, bp, n) ((ip)->vmt->bss.read(ip, bp, n))
#define chSequentialStreamRead(ip, bp, n) ((ip)->vmt->read(ip, bp, n))
#endif /* _STREAMS_H_ */

View File

@ -52,12 +52,13 @@
*****************************************************************************
*** 1.5.0 ***
- FIX: Fixed parameter check in sdStart() function (bug 2932922)(backported
in 1.4.0).
- FIX: Fixed parameter check in sdStart() function (bug 2932922)(backported in
1.4.0).
- FIX: Fixed missing platform.mk file in MSP430 port (bug 2933735)(backported
in 1.4.0).
- CHANGE: Removed the unnamed union from the Thread structure some compilers
do not support this non standard construct.
- CHANGE: Removed the empty structures from the streams/channels headers.
- CHANGE: Modified the thread-related constant macros to have a THD_ prefix.
- OPT: Speed/size optimization to the events subsystem.
- OPT: Speed/size optimization to the mutexes subsystem.