zl程序教程

您现在的位置是:首页 >  其他

当前栏目

基于52840 S340协议栈USB flash U盘实现

协议 实现 基于 USB U盘 Flash
2023-09-14 09:16:39 时间

参考无协议栈例程目录下nRF5_SDK_17.0.2_d674dde\examples\peripheral\usbd_msc的工程

移植到S340工程下需要做以下步聚

  • 在sdk_config.h中加入以下配置
// <h> POWER_ENABLED菜单

// <e> NRFX_POWER_ENABLED - nrfx_power - POWER peripheral driver
//==========================================================
#ifndef NRFX_POWER_ENABLED
#define NRFX_POWER_ENABLED 1
#endif
// <o> NRFX_POWER_CONFIG_IRQ_PRIORITY  - Interrupt priority
 
// <0=> 0 (highest) 
// <1=> 1 
// <2=> 2 
// <3=> 3 
// <4=> 4 
// <5=> 5 
// <6=> 6 
// <7=> 7 

#ifndef NRFX_POWER_CONFIG_IRQ_PRIORITY
#define NRFX_POWER_CONFIG_IRQ_PRIORITY 6
#endif

// <q> NRFX_POWER_CONFIG_DEFAULT_DCDCEN  - The default configuration of main DCDC regulator
 

// <i> 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

// <q> NRFX_POWER_CONFIG_DEFAULT_DCDCENHV  - The default configuration of High Voltage DCDC regulator
 

// <i> 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

// </e>


// <e> POWER_ENABLED - nrf_drv_power - POWER peripheral driver - legacy layer
//==========================================================
#ifndef POWER_ENABLED
#define POWER_ENABLED 1
#endif
// <o> POWER_CONFIG_IRQ_PRIORITY  - Interrupt priority
 

// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
// <0=> 0 (highest) 
// <1=> 1 
// <2=> 2 
// <3=> 3 
// <4=> 4 
// <5=> 5 
// <6=> 6 
// <7=> 7 

#ifndef POWER_CONFIG_IRQ_PRIORITY
#define POWER_CONFIG_IRQ_PRIORITY 6
#endif

// <q> POWER_CONFIG_DEFAULT_DCDCEN  - The default configuration of main DCDC regulator
 

// <i> 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

// <q> POWER_CONFIG_DEFAULT_DCDCENHV  - The default configuration of High Voltage DCDC regulator
 

// <i> 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

// </e>


// </h>


// <h> QSPI菜单配置


// <q> 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

// <q> 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

// <q> 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


// <e> 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
// <o> NRF_BLOCK_DEV_QSPI_CONFIG_LOG_LEVEL  - Default Severity level
 
// <0=> Off 
// <1=> Error 
// <2=> Warning 
// <3=> Info 
// <4=> Debug 

#ifndef NRF_BLOCK_DEV_QSPI_CONFIG_LOG_LEVEL
#define NRF_BLOCK_DEV_QSPI_CONFIG_LOG_LEVEL 3
#endif

// <o> NRF_BLOCK_DEV_QSPI_CONFIG_LOG_INIT_FILTER_LEVEL  - Initial severity level if dynamic filtering is enabled
 
// <0=> Off 
// <1=> Error 
// <2=> Warning 
// <3=> Info 
// <4=> Debug 

#ifndef NRF_BLOCK_DEV_QSPI_CONFIG_LOG_INIT_FILTER_LEVEL
#define NRF_BLOCK_DEV_QSPI_CONFIG_LOG_INIT_FILTER_LEVEL 3
#endif

// <o> NRF_BLOCK_DEV_QSPI_CONFIG_INFO_COLOR  - ANSI escape code prefix.
 
// <0=> Default 
// <1=> Black 
// <2=> Red 
// <3=> Green 
// <4=> Yellow 
// <5=> Blue 
// <6=> Magenta 
// <7=> Cyan 
// <8=> White 

#ifndef NRF_BLOCK_DEV_QSPI_CONFIG_INFO_COLOR
#define NRF_BLOCK_DEV_QSPI_CONFIG_INFO_COLOR 0
#endif

