2021-05-18 09:23:14 +00:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <stddef.h>
|
|
|
|
|
2022-04-27 15:53:48 +00:00
|
|
|
#define FURI_HAL_FLASH_OB_RAW_SIZE_BYTES 0x80
|
|
|
|
#define FURI_HAL_FLASH_OB_SIZE_WORDS (FURI_HAL_FLASH_OB_RAW_SIZE_BYTES / sizeof(uint32_t))
|
|
|
|
#define FURI_HAL_FLASH_OB_TOTAL_VALUES (FURI_HAL_FLASH_OB_SIZE_WORDS / 2)
|
|
|
|
|
|
|
|
typedef union {
|
|
|
|
uint8_t bytes[FURI_HAL_FLASH_OB_RAW_SIZE_BYTES];
|
|
|
|
union {
|
|
|
|
struct {
|
|
|
|
uint32_t base;
|
|
|
|
uint32_t complementary_value;
|
|
|
|
} values;
|
|
|
|
uint64_t dword;
|
|
|
|
} obs[FURI_HAL_FLASH_OB_TOTAL_VALUES];
|
|
|
|
} FuriHalFlashRawOptionByteData;
|
|
|
|
|
|
|
|
_Static_assert(
|
|
|
|
sizeof(FuriHalFlashRawOptionByteData) == FURI_HAL_FLASH_OB_RAW_SIZE_BYTES,
|
|
|
|
"UpdateManifestOptionByteData size error");
|
|
|
|
|
2022-04-13 20:50:25 +00:00
|
|
|
/** Init flash, applying necessary workarounds
|
|
|
|
*/
|
|
|
|
void furi_hal_flash_init();
|
|
|
|
|
2021-05-18 09:23:14 +00:00
|
|
|
/** Get flash base address
|
2021-10-03 10:36:05 +00:00
|
|
|
*
|
|
|
|
* @return pointer to flash base
|
2021-05-18 09:23:14 +00:00
|
|
|
*/
|
2021-08-08 18:03:25 +00:00
|
|
|
size_t furi_hal_flash_get_base();
|
2021-05-18 09:23:14 +00:00
|
|
|
|
|
|
|
/** Get flash read block size
|
2021-10-03 10:36:05 +00:00
|
|
|
*
|
|
|
|
* @return size in bytes
|
2021-05-18 09:23:14 +00:00
|
|
|
*/
|
2021-08-08 18:03:25 +00:00
|
|
|
size_t furi_hal_flash_get_read_block_size();
|
2021-05-18 09:23:14 +00:00
|
|
|
|
|
|
|
/** Get flash write block size
|
2021-10-03 10:36:05 +00:00
|
|
|
*
|
|
|
|
* @return size in bytes
|
2021-05-18 09:23:14 +00:00
|
|
|
*/
|
2021-08-08 18:03:25 +00:00
|
|
|
size_t furi_hal_flash_get_write_block_size();
|
2021-05-18 09:23:14 +00:00
|
|
|
|
|
|
|
/** Get flash page size
|
2021-10-03 10:36:05 +00:00
|
|
|
*
|
|
|
|
* @return size in bytes
|
2021-05-18 09:23:14 +00:00
|
|
|
*/
|
2021-08-08 18:03:25 +00:00
|
|
|
size_t furi_hal_flash_get_page_size();
|
2021-05-18 09:23:14 +00:00
|
|
|
|
|
|
|
/** Get expected flash cycles count
|
2021-10-03 10:36:05 +00:00
|
|
|
*
|
|
|
|
* @return count of erase-write operations
|
2021-05-18 09:23:14 +00:00
|
|
|
*/
|
2021-08-08 18:03:25 +00:00
|
|
|
size_t furi_hal_flash_get_cycles_count();
|
2021-05-18 09:23:14 +00:00
|
|
|
|
|
|
|
/** Get free flash start address
|
2021-10-03 10:36:05 +00:00
|
|
|
*
|
|
|
|
* @return pointer to free region start
|
2021-05-18 09:23:14 +00:00
|
|
|
*/
|
2021-08-08 18:03:25 +00:00
|
|
|
const void* furi_hal_flash_get_free_start_address();
|
2021-05-18 09:23:14 +00:00
|
|
|
|
|
|
|
/** Get free flash end address
|
2021-10-03 10:36:05 +00:00
|
|
|
*
|
|
|
|
* @return pointer to free region end
|
2021-05-18 09:23:14 +00:00
|
|
|
*/
|
2021-08-08 18:03:25 +00:00
|
|
|
const void* furi_hal_flash_get_free_end_address();
|
2021-05-18 09:23:14 +00:00
|
|
|
|
|
|
|
/** Get first free page start address
|
2021-10-03 10:36:05 +00:00
|
|
|
*
|
|
|
|
* @return first free page memory address
|
2021-05-18 09:23:14 +00:00
|
|
|
*/
|
2021-08-08 18:03:25 +00:00
|
|
|
size_t furi_hal_flash_get_free_page_start_address();
|
2021-05-18 09:23:14 +00:00
|
|
|
|
|
|
|
/** Get free page count
|
2021-10-03 10:36:05 +00:00
|
|
|
*
|
|
|
|
* @return free page count
|
2021-05-18 09:23:14 +00:00
|
|
|
*/
|
2021-08-08 18:03:25 +00:00
|
|
|
size_t furi_hal_flash_get_free_page_count();
|
2021-05-18 09:23:14 +00:00
|
|
|
|
2021-10-03 10:36:05 +00:00
|
|
|
/** Erase Flash
|
|
|
|
*
|
2022-04-27 15:53:48 +00:00
|
|
|
* @warning locking operation with critical section, stalls execution
|
2021-10-03 10:36:05 +00:00
|
|
|
*
|
2021-11-10 09:53:00 +00:00
|
|
|
* @param page The page to erase
|
2021-10-03 10:36:05 +00:00
|
|
|
*
|
|
|
|
* @return true on success
|
2021-05-18 09:23:14 +00:00
|
|
|
*/
|
2021-11-10 09:53:00 +00:00
|
|
|
bool furi_hal_flash_erase(uint8_t page);
|
2021-05-18 09:23:14 +00:00
|
|
|
|
2021-10-03 10:36:05 +00:00
|
|
|
/** Write double word (64 bits)
|
|
|
|
*
|
2022-04-27 15:53:48 +00:00
|
|
|
* @warning locking operation with critical section, stalls execution
|
2021-10-03 10:36:05 +00:00
|
|
|
*
|
|
|
|
* @param address destination address, must be double word aligned.
|
|
|
|
* @param data data to write
|
|
|
|
*
|
|
|
|
* @return true on success
|
2021-05-18 09:23:14 +00:00
|
|
|
*/
|
2021-08-08 18:03:25 +00:00
|
|
|
bool furi_hal_flash_write_dword(size_t address, uint64_t data);
|
2022-04-13 20:50:25 +00:00
|
|
|
|
|
|
|
/** Write aligned page data (up to page size)
|
|
|
|
*
|
2022-04-27 15:53:48 +00:00
|
|
|
* @warning locking operation with critical section, stalls execution
|
2022-04-13 20:50:25 +00:00
|
|
|
*
|
|
|
|
* @param address destination address, must be page aligned.
|
|
|
|
* @param data data to write
|
|
|
|
* @param length data length
|
|
|
|
*
|
|
|
|
* @return true on success
|
|
|
|
*/
|
|
|
|
bool furi_hal_flash_program_page(const uint8_t page, const uint8_t* data, uint16_t length);
|
|
|
|
|
|
|
|
/** Get flash page number for address
|
|
|
|
*
|
|
|
|
* @return page number, -1 for invalid address
|
|
|
|
*/
|
2022-04-27 15:53:48 +00:00
|
|
|
int16_t furi_hal_flash_get_page_number(size_t address);
|
|
|
|
|
|
|
|
/** Writes OB word, using non-compl. index of register in Flash, OPTION_BYTE_BASE
|
|
|
|
*
|
|
|
|
* @warning locking operation with critical section, stalls execution
|
|
|
|
*
|
|
|
|
* @param word_idx OB word number
|
|
|
|
* @param value data to write
|
|
|
|
* @return true if value was written, false for read-only word
|
|
|
|
*/
|
|
|
|
bool furi_hal_flash_ob_set_word(size_t word_idx, const uint32_t value);
|
2022-04-13 20:50:25 +00:00
|
|
|
|
2022-04-27 15:53:48 +00:00
|
|
|
/** Forces a reload of OB data from flash to registers
|
|
|
|
*
|
|
|
|
* @warning Initializes system restart
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
void furi_hal_flash_ob_apply();
|
|
|
|
|
|
|
|
/** Get raw OB storage data
|
|
|
|
*
|
|
|
|
* @return pointer to read-only data of OB (raw + complementary values)
|
|
|
|
*/
|
|
|
|
const FuriHalFlashRawOptionByteData* furi_hal_flash_ob_get_raw_ptr();
|