UART to SPP bridge: how to send data from UART to SPP?

newsettler_AI
Posts: 121
Joined: Wed Apr 05, 2017 12:49 pm

UART to SPP bridge: how to send data from UART to SPP?

Postby newsettler_AI » Wed Apr 25, 2018 7:44 am

Hi,
I need to exchange data from PC (by UART) to smartphone over SPP.
Data from UARTmust be send to SPP and SSP data to UART.
Rout SPP-> UART works fine (thanks to loboris for assist ;) ), but I have trouble with handling esp_spp_write function in route UART -> SPP.

Here is prototype:

Code: Select all

/**
 * @brief       This function closes an SPP connection.
 *
 * @param[in]   handle: The connection handle.
 * @param[in]   len:    The length of the data written.
 * @param[in]   p_data: The data written.
 *
 * @return
 *              - ESP_OK: success
 *              - other: failed
 */
esp_err_t esp_spp_write(uint32_t handle, int len, uint8_t *p_data);
I'm not sure which arguments I should send to esp_spp_write in case it is calling in custom functions (not from esp_spp_cb):

Code: Select all

void custom_UART_to_SPP_write(???)
{
    //prepare data to MyData structure
    // ...
    esp_spp_write(???, MyData.UART_data_len, MyData.UART_buffer);
}
Is it corret way to send data outside of spp callbacks?

Markus Becker
Posts: 22
Joined: Fri Mar 02, 2018 3:24 pm

Re: UART to SPP bridge: how to send data from UART to SPP?

Postby Markus Becker » Wed Apr 25, 2018 8:23 pm

Hi newsettler_AI,
you need to somewhow manage the connection(s) anyway, to know if a connection is available at the point in time where you want to send data.
In the callback you can store the handle of a new connection:

Code: Select all

...
   case ESP_SPP_SRV_OPEN_EVT:
    	handle =param->open.handle;
        ESP_LOGI(TAG, "ESP_SPP_SRV_OPEN_EVT handle %d", handle);
        if (!your_connection_register_function(handle)) {
        	ESP_LOGE( TAG, "register SPP Connection failed");
        	break;
        }
...        
Later, if some event indicates the connection is broken, you can unregister the connection handle.
I had no issues, calling esp_spp_write() from an other task, while I didn't try concurrent writes from different tasks, but in many cases some coordination might be required by the apps protocol in that case anyway.

Best
Markus

newsettler_AI
Posts: 121
Joined: Wed Apr 05, 2017 12:49 pm

Re: UART to SPP bridge: how to send data from UART to SPP?

Postby newsettler_AI » Thu Apr 26, 2018 10:38 am

Thanks for advice Markus!

I will controll connection status. But still I'm not sure how param handle should to looks like?

Code: Select all

void SPP_to_UART_write(esp_spp_cb_param_t param)
{
    esp_spp_write(param.write.handle, MyData.UART_len, MyData.UART_buffer);
}

void app_main()
{
    ...  
    // maybe like this?
    esp_spp_cb_param_t my_param;
    my_param.write.handle = ???; // 129 ?
    
    SPP_to_UART_write(my_param)
    ...
}
Under debugging breakpoint at esp_spp_write in callback esp_spp_cb:

Code: Select all

     case ESP_SPP_DATA_IND_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_DATA_IND_EVT len=%d handle=%d", param->data_ind.len, param->data_ind.handle);
        if (param->data_ind.len < 1023)
        {
            if(MyData.UART_got_packet == true)
            {
               esp_spp_write(param->write.handle, MyData.UART_len, MyData.UART_buffer);
               MyData.UART_got_packet = false;
            }
        }
This param looks like this:
esp_spp.jpg
esp_spp.jpg (101.59 KiB) Viewed 13178 times
I tried to set it 129, but I dont receive any data in spp.

chegewara
Posts: 2228
Joined: Wed Jun 14, 2017 9:00 pm

Re: UART to SPP bridge: how to send data from UART to SPP?

Postby chegewara » Thu Apr 26, 2018 11:06 am

handle is uint32_t type:
https://github.com/espressif/esp-idf/bl ... .h#L95-L99

but what is interesting its the len value, i dont think it should be as high, it looks more like address or wrong value.

newsettler_AI
Posts: 121
Joined: Wed Apr 05, 2017 12:49 pm

Re: UART to SPP bridge: how to send data from UART to SPP?

Postby newsettler_AI » Thu Apr 26, 2018 11:25 am

