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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -52,12 +52,13 @@
***************************************************************************** *****************************************************************************
*** 1.5.0 *** *** 1.5.0 ***
- FIX: Fixed parameter check in sdStart() function (bug 2932922)(backported - FIX: Fixed parameter check in sdStart() function (bug 2932922)(backported in
in 1.4.0). 1.4.0).
- FIX: Fixed missing platform.mk file in MSP430 port (bug 2933735)(backported - FIX: Fixed missing platform.mk file in MSP430 port (bug 2933735)(backported
in 1.4.0). in 1.4.0).
- CHANGE: Removed the unnamed union from the Thread structure some compilers - CHANGE: Removed the unnamed union from the Thread structure some compilers
do not support this non standard construct. 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. - 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 events subsystem.
- OPT: Speed/size optimization to the mutexes subsystem. - OPT: Speed/size optimization to the mutexes subsystem.