UART to SPP Bridge - ESP reboots whenever esp_spp_write() is called

ben3welec
Posts: 7
Joined: Tue Jul 14, 2020 1:06 pm

UART to SPP Bridge - ESP reboots whenever esp_spp_write() is called

Postby ben3welec » Fri Jul 17, 2020 3:44 pm

Hi All, first post ever so hopefully I do this right :)

I'm trying to do something very similar to this post (https://esp32.com/viewtopic.php?t=5499), and likely experiencing a similar problem, but I just can't seem to get around it.

I'm trying to use the esp_spp_write() function to send data received from UART_NUM_1. I've essentially pulled together the code from the "bt_spp_acceptor" and "uart_echo" examples. I've used xTaskCreate to create a task that runs whenever data is received on the uart,
  1. xTaskCreate(uart_rx_task, "my_uart_rx_task", 1024*2, NULL, configMAX_PRIORITIES, NULL);
and in the task uart_rx_task(), I attempt to call the esp_spp_write() function:
  1. static void uart_rx_task() {
  2.     ...
  3.     while (1) {
  4.         const int rxBytes = uart_read_bytes(UART_NUM_1, data, RX_BUF_SIZE, 10 / portTICK_RATE_MS);
  5.         if (rxBytes > 0) {
  6.             data[rxBytes] = 0;
  7.  
  8.             if (spp_param->write.cong == 0) {
  9.             #define RX_STRING_LEN       10
  10.             uint8_t RX_STRING[RX_STRING_LEN] = "CHAR RXED";
  11.  
  12.             esp_spp_write(sppSendHandle, RX_STRING_LEN, RX_STRING);
  13.  
  14.             }
  15.         }
  16.     }
  17.     free(data);
  18. }
In this case I've dumbed it down to just sending a fixed string "CHAR RXED", I'm not even trying to write the data from the buffer yet, but whenever I sent a character through the UART to trigger the uart_rx_task(), the esp32 reboots. The unit does not reboot when I commenting out the esp_spp_write() line, so I think that the uart_rx_task() itself is working ok.

I should mention that I'm setting the send handle for the bluetooth "sppSendHandle" in the esp_spp_cb() callback function when the "ESP_SPP_SRV_OPEN_EVT" occurs.
  1. static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
  2. {
  3.     switch (event) {
  4.     ...
  5.     case ESP_SPP_SRV_OPEN_EVT:
  6.         sppSendHandle = param->srv_open.handle;
  7.         break;
  8.     ...
  9.    }
  10. }
I thought this might have to do with the way I'm calling the esp_spp_write() function outside of the esp_spp_cb() function or my use of the send handle, but I've successfully sent data every 1/2 second using a timer like so:
  1. static void periodic_timer_callback(void* arg) {
  2.     #define TEST_STRING_LEN     5
  3.     uint8_t TEST_STRING[TEST_STRING_LEN] = "TEST";
  4.     esp_spp_write(sppSendHandle, TEST_STRING_LEN, TEST_STRING);
  5. }
So I'm really not sure what I'm doing wrong. Any help to point me in the right direction would be much appreciated!

linuxpaul
Posts: 43
Joined: Thu Jul 20, 2017 6:10 pm

Re: UART to SPP Bridge - ESP reboots whenever esp_spp_write() is called

Postby linuxpaul » Fri Jul 17, 2020 11:02 pm


ben3welec
Posts: 7
Joined: Tue Jul 14, 2020 1:06 pm

Re: UART to SPP Bridge - ESP reboots whenever esp_spp_write() is called

Postby ben3welec » Mon Jul 20, 2020 12:32 pm

Hi linuxpaul,

Thanks for the reply. The pins I'm using for the uart are GPIO4 & 5. The datasheet says to avoid GPIO6-11, so I think I'm ok there. Also, I don't have a problem when I comment out the spp_uart_write() line, so I think everything is working from the standpoint of the uart.

ben3welec
Posts: 7
Joined: Tue Jul 14, 2020 1:06 pm

Re: UART to SPP Bridge - ESP reboots whenever esp_spp_write() is called

Postby ben3welec » Wed Aug 05, 2020 6:18 pm

So as linuxpaul alluded to, I was getting "LoadProhibited" error.

It appears that the error was being somehow caused by the line:

Code: Select all

if (spp_param->write.cong == 0) {}
located in my uart_rx_task(). What had me so stumped for so long was that commenting out lines inside the if statement prevented the exception from occurring. What I didn't realize was that I had effectively removed all lines of executable code within the if statement, and so the compiler was probably then ignoring the if statement itself as well. So it looks like my problem is in the <br/>
spp_param->write.cong statement (the conditional in the if statement), which is a pointer assigned in the esp_spp_cb() function that I conveniently left out of my post above for brevity :oops:. That pointer is most likely pointing to nothing since the thing it points to probably only exists within the scope of the esp_spp_cb().

I'm not sure if this is the "right" way to do it, but I'm now getting the handle of the bluetooth connection and the connection status from the esp_spp_cb() function and saving it into a global structure like so:

Code: Select all

typedef struct {
	uint32_t handle;
	bool congested;
	bool connected;
} uartRxParam_t;

static uartRxParam_t uart_rx_task_params;
...

static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param) {
    ...
    switch (event) {
    ...
    case ESP_SPP_CLOSE_EVT:
    	ESP_LOGI("ESP_SPP_CLOSE_EVT","Connection Closed");
        uart_rx_task_params.connected = 0;
        break;
   ...
     case ESP_SPP_CONG_EVT:
        uart_rx_task_params.congested = param->write.cong;	// Update congestion status
        break;
    ...
    case ESP_SPP_SRV_OPEN_EVT:
        // Store the handle to use for the esp_spp_write() function later on
        uart_rx_task_params.handle = param->srv_open.handle;
        uart_rx_task_params.connected = 1;	// Set connected status as true
        break;
...
    }
}
Then I just call the esp_spp_write(uart_rx_task_params.handle, idata_size, pData) function in whatever task I need it and everything seems to work ok. Again, not sure if this is the "correct" thing to do, but it seems to be working for the moment, and I wanted to post how I resolved the problem.

Who is online

Users browsing this forum: No registered users and 202 guests