git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1539 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
11a6a2bf64
commit
11215c3bcb
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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. */
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
|
@ -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_ */
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in New Issue