VUART and virtualized SIO tentative implementations, untested.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15736 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
parent
fe01e7759f
commit
bb4ca5e19c
|
@ -85,6 +85,7 @@ static inline uint32_t __sio_vuart_deinit(uint32_t nvuart) {
|
|||
#if !defined(SB_VUART1_SUPPRESS_ISR)
|
||||
OSAL_IRQ_HANDLER(MK_VECTOR(SB_SIO_VUART1_IRQ)) {
|
||||
|
||||
sio_lld_serve_interrupt(&SIOD1);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@ -93,6 +94,7 @@ OSAL_IRQ_HANDLER(MK_VECTOR(SB_SIO_VUART1_IRQ)) {
|
|||
#if !defined(SB_VUART2_SUPPRESS_ISR)
|
||||
OSAL_IRQ_HANDLER(MK_VECTOR(SB_SIO_VUART2_IRQ)) {
|
||||
|
||||
sio_lld_serve_interrupt(&SIOD2);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
@ -171,6 +173,7 @@ msg_t sio_lld_start(SIODriver *siop) {
|
|||
* @notapi
|
||||
*/
|
||||
void sio_lld_stop(SIODriver *siop) {
|
||||
msg_t msg = HAL_RET_SUCCESS;
|
||||
|
||||
if (siop->state == SIO_READY) {
|
||||
/* Disables the peripheral.*/
|
||||
|
@ -178,18 +181,20 @@ void sio_lld_stop(SIODriver *siop) {
|
|||
}
|
||||
#if SB_SIO_USE_VUART1 == TRUE
|
||||
else if (&SIOD1 == siop) {
|
||||
(void) __sio_vuart_deinit(siop->nvuart);
|
||||
msg = __sio_vuart_deinit(siop->nvuart);
|
||||
}
|
||||
#endif
|
||||
#if SB_SIO_USE_VUART2 == TRUE
|
||||
else if (&SIOD2 == siop) {
|
||||
(void) __sio_vuart_deinit(siop->nvuart);
|
||||
msg = __sio_vuart_deinit(siop->nvuart);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
osalDbgAssert(false, "invalid SIO instance");
|
||||
}
|
||||
}
|
||||
|
||||
osalDbgAssert(msg = HAL_RET_SUCCESS, "unexpected failure");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -199,8 +204,9 @@ void sio_lld_stop(SIODriver *siop) {
|
|||
*/
|
||||
void sio_lld_update_enable_flags(SIODriver *siop) {
|
||||
|
||||
(void)siop;
|
||||
}
|
||||
__syscall3r(201, SB_VUART_WREN, siop->nvuart, siop->enabled);
|
||||
osalDbgAssert((msg_t)r0 == HAL_RET_SUCCESS, "unexpected failure");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get and clears SIO error event flags.
|
||||
|
@ -211,11 +217,11 @@ void sio_lld_update_enable_flags(SIODriver *siop) {
|
|||
* @notapi
|
||||
*/
|
||||
sioevents_t sio_lld_get_and_clear_errors(SIODriver *siop) {
|
||||
sioevents_t errors = (sioevents_t)0;
|
||||
|
||||
(void)siop;
|
||||
__syscall2r(201, SB_VUART_GCERR, siop->nvuart);
|
||||
osalDbgAssert((msg_t)r0 == HAL_RET_SUCCESS, "unexpected failure");
|
||||
|
||||
return errors;
|
||||
return (sioevents_t)r1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -227,11 +233,11 @@ sioevents_t sio_lld_get_and_clear_errors(SIODriver *siop) {
|
|||
* @notapi
|
||||
*/
|
||||
sioevents_t sio_lld_get_and_clear_events(SIODriver *siop) {
|
||||
sioevents_t events = (sioevents_t)0;
|
||||
|
||||
(void)siop;
|
||||
__syscall2r(201, SB_VUART_GCEVT, siop->nvuart);
|
||||
osalDbgAssert((msg_t)r0 == HAL_RET_SUCCESS, "unexpected failure");
|
||||
|
||||
return events;
|
||||
return (sioevents_t)r1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -246,13 +252,11 @@ sioevents_t sio_lld_get_and_clear_events(SIODriver *siop) {
|
|||
* @retval 0 if the TX FIFO is full.
|
||||
*/
|
||||
size_t sio_lld_read(SIODriver *siop, uint8_t *buffer, size_t n) {
|
||||
// size_t rd;
|
||||
|
||||
(void)siop;
|
||||
(void)buffer;
|
||||
(void)n;
|
||||
__syscall4rr(201, SB_VUART_READ, siop->nvuart, buffer, n);
|
||||
osalDbgAssert((msg_t)r0 == HAL_RET_SUCCESS, "unexpected failure");
|
||||
|
||||
return 0;//rd;
|
||||
return (size_t)r1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -267,13 +271,11 @@ size_t sio_lld_read(SIODriver *siop, uint8_t *buffer, size_t n) {
|
|||
* @retval 0 if the TX FIFO is full.
|
||||
*/
|
||||
size_t sio_lld_write(SIODriver *siop, const uint8_t *buffer, size_t n) {
|
||||
// size_t wr;
|
||||
|
||||
(void)siop;
|
||||
(void)buffer;
|
||||
(void)n;
|
||||
__syscall4rr(201, SB_VUART_WRITE, siop->nvuart, buffer, n);
|
||||
osalDbgAssert((msg_t)r0 == HAL_RET_SUCCESS, "unexpected failure");
|
||||
|
||||
return 0;//wr;
|
||||
return (size_t)r1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -286,11 +288,11 @@ size_t sio_lld_write(SIODriver *siop, const uint8_t *buffer, size_t n) {
|
|||
* @notapi
|
||||
*/
|
||||
msg_t sio_lld_get(SIODriver *siop) {
|
||||
// msg_t msg;
|
||||
|
||||
(void)siop;
|
||||
__syscall2rr(201, SB_VUART_GET, siop->nvuart);
|
||||
osalDbgAssert((msg_t)r0 == HAL_RET_SUCCESS, "unexpected failure");
|
||||
|
||||
return 0;//msg;
|
||||
return (size_t)r1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -304,8 +306,8 @@ msg_t sio_lld_get(SIODriver *siop) {
|
|||
*/
|
||||
void sio_lld_put(SIODriver *siop, uint_fast16_t data) {
|
||||
|
||||
(void)siop;
|
||||
(void)data;
|
||||
__syscall3r(201, SB_VUART_PUT, siop->nvuart, data);
|
||||
osalDbgAssert((msg_t)r0 == HAL_RET_SUCCESS, "unexpected failure");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -324,11 +326,10 @@ void sio_lld_put(SIODriver *siop, uint_fast16_t data) {
|
|||
*/
|
||||
msg_t sio_lld_control(SIODriver *siop, unsigned int operation, void *arg) {
|
||||
|
||||
(void)siop;
|
||||
(void)operation;
|
||||
(void)arg;
|
||||
__syscall4rr(201, SB_VUART_CTL, siop->nvuart, operation, arg);
|
||||
osalDbgAssert((msg_t)r0 == HAL_RET_SUCCESS, "unexpected failure");
|
||||
|
||||
return MSG_OK;
|
||||
return (size_t)r1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -340,7 +341,9 @@ msg_t sio_lld_control(SIODriver *siop, unsigned int operation, void *arg) {
|
|||
*/
|
||||
void sio_lld_serve_interrupt(SIODriver *siop) {
|
||||
|
||||
(void)siop;
|
||||
/* The callback is simply invoked. Letting the driver on the host side
|
||||
decide how to manipulate IRQ sources.*/
|
||||
__sio_callback(siop);
|
||||
}
|
||||
|
||||
#endif /* HAL_USE_SIO == TRUE */
|
||||
|
|
|
@ -49,7 +49,8 @@
|
|||
#define SB_SYSC_EVENT_WAIT_ALL 10
|
||||
#define SB_SYSC_EVENT_BROADCAST 11
|
||||
#define SB_SYSC_LOADELF 12
|
||||
#define SB_SYSC_VHAL_PAL 200
|
||||
#define SB_SYSC_VHAL_VGPIO 200
|
||||
#define SB_SYSC_VHAL_VUART 201
|
||||
#define SB_SYSC_VRQ_SET_ALARM 245
|
||||
#define SB_SYSC_VRQ_RESET_ALARM 246
|
||||
#define SB_SYSC_VRQ_WAIT 247
|
||||
|
@ -104,8 +105,14 @@
|
|||
*/
|
||||
#define SB_VUART_INIT 0
|
||||
#define SB_VUART_DEINIT 1
|
||||
#define SB_VUART_WRITE 2
|
||||
#define SB_VUART_READ 3
|
||||
#define SB_VUART_READ 2
|
||||
#define SB_VUART_WRITE 3
|
||||
#define SB_VUART_GET 4
|
||||
#define SB_VUART_PUT 5
|
||||
#define SB_VUART_WREN 6
|
||||
#define SB_VUART_GCERR 7
|
||||
#define SB_VUART_GCEVT 8
|
||||
#define SB_VUART_CTL 9
|
||||
/** @} */
|
||||
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -166,21 +166,51 @@ typedef uint32_t eventflags_t;
|
|||
register uint32_t r0 asm ("r0"); \
|
||||
asm volatile ("svc " #x : "=r" (r0) : : "memory")
|
||||
|
||||
#define __syscall0rr(x) \
|
||||
register uint32_t r0 asm ("r0"); \
|
||||
register uint32_t r0 asm ("r1"); \
|
||||
asm volatile ("svc " #x : "=r" (r0), "=r" (r1) : : "memory")
|
||||
|
||||
#define __syscall1r(x, p1) \
|
||||
register uint32_t r0 asm ("r0") = (uint32_t)(p1); \
|
||||
asm volatile ("svc " #x : "=r" (r0) : "r" (r0) : "memory")
|
||||
|
||||
#define __syscall1rr(x, p1) \
|
||||
register uint32_t r0 asm ("r0") = (uint32_t)(p1); \
|
||||
register uint32_t r0 asm ("r1"); \
|
||||
asm volatile ("svc " #x : "=r" (r0), "=r" (r1) : \
|
||||
"r" (r0) : \
|
||||
"memory")
|
||||
|
||||
#define __syscall2r(x, p1, p2) \
|
||||
register uint32_t r0 asm ("r0") = (uint32_t)(p1); \
|
||||
register uint32_t r1 asm ("r1") = (uint32_t)(p2); \
|
||||
asm volatile ("svc " #x : "=r" (r0) : "r" (r0), "r" (r1) : "memory")
|
||||
asm volatile ("svc " #x : "=r" (r0) : \
|
||||
"r" (r0), "r" (r1) : \
|
||||
"memory")
|
||||
|
||||
#define __syscall2rr(x, p1, p2) \
|
||||
register uint32_t r0 asm ("r0") = (uint32_t)(p1); \
|
||||
register uint32_t r1 asm ("r1") = (uint32_t)(p2); \
|
||||
asm volatile ("svc " #x : "=r" (r0), "=r" (r1) : \
|
||||
"r" (r0), "r" (r1) : \
|
||||
"memory")
|
||||
|
||||
#define __syscall3r(x, p1, p2, p3) \
|
||||
register uint32_t r0 asm ("r0") = (uint32_t)(p1); \
|
||||
register uint32_t r1 asm ("r1") = (uint32_t)(p2); \
|
||||
register uint32_t r2 asm ("r2") = (uint32_t)(p3); \
|
||||
asm volatile ("svc " #x : "=r" (r0) : "r" (r0), "r" (r1), \
|
||||
"r" (r2) : "memory")
|
||||
"r" (r2) : \
|
||||
"memory")
|
||||
|
||||
#define __syscall3rr(x, p1, p2, p3) \
|
||||
register uint32_t r0 asm ("r0") = (uint32_t)(p1); \
|
||||
register uint32_t r1 asm ("r1") = (uint32_t)(p2); \
|
||||
register uint32_t r2 asm ("r2") = (uint32_t)(p3); \
|
||||
asm volatile ("svc " #x : "=r" (r0), "=r" (r1) : \
|
||||
"r" (r0), "r" (r1), "r" (r2) : \
|
||||
"memory")
|
||||
|
||||
#define __syscall4r(x, p1, p2, p3, p4) \
|
||||
register uint32_t r0 asm ("r0") = (uint32_t)(p1); \
|
||||
|
@ -188,7 +218,17 @@ typedef uint32_t eventflags_t;
|
|||
register uint32_t r2 asm ("r2") = (uint32_t)(p3); \
|
||||
register uint32_t r3 asm ("r3") = (uint32_t)(p4); \
|
||||
asm volatile ("svc " #x : "=r" (r0) : "r" (r0), "r" (r1), \
|
||||
"r" (r2), "r" (r3) : "memory")
|
||||
"r" (r2), "r" (r3) : \
|
||||
"memory")
|
||||
|
||||
#define __syscall4rr(x, p1, p2, p3, p4) \
|
||||
register uint32_t r0 asm ("r0") = (uint32_t)(p1); \
|
||||
register uint32_t r1 asm ("r1") = (uint32_t)(p2); \
|
||||
register uint32_t r2 asm ("r2") = (uint32_t)(p3); \
|
||||
register uint32_t r3 asm ("r3") = (uint32_t)(p4); \
|
||||
asm volatile ("svc " #x : "=r" (r0), "=r" (r1) : \
|
||||
"r" (r0), "r" (r1), "r" (r2), "r" (r3) : \
|
||||
"memory")
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
|
|
@ -61,8 +61,9 @@ static void vuart_cb(SIODriver *siop) {
|
|||
void sb_api_vio_uart(struct port_extctx *ectxp) {
|
||||
sb_class_t *sbp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p;
|
||||
ectxp->r0 = (uint32_t)CH_RET_INNER_ERROR;
|
||||
uint32_t sub = (unsigned)ectxp->r0;
|
||||
uint32_t unit = (unsigned)ectxp->r1;
|
||||
ectxp->r1 = (uint32_t)0;
|
||||
uint32_t sub = ectxp->r0;
|
||||
uint32_t unit = ectxp->r1;
|
||||
const vio_uart_unit_t *unitp;
|
||||
|
||||
if (unit >= sbp->config->vioconf->uarts->n) {
|
||||
|
@ -75,7 +76,7 @@ void sb_api_vio_uart(struct port_extctx *ectxp) {
|
|||
switch (sub) {
|
||||
case SB_VUART_INIT:
|
||||
{
|
||||
uint32_t conf = sbp->config->vioconf->uartconfs->n;
|
||||
uint32_t conf = ectxp->r2;
|
||||
const vio_uart_config_t *confp;
|
||||
msg_t msg;
|
||||
|
||||
|
@ -101,8 +102,108 @@ void sb_api_vio_uart(struct port_extctx *ectxp) {
|
|||
ectxp->r0 = (uint32_t)HAL_RET_SUCCESS;
|
||||
break;
|
||||
}
|
||||
case SB_VUART_READ:
|
||||
{
|
||||
uint8_t *buffer = (uint8_t *)ectxp->r2;
|
||||
size_t n = (size_t)ectxp->r3;
|
||||
|
||||
if (unitp->siop->state != SIO_READY) {
|
||||
ectxp->r0 = (uint32_t)CH_RET_EIO;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!sb_is_valid_write_range(sbp, buffer, n)) {
|
||||
ectxp->r0 = (uint32_t)CH_RET_EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
ectxp->r1 = sioAsyncRead(unitp->siop, buffer, n);
|
||||
ectxp->r0 = (uint32_t)HAL_RET_SUCCESS;
|
||||
break;
|
||||
}
|
||||
case SB_VUART_WRITE:
|
||||
{
|
||||
const uint8_t *buffer = (const uint8_t *)ectxp->r2;
|
||||
size_t n = (size_t)ectxp->r3;
|
||||
|
||||
if (unitp->siop->state != SIO_READY) {
|
||||
ectxp->r0 = (uint32_t)CH_RET_EIO;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!sb_is_valid_read_range(sbp, buffer, n)) {
|
||||
ectxp->r0 = (uint32_t)CH_RET_EFAULT;
|
||||
break;
|
||||
}
|
||||
|
||||
ectxp->r1 = sioAsyncWrite(unitp->siop, buffer, n);
|
||||
ectxp->r0 = (uint32_t)HAL_RET_SUCCESS;
|
||||
break;
|
||||
}
|
||||
case SB_VUART_GET:
|
||||
{
|
||||
if (unitp->siop->state != SIO_READY) {
|
||||
ectxp->r0 = (uint32_t)CH_RET_EIO;
|
||||
break;
|
||||
}
|
||||
|
||||
ectxp->r1 = sioGetX(unitp->siop);
|
||||
ectxp->r0 = (uint32_t)HAL_RET_SUCCESS;
|
||||
break;
|
||||
}
|
||||
case SB_VUART_PUT:
|
||||
{
|
||||
uint_fast16_t data = (uint_fast16_t)ectxp->r2;
|
||||
|
||||
if (unitp->siop->state != SIO_READY) {
|
||||
ectxp->r0 = (uint32_t)CH_RET_EIO;
|
||||
break;
|
||||
}
|
||||
|
||||
sioPutX(unitp->siop, data);
|
||||
ectxp->r0 = (uint32_t)HAL_RET_SUCCESS;
|
||||
break;
|
||||
}
|
||||
case SB_VUART_WREN:
|
||||
{
|
||||
sioflags_t flags = (sioflags_t)ectxp->r2;
|
||||
|
||||
if (unitp->siop->state != SIO_READY) {
|
||||
ectxp->r0 = (uint32_t)CH_RET_EIO;
|
||||
break;
|
||||
}
|
||||
|
||||
sioWriteEnableFlags(unitp->siop, flags);
|
||||
ectxp->r0 = (uint32_t)HAL_RET_SUCCESS;
|
||||
break;
|
||||
}
|
||||
case SB_VUART_GCERR:
|
||||
{
|
||||
if (unitp->siop->state != SIO_READY) {
|
||||
ectxp->r0 = (uint32_t)CH_RET_EIO;
|
||||
break;
|
||||
}
|
||||
|
||||
ectxp->r1 = (uint32_t)sioGetAndClearErrors(unitp->siop);
|
||||
ectxp->r0 = (uint32_t)HAL_RET_SUCCESS;
|
||||
break;
|
||||
}
|
||||
case SB_VUART_GCEVT:
|
||||
{
|
||||
if (unitp->siop->state != SIO_READY) {
|
||||
ectxp->r0 = (uint32_t)CH_RET_EIO;
|
||||
break;
|
||||
}
|
||||
|
||||
ectxp->r1 = (uint32_t)sioGetAndClearEvents(unitp->siop);
|
||||
ectxp->r0 = (uint32_t)HAL_RET_SUCCESS;
|
||||
break;
|
||||
}
|
||||
case SB_VUART_CTL:
|
||||
/* falls through */
|
||||
default:
|
||||
return;
|
||||
ectxp->r0 = (uint32_t)CH_RET_ENOSYS;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ typedef struct vio_uart_config {
|
|||
*/
|
||||
typedef struct vio_uart_configs {
|
||||
uint32_t n;
|
||||
vio_uart_config_t cfgs[];
|
||||
vio_uart_config_t cfgs[];
|
||||
} vio_uart_configs_t;
|
||||
|
||||
/*===========================================================================*/
|
||||
|
|
Loading…
Reference in New Issue