#include "board.h" void lpuart0_drv_init(uint8_t baud) { // LPUART0_RX: PD09(AF1) GpioInit(PD09_LPUART0_RXD, GPIO_DIG_IN_PULLUP_NONEDOWN); PeriClk_MutEnable(PeriClk_LpUart0); M0P_LPUART0->SCON = (0<<21) | // FEIE, Frame error interrupt 0:close; 1:open; (0<<17) | // DMATXEN, TX DMAC handshake 0:close; 1:open; (0<<16) | // DMARXEN, RX DMAC handshake 0:close; 1:open; (0<<14) | // STOPBIT, Stop bit length, 0:1-bit; 1:1.5-bits; 2:2-bits; 3:RSV (0<<13) | // PEIE, Parity error interrupt 0:close; 1:open; (baud<<11) | // SCLKSEL, 0,1:PCLK; 2:XTL; 3:RCL; (2<<9) | // OVER, 0:16x-sample; 1:8x-sample; 2:4x-sample; (0<<8) | // TXEIE, TX empty interrupt 0:close; 1:open; (1<<6) | // SM, 0:mode0; 1:mode1; 2:mode2; 3:mode3; (1<<4) | // REN, in mode1 0:TX only; 1:RX/TX (0<<1) | // TCIE, Tx completed interrupt 0:close; 1:open; (1<<0); // RCIE, Rx completed interrupt 0:close; 1:open; // BaudRate = fSCLK/(OVER*SCNT) = 16MHz/(4*35) = 114286 baud (-0.79%). if (baud == 3) { M0P_LPUART0->SCNT = 1; // 9600 } else { M0P_LPUART0->SCNT = 35; // 115200 } // enable interrupt at NVIC side IRQMutEnable(LPUART0_IRQn, NVIC_PRIO_3); // IRQMutEnable(LPUART1_IRQn, NVIC_PRIO_0); // LPUART0_TX: PD08(AF1) GpioInit(PD08_LPUART0_TXD, GPIO_DIG_OUT_STRN_PUSH_NONEUP_NONEDOWN); SerPlot.f.Preamble = 0xFFFFFFFF; } static uart_rx_itf Lpuart0RxItf; void lpuart0_set_rx_itf(uart_rx_itf itf) { Lpuart0RxItf = itf; } // interrupt routine void LPUART0_IRQHandler(void) { union { uint32_t ISR; stc_uart_isr_field_t ISR_f; } IRQ; #ifdef FINSH_TXBUF_DEPTH rt_base_t level; #endif IRQ.ISR = M0P_LPUART0->ISR; M0P_LPUART0->ICR = ~IRQ.ISR; // write 0 to clear interrupts // receive a ch if (IRQ.ISR_f.RC) { Lpuart0RxItf(M0P_LPUART0->SBUF); } if (IRQ.ISR_f.TXE & M0P_LPUART0->SCON_f.TXEIE) { #ifdef FINSH_TXBUF_DEPTH if (TxRaddr==TxWaddr){ // read FIFO to empty M0P_LPUART0->SCON_f.TXEIE = 0; // disable tx interrupt source } else { M0P_LPUART0->SBUF = (uint32_t)TxBuf[TxRaddr]; level = rt_hw_interrupt_disable(); if (TxRaddr>=(FINSH_TXBUF_DEPTH-1)){ TxRaddr = 0; } else { TxRaddr++; } rt_hw_interrupt_enable(level); } #else M0P_LPUART0->SCON_f.TXEIE = 0; // disable tx interrupt source #endif } // CalExpireTime(120); } void lpuart0_tx_ch(char ch) { #ifdef FINSH_TXBUF_DEPTH // put a ch to TXBUF with nonblocking, drop it if almost full rt_base_t level; uint16_t used; while(1){ used = TxWaddr - TxRaddr; if (TxWaddr=(FINSH_TXBUF_DEPTH-1)){ TxWaddr = 0; } else { TxWaddr++; } M0P_LPUART0->SCON_f.TXEIE = 1; // enable tx interrupt source #ifdef SLEEPDEEP_ENABLE SCB->SCR = (0x0<ISR_f.TXE==0) { // wait until TX empty } M0P_LPUART0->SBUF = (uint32_t)ch; //#ifdef SLEEPDEEP_ENABLE // // wait until TDR is moved to 32.768K clock domain // while (M0P_LPUART1->ISR_f.TXE==0) { // // wait until TX empty // } //#endif return; #endif } void lpuart0_tx_str(char *str) { char ch; uint32_t ClkEn; uint32_t ClkOff; #ifdef DEBUG_NB //WXL2026-5-20 LOG("s:%s",str); #endif ClkEn = M0P_SYSCTRL->PERI_CLKEN0; ClkOff = (~ClkEn) & (1u<