chegewara wrote:handle is uint32_t type:
https://github.com/espressif/esp-idf/bl ... .h#L95-L99

but what is interesting its the len value, i dont think it should be as high, it looks more like address or wrong value.
Yes, this is address.
esp_spp_2.jpg
esp_spp_2.jpg (97.16 KiB) Viewed 13177 times

chegewara
Posts: 2228
Joined: Wed Jun 14, 2017 9:00 pm

Re: UART to SPP bridge: how to send data from UART to SPP?

Postby chegewara » Thu Apr 26, 2018 11:30 am

Why? It should be int type, not int*:

https://github.com/espressif/esp-idf/bl ... api.c#L153

newsettler_AI
Posts: 121
Joined: Wed Apr 05, 2017 12:49 pm

Re: UART to SPP bridge: how to send data from UART to SPP?

Postby newsettler_AI » Thu Apr 26, 2018 11:53 am

chegewara wrote:Why? It should be int type, not int*:

https://github.com/espressif/esp-idf/bl ... api.c#L153
Yes and it is uint32, but in debugger I'm looking at param which comes as address.

In debug log (under CASE in cb section) this looks like this:

SPP_RS485: ESP_SPP_DATA_IND_EVT len=14 handle=129

I think, there is a bit mess with my code and messages, os here is main parts, all together:

Code: Select all

//my structure
typedef struct MyData_s
{
    uint8_t  SPP_buffer[BUF_SIZE];
    uint8_t  UART_buffer[BUF_SIZE];
    uint32_t SPP_len;
    uint32_t UART_len;
    uint8_t  SPP_got_packet;
    uint8_t  UART_got_packet;
    bool     SPP_conn; // TRUE: spp connected
}MyData_t;
MyData_t MyData;

// SPP callback
static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
{
    ... 
    case ESP_SPP_CLOSE_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_CLOSE_EVT"); // when client disconnects
        MyData.SPP_conn = false;
        break;
        
    case ESP_SPP_SRV_OPEN_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_SRV_OPEN_EVT"); // client connected
        FlowMeterData.SPP_conn = true;
        break;
        
    case ESP_SPP_DATA_IND_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_DATA_IND_EVT len=%d handle=%d", param->data_ind.len, param->data_ind.handle);
        if (param->data_ind.len < 1023)
        {
            // this part tranferring data fom SPP to UART (at this stage only fills the proper buffer, later it will be handled)
            memcpy(MyData.SPP_Buf,param->data_ind.data, (size_t)param->data_ind.len);
            MyData.SPP_len = param->data_ind.len;
            MyData.SPP_got_packet = true;
            
            // And this part works ONLY if I send something via SPP (I need independence sending)
            if(MyData.UART_got_packet == true) 
            {
               esp_spp_write(param->write.handle, MyData.UART_len, MyData.UART_buffer);
               MyData.UART_got_packet = false;
            }
        }
    ...
}

// My function that should write data from UART to SPP outside spp callbacks
void SPP_to_UART_write(esp_spp_cb_param_t param)
{
    esp_spp_write(param.write.handle, MyData.UART_len, MyData.UART_buffer);
}

//Main
void app_main()
{
    ...  
    // maybe like this?
    esp_spp_cb_param_t my_param;
    my_param.write.handle = ???; // 129 ?
    
    SPP_to_UART_write(my_param)
    ...
}
Last edited by newsettler_AI on Thu Apr 26, 2018 12:07 pm, edited 2 times in total.

chegewara
Posts: 2228
Joined: Wed Jun 14, 2017 9:00 pm

Re: UART to SPP bridge: how to send data from UART to SPP?

Postby chegewara » Thu Apr 26, 2018 12:00 pm

param is type of union esp_spp_cb_param_t:
https://github.com/espressif/esp-idf/bl ... api.h#L168

For this particular event it will be this structure:
https://github.com/espressif/esp-idf/bl ... #L150-L158


