Initial commit: TXW82x FPV v2.7.0.7-42229 SDK + project sources

This commit is contained in:
2026-07-06 11:30:13 +08:00
commit e76462eeb7
3451 changed files with 1415300 additions and 0 deletions

1066
sdk/driver/uart/hguart_v2.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,250 @@
#ifndef _HGUART_V2_HW_H_
#define _HGUART_V2_HW_H_
#ifdef __cplusplus
extern "C" {
#endif
/***** UARTCON *****/
/*! RX buffer trigger threshold
*/
#define LL_UART_CON_RBUF_TRIG(n) (((n)&0x03) << 18)
/*! Singal RTS_N enable
*/
#define LL_UART_CON_RTS_EN (1UL << 17)
/*! Singal CTS_N enable
*/
#define LL_UART_CON_CTS_EN (1UL << 16)
/*! Transmission complete interrupt enable
*/
#define LL_UART_CON_TCIE_EN (1UL << 15)
/*! UART with carrier output enable.
* @note UART0 outputs pwm of TIMER0, and UART1 outputs pwm of TIMER1.
*/
#define LL_UART_CON_TMR_PWM_EN (1UL << 14)
/*! Frame error interrupt enable
* @note A frame error refers to a low-level signal received by rx during
* the stop bit.
*/
#define LL_UART_CON_FERR_IE_EN (1UL << 11)
/*! TX buffer empty interrupt enable
*/
#define LL_UART_CON_TXBUF_EMPTY_IE_EN (1UL << 10)
/*! RX buffer not empty interrupt enable
*/
#define LL_UART_CON_RXBUF_NEMPTY_IE_EN (1UL << 9)
/*! Inverted TX signal
*/
#define LL_UART_CON_TX_INV_EN (1UL << 8)
/*! Inverted RX signal
*/
#define LL_UART_CON_RX_INV_EN (1UL << 7)
/*! Odd parity
* @note Parity and 9bit data transfer cannot be used at the same time.
*/
#define LL_UART_CON_ODD_EN (1UL << 6)
/*! parity enable
* @note Parity and 9bit data transfer cannot be used at the same time.
*/
#define LL_UART_CON_PARITY_EN (1UL << 5)
/*! 9bit data transfer enable
* @note Parity and 9bit data transfer cannot be used at the same time.
*/
#define LL_UART_CON_BIT9_EN (1UL << 4)
/*! Stop bit selection
*/
#define LL_UART_CON_STOP_BIT(n) (((n)&0x01) << 3)
/*! Work mode selection
*/
#define LL_UART_CON_WORK_MODE(n) (((n)&0x03) << 1)
/*! UART module enable
*/
#define LL_UART_CON_UART_EN (1UL << 0)
/***** UARTSTA *****/
/*! Transmission complete pending
*/
#define LL_UART_STA_TC_PENDING (1UL << 12)
/*! RX timeout detection pending
* @note Only UART0 has this feature.
*/
#define LL_UART_STA_TO_PEND (1UL << 11)
/*! RX parity error pending
* @note 4 bits corrspond to 4 frame data in rx buffer.
*/
#define LL_UART_STA_PERR_PEND(n) (((n)>>7) & 0x0F)
/*! The amount of data in the rx fifo
*/
#define LL_UART_STA_RX_CNT(n) (((n)>>4) & 0x07)
/*! Frame error pending
*/
#define LL_UART_STA_FERR_PENDING (1UL << 3)
/*! RX FIFO overflow pending
*/
#define LL_UART_STA_RX_BUF_OV (1UL << 2)
/*! RX FIFO not empty pending
*/
#define LL_UART_STA_RX_BUF_NOT_EMPTY (1UL << 1)
/*! TX FIFO empty pending
*/
#define LL_UART_STA_TX_BUF_EMPTY (1UL << 0)
/***** DMACON *****/
/*! RX DMA parity error interrupt enable
* @note Only UART1 has this feature
*/
#define LL_UART_DMACON_RX_DMA_PERR_IE_EN (1UL << 4)
/*! RX DMA interrupt enable
* @note Only UART1 has this feature
*/
#define LL_UART_DMACON_RX_DMA_IE_EN (1UL << 3)
/*! TX DMA interrupt enable
* @note Only UART1 has this feature
*/
#define LL_UART_DMACON_TX_DMA_IE_EN (1UL << 2)
/*! RX DMA enable
* @note Only UART1 has this feature
*/
#define LL_UART_DMACON_RX_DMA_EN (0x0101UL << 1)
/*! TX DMA enable
* @note Only UART1 has this feature
*/
#define LL_UART_DMACON_TX_DMA_EN (0x0101UL << 0)
/***** DMASTA *****/
/*! RX DMA parity error pending
* @note Only UART1 has this feature
*/
#define LL_UART_DMASTA_RX_DMA_PERR (1UL << 2)
/*! RX DMA pending
* @note Only UART1 has this feature
*/
#define LL_UART_DMASTA_RX_DMA_PEND (1UL << 1)
/*! TX DMA pending
* @note Only UART1 has this feature
*/
#define LL_UART_DMASTA_TX_DMA_PEND (1UL << 0)
/***** UART_RS485_CON *****/
/*! RS485 RE enable
* @note Only UART1 has this feature
*/
#define LL_UART_RS485_CON_RE_EN (1UL << 9)
/*! RS485 DE enable
* @note Only UART1 has this feature
*/
#define LL_UART_RS485_CON_DE_EN (1UL << 8)
/*! RS485 work mode
* @note Only UART1 has this feature
*/
#define LL_UART_RS485_CON_RS485_MODE(n) (((n)&0x01) << 3)
/*! RS485 RE polarity
* @note Only UART1 has this feature
*/
#define LL_UART_RS485_CON_RE_POL(n) (((n)&0x01) << 2)
/*! RS485 DE polarity
* @note Only UART1 has this feature
*/
#define LL_UART_RS485_CON_DE_POL(n) (((n)&0x01) << 1)
/*! RS485 enable
* @note Only UART1 has this feature
*/
#define LL_UART_RS485_CON_RS485_EN (1UL << 0)
/***** UART_RS485_DET *****/
/*! The time interval between the end of STOP BIT and DE invalid. The unit
* is the uart module clock.
* @note Only UART1 has this feature
*/
#define LL_UART_RS485_DET_DE_DAT(n) (((n)&0x01FF) << 16)
/*! The time interval between the time DE is valid and the START BIT is sent.
* The unit is the uart module clock.
* @note Only UART1 has this feature
*/
#define LL_UART_RS485_DET_DE_AT(n) (((n)&0x01FF) << 0)
/***** UART_RS485_TAT *****/
/*! The time interval between the valid of RE and DE valid, the unit is the
* uart module clock.
* @note Only UART1 has this feature
*/
#define LL_UART_RS485_TAT_RE2DE_T(n) (((n)&0xFFFF) << 16)
/*! The time interval between DE valid and RE valid, the unit is the uart
* module clock.
* @note Only UART1 has this feature
*/
#define LL_UART_RS485_TAT_DE2RE_T(n) (((n)&0xFFFF) << 0)
/***** UART_TOCON *****/
/*! Timeout time configure
*/
#define LL_UART_TOCON_TO_BIT_LEN(n) (((n)&0xFFFF) << 16)
/*! Timeout interrupt enable
*/
#define LL_UART_TOCON_TO_IE_EN (1UL << 1)
/*! Timeout enable
*/
#define LL_UART_TOCON_TO_EN (1UL << 0)
typedef struct hguart_v2_hw {
__IO uint32_t CON;
__IO uint32_t BAUD;
__IO uint32_t DATA;
__IO uint32_t STA;
__IO uint32_t TSTADR;
__IO uint32_t RSTADR;
__IO uint32_t TDMALEN;
__IO uint32_t RDMALEN;
__IO uint32_t TDMACNT;
__IO uint32_t RDMACNT;
__IO uint32_t DMACON;
__IO uint32_t DMASTA;
__IO uint32_t RS485_CON;
__IO uint32_t RS485_DET;
__IO uint32_t RS485_TAT;
__IO uint32_t TOCON;
}UART_TypeDef;
/**
* @brief enable RS485 RE pin
* @param p_uart : The structure pointer of the UART
* @retval None
*/
__STATIC_INLINE void ll_uart485_re_enable(UART_TypeDef *p_uart) {
p_uart->RS485_CON |= LL_UART_RS485_CON_RE_EN;
}
/**
* @brief disable RS485 RE pin
* @param p_uart : The structure pointer of the UART
* @retval None
*/
__STATIC_INLINE void ll_uart485_re_disable(UART_TypeDef *p_uart) {
p_uart->RS485_CON &= (~LL_UART_RS485_CON_RE_EN);
}
/**
* @brief enable RS485 DE pin
* @param p_uart : The structure pointer of the UART
* @retval None
*/
__STATIC_INLINE void ll_uart485_de_enable(UART_TypeDef *p_uart) {
p_uart->RS485_CON |= LL_UART_RS485_CON_DE_EN;
}
/**
* @brief disable RS485 DE pin
* @param p_uart : The structure pointer of the UART
* @retval None
*/
__STATIC_INLINE void ll_uart485_de_disable(UART_TypeDef *p_uart) {
p_uart->RS485_CON &= (~LL_UART_RS485_CON_DE_EN);
}
#ifdef __cplusplus
}
#endif
#endif /* _HGUART_V2_HW_H_ */

