/** 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; }
/** 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); } } }
/** * Preprocess the USART rx interrupt * * @param obj_s The serial object * @param pData Pointer to rx buffer * @param Size Size of rx buffer * @return Returns the status */ static gd_status_enum usart_rx_interrupt_preprocess(struct serial_s *obj_s, uint8_t *pData, uint16_t Size) { if (obj_s->rx_state == OP_STATE_READY) { if ((pData == NULL) || (Size == 0U)) { return GD_ERROR; } obj_s->rx_buffer_ptr = pData; obj_s->rx_size = Size; obj_s->rx_count = Size; obj_s->error_code = USART_ERROR_CODE_NONE; obj_s->rx_state = OP_STATE_BUSY_RX; usart_interrupt_enable(obj_s->uart, USART_INT_PERR); usart_interrupt_enable(obj_s->uart, USART_INT_ERR); usart_interrupt_enable(obj_s->uart, USART_INT_RBNE); return GD_OK; } else { return GD_BUSY; } }