mirror of
https://github.com/g4klx/MMDVM.git
synced 2026-08-21 14:36:21 +02:00
handleIRQ() hardcoded USART1 when clearing the RXNE pending bit, so on boards where the repeater/display UART is not USART1 (Nucleo, Discovery, F767, UART5-based boards) the flag was cleared on the wrong peripheral. Use the m_usart member, matching the TXE handling below. Also fix flush(): it passed a flag constant to USART_GetITStatus and span while TXE was set, which returns immediately since TXE indicates the data register is already empty. Wait for the software TX FIFO to drain and then for the TC flag, which indicates the shift register has actually emptied.
104 lines
2.5 KiB
C++
104 lines
2.5 KiB
C++
/*
|
|
* Copyright (c) 2020 by Jonathan Naylor G4KLX
|
|
* Copyright (c) 2020 by Geoffrey Merck F4FXL - KC3FRA
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*/
|
|
|
|
#if defined(STM32F4XX) || defined(STM32F7XX)
|
|
|
|
#include "STMUART.h"
|
|
|
|
CSTMUART::CSTMUART() :
|
|
m_usart(NULL)
|
|
{
|
|
|
|
}
|
|
|
|
void CSTMUART::init(USART_TypeDef* usart)
|
|
{
|
|
m_usart = usart;
|
|
}
|
|
|
|
void CSTMUART::write(const uint8_t * data, uint16_t length)
|
|
{
|
|
if(length == 0U || m_usart == NULL)
|
|
return;
|
|
|
|
|
|
m_txFifo.put(data[0]);
|
|
USART_ITConfig(m_usart, USART_IT_TXE, ENABLE);//switch TX IRQ is on
|
|
|
|
for(uint16_t i = 1U; i < length; i++) {
|
|
m_txFifo.put(data[i]);
|
|
}
|
|
|
|
USART_ITConfig(m_usart, USART_IT_TXE, ENABLE);//make sure TX IRQ is on
|
|
}
|
|
|
|
uint8_t CSTMUART::read()
|
|
{
|
|
return m_rxFifo.get();
|
|
}
|
|
|
|
void CSTMUART::handleIRQ()
|
|
{
|
|
if(m_usart == NULL)
|
|
return;
|
|
|
|
if (USART_GetITStatus(m_usart, USART_IT_RXNE)) {
|
|
if(!m_rxFifo.isFull())
|
|
m_rxFifo.put((uint8_t) USART_ReceiveData(m_usart));
|
|
USART_ClearITPendingBit(m_usart, USART_IT_RXNE);
|
|
}
|
|
|
|
if (USART_GetITStatus(m_usart, USART_IT_TXE)) {
|
|
if(!m_txFifo.isEmpty())
|
|
USART_SendData(m_usart, m_txFifo.get());
|
|
|
|
USART_ClearITPendingBit(m_usart, USART_IT_TXE);
|
|
|
|
if (m_txFifo.isEmpty()) // if there's no more data to transmit then turn off TX interrupts
|
|
USART_ITConfig(m_usart, USART_IT_TXE, DISABLE);
|
|
}
|
|
}
|
|
|
|
// Flushes the transmit shift register
|
|
// warning: this call is blocking
|
|
void CSTMUART::flush()
|
|
{
|
|
if(m_usart == NULL)
|
|
return;
|
|
|
|
// wait until the TX FIFO has drained
|
|
while (!m_txFifo.isEmpty())
|
|
;
|
|
|
|
// wait until the TC flag shows the shift register is empty
|
|
while (USART_GetFlagStatus(m_usart, USART_FLAG_TC) == RESET)
|
|
;
|
|
}
|
|
|
|
uint16_t CSTMUART::available()
|
|
{
|
|
return m_rxFifo.isEmpty() ? 0U : 1U;
|
|
}
|
|
|
|
uint16_t CSTMUART::availableForWrite()
|
|
{
|
|
return m_txFifo.isFull() ? 0U : 1U;
|
|
}
|
|
|
|
#endif |