Fstorage with usbd_HID_composite what to do with softdevice

Good day all.

Im finding my self working in a circle and not quite sure how to go about this.  My USBD_HID device code  with my  Neopixel lib work well together. I now need to store a number using Fstorage. My problem is that Fstorage uses Softdevice and the USBD_HID code does not. I have tried building my HID code around the Fstorage example and visa versa but because of ifdef statements around the include Softdevice I keep getting undeclared variables.

Is there an easier way to save an int to flash without having the softdevice incorporated. 

Parents Reply Children
  • I need some help reading my int back please. I need to store the number associated with the RGB Neopixel that was last displayed. (1 to 5). After a power cycle it needs to display the same color.

    #define FLASHWRITE_EXAMPLE_MAX_STRING_LEN       (1u)
    #define FLASHWRITE_EXAMPLE_BLOCK_VALID          (0xA55A5AA5)
    #define FLASHWRITE_EXAMPLE_BLOCK_INVALID        (0xA55A0000)
    #define FLASHWRITE_EXAMPLE_BLOCK_NOT_INIT       (0xFFFFFFFF)
    
    int magic_number;
    
    
    typedef struct
    {
       int magic_number;
       uint32_t buffer[FLASHWRITE_EXAMPLE_MAX_STRING_LEN + 1]; // + 1 for end of string
    } flashwrite_example_flash_data_t;
       
    typedef struct
    {
        uint32_t addr;
        uint32_t pg_size;
        uint32_t pg_num;
        flashwrite_example_flash_data_t * m_p_flash_data;
    } flashwrite_example_data_t;
    
    static flashwrite_example_data_t m_data;
    
    static ret_code_t clock_config(void)
    {
        ret_code_t err_code;
    
        err_code = nrf_drv_clock_init();
        if (err_code != NRF_SUCCESS && err_code != NRF_ERROR_MODULE_ALREADY_INITIALIZED)
        {
            return err_code;
        }
    
        nrf_drv_clock_lfclk_request(NULL);
    
        return NRF_SUCCESS;
    }
    
    static void flash_page_init(void)
    {
        m_data.pg_num = NRF_FICR->CODESIZE - 1;
        m_data.pg_size = NRF_FICR->CODEPAGESIZE;
        m_data.addr = (m_data.pg_num * m_data.pg_size);
    
        m_data.m_p_flash_data = (flashwrite_example_flash_data_t *)m_data.addr;
    
        while (1)
        {
            if (m_data.m_p_flash_data->magic_number == FLASHWRITE_EXAMPLE_BLOCK_VALID)
            {
                return;
            }
    
            if (m_data.m_p_flash_data->magic_number == FLASHWRITE_EXAMPLE_BLOCK_INVALID)
            {
                ++m_data.m_p_flash_data;
                continue;
            }
    
            nrf_nvmc_page_erase(m_data.addr);
            return;
        }
    }
    
     void RGB_cycle(void){
               
              if (magic_number == 1){ drv_ws2812_set_pixel_all(16711680);//red
               drv_ws2812_display(NULL, NULL);
               }
              
              if (magic_number == 2) {drv_ws2812_set_pixel_all(8388736);//purple
               drv_ws2812_display(NULL, NULL);
               }
              if (magic_number == 3) {drv_ws2812_set_pixel_all(16776960);//yellow
               drv_ws2812_display(NULL, NULL);
               }
              if (magic_number == 4){drv_ws2812_set_pixel_all(255);//blue
               drv_ws2812_display(NULL, NULL);
               }
              if (magic_number == 5){drv_ws2812_set_pixel_all(8393875);//pink
               drv_ws2812_display(NULL, NULL);
              }
               if (magic_number == 6){magic_number = 0;}
               flashwrite_example_flash_data_t magic_number;//store the magic number
    }
    
    
    
    
    int main(void)
    {
        ret_code_t ret;
      
      *
      *
      *
        init_bsp();
        init_cli();
        leds_init();
        flash_page_init();
        NRF_LOG_PROCESS();
    
        //This is not working Need more info on flashwrite_read_cmd please
        
        //Assign Magic number stored in flash back to magic number  
        magic_number = flashwrite_read_cmd(magic_number, 1,0);
      
        log_init();
        drv_ws2812_init(LED_CHAIN_DOUT_PIN);
    
      *
      *
      *
      *
    
          
    }
    
    
    
    static void flash_string_write(uint32_t address, const char * src, uint32_t num_words)
    {
        uint32_t i;
    
        // Enable write.
        NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Wen;
        while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
        {
        }
    
        for (i = 0; i < num_words; i++)
        {
            /* Only full 32-bit words can be written to Flash. */
            ((uint32_t*)address)[i] = 0x000000FFUL & (uint32_t)((uint8_t)src[i]);
            while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
            {
            }
        }
    
        NRF_NVMC->CONFIG = NVMC_CONFIG_WEN_Ren;
        while (NRF_NVMC->READY == NVMC_READY_READY_Busy)
        {
        }
    }
    
    
    static void flashwrite_erase_cmd(nrf_cli_t const * p_cli, size_t argc, char **argv)
    {
        nrf_nvmc_page_erase(m_data.addr);
    
        m_data.m_p_flash_data = (flashwrite_example_flash_data_t *)m_data.addr;
    }
    
    static void flashwrite_read_cmd(nrf_cli_t const * p_cli, size_t argc, char **argv)
    {
        flashwrite_example_flash_data_t * p_data = (flashwrite_example_flash_data_t *)m_data.addr;
        char string_buff[FLASHWRITE_EXAMPLE_MAX_STRING_LEN + 1]; // + 1 for end of string
    
        if ((p_data == m_data.m_p_flash_data) &&
            (p_data->magic_number != FLASHWRITE_EXAMPLE_BLOCK_VALID))
        {
            nrf_cli_fprintf(p_cli, NRF_CLI_WARNING, "Please write something first.\r\n");
            return;
        }
    
        while (p_data <= m_data.m_p_flash_data)
        {
            if ((p_data->magic_number != FLASHWRITE_EXAMPLE_BLOCK_VALID) &&
                (p_data->magic_number != FLASHWRITE_EXAMPLE_BLOCK_INVALID))
            {
                nrf_cli_fprintf(p_cli, NRF_CLI_WARNING, "Corrupted data found.\r\n");
                return;
            }
            uint8_t i;
            for (i = 0 ; i <= FLASHWRITE_EXAMPLE_MAX_STRING_LEN; i++)
            {
                string_buff[i] = (char)p_data->buffer[i];
            }
    
            nrf_cli_fprintf(p_cli, NRF_CLI_NORMAL, "%s\r\n", string_buff);
            ++p_data;
        }
    }
    
    static void flashwrite_write_cmd(nrf_cli_t const * p_cli, size_t argc, char **argv)
    {
        static uint16_t const page_size = 4096;
    
        if (argc < 2)
        {
            nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "%s:%s", argv[0], " bad parameter count\r\n");
            return;
        }
        if (argc > 2)
        {
            nrf_cli_fprintf(p_cli,
                            NRF_CLI_WARNING,
                            "%s:%s",
                            argv[0],
                            " bad parameter count - please use quotes\r\n");
            return;
        }
    
        uint32_t len = strlen(argv[1]);
        if (len > FLASHWRITE_EXAMPLE_MAX_STRING_LEN)
        {
            nrf_cli_fprintf(p_cli,
                            NRF_CLI_ERROR,
                            "Too long string. Please limit entered string to %d chars.\r\n",
                            FLASHWRITE_EXAMPLE_MAX_STRING_LEN);
            return;
        }
    
        if ((m_data.m_p_flash_data->magic_number != FLASHWRITE_EXAMPLE_BLOCK_NOT_INIT) &&
            (m_data.m_p_flash_data->magic_number != FLASHWRITE_EXAMPLE_BLOCK_VALID))
        {
            nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "Flash corrupted, please errase it first.");
            return;
        }
    
        if (m_data.m_p_flash_data->magic_number == FLASHWRITE_EXAMPLE_BLOCK_VALID)
        {
            uint32_t new_end_addr = (uint32_t)(m_data.m_p_flash_data + 2);
            uint32_t diff = new_end_addr - m_data.addr;
            if (diff > page_size)
            {
                nrf_cli_fprintf(p_cli,
                                NRF_CLI_WARNING,
                                "Not enough space - please erase flash first.\r\n");
                return;
            }
            nrf_nvmc_write_word((uint32_t)&m_data.m_p_flash_data->magic_number,
                                FLASHWRITE_EXAMPLE_BLOCK_INVALID);
            ++m_data.m_p_flash_data;
        }
    
        //++len -> store also end of string '\0'
        flash_string_write((uint32_t)m_data.m_p_flash_data->buffer, argv[1], ++len);
        nrf_nvmc_write_word((uint32_t)&m_data.m_p_flash_data->magic_number,
                            FLASHWRITE_EXAMPLE_BLOCK_VALID);
    }
    
    static void flashwrite_cmd(nrf_cli_t const * p_cli, size_t argc, char **argv)
    {
        ASSERT(p_cli);
        ASSERT(p_cli->p_ctx && p_cli->p_iface && p_cli->p_name);
    
        if ((argc == 1) || nrf_cli_help_requested(p_cli))
        {
            nrf_cli_help_print(p_cli, NULL, 0);
            return;
        }
    
        nrf_cli_fprintf(p_cli, NRF_CLI_ERROR, "%s:%s%s\r\n", argv[0], " unknown parameter: ", argv[1]);
    }
    
    NRF_CLI_CREATE_STATIC_SUBCMD_SET(m_sub_flash)
    {
        NRF_CLI_CMD(erase, NULL, "Erase flash.",          flashwrite_erase_cmd),
        NRF_CLI_CMD(read,  NULL, "Read data from flash.", flashwrite_read_cmd),
        NRF_CLI_CMD(write, NULL, "Write data to flash.\n"
                                 "Limitations:\n"
                                 "- maximum 16 entries,\n"
                                 "- each entry is maximum 62 chars long.",
                                                          flashwrite_write_cmd),
        NRF_CLI_SUBCMD_SET_END
    };
    NRF_CLI_CMD_REGISTER(flash, &m_sub_flash, "Flash access command.", flashwrite_cmd);
    
    /** @} */
    
    

  • Hi,

    Where do you call nrf_fstorage_write() and nrf_fstorage_read to write and read to/from the memory? You should consider using the flash_fds module instead, it's more high-level, has more features and is much easier to use. 

    regards

    Jared 

  • Jared, I see fstorage and flash_fds use softdevice. Im building my app of the HID_USB_Composite example so no softdevice.. I did try and include the soft device with a lot of IF_DEF problems and since im only saving one INT I thought flash write would be easy to incorporate.

    im looking at these but not sure how to use them to store the int. 

    flashwrite_write_cmd(nrf_cli_t const * p_cli, size_t argc, char **argv)

    flashwrite_read_cmd(nrf_cli_t const * p_cli, size_t argc, char **argv)

  • melt said:
    Jared, I see fstorage and flash_fds use softdevice. Im building my app of the HID_USB_Composite example so no softdevice.. I did try and include the soft device with a lot of IF_DEF problems and since im only saving one INT I thought flash write would be easy to incorporate.

    FDS does not require you to use the Softdevice. If the Softdevice isn't available, then the module will use the NVMC.

    melt said:

    im looking at these but not sure how to use them to store the int. 

    flashwrite_write_cmd(nrf_cli_t const * p_cli, size_t argc, char **argv)

    flashwrite_read_cmd(nrf_cli_t const * p_cli, size_t argc, char **argv)

    See the example in the documentation. Just set the *p_src to point to the number variable, and call  nrf_fstorage_write() to write the data to flash. The module is asynchronous so you've to wait for the handler to be called with a NRF_FSTORAGE_EVT_WRITE_RESULT  before you try to read the data. 

    regards

    Jared 

  • Thanks Jared il try FDS tonight. example in the documentation says  "access denied" when I click on it

Related