Exemple #1
0
uint32_t pstorage_store(pstorage_handle_t * p_dest,
                        uint8_t           * p_src,
                        pstorage_size_t     size,
                        pstorage_size_t     offset)
{
    VERIFY_MODULE_INITIALIZED();
    NULL_PARAM_CHECK(p_src);
    NULL_PARAM_CHECK(p_dest);
    MODULE_ID_RANGE_CHECK(p_dest);
    BLOCK_ID_RANGE_CHECK(p_dest);
    SIZE_CHECK(p_dest, size);
    OFFSET_CHECK(p_dest, offset, size);

    // Verify word alignment.
    if ((!is_word_aligned(p_src)) || (!is_word_aligned((void *)(uint32_t)offset)))
    {
        return NRF_ERROR_INVALID_ADDR;
    }

    uint32_t storage_addr = p_dest->block_id + offset;

    uint32_t retval = ble_flash_block_write((uint32_t *)storage_addr,
                                            (uint32_t *)p_src,
                                            (size /sizeof(uint32_t)));

    app_notify(p_dest, p_src, PSTORAGE_STORE_OP_CODE, size, retval);
    
    return retval;
}
Exemple #2
0
/**@brief      This function stores in flash the System Attributes related to a specified master.
 *
 * @param[in]  p_sys_attr   System Attributes to be stored.
 *
 * @return     NRF_SUCCESS on success, an error_code otherwise.
 */
static uint32_t sys_attr_store(master_sys_attr_t * p_sys_attr)
{
    uint32_t err_code;

    // Check if flash is full.
    if (m_sys_attr_in_flash_count >= MAX_BONDS_IN_FLASH)
    {
        return NRF_ERROR_NO_MEM;
    }

    // Check if this is the first time any System Attributes is stored.
    if (m_sys_attr_in_flash_count == 0)
    {
        // Initialize CRC
        m_crc_sys_attr = ble_flash_crc16_compute(NULL, 0, NULL);
    
        // Find pointer to start of System Attributes flash block.
        err_code = ble_flash_page_addr(m_bondmngr_config.flash_page_num_sys_attr, 
                                       &mp_flash_sys_attr);
        if (err_code != NRF_SUCCESS)
        {
            return err_code;
        }
    }
    
    // Write System Attributes in flash.
    err_code = ble_flash_block_write(mp_flash_sys_attr + 1,
                                    (uint32_t *)p_sys_attr,
                                    sizeof(master_sys_attr_t) / sizeof(uint32_t));
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }
    m_crc_sys_attr = ble_flash_crc16_compute((uint8_t *)p_sys_attr, 
                                             sizeof(master_sys_attr_t), 
                                             &m_crc_sys_attr);
    
    // Write header
    err_code = ble_flash_word_write(mp_flash_sys_attr, BLE_FLASH_MAGIC_NUMBER | m_crc_sys_attr);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }
    
    // Update flash pointer
    mp_flash_sys_attr += ((sizeof(master_sys_attr_t) / sizeof(uint32_t)) + 1);
    
    m_sys_attr_in_flash_count++;
    return NRF_SUCCESS;
}
Exemple #3
0
/**@brief      This function stores the Bonding Information of the specified master to the flash.
 *
 * @param[in]  p_bond   Bonding information to be stored.
 *
 * @return     NRF_SUCCESS on success, an error_code otherwise.
 */
static uint32_t bond_info_store(master_bond_t * p_bond)
{
    uint32_t err_code;

    // Check if flash is full
    if (m_bond_info_in_flash_count >= MAX_BONDS_IN_FLASH)
    {
        return NRF_ERROR_NO_MEM;
    }

    // Check if this is the first bond to be stored
    if (m_bond_info_in_flash_count == 0)
    {
        // Initialize CRC
        m_crc_bond_info = ble_flash_crc16_compute(NULL, 0, NULL);
    
        // Find pointer to start of bond information flash block
        err_code = ble_flash_page_addr(m_bondmngr_config.flash_page_num_bond, &mp_flash_bond_info);
        if (err_code != NRF_SUCCESS)
        {
            return err_code;
        }
    }
    
    // Write Bonding Information
    err_code = ble_flash_block_write(mp_flash_bond_info + 1,
                                     (uint32_t *)p_bond,
                                     sizeof(master_bond_t) / sizeof(uint32_t));
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }
    m_crc_bond_info = ble_flash_crc16_compute((uint8_t *)p_bond, 
                                              sizeof(master_bond_t), 
                                              &m_crc_bond_info);
    
    // Write header
    err_code = ble_flash_word_write(mp_flash_bond_info, BLE_FLASH_MAGIC_NUMBER | m_crc_bond_info);
    if (err_code != NRF_SUCCESS)
    {
        return err_code;
    }
    
    // Update flash pointer
    mp_flash_bond_info += (sizeof(master_bond_t) / sizeof(uint32_t)) + 1;
    
    m_bond_info_in_flash_count++;
    return NRF_SUCCESS;
}
Exemple #4
0
static void bootloader_settings_save(bootloader_settings_t settings)
{
    const bootloader_settings_t * p_bootloader_settings;

    bootloader_util_settings_get(&p_bootloader_settings);

    // Save needed data for later use. 
    uint32_t settings_page = ((uint32_t) p_bootloader_settings) / NRF_FICR->CODEPAGESIZE;

    uint32_t num_of_words = sizeof(bootloader_settings_t) / sizeof(uint32_t);

    // Save bootloader settings.
    uint32_t err_code = ble_flash_page_erase(settings_page);
    APP_ERROR_CHECK(err_code);    
    err_code          = ble_flash_block_write((uint32_t *)p_bootloader_settings, 
                                              (uint32_t *)&settings, 
                                              num_of_words);
    APP_ERROR_CHECK(err_code);
}
Exemple #5
0
uint32_t bond_store_user_id(void)
{
    uint32_t  err_code;
    uint16_t  m_crc_bond_info;
    uint32_t  *mp_flash_bond_info;

    /* inialize crc check */
    m_crc_bond_info = ble_flash_crc16_compute(NULL, 0, NULL);

    // Find pointer to start of bond information flash block
    err_code = ble_flash_page_addr(FLASH_PAGE_USER_ID, &mp_flash_bond_info);
    if (err_code != NRF_SUCCESS) {
        return err_code;
    }

    /*FIXME: erase a page while bluetooth connected may cause disconnect, so this maybe stored when bluetooth disconnected*/
    /* Erase the whole page */
    ble_flash_page_erase(FLASH_PAGE_USER_ID);

    // Write private bonding Information
    err_code = ble_flash_block_write(mp_flash_bond_info + 1, //the first word is used to store crc
                                     (uint32_t *)user_id,
                                     ((USER_ID_LENGTH - 1) / (4) + 1));
    if (err_code != NRF_SUCCESS) {
        return err_code;
    }

    m_crc_bond_info = ble_flash_crc16_compute((uint8_t *)user_id,
                      USER_ID_LENGTH,
                      &m_crc_bond_info);

    // Write header
    err_code = ble_flash_word_write(mp_flash_bond_info, BLE_FLASH_MAGIC_NUMBER | m_crc_bond_info);
    if (err_code != NRF_SUCCESS) {
        return err_code;
    }

    return NRF_SUCCESS;
}
Exemple #6
0
uint32_t pstorage_update(pstorage_handle_t * p_dest,
                        uint8_t           * p_src,
                        pstorage_size_t     size,
                        pstorage_size_t     offset)
{

    uint32_t *p_swap_addr = (uint32_t *)PSTORAGE_SWAP_ADDR;
    uint32_t *p_page_addr1 =  (uint32_t *) PAGE_BASE_ADDR(p_dest->block_id + offset);
#ifdef SUPPORT_MODULES_LARGER_THAN_PAGE
    uint32_t *p_page_addr2 =  (uint32_t *) PAGE_BASE_ADDR(p_dest->block_id + offset + size-1);
#endif
    uint16_t head_word_count =  offset/sizeof(uint32_t);
    uint16_t body_word_count =  size/sizeof(uint32_t);
    uint16_t tail_word_count;
    uint32_t retval;


	VERIFY_MODULE_INITIALIZED();
    NULL_PARAM_CHECK(p_src);
    NULL_PARAM_CHECK(p_dest);
    MODULE_ID_RANGE_CHECK(p_dest);
    BLOCK_ID_RANGE_CHECK(p_dest);
    SIZE_CHECK(p_dest, size);
    OFFSET_CHECK(p_dest, offset, size);

    // Verify word alignment.
    if ((!is_word_aligned(p_src)) || (!is_word_aligned((void *)(uint32_t)offset)))
    {
        return NRF_ERROR_INVALID_ADDR;
    }
    // erase swap page
    (void) ble_flash_page_erase(PSTORAGE_SWAP_ADDR / BLE_FLASH_PAGE_SIZE);
#ifdef SUPPORT_MODULES_LARGER_THAN_PAGE
    if (p_page_addr1 == p_page_addr2)
    {
#endif
    	// tail is in the same page as head
        tail_word_count = BLE_FLASH_PAGE_SIZE/sizeof(uint32_t) - head_word_count - body_word_count;
    	// copy of the head
        if (head_word_count)
        {
        	retval = ble_flash_block_write(p_swap_addr, p_page_addr1, head_word_count );
        	if (retval != NRF_SUCCESS)
        	{
        		app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval);
        		return retval;
        	}
        }
        // copy of the body
        retval = ble_flash_block_write(p_swap_addr+head_word_count, (uint32_t *)p_src, body_word_count);
    	if (retval != NRF_SUCCESS)
    	{
    		app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval);
    		return retval;
    	}
        // copy of the tail
        if (tail_word_count)
        {
        	retval = ble_flash_block_write(p_swap_addr+head_word_count+body_word_count, p_page_addr1+head_word_count+body_word_count, tail_word_count );
        	if (retval != NRF_SUCCESS)
        	{
        		app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval);
        		return retval;
        	}
        }
        // erase active page
        (void) ble_flash_page_erase((uint32_t)p_page_addr1 / BLE_FLASH_PAGE_SIZE);
        // restore updated page
        retval = ble_flash_block_write(p_page_addr1, p_swap_addr, BLE_FLASH_PAGE_SIZE/sizeof(uint32_t));
