Buffered SIO complete, to be tested.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15725 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
Giovanni Di Sirio 2022-08-15 07:12:38 +00:00
parent 878e717a9c
commit 4fddf58480
7 changed files with 113 additions and 101 deletions

View File

@ -113,6 +113,10 @@
* @details Peripheral failed, for example HW timeouts.
*/
#define HAL_RET_HW_FAILURE (msg_t)-19
/**
* @brief Unknown control code.
*/
#define HAL_RET_UNKNOWN_CTL (msg_t)-20
/** @} */
/*===========================================================================*/

View File

@ -245,18 +245,12 @@ static inline msg_t __buffered_serial_ctl_impl(void *ip,
osalDbgCheck(arg == NULL);
break;
case CHN_CTL_INVALID:
osalDbgAssert(false, "invalid CTL operation");
break;
return HAL_RET_UNKNOWN_CTL;
default:
#if defined(SD_LLD_IMPLEMENTS_CTL)
/* Delegating to the LLD if supported.*/
return sd_lld_control(bsp, operation, arg);
#else
break;
#endif
return HAL_RET_UNKNOWN_CTL;
}
return MSG_OK;
return HAL_RET_SUCCESS;
}
/** @} */

View File

@ -127,7 +127,7 @@
* @name Additional messages
* @{
*/
#define SIO_MSG_ERRORS 1
#define SIO_MSG_ERRORS 1
/** @} */
/*===========================================================================*/

View File

@ -40,17 +40,40 @@
/* Driver local variables and types. */
/*===========================================================================*/
static void bs_default_cb(SIODriver *siop);
static const SIOOperation bs_default_operation = {
.cb = bs_default_cb
static void __bsio_default_cb(SIODriver *siop);
static const SIOOperation __bsio_default_operation = {
.cb = __bsio_default_cb
};
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
static void bs_default_cb(SIODriver *siop) {
BufferedSIODriver *bsdp = (BufferedSIODriver *)siop->arg;
static void __bsio_push_data(BufferedSIODriver *bsiop) {
while (!sioIsTXFullX(bsiop->siop)) {
msg_t msg;
msg = oqGetI(&bsiop->oqueue);
if (msg < MSG_OK) {
chnAddFlagsI((BufferedSerial *)bsiop, CHN_OUTPUT_EMPTY);
return;
}
sioPutX(bsiop->siop, (uint_fast16_t)msg);
}
}
static void __bsio_pop_data(BufferedSIODriver *bsiop) {
/* RX FIFO needs to be fully emptied or SIO will not generate more RX FIFO
events.*/
while (!sioIsRXEmptyX(bsiop->siop)) {
bsIncomingDataI((BufferedSerial *)bsiop, sioGetX(bsiop->siop));
}
}
static void __bsio_default_cb(SIODriver *siop) {
BufferedSIODriver *bsiop = (BufferedSIODriver *)siop->arg;
sioevents_t events;
osalSysLockFromISR();
@ -58,90 +81,83 @@ static void bs_default_cb(SIODriver *siop) {
/* Posting the non-data SIO events as channel event flags, the masks are
made to match.*/
events = sioGetAndClearEventsI(siop);
chnAddFlagsI(bsdp, (eventflags_t)(events & ~SIO_EV_ALL_DATA));
chnAddFlagsI(bsiop, (eventflags_t)(events & ~SIO_EV_ALL_DATA));
/* RX FIFO event.*/
if ((events & SIO_EV_RXNOTEMPY) != (sioevents_t)0) {
/* RX FIFO needs to be emptied or SIO will not generate more RX FIFO
events.*/
while (!sioIsRXEmptyX(siop)) {
bsIncomingDataI((BufferedSerial *)bsdp, sioGetX(siop));
}
__bsio_pop_data(bsiop);
}
/* TX FIFO event.*/
if ((events & SIO_EV_TXNOTFULL) != (sioevents_t)0) {
while (!sioIsTXFullX(siop)) {
msg_t msg;
msg = oqGetI(&bsdp->oqueue);
if (msg < MSG_OK) {
chnAddFlagsI((BufferedSerial *)bsdp, CHN_OUTPUT_EMPTY);
break;
}
sioPutX(siop, (uint_fast16_t)msg);
}
__bsio_push_data(bsiop);
}
osalSysUnlockFromISR();
}
static void __bsio_onotify(io_queue_t *qp) {
__bsio_push_data((BufferedSIODriver *)qp->q_link);
}
/*
* Interface implementation.
*/
static size_t _write(void *ip, const uint8_t *bp, size_t n) {
static size_t __bsio_write(void *ip, const uint8_t *bp, size_t n) {
return __buffered_serial_write_impl(ip, bp, n);
}
static size_t _read(void *ip, uint8_t *bp, size_t n) {
static size_t __bsio_read(void *ip, uint8_t *bp, size_t n) {
return __buffered_serial_read_impl(ip, bp, n);
}
static msg_t _put(void *ip, uint8_t b) {
static msg_t __bsio_put(void *ip, uint8_t b) {
return __buffered_serial_put_impl(ip, b);
}
static msg_t _get(void *ip) {
static msg_t __bsio_get(void *ip) {
return __buffered_serial_get_impl(ip);
}
static msg_t _putt(void *ip, uint8_t b, sysinterval_t timeout) {
static msg_t __bsio_putt(void *ip, uint8_t b, sysinterval_t timeout) {
return __buffered_serial_put_timeout_impl(ip, b, timeout);
}
static msg_t _gett(void *ip, sysinterval_t timeout) {
static msg_t __bsio_gett(void *ip, sysinterval_t timeout) {
return __buffered_serial_get_timeout_impl(ip, timeout);
}
static size_t _writet(void *ip, const uint8_t *bp, size_t n,
sysinterval_t timeout) {
static size_t __bsio_writet(void *ip, const uint8_t *bp, size_t n,
sysinterval_t timeout) {
return __buffered_serial_write_timeout_impl(ip, bp, n, timeout);
}
static size_t _readt(void *ip, uint8_t *bp, size_t n,
sysinterval_t timeout) {
static size_t __bsio_readt(void *ip, uint8_t *bp, size_t n,
sysinterval_t timeout) {
return __buffered_serial_read_timeout_impl(ip, bp, n, timeout);
}
static msg_t _ctl(void *ip, unsigned int operation, void *arg) {
static msg_t __bsio_ctl(void *ip, unsigned int operation, void *arg) {
/* TODO call SIO control first.*/
return __buffered_serial_ctl_impl(ip, operation, arg);
return sioControlX(((BufferedSIODriver *)ip)->siop, operation, arg);
}
static const struct BufferedSIODriverVMT vmt = {
(size_t)0,
_write, _read, _put, _get,
_putt, _gett, _writet, _readt,
_ctl
__bsio_write, __bsio_read, __bsio_put, __bsio_get,
__bsio_putt, __bsio_gett, __bsio_writet, __bsio_readt,
__bsio_ctl
};
/*===========================================================================*/
@ -153,7 +169,7 @@ static const struct BufferedSIODriverVMT vmt = {
* @details The HW dependent part of the initialization has to be performed
* outside, usually in the hardware initialization code.
*
* @param[out] bsdp pointer to a @p BufferedSIODriver structure
* @param[out] bsiop pointer to a @p BufferedSIODriver structure
* @param[in] siop pointer to the @p SIODriver object
* @param[in] ib pointer to the input buffer
* @param[in] ibsize size of the input buffer
@ -162,21 +178,21 @@ static const struct BufferedSIODriverVMT vmt = {
*
* @init
*/
void bsdObjectInit(BufferedSIODriver *bsdp, SIODriver *siop,
void bsioObjectInit(BufferedSIODriver *bsiop, SIODriver *siop,
uint8_t *ib, size_t ibsize,
uint8_t *ob, size_t obsize) {
__buffered_serial_objinit_impl((void *)bsdp, (const void *)&vmt,
__buffered_serial_objinit_impl((void *)bsiop, (const void *)&vmt,
ib, ibsize, NULL, NULL,
ob, obsize, NULL, NULL);
bsdp->siop = siop;
siop->arg = (void *)bsdp;
ob, obsize, __bsio_onotify, (void *)bsiop);
bsiop->siop = siop;
siop->arg = (void *)bsiop;
}
/**
* @brief Configures and starts the driver.
*
* @param[out] bsdp pointer to a @p BufferedSIODriver structure
* @param[out] bsiop pointer to a @p BufferedSIODriver structure
* @param[in] config the architecture-dependent serial driver configuration.
* If this parameter is set to @p NULL then a default
* configuration is used.
@ -184,29 +200,29 @@ void bsdObjectInit(BufferedSIODriver *bsdp, SIODriver *siop,
*
* @api
*/
msg_t bsdStart(BufferedSIODriver *bsdp, const BufferedSIOConfig *config) {
msg_t bsioStart(BufferedSIODriver *bsiop, const BufferedSIOConfig *config) {
msg_t msg;
osalDbgCheck(bsdp != NULL);
osalDbgCheck(bsiop != NULL);
osalDbgAssert((bsdp->state == BS_STOP) || (bsdp->state == BS_READY),
osalDbgAssert((bsiop->state == BS_STOP) || (bsiop->state == BS_READY),
"invalid state");
/* Stopping current operation, if any.*/
if (bsdp->siop->state == SIO_ACTIVE) {
sioStopOperation(bsdp->siop);
if (bsiop->siop->state == SIO_ACTIVE) {
sioStopOperation(bsiop->siop);
}
msg = sioStart(bsdp->siop, config);
msg = sioStart(bsiop->siop, config);
if (msg == HAL_RET_SUCCESS) {
osalSysLock();
sioStartOperationI(bsdp->siop, &bs_default_operation);
sioWriteEnableFlagsI(bsdp->siop, SIO_FL_ALL);
bsdp->state = BS_READY;
sioStartOperationI(bsiop->siop, &__bsio_default_operation);
sioWriteEnableFlagsI(bsiop->siop, SIO_FL_ALL);
bsiop->state = BS_READY;
osalSysUnlock();
}
else {
bsdp->state = BS_STOP;
bsiop->state = BS_STOP;
}
return msg;
@ -217,28 +233,28 @@ msg_t bsdStart(BufferedSIODriver *bsdp, const BufferedSIOConfig *config) {
* @details Any thread waiting on the driver's queues will be awakened with
* the message @p MSG_RESET.
*
* @param[out] bsdp pointer to a @p BufferedSIODriver structure
* @param[out] bsiop pointer to a @p BufferedSIODriver structure
*
* @api
*/
void bsdStop(BufferedSIODriver *bsdp) {
void bsioStop(BufferedSIODriver *bsiop) {
osalDbgCheck(bsdp != NULL);
osalDbgCheck(bsiop != NULL);
osalDbgAssert((bsdp->state == BS_STOP) || (bsdp->state == BS_READY),
osalDbgAssert((bsiop->state == BS_STOP) || (bsiop->state == BS_READY),
"invalid state");
/* Stopping current operation, if any.*/
sioStopOperation(bsdp->siop);
sioStopOperation(bsiop->siop);
/* Stopping undelying SIO driver.*/
sioStop(bsdp->siop);
sioStop(bsiop->siop);
bsdp->state = BS_STOP;
bsiop->state = BS_STOP;
osalSysLock();
oqResetI(&bsdp->oqueue); /* TODO should go in the upper class.*/
iqResetI(&bsdp->iqueue);
oqResetI(&bsiop->oqueue); /* TODO should go in the upper class.*/
iqResetI(&bsiop->iqueue);
osalOsRescheduleS();
osalSysUnlock();
}

View File

@ -99,7 +99,7 @@ typedef SIOConfig BufferedSIOConfig;
*
* @iclass
*/
#define bsdPutI(bsdp, b) oqPutI(&(bsdp)->oqueue, b)
#define bsioPutI(bsiop, b) oqPutI(&(bsiop)->oqueue, b)
/**
* @brief Direct write to a @p BufferedSIODriver.
@ -109,7 +109,7 @@ typedef SIOConfig BufferedSIOConfig;
*
* @api
*/
#define bsdPut(bsdp, b) oqPut(&(bsdp)->oqueue, b)
#define bsioPut(bsiop, b) oqPut(&(bsiop)->oqueue, b)
/**
* @brief Direct write to a @p BufferedSIODriver with timeout specification.
@ -119,7 +119,7 @@ typedef SIOConfig BufferedSIOConfig;
*
* @api
*/
#define bsdPutTimeout(bsdp, b, t) oqPutTimeout(&(bsdp)->oqueue, b, t)
#define bsioPutTimeout(bsiop, b, t) oqPutTimeout(&(bsiop)->oqueue, b, t)
/**
* @brief Direct read from a @p BufferedSIODriver.
@ -129,7 +129,7 @@ typedef SIOConfig BufferedSIOConfig;
*
* @iclass
*/
#define bsdGetI(bsdp) iqGetI(&(bsdp)->iqueue)
#define bsioGetI(bsiop) iqGetI(&(bsiop)->iqueue)
/**
* @brief Direct read from a @p BufferedSIODriver.
@ -139,7 +139,7 @@ typedef SIOConfig BufferedSIOConfig;
*
* @api
*/
#define bsdGet(bsdp) iqGet(&(bsdp)->iqueue)
#define bsioGet(bsiop) iqGet(&(bsiop)->iqueue)
/**
* @brief Direct read from a @p BufferedSIODriver with timeout specification.
@ -149,7 +149,7 @@ typedef SIOConfig BufferedSIOConfig;
*
* @api
*/
#define bsdGetTimeout(bsdp, t) iqGetTimeout(&(bsdp)->iqueue, t)
#define bsioGetTimeout(bsiop, t) iqGetTimeout(&(bsiop)->iqueue, t)
/**
* @brief Direct blocking write to a @p BufferedSIODriver.
@ -159,7 +159,7 @@ typedef SIOConfig BufferedSIOConfig;
*
* @iclass
*/
#define bsdWriteI(bsdp, b, n) oqWriteI(&(bsdp)->oqueue, b, n)
#define bsioWriteI(bsiop, b, n) oqWriteI(&(bsiop)->oqueue, b, n)
/**
* @brief Direct blocking write to a @p BufferedSIODriver.
@ -169,7 +169,7 @@ typedef SIOConfig BufferedSIOConfig;
*
* @api
*/
#define bsdWrite(bsdp, b, n) oqWriteTimeout(&(bsdp)->oqueue, b, n, TIME_INFINITE)
#define bsioWrite(bsiop, b, n) oqWriteTimeout(&(bsiop)->oqueue, b, n, TIME_INFINITE)
/**
* @brief Direct blocking write to a @p BufferedSIODriver with timeout
@ -180,8 +180,8 @@ typedef SIOConfig BufferedSIOConfig;
*
* @api
*/
#define bsdWriteTimeout(bsdp, b, n, t) \
oqWriteTimeout(&(bsdp)->oqueue, b, n, t)
#define bsioWriteTimeout(bsiop, b, n, t) \
oqWriteTimeout(&(bsiop)->oqueue, b, n, t)
/**
* @brief Direct non-blocking write to a @p BufferedSIODriver.
@ -191,8 +191,8 @@ typedef SIOConfig BufferedSIOConfig;
*
* @api
*/
#define bsdAsynchronousWrite(bsdp, b, n) \
oqWriteTimeout(&(bsdp)->oqueue, b, n, TIME_IMMEDIATE)
#define bsioAsynchronousWrite(bsiop, b, n) \
oqWriteTimeout(&(bsiop)->oqueue, b, n, TIME_IMMEDIATE)
/**
* @brief Direct blocking read from a @p BufferedSIODriver.
@ -202,7 +202,7 @@ typedef SIOConfig BufferedSIOConfig;
*
* @iclass
*/
#define bsdReadI(bsdp, b, n) iqReadI(&(bsdp)->iqueue, b, n, TIME_INFINITE)
#define bsioReadI(bsiop, b, n) iqReadI(&(bsiop)->iqueue, b, n, TIME_INFINITE)
/**
* @brief Direct blocking read from a @p BufferedSIODriver.
@ -212,7 +212,7 @@ typedef SIOConfig BufferedSIOConfig;
*
* @api
*/
#define bsdRead(bsdp, b, n) iqReadTimeout(&(bsdp)->iqueue, b, n, TIME_INFINITE)
#define bsioRead(bsiop, b, n) iqReadTimeout(&(bsiop)->iqueue, b, n, TIME_INFINITE)
/**
* @brief Direct blocking read from a @p BufferedSIODriver with timeout
@ -223,7 +223,7 @@ typedef SIOConfig BufferedSIOConfig;
*
* @api
*/
#define bsdReadTimeout(bsdp, b, n, t) iqReadTimeout(&(bsdp)->iqueue, b, n, t)
#define bsioReadTimeout(bsiop, b, n, t) iqReadTimeout(&(bsiop)->iqueue, b, n, t)
/**
* @brief Direct non-blocking read from a @p BufferedSIODriver.
@ -233,8 +233,8 @@ typedef SIOConfig BufferedSIOConfig;
*
* @api
*/
#define bsdAsynchronousRead(bsdp, b, n) \
iqReadTimeout(&(bsdp)->iqueue, b, n, TIME_IMMEDIATE)
#define bsioAsynchronousRead(bsiop, b, n) \
iqReadTimeout(&(bsiop)->iqueue, b, n, TIME_IMMEDIATE)
/** @} */
/*===========================================================================*/
@ -244,11 +244,11 @@ typedef SIOConfig BufferedSIOConfig;
#ifdef __cplusplus
extern "C" {
#endif
void bsdObjectInit(BufferedSIODriver *bsdp, SIODriver *siop,
uint8_t *ib, size_t ibsize,
uint8_t *ob, size_t obsize);
msg_t bsdStart(BufferedSIODriver *bsdp, const BufferedSIOConfig *config);
void bsdStop(BufferedSIODriver *bsdp);
void bsioObjectInit(BufferedSIODriver *bsiop, SIODriver *siop,
uint8_t *ib, size_t ibsize,
uint8_t *ob, size_t obsize);
msg_t bsioStart(BufferedSIODriver *bsiop, const BufferedSIOConfig *config);
void bsioStop(BufferedSIODriver *bsiop);
#ifdef __cplusplus
}
#endif

View File

@ -101,17 +101,16 @@ static msg_t _ctl(void *ip, unsigned int operation, void *arg) {
osalDbgCheck(arg == NULL);
break;
case CHN_CTL_INVALID:
osalDbgAssert(false, "invalid CTL operation");
break;
return HAL_RET_UNKNOWN_CTL;
default:
#if defined(SD_LLD_IMPLEMENTS_CTL)
/* Delegating to the LLD if supported.*/
return sd_lld_control(sdp, operation, arg);
#else
break;
return HAL_RET_UNKNOWN_CTL;
#endif
}
return MSG_OK;
return HAL_RET_SUCCESS;
}
static const struct SerialDriverVMT vmt = {

View File

@ -178,13 +178,12 @@ static msg_t __ctl(void *ip, unsigned int operation, void *arg) {
osalDbgCheck(arg == NULL);
break;
case CHN_CTL_INVALID:
osalDbgAssert(false, "invalid CTL operation");
break;
return HAL_RET_UNKNOWN_CTL;
default:
/* Delegating to the LLD if supported.*/
return sio_lld_control(siop, operation, arg);
}
return MSG_OK;
return HAL_RET_SUCCESS;
}
static const struct sio_driver_vmt vmt = {