This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Problems with UART receiving from MCU

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

Parents Reply Children
No Data
Related