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

the fatfs example is work ,but dont work in my project

/**
 * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form, except as embedded into a Nordic
 *    Semiconductor ASA integrated circuit in a product or a software update for
 *    such product, must reproduce the above copyright notice, this list of
 *    conditions and the following disclaimer in the documentation and/or other
 *    materials provided with the distribution.
 *
 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * 4. This software, with or without modification, must only be used with a
 *    Nordic Semiconductor ASA integrated circuit.
 *
 * 5. Any software provided in binary form under this license must not be reverse
 *    engineered, decompiled, modified and/or disassembled.
 *
 * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
/** @file
 * @defgroup fatfs_example_main main.c
 * @{
 * @ingroup fatfs_example
 * @brief FATFS Example Application main file.
 *
 * This file contains the source code for a sample application using FAT filesystem and SD card library.
 *
 */

#include "bsp.h"
#include "diskio_blkdev.h"
#include "ff.h"
#include "nrf.h"
#include "nrf_block_dev_sdc.h"

#include "app_usbd.h"
#include "app_usbd_cdc_acm.h"
#include "app_usbd_core.h"
#include "app_usbd_serial_num.h"
#include "app_usbd_string_desc.h"
#include "nrf_drv_usbd.h"
#include "nrf_gpio.h"

#include "nrf_drv_clock.h"
#include "nrf_drv_gpiote.h"

#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"

#define SDC_SCK_PIN NRF_GPIO_PIN_MAP(1, 13)  ///< SDC serial clock (SCK) pin.
#define SDC_MOSI_PIN NRF_GPIO_PIN_MAP(1, 15) ///< SDC serial data in (DI) pin.
#define SDC_MISO_PIN NRF_GPIO_PIN_MAP(0, 2)  ///< SDC serial data out (DO) pin.
#define SDC_CS_PIN NRF_GPIO_PIN_MAP(1, 10)   ///< SDC chip select (CS) pin.

// #define BUTTON_1 NRF_GPIO_PIN_MAP(1, 6)
#define TEST_TIME_DELAY NRF_GPIO_PIN_MAP(0, 13)

#define FILE_NAME "NORDIC.TXT"
#define TEST_STRING "Hello world."

#define LED_USB_RESUME (BSP_BOARD_LED_0)
#define LED_CDC_ACM_OPEN (BSP_BOARD_LED_1)
#define LED_CDC_ACM_RX (BSP_BOARD_LED_2)
#define LED_CDC_ACM_TX (BSP_BOARD_LED_3)

#define BTN_CDC_DATA_SEND 0
#define BTN_CDC_NOTIFY_SEND 1

#ifndef USBD_POWER_DETECTION
#define USBD_POWER_DETECTION true
#endif

// UARTUI

static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const *p_inst,
                                    app_usbd_cdc_acm_user_event_t event);

#define CDC_ACM_COMM_INTERFACE 0
#define CDC_ACM_COMM_EPIN NRF_DRV_USBD_EPIN2

#define CDC_ACM_DATA_INTERFACE 1
#define CDC_ACM_DATA_EPIN NRF_DRV_USBD_EPIN1
#define CDC_ACM_DATA_EPOUT NRF_DRV_USBD_EPOUT1

#define READ_SIZE 64
static char m_rx_buffer[READ_SIZE];
static char m_tx_buffer[READ_SIZE];

static void fatfs_example();

/**
 * @brief CDC_ACM class instance
 * */
APP_USBD_CDC_ACM_GLOBAL_DEF(m_app_cdc_acm,
                            cdc_acm_user_ev_handler,
                            CDC_ACM_COMM_INTERFACE,
                            CDC_ACM_DATA_INTERFACE,
                            CDC_ACM_COMM_EPIN,
                            CDC_ACM_DATA_EPIN,
                            CDC_ACM_DATA_EPOUT,
                            APP_USBD_CDC_COMM_PROTOCOL_AT_V250);

/**
 * @brief  SDC block device definition
 * */
