Merge branch 'dev' into nfcf

This commit is contained in:
nullableVoidPtr
2023-03-24 18:55:58 +11:00
1084 changed files with 30782 additions and 11463 deletions
+4 -13
View File
@@ -2,15 +2,6 @@ Import("env")
env.Append(
LINT_SOURCES=[Dir(".")],
SDK_HEADERS=[
*env.GlobRecursive("*.h", "targets/furi_hal_include", "*_i.h"),
*env.GlobRecursive("*.h", "targets/f${TARGET_HW}/furi_hal", "*_i.h"),
File("targets/f7/platform_specific/intrinsic_export.h"),
],
)
env.SetDefault(
SDK_DEFINITION=env.File("./targets/f${TARGET_HW}/api_symbols.csv").srcnode()
)
libenv = env.Clone(FW_LIB_NAME="flipper${TARGET_HW}")
@@ -22,9 +13,9 @@ libenv.Append(
libenv.ApplyLibFlags()
sources = ["targets/f${TARGET_HW}/startup_stm32wb55xx_cm4.s"]
sources += libenv.GlobRecursive("*.c")
lib = libenv.StaticLibrary("${FW_LIB_NAME}", sources)
lib = libenv.StaticLibrary(
"${FW_LIB_NAME}",
env.get("TARGET_CFG").gatherSources(),
)
libenv.Install("${LIB_DIST_DIR}", lib)
Return("lib")
File diff suppressed because it is too large Load Diff
+62
View File
@@ -0,0 +1,62 @@
#include <furi_hal.h>
#include <furi_hal_mpu.h>
#include <furi_hal_memory.h>
#include <stm32wbxx_ll_cortex.h>
#define TAG "FuriHal"
void furi_hal_init_early() {
furi_hal_cortex_init_early();
furi_hal_clock_init_early();
furi_hal_resources_init_early();
furi_hal_os_init();
furi_hal_spi_config_init_early();
furi_hal_i2c_init_early();
furi_hal_light_init();
furi_hal_rtc_init_early();
}
void furi_hal_deinit_early() {
furi_hal_rtc_deinit_early();
furi_hal_i2c_deinit_early();
furi_hal_spi_config_deinit_early();
furi_hal_resources_deinit_early();
furi_hal_clock_deinit_early();
}
void furi_hal_init() {
furi_hal_mpu_init();
furi_hal_clock_init();
furi_hal_console_init();
furi_hal_rtc_init();
furi_hal_interrupt_init();
furi_hal_flash_init();
furi_hal_resources_init();
furi_hal_version_init();
furi_hal_spi_config_init();
furi_hal_spi_dma_init();
furi_hal_speaker_init();
furi_hal_crypto_init();
furi_hal_i2c_init();
furi_hal_power_init();
furi_hal_light_init();
furi_hal_bt_init();
furi_hal_memory_init();
#ifndef FURI_RAM_EXEC
furi_hal_usb_init();
furi_hal_vibro_init();
#endif
}
void furi_hal_switch(void* address) {
__set_BASEPRI(0);
asm volatile("ldr r3, [%0] \n"
"msr msp, r3 \n"
"ldr r3, [%1] \n"
"mov pc, r3 \n"
:
: "r"(address), "r"(address + 0x4)
: "r3");
}
@@ -0,0 +1,229 @@
#include <furi_hal_resources.h>
#include <furi.h>
#include <stm32wbxx_ll_rcc.h>
#include <stm32wbxx_ll_pwr.h>
#define TAG "FuriHalResources"
const GpioPin vibro_gpio = {.port = GPIOA, .pin = LL_GPIO_PIN_8};
const GpioPin ibutton_gpio = {.port = GPIOB, .pin = LL_GPIO_PIN_14};
const GpioPin gpio_display_cs = {.port = GPIOC, .pin = LL_GPIO_PIN_11};
const GpioPin gpio_display_rst_n = {.port = GPIOB, .pin = LL_GPIO_PIN_0};
const GpioPin gpio_display_di = {.port = GPIOB, .pin = LL_GPIO_PIN_1};
const GpioPin gpio_sdcard_cs = {.port = GPIOC, .pin = LL_GPIO_PIN_12};
const GpioPin gpio_sdcard_cd = {.port = GPIOC, .pin = LL_GPIO_PIN_10};
const GpioPin gpio_button_up = {.port = GPIOB, .pin = LL_GPIO_PIN_10};
const GpioPin gpio_button_down = {.port = GPIOC, .pin = LL_GPIO_PIN_6};
const GpioPin gpio_button_right = {.port = GPIOB, .pin = LL_GPIO_PIN_12};
const GpioPin gpio_button_left = {.port = GPIOB, .pin = LL_GPIO_PIN_11};
const GpioPin gpio_button_ok = {.port = GPIOH, .pin = LL_GPIO_PIN_3};
const GpioPin gpio_button_back = {.port = GPIOC, .pin = LL_GPIO_PIN_13};
const GpioPin gpio_spi_d_miso = {.port = GPIOC, .pin = LL_GPIO_PIN_2};
const GpioPin gpio_spi_d_mosi = {.port = GPIOB, .pin = LL_GPIO_PIN_15};
const GpioPin gpio_spi_d_sck = {.port = GPIOD, .pin = LL_GPIO_PIN_1};
const GpioPin gpio_ext_pc0 = {.port = GPIOC, .pin = LL_GPIO_PIN_0};
const GpioPin gpio_ext_pc1 = {.port = GPIOC, .pin = LL_GPIO_PIN_1};
const GpioPin gpio_ext_pc3 = {.port = GPIOC, .pin = LL_GPIO_PIN_3};
const GpioPin gpio_ext_pb2 = {.port = GPIOB, .pin = LL_GPIO_PIN_2};
const GpioPin gpio_ext_pb3 = {.port = GPIOB, .pin = LL_GPIO_PIN_3};
const GpioPin gpio_ext_pa4 = {.port = GPIOA, .pin = LL_GPIO_PIN_4};
const GpioPin gpio_ext_pa6 = {.port = GPIOA, .pin = LL_GPIO_PIN_6};
const GpioPin gpio_ext_pa7 = {.port = GPIOA, .pin = LL_GPIO_PIN_7};
const GpioPin gpio_ext_pc5 = {.port = GPIOC, .pin = LL_GPIO_PIN_5};
const GpioPin gpio_ext_pc4 = {.port = GPIOC, .pin = LL_GPIO_PIN_4};
const GpioPin gpio_ext_pa5 = {.port = GPIOA, .pin = LL_GPIO_PIN_5};
const GpioPin gpio_ext_pb9 = {.port = GPIOB, .pin = LL_GPIO_PIN_9};
const GpioPin gpio_ext_pa0 = {.port = GPIOA, .pin = LL_GPIO_PIN_0};
const GpioPin gpio_ext_pa1 = {.port = GPIOA, .pin = LL_GPIO_PIN_1};
const GpioPin gpio_ext_pa15 = {.port = GPIOA, .pin = LL_GPIO_PIN_15};
const GpioPin gpio_ext_pe4 = {.port = GPIOE, .pin = LL_GPIO_PIN_4};
const GpioPin gpio_ext_pa2 = {.port = GPIOA, .pin = LL_GPIO_PIN_2};
const GpioPin gpio_ext_pb4 = {.port = GPIOB, .pin = LL_GPIO_PIN_4};
const GpioPin gpio_ext_pb5 = {.port = GPIOB, .pin = LL_GPIO_PIN_5};
const GpioPin gpio_ext_pd0 = {.port = GPIOD, .pin = LL_GPIO_PIN_0};
const GpioPin gpio_ext_pb13 = {.port = GPIOB, .pin = LL_GPIO_PIN_13};
const GpioPin gpio_usart_tx = {.port = GPIOB, .pin = LL_GPIO_PIN_6};
const GpioPin gpio_usart_rx = {.port = GPIOB, .pin = LL_GPIO_PIN_7};
const GpioPin gpio_i2c_power_sda = {.port = GPIOA, .pin = LL_GPIO_PIN_10};
const GpioPin gpio_i2c_power_scl = {.port = GPIOA, .pin = LL_GPIO_PIN_9};
const GpioPin gpio_speaker = {.port = GPIOB, .pin = LL_GPIO_PIN_8};
const GpioPin periph_power = {.port = GPIOA, .pin = LL_GPIO_PIN_3};
const GpioPin gpio_usb_dm = {.port = GPIOA, .pin = LL_GPIO_PIN_11};
const GpioPin gpio_usb_dp = {.port = GPIOA, .pin = LL_GPIO_PIN_12};
const GpioPinRecord gpio_pins[] = {
{.pin = &gpio_ext_pa7, .name = "PA7", .debug = false},
{.pin = &gpio_ext_pa6, .name = "PA6", .debug = false},
{.pin = &gpio_ext_pa4, .name = "PA4", .debug = false},
{.pin = &gpio_ext_pb3, .name = "PB3", .debug = false},
{.pin = &gpio_ext_pb2, .name = "PB2", .debug = false},
{.pin = &gpio_ext_pc3, .name = "PC3", .debug = false},
{.pin = &gpio_ext_pc1, .name = "PC1", .debug = false},
{.pin = &gpio_ext_pc0, .name = "PC0", .debug = false},
{.pin = &gpio_ext_pc5, .name = "PC5", .debug = false},
{.pin = &gpio_ext_pc4, .name = "PC4", .debug = false},
{.pin = &gpio_ext_pa5, .name = "PA5", .debug = false},
{.pin = &gpio_ext_pb9, .name = "PB9", .debug = false},
{.pin = &gpio_ext_pa0, .name = "PA0", .debug = false},
{.pin = &gpio_ext_pa1, .name = "PA1", .debug = false},
{.pin = &gpio_ext_pa15, .name = "PA15", .debug = false},
{.pin = &gpio_ext_pe4, .name = "PE4", .debug = false},
{.pin = &gpio_ext_pa2, .name = "PA2", .debug = false},
{.pin = &gpio_ext_pb4, .name = "PB4", .debug = false},
{.pin = &gpio_ext_pb5, .name = "PB5", .debug = false},
{.pin = &gpio_ext_pd0, .name = "PD0", .debug = false},
{.pin = &gpio_ext_pb13, .name = "PB13", .debug = false},
/* Dangerous pins, may damage hardware */
{.pin = &gpio_usart_rx, .name = "PB7", .debug = true},
{.pin = &gpio_speaker, .name = "PB8", .debug = true},
};
const size_t gpio_pins_count = sizeof(gpio_pins) / sizeof(GpioPinRecord);
const InputPin input_pins[] = {
{.gpio = &gpio_button_up, .key = InputKeyUp, .inverted = true, .name = "Up"},
{.gpio = &gpio_button_down, .key = InputKeyDown, .inverted = true, .name = "Down"},
{.gpio = &gpio_button_right, .key = InputKeyRight, .inverted = true, .name = "Right"},
{.gpio = &gpio_button_left, .key = InputKeyLeft, .inverted = true, .name = "Left"},
{.gpio = &gpio_button_ok, .key = InputKeyOk, .inverted = false, .name = "OK"},
{.gpio = &gpio_button_back, .key = InputKeyBack, .inverted = true, .name = "Back"},
};
const size_t input_pins_count = sizeof(input_pins) / sizeof(InputPin);
static void furi_hal_resources_init_input_pins(GpioMode mode) {
for(size_t i = 0; i < input_pins_count; i++) {
furi_hal_gpio_init(
input_pins[i].gpio,
mode,
(input_pins[i].inverted) ? GpioPullUp : GpioPullDown,
GpioSpeedLow);
}
}
void furi_hal_resources_init_early() {
furi_hal_resources_init_input_pins(GpioModeInput);
// SD Card stepdown control
furi_hal_gpio_write(&periph_power, 1);
furi_hal_gpio_init(&periph_power, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow);
// Display pins
furi_hal_gpio_write(&gpio_display_rst_n, 1);
furi_hal_gpio_init_simple(&gpio_display_rst_n, GpioModeOutputPushPull);
furi_hal_gpio_init(&gpio_display_di, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow);
// Pullup display reset pin for shutdown
SET_BIT(PWR->PUCRB, gpio_display_rst_n.pin);
CLEAR_BIT(PWR->PDCRB, gpio_display_rst_n.pin);
SET_BIT(PWR->CR3, PWR_CR3_APC);
// Hard reset USB
furi_hal_gpio_write(&gpio_usb_dm, 1);
furi_hal_gpio_write(&gpio_usb_dp, 1);
furi_hal_gpio_init_simple(&gpio_usb_dm, GpioModeOutputOpenDrain);
furi_hal_gpio_init_simple(&gpio_usb_dp, GpioModeOutputOpenDrain);
furi_hal_gpio_write(&gpio_usb_dm, 0);
furi_hal_gpio_write(&gpio_usb_dp, 0);
furi_delay_us(5); // Device Driven disconnect: 2.5us + extra to compensate cables
furi_hal_gpio_write(&gpio_usb_dm, 1);
furi_hal_gpio_write(&gpio_usb_dp, 1);
furi_hal_gpio_init_simple(&gpio_usb_dm, GpioModeAnalog);
furi_hal_gpio_init_simple(&gpio_usb_dp, GpioModeAnalog);
furi_hal_gpio_write(&gpio_usb_dm, 0);
furi_hal_gpio_write(&gpio_usb_dp, 0);
// External header pins
furi_hal_gpio_init(&gpio_ext_pc0, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
furi_hal_gpio_init(&gpio_ext_pc1, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
furi_hal_gpio_init(&gpio_ext_pc3, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
furi_hal_gpio_init(&gpio_ext_pb2, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
furi_hal_gpio_init(&gpio_ext_pb3, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
furi_hal_gpio_init(&gpio_ext_pa4, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
furi_hal_gpio_init(&gpio_ext_pa6, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
furi_hal_gpio_init(&gpio_ext_pa7, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
}
void furi_hal_resources_deinit_early() {
furi_hal_resources_init_input_pins(GpioModeAnalog);
}
void furi_hal_resources_init() {
// Button pins
furi_hal_resources_init_input_pins(GpioModeInterruptRiseFall);
// Display pins
furi_hal_gpio_init(&gpio_display_rst_n, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow);
furi_hal_gpio_write(&gpio_display_rst_n, 0);
furi_hal_gpio_init(&gpio_display_di, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow);
furi_hal_gpio_write(&gpio_display_di, 0);
// SD pins
furi_hal_gpio_init(&gpio_sdcard_cd, GpioModeInput, GpioPullNo, GpioSpeedLow);
furi_hal_gpio_write(&gpio_sdcard_cd, 0);
furi_hal_gpio_init(&vibro_gpio, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
furi_hal_gpio_init(&ibutton_gpio, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
NVIC_SetPriority(EXTI0_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
NVIC_EnableIRQ(EXTI0_IRQn);
NVIC_SetPriority(EXTI1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
NVIC_EnableIRQ(EXTI1_IRQn);
NVIC_SetPriority(EXTI2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
NVIC_EnableIRQ(EXTI2_IRQn);
NVIC_SetPriority(EXTI3_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
NVIC_EnableIRQ(EXTI3_IRQn);
NVIC_SetPriority(EXTI4_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
NVIC_EnableIRQ(EXTI4_IRQn);
NVIC_SetPriority(EXTI9_5_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
NVIC_EnableIRQ(EXTI9_5_IRQn);
NVIC_SetPriority(EXTI15_10_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
NVIC_EnableIRQ(EXTI15_10_IRQn);
FURI_LOG_I(TAG, "Init OK");
}
int32_t furi_hal_resources_get_ext_pin_number(const GpioPin* gpio) {
// TODO: describe second ROW
if(gpio == &gpio_ext_pa7)
return 2;
else if(gpio == &gpio_ext_pa6)
return 3;
else if(gpio == &gpio_ext_pa4)
return 4;
else if(gpio == &gpio_ext_pb3)
return 5;
else if(gpio == &gpio_ext_pb2)
return 6;
else if(gpio == &gpio_ext_pc3)
return 7;
else if(gpio == &gpio_ext_pc1)
return 15;
else if(gpio == &gpio_ext_pc0)
return 16;
else if(gpio == &ibutton_gpio)
return 17;
else
return -1;
}
@@ -0,0 +1,123 @@
#pragma once
#include <furi.h>
#include <stm32wbxx.h>
#include <stm32wbxx_ll_gpio.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Input Related Constants */
#define INPUT_DEBOUNCE_TICKS 4
/* Input Keys */
typedef enum {
InputKeyUp,
InputKeyDown,
InputKeyRight,
InputKeyLeft,
InputKeyOk,
InputKeyBack,
InputKeyMAX, /**< Special value */
} InputKey;
/* Light */
typedef enum {
LightRed = (1 << 0),
LightGreen = (1 << 1),
LightBlue = (1 << 2),
LightBacklight = (1 << 3),
} Light;
typedef struct {
const GpioPin* gpio;
const InputKey key;
const bool inverted;
const char* name;
} InputPin;
typedef struct {
const GpioPin* pin;
const char* name;
const bool debug;
} GpioPinRecord;
extern const InputPin input_pins[];
extern const size_t input_pins_count;
extern const GpioPinRecord gpio_pins[];
extern const size_t gpio_pins_count;
extern const GpioPin vibro_gpio;
extern const GpioPin ibutton_gpio;
extern const GpioPin gpio_display_cs;
extern const GpioPin gpio_display_rst_n;
extern const GpioPin gpio_display_di;
extern const GpioPin gpio_sdcard_cs;
extern const GpioPin gpio_sdcard_cd;
extern const GpioPin gpio_button_up;
extern const GpioPin gpio_button_down;
extern const GpioPin gpio_button_right;
extern const GpioPin gpio_button_left;
extern const GpioPin gpio_button_ok;
extern const GpioPin gpio_button_back;
extern const GpioPin gpio_spi_d_miso;
extern const GpioPin gpio_spi_d_mosi;
extern const GpioPin gpio_spi_d_sck;
extern const GpioPin gpio_ext_pc0;
extern const GpioPin gpio_ext_pc1;
extern const GpioPin gpio_ext_pc3;
extern const GpioPin gpio_ext_pb2;
extern const GpioPin gpio_ext_pb3;
extern const GpioPin gpio_ext_pa4;
extern const GpioPin gpio_ext_pa6;
extern const GpioPin gpio_ext_pa7;
extern const GpioPin gpio_ext_pc5;
extern const GpioPin gpio_ext_pc4;
extern const GpioPin gpio_ext_pa5;
extern const GpioPin gpio_ext_pb9;
extern const GpioPin gpio_ext_pa0;
extern const GpioPin gpio_ext_pa1;
extern const GpioPin gpio_ext_pa15;
extern const GpioPin gpio_ext_pe4;
extern const GpioPin gpio_ext_pa2;
extern const GpioPin gpio_ext_pb4;
extern const GpioPin gpio_ext_pb5;
extern const GpioPin gpio_ext_pd0;
extern const GpioPin gpio_ext_pb13;
extern const GpioPin gpio_usart_tx;
extern const GpioPin gpio_usart_rx;
extern const GpioPin gpio_i2c_power_sda;
extern const GpioPin gpio_i2c_power_scl;
extern const GpioPin gpio_speaker;
extern const GpioPin periph_power;
extern const GpioPin gpio_usb_dm;
extern const GpioPin gpio_usb_dp;
void furi_hal_resources_init_early();
void furi_hal_resources_deinit_early();
void furi_hal_resources_init();
/**
* Get a corresponding external connector pin number for a gpio
* @param gpio GpioPin
* @return pin number or -1 if gpio is not on the external connector
*/
int32_t furi_hal_resources_get_ext_pin_number(const GpioPin* gpio);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,377 @@
#include <furi_hal_spi_config.h>
#include <furi_hal_resources.h>
#include <furi_hal_spi.h>
#include <furi.h>
#define TAG "FuriHalSpiConfig"
/* SPI Presets */
const LL_SPI_InitTypeDef furi_hal_spi_preset_2edge_low_8m = {
.Mode = LL_SPI_MODE_MASTER,
.TransferDirection = LL_SPI_FULL_DUPLEX,
.DataWidth = LL_SPI_DATAWIDTH_8BIT,
.ClockPolarity = LL_SPI_POLARITY_LOW,
.ClockPhase = LL_SPI_PHASE_2EDGE,
.NSS = LL_SPI_NSS_SOFT,
.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV8,
.BitOrder = LL_SPI_MSB_FIRST,
.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE,
.CRCPoly = 7,
};
const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_8m = {
.Mode = LL_SPI_MODE_MASTER,
.TransferDirection = LL_SPI_FULL_DUPLEX,
.DataWidth = LL_SPI_DATAWIDTH_8BIT,
.ClockPolarity = LL_SPI_POLARITY_LOW,
.ClockPhase = LL_SPI_PHASE_1EDGE,
.NSS = LL_SPI_NSS_SOFT,
.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV8,
.BitOrder = LL_SPI_MSB_FIRST,
.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE,
.CRCPoly = 7,
};
const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_4m = {
.Mode = LL_SPI_MODE_MASTER,
.TransferDirection = LL_SPI_FULL_DUPLEX,
.DataWidth = LL_SPI_DATAWIDTH_8BIT,
.ClockPolarity = LL_SPI_POLARITY_LOW,
.ClockPhase = LL_SPI_PHASE_1EDGE,
.NSS = LL_SPI_NSS_SOFT,
.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV16,
.BitOrder = LL_SPI_MSB_FIRST,
.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE,
.CRCPoly = 7,
};
const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_16m = {
.Mode = LL_SPI_MODE_MASTER,
.TransferDirection = LL_SPI_FULL_DUPLEX,
.DataWidth = LL_SPI_DATAWIDTH_8BIT,
.ClockPolarity = LL_SPI_POLARITY_LOW,
.ClockPhase = LL_SPI_PHASE_1EDGE,
.NSS = LL_SPI_NSS_SOFT,
.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV2,
.BitOrder = LL_SPI_MSB_FIRST,
.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE,
.CRCPoly = 7,
};
const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_2m = {
.Mode = LL_SPI_MODE_MASTER,
.TransferDirection = LL_SPI_FULL_DUPLEX,
.DataWidth = LL_SPI_DATAWIDTH_8BIT,
.ClockPolarity = LL_SPI_POLARITY_LOW,
.ClockPhase = LL_SPI_PHASE_1EDGE,
.NSS = LL_SPI_NSS_SOFT,
.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV32,
.BitOrder = LL_SPI_MSB_FIRST,
.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE,
.CRCPoly = 7,
};
/* SPI Buses */
FuriMutex* furi_hal_spi_bus_r_mutex = NULL;
void furi_hal_spi_config_init_early() {
furi_hal_spi_bus_init(&furi_hal_spi_bus_d);
furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_display);
}
void furi_hal_spi_config_deinit_early() {
furi_hal_spi_bus_handle_deinit(&furi_hal_spi_bus_handle_display);
furi_hal_spi_bus_deinit(&furi_hal_spi_bus_d);
}
void furi_hal_spi_config_init() {
furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_sd_fast);
furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_sd_slow);
FURI_LOG_I(TAG, "Init OK");
}
static void furi_hal_spi_bus_r_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) {
if(event == FuriHalSpiBusEventInit) {
furi_hal_spi_bus_r_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
FURI_CRITICAL_ENTER();
LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1);
FURI_CRITICAL_EXIT();
bus->current_handle = NULL;
} else if(event == FuriHalSpiBusEventDeinit) {
furi_mutex_free(furi_hal_spi_bus_r_mutex);
FURI_CRITICAL_ENTER();
LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1);
LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI1);
FURI_CRITICAL_EXIT();
} else if(event == FuriHalSpiBusEventLock) {
furi_check(furi_mutex_acquire(furi_hal_spi_bus_r_mutex, FuriWaitForever) == FuriStatusOk);
} else if(event == FuriHalSpiBusEventUnlock) {
furi_check(furi_mutex_release(furi_hal_spi_bus_r_mutex) == FuriStatusOk);
} else if(event == FuriHalSpiBusEventActivate) {
FURI_CRITICAL_ENTER();
LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI1);
FURI_CRITICAL_EXIT();
} else if(event == FuriHalSpiBusEventDeactivate) {
FURI_CRITICAL_ENTER();
LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1);
FURI_CRITICAL_EXIT();
}
}
FuriHalSpiBus furi_hal_spi_bus_r = {
.spi = SPI1,
.callback = furi_hal_spi_bus_r_event_callback,
};
FuriMutex* furi_hal_spi_bus_d_mutex = NULL;
static void furi_hal_spi_bus_d_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) {
if(event == FuriHalSpiBusEventInit) {
furi_hal_spi_bus_d_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
FURI_CRITICAL_ENTER();
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2);
FURI_CRITICAL_EXIT();
bus->current_handle = NULL;
} else if(event == FuriHalSpiBusEventDeinit) {
furi_mutex_free(furi_hal_spi_bus_d_mutex);
FURI_CRITICAL_ENTER();
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2);
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2);
FURI_CRITICAL_EXIT();
} else if(event == FuriHalSpiBusEventLock) {
furi_check(furi_mutex_acquire(furi_hal_spi_bus_d_mutex, FuriWaitForever) == FuriStatusOk);
} else if(event == FuriHalSpiBusEventUnlock) {
furi_check(furi_mutex_release(furi_hal_spi_bus_d_mutex) == FuriStatusOk);
} else if(event == FuriHalSpiBusEventActivate) {
FURI_CRITICAL_ENTER();
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2);
FURI_CRITICAL_EXIT();
} else if(event == FuriHalSpiBusEventDeactivate) {
FURI_CRITICAL_ENTER();
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2);
FURI_CRITICAL_EXIT();
}
}
FuriHalSpiBus furi_hal_spi_bus_d = {
.spi = SPI2,
.callback = furi_hal_spi_bus_d_event_callback,
};
/* SPI Bus Handles */
inline static void furi_hal_spi_bus_r_handle_event_callback(
FuriHalSpiBusHandle* handle,
FuriHalSpiBusHandleEvent event,
const LL_SPI_InitTypeDef* preset) {
if(event == FuriHalSpiBusHandleEventInit) {
furi_hal_gpio_write(handle->cs, true);
furi_hal_gpio_init(handle->cs, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh);
} else if(event == FuriHalSpiBusHandleEventDeinit) {
furi_hal_gpio_write(handle->cs, true);
furi_hal_gpio_init(handle->cs, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
} else if(event == FuriHalSpiBusHandleEventActivate) {
LL_SPI_Init(handle->bus->spi, (LL_SPI_InitTypeDef*)preset);
LL_SPI_SetRxFIFOThreshold(handle->bus->spi, LL_SPI_RX_FIFO_TH_QUARTER);
LL_SPI_Enable(handle->bus->spi);
furi_hal_gpio_init_ex(
handle->miso,
GpioModeAltFunctionPushPull,
GpioPullNo,
GpioSpeedVeryHigh,
GpioAltFn5SPI1);
furi_hal_gpio_init_ex(
handle->mosi,
GpioModeAltFunctionPushPull,
GpioPullNo,
GpioSpeedVeryHigh,
GpioAltFn5SPI1);
furi_hal_gpio_init_ex(
handle->sck,
GpioModeAltFunctionPushPull,
GpioPullNo,
GpioSpeedVeryHigh,
GpioAltFn5SPI1);
furi_hal_gpio_write(handle->cs, false);
} else if(event == FuriHalSpiBusHandleEventDeactivate) {
furi_hal_gpio_write(handle->cs, true);
furi_hal_gpio_init(handle->miso, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
furi_hal_gpio_init(handle->mosi, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
furi_hal_gpio_init(handle->sck, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
LL_SPI_Disable(handle->bus->spi);
}
}
inline static void furi_hal_spi_bus_nfc_handle_event_callback(
FuriHalSpiBusHandle* handle,
FuriHalSpiBusHandleEvent event,
const LL_SPI_InitTypeDef* preset) {
if(event == FuriHalSpiBusHandleEventInit) {
// Configure GPIOs in normal SPI mode
furi_hal_gpio_init_ex(
handle->miso,
GpioModeAltFunctionPushPull,
GpioPullNo,
GpioSpeedVeryHigh,
GpioAltFn5SPI1);
furi_hal_gpio_init_ex(
handle->mosi,
GpioModeAltFunctionPushPull,
GpioPullNo,
GpioSpeedVeryHigh,
GpioAltFn5SPI1);
furi_hal_gpio_init_ex(
handle->sck,
GpioModeAltFunctionPushPull,
GpioPullNo,
GpioSpeedVeryHigh,
GpioAltFn5SPI1);
furi_hal_gpio_write(handle->cs, true);
furi_hal_gpio_init(handle->cs, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh);
} else if(event == FuriHalSpiBusHandleEventDeinit) {
// Configure GPIOs for st25r3916 Transparent mode
furi_hal_gpio_init(handle->sck, GpioModeInput, GpioPullUp, GpioSpeedLow);
furi_hal_gpio_init(handle->miso, GpioModeInput, GpioPullUp, GpioSpeedLow);
furi_hal_gpio_init(handle->cs, GpioModeInput, GpioPullUp, GpioSpeedLow);
furi_hal_gpio_write(handle->mosi, false);
furi_hal_gpio_init(handle->mosi, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh);
} else if(event == FuriHalSpiBusHandleEventActivate) {
LL_SPI_Init(handle->bus->spi, (LL_SPI_InitTypeDef*)preset);
LL_SPI_SetRxFIFOThreshold(handle->bus->spi, LL_SPI_RX_FIFO_TH_QUARTER);
LL_SPI_Enable(handle->bus->spi);
furi_hal_gpio_init_ex(
handle->miso,
GpioModeAltFunctionPushPull,
GpioPullNo,
GpioSpeedVeryHigh,
GpioAltFn5SPI1);
furi_hal_gpio_init_ex(
handle->mosi,
GpioModeAltFunctionPushPull,
GpioPullNo,
GpioSpeedVeryHigh,
GpioAltFn5SPI1);
furi_hal_gpio_init_ex(
handle->sck,
GpioModeAltFunctionPushPull,
GpioPullNo,
GpioSpeedVeryHigh,
GpioAltFn5SPI1);
} else if(event == FuriHalSpiBusHandleEventDeactivate) {
furi_hal_gpio_init(handle->miso, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
furi_hal_gpio_init(handle->mosi, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
furi_hal_gpio_init(handle->sck, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
LL_SPI_Disable(handle->bus->spi);
}
}
static void furi_hal_spi_bus_handle_external_event_callback(
FuriHalSpiBusHandle* handle,
FuriHalSpiBusHandleEvent event) {
furi_hal_spi_bus_r_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_2m);
}
FuriHalSpiBusHandle furi_hal_spi_bus_handle_external = {
.bus = &furi_hal_spi_bus_r,
.callback = furi_hal_spi_bus_handle_external_event_callback,
.miso = &gpio_ext_pa6,
.mosi = &gpio_ext_pa7,
.sck = &gpio_ext_pb3,
.cs = &gpio_ext_pa4,
};
inline static void furi_hal_spi_bus_d_handle_event_callback(
FuriHalSpiBusHandle* handle,
FuriHalSpiBusHandleEvent event,
const LL_SPI_InitTypeDef* preset) {
if(event == FuriHalSpiBusHandleEventInit) {
furi_hal_gpio_write(handle->cs, true);
furi_hal_gpio_init(handle->cs, GpioModeOutputPushPull, GpioPullUp, GpioSpeedVeryHigh);
furi_hal_gpio_init_ex(
handle->miso,
GpioModeAltFunctionPushPull,
GpioPullNo,
GpioSpeedVeryHigh,
GpioAltFn5SPI2);
furi_hal_gpio_init_ex(
handle->mosi,
GpioModeAltFunctionPushPull,
GpioPullNo,
GpioSpeedVeryHigh,
GpioAltFn5SPI2);
furi_hal_gpio_init_ex(
handle->sck,
GpioModeAltFunctionPushPull,
GpioPullNo,
GpioSpeedVeryHigh,
GpioAltFn5SPI2);
} else if(event == FuriHalSpiBusHandleEventDeinit) {
furi_hal_gpio_write(handle->cs, true);
furi_hal_gpio_init(handle->cs, GpioModeAnalog, GpioPullUp, GpioSpeedLow);
} else if(event == FuriHalSpiBusHandleEventActivate) {
LL_SPI_Init(handle->bus->spi, (LL_SPI_InitTypeDef*)preset);
LL_SPI_SetRxFIFOThreshold(handle->bus->spi, LL_SPI_RX_FIFO_TH_QUARTER);
LL_SPI_Enable(handle->bus->spi);
furi_hal_gpio_write(handle->cs, false);
} else if(event == FuriHalSpiBusHandleEventDeactivate) {
furi_hal_gpio_write(handle->cs, true);
LL_SPI_Disable(handle->bus->spi);
}
}
static void furi_hal_spi_bus_handle_display_event_callback(
FuriHalSpiBusHandle* handle,
FuriHalSpiBusHandleEvent event) {
furi_hal_spi_bus_d_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_4m);
}
FuriHalSpiBusHandle furi_hal_spi_bus_handle_display = {
.bus = &furi_hal_spi_bus_d,
.callback = furi_hal_spi_bus_handle_display_event_callback,
.miso = &gpio_spi_d_miso,
.mosi = &gpio_spi_d_mosi,
.sck = &gpio_spi_d_sck,
.cs = &gpio_display_cs,
};
static void furi_hal_spi_bus_handle_sd_fast_event_callback(
FuriHalSpiBusHandle* handle,
FuriHalSpiBusHandleEvent event) {
furi_hal_spi_bus_d_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_16m);
}
FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_fast = {
.bus = &furi_hal_spi_bus_d,
.callback = furi_hal_spi_bus_handle_sd_fast_event_callback,
.miso = &gpio_spi_d_miso,
.mosi = &gpio_spi_d_mosi,
.sck = &gpio_spi_d_sck,
.cs = &gpio_sdcard_cs,
};
static void furi_hal_spi_bus_handle_sd_slow_event_callback(
FuriHalSpiBusHandle* handle,
FuriHalSpiBusHandleEvent event) {
furi_hal_spi_bus_d_handle_event_callback(handle, event, &furi_hal_spi_preset_1edge_low_2m);
}
FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_slow = {
.bus = &furi_hal_spi_bus_d,
.callback = furi_hal_spi_bus_handle_sd_slow_event_callback,
.miso = &gpio_spi_d_miso,
.mosi = &gpio_spi_d_mosi,
.sck = &gpio_spi_d_sck,
.cs = &gpio_sdcard_cs,
};
@@ -0,0 +1,55 @@
#pragma once
#include <furi_hal_spi_types.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Preset for ST25R916 */
extern const LL_SPI_InitTypeDef furi_hal_spi_preset_2edge_low_8m;
/** Preset for CC1101 */
extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_8m;
/** Preset for ST7567 (Display) */
extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_4m;
/** Preset for SdCard in fast mode */
extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_16m;
/** Preset for SdCard in slow mode */
extern const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_2m;
/** Furi Hal Spi Bus R (External) */
extern FuriHalSpiBus furi_hal_spi_bus_r;
/** Furi Hal Spi Bus D (Display, SdCard) */
extern FuriHalSpiBus furi_hal_spi_bus_d;
/** External on `furi_hal_spi_bus_r`
* Preset: `furi_hal_spi_preset_1edge_low_2m`
*
* miso: pa6
* mosi: pa7
* sck: pb3
* cs: pa4 (software controlled)
*
* @warning not initialized by default, call `furi_hal_spi_bus_handle_init` to initialize
* Bus pins are floating on inactive state, CS high after initialization
*
*/
extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_external;
/** ST7567(Display) on `furi_hal_spi_bus_d` */
extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_display;
/** SdCard in fast mode on `furi_hal_spi_bus_d` */
extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_fast;
/** SdCard in slow mode on `furi_hal_spi_bus_d` */
extern FuriHalSpiBusHandle furi_hal_spi_bus_handle_sd_slow;
#ifdef __cplusplus
}
#endif
@@ -0,0 +1 @@
#pragma once
@@ -0,0 +1,21 @@
#include <furi_hal_version.h>
bool furi_hal_version_do_i_belong_here() {
return (furi_hal_version_get_hw_target() == 18) || (furi_hal_version_get_hw_target() == 0);
}
const char* furi_hal_version_get_model_name() {
return "Komi";
}
const char* furi_hal_version_get_model_code() {
return "N/A";
}
const char* furi_hal_version_get_fcc_id() {
return "N/A";
}
const char* furi_hal_version_get_ic_id() {
return "N/A";
}
+56
View File
@@ -0,0 +1,56 @@
{
"inherit": "7",
"include_paths": [
"furi_hal"
],
"sdk_header_paths": [
"../furi_hal_include",
"furi_hal",
"platform_specific"
],
"sdk_symbols": "api_symbols.csv",
"linker_dependencies": [
"print",
"flipper18",
"furi",
"freertos",
"stm32cubewb",
"hwdrivers",
"fatfs",
"littlefs",
"flipperformat",
"toolbox",
"microtar",
"usb_stm32",
"appframe",
"assets",
"one_wire",
"misc",
"flipper_application",
"flipperformat",
"toolbox",
"flipper18"
],
"excluded_sources": [
"furi_hal_infrared.c",
"furi_hal_nfc.c",
"furi_hal_rfid.c",
"furi_hal_subghz.c"
],
"excluded_headers": [
"furi_hal_infrared.h",
"furi_hal_nfc.h",
"furi_hal_rfid.h",
"furi_hal_subghz.h",
"furi_hal_ibutton.h",
"furi_hal_subghz_configs.h"
],
"excluded_modules": [
"nfc",
"lfrfid",
"subghz",
"ibutton",
"infrared",
"st25rfal002"
]
}
+157 -99
View File
@@ -1,5 +1,5 @@
entry,status,name,type,params
Version,+,11.10,,
Version,+,20.0,,
Header,+,applications/services/bt/bt_service/bt.h,,
Header,+,applications/services/cli/cli.h,,
Header,+,applications/services/cli/cli_vcp.h,,
@@ -28,6 +28,7 @@ Header,+,applications/services/gui/modules/widget_elements/widget_element.h,,
Header,+,applications/services/gui/view_dispatcher.h,,
Header,+,applications/services/gui/view_stack.h,,
Header,+,applications/services/input/input.h,,
Header,+,applications/services/loader/firmware_api/firmware_api.h,,
Header,+,applications/services/loader/loader.h,,
Header,+,applications/services/locale/locale.h,,
Header,+,applications/services/notification/notification.h,,
@@ -41,14 +42,19 @@ Header,+,firmware/targets/f7/furi_hal/furi_hal_flash.h,,
Header,+,firmware/targets/f7/furi_hal/furi_hal_gpio.h,,
Header,+,firmware/targets/f7/furi_hal/furi_hal_i2c_config.h,,
Header,+,firmware/targets/f7/furi_hal/furi_hal_i2c_types.h,,
Header,+,firmware/targets/f7/furi_hal/furi_hal_ibutton.h,,
Header,+,firmware/targets/f7/furi_hal/furi_hal_idle_timer.h,,
Header,+,firmware/targets/f7/furi_hal/furi_hal_interrupt.h,,
Header,+,firmware/targets/f7/furi_hal/furi_hal_nfc.h,,
Header,+,firmware/targets/f7/furi_hal/furi_hal_os.h,,
Header,+,firmware/targets/f7/furi_hal/furi_hal_pwm.h,,
Header,+,firmware/targets/f7/furi_hal/furi_hal_resources.h,,
Header,+,firmware/targets/f7/furi_hal/furi_hal_rfid.h,,
Header,+,firmware/targets/f7/furi_hal/furi_hal_spi_config.h,,
Header,+,firmware/targets/f7/furi_hal/furi_hal_spi_types.h,,
Header,+,firmware/targets/f7/furi_hal/furi_hal_subghz.h,,
Header,+,firmware/targets/f7/furi_hal/furi_hal_subghz_configs.h,,
Header,+,firmware/targets/f7/furi_hal/furi_hal_target_hw.h,,
Header,+,firmware/targets/f7/furi_hal/furi_hal_uart.h,,
Header,+,firmware/targets/f7/furi_hal/furi_hal_usb_cdc.h,,
Header,+,firmware/targets/f7/platform_specific/intrinsic_export.h,,
@@ -56,27 +62,22 @@ Header,+,firmware/targets/furi_hal_include/furi_hal.h,,
Header,+,firmware/targets/furi_hal_include/furi_hal_bt.h,,
Header,+,firmware/targets/furi_hal_include/furi_hal_bt_hid.h,,
Header,+,firmware/targets/furi_hal_include/furi_hal_bt_serial.h,,
Header,+,firmware/targets/furi_hal_include/furi_hal_compress.h,,
Header,+,firmware/targets/furi_hal_include/furi_hal_cortex.h,,
Header,+,firmware/targets/furi_hal_include/furi_hal_crypto.h,,
Header,+,firmware/targets/furi_hal_include/furi_hal_debug.h,,
Header,+,firmware/targets/furi_hal_include/furi_hal_i2c.h,,
Header,+,firmware/targets/furi_hal_include/furi_hal_ibutton.h,,
Header,+,firmware/targets/furi_hal_include/furi_hal_info.h,,
Header,+,firmware/targets/furi_hal_include/furi_hal_infrared.h,,
Header,+,firmware/targets/furi_hal_include/furi_hal_light.h,,
Header,+,firmware/targets/furi_hal_include/furi_hal_memory.h,,
Header,+,firmware/targets/furi_hal_include/furi_hal_mpu.h,,
Header,+,firmware/targets/furi_hal_include/furi_hal_nfc.h,,
Header,+,firmware/targets/furi_hal_include/furi_hal_power.h,,
Header,+,firmware/targets/furi_hal_include/furi_hal_random.h,,
Header,+,firmware/targets/furi_hal_include/furi_hal_region.h,,
Header,+,firmware/targets/furi_hal_include/furi_hal_rfid.h,,
Header,+,firmware/targets/furi_hal_include/furi_hal_rtc.h,,
Header,+,firmware/targets/furi_hal_include/furi_hal_sd.h,,
Header,+,firmware/targets/furi_hal_include/furi_hal_speaker.h,,
Header,+,firmware/targets/furi_hal_include/furi_hal_spi.h,,
Header,+,firmware/targets/furi_hal_include/furi_hal_subghz.h,,
Header,+,firmware/targets/furi_hal_include/furi_hal_usb.h,,
Header,+,firmware/targets/furi_hal_include/furi_hal_usb_hid.h,,
Header,+,firmware/targets/furi_hal_include/furi_hal_usb_hid_u2f.h,,
@@ -109,9 +110,16 @@ Header,+,lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Inc/stm32wbxx_ll_tim.h,,
Header,+,lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Inc/stm32wbxx_ll_usart.h,,
Header,+,lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Inc/stm32wbxx_ll_utils.h,,
Header,+,lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Inc/stm32wbxx_ll_wwdg.h,,
Header,+,lib/flipper_application/api_hashtable/api_hashtable.h,,
Header,+,lib/flipper_application/api_hashtable/compilesort.hpp,,
Header,+,lib/flipper_application/flipper_application.h,,
Header,+,lib/flipper_application/plugins/composite_resolver.h,,
Header,+,lib/flipper_application/plugins/plugin_manager.h,,
Header,+,lib/flipper_format/flipper_format.h,,
Header,+,lib/flipper_format/flipper_format_i.h,,
Header,+,lib/ibutton/ibutton_key.h,,
Header,+,lib/ibutton/ibutton_protocols.h,,
Header,+,lib/ibutton/ibutton_worker.h,,
Header,+,lib/infrared/encoder_decoder/infrared.h,,
Header,+,lib/infrared/worker/infrared_transmit.h,,
Header,+,lib/infrared/worker/infrared_worker.h,,
@@ -150,12 +158,19 @@ Header,+,lib/libusb_stm32/inc/usbd_core.h,,
Header,+,lib/mbedtls/include/mbedtls/des.h,,
Header,+,lib/mbedtls/include/mbedtls/sha1.h,,
Header,+,lib/micro-ecc/uECC.h,,
Header,+,lib/mlib/m-algo.h,,
Header,+,lib/mlib/m-array.h,,
Header,+,lib/mlib/m-bptree.h,,
Header,+,lib/mlib/m-core.h,,
Header,+,lib/mlib/m-deque.h,,
Header,+,lib/mlib/m-dict.h,,
Header,+,lib/mlib/m-list.h,,
Header,+,lib/mlib/m-rbtree.h,,
Header,+,lib/mlib/m-tuple.h,,
Header,+,lib/mlib/m-variant.h,,
Header,+,lib/nfc/nfc_device.h,,
Header,+,lib/one_wire/ibutton/ibutton_worker.h,,
Header,+,lib/one_wire/maxim_crc.h,,
Header,+,lib/one_wire/one_wire_device.h,,
Header,+,lib/one_wire/one_wire_host.h,,
Header,+,lib/one_wire/one_wire_host_timing.h,,
Header,+,lib/one_wire/one_wire_slave.h,,
Header,+,lib/print/wrappers.h,,
Header,+,lib/subghz/blocks/const.h,,
@@ -175,14 +190,15 @@ Header,+,lib/toolbox/args.h,,
Header,+,lib/toolbox/crc32_calc.h,,
Header,+,lib/toolbox/dir_walk.h,,
Header,+,lib/toolbox/float_tools.h,,
Header,+,lib/toolbox/hmac_sha256.h,,
Header,+,lib/toolbox/manchester_decoder.h,,
Header,+,lib/toolbox/manchester_encoder.h,,
Header,+,lib/toolbox/md5.h,,
Header,+,lib/toolbox/path.h,,
Header,+,lib/toolbox/pretty_format.h,,
Header,+,lib/toolbox/protocols/protocol_dict.h,,
Header,+,lib/toolbox/random_name.h,,
Header,+,lib/toolbox/saved_struct.h,,
Header,+,lib/toolbox/sha256.h,,
Header,+,lib/toolbox/stream/buffered_file_stream.h,,
Header,+,lib/toolbox/stream/file_stream.h,,
Header,+,lib/toolbox/stream/stream.h,,
@@ -478,7 +494,6 @@ Function,-,acosh,double,double
Function,-,acoshf,float,float
Function,-,acoshl,long double,long double
Function,-,acosl,long double,long double
Function,+,acquire_mutex,void*,"ValueMutex*, uint32_t"
Function,-,aligned_alloc,void*,"size_t, size_t"
Function,+,aligned_free,void,void*
Function,+,aligned_malloc,void*,"size_t, size_t"
@@ -596,7 +611,7 @@ Function,-,bzero,void,"void*, size_t"
Function,-,calloc,void*,"size_t, size_t"
Function,+,canvas_clear,void,Canvas*
Function,+,canvas_commit,void,Canvas*
Function,+,canvas_current_font_height,uint8_t,Canvas*
Function,+,canvas_current_font_height,uint8_t,const Canvas*
Function,+,canvas_draw_bitmap,void,"Canvas*, uint8_t, uint8_t, uint8_t, uint8_t, const uint8_t*"
Function,+,canvas_draw_box,void,"Canvas*, uint8_t, uint8_t, uint8_t, uint8_t"
Function,+,canvas_draw_circle,void,"Canvas*, uint8_t, uint8_t, uint8_t"
@@ -613,17 +628,18 @@ Function,+,canvas_draw_str,void,"Canvas*, uint8_t, uint8_t, const char*"
Function,+,canvas_draw_str_aligned,void,"Canvas*, uint8_t, uint8_t, Align, Align, const char*"
Function,+,canvas_draw_triangle,void,"Canvas*, uint8_t, uint8_t, uint8_t, uint8_t, CanvasDirection"
Function,+,canvas_draw_xbm,void,"Canvas*, uint8_t, uint8_t, uint8_t, uint8_t, const uint8_t*"
Function,+,canvas_get_font_params,CanvasFontParameters*,"Canvas*, Font"
Function,+,canvas_get_font_params,const CanvasFontParameters*,"const Canvas*, Font"
Function,+,canvas_glyph_width,uint8_t,"Canvas*, char"
Function,+,canvas_height,uint8_t,Canvas*
Function,+,canvas_height,uint8_t,const Canvas*
Function,+,canvas_invert_color,void,Canvas*
Function,+,canvas_reset,void,Canvas*
Function,+,canvas_set_bitmap_mode,void,"Canvas*, _Bool"
Function,+,canvas_set_color,void,"Canvas*, Color"
Function,+,canvas_set_custom_u8g2_font,void,"Canvas*, const uint8_t*"
Function,+,canvas_set_font,void,"Canvas*, Font"
Function,+,canvas_set_font_direction,void,"Canvas*, CanvasDirection"
Function,+,canvas_string_width,uint16_t,"Canvas*, const char*"
Function,+,canvas_width,uint8_t,Canvas*
Function,+,canvas_width,uint8_t,const Canvas*
Function,-,cbrt,double,double
Function,-,cbrtf,float,float
Function,-,cbrtl,long double,long double
@@ -666,6 +682,10 @@ Function,+,cli_session_close,void,Cli*
Function,+,cli_session_open,void,"Cli*, void*"
Function,+,cli_write,void,"Cli*, const uint8_t*, size_t"
Function,-,clock,clock_t,
Function,+,composite_api_resolver_add,void,"CompositeApiResolver*, const ElfApiInterface*"
Function,+,composite_api_resolver_alloc,CompositeApiResolver*,
Function,+,composite_api_resolver_free,void,CompositeApiResolver*
Function,+,composite_api_resolver_get,const ElfApiInterface*,CompositeApiResolver*
Function,-,copysign,double,"double, double"
Function,-,copysignf,float,"float, float"
Function,-,copysignl,long double,"long double, long double"
@@ -689,7 +709,6 @@ Function,-,ctermid,char*,char*
Function,-,ctime,char*,const time_t*
Function,-,ctime_r,char*,"const time_t*, char*"
Function,-,cuserid,char*,char*
Function,+,delete_mutex,_Bool,ValueMutex*
Function,+,dialog_ex_alloc,DialogEx*,
Function,+,dialog_ex_disable_extended_events,void,DialogEx*
Function,+,dialog_ex_enable_extended_events,void,DialogEx*
@@ -766,6 +785,7 @@ Function,+,elements_slightly_rounded_box,void,"Canvas*, uint8_t, uint8_t, uint8_
Function,+,elements_slightly_rounded_frame,void,"Canvas*, uint8_t, uint8_t, uint8_t, uint8_t"
Function,+,elements_string_fit_width,void,"Canvas*, FuriString*, uint8_t"
Function,+,elements_text_box,void,"Canvas*, uint8_t, uint8_t, uint8_t, uint8_t, Align, Align, const char*, _Bool"
Function,+,elf_resolve_from_hashtable,_Bool,"const ElfApiInterface*, const char*, Elf32_Addr*"
Function,+,empty_screen_alloc,EmptyScreen*,
Function,+,empty_screen_free,void,EmptyScreen*
Function,+,empty_screen_get_view,View*,EmptyScreen*
@@ -850,6 +870,7 @@ Function,+,file_browser_worker_set_folder_callback,void,"BrowserWorker*, Browser
Function,+,file_browser_worker_set_item_callback,void,"BrowserWorker*, BrowserWorkerListItemCallback"
Function,+,file_browser_worker_set_list_callback,void,"BrowserWorker*, BrowserWorkerListLoadCallback"
Function,+,file_browser_worker_set_long_load_callback,void,"BrowserWorker*, BrowserWorkerLongLoadCallback"
Function,+,file_info_is_dir,_Bool,const FileInfo*
Function,+,file_stream_alloc,Stream*,Storage*
Function,+,file_stream_close,_Bool,Stream*
Function,+,file_stream_get_error,FS_Error,Stream*
@@ -865,16 +886,20 @@ Function,-,fiscanf,int,"FILE*, const char*, ..."
Function,+,flipper_application_alloc,FlipperApplication*,"Storage*, const ElfApiInterface*"
Function,+,flipper_application_free,void,FlipperApplication*
Function,+,flipper_application_get_manifest,const FlipperApplicationManifest*,FlipperApplication*
Function,+,flipper_application_is_plugin,_Bool,FlipperApplication*
Function,+,flipper_application_load_status_to_string,const char*,FlipperApplicationLoadStatus
Function,+,flipper_application_manifest_is_compatible,_Bool,"const FlipperApplicationManifest*, const ElfApiInterface*"
Function,+,flipper_application_manifest_is_target_compatible,_Bool,const FlipperApplicationManifest*
Function,+,flipper_application_manifest_is_valid,_Bool,const FlipperApplicationManifest*
Function,+,flipper_application_map_to_memory,FlipperApplicationLoadStatus,FlipperApplication*
Function,+,flipper_application_plugin_get_descriptor,const FlipperAppPluginDescriptor*,FlipperApplication*
Function,+,flipper_application_preload,FlipperApplicationPreloadStatus,"FlipperApplication*, const char*"
Function,+,flipper_application_preload_manifest,FlipperApplicationPreloadStatus,"FlipperApplication*, const char*"
Function,-,flipper_application_preload_status_to_string,const char*,FlipperApplicationPreloadStatus
Function,+,flipper_application_preload_status_to_string,const char*,FlipperApplicationPreloadStatus
Function,+,flipper_application_spawn,FuriThread*,"FlipperApplication*, void*"
Function,+,flipper_format_buffered_file_alloc,FlipperFormat*,Storage*
Function,+,flipper_format_buffered_file_close,_Bool,FlipperFormat*
Function,+,flipper_format_buffered_file_open_always,_Bool,"FlipperFormat*, const char*"
Function,+,flipper_format_buffered_file_open_existing,_Bool,"FlipperFormat*, const char*"
Function,+,flipper_format_delete_key,_Bool,"FlipperFormat*, const char*"
Function,+,flipper_format_file_alloc,FlipperFormat*,Storage*
@@ -1037,7 +1062,7 @@ Function,+,furi_hal_cdc_get_port_settings,usb_cdc_line_coding*,uint8_t
Function,+,furi_hal_cdc_receive,int32_t,"uint8_t, uint8_t*, uint16_t"
Function,+,furi_hal_cdc_send,void,"uint8_t, uint8_t*, uint16_t"
Function,+,furi_hal_cdc_set_callbacks,void,"uint8_t, CdcCallbacks*, void*"
Function,+,furi_hal_clock_deinit_early,void,
Function,-,furi_hal_clock_deinit_early,void,
Function,-,furi_hal_clock_init,void,
Function,-,furi_hal_clock_init_early,void,
Function,+,furi_hal_clock_mco_disable,void,
@@ -1046,12 +1071,6 @@ Function,-,furi_hal_clock_resume_tick,void,
Function,-,furi_hal_clock_suspend_tick,void,
Function,-,furi_hal_clock_switch_to_hsi,void,
Function,-,furi_hal_clock_switch_to_pll,void,
Function,-,furi_hal_compress_alloc,FuriHalCompress*,uint16_t
Function,-,furi_hal_compress_decode,_Bool,"FuriHalCompress*, uint8_t*, size_t, uint8_t*, size_t, size_t*"
Function,-,furi_hal_compress_encode,_Bool,"FuriHalCompress*, uint8_t*, size_t, uint8_t*, size_t, size_t*"
Function,-,furi_hal_compress_free,void,FuriHalCompress*
Function,-,furi_hal_compress_icon_decode,void,"const uint8_t*, uint8_t**"
Function,-,furi_hal_compress_icon_init,void,
Function,+,furi_hal_console_disable,void,
Function,+,furi_hal_console_enable,void,
Function,+,furi_hal_console_init,void,
@@ -1118,7 +1137,7 @@ Function,+,furi_hal_hid_u2f_is_connected,_Bool,
Function,+,furi_hal_hid_u2f_send_response,void,"uint8_t*, uint8_t"
Function,+,furi_hal_hid_u2f_set_callback,void,"HidU2fCallback, void*"
Function,+,furi_hal_i2c_acquire,void,FuriHalI2cBusHandle*
Function,+,furi_hal_i2c_deinit_early,void,
Function,-,furi_hal_i2c_deinit_early,void,
Function,-,furi_hal_i2c_init,void,
Function,-,furi_hal_i2c_init_early,void,
Function,+,furi_hal_i2c_is_device_ready,_Bool,"FuriHalI2cBusHandle*, uint8_t, uint32_t"
@@ -1132,20 +1151,13 @@ Function,+,furi_hal_i2c_tx,_Bool,"FuriHalI2cBusHandle*, const uint8_t, const uin
Function,+,furi_hal_i2c_write_mem,_Bool,"FuriHalI2cBusHandle*, uint8_t, uint8_t, uint8_t*, uint8_t, uint32_t"
Function,+,furi_hal_i2c_write_reg_16,_Bool,"FuriHalI2cBusHandle*, uint8_t, uint8_t, uint16_t, uint32_t"
Function,+,furi_hal_i2c_write_reg_8,_Bool,"FuriHalI2cBusHandle*, uint8_t, uint8_t, uint8_t, uint32_t"
Function,+,furi_hal_ibutton_add_interrupt,void,"GpioExtiCallback, void*"
Function,+,furi_hal_ibutton_emulate_set_next,void,uint32_t
Function,+,furi_hal_ibutton_emulate_start,void,"uint32_t, FuriHalIbuttonEmulateCallback, void*"
Function,+,furi_hal_ibutton_emulate_stop,void,
Function,-,furi_hal_ibutton_init,void,
Function,+,furi_hal_ibutton_pin_get_level,_Bool,
Function,+,furi_hal_ibutton_pin_high,void,
Function,+,furi_hal_ibutton_pin_low,void,
Function,+,furi_hal_ibutton_remove_interrupt,void,
Function,+,furi_hal_ibutton_start_drive,void,
Function,+,furi_hal_ibutton_start_drive_in_isr,void,
Function,+,furi_hal_ibutton_start_interrupt,void,
Function,+,furi_hal_ibutton_start_interrupt_in_isr,void,
Function,+,furi_hal_ibutton_stop,void,
Function,+,furi_hal_ibutton_pin_configure,void,
Function,+,furi_hal_ibutton_pin_reset,void,
Function,+,furi_hal_ibutton_pin_write,void,const _Bool
Function,+,furi_hal_info_get,void,"PropertyValueCallback, char, void*"
Function,+,furi_hal_infrared_async_rx_set_capture_isr_callback,void,"FuriHalInfraredRxCaptureCallback, void*"
Function,+,furi_hal_infrared_async_rx_set_timeout,void,uint32_t
@@ -1180,6 +1192,7 @@ Function,+,furi_hal_mpu_protect_disable,void,FuriHalMpuRegion
Function,+,furi_hal_mpu_protect_no_access,void,"FuriHalMpuRegion, uint32_t, FuriHalMPURegionSize"
Function,+,furi_hal_mpu_protect_read_only,void,"FuriHalMpuRegion, uint32_t, FuriHalMPURegionSize"
Function,+,furi_hal_nfc_activate_nfca,_Bool,"uint32_t, uint32_t*"
Function,-,furi_hal_nfc_deinit,void,
Function,+,furi_hal_nfc_detect,_Bool,"FuriHalNfcDevData*, uint32_t"
Function,+,furi_hal_nfc_emulate_nfca,_Bool,"uint8_t*, uint8_t, uint8_t*, uint8_t, FuriHalNfcEmulateCallback, void*, uint32_t"
Function,+,furi_hal_nfc_exit_sleep,void,
@@ -1219,7 +1232,7 @@ Function,+,furi_hal_power_enable_external_3_3v,void,
Function,+,furi_hal_power_enable_otg,void,
Function,+,furi_hal_power_gauge_is_ok,_Bool,
Function,+,furi_hal_power_get_bat_health_pct,uint8_t,
Function,+,furi_hal_power_get_battery_charging_voltage,float,
Function,+,furi_hal_power_get_battery_charge_voltage_limit,float,
Function,+,furi_hal_power_get_battery_current,float,FuriHalPowerIC
Function,+,furi_hal_power_get_battery_design_capacity,uint32_t,
Function,+,furi_hal_power_get_battery_full_capacity,uint32_t,
@@ -1238,7 +1251,7 @@ Function,+,furi_hal_power_is_charging_done,_Bool,
Function,+,furi_hal_power_is_otg_enabled,_Bool,
Function,+,furi_hal_power_off,void,
Function,+,furi_hal_power_reset,void,
Function,+,furi_hal_power_set_battery_charging_voltage,void,float
Function,+,furi_hal_power_set_battery_charge_voltage_limit,void,float
Function,+,furi_hal_power_shutdown,void,
Function,+,furi_hal_power_sleep,void,
Function,+,furi_hal_power_sleep_available,_Bool,
@@ -1256,7 +1269,8 @@ Function,-,furi_hal_region_init,void,
Function,+,furi_hal_region_is_frequency_allowed,_Bool,uint32_t
Function,+,furi_hal_region_is_provisioned,_Bool,
Function,+,furi_hal_region_set,void,FuriHalRegion*
Function,+,furi_hal_resources_deinit_early,void,
Function,-,furi_hal_resources_deinit_early,void,
Function,+,furi_hal_resources_get_ext_pin_number,int32_t,const GpioPin*
Function,-,furi_hal_resources_init,void,
Function,-,furi_hal_resources_init_early,void,
Function,+,furi_hal_rfid_change_read_config,void,"float, float"
@@ -1285,7 +1299,7 @@ Function,+,furi_hal_rfid_tim_read_start,void,
Function,+,furi_hal_rfid_tim_read_stop,void,
Function,+,furi_hal_rfid_tim_reset,void,
Function,+,furi_hal_rtc_datetime_to_timestamp,uint32_t,FuriHalRtcDateTime*
Function,+,furi_hal_rtc_deinit_early,void,
Function,-,furi_hal_rtc_deinit_early,void,
Function,+,furi_hal_rtc_get_boot_mode,FuriHalRtcBootMode,
Function,+,furi_hal_rtc_get_datetime,void,FuriHalRtcDateTime*
Function,+,furi_hal_rtc_get_fault_data,uint32_t,
@@ -1327,11 +1341,13 @@ Function,+,furi_hal_spi_bus_handle_deinit,void,FuriHalSpiBusHandle*
Function,+,furi_hal_spi_bus_handle_init,void,FuriHalSpiBusHandle*
Function,+,furi_hal_spi_bus_init,void,FuriHalSpiBus*
Function,+,furi_hal_spi_bus_rx,_Bool,"FuriHalSpiBusHandle*, uint8_t*, size_t, uint32_t"
Function,+,furi_hal_spi_bus_trx,_Bool,"FuriHalSpiBusHandle*, uint8_t*, uint8_t*, size_t, uint32_t"
Function,+,furi_hal_spi_bus_tx,_Bool,"FuriHalSpiBusHandle*, uint8_t*, size_t, uint32_t"
Function,+,furi_hal_spi_deinit_early,void,
Function,-,furi_hal_spi_init,void,
Function,+,furi_hal_spi_init_early,void,
Function,+,furi_hal_spi_bus_trx,_Bool,"FuriHalSpiBusHandle*, const uint8_t*, uint8_t*, size_t, uint32_t"
Function,+,furi_hal_spi_bus_trx_dma,_Bool,"FuriHalSpiBusHandle*, uint8_t*, uint8_t*, size_t, uint32_t"
Function,+,furi_hal_spi_bus_tx,_Bool,"FuriHalSpiBusHandle*, const uint8_t*, size_t, uint32_t"
Function,-,furi_hal_spi_config_deinit_early,void,
Function,-,furi_hal_spi_config_init,void,
Function,-,furi_hal_spi_config_init_early,void,
Function,-,furi_hal_spi_dma_init,void,
Function,+,furi_hal_spi_release,void,FuriHalSpiBusHandle*
Function,-,furi_hal_subghz_dump_state,void,
Function,+,furi_hal_subghz_flush_rx,void,
@@ -1385,6 +1401,7 @@ Function,+,furi_hal_version_do_i_belong_here,_Bool,
Function,+,furi_hal_version_get_ble_local_device_name_ptr,const char*,
Function,+,furi_hal_version_get_ble_mac,const uint8_t*,
Function,+,furi_hal_version_get_device_name_ptr,const char*,
Function,+,furi_hal_version_get_fcc_id,const char*,
Function,+,furi_hal_version_get_firmware_version,const Version*,
Function,+,furi_hal_version_get_hw_body,uint8_t,
Function,+,furi_hal_version_get_hw_color,FuriHalVersionColor,
@@ -1395,6 +1412,8 @@ Function,+,furi_hal_version_get_hw_region_name,const char*,
Function,+,furi_hal_version_get_hw_target,uint8_t,
Function,+,furi_hal_version_get_hw_timestamp,uint32_t,
Function,+,furi_hal_version_get_hw_version,uint8_t,
Function,+,furi_hal_version_get_ic_id,const char*,
Function,+,furi_hal_version_get_model_code,const char*,
Function,+,furi_hal_version_get_model_name,const char*,
Function,+,furi_hal_version_get_name_ptr,const char*,
Function,+,furi_hal_version_get_otp_version,FuriHalVersionOtpVersion,
@@ -1412,6 +1431,7 @@ Function,+,furi_kernel_unlock,int32_t,
Function,+,furi_log_get_level,FuriLogLevel,
Function,-,furi_log_init,void,
Function,+,furi_log_print_format,void,"FuriLogLevel, const char*, const char*, ..."
Function,+,furi_log_print_raw_format,void,"FuriLogLevel, const char*, ..."
Function,+,furi_log_set_level,void,FuriLogLevel
Function,-,furi_log_set_puts,void,FuriLogPuts
Function,-,furi_log_set_timestamp,void,FuriLogTimestamp
@@ -1522,8 +1542,10 @@ Function,+,furi_thread_flags_get,uint32_t,
Function,+,furi_thread_flags_set,uint32_t,"FuriThreadId, uint32_t"
Function,+,furi_thread_flags_wait,uint32_t,"uint32_t, uint32_t, uint32_t"
Function,+,furi_thread_free,void,FuriThread*
Function,+,furi_thread_get_appid,const char*,FuriThreadId
Function,+,furi_thread_get_current,FuriThread*,
Function,+,furi_thread_get_current_id,FuriThreadId,
Function,+,furi_thread_get_current_priority,FuriThreadPriority,
Function,+,furi_thread_get_heap_size,size_t,FuriThread*
Function,+,furi_thread_get_id,FuriThreadId,FuriThread*
Function,+,furi_thread_get_name,const char*,FuriThreadId
@@ -1535,8 +1557,10 @@ Function,+,furi_thread_is_suspended,_Bool,FuriThreadId
Function,+,furi_thread_join,_Bool,FuriThread*
Function,+,furi_thread_mark_as_service,void,FuriThread*
Function,+,furi_thread_resume,void,FuriThreadId
Function,+,furi_thread_set_appid,void,"FuriThread*, const char*"
Function,+,furi_thread_set_callback,void,"FuriThread*, FuriThreadCallback"
Function,+,furi_thread_set_context,void,"FuriThread*, void*"
Function,+,furi_thread_set_current_priority,void,FuriThreadPriority
Function,+,furi_thread_set_name,void,"FuriThread*, const char*"
Function,+,furi_thread_set_priority,void,"FuriThread*, FuriThreadPriority"
Function,+,furi_thread_set_stack_size,void,"FuriThread*, size_t"
@@ -1578,7 +1602,7 @@ Function,+,gui_add_framebuffer_callback,void,"Gui*, GuiCanvasCommitCallback, voi
Function,+,gui_add_view_port,void,"Gui*, ViewPort*, GuiLayer"
Function,+,gui_direct_draw_acquire,Canvas*,Gui*
Function,+,gui_direct_draw_release,void,Gui*
Function,+,gui_get_framebuffer_size,size_t,Gui*
Function,+,gui_get_framebuffer_size,size_t,const Gui*
Function,+,gui_remove_framebuffer_callback,void,"Gui*, GuiCanvasCommitCallback, void*"
Function,+,gui_remove_view_port,void,"Gui*, ViewPort*"
Function,+,gui_set_lockdown,void,"Gui*, _Bool"
@@ -1587,28 +1611,36 @@ Function,+,gui_view_port_send_to_front,void,"Gui*, ViewPort*"
Function,+,hal_sd_detect,_Bool,
Function,+,hal_sd_detect_init,void,
Function,+,hal_sd_detect_set_low,void,
Function,+,hmac_sha256_finish,void,"const hmac_sha256_context*, const uint8_t*, uint8_t*"
Function,+,hmac_sha256_init,void,"hmac_sha256_context*, const uint8_t*"
Function,+,hmac_sha256_update,void,"const hmac_sha256_context*, const uint8_t*, unsigned"
Function,-,hypot,double,"double, double"
Function,-,hypotf,float,"float, float"
Function,-,hypotl,long double,"long double, long double"
Function,+,ibutton_key_alloc,iButtonKey*,
Function,+,ibutton_key_clear_data,void,iButtonKey*
Function,+,ibutton_key_dallas_crc_is_valid,_Bool,iButtonKey*
Function,+,ibutton_key_dallas_is_1990_key,_Bool,iButtonKey*
Function,+,ibutton_key_alloc,iButtonKey*,size_t
Function,+,ibutton_key_free,void,iButtonKey*
Function,+,ibutton_key_get_data_p,const uint8_t*,iButtonKey*
Function,+,ibutton_key_get_data_size,uint8_t,iButtonKey*
Function,+,ibutton_key_get_max_size,uint8_t,
Function,+,ibutton_key_get_size_by_type,uint8_t,iButtonKeyType
Function,+,ibutton_key_get_string_by_type,const char*,iButtonKeyType
Function,+,ibutton_key_get_type,iButtonKeyType,iButtonKey*
Function,+,ibutton_key_get_type_by_string,_Bool,"const char*, iButtonKeyType*"
Function,+,ibutton_key_set,void,"iButtonKey*, const iButtonKey*"
Function,+,ibutton_key_set_data,void,"iButtonKey*, uint8_t*, uint8_t"
Function,+,ibutton_key_set_type,void,"iButtonKey*, iButtonKeyType"
Function,+,ibutton_worker_alloc,iButtonWorker*,
Function,+,ibutton_key_get_protocol_id,iButtonProtocolId,const iButtonKey*
Function,+,ibutton_key_reset,void,iButtonKey*
Function,+,ibutton_key_set_protocol_id,void,"iButtonKey*, iButtonProtocolId"
Function,+,ibutton_protocols_alloc,iButtonProtocols*,
Function,+,ibutton_protocols_apply_edits,void,"iButtonProtocols*, const iButtonKey*"
Function,+,ibutton_protocols_emulate_start,void,"iButtonProtocols*, iButtonKey*"
Function,+,ibutton_protocols_emulate_stop,void,"iButtonProtocols*, iButtonKey*"
Function,+,ibutton_protocols_free,void,iButtonProtocols*
Function,+,ibutton_protocols_get_editable_data,void,"iButtonProtocols*, const iButtonKey*, iButtonEditableData*"
Function,+,ibutton_protocols_get_features,uint32_t,"iButtonProtocols*, iButtonProtocolId"
Function,+,ibutton_protocols_get_id_by_name,iButtonProtocolId,"iButtonProtocols*, const char*"
Function,+,ibutton_protocols_get_manufacturer,const char*,"iButtonProtocols*, iButtonProtocolId"
Function,+,ibutton_protocols_get_max_data_size,size_t,iButtonProtocols*
Function,+,ibutton_protocols_get_name,const char*,"iButtonProtocols*, iButtonProtocolId"
Function,+,ibutton_protocols_get_protocol_count,uint32_t,
Function,+,ibutton_protocols_is_valid,_Bool,"iButtonProtocols*, const iButtonKey*"
Function,+,ibutton_protocols_load,_Bool,"iButtonProtocols*, iButtonKey*, const char*"
Function,+,ibutton_protocols_read,_Bool,"iButtonProtocols*, iButtonKey*"
Function,+,ibutton_protocols_render_brief_data,void,"iButtonProtocols*, const iButtonKey*, FuriString*"
Function,+,ibutton_protocols_render_data,void,"iButtonProtocols*, const iButtonKey*, FuriString*"
Function,+,ibutton_protocols_render_error,void,"iButtonProtocols*, const iButtonKey*, FuriString*"
Function,+,ibutton_protocols_save,_Bool,"iButtonProtocols*, const iButtonKey*, const char*"
Function,+,ibutton_protocols_write_blank,_Bool,"iButtonProtocols*, iButtonKey*"
Function,+,ibutton_protocols_write_copy,_Bool,"iButtonProtocols*, iButtonKey*"
Function,+,ibutton_worker_alloc,iButtonWorker*,iButtonProtocols*
Function,+,ibutton_worker_emulate_set_callback,void,"iButtonWorker*, iButtonWorkerEmulateCallback, void*"
Function,+,ibutton_worker_emulate_start,void,"iButtonWorker*, iButtonKey*"
Function,+,ibutton_worker_free,void,iButtonWorker*
@@ -1617,13 +1649,14 @@ Function,+,ibutton_worker_read_start,void,"iButtonWorker*, iButtonKey*"
Function,+,ibutton_worker_start_thread,void,iButtonWorker*
Function,+,ibutton_worker_stop,void,iButtonWorker*
Function,+,ibutton_worker_stop_thread,void,iButtonWorker*
Function,+,ibutton_worker_write_blank_start,void,"iButtonWorker*, iButtonKey*"
Function,+,ibutton_worker_write_copy_start,void,"iButtonWorker*, iButtonKey*"
Function,+,ibutton_worker_write_set_callback,void,"iButtonWorker*, iButtonWorkerWriteCallback, void*"
Function,+,ibutton_worker_write_start,void,"iButtonWorker*, iButtonKey*"
Function,+,icon_animation_alloc,IconAnimation*,const Icon*
Function,+,icon_animation_free,void,IconAnimation*
Function,+,icon_animation_get_height,uint8_t,IconAnimation*
Function,+,icon_animation_get_width,uint8_t,IconAnimation*
Function,+,icon_animation_is_last_frame,_Bool,IconAnimation*
Function,+,icon_animation_get_height,uint8_t,const IconAnimation*
Function,+,icon_animation_get_width,uint8_t,const IconAnimation*
Function,+,icon_animation_is_last_frame,_Bool,const IconAnimation*
Function,+,icon_animation_set_update_callback,void,"IconAnimation*, IconAnimationCallback, void*"
Function,+,icon_animation_start,void,IconAnimation*
Function,+,icon_animation_stop,void,IconAnimation*
@@ -1673,7 +1706,6 @@ Function,+,infrared_worker_tx_set_get_signal_callback,void,"InfraredWorker*, Inf
Function,+,infrared_worker_tx_set_signal_sent_callback,void,"InfraredWorker*, InfraredWorkerMessageSentCallback, void*"
Function,+,infrared_worker_tx_start,void,InfraredWorker*
Function,+,infrared_worker_tx_stop,void,InfraredWorker*
Function,+,init_mutex,_Bool,"ValueMutex*, void*, size_t"
Function,-,initstate,char*,"unsigned, char*, size_t"
Function,+,input_get_key_name,const char*,InputKey
Function,+,input_get_type_name,const char*,InputType
@@ -1763,7 +1795,7 @@ Function,-,llround,long long int,double
Function,-,llroundf,long long int,float
Function,-,llroundl,long long int,long double
Function,+,loader_get_pubsub,FuriPubSub*,Loader*
Function,+,loader_is_locked,_Bool,Loader*
Function,+,loader_is_locked,_Bool,const Loader*
Function,+,loader_lock,_Bool,Loader*
Function,+,loader_show_menu,void,
Function,+,loader_start,LoaderStatus,"Loader*, const char*, const char*"
@@ -1876,10 +1908,12 @@ Function,+,menu_free,void,Menu*
Function,+,menu_get_view,View*,Menu*
Function,+,menu_reset,void,Menu*
Function,+,menu_set_selected_item,void,"Menu*, uint32_t"
Function,-,mf_classic_auth_attempt,_Bool,"FuriHalNfcTxRxContext*, MfClassicAuthContext*, uint64_t"
Function,-,mf_classic_auth_attempt,_Bool,"FuriHalNfcTxRxContext*, Crypto1*, MfClassicAuthContext*, uint64_t"
Function,-,mf_classic_auth_init_context,void,"MfClassicAuthContext*, uint8_t"
Function,-,mf_classic_auth_write_block,_Bool,"FuriHalNfcTxRxContext*, MfClassicBlock*, uint8_t, MfClassicKey, uint64_t"
Function,-,mf_classic_authenticate,_Bool,"FuriHalNfcTxRxContext*, uint8_t, uint64_t, MfClassicKey"
Function,-,mf_classic_authenticate_skip_activate,_Bool,"FuriHalNfcTxRxContext*, uint8_t, uint64_t, MfClassicKey, _Bool, uint32_t"
Function,-,mf_classic_block_to_value,_Bool,"const uint8_t*, int32_t*, uint8_t*"
Function,-,mf_classic_check_card_type,_Bool,FuriHalNfcADevData*
Function,-,mf_classic_dict_add_key,_Bool,"MfClassicDict*, uint8_t*"
Function,-,mf_classic_dict_add_key_str,_Bool,"MfClassicDict*, FuriString*"
@@ -1906,6 +1940,7 @@ Function,-,mf_classic_get_sector_trailer_by_sector,MfClassicSectorTrailer*,"MfCl
Function,-,mf_classic_get_total_block_num,uint16_t,MfClassicType
Function,-,mf_classic_get_total_sectors_num,uint8_t,MfClassicType
Function,-,mf_classic_get_type_str,const char*,MfClassicType
Function,-,mf_classic_halt,void,"FuriHalNfcTxRxContext*, Crypto1*"
Function,-,mf_classic_is_allowed_access_data_block,_Bool,"MfClassicData*, uint8_t, MfClassicKey, MfClassicAction"
Function,-,mf_classic_is_allowed_access_sector_trailer,_Bool,"MfClassicData*, uint8_t, MfClassicKey, MfClassicAction"
Function,-,mf_classic_is_block_read,_Bool,"MfClassicData*, uint8_t"
@@ -1914,6 +1949,8 @@ Function,-,mf_classic_is_key_found,_Bool,"MfClassicData*, uint8_t, MfClassicKey"
Function,-,mf_classic_is_sector_data_read,_Bool,"MfClassicData*, uint8_t"
Function,-,mf_classic_is_sector_read,_Bool,"MfClassicData*, uint8_t"
Function,-,mf_classic_is_sector_trailer,_Bool,uint8_t
Function,-,mf_classic_is_value_block,_Bool,"MfClassicData*, uint8_t"
Function,-,mf_classic_read_block,_Bool,"FuriHalNfcTxRxContext*, Crypto1*, uint8_t, MfClassicBlock*"
Function,-,mf_classic_read_card,uint8_t,"FuriHalNfcTxRxContext*, MfClassicReader*, MfClassicData*"
Function,-,mf_classic_read_sector,void,"FuriHalNfcTxRxContext*, MfClassicData*, uint8_t"
Function,-,mf_classic_reader_add_sector,void,"MfClassicReader*, uint8_t, uint64_t, uint64_t"
@@ -1921,8 +1958,12 @@ Function,-,mf_classic_set_block_read,void,"MfClassicData*, uint8_t, MfClassicBlo
Function,-,mf_classic_set_key_found,void,"MfClassicData*, uint8_t, MfClassicKey, uint64_t"
Function,-,mf_classic_set_key_not_found,void,"MfClassicData*, uint8_t, MfClassicKey"
Function,-,mf_classic_set_sector_data_not_read,void,MfClassicData*
Function,-,mf_classic_transfer,_Bool,"FuriHalNfcTxRxContext*, Crypto1*, uint8_t"
Function,-,mf_classic_update_card,uint8_t,"FuriHalNfcTxRxContext*, MfClassicData*"
Function,-,mf_classic_write_block,_Bool,"FuriHalNfcTxRxContext*, MfClassicBlock*, uint8_t, MfClassicKey, uint64_t"
Function,-,mf_classic_value_cmd,_Bool,"FuriHalNfcTxRxContext*, Crypto1*, uint8_t, uint8_t, int32_t"
Function,-,mf_classic_value_cmd_full,_Bool,"FuriHalNfcTxRxContext*, MfClassicBlock*, uint8_t, MfClassicKey, uint64_t, int32_t"
Function,-,mf_classic_value_to_block,void,"int32_t, uint8_t, uint8_t*"
Function,-,mf_classic_write_block,_Bool,"FuriHalNfcTxRxContext*, Crypto1*, uint8_t, MfClassicBlock*"
Function,-,mf_classic_write_sector,_Bool,"FuriHalNfcTxRxContext*, MfClassicData*, MfClassicData*, uint8_t"
Function,-,mf_df_cat_application,void,"MifareDesfireApplication*, FuriString*"
Function,-,mf_df_cat_application_info,void,"MifareDesfireApplication*, FuriString*"
@@ -2021,30 +2062,30 @@ Function,+,notification_message,void,"NotificationApp*, const NotificationSequen
Function,+,notification_message_block,void,"NotificationApp*, const NotificationSequence*"
Function,-,nrand48,long,unsigned short[3]
Function,-,on_exit,int,"void (*)(int, void*), void*"
Function,+,onewire_device_alloc,OneWireDevice*,"uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t"
Function,+,onewire_device_attach,void,"OneWireDevice*, OneWireSlave*"
Function,+,onewire_device_detach,void,OneWireDevice*
Function,+,onewire_device_free,void,OneWireDevice*
Function,+,onewire_device_get_id_p,uint8_t*,OneWireDevice*
Function,+,onewire_device_send_id,void,OneWireDevice*
Function,+,onewire_host_alloc,OneWireHost*,
Function,+,onewire_host_alloc,OneWireHost*,const GpioPin*
Function,+,onewire_host_free,void,OneWireHost*
Function,+,onewire_host_read,uint8_t,OneWireHost*
Function,+,onewire_host_read_bit,_Bool,OneWireHost*
Function,+,onewire_host_read_bytes,void,"OneWireHost*, uint8_t*, uint16_t"
Function,+,onewire_host_reset,_Bool,OneWireHost*
Function,+,onewire_host_reset_search,void,OneWireHost*
Function,+,onewire_host_search,uint8_t,"OneWireHost*, uint8_t*, OneWireHostSearchMode"
Function,+,onewire_host_skip,void,OneWireHost*
Function,+,onewire_host_search,_Bool,"OneWireHost*, uint8_t*, OneWireHostSearchMode"
Function,+,onewire_host_set_overdrive,void,"OneWireHost*, _Bool"
Function,+,onewire_host_start,void,OneWireHost*
Function,+,onewire_host_stop,void,OneWireHost*
Function,+,onewire_host_target_search,void,"OneWireHost*, uint8_t"
Function,+,onewire_host_write,void,"OneWireHost*, uint8_t"
Function,+,onewire_host_write_bit,void,"OneWireHost*, _Bool"
Function,+,onewire_slave_alloc,OneWireSlave*,
Function,+,onewire_slave_attach,void,"OneWireSlave*, OneWireDevice*"
Function,+,onewire_slave_detach,void,OneWireSlave*
Function,+,onewire_host_write_bytes,void,"OneWireHost*, const uint8_t*, uint16_t"
Function,+,onewire_slave_alloc,OneWireSlave*,const GpioPin*
Function,+,onewire_slave_free,void,OneWireSlave*
Function,+,onewire_slave_receive,_Bool,"OneWireSlave*, uint8_t*, size_t"
Function,+,onewire_slave_receive_bit,_Bool,OneWireSlave*
Function,+,onewire_slave_send,_Bool,"OneWireSlave*, const uint8_t*, size_t"
Function,+,onewire_slave_send_bit,_Bool,"OneWireSlave*, _Bool"
Function,+,onewire_slave_set_command_callback,void,"OneWireSlave*, OneWireSlaveCommandCallback, void*"
Function,+,onewire_slave_set_overdrive,void,"OneWireSlave*, _Bool"
Function,+,onewire_slave_set_reset_callback,void,"OneWireSlave*, OneWireSlaveResetCallback, void*"
Function,+,onewire_slave_set_result_callback,void,"OneWireSlave*, OneWireSlaveResultCallback, void*"
Function,+,onewire_slave_start,void,OneWireSlave*
Function,+,onewire_slave_stop,void,OneWireSlave*
@@ -2067,6 +2108,13 @@ Function,-,platformProtectST25RComm,void,
Function,-,platformSetIrqCallback,void,PlatformIrqCallback
Function,-,platformSpiTxRx,_Bool,"const uint8_t*, uint8_t*, uint16_t"
Function,-,platformUnprotectST25RComm,void,
Function,+,plugin_manager_alloc,PluginManager*,"const char*, uint32_t, const ElfApiInterface*"
Function,+,plugin_manager_free,void,PluginManager*
Function,+,plugin_manager_get,const FlipperAppPluginDescriptor*,"PluginManager*, uint32_t"
Function,+,plugin_manager_get_count,uint32_t,PluginManager*
Function,+,plugin_manager_get_ep,const void*,"PluginManager*, uint32_t"
Function,+,plugin_manager_load_all,PluginManagerError,"PluginManager*, const char*"
Function,+,plugin_manager_load_single,PluginManagerError,"PluginManager*, const char*"
Function,-,popen,FILE*,"const char*, const char*"
Function,+,popup_alloc,Popup*,
Function,+,popup_disable_timeout,void,Popup*
@@ -2092,6 +2140,7 @@ Function,+,power_off,void,Power*
Function,+,power_reboot,void,PowerBootMode
Function,+,powf,float,"float, float"
Function,-,powl,long double,"long double, long double"
Function,+,pretty_format_bytes_hex_canonical,void,"FuriString*, size_t, const char*, const uint8_t*, size_t"
Function,-,printf,int,"const char*, ..."
Function,-,prng_successor,uint32_t,"uint32_t, uint32_t"
Function,+,property_value_out,void,"PropertyValueContext*, const char*, unsigned int, ..."
@@ -2136,12 +2185,10 @@ Function,+,rand,int,
Function,-,rand_r,int,unsigned*
Function,+,random,long,
Function,-,rawmemchr,void*,"const void*, int"
Function,-,read_mutex,_Bool,"ValueMutex*, void*, size_t, uint32_t"
Function,+,realloc,void*,"void*, size_t"
Function,-,reallocarray,void*,"void*, size_t, size_t"
Function,-,reallocf,void*,"void*, size_t"
Function,-,realpath,char*,"const char*, char*"
Function,+,release_mutex,_Bool,"ValueMutex*, const void*"
Function,-,remainder,double,"double, double"
Function,-,remainderf,float,"float, float"
Function,-,remainderl,long double,"long double, long double"
@@ -2363,11 +2410,11 @@ Function,-,scalbnl,long double,"long double, int"
Function,-,scanf,int,"const char*, ..."
Function,+,scene_manager_alloc,SceneManager*,"const SceneManagerHandlers*, void*"
Function,+,scene_manager_free,void,SceneManager*
Function,+,scene_manager_get_scene_state,uint32_t,"SceneManager*, uint32_t"
Function,+,scene_manager_get_scene_state,uint32_t,"const SceneManager*, uint32_t"
Function,+,scene_manager_handle_back_event,_Bool,SceneManager*
Function,+,scene_manager_handle_custom_event,_Bool,"SceneManager*, uint32_t"
Function,+,scene_manager_handle_tick_event,void,SceneManager*
Function,+,scene_manager_has_previous_scene,_Bool,"SceneManager*, uint32_t"
Function,+,scene_manager_has_previous_scene,_Bool,"const SceneManager*, uint32_t"
Function,+,scene_manager_next_scene,void,"SceneManager*, uint32_t"
Function,+,scene_manager_previous_scene,_Bool,SceneManager*
Function,+,scene_manager_search_and_switch_to_another_scene,_Bool,"SceneManager*, uint32_t"
@@ -2420,20 +2467,25 @@ Function,-,srand48,void,long
Function,-,srandom,void,unsigned
Function,+,sscanf,int,"const char*, const char*, ..."
Function,+,storage_common_copy,FS_Error,"Storage*, const char*, const char*"
Function,+,storage_common_exists,_Bool,"Storage*, const char*"
Function,+,storage_common_fs_info,FS_Error,"Storage*, const char*, uint64_t*, uint64_t*"
Function,+,storage_common_merge,FS_Error,"Storage*, const char*, const char*"
Function,+,storage_common_migrate,FS_Error,"Storage*, const char*, const char*"
Function,+,storage_common_mkdir,FS_Error,"Storage*, const char*"
Function,+,storage_common_remove,FS_Error,"Storage*, const char*"
Function,+,storage_common_rename,FS_Error,"Storage*, const char*, const char*"
Function,+,storage_common_resolve_path_and_ensure_app_directory,void,"Storage*, FuriString*"
Function,+,storage_common_stat,FS_Error,"Storage*, const char*, FileInfo*"
Function,+,storage_common_timestamp,FS_Error,"Storage*, const char*, uint32_t*"
Function,+,storage_dir_close,_Bool,File*
Function,+,storage_dir_exists,_Bool,"Storage*, const char*"
Function,+,storage_dir_open,_Bool,"File*, const char*"
Function,+,storage_dir_read,_Bool,"File*, FileInfo*, char*, uint16_t"
Function,-,storage_dir_rewind,_Bool,File*
Function,+,storage_error_get_desc,const char*,FS_Error
Function,+,storage_file_alloc,File*,Storage*
Function,+,storage_file_close,_Bool,File*
Function,+,storage_file_copy_to_file,_Bool,"File*, File*, uint32_t"
Function,+,storage_file_eof,_Bool,File*
Function,+,storage_file_exists,_Bool,"Storage*, const char*"
Function,+,storage_file_free,void,File*
@@ -2556,17 +2608,20 @@ Function,-,strupr,char*,char*
Function,-,strverscmp,int,"const char*, const char*"
Function,-,strxfrm,size_t,"char*, const char*, size_t"
Function,-,strxfrm_l,size_t,"char*, const char*, size_t, locale_t"
Function,+,subghz_block_generic_deserialize,_Bool,"SubGhzBlockGeneric*, FlipperFormat*"
Function,+,subghz_block_generic_deserialize,SubGhzProtocolStatus,"SubGhzBlockGeneric*, FlipperFormat*"
Function,+,subghz_block_generic_deserialize_check_count_bit,SubGhzProtocolStatus,"SubGhzBlockGeneric*, FlipperFormat*, uint16_t"
Function,+,subghz_block_generic_get_preset_name,void,"const char*, FuriString*"
Function,+,subghz_block_generic_serialize,_Bool,"SubGhzBlockGeneric*, FlipperFormat*, SubGhzRadioPreset*"
Function,+,subghz_block_generic_serialize,SubGhzProtocolStatus,"SubGhzBlockGeneric*, FlipperFormat*, SubGhzRadioPreset*"
Function,+,subghz_environment_alloc,SubGhzEnvironment*,
Function,+,subghz_environment_free,void,SubGhzEnvironment*
Function,+,subghz_environment_get_alutech_at_4n_rainbow_table_file_name,const char*,SubGhzEnvironment*
Function,+,subghz_environment_get_came_atomo_rainbow_table_file_name,const char*,SubGhzEnvironment*
Function,+,subghz_environment_get_keystore,SubGhzKeystore*,SubGhzEnvironment*
Function,+,subghz_environment_get_nice_flor_s_rainbow_table_file_name,const char*,SubGhzEnvironment*
Function,+,subghz_environment_get_protocol_name_registry,const char*,"SubGhzEnvironment*, size_t"
Function,+,subghz_environment_get_protocol_registry,void*,SubGhzEnvironment*
Function,+,subghz_environment_load_keystore,_Bool,"SubGhzEnvironment*, const char*"
Function,+,subghz_environment_set_alutech_at_4n_rainbow_table_file_name,void,"SubGhzEnvironment*, const char*"
Function,+,subghz_environment_set_came_atomo_rainbow_table_file_name,void,"SubGhzEnvironment*, const char*"
Function,+,subghz_environment_set_nice_flor_s_rainbow_table_file_name,void,"SubGhzEnvironment*, const char*"
Function,+,subghz_environment_set_protocol_registry,void,"SubGhzEnvironment*, void*"
@@ -2589,7 +2644,7 @@ Function,+,subghz_protocol_blocks_crc8le,uint8_t,"const uint8_t[], size_t, uint8
Function,+,subghz_protocol_blocks_get_bit_array,_Bool,"uint8_t[], size_t"
Function,+,subghz_protocol_blocks_get_hash_data,uint8_t,"SubGhzBlockDecoder*, size_t"
Function,+,subghz_protocol_blocks_get_parity,uint8_t,"uint64_t, uint8_t"
Function,+,subghz_protocol_blocks_get_upload,size_t,"uint8_t[], size_t, LevelDuration*, size_t, uint32_t"
Function,+,subghz_protocol_blocks_get_upload_from_bit_array,size_t,"uint8_t[], size_t, LevelDuration*, size_t, uint32_t, SubGhzProtocolBlockAlignBit"
Function,+,subghz_protocol_blocks_lfsr_digest16,uint16_t,"const uint8_t[], size_t, uint16_t, uint16_t"
Function,+,subghz_protocol_blocks_lfsr_digest8,uint8_t,"const uint8_t[], size_t, uint8_t, uint8_t"
Function,+,subghz_protocol_blocks_lfsr_digest8_reflect,uint8_t,"const uint8_t[], size_t, uint8_t, uint8_t"
@@ -2598,19 +2653,19 @@ Function,+,subghz_protocol_blocks_parity_bytes,uint8_t,"const uint8_t[], size_t"
Function,+,subghz_protocol_blocks_reverse_key,uint64_t,"uint64_t, uint8_t"
Function,+,subghz_protocol_blocks_set_bit_array,void,"_Bool, uint8_t[], size_t, size_t"
Function,+,subghz_protocol_blocks_xor_bytes,uint8_t,"const uint8_t[], size_t"
Function,-,subghz_protocol_decoder_base_deserialize,_Bool,"SubGhzProtocolDecoderBase*, FlipperFormat*"
Function,+,subghz_protocol_decoder_base_deserialize,SubGhzProtocolStatus,"SubGhzProtocolDecoderBase*, FlipperFormat*"
Function,+,subghz_protocol_decoder_base_get_hash_data,uint8_t,SubGhzProtocolDecoderBase*
Function,+,subghz_protocol_decoder_base_get_string,_Bool,"SubGhzProtocolDecoderBase*, FuriString*"
Function,+,subghz_protocol_decoder_base_serialize,_Bool,"SubGhzProtocolDecoderBase*, FlipperFormat*, SubGhzRadioPreset*"
Function,+,subghz_protocol_decoder_base_serialize,SubGhzProtocolStatus,"SubGhzProtocolDecoderBase*, FlipperFormat*, SubGhzRadioPreset*"
Function,-,subghz_protocol_decoder_base_set_decoder_callback,void,"SubGhzProtocolDecoderBase*, SubGhzProtocolDecoderBaseRxCallback, void*"
Function,+,subghz_protocol_decoder_raw_alloc,void*,SubGhzEnvironment*
Function,+,subghz_protocol_decoder_raw_deserialize,_Bool,"void*, FlipperFormat*"
Function,+,subghz_protocol_decoder_raw_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*"
Function,+,subghz_protocol_decoder_raw_feed,void,"void*, _Bool, uint32_t"
Function,+,subghz_protocol_decoder_raw_free,void,void*
Function,+,subghz_protocol_decoder_raw_get_string,void,"void*, FuriString*"
Function,+,subghz_protocol_decoder_raw_reset,void,void*
Function,+,subghz_protocol_encoder_raw_alloc,void*,SubGhzEnvironment*
Function,+,subghz_protocol_encoder_raw_deserialize,_Bool,"void*, FlipperFormat*"
Function,+,subghz_protocol_encoder_raw_deserialize,SubGhzProtocolStatus,"void*, FlipperFormat*"
Function,+,subghz_protocol_encoder_raw_free,void,void*
Function,+,subghz_protocol_encoder_raw_stop,void,void*
Function,+,subghz_protocol_encoder_raw_yield,LevelDuration,void*
@@ -2648,7 +2703,7 @@ Function,+,subghz_setting_get_preset_name,const char*,"SubGhzSetting*, size_t"
Function,+,subghz_setting_load,void,"SubGhzSetting*, const char*"
Function,+,subghz_setting_load_custom_preset,_Bool,"SubGhzSetting*, const char*, FlipperFormat*"
Function,+,subghz_transmitter_alloc_init,SubGhzTransmitter*,"SubGhzEnvironment*, const char*"
Function,+,subghz_transmitter_deserialize,_Bool,"SubGhzTransmitter*, FlipperFormat*"
Function,+,subghz_transmitter_deserialize,SubGhzProtocolStatus,"SubGhzTransmitter*, FlipperFormat*"
Function,+,subghz_transmitter_free,void,SubGhzTransmitter*
Function,+,subghz_transmitter_get_protocol_instance,SubGhzProtocolEncoderBase*,SubGhzTransmitter*
Function,+,subghz_transmitter_stop,_Bool,SubGhzTransmitter*
@@ -2667,6 +2722,7 @@ Function,+,subghz_worker_free,void,SubGhzWorker*
Function,+,subghz_worker_is_running,_Bool,SubGhzWorker*
Function,+,subghz_worker_rx_callback,void,"_Bool, uint32_t, void*"
Function,+,subghz_worker_set_context,void,"SubGhzWorker*, void*"
Function,+,subghz_worker_set_filter,void,"SubGhzWorker*, uint16_t"
Function,+,subghz_worker_set_overrun_callback,void,"SubGhzWorker*, SubGhzWorkerOverrunCallback"
Function,+,subghz_worker_set_pair_callback,void,"SubGhzWorker*, SubGhzWorkerPairCallback"
Function,+,subghz_worker_start,void,SubGhzWorker*
@@ -2883,11 +2939,11 @@ Function,+,view_port_alloc,ViewPort*,
Function,+,view_port_draw_callback_set,void,"ViewPort*, ViewPortDrawCallback, void*"
Function,+,view_port_enabled_set,void,"ViewPort*, _Bool"
Function,+,view_port_free,void,ViewPort*
Function,+,view_port_get_height,uint8_t,ViewPort*
Function,+,view_port_get_height,uint8_t,const ViewPort*
Function,+,view_port_get_orientation,ViewPortOrientation,const ViewPort*
Function,+,view_port_get_width,uint8_t,ViewPort*
Function,+,view_port_get_width,uint8_t,const ViewPort*
Function,+,view_port_input_callback_set,void,"ViewPort*, ViewPortInputCallback, void*"
Function,+,view_port_is_enabled,_Bool,ViewPort*
Function,+,view_port_is_enabled,_Bool,const ViewPort*
Function,+,view_port_set_height,void,"ViewPort*, uint8_t"
Function,+,view_port_set_orientation,void,"ViewPort*, ViewPortOrientation"
Function,+,view_port_set_width,void,"ViewPort*, uint8_t"
@@ -2931,7 +2987,6 @@ Function,+,widget_alloc,Widget*,
Function,+,widget_free,void,Widget*
Function,+,widget_get_view,View*,Widget*
Function,+,widget_reset,void,Widget*
Function,-,write_mutex,_Bool,"ValueMutex*, void*, size_t, uint32_t"
Function,-,xPortGetFreeHeapSize,size_t,
Function,-,xPortGetMinimumEverFreeHeapSize,size_t,
Function,-,xPortStartScheduler,BaseType_t,
@@ -2990,6 +3045,7 @@ Variable,-,_sys_nerr,int,
Variable,-,_timezone,long,
Variable,-,_tzname,char*[2],
Variable,+,cli_vcp,CliSession,
Variable,+,firmware_api_interface,const ElfApiInterface*,
Variable,+,furi_hal_i2c_bus_external,FuriHalI2cBus,
Variable,+,furi_hal_i2c_bus_power,FuriHalI2cBus,
Variable,+,furi_hal_i2c_handle_external,FuriHalI2cBusHandle,
@@ -3032,6 +3088,8 @@ Variable,+,gpio_infrared_rx,const GpioPin,
Variable,+,gpio_infrared_tx,const GpioPin,
Variable,+,gpio_nfc_cs,const GpioPin,
Variable,+,gpio_nfc_irq_rfid_pull,const GpioPin,
Variable,+,gpio_pins,const GpioPinRecord[],
Variable,+,gpio_pins_count,const size_t,
Variable,+,gpio_rf_sw_0,const GpioPin,
Variable,+,gpio_rfid_carrier,const GpioPin,
Variable,+,gpio_rfid_carrier_out,const GpioPin,
1 entry status name type params
2 Version + 11.10 20.0
3 Header + applications/services/bt/bt_service/bt.h
4 Header + applications/services/cli/cli.h
5 Header + applications/services/cli/cli_vcp.h
28 Header + applications/services/gui/view_dispatcher.h
29 Header + applications/services/gui/view_stack.h
30 Header + applications/services/input/input.h
31 Header + applications/services/loader/firmware_api/firmware_api.h
32 Header + applications/services/loader/loader.h
33 Header + applications/services/locale/locale.h
34 Header + applications/services/notification/notification.h
42 Header + firmware/targets/f7/furi_hal/furi_hal_gpio.h
43 Header + firmware/targets/f7/furi_hal/furi_hal_i2c_config.h
44 Header + firmware/targets/f7/furi_hal/furi_hal_i2c_types.h
45 Header + firmware/targets/f7/furi_hal/furi_hal_ibutton.h
46 Header + firmware/targets/f7/furi_hal/furi_hal_idle_timer.h
47 Header + firmware/targets/f7/furi_hal/furi_hal_interrupt.h
48 Header + firmware/targets/f7/furi_hal/furi_hal_nfc.h
49 Header + firmware/targets/f7/furi_hal/furi_hal_os.h
50 Header + firmware/targets/f7/furi_hal/furi_hal_pwm.h
51 Header + firmware/targets/f7/furi_hal/furi_hal_resources.h
52 Header + firmware/targets/f7/furi_hal/furi_hal_rfid.h
53 Header + firmware/targets/f7/furi_hal/furi_hal_spi_config.h
54 Header + firmware/targets/f7/furi_hal/furi_hal_spi_types.h
55 Header + firmware/targets/f7/furi_hal/furi_hal_subghz.h
56 Header + firmware/targets/f7/furi_hal/furi_hal_subghz_configs.h
57 Header + firmware/targets/f7/furi_hal/furi_hal_target_hw.h
58 Header + firmware/targets/f7/furi_hal/furi_hal_uart.h
59 Header + firmware/targets/f7/furi_hal/furi_hal_usb_cdc.h
60 Header + firmware/targets/f7/platform_specific/intrinsic_export.h
62 Header + firmware/targets/furi_hal_include/furi_hal_bt.h
63 Header + firmware/targets/furi_hal_include/furi_hal_bt_hid.h
64 Header + firmware/targets/furi_hal_include/furi_hal_bt_serial.h
Header + firmware/targets/furi_hal_include/furi_hal_compress.h
65 Header + firmware/targets/furi_hal_include/furi_hal_cortex.h
66 Header + firmware/targets/furi_hal_include/furi_hal_crypto.h
67 Header + firmware/targets/furi_hal_include/furi_hal_debug.h
68 Header + firmware/targets/furi_hal_include/furi_hal_i2c.h
Header + firmware/targets/furi_hal_include/furi_hal_ibutton.h
69 Header + firmware/targets/furi_hal_include/furi_hal_info.h
70 Header + firmware/targets/furi_hal_include/furi_hal_infrared.h
71 Header + firmware/targets/furi_hal_include/furi_hal_light.h
72 Header + firmware/targets/furi_hal_include/furi_hal_memory.h
73 Header + firmware/targets/furi_hal_include/furi_hal_mpu.h
Header + firmware/targets/furi_hal_include/furi_hal_nfc.h
74 Header + firmware/targets/furi_hal_include/furi_hal_power.h
75 Header + firmware/targets/furi_hal_include/furi_hal_random.h
76 Header + firmware/targets/furi_hal_include/furi_hal_region.h
Header + firmware/targets/furi_hal_include/furi_hal_rfid.h
77 Header + firmware/targets/furi_hal_include/furi_hal_rtc.h
78 Header + firmware/targets/furi_hal_include/furi_hal_sd.h
79 Header + firmware/targets/furi_hal_include/furi_hal_speaker.h
80 Header + firmware/targets/furi_hal_include/furi_hal_spi.h
Header + firmware/targets/furi_hal_include/furi_hal_subghz.h
81 Header + firmware/targets/furi_hal_include/furi_hal_usb.h
82 Header + firmware/targets/furi_hal_include/furi_hal_usb_hid.h
83 Header + firmware/targets/furi_hal_include/furi_hal_usb_hid_u2f.h
110 Header + lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Inc/stm32wbxx_ll_usart.h
111 Header + lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Inc/stm32wbxx_ll_utils.h
112 Header + lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Inc/stm32wbxx_ll_wwdg.h
113 Header + lib/flipper_application/api_hashtable/api_hashtable.h
114 Header + lib/flipper_application/api_hashtable/compilesort.hpp
115 Header + lib/flipper_application/flipper_application.h
116 Header + lib/flipper_application/plugins/composite_resolver.h
117 Header + lib/flipper_application/plugins/plugin_manager.h
118 Header + lib/flipper_format/flipper_format.h
119 Header + lib/flipper_format/flipper_format_i.h
120 Header + lib/ibutton/ibutton_key.h
121 Header + lib/ibutton/ibutton_protocols.h
122 Header + lib/ibutton/ibutton_worker.h
123 Header + lib/infrared/encoder_decoder/infrared.h
124 Header + lib/infrared/worker/infrared_transmit.h
125 Header + lib/infrared/worker/infrared_worker.h
158 Header + lib/mbedtls/include/mbedtls/des.h
159 Header + lib/mbedtls/include/mbedtls/sha1.h
160 Header + lib/micro-ecc/uECC.h
161 Header + lib/mlib/m-algo.h
162 Header + lib/mlib/m-array.h
163 Header + lib/mlib/m-bptree.h
164 Header + lib/mlib/m-core.h
165 Header + lib/mlib/m-deque.h
166 Header + lib/mlib/m-dict.h
167 Header + lib/mlib/m-list.h
168 Header + lib/mlib/m-rbtree.h
169 Header + lib/mlib/m-tuple.h
170 Header + lib/mlib/m-variant.h
171 Header + lib/nfc/nfc_device.h
Header + lib/one_wire/ibutton/ibutton_worker.h
172 Header + lib/one_wire/maxim_crc.h
Header + lib/one_wire/one_wire_device.h
173 Header + lib/one_wire/one_wire_host.h
Header + lib/one_wire/one_wire_host_timing.h
174 Header + lib/one_wire/one_wire_slave.h
175 Header + lib/print/wrappers.h
176 Header + lib/subghz/blocks/const.h
190 Header + lib/toolbox/crc32_calc.h
191 Header + lib/toolbox/dir_walk.h
192 Header + lib/toolbox/float_tools.h
Header + lib/toolbox/hmac_sha256.h
193 Header + lib/toolbox/manchester_decoder.h
194 Header + lib/toolbox/manchester_encoder.h
195 Header + lib/toolbox/md5.h
196 Header + lib/toolbox/path.h
197 Header + lib/toolbox/pretty_format.h
198 Header + lib/toolbox/protocols/protocol_dict.h
199 Header + lib/toolbox/random_name.h
200 Header + lib/toolbox/saved_struct.h
201 Header + lib/toolbox/sha256.h
202 Header + lib/toolbox/stream/buffered_file_stream.h
203 Header + lib/toolbox/stream/file_stream.h
204 Header + lib/toolbox/stream/stream.h
494 Function - acoshf float float
495 Function - acoshl long double long double
496 Function - acosl long double long double
Function + acquire_mutex void* ValueMutex*, uint32_t
497 Function - aligned_alloc void* size_t, size_t
498 Function + aligned_free void void*
499 Function + aligned_malloc void* size_t, size_t
611 Function - calloc void* size_t, size_t
612 Function + canvas_clear void Canvas*
613 Function + canvas_commit void Canvas*
614 Function + canvas_current_font_height uint8_t Canvas* const Canvas*
615 Function + canvas_draw_bitmap void Canvas*, uint8_t, uint8_t, uint8_t, uint8_t, const uint8_t*
616 Function + canvas_draw_box void Canvas*, uint8_t, uint8_t, uint8_t, uint8_t
617 Function + canvas_draw_circle void Canvas*, uint8_t, uint8_t, uint8_t
628 Function + canvas_draw_str_aligned void Canvas*, uint8_t, uint8_t, Align, Align, const char*
629 Function + canvas_draw_triangle void Canvas*, uint8_t, uint8_t, uint8_t, uint8_t, CanvasDirection
630 Function + canvas_draw_xbm void Canvas*, uint8_t, uint8_t, uint8_t, uint8_t, const uint8_t*
631 Function + canvas_get_font_params CanvasFontParameters* const CanvasFontParameters* Canvas*, Font const Canvas*, Font
632 Function + canvas_glyph_width uint8_t Canvas*, char
633 Function + canvas_height uint8_t Canvas* const Canvas*
634 Function + canvas_invert_color void Canvas*
635 Function + canvas_reset void Canvas*
636 Function + canvas_set_bitmap_mode void Canvas*, _Bool
637 Function + canvas_set_color void Canvas*, Color
638 Function + canvas_set_custom_u8g2_font void Canvas*, const uint8_t*
639 Function + canvas_set_font void Canvas*, Font
640 Function + canvas_set_font_direction void Canvas*, CanvasDirection
641 Function + canvas_string_width uint16_t Canvas*, const char*
642 Function + canvas_width uint8_t Canvas* const Canvas*
643 Function - cbrt double double
644 Function - cbrtf float float
645 Function - cbrtl long double long double
682 Function + cli_session_open void Cli*, void*
683 Function + cli_write void Cli*, const uint8_t*, size_t
684 Function - clock clock_t
685 Function + composite_api_resolver_add void CompositeApiResolver*, const ElfApiInterface*
686 Function + composite_api_resolver_alloc CompositeApiResolver*
687 Function + composite_api_resolver_free void CompositeApiResolver*
688 Function + composite_api_resolver_get const ElfApiInterface* CompositeApiResolver*
689 Function - copysign double double, double
690 Function - copysignf float float, float
691 Function - copysignl long double long double, long double
709 Function - ctime char* const time_t*
710 Function - ctime_r char* const time_t*, char*
711 Function - cuserid char* char*
Function + delete_mutex _Bool ValueMutex*
712 Function + dialog_ex_alloc DialogEx*
713 Function + dialog_ex_disable_extended_events void DialogEx*
714 Function + dialog_ex_enable_extended_events void DialogEx*
785 Function + elements_slightly_rounded_frame void Canvas*, uint8_t, uint8_t, uint8_t, uint8_t
786 Function + elements_string_fit_width void Canvas*, FuriString*, uint8_t
787 Function + elements_text_box void Canvas*, uint8_t, uint8_t, uint8_t, uint8_t, Align, Align, const char*, _Bool
788 Function + elf_resolve_from_hashtable _Bool const ElfApiInterface*, const char*, Elf32_Addr*
789 Function + empty_screen_alloc EmptyScreen*
790 Function + empty_screen_free void EmptyScreen*
791 Function + empty_screen_get_view View* EmptyScreen*
870 Function + file_browser_worker_set_item_callback void BrowserWorker*, BrowserWorkerListItemCallback
871 Function + file_browser_worker_set_list_callback void BrowserWorker*, BrowserWorkerListLoadCallback
872 Function + file_browser_worker_set_long_load_callback void BrowserWorker*, BrowserWorkerLongLoadCallback
873 Function + file_info_is_dir _Bool const FileInfo*
874 Function + file_stream_alloc Stream* Storage*
875 Function + file_stream_close _Bool Stream*
876 Function + file_stream_get_error FS_Error Stream*
886 Function + flipper_application_alloc FlipperApplication* Storage*, const ElfApiInterface*
887 Function + flipper_application_free void FlipperApplication*
888 Function + flipper_application_get_manifest const FlipperApplicationManifest* FlipperApplication*
889 Function + flipper_application_is_plugin _Bool FlipperApplication*
890 Function + flipper_application_load_status_to_string const char* FlipperApplicationLoadStatus
891 Function + flipper_application_manifest_is_compatible _Bool const FlipperApplicationManifest*, const ElfApiInterface*
892 Function + flipper_application_manifest_is_target_compatible _Bool const FlipperApplicationManifest*
893 Function + flipper_application_manifest_is_valid _Bool const FlipperApplicationManifest*
894 Function + flipper_application_map_to_memory FlipperApplicationLoadStatus FlipperApplication*
895 Function + flipper_application_plugin_get_descriptor const FlipperAppPluginDescriptor* FlipperApplication*
896 Function + flipper_application_preload FlipperApplicationPreloadStatus FlipperApplication*, const char*
897 Function + flipper_application_preload_manifest FlipperApplicationPreloadStatus FlipperApplication*, const char*
898 Function - + flipper_application_preload_status_to_string const char* FlipperApplicationPreloadStatus
899 Function + flipper_application_spawn FuriThread* FlipperApplication*, void*
900 Function + flipper_format_buffered_file_alloc FlipperFormat* Storage*
901 Function + flipper_format_buffered_file_close _Bool FlipperFormat*
902 Function + flipper_format_buffered_file_open_always _Bool FlipperFormat*, const char*
903 Function + flipper_format_buffered_file_open_existing _Bool FlipperFormat*, const char*
904 Function + flipper_format_delete_key _Bool FlipperFormat*, const char*
905 Function + flipper_format_file_alloc FlipperFormat* Storage*
1062 Function + furi_hal_cdc_receive int32_t uint8_t, uint8_t*, uint16_t
1063 Function + furi_hal_cdc_send void uint8_t, uint8_t*, uint16_t
1064 Function + furi_hal_cdc_set_callbacks void uint8_t, CdcCallbacks*, void*
1065 Function + - furi_hal_clock_deinit_early void
1066 Function - furi_hal_clock_init void
1067 Function - furi_hal_clock_init_early void
1068 Function + furi_hal_clock_mco_disable void
1071 Function - furi_hal_clock_suspend_tick void
1072 Function - furi_hal_clock_switch_to_hsi void
1073 Function - furi_hal_clock_switch_to_pll void
Function - furi_hal_compress_alloc FuriHalCompress* uint16_t
Function - furi_hal_compress_decode _Bool FuriHalCompress*, uint8_t*, size_t, uint8_t*, size_t, size_t*
Function - furi_hal_compress_encode _Bool FuriHalCompress*, uint8_t*, size_t, uint8_t*, size_t, size_t*
Function - furi_hal_compress_free void FuriHalCompress*
Function - furi_hal_compress_icon_decode void const uint8_t*, uint8_t**
Function - furi_hal_compress_icon_init void
1074 Function + furi_hal_console_disable void
1075 Function + furi_hal_console_enable void
1076 Function + furi_hal_console_init void
1137 Function + furi_hal_hid_u2f_send_response void uint8_t*, uint8_t
1138 Function + furi_hal_hid_u2f_set_callback void HidU2fCallback, void*
1139 Function + furi_hal_i2c_acquire void FuriHalI2cBusHandle*
1140 Function + - furi_hal_i2c_deinit_early void
1141 Function - furi_hal_i2c_init void
1142 Function - furi_hal_i2c_init_early void
1143 Function + furi_hal_i2c_is_device_ready _Bool FuriHalI2cBusHandle*, uint8_t, uint32_t
1151 Function + furi_hal_i2c_write_mem _Bool FuriHalI2cBusHandle*, uint8_t, uint8_t, uint8_t*, uint8_t, uint32_t
1152 Function + furi_hal_i2c_write_reg_16 _Bool FuriHalI2cBusHandle*, uint8_t, uint8_t, uint16_t, uint32_t
1153 Function + furi_hal_i2c_write_reg_8 _Bool FuriHalI2cBusHandle*, uint8_t, uint8_t, uint8_t, uint32_t
Function + furi_hal_ibutton_add_interrupt void GpioExtiCallback, void*
1154 Function + furi_hal_ibutton_emulate_set_next void uint32_t
1155 Function + furi_hal_ibutton_emulate_start void uint32_t, FuriHalIbuttonEmulateCallback, void*
1156 Function + furi_hal_ibutton_emulate_stop void
1157 Function - furi_hal_ibutton_init void
1158 Function + furi_hal_ibutton_pin_get_level furi_hal_ibutton_pin_configure _Bool void
1159 Function + furi_hal_ibutton_pin_high furi_hal_ibutton_pin_reset void
1160 Function + furi_hal_ibutton_pin_low furi_hal_ibutton_pin_write void const _Bool
Function + furi_hal_ibutton_remove_interrupt void
Function + furi_hal_ibutton_start_drive void
Function + furi_hal_ibutton_start_drive_in_isr void
Function + furi_hal_ibutton_start_interrupt void
Function + furi_hal_ibutton_start_interrupt_in_isr void
Function + furi_hal_ibutton_stop void
1161 Function + furi_hal_info_get void PropertyValueCallback, char, void*
1162 Function + furi_hal_infrared_async_rx_set_capture_isr_callback void FuriHalInfraredRxCaptureCallback, void*
1163 Function + furi_hal_infrared_async_rx_set_timeout void uint32_t
1192 Function + furi_hal_mpu_protect_no_access void FuriHalMpuRegion, uint32_t, FuriHalMPURegionSize
1193 Function + furi_hal_mpu_protect_read_only void FuriHalMpuRegion, uint32_t, FuriHalMPURegionSize
1194 Function + furi_hal_nfc_activate_nfca _Bool uint32_t, uint32_t*
1195 Function - furi_hal_nfc_deinit void
1196 Function + furi_hal_nfc_detect _Bool FuriHalNfcDevData*, uint32_t
1197 Function + furi_hal_nfc_emulate_nfca _Bool uint8_t*, uint8_t, uint8_t*, uint8_t, FuriHalNfcEmulateCallback, void*, uint32_t
1198 Function + furi_hal_nfc_exit_sleep void
1232 Function + furi_hal_power_enable_otg void
1233 Function + furi_hal_power_gauge_is_ok _Bool
1234 Function + furi_hal_power_get_bat_health_pct uint8_t
1235 Function + furi_hal_power_get_battery_charging_voltage furi_hal_power_get_battery_charge_voltage_limit float
1236 Function + furi_hal_power_get_battery_current float FuriHalPowerIC
1237 Function + furi_hal_power_get_battery_design_capacity uint32_t
1238 Function + furi_hal_power_get_battery_full_capacity uint32_t
1251 Function + furi_hal_power_is_otg_enabled _Bool
1252 Function + furi_hal_power_off void
1253 Function + furi_hal_power_reset void
1254 Function + furi_hal_power_set_battery_charging_voltage furi_hal_power_set_battery_charge_voltage_limit void float
1255 Function + furi_hal_power_shutdown void
1256 Function + furi_hal_power_sleep void
1257 Function + furi_hal_power_sleep_available _Bool
1269 Function + furi_hal_region_is_frequency_allowed _Bool uint32_t
1270 Function + furi_hal_region_is_provisioned _Bool
1271 Function + furi_hal_region_set void FuriHalRegion*
1272 Function + - furi_hal_resources_deinit_early void
1273 Function + furi_hal_resources_get_ext_pin_number int32_t const GpioPin*
1274 Function - furi_hal_resources_init void
1275 Function - furi_hal_resources_init_early void
1276 Function + furi_hal_rfid_change_read_config void float, float
1299 Function + furi_hal_rfid_tim_read_stop void
1300 Function + furi_hal_rfid_tim_reset void
1301 Function + furi_hal_rtc_datetime_to_timestamp uint32_t FuriHalRtcDateTime*
1302 Function + - furi_hal_rtc_deinit_early void
1303 Function + furi_hal_rtc_get_boot_mode FuriHalRtcBootMode
1304 Function + furi_hal_rtc_get_datetime void FuriHalRtcDateTime*
1305 Function + furi_hal_rtc_get_fault_data uint32_t
1341 Function + furi_hal_spi_bus_handle_init void FuriHalSpiBusHandle*
1342 Function + furi_hal_spi_bus_init void FuriHalSpiBus*
1343 Function + furi_hal_spi_bus_rx _Bool FuriHalSpiBusHandle*, uint8_t*, size_t, uint32_t
1344 Function + furi_hal_spi_bus_trx _Bool FuriHalSpiBusHandle*, uint8_t*, uint8_t*, size_t, uint32_t FuriHalSpiBusHandle*, const uint8_t*, uint8_t*, size_t, uint32_t
1345 Function + furi_hal_spi_bus_tx furi_hal_spi_bus_trx_dma _Bool FuriHalSpiBusHandle*, uint8_t*, size_t, uint32_t FuriHalSpiBusHandle*, uint8_t*, uint8_t*, size_t, uint32_t
1346 Function + furi_hal_spi_deinit_early furi_hal_spi_bus_tx void _Bool FuriHalSpiBusHandle*, const uint8_t*, size_t, uint32_t
1347 Function - furi_hal_spi_init furi_hal_spi_config_deinit_early void
1348 Function + - furi_hal_spi_init_early furi_hal_spi_config_init void
1349 Function - furi_hal_spi_config_init_early void
1350 Function - furi_hal_spi_dma_init void
1351 Function + furi_hal_spi_release void FuriHalSpiBusHandle*
1352 Function - furi_hal_subghz_dump_state void
1353 Function + furi_hal_subghz_flush_rx void
1401 Function + furi_hal_version_get_ble_local_device_name_ptr const char*
1402 Function + furi_hal_version_get_ble_mac const uint8_t*
1403 Function + furi_hal_version_get_device_name_ptr const char*
1404 Function + furi_hal_version_get_fcc_id const char*
1405 Function + furi_hal_version_get_firmware_version const Version*
1406 Function + furi_hal_version_get_hw_body uint8_t
1407 Function + furi_hal_version_get_hw_color FuriHalVersionColor
1412 Function + furi_hal_version_get_hw_target uint8_t
1413 Function + furi_hal_version_get_hw_timestamp uint32_t
1414 Function + furi_hal_version_get_hw_version uint8_t
1415 Function + furi_hal_version_get_ic_id const char*
1416 Function + furi_hal_version_get_model_code const char*
1417 Function + furi_hal_version_get_model_name const char*
1418 Function + furi_hal_version_get_name_ptr const char*
1419 Function + furi_hal_version_get_otp_version FuriHalVersionOtpVersion
1431 Function + furi_log_get_level FuriLogLevel
1432 Function - furi_log_init void
1433 Function + furi_log_print_format void FuriLogLevel, const char*, const char*, ...
1434 Function + furi_log_print_raw_format void FuriLogLevel, const char*, ...
1435 Function + furi_log_set_level void FuriLogLevel
1436 Function - furi_log_set_puts void FuriLogPuts
1437 Function - furi_log_set_timestamp void FuriLogTimestamp
1542 Function + furi_thread_flags_set uint32_t FuriThreadId, uint32_t
1543 Function + furi_thread_flags_wait uint32_t uint32_t, uint32_t, uint32_t
1544 Function + furi_thread_free void FuriThread*
1545 Function + furi_thread_get_appid const char* FuriThreadId
1546 Function + furi_thread_get_current FuriThread*
1547 Function + furi_thread_get_current_id FuriThreadId
1548 Function + furi_thread_get_current_priority FuriThreadPriority
1549 Function + furi_thread_get_heap_size size_t FuriThread*
1550 Function + furi_thread_get_id FuriThreadId FuriThread*
1551 Function + furi_thread_get_name const char* FuriThreadId
1557 Function + furi_thread_join _Bool FuriThread*
1558 Function + furi_thread_mark_as_service void FuriThread*
1559 Function + furi_thread_resume void FuriThreadId
1560 Function + furi_thread_set_appid void FuriThread*, const char*
1561 Function + furi_thread_set_callback void FuriThread*, FuriThreadCallback
1562 Function + furi_thread_set_context void FuriThread*, void*
1563 Function + furi_thread_set_current_priority void FuriThreadPriority
1564 Function + furi_thread_set_name void FuriThread*, const char*
1565 Function + furi_thread_set_priority void FuriThread*, FuriThreadPriority
1566 Function + furi_thread_set_stack_size void FuriThread*, size_t
1602 Function + gui_add_view_port void Gui*, ViewPort*, GuiLayer
1603 Function + gui_direct_draw_acquire Canvas* Gui*
1604 Function + gui_direct_draw_release void Gui*
1605 Function + gui_get_framebuffer_size size_t Gui* const Gui*
1606 Function + gui_remove_framebuffer_callback void Gui*, GuiCanvasCommitCallback, void*
1607 Function + gui_remove_view_port void Gui*, ViewPort*
1608 Function + gui_set_lockdown void Gui*, _Bool
1611 Function + hal_sd_detect _Bool
1612 Function + hal_sd_detect_init void
1613 Function + hal_sd_detect_set_low void
Function + hmac_sha256_finish void const hmac_sha256_context*, const uint8_t*, uint8_t*
Function + hmac_sha256_init void hmac_sha256_context*, const uint8_t*
Function + hmac_sha256_update void const hmac_sha256_context*, const uint8_t*, unsigned
1614 Function - hypot double double, double
1615 Function - hypotf float float, float
1616 Function - hypotl long double long double, long double
1617 Function + ibutton_key_alloc iButtonKey* size_t
Function + ibutton_key_clear_data void iButtonKey*
Function + ibutton_key_dallas_crc_is_valid _Bool iButtonKey*
Function + ibutton_key_dallas_is_1990_key _Bool iButtonKey*
1618 Function + ibutton_key_free void iButtonKey*
1619 Function + ibutton_key_get_data_p ibutton_key_get_protocol_id const uint8_t* iButtonProtocolId iButtonKey* const iButtonKey*
1620 Function + ibutton_key_get_data_size ibutton_key_reset uint8_t void iButtonKey*
1621 Function + ibutton_key_get_max_size ibutton_key_set_protocol_id uint8_t void iButtonKey*, iButtonProtocolId
1622 Function + ibutton_key_get_size_by_type ibutton_protocols_alloc uint8_t iButtonProtocols* iButtonKeyType
1623 Function + ibutton_key_get_string_by_type ibutton_protocols_apply_edits const char* void iButtonKeyType iButtonProtocols*, const iButtonKey*
1624 Function + ibutton_key_get_type ibutton_protocols_emulate_start iButtonKeyType void iButtonKey* iButtonProtocols*, iButtonKey*
1625 Function + ibutton_key_get_type_by_string ibutton_protocols_emulate_stop _Bool void const char*, iButtonKeyType* iButtonProtocols*, iButtonKey*
1626 Function + ibutton_key_set ibutton_protocols_free void iButtonKey*, const iButtonKey* iButtonProtocols*
1627 Function + ibutton_key_set_data ibutton_protocols_get_editable_data void iButtonKey*, uint8_t*, uint8_t iButtonProtocols*, const iButtonKey*, iButtonEditableData*
1628 Function + ibutton_key_set_type ibutton_protocols_get_features void uint32_t iButtonKey*, iButtonKeyType iButtonProtocols*, iButtonProtocolId
1629 Function + ibutton_worker_alloc ibutton_protocols_get_id_by_name iButtonWorker* iButtonProtocolId iButtonProtocols*, const char*
1630 Function + ibutton_protocols_get_manufacturer const char* iButtonProtocols*, iButtonProtocolId
1631 Function + ibutton_protocols_get_max_data_size size_t iButtonProtocols*
1632 Function + ibutton_protocols_get_name const char* iButtonProtocols*, iButtonProtocolId
1633 Function + ibutton_protocols_get_protocol_count uint32_t
1634 Function + ibutton_protocols_is_valid _Bool iButtonProtocols*, const iButtonKey*
1635 Function + ibutton_protocols_load _Bool iButtonProtocols*, iButtonKey*, const char*
1636 Function + ibutton_protocols_read _Bool iButtonProtocols*, iButtonKey*
1637 Function + ibutton_protocols_render_brief_data void iButtonProtocols*, const iButtonKey*, FuriString*
1638 Function + ibutton_protocols_render_data void iButtonProtocols*, const iButtonKey*, FuriString*
1639 Function + ibutton_protocols_render_error void iButtonProtocols*, const iButtonKey*, FuriString*
1640 Function + ibutton_protocols_save _Bool iButtonProtocols*, const iButtonKey*, const char*
1641 Function + ibutton_protocols_write_blank _Bool iButtonProtocols*, iButtonKey*
1642 Function + ibutton_protocols_write_copy _Bool iButtonProtocols*, iButtonKey*
1643 Function + ibutton_worker_alloc iButtonWorker* iButtonProtocols*
1644 Function + ibutton_worker_emulate_set_callback void iButtonWorker*, iButtonWorkerEmulateCallback, void*
1645 Function + ibutton_worker_emulate_start void iButtonWorker*, iButtonKey*
1646 Function + ibutton_worker_free void iButtonWorker*
1649 Function + ibutton_worker_start_thread void iButtonWorker*
1650 Function + ibutton_worker_stop void iButtonWorker*
1651 Function + ibutton_worker_stop_thread void iButtonWorker*
1652 Function + ibutton_worker_write_blank_start void iButtonWorker*, iButtonKey*
1653 Function + ibutton_worker_write_copy_start void iButtonWorker*, iButtonKey*
1654 Function + ibutton_worker_write_set_callback void iButtonWorker*, iButtonWorkerWriteCallback, void*
Function + ibutton_worker_write_start void iButtonWorker*, iButtonKey*
1655 Function + icon_animation_alloc IconAnimation* const Icon*
1656 Function + icon_animation_free void IconAnimation*
1657 Function + icon_animation_get_height uint8_t IconAnimation* const IconAnimation*
1658 Function + icon_animation_get_width uint8_t IconAnimation* const IconAnimation*
1659 Function + icon_animation_is_last_frame _Bool IconAnimation* const IconAnimation*
1660 Function + icon_animation_set_update_callback void IconAnimation*, IconAnimationCallback, void*
1661 Function + icon_animation_start void IconAnimation*
1662 Function + icon_animation_stop void IconAnimation*
1706 Function + infrared_worker_tx_set_signal_sent_callback void InfraredWorker*, InfraredWorkerMessageSentCallback, void*
1707 Function + infrared_worker_tx_start void InfraredWorker*
1708 Function + infrared_worker_tx_stop void InfraredWorker*
Function + init_mutex _Bool ValueMutex*, void*, size_t
1709 Function - initstate char* unsigned, char*, size_t
1710 Function + input_get_key_name const char* InputKey
1711 Function + input_get_type_name const char* InputType
1795 Function - llroundf long long int float
1796 Function - llroundl long long int long double
1797 Function + loader_get_pubsub FuriPubSub* Loader*
1798 Function + loader_is_locked _Bool Loader* const Loader*
1799 Function + loader_lock _Bool Loader*
1800 Function + loader_show_menu void
1801 Function + loader_start LoaderStatus Loader*, const char*, const char*
1908 Function + menu_get_view View* Menu*
1909 Function + menu_reset void Menu*
1910 Function + menu_set_selected_item void Menu*, uint32_t
1911 Function - mf_classic_auth_attempt _Bool FuriHalNfcTxRxContext*, MfClassicAuthContext*, uint64_t FuriHalNfcTxRxContext*, Crypto1*, MfClassicAuthContext*, uint64_t
1912 Function - mf_classic_auth_init_context void MfClassicAuthContext*, uint8_t
1913 Function - mf_classic_auth_write_block _Bool FuriHalNfcTxRxContext*, MfClassicBlock*, uint8_t, MfClassicKey, uint64_t
1914 Function - mf_classic_authenticate _Bool FuriHalNfcTxRxContext*, uint8_t, uint64_t, MfClassicKey
1915 Function - mf_classic_authenticate_skip_activate _Bool FuriHalNfcTxRxContext*, uint8_t, uint64_t, MfClassicKey, _Bool, uint32_t
1916 Function - mf_classic_block_to_value _Bool const uint8_t*, int32_t*, uint8_t*
1917 Function - mf_classic_check_card_type _Bool FuriHalNfcADevData*
1918 Function - mf_classic_dict_add_key _Bool MfClassicDict*, uint8_t*
1919 Function - mf_classic_dict_add_key_str _Bool MfClassicDict*, FuriString*
1940 Function - mf_classic_get_total_block_num uint16_t MfClassicType
1941 Function - mf_classic_get_total_sectors_num uint8_t MfClassicType
1942 Function - mf_classic_get_type_str const char* MfClassicType
1943 Function - mf_classic_halt void FuriHalNfcTxRxContext*, Crypto1*
1944 Function - mf_classic_is_allowed_access_data_block _Bool MfClassicData*, uint8_t, MfClassicKey, MfClassicAction
1945 Function - mf_classic_is_allowed_access_sector_trailer _Bool MfClassicData*, uint8_t, MfClassicKey, MfClassicAction
1946 Function - mf_classic_is_block_read _Bool MfClassicData*, uint8_t
1949 Function - mf_classic_is_sector_data_read _Bool MfClassicData*, uint8_t
1950 Function - mf_classic_is_sector_read _Bool MfClassicData*, uint8_t
1951 Function - mf_classic_is_sector_trailer _Bool uint8_t
1952 Function - mf_classic_is_value_block _Bool MfClassicData*, uint8_t
1953 Function - mf_classic_read_block _Bool FuriHalNfcTxRxContext*, Crypto1*, uint8_t, MfClassicBlock*
1954 Function - mf_classic_read_card uint8_t FuriHalNfcTxRxContext*, MfClassicReader*, MfClassicData*
1955 Function - mf_classic_read_sector void FuriHalNfcTxRxContext*, MfClassicData*, uint8_t
1956 Function - mf_classic_reader_add_sector void MfClassicReader*, uint8_t, uint64_t, uint64_t
1958 Function - mf_classic_set_key_found void MfClassicData*, uint8_t, MfClassicKey, uint64_t
1959 Function - mf_classic_set_key_not_found void MfClassicData*, uint8_t, MfClassicKey
1960 Function - mf_classic_set_sector_data_not_read void MfClassicData*
1961 Function - mf_classic_transfer _Bool FuriHalNfcTxRxContext*, Crypto1*, uint8_t
1962 Function - mf_classic_update_card uint8_t FuriHalNfcTxRxContext*, MfClassicData*
1963 Function - mf_classic_write_block mf_classic_value_cmd _Bool FuriHalNfcTxRxContext*, MfClassicBlock*, uint8_t, MfClassicKey, uint64_t FuriHalNfcTxRxContext*, Crypto1*, uint8_t, uint8_t, int32_t
1964 Function - mf_classic_value_cmd_full _Bool FuriHalNfcTxRxContext*, MfClassicBlock*, uint8_t, MfClassicKey, uint64_t, int32_t
1965 Function - mf_classic_value_to_block void int32_t, uint8_t, uint8_t*
1966 Function - mf_classic_write_block _Bool FuriHalNfcTxRxContext*, Crypto1*, uint8_t, MfClassicBlock*
1967 Function - mf_classic_write_sector _Bool FuriHalNfcTxRxContext*, MfClassicData*, MfClassicData*, uint8_t
1968 Function - mf_df_cat_application void MifareDesfireApplication*, FuriString*
1969 Function - mf_df_cat_application_info void MifareDesfireApplication*, FuriString*
2062 Function + notification_message_block void NotificationApp*, const NotificationSequence*
2063 Function - nrand48 long unsigned short[3]
2064 Function - on_exit int void (*)(int, void*), void*
2065 Function + onewire_device_alloc onewire_host_alloc OneWireDevice* OneWireHost* uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t const GpioPin*
Function + onewire_device_attach void OneWireDevice*, OneWireSlave*
Function + onewire_device_detach void OneWireDevice*
Function + onewire_device_free void OneWireDevice*
Function + onewire_device_get_id_p uint8_t* OneWireDevice*
Function + onewire_device_send_id void OneWireDevice*
Function + onewire_host_alloc OneWireHost*
2066 Function + onewire_host_free void OneWireHost*
2067 Function + onewire_host_read uint8_t OneWireHost*
2068 Function + onewire_host_read_bit _Bool OneWireHost*
2069 Function + onewire_host_read_bytes void OneWireHost*, uint8_t*, uint16_t
2070 Function + onewire_host_reset _Bool OneWireHost*
2071 Function + onewire_host_reset_search void OneWireHost*
2072 Function + onewire_host_search uint8_t _Bool OneWireHost*, uint8_t*, OneWireHostSearchMode
2073 Function + onewire_host_skip onewire_host_set_overdrive void OneWireHost* OneWireHost*, _Bool
2074 Function + onewire_host_start void OneWireHost*
2075 Function + onewire_host_stop void OneWireHost*
2076 Function + onewire_host_target_search void OneWireHost*, uint8_t
2077 Function + onewire_host_write void OneWireHost*, uint8_t
2078 Function + onewire_host_write_bit void OneWireHost*, _Bool
2079 Function + onewire_slave_alloc onewire_host_write_bytes OneWireSlave* void OneWireHost*, const uint8_t*, uint16_t
2080 Function + onewire_slave_attach onewire_slave_alloc void OneWireSlave* OneWireSlave*, OneWireDevice* const GpioPin*
Function + onewire_slave_detach void OneWireSlave*
2081 Function + onewire_slave_free void OneWireSlave*
2082 Function + onewire_slave_receive _Bool OneWireSlave*, uint8_t*, size_t
2083 Function + onewire_slave_receive_bit _Bool OneWireSlave*
2084 Function + onewire_slave_send _Bool OneWireSlave*, const uint8_t*, size_t
2085 Function + onewire_slave_send_bit _Bool OneWireSlave*, _Bool
2086 Function + onewire_slave_set_command_callback void OneWireSlave*, OneWireSlaveCommandCallback, void*
2087 Function + onewire_slave_set_overdrive void OneWireSlave*, _Bool
2088 Function + onewire_slave_set_reset_callback void OneWireSlave*, OneWireSlaveResetCallback, void*
2089 Function + onewire_slave_set_result_callback void OneWireSlave*, OneWireSlaveResultCallback, void*
2090 Function + onewire_slave_start void OneWireSlave*
2091 Function + onewire_slave_stop void OneWireSlave*
2108 Function - platformSetIrqCallback void PlatformIrqCallback
2109 Function - platformSpiTxRx _Bool const uint8_t*, uint8_t*, uint16_t
2110 Function - platformUnprotectST25RComm void
2111 Function + plugin_manager_alloc PluginManager* const char*, uint32_t, const ElfApiInterface*
2112 Function + plugin_manager_free void PluginManager*
2113 Function + plugin_manager_get const FlipperAppPluginDescriptor* PluginManager*, uint32_t
2114 Function + plugin_manager_get_count uint32_t PluginManager*
2115 Function + plugin_manager_get_ep const void* PluginManager*, uint32_t
2116 Function + plugin_manager_load_all PluginManagerError PluginManager*, const char*
2117 Function + plugin_manager_load_single PluginManagerError PluginManager*, const char*
2118 Function - popen FILE* const char*, const char*
2119 Function + popup_alloc Popup*
2120 Function + popup_disable_timeout void Popup*
2140 Function + power_reboot void PowerBootMode
2141 Function + powf float float, float
2142 Function - powl long double long double, long double
2143 Function + pretty_format_bytes_hex_canonical void FuriString*, size_t, const char*, const uint8_t*, size_t
2144 Function - printf int const char*, ...
2145 Function - prng_successor uint32_t uint32_t, uint32_t
2146 Function + property_value_out void PropertyValueContext*, const char*, unsigned int, ...
2185 Function - rand_r int unsigned*
2186 Function + random long
2187 Function - rawmemchr void* const void*, int
Function - read_mutex _Bool ValueMutex*, void*, size_t, uint32_t
2188 Function + realloc void* void*, size_t
2189 Function - reallocarray void* void*, size_t, size_t
2190 Function - reallocf void* void*, size_t
2191 Function - realpath char* const char*, char*
Function + release_mutex _Bool ValueMutex*, const void*
2192 Function - remainder double double, double
2193 Function - remainderf float float, float
2194 Function - remainderl long double long double, long double
2410 Function - scanf int const char*, ...
2411 Function + scene_manager_alloc SceneManager* const SceneManagerHandlers*, void*
2412 Function + scene_manager_free void SceneManager*
2413 Function + scene_manager_get_scene_state uint32_t SceneManager*, uint32_t const SceneManager*, uint32_t
2414 Function + scene_manager_handle_back_event _Bool SceneManager*
2415 Function + scene_manager_handle_custom_event _Bool SceneManager*, uint32_t
2416 Function + scene_manager_handle_tick_event void SceneManager*
2417 Function + scene_manager_has_previous_scene _Bool SceneManager*, uint32_t const SceneManager*, uint32_t
2418 Function + scene_manager_next_scene void SceneManager*, uint32_t
2419 Function + scene_manager_previous_scene _Bool SceneManager*
2420 Function + scene_manager_search_and_switch_to_another_scene _Bool SceneManager*, uint32_t
2467 Function - srandom void unsigned
2468 Function + sscanf int const char*, const char*, ...
2469 Function + storage_common_copy FS_Error Storage*, const char*, const char*
2470 Function + storage_common_exists _Bool Storage*, const char*
2471 Function + storage_common_fs_info FS_Error Storage*, const char*, uint64_t*, uint64_t*
2472 Function + storage_common_merge FS_Error Storage*, const char*, const char*
2473 Function + storage_common_migrate FS_Error Storage*, const char*, const char*
2474 Function + storage_common_mkdir FS_Error Storage*, const char*
2475 Function + storage_common_remove FS_Error Storage*, const char*
2476 Function + storage_common_rename FS_Error Storage*, const char*, const char*
2477 Function + storage_common_resolve_path_and_ensure_app_directory void Storage*, FuriString*
2478 Function + storage_common_stat FS_Error Storage*, const char*, FileInfo*
2479 Function + storage_common_timestamp FS_Error Storage*, const char*, uint32_t*
2480 Function + storage_dir_close _Bool File*
2481 Function + storage_dir_exists _Bool Storage*, const char*
2482 Function + storage_dir_open _Bool File*, const char*
2483 Function + storage_dir_read _Bool File*, FileInfo*, char*, uint16_t
2484 Function - storage_dir_rewind _Bool File*
2485 Function + storage_error_get_desc const char* FS_Error
2486 Function + storage_file_alloc File* Storage*
2487 Function + storage_file_close _Bool File*
2488 Function + storage_file_copy_to_file _Bool File*, File*, uint32_t
2489 Function + storage_file_eof _Bool File*
2490 Function + storage_file_exists _Bool Storage*, const char*
2491 Function + storage_file_free void File*
2608 Function - strverscmp int const char*, const char*
2609 Function - strxfrm size_t char*, const char*, size_t
2610 Function - strxfrm_l size_t char*, const char*, size_t, locale_t
2611 Function + subghz_block_generic_deserialize _Bool SubGhzProtocolStatus SubGhzBlockGeneric*, FlipperFormat*
2612 Function + subghz_block_generic_deserialize_check_count_bit SubGhzProtocolStatus SubGhzBlockGeneric*, FlipperFormat*, uint16_t
2613 Function + subghz_block_generic_get_preset_name void const char*, FuriString*
2614 Function + subghz_block_generic_serialize _Bool SubGhzProtocolStatus SubGhzBlockGeneric*, FlipperFormat*, SubGhzRadioPreset*
2615 Function + subghz_environment_alloc SubGhzEnvironment*
2616 Function + subghz_environment_free void SubGhzEnvironment*
2617 Function + subghz_environment_get_alutech_at_4n_rainbow_table_file_name const char* SubGhzEnvironment*
2618 Function + subghz_environment_get_came_atomo_rainbow_table_file_name const char* SubGhzEnvironment*
2619 Function + subghz_environment_get_keystore SubGhzKeystore* SubGhzEnvironment*
2620 Function + subghz_environment_get_nice_flor_s_rainbow_table_file_name const char* SubGhzEnvironment*
2621 Function + subghz_environment_get_protocol_name_registry const char* SubGhzEnvironment*, size_t
2622 Function + subghz_environment_get_protocol_registry void* SubGhzEnvironment*
2623 Function + subghz_environment_load_keystore _Bool SubGhzEnvironment*, const char*
2624 Function + subghz_environment_set_alutech_at_4n_rainbow_table_file_name void SubGhzEnvironment*, const char*
2625 Function + subghz_environment_set_came_atomo_rainbow_table_file_name void SubGhzEnvironment*, const char*
2626 Function + subghz_environment_set_nice_flor_s_rainbow_table_file_name void SubGhzEnvironment*, const char*
2627 Function + subghz_environment_set_protocol_registry void SubGhzEnvironment*, void*
2644 Function + subghz_protocol_blocks_get_bit_array _Bool uint8_t[], size_t
2645 Function + subghz_protocol_blocks_get_hash_data uint8_t SubGhzBlockDecoder*, size_t
2646 Function + subghz_protocol_blocks_get_parity uint8_t uint64_t, uint8_t
2647 Function + subghz_protocol_blocks_get_upload subghz_protocol_blocks_get_upload_from_bit_array size_t uint8_t[], size_t, LevelDuration*, size_t, uint32_t uint8_t[], size_t, LevelDuration*, size_t, uint32_t, SubGhzProtocolBlockAlignBit
2648 Function + subghz_protocol_blocks_lfsr_digest16 uint16_t const uint8_t[], size_t, uint16_t, uint16_t
2649 Function + subghz_protocol_blocks_lfsr_digest8 uint8_t const uint8_t[], size_t, uint8_t, uint8_t
2650 Function + subghz_protocol_blocks_lfsr_digest8_reflect uint8_t const uint8_t[], size_t, uint8_t, uint8_t
2653 Function + subghz_protocol_blocks_reverse_key uint64_t uint64_t, uint8_t
2654 Function + subghz_protocol_blocks_set_bit_array void _Bool, uint8_t[], size_t, size_t
2655 Function + subghz_protocol_blocks_xor_bytes uint8_t const uint8_t[], size_t
2656 Function - + subghz_protocol_decoder_base_deserialize _Bool SubGhzProtocolStatus SubGhzProtocolDecoderBase*, FlipperFormat*
2657 Function + subghz_protocol_decoder_base_get_hash_data uint8_t SubGhzProtocolDecoderBase*
2658 Function + subghz_protocol_decoder_base_get_string _Bool SubGhzProtocolDecoderBase*, FuriString*
2659 Function + subghz_protocol_decoder_base_serialize _Bool SubGhzProtocolStatus SubGhzProtocolDecoderBase*, FlipperFormat*, SubGhzRadioPreset*
2660 Function - subghz_protocol_decoder_base_set_decoder_callback void SubGhzProtocolDecoderBase*, SubGhzProtocolDecoderBaseRxCallback, void*
2661 Function + subghz_protocol_decoder_raw_alloc void* SubGhzEnvironment*
2662 Function + subghz_protocol_decoder_raw_deserialize _Bool SubGhzProtocolStatus void*, FlipperFormat*
2663 Function + subghz_protocol_decoder_raw_feed void void*, _Bool, uint32_t
2664 Function + subghz_protocol_decoder_raw_free void void*
2665 Function + subghz_protocol_decoder_raw_get_string void void*, FuriString*
2666 Function + subghz_protocol_decoder_raw_reset void void*
2667 Function + subghz_protocol_encoder_raw_alloc void* SubGhzEnvironment*
2668 Function + subghz_protocol_encoder_raw_deserialize _Bool SubGhzProtocolStatus void*, FlipperFormat*
2669 Function + subghz_protocol_encoder_raw_free void void*
2670 Function + subghz_protocol_encoder_raw_stop void void*
2671 Function + subghz_protocol_encoder_raw_yield LevelDuration void*
2703 Function + subghz_setting_load void SubGhzSetting*, const char*
2704 Function + subghz_setting_load_custom_preset _Bool SubGhzSetting*, const char*, FlipperFormat*
2705 Function + subghz_transmitter_alloc_init SubGhzTransmitter* SubGhzEnvironment*, const char*
2706 Function + subghz_transmitter_deserialize _Bool SubGhzProtocolStatus SubGhzTransmitter*, FlipperFormat*
2707 Function + subghz_transmitter_free void SubGhzTransmitter*
2708 Function + subghz_transmitter_get_protocol_instance SubGhzProtocolEncoderBase* SubGhzTransmitter*
2709 Function + subghz_transmitter_stop _Bool SubGhzTransmitter*
2722 Function + subghz_worker_is_running _Bool SubGhzWorker*
2723 Function + subghz_worker_rx_callback void _Bool, uint32_t, void*
2724 Function + subghz_worker_set_context void SubGhzWorker*, void*
2725 Function + subghz_worker_set_filter void SubGhzWorker*, uint16_t
2726 Function + subghz_worker_set_overrun_callback void SubGhzWorker*, SubGhzWorkerOverrunCallback
2727 Function + subghz_worker_set_pair_callback void SubGhzWorker*, SubGhzWorkerPairCallback
2728 Function + subghz_worker_start void SubGhzWorker*
2939 Function + view_port_draw_callback_set void ViewPort*, ViewPortDrawCallback, void*
2940 Function + view_port_enabled_set void ViewPort*, _Bool
2941 Function + view_port_free void ViewPort*
2942 Function + view_port_get_height uint8_t ViewPort* const ViewPort*
2943 Function + view_port_get_orientation ViewPortOrientation const ViewPort*
2944 Function + view_port_get_width uint8_t ViewPort* const ViewPort*
2945 Function + view_port_input_callback_set void ViewPort*, ViewPortInputCallback, void*
2946 Function + view_port_is_enabled _Bool ViewPort* const ViewPort*
2947 Function + view_port_set_height void ViewPort*, uint8_t
2948 Function + view_port_set_orientation void ViewPort*, ViewPortOrientation
2949 Function + view_port_set_width void ViewPort*, uint8_t
2987 Function + widget_free void Widget*
2988 Function + widget_get_view View* Widget*
2989 Function + widget_reset void Widget*
Function - write_mutex _Bool ValueMutex*, void*, size_t, uint32_t
2990 Function - xPortGetFreeHeapSize size_t
2991 Function - xPortGetMinimumEverFreeHeapSize size_t
2992 Function - xPortStartScheduler BaseType_t
3045 Variable - _timezone long
3046 Variable - _tzname char*[2]
3047 Variable + cli_vcp CliSession
3048 Variable + firmware_api_interface const ElfApiInterface*
3049 Variable + furi_hal_i2c_bus_external FuriHalI2cBus
3050 Variable + furi_hal_i2c_bus_power FuriHalI2cBus
3051 Variable + furi_hal_i2c_handle_external FuriHalI2cBusHandle
3088 Variable + gpio_infrared_tx const GpioPin
3089 Variable + gpio_nfc_cs const GpioPin
3090 Variable + gpio_nfc_irq_rfid_pull const GpioPin
3091 Variable + gpio_pins const GpioPinRecord[]
3092 Variable + gpio_pins_count const size_t
3093 Variable + gpio_rf_sw_0 const GpioPin
3094 Variable + gpio_rfid_carrier const GpioPin
3095 Variable + gpio_rfid_carrier_out const GpioPin
+6 -41
View File
@@ -1,39 +1,12 @@
/**
******************************************************************************
* @file fatfs.c
* @brief Code for fatfs applications
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
#include "fatfs.h"
uint8_t retUSER; /* Return value for USER */
char USERPath[4]; /* USER logical drive path */
FATFS USERFatFS; /* File system object for USER logical drive */
FIL USERFile; /* File object for USER */
/** logical drive path */
char fatfs_path[4];
/** File system object */
FATFS fatfs_object;
/* USER CODE BEGIN Variables */
/* USER CODE END Variables */
void MX_FATFS_Init(void) {
/*## FatFS: Link the USER driver ###########################*/
retUSER = FATFS_LinkDriver(&USER_Driver, USERPath);
/* USER CODE BEGIN Init */
/* additional user code for init */
/* USER CODE END Init */
void fatfs_init(void) {
FATFS_LinkDriver(&sd_fatfs_driver, fatfs_path);
}
/**
@@ -42,13 +15,5 @@ void MX_FATFS_Init(void) {
* @retval Time in DWORD
*/
DWORD get_fattime(void) {
/* USER CODE BEGIN get_fattime */
return 0;
/* USER CODE END get_fattime */
}
/* USER CODE BEGIN Application */
/* USER CODE END Application */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+10 -40
View File
@@ -1,49 +1,19 @@
/**
******************************************************************************
* @file fatfs.h
* @brief Header for fatfs applications
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
#pragma once
#include "fatfs/ff.h"
#include "fatfs/ff_gen_drv.h"
#include "user_diskio.h"
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __fatfs_H
#define __fatfs_H
#ifdef __cplusplus
extern "C" {
#endif
#include "fatfs/ff.h"
#include "fatfs/ff_gen_drv.h"
#include "user_diskio.h" /* defines USER_Driver as external */
/** File system object */
extern FATFS fatfs_object;
/* USER CODE BEGIN Includes */
/** Init file system driver */
void fatfs_init(void);
/* USER CODE END Includes */
extern uint8_t retUSER; /* Return value for USER */
extern char USERPath[4]; /* USER logical drive path */
extern FATFS USERFatFS; /* File system object for USER logical drive */
extern FIL USERFile; /* File object for USER */
void MX_FATFS_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /*__fatfs_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
#endif
+1 -1
View File
@@ -164,7 +164,7 @@
/* USER CODE BEGIN Volumes */
#define _STR_VOLUME_ID 0 /* 0:Use only 0-9 for drive ID, 1:Use strings for drive ID */
#define _VOLUME_STRS "RAM", "NAND", "CF", "SD1", "SD2", "USB1", "USB2", "USB3"
#define _VOLUME_STRS "SD"
/* _STR_VOLUME_ID switches string support of volume ID.
/ When _STR_VOLUME_ID is set to 1, also pre-defined strings can be used as drive
/ number in the path name. _VOLUME_STRS defines the drive ID strings for each
+843
View File
@@ -0,0 +1,843 @@
#include "sd_spi_io.h"
#include "sector_cache.h"
#include <furi.h>
#include <furi_hal.h>
#include <furi/core/core_defines.h>
// #define SD_SPI_DEBUG 1
#define TAG "SdSpi"
#ifdef SD_SPI_DEBUG
#define sd_spi_debug(...) FURI_LOG_I(TAG, __VA_ARGS__)
#else
#define sd_spi_debug(...)
#endif
#define SD_CMD_LENGTH 6
#define SD_DUMMY_BYTE 0xFF
#define SD_ANSWER_RETRY_COUNT 8
#define SD_IDLE_RETRY_COUNT 100
#define FLAG_SET(x, y) (((x) & (y)) == (y))
static bool sd_high_capacity = false;
typedef enum {
SdSpiDataResponceOK = 0x05,
SdSpiDataResponceCRCError = 0x0B,
SdSpiDataResponceWriteError = 0x0D,
SdSpiDataResponceOtherError = 0xFF,
} SdSpiDataResponce;
typedef struct {
uint8_t r1;
uint8_t r2;
uint8_t r3;
uint8_t r4;
uint8_t r5;
} SdSpiCmdAnswer;
typedef enum {
SdSpiCmdAnswerTypeR1,
SdSpiCmdAnswerTypeR1B,
SdSpiCmdAnswerTypeR2,
SdSpiCmdAnswerTypeR3,
SdSpiCmdAnswerTypeR4R5,
SdSpiCmdAnswerTypeR7,
} SdSpiCmdAnswerType;
/*
SdSpiCmd and SdSpiToken use non-standard enum value names convention,
because it is more convenient to look for documentation on a specific command.
For example, to find out what the SD_CMD23_SET_BLOCK_COUNT command does, you need to look for
SET_BLOCK_COUNT or CMD23 in the "Part 1 Physical Layer Simplified Specification".
Do not use that naming convention in other places.
*/
typedef enum {
SD_CMD0_GO_IDLE_STATE = 0,
SD_CMD1_SEND_OP_COND = 1,
SD_CMD8_SEND_IF_COND = 8,
SD_CMD9_SEND_CSD = 9,
SD_CMD10_SEND_CID = 10,
SD_CMD12_STOP_TRANSMISSION = 12,
SD_CMD13_SEND_STATUS = 13,
SD_CMD16_SET_BLOCKLEN = 16,
SD_CMD17_READ_SINGLE_BLOCK = 17,
SD_CMD18_READ_MULT_BLOCK = 18,
SD_CMD23_SET_BLOCK_COUNT = 23,
SD_CMD24_WRITE_SINGLE_BLOCK = 24,
SD_CMD25_WRITE_MULT_BLOCK = 25,
SD_CMD27_PROG_CSD = 27,
SD_CMD28_SET_WRITE_PROT = 28,
SD_CMD29_CLR_WRITE_PROT = 29,
SD_CMD30_SEND_WRITE_PROT = 30,
SD_CMD32_SD_ERASE_GRP_START = 32,
SD_CMD33_SD_ERASE_GRP_END = 33,
SD_CMD34_UNTAG_SECTOR = 34,
SD_CMD35_ERASE_GRP_START = 35,
SD_CMD36_ERASE_GRP_END = 36,
SD_CMD37_UNTAG_ERASE_GROUP = 37,
SD_CMD38_ERASE = 38,
SD_CMD41_SD_APP_OP_COND = 41,
SD_CMD55_APP_CMD = 55,
SD_CMD58_READ_OCR = 58,
} SdSpiCmd;
/** Data tokens */
typedef enum {
SD_TOKEN_START_DATA_SINGLE_BLOCK_READ = 0xFE,
SD_TOKEN_START_DATA_MULTIPLE_BLOCK_READ = 0xFE,
SD_TOKEN_START_DATA_SINGLE_BLOCK_WRITE = 0xFE,
SD_TOKEN_START_DATA_MULTIPLE_BLOCK_WRITE = 0xFC,
SD_TOKEN_STOP_DATA_MULTIPLE_BLOCK_WRITE = 0xFD,
} SdSpiToken;
/** R1 answer value */
typedef enum {
SdSpi_R1_NO_ERROR = 0x00,
SdSpi_R1_IN_IDLE_STATE = 0x01,
SdSpi_R1_ERASE_RESET = 0x02,
SdSpi_R1_ILLEGAL_COMMAND = 0x04,
SdSpi_R1_COM_CRC_ERROR = 0x08,
SdSpi_R1_ERASE_SEQUENCE_ERROR = 0x10,
SdSpi_R1_ADDRESS_ERROR = 0x20,
SdSpi_R1_PARAMETER_ERROR = 0x40,
} SdSpiR1;
/** R2 answer value */
typedef enum {
/* R2 answer value */
SdSpi_R2_NO_ERROR = 0x00,
SdSpi_R2_CARD_LOCKED = 0x01,
SdSpi_R2_LOCKUNLOCK_ERROR = 0x02,
SdSpi_R2_ERROR = 0x04,
SdSpi_R2_CC_ERROR = 0x08,
SdSpi_R2_CARD_ECC_FAILED = 0x10,
SdSpi_R2_WP_VIOLATION = 0x20,
SdSpi_R2_ERASE_PARAM = 0x40,
SdSpi_R2_OUTOFRANGE = 0x80,
} SdSpiR2;
static inline void sd_spi_select_card() {
furi_hal_gpio_write(furi_hal_sd_spi_handle->cs, false);
furi_delay_us(10); // Entry guard time for some SD cards
}
static inline void sd_spi_deselect_card() {
furi_delay_us(10); // Exit guard time for some SD cards
furi_hal_gpio_write(furi_hal_sd_spi_handle->cs, true);
}
static void sd_spi_bus_to_ground() {
furi_hal_gpio_init_ex(
furi_hal_sd_spi_handle->miso,
GpioModeOutputPushPull,
GpioPullNo,
GpioSpeedVeryHigh,
GpioAltFnUnused);
furi_hal_gpio_init_ex(
furi_hal_sd_spi_handle->mosi,
GpioModeOutputPushPull,
GpioPullNo,
GpioSpeedVeryHigh,
GpioAltFnUnused);
furi_hal_gpio_init_ex(
furi_hal_sd_spi_handle->sck,
GpioModeOutputPushPull,
GpioPullNo,
GpioSpeedVeryHigh,
GpioAltFnUnused);
sd_spi_select_card();
furi_hal_gpio_write(furi_hal_sd_spi_handle->miso, false);
furi_hal_gpio_write(furi_hal_sd_spi_handle->mosi, false);
furi_hal_gpio_write(furi_hal_sd_spi_handle->sck, false);
}
static void sd_spi_bus_rise_up() {
sd_spi_deselect_card();
furi_hal_gpio_init_ex(
furi_hal_sd_spi_handle->miso,
GpioModeAltFunctionPushPull,
GpioPullUp,
GpioSpeedVeryHigh,
GpioAltFn5SPI2);
furi_hal_gpio_init_ex(
furi_hal_sd_spi_handle->mosi,
GpioModeAltFunctionPushPull,
GpioPullUp,
GpioSpeedVeryHigh,
GpioAltFn5SPI2);
furi_hal_gpio_init_ex(
furi_hal_sd_spi_handle->sck,
GpioModeAltFunctionPushPull,
GpioPullUp,
GpioSpeedVeryHigh,
GpioAltFn5SPI2);
}
static inline uint8_t sd_spi_read_byte(void) {
uint8_t responce;
furi_check(furi_hal_spi_bus_trx(furi_hal_sd_spi_handle, NULL, &responce, 1, SD_TIMEOUT_MS));
return responce;
}
static inline void sd_spi_write_byte(uint8_t data) {
furi_check(furi_hal_spi_bus_trx(furi_hal_sd_spi_handle, &data, NULL, 1, SD_TIMEOUT_MS));
}
static inline uint8_t sd_spi_write_and_read_byte(uint8_t data) {
uint8_t responce;
furi_check(furi_hal_spi_bus_trx(furi_hal_sd_spi_handle, &data, &responce, 1, SD_TIMEOUT_MS));
return responce;
}
static inline void sd_spi_write_bytes(uint8_t* data, uint32_t size) {
furi_check(furi_hal_spi_bus_trx(furi_hal_sd_spi_handle, data, NULL, size, SD_TIMEOUT_MS));
}
static inline void sd_spi_read_bytes(uint8_t* data, uint32_t size) {
furi_check(furi_hal_spi_bus_trx(furi_hal_sd_spi_handle, NULL, data, size, SD_TIMEOUT_MS));
}
static inline void sd_spi_write_bytes_dma(uint8_t* data, uint32_t size) {
uint32_t timeout_mul = (size / 512) + 1;
furi_check(furi_hal_spi_bus_trx_dma(
furi_hal_sd_spi_handle, data, NULL, size, SD_TIMEOUT_MS * timeout_mul));
}
static inline void sd_spi_read_bytes_dma(uint8_t* data, uint32_t size) {
uint32_t timeout_mul = (size / 512) + 1;
furi_check(furi_hal_spi_bus_trx_dma(
furi_hal_sd_spi_handle, NULL, data, size, SD_TIMEOUT_MS * timeout_mul));
}
static uint8_t sd_spi_wait_for_data_and_read(void) {
uint8_t retry_count = SD_ANSWER_RETRY_COUNT;
uint8_t responce;
// Wait until we get a valid data
do {
responce = sd_spi_read_byte();
retry_count--;
} while((responce == SD_DUMMY_BYTE) && retry_count);
return responce;
}
static SdSpiStatus sd_spi_wait_for_data(uint8_t data, uint32_t timeout_ms) {
FuriHalCortexTimer timer = furi_hal_cortex_timer_get(timeout_ms * 1000);
uint8_t byte;
do {
byte = sd_spi_read_byte();
if(furi_hal_cortex_timer_is_expired(timer)) {
return SdSpiStatusTimeout;
}
} while((byte != data));
return SdSpiStatusOK;
}
static inline void sd_spi_deselect_card_and_purge() {
sd_spi_deselect_card();
sd_spi_read_byte();
}
static inline void sd_spi_purge_crc() {
sd_spi_read_byte();
sd_spi_read_byte();
}
static SdSpiCmdAnswer
sd_spi_send_cmd(SdSpiCmd cmd, uint32_t arg, uint8_t crc, SdSpiCmdAnswerType answer_type) {
uint8_t frame[SD_CMD_LENGTH];
SdSpiCmdAnswer cmd_answer = {
.r1 = SD_DUMMY_BYTE,
.r2 = SD_DUMMY_BYTE,
.r3 = SD_DUMMY_BYTE,
.r4 = SD_DUMMY_BYTE,
.r5 = SD_DUMMY_BYTE,
};
// R1 Length = NCS(0)+ 6 Bytes command + NCR(min1 max8) + 1 Bytes answer + NEC(0) = 15bytes
// R1b identical to R1 + Busy information
// R2 Length = NCS(0)+ 6 Bytes command + NCR(min1 max8) + 2 Bytes answer + NEC(0) = 16bytes
frame[0] = ((uint8_t)cmd | 0x40);
frame[1] = (uint8_t)(arg >> 24);
frame[2] = (uint8_t)(arg >> 16);
frame[3] = (uint8_t)(arg >> 8);
frame[4] = (uint8_t)(arg);
frame[5] = (crc | 0x01);
sd_spi_select_card();
sd_spi_write_bytes(frame, sizeof(frame));
switch(answer_type) {
case SdSpiCmdAnswerTypeR1:
cmd_answer.r1 = sd_spi_wait_for_data_and_read();
break;
case SdSpiCmdAnswerTypeR1B:
// TODO: can be wrong, at least for SD_CMD12_STOP_TRANSMISSION you need to purge one byte before reading R1
cmd_answer.r1 = sd_spi_wait_for_data_and_read();
// In general this shenenigans seems suspicious, please double check SD specs if you are using SdSpiCmdAnswerTypeR1B
// reassert card
sd_spi_deselect_card();
furi_delay_us(1000);
sd_spi_deselect_card();
// and wait for it to be ready
while(sd_spi_read_byte() != 0xFF) {
};
break;
case SdSpiCmdAnswerTypeR2:
cmd_answer.r1 = sd_spi_wait_for_data_and_read();
cmd_answer.r2 = sd_spi_read_byte();
break;
case SdSpiCmdAnswerTypeR3:
case SdSpiCmdAnswerTypeR7:
cmd_answer.r1 = sd_spi_wait_for_data_and_read();
cmd_answer.r2 = sd_spi_read_byte();
cmd_answer.r3 = sd_spi_read_byte();
cmd_answer.r4 = sd_spi_read_byte();
cmd_answer.r5 = sd_spi_read_byte();
break;
default:
break;
}
return cmd_answer;
}
static SdSpiDataResponce sd_spi_get_data_response(uint32_t timeout_ms) {
SdSpiDataResponce responce = sd_spi_read_byte();
// read busy response byte
sd_spi_read_byte();
switch(responce & 0x1F) {
case SdSpiDataResponceOK:
// TODO: check timings
sd_spi_deselect_card();
sd_spi_select_card();
// wait for 0xFF
if(sd_spi_wait_for_data(0xFF, timeout_ms) == SdSpiStatusOK) {
return SdSpiDataResponceOK;
} else {
return SdSpiDataResponceOtherError;
}
case SdSpiDataResponceCRCError:
return SdSpiDataResponceCRCError;
case SdSpiDataResponceWriteError:
return SdSpiDataResponceWriteError;
default:
return SdSpiDataResponceOtherError;
}
}
static SdSpiStatus sd_spi_init_spi_mode_v1(void) {
SdSpiCmdAnswer response;
uint8_t retry_count = 0;
sd_spi_debug("Init SD card in SPI mode v1");
do {
retry_count++;
// CMD55 (APP_CMD) before any ACMD command: R1 response (0x00: no errors)
sd_spi_send_cmd(SD_CMD55_APP_CMD, 0, 0xFF, SdSpiCmdAnswerTypeR1);
sd_spi_deselect_card_and_purge();
// ACMD41 (SD_APP_OP_COND) to initialize SDHC or SDXC cards: R1 response (0x00: no errors)
response = sd_spi_send_cmd(SD_CMD41_SD_APP_OP_COND, 0, 0xFF, SdSpiCmdAnswerTypeR1);
sd_spi_deselect_card_and_purge();
if(retry_count >= SD_IDLE_RETRY_COUNT) {
return SdSpiStatusError;
}
} while(response.r1 == SdSpi_R1_IN_IDLE_STATE);
sd_spi_debug("Init SD card in SPI mode v1 done");
return SdSpiStatusOK;
}
static SdSpiStatus sd_spi_init_spi_mode_v2(void) {
SdSpiCmdAnswer response;
uint8_t retry_count = 0;
sd_spi_debug("Init SD card in SPI mode v2");
do {
retry_count++;
// CMD55 (APP_CMD) before any ACMD command: R1 response (0x00: no errors)
sd_spi_send_cmd(SD_CMD55_APP_CMD, 0, 0xFF, SdSpiCmdAnswerTypeR1);
sd_spi_deselect_card_and_purge();
// ACMD41 (APP_OP_COND) to initialize SDHC or SDXC cards: R1 response (0x00: no errors)
response =
sd_spi_send_cmd(SD_CMD41_SD_APP_OP_COND, 0x40000000, 0xFF, SdSpiCmdAnswerTypeR1);
sd_spi_deselect_card_and_purge();
if(retry_count >= SD_IDLE_RETRY_COUNT) {
sd_spi_debug("ACMD41 failed");
return SdSpiStatusError;
}
} while(response.r1 == SdSpi_R1_IN_IDLE_STATE);
if(FLAG_SET(response.r1, SdSpi_R1_ILLEGAL_COMMAND)) {
sd_spi_debug("ACMD41 is illegal command");
retry_count = 0;
do {
retry_count++;
// CMD55 (APP_CMD) before any ACMD command: R1 response (0x00: no errors)
response = sd_spi_send_cmd(SD_CMD55_APP_CMD, 0, 0xFF, SdSpiCmdAnswerTypeR1);
sd_spi_deselect_card_and_purge();
if(response.r1 != SdSpi_R1_IN_IDLE_STATE) {
sd_spi_debug("CMD55 failed");
return SdSpiStatusError;
}
// ACMD41 (SD_APP_OP_COND) to initialize SDHC or SDXC cards: R1 response (0x00: no errors)
response = sd_spi_send_cmd(SD_CMD41_SD_APP_OP_COND, 0, 0xFF, SdSpiCmdAnswerTypeR1);
sd_spi_deselect_card_and_purge();
if(retry_count >= SD_IDLE_RETRY_COUNT) {
sd_spi_debug("ACMD41 failed");
return SdSpiStatusError;
}
} while(response.r1 == SdSpi_R1_IN_IDLE_STATE);
}
sd_spi_debug("Init SD card in SPI mode v2 done");
return SdSpiStatusOK;
}
static SdSpiStatus sd_spi_init_spi_mode(void) {
SdSpiCmdAnswer response;
uint8_t retry_count;
// CMD0 (GO_IDLE_STATE) to put SD in SPI mode and
// wait for In Idle State Response (R1 Format) equal to 0x01
retry_count = 0;
do {
retry_count++;
response = sd_spi_send_cmd(SD_CMD0_GO_IDLE_STATE, 0, 0x95, SdSpiCmdAnswerTypeR1);
sd_spi_deselect_card_and_purge();
if(retry_count >= SD_IDLE_RETRY_COUNT) {
sd_spi_debug("CMD0 failed");
return SdSpiStatusError;
}
} while(response.r1 != SdSpi_R1_IN_IDLE_STATE);
// CMD8 (SEND_IF_COND) to check the power supply status
// and wait until response (R7 Format) equal to 0xAA and
response = sd_spi_send_cmd(SD_CMD8_SEND_IF_COND, 0x1AA, 0x87, SdSpiCmdAnswerTypeR7);
sd_spi_deselect_card_and_purge();
if(FLAG_SET(response.r1, SdSpi_R1_ILLEGAL_COMMAND)) {
if(sd_spi_init_spi_mode_v1() != SdSpiStatusOK) {
sd_spi_debug("Init mode v1 failed");
return SdSpiStatusError;
}
sd_high_capacity = 0;
} else if(response.r1 == SdSpi_R1_IN_IDLE_STATE) {
if(sd_spi_init_spi_mode_v2() != SdSpiStatusOK) {
sd_spi_debug("Init mode v2 failed");
return SdSpiStatusError;
}
// CMD58 (READ_OCR) to initialize SDHC or SDXC cards: R3 response
response = sd_spi_send_cmd(SD_CMD58_READ_OCR, 0, 0xFF, SdSpiCmdAnswerTypeR3);
sd_spi_deselect_card_and_purge();
if(response.r1 != SdSpi_R1_NO_ERROR) {
sd_spi_debug("CMD58 failed");
return SdSpiStatusError;
}
sd_high_capacity = (response.r2 & 0x40) >> 6;
} else {
return SdSpiStatusError;
}
sd_spi_debug("SD card is %s", sd_high_capacity ? "SDHC or SDXC" : "SDSC");
return SdSpiStatusOK;
}
static SdSpiStatus sd_spi_get_csd(SD_CSD* csd) {
uint16_t counter = 0;
uint8_t csd_data[16];
SdSpiStatus ret = SdSpiStatusError;
SdSpiCmdAnswer response;
// CMD9 (SEND_CSD): R1 format (0x00 is no errors)
response = sd_spi_send_cmd(SD_CMD9_SEND_CSD, 0, 0xFF, SdSpiCmdAnswerTypeR1);
if(response.r1 == SdSpi_R1_NO_ERROR) {
if(sd_spi_wait_for_data(SD_TOKEN_START_DATA_SINGLE_BLOCK_READ, SD_TIMEOUT_MS) ==
SdSpiStatusOK) {
// read CSD data
for(counter = 0; counter < 16; counter++) {
csd_data[counter] = sd_spi_read_byte();
}
sd_spi_purge_crc();
/*************************************************************************
CSD header decoding
*************************************************************************/
csd->CSDStruct = (csd_data[0] & 0xC0) >> 6;
csd->Reserved1 = csd_data[0] & 0x3F;
csd->TAAC = csd_data[1];
csd->NSAC = csd_data[2];
csd->MaxBusClkFrec = csd_data[3];
csd->CardComdClasses = (csd_data[4] << 4) | ((csd_data[5] & 0xF0) >> 4);
csd->RdBlockLen = csd_data[5] & 0x0F;
csd->PartBlockRead = (csd_data[6] & 0x80) >> 7;
csd->WrBlockMisalign = (csd_data[6] & 0x40) >> 6;
csd->RdBlockMisalign = (csd_data[6] & 0x20) >> 5;
csd->DSRImpl = (csd_data[6] & 0x10) >> 4;
/*************************************************************************
CSD v1/v2 decoding
*************************************************************************/
if(sd_high_capacity == 0) {
csd->version.v1.Reserved1 = ((csd_data[6] & 0x0C) >> 2);
csd->version.v1.DeviceSize = ((csd_data[6] & 0x03) << 10) | (csd_data[7] << 2) |
((csd_data[8] & 0xC0) >> 6);
csd->version.v1.MaxRdCurrentVDDMin = (csd_data[8] & 0x38) >> 3;
csd->version.v1.MaxRdCurrentVDDMax = (csd_data[8] & 0x07);
csd->version.v1.MaxWrCurrentVDDMin = (csd_data[9] & 0xE0) >> 5;
csd->version.v1.MaxWrCurrentVDDMax = (csd_data[9] & 0x1C) >> 2;
csd->version.v1.DeviceSizeMul = ((csd_data[9] & 0x03) << 1) |
((csd_data[10] & 0x80) >> 7);
} else {
csd->version.v2.Reserved1 = ((csd_data[6] & 0x0F) << 2) |
((csd_data[7] & 0xC0) >> 6);
csd->version.v2.DeviceSize = ((csd_data[7] & 0x3F) << 16) | (csd_data[8] << 8) |
csd_data[9];
csd->version.v2.Reserved2 = ((csd_data[10] & 0x80) >> 8);
}
csd->EraseSingleBlockEnable = (csd_data[10] & 0x40) >> 6;
csd->EraseSectorSize = ((csd_data[10] & 0x3F) << 1) | ((csd_data[11] & 0x80) >> 7);
csd->WrProtectGrSize = (csd_data[11] & 0x7F);
csd->WrProtectGrEnable = (csd_data[12] & 0x80) >> 7;
csd->Reserved2 = (csd_data[12] & 0x60) >> 5;
csd->WrSpeedFact = (csd_data[12] & 0x1C) >> 2;
csd->MaxWrBlockLen = ((csd_data[12] & 0x03) << 2) | ((csd_data[13] & 0xC0) >> 6);
csd->WriteBlockPartial = (csd_data[13] & 0x20) >> 5;
csd->Reserved3 = (csd_data[13] & 0x1F);
csd->FileFormatGrouop = (csd_data[14] & 0x80) >> 7;
csd->CopyFlag = (csd_data[14] & 0x40) >> 6;
csd->PermWrProtect = (csd_data[14] & 0x20) >> 5;
csd->TempWrProtect = (csd_data[14] & 0x10) >> 4;
csd->FileFormat = (csd_data[14] & 0x0C) >> 2;
csd->Reserved4 = (csd_data[14] & 0x03);
csd->crc = (csd_data[15] & 0xFE) >> 1;
csd->Reserved5 = (csd_data[15] & 0x01);
ret = SdSpiStatusOK;
}
}
sd_spi_deselect_card_and_purge();
return ret;
}
static SdSpiStatus sd_spi_get_cid(SD_CID* Cid) {
uint16_t counter = 0;
uint8_t cid_data[16];
SdSpiStatus ret = SdSpiStatusError;
SdSpiCmdAnswer response;
// CMD10 (SEND_CID): R1 format (0x00 is no errors)
response = sd_spi_send_cmd(SD_CMD10_SEND_CID, 0, 0xFF, SdSpiCmdAnswerTypeR1);
if(response.r1 == SdSpi_R1_NO_ERROR) {
if(sd_spi_wait_for_data(SD_TOKEN_START_DATA_SINGLE_BLOCK_READ, SD_TIMEOUT_MS) ==
SdSpiStatusOK) {
// read CID data
for(counter = 0; counter < 16; counter++) {
cid_data[counter] = sd_spi_read_byte();
}
sd_spi_purge_crc();
Cid->ManufacturerID = cid_data[0];
memcpy(Cid->OEM_AppliID, cid_data + 1, 2);
memcpy(Cid->ProdName, cid_data + 3, 5);
Cid->ProdRev = cid_data[8];
Cid->ProdSN = cid_data[9] << 24;
Cid->ProdSN |= cid_data[10] << 16;
Cid->ProdSN |= cid_data[11] << 8;
Cid->ProdSN |= cid_data[12];
Cid->Reserved1 = (cid_data[13] & 0xF0) >> 4;
Cid->ManufactYear = (cid_data[13] & 0x0F) << 4;
Cid->ManufactYear |= (cid_data[14] & 0xF0) >> 4;
Cid->ManufactMonth = (cid_data[14] & 0x0F);
Cid->CID_CRC = (cid_data[15] & 0xFE) >> 1;
Cid->Reserved2 = 1;
ret = SdSpiStatusOK;
}
}
sd_spi_deselect_card_and_purge();
return ret;
}
static SdSpiStatus
sd_spi_cmd_read_blocks(uint32_t* data, uint32_t address, uint32_t blocks, uint32_t timeout_ms) {
uint32_t block_address = address;
uint32_t offset = 0;
// CMD16 (SET_BLOCKLEN): R1 response (0x00: no errors)
SdSpiCmdAnswer response =
sd_spi_send_cmd(SD_CMD16_SET_BLOCKLEN, SD_BLOCK_SIZE, 0xFF, SdSpiCmdAnswerTypeR1);
sd_spi_deselect_card_and_purge();
if(response.r1 != SdSpi_R1_NO_ERROR) {
return SdSpiStatusError;
}
if(!sd_high_capacity) {
block_address = address * SD_BLOCK_SIZE;
}
while(blocks--) {
// CMD17 (READ_SINGLE_BLOCK): R1 response (0x00: no errors)
response =
sd_spi_send_cmd(SD_CMD17_READ_SINGLE_BLOCK, block_address, 0xFF, SdSpiCmdAnswerTypeR1);
if(response.r1 != SdSpi_R1_NO_ERROR) {
sd_spi_deselect_card_and_purge();
return SdSpiStatusError;
}
// Wait for the data start token
if(sd_spi_wait_for_data(SD_TOKEN_START_DATA_SINGLE_BLOCK_READ, timeout_ms) ==
SdSpiStatusOK) {
// Read the data block
sd_spi_read_bytes_dma((uint8_t*)data + offset, SD_BLOCK_SIZE);
sd_spi_purge_crc();
// increase offset
offset += SD_BLOCK_SIZE;
// increase block address
if(sd_high_capacity) {
block_address += 1;
} else {
block_address += SD_BLOCK_SIZE;
}
} else {
sd_spi_deselect_card_and_purge();
return SdSpiStatusError;
}
sd_spi_deselect_card_and_purge();
}
return SdSpiStatusOK;
}
static SdSpiStatus sd_spi_cmd_write_blocks(
uint32_t* data,
uint32_t address,
uint32_t blocks,
uint32_t timeout_ms) {
uint32_t block_address = address;
uint32_t offset = 0;
// CMD16 (SET_BLOCKLEN): R1 response (0x00: no errors)
SdSpiCmdAnswer response =
sd_spi_send_cmd(SD_CMD16_SET_BLOCKLEN, SD_BLOCK_SIZE, 0xFF, SdSpiCmdAnswerTypeR1);
sd_spi_deselect_card_and_purge();
if(response.r1 != SdSpi_R1_NO_ERROR) {
return SdSpiStatusError;
}
if(!sd_high_capacity) {
block_address = address * SD_BLOCK_SIZE;
}
while(blocks--) {
// CMD24 (WRITE_SINGLE_BLOCK): R1 response (0x00: no errors)
response = sd_spi_send_cmd(
SD_CMD24_WRITE_SINGLE_BLOCK, block_address, 0xFF, SdSpiCmdAnswerTypeR1);
if(response.r1 != SdSpi_R1_NO_ERROR) {
sd_spi_deselect_card_and_purge();
return SdSpiStatusError;
}
// Send dummy byte for NWR timing : one byte between CMD_WRITE and TOKEN
// TODO: check bytes count
sd_spi_write_byte(SD_DUMMY_BYTE);
sd_spi_write_byte(SD_DUMMY_BYTE);
// Send the data start token
sd_spi_write_byte(SD_TOKEN_START_DATA_SINGLE_BLOCK_WRITE);
sd_spi_write_bytes_dma((uint8_t*)data + offset, SD_BLOCK_SIZE);
sd_spi_purge_crc();
// Read data response
SdSpiDataResponce data_responce = sd_spi_get_data_response(timeout_ms);
sd_spi_deselect_card_and_purge();
if(data_responce != SdSpiDataResponceOK) {
return SdSpiStatusError;
}
// increase offset
offset += SD_BLOCK_SIZE;
// increase block address
if(sd_high_capacity) {
block_address += 1;
} else {
block_address += SD_BLOCK_SIZE;
}
}
return SdSpiStatusOK;
}
uint8_t sd_max_mount_retry_count() {
return 10;
}
SdSpiStatus sd_init(bool power_reset) {
// Slow speed init
furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_slow);
furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_slow;
// We reset card in spi_lock context, so it is safe to disturb spi bus
if(power_reset) {
sd_spi_debug("Power reset");
// disable power and set low on all bus pins
furi_hal_power_disable_external_3_3v();
sd_spi_bus_to_ground();
hal_sd_detect_set_low();
furi_delay_ms(250);
// reinit bus and enable power
sd_spi_bus_rise_up();
hal_sd_detect_init();
furi_hal_power_enable_external_3_3v();
furi_delay_ms(100);
}
SdSpiStatus status = SdSpiStatusError;
// Send 80 dummy clocks with CS high
sd_spi_deselect_card();
for(uint8_t i = 0; i < 80; i++) {
sd_spi_write_byte(SD_DUMMY_BYTE);
}
for(uint8_t i = 0; i < 128; i++) {
status = sd_spi_init_spi_mode();
if(status == SdSpiStatusOK) {
// SD initialized and init to SPI mode properly
sd_spi_debug("SD init OK after %d retries", i);
break;
}
}
furi_hal_sd_spi_handle = NULL;
furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_slow);
// Init sector cache
sector_cache_init();
return status;
}
SdSpiStatus sd_get_card_state(void) {
SdSpiCmdAnswer response;
// Send CMD13 (SEND_STATUS) to get SD status
response = sd_spi_send_cmd(SD_CMD13_SEND_STATUS, 0, 0xFF, SdSpiCmdAnswerTypeR2);
sd_spi_deselect_card_and_purge();
// Return status OK if response is valid
if((response.r1 == SdSpi_R1_NO_ERROR) && (response.r2 == SdSpi_R2_NO_ERROR)) {
return SdSpiStatusOK;
}
return SdSpiStatusError;
}
SdSpiStatus sd_get_card_info(SD_CardInfo* card_info) {
SdSpiStatus status;
status = sd_spi_get_csd(&(card_info->Csd));
if(status != SdSpiStatusOK) {
return status;
}
status = sd_spi_get_cid(&(card_info->Cid));
if(status != SdSpiStatusOK) {
return status;
}
if(sd_high_capacity == 1) {
card_info->LogBlockSize = 512;
card_info->CardBlockSize = 512;
card_info->CardCapacity = ((uint64_t)card_info->Csd.version.v2.DeviceSize + 1UL) * 1024UL *
(uint64_t)card_info->LogBlockSize;
card_info->LogBlockNbr = (card_info->CardCapacity) / (card_info->LogBlockSize);
} else {
card_info->CardCapacity = (card_info->Csd.version.v1.DeviceSize + 1);
card_info->CardCapacity *= (1UL << (card_info->Csd.version.v1.DeviceSizeMul + 2));
card_info->LogBlockSize = 512;
card_info->CardBlockSize = 1UL << (card_info->Csd.RdBlockLen);
card_info->CardCapacity *= card_info->CardBlockSize;
card_info->LogBlockNbr = (card_info->CardCapacity) / (card_info->LogBlockSize);
}
return status;
}
SdSpiStatus
sd_read_blocks(uint32_t* data, uint32_t address, uint32_t blocks, uint32_t timeout_ms) {
SdSpiStatus status = sd_spi_cmd_read_blocks(data, address, blocks, timeout_ms);
return status;
}
SdSpiStatus
sd_write_blocks(uint32_t* data, uint32_t address, uint32_t blocks, uint32_t timeout_ms) {
SdSpiStatus status = sd_spi_cmd_write_blocks(data, address, blocks, timeout_ms);
return status;
}
SdSpiStatus sd_get_cid(SD_CID* cid) {
SdSpiStatus status;
furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_fast);
furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_fast;
memset(cid, 0, sizeof(SD_CID));
status = sd_spi_get_cid(cid);
furi_hal_sd_spi_handle = NULL;
furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_fast);
return status;
}
+158
View File
@@ -0,0 +1,158 @@
#pragma once
#include <stdint.h>
#include <stdbool.h>
#define __IO volatile
#define SD_TIMEOUT_MS (1000)
#define SD_BLOCK_SIZE 512
typedef enum {
SdSpiStatusOK,
SdSpiStatusError,
SdSpiStatusTimeout,
} SdSpiStatus;
/**
* @brief Card Specific Data: CSD Register
*/
typedef struct {
/* Header part */
uint8_t CSDStruct : 2; /* CSD structure */
uint8_t Reserved1 : 6; /* Reserved */
uint8_t TAAC : 8; /* Data read access-time 1 */
uint8_t NSAC : 8; /* Data read access-time 2 in CLK cycles */
uint8_t MaxBusClkFrec : 8; /* Max. bus clock frequency */
uint16_t CardComdClasses : 12; /* Card command classes */
uint8_t RdBlockLen : 4; /* Max. read data block length */
uint8_t PartBlockRead : 1; /* Partial blocks for read allowed */
uint8_t WrBlockMisalign : 1; /* Write block misalignment */
uint8_t RdBlockMisalign : 1; /* Read block misalignment */
uint8_t DSRImpl : 1; /* DSR implemented */
/* v1 or v2 struct */
union csd_version {
struct {
uint8_t Reserved1 : 2; /* Reserved */
uint16_t DeviceSize : 12; /* Device Size */
uint8_t MaxRdCurrentVDDMin : 3; /* Max. read current @ VDD min */
uint8_t MaxRdCurrentVDDMax : 3; /* Max. read current @ VDD max */
uint8_t MaxWrCurrentVDDMin : 3; /* Max. write current @ VDD min */
uint8_t MaxWrCurrentVDDMax : 3; /* Max. write current @ VDD max */
uint8_t DeviceSizeMul : 3; /* Device size multiplier */
} v1;
struct {
uint8_t Reserved1 : 6; /* Reserved */
uint32_t DeviceSize : 22; /* Device Size */
uint8_t Reserved2 : 1; /* Reserved */
} v2;
} version;
uint8_t EraseSingleBlockEnable : 1; /* Erase single block enable */
uint8_t EraseSectorSize : 7; /* Erase group size multiplier */
uint8_t WrProtectGrSize : 7; /* Write protect group size */
uint8_t WrProtectGrEnable : 1; /* Write protect group enable */
uint8_t Reserved2 : 2; /* Reserved */
uint8_t WrSpeedFact : 3; /* Write speed factor */
uint8_t MaxWrBlockLen : 4; /* Max. write data block length */
uint8_t WriteBlockPartial : 1; /* Partial blocks for write allowed */
uint8_t Reserved3 : 5; /* Reserved */
uint8_t FileFormatGrouop : 1; /* File format group */
uint8_t CopyFlag : 1; /* Copy flag (OTP) */
uint8_t PermWrProtect : 1; /* Permanent write protection */
uint8_t TempWrProtect : 1; /* Temporary write protection */
uint8_t FileFormat : 2; /* File Format */
uint8_t Reserved4 : 2; /* Reserved */
uint8_t crc : 7; /* Reserved */
uint8_t Reserved5 : 1; /* always 1*/
} SD_CSD;
/**
* @brief Card Identification Data: CID Register
*/
typedef struct {
uint8_t ManufacturerID; /* ManufacturerID */
char OEM_AppliID[2]; /* OEM/Application ID */
char ProdName[5]; /* Product Name */
uint8_t ProdRev; /* Product Revision */
uint32_t ProdSN; /* Product Serial Number */
uint8_t Reserved1; /* Reserved1 */
uint8_t ManufactYear; /* Manufacturing Year */
uint8_t ManufactMonth; /* Manufacturing Month */
uint8_t CID_CRC; /* CID CRC */
uint8_t Reserved2; /* always 1 */
} SD_CID;
/**
* @brief SD Card information structure
*/
typedef struct {
SD_CSD Csd;
SD_CID Cid;
uint64_t CardCapacity; /*!< Card Capacity */
uint32_t CardBlockSize; /*!< Card Block Size */
uint32_t LogBlockNbr; /*!< Specifies the Card logical Capacity in blocks */
uint32_t LogBlockSize; /*!< Specifies logical block size in bytes */
} SD_CardInfo;
/**
* @brief SD card max mount retry count
*
* @return uint8_t
*/
uint8_t sd_max_mount_retry_count();
/**
* @brief Init sd card
*
* @param power_reset reset card power
* @return SdSpiStatus
*/
SdSpiStatus sd_init(bool power_reset);
/**
* @brief Get card state
*
* @return SdSpiStatus
*/
SdSpiStatus sd_get_card_state(void);
/**
* @brief Get card info
*
* @param card_info
* @return SdSpiStatus
*/
SdSpiStatus sd_get_card_info(SD_CardInfo* card_info);
/**
* @brief Read blocks
*
* @param data
* @param address
* @param blocks
* @param timeout_ms
* @return SdSpiStatus
*/
SdSpiStatus sd_read_blocks(uint32_t* data, uint32_t address, uint32_t blocks, uint32_t timeout_ms);
/**
* @brief Write blocks
*
* @param data
* @param address
* @param blocks
* @param timeout_ms
* @return SdSpiStatus
*/
SdSpiStatus
sd_write_blocks(uint32_t* data, uint32_t address, uint32_t blocks, uint32_t timeout_ms);
/**
* @brief Get card CSD register
*
* @param Cid
* @return SdSpiStatus
*/
SdSpiStatus sd_get_cid(SD_CID* cid);
-5
View File
@@ -8,7 +8,6 @@
#define SECTOR_SIZE 512
#define N_SECTORS 8
#define TAG "SDCache"
typedef struct {
uint32_t itr;
@@ -20,15 +19,11 @@ static SectorCache* cache = NULL;
void sector_cache_init() {
if(cache == NULL) {
// TODO: tuneup allocation order, to place cache in mem pool (MEM2)
cache = memmgr_alloc_from_pool(sizeof(SectorCache));
}
if(cache != NULL) {
FURI_LOG_I(TAG, "Init");
memset(cache, 0, sizeof(SectorCache));
} else {
FURI_LOG_E(TAG, "Init failed");
}
}
-98
View File
@@ -1,98 +0,0 @@
#include <furi_hal.h>
#include <furi.h>
#define SD_DUMMY_BYTE 0xFF
const uint32_t SpiTimeout = 1000;
uint8_t SD_IO_WriteByte(uint8_t Data);
/******************************************************************************
BUS OPERATIONS
*******************************************************************************/
/**
* @brief SPI Write byte(s) to device
* @param DataIn: Pointer to data buffer to write
* @param DataOut: Pointer to data buffer for read data
* @param DataLength: number of bytes to write
* @retval None
*/
static void SPIx_WriteReadData(const uint8_t* DataIn, uint8_t* DataOut, uint16_t DataLength) {
furi_check(furi_hal_spi_bus_trx(
furi_hal_sd_spi_handle, (uint8_t*)DataIn, DataOut, DataLength, SpiTimeout));
}
/**
* @brief SPI Write a byte to device
* @param Value: value to be written
* @retval None
*/
__attribute__((unused)) static void SPIx_Write(uint8_t Value) {
furi_check(furi_hal_spi_bus_tx(furi_hal_sd_spi_handle, (uint8_t*)&Value, 1, SpiTimeout));
}
/******************************************************************************
LINK OPERATIONS
*******************************************************************************/
/********************************* LINK SD ************************************/
/**
* @brief Initialize the SD Card and put it into StandBy State (Ready for
* data transfer).
* @retval None
*/
void SD_IO_Init(void) {
uint8_t counter = 0;
/* SD chip select high */
furi_hal_gpio_write(furi_hal_sd_spi_handle->cs, true);
furi_delay_us(10);
/* Send dummy byte 0xFF, 10 times with CS high */
/* Rise CS and MOSI for 80 clocks cycles */
for(counter = 0; counter <= 200; counter++) {
/* Send dummy byte 0xFF */
SD_IO_WriteByte(SD_DUMMY_BYTE);
}
}
/**
* @brief Set SD interface Chip Select state
* @param val: 0 (low) or 1 (high) state
* @retval None
*/
void SD_IO_CSState(uint8_t val) {
/* Some SD Cards are prone to fail if CLK-ed too soon after CS transition. Worst case found: 8us */
if(val == 1) {
furi_delay_us(10); // Exit guard time for some SD cards
furi_hal_gpio_write(furi_hal_sd_spi_handle->cs, true);
} else {
furi_hal_gpio_write(furi_hal_sd_spi_handle->cs, false);
furi_delay_us(10); // Entry guard time for some SD cards
}
}
/**
* @brief Write byte(s) on the SD
* @param DataIn: Pointer to data buffer to write
* @param DataOut: Pointer to data buffer for read data
* @param DataLength: number of bytes to write
* @retval None
*/
void SD_IO_WriteReadData(const uint8_t* DataIn, uint8_t* DataOut, uint16_t DataLength) {
/* Send the byte */
SPIx_WriteReadData(DataIn, DataOut, DataLength);
}
/**
* @brief Write a byte on the SD.
* @param Data: byte to send.
* @retval Data written
*/
uint8_t SD_IO_WriteByte(uint8_t Data) {
uint8_t tmp;
/* Send the byte */
SPIx_WriteReadData(&Data, &tmp, 1);
return tmp;
}
File diff suppressed because it is too large Load Diff
@@ -1,245 +0,0 @@
/**
******************************************************************************
* @file stm32_adafruit_sd.h
* @author MCD Application Team
* @version V3.0.0
* @date 23-December-2016
* @brief This file contains the common defines and functions prototypes for
* the stm32_adafruit_sd.c driver.
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT(c) 2016 STMicroelectronics</center></h2>
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of STMicroelectronics nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32_ADAFRUIT_SD_H
#define __STM32_ADAFRUIT_SD_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
#include <stdbool.h>
/** @addtogroup BSP
* @{
*/
#define __IO volatile
/** @addtogroup STM32_ADAFRUIT
* @{
*/
/** @defgroup STM32_ADAFRUIT_SD
* @{
*/
/** @defgroup STM32_ADAFRUIT_SD_Exported_Types
* @{
*/
/**
* @brief SD status structure definition
*/
enum { BSP_SD_OK = 0x00, MSD_OK = 0x00, BSP_SD_ERROR = 0x01, BSP_SD_TIMEOUT };
typedef struct {
uint8_t Reserved1 : 2; /* Reserved */
uint16_t DeviceSize : 12; /* Device Size */
uint8_t MaxRdCurrentVDDMin : 3; /* Max. read current @ VDD min */
uint8_t MaxRdCurrentVDDMax : 3; /* Max. read current @ VDD max */
uint8_t MaxWrCurrentVDDMin : 3; /* Max. write current @ VDD min */
uint8_t MaxWrCurrentVDDMax : 3; /* Max. write current @ VDD max */
uint8_t DeviceSizeMul : 3; /* Device size multiplier */
} struct_v1;
typedef struct {
uint8_t Reserved1 : 6; /* Reserved */
uint32_t DeviceSize : 22; /* Device Size */
uint8_t Reserved2 : 1; /* Reserved */
} struct_v2;
/**
* @brief Card Specific Data: CSD Register
*/
typedef struct {
/* Header part */
uint8_t CSDStruct : 2; /* CSD structure */
uint8_t Reserved1 : 6; /* Reserved */
uint8_t TAAC : 8; /* Data read access-time 1 */
uint8_t NSAC : 8; /* Data read access-time 2 in CLK cycles */
uint8_t MaxBusClkFrec : 8; /* Max. bus clock frequency */
uint16_t CardComdClasses : 12; /* Card command classes */
uint8_t RdBlockLen : 4; /* Max. read data block length */
uint8_t PartBlockRead : 1; /* Partial blocks for read allowed */
uint8_t WrBlockMisalign : 1; /* Write block misalignment */
uint8_t RdBlockMisalign : 1; /* Read block misalignment */
uint8_t DSRImpl : 1; /* DSR implemented */
/* v1 or v2 struct */
union csd_version {
struct_v1 v1;
struct_v2 v2;
} version;
uint8_t EraseSingleBlockEnable : 1; /* Erase single block enable */
uint8_t EraseSectorSize : 7; /* Erase group size multiplier */
uint8_t WrProtectGrSize : 7; /* Write protect group size */
uint8_t WrProtectGrEnable : 1; /* Write protect group enable */
uint8_t Reserved2 : 2; /* Reserved */
uint8_t WrSpeedFact : 3; /* Write speed factor */
uint8_t MaxWrBlockLen : 4; /* Max. write data block length */
uint8_t WriteBlockPartial : 1; /* Partial blocks for write allowed */
uint8_t Reserved3 : 5; /* Reserved */
uint8_t FileFormatGrouop : 1; /* File format group */
uint8_t CopyFlag : 1; /* Copy flag (OTP) */
uint8_t PermWrProtect : 1; /* Permanent write protection */
uint8_t TempWrProtect : 1; /* Temporary write protection */
uint8_t FileFormat : 2; /* File Format */
uint8_t Reserved4 : 2; /* Reserved */
uint8_t crc : 7; /* Reserved */
uint8_t Reserved5 : 1; /* always 1*/
} SD_CSD;
/**
* @brief Card Identification Data: CID Register
*/
typedef struct {
uint8_t ManufacturerID; /* ManufacturerID */
char OEM_AppliID[2]; /* OEM/Application ID */
char ProdName[5]; /* Product Name */
uint8_t ProdRev; /* Product Revision */
uint32_t ProdSN; /* Product Serial Number */
uint8_t Reserved1; /* Reserved1 */
uint8_t ManufactYear; /* Manufacturing Year */
uint8_t ManufactMonth; /* Manufacturing Month */
uint8_t CID_CRC; /* CID CRC */
uint8_t Reserved2; /* always 1 */
} SD_CID;
/**
* @brief SD Card information
*/
typedef struct {
SD_CSD Csd;
SD_CID Cid;
uint64_t CardCapacity; /*!< Card Capacity */
uint32_t CardBlockSize; /*!< Card Block Size */
uint32_t LogBlockNbr; /*!< Specifies the Card logical Capacity in blocks */
uint32_t LogBlockSize; /*!< Specifies logical block size in bytes */
} SD_CardInfo;
/**
* @}
*/
/** @defgroup STM32_ADAFRUIT_SPI_SD_Exported_Constants
* @{
*/
/**
* @brief Block Size
*/
#define SD_BLOCK_SIZE 0x200
/**
* @brief SD detection on its memory slot
*/
#define SD_PRESENT ((uint8_t)0x01)
#define SD_NOT_PRESENT ((uint8_t)0x00)
#define SD_DATATIMEOUT ((uint32_t)100000000)
/**
* @brief SD Card information structure
*/
#define BSP_SD_CardInfo SD_CardInfo
/**
* @}
*/
/** @defgroup STM32_ADAFRUIT_SD_Exported_Macro
* @{
*/
/**
* @}
*/
/** @defgroup STM32_ADAFRUIT_SD_Exported_Functions
* @{
*/
uint8_t BSP_SD_MaxMountRetryCount();
uint8_t BSP_SD_Init(bool reset_card);
uint8_t
BSP_SD_ReadBlocks(uint32_t* pData, uint32_t ReadAddr, uint32_t NumOfBlocks, uint32_t Timeout);
uint8_t
BSP_SD_WriteBlocks(uint32_t* pData, uint32_t WriteAddr, uint32_t NumOfBlocks, uint32_t Timeout);
uint8_t BSP_SD_Erase(uint32_t StartAddr, uint32_t EndAddr);
uint8_t BSP_SD_GetCardState(void);
uint8_t BSP_SD_GetCardInfo(SD_CardInfo* pCardInfo);
uint8_t BSP_SD_GetCIDRegister(SD_CID* Cid);
/* Link functions for SD Card peripheral*/
void SD_SPI_Slow_Init(void);
void SD_SPI_Fast_Init(void);
void SD_IO_Init(void);
void SD_IO_CSState(uint8_t state);
void SD_IO_WriteReadData(const uint8_t* DataIn, uint8_t* DataOut, uint16_t DataLength);
uint8_t SD_IO_WriteByte(uint8_t Data);
/* Link function for HAL delay */
void HAL_Delay(__IO uint32_t Delay);
#ifdef __cplusplus
}
#endif
#endif /* __STM32_ADAFRUIT_SD_H */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
-116
View File
@@ -1,116 +0,0 @@
/*------------------------------------------------------------------------*/
/* Sample code of OS dependent controls for FatFs */
/* (C)ChaN, 2014 */
/* Portions COPYRIGHT 2017 STMicroelectronics */
/* Portions Copyright (C) 2014, ChaN, all right reserved */
/*------------------------------------------------------------------------*/
/**
******************************************************************************
* @attention
*
* Copyright (c) 2017 STMicroelectronics. All rights reserved.
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
**/
#include "fatfs/ff.h"
#if _FS_REENTRANT
/*------------------------------------------------------------------------*/
/* Create a Synchronization Object */
/*------------------------------------------------------------------------*/
/* This function is called in f_mount() function to create a new
/ synchronization object, such as semaphore and mutex. When a 0 is returned,
/ the f_mount() function fails with FR_INT_ERR.
*/
int ff_cre_syncobj(/* 1:Function succeeded, 0:Could not create the sync object */
BYTE vol, /* Corresponding volume (logical drive number) */
_SYNC_t* sobj /* Pointer to return the created sync object */
) {
int ret;
//osSemaphoreDef(SEM);
//*sobj = osSemaphoreCreate(osSemaphore(SEM), 1);
*sobj = furi_mutex_alloc(FuriMutexTypeNormal);
ret = (*sobj != NULL);
return ret;
}
/*------------------------------------------------------------------------*/
/* Delete a Synchronization Object */
/*------------------------------------------------------------------------*/
/* This function is called in f_mount() function to delete a synchronization
/ object that created with ff_cre_syncobj() function. When a 0 is returned,
/ the f_mount() function fails with FR_INT_ERR.
*/
int ff_del_syncobj(/* 1:Function succeeded, 0:Could not delete due to any error */
_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */
) {
furi_mutex_free(sobj);
return 1;
}
/*------------------------------------------------------------------------*/
/* Request Grant to Access the Volume */
/*------------------------------------------------------------------------*/
/* This function is called on entering file functions to lock the volume.
/ When a 0 is returned, the file function fails with FR_TIMEOUT.
*/
int ff_req_grant(/* 1:Got a grant to access the volume, 0:Could not get a grant */
_SYNC_t sobj /* Sync object to wait */
) {
int ret = 0;
if(furi_mutex_acquire(sobj, _FS_TIMEOUT) == FuriStatusOk) {
ret = 1;
}
return ret;
}
/*------------------------------------------------------------------------*/
/* Release Grant to Access the Volume */
/*------------------------------------------------------------------------*/
/* This function is called on leaving file functions to unlock the volume.
*/
void ff_rel_grant(_SYNC_t sobj /* Sync object to be signaled */
) {
furi_mutex_release(sobj);
}
#endif
#if _USE_LFN == 3 /* LFN with a working buffer on the heap */
/*------------------------------------------------------------------------*/
/* Allocate a memory block */
/*------------------------------------------------------------------------*/
/* If a NULL is returned, the file function fails with FR_NOT_ENOUGH_CORE.
*/
void* ff_memalloc(/* Returns pointer to the allocated memory block */
UINT msize /* Number of bytes to allocate */
) {
return ff_malloc(msize); /* Allocate a new memory block with POSIX API */
}
/*------------------------------------------------------------------------*/
/* Free a memory block */
/*------------------------------------------------------------------------*/
void ff_memfree(void* mblock /* Pointer to the memory block to free */
) {
ff_free(mblock); /* Discard the memory block with POSIX API */
}
#endif
+149 -114
View File
@@ -1,103 +1,121 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file user_diskio.c
* @brief This file includes a diskio driver skeleton to be completed by the user.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE END Header */
#ifdef USE_OBSOLETE_USER_CODE_SECTION_0
/*
* Warning: the user section 0 is no more in use (starting from CubeMx version 4.16.0)
* To be suppressed in the future.
* Kept to ensure backward compatibility with previous CubeMx versions when
* migrating projects.
* User code previously added there should be copied in the new user sections before
* the section contents can be deleted.
*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
#endif
/* USER CODE BEGIN DECL */
/* Includes ------------------------------------------------------------------*/
#include "user_diskio.h"
#include <furi_hal.h>
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#include "sector_cache.h"
/* Private variables ---------------------------------------------------------*/
/* Disk status */
static volatile DSTATUS Stat = STA_NOINIT;
static DSTATUS User_CheckStatus(BYTE lun) {
static DSTATUS driver_check_status(BYTE lun) {
UNUSED(lun);
Stat = STA_NOINIT;
if(BSP_SD_GetCardState() == MSD_OK) {
if(sd_get_card_state() == SdSpiStatusOK) {
Stat &= ~STA_NOINIT;
}
return Stat;
}
/* USER CODE END DECL */
static DSTATUS driver_initialize(BYTE pdrv);
static DSTATUS driver_status(BYTE pdrv);
static DRESULT driver_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
static DRESULT driver_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
static DRESULT driver_ioctl(BYTE pdrv, BYTE cmd, void* buff);
/* Private function prototypes -----------------------------------------------*/
DSTATUS USER_initialize(BYTE pdrv);
DSTATUS USER_status(BYTE pdrv);
DRESULT USER_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
#if _USE_WRITE == 1
DRESULT USER_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
#endif /* _USE_WRITE == 1 */
#if _USE_IOCTL == 1
DRESULT USER_ioctl(BYTE pdrv, BYTE cmd, void* buff);
#endif /* _USE_IOCTL == 1 */
Diskio_drvTypeDef USER_Driver = {
USER_initialize,
USER_status,
USER_read,
#if _USE_WRITE
USER_write,
#endif /* _USE_WRITE == 1 */
#if _USE_IOCTL == 1
USER_ioctl,
#endif /* _USE_IOCTL == 1 */
Diskio_drvTypeDef sd_fatfs_driver = {
driver_initialize,
driver_status,
driver_read,
driver_write,
driver_ioctl,
};
/* Private functions ---------------------------------------------------------*/
static inline bool sd_cache_get(uint32_t address, uint32_t* data) {
uint8_t* cached_data = sector_cache_get(address);
if(cached_data) {
memcpy(data, cached_data, SD_BLOCK_SIZE);
return true;
}
return false;
}
static inline void sd_cache_put(uint32_t address, uint32_t* data) {
sector_cache_put(address, (uint8_t*)data);
}
static inline void sd_cache_invalidate_range(uint32_t start_sector, uint32_t end_sector) {
sector_cache_invalidate_range(start_sector, end_sector);
}
static inline void sd_cache_invalidate_all() {
sector_cache_init();
}
static bool sd_device_read(uint32_t* buff, uint32_t sector, uint32_t count) {
bool result = false;
furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_fast);
furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_fast;
if(sd_read_blocks(buff, sector, count, SD_TIMEOUT_MS) == SdSpiStatusOK) {
FuriHalCortexTimer timer = furi_hal_cortex_timer_get(SD_TIMEOUT_MS * 1000);
/* wait until the read operation is finished */
result = true;
while(sd_get_card_state() != SdSpiStatusOK) {
if(furi_hal_cortex_timer_is_expired(timer)) {
result = false;
break;
}
}
}
furi_hal_sd_spi_handle = NULL;
furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_fast);
return result;
}
static bool sd_device_write(uint32_t* buff, uint32_t sector, uint32_t count) {
bool result = false;
furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_fast);
furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_fast;
if(sd_write_blocks(buff, sector, count, SD_TIMEOUT_MS) == SdSpiStatusOK) {
FuriHalCortexTimer timer = furi_hal_cortex_timer_get(SD_TIMEOUT_MS * 1000);
/* wait until the Write operation is finished */
result = true;
while(sd_get_card_state() != SdSpiStatusOK) {
if(furi_hal_cortex_timer_is_expired(timer)) {
sd_cache_invalidate_all();
result = false;
break;
}
}
}
furi_hal_sd_spi_handle = NULL;
furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_fast);
return result;
}
/**
* @brief Initializes a Drive
* @param pdrv: Physical drive number (0..)
* @retval DSTATUS: Operation status
*/
DSTATUS USER_initialize(BYTE pdrv) {
/* USER CODE BEGIN INIT */
static DSTATUS driver_initialize(BYTE pdrv) {
furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_fast);
furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_fast;
DSTATUS status = User_CheckStatus(pdrv);
DSTATUS status = driver_check_status(pdrv);
furi_hal_sd_spi_handle = NULL;
furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_fast);
return status;
/* USER CODE END INIT */
}
/**
@@ -105,11 +123,9 @@ DSTATUS USER_initialize(BYTE pdrv) {
* @param pdrv: Physical drive number (0..)
* @retval DSTATUS: Operation status
*/
DSTATUS USER_status(BYTE pdrv) {
/* USER CODE BEGIN STATUS */
static DSTATUS driver_status(BYTE pdrv) {
UNUSED(pdrv);
return Stat;
/* USER CODE END STATUS */
}
/**
@@ -120,26 +136,45 @@ DSTATUS USER_status(BYTE pdrv) {
* @param count: Number of sectors to read (1..128)
* @retval DRESULT: Operation result
*/
DRESULT USER_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) {
/* USER CODE BEGIN READ */
static DRESULT driver_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) {
UNUSED(pdrv);
DRESULT res = RES_ERROR;
furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_fast);
furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_fast;
bool result;
bool single_sector = count == 1;
if(BSP_SD_ReadBlocks((uint32_t*)buff, (uint32_t)(sector), count, SD_DATATIMEOUT) == MSD_OK) {
/* wait until the read operation is finished */
while(BSP_SD_GetCardState() != MSD_OK) {
if(single_sector) {
if(sd_cache_get(sector, (uint32_t*)buff)) {
return RES_OK;
}
res = RES_OK;
}
furi_hal_sd_spi_handle = NULL;
furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_fast);
result = sd_device_read((uint32_t*)buff, (uint32_t)(sector), count);
return res;
/* USER CODE END READ */
if(!result) {
uint8_t counter = sd_max_mount_retry_count();
while(result == false && counter > 0 && hal_sd_detect()) {
SdSpiStatus status;
if((counter % 2) == 0) {
// power reset sd card
status = sd_init(true);
} else {
status = sd_init(false);
}
if(status == SdSpiStatusOK) {
result = sd_device_read((uint32_t*)buff, (uint32_t)(sector), count);
}
counter--;
}
}
if(single_sector && result == true) {
sd_cache_put(sector, (uint32_t*)buff);
}
return result ? RES_OK : RES_ERROR;
}
/**
@@ -150,30 +185,36 @@ DRESULT USER_read(BYTE pdrv, BYTE* buff, DWORD sector, UINT count) {
* @param count: Number of sectors to write (1..128)
* @retval DRESULT: Operation result
*/
#if _USE_WRITE == 1
DRESULT USER_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) {
/* USER CODE BEGIN WRITE */
/* USER CODE HERE */
static DRESULT driver_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) {
UNUSED(pdrv);
DRESULT res = RES_ERROR;
bool result;
furi_hal_spi_acquire(&furi_hal_spi_bus_handle_sd_fast);
furi_hal_sd_spi_handle = &furi_hal_spi_bus_handle_sd_fast;
sd_cache_invalidate_range(sector, sector + count);
if(BSP_SD_WriteBlocks((uint32_t*)buff, (uint32_t)(sector), count, SD_DATATIMEOUT) == MSD_OK) {
/* wait until the Write operation is finished */
while(BSP_SD_GetCardState() != MSD_OK) {
result = sd_device_write((uint32_t*)buff, (uint32_t)(sector), count);
if(!result) {
uint8_t counter = sd_max_mount_retry_count();
while(result == false && counter > 0 && hal_sd_detect()) {
SdSpiStatus status;
if((counter % 2) == 0) {
// power reset sd card
status = sd_init(true);
} else {
status = sd_init(false);
}
if(status == SdSpiStatusOK) {
result = sd_device_write((uint32_t*)buff, (uint32_t)(sector), count);
}
counter--;
}
res = RES_OK;
}
furi_hal_sd_spi_handle = NULL;
furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_fast);
return res;
/* USER CODE END WRITE */
return result ? RES_OK : RES_ERROR;
}
#endif /* _USE_WRITE == 1 */
/**
* @brief I/O control operation
@@ -182,12 +223,10 @@ DRESULT USER_write(BYTE pdrv, const BYTE* buff, DWORD sector, UINT count) {
* @param *buff: Buffer to send/receive control data
* @retval DRESULT: Operation result
*/
#if _USE_IOCTL == 1
DRESULT USER_ioctl(BYTE pdrv, BYTE cmd, void* buff) {
/* USER CODE BEGIN IOCTL */
static DRESULT driver_ioctl(BYTE pdrv, BYTE cmd, void* buff) {
UNUSED(pdrv);
DRESULT res = RES_ERROR;
BSP_SD_CardInfo CardInfo;
SD_CardInfo CardInfo;
if(Stat & STA_NOINIT) return RES_NOTRDY;
@@ -202,21 +241,21 @@ DRESULT USER_ioctl(BYTE pdrv, BYTE cmd, void* buff) {
/* Get number of sectors on the disk (DWORD) */
case GET_SECTOR_COUNT:
BSP_SD_GetCardInfo(&CardInfo);
sd_get_card_info(&CardInfo);
*(DWORD*)buff = CardInfo.LogBlockNbr;
res = RES_OK;
break;
/* Get R/W sector size (WORD) */
case GET_SECTOR_SIZE:
BSP_SD_GetCardInfo(&CardInfo);
sd_get_card_info(&CardInfo);
*(WORD*)buff = CardInfo.LogBlockSize;
res = RES_OK;
break;
/* Get erase block size in unit of sector (DWORD) */
case GET_BLOCK_SIZE:
BSP_SD_GetCardInfo(&CardInfo);
sd_get_card_info(&CardInfo);
*(DWORD*)buff = CardInfo.LogBlockSize;
res = RES_OK;
break;
@@ -229,8 +268,4 @@ DRESULT USER_ioctl(BYTE pdrv, BYTE cmd, void* buff) {
furi_hal_spi_release(&furi_hal_spi_bus_handle_sd_fast);
return res;
/* USER CODE END IOCTL */
}
#endif /* _USE_IOCTL == 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+4 -38
View File
@@ -1,48 +1,14 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file user_diskio.h
* @brief This file contains the common defines and functions prototypes for
* the user_diskio driver.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __USER_DISKIO_H
#define __USER_DISKIO_H
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
/* USER CODE BEGIN 0 */
/* Includes ------------------------------------------------------------------*/
#include "stm32_adafruit_sd.h"
#include "sd_spi_io.h"
#include "fatfs/ff_gen_drv.h"
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* Exported functions ------------------------------------------------------- */
extern Diskio_drvTypeDef USER_Driver;
/* USER CODE END 0 */
extern Diskio_drvTypeDef sd_fatfs_driver;
#ifdef __cplusplus
}
#endif
#endif /* __USER_DISKIO_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
#endif
+4 -35
View File
@@ -4,35 +4,24 @@
#include <stm32wbxx_ll_cortex.h>
#include <fatfs.h>
#define TAG "FuriHal"
void furi_hal_init_early() {
furi_hal_cortex_init_early();
furi_hal_clock_init_early();
furi_hal_resources_init_early();
furi_hal_os_init();
furi_hal_spi_init_early();
furi_hal_spi_config_init_early();
furi_hal_i2c_init_early();
furi_hal_light_init();
furi_hal_rtc_init_early();
}
void furi_hal_deinit_early() {
furi_hal_rtc_deinit_early();
furi_hal_i2c_deinit_early();
furi_hal_spi_deinit_early();
furi_hal_spi_config_deinit_early();
furi_hal_resources_deinit_early();
furi_hal_clock_deinit_early();
}
@@ -41,49 +30,29 @@ void furi_hal_init() {
furi_hal_clock_init();
furi_hal_console_init();
furi_hal_rtc_init();
furi_hal_interrupt_init();
furi_hal_flash_init();
furi_hal_resources_init();
FURI_LOG_I(TAG, "GPIO OK");
furi_hal_version_init();
furi_hal_region_init();
furi_hal_spi_init();
furi_hal_spi_config_init();
furi_hal_spi_dma_init();
furi_hal_ibutton_init();
FURI_LOG_I(TAG, "iButton OK");
furi_hal_speaker_init();
FURI_LOG_I(TAG, "Speaker OK");
furi_hal_crypto_init();
furi_hal_i2c_init();
// High Level
furi_hal_power_init();
furi_hal_light_init();
furi_hal_bt_init();
furi_hal_memory_init();
furi_hal_compress_icon_init();
#ifndef FURI_RAM_EXEC
// USB
furi_hal_usb_init();
FURI_LOG_I(TAG, "USB OK");
furi_hal_vibro_init();
furi_hal_subghz_init();
furi_hal_nfc_init();
furi_hal_rfid_init();
#endif
// FatFS driver initialization
MX_FATFS_Init();
FURI_LOG_I(TAG, "FATFS OK");
}
void furi_hal_switch(void* address) {
@@ -1,5 +1,5 @@
#include "furi_hal_bt_hid.h"
#include "furi_hal_usb_hid.h"
#include <furi_hal_bt_hid.h>
#include <furi_hal_usb_hid.h>
#include "usb_hid.h"
#include "dev_info_service.h"
#include "battery_service.h"
@@ -1,4 +1,4 @@
#include "furi_hal_bt_serial.h"
#include <furi_hal_bt_serial.h>
#include "dev_info_service.h"
#include "battery_service.h"
#include "serial_service.h"
@@ -1,264 +0,0 @@
#include <furi_hal_compress.h>
#include <furi.h>
#include <lib/heatshrink/heatshrink_encoder.h>
#include <lib/heatshrink/heatshrink_decoder.h>
#define TAG "FuriHalCompress"
#define FURI_HAL_COMPRESS_ICON_ENCODED_BUFF_SIZE (2 * 512)
#define FURI_HAL_COMPRESS_ICON_DECODED_BUFF_SIZE (1024)
#define FURI_HAL_COMPRESS_EXP_BUFF_SIZE (1 << FURI_HAL_COMPRESS_EXP_BUFF_SIZE_LOG)
typedef struct {
uint8_t is_compressed;
uint8_t reserved;
uint16_t compressed_buff_size;
} FuriHalCompressHeader;
typedef struct {
heatshrink_decoder* decoder;
uint8_t
compress_buff[FURI_HAL_COMPRESS_EXP_BUFF_SIZE + FURI_HAL_COMPRESS_ICON_ENCODED_BUFF_SIZE];
uint8_t decoded_buff[FURI_HAL_COMPRESS_ICON_DECODED_BUFF_SIZE];
} FuriHalCompressIcon;
struct FuriHalCompress {
heatshrink_encoder* encoder;
heatshrink_decoder* decoder;
uint8_t* compress_buff;
uint16_t compress_buff_size;
};
static FuriHalCompressIcon* icon_decoder;
static void furi_hal_compress_reset(FuriHalCompress* compress) {
furi_assert(compress);
heatshrink_encoder_reset(compress->encoder);
heatshrink_decoder_reset(compress->decoder);
memset(compress->compress_buff, 0, compress->compress_buff_size);
}
void furi_hal_compress_icon_init() {
icon_decoder = malloc(sizeof(FuriHalCompressIcon));
icon_decoder->decoder = heatshrink_decoder_alloc(
icon_decoder->compress_buff,
FURI_HAL_COMPRESS_ICON_ENCODED_BUFF_SIZE,
FURI_HAL_COMPRESS_EXP_BUFF_SIZE_LOG,
FURI_HAL_COMPRESS_LOOKAHEAD_BUFF_SIZE_LOG);
heatshrink_decoder_reset(icon_decoder->decoder);
memset(icon_decoder->decoded_buff, 0, sizeof(icon_decoder->decoded_buff));
FURI_LOG_I(TAG, "Init OK");
}
void furi_hal_compress_icon_decode(const uint8_t* icon_data, uint8_t** decoded_buff) {
furi_assert(icon_data);
furi_assert(decoded_buff);
FuriHalCompressHeader* header = (FuriHalCompressHeader*)icon_data;
if(header->is_compressed) {
size_t data_processed = 0;
heatshrink_decoder_sink(
icon_decoder->decoder,
(uint8_t*)&icon_data[4],
header->compressed_buff_size,
&data_processed);
while(1) {
HSD_poll_res res = heatshrink_decoder_poll(
icon_decoder->decoder,
icon_decoder->decoded_buff,
sizeof(icon_decoder->decoded_buff),
&data_processed);
furi_assert((res == HSDR_POLL_EMPTY) || (res == HSDR_POLL_MORE));
if(res != HSDR_POLL_MORE) {
break;
}
}
heatshrink_decoder_reset(icon_decoder->decoder);
memset(icon_decoder->compress_buff, 0, sizeof(icon_decoder->compress_buff));
*decoded_buff = icon_decoder->decoded_buff;
} else {
*decoded_buff = (uint8_t*)&icon_data[1];
}
}
FuriHalCompress* furi_hal_compress_alloc(uint16_t compress_buff_size) {
FuriHalCompress* compress = malloc(sizeof(FuriHalCompress));
compress->compress_buff = malloc(compress_buff_size + FURI_HAL_COMPRESS_EXP_BUFF_SIZE);
compress->encoder = heatshrink_encoder_alloc(
compress->compress_buff,
FURI_HAL_COMPRESS_EXP_BUFF_SIZE_LOG,
FURI_HAL_COMPRESS_LOOKAHEAD_BUFF_SIZE_LOG);
compress->decoder = heatshrink_decoder_alloc(
compress->compress_buff,
compress_buff_size,
FURI_HAL_COMPRESS_EXP_BUFF_SIZE_LOG,
FURI_HAL_COMPRESS_LOOKAHEAD_BUFF_SIZE_LOG);
return compress;
}
void furi_hal_compress_free(FuriHalCompress* compress) {
furi_assert(compress);
heatshrink_encoder_free(compress->encoder);
heatshrink_decoder_free(compress->decoder);
free(compress->compress_buff);
free(compress);
}
bool furi_hal_compress_encode(
FuriHalCompress* compress,
uint8_t* data_in,
size_t data_in_size,
uint8_t* data_out,
size_t data_out_size,
size_t* data_res_size) {
furi_assert(compress);
furi_assert(data_in);
furi_assert(data_in_size);
size_t sink_size = 0;
size_t poll_size = 0;
HSE_sink_res sink_res;
HSE_poll_res poll_res;
HSE_finish_res finish_res;
bool encode_failed = false;
size_t sunk = 0;
size_t res_buff_size = sizeof(FuriHalCompressHeader);
// Sink data to encoding buffer
while((sunk < data_in_size) && !encode_failed) {
sink_res = heatshrink_encoder_sink(
compress->encoder, &data_in[sunk], data_in_size - sunk, &sink_size);
if(sink_res != HSER_SINK_OK) {
encode_failed = true;
break;
}
sunk += sink_size;
do {
poll_res = heatshrink_encoder_poll(
compress->encoder,
&data_out[res_buff_size],
data_out_size - res_buff_size,
&poll_size);
if(poll_res < 0) {
encode_failed = true;
break;
}
res_buff_size += poll_size;
} while(poll_res == HSER_POLL_MORE);
}
// Notify sinking complete and poll encoded data
finish_res = heatshrink_encoder_finish(compress->encoder);
if(finish_res < 0) {
encode_failed = true;
} else {
do {
poll_res = heatshrink_encoder_poll(
compress->encoder,
&data_out[res_buff_size],
data_out_size - 4 - res_buff_size,
&poll_size);
if(poll_res < 0) {
encode_failed = true;
break;
}
res_buff_size += poll_size;
finish_res = heatshrink_encoder_finish(compress->encoder);
} while(finish_res != HSER_FINISH_DONE);
}
bool result = true;
// Write encoded data to output buffer if compression is efficient. Else - write header and original data
if(!encode_failed && (res_buff_size < data_in_size + 1)) {
FuriHalCompressHeader header = {
.is_compressed = 0x01, .reserved = 0x00, .compressed_buff_size = res_buff_size};
memcpy(data_out, &header, sizeof(header));
*data_res_size = res_buff_size;
} else if(data_out_size > data_in_size) {
data_out[0] = 0x00;
memcpy(&data_out[1], data_in, data_in_size);
*data_res_size = data_in_size + 1;
} else {
*data_res_size = 0;
result = false;
}
furi_hal_compress_reset(compress);
return result;
}
bool furi_hal_compress_decode(
FuriHalCompress* compress,
uint8_t* data_in,
size_t data_in_size,
uint8_t* data_out,
size_t data_out_size,
size_t* data_res_size) {
furi_assert(compress);
furi_assert(data_in);
furi_assert(data_out);
furi_assert(data_res_size);
bool result = false;
bool decode_failed = false;
HSD_sink_res sink_res;
HSD_poll_res poll_res;
HSD_finish_res finish_res;
size_t sink_size = 0;
size_t res_buff_size = 0;
size_t poll_size = 0;
FuriHalCompressHeader* header = (FuriHalCompressHeader*)data_in;
if(header->is_compressed) {
// Sink data to decoding buffer
size_t compressed_size = header->compressed_buff_size;
size_t sunk = sizeof(FuriHalCompressHeader);
while(sunk < compressed_size && !decode_failed) {
sink_res = heatshrink_decoder_sink(
compress->decoder, &data_in[sunk], compressed_size - sunk, &sink_size);
if(sink_res < 0) {
decode_failed = true;
break;
}
sunk += sink_size;
do {
poll_res = heatshrink_decoder_poll(
compress->decoder, &data_out[res_buff_size], data_out_size, &poll_size);
if(poll_res < 0) {
decode_failed = true;
break;
}
res_buff_size += poll_size;
} while(poll_res == HSDR_POLL_MORE);
}
// Notify sinking complete and poll decoded data
if(!decode_failed) {
finish_res = heatshrink_decoder_finish(compress->decoder);
if(finish_res < 0) {
decode_failed = true;
} else {
do {
poll_res = heatshrink_decoder_poll(
compress->decoder, &data_out[res_buff_size], data_out_size, &poll_size);
res_buff_size += poll_size;
finish_res = heatshrink_decoder_finish(compress->decoder);
} while(finish_res != HSDR_FINISH_DONE);
}
}
*data_res_size = res_buff_size;
result = !decode_failed;
} else if(data_out_size >= data_in_size - 1) {
memcpy(data_out, &data_in[1], data_in_size);
*data_res_size = data_in_size - 1;
result = true;
} else {
result = false;
}
furi_hal_compress_reset(compress);
return result;
}
@@ -1,4 +1,4 @@
#include "furi_hal_cortex.h"
#include <furi_hal_cortex.h>
#include <stm32wbxx.h>
+17 -16
View File
@@ -1,6 +1,7 @@
#include <furi.h>
#include <furi_hal_gpio.h>
#include <furi_hal_version.h>
#include <furi_hal_resources.h>
#include <stm32wbxx_ll_comp.h>
#define GET_SYSCFG_EXTI_PORT(gpio) \
@@ -224,85 +225,85 @@ static void furi_hal_gpio_int_call(uint16_t pin_num) {
/* Interrupt handlers */
void EXTI0_IRQHandler(void) {
if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_0)) {
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_0);
furi_hal_gpio_int_call(0);
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_0);
}
}
void EXTI1_IRQHandler(void) {
if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_1)) {
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_1);
furi_hal_gpio_int_call(1);
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_1);
}
}
void EXTI2_IRQHandler(void) {
if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_2)) {
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_2);
furi_hal_gpio_int_call(2);
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_2);
}
}
void EXTI3_IRQHandler(void) {
if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_3)) {
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_3);
furi_hal_gpio_int_call(3);
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_3);
}
}
void EXTI4_IRQHandler(void) {
if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_4)) {
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_4);
furi_hal_gpio_int_call(4);
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_4);
}
}
void EXTI9_5_IRQHandler(void) {
if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_5)) {
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_5);
furi_hal_gpio_int_call(5);
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_5);
}
if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_6)) {
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_6);
furi_hal_gpio_int_call(6);
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_6);
}
if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_7)) {
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_7);
furi_hal_gpio_int_call(7);
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_7);
}
if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_8)) {
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_8);
furi_hal_gpio_int_call(8);
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_8);
}
if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_9)) {
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_9);
furi_hal_gpio_int_call(9);
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_9);
}
}
void EXTI15_10_IRQHandler(void) {
if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_10)) {
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_10);
furi_hal_gpio_int_call(10);
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_10);
}
if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_11)) {
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_11);
furi_hal_gpio_int_call(11);
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_11);
}
if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_12)) {
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_12);
furi_hal_gpio_int_call(12);
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_12);
}
if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_13)) {
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_13);
furi_hal_gpio_int_call(13);
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_13);
}
if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_14)) {
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_14);
furi_hal_gpio_int_call(14);
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_14);
}
if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_15)) {
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_15);
furi_hal_gpio_int_call(15);
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_15);
}
}
@@ -1,4 +1,4 @@
#include "furi_hal_i2c_config.h"
#include <furi_hal_i2c_config.h>
#include <furi_hal_resources.h>
#include <furi_hal_version.h>
#include <stm32wbxx_ll_bus.h>
@@ -7,6 +7,7 @@
#include <furi.h>
#define TAG "FuriHalIbutton"
#define FURI_HAL_IBUTTON_TIMER TIM1
#define FURI_HAL_IBUTTON_TIMER_IRQ FuriHalInterruptIdTim1UpTim16
@@ -33,6 +34,8 @@ static void furi_hal_ibutton_emulate_isr() {
void furi_hal_ibutton_init() {
furi_hal_ibutton = malloc(sizeof(FuriHalIbutton));
furi_hal_ibutton->state = FuriHalIbuttonStateIdle;
FURI_LOG_I(TAG, "Init OK");
}
void furi_hal_ibutton_emulate_start(
@@ -89,47 +92,16 @@ void furi_hal_ibutton_emulate_stop() {
}
}
void furi_hal_ibutton_start_drive() {
furi_hal_ibutton_pin_high();
void furi_hal_ibutton_pin_configure() {
furi_hal_gpio_write(&ibutton_gpio, true);
furi_hal_gpio_init(&ibutton_gpio, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow);
}
void furi_hal_ibutton_start_drive_in_isr() {
furi_hal_gpio_init(&ibutton_gpio, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow);
LL_EXTI_ClearFlag_0_31(ibutton_gpio.pin);
}
void furi_hal_ibutton_start_interrupt() {
furi_hal_ibutton_pin_high();
furi_hal_gpio_init(&ibutton_gpio, GpioModeInterruptRiseFall, GpioPullNo, GpioSpeedLow);
}
void furi_hal_ibutton_start_interrupt_in_isr() {
furi_hal_gpio_init(&ibutton_gpio, GpioModeInterruptRiseFall, GpioPullNo, GpioSpeedLow);
LL_EXTI_ClearFlag_0_31(ibutton_gpio.pin);
}
void furi_hal_ibutton_stop() {
furi_hal_ibutton_pin_high();
void furi_hal_ibutton_pin_reset() {
furi_hal_gpio_write(&ibutton_gpio, true);
furi_hal_gpio_init(&ibutton_gpio, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
}
void furi_hal_ibutton_add_interrupt(GpioExtiCallback cb, void* context) {
furi_hal_gpio_add_int_callback(&ibutton_gpio, cb, context);
}
void furi_hal_ibutton_remove_interrupt() {
furi_hal_gpio_remove_int_callback(&ibutton_gpio);
}
void furi_hal_ibutton_pin_low() {
furi_hal_gpio_write(&ibutton_gpio, false);
}
void furi_hal_ibutton_pin_high() {
furi_hal_gpio_write(&ibutton_gpio, true);
}
bool furi_hal_ibutton_pin_get_level() {
return furi_hal_gpio_read(&ibutton_gpio);
void furi_hal_ibutton_pin_write(const bool state) {
furi_hal_gpio_write(&ibutton_gpio, state);
}
@@ -0,0 +1,60 @@
/**
* @file furi_hal_ibutton.h
* iButton HAL API
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*FuriHalIbuttonEmulateCallback)(void* context);
/** Initialize */
void furi_hal_ibutton_init();
/**
* Start emulation timer
* @param period timer period
* @param callback timer callback
* @param context callback context
*/
void furi_hal_ibutton_emulate_start(
uint32_t period,
FuriHalIbuttonEmulateCallback callback,
void* context);
/**
* Update emulation timer period
* @param period new timer period
*/
void furi_hal_ibutton_emulate_set_next(uint32_t period);
/**
* Stop emulation timer
*/
void furi_hal_ibutton_emulate_stop();
/**
* Set the pin to normal mode (open collector), and sets it to float
*/
void furi_hal_ibutton_pin_configure();
/**
* Sets the pin to analog mode, and sets it to float
*/
void furi_hal_ibutton_pin_reset();
/**
* iButton write pin
* @param state true / false
*/
void furi_hal_ibutton_pin_write(const bool state);
#ifdef __cplusplus
}
#endif
@@ -1,4 +1,4 @@
#include "furi_hal_infrared.h"
#include <furi_hal_infrared.h>
#include <core/check.h>
#include "stm32wbxx_ll_dma.h"
#include "sys/_stdint.h"
@@ -28,6 +28,15 @@ const GpioPin gpio_infrared_tx_debug = {.port = GPIOA, .pin = GPIO_PIN_7};
#define INFRARED_TX_CCMR_LOW \
(TIM_CCMR2_OC3PE | LL_TIM_OCMODE_FORCED_INACTIVE) /* Space time - force low */
/* DMA Channels definition */
#define IR_DMA DMA2
#define IR_DMA_CH1_CHANNEL LL_DMA_CHANNEL_1
#define IR_DMA_CH2_CHANNEL LL_DMA_CHANNEL_2
#define IR_DMA_CH1_IRQ FuriHalInterruptIdDma2Ch1
#define IR_DMA_CH2_IRQ FuriHalInterruptIdDma2Ch2
#define IR_DMA_CH1_DEF IR_DMA, IR_DMA_CH1_CHANNEL
#define IR_DMA_CH2_DEF IR_DMA, IR_DMA_CH2_CHANNEL
typedef struct {
FuriHalInfraredRxCaptureCallback capture_callback;
void* capture_context;
@@ -213,15 +222,15 @@ void furi_hal_infrared_async_rx_set_timeout_isr_callback(
}
static void furi_hal_infrared_tx_dma_terminate(void) {
LL_DMA_DisableIT_TC(DMA1, LL_DMA_CHANNEL_1);
LL_DMA_DisableIT_HT(DMA1, LL_DMA_CHANNEL_2);
LL_DMA_DisableIT_TC(DMA1, LL_DMA_CHANNEL_2);
LL_DMA_DisableIT_TC(IR_DMA_CH1_DEF);
LL_DMA_DisableIT_HT(IR_DMA_CH2_DEF);
LL_DMA_DisableIT_TC(IR_DMA_CH2_DEF);
furi_assert(furi_hal_infrared_state == InfraredStateAsyncTxStopInProgress);
LL_DMA_DisableIT_TC(DMA1, LL_DMA_CHANNEL_1);
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_2);
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1);
LL_DMA_DisableIT_TC(IR_DMA_CH1_DEF);
LL_DMA_DisableChannel(IR_DMA_CH2_DEF);
LL_DMA_DisableChannel(IR_DMA_CH1_DEF);
LL_TIM_DisableCounter(TIM1);
FuriStatus status = furi_semaphore_release(infrared_tim_tx.stop_semaphore);
furi_check(status == FuriStatusOk);
@@ -230,7 +239,7 @@ static void furi_hal_infrared_tx_dma_terminate(void) {
static uint8_t furi_hal_infrared_get_current_dma_tx_buffer(void) {
uint8_t buf_num = 0;
uint32_t buffer_adr = LL_DMA_GetMemoryAddress(DMA1, LL_DMA_CHANNEL_2);
uint32_t buffer_adr = LL_DMA_GetMemoryAddress(IR_DMA_CH2_DEF);
if(buffer_adr == (uint32_t)infrared_tim_tx.buffer[0].data) {
buf_num = 0;
} else if(buffer_adr == (uint32_t)infrared_tim_tx.buffer[1].data) {
@@ -242,12 +251,13 @@ static uint8_t furi_hal_infrared_get_current_dma_tx_buffer(void) {
}
static void furi_hal_infrared_tx_dma_polarity_isr() {
if(LL_DMA_IsActiveFlag_TE1(DMA1)) {
LL_DMA_ClearFlag_TE1(DMA1);
#if IR_DMA_CH1_CHANNEL == LL_DMA_CHANNEL_1
if(LL_DMA_IsActiveFlag_TE1(IR_DMA)) {
LL_DMA_ClearFlag_TE1(IR_DMA);
furi_crash(NULL);
}
if(LL_DMA_IsActiveFlag_TC1(DMA1) && LL_DMA_IsEnabledIT_TC(DMA1, LL_DMA_CHANNEL_1)) {
LL_DMA_ClearFlag_TC1(DMA1);
if(LL_DMA_IsActiveFlag_TC1(IR_DMA) && LL_DMA_IsEnabledIT_TC(IR_DMA_CH1_DEF)) {
LL_DMA_ClearFlag_TC1(IR_DMA);
furi_check(
(furi_hal_infrared_state == InfraredStateAsyncTx) ||
@@ -257,25 +267,29 @@ static void furi_hal_infrared_tx_dma_polarity_isr() {
uint8_t next_buf_num = furi_hal_infrared_get_current_dma_tx_buffer();
furi_hal_infrared_tx_dma_set_polarity(next_buf_num, 0);
}
#else
#error Update this code. Would you kindly?
#endif
}
static void furi_hal_infrared_tx_dma_isr() {
if(LL_DMA_IsActiveFlag_TE2(DMA1)) {
LL_DMA_ClearFlag_TE2(DMA1);
#if IR_DMA_CH2_CHANNEL == LL_DMA_CHANNEL_2
if(LL_DMA_IsActiveFlag_TE2(IR_DMA)) {
LL_DMA_ClearFlag_TE2(IR_DMA);
furi_crash(NULL);
}
if(LL_DMA_IsActiveFlag_HT2(DMA1) && LL_DMA_IsEnabledIT_HT(DMA1, LL_DMA_CHANNEL_2)) {
LL_DMA_ClearFlag_HT2(DMA1);
if(LL_DMA_IsActiveFlag_HT2(IR_DMA) && LL_DMA_IsEnabledIT_HT(IR_DMA_CH2_DEF)) {
LL_DMA_ClearFlag_HT2(IR_DMA);
uint8_t buf_num = furi_hal_infrared_get_current_dma_tx_buffer();
uint8_t next_buf_num = !buf_num;
if(infrared_tim_tx.buffer[buf_num].last_packet_end) {
LL_DMA_DisableIT_HT(DMA1, LL_DMA_CHANNEL_2);
LL_DMA_DisableIT_HT(IR_DMA_CH2_DEF);
} else if(
!infrared_tim_tx.buffer[buf_num].packet_end ||
(furi_hal_infrared_state == InfraredStateAsyncTx)) {
furi_hal_infrared_tx_fill_buffer(next_buf_num, 0);
if(infrared_tim_tx.buffer[next_buf_num].last_packet_end) {
LL_DMA_DisableIT_HT(DMA1, LL_DMA_CHANNEL_2);
LL_DMA_DisableIT_HT(IR_DMA_CH2_DEF);
}
} else if(furi_hal_infrared_state == InfraredStateAsyncTxStopReq) {
/* fallthrough */
@@ -283,8 +297,8 @@ static void furi_hal_infrared_tx_dma_isr() {
furi_crash(NULL);
}
}
if(LL_DMA_IsActiveFlag_TC2(DMA1) && LL_DMA_IsEnabledIT_TC(DMA1, LL_DMA_CHANNEL_2)) {
LL_DMA_ClearFlag_TC2(DMA1);
if(LL_DMA_IsActiveFlag_TC2(IR_DMA) && LL_DMA_IsEnabledIT_TC(IR_DMA_CH2_DEF)) {
LL_DMA_ClearFlag_TC2(IR_DMA);
furi_check(
(furi_hal_infrared_state == InfraredStateAsyncTxStopInProgress) ||
(furi_hal_infrared_state == InfraredStateAsyncTxStopReq) ||
@@ -310,6 +324,9 @@ static void furi_hal_infrared_tx_dma_isr() {
infrared_tim_tx.signal_sent_callback(infrared_tim_tx.signal_sent_context);
}
}
#else
#error Update this code. Would you kindly?
#endif
}
static void furi_hal_infrared_configure_tim_pwm_tx(uint32_t freq, float duty_cycle) {
@@ -369,16 +386,19 @@ static void furi_hal_infrared_configure_tim_cmgr2_dma_tx(void) {
dma_config.NbData = 0;
dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM1_UP;
dma_config.Priority = LL_DMA_PRIORITY_VERYHIGH;
LL_DMA_Init(DMA1, LL_DMA_CHANNEL_1, &dma_config);
LL_DMA_Init(IR_DMA_CH1_DEF, &dma_config);
LL_DMA_ClearFlag_TE1(DMA1);
LL_DMA_ClearFlag_TC1(DMA1);
#if IR_DMA_CH1_CHANNEL == LL_DMA_CHANNEL_1
LL_DMA_ClearFlag_TE1(IR_DMA);
LL_DMA_ClearFlag_TC1(IR_DMA);
#else
#error Update this code. Would you kindly?
#endif
LL_DMA_EnableIT_TE(DMA1, LL_DMA_CHANNEL_1);
LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1);
LL_DMA_EnableIT_TE(IR_DMA_CH1_DEF);
LL_DMA_EnableIT_TC(IR_DMA_CH1_DEF);
furi_hal_interrupt_set_isr_ex(
FuriHalInterruptIdDma1Ch1, 4, furi_hal_infrared_tx_dma_polarity_isr, NULL);
furi_hal_interrupt_set_isr_ex(IR_DMA_CH1_IRQ, 4, furi_hal_infrared_tx_dma_polarity_isr, NULL);
}
static void furi_hal_infrared_configure_tim_rcr_dma_tx(void) {
@@ -394,18 +414,21 @@ static void furi_hal_infrared_configure_tim_rcr_dma_tx(void) {
dma_config.NbData = 0;
dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM1_UP;
dma_config.Priority = LL_DMA_PRIORITY_MEDIUM;
LL_DMA_Init(DMA1, LL_DMA_CHANNEL_2, &dma_config);
LL_DMA_Init(IR_DMA_CH2_DEF, &dma_config);
LL_DMA_ClearFlag_TC2(DMA1);
LL_DMA_ClearFlag_HT2(DMA1);
LL_DMA_ClearFlag_TE2(DMA1);
#if IR_DMA_CH2_CHANNEL == LL_DMA_CHANNEL_2
LL_DMA_ClearFlag_TC2(IR_DMA);
LL_DMA_ClearFlag_HT2(IR_DMA);
LL_DMA_ClearFlag_TE2(IR_DMA);
#else
#error Update this code. Would you kindly?
#endif
LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_2);
LL_DMA_EnableIT_HT(DMA1, LL_DMA_CHANNEL_2);
LL_DMA_EnableIT_TE(DMA1, LL_DMA_CHANNEL_2);
LL_DMA_EnableIT_TC(IR_DMA_CH2_DEF);
LL_DMA_EnableIT_HT(IR_DMA_CH2_DEF);
LL_DMA_EnableIT_TE(IR_DMA_CH2_DEF);
furi_hal_interrupt_set_isr_ex(
FuriHalInterruptIdDma1Ch2, 5, furi_hal_infrared_tx_dma_isr, NULL);
furi_hal_interrupt_set_isr_ex(IR_DMA_CH2_IRQ, 5, furi_hal_infrared_tx_dma_isr, NULL);
}
static void furi_hal_infrared_tx_fill_buffer_last(uint8_t buf_num) {
@@ -507,14 +530,14 @@ static void furi_hal_infrared_tx_dma_set_polarity(uint8_t buf_num, uint8_t polar
furi_assert(buffer->polarity != NULL);
FURI_CRITICAL_ENTER();
bool channel_enabled = LL_DMA_IsEnabledChannel(DMA1, LL_DMA_CHANNEL_1);
bool channel_enabled = LL_DMA_IsEnabledChannel(IR_DMA_CH1_DEF);
if(channel_enabled) {
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1);
LL_DMA_DisableChannel(IR_DMA_CH1_DEF);
}
LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_1, (uint32_t)buffer->polarity);
LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_1, buffer->size + polarity_shift);
LL_DMA_SetMemoryAddress(IR_DMA_CH1_DEF, (uint32_t)buffer->polarity);
LL_DMA_SetDataLength(IR_DMA_CH1_DEF, buffer->size + polarity_shift);
if(channel_enabled) {
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);
LL_DMA_EnableChannel(IR_DMA_CH1_DEF);
}
FURI_CRITICAL_EXIT();
}
@@ -527,14 +550,14 @@ static void furi_hal_infrared_tx_dma_set_buffer(uint8_t buf_num) {
/* non-circular mode requires disabled channel before setup */
FURI_CRITICAL_ENTER();
bool channel_enabled = LL_DMA_IsEnabledChannel(DMA1, LL_DMA_CHANNEL_2);
bool channel_enabled = LL_DMA_IsEnabledChannel(IR_DMA_CH2_DEF);
if(channel_enabled) {
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_2);
LL_DMA_DisableChannel(IR_DMA_CH2_DEF);
}
LL_DMA_SetMemoryAddress(DMA1, LL_DMA_CHANNEL_2, (uint32_t)buffer->data);
LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_2, buffer->size);
LL_DMA_SetMemoryAddress(IR_DMA_CH2_DEF, (uint32_t)buffer->data);
LL_DMA_SetDataLength(IR_DMA_CH2_DEF, buffer->size);
if(channel_enabled) {
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_2);
LL_DMA_EnableChannel(IR_DMA_CH2_DEF);
}
FURI_CRITICAL_EXIT();
}
@@ -545,8 +568,8 @@ static void furi_hal_infrared_async_tx_free_resources(void) {
(furi_hal_infrared_state == InfraredStateAsyncTxStopped));
furi_hal_gpio_init(&gpio_infrared_tx, GpioModeOutputOpenDrain, GpioPullDown, GpioSpeedLow);
furi_hal_interrupt_set_isr(FuriHalInterruptIdDma1Ch1, NULL, NULL);
furi_hal_interrupt_set_isr(FuriHalInterruptIdDma1Ch2, NULL, NULL);
furi_hal_interrupt_set_isr(IR_DMA_CH1_IRQ, NULL, NULL);
furi_hal_interrupt_set_isr(IR_DMA_CH2_IRQ, NULL, NULL);
LL_TIM_DeInit(TIM1);
furi_semaphore_free(infrared_tim_tx.stop_semaphore);
@@ -597,8 +620,8 @@ void furi_hal_infrared_async_tx_start(uint32_t freq, float duty_cycle) {
furi_hal_infrared_state = InfraredStateAsyncTx;
LL_TIM_ClearFlag_UPDATE(TIM1);
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_2);
LL_DMA_EnableChannel(IR_DMA_CH1_DEF);
LL_DMA_EnableChannel(IR_DMA_CH2_DEF);
furi_delay_us(5);
LL_TIM_GenerateEvent_UPDATE(TIM1); /* DMA -> TIMx_RCR */
furi_delay_us(5);
@@ -1,5 +1,5 @@
#include "furi_hal_interrupt.h"
#include "furi_hal_os.h"
#include <furi_hal_interrupt.h>
#include <furi_hal_os.h>
#include <furi.h>
@@ -74,6 +74,21 @@ __attribute__((always_inline)) static inline void
NVIC_EnableIRQ(furi_hal_interrupt_irqn[index]);
}
__attribute__((always_inline)) static inline void
furi_hal_interrupt_clear_pending(FuriHalInterruptId index) {
NVIC_ClearPendingIRQ(furi_hal_interrupt_irqn[index]);
}
__attribute__((always_inline)) static inline void
furi_hal_interrupt_get_pending(FuriHalInterruptId index) {
NVIC_GetPendingIRQ(furi_hal_interrupt_irqn[index]);
}
__attribute__((always_inline)) static inline void
furi_hal_interrupt_set_pending(FuriHalInterruptId index) {
NVIC_SetPendingIRQ(furi_hal_interrupt_irqn[index]);
}
__attribute__((always_inline)) static inline void
furi_hal_interrupt_disable(FuriHalInterruptId index) {
NVIC_DisableIRQ(furi_hal_interrupt_irqn[index]);
@@ -123,6 +138,7 @@ void furi_hal_interrupt_set_isr_ex(
// Pre ISR clear
furi_assert(furi_hal_interrupt_isr[index].isr != NULL);
furi_hal_interrupt_disable(index);
furi_hal_interrupt_clear_pending(index);
}
furi_hal_interrupt_isr[index].isr = isr;
@@ -131,6 +147,7 @@ void furi_hal_interrupt_set_isr_ex(
if(isr) {
// Post ISR set
furi_hal_interrupt_clear_pending(index);
furi_hal_interrupt_enable(index, priority);
} else {
// Post ISR clear
@@ -1,5 +1,5 @@
#include <core/common_defines.h>
#include "furi_hal_resources.h"
#include <furi_hal_resources.h>
#include <furi_hal_light.h>
#include <lp5562.h>
#include <stdint.h>
+19 -3
View File
@@ -1,5 +1,5 @@
#include <limits.h>
#include "furi_hal_nfc.h"
#include <furi_hal_nfc.h>
#include <st25r3916.h>
#include <st25r3916_irq.h>
#include <rfal_rf.h>
@@ -24,13 +24,29 @@ FuriEventFlag* event = NULL;
#define FURI_HAL_NFC_UID_INCOMPLETE (0x04)
void furi_hal_nfc_init() {
furi_assert(!event);
event = furi_event_flag_alloc();
ReturnCode ret = rfalNfcInitialize();
if(ret == ERR_NONE) {
furi_hal_nfc_start_sleep();
event = furi_event_flag_alloc();
FURI_LOG_I(TAG, "Init OK");
} else {
FURI_LOG_W(TAG, "Initialization failed, RFAL returned: %d", ret);
FURI_LOG_W(TAG, "Init Failed, RFAL returned: %d", ret);
}
}
void furi_hal_nfc_deinit() {
ReturnCode ret = rfalDeinitialize();
if(ret == ERR_NONE) {
FURI_LOG_I(TAG, "Deinit OK");
} else {
FURI_LOG_W(TAG, "Deinit Failed, RFAL returned: %d", ret);
}
if(event) {
furi_event_flag_free(event);
event = NULL;
}
}
@@ -112,6 +112,10 @@ typedef struct {
*/
void furi_hal_nfc_init();
/** Deinit nfc
*/
void furi_hal_nfc_deinit();
/** Check if nfc worker is busy
*
* @return true if busy
@@ -341,14 +341,14 @@ bool furi_hal_power_is_otg_enabled() {
return ret;
}
float furi_hal_power_get_battery_charging_voltage() {
float furi_hal_power_get_battery_charge_voltage_limit() {
furi_hal_i2c_acquire(&furi_hal_i2c_handle_power);
float ret = (float)bq25896_get_vreg_voltage(&furi_hal_i2c_handle_power) / 1000.0f;
furi_hal_i2c_release(&furi_hal_i2c_handle_power);
return ret;
}
void furi_hal_power_set_battery_charging_voltage(float voltage) {
void furi_hal_power_set_battery_charge_voltage_limit(float voltage) {
furi_hal_i2c_acquire(&furi_hal_i2c_handle_power);
// Adding 0.0005 is necessary because 4.016f is 4.015999794000, which gets truncated
bq25896_set_vreg_voltage(&furi_hal_i2c_handle_power, (uint16_t)(voltage * 1000.0f + 0.0005f));
@@ -486,7 +486,7 @@ void furi_hal_power_info_get(PropertyValueCallback out, char sep, void* context)
property_value_out(&property_context, NULL, 2, "format", "major", "2");
property_value_out(&property_context, NULL, 2, "format", "minor", "1");
} else {
property_value_out(&property_context, NULL, 3, "power", "info", "major", "1");
property_value_out(&property_context, NULL, 3, "power", "info", "major", "2");
property_value_out(&property_context, NULL, 3, "power", "info", "minor", "1");
}
@@ -505,8 +505,10 @@ void furi_hal_power_info_get(PropertyValueCallback out, char sep, void* context)
}
property_value_out(&property_context, NULL, 2, "charge", "state", charge_state);
uint16_t charge_voltage = (uint16_t)(furi_hal_power_get_battery_charging_voltage() * 1000.f);
property_value_out(&property_context, "%u", 2, "charge", "voltage", charge_voltage);
uint16_t charge_voltage_limit =
(uint16_t)(furi_hal_power_get_battery_charge_voltage_limit() * 1000.f);
property_value_out(
&property_context, "%u", 3, "charge", "voltage", "limit", charge_voltage_limit);
uint16_t voltage =
(uint16_t)(furi_hal_power_get_battery_voltage(FuriHalPowerICFuelGauge) * 1000.f);
property_value_out(&property_context, "%u", 2, "battery", "voltage", voltage);
+1 -1
View File
@@ -1,4 +1,4 @@
#include "furi_hal_pwm.h"
#include <furi_hal_pwm.h>
#include <core/check.h>
#include <furi_hal_resources.h>
@@ -1,4 +1,4 @@
#include "furi_hal_random.h"
#include <furi_hal_random.h>
#include <furi.h>
#include <furi_hal.h>
@@ -4,6 +4,8 @@
#include <stm32wbxx_ll_rcc.h>
#include <stm32wbxx_ll_pwr.h>
#define TAG "FuriHalResources"
const GpioPin vibro_gpio = {.port = VIBRO_GPIO_Port, .pin = VIBRO_Pin};
const GpioPin ibutton_gpio = {.port = iBTN_GPIO_Port, .pin = iBTN_Pin};
@@ -62,6 +64,23 @@ const GpioPin periph_power = {.port = GPIOA, .pin = LL_GPIO_PIN_3};
const GpioPin gpio_usb_dm = {.port = GPIOA, .pin = LL_GPIO_PIN_11};
const GpioPin gpio_usb_dp = {.port = GPIOA, .pin = LL_GPIO_PIN_12};
const GpioPinRecord gpio_pins[] = {
{.pin = &gpio_ext_pa7, .name = "PA7", .debug = false},
{.pin = &gpio_ext_pa6, .name = "PA6", .debug = false},
{.pin = &gpio_ext_pa4, .name = "PA4", .debug = false},
{.pin = &gpio_ext_pb3, .name = "PB3", .debug = false},
{.pin = &gpio_ext_pb2, .name = "PB2", .debug = false},
{.pin = &gpio_ext_pc3, .name = "PC3", .debug = false},
{.pin = &gpio_ext_pc1, .name = "PC1", .debug = false},
{.pin = &gpio_ext_pc0, .name = "PC0", .debug = false},
/* Dangerous pins, may damage hardware */
{.pin = &gpio_usart_rx, .name = "PB7", .debug = true},
{.pin = &gpio_speaker, .name = "PB8", .debug = true},
};
const size_t gpio_pins_count = sizeof(gpio_pins) / sizeof(GpioPinRecord);
const InputPin input_pins[] = {
{.gpio = &gpio_button_up, .key = InputKeyUp, .inverted = true, .name = "Up"},
{.gpio = &gpio_button_down, .key = InputKeyDown, .inverted = true, .name = "Down"},
@@ -73,8 +92,18 @@ const InputPin input_pins[] = {
const size_t input_pins_count = sizeof(input_pins) / sizeof(InputPin);
static void furi_hal_resources_init_input_pins(GpioMode mode) {
for(size_t i = 0; i < input_pins_count; i++) {
furi_hal_gpio_init(
input_pins[i].gpio,
mode,
(input_pins[i].inverted) ? GpioPullUp : GpioPullDown,
GpioSpeedLow);
}
}
void furi_hal_resources_init_early() {
furi_hal_gpio_init(&gpio_button_left, GpioModeInput, GpioPullUp, GpioSpeedLow);
furi_hal_resources_init_input_pins(GpioModeInput);
// SD Card stepdown control
furi_hal_gpio_write(&periph_power, 1);
@@ -117,14 +146,12 @@ void furi_hal_resources_init_early() {
}
void furi_hal_resources_deinit_early() {
furi_hal_resources_init_input_pins(GpioModeAnalog);
}
void furi_hal_resources_init() {
// Button pins
for(size_t i = 0; i < input_pins_count; i++) {
furi_hal_gpio_init(
input_pins[i].gpio, GpioModeInterruptRiseFall, GpioPullUp, GpioSpeedLow);
}
furi_hal_resources_init_input_pins(GpioModeInterruptRiseFall);
// Display pins
furi_hal_gpio_init(&gpio_display_rst_n, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow);
@@ -165,4 +192,29 @@ void furi_hal_resources_init() {
NVIC_SetPriority(EXTI15_10_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
NVIC_EnableIRQ(EXTI15_10_IRQn);
FURI_LOG_I(TAG, "Init OK");
}
int32_t furi_hal_resources_get_ext_pin_number(const GpioPin* gpio) {
if(gpio == &gpio_ext_pa7)
return 2;
else if(gpio == &gpio_ext_pa6)
return 3;
else if(gpio == &gpio_ext_pa4)
return 4;
else if(gpio == &gpio_ext_pb3)
return 5;
else if(gpio == &gpio_ext_pb2)
return 6;
else if(gpio == &gpio_ext_pc3)
return 7;
else if(gpio == &gpio_ext_pc1)
return 15;
else if(gpio == &gpio_ext_pc0)
return 16;
else if(gpio == &ibutton_gpio)
return 17;
else
return -1;
}
@@ -38,9 +38,18 @@ typedef struct {
const char* name;
} InputPin;
typedef struct {
const GpioPin* pin;
const char* name;
const bool debug;
} GpioPinRecord;
extern const InputPin input_pins[];
extern const size_t input_pins_count;
extern const GpioPinRecord gpio_pins[];
extern const size_t gpio_pins_count;
extern const GpioPin vibro_gpio;
extern const GpioPin ibutton_gpio;
@@ -207,6 +216,13 @@ void furi_hal_resources_deinit_early();
void furi_hal_resources_init();
/**
* Get a corresponding external connector pin number for a gpio
* @param gpio GpioPin
* @return pin number or -1 if gpio is not on the external connector
*/
int32_t furi_hal_resources_get_ext_pin_number(const GpioPin* gpio);
#ifdef __cplusplus
}
#endif
+34 -22
View File
@@ -21,6 +21,14 @@
#define RFID_CAPTURE_IND_CH LL_TIM_CHANNEL_CH3
#define RFID_CAPTURE_DIR_CH LL_TIM_CHANNEL_CH4
/* DMA Channels definition */
#define RFID_DMA DMA2
#define RFID_DMA_CH1_CHANNEL LL_DMA_CHANNEL_1
#define RFID_DMA_CH2_CHANNEL LL_DMA_CHANNEL_2
#define RFID_DMA_CH1_IRQ FuriHalInterruptIdDma2Ch1
#define RFID_DMA_CH1_DEF RFID_DMA, RFID_DMA_CH1_CHANNEL
#define RFID_DMA_CH2_DEF RFID_DMA, RFID_DMA_CH2_CHANNEL
typedef struct {
FuriHalRfidEmulateCallback callback;
FuriHalRfidDMACallback dma_callback;
@@ -69,7 +77,7 @@ void furi_hal_rfid_init() {
void furi_hal_rfid_pins_reset() {
// ibutton bus disable
furi_hal_ibutton_stop();
furi_hal_ibutton_pin_reset();
// pulldown rfid antenna
furi_hal_gpio_init(&gpio_rfid_carrier_out, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow);
@@ -86,8 +94,8 @@ void furi_hal_rfid_pins_reset() {
void furi_hal_rfid_pins_emulate() {
// ibutton low
furi_hal_ibutton_start_drive();
furi_hal_ibutton_pin_low();
furi_hal_ibutton_pin_configure();
furi_hal_ibutton_pin_write(false);
// pull pin to timer out
furi_hal_gpio_init_ex(
@@ -107,8 +115,8 @@ void furi_hal_rfid_pins_emulate() {
void furi_hal_rfid_pins_read() {
// ibutton low
furi_hal_ibutton_start_drive();
furi_hal_ibutton_pin_low();
furi_hal_ibutton_pin_configure();
furi_hal_ibutton_pin_write(false);
// dont pull rfid antenna
furi_hal_gpio_init(&gpio_nfc_irq_rfid_pull, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow);
@@ -302,15 +310,19 @@ void furi_hal_rfid_tim_read_capture_stop() {
}
static void furi_hal_rfid_dma_isr() {
if(LL_DMA_IsActiveFlag_HT1(DMA1)) {
LL_DMA_ClearFlag_HT1(DMA1);
#if RFID_DMA_CH1_CHANNEL == LL_DMA_CHANNEL_1
if(LL_DMA_IsActiveFlag_HT1(RFID_DMA)) {
LL_DMA_ClearFlag_HT1(RFID_DMA);
furi_hal_rfid->dma_callback(true, furi_hal_rfid->context);
}
if(LL_DMA_IsActiveFlag_TC1(DMA1)) {
LL_DMA_ClearFlag_TC1(DMA1);
if(LL_DMA_IsActiveFlag_TC1(RFID_DMA)) {
LL_DMA_ClearFlag_TC1(RFID_DMA);
furi_hal_rfid->dma_callback(false, furi_hal_rfid->context);
}
#else
#error Update this code. Would you kindly?
#endif
}
void furi_hal_rfid_tim_emulate_dma_start(
@@ -347,8 +359,8 @@ void furi_hal_rfid_tim_emulate_dma_start(
dma_config.NbData = length;
dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM2_UP;
dma_config.Priority = LL_DMA_MODE_NORMAL;
LL_DMA_Init(DMA1, LL_DMA_CHANNEL_1, &dma_config);
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);
LL_DMA_Init(RFID_DMA_CH1_DEF, &dma_config);
LL_DMA_EnableChannel(RFID_DMA_CH1_DEF);
// configure DMA "mem -> CCR3" channel
#if FURI_HAL_RFID_EMULATE_TIMER_CHANNEL == LL_TIM_CHANNEL_CH3
@@ -366,13 +378,13 @@ void furi_hal_rfid_tim_emulate_dma_start(
dma_config.NbData = length;
dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM2_UP;
dma_config.Priority = LL_DMA_MODE_NORMAL;
LL_DMA_Init(DMA1, LL_DMA_CHANNEL_2, &dma_config);
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_2);
LL_DMA_Init(RFID_DMA_CH2_DEF, &dma_config);
LL_DMA_EnableChannel(RFID_DMA_CH2_DEF);
// attach interrupt to one of DMA channels
furi_hal_interrupt_set_isr(FuriHalInterruptIdDma1Ch1, furi_hal_rfid_dma_isr, NULL);
LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1);
LL_DMA_EnableIT_HT(DMA1, LL_DMA_CHANNEL_1);
furi_hal_interrupt_set_isr(RFID_DMA_CH1_IRQ, furi_hal_rfid_dma_isr, NULL);
LL_DMA_EnableIT_TC(RFID_DMA_CH1_DEF);
LL_DMA_EnableIT_HT(RFID_DMA_CH1_DEF);
// start
LL_TIM_EnableAllOutputs(FURI_HAL_RFID_EMULATE_TIMER);
@@ -385,14 +397,14 @@ void furi_hal_rfid_tim_emulate_dma_stop() {
LL_TIM_DisableCounter(FURI_HAL_RFID_EMULATE_TIMER);
LL_TIM_DisableAllOutputs(FURI_HAL_RFID_EMULATE_TIMER);
furi_hal_interrupt_set_isr(FuriHalInterruptIdDma1Ch1, NULL, NULL);
LL_DMA_DisableIT_TC(DMA1, LL_DMA_CHANNEL_1);
LL_DMA_DisableIT_HT(DMA1, LL_DMA_CHANNEL_1);
furi_hal_interrupt_set_isr(RFID_DMA_CH1_IRQ, NULL, NULL);
LL_DMA_DisableIT_TC(RFID_DMA_CH1_DEF);
LL_DMA_DisableIT_HT(RFID_DMA_CH1_DEF);
FURI_CRITICAL_ENTER();
LL_DMA_DeInit(DMA1, LL_DMA_CHANNEL_1);
LL_DMA_DeInit(DMA1, LL_DMA_CHANNEL_2);
LL_DMA_DeInit(RFID_DMA_CH1_DEF);
LL_DMA_DeInit(RFID_DMA_CH2_DEF);
LL_TIM_DeInit(FURI_HAL_RFID_EMULATE_TIMER);
FURI_CRITICAL_EXIT();
@@ -471,4 +483,4 @@ void COMP_IRQHandler() {
(LL_COMP_ReadOutputLevel(COMP1) == LL_COMP_OUTPUT_LEVEL_LOW),
furi_hal_rfid_comp_callback_context);
}
}
}
+5 -8
View File
@@ -1,24 +1,21 @@
#include "furi_hal_sd.h"
#include <furi_hal_sd.h>
#include <stm32wbxx_ll_gpio.h>
#include <furi.h>
#include <furi_hal.h>
void hal_sd_detect_init(void) {
// low speed input with pullup
LL_GPIO_SetPinMode(SD_CD_GPIO_Port, SD_CD_Pin, LL_GPIO_MODE_INPUT);
LL_GPIO_SetPinSpeed(SD_CD_GPIO_Port, SD_CD_Pin, LL_GPIO_SPEED_FREQ_LOW);
LL_GPIO_SetPinPull(SD_CD_GPIO_Port, SD_CD_Pin, LL_GPIO_PULL_UP);
furi_hal_gpio_init(&gpio_sdcard_cd, GpioModeInput, GpioPullUp, GpioSpeedLow);
}
void hal_sd_detect_set_low(void) {
// low speed input with pullup
LL_GPIO_SetPinMode(SD_CD_GPIO_Port, SD_CD_Pin, LL_GPIO_MODE_OUTPUT);
LL_GPIO_SetPinOutputType(SD_CD_GPIO_Port, SD_CD_Pin, LL_GPIO_OUTPUT_OPENDRAIN);
LL_GPIO_ResetOutputPin(SD_CD_GPIO_Port, SD_CD_Pin);
furi_hal_gpio_init_simple(&gpio_sdcard_cd, GpioModeOutputOpenDrain);
furi_hal_gpio_write(&gpio_sdcard_cd, 0);
}
bool hal_sd_detect(void) {
bool result = !(LL_GPIO_IsInputPinSet(SD_CD_GPIO_Port, SD_CD_Pin));
bool result = !furi_hal_gpio_read(&gpio_sdcard_cd);
return result;
}
+226 -25
View File
@@ -1,36 +1,31 @@
#include "furi_hal_spi.h"
#include "furi_hal_resources.h"
#include <furi_hal_power.h>
#include <stdbool.h>
#include <string.h>
#include <furi.h>
#include <furi_hal_spi.h>
#include <furi_hal_resources.h>
#include <furi_hal_power.h>
#include <furi_hal_interrupt.h>
#include <stm32wbxx_ll_dma.h>
#include <stm32wbxx_ll_spi.h>
#include <stm32wbxx_ll_utils.h>
#include <stm32wbxx_ll_cortex.h>
#define TAG "FuriHalSpi"
void furi_hal_spi_init_early() {
furi_hal_spi_bus_init(&furi_hal_spi_bus_d);
furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_display);
}
#define SPI_DMA DMA2
#define SPI_DMA_RX_CHANNEL LL_DMA_CHANNEL_3
#define SPI_DMA_TX_CHANNEL LL_DMA_CHANNEL_4
#define SPI_DMA_RX_IRQ FuriHalInterruptIdDma2Ch3
#define SPI_DMA_TX_IRQ FuriHalInterruptIdDma2Ch4
#define SPI_DMA_RX_DEF SPI_DMA, SPI_DMA_RX_CHANNEL
#define SPI_DMA_TX_DEF SPI_DMA, SPI_DMA_TX_CHANNEL
void furi_hal_spi_deinit_early() {
furi_hal_spi_bus_handle_deinit(&furi_hal_spi_bus_handle_display);
furi_hal_spi_bus_deinit(&furi_hal_spi_bus_d);
}
// For simplicity, I assume that only one SPI DMA transaction can occur at a time.
static FuriSemaphore* spi_dma_lock = NULL;
static FuriSemaphore* spi_dma_completed = NULL;
void furi_hal_spi_init() {
furi_hal_spi_bus_init(&furi_hal_spi_bus_r);
furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_subghz);
furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_nfc);
furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_sd_fast);
furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_sd_slow);
FURI_LOG_I(TAG, "Init OK");
void furi_hal_spi_dma_init() {
spi_dma_lock = furi_semaphore_alloc(1, 1);
spi_dma_completed = furi_semaphore_alloc(1, 1);
}
void furi_hal_spi_bus_init(FuriHalSpiBus* bus) {
@@ -108,7 +103,7 @@ bool furi_hal_spi_bus_rx(
bool furi_hal_spi_bus_tx(
FuriHalSpiBusHandle* handle,
uint8_t* buffer,
const uint8_t* buffer,
size_t size,
uint32_t timeout) {
furi_assert(handle);
@@ -133,7 +128,7 @@ bool furi_hal_spi_bus_tx(
bool furi_hal_spi_bus_trx(
FuriHalSpiBusHandle* handle,
uint8_t* tx_buffer,
const uint8_t* tx_buffer,
uint8_t* rx_buffer,
size_t size,
uint32_t timeout) {
@@ -173,3 +168,209 @@ bool furi_hal_spi_bus_trx(
return ret;
}
static void spi_dma_isr() {
#if SPI_DMA_RX_CHANNEL == LL_DMA_CHANNEL_3
if(LL_DMA_IsActiveFlag_TC3(SPI_DMA) && LL_DMA_IsEnabledIT_TC(SPI_DMA_RX_DEF)) {
LL_DMA_ClearFlag_TC3(SPI_DMA);
furi_check(furi_semaphore_release(spi_dma_completed) == FuriStatusOk);
}
#else
#error Update this code. Would you kindly?
#endif
#if SPI_DMA_TX_CHANNEL == LL_DMA_CHANNEL_4
if(LL_DMA_IsActiveFlag_TC4(SPI_DMA) && LL_DMA_IsEnabledIT_TC(SPI_DMA_TX_DEF)) {
LL_DMA_ClearFlag_TC4(SPI_DMA);
furi_check(furi_semaphore_release(spi_dma_completed) == FuriStatusOk);
}
#else
#error Update this code. Would you kindly?
#endif
}
bool furi_hal_spi_bus_trx_dma(
FuriHalSpiBusHandle* handle,
uint8_t* tx_buffer,
uint8_t* rx_buffer,
size_t size,
uint32_t timeout_ms) {
furi_assert(handle);
furi_assert(handle->bus->current_handle == handle);
furi_assert(size > 0);
// If scheduler is not running, use blocking mode
if(xTaskGetSchedulerState() != taskSCHEDULER_RUNNING) {
return furi_hal_spi_bus_trx(handle, tx_buffer, rx_buffer, size, timeout_ms);
}
// Lock DMA
furi_check(furi_semaphore_acquire(spi_dma_lock, FuriWaitForever) == FuriStatusOk);
const uint32_t dma_dummy_u32 = 0xFFFFFFFF;
bool ret = true;
SPI_TypeDef* spi = handle->bus->spi;
uint32_t dma_rx_req;
uint32_t dma_tx_req;
if(spi == SPI1) {
dma_rx_req = LL_DMAMUX_REQ_SPI1_RX;
dma_tx_req = LL_DMAMUX_REQ_SPI1_TX;
} else if(spi == SPI2) {
dma_rx_req = LL_DMAMUX_REQ_SPI2_RX;
dma_tx_req = LL_DMAMUX_REQ_SPI2_TX;
} else {
furi_crash(NULL);
}
if(rx_buffer == NULL) {
// Only TX mode, do not use RX channel
LL_DMA_InitTypeDef dma_config = {0};
dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (spi->DR);
dma_config.MemoryOrM2MDstAddress = (uint32_t)tx_buffer;
dma_config.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH;
dma_config.Mode = LL_DMA_MODE_NORMAL;
dma_config.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT;
dma_config.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT;
dma_config.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_BYTE;
dma_config.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_BYTE;
dma_config.NbData = size;
dma_config.PeriphRequest = dma_tx_req;
dma_config.Priority = LL_DMA_PRIORITY_MEDIUM;
LL_DMA_Init(SPI_DMA_TX_DEF, &dma_config);
#if SPI_DMA_TX_CHANNEL == LL_DMA_CHANNEL_4
LL_DMA_ClearFlag_TC4(SPI_DMA);
#else
#error Update this code. Would you kindly?
#endif
furi_hal_interrupt_set_isr(SPI_DMA_TX_IRQ, spi_dma_isr, NULL);
bool dma_tx_was_enabled = LL_SPI_IsEnabledDMAReq_TX(spi);
if(!dma_tx_was_enabled) {
LL_SPI_EnableDMAReq_TX(spi);
}
// acquire semaphore before enabling DMA
furi_check(furi_semaphore_acquire(spi_dma_completed, timeout_ms) == FuriStatusOk);
LL_DMA_EnableIT_TC(SPI_DMA_TX_DEF);
LL_DMA_EnableChannel(SPI_DMA_TX_DEF);
// and wait for it to be released (DMA transfer complete)
if(furi_semaphore_acquire(spi_dma_completed, timeout_ms) != FuriStatusOk) {
ret = false;
FURI_LOG_E(TAG, "DMA timeout\r\n");
}
// release semaphore, because we are using it as a flag
furi_semaphore_release(spi_dma_completed);
LL_DMA_DisableIT_TC(SPI_DMA_TX_DEF);
LL_DMA_DisableChannel(SPI_DMA_TX_DEF);
if(!dma_tx_was_enabled) {
LL_SPI_DisableDMAReq_TX(spi);
}
furi_hal_interrupt_set_isr(SPI_DMA_TX_IRQ, NULL, NULL);
LL_DMA_DeInit(SPI_DMA_TX_DEF);
} else {
// TRX or RX mode, use both channels
uint32_t tx_mem_increase_mode;
if(tx_buffer == NULL) {
// RX mode, use dummy data instead of TX buffer
tx_buffer = (uint8_t*)&dma_dummy_u32;
tx_mem_increase_mode = LL_DMA_PERIPH_NOINCREMENT;
} else {
tx_mem_increase_mode = LL_DMA_MEMORY_INCREMENT;
}
LL_DMA_InitTypeDef dma_config = {0};
dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (spi->DR);
dma_config.MemoryOrM2MDstAddress = (uint32_t)tx_buffer;
dma_config.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH;
dma_config.Mode = LL_DMA_MODE_NORMAL;
dma_config.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT;
dma_config.MemoryOrM2MDstIncMode = tx_mem_increase_mode;
dma_config.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_BYTE;
dma_config.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_BYTE;
dma_config.NbData = size;
dma_config.PeriphRequest = dma_tx_req;
dma_config.Priority = LL_DMA_PRIORITY_MEDIUM;
LL_DMA_Init(SPI_DMA_TX_DEF, &dma_config);
dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (spi->DR);
dma_config.MemoryOrM2MDstAddress = (uint32_t)rx_buffer;
dma_config.Direction = LL_DMA_DIRECTION_PERIPH_TO_MEMORY;
dma_config.Mode = LL_DMA_MODE_NORMAL;
dma_config.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT;
dma_config.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT;
dma_config.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_BYTE;
dma_config.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_BYTE;
dma_config.NbData = size;
dma_config.PeriphRequest = dma_rx_req;
dma_config.Priority = LL_DMA_PRIORITY_MEDIUM;
LL_DMA_Init(SPI_DMA_RX_DEF, &dma_config);
#if SPI_DMA_RX_CHANNEL == LL_DMA_CHANNEL_3
LL_DMA_ClearFlag_TC3(SPI_DMA);
#else
#error Update this code. Would you kindly?
#endif
furi_hal_interrupt_set_isr(SPI_DMA_RX_IRQ, spi_dma_isr, NULL);
bool dma_tx_was_enabled = LL_SPI_IsEnabledDMAReq_TX(spi);
bool dma_rx_was_enabled = LL_SPI_IsEnabledDMAReq_RX(spi);
if(!dma_tx_was_enabled) {
LL_SPI_EnableDMAReq_TX(spi);
}
if(!dma_rx_was_enabled) {
LL_SPI_EnableDMAReq_RX(spi);
}
// acquire semaphore before enabling DMA
furi_check(furi_semaphore_acquire(spi_dma_completed, timeout_ms) == FuriStatusOk);
LL_DMA_EnableIT_TC(SPI_DMA_RX_DEF);
LL_DMA_EnableChannel(SPI_DMA_RX_DEF);
LL_DMA_EnableChannel(SPI_DMA_TX_DEF);
// and wait for it to be released (DMA transfer complete)
if(furi_semaphore_acquire(spi_dma_completed, timeout_ms) != FuriStatusOk) {
ret = false;
FURI_LOG_E(TAG, "DMA timeout\r\n");
}
// release semaphore, because we are using it as a flag
furi_semaphore_release(spi_dma_completed);
LL_DMA_DisableIT_TC(SPI_DMA_RX_DEF);
LL_DMA_DisableChannel(SPI_DMA_TX_DEF);
LL_DMA_DisableChannel(SPI_DMA_RX_DEF);
if(!dma_tx_was_enabled) {
LL_SPI_DisableDMAReq_TX(spi);
}
if(!dma_rx_was_enabled) {
LL_SPI_DisableDMAReq_RX(spi);
}
furi_hal_interrupt_set_isr(SPI_DMA_RX_IRQ, NULL, NULL);
LL_DMA_DeInit(SPI_DMA_TX_DEF);
LL_DMA_DeInit(SPI_DMA_RX_DEF);
}
furi_hal_spi_bus_end_txrx(handle, timeout_ms);
furi_check(furi_semaphore_release(spi_dma_lock) == FuriStatusOk);
return ret;
}
@@ -1,5 +1,9 @@
#include <furi_hal_spi_config.h>
#include <furi_hal_resources.h>
#include <furi_hal_spi.h>
#include <furi.h>
#define TAG "FuriHalSpiConfig"
/* SPI Presets */
@@ -72,6 +76,27 @@ const LL_SPI_InitTypeDef furi_hal_spi_preset_1edge_low_2m = {
FuriMutex* furi_hal_spi_bus_r_mutex = NULL;
void furi_hal_spi_config_init_early() {
furi_hal_spi_bus_init(&furi_hal_spi_bus_d);
furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_display);
}
void furi_hal_spi_config_deinit_early() {
furi_hal_spi_bus_handle_deinit(&furi_hal_spi_bus_handle_display);
furi_hal_spi_bus_deinit(&furi_hal_spi_bus_d);
}
void furi_hal_spi_config_init() {
furi_hal_spi_bus_init(&furi_hal_spi_bus_r);
furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_subghz);
furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_nfc);
furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_sd_fast);
furi_hal_spi_bus_handle_init(&furi_hal_spi_bus_handle_sd_slow);
FURI_LOG_I(TAG, "Init OK");
}
static void furi_hal_spi_bus_r_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) {
if(event == FuriHalSpiBusEventInit) {
furi_hal_spi_bus_r_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
+41 -23
View File
@@ -1,5 +1,5 @@
#include "furi_hal_subghz.h"
#include "furi_hal_subghz_configs.h"
#include <furi_hal_subghz.h>
#include <furi_hal_subghz_configs.h>
#include <furi_hal_region.h>
#include <furi_hal_version.h>
@@ -18,6 +18,14 @@
static uint32_t furi_hal_subghz_debug_gpio_buff[2];
/* DMA Channels definition */
#define SUBGHZ_DMA DMA2
#define SUBGHZ_DMA_CH1_CHANNEL LL_DMA_CHANNEL_1
#define SUBGHZ_DMA_CH2_CHANNEL LL_DMA_CHANNEL_2
#define SUBGHZ_DMA_CH1_IRQ FuriHalInterruptIdDma2Ch1
#define SUBGHZ_DMA_CH1_DEF SUBGHZ_DMA, SUBGHZ_DMA_CH1_CHANNEL
#define SUBGHZ_DMA_CH2_DEF SUBGHZ_DMA, SUBGHZ_DMA_CH2_CHANNEL
typedef struct {
volatile SubGhzState state;
volatile SubGhzRegulation regulation;
@@ -430,7 +438,7 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void*
TIM_InitStruct.Prescaler = 64 - 1;
TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
TIM_InitStruct.Autoreload = 0x7FFFFFFE;
TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV4;
TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV4; // Clock division for capture filter
LL_TIM_Init(TIM2, &TIM_InitStruct);
// Timer: advanced
@@ -447,13 +455,15 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void*
LL_TIM_IC_SetActiveInput(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_ACTIVEINPUT_INDIRECTTI);
LL_TIM_IC_SetPrescaler(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_ICPSC_DIV1);
LL_TIM_IC_SetPolarity(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_IC_POLARITY_FALLING);
LL_TIM_IC_SetFilter(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_IC_FILTER_FDIV1);
// Timer: channel 2 direct
LL_TIM_IC_SetActiveInput(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_ACTIVEINPUT_DIRECTTI);
LL_TIM_IC_SetPrescaler(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_ICPSC_DIV1);
LL_TIM_IC_SetPolarity(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_IC_POLARITY_RISING);
LL_TIM_IC_SetFilter(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_IC_FILTER_FDIV32_N8);
LL_TIM_IC_SetFilter(
TIM2,
LL_TIM_CHANNEL_CH2,
LL_TIM_IC_FILTER_FDIV32_N8); // Capture filter: 1/(64000000/64/4/32*8) = 16us
// ISR setup
furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, furi_hal_subghz_capture_ISR, NULL);
@@ -473,6 +483,9 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void*
// Switch to RX
furi_hal_subghz_rx();
//Clear the variable after the end of the session
furi_hal_subghz_capture_delta_duration = 0;
}
void furi_hal_subghz_stop_async_rx() {
@@ -525,8 +538,8 @@ static void furi_hal_subghz_async_tx_refill(uint32_t* buffer, size_t samples) {
*buffer = 0;
buffer++;
samples--;
LL_DMA_DisableIT_HT(DMA1, LL_DMA_CHANNEL_1);
LL_DMA_DisableIT_TC(DMA1, LL_DMA_CHANNEL_1);
LL_DMA_DisableIT_HT(SUBGHZ_DMA_CH1_DEF);
LL_DMA_DisableIT_TC(SUBGHZ_DMA_CH1_DEF);
LL_TIM_EnableIT_UPDATE(TIM2);
break;
} else {
@@ -567,17 +580,22 @@ static void furi_hal_subghz_async_tx_refill(uint32_t* buffer, size_t samples) {
static void furi_hal_subghz_async_tx_dma_isr() {
furi_assert(furi_hal_subghz.state == SubGhzStateAsyncTx);
if(LL_DMA_IsActiveFlag_HT1(DMA1)) {
LL_DMA_ClearFlag_HT1(DMA1);
#if SUBGHZ_DMA_CH1_CHANNEL == LL_DMA_CHANNEL_1
if(LL_DMA_IsActiveFlag_HT1(SUBGHZ_DMA)) {
LL_DMA_ClearFlag_HT1(SUBGHZ_DMA);
furi_hal_subghz_async_tx_refill(
furi_hal_subghz_async_tx.buffer, API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF);
}
if(LL_DMA_IsActiveFlag_TC1(DMA1)) {
LL_DMA_ClearFlag_TC1(DMA1);
if(LL_DMA_IsActiveFlag_TC1(SUBGHZ_DMA)) {
LL_DMA_ClearFlag_TC1(SUBGHZ_DMA);
furi_hal_subghz_async_tx_refill(
furi_hal_subghz_async_tx.buffer + API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF,
API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF);
}
#else
#error Update this code. Would you kindly?
#endif
}
static void furi_hal_subghz_async_tx_timer_isr() {
@@ -586,7 +604,7 @@ static void furi_hal_subghz_async_tx_timer_isr() {
if(LL_TIM_GetAutoReload(TIM2) == 0) {
if(furi_hal_subghz.state == SubGhzStateAsyncTx) {
furi_hal_subghz.state = SubGhzStateAsyncTxLast;
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1);
LL_DMA_DisableChannel(SUBGHZ_DMA_CH1_DEF);
} else if(furi_hal_subghz.state == SubGhzStateAsyncTxLast) {
furi_hal_subghz.state = SubGhzStateAsyncTxEnd;
//forcibly pulls the pin to the ground so that there is no carrier
@@ -634,11 +652,11 @@ bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void*
dma_config.NbData = API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL;
dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM2_UP;
dma_config.Priority = LL_DMA_MODE_NORMAL;
LL_DMA_Init(DMA1, LL_DMA_CHANNEL_1, &dma_config);
furi_hal_interrupt_set_isr(FuriHalInterruptIdDma1Ch1, furi_hal_subghz_async_tx_dma_isr, NULL);
LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1);
LL_DMA_EnableIT_HT(DMA1, LL_DMA_CHANNEL_1);
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);
LL_DMA_Init(SUBGHZ_DMA_CH1_DEF, &dma_config);
furi_hal_interrupt_set_isr(SUBGHZ_DMA_CH1_IRQ, furi_hal_subghz_async_tx_dma_isr, NULL);
LL_DMA_EnableIT_TC(SUBGHZ_DMA_CH1_DEF);
LL_DMA_EnableIT_HT(SUBGHZ_DMA_CH1_DEF);
LL_DMA_EnableChannel(SUBGHZ_DMA_CH1_DEF);
// Configure TIM2
LL_TIM_InitTypeDef TIM_InitStruct = {0};
@@ -696,9 +714,9 @@ bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void*
dma_config.NbData = 2;
dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM2_UP;
dma_config.Priority = LL_DMA_PRIORITY_VERYHIGH;
LL_DMA_Init(DMA1, LL_DMA_CHANNEL_2, &dma_config);
LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_2, 2);
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_2);
LL_DMA_Init(SUBGHZ_DMA_CH2_DEF, &dma_config);
LL_DMA_SetDataLength(SUBGHZ_DMA_CH2_DEF, 2);
LL_DMA_EnableChannel(SUBGHZ_DMA_CH2_DEF);
}
return true;
@@ -726,16 +744,16 @@ void furi_hal_subghz_stop_async_tx() {
furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, NULL, NULL);
// Deinitialize DMA
LL_DMA_DeInit(DMA1, LL_DMA_CHANNEL_1);
LL_DMA_DeInit(SUBGHZ_DMA_CH1_DEF);
furi_hal_interrupt_set_isr(FuriHalInterruptIdDma1Ch1, NULL, NULL);
furi_hal_interrupt_set_isr(SUBGHZ_DMA_CH1_IRQ, NULL, NULL);
// Deinitialize GPIO
furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
// Stop debug
if(furi_hal_subghz_stop_debug()) {
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_2);
LL_DMA_DisableChannel(SUBGHZ_DMA_CH2_DEF);
}
FURI_CRITICAL_EXIT();
@@ -0,0 +1,6 @@
#pragma once
#include <furi_hal_subghz.h>
#include <furi_hal_ibutton.h>
#include <furi_hal_rfid.h>
#include <furi_hal_nfc.h>
+13 -6
View File
@@ -44,7 +44,8 @@ static void furi_hal_usart_init(uint32_t baud) {
while(!LL_USART_IsActiveFlag_TEACK(USART1) || !LL_USART_IsActiveFlag_REACK(USART1))
;
LL_USART_EnableIT_RXNE_RXFNE(USART1);
LL_USART_DisableIT_ERROR(USART1);
NVIC_SetPriority(USART1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
}
@@ -79,8 +80,8 @@ static void furi_hal_lpuart_init(uint32_t baud) {
;
furi_hal_uart_set_br(FuriHalUartIdLPUART1, baud);
LL_LPUART_DisableIT_ERROR(LPUART1);
LL_LPUART_EnableIT_RXNE_RXFNE(LPUART1);
NVIC_SetPriority(LPUART1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
}
@@ -190,19 +191,25 @@ void furi_hal_uart_set_irq_cb(
void (*cb)(UartIrqEvent ev, uint8_t data, void* ctx),
void* ctx) {
if(cb == NULL) {
if(ch == FuriHalUartIdUSART1)
if(ch == FuriHalUartIdUSART1) {
NVIC_DisableIRQ(USART1_IRQn);
else if(ch == FuriHalUartIdLPUART1)
LL_USART_DisableIT_RXNE_RXFNE(USART1);
} else if(ch == FuriHalUartIdLPUART1) {
NVIC_DisableIRQ(LPUART1_IRQn);
LL_LPUART_DisableIT_RXNE_RXFNE(LPUART1);
}
irq_cb[ch] = cb;
irq_ctx[ch] = ctx;
} else {
irq_ctx[ch] = ctx;
irq_cb[ch] = cb;
if(ch == FuriHalUartIdUSART1)
if(ch == FuriHalUartIdUSART1) {
NVIC_EnableIRQ(USART1_IRQn);
else if(ch == FuriHalUartIdLPUART1)
LL_USART_EnableIT_RXNE_RXFNE(USART1);
} else if(ch == FuriHalUartIdLPUART1) {
NVIC_EnableIRQ(LPUART1_IRQn);
LL_LPUART_EnableIT_RXNE_RXFNE(LPUART1);
}
}
}
+4 -4
View File
@@ -1,6 +1,6 @@
#include "furi_hal_version.h"
#include "furi_hal_usb_i.h"
#include "furi_hal_usb.h"
#include <furi_hal_version.h>
#include <furi_hal_usb_i.h>
#include <furi_hal_usb.h>
#include <furi_hal_power.h>
#include <stm32wbxx_ll_pwr.h>
#include <furi.h>
@@ -340,7 +340,7 @@ static void usb_process_mode_start(FuriHalUsbInterface* interface, void* context
}
static void usb_process_mode_change(FuriHalUsbInterface* interface, void* context) {
if(interface != usb.interface) {
if((interface != usb.interface) || (context != usb.interface_context)) {
if(usb.enabled) {
// Disable current interface
susp_evt(&udev, 0, 0);
@@ -1,7 +1,7 @@
#include "furi_hal_version.h"
#include "furi_hal_usb_i.h"
#include "furi_hal_usb.h"
#include "furi_hal_usb_cdc.h"
#include <furi_hal_version.h>
#include <furi_hal_usb_i.h>
#include <furi_hal_usb.h>
#include <furi_hal_usb_cdc.h>
#include <furi.h>
#include "usb.h"
+137 -121
View File
@@ -1,35 +1,29 @@
#include "furi_hal_version.h"
#include "furi_hal_usb_i.h"
#include "furi_hal_usb.h"
#include "furi_hal_usb_hid.h"
#include <furi_hal_version.h>
#include <furi_hal_usb_i.h>
#include <furi_hal_usb.h>
#include <furi_hal_usb_hid.h>
#include <furi.h>
#include "usb.h"
#include "usb_hid.h"
#define HID_EP_IN 0x81
#define HID_EP_OUT 0x01
#define HID_EP_SZ 0x10
#define HID_KB_MAX_KEYS 6
#define HID_CONSUMER_MAX_KEYS 2
#define HID_INTERVAL 2
#define HID_VID_DEFAULT 0x046D
#define HID_PID_DEFAULT 0xC529
struct HidIadDescriptor {
struct usb_iad_descriptor hid_iad;
struct HidIntfDescriptor {
struct usb_interface_descriptor hid;
struct usb_hid_descriptor hid_desc;
struct usb_endpoint_descriptor hid_ep_in;
struct usb_endpoint_descriptor hid_ep_out;
};
struct HidConfigDescriptor {
struct usb_config_descriptor config;
struct HidIadDescriptor iad_0;
struct HidIntfDescriptor intf_0;
} __attribute__((packed));
enum HidReportId {
@@ -38,78 +32,98 @@ enum HidReportId {
ReportIdConsumer = 3,
};
/* HID report: keyboard+mouse */
/* HID report descriptor: keyboard + mouse + consumer control */
static const uint8_t hid_report_desc[] = {
// clang-format off
HID_USAGE_PAGE(HID_PAGE_DESKTOP),
HID_USAGE(HID_DESKTOP_KEYBOARD),
HID_COLLECTION(HID_APPLICATION_COLLECTION),
HID_REPORT_ID(ReportIdKeyboard),
HID_USAGE_PAGE(HID_DESKTOP_KEYPAD),
HID_USAGE_MINIMUM(HID_KEYBOARD_L_CTRL),
HID_USAGE_MAXIMUM(HID_KEYBOARD_R_GUI),
HID_LOGICAL_MINIMUM(0),
HID_LOGICAL_MAXIMUM(1),
HID_REPORT_SIZE(1),
HID_REPORT_COUNT(8),
HID_INPUT(HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
HID_REPORT_COUNT(1),
HID_REPORT_SIZE(8),
HID_INPUT(HID_IOF_CONSTANT | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
HID_USAGE_PAGE(HID_PAGE_LED),
HID_REPORT_COUNT(8),
HID_REPORT_SIZE(1),
HID_USAGE_MINIMUM(1),
HID_USAGE_MAXIMUM(8),
HID_OUTPUT(HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
HID_REPORT_COUNT(HID_KB_MAX_KEYS),
HID_REPORT_SIZE(8),
HID_LOGICAL_MINIMUM(0),
HID_LOGICAL_MAXIMUM(101),
HID_USAGE_PAGE(HID_DESKTOP_KEYPAD),
HID_USAGE_MINIMUM(0),
HID_USAGE_MAXIMUM(101),
HID_INPUT(HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
HID_REPORT_ID(ReportIdKeyboard),
// Keyboard report
HID_USAGE_PAGE(HID_DESKTOP_KEYPAD),
HID_USAGE_MINIMUM(HID_KEYBOARD_L_CTRL),
HID_USAGE_MAXIMUM(HID_KEYBOARD_R_GUI),
HID_LOGICAL_MINIMUM(0),
HID_LOGICAL_MAXIMUM(1),
HID_REPORT_SIZE(1),
HID_REPORT_COUNT(8),
// Input - Modifier keys byte
HID_INPUT(HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
HID_REPORT_COUNT(1),
HID_REPORT_SIZE(8),
// Input - Reserved byte
HID_INPUT(HID_IOF_CONSTANT | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
HID_USAGE_PAGE(HID_PAGE_LED),
HID_REPORT_COUNT(8),
HID_REPORT_SIZE(1),
HID_USAGE_MINIMUM(1),
HID_USAGE_MAXIMUM(8),
// Output - LEDs
HID_OUTPUT(HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
HID_REPORT_COUNT(HID_KB_MAX_KEYS),
HID_REPORT_SIZE(8),
HID_LOGICAL_MINIMUM(0),
HID_LOGICAL_MAXIMUM(101),
HID_USAGE_PAGE(HID_DESKTOP_KEYPAD),
HID_USAGE_MINIMUM(0),
HID_USAGE_MAXIMUM(101),
// Input - Key codes
HID_INPUT(HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
HID_END_COLLECTION,
HID_USAGE_PAGE(HID_PAGE_DESKTOP),
HID_USAGE(HID_DESKTOP_MOUSE),
HID_COLLECTION(HID_APPLICATION_COLLECTION),
HID_USAGE(HID_DESKTOP_POINTER),
HID_COLLECTION(HID_PHYSICAL_COLLECTION),
HID_REPORT_ID(ReportIdMouse),
HID_USAGE_PAGE(HID_PAGE_BUTTON),
HID_USAGE_MINIMUM(1),
HID_USAGE_MAXIMUM(3),
HID_LOGICAL_MINIMUM(0),
HID_LOGICAL_MAXIMUM(1),
HID_REPORT_COUNT(3),
HID_REPORT_SIZE(1),
HID_INPUT(HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
HID_REPORT_SIZE(1),
HID_REPORT_COUNT(5),
HID_INPUT(HID_IOF_CONSTANT | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
HID_USAGE_PAGE(HID_PAGE_DESKTOP),
HID_USAGE(HID_DESKTOP_X),
HID_USAGE(HID_DESKTOP_Y),
HID_USAGE(HID_DESKTOP_WHEEL),
HID_LOGICAL_MINIMUM(-127),
HID_LOGICAL_MAXIMUM(127),
HID_REPORT_SIZE(8),
HID_REPORT_COUNT(3),
HID_INPUT(HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
HID_END_COLLECTION,
HID_USAGE(HID_DESKTOP_POINTER),
HID_COLLECTION(HID_PHYSICAL_COLLECTION),
HID_REPORT_ID(ReportIdMouse),
// Mouse report
HID_USAGE_PAGE(HID_PAGE_BUTTON),
HID_USAGE_MINIMUM(1),
HID_USAGE_MAXIMUM(3),
HID_LOGICAL_MINIMUM(0),
HID_LOGICAL_MAXIMUM(1),
HID_REPORT_COUNT(3),
HID_REPORT_SIZE(1),
// Input - Mouse keys
HID_INPUT(HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
HID_REPORT_SIZE(1),
HID_REPORT_COUNT(5),
// Input - Mouse keys padding
HID_INPUT(HID_IOF_CONSTANT | HID_IOF_VARIABLE | HID_IOF_ABSOLUTE),
HID_USAGE_PAGE(HID_PAGE_DESKTOP),
HID_USAGE(HID_DESKTOP_X),
HID_USAGE(HID_DESKTOP_Y),
HID_USAGE(HID_DESKTOP_WHEEL),
HID_LOGICAL_MINIMUM(-127),
HID_LOGICAL_MAXIMUM(127),
HID_REPORT_SIZE(8),
HID_REPORT_COUNT(3),
// Input - Mouse movement data (x, y, scroll)
HID_INPUT(HID_IOF_DATA | HID_IOF_VARIABLE | HID_IOF_RELATIVE),
HID_END_COLLECTION,
HID_END_COLLECTION,
HID_USAGE_PAGE(HID_PAGE_CONSUMER),
HID_USAGE(HID_CONSUMER_CONTROL),
HID_COLLECTION(HID_APPLICATION_COLLECTION),
HID_REPORT_ID(ReportIdConsumer),
HID_LOGICAL_MINIMUM(0),
HID_RI_LOGICAL_MAXIMUM(16, 0x3FF),
HID_USAGE_MINIMUM(0),
HID_RI_USAGE_MAXIMUM(16, 0x3FF),
HID_REPORT_COUNT(HID_CONSUMER_MAX_KEYS),
HID_REPORT_SIZE(16),
HID_INPUT(HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
HID_REPORT_ID(ReportIdConsumer),
// Consumer report
HID_LOGICAL_MINIMUM(0),
HID_RI_LOGICAL_MAXIMUM(16, 0x3FF),
HID_USAGE_MINIMUM(0),
HID_RI_USAGE_MAXIMUM(16, 0x3FF),
HID_REPORT_COUNT(HID_CONSUMER_MAX_KEYS),
HID_REPORT_SIZE(16),
// Input - Consumer control keys
HID_INPUT(HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
HID_END_COLLECTION,
// clang-format on
};
/* Device descriptor */
@@ -117,9 +131,9 @@ static struct usb_device_descriptor hid_device_desc = {
.bLength = sizeof(struct usb_device_descriptor),
.bDescriptorType = USB_DTYPE_DEVICE,
.bcdUSB = VERSION_BCD(2, 0, 0),
.bDeviceClass = USB_CLASS_IAD,
.bDeviceSubClass = USB_SUBCLASS_IAD,
.bDeviceProtocol = USB_PROTO_IAD,
.bDeviceClass = USB_CLASS_PER_INTERFACE,
.bDeviceSubClass = USB_SUBCLASS_NONE,
.bDeviceProtocol = USB_PROTO_NONE,
.bMaxPacketSize0 = USB_EP0_SIZE,
.idVendor = HID_VID_DEFAULT,
.idProduct = HID_PID_DEFAULT,
@@ -143,29 +157,18 @@ static const struct HidConfigDescriptor hid_cfg_desc = {
.bmAttributes = USB_CFG_ATTR_RESERVED | USB_CFG_ATTR_SELFPOWERED,
.bMaxPower = USB_CFG_POWER_MA(100),
},
.iad_0 =
.intf_0 =
{
.hid_iad =
{
.bLength = sizeof(struct usb_iad_descriptor),
.bDescriptorType = USB_DTYPE_INTERFASEASSOC,
.bFirstInterface = 0,
.bInterfaceCount = 1,
.bFunctionClass = USB_CLASS_PER_INTERFACE,
.bFunctionSubClass = USB_SUBCLASS_NONE,
.bFunctionProtocol = USB_PROTO_NONE,
.iFunction = NO_DESCRIPTOR,
},
.hid =
{
.bLength = sizeof(struct usb_interface_descriptor),
.bDescriptorType = USB_DTYPE_INTERFACE,
.bInterfaceNumber = 0,
.bAlternateSetting = 0,
.bNumEndpoints = 2,
.bNumEndpoints = 1,
.bInterfaceClass = USB_CLASS_HID,
.bInterfaceSubClass = USB_HID_SUBCLASS_NONBOOT,
.bInterfaceProtocol = USB_HID_PROTO_NONBOOT,
.bInterfaceSubClass = USB_HID_SUBCLASS_BOOT,
.bInterfaceProtocol = USB_HID_PROTO_KEYBOARD,
.iInterface = NO_DESCRIPTOR,
},
.hid_desc =
@@ -187,15 +190,6 @@ static const struct HidConfigDescriptor hid_cfg_desc = {
.wMaxPacketSize = HID_EP_SZ,
.bInterval = HID_INTERVAL,
},
.hid_ep_out =
{
.bLength = sizeof(struct usb_endpoint_descriptor),
.bDescriptorType = USB_DTYPE_ENDPOINT,
.bEndpointAddress = HID_EP_OUT,
.bmAttributes = USB_EPTYPE_INTERRUPT,
.wMaxPacketSize = HID_EP_SZ,
.bInterval = HID_INTERVAL,
},
},
};
@@ -209,9 +203,11 @@ struct HidReportMouse {
struct HidReportKB {
uint8_t report_id;
uint8_t mods;
uint8_t reserved;
uint8_t btn[HID_KB_MAX_KEYS];
struct {
uint8_t mods;
uint8_t reserved;
uint8_t btn[HID_KB_MAX_KEYS];
} boot;
} __attribute__((packed));
struct HidReportConsumer {
@@ -259,6 +255,7 @@ static bool hid_connected = false;
static HidStateCallback callback;
static void* cb_ctx;
static uint8_t led_state;
static bool boot_protocol = false;
bool furi_hal_hid_is_connected() {
return hid_connected;
@@ -283,31 +280,31 @@ void furi_hal_hid_set_state_callback(HidStateCallback cb, void* ctx) {
bool furi_hal_hid_kb_press(uint16_t button) {
for(uint8_t key_nb = 0; key_nb < HID_KB_MAX_KEYS; key_nb++) {
if(hid_report.keyboard.btn[key_nb] == 0) {
hid_report.keyboard.btn[key_nb] = button & 0xFF;
if(hid_report.keyboard.boot.btn[key_nb] == 0) {
hid_report.keyboard.boot.btn[key_nb] = button & 0xFF;
break;
}
}
hid_report.keyboard.mods |= (button >> 8);
hid_report.keyboard.boot.mods |= (button >> 8);
return hid_send_report(ReportIdKeyboard);
}
bool furi_hal_hid_kb_release(uint16_t button) {
for(uint8_t key_nb = 0; key_nb < HID_KB_MAX_KEYS; key_nb++) {
if(hid_report.keyboard.btn[key_nb] == (button & 0xFF)) {
hid_report.keyboard.btn[key_nb] = 0;
if(hid_report.keyboard.boot.btn[key_nb] == (button & 0xFF)) {
hid_report.keyboard.boot.btn[key_nb] = 0;
break;
}
}
hid_report.keyboard.mods &= ~(button >> 8);
hid_report.keyboard.boot.mods &= ~(button >> 8);
return hid_send_report(ReportIdKeyboard);
}
bool furi_hal_hid_kb_release_all() {
for(uint8_t key_nb = 0; key_nb < HID_KB_MAX_KEYS; key_nb++) {
hid_report.keyboard.btn[key_nb] = 0;
hid_report.keyboard.boot.btn[key_nb] = 0;
}
hid_report.keyboard.mods = 0;
hid_report.keyboard.boot.mods = 0;
return hid_send_report(ReportIdKeyboard);
}
@@ -437,27 +434,35 @@ static void hid_on_suspend(usbd_device* dev) {
static bool hid_send_report(uint8_t report_id) {
if((hid_semaphore == NULL) || (hid_connected == false)) return false;
if((boot_protocol == true) && (report_id != ReportIdKeyboard)) return false;
furi_check(furi_semaphore_acquire(hid_semaphore, FuriWaitForever) == FuriStatusOk);
if(hid_connected == true) {
if(hid_connected == false) {
return false;
}
if(boot_protocol == true) {
usbd_ep_write(
usb_dev, HID_EP_IN, &hid_report.keyboard.boot, sizeof(hid_report.keyboard.boot));
} else {
if(report_id == ReportIdKeyboard)
usbd_ep_write(usb_dev, HID_EP_IN, &hid_report.keyboard, sizeof(hid_report.keyboard));
else if(report_id == ReportIdMouse)
usbd_ep_write(usb_dev, HID_EP_IN, &hid_report.mouse, sizeof(hid_report.mouse));
else if(report_id == ReportIdConsumer)
usbd_ep_write(usb_dev, HID_EP_IN, &hid_report.consumer, sizeof(hid_report.consumer));
return true;
}
return false;
return true;
}
static void hid_txrx_ep_callback(usbd_device* dev, uint8_t event, uint8_t ep) {
UNUSED(dev);
if(event == usbd_evt_eptx) {
furi_semaphore_release(hid_semaphore);
} else if(boot_protocol == true) {
usbd_ep_read(usb_dev, ep, &led_state, sizeof(led_state));
} else {
struct HidReportLED leds;
usbd_ep_read(usb_dev, ep, &leds, 2);
usbd_ep_read(usb_dev, ep, &leds, sizeof(leds));
led_state = leds.led_state;
}
}
@@ -467,18 +472,15 @@ static usbd_respond hid_ep_config(usbd_device* dev, uint8_t cfg) {
switch(cfg) {
case 0:
/* deconfiguring device */
usbd_ep_deconfig(dev, HID_EP_OUT);
usbd_ep_deconfig(dev, HID_EP_IN);
usbd_reg_endpoint(dev, HID_EP_OUT, 0);
usbd_reg_endpoint(dev, HID_EP_IN, 0);
return usbd_ack;
case 1:
/* configuring device */
usbd_ep_config(dev, HID_EP_IN, USB_EPTYPE_INTERRUPT, HID_EP_SZ);
usbd_ep_config(dev, HID_EP_OUT, USB_EPTYPE_INTERRUPT, HID_EP_SZ);
usbd_reg_endpoint(dev, HID_EP_IN, hid_txrx_ep_callback);
usbd_reg_endpoint(dev, HID_EP_OUT, hid_txrx_ep_callback);
usbd_ep_write(dev, HID_EP_IN, 0, 0);
boot_protocol = false; /* BIOS will SET_PROTOCOL if it wants this */
return usbd_ack;
default:
return usbd_fail;
@@ -496,8 +498,21 @@ static usbd_respond hid_control(usbd_device* dev, usbd_ctlreq* req, usbd_rqc_cal
case USB_HID_SETIDLE:
return usbd_ack;
case USB_HID_GETREPORT:
dev->status.data_ptr = &hid_report;
dev->status.data_count = sizeof(hid_report);
if(boot_protocol == true) {
dev->status.data_ptr = &hid_report.keyboard.boot;
dev->status.data_count = sizeof(hid_report.keyboard.boot);
} else {
dev->status.data_ptr = &hid_report;
dev->status.data_count = sizeof(hid_report);
}
return usbd_ack;
case USB_HID_SETPROTOCOL:
if(req->wValue == 0)
boot_protocol = true;
else if(req->wValue == 1)
boot_protocol = false;
else
return usbd_fail;
return usbd_ack;
default:
return usbd_fail;
@@ -508,10 +523,11 @@ static usbd_respond hid_control(usbd_device* dev, usbd_ctlreq* req, usbd_rqc_cal
req->wIndex == 0 && req->bRequest == USB_STD_GET_DESCRIPTOR) {
switch(req->wValue >> 8) {
case USB_DTYPE_HID:
dev->status.data_ptr = (uint8_t*)&(hid_cfg_desc.iad_0.hid_desc);
dev->status.data_count = sizeof(hid_cfg_desc.iad_0.hid_desc);
dev->status.data_ptr = (uint8_t*)&(hid_cfg_desc.intf_0.hid_desc);
dev->status.data_count = sizeof(hid_cfg_desc.intf_0.hid_desc);
return usbd_ack;
case USB_DTYPE_HID_REPORT:
boot_protocol = false; /* BIOS does not read this */
dev->status.data_ptr = (uint8_t*)hid_report_desc;
dev->status.data_count = sizeof(hid_report_desc);
return usbd_ack;
@@ -1,7 +1,7 @@
#include "furi_hal_version.h"
#include "furi_hal_usb_i.h"
#include "furi_hal_usb_hid_u2f.h"
#include "furi_hal_usb.h"
#include <furi_hal_version.h>
#include <furi_hal_usb_i.h>
#include <furi_hal_usb_hid_u2f.h>
#include <furi_hal_usb.h>
#include <furi.h>
#include "usb.h"
#include "usb_hid.h"
@@ -195,14 +195,6 @@ void furi_hal_version_init() {
FURI_LOG_I(TAG, "Init OK");
}
bool furi_hal_version_do_i_belong_here() {
return furi_hal_version_get_hw_target() == 7;
}
const char* furi_hal_version_get_model_name() {
return "Flipper Zero";
}
FuriHalVersionOtpVersion furi_hal_version_get_otp_version() {
if(*(uint64_t*)FURI_HAL_VERSION_OTP_ADDRESS == 0xFFFFFFFF) {
return FuriHalVersionOtpVersionEmpty;
@@ -0,0 +1,21 @@
#include <furi_hal_version.h>
bool furi_hal_version_do_i_belong_here() {
return (furi_hal_version_get_hw_target() == 7) || (furi_hal_version_get_hw_target() == 0);
}
const char* furi_hal_version_get_model_name() {
return "Flipper Zero";
}
const char* furi_hal_version_get_model_code() {
return "FZ.1";
}
const char* furi_hal_version_get_fcc_id() {
return "2A2V6-FZ";
}
const char* furi_hal_version_get_ic_id() {
return "27624-FZ";
}
@@ -8,6 +8,8 @@ void flipper_boot_update_exec();
void flipper_boot_dfu_exec();
void flipper_boot_recovery_exec();
#ifdef __cplusplus
}
#endif
@@ -4,10 +4,11 @@
#include <alt_boot.h>
#include <u8g2_glue.h>
#include <assets_icons.h>
#include <toolbox/compress.h>
void flipper_boot_dfu_show_splash() {
// Initialize
furi_hal_compress_icon_init();
CompressIcon* compress_icon = compress_icon_alloc();
u8g2_t* fb = malloc(sizeof(u8g2_t));
memset(fb, 0, sizeof(u8g2_t));
@@ -15,13 +16,15 @@ void flipper_boot_dfu_show_splash() {
u8g2_InitDisplay(fb);
u8g2_SetDrawColor(fb, 0x01);
uint8_t* splash_data = NULL;
furi_hal_compress_icon_decode(icon_get_data(&I_DFU_128x50), &splash_data);
compress_icon_decode(compress_icon, icon_get_data(&I_DFU_128x50), &splash_data);
u8g2_DrawXBM(fb, 0, 64 - 50, 128, 50, splash_data);
u8g2_SetFont(fb, u8g2_font_helvB08_tr);
u8g2_DrawStr(fb, 2, 8, "Update & Recovery Mode");
u8g2_DrawStr(fb, 2, 21, "DFU Started");
u8g2_SetPowerSave(fb, 0);
u8g2_SendBuffer(fb);
compress_icon_free(compress_icon);
}
void flipper_boot_dfu_exec() {
@@ -49,6 +49,10 @@ int main() {
// But if we do, abandon to avoid bootloops
furi_hal_rtc_set_boot_mode(FuriHalRtcBootModeNormal);
furi_hal_power_reset();
} else if(!furi_hal_gpio_read(&gpio_button_up)) {
furi_hal_light_sequence("rgb WR");
flipper_boot_recovery_exec();
furi_hal_power_reset();
} else {
furi_hal_light_sequence("rgb G");
furi_thread_start(main_thread);
+64
View File
@@ -0,0 +1,64 @@
#include <furi.h>
#include <furi_hal.h>
#include <flipper.h>
#include <alt_boot.h>
#include <u8g2_glue.h>
#include <assets_icons.h>
#include <toolbox/compress.h>
#define COUNTER_VALUE (136U)
static void flipper_boot_recovery_draw_splash(u8g2_t* fb, size_t progress) {
if(progress < COUNTER_VALUE) {
// Fill the progress bar while the progress is going down
u8g2_SetDrawColor(fb, 0x01);
u8g2_DrawRFrame(fb, 59, 41, 69, 8, 2);
size_t width = (COUNTER_VALUE - progress) * 68 / COUNTER_VALUE;
u8g2_DrawBox(fb, 60, 42, width, 6);
} else {
u8g2_SetDrawColor(fb, 0x00);
u8g2_DrawRBox(fb, 59, 41, 69, 8, 2);
}
u8g2_SendBuffer(fb);
}
void flipper_boot_recovery_exec() {
u8g2_t* fb = malloc(sizeof(u8g2_t));
u8g2_Setup_st756x_flipper(fb, U8G2_R0, u8x8_hw_spi_stm32, u8g2_gpio_and_delay_stm32);
u8g2_InitDisplay(fb);
CompressIcon* compress_icon = compress_icon_alloc();
uint8_t* splash_data = NULL;
compress_icon_decode(compress_icon, icon_get_data(&I_Erase_pin_128x64), &splash_data);
u8g2_ClearBuffer(fb);
u8g2_SetDrawColor(fb, 0x01);
// Draw the recovery picture
u8g2_DrawXBM(fb, 0, 0, 128, 64, splash_data);
u8g2_SendBuffer(fb);
u8g2_SetPowerSave(fb, 0);
compress_icon_free(compress_icon);
size_t counter = COUNTER_VALUE;
while(counter) {
if(!furi_hal_gpio_read(&gpio_button_down)) {
break;
}
if(!furi_hal_gpio_read(&gpio_button_right)) {
counter--;
} else {
counter = COUNTER_VALUE;
}
flipper_boot_recovery_draw_splash(fb, counter);
}
if(!counter) {
furi_hal_rtc_set_flag(FuriHalRtcFlagFactoryReset);
furi_hal_rtc_set_pin_fails(0);
furi_hal_rtc_reset_flag(FuriHalRtcFlagLock);
}
}
@@ -23,8 +23,8 @@ static FATFS* pfs = NULL;
}
static bool flipper_update_mount_sd() {
for(int i = 0; i < BSP_SD_MaxMountRetryCount(); ++i) {
if(BSP_SD_Init((i % 2) == 0) != MSD_OK) {
for(int i = 0; i < sd_max_mount_retry_count(); ++i) {
if(sd_init((i % 2) == 0) != SdSpiStatusOK) {
/* Next attempt will be without card reset, let it settle */
furi_delay_ms(1000);
continue;
@@ -42,9 +42,9 @@ static bool flipper_update_init() {
furi_hal_rtc_init();
furi_hal_interrupt_init();
furi_hal_spi_init();
furi_hal_spi_config_init();
MX_FATFS_Init();
fatfs_init();
if(!hal_sd_detect()) {
return false;
}
+1 -1
View File
@@ -1,7 +1,7 @@
/**
*****************************************************************************
**
** File : stm32wb55xx_flash_cm4.ld
** File : stm32wb55xx_flash.ld
**
** Abstract : System Workbench Minimal System calls file
**
+1 -1
View File
@@ -1,7 +1,7 @@
/**
*****************************************************************************
**
** File : stm32wb55xx_flash_cm4.ld
** File : stm32wb55xx_ram_fw.ld
**
** Abstract : System Workbench Minimal System calls file
**
+46
View File
@@ -0,0 +1,46 @@
{
"include_paths": [
"ble_glue",
"fatfs",
"furi_hal",
"inc"
],
"sdk_header_paths": [
"../furi_hal_include",
"furi_hal",
"platform_specific"
],
"startup_script": "startup_stm32wb55xx_cm4.s",
"linker_script_flash": "stm32wb55xx_flash.ld",
"linker_script_ram": "stm32wb55xx_ram_fw.ld",
"linker_script_app": "application_ext.ld",
"sdk_symbols": "api_symbols.csv",
"linker_dependencies": [
"print",
"flipper7",
"furi",
"freertos",
"stm32cubewb",
"hwdrivers",
"fatfs",
"littlefs",
"subghz",
"flipperformat",
"toolbox",
"nfc",
"microtar",
"usb_stm32",
"st25rfal002",
"infrared",
"appframe",
"assets",
"one_wire",
"ibutton",
"misc",
"mbedtls",
"lfrfid",
"flipper_application",
"flipperformat",
"toolbox"
]
}
+27 -31
View File
@@ -10,37 +10,33 @@ template <unsigned int N>
struct STOP_EXTERNING_ME {};
#endif
#include "furi_hal_cortex.h"
#include "furi_hal_clock.h"
#include "furi_hal_crypto.h"
#include "furi_hal_console.h"
#include "furi_hal_debug.h"
#include "furi_hal_os.h"
#include "furi_hal_sd.h"
#include "furi_hal_i2c.h"
#include "furi_hal_resources.h"
#include "furi_hal_region.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_subghz.h"
#include "furi_hal_vibro.h"
#include "furi_hal_ibutton.h"
#include "furi_hal_rfid.h"
#include "furi_hal_nfc.h"
#include "furi_hal_usb.h"
#include "furi_hal_usb_hid.h"
#include "furi_hal_compress.h"
#include "furi_hal_uart.h"
#include "furi_hal_info.h"
#include "furi_hal_random.h"
#include <furi_hal_cortex.h>
#include <furi_hal_clock.h>
#include <furi_hal_crypto.h>
#include <furi_hal_console.h>
#include <furi_hal_debug.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_uart.h>
#include <furi_hal_info.h>
#include <furi_hal_random.h>
#include <furi_hal_target_hw.h>
#ifdef __cplusplus
extern "C" {
@@ -12,7 +12,7 @@
#include <ble_glue.h>
#include <ble_app.h>
#include "furi_hal_bt_serial.h"
#include <furi_hal_bt_serial.h>
#define FURI_HAL_BT_STACK_VERSION_MAJOR (1)
#define FURI_HAL_BT_STACK_VERSION_MINOR (12)
@@ -1,87 +0,0 @@
/**
* @file furi_hal_compress.h
* LZSS based compression HAL API
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/** Defines encoder and decoder window size */
#define FURI_HAL_COMPRESS_EXP_BUFF_SIZE_LOG (8)
/** Defines encoder and decoder lookahead buffer size */
#define FURI_HAL_COMPRESS_LOOKAHEAD_BUFF_SIZE_LOG (4)
/** FuriHalCompress control structure */
typedef struct FuriHalCompress FuriHalCompress;
/** Initialize icon decoder
*/
void furi_hal_compress_icon_init();
/** Icon decoder
*
* @param icon_data pointer to icon data
* @param decoded_buff pointer to decoded buffer
*/
void furi_hal_compress_icon_decode(const uint8_t* icon_data, uint8_t** decoded_buff);
/** Allocate encoder and decoder
*
* @param compress_buff_size size of decoder and encoder buffer to allocate
*
* @return FuriHalCompress instance
*/
FuriHalCompress* furi_hal_compress_alloc(uint16_t compress_buff_size);
/** Free encoder and decoder
*
* @param compress FuriHalCompress instance
*/
void furi_hal_compress_free(FuriHalCompress* compress);
/** Encode data
*
* @param compress FuriHalCompress instance
* @param data_in pointer to input data
* @param data_in_size size of input data
* @param data_out maximum size of output data
* @param data_res_size pointer to result output data size
*
* @return true on success
*/
bool furi_hal_compress_encode(
FuriHalCompress* compress,
uint8_t* data_in,
size_t data_in_size,
uint8_t* data_out,
size_t data_out_size,
size_t* data_res_size);
/** Decode data
*
* @param compress FuriHalCompress instance
* @param data_in pointer to input data
* @param data_in_size size of input data
* @param data_out maximum size of output data
* @param data_res_size pointer to result output data size
*
* @return true on success
*/
bool furi_hal_compress_decode(
FuriHalCompress* compress,
uint8_t* data_in,
size_t data_in_size,
uint8_t* data_out,
size_t data_out_size,
size_t* data_res_size);
#ifdef __cplusplus
}
#endif
@@ -1,88 +0,0 @@
/**
* @file furi_hal_ibutton.h
* iButton HAL API
*/
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include "furi_hal_gpio.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*FuriHalIbuttonEmulateCallback)(void* context);
/** Initialize */
void furi_hal_ibutton_init();
void furi_hal_ibutton_emulate_start(
uint32_t period,
FuriHalIbuttonEmulateCallback callback,
void* context);
void furi_hal_ibutton_emulate_set_next(uint32_t period);
void furi_hal_ibutton_emulate_stop();
/**
* Sets the pin to normal mode (open collector), and sets it to float
*/
void furi_hal_ibutton_start_drive();
/**
* Sets the pin to normal mode (open collector), and clears pin EXTI interrupt.
* Used in EXTI interrupt context.
*/
void furi_hal_ibutton_start_drive_in_isr();
/**
* Sets the pin to interrupt mode (EXTI interrupt on rise or fall), and sets it to float
*/
void furi_hal_ibutton_start_interrupt();
/**
* Sets the pin to interrupt mode (EXTI interrupt on rise or fall), and clears pin EXTI interrupt.
* Used in EXTI interrupt context.
*/
void furi_hal_ibutton_start_interrupt_in_isr();
/**
* Sets the pin to analog mode, and sets it to float
*/
void furi_hal_ibutton_stop();
/**
* Attach interrupt callback to iButton pin
* @param cb callback
* @param context context
*/
void furi_hal_ibutton_add_interrupt(GpioExtiCallback cb, void* context);
/**
* Remove interrupt callback from iButton pin
*/
void furi_hal_ibutton_remove_interrupt();
/**
* Sets the pin to low
*/
void furi_hal_ibutton_pin_low();
/**
* Sets the pin to high (float in iButton pin modes)
*/
void furi_hal_ibutton_pin_high();
/**
* Get pin level
* @return true if level is high
* @return false if level is low
*/
bool furi_hal_ibutton_pin_get_level();
#ifdef __cplusplus
}
#endif
@@ -121,21 +121,21 @@ void furi_hal_power_check_otg_status();
*/
bool furi_hal_power_is_otg_enabled();
/** Get battery charging voltage in V
/** Get battery charge voltage limit in V
*
* @return voltage in V
*/
float furi_hal_power_get_battery_charging_voltage();
float furi_hal_power_get_battery_charge_voltage_limit();
/** Set battery charging voltage in V
/** Set battery charge voltage limit in V
*
* Invalid values will be clamped to the nearest valid value.
* 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_charging_voltage(float voltage);
void furi_hal_power_set_battery_charge_voltage_limit(float voltage);
/** Get remaining battery battery capacity in mAh
*
@@ -29,6 +29,7 @@ typedef enum {
FuriHalRtcFlagFactoryReset = (1 << 1),
FuriHalRtcFlagLock = (1 << 2),
FuriHalRtcFlagC2Update = (1 << 3),
FuriHalRtcFlagHandOrient = (1 << 4),
} FuriHalRtcFlag;
typedef enum {
@@ -8,13 +8,16 @@ extern "C" {
#endif
/** Early initialize SPI HAL */
void furi_hal_spi_init_early();
void furi_hal_spi_config_init_early();
/** Early deinitialize SPI HAL */
void furi_hal_spi_deinit_early();
void furi_hal_spi_config_deinit_early();
/** Initialize SPI HAL */
void furi_hal_spi_init();
void furi_hal_spi_config_init();
/** Initialize SPI DMA HAL */
void furi_hal_spi_dma_init();
/** Initialize SPI Bus
*
@@ -82,7 +85,7 @@ bool furi_hal_spi_bus_rx(
*/
bool furi_hal_spi_bus_tx(
FuriHalSpiBusHandle* handle,
uint8_t* buffer,
const uint8_t* buffer,
size_t size,
uint32_t timeout);
@@ -98,11 +101,28 @@ bool furi_hal_spi_bus_tx(
*/
bool furi_hal_spi_bus_trx(
FuriHalSpiBusHandle* handle,
uint8_t* tx_buffer,
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
@@ -9,6 +9,11 @@
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 */
@@ -67,6 +67,24 @@ bool furi_hal_version_do_i_belong_here();
*/
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 OTP version
*
* @return OTP Version