/* * ll_dmadrivenusartcore.cpp * * Created on: Nov 4, 2019 * Author: abody */ #include "f4ll/usartcore.h" namespace f4ll { UsartCore::UsartCore(USART_TypeDef *usart, DMA_TypeDef *dma, uint32_t streamRx, uint32_t streamTx) : m_usart(usart) , m_rxDma(dma, streamRx) , m_txDma(dma, streamTx) { LL_DMA_EnableIT_TC(dma, streamRx); LL_DMA_EnableIT_TE(dma, streamRx); LL_DMA_EnableIT_TC(dma, streamTx); LL_DMA_EnableIT_TE(dma, streamTx); LL_USART_EnableIT_IDLE(usart); LL_USART_EnableIT_ERROR(usart); } void UsartCore::UsartIsr() { if(LL_USART_IsActiveFlag_TC(m_usart) && LL_USART_IsEnabledIT_TC(m_usart)) { // transmission complete LL_USART_DisableIT_TC(m_usart); TransmissionComplete(); } else if(LL_USART_IsEnabledIT_ERROR(m_usart)) { uint32_t status = m_usart->SR; volatile uint32_t tmpreg = m_usart->DR; // clearing some of the error/status bits in the HW (void) tmpreg; if(status & USART_SR_IDLE) { ReceiverIdle(); } if(status & USART_SR_FE) { FramingError(); } if(status & USART_SR_ORE) { Overrun(); } } } void UsartCore::RxDmaIsr() { if(*m_rxDma.GetIsReg() & m_rxDma.GetTcMask()) { *m_rxDma.GetIfcReg() = m_rxDma.GetTcMask(); if(m_rxDma.IsEnabledIt_TC()) RxDmaTransferComplete(); } if(*m_rxDma.GetIsReg() & m_rxDma.GetHtMask()) { *m_rxDma.GetIfcReg() = m_rxDma.GetHtMask(); if(m_rxDma.IsEnabledIt_HT()) RxDmaHalfTransfer(); } if(*m_rxDma.GetIsReg() & m_rxDma.GetTeMask()) { *m_rxDma.GetIfcReg() = m_rxDma.GetTeMask(); if(m_rxDma.IsEnabledIt_TE()) RxDmaError(DmaHelper::DmaErrorType::Transfer); } if(*m_rxDma.GetIsReg() & m_rxDma.GetFeMask()) { *m_rxDma.GetIfcReg() = m_rxDma.GetFeMask(); if(m_rxDma.IsEnabledIt_FE()) RxDmaError(DmaHelper::DmaErrorType::Fifo); } if(*m_rxDma.GetIsReg() & m_rxDma.GetDmeMask()) { *m_rxDma.GetIfcReg() = m_rxDma.GetDmeMask(); if(m_rxDma.IsEnabledIt_DME()) RxDmaError(DmaHelper::DmaErrorType::DirectMode); } } void UsartCore::TxDmaIsr() { if(*m_txDma.GetIsReg() & m_txDma.GetTcMask()) { // DMA transfer complete *m_txDma.GetIfcReg() = m_txDma.GetTcMask(); if(m_txDma.IsEnabledIt_TC()) TxDmaTransferComplete(); } if(*m_txDma.GetIsReg() & m_txDma.GetHtMask()) { *m_txDma.GetIfcReg() = m_txDma.GetHtMask(); if(m_txDma.IsEnabledIt_HT()) TxDmaHalfTransfer(); } if(*m_txDma.GetIsReg() & m_txDma.GetTeMask()) { *m_txDma.GetIfcReg() = m_txDma.GetTeMask(); if(m_txDma.IsEnabledIt_TE()) TxDmaError(DmaHelper::DmaErrorType::Transfer); } if(*m_txDma.GetIsReg() & m_txDma.GetFeMask()) { *m_txDma.GetIfcReg() = m_txDma.GetFeMask(); if(m_txDma.IsEnabledIt_FE()) TxDmaError(DmaHelper::DmaErrorType::Fifo); } if(*m_txDma.GetIsReg() & m_txDma.GetDmeMask()) { *m_txDma.GetIfcReg() = m_txDma.GetDmeMask(); if(m_txDma.IsEnabledIt_DME()) TxDmaError(DmaHelper::DmaErrorType::DirectMode); } } void UsartCore::SetupTransmit(void const *buffer, uint16_t length) { LL_DMA_ConfigAddresses(m_txDma.GetDma(), m_txDma.GetStream(), reinterpret_cast(buffer), LL_USART_DMA_GetRegAddr(m_usart), LL_DMA_DIRECTION_MEMORY_TO_PERIPH); LL_DMA_SetDataLength(m_txDma.GetDma(), m_txDma.GetStream(), length); LL_USART_EnableDMAReq_TX(m_usart); LL_DMA_EnableStream(m_txDma.GetDma(), m_txDma.GetStream()); } void UsartCore::SetupReceive(void *buffer, uint16_t length) { LL_DMA_ConfigAddresses(m_rxDma.GetDma(), m_rxDma.GetStream(), LL_USART_DMA_GetRegAddr(m_usart), reinterpret_cast(buffer), LL_DMA_DIRECTION_PERIPH_TO_MEMORY); LL_DMA_SetDataLength(m_rxDma.GetDma(), m_rxDma.GetStream(), length); LL_USART_EnableDMAReq_RX(m_usart); LL_USART_ClearFlag_ORE(m_usart); LL_DMA_EnableStream(m_rxDma.GetDma(), m_rxDma.GetStream()); } } /* namespace f4ll */