| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- #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<TxRaddr){
- used += FINSH_TXBUF_DEPTH;
- }
- if (used<(FINSH_TXBUF_DEPTH-1)){
- break;
- }
- }
- TxBuf[TxWaddr] = ch;
- level = rt_hw_interrupt_disable();
- 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<<SCB_SCR_SEVONPEND_Pos) |
- (0x0<<SCB_SCR_SLEEPDEEP_Pos) | // sleep
- (0x0<<SCB_SCR_SLEEPONEXIT_Pos);
- #endif
- rt_hw_interrupt_enable(level);
- return;
- #else
- // put a ch to TX data register directly, wait if not empty
- while (M0P_LPUART0->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<<PeriClk_LpUart0);
- if (ClkOff) {
- return;
- }
- while(1){
- ch = *str++;
- if (ch=='\0'){
- return;
- }
- // fow windows, line end is "\r\n"
- //if (ch=='\n'){
- // print_ch('\r');
- //}
- lpuart0_tx_ch(ch);
- }
- }
|