Программирование ARM BL602 SDK UART API Sun, September 08 2024  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.

BL602 SDK UART API Печать
Добавил(а) microsin   

Исходный код функций UART находится в модуле hosal_uart.c (см. bl_iot_sdk/components/platform/hosal/bl602_hal/), соответствующие заголовочные файлы в hosal_uart.h, hosal_dma.h (находятся в bl_iot_sdk/components/platform/hosal/include/) и bl_uart.h (находится в bl_iot_sdk/components/platform/hosal/bl602_hal/), а также bl602_uart.h (находится в bl_iot_sdk/components/platform/soc/bl602/bl602_std/bl602_std/StdDriver/Inc/).

hosal_uart.h

#ifndef __HOSAL_UART_H__
#define __HOSAL_UART_H__

#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup hosal_uart UART * HOSAL UART API * * @{ */

#include < stdio.h>
#include < stdint.h>
#include "hosal_dma.h"

#define HOSAL_UART_AUTOBAUD_0X55 1 /**< @brief UART автоматическое детектирование скорости по байту 0x55 */
#define HOSAL_UART_AUTOBAUD_STARTBIT 2 /**< @brief UART автоматическое детектирование скорости по по start-биту */

#define HOSAL_UART_TX_CALLBACK 1 /**< @brief UART tx idle interrupt callback */
#define HOSAL_UART_RX_CALLBACK 2 /**< @brief UART rx complete callback */
#define HOSAL_UART_TX_DMA_CALLBACK 3 /**< @brief UART tx DMA trans complete callback */
#define HOSAL_UART_RX_DMA_CALLBACK 4 /**< @brief UART rx DMA trans complete callback */

#define HOSAL_UART_BAUD_SET 1 /**< @brief UART baud set */
#define HOSAL_UART_BAUD_GET 2 /**< @brief UART baud get */
#define HOSAL_UART_DATA_WIDTH_SET 3 /**< @brief UART data width set */
#define HOSAL_UART_DATA_WIDTH_GET 4 /**< @brief UART data width get */
#define HOSAL_UART_STOP_BITS_SET 5 /**< @brief UART stop bits set */
#define HOSAL_UART_STOP_BITS_GET 6 /**< @brief UART stop bits get */
#define HOSAL_UART_FLOWMODE_SET 7 /**< @brief UART flow mode set */
#define HOSAL_UART_FLOWSTAT_GET 8 /**< @brief UART flow state get */
#define HOSAL_UART_PARITY_SET 9 /**< @brief UART flow mode set */
#define HOSAL_UART_PARITY_GET 10 /**< @brief UART flow state get */
#define HOSAL_UART_MODE_SET 11 /**< @brief UART mode set */
#define HOSAL_UART_MODE_GET 12 /**< @brief UART mode get */
#define HOSAL_UART_FREE_TXFIFO_GET 13 /**< @brief UART free tx fifo get */
#define HOSAL_UART_FREE_RXFIFO_GET 14 /**< @brief UART free rx fifo get */
#define HOSAL_UART_FLUSH 15 /**< @brief Ожидание завершения передачи */
#define HOSAL_UART_TX_TRIGGER_ON 16 /**< @brief UART TX trigger on */
#define HOSAL_UART_TX_TRIGGER_OFF 17 /**< @brief UART TX trigger off */
#define HOSAL_UART_DMA_TX_START 18 /**< @brief UART DMA TX start trans */
#define HOSAL_UART_DMA_RX_START 19 /**< @brief UART DMA RX start trans */

/**
* @brief hosal uart callback * * @param[in] p_arg Набор пользовательских параметров, который устанавливается * в момент привязки callback-функции. * * @return * - 0 : успех * - EIO : если произошла ошибка на любом шаге */
typedef int (*hosal_uart_callback_t)(void *p_arg);

/** * @brief ширина фрейма UART */
typedef enum { HOSAL_DATA_WIDTH_5BIT, HOSAL_DATA_WIDTH_6BIT, HOSAL_DATA_WIDTH_7BIT, HOSAL_DATA_WIDTH_8BIT, HOSAL_DATA_WIDTH_9BIT } hosal_uart_data_width_t;

/** * @brief количество стоп-бит */
typedef enum { HOSAL_STOP_BITS_1 = 1, HOSAL_STOP_BITS_2 = 3 } hosal_uart_stop_bits_t;

/** * @brief управление потоком UART (flow control) */
typedef enum { HOSAL_FLOW_CONTROL_DISABLED, HOSAL_FLOW_CONTROL_RTS, HOSAL_FLOW_CONTROL_CTS, HOSAL_FLOW_CONTROL_CTS_RTS } hosal_uart_flow_control_t;

/** * @brief настройка проверки четности UART (parity) */
typedef enum { HOSAL_NO_PARITY, HOSAL_ODD_PARITY, HOSAL_EVEN_PARITY } hosal_uart_parity_t;

