More SIO-related changes.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15746 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
Giovanni Di Sirio 2022-08-31 12:29:47 +00:00
parent b09bc777ad
commit 8e7bdc79b5
6 changed files with 125 additions and 36 deletions

View File

@ -32,14 +32,19 @@
/*===========================================================================*/
/**
* @name Events enable flags offsets
* @name SIO masks offsets
* @{
*/
#define SIO_FL_RXNOTEMPY_POS 1
#define SIO_FL_TXNOTFULL_POS 2
#define SIO_FL_RXIDLE_POS 3
#define SIO_FL_TXDONE_POS 4
#define SIO_FL_ALL_ERRORS_POS 5
#define SIO_MSK_RXNOTEMPY_POS 2 /* CHN_INPUT_AVAILABLE */
#define SIO_MSK_TXNOTFULL_POS 3 /* CHN_OUTPUT_EMPTY */
#define SIO_MSK_TXDONE_POS 4 /* CHN_TRANSMISSION_END */
#define SIO_MSK_ALL_ERRORS_POS 5 /* CHN all errors */
#define SIO_MSK_PARITY_ERR_POS 5 /* CHN_PARITY_ERROR */
#define SIO_MSK_FRAMING_ERR_POS 6 /* CHN_FRAMING_ERROR */
#define SIO_MSK_OVERRUN_ERR_POS 7 /* CHN_OVERRUN_ERROR */
#define SIO_MSK_NOISE_ERR_POS 8 /* CHN_NOISE_ERROR */
#define SIO_MSK_BREAK_POS 9 /* CHN_BREAK_DETECTED */
#define SIO_MSK_RXIDLE_POS 11 /* CHN does not define it */
/** @} */
/**
@ -53,11 +58,11 @@
/**
* @brief RX buffer not empty event.
*/
#define SIO_FL_RXNOTEMPY (1U << SIO_FL_RXNOTEMPY_POS)
#define SIO_FL_RXNOTEMPY (1U << SIO_MSK_RXNOTEMPY_POS)
/**
* @brief TX buffer not full event.
*/
#define SIO_FL_TXNOTFULL (1U << SIO_FL_TXNOTFULL_POS)
#define SIO_FL_TXNOTFULL (1U << SIO_MSK_TXNOTFULL_POS)
/**
* @brief All data-related events.
*/
@ -66,11 +71,11 @@
/**
* @brief RX line idling event.
*/
#define SIO_FL_RXIDLE (1U << SIO_FL_RXIDLE_POS)
#define SIO_FL_RXIDLE (1U << SIO_MSK_RXIDLE_POS)
/**
* @brief TX complete event.
*/
#define SIO_FL_TXDONE (1U << SIO_FL_TXDONE_POS)
#define SIO_FL_TXDONE (1U << SIO_MSK_TXDONE_POS)
/**
* @brief All protocol-related events.
*/
@ -79,7 +84,7 @@
/**
* @brief All RX error events.
*/
#define SIO_FL_ALL_ERRORS (1U << SIO_FL_ALL_ERRORS_POS)
#define SIO_FL_ALL_ERRORS (1U << SIO_MSK_ALL_ERRORS_POS)
/**
* @brief All events.
*/
@ -92,9 +97,9 @@
* @name Event flags offsets
* @{
*/
#define SIO_EV_RXNOTEMPY_POS 2 /* CHN_INPUT_AVAILABLE */
#define SIO_EV_TXNOTFULL_POS 3 /* CHN_OUTPUT_EMPTY */
#define SIO_EV_TXDONE_POS 4 /* CHN_TRANSMISSION_END */
#define SIO_EV_RXNOTEMPY_POS 2
#define SIO_EV_TXNOTFULL_POS 3
#define SIO_EV_TXDONE_POS 4
#define SIO_EV_PARITY_ERR_POS 5 /* CHN_PARITY_ERROR */
#define SIO_EV_FRAMING_ERR_POS 6 /* CHN_FRAMING_ERROR */
#define SIO_EV_OVERRUN_ERR_POS 7 /* CHN_OVERRUN_ERROR */
@ -177,7 +182,7 @@
/**
* @brief Type of events enable flags.
*/
typedef uint_least8_t sioflags_t;
typedef eventflags_t sioflags_t;
/**
* @brief Type of event flags.
@ -440,6 +445,16 @@ struct hal_sio_driver {
*/
#define sioGetAndClearEventsI(siop) sio_lld_get_and_clear_events(siop)
/**
* @brief Returns the pending SIO event flags.
*
* @param[in] siop pointer to the @p SIODriver object
* @return The pending event flags.
*
* @iclass
*/
#define sioGetEventsI(siop) sio_lld_get_events(siop)
/**
* @brief Returns one frame from the RX FIFO.
* @note If the FIFO is empty then the returned value is unpredictable.
@ -535,7 +550,7 @@ struct hal_sio_driver {
*
* @notapi
*/
#define __sio_wakeup_events(siop) do { \
#define __sio_wakeup_errors(siop) do { \
osalSysLockFromISR(); \
osalThreadResumeI(&(siop)->sync_rx, SIO_MSG_ERRORS); \
osalThreadResumeI(&(siop)->sync_rxidle, SIO_MSG_ERRORS); \

View File

@ -256,9 +256,9 @@ void sio_lld_update_enable_flags(SIODriver *siop) {
UART_UARTIMSC_PEIM | UART_UARTIMSC_FEIM;
}
imsc |= __sio_reloc_field(siop->enabled, SIO_FL_RXNOTEMPY, SIO_FL_RXNOTEMPY_POS, UART_UARTIMSC_RXIM_Pos) |
__sio_reloc_field(siop->enabled, SIO_FL_TXNOTFULL, SIO_FL_TXNOTFULL_POS, UART_UARTIMSC_TXIM_Pos) |
__sio_reloc_field(siop->enabled, SIO_FL_RXIDLE, SIO_FL_RXIDLE_POS, UART_UARTIMSC_RTIM_Pos);
imsc |= __sio_reloc_field(siop->enabled, SIO_FL_RXNOTEMPY, SIO_MSK_RXNOTEMPY_POS, UART_UARTIMSC_RXIM_Pos) |
__sio_reloc_field(siop->enabled, SIO_FL_TXNOTFULL, SIO_MSK_TXNOTFULL_POS, UART_UARTIMSC_TXIM_Pos) |
__sio_reloc_field(siop->enabled, SIO_FL_RXIDLE, SIO_MSK_RXIDLE_POS, UART_UARTIMSC_RTIM_Pos);
/* Setting up the operation.*/
siop->uart->UARTIMSC |= imsc;
@ -509,7 +509,7 @@ void sio_lld_serve_interrupt(SIODriver *siop) {
UART_UARTIMSC_PEIM | UART_UARTIMSC_FEIM);
/* Waiting thread woken, if any.*/
__sio_wakeup_events(siop);
__sio_wakeup_errors(siop);
}
/* Idle RX event.*/

