/* * Copyright 2021 MindMotion Microelectronics Co., Ltd. * All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include "hal_lpuart.h" void LPUART_SetBaudrate2(LPU_Type * LPUARTx, uint32_t freq, uint32_t baudrate) { LPUARTx->LPUBAUD |= LPU_LPUBAUD_BREN_MASK; uint32_t base_cycles = freq / baudrate; uint32_t current_cycles = 0; uint32_t ideal_K; uint32_t K; K = 0xFFFFFFFF / freq / 4 * 2; LPUARTx->LPUBAUD |= LPU_LPUBAUD_BR(base_cycles); LPUARTx->MODU = 0; for (uint8_t bit_idx = 0; bit_idx < 12; bit_idx++) { ideal_K = ( (base_cycles * K + 0.5) * (bit_idx + 1) ); current_cycles += base_cycles; if (current_cycles * K >= ideal_K) { continue; } else if ( (ideal_K - current_cycles * K) >= (K / 2) ) { LPUARTx->MODU |= 1 << bit_idx; current_cycles += 1; } } } /* LPUART initialization use LSE(32.768KHz) clock source. */ void LPUART_Init(LPU_Type * LPUARTx, LPUART_Init_Type * init) { uint32_t lpuart_mctl[6] = {0x952, 0xefb, 0x6db, 0x482,0x6d6, 0x842}; if (init->ClockSource == LPUART_ClockSource_LSE) { LPUARTx->LPUBAUD &= ~LPU_LPUBAUD_BREN_MASK; /* BREN = 0, only 32.768KHz clock is supported as clock source. */ LPUARTx->LPUBAUD = LPU_LPUBAUD_BAUD(init->BaudRate); LPUARTx->MODU = lpuart_mctl[init->BaudRate]; } /* WordLength. */ LPUARTx->LPUCON |= LPU_LPUCON_DL(init->WordLength); /* StopBits. */ LPUARTx->LPUCON |= LPU_LPUCON_SL(init->StopBits); /* Parity. */ if (init->Parity == LPUART_Parity_Even) { LPUARTx->LPUCON |= LPU_LPUCON_PAREN_MASK; LPUARTx->LPUCON &= ~LPU_LPUCON_PTYP_MASK; } if (init->Parity == LPUART_Parity_Odd) { LPUARTx->LPUCON |= (LPU_LPUCON_PAREN_MASK | LPU_LPUCON_PTYP_MASK); } } /* LPUART enable tx. */ void LPUART_EnableTx(LPU_Type * LPUARTx, bool enable) { if (enable) { LPUARTx->LPUEN |= LPU_LPUEN_TXEN_MASK; } else { LPUARTx->LPUEN &= ~LPU_LPUEN_TXEN_MASK; } } /* LPUART enable rx. */ void LPUART_EnableRx(LPU_Type * LPUARTx, bool enable) { if (enable) { LPUARTx->LPUEN |= LPU_LPUEN_RXEN_MASK; } else { LPUARTx->LPUEN &= ~LPU_LPUEN_RXEN_MASK; } } /* LPUART get status. */ uint32_t LPUART_GetStatus(LPU_Type * LPUARTx) { return LPUARTx->LPUSTA; } /* LPUART put data. */ void LPUART_PutData(LPU_Type * LPUARTx, uint8_t value) { LPUARTx->LPUTXD = value; } /* LPAURT put data. */ uint8_t LPUART_GetData(LPU_Type * LPUARTx) { return (uint8_t)(LPUARTx->LPURXD & 0xff); } /* LPUART enable interrupt. */ void LPUART_EnableInterrupts(LPU_Type * LPUARTx, uint32_t interrupts, bool enable) { switch (interrupts) { case LPUART_INT_RX_FULL: if (enable) { LPUARTx->LPUCON |= LPU_LPUCON_RXIE_MASK; } else { LPUARTx->LPUCON &= ~LPU_LPUCON_TCIE_MASK; } break; case LPUART_INT_TX_EMPTY: if (enable) { LPUARTx->LPUCON |= LPU_LPUCON_TXIE_MASK; } else { LPUARTx->LPUCON &= ~LPU_LPUCON_TXIE_MASK; } break; case LPUART_INT_TX_DONE: if (enable) { LPUARTx->LPUCON |= LPU_LPUCON_TCIE_MASK; } else { LPUARTx->LPUCON &= ~LPU_LPUCON_TCIE_MASK; } break; default: break; } } /* Get LPUART interrupt status. */ uint32_t LPUART_GetInterruptStatus(LPU_Type * LPUARTx) { return LPUARTx->LPUIF; } /* Get LPUART interrupt enable status. */ uint32_t LPUART_GetEnabledInterrupts(LPU_Type * LPUARTx) { uint32_t flags = 0u; if ( 0u != (LPU_LPUCON_RXIE_MASK & LPUARTx->LPUCON) ) { flags |= LPUART_INT_RX_FULL; } if ( 0u != (LPU_LPUCON_TXIE_MASK & LPUARTx->LPUCON) ) { flags |= LPUART_INT_TX_EMPTY; } if ( 0u != (LPU_LPUCON_TCIE_MASK & LPUARTx->LPUCON) ) { flags |= LPUART_INT_TX_DONE; } return flags; } /* Clear LPUART interrupt status. */ void LPUART_ClearInterruptStatus(LPU_Type * LPUARTx, uint32_t interrupts) { LPUARTx->LPUIF |= interrupts; } /* LPUART enable DMA. */ void LPUART_EnableDMA(LPU_Type * LPUARTx, uint32_t dma, bool enable) { if (enable) { LPUARTx->LPUEN |= dma; } else { LPUARTx->LPUEN &= ~dma; } } /* LPUART get tx data register address. */ uint32_t LPUART_GetTxDataRegAddr(LPU_Type * LPUARTx) { return (uint32_t)(&(LPUARTx->LPUTXD)); } /* LPUART get rx data register address. */ uint32_t LPUART_GetRxDataRegAddr(LPU_Type * LPUARTx) { return (uint32_t)(&(LPUARTx->LPURXD)); } /* EOF. */