726
sdk/driver/uart/hguart_v4.c Normal file
View File

@@ -0,0 +1,726 @@
/**
* @file hguart_v4.c
* @author bxd
* @brief simple uart
* @version
* TXW81X
* @date 2023-08-02
*
* @copyright Copyright (c) 2023
*
*/
#include "typesdef.h"
#include "list.h"
#include "errno.h"
#include "dev.h"
#include "osal/irq.h"
#include "osal/semaphore.h"
#include "osal/mutex.h"
#include "osal/string.h"
#include "hal/uart.h"
#include "hal/gpio.h"
#include "dev/uart/hguart_v4.h"
#include "hguart_v4_hw.h"
#define SIMPLE_UART_LOCK(mutex, flag)\
do{\
if(flag){\
os_mutex_lock(mutex, osWaitForever);\
}\
}while(0);
#define SIMPLE_UART_UNLOCK(mutex, flag)\
do{\
if(flag){\
os_mutex_unlock(mutex);\
}\
}while(0);
/**********************************************************************************/
/* UART LOW LAYER FUNCTION */
/**********************************************************************************/
static int32 hguart_v4_set_dma(struct hguart_v4 *dev, uint32 enable)
{
if (enable) {
dev->use_dma = 1;
} else {
dev->use_dma = 0;
}
return RET_OK;
}
static int32 hguart_v4_dma_rx_config(struct hguart_v4_hw *p_uart, uint8 status)
{
uint32 _dmacon = p_uart->DMACON;
uint32 flag = 0;
if (status) {
_dmacon = 0x5;
} else {
_dmacon = 0;
}
/*!
* fix: kick 2 times to counteract an unnecessary rx dma done
*/
if (p_uart->CON & LL_SIMPLE_UART_CON_DMA_IE) {
p_uart->CON &=~ LL_SIMPLE_UART_CON_DMA_IE;
flag = 1;
//printf("<%x>", *(uint32 *)(0x40004b70));
}
p_uart->DMACON = _dmacon;
__NOP();__NOP();__NOP();__NOP();
//printf("<%x>", *(uint32 *)(0x40004b70));
//clear rx done pending
p_uart->CON |= LL_SIMPLE_UART_CON_CLRDMAPEND;
//kick again
p_uart->DMACON = _dmacon;
__NOP();__NOP();__NOP();__NOP();
//printf("<%x>", *(uint32 *)(0x40004b70));
//clear rx done pending
p_uart->CON |= LL_SIMPLE_UART_CON_CLRDMAPEND;
//printf("<%x>", *(uint32 *)(0x40004b70));
if (flag) {
flag = 0;
p_uart->CON |= LL_SIMPLE_UART_CON_DMA_IE;
}
return 0;
}
static int32 hguart_v4_dma_tx_config(struct hguart_v4_hw *p_uart, uint8 status)
{
uint32 _dmacon = p_uart->DMACON;
if (status) {
_dmacon = 0xA;
} else {
_dmacon = 0;
}
p_uart->DMACON = _dmacon;
return 0;
}
static int32 hguart_v4_set_time_out(struct hguart_v4_hw *p_uart, uint32 time_bit, uint32 enable)
{
if (enable) {
p_uart->CON |= LL_SIMPLE_UART_CON_TO_EN;
p_uart->TOCON = LL_SIMPLE_UART_TOCON(time_bit);
} else {
p_uart->CON &=~ LL_SIMPLE_UART_CON_TO_EN;
p_uart->TOCON = 0;
}
return RET_OK;
}
/**********************************************************************************/
/* UART ATTCH FUNCTION */
/**********************************************************************************/
static int32 hguart_v4_open(struct uart_device *uart, uint32 baudrate) {
struct hguart_v4 *dev = (struct hguart_v4 *)uart;
struct hguart_v4_hw *hw = (struct hguart_v4_hw *)dev->hw;
if (dev->opened) {
if (!dev->dsleep) {
return -EBUSY;
}
}
/* pin config */
if (pin_func(dev->dev.dev.dev_id , 1) != RET_OK) {
return RET_ERR;
}
/* reg config */
hw->BAUD = (peripheral_clock_get(HG_APB0_PT_UART4) / baudrate) - 1;
hw->CON = LL_SIMPLE_UART_CON_UARTEN;
dev->opened = 1;
dev->irq_dma_rx = 0;
dev->irq_dma_tx = 0;
dev->use_dma = 0;
dev->dsleep = 0;
return RET_OK;
}
static int32 hguart_v4_close(struct uart_device *uart) {
struct hguart_v4 *dev = (struct hguart_v4 *)uart;
struct hguart_v4_hw *hw = (struct hguart_v4_hw *)dev->hw;
if (!dev->opened) {
return RET_OK;
}
irq_disable(dev->irq_num );
pin_func(dev->dev.dev.dev_id, 0);
hw->CON &= ~ LL_SIMPLE_UART_CON_UARTEN;
dev->opened = 0;
dev->irq_dma_rx = 0;
dev->irq_dma_tx = 0;
dev->use_dma = 0;
dev->dsleep = 0;
return RET_OK;
}
static int32 hguart_v4_putc(struct uart_device *uart, int8 value) {
struct hguart_v4 *dev = (struct hguart_v4 *)uart;
struct hguart_v4_hw *hw = (struct hguart_v4_hw *)dev->hw;
if ((!dev->opened) || (dev->dsleep)) {
return RET_ERR;
}
SIMPLE_UART_LOCK(&dev->mutex_tx, dev->debug_uart);
if (dev->opened && (hw->CON & LL_SIMPLE_UART_CON_UARTEN)) {
while(!(hw->CON & LL_SIMPLE_UART_CON_TXBUFEMPTY));
hw->DATA = value;
SIMPLE_UART_UNLOCK(&dev->mutex_tx, dev->debug_uart);
return RET_OK;
} else {
SIMPLE_UART_UNLOCK(&dev->mutex_tx, dev->debug_uart);
return -EIO;
}
}
static uint8 hguart_v4_getc(struct uart_device *uart) {
struct hguart_v4 *dev = (struct hguart_v4 *)uart;
struct hguart_v4_hw *hw = (struct hguart_v4_hw *)dev->hw;
if ((!dev->opened) || (dev->dsleep)) {
return RET_ERR;
}
SIMPLE_UART_LOCK(&dev->mutex_rx, dev->debug_uart);
while(!(hw->CON & LL_SIMPLE_UART_CON_RXBUFNOTEMPTY));
hw->CON |= LL_SIMPLE_UART_CON_CLRRXDONE;
SIMPLE_UART_UNLOCK(&dev->mutex_rx, dev->debug_uart);
return hw->DATA;
}
static int32 hguart_v4_rs485_de_set(void)
{
if(PIN_UART4_DE != 255) {
gpio_set_val(PIN_UART4_DE, 1);
return RET_OK;
}
if(PIN_UART5_DE != 255) {
gpio_set_val(PIN_UART5_DE, 1);
return RET_OK;
}
return RET_ERR;
}
static int32 hguart_v4_rs485_de_reset(void)
{
if(PIN_UART4_DE != 255) {
gpio_set_val(PIN_UART4_DE, 0);
return RET_OK;
}
if(PIN_UART5_DE != 255) {
gpio_set_val(PIN_UART5_DE, 0);
return RET_OK;
}
return RET_ERR;
}
static int32 hguart_v4_rs485_re_set(void)
{
if(PIN_UART4_RE != 255) {
gpio_set_val(PIN_UART4_RE, 1);
return RET_OK;
}
if(PIN_UART5_RE != 255) {
gpio_set_val(PIN_UART5_RE, 1);
return RET_OK;
}
return RET_ERR;
}
static int32 hguart_v4_rs485_re_reset(void)
{
if(PIN_UART4_RE != 255) {
gpio_set_val(PIN_UART4_RE, 0);
return RET_OK;
}
if(PIN_UART5_RE != 255) {
gpio_set_val(PIN_UART5_RE, 0);
return RET_OK;
}
return RET_ERR;
}
static int32 hguart_v4_puts(struct uart_device *uart, uint8 *buf, uint32 size) {
struct hguart_v4 *dev = (struct hguart_v4 *)uart;
struct hguart_v4_hw *hw = (struct hguart_v4_hw *)dev->hw;
uint32 i = 0;
if ((!dev->opened) || (dev->dsleep)) {
return RET_ERR;
}
SIMPLE_UART_LOCK(&dev->mutex_tx, dev->debug_uart);
if (dev->use_dma) {
if (dev->debug_uart) {
//enable uart 1Byte tx done irq
hw->CON |= LL_SIMPLE_UART_CON_UARTTXIE;
dev->p_tx_buf = (uint8 *)buf;
dev->tx_total_byte = size;
dev->tx_cur_byte = 0;
//send 1Byte to trigger 1Byte tx done irq
hw->DATA = buf[0];
os_sema_down(&dev->sema_tx, osWaitForever);
//disable uart 1Byte tx done irq
hw->CON &=~ LL_SIMPLE_UART_CON_UARTTXIE;
} else if (dev->rs485_set) {
hguart_v4_dma_tx_config(hw, 0);
hw->CON |= LL_SIMPLE_UART_CON_CLRDMAPEND;
hguart_v4_rs485_de_set();
hguart_v4_rs485_re_set();
hw->DMAADR = (uint32)buf;
hw->DMALEN = size;
hguart_v4_dma_tx_config(hw, 1);
/* waiting for tx done */
while (!(hw->CON & LL_SIMPLE_UART_CON_DMAPEND));
hguart_v4_rs485_re_reset();
hguart_v4_rs485_de_reset();
} else {
for (i = 0; i < size; i++) {
hguart_v4_putc(uart, buf[i]);
}
}
} else {
for (i = 0; i < size; i++) {
hguart_v4_putc(uart, buf[i]);
}
}
SIMPLE_UART_UNLOCK(&dev->mutex_tx, dev->debug_uart);
return RET_OK;
}
static int32 hguart_v4_gets(struct uart_device *uart, uint8 *buf, uint32 size) {
struct hguart_v4 *dev = (struct hguart_v4 *)uart;
struct hguart_v4_hw *hw = (struct hguart_v4_hw *)dev->hw;
uint32 i = 0;
if ((!dev->opened) || (dev->dsleep)) {
return RET_ERR;
}
SIMPLE_UART_LOCK(&dev->mutex_rx, dev->debug_uart);
if (dev->use_dma) {
hw->DMAADR = (uint32)buf;
hw->DMALEN = size;
hguart_v4_dma_rx_config(hw, 1);
} else {
for (i = 0; i < size; i++) {
hguart_v4_getc(uart);
}
}
SIMPLE_UART_UNLOCK(&dev->mutex_rx, dev->debug_uart);
return i;
}
static int32 hguart_v4_ioctl(struct uart_device *uart, enum uart_ioctl_cmd ioctl_cmd, uint32 param1, uint32 param2) {
int32 ret_val = RET_OK;
struct hguart_v4 *dev = (struct hguart_v4 *)uart;
if ((!dev->opened) || (dev->dsleep)) {
return RET_ERR;
}
switch (ioctl_cmd) {
case (UART_IOCTL_CMD_USE_DMA):
ret_val = hguart_v4_set_dma(dev, param1);
break;
case (UART_IOCTL_CMD_SET_TIME_OUT):
ret_val = hguart_v4_set_time_out((struct hguart_v4_hw *)dev->hw, param1, param2);
break;
case (UART_IOCTL_CMD_DISABLE_DEBUG_SELECTION):
dev->debug_uart = (param1) ? (1) : (0);
ret_val = RET_OK;
break;
case (UART_IOCTL_CMD_SET_RS485_EN):
dev->rs485_set = (param1) ? (1) : (0);
ret_val = RET_OK;
break;
default:
ret_val = -ENOTSUPP;
break;
}
return ret_val;
}
/* interrupt handler */
static void hguart_v4_irq_handler(void *data) {
struct hguart_v4 *dev = (struct hguart_v4 *)data;
struct hguart_v4_hw *hw = (struct hguart_v4_hw *)dev->hw;
if ((hw->CON & LL_SIMPLE_UART_CON_UARTTXIE) && (hw->CON & LL_SIMPLE_UART_CON_TXDONE)) {
hw->CON |= LL_SIMPLE_UART_CON_CLRTXDONE;
dev->tx_cur_byte++;
//printf("cur len:%d\r\n", dev->tx_cur_byte);
if (dev->tx_cur_byte == dev->tx_total_byte) {
//printf("up\r\n");
os_sema_up(&dev->sema_tx);
//diable uart tx 1byte done irq
hw->CON &=~ LL_SIMPLE_UART_CON_UARTTXIE;
} else {
hw->DATA = dev->p_tx_buf[dev->tx_cur_byte];
}
}
if ((hw->CON & LL_SIMPLE_UART_CON_UARTRXIE) && (hw->CON & LL_SIMPLE_UART_CON_RXBUFNOTEMPTY)) {
hw->CON |= LL_SIMPLE_UART_CON_CLRRXDONE;
if (dev->irq_hdl) {
dev->irq_hdl(UART_IRQ_FLAG_RX_BYTE, dev->irq_data, hw->DATA, 0);
}
}
if ((hw->CON & LL_SIMPLE_UART_CON_FERRIE) && (hw->CON & LL_SIMPLE_UART_CON_FERR)) {
hw->CON |= LL_SIMPLE_UART_CON_CLRFERR;
if (dev->irq_hdl) {
dev->irq_hdl(UART_IRQ_FLAG_FRAME_ERR, dev->irq_data, 0, 0);
}
}
//UART4/5 TIMEOUT来了之后DMA DONE也会起来故DMA DONE中断之前要判断是否TIMEOUT
if (!(hw->CON & LL_SIMPLE_UART_CON_TO_PENDING)) {
if ((hw->CON & LL_SIMPLE_UART_CON_DMA_IE) && (hw->CON & LL_SIMPLE_UART_CON_DMAPEND)) {
hw->CON |= LL_SIMPLE_UART_CON_CLRDMAPEND;
if (dev->irq_hdl) {
if (dev->irq_dma_rx) {
dev->irq_hdl(UART_IRQ_FLAG_DMA_RX_DONE, dev->irq_data, hw->DMACNT, 0);
} else {
dev->irq_hdl(UART_IRQ_FLAG_DMA_TX_DONE, dev->irq_data, hw->DMACNT, 0);
}
}
}
} else {
if ((hw->CON & LL_SIMPLE_UART_CON_TO_IE) && (hw->CON & LL_SIMPLE_UART_CON_TO_PENDING)) {
hw->CON |= (LL_SIMPLE_UART_CON_CLRTOPEND | LL_SIMPLE_UART_CON_CLRDMAPEND);
if (dev->irq_hdl) {
dev->irq_hdl(UART_IRQ_FLAG_TIME_OUT, dev->irq_data, hw->DMACNT, 0);
}
}
}
}
/* request interrupt */
static int32 hguart_v4_request_irq(struct uart_device *uart, uart_irq_hdl irqhdl, uint32 irq_flag, uint32 data) {
struct hguart_v4 *dev = (struct hguart_v4 *)uart;
struct hguart_v4_hw *hw = (struct hguart_v4_hw *)dev->hw;
if ((!dev->opened) || (dev->dsleep)) {
return RET_ERR;
}
dev->irq_hdl = irqhdl;
dev->irq_data = data ;
if (irq_flag & UART_IRQ_FLAG_RX_BYTE) {
hw->CON |= LL_SIMPLE_UART_CON_UARTRXIE;
}
if (irq_flag & UART_IRQ_FLAG_FRAME_ERR) {
hw->CON |= LL_SIMPLE_UART_CON_FERRIE;
}
if (irq_flag & UART_IRQ_FLAG_DMA_RX_DONE) {
hw->CON |= LL_SIMPLE_UART_CON_DMA_IE;
dev->irq_dma_tx = 0;
dev->irq_dma_rx = 1;
}
if (irq_flag & UART_IRQ_FLAG_DMA_TX_DONE) {
hw->CON |= LL_SIMPLE_UART_CON_DMA_IE;
dev->irq_dma_tx = 1;
dev->irq_dma_rx = 0;
}
if (irq_flag & UART_IRQ_FLAG_TIME_OUT) {
hw->CON |= LL_SIMPLE_UART_CON_TO_IE;
}
#if defined(TXW81X)
irq_enable(dev->comm_irq_num);
#elif defined(TXW82X)
irq_enable(dev->irq_num);
#endif
return RET_OK;
}
static int32 hguart_v4_release_irq(struct uart_device *uart, uint32 irq_flag) {
struct hguart_v4 *dev = (struct hguart_v4 *)uart;
struct hguart_v4_hw *hw = (struct hguart_v4_hw *)dev->hw;
if ((!dev->opened) || (dev->dsleep)) {
return RET_ERR;
}
if (irq_flag & UART_IRQ_FLAG_RX_BYTE) {
hw->CON &= ~ LL_SIMPLE_UART_CON_UARTRXIE;
}
if (irq_flag & UART_IRQ_FLAG_FRAME_ERR) {
hw->CON &= ~ LL_SIMPLE_UART_CON_FERRIE;
}
if (irq_flag & UART_IRQ_FLAG_DMA_RX_DONE) {
hw->CON &=~ LL_SIMPLE_UART_CON_DMA_IE;
}
if (irq_flag & UART_IRQ_FLAG_TIME_OUT) {
hw->CON &=~ LL_SIMPLE_UART_CON_TO_IE;
}
#if defined(TXW81X)
irq_disable(dev->comm_irq_num);
#elif defined(TXW82X)
irq_disable(dev->irq_num);
#endif
return RET_OK;
}
#ifdef CONFIG_SLEEP
int32 hguart_v4_suspend(struct dev_obj *obj)
{
struct hguart_v4 *dev = (struct hguart_v4 *)obj;
struct hguart_v4_hw *hw = (struct hguart_v4_hw *)dev->hw;
if (!dev->opened) {
return RET_OK;
}
if (0 > os_mutex_lock(&dev->bp_suspend_lock, 10000)) {
return RET_ERR;
}
/*!
* Close the UART
*/
hw->CON &= ~ BIT(4);
// pin_func(dev->dev.dev.dev_id, 0);
#if defined(TXW81X)
irq_disable(dev->comm_irq_num);
#elif defined(TXW82X)
irq_disable(dev->irq_num);
#endif
/*
* clear pending
*/
hw->CON |= 0x3f000000;
os_memset((void *)&dev->bp_regs, 0, sizeof(dev->bp_regs));
/*
* save the reglist
*/
dev->bp_regs.con = hw->CON;
dev->bp_regs.baud = hw->BAUD;
dev->bp_regs.tocon = hw->TOCON;
dev->bp_regs.dmaadr = hw->DMAADR;
dev->bp_regs.dmalen = hw->DMALEN;
dev->bp_regs.dmacon = hw->DMACON;
/*
* save the irq_hdl created by user
*/
dev->bp_irq_hdl = dev->irq_hdl;
dev->bp_irq_data = dev->irq_data;
//venus v2uart4&5 clk and uart0 clk are share the same source
if (UART4_BASE == (uint32)hw) {
// sysctrl_uart4_clk_close();
} else if (UART5_BASE == (uint32)hw) {
// sysctrl_uart5_clk_close();
}
dev->dsleep = 1;
os_mutex_unlock(&dev->bp_suspend_lock);
return RET_OK;
}
int32 hguart_v4_resume(struct dev_obj *obj)
{
struct hguart_v4 *dev = (struct hguart_v4 *)obj;
struct hguart_v4_hw *hw = (struct hguart_v4_hw *)dev->hw;
if (!dev->opened) {
return RET_OK;
}
if (0 > os_mutex_lock(&dev->bp_resume_lock, 10000)) {
return RET_ERR;
}
/* pin config */
// if (pin_func(dev->dev.dev.dev_id, 1) != RET_OK) {
// return RET_ERR;
// }
/*
* recovery the UART clk
*/
if (UART4_BASE == (uint32)hw) {
// sysctrl_uart4_clk_open();
} else if (UART5_BASE == (uint32)hw) {
// sysctrl_uart5_clk_open();
}
/*
* recovery the reglist from sram
*/
hw->CON = dev->bp_regs.con;
hw->BAUD = dev->bp_regs.baud;
hw->TOCON = dev->bp_regs.tocon;
hw->DMAADR = dev->bp_regs.dmaadr;
hw->DMALEN = dev->bp_regs.dmalen;
hw->DMACON = dev->bp_regs.dmacon;
/*
* recovery the irq handle and data
*/
dev->irq_hdl = dev->bp_irq_hdl;
dev->irq_data = dev->bp_irq_data;
os_memset((void *)&dev->bp_regs, 0, sizeof(dev->bp_regs));
/*!
* Open the UART
*/
hw->CON |= BIT(4);
if (hw->DMACON & 1) {
hguart_v4_dma_rx_config(hw, 1);
}
#if defined(TXW81X)
irq_enable(dev->comm_irq_num);
#elif defined(TXW82X)
irq_enable(dev->irq_num);
#endif
dev->dsleep = 0;
os_mutex_unlock(&dev->bp_resume_lock);
return RET_OK;
}
#endif
static const struct uart_hal_ops uart_v4_ops = {
.open = hguart_v4_open,
.close = hguart_v4_close,
.getc = hguart_v4_getc,
.putc = hguart_v4_putc,
.gets = hguart_v4_gets,
.puts = hguart_v4_puts,
.ioctl = hguart_v4_ioctl,
.request_irq = hguart_v4_request_irq,
.release_irq = hguart_v4_release_irq,
#ifdef CONFIG_SLEEP
.ops.suspend = hguart_v4_suspend,
.ops.resume = hguart_v4_resume,
#endif
};
int32 hguart_v4_attach(uint32 dev_id, struct hguart_v4 *uart) {
uart->irq_data = 0;
uart->irq_hdl = NULL;
uart->opened = 0;
uart->irq_dma_rx = 0;
uart->irq_dma_tx = 0;
uart->use_dma = 0;
uart->debug_uart = 0;
uart->rs485_set = 0;
uart->dsleep = 0;
uart->p_tx_buf = NULL;
uart->tx_cur_byte = 0;
uart->tx_total_byte = 0;
uart->dev.dev.ops = (const struct devobj_ops *)&uart_v4_ops;
os_sema_init(&uart->sema_tx, 0);
os_mutex_init(&uart->mutex_rx);
os_mutex_init(&uart->mutex_tx);
#ifdef CONFIG_SLEEP
os_mutex_init(&uart->bp_suspend_lock);
os_mutex_init(&uart->bp_resume_lock);
#endif
request_irq(uart->irq_num, hguart_v4_irq_handler, uart);
dev_register(dev_id, (struct dev_obj *)uart);
return RET_OK;
}

