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:
parent
f87d680ab7
commit
510da52979
|
@ -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);
|
||||
|
|
|
@ -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. */
|
||||
/*===========================================================================*/
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
||||
/** @} */
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue