基于52840 S340协议栈USB flash U盘实现
参考无协议栈例程目录下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" {#endifvoid 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_QSPIstatic 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 UNRF_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 sectorfre_sect = fre_clust * fs1->csize;
#if _MAX_SS != 512tot_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);
#endifret_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_ENABLEDNRF_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
基于52840 S340协议栈USB flash U盘实现相关推荐
- STM32CubeMX | STM32基于HAL实现USB模拟U盘
STM32CubeMX | STM32基于HAL实现USB模拟U盘 目录 STM32CubeMX | STM32基于HAL实现USB模拟U盘 (1)工程配置 (2)代码修改 环境说明: win10 S ...
- 基于闪存存储原理的U盘数据安全测试和U盘数据保护软件
第一章 摘要 Flash Memory是一种长寿命的非易失性存储介质,其存储原理存在诸多漏洞.其中最为严重的则为写入次数上限.而以闪存作为存储介质的U盘是否会因闪存的存储缺陷而成为不安全的存储设备,这 ...
- RT-thread实现USB虚拟U盘 模拟读卡器读写sd0
前言 rt-thread的usb组件包含了usb-device.usb-host等,最近需要在项目中添加PC端读写SD的功能,于是便考虑使用到本项目中去,这里我选用了usb-device,可以给USB ...
- bios 闪存颗粒_使用USB闪存盘从失败的BIOS刷新中恢复HP Compaq BIOS危机
bios 闪存颗粒 I tried to flash my HP Compaq CQ35-240TX's BIOS to F.15 but unfortunately failed. The comp ...
- 基于CH375的嵌入式USB文件加解密系统的设计
基于CH375的嵌入式USB文件加解密系统的设计 [日期:2008-7-21] 来源:电子技术应用 作者:华中科技大学 电子与信息工程系, 湖北 武汉 430074 [字体:大 中 小] <s ...
- linux mic阵列通道丢数据,基于XMOS平台的USB麦克风阵列多声道采集装置
技术领域 本实用新型涉及麦克风阵列多声道声音采集领域,尤其涉及基于XMOS平台的USB麦克风阵列多声道采集装置. 背景技术 麦克风阵列(Array Microphone),是由2个以上数量的声学数字或 ...
- 嵌入式linux作为hid设备,基于嵌入式系统的USB(HID)设备
基于嵌入式系统的USB(HID)设备 目前嵌入式系统在数字化电子产品领域应用越来越广泛.随着其成本的降低,大有取代单片机的趋势. USB设备以其小巧.便携.即插即用.成本低廉等优势在当前的桌面应用中有 ...
- 简单实现stm32f103芯片usb模拟U盘进行IAP更新用户程序
更新单片机内的用户程序,方式一般都是仿真器,串口,网络口,usb DFU,另类一点CAN也行,但是这些方式都有一个共同点,必须要有相应的上位机配合操作,还要教会别人使用,那么能不能有更简单傻瓜化的升级 ...
- ecs服务器配置git_基于ECS和NAS搭建个人网盘
场景介绍 本文为您介绍如何快速搭建一个基于ECS和NAS的私有网盘. 背景知识 本场景主要涉及以下云产品和服务: 云服务器ECS 云服务器(Elastic Compute Service,简称ECS) ...
最新文章
- android定义空字符串数组,android – retrofit:处理可以是空字符串或数组的属性
- 寄存器和常用的汇编指令
- Centos7 修改SSH 端口
- Security-OAuth2.0 密码模式之客户端实现
- Delphi中判断控件的详细类型
- 【数据竞赛】Kaggle实战之特征工程篇-20大文本特征(下)
- c语言编程输出数组元素之和,C语言 输出一个数组中,所有元素之和为0的子序列...
- kotlin的loop和Range、list和map
- Tensorflow CUDA及CUDNN版本对应关系表查询
- Atitit.常见的异常分类 目录 1. 双元分类法	1 1.1. 按照语言分 java js c# php等	1 1.2. 通用常见异常vs 特定异常	1 1.3. Runtime ex vs c
- Mysql 时间戳类型使用心得
- 机器视觉详解及入门必看
- 用这些进行PDF翻译,双语对照、翻译后排版不变、还免费!
- POJ-1637 混合图欧拉回路-网络流求解
- vue,videojs实现hls直播(萤石视频回放)
- 用ssm进行微信开发,实现微信登录验证功能
- C语言开发必会 宏定义、宏函数
- 堡垒机-百百堡垒机-基于WEB的VNC、RDP、SSH远程控制。无须任何插件,随时随地远程。
- 机器人视觉分析算法_机器视觉处理:目标检测和跟踪
- java.awt包_Java中awt包
热门文章
- html当作附件发送,邮件作为附件怎么发 怎样把邮件作为附件来进行传送?
- MES管理系统中,生产调度业务流程是怎么样的
- Spring框架学习路线
- 成功将 戴尔灵越燃7000 II 改装Win7
- jenkins2.3031 出现“Error 403 No valid crumb was included in the request ”的解决方案
- 广告图片自动轮播控件
- 我为什么而活着 [英]罗素
- 网络能力认证CCSC-管理1级 技术1级别
- 数据分析: kaggle比赛 - 销量预测
- java基于springboot在线小说阅读网站