/** * @brief режим работы UART */
typedef enum { HOSAL_UART_MODE_POLL, /**< @brief режим по опросу (по умолчанию) */ HOSAL_UART_MODE_INT_TX, /**< @brief UART TX int mode */ HOSAL_UART_MODE_INT_RX, /**< @brief UART RX int mode */ HOSAL_UART_MODE_INT, /**< @brief UART TX и RX int mode */ } hosal_uart_mode_t;

/** * @brief Конфигурация UART DMA */
typedef struct { /** * @brief UART DMA trans buffer * Адрес источника для передачи (TX), или адрес назначения для приема (RX) */ uint8_t *dma_buf; uint32_t dma_buf_size; /**< @brief размер буфера транзакции UART DMA */ } hosal_uart_dma_cfg_t;

/** * @brief Конфигурация UART */
typedef struct { uint8_t uart_id;/**< @brief UART id */ uint8_t tx_pin;/**< @brief UART tx pin */ uint8_t rx_pin;/**< @brief UART rx pin */ uint8_t cts_pin;/**< @brief UART cts pin */ uint8_t rts_pin;/**< @brief UART rts pin */ uint32_t baud_rate;/**< @brief UART baud rate */ hosal_uart_data_width_t data_width;/**< @brief UART data width */ hosal_uart_parity_t parity;/**< @brief UART parity bit */ hosal_uart_stop_bits_t stop_bits;/**< @brief UART stop-биты */ hosal_uart_flow_control_t flow_control;/**< @brief UART flow control */ hosal_uart_mode_t mode;/**< @brief UART int или poll mode */ } hosal_uart_config_t;

/** * @brief тип устройства UART */
typedef struct { uint8_t port;/**< @brief UART port */ hosal_uart_config_t config;/**< @brief UART config */ hosal_uart_callback_t tx_cb;/**< @brief UART tx callback */ void *p_txarg;/**< @brief UART tx callback arg */ hosal_uart_callback_t rx_cb;/**< @brief UART rx callback */ void *p_rxarg;/**< @brief UART rx callback arg */ hosal_uart_callback_t txdma_cb;/**< @brief UART tx dma callback */ void *p_txdma_arg;/**< @brief UART tx dma callback arg */ hosal_uart_callback_t rxdma_cb;/**< @brief UART rx dma callback */ void *p_rxdma_arg;/**< @brief UART rx dma callback arg */ hosal_dma_chan_t dma_tx_chan;/**< @brief UART dma tx channel */ hosal_dma_chan_t dma_rx_chan;/**< @brief UART dma rx channel */ void *priv;/**< @brief UART private data */ } hosal_uart_dev_t;

/** * @brief Конфигурация UART по умолчанию * * @param[in] cfg переменная конфига * @param[in] id uart id * @param[in] tx uart tx pin * @param[in] rx uart rx pin * @param[in] baud скорость uart * */
#define HOSAL_UART_CFG_DECL(cfg, id, tx, rx, baud) \ hosal_uart_config_t cfg = { \ .uart_id = id, \ .tx_pin = tx, \ .rx_pin = rx, \ .cts_pin = 255, \ .rts_pin = 255, \ .baud_rate = baud, \ .data_width = HOSAL_DATA_WIDTH_8BIT, \ .parity = HOSAL_NO_PARITY, \ .stop_bits = HOSAL_STOP_BITS_1, \ .mode = HOSAL_UART_MODE_POLL, \ };

/** * @brief Определение устройства UART * * @param[in] dev устройство uart * @param[in] id uart id * @param[in] tx uart tx pin * @param[in] rx uart rx pin * @param[in] baud скорость uart */
#define HOSAL_UART_DEV_DECL(dev, id, tx, rx, baud) \ hosal_uart_dev_t dev = { \ .config = { \ .uart_id = id, \ .tx_pin = tx, \ .rx_pin = rx, \ .cts_pin = 255, \ .rts_pin = 255, \ .baud_rate = baud, \ .data_width = HOSAL_DATA_WIDTH_8BIT, \ .parity = HOSAL_NO_PARITY, \ .stop_bits = HOSAL_STOP_BITS_1, \ .mode = HOSAL_UART_MODE_POLL, \ }, \ };

/** * @brief Автоопределение скорости на интерфейсе UART * * @param[in] uart интерфейс (0 или 1) * @param[in] mode auto baudrate detection mode (по байту 0x55 * или длительности start-бита) * * @return * - = 0 успех * - EIO если на любом шаге произошла ошибка */
int hosal_uart_abr_get(hosal_uart_dev_t *uart, uint8_t mode);

/** * @brief Инициализирует интерфейс UART * * @param[in] uart инициализируемый интерфейс (0 или 1) * * @return * - 0 успех * - EIO если на любом шаге произошла ошибка */
int hosal_uart_init(hosal_uart_dev_t *uart);

/** * @brief Передача с опросом завершения * * @param[in] uart интерфейс (0 или 1) * @param[in] txbuf указатель на начало данных * @param[in] size количество передаваемых байт * * @return * - > 0 on success * - EIO если на любом шаге произошла ошибка */
int hosal_uart_send(hosal_uart_dev_t *uart, const void *txbuf, uint32_t size);

