参考无协议栈例程目录下nRF5_SDK_17.0.2_d674dde\examples\peripheral\usbd_msc的工程
移植到S340工程下需要做以下步聚
- 在sdk_config.h中加入以下配置
// POWER_ENABLED菜单
// NRFX_POWER_ENABLED - nrfx_power - POWER peripheral driver
//==========================================================
#ifndef NRFX_POWER_ENABLED
#define NRFX_POWER_ENABLED 1
#endif
// NRFX_POWER_CONFIG_IRQ_PRIORITY - Interrupt priority
// 0 (highest)
// 1
// 2
// 3
// 4
// 5
// 6
// 7
#ifndef NRFX_POWER_CONFIG_IRQ_PRIORITY
#define NRFX_POWER_CONFIG_IRQ_PRIORITY 6
#endif
// NRFX_POWER_CONFIG_DEFAULT_DCDCEN - The default configuration of main DCDC regulator
// This settings means only that components for DCDC regulator are installed and it can be enabled.
#ifndef NRFX_POWER_CONFIG_DEFAULT_DCDCEN
#define NRFX_POWER_CONFIG_DEFAULT_DCDCEN 0
#endif
// NRFX_POWER_CONFIG_DEFAULT_DCDCENHV - The default configuration of High Voltage DCDC regulator
// This settings means only that components for DCDC regulator are installed and it can be enabled.
#ifndef NRFX_POWER_CONFIG_DEFAULT_DCDCENHV
#define NRFX_POWER_CONFIG_DEFAULT_DCDCENHV 0
#endif
//
// POWER_ENABLED - nrf_drv_power - POWER peripheral driver - legacy layer
//==========================================================
#ifndef POWER_ENABLED
#define POWER_ENABLED 1
#endif
// POWER_CONFIG_IRQ_PRIORITY - Interrupt priority
// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
// 0 (highest)
// 1
// 2
// 3
// 4
// 5
// 6
// 7
#ifndef POWER_CONFIG_IRQ_PRIORITY
#define POWER_CONFIG_IRQ_PRIORITY 6
#endif
// POWER_CONFIG_DEFAULT_DCDCEN - The default configuration of main DCDC regulator
// This settings means only that components for DCDC regulator are installed and it can be enabled.
#ifndef POWER_CONFIG_DEFAULT_DCDCEN
#define POWER_CONFIG_DEFAULT_DCDCEN 0
#endif
// POWER_CONFIG_DEFAULT_DCDCENHV - The default configuration of High Voltage DCDC regulator
// This settings means only that components for DCDC regulator are installed and it can be enabled.
#ifndef POWER_CONFIG_DEFAULT_DCDCENHV
#define POWER_CONFIG_DEFAULT_DCDCENHV 0
#endif
//
//
// QSPI菜单配置
// NRF_BLOCK_DEV_EMPTY_ENABLED - nrf_block_dev_empty - Empty block device
#ifndef NRF_BLOCK_DEV_EMPTY_ENABLED
#define NRF_BLOCK_DEV_EMPTY_ENABLED 1
#endif
// NRF_BLOCK_DEV_QSPI_ENABLED - nrf_block_dev_qspi - QSPI block device
#ifndef NRF_BLOCK_DEV_QSPI_ENABLED
#define NRF_BLOCK_DEV_QSPI_ENABLED 1
#endif
// NRF_BLOCK_DEV_RAM_ENABLED - nrf_block_dev_ram - RAM block device
#ifndef NRF_BLOCK_DEV_RAM_ENABLED
#define NRF_BLOCK_DEV_RAM_ENABLED 1
#endif
// NRF_BLOCK_DEV_QSPI_CONFIG_LOG_ENABLED - Enables logging in the module.
//==========================================================
#ifndef NRF_BLOCK_DEV_QSPI_CONFIG_LOG_ENABLED
#define NRF_BLOCK_DEV_QSPI_CONFIG_LOG_ENABLED 1
#endif
// NRF_BLOCK_DEV_QSPI_CONFIG_LOG_LEVEL - Default Severity level
// Off
// Error
// Warning
// Info
// Debug
#ifndef NRF_BLOCK_DEV_QSPI_CONFIG_LOG_LEVEL
#define NRF_BLOCK_DEV_QSPI_CONFIG_LOG_LEVEL 3
#endif
// NRF_BLOCK_DEV_QSPI_CONFIG_LOG_INIT_FILTER_LEVEL - Initial severity level if dynamic filtering is enabled
// Off
// Error
// Warning
// Info
// Debug
#ifndef NRF_BLOCK_DEV_QSPI_CONFIG_LOG_INIT_FILTER_LEVEL
#define NRF_BLOCK_DEV_QSPI_CONFIG_LOG_INIT_FILTER_LEVEL 3
#endif
// NRF_BLOCK_DEV_QSPI_CONFIG_INFO_COLOR - ANSI escape code prefix.
// Default
// Black
// Red
// Green
// Yellow
// Blue
// Magenta
// Cyan
// White
#ifndef NRF_BLOCK_DEV_QSPI_CONFIG_INFO_COLOR
#define NRF_BLOCK_DEV_QSPI_CONFIG_INFO_COLOR 0
#endif
// NRF_BLOCK_DEV_QSPI_CONFIG_DEBUG_COLOR - ANSI escape code prefix.
// Default
// Black
// Red
// Green
// Yellow
// Blue
// Magenta
// Cyan
// White
#ifndef NRF_BLOCK_DEV_QSPI_CONFIG_DEBUG_COLOR
#define NRF_BLOCK_DEV_QSPI_CONFIG_DEBUG_COLOR 0
#endif
//
// NRFX_QSPI_ENABLED - nrfx_qspi - QSPI peripheral driver
//==========================================================
#ifndef NRFX_QSPI_ENABLED
#define NRFX_QSPI_ENABLED 1
#endif
// NRFX_QSPI_CONFIG_SCK_DELAY - tSHSL, tWHSL and tSHWL in number of 16 MHz periods (62.5 ns).
#ifndef NRFX_QSPI_CONFIG_SCK_DELAY
#define NRFX_QSPI_CONFIG_SCK_DELAY 1
#endif
// NRFX_QSPI_CONFIG_XIP_OFFSET - Address offset in the external memory for Execute in Place operation.
#ifndef NRFX_QSPI_CONFIG_XIP_OFFSET
#define NRFX_QSPI_CONFIG_XIP_OFFSET 0
#endif
// NRFX_QSPI_CONFIG_READOC - Number of data lines and opcode used for reading.
// FastRead
// Read2O
// Read2IO
// Read4O
// Read4IO
#ifndef NRFX_QSPI_CONFIG_READOC
#define NRFX_QSPI_CONFIG_READOC 0
#endif
// NRFX_QSPI_CONFIG_WRITEOC - Number of data lines and opcode used for writing.
// PP
// PP2O
// PP4O
// PP4IO
#ifndef NRFX_QSPI_CONFIG_WRITEOC
#define NRFX_QSPI_CONFIG_WRITEOC 0
#endif
// NRFX_QSPI_CONFIG_ADDRMODE - Addressing mode.
// 24bit
// 32bit
#ifndef NRFX_QSPI_CONFIG_ADDRMODE
#define NRFX_QSPI_CONFIG_ADDRMODE 0
#endif
// NRFX_QSPI_CONFIG_MODE - SPI mode.
// Mode 0
// Mode 1
#ifndef NRFX_QSPI_CONFIG_MODE
#define NRFX_QSPI_CONFIG_MODE 0
#endif
// NRFX_QSPI_CONFIG_FREQUENCY - Frequency divider.
// 32MHz/1
// 32MHz/2
// 32MHz/3
// 32MHz/4
// 32MHz/5
// 32MHz/6
// 32MHz/7
// 32MHz/8
// 32MHz/9
// 32MHz/10
// 32MHz/11
// 32MHz/12
// 32MHz/13
// 32MHz/14
// 32MHz/15
// 32MHz/16
#ifndef NRFX_QSPI_CONFIG_FREQUENCY
#define NRFX_QSPI_CONFIG_FREQUENCY 0
#endif
// NRFX_QSPI_PIN_SCK - SCK pin value.
#ifndef NRFX_QSPI_PIN_SCK
#define NRFX_QSPI_PIN_SCK 29
#endif
// NRFX_QSPI_PIN_CSN - CSN pin value.
#ifndef NRFX_QSPI_PIN_CSN
#define NRFX_QSPI_PIN_CSN 2
#endif
// NRFX_QSPI_PIN_IO0 - IO0 pin value.
#ifndef NRFX_QSPI_PIN_IO0
#define NRFX_QSPI_PIN_IO0 30
#endif
// NRFX_QSPI_PIN_IO1 - IO1 pin value.
#ifndef NRFX_QSPI_PIN_IO1
#define NRFX_QSPI_PIN_IO1 3
#endif
// NRFX_QSPI_PIN_IO2 - IO2 pin value.
#ifndef NRFX_QSPI_PIN_IO2
#define NRFX_QSPI_PIN_IO2 47
#endif
// NRFX_QSPI_PIN_IO3 - IO3 pin value.
#ifndef NRFX_QSPI_PIN_IO3
#define NRFX_QSPI_PIN_IO3 28
#endif
// NRFX_QSPI_CONFIG_IRQ_PRIORITY - Interrupt priority
// 0 (highest)
// 1
// 2
// 3
// 4
// 5
// 6
// 7
#ifndef NRFX_QSPI_CONFIG_IRQ_PRIORITY
#define NRFX_QSPI_CONFIG_IRQ_PRIORITY 6
#endif
//
// QSPI_ENABLED - nrf_drv_qspi - QSPI peripheral driver - legacy layer
//==========================================================
#ifndef QSPI_ENABLED
#define QSPI_ENABLED 1
#endif
// QSPI_CONFIG_SCK_DELAY - tSHSL, tWHSL and tSHWL in number of 16 MHz periods (62.5 ns).
#ifndef QSPI_CONFIG_SCK_DELAY
#define QSPI_CONFIG_SCK_DELAY 1
#endif
// QSPI_CONFIG_XIP_OFFSET - Address offset in the external memory for Execute in Place operation.
#ifndef QSPI_CONFIG_XIP_OFFSET
#define QSPI_CONFIG_XIP_OFFSET 0
#endif
// QSPI_CONFIG_READOC - Number of data lines and opcode used for reading.
// FastRead
// Read2O
// Read2IO
// Read4O
// Read4IO
#ifndef QSPI_CONFIG_READOC
#define QSPI_CONFIG_READOC 0
#endif
// QSPI_CONFIG_WRITEOC - Number of data lines and opcode used for writing.
// PP
// PP2O
// PP4O
// PP4IO
#ifndef QSPI_CONFIG_WRITEOC
#define QSPI_CONFIG_WRITEOC 0
#endif
// QSPI_CONFIG_ADDRMODE - Addressing mode.
// 24bit
// 32bit
#ifndef QSPI_CONFIG_ADDRMODE
#define QSPI_CONFIG_ADDRMODE 0
#endif
// QSPI_CONFIG_MODE - SPI mode.
// Mode 0
// Mode 1
#ifndef QSPI_CONFIG_MODE
#define QSPI_CONFIG_MODE 0
#endif
// QSPI_CONFIG_FREQUENCY - Frequency divider.
// 32MHz/1
// 32MHz/2
// 32MHz/3
// 32MHz/4
// 32MHz/5
// 32MHz/6
// 32MHz/7
// 32MHz/8
// 32MHz/9
// 32MHz/10
// 32MHz/11
// 32MHz/12
// 32MHz/13
// 32MHz/14
// 32MHz/15
// 32MHz/16
#ifndef QSPI_CONFIG_FREQUENCY
#define QSPI_CONFIG_FREQUENCY 0
#endif
// QSPI_PIN_SCK - SCK pin value.
#ifndef QSPI_PIN_SCK
#define QSPI_PIN_SCK 29
#endif
// QSPI_PIN_CSN - CSN pin value.
#ifndef QSPI_PIN_CSN
#define QSPI_PIN_CSN 2
#endif
// QSPI_PIN_IO0 - IO0 pin value.
#ifndef QSPI_PIN_IO0
#define QSPI_PIN_IO0 30
#endif
// QSPI_PIN_IO1 - IO1 pin value.
#ifndef QSPI_PIN_IO1
#define QSPI_PIN_IO1 3
#endif
// QSPI_PIN_IO2 - IO2 pin value.
#ifndef QSPI_PIN_IO2
#define QSPI_PIN_IO2 47
#endif
// QSPI_PIN_IO3 - IO3 pin value.
#ifndef QSPI_PIN_IO3
#define QSPI_PIN_IO3 28
#endif
// QSPI_CONFIG_IRQ_PRIORITY - Interrupt priority
// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
// 0 (highest)
// 1
// 2
// 3
// 4
// 5
// 6
// 7
#ifndef QSPI_CONFIG_IRQ_PRIORITY
#define QSPI_CONFIG_IRQ_PRIORITY 6
#endif
//
//
// USB菜单配置
// NRFX_USBD_ENABLED - nrfx_usbd - USBD peripheral driver
//==========================================================
#ifndef NRFX_USBD_ENABLED
#define NRFX_USBD_ENABLED 1
#endif
// NRFX_USBD_CONFIG_IRQ_PRIORITY - Interrupt priority
// 0 (highest)
// 1
// 2
// 3
// 4
// 5
// 6
// 7
#ifndef NRFX_USBD_CONFIG_IRQ_PRIORITY
#define NRFX_USBD_CONFIG_IRQ_PRIORITY 6
#endif
// NRFX_USBD_CONFIG_DMASCHEDULER_MODE - USBD DMA scheduler working scheme
// Prioritized access
// Round Robin
#ifndef NRFX_USBD_CONFIG_DMASCHEDULER_MODE
#define NRFX_USBD_CONFIG_DMASCHEDULER_MODE 0
#endif
// NRFX_USBD_CONFIG_DMASCHEDULER_ISO_BOOST - Give priority to isochronous transfers
// This option gives priority to isochronous transfers.
// Enabling it assures that isochronous transfers are always processed,
// even if multiple other transfers are pending.
// Isochronous endpoints are prioritized before the usbd_dma_scheduler_algorithm
// function is called, so the option is independent of the algorithm chosen.
#ifndef NRFX_USBD_CONFIG_DMASCHEDULER_ISO_BOOST
#define NRFX_USBD_CONFIG_DMASCHEDULER_ISO_BOOST 1
#endif
// NRFX_USBD_CONFIG_ISO_IN_ZLP - Respond to an IN token on ISO IN endpoint with ZLP when no data is ready
// If set, ISO IN endpoint will respond to an IN token with ZLP when no data is ready to be sent.
// Else, there will be no response.
#ifndef NRFX_USBD_CONFIG_ISO_IN_ZLP
#define NRFX_USBD_CONFIG_ISO_IN_ZLP 0
#endif
// NRFX_USBD_USE_WORKAROUND_FOR_ANOMALY_211 - Use workaround for anomaly 211
// If set, workaround for anomaly 211 will be enabled.
// Anomaly 211 - Device remains in SUSPEND too long when host resumes
// bus activity (sending SOF packets) without a RESUME condition.
#ifndef NRFX_USBD_USE_WORKAROUND_FOR_ANOMALY_211
#define NRFX_USBD_USE_WORKAROUND_FOR_ANOMALY_211 0
#endif
//
// USBD_ENABLED - nrf_drv_usbd - Software Component
//==========================================================
#ifndef USBD_ENABLED
#define USBD_ENABLED 1
#endif
// USBD_CONFIG_IRQ_PRIORITY - Interrupt priority
// Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
// 0 (highest)
// 1
// 2
// 3
// 4
// 5
// 6
// 7
#ifndef USBD_CONFIG_IRQ_PRIORITY
#define USBD_CONFIG_IRQ_PRIORITY 6
#endif
// USBD_CONFIG_DMASCHEDULER_MODE - USBD SMA scheduler working scheme
// Prioritized access
// Round Robin
#ifndef USBD_CONFIG_DMASCHEDULER_MODE
#define USBD_CONFIG_DMASCHEDULER_MODE 0
#endif
// USBD_CONFIG_DMASCHEDULER_ISO_BOOST - Give priority to isochronous transfers
// This option gives priority to isochronous transfers.
// Enabling it assures that isochronous transfers are always processed,
// even if multiple other transfers are pending.
// Isochronous endpoints are prioritized before the usbd_dma_scheduler_algorithm
// function is called, so the option is independent of the algorithm chosen.
#ifndef USBD_CONFIG_DMASCHEDULER_ISO_BOOST
#define USBD_CONFIG_DMASCHEDULER_ISO_BOOST 1
#endif
// USBD_CONFIG_ISO_IN_ZLP - Respond to an IN token on ISO IN endpoint with ZLP when no data is ready
// If set, ISO IN endpoint will respond to an IN token with ZLP when no data is ready to be sent.
// Else, there will be no response.
// NOTE: This option does not work on Engineering A chip.
#ifndef USBD_CONFIG_ISO_IN_ZLP
#define USBD_CONFIG_ISO_IN_ZLP 0
#endif
//
// APP_USBD_ENABLED - app_usbd - USB Device library
//==========================================================
#ifndef APP_USBD_ENABLED
#define APP_USBD_ENABLED 1
#endif
// APP_USBD_VID - Vendor ID.
// Note: This value is not editable in Configuration Wizard.
// Vendor ID ordered from USB IF: http://www.usb.org/developers/vendor/
#ifndef APP_USBD_VID
#define APP_USBD_VID 0x1915
#endif
// APP_USBD_PID - Product ID.
// Note: This value is not editable in Configuration Wizard.
// Selected Product ID
#ifndef APP_USBD_PID
#define APP_USBD_PID 0x520D
#endif
// APP_USBD_DEVICE_VER_MAJOR - Major device version
// Major device version, will be converted automatically to BCD notation. Use just decimal values.
#ifndef APP_USBD_DEVICE_VER_MAJOR
#define APP_USBD_DEVICE_VER_MAJOR 1
#endif
// APP_USBD_DEVICE_VER_MINOR - Minor device version
// Minor device version, will be converted automatically to BCD notation. Use just decimal values.
#ifndef APP_USBD_DEVICE_VER_MINOR
#define APP_USBD_DEVICE_VER_MINOR 0
#endif
// APP_USBD_DEVICE_VER_SUB - Sub-minor device version
// Sub-minor device version, will be converted automatically to BCD notation. Use just decimal values.
#ifndef APP_USBD_DEVICE_VER_SUB
#define APP_USBD_DEVICE_VER_SUB 0
#endif
// APP_USBD_CONFIG_SELF_POWERED - Self-powered device, as opposed to bus-powered.
#ifndef APP_USBD_CONFIG_SELF_POWERED
#define APP_USBD_CONFIG_SELF_POWERED 1
#endif
// APP_USBD_CONFIG_MAX_POWER - MaxPower field in configuration descriptor in milliamps.
#ifndef APP_USBD_CONFIG_MAX_POWER
#define APP_USBD_CONFIG_MAX_POWER 100
#endif
// APP_USBD_CONFIG_POWER_EVENTS_PROCESS - Process power events.
// Enable processing power events in USB event handler.
#ifndef APP_USBD_CONFIG_POWER_EVENTS_PROCESS
#define APP_USBD_CONFIG_POWER_EVENTS_PROCESS 1
#endif
// APP_USBD_CONFIG_EVENT_QUEUE_ENABLE - Enable event queue.
// This is the default configuration when all the events are placed into internal queue.
// Disable it when an external queue is used like app_scheduler or if you wish to process all events inside interrupts.
// Processing all events from the interrupt level adds requirement not to call any functions that modifies the USBD library state from the context higher than USB interrupt context.
// Functions that modify USBD state are functions for sleep, wakeup, start, stop, enable, and disable.
//==========================================================
#ifndef APP_USBD_CONFIG_EVENT_QUEUE_ENABLE
#define APP_USBD_CONFIG_EVENT_QUEUE_ENABLE 1
#endif
// APP_USBD_CONFIG_EVENT_QUEUE_SIZE - The size of the event queue.
// The size of the queue for the events that would be processed in the main loop.
#ifndef APP_USBD_CONFIG_EVENT_QUEUE_SIZE
#define APP_USBD_CONFIG_EVENT_QUEUE_SIZE 32
#endif
// APP_USBD_CONFIG_SOF_HANDLING_MODE - Change SOF events handling mode.
// Normal queue - SOF events are pushed normally into the event queue.
// Compress queue - SOF events are counted and binded with other events or executed when the queue is empty.
// This prevents the queue from filling up with SOF events.
// Interrupt - SOF events are processed in interrupt.
// Normal queue
// Compress queue
// Interrupt
#ifndef APP_USBD_CONFIG_SOF_HANDLING_MODE
#define APP_USBD_CONFIG_SOF_HANDLING_MODE 1
#endif
//
// APP_USBD_CONFIG_SOF_TIMESTAMP_PROVIDE - Provide a function that generates timestamps for logs based on the current SOF.
// The function app_usbd_sof_timestamp_get is implemented if the logger is enabled.
// Use it when initializing the logger.
// SOF processing is always enabled when this configuration parameter is active.
// Note: This option is configured outside of APP_USBD_CONFIG_LOG_ENABLED.
// This means that it works even if the logging in this very module is disabled.
#ifndef APP_USBD_CONFIG_SOF_TIMESTAMP_PROVIDE
#define APP_USBD_CONFIG_SOF_TIMESTAMP_PROVIDE 1
#endif
// APP_USBD_CONFIG_DESC_STRING_SIZE - Maximum size of the NULL-terminated string of the string descriptor.
// 31 characters can be stored in the internal USB buffer used for transfers.
// Any value higher than 31 creates an additional buffer just for descriptor strings.
#ifndef APP_USBD_CONFIG_DESC_STRING_SIZE
#define APP_USBD_CONFIG_DESC_STRING_SIZE 31
#endif
// APP_USBD_CONFIG_DESC_STRING_UTF_ENABLED - Enable UTF8 conversion.
// Enable UTF8-encoded characters. In normal processing, only ASCII characters are available.
#ifndef APP_USBD_CONFIG_DESC_STRING_UTF_ENABLED
#define APP_USBD_CONFIG_DESC_STRING_UTF_ENABLED 0
#endif
// APP_USBD_STRINGS_LANGIDS - Supported languages identifiers.
// Note: This value is not editable in Configuration Wizard.
// Comma-separated list of supported languages.
#ifndef APP_USBD_STRINGS_LANGIDS
#define APP_USBD_STRINGS_LANGIDS APP_USBD_LANG_AND_SUBLANG(APP_USBD_LANG_ENGLISH, APP_USBD_SUBLANG_ENGLISH_US)
#endif
// APP_USBD_STRING_ID_MANUFACTURER - Define manufacturer string ID.
// Setting ID to 0 disables the string.
//==========================================================
#ifndef APP_USBD_STRING_ID_MANUFACTURER
#define APP_USBD_STRING_ID_MANUFACTURER 1
#endif
// APP_USBD_STRINGS_MANUFACTURER_EXTERN - Define whether @ref APP_USBD_STRINGS_MANUFACTURER is created by macro or declared as a global variable.
#ifndef APP_USBD_STRINGS_MANUFACTURER_EXTERN
#define APP_USBD_STRINGS_MANUFACTURER_EXTERN 0
#endif
// APP_USBD_STRINGS_MANUFACTURER - String descriptor for the manufacturer name.
// Note: This value is not editable in Configuration Wizard.
// Comma-separated list of manufacturer names for each defined language.
// Use @ref APP_USBD_STRING_DESC macro to create string descriptor from a NULL-terminated string.
// Use @ref APP_USBD_STRING_RAW8_DESC macro to create string descriptor from comma-separated uint8_t values.
// Use @ref APP_USBD_STRING_RAW16_DESC macro to create string descriptor from comma-separated uint16_t values.
// Alternatively, configure the macro to point to any internal variable pointer that already contains the descriptor.
// Setting string to NULL disables that string.
// The order of manufacturer names must be the same like in @ref APP_USBD_STRINGS_LANGIDS.
#ifndef APP_USBD_STRINGS_MANUFACTURER
#define APP_USBD_STRINGS_MANUFACTURER APP_USBD_STRING_DESC("Nordic Semiconductor")
#endif
//
// APP_USBD_STRING_ID_PRODUCT - Define product string ID.
// Setting ID to 0 disables the string.
//==========================================================
#ifndef APP_USBD_STRING_ID_PRODUCT
#define APP_USBD_STRING_ID_PRODUCT 2
#endif
// APP_USBD_STRINGS_PRODUCT_EXTERN - Define whether @ref APP_USBD_STRINGS_PRODUCT is created by macro or declared as a global variable.
#ifndef APP_USBD_STRINGS_PRODUCT_EXTERN
#define APP_USBD_STRINGS_PRODUCT_EXTERN 0
#endif
// APP_USBD_STRINGS_PRODUCT - String descriptor for the product name.
// Note: This value is not editable in Configuration Wizard.
// List of product names that is defined the same way like in @ref APP_USBD_STRINGS_MANUFACTURER.
#ifndef APP_USBD_STRINGS_PRODUCT
#define APP_USBD_STRINGS_PRODUCT APP_USBD_STRING_DESC("nRF52 USB MSC Demo")
#endif
//
// APP_USBD_STRING_ID_SERIAL - Define serial number string ID.
// Setting ID to 0 disables the string.
//==========================================================
#ifndef APP_USBD_STRING_ID_SERIAL
#define APP_USBD_STRING_ID_SERIAL 3
#endif
// APP_USBD_STRING_SERIAL_EXTERN - Define whether @ref APP_USBD_STRING_SERIAL is created by macro or declared as a global variable.
#ifndef APP_USBD_STRING_SERIAL_EXTERN
#define APP_USBD_STRING_SERIAL_EXTERN 1
#endif
// APP_USBD_STRING_SERIAL - String descriptor for the serial number.
// Note: This value is not editable in Configuration Wizard.
// Serial number that is defined the same way like in @ref APP_USBD_STRINGS_MANUFACTURER.
#ifndef APP_USBD_STRING_SERIAL
#define APP_USBD_STRING_SERIAL g_extern_serial_number
#endif
//
// APP_USBD_STRING_ID_CONFIGURATION - Define configuration string ID.
// Setting ID to 0 disables the string.
//==========================================================
#ifndef APP_USBD_STRING_ID_CONFIGURATION
#define APP_USBD_STRING_ID_CONFIGURATION 4
#endif
// APP_USBD_STRING_CONFIGURATION_EXTERN - Define whether @ref APP_USBD_STRINGS_CONFIGURATION is created by macro or declared as global variable.
#ifndef APP_USBD_STRING_CONFIGURATION_EXTERN
#define APP_USBD_STRING_CONFIGURATION_EXTERN 0
#endif
// APP_USBD_STRINGS_CONFIGURATION - String descriptor for the device configuration.
// Note: This value is not editable in Configuration Wizard.
// Configuration string that is defined the same way like in @ref APP_USBD_STRINGS_MANUFACTURER.
#ifndef APP_USBD_STRINGS_CONFIGURATION
#define APP_USBD_STRINGS_CONFIGURATION APP_USBD_STRING_DESC("Default configuration")
#endif
//
// APP_USBD_STRINGS_USER - Default values for user strings.
// Note: This value is not editable in Configuration Wizard.
// This value stores all application specific user strings with the default initialization.
// The setup is done by X-macros.
// Expected macro parameters:
// @code
// X(mnemonic, [=str_idx], ...)
// @endcode
// - @c mnemonic: Mnemonic of the string descriptor that would be added to
// @ref app_usbd_string_desc_idx_t enumerator.
// - @c str_idx : String index value, can be set or left empty.
// For example, WinUSB driver requires descriptor to be present on 0xEE index.
// Then use X(USBD_STRING_WINUSB, =0xEE, (APP_USBD_STRING_DESC(...)))
// - @c ... : List of string descriptors for each defined language.
#ifndef APP_USBD_STRINGS_USER
#define APP_USBD_STRINGS_USER X(APP_USER_1, , APP_USBD_STRING_DESC("User 1"))
#endif
//
// APP_USBD_MSC_ENABLED - app_usbd_msc - USB MSC class
#ifndef APP_USBD_MSC_ENABLED
#define APP_USBD_MSC_ENABLED 1
#endif
//
- 加入以下文件到工程
- sdk_config.h中修改QSPI引脚及频率为32MHz
- nrf_serial_flash_params.c中修改flash的ID及容量,根据flash的规格描述来修改,以下为0xA1, 0x28, 0x18的ID及16MB容量的flash
static const nrf_serial_flash_params_t m_sflash_params[] = {
{ /*MXIC MX25R6435F*/
.read_id = { 0xA1, 0x28, 0x18 },
.capabilities = 0x00,
.size = 16 * 1024 * 1024,
.erase_size = 4 * 1024,
.program_size = 256,
}
};
- U盘函数文件
#ifndef __BSP_USBD_CORE_H
#define __BSP_USBD_CORE_H
#include "nrf_drv_usbd.h"
#include "ff.h"
#include "diskio_blkdev.h"
#include "app_usbd.h"
#include "app_usbd_core.h"
#include "app_usbd_string_desc.h"
#include "app_usbd_msc.h"
#include "nrf_block_dev_qspi.h"
#include "nrf_drv_clock.h"
#include "nrf_drv_power.h"
#include "app_usbd_serial_num.h"
#ifdef __cplusplus
extern "C" {
#endif
void usbd_evt_process(void);
void usbd_initialization(void);
#ifdef __cplusplus
}
#endif
#endif
#include "BSP_USBD_core.h"
#include "nrf_delay.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#define NRF_LOG_MODULE_NAME usbd_core
#define NRF_LOG_LEVEL 3
#define NRF_LOG_INFO_COLOR 4
#define NRF_LOG_DEBUG_COLOR 3
#include "nrf_log.h"
NRF_LOG_MODULE_REGISTER();
/**
* @brief Enable power USB detection
*
* Configure if example supports USB port connection
*/
#ifndef USBD_POWER_DETECTION
#define USBD_POWER_DETECTION true
#endif
/**
* @brief FatFS for QPSI enable/disable
*/
#define USE_FATFS_QSPI 1
/**
* @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);
/**
* @brief QSPI block device definition
*/
NRF_BLOCK_DEV_QSPI_DEFINE(
m_block_dev_qspi,
NRF_BLOCK_DEV_QSPI_CONFIG(
512,
NRF_BLOCK_DEV_QSPI_FLAG_CACHE_WRITEBACK,
NRF_DRV_QSPI_DEFAULT_CONFIG
),
NFR_BLOCK_DEV_INFO_CONFIG("Nordic", "QSPI", "1.00")
);
#define BLOCKDEV_LIST() ( \
NRF_BLOCKDEV_BASE_ADDR(m_block_dev_qspi, block_dev), \
)
/**
* @brief Endpoint list passed to @ref APP_USBD_MSC_GLOBAL_DEF
*/
#define ENDPOINT_LIST() APP_USBD_MSC_ENDPOINT_LIST(1, 1)
/**
* @brief Mass storage class work buffer size
*/
#define MSC_WORKBUFFER_SIZE (1024)
/*lint -save -e26 -e64 -e123 -e505 -e651*/
/**
* @brief Mass storage class instance
*/
APP_USBD_MSC_GLOBAL_DEF(m_app_msc,
0,
msc_user_ev_handler,
ENDPOINT_LIST(),
BLOCKDEV_LIST(),
MSC_WORKBUFFER_SIZE);
/**
* @brief USB connection status
*/
static bool m_usb_connected = false;
#if USE_FATFS_QSPI
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_qspi, block_dev), NULL)
};
diskio_blockdev_register(drives, ARRAY_SIZE(drives));
NRF_LOG_INFO("Initializing disk 0 (QSPI)...");
disk_state = disk_initialize(0);
if (disk_state)
{
NRF_LOG_INFO("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)
{
uint8_t work[_MAX_SS]; /* Work area (larger is better for process time) */
ff_result=f_mkfs("",FM_FAT|FM_SFD,1024,work,sizeof work);//格式化FLASH,1,盘符;1,不需要引导区,8个扇区为1个簇
if(ff_result==0)
{
f_setlabel((const TCHAR *)"NORDIC U"); //设置Flash磁盘的名字为:NORDIC U
NRF_LOG_INFO("set disk name");
}
else
{
NRF_LOG_INFO("format fail");
} //格式化失败
}
else
{
NRF_LOG_INFO("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_FAT, 1024, buf, sizeof(buf));
if (ff_result != FR_OK)
{
NRF_LOG_ERROR("Mkfs failed.");
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(" %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;
char filename[16];
if (m_usb_connected)
{
NRF_LOG_ERROR("Unable to operate on filesystem while USB is connected");
return;
}
(void)snprintf(filename, sizeof(filename), "%s.txt", "dev_id");
NRF_LOG_RAW_INFO("Creating random file: %s ...", (uint32_t)filename);
NRF_LOG_FLUSH();
ff_result = f_open(&file, filename, FA_OPEN_ALWAYS | FA_WRITE);
if (ff_result != FR_OK)
{
NRF_LOG_INFO("\r\nUnable to open or create file: %u", ff_result);
NRF_LOG_FLUSH();
return;
}
if(f_size(&file) == 0)
{
uint32_t id = 1;
uint32_t len;
ff_result = f_write(&file,&id,sizeof(uint32_t),&len);
if(ff_result != FR_OK)
{
NRF_LOG_ERROR("\r\nUnable to write file: %u", ff_result);
}
}
NRF_LOG_INFO("\r\nfile size: %u", f_size(&file));
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 (QSPI)...");
UNUSED_RETURN_VALUE(disk_uninitialize(0));
}
#else //USE_FATFS_QSPI
#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);
}
/**
* @brief USBD library specific event handler.
*
* @param event USBD library event.
*/
static void usbd_user_ev_handler(app_usbd_event_type_t event)
{
switch (event)
{
case APP_USBD_EVT_DRV_SUSPEND:
NRF_LOG_INFO("APP_USBD_EVT_DRV_SUSPEND");
break;
case APP_USBD_EVT_DRV_RESUME:
NRF_LOG_INFO("APP_USBD_EVT_DRV_RESUME");
break;
case APP_USBD_EVT_STARTED:
NRF_LOG_INFO("APP_USBD_EVT_STARTED");
break;
case APP_USBD_EVT_STOPPED:
UNUSED_RETURN_VALUE(fatfs_init());
app_usbd_disable();
NRF_LOG_INFO("APP_USBD_EVT_STOPPED");
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;
}
}
/**
* @brieaf usbd事件处理
*/
void usbd_evt_process(void)
{
while (app_usbd_event_queue_process())
{
/* Nothing to do */
}
}
static volatile bool m_finished = false;
static void qspi_handler(nrf_drv_qspi_evt_t event, void * p_context)
{
UNUSED_PARAMETER(event);
UNUSED_PARAMETER(p_context);
m_finished = true;
}
FRESULT get_memory_space(uint32_t * total_p, uint32_t * free_p)
{
FRESULT result;
DWORD fre_clust = 0;
uint32_t fre_sect = 0;
uint32_t tot_sect = 0;
FATFS fs;
FATFS *fs1 = &fs;
result = f_getfree((const TCHAR*)"/",&fre_clust,&fs1);
if(result == 0)
{
tot_sect = (fs1->n_fatent-2)*fs1->csize; // total sector
fre_sect = fre_clust * fs1->csize;
#if _MAX_SS != 512
tot_sect*=fs1->ssize/512;
tot_sect*=fs1->ssize/512;
#endif
*total_p = tot_sect >> 1; // unit in kb
*free_p = fre_sect >> 1; // unit in kb
}
return result;
}
/**
* @brieaf USB初时化
*/
void usbd_initialization(void)
{
ret_code_t ret;
static const app_usbd_config_t usbd_config = {
.ev_state_proc = usbd_user_ev_handler
};
app_usbd_serial_num_generate();
if (fatfs_init())
{
NRF_LOG_INFO("================> fatfs_init");
fatfs_ls();
fatfs_file_create();
}
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);
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;
}
uint32_t total,free;
get_memory_space(&total,&free);
NRF_LOG_INFO("total %d,free %d",total,free);
}
- 在softdevice_setup函数中加入nrf_drv_power_init初时化
/**@brief BLE + ANT stack initialization.
*
* @details Initializes the SoftDevice and the stack event interrupt.
*/
static void softdevice_setup(void)
{
#if NRF_MODULE_ENABLED(POWER)
ret_code_t ret = nrf_drv_power_init(NULL);
APP_ERROR_CHECK(ret);
#endif
ret_code_t err_code = nrf_sdh_enable_request();
APP_ERROR_CHECK(err_code);
ASSERT(nrf_sdh_is_enabled());
// 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);
err_code = nrf_sdh_ant_enable();
APP_ERROR_CHECK(err_code);
err_code = ant_plus_key_set(ANTPLUS_NETWORK_NUMBER);
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);
#if ANT_HRM_ENABLED
NRF_SDH_ANT_OBSERVER(m_ant_observer, APP_ANT_OBSERVER_PRIO, ant_evt_handler, NULL);
#endif
}
- 在ffconf.h文件中打开磁盘名称设置功能
#define _USE_LABEL 1
- 在fatfs_init
- main.c中进入主循环前调用usbd_initialization函数
usbd_initialization();
- 在main.c主循环中调用 usbd_evt_process函数
usbd_evt_process();
- 编译运行,并插入到电脑
- 调用get_memory_space获取存储空间信息
uint32_t total,free;
get_memory_space(&total,&free);
NRF_LOG_INFO("total %d,free %d",total,free);
info> usbd_core: total 16335,free 16333