Fix BluetoothSerial TX Stall
Fixes: https://github.com/espressif/arduino-esp32/issues/4949
This commit is contained in:
		
							parent
							
								
									5da4a47bdf
								
							
						
					
					
						commit
						5b845272ed
					
				| @ -42,6 +42,10 @@ const char * _spp_server_name = "ESP32SPP"; | ||||
| 
 | ||||
| #define RX_QUEUE_SIZE 512 | ||||
| #define TX_QUEUE_SIZE 32 | ||||
| #define SPP_TX_QUEUE_TIMEOUT 1000 | ||||
| #define SPP_TX_DONE_TIMEOUT 1000 | ||||
| #define SPP_CONGESTED_TIMEOUT 1000 | ||||
| 
 | ||||
| static uint32_t _spp_client = 0; | ||||
| static xQueueHandle _spp_rx_queue = NULL; | ||||
| static xQueueHandle _spp_tx_queue = NULL; | ||||
| @ -143,7 +147,7 @@ static esp_err_t _spp_queue_packet(uint8_t *data, size_t len){ | ||||
|     } | ||||
|     packet->len = len; | ||||
|     memcpy(packet->data, data, len); | ||||
|     if (xQueueSend(_spp_tx_queue, &packet, portMAX_DELAY) != pdPASS) { | ||||
|     if (!_spp_tx_queue || xQueueSend(_spp_tx_queue, &packet, SPP_TX_QUEUE_TIMEOUT) != pdPASS) { | ||||
|         log_e("SPP TX Queue Send Failed!"); | ||||
|         free(packet); | ||||
|         return ESP_FAIL; | ||||
| @ -156,19 +160,25 @@ static uint8_t _spp_tx_buffer[SPP_TX_MAX]; | ||||
| static uint16_t _spp_tx_buffer_len = 0; | ||||
| 
 | ||||
| static bool _spp_send_buffer(){ | ||||
|     if((xEventGroupWaitBits(_spp_event_group, SPP_CONGESTED, pdFALSE, pdTRUE, portMAX_DELAY) & SPP_CONGESTED) != 0){ | ||||
|     if((xEventGroupWaitBits(_spp_event_group, SPP_CONGESTED, pdFALSE, pdTRUE, SPP_CONGESTED_TIMEOUT) & SPP_CONGESTED) != 0){ | ||||
|         if(!_spp_client){ | ||||
|             log_v("SPP Client Gone!"); | ||||
|             return false; | ||||
|         } | ||||
|         log_v("SPP Write %u", _spp_tx_buffer_len); | ||||
|         esp_err_t err = esp_spp_write(_spp_client, _spp_tx_buffer_len, _spp_tx_buffer); | ||||
|         if(err != ESP_OK){ | ||||
|             log_e("SPP Write Failed! [0x%X]", err); | ||||
|             return false; | ||||
|         } | ||||
|         _spp_tx_buffer_len = 0; | ||||
|         if(xSemaphoreTake(_spp_tx_done, portMAX_DELAY) != pdTRUE){ | ||||
|         if(xSemaphoreTake(_spp_tx_done, SPP_TX_DONE_TIMEOUT) != pdTRUE){ | ||||
|             log_e("SPP Ack Failed!"); | ||||
|             return false; | ||||
|         } | ||||
|         return true; | ||||
|     } | ||||
|     log_e("SPP Write Congested!"); | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| @ -194,13 +204,18 @@ static void _spp_tx_task(void * arg){ | ||||
|                 _spp_tx_buffer_len = SPP_TX_MAX; | ||||
|                 data += to_send; | ||||
|                 len -= to_send; | ||||
|                 _spp_send_buffer(); | ||||
|                 if(!_spp_send_buffer()){ | ||||
|                     len = 0; | ||||
|                 } | ||||
|                 while(len >= SPP_TX_MAX){ | ||||
|                     memcpy(_spp_tx_buffer, data, SPP_TX_MAX); | ||||
|                     _spp_tx_buffer_len = SPP_TX_MAX; | ||||
|                     data += SPP_TX_MAX; | ||||
|                     len -= SPP_TX_MAX; | ||||
|                     _spp_send_buffer(); | ||||
|                     if(!_spp_send_buffer()){ | ||||
|                         len = 0; | ||||
|                         break; | ||||
|                     } | ||||
|                 } | ||||
|                 if(len){ | ||||
|                     memcpy(_spp_tx_buffer, data, len); | ||||
| @ -236,9 +251,10 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) | ||||
| 
 | ||||
|     case ESP_SPP_SRV_OPEN_EVT://Server connection open
 | ||||
|         if (param->srv_open.status == ESP_SPP_SUCCESS) { | ||||
|             log_i("ESP_SPP_SRV_OPEN_EVT"); | ||||
|             log_i("ESP_SPP_SRV_OPEN_EVT: %u", _spp_client); | ||||
|             if (!_spp_client){ | ||||
|                 _spp_client = param->srv_open.handle; | ||||
|                 _spp_tx_buffer_len = 0; | ||||
|             } else { | ||||
|                 secondConnectionAttempt = true; | ||||
|                 esp_spp_disconnect(param->srv_open.handle); | ||||
| @ -252,12 +268,13 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) | ||||
| 
 | ||||
|     case ESP_SPP_CLOSE_EVT://Client connection closed
 | ||||
|         if ((param->close.async == false && param->close.status == ESP_SPP_SUCCESS) || param->close.async) { | ||||
|             log_i("ESP_SPP_CLOSE_EVT"); | ||||
|             log_i("ESP_SPP_CLOSE_EVT: %u", secondConnectionAttempt); | ||||
|             if(secondConnectionAttempt) { | ||||
|                 secondConnectionAttempt = false; | ||||
|             } else { | ||||
|                 _spp_client = 0; | ||||
|                 xEventGroupSetBits(_spp_event_group, SPP_DISCONNECTED); | ||||
|                 xEventGroupSetBits(_spp_event_group, SPP_CONGESTED); | ||||
|             }         | ||||
|             xEventGroupClearBits(_spp_event_group, SPP_CONNECTED); | ||||
|         } else { | ||||
| @ -279,11 +296,11 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) | ||||
|             if(param->write.cong){ | ||||
|                 xEventGroupClearBits(_spp_event_group, SPP_CONGESTED); | ||||
|             } | ||||
|             xSemaphoreGive(_spp_tx_done);//we can try to send another packet
 | ||||
|             log_v("ESP_SPP_WRITE_EVT: %u %s", param->write.len, param->write.cong?"CONGESTED":""); | ||||
|         } else { | ||||
|             log_e("ESP_SPP_WRITE_EVT failed!, status:%d", param->write.status); | ||||
|         } | ||||
|         xSemaphoreGive(_spp_tx_done);//we can try to send another packet
 | ||||
|         break; | ||||
| 
 | ||||
|     case ESP_SPP_DATA_IND_EVT://connection received data
 | ||||
| @ -323,6 +340,7 @@ static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) | ||||
|         } | ||||
|         xEventGroupClearBits(_spp_event_group, SPP_DISCONNECTED); | ||||
|         xEventGroupSetBits(_spp_event_group, SPP_CONNECTED); | ||||
|         xEventGroupSetBits(_spp_event_group, SPP_CONGESTED); | ||||
|         break; | ||||
| 
 | ||||
|     case ESP_SPP_START_EVT://server started
 | ||||
| @ -693,7 +711,7 @@ void BluetoothSerial::flush() | ||||
| { | ||||
|     if (_spp_tx_queue != NULL){ | ||||
|         while(uxQueueMessagesWaiting(_spp_tx_queue) > 0){ | ||||
| 	    delay(5); | ||||
|            delay(100); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user