usb msc code with FreeRtos gives error in vPortEnterCritical.

Hi ,

     I am trying to create a project with USB MSC using FreeRTOS. I have referred the examples "usb_msc" & "usbd_ble_uart_freertos_example" and created a project. I am not using CDC class. I am only using MSC class in my project. I am trying to communicate with an external flash chip and my spi drivers have some routines which include vTaskDelay function in read and write spi. Without RTOS my code works fine and I am able to communicate with the spi chip and create file system on it. While testing the code with FREERTOS, I am getting error inside vPortEnterCritical function and the code gets hanged in 

configASSERT( ( SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk ) == 0 );

I am not sure what is causing this issue. Can anyone please help?? I have attached my main.c here to check if any errors are there. Need some help on it as this task is critical and of high priority.

#include <stdint.h>
#include <string.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 "nrf_sdh_freertos.h"
#include "app_timer.h"
#include "peer_manager.h"
#include "peer_manager_handler.h"
#include "bsp_btn_ble.h"
#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "semphr.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_psf_comm.h"

#include "nrf_drv_gpiote.h"
#include "battery.h"
#include "version.h"
#include "task_led_button.h"
#include "app_button.h"
#include "usb_msc.h"
#include "bsp.h"
#include "spi.h"
#include "task_usb_msc.h"
#include "app_usbd_types.h"
#include "app_usbd_core.h"
#include "app_usbd.h"
#include "app_usbd_string_desc.h"
#include "app_usbd_msc.h"
#include "nrf_block_dev_spi.h"

#include "ff.h"
#include "diskio_blkdev.h"


#define MAIN_DEVICE_NAME                         LE_DEVICE_NAME                            /**< Name of device. Will be included in the advertising data. */
#define MANUFACTURER_NAME                   "Test"                   /**< 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                    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. */

#define RTC_INTERVAL                        1000                                    /**< RTC interval (ms). */
#define MIN_BATTERY_LEVEL                   81                                      /**< Minimum simulated battery level. */
#define MAX_BATTERY_LEVEL                   100                                     /**< Maximum simulated battery level. */

#define MIN_CONN_INTERVAL                   MSEC_TO_UNITS(200, UNIT_1_25_MS)        /**< Minimum acceptable connection interval (0.4 seconds). */
#define MAX_CONN_INTERVAL                   MSEC_TO_UNITS(300, UNIT_1_25_MS)        /**< Maximum acceptable connection interval (0.65 second). */
#define SLAVE_LATENCY                       3                                       /**< Slave latency. */
#define CONN_SUP_TIMEOUT                    MSEC_TO_UNITS(5000, UNIT_10_MS)         /**< Connection supervisory time-out (4 seconds). */

#define FIRST_CONN_PARAMS_UPDATE_DELAY      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       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;

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;



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. */
int adv_success = 0;

static ble_uuid_t m_adv_uuids[] =                                   /**< Universally unique service identifiers. */
{
    {BLE_UUID_RCBR_SERVICE, BLE_UUID_TYPE_VENDOR_BEGIN}
};




/**@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 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 advertising_start(void * p_erase_bonds);
static void nrf_nvmc_write_word(uint32_t address, uint32_t value);


ble_rcbr_t * get_rcbr_service(void)
{
    return &m_rcbr;
}


uint16_t get_conn_handle(void)
{
    return m_conn_handle;
}



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);
}

/**@brief Function for handling Peer Manager events.
 *
 * @param[in] p_evt  Peer Manager event.
 */
static void pm_evt_handler(pm_evt_t const * p_evt)
{
    bool delete_bonds = false;

    pm_handler_on_pm_evt(p_evt);
    pm_handler_flash_clean(p_evt);

    switch (p_evt->evt_id) {
    case PM_EVT_PEERS_DELETE_SUCCEEDED:
        //..advertising_start(&delete_bonds);
        advertising_start(false);
        break;

    default:
        break;
    }
}


/**@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 Timer initialization.
 *
 * @details Initializes the timer module. This creates and starts application timers.
 */
static void timers_init(void)
{
    // Initialize timer module.
    ret_code_t err_code = app_timer_init();
    APP_ERROR_CHECK(err_code);



    // Create timers.
    m_rtc_timer = xTimerCreateStatic("RTC",
                                     RTC_INTERVAL,
                                     pdTRUE,
                                     NULL,
                                     rtc_timeout_handler,
                                     &xRTCTimer);


    /* Error checking */
    if (NULL == m_rtc_timer) {
        APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
    }
}


/**@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*/


}


/**@brief Function for initializing the GATT module. */
static void gatt_init(void)
{
    ret_code_t err_code = nrf_ble_gatt_init(&m_gatt, NULL);
    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 */
            //clini_task_queue_event(CLINITRAQ_TASK_EVT_SETTING_CMD);
        }
    } else if(p_evt->type == BLE_RCBR_EVT_NOTIF_ENABLED) {
        /* Inform borrower Task notifications have begun */
        //clini_task_queue_event(CLINITRAQ_TASK_EVT_NOTIF_EN);
    }
}

/**@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};

    // 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);

}



/**@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             = false;
    cp_init.evt_handler                    = on_conn_params_evt;
    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:
         
         //  NRF_LOG_INFO("Going to sleep mode\r\n");
           //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");
        //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_blue_pwr_active = 1;rtc_val=0;
        led_on_duration = get_system_rtc();
        evt.id = LED_TASK_EVT_PROCESS_LED_RC1; // glow green led to indicate successful connection of the app.

        led_btn_task_queue_event(evt);


        break;

    case BLE_GAP_EVT_DISCONNECTED:
        NRF_LOG_INFO("Disconnected");
       // turn_off_wireless_charging();
            led_on_duration = 0;
            adv_led_button = 0;
            led_blue_pwr_active = 0;
            led_blue_pwr_state = 0;
        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 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))
//    {
//        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 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 nrf log module.
 */
static void log_init(void)
{
    ret_code_t err_code = NRF_LOG_INIT(NULL);
   // ret_code_t err_code = NRF_LOG_INIT(app_timer_cnt_get); //..snehal
    APP_ERROR_CHECK(err_code);

    NRF_LOG_DEFAULT_BACKENDS_INIT();
}
/**@brief Function for starting advertising. */
void advertising_start(void * p_erase_bonds)
{
    bool erase_bonds = *(bool*)p_erase_bonds;
    ret_code_t err_code;

    if (erase_bonds) {
        delete_bonds();
        // Advertising is started by PM_EVT_PEERS_DELETE_SUCCEEDED event.
    } else {
        err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
        APP_ERROR_CHECK(err_code);
    }

    NRF_LOG_INFO("ERROR CODE adv IS %d\r\n",err_code);
    if(err_code == 0)
    {
      adv_success  = 1;
    }
    else
    {
      adv_success  = 0;
    }
}

/* configSUPPORT_STATIC_ALLOCATION is set to 1, so the application must provide an
implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
used by the Idle task. */
void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer,
                                    StackType_t **ppxIdleTaskStackBuffer,
                                    uint32_t *pulIdleTaskStackSize )
{
    /* If the buffers to be provided to the Idle task are declared inside this
    function then they must be declared static - otherwise they will be allocated on
    the stack and so not exists after this function exits. */
    static StaticTask_t xIdleTaskTCB;
    static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ];

    /* Pass out a pointer to the StaticTask_t structure in which the Idle task's
    state will be stored. */
    *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;

    /* Pass out the array that will be used as the Idle task's stack. */
    *ppxIdleTaskStackBuffer = uxIdleTaskStack;

    /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
    Note that, as the array is necessarily of type StackType_t,
    configMINIMAL_STACK_SIZE is specified in words, not bytes. */
    *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
}

/* configSUPPORT_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
application must provide an implementation of vApplicationGetTimerTaskMemory()
to provide the memory that is used by the Timer service task. */
void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer,
                                     StackType_t **ppxTimerTaskStackBuffer,
                                     uint32_t *pulTimerTaskStackSize )
{
    /* If the buffers to be provided to the Timer task are declared inside this
    function then they must be declared static - otherwise they will be allocated on
    the stack and so not exists after this function exits. */
    static StaticTask_t xTimerTaskTCB;
    static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ];

    /* Pass out a pointer to the StaticTask_t structure in which the Timer
    task's state will be stored. */
    *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;

    /* Pass out the array that will be used as the Timer task's stack. */
    *ppxTimerTaskStackBuffer = uxTimerTaskStack;

    /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
    Note that, as the array is necessarily of type StackType_t,
    configTIMER_TASK_STACK_DEPTH is specified in words, not bytes. */
    *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
}

void vApplicationMallocFailedHook( void )
{
    NRF_LOG_INFO("Malloc Failed");
}

void vApplicationStackOverflowHook(xTaskHandle *pxTask, signed char *pcTaskName )
{

   for( ;; );
}


#if NRF_LOG_ENABLED
/**@brief Thread for handling the logger.
 *
 * @details This thread is responsible for processing log entries if logs are deferred.
 *          Thread flushes all log entries and suspends. It is resumed by idle task hook.
 *
 * @param[in]   arg   Pointer used for passing some arbitrary information (context) from the
 *                    osThreadCreate() call to the thread.
 */
static void logger_thread(void * arg)
{
    UNUSED_PARAMETER(arg);

    while (1) {
        NRF_LOG_FLUSH();

        vTaskSuspend(NULL); // Suspend myself
    }
}
#endif //NRF_LOG_ENABLED

/**@brief A function which is hooked to idle task.
 * @note Idle hook must be enabled in FreeRTOS configuration (configUSE_IDLE_HOOK).
 */
void vApplicationIdleHook( void )
{
#if NRF_LOG_ENABLED
    vTaskResume(m_logger_thread);
#endif
}


/**@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);
}

#define LOGGER_TASK_STACK_SIZE 512
#define LOGGER_TASK_PRIORITY   1
/* Structure that will hold the TCB of the task being created. */
StaticTask_t xLoggerTaskBuffer;

/* Buffer that the task being created will use as its stack.  Note this is
an array of StackType_t variables.  The size of StackType_t is dependent on
the RTOS port. */
StackType_t xLoggerStack[ LOGGER_TASK_STACK_SIZE ];

/**@brief Function for application main entry.
 */

#define USB_THREAD_MAX_BLOCK_TIME portMAX_DELAY
#define USBD_PRIORITY   3

StackType_t usb_msc_stack[ 512];
#define USBD_STACK_SIZE   256
static TaskHandle_t m_usbd_thread;        /**< USB stack thread. */
bool m_usb_connected = false;

bool g_test_open = false;
uint32_t g_idle_s = 0;

uint8_t rx_buff[1024];
uint16_t rx_index;

#define USE_FATFS_SPI    1

#define FR_FILE_OPENED 1
#define FR_FILE_CLOSED 2

const char my_filename[] = "test1.xls";
static nrf_atomic_u32_t m_key_events;

static bool fatfs_init(void);
static void fatfs_uninit(void);
void fatfs_mkfs(void);
static bool fatfs_init(void);
static void fatfs_ls(void);
static void fatfs_file_create(void);
static FRESULT my_file_open(FIL* my_file);
static FRESULT my_file_close(FIL * my_file);
static void my_file_write(void);
static void my_write_data(void);

static void msc_user_ev_handler(app_usbd_class_inst_t const * p_inst,
                                app_usbd_msc_user_event_t     event);


#ifndef USBD_POWER_DETECTION
#define USBD_POWER_DETECTION true
#endif

