214 lines
5.5 KiB
C
214 lines
5.5 KiB
C
#ifdef SUPPORT_MS_EXTENSIONS
|
|
#pragma bss_seg(".uart.bss")
|
|
#pragma data_seg(".uart.data")
|
|
#pragma const_seg(".uart.const")
|
|
#pragma code_seg(".uart.text")
|
|
#pragma str_literal_override(".uart.text")
|
|
#endif /* #ifdef SUPPORT_MS_EXTENSIONS */
|
|
|
|
#include "includes.h"
|
|
#include "uart.h"
|
|
#include "gpio.h"
|
|
#include "ipc_spin_lock.h"
|
|
|
|
//uart时钟选择:
|
|
//#define UART_CLK_SEL UART_CLK_SYS_CLK //由主系统gpcnt模块算出rc16m频率,rc16m频率跟pvdd有关,注意配置被覆盖。
|
|
#define UART_CLK_SEL UART_CLK_STD_12M //低功耗不能使用该时钟源
|
|
|
|
//uart波特率选择:
|
|
#define UART_TARGET_BAUD CONFIG_DEBUG_UART_BAUD
|
|
//#define UART_TARGET_BAUD 1000000L
|
|
|
|
//调试串口选择: P11_UART0/P11_UART1
|
|
#define DEBUG_UART_SELECT P11_UART0
|
|
|
|
//输入选择. 只有UART0有输入功能
|
|
#define DEBUG_UART_RX_ENABLE 0
|
|
#if DEBUG_UART_RX_ENABLE
|
|
#define DEBUG_UART_RX_IO IO_PORTB_05
|
|
#define DEBUG_UART_RX_OVERTIME 100 //ms
|
|
#endif /* #if DEBUG_UART_RX_ENABLE */
|
|
|
|
static u8 init = 0;
|
|
|
|
#define P11_UART_CLK_SEL(x) SFR(P11_CLOCK->CLK_CON2, 2, 2, x)
|
|
|
|
|
|
#define UART_ENTER_CRITICAL() irq_disable_core();//ipc_spin_lock(IPC_SPIN_LOCK_EVENT_UART)
|
|
#define UART_EXIT_CRITICAL() irq_enable_core(); //ipc_spin_unlock(IPC_SPIN_LOCK_EVENT_UART)
|
|
|
|
|
|
|
|
|
|
___interrupt
|
|
static void uart0_isr(void)
|
|
{
|
|
u8 rx = 0;
|
|
|
|
if (UART_RX_PENDING_IS(P11_UART0)) {
|
|
rx = UART_BUF_READ(P11_UART0);
|
|
UART_RX_PENDING_CLEAR(P11_UART0);
|
|
printf("RX pending, rx: 0x%x\n", rx);
|
|
}
|
|
|
|
if (UART_OT_PENDING_IS(P11_UART0)) {
|
|
rx = UART_BUF_READ(P11_UART0);
|
|
UART_OT_PENDING_CLEAR(P11_UART0);
|
|
printf("OT pending, rx: 0x%x\n", rx);
|
|
}
|
|
}
|
|
|
|
static u32 uart_src_clk_get(void)
|
|
{
|
|
u32 freq = 0;
|
|
|
|
if (UART_CLK_SEL == UART_CLK_STD_12M) {
|
|
SFR(P11_CLOCK->CLK_CON1, 15, 2, 1); //MSYS_BT24M --> P11_BT24M
|
|
SFR(P11_CLOCK->CLK_CON1, 17, 3, 1); //STD12M sel P11_BT24M input
|
|
SFR(P11_CLOCK->CLK_CON1, 20, 2, 0); // div0
|
|
SFR(P11_CLOCK->CLK_CON1, 22, 2, 1); // div1
|
|
freq = 12000000;
|
|
} else if (UART_CLK_SEL == UART_CLK_RC16M) {
|
|
freq = 16000000;//(u32)((u32)m2p_message[M2P_RCH_FEQ_H] << 8 | m2p_message[M2P_RCH_FEQ_L]) * 1000;
|
|
} else if (UART_CLK_SEL == UART_CLK_SYS_CLK) {
|
|
freq = 24000000;
|
|
}
|
|
|
|
return freq;
|
|
}
|
|
|
|
void uart_clk_sel(enum UART_CLK_TABLE clk)
|
|
{
|
|
u32 freq = 0;
|
|
|
|
if (clk == UART_CLK_STD_12M) {
|
|
freq = 12000000;
|
|
} else if (clk == UART_CLK_RC16M) {
|
|
freq = 16000000;
|
|
} else if (clk == UART_CLK_SYS_CLK) {
|
|
freq = 24000000;
|
|
}
|
|
|
|
P11_UART_CLK_SEL(clk);
|
|
|
|
u16 baud_reg = (freq / UART_TARGET_BAUD) / 4 - 1;
|
|
|
|
UART_BAUD_SET(DEBUG_UART_SELECT, baud_reg);
|
|
}
|
|
|
|
void debug_uart_init(u8 tx_port)
|
|
{
|
|
UART_CON0_CLEAR(DEBUG_UART_SELECT);
|
|
UART_CON1_CLEAR(DEBUG_UART_SELECT);
|
|
|
|
uart_clk_sel(UART_CLK_SEL);
|
|
|
|
//tx io inita
|
|
gpio_set_output_value(tx_port, 1);
|
|
gpio_set_direction(tx_port, 0);
|
|
|
|
if (DEBUG_UART_SELECT == P11_UART1) {
|
|
//gpio_set_fun_output_port(tx_port, P11_FO_UART1_TX, 1, 1);
|
|
} else if (DEBUG_UART_SELECT == P11_UART0) {
|
|
gpio_set_fun_output_port(tx_port, P11_FO_UART0_TX, 1, 1);
|
|
}
|
|
|
|
#if DEBUG_UART_RX_ENABLE
|
|
u32 ot_value = 0;
|
|
if (DEBUG_UART_SELECT == P11_UART0) {
|
|
//rx io init:
|
|
gpio_set_direction(DEBUG_UART_RX_IO, 1);
|
|
gpio_set_pull_up(DEBUG_UART_RX_IO, 1);
|
|
gpio_set_pull_down(DEBUG_UART_RX_IO, 0);
|
|
gpio_set_die(DEBUG_UART_RX_IO, 1);
|
|
//iomc:
|
|
gpio_set_fun_input_port(DEBUG_UART_RX_IO, PFI_UART0_RX);
|
|
|
|
//rx config:
|
|
UART_OT_PENDING_CLEAR(P11_UART0);
|
|
UART_RX_PENDING_CLEAR(P11_UART0);
|
|
ot_value = (uart_src_clk_get() * DEBUG_UART_RX_OVERTIME) / 1000;
|
|
UART_OTCNT_SET(P11_UART0, ot_value);
|
|
UART_OT_INT_ENABLE(P11_UART0);
|
|
UART_RX_INT_ENABLE(P11_UART0);
|
|
UART_RX_ENABLE(P11_UART0);
|
|
P11_CLOCK->WKUP_EN |= BIT(IRQ_UART0_IDX);
|
|
request_irq(IRQ_UART0_IDX, uart0_isr, 0);
|
|
}
|
|
#endif /* #if DEBUG_UART_RX_ENABLE */
|
|
|
|
UART_TX_ENABLE(DEBUG_UART_SELECT);
|
|
|
|
init = 1;
|
|
}
|
|
void uart_putbyte(char a)
|
|
{
|
|
u32 ot = 400;
|
|
while (!UART_TX_PENDING_IS(DEBUG_UART_SELECT)) {
|
|
if (ot-- == 0) {
|
|
break;
|
|
}
|
|
}
|
|
UART_TX_PENDING_CLEAR(DEBUG_UART_SELECT);
|
|
UART_BUF_WRITE(DEBUG_UART_SELECT, a);
|
|
}
|
|
__WEAK__
|
|
void putchar(char a)
|
|
{
|
|
if (init == 0) {
|
|
return;
|
|
}
|
|
|
|
if (a == '\r') {
|
|
return;
|
|
}
|
|
|
|
if (a == '\n') {
|
|
uart_putbyte('\r');
|
|
}
|
|
uart_putbyte(a);
|
|
}
|
|
|
|
__WEAK__
|
|
void putbyte(char a)
|
|
{
|
|
putchar(a);
|
|
}
|
|
|
|
#include "power_interface.h"
|
|
|
|
static P11_UART_TypeDef UART0_POWEROFF;
|
|
|
|
static u8 uart_enter_deepsleep(void)
|
|
{
|
|
UART0_POWEROFF.CON0 = DEBUG_UART_SELECT->CON0;
|
|
UART0_POWEROFF.CON1 = DEBUG_UART_SELECT->CON1;
|
|
UART0_POWEROFF.CON2 = DEBUG_UART_SELECT->CON2;
|
|
UART0_POWEROFF.BAUD = DEBUG_UART_SELECT->BAUD;
|
|
UART0_POWEROFF.OTCNT = DEBUG_UART_SELECT->OTCNT;
|
|
|
|
return 0;
|
|
}
|
|
|
|
static u8 uart_exit_deepsleep(void)
|
|
{
|
|
DEBUG_UART_SELECT->CON1 = UART0_POWEROFF.CON1;
|
|
DEBUG_UART_SELECT->BAUD = UART0_POWEROFF.BAUD;
|
|
DEBUG_UART_SELECT->OTCNT = UART0_POWEROFF.OTCNT;
|
|
DEBUG_UART_SELECT->CON2 = UART0_POWEROFF.CON2;
|
|
|
|
DEBUG_UART_SELECT->CON0 = UART0_POWEROFF.CON0;
|
|
DEBUG_UART_SELECT->CON0 |= (BIT(13) | BIT(12) | BIT(10));
|
|
|
|
return 0;
|
|
}
|
|
|
|
#if CONFIG_UART_DEBUG_ENABLE
|
|
DEEPSLEEP_TARGET_REGISTER(uart) = {
|
|
.name = "uart",
|
|
.enter = uart_enter_deepsleep,
|
|
.exit = uart_exit_deepsleep,
|
|
};
|
|
#endif
|
|
/*-----------------------------------------------------------*/
|