NRF_BLOCK_DEV_SDC_DEFINE(
    m_block_dev_sdc,
    NRF_BLOCK_DEV_SDC_CONFIG(
        SDC_SECTOR_SIZE,
        APP_SDCARD_CONFIG(SDC_MOSI_PIN, SDC_MISO_PIN, SDC_SCK_PIN, SDC_CS_PIN)),
    NFR_BLOCK_DEV_INFO_CONFIG("Nordic", "SDC", "1.00"));

static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const *p_inst,
                                    app_usbd_cdc_acm_user_event_t event)
{
    app_usbd_cdc_acm_t const *p_cdc_acm = app_usbd_cdc_acm_class_get(p_inst);

    switch (event)
    {
    case APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN:
    {
        bsp_board_led_on(LED_CDC_ACM_OPEN);

        /*Setup first transfer*/
        ret_code_t ret = app_usbd_cdc_acm_read(&m_app_cdc_acm,
                                               m_rx_buffer,
                                               READ_SIZE);
        UNUSED_VARIABLE(ret);
        break;
    }
    case APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE:
        bsp_board_led_off(LED_CDC_ACM_OPEN);
        break;
    case APP_USBD_CDC_ACM_USER_EVT_TX_DONE:
        // nrfx_gpiote_out_clear(TEST_TIME_DELAY);
        bsp_board_led_invert(LED_CDC_ACM_TX);
        break;
    case APP_USBD_CDC_ACM_USER_EVT_RX_DONE:
    {
        ret_code_t ret;
        //            NRF_LOG_INFO("Bytes waiting: %d", app_usbd_cdc_acm_bytes_stored(p_cdc_acm));
        app_usbd_cdc_acm_bytes_stored(&m_app_cdc_acm);
        do
        {
            /*Get amount of data transfered*/
            size_t size = app_usbd_cdc_acm_rx_size(&m_app_cdc_acm);
            //                NRF_LOG_INFO("RX: size: %lu char: %c", size, m_rx_buffer[0]);

            /* Fetch data until internal buffer is empty */
            ret = app_usbd_cdc_acm_read(&m_app_cdc_acm,
                                        m_rx_buffer,
                                        READ_SIZE);
        } while (ret == NRF_SUCCESS);

        memcpy(m_tx_buffer, m_rx_buffer, READ_SIZE);
        app_usbd_cdc_acm_write(&m_app_cdc_acm, m_tx_buffer, READ_SIZE); //

        bsp_board_led_invert(LED_CDC_ACM_RX);
        break;
    }
    default:
        break;
    }
}

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:
        break;
    case APP_USBD_EVT_STOPPED:
        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())
        {
            app_usbd_enable();
        }
        break;
    case APP_USBD_EVT_POWER_REMOVED:
        //            NRF_LOG_INFO("USB power removed");
        app_usbd_stop();
        break;
    case APP_USBD_EVT_POWER_READY:
        //            NRF_LOG_INFO("USB ready");
        app_usbd_start();
        break;
    default:
        break;
    }
}
/// end for USB CDC

void clocks_start(void)
{
    NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
    NRF_CLOCK->TASKS_HFCLKSTART = 1;

    while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0)
        ;
}

//-----------------------GPIO-----------------------------

static void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
    if (pin == BUTTON_1)
    {
        // bsp_board_led_invert(LED_CDC_ACM_RX);

        fatfs_example();
    }
    else
    {
    }
}

void gpio_init(void)
{
    bsp_board_init(BSP_INIT_LEDS);
    ret_code_t err_code;

    err_code = nrf_drv_gpiote_init();
    //        APP_ERROR_CHECK(err_code);

    nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(false);
    in_config.pull = NRF_GPIO_PIN_PULLUP;

    err_code = nrf_drv_gpiote_in_init(BUTTON_1, &in_config, in_pin_handler);
    APP_ERROR_CHECK(err_code);

    nrf_drv_gpiote_in_event_enable(BUTTON_1, true);
}

/**
 * @brief Function for demonstrating FAFTS usage.
 */
