#include #include #include void modemISR() { uint32_t isrflags = READ_REG(modemUart.Instance->SR); uint32_t cr1its = READ_REG(modemUart.Instance->CR1); // RXNEIE doesn't need to be considered since it is always on and more over the // RXNE flag is cleared by reading the DR, which is done in any case if (((isrflags & USART_SR_RXNE) != RESET) || ((isrflags & (USART_SR_ORE | USART_SR_FE | USART_SR_PE | USART_SR_NE)) != RESET)) { // Error flags are only valid together with the RX flag. // They will be cleared by reading SR (already done above) followed by reading DR (below). bool errorFound = false; if ((isrflags & USART_SR_ORE) != RESET) { mbusCommStats.uartOverrunCnt += 1; errorFound = true; } if ((isrflags & USART_SR_FE) != RESET) { mbusCommStats.uartFramingErrCnt += 1; errorFound = true; } if ((isrflags & USART_SR_PE) != RESET) { mbusCommStats.uartParityErrCnt += 1; errorFound = true; } if ((isrflags & USART_SR_NE) != RESET) { mbusCommStats.uartNoiseErrCnt += 1; errorFound = true; } mbusCommStats.uartOctetCnt += 1; // it is required to read the DR in any case here, not only when the buffer has space // otherwise the interrupt flag won't be reset, particularly important in case of ORE uint8_t data = (uint8_t)(mbusUart.Instance->DR & (uint8_t)0x00FF); if ((! errorFound) && (mbusCommHandle.receiveBuffer.writeIdx < mbusCommHandle.receiveBuffer.size)) { mbusCommHandle.receiveBuffer.buffer[mbusCommHandle.receiveBuffer.writeIdx] = data; mbusCommHandle.receiveBuffer.writeIdx += 1; } } // TXEIE needs to be considered since TXE is cleared by writing the DR, which isn't done // after the last octet sent if (((isrflags & USART_SR_TXE) != RESET) && ((cr1its & USART_CR1_TXEIE) != RESET)) { if (mbusCommHandle.sendBuffer.readIdx < mbusCommHandle.sendBuffer.writeIdx) { mbusUart.Instance->DR = mbusCommHandle.sendBuffer.buffer[mbusCommHandle.sendBuffer.readIdx]; mbusCommHandle.sendBuffer.readIdx += 1; if (mbusCommHandle.sendBuffer.readIdx == mbusCommHandle.sendBuffer.writeIdx) { __HAL_UART_DISABLE_IT(&mbusUart, UART_IT_TXE); __HAL_UART_ENABLE_IT(&mbusUart, UART_IT_TC); } } } // advance the state for the engine only when the last octet is shifted out completely if (((isrflags & USART_SR_TC) != RESET) && ((cr1its & USART_CR1_TCIE) != RESET)) { __HAL_UART_DISABLE_IT(&mbusUart, UART_IT_TC); mbusCommHandle.state = MBCS_SENDING_DONE; } }