mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-13 13:58:36 -07:00
merge
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
entry,status,name,type,params
|
||||
Version,v,13.9,,
|
||||
Version,+,15.0,,
|
||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||
Header,+,applications/services/cli/cli.h,,
|
||||
Header,+,applications/services/cli/cli_vcp.h,,
|
||||
@@ -42,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,,
|
||||
@@ -62,22 +67,18 @@ 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,,
|
||||
@@ -153,6 +154,16 @@ 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,,
|
||||
@@ -167,7 +178,6 @@ Header,+,lib/subghz/blocks/encoder.h,,
|
||||
Header,+,lib/subghz/blocks/generic.h,,
|
||||
Header,+,lib/subghz/blocks/math.h,,
|
||||
Header,+,lib/subghz/environment.h,,
|
||||
Header,+,lib/subghz/protocols/protocol_items.h,,
|
||||
Header,+,lib/subghz/protocols/raw.h,,
|
||||
Header,+,lib/subghz/receiver.h,,
|
||||
Header,+,lib/subghz/registry.h,,
|
||||
@@ -194,7 +204,6 @@ Header,+,lib/toolbox/stream/string_stream.h,,
|
||||
Header,+,lib/toolbox/tar/tar_archive.h,,
|
||||
Header,+,lib/toolbox/value_index.h,,
|
||||
Header,+,lib/toolbox/version.h,,
|
||||
Header,+,lib/u8g2/u8g2.h,,
|
||||
Function,-,LL_ADC_CommonDeInit,ErrorStatus,ADC_Common_TypeDef*
|
||||
Function,-,LL_ADC_CommonInit,ErrorStatus,"ADC_Common_TypeDef*, LL_ADC_CommonInitTypeDef*"
|
||||
Function,-,LL_ADC_CommonStructInit,void,LL_ADC_CommonInitTypeDef*
|
||||
@@ -525,8 +534,6 @@ Function,-,atoff,float,const char*
|
||||
Function,+,atoi,int,const char*
|
||||
Function,-,atol,long,const char*
|
||||
Function,-,atoll,long long,const char*
|
||||
Function,-,atomo_decrypt,void,uint8_t*
|
||||
Function,-,atomo_encrypt,void,uint8_t*
|
||||
Function,-,basename,char*,const char*
|
||||
Function,-,bcmp,int,"const void*, const void*, size_t"
|
||||
Function,-,bcopy,void,"const void*, void*, size_t"
|
||||
@@ -644,6 +651,7 @@ 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_set_orientation,void,"Canvas*, CanvasOrientation"
|
||||
@@ -886,6 +894,7 @@ Function,+,flipper_application_free,void,FlipperApplication*
|
||||
Function,+,flipper_application_get_manifest,const FlipperApplicationManifest*,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_preload,FlipperApplicationPreloadStatus,"FlipperApplication*, const char*"
|
||||
@@ -1066,7 +1075,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,
|
||||
@@ -1147,7 +1156,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"
|
||||
@@ -1285,7 +1294,7 @@ 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_init,void,
|
||||
Function,-,furi_hal_resources_init_early,void,
|
||||
Function,+,furi_hal_rfid_change_read_config,void,"float, float"
|
||||
@@ -1314,7 +1323,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,
|
||||
@@ -1356,11 +1365,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,
|
||||
@@ -1415,6 +1426,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,
|
||||
@@ -1425,6 +1437,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,
|
||||
@@ -1752,8 +1766,6 @@ Function,-,j1f,float,float
|
||||
Function,-,jn,double,"int, double"
|
||||
Function,-,jnf,float,"int, float"
|
||||
Function,-,jrand48,long,unsigned short[3]
|
||||
Function,-,keeloq_reset_kl_type,void,
|
||||
Function,-,keeloq_reset_mfname,void,
|
||||
Function,-,l64a,char*,long
|
||||
Function,-,labs,long,long
|
||||
Function,-,lcong48,void,unsigned short[7]
|
||||
@@ -1915,8 +1927,10 @@ 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_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,"uint8_t, uint8_t, uint8_t"
|
||||
Function,-,mf_classic_dict_add_key,_Bool,"MfClassicDict*, uint8_t*"
|
||||
Function,-,mf_classic_dict_add_key_str,_Bool,"MfClassicDict*, FuriString*"
|
||||
@@ -1943,6 +1957,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"
|
||||
@@ -1951,6 +1966,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"
|
||||
@@ -1958,8 +1975,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*"
|
||||
@@ -2073,9 +2094,10 @@ Function,+,nfc_device_save_shadow,_Bool,"NfcDevice*, const char*"
|
||||
Function,+,nfc_device_set_loading_callback,void,"NfcDevice*, NfcLoadingCallback, void*"
|
||||
Function,+,nfc_device_set_name,void,"NfcDevice*, const char*"
|
||||
Function,+,nfc_file_select,_Bool,NfcDevice*
|
||||
Function,-,nfc_util_bytes2num,uint64_t,"uint8_t*, uint8_t"
|
||||
Function,-,nfc_util_bytes2num,uint64_t,"const uint8_t*, uint8_t"
|
||||
Function,-,nfc_util_even_parity32,uint8_t,uint32_t
|
||||
Function,-,nfc_util_num2bytes,void,"uint64_t, uint8_t, uint8_t*"
|
||||
Function,-,nfc_util_odd_parity,void,"const uint8_t*, uint8_t*, uint8_t"
|
||||
Function,-,nfc_util_odd_parity8,uint8_t,uint8_t
|
||||
Function,-,nfca_append_crc16,void,"uint8_t*, uint16_t"
|
||||
Function,-,nfca_emulation_handler,_Bool,"uint8_t*, uint16_t, uint8_t*, uint16_t*"
|
||||
@@ -2503,8 +2525,6 @@ Function,+,srand,void,unsigned
|
||||
Function,-,srand48,void,long
|
||||
Function,-,srandom,void,unsigned
|
||||
Function,+,sscanf,int,"const char*, const char*, ..."
|
||||
Function,-,star_line_reset_kl_type,void,
|
||||
Function,-,star_line_reset_mfname,void,
|
||||
Function,+,storage_common_copy,FS_Error,"Storage*, const char*, 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*"
|
||||
@@ -2647,12 +2667,14 @@ Function,+,subghz_block_generic_get_preset_name,void,"const char*, FuriString*"
|
||||
Function,+,subghz_block_generic_serialize,_Bool,"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*"
|
||||
@@ -2675,7 +2697,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"
|
||||
@@ -2684,243 +2706,11 @@ 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_ansonic_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_ansonic_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_ansonic_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_ansonic_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_ansonic_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_ansonic_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_ansonic_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_ansonic_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,+,subghz_protocol_decoder_base_deserialize,_Bool,"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_set_decoder_callback,void,"SubGhzProtocolDecoderBase*, SubGhzProtocolDecoderBaseRxCallback, void*"
|
||||
Function,-,subghz_protocol_decoder_bett_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_bett_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_bett_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_bett_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_bett_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_bett_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_bett_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_bett_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_decoder_came_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_came_atomo_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_came_atomo_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_came_atomo_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_came_atomo_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_came_atomo_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_came_atomo_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_came_atomo_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_came_atomo_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_decoder_came_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_came_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_came_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_came_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_came_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_came_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_came_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_decoder_came_twee_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_came_twee_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_came_twee_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_came_twee_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_came_twee_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_came_twee_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_came_twee_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_came_twee_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_decoder_chamb_code_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_chamb_code_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_chamb_code_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_chamb_code_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_chamb_code_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_chamb_code_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_chamb_code_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_chamb_code_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_decoder_clemsa_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_clemsa_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_clemsa_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_clemsa_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_clemsa_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_clemsa_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_clemsa_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_clemsa_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_decoder_doitrand_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_doitrand_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_doitrand_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_doitrand_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_doitrand_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_doitrand_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_doitrand_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_doitrand_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_decoder_faac_slh_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_faac_slh_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_faac_slh_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_faac_slh_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_faac_slh_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_faac_slh_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_faac_slh_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_faac_slh_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_decoder_gate_tx_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_gate_tx_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_gate_tx_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_gate_tx_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_gate_tx_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_gate_tx_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_gate_tx_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_gate_tx_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_decoder_holtek_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_holtek_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_holtek_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_holtek_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_holtek_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_holtek_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_holtek_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_holtek_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_decoder_holtek_th12x_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_holtek_th12x_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_holtek_th12x_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_holtek_th12x_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_holtek_th12x_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_holtek_th12x_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_holtek_th12x_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_holtek_th12x_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_decoder_honeywell_wdb_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_honeywell_wdb_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_honeywell_wdb_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_honeywell_wdb_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_honeywell_wdb_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_honeywell_wdb_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_honeywell_wdb_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_honeywell_wdb_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_decoder_hormann_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_hormann_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_hormann_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_hormann_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_hormann_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_hormann_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_hormann_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_hormann_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_decoder_ido_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_ido_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_ido_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_ido_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_ido_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_ido_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_ido_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_ido_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_decoder_intertechno_v3_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_intertechno_v3_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_intertechno_v3_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_intertechno_v3_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_intertechno_v3_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_intertechno_v3_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_intertechno_v3_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_intertechno_v3_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_decoder_keeloq_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_keeloq_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_keeloq_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_keeloq_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_keeloq_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_keeloq_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_keeloq_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_keeloq_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_decoder_kia_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_kia_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_kia_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_kia_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_kia_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_kia_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_kia_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_kia_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_decoder_linear_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_linear_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_linear_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_linear_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_linear_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_linear_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_linear_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_linear_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_decoder_magellan_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_magellan_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_magellan_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_magellan_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_magellan_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_magellan_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_magellan_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_magellan_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_decoder_marantec_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_marantec_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_marantec_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_marantec_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_marantec_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_marantec_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_marantec_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_marantec_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_decoder_megacode_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_megacode_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_megacode_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_megacode_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_megacode_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_megacode_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_megacode_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_megacode_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_decoder_nero_radio_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_nero_radio_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_nero_radio_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_nero_radio_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_nero_radio_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_nero_radio_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_nero_radio_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_nero_radio_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_decoder_nero_sketch_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_nero_sketch_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_nero_sketch_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_nero_sketch_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_nero_sketch_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_nero_sketch_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_nero_sketch_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_nero_sketch_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_decoder_nice_flo_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_nice_flo_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_nice_flo_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_nice_flo_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_nice_flo_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_nice_flo_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_nice_flo_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_nice_flo_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_decoder_nice_flor_s_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_nice_flor_s_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_nice_flor_s_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_nice_flor_s_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_nice_flor_s_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_nice_flor_s_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_nice_flor_s_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_nice_flor_s_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_decoder_phoenix_v2_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_phoenix_v2_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_phoenix_v2_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_phoenix_v2_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_phoenix_v2_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_phoenix_v2_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_phoenix_v2_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_phoenix_v2_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_decoder_power_smart_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_power_smart_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_power_smart_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_power_smart_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_power_smart_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_power_smart_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_power_smart_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_power_smart_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,+,subghz_protocol_decoder_princeton_alloc,void*,SubGhzEnvironment*
|
||||
Function,+,subghz_protocol_decoder_princeton_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,+,subghz_protocol_decoder_princeton_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,+,subghz_protocol_decoder_princeton_free,void,void*
|
||||
Function,+,subghz_protocol_decoder_princeton_get_hash_data,uint8_t,void*
|
||||
Function,+,subghz_protocol_decoder_princeton_get_string,void,"void*, FuriString*"
|
||||
Function,+,subghz_protocol_decoder_princeton_reset,void,void*
|
||||
Function,+,subghz_protocol_decoder_princeton_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,+,subghz_protocol_decoder_raw_alloc,void*,SubGhzEnvironment*
|
||||
Function,+,subghz_protocol_decoder_raw_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,+,subghz_protocol_decoder_raw_feed,void,"void*, _Bool, uint32_t"
|
||||
@@ -2932,228 +2722,12 @@ Function,+,subghz_protocol_decoder_raw_serialize,_Bool,"void*, FlipperFormat*, S
|
||||
Function,+,subghz_protocol_decoder_raw_set_auto_mode,void,"void*, _Bool"
|
||||
Function,+,subghz_protocol_decoder_raw_set_rssi_threshold,void,"void*, int"
|
||||
Function,+,subghz_protocol_decoder_raw_write_data,_Bool,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_scher_khan_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_scher_khan_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_scher_khan_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_scher_khan_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_scher_khan_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_scher_khan_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_scher_khan_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_scher_khan_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_decoder_secplus_v1_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_secplus_v1_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_secplus_v1_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_secplus_v1_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_secplus_v1_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_secplus_v1_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_secplus_v1_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_secplus_v1_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_decoder_secplus_v2_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_secplus_v2_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_secplus_v2_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_secplus_v2_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_secplus_v2_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_secplus_v2_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_secplus_v2_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_secplus_v2_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_decoder_smc5326_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_smc5326_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_smc5326_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_smc5326_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_smc5326_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_smc5326_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_smc5326_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_smc5326_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_decoder_somfy_keytis_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_somfy_keytis_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_somfy_keytis_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_somfy_keytis_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_somfy_keytis_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_somfy_keytis_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_somfy_keytis_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_somfy_keytis_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_decoder_somfy_telis_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_somfy_telis_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_somfy_telis_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_somfy_telis_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_somfy_telis_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_somfy_telis_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_somfy_telis_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_somfy_telis_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_decoder_star_line_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_decoder_star_line_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_decoder_star_line_feed,void,"void*, _Bool, uint32_t"
|
||||
Function,-,subghz_protocol_decoder_star_line_free,void,void*
|
||||
Function,-,subghz_protocol_decoder_star_line_get_hash_data,uint8_t,void*
|
||||
Function,-,subghz_protocol_decoder_star_line_get_string,void,"void*, FuriString*"
|
||||
Function,-,subghz_protocol_decoder_star_line_reset,void,void*
|
||||
Function,-,subghz_protocol_decoder_star_line_serialize,_Bool,"void*, FlipperFormat*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_encoder_ansonic_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_encoder_ansonic_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_encoder_ansonic_free,void,void*
|
||||
Function,-,subghz_protocol_encoder_ansonic_stop,void,void*
|
||||
Function,-,subghz_protocol_encoder_ansonic_yield,LevelDuration,void*
|
||||
Function,-,subghz_protocol_encoder_bett_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_encoder_bett_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_encoder_bett_free,void,void*
|
||||
Function,-,subghz_protocol_encoder_bett_stop,void,void*
|
||||
Function,-,subghz_protocol_encoder_bett_yield,LevelDuration,void*
|
||||
Function,-,subghz_protocol_encoder_came_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_encoder_came_atomo_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_encoder_came_atomo_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_encoder_came_atomo_free,void,void*
|
||||
Function,-,subghz_protocol_encoder_came_atomo_stop,void,void*
|
||||
Function,-,subghz_protocol_encoder_came_atomo_yield,LevelDuration,void*
|
||||
Function,-,subghz_protocol_encoder_came_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_encoder_came_free,void,void*
|
||||
Function,-,subghz_protocol_encoder_came_stop,void,void*
|
||||
Function,-,subghz_protocol_encoder_came_twee_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_encoder_came_twee_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_encoder_came_twee_free,void,void*
|
||||
Function,-,subghz_protocol_encoder_came_twee_stop,void,void*
|
||||
Function,-,subghz_protocol_encoder_came_twee_yield,LevelDuration,void*
|
||||
Function,-,subghz_protocol_encoder_came_yield,LevelDuration,void*
|
||||
Function,-,subghz_protocol_encoder_chamb_code_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_encoder_chamb_code_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_encoder_chamb_code_free,void,void*
|
||||
Function,-,subghz_protocol_encoder_chamb_code_stop,void,void*
|
||||
Function,-,subghz_protocol_encoder_chamb_code_yield,LevelDuration,void*
|
||||
Function,-,subghz_protocol_encoder_clemsa_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_encoder_clemsa_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_encoder_clemsa_free,void,void*
|
||||
Function,-,subghz_protocol_encoder_clemsa_stop,void,void*
|
||||
Function,-,subghz_protocol_encoder_clemsa_yield,LevelDuration,void*
|
||||
Function,-,subghz_protocol_encoder_doitrand_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_encoder_doitrand_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_encoder_doitrand_free,void,void*
|
||||
Function,-,subghz_protocol_encoder_doitrand_stop,void,void*
|
||||
Function,-,subghz_protocol_encoder_doitrand_yield,LevelDuration,void*
|
||||
Function,-,subghz_protocol_encoder_faac_slh_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_encoder_faac_slh_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_encoder_faac_slh_free,void,void*
|
||||
Function,-,subghz_protocol_encoder_faac_slh_stop,void,void*
|
||||
Function,-,subghz_protocol_encoder_faac_slh_yield,LevelDuration,void*
|
||||
Function,-,subghz_protocol_encoder_gate_tx_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_encoder_gate_tx_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_encoder_gate_tx_free,void,void*
|
||||
Function,-,subghz_protocol_encoder_gate_tx_stop,void,void*
|
||||
Function,-,subghz_protocol_encoder_gate_tx_yield,LevelDuration,void*
|
||||
Function,-,subghz_protocol_encoder_get_rssi_threshold,int,void*
|
||||
Function,-,subghz_protocol_encoder_holtek_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_encoder_holtek_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_encoder_holtek_free,void,void*
|
||||
Function,-,subghz_protocol_encoder_holtek_stop,void,void*
|
||||
Function,-,subghz_protocol_encoder_holtek_th12x_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_encoder_holtek_th12x_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_encoder_holtek_th12x_free,void,void*
|
||||
Function,-,subghz_protocol_encoder_holtek_th12x_stop,void,void*
|
||||
Function,-,subghz_protocol_encoder_holtek_th12x_yield,LevelDuration,void*
|
||||
Function,-,subghz_protocol_encoder_holtek_yield,LevelDuration,void*
|
||||
Function,-,subghz_protocol_encoder_honeywell_wdb_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_encoder_honeywell_wdb_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_encoder_honeywell_wdb_free,void,void*
|
||||
Function,-,subghz_protocol_encoder_honeywell_wdb_stop,void,void*
|
||||
Function,-,subghz_protocol_encoder_honeywell_wdb_yield,LevelDuration,void*
|
||||
Function,-,subghz_protocol_encoder_hormann_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_encoder_hormann_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_encoder_hormann_free,void,void*
|
||||
Function,-,subghz_protocol_encoder_hormann_stop,void,void*
|
||||
Function,-,subghz_protocol_encoder_hormann_yield,LevelDuration,void*
|
||||
Function,-,subghz_protocol_encoder_intertechno_v3_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_encoder_intertechno_v3_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_encoder_intertechno_v3_free,void,void*
|
||||
Function,-,subghz_protocol_encoder_intertechno_v3_stop,void,void*
|
||||
Function,-,subghz_protocol_encoder_intertechno_v3_yield,LevelDuration,void*
|
||||
Function,-,subghz_protocol_encoder_keeloq_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_encoder_keeloq_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_encoder_keeloq_free,void,void*
|
||||
Function,-,subghz_protocol_encoder_keeloq_stop,void,void*
|
||||
Function,-,subghz_protocol_encoder_keeloq_yield,LevelDuration,void*
|
||||
Function,-,subghz_protocol_encoder_linear_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_encoder_linear_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_encoder_linear_free,void,void*
|
||||
Function,-,subghz_protocol_encoder_linear_stop,void,void*
|
||||
Function,-,subghz_protocol_encoder_linear_yield,LevelDuration,void*
|
||||
Function,-,subghz_protocol_encoder_magellan_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_encoder_magellan_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_encoder_magellan_free,void,void*
|
||||
Function,-,subghz_protocol_encoder_magellan_stop,void,void*
|
||||
Function,-,subghz_protocol_encoder_magellan_yield,LevelDuration,void*
|
||||
Function,-,subghz_protocol_encoder_marantec_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_encoder_marantec_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_encoder_marantec_free,void,void*
|
||||
Function,-,subghz_protocol_encoder_marantec_stop,void,void*
|
||||
Function,-,subghz_protocol_encoder_marantec_yield,LevelDuration,void*
|
||||
Function,-,subghz_protocol_encoder_megacode_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_encoder_megacode_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_encoder_megacode_free,void,void*
|
||||
Function,-,subghz_protocol_encoder_megacode_stop,void,void*
|
||||
Function,-,subghz_protocol_encoder_megacode_yield,LevelDuration,void*
|
||||
Function,-,subghz_protocol_encoder_nero_radio_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_encoder_nero_radio_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_encoder_nero_radio_free,void,void*
|
||||
Function,-,subghz_protocol_encoder_nero_radio_stop,void,void*
|
||||
Function,-,subghz_protocol_encoder_nero_radio_yield,LevelDuration,void*
|
||||
Function,-,subghz_protocol_encoder_nero_sketch_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_encoder_nero_sketch_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_encoder_nero_sketch_free,void,void*
|
||||
Function,-,subghz_protocol_encoder_nero_sketch_stop,void,void*
|
||||
Function,-,subghz_protocol_encoder_nero_sketch_yield,LevelDuration,void*
|
||||
Function,-,subghz_protocol_encoder_nice_flo_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_encoder_nice_flo_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_encoder_nice_flo_free,void,void*
|
||||
Function,-,subghz_protocol_encoder_nice_flo_stop,void,void*
|
||||
Function,-,subghz_protocol_encoder_nice_flo_yield,LevelDuration,void*
|
||||
Function,-,subghz_protocol_encoder_nice_flor_s_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_encoder_nice_flor_s_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_encoder_nice_flor_s_free,void,void*
|
||||
Function,-,subghz_protocol_encoder_nice_flor_s_stop,void,void*
|
||||
Function,-,subghz_protocol_encoder_nice_flor_s_yield,LevelDuration,void*
|
||||
Function,-,subghz_protocol_encoder_phoenix_v2_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_encoder_phoenix_v2_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_encoder_phoenix_v2_free,void,void*
|
||||
Function,-,subghz_protocol_encoder_phoenix_v2_stop,void,void*
|
||||
Function,-,subghz_protocol_encoder_phoenix_v2_yield,LevelDuration,void*
|
||||
Function,-,subghz_protocol_encoder_power_smart_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_encoder_power_smart_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_encoder_power_smart_free,void,void*
|
||||
Function,-,subghz_protocol_encoder_power_smart_stop,void,void*
|
||||
Function,-,subghz_protocol_encoder_power_smart_yield,LevelDuration,void*
|
||||
Function,+,subghz_protocol_encoder_princeton_alloc,void*,SubGhzEnvironment*
|
||||
Function,+,subghz_protocol_encoder_princeton_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,+,subghz_protocol_encoder_princeton_free,void,void*
|
||||
Function,+,subghz_protocol_encoder_princeton_stop,void,void*
|
||||
Function,+,subghz_protocol_encoder_princeton_yield,LevelDuration,void*
|
||||
Function,+,subghz_protocol_encoder_raw_alloc,void*,SubGhzEnvironment*
|
||||
Function,+,subghz_protocol_encoder_raw_deserialize,_Bool,"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*
|
||||
Function,-,subghz_protocol_encoder_secplus_v1_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_encoder_secplus_v1_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_encoder_secplus_v1_free,void,void*
|
||||
Function,-,subghz_protocol_encoder_secplus_v1_stop,void,void*
|
||||
Function,-,subghz_protocol_encoder_secplus_v1_yield,LevelDuration,void*
|
||||
Function,-,subghz_protocol_encoder_secplus_v2_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_encoder_secplus_v2_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_encoder_secplus_v2_free,void,void*
|
||||
Function,-,subghz_protocol_encoder_secplus_v2_stop,void,void*
|
||||
Function,-,subghz_protocol_encoder_secplus_v2_yield,LevelDuration,void*
|
||||
Function,-,subghz_protocol_encoder_smc5326_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_encoder_smc5326_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_encoder_smc5326_free,void,void*
|
||||
Function,-,subghz_protocol_encoder_smc5326_stop,void,void*
|
||||
Function,-,subghz_protocol_encoder_smc5326_yield,LevelDuration,void*
|
||||
Function,-,subghz_protocol_encoder_star_line_alloc,void*,SubGhzEnvironment*
|
||||
Function,-,subghz_protocol_encoder_star_line_deserialize,_Bool,"void*, FlipperFormat*"
|
||||
Function,-,subghz_protocol_encoder_star_line_free,void,void*
|
||||
Function,-,subghz_protocol_encoder_star_line_stop,void,void*
|
||||
Function,-,subghz_protocol_encoder_star_line_yield,LevelDuration,void*
|
||||
Function,-,subghz_protocol_faac_slh_create_data,_Bool,"void*, FlipperFormat*, uint32_t, uint8_t, uint32_t, uint32_t, const char*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_keeloq_bft_create_data,_Bool,"void*, FlipperFormat*, uint32_t, uint8_t, uint16_t, uint32_t, const char*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_keeloq_create_data,_Bool,"void*, FlipperFormat*, uint32_t, uint8_t, uint16_t, const char*, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_nice_flor_s_create_data,_Bool,"void*, FlipperFormat*, uint32_t, uint8_t, uint16_t, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_nice_flor_s_encrypt,uint64_t,"uint64_t, const char*"
|
||||
Function,+,subghz_protocol_raw_file_encoder_worker_set_callback_end,void,"SubGhzProtocolEncoderRAW*, SubGhzProtocolEncoderRAWCallbackEnd, void*"
|
||||
Function,+,subghz_protocol_raw_gen_fff_data,void,"FlipperFormat*, const char*"
|
||||
Function,+,subghz_protocol_raw_get_sample_write,size_t,SubGhzProtocolDecoderRAW*
|
||||
@@ -3163,9 +2737,6 @@ Function,+,subghz_protocol_raw_save_to_file_stop,void,SubGhzProtocolDecoderRAW*
|
||||
Function,+,subghz_protocol_registry_count,size_t,const SubGhzProtocolRegistry*
|
||||
Function,+,subghz_protocol_registry_get_by_index,const SubGhzProtocol*,"const SubGhzProtocolRegistry*, size_t"
|
||||
Function,+,subghz_protocol_registry_get_by_name,const SubGhzProtocol*,"const SubGhzProtocolRegistry*, const char*"
|
||||
Function,-,subghz_protocol_secplus_v1_check_fixed,_Bool,uint32_t
|
||||
Function,-,subghz_protocol_secplus_v2_create_data,_Bool,"void*, FlipperFormat*, uint32_t, uint8_t, uint32_t, SubGhzRadioPreset*"
|
||||
Function,-,subghz_protocol_star_line_create_data,_Bool,"void*, FlipperFormat*, uint32_t, uint8_t, uint16_t, const char*, SubGhzRadioPreset*"
|
||||
Function,+,subghz_receiver_alloc_init,SubGhzReceiver*,SubGhzEnvironment*
|
||||
Function,+,subghz_receiver_decode,void,"SubGhzReceiver*, _Bool, uint32_t"
|
||||
Function,+,subghz_receiver_free,void,SubGhzReceiver*
|
||||
@@ -4364,8 +3935,8 @@ Function,-,uECC_verify,int,"const uint8_t*, const uint8_t*, unsigned, const uint
|
||||
Function,-,ucStreamBufferGetStreamBufferType,uint8_t,StreamBufferHandle_t
|
||||
Function,-,ulTaskGenericNotifyTake,uint32_t,"UBaseType_t, BaseType_t, TickType_t"
|
||||
Function,-,ulTaskGenericNotifyValueClear,uint32_t,"TaskHandle_t, UBaseType_t, uint32_t"
|
||||
Function,-,ulTaskGetIdleRunTimeCounter,configRUN_TIME_COUNTER_TYPE,
|
||||
Function,-,ulTaskGetIdleRunTimePercent,configRUN_TIME_COUNTER_TYPE,
|
||||
Function,-,ulTaskGetIdleRunTimeCounter,uint32_t,
|
||||
Function,-,ulTaskGetIdleRunTimePercent,uint32_t,
|
||||
Function,-,ungetc,int,"int, FILE*"
|
||||
Function,-,unsetenv,int,const char*
|
||||
Function,-,usbd_poll,void,usbd_device*
|
||||
@@ -4376,7 +3947,7 @@ Function,-,uxStreamBufferGetStreamBufferNumber,UBaseType_t,StreamBufferHandle_t
|
||||
Function,-,uxTaskGetNumberOfTasks,UBaseType_t,
|
||||
Function,-,uxTaskGetStackHighWaterMark,UBaseType_t,TaskHandle_t
|
||||
Function,-,uxTaskGetStackHighWaterMark2,uint16_t,TaskHandle_t
|
||||
Function,-,uxTaskGetSystemState,UBaseType_t,"TaskStatus_t*, const UBaseType_t, configRUN_TIME_COUNTER_TYPE*"
|
||||
Function,+,uxTaskGetSystemState,UBaseType_t,"TaskStatus_t*, const UBaseType_t, uint32_t*"
|
||||
Function,-,uxTaskGetTaskNumber,UBaseType_t,TaskHandle_t
|
||||
Function,+,uxTaskPriorityGet,UBaseType_t,const TaskHandle_t
|
||||
Function,-,uxTaskPriorityGetFromISR,UBaseType_t,const TaskHandle_t
|
||||
@@ -4657,6 +4228,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,
|
||||
@@ -4873,119 +4446,9 @@ Variable,+,sequence_set_vibro_on,const NotificationSequence,
|
||||
Variable,+,sequence_single_vibro,const NotificationSequence,
|
||||
Variable,+,sequence_solid_yellow,const NotificationSequence,
|
||||
Variable,+,sequence_success,const NotificationSequence,
|
||||
Variable,-,subghz_protocol_ansonic,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_ansonic_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_ansonic_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_bett,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_bett_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_bett_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_came,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_came_atomo,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_came_atomo_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_came_atomo_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_came_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_came_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_came_twee,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_came_twee_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_came_twee_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_chamb_code,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_chamb_code_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_chamb_code_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_clemsa,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_clemsa_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_clemsa_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_doitrand,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_doitrand_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_doitrand_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_faac_slh,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_faac_slh_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_faac_slh_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_gate_tx,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_gate_tx_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_gate_tx_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_holtek,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_holtek_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_holtek_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_holtek_th12x,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_holtek_th12x_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_holtek_th12x_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_honeywell_wdb,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_honeywell_wdb_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_honeywell_wdb_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_hormann,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_hormann_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_hormann_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_ido,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_ido_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_ido_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_intertechno_v3,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_intertechno_v3_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_intertechno_v3_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_keeloq,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_keeloq_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_keeloq_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_kia,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_kia_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_kia_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_linear,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_linear_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_linear_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_magellan,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_magellan_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_magellan_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_marantec,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_marantec_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_marantec_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_megacode,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_megacode_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_megacode_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_nero_radio,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_nero_radio_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_nero_radio_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_nero_sketch,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_nero_sketch_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_nero_sketch_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_nice_flo,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_nice_flo_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_nice_flo_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_nice_flor_s,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_nice_flor_s_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_nice_flor_s_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_phoenix_v2,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_phoenix_v2_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_phoenix_v2_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_pocsag,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_power_smart,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_power_smart_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_power_smart_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_princeton,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_princeton_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_princeton_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,+,subghz_protocol_raw,const SubGhzProtocol,
|
||||
Variable,+,subghz_protocol_raw_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,+,subghz_protocol_raw_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,+,subghz_protocol_registry,const SubGhzProtocolRegistry,
|
||||
Variable,-,subghz_protocol_scher_khan,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_scher_khan_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_scher_khan_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_secplus_v1,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_secplus_v1_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_secplus_v1_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_secplus_v2,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_secplus_v2_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_secplus_v2_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_smc5326,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_smc5326_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_smc5326_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_somfy_keytis,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_somfy_keytis_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_somfy_keytis_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_somfy_telis,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_somfy_telis_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_somfy_telis_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,subghz_protocol_star_line,const SubGhzProtocol,
|
||||
Variable,-,subghz_protocol_star_line_decoder,const SubGhzProtocolDecoder,
|
||||
Variable,-,subghz_protocol_star_line_encoder,const SubGhzProtocolEncoder,
|
||||
Variable,-,suboptarg,char*,
|
||||
Variable,-,u8g2_cb_mirror,const u8g2_cb_t,
|
||||
Variable,-,u8g2_cb_r0,const u8g2_cb_t,
|
||||
|
||||
|
877
firmware/targets/f7/fatfs/sd_spi_io.c
Normal file
877
firmware/targets/f7/fatfs/sd_spi_io.c
Normal file
@@ -0,0 +1,877 @@
|
||||
#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 SD_BLOCK_SIZE 512
|
||||
|
||||
#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->CID_CRC = (cid_data[15] & 0xFE) >> 1;
|
||||
Cid->Reserved2 = 1;
|
||||
|
||||
ret = SdSpiStatusOK;
|
||||
}
|
||||
}
|
||||
|
||||
sd_spi_deselect_card_and_purge();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
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 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 = SdSpiStatusError;
|
||||
|
||||
bool single_sector_read = (blocks == 1);
|
||||
|
||||
if(single_sector_read) {
|
||||
if(sd_cache_get(address, data)) {
|
||||
return SdSpiStatusOK;
|
||||
}
|
||||
|
||||
status = sd_spi_cmd_read_blocks(data, address, blocks, timeout_ms);
|
||||
|
||||
if(status == SdSpiStatusOK) {
|
||||
sd_cache_put(address, data);
|
||||
}
|
||||
} else {
|
||||
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) {
|
||||
sd_cache_invalidate_range(address, address + blocks);
|
||||
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;
|
||||
}
|
||||
157
firmware/targets/f7/fatfs/sd_spi_io.h
Normal file
157
firmware/targets/f7/fatfs/sd_spi_io.h
Normal file
@@ -0,0 +1,157 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define __IO volatile
|
||||
|
||||
#define SD_TIMEOUT_MS (1000)
|
||||
|
||||
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);
|
||||
@@ -17,7 +17,7 @@ void furi_hal_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();
|
||||
@@ -29,7 +29,7 @@ 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();
|
||||
|
||||
@@ -51,7 +51,7 @@ void furi_hal_init() {
|
||||
|
||||
furi_hal_version_init();
|
||||
|
||||
furi_hal_spi_init();
|
||||
furi_hal_spi_config_init();
|
||||
|
||||
furi_hal_ibutton_init();
|
||||
FURI_LOG_I(TAG, "iButton OK");
|
||||
|
||||
@@ -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,4 +1,4 @@
|
||||
#include "furi_hal_cortex.h"
|
||||
#include <furi_hal_cortex.h>
|
||||
|
||||
#include <stm32wbxx.h>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
88
firmware/targets/f7/furi_hal/furi_hal_ibutton.h
Normal file
88
firmware/targets/f7/furi_hal/furi_hal_ibutton.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/**
|
||||
* @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
|
||||
@@ -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"
|
||||
|
||||
@@ -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>
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
424
firmware/targets/f7/furi_hal/furi_hal_nfc.h
Normal file
424
firmware/targets/f7/furi_hal/furi_hal_nfc.h
Normal file
@@ -0,0 +1,424 @@
|
||||
/**
|
||||
* @file furi_hal_nfc.h
|
||||
* NFC HAL API
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <st_errno.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include <rfal_nfc.h>
|
||||
#include <lib/nfc/protocols/nfca.h>
|
||||
|
||||
#define FURI_HAL_NFC_UID_MAX_LEN 10
|
||||
#define FURI_HAL_NFC_DATA_BUFF_SIZE (512)
|
||||
#define FURI_HAL_NFC_PARITY_BUFF_SIZE (FURI_HAL_NFC_DATA_BUFF_SIZE / 8)
|
||||
|
||||
#define FURI_HAL_NFC_TXRX_DEFAULT \
|
||||
((uint32_t)RFAL_TXRX_FLAGS_CRC_TX_AUTO | (uint32_t)RFAL_TXRX_FLAGS_CRC_RX_REMV | \
|
||||
(uint32_t)RFAL_TXRX_FLAGS_PAR_RX_REMV | (uint32_t)RFAL_TXRX_FLAGS_PAR_TX_AUTO)
|
||||
|
||||
#define FURI_HAL_NFC_TX_DEFAULT_RX_NO_CRC \
|
||||
((uint32_t)RFAL_TXRX_FLAGS_CRC_TX_AUTO | (uint32_t)RFAL_TXRX_FLAGS_CRC_RX_KEEP | \
|
||||
(uint32_t)RFAL_TXRX_FLAGS_PAR_RX_REMV | (uint32_t)RFAL_TXRX_FLAGS_PAR_TX_AUTO)
|
||||
|
||||
#define FURI_HAL_NFC_TXRX_WITH_PAR \
|
||||
((uint32_t)RFAL_TXRX_FLAGS_CRC_TX_MANUAL | (uint32_t)RFAL_TXRX_FLAGS_CRC_RX_KEEP | \
|
||||
(uint32_t)RFAL_TXRX_FLAGS_PAR_RX_KEEP | (uint32_t)RFAL_TXRX_FLAGS_PAR_TX_AUTO)
|
||||
|
||||
#define FURI_HAL_NFC_TXRX_RAW \
|
||||
((uint32_t)RFAL_TXRX_FLAGS_CRC_TX_MANUAL | (uint32_t)RFAL_TXRX_FLAGS_CRC_RX_KEEP | \
|
||||
(uint32_t)RFAL_TXRX_FLAGS_PAR_RX_KEEP | (uint32_t)RFAL_TXRX_FLAGS_PAR_TX_NONE)
|
||||
|
||||
#define FURI_HAL_NFC_TX_RAW_RX_DEFAULT \
|
||||
((uint32_t)RFAL_TXRX_FLAGS_CRC_TX_MANUAL | (uint32_t)RFAL_TXRX_FLAGS_CRC_RX_REMV | \
|
||||
(uint32_t)RFAL_TXRX_FLAGS_PAR_RX_REMV | (uint32_t)RFAL_TXRX_FLAGS_PAR_TX_NONE)
|
||||
|
||||
typedef enum {
|
||||
FuriHalNfcTxRxTypeDefault,
|
||||
FuriHalNfcTxRxTypeRxNoCrc,
|
||||
FuriHalNfcTxRxTypeRxKeepPar,
|
||||
FuriHalNfcTxRxTypeRaw,
|
||||
FuriHalNfcTxRxTypeRxRaw,
|
||||
FuriHalNfcTxRxTransparent,
|
||||
} FuriHalNfcTxRxType;
|
||||
|
||||
typedef bool (*FuriHalNfcEmulateCallback)(
|
||||
uint8_t* buff_rx,
|
||||
uint16_t buff_rx_len,
|
||||
uint8_t* buff_tx,
|
||||
uint16_t* buff_tx_len,
|
||||
uint32_t* flags,
|
||||
void* context);
|
||||
|
||||
typedef enum {
|
||||
FuriHalNfcTypeA,
|
||||
FuriHalNfcTypeB,
|
||||
FuriHalNfcTypeF,
|
||||
FuriHalNfcTypeV,
|
||||
} FuriHalNfcType;
|
||||
|
||||
typedef enum {
|
||||
FuriHalNfcInterfaceRf,
|
||||
FuriHalNfcInterfaceIsoDep,
|
||||
FuriHalNfcInterfaceNfcDep,
|
||||
} FuriHalNfcInterface;
|
||||
|
||||
typedef struct {
|
||||
FuriHalNfcType type;
|
||||
FuriHalNfcInterface interface;
|
||||
uint8_t uid_len;
|
||||
uint8_t uid[10];
|
||||
uint32_t cuid;
|
||||
uint8_t atqa[2];
|
||||
uint8_t sak;
|
||||
} FuriHalNfcDevData;
|
||||
|
||||
typedef void (
|
||||
*FuriHalNfcTxRxSniffCallback)(uint8_t* data, uint16_t bits, bool crc_dropped, void* context);
|
||||
|
||||
typedef struct {
|
||||
uint8_t tx_data[FURI_HAL_NFC_DATA_BUFF_SIZE];
|
||||
uint8_t tx_parity[FURI_HAL_NFC_PARITY_BUFF_SIZE];
|
||||
uint16_t tx_bits;
|
||||
uint8_t rx_data[FURI_HAL_NFC_DATA_BUFF_SIZE];
|
||||
uint8_t rx_parity[FURI_HAL_NFC_PARITY_BUFF_SIZE];
|
||||
uint16_t rx_bits;
|
||||
FuriHalNfcTxRxType tx_rx_type;
|
||||
NfcaSignal* nfca_signal;
|
||||
|
||||
FuriHalNfcTxRxSniffCallback sniff_tx;
|
||||
FuriHalNfcTxRxSniffCallback sniff_rx;
|
||||
void* sniff_context;
|
||||
} FuriHalNfcTxRxContext;
|
||||
|
||||
/** Init nfc
|
||||
*/
|
||||
void furi_hal_nfc_init();
|
||||
|
||||
/** Check if nfc worker is busy
|
||||
*
|
||||
* @return true if busy
|
||||
*/
|
||||
bool furi_hal_nfc_is_busy();
|
||||
|
||||
/** Check if nfc is initialized
|
||||
*
|
||||
* @return true if initialized
|
||||
*/
|
||||
bool furi_hal_nfc_is_init();
|
||||
|
||||
/** NFC field on
|
||||
*/
|
||||
void furi_hal_nfc_field_on();
|
||||
|
||||
/** NFC field off
|
||||
*/
|
||||
void furi_hal_nfc_field_off();
|
||||
|
||||
/** NFC start sleep
|
||||
*/
|
||||
void furi_hal_nfc_start_sleep();
|
||||
|
||||
void furi_hal_nfc_stop_cmd();
|
||||
|
||||
/** NFC stop sleep
|
||||
*/
|
||||
void furi_hal_nfc_exit_sleep();
|
||||
|
||||
/** NFC poll
|
||||
*
|
||||
* @param dev_list pointer to rfalNfcDevice buffer
|
||||
* @param dev_cnt pointer device count
|
||||
* @param timeout timeout in ms
|
||||
* @param deactivate deactivate flag
|
||||
*
|
||||
* @return true on success
|
||||
*/
|
||||
bool furi_hal_nfc_detect(FuriHalNfcDevData* nfc_data, uint32_t timeout);
|
||||
|
||||
/** Activate NFC-A tag
|
||||
*
|
||||
* @param timeout timeout in ms
|
||||
* @param cuid pointer to 32bit uid
|
||||
*
|
||||
* @return true on succeess
|
||||
*/
|
||||
bool furi_hal_nfc_activate_nfca(uint32_t timeout, uint32_t* cuid);
|
||||
|
||||
/** NFC listen
|
||||
*
|
||||
* @param uid pointer to uid buffer
|
||||
* @param uid_len uid length
|
||||
* @param atqa pointer to atqa
|
||||
* @param sak sak
|
||||
* @param activate_after_sak activate after sak flag
|
||||
* @param timeout timeout in ms
|
||||
*
|
||||
* @return true on success
|
||||
*/
|
||||
bool furi_hal_nfc_listen(
|
||||
uint8_t* uid,
|
||||
uint8_t uid_len,
|
||||
uint8_t* atqa,
|
||||
uint8_t sak,
|
||||
bool activate_after_sak,
|
||||
uint32_t timeout);
|
||||
|
||||
/** Start Target Listen mode
|
||||
* @note RFAL free implementation
|
||||
*
|
||||
* @param nfc_data FuriHalNfcDevData instance
|
||||
*/
|
||||
void furi_hal_nfc_listen_start(FuriHalNfcDevData* nfc_data);
|
||||
|
||||
/** Read data in Target Listen mode
|
||||
* @note Must be called only after furi_hal_nfc_listen_start()
|
||||
*
|
||||
* @param tx_rx FuriHalNfcTxRxContext instance
|
||||
* @param timeout_ms timeout im ms
|
||||
*
|
||||
* @return true on not empty receive
|
||||
*/
|
||||
bool furi_hal_nfc_listen_rx(FuriHalNfcTxRxContext* tx_rx, uint32_t timeout_ms);
|
||||
|
||||
/** Set Target in Sleep state */
|
||||
void furi_hal_nfc_listen_sleep();
|
||||
|
||||
/** Emulate NFC-A Target
|
||||
* @note RFAL based implementation
|
||||
*
|
||||
* @param uid NFC-A UID
|
||||
* @param uid_len NFC-A UID length
|
||||
* @param atqa NFC-A ATQA
|
||||
* @param sak NFC-A SAK
|
||||
* @param callback FuriHalNfcEmulateCallback instance
|
||||
* @param context pointer to context for callback
|
||||
* @param timeout timeout in ms
|
||||
*
|
||||
* @return true on success
|
||||
*/
|
||||
bool furi_hal_nfc_emulate_nfca(
|
||||
uint8_t* uid,
|
||||
uint8_t uid_len,
|
||||
uint8_t* atqa,
|
||||
uint8_t sak,
|
||||
FuriHalNfcEmulateCallback callback,
|
||||
void* context,
|
||||
uint32_t timeout);
|
||||
|
||||
/** NFC data exchange
|
||||
*
|
||||
* @param tx_rx_ctx FuriHalNfcTxRxContext instance
|
||||
*
|
||||
* @return true on success
|
||||
*/
|
||||
bool furi_hal_nfc_tx_rx(FuriHalNfcTxRxContext* tx_rx, uint16_t timeout_ms);
|
||||
|
||||
/** NFC data full exhange
|
||||
*
|
||||
* @param tx_rx_ctx FuriHalNfcTxRxContext instance
|
||||
*
|
||||
* @return true on success
|
||||
*/
|
||||
bool furi_hal_nfc_tx_rx_full(FuriHalNfcTxRxContext* tx_rx);
|
||||
|
||||
/** NFC deactivate and start sleep
|
||||
*/
|
||||
void furi_hal_nfc_sleep();
|
||||
|
||||
void furi_hal_nfc_stop();
|
||||
|
||||
/* Low level transport API, use it to implement your own transport layers */
|
||||
|
||||
#define furi_hal_nfc_ll_ms2fc rfalConvMsTo1fc
|
||||
|
||||
#define FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_TX_MANUAL RFAL_TXRX_FLAGS_CRC_TX_MANUAL
|
||||
#define FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON RFAL_TXRX_FLAGS_AGC_ON
|
||||
#define FURI_HAL_NFC_LL_TXRX_FLAGS_PAR_RX_REMV RFAL_TXRX_FLAGS_PAR_RX_REMV
|
||||
#define FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_RX_KEEP RFAL_TXRX_FLAGS_CRC_RX_KEEP
|
||||
|
||||
typedef enum {
|
||||
FuriHalNfcReturnOk = 0, /*!< no error occurred */
|
||||
FuriHalNfcReturnNomem = 1, /*!< not enough memory to perform the requested operation */
|
||||
FuriHalNfcReturnBusy = 2, /*!< device or resource busy */
|
||||
FuriHalNfcReturnIo = 3, /*!< generic IO error */
|
||||
FuriHalNfcReturnTimeout = 4, /*!< error due to timeout */
|
||||
FuriHalNfcReturnRequest =
|
||||
5, /*!< invalid request or requested function can't be executed at the moment */
|
||||
FuriHalNfcReturnNomsg = 6, /*!< No message of desired type */
|
||||
FuriHalNfcReturnParam = 7, /*!< Parameter error */
|
||||
FuriHalNfcReturnSystem = 8, /*!< System error */
|
||||
FuriHalNfcReturnFraming = 9, /*!< Framing error */
|
||||
FuriHalNfcReturnOverrun = 10, /*!< lost one or more received bytes */
|
||||
FuriHalNfcReturnProto = 11, /*!< protocol error */
|
||||
FuriHalNfcReturnInternal = 12, /*!< Internal Error */
|
||||
FuriHalNfcReturnAgain = 13, /*!< Call again */
|
||||
FuriHalNfcReturnMemCorrupt = 14, /*!< memory corruption */
|
||||
FuriHalNfcReturnNotImplemented = 15, /*!< not implemented */
|
||||
FuriHalNfcReturnPcCorrupt =
|
||||
16, /*!< Program Counter has been manipulated or spike/noise trigger illegal operation */
|
||||
FuriHalNfcReturnSend = 17, /*!< error sending*/
|
||||
FuriHalNfcReturnIgnore = 18, /*!< indicates error detected but to be ignored */
|
||||
FuriHalNfcReturnSemantic = 19, /*!< indicates error in state machine (unexpected cmd) */
|
||||
FuriHalNfcReturnSyntax = 20, /*!< indicates error in state machine (unknown cmd) */
|
||||
FuriHalNfcReturnCrc = 21, /*!< crc error */
|
||||
FuriHalNfcReturnNotfound = 22, /*!< transponder not found */
|
||||
FuriHalNfcReturnNotunique =
|
||||
23, /*!< transponder not unique - more than one transponder in field */
|
||||
FuriHalNfcReturnNotsupp = 24, /*!< requested operation not supported */
|
||||
FuriHalNfcReturnWrite = 25, /*!< write error */
|
||||
FuriHalNfcReturnFifo = 26, /*!< fifo over or underflow error */
|
||||
FuriHalNfcReturnPar = 27, /*!< parity error */
|
||||
FuriHalNfcReturnDone = 28, /*!< transfer has already finished */
|
||||
FuriHalNfcReturnRfCollision =
|
||||
29, /*!< collision error (Bit Collision or during RF Collision avoidance ) */
|
||||
FuriHalNfcReturnHwOverrun = 30, /*!< lost one or more received bytes */
|
||||
FuriHalNfcReturnReleaseReq = 31, /*!< device requested release */
|
||||
FuriHalNfcReturnSleepReq = 32, /*!< device requested sleep */
|
||||
FuriHalNfcReturnWrongState = 33, /*!< incorrent state for requested operation */
|
||||
FuriHalNfcReturnMaxReruns = 34, /*!< blocking procedure reached maximum runs */
|
||||
FuriHalNfcReturnDisabled = 35, /*!< operation aborted due to disabled configuration */
|
||||
FuriHalNfcReturnHwMismatch = 36, /*!< expected hw do not match */
|
||||
FuriHalNfcReturnLinkLoss =
|
||||
37, /*!< Other device's field didn't behave as expected: turned off by Initiator in Passive mode, or AP2P did not turn on field */
|
||||
FuriHalNfcReturnInvalidHandle = 38, /*!< invalid or not initalized device handle */
|
||||
FuriHalNfcReturnIncompleteByte = 40, /*!< Incomplete byte rcvd */
|
||||
FuriHalNfcReturnIncompleteByte01 = 41, /*!< Incomplete byte rcvd - 1 bit */
|
||||
FuriHalNfcReturnIncompleteByte02 = 42, /*!< Incomplete byte rcvd - 2 bit */
|
||||
FuriHalNfcReturnIncompleteByte03 = 43, /*!< Incomplete byte rcvd - 3 bit */
|
||||
FuriHalNfcReturnIncompleteByte04 = 44, /*!< Incomplete byte rcvd - 4 bit */
|
||||
FuriHalNfcReturnIncompleteByte05 = 45, /*!< Incomplete byte rcvd - 5 bit */
|
||||
FuriHalNfcReturnIncompleteByte06 = 46, /*!< Incomplete byte rcvd - 6 bit */
|
||||
FuriHalNfcReturnIncompleteByte07 = 47, /*!< Incomplete byte rcvd - 7 bit */
|
||||
} FuriHalNfcReturn;
|
||||
|
||||
typedef enum {
|
||||
FuriHalNfcModeNone = 0, /*!< No mode selected/defined */
|
||||
FuriHalNfcModePollNfca = 1, /*!< Mode to perform as NFCA (ISO14443A) Poller (PCD) */
|
||||
FuriHalNfcModePollNfcaT1t = 2, /*!< Mode to perform as NFCA T1T (Topaz) Poller (PCD) */
|
||||
FuriHalNfcModePollNfcb = 3, /*!< Mode to perform as NFCB (ISO14443B) Poller (PCD) */
|
||||
FuriHalNfcModePollBPrime = 4, /*!< Mode to perform as B' Calypso (Innovatron) (PCD) */
|
||||
FuriHalNfcModePollBCts = 5, /*!< Mode to perform as CTS Poller (PCD) */
|
||||
FuriHalNfcModePollNfcf = 6, /*!< Mode to perform as NFCF (FeliCa) Poller (PCD) */
|
||||
FuriHalNfcModePollNfcv = 7, /*!< Mode to perform as NFCV (ISO15963) Poller (PCD) */
|
||||
FuriHalNfcModePollPicopass = 8, /*!< Mode to perform as PicoPass / iClass Poller (PCD) */
|
||||
FuriHalNfcModePollActiveP2p = 9, /*!< Mode to perform as Active P2P (ISO18092) Initiator */
|
||||
FuriHalNfcModeListenNfca = 10, /*!< Mode to perform as NFCA (ISO14443A) Listener (PICC) */
|
||||
FuriHalNfcModeListenNfcb = 11, /*!< Mode to perform as NFCA (ISO14443B) Listener (PICC) */
|
||||
FuriHalNfcModeListenNfcf = 12, /*!< Mode to perform as NFCA (ISO15963) Listener (PICC) */
|
||||
FuriHalNfcModeListenActiveP2p = 13 /*!< Mode to perform as Active P2P (ISO18092) Target */
|
||||
} FuriHalNfcMode;
|
||||
|
||||
typedef enum {
|
||||
FuriHalNfcBitrate106 = 0, /*!< Bit Rate 106 kbit/s (fc/128) */
|
||||
FuriHalNfcBitrate212 = 1, /*!< Bit Rate 212 kbit/s (fc/64) */
|
||||
FuriHalNfcBitrate424 = 2, /*!< Bit Rate 424 kbit/s (fc/32) */
|
||||
FuriHalNfcBitrate848 = 3, /*!< Bit Rate 848 kbit/s (fc/16) */
|
||||
FuriHalNfcBitrate1695 = 4, /*!< Bit Rate 1695 kbit/s (fc/8) */
|
||||
FuriHalNfcBitrate3390 = 5, /*!< Bit Rate 3390 kbit/s (fc/4) */
|
||||
FuriHalNfcBitrate6780 = 6, /*!< Bit Rate 6780 kbit/s (fc/2) */
|
||||
FuriHalNfcBitrate13560 = 7, /*!< Bit Rate 13560 kbit/s (fc) */
|
||||
FuriHalNfcBitrate52p97 = 0xEB, /*!< Bit Rate 52.97 kbit/s (fc/256) Fast Mode VICC->VCD */
|
||||
FuriHalNfcBitrate26p48 =
|
||||
0xEC, /*!< Bit Rate 26,48 kbit/s (fc/512) NFCV VICC->VCD & VCD->VICC 1of4 */
|
||||
FuriHalNfcBitrate1p66 = 0xED, /*!< Bit Rate 1,66 kbit/s (fc/8192) NFCV VCD->VICC 1of256 */
|
||||
FuriHalNfcBitrateKeep = 0xFF /*!< Value indicating to keep the same previous bit rate */
|
||||
} FuriHalNfcBitrate;
|
||||
|
||||
FuriHalNfcReturn
|
||||
furi_hal_nfc_ll_set_mode(FuriHalNfcMode mode, FuriHalNfcBitrate txBR, FuriHalNfcBitrate rxBR);
|
||||
|
||||
#define FURI_HAL_NFC_LL_GT_NFCA furi_hal_nfc_ll_ms2fc(5U) /*!< GTA Digital 2.0 6.10.4.1 & B.2 */
|
||||
#define FURI_HAL_NFC_LL_GT_NFCB furi_hal_nfc_ll_ms2fc(5U) /*!< GTB Digital 2.0 7.9.4.1 & B.3 */
|
||||
#define FURI_HAL_NFC_LL_GT_NFCF furi_hal_nfc_ll_ms2fc(20U) /*!< GTF Digital 2.0 8.7.4.1 & B.4 */
|
||||
#define FURI_HAL_NFC_LL_GT_NFCV furi_hal_nfc_ll_ms2fc(5U) /*!< GTV Digital 2.0 9.7.5.1 & B.5 */
|
||||
#define FURI_HAL_NFC_LL_GT_PICOPASS furi_hal_nfc_ll_ms2fc(1U) /*!< GT Picopass */
|
||||
#define FURI_HAL_NFC_LL_GT_AP2P furi_hal_nfc_ll_ms2fc(5U) /*!< TIRFG Ecma 340 11.1.1 */
|
||||
#define FURI_HAL_NFC_LL_GT_AP2P_ADJUSTED \
|
||||
furi_hal_nfc_ll_ms2fc( \
|
||||
5U + \
|
||||
25U) /*!< Adjusted GT for greater interoperability (Sony XPERIA P, Nokia N9, Huawei P2) */
|
||||
|
||||
void furi_hal_nfc_ll_set_guard_time(uint32_t cycles);
|
||||
|
||||
typedef enum {
|
||||
FuriHalNfcErrorHandlingNone = 0, /*!< No special error handling will be performed */
|
||||
FuriHalNfcErrorHandlingNfc = 1, /*!< Error handling set to perform as NFC compliant device */
|
||||
FuriHalNfcErrorHandlingEmvco =
|
||||
2 /*!< Error handling set to perform as EMVCo compliant device */
|
||||
} FuriHalNfcErrorHandling;
|
||||
|
||||
void furi_hal_nfc_ll_set_error_handling(FuriHalNfcErrorHandling eHandling);
|
||||
|
||||
/* RFAL Frame Delay Time (FDT) Listen default values */
|
||||
#define FURI_HAL_NFC_LL_FDT_LISTEN_NFCA_POLLER \
|
||||
1172U /*!< FDTA,LISTEN,MIN (n=9) Last bit: Logic "1" - tnn,min/2 Digital 1.1 6.10 ; EMV CCP Spec Book D v2.01 4.8.1.3 */
|
||||
#define FURI_HAL_NFC_LL_FDT_LISTEN_NFCB_POLLER \
|
||||
1008U /*!< TR0B,MIN Digital 1.1 7.1.3 & A.3 ; EMV CCP Spec Book D v2.01 4.8.1.3 & Table A.5 */
|
||||
#define FURI_HAL_NFC_LL_FDT_LISTEN_NFCF_POLLER \
|
||||
2672U /*!< TR0F,LISTEN,MIN Digital 1.1 8.7.1.1 & A.4 */
|
||||
#define FURI_HAL_NFC_LL_FDT_LISTEN_NFCV_POLLER \
|
||||
4310U /*!< FDTV,LISTEN,MIN t1 min Digital 2.1 B.5 ; ISO15693-3 2009 9.1 */
|
||||
#define FURI_HAL_NFC_LL_FDT_LISTEN_PICOPASS_POLLER \
|
||||
3400U /*!< ISO15693 t1 min - observed adjustment */
|
||||
#define FURI_HAL_NFC_LL_FDT_LISTEN_AP2P_POLLER \
|
||||
64U /*!< FDT AP2P No actual FDTListen is required as fields switch and collision avoidance */
|
||||
#define FURI_HAL_NFC_LL_FDT_LISTEN_NFCA_LISTENER 1172U /*!< FDTA,LISTEN,MIN Digital 1.1 6.10 */
|
||||
#define FURI_HAL_NFC_LL_FDT_LISTEN_NFCB_LISTENER \
|
||||
1024U /*!< TR0B,MIN Digital 1.1 7.1.3 & A.3 ; EMV CCP Spec Book D v2.01 4.8.1.3 & Table A.5 */
|
||||
#define FURI_HAL_NFC_LL_FDT_LISTEN_NFCF_LISTENER \
|
||||
2688U /*!< TR0F,LISTEN,MIN Digital 2.1 8.7.1.1 & B.4 */
|
||||
#define FURI_HAL_NFC_LL_FDT_LISTEN_AP2P_LISTENER \
|
||||
64U /*!< FDT AP2P No actual FDTListen exists as fields switch and collision avoidance */
|
||||
|
||||
void furi_hal_nfc_ll_set_fdt_listen(uint32_t cycles);
|
||||
|
||||
/* RFAL Frame Delay Time (FDT) Poll default values */
|
||||
#define FURI_HAL_NFC_LL_FDT_POLL_NFCA_POLLER \
|
||||
6780U /*!< FDTA,POLL,MIN Digital 1.1 6.10.3.1 & A.2 */
|
||||
#define FURI_HAL_NFC_LL_FDT_POLL_NFCA_T1T_POLLER \
|
||||
384U /*!< RRDDT1T,MIN,B1 Digital 1.1 10.7.1 & A.5 */
|
||||
#define FURI_HAL_NFC_LL_FDT_POLL_NFCB_POLLER \
|
||||
6780U /*!< FDTB,POLL,MIN = TR2B,MIN,DEFAULT Digital 1.1 7.9.3 & A.3 ; EMVCo 3.0 FDTB,PCD,MIN Table A.5 */
|
||||
#define FURI_HAL_NFC_LL_FDT_POLL_NFCF_POLLER 6800U /*!< FDTF,POLL,MIN Digital 2.1 8.7.3 & B.4 */
|
||||
#define FURI_HAL_NFC_LL_FDT_POLL_NFCV_POLLER 4192U /*!< FDTV,POLL Digital 2.1 9.7.3.1 & B.5 */
|
||||
#define FURI_HAL_NFC_LL_FDT_POLL_PICOPASS_POLLER 1790U /*!< FDT Max */
|
||||
#define FURI_HAL_NFC_LL_FDT_POLL_AP2P_POLLER \
|
||||
0U /*!< FDT AP2P No actual FDTPoll exists as fields switch and collision avoidance */
|
||||
|
||||
void furi_hal_nfc_ll_set_fdt_poll(uint32_t FDTPoll);
|
||||
|
||||
void furi_hal_nfc_ll_txrx_on();
|
||||
|
||||
void furi_hal_nfc_ll_txrx_off();
|
||||
|
||||
// TODO rework all pollers with furi_hal_nfc_ll_txrx_bits
|
||||
FuriHalNfcReturn furi_hal_nfc_ll_txrx(
|
||||
uint8_t* txBuf,
|
||||
uint16_t txBufLen,
|
||||
uint8_t* rxBuf,
|
||||
uint16_t rxBufLen,
|
||||
uint16_t* actLen,
|
||||
uint32_t flags,
|
||||
uint32_t fwt);
|
||||
|
||||
FuriHalNfcReturn furi_hal_nfc_ll_txrx_bits(
|
||||
uint8_t* txBuf,
|
||||
uint16_t txBufLen,
|
||||
uint8_t* rxBuf,
|
||||
uint16_t rxBufLen,
|
||||
uint16_t* actLen,
|
||||
uint32_t flags,
|
||||
uint32_t fwt);
|
||||
|
||||
void furi_hal_nfc_ll_poll();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -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>
|
||||
#include <stm32wbxx_ll_rng.h>
|
||||
|
||||
@@ -62,6 +62,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 +90,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 +144,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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
136
firmware/targets/f7/furi_hal/furi_hal_rfid.h
Normal file
136
firmware/targets/f7/furi_hal/furi_hal_rfid.h
Normal file
@@ -0,0 +1,136 @@
|
||||
/**
|
||||
* @file furi_hal_rfid.h
|
||||
* RFID HAL API
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Initialize RFID subsystem
|
||||
*/
|
||||
void furi_hal_rfid_init();
|
||||
|
||||
/** Config rfid pins to reset state
|
||||
*/
|
||||
void furi_hal_rfid_pins_reset();
|
||||
|
||||
/** Config rfid pins to emulate state
|
||||
*/
|
||||
void furi_hal_rfid_pins_emulate();
|
||||
|
||||
/** Config rfid pins to read state
|
||||
*/
|
||||
void furi_hal_rfid_pins_read();
|
||||
|
||||
/** Release rfid pull pin
|
||||
*/
|
||||
void furi_hal_rfid_pin_pull_release();
|
||||
|
||||
/** Pulldown rfid pull pin
|
||||
*/
|
||||
void furi_hal_rfid_pin_pull_pulldown();
|
||||
|
||||
/** Config rfid timer to read state
|
||||
*
|
||||
* @param freq timer frequency
|
||||
* @param duty_cycle timer duty cycle, 0.0-1.0
|
||||
*/
|
||||
void furi_hal_rfid_tim_read(float freq, float duty_cycle);
|
||||
|
||||
/** Start read timer
|
||||
*/
|
||||
void furi_hal_rfid_tim_read_start();
|
||||
|
||||
/** Stop read timer
|
||||
*/
|
||||
void furi_hal_rfid_tim_read_stop();
|
||||
|
||||
/** Config rfid timer to emulate state
|
||||
*
|
||||
* @param freq timer frequency
|
||||
*/
|
||||
void furi_hal_rfid_tim_emulate(float freq);
|
||||
|
||||
typedef void (*FuriHalRfidEmulateCallback)(void* context);
|
||||
|
||||
/** Start emulation timer
|
||||
*/
|
||||
void furi_hal_rfid_tim_emulate_start(FuriHalRfidEmulateCallback callback, void* context);
|
||||
|
||||
typedef void (*FuriHalRfidReadCaptureCallback)(bool level, uint32_t duration, void* context);
|
||||
|
||||
void furi_hal_rfid_tim_read_capture_start(FuriHalRfidReadCaptureCallback callback, void* context);
|
||||
|
||||
void furi_hal_rfid_tim_read_capture_stop();
|
||||
|
||||
typedef void (*FuriHalRfidDMACallback)(bool half, void* context);
|
||||
|
||||
void furi_hal_rfid_tim_emulate_dma_start(
|
||||
uint32_t* duration,
|
||||
uint32_t* pulse,
|
||||
size_t length,
|
||||
FuriHalRfidDMACallback callback,
|
||||
void* context);
|
||||
|
||||
void furi_hal_rfid_tim_emulate_dma_stop();
|
||||
|
||||
/** Stop emulation timer
|
||||
*/
|
||||
void furi_hal_rfid_tim_emulate_stop();
|
||||
|
||||
/** Config rfid timers to reset state
|
||||
*/
|
||||
void furi_hal_rfid_tim_reset();
|
||||
|
||||
/** Set emulation timer period
|
||||
*
|
||||
* @param period overall duration
|
||||
*/
|
||||
void furi_hal_rfid_set_emulate_period(uint32_t period);
|
||||
|
||||
/** Set emulation timer pulse
|
||||
*
|
||||
* @param pulse duration of high level
|
||||
*/
|
||||
void furi_hal_rfid_set_emulate_pulse(uint32_t pulse);
|
||||
|
||||
/** Set read timer period
|
||||
*
|
||||
* @param period overall duration
|
||||
*/
|
||||
void furi_hal_rfid_set_read_period(uint32_t period);
|
||||
|
||||
/** Set read timer pulse
|
||||
*
|
||||
* @param pulse duration of high level
|
||||
*/
|
||||
void furi_hal_rfid_set_read_pulse(uint32_t pulse);
|
||||
|
||||
/** Сhanges the configuration of the RFID timer "on a fly"
|
||||
*
|
||||
* @param freq new frequency
|
||||
* @param duty_cycle new duty cycle
|
||||
*/
|
||||
void furi_hal_rfid_change_read_config(float freq, float duty_cycle);
|
||||
|
||||
/** Start/Enable comparator */
|
||||
void furi_hal_rfid_comp_start();
|
||||
|
||||
/** Stop/Disable comparator */
|
||||
void furi_hal_rfid_comp_stop();
|
||||
|
||||
typedef void (*FuriHalRfidCompCallback)(bool level, void* context);
|
||||
|
||||
/** Set comparator callback */
|
||||
void furi_hal_rfid_comp_set_callback(FuriHalRfidCompCallback callback, void* context);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
263
firmware/targets/f7/furi_hal/furi_hal_subghz.h
Normal file
263
firmware/targets/f7/furi_hal/furi_hal_subghz.h
Normal file
@@ -0,0 +1,263 @@
|
||||
/**
|
||||
* @file furi_hal_subghz.h
|
||||
* SubGhz HAL API
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <toolbox/level_duration.h>
|
||||
#include <furi_hal_gpio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Low level buffer dimensions and guard times */
|
||||
#define API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL (256)
|
||||
#define API_HAL_SUBGHZ_ASYNC_TX_BUFFER_HALF (API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL / 2)
|
||||
#define API_HAL_SUBGHZ_ASYNC_TX_GUARD_TIME 999
|
||||
|
||||
/** Radio Presets */
|
||||
typedef enum {
|
||||
FuriHalSubGhzPresetIDLE, /**< default configuration */
|
||||
FuriHalSubGhzPresetOok270Async, /**< OOK, bandwidth 270kHz, asynchronous */
|
||||
FuriHalSubGhzPresetOok650Async, /**< OOK, bandwidth 650kHz, asynchronous */
|
||||
FuriHalSubGhzPreset2FSKDev238Async, /**< FM, deviation 2.380371 kHz, asynchronous */
|
||||
FuriHalSubGhzPreset2FSKDev476Async, /**< FM, deviation 47.60742 kHz, asynchronous */
|
||||
FuriHalSubGhzPresetMSK99_97KbAsync, /**< MSK, deviation 47.60742 kHz, 99.97Kb/s, asynchronous */
|
||||
FuriHalSubGhzPresetGFSK9_99KbAsync, /**< GFSK, deviation 19.042969 kHz, 9.996Kb/s, asynchronous */
|
||||
FuriHalSubGhzPresetCustom, /**Custom Preset*/
|
||||
} FuriHalSubGhzPreset;
|
||||
|
||||
/** Switchable Radio Paths */
|
||||
typedef enum {
|
||||
FuriHalSubGhzPathIsolate, /**< Isolate Radio from antenna */
|
||||
FuriHalSubGhzPath433, /**< Center Frequency: 433MHz. Path 1: SW1RF1-SW2RF2, LCLCL */
|
||||
FuriHalSubGhzPath315, /**< Center Frequency: 315MHz. Path 2: SW1RF2-SW2RF1, LCLCLCL */
|
||||
FuriHalSubGhzPath868, /**< Center Frequency: 868MHz. Path 3: SW1RF3-SW2RF3, LCLC */
|
||||
} FuriHalSubGhzPath;
|
||||
|
||||
/** SubGhz state */
|
||||
typedef enum {
|
||||
SubGhzStateInit, /**< Init pending */
|
||||
|
||||
SubGhzStateIdle, /**< Idle, energy save mode */
|
||||
|
||||
SubGhzStateAsyncRx, /**< Async RX started */
|
||||
|
||||
SubGhzStateAsyncTx, /**< Async TX started, DMA and timer is on */
|
||||
SubGhzStateAsyncTxLast, /**< Async TX continue, DMA completed and timer got last value to go */
|
||||
SubGhzStateAsyncTxEnd, /**< Async TX complete, cleanup needed */
|
||||
|
||||
} SubGhzState;
|
||||
|
||||
/** SubGhz regulation, receive transmission on the current frequency for the
|
||||
* region */
|
||||
typedef enum {
|
||||
SubGhzRegulationOnlyRx, /**only Rx*/
|
||||
SubGhzRegulationTxRx, /**TxRx*/
|
||||
} SubGhzRegulation;
|
||||
|
||||
/* Mirror RX/TX async modulation signal to specified pin
|
||||
*
|
||||
* @warning Configures pin to output mode. Make sure it is not connected
|
||||
* directly to power or ground.
|
||||
*
|
||||
* @param[in] pin pointer to the gpio pin structure or NULL to disable
|
||||
*/
|
||||
void furi_hal_subghz_set_async_mirror_pin(const GpioPin* pin);
|
||||
|
||||
/** Initialize and switch to power save mode Used by internal API-HAL
|
||||
* initialization routine Can be used to reinitialize device to safe state and
|
||||
* send it to sleep
|
||||
*/
|
||||
void furi_hal_subghz_init();
|
||||
|
||||
/** Send device to sleep mode
|
||||
*/
|
||||
void furi_hal_subghz_sleep();
|
||||
|
||||
/** Dump info to stdout
|
||||
*/
|
||||
void furi_hal_subghz_dump_state();
|
||||
|
||||
/** Load registers from preset by preset name
|
||||
*
|
||||
* @param preset to load
|
||||
*/
|
||||
void furi_hal_subghz_load_preset(FuriHalSubGhzPreset preset);
|
||||
|
||||
/** Load custom registers from preset
|
||||
*
|
||||
* @param preset_data registers to load
|
||||
*/
|
||||
void furi_hal_subghz_load_custom_preset(uint8_t* preset_data);
|
||||
|
||||
/** Load registers
|
||||
*
|
||||
* @param data Registers data
|
||||
*/
|
||||
void furi_hal_subghz_load_registers(uint8_t* data);
|
||||
|
||||
/** Load PATABLE
|
||||
*
|
||||
* @param data 8 uint8_t values
|
||||
*/
|
||||
void furi_hal_subghz_load_patable(const uint8_t data[8]);
|
||||
|
||||
/** Write packet to FIFO
|
||||
*
|
||||
* @param data bytes array
|
||||
* @param size size
|
||||
*/
|
||||
void furi_hal_subghz_write_packet(const uint8_t* data, uint8_t size);
|
||||
|
||||
/** Check if receive pipe is not empty
|
||||
*
|
||||
* @return true if not empty
|
||||
*/
|
||||
bool furi_hal_subghz_rx_pipe_not_empty();
|
||||
|
||||
/** Check if received data crc is valid
|
||||
*
|
||||
* @return true if valid
|
||||
*/
|
||||
bool furi_hal_subghz_is_rx_data_crc_valid();
|
||||
|
||||
/** Read packet from FIFO
|
||||
*
|
||||
* @param data pointer
|
||||
* @param size size
|
||||
*/
|
||||
void furi_hal_subghz_read_packet(uint8_t* data, uint8_t* size);
|
||||
|
||||
/** Flush rx FIFO buffer
|
||||
*/
|
||||
void furi_hal_subghz_flush_rx();
|
||||
|
||||
/** Flush tx FIFO buffer
|
||||
*/
|
||||
void furi_hal_subghz_flush_tx();
|
||||
|
||||
/** Shutdown Issue SPWD command
|
||||
* @warning registers content will be lost
|
||||
*/
|
||||
void furi_hal_subghz_shutdown();
|
||||
|
||||
/** Reset Issue reset command
|
||||
* @warning registers content will be lost
|
||||
*/
|
||||
void furi_hal_subghz_reset();
|
||||
|
||||
/** Switch to Idle
|
||||
*/
|
||||
void furi_hal_subghz_idle();
|
||||
|
||||
/** Switch to Receive
|
||||
*/
|
||||
void furi_hal_subghz_rx();
|
||||
|
||||
/** Switch to Transmit
|
||||
*
|
||||
* @return true if the transfer is allowed by belonging to the region
|
||||
*/
|
||||
bool furi_hal_subghz_tx();
|
||||
|
||||
/** Get RSSI value in dBm
|
||||
*
|
||||
* @return RSSI value
|
||||
*/
|
||||
float furi_hal_subghz_get_rssi();
|
||||
|
||||
/** Get LQI
|
||||
*
|
||||
* @return LQI value
|
||||
*/
|
||||
uint8_t furi_hal_subghz_get_lqi();
|
||||
|
||||
/** Check if frequency is in valid range
|
||||
*
|
||||
* @param value frequency in Hz
|
||||
*
|
||||
* @return true if frequency is valid, otherwise false
|
||||
*/
|
||||
bool furi_hal_subghz_is_frequency_valid(uint32_t value);
|
||||
|
||||
/** Set frequency and path This function automatically selects antenna matching
|
||||
* network
|
||||
*
|
||||
* @param value frequency in Hz
|
||||
*
|
||||
* @return real frequency in Hz
|
||||
*/
|
||||
uint32_t furi_hal_subghz_set_frequency_and_path(uint32_t value);
|
||||
|
||||
/** Сheck if transmission is allowed on this frequency with your current config
|
||||
*
|
||||
* @param value frequency in Hz
|
||||
*
|
||||
* @return true if allowed
|
||||
*/
|
||||
bool furi_hal_subghz_is_tx_allowed(uint32_t value);
|
||||
|
||||
/** Set frequency
|
||||
*
|
||||
* @param value frequency in Hz
|
||||
*
|
||||
* @return real frequency in Hz
|
||||
*/
|
||||
uint32_t furi_hal_subghz_set_frequency(uint32_t value);
|
||||
|
||||
/** Set path
|
||||
*
|
||||
* @param path path to use
|
||||
*/
|
||||
void furi_hal_subghz_set_path(FuriHalSubGhzPath path);
|
||||
|
||||
/* High Level API */
|
||||
|
||||
/** Signal Timings Capture callback */
|
||||
typedef void (*FuriHalSubGhzCaptureCallback)(bool level, uint32_t duration, void* context);
|
||||
|
||||
/** Enable signal timings capture Initializes GPIO and TIM2 for timings capture
|
||||
*
|
||||
* @param callback FuriHalSubGhzCaptureCallback
|
||||
* @param context callback context
|
||||
*/
|
||||
void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* context);
|
||||
|
||||
/** Disable signal timings capture Resets GPIO and TIM2
|
||||
*/
|
||||
void furi_hal_subghz_stop_async_rx();
|
||||
|
||||
/** Async TX callback type
|
||||
* @param context callback context
|
||||
* @return LevelDuration
|
||||
*/
|
||||
typedef LevelDuration (*FuriHalSubGhzAsyncTxCallback)(void* context);
|
||||
|
||||
/** Start async TX Initializes GPIO, TIM2 and DMA1 for signal output
|
||||
*
|
||||
* @param callback FuriHalSubGhzAsyncTxCallback
|
||||
* @param context callback context
|
||||
*
|
||||
* @return true if the transfer is allowed by belonging to the region
|
||||
*/
|
||||
bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* context);
|
||||
|
||||
/** Wait for async transmission to complete
|
||||
*
|
||||
* @return true if TX complete
|
||||
*/
|
||||
bool furi_hal_subghz_is_async_tx_complete();
|
||||
|
||||
/** Stop async transmission and cleanup resources Resets GPIO, TIM2, and DMA1
|
||||
*/
|
||||
void furi_hal_subghz_stop_async_tx();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
6
firmware/targets/f7/furi_hal/furi_hal_target_hw.h
Normal file
6
firmware/targets/f7/furi_hal/furi_hal_target_hw.h
Normal file
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -224,14 +224,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;
|
||||
|
||||
21
firmware/targets/f7/furi_hal/furi_hal_version_device.c
Normal file
21
firmware/targets/f7/furi_hal/furi_hal_version_device.c
Normal file
@@ -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
|
||||
@@ -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);
|
||||
54
firmware/targets/f7/src/recovery.c
Normal file
54
firmware/targets/f7/src/recovery.c
Normal file
@@ -0,0 +1,54 @@
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
#include <flipper.h>
|
||||
#include <alt_boot.h>
|
||||
#include <u8g2_glue.h>
|
||||
#include <assets_icons.h>
|
||||
|
||||
#define COUNTER_VALUE (100U)
|
||||
|
||||
static void flipper_boot_recovery_draw_splash(u8g2_t* fb, size_t progress) {
|
||||
u8g2_ClearBuffer(fb);
|
||||
u8g2_SetDrawColor(fb, 0x01);
|
||||
|
||||
u8g2_SetFont(fb, u8g2_font_helvB08_tr);
|
||||
u8g2_DrawStr(fb, 2, 8, "PIN and Factory Reset");
|
||||
u8g2_SetFont(fb, u8g2_font_haxrcorp4089_tr);
|
||||
u8g2_DrawStr(fb, 2, 21, "Hold Right to confirm");
|
||||
u8g2_DrawStr(fb, 2, 31, "Press Down to cancel");
|
||||
|
||||
if(progress < COUNTER_VALUE) {
|
||||
size_t width = progress / (COUNTER_VALUE / 100);
|
||||
u8g2_DrawBox(fb, 14 + (50 - width / 2), 54, width, 3);
|
||||
}
|
||||
|
||||
u8g2_SetPowerSave(fb, 0);
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -42,7 +42,7 @@ 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();
|
||||
if(!hal_sd_detect()) {
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
*****************************************************************************
|
||||
**
|
||||
** File : stm32wb55xx_flash_cm4.ld
|
||||
** File : stm32wb55xx_flash.ld
|
||||
**
|
||||
** Abstract : System Workbench Minimal System calls file
|
||||
**
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
*****************************************************************************
|
||||
**
|
||||
** File : stm32wb55xx_flash_cm4.ld
|
||||
** File : stm32wb55xx_ram_fw.ld
|
||||
**
|
||||
** Abstract : System Workbench Minimal System calls file
|
||||
**
|
||||
|
||||
45
firmware/targets/f7/target.json
Normal file
45
firmware/targets/f7/target.json
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
"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",
|
||||
"misc",
|
||||
"mbedtls",
|
||||
"lfrfid",
|
||||
"flipper_application",
|
||||
"flipperformat",
|
||||
"toolbox"
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user