/** * @brief Прием данных через UART с опросом завершения * * @param[in] uart интерфейс (0 или 1) * @param[out] rxbuf указатель на буфер, который будет сохранять приходящие данные * @param[in] expect_size ожидаемое количество принимаемых байт * * @return * - > 0 количество принятых байт (если 0, то это успешный возврат, * но ни одного байта не принято) * - EIO если на любом шаге произошла ошибка */
int hosal_uart_receive(hosal_uart_dev_t *uart, void *data, uint32_t expect_size);

/** * @brief hal uart ioctl * * @param[in] uart интерфейс (0 или 1) * @param[in] ctl Управляющий запрос * - HOSAL_UART_BAUD_SET : установка скорости, в p_arg скорость baud * - HOSAL_UART_BAUD_GET : получение скорости, в p_arg указатель на ячейку для скорости * - HOSAL_UART_DATA_WIDTH_SET : установка ширины (количества бит) кадра, в p_arg hosal_uart_data_width_t * - HOSAL_UART_DATA_WIDTH_GET : получение ширины кадра, в p_arg указатель на значение hosal_uart_data_width_t * - HOSAL_UART_STOP_BITS_SET : установка количества stop-бит, в p_arg hosal_uart_stop_bits_t * - HOSAL_UART_STOP_BITS_GET : получение количества stop-бит, в p_arg указатель на hosal_uart_stop_bits_t * - HOSAL_UART_PARITY_SET : установка parity, в p_arg hosal_uart_parity_t * - HOSAL_UART_PARITY_GET : получение parity, в p_arg указатель на hosal_uart_parity_t * - HOSAL_UART_MODE_SET : установка режима UART, в p_arg hosal_uart_mode_t * - HOSAL_UART_MODE_GET : получение режима UART, в p_arg указатель на hosal_uart_mode_t * - HOSAL_UART_FLOWMODE_SET : установка управления потоком UART, в p_arg hosal_uart_flow_control_t * - HOSAL_UART_FLOWSTAT_GET : получение управления потоком UART, в p_arg указатель на hosal_uart_flow_control_t * - HOSAL_UART_FREE_TXFIFO_GET : получение свободного пространства в буфере tx fifo (в байтах) * - HOSAL_UART_FREE_RXFIFO_GET : получение свободного пространства в буфере rx fifo (в байтах) * - HOSAL_UART_FLUSH : ожидание завершения передачи * - HOSAL_UART_TX_TRIGGER_ON : UART TX trigger on * - HOSAL_UART_TX_TRIGGER_OFF : UART TX trigger off * - HOSAL_UART_DMA_CONFIG : в p_arg указатель на hosal_uart_dma_cfg_t * - HOSAL_UART_DMA_TX_START : запуск транзакции UART DMA TX, в p_arg указатель на hosal_uart_dma_cfg_t * - HOSAL_UART_DMA_RX_START : запуск транзакции UART DMA RX, в p_arg указатель на hosal_uart_dma_cfg_t * * @param[in,out] p_arg параметр * * @return * - 0 успех * - EIO если на любом шаге произошла ошибка */int hosal_uart_ioctl (hosal_uart_dev_t *uart, int ctl, void *p_arg);

/** * @brief hal-привязка uart callback * * @param[in] uart интерфейс (0 или 1) * @param[in] callback_type тип callback * - HOSAL_UART_TX_CALLBACK * - HOSAL_UART_RX_CALLBACK * - HOSAL_UART_TX_DMA_CALLBACK * - HOSAL_UART_RX_DMA_CALLBACK * @param[in] pfn_callback callback-функция * @param[in] arg параметр callback-функции * * @return * - 0 успех * - EIO если на любом шаге произошла ошибка */
int hosal_uart_callback_set (hosal_uart_dev_t *uart, int callback_type, hosal_uart_callback_t pfn_callback, void *arg);
/** * @brief Отменяет инициализацию интерфейса UART * * @param[in] uart интерфейс (0 или 1) * * @return * - 0 успех * - EIO если на любом шаге произошла ошибка */
int hosal_uart_finalize(hosal_uart_dev_t *uart);

/** @} */
#ifdef __cplusplus }
#endif

#endif /* __HOSAL_UART_H__ */

hosal_dma.h

#ifndef __HOSAL_DMA_H__
#define __HOSAL_DMA_H__