static FATFS fs;
static DIR dir;
static FILINFO fno;
static FIL file;
static void fatfs_init()
{

    uint32_t bytes_written;
    FRESULT ff_result;
    DSTATUS disk_state = STA_NOINIT;

    // 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_sdc, block_dev), NULL)};

    diskio_blockdev_register(drives, ARRAY_SIZE(drives));

    NRF_LOG_INFO("Initializing disk 0 (SDC)...");
    for (uint32_t retries = 3; retries && disk_state; --retries)
    {
        disk_state = disk_initialize(0);
    }
    if (disk_state)
    {
        NRF_LOG_INFO("Disk initialization failed.");

        return;
    }

    uint32_t blocks_per_mb = (1024uL * 1024uL) / m_block_dev_sdc.block_dev.p_ops->geometry(&m_block_dev_sdc.block_dev)->blk_size;
    uint32_t capacity = m_block_dev_sdc.block_dev.p_ops->geometry(&m_block_dev_sdc.block_dev)->blk_count / blocks_per_mb;
    NRF_LOG_INFO("Capacity: %d MB", capacity);

    NRF_LOG_INFO("Mounting volume...");
    ff_result = f_mount(&fs, "", 1);
    if (ff_result)
    {
        bsp_board_led_invert(1);
        NRF_LOG_INFO("Mount failed.");
        return;
    }

    NRF_LOG_INFO("\r\n Listing directory: /");
    ff_result = f_opendir(&dir, "/");
    if (ff_result)
    {
        NRF_LOG_INFO("Directory listing failed!");
        return;
    }

    do
    {
        ff_result = f_readdir(&dir, &fno);
        if (ff_result != FR_OK)
        {
            NRF_LOG_INFO("Directory read failed.");
            return;
        }

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

static void fatfs_example()
{
    uint32_t bytes_written;
    FRESULT ff_result;

    NRF_LOG_INFO("Writing to file " FILE_NAME "...");
    ff_result = f_open(&file, FILE_NAME, FA_READ | FA_WRITE | FA_OPEN_APPEND);
    if (ff_result != FR_OK)
    {
        NRF_LOG_INFO("Unable to open or create file: " FILE_NAME ".");
        sprintf(m_tx_buffer,"ff_result = %d", ff_result);
        app_usbd_cdc_acm_write(&m_app_cdc_acm, m_tx_buffer, sizeof(m_tx_buffer));
        bsp_board_led_invert(LED_CDC_ACM_TX);
        return;
    }

    ff_result = f_write(&file, TEST_STRING, sizeof(TEST_STRING) - 1, (UINT *)&bytes_written);
    if (ff_result != FR_OK)
    {
        NRF_LOG_INFO("Write failed\r\n.");
    }
    else
    {

        NRF_LOG_INFO("%d bytes written.", bytes_written);
    }

    (void)f_close(&file);
    return;
}

/**
 * @brief Function for main application entry.
 */
int main(void)
{
    static const app_usbd_config_t usbd_config = {
        .ev_state_proc = usbd_user_ev_handler};

    nrf_drv_clock_init();

    clocks_start();

    gpio_init();

    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
    NRF_LOG_DEFAULT_BACKENDS_INIT();

    NRF_LOG_INFO("FATFS example started.");

    app_usbd_serial_num_generate();
    app_usbd_init(&usbd_config);

    app_usbd_class_inst_t const *class_cdc_acm = app_usbd_cdc_acm_class_inst_get(&m_app_cdc_acm);
    app_usbd_class_append(class_cdc_acm);

    if (USBD_POWER_DETECTION)
    {
        app_usbd_power_events_enable();
    }
    else
    {
        app_usbd_enable();
        app_usbd_start();
    }

    fatfs_init();

    while (true)
    {

        __WFE();
    }
}

/** @} */
id my code ,please help me

  • The essence of the problem is that when I use CDC_ACM and SD card at the same time, I encounter the problem of SD write failure, always prompting "FR_NOT_READY", the following is my code, please help me to see. The problem of different drivers before and after is something I found by debugging myself, I don't know if it is accurate.

    /**
     * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
     *
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     *
     * 1. Redistributions of source code must retain the above copyright notice, this
     *    list of conditions and the following disclaimer.
     *
     * 2. Redistributions in binary form, except as embedded into a Nordic
     *    Semiconductor ASA integrated circuit in a product or a software update for
     *    such product, must reproduce the above copyright notice, this list of
     *    conditions and the following disclaimer in the documentation and/or other
     *    materials provided with the distribution.
     *
     * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
     *    contributors may be used to endorse or promote products derived from this
     *    software without specific prior written permission.
     *
     * 4. This software, with or without modification, must only be used with a
     *    Nordic Semiconductor ASA integrated circuit.
     *
     * 5. Any software provided in binary form under this license must not be reverse
     *    engineered, decompiled, modified and/or disassembled.
     *
     * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
     * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     */
    /** @file
     * @defgroup fatfs_example_main main.c
     * @{
     * @ingroup fatfs_example
     * @brief FATFS Example Application main file.
     *
     * This file contains the source code for a sample application using FAT filesystem and SD card library.
     *
     */
    
    #include "bsp.h"
    #include "diskio_blkdev.h"
    #include "ff.h"
    #include "nrf.h"
    #include "nrf_block_dev_sdc.h"
    
    #include "nrf_drv_power.h"
    
    #include "app_usbd.h"
    #include "app_usbd_cdc_acm.h"
    #include "app_usbd_core.h"
    #include "app_usbd_msc.h"
    #include "app_usbd_serial_num.h"
    #include "app_usbd_string_desc.h"
    #include "app_util.h"
    #include "nrf_drv_usbd.h"
    #include "nrf_gpio.h"
    
    #include "nrf_delay.h"
    
    #include "app_scheduler.h"
    #include "app_timer.h"
    #include "nrf_drv_clock.h"
    #include "nrf_drv_gpiote.h"
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    #define SDC_SCK_PIN NRF_GPIO_PIN_MAP(1, 13)  ///< SDC serial clock (SCK) pin.
    #define SDC_MOSI_PIN NRF_GPIO_PIN_MAP(1, 15) ///< SDC serial data in (DI) pin.
    #define SDC_MISO_PIN NRF_GPIO_PIN_MAP(0, 2)  ///< SDC serial data out (DO) pin.
    #define SDC_CS_PIN NRF_GPIO_PIN_MAP(1, 10)   ///< SDC chip select (CS) pin.
    
    // #define BUTTON_1 NRF_GPIO_PIN_MAP(1, 6)
    #define TEST_TIME_DELAY NRF_GPIO_PIN_MAP(0, 13)
    
    #define FILE_NAME "NORDIC.TXT"
    #define TEST_STRING "Hello world111."
    
    #define LED_USB_RESUME (BSP_BOARD_LED_0)
    #define LED_CDC_ACM_OPEN (BSP_BOARD_LED_1)
    #define LED_CDC_ACM_RX (BSP_BOARD_LED_2)
    #define LED_CDC_ACM_TX (BSP_BOARD_LED_3)
    
    #define BTN_CDC_DATA_SEND 0
    #define BTN_CDC_NOTIFY_SEND 1
    
    #ifndef USBD_POWER_DETECTION
    #define USBD_POWER_DETECTION true
    #endif
    
    // UARTUI
    
    static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const *p_inst,
                                        app_usbd_cdc_acm_user_event_t event);
    
    /**
     * @brief Mass storage class user event handler
     */
    static void msc_user_ev_handler(app_usbd_class_inst_t const *p_inst,
                                    app_usbd_msc_user_event_t event);
    
    #define CDC_ACM_COMM_INTERFACE 0
    #define CDC_ACM_COMM_EPIN NRF_DRV_USBD_EPIN2
    
    #define CDC_ACM_DATA_INTERFACE 1
    #define CDC_ACM_DATA_EPIN NRF_DRV_USBD_EPIN1
    #define CDC_ACM_DATA_EPOUT NRF_DRV_USBD_EPOUT1
    
    #define MSC_DATA_INTERFACE 2
    
    #define READ_SIZE 64
    static char m_rx_buffer[READ_SIZE];
    static char m_tx_buffer[READ_SIZE];
    
    static bool sdc_init_status = false;
    
    /**
     * @brief CDC_ACM class instance
     * */
    APP_USBD_CDC_ACM_GLOBAL_DEF(m_app_cdc_acm,
                                cdc_acm_user_ev_handler,
                                CDC_ACM_COMM_INTERFACE,
                                CDC_ACM_DATA_INTERFACE,
                                CDC_ACM_COMM_EPIN,
                                CDC_ACM_DATA_EPIN,
                                CDC_ACM_DATA_EPOUT,
                                APP_USBD_CDC_COMM_PROTOCOL_AT_V250);
    
    /**
     * @brief  SDC block device definition
     * */
    NRF_BLOCK_DEV_SDC_DEFINE(
        m_block_dev_sdc,
        NRF_BLOCK_DEV_SDC_CONFIG(
            SDC_SECTOR_SIZE,
            APP_SDCARD_CONFIG(SDC_MOSI_PIN, SDC_MISO_PIN, SDC_SCK_PIN, SDC_CS_PIN)),
        NFR_BLOCK_DEV_INFO_CONFIG("Nordic", "SDC", "1.00"));
    
    /**
     * @brief Block devices list passed to @ref APP_USBD_MSC_GLOBAL_DEF
     */
    #define BLOCKDEV_LIST() (NRF_BLOCKDEV_BASE_ADDR(m_block_dev_sdc, block_dev))
    
    #define ENDPOINT_LIST() APP_USBD_MSC_ENDPOINT_LIST(5, 5)
    
    /**
     * @brief Mass storage class work buffer size
     */
    #define MSC_WORKBUFFER_SIZE (1024)
    
    /**
     * @brief Mass storage class instance
     */
    APP_USBD_MSC_GLOBAL_DEF(m_app_msc,
                            MSC_DATA_INTERFACE,
                            msc_user_ev_handler,
                            ENDPOINT_LIST(),
                            BLOCKDEV_LIST(),
                            MSC_WORKBUFFER_SIZE);
    
    // APP_USBD_DUMMY_GLOBAL_DEF(m_app_msc_dummy, MSC_DATA_INTERFACE);
    
    /**
     * @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);
    }
    
    /**
     * @brief Timer instance
     */
    APP_TIMER_DEF(ssm_timer_id);
    
    /**
     * @brief  USB connection status
     */
    static bool m_usb_connected = false;
    
    static FATFS m_filesystem;
    
    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_sdc, block_dev), NULL)};
    
        diskio_blockdev_register(drives, ARRAY_SIZE(drives));
    
        NRF_LOG_INFO("Initializing disk 0 (SDC)...");
        disk_state = disk_initialize(0);
        if (disk_state)
        {
            NRF_LOG_ERROR("Disk initialization failed.");
            return false;
        }
    
        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.");
            }
            else
            {
                NRF_LOG_ERROR("Mount failed: %u", ff_result);
            }
            return false;
        }
    
        return true;
    }
    
    static 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...");
        static uint8_t buf[512];
        ff_result = f_mkfs("", FM_FAT32, 4096, buf, sizeof(buf));
        if (ff_result != FR_OK)
        {
            NRF_LOG_ERROR("Mkfs failed. ff_res:%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 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;
        uint32_t file_size = 0;
    
        ff_result = f_open(&file, "log_data.txt", FA_READ);
        if (ff_result != FR_OK)
        {
            NRF_LOG_ERROR("log_data.txt Does not exist\r\n");
            NRF_LOG_INFO("Creating log_data.txt");
            ff_result = f_open(&file, "log_data.txt", FA_CREATE_ALWAYS | FA_WRITE);
            if (ff_result != FR_OK)
            {
                if (!m_usb_connected)
                    NRF_LOG_ERROR("Unable to open or create file: log_data.txt");
                NRF_LOG_FLUSH();
                return;
            }
        }
    
        ff_result = f_close(&file);
        if (ff_result != FR_OK)
        {
            NRF_LOG_ERROR("Unable to close file: %u \r\n", ff_result);
            NRF_LOG_FLUSH();
            return;
        }
    
        file_size = f_size(&file);
        NRF_LOG_INFO("log_data.txt create SUCCESSFUL; file size = %d\r\n", file_size);
    }
    
    static uint32_t record_number = 0;
    
    static volatile bool write_file = false;
    static void log_data_write_handler(void *p_context)
    {
        write_file = true;
    }
    
    static void write()
    {
        int i = 0;
        char log_record[128] = {0};
        char log_record_r[128] = {0};
    
        FRESULT ff_result;
        FIL file;
        uint32_t fileSize;
        UINT BW;
    
        ff_result = f_open(&file, "log_data.txt", FA_OPEN_APPEND | FA_OPEN_ALWAYS | FA_WRITE | FA_READ);
        if (ff_result != FR_OK)
        {
            sprintf(m_tx_buffer, "ff_result:%d", ff_result);
            app_usbd_cdc_acm_write(&m_app_cdc_acm, m_tx_buffer, ARRAY_SIZE(m_tx_buffer));
            bsp_board_led_invert(LED_CDC_ACM_RX);
            if (!m_usb_connected)
            {
    
                NRF_LOG_INFO("Unable to open or create log_data.txt: %u", ff_result);
            }
            NRF_LOG_FLUSH();
            return;
        }
    
        ++record_number;
        sprintf(log_record, "1234567890123456789012345678901234567890%ld\r\n", record_number + 10000000);
    
        FSIZE_t ptr = f_tell(&file);
        i = f_printf(&file, log_record);
    
        i = f_close(&file);
        if (i != 0)
        {
            NRF_LOG_INFO("f_close != 0, %d, %d", i, record_number);
        }
    
        NRF_LOG_INFO("Wrote Data Record: %d", record_number);
    }
    
    static void fatfs_uninit(void)
    {
        NRF_LOG_INFO("Un-initializing disk 0 (QSPI)...");
        UNUSED_RETURN_VALUE(disk_uninitialize(0));
    }
    
    static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const *p_inst,
                                        app_usbd_cdc_acm_user_event_t event)
    {
        app_usbd_cdc_acm_t const *p_cdc_acm = app_usbd_cdc_acm_class_get(p_inst);
    
        switch (event)
        {
        case APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN:
        {
            bsp_board_led_on(LED_CDC_ACM_OPEN);
            m_usb_connected = true;
            /*Setup first transfer*/
            ret_code_t ret = app_usbd_cdc_acm_read(p_cdc_acm,
                                                   m_rx_buffer,
                                                   READ_SIZE);
            UNUSED_VARIABLE(ret);
            break;
        }
        case APP_USBD_CDC_ACM_USER_EVT_PORT_CLOSE:
            m_usb_connected = false;
            bsp_board_led_off(LED_CDC_ACM_OPEN);
            break;
        case APP_USBD_CDC_ACM_USER_EVT_TX_DONE:
            // nrfx_gpiote_out_clear(TEST_TIME_DELAY);
            bsp_board_led_invert(LED_CDC_ACM_TX);
            break;
        case APP_USBD_CDC_ACM_USER_EVT_RX_DONE:
        {
            ret_code_t ret;
            //            NRF_LOG_INFO("Bytes waiting: %d", app_usbd_cdc_acm_bytes_stored(p_cdc_acm));
            app_usbd_cdc_acm_bytes_stored(p_cdc_acm);
            do
            {
                /*Get amount of data transfered*/
                size_t size = app_usbd_cdc_acm_rx_size(p_cdc_acm);
                //                NRF_LOG_INFO("RX: size: %lu char: %c", size, m_rx_buffer[0]);
    
                /* Fetch data until internal buffer is empty */
                ret = app_usbd_cdc_acm_read(&m_app_cdc_acm,
                                            m_rx_buffer,
                                            READ_SIZE);
            } while (ret == NRF_SUCCESS);
    
            memcpy(m_tx_buffer, m_rx_buffer, READ_SIZE);
            app_usbd_cdc_acm_write(&m_app_cdc_acm, m_tx_buffer, READ_SIZE); //
    
            bsp_board_led_invert(LED_CDC_ACM_RX);
            break;
        }
        default:
            break;
        }
    }
    
    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:
            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;
            break;
        case APP_USBD_EVT_POWER_READY:
            //            NRF_LOG_INFO("USB ready");
            app_usbd_start();
            m_usb_connected = true;
            break;
        default:
            break;
        }
    }
    /// end for USB CDC
    
    void clocks_start(void)
    {
        NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
        NRF_CLOCK->TASKS_HFCLKSTART = 1;
    
        while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0)
            ;
    }
    
    //-----------------------GPIO-----------------------------
    
    static void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
    {
        if (pin == BUTTON_1)
        {
            
            write();
        }
        else
        {
        }
    }
    
    void gpio_init(void)
    {
        bsp_board_init(BSP_INIT_LEDS);
        ret_code_t err_code;
    
        err_code = nrf_drv_gpiote_init();
        //        APP_ERROR_CHECK(err_code);
    
        nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_HITOLO(false);
        in_config.pull = NRF_GPIO_PIN_PULLUP;
    
        err_code = nrf_drv_gpiote_in_init(BUTTON_1, &in_config, in_pin_handler);
        APP_ERROR_CHECK(err_code);
    
        nrf_drv_gpiote_in_event_enable(BUTTON_1, true);
    }
    
    /**
     * @brief Function for main application entry.
     */
    int main(void)
    {
        static const app_usbd_config_t usbd_config = {
            .ev_state_proc = usbd_user_ev_handler};
    
        // APP_SCHED_INIT(32, 20);
    
        nrf_drv_clock_init();
        nrf_drv_clock_lfclk_request(NULL); // for HF 32MHz external X-tal
    
        clocks_start();
    
        gpio_init();
        app_timer_init();
        app_timer_create(&ssm_timer_id,
                         APP_TIMER_MODE_REPEATED,
                         log_data_write_handler);
    
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    
        NRF_LOG_INFO("FATFS example started.");
    
        if (fatfs_init())
        {
    
            fatfs_ls();
            fatfs_file_create();
        }
    
        app_usbd_serial_num_generate();
        app_usbd_init(&usbd_config);
    
        app_usbd_class_inst_t const *class_inst_msc = app_usbd_msc_class_inst_get(&m_app_msc);
        app_usbd_class_append(class_inst_msc);
        app_usbd_class_inst_t const *class_cdc_acm = app_usbd_cdc_acm_class_inst_get(&m_app_cdc_acm);
        app_usbd_class_append(class_cdc_acm);
    
        if (USBD_POWER_DETECTION)
        {
            app_usbd_power_events_enable();
        }
        else
        {
            app_usbd_enable();
            app_usbd_start();
            m_usb_connected = true;
        }
    
        app_timer_start(ssm_timer_id, APP_TIMER_TICKS(1000), NULL);
    
        while (true)
        {
            while (app_usbd_event_queue_process())
            {
                // app_sched_execute();
            }
            if (write_file)
            {
                write_file = false;
                write();
            }
            __WFI();
        }
    }
    
    /** @} */
    

  • If I don't use the CDC_ACM, there is no problem with SD card storage.

  • I want to know whether CDC_ACM and fatfs can be used at the same time?

  • Thank you for the update. I don't think there should be any trouble with the block device in your example. Can you confirm which function it is that returns FR_NOT_READY. I assume it is f_mount(), please let me know if it isn't. The FR_NOT_READY points to the disk isfailing to initialize due to "no medium" or a hardfault for some reason.

    From looking at your code, I'm not able to see where the issue is I'm afraid, so I will need some more details. Do the functions you've added to one example conflict with the priority level of the other example perhaps? What priority levels are you running the USB and filesystem functions on?

    Best regards,

    Simon

  • The FR_NOT_READY is returned by f_open();

    I also think it is a resource conflict problem, I did not set any priority, that is to say, I'm using the default priority, this will affect the interrupt?

    The usb priority is 6 and the spi priority is 6.

    And I set the usb priority 5 ,the problem is still.

Related