예제 #1
0
파일: flash_api.c 프로젝트: sg-/mbed-os
int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data, uint32_t size)
{
    (void)(obj);

    /* Return value defaults to error. */
    uint32_t result = NRF_ERROR_BUSY;

    /* Convert size to words. */
    uint32_t words = size / sizeof(uint32_t);

    if (NRF_HAL_SD_IS_ENABLED()) {

        /* Setup stop watch for timeout. */
        uint32_t start_us = lp_ticker_read();
        uint32_t now_us = start_us;

        /* Retry if flash is busy until timeout is reached. */
        while (((now_us - start_us) < (words * WORD_WRITE_TIMEOUT_US)) &&
               (result == NRF_ERROR_BUSY)) {

            result = sd_flash_write((uint32_t *) address, (const uint32_t *) data, words);

            /* Read timeout timer. */
            now_us = lp_ticker_read();            
        }

    } else {
        /* We will use *_words function to speed up flashing code. Word means 32bit -> 4B
         * or sizeof(uint32_t).
         */
        nrf_nvmc_write_words(address, (const uint32_t *) data, words);
        result = NRF_SUCCESS;
    }

    /* Convert Nordic error code to mbed HAL error code. */
    return (result == NRF_SUCCESS) ? 0 : -1;
}
예제 #2
0
fs_ret_t nrf_dfu_flash_store(uint32_t const * p_dest, uint32_t const * const p_src, uint32_t len_words, dfu_flash_callback_t callback)
{
    fs_ret_t ret_val = FS_SUCCESS;

#ifdef BLE_STACK_SUPPORT_REQD
    if ((m_flags & FLASH_FLAG_SD_ENABLED) != 0)
    {
        // Check if there is a pending error
        if ((m_flags & FLASH_FLAG_FAILURE_SINCE_LAST) != 0)
        {
            NRF_LOG_ERROR("Flash: Failure since last\r\n");
            return FS_ERR_FAILURE_SINCE_LAST;
        }

        // Set the flag to indicate ongoing operation
        m_flags |= FLASH_FLAG_OPER;
        //lint -e611
        ret_val = fs_store(&fs_dfu_config, p_dest, p_src, len_words, (void*)callback);

        if (ret_val != FS_SUCCESS)
        {
            NRF_LOG_ERROR("Flash: failed %d\r\n", ret_val);
            return ret_val;
        }

        // Set the flag to indicate ongoing operation
        m_flags |= FLASH_FLAG_OPER;
    }
    else
#endif
    {

#ifndef NRF51
        if ((p_src == NULL) || (p_dest == NULL))
        {
            return FS_ERR_NULL_ARG;
        }

        // Check that both pointers are word aligned.
        if (((uint32_t)p_src  & 0x03) ||
            ((uint32_t)p_dest & 0x03))
        {
            return FS_ERR_UNALIGNED_ADDR;
        }

        if (len_words == 0)
        {
            NRF_LOG_ERROR("Flash: Invalid length (NVMC)\r\n");
            return FS_ERR_INVALID_ARG;
        }
#endif

        nrf_nvmc_write_words((uint32_t)p_dest, p_src, len_words);

        #if (__LINT__ != 1)
        if (callback)
        {
            fs_evt_t evt =
            {
                .id = FS_EVT_STORE,
                .p_context = (void*)callback,
                .store =
                {
                    .length_words = len_words,
                    .p_data = p_dest
                }
            };
            callback(&evt, FS_SUCCESS);
        }
        #endif
    }

    return ret_val;
}