/** Abort the ongoing TX transaction. It disables the enabled interupt for TX and * flushes the TX hardware buffer if TX FIFO is used * * @param obj The serial object */ void serial_tx_abort_asynch(serial_t *obj) { struct serial_s *p_obj = GET_SERIAL_S(obj); usart_interrupt_disable(p_obj->uart, USART_INT_TC); usart_interrupt_disable(p_obj->uart, USART_INT_TBE); usart_flag_clear(p_obj->uart, USART_FLAG_TC); p_obj->tx_count = 0; p_obj->tx_state = OP_STATE_READY; }
/** Handle the serial tx interrupt * * @param obj_s The serial object * @return Returns the status */ static gd_status_enum usart_tx_interrupt(struct serial_s *obj_s) { uint16_t *temp; if (obj_s->tx_state == OP_STATE_BUSY_TX) { if (obj_s->databits == USART_WL_9BIT) { temp = (uint16_t *) obj_s->tx_buffer_ptr; USART_DATA(obj_s->uart) = (uint16_t)(*temp & (uint16_t)0x01FF); if (obj_s->parity == USART_PM_NONE) { obj_s->tx_buffer_ptr += 2U; } else { obj_s->tx_buffer_ptr += 1U; } } else { USART_DATA(obj_s->uart) = (uint8_t)(*obj_s->tx_buffer_ptr++ & (uint8_t)0x00FF); } if (--obj_s->tx_count == 0U) { /* disable USART_INT_TBE interrupt */ usart_interrupt_disable(obj_s->uart, USART_INT_TBE); /* enable USART_INT_TC interrupt */ usart_interrupt_enable(obj_s->uart, USART_INT_TC); } return GD_OK; } else { return GD_BUSY; } }
static rt_err_t gd32_control(struct rt_serial_device *serial, int cmd, void *arg) { struct gd32_uart *uart; RT_ASSERT(serial != RT_NULL); uart = (struct gd32_uart *)serial->parent.user_data; switch (cmd) { case RT_DEVICE_CTRL_CLR_INT: /* disable rx irq */ NVIC_DisableIRQ(uart->irqn); /* disable interrupt */ usart_interrupt_disable(uart->uart_periph, USART_INT_RBNE); break; case RT_DEVICE_CTRL_SET_INT: /* enable rx irq */ NVIC_EnableIRQ(uart->irqn); /* enable interrupt */ usart_interrupt_enable(uart->uart_periph, USART_INT_RBNE); break; } return RT_EOK; }
/*! \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); } } }
/** Configure serial interrupt. This function is used for word-approach * * @param obj The serial object * @param irq The serial IRQ type (RX or TX) * @param enable Set to non-zero to enable events, or zero to disable them */ void serial_irq_set(serial_t *obj, SerialIrq irq, uint32_t enable) { struct serial_s *p_obj = GET_SERIAL_S(obj); IRQn_Type irq_n = (IRQn_Type)0; uint32_t vector = 0; if (p_obj->uart == USART0) { irq_n = USART0_IRQn; vector = (uint32_t)&usart0_irq; } else if (p_obj->uart == USART1) { irq_n = USART1_IRQn; vector = (uint32_t)&usart1_irq; } else if (p_obj->uart == USART2) { irq_n = USART2_IRQn; vector = (uint32_t)&usart2_irq; } else if (p_obj->uart == UART3) { irq_n = UART3_IRQn; vector = (uint32_t)&uart3_irq; } else if (p_obj->uart == UART4) { irq_n = UART4_IRQn; vector = (uint32_t)&uart4_irq; } if (enable) { if (irq == RxIrq) { /* Rx IRQ */ usart_interrupt_enable(p_obj->uart, USART_INT_RBNE); } else { /* Tx IRQ */ usart_interrupt_enable(p_obj->uart, USART_INT_TBE); } NVIC_SetVector(irq_n, vector); NVIC_EnableIRQ(irq_n); } else { if (irq == RxIrq) { /* Rx IRQ */ usart_interrupt_disable(p_obj->uart, USART_INT_RBNE); } else { /* Tx IRQ */ usart_interrupt_disable(p_obj->uart, USART_INT_TBE); } } }
/** Handle the serial rx interrupt * * @param obj_s The serial object * @return Returns the status */ static gd_status_enum usart_rx_interrupt(struct serial_s *obj_s) { uint16_t *temp; if (obj_s->rx_state == OP_STATE_BUSY_RX) { if (obj_s->databits == USART_WL_9BIT) { temp = (uint16_t *) obj_s->rx_buffer_ptr; if (obj_s->parity == USART_PM_NONE) { /* 9-bit data, none parity bit */ *temp = (uint16_t)(USART_DATA(obj_s->uart) & (uint16_t)0x01FF); obj_s->rx_buffer_ptr += 2U; } else { /* 9-bit data, with parity bit */ *temp = (uint16_t)(USART_DATA(obj_s->uart) & (uint16_t)0x00FF); obj_s->rx_buffer_ptr += 1U; } } else { if (obj_s->parity == USART_PM_NONE) { /* 8-bit data, none parity bit */ *obj_s->rx_buffer_ptr++ = (uint8_t)(USART_DATA(obj_s->uart) & (uint8_t)0x00FF); } else { /* 8-bit data, with parity bit */ *obj_s->rx_buffer_ptr++ = (uint8_t)(USART_DATA(obj_s->uart) & (uint8_t)0x007F); } } if (--obj_s->rx_count == 0U) { usart_interrupt_disable(obj_s->uart, USART_INT_RBNE); usart_interrupt_disable(obj_s->uart, USART_INT_PERR); usart_interrupt_disable(obj_s->uart, USART_INT_ERR); obj_s->rx_state = OP_STATE_READY; } return GD_OK; } else { return GD_BUSY; } }
/** Abort the ongoing RX transaction. It disables the enabled interrupt for RX and * flushes the RX hardware buffer if RX FIFO is used * * @param obj The serial object */ void serial_rx_abort_asynch(serial_t *obj) { struct serial_s *p_obj = GET_SERIAL_S(obj); /* disable interrupts */ usart_interrupt_disable(p_obj->uart, USART_INT_RBNE); usart_interrupt_disable(p_obj->uart, USART_INT_PERR); usart_interrupt_disable(p_obj->uart, USART_INT_ERR); /* clear USART_FLAG_RBNE flag */ usart_flag_clear(p_obj->uart, USART_FLAG_RBNE); /* clear errors flag by reading USART STATx register and then USART DATA register */ usart_flag_get(p_obj->uart, USART_FLAG_PERR); usart_flag_get(p_obj->uart, USART_FLAG_FERR); usart_flag_get(p_obj->uart, USART_FLAG_ORERR); USART_DATA(p_obj->uart); /* reset rx transfer count */ p_obj->rx_count = 0; /* reset rx state */ p_obj->rx_state = OP_STATE_READY; }
/** Handle the serial tx complete interrupt * * @param obj_s The serial object */ static void usart_tx_complete_interrupt(struct serial_s *obj_s) { usart_interrupt_disable(obj_s->uart, USART_INT_TC); obj_s->tx_state = OP_STATE_READY; }