// <o> NRF_BLOCK_DEV_QSPI_CONFIG_DEBUG_COLOR  - ANSI escape code prefix.
 
// <0=> Default 
// <1=> Black 
// <2=> Red 
// <3=> Green 
// <4=> Yellow 
// <5=> Blue 
// <6=> Magenta 
// <7=> Cyan 
// <8=> White 

#ifndef NRF_BLOCK_DEV_QSPI_CONFIG_DEBUG_COLOR
#define NRF_BLOCK_DEV_QSPI_CONFIG_DEBUG_COLOR 0
#endif

// </e>



// <e> NRFX_QSPI_ENABLED - nrfx_qspi - QSPI peripheral driver
//==========================================================
#ifndef NRFX_QSPI_ENABLED
#define NRFX_QSPI_ENABLED 1
#endif
// <o> NRFX_QSPI_CONFIG_SCK_DELAY - tSHSL, tWHSL and tSHWL in number of 16 MHz periods (62.5 ns).  <0-255> 


#ifndef NRFX_QSPI_CONFIG_SCK_DELAY
#define NRFX_QSPI_CONFIG_SCK_DELAY 1
#endif

// <o> 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

// <o> NRFX_QSPI_CONFIG_READOC  - Number of data lines and opcode used for reading.
 
// <0=> FastRead 
// <1=> Read2O 
// <2=> Read2IO 
// <3=> Read4O 
// <4=> Read4IO 

#ifndef NRFX_QSPI_CONFIG_READOC
#define NRFX_QSPI_CONFIG_READOC 0
#endif

// <o> NRFX_QSPI_CONFIG_WRITEOC  - Number of data lines and opcode used for writing.
 
// <0=> PP 
// <1=> PP2O 
// <2=> PP4O 
// <3=> PP4IO 

#ifndef NRFX_QSPI_CONFIG_WRITEOC
#define NRFX_QSPI_CONFIG_WRITEOC 0
#endif

// <o> NRFX_QSPI_CONFIG_ADDRMODE  - Addressing mode.
 
// <0=> 24bit 
// <1=> 32bit 

#ifndef NRFX_QSPI_CONFIG_ADDRMODE
#define NRFX_QSPI_CONFIG_ADDRMODE 0
#endif

// <o> NRFX_QSPI_CONFIG_MODE  - SPI mode.
 
// <0=> Mode 0 
// <1=> Mode 1 

#ifndef NRFX_QSPI_CONFIG_MODE
#define NRFX_QSPI_CONFIG_MODE 0
#endif

// <o> NRFX_QSPI_CONFIG_FREQUENCY  - Frequency divider.
 
// <0=> 32MHz/1 
// <1=> 32MHz/2 
// <2=> 32MHz/3 
// <3=> 32MHz/4 
// <4=> 32MHz/5 
// <5=> 32MHz/6 
// <6=> 32MHz/7 
// <7=> 32MHz/8 
// <8=> 32MHz/9 
// <9=> 32MHz/10 
// <10=> 32MHz/11 
// <11=> 32MHz/12 
// <12=> 32MHz/13 
// <13=> 32MHz/14 
// <14=> 32MHz/15 
// <15=> 32MHz/16 

#ifndef NRFX_QSPI_CONFIG_FREQUENCY
#define NRFX_QSPI_CONFIG_FREQUENCY 0
#endif

// <s> NRFX_QSPI_PIN_SCK - SCK pin value.
#ifndef NRFX_QSPI_PIN_SCK
#define NRFX_QSPI_PIN_SCK 29
#endif

// <s> NRFX_QSPI_PIN_CSN - CSN pin value.
#ifndef NRFX_QSPI_PIN_CSN
#define NRFX_QSPI_PIN_CSN 2
#endif

// <s> NRFX_QSPI_PIN_IO0 - IO0 pin value.
#ifndef NRFX_QSPI_PIN_IO0
#define NRFX_QSPI_PIN_IO0  30
#endif

// <s> NRFX_QSPI_PIN_IO1 - IO1 pin value.
#ifndef NRFX_QSPI_PIN_IO1
#define NRFX_QSPI_PIN_IO1 3
#endif

