Files
TencentOS-tiny/board/ALIENTEK_W601/BSP/Src/usart.c
supowang e147b06080 add ALIENTEK_W601 support
add ALIENTEK_W601 wifi support
2019-09-25 15:24:38 +08:00

177 lines
4.5 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 "sys.h"
#include "usart.h"
/*********************************************************************************
___ _ _____ _____ _ _ _____ _____ _ __
/ _ \ | | |_ _|| ___|| \ | ||_ _|| ___|| | / /
/ /_\ \| | | | | |__ | \| | | | | |__ | |/ /
| _ || | | | | __| | . ` | | | | __| | \
| | | || |_____| |_ | |___ | |\ | | | | |___ | |\ \
\_| |_/\_____/\___/ \____/ \_| \_/ \_/ \____/ \_| \_/
* ******************************************************************************
* 本程序只供学习使用,未经作者许可,不得用于其它任何用途
* ALIENTEK W601开发板
* 串口0初始化
* 正点原子@ALIENTEK
* 技术论坛:www.openedv.com
* 创建日期:2019/7/10
* 版本V1.0
* 版权所有,盗版必究。
* Copyright(C) 广州市星翼电子科技有限公司 2019-2029
* All rights reserved
* ******************************************************************************
* 修改说明
* ******************************************************************************/
//////////////////////////////////////////////////////////////
//加入以下代码,支持printf函数,而不需要选择use MicroLIB
#if 1
#pragma import(__use_no_semihosting)
//标准库需要的支持函数
struct __FILE
{
int handle;
};
FILE __stdout;
/**
* @brief 定义_sys_exit()以避免使用半主机模式
*
* @param void
*
* @return void
*/
void _sys_exit(int x)
{
x = x;
}
/**
* @brief 重定义fputc函数
*
* @param ch 输出字符量
* @param f 文件指针
*
* @return void
*/
int fputc(int ch, FILE *f)
{
while(tls_reg_read32(HR_UART0_FIFO_STATUS) & 0x3F); //等待发送完毕
tls_reg_write32(HR_UART0_TX_WIN, (u8) ch);
return ch;
}
#endif
#if EN_USART1_RX //如果使能了接收
//串口1中断服务程序
//注意,读取USARTx->SR能避免莫名其妙的错误
u8 USART_RX_BUF[USART_REC_LEN]; //接收缓冲,最大USART_REC_LEN个字节.
//接收状态
//bit15 接收完成标志
//bit14 接收到0x0d
//bit13~0 接收到的有效字节数目
u16 USART_RX_STA = 0; //接收状态标记
/**
* @brief 初始化串口0函数
*
* @param bound 串口波特率
*
* @return void
*/
void uart_init(u32 bound)
{
u32 bd;
u32 apbclk;
tls_sys_clk sysclk;
/* 1.配置IO */
wm_uart0_tx_config(WM_IO_PA_04);
wm_uart0_rx_config(WM_IO_PA_05);
/* 2.波特率设置:
ubdiv = (apbclk / (16 * bound) - 1)
ubdiv_frac = ((apbclk % (bound * 16)) / (bound)) */
tls_sys_clk_get(&sysclk);
apbclk = sysclk.apbclk * 1000000;
bd = (apbclk / (16 * bound) - 1) | (((apbclk % (bound * 16)) / (bound)) << 16);
tls_reg_write32(HR_UART0_BAUD_RATE_CTRL, bd);
/* 2.串口参数设置8位数据位/1位停止位/无奇偶校验位/发送使能/接收使能 */
tls_reg_write32(HR_UART0_LINE_CTRL, ULCON_WL8 | ULCON_TX_EN | ULCON_RX_EN);
/* 3.硬件流控关闭 */
tls_reg_write32(HR_UART0_FLOW_CTRL, 0);
/* 3.不使能DMA */
tls_reg_write32(HR_UART0_DMA_CTRL, 0);
/* 4.FIFO触发设置1个字节 */
tls_reg_write32(HR_UART0_FIFO_CTRL, 0);
/* 5.开启RX中断:接收触发中断和接收超时中断*/
tls_reg_write32(HR_UART0_INT_MASK, 0xFF & (~(UIS_RX_FIFO | UIS_RX_FIFO_TIMEOUT)));
/* 6.串口接收中断配置 */
NVIC_ClearPendingIRQ(UART0_IRQn);
NVIC_InitTypeDef NVIC_InitStruct;
NVIC_InitStruct.NVIC_IRQChannel = UART0_IRQn;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 7;
NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStruct);
}
/**
* @brief 串口0中断服务程序
*
* @param void
*
* @return void
*/
void UART0_IRQHandler(void)
{
u8 res;
if(tls_reg_read32(HR_UART0_INT_SRC) & UIS_RX_FIFO) //接收到数据
{
res = (u8)tls_reg_read32(HR_UART0_RX_WIN);
if((USART_RX_STA & 0x8000) == 0) //接收未完成
{
if(USART_RX_STA & 0x4000) //接收到了0x0d
{
if(res != 0x0a)USART_RX_STA = 0; //接收错误,重新开始
else USART_RX_STA |= 0x8000; //接收完成了
}
else //还没收到0X0D
{
if(res == 0x0d)USART_RX_STA |= 0x4000;
else
{
USART_RX_BUF[USART_RX_STA & 0X3FFF] = res;
USART_RX_STA++;
if(USART_RX_STA > (USART_REC_LEN - 1))USART_RX_STA = 0; //接收数据错误,重新开始接收
}
}
}
tls_reg_write32(HR_UART0_INT_SRC, UIS_RX_FIFO); //清除状态标志位
}
if(tls_reg_read32(HR_UART0_INT_SRC) & UIS_RX_FIFO_TIMEOUT) //接收到数据
{
tls_reg_write32(HR_UART0_INT_SRC, UIS_RX_FIFO_TIMEOUT); //清除状态标志位
}
}
#endif