I think this ( my_param.write.handle = ???; // 129 ?) should be somewhere in here:

Code: Select all

    case ESP_SPP_SRV_OPEN_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_SRV_OPEN_EVT"); // client connected
        FlowMeterData.SPP_conn = true;
        <--- HERE
        break;

     case ESP_SPP_DATA_IND_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_DATA_IND_EVT len=%d handle=%d", param->data_ind.len, param->data_ind.handle);
        if (param->data_ind.len < 1023)
        {
 <--- OR HERE
        

newsettler_AI
Posts: 121
Joined: Wed Apr 05, 2017 12:49 pm

Re: UART to SPP bridge: how to send data from UART to SPP?

Postby newsettler_AI » Thu Apr 26, 2018 12:20 pm

chegewara wrote:param is type of union esp_spp_cb_param_t:
https://github.com/espressif/esp-idf/bl ... api.h#L168

For this particular event it will be this structure:
https://github.com/espressif/esp-idf/bl ... #L150-L158


I think this ( my_param.write.handle = ???; // 129 ?) should be somewhere in here:

Code: Select all

    case ESP_SPP_SRV_OPEN_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_SRV_OPEN_EVT"); // client connected
        FlowMeterData.SPP_conn = true;
        <--- HERE
        break;

     case ESP_SPP_DATA_IND_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_DATA_IND_EVT len=%d handle=%d", param->data_ind.len, param->data_ind.handle);
        if (param->data_ind.len < 1023)
        {
 <--- OR HERE
        

Sorry, I updated my previous post to late. :oops:


Here is code:

Code: Select all

//my structure
typedef struct MyData_s
{
    uint8_t  SPP_buffer[BUF_SIZE];
    uint8_t  UART_buffer[BUF_SIZE];
    uint32_t SPP_len;
    uint32_t UART_len;
    uint8_t  SPP_got_packet;
    uint8_t  UART_got_packet;
    bool     SPP_conn; // TRUE: spp connected
}MyData_t;
MyData_t MyData;

// SPP callback
static void esp_spp_cb(esp_spp_cb_event_t event, esp_spp_cb_param_t *param)
{
    ... 
    case ESP_SPP_CLOSE_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_CLOSE_EVT"); // when client disconnects
        MyData.SPP_conn = false;
        break;
        
    case ESP_SPP_SRV_OPEN_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_SRV_OPEN_EVT"); // client connected
        FlowMeterData.SPP_conn = true;
        break;
        
    case ESP_SPP_DATA_IND_EVT:
        ESP_LOGI(SPP_TAG, "ESP_SPP_DATA_IND_EVT len=%d handle=%d", param->data_ind.len, param->data_ind.handle);
        if (param->data_ind.len < 1023)
        {
            // this part tranferring data fom SPP to UART (at this stage only fills the proper buffer, later it will be handled)
            memcpy(MyData.SPP_Buf,param->data_ind.data, (size_t)param->data_ind.len);
            MyData.SPP_len = param->data_ind.len;
            MyData.SPP_got_packet = true;
            
            // And this part works ONLY if I send something via SPP (I need independence sending)
            if(MyData.UART_got_packet == true) 
            {
               esp_spp_write(param->write.handle, MyData.UART_len, MyData.UART_buffer);
               MyData.UART_got_packet = false;
            }
        }
    ...
}

// My function that should write data from UART to SPP outside spp callbacks
void SPP_to_UART_write(esp_spp_cb_param_t param)
{
    esp_spp_write(param.write.handle, MyData.UART_len, MyData.UART_buffer);
}

//Main
void app_main()
{
    ...  
    // maybe like this?
    esp_spp_cb_param_t my_param;
    my_param.write.handle = ???; // 129 ?
    
    SPP_to_UART_write(my_param)
    ...
}

(and at pastebin):
https://pastebin.com/sAhKXtM1


In your solution data from UART will be tranferred only when I'm connecting/disconnecting from smartphone, am I right?

I would like to connect (and stay connected), if something will arrive in esp UART, it should send to phone via SPP. And if I'm sending something from phone, it should transmitting over UART (this part is done!).

Problem is that I cant see UART data in realtime:
"uart_packet_1" arrived
"uart_packet_2" after 1 second
Packet #1 stored in buffer and if there wasnt any incoming SPP events I cant read it.
I will read uart_packet #2 or #3 or whatever later, when I will send something over SPP.
So I want all packet will transfering automatically over SPP.

newsettler_AI
Posts: 121
Joined: Wed Apr 05, 2017 12:49 pm

Re: UART to SPP bridge: how to send data from UART to SPP?

Postby newsettler_AI » Thu Apr 26, 2018 2:11 pm

I have managed this route UART -> SPP! :P

As Markus said, I'm keeping handle for connection and then transferring it to my functions.
And as chegewara noted about unions, I have remake my function for transferring handle, len&buffers (I'm pretty sure there was some mistake).

Thanks you both! :)

Who is online

Users browsing this forum: No registered users and 77 guests