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

f_write/f_close cause BLE disconnect

Hardware: nrf52832

SDK: 16.0.0 with FreeRtos, 

Softdevice: S132 7.0

I set configMAX_PRIORITIES to 5 and modified nrf_sdh_freertos_init to set BLE task priority to 4.

My sd card maintain task priority is set to 2.

For BLE NUS service:

#define MIN_CONN_INTERVAL MSEC_TO_UNITS(20, UNIT_1_25_MS) /**< Minimum acceptable connection interval (20 ms), Connection interval uses 1.25 ms units. */
#define MAX_CONN_INTERVAL MSEC_TO_UNITS(75, UNIT_1_25_MS) /**< Maximum acceptable connection interval (75 ms), Connection interval uses 1.25 ms units. */
#define SLAVE_LATENCY 0 /**< Slave latency. */
#define CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS) /**< Connection supervisory time-out (4 seconds). */

The NUS service and SD card function works fine when test them separately. But if Operate SD card during NUS connection, I got disconnect with reason:0x8

I have tried to enlarge INTERVAL to 120ms/175ms, also tried to change SLAVE_LATENCY to 4. Problem still exist.

I searched internet and NRF Dev Zone, found some similar question, but none of them can resolve my problem. So I have to raise a new question here. 

 

  • I tried f_opendir / f_readdir() will also cause ble disconnect. 

  • More information: I tried lower down SD card SPI interface speed (from 4M to 250K), problem is still there

  • Attached SD operation source code below: (This function is called from a task with priority 2.)

    static int cmd_get_record_num(unsigned char *buf, int len)
    {
        u8 rsp[32];
        s16 imu_file_num;
        s16 env_file_num;
        u32 total_space;
        u32 free_space;
        int rv;
        DIR dir;
        FILINFO fno;
    
        if(scb.disk_state)
        {
            return RV_CMD_PUB_ERR;
        }
    
        rsp[0] = CMD_GET_RECORD_NUM;
        rsp[1] = 'V';
    
        imu_file_num = 0;
        env_file_num = 0;
    
        rv = f_opendir(&dir,"/");
        if(rv)
        {
            NRF_LOG_INFO("root dir open fail");
            return RV_CMD_PUB_ERR;
        }
        
        do
        {
            rv = f_readdir(&dir, &fno);
            if (rv != FR_OK)
            {
                NRF_LOG_INFO("root read failed.");
                return RV_CMD_PUB_ERR;
            }
    
            if (fno.fname[0])
            {
                if (fno.fattrib & AM_DIR)
                {
                    NRF_LOG_INFO("skip dir:%s",(uint32_t)fno.fname);
                    NRF_LOG_FLUSH();
                }
                else
                {
                    int dot_pos = 0;
                    while(fno.fname[dot_pos] != '.')
                    {
                        dot_pos++;
                    }
                    
                    if(memcmp(fno.fname+dot_pos+1,"DAT",3) == 0)
                    {
                        if(fno.fname[0] == 'M')
                        {
                            imu_file_num++;
                        }
                        else if(fno.fname[0] == 'E')
                        {
                            env_file_num++;
                        }
                        else
                        {
                            NRF_LOG_INFO("skip dat file:%s",(uint32_t)fno.fname);                        
                            NRF_LOG_FLUSH();
                        }
                    }
                    else
                    {
                        NRF_LOG_INFO("skip file:%s",(uint32_t)fno.fname);                    
                        NRF_LOG_FLUSH();
                    }
                }
            }
        }
        while (fno.fname[0]);
    
        f_closedir(&dir);
    
        uint32_encode(imu_file_num, rsp+2);
        uint32_encode(env_file_num, rsp+4);
    
        const nrf_block_dev_geometry_t *p_dev_geom = m_block_dev_sdc.block_dev.p_ops->geometry(&m_block_dev_sdc.block_dev);
        total_space = p_dev_geom->blk_count/2048;
        uint32_encode(total_space, rsp+6);
    
        free_space = scb.fs.free_clst * scb.fs.csize / 2048;
        uint32_encode(free_space, rsp+10);
    
        ble_nus_long_send(rsp, 14 );
    
        NRF_LOG_INFO("list total=%d, free=%d, i_n=%d,e_n=%d",
            total_space,
            free_space,
            imu_file_num,
            env_file_num
            );
    
    
        return RV_CMD_ACKED;
    }
    

  • Attached log:

    0> <info> app: Connected  <---------------BLE connected
    0> <info> app: Data len is set to 0xF4(244)
    0> <info> app: Data len is set to 0xF4(244)
    0> <info> app: nus long send: 244x0+3. cost tick=0
    0> <info> app: skip dir:SYSTEM~1
    0> <info> app: skip dir:D1
    0> <info> app: skip dir:D2
    0> <info> app: nus long send: 244x0+14. cost tick=0
    0> <info> app: list total=14804, free=14753, i_n=7,e_n=0   
    0> <info> app: Fast advertising. <----------------------------------------BLE disconnected
    0> <info> app: Disconnected for reason:8  <-------------------------- reason:0x8
    0> <info> app: Connected
    0> <info> app: Data len is set to 0xF4(244)
    0> <info> app: Data len is set to 0xF4(244)
    0> <info> app: nus long send: 244x0+3. cost tick=0

  • Hi

    You should not edit the SoftDevice's priority levels at all, as that might cause trouble for your application. If the SD card operations are able to interrupt the BLE activities that might cause trouble when the radio is active. You can see the interrupt priority levels documentation here for some more details on the matter.

    Your disconnect reason (0x8 BLE_HCI_CONNECTION_TIMEOUT)  points to that the other device has stopped responding, and I'm guessing this is because the SD card operations are allowed to interrupt the radio. What devices are you testing this on?

    Best regards,

    Simon

Related