/** **************************************************************************************** * @brief Disable hardware flow control * @param[in] UART QN_UART0 or QN_UART1 * @return TRUE * @description * Disable specified UART port hardware flow control ***************************************************************************************** */ bool uart_flow_off(QN_UART_TypeDef *UART) { //uart_uart_SetCRWithMask(UART, UART_MASK_CTS_EN|UART_MASK_RTS_EN, MASK_DISABLE); //return true; bool rt = false; uint32_t int_restore = 0; // Disable UART interrupt #if CONFIG_ENABLE_DRIVER_UART0==TRUE if(UART == QN_UART0) int_restore = NVIC->ISER[0] & ((1<<UART0_TX_IRQn) | (1<<UART0_RX_IRQn)); #endif #if CONFIG_ENABLE_DRIVER_UART1==TRUE if(UART == QN_UART1) int_restore = NVIC->ISER[0] & ((1<<UART1_TX_IRQn) | (1<<UART1_RX_IRQn)); #endif NVIC->ICER[0] = int_restore; do { // Check if no tx is ongoing if(UART_TX_FREE == uart_check_tx_free(UART)) break; // Disable rx (RTS/CTS -> GPIO high) #if CONFIG_ENABLE_DRIVER_UART0==TRUE if(UART == QN_UART0) { syscon_SetPMCR0WithMask(QN_SYSCON, P02_MASK_PIN_CTRL | P01_MASK_PIN_CTRL, P02_GPIO_2_PIN_CTRL | P01_GPIO_1_PIN_CTRL); gpio_write_pin(GPIO_P02, GPIO_HIGH); gpio_write_pin(GPIO_P01, GPIO_HIGH); } #endif #if CONFIG_ENABLE_DRIVER_UART1==TRUE if(UART == QN_UART1) { // NOTE!!!!! // Assume UART1 used P2.2 and P3.6 as RTS/CTS. Other case this snippet should be modified. syscon_SetPMCR1WithMask(QN_SYSCON, P22_MASK_PIN_CTRL | P36_MASK_PIN_CTRL, P22_GPIO_18_PIN_CTRL | P36_GPIO_30_PIN_CTRL); gpio_write_pin(GPIO_P22, GPIO_HIGH); gpio_write_pin(GPIO_P36, GPIO_HIGH); } #endif // Wait for 1 bytes duration to guarantee host has not started a tx at this time. // Assume buadrate 115200 delay(100); // Check if data has been received during the waiting time if(uart_uart_GetIntFlag(UART) & UART_MASK_RX_IF) { // Switch RTS/CTS back #if CONFIG_ENABLE_DRIVER_UART0==TRUE if(UART == QN_UART0) { syscon_SetPMCR0WithMask(QN_SYSCON, P02_MASK_PIN_CTRL | P01_MASK_PIN_CTRL, P02_UART0_RTS_PIN_CTRL | P01_UART0_CTS_PIN_CTRL); } #endif #if CONFIG_ENABLE_DRIVER_UART1==TRUE if(UART == QN_UART1) { // NOTE!!!!! // Assume UART1 used P2.2 and P3.6 as RTS/CTS. Other case this snippet should be modified. syscon_SetPMCR1WithMask(QN_SYSCON, P22_MASK_PIN_CTRL | P36_MASK_PIN_CTRL, P22_UART1_RTS_PIN_CTRL | P36_UART1_CTS_PIN_CTRL); } #endif // failed. break; } // success. rt = true; } while(false); // Restore uart interrupt status NVIC->ISER[0] = int_restore; return rt; }
/** **************************************************************************************** * @brief Check application whether to enter sleep mode * @return sleep allowed status **************************************************************************************** */ int usr_sleep(void) { int32_t rt; rt = sleep_get_pm(); // If the BLE timer queue is not NULL, prevent entering into DEEPSLEEP mode if(rt == PM_DEEP_SLEEP && !ke_timer_empty()) { rt = PM_SLEEP; } // Check Device status if((rt >= PM_SLEEP) && dev_get_bf()) { // If any devices are still working, the chip cann't enter into SLEEP/DEEPSLEEP mode. rt = PM_IDLE; } if ((rt >= PM_SLEEP) && (!gpio_sleep_allowed())) { return PM_ACTIVE; // If CLOCK OFF & POWER DOWN is disabled, return immediately } #if QN_DBG_PRINT int uart_tx_st = uart_check_tx_free(QN_DEBUG_UART); if((rt >= PM_SLEEP) && (uart_tx_st == UART_TX_BUF_BUSY)) { rt = PM_IDLE; } else if(uart_tx_st == UART_LAST_BYTE_ONGOING) { return PM_ACTIVE; // If CLOCK OFF & POWER DOWN is disabled, return immediately } #endif #if QN_EACI if((GPIO_LOW == gpio_read_pin(QN_EACI_GPIO_WAKEUP_QN_MCU)) // Check external wakeup source || (eaci_env.tx_state!=EACI_STATE_TX_IDLE) // Check EACI UART TX status || (eaci_env.rx_state!=EACI_STATE_RX_START)) // Check EACI UART RX status { rt = PM_IDLE; } int tx_st = uart_check_tx_free(QN_HCI_UART); if((rt >= PM_SLEEP) && (tx_st == UART_TX_BUF_BUSY)) { rt = PM_IDLE; } else if(tx_st == UART_LAST_BYTE_ONGOING) { return PM_ACTIVE; // If CLOCK OFF & POWER DOWN is disabled, return immediately } #endif #if QN_COM if((GPIO_LOW == gpio_read_pin(QN_EACI_GPIO_WAKEUP_QN_MCU)) // Check external wakeup source || (eaci_env.tx_state!=EACI_STATE_TX_IDLE) // Check EACI UART TX status || (eaci_env.rx_state!=EACI_STATE_RX_START)) // Check EACI UART RX status { rt = PM_IDLE; } int tx_st = uart_check_tx_free(QN_COM_UART); if((rt >= PM_SLEEP) && (tx_st == UART_TX_BUF_BUSY)) { rt = PM_IDLE; } else if(tx_st == UART_LAST_BYTE_ONGOING) { return PM_ACTIVE; // If CLOCK OFF & POWER DOWN is disabled, return immediately } #endif return rt; }