IoT_SCV_CH584M/bsp/src/bsp_uart.c

305 lines
7.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "bsp_uart.h"
#include "bsp_ml307r.h"
#include "lwrb.h"
#include "CH58x_uart.h"
#include "shell_port.h"
#include "SLEEP.h"
#include "CONFIG.h"
#include "log.h"
#define UART1_RX_BUFFER_LENGTH 512U
#define UART1_TX_BUFFER_LENGTH 512U
#define UART3_RX_BUFFER_LENGTH 1024U
#define UART3_TX_BUFFER_LENGTH 1024U
void BSP_Shell_SetActive(void);
lwrb_t uart1_rx_t;
lwrb_t uart1_tx_t;
uint8_t uart1_tx_buf[UART1_TX_BUFFER_LENGTH] = {0};
uint8_t uart1_rx_buf[UART1_RX_BUFFER_LENGTH] = {0};
lwrb_t uart3_rx_t;
lwrb_t uart3_tx_t;
uint8_t uart3_tx_buf[UART3_TX_BUFFER_LENGTH] = {0};
uint8_t uart3_rx_buf[UART3_RX_BUFFER_LENGTH] = {0};
//串口接收
unsigned int BSP_Uart1_Receive_Data(void *buf, unsigned int len)
{
return lwrb_read(&uart1_rx_t, buf, len);
}
//串口发送数据
unsigned int BSP_Uart1_Send_Data(const void *buf, unsigned int len)
{
unsigned int ret;
ret = lwrb_write(&uart1_tx_t, buf, len);
UART1_INTCfg(ENABLE, RB_IER_THR_EMPTY);
return ret;
}
//串口接收
unsigned int BSP_Uart3_Receive_Data(void *buf, unsigned int len)
{
// return lwrb_write(&uart3_rx_t, buf, len);
return lwrb_read(&uart3_rx_t, buf, len);
}
//串口发送数据
unsigned int BSP_Uart3_Send_Data(const void *buf, unsigned int len)
{
unsigned int ret;
ret = lwrb_write(&uart3_tx_t, buf, len);
// UART3_INTCfg(ENABLE, RB_IER_THR_EMPTY);
// BSP_BlockSleep();
BSP_UART3_TxLoop();
// BSP_RequestSleep();
return ret;
}
// https://www.cnblogs.com/iot-fan/p/13439293.html
// tx process
// 本查询函数需要扔到主循环不断调用
void BSP_UART3_TxLoop(void)
{
uint8_t data;
while (R8_UART3_TFC < UART_FIFO_SIZE)
{
// 判断发送软件缓冲区,是否空,如果不空,就一个一个读出来,填到硬件fifo里
if (lwrb_get_full(&uart3_tx_t))
{
lwrb_read(&uart3_tx_t, &data, 1);
// 把软件缓冲区的数据填到uart的硬件发送fifo里
UART3_SendByte(data);
}
else
{
break;
}
}
}
/**
* \brief Buffer event function
*/
static void Uart1_evt_fn(struct lwrb* buff, lwrb_evt_type_t evt, lwrb_sz_t bp)
{
switch (evt)
{
case LWRB_EVT_RESET:
printf("[EVT] Buffer reset event!\r\n");
break;
case LWRB_EVT_READ:
printf("[EVT] Buffer read event: %d byte(s)!\r\n", (int)bp);
break;
case LWRB_EVT_WRITE:
printf("[EVT] Buffer write event: %d byte(s)!\r\n", (int)bp);
break;
default: break;
}
}
void UART1_FifoInit(void)
{
lwrb_init(&uart1_tx_t, uart1_tx_buf, sizeof(uart1_tx_buf));
lwrb_init(&uart1_rx_t, uart1_rx_buf, sizeof(uart1_rx_buf));
// lwrb_set_evt_fn(&uart1_rx_t, Uart1_evt_fn);
}
void UART3_FifoInit(void)
{
lwrb_init(&uart3_tx_t, uart3_tx_buf, sizeof(uart3_tx_buf));
lwrb_init(&uart3_rx_t, uart3_rx_buf, sizeof(uart3_rx_buf));
//lwrb_set_evt_fn(&uart1_rx_t, Uart1_evt_fn);
}
void BSP_UART1_Init(void)
{
GPIOPinRemap(ENABLE, RB_PIN_UART1);
/* 配置串口1先配置IO口模式再配置串口 */
GPIOB_SetBits(ML307_UART_TX_PIN);
GPIOB_ModeCfg(ML307_UART_RX_PIN, GPIO_ModeIN_PU); // RXD-配置上拉输入
GPIOB_ModeCfg(ML307_UART_TX_PIN, GPIO_ModeOut_PP_5mA); // TXD-配置推挽输出注意先让IO口输出高电平
UART1_DefInit();
UART1_BaudRateCfg(115200);
UART1_ByteTrigCfg(UART_1BYTE_TRIG);
// 中断方式接收数据
UART1_INTCfg(ENABLE, RB_IER_LINE_STAT | RB_IER_RECV_RDY | RB_IER_THR_EMPTY);
PFIC_EnableIRQ(UART1_IRQn);
UART1_FifoInit();
}
void BSP_UART3_Init(void)
{
GPIOPinRemap(ENABLE, RB_PIN_UART3);
/* 配置串口3先配置IO口模式再配置串口 */
GPIOB_SetBits(UART3_TX_PIN);
GPIOB_ModeCfg(UART3_RX_PIN, GPIO_ModeIN_PU); // RXD-配置上拉输入
GPIOB_ModeCfg(UART3_TX_PIN, GPIO_ModeOut_PP_5mA); // TXD-配置推挽输出注意先让IO口输出高电平
UART3_DefInit();
UART3_BaudRateCfg(460800); //115200
UART3_ByteTrigCfg(UART_1BYTE_TRIG);
// 中断方式接收数据
UART3_INTCfg(ENABLE, RB_IER_LINE_STAT | RB_IER_RECV_RDY | RB_IER_THR_EMPTY);
PFIC_EnableIRQ(UART3_IRQn);
UART3_FifoInit();
userShellInit();
}
static tmosTaskID shell_timeout_task_id = INVALID_TASK_ID;
#define SHELL_TIMEOUT_EVT 0x0001
/**
* @brief 超时后系统睡眠
*/
static uint16_t BSP_Shell_TimeoutTask(uint8_t task_id, uint16_t events)
{
if (events & SHELL_TIMEOUT_EVT)
{
printf("Shell_Timeout UART3 enter low power mode\r\n");
BSP_RequestSleep();
return (events ^ SHELL_TIMEOUT_EVT);
}
return 0;
}
/**
* @brief 启动Shell活动超时定时器
*/
void BSP_Shell_StartTimeoutTimer(void)
{
if (shell_timeout_task_id == INVALID_TASK_ID)
{
shell_timeout_task_id = TMOS_ProcessEventRegister(BSP_Shell_TimeoutTask);
}
tmos_stop_task(shell_timeout_task_id, SHELL_TIMEOUT_EVT);
tmos_start_task(shell_timeout_task_id, SHELL_TIMEOUT_EVT, MS1_TO_SYSTEM_TIME(SHELL_ACTIVITY_TIMEOUT));
}
/**
* @brief 将Shell设置为活动状态阻止系统睡眠
*/
void BSP_Shell_SetActive(void)
{
BSP_BlockSleep();
BSP_Shell_StartTimeoutTimer();
}
/*********************************************************************
* @fn UART1_IRQHandler
*
* @brief UART1中断函数
*
* @return none
*/
__INTERRUPT
__HIGH_CODE
void UART1_IRQHandler(void)
{
uint8_t data,q;
// q = UART1_GetITFlag();
// printf("q1 = %#x\r\n", q);
switch(UART1_GetITFlag())
{
case UART_II_LINE_STAT: // 线路状态错误
{
// UART1_GetLinSTA();
break;
}
case UART_II_RECV_RDY:
data = UART1_RecvByte();
UART3_SendByte(data);
lwrb_write(&uart1_rx_t, &data, 1);
break;
case UART_II_RECV_TOUT: // 接收数据
break;
case UART_II_THR_EMPTY: // 发送缓存区空,可继续发送
if(lwrb_read(&uart1_tx_t, &data, 1))
{
UART1_SendByte(data);
}
else
{
UART1_INTCfg(DISABLE, RB_IER_THR_EMPTY);
}
break;
case UART_II_MODEM_CHG: // 只支持串口0
break;
default:
break;
}
}
/*********************************************************************
* @fn UART3_IRQHandler
*
* @brief UART1中断函数
*
* @return none
*/
__INTERRUPT
__HIGH_CODE
void UART3_IRQHandler(void)
{
uint8_t data,q;
// q = UART3_GetITFlag();
// printf("q3 = %#x\r\n", q);
switch(UART3_GetITFlag())
{
case UART_II_LINE_STAT: // 线路状态错误
{
// UART1_GetLinSTA();
break;
}
case UART_II_RECV_RDY:
case UART_II_RECV_TOUT: //接收超时
BSP_Shell_SetActive();
while(R8_UART3_RFC)
{
logDebug("shellHandler \r\n");
shellHandler(&shell, R8_UART3_RBR);
}
break;
case UART_II_THR_EMPTY: // 发送缓存区空,可继续发送
// if(lwrb_get_full(&uart3_tx_t))
// {
// lwrb_read(&uart3_tx_t, &data, 1);
// UART3_SendByte(data);
// }
// else
// {
// UART3_INTCfg(DISABLE, RB_IER_THR_EMPTY);
// }
break;
case UART_II_MODEM_CHG: // 只支持串口0
break;
default:
break;
}
}