bool uart_sps_sw_flow_off(void) { bool flow_off = true; do { // First check if no transmission is ongoing if ((uart_temt_getf() == 0) || (uart_thre_getf() == 0) || !uart_sps_is_rx_fifo_empty()) { flow_off = false; break; } uart_txdata_setf(UART_XOFF_BYTE); // Wait for 1 character duration to ensure host has not started a transmission at the // same time for (int i=0;i<UART_WAIT_BYTE_COUNTER;i++); // Check if data has been received during wait time if(!uart_sps_is_rx_fifo_empty()) { // Re-enable UART flow uart_sps_sw_flow_on(); // We failed stopping the flow flow_off = false; } } while(false); return (flow_off); }
/** **************************************************************************************** * @brief Serves the transmit data fill interrupt requests. It clears the requests and * executes the callback function. * * The callback function is called as soon as the last byte of the provided data is * put into the FIFO. The interrupt is disabled at the same time. **************************************************************************************** */ static void uart_thr_empty_isr(void) { void (*callback) (uint8_t) = NULL; // Fill TX FIFO until there is no more room inside it while (uart_txfifo_full_getf()) { // Put a byte in the FIFO uart_txdata_setf(*uart_env.tx.bufptr); // Update TX parameters uart_env.tx.size--; uart_env.tx.bufptr++; if (uart_env.tx.size == 0) { // Reset TX parameters uart_env.tx.bufptr = NULL; // Disable TX interrupt uart_thr_empty_setf(0); // Retrieve callback pointer callback = uart_env.tx.callback; if(callback != NULL) { // Clear callback pointer uart_env.tx.callback = NULL; // Call handler callback(UART_STATUS_OK); } else { ASSERT_ERR(0); } // Exit loop break; } } }
void uart_sps_sw_flow_on(void) { uart_txdata_setf(UART_XON_BYTE); }
/** **************************************************************************************** * @brief Serves the transmit data fill interrupt requests. It clears the requests and * executes the callback function. The callback function is called as soon as the * last byte of the provided data is put into the FIFO. The interrupt is disabled * at the same time. * * @return void **************************************************************************************** */ static void uart_sps_thr_empty_isr(void) { void (*callback) (uint8_t) = NULL; // Fill TX FIFO until there is no more room inside it while (uart_txfifo_full_getf()) { #if (UART_SW_FLOW_ENABLED) if(*uart_sps_env.tx.state == UART_NONE) #endif { // Put a byte in the FIFO uart_txdata_setf(*uart_sps_env.tx.bufptr); // Update TX parameters uart_sps_env.tx.size--; uart_sps_env.tx.bufptr++; } #if (UART_SW_FLOW_ENABLED) else if(*uart_sps_env.tx.state == UART_XOFF) { uart_txdata_setf(UART_XOFF_BYTE); //push UART XOFF byte } else if (*uart_sps_env.tx.state == UART_XON) { uart_txdata_setf(UART_XON_BYTE); //push UART XON byte } else //undefined state { while(1); //this should never happen } *uart_sps_env.tx.state = UART_NONE; //just send data from now on #endif if (uart_sps_env.tx.size == 0 && *uart_sps_env.tx.state == UART_NONE) { // Reset TX parameters uart_sps_env.tx.bufptr = NULL; // Disable TX interrupt uart_thr_empty_setf(0); // Retrieve callback pointer callback = uart_sps_env.tx.callback; if(callback != NULL) { // Clear callback pointer uart_sps_env.tx.callback = NULL; // Call handler callback(UART_STATUS_OK); } else { ASSERT_ERR(0); } // Exit loop break; } } }