216 lines
6.3 KiB
C
216 lines
6.3 KiB
C
/*
|
|
ChibiOS - Copyright (C) 2006..2018 Giovanni Di Sirio
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
/**
|
|
* @file hal_buffered_sio.c
|
|
* @brief Buffered SIO Driver code.
|
|
*
|
|
* @addtogroup HAL_BUFFERED_SIO
|
|
* @{
|
|
*/
|
|
|
|
#include "hal.h"
|
|
|
|
#if (HAL_USE_SIO == TRUE) || defined(__DOXYGEN__)
|
|
|
|
#include "hal_buffered_sio.h"
|
|
|
|
/*===========================================================================*/
|
|
/* Driver local definitions. */
|
|
/*===========================================================================*/
|
|
|
|
/*===========================================================================*/
|
|
/* Driver exported variables. */
|
|
/*===========================================================================*/
|
|
|
|
/*===========================================================================*/
|
|
/* Driver local variables and types. */
|
|
/*===========================================================================*/
|
|
|
|
static void bs_default_cb(SIODriver *siop);
|
|
static const SIOOperation bs_default_operation = {
|
|
.cb = bs_default_cb
|
|
};
|
|
|
|
/*===========================================================================*/
|
|
/* Driver local functions. */
|
|
/*===========================================================================*/
|
|
|
|
static void bs_default_cb(SIODriver *siop) {
|
|
|
|
(void)siop;
|
|
}
|
|
|
|
/*
|
|
* Interface implementation.
|
|
*/
|
|
static size_t _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) {
|
|
|
|
return __buffered_serial_read_impl(ip, bp, n);
|
|
}
|
|
|
|
static msg_t _put(void *ip, uint8_t b) {
|
|
|
|
return __buffered_serial_put_impl(ip, b);
|
|
}
|
|
|
|
static msg_t _get(void *ip) {
|
|
|
|
return __buffered_serial_get_impl(ip);
|
|
}
|
|
|
|
static msg_t _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) {
|
|
|
|
return __buffered_serial_get_timeout_impl(ip, timeout);
|
|
}
|
|
|
|
static size_t _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) {
|
|
|
|
return __buffered_serial_read_timeout_impl(ip, bp, n, timeout);
|
|
}
|
|
|
|
static msg_t _ctl(void *ip, unsigned int operation, void *arg) {
|
|
|
|
/* TODO call SIO control first.*/
|
|
return __buffered_serial_ctl_impl(ip, operation, arg);
|
|
}
|
|
|
|
static const struct BufferedSIODriverVMT vmt = {
|
|
(size_t)0,
|
|
_write, _read, _put, _get,
|
|
_putt, _gett, _writet, _readt,
|
|
_ctl
|
|
};
|
|
|
|
/*===========================================================================*/
|
|
/* Driver exported functions. */
|
|
/*===========================================================================*/
|
|
|
|
/**
|
|
* @brief Initializes a generic serial driver object.
|
|
* @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[in] siop pointer to the @p SIODriver object
|
|
* @param[in] ib pointer to the input buffer
|
|
* @param[in] ibsize size of the input buffer
|
|
* @param[in] ob pointer to the output buffer
|
|
* @param[in] obsize size of the output buffer
|
|
*
|
|
* @init
|
|
*/
|
|
void bsdObjectInit(BufferedSIODriver *bsdp, SIODriver *siop,
|
|
uint8_t *ib, size_t ibsize,
|
|
uint8_t *ob, size_t obsize) {
|
|
|
|
__buffered_serial_objinit_impl((void *)bsdp, (const void *)&vmt,
|
|
ib, ibsize, NULL, NULL,
|
|
ob, obsize, NULL, NULL);
|
|
bsdp->siop = siop;
|
|
}
|
|
|
|
/**
|
|
* @brief Configures and starts the driver.
|
|
*
|
|
* @param[out] bsdp 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.
|
|
* @return The operation status.
|
|
*
|
|
* @api
|
|
*/
|
|
msg_t bsdStart(BufferedSIODriver *bsdp, const BufferedSIOConfig *config) {
|
|
msg_t msg;
|
|
|
|
osalDbgCheck(bsdp != NULL);
|
|
|
|
osalDbgAssert((bsdp->state == BS_STOP) || (bsdp->state == BS_READY),
|
|
"invalid state");
|
|
|
|
/* Stopping current operation, if any.*/
|
|
if (bsdp->siop->state == SIO_ACTIVE) {
|
|
sioStopOperation(bsdp->siop);
|
|
}
|
|
|
|
msg = sioStart(bsdp->siop, config);
|
|
if (msg == HAL_RET_SUCCESS) {
|
|
osalSysLock();
|
|
sioStartOperationI(bsdp->siop, &bs_default_operation);
|
|
sioWriteEnableFlagsI(bsdp->siop, SIO_FL_ALL);
|
|
bsdp->state = BS_READY;
|
|
osalSysUnlock();
|
|
}
|
|
else {
|
|
bsdp->state = BS_STOP;
|
|
}
|
|
|
|
return msg;
|
|
}
|
|
|
|
/**
|
|
* @brief Stops the driver.
|
|
* @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
|
|
*
|
|
* @api
|
|
*/
|
|
void bsdStop(BufferedSIODriver *bsdp) {
|
|
|
|
osalDbgCheck(bsdp != NULL);
|
|
|
|
osalDbgAssert((bsdp->state == BS_STOP) || (bsdp->state == BS_READY),
|
|
"invalid state");
|
|
|
|
/* Stopping current operation, if any.*/
|
|
sioStopOperation(bsdp->siop);
|
|
|
|
/* Stopping undelying SIO driver.*/
|
|
sioStop(bsdp->siop);
|
|
|
|
bsdp->state = BS_STOP;
|
|
|
|
osalSysLock();
|
|
oqResetI(&bsdp->oqueue); /* TODO should go in the upper class.*/
|
|
iqResetI(&bsdp->iqueue);
|
|
osalOsRescheduleS();
|
|
osalSysUnlock();
|
|
}
|
|
|
|
#endif /* HAL_USE_SIO == TRUE */
|
|
|
|
/** @} */
|