[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:
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user