NRF_BLOCK_DEV_SPI_DEFINE(
    m_block_dev_spi,
    NRF_BLOCK_DEV_SPI_CONFIG(
        512,
        NRF_BLOCK_DEV_SPI_FLAG_CACHE_WRITEBACK,
        NRF_DRV_SPI_DEFAULT_CONFIG
     ),
     NFR_BLOCK_DEV_INFO_CONFIG("Nordic", "SPI", "1.00")
);

#define BLOCKDEV_LIST() (                                   \
    NRF_BLOCKDEV_BASE_ADDR(m_block_dev_spi, block_dev)     \
)

#define MSC_WORKBUFFER_SIZE (4096)
#define ENDPOINT_LIST() APP_USBD_MSC_ENDPOINT_LIST(1, 1)

APP_USBD_MSC_GLOBAL_DEF(m_app_msc,
                        0,
                        msc_user_ev_handler,
                        ENDPOINT_LIST(),
                        BLOCKDEV_LIST(),
                        MSC_WORKBUFFER_SIZE);



void usb_new_event_isr_handler(app_usbd_internal_evt_t const * const p_event, bool queued)
{
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    UNUSED_PARAMETER(p_event);
    UNUSED_PARAMETER(queued);
    ASSERT(m_usbd_thread != NULL);
    /* Release the semaphore */
    vTaskNotifyGiveFromISR(m_usbd_thread, &xHigherPriorityTaskWoken);
    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}

static void usbd_user_ev_handler(app_usbd_event_type_t event)
{
    switch (event)
    {
        case APP_USBD_EVT_DRV_SUSPEND:
            //bsp_board_led_off(LED_USB_RESUME);
            break;
        case APP_USBD_EVT_DRV_RESUME:
            //bsp_board_led_on(LED_USB_RESUME);
            break;
        case APP_USBD_EVT_STARTED:
            //bsp_board_led_on(LED_USB_START);
            break;
        case APP_USBD_EVT_STOPPED:
            UNUSED_RETURN_VALUE(fatfs_init());
            app_usbd_disable();
            //bsp_board_leds_off();
            break;
        case APP_USBD_EVT_POWER_DETECTED:
            NRF_LOG_INFO("USB power detected");

            if (!nrf_drv_usbd_is_enabled())
            {
                fatfs_uninit();
                app_usbd_enable();
            }
            break;
        case APP_USBD_EVT_POWER_REMOVED:
            NRF_LOG_INFO("USB power removed");
            app_usbd_stop();
            m_usb_connected = false;
            //memset(&m_rx, 0, sizeof(m_rx));
            break;
        case APP_USBD_EVT_POWER_READY:
            NRF_LOG_INFO("USB ready");
            app_usbd_start();
            m_usb_connected = true;
            break;
        default:
            break;
    }
}


static void usbd_thread(void * arg)
{
    ret_code_t ret;
    static const app_usbd_config_t usbd_config = {
        .ev_isr_handler = usb_new_event_isr_handler,
        .ev_state_proc  = usbd_user_ev_handler
    };
    UNUSED_PARAMETER(arg);


    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);


    //ret = app_usbd_power_events_enable();
    //APP_ERROR_CHECK(ret);

    // Set the first event to make sure that USB queue is processed after it is started
    UNUSED_RETURN_VALUE(xTaskNotifyGive(xTaskGetCurrentTaskHandle()));
    // Enter main loop.
    for (;;)
    {
        /* Waiting for event */
        UNUSED_RETURN_VALUE(ulTaskNotifyTake(pdTRUE, USB_THREAD_MAX_BLOCK_TIME));
        while (app_usbd_event_queue_process())
        {
            /* Nothing to do */
        }
    }
}

StaticTask_t task_usb_msc_tcb;
volatile TaskHandle_t usb_msc_task_handle = NULL;


