Hi,
I am working on a battery powered device that collects data, save it to files and go to sleep, when it is not connected to a laptop via USB. When connected, the device just become a "usb sd card reader" that shows the files, the sensors are disabled and the device never goes to sleep. I have based my application on the MSC sample, I can read the SD when I connect to a PC with no issue. My problem is when not connected to USB, on a "fresh" boot I can save data files fine but after waking up from sleep I get an initialisation error from usb_msc and a system reset, the next boot works fine (data can be written on sd) until the mcu is sent to sleep again and the loop repeats. It seems that I need to disable/uninit the mass storage before going to sleep somehow. However wouldn't CONFIG_USB_MASS_STORAGE=y keep the mass storage enabled, is there a way to only have Mass storage activated when connected with USB?
I found this post but it is using a older ncs sdk and this post that suggest to change the USB descriptors at runtime but I couldn't figure out how to edit the descriptors at runtime.
I am using nrf-sdk 2.6.1 on VS code, a nrf5340 custom PCB.
Any help would be greatly appreciated.
main.c
#include <errno.h> #include <string.h> #include <stdio.h> #include <zephyr/kernel.h> #include <zephyr/logging/log.h> #include <zephyr/sys/printk.h> #define SLEEP_TIME_MS 1000 #define MODULE main LOG_MODULE_REGISTER(MODULE, LOG_LEVEL_DBG); #include <inttypes.h> #include <zephyr/device.h> #include <zephyr/drivers/gpio.h> #include <zephyr/pm/pm.h> #include <zephyr/pm/device.h> #include <zephyr/pm/policy.h> #include <zephyr/sys/poweroff.h> #include <zephyr/sys/util.h> #include <zephyr/drivers/gpio.h> #include <hal/nrf_gpio.h> #include <zephyr/usb/usb_device.h> #include <zephyr/init.h> #include <zephyr/sys/reboot.h> #define SD_THREAD_STACK_SIZE 4096 K_THREAD_STACK_DEFINE(sd_thread_stack, SD_THREAD_STACK_SIZE); struct k_thread sd_thread_data; void sd_init_thread(void) { LOG_DBG("Starting SD card initialization thread..."); turn_off_sd(0); // Ensure SD card power is on int ret = sd_card_init(); if (ret != 0) { LOG_ERR("Failed to initialize SD card"); } else { sd_card_initialized = 1; save_sd_init_config(1); LOG_DBG("SD card initialized successfully."); } } void status_cb(enum usb_dc_status_code status, const uint8_t *param) { switch (status) { case USB_DC_CONNECTED: LOG_DBG("Device connected"); if (!sd_card_initialized) { LOG_DBG("Starting SD initialization thread..."); k_thread_create(&sd_thread_data, sd_thread_stack, K_THREAD_STACK_SIZEOF(sd_thread_stack), sd_init_thread, NULL, NULL, NULL, K_LOWEST_APPLICATION_THREAD_PRIO, 0, K_NO_WAIT); } save_usb_connected_config(1); usb_connected = 1; break; case USB_DC_DISCONNECTED: LOG_INF("Device disconnected"); if (sd_card_initialized) { LOG_INF("Unmounting SD card..."); unmount_sd_card(); turn_off_sd(0); // Turn off SD card power sd_card_initialized = 0; save_sd_init_config(0); LOG_INF("SD card unmounted and powered off."); } save_usb_connected_config(0); usb_connected = 0; save_usb_callback_config(1); usb_call_back_set = 1; usb_disable(); break; default: LOG_DBG("status %u unhandled", status); break; } } int main(void) { if(usb_call_back_set == 0){ int ret = usb_enable(status_cb); LOG_INF("Enable USB..."); if (ret != 0) { LOG_ERR("Failed to enable USB"); //return 0; } save_usb_callback_config(1); usb_call_back_set = 1; } accelerometer_init(usb_connected, sd_card_initialized); accelerometer_run(); LOG_DBG("Done."); return 0; }
logs
SEGGER J-Link V7.94e - Real time terminal output SEGGER J-Link (unknown) V1.0, SN=801046272 Process: JLink.exe [00:00:00.003,875] <inf> lis2dh: LIS2DH: int2 on [email protected] [00:00:00.006,103] <inf> lis2dh: fs=2, odr=0x3 lp_en=0x8 scale=9576 [00:00:00.007,568] <inf> pcf85063a: pcf85063a@51 is initialized! *** Booting nRF Connect SDK v3.5.99-ncs1-1 *** [00:00:00.149,169] <inf> main: Hi! DFU Starting nrf5340dk_nrf5340_cpuapp [00:00:00.165,069] <inf> nvs_storage: set SD_INIT config 0 at id 7 [00:00:00.165,924] <inf> nvs_storage: set acc sensitivity config 1.200 at id 4 [00:00:00.166,687] <inf> nvs_storage: config: 4, acc_sensitivity: 1.200 [00:00:00.174,774] <inf> nvs_storage: set acc sampling config 1 at id 3 [00:00:00.175,476] <inf> nvs_storage: config: 3, acc_sampling: 1 [00:00:00.175,933] <inf> nvs_storage: The integer value is: 1 [00:00:00.176,452] <inf> nvs_storage: config: 7, SD_INIT: 0 [00:00:00.176,879] <inf> nvs_storage: The integer value is: 0 [00:00:00.177,947] <inf> main: Enable USB... [00:[00:00:08.308,868] <inf> accelerometer: Motion detected, starting data collection [00:00:08.309,387] <inf> accelerometer: Motion detected, starting data collection, usb_connected:0 sd_card_initialized:0 [00:00:08.428,436] <inf> accelerometer: Motion detected, starting data collection [00:00:08.428,955] <inf> accelerometer: Motion detected, starting data collection, usb_connected:0 sd_card_initialized:0 [00:00:13.430,206] <inf> accelerometer: Motion timer expired, stopping data collection [00:00:13.430,725] <inf> accelerometer: Submit to queue... [00:00:13.431,152] <inf> accelerometer: sd_card_write_work_handler called [00:00:13.609,130] <inf> nvs_storage: set SD_INIT config 1 at id 7 [00:00:13.610,900] <inf> accelerometer: filename:2BFE6027164802EE_2020_04_12.csv [00:00:13.688,476] <inf> accelerometer: Unmount disk... [00:00:13.688,720] <inf> accelerometer: Disk unmounted. [00:00:13.694,702] <inf> nvs_storage: set SD_INIT config 0 at id 7 [00:00:13.695,159] <inf> accelerometer: Unmount done. [00:00:13.695,526] <inf> accelerometer: CONFIG acc_sensitivity:1.200000 acc_sampling:1 usb_connected:0 usb_call_back_set:1 sd_card_initialized:0 [00:00:13.696,105] <inf> accelerometer: Going to sleep... [00:00:13.702,117] <inf> nvs_storage: set USB_CALLBACK config 0 at id 6 [00:00:00.003,875] <inf> lis2dh: LIS2DH: int2 on [email protected] [00:00:00.006,042] <inf> lis2dh: fs=2, odr=0x3 lp_en=0x8 scale=9576 [00:00:00.007,446] <inf> pcf85063a: pcf85063a@51 is initialized! *** Booting nRF Connect SDK v3.5.99-ncs1-1 *** [00:00:00.014,831] <err> usb_msc: Storage init ERROR !!!! - Aborting USB init [00:00:00.015,716] <inf> main: Hi! DFU Starting nrf5340dk_nrf5340_cpuapp [00:00:00.031,341] <inf> nvs_storage: set SD_INIT config 0 at id 7 [00:00:00.031,860] <inf> nvs_storage: config: 4, acc_sensitivity: 1.200 [00:00:00.032,409] <inf> nvs_storage: config: 3, acc_sampling: 0 [00:00:00.032,867] <inf> nvs_storage: The integer value is: 0 [00:00:00.033,416] <inf> nvs_storage: config: 7, SD_INIT: 0 [00:00:00.033,813] <inf> nvs_storage: The integer value is: 0 [00:00:00.034,851] <inf> main: Enable USB... [00:00:00.042,694] <inf> nvs_storage: set USB_CALLBACK config 1 at id 6 [00:00:00.043,365] <inf> main: CONFIG acc_sensitivity:1.200000 acc_sampling:0 usb_connected:0 usb_call_back_set:1 sd_card_initialized:0 [00:00:00.044,525] <inf> accelerometer: Setting triggers for motion detection... [00:00:00.048,553] <inf> lis2dh: int2_ths=0x4c range_g=2 ums2=11767979 [00:00:00.050,903] <inf> lis2dh: int2_dur=0x0 [00:00:00.052,246] <dbg> main: main: Done. [00:00:10.573,455] <inf> accelerometer: Motion detected, starting data collection [00:00:10.573,974] <inf> accelerometer: Motion detected, starting data collection, usb_connected:0 sd_card_initialized:0 [00:00:10.578,552] <err> os: ***** USAGE FAULT ***** [00:00:10.578,918] <err> os: Division by zero [00:00:10.579,315] <err> os: r0/a1: 0x000003e7 r1/a2: 0x200437ec r2/a3: 0x00000000 [00:00:10.579,895] <err> os: r3/a4: 0x00000000 r12/ip: 0x00000000 r14/lr: 0x000093bb [00:00:10.580,444] <err> os: xpsr: 0x21000000 [00:00:10.580,841] <err> os: Faulting instruction address (r15/pc): 0x000091ea [00:00:10.581,359] <err> os: >>> ZEPHYR FATAL ERROR 30: Unknown error on CPU 0 [00:00:10.581,878] <err> os: Current thread: 0x200092d8 (sysworkq) [00:00:10.587,341] <err> fatal_error: Resetting system [00:00:10.580,841] <err> os: Faulting instruction address (r15/pc): 0x000091ea [00:00:10.581,359] <err> os: >>> ZEPHYR FATAL ERROR 30: Unknown error on CPU 0 [00:00:10.581,878] <err> os: Current thread: 0x200092d8 (sysworkq) [00:00:10.587,341] <err> fatal_error: Resetting system [00:00:00.003,875] <inf> lis2dh: LIS2DH: int2 on [email protected] [00:00:00.006,042] <inf> lis2dh: fs=2, odr=0x3 lp_en=0x8 scale=9576 [00:00:00.007,446] <inf> pcf85063a: pcf85063a@51 is initialized! *** Booting nRF Connect SDK v3.5.99-ncs1-1 *** [00:00:00.148,498] <inf> main: Hi! DFU Starting nrf5340dk_nrf5340_cpuapp [00:00:00.164,123] <inf> nvs_storage: set SD_INIT config 0 at id 7 [00:00:00.164,672] <inf> nvs_storage: config: 4, acc_sensitivity: 1.200 [00:00:00.165,222] <inf> nvs_storage: config: 3, acc_sampling: 1 [00:00:00.165,679] <inf> nvs_storage: The integer value is: 1 [00:00:00.166,229] <inf> nvs_storage: config: 7, SD_INIT: 0 [00:00:00.166,656] <inf> nvs_storage: The integer value is: 0 [00:00:00.167,694] <inf> main: Enable USB... [00:00:00.175,506] <inf> nvs_storage: set USB_CALLBACK config 1 at id 6 [00:00:00.176,055] <inf> main: CONFIG acc_sensitivity:1.200000 acc_sampling:1 usb_connected:0 usb_call_back_set:1 sd_card_initialized:0 [00:00:00.177,185] <inf> accelerometer: Setting triggers for motion detection... [00:00:00.181,213] <inf> lis2dh: int2_ths=0x4c range_g=2 ums2=11767979 [00:00:00.183,563] <inf> lis2dh: int2_dur=0x0 [00:00:00.184,997] <dbg> main: main: Done. [00:00:00.185,485] <inf> accelerometer: Motion detected, starting data collection [00:00:00.186,004] <inf> accelerometer: Motion detected, starting data collection, usb_connected:0 sd_card_initialized:0 [00:00:05.187,225] <inf> accelerometer: Motion timer expired, stopping data collection [00:00:05.187,744] <inf> accelerometer: Submit to queue... [00:00:05.188,171] <inf> accelerometer: sd_card_write_work_handler called [00:00:05.366,058] <inf> nvs_storage: set SD_INIT config 1 at id 7 [00:00:05.367,828] <inf> accelerometer: filename:2BFE6027164802EE_2020_04_12.csv [00:00:05.445,343] <inf> accelerometer: Unmount disk... [00:00:05.445,587] <inf> accelerometer: Disk unmounted. [00:00:05.451,538] <inf> nvs_storage: set SD_INIT config 0 at id 7 [00:00:05.451,995] <inf> accelerometer: Unmount done. [00:00:05.452,362] <inf> accelerometer: CONFIG acc_sensitivity:1.200000 acc_sampling:1 usb_connected:0 usb_call_back_set:1 sd_card_initialized:0 [00:00:05.452,941] <inf> accelerometer: Going to sleep... [00:00:05.458,923] <inf> nvs_storage: set USB_CALLBACK config 0 at id 6
pjr.conf
#Storage related CONFIG_SPI=y CONFIG_SPI_NRFX_RAM_BUFFER_SIZE=128 #Filesystem CONFIG_DISK_ACCESS=y CONFIG_FILE_SYSTEM=y CONFIG_FAT_FILESYSTEM_ELM=y CONFIG_FS_FATFS_EXFAT=y #Add external flash CONFIG_DISK_DRIVER_SDMMC=y CONFIG_SDMMC_SUBSYS=y CONFIG_SD_LOG_LEVEL_DBG=n CONFIG_SDHC_LOG_LEVEL_DBG=n #USB related configs CONFIG_USB_DEVICE_STACK=y CONFIG_USB_DEVICE_PID=0x0008 CONFIG_USB_DRIVER_LOG_LEVEL_ERR=y CONFIG_USB_MASS_STORAGE=y CONFIG_USB_DEVICE_LOG_LEVEL_ERR=y CONFIG_USB_MASS_STORAGE_LOG_LEVEL_ERR=y CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n CONFIG_MAIN_STACK_SIZE=4096 CONFIG_MASS_STORAGE_STACK_SIZE=8192 CONFIG_LOG=y CONFIG_USB_WORKQUEUE_STACK_SIZE=4096
Kconfig
config APP_WIPE_STORAGE bool "Option to clear the flash area before mounting" help Use this to force an existing file system to be created. choice prompt "Storage and file system type used by the application" default APP_MSC_STORAGE_NONE help Specify the type of storage and file system. config APP_MSC_STORAGE_NONE bool "Use RAM disk as block device" config APP_MSC_STORAGE_RAM bool "Use RAM disk and FAT file system" imply FILE_SYSTEM imply FAT_FILESYSTEM_ELM config APP_MSC_STORAGE_FLASH_FATFS bool "Use FLASH disk and FAT file system" imply DISK_DRIVER_FLASH imply FILE_SYSTEM imply FAT_FILESYSTEM_ELM config APP_MSC_STORAGE_FLASH_LITTLEFS bool "Use FLASH disk and LittleFS" imply DISK_DRIVER_FLASH imply FILE_SYSTEM imply FILE_SYSTEM_LITTLEFS config APP_MSC_STORAGE_SDCARD bool "Use SDHC and FAT file system" imply DISK_DRIVER_SDMMC imply FILE_SYSTEM imply FAT_FILESYSTEM_ELM endchoice config MASS_STORAGE_DISK_NAME default "NAND" if DISK_DRIVER_FLASH default "RAM" if DISK_DRIVER_RAM default "SD" if DISK_DRIVER_SDMMC if DISK_DRIVER_FLASH config FLASH_MAP default y config FLASH_PAGE_LAYOUT default y config FLASH_LOG_LEVEL default 3 if NORDIC_QSPI_NOR config NORDIC_QSPI_NOR_FLASH_LAYOUT_PAGE_SIZE default 4096 config FF_FS_NORTC int "Timestamp" default 0 endif # NORDIC_QSPI_NOR endif # DISK_DRIVER_FLASH source "Kconfig.zephyr"