// <s> NRFX_QSPI_PIN_IO2 - IO2 pin value.
#ifndef NRFX_QSPI_PIN_IO2
#define NRFX_QSPI_PIN_IO2 47
#endif

// <s> NRFX_QSPI_PIN_IO3 - IO3 pin value.
#ifndef NRFX_QSPI_PIN_IO3
#define NRFX_QSPI_PIN_IO3 28
#endif

// <o> NRFX_QSPI_CONFIG_IRQ_PRIORITY  - Interrupt priority
 
// <0=> 0 (highest) 
// <1=> 1 
// <2=> 2 
// <3=> 3 
// <4=> 4 
// <5=> 5 
// <6=> 6 
// <7=> 7 

#ifndef NRFX_QSPI_CONFIG_IRQ_PRIORITY
#define NRFX_QSPI_CONFIG_IRQ_PRIORITY 6
#endif

// </e>


// <e> QSPI_ENABLED - nrf_drv_qspi - QSPI peripheral driver - legacy layer
//==========================================================
#ifndef QSPI_ENABLED
#define QSPI_ENABLED 1
#endif
// <o> QSPI_CONFIG_SCK_DELAY - tSHSL, tWHSL and tSHWL in number of 16 MHz periods (62.5 ns).  <0-255> 


#ifndef QSPI_CONFIG_SCK_DELAY
#define QSPI_CONFIG_SCK_DELAY 1
#endif

// <o> 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

// <o> QSPI_CONFIG_READOC  - Number of data lines and opcode used for reading.
 
// <0=> FastRead 
// <1=> Read2O 
// <2=> Read2IO 
// <3=> Read4O 
// <4=> Read4IO 

#ifndef QSPI_CONFIG_READOC
#define QSPI_CONFIG_READOC 0
#endif

// <o> QSPI_CONFIG_WRITEOC  - Number of data lines and opcode used for writing.
 
// <0=> PP 
// <1=> PP2O 
// <2=> PP4O 
// <3=> PP4IO 

#ifndef QSPI_CONFIG_WRITEOC
#define QSPI_CONFIG_WRITEOC 0
#endif

// <o> QSPI_CONFIG_ADDRMODE  - Addressing mode.
 
// <0=> 24bit 
// <1=> 32bit 

#ifndef QSPI_CONFIG_ADDRMODE
#define QSPI_CONFIG_ADDRMODE 0
#endif

// <o> QSPI_CONFIG_MODE  - SPI mode.
 
// <0=> Mode 0 
// <1=> Mode 1 

#ifndef QSPI_CONFIG_MODE
#define QSPI_CONFIG_MODE 0
#endif

// <o> QSPI_CONFIG_FREQUENCY  - Frequency divider.
 
// <0=> 32MHz/1 
// <1=> 32MHz/2 
// <2=> 32MHz/3 
// <3=> 32MHz/4 
// <4=> 32MHz/5 
// <5=> 32MHz/6 
// <6=> 32MHz/7 
// <7=> 32MHz/8 
// <8=> 32MHz/9 
// <9=> 32MHz/10 
// <10=> 32MHz/11 
// <11=> 32MHz/12 
// <12=> 32MHz/13 
// <13=> 32MHz/14 
// <14=> 32MHz/15 
// <15=> 32MHz/16 

#ifndef QSPI_CONFIG_FREQUENCY
#define QSPI_CONFIG_FREQUENCY 0
#endif

// <s> QSPI_PIN_SCK - SCK pin value.
#ifndef QSPI_PIN_SCK
#define QSPI_PIN_SCK 29
#endif

// <s> QSPI_PIN_CSN - CSN pin value.
#ifndef QSPI_PIN_CSN
#define QSPI_PIN_CSN 2
#endif

// <s> QSPI_PIN_IO0 - IO0 pin value.
#ifndef QSPI_PIN_IO0
#define QSPI_PIN_IO0 30
#endif

// <s> QSPI_PIN_IO1 - IO1 pin value.
#ifndef QSPI_PIN_IO1
#define QSPI_PIN_IO1 3
#endif

// <s> QSPI_PIN_IO2 - IO2 pin value.
#ifndef QSPI_PIN_IO2
#define QSPI_PIN_IO2  47
#endif

