FAT FS USB MSC not opening file after enabling timers.

Hi, 

 I am using USB MSC code from sdk examples with QSPI module on development kit. I am using sdk 17.1.0. My project includes capturing some pulses on a GPIO and then saving the data inside the file of flash chip. I am able to mount the file system as well as write some data inside it. After this I enable the timers and ppi configuration. Now when I try to write some data from the timer1 handler, I am no longer able to open the created file and append data into it. It gives me an error of "FR_NOT_READY". Can anyone please help me with this? 

After test_init() function is called the timers and ppi start and I am no longer able to open the file and write into it from the timer1 event handler. What could be causing this?

Please check the attached project. It is the same as USB MSC code from SDK example. Only added ppi and timers. This project can be ran on NRF52840 development kit.

Thanks & Regards,

Snehal 

  • Thanks for your help. One question I wanted to ask. When the USB is connected the device is not able to save data inside the flash. If I remove USB from laptop only then device can save data inside the file. Can we save data inside the file even when USB is connected?

    Regards,
    Snehal

  • Hi Snehal

    The USB MSC class does not permit sharing of the storage medium between multiple users. It assumes and requires exclusive access to the underlying flash hardware. 

    You can disable the USB stack completely in the code in order to be able to access the flash, but this will probably not provide for a very good user experience since it will make it look like the USB device is disconnected on the host (PC) side as well. 

    Best regards
    Torbjørn

  • Hi Torbjørn,

             Thank you so much for your reply. Now that this file is created and stored inside the flash chip. Is there any way the nrf52840 can send this file via ble to the mobile APP. Is it even possible?

    Thanks & Regards,

    Snehal

  • Hi Torbjorn,

                       I was successfully able to create a drive and file inside the flash chip. Now I want to enable BLE as well. I have added the ble functions but I am not able to connect to the device. I am getting error of "GATT CONN LMP TIMEOUT" in the nrf connect app. Also when I check the code, the code goes inside some dummy handler in the startup file and it seems to get stuck over there. Can you please help?? I have inserted my main.c code here.

    #include <stdint.h>
    #include <string.h>
    #include <stdbool.h>
    #include <stdio.h>
    
    #include <stddef.h>
    #include <inttypes.h>
    #include <stdlib.h>
    #include "nordic_common.h"
    #include "nrf.h"
    #include "app_error.h"
    #include "ble.h"
    #include "ble_hci.h"
    #include "ble_srv_common.h"
    #include "ble_advdata.h"
    #include "ble_advertising.h"
    #include "ble_bas.h"
    #include "ble_dis.h"
    #include "ble_conn_params.h"
    #include "sensorsim.h"
    #include "nrf_sdh.h"
    #include "nrf_sdh_soc.h"
    #include "nrf_sdh_ble.h"
    #include "app_timer.h"
    #include "peer_manager.h"
    #include "peer_manager_handler.h"
    #include "bsp_btn_ble.h"
    
    #include "fds.h"
    #include "ble_conn_state.h"
    #include "ble_dfu.h"
    #include "nrf_pwr_mgmt.h"
    #include "nrf_drv_wdt.h"
    #include "nrf_drv_clock.h"
    #include "nrf_ble_gatt.h"
    #include "nrf_ble_qwr.h"
    #include "nrf_power.h"
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    #include "product_config.h"
    #include "ble_clinitraq.h"
    #include "task_led_button.h"
    #include "task_clinitraq_ble.h"
    #include "task_id_accessory.h"
    #include "task_psf_comm.h"
    #include "device_storage.h"
    #include "nrf_drv_gpiote.h"
    #include "version.h"
    #include "nrf_drv_twi.h"
    #include "app_button.h"
    #include "nrf_dfu_ble_svci_bond_sharing.h"
    #include "nrf_svci_async_function.h"
    #include "nrf_svci_async_handler.h"
    #include "nrf_bootloader_info.h"
    #include "app_usbd.h"
    #include "nrf_delay.h"
    #include "usb_msc.h"
    #include "spi.h"
    
    
    
    #define MAIN_DEVICE_NAME                         LE_DEVICE_NAME                            /**< Name of device. Will be included in the advertising data. */
    #define MANUFACTURER_NAME                   "Nordic"                   /**< Manufacturer. Will be passed to Device Information Service. */
    
    #define APP_BLE_OBSERVER_PRIO               3                                       /**< Application's BLE observer priority. You shouldn't need to modify this value. */
    #define APP_BLE_CONN_CFG_TAG                1                                       /**< A tag identifying the SoftDevice BLE configuration. */
    
    #define APP_ADV_INTERVAL                    64 //kkk 300 //300                                     /**< The advertising interval (in units of 0.625 ms. This value corresponds to 187.5 ms). */
    #define APP_ADV_DURATION                    18000 //0                                       /**< The advertising duration (180 seconds) in units of 10 milliseconds. */
                                       /**< Maximum simulated battery level. */
    
    #define MIN_CONN_INTERVAL                   MSEC_TO_UNITS(20, UNIT_1_25_MS)        /**< Minimum acceptable connection interval (0.4 seconds). */
    #define MAX_CONN_INTERVAL                   MSEC_TO_UNITS(75, UNIT_1_25_MS)        /**< Maximum acceptable connection interval (0.65 second). */
    #define SLAVE_LATENCY                       0                                       /**< Slave latency. */
    #define CONN_SUP_TIMEOUT                    MSEC_TO_UNITS(4000, UNIT_10_MS)         /**< Connection supervisory time-out (4 seconds). */
    
    #define FIRST_CONN_PARAMS_UPDATE_DELAY      APP_TIMER_TICKS(5000)                                    /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (5 seconds). */
    #define NEXT_CONN_PARAMS_UPDATE_DELAY       APP_TIMER_TICKS(30000)                                   /**< Time between each call to sd_ble_gap_conn_param_update after the first call (30 seconds). */
    #define MAX_CONN_PARAMS_UPDATE_COUNT        3                                       /**< Number of attempts before giving up the connection parameter negotiation. */
    
    //#define SEC_PARAM_BOND                      0                                       /**< Perform bonding. */
    //#define SEC_PARAM_MITM                      0                                       /**< Man In The Middle protection not required. */
    //#define SEC_PARAM_LESC                      0                                       /**< LE Secure Connections not enabled. */
    //#define SEC_PARAM_KEYPRESS                  0                                       /**< Keypress notifications not enabled. */
    //#define SEC_PARAM_IO_CAPABILITIES           BLE_GAP_IO_CAPS_NONE                    /**< No I/O capabilities. */
    //#define SEC_PARAM_OOB                       0                                       /**< Out Of Band data not available. */
    //#define SEC_PARAM_MIN_KEY_SIZE              16                                      /**< Minimum encryption key size. */
    //#define SEC_PARAM_MAX_KEY_SIZE              16                                      /**< Maximum encryption key size. */
    
    #define DEAD_BEEF                           0xDEADBEEF                              /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */
    
    #define OSTIMER_WAIT_FOR_QUEUE              2                                       /**< Number of ticks to wait for the timer queue to be ready */
    
    #define DEVICEID_SIZE           16
    uint8_t device_id[DEVICEID_SIZE+1] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    
    extern uint8_t adv_led_button;
    extern uint8_t led_on_duration;
    extern uint8_t led_grn_pwr_active;
    extern uint8_t led_grn_pwr_state;
    extern uint8_t led_blue_pwr_active ;
    extern uint8_t led_blue_pwr_state ;
    int8_t rssi;
    extern int wireless_charging_on;
    extern bool m_usb_connected;
    
    static char app_fw_version[32];
    static char pulsecount[20];
    //uint8_t rclr_data_buf[256] = {0};
    uint8_t rcbr_data_buf[256] = {0};
    //uint16_t rclr_data_cnt = 0;
    uint16_t rcbr_data_cnt = 0;
    
    extern bq24292i_charge_state_t charge_state;
    
    
    
    BLE_RCBR_DEF(m_rcbr, NRF_SDH_BLE_TOTAL_LINK_COUNT);                  /**< BLE R3charge borrower service instance. */
    
    BLE_BAS_DEF(m_bas);                                                 /**< Battery service instance. */
    NRF_BLE_GATT_DEF(m_gatt);                                           /**< GATT module instance. */
    NRF_BLE_QWR_DEF(m_qwr);                                             /**< Context for the Queued Write module.*/
    BLE_ADVERTISING_DEF(m_advertising);                                 /**< Advertising module instance. */
    
    nrfx_wdt_channel_id m_channel_id;
    
    ////////////Added for bonding///////////
    // Static passkey
    #define STATIC_PASSKEY    "123456" 
    static ble_opt_t    m_static_pin_option;
    uint8_t passkey[] = STATIC_PASSKEY; 
    ////////////Added for bonding///////////
    static uint16_t m_conn_handle         = BLE_CONN_HANDLE_INVALID;    /**< Handle of the current connection. */
    static uint16_t   m_ble_nus_max_data_len = BLE_GATT_ATT_MTU_DEFAULT - 3;            /**< Maximum length of data (in bytes) that can be transmitted to the peer by the Nordic UART service module. */
    
    int adv_success = 0;
    
    static ble_uuid_t m_adv_uuids[] =                                   /**< Universally unique service identifiers. */
    {
        {BLE_UUID_RCBR_SERVICE, BLE_UUID_TYPE_VENDOR_BEGIN}
    };
    
    void advertising_start1(void);
    
    
    void advertising_start1(void)
    {
        uint32_t err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
        APP_ERROR_CHECK(err_code);
    }
    
    
    
    /**@brief Handler for shutdown preparation.
     *
     * @details During shutdown procedures, this function will be called at a 1 second interval
     *          untill the function returns true. When the function returns true, it means that the
     *          app is ready to reset to DFU mode.
     *
     * @param[in]   event   Power manager event.
     *
     * @retval  True if shutdown is allowed by this power manager handler, otherwise false.
     */
    static bool app_shutdown_handler(nrf_pwr_mgmt_evt_t event)
    {
        switch (event)
        {
            case NRF_PWR_MGMT_EVT_PREPARE_DFU:
                NRF_LOG_INFO("Power management wants to reset to DFU mode.");
                // YOUR_JOB: Get ready to reset into DFU mode
                //
                // If you aren't finished with any ongoing tasks, return "false" to
                // signal to the system that reset is impossible at this stage.
                //
                // Here is an example using a variable to delay resetting the device.
                //
                // if (!m_ready_for_reset)
                // {
                //      return false;
                // }
                // else
                //{
                //
                //    // Device ready to enter
                //    uint32_t err_code;
                //    err_code = sd_softdevice_disable();
                //    APP_ERROR_CHECK(err_code);
                //    err_code = app_timer_stop_all();
                //    APP_ERROR_CHECK(err_code);
                //}
                break;
    
            default:
                // YOUR_JOB: Implement any of the other events available from the power management module:
                //      -NRF_PWR_MGMT_EVT_PREPARE_SYSOFF
                //      -NRF_PWR_MGMT_EVT_PREPARE_WAKEUP
                //      -NRF_PWR_MGMT_EVT_PREPARE_RESET
                return true;
        }
    
        NRF_LOG_INFO("Power management allowed to reset to DFU mode.");
        return true;
    }
    
    //lint -esym(528, m_app_shutdown_handler)
    /**@brief Register application shutdown handler with priority 0.
     */
    NRF_PWR_MGMT_HANDLER_REGISTER(app_shutdown_handler, 0);
    
    
    static void buttonless_dfu_sdh_state_observer(nrf_sdh_state_evt_t state, void * p_context)
    {
        if (state == NRF_SDH_EVT_STATE_DISABLED)
        {
            // Softdevice was disabled before going into reset. Inform bootloader to skip CRC on next boot.
            nrf_power_gpregret2_set(BOOTLOADER_DFU_SKIP_CRC);
    
            //Go to system off.
            nrf_pwr_mgmt_shutdown(NRF_PWR_MGMT_SHUTDOWN_GOTO_SYSOFF);
        }
    }
    
    /* nrf_sdh state observer. */
    NRF_SDH_STATE_OBSERVER(m_buttonless_dfu_state_obs, 0) =
    {
        .handler = buttonless_dfu_sdh_state_observer,
    };
    
    
    static void advertising_config_get(ble_adv_modes_config_t * p_config)
    {
        memset(p_config, 0, sizeof(ble_adv_modes_config_t));
    
        p_config->ble_adv_fast_enabled  = true;
        p_config->ble_adv_fast_interval = APP_ADV_INTERVAL;
        p_config->ble_adv_fast_timeout  = APP_ADV_DURATION;
    }
    
    
    static void disconnect(uint16_t conn_handle, void * p_context)
    {
        UNUSED_PARAMETER(p_context);
    
        ret_code_t err_code = sd_ble_gap_disconnect(conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
        if (err_code != NRF_SUCCESS)
        {
            NRF_LOG_WARNING("Failed to disconnect connection. Connection handle: %d Error: %d", conn_handle, err_code);
        }
        else
        {
            NRF_LOG_DEBUG("Disconnected connection handle %d", conn_handle);
        }
    }
    
    static TimerHandle_t m_rtc_timer;                               /**< Definition of battery timer. */
    
    #if NRF_LOG_ENABLED
    static TaskHandle_t m_logger_thread;                                /**< Definition of Logger thread. */
    #endif
    
    
    static void nrf_nvmc_write_word(uint32_t address, uint32_t value);
    
    //ble_rclr_t * get_rclr_service(void)
    //{
    //    return &m_rclr;
    //}
    
    ble_rcbr_t * get_rcbr_service(void)
    {
        return &m_rcbr;
    }
    
    
    uint16_t get_conn_handle(void)
    {
        return m_conn_handle;
    }
    
    
    //uint8_t * get_rclr_rcv_buffer(void)
    //{
    //    return rclr_data_buf;
    //}
    
    //uint16_t get_rclr_rcv_cnt(void)
    //{
    //    return rclr_data_cnt;
    //}
    
    uint8_t * get_rcbr_rcv_buffer(void)
    {
        return rcbr_data_buf;
    }
    
    uint16_t get_rcbr_rcv_cnt(void)
    {
        return rcbr_data_cnt;
    }
    
    /**@brief Callback function for asserts in the SoftDevice.
     *
     * @details This function will be called in case of an assert in the SoftDevice.
     *
     * @warning This handler is an example only and does not fit a final product. You need to analyze
     *          how your product is supposed to react in case of Assert.
     * @warning On assert from the SoftDevice, the system can only recover on reset.
     *
     * @param[in]   line_num   Line number of the failing ASSERT call.
     * @param[in]   file_name  File name of the failing ASSERT call.
     */
    void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name)
    {
        app_error_handler(DEAD_BEEF, line_num, p_file_name);
    }
    
    
    void wdt_event_handler(void)
    {
    NRF_LOG_INFO("SNEHAL");
    
    }
    
    #define NRFX_WDT_DEAFULT_CONFIG_1                                             \
        {                                                                         \
            .behaviour          = WDT_CONFIG_BEHAVIOUR,                           \
            .reload_value       = WDT_CONFIG_RELOAD_VALUE,                   \
            NRFX_WDT_IRQ_CONFIG                                                   \
        }
    
    void wdt_init(void)
    {
      uint32_t err_code = NRF_SUCCESS;
    
      nrfx_wdt_config_t w_config  = NRFX_WDT_DEAFULT_CONFIG;
      
      err_code = nrfx_wdt_init(&w_config, NULL);
      APP_ERROR_CHECK(err_code);
    
      err_code = nrfx_wdt_channel_alloc(&m_channel_id);
      APP_ERROR_CHECK(err_code);
    
      nrfx_wdt_enable();
    
     
    
    }
    
    /**@brief Function for performing battery measurement and updating the Battery Level characteristic
     *        in Battery Service.
     */
     extern uint8_t SOC;
    
    void battery_level_update(void)
    {
        ret_code_t err_code;
        uint8_t  battery_level;
    
        //battery_level = battery_get_percentage(); /* Update TODO */
        battery_level = SOC; //battery_get_percentage(); /* Update TODO */
    
        err_code = ble_bas_battery_level_update(&m_bas, battery_level, BLE_CONN_HANDLE_ALL);
        if ((err_code != NRF_SUCCESS) &&
                (err_code != NRF_ERROR_INVALID_STATE) &&
                (err_code != NRF_ERROR_RESOURCES) &&
                (err_code != NRF_ERROR_BUSY) &&
                (err_code != BLE_ERROR_GATTS_SYS_ATTR_MISSING)
           ) {
            APP_ERROR_HANDLER(err_code);
        }
    }
    
    
    
    
    
    uint32_t rtc_val = 0;
    
    uint32_t get_system_rtc(void)
    {
        return rtc_val;
    }
    
    /**@brief Function for handling the RTC event
     *
     * @details This function will be called each time the RTC timer expires.
     *
     * @param[in] xTimer Handler to the timer that called this function.
     *                   You may get identifier given to the function xTimerCreate using pvTimerGetTimerID.
     */
    static void rtc_timeout_handler(TimerHandle_t xTimer)
    {
        UNUSED_PARAMETER(xTimer);
        rtc_val++;
    }
    
    
    static StaticTimer_t xRTCTimer;
    
    
    /**@brief Function for the GAP initialization.
     *
     * @details This function sets up all the necessary GAP (Generic Access Profile) parameters of the
     *          device including the device name, appearance, and the preferred connection parameters.
     */
    
    static void gap_params_init(void)
    {
        ret_code_t              err_code;
        ble_gap_conn_params_t   gap_conn_params;
        ble_gap_conn_sec_mode_t sec_mode;
    
        BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
    
        //commented for adding device id.
        //err_code = sd_ble_gap_device_name_set(&sec_mode,
        //                                      (const uint8_t *)DEVICE_NAME,
        //                                      strlen(DEVICE_NAME));
    
    #ifdef USE_DEVICEID_ON_SRDATA
        err_code = sd_ble_gap_device_name_set(&sec_mode,
                                              (const uint8_t *)DEVICE_NAME,
                                              strlen(DEVICE_NAME));
    #else
        uint8_t basename_size = strlen(MAIN_DEVICE_NAME);
        uint8_t devicename[DEVICEID_SIZE+1+basename_size+1];
            
        memcpy(&devicename[0], (const uint8_t *)MAIN_DEVICE_NAME, basename_size);
        devicename[basename_size] = '-';
        memcpy(&devicename[basename_size+1], device_id, DEVICEID_SIZE);
        memset(&devicename[basename_size+1+DEVICEID_SIZE], 0x00, 1);
    
        err_code = sd_ble_gap_device_name_set(&sec_mode,
                                              (const uint8_t *)devicename,
                                              strlen(devicename));
    #endif
    
    
    
        APP_ERROR_CHECK(err_code);
    
        err_code = sd_ble_gap_appearance_set(BLE_APPEARANCE_UNKNOWN);
        APP_ERROR_CHECK(err_code);
    
        memset(&gap_conn_params, 0, sizeof(gap_conn_params));
    
        gap_conn_params.min_conn_interval = MIN_CONN_INTERVAL;
        gap_conn_params.max_conn_interval = MAX_CONN_INTERVAL;
        gap_conn_params.slave_latency     = SLAVE_LATENCY;
        gap_conn_params.conn_sup_timeout  = CONN_SUP_TIMEOUT;
    
        err_code = sd_ble_gap_ppcp_set(&gap_conn_params);
        APP_ERROR_CHECK(err_code);
    /*sne    ////////Added for bonding ///////////
        m_static_pin_option.gap_opt.passkey.p_passkey = &passkey[0]; 
        err_code =  sd_ble_opt_set(BLE_GAP_OPT_PASSKEY, &m_static_pin_option); 
        APP_ERROR_CHECK(err_code);
        ////////Added for bonding /////////// sne*/
    
    
    }
    
    typedef struct
    {
        uint16_t peripheral_mtu;
    
    } sys_info_t;
    
    static sys_info_t      sys_info;
    
    void sys_set_peripheral_mtu(uint16_t mtu)
    {
        sys_info.peripheral_mtu = mtu;
    
    }
    
    
    uint16_t sys_get_peripheral_mtu(void)
    {
        return sys_info.peripheral_mtu;
    }
    
    ///**@brief Function for handling events from the GATT library. */
    //void gatt_evt_handler(nrf_ble_gatt_t * p_gatt, nrf_ble_gatt_evt_t const * p_evt)
    //{
    //    if ((m_conn_handle == p_evt->conn_handle) && (p_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED))
    //    {        
    //        sys_set_peripheral_mtu(p_evt->params.att_mtu_effective - OPCODE_LENGTH - HANDLE_LENGTH);
    
    //        NRF_LOG_INFO("Data len is set to 0x%X(%d)", sys_get_peripheral_mtu(), sys_get_peripheral_mtu());
    //        NRF_LOG_PROCESS();
    //    }
    //    NRF_LOG_INFO("ATT MTU exchange completed. central 0x%x peripheral 0x%x",
    //                  p_gatt->att_mtu_desired_central,
    //                  p_gatt->att_mtu_desired_periph);
    //    NRF_LOG_PROCESS();
    //}
    
    void gatt_evt_handler(nrf_ble_gatt_t * p_gatt, nrf_ble_gatt_evt_t const * p_evt)
    {
        if ((m_conn_handle == p_evt->conn_handle) && (p_evt->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED))
        {
            m_ble_nus_max_data_len = p_evt->params.att_mtu_effective - OPCODE_LENGTH - HANDLE_LENGTH;
            NRF_LOG_INFO("Data len is set to 0x%X(%d)", m_ble_nus_max_data_len, m_ble_nus_max_data_len);
        }
        NRF_LOG_DEBUG("ATT MTU exchange completed. central 0x%x peripheral 0x%x",
                      p_gatt->att_mtu_desired_central,
                      p_gatt->att_mtu_desired_periph);
    }
    
    /**@brief Function for initializing the GATT module. */
    static void gatt_init(void)
    {
        ret_code_t err_code = nrf_ble_gatt_init(&m_gatt, gatt_evt_handler);
        APP_ERROR_CHECK(err_code);
        err_code = nrf_ble_gatt_att_mtu_periph_set(&m_gatt, NRF_SDH_BLE_GATT_MAX_MTU_SIZE);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for handling Queued Write Module errors.
     *
     * @details A pointer to this function will be passed to each service which may need to inform the
     *          application about an error.
     *
     * @param[in]   nrf_error   Error code containing information about what went wrong.
     */
    static void nrf_qwr_error_handler(uint32_t nrf_error)
    {
        APP_ERROR_HANDLER(nrf_error);
    }
    
    
    
    //static void rclr_data_handler(ble_rclr_evt_t * p_evt)
    //{
    //    if (p_evt->type == BLE_RCLR_EVT_RX_DATA) {
    //        uint32_t err_code;
    
    //        if(p_evt->params.rx_data.length < sizeof(rclr_data_buf)) {
    //            memset(rclr_data_buf, 0, sizeof(rclr_data_buf));
    //            memcpy(rclr_data_buf, p_evt->params.rx_data.p_data, p_evt->params.rx_data.length);
    //            rclr_data_cnt = p_evt->params.rx_data.length;
    
    //            /* Inform lender Task we have a command */
    //            lender_task_queue_event(LENDER_TASK_EVT_SETTING_CMD);
    //        }
    //    } else if(p_evt->type == BLE_RCLR_EVT_NOTIF_ENABLED) {
    //        /* Inform lender Task notifications have begun */
    //        lender_task_queue_event(LENDER_TASK_EVT_NOTIF_EN);
    //    }
    //}
    
    
    static void rcbr_data_handler_new(ble_rcbr_evt_t * p_evt)
    {
        psf_comm_task_evt_t evt;
    
        if (p_evt->type == BLE_RCBR_EVT_RX_DATA) {
            uint32_t err_code;
    
            if(p_evt->params.rx_data.length < MAX_FRAME_PAYLOAD_SIZE) {
              
                evt.evt_id = PSF_COMM_TASK_EVT_PSF_DATA;
                evt.length = p_evt->params.rx_data.length;
                memcpy(evt.payload, p_evt->params.rx_data.p_data, p_evt->params.rx_data.length);            
    
             //   psf_comm_task_queue_event(&evt);
            }
        } else if(p_evt->type == BLE_RCBR_EVT_NOTIF_ENABLED) {
            /* Inform Toilet Task notifications have begun */
            // toilet_task_queue_event(TOILET_TASK_EVT_NOTIF_EN);
        }
    }
    
    
    
    static void rcbr_data_handler(ble_rcbr_evt_t * p_evt)
    {
        if (p_evt->type == BLE_RCBR_EVT_RX_DATA) {
            uint32_t err_code;
    
            if(p_evt->params.rx_data.length < sizeof(rcbr_data_buf)) {
                memset(rcbr_data_buf, 0, sizeof(rcbr_data_buf));
                memcpy(rcbr_data_buf, p_evt->params.rx_data.p_data, p_evt->params.rx_data.length);
                rcbr_data_cnt = p_evt->params.rx_data.length;
    
                /* Inform borrower Task we have a command */
               // clinitraq_task_queue_event(CLINITRAQ_TASK_EVT_SETTING_CMD);
            }
        } else if(p_evt->type == BLE_RCBR_EVT_NOTIF_ENABLED) {
            /* Inform borrower Task notifications have begun */
           // clinitraq_task_queue_event(CLINITRAQ_TASK_EVT_NOTIF_EN);
        }
    }
    
    
    static void ble_dfu_evt_handler(ble_dfu_buttonless_evt_type_t event)
    {
        switch (event)
        {
            case BLE_DFU_EVT_BOOTLOADER_ENTER_PREPARE:
            {
                NRF_LOG_INFO("Device is preparing to enter bootloader mode.");
    
                // Prevent device from advertising on disconnect.
                ble_adv_modes_config_t config;
                advertising_config_get(&config);
                config.ble_adv_on_disconnect_disabled = true;
                ble_advertising_modes_config_set(&m_advertising, &config);
    
                // Disconnect all other bonded devices that currently are connected.
                // This is required to receive a service changed indication
                // on bootup after a successful (or aborted) Device Firmware Update.
                uint32_t conn_count = ble_conn_state_for_each_connected(disconnect, NULL);
                NRF_LOG_INFO("Disconnected %d links.", conn_count);
                break;
            }
    
            case BLE_DFU_EVT_BOOTLOADER_ENTER:
                // YOUR_JOB: Write app-specific unwritten data to FLASH, control finalization of this
                //           by delaying reset by reporting false in app_shutdown_handler
                NRF_LOG_INFO("Device will enter bootloader mode.");
                break;
    
            case BLE_DFU_EVT_BOOTLOADER_ENTER_FAILED:
                NRF_LOG_ERROR("Request to enter bootloader mode failed asynchroneously.");
                // YOUR_JOB: Take corrective measures to resolve the issue
                //           like calling APP_ERROR_CHECK to reset the device.
                break;
    
            case BLE_DFU_EVT_RESPONSE_SEND_ERROR:
                NRF_LOG_ERROR("Request to send a response to client failed.");
                // YOUR_JOB: Take corrective measures to resolve the issue
                //           like calling APP_ERROR_CHECK to reset the device.
                APP_ERROR_CHECK(false);
                break;
    
            default:
                NRF_LOG_ERROR("Unknown event from ble_dfu_buttonless.");
                break;
        }
    }
    
    /**@brief Function for initializing services that will be used by the application.
     *
     * @details Initialize the Heart Rate, Battery and Device Information services.
     */
    static void services_init(void)
    {
        ret_code_t         err_code;
       // ble_rclr_init_t    rclr_init;
        ble_rcbr_init_t    rcbr_init;
        ble_bas_init_t     bas_init;
        ble_dis_init_t     dis_init;
        nrf_ble_qwr_init_t qwr_init = {0};
        ble_dfu_buttonless_init_t dfus_init = {0};
    
        // Initialize Queued Write Module.
        qwr_init.error_handler = nrf_qwr_error_handler;
    
        err_code = nrf_ble_qwr_init(&m_qwr, &qwr_init);
        APP_ERROR_CHECK(err_code);
    
        // Initialize Battery Service.
        memset(&bas_init, 0, sizeof(bas_init));
    
        // Here the sec level for the Battery Service can be changed/increased.
        bas_init.bl_rd_sec        = SEC_OPEN;
        bas_init.bl_cccd_wr_sec   = SEC_OPEN;
        bas_init.bl_report_rd_sec = SEC_OPEN;
    
        bas_init.evt_handler          = NULL;
        bas_init.support_notification = true;
        bas_init.p_report_ref         = NULL;
        bas_init.initial_batt_level   = 100;
    
        err_code = ble_bas_init(&m_bas, &bas_init);
        APP_ERROR_CHECK(err_code);
    
        // Initialize Device Information Service.
        memset(&dis_init, 0, sizeof(dis_init));
    
        ble_srv_ascii_to_utf8(&dis_init.manufact_name_str, (char *)MANUFACTURER_NAME);
        ble_srv_ascii_to_utf8(&dis_init.model_num_str, (char *)DEVICE_MODEL_NUM);
        ble_srv_ascii_to_utf8(&dis_init.serial_num_str, (char *)device_id);
        ble_srv_ascii_to_utf8(&dis_init.hw_rev_str, (char *)DEVICE_HW_VER);
        ble_srv_ascii_to_utf8(&dis_init.fw_rev_str, (char *)app_fw_version);
    
    
        dis_init.dis_char_rd_sec = SEC_OPEN;
    
    
        err_code = ble_dis_init(&dis_init);
        APP_ERROR_CHECK(err_code);
    
    
        // Initialize RCLR- LENDER Service
        //memset(&rclr_init, 0, sizeof(rclr_init));
    
        //rclr_init.data_handler = rclr_data_handler;
    
        //err_code = ble_rclr_init(&m_rclr, &rclr_init);
        //APP_ERROR_CHECK(err_code);
    
       // Initialize RCBR - BORROWER Service
        memset(&rcbr_init, 0, sizeof(rcbr_init));
    
        rcbr_init.pulsecount   = 100;
        rcbr_init.data_handler = rcbr_data_handler;
    
        err_code = ble_rcbr_init(&m_rcbr, &rcbr_init);
        APP_ERROR_CHECK(err_code);
    
    
        // Initialize the Nordic DFU Buttonless Service
        dfus_init.evt_handler = ble_dfu_evt_handler;
    
        err_code = ble_dfu_buttonless_init(&dfus_init);
        APP_ERROR_CHECK(err_code);
    
    
    }
    
    
    
    /**@brief   Function for starting application timers.
     * @details Timers are run after the scheduler has started.
     */
    static void application_timers_start(void)
    {
        // Start application timers.
        if (pdPASS != xTimerStart(m_rtc_timer, OSTIMER_WAIT_FOR_QUEUE)) {
            APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
        }
    }
    
    /**@brief Function for handling the Connection Parameters Module.
     *
     * @details This function will be called for all events in the Connection Parameters Module which
     *          are passed to the application.
     *          @note All this function does is to disconnect. This could have been done by simply
     *                setting the disconnect_on_fail config parameter, but instead we use the event
     *                handler mechanism to demonstrate its use.
     *
     * @param[in]   p_evt   Event received from the Connection Parameters Module.
     */
    static void on_conn_params_evt(ble_conn_params_evt_t * p_evt)
    {
        ret_code_t err_code;
    
        if (p_evt->evt_type == BLE_CONN_PARAMS_EVT_FAILED) {
            err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_CONN_INTERVAL_UNACCEPTABLE);
            APP_ERROR_CHECK(err_code);
        }
    }
    
    
    /**@brief Function for handling a Connection Parameters error.
     *
     * @param[in]   nrf_error   Error code containing information about what went wrong.
     */
    static void conn_params_error_handler(uint32_t nrf_error)
    {
        APP_ERROR_HANDLER(nrf_error);
    }
    
    
    /**@brief Function for initializing the Connection Parameters module. */
    static void conn_params_init(void)
    {
        ret_code_t             err_code;
        ble_conn_params_init_t cp_init;
    
        memset(&cp_init, 0, sizeof(cp_init));
    
        cp_init.p_conn_params                  = NULL;
        cp_init.first_conn_params_update_delay = FIRST_CONN_PARAMS_UPDATE_DELAY;
        cp_init.next_conn_params_update_delay  = NEXT_CONN_PARAMS_UPDATE_DELAY;
        cp_init.max_conn_params_update_count   = MAX_CONN_PARAMS_UPDATE_COUNT;
        cp_init.start_on_notify_cccd_handle    = BLE_GATT_HANDLE_INVALID;
        cp_init.disconnect_on_fail             = true;
        cp_init.evt_handler                    = NULL;
        cp_init.error_handler                  = conn_params_error_handler;
    
        err_code = ble_conn_params_init(&cp_init);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for putting the chip into sleep mode.
     *
     * @note This function will not return.
     */
     int sleep = 0;
    
    static void sleep_mode_enter(void)
    {
        ret_code_t err_code;
        sleep = 1;adv_success = 0;
        NRF_LOG_INFO("SLEEP MODE ENTER\r\n");
    
          nrf_gpio_pin_set(LED_RC_1);    
          nrf_gpio_pin_set(LED_RC_2);  
          nrf_gpio_pin_set(LED_RC_3);  
        
        err_code = bsp_indication_set(BSP_INDICATE_IDLE);
        APP_ERROR_CHECK(err_code);
    
    
        // Prepare wakeup buttons.
        //err_code = bsp_btn_ble_sleep_mode_prepare();
        //APP_ERROR_CHECK(err_code);
    
        // Go to system-off mode (this function will not return; wakeup will cause a reset).
        err_code = sd_power_system_off();
        //nrf_power_system_off();
       
    }
    
    
    /**@brief Function for handling advertising events.
     *
     * @details This function will be called for advertising events which are passed to the application.
     *
     * @param[in] ble_adv_evt  Advertising event.
     */
    static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
    {
        uint32_t err_code;
    
        switch (ble_adv_evt) {
        case BLE_ADV_EVT_FAST:
            NRF_LOG_INFO("Fast advertising.");
            //err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
            //APP_ERROR_CHECK(err_code);
            break;
    
        case BLE_ADV_EVT_IDLE:
             {
                //err_code = bsp_indication_set(BSP_INDICATE_IDLE);
                //APP_ERROR_CHECK(err_code);
                
                /* auto restart advertising */
                advertising_start1();
               //sleep_mode_enter();
             }
            break;
    
        default:
            break;
        }
    }
    
    
    extern uint8_t led_all_active;
    extern uint8_t led_all_state;
    
    /**@brief Function for handling BLE events.
     *
     * @param[in]   p_ble_evt   Bluetooth stack event.
     * @param[in]   p_context   Unused.
     */
    static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
    {
        uint32_t err_code;
        led_btn_task_evt_t evt;
    
        switch (p_ble_evt->header.evt_id) {
        case BLE_GAP_EVT_CONNECTED:
            NRF_LOG_INFO("APP is Connected\n\r");
            m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
                //err_code = nrf_ble_qwr_conn_handle_assign(&m_qwr, m_conn_handle);
                //APP_ERROR_CHECK(err_code);
            break;
    
        case BLE_GAP_EVT_DISCONNECTED:
            NRF_LOG_INFO("Disconnected");
            m_conn_handle = BLE_CONN_HANDLE_INVALID;
            break;
    
        case BLE_GAP_EVT_PHY_UPDATE_REQUEST: {
            NRF_LOG_DEBUG("PHY update request.");
            ble_gap_phys_t const phys = {
                .rx_phys = BLE_GAP_PHY_AUTO,
                .tx_phys = BLE_GAP_PHY_AUTO,
            };
            err_code = sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys);
            APP_ERROR_CHECK(err_code);
        }
        break;
    
        case BLE_GATTC_EVT_TIMEOUT:
            // Disconnect on GATT Client timeout event.
            NRF_LOG_DEBUG("GATT Client Timeout.");
            err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
                                             BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            APP_ERROR_CHECK(err_code);
            break;
    
        case BLE_GATTS_EVT_TIMEOUT:
            // Disconnect on GATT Server timeout event.
            NRF_LOG_DEBUG("GATT Server Timeout.");
            err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
                                             BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            APP_ERROR_CHECK(err_code);
            break;
    
        default:
            // No implementation needed.
            break;
        }
    }
    
    
    
    static void ble_evt_handler1111(ble_evt_t const * p_ble_evt, void * p_context)
    {
        char        passkey[BLE_GAP_PASSKEY_LEN + 1];
        uint16_t    role = ble_conn_state_role(m_conn_handle);
    
     //   pm_handler_secure_on_connection(p_ble_evt);
    
        uint32_t err_code;
        ble_gap_evt_t const * p_gap_evt = &p_ble_evt->evt.gap_evt; //$$ new
    
        switch (p_ble_evt->header.evt_id) {
        case BLE_GAP_EVT_CONNECTED:
            NRF_LOG_INFO("Connected");
            err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
            APP_ERROR_CHECK(err_code);
            m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
            err_code = nrf_ble_qwr_conn_handle_assign(&m_qwr, m_conn_handle);
            APP_ERROR_CHECK(err_code);
    
            //adv_led_button =1;
            //led_grn_pwr_active = 1;
            //led_on_duration = get_system_rtc();
            //led_btn_task_evt_t evt;
            //evt.id = LED_TASK_EVT_PROCESS_LED_RC2;
    
            //led_btn_task_queue_event(evt);
    
    
            err_code = sd_ble_gap_rssi_start(p_ble_evt->evt.gap_evt.conn_handle,1,2); //$$ new
            APP_ERROR_CHECK(err_code); //$$ new      
          
        break;
    
        case BLE_GAP_EVT_DISCONNECTED:
            NRF_LOG_INFO("Disconnected");
            m_conn_handle = BLE_CONN_HANDLE_INVALID;
            break;
    #if 1
            case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
                //NRF_LOG_INFO("%s: BLE_GAP_EVT_SEC_PARAMS_REQUEST", nrf_log_push(roles_str[role]));
                break;
    
    
            //case BLE_GAP_EVT_PASSKEY_DISPLAY:
            //    memcpy(passkey, p_ble_evt->evt.gap_evt.params.passkey_display.passkey, BLE_GAP_PASSKEY_LEN);
            //    passkey[BLE_GAP_PASSKEY_LEN] = 0x00;
            //    NRF_LOG_INFO("%s: BLE_GAP_EVT_PASSKEY_DISPLAY: passkey=%s match_req=%d",
            //                 nrf_log_push(roles_str[role]),
            //                 nrf_log_push(passkey),
            //                 p_ble_evt->evt.gap_evt.params.passkey_display.match_request);
    
            //    if (p_ble_evt->evt.gap_evt.params.passkey_display.match_request)
            //    {
            //        on_match_request(m_conn_handle, role);
            //    }
            //    break;
    
         /*sne   case BLE_GAP_EVT_PASSKEY_DISPLAY:
            {
                //char passkey[16 + 1];
                memcpy(passkey, p_ble_evt->evt.gap_evt.params.passkey_display.passkey, 16);
                passkey[16] = 0;
                // Don't send delayed Security Request if security procedure is already in progress.
                //err_code = app_timer_stop(m_sec_req_timer_id);
                //APP_ERROR_CHECK(err_code);
    
                NRF_LOG_INFO("Passkey: %s", nrf_log_push(passkey));
            } break; sne */
    
      /*sne      case BLE_GAP_EVT_AUTH_KEY_REQUEST:
               // NRF_LOG_INFO("%s: BLE_GAP_EVT_AUTH_KEY_REQUEST", nrf_log_push(roles_str[role]));
                break;
    
            case BLE_GAP_EVT_LESC_DHKEY_REQUEST:
                //NRF_LOG_INFO("%s: BLE_GAP_EVT_LESC_DHKEY_REQUEST", nrf_log_push(roles_str[role]));
                break;
    
             case BLE_GAP_EVT_AUTH_STATUS:
                 //NRF_LOG_INFO("%s: BLE_GAP_EVT_AUTH_STATUS: status=0x%x bond=0x%x lv4: %d kdist_own:0x%x kdist_peer:0x%x",
                 //             nrf_log_push(roles_str[role]),
                              //p_ble_evt->evt.gap_evt.params.auth_status.auth_status,
                              //p_ble_evt->evt.gap_evt.params.auth_status.bonded,
                              //p_ble_evt->evt.gap_evt.params.auth_status.sm1_levels.lv4,
                              //*((uint8_t *)&p_ble_evt->evt.gap_evt.params.auth_status.kdist_own),
                              //*((uint8_t *)&p_ble_evt->evt.gap_evt.params.auth_status.kdist_peer));
                break; sne*/
    #endif
    
        case BLE_GAP_EVT_PHY_UPDATE_REQUEST: {
            NRF_LOG_DEBUG("PHY update request.");
            ble_gap_phys_t const phys = {
                .rx_phys = BLE_GAP_PHY_AUTO,
                .tx_phys = BLE_GAP_PHY_AUTO,
            };
            err_code = sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys);
            APP_ERROR_CHECK(err_code);
        }
        break;
    
        case BLE_GATTC_EVT_TIMEOUT:
            // Disconnect on GATT Client timeout event.
            NRF_LOG_DEBUG("GATT Client Timeout.");
            err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gattc_evt.conn_handle,
                                             BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            APP_ERROR_CHECK(err_code);
            break;
    
        case BLE_GATTS_EVT_TIMEOUT:
            // Disconnect on GATT Server timeout event.
            NRF_LOG_DEBUG("GATT Server Timeout.");
            err_code = sd_ble_gap_disconnect(p_ble_evt->evt.gatts_evt.conn_handle,
                                             BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            APP_ERROR_CHECK(err_code);
            break;
    
        case BLE_GAP_EVT_RSSI_CHANGED:
             rssi = p_ble_evt->evt.gap_evt.params.rssi_changed.rssi;
            // NRF_LOG_INFO("RSSI: %d", p_ble_evt->evt.gap_evt.params.rssi_changed.rssi);
            break;
    
        default:
            // No implementation needed.
            break;
        }
    }
    
    
    /**@brief Function for initializing the BLE stack.
     *
     * @details Initializes the SoftDevice and the BLE event interrupt.
     */
    static void ble_stack_init(void)
    {
        ret_code_t err_code;
    
        err_code = nrf_sdh_enable_request();
        APP_ERROR_CHECK(err_code);
    
        // Configure the BLE stack using the default settings.
        // Fetch the start address of the application RAM.
        uint32_t ram_start = 0;
        err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
        APP_ERROR_CHECK(err_code);
    
        // Enable BLE stack.
        err_code = nrf_sdh_ble_enable(&ram_start);
        APP_ERROR_CHECK(err_code);
    
        // Register a handler for BLE events.
        NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
    }
    
    
    /**@brief Function for handling events from the BSP module.
     *
     * @param[in]   event   Event generated by button press.
     */
    static void bsp_event_handler(bsp_event_t event)
    {
        ret_code_t err_code;
    
        switch (event) {
        case BSP_EVENT_SLEEP:
           // sleep_mode_enter();
            break;
    
        case BSP_EVENT_DISCONNECT:
            err_code = sd_ble_gap_disconnect(m_conn_handle,
                                             BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
            if (err_code != NRF_ERROR_INVALID_STATE) {
                APP_ERROR_CHECK(err_code);
            }
            break;
    
        case BSP_EVENT_WHITELIST_OFF:
            if (m_conn_handle == BLE_CONN_HANDLE_INVALID) {
                err_code = ble_advertising_restart_without_whitelist(&m_advertising);
                if (err_code != NRF_ERROR_INVALID_STATE) {
                    APP_ERROR_CHECK(err_code);
                }
            }
            break;
        default:
            break;
        }
    }
    
    
    /**@brief Function for the Peer Manager initialization. */
    static void peer_manager_init(void)
    {
        //ble_gap_sec_params_t sec_param;
        //ret_code_t           err_code;
    
        //err_code = pm_init();
        //APP_ERROR_CHECK(err_code);
    
    
    
        //memset(&sec_param, 0, sizeof(ble_gap_sec_params_t));
    
        //// Security parameters to be used for all security procedures.
        //sec_param.bond           = SEC_PARAM_BOND;
        //sec_param.mitm           = SEC_PARAM_MITM;
        //sec_param.lesc           = SEC_PARAM_LESC;
        //sec_param.keypress       = SEC_PARAM_KEYPRESS;
        //sec_param.io_caps        = SEC_PARAM_IO_CAPABILITIES;
        //sec_param.oob            = SEC_PARAM_OOB;
        //sec_param.min_key_size   = SEC_PARAM_MIN_KEY_SIZE;
        //sec_param.max_key_size   = SEC_PARAM_MAX_KEY_SIZE;
        //sec_param.kdist_own.enc  = 0;
        //sec_param.kdist_own.id   = 0;
        //sec_param.kdist_peer.enc = 0;
        //sec_param.kdist_peer.id  = 0;
    
        //err_code = pm_sec_params_set(&sec_param);
        //APP_ERROR_CHECK(err_code);
    
        //err_code = pm_register(pm_evt_handler);
        //APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Clear bond information from persistent storage. */
    static void delete_bonds(void)
    {
        ret_code_t err_code;
    
        NRF_LOG_INFO("Erase bonds!");
    
        err_code = pm_peers_delete();
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for initializing the Advertising functionality. */
    
    
    static void advertising_init(void)
    {
        ret_code_t             err_code;
        ble_advertising_init_t init;
    
        memset(&init, 0, sizeof(init));
    
        init.advdata.name_type               = BLE_ADVDATA_NO_NAME;
        init.advdata.include_appearance      = false;
        init.advdata.flags                   = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;//BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
        init.advdata.uuids_more_available.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
        init.advdata.uuids_more_available.p_uuids  = m_adv_uuids;
    
        init.config.ble_adv_fast_enabled  = true;
        init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
        init.config.ble_adv_fast_timeout  = APP_ADV_DURATION;
    
    
        init.srdata.name_type = BLE_ADVDATA_FULL_NAME;
    
        init.evt_handler = on_adv_evt;
    
        err_code = ble_advertising_init(&m_advertising, &init);
        APP_ERROR_CHECK(err_code);
    
        ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
    }
    
    
    /**@brief Function for initializing the clock.
     */
    static void clock_init(void)
    {
        ret_code_t err_code = nrf_drv_clock_init();
        APP_ERROR_CHECK(err_code);
    }
    
    
    
    static void timers_init(void)
    {
        ret_code_t err_code = app_timer_init();
        APP_ERROR_CHECK(err_code);
    
    }
    
    
    static void idle_state_handle(void)
    {
        UNUSED_RETURN_VALUE(NRF_LOG_PROCESS());
        
        uint32_t err_code = sd_app_evt_wait();
        APP_ERROR_CHECK(err_code);
    
        NRF_LOG_FLUSH();
        //if (NRF_LOG_PROCESS() == false)
        //{
        //    nrf_pwr_mgmt_run();
        //}
    
    }
    
    /** @brief Function for initializing the nrf_log module. */
    static void log_init(void)
    {
        ret_code_t err_code = NRF_LOG_INIT(NULL);
        APP_ERROR_CHECK(err_code);
    
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    }
    
    /**@brief Function for application main entry.
     */
     /**
     * @brief Function for main application entry.
     */
    int main(void)
    {
        ret_code_t ret;
        bool erase_bonds;
    
        log_init();
        timers_init();
    
        ret = nrf_drv_clock_init();
        APP_ERROR_CHECK(ret);
      
        //nrf_drv_clock_lfclk_request(NULL);
         usbd_config_init();
    
        ret = nrf_drv_gpiote_init();
        APP_ERROR_CHECK(ret);
    
        gpio_init();
    
       nrf_gpio_pin_set(EN_SUPPLY);
       start_charging();
       nrf_delay_ms(1000);
       spi_init();
       nrf_delay_ms(2000);
        
    
        ble_stack_init();
        gap_params_init();
        gatt_init();
        services_init();
        advertising_init();
        conn_params_init();
        //peer_manager_init();
    
        usb_msc_init();
    
        advertising_start1();
    
        ret = app_usbd_power_events_enable();
        APP_ERROR_CHECK(ret);
    
        //for(int i=0;i<100;i++)
        //{
    
        //write_data_in_file(16,0.1234);
        //get_memory_space(&total,&free1);
        //nrf_delay_ms(500);
    
        //}
    
        while (true)
        {
    
            while (app_usbd_event_queue_process())
            {
              
            }
            idle_state_handle();
    
        }
    }
    
    
    void usb_msc_init(void)
    {
    
        ret_code_t ret;
    
        app_usbd_class_inst_t const * class_inst_msc = app_usbd_msc_class_inst_get(&m_app_msc);
        ret = app_usbd_class_append(class_inst_msc);
        APP_ERROR_CHECK(ret);
    
        if (fatfs_init())
        {
              fatfs_ls();
              fatfs_mkfs();
              fatfs_file_create();
    
        }
    
        NRF_LOG_FLUSH();
    
    
    
        NRF_LOG_INFO("USBD MSC example started.");
    
        nrf_qspi_cinstr_conf_t cinstr_cfg = {
            .opcode    = 0x9F,
            .length    = 4,
            .io2_level = true,
            .io3_level = true,
            .wipwait   = true,
            .wren      = true
        };
    
        uint8_t rdid_buf[3] = {0, 0, 0};
        ret = nrf_drv_qspi_cinstr_xfer(&cinstr_cfg, NULL, rdid_buf);
        if (ret != NRF_SUCCESS)
        {
            NRF_LOG_INFO("read eror.");
            //NRF_LOG_INST_ERROR(p_qspi_dev->p_log, "QSPI get 3 byte id error: %"PRIu32"", ret);
            //return ret;
        }
        NRF_LOG_INFO("rdid_buf [%02x %02x %02x]", rdid_buf[0], rdid_buf[1], rdid_buf[2]);
        
    
        get_memory_space(&total,&free1);
        NRF_LOG_INFO("total %d,free %d",total,free1);
    
        // write_header();
        write_data_in_file(15,0.1234);
    
        clinitraq_init();   
        write_data_in_file(16,0.0001);
        get_memory_space(&total,&free1);
    
      
    }
    
    
    void usbd_config_init(void)
    {
       ret_code_t ret;
    
       static const app_usbd_config_t usbd_config = {
          //  .ev_handler    = usbd_event_handler,
            .ev_state_proc = usbd_user_ev_handler
        };
    
        ret = app_usbd_init(&usbd_config);
        APP_ERROR_CHECK(ret);
    
        //app_usbd_class_inst_t const * class_inst_msc = app_usbd_msc_class_inst_get(&m_app_msc);
        //ret = app_usbd_class_append(class_inst_msc);
        //APP_ERROR_CHECK(ret);
    
    }

    Thanks & Regards,
    Snehal

  • Hi Snehal

    When using the SoftDevice the initialization sequence can be important. There aren't a lot of examples showing USB and BLE, but there are some, including the usbd_ble_uart example in the peripherals folder. 

    Could you take a look at that example and try to initialize your modules in the same order?

    Also, did you make sure to add all the project defines needed to use BLE and the SoftDevice?

    Best regards
    Torbjørn

Related