Исходный код функций 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. |