Some checks failed
Basic Checks / license-check (push) Has been cancelled
Basic Checks / include-check (push) Has been cancelled
Basic Checks / style-check (push) Has been cancelled
Basic Checks / docs-check (push) Has been cancelled
Basic Checks / python-tests (push) Has been cancelled
Basic Checks / pin-validation (push) Has been cancelled
Basic Checks / cmake-checks (push) Has been cancelled
Basic Checks / frozen-tools-check (push) Has been cancelled
Publish or Update docker image for head of branch / prepare-tags (push) Has been cancelled
Release or update docker image for a released mbed-os version / prepare-tags (push) Has been cancelled
Publish or Update docker image for head of branch / build-container (push) Has been cancelled
Publish or Update docker image for head of branch / test-container (linux/amd64) (push) Has been cancelled
Publish or Update docker image for head of branch / test-container (linux/arm64) (push) Has been cancelled
Publish or Update docker image for head of branch / deploy-container (push) Has been cancelled
Release or update docker image for a released mbed-os version / build-container (push) Has been cancelled
Release or update docker image for a released mbed-os version / test-container (linux/amd64) (push) Has been cancelled
Release or update docker image for a released mbed-os version / test-container (linux/arm64) (push) Has been cancelled
Release or update docker image for a released mbed-os version / deploy-container (push) Has been cancelled
Prune temporary docker images / prune-images (push) Has been cancelled
439 lines
18 KiB
C
439 lines
18 KiB
C
/***************************************************************************//**
|
|
* \file cyhal_uart.h
|
|
*
|
|
* \brief
|
|
* Provides a high level interface for interacting with the Cypress UART.
|
|
* This interface abstracts out the chip specific details. If any chip specific
|
|
* functionality is necessary, or performance is critical the low level functions
|
|
* can be used directly.
|
|
*
|
|
********************************************************************************
|
|
* \copyright
|
|
* Copyright 2018-2021 Cypress Semiconductor Corporation
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* 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.
|
|
*******************************************************************************/
|
|
|
|
/**
|
|
* \addtogroup group_hal_uart UART (Universal Asynchronous Receiver-Transmitter)
|
|
* \ingroup group_hal
|
|
* \{
|
|
* High level interface for interacting with the Universal Asynchronous Receiver-Transmitter (UART).
|
|
*
|
|
* The Universal Asynchronous Receiver/Transmitter (UART) protocol is an
|
|
* asynchronous serial interface protocol. UART communication is typically
|
|
* point-to-point. The UART interface consists of two signals:
|
|
* * TX: Transmitter output
|
|
* * RX: Receiver input
|
|
*
|
|
* Additionally, two side-band signals are used to implement flow control in
|
|
* UART. Note that the flow control applies only to TX functionality.
|
|
* * Clear to Send (CTS): This is an input signal to the transmitter.
|
|
* When active, it indicates that the slave is ready for the master to
|
|
* transmit data.
|
|
* * Ready to Send (RTS): This is an output signal from the receiver. When
|
|
* active, it indicates that the receiver is ready to receive data
|
|
*
|
|
* Flow control can be configured via cyhal_uart_set_flow_control()
|
|
*
|
|
* The data frame size, STOP bits and parity can be configured via \ref cyhal_uart_cfg_t.
|
|
* The UART contains dedicated hardware buffers for transmit and receive. Optionally,
|
|
* either of these can be augmented with a software buffer.
|
|
*
|
|
* \note For applications that require printing messages on a UART terminal using printf(),
|
|
* the <a href="https://github.com/cypresssemiconductorco/retarget-io">retarget-io</a> utility library can be used directly.
|
|
*
|
|
*
|
|
* \section subsection_uart_features Features
|
|
* * Configurable UART baud rate - \ref cyhal_uart_set_baud
|
|
* * Configurable data frame size, STOP bits and parity - \ref cyhal_uart_cfg_t
|
|
* * Configurable interrupts and callback on UART events - \ref cyhal_uart_event_t
|
|
* \section subsection_uart_interrupts Interrupts and callbacks
|
|
* Interrupts are handled by callbacks based on events \ref cyhal_uart_event_t
|
|
* If an event is disabled, the underlying interrupt is still enabled. Enabling or disabling
|
|
* an event only enables or disables the callback.
|
|
* \note Care must be exercised whenusing the \ref CYHAL_UART_IRQ_RX_NOT_EMPTY event.
|
|
* The callback must read all available received data or the interrupt will not be cleared
|
|
* leading to the callback being immediately retriggered.
|
|
* \section subsection_uart_quickstart Quick Start
|
|
* \ref cyhal_uart_init is used for UART initialization
|
|
*
|
|
* \section subsection_uart_sample_snippets Code Snippets
|
|
*
|
|
* \subsection subsection_uart_snippet_1 Snippet 1: Initialization and Configuration
|
|
* The following snippet initializes the UART block and assigns the **tx**, **rx** pins and sets the baudrate.
|
|
*
|
|
* The snippet also shows how to use \ref cyhal_uart_write, \ref cyhal_uart_putc, \ref cyhal_uart_read API.
|
|
*
|
|
* \snippet hal_uart.c snippet_cyhal_uart_init
|
|
*
|
|
* \subsection subsection_uart_snippet_2 Snippet 2: Interrupts on UART events
|
|
*
|
|
* In the following snippet, UART events are handled in a callback function.
|
|
* The callback function has to be registered and then the events have to be enabled.
|
|
*
|
|
* \snippet hal_uart.c snippet_cyhal_uart_event
|
|
*
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <stdint.h>
|
|
#include <stdbool.h>
|
|
#include "cy_result.h"
|
|
#include "cyhal_hw_types.h"
|
|
|
|
#if defined(__cplusplus)
|
|
extern "C" {
|
|
#endif
|
|
|
|
/****************************************************************
|
|
* Defines
|
|
*****************************************************************/
|
|
|
|
/** \addtogroup group_hal_results_uart UART HAL Results
|
|
* UART specific return codes
|
|
* \ingroup group_hal_results
|
|
* \{ *//**
|
|
*/
|
|
/** The requested resource type is invalid */
|
|
#define CYHAL_UART_RSLT_ERR_INVALID_PIN \
|
|
(CYHAL_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_UART, 0))
|
|
/** Failed to configure power management callback */
|
|
#define CYHAL_UART_RSLT_ERR_PM_CALLBACK \
|
|
(CYHAL_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_UART, 1))
|
|
/** The getc call timed out with no received data */
|
|
#define CY_RSLT_ERR_CSP_UART_GETC_TIMEOUT \
|
|
(CYHAL_RSLT_CREATE(CY_RSLT_TYPE_ERROR, CYHAL_RSLT_MODULE_UART, 2))
|
|
/** The actual baud rate is greater than 10% off the requested baud rate */
|
|
#define CY_RSLT_WRN_CSP_UART_BAUD_TOLERANCE \
|
|
(CYHAL_RSLT_CREATE(CY_RSLT_TYPE_WARNING, CYHAL_RSLT_MODULE_UART, 3))
|
|
|
|
/**
|
|
* \}
|
|
*/
|
|
|
|
/** The baud rate to set to if no clock is specified in the init function */
|
|
#define CYHAL_UART_DEFAULT_BAUD 115200
|
|
/** The maximum allowable difference between baud requested and actual baud **/
|
|
#define CYHAL_UART_MAX_BAUD_PERCENT_DIFFERENCE 10
|
|
|
|
|
|
/****************************************************************
|
|
* Enumerations
|
|
*****************************************************************/
|
|
|
|
|
|
/** UART Parity */
|
|
typedef enum
|
|
{
|
|
CYHAL_UART_PARITY_NONE, /**< UART has no parity check */
|
|
CYHAL_UART_PARITY_EVEN, /**< UART has even parity check */
|
|
CYHAL_UART_PARITY_ODD, /**< UART has odd parity check */
|
|
} cyhal_uart_parity_t;
|
|
|
|
/** Enum to enable/disable/report interrupt cause flags. */
|
|
typedef enum
|
|
{
|
|
CYHAL_UART_IRQ_NONE = 0, //!< No interrupt
|
|
CYHAL_UART_IRQ_TX_TRANSMIT_IN_FIFO = 1 << 1, //!< All tx data from transmit has been moved to UART FIFO
|
|
CYHAL_UART_IRQ_TX_DONE = 1 << 2, //!< All tx data has been transmitted
|
|
CYHAL_UART_IRQ_TX_ERROR = 1 << 3, //!< An error occurred in tx
|
|
CYHAL_UART_IRQ_RX_FULL = 1 << 4, //!< The rx software buffer is full, additional data are store into fifo buffer.
|
|
CYHAL_UART_IRQ_RX_DONE = 1 << 5, //!< All rx data has been received
|
|
CYHAL_UART_IRQ_RX_ERROR = 1 << 6, //!< An error occurred in rx
|
|
CYHAL_UART_IRQ_RX_NOT_EMPTY = 1 << 7, //!< The rx hardware buffer is not empty
|
|
CYHAL_UART_IRQ_TX_EMPTY = 1 << 8, //!< The tx hardware buffer is empty
|
|
} cyhal_uart_event_t;
|
|
|
|
/** UART FIFO type */
|
|
typedef enum
|
|
{
|
|
CYHAL_UART_FIFO_RX, //!< Set RX FIFO level
|
|
CYHAL_UART_FIFO_TX, //!< Set TX FIFO level
|
|
} cyhal_uart_fifo_type_t;
|
|
|
|
/** Enum of possible output signals from a UART */
|
|
typedef enum
|
|
{
|
|
CYHAL_UART_OUTPUT_TRIGGER_RX_FIFO_LEVEL_REACHED, //!< Output the RX FIFO signal which is triggered when the receive FIFO has more entries than the configured level.
|
|
CYHAL_UART_OUTPUT_TRIGGER_TX_FIFO_LEVEL_REACHED, //!< Output the TX FIFO signal which is triggered when the transmit FIFO has less entries than the configured level.
|
|
} cyhal_uart_output_t;
|
|
|
|
/****************************************************************
|
|
* Typedef
|
|
*****************************************************************/
|
|
|
|
/** @brief Initial UART configuration */
|
|
|
|
typedef struct
|
|
{
|
|
uint32_t data_bits; //!< The number of data bits (generally 8 or 9)
|
|
uint32_t stop_bits; //!< The number of stop bits (generally 0 or 1)
|
|
cyhal_uart_parity_t parity; //!< The parity
|
|
uint8_t *rx_buffer; //!< The rx software buffer pointer, if NULL, no rx software buffer will be used
|
|
uint32_t rx_buffer_size; //!< The number of bytes in the rx software buffer
|
|
} cyhal_uart_cfg_t;
|
|
|
|
|
|
/** UART callback function type */
|
|
typedef void (*cyhal_uart_event_callback_t)(void *callback_arg, cyhal_uart_event_t event);
|
|
|
|
/*******************************************************************************
|
|
* Functions
|
|
*******************************************************************************/
|
|
|
|
/** Initialize the UART peripheral.
|
|
*
|
|
* \note This will set the baud rate to a default of \ref CYHAL_UART_DEFAULT_BAUD. This can
|
|
* be changed by calling \ref cyhal_uart_set_baud.
|
|
*
|
|
* @param[out] obj Pointer to a UART object. The caller must allocate the memory
|
|
* for this object but the init function will initialize its contents.
|
|
* @param[in] tx The TX pin name, if no TX pin use NC
|
|
* @param[in] rx The RX pin name, if no RX pin use NC
|
|
* @param[in] clk The clock to use can be shared. If not provided, a new clock will be
|
|
* allocated and the default baud rate will be set
|
|
* @param[in] cfg The UART configuration data for data bits, stop bits and parity.
|
|
* If not provided, default values of (8, 1, none) will be used
|
|
* @return The status of the init request
|
|
*/
|
|
cy_rslt_t cyhal_uart_init(cyhal_uart_t *obj, cyhal_gpio_t tx, cyhal_gpio_t rx, const cyhal_clock_t *clk, const cyhal_uart_cfg_t *cfg);
|
|
|
|
/** Release the UART peripheral.
|
|
*
|
|
* @param[in,out] obj The UART object
|
|
*/
|
|
void cyhal_uart_free(cyhal_uart_t *obj);
|
|
|
|
/** Configure the baud rate
|
|
*
|
|
* @note This function should only be called if a shared clock divider is not used i.e. the clock
|
|
* parameter is set to NULL when calling \ref cyhal_uart_init.
|
|
*
|
|
* @param[in,out] obj The UART object
|
|
* @param[in] baudrate The baud rate to be configured
|
|
* @param[out] actualbaud The actual baud rate achieved by the HAL
|
|
* Specify NULL if you do not want this information.
|
|
* @return The status of the set_baud request
|
|
*/
|
|
cy_rslt_t cyhal_uart_set_baud(cyhal_uart_t *obj, uint32_t baudrate, uint32_t *actualbaud);
|
|
|
|
/** Configure the data bits, stop bits, and parity
|
|
*
|
|
* @param[in,out] obj The UART object
|
|
* @param[in] cfg The UART configuration data for data bits, stop bits and parity.
|
|
* rx_buffer and rx_buffer_size are ignored.
|
|
* @return The status of the configure request
|
|
*/
|
|
cy_rslt_t cyhal_uart_configure(cyhal_uart_t *obj, const cyhal_uart_cfg_t *cfg);
|
|
|
|
/** Get a character. This is a blocking call which waits till a character is received.
|
|
*
|
|
* @param[in] obj The UART object
|
|
* @param[out] value The value read from the serial port
|
|
* @param[in] timeout The time in ms to spend attempting to receive from serial port.
|
|
* Zero is wait forever
|
|
* @return The status of the getc request
|
|
*/
|
|
cy_rslt_t cyhal_uart_getc(cyhal_uart_t *obj, uint8_t *value, uint32_t timeout);
|
|
|
|
/** Send a character. This is a blocking call which waits till the character is sent out from the UART completley.
|
|
*
|
|
* @param[in] obj The UART object
|
|
* @param[in] value The character to be sent
|
|
* @return The status of the putc request
|
|
*/
|
|
cy_rslt_t cyhal_uart_putc(cyhal_uart_t *obj, uint32_t value);
|
|
|
|
/** Check the number of bytes available to read from the receive buffers
|
|
*
|
|
* @param[in] obj The UART object
|
|
* @return The number of readable bytes
|
|
*/
|
|
uint32_t cyhal_uart_readable(cyhal_uart_t *obj);
|
|
|
|
/** Check the number of bytes than can be written to the transmit buffer
|
|
*
|
|
* @param[in] obj The UART object
|
|
* @return The number of bytes that can be written
|
|
*/
|
|
uint32_t cyhal_uart_writable(cyhal_uart_t *obj);
|
|
|
|
/** Clear the UART buffers
|
|
*
|
|
* @param[in] obj The UART object
|
|
* @return The status of the clear request
|
|
*/
|
|
cy_rslt_t cyhal_uart_clear(cyhal_uart_t *obj);
|
|
|
|
/** Configure the UART for the flow control. It sets flow control in the hardware
|
|
* if a UART peripheral supports it, otherwise software emulation is used.
|
|
*
|
|
* @param[in,out] obj The UART object
|
|
* @param[in] cts The TX pin name
|
|
* @param[in] rts The RX pin name
|
|
* @return The status of the init_flow_control request
|
|
*/
|
|
cy_rslt_t cyhal_uart_set_flow_control(cyhal_uart_t *obj, cyhal_gpio_t cts, cyhal_gpio_t rts);
|
|
|
|
/** Begin synchronous TX transfer.
|
|
*
|
|
* This will write either `length` bytes or until the write buffer is full, whichever is less,
|
|
* then return. The value pointed to by `length` will be updated to reflect the number of bytes
|
|
* that were actually written.
|
|
*
|
|
* @param[in] obj The UART object
|
|
* @param[in] tx The transmit buffer
|
|
* @param[in,out] tx_length [in] The number of bytes to transmit, [out] number actually transmitted
|
|
* @return The status of the tx request
|
|
*/
|
|
cy_rslt_t cyhal_uart_write(cyhal_uart_t *obj, void *tx, size_t *tx_length);
|
|
|
|
/** Begin synchronous RX transfer (enable interrupt for data collecting)
|
|
*
|
|
* This will read either `length` bytes or the number of bytes that are currently available in the
|
|
* receive buffer, whichever is less, then return. The value pointed to by `length` will be updated
|
|
* to reflect the number of bytes that were actually read.
|
|
*
|
|
* @param[in] obj The UART object
|
|
* @param[in] rx The receive buffer
|
|
* @param[in,out] rx_length [in] The number of bytes to receive, [out] number actually received
|
|
* @return The status of the rx request
|
|
*/
|
|
cy_rslt_t cyhal_uart_read(cyhal_uart_t *obj, void *rx, size_t *rx_length);
|
|
|
|
/** Begin asynchronous TX transfer.
|
|
*
|
|
* This will transfer `length` bytes into the buffer pointed to by `rx` in the background. When the
|
|
* requested quantity of data has been read, the @ref CYHAL_UART_IRQ_TX_TRANSMIT_IN_FIFO event will
|
|
* be raised. The transmit buffer is a user defined buffer that will be sent on the UART. The user
|
|
* must register a callback with \ref cyhal_uart_register_callback. If desired, TX callback
|
|
* events can be enabled using \ref cyhal_uart_enable_event with the appropriate events.
|
|
*
|
|
* @param[in] obj The UART object
|
|
* @param[in] tx The transmit buffer
|
|
* @param[in] length The number of bytes to transmit
|
|
* @return The status of the tx_async request
|
|
*/
|
|
cy_rslt_t cyhal_uart_write_async(cyhal_uart_t *obj, void *tx, size_t length);
|
|
|
|
/** Begin asynchronous RX transfer.
|
|
*
|
|
* This will transfer `length` bytes into the buffer pointed to by `rx` in the background. When the
|
|
* requested quantity of data has been read, the @ref CYHAL_UART_IRQ_RX_DONE event will be raised.
|
|
* Received data is placed in the user specified buffer. The user must register a callback with
|
|
* \ref cyhal_uart_register_callback. RX callback events can be enabled using \ref
|
|
* cyhal_uart_enable_event with the appropriate events.
|
|
*
|
|
* @param[in] obj The UART object
|
|
* @param[out] rx The user specified receive buffer
|
|
* @param[in] length The number of bytes to receive
|
|
* @return The status of the rx_async request
|
|
*/
|
|
cy_rslt_t cyhal_uart_read_async(cyhal_uart_t *obj, void *rx, size_t length);
|
|
|
|
/** Attempts to determine if the UART peripheral is already in use for TX
|
|
*
|
|
* @param[in] obj The UART object
|
|
* @return Is the TX channel active
|
|
*/
|
|
bool cyhal_uart_is_tx_active(cyhal_uart_t *obj);
|
|
|
|
/** Attempts to determine if the UART peripheral is already in use for RX
|
|
*
|
|
* @param[in] obj The UART object
|
|
* @return Is the RX channel active
|
|
*/
|
|
bool cyhal_uart_is_rx_active(cyhal_uart_t *obj);
|
|
|
|
/** Abort the ongoing TX transaction. It disables the enabled interupt for TX and
|
|
* flushes the TX hardware buffer if TX FIFO is used
|
|
*
|
|
* @param[in] obj The UART object
|
|
* @return The status of the tx_abort request
|
|
*/
|
|
cy_rslt_t cyhal_uart_write_abort(cyhal_uart_t *obj);
|
|
|
|
/** Abort the ongoing read transaction. It disables the enabled interrupt for RX and
|
|
* flushes the RX hardware buffer if RX FIFO is used
|
|
*
|
|
* @param[in] obj The UART object
|
|
* @return The status of the read_abort request
|
|
*/
|
|
cy_rslt_t cyhal_uart_read_abort(cyhal_uart_t *obj);
|
|
|
|
/** Register a uart callback handler
|
|
*
|
|
* This function will be called when one of the events enabled by \ref cyhal_uart_enable_event occurs.
|
|
*
|
|
* @param[in] obj The UART object
|
|
* @param[in] callback The callback handler which will be invoked when the interrupt fires
|
|
* @param[in] callback_arg Generic argument that will be provided to the callback when called
|
|
*/
|
|
void cyhal_uart_register_callback(cyhal_uart_t *obj, cyhal_uart_event_callback_t callback, void *callback_arg);
|
|
|
|
/** Enable or disable specified UART events.
|
|
*
|
|
* When an enabled event occurs, the function specified by \ref cyhal_uart_register_callback will be called.
|
|
*
|
|
* @param[in] obj The UART object
|
|
* @param[in] event The uart event type, this argument supports the bitwise-or of multiple enum flag values
|
|
* @param[in] intr_priority The priority for NVIC interrupt events
|
|
* @param[in] enable True to turn on interrupts, False to turn off
|
|
*/
|
|
void cyhal_uart_enable_event(cyhal_uart_t *obj, cyhal_uart_event_t event, uint8_t intr_priority, bool enable);
|
|
|
|
/** Sets a threshold level for a FIFO that will generate an interrupt and a
|
|
* trigger output. The RX FIFO interrupt and trigger will be activated when
|
|
* the receive FIFO has more entries than the threshold. The TX FIFO interrupt
|
|
* and trigger will be activated when the transmit FIFO has less entries than
|
|
* the threshold.
|
|
*
|
|
* @param[in] obj The UART object
|
|
* @param[in] type FIFO type to set level for
|
|
* @param[in] level Level threshold to set
|
|
* @return The status of the level set
|
|
* */
|
|
cy_rslt_t cyhal_uart_set_fifo_level(cyhal_uart_t *obj, cyhal_uart_fifo_type_t type, uint16_t level);
|
|
|
|
/** Enables the specified output signal from a UART.
|
|
*
|
|
* @param[in] obj The UART object
|
|
* @param[in] output Which output signal to enable
|
|
* @param[out] source Pointer to user-allocated source signal object which
|
|
* will be initialized by enable_output. \p source should be passed to
|
|
* (dis)connect_digital functions to (dis)connect the associated endpoints.
|
|
* @return The status of the output enable
|
|
* */
|
|
cy_rslt_t cyhal_uart_enable_output(cyhal_uart_t *obj, cyhal_uart_output_t output, cyhal_source_t *source);
|
|
|
|
/** Disables the specified output signal from a UART
|
|
*
|
|
* @param[in] obj The UART object
|
|
* @param[in] output Which output signal to disable
|
|
* @return The status of the output disable
|
|
* */
|
|
cy_rslt_t cyhal_uart_disable_output(cyhal_uart_t *obj, cyhal_uart_output_t output);
|
|
|
|
#if defined(__cplusplus)
|
|
}
|
|
#endif
|
|
|
|
#ifdef CYHAL_UART_IMPL_HEADER
|
|
#include CYHAL_UART_IMPL_HEADER
|
|
#endif /* CYHAL_UART_IMPL_HEADER */
|
|
|
|
/** \} group_hal_uart */
|