#ifdef SUPPORT_MODULES_LARGER_THAN_PAGE
    }
    else
    {
    	// tail is in NOT in the same page as head - need to swap twice
    	uint16_t body1_word_count =  BLE_FLASH_PAGE_SIZE/sizeof(uint32_t) - head_word_count;
    	uint16_t body2_word_count =  body_word_count - body1_word_count;
        tail_word_count = BLE_FLASH_PAGE_SIZE/sizeof(uint32_t) - body2_word_count;
        // copy head
        retval = ble_flash_block_write(p_swap_addr, p_page_addr1, head_word_count );
    	if (retval != NRF_SUCCESS)
    	{
    		app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval);
    		return retval;
    	}
        // copy body1
        retval = ble_flash_block_write(p_swap_addr, (uint32_t *)p_src, body1_word_count );
    	if (retval != NRF_SUCCESS)
    	{
    		app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval);
    		return retval;
    	}
        // erase active page
        (void) ble_flash_page_erase((uint32_t)p_page_addr1 / BLE_FLASH_PAGE_SIZE);
        // restore updated page1
        retval = ble_flash_block_write(p_page_addr1, p_swap_addr, BLE_FLASH_PAGE_SIZE/sizeof(uint32_t));
    	if (retval != NRF_SUCCESS)
    	{
    		app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval);
    		return retval;
    	}
        // erase swap page
        (void) ble_flash_page_erase(PSTORAGE_SWAP_ADDR / BLE_FLASH_PAGE_SIZE);
        // copy body2
        retval = ble_flash_block_write(p_swap_addr, (uint32_t *)p_src + body1_word_count, body2_word_count );
    	if (retval != NRF_SUCCESS)
    	{
    		app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval);
    		return retval;
    	}
        // copy tail
        retval = ble_flash_block_write(p_swap_addr, p_page_addr2+body2_word_count, tail_word_count );
    	if (retval != NRF_SUCCESS)
    	{
    		app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval);
    		return retval;
    	}
        // erase active page
        (void) ble_flash_page_erase((uint32_t)p_page_addr2 / BLE_FLASH_PAGE_SIZE);
        // restore updated page2
        retval = ble_flash_block_write(p_page_addr2, p_swap_addr, BLE_FLASH_PAGE_SIZE/sizeof(uint32_t));
    	if (retval != NRF_SUCCESS)
    	{
    		app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval);
    		return retval;
    	}
    }
#endif
    app_notify(p_dest, p_src, PSTORAGE_UPDATE_OP_CODE, size, retval);
    return retval;

}