More SIO changes.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@13819 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
Giovanni Di Sirio 2020-08-31 09:32:24 +00:00
parent f87d680ab7
commit 510da52979
6 changed files with 231 additions and 52 deletions

View File

@ -252,9 +252,9 @@ struct hal_sio_operation {
* @param[in] siop pointer to the @p SIODriver object
* @return The frame from RX FIFO.
*
* @iclass
* @xclass
*/
#define sioGetI(siop) sio_lld_get(siop)
#define sioGetX(siop) sio_lld_get(siop)
/**
* @brief Pushes one frame into the TX FIFO.
@ -263,9 +263,9 @@ struct hal_sio_operation {
* @param[in] siop pointer to the @p SIODriver object
* @param[in] data frame to be written
*
* @iclass
* @xclass
*/
#define sioPutI(siop, data) sio_lld_put(siop, data)
#define sioPutX(siop, data) sio_lld_put(siop, data)
/**
* @brief Reads data from the RX FIFO.
@ -442,8 +442,8 @@ extern "C" {
void sioStop(SIODriver *siop);
void sioStartOperation(SIODriver *siop, const SIOOperation *operation);
void sioStopOperation(SIODriver *siop);
size_t sioAsyncRead(SIODriver *siop, size_t n, uint8_t *buffer);
size_t sioAsyncWrite(SIODriver *siop, size_t n, const uint8_t *buffer);
size_t sioAsyncRead(SIODriver *siop, uint8_t *buffer, size_t n);
size_t sioAsyncWrite(SIODriver *siop, const uint8_t *buffer, size_t n);
#if (HAL_SIO_USE_SYNCHRONIZATION == TRUE) || defined(__DOXYGEN__)
msg_t sioSynchronizeRX(SIODriver *siop, sysinterval_t timeout);
msg_t sioSynchronizeTX(SIODriver *siop, sysinterval_t timeout);

View File

@ -27,6 +27,8 @@
#if HAL_USE_SERIAL || defined(__DOXYGEN__)
#include "stm32_usart.h"
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
@ -549,14 +551,6 @@ typedef struct {
/* Driver macros. */
/*===========================================================================*/
/*
* Extra USARTs definitions here (missing from the ST header file).
*/
#define USART_CR2_STOP1_BITS (0 << 12) /**< @brief CR2 1 stop bit value.*/
#define USART_CR2_STOP0P5_BITS (1 << 12) /**< @brief CR2 0.5 stop bit value.*/
#define USART_CR2_STOP2_BITS (2 << 12) /**< @brief CR2 2 stop bit value.*/
#define USART_CR2_STOP1P5_BITS (3 << 12) /**< @brief CR2 1.5 stop bit value.*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/

View File

@ -148,7 +148,7 @@ static void usart_init(SIODriver *siop) {
(siop->clock <= siop->config->baud * 4096U),
"invalid baud rate vs input clock");
brr = (uint32_t)(((uint64_t)(siop->clock / presc) * (uint64_t)256) / siop->config->speed);
brr = (uint32_t)(((uint64_t)(siop->clock / presc) * (uint64_t)256) / siop->config->baud);
osalDbgAssert((brr >= 0x300) && (brr < 0x100000), "invalid BRR value");
}
@ -474,12 +474,12 @@ void sio_lld_stop_operation(SIODriver *siop) {
* is space available without waiting.
*
* @param[in] siop pointer to an @p SIODriver structure
* @param[in] n maximum number of frames to be read
* @param[in] buffer pointer to the buffer for read frames
* @param[in] n maximum number of frames to be read
* @return The number of frames copied from the buffer.
* @retval 0 if the TX FIFO is full.
*/
size_t sio_lld_read(SIODriver *siop, size_t n, uint8_t *buffer) {
size_t sio_lld_read(SIODriver *siop, uint8_t *buffer, size_t n) {
size_t rd;
rd = 0U;
@ -511,12 +511,12 @@ size_t sio_lld_read(SIODriver *siop, size_t n, uint8_t *buffer) {
* is space available without waiting.
*
* @param[in] siop pointer to an @p SIODriver structure
* @param[in] n maximum number of frames to be written
* @param[in] buffer pointer to the buffer for read frames
* @param[in] n maximum number of frames to be written
* @return The number of frames copied from the buffer.
* @retval 0 if the TX FIFO is full.
*/
size_t sio_lld_write(SIODriver *siop, size_t n, const uint8_t *buffer) {
size_t sio_lld_write(SIODriver *siop, const uint8_t *buffer, size_t n) {
size_t wr;
wr = 0U;
@ -583,9 +583,11 @@ void sio_lld_serve_interrupt(SIODriver *siop) {
osalDbgAssert(siop->state == SIO_ACTIVE, "invalid state");
/* Reading and clearing status.*/
/* Reading and clearing status, note that TC is not cleared because
it is for checking if a transmission is ongoing, it is set/reset
in HW.*/
isr = u->ISR;
u->ICR = isr;
u->ICR = isr & ~USART_ISR_TC;
/* One read on control registers.*/
cr1 = u->CR1;

View File

@ -27,6 +27,8 @@
#if (HAL_USE_SIO == TRUE) || defined(__DOXYGEN__)
#include "stm32_usart.h"
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
@ -116,7 +118,7 @@
* @details If set to @p TRUE the support for LPUART1 is included.
* @note The default is @p FALSE.
*/
#if !defined(STM32_SIO_USE_ULPUART1) || defined(__DOXYGEN__)
#if !defined(STM32_SIO_USE_LPUART1) || defined(__DOXYGEN__)
#define STM32_SIO_USE_LPUART1 FALSE
#endif
/** @} */
@ -296,7 +298,7 @@
*
* @notapi
*/
#define sio_lld_rx_get(siop)
#define sio_lld_get(siop) (siop)->usart->RDR
/**
* @brief Pushes one frame into the TX FIFO.
@ -307,7 +309,7 @@
*
* @notapi
*/
#define sio_lld_tx_put(siop, data)
#define sio_lld_put(siop, data) (siop)->usart->TDR = (data)
/*===========================================================================*/
/* External declarations. */
@ -357,8 +359,8 @@ extern "C" {
void sio_lld_stop(SIODriver *siop);
void sio_lld_start_operation(SIODriver *siop);
void sio_lld_stop_operation(SIODriver *siop);
size_t sio_lld_read(SIODriver *siop, size_t size, uint8_t *buffer);
size_t sio_lld_write(SIODriver *siop, size_t size, const uint8_t *buffer);
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_control(SIODriver *siop, unsigned int operation, void *arg);
void sio_lld_serve_interrupt(SIODriver *siop);
#ifdef __cplusplus

View File

@ -0,0 +1,116 @@
/*
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 USARTv2/stm32_usart.h
* @brief STM32 USART helpers header.
*
* @addtogroup STM32_USARTv2
* @{
*/
#ifndef STM32_USART_H
#define STM32_USART_H
/*===========================================================================*/
/* Driver constants. */
/*===========================================================================*/
/**
* @brief CR2 register additional macros
*/
#define USART_CR1_DATA7 (USART_CR1_M1)
#define USART_CR1_DATA8 (0U)
#define USART_CR1_DATA9 (USART_CR1_M0)
#define USART_CR1_OVER16 (0)
/** @} */
/**
* @brief CR2 register additional macros
*/
#define USART_CR2_STOP1_BITS (0U << 12)
#define USART_CR2_STOP0P5_BITS (1U << 12)
#define USART_CR2_STOP2_BITS (2U << 12)
#define USART_CR2_STOP1P5_BITS (3U << 12)
/** @} */
/**
* @brief CR3 register additional macros
*/
#define USART_CR3_TXFTCFG_NONFULL (0U)
#define USART_CR3_TXFTCFG_1Q (USART_CR3_TXFTCFG_0)
#define USART_CR3_TXFTCFG_1H (USART_CR3_TXFTCFG_1)
#define USART_CR3_TXFTCFG_3Q (USART_CR3_TXFTCFG_1 | USART_CR3_TXFTCFG_0)
#define USART_CR3_TXFTCFG_7E (USART_CR3_TXFTCFG_2)
#define USART_CR3_TXFTCFG_EMPTY (USART_CR3_TXFTCFG_2 | USART_CR3_TXFTCFG_0)
#define USART_CR3_RXFTCFG_NONEMPTY (0U)
#define USART_CR3_RXFTCFG_1Q (USART_CR3_RXFTCFG_0)
#define USART_CR3_RXFTCFG_1H (USART_CR3_RXFTCFG_1)
#define USART_CR3_RXFTCFG_3Q (USART_CR3_RXFTCFG_1 | USART_CR3_RXFTCFG_0)
#define USART_CR3_RXFTCFG_7E (USART_CR3_RXFTCFG_2)
#define USART_CR3_RXFTCFG_FULL (USART_CR3_RXFTCFG_2 | USART_CR3_RXFTCFG_0)
/** @} */
/**
* @brief PRESC register additional macros
*/
#define USART_PRESC_N(n) ((n) << USART_PRESC_PRESCALER_Pos)
#define USART_PRESC1 USART_PRESC_N(0U)
#define USART_PRESC2 USART_PRESC_N(1U)
#define USART_PRESC4 USART_PRESC_N(2U)
#define USART_PRESC6 USART_PRESC_N(3U)
#define USART_PRESC8 USART_PRESC_N(4U)
#define USART_PRESC10 USART_PRESC_N(5U)
#define USART_PRESC12 USART_PRESC_N(6U)
#define USART_PRESC16 USART_PRESC_N(7U)
#define USART_PRESC32 USART_PRESC_N(8U)
#define USART_PRESC64 USART_PRESC_N(9U)
#define USART_PRESC128 USART_PRESC_N(10U)
#define USART_PRESC256 USART_PRESC_N(11U)
/** @} */
/*===========================================================================*/
/* Driver pre-compile time settings. */
/*===========================================================================*/
/*===========================================================================*/
/* Derived constants and error checks. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver data structures and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver macros. */
/*===========================================================================*/
/*===========================================================================*/
/* External declarations. */
/*===========================================================================*/
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
#endif /* STM32_USART_H */
/** @} */

View File

@ -43,69 +43,125 @@
/*===========================================================================*/
#if (HAL_SIO_USE_SYNCHRONIZATION == TRUE) || defined(__DOXYGEN__)
static size_t sync_write(void *ip, const uint8_t *bp, size_t n,
sysinterval_t timeout) {
SIODriver *siop = (SIODriver *)ip;
size_t i;
i = 0U;
while (i < n) {
size_t written;
msg_t msg;
msg = sioSynchronizeTX(siop, timeout);
if (msg != MSG_OK) {
break;
}
written = sioAsyncWrite(siop, bp, n - i);
i += written;
bp += written;
}
return n;
}
static size_t sync_read(void *ip, uint8_t *bp, size_t n,
sysinterval_t timeout) {
SIODriver *siop = (SIODriver *)ip;
size_t i;
i = 0U;
while (i < n) {
size_t read;
msg_t msg;
msg = sioSynchronizeTX(siop, timeout);
if (msg != MSG_OK) {
break;
}
read = sioAsyncRead(siop, bp, n - i);
i += read;
bp += read;
}
return n;
}
/*
* Interface implementation, the following functions just invoke the equivalent
* queue-level function or macro.
*/
static size_t __write(void *ip, const uint8_t *bp, size_t n) {
SIODriver *siop = (SIODriver *)ip;
sioSynchronizeTX(siop, TIME_INFINITE);
return sioAsyncWrite(siop, n, bp);
return sync_write(ip, bp, n, TIME_INFINITE);
}
static size_t __read(void *ip, uint8_t *bp, size_t n) {
SIODriver *siop = (SIODriver *)ip;
sioSynchronizeRX(siop, TIME_INFINITE);
return sioAsyncRead(siop, n, bp);
return sync_read(ip, bp, n, TIME_INFINITE);
}
static msg_t __put(void *ip, uint8_t b) {
SIODriver *siop = (SIODriver *)ip;
msg_t msg;
sioSynchronizeTX(siop, TIME_INFINITE);
sioPut(b);
msg = sioSynchronizeTX(siop, TIME_INFINITE);
if (msg != MSG_OK) {
return MSG_RESET;
}
sioPutX(siop, b);
return MSG_OK;
}
static msg_t __get(void *ip) {
SIODriver *siop = (SIODriver *)ip;
msg_t msg;
sioSynchronizeRX(siop, TIME_INFINITE);
return sioGet();
msg = sioSynchronizeRX(siop, TIME_INFINITE);
if (msg != MSG_OK) {
return MSG_RESET;
}
return sioGetX(siop);
}
static msg_t __putt(void *ip, uint8_t b, sysinterval_t timeout) {
SIODriver *siop = (SIODriver *)ip;
msg_t msg;
sioSynchronizeTX(siop, timeout);
sioPut(b);
msg = sioSynchronizeTX(siop, timeout);
if (msg != MSG_OK) {
return MSG_RESET;
}
sioPutX(siop, b);
return MSG_OK;
}
static msg_t __gett(void *ip, sysinterval_t timeout) {
SIODriver *siop = (SIODriver *)ip;
msg_t msg;
sioSynchronizeRX(siop, timeout);
return sioGet();
msg = sioSynchronizeRX(siop, timeout);
if (msg != MSG_OK) {
return MSG_RESET;
}
return sioGetX(siop);
}
static size_t __writet(void *ip, const uint8_t *bp, size_t n,
sysinterval_t timeout) {
SIODriver *siop = (SIODriver *)ip;
sioSynchronizeTX(siop, timeout);
return sioAsyncWrite(siop, n, bp);
return sync_write(ip, bp, n, timeout);
}
static size_t __readt(void *ip, uint8_t *bp, size_t n,
sysinterval_t timeout) {
SIODriver *siop = (SIODriver *)ip;
sioSynchronizeRX(siop, timeout);
return sioAsyncRead(siop, n, bp);
return sync_read(ip, bp, n, timeout);
}
static msg_t __ctl(void *ip, unsigned int operation, void *arg) {
@ -264,6 +320,13 @@ void sioStopOperation(SIODriver *siop) {
osalDbgAssert(siop->state == SIO_ACTIVE, "invalid state");
#if HAL_SIO_USE_SYNCHRONIZATION == TRUE
/* Informing waiting threads, if any.*/
osalThreadResumeI(&siop->sync_rx, MSG_RESET);
osalThreadResumeI(&siop->sync_tx, MSG_RESET);
osalThreadResumeI(&siop->sync_txend, MSG_RESET);
#endif
sio_lld_stop_operation(siop);
siop->operation = NULL;
@ -281,18 +344,18 @@ void sioStopOperation(SIODriver *siop) {
*
* @param[in] siop pointer to the @p SIODriver object
* @param[in] buffer buffer for the received data
* @param[in] size maximum number of frames to read
* @param[in] n maximum number of frames to read
* @return The number of received frames.
*
* @api
*/
size_t sioAsyncRead(SIODriver *siop, size_t n, uint8_t *buffer) {
size_t sioAsyncRead(SIODriver *siop, uint8_t *buffer, size_t n) {
osalDbgCheck((siop != NULL) && (buffer));
osalSysLock();
n = sioAsyncReadI(siop, n, buffer);
n = sioAsyncReadI(siop, buffer, n);
osalSysUnlock();
@ -308,18 +371,18 @@ size_t sioAsyncRead(SIODriver *siop, size_t n, uint8_t *buffer) {
*
* @param[in] siop pointer to the @p SIODriver object
* @param[out] buffer buffer containing the data to be transmitted
* @param[in] size maximum number of frames to read
* @param[in] n maximum number of frames to read
* @return The number of transmitted frames.
*
* @api
*/
size_t sioAsyncWrite(SIODriver *siop, size_t n, const uint8_t *buffer) {
size_t sioAsyncWrite(SIODriver *siop, const uint8_t *buffer, size_t n) {
osalDbgCheck((siop != NULL) && (buffer != NULL));
osalSysLock();
n = sioAsyncWriteI(siop, n, buffer);
n = sioAsyncWriteI(siop, buffer, n);
osalSysUnlock();
@ -338,6 +401,7 @@ size_t sioAsyncWrite(SIODriver *siop, size_t n, const uint8_t *buffer) {
* @return The synchronization result.
* @retval MSG_OK if there is data in the RX FIFO.
* @retval MSG_TIMEOUT if synchronization timed out.
* @retval MSG_RESET operation has been stopped while waiting.
* @retval SIO_MSG_IDLE if RX line went idle.
* @retval SIO_MSG_ERRORS if RX errors occurred during wait.
*/
@ -373,6 +437,7 @@ msg_t sioSynchronizeRX(SIODriver *siop, sysinterval_t timeout) {
* @return The synchronization result.
* @retval MSG_OK if there is space in the TX FIFO.
* @retval MSG_TIMEOUT if synchronization timed out.
* @retval MSG_RESET operation has been stopped while waiting.
*/
msg_t sioSynchronizeTX(SIODriver *siop, sysinterval_t timeout) {
msg_t msg;