| | |
| | | .dma_tx_ch = DMA_CH7, |
| | | }, |
| | | }; |
| | | //ÒÆÖ² |
| | | uint32_t SerialKeyPressed(uint8_t *key)//ÅжÏÊý¾ÝÊÇ·ñÊÕµ½µÄ MK8000ÐÞ¸Ä |
| | | { |
| | | uint32_t status = uart_handle[1].base->STATUS; |
| | | if (status & UART_STATUS_DR_MSK) |
| | | { |
| | | //Serial0PutString("³É¹¦½ÓÊÕing"); |
| | | //uart_receive(UART_ID1,test_buf,10,NULL); |
| | | *key = (uint8_t)uart_handle[1].base->RX_DATA; |
| | | //uart_rx_fifo_clear(UART_ID1); |
| | | return 1; |
| | | } |
| | | else |
| | | { |
| | | return 0; |
| | | } |
| | | } |
| | | void SerialPutChar(uint8_t c) |
| | | { |
| | | while (uart_handle[0].base->TX_FL) |
| | | { |
| | | } |
| | | uart_send(UART_ID1, &c, 1, NULL); |
| | | } |
| | | |
| | | void Serial_PutString(uint8_t *s) |
| | | { |
| | | while (*s != '\0') |
| | | { |
| | | SerialPutChar(*s); |
| | | s++; |
| | | } |
| | | } |
| | | void Serial0PutChar(uint8_t c) |
| | | { //ÅжÏÊý¾Ý»º´æÇøÎª¿Õ¼´ÉÏÒ»¸ö×Ö½ÚÊý¾ÝÒѾ±»Ë͵½·¢ËͼĴæÆ÷·¢ËͳöÈ¥ÁË |
| | | { |
| | | // wait TX FIFO empty |
| | | while (uart_handle[0].base->TX_FL) |
| | | { |
| | |
| | | // update state |
| | | switch (uart_handle[id].state) |
| | | { |
| | | case UART_STATE_READY: |
| | | uart_handle[id].state = state; |
| | | break; |
| | | case UART_STATE_BUSY_RX: |
| | | if (state == UART_STATE_BUSY_TX) |
| | | { |
| | | uart_handle[id].state = UART_STATE_BUSY_TX_RX; |
| | | } |
| | | else |
| | | { |
| | | case UART_STATE_READY: |
| | | uart_handle[id].state = state; |
| | | break; |
| | | case UART_STATE_BUSY_RX: |
| | | if (state == UART_STATE_BUSY_TX) |
| | | { |
| | | uart_handle[id].state = UART_STATE_BUSY_TX_RX; |
| | | } |
| | | else |
| | | { |
| | | ret = DRV_BUSY; |
| | | } |
| | | break; |
| | | case UART_STATE_BUSY_TX: |
| | | if (state == UART_STATE_BUSY_RX) |
| | | { |
| | | uart_handle[id].state = UART_STATE_BUSY_TX_RX; |
| | | } |
| | | else |
| | | { |
| | | ret = DRV_BUSY; |
| | | } |
| | | break; |
| | | case UART_STATE_BUSY_TX_RX: |
| | | ret = DRV_BUSY; |
| | | } |
| | | break; |
| | | case UART_STATE_BUSY_TX: |
| | | if (state == UART_STATE_BUSY_RX) |
| | | { |
| | | uart_handle[id].state = UART_STATE_BUSY_TX_RX; |
| | | } |
| | | else |
| | | { |
| | | ret = DRV_BUSY; |
| | | } |
| | | break; |
| | | case UART_STATE_BUSY_TX_RX: |
| | | ret = DRV_BUSY; |
| | | break; |
| | | case UART_STATE_RESET: |
| | | case UART_STATE_TIMEOUT: |
| | | case UART_STATE_ERROR: |
| | | ret = DRV_ERROR; |
| | | break; |
| | | break; |
| | | case UART_STATE_RESET: |
| | | case UART_STATE_TIMEOUT: |
| | | case UART_STATE_ERROR: |
| | | ret = DRV_ERROR; |
| | | break; |
| | | } |
| | | int_unlock(lock); |
| | | |
| | |
| | | while (uart_handle[id].tx_count < uart_handle[id].tx_size) |
| | | { |
| | | status = uart_handle[id].base->STATUS; |
| | | if (status & (UART_STATUS_OE_MSK | UART_STATUS_PE_MSK | UART_STATUS_FE_MSK | UART_STATUS_BI_MSK | UART_STATUS_RFE_MSK)) |
| | | { |
| | | // TODO: user handle the error case |
| | | uart_handle[id].base->INTR_CLR = UART_INTR_CLR_LSR_INT_CLR_MSK; |
| | | status |= UART_ERR_LINE; |
| | | ret = DRV_ERROR; |
| | | break; |
| | | } |
| | | |
| | | if (uart_handle[id].base->STATUS & UART_STATUS_TFNF_MSK) |
| | | { |
| | |
| | | if (status & (UART_STATUS_OE_MSK | UART_STATUS_PE_MSK | UART_STATUS_FE_MSK | UART_STATUS_BI_MSK | UART_STATUS_RFE_MSK)) |
| | | { |
| | | // TODO: user handle the error case |
| | | // Clear error bits |
| | | uart_handle[id].base->INTR_CLR = UART_INTR_CLR_LSR_INT_CLR_MSK; |
| | | status |= UART_ERR_LINE; |
| | | ret = DRV_ERROR; |
| | | break; |
| | |
| | | } |
| | | |
| | | return ret; |
| | | } |
| | | |
| | | void uart_send_over_fifo(enum UART_DEV_T id, uint8_t *tx_buf, uint32_t len) |
| | | { |
| | | for (uint32_t i = 0; i < len; i++) |
| | | { |
| | | uart_handle[id].base->TX_DATA = tx_buf[i]; |
| | | } |
| | | } |
| | | |
| | | uint32_t uart_receive_from_fifo(enum UART_DEV_T id, uint8_t *rx_buf, uint32_t len) |
| | | { |
| | | for (uint32_t i = 0; i < len; i++) |
| | | { |
| | | uint32_t status = uart_handle[id].base->STATUS; |
| | | |
| | | if (status & UART_STATUS_RFNE_MSK) |
| | | { |
| | | rx_buf[i] = (uint8_t)uart_handle[id].base->RX_DATA; |
| | | } |
| | | else |
| | | { |
| | | return i; |
| | | } |
| | | } |
| | | |
| | | return len; |
| | | } |
| | | |
| | | int uart_tx_abort_dma(enum UART_DEV_T id, drv_callback_t abort_tx_callback) |
| | |
| | | void uart_irq_handler(enum UART_DEV_T id) |
| | | { |
| | | drv_callback_t usr_callback = NULL; |
| | | uint32_t err_code = 0; |
| | | |
| | | // read interrupt ID |
| | | uint8_t iid = uart_handle[id].base->INTR_STATUS & 0x0f; |
| | | uint32_t err_code = uart_handle[id].base->STATUS; |
| | | |
| | | // If DMA is enabled, the uart interrupt handler is only used to handle the error events reported by the receiver |
| | | if (uart_handle[id].dma_en) |
| | | { |
| | | #if UART_DMA_MODE_EN |
| | | err_code = uart_handle[id].base->STATUS; |
| | | // iid == 0xC: The precondition that the timeout event will not be triggered is that the length of |
| | | // the received data is an integer multiple of the RX FIFO level |
| | | if ((err_code & UART_STATUS_ERROR_MSK) || (iid == 0x0C) || (iid == 0x01)) |
| | | if (err_code & UART_STATUS_ERROR_MSK) |
| | | { |
| | | // RX err - disable interrupts |
| | | uart_handle[id].base->INTR_EN &= ~UART_INTR_EN_ELSI_MSK; |
| | | uart_handle[id].base->INTR_CLR = UART_INTR_CLR_LSR_INT_CLR_MSK; |
| | | uart_handle[id].dma_rx_err_state = UART_ERR_LINE | iid; |
| | | uart_handle[id].dma_rx_err_state = UART_ERR_LINE; |
| | | usr_callback = uart_handle[id].rx_callback; |
| | | err_code = UART_ERR_LINE | iid; |
| | | err_code |= UART_ERR_LINE; |
| | | |
| | | // update state |
| | | uart_state_clear(id, UART_STATE_BUSY_RX); |
| | |
| | | else |
| | | { |
| | | #if UART_INT_MODE_EN |
| | | // read interrupt ID |
| | | uint8_t iid = uart_handle[id].base->INTR_STATUS & 0x0f; |
| | | |
| | | switch (iid) |
| | | { |
| | | // modem status |
| | | case 0x0: |
| | | // clear int |
| | | uart_handle[id].base->INTR_CLR = UART_INTR_CLR_MSR_INT_CLR_MSK; |
| | | err_code = UART_ERR_MODEM | iid; |
| | | break; |
| | | case 0x0: |
| | | // clear int |
| | | uart_handle[id].base->INTR_CLR = UART_INTR_CLR_MSR_INT_CLR_MSK; |
| | | err_code |= UART_ERR_MODEM; |
| | | break; |
| | | |
| | | // no interrupt pending |
| | | case 0x1: |
| | | break; |
| | | case 0x1: |
| | | break; |
| | | |
| | | // TX_DATA empty |
| | | case 0x2: |
| | | // clear int |
| | | uart_handle[id].base->INTR_CLR = UART_INTR_CLR_THRE_INT_CLR_MSK; |
| | | if ((uart_handle[id].state == UART_STATE_BUSY_TX) || (uart_handle[id].state == UART_STATE_BUSY_TX_RX)) |
| | | { |
| | | if (uart_handle[id].tx_count == uart_handle[id].tx_size) |
| | | case 0x2: |
| | | // clear int |
| | | uart_handle[id].base->INTR_CLR = UART_INTR_CLR_THRE_INT_CLR_MSK; |
| | | if ((uart_handle[id].state == UART_STATE_BUSY_TX) || (uart_handle[id].state == UART_STATE_BUSY_TX_RX)) |
| | | { |
| | | // TX done - disable interrupt |
| | | uart_handle[id].base->INTR_EN &= ~UART_INTR_EN_ETBEI_MSK; |
| | | usr_callback = uart_handle[id].tx_callback; |
| | | if (uart_handle[id].tx_count == uart_handle[id].tx_size) |
| | | { |
| | | // TX done - disable interrupt |
| | | uart_handle[id].base->INTR_EN &= ~UART_INTR_EN_ETBEI_MSK; |
| | | usr_callback = uart_handle[id].tx_callback; |
| | | |
| | | // update state |
| | | uart_state_clear(id, UART_STATE_BUSY_TX); |
| | | // update state |
| | | uart_state_clear(id, UART_STATE_BUSY_TX); |
| | | |
| | | uart_handle[id].tx_buff = NULL; |
| | | uart_handle[id].tx_callback = NULL; |
| | | uart_handle[id].tx_count = 0; |
| | | uart_handle[id].tx_size = 0; |
| | | uart_handle[id].tx_buff = NULL; |
| | | uart_handle[id].tx_callback = NULL; |
| | | uart_handle[id].tx_count = 0; |
| | | uart_handle[id].tx_size = 0; |
| | | } |
| | | else |
| | | { |
| | | // TX continue - write data to FIFO |
| | | while ((uart_handle[id].tx_count < uart_handle[id].tx_size) && (uart_handle[id].base->STATUS & UART_STATUS_TFNF_MSK)) |
| | | { |
| | | uart_handle[id].base->TX_DATA = uart_handle[id].tx_buff[uart_handle[id].tx_count++]; |
| | | } |
| | | } |
| | | } |
| | | else |
| | | { |
| | | // TX continue - write data to FIFO |
| | | while ((uart_handle[id].tx_count < uart_handle[id].tx_size) && (uart_handle[id].base->STATUS & UART_STATUS_TFNF_MSK)) |
| | | { |
| | | uart_handle[id].base->TX_DATA = uart_handle[id].tx_buff[uart_handle[id].tx_count++]; |
| | | } |
| | | // should not get this interrupt in any other state |
| | | ASSERT(0, "Uart %d state goes wrong %d", id, uart_handle[id].state); |
| | | } |
| | | } |
| | | else |
| | | { |
| | | // should not get this interrupt in any other state |
| | | ASSERT(0, "Uart %d state goes wrong %d", id, uart_handle[id].state); |
| | | } |
| | | break; |
| | | break; |
| | | |
| | | // timeout |
| | | case 0xc: |
| | | case 0xc: |
| | | // No characters in or out of the RCVR FIFO during the last 4 character times and |
| | | // there is at least 1 character in it during this time |
| | | |
| | | // received data available |
| | | case 0x4: |
| | | if ((uart_handle[id].state == UART_STATE_BUSY_RX) || (uart_handle[id].state == UART_STATE_BUSY_TX_RX)) |
| | | { |
| | | // uint8_t len = uart_handle[id].base->RX_FL; |
| | | while ((uart_handle[id].rx_count < uart_handle[id].rx_size) && (uart_handle[id].base->STATUS & UART_STATUS_RFNE_MSK)) |
| | | case 0x4: |
| | | if ((uart_handle[id].state == UART_STATE_BUSY_RX) || (uart_handle[id].state == UART_STATE_BUSY_TX_RX)) |
| | | { |
| | | uint8_t data = (uint8_t)uart_handle[id].base->RX_DATA; |
| | | uart_handle[id].rx_buff[uart_handle[id].rx_count++] = data; |
| | | } |
| | | // uint8_t len = uart_handle[id].base->RX_FL; |
| | | while ((uart_handle[id].rx_count < uart_handle[id].rx_size) && (uart_handle[id].base->STATUS & UART_STATUS_RFNE_MSK)) |
| | | { |
| | | uint8_t data = (uint8_t)uart_handle[id].base->RX_DATA; |
| | | uart_handle[id].rx_buff[uart_handle[id].rx_count++] = data; |
| | | } |
| | | |
| | | if (uart_handle[id].rx_count == uart_handle[id].rx_size) |
| | | if (uart_handle[id].rx_count == uart_handle[id].rx_size) |
| | | { |
| | | // RX done - disable interrupts |
| | | uart_handle[id].base->INTR_EN &= ~(UART_INTR_EN_ELSI_MSK | UART_INTR_EN_ERBFI_MSK); |
| | | usr_callback = uart_handle[id].rx_callback; |
| | | |
| | | // update state |
| | | uart_state_clear(id, UART_STATE_BUSY_RX); |
| | | |
| | | uart_handle[id].rx_buff = NULL; |
| | | uart_handle[id].rx_callback = NULL; |
| | | uart_handle[id].rx_count = 0; |
| | | uart_handle[id].rx_size = 0; |
| | | } |
| | | } |
| | | else |
| | | { |
| | | // RX done - disable interrupts |
| | | uart_handle[id].base->INTR_EN &= ~(UART_INTR_EN_ELSI_MSK | UART_INTR_EN_ERBFI_MSK); |
| | | usr_callback = uart_handle[id].rx_callback; |
| | | |
| | | // update state |
| | | uart_state_clear(id, UART_STATE_BUSY_RX); |
| | | |
| | | uart_handle[id].rx_buff = NULL; |
| | | uart_handle[id].rx_callback = NULL; |
| | | uart_handle[id].rx_count = 0; |
| | | uart_handle[id].rx_size = 0; |
| | | // received unexpected data |
| | | } |
| | | } |
| | | else |
| | | { |
| | | // received unexpected data |
| | | } |
| | | break; |
| | | break; |
| | | |
| | | // receiver line status |
| | | case 0x6: |
| | | // clear int |
| | | uart_handle[id].base->INTR_CLR = UART_INTR_CLR_LSR_INT_CLR_MSK; |
| | | err_code = UART_ERR_LINE | iid; |
| | | break; |
| | | case 0x6: |
| | | // clear int (Overrun/parity/framing errors, break interrupt, or address received interrupt) |
| | | // RX err - disable interrupts |
| | | uart_handle[id].base->INTR_EN &= ~UART_INTR_EN_ELSI_MSK; |
| | | uart_handle[id].base->INTR_CLR = UART_INTR_CLR_LSR_INT_CLR_MSK; |
| | | usr_callback = uart_handle[id].rx_callback; |
| | | err_code |= UART_ERR_LINE; |
| | | |
| | | uart_handle[id].rx_buff = NULL; |
| | | uart_handle[id].rx_callback = NULL; |
| | | uart_handle[id].rx_count = 0; |
| | | uart_handle[id].rx_size = 0; |
| | | break; |
| | | |
| | | // busy detect |
| | | case 0x7: |
| | | // clear int |
| | | uart_handle[id].base->INTR_CLR = UART_INTR_CLR_BUSY_INT_CLR_MSK; |
| | | err_code = UART_ERR_BUSY | iid; |
| | | break; |
| | | case 0x7: |
| | | // clear int |
| | | uart_handle[id].base->INTR_CLR = UART_INTR_CLR_BUSY_INT_CLR_MSK; |
| | | err_code |= UART_ERR_BUSY; |
| | | break; |
| | | |
| | | default: |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | #endif |
| | | } |