int main(void)
{
    ret_code_t ret;
    bool erase_bonds;
    err_rc_t rc = RESULT_SUCCESS;

    ret_code_t err_code;
    // Initialize modules.
    log_init();
    // Initialize the async SVCI interface to bootloader before any interrupts are enabled.
    // We don't check for error in case bootloader not in place
    ret = nrf_drv_power_init(NULL);
    APP_ERROR_CHECK(ret);

    clock_init();
    nrf_drv_clock_lfclk_request(NULL);
    
    err_code = nrf_drv_gpiote_init();
    APP_ERROR_CHECK(err_code);

    spi_init();
    // Do not start any interrupt that uses system functions before system initialisation.
    // The best solution is to start the OS before any other initalisation.

#if NRF_LOG_ENABLED
    // Start execution.
    m_logger_thread = xTaskCreateStatic(logger_thread, "LOGGER", sizeof(xLoggerStack) / sizeof(xLoggerStack[0]), NULL, LOGGER_TASK_PRIORITY, xLoggerStack, &xLoggerTaskBuffer);
    if (m_logger_thread == NULL) {
        APP_ERROR_HANDLER(NRF_ERROR_NO_MEM);
    }
#endif

usb_msc_task_handle= xTaskCreateStatic(usbd_thread,"USBD",USBD_STACK_SIZE,NULL,USBD_PRIORITY,usb_msc_stack,&task_usb_msc_tcb);

 if(usb_msc_task_handle == NULL) {
            rc = RESULT_ERROR_FAILURE;
            NRF_LOG_INFO("ERROR IN TASK CREATE.");
        }
NRF_LOG_INFO("USBD BLE UART example started.");

 

    // Activate deep sleep mode.
    SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;

    memset(app_fw_version, 0, sizeof(app_fw_version));
    app_version_str(app_fw_version, sizeof(app_fw_version));



    // Configure and initialize the BLE stack.
    ble_stack_init();
      

    
    timers_init();
    

    gap_params_init();
    gatt_init();
    services_init();
    advertising_init();
    conn_params_init();
    peer_manager_init();
    application_timers_start();

    // Create a FreeRTOS task for the BLE stack.
    // The task will run advertising_start() before entering its loop.
    nrf_sdh_freertos_init(advertising_start, &erase_bonds);

    init_led_button_task(); 
   // init_psf_comm_task();       

     

     // Start FreeRTOS scheduler.
    vTaskStartScheduler();

    for (;;) {
        APP_ERROR_HANDLER(NRF_ERROR_FORBIDDEN);
    }
}

static void nrf_nvmc_write_word(uint32_t address, uint32_t value)
{
    // Enable write.
    NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen;
    __ISB();
    __DSB();

    *(uint32_t*)address = value;
    while (NRF_NVMC->READY == NVMC_READY_READY_Busy) {;}

    NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
    __ISB();
    __DSB();
}


uint32_t app_timer_cnt_get(void)
{
    return xTaskGetTickCount();
}

uint32_t app_timer_cnt_diff_compute(uint32_t   ticks_to,
                                    uint32_t   ticks_from)
{
    return ((ticks_to - ticks_from) & RTC_COUNTER_COUNTER_Msk);
}



/////////////////////////////////////////////////////////////////////////////////////
static FATFS m_filesystem;


void fatfs_mkfs(void)
{
    FRESULT ff_result;

    if (m_usb_connected)
    {
        NRF_LOG_ERROR("Unable to operate on filesystem while USB is connected");
        return;
    }

    NRF_LOG_INFO("\r\nCreating filesystem...");
     uint8_t buf[4096] = {0};
  //  ff_result = f_mkfs("", FM_FAT, 1024, buf, sizeof(buf));
   // ff_result = f_mkfs("", FM_FAT, 4096, buf, sizeof(buf));
  ff_result = f_mkfs("", FM_FAT | FM_SFD, 4096, buf, sizeof(buf));


    if (ff_result != FR_OK)
    {
        NRF_LOG_ERROR("Mkfs failed with error %d",ff_result);
        return;
    }

    NRF_LOG_INFO("Mounting volume...");
    ff_result = f_mount(&m_filesystem, "", 1);
    if (ff_result != FR_OK)
    {
        NRF_LOG_ERROR("Mount failed.");
        return;
    }

    NRF_LOG_INFO("Done");
}