View File

@@ -0,0 +1,164 @@
#ifndef _HGUART_V4_HW_H_
#define _HGUART_V4_HW_H_
#ifdef __cplusplus
extern "C" {
#endif
/***** UARTCON *****/
/*! Timeout interrupt en
*/
#define LL_SIMPLE_UART_CON_TO_IE (1UL << 31)
/*! Timeout function en
*/
#define LL_SIMPLE_UART_CON_TO_EN (1UL << 30)
/*! Timeout pending
*/
#define LL_SIMPLE_UART_CON_CLRTOPEND (1UL << 29)
/*! Transmission completed The 1byte flag was cleared to zero
*/
#define LL_SIMPLE_UART_CON_CLRTXDONE (1UL << 28)
/*! The frame receiving error detection flag is cleared to zero
*/
#define LL_SIMPLE_UART_CON_CLRFERR (1UL << 27)
/*! The receive cache register is not null flag cleared
*/
#define LL_SIMPLE_UART_CON_CLRRXDONE (1UL << 26)
/*! DMA interrupt flag cleared to zero
*/
#define LL_SIMPLE_UART_CON_CLRDMAPEND (1UL << 25)
/*! Receive address interrupt flag cleared to zero
*/
#define LL_SIMPLE_UART_CON_CLRRXADDRPEND (1UL << 24)
/*! Transmission completed 1byte flag. This bit is 0 when the module is disabled
*/
#define LL_SIMPLE_UART_CON_TXDONE (1UL << 21)
/*! Frame receiving error detection flag
*/
#define LL_SIMPLE_UART_CON_FERR (1UL << 20)
/*! Receive cache register is not empty flag, this bit is 0 when the module is not enabled
*/
#define LL_SIMPLE_UART_CON_RXBUFNOTEMPTY (1UL << 19)
/*! The send cache register is an empty flag. This bit is 0 when the module is disabled
*/
#define LL_SIMPLE_UART_CON_TXBUFEMPTY (1UL << 18)
/*! The DMA completion flag bit, which is set to 1 when a send or receive is complete using DMA
*/
#define LL_SIMPLE_UART_CON_DMAPEND (1UL << 17)
/*! Receive address interrupt flag RXADDRPEND
*/
#define LL_SIMPLE_UART_CON_RXADDRPEND (1UL << 16)
/*! RX_TIMEOUT PENDING
*/
#define LL_SIMPLE_UART_CON_TO_PENDING (1UL << 15)
/*! Select UART output with which PWM carrier:
*/
#define LL_SIMPLE_UART_CON_CARRIER_SEL(n) (((n)&0x09) << 11)
/*! Set the CARRIER_SEL bit to the PWM carrier mode enable bit. Specify the carrier_sel bit for the specific PWM carrier of the TIMER
*/
#define LL_SIMPLE_UART_CON_PWM_CARRIER_EN (1UL << 10)
/*! The receiving address was interrupted. Procedure
*/
#define LL_SIMPLE_UART_CON_RXADDRIE (1UL << 9)
/*! Error detection interrupt enabled
*/
#define LL_SIMPLE_UART_CON_FERRIE (1UL << 8)
/*! DMA interrupt enabled
*/
#define LL_SIMPLE_UART_CON_DMA_IE (1UL << 7)
/*! Stop bit setting
*/
#define LL_SIMPLE_UART_CON_STOPBIT (1UL << 6)
/*! The 9bit function was enabled
*/
#define LL_SIMPLE_UART_CON_BIT9EN (1UL << 5)
/*! The Uart function was enabled
*/
#define LL_SIMPLE_UART_CON_UARTEN (1UL << 4)
/*! Send data inversely
*/
#define LL_SIMPLE_UART_CON_TXINV (1UL << 3)
/*! The received data is reversed
*/
#define LL_SIMPLE_UART_CON_RXINV (1UL << 2)
/*! Send 1byte to enable the interrupt
*/
#define LL_SIMPLE_UART_CON_UARTTXIE (1UL << 1)
/*! The receiving interrupt function was enabled
*/
#define LL_SIMPLE_UART_CON_UARTRXIE (1UL << 0)
/***** UARTBAUD *****/
/*! Baud rate setting
*/
#define LL_SIMPLE_UART_UARTBAUD(n) (((n)&0x0003FFFF) << 0)
/***** UARTDATA *****/
/*! Data register
*/
#define LL_SIMPLE_UART_UARTDATA(n) (((n)&0x000000FF) << 0)
/***** UARTTOCON *****/
/*! TOCON register
*/
#define LL_SIMPLE_UART_TOCON(n) (((n)&0x0000FFFF) << 0)
/***** UARTDMAADR *****/
/*! DMAADR register
*/
#define LL_SIMPLE_UART_UARTDMAADR(n) (((n)&0xFFFFFFFF) << 0)
/***** UARTDMALEN *****/
/*! DMALEN register
*/
#define LL_SIMPLE_UART_UARTDMALEN(n) (((n)&0x000007FF) << 0)
/***** UARTDMACON *****/
/*!DMACON register
*/
#define LL_SIMPLE_UART_UART_TX_USEDMA_KEY (1UL << 3)
#define LL_SIMPLE_UART_UART_RX_USEDMA_KEY (1UL << 2)
#define LL_SIMPLE_UART_UART_TX_USEDMA (1UL << 1)
#define LL_SIMPLE_UART_UART_RX_USEDMA (1UL << 0)
/**
* @brief Simple Universal Synchronous Asynchronous Receiver Transmitter
*/
struct hguart_v4_hw{
__IO uint32_t CON;
__IO uint32_t BAUD;
__IO uint32_t DATA;
__IO uint32_t TOCON;
__IO uint32_t DMAADR;
__IO uint32_t DMALEN;
__IO uint32_t DMACON;
__IO uint32_t DMACNT;
};
#ifdef __cplusplus
}
#endif
#endif /* _HGUART_V4_HW_H_ */