/** Handle all the serial interrupt request * * @param obj_s The serial object */ static void usart_irq_handler(struct serial_s *obj_s) { uint32_t err_flags = 0U; /* no error occurs */ err_flags = (USART_STAT0(obj_s->uart) & (uint32_t)(USART_FLAG_PERR | USART_FLAG_FERR | USART_FLAG_ORERR | USART_FLAG_NERR)); if (err_flags == RESET) { /* check whether USART is in receiver mode or not */ if (usart_interrupt_flag_get(obj_s->uart, USART_INT_FLAG_RBNE) != RESET) { usart_rx_interrupt(obj_s); return; } } if (usart_interrupt_flag_get(obj_s->uart, USART_INT_FLAG_TBE) != RESET) { usart_tx_interrupt(obj_s); return; } if (usart_interrupt_flag_get(obj_s->uart, USART_INT_FLAG_TC) != RESET) { usart_tx_complete_interrupt(obj_s); return; } }
/*! \brief this function handles USART RBNE interrupt request and TBE interrupt request \param[in] none \param[out] none \retval none */ void USART0_IRQHandler(void) { if(RESET != usart_interrupt_flag_get(EVAL_COM1, USART_STAT_RBNE,USART_INT_RBNEIE)){ /* receive data */ receiver_buffer[rxcount++] = (usart_data_receive(EVAL_COM1) & 0x7F); if(rxcount == receivesize){ usart_interrupt_disable(EVAL_COM1, USART_INT_RBNEIE); } } if(RESET != usart_interrupt_flag_get(EVAL_COM1, USART_STAT_TC,USART_INT_TBEIE)){ /* transmit data */ usart_data_transmit(EVAL_COM1, transmitter_buffer[txcount++]); if(txcount == transfersize){ usart_interrupt_disable(EVAL_COM1, USART_INT_TBEIE); } } }
/** This function handles USART interrupt handler * * @param usart_index The index of UART * @param usart_periph The UART peripheral */ static void usart_irq(int usart_index, uint32_t usart_periph) { if (serial_irq_ids[usart_index] != 0) { if (usart_interrupt_flag_get(usart_periph, USART_INT_FLAG_TC) != RESET) { usart_interrupt_flag_clear(usart_periph, USART_INT_FLAG_TC); irq_handler(serial_irq_ids[usart_index], TxIrq); } if (usart_interrupt_flag_get(usart_periph, USART_INT_FLAG_RBNE) != RESET) { usart_interrupt_flag_clear(usart_periph, USART_INT_FLAG_RBNE); irq_handler(serial_irq_ids[usart_index], RxIrq); } if (usart_interrupt_flag_get(usart_periph, USART_INT_FLAG_ERR_ORERR) != RESET) { /* clear ORERR error flag by reading USART DATA register */ USART_DATA(usart_periph); } if (usart_interrupt_flag_get(usart_periph, USART_INT_FLAG_ERR_NERR) != RESET) { /* clear NERR error flag by reading USART DATA register */ USART_DATA(usart_periph); } if (usart_interrupt_flag_get(usart_periph, USART_INT_FLAG_ERR_FERR) != RESET) { /* clear FERR error flag by reading USART DATA register */ USART_DATA(usart_periph); } if (usart_interrupt_flag_get(usart_periph, USART_INT_FLAG_PERR) != RESET) { /* clear PERR error flag by reading USART DATA register */ USART_DATA(usart_periph); } } }
/** * Uart common interrupt process. This need add to uart ISR. * * @param serial serial device */ static void uart_isr(struct rt_serial_device *serial) { struct gd32_uart *uart = (struct gd32_uart *) serial->parent.user_data; RT_ASSERT(uart != RT_NULL); /* UART in mode Receiver */ if ((usart_interrupt_flag_get(uart->uart_periph, USART_INT_FLAG_RBNE) != RESET) && (usart_flag_get(uart->uart_periph, USART_FLAG_RBNE) != RESET)) { rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); /* Clear RXNE interrupt flag */ usart_flag_clear(uart->uart_periph, USART_FLAG_RBNE); } }
/** The asynchronous TX and RX handler. * * @param obj The serial object * @return Returns event flags if an RX transfer termination condition was met; otherwise returns 0 */ int serial_irq_handler_asynch(serial_t *obj) { struct serial_s *p_obj = GET_SERIAL_S(obj); volatile uint8_t i = 0; volatile int return_val = 0; uint8_t *p_buf = (uint8_t *)(obj->rx_buff.buffer); if (usart_interrupt_flag_get(p_obj->uart, USART_INT_FLAG_PERR) != RESET) { /* clear PERR error flag by reading USART DATA register */ USART_DATA(p_obj->uart); return_val |= (SERIAL_EVENT_RX_PARITY_ERROR & p_obj->events); p_obj->error_code |= USART_ERROR_CODE_PERR; } if (usart_interrupt_flag_get(p_obj->uart, USART_INT_FLAG_ERR_FERR) != RESET) { /* clear FERR error flag by reading USART DATA register */ USART_DATA(p_obj->uart); return_val |= (SERIAL_EVENT_RX_FRAMING_ERROR & p_obj->events); p_obj->error_code |= USART_ERROR_CODE_FERR; } if (usart_interrupt_flag_get(p_obj->uart, USART_INT_FLAG_ERR_ORERR) != RESET) { /* clear ORERR error flag by reading USART DATA register */ USART_DATA(p_obj->uart); return_val |= (SERIAL_EVENT_RX_OVERRUN_ERROR & p_obj->events); p_obj->error_code |= USART_ERROR_CODE_ORERR; } if (return_val & (SERIAL_EVENT_RX_PARITY_ERROR | SERIAL_EVENT_RX_FRAMING_ERROR | SERIAL_EVENT_RX_OVERRUN_ERROR)) { return return_val; } if (usart_interrupt_flag_get(p_obj->uart, USART_INT_FLAG_TC) != RESET) { if ((p_obj->events & SERIAL_EVENT_TX_COMPLETE) != 0) { return_val |= (SERIAL_EVENT_TX_COMPLETE & p_obj->events); } } usart_irq_handler(p_obj); if (p_obj->rx_size != 0) { obj->rx_buff.pos = p_obj->rx_size - p_obj->rx_count; } if ((p_obj->rx_count == 0) && (obj->rx_buff.pos >= (obj->rx_buff.length - 1))) { return_val |= (SERIAL_EVENT_RX_COMPLETE & p_obj->events); } if (p_obj->events & SERIAL_EVENT_RX_CHARACTER_MATCH) { if (p_buf != NULL) { for (i = 0; i < obj->rx_buff.pos; i++) { if (p_buf[i] == obj->char_match) { obj->rx_buff.pos = i; return_val |= (SERIAL_EVENT_RX_CHARACTER_MATCH & p_obj->events); serial_rx_abort_asynch(obj); break; } } } } return return_val; }