static bool fatfs_init(void)
{
    FRESULT ff_result;
    DSTATUS disk_state = STA_NOINIT;

    memset(&m_filesystem, 0, sizeof(FATFS));

    // Initialize FATFS disk I/O interface by providing the block device.
    static diskio_blkdev_t drives[] =
    {
        DISKIO_BLOCKDEV_CONFIG(NRF_BLOCKDEV_BASE_ADDR(m_block_dev_spi, block_dev), NULL)
    };

    diskio_blockdev_register(drives, ARRAY_SIZE(drives));

    NRF_LOG_INFO("Initializing disk 0 (SPI)...");
    disk_state = disk_initialize(0);
    if (disk_state)
    {
        NRF_LOG_ERROR("Disk initialization failed.disk_state<%d>", disk_state);
        return false;
    }
    NRF_LOG_ERROR("disk_state <%d>", disk_state);
    NRF_LOG_INFO("Mounting volume...");
    ff_result = f_mount(&m_filesystem, "", 1);
    if (ff_result != FR_OK)
    {
        if (ff_result == FR_NO_FILESYSTEM)
        {
            NRF_LOG_ERROR("Mount failed. Filesystem not found. Please format device.");
            fatfs_mkfs();// flash is new, should execute this here once, and then it can be annotated 
        }
        else
        {
            NRF_LOG_ERROR("Mount failed: %u", ff_result);
        }
        return false;
    }

    return true;
}



static void fatfs_ls(void)
{
    DIR dir;
    FRESULT ff_result;
    FILINFO fno;

    if (m_usb_connected)
    {
        NRF_LOG_ERROR("Unable to operate on filesystem while USB is connected");
        return;
    }

    NRF_LOG_INFO("\r\nListing directory: /");
    ff_result = f_opendir(&dir, "/");
    if (ff_result != FR_OK)
    {
        NRF_LOG_ERROR("Directory listing failed: %u", ff_result);
        return;
    }

    uint32_t entries_count = 0;
    do
    {
        ff_result = f_readdir(&dir, &fno);
        if (ff_result != FR_OK)
        {
            NRF_LOG_ERROR("Directory read failed: %u", ff_result);
            return;
        }

        if (fno.fname[0])
        {
            if (fno.fattrib & AM_DIR)
            {
                NRF_LOG_RAW_INFO("   <DIR>   %s\r\n",(uint32_t)fno.fname);
            }
            else
            {
                NRF_LOG_RAW_INFO("%9lu  %s\r\n", fno.fsize, (uint32_t)fno.fname);
            }
        }

        ++entries_count;
        NRF_LOG_FLUSH();
    } while (fno.fname[0]);


    NRF_LOG_RAW_INFO("Entries count: %u\r\n", entries_count);
}




static void fatfs_file_create(void)
{
    FRESULT ff_result;
    FIL file;


    if (m_usb_connected)
    {
        NRF_LOG_ERROR("Unable to operate on filesystem while USB is connected");
        return;
    }

    NRF_LOG_RAW_INFO("Creating random file: %s ...", (uint32_t)my_filename);
    NRF_LOG_FLUSH();

    ff_result = f_open(&file, my_filename, FA_CREATE_ALWAYS | FA_WRITE);
    if (ff_result != FR_OK)
    {
        NRF_LOG_ERROR("\r\nUnable to open or create file: %u", ff_result);
        NRF_LOG_FLUSH();
        return;
    }

//write a string

    static BYTE test_string[] = "christophe\t1995\t0707\r\nsid\t1997\t1234\r\n";
    UINT data_len_written = 0;
    ff_result = f_write(&file, test_string, (UINT)strlen(test_string), &data_len_written);
    if (ff_result != FR_OK)
    {
        NRF_LOG_ERROR("\r\nUnable to write data: %u", ff_result);
        NRF_LOG_FLUSH();
        return;
    }


    ff_result = f_close(&file);
    if (ff_result != FR_OK)
    {
        NRF_LOG_ERROR("\r\nUnable to close file: %u", ff_result);
        NRF_LOG_FLUSH();
        return;
    }
    NRF_LOG_RAW_INFO("done\r\n");

}


