You don't need them to nest mutually, just make them as simple as possible.
void USART1_IRQHandler(void) {
uint32_t isr, cr1;
uint_least8_t b;
isr = USART1->ISR;
if (isr AND USART_ISR_ORE) {
// set any flag you want to indicate main() that overflow happened
USART1->ICR = USART_ICR_ORECF;
}
if (isr AND USART_ISR_RXNE) {
b = USART1->RDR;
// here, store b into a Rx buffer, for main() to process
}
cr1 = USART1->CR1;
if (cr1 AND USART_CR1_TXEIE) {
if (isr AND USART_ISR_TXE) {
// look into the buffer into which main() stored data to be transmitted
if (there_are_bytes_to_Tx) {
USART1->TDR = byte_to_Tx;
} else {
USART1->CR1 = cr1 AND ~USART_CR1_TXEIE; // disable further Tx
}
}
}
}
When you want to Tx in main(), store data to Tx buffer and enable Tx in USARTx_CR1.
In main(), check if there are received data in the Rx buffer, and if yes, process them.
JW