Hi,
I'm using S110 on PCA10028, I have problems with byte receiving on UART and can't make it work.
I can easily send and receive data over terminal using UART. I can also receive and send data over BT to mobile device correctly.
Bytes come in packets(meaning we have a distinction which is 1st byte and that 1st byte tells us how long the entire packet will be). On uart receive I must get bytes and distinct that 1st byte, collect all others and send that packet. My code for that looks like this:
void uart_event_handle(app_uart_evt_t * p_event)
{
uint32_t err_code;
uint8_t byte;
switch (p_event->evt_type)
{
case APP_UART_DATA_READY:
err_code = app_uart_get(&byte);
APP_ERROR_CHECK(err_code);
if (byte & 0x80)
{
expected_uart_length = byte - 0x8D;
ble_data_buffer[0] = byte;
rx_byte_index = 1;
nrf_gpio_pin_clear(LED_2);
}
else
{
ble_data_buffer[rx_byte_index] = byte;
rx_byte_index++;
if (rx_byte_index == (expected_uart_length + 1))
{
nrf_gpio_pin_set(LED_2);
/*data_buffer_t data_buffer;
data_buffer_init(&data_buffer, ble_data_buffer, rx_byte_index);
data_array_add(&m_data_array, &data_buffer);*/
}
}
break;
case APP_UART_COMMUNICATION_ERROR:
APP_ERROR_HANDLER(p_event->data.error_communication);
break;
case APP_UART_FIFO_ERROR:
APP_ERROR_HANDLER(p_event->data.error_code);
break;
default:
break;
}
}
And it works, as much as I can see when stopped, bytes are received correctly from UART, but I can't send them over BT. When I try to enable:
data_buffer_t data_buffer;
data_buffer_init(&data_buffer, ble_data_buffer, rx_byte_index);
data_array_add(&m_data_array, &data_buffer);
...code begins to break. Also, if I try to send data here, it also breaks/restarts. Why? Does it have to much to do in this handle?
Since calling of sd_ble_gatts_hvx here introduced app crashing(restarting) I've added the 3 lines above and created a simple data buffer fifo:
typedef struct
{
uint8_t buffer[BUFFER_SIZE];
uint16_t size;
} data_buffer_t;
typedef struct
{
data_buffer_t* array[128];
volatile uint32_t in_pos;
volatile uint32_t out_pos;
} data_array_t;
void data_array_init(data_array_t* p_data_array)
{
p_data_array->in_pos = 0;
p_data_array->out_pos = 0;
}
void data_buffer_init(data_buffer_t* p_data_buffer, uint8_t* buffer, uint16_t size)
{
memset(p_data_buffer->buffer, 0, BUFFER_SIZE);
memcpy(p_data_buffer->buffer, buffer, size);
p_data_buffer->size = size;
}
void data_array_add(data_array_t* p_data_array, data_buffer_t* p_data_buffer)
{
p_data_array->array[p_data_array->in_pos] = p_data_buffer;
p_data_array->in_pos++;
}
data_buffer_t* data_array_get_next(data_array_t* p_data_array)
{
if (p_data_array->in_pos == p_data_array->out_pos)
{
return NULL;
}
data_buffer_t* p_data_buffer = p_data_array->array[p_data_array->out_pos];
p_data_array->out_pos++;
if (p_data_array->in_pos == p_data_array->out_pos)
{
p_data_array->in_pos = 0;
p_data_array->out_pos = 0;
}
return p_data_buffer;
}
And then I call sd_ble_gatts_hvx in main loop like this:
// Start execution
timers_start();
err_code = ble_advertising_start(BLE_ADV_MODE_FAST);
APP_ERROR_CHECK(err_code);
// Enter main loop
for (;;)
{
app_sched_execute();
power_manage();
while (is_connected)
{
data_buffer_t* data_buffer = data_array_get_next(&m_data_array);
if (data_buffer)
{
err_code = ble_alps_data_send(&m_alps, data_buffer->buffer, data_buffer->size);
APP_ERROR_CHECK(err_code);
}
else
{
break;
}
}
}
But it still crashes the app. :/
Is there any efficient way of doing this? I'm using uart fifo.
Basically I need:
- get 1st byte, calculate size
- get all other bytes
- store them somewhere so I can send it
- send them over BT to mobile device (when, how?)
I've tried different approaches but when I put more code to uart_event_handle things begin to go haywire. Any other way to collect data from uart?
Thank you!
Br, Mladen