// <s> QSPI_PIN_IO3 - IO3 pin value.
#ifndef QSPI_PIN_IO3
#define QSPI_PIN_IO3 28
#endif

// <o> QSPI_CONFIG_IRQ_PRIORITY  - Interrupt priority
 

// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
// <0=> 0 (highest) 
// <1=> 1 
// <2=> 2 
// <3=> 3 
// <4=> 4 
// <5=> 5 
// <6=> 6 
// <7=> 7 

#ifndef QSPI_CONFIG_IRQ_PRIORITY
#define QSPI_CONFIG_IRQ_PRIORITY 6
#endif

// </e>


// </h>


// <h> USB菜单配置

// <e> NRFX_USBD_ENABLED - nrfx_usbd - USBD peripheral driver
//==========================================================
#ifndef NRFX_USBD_ENABLED
#define NRFX_USBD_ENABLED 1
#endif
// <o> NRFX_USBD_CONFIG_IRQ_PRIORITY  - Interrupt priority
 
// <0=> 0 (highest) 
// <1=> 1 
// <2=> 2 
// <3=> 3 
// <4=> 4 
// <5=> 5 
// <6=> 6 
// <7=> 7 

#ifndef NRFX_USBD_CONFIG_IRQ_PRIORITY
#define NRFX_USBD_CONFIG_IRQ_PRIORITY 6
#endif

// <o> NRFX_USBD_CONFIG_DMASCHEDULER_MODE  - USBD DMA scheduler working scheme
 
// <0=> Prioritized access 
// <1=> Round Robin 

#ifndef NRFX_USBD_CONFIG_DMASCHEDULER_MODE
#define NRFX_USBD_CONFIG_DMASCHEDULER_MODE 0
#endif

// <q> NRFX_USBD_CONFIG_DMASCHEDULER_ISO_BOOST  - Give priority to isochronous transfers
 

// <i> This option gives priority to isochronous transfers.
// <i> Enabling it assures that isochronous transfers are always processed,
// <i> even if multiple other transfers are pending.
// <i> Isochronous endpoints are prioritized before the usbd_dma_scheduler_algorithm
// <i> 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

// <q> NRFX_USBD_CONFIG_ISO_IN_ZLP  - Respond to an IN token on ISO IN endpoint with ZLP when no data is ready
 

// <i> If set, ISO IN endpoint will respond to an IN token with ZLP when no data is ready to be sent.
// <i> Else, there will be no response.

#ifndef NRFX_USBD_CONFIG_ISO_IN_ZLP
#define NRFX_USBD_CONFIG_ISO_IN_ZLP 0
#endif

// <q> NRFX_USBD_USE_WORKAROUND_FOR_ANOMALY_211  - Use workaround for anomaly 211
 

// <i> If set, workaround for anomaly 211 will be enabled.
// <i> Anomaly 211 - Device remains in SUSPEND too long when host resumes
// <i> 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

// </e>



// <e> USBD_ENABLED - nrf_drv_usbd - Software Component
//==========================================================
#ifndef USBD_ENABLED
#define USBD_ENABLED 1
#endif
// <o> USBD_CONFIG_IRQ_PRIORITY  - Interrupt priority
 

// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
// <0=> 0 (highest) 
// <1=> 1 
// <2=> 2 
// <3=> 3 
// <4=> 4 
// <5=> 5 
// <6=> 6 
// <7=> 7 

#ifndef USBD_CONFIG_IRQ_PRIORITY
#define USBD_CONFIG_IRQ_PRIORITY 6
#endif

// <o> USBD_CONFIG_DMASCHEDULER_MODE  - USBD SMA scheduler working scheme
 
// <0=> Prioritized access 
// <1=> Round Robin 

#ifndef USBD_CONFIG_DMASCHEDULER_MODE
#define USBD_CONFIG_DMASCHEDULER_MODE 0
#endif

// <q> USBD_CONFIG_DMASCHEDULER_ISO_BOOST  - Give priority to isochronous transfers
 

