[FL-3629] fbt: reworked assets & resources handling (#3160)

* fbt: reworking targets & assets handling WIP
* fbt: dist fixes
* fbt: moved SD card resources to owning apps
* unit_tests: moved resources to app folder
* github: updated unit_tests paths
* github: packaging fixes
* unit_tests: fixes
* fbt: assets: internal cleanup
* fbt: reworked assets handling
* github: unit_tests: reintroducing fixes
* minor cleanup
* fbt: naming changes to reflect private nature of scons tools
* fbt: resources: fixed dist archive paths
* docs: updated paths
* docs: updated more paths
* docs: included "resources" parameter in app manifest docs; updated assets readme
* updated gitignore for assets
* github: updated action versions
* unit_tests: restored timeout; scripts: assets: logging changes
* gh: don't upload desktop animations for unit test run

Co-authored-by: あく <alleteam@gmail.com>
This commit is contained in:
hedger
2023-10-31 00:17:30 +09:00
committed by GitHub
co-authored by あく
parent 176fb21f5f
commit 917410a0a8
345 changed files with 466 additions and 394 deletions
+65
View File
@@ -0,0 +1,65 @@
/**
* @file furi_hal.h
* Furi HAL API
*/
#pragma once
#ifdef __cplusplus
template <unsigned int N>
struct STOP_EXTERNING_ME {};
#endif
#include <furi_hal_cortex.h>
#include <furi_hal_clock.h>
#include <furi_hal_bus.h>
#include <furi_hal_crypto.h>
#include <furi_hal_console.h>
#include <furi_hal_debug.h>
#include <furi_hal_dma.h>
#include <furi_hal_os.h>
#include <furi_hal_sd.h>
#include <furi_hal_i2c.h>
#include <furi_hal_region.h>
#include <furi_hal_resources.h>
#include <furi_hal_rtc.h>
#include <furi_hal_speaker.h>
#include <furi_hal_gpio.h>
#include <furi_hal_light.h>
#include <furi_hal_power.h>
#include <furi_hal_interrupt.h>
#include <furi_hal_version.h>
#include <furi_hal_bt.h>
#include <furi_hal_spi.h>
#include <furi_hal_flash.h>
#include <furi_hal_vibro.h>
#include <furi_hal_usb.h>
#include <furi_hal_usb_hid.h>
#include <furi_hal_usb_ccid.h>
#include <furi_hal_uart.h>
#include <furi_hal_info.h>
#include <furi_hal_random.h>
#include <furi_hal_target_hw.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Early FuriHal init, only essential subsystems */
void furi_hal_init_early();
/** Early FuriHal deinit */
void furi_hal_deinit_early();
/** Init FuriHal */
void furi_hal_init();
/** Transfer execution to address
*
* @param[in] address pointer to new executable
*/
void furi_hal_switch(void* address);
#ifdef __cplusplus
}
#endif
+242
View File
@@ -0,0 +1,242 @@
/**
* @file furi_hal_bt.h
* BT/BLE HAL API
*/
#pragma once
#include <furi.h>
#include <stdbool.h>
#include <gap.h>
#include <services/serial_service.h>
#include <ble_glue.h>
#include <ble_app.h>
#include <furi_hal_bt_serial.h>
#define FURI_HAL_BT_STACK_VERSION_MAJOR (1)
#define FURI_HAL_BT_STACK_VERSION_MINOR (12)
#define FURI_HAL_BT_C2_START_TIMEOUT 1000
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
FuriHalBtStackUnknown,
FuriHalBtStackLight,
FuriHalBtStackFull,
} FuriHalBtStack;
typedef enum {
FuriHalBtProfileSerial,
FuriHalBtProfileHidKeyboard,
// Keep last for Profiles number calculation
FuriHalBtProfileNumber,
} FuriHalBtProfile;
/** Initialize
*/
void furi_hal_bt_init();
/** Lock core2 state transition */
void furi_hal_bt_lock_core2();
/** Lock core2 state transition */
void furi_hal_bt_unlock_core2();
/** Start radio stack
*
* @return true on successfull radio stack start
*/
bool furi_hal_bt_start_radio_stack();
/** Get radio stack type
*
* @return FuriHalBtStack instance
*/
FuriHalBtStack furi_hal_bt_get_radio_stack();
/** Check if radio stack supports BLE GAT/GAP
*
* @return true if supported
*/
bool furi_hal_bt_is_ble_gatt_gap_supported();
/** Check if radio stack supports testing
*
* @return true if supported
*/
bool furi_hal_bt_is_testing_supported();
/** Start BLE app
*
* @param profile FuriHalBtProfile instance
* @param event_cb GapEventCallback instance
* @param context pointer to context
*
* @return true on success
*/
bool furi_hal_bt_start_app(FuriHalBtProfile profile, GapEventCallback event_cb, void* context);
/** Reinitialize core2
*
* Also can be used to prepare core2 for stop modes
*/
void furi_hal_bt_reinit();
/** Change BLE app
* Restarts 2nd core
*
* @param profile FuriHalBtProfile instance
* @param event_cb GapEventCallback instance
* @param context pointer to context
*
* @return true on success
*/
bool furi_hal_bt_change_app(FuriHalBtProfile profile, GapEventCallback event_cb, void* context);
/** Update battery level
*
* @param battery_level battery level
*/
void furi_hal_bt_update_battery_level(uint8_t battery_level);
/** Update battery power state */
void furi_hal_bt_update_power_state();
/** Checks if BLE state is active
*
* @return true if device is connected or advertising, false otherwise
*/
bool furi_hal_bt_is_active();
/** Start advertising
*/
void furi_hal_bt_start_advertising();
/** Stop advertising
*/
void furi_hal_bt_stop_advertising();
/** Get BT/BLE system component state
*
* @param[in] buffer FuriString* buffer to write to
*/
void furi_hal_bt_dump_state(FuriString* buffer);
/** Get BT/BLE system component state
*
* @return true if core2 is alive
*/
bool furi_hal_bt_is_alive();
/** Get key storage buffer address and size
*
* @param key_buff_addr pointer to store buffer address
* @param key_buff_size pointer to store buffer size
*/
void furi_hal_bt_get_key_storage_buff(uint8_t** key_buff_addr, uint16_t* key_buff_size);
/** Get SRAM2 hardware semaphore
* @note Must be called before SRAM2 read/write operations
*/
void furi_hal_bt_nvm_sram_sem_acquire();
/** Release SRAM2 hardware semaphore
* @note Must be called after SRAM2 read/write operations
*/
void furi_hal_bt_nvm_sram_sem_release();
/** Clear key storage
*
* @return true on success
*/
bool furi_hal_bt_clear_white_list();
/** Set key storage change callback
*
* @param callback BleGlueKeyStorageChangedCallback instance
* @param context pointer to context
*/
void furi_hal_bt_set_key_storage_change_callback(
BleGlueKeyStorageChangedCallback callback,
void* context);
/** Start ble tone tx at given channel and power
*
* @param[in] channel The channel
* @param[in] power The power
*/
void furi_hal_bt_start_tone_tx(uint8_t channel, uint8_t power);
/** Stop ble tone tx
*/
void furi_hal_bt_stop_tone_tx();
/** Start sending ble packets at a given frequency and datarate
*
* @param[in] channel The channel
* @param[in] pattern The pattern
* @param[in] datarate The datarate
*/
void furi_hal_bt_start_packet_tx(uint8_t channel, uint8_t pattern, uint8_t datarate);
/** Stop sending ble packets
*
* @return sent packet count
*/
uint16_t furi_hal_bt_stop_packet_test();
/** Start receiving packets
*
* @param[in] channel RX channel
* @param[in] datarate Datarate
*/
void furi_hal_bt_start_packet_rx(uint8_t channel, uint8_t datarate);
/** Set up the RF to listen to a given RF channel
*
* @param[in] channel RX channel
*/
void furi_hal_bt_start_rx(uint8_t channel);
/** Stop RF listenning
*/
void furi_hal_bt_stop_rx();
/** Get RSSI
*
* @return RSSI in dBm
*/
float furi_hal_bt_get_rssi();
/** Get number of transmitted packets
*
* @return packet count
*/
uint32_t furi_hal_bt_get_transmitted_packets();
/** Check & switch C2 to given mode
*
* @param[in] mode mode to switch into
*/
bool furi_hal_bt_ensure_c2_mode(BleGlueC2Mode mode);
typedef struct {
uint32_t magic;
uint32_t source_pc;
uint32_t source_lr;
uint32_t source_sp;
} FuriHalBtHardfaultInfo;
/** Get hardfault info
*
* @return hardfault info. NULL if no hardfault
*/
const FuriHalBtHardfaultInfo* furi_hal_bt_get_hardfault_info();
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,91 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Start Hid Keyboard Profile
*/
void furi_hal_bt_hid_start();
/** Stop Hid Keyboard Profile
*/
void furi_hal_bt_hid_stop();
/** Press keyboard button
*
* @param button button code from HID specification
*
* @return true on success
*/
bool furi_hal_bt_hid_kb_press(uint16_t button);
/** Release keyboard button
*
* @param button button code from HID specification
*
* @return true on success
*/
bool furi_hal_bt_hid_kb_release(uint16_t button);
/** Release all keyboard buttons
*
* @return true on success
*/
bool furi_hal_bt_hid_kb_release_all();
/** Set mouse movement and send HID report
*
* @param dx x coordinate delta
* @param dy y coordinate delta
*/
bool furi_hal_bt_hid_mouse_move(int8_t dx, int8_t dy);
/** Set mouse button to pressed state and send HID report
*
* @param button key code
*/
bool furi_hal_bt_hid_mouse_press(uint8_t button);
/** Set mouse button to released state and send HID report
*
* @param button key code
*/
bool furi_hal_bt_hid_mouse_release(uint8_t button);
/** Set mouse button to released state and send HID report
*
* @param button key code
*/
bool furi_hal_bt_hid_mouse_release_all();
/** Set mouse wheel position and send HID report
*
* @param delta number of scroll steps
*/
bool furi_hal_bt_hid_mouse_scroll(int8_t delta);
/** Set the following consumer key to pressed state and send HID report
*
* @param button key code
*/
bool furi_hal_bt_hid_consumer_key_press(uint16_t button);
/** Set the following consumer key to released state and send HID report
*
* @param button key code
*/
bool furi_hal_bt_hid_consumer_key_release(uint16_t button);
/** Set consumer key to released state and send HID report
*
* @param button key code
*/
bool furi_hal_bt_hid_consumer_key_release_all();
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,59 @@
#pragma once
#include <services/serial_service.h>
#ifdef __cplusplus
extern "C" {
#endif
#define FURI_HAL_BT_SERIAL_PACKET_SIZE_MAX SERIAL_SVC_DATA_LEN_MAX
typedef enum {
FuriHalBtSerialRpcStatusNotActive,
FuriHalBtSerialRpcStatusActive,
} FuriHalBtSerialRpcStatus;
/** Serial service callback type */
typedef SerialServiceEventCallback FuriHalBtSerialCallback;
/** Start Serial Profile
*/
void furi_hal_bt_serial_start();
/** Stop Serial Profile
*/
void furi_hal_bt_serial_stop();
/** Set Serial service events callback
*
* @param buffer_size Applicaition buffer size
* @param calback FuriHalBtSerialCallback instance
* @param context pointer to context
*/
void furi_hal_bt_serial_set_event_callback(
uint16_t buff_size,
FuriHalBtSerialCallback callback,
void* context);
/** Set BLE RPC status
*
* @param status FuriHalBtSerialRpcStatus instance
*/
void furi_hal_bt_serial_set_rpc_status(FuriHalBtSerialRpcStatus status);
/** Notify that application buffer is empty
*/
void furi_hal_bt_serial_notify_buffer_is_empty();
/** Send data through BLE
*
* @param data data buffer
* @param size data buffer size
*
* @return true on success
*/
bool furi_hal_bt_serial_tx(uint8_t* data, uint16_t size);
#ifdef __cplusplus
}
#endif
+108
View File
@@ -0,0 +1,108 @@
/**
* @file furi_hal_cortex.h
* ARM Cortex HAL
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Cortex timer provides high precision low level expiring timer */
typedef struct {
uint32_t start;
uint32_t value;
} FuriHalCortexTimer;
/** Early init stage for cortex
*/
void furi_hal_cortex_init_early();
/** Microseconds delay
*
* @param[in] microseconds The microseconds to wait
*/
void furi_hal_cortex_delay_us(uint32_t microseconds);
/** Get instructions per microsecond count
*
* @return instructions per microsecond count
*/
uint32_t furi_hal_cortex_instructions_per_microsecond();
/** Get Timer
*
* @param[in] timeout_us The expire timeout in us
*
* @return The FuriHalCortexTimer
*/
FuriHalCortexTimer furi_hal_cortex_timer_get(uint32_t timeout_us);
/** Check if timer expired
*
* @param[in] cortex_timer The FuriHalCortexTimer
*
* @return true if expired
*/
bool furi_hal_cortex_timer_is_expired(FuriHalCortexTimer cortex_timer);
/** Wait for timer expire
*
* @param[in] cortex_timer The FuriHalCortexTimer
*/
void furi_hal_cortex_timer_wait(FuriHalCortexTimer cortex_timer);
typedef enum {
FuriHalCortexComp0,
FuriHalCortexComp1,
FuriHalCortexComp2,
FuriHalCortexComp3,
} FuriHalCortexComp;
typedef enum {
FuriHalCortexCompSizeWord = 0b10,
FuriHalCortexCompSizeHalfWord = 0b01,
FuriHalCortexCompSizeByte = 0b00,
} FuriHalCortexCompSize;
typedef enum {
FuriHalCortexCompFunctionPC = 0b100,
FuriHalCortexCompFunctionRead = 0b101,
FuriHalCortexCompFunctionWrite = 0b110,
FuriHalCortexCompFunctionReadWrite = 0b110,
} FuriHalCortexCompFunction;
/** Enable DWT comparator
*
* Allows to programmatically set instruction/data breakpoints.
*
* More details on how it works can be found in armv7m official documentation:
* https://developer.arm.com/documentation/ddi0403/d/Debug-Architecture/ARMv7-M-Debug/The-Data-Watchpoint-and-Trace-unit/The-DWT-comparators
* https://developer.arm.com/documentation/ddi0403/d/Debug-Architecture/ARMv7-M-Debug/The-Data-Watchpoint-and-Trace-unit/Comparator-Function-registers--DWT-FUNCTIONn
*
* @param[in] comp The Comparator
* @param[in] function The Comparator Function to use
* @param[in] value The value
* @param[in] mask The mask
* @param[in] size The size
*/
void furi_hal_cortex_comp_enable(
FuriHalCortexComp comp,
FuriHalCortexCompFunction function,
uint32_t value,
uint32_t mask,
FuriHalCortexCompSize size);
/** Reset DWT comparator
*
* @param[in] comp The Comparator
*/
void furi_hal_cortex_comp_reset(FuriHalCortexComp comp);
#ifdef __cplusplus
}
#endif
+295
View File
@@ -0,0 +1,295 @@
/**
* @file furi_hal_crypto.h
*
* Cryptography HAL API
*
* !!! READ THIS FIRST !!!
*
* Flipper was never designed to be secure, nor it passed cryptography audit.
* Despite of the fact that keys are stored in secure enclave there are some
* types of attack that can be performed against AES engine to recover
* keys(theoretical). Also there is no way to securely deliver user keys to
* device and never will be. In addition device is fully open and there is no
* way to guarantee safety of your data, it can be easily dumped with debugger
* or modified code.
*
* Secure enclave on WB series is implemented on core2 FUS side and can be used
* only if core2 alive. Enclave is responsible for storing, loading and
* unloading keys to and from enclave/AES in secure manner(AES engine key
* registers will be locked when key from enclave loaded)
*
* There are 11 keys that we provision at factory:
* - 0 - Master key for secure key delivery. Impossible to use for anything but
* key provisioning. We don't plan to use it too.
* - 1 - 10 - Keys used by firmware. All devices got the same set of keys. You
* also can use them in your applications.
*
* Also there is a slot 11 that we use for device unique key. This slot is
* intentionally left blank till the moment of first use, so you can ensure that
* we don't know your unique key. Also you can provision this key by your self
* with crypto cli or API.
*
* Other slots can be used for your needs. But since enclave is sequential
* append only, we can not guarantee you that slots you want are free. NEVER USE
* THEM FOR PUBLIC APPLICATIONS.
*
* Also you can directly load raw keys into AES engine and use it for your
* needs.
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Factory provisioned master key slot. Should never be used. */
#define FURI_HAL_CRYPTO_ENCLAVE_MASTER_KEY_SLOT (0u)
/** Factory provisioned keys slot range. All of them are exactly same on all flippers. */
#define FURI_HAL_CRYPTO_ENCLAVE_FACTORY_KEY_SLOT_START (1u)
#define FURI_HAL_CRYPTO_ENCLAVE_FACTORY_KEY_SLOT_END (10u)
/** Device unique key slot. This key generated on first use or provisioned by user. Use furi_hal_crypto_enclave_ensure_key before using this slot. */
#define FURI_HAL_CRYPTO_ENCLAVE_UNIQUE_KEY_SLOT (11u)
/** User key slot range. This slots can be used for your needs, but never use them in public apps. */
#define FURI_HAL_CRYPTO_ENCLAVE_USER_KEY_SLOT_START (12u)
#define FURI_HAL_CRYPTO_ENCLAVE_USER_KEY_SLOT_END (100u)
/** [Deprecated] Indicates availability of advanced crypto functions, will be dropped before v1.0 */
#define FURI_HAL_CRYPTO_ADVANCED_AVAIL 1
/** FuriHalCryptoKey Type */
typedef enum {
FuriHalCryptoKeyTypeMaster, /**< Master key */
FuriHalCryptoKeyTypeSimple, /**< Simple unencrypted key */
FuriHalCryptoKeyTypeEncrypted, /**< Encrypted with Master key */
} FuriHalCryptoKeyType;
/** FuriHalCryptoKey Size in bits */
typedef enum {
FuriHalCryptoKeySize128,
FuriHalCryptoKeySize256,
} FuriHalCryptoKeySize;
/** FuriHalCryptoKey */
typedef struct {
FuriHalCryptoKeyType type;
FuriHalCryptoKeySize size;
uint8_t* data;
} FuriHalCryptoKey;
/** FuriHalCryptoGCMState Result of a GCM operation */
typedef enum {
FuriHalCryptoGCMStateOk, /**< operation successful */
FuriHalCryptoGCMStateError, /**< error during encryption/decryption */
FuriHalCryptoGCMStateAuthFailure, /**< tags do not match, auth failed */
} FuriHalCryptoGCMState;
/** Initialize cryptography layer(includes AES engines, PKA and RNG) */
void furi_hal_crypto_init();
/** Verify factory provisioned keys
*
* @param keys_nb The keys number of
* @param valid_keys_nb The valid keys number of
*
* @return true if all enclave keys are intact, false otherwise
*/
bool furi_hal_crypto_enclave_verify(uint8_t* keys_nb, uint8_t* valid_keys_nb);
/** Ensure that requested slot and slots before this slot contains keys.
*
* This function is used to provision FURI_HAL_CRYPTO_ENCLAVE_UNIQUE_KEY_SLOT. Also you
* may want to use it to generate some unique keys in user key slot range.
*
* @warning Because of the sequential nature of the secure enclave this
* method will generate key for all slots from
* FURI_HAL_CRYPTO_ENCLAVE_FACTORY_KEY_SLOT_END to the slot your requested.
* Keys are generated using on-chip RNG.
*
* @param[in] key_slot The key slot to enclave
*
* @return true if key exists or created, false if enclave corrupted
*/
bool furi_hal_crypto_enclave_ensure_key(uint8_t key_slot);
/** Store key in crypto enclave
*
* @param key FuriHalCryptoKey to be stored
* @param slot pointer to int where enclave slot will be stored
*
* @return true on success
*/
bool furi_hal_crypto_enclave_store_key(FuriHalCryptoKey* key, uint8_t* slot);
/** Init AES engine and load key from crypto enclave
*
* @warning Use only with furi_hal_crypto_enclave_unload_key()
*
* @param slot enclave slot
* @param[in] iv pointer to 16 bytes Initialization Vector data
*
* @return true on success
*/
bool furi_hal_crypto_enclave_load_key(uint8_t slot, const uint8_t* iv);
/** Unload key and deinit AES engine
*
* @warning Use only with furi_hal_crypto_enclave_load_key()
*
* @param slot enclave slot
*
* @return true on success
*/
bool furi_hal_crypto_enclave_unload_key(uint8_t slot);
/** Init AES engine and load supplied key
*
* @warning Use only with furi_hal_crypto_unload_key()
*
* @param[in] key pointer to 32 bytes key data
* @param[in] iv pointer to 16 bytes Initialization Vector data
*
* @return true on success
*/
bool furi_hal_crypto_load_key(const uint8_t* key, const uint8_t* iv);
/** Unload key and de-init AES engine
*
* @warning Use this function only with furi_hal_crypto_load_key()
*
* @return true on success
*/
bool furi_hal_crypto_unload_key(void);
/** Encrypt data
*
* @param input pointer to input data
* @param output pointer to output data
* @param size input/output buffer size in bytes
*
* @return true on success
*/
bool furi_hal_crypto_encrypt(const uint8_t* input, uint8_t* output, size_t size);
/** Decrypt data
*
* @param input pointer to input data
* @param output pointer to output data
* @param size input/output buffer size in bytes
*
* @return true on success
*/
bool furi_hal_crypto_decrypt(const uint8_t* input, uint8_t* output, size_t size);
/** Encrypt the input using AES-CTR
*
* Decryption can be performed by supplying the ciphertext as input. Inits and
* deinits the AES engine internally.
*
* @param[in] key pointer to 32 bytes key data
* @param[in] iv pointer to 12 bytes Initialization Vector data
* @param[in] input pointer to input data
* @param[out] output pointer to output data
* @param length length of the input and output in bytes
*
* @return true on success
*/
bool furi_hal_crypto_ctr(
const uint8_t* key,
const uint8_t* iv,
const uint8_t* input,
uint8_t* output,
size_t length);
/** Encrypt/decrypt the input using AES-GCM
*
* When decrypting the tag generated needs to be compared to the tag attached to
* the ciphertext in a constant-time fashion. If the tags are not equal, the
* decryption failed and the plaintext returned needs to be discarded. Inits and
* deinits the AES engine internally.
*
* @param[in] key pointer to 32 bytes key data
* @param[in] iv pointer to 12 bytes Initialization Vector data
* @param[in] aad pointer to additional authentication data
* @param aad_length length of the additional authentication data in bytes
* @param[in] input pointer to input data
* @param[out] output pointer to output data
* @param length length of the input and output in bytes
* @param[out] tag pointer to 16 bytes space for the tag
* @param decrypt true for decryption, false otherwise
*
* @return true on success
*/
bool furi_hal_crypto_gcm(
const uint8_t* key,
const uint8_t* iv,
const uint8_t* aad,
size_t aad_length,
const uint8_t* input,
uint8_t* output,
size_t length,
uint8_t* tag,
bool decrypt);
/** Encrypt the input using AES-GCM and generate a tag
*
* Inits and deinits the AES engine internally.
*
* @param[in] key pointer to 32 bytes key data
* @param[in] iv pointer to 12 bytes Initialization Vector data
* @param[in] aad pointer to additional authentication data
* @param aad_length length of the additional authentication data in bytes
* @param[in] input pointer to input data
* @param[out] output pointer to output data
* @param length length of the input and output in bytes
* @param[out] tag pointer to 16 bytes space for the tag
*
* @return FuriHalCryptoGCMStateOk on success, FuriHalCryptoGCMStateError on
* failure
*/
FuriHalCryptoGCMState furi_hal_crypto_gcm_encrypt_and_tag(
const uint8_t* key,
const uint8_t* iv,
const uint8_t* aad,
size_t aad_length,
const uint8_t* input,
uint8_t* output,
size_t length,
uint8_t* tag);
/** Decrypt the input using AES-GCM and verify the provided tag
*
* Inits and deinits the AES engine internally.
*
* @param[in] key pointer to 32 bytes key data
* @param[in] iv pointer to 12 bytes Initialization Vector data
* @param[in] aad pointer to additional authentication data
* @param aad_length length of the additional authentication data in bytes
* @param[in] input pointer to input data
* @param[out] output pointer to output data
* @param length length of the input and output in bytes
* @param[out] tag pointer to 16 bytes tag
*
* @return FuriHalCryptoGCMStateOk on success, FuriHalCryptoGCMStateError on
* failure, FuriHalCryptoGCMStateAuthFailure if the tag does not
* match
*/
FuriHalCryptoGCMState furi_hal_crypto_gcm_decrypt_and_verify(
const uint8_t* key,
const uint8_t* iv,
const uint8_t* aad,
size_t aad_length,
const uint8_t* input,
uint8_t* output,
size_t length,
const uint8_t* tag);
#ifdef __cplusplus
}
#endif
+26
View File
@@ -0,0 +1,26 @@
/**
* @file furi_hal_debug.h
* Debug HAL API
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Enable MCU debug */
void furi_hal_debug_enable();
/** Disable MCU debug */
void furi_hal_debug_disable();
/** Check if GDB debug session is active */
bool furi_hal_debug_is_gdb_session_active();
#ifdef __cplusplus
}
#endif
+287
View File
@@ -0,0 +1,287 @@
/**
* @file furi_hal_i2c.h I2C HAL API
*/
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <furi_hal_i2c_config.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Transaction beginning signal */
typedef enum {
/*!Begin the transaction by sending a START condition followed by the
* address */
FuriHalI2cBeginStart,
/*!Begin the transaction by sending a RESTART condition followed by the
* address
* @note Must follow a transaction ended with
* FuriHalI2cEndAwaitRestart */
FuriHalI2cBeginRestart,
/*!Continue the previous transaction with new data
* @note Must follow a transaction ended with FuriHalI2cEndPause and
* be of the same type (RX/TX) */
FuriHalI2cBeginResume,
} FuriHalI2cBegin;
/** Transaction end signal */
typedef enum {
/*!End the transaction by sending a STOP condition */
FuriHalI2cEndStop,
/*!End the transaction by clock stretching
* @note Must be followed by a transaction using
* FuriHalI2cBeginRestart */
FuriHalI2cEndAwaitRestart,
/*!Pauses the transaction by clock stretching
* @note Must be followed by a transaction using FuriHalI2cBeginResume */
FuriHalI2cEndPause,
} FuriHalI2cEnd;
/** Early Init I2C */
void furi_hal_i2c_init_early();
/** Early DeInit I2C */
void furi_hal_i2c_deinit_early();
/** Init I2C */
void furi_hal_i2c_init();
/** Acquire I2C bus handle
*
* @param handle Pointer to FuriHalI2cBusHandle instance
*/
void furi_hal_i2c_acquire(FuriHalI2cBusHandle* handle);
/** Release I2C bus handle
*
* @param handle Pointer to FuriHalI2cBusHandle instance acquired in
* `furi_hal_i2c_acquire`
*/
void furi_hal_i2c_release(FuriHalI2cBusHandle* handle);
/** Perform I2C TX transfer
*
* @param handle Pointer to FuriHalI2cBusHandle instance
* @param address I2C slave address
* @param data Pointer to data buffer
* @param size Size of data buffer
* @param timeout Timeout in milliseconds
*
* @return true on successful transfer, false otherwise
*/
bool furi_hal_i2c_tx(
FuriHalI2cBusHandle* handle,
uint8_t address,
const uint8_t* data,
size_t size,
uint32_t timeout);
/**
* Perform I2C TX transfer, with additional settings.
*
* @param handle Pointer to FuriHalI2cBusHandle instance
* @param address I2C slave address
* @param ten_bit Whether the address is 10 bits wide
* @param data Pointer to data buffer
* @param size Size of data buffer
* @param begin How to begin the transaction
* @param end How to end the transaction
* @param timer Timeout timer
*
* @return true on successful transfer, false otherwise
*/
bool furi_hal_i2c_tx_ext(
FuriHalI2cBusHandle* handle,
uint16_t address,
bool ten_bit,
const uint8_t* data,
size_t size,
FuriHalI2cBegin begin,
FuriHalI2cEnd end,
uint32_t timeout);
/** Perform I2C RX transfer
*
* @param handle Pointer to FuriHalI2cBusHandle instance
* @param address I2C slave address
* @param data Pointer to data buffer
* @param size Size of data buffer
* @param timeout Timeout in milliseconds
*
* @return true on successful transfer, false otherwise
*/
bool furi_hal_i2c_rx(
FuriHalI2cBusHandle* handle,
uint8_t address,
uint8_t* data,
size_t size,
uint32_t timeout);
/** Perform I2C RX transfer, with additional settings.
*
* @param handle Pointer to FuriHalI2cBusHandle instance
* @param address I2C slave address
* @param ten_bit Whether the address is 10 bits wide
* @param data Pointer to data buffer
* @param size Size of data buffer
* @param begin How to begin the transaction
* @param end How to end the transaction
* @param timer Timeout timer
*
* @return true on successful transfer, false otherwise
*/
bool furi_hal_i2c_rx_ext(
FuriHalI2cBusHandle* handle,
uint16_t address,
bool ten_bit,
uint8_t* data,
size_t size,
FuriHalI2cBegin begin,
FuriHalI2cEnd end,
uint32_t timeout);
/** Perform I2C TX and RX transfers
*
* @param handle Pointer to FuriHalI2cBusHandle instance
* @param address I2C slave address
* @param tx_data Pointer to TX data buffer
* @param tx_size Size of TX data buffer
* @param rx_data Pointer to RX data buffer
* @param rx_size Size of RX data buffer
* @param timeout Timeout in milliseconds
*
* @return true on successful transfer, false otherwise
*/
bool furi_hal_i2c_trx(
FuriHalI2cBusHandle* handle,
uint8_t address,
const uint8_t* tx_data,
size_t tx_size,
uint8_t* rx_data,
size_t rx_size,
uint32_t timeout);
/** Check if I2C device presents on bus
*
* @param handle Pointer to FuriHalI2cBusHandle instance
* @param i2c_addr I2C slave address
* @param timeout Timeout in milliseconds
*
* @return true if device present and is ready, false otherwise
*/
bool furi_hal_i2c_is_device_ready(FuriHalI2cBusHandle* handle, uint8_t i2c_addr, uint32_t timeout);
/** Perform I2C device register read (8-bit)
*
* @param handle Pointer to FuriHalI2cBusHandle instance
* @param i2c_addr I2C slave address
* @param reg_addr Register address
* @param data Pointer to register value
* @param timeout Timeout in milliseconds
*
* @return true on successful transfer, false otherwise
*/
bool furi_hal_i2c_read_reg_8(
FuriHalI2cBusHandle* handle,
uint8_t i2c_addr,
uint8_t reg_addr,
uint8_t* data,
uint32_t timeout);
/** Perform I2C device register read (16-bit)
*
* @param handle Pointer to FuriHalI2cBusHandle instance
* @param i2c_addr I2C slave address
* @param reg_addr Register address
* @param data Pointer to register value
* @param timeout Timeout in milliseconds
*
* @return true on successful transfer, false otherwise
*/
bool furi_hal_i2c_read_reg_16(
FuriHalI2cBusHandle* handle,
uint8_t i2c_addr,
uint8_t reg_addr,
uint16_t* data,
uint32_t timeout);
/** Perform I2C device memory read
*
* @param handle Pointer to FuriHalI2cBusHandle instance
* @param i2c_addr I2C slave address
* @param mem_addr Memory start address
* @param data Pointer to data buffer
* @param len Size of data buffer
* @param timeout Timeout in milliseconds
*
* @return true on successful transfer, false otherwise
*/
bool furi_hal_i2c_read_mem(
FuriHalI2cBusHandle* handle,
uint8_t i2c_addr,
uint8_t mem_addr,
uint8_t* data,
size_t len,
uint32_t timeout);
/** Perform I2C device register write (8-bit)
*
* @param handle Pointer to FuriHalI2cBusHandle instance
* @param i2c_addr I2C slave address
* @param reg_addr Register address
* @param data Register value
* @param timeout Timeout in milliseconds
*
* @return true on successful transfer, false otherwise
*/
bool furi_hal_i2c_write_reg_8(
FuriHalI2cBusHandle* handle,
uint8_t i2c_addr,
uint8_t reg_addr,
uint8_t data,
uint32_t timeout);
/** Perform I2C device register write (16-bit)
*
* @param handle Pointer to FuriHalI2cBusHandle instance
* @param i2c_addr I2C slave address
* @param reg_addr Register address
* @param data Register value
* @param timeout Timeout in milliseconds
*
* @return true on successful transfer, false otherwise
*/
bool furi_hal_i2c_write_reg_16(
FuriHalI2cBusHandle* handle,
uint8_t i2c_addr,
uint8_t reg_addr,
uint16_t data,
uint32_t timeout);
/** Perform I2C device memory
*
* @param handle Pointer to FuriHalI2cBusHandle instance
* @param i2c_addr I2C slave address
* @param mem_addr Memory start address
* @param data Pointer to data buffer
* @param len Size of data buffer
* @param timeout Timeout in milliseconds
*
* @return true on successful transfer, false otherwise
*/
bool furi_hal_i2c_write_mem(
FuriHalI2cBusHandle* handle,
uint8_t i2c_addr,
uint8_t mem_addr,
const uint8_t* data,
size_t len,
uint32_t timeout);
#ifdef __cplusplus
}
#endif
+29
View File
@@ -0,0 +1,29 @@
/**
* @file furi_hal_info.h
* Device info HAL API
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <core/string.h>
#include <toolbox/property.h>
#ifdef __cplusplus
extern "C" {
#endif
void furi_hal_info_get_api_version(uint16_t* major, uint16_t* minor);
/** Get device information
*
* @param[in] callback callback to provide with new data
* @param[in] sep category separator character
* @param[in] context context to pass to callback
*/
void furi_hal_info_get(PropertyValueCallback callback, char sep, void* context);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,148 @@
/**
* @file furi_hal_infrared.h
* INFRARED HAL API
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
#define INFRARED_MAX_FREQUENCY 56000
#define INFRARED_MIN_FREQUENCY 10000
typedef enum {
FuriHalInfraredTxGetDataStateOk, /**< New data obtained */
FuriHalInfraredTxGetDataStateDone, /**< New data obtained, and this is end of package */
FuriHalInfraredTxGetDataStateLastDone, /**< New data obtained, and this is end of package and no more data available */
} FuriHalInfraredTxGetDataState;
/** Callback type for providing data to INFRARED DMA TX system. It is called every tim */
typedef FuriHalInfraredTxGetDataState (
*FuriHalInfraredTxGetDataISRCallback)(void* context, uint32_t* duration, bool* level);
/** Callback type called every time signal is sent by DMA to Timer.
*
* Actually, it means there are 2 timings left to send for this signal, which is
* almost end. Don't use this callback to stop transmission, as far as there are
* next signal is charged for transmission by DMA.
*/
typedef void (*FuriHalInfraredTxSignalSentISRCallback)(void* context);
/** Signature of callback function for receiving continuous INFRARED rx signal.
*
* @param ctx[in] context to pass to callback
* @param level[in] level of input INFRARED rx signal
* @param duration[in] duration of continuous rx signal level in us
*/
typedef void (*FuriHalInfraredRxCaptureCallback)(void* ctx, bool level, uint32_t duration);
/** Signature of callback function for reaching silence timeout on INFRARED port.
*
* @param ctx[in] context to pass to callback
*/
typedef void (*FuriHalInfraredRxTimeoutCallback)(void* ctx);
/** Initialize INFRARED RX timer to receive interrupts.
*
* It provides interrupts for every RX-signal edge changing with its duration.
*/
void furi_hal_infrared_async_rx_start(void);
/** Deinitialize INFRARED RX interrupt.
*/
void furi_hal_infrared_async_rx_stop(void);
/** Setup hal for receiving silence timeout.
*
* Should be used with 'furi_hal_infrared_timeout_irq_set_callback()'.
*
* @param[in] timeout_us time to wait for silence on INFRARED port before
* generating IRQ.
*/
void furi_hal_infrared_async_rx_set_timeout(uint32_t timeout_us);
/** Setup callback for previously initialized INFRARED RX interrupt.
*
* @param[in] callback callback to call when RX signal edge changing occurs
* @param[in] ctx context for callback
*/
void furi_hal_infrared_async_rx_set_capture_isr_callback(
FuriHalInfraredRxCaptureCallback callback,
void* ctx);
/** Setup callback for reaching silence timeout on INFRARED port.
*
* Should setup hal with 'furi_hal_infrared_setup_rx_timeout_irq()' first.
*
* @param[in] callback callback for silence timeout
* @param[in] ctx context to pass to callback
*/
void furi_hal_infrared_async_rx_set_timeout_isr_callback(
FuriHalInfraredRxTimeoutCallback callback,
void* ctx);
/** Check if INFRARED is in use now.
*
* @return true if INFRARED is busy, false otherwise.
*/
bool furi_hal_infrared_is_busy(void);
/** Set callback providing new data.
*
* This function has to be called before furi_hal_infrared_async_tx_start().
*
* @param[in] callback function to provide new data
* @param[in] context context for callback
*/
void furi_hal_infrared_async_tx_set_data_isr_callback(
FuriHalInfraredTxGetDataISRCallback callback,
void* context);
/** Start IR asynchronous transmission.
*
* It can be stopped by 2 reasons:
* 1. implicit call for furi_hal_infrared_async_tx_stop()
* 2. callback can provide FuriHalInfraredTxGetDataStateLastDone response which
* means no more data available for transmission.
*
* Any func (furi_hal_infrared_async_tx_stop() or
* furi_hal_infrared_async_tx_wait_termination()) has to be called to wait end of
* transmission and free resources.
*
* @param[in] freq frequency for PWM
* @param[in] duty_cycle duty cycle for PWM
*/
void furi_hal_infrared_async_tx_start(uint32_t freq, float duty_cycle);
/** Stop IR asynchronous transmission and free resources.
*
* Transmission will stop as soon as transmission reaches end of package
* (FuriHalInfraredTxGetDataStateDone or FuriHalInfraredTxGetDataStateLastDone).
*/
void furi_hal_infrared_async_tx_stop(void);
/** Wait for end of IR asynchronous transmission and free resources.
*
* Transmission will stop as soon as transmission reaches end of transmission
* (FuriHalInfraredTxGetDataStateLastDone).
*/
void furi_hal_infrared_async_tx_wait_termination(void);
/** Set callback for end of signal transmission
*
* @param[in] callback function to call when signal is sent
* @param[in] context context for callback
*/
void furi_hal_infrared_async_tx_set_signal_sent_isr_callback(
FuriHalInfraredTxSignalSentISRCallback callback,
void* context);
#ifdef __cplusplus
}
#endif
+54
View File
@@ -0,0 +1,54 @@
/**
* @file furi_hal_light.h
* Light control HAL API
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <furi_hal_resources.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Init light driver
*/
void furi_hal_light_init();
/** Set light value
*
* @param light Light
* @param value light brightness [0-255]
*/
void furi_hal_light_set(Light light, uint8_t value);
/** Start hardware LED blinking mode
*
* @param light Light
* @param brightness light brightness [0-255]
* @param on_time LED on time in ms
* @param period LED blink period in ms
*/
void furi_hal_light_blink_start(Light light, uint8_t brightness, uint16_t on_time, uint16_t period);
/** Stop hardware LED blinking mode
*/
void furi_hal_light_blink_stop();
/** Set color in hardware LED blinking mode
*
* @param light Light
*/
void furi_hal_light_blink_set_color(Light light);
/** Execute sequence
*
* @param sequence Sequence to execute
*/
void furi_hal_light_sequence(const char* sequence);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,44 @@
/**
* @file furi_hal_memory.h
* Memory HAL API
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Init memory pool manager
*/
void furi_hal_memory_init();
/**
* @brief Allocate memory from separate memory pool. That memory can't be freed.
*
* @param size
* @return void*
*/
void* furi_hal_memory_alloc(size_t size);
/**
* @brief Get free memory pool size
*
* @return size_t
*/
size_t furi_hal_memory_get_free();
/**
* @brief Get max free block size from memory pool
*
* @return size_t
*/
size_t furi_hal_memory_max_pool_block();
#ifdef __cplusplus
}
#endif
+86
View File
@@ -0,0 +1,86 @@
/**
* @file furi_hal_light.h
* Light control HAL API
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
FuriHalMpuRegionNULL = 0x00, // region 0 used to protect null pointer dereference
FuriHalMpuRegionStack = 0x01, // region 1 used to protect stack
FuriHalMpuRegion2 = 0x02,
FuriHalMpuRegion3 = 0x03,
FuriHalMpuRegion4 = 0x04,
FuriHalMpuRegion5 = 0x05,
FuriHalMpuRegion6 = 0x06,
FuriHalMpuRegion7 = 0x07,
} FuriHalMpuRegion;
typedef enum {
FuriHalMPURegionSize32B = 0x04U,
FuriHalMPURegionSize64B = 0x05U,
FuriHalMPURegionSize128B = 0x06U,
FuriHalMPURegionSize256B = 0x07U,
FuriHalMPURegionSize512B = 0x08U,
FuriHalMPURegionSize1KB = 0x09U,
FuriHalMPURegionSize2KB = 0x0AU,
FuriHalMPURegionSize4KB = 0x0BU,
FuriHalMPURegionSize8KB = 0x0CU,
FuriHalMPURegionSize16KB = 0x0DU,
FuriHalMPURegionSize32KB = 0x0EU,
FuriHalMPURegionSize64KB = 0x0FU,
FuriHalMPURegionSize128KB = 0x10U,
FuriHalMPURegionSize256KB = 0x11U,
FuriHalMPURegionSize512KB = 0x12U,
FuriHalMPURegionSize1MB = 0x13U,
FuriHalMPURegionSize2MB = 0x14U,
FuriHalMPURegionSize4MB = 0x15U,
FuriHalMPURegionSize8MB = 0x16U,
FuriHalMPURegionSize16MB = 0x17U,
FuriHalMPURegionSize32MB = 0x18U,
FuriHalMPURegionSize64MB = 0x19U,
FuriHalMPURegionSize128MB = 0x1AU,
FuriHalMPURegionSize256MB = 0x1BU,
FuriHalMPURegionSize512MB = 0x1CU,
FuriHalMPURegionSize1GB = 0x1DU,
FuriHalMPURegionSize2GB = 0x1EU,
FuriHalMPURegionSize4GB = 0x1FU,
} FuriHalMPURegionSize;
/**
* @brief Initialize memory protection unit
*/
void furi_hal_mpu_init();
/**
* @brief Enable memory protection unit
*/
void furi_hal_mpu_enable();
/**
* @brief Disable memory protection unit
*/
void furi_hal_mpu_disable();
void furi_hal_mpu_protect_no_access(
FuriHalMpuRegion region,
uint32_t address,
FuriHalMPURegionSize size);
void furi_hal_mpu_protect_read_only(
FuriHalMpuRegion region,
uint32_t address,
FuriHalMPURegionSize size);
void furi_hal_mpu_protect_disable(FuriHalMpuRegion region);
#ifdef __cplusplus
}
#endif
+457
View File
@@ -0,0 +1,457 @@
/**
* @file furi_hal_nfc.h
* @brief NFC HAL library.
*
* This library contains functions and definitions needed for NFC hardware low-level access.
*
* Application developers should first consider using the NFC protocol stack or
* the NFC transport layer and see if the APIs provided there sufficient
* for the applicaton's intended purpose.
*
* @see nfc.h
* @see nfc_protocol.h
*
* If any of the above mentioned options is used, calling any of the functions provided by this
* library is hardly necessary, as it will be taken care of under the hood.
*
*/
#pragma once
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief NFC carrier frequency, in Hz.
*/
#define FURI_HAL_NFC_CARRIER_HZ (13560000UL)
/**
* @brief Special value indicating that waiting for an event shall never time out.
*/
#define FURI_HAL_NFC_EVENT_WAIT_FOREVER (0xFFFFFFFFU)
/**
* @brief Enumeration of possible NFC HAL events.
*/
typedef enum {
FuriHalNfcEventOscOn = (1U << 0), /**< Oscillator has been started. */
FuriHalNfcEventFieldOn = (1U << 1), /**< External field (carrier) has been detected. */
FuriHalNfcEventFieldOff = (1U << 2), /**< External field (carrier) has been lost. */
FuriHalNfcEventListenerActive = (1U << 3), /**< Reader has issued a wake-up command. */
FuriHalNfcEventTxStart = (1U << 4), /**< Transmission has started. */
FuriHalNfcEventTxEnd = (1U << 5), /**< Transmission has ended. */
FuriHalNfcEventRxStart = (1U << 6), /**< Reception has started. */
FuriHalNfcEventRxEnd = (1U << 7), /**< Reception has ended. */
FuriHalNfcEventCollision = (1U << 8), /**< A collision has occurred. */
FuriHalNfcEventTimerFwtExpired = (1U << 9), /**< Frame wait timer has expired. */
FuriHalNfcEventTimerBlockTxExpired = (1U << 10), /**< Transmission block timer has expired. */
FuriHalNfcEventTimeout =
(1U << 11), /**< No events have occurred in a specified time period. */
FuriHalNfcEventAbortRequest =
(1U << 12), /**< User has requested to abort current operation. */
} FuriHalNfcEvent;
/**
* @brief Enumeration of possible NFC HAL errors.
*/
typedef enum {
FuriHalNfcErrorNone, /**< No error has occurred. */
FuriHalNfcErrorBusy, /**< The communication bus is busy. */
FuriHalNfcErrorCommunication, /**< NFC hardware did not respond or responded unexpectedly. */
FuriHalNfcErrorOscillator, /**< Oscillator failed to start. */
FuriHalNfcErrorCommunicationTimeout, /**< NFC hardware did not respond in time. */
FuriHalNfcErrorBufferOverflow, /**< Receive buffer was too small for the received data. */
FuriHalNfcErrorIncompleteFrame, /**< Not enough data was received to parse a valid frame. */
FuriHalNfcErrorDataFormat, /**< Cannot parse a frame due to unexpected/invalid data. */
} FuriHalNfcError;
/**
* @brief Enumeration of possible NFC HAL operating modes.
*/
typedef enum {
FuriHalNfcModePoller, /**< Configure NFC HAL to operate as a poller. */
FuriHalNfcModeListener, /**< Configure NFC HAL to operate as a listener. */
FuriHalNfcModeNum, /**< Special value equal to the operating modes count. Internal use. */
} FuriHalNfcMode;
/**
* @brief Enumeration of supported NFC technologies.
*/
typedef enum {
FuriHalNfcTechIso14443a, /**< Configure NFC HAL to use the ISO14443 (type A) technology. */
FuriHalNfcTechIso14443b, /**< Configure NFC HAL to use the ISO14443 (type B) technology. */
FuriHalNfcTechIso15693, /**< Configure NFC HAL to use the ISO15693 technology. */
FuriHalNfcTechFelica, /**< Configure NFC HAL to use the FeliCa technology. */
FuriHalNfcTechNum, /**< Special value equal to the supported technologies count. Internal use. */
FuriHalNfcTechInvalid, /**< Special value indicating the unconfigured state. Internal use. */
} FuriHalNfcTech;
/**
* @brief Initialise the NFC HAL and associated hardware.
*
* This function is called automatically during the firmware initialisation,
* so there is no need to call it explicitly.
*
* @returns FuriHalNfcErrorNone on success, any other error code on failure.
*/
FuriHalNfcError furi_hal_nfc_init();
/**
* @brief Check whether the NFC HAL was properly initialised and is ready.
*
* @returns FuriHalNfcErrorNone if ready, any other error code if not ready.
*/
FuriHalNfcError furi_hal_nfc_is_hal_ready();
/**
* @brief Exclusively take over the NFC HAL and associated hardware.
*
* This function needs to be called whenever an interaction with the NFC HAL
* is to take place (usually once upon the application start).
*
* @returns FuriHalNfcErrorNone on success, any other error code on failure.
*/
FuriHalNfcError furi_hal_nfc_acquire();
/**
* @brief Release the exclusive lock and make the NFC HAL available for others.
*
* This function needs to be called when the user code is done working
* with the NFC HAL (usually once upon application exit). It must be called
* from the same thread that has called furi_hal_nfc_acquire().
*
* @returns FuriHalNfcErrorNone on success, any other error code on failure.
*/
FuriHalNfcError furi_hal_nfc_release();
/**
* @brief Configure the NFC hardware to enter the low-power mode.
*
* This function must be called each time when the user code is done working
* with the NFC HAL for the time being (e.g. waiting on user input).
*
* @returns FuriHalNfcErrorNone on success, any other error code on failure.
*/
FuriHalNfcError furi_hal_nfc_low_power_mode_start();
/**
* @brief Configure the NFC hardware to exit the low-power mode.
*
* This function must be called each time when the user code begins working
* with the NFC HAL, as the default state is low-power mode.
*
* @returns FuriHalNfcErrorNone on success, any other error code on failure.
*/
FuriHalNfcError furi_hal_nfc_low_power_mode_stop();
/**
* @brief Configure the NFC HAL to work in a particular mode.
*
* Not all technologies implement the listener operating mode.
*
* @param[in] mode required operating mode.
* @param[in] tech required technology configuration.
* @returns FuriHalNfcErrorNone on success, any other error code on failure.
*/
FuriHalNfcError furi_hal_nfc_set_mode(FuriHalNfcMode mode, FuriHalNfcTech tech);
/**
* @brief Reset the NFC HAL to its default (unconfigured) state.
*
* @returns FuriHalNfcErrorNone on success, any other error code on failure.
*/
FuriHalNfcError furi_hal_nfc_reset_mode();
/**
* @brief Enable field (carrier) detection by the NFC hardware.
*
* @returns FuriHalNfcErrorNone on success, any other error code on failure.
*/
FuriHalNfcError furi_hal_nfc_field_detect_start();
/**
* @brief Disable field (carrier) detection by the NFC hardware.
*
* @returns FuriHalNfcErrorNone on success, any other error code on failure.
*/
FuriHalNfcError furi_hal_nfc_field_detect_stop();
/**
* @brief Check if the reader field (carrier) was detected by the NFC hardware.
*
* @returns true if the field was detected, false otherwise.
*/
bool furi_hal_nfc_field_is_present();
/**
* @brief Enable field (carrier) generation by the NFC hardware.
*
* No carrier modulation will occur unless a transmission is explicitly started.
*
* @returns FuriHalNfcErrorNone on success, any other error code on failure.
*/
FuriHalNfcError furi_hal_nfc_poller_field_on();
/**
* @brief Wait for an NFC HAL event in poller mode.
*
* @param[in] timeout_ms time to wait (timeout) in milliseconds.
* @returns FuriHalNfcErrorNone on success, any other error code on failure.
*/
FuriHalNfcEvent furi_hal_nfc_poller_wait_event(uint32_t timeout_ms);
/**
* @brief Wait for an NFC HAL event in listener mode.
* @param[in] timeout_ms time to wait (timeout) in milliseconds.
* @returns FuriHalNfcErrorNone on success, any other error code on failure.
*/
FuriHalNfcEvent furi_hal_nfc_listener_wait_event(uint32_t timeout_ms);
/**
* @brief Transmit data in poller mode.
*
* @param[in] tx_data pointer to a byte array containing the data to be transmitted.
* @param[in] tx_bits transmit data size, in bits.
* @returns FuriHalNfcErrorNone on success, any other error code on failure.
*/
FuriHalNfcError furi_hal_nfc_poller_tx(const uint8_t* tx_data, size_t tx_bits);
/**
* @brief Receive data in poller mode.
*
* The receive buffer must be big enough to accomodate all of the expected data.
*
* @param rx_data[out] pointer to a byte array to be filled with received data.
* @param rx_data_size[in] maximum received data size, in bytes.
* @param rx_bits[out] pointer to the variable to hold received data size, in bits.
* @returns FuriHalNfcErrorNone on success, any other error code on failure.
*/
FuriHalNfcError furi_hal_nfc_poller_rx(uint8_t* rx_data, size_t rx_data_size, size_t* rx_bits);
/**
* @brief Transmit data in listener mode.
*
* @param[in] tx_data pointer to a byte array containing the data to be transmitted.
* @param[in] tx_bits transmit data size, in bits.
* @returns FuriHalNfcErrorNone on success, any other error code on failure.
*/
FuriHalNfcError furi_hal_nfc_listener_tx(const uint8_t* tx_data, size_t tx_bits);
/**
* @brief Receive data in listener mode.
*
* The receive buffer must be big enough to accomodate all of the expected data.
*
* @param rx_data[out] pointer to a byte array to be filled with received data.
* @param rx_data_size[in] maximum received data size, in bytes.
* @param rx_bits[out] pointer to the variable to hold received data size, in bits.
* @returns FuriHalNfcErrorNone on success, any other error code on failure.
*/
FuriHalNfcError furi_hal_nfc_listener_rx(uint8_t* rx_data, size_t rx_data_size, size_t* rx_bits);
/**
* @brief Go to sleep in listener mode.
*
* Puts the passive target logic into Sleep (Halt) state.
*
* @returns FuriHalNfcErrorNone on success, any other error code on failure.
*/
FuriHalNfcError furi_hal_nfc_listener_sleep();
/**
* @brief Go to idle in listener mode.
*
* Puts the passive target logic into Sense (Idle) state.
*
* @returns FuriHalNfcErrorNone on success, any other error code on failure.
*/
FuriHalNfcError furi_hal_nfc_listener_idle();
/**
* @brief Enable reception in listener mode.
*
* Starts hardware receivers and receive decoders.
*
* @returns FuriHalNfcErrorNone on success, any other error code on failure.
*/
FuriHalNfcError furi_hal_nfc_listener_enable_rx();
/**
* @brief Reset communication.
*
* Resets the communication state and stops all activities: transmission, reception, etc.
*
* @returns FuriHalNfcErrorNone on success, any other error code on failure.
*/
FuriHalNfcError furi_hal_nfc_trx_reset();
/**
* @brief Enable generation of NFC HAL events.
*
* @warning This function must be called from the same thread from which
* the the furi_hal_nfc_*_wait_event() calls will be made.
*
* @returns FuriHalNfcErrorNone on success, any other error code on failure.
*/
FuriHalNfcError furi_hal_nfc_event_start();
/**
* @brief Disable generation of NFC HAL events.
*
* Unlike furi_hal_nfc_event_start(), this function may be called from any thread.
*
* @returns FuriHalNfcErrorNone on success, any other error code on failure.
*/
FuriHalNfcError furi_hal_nfc_event_stop();
/**
* @brief Manually emit the FuriHalNfcEventAbortRequest event.
*
* @returns FuriHalNfcErrorNone on success, any other error code on failure.
*/
FuriHalNfcError furi_hal_nfc_abort();
/**
* @brief Start frame wait timeout timer.
*
* @param[in] time_fc time to wait, in carrier cycles.
*/
void furi_hal_nfc_timer_fwt_start(uint32_t time_fc);
/**
* @brief Stop frame wait timeout timer.
*/
void furi_hal_nfc_timer_fwt_stop();
/**
* @brief Start block transmit (frame delay) timer.
*
* @param[in] time_fc time to wait, in carrier cycles.
*/
void furi_hal_nfc_timer_block_tx_start(uint32_t time_fc);
/**
* @brief Start block transmit (frame delay) timer.
*
* @param[in] time_us time to wait, in microseconds.
*/
void furi_hal_nfc_timer_block_tx_start_us(uint32_t time_us);
/**
* @brief Stop block transmit (frame delay) timer.
*/
void furi_hal_nfc_timer_block_tx_stop();
/**
* @brief Check whether block transmit (frame delay) timer is running.
*
* @returns true if timer is running, false otherwise.
*/
bool furi_hal_nfc_timer_block_tx_is_running();
/*
* Technology-specific functions.
*
* In a perfect world, this would not be necessary.
* However, the current implementation employs NFC hardware that partially implements
* certain protocols (e.g. ISO14443-3A), thus requiring methods to access such features.
*/
/******************* Iso14443a specific API *******************/
/**
* @brief Enumeration of ISO14443 (Type A) short frame types.
*/
typedef enum {
FuriHalNfcaShortFrameAllReq,
FuriHalNfcaShortFrameSensReq,
} FuriHalNfcaShortFrame;
/**
* @brief Transmit ISO14443 (Type A) short frame in poller mode.
*
* @param[in] frame short frame type to be transmitted.
* @returns FuriHalNfcErrorNone on success, any other error code on failure.
*/
FuriHalNfcError furi_hal_nfc_iso14443a_poller_trx_short_frame(FuriHalNfcaShortFrame frame);
/** Transmit ISO14443 (Type A) SDD frame in poller mode.
*
* @param[in] tx_data pointer to a byte array containing the data to be transmitted.
* @param[in] tx_bits transmit data size, in bits.
* @returns FuriHalNfcErrorNone on success, any other error code on failure.
*/
FuriHalNfcError furi_hal_nfc_iso14443a_tx_sdd_frame(const uint8_t* tx_data, size_t tx_bits);
/**
* Receive ISO14443 (Type A) SDD frame in poller mode.
*
* The receive buffer must be big enough to accomodate all of the expected data.
*
* @param rx_data[out] pointer to a byte array to be filled with received data.
* @param rx_data_size[in] maximum received data size, in bytes.
* @param rx_bits[out] pointer to the variable to hold received data size, in bits.
* @returns FuriHalNfcErrorNone on success, any other error code on failure.
*/
FuriHalNfcError
furi_hal_nfc_iso14443a_rx_sdd_frame(uint8_t* rx_data, size_t rx_data_size, size_t* rx_bits);
/**
* @brief Transmit ISO14443 (Type A) frame with custom parity bits in poller mode.
*
* Same as furi_hal_nfc_poller_tx(), but uses the parity bits provided
* by the user code instead of calculating them automatically.
*
* @param[in] tx_data pointer to a byte array containing the data to be transmitted.
* @param[in] tx_bits transmit data size, in bits.
* @returns FuriHalNfcErrorNone on success, any other error code on failure.
*/
FuriHalNfcError
furi_hal_nfc_iso14443a_poller_tx_custom_parity(const uint8_t* tx_data, size_t tx_bits);
/**
* @brief Set ISO14443 (Type A) collision resolution parameters in listener mode.
*
* Configures the NFC hardware for automatic collision resolution.
*
* @param[in] uid pointer to a byte array containing the UID.
* @param[in] uid_len UID length in bytes (must be supported by the protocol).
* @param[in] atqa ATQA byte value.
* @param[in] sak SAK byte value.
* @returns FuriHalNfcErrorNone on success, any other error code on failure.
*/
FuriHalNfcError furi_hal_nfc_iso14443a_listener_set_col_res_data(
uint8_t* uid,
uint8_t uid_len,
uint8_t* atqa,
uint8_t sak);
/**
* @brief Transmit ISO14443 (Type A) frame with custom parity bits in listener mode.
*
* @param[in] tx_data pointer to a byte array containing the data to be transmitted.
* @param[in] tx_parity pointer to a (bit-packed) byte array containing the parity to be transmitted.
* @param[in] tx_bits transmit data size, in bits.
* @returns FuriHalNfcErrorNone on success, any other error code on failure.
*/
FuriHalNfcError furi_hal_nfc_iso14443a_listener_tx_custom_parity(
const uint8_t* tx_data,
const uint8_t* tx_parity,
size_t tx_bits);
/** Send ISO15693 SOF in listener mode
*
* @return FuriHalNfcError
*/
FuriHalNfcError furi_hal_nfc_iso15693_listener_tx_sof();
#ifdef __cplusplus
}
#endif
+227
View File
@@ -0,0 +1,227 @@
/**
* @file furi_hal_power.h
* Power HAL API
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#include <core/string.h>
#include <toolbox/property.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Power IC type */
typedef enum {
FuriHalPowerICCharger,
FuriHalPowerICFuelGauge,
} FuriHalPowerIC;
/** Initialize drivers */
void furi_hal_power_init();
/** Check if gauge is ok
*
* Verifies that:
* - gauge is alive
* - correct profile loaded
* - self diagnostic status is good
*
* @return true if gauge is ok
*/
bool furi_hal_power_gauge_is_ok();
/** Check if gauge requests system shutdown
*
* @return true if system shutdown requested
*/
bool furi_hal_power_is_shutdown_requested();
/** Get current insomnia level
*
* @return insomnia level: 0 - no insomnia, >0 - insomnia, bearer count.
*/
uint16_t furi_hal_power_insomnia_level();
/** Enter insomnia mode Prevents device from going to sleep
* @warning Internally increases insomnia level Must be paired with
* furi_hal_power_insomnia_exit
*/
void furi_hal_power_insomnia_enter();
/** Exit insomnia mode Allow device to go to sleep
* @warning Internally decreases insomnia level. Must be paired with
* furi_hal_power_insomnia_enter
*/
void furi_hal_power_insomnia_exit();
/** Check if sleep availble
*
* @return true if available
*/
bool furi_hal_power_sleep_available();
/** Go to sleep
*/
void furi_hal_power_sleep();
/** Get predicted remaining battery capacity in percents
*
* @return remaining battery capacity in percents
*/
uint8_t furi_hal_power_get_pct();
/** Get battery health state in percents
*
* @return health in percents
*/
uint8_t furi_hal_power_get_bat_health_pct();
/** Get charging status
*
* @return true if charging
*/
bool furi_hal_power_is_charging();
/** Get charge complete status
*
* @return true if done charging and connected to charger
*/
bool furi_hal_power_is_charging_done();
/** Switch MCU to SHUTDOWN */
void furi_hal_power_shutdown();
/** Poweroff device
*/
void furi_hal_power_off();
/** Reset device
*/
void furi_hal_power_reset();
/** OTG enable
*/
bool furi_hal_power_enable_otg();
/** OTG disable
*/
void furi_hal_power_disable_otg();
/** Check OTG status fault
*/
bool furi_hal_power_check_otg_fault();
/** Check OTG status and disable it if falt happened
*/
void furi_hal_power_check_otg_status();
/** Get OTG status
*
* @return true if enabled
*/
bool furi_hal_power_is_otg_enabled();
/** Get battery charge voltage limit in V
*
* @return voltage in V
*/
float furi_hal_power_get_battery_charge_voltage_limit();
/** Set battery charge voltage limit in V
*
* Invalid values will be clamped downward to the nearest valid value.
*
* @param voltage[in] voltage in V
*
* @return voltage in V
*/
void furi_hal_power_set_battery_charge_voltage_limit(float voltage);
/** Get remaining battery battery capacity in mAh
*
* @return capacity in mAh
*/
uint32_t furi_hal_power_get_battery_remaining_capacity();
/** Get full charge battery capacity in mAh
*
* @return capacity in mAh
*/
uint32_t furi_hal_power_get_battery_full_capacity();
/** Get battery capacity in mAh from battery profile
*
* @return capacity in mAh
*/
uint32_t furi_hal_power_get_battery_design_capacity();
/** Get battery voltage in V
*
* @param ic FuriHalPowerIc to get measurment
*
* @return voltage in V
*/
float furi_hal_power_get_battery_voltage(FuriHalPowerIC ic);
/** Get battery current in A
*
* @param ic FuriHalPowerIc to get measurment
*
* @return current in A
*/
float furi_hal_power_get_battery_current(FuriHalPowerIC ic);
/** Get temperature in C
*
* @param ic FuriHalPowerIc to get measurment
*
* @return temperature in C
*/
float furi_hal_power_get_battery_temperature(FuriHalPowerIC ic);
/** Get USB voltage in V
*
* @return voltage in V
*/
float furi_hal_power_get_usb_voltage();
/** Enable 3.3v on external gpio and sd card
*/
void furi_hal_power_enable_external_3_3v();
/** Disable 3.3v on external gpio and sd card
*/
void furi_hal_power_disable_external_3_3v();
/** Enter supress charge mode.
*
* Use this function when your application need clean power supply.
*/
void furi_hal_power_suppress_charge_enter();
/** Exit supress charge mode
*/
void furi_hal_power_suppress_charge_exit();
/** Get power information
*
* @param[in] callback callback to provide with new data
* @param[in] sep category separator character
* @param[in] context context to pass to callback
*/
void furi_hal_power_info_get(PropertyValueCallback callback, char sep, void* context);
/** Get power debug information
*
* @param[in] callback callback to provide with new data
* @param[in] context context to pass to callback
*/
void furi_hal_power_debug_get(PropertyValueCallback callback, void* context);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,27 @@
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Initialize random subsystem */
void furi_hal_random_init();
/** Get random value
*
* @return random value
*/
uint32_t furi_hal_random_get();
/** Fill buffer with random data
*
* @param buf buffer pointer
* @param data buffer len
*/
void furi_hal_random_fill_buf(uint8_t* buf, uint32_t len);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,81 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
uint32_t start;
uint32_t end;
int8_t power_limit;
uint8_t duty_cycle;
} FuriHalRegionBand;
typedef struct {
char country_code[4];
uint16_t bands_count;
FuriHalRegionBand bands[];
} FuriHalRegion;
/** Initialize region */
void furi_hal_region_init();
/** Get Region Data.
*
* Region data may be allocated in Flash or in RAM.
* Keep in mind that we don't do memory management on our side.
*
* @return pointer to FuriHalRegion instance (in RAM or Flash, check before freeing on region update)
*/
const FuriHalRegion* furi_hal_region_get();
/** Set device region data
*
* @param region pointer to the FuriHalRegion
*/
void furi_hal_region_set(FuriHalRegion* region);
/** Check if region data provisioned
*
* @return true if provisioned, false otherwise
*/
bool furi_hal_region_is_provisioned();
/** Get region name
*
* 2 letter Region code according to iso 3166 standard
* There are 2 extra values that we use in special cases:
* - "00" - developer edition, unlocked
* - "WW" - world wide, region provisioned by default
* - "--" - no provisioned region
*
* @return Pointer to string
*/
const char* furi_hal_region_get_name();
/** Сheck if transmission is allowed on this frequency for your flipper region
*
* @param[in] frequency The frequency
* @param value frequency in Hz
*
* @return true if allowed
*/
bool furi_hal_region_is_frequency_allowed(uint32_t frequency);
/** Get band data for frequency
*
*
*
* @param[in] frequency The frequency
*
* @return { description_of_the_return_value }
*/
const FuriHalRegionBand* furi_hal_region_get_band(uint32_t frequency);
#ifdef __cplusplus
}
#endif
+285
View File
@@ -0,0 +1,285 @@
/**
* @file furi_hal_rtc.h
* Furi Hal RTC API
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
// Time
uint8_t hour; /**< Hour in 24H format: 0-23 */
uint8_t minute; /**< Minute: 0-59 */
uint8_t second; /**< Second: 0-59 */
// Date
uint8_t day; /**< Current day: 1-31 */
uint8_t month; /**< Current month: 1-12 */
uint16_t year; /**< Current year: 2000-2099 */
uint8_t weekday; /**< Current weekday: 1-7 */
} FuriHalRtcDateTime;
typedef enum {
FuriHalRtcFlagDebug = (1 << 0),
FuriHalRtcFlagFactoryReset = (1 << 1),
FuriHalRtcFlagLock = (1 << 2),
FuriHalRtcFlagC2Update = (1 << 3),
FuriHalRtcFlagHandOrient = (1 << 4),
FuriHalRtcFlagLegacySleep = (1 << 5),
FuriHalRtcFlagStealthMode = (1 << 6),
FuriHalRtcFlagDetailedFilename = (1 << 7),
} FuriHalRtcFlag;
typedef enum {
FuriHalRtcBootModeNormal = 0, /**< Normal boot mode, default value */
FuriHalRtcBootModeDfu, /**< Boot to DFU (MCU bootloader by ST) */
FuriHalRtcBootModePreUpdate, /**< Boot to Update, pre update */
FuriHalRtcBootModeUpdate, /**< Boot to Update, main */
FuriHalRtcBootModePostUpdate, /**< Boot to Update, post update */
} FuriHalRtcBootMode;
typedef enum {
FuriHalRtcHeapTrackModeNone = 0, /**< Disable allocation tracking */
FuriHalRtcHeapTrackModeMain, /**< Enable allocation tracking for main application thread */
FuriHalRtcHeapTrackModeTree, /**< Enable allocation tracking for main and children application threads */
FuriHalRtcHeapTrackModeAll, /**< Enable allocation tracking for all threads */
} FuriHalRtcHeapTrackMode;
typedef enum {
FuriHalRtcRegisterHeader, /**< RTC structure header */
FuriHalRtcRegisterSystem, /**< Various system bits */
FuriHalRtcRegisterVersion, /**< Pointer to Version */
FuriHalRtcRegisterLfsFingerprint, /**< LFS geometry fingerprint */
FuriHalRtcRegisterFaultData, /**< Pointer to last fault message */
FuriHalRtcRegisterPinFails, /**< Failed pins count */
/* Index of FS directory entry corresponding to FW update to be applied */
FuriHalRtcRegisterUpdateFolderFSIndex,
FuriHalRtcRegisterMAX, /**< Service value, do not use */
} FuriHalRtcRegister;
typedef enum {
FuriHalRtcLocaleUnitsMetric = 0, /**< Metric measurement units */
FuriHalRtcLocaleUnitsImperial = 1, /**< Imperial measurement units */
} FuriHalRtcLocaleUnits;
typedef enum {
FuriHalRtcLocaleTimeFormat24h = 0, /**< 24-hour format */
FuriHalRtcLocaleTimeFormat12h = 1, /**< 12-hour format */
} FuriHalRtcLocaleTimeFormat;
typedef enum {
FuriHalRtcLocaleDateFormatDMY = 0, /**< Day/Month/Year */
FuriHalRtcLocaleDateFormatMDY = 1, /**< Month/Day/Year */
FuriHalRtcLocaleDateFormatYMD = 2, /**< Year/Month/Day */
} FuriHalRtcLocaleDateFormat;
/** Early initialization */
void furi_hal_rtc_init_early();
/** Early de-initialization */
void furi_hal_rtc_deinit_early();
/** Initialize RTC subsystem */
void furi_hal_rtc_init();
/** Force sync shadow registers */
void furi_hal_rtc_sync_shadow();
/** Get RTC register content
*
* @param[in] reg The register identifier
*
* @return content of the register
*/
uint32_t furi_hal_rtc_get_register(FuriHalRtcRegister reg);
/** Set register content
*
* @param[in] reg The register identifier
* @param[in] value The value to store into register
*/
void furi_hal_rtc_set_register(FuriHalRtcRegister reg, uint32_t value);
/** Set Log Level value
*
* @param[in] level The level to store
*/
void furi_hal_rtc_set_log_level(uint8_t level);
/** Get Log Level value
*
* @return The Log Level value
*/
uint8_t furi_hal_rtc_get_log_level();
/** Set RTC Flag
*
* @param[in] flag The flag to set
*/
void furi_hal_rtc_set_flag(FuriHalRtcFlag flag);
/** Reset RTC Flag
*
* @param[in] flag The flag to reset
*/
void furi_hal_rtc_reset_flag(FuriHalRtcFlag flag);
/** Check if RTC Flag is set
*
* @param[in] flag The flag to check
*
* @return true if set
*/
bool furi_hal_rtc_is_flag_set(FuriHalRtcFlag flag);
/** Set RTC boot mode
*
* @param[in] mode The mode to set
*/
void furi_hal_rtc_set_boot_mode(FuriHalRtcBootMode mode);
/** Get RTC boot mode
*
* @return The RTC boot mode.
*/
FuriHalRtcBootMode furi_hal_rtc_get_boot_mode();
/** Set Heap Track mode
*
* @param[in] mode The mode to set
*/
void furi_hal_rtc_set_heap_track_mode(FuriHalRtcHeapTrackMode mode);
/** Get RTC Heap Track mode
*
* @return The RTC heap track mode.
*/
FuriHalRtcHeapTrackMode furi_hal_rtc_get_heap_track_mode();
/** Set locale units
*
* @param[in] mode The RTC Locale Units
*/
void furi_hal_rtc_set_locale_units(FuriHalRtcLocaleUnits value);
/** Get RTC Locale Units
*
* @return The RTC Locale Units.
*/
FuriHalRtcLocaleUnits furi_hal_rtc_get_locale_units();
/** Set RTC Locale Time Format
*
* @param[in] value The RTC Locale Time Format
*/
void furi_hal_rtc_set_locale_timeformat(FuriHalRtcLocaleTimeFormat value);
/** Get RTC Locale Time Format
*
* @return The RTC Locale Time Format.
*/
FuriHalRtcLocaleTimeFormat furi_hal_rtc_get_locale_timeformat();
/** Set RTC Locale Date Format
*
* @param[in] value The RTC Locale Date Format
*/
void furi_hal_rtc_set_locale_dateformat(FuriHalRtcLocaleDateFormat value);
/** Get RTC Locale Date Format
*
* @return The RTC Locale Date Format
*/
FuriHalRtcLocaleDateFormat furi_hal_rtc_get_locale_dateformat();
/** Set RTC Date Time
*
* @param datetime The date time to set
*/
void furi_hal_rtc_set_datetime(FuriHalRtcDateTime* datetime);
/** Get RTC Date Time
*
* @param datetime The datetime
*/
void furi_hal_rtc_get_datetime(FuriHalRtcDateTime* datetime);
/** Validate Date Time
*
* @param datetime The datetime to validate
*
* @return { description_of_the_return_value }
*/
bool furi_hal_rtc_validate_datetime(FuriHalRtcDateTime* datetime);
/** Set RTC Fault Data
*
* @param[in] value The value
*/
void furi_hal_rtc_set_fault_data(uint32_t value);
/** Get RTC Fault Data
*
* @return RTC Fault Data value
*/
uint32_t furi_hal_rtc_get_fault_data();
/** Set Pin Fails count
*
* @param[in] value The Pin Fails count
*/
void furi_hal_rtc_set_pin_fails(uint32_t value);
/** Get Pin Fails count
*
* @return Pin Fails Count
*/
uint32_t furi_hal_rtc_get_pin_fails();
/** Get UNIX Timestamp
*
* @return Unix Timestamp in seconds from UNIX epoch start
*/
uint32_t furi_hal_rtc_get_timestamp();
/** Convert DateTime to UNIX timestamp
*
* @param datetime The datetime
*
* @return UNIX Timestamp in seconds from UNIX epoch start
*/
uint32_t furi_hal_rtc_datetime_to_timestamp(FuriHalRtcDateTime* datetime);
/** Gets the number of days in the year according to the Gregorian calendar.
*
* @param year Input year.
*
* @return number of days in `year`.
*/
uint16_t furi_hal_rtc_get_days_per_year(uint16_t year);
/** Check if a year a leap year in the Gregorian calendar.
*
* @param year Input year.
*
* @return true if `year` is a leap year.
*/
bool furi_hal_rtc_is_leap_year(uint16_t year);
/** Get the number of days in the month.
*
* @param leap_year true to calculate based on leap years
* @param month month to check, where 1 = January
* @return the number of days in the month
*/
uint8_t furi_hal_rtc_get_days_per_month(bool leap_year, uint8_t month);
#ifdef __cplusplus
}
#endif
+86
View File
@@ -0,0 +1,86 @@
#pragma once
/**
* @file furi_hal_sd.h
* SD Card HAL API
*/
#include <furi.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
uint64_t capacity; /*!< total capacity in bytes */
uint32_t block_size; /*!< block size */
uint32_t logical_block_count; /*!< logical capacity in blocks */
uint32_t logical_block_size; /*!< logical block size in bytes */
uint8_t manufacturer_id; /*!< manufacturer ID */
char oem_id[3]; /*!< OEM ID, 2 characters + null terminator */
char product_name[6]; /*!< product name, 5 characters + null terminator */
uint8_t product_revision_major; /*!< product revision major */
uint8_t product_revision_minor; /*!< product revision minor */
uint32_t product_serial_number; /*!< product serial number */
uint8_t manufacturing_month; /*!< manufacturing month */
uint16_t manufacturing_year; /*!< manufacturing year */
} FuriHalSdInfo;
/**
* @brief Init SD card presence detection
*/
void furi_hal_sd_presence_init();
/**
* @brief Get SD card status
* @return true if SD card is present
*/
bool furi_hal_sd_is_present();
/**
* @brief SD card max mount retry count
* @return uint8_t
*/
uint8_t furi_hal_sd_max_mount_retry_count();
/**
* @brief Init SD card
* @param power_reset reset card power
* @return FuriStatus
*/
FuriStatus furi_hal_sd_init(bool power_reset);
/**
* @brief Read blocks from SD card
* @param buff
* @param sector
* @param count
* @return FuriStatus
*/
FuriStatus furi_hal_sd_read_blocks(uint32_t* buff, uint32_t sector, uint32_t count);
/**
* @brief Write blocks to SD card
* @param buff
* @param sector
* @param count
* @return FuriStatus
*/
FuriStatus furi_hal_sd_write_blocks(const uint32_t* buff, uint32_t sector, uint32_t count);
/**
* @brief Get SD card info
* @param info
* @return FuriStatus
*/
FuriStatus furi_hal_sd_info(FuriHalSdInfo* info);
/**
* @brief Get SD card state
* @return FuriStatus
*/
FuriStatus furi_hal_sd_get_card_state();
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,68 @@
/**
* @file furi_hal_speaker.h
* Speaker HAL
*/
#pragma once
#include <furi.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Init speaker */
void furi_hal_speaker_init();
/** Deinit speaker */
void furi_hal_speaker_deinit();
/** Acquire speaker ownership
*
* @warning You must acquire speaker ownership before use
*
* @param timeout Timeout during which speaker ownership must be acquired
*
* @return bool returns true on success
*/
FURI_WARN_UNUSED bool furi_hal_speaker_acquire(uint32_t timeout);
/** Release speaker ownership
*
* @warning You must release speaker ownership after use
*/
void furi_hal_speaker_release();
/** Check current process speaker ownership
*
* @warning always returns true if called from ISR
*
* @return bool returns true if process owns speaker
*/
bool furi_hal_speaker_is_mine();
/** Play a note
*
* @warning no ownership check if called from ISR
*
* @param frequency The frequency
* @param volume The volume
*/
void furi_hal_speaker_start(float frequency, float volume);
/** Set volume
*
* @warning no ownership check if called from ISR
*
* @param volume The volume
*/
void furi_hal_speaker_set_volume(float volume);
/** Stop playback
*
* @warning no ownership check if called from ISR
*/
void furi_hal_speaker_stop();
#ifdef __cplusplus
}
#endif
+128
View File
@@ -0,0 +1,128 @@
#pragma once
#include <furi_hal_spi_config.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Early initialize SPI HAL */
void furi_hal_spi_config_init_early();
/** Early deinitialize SPI HAL */
void furi_hal_spi_config_deinit_early();
/** Initialize SPI HAL */
void furi_hal_spi_config_init();
/** Initialize SPI DMA HAL */
void furi_hal_spi_dma_init();
/** Initialize SPI Bus
*
* @param handle pointer to FuriHalSpiBus instance
*/
void furi_hal_spi_bus_init(FuriHalSpiBus* bus);
/** Deinitialize SPI Bus
*
* @param handle pointer to FuriHalSpiBus instance
*/
void furi_hal_spi_bus_deinit(FuriHalSpiBus* bus);
/** Initialize SPI Bus Handle
*
* @param handle pointer to FuriHalSpiBusHandle instance
*/
void furi_hal_spi_bus_handle_init(FuriHalSpiBusHandle* handle);
/** Deinitialize SPI Bus Handle
*
* @param handle pointer to FuriHalSpiBusHandle instance
*/
void furi_hal_spi_bus_handle_deinit(FuriHalSpiBusHandle* handle);
/** Acquire SPI bus
*
* @warning blocking, calls `furi_crash` on programming error, CS transition is up to handler event routine
*
* @param handle pointer to FuriHalSpiBusHandle instance
*/
void furi_hal_spi_acquire(FuriHalSpiBusHandle* handle);
/** Release SPI bus
*
* @warning calls `furi_crash` on programming error, CS transition is up to handler event routine
*
* @param handle pointer to FuriHalSpiBusHandle instance
*/
void furi_hal_spi_release(FuriHalSpiBusHandle* handle);
/** SPI Receive
*
* @param handle pointer to FuriHalSpiBusHandle instance
* @param buffer receive buffer
* @param size transaction size (buffer size)
* @param timeout operation timeout in ms
*
* @return true on sucess
*/
bool furi_hal_spi_bus_rx(
FuriHalSpiBusHandle* handle,
uint8_t* buffer,
size_t size,
uint32_t timeout);
/** SPI Transmit
*
* @param handle pointer to FuriHalSpiBusHandle instance
* @param buffer transmit buffer
* @param size transaction size (buffer size)
* @param timeout operation timeout in ms
*
* @return true on success
*/
bool furi_hal_spi_bus_tx(
FuriHalSpiBusHandle* handle,
const uint8_t* buffer,
size_t size,
uint32_t timeout);
/** SPI Transmit and Receive
*
* @param handle pointer to FuriHalSpiBusHandle instance
* @param tx_buffer pointer to tx buffer
* @param rx_buffer pointer to rx buffer
* @param size transaction size (buffer size)
* @param timeout operation timeout in ms
*
* @return true on success
*/
bool furi_hal_spi_bus_trx(
FuriHalSpiBusHandle* handle,
const uint8_t* tx_buffer,
uint8_t* rx_buffer,
size_t size,
uint32_t timeout);
/** SPI Transmit and Receive with DMA
*
* @param handle pointer to FuriHalSpiBusHandle instance
* @param tx_buffer pointer to tx buffer
* @param rx_buffer pointer to rx buffer
* @param size transaction size (buffer size)
* @param timeout_ms operation timeout in ms
*
* @return true on success
*/
bool furi_hal_spi_bus_trx_dma(
FuriHalSpiBusHandle* handle,
uint8_t* tx_buffer,
uint8_t* rx_buffer,
size_t size,
uint32_t timeout_ms);
#ifdef __cplusplus
}
#endif
+92
View File
@@ -0,0 +1,92 @@
#pragma once
#include "usb.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct FuriHalUsbInterface FuriHalUsbInterface;
struct FuriHalUsbInterface {
void (*init)(usbd_device* dev, FuriHalUsbInterface* intf, void* ctx);
void (*deinit)(usbd_device* dev);
void (*wakeup)(usbd_device* dev);
void (*suspend)(usbd_device* dev);
struct usb_device_descriptor* dev_descr;
void* str_manuf_descr;
void* str_prod_descr;
void* str_serial_descr;
void* cfg_descr;
};
/** USB device interface modes */
extern FuriHalUsbInterface usb_cdc_single;
extern FuriHalUsbInterface usb_cdc_dual;
extern FuriHalUsbInterface usb_hid;
extern FuriHalUsbInterface usb_hid_u2f;
extern FuriHalUsbInterface usb_ccid;
typedef enum {
FuriHalUsbStateEventReset,
FuriHalUsbStateEventWakeup,
FuriHalUsbStateEventSuspend,
FuriHalUsbStateEventDescriptorRequest,
} FuriHalUsbStateEvent;
typedef void (*FuriHalUsbStateCallback)(FuriHalUsbStateEvent state, void* context);
/** USB device low-level initialization
*/
void furi_hal_usb_init();
/** Set USB device configuration
*
* @param mode new USB device mode
* @param ctx context passed to device mode init function
* @return true - mode switch started, false - mode switch is locked
*/
bool furi_hal_usb_set_config(FuriHalUsbInterface* new_if, void* ctx);
/** Get USB device configuration
*
* @return current USB device mode
*/
FuriHalUsbInterface* furi_hal_usb_get_config();
/** Lock USB device mode switch
*/
void furi_hal_usb_lock();
/** Unlock USB device mode switch
*/
void furi_hal_usb_unlock();
/** Check if USB device mode switch locked
*
* @return lock state
*/
bool furi_hal_usb_is_locked();
/** Disable USB device
*/
void furi_hal_usb_disable();
/** Enable USB device
*/
void furi_hal_usb_enable();
/** Set USB state callback
*/
void furi_hal_usb_set_state_callback(FuriHalUsbStateCallback cb, void* ctx);
/** Restart USB device
*/
void furi_hal_usb_reinit();
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,36 @@
#pragma once
#include "hid_usage_desktop.h"
#include "hid_usage_button.h"
#include "hid_usage_keyboard.h"
#include "hid_usage_consumer.h"
#include "hid_usage_led.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
uint16_t vid;
uint16_t pid;
char manuf[32];
char product[32];
} FuriHalUsbCcidConfig;
typedef struct {
void (*icc_power_on_callback)(uint8_t* dataBlock, uint32_t* dataBlockLen, void* context);
void (*xfr_datablock_callback)(
const uint8_t* dataBlock,
uint32_t dataBlockLen,
uint8_t* responseDataBlock,
uint32_t* responseDataBlockLen,
void* context);
} CcidCallbacks;
void furi_hal_ccid_set_callbacks(CcidCallbacks* cb);
void furi_hal_ccid_ccid_insert_smartcard();
void furi_hal_ccid_ccid_remove_smartcard();
#ifdef __cplusplus
}
#endif
+264
View File
@@ -0,0 +1,264 @@
#pragma once
#include "hid_usage_desktop.h"
#include "hid_usage_button.h"
#include "hid_usage_keyboard.h"
#include "hid_usage_consumer.h"
#include "hid_usage_led.h"
#ifdef __cplusplus
extern "C" {
#endif
/** Max number of simultaneously pressed keys (keyboard) */
#define HID_KB_MAX_KEYS 6
/** Max number of simultaneously pressed keys (consumer control) */
#define HID_CONSUMER_MAX_KEYS 2
#define HID_KEYBOARD_NONE 0x00
/** HID keyboard modifier keys */
enum HidKeyboardMods {
KEY_MOD_LEFT_CTRL = (1 << 8),
KEY_MOD_LEFT_SHIFT = (1 << 9),
KEY_MOD_LEFT_ALT = (1 << 10),
KEY_MOD_LEFT_GUI = (1 << 11),
KEY_MOD_RIGHT_CTRL = (1 << 12),
KEY_MOD_RIGHT_SHIFT = (1 << 13),
KEY_MOD_RIGHT_ALT = (1 << 14),
KEY_MOD_RIGHT_GUI = (1 << 15),
};
/** ASCII to keycode conversion table */
static const uint16_t hid_asciimap[] = {
HID_KEYBOARD_NONE, // NUL
HID_KEYBOARD_NONE, // SOH
HID_KEYBOARD_NONE, // STX
HID_KEYBOARD_NONE, // ETX
HID_KEYBOARD_NONE, // EOT
HID_KEYBOARD_NONE, // ENQ
HID_KEYBOARD_NONE, // ACK
HID_KEYBOARD_NONE, // BEL
HID_KEYBOARD_DELETE, // BS Backspace
HID_KEYBOARD_TAB, // TAB Tab
HID_KEYBOARD_RETURN, // LF Enter
HID_KEYBOARD_NONE, // VT
HID_KEYBOARD_NONE, // FF
HID_KEYBOARD_NONE, // CR
HID_KEYBOARD_NONE, // SO
HID_KEYBOARD_NONE, // SI
HID_KEYBOARD_NONE, // DEL
HID_KEYBOARD_NONE, // DC1
HID_KEYBOARD_NONE, // DC2
HID_KEYBOARD_NONE, // DC3
HID_KEYBOARD_NONE, // DC4
HID_KEYBOARD_NONE, // NAK
HID_KEYBOARD_NONE, // SYN
HID_KEYBOARD_NONE, // ETB
HID_KEYBOARD_NONE, // CAN
HID_KEYBOARD_NONE, // EM
HID_KEYBOARD_NONE, // SUB
HID_KEYBOARD_NONE, // ESC
HID_KEYBOARD_NONE, // FS
HID_KEYBOARD_NONE, // GS
HID_KEYBOARD_NONE, // RS
HID_KEYBOARD_NONE, // US
HID_KEYBOARD_SPACEBAR, // ' ' Space
HID_KEYBOARD_1 | KEY_MOD_LEFT_SHIFT, // !
HID_KEYBOARD_APOSTROPHE | KEY_MOD_LEFT_SHIFT, // "
HID_KEYBOARD_3 | KEY_MOD_LEFT_SHIFT, // #
HID_KEYBOARD_4 | KEY_MOD_LEFT_SHIFT, // $
HID_KEYBOARD_5 | KEY_MOD_LEFT_SHIFT, // %
HID_KEYBOARD_7 | KEY_MOD_LEFT_SHIFT, // &
HID_KEYBOARD_APOSTROPHE, // '
HID_KEYBOARD_9 | KEY_MOD_LEFT_SHIFT, // (
HID_KEYBOARD_0 | KEY_MOD_LEFT_SHIFT, // )
HID_KEYBOARD_8 | KEY_MOD_LEFT_SHIFT, // *
HID_KEYBOARD_EQUAL_SIGN | KEY_MOD_LEFT_SHIFT, // +
HID_KEYBOARD_COMMA, // ,
HID_KEYBOARD_MINUS, // -
HID_KEYBOARD_DOT, // .
HID_KEYBOARD_SLASH, // /
HID_KEYBOARD_0, // 0
HID_KEYBOARD_1, // 1
HID_KEYBOARD_2, // 2
HID_KEYBOARD_3, // 3
HID_KEYBOARD_4, // 4
HID_KEYBOARD_5, // 5
HID_KEYBOARD_6, // 6
HID_KEYBOARD_7, // 7
HID_KEYBOARD_8, // 8
HID_KEYBOARD_9, // 9
HID_KEYBOARD_SEMICOLON | KEY_MOD_LEFT_SHIFT, // :
HID_KEYBOARD_SEMICOLON, // ;
HID_KEYBOARD_COMMA | KEY_MOD_LEFT_SHIFT, // <
HID_KEYBOARD_EQUAL_SIGN, // =
HID_KEYBOARD_DOT | KEY_MOD_LEFT_SHIFT, // >
HID_KEYBOARD_SLASH | KEY_MOD_LEFT_SHIFT, // ?
HID_KEYBOARD_2 | KEY_MOD_LEFT_SHIFT, // @
HID_KEYBOARD_A | KEY_MOD_LEFT_SHIFT, // A
HID_KEYBOARD_B | KEY_MOD_LEFT_SHIFT, // B
HID_KEYBOARD_C | KEY_MOD_LEFT_SHIFT, // C
HID_KEYBOARD_D | KEY_MOD_LEFT_SHIFT, // D
HID_KEYBOARD_E | KEY_MOD_LEFT_SHIFT, // E
HID_KEYBOARD_F | KEY_MOD_LEFT_SHIFT, // F
HID_KEYBOARD_G | KEY_MOD_LEFT_SHIFT, // G
HID_KEYBOARD_H | KEY_MOD_LEFT_SHIFT, // H
HID_KEYBOARD_I | KEY_MOD_LEFT_SHIFT, // I
HID_KEYBOARD_J | KEY_MOD_LEFT_SHIFT, // J
HID_KEYBOARD_K | KEY_MOD_LEFT_SHIFT, // K
HID_KEYBOARD_L | KEY_MOD_LEFT_SHIFT, // L
HID_KEYBOARD_M | KEY_MOD_LEFT_SHIFT, // M
HID_KEYBOARD_N | KEY_MOD_LEFT_SHIFT, // N
HID_KEYBOARD_O | KEY_MOD_LEFT_SHIFT, // O
HID_KEYBOARD_P | KEY_MOD_LEFT_SHIFT, // P
HID_KEYBOARD_Q | KEY_MOD_LEFT_SHIFT, // Q
HID_KEYBOARD_R | KEY_MOD_LEFT_SHIFT, // R
HID_KEYBOARD_S | KEY_MOD_LEFT_SHIFT, // S
HID_KEYBOARD_T | KEY_MOD_LEFT_SHIFT, // T
HID_KEYBOARD_U | KEY_MOD_LEFT_SHIFT, // U
HID_KEYBOARD_V | KEY_MOD_LEFT_SHIFT, // V
HID_KEYBOARD_W | KEY_MOD_LEFT_SHIFT, // W
HID_KEYBOARD_X | KEY_MOD_LEFT_SHIFT, // X
HID_KEYBOARD_Y | KEY_MOD_LEFT_SHIFT, // Y
HID_KEYBOARD_Z | KEY_MOD_LEFT_SHIFT, // Z
HID_KEYBOARD_OPEN_BRACKET, // [
HID_KEYBOARD_BACKSLASH, // bslash
HID_KEYBOARD_CLOSE_BRACKET, // ]
HID_KEYBOARD_6 | KEY_MOD_LEFT_SHIFT, // ^
HID_KEYBOARD_MINUS | KEY_MOD_LEFT_SHIFT, // _
HID_KEYBOARD_GRAVE_ACCENT, // `
HID_KEYBOARD_A, // a
HID_KEYBOARD_B, // b
HID_KEYBOARD_C, // c
HID_KEYBOARD_D, // d
HID_KEYBOARD_E, // e
HID_KEYBOARD_F, // f
HID_KEYBOARD_G, // g
HID_KEYBOARD_H, // h
HID_KEYBOARD_I, // i
HID_KEYBOARD_J, // j
HID_KEYBOARD_K, // k
HID_KEYBOARD_L, // l
HID_KEYBOARD_M, // m
HID_KEYBOARD_N, // n
HID_KEYBOARD_O, // o
HID_KEYBOARD_P, // p
HID_KEYBOARD_Q, // q
HID_KEYBOARD_R, // r
HID_KEYBOARD_S, // s
HID_KEYBOARD_T, // t
HID_KEYBOARD_U, // u
HID_KEYBOARD_V, // v
HID_KEYBOARD_W, // w
HID_KEYBOARD_X, // x
HID_KEYBOARD_Y, // y
HID_KEYBOARD_Z, // z
HID_KEYBOARD_OPEN_BRACKET | KEY_MOD_LEFT_SHIFT, // {
HID_KEYBOARD_BACKSLASH | KEY_MOD_LEFT_SHIFT, // |
HID_KEYBOARD_CLOSE_BRACKET | KEY_MOD_LEFT_SHIFT, // }
HID_KEYBOARD_GRAVE_ACCENT | KEY_MOD_LEFT_SHIFT, // ~
HID_KEYBOARD_NONE, // DEL
};
typedef struct {
uint32_t vid;
uint32_t pid;
char manuf[32];
char product[32];
} FuriHalUsbHidConfig;
typedef void (*HidStateCallback)(bool state, void* context);
/** ASCII to keycode conversion macro */
#define HID_ASCII_TO_KEY(x) (((uint8_t)x < 128) ? (hid_asciimap[(uint8_t)x]) : HID_KEYBOARD_NONE)
/** HID keyboard leds */
enum HidKeyboardLeds {
HID_KB_LED_NUM = (1 << 0),
HID_KB_LED_CAPS = (1 << 1),
HID_KB_LED_SCROLL = (1 << 2),
};
/** HID mouse buttons */
enum HidMouseButtons {
HID_MOUSE_BTN_LEFT = (1 << 0),
HID_MOUSE_BTN_RIGHT = (1 << 1),
HID_MOUSE_BTN_WHEEL = (1 << 2),
};
/** Get USB HID connection state
*
* @return true / false
*/
bool furi_hal_hid_is_connected();
/** Get USB HID keyboard leds state
*
* @return leds state
*/
uint8_t furi_hal_hid_get_led_state();
/** Set USB HID connect/disconnect callback
*
* @param cb callback
* @param ctx callback context
*/
void furi_hal_hid_set_state_callback(HidStateCallback cb, void* ctx);
/** Set the following key to pressed state and send HID report
*
* @param button key code
*/
bool furi_hal_hid_kb_press(uint16_t button);
/** Set the following key to released state and send HID report
*
* @param button key code
*/
bool furi_hal_hid_kb_release(uint16_t button);
/** Clear all pressed keys and send HID report
*
*/
bool furi_hal_hid_kb_release_all();
/** Set mouse movement and send HID report
*
* @param dx x coordinate delta
* @param dy y coordinate delta
*/
bool furi_hal_hid_mouse_move(int8_t dx, int8_t dy);
/** Set mouse button to pressed state and send HID report
*
* @param button key code
*/
bool furi_hal_hid_mouse_press(uint8_t button);
/** Set mouse button to released state and send HID report
*
* @param button key code
*/
bool furi_hal_hid_mouse_release(uint8_t button);
/** Set mouse wheel position and send HID report
*
* @param delta number of scroll steps
*/
bool furi_hal_hid_mouse_scroll(int8_t delta);
/** Set the following consumer key to pressed state and send HID report
*
* @param button key code
*/
bool furi_hal_hid_consumer_key_press(uint16_t button);
/** Set the following consumer key to released state and send HID report
*
* @param button key code
*/
bool furi_hal_hid_consumer_key_release(uint16_t button);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,44 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#define HID_U2F_PACKET_LEN 64
typedef enum {
HidU2fDisconnected,
HidU2fConnected,
HidU2fRequest,
} HidU2fEvent;
typedef void (*HidU2fCallback)(HidU2fEvent ev, void* context);
/** Get HID U2F connection state
*
* @return true / false
*/
bool furi_hal_hid_u2f_is_connected();
/** Set HID U2F event callback
*
* @param cb callback
* @param ctx callback context
*/
void furi_hal_hid_u2f_set_callback(HidU2fCallback cb, void* ctx);
/** Get received U2F HID packet
*
*/
uint32_t furi_hal_hid_u2f_get_request(uint8_t* data);
/** Send U2F HID response packet
*
* @param data response data
* @param len packet length
*/
void furi_hal_hid_u2f_send_response(uint8_t* data, uint8_t len);
#ifdef __cplusplus
}
#endif
+199
View File
@@ -0,0 +1,199 @@
/**
* @file furi_hal_version.h
* Version HAL API
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <lib/toolbox/version.h>
#ifdef __cplusplus
extern "C" {
#endif
#define FURI_HAL_VERSION_NAME_LENGTH 8
#define FURI_HAL_VERSION_ARRAY_NAME_LENGTH (FURI_HAL_VERSION_NAME_LENGTH + 1)
/** BLE symbol + "Flipper " + name */
#define FURI_HAL_VERSION_DEVICE_NAME_LENGTH (1 + 8 + FURI_HAL_VERSION_ARRAY_NAME_LENGTH)
/** OTP Versions enum */
typedef enum {
FuriHalVersionOtpVersion0 = 0x00,
FuriHalVersionOtpVersion1 = 0x01,
FuriHalVersionOtpVersion2 = 0x02,
FuriHalVersionOtpVersionEmpty = 0xFFFFFFFE,
FuriHalVersionOtpVersionUnknown = 0xFFFFFFFF,
} FuriHalVersionOtpVersion;
/** Device Colors */
typedef enum {
FuriHalVersionColorUnknown = 0x00,
FuriHalVersionColorBlack = 0x01,
FuriHalVersionColorWhite = 0x02,
FuriHalVersionColorTransparent = 0x03,
} FuriHalVersionColor;
/** Device Regions */
typedef enum {
FuriHalVersionRegionUnknown = 0x00,
FuriHalVersionRegionEuRu = 0x01,
FuriHalVersionRegionUsCaAu = 0x02,
FuriHalVersionRegionJp = 0x03,
FuriHalVersionRegionWorld = 0x04,
} FuriHalVersionRegion;
/** Device Display */
typedef enum {
FuriHalVersionDisplayUnknown = 0x00,
FuriHalVersionDisplayErc = 0x01,
FuriHalVersionDisplayMgg = 0x02,
} FuriHalVersionDisplay;
/** Init flipper version
*/
void furi_hal_version_init();
/** Check target firmware version
*
* @return true if target and real matches
*/
bool furi_hal_version_do_i_belong_here();
/** Get model name
*
* @return model name C-string
*/
const char* furi_hal_version_get_model_name();
/** Get model name
*
* @return model code C-string
*/
const char* furi_hal_version_get_model_code();
/** Get FCC ID
*
* @return FCC id as C-string
*/
const char* furi_hal_version_get_fcc_id();
/** Get IC id
*
* @return IC id as C-string
*/
const char* furi_hal_version_get_ic_id();
/** Get MIC id
*
* @return MIC id as C-string
*/
const char* furi_hal_version_get_mic_id();
/** Get OTP version
*
* @return OTP Version
*/
FuriHalVersionOtpVersion furi_hal_version_get_otp_version();
/** Get hardware version
*
* @return Hardware Version
*/
uint8_t furi_hal_version_get_hw_version();
/** Get hardware target
*
* @return Hardware Target
*/
uint8_t furi_hal_version_get_hw_target();
/** Get hardware body
*
* @return Hardware Body
*/
uint8_t furi_hal_version_get_hw_body();
/** Get hardware body color
*
* @return Hardware Color
*/
FuriHalVersionColor furi_hal_version_get_hw_color();
/** Get hardware connect
*
* @return Hardware Interconnect
*/
uint8_t furi_hal_version_get_hw_connect();
/** Get hardware region
*
* @return Hardware Region
*/
FuriHalVersionRegion furi_hal_version_get_hw_region();
/** Get hardware region name
*
* @return Hardware Region name
*/
const char* furi_hal_version_get_hw_region_name();
/** Get hardware display id
*
* @return Display id
*/
FuriHalVersionDisplay furi_hal_version_get_hw_display();
/** Get hardware timestamp
*
* @return Hardware Manufacture timestamp
*/
uint32_t furi_hal_version_get_hw_timestamp();
/** Get pointer to target name
*
* @return Hardware Name C-string
*/
const char* furi_hal_version_get_name_ptr();
/** Get pointer to target device name
*
* @return Hardware Device Name C-string
*/
const char* furi_hal_version_get_device_name_ptr();
/** Get pointer to target ble local device name
*
* @return Ble Device Name C-string
*/
const char* furi_hal_version_get_ble_local_device_name_ptr();
/** Get BLE MAC address
*
* @return pointer to BLE MAC address
*/
const uint8_t* furi_hal_version_get_ble_mac();
/** Get address of version structure of firmware.
*
* @return Address of firmware version structure.
*/
const struct Version* furi_hal_version_get_firmware_version();
/** Get platform UID size in bytes
*
* @return UID size in bytes
*/
size_t furi_hal_version_uid_size();
/** Get const pointer to UID
*
* @return pointer to UID
*/
const uint8_t* furi_hal_version_uid();
#ifdef __cplusplus
}
#endif
+28
View File
@@ -0,0 +1,28 @@
/**
* @file furi_hal_vibro.h
* Vibro HAL API
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <furi_hal_resources.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Initialize vibro
*/
void furi_hal_vibro_init();
/** Turn on/off vibro
*
* @param[in] value new state
*/
void furi_hal_vibro_on(bool value);
#ifdef __cplusplus
}
#endif