DA14531 central disconnect issue

Hello Sir, 

I am working with two DA14531 Tiny modules: one acting as a central and the other as a multi-com peripheral. After making changes as per the README file to support connecting to 3 devices, both modules initially connect. However, after 2-4 seconds, the central module automatically disconnects, and I receive the following error in the UART log: user_on_disconnect: reason: 08 (SMP_ERROR_CMD_NOT_SUPPORTED).

  • Hi Amar,

    Thank you for posting your questions online.

    I will check this and back to you as soon as possible.

    BR,

    JH_Renesas

  • Hi Amar,

    The error you are facing is related to the Security configurations.
    My guess would be that you have enabled Security on the Peripheral side and that Central cannot access the Services without having a secure connection.
    Please check the Security configurations in order to make sure that both devices have either enabled or disabled security at the same time.
    Please refer here: DA1453x Tutorial BLE Security — DA1453x&DA1458x Tutorial BLE security (renesas.com)

    Best Regards,
    OV_Renesas

  • Hello Sir,

    I am trying to send some data to a connected peripheral device through UART. I have reviewed the UART functionality in the peripheral example, but I am unsure of how to send data in the central code. Could you please guide me on how to implement the data transmission in the central device code?

  • Hi Amar,

    Thank you for the reply.
    Please refer on the following:
    (1) DA14531mod central request data - Bluetooth Low Energy - Wireless Connectivity - Renesas Engineering Community
    On this thread I had explained the Central related APis on how to Read/Write on the Peripheral characteristics.
    (1) DA14531 Central With Security Read Characteristic - Bluetooth Low Energy - Wireless Connectivity - Renesas Engineering Community

    Please share more information regarding the Application Scenario and what is the expected the behavior of your application so we can actually guide you.

    Best Regards,
    OV_Renesas

  • Hello sir,

       I hope you're doing well. I am currently working on storing data in a variable through UART communication on the central device (DA14531). However, I'm encountering an issue where I am unable to store the data correctly.

  • HI Amar,

    Thank you for the reply.
    I hope you are doing well too.
    Could you please share more information? A high level description of your application scenario and the code snippets of what you are trying to achieve?

    Best Regards,
    OV_Renesas

  • Hello sir,

       I hope you're doing well.  am working with two DA14531 Bluetooth modules (Central and Multi-Com Peripheral) to send data via the GATT write function using UART. The communication works fine when the Mobile Bluetooth LightBlue app is used as the central device, but when using the DA14531 as the central device, the write operation fails after approximately 40-50 seconds, returning error code 0045, indicating a failure in the GATTC_WRITE process.     

    the central device output on COM

    Completion Event: GATTC_DISC_ALL_SVC: status: 0000
    1235
    Received data: 0x31 0x32 0x33 0x35
    check string to integer convert is =1235
    GATTC_WRITE: status: 0000
    Write successful!


    1543
    Received data: 0x31 0x35 0x34 0x33
    check string to integer convert is =1543
    GATTC_WRITE: status: 0045
    Write failed, status: 0045


    1000
    Received data: 0x31 0x30 0x30 0x30
    check string to integer convert is =1000
    GATTC_WRITE: status: 0043
    Write failed, status: 0043

  • Hi Amar,

    Thank you for the reply.
    The errors you are facing are:

        ///Request not allowed in current state.
        GAP_ERR_COMMAND_DISALLOWED = 0x43,
    
        ///Requested operation timeout.
        GAP_ERR_TIMEOUT            = 0x45,

    Could you please share the Full Service Discovery information? What is the Characteristics Attribute permissions?
    Do you have Security implemented?
    Could you please share the API you used to perform the GATTC_WRITE?

    Best Regards,
    OV_Renesas

  • Hello sir, 

    Do you have Security implemented?

    I have disable sleep mod function 

    static const sleep_state_t app_default_sleep_mode = ARCH_SLEEP_OFF;

    Could you please share the Full Service Discovery information?

    static void handle_svc_ind(uint8_t con_idx, struct gattc_sdp_svc_ind const *disc_svc)
    {
    	service_info_t *svc = ke_malloc(user_ble_get_svc_size(disc_svc), KE_MEM_NON_RETENTION);
    	
    	 if (svc == NULL) {
            dbg_block_printf("Error: Service allocation failed\r\n",NULL);
            return;
        }
    	dbg_block_printf("%s: conn_idx=%04x start_h=%04x end_h=%04x\r\n", __func__, con_idx,
                                                                            disc_svc->start_hdl, disc_svc->end_hdl);
    	user_gatt_parse_service(disc_svc, svc, con_idx);
    	
     uint16_t i;
        	
    	dbg_block_printf("%s: check gatt_char_handle =%04x\r\n",gatt_char_handle);		
    		
    #ifdef ENABLE_IAS
    	bool ias_uuid_match;
    	uint16_t ias_uuid = ATT_SVC_IMMEDIATE_ALERT;
    	uint16_t ias_alert_uuid = ATT_CHAR_ALERT_LEVEL;
    	if(svc->svc_uuid.type == ATT_UUID_16){
    		ias_uuid_match = match_uuid((uint8_t *)&ias_uuid, (uint8_t *)&svc->svc_uuid.uuid.uuid16, sizeof(uint16_t));
    	}
    	
    	if(ias_uuid_match){
    		dbg_block_printf("Immediate Alert Service: ", NULL);
    	}
    #endif 
    	
    #ifdef ENABLE_BAS
    	bool bas_uuid_match;
    	uint16_t bas_uuid = ATT_SVC_BATTERY_SERVICE;
    	uint16_t bas_level_uuid= ATT_CHAR_BATTERY_LEVEL;
    	
    	if(svc->svc_uuid.type == ATT_UUID_16){
    		bas_uuid_match = match_uuid((uint8_t *)&bas_uuid, (uint8_t *)&svc->svc_uuid.uuid.uuid16, sizeof(uint16_t));
    	}
    	if(bas_uuid_match){
    		dbg_block_printf("Battery Service: ", NULL);
    	}
    #endif
    	dbg_block_printf("%s: \r\n", format_uuid(&svc->svc_uuid) );
    	for(i = 0 ; i<svc->num_chars; i++)
    	{
    		gattc_chars_t *gatt_char = &svc->items[i];
    #ifdef ENABLE_IAS
    		if(ias_uuid_match)
    		{
    			if( match_uuid( (uint8_t *)&ias_alert_uuid , (uint8_t *)&gatt_char->uuid.uuid, 2) )
    			{
    				memcpy(&central_app_env.periph_devices[con_idx].serv_disc.ias_char, 
    																									gatt_char, sizeof(gattc_chars_t) );
    				
    				central_app_env.periph_devices[con_idx].serv_disc.ias_handle_valid = true;
    				dbg_block_printf("\tAlert Level Char\r\n", NULL);
    				
    				if(gatt_char->c.properties & GATT_PROP_WRITE)
    				{
    					central_app_env.periph_devices[con_idx].serv_disc.ias_write_op = GATTC_WRITE;
    				}
    				else if(gatt_char->c.properties & GATT_PROP_WRITE_NO_RESP)
    				{
    					central_app_env.periph_devices[con_idx].serv_disc.ias_write_op = GATTC_WRITE_NO_RESPONSE;	
    				}
    				else if(gatt_char->c.properties & GATT_PROP_WRITE_SIGNED)
    				{
    					central_app_env.periph_devices[con_idx].serv_disc.ias_write_op = GATTC_WRITE_SIGNED;	
    				}else
    				{		
    					central_app_env.periph_devices[con_idx].serv_disc.ias_handle_valid = false;
    				}
    			}
    		}
    #endif 
    #ifdef ENABLE_BAS
    		if(bas_uuid_match)
    		{
    			if( match_uuid( (uint8_t *)&bas_level_uuid , (uint8_t *)&gatt_char->uuid.uuid, 2) )
    			{
    				memcpy(&central_app_env.periph_devices[con_idx].serv_disc.bas_char, 
    																										gatt_char, sizeof(gattc_chars_t));
    				
    				central_app_env.periph_devices[con_idx].serv_disc.bas_handle_valid = true;
    				dbg_block_printf("\tBattery Level Char\r\n", NULL);
    			}
    		}
    #endif 
    		dbg_block_printf("\t%04x char %s prop=%02x (%s)\r\n", gatt_char->handle,
                                                    format_uuid(&gatt_char->uuid), gatt_char->c.properties,
                                                    format_properties(gatt_char->c.properties));	
    	}
    	
    	ke_free(svc);
    	
    	central_app_env.periph_devices[con_idx].serv_disc.last_handle = disc_svc->end_hdl;
    	
    	
    }

    "I have made some changes in the user_central_app_c file. I have taken input data from the user through UART and sent the data to the peripheral device."

    #define SCAN_INTVL_MS		(50)
    #define SCAN_WINDOW_MS	(50)
    #define HANDLE        0x0025
     
     
    timer_hnd uart_receive_timer_used								__SECTION_ZERO("retention_mem_area0");
    
     
    static void uart_receive_cb(uint16_t length);
    void continuous_uart_send_callback();
    void send_data_to_peripheral();
     
    typedef struct
    {
    struct bd_addr addr;
    }connecting_device_t;
    
    typedef struct
    {
    	periph_device_t 	periph_devices[CFG_MAX_CONNECTIONS];
    	
    	bool 							connect_to_periph;
    	struct bd_addr 		connect_to_addr;
    	uint8_t 					connect_to_addr_type;
    	uint8_t						num_connections;
    	timer_hnd					connection_timer;
    	
    }central_app_env_t;
    
    central_app_env_t central_app_env;
    
     /*
     * FUNCTION DEFINITIONS
     ****************************************************************************************
    */
    
    #define UART_RECEIVE_BUFFER_SIZE 4
    uint8_t uart_receive_buffer[UART_RECEIVE_BUFFER_SIZE];
    
    volatile bool uart_receive_finished = false;
    volatile uint16_t data_received_cnt = 0;
    
    //Data sent via UART will be stored here
     uint8_t received_data[UART_RECEIVE_BUFFER_SIZE] = {0}; 
    
    void uart_receive_interrupt_example(uart_t* uart)
    {
        uart_receive_finished = false;
        data_received_cnt = 0;
        uart_register_rx_cb(uart, uart_receive_cb);
    
        uart_receive(uart, uart_receive_buffer, UART_RECEIVE_BUFFER_SIZE, UART_OP_INTR); 	
    	uart_receive_timer_used = app_easy_timer(300, continuous_uart_send_callback);
    }
    
     uint8_t con_idx = 0;
     uint16_t  gatt_char_handle = 0x002c ;          
     
    
    static void uart_receive_cb(uint16_t length){
        
    	  uart_receive_finished = true;
        data_received_cnt = length;
       
    	 //Copy uart_receive_buffer data to received_data    
    	 
    	 memcpy(&received_data,uart_receive_buffer , sizeof(uart_receive_buffer));
    	
    	 uart_receive_timer_used = app_easy_timer(300, continuous_uart_send_callback);
    	 
    	    // Null-terminate the string if it's textual
    	  received_data[length] = 0;
    
        // Debug the received data
        dbg_block_printf("Received data: ",NULL);
        for (int i = 0; i < data_received_cnt; i++) {
            dbg_block_printf("0x%02X ", received_data[i]);
        }
        dbg_block_printf("\r\n",NULL);
    
        wdg_resume();
        
        // Re-enable the Extended Sleep Mode
      //  arch_set_extended_sleep(false);
        
    
        // Re-enable the app_easy_timer
        if (uart_receive_timer_used != EASY_TIMER_INVALID_TIMER) {
            uart_receive_timer_used = EASY_TIMER_INVALID_TIMER;
        }
    		    // Handle the received data by sending it to the connected GATT characteristic
          send_data_to_peripheral();
    }
      void send_data_to_peripheral() {
    	//	 arch_set_extended_sleep(true);
        uint8_t con_idx = 0;  // Connection index
      //uint8_t gatt_char_handle = 0x002c; 
    	//	uint8_t gatt_char_handle = 0x0027;  // Handle for the characteristic
            uint16_t num = 0; 
             for(int i=0;i<sizeof(received_data);i++){
             if(received_data[i]>='0' && received_data[i]<='9'){
            num = num*10+(received_data[i]-'0');		
            }	
             else {
              break;		
        	}
        }	
      	dbg_block_printf("check string to integer convert is =%d\r\n",num);
    	  dbg_block_printf(" Checking code with sleep mode function.... \r\n",NULL);
    	arch_asm_delay_us(5);
    	user_ble_gatt_write(GATTC_WRITE, con_idx, gatt_char_handle, &num, sizeof(num));
    	arch_asm_delay_us(5);	
    			
    }
    	void continuous_uart_send_callback(){
    
    	//	 arch_disable_sleep();
    	  uart_receive_interrupt_example(UART2); // Start UART reception   
    }

    Could you please share the API you used to perform the GATTC_WRITE?

    "I have to perform the GATT_Write function after user_gatt_discover_all_services in the user_on_connection function."

    void user_on_connection(uint8_t connection_idx, struct gapc_connection_req_ind const *param)
    {
    	
    		if(central_app_env.connection_timer != EASY_TIMER_INVALID_TIMER){
    			app_easy_timer_cancel(central_app_env.connection_timer);
    			central_app_env.connection_timer = EASY_TIMER_INVALID_TIMER;
    		}
    	
        default_app_on_connection(connection_idx, param);
    		dbg_printf("%s\r\n", __func__);
    		
    		central_app_env.periph_devices[connection_idx].addr = param->peer_addr;
    		central_app_env.periph_devices[connection_idx].con_idx = connection_idx;
    		central_app_env.periph_devices[connection_idx].con_valid = true;
    		central_app_env.num_connections++;
    	
    
        
    		dbg_block_printf("Communicate with peripheral..... \r\n", NULL);
    		dbg_printf("Connected to device with address: %02X:%02X:%02X:%02X:%02X:%02X\r\n",
        param->peer_addr.addr[5], param->peer_addr.addr[4], param->peer_addr.addr[3], 
        param->peer_addr.addr[2], param->peer_addr.addr[1], param->peer_addr.addr[0]);
      
    		
    		if(central_app_env.num_connections < CFG_MAX_CONNECTIONS)
    		{
    			ble_scan_for_devices();
    			 
    		}
    		
    
    #ifdef ENABLE_IAS		
    		central_app_env.periph_devices[connection_idx].serv_disc.ias_handle_valid = false;
    #endif
    #ifdef ENABLE_BAS
    		central_app_env.periph_devices[connection_idx].serv_disc.bas_handle_valid = false;
    #endif
    		
    		user_gatt_discover_all_services(connection_idx, 1);
    		
    	 uart_receive_timer_used = app_easy_timer(300, continuous_uart_send_callback);	
    
    }