// <i> This option gives priority to isochronous transfers.
// <i> Enabling it assures that isochronous transfers are always processed,
// <i> even if multiple other transfers are pending.
// <i> Isochronous endpoints are prioritized before the usbd_dma_scheduler_algorithm
// <i> 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

// <q> USBD_CONFIG_ISO_IN_ZLP  - Respond to an IN token on ISO IN endpoint with ZLP when no data is ready
 

// <i> If set, ISO IN endpoint will respond to an IN token with ZLP when no data is ready to be sent.
// <i> Else, there will be no response.
// <i> NOTE: This option does not work on Engineering A chip.

#ifndef USBD_CONFIG_ISO_IN_ZLP
#define USBD_CONFIG_ISO_IN_ZLP 0
#endif

// </e>





// <e> APP_USBD_ENABLED - app_usbd - USB Device library
//==========================================================
#ifndef APP_USBD_ENABLED
#define APP_USBD_ENABLED 1
#endif
// <s> APP_USBD_VID - Vendor ID.

// <i> Note: This value is not editable in Configuration Wizard.
// <i> Vendor ID ordered from USB IF: http://www.usb.org/developers/vendor/
#ifndef APP_USBD_VID
#define APP_USBD_VID 0x1915
#endif

// <s> APP_USBD_PID - Product ID.

// <i> Note: This value is not editable in Configuration Wizard.
// <i> Selected Product ID
#ifndef APP_USBD_PID
#define APP_USBD_PID 0x520D
#endif

// <o> APP_USBD_DEVICE_VER_MAJOR - Major device version  <0-99> 


// <i> 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

// <o> APP_USBD_DEVICE_VER_MINOR - Minor device version  <0-9> 


// <i> 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

// <o> APP_USBD_DEVICE_VER_SUB - Sub-minor device version  <0-9> 


// <i> 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

// <q> 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

// <o> APP_USBD_CONFIG_MAX_POWER - MaxPower field in configuration descriptor in milliamps.  <0-500> 


#ifndef APP_USBD_CONFIG_MAX_POWER
#define APP_USBD_CONFIG_MAX_POWER 100
#endif

// <q> APP_USBD_CONFIG_POWER_EVENTS_PROCESS  - Process power events.
 

// <i> Enable processing power events in USB event handler.

#ifndef APP_USBD_CONFIG_POWER_EVENTS_PROCESS
#define APP_USBD_CONFIG_POWER_EVENTS_PROCESS 1
#endif

// <e> APP_USBD_CONFIG_EVENT_QUEUE_ENABLE - Enable event queue.

// <i> This is the default configuration when all the events are placed into internal queue.
// <i> Disable it when an external queue is used like app_scheduler or if you wish to process all events inside interrupts.
// <i> 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.
// <i> 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
// <o> APP_USBD_CONFIG_EVENT_QUEUE_SIZE - The size of the event queue.  <16-64> 


// <i> 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

// <o> APP_USBD_CONFIG_SOF_HANDLING_MODE  - Change SOF events handling mode.
 

// <i> Normal queue   - SOF events are pushed normally into the event queue.
// <i> Compress queue - SOF events are counted and binded with other events or executed when the queue is empty.
// <i>                  This prevents the queue from filling up with SOF events.
// <i> Interrupt      - SOF events are processed in interrupt.
// <0=> Normal queue 
// <1=> Compress queue 
// <2=> Interrupt 

#ifndef APP_USBD_CONFIG_SOF_HANDLING_MODE
#define APP_USBD_CONFIG_SOF_HANDLING_MODE 1
#endif

// </e>

// <q> APP_USBD_CONFIG_SOF_TIMESTAMP_PROVIDE  - Provide a function that generates timestamps for logs based on the current SOF.
 

// <i> The function app_usbd_sof_timestamp_get is implemented if the logger is enabled. 
// <i> Use it when initializing the logger. 
// <i> SOF processing is always enabled when this configuration parameter is active. 
// <i> Note: This option is configured outside of APP_USBD_CONFIG_LOG_ENABLED. 
// <i> 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

// <o> APP_USBD_CONFIG_DESC_STRING_SIZE - Maximum size of the NULL-terminated string of the string descriptor.  <31-254> 