static FRESULT my_file_open(FIL* my_file)
{
    FRESULT ff_result;
    ret_code_t err_code;

    if (g_test_open)
    {
        return FR_FILE_OPENED;
    }

    ff_result = f_open(my_file, my_filename, FA_OPEN_ALWAYS | FA_WRITE | FA_OPEN_APPEND);
    if (ff_result != FR_OK)
    {
        NRF_LOG_ERROR("\r\nUnable to open or create file: %u", ff_result);
        NRF_LOG_FLUSH();
        return ff_result;
    }

#if CLOSE_FILE_BY_TIMER
    err_code = app_timer_start(file_close_timer_id, CLOSE_INTERVAL, NULL);
    APP_ERROR_CHECK(err_code);
#endif

    g_test_open = true;

      return ff_result;
}


//static void my_file_write(void)
//{
//    FRESULT ff_result;
//    FIL file;

//    ff_result = f_write(&file, test, (UINT)strlen(test), &written);
//    if (ff_result != FR_OK)
//    {
//        NRF_LOG_ERROR("\r\nUnable to write data: %u", ff_result);
//        NRF_LOG_FLUSH();
//        return;
//    }

//}


static FRESULT my_file_close(FIL * my_file)
{
    FRESULT ff_result;

    if (g_test_open == false)
    {
        return FR_FILE_CLOSED;
       
    }

    ff_result = f_close(my_file);
    if (ff_result != FR_OK)
    {
        NRF_LOG_ERROR("\r\nUnable to close file: %u", ff_result);
        NRF_LOG_FLUSH();
        return ff_result;
    }
    NRF_LOG_RAW_INFO("done\r\n");

    g_test_open = false;
#if CLOSE_FILE_BY_TIMER
    //app_timer_stop(file_close_timer_id);
#endif
    NRF_LOG_RAW_INFO("file closed!\r\n"); 
    NRF_LOG_FLUSH();

     return ff_result;

}


static void my_write_data(void)
{

    FRESULT ff_result;
    FIL file;

    ff_result = f_open(&file, my_filename, FA_CREATE_ALWAYS | FA_WRITE);
    if (ff_result != FR_OK)
    {
        NRF_LOG_ERROR("\r\nUnable to open or create file: %u", ff_result);
        NRF_LOG_FLUSH();
        return;
    }

//write a string

#if 1
//    ff_result = f_lseek(&file, file.obj->fs.fsize));
//    if (ff_result != FR_OK)
//    {
//        NRF_LOG_ERROR("\r\nUnable to write data: %u", ff_result);
//        NRF_LOG_FLUSH();
//        return;
//    }


    static BYTE test[] = "1111\t2222\t3333\r\n4444\t5555\t6666\r\n";
    UINT written = 0;
    ff_result = f_write(&file, test, (UINT)strlen(test), &written);
    if (ff_result != FR_OK)
    {
        NRF_LOG_ERROR("\r\nUnable to write data: %u", ff_result);
        NRF_LOG_FLUSH();
        return;
    }

    ff_result = f_close(&file);
    if (ff_result != FR_OK)
    {
        NRF_LOG_ERROR("\r\nUnable to close file: %u", ff_result);
        NRF_LOG_FLUSH();
        return;
    }
    NRF_LOG_RAW_INFO("done\r\n");

}