View File

@ -458,13 +458,13 @@ void sio_lld_update_enable_flags(SIODriver *siop) {
cr2irq = siop->usart->CR2 & ~(USART_CR2_LBDIE);
cr3irq = siop->usart->CR3 & ~(USART_CR3_EIE);
cr1irq |= __sio_reloc_field(siop->enabled, SIO_FL_RXNOTEMPY, SIO_FL_RXNOTEMPY_POS, USART_CR1_RXNEIE_Pos) |
__sio_reloc_field(siop->enabled, SIO_FL_TXNOTFULL, SIO_FL_TXNOTFULL_POS, USART_CR1_TXEIE_Pos) |
__sio_reloc_field(siop->enabled, SIO_FL_RXIDLE, SIO_FL_RXIDLE_POS, USART_CR1_IDLEIE_Pos) |
__sio_reloc_field(siop->enabled, SIO_FL_TXDONE, SIO_FL_TXDONE_POS, USART_CR1_TCIE_Pos) |
__sio_reloc_field(siop->enabled, SIO_FL_ALL_ERRORS, SIO_FL_ALL_ERRORS_POS, USART_CR1_PEIE_Pos);
cr2irq |= __sio_reloc_field(siop->enabled, SIO_FL_ALL_ERRORS, SIO_FL_ALL_ERRORS_POS, USART_CR2_LBDIE_Pos);
cr3irq |= __sio_reloc_field(siop->enabled, SIO_FL_ALL_ERRORS, SIO_FL_ALL_ERRORS_POS, USART_CR3_EIE_Pos);
cr1irq |= __sio_reloc_field(siop->enabled, SIO_FL_RXNOTEMPY, SIO_MSK_RXNOTEMPY_POS, USART_CR1_RXNEIE_Pos) |
__sio_reloc_field(siop->enabled, SIO_FL_TXNOTFULL, SIO_MSK_TXNOTFULL_POS, USART_CR1_TXEIE_Pos) |
__sio_reloc_field(siop->enabled, SIO_FL_RXIDLE, SIO_MSK_RXIDLE_POS, USART_CR1_IDLEIE_Pos) |
__sio_reloc_field(siop->enabled, SIO_FL_TXDONE, SIO_MSK_TXDONE_POS, USART_CR1_TCIE_Pos) |
__sio_reloc_field(siop->enabled, SIO_FL_ALL_ERRORS, SIO_MSK_ALL_ERRORS_POS, USART_CR1_PEIE_Pos);
cr2irq |= __sio_reloc_field(siop->enabled, SIO_FL_ALL_ERRORS, SIO_MSK_ALL_ERRORS_POS, USART_CR2_LBDIE_Pos);
cr3irq |= __sio_reloc_field(siop->enabled, SIO_FL_ALL_ERRORS, SIO_MSK_ALL_ERRORS_POS, USART_CR3_EIE_Pos);
/* Setting up the operation.*/
siop->usart->CR1 = cr1irq;
@ -551,6 +551,42 @@ sioevents_t sio_lld_get_and_clear_events(SIODriver *siop) {
return events;
}
/**
* @brief Returns the pending SIO event flags.
*
* @param[in] siop pointer to the @p SIODriver object
* @return The pending event flags.
*
* @notapi
*/
sioevents_t sio_lld_get_events(SIODriver *siop) {
uint32_t isr;
sioevents_t events;
/* Getting all ISR flags.
NOTE: Do not trust the position of other bits in ISR/ICR because
some scientist decided to use different positions for some
of them.*/
isr = siop->usart->ISR & (SIO_LLD_ISR_RX_ERRORS |
USART_ISR_RXNE |
USART_ISR_IDLE |
USART_ISR_TXE |
USART_ISR_TC);
/* Translating the status flags in SIO events.*/
events = __sio_reloc_field(isr, USART_ISR_RXNE_Msk, USART_ISR_RXNE_Pos, SIO_EV_RXNOTEMPY_POS) |
__sio_reloc_field(isr, USART_ISR_TXE_Msk, USART_ISR_TXE_Pos, SIO_EV_TXNOTFULL_POS) |
__sio_reloc_field(isr, USART_ISR_IDLE_Msk, USART_ISR_IDLE_Pos, SIO_EV_RXIDLE_POS) |
__sio_reloc_field(isr, USART_ISR_TC_Msk, USART_ISR_TC_Pos, SIO_EV_TXDONE_POS) |
__sio_reloc_field(isr, USART_ISR_LBDF_Msk, USART_ISR_LBDF_Pos, SIO_EV_BREAK_POS) |
__sio_reloc_field(isr, USART_ISR_PE_Msk, USART_ISR_PE_Pos, SIO_EV_PARITY_ERR_POS) |
__sio_reloc_field(isr, USART_ISR_FE_Msk, USART_ISR_FE_Pos, SIO_EV_FRAMING_ERR_POS) |
__sio_reloc_field(isr, USART_ISR_NE_Msk, USART_ISR_NE_Pos, SIO_EV_NOISE_ERR_POS) |
__sio_reloc_field(isr, USART_ISR_ORE_Msk, USART_ISR_ORE_Pos, SIO_EV_OVERRUN_ERR_POS);
return events;
}
/**
* @brief Reads data from the RX FIFO.
* @details The function is not blocking, it writes frames until there
@ -746,7 +782,7 @@ void sio_lld_serve_interrupt(SIODriver *siop) {
cr1 &= ~USART_CR1_PEIE;
/* Waiting thread woken, if any.*/
__sio_wakeup_events(siop);
__sio_wakeup_errors(siop);
}
/* Idle RX event.*/