// <i> 31 characters can be stored in the internal USB buffer used for transfers.
// <i> 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

// <q> APP_USBD_CONFIG_DESC_STRING_UTF_ENABLED  - Enable UTF8 conversion.
 

// <i> 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

// <s> APP_USBD_STRINGS_LANGIDS - Supported languages identifiers.

// <i> Note: This value is not editable in Configuration Wizard.
// <i> 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

// <e> APP_USBD_STRING_ID_MANUFACTURER - Define manufacturer string ID.

// <i> Setting ID to 0 disables the string.
//==========================================================
#ifndef APP_USBD_STRING_ID_MANUFACTURER
#define APP_USBD_STRING_ID_MANUFACTURER 1
#endif
// <q> 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

// <s> APP_USBD_STRINGS_MANUFACTURER - String descriptor for the manufacturer name.

// <i> Note: This value is not editable in Configuration Wizard.
// <i> Comma-separated list of manufacturer names for each defined language.
// <i> Use @ref APP_USBD_STRING_DESC macro to create string descriptor from a NULL-terminated string.
// <i> Use @ref APP_USBD_STRING_RAW8_DESC macro to create string descriptor from comma-separated uint8_t values.
// <i> Use @ref APP_USBD_STRING_RAW16_DESC macro to create string descriptor from comma-separated uint16_t values.
// <i> Alternatively, configure the macro to point to any internal variable pointer that already contains the descriptor.
// <i> Setting string to NULL disables that string.
// <i> 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

// </e>

// <e> APP_USBD_STRING_ID_PRODUCT - Define product string ID.

// <i> Setting ID to 0 disables the string.
//==========================================================
#ifndef APP_USBD_STRING_ID_PRODUCT
#define APP_USBD_STRING_ID_PRODUCT 2
#endif
// <q> 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

// <s> APP_USBD_STRINGS_PRODUCT - String descriptor for the product name.

// <i> Note: This value is not editable in Configuration Wizard.
// <i> 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

// </e>

// <e> APP_USBD_STRING_ID_SERIAL - Define serial number string ID.

// <i> Setting ID to 0 disables the string.
//==========================================================
#ifndef APP_USBD_STRING_ID_SERIAL
#define APP_USBD_STRING_ID_SERIAL 3
#endif
// <q> 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

// <s> APP_USBD_STRING_SERIAL - String descriptor for the serial number.

// <i> Note: This value is not editable in Configuration Wizard.
// <i> 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

// </e>

// <e> APP_USBD_STRING_ID_CONFIGURATION - Define configuration string ID.

// <i> Setting ID to 0 disables the string.
//==========================================================
#ifndef APP_USBD_STRING_ID_CONFIGURATION
#define APP_USBD_STRING_ID_CONFIGURATION 4
#endif
// <q> 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

// <s> APP_USBD_STRINGS_CONFIGURATION - String descriptor for the device configuration.

// <i> Note: This value is not editable in Configuration Wizard.
// <i> 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

// </e>

// <s> APP_USBD_STRINGS_USER - Default values for user strings.

// <i> Note: This value is not editable in Configuration Wizard.
// <i> This value stores all application specific user strings with the default initialization.
// <i> The setup is done by X-macros.
// <i> Expected macro parameters:
// <i> @code
// <i> X(mnemonic, [=str_idx], ...)
// <i> @endcode
// <i> - @c mnemonic: Mnemonic of the string descriptor that would be added to
// <i>                @ref app_usbd_string_desc_idx_t enumerator.
// <i> - @c str_idx : String index value, can be set or left empty.
// <i>                For example, WinUSB driver requires descriptor to be present on 0xEE index.
// <i>                Then use X(USBD_STRING_WINUSB, =0xEE, (APP_USBD_STRING_DESC(...)))
// <i> - @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

// </e>

// <q> APP_USBD_MSC_ENABLED  - app_usbd_msc - USB MSC class
 
#ifndef APP_USBD_MSC_ENABLED
#define APP_USBD_MSC_ENABLED 1
#endif
// </h>
  • 加入以下文件到工程
  • 在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

  • 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("   <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;
    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);

<00> info> usbd_core: total 16335,free 16333