#ifdef __cplusplus
extern "C" {
#endif

/** @addtogroup hosal_dma DMA * HOSAL DMA API * * @{ */

#include < stdint.h>
#include < stdio.h>

/** * @brief Флаги прерываний callback-функции DMA */
#define HOSAL_DMA_INT_TRANS_COMPLETE 0
#define HOSAL_DMA_INT_TRANS_ERROR 1

/** * @brief callback-функция прерывания DMA */
typedef void (*hosal_dma_irq_t)(void *p_arg, uint32_t flag);

/** * @brief Описание канала DMA */
struct hosal_dma_chan { uint8_t used; hosal_dma_irq_t callback; void *p_arg; };

/** * @brief Тип устройства DMA */
typedef struct hosal_dma_dev { int max_chans; struct hosal_dma_chan *used_chan; void *priv; } hosal_dma_dev_t;

/** * @brief Канал DMA */
typedef int hosal_dma_chan_t;

/** * @brief Инициализирует интерфейс DMA * * @return 0 : успех, EIO : если на любом шаге произошла ошибка */
int hosal_dma_init(void);

/** * @brief Запрос канала DMA * * @param[in] flag : DMA CHAN REQUEST FLAG * * @return < 0 : если на любом шаге произошла ошибка, иначе номер канала DMA */
hosal_dma_chan_t hosal_dma_chan_request(int flag);

/** * @brief Освобождение канала DMA * * @param[in] chan номер канала DMA * * @return 0 : успех, EIO : если на любом шаге произошла ошибка */
int hosal_dma_chan_release(hosal_dma_chan_t chan);

/** * @brief Запуск транзакции канала DMA * * @param[in] chan номер канала DMA * * @return 0 : успех, или EIO : если на любом шаге произошла ошибка */
int hosal_dma_chan_start(hosal_dma_chan_t chan);

/** * @brief Остановка транзакции канала DMA * * @param[in] chan номер канала DMA * * @return 0 : успех, или EIO : если на любом шаге произошла ошибка */
int hosal_dma_chan_stop(hosal_dma_chan_t chan);

/** * @brief Установка callback-функции канала DMA * * @param[in] chan : номер канала DMA * @param[in] pfn : callback-функция * @param[in] arg : параметр callback-функции * * @return 0 : успех, или EIO : если на любом шаге произошла ошибка */
int hosal_dma_irq_callback_set(hosal_dma_chan_t chan, hosal_dma_irq_t pfn, void *p_arg);

/** * @brief Отмена инициализации интерфейса DMA * * @param[in] интерфейс DMA, который должен быть деинициализирован * * @return 0 : успех, или EIO : если на любом шаге произошла ошибка */
int hosal_dma_finalize(void);

/** @} */
#ifdef __cplusplus }

#endif
#endif /* __HOSAL_DMA_H__ */

bl_uart.h

#ifndef __BL_UART_H__
#define __BL_UART_H__

#include < stdint.h>
#include < bl602_uart.h>

#define BL_UART_BUFFER_SIZE_MIN (128)
#define BL_UART_BUFFER_SIZE_MASK (128 - 1)

typedef void (*cb_uart_notify_t)(void *arg);

int bl_uart_gpio_init(uint8_t id, uint8_t tx, uint8_t rx, uint8_t rts, uint8_t cts, int baudrate);
int bl_uart_init(uint8_t id, uint8_t tx_pin, uint8_t rx_pin, uint8_t cts_pin, uint8_t rts_pin, uint32_t baudrate);
int bl_uart_debug_early_init(uint32_t baudrate);
int bl_uart_early_init(uint8_t id, uint8_t tx_pin, uint32_t baudrate);

int bl_uart_int_rx_enable(uint8_t id);
int bl_uart_int_rx_disable(uint8_t id);
int bl_uart_int_tx_enable(uint8_t id);
int bl_uart_int_tx_disable(uint8_t id);
int bl_uart_string_send(uint8_t id, char *data);
int bl_uart_flush(uint8_t id);
void bl_uart_getdefconfig(uint8_t id, uint8_t *parity);
void bl_uart_setconfig(uint8_t id, uint32_t baudrate, UART_Parity_Type parity);
void bl_uart_setbaud(uint8_t id, uint32_t baud);
int bl_uart_data_send(uint8_t id, uint8_t data);
int bl_uart_datas_send(uint8_t id, uint8_t *data, int len);
int bl_uart_data_recv(uint8_t id);
int bl_uart_int_enable(uint8_t id);
int bl_uart_int_disable(uint8_t id);
int bl_uart_int_rx_notify_register(uint8_t id, cb_uart_notify_t cb, void *arg);
int bl_uart_int_tx_notify_register(uint8_t id, cb_uart_notify_t cb, void *arg);
int bl_uart_int_rx_notify_unregister(uint8_t id, cb_uart_notify_t cb, void *arg);
int bl_uart_int_tx_notify_unregister(uint8_t id, cb_uart_notify_t cb, void *arg);

#endif

bl602_uart.h

#include "uart_reg.h"
#include "bl602_common.h"

/** @addtogroup BL602_Peripheral_Driver * @{ */

/** @addtogroup UART * @{ */

/** @defgroup UART_Public_Types * @{ */

/** * @brief UART port type definition */
typedef enum { UART0_ID, /*!< UART0 port define */ UART1_ID, /*!< UART1 port define */ UART_ID_MAX, /*!< UART MAX ID define */ }UART_ID_Type;

/** * @brief UART direction type definition */
typedef enum { UART_TX, /*!< UART TX Direction */ UART_RX, /*!< UART RX Direction */ UART_TXRX, /*!< UART TX and RX Direction */ }UART_Direction_Type;

/** * @brief UART parity type definition */
typedef enum { UART_PARITY_NONE, /*!< UART parity none define */ UART_PARITY_ODD, /*!< UART parity odd define */ UART_PARITY_EVEN, /*!< UART parity even define */ }UART_Parity_Type;

/** * @brief UART data bits type definiton */
typedef enum { UART_DATABITS_5, /*!< UART data bits length:5 bits */ UART_DATABITS_6, /*!< UART data bits length:6 bits */ UART_DATABITS_7, /*!< UART data bits length:7 bits */ UART_DATABITS_8, /*!< UART data bits length:8 bits */ }UART_DataBits_Type;

/** * @brief UART stop bits type definiton */typedef enum { UART_STOPBITS_0_5, /*!< UART data stop bits length:0.5 bits */ UART_STOPBITS_1, /*!< UART data stop bits length:1 bits */ UART_STOPBITS_1_5, /*!< UART data stop bits length:1.5 bits */ UART_STOPBITS_2, /*!< UART data stop bits length:2 bits */ }UART_StopBits_Type;

/** * @brief Определение, как отправляется каждый байт UART: * старшим байтом (MSB) вперед, или наоборот, младшим * байтом (LSB) вперед. */
typedef enum { UART_LSB_FIRST, /*!< младший бит идет впереди */ UART_MSB_FIRST, /*!< старший бит идет впереди */ }UART_ByteBitInverse_Type;

/** * @brief UART auto baudrate detection using codeword 0x55 or start bit definiton */
typedef enum { UART_AUTOBAUD_0X55, /*!< UART auto baudrate detection using codeword 0x55 */ UART_AUTOBAUD_STARTBIT, /*!< UART auto baudrate detection using start bit */ }UART_AutoBaudDetection_Type;

/** * @brief UART interrupt type definition */
typedef enum { UART_INT_TX_END, /*!< UART tx transfer end interrupt */ UART_INT_RX_END, /*!< UART rx transfer end interrupt */ UART_INT_TX_FIFO_REQ, /*!< UART tx fifo interrupt when tx fifo count reaches,auto clear */ UART_INT_RX_FIFO_REQ, /*!< UART rx fifo interrupt when rx fifo count reaches,auto clear */ UART_INT_RTO, /*!< UART rx time-out interrupt */ UART_INT_PCE, /*!< UART rx parity check error interrupt */ UART_INT_TX_FER, /*!< UART tx fifo overflow/underflow error interrupt */ UART_INT_RX_FER, /*!< UART rx fifo overflow/underflow error interrupt */ UART_INT_ALL, /*!< All the interrupt */ }UART_INT_Type;

/** * @brief Определение типа переполнения (overflow) или недогрузки (underflow) UART */
typedef enum { UART_TX_OVERFLOW, /*!< UART tx fifo overflow */ UART_TX_UNDERFLOW, /*!< UART tx fifo underflow */ UART_RX_OVERFLOW, /*!< UART rx fifo overflow */ UART_RX_UNDERFLOW, /*!< UART rx fifo underflow */ }UART_Overflow_Type;

/** * @brief UART configuration structure type definition */
typedef struct { uint32_t uartClk; /*!< Uart module clock */ uint32_t baudRate; /*!< Uart baudrate */ UART_DataBits_Type dataBits; /*!< Uart frame length of data bit */ UART_StopBits_Type stopBits; /*!< Uart frame length of stop bit */ UART_Parity_Type parity; /*!< Uart parity check type */ BL_Fun_Type ctsFlowControl; /*!< Enable or disable tx CTS flow control */ BL_Fun_Type rxDeglitch; /*!< Enable or disable rx input de-glitch function */ BL_Fun_Type rtsSoftwareControl; /*!< Enable or disable rx RTS output SW control mode */ UART_ByteBitInverse_Type byteBitInverse; /*!< Uart each data byte is send out LSB-first or MSB-first */ }UART_CFG_Type;

/** * @brief UART FIFO configuration structure type definition */
typedef struct { uint8_t txFifoDmaThreshold; /*!< порог TX FIFO, dma tx request не будет выставлен, если счетчик tx fifo меньше этого значения */ uint8_t rxFifoDmaThreshold; /*!< порог RX FIFO, dma rx request не будет выставлен, если счетчик rx fifo меньше этого значения */ BL_Fun_Type txFifoDmaEnable; /*!< разрешить или запретить интерфейс tx dma req/ack */ BL_Fun_Type rxFifoDmaEnable; /*!< разрешить или запретить интерфейс rx dma req/ack */ }UART_FifoCfg_Type;

/** * @brief UART infrared configuration structure type definition */
typedef struct { BL_Fun_Type txIrEnable; /*!< Enable or disable uart tx ir mode */ BL_Fun_Type rxIrEnable; /*!< Enable or disable uart rx ir mode */ BL_Fun_Type txIrInverse; /*!< Enable or disable inverse signal of uart tx output in ir mode */ BL_Fun_Type rxIrInverse; /*!< Enable or disable inverse signal of uart rx input in ir mode */ uint16_t txIrPulseStart; /*!< Set start position of uart tx ir pulse */ uint16_t txIrPulseStop; /*!< Set stop position of uart tx ir pulse */ uint16_t rxIrPulseStart; /*!< Set start position of uart rx pulse recovered from ir signal */ }UART_IrCfg_Type;

/*@} end of group UART_Public_Types */

/** @defgroup UART_Public_Constants * @{ */

/** @defgroup UART_ID_TYPE * @{ */
#define IS_UART_ID_TYPE(type) (((type) == UART0_ID) || \ ((type) == UART1_ID) || \ ((type) == UART_ID_MAX))

/** @defgroup UART_DIRECTION_TYPE * @{ */
#define IS_UART_DIRECTION_TYPE(type) (((type) == UART_TX) || \ ((type) == UART_RX) || \ ((type) == UART_TXRX))

/** @defgroup UART_PARITY_TYPE * @{ */
#define IS_UART_PARITY_TYPE(type) (((type) == UART_PARITY_NONE) || \ ((type) == UART_PARITY_ODD) || \ ((type) == UART_PARITY_EVEN))

/** @defgroup UART_DATABITS_TYPE * @{ */
#define IS_UART_DATABITS_TYPE(type) (((type) == UART_DATABITS_5) || \ ((type) == UART_DATABITS_6) || \ ((type) == UART_DATABITS_7) || \ ((type) == UART_DATABITS_8))

/** @defgroup UART_STOPBITS_TYPE * @{ */
#define IS_UART_STOPBITS_TYPE(type) (((type) == UART_STOPBITS_1) || \ ((type) == UART_STOPBITS_1_5) || \ ((type) == UART_STOPBITS_2))

/** @defgroup UART_BYTEBITINVERSE_TYPE * @{ */
#define IS_UART_BYTEBITINVERSE_TYPE(type) (((type) == UART_LSB_FIRST) || \ ((type) == UART_MSB_FIRST))

/** @defgroup UART_AUTOBAUDDETECTION_TYPE * @{ */
#define IS_UART_AUTOBAUDDETECTION_TYPE(type) (((type) == UART_AUTOBAUD_0X55) || \ ((type) == UART_AUTOBAUD_STARTBIT))

/** @defgroup UART_INT_TYPE * @{ */
#define IS_UART_INT_TYPE(type) (((type) == UART_INT_TX_END) || \ ((type) == UART_INT_RX_END) || \ ((type) == UART_INT_TX_FIFO_REQ) || \ ((type) == UART_INT_RX_FIFO_REQ) || \ ((type) == UART_INT_RTO) || \ ((type) == UART_INT_PCE) || \ ((type) == UART_INT_TX_FER) || \ ((type) == UART_INT_RX_FER) || \ ((type) == UART_INT_ALL))

/** @defgroup UART_OVERFLOW_TYPE * @{ */
#define IS_UART_OVERFLOW_TYPE(type) (((type) == UART_TX_OVERFLOW) || \ ((type) == UART_TX_UNDERFLOW) || \ ((type) == UART_RX_OVERFLOW) || \ ((type) == UART_RX_UNDERFLOW))

/*@} end of group UART_Public_Constants */

/** @defgroup UART_Public_Macros * @{ */
#define UART_RX_FIFO_SIZE 32
#define UART_TX_FIFO_SIZE 32
#define UART_DEFAULT_RECV_TIMEOUT 80

/*@} end of group UART_Public_Macros */

/** @defgroup UART_Public_Functions * @{ */

/** * @brief UART Functions */
#if (!defined BL602_USE_HAL_DRIVER)||(defined BL602_EFLASH_LOADER)
void UART0_IRQHandler(void);
void UART1_IRQHandler(void);
#endif BL_Err_Type UART_Init(UART_ID_Type uartId,UART_CFG_Type* uartCfg); BL_Err_Type UART_DeInit(UART_ID_Type uartId); BL_Err_Type UART_FifoConfig(UART_ID_Type uartId,UART_FifoCfg_Type* fifoCfg); BL_Err_Type UART_IrConfig(UART_ID_Type uartId,UART_IrCfg_Type* irCfg); BL_Err_Type UART_Enable(UART_ID_Type uartId,UART_Direction_Type direct); BL_Err_Type UART_Disable(UART_ID_Type uartId,UART_Direction_Type direct); BL_Err_Type UART_SetTxDataLength(UART_ID_Type uartId,uint16_t length); BL_Err_Type UART_SetRxDataLength(UART_ID_Type uartId,uint16_t length); BL_Err_Type UART_SetRxTimeoutValue(UART_ID_Type uartId,uint8_t time); BL_Err_Type UART_SetDeglitchCount(UART_ID_Type uartId,uint8_t deglitchCnt); BL_Err_Type UART_SetBaudrate(UART_ID_Type uartId,UART_AutoBaudDetection_Type autoBaudDet); BL_Err_Type UART_SetRtsValue(UART_ID_Type uartId); BL_Err_Type UART_ClrRtsValue(UART_ID_Type uartId); BL_Err_Type UART_TxFreeRun(UART_ID_Type uartId,BL_Fun_Type txFreeRun); BL_Err_Type UART_AutoBaudDetection(UART_ID_Type uartId,BL_Fun_Type autoBaud); BL_Err_Type UART_TxFifoClear(UART_ID_Type uartId); BL_Err_Type UART_RxFifoClear(UART_ID_Type uartId); BL_Err_Type UART_IntMask(UART_ID_Type uartId,UART_INT_Type intType,BL_Mask_Type intMask); BL_Err_Type UART_IntClear(UART_ID_Type uartId,UART_INT_Type intType); BL_Err_Type UART_Int_Callback_Install(UART_ID_Type uartId,UART_INT_Type intType,intCallback_Type* cbFun); BL_Err_Type UART_SendData(UART_ID_Type uartId,uint8_t* data,uint32_t len); BL_Err_Type UART_SendDataBlock(UART_ID_Type uartId,uint8_t* data,uint32_t len);
uint32_t UART_ReceiveData(UART_ID_Type uartId,uint8_t* data,uint32_t maxLen);
uint16_t UART_GetAutoBaudCount(UART_ID_Type uartId,UART_AutoBaudDetection_Type autoBaudDet);
uint8_t UART_GetTxFifoCount(UART_ID_Type uartId);
uint8_t UART_GetRxFifoCount(UART_ID_Type uartId); BL_Sts_Type UART_GetIntStatus(UART_ID_Type uartId,UART_INT_Type intType); BL_Sts_Type UART_GetTxBusBusyStatus(UART_ID_Type uartId); BL_Sts_Type UART_GetRxBusBusyStatus(UART_ID_Type uartId); BL_Sts_Type UART_GetOverflowStatus(UART_ID_Type uartId,UART_Overflow_Type overflow);
uint32_t UART_GetBaudrate(UART_ID_Type uartId);

/*@} end of group UART_Public_Functions */

/*@} end of group UART */

/*@} end of group BL602_Peripheral_Driver */

#endif /* __BL602_UART_H__ */

[Пример использования UART в режиме прерываний]

Настройка может быть выполнена следующим образом, с помощью функции bl_uart_init:

int bl_uart_init(uint8_t id,
                 uint8_t tx_pin,
                 uint8_t rx_pin,
                 uint8_t cts_pin,
                 uint8_t rts_pin,
                 uint32_t baudrate);

// Здесь 255 для параметров cts_pin и rts_pin указывает, что выводы портов
// для аппаратного управления потоком не используются. 2000000 это скорость
// порта UART в бодах (2M). bl_uart_init(UART0_ID, tx_pin, rx_pin, 255, 255, 2000000);

Или можно настроить порт с помощью hosal_uart_init (пример взят из bl_iot_sdk/customer_app/peripheral/demo_uart/demo_uart/demo_uart_int.c для BL602):

//HOSAL_UART_DEV_DECL(uart_dev_int, UART0_ID, 16, 7, 1500000);
hosal_uart_dev_t uart_dev_int = { .config = { .uart_id = UART0_ID, .tx_pin = 16, .rx_pin = 7, .cts_pin = 255, .rts_pin = 255, .baud_rate = 1500000, .data_width = HOSAL_DATA_WIDTH_8BIT, .parity = HOSAL_NO_PARITY, .stop_bits = HOSAL_STOP_BITS_1, .mode = HOSAL_UART_MODE_INT_RX } };

/** * hal uart TX interrupt callback */
static int __uart_tx_callback(void *p_arg) { static uint8_t tx_counts = 0; char buf[] = "TX interrupt TEST\r\n"; hosal_uart_dev_t *p_dev = (hosal_uart_dev_t *)p_arg; if (tx_counts < sizeof(buf)) { hosal_uart_send(p_dev, &buf[tx_counts++], 1); } else { /* Если передача данных завершена, выключение TX trigger mode */ hosal_uart_ioctl(p_dev, HOSAL_UART_TX_TRIGGER_OFF, NULL); } return 0; }

/** * hal uart RX interrupt callback */
static int __uart_rx_callback(void *p_arg) { int ret; uint8_t data_buf[32]; hosal_uart_dev_t *p_dev = (hosal_uart_dev_t *)p_arg; ret = hosal_uart_receive(p_dev, data_buf, sizeof(data_buf)); hosal_uart_send(p_dev, data_buf, ret); return 0; } hosal_uart_init(&uart_dev_int);

/* Конфигурирование UART в режиме приема по прерываниям */ hosal_uart_ioctl(&uart_dev_int, HOSAL_UART_MODE_SET, (void *)HOSAL_UART_MODE_INT);

/* Привязка callback-функций приема и передачи */ hosal_uart_callback_set(&uart_dev_int, HOSAL_UART_RX_CALLBACK, __uart_rx_callback, &uart_dev_int); hosal_uart_callback_set(&uart_dev_int, HOSAL_UART_TX_CALLBACK, __uart_tx_callback, &uart_dev_int);

/* Запуск прерывания UART TX */ hosal_uart_ioctl(&uart_dev_int, HOSAL_UART_TX_TRIGGER_ON, NULL);

while(1){}

[Пример использования UART в режиме DMA]

Взято из bl_iot_sdk/customer_app/peripheral/demo_uart/demo_uart/demo_uart_dma.c для BL602:

static uint8_t g_tx_buf[] = "Please input 16 bytes\r\n";
static uint8_t g_rx_buf[16];

/** * Define a UART device, * TX pin : 16 * RX pin : 7 * baud : 2000000 */ HOSAL_UART_DEV_DECL(uart_dev_dma, 0, 16, 7, 2000000);

/** * hal uart DMA RX interrupt callback */
static int __uart_rx_dma_callback(void *p_arg) { // Если прием завершен, то в g_rx_buf окажутся принятые данные: blog_info("%s\r\n", g_rx_buf); return 0; }

/** * hal uart DMA TX interrupt callback */
static int __uart_tx_dma_callback(void *p_arg) { // Если передача завершена: return 0; }

hosal_uart_dma_cfg_t txdam_cfg = { .dma_buf = g_tx_buf, .dma_buf_size = sizeof(g_tx_buf), };
hosal_uart_dma_cfg_t rxdam_cfg = { .dma_buf = g_rx_buf, .dma_buf_size = sizeof(g_rx_buf), }; uart_dev_dma.config.uart_id = uart_id;

/* Инициализация устройства uart */ hosal_uart_init(&uart_dev_dma);

/* Привязка callback-функций прерываний передачи и приема DMA */ hosal_uart_callback_set(&uart_dev_dma, HOSAL_UART_TX_DMA_CALLBACK, __uart_tx_dma_callback, &uart_dev_dma); hosal_uart_callback_set(&uart_dev_dma, HOSAL_UART_RX_DMA_CALLBACK, __uart_rx_dma_callback, &uart_dev_dma);

/* Запуск транзакции UART TX DMA */ hosal_uart_ioctl(&uart_dev_dma, HOSAL_UART_DMA_TX_START, &txdam_cfg);

/* Запуск транзакции UART RX DMA */ hosal_uart_ioctl(&uart_dev_dma, HOSAL_UART_DMA_RX_START, &rxdam_cfg);

while (1) {}

[Настройка минимальной кратности размера блока DMA]

По умолчанию минимальный размер блока данных, на который сработает прерывание DMA (и соответственно может быть вызвана callback-функция), равен 16 байтам. Размер порции данных, на который может сработать прерывание DMA, настраивается полями srcBurstSzie и dstBurstSzie структуры DMA_Channel_Cfg_Type (для BL602 см. код components/platform/hosal/bl602_hal/hosal_uart.c, функция __uart_dma_rxcfg).

По умолчанию в оба этих поля записана константа DMA_BURST_SIZE_16, что соответствует 16 байтам:

static int __uart_dma_rxcfg(hosal_uart_dev_t *uart, hosal_uart_dma_cfg_t *dma_cfg)
{
   if (dma_cfg->dma_buf == NULL || dma_cfg->dma_buf_size == 0) {
      return -1;
   }
   DMA_Channel_Cfg_Type rxchCfg = {
      g_uart_addr[uart->port] + UART_FIFO_RDATA_OFFSET,
      (uint32_t)dma_cfg->dma_buf,
      dma_cfg->dma_buf_size,
       DMA_TRNS_P2M,
      DMA_CH0,
       DMA_TRNS_WIDTH_8BITS,
       DMA_TRNS_WIDTH_8BITS,
       DMA_BURST_SIZE_16,
       DMA_BURST_SIZE_16,
       DMA_PINC_DISABLE,
       DMA_MINC_ENABLE,
       DMA_REQ_UART0_RX,
       DMA_REQ_NONE,
   };
   UART_FifoCfg_Type fifoCfg =
   {
      .txFifoDmaThreshold     = 0x10,
      .rxFifoDmaThreshold     = 0x10,
      .txFifoDmaEnable        = DISABLE,
      .rxFifoDmaEnable        = ENABLE,
   };
   ...

Для минимальной кратности в 1 байт для приема можно применить константу DMA_BURST_SIZE_1 вместо DMA_BURST_SIZE_16, и в поле rxFifoDmaThreshold структуры UART_FifoCfg_Type вместо 0x10 записать 0x01. Однако увлекаться этим не стоит, потому что смысл DMA теряется, и на высоких скоростях значительно возрастет загрузка ядра MCU.

[Ссылки]

1. bouffalolab / bl_iot_sdk site:github.com.
2. bouffalolab / bouffalo_sdk site:github.com.

 

Добавить комментарий


Защитный код
Обновить

Top of Page