View File

@ -399,6 +399,7 @@ extern "C" {
void sio_lld_update_enable_flags(SIODriver *siop);
sioevents_t sio_lld_get_and_clear_errors(SIODriver *siop);
sioevents_t sio_lld_get_and_clear_events(SIODriver *siop);
sioevents_t sio_lld_get_events(SIODriver *siop);
size_t sio_lld_read(SIODriver *siop, uint8_t *buffer, size_t n);
size_t sio_lld_write(SIODriver *siop, const uint8_t *buffer, size_t n);
msg_t sio_lld_get(SIODriver *siop);

View File

@ -510,13 +510,13 @@ void sio_lld_update_enable_flags(SIODriver *siop) {
cr2irq = siop->usart->CR2 & ~(USART_CR2_LBDIE);
cr3irq = siop->usart->CR3 & ~(USART_CR3_RXFTIE | USART_CR3_TXFTIE | USART_CR3_EIE);
cr1irq |= __sio_reloc_field(siop->enabled, SIO_FL_RXIDLE, SIO_FL_RXIDLE_POS, USART_CR1_IDLEIE_Pos) |
__sio_reloc_field(siop->enabled, SIO_FL_TXDONE, SIO_FL_TXDONE_POS, USART_CR1_TCIE_Pos) |
__sio_reloc_field(siop->enabled, SIO_FL_ALL_ERRORS, SIO_FL_ALL_ERRORS_POS, USART_CR1_PEIE_Pos);
cr2irq |= __sio_reloc_field(siop->enabled, SIO_FL_ALL_ERRORS, SIO_FL_ALL_ERRORS_POS, USART_CR2_LBDIE_Pos);
cr3irq |= __sio_reloc_field(siop->enabled, SIO_FL_RXNOTEMPY, SIO_FL_RXNOTEMPY_POS, USART_CR3_RXFTIE_Pos) |
__sio_reloc_field(siop->enabled, SIO_FL_TXNOTFULL, SIO_FL_TXNOTFULL_POS, USART_CR3_TXFTIE_Pos) |
__sio_reloc_field(siop->enabled, SIO_FL_ALL_ERRORS, SIO_FL_ALL_ERRORS_POS, USART_CR3_EIE_Pos);
cr1irq |= __sio_reloc_field(siop->enabled, SIO_FL_RXIDLE, SIO_MSK_RXIDLE_POS, USART_CR1_IDLEIE_Pos) |
__sio_reloc_field(siop->enabled, SIO_FL_TXDONE, SIO_MSK_TXDONE_POS, USART_CR1_TCIE_Pos) |
__sio_reloc_field(siop->enabled, SIO_FL_ALL_ERRORS, SIO_MSK_ALL_ERRORS_POS, USART_CR1_PEIE_Pos);
cr2irq |= __sio_reloc_field(siop->enabled, SIO_FL_ALL_ERRORS, SIO_MSK_ALL_ERRORS_POS, USART_CR2_LBDIE_Pos);
cr3irq |= __sio_reloc_field(siop->enabled, SIO_FL_RXNOTEMPY, SIO_MSK_RXNOTEMPY_POS, USART_CR3_RXFTIE_Pos) |
__sio_reloc_field(siop->enabled, SIO_FL_TXNOTFULL, SIO_MSK_TXNOTFULL_POS, USART_CR3_TXFTIE_Pos) |
__sio_reloc_field(siop->enabled, SIO_FL_ALL_ERRORS, SIO_MSK_ALL_ERRORS_POS, USART_CR3_EIE_Pos);
/* Setting up the operation.*/
siop->usart->CR1 = cr1irq;
@ -603,6 +603,42 @@ sioevents_t sio_lld_get_and_clear_events(SIODriver *siop) {
return events;
}
/**
* @brief Returns the pending SIO event flags.
*
* @param[in] siop pointer to the @p SIODriver object
* @return The pending event flags.
*
* @notapi
*/
sioevents_t sio_lld_get_events(SIODriver *siop) {
uint32_t isr;
sioevents_t events;
/* Getting all ISR flags.
NOTE: Do not trust the position of other bits in ISR/ICR because
some scientist decided to use different positions for some
of them.*/
isr = siop->usart->ISR & (SIO_LLD_ISR_RX_ERRORS |
USART_ISR_RXNE_RXFNE |
USART_ISR_IDLE |
USART_ISR_TXE_TXFNF |
USART_ISR_TC);
/* Translating the status flags in SIO events.*/
events = __sio_reloc_field(isr, USART_ISR_RXNE_RXFNE_Msk, USART_ISR_RXNE_RXFNE_Pos, SIO_EV_RXNOTEMPY_POS) |
__sio_reloc_field(isr, USART_ISR_TXE_TXFNF_Msk, USART_ISR_TXE_TXFNF_Pos, SIO_EV_TXNOTFULL_POS) |
__sio_reloc_field(isr, USART_ISR_IDLE_Msk, USART_ISR_IDLE_Pos, SIO_EV_RXIDLE_POS) |
__sio_reloc_field(isr, USART_ISR_TC_Msk, USART_ISR_TC_Pos, SIO_EV_TXDONE_POS) |
__sio_reloc_field(isr, USART_ISR_LBDF_Msk, USART_ISR_LBDF_Pos, SIO_EV_BREAK_POS) |
__sio_reloc_field(isr, USART_ISR_PE_Msk, USART_ISR_PE_Pos, SIO_EV_PARITY_ERR_POS) |
__sio_reloc_field(isr, USART_ISR_FE_Msk, USART_ISR_FE_Pos, SIO_EV_FRAMING_ERR_POS) |
__sio_reloc_field(isr, USART_ISR_NE_Msk, USART_ISR_NE_Pos, SIO_EV_NOISE_ERR_POS) |
__sio_reloc_field(isr, USART_ISR_ORE_Msk, USART_ISR_ORE_Pos, SIO_EV_OVERRUN_ERR_POS);
return events;
}
/**
* @brief Reads data from the RX FIFO.
* @details The function is not blocking, it writes frames until there
@ -798,7 +834,7 @@ void sio_lld_serve_interrupt(SIODriver *siop) {
cr1 &= ~USART_CR1_PEIE;
/* Waiting thread woken, if any.*/
__sio_wakeup_events(siop);
__sio_wakeup_errors(siop);
}
/* Idle RX event.*/

View File

@ -454,6 +454,7 @@ extern "C" {
void sio_lld_update_enable_flags(SIODriver *siop);
sioevents_t sio_lld_get_and_clear_errors(SIODriver *siop);
sioevents_t sio_lld_get_and_clear_events(SIODriver *siop);
sioevents_t sio_lld_get_events(SIODriver *siop);
size_t sio_lld_read(SIODriver *siop, uint8_t *buffer, size_t n);
size_t sio_lld_write(SIODriver *siop, const uint8_t *buffer, size_t n);
msg_t sio_lld_get(SIODriver *siop);