Hi, everyone.
1. The followings are development enviroments :
- Dev. Enviroments : nRFSDK 16, Mesh v4.2, Board PCA10040
- Project Example : nrf5_SDK_for_Mesh_v4.2.0_src\examples\sdk_coexist\ble_app_uart_coexist\pca10040\s132\ses
2. Application Data Flow
- At first, Mobile app send a string data to Mesh-server ---> Client Node gets the data --> PC gets the data
- The PC replys to Client node with 8 bytes by uart communication to respond to the Moibile app.
- I atach the following codes
3. Problems
- It works with button_event_handler for sendind data.
- But NRF_BREAKPOINT_COND occurs when sending a string through the UART Terminal (ex, SerialPort program)
- I tried to figure out what the reason is , I cannot find why.
- Maybe priority issue?
- Anybody help me if you got same troubles and solved.
---- mesh-main.c ----
/* Get public address for accessing server */
static uint32_t assign_server_address(uint16_t new_address)
{
uint32_t status = NRF_SUCCESS;
dsm_handle_t publish_address_handle = DSM_HANDLE_INVALID;
nrf_mesh_address_t publish_address_stored;
uint16_t destination_address = new_address;
__LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "=== assign_server_address ===\n")
__LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "new Address : %x \n", new_address);
__LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "destination Address : %x \n", destination_address);
if (access_model_publish_address_get(m_clients[0].model_handle, &publish_address_handle) != NRF_SUCCESS) {
status = dsm_address_publish_add(destination_address, &publish_address_handle);
__LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "access_model_publish_address_get %d.\n", status)
} else {
__LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "access_model_publish_address_get:SUCCESS\n");
if (dsm_address_get(publish_address_handle, &publish_address_stored) == NRF_SUCCESS)
{
if ((publish_address_stored.type == NRF_MESH_ADDRESS_TYPE_VIRTUAL) ||
(publish_address_stored.type != NRF_MESH_ADDRESS_TYPE_VIRTUAL &&
publish_address_stored.value != destination_address))
{
__LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Destination Address is Different.\n")
__LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "new_addre %x : stored.val %x \n", destination_address, publish_address_stored.value);
/* This should never assert */
NRF_MESH_ASSERT(dsm_address_publish_remove(publish_address_handle) == NRF_SUCCESS);
status = dsm_address_publish_remove(publish_address_handle); // sometimes dead here
status = dsm_address_publish_add(destination_address, &publish_address_handle);
} else {
/* Use the retrieved publish_address_handle */
}
} else {
// get publish_address_handle
__LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "else : dsm_address_publish_add : Success !!!\n");
status = dsm_address_publish_add(destination_address, &publish_address_handle);
}
}
switch (status) {
case NRF_ERROR_NO_MEM:
__LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "NRF_ERROR_NO_MEM\n");
return status;
case NRF_ERROR_NULL:
__LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "Unexpected NULL pointer is given.\n"); // dsm_address_publish_add Fail
case NRF_SUCCESS:
__LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "dsm_address_publish_add is Success.\n"); // dsm_address_publish_add Success
break;
default:
__LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "ACCESS_STATUS_UNSPECIFIED_ERROR\n");
return status;
}
NRF_MESH_ASSERT(access_model_publish_address_set(m_clients[0].model_handle, publish_address_handle) == NRF_SUCCESS);
return status;
}
[main.c]
[uart setting]
APP_UART_FIFO_INIT(&comm_params,
UART_RX_BUF_SIZE,
UART_TX_BUF_SIZE,
uart_event_handle,
APP_IRQ_PRIORITY_LOW,
err_code);
APP_ERROR_CHECK(err_code);
[uart_event_hadler]
void uart_event_handle(app_uart_evt_t * p_event)
{
~~~
case APP_UART_DATA_READY:
~~
else if (STX_FLAG == true && RECEIPT_FLAG == true) // Get a string data from UART terminal (baudrate 57600 or 115200 tests)
{
index++;
if (index == 4 ) {
Msg_Length = calc_datalength(data_array);
}
if (index == Msg_Length) // check Message arrived
{
memcpy(message_array, data_array, Msg_Length); // copy data_array to message_array
MESSAGE_READY_FLAG = true; // make MESSAGE_READY_FLAG to be true
~
break;
}
[main]
int main(void)
{
~
uart_init();
log_init();
~
mesh_main_initialize();
// Start execution.
advertising_start();
mesh_main_start();
for (;;)
{
if(MESSAGE_READY_FLAG == true)
{
MESSAGE_READY_FLAG = false;
_generic_onoff_client_set(message_array); // call mesh-
}
idle_state_handle();
}
[mesh-main.c]
uint32_t _generic_onoff_client_set (uint8_t * message_array)
{
uint32_t status = NRF_SUCCESS;
generic_onoff_set_params_t set_params;
model_transition_t transition_params;
static uint8_t tid = 0;
static uint16_t new_address1;
uint8_t tx_message[8] = {0};
tx_message[0] = message_array[1];
~
tx_message[7] = message_array[12];
set_params.on_off = tx_message;
// 2. set params
set_params.tid = tid++;
transition_params.delay_ms = APP_ONOFF_DELAY_MS;
transition_params.transition_time_ms = APP_ONOFF_TRANSITION_TIME_MS;
// 3.
access_model_reliable_cancel(m_clients[0].model_handle);
// 4. Assign destination address
new_address1 = ((0xffff & message_array[5]) << 8) + message_array[6];
NRF_LOG_INFO(" start new dest_address = %4x \n", new_address1);
status = assign_server_address(new_address1);
switch (status)
{
case NRF_SUCCESS:
~
break;
}
// 5. send message
status = generic_onoff_client_set(&m_clients[0], &set_params, &transition_params);
switch (status)
{
case NRF_SUCCESS:
break;
3. Problems
- I modified the genric_onoff_model for sending a sting.
- It works fine to send a string by using button_event_handler in client node
[mesh_main_button_event_handler]
void mesh_main_button_event_handler(uint32_t button_number)
{
uint8_t tx_message[8] = {0xc7, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36}; //ok
uint16_t uart_length = 8;
/* Increase button number because the buttons on the board is marked with 1 to 4 */
button_number++;
NRF_LOG_INFO("Button %u pressed\n", button_number);
uint32_t status = NRF_SUCCESS;
generic_onoff_set_params_t set_params;
model_transition_t transition_params;
static uint8_t tid = 0;
/* Button 1: On, Button 2: Off, Client[0] --> ODD Group : Board 1
* Button 2: On, Button 4: Off, Client[1] --> EVEN Group : Board 2
*/
switch(button_number)
{
case 1:
case 2:
case 3:
//set_params.on_off = APP_STATE_ON;
set_params.on_off = tx_message; //choi
break;
// case 2:
case 4:
set_params.on_off = APP_STATE_OFF;
break;
}
~~
assign_server_address(new_address); // call for chainging unicast address for publinsing
~~
generic_onoff_client_set(&m_clients[0], &set_params, &transition_params); // send a string message