static void fatfs_uninit(void)
{
    NRF_LOG_INFO("Un-initializing disk 0 (SPI)...");
    UNUSED_RETURN_VALUE(disk_uninitialize(0));
}
#else //USE_FATFS_SPI
#define fatfs_init()        false
#define fatfs_mkfs()        do { } while (0)
#define fatfs_ls()          do { } while (0)
#define fatfs_file_create() do { } while (0)
#define fatfs_uninit()      do { } while (0)
#endif

/**
 * @brief Class specific event handler.
 *
 * @param p_inst    Class instance.
 * @param event     Class specific event.
 */
static void msc_user_ev_handler(app_usbd_class_inst_t const * p_inst,
                                app_usbd_msc_user_event_t     event)
{
    UNUSED_PARAMETER(p_inst);
    UNUSED_PARAMETER(event);
}



static void close_file_handler(void * p_context)
{
    UNUSED_PARAMETER(p_context);
    g_idle_s++;

}



void usbd_msc_task(void)
{
    FRESULT ff_result;
    FIL file;

   

    ret_code_t ret;
 

    if (fatfs_init())
        {
              fatfs_ls();
              fatfs_file_create();
        }



    NRF_LOG_INFO("USBD MSC example started.");
    
    if (USBD_POWER_DETECTION)
    {
        ret = app_usbd_power_events_enable();
        APP_ERROR_CHECK(ret);
    }
    else
    {
        NRF_LOG_INFO("No USB power detection enabled\r\nStarting USB now");

        app_usbd_enable();
        app_usbd_start();
        m_usb_connected = true;
    }

    uint8_t write_cnt = 0;


   // memset(&m_rx, 0, sizeof(m_rx));
    NRF_LOG_INFO("New Flash to write.");

            fatfs_mkfs();

            fatfs_file_create();          
        
            fatfs_ls();

   

}

Thanks & Regards,

Snehal.

Parents Reply Children
  • I did the following changes 

    static void usbd_thread(void * arg)
    {
    
    //while(1)
    //{
    //  NRF_LOG_INFO("usbd_thread");
    //}
        ret_code_t ret;
        static const app_usbd_config_t usbd_config = {
            .ev_isr_handler = usb_new_event_isr_handler,
            .ev_state_proc  = usbd_user_ev_handler
        };
        UNUSED_PARAMETER(arg);
    
    
        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);
    
    
        //ret = app_usbd_power_events_enable();
        //APP_ERROR_CHECK(ret);
    
        // Set the first event to make sure that USB queue is processed after it is started
       // UNUSED_RETURN_VALUE(xTaskNotifyGive(xTaskGetCurrentTaskHandle()));
        // Enter main loop.
        for (;;)
        {
            /* Waiting for event */
          //  UNUSED_RETURN_VALUE(ulTaskNotifyTake(pdTRUE, USB_THREAD_MAX_BLOCK_TIME));
            while (app_usbd_event_queue_process())
            {
                /* Nothing to do */
            }
        }
    }
    
    
    
    
    
    
    
    
    void usb_new_event_isr_handler(app_usbd_internal_evt_t const * const p_event, bool queued)
    {
        BaseType_t xHigherPriorityTaskWoken = pdFALSE;
        UNUSED_PARAMETER(p_event);
        UNUSED_PARAMETER(queued);
      //  ASSERT(m_usbd_thread != NULL);
        /* Release the semaphore */
     //   vTaskNotifyGiveFromISR(m_usbd_thread, &xHigherPriorityTaskWoken);
        portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
    }
    
    

    #define configTIMER_TASK_PRIORITY ( 1 )

    #define configTIMER_TASK_STACK_DEPTH ( 1024 )

    But still getting same error. Disappointed

  • Then something else is different on your end Sneha. Unfortunately I cannot look into this before Easter holidays here in Norway. And there are no other FreeRTOS experts available during this time. I will be back after Easter. Sorry for the timing.

  • Hi Susheel, Thanks for your help but before going on for holidays can you please check my code once?? I have attached here. Requesting you to take a look at it once. 

    firmware-nrf52840.zip

Related