diff --git a/applications/accessor/accessor_app.cpp b/applications/accessor/accessor_app.cpp index 064c0f10..21b2e258 100644 --- a/applications/accessor/accessor_app.cpp +++ b/applications/accessor/accessor_app.cpp @@ -9,7 +9,7 @@ void AccessorApp::run(void) { bool exit = false; wiegand.begin(); - onewire_master.start(); + onewire_host_start(onewire_host); scenes[current_scene]->on_enter(this); @@ -28,19 +28,20 @@ void AccessorApp::run(void) { scenes[current_scene]->on_exit(this); wiegand.end(); - onewire_master.stop(); + onewire_host_stop(onewire_host); } -AccessorApp::AccessorApp() - : onewire_master{&ibutton_gpio} { +AccessorApp::AccessorApp() { furi_hal_power_insomnia_enter(); notification = static_cast(furi_record_open("notification")); + onewire_host = onewire_host_alloc(); furi_hal_power_enable_otg(); } AccessorApp::~AccessorApp() { furi_hal_power_disable_otg(); furi_record_close("notification"); + onewire_host_free(onewire_host); furi_hal_power_insomnia_exit(); } @@ -136,6 +137,6 @@ WIEGAND* AccessorApp::get_wiegand() { return &wiegand; } -OneWireMaster* AccessorApp::get_one_wire() { - return &onewire_master; +OneWireHost* AccessorApp::get_one_wire() { + return onewire_host; } \ No newline at end of file diff --git a/applications/accessor/accessor_app.h b/applications/accessor/accessor_app.h index 9af62e1c..ce18c177 100644 --- a/applications/accessor/accessor_app.h +++ b/applications/accessor/accessor_app.h @@ -2,13 +2,9 @@ #include #include #include "accessor_view_manager.h" - #include "scene/accessor_scene_start.h" - #include "helpers/wiegand.h" - -#include - +#include #include class AccessorApp { @@ -37,7 +33,7 @@ public: void set_text_store(const char* text...); WIEGAND* get_wiegand(); - OneWireMaster* get_one_wire(); + OneWireHost* get_one_wire(); private: std::list previous_scenes_list = {Scene::Exit}; @@ -52,7 +48,7 @@ private: char text_store[text_store_size + 1]; WIEGAND wiegand; - OneWireMaster onewire_master; + OneWireHost* onewire_host; NotificationApp* notification; }; \ No newline at end of file diff --git a/applications/accessor/helpers/wiegand.cpp b/applications/accessor/helpers/wiegand.cpp index c1247387..79c9f723 100644 --- a/applications/accessor/helpers/wiegand.cpp +++ b/applications/accessor/helpers/wiegand.cpp @@ -55,19 +55,19 @@ void WIEGAND::begin() { _wiegandType = 0; _bitCount = 0; - hal_gpio_init_simple(pinD0, GpioModeInterruptFall); // Set D0 pin as input - hal_gpio_init_simple(pinD1, GpioModeInterruptFall); // Set D1 pin as input + furi_hal_gpio_init_simple(pinD0, GpioModeInterruptFall); // Set D0 pin as input + furi_hal_gpio_init_simple(pinD1, GpioModeInterruptFall); // Set D1 pin as input - hal_gpio_add_int_callback(pinD0, input_isr_d0, this); - hal_gpio_add_int_callback(pinD1, input_isr_d1, this); + furi_hal_gpio_add_int_callback(pinD0, input_isr_d0, this); + furi_hal_gpio_add_int_callback(pinD1, input_isr_d1, this); } void WIEGAND::end() { - hal_gpio_remove_int_callback(pinD0); - hal_gpio_remove_int_callback(pinD1); + furi_hal_gpio_remove_int_callback(pinD0); + furi_hal_gpio_remove_int_callback(pinD1); - hal_gpio_init_simple(pinD0, GpioModeAnalog); - hal_gpio_init_simple(pinD1, GpioModeAnalog); + furi_hal_gpio_init_simple(pinD0, GpioModeAnalog); + furi_hal_gpio_init_simple(pinD1, GpioModeAnalog); } void WIEGAND::ReadD0() { diff --git a/applications/accessor/scene/accessor_scene_start.cpp b/applications/accessor/scene/accessor_scene_start.cpp index a82fc275..6f5a4d11 100644 --- a/applications/accessor/scene/accessor_scene_start.cpp +++ b/applications/accessor/scene/accessor_scene_start.cpp @@ -21,7 +21,7 @@ bool AccessorSceneStart::on_event(AccessorApp* app, AccessorEvent* event) { if(event->type == AccessorEvent::Type::Tick) { WIEGAND* wiegand = app->get_wiegand(); Popup* popup = app->get_view_manager()->get_popup(); - OneWireMaster* onewire = app->get_one_wire(); + OneWireHost* onewire_host = app->get_one_wire(); uint8_t data[8] = {0, 0, 0, 0, 0, 0, 0, 0}; uint8_t type = 0; @@ -38,11 +38,11 @@ bool AccessorSceneStart::on_event(AccessorApp* app, AccessorEvent* event) { } } else { FURI_CRITICAL_ENTER(); - if(onewire->reset()) { + if(onewire_host_reset(onewire_host)) { type = 255; - onewire->write(0x33); + onewire_host_write(onewire_host, 0x33); for(uint8_t i = 0; i < 8; i++) { - data[i] = onewire->read(); + data[i] = onewire_host_read(onewire_host); } for(uint8_t i = 0; i < 7; i++) { diff --git a/applications/archive/scenes/archive_scene_browser.c b/applications/archive/scenes/archive_scene_browser.c index cee19168..462fecbd 100644 --- a/applications/archive/scenes/archive_scene_browser.c +++ b/applications/archive/scenes/archive_scene_browser.c @@ -99,6 +99,7 @@ bool archive_scene_browser_on_event(void* context, SceneManagerEvent event) { if(favorites) { browser->callback(ArchiveBrowserEventEnterFavMove, browser->context); } else if((known_app) && (selected->is_app == false)) { + archive_show_file_menu(browser, false); scene_manager_next_scene(archive->scene_manager, ArchiveAppSceneRename); } consumed = true; diff --git a/applications/desktop/scenes/desktop_scene_pin_input.c b/applications/desktop/scenes/desktop_scene_pin_input.c index 5a0f63f0..60935f07 100644 --- a/applications/desktop/scenes/desktop_scene_pin_input.c +++ b/applications/desktop/scenes/desktop_scene_pin_input.c @@ -155,7 +155,7 @@ void desktop_scene_pin_input_on_exit(void* context) { desktop->scene_manager, DesktopScenePinInput); xTimerStop(state->timer, portMAX_DELAY); while(xTimerIsTimerActive(state->timer)) { - delay(1); + furi_hal_delay_ms(1); } xTimerDelete(state->timer, portMAX_DELAY); free(state); diff --git a/applications/desktop/views/desktop_view_pin_input.c b/applications/desktop/views/desktop_view_pin_input.c index 11af5f4a..2b3b53aa 100644 --- a/applications/desktop/views/desktop_view_pin_input.c +++ b/applications/desktop/views/desktop_view_pin_input.c @@ -214,7 +214,7 @@ void desktop_view_pin_input_free(DesktopViewPinInput* pin_input) { xTimerStop(pin_input->timer, portMAX_DELAY); while(xTimerIsTimerActive(pin_input->timer)) { - delay(1); + furi_hal_delay_ms(1); } xTimerDelete(pin_input->timer, portMAX_DELAY); diff --git a/applications/gpio/gpio_item.c b/applications/gpio/gpio_item.c index 48fed61f..2d0f5f67 100644 --- a/applications/gpio/gpio_item.c +++ b/applications/gpio/gpio_item.c @@ -20,8 +20,8 @@ static const GpioItem gpio_item[GPIO_ITEM_COUNT] = { void gpio_item_configure_pin(uint8_t index, GpioMode mode) { furi_assert(index < GPIO_ITEM_COUNT); - hal_gpio_write(gpio_item[index].pin, false); - hal_gpio_init(gpio_item[index].pin, mode, GpioPullNo, GpioSpeedVeryHigh); + furi_hal_gpio_write(gpio_item[index].pin, false); + furi_hal_gpio_init(gpio_item[index].pin, mode, GpioPullNo, GpioSpeedVeryHigh); } void gpio_item_configure_all_pins(GpioMode mode) { @@ -32,7 +32,7 @@ void gpio_item_configure_all_pins(GpioMode mode) { void gpio_item_set_pin(uint8_t index, bool level) { furi_assert(index < GPIO_ITEM_COUNT); - hal_gpio_write(gpio_item[index].pin, level); + furi_hal_gpio_write(gpio_item[index].pin, level); } void gpio_item_set_all_pins(bool level) { diff --git a/applications/gpio/usb_uart_bridge.c b/applications/gpio/usb_uart_bridge.c index 51c2bc32..c33f97b1 100644 --- a/applications/gpio/usb_uart_bridge.c +++ b/applications/gpio/usb_uart_bridge.c @@ -134,8 +134,8 @@ static void usb_uart_update_ctrl_lines(UsbUartBridge* usb_uart) { furi_assert((usb_uart->cfg.flow_pins - 1) < (sizeof(flow_pins) / sizeof(flow_pins[0]))); uint8_t state = furi_hal_cdc_get_ctrl_line_state(usb_uart->cfg.vcp_ch); - hal_gpio_write(flow_pins[usb_uart->cfg.flow_pins - 1][0], !(state & USB_CDC_BIT_RTS)); - hal_gpio_write(flow_pins[usb_uart->cfg.flow_pins - 1][1], !(state & USB_CDC_BIT_DTR)); + furi_hal_gpio_write(flow_pins[usb_uart->cfg.flow_pins - 1][0], !(state & USB_CDC_BIT_RTS)); + furi_hal_gpio_write(flow_pins[usb_uart->cfg.flow_pins - 1][1], !(state & USB_CDC_BIT_DTR)); } } @@ -161,8 +161,10 @@ static int32_t usb_uart_worker(void* context) { usb_uart_set_baudrate(usb_uart, usb_uart->cfg.baudrate); if(usb_uart->cfg.flow_pins != 0) { furi_assert((usb_uart->cfg.flow_pins - 1) < (sizeof(flow_pins) / sizeof(flow_pins[0]))); - hal_gpio_init_simple(flow_pins[usb_uart->cfg.flow_pins - 1][0], GpioModeOutputPushPull); - hal_gpio_init_simple(flow_pins[usb_uart->cfg.flow_pins - 1][1], GpioModeOutputPushPull); + furi_hal_gpio_init_simple( + flow_pins[usb_uart->cfg.flow_pins - 1][0], GpioModeOutputPushPull); + furi_hal_gpio_init_simple( + flow_pins[usb_uart->cfg.flow_pins - 1][1], GpioModeOutputPushPull); usb_uart_update_ctrl_lines(usb_uart); } @@ -219,18 +221,18 @@ static int32_t usb_uart_worker(void* context) { } if(usb_uart->cfg.flow_pins != usb_uart->cfg_new.flow_pins) { if(usb_uart->cfg.flow_pins != 0) { - hal_gpio_init_simple( + furi_hal_gpio_init_simple( flow_pins[usb_uart->cfg.flow_pins - 1][0], GpioModeAnalog); - hal_gpio_init_simple( + furi_hal_gpio_init_simple( flow_pins[usb_uart->cfg.flow_pins - 1][1], GpioModeAnalog); } if(usb_uart->cfg_new.flow_pins != 0) { furi_assert( (usb_uart->cfg_new.flow_pins - 1) < (sizeof(flow_pins) / sizeof(flow_pins[0]))); - hal_gpio_init_simple( + furi_hal_gpio_init_simple( flow_pins[usb_uart->cfg_new.flow_pins - 1][0], GpioModeOutputPushPull); - hal_gpio_init_simple( + furi_hal_gpio_init_simple( flow_pins[usb_uart->cfg_new.flow_pins - 1][1], GpioModeOutputPushPull); } usb_uart->cfg.flow_pins = usb_uart->cfg_new.flow_pins; @@ -251,8 +253,8 @@ static int32_t usb_uart_worker(void* context) { furi_hal_usb_unlock(); furi_hal_usb_set_config(usb_mode_prev, NULL); if(usb_uart->cfg.flow_pins != 0) { - hal_gpio_init_simple(flow_pins[usb_uart->cfg.flow_pins - 1][0], GpioModeAnalog); - hal_gpio_init_simple(flow_pins[usb_uart->cfg.flow_pins - 1][1], GpioModeAnalog); + furi_hal_gpio_init_simple(flow_pins[usb_uart->cfg.flow_pins - 1][0], GpioModeAnalog); + furi_hal_gpio_init_simple(flow_pins[usb_uart->cfg.flow_pins - 1][1], GpioModeAnalog); } osThreadFlagsSet(furi_thread_get_thread_id(usb_uart->tx_thread), WorkerEvtTxStop); diff --git a/applications/ibutton/helpers/cyfral_decoder.cpp b/applications/ibutton/helpers/cyfral_decoder.cpp deleted file mode 100644 index b782deea..00000000 --- a/applications/ibutton/helpers/cyfral_decoder.cpp +++ /dev/null @@ -1,193 +0,0 @@ -#include "cyfral_decoder.h" -#include - -void CyfralDecoder::reset_state() { - state = State::WAIT_START_NIBBLE; - bit_state = BitState::WAIT_FRONT_LOW; - - period_time = 0; - bit_index = 0; - ready = false; - index = 0; - - key_data = 0; - readed_nibble = 0; - data_valid = true; -} - -bool CyfralDecoder::nibble_valid(uint8_t data) { - uint8_t data_value = data & 0x0F; - - switch(data_value) { - case 0b1110: - case 0b1101: - case 0b1011: - case 0b0111: - return true; - break; - default: - return false; - } -} - -CyfralDecoder::CyfralDecoder() { - reset_state(); - max_period = 0; -} - -void CyfralDecoder::process_front(bool polarity, uint32_t time) { - bool readed; - bool value; - - if(max_period == 0) { - max_period = 230 * (SystemCoreClock / 1000000.0f); - } - - if(ready) return; - - switch(state) { - case State::WAIT_START_NIBBLE: - // wait for start word - if(process_bit(polarity, time, &readed, &value)) { - if(readed) { - readed_nibble = ((readed_nibble << 1) | value) & 0x0F; - if(readed_nibble == 0b0001) { - readed_nibble = 0; - state = State::READ_NIBBLE; - } - } - } else { - reset_state(); - } - - break; - case State::READ_NIBBLE: - // read nibbles - if(process_bit(polarity, time, &readed, &value)) { - if(readed) { - readed_nibble = (readed_nibble << 1) | value; - - bit_index++; - - //convert every nibble to 2-bit index - if(bit_index == 4) { - switch(readed_nibble) { - case 0b1110: - key_data = (key_data << 2) | 0b11; - break; - case 0b1101: - key_data = (key_data << 2) | 0b10; - break; - case 0b1011: - key_data = (key_data << 2) | 0b01; - break; - case 0b0111: - key_data = (key_data << 2) | 0b00; - break; - default: - data_valid = false; - break; - } - - readed_nibble = 0; - bit_index = 0; - index++; - } - - // succefully read 8 nibbles - if(index == 8) { - state = State::READ_STOP_NIBBLE; - } - } - } else { - reset_state(); - } - break; - case State::READ_STOP_NIBBLE: - // read stop nibble - if(process_bit(polarity, time, &readed, &value)) { - if(readed) { - readed_nibble = ((readed_nibble << 1) | value) & 0x0F; - bit_index++; - - switch(bit_index) { - case 0: - case 1: - case 2: - case 3: - break; - case 4: - if(readed_nibble == 0b0001) { - // validate data - if(data_valid) { - ready = true; - } else { - reset_state(); - } - } else { - reset_state(); - } - break; - default: - reset_state(); - break; - } - } - } else { - reset_state(); - } - break; - } -} - -bool CyfralDecoder::process_bit(bool polarity, uint32_t time, bool* readed, bool* readed_value) { - bool result = true; - *readed = false; - - // bit start from low - switch(bit_state) { - case BitState::WAIT_FRONT_LOW: - if(polarity == true) { - period_time += time; - - *readed = true; - if(period_time <= max_period) { - if((period_time / 2) > time) { - *readed_value = false; - } else { - *readed_value = true; - } - } else { - result = false; - } - - bit_state = BitState::WAIT_FRONT_HIGH; - } else { - result = false; - } - break; - case BitState::WAIT_FRONT_HIGH: - if(polarity == false) { - period_time = time; - bit_state = BitState::WAIT_FRONT_LOW; - } else { - result = false; - } - break; - } - - return result; -} - -bool CyfralDecoder::read(uint8_t* _data, uint8_t data_size) { - furi_check(data_size <= 2); - bool result = false; - - if(ready) { - memcpy(_data, &key_data, data_size); - reset_state(); - result = true; - } - - return result; -} diff --git a/applications/ibutton/helpers/cyfral_decoder.h b/applications/ibutton/helpers/cyfral_decoder.h deleted file mode 100644 index efddbd7f..00000000 --- a/applications/ibutton/helpers/cyfral_decoder.h +++ /dev/null @@ -1,55 +0,0 @@ -#pragma once -#include -#include - -class CyfralDecoder { -public: - bool read(uint8_t* data, uint8_t data_size); - void process_front(bool polarity, uint32_t time); - - CyfralDecoder(); - -private: - enum class BitState : uint8_t { - WAIT_FRONT_HIGH, - WAIT_FRONT_LOW, - }; - - enum class State : uint8_t { - WAIT_START_NIBBLE, - READ_NIBBLE, - READ_STOP_NIBBLE, - }; - - State state; - BitState bit_state; - - bool process_bit(bool polarity, uint32_t time, bool* readed, bool* readed_value); - void reset_state(); - bool nibble_valid(uint8_t data); - - // high + low period time - uint32_t period_time; - - // ready flag, key is readed and valid - std::atomic ready; - - // key data storage - uint16_t key_data; - - // temporary nibble storage - uint8_t readed_nibble; - - // data valid flag - // MUST be checked only in READ_STOP_NIBBLE state - bool data_valid; - - // nibble index, we expect 8 nibbles - uint8_t index; - - // bit index in nibble, 4 bit per nibble - uint8_t bit_index; - - // max period, 230us x clock per us - uint32_t max_period; -}; diff --git a/applications/ibutton/helpers/key_commands.h b/applications/ibutton/helpers/key_commands.h deleted file mode 100644 index 39c32df0..00000000 --- a/applications/ibutton/helpers/key_commands.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once -#include - -class RW1990_1 { -public: - constexpr static const uint8_t CMD_WRITE_RECORD_FLAG = 0xD1; - constexpr static const uint8_t CMD_READ_RECORD_FLAG = 0xB5; - constexpr static const uint8_t CMD_WRITE_ROM = 0xD5; -}; - -class RW1990_2 { -public: - constexpr static const uint8_t CMD_WRITE_RECORD_FLAG = 0x1D; - constexpr static const uint8_t CMD_READ_RECORD_FLAG = 0x1E; - constexpr static const uint8_t CMD_WRITE_ROM = 0xD5; -}; - -class TM2004 { -public: - constexpr static const uint8_t CMD_READ_STATUS = 0xAA; - constexpr static const uint8_t CMD_READ_MEMORY = 0xF0; - constexpr static const uint8_t CMD_WRITE_ROM = 0x3C; - constexpr static const uint8_t CMD_FINALIZATION = 0x35; - - constexpr static const uint8_t ANSWER_READ_MEMORY = 0xF5; -}; - -class TM01 { -public: - constexpr static const uint8_t CMD_WRITE_RECORD_FLAG = 0xC1; - constexpr static const uint8_t CMD_WRITE_ROM = 0xC5; - constexpr static const uint8_t CMD_SWITCH_TO_CYFRAL = 0xCA; - constexpr static const uint8_t CMD_SWITCH_TO_METAKOM = 0xCB; -}; - -class DS1990 { -public: - constexpr static const uint8_t CMD_READ_ROM = 0x33; -}; \ No newline at end of file diff --git a/applications/ibutton/helpers/key_emulator.cpp b/applications/ibutton/helpers/key_emulator.cpp deleted file mode 100644 index b8f0b864..00000000 --- a/applications/ibutton/helpers/key_emulator.cpp +++ /dev/null @@ -1,208 +0,0 @@ -#include "key_emulator.h" -#include - -KeyEmulator::~KeyEmulator() { - stop(); -} - -KeyEmulator::KeyEmulator(OneWireSlave* _onewire_slave) - : dallas_key{0, 0, 0, 0, 0, 0, 0} { - onewire_slave = _onewire_slave; - - auto cb = cbc::obtain_connector(this, &KeyEmulator::result_callback); - onewire_slave->set_result_callback(cb, this); -} - -void KeyEmulator::start(iButtonKey* key) { - anything_emulated = false; - stop(); - - // pulldown pull pin, to prevent low-pass filtering by the RFID part of the schematic - furi_hal_rfid_pin_pull_pulldown(); - - switch(key->get_key_type()) { - case iButtonKeyType::KeyDallas: - start_dallas_emulate(key); - break; - case iButtonKeyType::KeyCyfral: - start_cyfral_emulate(key); - break; - case iButtonKeyType::KeyMetakom: - start_metakom_emulate(key); - break; - } -} - -bool KeyEmulator::emulated() { - bool result = false; - - if(anything_emulated) { - anything_emulated = false; - result = true; - } - - return result; -} - -void KeyEmulator::stop() { - onewire_slave->stop(); - pulser.stop(); - furi_hal_rfid_pins_reset(); -} - -void KeyEmulator::start_cyfral_emulate(iButtonKey* key) { - furi_assert(key->get_key_type() == iButtonKeyType::KeyCyfral); - furi_assert(key->get_type_data_size() == 2); - - const uint32_t cyfral_period_full = 8000; - const uint32_t cyfral_period_one[2] = { - uint32_t(cyfral_period_full * 0.33f), uint32_t(cyfral_period_full * 0.66f)}; - const uint32_t cyfral_period_zero[2] = { - uint32_t(cyfral_period_full * 0.66f), uint32_t(cyfral_period_full * 0.33f)}; - uint8_t pd_index = 0; - uint8_t* key_data = key->get_data(); - - // start nibble - set_pulse_data_cyfral(pd_index, cyfral_period_zero); - pd_index++; - set_pulse_data_cyfral(pd_index, cyfral_period_zero); - pd_index++; - set_pulse_data_cyfral(pd_index, cyfral_period_zero); - pd_index++; - set_pulse_data_cyfral(pd_index, cyfral_period_one); - pd_index++; - - // data nibbles x 8 - for(int8_t i = key->get_type_data_size() - 1; i >= 0; i--) { - for(int8_t j = 3; j >= 0; j--) { - switch((key_data[i] >> (j * 2)) & 0b00000011) { - case 0b11: - set_pulse_data_cyfral(pd_index, cyfral_period_one); - pd_index++; - set_pulse_data_cyfral(pd_index, cyfral_period_one); - pd_index++; - set_pulse_data_cyfral(pd_index, cyfral_period_one); - pd_index++; - set_pulse_data_cyfral(pd_index, cyfral_period_zero); - pd_index++; - break; - case 0b10: - set_pulse_data_cyfral(pd_index, cyfral_period_one); - pd_index++; - set_pulse_data_cyfral(pd_index, cyfral_period_one); - pd_index++; - set_pulse_data_cyfral(pd_index, cyfral_period_zero); - pd_index++; - set_pulse_data_cyfral(pd_index, cyfral_period_one); - pd_index++; - break; - case 0b01: - set_pulse_data_cyfral(pd_index, cyfral_period_one); - pd_index++; - set_pulse_data_cyfral(pd_index, cyfral_period_zero); - pd_index++; - set_pulse_data_cyfral(pd_index, cyfral_period_one); - pd_index++; - set_pulse_data_cyfral(pd_index, cyfral_period_one); - pd_index++; - break; - case 0b00: - set_pulse_data_cyfral(pd_index, cyfral_period_zero); - pd_index++; - set_pulse_data_cyfral(pd_index, cyfral_period_one); - pd_index++; - set_pulse_data_cyfral(pd_index, cyfral_period_one); - pd_index++; - set_pulse_data_cyfral(pd_index, cyfral_period_one); - pd_index++; - break; - default: - // cannot be anyway - furi_check(false); - break; - } - } - } - - // 4 (nibbles) x (8 data + 1 start) = 4 x 9 = 36 - if(pd_index != 36) { - // something is very wrong - furi_check(false); - } - - pulser.set_periods(pulse_data, 72, false); - pulser.start(); -} - -void KeyEmulator::start_metakom_emulate(iButtonKey* key) { - furi_assert(key->get_key_type() == iButtonKeyType::KeyMetakom); - furi_assert(key->get_type_data_size() == 4); - - const uint32_t metakom_period_full = 8000; - const uint32_t metakom_period_zero[2] = { - uint32_t(metakom_period_full * 0.33f), uint32_t(metakom_period_full * 0.66f)}; - const uint32_t metakom_period_one[2] = { - uint32_t(metakom_period_full * 0.66f), uint32_t(metakom_period_full * 0.33f)}; - uint8_t pd_index = 0; - - uint8_t* key_data = key->get_data(); - - // start pulse - pulse_data[0] = metakom_period_full; - - // start triplet - set_pulse_data_metakom(pd_index, metakom_period_zero); - pd_index++; - set_pulse_data_metakom(pd_index, metakom_period_one); - pd_index++; - set_pulse_data_metakom(pd_index, metakom_period_zero); - pd_index++; - - for(int8_t i = key->get_type_data_size() - 1; i >= 0; i--) { - for(int8_t j = 7; j >= 0; j--) { - if(((key_data[i] >> j) & 0b00000001) == 1) { - set_pulse_data_metakom(pd_index, metakom_period_one); - pd_index++; - } else { - set_pulse_data_metakom(pd_index, metakom_period_zero); - pd_index++; - } - } - } - - // 4 byte x 8 bits + 3 start bits = 35 - if(pd_index != 35) { - // something is very wrong - furi_check(false); - } - - pulser.set_periods(pulse_data, 71, false); - pulser.start(); -} - -void KeyEmulator::start_dallas_emulate(iButtonKey* key) { - furi_assert(key->get_key_type() == iButtonKeyType::KeyDallas); - furi_assert(key->get_type_data_size() == 8); - - onewire_slave->deattach(); - memcpy(dallas_key.id_storage, key->get_data(), key->get_type_data_size()); - onewire_slave->attach(&dallas_key); - onewire_slave->start(); -} - -void KeyEmulator::set_pulse_data_cyfral(uint8_t index, const uint32_t* data) { - pulse_data[index * 2] = data[0]; - pulse_data[index * 2 + 1] = data[1]; -} - -void KeyEmulator::set_pulse_data_metakom(uint8_t index, const uint32_t* data) { - // damn start pulse - pulse_data[(index * 2) + 1] = data[0]; - pulse_data[(index * 2) + 2] = data[1]; -} - -void KeyEmulator::result_callback(bool success, void* ctx) { - KeyEmulator* _this = static_cast(ctx); - - _this->anything_emulated = true; -} \ No newline at end of file diff --git a/applications/ibutton/helpers/key_emulator.h b/applications/ibutton/helpers/key_emulator.h deleted file mode 100644 index 11edbe46..00000000 --- a/applications/ibutton/helpers/key_emulator.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once -#include "pulse_sequencer.h" -#include "../ibutton_key.h" -#include -#include -#include - -class KeyEmulator { -public: - KeyEmulator(OneWireSlave* onewire_slave); - ~KeyEmulator(); - - void start(iButtonKey* key); - bool emulated(); - void stop(); - -private: - DS1990 dallas_key; - OneWireSlave* onewire_slave; - - PulseSequencer pulser; - uint32_t pulse_data[72]; - - std::atomic anything_emulated; - - void start_cyfral_emulate(iButtonKey* key); - void start_metakom_emulate(iButtonKey* key); - void start_dallas_emulate(iButtonKey* key); - - void set_pulse_data_cyfral(uint8_t index, const uint32_t* data); - void set_pulse_data_metakom(uint8_t index, const uint32_t* data); - - void result_callback(bool success, void* ctx); -}; diff --git a/applications/ibutton/helpers/key_info.h b/applications/ibutton/helpers/key_info.h deleted file mode 100644 index 20ee7e1d..00000000 --- a/applications/ibutton/helpers/key_info.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once -#include - -static const uint8_t IBUTTON_KEY_DATA_SIZE = 8; -static const uint8_t IBUTTON_KEY_NAME_SIZE = 22; - -enum class iButtonKeyType : uint8_t { - KeyDallas, - KeyCyfral, - KeyMetakom, -}; \ No newline at end of file diff --git a/applications/ibutton/helpers/key_reader.cpp b/applications/ibutton/helpers/key_reader.cpp deleted file mode 100644 index cf6fc4a3..00000000 --- a/applications/ibutton/helpers/key_reader.cpp +++ /dev/null @@ -1,181 +0,0 @@ -#include "key_reader.h" -#include "key_commands.h" -#include -#include - -KeyReader::Error KeyReader::read(iButtonKey* key) { - uint8_t tmp_key_data[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - iButtonKeyType key_type; - - KeyReader::Error result = KeyReader::Error::EMPTY; - - if(read_key(&key_type, tmp_key_data, 8)) { - switch(key_type) { - case iButtonKeyType::KeyDallas: - if(verify_key(key_type, tmp_key_data, 8)) { - if(maxim_crc8(tmp_key_data, 8) == 0) { - if(tmp_key_data[0] == 0x01) { - result = KeyReader::Error::OK; - } else { - result = KeyReader::Error::NOT_ARE_KEY; - } - } else { - result = KeyReader::Error::CRC_ERROR; - } - } - - break; - case iButtonKeyType::KeyCyfral: - result = KeyReader::Error::OK; - break; - case iButtonKeyType::KeyMetakom: - result = KeyReader::Error::OK; - break; - } - - if(result != KeyReader::Error::EMPTY) { - key->set_type(key_type); - key->set_data(tmp_key_data, 8); - } - } - - switch_mode_if_needed(); - - return result; -} - -KeyReader::KeyReader(OneWireMaster* _onewire_master) { - onewire_master = _onewire_master; - read_mode_switch_time = 0; - read_mode = ReadMode::DALLAS; -} - -KeyReader::~KeyReader() { - stop(); -} - -bool KeyReader::read_key(iButtonKeyType* key_type, uint8_t* data, uint8_t data_size) { - bool readed = false; - - if(read_mode == ReadMode::DALLAS) { - FURI_CRITICAL_ENTER(); - if(onewire_master->search(data)) { - onewire_master->reset_search(); - readed = true; - *key_type = iButtonKeyType::KeyDallas; - } else { - onewire_master->reset_search(); - } - FURI_CRITICAL_EXIT(); - } else if(read_mode == ReadMode::CYFRAL_METAKOM) { - if(cyfral_decoder.read(data, 2)) { - readed = true; - *key_type = iButtonKeyType::KeyCyfral; - } else if(metakom_decoder.read(data, 4)) { - readed = true; - *key_type = iButtonKeyType::KeyMetakom; - } - } - - return readed; -} - -bool KeyReader::verify_key(iButtonKeyType key_type, const uint8_t* const data, uint8_t data_size) { - bool result = true; - - if(key_type == iButtonKeyType::KeyDallas) { - switch_to(ReadMode::DALLAS); - - FURI_CRITICAL_ENTER(); - if(onewire_master->reset()) { - onewire_master->write(DS1990::CMD_READ_ROM); - for(uint8_t i = 0; i < data_size; i++) { - if(onewire_master->read() != data[i]) { - result = false; - } - } - } else { - result = false; - } - FURI_CRITICAL_EXIT(); - - } else { - result = false; - } - - return result; -} - -void KeyReader::start_comaparator(void) { - furi_hal_rfid_pins_reset(); - - // pulldown pull pin, we sense the signal through the analog part of the RFID schematic - furi_hal_rfid_pin_pull_pulldown(); - - comparator_callback_pointer = - cbc::obtain_connector(this, &KeyReader::comparator_trigger_callback); - furi_hal_rfid_comp_set_callback(comparator_callback_pointer, this); - last_dwt_value = DWT->CYCCNT; - furi_hal_rfid_comp_start(); -} - -void KeyReader::stop_comaparator(void) { - furi_hal_rfid_pins_reset(); - - // rfid_pins_reset will disable ibutton pin - furi_hal_ibutton_start(); - - furi_hal_rfid_comp_stop(); - furi_hal_rfid_comp_set_callback(NULL, NULL); -} - -void KeyReader::comparator_trigger_callback(bool level, void* comp_ctx) { - KeyReader* _this = static_cast(comp_ctx); - - uint32_t current_dwt_value = DWT->CYCCNT; - - _this->cyfral_decoder.process_front(level, current_dwt_value - last_dwt_value); - _this->metakom_decoder.process_front(level, current_dwt_value - last_dwt_value); - - last_dwt_value = current_dwt_value; -} - -void KeyReader::switch_to(ReadMode mode) { - switch(mode) { - case ReadMode::DALLAS: - onewire_master->start(); - stop_comaparator(); - break; - case ReadMode::CYFRAL_METAKOM: - onewire_master->stop(); - start_comaparator(); - break; - } - - read_mode = mode; -} - -void KeyReader::switch_mode_if_needed() { - if(osKernelGetTickCount() - read_mode_switch_time > (osKernelGetTickFreq() / 5)) { - read_mode_switch_time = osKernelGetTickCount(); - switch(read_mode) { - case ReadMode::DALLAS: - switch_to(ReadMode::CYFRAL_METAKOM); - break; - case ReadMode::CYFRAL_METAKOM: - switch_to(ReadMode::DALLAS); - break; - } - } -} - -void KeyReader::start() { - furi_hal_power_enable_otg(); - switch_to(ReadMode::CYFRAL_METAKOM); -} - -void KeyReader::stop() { - furi_hal_power_disable_otg(); - onewire_master->stop(); - stop_comaparator(); -} diff --git a/applications/ibutton/helpers/key_reader.h b/applications/ibutton/helpers/key_reader.h deleted file mode 100644 index 2eb8dcd1..00000000 --- a/applications/ibutton/helpers/key_reader.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once -#include -#include -#include "cyfral_decoder.h" -#pragma once -#include "metakom_decoder.h" -#include "../ibutton_key.h" -#include -#include - -class KeyReader { -public: - enum class Error : uint8_t { - EMPTY, - CRC_ERROR, - NOT_ARE_KEY, - OK, - }; - - void start(); - void stop(); - KeyReader::Error read(iButtonKey* key); - KeyReader(OneWireMaster* onewire_master); - ~KeyReader(); - -private: - bool read_key(iButtonKeyType* key_type, uint8_t* data, uint8_t data_size); - bool verify_key(iButtonKeyType key_type, const uint8_t* const data, uint8_t data_size); - - // cyfral and metakom readers data - void comparator_trigger_callback(bool level, void* comp_ctx); - void (*comparator_callback_pointer)(bool level, void* comp_ctx); - - void start_comaparator(void); - void stop_comaparator(void); - uint32_t last_dwt_value; - - CyfralDecoder cyfral_decoder; - MetakomDecoder metakom_decoder; - - // mode - uint32_t read_mode_switch_time; - enum class ReadMode : uint8_t { - CYFRAL_METAKOM, - DALLAS, - }; - ReadMode read_mode; - - // one wire - OneWireMaster* onewire_master; - - void switch_to(ReadMode mode); - void switch_mode_if_needed(); -}; diff --git a/applications/ibutton/helpers/key_worker.cpp b/applications/ibutton/helpers/key_worker.cpp deleted file mode 100644 index 885dc595..00000000 --- a/applications/ibutton/helpers/key_worker.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "key_worker.h" -#include -#include - -KeyReader::Error KeyWorker::read(iButtonKey* key) { - KeyReader::Error result = key_reader.read(key); - - return result; -} - -void KeyWorker::start_read() { - key_reader.start(); -} - -void KeyWorker::stop_read() { - key_reader.stop(); -} - -bool KeyWorker::emulated() { - return key_emulator.emulated(); -} - -void KeyWorker::start_emulate(iButtonKey* key) { - key_emulator.start(key); -} - -void KeyWorker::stop_emulate() { - key_emulator.stop(); -} - -KeyWriter::Error KeyWorker::write(iButtonKey* key) { - return key_writer.write(key); -} - -void KeyWorker::start_write() { - key_writer.start(); -} - -void KeyWorker::stop_write() { - key_writer.stop(); -} - -KeyWorker::KeyWorker(const GpioPin* one_wire_gpio) - : onewire_master{one_wire_gpio} - , onewire_slave{one_wire_gpio} - , key_reader{&onewire_master} - , key_emulator{&onewire_slave} - , key_writer{&onewire_master} { -} - -KeyWorker::~KeyWorker() { -} diff --git a/applications/ibutton/helpers/key_worker.h b/applications/ibutton/helpers/key_worker.h deleted file mode 100644 index efe141b0..00000000 --- a/applications/ibutton/helpers/key_worker.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once -#include -#include "key_info.h" -#include "key_reader.h" -#include "key_emulator.h" -#include "key_writer.h" -#include "../ibutton_key.h" -#include -#include - -class KeyWorker { -public: - KeyReader::Error read(iButtonKey* key); - void start_read(); - void stop_read(); - - bool emulated(); - void start_emulate(iButtonKey* key); - void stop_emulate(); - - KeyWriter::Error write(iButtonKey* key); - void start_write(); - void stop_write(); - - KeyWorker(const GpioPin* one_wire_gpio); - ~KeyWorker(); - -private: - // one wire - OneWireMaster onewire_master; - OneWireSlave onewire_slave; - KeyReader key_reader; - KeyEmulator key_emulator; - KeyWriter key_writer; -}; \ No newline at end of file diff --git a/applications/ibutton/helpers/key_writer.cpp b/applications/ibutton/helpers/key_writer.cpp deleted file mode 100644 index 39637b3a..00000000 --- a/applications/ibutton/helpers/key_writer.cpp +++ /dev/null @@ -1,278 +0,0 @@ -#include "key_writer.h" -#include "key_commands.h" - -KeyWriter::KeyWriter(OneWireMaster* _onewire_master) { - onewire_master = _onewire_master; -} - -KeyWriter::~KeyWriter() { - stop(); -} - -KeyWriter::Error KeyWriter::write(iButtonKey* key) { - return write_internal(key); -} - -void KeyWriter::start() { - furi_hal_power_enable_otg(); - onewire_master->start(); -} - -void KeyWriter::stop() { - furi_hal_power_disable_otg(); - onewire_master->stop(); -} - -KeyWriter::Error KeyWriter::write_internal(iButtonKey* key) { - Error result = Error::NO_DETECT; - bool same_key = false; - - osKernelLock(); - bool presence = onewire_master->reset(); - osKernelUnlock(); - - if(presence) { - switch(key->get_key_type()) { - case iButtonKeyType::KeyDallas: - same_key = compare_key_ds1990(key); - - if(!same_key) { - bool write_result = false; - // currently we can write: - // RW1990, TM08v2, TM08vi-2 by write_1990_1() - // RW2004, RW2004 with EEPROM by write_TM2004(); - - if(!write_result) { - write_result = write_1990_1(key); - } - if(!write_result) { - write_result = write_1990_2(key); - } - if(!write_result) { - write_result = write_TM2004(key); - } - - if(write_result) { - result = Error::OK; - } else { - result = Error::CANNOT_WRITE; - } - } else { - result = Error::SAME_KEY; - } - break; - - default: - break; - } - } - - return result; -} - -bool KeyWriter::compare_key_ds1990(iButtonKey* key) { - bool result = false; - - if(key->get_key_type() == iButtonKeyType::KeyDallas) { - FURI_CRITICAL_ENTER(); - bool presence = onewire_master->reset(); - - if(presence) { - onewire_master->write(DS1990::CMD_READ_ROM); - - result = true; - for(uint8_t i = 0; i < key->get_type_data_size(); i++) { - if(key->get_data()[i] != onewire_master->read()) { - result = false; - break; - } - } - } - - FURI_CRITICAL_EXIT(); - } - - return result; -} - -bool KeyWriter::write_1990_1(iButtonKey* key) { - bool result = false; - - if(key->get_key_type() == iButtonKeyType::KeyDallas) { - FURI_CRITICAL_ENTER(); - - // unlock - onewire_master->reset(); - onewire_master->write(RW1990_1::CMD_WRITE_RECORD_FLAG); - delay_us(10); - onewire_write_one_bit(0, 5000); - - // write key - onewire_master->reset(); - onewire_master->write(RW1990_1::CMD_WRITE_ROM); - for(uint8_t i = 0; i < key->get_type_data_size(); i++) { - // inverted key for RW1990.1 - write_byte_ds1990(~key->get_data()[i]); - delay_us(30000); - } - - // lock - onewire_master->write(RW1990_1::CMD_WRITE_RECORD_FLAG); - onewire_write_one_bit(1); - - FURI_CRITICAL_EXIT(); - - if(compare_key_ds1990(key)) { - result = true; - } - } - - return result; -} - -bool KeyWriter::write_1990_2(iButtonKey* key) { - bool result = false; - - if(key->get_key_type() == iButtonKeyType::KeyDallas) { - FURI_CRITICAL_ENTER(); - - // unlock - onewire_master->reset(); - onewire_master->write(RW1990_2::CMD_WRITE_RECORD_FLAG); - delay_us(10); - onewire_write_one_bit(1, 5000); - - // write key - onewire_master->reset(); - onewire_master->write(RW1990_2::CMD_WRITE_ROM); - for(uint8_t i = 0; i < key->get_type_data_size(); i++) { - write_byte_ds1990(key->get_data()[i]); - delay_us(30000); - } - - // lock - onewire_master->write(RW1990_2::CMD_WRITE_RECORD_FLAG); - onewire_write_one_bit(0); - - FURI_CRITICAL_EXIT(); - - if(compare_key_ds1990(key)) { - result = true; - } - } - - return result; -} - -bool KeyWriter::write_TM2004(iButtonKey* key) { - uint8_t answer; - bool result = true; - - if(key->get_key_type() == iButtonKeyType::KeyDallas) { - FURI_CRITICAL_ENTER(); - - // write rom, addr is 0x0000 - onewire_master->reset(); - onewire_master->write(TM2004::CMD_WRITE_ROM); - onewire_master->write(0x00); - onewire_master->write(0x00); - - // write key - for(uint8_t i = 0; i < key->get_type_data_size(); i++) { - // write key byte - onewire_master->write(key->get_data()[i]); - answer = onewire_master->read(); - // TODO: check answer CRC - - // pulse indicating that data is correct - delay_us(600); - onewire_write_one_bit(1, 50000); - - // read writed key byte - answer = onewire_master->read(); - - // check that writed and readed are same - if(key->get_data()[i] != answer) { - result = false; - break; - } - } - - if(!compare_key_ds1990(key)) { - result = false; - } - - onewire_master->reset(); - - FURI_CRITICAL_EXIT(); - } else { - result = false; - } - - return result; -} - -bool KeyWriter::write_TM01(iButtonKey* key) { - /*bool result = true; - - // TODO test and encoding - FURI_CRITICAL_ENTER(); - - // unlock - onewire_master->reset(); - onewire_master->write(TM01::CMD_WRITE_RECORD_FLAG); - onewire_write_one_bit(1, 10000); - - // write key - onewire_master->reset(); - onewire_master->write(TM01::CMD_WRITE_ROM); - - // TODO: key types - //if(type == KEY_METAKOM || type == KEY_CYFRAL) { - //} else { - for(uint8_t i = 0; i < key->get_type_data_size(); i++) { - write_byte_ds1990(key->get_data()[i]); - delay_us(10000); - } - //} - - // lock - onewire_master->write(TM01::CMD_WRITE_RECORD_FLAG); - onewire_write_one_bit(0, 10000); - - FURI_CRITICAL_EXIT(); - - if(!compare_key_ds1990(key)) { - result = false; - } - - FURI_CRITICAL_ENTER(); - - if(key->get_key_type() == iButtonKeyType::KeyMetakom || - key->get_key_type() == iButtonKeyType::KeyCyfral) { - onewire_master->reset(); - if(key->get_key_type() == iButtonKeyType::KeyCyfral) - onewire_master->write(TM01::CMD_SWITCH_TO_CYFRAL); - else - onewire_master->write(TM01::CMD_SWITCH_TO_METAKOM); - onewire_write_one_bit(1); - } - - FURI_CRITICAL_EXIT(); - - return result;*/ - return false; -} - -void KeyWriter::onewire_write_one_bit(bool value, uint32_t delay) { - onewire_master->write_bit(value); - delay_us(delay); -} - -void KeyWriter::write_byte_ds1990(uint8_t data) { - for(uint8_t n_bit = 0; n_bit < 8; n_bit++) { - onewire_master->write_bit(data & 1); - delay_us(5000); - data = data >> 1; - } -} diff --git a/applications/ibutton/helpers/key_writer.h b/applications/ibutton/helpers/key_writer.h deleted file mode 100644 index e4aac7d2..00000000 --- a/applications/ibutton/helpers/key_writer.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once -#include "../ibutton_key.h" -#include - -class KeyWriter { -public: - enum class Error : uint8_t { - OK, - SAME_KEY, - NO_DETECT, - CANNOT_WRITE, - }; - - KeyWriter(OneWireMaster* onewire_master); - ~KeyWriter(); - - KeyWriter::Error write(iButtonKey* key); - void start(); - void stop(); - -private: - OneWireMaster* onewire_master; - - KeyWriter::Error write_internal(iButtonKey* key); - bool compare_key_ds1990(iButtonKey* key); - - // write strategy - bool write_1990_1(iButtonKey* key); - bool write_1990_2(iButtonKey* key); - bool write_TM2004(iButtonKey* key); - bool write_TM01(iButtonKey* key); - - void onewire_write_one_bit(bool value, uint32_t delay = 10000); - void write_byte_ds1990(uint8_t data); -}; diff --git a/applications/ibutton/helpers/metakom_decoder.cpp b/applications/ibutton/helpers/metakom_decoder.cpp deleted file mode 100644 index 9c8ec30a..00000000 --- a/applications/ibutton/helpers/metakom_decoder.cpp +++ /dev/null @@ -1,191 +0,0 @@ -#include "metakom_decoder.h" -#include - -bool MetakomDecoder::read(uint8_t* _data, uint8_t data_size) { - bool result = false; - - if(ready) { - memcpy(_data, &key_data, 4); - reset_state(); - result = true; - } - - return result; -} - -void MetakomDecoder::process_front(bool polarity, uint32_t time) { - if(max_period == 0) { - max_period = 230 * (SystemCoreClock / 1000000.0f); - } - - if(ready) return; - - uint32_t high_time = 0; - uint32_t low_time = 0; - - switch(state) { - case State::WAIT_PERIOD_SYNC: - if(process_bit(polarity, time, &high_time, &low_time)) { - period_sample_data[period_sample_index] = high_time + low_time; - period_sample_index++; - - if(period_sample_index == period_sample_count) { - for(uint8_t i = 0; i < period_sample_count; i++) { - period_time += period_sample_data[i]; - }; - period_time /= period_sample_count; - - state = State::WAIT_START_BIT; - } - } - - break; - case State::WAIT_START_BIT: - if(process_bit(polarity, time, &high_time, &low_time)) { - tmp_counter++; - if(high_time > period_time) { - tmp_counter = 0; - state = State::WAIT_START_WORD; - } - - if(tmp_counter > 40) { - reset_state(); - } - } - - break; - case State::WAIT_START_WORD: - if(process_bit(polarity, time, &high_time, &low_time)) { - if(low_time < (period_time / 2)) { - tmp_data = (tmp_data << 1) | 0b0; - } else { - tmp_data = (tmp_data << 1) | 0b1; - } - tmp_counter++; - - if(tmp_counter == 3) { - if(tmp_data == 0b010) { - tmp_counter = 0; - tmp_data = 0; - state = State::READ_WORD; - } else { - reset_state(); - } - } - } - break; - case State::READ_WORD: - if(process_bit(polarity, time, &high_time, &low_time)) { - if(low_time < (period_time / 2)) { - tmp_data = (tmp_data << 1) | 0b0; - } else { - tmp_data = (tmp_data << 1) | 0b1; - } - tmp_counter++; - - if(tmp_counter == 8) { - if(parity_check(tmp_data)) { - key_data = (key_data << 8) | tmp_data; - key_data_index++; - tmp_data = 0; - tmp_counter = 0; - - if(key_data_index == 4) { - // check for stop bit - if(high_time > period_time) { - state = State::READ_STOP_WORD; - } else { - reset_state(); - } - } - } else { - reset_state(); - } - } - } - break; - case State::READ_STOP_WORD: - if(process_bit(polarity, time, &high_time, &low_time)) { - if(low_time < (period_time / 2)) { - tmp_data = (tmp_data << 1) | 0b0; - } else { - tmp_data = (tmp_data << 1) | 0b1; - } - tmp_counter++; - - if(tmp_counter == 3) { - if(tmp_data == 0b010) { - ready = true; - } else { - reset_state(); - } - } - } - break; - } -} - -MetakomDecoder::MetakomDecoder() { - reset_state(); -} - -void MetakomDecoder::reset_state() { - ready = false; - period_sample_index = 0; - period_time = 0; - - tmp_counter = 0; - tmp_data = 0; - - for(uint8_t i = 0; i < period_sample_count; i++) { - period_sample_data[i] = 0; - }; - - state = State::WAIT_PERIOD_SYNC; - bit_state = BitState::WAIT_FRONT_LOW; - - key_data = 0; - key_data_index = 0; -} - -bool MetakomDecoder::parity_check(uint8_t data) { - uint8_t ones_count = 0; - bool result; - - for(uint8_t i = 0; i < 8; i++) { - if((data >> i) & 0b00000001) { - ones_count++; - } - } - - result = (ones_count % 2 == 0); - - return result; -} - -bool MetakomDecoder::process_bit( - bool polarity, - uint32_t time, - uint32_t* high_time, - uint32_t* low_time) { - bool result = false; - - switch(bit_state) { - case BitState::WAIT_FRONT_LOW: - if(polarity == false) { - *low_time = low_time_storage; - *high_time = time; - result = true; - bit_state = BitState::WAIT_FRONT_HIGH; - } - break; - case BitState::WAIT_FRONT_HIGH: - if(polarity == true) { - low_time_storage = time; - bit_state = BitState::WAIT_FRONT_LOW; - } - break; - } - - return result; -} \ No newline at end of file diff --git a/applications/ibutton/helpers/metakom_decoder.h b/applications/ibutton/helpers/metakom_decoder.h deleted file mode 100644 index 4a309935..00000000 --- a/applications/ibutton/helpers/metakom_decoder.h +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once -#include -#include - -class MetakomDecoder { -public: - bool read(uint8_t* data, uint8_t data_size); - void process_front(bool polarity, uint32_t time); - - MetakomDecoder(); - -private: - enum class BitState : uint8_t { - WAIT_FRONT_HIGH, - WAIT_FRONT_LOW, - }; - - BitState bit_state; - - enum class State : uint8_t { - WAIT_PERIOD_SYNC, - WAIT_START_BIT, - WAIT_START_WORD, - READ_WORD, - READ_STOP_WORD, - }; - - State state; - - // high + low period time - uint32_t period_time; - uint32_t low_time_storage; - - static const uint8_t period_sample_count = 10; - uint8_t period_sample_index; - uint32_t period_sample_data[period_sample_count]; - - // ready flag, key is readed and valid - std::atomic ready; - - // max period, 230us x clock per us - uint32_t max_period; - - uint8_t tmp_data; - uint8_t tmp_counter; - - uint32_t key_data; - uint8_t key_data_index; - - void reset_state(); - bool parity_check(uint8_t data); - - bool process_bit(bool polarity, uint32_t time, uint32_t* high_time, uint32_t* low_time); -}; diff --git a/applications/ibutton/helpers/pulse_sequencer.cpp b/applications/ibutton/helpers/pulse_sequencer.cpp deleted file mode 100644 index 9453653a..00000000 --- a/applications/ibutton/helpers/pulse_sequencer.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include "pulse_sequencer.h" - -#include -#include - -void PulseSequencer::set_periods( - uint32_t* _periods, - uint16_t _periods_count, - bool _pin_start_state) { - periods = _periods; - periods_count = _periods_count; - pin_start_state = _pin_start_state; -} - -void PulseSequencer::start() { - period_index = 1; - pin_state = pin_start_state; - hal_gpio_write(&ibutton_gpio, pin_state); - pin_state = !pin_state; - - hal_gpio_init(&ibutton_gpio, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedVeryHigh); - furi_hal_ibutton_emulate_start( - periods[period_index], PulseSequencer::timer_elapsed_callback, this); -} - -void PulseSequencer::stop() { - furi_hal_ibutton_emulate_stop(); -} - -PulseSequencer::~PulseSequencer() { - stop(); -} - -void PulseSequencer::timer_elapsed_callback(void* context) { - PulseSequencer* self = static_cast(context); - - furi_hal_ibutton_emulate_set_next(self->periods[self->period_index]); - - if(self->period_index == 0) { - self->pin_state = self->pin_start_state; - } else { - self->pin_state = !self->pin_state; - } - - hal_gpio_write(&ibutton_gpio, self->pin_state); - - self->period_index++; - - if(self->period_index == self->periods_count) { - self->period_index = 0; - } -} diff --git a/applications/ibutton/helpers/pulse_sequencer.h b/applications/ibutton/helpers/pulse_sequencer.h deleted file mode 100644 index 20d9e50f..00000000 --- a/applications/ibutton/helpers/pulse_sequencer.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once -#include - -class PulseSequencer { -public: - void set_periods(uint32_t* periods, uint16_t periods_count, bool pin_start_state); - void start(); - void stop(); - - ~PulseSequencer(); - -private: - uint16_t period_index; - uint16_t periods_count; - uint32_t* periods; - bool pin_start_state; - bool pin_state; - - void init_timer(uint32_t period); - - void reset_period_index(PulseSequencer* _this); - - void (*callback_pointer)(void*, void*); - - static void timer_elapsed_callback(void* comp_ctx); -}; diff --git a/applications/ibutton/ibutton_app.cpp b/applications/ibutton/ibutton_app.cpp index d69f0097..61bbcffc 100644 --- a/applications/ibutton/ibutton_app.cpp +++ b/applications/ibutton/ibutton_app.cpp @@ -1,6 +1,6 @@ #include "ibutton_app.h" #include -#include +#include #include #include #include @@ -42,7 +42,9 @@ iButtonApp::iButtonApp() , storage{"storage"} , dialogs{"dialogs"} { furi_hal_power_insomnia_enter(); - key_worker = new KeyWorker(&ibutton_gpio); + key = ibutton_key_alloc(); + key_worker = ibutton_worker_alloc(); + ibutton_worker_start_thread(key_worker); } iButtonApp::~iButtonApp() { @@ -50,7 +52,10 @@ iButtonApp::~iButtonApp() { delete it->second; } scenes.clear(); - delete key_worker; + + ibutton_worker_stop_thread(key_worker); + ibutton_worker_free(key_worker); + ibutton_key_free(key); furi_hal_power_insomnia_exit(); } @@ -112,17 +117,12 @@ iButtonApp::Scene iButtonApp::get_previous_scene() { return scene; } -const GpioPin* iButtonApp::get_ibutton_pin() { - // TODO open record - return &ibutton_gpio; -} - -KeyWorker* iButtonApp::get_key_worker() { +iButtonWorker* iButtonApp::get_key_worker() { return key_worker; } iButtonKey* iButtonApp::get_key() { - return &key; + return key; } char* iButtonApp::get_file_name() { @@ -201,10 +201,11 @@ bool iButtonApp::save_key(const char* key_name) { if(!delete_key()) break; // Save the key - key.set_name(key_name); + ibutton_key_set_name(key, key_name); // Set full file name, for new key - string_printf(key_file_name, "%s/%s%s", app_folder, key.get_name(), app_extension); + string_printf( + key_file_name, "%s/%s%s", app_folder, ibutton_key_get_name_p(key), app_extension); // Open file for write if(!flipper_format_file_open_always(file, string_get_cstr(key_file_name))) break; @@ -215,7 +216,7 @@ bool iButtonApp::save_key(const char* key_name) { // Write key type if(!flipper_format_write_comment_cstr(file, "Key type can be Cyfral, Dallas or Metakom")) break; - const char* key_type = key.get_key_type_string_by_type(key.get_key_type()); + const char* key_type = ibutton_key_get_string_by_type(ibutton_key_get_type(key)); if(!flipper_format_write_string_cstr(file, "Key type", key_type)) break; // Write data @@ -223,7 +224,8 @@ bool iButtonApp::save_key(const char* key_name) { file, "Data size for Cyfral is 2, for Metakom is 4, for Dallas is 8")) break; - if(!flipper_format_write_hex(file, "Data", key.get_data(), key.get_type_data_size())) + if(!flipper_format_write_hex( + file, "Data", ibutton_key_get_data_p(key), ibutton_key_get_data_size(key))) break; result = true; @@ -258,15 +260,15 @@ bool iButtonApp::load_key_data(string_t key_path) { // key type iButtonKeyType type; if(!flipper_format_read_string(file, "Key type", data)) break; - if(!key.get_key_type_by_type_string(string_get_cstr(data), &type)) break; + if(!ibutton_key_get_type_by_string(string_get_cstr(data), &type)) break; // key data uint8_t key_data[IBUTTON_KEY_DATA_SIZE] = {0}; - if(!flipper_format_read_hex(file, "Data", key_data, key.get_type_data_size_by_type(type))) + if(!flipper_format_read_hex(file, "Data", key_data, ibutton_key_get_size_by_type(type))) break; - key.set_type(type); - key.set_data(key_data, IBUTTON_KEY_DATA_SIZE); + ibutton_key_set_type(key, type); + ibutton_key_set_data(key, key_data, IBUTTON_KEY_DATA_SIZE); result = true; } while(false); @@ -290,7 +292,7 @@ bool iButtonApp::load_key(const char* key_name) { result = load_key_data(key_path); if(result) { path_extract_filename_no_ext(key_name, key_path); - get_key()->set_name(string_get_cstr(key_path)); + ibutton_key_set_name(key, string_get_cstr(key_path)); } string_clear(key_path); return result; @@ -306,7 +308,7 @@ bool iButtonApp::load_key() { app_extension, get_file_name(), get_file_name_size(), - get_key()->get_name()); + ibutton_key_get_name_p(key)); if(res) { string_t key_str; @@ -316,7 +318,7 @@ bool iButtonApp::load_key() { result = load_key_data(key_str); if(result) { - get_key()->set_name(get_file_name()); + ibutton_key_set_name(key, get_file_name()); } string_clear(key_str); } @@ -328,7 +330,8 @@ bool iButtonApp::delete_key() { string_t file_name; bool result = false; - string_init_printf(file_name, "%s/%s%s", app_folder, get_key()->get_name(), app_extension); + string_init_printf( + file_name, "%s/%s%s", app_folder, ibutton_key_get_name_p(key), app_extension); result = storage_simply_remove(storage, string_get_cstr(file_name)); string_clear(file_name); diff --git a/applications/ibutton/ibutton_app.h b/applications/ibutton/ibutton_app.h index fc2a32e7..ddaadfcd 100644 --- a/applications/ibutton/ibutton_app.h +++ b/applications/ibutton/ibutton_app.h @@ -22,17 +22,10 @@ #include "scene/ibutton_scene_select_key.h" #include "scene/ibutton_scene_add_type.h" #include "scene/ibutton_scene_add_value.h" - -#include "helpers/key_worker.h" - -#include "one_wire_master.h" -#include "maxim_crc.h" -#include "ibutton_key.h" - +#include #include #include #include - #include class iButtonApp { @@ -75,7 +68,7 @@ public: Scene get_previous_scene(); const GpioPin* get_ibutton_pin(); - KeyWorker* get_key_worker(); + iButtonWorker* get_key_worker(); iButtonKey* get_key(); void notify_green_blink(); @@ -127,9 +120,8 @@ private: {Scene::SceneAddValue, new iButtonSceneAddValue()}, }; - KeyWorker* key_worker; - - iButtonKey key; + iButtonWorker* key_worker; + iButtonKey* key; RecordController notification; RecordController storage; diff --git a/applications/ibutton/ibutton_cli.c b/applications/ibutton/ibutton_cli.c new file mode 100644 index 00000000..44d7025c --- /dev/null +++ b/applications/ibutton/ibutton_cli.c @@ -0,0 +1,309 @@ +#include +#include +#include +#include +#include +#include +#include + +void ibutton_cli(Cli* cli, string_t args, void* context); +void onewire_cli(Cli* cli, string_t args, void* context); + +// app cli function +void ibutton_on_system_start() { +#ifdef SRV_CLI + Cli* cli = furi_record_open("cli"); + cli_add_command(cli, "ikey", CliCommandFlagDefault, ibutton_cli, cli); + cli_add_command(cli, "onewire", CliCommandFlagDefault, onewire_cli, cli); + furi_record_close("cli"); +#endif +} + +void ibutton_cli_print_usage() { + printf("Usage:\r\n"); + printf("ikey read\r\n"); + printf("ikey emulate \r\n"); + printf("ikey write Dallas \r\n"); + printf("\t choose from:\r\n"); + printf("\tDallas (8 bytes key_data)\r\n"); + printf("\tCyfral (2 bytes key_data)\r\n"); + printf("\tMetakom (4 bytes key_data), must contain correct parity\r\n"); + printf("\t are hex-formatted\r\n"); +}; + +bool ibutton_cli_get_key_type(string_t data, iButtonKeyType* type) { + bool result = false; + + if(string_cmp_str(data, "Dallas") == 0 || string_cmp_str(data, "dallas") == 0) { + result = true; + *type = iButtonKeyDS1990; + } else if(string_cmp_str(data, "Cyfral") == 0 || string_cmp_str(data, "cyfral") == 0) { + result = true; + *type = iButtonKeyCyfral; + } else if(string_cmp_str(data, "Metakom") == 0 || string_cmp_str(data, "metakom") == 0) { + result = true; + *type = iButtonKeyMetakom; + } + + return result; +} + +void ibutton_cli_print_key_data(iButtonKey* key) { + const uint8_t* key_data = ibutton_key_get_data_p(key); + iButtonKeyType type = ibutton_key_get_type(key); + + printf("%s ", ibutton_key_get_string_by_type(type)); + for(size_t i = 0; i < ibutton_key_get_size_by_type(type); i++) { + printf("%02X", key_data[i]); + } + + printf("\r\n"); +} + +#define EVENT_FLAG_IBUTTON_COMPLETE (1 << 0) + +static void ibutton_cli_worker_read_cb(void* context) { + osEventFlagsId_t event = context; + osEventFlagsSet(event, EVENT_FLAG_IBUTTON_COMPLETE); +} + +void ibutton_cli_read(Cli* cli) { + iButtonKey* key = ibutton_key_alloc(); + iButtonWorker* worker = ibutton_worker_alloc(); + osEventFlagsId_t event = osEventFlagsNew(NULL); + + ibutton_worker_start_thread(worker); + ibutton_worker_read_set_callback(worker, ibutton_cli_worker_read_cb, event); + + printf("Reading iButton...\r\nPress Ctrl+C to abort\r\n"); + ibutton_worker_read_start(worker, key); + while(true) { + uint32_t flags = osEventFlagsWait(event, EVENT_FLAG_IBUTTON_COMPLETE, osFlagsWaitAny, 100); + + if(flags & EVENT_FLAG_IBUTTON_COMPLETE) { + ibutton_cli_print_key_data(key); + + if(ibutton_key_get_type(key) == iButtonKeyDS1990) { + if(!ibutton_key_dallas_crc_is_valid(key)) { + printf("Warning: invalid CRC\r\n"); + } + + if(!ibutton_key_dallas_is_1990_key(key)) { + printf("Warning: not a key\r\n"); + } + } + break; + } + + if(cli_cmd_interrupt_received(cli)) break; + } + ibutton_worker_stop(worker); + + ibutton_worker_stop_thread(worker); + ibutton_worker_free(worker); + ibutton_key_free(key); + + osEventFlagsDelete(event); +}; + +typedef struct { + osEventFlagsId_t event; + iButtonWorkerWriteResult result; +} iButtonWriteContext; + +static void ibutton_cli_worker_write_cb(void* context, iButtonWorkerWriteResult result) { + iButtonWriteContext* write_context = (iButtonWriteContext*)context; + write_context->result = result; + osEventFlagsSet(write_context->event, EVENT_FLAG_IBUTTON_COMPLETE); +} + +void ibutton_cli_write(Cli* cli, string_t args) { + iButtonKey* key = ibutton_key_alloc(); + iButtonWorker* worker = ibutton_worker_alloc(); + iButtonKeyType type; + iButtonWriteContext write_context; + uint8_t key_data[IBUTTON_KEY_DATA_SIZE]; + string_t data; + + write_context.event = osEventFlagsNew(NULL); + + string_init(data); + ibutton_worker_start_thread(worker); + ibutton_worker_write_set_callback(worker, ibutton_cli_worker_write_cb, &write_context); + + do { + if(!args_read_string_and_trim(args, data)) { + ibutton_cli_print_usage(); + break; + } + + if(!ibutton_cli_get_key_type(data, &type)) { + ibutton_cli_print_usage(); + break; + } + + if(type != iButtonKeyDS1990) { + ibutton_cli_print_usage(); + break; + } + + if(!args_read_hex_bytes(args, key_data, ibutton_key_get_size_by_type(type))) { + ibutton_cli_print_usage(); + break; + } + + ibutton_key_set_type(key, type); + ibutton_key_set_data(key, key_data, ibutton_key_get_size_by_type(type)); + + printf("Writing key "); + ibutton_cli_print_key_data(key); + printf("Press Ctrl+C to abort\r\n"); + + ibutton_worker_write_start(worker, key); + while(true) { + uint32_t flags = osEventFlagsWait( + write_context.event, EVENT_FLAG_IBUTTON_COMPLETE, osFlagsWaitAny, 100); + + if(flags & EVENT_FLAG_IBUTTON_COMPLETE) { + if(write_context.result == iButtonWorkerWriteSameKey || + write_context.result == iButtonWorkerWriteOK) { + printf("Write success\r\n"); + break; + } else if(write_context.result == iButtonWorkerWriteCannotWrite) { + printf("Write fail\r\n"); + break; + } + } + + if(cli_cmd_interrupt_received(cli)) break; + } + ibutton_worker_stop(worker); + } while(false); + + string_clear(data); + ibutton_worker_stop_thread(worker); + ibutton_worker_free(worker); + ibutton_key_free(key); + + osEventFlagsDelete(write_context.event); +}; + +void ibutton_cli_emulate(Cli* cli, string_t args) { + iButtonKey* key = ibutton_key_alloc(); + iButtonWorker* worker = ibutton_worker_alloc(); + iButtonKeyType type; + uint8_t key_data[IBUTTON_KEY_DATA_SIZE]; + string_t data; + + string_init(data); + ibutton_worker_start_thread(worker); + + do { + if(!args_read_string_and_trim(args, data)) { + ibutton_cli_print_usage(); + break; + } + + if(!ibutton_cli_get_key_type(data, &type)) { + ibutton_cli_print_usage(); + break; + } + + if(!args_read_hex_bytes(args, key_data, ibutton_key_get_size_by_type(type))) { + ibutton_cli_print_usage(); + break; + } + + ibutton_key_set_type(key, type); + ibutton_key_set_data(key, key_data, ibutton_key_get_size_by_type(type)); + + printf("Emulating key "); + ibutton_cli_print_key_data(key); + printf("Press Ctrl+C to abort\r\n"); + + ibutton_worker_emulate_start(worker, key); + while(!cli_cmd_interrupt_received(cli)) { + furi_hal_delay_ms(100); + }; + ibutton_worker_stop(worker); + } while(false); + + string_clear(data); + ibutton_worker_stop_thread(worker); + ibutton_worker_free(worker); + ibutton_key_free(key); +}; + +void ibutton_cli(Cli* cli, string_t args, void* context) { + string_t cmd; + string_init(cmd); + + if(!args_read_string_and_trim(args, cmd)) { + string_clear(cmd); + ibutton_cli_print_usage(); + return; + } + + if(string_cmp_str(cmd, "read") == 0) { + ibutton_cli_read(cli); + } else if(string_cmp_str(cmd, "write") == 0) { + ibutton_cli_write(cli, args); + } else if(string_cmp_str(cmd, "emulate") == 0) { + ibutton_cli_emulate(cli, args); + } else { + ibutton_cli_print_usage(); + } + + string_clear(cmd); +} + +void onewire_cli_print_usage() { + printf("Usage:\r\n"); + printf("onewire search\r\n"); +}; + +void onewire_cli_search(Cli* cli) { + OneWireHost* onewire = onewire_host_alloc(); + uint8_t address[8]; + bool done = false; + + printf("Search started\r\n"); + + onewire_host_start(onewire); + furi_hal_power_enable_otg(); + + while(!done) { + if(onewire_host_search(onewire, address, NORMAL_SEARCH) != 1) { + printf("Search finished\r\n"); + onewire_host_reset_search(onewire); + done = true; + } else { + printf("Found: "); + for(uint8_t i = 0; i < 8; i++) { + printf("%02X", address[i]); + } + printf("\r\n"); + } + furi_hal_delay_ms(100); + } + + furi_hal_power_disable_otg(); + onewire_host_free(onewire); +} + +void onewire_cli(Cli* cli, string_t args, void* context) { + string_t cmd; + string_init(cmd); + + if(!args_read_string_and_trim(args, cmd)) { + string_clear(cmd); + onewire_cli_print_usage(); + return; + } + + if(string_cmp_str(cmd, "search") == 0) { + onewire_cli_search(cli); + } + + string_clear(cmd); +} diff --git a/applications/ibutton/ibutton_cli.cpp b/applications/ibutton/ibutton_cli.cpp deleted file mode 100644 index 3e41befa..00000000 --- a/applications/ibutton/ibutton_cli.cpp +++ /dev/null @@ -1,292 +0,0 @@ -#include -#include -#include -#include -#include - -#include "helpers/key_info.h" -#include "helpers/key_worker.h" - -#include - -void ibutton_cli(Cli* cli, string_t args, void* context); -void onewire_cli(Cli* cli, string_t args, void* context); - -// app cli function -extern "C" void ibutton_on_system_start() { -#ifdef SRV_CLI - Cli* cli = static_cast(furi_record_open("cli")); - cli_add_command(cli, "ikey", CliCommandFlagDefault, ibutton_cli, cli); - cli_add_command(cli, "onewire", CliCommandFlagDefault, onewire_cli, cli); - furi_record_close("cli"); -#endif -} - -void ibutton_cli_print_usage() { - printf("Usage:\r\n"); - printf("ikey read\r\n"); - printf("ikey \r\n"); - printf("\t choose from:\r\n"); - printf("\tDallas (8 bytes key_data)\r\n"); - printf("\tCyfral (2 bytes key_data)\r\n"); - printf("\tMetakom (4 bytes key_data)\r\n"); - printf("\t are hex-formatted\r\n"); -}; - -bool ibutton_cli_get_key_type(string_t data, iButtonKeyType* type) { - bool result = false; - - if(string_cmp_str(data, "Dallas") == 0 || string_cmp_str(data, "dallas") == 0) { - result = true; - *type = iButtonKeyType::KeyDallas; - } else if(string_cmp_str(data, "Cyfral") == 0 || string_cmp_str(data, "cyfral") == 0) { - result = true; - *type = iButtonKeyType::KeyCyfral; - } else if(string_cmp_str(data, "Metakom") == 0 || string_cmp_str(data, "metakom") == 0) { - result = true; - *type = iButtonKeyType::KeyMetakom; - } - - return result; -} - -void ibutton_cli_print_key_data(iButtonKey* key) { - uint8_t* key_data = key->get_data(); - switch(key->get_key_type()) { - case iButtonKeyType::KeyDallas: - printf( - "Dallas %02X%02X%02X%02X%02X%02X%02X%02X\r\n", - key_data[0], - key_data[1], - key_data[2], - key_data[3], - key_data[4], - key_data[5], - key_data[6], - key_data[7]); - break; - case iButtonKeyType::KeyCyfral: - printf("Cyfral %02X%02X\r\n", key_data[0], key_data[1]); - break; - case iButtonKeyType::KeyMetakom: - printf("Metakom %02X%02X%02X%02X\r\n", key_data[0], key_data[1], key_data[2], key_data[3]); - break; - } -} - -void ibutton_cli_read(Cli* cli) { - iButtonKey key; - std::unique_ptr worker(new KeyWorker(&ibutton_gpio)); - - bool exit = false; - - worker->start_read(); - printf("Reading iButton...\r\nPress Ctrl+C to abort\r\n"); - - while(!exit) { - exit = cli_cmd_interrupt_received(cli); - - switch(worker->read(&key)) { - case KeyReader::Error::EMPTY: - break; - case KeyReader::Error::CRC_ERROR: - ibutton_cli_print_key_data(&key); - printf("Warning: invalid CRC\r\n"); - exit = true; - break; - case KeyReader::Error::OK: - ibutton_cli_print_key_data(&key); - exit = true; - break; - case KeyReader::Error::NOT_ARE_KEY: - ibutton_cli_print_key_data(&key); - printf("Warning: not a key\r\n"); - exit = true; - break; - } - - delay(100); - } - - worker->stop_read(); -}; - -void ibutton_cli_write(Cli* cli, string_t args) { - iButtonKey key; - iButtonKeyType type; - std::unique_ptr worker(new KeyWorker(&ibutton_gpio)); - - bool exit = false; - string_t data; - string_init(data); - - if(!args_read_string_and_trim(args, data)) { - ibutton_cli_print_usage(); - string_clear(data); - return; - } - - if(!ibutton_cli_get_key_type(data, &type)) { - ibutton_cli_print_usage(); - string_clear(data); - return; - } - - key.set_type(type); - - if(!args_read_hex_bytes(args, key.get_data(), key.get_type_data_size())) { - ibutton_cli_print_usage(); - string_clear(data); - return; - } - - printf("Writing key "); - ibutton_cli_print_key_data(&key); - printf("Press Ctrl+C to abort\r\n"); - - worker->start_write(); - - while(!exit) { - exit = cli_cmd_interrupt_received(cli); - - KeyWriter::Error result = worker->write(&key); - - switch(result) { - case KeyWriter::Error::SAME_KEY: - case KeyWriter::Error::OK: - printf("Write success\r\n"); - exit = true; - break; - case KeyWriter::Error::NO_DETECT: - break; - case KeyWriter::Error::CANNOT_WRITE: - printf("Write fail\r\n"); - exit = true; - break; - } - - delay(100); - }; - - worker->stop_write(); - - string_clear(data); -}; - -void ibutton_cli_emulate(Cli* cli, string_t args) { - iButtonKey key; - iButtonKeyType type; - std::unique_ptr worker(new KeyWorker(&ibutton_gpio)); - bool exit = false; - string_t data; - string_init(data); - - if(!args_read_string_and_trim(args, data)) { - ibutton_cli_print_usage(); - string_clear(data); - return; - } - - if(!ibutton_cli_get_key_type(data, &type)) { - ibutton_cli_print_usage(); - string_clear(data); - return; - } - - key.set_type(type); - - if(!args_read_hex_bytes(args, key.get_data(), key.get_type_data_size())) { - ibutton_cli_print_usage(); - string_clear(data); - return; - } - - printf("Emulating key "); - ibutton_cli_print_key_data(&key); - printf("Press Ctrl+C to abort\r\n"); - - worker->start_emulate(&key); - - while(!exit) { - exit = cli_cmd_interrupt_received(cli); - delay(100); - }; - - worker->stop_emulate(); - - string_clear(data); -}; - -void ibutton_cli(Cli* cli, string_t args, void* context) { - string_t cmd; - string_init(cmd); - - if(!args_read_string_and_trim(args, cmd)) { - string_clear(cmd); - ibutton_cli_print_usage(); - return; - } - - if(string_cmp_str(cmd, "read") == 0) { - ibutton_cli_read(cli); - } else if(string_cmp_str(cmd, "write") == 0) { - ibutton_cli_write(cli, args); - } else if(string_cmp_str(cmd, "emulate") == 0) { - ibutton_cli_emulate(cli, args); - } else { - ibutton_cli_print_usage(); - } - - string_clear(cmd); -} - -void onewire_cli_print_usage() { - printf("Usage:\r\n"); - printf("onewire search\r\n"); -}; - -void onewire_cli_search(Cli* cli) { - OneWireMaster onewire(&ibutton_gpio); - uint8_t address[8]; - bool done = false; - - printf("Search started\r\n"); - - onewire.start(); - furi_hal_power_enable_otg(); - - while(!done) { - if(onewire.search(address, true) != 1) { - printf("Search finished\r\n"); - onewire.reset_search(); - done = true; - } else { - printf("Found: "); - for(uint8_t i = 0; i < 8; i++) { - printf("%02X", address[i]); - } - printf("\r\n"); - } - delay(100); - } - - furi_hal_power_disable_otg(); - onewire.stop(); -} - -void onewire_cli(Cli* cli, string_t args, void* context) { - string_t cmd; - string_init(cmd); - - if(!args_read_string_and_trim(args, cmd)) { - string_clear(cmd); - onewire_cli_print_usage(); - return; - } - - if(string_cmp_str(cmd, "search") == 0) { - onewire_cli_search(cli); - } - - string_clear(cmd); -} diff --git a/applications/ibutton/ibutton_event.h b/applications/ibutton/ibutton_event.h index 0d6f4d90..b4dac2f4 100644 --- a/applications/ibutton/ibutton_event.h +++ b/applications/ibutton/ibutton_event.h @@ -2,6 +2,7 @@ #include #include #include +#include class iButtonApp; @@ -16,6 +17,9 @@ public: EventTypeTextEditResult, EventTypeByteEditResult, EventTypeWidgetButtonResult, + EventTypeWorkerEmulated, + EventTypeWorkerRead, + EventTypeWorkerWrite, }; // payload @@ -23,6 +27,7 @@ public: uint32_t menu_index; DialogExResult dialog_result; GuiButtonType widget_button_result; + iButtonWorkerWriteResult worker_write_result; } payload; // event type diff --git a/applications/ibutton/ibutton_key.cpp b/applications/ibutton/ibutton_key.cpp deleted file mode 100644 index cb65a239..00000000 --- a/applications/ibutton/ibutton_key.cpp +++ /dev/null @@ -1,95 +0,0 @@ -#include "ibutton_key.h" -#include - -uint8_t iButtonKey::get_size() { - return IBUTTON_KEY_DATA_SIZE; -} - -void iButtonKey::set_data(uint8_t* _data, uint8_t _data_count) { - furi_check(_data_count > 0); - furi_check(_data_count <= get_size()); - - memset(data, 0, get_size()); - memcpy(data, _data, _data_count); -} - -void iButtonKey::clear_data() { - memset(data, 0, get_size()); -} - -uint8_t* iButtonKey::get_data() { - return data; -} - -uint8_t iButtonKey::get_type_data_size() { - return get_type_data_size_by_type(type); -} - -void iButtonKey::set_name(const char* _name) { - strlcpy(name, _name, IBUTTON_KEY_NAME_SIZE); -} - -char* iButtonKey::get_name() { - return name; -} - -void iButtonKey::set_type(iButtonKeyType _key_type) { - type = _key_type; -} - -iButtonKeyType iButtonKey::get_key_type() { - return type; -} - -const char* iButtonKey::get_key_type_string_by_type(iButtonKeyType key_type) { - switch(key_type) { - case iButtonKeyType::KeyCyfral: - return "Cyfral"; - break; - case iButtonKeyType::KeyMetakom: - return "Metakom"; - break; - case iButtonKeyType::KeyDallas: - return "Dallas"; - break; - default: - furi_crash("Invalid iButton type"); - return ""; - break; - } -} - -bool iButtonKey::get_key_type_by_type_string(const char* type_string, iButtonKeyType* key_type) { - if(strcmp(type_string, get_key_type_string_by_type(iButtonKeyType::KeyCyfral)) == 0) { - *key_type = iButtonKeyType::KeyCyfral; - } else if(strcmp(type_string, get_key_type_string_by_type(iButtonKeyType::KeyMetakom)) == 0) { - *key_type = iButtonKeyType::KeyMetakom; - } else if(strcmp(type_string, get_key_type_string_by_type(iButtonKeyType::KeyDallas)) == 0) { - *key_type = iButtonKeyType::KeyDallas; - } else { - return false; - } - - return true; -} - -uint8_t iButtonKey::get_type_data_size_by_type(iButtonKeyType key_type) { - uint8_t size = 0; - - switch(key_type) { - case iButtonKeyType::KeyCyfral: - size = 2; - break; - case iButtonKeyType::KeyMetakom: - size = 4; - break; - case iButtonKeyType::KeyDallas: - size = 8; - break; - } - - return size; -} - -iButtonKey::iButtonKey() { -} diff --git a/applications/ibutton/ibutton_key.h b/applications/ibutton/ibutton_key.h deleted file mode 100644 index 506182fe..00000000 --- a/applications/ibutton/ibutton_key.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once -#include -#include "helpers/key_info.h" - -class iButtonKey { -public: - uint8_t get_size(); - - void set_data(uint8_t* data, uint8_t data_count); - void clear_data(); - uint8_t* get_data(); - uint8_t get_type_data_size(); - - void set_name(const char* name); - char* get_name(); - - void set_type(iButtonKeyType key_type); - iButtonKeyType get_key_type(); - - const char* get_key_type_string_by_type(iButtonKeyType key_type); - bool get_key_type_by_type_string(const char* type_string, iButtonKeyType* key_type); - uint8_t get_type_data_size_by_type(iButtonKeyType key_type); - - iButtonKey(); - -private: - uint8_t data[IBUTTON_KEY_DATA_SIZE] = {0, 0, 0, 0, 0, 0, 0, 0}; - char name[IBUTTON_KEY_NAME_SIZE] = {0}; - - iButtonKeyType type = iButtonKeyType::KeyDallas; -}; \ No newline at end of file diff --git a/applications/ibutton/scene/ibutton_scene_add_type.cpp b/applications/ibutton/scene/ibutton_scene_add_type.cpp index 0c573f41..aa76d3c0 100644 --- a/applications/ibutton/scene/ibutton_scene_add_type.cpp +++ b/applications/ibutton/scene/ibutton_scene_add_type.cpp @@ -1,7 +1,5 @@ #include "ibutton_scene_add_type.h" #include "../ibutton_app.h" -#include "../ibutton_view_manager.h" -#include "../ibutton_event.h" #include typedef enum { @@ -10,14 +8,23 @@ typedef enum { SubmenuIndexMetakom, } SubmenuIndex; +static void submenu_callback(void* context, uint32_t index) { + iButtonApp* app = static_cast(context); + iButtonEvent event; + + event.type = iButtonEvent::Type::EventTypeMenuSelected; + event.payload.menu_index = index; + + app->get_view_manager()->send_event(&event); +} + void iButtonSceneAddType::on_enter(iButtonApp* app) { iButtonAppViewManager* view_manager = app->get_view_manager(); Submenu* submenu = view_manager->get_submenu(); - auto callback = cbc::obtain_connector(this, &iButtonSceneAddType::submenu_callback); - submenu_add_item(submenu, "Cyfral", SubmenuIndexCyfral, callback, app); - submenu_add_item(submenu, "Dallas", SubmenuIndexDallas, callback, app); - submenu_add_item(submenu, "Metakom", SubmenuIndexMetakom, callback, app); + submenu_add_item(submenu, "Cyfral", SubmenuIndexCyfral, submenu_callback, app); + submenu_add_item(submenu, "Dallas", SubmenuIndexDallas, submenu_callback, app); + submenu_add_item(submenu, "Metakom", SubmenuIndexMetakom, submenu_callback, app); submenu_set_selected_item(submenu, submenu_item_selected); view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewSubmenu); @@ -28,19 +35,21 @@ bool iButtonSceneAddType::on_event(iButtonApp* app, iButtonEvent* event) { if(event->type == iButtonEvent::Type::EventTypeMenuSelected) { submenu_item_selected = event->payload.menu_index; + iButtonKey* key = app->get_key(); + switch(event->payload.menu_index) { case SubmenuIndexCyfral: - app->get_key()->set_type(iButtonKeyType::KeyCyfral); + ibutton_key_set_type(key, iButtonKeyCyfral); break; case SubmenuIndexDallas: - app->get_key()->set_type(iButtonKeyType::KeyDallas); + ibutton_key_set_type(key, iButtonKeyDS1990); break; case SubmenuIndexMetakom: - app->get_key()->set_type(iButtonKeyType::KeyMetakom); + ibutton_key_set_type(key, iButtonKeyMetakom); break; } - app->get_key()->set_name(""); - app->get_key()->clear_data(); + ibutton_key_set_name(key, ""); + ibutton_key_clear_data(key); app->switch_to_next_scene(iButtonApp::Scene::SceneAddValue); consumed = true; } @@ -54,13 +63,3 @@ void iButtonSceneAddType::on_exit(iButtonApp* app) { submenu_reset(submenu); } - -void iButtonSceneAddType::submenu_callback(void* context, uint32_t index) { - iButtonApp* app = static_cast(context); - iButtonEvent event; - - event.type = iButtonEvent::Type::EventTypeMenuSelected; - event.payload.menu_index = index; - - app->get_view_manager()->send_event(&event); -} diff --git a/applications/ibutton/scene/ibutton_scene_add_type.h b/applications/ibutton/scene/ibutton_scene_add_type.h index fd0eb6c1..d49ac128 100644 --- a/applications/ibutton/scene/ibutton_scene_add_type.h +++ b/applications/ibutton/scene/ibutton_scene_add_type.h @@ -8,6 +8,5 @@ public: void on_exit(iButtonApp* app) final; private: - void submenu_callback(void* context, uint32_t index); uint32_t submenu_item_selected = 0; }; \ No newline at end of file diff --git a/applications/ibutton/scene/ibutton_scene_add_value.cpp b/applications/ibutton/scene/ibutton_scene_add_value.cpp index d91408b6..95d5f82f 100755 --- a/applications/ibutton/scene/ibutton_scene_add_value.cpp +++ b/applications/ibutton/scene/ibutton_scene_add_value.cpp @@ -1,17 +1,30 @@ #include "ibutton_scene_add_value.h" #include "../ibutton_app.h" -#include "../ibutton_view_manager.h" -#include "../ibutton_event.h" -#include #include +static void byte_input_callback(void* context) { + iButtonApp* app = static_cast(context); + iButtonEvent event; + + event.type = iButtonEvent::Type::EventTypeByteEditResult; + app->get_view_manager()->send_event(&event); +} + void iButtonSceneAddValue::on_enter(iButtonApp* app) { iButtonAppViewManager* view_manager = app->get_view_manager(); ByteInput* byte_input = view_manager->get_byte_input(); - auto callback = cbc::obtain_connector(this, &iButtonSceneAddValue::byte_input_callback); - memcpy(this->new_key_data, app->get_key()->get_data(), app->get_key()->get_type_data_size()); + iButtonKey* key = app->get_key(); + + memcpy(this->new_key_data, ibutton_key_get_data_p(key), ibutton_key_get_data_size(key)); + byte_input_set_result_callback( - byte_input, callback, NULL, app, this->new_key_data, app->get_key()->get_type_data_size()); + byte_input, + byte_input_callback, + NULL, + app, + this->new_key_data, + ibutton_key_get_data_size(key)); + byte_input_set_header_text(byte_input, "Enter the key"); view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewByteInput); @@ -21,6 +34,7 @@ bool iButtonSceneAddValue::on_event(iButtonApp* app, iButtonEvent* event) { bool consumed = false; if(event->type == iButtonEvent::Type::EventTypeByteEditResult) { + ibutton_key_set_data(app->get_key(), this->new_key_data, IBUTTON_KEY_DATA_SIZE); DOLPHIN_DEED(DolphinDeedIbuttonAdd); app->switch_to_next_scene(iButtonApp::Scene::SceneSaveName); consumed = true; @@ -35,13 +49,4 @@ void iButtonSceneAddValue::on_exit(iButtonApp* app) { byte_input_set_result_callback(byte_input, NULL, NULL, NULL, NULL, 0); byte_input_set_header_text(byte_input, {0}); -} - -void iButtonSceneAddValue::byte_input_callback(void* context) { - iButtonApp* app = static_cast(context); - iButtonEvent event; - - event.type = iButtonEvent::Type::EventTypeByteEditResult; - memcpy(app->get_key()->get_data(), this->new_key_data, app->get_key()->get_type_data_size()); - app->get_view_manager()->send_event(&event); -} +} \ No newline at end of file diff --git a/applications/ibutton/scene/ibutton_scene_add_value.h b/applications/ibutton/scene/ibutton_scene_add_value.h index 60efd31e..ff6de577 100644 --- a/applications/ibutton/scene/ibutton_scene_add_value.h +++ b/applications/ibutton/scene/ibutton_scene_add_value.h @@ -1,6 +1,6 @@ #pragma once #include "ibutton_scene_generic.h" -#include "../ibutton_key.h" +#include class iButtonSceneAddValue : public iButtonScene { public: @@ -9,6 +9,5 @@ public: void on_exit(iButtonApp* app) final; private: - void byte_input_callback(void* context); uint8_t new_key_data[IBUTTON_KEY_DATA_SIZE] = {}; }; \ No newline at end of file diff --git a/applications/ibutton/scene/ibutton_scene_delete_confirm.cpp b/applications/ibutton/scene/ibutton_scene_delete_confirm.cpp index e5303d04..91e471df 100755 --- a/applications/ibutton/scene/ibutton_scene_delete_confirm.cpp +++ b/applications/ibutton/scene/ibutton_scene_delete_confirm.cpp @@ -1,25 +1,31 @@ #include "ibutton_scene_delete_confirm.h" #include "../ibutton_app.h" -#include "../ibutton_view_manager.h" -#include "../ibutton_event.h" -#include + +static void widget_callback(GuiButtonType result, InputType type, void* context) { + iButtonApp* app = static_cast(context); + iButtonEvent event; + + if(type == InputTypeShort) { + event.type = iButtonEvent::Type::EventTypeWidgetButtonResult; + event.payload.widget_button_result = result; + app->get_view_manager()->send_event(&event); + } +} void iButtonSceneDeleteConfirm::on_enter(iButtonApp* app) { iButtonAppViewManager* view_manager = app->get_view_manager(); Widget* widget = view_manager->get_widget(); - auto callback = cbc::obtain_connector(this, &iButtonSceneDeleteConfirm::widget_callback); - iButtonKey* key = app->get_key(); - uint8_t* key_data = key->get_data(); + const uint8_t* key_data = ibutton_key_get_data_p(key); - app->set_text_store("\e#Delete %s?\e#", key->get_name()); + app->set_text_store("\e#Delete %s?\e#", ibutton_key_get_name_p(key)); widget_add_text_box_element( widget, 0, 0, 128, 27, AlignCenter, AlignCenter, app->get_text_store()); - widget_add_button_element(widget, GuiButtonTypeLeft, "Back", callback, app); - widget_add_button_element(widget, GuiButtonTypeRight, "Delete", callback, app); + widget_add_button_element(widget, GuiButtonTypeLeft, "Back", widget_callback, app); + widget_add_button_element(widget, GuiButtonTypeRight, "Delete", widget_callback, app); - switch(key->get_key_type()) { - case iButtonKeyType::KeyDallas: + switch(ibutton_key_get_type(key)) { + case iButtonKeyDS1990: app->set_text_store( "%02X %02X %02X %02X %02X %02X %02X %02X", key_data[0], @@ -33,12 +39,12 @@ void iButtonSceneDeleteConfirm::on_enter(iButtonApp* app) { widget_add_string_element( widget, 64, 45, AlignCenter, AlignBottom, FontSecondary, "Dallas"); break; - case iButtonKeyType::KeyCyfral: + case iButtonKeyCyfral: app->set_text_store("%02X %02X", key_data[0], key_data[1]); widget_add_string_element( widget, 64, 45, AlignCenter, AlignBottom, FontSecondary, "Cyfral"); break; - case iButtonKeyType::KeyMetakom: + case iButtonKeyMetakom: app->set_text_store( "%02X %02X %02X %02X", key_data[0], key_data[1], key_data[2], key_data[3]); widget_add_string_element( @@ -77,18 +83,3 @@ void iButtonSceneDeleteConfirm::on_exit(iButtonApp* app) { widget_reset(widget); } - -void iButtonSceneDeleteConfirm::widget_callback( - GuiButtonType result, - InputType type, - void* context) { - iButtonApp* app = static_cast(context); - iButtonEvent event; - - if(type == InputTypeShort) { - event.type = iButtonEvent::Type::EventTypeWidgetButtonResult; - event.payload.widget_button_result = result; - } - - app->get_view_manager()->send_event(&event); -} diff --git a/applications/ibutton/scene/ibutton_scene_delete_confirm.h b/applications/ibutton/scene/ibutton_scene_delete_confirm.h index 017acc53..d82c376d 100644 --- a/applications/ibutton/scene/ibutton_scene_delete_confirm.h +++ b/applications/ibutton/scene/ibutton_scene_delete_confirm.h @@ -6,7 +6,4 @@ public: void on_enter(iButtonApp* app) final; bool on_event(iButtonApp* app, iButtonEvent* event) final; void on_exit(iButtonApp* app) final; - -private: - void widget_callback(GuiButtonType result, InputType type, void* context); }; \ No newline at end of file diff --git a/applications/ibutton/scene/ibutton_scene_delete_success.cpp b/applications/ibutton/scene/ibutton_scene_delete_success.cpp index b38aa653..e2b64999 100644 --- a/applications/ibutton/scene/ibutton_scene_delete_success.cpp +++ b/applications/ibutton/scene/ibutton_scene_delete_success.cpp @@ -1,19 +1,21 @@ #include "ibutton_scene_delete_success.h" #include "../ibutton_app.h" -#include "../ibutton_view_manager.h" -#include "../ibutton_event.h" -#include "../ibutton_key.h" -#include + +static void popup_callback(void* context) { + iButtonApp* app = static_cast(context); + iButtonEvent event; + event.type = iButtonEvent::Type::EventTypeBack; + app->get_view_manager()->send_event(&event); +} void iButtonSceneDeleteSuccess::on_enter(iButtonApp* app) { iButtonAppViewManager* view_manager = app->get_view_manager(); Popup* popup = view_manager->get_popup(); - auto callback = cbc::obtain_connector(this, &iButtonSceneDeleteSuccess::popup_callback); popup_set_icon(popup, 0, 2, &I_DolphinMafia_115x62); popup_set_text(popup, "Deleted", 83, 19, AlignLeft, AlignBottom); - popup_set_callback(popup, callback); + popup_set_callback(popup, popup_callback); popup_set_context(popup, app); popup_set_timeout(popup, 1500); popup_enable_timeout(popup); @@ -41,11 +43,4 @@ void iButtonSceneDeleteSuccess::on_exit(iButtonApp* app) { popup_disable_timeout(popup); popup_set_context(popup, NULL); popup_set_callback(popup, NULL); -} - -void iButtonSceneDeleteSuccess::popup_callback(void* context) { - iButtonApp* app = static_cast(context); - iButtonEvent event; - event.type = iButtonEvent::Type::EventTypeBack; - app->get_view_manager()->send_event(&event); } \ No newline at end of file diff --git a/applications/ibutton/scene/ibutton_scene_delete_success.h b/applications/ibutton/scene/ibutton_scene_delete_success.h index 42be6705..0c17c7ed 100644 --- a/applications/ibutton/scene/ibutton_scene_delete_success.h +++ b/applications/ibutton/scene/ibutton_scene_delete_success.h @@ -6,7 +6,4 @@ public: void on_enter(iButtonApp* app) final; bool on_event(iButtonApp* app, iButtonEvent* event) final; void on_exit(iButtonApp* app) final; - -private: - void popup_callback(void* context); }; \ No newline at end of file diff --git a/applications/ibutton/scene/ibutton_scene_emulate.cpp b/applications/ibutton/scene/ibutton_scene_emulate.cpp index 7fe6df28..8f517c78 100644 --- a/applications/ibutton/scene/ibutton_scene_emulate.cpp +++ b/applications/ibutton/scene/ibutton_scene_emulate.cpp @@ -1,17 +1,21 @@ #include "ibutton_scene_emulate.h" #include "../ibutton_app.h" -#include "../ibutton_view_manager.h" -#include "../ibutton_event.h" -#include "../ibutton_key.h" #include -#include + +static void emulate_callback(void* context, bool emulated) { + if(emulated) { + iButtonApp* app = static_cast(context); + iButtonEvent event = {.type = iButtonEvent::Type::EventTypeWorkerEmulated}; + app->get_view_manager()->send_event(&event); + } +} void iButtonSceneEmulate::on_enter(iButtonApp* app) { iButtonAppViewManager* view_manager = app->get_view_manager(); Popup* popup = view_manager->get_popup(); iButtonKey* key = app->get_key(); - uint8_t* key_data = key->get_data(); - const char* key_name = key->get_name(); + const uint8_t* key_data = ibutton_key_get_data_p(key); + const char* key_name = ibutton_key_get_name_p(key); uint8_t line_count = 2; DOLPHIN_DEED(DolphinDeedIbuttonEmulate); @@ -21,8 +25,8 @@ void iButtonSceneEmulate::on_enter(iButtonApp* app) { line_count = 2; } else { // if not, show key data - switch(key->get_key_type()) { - case iButtonKeyType::KeyDallas: + switch(ibutton_key_get_type(key)) { + case iButtonKeyDS1990: app->set_text_store( "emulating\n%02X %02X %02X %02X\n%02X %02X %02X %02X", key_data[0], @@ -35,11 +39,11 @@ void iButtonSceneEmulate::on_enter(iButtonApp* app) { key_data[7]); line_count = 3; break; - case iButtonKeyType::KeyCyfral: + case iButtonKeyCyfral: app->set_text_store("emulating\n%02X %02X", key_data[0], key_data[1]); line_count = 2; break; - case iButtonKeyType::KeyMetakom: + case iButtonKeyMetakom: app->set_text_store( "emulating\n%02X %02X %02X %02X", key_data[0], @@ -66,29 +70,28 @@ void iButtonSceneEmulate::on_enter(iButtonApp* app) { popup_set_icon(popup, 2, 10, &I_iButtonKey_49x44); view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewPopup); - app->get_key_worker()->start_emulate(app->get_key()); + + ibutton_worker_emulate_set_callback(app->get_key_worker(), emulate_callback, app); + ibutton_worker_emulate_start(app->get_key_worker(), key); } bool iButtonSceneEmulate::on_event(iButtonApp* app, iButtonEvent* event) { bool consumed = false; - if(event->type == iButtonEvent::Type::EventTypeTick) { + if(event->type == iButtonEvent::Type::EventTypeWorkerEmulated) { + app->notify_yellow_blink(); + consumed = true; + } else if(event->type == iButtonEvent::Type::EventTypeTick) { + app->notify_red_blink(); consumed = true; - if(app->get_key_worker()->emulated()) { - app->notify_yellow_blink(); - } else { - app->notify_red_blink(); - } } return consumed; } void iButtonSceneEmulate::on_exit(iButtonApp* app) { - app->get_key_worker()->stop_emulate(); - Popup* popup = app->get_view_manager()->get_popup(); - + ibutton_worker_stop(app->get_key_worker()); popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); popup_set_icon(popup, 0, 0, NULL); diff --git a/applications/ibutton/scene/ibutton_scene_emulate.h b/applications/ibutton/scene/ibutton_scene_emulate.h index 112c13f5..c2bedcc5 100644 --- a/applications/ibutton/scene/ibutton_scene_emulate.h +++ b/applications/ibutton/scene/ibutton_scene_emulate.h @@ -1,6 +1,5 @@ #pragma once #include "ibutton_scene_generic.h" -#include "../helpers/key_emulator.h" class iButtonSceneEmulate : public iButtonScene { public: diff --git a/applications/ibutton/scene/ibutton_scene_info.cpp b/applications/ibutton/scene/ibutton_scene_info.cpp index a05d013f..f4cbd809 100755 --- a/applications/ibutton/scene/ibutton_scene_info.cpp +++ b/applications/ibutton/scene/ibutton_scene_info.cpp @@ -1,24 +1,30 @@ #include "ibutton_scene_info.h" #include "../ibutton_app.h" -#include "../ibutton_view_manager.h" -#include "../ibutton_event.h" -#include + +static void widget_callback(GuiButtonType result, InputType type, void* context) { + iButtonApp* app = static_cast(context); + iButtonEvent event; + + if(type == InputTypeShort) { + event.type = iButtonEvent::Type::EventTypeWidgetButtonResult; + event.payload.widget_button_result = result; + app->get_view_manager()->send_event(&event); + } +} void iButtonSceneInfo::on_enter(iButtonApp* app) { iButtonAppViewManager* view_manager = app->get_view_manager(); Widget* widget = view_manager->get_widget(); - auto callback = cbc::obtain_connector(this, &iButtonSceneInfo::widget_callback); - iButtonKey* key = app->get_key(); - uint8_t* key_data = key->get_data(); + const uint8_t* key_data = ibutton_key_get_data_p(key); - app->set_text_store("%s", key->get_name()); + app->set_text_store("%s", ibutton_key_get_name_p(key)); widget_add_text_box_element( widget, 0, 0, 128, 27, AlignCenter, AlignCenter, app->get_text_store()); - widget_add_button_element(widget, GuiButtonTypeLeft, "Back", callback, app); + widget_add_button_element(widget, GuiButtonTypeLeft, "Back", widget_callback, app); - switch(key->get_key_type()) { - case iButtonKeyType::KeyDallas: + switch(ibutton_key_get_type(key)) { + case iButtonKeyDS1990: app->set_text_store( "%02X %02X %02X %02X %02X %02X %02X %02X", key_data[0], @@ -32,13 +38,13 @@ void iButtonSceneInfo::on_enter(iButtonApp* app) { widget_add_string_element( widget, 64, 45, AlignCenter, AlignBottom, FontSecondary, "Dallas"); break; - case iButtonKeyType::KeyMetakom: + case iButtonKeyMetakom: app->set_text_store( "%02X %02X %02X %02X", key_data[0], key_data[1], key_data[2], key_data[3]); widget_add_string_element( widget, 64, 45, AlignCenter, AlignBottom, FontSecondary, "Metakom"); break; - case iButtonKeyType::KeyCyfral: + case iButtonKeyCyfral: app->set_text_store("%02X %02X", key_data[0], key_data[1]); widget_add_string_element( widget, 64, 45, AlignCenter, AlignBottom, FontSecondary, "Cyfral"); @@ -71,15 +77,3 @@ void iButtonSceneInfo::on_exit(iButtonApp* app) { widget_reset(widget); } - -void iButtonSceneInfo::widget_callback(GuiButtonType result, InputType type, void* context) { - iButtonApp* app = static_cast(context); - iButtonEvent event; - - if(type == InputTypeShort) { - event.type = iButtonEvent::Type::EventTypeWidgetButtonResult; - event.payload.widget_button_result = result; - } - - app->get_view_manager()->send_event(&event); -} diff --git a/applications/ibutton/scene/ibutton_scene_info.h b/applications/ibutton/scene/ibutton_scene_info.h index 6869c1c7..e2c6b2cf 100644 --- a/applications/ibutton/scene/ibutton_scene_info.h +++ b/applications/ibutton/scene/ibutton_scene_info.h @@ -6,7 +6,4 @@ public: void on_enter(iButtonApp* app) final; bool on_event(iButtonApp* app, iButtonEvent* event) final; void on_exit(iButtonApp* app) final; - -private: - void widget_callback(GuiButtonType result, InputType type, void* context); }; \ No newline at end of file diff --git a/applications/ibutton/scene/ibutton_scene_read.cpp b/applications/ibutton/scene/ibutton_scene_read.cpp index a16cb23d..b5c7ac8f 100644 --- a/applications/ibutton/scene/ibutton_scene_read.cpp +++ b/applications/ibutton/scene/ibutton_scene_read.cpp @@ -1,12 +1,18 @@ #include "ibutton_scene_read.h" #include "../ibutton_app.h" -#include "../ibutton_view_manager.h" -#include "../ibutton_event.h" #include +static void read_callback(void* context) { + iButtonApp* app = static_cast(context); + iButtonEvent event = {.type = iButtonEvent::Type::EventTypeWorkerRead}; + app->get_view_manager()->send_event(&event); +} + void iButtonSceneRead::on_enter(iButtonApp* app) { iButtonAppViewManager* view_manager = app->get_view_manager(); Popup* popup = view_manager->get_popup(); + iButtonKey* key = app->get_key(); + iButtonWorker* worker = app->get_key_worker(); DOLPHIN_DEED(DolphinDeedIbuttonRead); popup_set_header(popup, "iButton", 95, 26, AlignCenter, AlignBottom); @@ -14,41 +20,41 @@ void iButtonSceneRead::on_enter(iButtonApp* app) { popup_set_icon(popup, 0, 5, &I_DolphinWait_61x59); view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewPopup); - app->get_key()->set_name(""); + ibutton_key_set_name(key, ""); - app->get_key_worker()->start_read(); + ibutton_worker_read_set_callback(worker, read_callback, app); + ibutton_worker_read_start(worker, key); } bool iButtonSceneRead::on_event(iButtonApp* app, iButtonEvent* event) { bool consumed = false; - if(event->type == iButtonEvent::Type::EventTypeTick) { + if(event->type == iButtonEvent::Type::EventTypeWorkerRead) { + consumed = true; + + iButtonKey* key = app->get_key(); + if(ibutton_key_get_type(key) == iButtonKeyDS1990) { + if(!ibutton_key_dallas_crc_is_valid(key)) { + app->switch_to_next_scene(iButtonApp::Scene::SceneReadCRCError); + } else if(!ibutton_key_dallas_is_1990_key(key)) { + app->switch_to_next_scene(iButtonApp::Scene::SceneReadNotKeyError); + } else { + app->switch_to_next_scene(iButtonApp::Scene::SceneReadSuccess); + } + } else { + app->switch_to_next_scene(iButtonApp::Scene::SceneReadSuccess); + } + } else if(event->type == iButtonEvent::Type::EventTypeTick) { consumed = true; app->notify_red_blink(); - - switch(app->get_key_worker()->read(app->get_key())) { - case KeyReader::Error::EMPTY: - break; - case KeyReader::Error::OK: - app->switch_to_next_scene(iButtonApp::Scene::SceneReadSuccess); - break; - case KeyReader::Error::CRC_ERROR: - app->switch_to_next_scene(iButtonApp::Scene::SceneReadCRCError); - break; - case KeyReader::Error::NOT_ARE_KEY: - app->switch_to_next_scene(iButtonApp::Scene::SceneReadNotKeyError); - break; - } } return consumed; } void iButtonSceneRead::on_exit(iButtonApp* app) { - app->get_key_worker()->stop_read(); - Popup* popup = app->get_view_manager()->get_popup(); - + ibutton_worker_stop(app->get_key_worker()); popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); popup_set_icon(popup, 0, 0, NULL); diff --git a/applications/ibutton/scene/ibutton_scene_read.h b/applications/ibutton/scene/ibutton_scene_read.h index 0b9e9e80..b9fefb0c 100644 --- a/applications/ibutton/scene/ibutton_scene_read.h +++ b/applications/ibutton/scene/ibutton_scene_read.h @@ -6,6 +6,4 @@ public: void on_enter(iButtonApp* app) final; bool on_event(iButtonApp* app, iButtonEvent* event) final; void on_exit(iButtonApp* app) final; - -private: }; \ No newline at end of file diff --git a/applications/ibutton/scene/ibutton_scene_read_crc_error.cpp b/applications/ibutton/scene/ibutton_scene_read_crc_error.cpp index a52495ea..9d67e442 100644 --- a/applications/ibutton/scene/ibutton_scene_read_crc_error.cpp +++ b/applications/ibutton/scene/ibutton_scene_read_crc_error.cpp @@ -1,16 +1,21 @@ #include "ibutton_scene_read_crc_error.h" #include "../ibutton_app.h" -#include "../ibutton_view_manager.h" -#include "../ibutton_event.h" -#include +#include + +static void dialog_ex_callback(DialogExResult result, void* context) { + iButtonApp* app = static_cast(context); + iButtonEvent event; + + event.type = iButtonEvent::Type::EventTypeDialogResult; + event.payload.dialog_result = result; + + app->get_view_manager()->send_event(&event); +} void iButtonSceneReadCRCError::on_enter(iButtonApp* app) { iButtonAppViewManager* view_manager = app->get_view_manager(); DialogEx* dialog_ex = view_manager->get_dialog_ex(); - auto callback = cbc::obtain_connector(this, &iButtonSceneReadCRCError::dialog_ex_callback); - - iButtonKey* key = app->get_key(); - uint8_t* key_data = key->get_data(); + const uint8_t* key_data = ibutton_key_get_data_p(app->get_key()); app->set_text_store( "%02X %02X %02X %02X %02X %02X %02X %02X\nExpected CRC: %X", @@ -22,13 +27,13 @@ void iButtonSceneReadCRCError::on_enter(iButtonApp* app) { key_data[5], key_data[6], key_data[7], - maxim_crc8(key_data, 7)); + maxim_crc8(key_data, 7, MAXIM_CRC8_INIT)); dialog_ex_set_header(dialog_ex, "CRC ERROR", 64, 10, AlignCenter, AlignCenter); dialog_ex_set_text(dialog_ex, app->get_text_store(), 64, 19, AlignCenter, AlignTop); dialog_ex_set_left_button_text(dialog_ex, "Retry"); dialog_ex_set_right_button_text(dialog_ex, "More"); - dialog_ex_set_result_callback(dialog_ex, callback); + dialog_ex_set_result_callback(dialog_ex, dialog_ex_callback); dialog_ex_set_context(dialog_ex, app); view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewDialogEx); @@ -65,14 +70,4 @@ void iButtonSceneReadCRCError::on_exit(iButtonApp* app) { dialog_ex_set_context(dialog_ex, NULL); app->notify_red_off(); -} - -void iButtonSceneReadCRCError::dialog_ex_callback(DialogExResult result, void* context) { - iButtonApp* app = static_cast(context); - iButtonEvent event; - - event.type = iButtonEvent::Type::EventTypeDialogResult; - event.payload.dialog_result = result; - - app->get_view_manager()->send_event(&event); } \ No newline at end of file diff --git a/applications/ibutton/scene/ibutton_scene_read_crc_error.h b/applications/ibutton/scene/ibutton_scene_read_crc_error.h index f64adc2c..43a4dfac 100644 --- a/applications/ibutton/scene/ibutton_scene_read_crc_error.h +++ b/applications/ibutton/scene/ibutton_scene_read_crc_error.h @@ -1,13 +1,9 @@ #pragma once #include "ibutton_scene_generic.h" -#include class iButtonSceneReadCRCError : public iButtonScene { public: void on_enter(iButtonApp* app) final; bool on_event(iButtonApp* app, iButtonEvent* event) final; void on_exit(iButtonApp* app) final; - -private: - void dialog_ex_callback(DialogExResult result, void* context); }; \ No newline at end of file diff --git a/applications/ibutton/scene/ibutton_scene_read_not_key_error.cpp b/applications/ibutton/scene/ibutton_scene_read_not_key_error.cpp index b9704bed..fab3c3f2 100644 --- a/applications/ibutton/scene/ibutton_scene_read_not_key_error.cpp +++ b/applications/ibutton/scene/ibutton_scene_read_not_key_error.cpp @@ -1,16 +1,21 @@ #include "ibutton_scene_read_not_key_error.h" #include "../ibutton_app.h" -#include "../ibutton_view_manager.h" -#include "../ibutton_event.h" -#include +#include + +static void dialog_ex_callback(DialogExResult result, void* context) { + iButtonApp* app = static_cast(context); + iButtonEvent event; + + event.type = iButtonEvent::Type::EventTypeDialogResult; + event.payload.dialog_result = result; + + app->get_view_manager()->send_event(&event); +} void iButtonSceneReadNotKeyError::on_enter(iButtonApp* app) { iButtonAppViewManager* view_manager = app->get_view_manager(); DialogEx* dialog_ex = view_manager->get_dialog_ex(); - auto callback = cbc::obtain_connector(this, &iButtonSceneReadNotKeyError::dialog_ex_callback); - - iButtonKey* key = app->get_key(); - uint8_t* key_data = key->get_data(); + const uint8_t* key_data = ibutton_key_get_data_p(app->get_key()); app->set_text_store( "THIS IS NOT A KEY\n%02X %02X %02X %02X %02X %02X %02X %02X", @@ -22,13 +27,13 @@ void iButtonSceneReadNotKeyError::on_enter(iButtonApp* app) { key_data[5], key_data[6], key_data[7], - maxim_crc8(key_data, 7)); + maxim_crc8(key_data, 7, MAXIM_CRC8_INIT)); dialog_ex_set_header(dialog_ex, "ERROR:", 64, 10, AlignCenter, AlignCenter); dialog_ex_set_text(dialog_ex, app->get_text_store(), 64, 19, AlignCenter, AlignTop); dialog_ex_set_left_button_text(dialog_ex, "Retry"); dialog_ex_set_right_button_text(dialog_ex, "More"); - dialog_ex_set_result_callback(dialog_ex, callback); + dialog_ex_set_result_callback(dialog_ex, dialog_ex_callback); dialog_ex_set_context(dialog_ex, app); view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewDialogEx); @@ -65,14 +70,4 @@ void iButtonSceneReadNotKeyError::on_exit(iButtonApp* app) { dialog_ex_set_context(dialog_ex, NULL); app->notify_red_off(); -} - -void iButtonSceneReadNotKeyError::dialog_ex_callback(DialogExResult result, void* context) { - iButtonApp* app = static_cast(context); - iButtonEvent event; - - event.type = iButtonEvent::Type::EventTypeDialogResult; - event.payload.dialog_result = result; - - app->get_view_manager()->send_event(&event); } \ No newline at end of file diff --git a/applications/ibutton/scene/ibutton_scene_read_not_key_error.h b/applications/ibutton/scene/ibutton_scene_read_not_key_error.h index a9a0112a..6643a206 100644 --- a/applications/ibutton/scene/ibutton_scene_read_not_key_error.h +++ b/applications/ibutton/scene/ibutton_scene_read_not_key_error.h @@ -1,13 +1,9 @@ #pragma once #include "ibutton_scene_generic.h" -#include class iButtonSceneReadNotKeyError : public iButtonScene { public: void on_enter(iButtonApp* app) final; bool on_event(iButtonApp* app, iButtonEvent* event) final; void on_exit(iButtonApp* app) final; - -private: - void dialog_ex_callback(DialogExResult result, void* context); }; \ No newline at end of file diff --git a/applications/ibutton/scene/ibutton_scene_read_success.cpp b/applications/ibutton/scene/ibutton_scene_read_success.cpp index afeb154f..818f7e38 100644 --- a/applications/ibutton/scene/ibutton_scene_read_success.cpp +++ b/applications/ibutton/scene/ibutton_scene_read_success.cpp @@ -1,21 +1,26 @@ #include "ibutton_scene_read_success.h" #include "../ibutton_app.h" -#include "../ibutton_view_manager.h" -#include "../ibutton_event.h" #include -#include + +static void dialog_ex_callback(DialogExResult result, void* context) { + iButtonApp* app = static_cast(context); + iButtonEvent event; + + event.type = iButtonEvent::Type::EventTypeDialogResult; + event.payload.dialog_result = result; + + app->get_view_manager()->send_event(&event); +} void iButtonSceneReadSuccess::on_enter(iButtonApp* app) { iButtonAppViewManager* view_manager = app->get_view_manager(); DialogEx* dialog_ex = view_manager->get_dialog_ex(); - auto callback = cbc::obtain_connector(this, &iButtonSceneReadSuccess::dialog_ex_callback); + iButtonKey* key = app->get_key(); + const uint8_t* key_data = ibutton_key_get_data_p(key); DOLPHIN_DEED(DolphinDeedIbuttonReadSuccess); - iButtonKey* key = app->get_key(); - uint8_t* key_data = key->get_data(); - - switch(key->get_key_type()) { - case iButtonKeyType::KeyDallas: + switch(ibutton_key_get_type(key)) { + case iButtonKeyDS1990: app->set_text_store( "Dallas\n%02X %02X %02X %02X\n%02X %02X %02X %02X", key_data[0], @@ -27,10 +32,10 @@ void iButtonSceneReadSuccess::on_enter(iButtonApp* app) { key_data[6], key_data[7]); break; - case iButtonKeyType::KeyCyfral: + case iButtonKeyCyfral: app->set_text_store("Cyfral\n%02X %02X", key_data[0], key_data[1]); break; - case iButtonKeyType::KeyMetakom: + case iButtonKeyMetakom: app->set_text_store( "Metakom\n%02X %02X %02X %02X", key_data[0], key_data[1], key_data[2], key_data[3]); break; @@ -40,7 +45,7 @@ void iButtonSceneReadSuccess::on_enter(iButtonApp* app) { dialog_ex_set_left_button_text(dialog_ex, "Retry"); dialog_ex_set_right_button_text(dialog_ex, "More"); dialog_ex_set_icon(dialog_ex, 0, 1, &I_DolphinExcited_64x63); - dialog_ex_set_result_callback(dialog_ex, callback); + dialog_ex_set_result_callback(dialog_ex, dialog_ex_callback); dialog_ex_set_context(dialog_ex, app); view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewDialogEx); @@ -80,13 +85,3 @@ void iButtonSceneReadSuccess::on_exit(iButtonApp* app) { app->notify_green_off(); } - -void iButtonSceneReadSuccess::dialog_ex_callback(DialogExResult result, void* context) { - iButtonApp* app = static_cast(context); - iButtonEvent event; - - event.type = iButtonEvent::Type::EventTypeDialogResult; - event.payload.dialog_result = result; - - app->get_view_manager()->send_event(&event); -} diff --git a/applications/ibutton/scene/ibutton_scene_read_success.h b/applications/ibutton/scene/ibutton_scene_read_success.h index d60dba40..9548d6b4 100644 --- a/applications/ibutton/scene/ibutton_scene_read_success.h +++ b/applications/ibutton/scene/ibutton_scene_read_success.h @@ -1,13 +1,9 @@ #pragma once #include "ibutton_scene_generic.h" -#include class iButtonSceneReadSuccess : public iButtonScene { public: void on_enter(iButtonApp* app) final; bool on_event(iButtonApp* app, iButtonEvent* event) final; void on_exit(iButtonApp* app) final; - -private: - void dialog_ex_callback(DialogExResult result, void* context); }; \ No newline at end of file diff --git a/applications/ibutton/scene/ibutton_scene_readed_key_menu.cpp b/applications/ibutton/scene/ibutton_scene_readed_key_menu.cpp index c2a9ff0a..63af10ad 100644 --- a/applications/ibutton/scene/ibutton_scene_readed_key_menu.cpp +++ b/applications/ibutton/scene/ibutton_scene_readed_key_menu.cpp @@ -1,8 +1,5 @@ #include "ibutton_scene_readed_key_menu.h" #include "../ibutton_app.h" -#include "../ibutton_view_manager.h" -#include "../ibutton_event.h" -#include typedef enum { SubmenuIndexWrite, @@ -11,17 +8,26 @@ typedef enum { SubmenuIndexReadNewKey, } SubmenuIndex; +static void submenu_callback(void* context, uint32_t index) { + iButtonApp* app = static_cast(context); + iButtonEvent event; + + event.type = iButtonEvent::Type::EventTypeMenuSelected; + event.payload.menu_index = index; + + app->get_view_manager()->send_event(&event); +} + void iButtonSceneReadedKeyMenu::on_enter(iButtonApp* app) { iButtonAppViewManager* view_manager = app->get_view_manager(); Submenu* submenu = view_manager->get_submenu(); - auto callback = cbc::obtain_connector(this, &iButtonSceneReadedKeyMenu::submenu_callback); - if(app->get_key()->get_key_type() == iButtonKeyType::KeyDallas) { - submenu_add_item(submenu, "Write", SubmenuIndexWrite, callback, app); + if(ibutton_key_get_type(app->get_key()) == iButtonKeyDS1990) { + submenu_add_item(submenu, "Write", SubmenuIndexWrite, submenu_callback, app); } - submenu_add_item(submenu, "Name and save", SubmenuIndexNameAndSave, callback, app); - submenu_add_item(submenu, "Emulate", SubmenuIndexEmulate, callback, app); - submenu_add_item(submenu, "Read new key", SubmenuIndexReadNewKey, callback, app); + submenu_add_item(submenu, "Name and save", SubmenuIndexNameAndSave, submenu_callback, app); + submenu_add_item(submenu, "Emulate", SubmenuIndexEmulate, submenu_callback, app); + submenu_add_item(submenu, "Read new key", SubmenuIndexReadNewKey, submenu_callback, app); submenu_set_selected_item(submenu, submenu_item_selected); view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewSubmenu); @@ -60,14 +66,4 @@ void iButtonSceneReadedKeyMenu::on_exit(iButtonApp* app) { Submenu* submenu = view->get_submenu(); submenu_reset(submenu); -} - -void iButtonSceneReadedKeyMenu::submenu_callback(void* context, uint32_t index) { - iButtonApp* app = static_cast(context); - iButtonEvent event; - - event.type = iButtonEvent::Type::EventTypeMenuSelected; - event.payload.menu_index = index; - - app->get_view_manager()->send_event(&event); -} +} \ No newline at end of file diff --git a/applications/ibutton/scene/ibutton_scene_readed_key_menu.h b/applications/ibutton/scene/ibutton_scene_readed_key_menu.h index fb00111d..caa9ad43 100644 --- a/applications/ibutton/scene/ibutton_scene_readed_key_menu.h +++ b/applications/ibutton/scene/ibutton_scene_readed_key_menu.h @@ -8,6 +8,5 @@ public: void on_exit(iButtonApp* app) final; private: - void submenu_callback(void* context, uint32_t index); uint32_t submenu_item_selected = 0; }; \ No newline at end of file diff --git a/applications/ibutton/scene/ibutton_scene_save_name.cpp b/applications/ibutton/scene/ibutton_scene_save_name.cpp index 0d5c5900..bde6133d 100644 --- a/applications/ibutton/scene/ibutton_scene_save_name.cpp +++ b/applications/ibutton/scene/ibutton_scene_save_name.cpp @@ -1,18 +1,21 @@ #include "ibutton_scene_save_name.h" #include "../ibutton_app.h" -#include "../ibutton_view_manager.h" -#include "../ibutton_event.h" -#include "../ibutton_key.h" -#include #include +static void text_input_callback(void* context) { + iButtonApp* app = static_cast(context); + iButtonEvent event; + + event.type = iButtonEvent::Type::EventTypeTextEditResult; + + app->get_view_manager()->send_event(&event); +} + void iButtonSceneSaveName::on_enter(iButtonApp* app) { iButtonAppViewManager* view_manager = app->get_view_manager(); TextInput* text_input = view_manager->get_text_input(); - auto callback = cbc::obtain_connector(this, &iButtonSceneSaveName::text_input_callback); - iButtonKey* key = app->get_key(); - const char* key_name = key->get_name(); + const char* key_name = ibutton_key_get_name_p(app->get_key()); bool key_name_empty = !strcmp(key_name, ""); if(key_name_empty) { @@ -23,7 +26,12 @@ void iButtonSceneSaveName::on_enter(iButtonApp* app) { text_input_set_header_text(text_input, "Name the key"); text_input_set_result_callback( - text_input, callback, app, app->get_text_store(), IBUTTON_KEY_NAME_SIZE, key_name_empty); + text_input, + text_input_callback, + app, + app->get_text_store(), + IBUTTON_KEY_NAME_SIZE, + key_name_empty); ValidatorIsFile* validator_is_file = validator_is_file_alloc_init(app->app_folder, app->app_extension); @@ -59,12 +67,3 @@ void iButtonSceneSaveName::on_exit(iButtonApp* app) { text_input_reset(text_input); } - -void iButtonSceneSaveName::text_input_callback(void* context) { - iButtonApp* app = static_cast(context); - iButtonEvent event; - - event.type = iButtonEvent::Type::EventTypeTextEditResult; - - app->get_view_manager()->send_event(&event); -} diff --git a/applications/ibutton/scene/ibutton_scene_save_name.h b/applications/ibutton/scene/ibutton_scene_save_name.h index f0dafb2e..8be593da 100644 --- a/applications/ibutton/scene/ibutton_scene_save_name.h +++ b/applications/ibutton/scene/ibutton_scene_save_name.h @@ -6,7 +6,4 @@ public: void on_enter(iButtonApp* app) final; bool on_event(iButtonApp* app, iButtonEvent* event) final; void on_exit(iButtonApp* app) final; - -private: - void text_input_callback(void* context); }; \ No newline at end of file diff --git a/applications/ibutton/scene/ibutton_scene_save_success.cpp b/applications/ibutton/scene/ibutton_scene_save_success.cpp index c652e5d1..891b020a 100644 --- a/applications/ibutton/scene/ibutton_scene_save_success.cpp +++ b/applications/ibutton/scene/ibutton_scene_save_success.cpp @@ -1,21 +1,23 @@ #include "ibutton_scene_save_success.h" #include "../ibutton_app.h" -#include "../ibutton_view_manager.h" -#include "../ibutton_event.h" -#include "../ibutton_key.h" #include -#include + +static void popup_callback(void* context) { + iButtonApp* app = static_cast(context); + iButtonEvent event; + event.type = iButtonEvent::Type::EventTypeBack; + app->get_view_manager()->send_event(&event); +} void iButtonSceneSaveSuccess::on_enter(iButtonApp* app) { iButtonAppViewManager* view_manager = app->get_view_manager(); Popup* popup = view_manager->get_popup(); - auto callback = cbc::obtain_connector(this, &iButtonSceneSaveSuccess::popup_callback); DOLPHIN_DEED(DolphinDeedIbuttonSave); popup_set_icon(popup, 32, 5, &I_DolphinNice_96x59); popup_set_text(popup, "Saved!", 13, 22, AlignLeft, AlignBottom); - popup_set_callback(popup, callback); + popup_set_callback(popup, popup_callback); popup_set_context(popup, app); popup_set_timeout(popup, 1500); popup_enable_timeout(popup); @@ -46,11 +48,4 @@ void iButtonSceneSaveSuccess::on_exit(iButtonApp* app) { popup_disable_timeout(popup); popup_set_context(popup, NULL); popup_set_callback(popup, NULL); -} - -void iButtonSceneSaveSuccess::popup_callback(void* context) { - iButtonApp* app = static_cast(context); - iButtonEvent event; - event.type = iButtonEvent::Type::EventTypeBack; - app->get_view_manager()->send_event(&event); -} +} \ No newline at end of file diff --git a/applications/ibutton/scene/ibutton_scene_save_success.h b/applications/ibutton/scene/ibutton_scene_save_success.h index 3f784696..95742bda 100644 --- a/applications/ibutton/scene/ibutton_scene_save_success.h +++ b/applications/ibutton/scene/ibutton_scene_save_success.h @@ -6,7 +6,4 @@ public: void on_enter(iButtonApp* app) final; bool on_event(iButtonApp* app, iButtonEvent* event) final; void on_exit(iButtonApp* app) final; - -private: - void popup_callback(void* context); }; \ No newline at end of file diff --git a/applications/ibutton/scene/ibutton_scene_saved_key_menu.cpp b/applications/ibutton/scene/ibutton_scene_saved_key_menu.cpp index ee92284f..1d87e85f 100644 --- a/applications/ibutton/scene/ibutton_scene_saved_key_menu.cpp +++ b/applications/ibutton/scene/ibutton_scene_saved_key_menu.cpp @@ -1,7 +1,5 @@ #include "ibutton_scene_saved_key_menu.h" #include "../ibutton_app.h" -#include "../ibutton_view_manager.h" -#include "../ibutton_event.h" #include typedef enum { @@ -12,18 +10,27 @@ typedef enum { SubmenuIndexInfo, } SubmenuIndex; +static void submenu_callback(void* context, uint32_t index) { + iButtonApp* app = static_cast(context); + iButtonEvent event; + + event.type = iButtonEvent::Type::EventTypeMenuSelected; + event.payload.menu_index = index; + + app->get_view_manager()->send_event(&event); +} + void iButtonSceneSavedKeyMenu::on_enter(iButtonApp* app) { iButtonAppViewManager* view_manager = app->get_view_manager(); Submenu* submenu = view_manager->get_submenu(); - auto callback = cbc::obtain_connector(this, &iButtonSceneSavedKeyMenu::submenu_callback); - submenu_add_item(submenu, "Emulate", SubmenuIndexEmulate, callback, app); - if(app->get_key()->get_key_type() == iButtonKeyType::KeyDallas) { - submenu_add_item(submenu, "Write", SubmenuIndexWrite, callback, app); + submenu_add_item(submenu, "Emulate", SubmenuIndexEmulate, submenu_callback, app); + if(ibutton_key_get_type(app->get_key()) == iButtonKeyDS1990) { + submenu_add_item(submenu, "Write", SubmenuIndexWrite, submenu_callback, app); } - submenu_add_item(submenu, "Edit", SubmenuIndexEdit, callback, app); - submenu_add_item(submenu, "Delete", SubmenuIndexDelete, callback, app); - submenu_add_item(submenu, "Info", SubmenuIndexInfo, callback, app); + submenu_add_item(submenu, "Edit", SubmenuIndexEdit, submenu_callback, app); + submenu_add_item(submenu, "Delete", SubmenuIndexDelete, submenu_callback, app); + submenu_add_item(submenu, "Info", SubmenuIndexInfo, submenu_callback, app); submenu_set_selected_item(submenu, submenu_item_selected); view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewSubmenu); @@ -63,13 +70,3 @@ void iButtonSceneSavedKeyMenu::on_exit(iButtonApp* app) { submenu_reset(submenu); } - -void iButtonSceneSavedKeyMenu::submenu_callback(void* context, uint32_t index) { - iButtonApp* app = static_cast(context); - iButtonEvent event; - - event.type = iButtonEvent::Type::EventTypeMenuSelected; - event.payload.menu_index = index; - - app->get_view_manager()->send_event(&event); -} diff --git a/applications/ibutton/scene/ibutton_scene_saved_key_menu.h b/applications/ibutton/scene/ibutton_scene_saved_key_menu.h index 461030d1..399ed1ce 100644 --- a/applications/ibutton/scene/ibutton_scene_saved_key_menu.h +++ b/applications/ibutton/scene/ibutton_scene_saved_key_menu.h @@ -8,6 +8,5 @@ public: void on_exit(iButtonApp* app) final; private: - void submenu_callback(void* context, uint32_t index); uint32_t submenu_item_selected = 0; }; \ No newline at end of file diff --git a/applications/ibutton/scene/ibutton_scene_select_key.cpp b/applications/ibutton/scene/ibutton_scene_select_key.cpp index a4739852..1f1ece35 100644 --- a/applications/ibutton/scene/ibutton_scene_select_key.cpp +++ b/applications/ibutton/scene/ibutton_scene_select_key.cpp @@ -1,7 +1,5 @@ #include "ibutton_scene_select_key.h" #include "../ibutton_app.h" -#include "../ibutton_event.h" -#include "../ibutton_key.h" void iButtonSceneSelectKey::on_enter(iButtonApp* app) { // Process file_select return diff --git a/applications/ibutton/scene/ibutton_scene_start.cpp b/applications/ibutton/scene/ibutton_scene_start.cpp index 9d064aad..2dbe9878 100644 --- a/applications/ibutton/scene/ibutton_scene_start.cpp +++ b/applications/ibutton/scene/ibutton_scene_start.cpp @@ -1,8 +1,5 @@ #include "ibutton_scene_start.h" #include "../ibutton_app.h" -#include "../ibutton_view_manager.h" -#include "../ibutton_event.h" -#include typedef enum { SubmenuIndexRead, @@ -10,14 +7,23 @@ typedef enum { SubmenuIndexAdd, } SubmenuIndex; +static void submenu_callback(void* context, uint32_t index) { + iButtonApp* app = static_cast(context); + iButtonEvent event; + + event.type = iButtonEvent::Type::EventTypeMenuSelected; + event.payload.menu_index = index; + + app->get_view_manager()->send_event(&event); +} + void iButtonSceneStart::on_enter(iButtonApp* app) { iButtonAppViewManager* view_manager = app->get_view_manager(); Submenu* submenu = view_manager->get_submenu(); - auto callback = cbc::obtain_connector(this, &iButtonSceneStart::submenu_callback); - submenu_add_item(submenu, "Read", SubmenuIndexRead, callback, app); - submenu_add_item(submenu, "Saved", SubmenuIndexSaved, callback, app); - submenu_add_item(submenu, "Add manually", SubmenuIndexAdd, callback, app); + submenu_add_item(submenu, "Read", SubmenuIndexRead, submenu_callback, app); + submenu_add_item(submenu, "Saved", SubmenuIndexSaved, submenu_callback, app); + submenu_add_item(submenu, "Add manually", SubmenuIndexAdd, submenu_callback, app); submenu_set_selected_item(submenu, submenu_item_selected); view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewSubmenu); @@ -51,13 +57,3 @@ void iButtonSceneStart::on_exit(iButtonApp* app) { submenu_reset(submenu); } - -void iButtonSceneStart::submenu_callback(void* context, uint32_t index) { - iButtonApp* app = static_cast(context); - iButtonEvent event; - - event.type = iButtonEvent::Type::EventTypeMenuSelected; - event.payload.menu_index = index; - - app->get_view_manager()->send_event(&event); -} diff --git a/applications/ibutton/scene/ibutton_scene_start.h b/applications/ibutton/scene/ibutton_scene_start.h index 2ce9bb43..be1ce79f 100644 --- a/applications/ibutton/scene/ibutton_scene_start.h +++ b/applications/ibutton/scene/ibutton_scene_start.h @@ -8,6 +8,5 @@ public: void on_exit(iButtonApp* app) final; private: - void submenu_callback(void* context, uint32_t index); uint32_t submenu_item_selected = 0; }; \ No newline at end of file diff --git a/applications/ibutton/scene/ibutton_scene_write.cpp b/applications/ibutton/scene/ibutton_scene_write.cpp index 6afb034e..af86a148 100644 --- a/applications/ibutton/scene/ibutton_scene_write.cpp +++ b/applications/ibutton/scene/ibutton_scene_write.cpp @@ -1,15 +1,22 @@ #include "ibutton_scene_write.h" #include "../ibutton_app.h" -#include "../ibutton_view_manager.h" -#include "../ibutton_event.h" -#include "../ibutton_key.h" + +static void ibutton_worker_write_cb(void* context, iButtonWorkerWriteResult result) { + iButtonApp* app = static_cast(context); + iButtonEvent event; + event.type = iButtonEvent::Type::EventTypeWorkerWrite; + event.payload.worker_write_result = result; + + app->get_view_manager()->send_event(&event); +} void iButtonSceneWrite::on_enter(iButtonApp* app) { iButtonAppViewManager* view_manager = app->get_view_manager(); Popup* popup = view_manager->get_popup(); iButtonKey* key = app->get_key(); - uint8_t* key_data = key->get_data(); - const char* key_name = key->get_name(); + iButtonWorker* worker = app->get_key_worker(); + const uint8_t* key_data = ibutton_key_get_data_p(key); + const char* key_name = ibutton_key_get_name_p(key); uint8_t line_count = 2; // check that stored key has name @@ -18,8 +25,8 @@ void iButtonSceneWrite::on_enter(iButtonApp* app) { line_count = 2; } else { // if not, show key data - switch(key->get_key_type()) { - case iButtonKeyType::KeyDallas: + switch(ibutton_key_get_type(key)) { + case iButtonKeyDS1990: app->set_text_store( "writing\n%02X %02X %02X %02X\n%02X %02X %02X %02X", key_data[0], @@ -32,11 +39,11 @@ void iButtonSceneWrite::on_enter(iButtonApp* app) { key_data[7]); line_count = 3; break; - case iButtonKeyType::KeyCyfral: + case iButtonKeyCyfral: app->set_text_store("writing\n%02X %02X", key_data[0], key_data[1]); line_count = 2; break; - case iButtonKeyType::KeyMetakom: + case iButtonKeyMetakom: app->set_text_store( "writing\n%02X %02X %02X %02X", key_data[0], key_data[1], key_data[2], key_data[3]); line_count = 2; @@ -60,27 +67,34 @@ void iButtonSceneWrite::on_enter(iButtonApp* app) { view_manager->switch_to(iButtonAppViewManager::Type::iButtonAppViewPopup); - app->get_key_worker()->start_write(); + blink_yellow = false; + ibutton_worker_write_set_callback(worker, ibutton_worker_write_cb, app); + ibutton_worker_write_start(worker, key); } bool iButtonSceneWrite::on_event(iButtonApp* app, iButtonEvent* event) { bool consumed = false; - if(event->type == iButtonEvent::Type::EventTypeTick) { + if(event->type == iButtonEvent::Type::EventTypeWorkerWrite) { consumed = true; - KeyWriter::Error result = app->get_key_worker()->write(app->get_key()); - switch(result) { - case KeyWriter::Error::SAME_KEY: - case KeyWriter::Error::OK: + switch(event->payload.worker_write_result) { + case iButtonWorkerWriteOK: + case iButtonWorkerWriteSameKey: app->switch_to_next_scene(iButtonApp::Scene::SceneWriteSuccess); break; - case KeyWriter::Error::NO_DETECT: - app->notify_red_blink(); + case iButtonWorkerWriteNoDetect: + blink_yellow = false; break; - case KeyWriter::Error::CANNOT_WRITE: + case iButtonWorkerWriteCannotWrite: + blink_yellow = true; + break; + } + } else if(event->type == iButtonEvent::Type::EventTypeTick) { + if(blink_yellow) { app->notify_yellow_blink(); - break; + } else { + app->notify_red_blink(); } } @@ -89,10 +103,8 @@ bool iButtonSceneWrite::on_event(iButtonApp* app, iButtonEvent* event) { void iButtonSceneWrite::on_exit(iButtonApp* app) { Popup* popup = app->get_view_manager()->get_popup(); - + ibutton_worker_stop(app->get_key_worker()); popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom); popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop); popup_set_icon(popup, 0, 0, NULL); - - app->get_key_worker()->stop_write(); } \ No newline at end of file diff --git a/applications/ibutton/scene/ibutton_scene_write.h b/applications/ibutton/scene/ibutton_scene_write.h index 98fac375..bd99b377 100644 --- a/applications/ibutton/scene/ibutton_scene_write.h +++ b/applications/ibutton/scene/ibutton_scene_write.h @@ -8,4 +8,5 @@ public: void on_exit(iButtonApp* app) final; private: + bool blink_yellow; }; \ No newline at end of file diff --git a/applications/ibutton/scene/ibutton_scene_write_success.cpp b/applications/ibutton/scene/ibutton_scene_write_success.cpp index 270ad52e..48acaaa4 100644 --- a/applications/ibutton/scene/ibutton_scene_write_success.cpp +++ b/applications/ibutton/scene/ibutton_scene_write_success.cpp @@ -1,19 +1,22 @@ #include "ibutton_scene_write_success.h" #include "../ibutton_app.h" -#include "../ibutton_view_manager.h" -#include "../ibutton_event.h" -#include "../ibutton_key.h" -#include + +static void popup_callback(void* context) { + iButtonApp* app = static_cast(context); + iButtonEvent event; + event.type = iButtonEvent::Type::EventTypeBack; + app->get_view_manager()->send_event(&event); + app->notify_green_off(); +} void iButtonSceneWriteSuccess::on_enter(iButtonApp* app) { iButtonAppViewManager* view_manager = app->get_view_manager(); Popup* popup = view_manager->get_popup(); - auto callback = cbc::obtain_connector(this, &iButtonSceneWriteSuccess::popup_callback); popup_set_icon(popup, 0, 12, &I_iButtonDolphinVerySuccess_108x52); popup_set_text(popup, "Successfully written!", 40, 12, AlignLeft, AlignBottom); - popup_set_callback(popup, callback); + popup_set_callback(popup, popup_callback); popup_set_context(popup, app); popup_set_timeout(popup, 1500); popup_enable_timeout(popup); @@ -45,12 +48,4 @@ void iButtonSceneWriteSuccess::on_exit(iButtonApp* app) { popup_disable_timeout(popup); popup_set_context(popup, NULL); popup_set_callback(popup, NULL); -} - -void iButtonSceneWriteSuccess::popup_callback(void* context) { - iButtonApp* app = static_cast(context); - iButtonEvent event; - event.type = iButtonEvent::Type::EventTypeBack; - app->get_view_manager()->send_event(&event); - app->notify_green_off(); } \ No newline at end of file diff --git a/applications/ibutton/scene/ibutton_scene_write_success.h b/applications/ibutton/scene/ibutton_scene_write_success.h index 693c4353..c6e76885 100644 --- a/applications/ibutton/scene/ibutton_scene_write_success.h +++ b/applications/ibutton/scene/ibutton_scene_write_success.h @@ -6,7 +6,4 @@ public: void on_enter(iButtonApp* app) final; bool on_event(iButtonApp* app, iButtonEvent* event) final; void on_exit(iButtonApp* app) final; - -private: - void popup_callback(void* context); }; \ No newline at end of file diff --git a/applications/infrared/cli/infrared_cli.cpp b/applications/infrared/cli/infrared_cli.cpp index 0613ca51..8cda0cd7 100644 --- a/applications/infrared/cli/infrared_cli.cpp +++ b/applications/infrared/cli/infrared_cli.cpp @@ -66,7 +66,7 @@ static void infrared_cli_start_ir_rx(Cli* cli, string_t args) { printf("Receiving INFRARED...\r\nPress Ctrl+C to abort\r\n"); while(!cli_cmd_interrupt_received(cli)) { - delay(50); + furi_hal_delay_ms(50); } infrared_worker_rx_stop(worker); diff --git a/applications/infrared/scene/infrared_app_scene_learn.cpp b/applications/infrared/scene/infrared_app_scene_learn.cpp index 1ae3b92c..5ad783e7 100644 --- a/applications/infrared/scene/infrared_app_scene_learn.cpp +++ b/applications/infrared/scene/infrared_app_scene_learn.cpp @@ -37,6 +37,7 @@ void InfraredAppSceneLearn::on_enter(InfraredApp* app) { infrared_worker_rx_start(worker); popup_set_icon(popup, 0, 32, &I_InfraredLearnShort_128x31); + popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignCenter); popup_set_text( popup, "Point the remote at IR port\nand push the button", 5, 10, AlignLeft, AlignCenter); popup_set_callback(popup, NULL); diff --git a/applications/input/input.c b/applications/input/input.c index 46a9c369..a2dd62f7 100644 --- a/applications/input/input.c +++ b/applications/input/input.c @@ -1,8 +1,6 @@ #include "input_i.h" -#define GPIO_Read(input_pin) \ - (HAL_GPIO_ReadPin((GPIO_TypeDef*)input_pin.pin->port, input_pin.pin->pin) ^ \ - input_pin.pin->inverted) +#define GPIO_Read(input_pin) (furi_hal_gpio_read(input_pin.pin->gpio) ^ (input_pin.pin->inverted)) static Input* input = NULL; @@ -81,8 +79,7 @@ int32_t input_srv() { input->pin_states = malloc(input_pins_count * sizeof(InputPinState)); for(size_t i = 0; i < input_pins_count; i++) { - GpioPin gpio = {(GPIO_TypeDef*)input_pins[i].port, (uint16_t)input_pins[i].pin}; - hal_gpio_add_int_callback(&gpio, input_isr, NULL); + furi_hal_gpio_add_int_callback(input_pins[i].gpio, input_isr, NULL); input->pin_states[i].pin = &input_pins[i]; input->pin_states[i].state = GPIO_Read(input->pin_states[i]); input->pin_states[i].debounce = INPUT_DEBOUNCE_TICKS_HALF; diff --git a/applications/lfrfid/helpers/decoder_gpio_out.cpp b/applications/lfrfid/helpers/decoder_gpio_out.cpp index fec21bfe..03e03994 100644 --- a/applications/lfrfid/helpers/decoder_gpio_out.cpp +++ b/applications/lfrfid/helpers/decoder_gpio_out.cpp @@ -3,13 +3,13 @@ #include void DecoderGpioOut::process_front(bool polarity, uint32_t time) { - hal_gpio_write(&gpio_ext_pa7, polarity); + furi_hal_gpio_write(&gpio_ext_pa7, polarity); } DecoderGpioOut::DecoderGpioOut() { - hal_gpio_init_simple(&gpio_ext_pa7, GpioModeOutputPushPull); + furi_hal_gpio_init_simple(&gpio_ext_pa7, GpioModeOutputPushPull); } DecoderGpioOut::~DecoderGpioOut() { - hal_gpio_init_simple(&gpio_ext_pa7, GpioModeAnalog); + furi_hal_gpio_init_simple(&gpio_ext_pa7, GpioModeAnalog); } diff --git a/applications/lfrfid/helpers/rfid_writer.cpp b/applications/lfrfid/helpers/rfid_writer.cpp index 49d91a20..996cb36a 100644 --- a/applications/lfrfid/helpers/rfid_writer.cpp +++ b/applications/lfrfid/helpers/rfid_writer.cpp @@ -48,15 +48,15 @@ void RfidWriter::stop() { void RfidWriter::write_gap(uint32_t gap_time) { furi_hal_rfid_tim_read_stop(); - delay_us(gap_time * 8); + furi_hal_delay_us(gap_time * 8); furi_hal_rfid_tim_read_start(); } void RfidWriter::write_bit(bool value) { if(value) { - delay_us(T55xxTiming::data_1 * 8); + furi_hal_delay_us(T55xxTiming::data_1 * 8); } else { - delay_us(T55xxTiming::data_0 * 8); + furi_hal_delay_us(T55xxTiming::data_0 * 8); } write_gap(T55xxTiming::write_gap); } @@ -68,7 +68,7 @@ void RfidWriter::write_byte(uint8_t value) { } void RfidWriter::write_block(uint8_t page, uint8_t block, bool lock_bit, uint32_t data) { - delay_us(T55xxTiming::wait_time * 8); + furi_hal_delay_us(T55xxTiming::wait_time * 8); // start gap write_gap(T55xxTiming::start_gap); @@ -101,9 +101,9 @@ void RfidWriter::write_block(uint8_t page, uint8_t block, bool lock_bit, uint32_ write_bit((block >> 1) & 1); write_bit((block >> 0) & 1); - delay_us(T55xxTiming::program * 8); + furi_hal_delay_us(T55xxTiming::program * 8); - delay_us(T55xxTiming::wait_time * 8); + furi_hal_delay_us(T55xxTiming::wait_time * 8); write_reset(); } diff --git a/applications/lfrfid/lfrfid_cli.cpp b/applications/lfrfid/lfrfid_cli.cpp index 79063ddd..18784876 100644 --- a/applications/lfrfid/lfrfid_cli.cpp +++ b/applications/lfrfid/lfrfid_cli.cpp @@ -88,7 +88,7 @@ void lfrfid_cli_read(Cli* cli, string_t args) { printf("\r\n"); break; } - delay(100); + furi_hal_delay_ms(100); } printf("Reading stopped\r\n"); @@ -136,7 +136,7 @@ void lfrfid_cli_emulate(Cli* cli, string_t args) { printf("Emulating RFID...\r\nPress Ctrl+C to abort\r\n"); while(!cli_cmd_interrupt_received(cli)) { - delay(100); + furi_hal_delay_ms(100); } printf("Emulation stopped\r\n"); emulator.stop(); diff --git a/applications/lfrfid_debug/scene/lfrfid_debug_app_scene_tune.cpp b/applications/lfrfid_debug/scene/lfrfid_debug_app_scene_tune.cpp index 682d436a..53679402 100644 --- a/applications/lfrfid_debug/scene/lfrfid_debug_app_scene_tune.cpp +++ b/applications/lfrfid_debug/scene/lfrfid_debug_app_scene_tune.cpp @@ -2,12 +2,12 @@ #include static void comparator_trigger_callback(bool level, void* comp_ctx) { - hal_gpio_write(&gpio_ext_pa7, !level); + furi_hal_gpio_write(&gpio_ext_pa7, !level); } void LfRfidDebugAppSceneTune::on_enter(LfRfidDebugApp* app, bool need_restore) { app->view_controller.switch_to(); - hal_gpio_init_simple(&gpio_ext_pa7, GpioModeOutputPushPull); + furi_hal_gpio_init_simple(&gpio_ext_pa7, GpioModeOutputPushPull); furi_hal_rfid_comp_set_callback(comparator_trigger_callback, this); furi_hal_rfid_comp_start(); @@ -34,7 +34,7 @@ void LfRfidDebugAppSceneTune::on_exit(LfRfidDebugApp* app) { furi_hal_rfid_comp_stop(); furi_hal_rfid_comp_set_callback(NULL, NULL); - hal_gpio_init_simple(&gpio_ext_pa7, GpioModeAnalog); + furi_hal_gpio_init_simple(&gpio_ext_pa7, GpioModeAnalog); furi_hal_rfid_tim_read_stop(); furi_hal_rfid_tim_reset(); furi_hal_rfid_pins_reset(); diff --git a/applications/loader/loader.c b/applications/loader/loader.c index 552b46f2..63eb3634 100644 --- a/applications/loader/loader.c +++ b/applications/loader/loader.c @@ -245,7 +245,7 @@ static void loader_thread_state_callback(FuriThreadState thread_state, void* con * started and after task completed. In process of leakage monitoring * both values should be taken into account. */ - delay(20); + furi_hal_delay_ms(20); int heap_diff = instance->free_heap_size - memmgr_get_free_heap(); FURI_LOG_I( TAG, diff --git a/applications/music_player/music_player.c b/applications/music_player/music_player.c index 8e1d6da9..4f8813d6 100644 --- a/applications/music_player/music_player.c +++ b/applications/music_player/music_player.c @@ -334,7 +334,7 @@ void process_note( if(note_record->note != N) { furi_hal_speaker_start(note_record->note, volume); } - delay(note_delay); + furi_hal_delay_ms(note_delay); furi_hal_speaker_stop(); } diff --git a/applications/nfc/nfc_worker.c b/applications/nfc/nfc_worker.c index 17b54260..a925a8d7 100644 --- a/applications/nfc/nfc_worker.c +++ b/applications/nfc/nfc_worker.c @@ -780,6 +780,7 @@ void nfc_worker_mifare_classic_dict_attack(NfcWorker* nfc_worker) { } } if(nfc_worker->state != NfcWorkerStateReadMifareClassic) break; + osDelay(1); } if(nfc_worker->state != NfcWorkerStateReadMifareClassic) break; if(sector_key_found) { diff --git a/applications/notification/notification_app.c b/applications/notification/notification_app.c index 6ecfaf90..d0594490 100644 --- a/applications/notification/notification_app.c +++ b/applications/notification/notification_app.c @@ -248,7 +248,7 @@ void notification_process_notification_message( if(led_active) { if(notification_is_any_led_layer_internal_and_not_empty(app)) { notification_apply_notification_leds(app, led_off_values); - delay(minimal_delay); + furi_hal_delay_ms(minimal_delay); } led_active = false; @@ -259,7 +259,7 @@ void notification_process_notification_message( reset_mask |= reset_blue_mask; } - delay(notification_message->data.delay.length); + furi_hal_delay_ms(notification_message->data.delay.length); break; case NotificationMessageTypeDoNotReset: reset_notifications = false; @@ -293,7 +293,7 @@ void notification_process_notification_message( if(need_minimal_delay) { notification_apply_notification_leds(app, led_off_values); - delay(minimal_delay); + furi_hal_delay_ms(minimal_delay); } } diff --git a/applications/storage/storage_test_app.c b/applications/storage/storage_test_app.c index 79569116..096276ad 100644 --- a/applications/storage/storage_test_app.c +++ b/applications/storage/storage_test_app.c @@ -334,7 +334,7 @@ int32_t storage_test_app(void* p) { do_test_end(api, "/ext"); while(true) { - delay(1000); + furi_hal_delay_ms(1000); } return 0; diff --git a/applications/storage/storages/storage_ext.c b/applications/storage/storages/storage_ext.c index 309ec1cf..1b76ef6c 100644 --- a/applications/storage/storages/storage_ext.c +++ b/applications/storage/storages/storage_ext.c @@ -82,7 +82,7 @@ static bool sd_mount_card(StorageData* storage, bool notify) { } if(!result) { - delay(1000); + furi_hal_delay_ms(1000); FURI_LOG_E( TAG, "init cycle %d, error: %s", counter, storage_data_status_text(storage)); counter--; diff --git a/applications/subghz/helpers/subghz_chat.c b/applications/subghz/helpers/subghz_chat.c index 75896958..30618813 100644 --- a/applications/subghz/helpers/subghz_chat.c +++ b/applications/subghz/helpers/subghz_chat.c @@ -42,11 +42,12 @@ static void subghz_chat_worker_update_rx_event_chat(void* context) { furi_assert(context); SubGhzChatWorker* instance = context; SubGhzChatEvent event; - if((millis() - instance->last_time_rx_data) > SUBGHZ_CHAT_WORKER_TIMEOUT_BETWEEN_MESSAGES) { + if((furi_hal_get_tick() - instance->last_time_rx_data) > + SUBGHZ_CHAT_WORKER_TIMEOUT_BETWEEN_MESSAGES) { event.event = SubGhzChatEventNewMessage; osMessageQueuePut(instance->event_queue, &event, 0, osWaitForever); } - instance->last_time_rx_data = millis(); + instance->last_time_rx_data = furi_hal_get_tick(); event.event = SubGhzChatEventRXData; osMessageQueuePut(instance->event_queue, &event, 0, osWaitForever); } diff --git a/applications/subghz/subghz_cli.c b/applications/subghz/subghz_cli.c index f9a85445..ad2f4031 100644 --- a/applications/subghz/subghz_cli.c +++ b/applications/subghz/subghz_cli.c @@ -40,8 +40,8 @@ void subghz_cli_command_tx_carrier(Cli* cli, string_t args, void* context) { furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async); frequency = furi_hal_subghz_set_frequency_and_path(frequency); - hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); - hal_gpio_write(&gpio_cc1101_g0, true); + furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_write(&gpio_cc1101_g0, true); furi_hal_power_suppress_charge_enter(); @@ -254,7 +254,7 @@ void subghz_cli_command_rx(Cli* cli, string_t args, void* context) { furi_hal_subghz_reset(); furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async); frequency = furi_hal_subghz_set_frequency_and_path(frequency); - hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); furi_hal_power_suppress_charge_enter(); @@ -495,7 +495,7 @@ static void subghz_cli_command_chat(Cli* cli, string_t args) { subghz_chat, (uint8_t*)string_get_cstr(input), strlen(string_get_cstr(input)))) { - delay(10); + furi_hal_delay_ms(10); } string_printf(input, "%s", string_get_cstr(name)); @@ -547,7 +547,7 @@ static void subghz_cli_command_chat(Cli* cli, string_t args) { subghz_chat, (uint8_t*)string_get_cstr(sysmsg), strlen(string_get_cstr(sysmsg))); - delay(10); + furi_hal_delay_ms(10); exit = true; break; default: diff --git a/applications/subghz/subghz_history.c b/applications/subghz/subghz_history.c index dc8d4fc6..cb30726b 100644 --- a/applications/subghz/subghz_history.c +++ b/applications/subghz/subghz_history.c @@ -140,13 +140,13 @@ bool subghz_history_add_to_history( SubGhzProtocolDecoderBase* decoder_base = context; if((instance->code_last_hash_data == subghz_protocol_decoder_base_get_hash_data(decoder_base)) && - ((millis() - instance->last_update_timestamp) < 500)) { - instance->last_update_timestamp = millis(); + ((furi_hal_get_tick() - instance->last_update_timestamp) < 500)) { + instance->last_update_timestamp = furi_hal_get_tick(); return false; } instance->code_last_hash_data = subghz_protocol_decoder_base_get_hash_data(decoder_base); - instance->last_update_timestamp = millis(); + instance->last_update_timestamp = furi_hal_get_tick(); string_t text; string_init(text); diff --git a/applications/subghz/subghz_i.c b/applications/subghz/subghz_i.c index 83ff2c8f..56ce7e97 100755 --- a/applications/subghz/subghz_i.c +++ b/applications/subghz/subghz_i.c @@ -62,7 +62,7 @@ void subghz_begin(SubGhz* subghz, FuriHalSubGhzPreset preset) { furi_hal_subghz_reset(); furi_hal_subghz_idle(); furi_hal_subghz_load_preset(preset); - hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); subghz->txrx->txrx_state = SubGhzTxRxStateIDLE; } @@ -77,7 +77,7 @@ uint32_t subghz_rx(SubGhz* subghz, uint32_t frequency) { furi_hal_subghz_idle(); uint32_t value = furi_hal_subghz_set_frequency_and_path(frequency); - hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); furi_hal_subghz_flush_rx(); furi_hal_subghz_rx(); @@ -95,8 +95,8 @@ static bool subghz_tx(SubGhz* subghz, uint32_t frequency) { furi_assert(subghz->txrx->txrx_state != SubGhzTxRxStateSleep); furi_hal_subghz_idle(); furi_hal_subghz_set_frequency_and_path(frequency); - hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); - hal_gpio_write(&gpio_cc1101_g0, true); + furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_write(&gpio_cc1101_g0, true); bool ret = furi_hal_subghz_tx(); subghz->txrx->txrx_state = SubGhzTxRxStateTx; return ret; diff --git a/applications/subghz/views/subghz_test_carrier.c b/applications/subghz/views/subghz_test_carrier.c index 6c0a8d16..cd2f70ec 100644 --- a/applications/subghz/views/subghz_test_carrier.c +++ b/applications/subghz/views/subghz_test_carrier.c @@ -113,13 +113,14 @@ bool subghz_test_carrier_input(InputEvent* event, void* context) { furi_hal_subghz_set_path(model->path); if(model->status == SubGhzTestCarrierModelStatusRx) { - hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); furi_hal_subghz_rx(); } else { - hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); - hal_gpio_write(&gpio_cc1101_g0, true); + furi_hal_gpio_init( + &gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_write(&gpio_cc1101_g0, true); if(!furi_hal_subghz_tx()) { - hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); subghz_test_carrier->callback( SubGhzTestCarrierEventOnlyRx, subghz_test_carrier->context); } @@ -138,7 +139,7 @@ void subghz_test_carrier_enter(void* context) { furi_hal_subghz_reset(); furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async); - hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); with_view_model( subghz_test_carrier->view, (SubGhzTestCarrierModel * model) { diff --git a/applications/subghz/views/subghz_test_packet.c b/applications/subghz/views/subghz_test_packet.c index 509d5c0a..fea3bd89 100644 --- a/applications/subghz/views/subghz_test_packet.c +++ b/applications/subghz/views/subghz_test_packet.c @@ -140,7 +140,7 @@ static bool subghz_test_packet_input(InputEvent* event, void* context) { if(model->status == SubGhzTestPacketModelStatusRx) { furi_hal_subghz_stop_async_rx(); } else if(model->status == SubGhzTestPacketModelStatusTx) { - subghz_encoder_princeton_for_testing_stop(instance->encoder, millis()); + subghz_encoder_princeton_for_testing_stop(instance->encoder, furi_hal_get_tick()); furi_hal_subghz_stop_async_tx(); } @@ -220,7 +220,7 @@ void subghz_test_packet_exit(void* context) { if(model->status == SubGhzTestPacketModelStatusRx) { furi_hal_subghz_stop_async_rx(); } else if(model->status == SubGhzTestPacketModelStatusTx) { - subghz_encoder_princeton_for_testing_stop(instance->encoder, millis()); + subghz_encoder_princeton_for_testing_stop(instance->encoder, furi_hal_get_tick()); furi_hal_subghz_stop_async_tx(); } return true; diff --git a/applications/subghz/views/subghz_test_static.c b/applications/subghz/views/subghz_test_static.c index aa564fd9..d1a7bfd4 100644 --- a/applications/subghz/views/subghz_test_static.c +++ b/applications/subghz/views/subghz_test_static.c @@ -118,7 +118,8 @@ bool subghz_test_static_input(InputEvent* event, void* context) { } else if(event->type == InputTypeRelease) { if(instance->satus_tx == SubGhzTestStaticStatusTX) { FURI_LOG_I(TAG, "TX Stop"); - subghz_encoder_princeton_for_testing_stop(instance->encoder, millis()); + subghz_encoder_princeton_for_testing_stop( + instance->encoder, furi_hal_get_tick()); subghz_encoder_princeton_for_testing_print_log(instance->encoder); furi_hal_subghz_stop_async_tx(); notification_message(notification, &sequence_reset_red); @@ -141,8 +142,8 @@ void subghz_test_static_enter(void* context) { furi_hal_subghz_reset(); furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async); - hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); - hal_gpio_write(&gpio_cc1101_g0, false); + furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_write(&gpio_cc1101_g0, false); instance->satus_tx = SubGhzTestStaticStatusIDLE; with_view_model( diff --git a/applications/tests/furi_valuemutex_test.c b/applications/tests/furi_valuemutex_test.c index 7a20f74f..4deb4f61 100644 --- a/applications/tests/furi_valuemutex_test.c +++ b/applications/tests/furi_valuemutex_test.c @@ -78,7 +78,7 @@ void furi_concurent_app(void* p) { uint8_t b = value->b; a++; b++; - delay(2); + furi_hal_delay_ms(2); value->a = a; value->b = b; release_mutex(mutex, value); @@ -114,12 +114,12 @@ void test_furi_concurrent_access() { a++; b++; value->a = a; - delay(10); // this is only for test, do not add delay between take/give in prod! + furi_hal_delay_ms(10); // this is only for test, do not add delay between take/give in prod! value->b = b; release_mutex(&mutex, value); } - delay(50); + furi_hal_delay_ms(50); mu_assert_pointers_eq(second_app->handler, NULL); diff --git a/applications/tests/rpc/rpc_test.c b/applications/tests/rpc/rpc_test.c index cdb63053..2a52ebb0 100644 --- a/applications/tests/rpc/rpc_test.c +++ b/applications/tests/rpc/rpc_test.c @@ -86,7 +86,7 @@ static void test_rpc_setup(void) { rpc = furi_record_open("rpc"); for(int i = 0; !(rpc_session[0].session) && (i < 10000); ++i) { rpc_session[0].session = rpc_session_open(rpc); - delay(1); + furi_hal_delay_ms(1); } furi_check(rpc_session[0].session); @@ -106,7 +106,7 @@ static void test_rpc_setup_second_session(void) { for(int i = 0; !(rpc_session[1].session) && (i < 10000); ++i) { rpc_session[1].session = rpc_session_open(rpc); - delay(1); + furi_hal_delay_ms(1); } furi_check(rpc_session[1].session); @@ -1518,28 +1518,28 @@ MU_TEST(test_app_start_and_lock_status) { test_app_get_status_lock_run(false, ++command_id); test_app_start_run("Delay Test", "0", PB_CommandStatus_OK, ++command_id); - delay(100); + furi_hal_delay_ms(100); test_app_get_status_lock_run(false, ++command_id); test_app_start_run("Delay Test", "200", PB_CommandStatus_OK, ++command_id); test_app_get_status_lock_run(true, ++command_id); - delay(100); + furi_hal_delay_ms(100); test_app_get_status_lock_run(true, ++command_id); test_app_start_run("Delay Test", "0", PB_CommandStatus_ERROR_APP_SYSTEM_LOCKED, ++command_id); - delay(200); + furi_hal_delay_ms(200); test_app_get_status_lock_run(false, ++command_id); test_app_start_run("Delay Test", "500", PB_CommandStatus_OK, ++command_id); - delay(100); + furi_hal_delay_ms(100); test_app_get_status_lock_run(true, ++command_id); test_app_start_run("Infrared", "0", PB_CommandStatus_ERROR_APP_SYSTEM_LOCKED, ++command_id); - delay(100); + furi_hal_delay_ms(100); test_app_get_status_lock_run(true, ++command_id); test_app_start_run( "2_girls_1_app", "0", PB_CommandStatus_ERROR_INVALID_PARAMETERS, ++command_id); - delay(100); + furi_hal_delay_ms(100); test_app_get_status_lock_run(true, ++command_id); - delay(500); + furi_hal_delay_ms(500); test_app_get_status_lock_run(false, ++command_id); } @@ -1786,7 +1786,7 @@ int32_t delay_test_app(void* p) { int timeout = atoi((const char*)p); if(timeout > 0) { - delay(timeout); + furi_hal_delay_ms(timeout); } return 0; diff --git a/applications/tests/test_index.c b/applications/tests/test_index.c index 2e567378..391f759e 100644 --- a/applications/tests/test_index.c +++ b/applications/tests/test_index.c @@ -63,7 +63,7 @@ void unit_tests_cli(Cli* cli, string_t args, void* context) { FURI_LOG_I(TAG, "Consumed: %0.2fs", (float)cycle_counter / (SystemCoreClock)); if(test_result == 0) { - delay(200); /* wait for tested services and apps to deallocate */ + furi_hal_delay_ms(200); /* wait for tested services and apps to deallocate */ uint32_t heap_after = memmgr_get_free_heap(); notification_message(notification, &sequence_success); if(heap_after != heap_before) { diff --git a/assets/compiled/protobuf_version.h b/assets/compiled/protobuf_version.h index 1e438d71..19d3f1ea 100644 --- a/assets/compiled/protobuf_version.h +++ b/assets/compiled/protobuf_version.h @@ -1,3 +1,3 @@ #pragma once #define PROTOBUF_MAJOR_VERSION 0 -#define PROTOBUF_MINOR_VERSION 2 +#define PROTOBUF_MINOR_VERSION 3 diff --git a/assets/protobuf b/assets/protobuf index 232e7e9a..cd11b029 160000 --- a/assets/protobuf +++ b/assets/protobuf @@ -1 +1 @@ -Subproject commit 232e7e9a50b12a95f950fabb515204775e51b04a +Subproject commit cd11b029ac21462ea8a7615126d0a29e087c2908 diff --git a/bootloader/targets/f7/furi_hal/furi_hal.c b/bootloader/targets/f7/furi_hal/furi_hal.c index 962a2e7e..33b0c8f1 100644 --- a/bootloader/targets/f7/furi_hal/furi_hal.c +++ b/bootloader/targets/f7/furi_hal/furi_hal.c @@ -8,11 +8,11 @@ void furi_hal_init() { furi_hal_version_init(); } -void delay(float milliseconds) { +void furi_hal_delay_ms(float milliseconds) { LL_mDelay((uint32_t)milliseconds); } -void delay_us(float microseconds) { +void furi_hal_delay_us(float microseconds) { microseconds = microseconds / 1000; if(microseconds < 1) { microseconds = 1; diff --git a/bootloader/targets/f7/furi_hal/furi_hal_gpio.c b/bootloader/targets/f7/furi_hal/furi_hal_gpio.c index a7c5c074..f80f4c1e 100644 --- a/bootloader/targets/f7/furi_hal/furi_hal_gpio.c +++ b/bootloader/targets/f7/furi_hal/furi_hal_gpio.c @@ -33,7 +33,7 @@ static volatile GpioInterrupt gpio_interrupt[GPIO_NUMBER]; -static uint8_t hal_gpio_get_pin_num(const GpioPin* gpio) { +static uint8_t furi_hal_gpio_get_pin_num(const GpioPin* gpio) { uint8_t pin_num = 0; for(pin_num = 0; pin_num < GPIO_NUMBER; pin_num++) { if(gpio->pin & (1 << pin_num)) break; @@ -41,11 +41,11 @@ static uint8_t hal_gpio_get_pin_num(const GpioPin* gpio) { return pin_num; } -void hal_gpio_init_simple(const GpioPin* gpio, const GpioMode mode) { - hal_gpio_init(gpio, mode, GpioPullNo, GpioSpeedLow); +void furi_hal_gpio_init_simple(const GpioPin* gpio, const GpioMode mode) { + furi_hal_gpio_init(gpio, mode, GpioPullNo, GpioSpeedLow); } -void hal_gpio_init( +void furi_hal_gpio_init( const GpioPin* gpio, const GpioMode mode, const GpioPull pull, @@ -54,10 +54,10 @@ void hal_gpio_init( assert(mode != GpioModeAltFunctionPushPull); assert(mode != GpioModeAltFunctionOpenDrain); - hal_gpio_init_ex(gpio, mode, pull, speed, GpioAltFnUnused); + furi_hal_gpio_init_ex(gpio, mode, pull, speed, GpioAltFnUnused); } -void hal_gpio_init_ex( +void furi_hal_gpio_init_ex( const GpioPin* gpio, const GpioMode mode, const GpioPull pull, @@ -132,7 +132,7 @@ void hal_gpio_init_ex( // Prepare alternative part if any if(mode == GpioModeAltFunctionPushPull || mode == GpioModeAltFunctionOpenDrain) { // set alternate function - if(hal_gpio_get_pin_num(gpio) < 8) { + if(furi_hal_gpio_get_pin_num(gpio) < 8) { LL_GPIO_SetAFPin_0_7(gpio->port, gpio->pin, alt_fn); } else { LL_GPIO_SetAFPin_8_15(gpio->port, gpio->pin, alt_fn); @@ -170,43 +170,43 @@ void hal_gpio_init_ex( __enable_irq(); } -void hal_gpio_add_int_callback(const GpioPin* gpio, GpioExtiCallback cb, void* ctx) { +void furi_hal_gpio_add_int_callback(const GpioPin* gpio, GpioExtiCallback cb, void* ctx) { assert(gpio); assert(cb); __disable_irq(); - uint8_t pin_num = hal_gpio_get_pin_num(gpio); + uint8_t pin_num = furi_hal_gpio_get_pin_num(gpio); gpio_interrupt[pin_num].callback = cb; gpio_interrupt[pin_num].context = ctx; gpio_interrupt[pin_num].ready = true; __enable_irq(); } -void hal_gpio_enable_int_callback(const GpioPin* gpio) { +void furi_hal_gpio_enable_int_callback(const GpioPin* gpio) { assert(gpio); __disable_irq(); - uint8_t pin_num = hal_gpio_get_pin_num(gpio); + uint8_t pin_num = furi_hal_gpio_get_pin_num(gpio); if(gpio_interrupt[pin_num].callback) { gpio_interrupt[pin_num].ready = true; } __enable_irq(); } -void hal_gpio_disable_int_callback(const GpioPin* gpio) { +void furi_hal_gpio_disable_int_callback(const GpioPin* gpio) { assert(gpio); __disable_irq(); - uint8_t pin_num = hal_gpio_get_pin_num(gpio); + uint8_t pin_num = furi_hal_gpio_get_pin_num(gpio); gpio_interrupt[pin_num].ready = false; __enable_irq(); } -void hal_gpio_remove_int_callback(const GpioPin* gpio) { +void furi_hal_gpio_remove_int_callback(const GpioPin* gpio) { assert(gpio); __disable_irq(); - uint8_t pin_num = hal_gpio_get_pin_num(gpio); + uint8_t pin_num = furi_hal_gpio_get_pin_num(gpio); gpio_interrupt[pin_num].callback = NULL; gpio_interrupt[pin_num].context = NULL; gpio_interrupt[pin_num].ready = false; diff --git a/bootloader/targets/f7/furi_hal/furi_hal_gpio.h b/bootloader/targets/f7/furi_hal/furi_hal_gpio.h index a81afb39..f633e834 100644 --- a/bootloader/targets/f7/furi_hal/furi_hal_gpio.h +++ b/bootloader/targets/f7/furi_hal/furi_hal_gpio.h @@ -1,6 +1,6 @@ #pragma once -#include "main.h" #include "stdbool.h" +#include "main.h" #include #include #include @@ -170,7 +170,7 @@ typedef struct { * @param gpio GpioPin * @param mode GpioMode */ -void hal_gpio_init_simple(const GpioPin* gpio, const GpioMode mode); +void furi_hal_gpio_init_simple(const GpioPin* gpio, const GpioMode mode); /** * GPIO initialization function, normal version @@ -179,7 +179,7 @@ void hal_gpio_init_simple(const GpioPin* gpio, const GpioMode mode); * @param pull GpioPull * @param speed GpioSpeed */ -void hal_gpio_init( +void furi_hal_gpio_init( const GpioPin* gpio, const GpioMode mode, const GpioPull pull, @@ -193,7 +193,7 @@ void hal_gpio_init( * @param speed GpioSpeed * @param alt_fn GpioAltFn */ -void hal_gpio_init_ex( +void furi_hal_gpio_init_ex( const GpioPin* gpio, const GpioMode mode, const GpioPull pull, @@ -206,32 +206,32 @@ void hal_gpio_init_ex( * @param cb GpioExtiCallback * @param ctx context for callback */ -void hal_gpio_add_int_callback(const GpioPin* gpio, GpioExtiCallback cb, void* ctx); +void furi_hal_gpio_add_int_callback(const GpioPin* gpio, GpioExtiCallback cb, void* ctx); /** * Enable interrupt * @param gpio GpioPin */ -void hal_gpio_enable_int_callback(const GpioPin* gpio); +void furi_hal_gpio_enable_int_callback(const GpioPin* gpio); /** * Disable interrupt * @param gpio GpioPin */ -void hal_gpio_disable_int_callback(const GpioPin* gpio); +void furi_hal_gpio_disable_int_callback(const GpioPin* gpio); /** * Remove interrupt * @param gpio GpioPin */ -void hal_gpio_remove_int_callback(const GpioPin* gpio); +void furi_hal_gpio_remove_int_callback(const GpioPin* gpio); /** * GPIO write pin * @param gpio GpioPin * @param state true / false */ -static inline void hal_gpio_write(const GpioPin* gpio, const bool state) { +static inline void furi_hal_gpio_write(const GpioPin* gpio, const bool state) { // writing to BSSR is an atomic operation if(state == true) { gpio->port->BSRR = gpio->pin; @@ -245,7 +245,7 @@ static inline void hal_gpio_write(const GpioPin* gpio, const bool state) { * @param gpio GpioPin * @return true / false */ -static inline bool hal_gpio_read(const GpioPin* gpio) { +static inline bool furi_hal_gpio_read(const GpioPin* gpio) { if((gpio->port->IDR & gpio->pin) != 0x00U) { return true; } else { @@ -257,7 +257,7 @@ static inline bool hal_gpio_read(const GpioPin* gpio) { * Get RFID IN level * @return false = LOW, true = HIGH */ -bool hal_gpio_get_rfid_in_level(); +bool furi_hal_gpio_get_rfid_in_level(); #ifdef __cplusplus } diff --git a/bootloader/targets/f7/furi_hal/furi_hal_i2c_config.c b/bootloader/targets/f7/furi_hal/furi_hal_i2c_config.c index 36610e42..e693911a 100644 --- a/bootloader/targets/f7/furi_hal/furi_hal_i2c_config.c +++ b/bootloader/targets/f7/furi_hal/furi_hal_i2c_config.c @@ -60,13 +60,13 @@ void furi_hal_i2c_bus_handle_power_event( FuriHalI2cBusHandleEvent event) { if(event == FuriHalI2cBusHandleEventActivate) { LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); - hal_gpio_init_ex( + furi_hal_gpio_init_ex( &gpio_i2c_power_sda, GpioModeAltFunctionOpenDrain, GpioPullNo, GpioSpeedLow, GpioAltFn4I2C1); - hal_gpio_init_ex( + furi_hal_gpio_init_ex( &gpio_i2c_power_scl, GpioModeAltFunctionOpenDrain, GpioPullNo, @@ -95,11 +95,11 @@ void furi_hal_i2c_bus_handle_power_event( LL_I2C_Enable(handle->bus->i2c); } else if(event == FuriHalI2cBusHandleEventDeactivate) { LL_I2C_Disable(handle->bus->i2c); - hal_gpio_write(&gpio_i2c_power_sda, 1); - hal_gpio_write(&gpio_i2c_power_scl, 1); - hal_gpio_init_ex( + furi_hal_gpio_write(&gpio_i2c_power_sda, 1); + furi_hal_gpio_write(&gpio_i2c_power_scl, 1); + furi_hal_gpio_init_ex( &gpio_i2c_power_sda, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused); - hal_gpio_init_ex( + furi_hal_gpio_init_ex( &gpio_i2c_power_scl, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused); } } @@ -113,9 +113,9 @@ void furi_hal_i2c_bus_handle_external_event( FuriHalI2cBusHandle* handle, FuriHalI2cBusHandleEvent event) { if(event == FuriHalI2cBusHandleEventActivate) { - hal_gpio_init_ex( + furi_hal_gpio_init_ex( &gpio_ext_pc0, GpioModeAltFunctionOpenDrain, GpioPullNo, GpioSpeedLow, GpioAltFn4I2C3); - hal_gpio_init_ex( + furi_hal_gpio_init_ex( &gpio_ext_pc1, GpioModeAltFunctionOpenDrain, GpioPullNo, GpioSpeedLow, GpioAltFn4I2C3); LL_I2C_InitTypeDef I2C_InitStruct = {0}; @@ -136,10 +136,12 @@ void furi_hal_i2c_bus_handle_external_event( LL_I2C_Enable(handle->bus->i2c); } else if(event == FuriHalI2cBusHandleEventDeactivate) { LL_I2C_Disable(handle->bus->i2c); - hal_gpio_write(&gpio_ext_pc0, 1); - hal_gpio_write(&gpio_ext_pc1, 1); - hal_gpio_init_ex(&gpio_ext_pc0, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused); - hal_gpio_init_ex(&gpio_ext_pc1, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused); + furi_hal_gpio_write(&gpio_ext_pc0, 1); + furi_hal_gpio_write(&gpio_ext_pc1, 1); + furi_hal_gpio_init_ex( + &gpio_ext_pc0, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused); + furi_hal_gpio_init_ex( + &gpio_ext_pc1, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused); } } diff --git a/bootloader/targets/f7/furi_hal/furi_hal_resources.c b/bootloader/targets/f7/furi_hal/furi_hal_resources.c index e73b7cbc..fd792aa6 100644 --- a/bootloader/targets/f7/furi_hal/furi_hal_resources.c +++ b/bootloader/targets/f7/furi_hal/furi_hal_resources.c @@ -1,5 +1,4 @@ #include "furi_hal_resources.h" -#include "main.h" const GpioPin vibro_gpio = {.port = VIBRO_GPIO_Port, .pin = VIBRO_Pin}; const GpioPin ibutton_gpio = {.port = iBTN_GPIO_Port, .pin = iBTN_Pin}; diff --git a/bootloader/targets/f7/furi_hal/furi_hal_spi_config.c b/bootloader/targets/f7/furi_hal/furi_hal_spi_config.c index 35032a38..a7c745cd 100644 --- a/bootloader/targets/f7/furi_hal/furi_hal_spi_config.c +++ b/bootloader/targets/f7/furi_hal/furi_hal_spi_config.c @@ -117,42 +117,42 @@ inline static void furi_hal_spi_bus_r_handle_event_callback( FuriHalSpiBusHandleEvent event, const LL_SPI_InitTypeDef* preset) { if(event == FuriHalSpiBusHandleEventInit) { - hal_gpio_write(handle->cs, true); - hal_gpio_init(handle->cs, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); + furi_hal_gpio_write(handle->cs, true); + furi_hal_gpio_init(handle->cs, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); } else if(event == FuriHalSpiBusHandleEventDeinit) { - hal_gpio_write(handle->cs, true); - hal_gpio_init(handle->cs, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_write(handle->cs, true); + furi_hal_gpio_init(handle->cs, GpioModeAnalog, GpioPullNo, GpioSpeedLow); } else if(event == FuriHalSpiBusHandleEventActivate) { LL_SPI_Init(handle->bus->spi, (LL_SPI_InitTypeDef*)preset); LL_SPI_SetRxFIFOThreshold(handle->bus->spi, LL_SPI_RX_FIFO_TH_QUARTER); LL_SPI_Enable(handle->bus->spi); - hal_gpio_init_ex( + furi_hal_gpio_init_ex( handle->miso, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI1); - hal_gpio_init_ex( + furi_hal_gpio_init_ex( handle->mosi, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI1); - hal_gpio_init_ex( + furi_hal_gpio_init_ex( handle->sck, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI1); - hal_gpio_write(handle->cs, false); + furi_hal_gpio_write(handle->cs, false); } else if(event == FuriHalSpiBusHandleEventDeactivate) { - hal_gpio_write(handle->cs, true); + furi_hal_gpio_write(handle->cs, true); - hal_gpio_init(handle->miso, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - hal_gpio_init(handle->mosi, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - hal_gpio_init(handle->sck, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(handle->miso, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(handle->mosi, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(handle->sck, GpioModeAnalog, GpioPullNo, GpioSpeedLow); LL_SPI_Disable(handle->bus->spi); } @@ -208,22 +208,22 @@ inline static void furi_hal_spi_bus_d_handle_event_callback( FuriHalSpiBusHandleEvent event, const LL_SPI_InitTypeDef* preset) { if(event == FuriHalSpiBusHandleEventInit) { - hal_gpio_write(handle->cs, true); - hal_gpio_init(handle->cs, GpioModeOutputPushPull, GpioPullUp, GpioSpeedVeryHigh); + furi_hal_gpio_write(handle->cs, true); + furi_hal_gpio_init(handle->cs, GpioModeOutputPushPull, GpioPullUp, GpioSpeedVeryHigh); - hal_gpio_init_ex( + furi_hal_gpio_init_ex( handle->miso, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI2); - hal_gpio_init_ex( + furi_hal_gpio_init_ex( handle->mosi, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI2); - hal_gpio_init_ex( + furi_hal_gpio_init_ex( handle->sck, GpioModeAltFunctionPushPull, GpioPullNo, @@ -231,15 +231,15 @@ inline static void furi_hal_spi_bus_d_handle_event_callback( GpioAltFn5SPI2); } else if(event == FuriHalSpiBusHandleEventDeinit) { - hal_gpio_write(handle->cs, true); - hal_gpio_init(handle->cs, GpioModeAnalog, GpioPullUp, GpioSpeedLow); + furi_hal_gpio_write(handle->cs, true); + furi_hal_gpio_init(handle->cs, GpioModeAnalog, GpioPullUp, GpioSpeedLow); } else if(event == FuriHalSpiBusHandleEventActivate) { LL_SPI_Init(handle->bus->spi, (LL_SPI_InitTypeDef*)preset); LL_SPI_SetRxFIFOThreshold(handle->bus->spi, LL_SPI_RX_FIFO_TH_QUARTER); LL_SPI_Enable(handle->bus->spi); - hal_gpio_write(handle->cs, false); + furi_hal_gpio_write(handle->cs, false); } else if(event == FuriHalSpiBusHandleEventDeactivate) { - hal_gpio_write(handle->cs, true); + furi_hal_gpio_write(handle->cs, true); LL_SPI_Disable(handle->bus->spi); } } diff --git a/bootloader/targets/f7/target.c b/bootloader/targets/f7/target.c index 377b20b6..58eace9c 100644 --- a/bootloader/targets/f7/target.c +++ b/bootloader/targets/f7/target.c @@ -185,8 +185,8 @@ void target_usb_wire_reset() { void target_display_init() { // Prepare gpio - hal_gpio_init_simple(&gpio_display_rst, GpioModeOutputPushPull); - hal_gpio_init_simple(&gpio_display_di, GpioModeOutputPushPull); + furi_hal_gpio_init_simple(&gpio_display_rst, GpioModeOutputPushPull); + furi_hal_gpio_init_simple(&gpio_display_di, GpioModeOutputPushPull); // Initialize u8g2_t fb; u8g2_Setup_st756x_flipper(&fb, U8G2_R0, u8x8_hw_spi_stm32, u8g2_gpio_and_delay_stm32); diff --git a/bootloader/targets/furi_hal_include/furi_hal.h b/bootloader/targets/furi_hal_include/furi_hal.h index 75c37a8a..5d612566 100644 --- a/bootloader/targets/furi_hal_include/furi_hal.h +++ b/bootloader/targets/furi_hal_include/furi_hal.h @@ -10,6 +10,6 @@ void furi_hal_init(); -void delay(float milliseconds); +void furi_hal_delay_ms(float milliseconds); -void delay_us(float microseconds); +void furi_hal_delay_us(float microseconds); diff --git a/core/furi/check.c b/core/furi/check.c index d43871b1..fafddd91 100644 --- a/core/furi/check.c +++ b/core/furi/check.c @@ -1,11 +1,13 @@ #include "check.h" -#include "furi_hal_task.h" +#include "common_defines.h" + #include +#include #include #include void __furi_print_name() { - if(task_is_isr_context()) { + if(FURI_IS_ISR()) { furi_hal_console_puts("[ISR] "); } else { const char* name = osThreadGetName(osThreadGetId()); @@ -50,7 +52,7 @@ void furi_crash(const char* message) { furi_hal_rtc_set_fault_data((uint32_t)message); furi_hal_console_puts("\r\nRebooting system.\r\n"); furi_hal_console_puts("\033[0m\r\n"); - NVIC_SystemReset(); + furi_hal_power_reset(); #endif } diff --git a/core/furi/common_defines.h b/core/furi/common_defines.h old mode 100755 new mode 100644 index f5c46be7..38e60315 --- a/core/furi/common_defines.h +++ b/core/furi/common_defines.h @@ -1,5 +1,14 @@ #pragma once +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#include + #ifndef MAX #define MAX(a, b) \ ({ \ @@ -57,6 +66,14 @@ #define ALIGN(n) __attribute__((aligned(n))) #endif +#ifndef __weak +#define __weak __attribute__((weak)) +#endif + +#ifndef UNUSED +#define UNUSED(X) (void)(X) +#endif + #ifndef STRINGIFY #define STRINGIFY(x) #x #endif @@ -75,12 +92,39 @@ #define FURI_BIT(x, n) ((x) >> (n)&1) #endif +#ifndef FURI_IS_IRQ_MASKED +#define FURI_IS_IRQ_MASKED() (__get_PRIMASK() != 0U) +#endif + +#ifndef FURI_IS_IRQ_MODE +#define FURI_IS_IRQ_MODE() (__get_IPSR() != 0U) +#endif + +#ifndef FURI_IS_ISR +#define FURI_IS_ISR() \ + (FURI_IS_IRQ_MODE() || (FURI_IS_IRQ_MASKED() && (osKernelGetState() == osKernelRunning))) +#endif + #ifndef FURI_CRITICAL_ENTER -#define FURI_CRITICAL_ENTER() \ - uint32_t primask_bit = __get_PRIMASK(); \ - __disable_irq() +#define FURI_CRITICAL_ENTER() \ + uint32_t __isrm = 0; \ + bool __from_isr = FURI_IS_ISR(); \ + if(__from_isr) { \ + __isrm = taskENTER_CRITICAL_FROM_ISR(); \ + } else { \ + taskENTER_CRITICAL(); \ + } #endif #ifndef FURI_CRITICAL_EXIT -#define FURI_CRITICAL_EXIT() __set_PRIMASK(primask_bit) +#define FURI_CRITICAL_EXIT() \ + if(__from_isr) { \ + taskEXIT_CRITICAL_FROM_ISR(__isrm); \ + } else { \ + taskEXIT_CRITICAL(); \ + } +#endif + +#ifdef __cplusplus +} #endif diff --git a/core/furi/log.c b/core/furi/log.c index bc1a39fd..9ce025b9 100644 --- a/core/furi/log.c +++ b/core/furi/log.c @@ -18,7 +18,7 @@ void furi_log_init() { // Set default logging parameters furi_log.log_level = FURI_LOG_LEVEL_DEFAULT; furi_log.puts = furi_hal_console_puts; - furi_log.timetamp = HAL_GetTick; + furi_log.timetamp = furi_hal_get_tick; furi_log.mutex = osMutexNew(NULL); } diff --git a/core/furi/memmgr_heap.c b/core/furi/memmgr_heap.c index f4bd6ab3..d40da870 100644 --- a/core/furi/memmgr_heap.c +++ b/core/furi/memmgr_heap.c @@ -41,7 +41,6 @@ #include #include #include -#include /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining all the API functions to use the MPU wrappers. That should only be done when diff --git a/firmware/targets/f7/Inc/FreeRTOSConfig.h b/firmware/targets/f7/Inc/FreeRTOSConfig.h index 2f7b1df4..ee56922b 100644 --- a/firmware/targets/f7/Inc/FreeRTOSConfig.h +++ b/firmware/targets/f7/Inc/FreeRTOSConfig.h @@ -77,11 +77,13 @@ to exclude the API function. */ /* CMSIS-RTOS V2 flags */ #define configUSE_OS2_THREAD_SUSPEND_RESUME 1 #define configUSE_OS2_THREAD_ENUMERATE 1 -#define configUSE_OS2_EVENTFLAGS_FROM_ISR 1 #define configUSE_OS2_THREAD_FLAGS 1 #define configUSE_OS2_TIMER 1 #define configUSE_OS2_MUTEX 1 +// NEVER TO BE USED, because of their hard realtime nature +// #define configUSE_OS2_EVENTFLAGS_FROM_ISR 1 + /* CMSIS-RTOS */ #define configTASK_NOTIFICATION_ARRAY_ENTRIES 2 #define CMSIS_TASK_NOTIFY_INDEX 1 diff --git a/firmware/targets/f7/Inc/gpio.h b/firmware/targets/f7/Inc/gpio.h deleted file mode 100644 index b8813862..00000000 --- a/firmware/targets/f7/Inc/gpio.h +++ /dev/null @@ -1,49 +0,0 @@ -/** - ****************************************************************************** - * @file gpio.h - * @brief This file contains all the function prototypes for - * the gpio.c file - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2021 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __GPIO_H__ -#define __GPIO_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" - -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -/* USER CODE BEGIN Private defines */ - -/* USER CODE END Private defines */ - -void MX_GPIO_Init(void); - -/* USER CODE BEGIN Prototypes */ - -/* USER CODE END Prototypes */ - -#ifdef __cplusplus -} -#endif -#endif /*__ GPIO_H__ */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/Inc/main.h b/firmware/targets/f7/Inc/main.h deleted file mode 100644 index 78aafd1f..00000000 --- a/firmware/targets/f7/Inc/main.h +++ /dev/null @@ -1,125 +0,0 @@ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#include "stm32wbxx_hal.h" - -void Error_Handler(void); - -#define BUTTON_BACK_EXTI_IRQn EXTI15_10_IRQn -#define BUTTON_BACK_GPIO_Port GPIOC -#define BUTTON_BACK_Pin GPIO_PIN_13 -#define BUTTON_DOWN_EXTI_IRQn EXTI6_IRQn -#define BUTTON_DOWN_GPIO_Port GPIOC -#define BUTTON_DOWN_Pin GPIO_PIN_6 -#define BUTTON_LEFT_EXTI_IRQn EXTI15_10_IRQn -#define BUTTON_LEFT_GPIO_Port GPIOB -#define BUTTON_LEFT_Pin GPIO_PIN_11 -#define BUTTON_OK_EXTI_IRQn EXTI3_IRQn -#define BUTTON_OK_GPIO_Port GPIOH -#define BUTTON_OK_Pin GPIO_PIN_3 -#define BUTTON_RIGHT_EXTI_IRQn EXTI15_10_IRQn -#define BUTTON_RIGHT_GPIO_Port GPIOB -#define BUTTON_RIGHT_Pin GPIO_PIN_12 -#define BUTTON_UP_EXTI_IRQn EXTI15_10_IRQn -#define BUTTON_UP_GPIO_Port GPIOB -#define BUTTON_UP_Pin GPIO_PIN_10 - -#define CC1101_CS_GPIO_Port GPIOD -#define CC1101_CS_Pin GPIO_PIN_0 -#define CC1101_G0_GPIO_Port GPIOA -#define CC1101_G0_Pin GPIO_PIN_1 - -#define DISPLAY_CS_GPIO_Port GPIOC -#define DISPLAY_CS_Pin GPIO_PIN_11 -#define DISPLAY_DI_GPIO_Port GPIOB -#define DISPLAY_DI_Pin GPIO_PIN_1 -#define DISPLAY_RST_GPIO_Port GPIOB -#define DISPLAY_RST_Pin GPIO_PIN_0 - -#define IR_RX_GPIO_Port GPIOA -#define IR_RX_Pin GPIO_PIN_0 -#define IR_TX_GPIO_Port GPIOB -#define IR_TX_Pin GPIO_PIN_9 - -#define NFC_CS_GPIO_Port GPIOE -#define NFC_CS_Pin GPIO_PIN_4 - -#define PA4_GPIO_Port GPIOA -#define PA4_Pin GPIO_PIN_4 -#define PA6_GPIO_Port GPIOA -#define PA6_Pin GPIO_PIN_6 -#define PA7_GPIO_Port GPIOA -#define PA7_Pin GPIO_PIN_7 -#define PB2_GPIO_Port GPIOB -#define PB2_Pin GPIO_PIN_2 -#define PB3_GPIO_Port GPIOB -#define PB3_Pin GPIO_PIN_3 -#define PC0_GPIO_Port GPIOC -#define PC0_Pin GPIO_PIN_0 -#define PC1_GPIO_Port GPIOC -#define PC1_Pin GPIO_PIN_1 -#define PC3_GPIO_Port GPIOC -#define PC3_Pin GPIO_PIN_3 - -#define PERIPH_POWER_GPIO_Port GPIOA -#define PERIPH_POWER_Pin GPIO_PIN_3 - -#define QUARTZ_32MHZ_IN_GPIO_Port GPIOC -#define QUARTZ_32MHZ_IN_Pin GPIO_PIN_14 -#define QUARTZ_32MHZ_OUT_GPIO_Port GPIOC -#define QUARTZ_32MHZ_OUT_Pin GPIO_PIN_15 - -#define RFID_OUT_GPIO_Port GPIOB -#define RFID_OUT_Pin GPIO_PIN_13 -#define RFID_PULL_GPIO_Port GPIOA -#define RFID_PULL_Pin GPIO_PIN_2 -#define RFID_RF_IN_GPIO_Port GPIOC -#define RFID_RF_IN_Pin GPIO_PIN_5 -#define RFID_CARRIER_GPIO_Port GPIOA -#define RFID_CARRIER_Pin GPIO_PIN_15 - -#define RF_SW_0_GPIO_Port GPIOC -#define RF_SW_0_Pin GPIO_PIN_4 - -#define SD_CD_GPIO_Port GPIOC -#define SD_CD_Pin GPIO_PIN_10 -#define SD_CS_GPIO_Port GPIOC -#define SD_CS_Pin GPIO_PIN_12 - -#define SPEAKER_GPIO_Port GPIOB -#define SPEAKER_Pin GPIO_PIN_8 - -#define VIBRO_GPIO_Port GPIOA -#define VIBRO_Pin GPIO_PIN_8 - -#define iBTN_GPIO_Port GPIOB -#define iBTN_Pin GPIO_PIN_14 - -#define USART1_TX_Pin GPIO_PIN_6 -#define USART1_TX_Port GPIOB -#define USART1_RX_Pin GPIO_PIN_7 -#define USART1_RX_Port GPIOB - -#define SPI_D_MISO_GPIO_Port GPIOC -#define SPI_D_MISO_Pin GPIO_PIN_2 -#define SPI_D_MOSI_GPIO_Port GPIOB -#define SPI_D_MOSI_Pin GPIO_PIN_15 -#define SPI_D_SCK_GPIO_Port GPIOD -#define SPI_D_SCK_Pin GPIO_PIN_1 - -#define SPI_R_MISO_GPIO_Port GPIOB -#define SPI_R_MISO_Pin GPIO_PIN_4 -#define SPI_R_MOSI_GPIO_Port GPIOB -#define SPI_R_MOSI_Pin GPIO_PIN_5 -#define SPI_R_SCK_GPIO_Port GPIOA -#define SPI_R_SCK_Pin GPIO_PIN_5 - -#define NFC_IRQ_Pin RFID_PULL_Pin -#define NFC_IRQ_GPIO_Port RFID_PULL_GPIO_Port - -#ifdef __cplusplus -} -#endif diff --git a/firmware/targets/f7/Inc/stm32_assert.h b/firmware/targets/f7/Inc/stm32_assert.h deleted file mode 100644 index b70ee402..00000000 --- a/firmware/targets/f7/Inc/stm32_assert.h +++ /dev/null @@ -1,40 +0,0 @@ -/** - ****************************************************************************** - * @file stm32_assert.h - * @brief STM32 assert file. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2019 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under BSD 3-Clause license, - * the "License"; You may not use this file except in compliance with the - * License. You may obtain a copy of the License at: - * opensource.org/licenses/BSD-3-Clause - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32_ASSERT_H -#define __STM32_ASSERT_H - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef USE_FULL_ASSERT -#define assert_param(expr) ((expr) ? (void)0U : assert_failed()) -void assert_failed(); -#else -#define assert_param(expr) ((void)0U) -#endif /* USE_FULL_ASSERT */ - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32_ASSERT_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/Inc/stm32wbxx_hal_conf.h b/firmware/targets/f7/Inc/stm32wbxx_hal_conf.h deleted file mode 100644 index 6f8c5354..00000000 --- a/firmware/targets/f7/Inc/stm32wbxx_hal_conf.h +++ /dev/null @@ -1,347 +0,0 @@ -/** - ****************************************************************************** - * @file stm32wbxx_hal_conf.h - * @author MCD Application Team - * @brief HAL configuration file. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2019 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under BSD 3-Clause license, - * the "License"; You may not use this file except in compliance with the - * License. You may obtain a copy of the License at: - * opensource.org/licenses/BSD-3-Clause - * - ****************************************************************************** - */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32WBxx_HAL_CONF_H -#define __STM32WBxx_HAL_CONF_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Exported types ------------------------------------------------------------*/ -/* Exported constants --------------------------------------------------------*/ - -/* ########################## Module Selection ############################## */ -/** - * @brief This is the list of modules to be used in the HAL driver - */ -#define HAL_MODULE_ENABLED -/*#define HAL_ADC_MODULE_ENABLED */ -#define HAL_CRYP_MODULE_ENABLED -/*#define HAL_COMP_MODULE_ENABLED */ -/*#define HAL_CRC_MODULE_ENABLED */ -#define HAL_HSEM_MODULE_ENABLED -/*#define HAL_I2C_MODULE_ENABLED */ -/*#define HAL_IPCC_MODULE_ENABLED */ -/*#define HAL_IRDA_MODULE_ENABLED */ -/*#define HAL_IWDG_MODULE_ENABLED */ -/*#define HAL_LCD_MODULE_ENABLED */ -/*#define HAL_LPTIM_MODULE_ENABLED */ -#define HAL_PCD_MODULE_ENABLED -#define HAL_PKA_MODULE_ENABLED -/*#define HAL_QSPI_MODULE_ENABLED */ -#define HAL_RNG_MODULE_ENABLED -/*#define HAL_RTC_MODULE_ENABLED */ -/*#define HAL_SAI_MODULE_ENABLED */ -/*#define HAL_SMBUS_MODULE_ENABLED */ -/*#define HAL_SMARTCARD_MODULE_ENABLED */ -/*#define HAL_SPI_MODULE_ENABLED */ -/*#define HAL_TIM_MODULE_ENABLED */ -/*#define HAL_TSC_MODULE_ENABLED */ -/*#define HAL_UART_MODULE_ENABLED */ -/*#define HAL_USART_MODULE_ENABLED */ -/*#define HAL_WWDG_MODULE_ENABLED */ -#define HAL_EXTI_MODULE_ENABLED -#define HAL_CORTEX_MODULE_ENABLED -#define HAL_DMA_MODULE_ENABLED -#define HAL_FLASH_MODULE_ENABLED -#define HAL_GPIO_MODULE_ENABLED -#define HAL_PWR_MODULE_ENABLED -#define HAL_RCC_MODULE_ENABLED - -#define USE_HAL_ADC_REGISTER_CALLBACKS 0u -#define USE_HAL_COMP_REGISTER_CALLBACKS 0u -#define USE_HAL_CRYP_REGISTER_CALLBACKS 0u -#define USE_HAL_I2C_REGISTER_CALLBACKS 0u -#define USE_HAL_IRDA_REGISTER_CALLBACKS 0u -#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0u -#define USE_HAL_PCD_REGISTER_CALLBACKS 0u -#define USE_HAL_PKA_REGISTER_CALLBACKS 0u -#define USE_HAL_QSPI_REGISTER_CALLBACKS 0u -#define USE_HAL_RNG_REGISTER_CALLBACKS 0u -#define USE_HAL_RTC_REGISTER_CALLBACKS 0u -#define USE_HAL_SAI_REGISTER_CALLBACKS 0u -#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0u -#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0u -#define USE_HAL_SPI_REGISTER_CALLBACKS 0u -#define USE_HAL_TIM_REGISTER_CALLBACKS 0u -#define USE_HAL_TSC_REGISTER_CALLBACKS 0u -#define USE_HAL_UART_REGISTER_CALLBACKS 0u -#define USE_HAL_USART_REGISTER_CALLBACKS 0u -#define USE_HAL_WWDG_REGISTER_CALLBACKS 0u - -/* ########################## Oscillator Values adaptation ####################*/ -/** - * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. - * This value is used by the RCC HAL module to compute the system frequency - * (when HSE is used as system clock source, directly or through the PLL). - */ -#if !defined(HSE_VALUE) -#define HSE_VALUE 32000000U /*!< Value of the External oscillator in Hz */ -#endif /* HSE_VALUE */ - -#if !defined(HSE_STARTUP_TIMEOUT) -#define HSE_STARTUP_TIMEOUT ((uint32_t)100) /*!< Time out for HSE start up, in ms */ -#endif /* HSE_STARTUP_TIMEOUT */ - -/** - * @brief Internal Multiple Speed oscillator (MSI) default value. - * This value is the default MSI range value after Reset. - */ -#if !defined(MSI_VALUE) -#define MSI_VALUE ((uint32_t)4000000) /*!< Value of the Internal oscillator in Hz*/ -#endif /* MSI_VALUE */ - -/** - * @brief Internal High Speed oscillator (HSI) value. - * This value is used by the RCC HAL module to compute the system frequency - * (when HSI is used as system clock source, directly or through the PLL). - */ -#if !defined(HSI_VALUE) -#define HSI_VALUE 16000000U /*!< Value of the Internal oscillator in Hz*/ -#endif /* HSI_VALUE */ - -/** - * @brief Internal Low Speed oscillator (LSI1) value. - */ -#if !defined(LSI1_VALUE) -#define LSI1_VALUE ((uint32_t)32000) /*!< LSI1 Typical Value in Hz*/ -#endif /* LSI1_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz - The real value may vary depending on the variations - in voltage and temperature.*/ -/** - * @brief Internal Low Speed oscillator (LSI2) value. - */ -#if !defined(LSI2_VALUE) -#define LSI2_VALUE ((uint32_t)32000) /*!< LSI2 Typical Value in Hz*/ -#endif /* LSI2_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz - The real value may vary depending on the variations - in voltage and temperature.*/ - -/** - * @brief External Low Speed oscillator (LSE) value. - * This value is used by the UART, RTC HAL module to compute the system frequency - */ -#if !defined(LSE_VALUE) -#define LSE_VALUE 32768U /*!< Value of the External oscillator in Hz*/ -#endif /* LSE_VALUE */ - -/** - * @brief Internal Multiple Speed oscillator (HSI48) default value. - * This value is the default HSI48 range value after Reset. - */ -#if !defined(HSI48_VALUE) -#define HSI48_VALUE ((uint32_t)48000000) /*!< Value of the Internal oscillator in Hz*/ -#endif /* HSI48_VALUE */ - -#if !defined(LSE_STARTUP_TIMEOUT) -#define LSE_STARTUP_TIMEOUT 1000U /*!< Time out for LSE start up, in ms */ -#endif /* HSE_STARTUP_TIMEOUT */ - -/** - * @brief External clock source for SAI1 peripheral - * This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source - * frequency. - */ -#if !defined(EXTERNAL_SAI1_CLOCK_VALUE) -#define EXTERNAL_SAI1_CLOCK_VALUE \ - ((uint32_t)2097000) /*!< Value of the SAI1 External clock source in Hz*/ -#endif /* EXTERNAL_SAI1_CLOCK_VALUE */ - -/* Tip: To avoid modifying this file each time you need to use different HSE, - === you can define the HSE value in your toolchain compiler preprocessor. */ - -/* ########################### System Configuration ######################### */ -/** - * @brief This is the HAL system configuration section - */ - -#define VDD_VALUE 3300U /*!< Value of VDD in mv */ -#define TICK_INT_PRIORITY 0U /*!< tick interrupt priority */ -#define USE_RTOS 0U -#define PREFETCH_ENABLE 1U -#define INSTRUCTION_CACHE_ENABLE 1U -#define DATA_CACHE_ENABLE 1U - -/* ########################## Assert Selection ############################## */ -/** - * @brief Uncomment the line below to expanse the "assert_param" macro in the - * HAL drivers code - */ -#ifdef APP_UNIT_TESTS -#define USE_FULL_ASSERT 1U -#endif - -/* ################## SPI peripheral configuration ########################## */ - -/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver - * Activated: CRC code is present inside driver - * Deactivated: CRC code cleaned from driver - */ - -#define USE_SPI_CRC 0U - -/* Includes ------------------------------------------------------------------*/ -/** - * @brief Include module's header file - */ -#ifdef HAL_DMA_MODULE_ENABLED -#include "stm32wbxx_hal_dma.h" -#endif /* HAL_DMA_MODULE_ENABLED */ - -#ifdef HAL_ADC_MODULE_ENABLED -#include "stm32wbxx_hal_adc.h" -#endif /* HAL_ADC_MODULE_ENABLED */ - -#ifdef HAL_COMP_MODULE_ENABLED -#include "stm32wbxx_hal_comp.h" -#endif /* HAL_COMP_MODULE_ENABLED */ - -#ifdef HAL_CORTEX_MODULE_ENABLED -#include "stm32wbxx_hal_cortex.h" -#endif /* HAL_CORTEX_MODULE_ENABLED */ - -#ifdef HAL_CRC_MODULE_ENABLED -#include "stm32wbxx_hal_crc.h" -#endif /* HAL_CRC_MODULE_ENABLED */ - -#ifdef HAL_CRYP_MODULE_ENABLED -#include "stm32wbxx_hal_cryp.h" -#endif /* HAL_CRYP_MODULE_ENABLED */ - -#ifdef HAL_EXTI_MODULE_ENABLED -#include "stm32wbxx_hal_exti.h" -#endif /* HAL_EXTI_MODULE_ENABLED */ - -#ifdef HAL_FLASH_MODULE_ENABLED -#include "stm32wbxx_hal_flash.h" -#endif /* HAL_FLASH_MODULE_ENABLED */ - -#ifdef HAL_GPIO_MODULE_ENABLED -#include "stm32wbxx_hal_gpio.h" -#endif /* HAL_GPIO_MODULE_ENABLED */ - -#ifdef HAL_HSEM_MODULE_ENABLED -#include "stm32wbxx_hal_hsem.h" -#endif /* HAL_HSEM_MODULE_ENABLED */ - -#ifdef HAL_I2C_MODULE_ENABLED -#include "stm32wbxx_hal_i2c.h" -#endif /* HAL_I2C_MODULE_ENABLED */ - -#ifdef HAL_IPCC_MODULE_ENABLED -#include "stm32wbxx_hal_ipcc.h" -#endif /* HAL_IPCC_MODULE_ENABLED */ - -#ifdef HAL_IRDA_MODULE_ENABLED -#include "stm32wbxx_hal_irda.h" -#endif /* HAL_IRDA_MODULE_ENABLED */ - -#ifdef HAL_IWDG_MODULE_ENABLED -#include "stm32wbxx_hal_iwdg.h" -#endif /* HAL_IWDG_MODULE_ENABLED */ - -#ifdef HAL_LCD_MODULE_ENABLED -#include "stm32wbxx_hal_lcd.h" -#endif /* HAL_LCD_MODULE_ENABLED */ - -#ifdef HAL_LPTIM_MODULE_ENABLED -#include "stm32wbxx_hal_lptim.h" -#endif /* HAL_LPTIM_MODULE_ENABLED */ - -#ifdef HAL_PCD_MODULE_ENABLED -#include "stm32wbxx_hal_pcd.h" -#endif /* HAL_PCD_MODULE_ENABLED */ - -#ifdef HAL_PKA_MODULE_ENABLED -#include "stm32wbxx_hal_pka.h" -#endif /* HAL_PKA_MODULE_ENABLED */ - -#ifdef HAL_PWR_MODULE_ENABLED -#include "stm32wbxx_hal_pwr.h" -#endif /* HAL_PWR_MODULE_ENABLED */ - -#ifdef HAL_QSPI_MODULE_ENABLED -#include "stm32wbxx_hal_qspi.h" -#endif /* HAL_QSPI_MODULE_ENABLED */ - -#ifdef HAL_RCC_MODULE_ENABLED -#include "stm32wbxx_hal_rcc.h" -#endif /* HAL_RCC_MODULE_ENABLED */ - -#ifdef HAL_RNG_MODULE_ENABLED -#include "stm32wbxx_hal_rng.h" -#endif /* HAL_RNG_MODULE_ENABLED */ - -#ifdef HAL_RTC_MODULE_ENABLED -#include "stm32wbxx_hal_rtc.h" -#endif /* HAL_RTC_MODULE_ENABLED */ - -#ifdef HAL_SAI_MODULE_ENABLED -#include "stm32wbxx_hal_sai.h" -#endif /* HAL_SAI_MODULE_ENABLED */ - -#ifdef HAL_SMARTCARD_MODULE_ENABLED -#include "stm32wbxx_hal_smartcard.h" -#endif /* HAL_SMARTCARD_MODULE_ENABLED */ - -#ifdef HAL_SMBUS_MODULE_ENABLED -#include "stm32wbxx_hal_smbus.h" -#endif /* HAL_SMBUS_MODULE_ENABLED */ - -#ifdef HAL_SPI_MODULE_ENABLED -#include "stm32wbxx_hal_spi.h" -#endif /* HAL_SPI_MODULE_ENABLED */ - -#ifdef HAL_TIM_MODULE_ENABLED -#include "stm32wbxx_hal_tim.h" -#endif /* HAL_TIM_MODULE_ENABLED */ - -#ifdef HAL_TSC_MODULE_ENABLED -#include "stm32wbxx_hal_tsc.h" -#endif /* HAL_TSC_MODULE_ENABLED */ - -#ifdef HAL_UART_MODULE_ENABLED -#include "stm32wbxx_hal_uart.h" -#endif /* HAL_UART_MODULE_ENABLED */ - -#ifdef HAL_USART_MODULE_ENABLED -#include "stm32wbxx_hal_usart.h" -#endif /* HAL_USART_MODULE_ENABLED */ - -#ifdef HAL_WWDG_MODULE_ENABLED -#include "stm32wbxx_hal_wwdg.h" -#endif /* HAL_WWDG_MODULE_ENABLED */ - -/* Exported macro ------------------------------------------------------------*/ -#ifdef USE_FULL_ASSERT -#define assert_param(expr) ((expr) ? (void)0U : assert_failed()) -void assert_failed(); -#else -#define assert_param(expr) ((void)0U) -#endif /* USE_FULL_ASSERT */ - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32WBxx_HAL_CONF_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/Inc/stm32wbxx_it.h b/firmware/targets/f7/Inc/stm32wbxx_it.h deleted file mode 100644 index d66e6e08..00000000 --- a/firmware/targets/f7/Inc/stm32wbxx_it.h +++ /dev/null @@ -1,69 +0,0 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file stm32wbxx_it.h - * @brief This file contains the headers of the interrupt handlers. - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2020 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __STM32WBxx_IT_H -#define __STM32WBxx_IT_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* Private includes ----------------------------------------------------------*/ -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -/* Exported types ------------------------------------------------------------*/ -/* USER CODE BEGIN ET */ - -/* USER CODE END ET */ - -/* Exported constants --------------------------------------------------------*/ -/* USER CODE BEGIN EC */ - -/* USER CODE END EC */ - -/* Exported macro ------------------------------------------------------------*/ -/* USER CODE BEGIN EM */ - -/* USER CODE END EM */ - -/* Exported functions prototypes ---------------------------------------------*/ -void SysTick_Handler(void); -void ADC1_IRQHandler(void); -void USB_LP_IRQHandler(void); -void COMP_IRQHandler(void); -void TIM1_UP_TIM16_IRQHandler(void); -void TIM1_TRG_COM_TIM17_IRQHandler(void); -void TIM1_CC_IRQHandler(void); -void TIM2_IRQHandler(void); -void HSEM_IRQHandler(void); -/* USER CODE BEGIN EFP */ - -/* USER CODE END EFP */ - -#ifdef __cplusplus -} -#endif - -#endif /* __STM32WBxx_IT_H */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/Src/gpio.c b/firmware/targets/f7/Src/gpio.c deleted file mode 100644 index 2bf2096b..00000000 --- a/firmware/targets/f7/Src/gpio.c +++ /dev/null @@ -1,131 +0,0 @@ -#include "gpio.h" - -void MX_GPIO_Init(void) { - GPIO_InitTypeDef GPIO_InitStruct = {0}; - - /*Configure GPIO pin : PtPin */ - GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; - GPIO_InitStruct.Pull = GPIO_PULLUP; - GPIO_InitStruct.Pin = BUTTON_BACK_Pin; - HAL_GPIO_Init(BUTTON_BACK_GPIO_Port, &GPIO_InitStruct); - - /*Configure GPIO pin : PtPin */ - GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Pin = BUTTON_OK_Pin; - HAL_GPIO_Init(BUTTON_OK_GPIO_Port, &GPIO_InitStruct); - - /*Configure GPIO pins : PCPin PCPin PCPin PCPin */ - GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Pin = PC0_Pin; - HAL_GPIO_Init(PC0_GPIO_Port, &GPIO_InitStruct); - GPIO_InitStruct.Pin = PC1_Pin; - HAL_GPIO_Init(PC1_GPIO_Port, &GPIO_InitStruct); - GPIO_InitStruct.Pin = PC3_Pin; - HAL_GPIO_Init(PC3_GPIO_Port, &GPIO_InitStruct); - GPIO_InitStruct.Pin = VIBRO_Pin; - HAL_GPIO_Init(VIBRO_GPIO_Port, &GPIO_InitStruct); - - /* RF_SW_0 */ - HAL_GPIO_WritePin(RF_SW_0_GPIO_Port, RF_SW_0_Pin, GPIO_PIN_RESET); - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.Pin = RF_SW_0_Pin; - HAL_GPIO_Init(RF_SW_0_GPIO_Port, &GPIO_InitStruct); - - /* PERIPH_POWER */ - HAL_GPIO_WritePin(PERIPH_POWER_GPIO_Port, PERIPH_POWER_Pin, GPIO_PIN_SET); - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.Pin = PERIPH_POWER_Pin; - HAL_GPIO_Init(PERIPH_POWER_GPIO_Port, &GPIO_InitStruct); - - /*Configure GPIO pins : PAPin PAPin PAPin */ - GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Pin = PA4_Pin; - HAL_GPIO_Init(PA4_GPIO_Port, &GPIO_InitStruct); - GPIO_InitStruct.Pin = PA6_Pin; - HAL_GPIO_Init(PA6_GPIO_Port, &GPIO_InitStruct); - GPIO_InitStruct.Pin = PA7_Pin; - HAL_GPIO_Init(PA7_GPIO_Port, &GPIO_InitStruct); - - /*Configure GPIO pin : PtPin */ - GPIO_InitStruct.Pin = RFID_PULL_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; - GPIO_InitStruct.Pull = GPIO_NOPULL; - HAL_GPIO_Init(RFID_PULL_GPIO_Port, &GPIO_InitStruct); - - /*Configure GPIO pins : PBPin PBPin PBPin */ - GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Pin = PB2_Pin; - HAL_GPIO_Init(PB2_GPIO_Port, &GPIO_InitStruct); - GPIO_InitStruct.Pin = iBTN_Pin; - HAL_GPIO_Init(iBTN_GPIO_Port, &GPIO_InitStruct); - GPIO_InitStruct.Pin = PB3_Pin; - HAL_GPIO_Init(PB3_GPIO_Port, &GPIO_InitStruct); - - /*Configure GPIO pins : PBPin PBPin PBPin PBPin */ - GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; - GPIO_InitStruct.Pull = GPIO_PULLUP; - GPIO_InitStruct.Pin = BUTTON_UP_Pin; - HAL_GPIO_Init(BUTTON_UP_GPIO_Port, &GPIO_InitStruct); - GPIO_InitStruct.Pin = BUTTON_LEFT_Pin; - HAL_GPIO_Init(BUTTON_LEFT_GPIO_Port, &GPIO_InitStruct); - GPIO_InitStruct.Pin = BUTTON_RIGHT_Pin; - HAL_GPIO_Init(BUTTON_RIGHT_GPIO_Port, &GPIO_InitStruct); - - /*Configure GPIO pins : PBPin PBPin PBPin PBPin */ - GPIO_InitStruct.Pin = BUTTON_DOWN_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING; - GPIO_InitStruct.Pull = GPIO_PULLUP; - HAL_GPIO_Init(BUTTON_DOWN_GPIO_Port, &GPIO_InitStruct); - - /* DISPLAY_RST */ - HAL_GPIO_WritePin(DISPLAY_RST_GPIO_Port, DISPLAY_RST_Pin, GPIO_PIN_RESET); - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.Pin = DISPLAY_RST_Pin; - HAL_GPIO_Init(DISPLAY_RST_GPIO_Port, &GPIO_InitStruct); - - /* DISPLAY_DI */ - HAL_GPIO_WritePin(DISPLAY_DI_GPIO_Port, DISPLAY_DI_Pin, GPIO_PIN_RESET); - GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; - GPIO_InitStruct.Pin = DISPLAY_DI_Pin; - HAL_GPIO_Init(DISPLAY_DI_GPIO_Port, &GPIO_InitStruct); - - /* SD_CD */ - GPIO_InitStruct.Pin = SD_CD_Pin; - GPIO_InitStruct.Mode = GPIO_MODE_INPUT; - GPIO_InitStruct.Pull = GPIO_NOPULL; - HAL_GPIO_Init(SD_CD_GPIO_Port, &GPIO_InitStruct); - - /* Enable all NVIC lines related to gpio */ - HAL_NVIC_SetPriority(EXTI0_IRQn, 5, 0); - HAL_NVIC_EnableIRQ(EXTI0_IRQn); - - HAL_NVIC_SetPriority(EXTI1_IRQn, 5, 0); - HAL_NVIC_EnableIRQ(EXTI1_IRQn); - - HAL_NVIC_SetPriority(EXTI2_IRQn, 5, 0); - HAL_NVIC_EnableIRQ(EXTI2_IRQn); - - HAL_NVIC_SetPriority(EXTI3_IRQn, 5, 0); - HAL_NVIC_EnableIRQ(EXTI3_IRQn); - - HAL_NVIC_SetPriority(EXTI4_IRQn, 5, 0); - HAL_NVIC_EnableIRQ(EXTI4_IRQn); - - HAL_NVIC_SetPriority(EXTI9_5_IRQn, 5, 0); - HAL_NVIC_EnableIRQ(EXTI9_5_IRQn); - - HAL_NVIC_SetPriority(EXTI15_10_IRQn, 5, 0); - HAL_NVIC_EnableIRQ(EXTI15_10_IRQn); -} diff --git a/firmware/targets/f7/Src/main.c b/firmware/targets/f7/Src/main.c index a265c4c1..2dcaab92 100644 --- a/firmware/targets/f7/Src/main.c +++ b/firmware/targets/f7/Src/main.c @@ -1,5 +1,3 @@ -#include "main.h" - #include #include #include @@ -13,9 +11,6 @@ int main(void) { // Initialize FURI layer furi_init(); - // Initialize ST HAL - HAL_Init(); - // Flipper FURI HAL furi_hal_init(); @@ -32,20 +27,3 @@ int main(void) { while(1) { } } - -void Error_Handler(void) { - furi_crash("ErrorHandler"); -} - -#ifdef USE_FULL_ASSERT -/** - * @brief Reports the name of the source file and the source line number - * where the assert_param error has occurred. - * @param file: pointer to the source file name - * @param line: assert_param error line source number - * @retval None - */ -void assert_failed(uint8_t* file, uint32_t line) { - furi_crash("HAL assert failed"); -} -#endif /* USE_FULL_ASSERT */ diff --git a/firmware/targets/f7/Src/stm32wbxx_hal_msp.c b/firmware/targets/f7/Src/stm32wbxx_hal_msp.c deleted file mode 100644 index 2ee7186d..00000000 --- a/firmware/targets/f7/Src/stm32wbxx_hal_msp.c +++ /dev/null @@ -1,11 +0,0 @@ -#include "main.h" - -void HAL_MspInit(void) { - HAL_NVIC_SetPriority(PendSV_IRQn, 15, 0); - - HAL_NVIC_SetPriority(RCC_IRQn, 5, 0); - HAL_NVIC_EnableIRQ(RCC_IRQn); - - HAL_NVIC_SetPriority(HSEM_IRQn, 5, 0); - HAL_NVIC_EnableIRQ(HSEM_IRQn); -} diff --git a/firmware/targets/f7/Src/stm32wbxx_it.c b/firmware/targets/f7/Src/stm32wbxx_it.c deleted file mode 100644 index 20d96e88..00000000 --- a/firmware/targets/f7/Src/stm32wbxx_it.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "main.h" -#include "stm32wbxx_it.h" -#include "FreeRTOS.h" -#include "task.h" -#include "usbd_core.h" - -extern usbd_device udev; - -extern void HW_TS_RTC_Wakeup_Handler(); -extern void HW_IPCC_Tx_Handler(); -extern void HW_IPCC_Rx_Handler(); - -void SysTick_Handler(void) { - HAL_IncTick(); -} - -void USB_LP_IRQHandler(void) { - usbd_poll(&udev); -} - -void HSEM_IRQHandler(void) { - HAL_HSEM_IRQHandler(); -} - -void IPCC_C1_TX_IRQHandler(void) { - HW_IPCC_Tx_Handler(); -} - -void IPCC_C1_RX_IRQHandler(void) { - HW_IPCC_Rx_Handler(); -} diff --git a/firmware/targets/f7/Src/system_stm32wbxx.c b/firmware/targets/f7/Src/system_stm32wbxx.c index 5b42c579..9fc52ca7 100644 --- a/firmware/targets/f7/Src/system_stm32wbxx.c +++ b/firmware/targets/f7/Src/system_stm32wbxx.c @@ -1,126 +1,5 @@ -/** - ****************************************************************************** - * @file system_stm32wbxx.c - * @author MCD Application Team - * @brief CMSIS Cortex Device Peripheral Access Layer System Source File - * - * This file provides two functions and one global variable to be called from - * user application: - * - SystemInit(): This function is called at startup just after reset and - * before branch to main program. This call is made inside - * the "startup_stm32wbxx.s" file. - * - * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used - * by the user application to setup the SysTick - * timer or configure other parameters. - * - * - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must - * be called whenever the core clock is changed - * during program execution. - * - * After each device reset the MSI (4 MHz) is used as system clock source. - * Then SystemInit() function is called, in "startup_stm32wbxx.s" file, to - * configure the system clock before to branch to main program. - * - * This file configures the system clock as follows: - *============================================================================= - *----------------------------------------------------------------------------- - * System Clock source | MSI - *----------------------------------------------------------------------------- - * SYSCLK(Hz) | 4000000 - *----------------------------------------------------------------------------- - * HCLK(Hz) | 4000000 - *----------------------------------------------------------------------------- - * AHB Prescaler | 1 - *----------------------------------------------------------------------------- - * APB1 Prescaler | 1 - *----------------------------------------------------------------------------- - * APB2 Prescaler | 1 - *----------------------------------------------------------------------------- - * PLL_M | 1 - *----------------------------------------------------------------------------- - * PLL_N | 8 - *----------------------------------------------------------------------------- - * PLL_P | 7 - *----------------------------------------------------------------------------- - * PLL_Q | 2 - *----------------------------------------------------------------------------- - * PLL_R | 2 - *----------------------------------------------------------------------------- - * PLLSAI1_P | NA - *----------------------------------------------------------------------------- - * PLLSAI1_Q | NA - *----------------------------------------------------------------------------- - * PLLSAI1_R | NA - *----------------------------------------------------------------------------- - * Require 48MHz for USB OTG FS, | Disabled - * SDIO and RNG clock | - *----------------------------------------------------------------------------- - *============================================================================= - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2019 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under BSD 3-Clause license, - * the "License"; You may not use this file except in compliance with the - * License. You may obtain a copy of the License at: - * opensource.org/licenses/BSD-3-Clause - * - ****************************************************************************** - */ - -/** @addtogroup CMSIS - * @{ - */ - -/** @addtogroup stm32WBxx_system - * @{ - */ - -/** @addtogroup stm32WBxx_System_Private_Includes - * @{ - */ - #include "stm32wbxx.h" -#if !defined(HSE_VALUE) -#define HSE_VALUE (32000000UL) /*!< Value of the External oscillator in Hz */ -#endif /* HSE_VALUE */ - -#if !defined(MSI_VALUE) -#define MSI_VALUE (4000000UL) /*!< Value of the Internal oscillator in Hz*/ -#endif /* MSI_VALUE */ - -#if !defined(HSI_VALUE) -#define HSI_VALUE (16000000UL) /*!< Value of the Internal oscillator in Hz*/ -#endif /* HSI_VALUE */ - -#if !defined(LSI_VALUE) -#define LSI_VALUE (32000UL) /*!< Value of LSI in Hz*/ -#endif /* LSI_VALUE */ - -#if !defined(LSE_VALUE) -#define LSE_VALUE (32768UL) /*!< Value of LSE in Hz*/ -#endif /* LSE_VALUE */ - -/** - * @} - */ - -/** @addtogroup STM32WBxx_System_Private_TypesDefinitions - * @{ - */ - -/** - * @} - */ - -/** @addtogroup STM32WBxx_System_Private_Defines - * @{ - */ - /*!< Uncomment the following line if you need to relocate your vector Table in Internal SRAM. */ /* #define VECT_TAB_SRAM */ @@ -131,21 +10,7 @@ #define VECT_TAB_BASE_ADDRESS \ SRAM1_BASE /*!< Vector Table base offset field. This value must be a multiple of 0x200. */ -/** - * @} - */ -/** @addtogroup STM32WBxx_System_Private_Macros - * @{ - */ - -/** - * @} - */ - -/** @addtogroup STM32WBxx_System_Private_Variables - * @{ - */ /* The SystemCoreClock variable is updated in three ways: 1) by calling CMSIS function SystemCoreClockUpdate() 2) by calling HAL API function HAL_RCC_GetHCLKFreq() @@ -179,30 +44,6 @@ const uint32_t MSIRangeTable[16UL] = { 0UL, 0UL}; /* 0UL values are incorrect cases */ -#if defined(STM32WB55xx) || defined(STM32WB5Mxx) || defined(STM32WB35xx) -const uint32_t SmpsPrescalerTable[4UL][6UL] = { - {1UL, 3UL, 2UL, 2UL, 1UL, 2UL}, - {2UL, 6UL, 4UL, 3UL, 2UL, 4UL}, - {4UL, 12UL, 8UL, 6UL, 4UL, 8UL}, - {4UL, 12UL, 8UL, 6UL, 4UL, 8UL}}; -#endif - -/** - * @} - */ - -/** @addtogroup STM32WBxx_System_Private_FunctionPrototypes - * @{ - */ - -/** - * @} - */ - -/** @addtogroup STM32WBxx_System_Private_Functions - * @{ - */ - /** * @brief Setup the microcontroller system. * @param None @@ -254,118 +95,3 @@ void SystemInit(void) { /* Disable all interrupts */ RCC->CIER = 0x00000000; } - -/** - * @brief Update SystemCoreClock variable according to Clock Register Values. - * The SystemCoreClock variable contains the core clock (HCLK), it can - * be used by the user application to setup the SysTick timer or configure - * other parameters. - * - * @note Each time the core clock (HCLK) changes, this function must be called - * to update SystemCoreClock variable value. Otherwise, any configuration - * based on this variable will be incorrect. - * - * @note - The system frequency computed by this function is not the real - * frequency in the chip. It is calculated based on the predefined - * constant and the selected clock source: - * - * - If SYSCLK source is MSI, SystemCoreClock will contain the MSI_VALUE(*) - * - * - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**) - * - * - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***) - * - * - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(***) - * or HSI_VALUE(*) or MSI_VALUE(*) multiplied/divided by the PLL factors. - * - * (*) MSI_VALUE is a constant defined in stm32wbxx_hal.h file (default value - * 4 MHz) but the real value may vary depending on the variations - * in voltage and temperature. - * - * (**) HSI_VALUE is a constant defined in stm32wbxx_hal_conf.h file (default value - * 16 MHz) but the real value may vary depending on the variations - * in voltage and temperature. - * - * (***) HSE_VALUE is a constant defined in stm32wbxx_hal_conf.h file (default value - * 32 MHz), user has to ensure that HSE_VALUE is same as the real - * frequency of the crystal used. Otherwise, this function may - * have wrong result. - * - * - The result of this function could be not correct when using fractional - * value for HSE crystal. - * - * @param None - * @retval None - */ -void SystemCoreClockUpdate(void) { - uint32_t tmp, msirange, pllvco, pllr, pllsource, pllm; - - /* Get MSI Range frequency--------------------------------------------------*/ - - /*MSI frequency range in Hz*/ - msirange = MSIRangeTable[(RCC->CR & RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos]; - - /* Get SYSCLK source -------------------------------------------------------*/ - switch(RCC->CFGR & RCC_CFGR_SWS) { - case 0x00: /* MSI used as system clock source */ - SystemCoreClock = msirange; - break; - - case 0x04: /* HSI used as system clock source */ - /* HSI used as system clock source */ - SystemCoreClock = HSI_VALUE; - break; - - case 0x08: /* HSE used as system clock source */ - SystemCoreClock = HSE_VALUE; - break; - - case 0x0C: /* PLL used as system clock source */ - /* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN - SYSCLK = PLL_VCO / PLLR - */ - pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC); - pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1UL; - - if(pllsource == 0x02UL) /* HSI used as PLL clock source */ - { - pllvco = (HSI_VALUE / pllm); - } else if(pllsource == 0x03UL) /* HSE used as PLL clock source */ - { - pllvco = (HSE_VALUE / pllm); - } else /* MSI used as PLL clock source */ - { - pllvco = (msirange / pllm); - } - - pllvco = pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos); - pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1UL); - - SystemCoreClock = pllvco / pllr; - break; - - default: - SystemCoreClock = msirange; - break; - } - - /* Compute HCLK clock frequency --------------------------------------------*/ - /* Get HCLK1 prescaler */ - tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos)]; - /* HCLK clock frequency */ - SystemCoreClock = SystemCoreClock / tmp; -} - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/ble_glue/app_debug.c b/firmware/targets/f7/ble_glue/app_debug.c index 8c1541c9..41d66704 100644 --- a/firmware/targets/f7/ble_glue/app_debug.c +++ b/firmware/targets/f7/ble_glue/app_debug.c @@ -149,29 +149,30 @@ void APPD_Init(void) { /** * Keep debugger enabled while in any low power mode */ - HAL_DBGMCU_EnableDBGSleepMode(); - HAL_DBGMCU_EnableDBGStopMode(); + LL_DBGMCU_EnableDBGSleepMode(); + LL_DBGMCU_EnableDBGStopMode(); /***************** ENABLE DEBUGGER *************************************/ LL_EXTI_EnableIT_32_63(LL_EXTI_LINE_48); #else - GPIO_InitTypeDef gpio_config = {0}; + LL_GPIO_InitTypeDef gpio_config = {0}; + LL_PWR_EnableVddUSB(); - gpio_config.Pull = GPIO_NOPULL; - gpio_config.Mode = GPIO_MODE_ANALOG; + gpio_config.Mode = LL_GPIO_MODE_ANALOG; + gpio_config.Speed = LL_GPIO_SPEED_FREQ_LOW; + // gpio_config.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + // gpio_config.Pull = LL_GPIO_PULL_NO; + // gpio_config.Alternate = LL_GPIO_AF_10; + gpio_config.Pin = LL_GPIO_PIN_15 | LL_GPIO_PIN_14 | LL_GPIO_PIN_13; + LL_GPIO_Init(GPIOA, &gpio_config); - gpio_config.Pin = GPIO_PIN_15 | GPIO_PIN_14 | GPIO_PIN_13; - __HAL_RCC_GPIOA_CLK_ENABLE(); - HAL_GPIO_Init(GPIOA, &gpio_config); + gpio_config.Pin = LL_GPIO_PIN_4 | LL_GPIO_PIN_3; + LL_GPIO_Init(GPIOB, &gpio_config); - gpio_config.Pin = GPIO_PIN_4 | GPIO_PIN_3; - __HAL_RCC_GPIOB_CLK_ENABLE(); - HAL_GPIO_Init(GPIOB, &gpio_config); - - HAL_DBGMCU_DisableDBGSleepMode(); - HAL_DBGMCU_DisableDBGStopMode(); - HAL_DBGMCU_DisableDBGStandbyMode(); + LL_DBGMCU_DisableDBGSleepMode(); + LL_DBGMCU_DisableDBGStopMode(); + LL_DBGMCU_DisableDBGStandbyMode(); #endif /* (CFG_DEBUGGER_SUPPORTED == 1) */ @@ -203,12 +204,12 @@ void APPD_EnableCPU2(void) { /** GPIO DEBUG Initialization */ SHCI_C2_DEBUG_Init(&DebugCmdPacket); - // GPIO_InitTypeDef GPIO_InitStruct; - // GPIO_InitStruct.Pull = GPIO_NOPULL; - // GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; - // GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - // GPIO_InitStruct.Pin = LL_GPIO_PIN_3; - // HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); + // LL_GPIO_InitTypeDef gpio_config; + // gpio_config.Pull = GPIO_NOPULL; + // gpio_config.Mode = GPIO_MODE_OUTPUT_PP; + // gpio_config.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + // gpio_config.Pin = LL_GPIO_PIN_3; + // HAL_GPIO_Init(GPIOC, &gpio_config); // SHCI_C2_ExtpaConfig((uint32_t)GPIOC, LL_GPIO_PIN_3, EXT_PA_ENABLED_LOW, EXT_PA_ENABLED); /* USER CODE END APPD_EnableCPU2 */ @@ -222,7 +223,7 @@ void APPD_EnableCPU2(void) { *************************************************************/ static void APPD_SetCPU2GpioConfig(void) { /* USER CODE BEGIN APPD_SetCPU2GpioConfig */ - GPIO_InitTypeDef gpio_config = {0}; + LL_GPIO_InitTypeDef gpio_config = {0}; uint8_t local_loop; uint16_t gpioa_pin_list; uint16_t gpiob_pin_list; @@ -253,32 +254,33 @@ static void APPD_SetCPU2GpioConfig(void) { } } - gpio_config.Pull = GPIO_NOPULL; - gpio_config.Mode = GPIO_MODE_OUTPUT_PP; - gpio_config.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + gpio_config.Mode = LL_GPIO_MODE_OUTPUT; + gpio_config.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; + gpio_config.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + gpio_config.Pull = LL_GPIO_PULL_NO; + + gpio_config.Pin = LL_GPIO_PIN_15 | LL_GPIO_PIN_14 | LL_GPIO_PIN_13; + LL_GPIO_Init(GPIOA, &gpio_config); if(gpioa_pin_list != 0) { gpio_config.Pin = gpioa_pin_list; - __HAL_RCC_GPIOA_CLK_ENABLE(); - __HAL_RCC_C2GPIOA_CLK_ENABLE(); - HAL_GPIO_Init(GPIOA, &gpio_config); - HAL_GPIO_WritePin(GPIOA, gpioa_pin_list, GPIO_PIN_RESET); + LL_C2_AHB2_GRP1_EnableClock(LL_C2_AHB2_GRP1_PERIPH_GPIOA); + LL_GPIO_Init(GPIOA, &gpio_config); + LL_GPIO_ResetOutputPin(GPIOA, gpioa_pin_list); } if(gpiob_pin_list != 0) { gpio_config.Pin = gpiob_pin_list; - __HAL_RCC_GPIOB_CLK_ENABLE(); - __HAL_RCC_C2GPIOB_CLK_ENABLE(); - HAL_GPIO_Init(GPIOB, &gpio_config); - HAL_GPIO_WritePin(GPIOB, gpiob_pin_list, GPIO_PIN_RESET); + LL_C2_AHB2_GRP1_EnableClock(LL_C2_AHB2_GRP1_PERIPH_GPIOB); + LL_GPIO_Init(GPIOB, &gpio_config); + LL_GPIO_ResetOutputPin(GPIOB, gpioa_pin_list); } if(gpioc_pin_list != 0) { gpio_config.Pin = gpioc_pin_list; - __HAL_RCC_GPIOC_CLK_ENABLE(); - __HAL_RCC_C2GPIOC_CLK_ENABLE(); - HAL_GPIO_Init(GPIOC, &gpio_config); - HAL_GPIO_WritePin(GPIOC, gpioc_pin_list, GPIO_PIN_RESET); + LL_C2_AHB2_GRP1_EnableClock(LL_C2_AHB2_GRP1_PERIPH_GPIOC); + LL_GPIO_Init(GPIOC, &gpio_config); + LL_GPIO_ResetOutputPin(GPIOC, gpioa_pin_list); } /* USER CODE END APPD_SetCPU2GpioConfig */ @@ -288,7 +290,7 @@ static void APPD_SetCPU2GpioConfig(void) { static void APPD_BleDtbCfg(void) { /* USER CODE BEGIN APPD_BleDtbCfg */ #if(BLE_DTB_CFG != 0) - GPIO_InitTypeDef gpio_config = {0}; + LL_GPIO_InitTypeDef gpio_config = {0}; uint8_t local_loop; uint16_t gpioa_pin_list; uint16_t gpiob_pin_list; @@ -313,23 +315,23 @@ static void APPD_BleDtbCfg(void) { } } - gpio_config.Pull = GPIO_NOPULL; - gpio_config.Mode = GPIO_MODE_AF_PP; - gpio_config.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - gpio_config.Alternate = GPIO_AF6_RF_DTB7; + gpio_config.Mode = LL_GPIO_MODE_ALTERNATE; + gpio_config.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH; + gpio_config.OutputType = LL_GPIO_OUTPUT_PUSHPULL; + gpio_config.Pull = LL_GPIO_PULL_NO; + gpio_config.Alternate = LL_GPIO_AF_6; + gpio_config.Pin = LL_GPIO_PIN_15 | LL_GPIO_PIN_14 | LL_GPIO_PIN_13; if(gpioa_pin_list != 0) { gpio_config.Pin = gpioa_pin_list; - __HAL_RCC_GPIOA_CLK_ENABLE(); - __HAL_RCC_C2GPIOA_CLK_ENABLE(); - HAL_GPIO_Init(GPIOA, &gpio_config); + LL_C2_AHB2_GRP1_EnableClock(LL_C2_AHB2_GRP1_PERIPH_GPIOA); + LL_GPIO_Init(GPIOA, &gpio_config); } if(gpiob_pin_list != 0) { gpio_config.Pin = gpiob_pin_list; - __HAL_RCC_GPIOB_CLK_ENABLE(); - __HAL_RCC_C2GPIOB_CLK_ENABLE(); - HAL_GPIO_Init(GPIOB, &gpio_config); + LL_C2_AHB2_GRP1_EnableClock(LL_C2_AHB2_GRP1_PERIPH_GPIOB); + LL_GPIO_Init(GPIOB, &gpio_config); } #endif diff --git a/firmware/targets/f7/ble_glue/battery_service.c b/firmware/targets/f7/ble_glue/battery_service.c index 1ee155bb..85f1eeea 100644 --- a/firmware/targets/f7/ble_glue/battery_service.c +++ b/firmware/targets/f7/ble_glue/battery_service.c @@ -71,7 +71,7 @@ bool battery_svc_update_level(uint8_t battery_charge) { return false; } // Update battery level characteristic - FURI_LOG_I(TAG, "Updating battery level characteristic"); + FURI_LOG_D(TAG, "Updating battery level characteristic"); tBleStatus result = aci_gatt_update_char_value( battery_svc->svc_handle, battery_svc->char_level_handle, 0, 1, &battery_charge); if(result) { diff --git a/firmware/targets/f7/ble_glue/ble_app.c b/firmware/targets/f7/ble_glue/ble_app.c index 052b3a9f..d76b4e7b 100644 --- a/firmware/targets/f7/ble_glue/ble_app.c +++ b/firmware/targets/f7/ble_glue/ble_app.c @@ -24,7 +24,6 @@ typedef struct { osMutexId_t hci_mtx; osSemaphoreId_t hci_sem; FuriThread* thread; - osEventFlagsId_t event_flags; } BleApp; static BleApp* ble_app = NULL; @@ -39,7 +38,6 @@ bool ble_app_init() { // Allocate semafore and mutex for ble command buffer access ble_app->hci_mtx = osMutexNew(NULL); ble_app->hci_sem = osSemaphoreNew(1, 0, NULL); - ble_app->event_flags = osEventFlagsNew(NULL); // HCI transport layer thread to handle user asynch events ble_app->thread = furi_thread_alloc(); furi_thread_set_name(ble_app->thread, "BleHciDriver"); @@ -108,15 +106,14 @@ void ble_app_get_key_storage_buff(uint8_t** addr, uint16_t* size) { void ble_app_thread_stop() { if(ble_app) { - osEventFlagsSet(ble_app->event_flags, BLE_APP_FLAG_KILL_THREAD); + osThreadId_t thread_id = furi_thread_get_thread_id(ble_app->thread); + furi_assert(thread_id); + osThreadFlagsSet(thread_id, BLE_APP_FLAG_KILL_THREAD); furi_thread_join(ble_app->thread); furi_thread_free(ble_app->thread); - // Wait to make sure that EventFlags delivers pending events before memory free - osDelay(50); // Free resources osMutexDelete(ble_app->hci_mtx); osSemaphoreDelete(ble_app->hci_sem); - osEventFlagsDelete(ble_app->event_flags); free(ble_app); ble_app = NULL; memset(&ble_app_cmd_buffer, 0, sizeof(ble_app_cmd_buffer)); @@ -125,9 +122,9 @@ void ble_app_thread_stop() { static int32_t ble_app_hci_thread(void* arg) { uint32_t flags = 0; + while(1) { - flags = osEventFlagsWait( - ble_app->event_flags, BLE_APP_FLAG_ALL, osFlagsWaitAny, osWaitForever); + flags = osThreadFlagsWait(BLE_APP_FLAG_ALL, osFlagsWaitAny, osWaitForever); if(flags & BLE_APP_FLAG_KILL_THREAD) { break; } @@ -142,7 +139,9 @@ static int32_t ble_app_hci_thread(void* arg) { // Called by WPAN lib void hci_notify_asynch_evt(void* pdata) { if(ble_app) { - osEventFlagsSet(ble_app->event_flags, BLE_APP_FLAG_HCI_EVENT); + osThreadId_t thread_id = furi_thread_get_thread_id(ble_app->thread); + furi_assert(thread_id); + osThreadFlagsSet(thread_id, BLE_APP_FLAG_HCI_EVENT); } } diff --git a/firmware/targets/f7/ble_glue/ble_conf.h b/firmware/targets/f7/ble_glue/ble_conf.h index 97650670..a04d1def 100644 --- a/firmware/targets/f7/ble_glue/ble_conf.h +++ b/firmware/targets/f7/ble_glue/ble_conf.h @@ -23,6 +23,10 @@ #include "app_conf.h" +#ifndef __weak +#define __weak __attribute__((weak)) +#endif + /****************************************************************************** * * BLE SERVICES CONFIGURATION diff --git a/firmware/targets/f7/ble_glue/ble_glue.c b/firmware/targets/f7/ble_glue/ble_glue.c index a509a96e..9142a261 100644 --- a/firmware/targets/f7/ble_glue/ble_glue.c +++ b/firmware/targets/f7/ble_glue/ble_glue.c @@ -1,6 +1,5 @@ #include "ble_glue.h" #include "app_common.h" -#include "main.h" #include "ble_app.h" #include "ble.h" #include "tl.h" @@ -41,7 +40,6 @@ typedef enum { typedef struct { osMutexId_t shci_mtx; osSemaphoreId_t shci_sem; - osEventFlagsId_t event_flags; FuriThread* thread; BleGlueStatus status; BleGlueKeyStorageChangedCallback callback; @@ -84,7 +82,6 @@ void ble_glue_init() { ble_glue->shci_mtx = osMutexNew(NULL); ble_glue->shci_sem = osSemaphoreNew(1, 0, NULL); - ble_glue->event_flags = osEventFlagsNew(NULL); // FreeRTOS system task creation ble_glue->thread = furi_thread_alloc(); @@ -258,15 +255,14 @@ static void ble_glue_clear_shared_memory() { void ble_glue_thread_stop() { if(ble_glue) { - osEventFlagsSet(ble_glue->event_flags, BLE_GLUE_FLAG_KILL_THREAD); + osThreadId_t thread_id = furi_thread_get_thread_id(ble_glue->thread); + furi_assert(thread_id); + osThreadFlagsSet(thread_id, BLE_GLUE_FLAG_KILL_THREAD); furi_thread_join(ble_glue->thread); furi_thread_free(ble_glue->thread); - // Wait to make sure that EventFlags delivers pending events before memory free - osDelay(50); // Free resources osMutexDelete(ble_glue->shci_mtx); osSemaphoreDelete(ble_glue->shci_sem); - osEventFlagsDelete(ble_glue->event_flags); ble_glue_clear_shared_memory(); free(ble_glue); ble_glue = NULL; @@ -276,9 +272,9 @@ void ble_glue_thread_stop() { // Wrap functions static int32_t ble_glue_shci_thread(void* context) { uint32_t flags = 0; + while(true) { - flags = osEventFlagsWait( - ble_glue->event_flags, BLE_GLUE_FLAG_ALL, osFlagsWaitAny, osWaitForever); + flags = osThreadFlagsWait(BLE_GLUE_FLAG_ALL, osFlagsWaitAny, osWaitForever); if(flags & BLE_GLUE_FLAG_SHCI_EVENT) { shci_user_evt_proc(); } @@ -293,7 +289,9 @@ static int32_t ble_glue_shci_thread(void* context) { void shci_notify_asynch_evt(void* pdata) { UNUSED(pdata); if(ble_glue) { - osEventFlagsSet(ble_glue->event_flags, BLE_GLUE_FLAG_SHCI_EVENT); + osThreadId_t thread_id = furi_thread_get_thread_id(ble_glue->thread); + furi_assert(thread_id); + osThreadFlagsSet(thread_id, BLE_GLUE_FLAG_SHCI_EVENT); } } diff --git a/firmware/targets/f7/ble_glue/dev_info_service.c b/firmware/targets/f7/ble_glue/dev_info_service.c old mode 100644 new mode 100755 index ebee56ba..4adfce59 --- a/firmware/targets/f7/ble_glue/dev_info_service.c +++ b/firmware/targets/f7/ble_glue/dev_info_service.c @@ -8,8 +8,6 @@ #define TAG "BtDevInfoSvc" -#define DEV_INFO_RPC_VERSION_CHAR_MAX_SIZE (10) - typedef struct { uint16_t service_handle; uint16_t man_name_char_handle; @@ -26,6 +24,7 @@ static const char dev_info_serial_num[] = "1.0"; static const char dev_info_firmware_rev_num[] = TOSTRING(TARGET); static const char dev_info_software_rev_num[] = GIT_COMMIT " " GIT_BRANCH " " GIT_BRANCH_NUM " " BUILD_DATE; +static const char dev_info_rpc_version[] = TOSTRING(PROTOBUF_MAJOR_VERSION.PROTOBUF_MINOR_VERSION); static const uint8_t dev_info_rpc_version_uuid[] = {0x33, 0xa9, 0xb5, 0x3e, 0x87, 0x5d, 0x1a, 0x8e, 0xc8, 0x47, 0x5e, 0xae, 0x6d, 0x66, 0xf6, 0x03}; @@ -107,7 +106,7 @@ void dev_info_svc_start() { dev_info_svc->service_handle, UUID_TYPE_128, (const Char_UUID_t*)dev_info_rpc_version_uuid, - DEV_INFO_RPC_VERSION_CHAR_MAX_SIZE, + strlen(dev_info_rpc_version), CHAR_PROP_READ, ATTR_PERMISSION_AUTHEN_READ, GATT_DONT_NOTIFY_EVENTS, @@ -155,18 +154,15 @@ void dev_info_svc_start() { if(status) { FURI_LOG_E(TAG, "Failed to update software revision char: %d", status); } - string_t rpc_version; - string_init_printf(rpc_version, "%d.%d", PROTOBUF_MAJOR_VERSION, PROTOBUF_MINOR_VERSION); status = aci_gatt_update_char_value( dev_info_svc->service_handle, dev_info_svc->rpc_version_char_handle, 0, - strlen(string_get_cstr(rpc_version)), - (uint8_t*)string_get_cstr(rpc_version)); + strlen(dev_info_rpc_version), + (uint8_t*)dev_info_rpc_version); if(status) { FURI_LOG_E(TAG, "Failed to update rpc version char: %d", status); } - string_clear(rpc_version); } void dev_info_svc_stop() { diff --git a/firmware/targets/f7/ble_glue/gap.c b/firmware/targets/f7/ble_glue/gap.c index c4f62855..b21095ed 100644 --- a/firmware/targets/f7/ble_glue/gap.c +++ b/firmware/targets/f7/ble_glue/gap.c @@ -10,6 +10,8 @@ #define FAST_ADV_TIMEOUT 30000 #define INITIAL_ADV_TIMEOUT 60000 +#define GAP_INTERVAL_TO_MS(x) (uint16_t)((x)*1.25) + typedef struct { uint16_t gap_svc_handle; uint16_t dev_name_char_handle; @@ -23,6 +25,7 @@ typedef struct { typedef struct { GapSvc service; GapConfig* config; + GapConnectionParams connection_params; GapState state; osMutexId_t state_mutex; GapEventCallback on_event_cb; @@ -58,6 +61,33 @@ static GapScan* gap_scan = NULL; static void gap_advertise_start(GapState new_state); static int32_t gap_app(void* context); +static void gap_verify_connection_parameters(Gap* gap) { + furi_assert(gap); + + FURI_LOG_I( + TAG, + "Connection parameters: Connection Interval: %d (%d ms), Slave Latency: %d, Supervision Timeout: %d", + gap->connection_params.conn_interval, + GAP_INTERVAL_TO_MS(gap->connection_params.conn_interval), + gap->connection_params.slave_latency, + gap->connection_params.supervisor_timeout); + + // Send connection parameters request update if necessary + GapConnectionParamsRequest* params = &gap->config->conn_param; + if(params->conn_int_min > gap->connection_params.conn_interval || + params->conn_int_max < gap->connection_params.conn_interval) { + FURI_LOG_W(TAG, "Unsupported connection interval. Request connection parameters update"); + if(aci_l2cap_connection_parameter_update_req( + gap->service.connection_handle, + params->conn_int_min, + params->conn_int_max, + gap->connection_params.slave_latency, + gap->connection_params.supervisor_timeout)) { + FURI_LOG_E(TAG, "Failed to request connection parameters update"); + } + } +} + SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { hci_event_pckt* event_pckt; evt_le_meta_event* meta_evt; @@ -97,12 +127,11 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { case EVT_LE_CONN_UPDATE_COMPLETE: { hci_le_connection_update_complete_event_rp0* event = (hci_le_connection_update_complete_event_rp0*)meta_evt->data; - FURI_LOG_I( - TAG, - "Connection interval: %d, latency: %d, supervision timeout: %d", - event->Conn_Interval, - event->Conn_Latency, - event->Supervision_Timeout); + gap->connection_params.conn_interval = event->Conn_Interval; + gap->connection_params.slave_latency = event->Conn_Latency; + gap->connection_params.supervisor_timeout = event->Supervision_Timeout; + FURI_LOG_I(TAG, "Connection parameters event complete"); + gap_verify_connection_parameters(gap); break; } @@ -124,31 +153,22 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { case EVT_LE_CONN_COMPLETE: furi_hal_power_insomnia_enter(); - hci_le_connection_complete_event_rp0* connection_complete_event = + hci_le_connection_complete_event_rp0* event = (hci_le_connection_complete_event_rp0*)meta_evt->data; - FURI_LOG_I( - TAG, - "Connection complete for connection handle 0x%x", - connection_complete_event->Connection_Handle); + gap->connection_params.conn_interval = event->Conn_Interval; + gap->connection_params.slave_latency = event->Conn_Latency; + gap->connection_params.supervisor_timeout = event->Supervision_Timeout; // Stop advertising as connection completed osTimerStop(gap->advertise_timer); // Update connection status and handle gap->state = GapStateConnected; - gap->service.connection_handle = connection_complete_event->Connection_Handle; - GapConnectionParams* params = &gap->config->conn_param; - if(aci_l2cap_connection_parameter_update_req( - gap->service.connection_handle, - params->conn_int_min, - params->conn_int_max, - params->slave_latency, - params->supervisor_timeout)) { - FURI_LOG_W(TAG, "Failed to request connection parameters update"); - } + gap->service.connection_handle = event->Connection_Handle; + gap_verify_connection_parameters(gap); // Start pairing by sending security request - aci_gap_slave_security_req(connection_complete_event->Connection_Handle); + aci_gap_slave_security_req(event->Connection_Handle); break; case EVT_LE_ADVERTISING_REPORT: { diff --git a/firmware/targets/f7/ble_glue/gap.h b/firmware/targets/f7/ble_glue/gap.h index 1a2e7962..7ad4e819 100644 --- a/firmware/targets/f7/ble_glue/gap.h +++ b/firmware/targets/f7/ble_glue/gap.h @@ -55,12 +55,18 @@ typedef enum { GapPairingPinCodeVerifyYesNo, } GapPairing; +typedef struct { + uint16_t conn_interval; + uint16_t slave_latency; + uint16_t supervisor_timeout; +} GapConnectionParams; + typedef struct { uint16_t conn_int_min; uint16_t conn_int_max; uint16_t slave_latency; uint16_t supervisor_timeout; -} GapConnectionParams; +} GapConnectionParamsRequest; typedef struct { uint16_t adv_service_uuid; @@ -69,7 +75,7 @@ typedef struct { GapPairing pairing_method; uint8_t mac_address[GAP_MAC_ADDR_SIZE]; char adv_name[FURI_HAL_VERSION_DEVICE_NAME_LENGTH]; - GapConnectionParams conn_param; + GapConnectionParamsRequest conn_param; } GapConfig; bool gap_init(GapConfig* config, GapEventCallback on_event_cb, void* context); diff --git a/firmware/targets/f7/ble_glue/hw_ipcc.c b/firmware/targets/f7/ble_glue/hw_ipcc.c index bd9c9ad6..ccdb0736 100644 --- a/firmware/targets/f7/ble_glue/hw_ipcc.c +++ b/firmware/targets/f7/ble_glue/hw_ipcc.c @@ -185,10 +185,10 @@ void HW_IPCC_Init(void) { LL_C1_IPCC_EnableIT_RXO(IPCC); LL_C1_IPCC_EnableIT_TXF(IPCC); - HAL_NVIC_SetPriority(IPCC_C1_RX_IRQn, 6, 0); - HAL_NVIC_EnableIRQ(IPCC_C1_RX_IRQn); - HAL_NVIC_SetPriority(IPCC_C1_TX_IRQn, 6, 0); - HAL_NVIC_EnableIRQ(IPCC_C1_TX_IRQn); + NVIC_SetPriority(IPCC_C1_RX_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 6, 0)); + NVIC_EnableIRQ(IPCC_C1_RX_IRQn); + NVIC_SetPriority(IPCC_C1_TX_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 6, 0)); + NVIC_EnableIRQ(IPCC_C1_TX_IRQn); return; } diff --git a/firmware/targets/f7/ble_glue/utilities_conf.h b/firmware/targets/f7/ble_glue/utilities_conf.h index 9143d4c0..9c15f226 100644 --- a/firmware/targets/f7/ble_glue/utilities_conf.h +++ b/firmware/targets/f7/ble_glue/utilities_conf.h @@ -29,15 +29,14 @@ extern "C" { #include "cmsis_compiler.h" #include "string.h" +#include /****************************************************************************** * common ******************************************************************************/ -#define UTILS_ENTER_CRITICAL_SECTION() \ - uint32_t primask_bit = __get_PRIMASK(); \ - __disable_irq() +#define UTILS_ENTER_CRITICAL_SECTION() FURI_CRITICAL_ENTER() -#define UTILS_EXIT_CRITICAL_SECTION() __set_PRIMASK(primask_bit) +#define UTILS_EXIT_CRITICAL_SECTION() FURI_CRITICAL_EXIT() #define UTILS_MEMSET8(dest, value, size) memset(dest, value, size); diff --git a/firmware/targets/f7/fatfs/ffconf.h b/firmware/targets/f7/fatfs/ffconf.h index 991e0e28..91c6c00c 100644 --- a/firmware/targets/f7/fatfs/ffconf.h +++ b/firmware/targets/f7/fatfs/ffconf.h @@ -24,9 +24,6 @@ / Additional user header to be used /-----------------------------------------------------------------------------*/ -#include "main.h" -#include "stm32wbxx_hal.h" - /*-----------------------------------------------------------------------------/ / Function Configurations /-----------------------------------------------------------------------------*/ diff --git a/firmware/targets/f7/fatfs/spi_sd_hal.c b/firmware/targets/f7/fatfs/spi_sd_hal.c index fce041cb..1b96568c 100644 --- a/firmware/targets/f7/fatfs/spi_sd_hal.c +++ b/firmware/targets/f7/fatfs/spi_sd_hal.c @@ -1,4 +1,3 @@ -#include "main.h" #include #include @@ -46,8 +45,8 @@ void SD_IO_Init(void) { uint8_t counter = 0; /* SD chip select high */ - hal_gpio_write(furi_hal_sd_spi_handle->cs, true); - delay_us(10); + furi_hal_gpio_write(furi_hal_sd_spi_handle->cs, true); + furi_hal_delay_us(10); /* Send dummy byte 0xFF, 10 times with CS high */ /* Rise CS and MOSI for 80 clocks cycles */ @@ -65,11 +64,11 @@ void SD_IO_Init(void) { void SD_IO_CSState(uint8_t val) { /* Some SD Cards are prone to fail if CLK-ed too soon after CS transition. Worst case found: 8us */ if(val == 1) { - delay_us(10); // Exit guard time for some SD cards - hal_gpio_write(furi_hal_sd_spi_handle->cs, true); + furi_hal_delay_us(10); // Exit guard time for some SD cards + furi_hal_gpio_write(furi_hal_sd_spi_handle->cs, true); } else { - hal_gpio_write(furi_hal_sd_spi_handle->cs, false); - delay_us(10); // Entry guard time for some SD cards + furi_hal_gpio_write(furi_hal_sd_spi_handle->cs, false); + furi_hal_delay_us(10); // Entry guard time for some SD cards } } diff --git a/firmware/targets/f7/fatfs/stm32_adafruit_sd.c b/firmware/targets/f7/fatfs/stm32_adafruit_sd.c index 9225a90b..246eabf0 100644 --- a/firmware/targets/f7/fatfs/stm32_adafruit_sd.c +++ b/firmware/targets/f7/fatfs/stm32_adafruit_sd.c @@ -279,47 +279,47 @@ static uint8_t SD_ReadData(void); /* Private functions ---------------------------------------------------------*/ void SD_SPI_Bus_To_Down_State() { - hal_gpio_init_ex( + furi_hal_gpio_init_ex( furi_hal_sd_spi_handle->miso, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused); - hal_gpio_init_ex( + furi_hal_gpio_init_ex( furi_hal_sd_spi_handle->mosi, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused); - hal_gpio_init_ex( + furi_hal_gpio_init_ex( furi_hal_sd_spi_handle->sck, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFnUnused); - hal_gpio_write(furi_hal_sd_spi_handle->cs, false); - hal_gpio_write(furi_hal_sd_spi_handle->miso, false); - hal_gpio_write(furi_hal_sd_spi_handle->mosi, false); - hal_gpio_write(furi_hal_sd_spi_handle->sck, false); + furi_hal_gpio_write(furi_hal_sd_spi_handle->cs, false); + 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); } void SD_SPI_Bus_To_Normal_State() { - hal_gpio_write(furi_hal_sd_spi_handle->cs, true); + furi_hal_gpio_write(furi_hal_sd_spi_handle->cs, true); - hal_gpio_init_ex( + furi_hal_gpio_init_ex( furi_hal_sd_spi_handle->miso, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2); - hal_gpio_init_ex( + furi_hal_gpio_init_ex( furi_hal_sd_spi_handle->mosi, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn5SPI2); - hal_gpio_init_ex( + furi_hal_gpio_init_ex( furi_hal_sd_spi_handle->sck, GpioModeAltFunctionPushPull, GpioPullUp, @@ -349,13 +349,13 @@ uint8_t BSP_SD_Init(bool reset_card) { furi_hal_power_disable_external_3_3v(); SD_SPI_Bus_To_Down_State(); hal_sd_detect_set_low(); - delay(250); + furi_hal_delay_ms(250); /* reinit bus and enable power */ SD_SPI_Bus_To_Normal_State(); hal_sd_detect_init(); furi_hal_power_enable_external_3_3v(); - delay(100); + furi_hal_delay_ms(100); } /* Configure IO functionalities for SD pin */ @@ -867,7 +867,7 @@ SD_CmdAnswer_typedef SD_SendCmd(uint8_t Cmd, uint32_t Arg, uint8_t Crc, uint8_t retr.r2 = SD_IO_WriteByte(SD_DUMMY_BYTE); /* Set CS High */ SD_IO_CSState(1); - HAL_Delay(1); + furi_hal_delay_us(1000); /* Set CS Low */ SD_IO_CSState(0); diff --git a/firmware/targets/f7/furi_hal/furi_hal.c b/firmware/targets/f7/furi_hal/furi_hal.c index 4d37e858..a8be527b 100644 --- a/firmware/targets/f7/furi_hal/furi_hal.c +++ b/firmware/targets/f7/furi_hal/furi_hal.c @@ -1,7 +1,5 @@ #include -#include - #include #include @@ -13,7 +11,7 @@ void furi_hal_init() { furi_hal_interrupt_init(); furi_hal_delay_init(); - MX_GPIO_Init(); + furi_hal_resources_init(); FURI_LOG_I(TAG, "GPIO OK"); furi_hal_bootloader_init(); diff --git a/firmware/targets/f7/furi_hal/furi_hal_bt.c b/firmware/targets/f7/furi_hal/furi_hal_bt.c index 1bd244a9..a8b85495 100755 --- a/firmware/targets/f7/furi_hal/furi_hal_bt.c +++ b/firmware/targets/f7/furi_hal/furi_hal_bt.c @@ -44,8 +44,8 @@ FuriHalBtProfileConfig profile_config[FuriHalBtProfileNumber] = { .mac_address = FURI_HAL_BT_DEFAULT_MAC_ADDR, .conn_param = { - .conn_int_min = 0x08, - .conn_int_max = 0x18, + .conn_int_min = 0x18, // 30 ms + .conn_int_max = 0x24, // 45 ms .slave_latency = 0, .supervisor_timeout = 0, }, @@ -62,13 +62,12 @@ FuriHalBtProfileConfig profile_config[FuriHalBtProfileNumber] = { .bonding_mode = true, .pairing_method = GapPairingPinCodeVerifyYesNo, .mac_address = FURI_HAL_BT_DEFAULT_MAC_ADDR, - // TODO optimize .conn_param = { - .conn_int_min = 0x12, - .conn_int_max = 0x1e, - .slave_latency = 6, - .supervisor_timeout = 700, + .conn_int_min = 0x18, // 30 ms + .conn_int_max = 0x24, // 45 ms + .slave_latency = 0, + .supervisor_timeout = 0, }, }, }, @@ -82,8 +81,8 @@ void furi_hal_bt_init() { } // Explicitly tell that we are in charge of CLK48 domain - if(!HAL_HSEM_IsSemTaken(CFG_HW_CLK48_CONFIG_SEMID)) { - HAL_HSEM_FastTake(CFG_HW_CLK48_CONFIG_SEMID); + if(!LL_HSEM_IsSemaphoreLocked(HSEM, CFG_HW_CLK48_CONFIG_SEMID)) { + furi_check(LL_HSEM_1StepLock(HSEM, CFG_HW_CLK48_CONFIG_SEMID) == 0); } // Start Core2 @@ -124,8 +123,8 @@ bool furi_hal_bt_start_radio_stack() { osMutexAcquire(furi_hal_bt_core2_mtx, osWaitForever); // Explicitly tell that we are in charge of CLK48 domain - if(!HAL_HSEM_IsSemTaken(CFG_HW_CLK48_CONFIG_SEMID)) { - HAL_HSEM_FastTake(CFG_HW_CLK48_CONFIG_SEMID); + if(!LL_HSEM_IsSemaphoreLocked(HSEM, CFG_HW_CLK48_CONFIG_SEMID)) { + furi_check(LL_HSEM_1StepLock(HSEM, CFG_HW_CLK48_CONFIG_SEMID) == 0); } do { @@ -283,13 +282,13 @@ void furi_hal_bt_set_key_storage_change_callback( } void furi_hal_bt_nvm_sram_sem_acquire() { - while(HAL_HSEM_FastTake(CFG_HW_BLE_NVM_SRAM_SEMID) != HAL_OK) { - osDelay(1); + while(LL_HSEM_1StepLock(HSEM, CFG_HW_BLE_NVM_SRAM_SEMID)) { + osThreadYield(); } } void furi_hal_bt_nvm_sram_sem_release() { - HAL_HSEM_Release(CFG_HW_BLE_NVM_SRAM_SEMID, 0); + LL_HSEM_ReleaseLock(HSEM, CFG_HW_BLE_NVM_SRAM_SEMID, 0); } bool furi_hal_bt_clear_white_list() { diff --git a/firmware/targets/f7/furi_hal/furi_hal_clock.c b/firmware/targets/f7/furi_hal/furi_hal_clock.c index 02822035..962f2123 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_clock.c +++ b/firmware/targets/f7/furi_hal/furi_hal_clock.c @@ -4,9 +4,12 @@ #include #include #include +#include +#include #define TAG "FuriHalClock" +#define TICK_INT_PRIORITY 0U #define HS_CLOCK_IS_READY() (LL_RCC_HSE_IsReady() && LL_RCC_HSI_IsReady()) #define LS_CLOCK_IS_READY() (LL_RCC_LSE_IsReady() && LL_RCC_LSI1_IsReady()) @@ -83,9 +86,10 @@ void furi_hal_clock_init() { LL_SetSystemCoreClock(64000000); /* Update the time base */ - if(HAL_InitTick(TICK_INT_PRIORITY) != HAL_OK) { - Error_Handler(); - } + LL_InitTick(64000000, 1000); + LL_SYSTICK_EnableIT(); + NVIC_SetPriority(SysTick_IRQn, TICK_INT_PRIORITY); + NVIC_EnableIRQ(SysTick_IRQn); LL_RCC_SetUSARTClockSource(LL_RCC_USART1_CLKSOURCE_PCLK2); LL_RCC_SetLPUARTClockSource(LL_RCC_LPUART1_CLKSOURCE_PCLK1); diff --git a/firmware/targets/f7/furi_hal/furi_hal_crypto.c b/firmware/targets/f7/furi_hal/furi_hal_crypto.c index 72de7d87..c34eb735 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_crypto.c +++ b/firmware/targets/f7/furi_hal/furi_hal_crypto.c @@ -1,16 +1,27 @@ #include #include #include +#include #include #include #define TAG "FuriHalCrypto" -CRYP_HandleTypeDef crypt; - #define ENCLAVE_FACTORY_KEY_SLOTS 10 #define ENCLAVE_SIGNATURE_SIZE 16 +#define CRYPTO_BLK_LEN (4 * sizeof(uint32_t)) +#define CRYPTO_TIMEOUT (1000) + +#define CRYPTO_MODE_ENCRYPT 0U +#define CRYPTO_MODE_DECRYPT (AES_CR_MODE_1) +#define CRYPTO_MODE_DECRYPT_INIT (AES_CR_MODE_0 | AES_CR_MODE_1) +#define CRYPTO_DATATYPE_32B 0U +#define CRYPTO_KEYSIZE_256B (AES_CR_KEYSIZE) +#define CRYPTO_AES_CBC (AES_CR_CHMOD_0) + +static osMutexId_t furi_hal_crypto_mutex = NULL; + static const uint8_t enclave_signature_iv[ENCLAVE_FACTORY_KEY_SLOTS][16] = { {0xac, 0x5d, 0x68, 0xb8, 0x79, 0x74, 0xfc, 0x7f, 0x45, 0x02, 0x82, 0xf1, 0x48, 0x7e, 0x75, 0x8a}, {0x38, 0xe6, 0x6a, 0x90, 0x5e, 0x5b, 0x8a, 0xa6, 0x70, 0x30, 0x04, 0x72, 0xc2, 0x42, 0xea, 0xaf}, @@ -51,6 +62,7 @@ static const uint8_t enclave_signature_expected[ENCLAVE_FACTORY_KEY_SLOTS][ENCLA }; void furi_hal_crypto_init() { + furi_hal_crypto_mutex = osMutexNew(NULL); FURI_LOG_I(TAG, "Init OK"); } @@ -127,6 +139,8 @@ bool furi_hal_crypto_store_add_key(FuriHalCryptoKey* key, uint8_t* slot) { furi_assert(key); furi_assert(slot); + furi_check(osMutexAcquire(furi_hal_crypto_mutex, osWaitForever) == osOK); + if(!furi_hal_bt_is_alive()) { return false; } @@ -157,30 +171,91 @@ bool furi_hal_crypto_store_add_key(FuriHalCryptoKey* key, uint8_t* slot) { memcpy(pParam.KeyData, key->data, key_data_size); - return SHCI_C2_FUS_StoreUsrKey(&pParam, slot) == SHCI_Success; + SHCI_CmdStatus_t shci_state = SHCI_C2_FUS_StoreUsrKey(&pParam, slot); + furi_check(osMutexRelease(furi_hal_crypto_mutex) == osOK); + return (shci_state == SHCI_Success); +} + +static void crypto_enable() { + SET_BIT(AES1->CR, AES_CR_EN); +} + +static void crypto_disable() { + CLEAR_BIT(AES1->CR, AES_CR_EN); +} + +static void crypto_key_init(uint32_t* key, uint32_t* iv) { + crypto_disable(); + MODIFY_REG( + AES1->CR, + AES_CR_DATATYPE | AES_CR_KEYSIZE | AES_CR_CHMOD, + CRYPTO_DATATYPE_32B | CRYPTO_KEYSIZE_256B | CRYPTO_AES_CBC); + + if(key != NULL) { + AES1->KEYR7 = key[0]; + AES1->KEYR6 = key[1]; + AES1->KEYR5 = key[2]; + AES1->KEYR4 = key[3]; + AES1->KEYR3 = key[4]; + AES1->KEYR2 = key[5]; + AES1->KEYR1 = key[6]; + AES1->KEYR0 = key[7]; + } + + AES1->IVR3 = iv[0]; + AES1->IVR2 = iv[1]; + AES1->IVR1 = iv[2]; + AES1->IVR0 = iv[3]; +} + +static bool crypto_process_block(uint32_t* in, uint32_t* out, uint8_t blk_len) { + furi_check((blk_len <= 4) && (blk_len > 0)); + + for(uint8_t i = 0; i < 4; i++) { + if(i < blk_len) { + AES1->DINR = in[i]; + } else { + AES1->DINR = 0; + } + } + + uint32_t countdown = CRYPTO_TIMEOUT; + while(!READ_BIT(AES1->SR, AES_SR_CCF)) { + if(LL_SYSTICK_IsActiveCounterFlag()) { + countdown--; + } + if(countdown == 0) { + return false; + } + } + + SET_BIT(AES1->CR, AES_CR_CCFC); + + uint32_t out_temp[4]; + for(uint8_t i = 0; i < 4; i++) { + out_temp[i] = AES1->DOUTR; + } + + memcpy(out, out_temp, blk_len * sizeof(uint32_t)); + return true; } bool furi_hal_crypto_store_load_key(uint8_t slot, const uint8_t* iv) { furi_assert(slot > 0 && slot <= 100); + furi_assert(furi_hal_crypto_mutex); + furi_check(osMutexAcquire(furi_hal_crypto_mutex, osWaitForever) == osOK); if(!furi_hal_bt_is_alive()) { return false; } - crypt.Instance = AES1; - crypt.Init.DataType = CRYP_DATATYPE_32B; - crypt.Init.KeySize = CRYP_KEYSIZE_256B; - crypt.Init.Algorithm = CRYP_AES_CBC; - crypt.Init.pInitVect = (uint32_t*)iv; - crypt.Init.KeyIVConfigSkip = CRYP_KEYIVCONFIG_ONCE; - crypt.Init.pKey = NULL; - - furi_check(HAL_CRYP_Init(&crypt) == HAL_OK); + crypto_key_init(NULL, (uint32_t*)iv); if(SHCI_C2_FUS_LoadUsrKey(slot) == SHCI_Success) { return true; } else { - furi_check(HAL_CRYP_DeInit(&crypt) == HAL_OK); + crypto_disable(); + furi_check(osMutexRelease(furi_hal_crypto_mutex) == osOK); return false; } } @@ -190,14 +265,55 @@ bool furi_hal_crypto_store_unload_key(uint8_t slot) { return false; } - furi_check(HAL_CRYP_DeInit(&crypt) == HAL_OK); - return SHCI_C2_FUS_UnloadUsrKey(slot) == SHCI_Success; + crypto_disable(); + + SHCI_CmdStatus_t shci_state = SHCI_C2_FUS_UnloadUsrKey(slot); + furi_check(osMutexRelease(furi_hal_crypto_mutex) == osOK); + return (shci_state == SHCI_Success); } bool furi_hal_crypto_encrypt(const uint8_t* input, uint8_t* output, size_t size) { - return HAL_CRYP_Encrypt(&crypt, (uint32_t*)input, size / 4, (uint32_t*)output, 1000) == HAL_OK; + bool state = false; + + crypto_enable(); + + MODIFY_REG(AES1->CR, AES_CR_MODE, CRYPTO_MODE_ENCRYPT); + + for(size_t i = 0; i < size; i += CRYPTO_BLK_LEN) { + size_t blk_len = size - i; + if(blk_len > CRYPTO_BLK_LEN) { + blk_len = CRYPTO_BLK_LEN; + } + state = crypto_process_block((uint32_t*)&input[i], (uint32_t*)&output[i], blk_len / 4); + if(state == false) { + break; + } + } + + crypto_disable(); + + return state; } bool furi_hal_crypto_decrypt(const uint8_t* input, uint8_t* output, size_t size) { - return HAL_CRYP_Decrypt(&crypt, (uint32_t*)input, size / 4, (uint32_t*)output, 1000) == HAL_OK; + bool state = false; + + MODIFY_REG(AES1->CR, AES_CR_MODE, CRYPTO_MODE_DECRYPT_INIT); + + crypto_enable(); + + for(size_t i = 0; i < size; i += CRYPTO_BLK_LEN) { + size_t blk_len = size - i; + if(blk_len > CRYPTO_BLK_LEN) { + blk_len = CRYPTO_BLK_LEN; + } + state = crypto_process_block((uint32_t*)&input[i], (uint32_t*)&output[i], blk_len / 4); + if(state == false) { + break; + } + } + + crypto_disable(); + + return state; } diff --git a/firmware/targets/f7/furi_hal/furi_hal_delay.c b/firmware/targets/f7/furi_hal/furi_hal_delay.c index 60c9b1c4..bb852ca9 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_delay.c +++ b/firmware/targets/f7/furi_hal/furi_hal_delay.c @@ -4,33 +4,37 @@ #include #define TAG "FuriHalDelay" - -static uint32_t clk_per_microsecond; +uint32_t instructions_per_us; +static volatile uint32_t tick_cnt = 0; void furi_hal_delay_init(void) { CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; DWT->CYCCNT = 0U; - clk_per_microsecond = SystemCoreClock / 1000000.0f; + instructions_per_us = SystemCoreClock / 1000000.0f; FURI_LOG_I(TAG, "Init OK"); } -void delay_us(float microseconds) { +void furi_hal_tick(void) { + tick_cnt++; +} + +uint32_t furi_hal_get_tick(void) { + return tick_cnt; +} + +void furi_hal_delay_us(float microseconds) { uint32_t start = DWT->CYCCNT; - uint32_t time_ticks = microseconds * clk_per_microsecond; + uint32_t time_ticks = microseconds * instructions_per_us; while((DWT->CYCCNT - start) < time_ticks) { }; } // cannot be used in ISR // TODO add delay_ISR variant -void delay(float milliseconds) { +void furi_hal_delay_ms(float milliseconds) { uint32_t ticks = milliseconds / (1000.0f / osKernelGetTickFreq()); osStatus_t result = osDelay(ticks); (void)result; furi_assert(result == osOK); } - -uint32_t millis(void) { - return HAL_GetTick(); -} diff --git a/firmware/targets/f7/furi_hal/furi_hal_flash.c b/firmware/targets/f7/furi_hal/furi_hal_flash.c index 15896fbf..fc1dbd2f 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_flash.c +++ b/firmware/targets/f7/furi_hal/furi_hal_flash.c @@ -12,6 +12,17 @@ #define FURI_HAL_FLASH_WRITE_BLOCK 8 #define FURI_HAL_FLASH_PAGE_SIZE 4096 #define FURI_HAL_FLASH_CYCLES_COUNT 10000 +#define FURI_HAL_FLASH_TIMEOUT 1000 +#define FURI_HAL_FLASH_KEY1 0x45670123U +#define FURI_HAL_FLASH_KEY2 0xCDEF89ABU +#define FURI_HAL_FLASH_SR_ERRORS \ + (FLASH_SR_OPERR | FLASH_SR_PROGERR | FLASH_SR_WRPERR | FLASH_SR_PGAERR | FLASH_SR_SIZERR | \ + FLASH_SR_PGSERR | FLASH_SR_MISERR | FLASH_SR_FASTERR | FLASH_SR_RDERR | FLASH_SR_OPTVERR) + +#define IS_ADDR_ALIGNED_64BITS(__VALUE__) (((__VALUE__)&0x7U) == (0x00UL)) +#define IS_FLASH_PROGRAM_ADDRESS(__VALUE__) \ + (((__VALUE__) >= FLASH_BASE) && ((__VALUE__) <= (FLASH_BASE + FLASH_SIZE - 8UL)) && \ + (((__VALUE__) % 8UL) == 0UL)) /* Free flash space borders, exported by linker */ extern const void __free_flash_start__; @@ -43,7 +54,7 @@ const void* furi_hal_flash_get_free_start_address() { const void* furi_hal_flash_get_free_end_address() { uint32_t sfr_reg_val = READ_REG(FLASH->SFR); uint32_t sfsa = (READ_BIT(sfr_reg_val, FLASH_SFR_SFSA) >> FLASH_SFR_SFSA_Pos); - return (const void*)((sfsa * FLASH_PAGE_SIZE) + FLASH_BASE); + return (const void*)((sfsa * FURI_HAL_FLASH_PAGE_SIZE) + FLASH_BASE); } size_t furi_hal_flash_get_free_page_start_address() { @@ -66,8 +77,8 @@ static void furi_hal_flash_unlock() { furi_check(READ_BIT(FLASH->CR, FLASH_CR_LOCK) != 0U); /* Authorize the FLASH Registers access */ - WRITE_REG(FLASH->KEYR, FLASH_KEY1); - WRITE_REG(FLASH->KEYR, FLASH_KEY2); + WRITE_REG(FLASH->KEYR, FURI_HAL_FLASH_KEY1); + WRITE_REG(FLASH->KEYR, FURI_HAL_FLASH_KEY2); /* verify Flash is unlock */ furi_check(READ_BIT(FLASH->CR, FLASH_CR_LOCK) == 0U); @@ -87,8 +98,8 @@ static void furi_hal_flash_lock(void) { static void furi_hal_flash_begin_with_core2(bool erase_flag) { // Take flash controller ownership - while(HAL_HSEM_FastTake(CFG_HW_FLASH_SEMID) != HAL_OK) { - taskYIELD(); + while(LL_HSEM_1StepLock(HSEM, CFG_HW_FLASH_SEMID) != 0) { + osThreadYield(); } // Unlock flash operation @@ -97,27 +108,31 @@ static void furi_hal_flash_begin_with_core2(bool erase_flag) { // Erase activity notification if(erase_flag) SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_ON); + // 64mHz 5us core2 flag protection + for(volatile uint32_t i = 0; i < 35; i++) + ; + while(true) { // Wait till flash controller become usable while(LL_FLASH_IsActiveFlag_OperationSuspended()) { - taskYIELD(); + osThreadYield(); }; // Just a little more love taskENTER_CRITICAL(); // Actually we already have mutex for it, but specification is specification - if(HAL_HSEM_IsSemTaken(CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID)) { + if(LL_HSEM_IsSemaphoreLocked(HSEM, CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID)) { taskEXIT_CRITICAL(); + osThreadYield(); continue; } - // Take sempahopre and prevent core2 from anyting funky - if(!HAL_HSEM_IsSemTaken(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID)) { - if(HAL_HSEM_FastTake(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID) != HAL_OK) { - taskEXIT_CRITICAL(); - continue; - } + // Take sempahopre and prevent core2 from anything funky + if(LL_HSEM_1StepLock(HSEM, CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID) != 0) { + taskEXIT_CRITICAL(); + osThreadYield(); + continue; } break; @@ -138,14 +153,14 @@ static void furi_hal_flash_begin(bool erase_flag) { static void furi_hal_flash_end_with_core2(bool erase_flag) { // Funky ops are ok at this point - HAL_HSEM_Release(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID, 0); + LL_HSEM_ReleaseLock(HSEM, CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID, 0); // Task switching is ok taskEXIT_CRITICAL(); // Doesn't make much sense, does it? - while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) { - taskYIELD(); + while(READ_BIT(FLASH->SR, FLASH_SR_BSY)) { + osThreadYield(); } // Erase activity over, core2 can continue @@ -155,7 +170,7 @@ static void furi_hal_flash_end_with_core2(bool erase_flag) { furi_hal_flash_lock(); // Release flash controller ownership - HAL_HSEM_Release(CFG_HW_FLASH_SEMID, 0); + LL_HSEM_ReleaseLock(HSEM, CFG_HW_FLASH_SEMID, 0); } static void furi_hal_flash_end(bool erase_flag) { @@ -194,7 +209,7 @@ static void furi_hal_flush_cache(void) { } } -HAL_StatusTypeDef furi_hal_flash_wait_last_operation(uint32_t timeout) { +bool furi_hal_flash_wait_last_operation(uint32_t timeout) { uint32_t error = 0; uint32_t countdown = 0; @@ -202,12 +217,12 @@ HAL_StatusTypeDef furi_hal_flash_wait_last_operation(uint32_t timeout) { // Even if the FLASH operation fails, the BUSY flag will be reset and an error // flag will be set countdown = timeout; - while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) { + while(READ_BIT(FLASH->SR, FLASH_SR_BSY)) { if(LL_SYSTICK_IsActiveCounterFlag()) { countdown--; } if(countdown == 0) { - return HAL_TIMEOUT; + return false; } } @@ -215,31 +230,30 @@ HAL_StatusTypeDef furi_hal_flash_wait_last_operation(uint32_t timeout) { error = FLASH->SR; /* Check FLASH End of Operation flag */ - if((error & FLASH_FLAG_EOP) != 0U) { + if((error & FLASH_SR_EOP) != 0U) { /* Clear FLASH End of Operation pending bit */ - __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP); + CLEAR_BIT(FLASH->SR, FLASH_SR_EOP); } /* Now update error variable to only error value */ - error &= FLASH_FLAG_SR_ERRORS; + error &= FURI_HAL_FLASH_SR_ERRORS; furi_check(error == 0); /* clear error flags */ - __HAL_FLASH_CLEAR_FLAG(error); + CLEAR_BIT(FLASH->SR, error); /* Wait for control register to be written */ countdown = timeout; - while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_CFGBSY)) { + while(READ_BIT(FLASH->SR, FLASH_SR_CFGBSY)) { if(LL_SYSTICK_IsActiveCounterFlag()) { countdown--; } if(countdown == 0) { - return HAL_TIMEOUT; + return false; } } - - return HAL_OK; + return true; } bool furi_hal_flash_erase(uint8_t page) { @@ -249,14 +263,14 @@ bool furi_hal_flash_erase(uint8_t page) { furi_check(FLASH->SR == 0); /* Verify that next operation can be proceed */ - furi_check(furi_hal_flash_wait_last_operation(FLASH_TIMEOUT_VALUE) == HAL_OK); + furi_check(furi_hal_flash_wait_last_operation(FURI_HAL_FLASH_TIMEOUT)); /* Select page and start operation */ MODIFY_REG( FLASH->CR, FLASH_CR_PNB, ((page << FLASH_CR_PNB_Pos) | FLASH_CR_PER | FLASH_CR_STRT)); /* Wait for last operation to be completed */ - furi_check(furi_hal_flash_wait_last_operation(FLASH_TIMEOUT_VALUE) == HAL_OK); + furi_check(furi_hal_flash_wait_last_operation(FURI_HAL_FLASH_TIMEOUT)); /* If operation is completed or interrupted, disable the Page Erase Bit */ CLEAR_BIT(FLASH->CR, (FLASH_CR_PER | FLASH_CR_PNB)); @@ -293,7 +307,7 @@ bool furi_hal_flash_write_dword(size_t address, uint64_t data) { *(uint32_t*)(address + 4U) = (uint32_t)(data >> 32U); /* Wait for last operation to be completed */ - furi_check(furi_hal_flash_wait_last_operation(FLASH_TIMEOUT_VALUE) == HAL_OK); + furi_check(furi_hal_flash_wait_last_operation(FURI_HAL_FLASH_TIMEOUT)); /* If the program operation is completed, disable the PG or FSTPG Bit */ CLEAR_BIT(FLASH->CR, FLASH_CR_PG); diff --git a/firmware/targets/f7/furi_hal/furi_hal_gpio.c b/firmware/targets/f7/furi_hal/furi_hal_gpio.c index ce4b2d5e..a148a3af 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_gpio.c +++ b/firmware/targets/f7/furi_hal/furi_hal_gpio.c @@ -34,7 +34,7 @@ static volatile GpioInterrupt gpio_interrupt[GPIO_NUMBER]; -static uint8_t hal_gpio_get_pin_num(const GpioPin* gpio) { +static uint8_t furi_hal_gpio_get_pin_num(const GpioPin* gpio) { uint8_t pin_num = 0; for(pin_num = 0; pin_num < GPIO_NUMBER; pin_num++) { if(gpio->pin & (1 << pin_num)) break; @@ -42,11 +42,11 @@ static uint8_t hal_gpio_get_pin_num(const GpioPin* gpio) { return pin_num; } -void hal_gpio_init_simple(const GpioPin* gpio, const GpioMode mode) { - hal_gpio_init(gpio, mode, GpioPullNo, GpioSpeedLow); +void furi_hal_gpio_init_simple(const GpioPin* gpio, const GpioMode mode) { + furi_hal_gpio_init(gpio, mode, GpioPullNo, GpioSpeedLow); } -void hal_gpio_init( +void furi_hal_gpio_init( const GpioPin* gpio, const GpioMode mode, const GpioPull pull, @@ -55,10 +55,10 @@ void hal_gpio_init( furi_assert(mode != GpioModeAltFunctionPushPull); furi_assert(mode != GpioModeAltFunctionOpenDrain); - hal_gpio_init_ex(gpio, mode, pull, speed, GpioAltFnUnused); + furi_hal_gpio_init_ex(gpio, mode, pull, speed, GpioAltFnUnused); } -void hal_gpio_init_ex( +void furi_hal_gpio_init_ex( const GpioPin* gpio, const GpioMode mode, const GpioPull pull, @@ -133,7 +133,7 @@ void hal_gpio_init_ex( // Prepare alternative part if any if(mode == GpioModeAltFunctionPushPull || mode == GpioModeAltFunctionOpenDrain) { // set alternate function - if(hal_gpio_get_pin_num(gpio) < 8) { + if(furi_hal_gpio_get_pin_num(gpio) < 8) { LL_GPIO_SetAFPin_0_7(gpio->port, gpio->pin, alt_fn); } else { LL_GPIO_SetAFPin_8_15(gpio->port, gpio->pin, alt_fn); @@ -171,12 +171,12 @@ void hal_gpio_init_ex( FURI_CRITICAL_EXIT(); } -void hal_gpio_add_int_callback(const GpioPin* gpio, GpioExtiCallback cb, void* ctx) { +void furi_hal_gpio_add_int_callback(const GpioPin* gpio, GpioExtiCallback cb, void* ctx) { furi_assert(gpio); furi_assert(cb); FURI_CRITICAL_ENTER(); - uint8_t pin_num = hal_gpio_get_pin_num(gpio); + uint8_t pin_num = furi_hal_gpio_get_pin_num(gpio); furi_assert(gpio_interrupt[pin_num].callback == NULL); gpio_interrupt[pin_num].callback = cb; gpio_interrupt[pin_num].context = ctx; @@ -184,38 +184,38 @@ void hal_gpio_add_int_callback(const GpioPin* gpio, GpioExtiCallback cb, void* c FURI_CRITICAL_EXIT(); } -void hal_gpio_enable_int_callback(const GpioPin* gpio) { +void furi_hal_gpio_enable_int_callback(const GpioPin* gpio) { furi_assert(gpio); FURI_CRITICAL_ENTER(); - uint8_t pin_num = hal_gpio_get_pin_num(gpio); + uint8_t pin_num = furi_hal_gpio_get_pin_num(gpio); if(gpio_interrupt[pin_num].callback) { gpio_interrupt[pin_num].ready = true; } FURI_CRITICAL_EXIT(); } -void hal_gpio_disable_int_callback(const GpioPin* gpio) { +void furi_hal_gpio_disable_int_callback(const GpioPin* gpio) { furi_assert(gpio); FURI_CRITICAL_ENTER(); - uint8_t pin_num = hal_gpio_get_pin_num(gpio); + uint8_t pin_num = furi_hal_gpio_get_pin_num(gpio); gpio_interrupt[pin_num].ready = false; FURI_CRITICAL_EXIT(); } -void hal_gpio_remove_int_callback(const GpioPin* gpio) { +void furi_hal_gpio_remove_int_callback(const GpioPin* gpio) { furi_assert(gpio); FURI_CRITICAL_ENTER(); - uint8_t pin_num = hal_gpio_get_pin_num(gpio); + uint8_t pin_num = furi_hal_gpio_get_pin_num(gpio); gpio_interrupt[pin_num].callback = NULL; gpio_interrupt[pin_num].context = NULL; gpio_interrupt[pin_num].ready = false; FURI_CRITICAL_EXIT(); } -static void hal_gpio_int_call(uint16_t pin_num) { +static void furi_hal_gpio_int_call(uint16_t pin_num) { if(gpio_interrupt[pin_num].callback && gpio_interrupt[pin_num].ready) { gpio_interrupt[pin_num].callback(gpio_interrupt[pin_num].context); } @@ -225,84 +225,84 @@ static void hal_gpio_int_call(uint16_t pin_num) { void EXTI0_IRQHandler(void) { if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_0)) { LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_0); - hal_gpio_int_call(0); + furi_hal_gpio_int_call(0); } } void EXTI1_IRQHandler(void) { if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_1)) { LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_1); - hal_gpio_int_call(1); + furi_hal_gpio_int_call(1); } } void EXTI2_IRQHandler(void) { if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_2)) { LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_2); - hal_gpio_int_call(2); + furi_hal_gpio_int_call(2); } } void EXTI3_IRQHandler(void) { if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_3)) { LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_3); - hal_gpio_int_call(3); + furi_hal_gpio_int_call(3); } } void EXTI4_IRQHandler(void) { if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_4)) { LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_4); - hal_gpio_int_call(4); + furi_hal_gpio_int_call(4); } } void EXTI9_5_IRQHandler(void) { if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_5)) { LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_5); - hal_gpio_int_call(5); + furi_hal_gpio_int_call(5); } if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_6)) { LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_6); - hal_gpio_int_call(6); + furi_hal_gpio_int_call(6); } if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_7)) { LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_7); - hal_gpio_int_call(7); + furi_hal_gpio_int_call(7); } if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_8)) { LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_8); - hal_gpio_int_call(8); + furi_hal_gpio_int_call(8); } if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_9)) { LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_9); - hal_gpio_int_call(9); + furi_hal_gpio_int_call(9); } } void EXTI15_10_IRQHandler(void) { if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_10)) { LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_10); - hal_gpio_int_call(10); + furi_hal_gpio_int_call(10); } if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_11)) { LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_11); - hal_gpio_int_call(11); + furi_hal_gpio_int_call(11); } if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_12)) { LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_12); - hal_gpio_int_call(12); + furi_hal_gpio_int_call(12); } if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_13)) { LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_13); - hal_gpio_int_call(13); + furi_hal_gpio_int_call(13); } if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_14)) { LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_14); - hal_gpio_int_call(14); + furi_hal_gpio_int_call(14); } if(LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_15)) { LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_15); - hal_gpio_int_call(15); + furi_hal_gpio_int_call(15); } } diff --git a/firmware/targets/f7/furi_hal/furi_hal_gpio.h b/firmware/targets/f7/furi_hal/furi_hal_gpio.h index c082c519..0999971b 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_gpio.h +++ b/firmware/targets/f7/furi_hal/furi_hal_gpio.h @@ -1,5 +1,4 @@ #pragma once -#include "main.h" #include "stdbool.h" #include #include @@ -170,7 +169,7 @@ typedef struct { * @param gpio GpioPin * @param mode GpioMode */ -void hal_gpio_init_simple(const GpioPin* gpio, const GpioMode mode); +void furi_hal_gpio_init_simple(const GpioPin* gpio, const GpioMode mode); /** * GPIO initialization function, normal version @@ -179,7 +178,7 @@ void hal_gpio_init_simple(const GpioPin* gpio, const GpioMode mode); * @param pull GpioPull * @param speed GpioSpeed */ -void hal_gpio_init( +void furi_hal_gpio_init( const GpioPin* gpio, const GpioMode mode, const GpioPull pull, @@ -193,7 +192,7 @@ void hal_gpio_init( * @param speed GpioSpeed * @param alt_fn GpioAltFn */ -void hal_gpio_init_ex( +void furi_hal_gpio_init_ex( const GpioPin* gpio, const GpioMode mode, const GpioPull pull, @@ -206,32 +205,32 @@ void hal_gpio_init_ex( * @param cb GpioExtiCallback * @param ctx context for callback */ -void hal_gpio_add_int_callback(const GpioPin* gpio, GpioExtiCallback cb, void* ctx); +void furi_hal_gpio_add_int_callback(const GpioPin* gpio, GpioExtiCallback cb, void* ctx); /** * Enable interrupt * @param gpio GpioPin */ -void hal_gpio_enable_int_callback(const GpioPin* gpio); +void furi_hal_gpio_enable_int_callback(const GpioPin* gpio); /** * Disable interrupt * @param gpio GpioPin */ -void hal_gpio_disable_int_callback(const GpioPin* gpio); +void furi_hal_gpio_disable_int_callback(const GpioPin* gpio); /** * Remove interrupt * @param gpio GpioPin */ -void hal_gpio_remove_int_callback(const GpioPin* gpio); +void furi_hal_gpio_remove_int_callback(const GpioPin* gpio); /** * GPIO write pin * @param gpio GpioPin * @param state true / false */ -static inline void hal_gpio_write(const GpioPin* gpio, const bool state) { +static inline void furi_hal_gpio_write(const GpioPin* gpio, const bool state) { // writing to BSSR is an atomic operation if(state == true) { gpio->port->BSRR = gpio->pin; @@ -240,12 +239,28 @@ static inline void hal_gpio_write(const GpioPin* gpio, const bool state) { } } +/** + * GPIO read pin + * @param port GPIO port + * @param pin pin mask + * @return true / false + */ +static inline void + furi_hal_gpio_write_port_pin(GPIO_TypeDef* port, uint16_t pin, const bool state) { + // writing to BSSR is an atomic operation + if(state == true) { + port->BSRR = pin; + } else { + port->BSRR = pin << GPIO_NUMBER; + } +} + /** * GPIO read pin * @param gpio GpioPin * @return true / false */ -static inline bool hal_gpio_read(const GpioPin* gpio) { +static inline bool furi_hal_gpio_read(const GpioPin* gpio) { if((gpio->port->IDR & gpio->pin) != 0x00U) { return true; } else { @@ -253,6 +268,20 @@ static inline bool hal_gpio_read(const GpioPin* gpio) { } } +/** + * GPIO read pin + * @param port GPIO port + * @param pin pin mask + * @return true / false + */ +static inline bool furi_hal_gpio_read_port_pin(GPIO_TypeDef* port, uint16_t pin) { + if((port->IDR & pin) != 0x00U) { + return true; + } else { + return false; + } +} + #ifdef __cplusplus } #endif diff --git a/firmware/targets/f7/furi_hal/furi_hal_i2c.c b/firmware/targets/f7/furi_hal/furi_hal_i2c.c index 770fcdeb..03c39a44 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_i2c.c +++ b/firmware/targets/f7/furi_hal/furi_hal_i2c.c @@ -1,4 +1,5 @@ #include +#include #include #include @@ -50,11 +51,11 @@ bool furi_hal_i2c_tx( furi_assert(timeout > 0); bool ret = true; - uint32_t timeout_tick = HAL_GetTick() + timeout; + uint32_t timeout_tick = furi_hal_get_tick() + timeout; do { while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) { - if(HAL_GetTick() >= timeout_tick) { + if(furi_hal_get_tick() >= timeout_tick) { ret = false; break; } @@ -79,7 +80,7 @@ bool furi_hal_i2c_tx( size--; } - if(HAL_GetTick() >= timeout_tick) { + if(furi_hal_get_tick() >= timeout_tick) { ret = false; break; } @@ -101,11 +102,11 @@ bool furi_hal_i2c_rx( furi_assert(timeout > 0); bool ret = true; - uint32_t timeout_tick = HAL_GetTick() + timeout; + uint32_t timeout_tick = furi_hal_get_tick() + timeout; do { while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) { - if(HAL_GetTick() >= timeout_tick) { + if(furi_hal_get_tick() >= timeout_tick) { ret = false; break; } @@ -130,7 +131,7 @@ bool furi_hal_i2c_rx( size--; } - if(HAL_GetTick() >= timeout_tick) { + if(furi_hal_get_tick() >= timeout_tick) { ret = false; break; } @@ -165,11 +166,11 @@ bool furi_hal_i2c_is_device_ready(FuriHalI2cBusHandle* handle, uint8_t i2c_addr, furi_assert(timeout > 0); bool ret = true; - uint32_t timeout_tick = HAL_GetTick() + timeout; + uint32_t timeout_tick = furi_hal_get_tick() + timeout; do { while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) { - if(HAL_GetTick() >= timeout_tick) { + if(furi_hal_get_tick() >= timeout_tick) { return false; } } @@ -180,14 +181,14 @@ bool furi_hal_i2c_is_device_ready(FuriHalI2cBusHandle* handle, uint8_t i2c_addr, while((!LL_I2C_IsActiveFlag_NACK(handle->bus->i2c)) && (!LL_I2C_IsActiveFlag_STOP(handle->bus->i2c))) { - if(HAL_GetTick() >= timeout_tick) { + if(furi_hal_get_tick() >= timeout_tick) { return false; } } if(LL_I2C_IsActiveFlag_NACK(handle->bus->i2c)) { while(!LL_I2C_IsActiveFlag_STOP(handle->bus->i2c)) { - if(HAL_GetTick() >= timeout_tick) { + if(furi_hal_get_tick() >= timeout_tick) { return false; } } @@ -204,7 +205,7 @@ bool furi_hal_i2c_is_device_ready(FuriHalI2cBusHandle* handle, uint8_t i2c_addr, } while(!LL_I2C_IsActiveFlag_STOP(handle->bus->i2c)) { - if(HAL_GetTick() >= timeout_tick) { + if(furi_hal_get_tick() >= timeout_tick) { return false; } } @@ -298,11 +299,11 @@ bool furi_hal_i2c_write_mem( bool ret = true; uint8_t size = len + 1; - uint32_t timeout_tick = HAL_GetTick() + timeout; + uint32_t timeout_tick = furi_hal_get_tick() + timeout; do { while(LL_I2C_IsActiveFlag_BUSY(handle->bus->i2c)) { - if(HAL_GetTick() >= timeout_tick) { + if(furi_hal_get_tick() >= timeout_tick) { ret = false; break; } @@ -331,7 +332,7 @@ bool furi_hal_i2c_write_mem( size--; } - if(HAL_GetTick() >= timeout_tick) { + if(furi_hal_get_tick() >= timeout_tick) { ret = false; break; } diff --git a/firmware/targets/f7/furi_hal/furi_hal_i2c_config.c b/firmware/targets/f7/furi_hal/furi_hal_i2c_config.c index f5e0f27a..84cada61 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_i2c_config.c +++ b/firmware/targets/f7/furi_hal/furi_hal_i2c_config.c @@ -1,6 +1,8 @@ #include "furi_hal_i2c_config.h" #include #include +#include +#include /** Timing register value is computed with the STM32CubeMX Tool, * Standard Mode @100kHz with I2CCLK = 64 MHz, @@ -70,13 +72,13 @@ void furi_hal_i2c_bus_handle_power_event( FuriHalI2cBusHandle* handle, FuriHalI2cBusHandleEvent event) { if(event == FuriHalI2cBusHandleEventActivate) { - hal_gpio_init_ex( + furi_hal_gpio_init_ex( &gpio_i2c_power_sda, GpioModeAltFunctionOpenDrain, GpioPullNo, GpioSpeedLow, GpioAltFn4I2C1); - hal_gpio_init_ex( + furi_hal_gpio_init_ex( &gpio_i2c_power_scl, GpioModeAltFunctionOpenDrain, GpioPullNo, @@ -104,11 +106,11 @@ void furi_hal_i2c_bus_handle_power_event( LL_I2C_EnableClockStretching(handle->bus->i2c); } else if(event == FuriHalI2cBusHandleEventDeactivate) { LL_I2C_Disable(handle->bus->i2c); - hal_gpio_write(&gpio_i2c_power_sda, 1); - hal_gpio_write(&gpio_i2c_power_scl, 1); - hal_gpio_init_ex( + furi_hal_gpio_write(&gpio_i2c_power_sda, 1); + furi_hal_gpio_write(&gpio_i2c_power_scl, 1); + furi_hal_gpio_init_ex( &gpio_i2c_power_sda, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused); - hal_gpio_init_ex( + furi_hal_gpio_init_ex( &gpio_i2c_power_scl, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused); } } @@ -122,9 +124,9 @@ void furi_hal_i2c_bus_handle_external_event( FuriHalI2cBusHandle* handle, FuriHalI2cBusHandleEvent event) { if(event == FuriHalI2cBusHandleEventActivate) { - hal_gpio_init_ex( + furi_hal_gpio_init_ex( &gpio_ext_pc0, GpioModeAltFunctionOpenDrain, GpioPullNo, GpioSpeedLow, GpioAltFn4I2C3); - hal_gpio_init_ex( + furi_hal_gpio_init_ex( &gpio_ext_pc1, GpioModeAltFunctionOpenDrain, GpioPullNo, GpioSpeedLow, GpioAltFn4I2C3); LL_I2C_InitTypeDef I2C_InitStruct = {0}; @@ -144,10 +146,12 @@ void furi_hal_i2c_bus_handle_external_event( LL_I2C_EnableClockStretching(handle->bus->i2c); } else if(event == FuriHalI2cBusHandleEventDeactivate) { LL_I2C_Disable(handle->bus->i2c); - hal_gpio_write(&gpio_ext_pc0, 1); - hal_gpio_write(&gpio_ext_pc1, 1); - hal_gpio_init_ex(&gpio_ext_pc0, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused); - hal_gpio_init_ex(&gpio_ext_pc1, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused); + furi_hal_gpio_write(&gpio_ext_pc0, 1); + furi_hal_gpio_write(&gpio_ext_pc1, 1); + furi_hal_gpio_init_ex( + &gpio_ext_pc0, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused); + furi_hal_gpio_init_ex( + &gpio_ext_pc1, GpioModeAnalog, GpioPullNo, GpioSpeedLow, GpioAltFnUnused); } } diff --git a/firmware/targets/f7/furi_hal/furi_hal_ibutton.c b/firmware/targets/f7/furi_hal/furi_hal_ibutton.c index 90ba1edc..0375893e 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_ibutton.c +++ b/firmware/targets/f7/furi_hal/furi_hal_ibutton.c @@ -3,11 +3,12 @@ #include #include +#include #include #define FURI_HAL_IBUTTON_TIMER TIM1 -#define FURI_HAL_IBUTTON_TIMER_IRQ TIM1_UP_TIM16_IRQn +#define FURI_HAL_IBUTTON_TIMER_IRQ FuriHalInterruptIdTim1UpTim16 typedef enum { FuriHalIbuttonStateIdle, @@ -49,10 +50,7 @@ void furi_hal_ibutton_emulate_start( LL_TIM_DeInit(FURI_HAL_IBUTTON_TIMER); FURI_CRITICAL_EXIT(); - furi_hal_interrupt_set_timer_isr(FURI_HAL_IBUTTON_TIMER, furi_hal_ibutton_emulate_isr); - NVIC_SetPriority( - FURI_HAL_IBUTTON_TIMER_IRQ, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); - NVIC_EnableIRQ(FURI_HAL_IBUTTON_TIMER_IRQ); + furi_hal_interrupt_set_isr(FURI_HAL_IBUTTON_TIMER_IRQ, furi_hal_ibutton_emulate_isr, NULL); LL_TIM_SetPrescaler(FURI_HAL_IBUTTON_TIMER, 0); LL_TIM_SetCounterMode(FURI_HAL_IBUTTON_TIMER, LL_TIM_COUNTERMODE_UP); @@ -84,31 +82,54 @@ void furi_hal_ibutton_emulate_stop() { LL_TIM_DeInit(FURI_HAL_IBUTTON_TIMER); FURI_CRITICAL_EXIT(); - furi_hal_interrupt_set_timer_isr(FURI_HAL_IBUTTON_TIMER, NULL); + furi_hal_interrupt_set_isr(FURI_HAL_IBUTTON_TIMER_IRQ, NULL, NULL); furi_hal_ibutton->callback = NULL; furi_hal_ibutton->context = NULL; } } -void furi_hal_ibutton_start() { +void furi_hal_ibutton_start_drive() { furi_hal_ibutton_pin_high(); - hal_gpio_init(&ibutton_gpio, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&ibutton_gpio, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow); +} + +void furi_hal_ibutton_start_drive_in_isr() { + furi_hal_gpio_init(&ibutton_gpio, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow); + LL_EXTI_ClearFlag_0_31(ibutton_gpio.pin); +} + +void furi_hal_ibutton_start_interrupt() { + furi_hal_ibutton_pin_high(); + furi_hal_gpio_init(&ibutton_gpio, GpioModeInterruptRiseFall, GpioPullNo, GpioSpeedLow); +} + +void furi_hal_ibutton_start_interrupt_in_isr() { + furi_hal_gpio_init(&ibutton_gpio, GpioModeInterruptRiseFall, GpioPullNo, GpioSpeedLow); + LL_EXTI_ClearFlag_0_31(ibutton_gpio.pin); } void furi_hal_ibutton_stop() { furi_hal_ibutton_pin_high(); - hal_gpio_init(&ibutton_gpio, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&ibutton_gpio, GpioModeAnalog, GpioPullNo, GpioSpeedLow); +} + +void furi_hal_ibutton_add_interrupt(GpioExtiCallback cb, void* context) { + furi_hal_gpio_add_int_callback(&ibutton_gpio, cb, context); +} + +void furi_hal_ibutton_remove_interrupt() { + furi_hal_gpio_remove_int_callback(&ibutton_gpio); } void furi_hal_ibutton_pin_low() { - hal_gpio_write(&ibutton_gpio, false); + furi_hal_gpio_write(&ibutton_gpio, false); } void furi_hal_ibutton_pin_high() { - hal_gpio_write(&ibutton_gpio, true); + furi_hal_gpio_write(&ibutton_gpio, true); } bool furi_hal_ibutton_pin_get_level() { - return hal_gpio_read(&ibutton_gpio); + return furi_hal_gpio_read(&ibutton_gpio); } diff --git a/firmware/targets/f7/furi_hal/furi_hal_infrared.c b/firmware/targets/f7/furi_hal/furi_hal_infrared.c index 6d5b00c9..f6f01887 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_infrared.c +++ b/firmware/targets/f7/furi_hal/furi_hal_infrared.c @@ -14,7 +14,6 @@ #include #include #include -#include #define INFRARED_TX_DEBUG 0 @@ -138,7 +137,7 @@ static void furi_hal_infrared_tim_rx_isr() { void furi_hal_infrared_async_rx_start(void) { furi_assert(furi_hal_infrared_state == InfraredStateIdle); - hal_gpio_init_ex( + furi_hal_gpio_init_ex( &gpio_infrared_rx, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2); LL_TIM_InitTypeDef TIM_InitStruct = {0}; @@ -166,7 +165,7 @@ void furi_hal_infrared_async_rx_start(void) { LL_TIM_IC_SetActiveInput(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_ACTIVEINPUT_INDIRECTTI); LL_TIM_IC_SetPrescaler(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_ICPSC_DIV1); - furi_hal_interrupt_set_timer_isr(TIM2, furi_hal_infrared_tim_rx_isr); + furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, furi_hal_infrared_tim_rx_isr, NULL); furi_hal_infrared_state = InfraredStateAsyncRx; LL_TIM_EnableIT_CC1(TIM2); @@ -176,9 +175,6 @@ void furi_hal_infrared_async_rx_start(void) { LL_TIM_SetCounter(TIM2, 0); LL_TIM_EnableCounter(TIM2); - - NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); - NVIC_EnableIRQ(TIM2_IRQn); } void furi_hal_infrared_async_rx_stop(void) { @@ -187,7 +183,7 @@ void furi_hal_infrared_async_rx_stop(void) { FURI_CRITICAL_ENTER(); LL_TIM_DeInit(TIM2); - furi_hal_interrupt_set_timer_isr(TIM2, NULL); + furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, NULL, NULL); furi_hal_infrared_state = InfraredStateIdle; FURI_CRITICAL_EXIT(); @@ -376,15 +372,15 @@ static void furi_hal_infrared_configure_tim_cmgr2_dma_tx(void) { dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM1_UP; dma_config.Priority = LL_DMA_PRIORITY_VERYHIGH; LL_DMA_Init(DMA1, LL_DMA_CHANNEL_1, &dma_config); - furi_hal_interrupt_set_dma_channel_isr( - DMA1, LL_DMA_CHANNEL_1, furi_hal_infrared_tx_dma_polarity_isr); + LL_DMA_ClearFlag_TE1(DMA1); LL_DMA_ClearFlag_TC1(DMA1); + LL_DMA_EnableIT_TE(DMA1, LL_DMA_CHANNEL_1); LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1); - NVIC_SetPriority(DMA1_Channel1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 4, 0)); - NVIC_EnableIRQ(DMA1_Channel1_IRQn); + furi_hal_interrupt_set_isr_ex( + FuriHalInterruptIdDma1Ch1, 4, furi_hal_infrared_tx_dma_polarity_isr, NULL); } static void furi_hal_infrared_configure_tim_rcr_dma_tx(void) { @@ -401,16 +397,17 @@ static void furi_hal_infrared_configure_tim_rcr_dma_tx(void) { dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM1_UP; dma_config.Priority = LL_DMA_PRIORITY_MEDIUM; LL_DMA_Init(DMA1, LL_DMA_CHANNEL_2, &dma_config); - furi_hal_interrupt_set_dma_channel_isr(DMA1, LL_DMA_CHANNEL_2, furi_hal_infrared_tx_dma_isr); + LL_DMA_ClearFlag_TC2(DMA1); LL_DMA_ClearFlag_HT2(DMA1); LL_DMA_ClearFlag_TE2(DMA1); + LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_2); LL_DMA_EnableIT_HT(DMA1, LL_DMA_CHANNEL_2); LL_DMA_EnableIT_TE(DMA1, LL_DMA_CHANNEL_2); - NVIC_SetPriority(DMA1_Channel2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); - NVIC_EnableIRQ(DMA1_Channel2_IRQn); + furi_hal_interrupt_set_isr_ex( + FuriHalInterruptIdDma1Ch2, 5, furi_hal_infrared_tx_dma_isr, NULL); } static void furi_hal_infrared_tx_fill_buffer_last(uint8_t buf_num) { @@ -550,9 +547,9 @@ static void furi_hal_infrared_async_tx_free_resources(void) { (furi_hal_infrared_state == InfraredStateAsyncTxStopped)); osStatus_t status; - hal_gpio_init(&gpio_infrared_tx, GpioModeOutputOpenDrain, GpioPullDown, GpioSpeedLow); - furi_hal_interrupt_set_dma_channel_isr(DMA1, LL_DMA_CHANNEL_1, NULL); - furi_hal_interrupt_set_dma_channel_isr(DMA1, LL_DMA_CHANNEL_2, NULL); + furi_hal_gpio_init(&gpio_infrared_tx, GpioModeOutputOpenDrain, GpioPullDown, GpioSpeedLow); + furi_hal_interrupt_set_isr(FuriHalInterruptIdDma1Ch1, NULL, NULL); + furi_hal_interrupt_set_isr(FuriHalInterruptIdDma1Ch2, NULL, NULL); LL_TIM_DeInit(TIM1); status = osSemaphoreDelete(infrared_tim_tx.stop_semaphore); @@ -606,12 +603,12 @@ void furi_hal_infrared_async_tx_start(uint32_t freq, float duty_cycle) { LL_TIM_ClearFlag_UPDATE(TIM1); LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1); LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_2); - delay_us(5); + furi_hal_delay_us(5); LL_TIM_GenerateEvent_UPDATE(TIM1); /* DMA -> TIMx_RCR */ - delay_us(5); + furi_hal_delay_us(5); LL_GPIO_ResetOutputPin( gpio_infrared_tx.port, gpio_infrared_tx.pin); /* when disable it prevents false pulse */ - hal_gpio_init_ex( + furi_hal_gpio_init_ex( &gpio_infrared_tx, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedHigh, GpioAltFn1TIM1); FURI_CRITICAL_ENTER(); diff --git a/firmware/targets/f7/furi_hal/furi_hal_interrupt.c b/firmware/targets/f7/furi_hal/furi_hal_interrupt.c index 23a67a49..5bee8067 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_interrupt.c +++ b/firmware/targets/f7/furi_hal/furi_hal_interrupt.c @@ -1,155 +1,201 @@ #include "furi_hal_interrupt.h" +#include "furi_hal_delay.h" #include -#include +#include #include +#include #define TAG "FuriHalInterrupt" -volatile FuriHalInterruptISR furi_hal_tim_tim2_isr = NULL; -volatile FuriHalInterruptISR furi_hal_tim_tim1_isr = NULL; +#define FURI_HAL_INTERRUPT_DEFAULT_PRIORITY 5 -#define FURI_HAL_INTERRUPT_DMA_COUNT 2 -#define FURI_HAL_INTERRUPT_DMA_CHANNELS_COUNT 8 +typedef struct { + FuriHalInterruptISR isr; + void* context; +} FuriHalInterruptISRPair; -volatile FuriHalInterruptISR furi_hal_dma_channel_isr[FURI_HAL_INTERRUPT_DMA_COUNT] - [FURI_HAL_INTERRUPT_DMA_CHANNELS_COUNT] = {0}; +FuriHalInterruptISRPair furi_hal_interrupt_isr[FuriHalInterruptIdMax] = {0}; + +const IRQn_Type furi_hal_interrupt_irqn[FuriHalInterruptIdMax] = { + // TIM1, TIM16, TIM17 + [FuriHalInterruptIdTim1TrgComTim17] = TIM1_TRG_COM_TIM17_IRQn, + [FuriHalInterruptIdTim1Cc] = TIM1_CC_IRQn, + [FuriHalInterruptIdTim1UpTim16] = TIM1_UP_TIM16_IRQn, + + // TIM2 + [FuriHalInterruptIdTIM2] = TIM2_IRQn, + + // DMA1 + [FuriHalInterruptIdDma1Ch1] = DMA1_Channel1_IRQn, + [FuriHalInterruptIdDma1Ch2] = DMA1_Channel2_IRQn, + [FuriHalInterruptIdDma1Ch3] = DMA1_Channel3_IRQn, + [FuriHalInterruptIdDma1Ch4] = DMA1_Channel4_IRQn, + [FuriHalInterruptIdDma1Ch5] = DMA1_Channel5_IRQn, + [FuriHalInterruptIdDma1Ch6] = DMA1_Channel6_IRQn, + [FuriHalInterruptIdDma1Ch7] = DMA1_Channel7_IRQn, + + // DMA2 + [FuriHalInterruptIdDma2Ch1] = DMA2_Channel1_IRQn, + [FuriHalInterruptIdDma2Ch2] = DMA2_Channel2_IRQn, + [FuriHalInterruptIdDma2Ch3] = DMA2_Channel3_IRQn, + [FuriHalInterruptIdDma2Ch4] = DMA2_Channel4_IRQn, + [FuriHalInterruptIdDma2Ch5] = DMA2_Channel5_IRQn, + [FuriHalInterruptIdDma2Ch6] = DMA2_Channel6_IRQn, + [FuriHalInterruptIdDma2Ch7] = DMA2_Channel7_IRQn, + + // RCC + [FuriHalInterruptIdRcc] = RCC_IRQn, + + // COMP + [FuriHalInterruptIdCOMP] = COMP_IRQn, + + // HSEM + [FuriHalInterruptIdHsem] = HSEM_IRQn, +}; + +__attribute__((always_inline)) static inline void + furi_hal_interrupt_call(FuriHalInterruptId index) { + furi_assert(furi_hal_interrupt_isr[index].isr); + furi_hal_interrupt_isr[index].isr(furi_hal_interrupt_isr[index].context); +} + +__attribute__((always_inline)) static inline void + furi_hal_interrupt_enable(FuriHalInterruptId index, uint16_t priority) { + NVIC_SetPriority( + furi_hal_interrupt_irqn[index], + NVIC_EncodePriority(NVIC_GetPriorityGrouping(), priority, 0)); + NVIC_EnableIRQ(furi_hal_interrupt_irqn[index]); +} + +__attribute__((always_inline)) static inline void + furi_hal_interrupt_disable(FuriHalInterruptId index) { + NVIC_DisableIRQ(furi_hal_interrupt_irqn[index]); +} void furi_hal_interrupt_init() { - NVIC_SetPriority(RCC_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0, 0)); - NVIC_EnableIRQ(RCC_IRQn); - NVIC_SetPriority( TAMP_STAMP_LSECSS_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0, 0)); NVIC_EnableIRQ(TAMP_STAMP_LSECSS_IRQn); - NVIC_SetPriority(DMA1_Channel1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); - NVIC_EnableIRQ(DMA1_Channel1_IRQn); + NVIC_SetPriority(PendSV_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 15, 0)); FURI_LOG_I(TAG, "Init OK"); } -void furi_hal_interrupt_set_timer_isr(TIM_TypeDef* timer, FuriHalInterruptISR isr) { - if(timer == TIM2) { - if(isr) { - furi_assert(furi_hal_tim_tim2_isr == NULL); - } else { - furi_assert(furi_hal_tim_tim2_isr != NULL); - } - furi_hal_tim_tim2_isr = isr; - } else if(timer == TIM1) { - if(isr) { - furi_assert(furi_hal_tim_tim1_isr == NULL); - } else { - furi_assert(furi_hal_tim_tim1_isr != NULL); - } - furi_hal_tim_tim1_isr = isr; - } else { - furi_crash(NULL); - } +void furi_hal_interrupt_set_isr(FuriHalInterruptId index, FuriHalInterruptISR isr, void* context) { + furi_hal_interrupt_set_isr_ex(index, FURI_HAL_INTERRUPT_DEFAULT_PRIORITY, isr, context); } -void furi_hal_interrupt_set_dma_channel_isr( - DMA_TypeDef* dma, - uint32_t channel, - FuriHalInterruptISR isr) { - --channel; // Pascal - furi_check(dma); - furi_check(channel < FURI_HAL_INTERRUPT_DMA_CHANNELS_COUNT); - if(dma == DMA1) { - furi_hal_dma_channel_isr[0][channel] = isr; - } else if(dma == DMA2) { - furi_hal_dma_channel_isr[1][channel] = isr; +void furi_hal_interrupt_set_isr_ex( + FuriHalInterruptId index, + uint16_t priority, + FuriHalInterruptISR isr, + void* context) { + furi_assert(index < FuriHalInterruptIdMax); + furi_assert(priority < 15); + furi_assert(furi_hal_interrupt_irqn[index]); + + if(isr) { + // Pre ISR set + furi_assert(furi_hal_interrupt_isr[index].isr == NULL); } else { - furi_crash(NULL); + // Pre ISR clear + furi_assert(furi_hal_interrupt_isr[index].isr != NULL); + furi_hal_interrupt_disable(index); + } + + furi_hal_interrupt_isr[index].isr = isr; + furi_hal_interrupt_isr[index].context = context; + __DMB(); + + if(isr) { + // Post ISR set + furi_hal_interrupt_enable(index, priority); + } else { + // Post ISR clear } } /* Timer 2 */ void TIM2_IRQHandler(void) { - if(furi_hal_tim_tim2_isr) { - furi_hal_tim_tim2_isr(); - } + furi_hal_interrupt_call(FuriHalInterruptIdTIM2); } /* Timer 1 Update */ void TIM1_UP_TIM16_IRQHandler(void) { - if(furi_hal_tim_tim1_isr) { - furi_hal_tim_tim1_isr(); - } + furi_hal_interrupt_call(FuriHalInterruptIdTim1UpTim16); } void TIM1_TRG_COM_TIM17_IRQHandler(void) { + furi_hal_interrupt_call(FuriHalInterruptIdTim1TrgComTim17); } void TIM1_CC_IRQHandler(void) { + furi_hal_interrupt_call(FuriHalInterruptIdTim1Cc); } /* DMA 1 */ void DMA1_Channel1_IRQHandler(void) { - if(furi_hal_dma_channel_isr[0][0]) furi_hal_dma_channel_isr[0][0](); + furi_hal_interrupt_call(FuriHalInterruptIdDma1Ch1); } void DMA1_Channel2_IRQHandler(void) { - if(furi_hal_dma_channel_isr[0][1]) furi_hal_dma_channel_isr[0][1](); + furi_hal_interrupt_call(FuriHalInterruptIdDma1Ch2); } void DMA1_Channel3_IRQHandler(void) { - if(furi_hal_dma_channel_isr[0][2]) furi_hal_dma_channel_isr[0][2](); + furi_hal_interrupt_call(FuriHalInterruptIdDma1Ch3); } void DMA1_Channel4_IRQHandler(void) { - if(furi_hal_dma_channel_isr[0][3]) furi_hal_dma_channel_isr[0][3](); + furi_hal_interrupt_call(FuriHalInterruptIdDma1Ch4); } void DMA1_Channel5_IRQHandler(void) { - if(furi_hal_dma_channel_isr[0][4]) furi_hal_dma_channel_isr[0][4](); + furi_hal_interrupt_call(FuriHalInterruptIdDma1Ch5); } void DMA1_Channel6_IRQHandler(void) { - if(furi_hal_dma_channel_isr[0][5]) furi_hal_dma_channel_isr[0][5](); + furi_hal_interrupt_call(FuriHalInterruptIdDma1Ch6); } void DMA1_Channel7_IRQHandler(void) { - if(furi_hal_dma_channel_isr[0][6]) furi_hal_dma_channel_isr[0][6](); -} - -void DMA1_Channel8_IRQHandler(void) { - if(furi_hal_dma_channel_isr[0][7]) furi_hal_dma_channel_isr[0][7](); + furi_hal_interrupt_call(FuriHalInterruptIdDma1Ch7); } /* DMA 2 */ void DMA2_Channel1_IRQHandler(void) { - if(furi_hal_dma_channel_isr[1][0]) furi_hal_dma_channel_isr[1][0](); + furi_hal_interrupt_call(FuriHalInterruptIdDma2Ch1); } void DMA2_Channel2_IRQHandler(void) { - if(furi_hal_dma_channel_isr[1][1]) furi_hal_dma_channel_isr[1][1](); + furi_hal_interrupt_call(FuriHalInterruptIdDma2Ch2); } void DMA2_Channel3_IRQHandler(void) { - if(furi_hal_dma_channel_isr[1][2]) furi_hal_dma_channel_isr[1][2](); + furi_hal_interrupt_call(FuriHalInterruptIdDma2Ch3); } void DMA2_Channel4_IRQHandler(void) { - if(furi_hal_dma_channel_isr[1][3]) furi_hal_dma_channel_isr[1][3](); + furi_hal_interrupt_call(FuriHalInterruptIdDma2Ch4); } void DMA2_Channel5_IRQHandler(void) { - if(furi_hal_dma_channel_isr[1][4]) furi_hal_dma_channel_isr[1][4](); + furi_hal_interrupt_call(FuriHalInterruptIdDma2Ch5); } void DMA2_Channel6_IRQHandler(void) { - if(furi_hal_dma_channel_isr[1][5]) furi_hal_dma_channel_isr[1][5](); + furi_hal_interrupt_call(FuriHalInterruptIdDma2Ch6); } void DMA2_Channel7_IRQHandler(void) { - if(furi_hal_dma_channel_isr[1][6]) furi_hal_dma_channel_isr[1][6](); + furi_hal_interrupt_call(FuriHalInterruptIdDma2Ch7); } -void DMA2_Channel8_IRQHandler(void) { - if(furi_hal_dma_channel_isr[1][7]) furi_hal_dma_channel_isr[1][7](); +void HSEM_IRQHandler(void) { + furi_hal_interrupt_call(FuriHalInterruptIdHsem); } void TAMP_STAMP_LSECSS_IRQHandler(void) { @@ -165,6 +211,7 @@ void TAMP_STAMP_LSECSS_IRQHandler(void) { } void RCC_IRQHandler(void) { + furi_hal_interrupt_call(FuriHalInterruptIdRcc); } void NMI_Handler(void) { @@ -193,3 +240,26 @@ void UsageFault_Handler(void) { void DebugMon_Handler(void) { } + +#include "usbd_core.h" + +extern usbd_device udev; + +extern void HW_IPCC_Tx_Handler(); +extern void HW_IPCC_Rx_Handler(); + +void SysTick_Handler(void) { + furi_hal_tick(); +} + +void USB_LP_IRQHandler(void) { + usbd_poll(&udev); +} + +void IPCC_C1_TX_IRQHandler(void) { + HW_IPCC_Tx_Handler(); +} + +void IPCC_C1_RX_IRQHandler(void) { + HW_IPCC_Rx_Handler(); +} diff --git a/firmware/targets/f7/furi_hal/furi_hal_interrupt.h b/firmware/targets/f7/furi_hal/furi_hal_interrupt.h index b4cb6030..725e779e 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_interrupt.h +++ b/firmware/targets/f7/furi_hal/furi_hal_interrupt.h @@ -7,29 +7,71 @@ extern "C" { #endif /** Timer ISR */ -typedef void (*FuriHalInterruptISR)(); +typedef void (*FuriHalInterruptISR)(void* context); + +typedef enum { + // TIM1, TIM16, TIM17 + FuriHalInterruptIdTim1TrgComTim17, + FuriHalInterruptIdTim1Cc, + FuriHalInterruptIdTim1UpTim16, + + // TIM2 + FuriHalInterruptIdTIM2, + + // DMA1 + FuriHalInterruptIdDma1Ch1, + FuriHalInterruptIdDma1Ch2, + FuriHalInterruptIdDma1Ch3, + FuriHalInterruptIdDma1Ch4, + FuriHalInterruptIdDma1Ch5, + FuriHalInterruptIdDma1Ch6, + FuriHalInterruptIdDma1Ch7, + + // DMA2 + FuriHalInterruptIdDma2Ch1, + FuriHalInterruptIdDma2Ch2, + FuriHalInterruptIdDma2Ch3, + FuriHalInterruptIdDma2Ch4, + FuriHalInterruptIdDma2Ch5, + FuriHalInterruptIdDma2Ch6, + FuriHalInterruptIdDma2Ch7, + + // RCC + FuriHalInterruptIdRcc, + + // Comp + FuriHalInterruptIdCOMP, + + // HSEM + FuriHalInterruptIdHsem, + + // Service value + FuriHalInterruptIdMax, +} FuriHalInterruptId; /** Initialize interrupt subsystem */ void furi_hal_interrupt_init(); -/** Set DMA Channel ISR +/** Set ISR and enable interrupt with default priority * We don't clear interrupt flags for you, do it by your self. - * @param dma - DMA instance - * @param channel - DMA channel + * @param index - interrupt ID * @param isr - your interrupt service routine or use NULL to clear + * @param context - isr context */ -void furi_hal_interrupt_set_dma_channel_isr( - DMA_TypeDef* dma, - uint32_t channel, - FuriHalInterruptISR isr); +void furi_hal_interrupt_set_isr(FuriHalInterruptId index, FuriHalInterruptISR isr, void* context); -/** Set Timer ISR - * By default ISR is serviced by ST HAL. Use this function to override it. +/** Set ISR and enable interrupt with custom priority * We don't clear interrupt flags for you, do it by your self. - * @param timer - timer instance + * @param index - interrupt ID + * @param priority - 0 to 15, 0 highest * @param isr - your interrupt service routine or use NULL to clear + * @param context - isr context */ -void furi_hal_interrupt_set_timer_isr(TIM_TypeDef* timer, FuriHalInterruptISR isr); +void furi_hal_interrupt_set_isr_ex( + FuriHalInterruptId index, + uint16_t priority, + FuriHalInterruptISR isr, + void* context); #ifdef __cplusplus } diff --git a/firmware/targets/f7/furi_hal/furi_hal_os.c b/firmware/targets/f7/furi_hal/furi_hal_os.c index 3a6e5f38..6ef5a9f4 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_os.c +++ b/firmware/targets/f7/furi_hal/furi_hal_os.c @@ -115,11 +115,11 @@ void vPortSuppressTicksAndSleep(TickType_t expected_idle_ticks) { } // Stop IRQ handling, no one should disturb us till we finish - FURI_CRITICAL_ENTER(); + __disable_irq(); // Confirm OS that sleep is still possible if(eTaskConfirmSleepModeStatus() == eAbortSleep) { - FURI_CRITICAL_EXIT(); + __enable_irq(); return; } @@ -136,7 +136,7 @@ void vPortSuppressTicksAndSleep(TickType_t expected_idle_ticks) { } // Reenable IRQ - FURI_CRITICAL_EXIT(); + __enable_irq(); } void vApplicationStackOverflowHook(TaskHandle_t xTask, char* pcTaskName) { diff --git a/firmware/targets/f7/furi_hal/furi_hal_os_timer.h b/firmware/targets/f7/furi_hal/furi_hal_os_timer.h index 5a827313..dd01ac60 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_os_timer.h +++ b/firmware/targets/f7/furi_hal/furi_hal_os_timer.h @@ -2,6 +2,7 @@ #include #include +#include #include // Timer used for system ticks diff --git a/firmware/targets/f7/furi_hal/furi_hal_power.c b/firmware/targets/f7/furi_hal/furi_hal_power.c index e34ba46e..ec30656e 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_power.c +++ b/firmware/targets/f7/furi_hal/furi_hal_power.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -8,7 +9,6 @@ #include #include -#include #include #include #include diff --git a/firmware/targets/f7/furi_hal/furi_hal_resources.c b/firmware/targets/f7/furi_hal/furi_hal_resources.c index f8cc8fcf..734967b7 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_resources.c +++ b/firmware/targets/f7/furi_hal/furi_hal_resources.c @@ -1,42 +1,6 @@ #include -#include "main.h" #include -const InputPin input_pins[] = { - {.port = BUTTON_UP_GPIO_Port, - .pin = BUTTON_UP_Pin, - .key = InputKeyUp, - .inverted = true, - .name = "Up"}, - {.port = BUTTON_DOWN_GPIO_Port, - .pin = BUTTON_DOWN_Pin, - .key = InputKeyDown, - .inverted = true, - .name = "Down"}, - {.port = BUTTON_RIGHT_GPIO_Port, - .pin = BUTTON_RIGHT_Pin, - .key = InputKeyRight, - .inverted = true, - .name = "Right"}, - {.port = BUTTON_LEFT_GPIO_Port, - .pin = BUTTON_LEFT_Pin, - .key = InputKeyLeft, - .inverted = true, - .name = "Left"}, - {.port = BUTTON_OK_GPIO_Port, - .pin = BUTTON_OK_Pin, - .key = InputKeyOk, - .inverted = false, - .name = "Ok"}, - {.port = BUTTON_BACK_GPIO_Port, - .pin = BUTTON_BACK_Pin, - .key = InputKeyBack, - .inverted = true, - .name = "Back"}, -}; - -const size_t input_pins_count = sizeof(input_pins) / sizeof(InputPin); - const GpioPin vibro_gpio = {.port = VIBRO_GPIO_Port, .pin = VIBRO_Pin}; const GpioPin ibutton_gpio = {.port = iBTN_GPIO_Port, .pin = iBTN_Pin}; @@ -48,8 +12,16 @@ const GpioPin gpio_display_cs = {.port = DISPLAY_CS_GPIO_Port, .pin = DISPLAY_CS const GpioPin gpio_display_rst = {.port = DISPLAY_RST_GPIO_Port, .pin = DISPLAY_RST_Pin}; const GpioPin gpio_display_di = {.port = DISPLAY_DI_GPIO_Port, .pin = DISPLAY_DI_Pin}; const GpioPin gpio_sdcard_cs = {.port = SD_CS_GPIO_Port, .pin = SD_CS_Pin}; +const GpioPin gpio_sdcard_cd = {.port = SD_CD_GPIO_Port, .pin = SD_CD_Pin}; const GpioPin gpio_nfc_cs = {.port = NFC_CS_GPIO_Port, .pin = NFC_CS_Pin}; +const GpioPin gpio_button_up = {.port = GPIOB, .pin = LL_GPIO_PIN_10}; +const GpioPin gpio_button_down = {.port = GPIOC, .pin = LL_GPIO_PIN_6}; +const GpioPin gpio_button_right = {.port = GPIOB, .pin = LL_GPIO_PIN_12}; +const GpioPin gpio_button_left = {.port = GPIOB, .pin = LL_GPIO_PIN_11}; +const GpioPin gpio_button_ok = {.port = GPIOH, .pin = LL_GPIO_PIN_3}; +const GpioPin gpio_button_back = {.port = GPIOC, .pin = LL_GPIO_PIN_13}; + const GpioPin gpio_spi_d_miso = {.port = SPI_D_MISO_GPIO_Port, .pin = SPI_D_MISO_Pin}; const GpioPin gpio_spi_d_mosi = {.port = SPI_D_MOSI_GPIO_Port, .pin = SPI_D_MOSI_Pin}; const GpioPin gpio_spi_d_sck = {.port = SPI_D_SCK_GPIO_Port, .pin = SPI_D_SCK_Pin}; @@ -57,14 +29,14 @@ const GpioPin gpio_spi_r_miso = {.port = SPI_R_MISO_GPIO_Port, .pin = SPI_R_MISO const GpioPin gpio_spi_r_mosi = {.port = SPI_R_MOSI_GPIO_Port, .pin = SPI_R_MOSI_Pin}; const GpioPin gpio_spi_r_sck = {.port = SPI_R_SCK_GPIO_Port, .pin = SPI_R_SCK_Pin}; -const GpioPin gpio_ext_pc0 = {.port = GPIOC, .pin = GPIO_PIN_0}; -const GpioPin gpio_ext_pc1 = {.port = GPIOC, .pin = GPIO_PIN_1}; -const GpioPin gpio_ext_pc3 = {.port = GPIOC, .pin = GPIO_PIN_3}; -const GpioPin gpio_ext_pb2 = {.port = GPIOB, .pin = GPIO_PIN_2}; -const GpioPin gpio_ext_pb3 = {.port = GPIOB, .pin = GPIO_PIN_3}; -const GpioPin gpio_ext_pa4 = {.port = GPIOA, .pin = GPIO_PIN_4}; -const GpioPin gpio_ext_pa6 = {.port = GPIOA, .pin = GPIO_PIN_6}; -const GpioPin gpio_ext_pa7 = {.port = GPIOA, .pin = GPIO_PIN_7}; +const GpioPin gpio_ext_pc0 = {.port = GPIOC, .pin = LL_GPIO_PIN_0}; +const GpioPin gpio_ext_pc1 = {.port = GPIOC, .pin = LL_GPIO_PIN_1}; +const GpioPin gpio_ext_pc3 = {.port = GPIOC, .pin = LL_GPIO_PIN_3}; +const GpioPin gpio_ext_pb2 = {.port = GPIOB, .pin = LL_GPIO_PIN_2}; +const GpioPin gpio_ext_pb3 = {.port = GPIOB, .pin = LL_GPIO_PIN_3}; +const GpioPin gpio_ext_pa4 = {.port = GPIOA, .pin = LL_GPIO_PIN_4}; +const GpioPin gpio_ext_pa6 = {.port = GPIOA, .pin = LL_GPIO_PIN_6}; +const GpioPin gpio_ext_pa7 = {.port = GPIOA, .pin = LL_GPIO_PIN_7}; const GpioPin gpio_rfid_pull = {.port = RFID_PULL_GPIO_Port, .pin = RFID_PULL_Pin}; const GpioPin gpio_rfid_carrier_out = {.port = RFID_OUT_GPIO_Port, .pin = RFID_OUT_Pin}; @@ -81,3 +53,76 @@ const GpioPin gpio_i2c_power_sda = {.port = GPIOA, .pin = LL_GPIO_PIN_10}; const GpioPin gpio_i2c_power_scl = {.port = GPIOA, .pin = LL_GPIO_PIN_9}; const GpioPin gpio_speaker = {.port = GPIOB, .pin = LL_GPIO_PIN_8}; + +const GpioPin periph_power = {.port = PERIPH_POWER_GPIO_Port, .pin = PERIPH_POWER_Pin}; + +const InputPin input_pins[] = { + {.gpio = &gpio_button_up, .key = InputKeyUp, .inverted = true, .name = "Up"}, + {.gpio = &gpio_button_down, .key = InputKeyDown, .inverted = true, .name = "Down"}, + {.gpio = &gpio_button_right, .key = InputKeyRight, .inverted = true, .name = "Right"}, + {.gpio = &gpio_button_left, .key = InputKeyLeft, .inverted = true, .name = "Left"}, + {.gpio = &gpio_button_ok, .key = InputKeyOk, .inverted = false, .name = "Ok"}, + {.gpio = &gpio_button_back, .key = InputKeyBack, .inverted = true, .name = "Back"}, +}; + +const size_t input_pins_count = sizeof(input_pins) / sizeof(InputPin); + +void furi_hal_resources_init(void) { + // Button pins + for(size_t i = 0; i < input_pins_count; i++) { + furi_hal_gpio_init( + input_pins[i].gpio, GpioModeInterruptRiseFall, GpioPullUp, GpioSpeedLow); + } + + // External header pins + furi_hal_gpio_init(&gpio_ext_pc0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_ext_pc1, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_ext_pc3, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_ext_pb2, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_ext_pb3, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_ext_pa4, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_ext_pa6, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_ext_pa7, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + + // Display pins + furi_hal_gpio_init(&gpio_display_rst, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_write(&gpio_display_rst, 0); + + furi_hal_gpio_init(&gpio_display_di, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_write(&gpio_display_di, 0); + + // SD pins + furi_hal_gpio_init(&gpio_sdcard_cd, GpioModeInput, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_write(&gpio_sdcard_cd, 0); + + furi_hal_gpio_init(&vibro_gpio, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + + furi_hal_gpio_init(&ibutton_gpio, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + + furi_hal_gpio_init(&gpio_rfid_pull, GpioModeInterruptRise, GpioPullNo, GpioSpeedLow); + + furi_hal_gpio_init(&gpio_rf_sw_0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); + + furi_hal_gpio_init(&periph_power, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow); + + NVIC_SetPriority(EXTI0_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); + NVIC_EnableIRQ(EXTI0_IRQn); + + NVIC_SetPriority(EXTI1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); + NVIC_EnableIRQ(EXTI1_IRQn); + + NVIC_SetPriority(EXTI2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); + NVIC_EnableIRQ(EXTI2_IRQn); + + NVIC_SetPriority(EXTI3_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); + NVIC_EnableIRQ(EXTI3_IRQn); + + NVIC_SetPriority(EXTI4_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); + NVIC_EnableIRQ(EXTI4_IRQn); + + NVIC_SetPriority(EXTI9_5_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); + NVIC_EnableIRQ(EXTI9_5_IRQn); + + NVIC_SetPriority(EXTI15_10_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); + NVIC_EnableIRQ(EXTI15_10_IRQn); +} diff --git a/firmware/targets/f7/furi_hal/furi_hal_resources.h b/firmware/targets/f7/furi_hal/furi_hal_resources.h index 6504afeb..1f3a4bce 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_resources.h +++ b/firmware/targets/f7/furi_hal/furi_hal_resources.h @@ -1,6 +1,5 @@ #pragma once -#include "main.h" #include #include @@ -32,8 +31,7 @@ typedef enum { } Light; typedef struct { - const GPIO_TypeDef* port; - const uint16_t pin; + const GpioPin* gpio; const InputKey key; const bool inverted; const char* name; @@ -53,6 +51,7 @@ extern const GpioPin gpio_display_cs; extern const GpioPin gpio_display_rst; extern const GpioPin gpio_display_di; extern const GpioPin gpio_sdcard_cs; +extern const GpioPin gpio_sdcard_cd; extern const GpioPin gpio_nfc_cs; extern const GpioPin gpio_spi_d_miso; @@ -86,6 +85,116 @@ extern const GpioPin gpio_i2c_power_scl; extern const GpioPin gpio_speaker; +extern const GpioPin periph_power; + +#define BUTTON_BACK_GPIO_Port GPIOC +#define BUTTON_BACK_Pin LL_GPIO_PIN_13 +#define BUTTON_DOWN_GPIO_Port GPIOC +#define BUTTON_DOWN_Pin LL_GPIO_PIN_6 +#define BUTTON_LEFT_GPIO_Port GPIOB +#define BUTTON_LEFT_Pin LL_GPIO_PIN_11 +#define BUTTON_OK_GPIO_Port GPIOH +#define BUTTON_OK_Pin LL_GPIO_PIN_3 +#define BUTTON_RIGHT_GPIO_Port GPIOB +#define BUTTON_RIGHT_Pin LL_GPIO_PIN_12 +#define BUTTON_UP_GPIO_Port GPIOB +#define BUTTON_UP_Pin LL_GPIO_PIN_10 + +#define CC1101_CS_GPIO_Port GPIOD +#define CC1101_CS_Pin LL_GPIO_PIN_0 +#define CC1101_G0_GPIO_Port GPIOA +#define CC1101_G0_Pin LL_GPIO_PIN_1 + +#define DISPLAY_CS_GPIO_Port GPIOC +#define DISPLAY_CS_Pin LL_GPIO_PIN_11 +#define DISPLAY_DI_GPIO_Port GPIOB +#define DISPLAY_DI_Pin LL_GPIO_PIN_1 +#define DISPLAY_RST_GPIO_Port GPIOB +#define DISPLAY_RST_Pin LL_GPIO_PIN_0 + +#define IR_RX_GPIO_Port GPIOA +#define IR_RX_Pin LL_GPIO_PIN_0 +#define IR_TX_GPIO_Port GPIOB +#define IR_TX_Pin LL_GPIO_PIN_9 + +#define NFC_CS_GPIO_Port GPIOE +#define NFC_CS_Pin LL_GPIO_PIN_4 + +#define PA4_GPIO_Port GPIOA +#define PA4_Pin LL_GPIO_PIN_4 +#define PA6_GPIO_Port GPIOA +#define PA6_Pin LL_GPIO_PIN_6 +#define PA7_GPIO_Port GPIOA +#define PA7_Pin LL_GPIO_PIN_7 +#define PB2_GPIO_Port GPIOB +#define PB2_Pin LL_GPIO_PIN_2 +#define PB3_GPIO_Port GPIOB +#define PB3_Pin LL_GPIO_PIN_3 +#define PC0_GPIO_Port GPIOC +#define PC0_Pin LL_GPIO_PIN_0 +#define PC1_GPIO_Port GPIOC +#define PC1_Pin LL_GPIO_PIN_1 +#define PC3_GPIO_Port GPIOC +#define PC3_Pin LL_GPIO_PIN_3 + +#define PERIPH_POWER_GPIO_Port GPIOA +#define PERIPH_POWER_Pin LL_GPIO_PIN_3 + +#define QUARTZ_32MHZ_IN_GPIO_Port GPIOC +#define QUARTZ_32MHZ_IN_Pin LL_GPIO_PIN_14 +#define QUARTZ_32MHZ_OUT_GPIO_Port GPIOC +#define QUARTZ_32MHZ_OUT_Pin LL_GPIO_PIN_15 + +#define RFID_OUT_GPIO_Port GPIOB +#define RFID_OUT_Pin LL_GPIO_PIN_13 +#define RFID_PULL_GPIO_Port GPIOA +#define RFID_PULL_Pin LL_GPIO_PIN_2 +#define RFID_RF_IN_GPIO_Port GPIOC +#define RFID_RF_IN_Pin LL_GPIO_PIN_5 +#define RFID_CARRIER_GPIO_Port GPIOA +#define RFID_CARRIER_Pin LL_GPIO_PIN_15 + +#define RF_SW_0_GPIO_Port GPIOC +#define RF_SW_0_Pin LL_GPIO_PIN_4 + +#define SD_CD_GPIO_Port GPIOC +#define SD_CD_Pin LL_GPIO_PIN_10 +#define SD_CS_GPIO_Port GPIOC +#define SD_CS_Pin LL_GPIO_PIN_12 + +#define SPEAKER_GPIO_Port GPIOB +#define SPEAKER_Pin LL_GPIO_PIN_8 + +#define VIBRO_GPIO_Port GPIOA +#define VIBRO_Pin LL_GPIO_PIN_8 + +#define iBTN_GPIO_Port GPIOB +#define iBTN_Pin LL_GPIO_PIN_14 + +#define USART1_TX_Pin LL_GPIO_PIN_6 +#define USART1_TX_Port GPIOB +#define USART1_RX_Pin LL_GPIO_PIN_7 +#define USART1_RX_Port GPIOB + +#define SPI_D_MISO_GPIO_Port GPIOC +#define SPI_D_MISO_Pin LL_GPIO_PIN_2 +#define SPI_D_MOSI_GPIO_Port GPIOB +#define SPI_D_MOSI_Pin LL_GPIO_PIN_15 +#define SPI_D_SCK_GPIO_Port GPIOD +#define SPI_D_SCK_Pin LL_GPIO_PIN_1 + +#define SPI_R_MISO_GPIO_Port GPIOB +#define SPI_R_MISO_Pin LL_GPIO_PIN_4 +#define SPI_R_MOSI_GPIO_Port GPIOB +#define SPI_R_MOSI_Pin LL_GPIO_PIN_5 +#define SPI_R_SCK_GPIO_Port GPIOA +#define SPI_R_SCK_Pin LL_GPIO_PIN_5 + +#define NFC_IRQ_Pin RFID_PULL_Pin +#define NFC_IRQ_GPIO_Port RFID_PULL_GPIO_Port + +void furi_hal_resources_init(void); + #ifdef __cplusplus } #endif diff --git a/firmware/targets/f7/furi_hal/furi_hal_rfid.c b/firmware/targets/f7/furi_hal/furi_hal_rfid.c index 6efd83a1..964bd12b 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_rfid.c +++ b/firmware/targets/f7/furi_hal/furi_hal_rfid.c @@ -13,7 +13,7 @@ #define FURI_HAL_RFID_READ_TIMER_CHANNEL_CONFIG LL_TIM_CHANNEL_CH1 #define FURI_HAL_RFID_EMULATE_TIMER TIM2 -#define FURI_HAL_RFID_EMULATE_TIMER_IRQ TIM2_IRQn +#define FURI_HAL_RFID_EMULATE_TIMER_IRQ FuriHalInterruptIdTIM2 #define FURI_HAL_RFID_EMULATE_TIMER_CHANNEL LL_TIM_CHANNEL_CH3 typedef struct { @@ -23,6 +23,13 @@ typedef struct { FuriHalRfid* furi_hal_rfid = NULL; +#define LFRFID_LL_READ_TIM TIM1 +#define LFRFID_LL_READ_CONFIG_CHANNEL LL_TIM_CHANNEL_CH1 +#define LFRFID_LL_READ_CHANNEL LL_TIM_CHANNEL_CH1N + +#define LFRFID_LL_EMULATE_TIM TIM2 +#define LFRFID_LL_EMULATE_CHANNEL LL_TIM_CHANNEL_CH3 + void furi_hal_rfid_init() { furi_assert(furi_hal_rfid == NULL); furi_hal_rfid = malloc(sizeof(FuriHalRfid)); @@ -58,46 +65,46 @@ void furi_hal_rfid_pins_reset() { furi_hal_ibutton_stop(); // pulldown rfid antenna - hal_gpio_init(&gpio_rfid_carrier_out, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); - hal_gpio_write(&gpio_rfid_carrier_out, false); + furi_hal_gpio_init(&gpio_rfid_carrier_out, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_write(&gpio_rfid_carrier_out, false); // from both sides - hal_gpio_init(&gpio_rfid_pull, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); - hal_gpio_write(&gpio_rfid_pull, true); + furi_hal_gpio_init(&gpio_rfid_pull, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_write(&gpio_rfid_pull, true); - hal_gpio_init_simple(&gpio_rfid_carrier, GpioModeAnalog); + furi_hal_gpio_init_simple(&gpio_rfid_carrier, GpioModeAnalog); - hal_gpio_init(&gpio_rfid_data_in, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_rfid_data_in, GpioModeAnalog, GpioPullNo, GpioSpeedLow); } void furi_hal_rfid_pins_emulate() { // ibutton low - furi_hal_ibutton_start(); + furi_hal_ibutton_start_drive(); furi_hal_ibutton_pin_low(); // pull pin to timer out - hal_gpio_init_ex( + furi_hal_gpio_init_ex( &gpio_rfid_pull, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2); // pull rfid antenna from carrier side - hal_gpio_init(&gpio_rfid_carrier_out, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); - hal_gpio_write(&gpio_rfid_carrier_out, false); + furi_hal_gpio_init(&gpio_rfid_carrier_out, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_write(&gpio_rfid_carrier_out, false); - hal_gpio_init_ex( + furi_hal_gpio_init_ex( &gpio_rfid_carrier, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn2TIM2); } void furi_hal_rfid_pins_read() { // ibutton low - furi_hal_ibutton_start(); + furi_hal_ibutton_start_drive(); furi_hal_ibutton_pin_low(); // dont pull rfid antenna - hal_gpio_init(&gpio_rfid_pull, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); - hal_gpio_write(&gpio_rfid_pull, false); + furi_hal_gpio_init(&gpio_rfid_pull, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_write(&gpio_rfid_pull, false); // carrier pin to timer out - hal_gpio_init_ex( + furi_hal_gpio_init_ex( &gpio_rfid_carrier_out, GpioModeAltFunctionPushPull, GpioPullNo, @@ -105,15 +112,15 @@ void furi_hal_rfid_pins_read() { GpioAltFn1TIM1); // comparator in - hal_gpio_init(&gpio_rfid_data_in, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_rfid_data_in, GpioModeAnalog, GpioPullNo, GpioSpeedLow); } void furi_hal_rfid_pin_pull_release() { - hal_gpio_write(&gpio_rfid_pull, true); + furi_hal_gpio_write(&gpio_rfid_pull, true); } void furi_hal_rfid_pin_pull_pulldown() { - hal_gpio_write(&gpio_rfid_pull, false); + furi_hal_gpio_write(&gpio_rfid_pull, false); } void furi_hal_rfid_tim_read(float freq, float duty_cycle) { @@ -187,15 +194,7 @@ void furi_hal_rfid_tim_emulate_start(FuriHalRfidEmulateCallback callback, void* furi_hal_rfid->callback = callback; furi_hal_rfid->context = context; - // TODO make api for interrupts priority - for(size_t i = WWDG_IRQn; i <= DMAMUX1_OVR_IRQn; i++) { - HAL_NVIC_SetPriority(i, 15, 0); - } - - furi_hal_interrupt_set_timer_isr(FURI_HAL_RFID_EMULATE_TIMER, furi_hal_rfid_emulate_isr); - NVIC_SetPriority( - FURI_HAL_RFID_EMULATE_TIMER_IRQ, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); - NVIC_EnableIRQ(FURI_HAL_RFID_EMULATE_TIMER_IRQ); + furi_hal_interrupt_set_isr(FURI_HAL_RFID_EMULATE_TIMER_IRQ, furi_hal_rfid_emulate_isr, NULL); LL_TIM_EnableIT_UPDATE(FURI_HAL_RFID_EMULATE_TIMER); LL_TIM_EnableAllOutputs(FURI_HAL_RFID_EMULATE_TIMER); @@ -205,7 +204,7 @@ void furi_hal_rfid_tim_emulate_start(FuriHalRfidEmulateCallback callback, void* void furi_hal_rfid_tim_emulate_stop() { LL_TIM_DisableCounter(FURI_HAL_RFID_EMULATE_TIMER); LL_TIM_DisableAllOutputs(FURI_HAL_RFID_EMULATE_TIMER); - furi_hal_interrupt_set_timer_isr(FURI_HAL_RFID_EMULATE_TIMER, NULL); + furi_hal_interrupt_set_isr(FURI_HAL_RFID_EMULATE_TIMER_IRQ, NULL, NULL); } void furi_hal_rfid_tim_reset() { diff --git a/firmware/targets/f7/furi_hal/furi_hal_sd.c b/firmware/targets/f7/furi_hal/furi_hal_sd.c index c62b4aa5..688a4e61 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_sd.c +++ b/firmware/targets/f7/furi_hal/furi_hal_sd.c @@ -1,6 +1,7 @@ #include "furi_hal_sd.h" #include #include +#include void hal_sd_detect_init(void) { // low speed input with pullup diff --git a/firmware/targets/f7/furi_hal/furi_hal_speaker.c b/firmware/targets/f7/furi_hal/furi_hal_speaker.c index a9b6c011..80c69a08 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_speaker.c +++ b/firmware/targets/f7/furi_hal/furi_hal_speaker.c @@ -16,7 +16,7 @@ void furi_hal_speaker_init() { LL_TIM_DeInit(FURI_HAL_SPEAKER_TIMER); FURI_CRITICAL_EXIT(); - hal_gpio_init_ex( + furi_hal_gpio_init_ex( &gpio_speaker, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn14TIM16); } diff --git a/firmware/targets/f7/furi_hal/furi_hal_spi_config.c b/firmware/targets/f7/furi_hal/furi_hal_spi_config.c index 2d110b83..440a64a0 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_spi_config.c +++ b/firmware/targets/f7/furi_hal/furi_hal_spi_config.c @@ -139,42 +139,42 @@ inline static void furi_hal_spi_bus_r_handle_event_callback( FuriHalSpiBusHandleEvent event, const LL_SPI_InitTypeDef* preset) { if(event == FuriHalSpiBusHandleEventInit) { - hal_gpio_write(handle->cs, true); - hal_gpio_init(handle->cs, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); + furi_hal_gpio_write(handle->cs, true); + furi_hal_gpio_init(handle->cs, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); } else if(event == FuriHalSpiBusHandleEventDeinit) { - hal_gpio_write(handle->cs, true); - hal_gpio_init(handle->cs, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_write(handle->cs, true); + furi_hal_gpio_init(handle->cs, GpioModeAnalog, GpioPullNo, GpioSpeedLow); } else if(event == FuriHalSpiBusHandleEventActivate) { LL_SPI_Init(handle->bus->spi, (LL_SPI_InitTypeDef*)preset); LL_SPI_SetRxFIFOThreshold(handle->bus->spi, LL_SPI_RX_FIFO_TH_QUARTER); LL_SPI_Enable(handle->bus->spi); - hal_gpio_init_ex( + furi_hal_gpio_init_ex( handle->miso, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI1); - hal_gpio_init_ex( + furi_hal_gpio_init_ex( handle->mosi, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI1); - hal_gpio_init_ex( + furi_hal_gpio_init_ex( handle->sck, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI1); - hal_gpio_write(handle->cs, false); + furi_hal_gpio_write(handle->cs, false); } else if(event == FuriHalSpiBusHandleEventDeactivate) { - hal_gpio_write(handle->cs, true); + furi_hal_gpio_write(handle->cs, true); - hal_gpio_init(handle->miso, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - hal_gpio_init(handle->mosi, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - hal_gpio_init(handle->sck, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(handle->miso, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(handle->mosi, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(handle->sck, GpioModeAnalog, GpioPullNo, GpioSpeedLow); LL_SPI_Disable(handle->bus->spi); } @@ -230,22 +230,22 @@ inline static void furi_hal_spi_bus_d_handle_event_callback( FuriHalSpiBusHandleEvent event, const LL_SPI_InitTypeDef* preset) { if(event == FuriHalSpiBusHandleEventInit) { - hal_gpio_write(handle->cs, true); - hal_gpio_init(handle->cs, GpioModeOutputPushPull, GpioPullUp, GpioSpeedVeryHigh); + furi_hal_gpio_write(handle->cs, true); + furi_hal_gpio_init(handle->cs, GpioModeOutputPushPull, GpioPullUp, GpioSpeedVeryHigh); - hal_gpio_init_ex( + furi_hal_gpio_init_ex( handle->miso, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI2); - hal_gpio_init_ex( + furi_hal_gpio_init_ex( handle->mosi, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn5SPI2); - hal_gpio_init_ex( + furi_hal_gpio_init_ex( handle->sck, GpioModeAltFunctionPushPull, GpioPullNo, @@ -253,15 +253,15 @@ inline static void furi_hal_spi_bus_d_handle_event_callback( GpioAltFn5SPI2); } else if(event == FuriHalSpiBusHandleEventDeinit) { - hal_gpio_write(handle->cs, true); - hal_gpio_init(handle->cs, GpioModeAnalog, GpioPullUp, GpioSpeedLow); + furi_hal_gpio_write(handle->cs, true); + furi_hal_gpio_init(handle->cs, GpioModeAnalog, GpioPullUp, GpioSpeedLow); } else if(event == FuriHalSpiBusHandleEventActivate) { LL_SPI_Init(handle->bus->spi, (LL_SPI_InitTypeDef*)preset); LL_SPI_SetRxFIFOThreshold(handle->bus->spi, LL_SPI_RX_FIFO_TH_QUARTER); LL_SPI_Enable(handle->bus->spi); - hal_gpio_write(handle->cs, false); + furi_hal_gpio_write(handle->cs, false); } else if(event == FuriHalSpiBusHandleEventDeactivate) { - hal_gpio_write(handle->cs, true); + furi_hal_gpio_write(handle->cs, true); LL_SPI_Disable(handle->bus->spi); } } diff --git a/firmware/targets/f7/furi_hal/furi_hal_subghz.c b/firmware/targets/f7/furi_hal/furi_hal_subghz.c index 1c498ed3..b64b2d7f 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_subghz.c +++ b/firmware/targets/f7/furi_hal/furi_hal_subghz.c @@ -7,6 +7,8 @@ #include #include +#include + #include #include #include @@ -328,34 +330,34 @@ void furi_hal_subghz_init() { furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); #ifdef FURI_HAL_SUBGHZ_TX_GPIO - hal_gpio_init(&FURI_HAL_SUBGHZ_TX_GPIO, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&FURI_HAL_SUBGHZ_TX_GPIO, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); #endif // Reset - hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); cc1101_reset(&furi_hal_spi_bus_handle_subghz); cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHighImpedance); // Prepare GD0 for power on self test - hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); // GD0 low cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHW); - while(hal_gpio_read(&gpio_cc1101_g0) != false) + while(furi_hal_gpio_read(&gpio_cc1101_g0) != false) ; // GD0 high cc1101_write_reg( &furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHW | CC1101_IOCFG_INV); - while(hal_gpio_read(&gpio_cc1101_g0) != true) + while(furi_hal_gpio_read(&gpio_cc1101_g0) != true) ; // Reset GD0 to floating state cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHighImpedance); - hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); // RF switches - hal_gpio_init(&gpio_rf_sw_0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_rf_sw_0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW); // Go to sleep @@ -372,7 +374,7 @@ void furi_hal_subghz_sleep() { cc1101_switch_to_idle(&furi_hal_spi_bus_handle_subghz); cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHighImpedance); - hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); cc1101_shutdown(&furi_hal_spi_bus_handle_subghz); @@ -493,7 +495,7 @@ void furi_hal_subghz_shutdown() { void furi_hal_subghz_reset() { furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); - hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); cc1101_switch_to_idle(&furi_hal_spi_bus_handle_subghz); cc1101_reset(&furi_hal_spi_bus_handle_subghz); cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHighImpedance); @@ -634,18 +636,18 @@ uint32_t furi_hal_subghz_set_frequency(uint32_t value) { void furi_hal_subghz_set_path(FuriHalSubGhzPath path) { furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz); if(path == FuriHalSubGhzPath433) { - hal_gpio_write(&gpio_rf_sw_0, 0); + furi_hal_gpio_write(&gpio_rf_sw_0, 0); cc1101_write_reg( &furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); } else if(path == FuriHalSubGhzPath315) { - hal_gpio_write(&gpio_rf_sw_0, 1); + furi_hal_gpio_write(&gpio_rf_sw_0, 1); cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW); } else if(path == FuriHalSubGhzPath868) { - hal_gpio_write(&gpio_rf_sw_0, 1); + furi_hal_gpio_write(&gpio_rf_sw_0, 1); cc1101_write_reg( &furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV); } else if(path == FuriHalSubGhzPathIsolate) { - hal_gpio_write(&gpio_rf_sw_0, 0); + furi_hal_gpio_write(&gpio_rf_sw_0, 0); cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW); } else { furi_crash(NULL); @@ -688,7 +690,7 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* furi_hal_subghz_capture_callback = callback; furi_hal_subghz_capture_callback_context = context; - hal_gpio_init_ex( + furi_hal_gpio_init_ex( &gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2); // Timer: base @@ -722,9 +724,7 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* LL_TIM_IC_SetFilter(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_IC_FILTER_FDIV32_N8); // ISR setup - furi_hal_interrupt_set_timer_isr(TIM2, furi_hal_subghz_capture_ISR); - NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); - NVIC_EnableIRQ(TIM2_IRQn); + furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, furi_hal_subghz_capture_ISR, NULL); // Interrupts and channels LL_TIM_EnableIT_CC1(TIM2); @@ -750,9 +750,9 @@ void furi_hal_subghz_stop_async_rx() { FURI_CRITICAL_ENTER(); LL_TIM_DeInit(TIM2); FURI_CRITICAL_EXIT(); - furi_hal_interrupt_set_timer_isr(TIM2, NULL); + furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, NULL, NULL); - hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); } #define API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL (256) @@ -840,7 +840,7 @@ static void furi_hal_subghz_async_tx_timer_isr() { if(furi_hal_subghz_state == SubGhzStateAsyncTx) { furi_hal_subghz_state = SubGhzStateAsyncTxLast; //forcibly pulls the pin to the ground so that there is no carrier - hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullDown, GpioSpeedLow); + furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullDown, GpioSpeedLow); } else { furi_hal_subghz_state = SubGhzStateAsyncTxEnd; LL_TIM_DisableCounter(TIM2); @@ -870,7 +870,7 @@ bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* furi_hal_subghz_async_tx.buffer, API_HAL_SUBGHZ_ASYNC_TX_BUFFER_FULL); // Connect CC1101_GD0 to TIM2 as output - hal_gpio_init_ex( + furi_hal_gpio_init_ex( &gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullDown, GpioSpeedLow, GpioAltFn1TIM2); // Configure DMA @@ -887,8 +887,7 @@ bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM2_UP; dma_config.Priority = LL_DMA_MODE_NORMAL; LL_DMA_Init(DMA1, LL_DMA_CHANNEL_1, &dma_config); - furi_hal_interrupt_set_dma_channel_isr( - DMA1, LL_DMA_CHANNEL_1, furi_hal_subghz_async_tx_dma_isr); + furi_hal_interrupt_set_isr(FuriHalInterruptIdDma1Ch1, furi_hal_subghz_async_tx_dma_isr, NULL); LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1); LL_DMA_EnableIT_HT(DMA1, LL_DMA_CHANNEL_1); LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1); @@ -914,9 +913,7 @@ bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* LL_TIM_OC_DisableFast(TIM2, LL_TIM_CHANNEL_CH2); LL_TIM_DisableMasterSlaveMode(TIM2); - furi_hal_interrupt_set_timer_isr(TIM2, furi_hal_subghz_async_tx_timer_isr); - NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); - NVIC_EnableIRQ(TIM2_IRQn); + furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, furi_hal_subghz_async_tx_timer_isr, NULL); LL_TIM_EnableIT_UPDATE(TIM2); LL_TIM_EnableDMAReq_UPDATE(TIM2); @@ -925,7 +922,7 @@ bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* // Start counter LL_TIM_GenerateEvent_UPDATE(TIM2); #ifdef FURI_HAL_SUBGHZ_TX_GPIO - hal_gpio_write(&FURI_HAL_SUBGHZ_TX_GPIO, true); + furi_hal_gpio_write(&FURI_HAL_SUBGHZ_TX_GPIO, true); #endif furi_hal_subghz_tx(); @@ -947,20 +944,21 @@ void furi_hal_subghz_stop_async_tx() { // Shutdown radio furi_hal_subghz_idle(); #ifdef FURI_HAL_SUBGHZ_TX_GPIO - hal_gpio_write(&FURI_HAL_SUBGHZ_TX_GPIO, false); + furi_hal_gpio_write(&FURI_HAL_SUBGHZ_TX_GPIO, false); #endif // Deinitialize Timer FURI_CRITICAL_ENTER(); LL_TIM_DeInit(TIM2); - furi_hal_interrupt_set_timer_isr(TIM2, NULL); + furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, NULL, NULL); // Deinitialize DMA LL_DMA_DeInit(DMA1, LL_DMA_CHANNEL_1); - furi_hal_interrupt_set_dma_channel_isr(DMA1, LL_DMA_CHANNEL_1, NULL); + + furi_hal_interrupt_set_isr(FuriHalInterruptIdDma1Ch1, NULL, NULL); // Deinitialize GPIO - hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); FURI_CRITICAL_EXIT(); free(furi_hal_subghz_async_tx.buffer); diff --git a/firmware/targets/f7/furi_hal/furi_hal_task.c b/firmware/targets/f7/furi_hal/furi_hal_task.c deleted file mode 100644 index 577586aa..00000000 --- a/firmware/targets/f7/furi_hal/furi_hal_task.c +++ /dev/null @@ -1,53 +0,0 @@ -#include "furi_hal_task.h" - -//-----------------------------cmsis_os2.c------------------------------- -// helpers to get isr context -// get arch -#ifndef __ARM_ARCH_6M__ -#define __ARM_ARCH_6M__ 0 -#endif -#ifndef __ARM_ARCH_7M__ -#define __ARM_ARCH_7M__ 0 -#endif -#ifndef __ARM_ARCH_7EM__ -#define __ARM_ARCH_7EM__ 0 -#endif -#ifndef __ARM_ARCH_8M_MAIN__ -#define __ARM_ARCH_8M_MAIN__ 0 -#endif -#ifndef __ARM_ARCH_7A__ -#define __ARM_ARCH_7A__ 0 -#endif - -// get masks -#if((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M_MAIN__ == 1U)) -#define IS_IRQ_MASKED() ((__get_PRIMASK() != 0U) || (__get_BASEPRI() != 0U)) -#elif(__ARM_ARCH_6M__ == 1U) -#define IS_IRQ_MASKED() (__get_PRIMASK() != 0U) -#elif(__ARM_ARCH_7A__ == 1U) -/* CPSR mask bits */ -#define CPSR_MASKBIT_I 0x80U - -#define IS_IRQ_MASKED() ((__get_CPSR() & CPSR_MASKBIT_I) != 0U) -#else -#define IS_IRQ_MASKED() (__get_PRIMASK() != 0U) -#endif - -// get is irq mode -#if(__ARM_ARCH_7A__ == 1U) -/* CPSR mode bitmasks */ -#define CPSR_MODE_USER 0x10U -#define CPSR_MODE_SYSTEM 0x1FU - -#define IS_IRQ_MODE() ((__get_mode() != CPSR_MODE_USER) && (__get_mode() != CPSR_MODE_SYSTEM)) -#else -#define IS_IRQ_MODE() (__get_IPSR() != 0U) -#endif - -// added osKernelGetState(), because KernelState is a static var -#define IS_IRQ() (IS_IRQ_MODE() || (IS_IRQ_MASKED() && (osKernelGetState() == osKernelRunning))) -//-------------------------end of cmsis_os2.c---------------------------- - -bool task_is_isr_context(void) { - return IS_IRQ(); -} diff --git a/firmware/targets/f7/furi_hal/furi_hal_task.h b/firmware/targets/f7/furi_hal/furi_hal_task.h deleted file mode 100644 index 8b157233..00000000 --- a/firmware/targets/f7/furi_hal/furi_hal_task.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include "main.h" -#include -#include - -// Task stack size in bytes -#define DEFAULT_STACK_SIZE 4096 - -// Max system tasks count -#define MAX_TASK_COUNT 14 - -bool task_is_isr_context(void); diff --git a/firmware/targets/f7/furi_hal/furi_hal_uart.c b/firmware/targets/f7/furi_hal/furi_hal_uart.c index 2ee0cf85..c4ad2016 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_uart.c +++ b/firmware/targets/f7/furi_hal/furi_hal_uart.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -11,13 +12,13 @@ static void (*irq_cb[2])(uint8_t ev, uint8_t data, void* context); static void* irq_ctx[2]; static void furi_hal_usart_init(uint32_t baud) { - hal_gpio_init_ex( + furi_hal_gpio_init_ex( &gpio_usart_tx, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn7USART1); - hal_gpio_init_ex( + furi_hal_gpio_init_ex( &gpio_usart_rx, GpioModeAltFunctionPushPull, GpioPullUp, @@ -44,17 +45,17 @@ static void furi_hal_usart_init(uint32_t baud) { LL_USART_EnableIT_RXNE_RXFNE(USART1); LL_USART_EnableIT_IDLE(USART1); - HAL_NVIC_SetPriority(USART1_IRQn, 5, 0); + NVIC_SetPriority(USART1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); } static void furi_hal_lpuart_init(uint32_t baud) { - hal_gpio_init_ex( + furi_hal_gpio_init_ex( &gpio_ext_pc0, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedVeryHigh, GpioAltFn8LPUART1); - hal_gpio_init_ex( + furi_hal_gpio_init_ex( &gpio_ext_pc1, GpioModeAltFunctionPushPull, GpioPullUp, @@ -81,7 +82,7 @@ static void furi_hal_lpuart_init(uint32_t baud) { LL_LPUART_EnableIT_RXNE_RXFNE(LPUART1); LL_LPUART_EnableIT_IDLE(LPUART1); - HAL_NVIC_SetPriority(LPUART1_IRQn, 5, 0); + NVIC_SetPriority(LPUART1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); } void furi_hal_uart_init(FuriHalUartId ch, uint32_t baud) { @@ -126,12 +127,12 @@ void furi_hal_uart_deinit(FuriHalUartId ch) { furi_hal_uart_set_irq_cb(ch, NULL, NULL); if(ch == FuriHalUartIdUSART1) { LL_USART_Disable(USART1); - hal_gpio_init(&gpio_usart_tx, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - hal_gpio_init(&gpio_usart_rx, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_usart_tx, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_usart_rx, GpioModeAnalog, GpioPullNo, GpioSpeedLow); } else if(ch == FuriHalUartIdLPUART1) { LL_LPUART_Disable(LPUART1); - hal_gpio_init(&gpio_ext_pc0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - hal_gpio_init(&gpio_ext_pc1, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_ext_pc0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_ext_pc1, GpioModeAnalog, GpioPullNo, GpioSpeedLow); } } diff --git a/firmware/targets/f7/furi_hal/furi_hal_usb.c b/firmware/targets/f7/furi_hal/furi_hal_usb.c index 00425c75..c2bfb969 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_usb.c +++ b/firmware/targets/f7/furi_hal/furi_hal_usb.c @@ -3,6 +3,7 @@ #include "furi_hal_usb.h" #include "furi_hal_vcp.h" #include +#include #include #include "usb.h" @@ -75,7 +76,7 @@ void furi_hal_usb_init(void) { usb.enabled = false; usb.if_cur = NULL; - HAL_NVIC_SetPriority(USB_LP_IRQn, 5, 0); + NVIC_SetPriority(USB_LP_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); NVIC_EnableIRQ(USB_LP_IRQn); usb.thread = furi_thread_alloc(); diff --git a/firmware/targets/f7/furi_hal/furi_hal_vibro.c b/firmware/targets/f7/furi_hal/furi_hal_vibro.c index d9e9ec58..4315ea63 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_vibro.c +++ b/firmware/targets/f7/furi_hal/furi_hal_vibro.c @@ -4,11 +4,11 @@ #define TAG "FuriHalVibro" void furi_hal_vibro_init() { - hal_gpio_init(&vibro_gpio, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); - hal_gpio_write(&vibro_gpio, false); + furi_hal_gpio_init(&vibro_gpio, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_write(&vibro_gpio, false); FURI_LOG_I(TAG, "Init OK"); } void furi_hal_vibro_on(bool value) { - hal_gpio_write(&vibro_gpio, value); + furi_hal_gpio_write(&vibro_gpio, value); } diff --git a/firmware/targets/f7/target.mk b/firmware/targets/f7/target.mk index 3fd9508e..6f010890 100644 --- a/firmware/targets/f7/target.mk +++ b/firmware/targets/f7/target.mk @@ -41,27 +41,13 @@ ASM_SOURCES += $(MXPROJECT_DIR)/startup_stm32wb55xx_cm4.s CUBE_DIR = ../lib/STM32CubeWB CFLAGS += \ -DUSE_FULL_LL_DRIVER \ - -DUSE_HAL_DRIVER \ -DHAVE_FREERTOS CFLAGS += \ -I$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Inc \ - -I$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Inc/Legacy \ -I$(CUBE_DIR)/Drivers/CMSIS/Device/ST \ -I$(CUBE_DIR)/Drivers/CMSIS/Device/ST/STM32WBxx/Include \ -I$(CUBE_DIR)/Drivers/CMSIS/Include C_SOURCES += \ - $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal.c \ - $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_cortex.c \ - $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_cryp.c \ - $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_exti.c \ - $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_gpio.c \ - $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_hsem.c \ - $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_ipcc.c \ - $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pcd.c \ - $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pcd_ex.c \ - $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pwr.c \ - $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pwr_ex.c \ - $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_rcc.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_adc.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_comp.c \ $(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_ll_dma.c \ diff --git a/firmware/targets/furi_hal_include/furi_hal.h b/firmware/targets/furi_hal_include/furi_hal.h index 28f0caf7..59e9e89b 100644 --- a/firmware/targets/furi_hal_include/furi_hal.h +++ b/firmware/targets/furi_hal_include/furi_hal.h @@ -22,7 +22,6 @@ template struct STOP_EXTERNING_ME {}; #include "furi_hal_gpio.h" #include "furi_hal_light.h" #include "furi_hal_delay.h" -#include "furi_hal_task.h" #include "furi_hal_power.h" #include "furi_hal_vcp.h" #include "furi_hal_interrupt.h" diff --git a/firmware/targets/furi_hal_include/furi_hal_delay.h b/firmware/targets/furi_hal_include/furi_hal_delay.h index 733097ce..d0e216f8 100644 --- a/firmware/targets/furi_hal_include/furi_hal_delay.h +++ b/firmware/targets/furi_hal_include/furi_hal_delay.h @@ -5,36 +5,43 @@ #pragma once -#include "main.h" +#include #ifdef __cplusplus extern "C" { #endif +extern uint32_t instructions_per_us; + /** Init DWT */ void furi_hal_delay_init(void); +/** Increase tick counter. + * Should be called from SysTick ISR + */ +void furi_hal_tick(void); + +/** Get current tick counter + * + * System uptime, may overflow. + * + * @return Current ticks in milliseconds + */ +uint32_t furi_hal_get_tick(void); + /** Delay in milliseconds * @warning Cannot be used from ISR * * @param[in] milliseconds milliseconds to wait */ -void delay(float milliseconds); +void furi_hal_delay_ms(float milliseconds); /** Delay in microseconds * * @param[in] microseconds microseconds to wait */ -void delay_us(float microseconds); - -/** Get current millisecond - * - * System uptime, pProvided by HAL, may overflow. - * - * @return Current milliseconds - */ -uint32_t millis(void); +void furi_hal_delay_us(float microseconds); #ifdef __cplusplus } diff --git a/firmware/targets/furi_hal_include/furi_hal_ibutton.h b/firmware/targets/furi_hal_include/furi_hal_ibutton.h index 025fa867..84ef0cd6 100644 --- a/firmware/targets/furi_hal_include/furi_hal_ibutton.h +++ b/firmware/targets/furi_hal_include/furi_hal_ibutton.h @@ -7,6 +7,7 @@ #include #include +#include "furi_hal_gpio.h" #ifdef __cplusplus extern "C" { @@ -26,14 +27,60 @@ void furi_hal_ibutton_emulate_set_next(uint32_t period); void furi_hal_ibutton_emulate_stop(); -void furi_hal_ibutton_start(); +/** + * 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 diff --git a/firmware/targets/furi_hal_include/furi_hal_rfid.h b/firmware/targets/furi_hal_include/furi_hal_rfid.h index 67245a7e..d26ba53f 100644 --- a/firmware/targets/furi_hal_include/furi_hal_rfid.h +++ b/firmware/targets/furi_hal_include/furi_hal_rfid.h @@ -7,7 +7,6 @@ #include #include -#include #ifdef __cplusplus extern "C" { diff --git a/firmware/targets/furi_hal_include/furi_hal_rtc.h b/firmware/targets/furi_hal_include/furi_hal_rtc.h index ee8eb1bb..e06978e1 100644 --- a/firmware/targets/furi_hal_include/furi_hal_rtc.h +++ b/firmware/targets/furi_hal_include/furi_hal_rtc.h @@ -7,7 +7,6 @@ #include #include -#include #ifdef __cplusplus extern "C" { diff --git a/lib/ST25RFAL002/platform.c b/lib/ST25RFAL002/platform.c index a4759f2a..2c624f6e 100644 --- a/lib/ST25RFAL002/platform.c +++ b/lib/ST25RFAL002/platform.c @@ -1,6 +1,5 @@ #include "platform.h" #include -#include #include #include @@ -30,25 +29,25 @@ void platformIrqThread() { } void platformEnableIrqCallback() { - hal_gpio_init(&pin, GpioModeInterruptRise, GpioPullDown, GpioSpeedLow); - hal_gpio_enable_int_callback(&pin); + furi_hal_gpio_init(&pin, GpioModeInterruptRise, GpioPullDown, GpioSpeedLow); + furi_hal_gpio_enable_int_callback(&pin); } void platformDisableIrqCallback() { - hal_gpio_init(&pin, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow); - hal_gpio_disable_int_callback(&pin); + furi_hal_gpio_init(&pin, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_disable_int_callback(&pin); } void platformSetIrqCallback(PlatformIrqCallback callback) { platform_irq_callback = callback; platform_irq_thread_id = osThreadNew(platformIrqThread, NULL, &platform_irq_thread_attr); - hal_gpio_add_int_callback(&pin, nfc_isr, NULL); + furi_hal_gpio_add_int_callback(&pin, nfc_isr, NULL); // Disable interrupt callback as the pin is shared between 2 apps // It is enabled in rfalLowPowerModeStop() - hal_gpio_disable_int_callback(&pin); + furi_hal_gpio_disable_int_callback(&pin); } -HAL_StatusTypeDef platformSpiTxRx(const uint8_t* txBuf, uint8_t* rxBuf, uint16_t len) { +bool platformSpiTxRx(const uint8_t* txBuf, uint8_t* rxBuf, uint16_t len) { bool ret = false; if(txBuf && rxBuf) { ret = @@ -59,11 +58,7 @@ HAL_StatusTypeDef platformSpiTxRx(const uint8_t* txBuf, uint8_t* rxBuf, uint16_t ret = furi_hal_spi_bus_rx(&furi_hal_spi_bus_handle_nfc, (uint8_t*)rxBuf, len, 1000); } - if(!ret) { - return HAL_ERROR; - } else { - return HAL_OK; - } + return ret; } void platformProtectST25RComm() { diff --git a/lib/ST25RFAL002/platform.h b/lib/ST25RFAL002/platform.h index b975fae2..99f97ace 100644 --- a/lib/ST25RFAL002/platform.h +++ b/lib/ST25RFAL002/platform.h @@ -5,10 +5,8 @@ #include #include #include -#include #include "timer.h" #include "math.h" -#include "main.h" #include #include #include @@ -18,7 +16,7 @@ void platformSetIrqCallback(PlatformIrqCallback cb); void platformEnableIrqCallback(); void platformDisableIrqCallback(); -HAL_StatusTypeDef platformSpiTxRx(const uint8_t* txBuf, uint8_t* rxBuf, uint16_t len); +bool platformSpiTxRx(const uint8_t* txBuf, uint8_t* rxBuf, uint16_t len); void platformProtectST25RComm(); void platformUnprotectST25RComm(); @@ -88,15 +86,15 @@ void platformUnprotectST25RComm(); platformUnprotectST25RComm() /*!< Unprotect the IRQ status var - IRQ enable on a single thread environment (MCU) ; Mutex unlock on a multi thread environment */ #define platformGpioSet(port, pin) \ - HAL_GPIO_WritePin(port, pin, GPIO_PIN_SET) /*!< Turns the given GPIO High */ + furi_hal_gpio_write_port_pin( \ + port, pin, true) /*!< Turns the given GPIO High */ #define platformGpioClear(port, pin) \ - HAL_GPIO_WritePin( \ - port, pin, GPIO_PIN_RESET) /*!< Turns the given GPIO Low */ -#define platformGpioToogle(port, pin) \ - HAL_GPIO_TogglePin(port, pin) /*!< Toogles the given GPIO */ -#define platformGpioIsHigh(port, pin) \ - (HAL_GPIO_ReadPin(port, pin) == \ - GPIO_PIN_SET) /*!< Checks if the given LED is High */ + furi_hal_gpio_write_port_pin( \ + port, pin, false) /*!< Turns the given GPIO Low */ + +#define platformGpioIsHigh(port, pin) \ + (furi_hal_gpio_read_port_pin(port, pin) == \ + true) /*!< Checks if the given LED is High */ #define platformGpioIsLow(port, pin) \ (!platformGpioIsHigh(port, pin)) /*!< Checks if the given LED is Low */ diff --git a/lib/ST25RFAL002/timer.c b/lib/ST25RFAL002/timer.c index 2f4bcefd..b7fe1c28 100644 --- a/lib/ST25RFAL002/timer.c +++ b/lib/ST25RFAL002/timer.c @@ -41,6 +41,7 @@ ****************************************************************************** */ #include "timer.h" +#include /* ****************************************************************************** @@ -64,7 +65,7 @@ static uint32_t timerStopwatchTick; /*******************************************************************************/ uint32_t timerCalculateTimer(uint16_t time) { - return (HAL_GetTick() + time); + return (furi_hal_get_tick() + time); } /*******************************************************************************/ @@ -72,7 +73,7 @@ bool timerIsExpired(uint32_t timer) { uint32_t uDiff; int32_t sDiff; - uDiff = (timer - HAL_GetTick()); /* Calculate the diff between the timers */ + uDiff = (timer - furi_hal_get_tick()); /* Calculate the diff between the timers */ sDiff = uDiff; /* Convert the diff to a signed var */ /* Check if the given timer has expired already */ @@ -95,10 +96,10 @@ void timerDelay(uint16_t tOut) { /*******************************************************************************/ void timerStopwatchStart(void) { - timerStopwatchTick = HAL_GetTick(); + timerStopwatchTick = furi_hal_get_tick(); } /*******************************************************************************/ uint32_t timerStopwatchMeasure(void) { - return (uint32_t)(HAL_GetTick() - timerStopwatchTick); + return (uint32_t)(furi_hal_get_tick() - timerStopwatchTick); } diff --git a/lib/drivers/bq27220.c b/lib/drivers/bq27220.c index a0401af7..bf654b5d 100644 --- a/lib/drivers/bq27220.c +++ b/lib/drivers/bq27220.c @@ -42,7 +42,7 @@ bool bq27220_set_parameter_u16(FuriHalI2cBusHandle* handle, uint16_t address, ui ret = furi_hal_i2c_write_mem( handle, BQ27220_ADDRESS, CommandSelectSubclass, buffer, 4, BQ27220_I2C_TIMEOUT); - delay_us(10000); + furi_hal_delay_us(10000); uint8_t checksum = bq27220_get_checksum(buffer, 4); buffer[0] = checksum; @@ -50,7 +50,7 @@ bool bq27220_set_parameter_u16(FuriHalI2cBusHandle* handle, uint16_t address, ui ret = furi_hal_i2c_write_mem( handle, BQ27220_ADDRESS, CommandMACDataSum, buffer, 2, BQ27220_I2C_TIMEOUT); - delay_us(10000); + furi_hal_delay_us(10000); return ret; } @@ -96,7 +96,7 @@ bool bq27220_init(FuriHalI2cBusHandle* handle, const ParamCEDV* cedv) { bq27220_set_parameter_u16(handle, AddressEDV2, cedv->EDV2); bq27220_control(handle, Control_EXIT_CFG_UPDATE_REINIT); - delay_us(10000); + furi_hal_delay_us(10000); design_cap = bq27220_get_design_capacity(handle); if(cedv->design_cap == design_cap) { FURI_LOG_I(TAG, "Battery profile update success"); diff --git a/lib/drivers/cc1101.c b/lib/drivers/cc1101.c index 0115002b..a0c9d44a 100644 --- a/lib/drivers/cc1101.c +++ b/lib/drivers/cc1101.c @@ -8,7 +8,7 @@ CC1101Status cc1101_strobe(FuriHalSpiBusHandle* handle, uint8_t strobe) { uint8_t tx[1] = {strobe}; CC1101Status rx[1] = {0}; - while(hal_gpio_read(handle->miso)) + while(furi_hal_gpio_read(handle->miso)) ; furi_hal_spi_bus_trx(handle, tx, (uint8_t*)rx, 1, CC1101_TIMEOUT); @@ -20,7 +20,7 @@ CC1101Status cc1101_write_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t uint8_t tx[2] = {reg, data}; CC1101Status rx[2] = {0}; - while(hal_gpio_read(handle->miso)) + while(furi_hal_gpio_read(handle->miso)) ; furi_hal_spi_bus_trx(handle, tx, (uint8_t*)rx, 2, CC1101_TIMEOUT); @@ -33,7 +33,7 @@ CC1101Status cc1101_read_reg(FuriHalSpiBusHandle* handle, uint8_t reg, uint8_t* uint8_t tx[2] = {reg | CC1101_READ, 0}; CC1101Status rx[2] = {0}; - while(hal_gpio_read(handle->miso)) + while(furi_hal_gpio_read(handle->miso)) ; furi_hal_spi_bus_trx(handle, tx, (uint8_t*)rx, 2, CC1101_TIMEOUT); @@ -128,7 +128,7 @@ void cc1101_set_pa_table(FuriHalSpiBusHandle* handle, const uint8_t value[8]) { memcpy(&tx[1], &value[0], 8); - while(hal_gpio_read(handle->miso)) + while(furi_hal_gpio_read(handle->miso)) ; furi_hal_spi_bus_trx(handle, tx, (uint8_t*)rx, sizeof(rx), CC1101_TIMEOUT); @@ -143,7 +143,7 @@ uint8_t cc1101_write_fifo(FuriHalSpiBusHandle* handle, const uint8_t* data, uint // Start transaction // Wait IC to become ready - while(hal_gpio_read(handle->miso)) + while(furi_hal_gpio_read(handle->miso)) ; // Tell IC what we want furi_hal_spi_bus_trx(handle, buff_tx, (uint8_t*)buff_rx, size + 1, CC1101_TIMEOUT); @@ -158,7 +158,7 @@ uint8_t cc1101_read_fifo(FuriHalSpiBusHandle* handle, uint8_t* data, uint8_t* si // Start transaction // Wait IC to become ready - while(hal_gpio_read(handle->miso)) + while(furi_hal_gpio_read(handle->miso)) ; // First byte - packet length diff --git a/lib/drivers/lp5562.c b/lib/drivers/lp5562.c index 82554365..34b67ff6 100644 --- a/lib/drivers/lp5562.c +++ b/lib/drivers/lp5562.c @@ -26,7 +26,7 @@ void lp5562_enable(FuriHalI2cBusHandle* handle) { Reg00_Enable reg = {.CHIP_EN = true, .LOG_EN = true}; furi_hal_i2c_write_reg_8(handle, LP5562_ADDRESS, 0x00, *(uint8_t*)®, LP5562_I2C_TIMEOUT); //>488μs delay is required after writing to 0x00 register, otherwise program engine will not work - delay_us(500); + furi_hal_delay_us(500); } void lp5562_set_channel_current(FuriHalI2cBusHandle* handle, LP5562Channel channel, uint8_t value) { @@ -121,7 +121,7 @@ void lp5562_execute_program( reg_val &= ~(0x3 << bit_offset); reg_val |= (0x01 << bit_offset); // load furi_hal_i2c_write_reg_8(handle, LP5562_ADDRESS, 0x01, reg_val, LP5562_I2C_TIMEOUT); - delay_us(100); + furi_hal_delay_us(100); // Program load for(uint8_t i = 0; i < 16; i++) { diff --git a/lib/infrared/worker/infrared_worker.c b/lib/infrared/worker/infrared_worker.c index 86a88367..4439a713 100644 --- a/lib/infrared/worker/infrared_worker.c +++ b/lib/infrared/worker/infrared_worker.c @@ -51,7 +51,6 @@ struct InfraredWorkerSignal { struct InfraredWorker { FuriThread* thread; StreamBufferHandle_t stream; - osEventFlagsId_t events; InfraredWorkerSignal signal; InfraredWorkerState state; @@ -93,7 +92,8 @@ static void infrared_worker_furi_hal_message_sent_isr_callback(void* context); static void infrared_worker_rx_timeout_callback(void* context) { InfraredWorker* instance = context; - uint32_t flags_set = osEventFlagsSet(instance->events, INFRARED_WORKER_RX_TIMEOUT_RECEIVED); + uint32_t flags_set = osThreadFlagsSet( + furi_thread_get_thread_id(instance->thread), INFRARED_WORKER_RX_TIMEOUT_RECEIVED); furi_check(flags_set & INFRARED_WORKER_RX_TIMEOUT_RECEIVED); } @@ -110,7 +110,7 @@ static void infrared_worker_rx_callback(void* context, bool level, uint32_t dura INFRARED_WORKER_OVERRUN; portYIELD_FROM_ISR(xHigherPriorityTaskWoken); - uint32_t flags_set = osEventFlagsSet(instance->events, events); + uint32_t flags_set = osThreadFlagsSet(furi_thread_get_thread_id(instance->thread), events); furi_check(flags_set & events); } @@ -152,7 +152,8 @@ static void instance->signal.timings[instance->signal.timings_cnt] = duration; ++instance->signal.timings_cnt; } else { - uint32_t flags_set = osEventFlagsSet(instance->events, INFRARED_WORKER_OVERRUN); + uint32_t flags_set = osThreadFlagsSet( + furi_thread_get_thread_id(instance->thread), INFRARED_WORKER_OVERRUN); furi_check(flags_set & INFRARED_WORKER_OVERRUN); instance->rx.overrun = true; } @@ -166,8 +167,7 @@ static int32_t infrared_worker_rx_thread(void* thread_context) { TickType_t last_blink_time = 0; while(1) { - events = - osEventFlagsWait(instance->events, INFRARED_WORKER_ALL_RX_EVENTS, 0, osWaitForever); + events = osThreadFlagsWait(INFRARED_WORKER_ALL_RX_EVENTS, 0, osWaitForever); furi_check(events & INFRARED_WORKER_ALL_RX_EVENTS); /* at least one caught */ if(events & INFRARED_WORKER_RX_RECEIVED) { @@ -238,7 +238,6 @@ InfraredWorker* infrared_worker_alloc() { instance->blink_enable = false; instance->notification = furi_record_open("notification"); instance->state = InfraredWorkerStateIdle; - instance->events = osEventFlagsNew(NULL); return instance; } @@ -252,7 +251,6 @@ void infrared_worker_free(InfraredWorker* instance) { infrared_free_encoder(instance->infrared_encoder); vStreamBufferDelete(instance->stream); furi_thread_free(instance->thread); - osEventFlagsDelete(instance->events); free(instance); } @@ -263,7 +261,6 @@ void infrared_worker_rx_start(InfraredWorker* instance) { xStreamBufferSetTriggerLevel(instance->stream, sizeof(LevelDuration)); - osEventFlagsClear(instance->events, INFRARED_WORKER_ALL_EVENTS); furi_thread_set_callback(instance->thread, infrared_worker_rx_thread); furi_thread_start(instance->thread); @@ -285,7 +282,7 @@ void infrared_worker_rx_stop(InfraredWorker* instance) { furi_hal_infrared_async_rx_set_capture_isr_callback(NULL, NULL); furi_hal_infrared_async_rx_stop(); - osEventFlagsSet(instance->events, INFRARED_WORKER_EXIT); + osThreadFlagsSet(furi_thread_get_thread_id(instance->thread), INFRARED_WORKER_EXIT); furi_thread_join(instance->thread); BaseType_t xReturn = xStreamBufferReset(instance->stream); @@ -330,7 +327,6 @@ void infrared_worker_tx_start(InfraredWorker* instance) { // size have to be greater than api hal infrared async tx buffer size xStreamBufferSetTriggerLevel(instance->stream, sizeof(InfraredWorkerTiming)); - osEventFlagsClear(instance->events, INFRARED_WORKER_ALL_EVENTS); furi_thread_set_callback(instance->thread, infrared_worker_tx_thread); instance->tx.steady_signal_sent = false; @@ -346,7 +342,8 @@ void infrared_worker_tx_start(InfraredWorker* instance) { static void infrared_worker_furi_hal_message_sent_isr_callback(void* context) { InfraredWorker* instance = context; - uint32_t flags_set = osEventFlagsSet(instance->events, INFRARED_WORKER_TX_MESSAGE_SENT); + uint32_t flags_set = osThreadFlagsSet( + furi_thread_get_thread_id(instance->thread), INFRARED_WORKER_TX_MESSAGE_SENT); furi_check(flags_set & INFRARED_WORKER_TX_MESSAGE_SENT); } @@ -372,7 +369,8 @@ static FuriHalInfraredTxGetDataState state = FuriHalInfraredTxGetDataStateDone; } - uint32_t flags_set = osEventFlagsSet(instance->events, INFRARED_WORKER_TX_FILL_BUFFER); + uint32_t flags_set = osThreadFlagsSet( + furi_thread_get_thread_id(instance->thread), INFRARED_WORKER_TX_FILL_BUFFER); furi_check(flags_set & INFRARED_WORKER_TX_FILL_BUFFER); return state; @@ -500,7 +498,7 @@ static int32_t infrared_worker_tx_thread(void* thread_context) { furi_hal_infrared_async_tx_wait_termination(); instance->state = InfraredWorkerStateStartTx; - events = osEventFlagsGet(instance->events); + events = osThreadFlagsGet(); if(events & INFRARED_WORKER_EXIT) { exit = true; break; @@ -508,8 +506,7 @@ static int32_t infrared_worker_tx_thread(void* thread_context) { break; case InfraredWorkerStateRunTx: - events = osEventFlagsWait( - instance->events, INFRARED_WORKER_ALL_TX_EVENTS, 0, osWaitForever); + events = osThreadFlagsWait(INFRARED_WORKER_ALL_TX_EVENTS, 0, osWaitForever); furi_check(events & INFRARED_WORKER_ALL_TX_EVENTS); /* at least one caught */ if(events & INFRARED_WORKER_EXIT) { @@ -561,7 +558,7 @@ void infrared_worker_tx_stop(InfraredWorker* instance) { furi_assert(instance); furi_assert(instance->state != InfraredWorkerStateRunRx); - osEventFlagsSet(instance->events, INFRARED_WORKER_EXIT); + osThreadFlagsSet(furi_thread_get_thread_id(instance->thread), INFRARED_WORKER_EXIT); furi_thread_join(instance->thread); furi_hal_infrared_async_tx_set_data_isr_callback(NULL, NULL); furi_hal_infrared_async_tx_set_signal_sent_isr_callback(NULL, NULL); diff --git a/lib/lib.mk b/lib/lib.mk index 5216b0ad..7d221331 100644 --- a/lib/lib.mk +++ b/lib/lib.mk @@ -65,16 +65,6 @@ CFLAGS += -I$(LIB_DIR)/app_scene_template CFLAGS += -I$(LIB_DIR)/fnv1a-hash C_SOURCES += $(LIB_DIR)/fnv1a-hash/fnv1a-hash.c -# onewire library -ONEWIRE_DIR = $(LIB_DIR)/onewire -CFLAGS += -I$(ONEWIRE_DIR) -CPP_SOURCES += $(wildcard $(ONEWIRE_DIR)/*.cpp) - -# cyfral library -CYFRAL_DIR = $(LIB_DIR)/cyfral -CFLAGS += -I$(CYFRAL_DIR) -CPP_SOURCES += $(wildcard $(CYFRAL_DIR)/*.cpp) - # common apps api CFLAGS += -I$(LIB_DIR)/common-api @@ -128,3 +118,8 @@ C_SOURCES += $(wildcard $(LIB_DIR)/flipper_format/*.c) # Micro-ECC CFLAGS += -I$(LIB_DIR)/micro-ecc C_SOURCES += $(wildcard $(LIB_DIR)/micro-ecc/*.c) + +# iButton and OneWire +C_SOURCES += $(wildcard $(LIB_DIR)/one_wire/*.c) +C_SOURCES += $(wildcard $(LIB_DIR)/one_wire/*/*.c) +C_SOURCES += $(wildcard $(LIB_DIR)/one_wire/*/*/*.c) diff --git a/lib/one_wire/ibutton/encoder/encoder_cyfral.c b/lib/one_wire/ibutton/encoder/encoder_cyfral.c new file mode 100644 index 00000000..717bf898 --- /dev/null +++ b/lib/one_wire/ibutton/encoder/encoder_cyfral.c @@ -0,0 +1,126 @@ +#include "encoder_cyfral.h" +#include + +#define CYFRAL_DATA_SIZE sizeof(uint16_t) +#define CYFRAL_PERIOD (125 * instructions_per_us) +#define CYFRAL_0_LOW (CYFRAL_PERIOD * 0.66f) +#define CYFRAL_0_HI (CYFRAL_PERIOD * 0.33f) +#define CYFRAL_1_LOW (CYFRAL_PERIOD * 0.33f) +#define CYFRAL_1_HI (CYFRAL_PERIOD * 0.66f) + +#define CYFRAL_SET_DATA(level, len) \ + *polarity = level; \ + *length = len; + +struct EncoderCyfral { + uint32_t data; + uint32_t index; +}; + +EncoderCyfral* encoder_cyfral_alloc() { + EncoderCyfral* cyfral = malloc(sizeof(EncoderCyfral)); + encoder_cyfral_reset(cyfral); + return cyfral; +} + +void encoder_cyfral_free(EncoderCyfral* cyfral) { + free(cyfral); +} + +void encoder_cyfral_reset(EncoderCyfral* cyfral) { + cyfral->data = 0; + cyfral->index = 0; +} + +uint32_t cyfral_encoder_encode(const uint16_t data) { + uint32_t value = 0; + for(int8_t i = 0; i <= 7; i++) { + switch((data >> (i * 2)) & 0b00000011) { + case 0b11: + value = value << 4; + value += 0b00000111; + break; + case 0b10: + value = value << 4; + value += 0b00001011; + break; + case 0b01: + value = value << 4; + value += 0b00001101; + break; + case 0b00: + value = value << 4; + value += 0b00001110; + break; + default: + break; + } + } + + return value; +} + +void encoder_cyfral_set_data(EncoderCyfral* cyfral, const uint8_t* data, size_t data_size) { + furi_assert(cyfral); + furi_check(data_size >= CYFRAL_DATA_SIZE); + uint16_t intermediate; + memcpy(&intermediate, data, CYFRAL_DATA_SIZE); + cyfral->data = cyfral_encoder_encode(intermediate); +} + +void encoder_cyfral_get_pulse(EncoderCyfral* cyfral, bool* polarity, uint32_t* length) { + if(cyfral->index < 8) { + // start word (0b0001) + switch(cyfral->index) { + case 0: + CYFRAL_SET_DATA(false, CYFRAL_0_LOW); + break; + case 1: + CYFRAL_SET_DATA(true, CYFRAL_0_HI); + break; + case 2: + CYFRAL_SET_DATA(false, CYFRAL_0_LOW); + break; + case 3: + CYFRAL_SET_DATA(true, CYFRAL_0_HI); + break; + case 4: + CYFRAL_SET_DATA(false, CYFRAL_0_LOW); + break; + case 5: + CYFRAL_SET_DATA(true, CYFRAL_0_HI); + break; + case 6: + CYFRAL_SET_DATA(false, CYFRAL_1_LOW); + break; + case 7: + CYFRAL_SET_DATA(true, CYFRAL_1_HI); + break; + } + } else { + // data + uint8_t data_start_index = cyfral->index - 8; + bool clock_polarity = (data_start_index) % 2; + uint8_t bit_index = (data_start_index) / 2; + bool bit_value = ((cyfral->data >> bit_index) & 1); + + if(!clock_polarity) { + if(bit_value) { + CYFRAL_SET_DATA(false, CYFRAL_1_LOW); + } else { + CYFRAL_SET_DATA(false, CYFRAL_0_LOW); + } + } else { + if(bit_value) { + CYFRAL_SET_DATA(true, CYFRAL_1_HI); + } else { + CYFRAL_SET_DATA(true, CYFRAL_0_HI); + } + } + } + + cyfral->index++; + if(cyfral->index >= (9 * 4 * 2)) { + cyfral->index = 0; + } +} diff --git a/lib/one_wire/ibutton/encoder/encoder_cyfral.h b/lib/one_wire/ibutton/encoder/encoder_cyfral.h new file mode 100644 index 00000000..1b0c3e12 --- /dev/null +++ b/lib/one_wire/ibutton/encoder/encoder_cyfral.h @@ -0,0 +1,54 @@ +/** + * @file encoder_cyfral.h + * + * Cyfral pulse format encoder + */ + +#pragma once +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct EncoderCyfral EncoderCyfral; + +/** + * Allocate Cyfral encoder + * @return EncoderCyfral* + */ +EncoderCyfral* encoder_cyfral_alloc(); + +/** + * Deallocate Cyfral encoder + * @param cyfral + */ +void encoder_cyfral_free(EncoderCyfral* cyfral); + +/** + * Reset Cyfral encoder + * @param cyfral + */ +void encoder_cyfral_reset(EncoderCyfral* cyfral); + +/** + * Set data to be encoded to Cyfral pulse format, 2 bytes + * @param cyfral + * @param data + * @param data_size + */ +void encoder_cyfral_set_data(EncoderCyfral* cyfral, const uint8_t* data, size_t data_size); + +/** + * Pop pulse from Cyfral encoder + * @param cyfral + * @param polarity + * @param length + */ +void encoder_cyfral_get_pulse(EncoderCyfral* cyfral, bool* polarity, uint32_t* length); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/lib/one_wire/ibutton/encoder/encoder_metakom.c b/lib/one_wire/ibutton/encoder/encoder_metakom.c new file mode 100644 index 00000000..ea2a28f0 --- /dev/null +++ b/lib/one_wire/ibutton/encoder/encoder_metakom.c @@ -0,0 +1,93 @@ +#include "encoder_metakom.h" +#include + +#define METAKOM_DATA_SIZE sizeof(uint32_t) +#define METAKOM_PERIOD (125 * instructions_per_us) +#define METAKOM_0_LOW (METAKOM_PERIOD * 0.33f) +#define METAKOM_0_HI (METAKOM_PERIOD * 0.66f) +#define METAKOM_1_LOW (METAKOM_PERIOD * 0.66f) +#define METAKOM_1_HI (METAKOM_PERIOD * 0.33f) + +#define METAKOM_SET_DATA(level, len) \ + *polarity = !level; \ + *length = len; + +struct EncoderMetakom { + uint32_t data; + uint32_t index; +}; + +EncoderMetakom* encoder_metakom_alloc() { + EncoderMetakom* metakom = malloc(sizeof(EncoderMetakom)); + encoder_metakom_reset(metakom); + return metakom; +} + +void encoder_metakom_free(EncoderMetakom* metakom) { + free(metakom); +} + +void encoder_metakom_reset(EncoderMetakom* metakom) { + metakom->data = 0; + metakom->index = 0; +} + +void encoder_metakom_set_data(EncoderMetakom* metakom, const uint8_t* data, size_t data_size) { + furi_assert(metakom); + furi_check(data_size >= METAKOM_DATA_SIZE); + memcpy(&metakom->data, data, METAKOM_DATA_SIZE); +} + +void encoder_metakom_get_pulse(EncoderMetakom* metakom, bool* polarity, uint32_t* length) { + if(metakom->index == 0) { + // sync bit + METAKOM_SET_DATA(true, METAKOM_PERIOD); + } else if(metakom->index >= 1 && metakom->index <= 6) { + // start word (0b010) + switch(metakom->index) { + case 1: + METAKOM_SET_DATA(false, METAKOM_0_LOW); + break; + case 2: + METAKOM_SET_DATA(true, METAKOM_0_HI); + break; + case 3: + METAKOM_SET_DATA(false, METAKOM_1_LOW); + break; + case 4: + METAKOM_SET_DATA(true, METAKOM_1_HI); + break; + case 5: + METAKOM_SET_DATA(false, METAKOM_0_LOW); + break; + case 6: + METAKOM_SET_DATA(true, METAKOM_0_HI); + break; + } + } else { + // data + uint8_t data_start_index = metakom->index - 7; + bool clock_polarity = (data_start_index) % 2; + uint8_t bit_index = (data_start_index) / 2; + bool bit_value = (metakom->data >> (32 - 1 - bit_index)) & 1; + + if(!clock_polarity) { + if(bit_value) { + METAKOM_SET_DATA(false, METAKOM_1_LOW); + } else { + METAKOM_SET_DATA(false, METAKOM_0_LOW); + } + } else { + if(bit_value) { + METAKOM_SET_DATA(true, METAKOM_1_HI); + } else { + METAKOM_SET_DATA(true, METAKOM_0_HI); + } + } + } + + metakom->index++; + if(metakom->index >= (1 + 3 * 2 + 32 * 2)) { + metakom->index = 0; + } +} diff --git a/lib/one_wire/ibutton/encoder/encoder_metakom.h b/lib/one_wire/ibutton/encoder/encoder_metakom.h new file mode 100644 index 00000000..2812dc12 --- /dev/null +++ b/lib/one_wire/ibutton/encoder/encoder_metakom.h @@ -0,0 +1,54 @@ +/** + * @file encoder_metakom.h + * + * Metakom pulse format encoder + */ + +#pragma once +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct EncoderMetakom EncoderMetakom; + +/** + * Allocate Metakom encoder + * @return EncoderMetakom* + */ +EncoderMetakom* encoder_metakom_alloc(); + +/** + * Deallocate Metakom encoder + * @param metakom + */ +void encoder_metakom_free(EncoderMetakom* metakom); + +/** + * Reset Metakom encoder + * @param metakom + */ +void encoder_metakom_reset(EncoderMetakom* metakom); + +/** + * Set data to be encoded to Metakom pulse format, 4 bytes + * @param metakom + * @param data + * @param data_size + */ +void encoder_metakom_set_data(EncoderMetakom* metakom, const uint8_t* data, size_t data_size); + +/** + * Pop pulse from Metakom encoder + * @param cyfral + * @param polarity + * @param length + */ +void encoder_metakom_get_pulse(EncoderMetakom* metakom, bool* polarity, uint32_t* length); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/lib/one_wire/ibutton/ibutton_key.c b/lib/one_wire/ibutton/ibutton_key.c new file mode 100644 index 00000000..c90d5f4a --- /dev/null +++ b/lib/one_wire/ibutton/ibutton_key.c @@ -0,0 +1,121 @@ +#include +#include +#include "ibutton_key.h" + +struct iButtonKey { + uint8_t data[IBUTTON_KEY_DATA_SIZE]; + char name[IBUTTON_KEY_NAME_SIZE]; + iButtonKeyType type; +}; + +iButtonKey* ibutton_key_alloc() { + iButtonKey* key = malloc(sizeof(iButtonKey)); + memset(key, 0, sizeof(iButtonKey)); + return key; +} + +void ibutton_key_free(iButtonKey* key) { + free(key); +} + +void ibutton_key_set(iButtonKey* to, const iButtonKey* from) { + memcpy(to, from, sizeof(iButtonKey)); +} + +void ibutton_key_set_data(iButtonKey* key, uint8_t* data, uint8_t data_count) { + furi_check(data_count > 0); + furi_check(data_count <= IBUTTON_KEY_DATA_SIZE); + + memset(key->data, 0, IBUTTON_KEY_DATA_SIZE); + memcpy(key->data, data, data_count); +} + +void ibutton_key_clear_data(iButtonKey* key) { + memset(key->data, 0, IBUTTON_KEY_DATA_SIZE); +} + +const uint8_t* ibutton_key_get_data_p(iButtonKey* key) { + return key->data; +} + +uint8_t ibutton_key_get_data_size(iButtonKey* key) { + return ibutton_key_get_size_by_type(key->type); +} + +void ibutton_key_set_name(iButtonKey* key, const char* name) { + strlcpy(key->name, name, IBUTTON_KEY_NAME_SIZE); +} + +const char* ibutton_key_get_name_p(iButtonKey* key) { + return key->name; +} + +void ibutton_key_set_type(iButtonKey* key, iButtonKeyType key_type) { + key->type = key_type; +} + +iButtonKeyType ibutton_key_get_type(iButtonKey* key) { + return key->type; +} + +const char* ibutton_key_get_string_by_type(iButtonKeyType key_type) { + switch(key_type) { + case iButtonKeyCyfral: + return "Cyfral"; + break; + case iButtonKeyMetakom: + return "Metakom"; + break; + case iButtonKeyDS1990: + return "Dallas"; + break; + default: + furi_crash("Invalid iButton type"); + return ""; + break; + } +} + +bool ibutton_key_get_type_by_string(const char* type_string, iButtonKeyType* key_type) { + if(strcmp(type_string, ibutton_key_get_string_by_type(iButtonKeyCyfral)) == 0) { + *key_type = iButtonKeyCyfral; + } else if(strcmp(type_string, ibutton_key_get_string_by_type(iButtonKeyMetakom)) == 0) { + *key_type = iButtonKeyMetakom; + } else if(strcmp(type_string, ibutton_key_get_string_by_type(iButtonKeyDS1990)) == 0) { + *key_type = iButtonKeyDS1990; + } else { + return false; + } + + return true; +} + +uint8_t ibutton_key_get_size_by_type(iButtonKeyType key_type) { + uint8_t size = 0; + + switch(key_type) { + case iButtonKeyCyfral: + size = 2; + break; + case iButtonKeyMetakom: + size = 4; + break; + case iButtonKeyDS1990: + size = 8; + break; + } + + return size; +} + +uint8_t ibutton_key_get_max_size() { + return IBUTTON_KEY_DATA_SIZE; +} + +bool ibutton_key_dallas_crc_is_valid(iButtonKey* key) { + return (maxim_crc8(key->data, 8, MAXIM_CRC8_INIT) == 0); +} + +bool ibutton_key_dallas_is_1990_key(iButtonKey* key) { + return (key->data[0] == 0x01); +} \ No newline at end of file diff --git a/lib/one_wire/ibutton/ibutton_key.h b/lib/one_wire/ibutton/ibutton_key.h new file mode 100644 index 00000000..f8286103 --- /dev/null +++ b/lib/one_wire/ibutton/ibutton_key.h @@ -0,0 +1,145 @@ +/** + * @file ibutton_key.h + * + * iButton key data holder + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#define IBUTTON_KEY_DATA_SIZE 8 +#define IBUTTON_KEY_NAME_SIZE 22 + +typedef enum { + iButtonKeyDS1990, + iButtonKeyCyfral, + iButtonKeyMetakom, +} iButtonKeyType; + +typedef struct iButtonKey iButtonKey; + +/** + * Allocate key + * @return iButtonKey* + */ +iButtonKey* ibutton_key_alloc(); + +/** + * Free key + * @param key + */ +void ibutton_key_free(iButtonKey* key); + +/** + * Copy key + * @param to + * @param from + */ +void ibutton_key_set(iButtonKey* to, const iButtonKey* from); + +/** + * Set key data + * @param key + * @param data + * @param data_count + */ +void ibutton_key_set_data(iButtonKey* key, uint8_t* data, uint8_t data_count); + +/** + * Clear key data + * @param key + */ +void ibutton_key_clear_data(iButtonKey* key); + +/** + * Get pointer to key data + * @param key + * @return const uint8_t* + */ +const uint8_t* ibutton_key_get_data_p(iButtonKey* key); + +/** + * Get key data size + * @param key + * @return uint8_t + */ +uint8_t ibutton_key_get_data_size(iButtonKey* key); + +/** + * Set key name + * @param key + * @param name + */ +void ibutton_key_set_name(iButtonKey* key, const char* name); + +/** + * Get pointer to key name + * @param key + * @return const char* + */ +const char* ibutton_key_get_name_p(iButtonKey* key); + +/** + * Set key type + * @param key + * @param key_type + */ +void ibutton_key_set_type(iButtonKey* key, iButtonKeyType key_type); + +/** + * Get key type + * @param key + * @return iButtonKeyType + */ +iButtonKeyType ibutton_key_get_type(iButtonKey* key); + +/** + * Get type string from key type + * @param key_type + * @return const char* + */ +const char* ibutton_key_get_string_by_type(iButtonKeyType key_type); + +/** + * Get key type from string + * @param type_string + * @param key_type + * @return bool + */ +bool ibutton_key_get_type_by_string(const char* type_string, iButtonKeyType* key_type); + +/** + * Get key data size from type + * @param key_type + * @return uint8_t + */ +uint8_t ibutton_key_get_size_by_type(iButtonKeyType key_type); + +/** + * Get max key size + * @return uint8_t + */ +uint8_t ibutton_key_get_max_size(); + +/** + * Check if CRC for onewire key is valid + * @param key + * @return true + * @return false + */ +bool ibutton_key_dallas_crc_is_valid(iButtonKey* key); + +/** + * Check if onewire key is a DS1990 key + * @param key + * @return true + * @return false + */ +bool ibutton_key_dallas_is_1990_key(iButtonKey* key); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/lib/one_wire/ibutton/ibutton_key_command.h b/lib/one_wire/ibutton/ibutton_key_command.h new file mode 100644 index 00000000..3978ea51 --- /dev/null +++ b/lib/one_wire/ibutton/ibutton_key_command.h @@ -0,0 +1,28 @@ +/** + * @file ibutton_key_command.h + * + * List of misc commands for Dallas and blanks + */ + +#pragma once + +#define RW1990_1_CMD_WRITE_RECORD_FLAG 0xD1 +#define RW1990_1_CMD_READ_RECORD_FLAG 0xB5 +#define RW1990_1_CMD_WRITE_ROM 0xD5 + +#define RW1990_2_CMD_WRITE_RECORD_FLAG 0x1D +#define RW1990_2_CMD_READ_RECORD_FLAG 0x1E +#define RW1990_2_CMD_WRITE_ROM 0xD5 + +#define TM2004_CMD_READ_STATUS 0xAA +#define TM2004_CMD_READ_MEMORY 0xF0 +#define TM2004_CMD_WRITE_ROM 0x3C +#define TM2004_CMD_FINALIZATION 0x35 +#define TM2004_ANSWER_READ_MEMORY 0xF5 + +#define TM01_CMD_WRITE_RECORD_FLAG 0xC1 +#define TM01_CMD_WRITE_ROM 0xC5 +#define TM01_CMD_SWITCH_TO_CYFRAL 0xCA +#define TM01_CMD_SWITCH_TO_METAKOM 0xCB + +#define DS1990_CMD_READ_ROM 0x33 \ No newline at end of file diff --git a/lib/one_wire/ibutton/ibutton_worker.c b/lib/one_wire/ibutton/ibutton_worker.c new file mode 100644 index 00000000..74734e75 --- /dev/null +++ b/lib/one_wire/ibutton/ibutton_worker.c @@ -0,0 +1,197 @@ +#include +#include +#include +#include "ibutton_worker_i.h" + +typedef enum { + iButtonMessageEnd, + iButtonMessageStop, + iButtonMessageRead, + iButtonMessageWrite, + iButtonMessageEmulate, +} iButtonMessageType; + +typedef struct { + iButtonMessageType type; + union { + iButtonKey* key; + } data; +} iButtonMessage; + +static int32_t ibutton_worker_thread(void* thread_context); + +iButtonWorker* ibutton_worker_alloc() { + iButtonWorker* worker = malloc(sizeof(iButtonWorker)); + worker->key_p = NULL; + worker->key_data = malloc(ibutton_key_get_max_size()); + worker->host = onewire_host_alloc(); + worker->slave = onewire_slave_alloc(); + worker->writer = ibutton_writer_alloc(worker->host); + worker->device = onewire_device_alloc(0, 0, 0, 0, 0, 0, 0, 0); + worker->pulse_decoder = pulse_decoder_alloc(); + worker->protocol_cyfral = protocol_cyfral_alloc(); + worker->protocol_metakom = protocol_metakom_alloc(); + worker->messages = osMessageQueueNew(1, sizeof(iButtonMessage), NULL); + worker->mode_index = iButtonWorkerIdle; + worker->last_dwt_value = 0; + worker->read_cb = NULL; + worker->write_cb = NULL; + worker->emulate_cb = NULL; + worker->cb_ctx = NULL; + + worker->encoder_cyfral = encoder_cyfral_alloc(); + worker->encoder_metakom = encoder_metakom_alloc(); + + worker->thread = furi_thread_alloc(); + furi_thread_set_name(worker->thread, "ibutton_worker"); + furi_thread_set_callback(worker->thread, ibutton_worker_thread); + furi_thread_set_context(worker->thread, worker); + furi_thread_set_stack_size(worker->thread, 2048); + + pulse_decoder_add_protocol( + worker->pulse_decoder, + protocol_cyfral_get_protocol(worker->protocol_cyfral), + PulseProtocolCyfral); + pulse_decoder_add_protocol( + worker->pulse_decoder, + protocol_metakom_get_protocol(worker->protocol_metakom), + PulseProtocolMetakom); + + return worker; +} + +void ibutton_worker_read_set_callback( + iButtonWorker* worker, + iButtonWorkerReadCallback callback, + void* context) { + furi_check(worker->mode_index == iButtonWorkerIdle); + worker->read_cb = callback; + worker->cb_ctx = context; +} + +void ibutton_worker_write_set_callback( + iButtonWorker* worker, + iButtonWorkerWriteCallback callback, + void* context) { + furi_check(worker->mode_index == iButtonWorkerIdle); + worker->write_cb = callback; + worker->cb_ctx = context; +} + +void ibutton_worker_emulate_set_callback( + iButtonWorker* worker, + iButtonWorkerEmulateCallback callback, + void* context) { + furi_check(worker->mode_index == iButtonWorkerIdle); + worker->emulate_cb = callback; + worker->cb_ctx = context; +} + +void ibutton_worker_read_start(iButtonWorker* worker, iButtonKey* key) { + iButtonMessage message = {.type = iButtonMessageRead, .data.key = key}; + furi_check(osMessageQueuePut(worker->messages, &message, 0, osWaitForever) == osOK); +} + +void ibutton_worker_write_start(iButtonWorker* worker, iButtonKey* key) { + iButtonMessage message = {.type = iButtonMessageWrite, .data.key = key}; + furi_check(osMessageQueuePut(worker->messages, &message, 0, osWaitForever) == osOK); +} + +void ibutton_worker_emulate_start(iButtonWorker* worker, iButtonKey* key) { + iButtonMessage message = {.type = iButtonMessageEmulate, .data.key = key}; + furi_check(osMessageQueuePut(worker->messages, &message, 0, osWaitForever) == osOK); +} + +void ibutton_worker_stop(iButtonWorker* worker) { + iButtonMessage message = {.type = iButtonMessageStop}; + furi_check(osMessageQueuePut(worker->messages, &message, 0, osWaitForever) == osOK); +} + +void ibutton_worker_free(iButtonWorker* worker) { + pulse_decoder_free(worker->pulse_decoder); + protocol_metakom_free(worker->protocol_metakom); + protocol_cyfral_free(worker->protocol_cyfral); + + ibutton_writer_free(worker->writer); + + onewire_slave_free(worker->slave); + + onewire_host_free(worker->host); + onewire_device_free(worker->device); + + encoder_cyfral_free(worker->encoder_cyfral); + encoder_metakom_free(worker->encoder_metakom); + + osMessageQueueDelete(worker->messages); + + furi_thread_free(worker->thread); + free(worker->key_data); + free(worker); +} + +void ibutton_worker_start_thread(iButtonWorker* worker) { + furi_thread_start(worker->thread); +} + +void ibutton_worker_stop_thread(iButtonWorker* worker) { + iButtonMessage message = {.type = iButtonMessageEnd}; + furi_check(osMessageQueuePut(worker->messages, &message, 0, osWaitForever) == osOK); + furi_thread_join(worker->thread); +} + +void ibutton_worker_switch_mode(iButtonWorker* worker, iButtonWorkerMode mode) { + ibutton_worker_modes[worker->mode_index].stop(worker); + worker->mode_index = mode; + ibutton_worker_modes[worker->mode_index].start(worker); +} + +void ibutton_worker_set_key_p(iButtonWorker* worker, iButtonKey* key) { + worker->key_p = key; +} + +static int32_t ibutton_worker_thread(void* thread_context) { + iButtonWorker* worker = thread_context; + bool running = true; + iButtonMessage message; + osStatus_t status; + + ibutton_worker_modes[worker->mode_index].start(worker); + + while(running) { + status = osMessageQueueGet( + worker->messages, &message, NULL, ibutton_worker_modes[worker->mode_index].quant); + if(status == osOK) { + switch(message.type) { + case iButtonMessageEnd: + ibutton_worker_switch_mode(worker, iButtonWorkerIdle); + ibutton_worker_set_key_p(worker, NULL); + running = false; + break; + case iButtonMessageStop: + ibutton_worker_switch_mode(worker, iButtonWorkerIdle); + ibutton_worker_set_key_p(worker, NULL); + break; + case iButtonMessageRead: + ibutton_worker_set_key_p(worker, message.data.key); + ibutton_worker_switch_mode(worker, iButtonWorkerRead); + break; + case iButtonMessageWrite: + ibutton_worker_set_key_p(worker, message.data.key); + ibutton_worker_switch_mode(worker, iButtonWorkerWrite); + break; + case iButtonMessageEmulate: + ibutton_worker_set_key_p(worker, message.data.key); + ibutton_worker_switch_mode(worker, iButtonWorkerEmulate); + break; + } + } else if(status == osErrorTimeout) { + ibutton_worker_modes[worker->mode_index].tick(worker); + } else { + furi_crash("iButton worker error"); + } + } + + ibutton_worker_modes[worker->mode_index].stop(worker); + + return 0; +} diff --git a/lib/one_wire/ibutton/ibutton_worker.h b/lib/one_wire/ibutton/ibutton_worker.h new file mode 100644 index 00000000..3350e05f --- /dev/null +++ b/lib/one_wire/ibutton/ibutton_worker.h @@ -0,0 +1,113 @@ +/** + * @file ibutton_worker.h + * + * iButton worker + */ + +#pragma once +#include "ibutton_key.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + iButtonWorkerWriteOK, + iButtonWorkerWriteSameKey, + iButtonWorkerWriteNoDetect, + iButtonWorkerWriteCannotWrite, +} iButtonWorkerWriteResult; + +typedef void (*iButtonWorkerReadCallback)(void* context); +typedef void (*iButtonWorkerWriteCallback)(void* context, iButtonWorkerWriteResult result); +typedef void (*iButtonWorkerEmulateCallback)(void* context, bool emulated); + +typedef struct iButtonWorker iButtonWorker; + +/** + * Allocate ibutton worker + * @return iButtonWorker* + */ +iButtonWorker* ibutton_worker_alloc(); + +/** + * Free ibutton worker + * @param worker + */ +void ibutton_worker_free(iButtonWorker* worker); + +/** + * Start ibutton worker thread + * @param worker + */ +void ibutton_worker_start_thread(iButtonWorker* worker); + +/** + * Stop ibutton worker thread + * @param worker + */ +void ibutton_worker_stop_thread(iButtonWorker* worker); + +/** + * Set "read success" callback + * @param worker + * @param callback + * @param context + */ +void ibutton_worker_read_set_callback( + iButtonWorker* worker, + iButtonWorkerReadCallback callback, + void* context); + +/** + * Start read mode + * @param worker + * @param key + */ +void ibutton_worker_read_start(iButtonWorker* worker, iButtonKey* key); + +/** + * Set "write event" callback + * @param worker + * @param callback + * @param context + */ +void ibutton_worker_write_set_callback( + iButtonWorker* worker, + iButtonWorkerWriteCallback callback, + void* context); + +/** + * Start write mode + * @param worker + * @param key + */ +void ibutton_worker_write_start(iButtonWorker* worker, iButtonKey* key); + +/** + * Set "emulate success" callback + * @param worker + * @param callback + * @param context + */ +void ibutton_worker_emulate_set_callback( + iButtonWorker* worker, + iButtonWorkerEmulateCallback callback, + void* context); + +/** + * Start emulate mode + * @param worker + * @param key + */ +void ibutton_worker_emulate_start(iButtonWorker* worker, iButtonKey* key); + +/** + * Stop all modes + * @param worker + */ +void ibutton_worker_stop(iButtonWorker* worker); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/lib/one_wire/ibutton/ibutton_worker_i.h b/lib/one_wire/ibutton/ibutton_worker_i.h new file mode 100644 index 00000000..14e5d39d --- /dev/null +++ b/lib/one_wire/ibutton/ibutton_worker_i.h @@ -0,0 +1,79 @@ +/** + * @file ibutton_worker_i.h + * + * iButton worker, internal definitions + */ + +#pragma once +#include "ibutton_worker.h" +#include "ibutton_writer.h" +#include "../one_wire_host.h" +#include "../one_wire_slave.h" +#include "../one_wire_device.h" +#include "../pulse_protocols/pulse_decoder.h" +#include "pulse_protocols/protocol_cyfral.h" +#include "pulse_protocols/protocol_metakom.h" +#include "encoder/encoder_cyfral.h" +#include "encoder/encoder_metakom.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + PulseProtocolCyfral, + PulseProtocolMetakom, +} PulseProtocols; + +typedef struct { + const uint32_t quant; + const void (*start)(iButtonWorker* worker); + const void (*tick)(iButtonWorker* worker); + const void (*stop)(iButtonWorker* worker); +} iButtonWorkerModeType; + +typedef enum { + iButtonWorkerIdle = 0, + iButtonWorkerRead = 1, + iButtonWorkerWrite = 2, + iButtonWorkerEmulate = 3, +} iButtonWorkerMode; + +typedef enum { + iButtonEmulateModeCyfral, + iButtonEmulateModeMetakom, +} iButtonEmulateMode; + +struct iButtonWorker { + iButtonKey* key_p; + uint8_t* key_data; + OneWireHost* host; + OneWireSlave* slave; + OneWireDevice* device; + iButtonWriter* writer; + iButtonWorkerMode mode_index; + osMessageQueueId_t messages; + FuriThread* thread; + + PulseDecoder* pulse_decoder; + ProtocolCyfral* protocol_cyfral; + ProtocolMetakom* protocol_metakom; + uint32_t last_dwt_value; + + iButtonWorkerReadCallback read_cb; + iButtonWorkerWriteCallback write_cb; + iButtonWorkerEmulateCallback emulate_cb; + void* cb_ctx; + + EncoderCyfral* encoder_cyfral; + EncoderMetakom* encoder_metakom; + iButtonEmulateMode emulate_mode; +}; + +extern const iButtonWorkerModeType ibutton_worker_modes[]; + +void ibutton_worker_switch_mode(iButtonWorker* worker, iButtonWorkerMode mode); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/lib/one_wire/ibutton/ibutton_worker_modes.c b/lib/one_wire/ibutton/ibutton_worker_modes.c new file mode 100644 index 00000000..7ee3a005 --- /dev/null +++ b/lib/one_wire/ibutton/ibutton_worker_modes.c @@ -0,0 +1,330 @@ +#include +#include +#include "ibutton_worker_i.h" +#include "ibutton_key_command.h" + +void ibutton_worker_mode_idle_start(iButtonWorker* worker); +void ibutton_worker_mode_idle_tick(iButtonWorker* worker); +void ibutton_worker_mode_idle_stop(iButtonWorker* worker); + +void ibutton_worker_mode_emulate_start(iButtonWorker* worker); +void ibutton_worker_mode_emulate_tick(iButtonWorker* worker); +void ibutton_worker_mode_emulate_stop(iButtonWorker* worker); + +void ibutton_worker_mode_read_start(iButtonWorker* worker); +void ibutton_worker_mode_read_tick(iButtonWorker* worker); +void ibutton_worker_mode_read_stop(iButtonWorker* worker); + +void ibutton_worker_mode_write_start(iButtonWorker* worker); +void ibutton_worker_mode_write_tick(iButtonWorker* worker); +void ibutton_worker_mode_write_stop(iButtonWorker* worker); + +const iButtonWorkerModeType ibutton_worker_modes[] = { + { + .quant = osWaitForever, + .start = ibutton_worker_mode_idle_start, + .tick = ibutton_worker_mode_idle_tick, + .stop = ibutton_worker_mode_idle_stop, + }, + { + .quant = 100, + .start = ibutton_worker_mode_read_start, + .tick = ibutton_worker_mode_read_tick, + .stop = ibutton_worker_mode_read_stop, + }, + { + .quant = 1000, + .start = ibutton_worker_mode_write_start, + .tick = ibutton_worker_mode_write_tick, + .stop = ibutton_worker_mode_write_stop, + }, + { + .quant = 1000, + .start = ibutton_worker_mode_emulate_start, + .tick = ibutton_worker_mode_emulate_tick, + .stop = ibutton_worker_mode_emulate_stop, + }, +}; + +/*********************** IDLE ***********************/ + +void ibutton_worker_mode_idle_start(iButtonWorker* worker) { +} + +void ibutton_worker_mode_idle_tick(iButtonWorker* worker) { +} + +void ibutton_worker_mode_idle_stop(iButtonWorker* worker) { +} + +/*********************** READ ***********************/ + +void ibutton_worker_comparator_callback(bool level, void* context) { + iButtonWorker* worker = context; + + uint32_t current_dwt_value = DWT->CYCCNT; + + pulse_decoder_process_pulse( + worker->pulse_decoder, level, current_dwt_value - worker->last_dwt_value); + + worker->last_dwt_value = current_dwt_value; +} + +bool ibutton_worker_read_comparator(iButtonWorker* worker) { + bool result = false; + + pulse_decoder_reset(worker->pulse_decoder); + + furi_hal_rfid_pins_reset(); + // pulldown pull pin, we sense the signal through the analog part of the RFID schematic + furi_hal_rfid_pin_pull_pulldown(); + furi_hal_rfid_comp_set_callback(ibutton_worker_comparator_callback, worker); + worker->last_dwt_value = DWT->CYCCNT; + furi_hal_rfid_comp_start(); + + // TODO: rework with thread events, "pulse_decoder_get_decoded_index_with_timeout" + furi_hal_delay_ms(100); + int32_t decoded_index = pulse_decoder_get_decoded_index(worker->pulse_decoder); + if(decoded_index >= 0) { + pulse_decoder_get_data( + worker->pulse_decoder, decoded_index, worker->key_data, ibutton_key_get_max_size()); + } + + switch(decoded_index) { + case PulseProtocolCyfral: + furi_check(worker->key_p != NULL); + ibutton_key_set_type(worker->key_p, iButtonKeyCyfral); + ibutton_key_set_data(worker->key_p, worker->key_data, ibutton_key_get_max_size()); + result = true; + break; + case PulseProtocolMetakom: + furi_check(worker->key_p != NULL); + ibutton_key_set_type(worker->key_p, iButtonKeyMetakom); + ibutton_key_set_data(worker->key_p, worker->key_data, ibutton_key_get_max_size()); + result = true; + break; + break; + default: + break; + } + + furi_hal_rfid_comp_stop(); + furi_hal_rfid_comp_set_callback(NULL, NULL); + furi_hal_rfid_pins_reset(); + + return result; +} + +bool ibutton_worker_read_dallas(iButtonWorker* worker) { + bool result = false; + onewire_host_start(worker->host); + furi_hal_delay_ms(100); + FURI_CRITICAL_ENTER(); + if(onewire_host_search(worker->host, worker->key_data, NORMAL_SEARCH)) { + onewire_host_reset_search(worker->host); + + // key found, verify + if(onewire_host_reset(worker->host)) { + onewire_host_write(worker->host, DS1990_CMD_READ_ROM); + bool key_valid = true; + for(uint8_t i = 0; i < ibutton_key_get_max_size(); i++) { + if(onewire_host_read(worker->host) != worker->key_data[i]) { + key_valid = false; + break; + } + } + + if(key_valid) { + result = true; + + furi_check(worker->key_p != NULL); + ibutton_key_set_type(worker->key_p, iButtonKeyDS1990); + ibutton_key_set_data(worker->key_p, worker->key_data, ibutton_key_get_max_size()); + } + } + } else { + onewire_host_reset_search(worker->host); + } + onewire_host_stop(worker->host); + FURI_CRITICAL_EXIT(); + return result; +} + +void ibutton_worker_mode_read_start(iButtonWorker* worker) { + furi_hal_power_enable_otg(); +} + +void ibutton_worker_mode_read_tick(iButtonWorker* worker) { + bool valid = false; + if(ibutton_worker_read_dallas(worker)) { + valid = true; + } else if(ibutton_worker_read_comparator(worker)) { + valid = true; + } + + if(valid) { + if(worker->read_cb != NULL) { + worker->read_cb(worker->cb_ctx); + } + + ibutton_worker_switch_mode(worker, iButtonWorkerIdle); + } +} + +void ibutton_worker_mode_read_stop(iButtonWorker* worker) { + furi_hal_power_disable_otg(); +} + +/*********************** EMULATE ***********************/ +static void onewire_slave_callback(void* context) { + furi_assert(context); + iButtonWorker* worker = context; + if(worker->emulate_cb != NULL) { + worker->emulate_cb(worker->cb_ctx, true); + } +} + +void ibutton_worker_emulate_dallas_start(iButtonWorker* worker) { + uint8_t* device_id = onewire_device_get_id_p(worker->device); + const uint8_t* key_id = ibutton_key_get_data_p(worker->key_p); + const uint8_t key_size = ibutton_key_get_max_size(); + memcpy(device_id, key_id, key_size); + + onewire_slave_attach(worker->slave, worker->device); + onewire_slave_start(worker->slave); + onewire_slave_set_result_callback(worker->slave, onewire_slave_callback, worker); +} + +void ibutton_worker_emulate_dallas_stop(iButtonWorker* worker) { + onewire_slave_stop(worker->slave); + onewire_slave_detach(worker->slave); +} + +void ibutton_worker_emulate_timer_cb(void* context) { + furi_assert(context); + iButtonWorker* worker = context; + + bool polarity; + uint32_t length; + + switch(worker->emulate_mode) { + case iButtonEmulateModeCyfral: + encoder_cyfral_get_pulse(worker->encoder_cyfral, &polarity, &length); + break; + case iButtonEmulateModeMetakom: + encoder_metakom_get_pulse(worker->encoder_metakom, &polarity, &length); + break; + } + + furi_hal_ibutton_emulate_set_next(length); + + if(polarity) { + furi_hal_ibutton_pin_high(); + } else { + furi_hal_ibutton_pin_low(); + } +} + +void ibutton_worker_emulate_timer_start(iButtonWorker* worker) { + furi_assert(worker->key_p); + const uint8_t* key_id = ibutton_key_get_data_p(worker->key_p); + const uint8_t key_size = ibutton_key_get_max_size(); + + switch(ibutton_key_get_type(worker->key_p)) { + case iButtonKeyDS1990: + return; + break; + case iButtonKeyCyfral: + worker->emulate_mode = iButtonEmulateModeCyfral; + encoder_cyfral_reset(worker->encoder_cyfral); + encoder_cyfral_set_data(worker->encoder_cyfral, key_id, key_size); + break; + case iButtonKeyMetakom: + worker->emulate_mode = iButtonEmulateModeMetakom; + encoder_metakom_reset(worker->encoder_metakom); + encoder_metakom_set_data(worker->encoder_metakom, key_id, key_size); + break; + } + + furi_hal_ibutton_start_drive(); + furi_hal_ibutton_emulate_start(0, ibutton_worker_emulate_timer_cb, worker); +} + +void ibutton_worker_emulate_timer_stop(iButtonWorker* worker) { + furi_hal_ibutton_emulate_stop(); +} + +void ibutton_worker_mode_emulate_start(iButtonWorker* worker) { + furi_assert(worker->key_p); + + furi_hal_rfid_pins_reset(); + furi_hal_rfid_pin_pull_pulldown(); + + switch(ibutton_key_get_type(worker->key_p)) { + case iButtonKeyDS1990: + ibutton_worker_emulate_dallas_start(worker); + break; + case iButtonKeyCyfral: + case iButtonKeyMetakom: + ibutton_worker_emulate_timer_start(worker); + break; + } +} + +void ibutton_worker_mode_emulate_tick(iButtonWorker* worker) { +} + +void ibutton_worker_mode_emulate_stop(iButtonWorker* worker) { + furi_assert(worker->key_p); + + furi_hal_rfid_pins_reset(); + + switch(ibutton_key_get_type(worker->key_p)) { + case iButtonKeyDS1990: + ibutton_worker_emulate_dallas_stop(worker); + break; + case iButtonKeyCyfral: + case iButtonKeyMetakom: + ibutton_worker_emulate_timer_stop(worker); + break; + } +} + +/*********************** WRITE ***********************/ + +void ibutton_worker_mode_write_start(iButtonWorker* worker) { + furi_hal_power_enable_otg(); + onewire_host_start(worker->host); +} + +void ibutton_worker_mode_write_tick(iButtonWorker* worker) { + furi_check(worker->key_p != NULL); + iButtonWriterResult writer_result = ibutton_writer_write(worker->writer, worker->key_p); + iButtonWorkerWriteResult result; + switch(writer_result) { + case iButtonWriterOK: + result = iButtonWorkerWriteOK; + break; + case iButtonWriterSameKey: + result = iButtonWorkerWriteSameKey; + break; + case iButtonWriterNoDetect: + result = iButtonWorkerWriteNoDetect; + break; + case iButtonWriterCannotWrite: + result = iButtonWorkerWriteCannotWrite; + break; + default: + result = iButtonWorkerWriteNoDetect; + break; + } + + if(worker->write_cb != NULL) { + worker->write_cb(worker->cb_ctx, result); + } +} + +void ibutton_worker_mode_write_stop(iButtonWorker* worker) { + furi_hal_power_disable_otg(); + onewire_host_stop(worker->host); +} \ No newline at end of file diff --git a/lib/one_wire/ibutton/ibutton_writer.c b/lib/one_wire/ibutton/ibutton_writer.c new file mode 100644 index 00000000..fc63e951 --- /dev/null +++ b/lib/one_wire/ibutton/ibutton_writer.c @@ -0,0 +1,298 @@ +#include +#include +#include "ibutton_writer.h" +#include "ibutton_key_command.h" + +/*********************** PRIVATE ***********************/ + +struct iButtonWriter { + OneWireHost* host; +}; + +static void writer_write_one_bit(iButtonWriter* writer, bool value, uint32_t delay) { + onewire_host_write_bit(writer->host, value); + furi_hal_delay_us(delay); +} + +static void writer_write_byte_ds1990(iButtonWriter* writer, uint8_t data) { + for(uint8_t n_bit = 0; n_bit < 8; n_bit++) { + onewire_host_write_bit(writer->host, data & 1); + furi_hal_delay_us(5000); + data = data >> 1; + } +} + +static bool writer_compare_key_ds1990(iButtonWriter* writer, iButtonKey* key) { + bool result = false; + + if(ibutton_key_get_type(key) == iButtonKeyDS1990) { + FURI_CRITICAL_ENTER(); + bool presence = onewire_host_reset(writer->host); + + if(presence) { + onewire_host_write(writer->host, DS1990_CMD_READ_ROM); + + result = true; + for(uint8_t i = 0; i < ibutton_key_get_data_size(key); i++) { + if(ibutton_key_get_data_p(key)[i] != onewire_host_read(writer->host)) { + result = false; + break; + } + } + } + + FURI_CRITICAL_EXIT(); + } + + return result; +} + +static bool writer_write_TM2004(iButtonWriter* writer, iButtonKey* key) { + uint8_t answer; + bool result = true; + + if(ibutton_key_get_type(key) == iButtonKeyDS1990) { + FURI_CRITICAL_ENTER(); + + // write rom, addr is 0x0000 + onewire_host_reset(writer->host); + onewire_host_write(writer->host, TM2004_CMD_WRITE_ROM); + onewire_host_write(writer->host, 0x00); + onewire_host_write(writer->host, 0x00); + + // write key + for(uint8_t i = 0; i < ibutton_key_get_data_size(key); i++) { + // write key byte + onewire_host_write(writer->host, ibutton_key_get_data_p(key)[i]); + answer = onewire_host_read(writer->host); + // TODO: check answer CRC + + // pulse indicating that data is correct + furi_hal_delay_us(600); + writer_write_one_bit(writer, 1, 50000); + + // read writed key byte + answer = onewire_host_read(writer->host); + + // check that writed and readed are same + if(ibutton_key_get_data_p(key)[i] != answer) { + result = false; + break; + } + } + + if(!writer_compare_key_ds1990(writer, key)) { + result = false; + } + + onewire_host_reset(writer->host); + + FURI_CRITICAL_EXIT(); + } else { + result = false; + } + + return result; +} + +static bool writer_write_1990_1(iButtonWriter* writer, iButtonKey* key) { + bool result = false; + + if(ibutton_key_get_type(key) == iButtonKeyDS1990) { + FURI_CRITICAL_ENTER(); + + // unlock + onewire_host_reset(writer->host); + onewire_host_write(writer->host, RW1990_1_CMD_WRITE_RECORD_FLAG); + furi_hal_delay_us(10); + writer_write_one_bit(writer, 0, 5000); + + // write key + onewire_host_reset(writer->host); + onewire_host_write(writer->host, RW1990_1_CMD_WRITE_ROM); + for(uint8_t i = 0; i < ibutton_key_get_data_size(key); i++) { + // inverted key for RW1990.1 + writer_write_byte_ds1990(writer, ~ibutton_key_get_data_p(key)[i]); + furi_hal_delay_us(30000); + } + + // lock + onewire_host_write(writer->host, RW1990_1_CMD_WRITE_RECORD_FLAG); + writer_write_one_bit(writer, 1, 10000); + + FURI_CRITICAL_EXIT(); + + if(writer_compare_key_ds1990(writer, key)) { + result = true; + } + } + + return result; +} + +static bool writer_write_1990_2(iButtonWriter* writer, iButtonKey* key) { + bool result = false; + + if(ibutton_key_get_type(key) == iButtonKeyDS1990) { + FURI_CRITICAL_ENTER(); + + // unlock + onewire_host_reset(writer->host); + onewire_host_write(writer->host, RW1990_2_CMD_WRITE_RECORD_FLAG); + furi_hal_delay_us(10); + writer_write_one_bit(writer, 1, 5000); + + // write key + onewire_host_reset(writer->host); + onewire_host_write(writer->host, RW1990_2_CMD_WRITE_ROM); + for(uint8_t i = 0; i < ibutton_key_get_data_size(key); i++) { + writer_write_byte_ds1990(writer, ibutton_key_get_data_p(key)[i]); + furi_hal_delay_us(30000); + } + + // lock + onewire_host_write(writer->host, RW1990_2_CMD_WRITE_RECORD_FLAG); + writer_write_one_bit(writer, 0, 10000); + + FURI_CRITICAL_EXIT(); + + if(writer_compare_key_ds1990(writer, key)) { + result = true; + } + } + + return result; +} + +/* +// TODO: adapt and test +static bool writer_write_TM01( + iButtonWriter* writer, + iButtonKey type, + const uint8_t* key, + uint8_t key_length) { + bool result = true; + + { + // TODO test and encoding + FURI_CRITICAL_ENTER(); + + // unlock + onewire_host_reset(writer->host); + onewire_host_write(writer->host, TM01::CMD_WRITE_RECORD_FLAG); + onewire_write_one_bit(1, 10000); + + // write key + onewire_host_reset(writer->host); + onewire_host_write(writer->host, TM01::CMD_WRITE_ROM); + + // TODO: key types + //if(type == KEY_METAKOM || type == KEY_CYFRAL) { + //} else { + for(uint8_t i = 0; i < key->get_type_data_size(); i++) { + write_byte_ds1990(key->get_data()[i]); + furi_hal_delay_us(10000); + } + //} + + // lock + onewire_host_write(writer->host, TM01::CMD_WRITE_RECORD_FLAG); + onewire_write_one_bit(0, 10000); + + FURI_CRITICAL_EXIT(); + } + + if(!compare_key_ds1990(key)) { + result = false; + } + + { + FURI_CRITICAL_ENTER(); + + if(key->get_key_type() == iButtonKeyType::KeyMetakom || + key->get_key_type() == iButtonKeyType::KeyCyfral) { + onewire_host_reset(writer->host); + if(key->get_key_type() == iButtonKeyType::KeyCyfral) + onewire_host_write(writer->host, TM01::CMD_SWITCH_TO_CYFRAL); + else + onewire_host_write(writer->host, TM01::CMD_SWITCH_TO_METAKOM); + onewire_write_one_bit(1); + } + + FURI_CRITICAL_EXIT(); + } + + return result; +} +*/ + +static iButtonWriterResult writer_write_DS1990(iButtonWriter* writer, iButtonKey* key) { + iButtonWriterResult result = iButtonWriterNoDetect; + bool same_key = writer_compare_key_ds1990(writer, key); + + if(!same_key) { + // currently we can write: + // RW1990_1, TM08v2, TM08vi-2 by write_1990_1() + // RW1990_2 by write_1990_2() + // RW2004, RW2004, TM2004 with EEPROM by write_TM2004(); + + bool write_result = true; + do { + if(writer_write_1990_1(writer, key)) break; + if(writer_write_1990_2(writer, key)) break; + if(writer_write_TM2004(writer, key)) break; + write_result = false; + } while(false); + + if(write_result) { + result = iButtonWriterOK; + } else { + result = iButtonWriterCannotWrite; + } + } else { + result = iButtonWriterSameKey; + } + + return result; +} + +/*********************** PUBLIC ***********************/ + +iButtonWriter* ibutton_writer_alloc(OneWireHost* host) { + iButtonWriter* writer = malloc(sizeof(iButtonWriter)); + writer->host = host; + return writer; +} + +void ibutton_writer_free(iButtonWriter* writer) { + free(writer); +} + +iButtonWriterResult ibutton_writer_write(iButtonWriter* writer, iButtonKey* key) { + iButtonWriterResult result = iButtonWriterNoDetect; + + osKernelLock(); + bool blank_present = onewire_host_reset(writer->host); + osKernelUnlock(); + + if(blank_present) { + switch(ibutton_key_get_type(key)) { + case iButtonKeyDS1990: + result = writer_write_DS1990(writer, key); + default: + break; + } + } + + return result; +} + +void ibutton_writer_start(iButtonWriter* writer) { + furi_hal_power_enable_otg(); + onewire_host_start(writer->host); +} + +void ibutton_writer_stop(iButtonWriter* writer) { + onewire_host_stop(writer->host); + furi_hal_power_disable_otg(); +} diff --git a/lib/one_wire/ibutton/ibutton_writer.h b/lib/one_wire/ibutton/ibutton_writer.h new file mode 100644 index 00000000..8e81cfd1 --- /dev/null +++ b/lib/one_wire/ibutton/ibutton_writer.h @@ -0,0 +1,60 @@ +/** + * @file ibutton_writer.h + * + * iButton blanks writer + */ + +#pragma once +#include +#include "ibutton_key.h" +#include "../one_wire_host.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + iButtonWriterOK, + iButtonWriterSameKey, + iButtonWriterNoDetect, + iButtonWriterCannotWrite, +} iButtonWriterResult; + +typedef struct iButtonWriter iButtonWriter; + +/** + * Allocate writer + * @param host + * @return iButtonWriter* + */ +iButtonWriter* ibutton_writer_alloc(OneWireHost* host); + +/** + * Deallocate writer + * @param writer + */ +void ibutton_writer_free(iButtonWriter* writer); + +/** + * Write key to blank + * @param writer + * @param key + * @return iButtonWriterResult + */ +iButtonWriterResult ibutton_writer_write(iButtonWriter* writer, iButtonKey* key); + +/** + * Start writing. Must be called before write attempt + * @param writer + */ +void ibutton_writer_start(iButtonWriter* writer); + +/** + * Stop writing + * @param writer + */ +void ibutton_writer_stop(iButtonWriter* writer); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/lib/one_wire/ibutton/pulse_protocols/protocol_cyfral.c b/lib/one_wire/ibutton/pulse_protocols/protocol_cyfral.c new file mode 100644 index 00000000..09635edf --- /dev/null +++ b/lib/one_wire/ibutton/pulse_protocols/protocol_cyfral.c @@ -0,0 +1,256 @@ +#include "protocol_cyfral.h" +#include +#include +#include +#include + +#define CYFRAL_DATA_SIZE 2 +#define CYFRAL_MAX_PERIOD_US 230 + +typedef enum { + CYFRAL_BIT_WAIT_FRONT_HIGH, + CYFRAL_BIT_WAIT_FRONT_LOW, +} CyfralBitState; + +typedef enum { + CYFRAL_WAIT_START_NIBBLE, + CYFRAL_READ_NIBBLE, + CYFRAL_READ_STOP_NIBBLE, +} CyfralState; + +struct ProtocolCyfral { + PulseProtocol* protocol; + + CyfralState state; + CyfralBitState bit_state; + + // ready flag, key is read and valid + // TODO: atomic access + bool ready; + // key data storage + uint16_t key_data; + // high + low period time + uint32_t period_time; + // temporary nibble storage + uint8_t nibble; + // data valid flag + // MUST be checked only in READ_STOP_NIBBLE state + bool data_valid; + // nibble index, we expect 8 nibbles + uint8_t index; + // bit index in nibble, 4 bit per nibble + uint8_t bit_index; + // max period, 230us x clock per us + uint32_t max_period; +}; + +static void cyfral_pulse(void* context, bool polarity, uint32_t length); +static void cyfral_reset(void* context); +static void cyfral_get_data(void* context, uint8_t* data, size_t length); +static bool cyfral_decoded(void* context); + +ProtocolCyfral* protocol_cyfral_alloc() { + ProtocolCyfral* cyfral = malloc(sizeof(ProtocolCyfral)); + cyfral_reset(cyfral); + + cyfral->protocol = pulse_protocol_alloc(); + + pulse_protocol_set_context(cyfral->protocol, cyfral); + pulse_protocol_set_pulse_cb(cyfral->protocol, cyfral_pulse); + pulse_protocol_set_reset_cb(cyfral->protocol, cyfral_reset); + pulse_protocol_set_get_data_cb(cyfral->protocol, cyfral_get_data); + pulse_protocol_set_decoded_cb(cyfral->protocol, cyfral_decoded); + + return cyfral; +} + +void protocol_cyfral_free(ProtocolCyfral* cyfral) { + furi_assert(cyfral); + pulse_protocol_free(cyfral->protocol); + free(cyfral); +} + +PulseProtocol* protocol_cyfral_get_protocol(ProtocolCyfral* cyfral) { + furi_assert(cyfral); + return cyfral->protocol; +} + +static void cyfral_get_data(void* context, uint8_t* data, size_t length) { + furi_assert(context); + furi_check(length >= CYFRAL_DATA_SIZE); + ProtocolCyfral* cyfral = context; + memcpy(data, &cyfral->key_data, CYFRAL_DATA_SIZE); +} + +static bool cyfral_decoded(void* context) { + furi_assert(context); + ProtocolCyfral* cyfral = context; + bool decoded = cyfral->ready; + return decoded; +} + +static void cyfral_reset(void* context) { + furi_assert(context); + ProtocolCyfral* cyfral = context; + cyfral->state = CYFRAL_WAIT_START_NIBBLE; + cyfral->bit_state = CYFRAL_BIT_WAIT_FRONT_LOW; + + cyfral->period_time = 0; + cyfral->bit_index = 0; + cyfral->ready = false; + cyfral->index = 0; + + cyfral->key_data = 0; + cyfral->nibble = 0; + cyfral->data_valid = true; + + cyfral->max_period = CYFRAL_MAX_PERIOD_US * instructions_per_us; +} + +static bool cyfral_process_bit( + ProtocolCyfral* cyfral, + bool polarity, + uint32_t length, + bool* bit_ready, + bool* bit_value) { + bool result = true; + *bit_ready = false; + + // bit start from low + switch(cyfral->bit_state) { + case CYFRAL_BIT_WAIT_FRONT_LOW: + if(polarity == true) { + cyfral->period_time += length; + + *bit_ready = true; + if(cyfral->period_time <= cyfral->max_period) { + if((cyfral->period_time / 2) > length) { + *bit_value = false; + } else { + *bit_value = true; + } + } else { + result = false; + } + + cyfral->bit_state = CYFRAL_BIT_WAIT_FRONT_HIGH; + } else { + result = false; + } + break; + case CYFRAL_BIT_WAIT_FRONT_HIGH: + if(polarity == false) { + cyfral->period_time = length; + cyfral->bit_state = CYFRAL_BIT_WAIT_FRONT_LOW; + } else { + result = false; + } + break; + } + + return result; +} + +static void cyfral_pulse(void* context, bool polarity, uint32_t length) { + furi_assert(context); + ProtocolCyfral* cyfral = context; + + bool bit_ready; + bool bit_value; + + if(cyfral->ready) return; + + switch(cyfral->state) { + case CYFRAL_WAIT_START_NIBBLE: + // wait for start word + if(cyfral_process_bit(cyfral, polarity, length, &bit_ready, &bit_value)) { + if(bit_ready) { + cyfral->nibble = ((cyfral->nibble << 1) | bit_value) & 0x0F; + if(cyfral->nibble == 0b0001) { + cyfral->nibble = 0; + cyfral->state = CYFRAL_READ_NIBBLE; + } + } + } else { + cyfral_reset(cyfral); + } + + break; + case CYFRAL_READ_NIBBLE: + // read nibbles + if(cyfral_process_bit(cyfral, polarity, length, &bit_ready, &bit_value)) { + if(bit_ready) { + cyfral->nibble = (cyfral->nibble << 1) | bit_value; + + cyfral->bit_index++; + + //convert every nibble to 2-bit index + if(cyfral->bit_index == 4) { + switch(cyfral->nibble) { + case 0b1110: + cyfral->key_data = (cyfral->key_data << 2) | 0b11; + break; + case 0b1101: + cyfral->key_data = (cyfral->key_data << 2) | 0b10; + break; + case 0b1011: + cyfral->key_data = (cyfral->key_data << 2) | 0b01; + break; + case 0b0111: + cyfral->key_data = (cyfral->key_data << 2) | 0b00; + break; + default: + cyfral->data_valid = false; + break; + } + + cyfral->nibble = 0; + cyfral->bit_index = 0; + cyfral->index++; + } + + // succefully read 8 nibbles + if(cyfral->index == 8) { + cyfral->state = CYFRAL_READ_STOP_NIBBLE; + } + } + } else { + cyfral_reset(cyfral); + } + break; + case CYFRAL_READ_STOP_NIBBLE: + // read stop nibble + if(cyfral_process_bit(cyfral, polarity, length, &bit_ready, &bit_value)) { + if(bit_ready) { + cyfral->nibble = ((cyfral->nibble << 1) | bit_value) & 0x0F; + cyfral->bit_index++; + + switch(cyfral->bit_index) { + case 0: + case 1: + case 2: + case 3: + break; + case 4: + if(cyfral->nibble == 0b0001) { + // validate data + if(cyfral->data_valid) { + cyfral->ready = true; + } else { + cyfral_reset(cyfral); + } + } else { + cyfral_reset(cyfral); + } + break; + default: + cyfral_reset(cyfral); + break; + } + } + } else { + cyfral_reset(cyfral); + } + break; + } +} diff --git a/lib/one_wire/ibutton/pulse_protocols/protocol_cyfral.h b/lib/one_wire/ibutton/pulse_protocols/protocol_cyfral.h new file mode 100644 index 00000000..4a7c00e4 --- /dev/null +++ b/lib/one_wire/ibutton/pulse_protocols/protocol_cyfral.h @@ -0,0 +1,38 @@ +/** + * @file protocol_cyfral.h + * + * Cyfral pulse format decoder + */ + +#pragma once +#include +#include "../../pulse_protocols/pulse_protocol.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ProtocolCyfral ProtocolCyfral; + +/** + * Allocate decoder + * @return ProtocolCyfral* + */ +ProtocolCyfral* protocol_cyfral_alloc(); + +/** + * Deallocate decoder + * @param cyfral + */ +void protocol_cyfral_free(ProtocolCyfral* cyfral); + +/** + * Get protocol interface + * @param cyfral + * @return PulseProtocol* + */ +PulseProtocol* protocol_cyfral_get_protocol(ProtocolCyfral* cyfral); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/lib/one_wire/ibutton/pulse_protocols/protocol_metakom.c b/lib/one_wire/ibutton/pulse_protocols/protocol_metakom.c new file mode 100644 index 00000000..d76ef886 --- /dev/null +++ b/lib/one_wire/ibutton/pulse_protocols/protocol_metakom.c @@ -0,0 +1,262 @@ +#include "protocol_metakom.h" +#include +#include +#include +#include + +#define METAKOM_DATA_SIZE 4 +#define METAKOM_PERIOD_SAMPLE_COUNT 10 + +typedef enum { + METAKOM_WAIT_PERIOD_SYNC, + METAKOM_WAIT_START_BIT, + METAKOM_WAIT_START_WORD, + METAKOM_READ_WORD, + METAKOM_READ_STOP_WORD, +} MetakomState; + +typedef enum { + METAKOM_BIT_WAIT_FRONT_HIGH, + METAKOM_BIT_WAIT_FRONT_LOW, +} MetakomBitState; + +struct ProtocolMetakom { + PulseProtocol* protocol; + + // high + low period time + uint32_t period_time; + uint32_t low_time_storage; + uint8_t period_sample_index; + uint32_t period_sample_data[METAKOM_PERIOD_SAMPLE_COUNT]; + + // ready flag + // TODO: atomic access + bool ready; + + uint8_t tmp_data; + uint8_t tmp_counter; + + uint32_t key_data; + uint8_t key_data_index; + + MetakomBitState bit_state; + MetakomState state; +}; + +static void metakom_pulse(void* context, bool polarity, uint32_t length); +static void metakom_reset(void* context); +static void metakom_get_data(void* context, uint8_t* data, size_t length); +static bool metakom_decoded(void* context); + +ProtocolMetakom* protocol_metakom_alloc() { + ProtocolMetakom* metakom = malloc(sizeof(ProtocolMetakom)); + metakom_reset(metakom); + + metakom->protocol = pulse_protocol_alloc(); + + pulse_protocol_set_context(metakom->protocol, metakom); + pulse_protocol_set_pulse_cb(metakom->protocol, metakom_pulse); + pulse_protocol_set_reset_cb(metakom->protocol, metakom_reset); + pulse_protocol_set_get_data_cb(metakom->protocol, metakom_get_data); + pulse_protocol_set_decoded_cb(metakom->protocol, metakom_decoded); + + return metakom; +} + +void protocol_metakom_free(ProtocolMetakom* metakom) { + furi_assert(metakom); + pulse_protocol_free(metakom->protocol); + free(metakom); +} + +PulseProtocol* protocol_metakom_get_protocol(ProtocolMetakom* metakom) { + furi_assert(metakom); + return metakom->protocol; +} + +static void metakom_get_data(void* context, uint8_t* data, size_t length) { + furi_assert(context); + furi_check(length >= METAKOM_DATA_SIZE); + ProtocolMetakom* metakom = context; + memcpy(data, &metakom->key_data, METAKOM_DATA_SIZE); +} + +static bool metakom_decoded(void* context) { + furi_assert(context); + ProtocolMetakom* metakom = context; + bool decoded = metakom->ready; + return decoded; +} + +static void metakom_reset(void* context) { + furi_assert(context); + ProtocolMetakom* metakom = context; + + metakom->ready = false; + metakom->period_sample_index = 0; + metakom->period_time = 0; + metakom->tmp_counter = 0; + metakom->tmp_data = 0; + for(uint8_t i = 0; i < METAKOM_PERIOD_SAMPLE_COUNT; i++) { + metakom->period_sample_data[i] = 0; + }; + metakom->state = METAKOM_WAIT_PERIOD_SYNC; + metakom->bit_state = METAKOM_BIT_WAIT_FRONT_LOW; + metakom->key_data = 0; + metakom->key_data_index = 0; + metakom->low_time_storage = 0; +} + +static bool metakom_parity_check(uint8_t data) { + uint8_t ones_count = 0; + bool result; + + for(uint8_t i = 0; i < 8; i++) { + if((data >> i) & 0b00000001) { + ones_count++; + } + } + + result = (ones_count % 2 == 0); + + return result; +} + +static bool metakom_process_bit( + ProtocolMetakom* metakom, + bool polarity, + uint32_t time, + uint32_t* high_time, + uint32_t* low_time) { + bool result = false; + + switch(metakom->bit_state) { + case METAKOM_BIT_WAIT_FRONT_LOW: + if(polarity == false) { + *low_time = metakom->low_time_storage; + *high_time = time; + result = true; + metakom->bit_state = METAKOM_BIT_WAIT_FRONT_HIGH; + } + break; + case METAKOM_BIT_WAIT_FRONT_HIGH: + if(polarity == true) { + metakom->low_time_storage = time; + metakom->bit_state = METAKOM_BIT_WAIT_FRONT_LOW; + } + break; + } + + return result; +} + +static void metakom_pulse(void* context, bool polarity, uint32_t time) { + furi_assert(context); + ProtocolMetakom* metakom = context; + + if(metakom->ready) return; + + uint32_t high_time = 0; + uint32_t low_time = 0; + + switch(metakom->state) { + case METAKOM_WAIT_PERIOD_SYNC: + if(metakom_process_bit(metakom, polarity, time, &high_time, &low_time)) { + metakom->period_sample_data[metakom->period_sample_index] = high_time + low_time; + metakom->period_sample_index++; + + if(metakom->period_sample_index == METAKOM_PERIOD_SAMPLE_COUNT) { + for(uint8_t i = 0; i < METAKOM_PERIOD_SAMPLE_COUNT; i++) { + metakom->period_time += metakom->period_sample_data[i]; + }; + metakom->period_time /= METAKOM_PERIOD_SAMPLE_COUNT; + + metakom->state = METAKOM_WAIT_START_BIT; + } + } + + break; + case METAKOM_WAIT_START_BIT: + if(metakom_process_bit(metakom, polarity, time, &high_time, &low_time)) { + metakom->tmp_counter++; + if(high_time > metakom->period_time) { + metakom->tmp_counter = 0; + metakom->state = METAKOM_WAIT_START_WORD; + } + + if(metakom->tmp_counter > 40) { + metakom_reset(metakom); + } + } + + break; + case METAKOM_WAIT_START_WORD: + if(metakom_process_bit(metakom, polarity, time, &high_time, &low_time)) { + if(low_time < (metakom->period_time / 2)) { + metakom->tmp_data = (metakom->tmp_data << 1) | 0b0; + } else { + metakom->tmp_data = (metakom->tmp_data << 1) | 0b1; + } + metakom->tmp_counter++; + + if(metakom->tmp_counter == 3) { + if(metakom->tmp_data == 0b010) { + metakom->tmp_counter = 0; + metakom->tmp_data = 0; + metakom->state = METAKOM_READ_WORD; + } else { + metakom_reset(metakom); + } + } + } + break; + case METAKOM_READ_WORD: + if(metakom_process_bit(metakom, polarity, time, &high_time, &low_time)) { + if(low_time < (metakom->period_time / 2)) { + metakom->tmp_data = (metakom->tmp_data << 1) | 0b0; + } else { + metakom->tmp_data = (metakom->tmp_data << 1) | 0b1; + } + metakom->tmp_counter++; + + if(metakom->tmp_counter == 8) { + if(metakom_parity_check(metakom->tmp_data)) { + metakom->key_data = (metakom->key_data << 8) | metakom->tmp_data; + metakom->key_data_index++; + metakom->tmp_data = 0; + metakom->tmp_counter = 0; + + if(metakom->key_data_index == 4) { + // check for stop bit + if(high_time > metakom->period_time) { + metakom->state = METAKOM_READ_STOP_WORD; + } else { + metakom_reset(metakom); + } + } + } else { + metakom_reset(metakom); + } + } + } + break; + case METAKOM_READ_STOP_WORD: + if(metakom_process_bit(metakom, polarity, time, &high_time, &low_time)) { + if(low_time < (metakom->period_time / 2)) { + metakom->tmp_data = (metakom->tmp_data << 1) | 0b0; + } else { + metakom->tmp_data = (metakom->tmp_data << 1) | 0b1; + } + metakom->tmp_counter++; + + if(metakom->tmp_counter == 3) { + if(metakom->tmp_data == 0b010) { + metakom->ready = true; + } else { + metakom_reset(metakom); + } + } + } + break; + } +} diff --git a/lib/one_wire/ibutton/pulse_protocols/protocol_metakom.h b/lib/one_wire/ibutton/pulse_protocols/protocol_metakom.h new file mode 100644 index 00000000..fbafc235 --- /dev/null +++ b/lib/one_wire/ibutton/pulse_protocols/protocol_metakom.h @@ -0,0 +1,38 @@ +/** + * @file protocol_metakom.h + * + * Metakom pulse format decoder + */ + +#pragma once +#include +#include "../../pulse_protocols/pulse_protocol.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ProtocolMetakom ProtocolMetakom; + +/** + * Allocate decoder + * @return ProtocolMetakom* + */ +ProtocolMetakom* protocol_metakom_alloc(); + +/** + * Free decoder + * @param metakom + */ +void protocol_metakom_free(ProtocolMetakom* metakom); + +/** + * Get protocol interface + * @param metakom + * @return PulseProtocol* + */ +PulseProtocol* protocol_metakom_get_protocol(ProtocolMetakom* metakom); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/lib/one_wire/maxim_crc.c b/lib/one_wire/maxim_crc.c new file mode 100644 index 00000000..bd89d3ad --- /dev/null +++ b/lib/one_wire/maxim_crc.c @@ -0,0 +1,16 @@ +#include "maxim_crc.h" + +uint8_t maxim_crc8(const uint8_t* data, const uint8_t data_size, const uint8_t crc_init) { + uint8_t crc = crc_init; + + for(uint8_t index = 0; index < data_size; ++index) { + uint8_t input_byte = data[index]; + for(uint8_t bit_position = 0; bit_position < 8; ++bit_position) { + const uint8_t mix = (crc ^ input_byte) & (uint8_t)(0x01); + crc >>= 1; + if(mix != 0) crc ^= 0x8C; + input_byte >>= 1; + } + } + return crc; +} \ No newline at end of file diff --git a/lib/one_wire/maxim_crc.h b/lib/one_wire/maxim_crc.h new file mode 100644 index 00000000..1b7e8498 --- /dev/null +++ b/lib/one_wire/maxim_crc.h @@ -0,0 +1,14 @@ +#pragma once +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAXIM_CRC8_INIT 0 + +uint8_t maxim_crc8(const uint8_t* data, const uint8_t data_size, const uint8_t crc_init); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/lib/one_wire/one_wire_device.c b/lib/one_wire/one_wire_device.c new file mode 100644 index 00000000..d9b4955d --- /dev/null +++ b/lib/one_wire/one_wire_device.c @@ -0,0 +1,59 @@ +#include +#include "maxim_crc.h" +#include "one_wire_device.h" +#include "one_wire_slave.h" +#include "one_wire_slave_i.h" + +struct OneWireDevice { + uint8_t id_storage[8]; + OneWireSlave* bus; +}; + +OneWireDevice* onewire_device_alloc( + uint8_t id_1, + uint8_t id_2, + uint8_t id_3, + uint8_t id_4, + uint8_t id_5, + uint8_t id_6, + uint8_t id_7, + uint8_t id_8) { + OneWireDevice* device = malloc(sizeof(OneWireDevice)); + device->id_storage[0] = id_1; + device->id_storage[1] = id_2; + device->id_storage[2] = id_3; + device->id_storage[3] = id_4; + device->id_storage[4] = id_5; + device->id_storage[5] = id_6; + device->id_storage[6] = id_7; + device->id_storage[7] = id_8; + device->bus = NULL; + + return device; +} + +void onewire_device_free(OneWireDevice* device) { + if(device->bus != NULL) { + onewire_slave_detach(device->bus); + } + + free(device); +} + +void onewire_device_send_id(OneWireDevice* device) { + if(device->bus != NULL) { + onewire_slave_send(device->bus, device->id_storage, 8); + } +} + +void onewire_device_attach(OneWireDevice* device, OneWireSlave* bus) { + device->bus = bus; +} + +void onewire_device_detach(OneWireDevice* device) { + device->bus = NULL; +} + +uint8_t* onewire_device_get_id_p(OneWireDevice* device) { + return device->id_storage; +} diff --git a/lib/one_wire/one_wire_device.h b/lib/one_wire/one_wire_device.h new file mode 100644 index 00000000..4ff16790 --- /dev/null +++ b/lib/one_wire/one_wire_device.h @@ -0,0 +1,74 @@ +/** + * @file one_wire_device.h + * + * 1-Wire slave library, device interface. Currently it can only emulate ID. + */ + +#pragma once +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct OneWireSlave OneWireSlave; +typedef struct OneWireDevice OneWireDevice; + +/** + * Allocate onewire device with ID + * @param id_1 + * @param id_2 + * @param id_3 + * @param id_4 + * @param id_5 + * @param id_6 + * @param id_7 + * @param id_8 + * @return OneWireDevice* + */ +OneWireDevice* onewire_device_alloc( + uint8_t id_1, + uint8_t id_2, + uint8_t id_3, + uint8_t id_4, + uint8_t id_5, + uint8_t id_6, + uint8_t id_7, + uint8_t id_8); + +/** + * Deallocate onewire device + * @param device + */ +void onewire_device_free(OneWireDevice* device); + +/** + * Send ID report, called from onewire slave + * @param device + */ +void onewire_device_send_id(OneWireDevice* device); + +/** + * Attach device to onewire slave bus + * @param device + * @param bus + */ +void onewire_device_attach(OneWireDevice* device, OneWireSlave* bus); + +/** + * Attach device from onewire slave bus + * @param device + */ +void onewire_device_detach(OneWireDevice* device); + +/** + * Get pointer to device id array + * @param device + * @return uint8_t* + */ +uint8_t* onewire_device_get_id_p(OneWireDevice* device); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/lib/one_wire/one_wire_host.c b/lib/one_wire/one_wire_host.c new file mode 100644 index 00000000..fd8deaf8 --- /dev/null +++ b/lib/one_wire/one_wire_host.c @@ -0,0 +1,261 @@ +#include +#include +#include "one_wire_host.h" +#include "one_wire_host_timing.h" + +struct OneWireHost { + // global search state + unsigned char saved_rom[8]; + uint8_t last_discrepancy; + uint8_t last_family_discrepancy; + bool last_device_flag; +}; + +OneWireHost* onewire_host_alloc() { + OneWireHost* host = malloc(sizeof(OneWireHost)); + onewire_host_reset_search(host); + return host; +} + +void onewire_host_free(OneWireHost* host) { + onewire_host_stop(host); + free(host); +} + +bool onewire_host_reset(OneWireHost* host) { + uint8_t r; + uint8_t retries = 125; + + // wait until the gpio is high + furi_hal_ibutton_pin_high(); + do { + if(--retries == 0) return 0; + furi_hal_delay_us(2); + } while(!furi_hal_ibutton_pin_get_level()); + + // pre delay + furi_hal_delay_us(OWH_RESET_DELAY_PRE); + + // drive low + furi_hal_ibutton_pin_low(); + furi_hal_delay_us(OWH_RESET_DRIVE); + + // release + furi_hal_ibutton_pin_high(); + furi_hal_delay_us(OWH_RESET_RELEASE); + + // read and post delay + r = !furi_hal_ibutton_pin_get_level(); + furi_hal_delay_us(OWH_RESET_DELAY_POST); + + return r; +} + +bool onewire_host_read_bit(OneWireHost* host) { + bool result; + + // drive low + furi_hal_ibutton_pin_low(); + furi_hal_delay_us(OWH_READ_DRIVE); + + // release + furi_hal_ibutton_pin_high(); + furi_hal_delay_us(OWH_READ_RELEASE); + + // read and post delay + result = furi_hal_ibutton_pin_get_level(); + furi_hal_delay_us(OWH_READ_DELAY_POST); + + return result; +} + +uint8_t onewire_host_read(OneWireHost* host) { + uint8_t result = 0; + + for(uint8_t bitMask = 0x01; bitMask; bitMask <<= 1) { + if(onewire_host_read_bit(host)) { + result |= bitMask; + } + } + + return result; +} + +void onewire_host_read_bytes(OneWireHost* host, uint8_t* buffer, uint16_t count) { + for(uint16_t i = 0; i < count; i++) { + buffer[i] = onewire_host_read(host); + } +} + +void onewire_host_write_bit(OneWireHost* host, bool value) { + if(value) { + // drive low + furi_hal_ibutton_pin_low(); + furi_hal_delay_us(OWH_WRITE_1_DRIVE); + + // release + furi_hal_ibutton_pin_high(); + furi_hal_delay_us(OWH_WRITE_1_RELEASE); + } else { + // drive low + furi_hal_ibutton_pin_low(); + furi_hal_delay_us(OWH_WRITE_0_DRIVE); + + // release + furi_hal_ibutton_pin_high(); + furi_hal_delay_us(OWH_WRITE_0_RELEASE); + } +} + +void onewire_host_write(OneWireHost* host, uint8_t value) { + uint8_t bitMask; + + for(bitMask = 0x01; bitMask; bitMask <<= 1) { + onewire_host_write_bit(host, (bitMask & value) ? 1 : 0); + } +} + +void onewire_host_skip(OneWireHost* host) { + onewire_host_write(host, 0xCC); +} + +void onewire_host_start(OneWireHost* host) { + furi_hal_ibutton_start_drive(); +} + +void onewire_host_stop(OneWireHost* host) { + furi_hal_ibutton_stop(); +} + +void onewire_host_reset_search(OneWireHost* host) { + host->last_discrepancy = 0; + host->last_device_flag = false; + host->last_family_discrepancy = 0; + for(int i = 7;; i--) { + host->saved_rom[i] = 0; + if(i == 0) break; + } +} + +void onewire_host_target_search(OneWireHost* host, uint8_t family_code) { + host->saved_rom[0] = family_code; + for(uint8_t i = 1; i < 8; i++) host->saved_rom[i] = 0; + host->last_discrepancy = 64; + host->last_family_discrepancy = 0; + host->last_device_flag = false; +} + +uint8_t onewire_host_search(OneWireHost* host, uint8_t* newAddr, OneWireHostSearchMode mode) { + uint8_t id_bit_number; + uint8_t last_zero, rom_byte_number, search_result; + uint8_t id_bit, cmp_id_bit; + + unsigned char rom_byte_mask, search_direction; + + // initialize for search + id_bit_number = 1; + last_zero = 0; + rom_byte_number = 0; + rom_byte_mask = 1; + search_result = 0; + + // if the last call was not the last one + if(!host->last_device_flag) { + // 1-Wire reset + if(!onewire_host_reset(host)) { + // reset the search + host->last_discrepancy = 0; + host->last_device_flag = false; + host->last_family_discrepancy = 0; + return false; + } + + // issue the search command + switch(mode) { + case CONDITIONAL_SEARCH: + onewire_host_write(host, 0xEC); + break; + case NORMAL_SEARCH: + onewire_host_write(host, 0xF0); + break; + } + + // loop to do the search + do { + // read a bit and its complement + id_bit = onewire_host_read_bit(host); + cmp_id_bit = onewire_host_read_bit(host); + + // check for no devices on 1-wire + if((id_bit == 1) && (cmp_id_bit == 1)) + break; + else { + // all devices coupled have 0 or 1 + if(id_bit != cmp_id_bit) + search_direction = id_bit; // bit write value for search + else { + // if this discrepancy if before the Last Discrepancy + // on a previous next then pick the same as last time + if(id_bit_number < host->last_discrepancy) + search_direction = + ((host->saved_rom[rom_byte_number] & rom_byte_mask) > 0); + else + // if equal to last pick 1, if not then pick 0 + search_direction = (id_bit_number == host->last_discrepancy); + + // if 0 was picked then record its position in LastZero + if(search_direction == 0) { + last_zero = id_bit_number; + + // check for Last discrepancy in family + if(last_zero < 9) host->last_family_discrepancy = last_zero; + } + } + + // set or clear the bit in the ROM byte rom_byte_number + // with mask rom_byte_mask + if(search_direction == 1) + host->saved_rom[rom_byte_number] |= rom_byte_mask; + else + host->saved_rom[rom_byte_number] &= ~rom_byte_mask; + + // serial number search direction write bit + onewire_host_write_bit(host, search_direction); + + // increment the byte counter id_bit_number + // and shift the mask rom_byte_mask + id_bit_number++; + rom_byte_mask <<= 1; + + // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask + if(rom_byte_mask == 0) { + rom_byte_number++; + rom_byte_mask = 1; + } + } + } while(rom_byte_number < 8); // loop until through all ROM bytes 0-7 + + // if the search was successful then + if(!(id_bit_number < 65)) { + // search successful so set last_Discrepancy, last_device_flag, search_result + host->last_discrepancy = last_zero; + + // check for last device + if(host->last_discrepancy == 0) host->last_device_flag = true; + + search_result = true; + } + } + + // if no device found then reset counters so next 'search' will be like a first + if(!search_result || !host->saved_rom[0]) { + host->last_discrepancy = 0; + host->last_device_flag = false; + host->last_family_discrepancy = 0; + search_result = false; + } else { + for(int i = 0; i < 8; i++) newAddr[i] = host->saved_rom[i]; + } + + return search_result; +} diff --git a/lib/one_wire/one_wire_host.h b/lib/one_wire/one_wire_host.h new file mode 100644 index 00000000..21530640 --- /dev/null +++ b/lib/one_wire/one_wire_host.h @@ -0,0 +1,121 @@ +/** + * @file one_wire_host.h + * + * 1-Wire host (master) library + */ + +#pragma once +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + CONDITIONAL_SEARCH = 0, /**< Search for alarmed device */ + NORMAL_SEARCH = 1, /**< Search all devices */ +} OneWireHostSearchMode; + +typedef struct OneWireHost OneWireHost; + +/** + * Allocate onewire host bus + * @param gpio + * @return OneWireHost* + */ +OneWireHost* onewire_host_alloc(); + +/** + * Deallocate onewire host bus + * @param host + */ +void onewire_host_free(OneWireHost* host); + +/** + * Reset bus + * @param host + * @return bool + */ +bool onewire_host_reset(OneWireHost* host); + +/** + * Read one bit + * @param host + * @return bool + */ +bool onewire_host_read_bit(OneWireHost* host); + +/** + * Read one byte + * @param host + * @return uint8_t + */ +uint8_t onewire_host_read(OneWireHost* host); + +/** + * Read many bytes + * @param host + * @param buffer + * @param count + */ +void onewire_host_read_bytes(OneWireHost* host, uint8_t* buffer, uint16_t count); + +/** + * Write one bit + * @param host + * @param value + */ +void onewire_host_write_bit(OneWireHost* host, bool value); + +/** + * Write one byte + * @param host + * @param value + */ +void onewire_host_write(OneWireHost* host, uint8_t value); + +/** + * Skip ROM command + * @param host + */ +void onewire_host_skip(OneWireHost* host); + +/** + * Start working with the bus + * @param host + */ +void onewire_host_start(OneWireHost* host); + +/** + * Stop working with the bus + * @param host + */ +void onewire_host_stop(OneWireHost* host); + +/** + * + * @param host + */ +void onewire_host_reset_search(OneWireHost* host); + +/** + * + * @param host + * @param family_code + */ +void onewire_host_target_search(OneWireHost* host, uint8_t family_code); + +/** + * + * @param host + * @param newAddr + * @param mode + * @return uint8_t + */ +uint8_t onewire_host_search(OneWireHost* host, uint8_t* newAddr, OneWireHostSearchMode mode); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/lib/one_wire/one_wire_host_timing.h b/lib/one_wire/one_wire_host_timing.h new file mode 100644 index 00000000..f95dd356 --- /dev/null +++ b/lib/one_wire/one_wire_host_timing.h @@ -0,0 +1,30 @@ +/** + * @file one_wire_host_timing.h + * + * 1-Wire library, timing list + */ + +#pragma once + +#define OWH_TIMING_A 9 +#define OWH_TIMING_B 64 +#define OWH_TIMING_C 64 +#define OWH_TIMING_D 14 +#define OWH_TIMING_E 9 +#define OWH_TIMING_F 55 +#define OWH_TIMING_G 0 +#define OWH_TIMING_H 480 +#define OWH_TIMING_I 70 +#define OWH_TIMING_J 410 + +#define OWH_WRITE_1_DRIVE OWH_TIMING_A +#define OWH_WRITE_1_RELEASE OWH_TIMING_B +#define OWH_WRITE_0_DRIVE OWH_TIMING_C +#define OWH_WRITE_0_RELEASE OWH_TIMING_D +#define OWH_READ_DRIVE 3 +#define OWH_READ_RELEASE OWH_TIMING_E +#define OWH_READ_DELAY_POST OWH_TIMING_F +#define OWH_RESET_DELAY_PRE OWH_TIMING_G +#define OWH_RESET_DRIVE OWH_TIMING_H +#define OWH_RESET_RELEASE OWH_TIMING_I +#define OWH_RESET_DELAY_POST OWH_TIMING_J diff --git a/lib/one_wire/one_wire_slave.c b/lib/one_wire/one_wire_slave.c new file mode 100644 index 00000000..4e385e9e --- /dev/null +++ b/lib/one_wire/one_wire_slave.c @@ -0,0 +1,317 @@ +#include "one_wire_slave.h" +#include "one_wire_slave_i.h" +#include "one_wire_device.h" +#include +#include +#include + +#define OWS_RESET_MIN 270 +#define OWS_RESET_MAX 960 +#define OWS_PRESENCE_TIMEOUT 20 +#define OWS_PRESENCE_MIN 100 +#define OWS_PRESENCE_MAX 480 +#define OWS_MSG_HIGH_TIMEOUT 15000 +#define OWS_SLOT_MAX 135 +#define OWS_READ_MIN 20 +#define OWS_READ_MAX 60 +#define OWS_WRITE_ZERO 30 + +typedef enum { + NO_ERROR = 0, + VERY_LONG_RESET, + VERY_SHORT_RESET, + PRESENCE_LOW_ON_LINE, + AWAIT_TIMESLOT_TIMEOUT_HIGH, + INCORRECT_ONEWIRE_CMD, + FIRST_BIT_OF_BYTE_TIMEOUT, + RESET_IN_PROGRESS +} OneWireSlaveError; + +struct OneWireSlave { + OneWireSlaveError error; + OneWireDevice* device; + OneWireSlaveResultCallback result_cb; + void* result_cb_ctx; +}; + +/*********************** PRIVATE ***********************/ + +uint32_t onewire_slave_wait_while_gpio_is(OneWireSlave* bus, uint32_t time, const bool pin_value) { + uint32_t start = DWT->CYCCNT; + uint32_t time_ticks = time * instructions_per_us; + uint32_t time_captured; + + do { + time_captured = DWT->CYCCNT; + if(furi_hal_ibutton_pin_get_level() != pin_value) { + uint32_t remaining_time = time_ticks - (time_captured - start); + remaining_time /= instructions_per_us; + return remaining_time; + } + } while((time_captured - start) < time_ticks); + + return 0; +} + +bool onewire_slave_show_presence(OneWireSlave* bus) { + // wait while master delay presence check + onewire_slave_wait_while_gpio_is(bus, OWS_PRESENCE_TIMEOUT, true); + + // show presence + furi_hal_ibutton_pin_low(); + furi_hal_delay_us(OWS_PRESENCE_MIN); + furi_hal_ibutton_pin_high(); + + // somebody also can show presence + const uint32_t wait_low_time = OWS_PRESENCE_MAX - OWS_PRESENCE_MIN; + + // so we will wait + if(onewire_slave_wait_while_gpio_is(bus, wait_low_time, false) == 0) { + bus->error = PRESENCE_LOW_ON_LINE; + return false; + } + + return true; +} + +bool onewire_slave_receive_bit(OneWireSlave* bus) { + // wait while bus is low + uint32_t time = OWS_SLOT_MAX; + time = onewire_slave_wait_while_gpio_is(bus, time, false); + if(time == 0) { + bus->error = RESET_IN_PROGRESS; + return false; + } + + // wait while bus is high + time = OWS_MSG_HIGH_TIMEOUT; + time = onewire_slave_wait_while_gpio_is(bus, time, true); + if(time == 0) { + bus->error = AWAIT_TIMESLOT_TIMEOUT_HIGH; + return false; + } + + // wait a time of zero + time = OWS_READ_MIN; + time = onewire_slave_wait_while_gpio_is(bus, time, false); + + return (time > 0); +} + +bool onewire_slave_send_bit(OneWireSlave* bus, bool value) { + const bool write_zero = !value; + + // wait while bus is low + uint32_t time = OWS_SLOT_MAX; + time = onewire_slave_wait_while_gpio_is(bus, time, false); + if(time == 0) { + bus->error = RESET_IN_PROGRESS; + return false; + } + + // wait while bus is high + time = OWS_MSG_HIGH_TIMEOUT; + time = onewire_slave_wait_while_gpio_is(bus, time, true); + if(time == 0) { + bus->error = AWAIT_TIMESLOT_TIMEOUT_HIGH; + return false; + } + + // choose write time + if(write_zero) { + furi_hal_ibutton_pin_low(); + time = OWS_WRITE_ZERO; + } else { + time = OWS_READ_MAX; + } + + // hold line for ZERO or ONE time + furi_hal_delay_us(time); + furi_hal_ibutton_pin_high(); + + return true; +} + +void onewire_slave_cmd_search_rom(OneWireSlave* bus) { + const uint8_t key_bytes = 8; + uint8_t* key = onewire_device_get_id_p(bus->device); + + for(uint8_t i = 0; i < key_bytes; i++) { + uint8_t key_byte = key[i]; + + for(uint8_t j = 0; j < 8; j++) { + bool bit = (key_byte >> j) & 0x01; + + if(!onewire_slave_send_bit(bus, bit)) return; + if(!onewire_slave_send_bit(bus, !bit)) return; + + onewire_slave_receive_bit(bus); + if(bus->error != NO_ERROR) return; + } + } +} + +bool onewire_slave_receive_and_process_cmd(OneWireSlave* bus) { + uint8_t cmd; + onewire_slave_receive(bus, &cmd, 1); + + if(bus->error == RESET_IN_PROGRESS) return true; + if(bus->error != NO_ERROR) return false; + + switch(cmd) { + case 0xF0: + // SEARCH ROM + onewire_slave_cmd_search_rom(bus); + return true; + + case 0x0F: + case 0x33: + // READ ROM + onewire_device_send_id(bus->device); + return true; + + default: // Unknown command + bus->error = INCORRECT_ONEWIRE_CMD; + } + + if(bus->error == RESET_IN_PROGRESS) return true; + return (bus->error == NO_ERROR); +} + +bool onewire_slave_bus_start(OneWireSlave* bus) { + bool result = true; + + if(bus->device == NULL) { + result = false; + } else { + FURI_CRITICAL_ENTER(); + furi_hal_ibutton_start_drive_in_isr(); + bus->error = NO_ERROR; + + if(onewire_slave_show_presence(bus)) { + // TODO think about multiple command cycles + onewire_slave_receive_and_process_cmd(bus); + result = (bus->error == NO_ERROR || bus->error == INCORRECT_ONEWIRE_CMD); + + } else { + result = false; + } + + furi_hal_ibutton_start_interrupt_in_isr(); + FURI_CRITICAL_EXIT(); + } + + return result; +} + +static void exti_cb(void* context) { + OneWireSlave* bus = context; + + volatile bool input_state = furi_hal_ibutton_pin_get_level(); + static uint32_t pulse_start = 0; + + if(input_state) { + uint32_t pulse_length = (DWT->CYCCNT - pulse_start) / instructions_per_us; + if(pulse_length >= OWS_RESET_MIN) { + if(pulse_length <= OWS_RESET_MAX) { + // reset cycle ok + bool result = onewire_slave_bus_start(bus); + if(result && bus->result_cb != NULL) { + bus->result_cb(bus->result_cb_ctx); + } + } else { + bus->error = VERY_LONG_RESET; + } + } else { + bus->error = VERY_SHORT_RESET; + } + } else { + //FALL event + pulse_start = DWT->CYCCNT; + } +}; + +/*********************** PUBLIC ***********************/ + +OneWireSlave* onewire_slave_alloc() { + OneWireSlave* bus = malloc(sizeof(OneWireSlave)); + bus->error = NO_ERROR; + bus->device = NULL; + bus->result_cb = NULL; + bus->result_cb_ctx = NULL; + return bus; +} + +void onewire_slave_free(OneWireSlave* bus) { + onewire_slave_stop(bus); + free(bus); +} + +void onewire_slave_start(OneWireSlave* bus) { + furi_hal_ibutton_add_interrupt(exti_cb, bus); + furi_hal_ibutton_start_interrupt(); +} + +void onewire_slave_stop(OneWireSlave* bus) { + furi_hal_ibutton_stop(); + furi_hal_ibutton_remove_interrupt(); +} + +void onewire_slave_attach(OneWireSlave* bus, OneWireDevice* device) { + bus->device = device; + onewire_device_attach(device, bus); +} + +void onewire_slave_detach(OneWireSlave* bus) { + if(bus->device != NULL) { + onewire_device_detach(bus->device); + } + bus->device = NULL; +} + +void onewire_slave_set_result_callback( + OneWireSlave* bus, + OneWireSlaveResultCallback result_cb, + void* context) { + bus->result_cb = result_cb; + bus->result_cb_ctx = context; +} + +bool onewire_slave_send(OneWireSlave* bus, const uint8_t* address, const uint8_t data_length) { + uint8_t bytes_sent = 0; + + furi_hal_ibutton_pin_high(); + + // bytes loop + for(; bytes_sent < data_length; ++bytes_sent) { + const uint8_t data_byte = address[bytes_sent]; + + // bit loop + for(uint8_t bit_mask = 0x01; bit_mask != 0; bit_mask <<= 1) { + if(!onewire_slave_send_bit(bus, bit_mask & data_byte)) { + // if we cannot send first bit + if((bit_mask == 0x01) && (bus->error == AWAIT_TIMESLOT_TIMEOUT_HIGH)) + bus->error = FIRST_BIT_OF_BYTE_TIMEOUT; + return false; + } + } + } + return true; +} + +bool onewire_slave_receive(OneWireSlave* bus, uint8_t* data, const uint8_t data_length) { + uint8_t bytes_received = 0; + + furi_hal_ibutton_pin_high(); + + for(; bytes_received < data_length; ++bytes_received) { + uint8_t value = 0; + + for(uint8_t bit_mask = 0x01; bit_mask != 0; bit_mask <<= 1) { + if(onewire_slave_receive_bit(bus)) value |= bit_mask; + } + + data[bytes_received] = value; + } + return (bytes_received != data_length); +} diff --git a/lib/one_wire/one_wire_slave.h b/lib/one_wire/one_wire_slave.h new file mode 100644 index 00000000..82e9f552 --- /dev/null +++ b/lib/one_wire/one_wire_slave.h @@ -0,0 +1,71 @@ +/** + * @file one_wire_slave.h + * + * 1-Wire slave library. Currently it can only emulate ID. + */ + +#pragma once +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct OneWireDevice OneWireDevice; +typedef struct OneWireSlave OneWireSlave; +typedef void (*OneWireSlaveResultCallback)(void* context); + +/** + * Allocate onewire slave + * @param pin + * @return OneWireSlave* + */ +OneWireSlave* onewire_slave_alloc(); + +/** + * Free onewire slave + * @param bus + */ +void onewire_slave_free(OneWireSlave* bus); + +/** + * Start working with the bus + * @param bus + */ +void onewire_slave_start(OneWireSlave* bus); + +/** + * Stop working with the bus + * @param bus + */ +void onewire_slave_stop(OneWireSlave* bus); + +/** + * Attach device for emulation + * @param bus + * @param device + */ +void onewire_slave_attach(OneWireSlave* bus, OneWireDevice* device); + +/** + * Detach device from bus + * @param bus + */ +void onewire_slave_detach(OneWireSlave* bus); + +/** + * Set a callback to report emulation success + * @param bus + * @param result_cb + * @param context + */ +void onewire_slave_set_result_callback( + OneWireSlave* bus, + OneWireSlaveResultCallback result_cb, + void* context); + +#ifdef __cplusplus +} +#endif diff --git a/lib/one_wire/one_wire_slave_i.h b/lib/one_wire/one_wire_slave_i.h new file mode 100644 index 00000000..55e0762e --- /dev/null +++ b/lib/one_wire/one_wire_slave_i.h @@ -0,0 +1,38 @@ +/** + * @file one_wire_slave_i.h + * + * 1-Wire slave library, internal functions + */ + +#pragma once +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct OneWireDevice OneWireDevice; +typedef struct OneWireSlave OneWireSlave; + +/** + * Send data, called from emulated device + * @param bus + * @param address + * @param data_length + * @return bool + */ +bool onewire_slave_send(OneWireSlave* bus, const uint8_t* address, const uint8_t data_length); + +/** + * Receive data, called from emulated device + * @param bus + * @param data + * @param data_length + * @return bool + */ +bool onewire_slave_receive(OneWireSlave* bus, uint8_t* data, const uint8_t data_length); + +#ifdef __cplusplus +} +#endif diff --git a/lib/one_wire/pulse_protocols/pulse_decoder.c b/lib/one_wire/pulse_protocols/pulse_decoder.c new file mode 100644 index 00000000..e8197a08 --- /dev/null +++ b/lib/one_wire/pulse_protocols/pulse_decoder.c @@ -0,0 +1,66 @@ +#include +#include "pulse_decoder.h" +#include +#include + +#define MAX_PROTOCOL 5 + +struct PulseDecoder { + PulseProtocol* protocols[MAX_PROTOCOL]; +}; + +PulseDecoder* pulse_decoder_alloc() { + PulseDecoder* decoder = malloc(sizeof(PulseDecoder)); + memset(decoder, 0, sizeof(PulseDecoder)); + return decoder; +} + +void pulse_decoder_free(PulseDecoder* reader) { + furi_assert(reader); + free(reader); +} + +void pulse_decoder_add_protocol(PulseDecoder* reader, PulseProtocol* protocol, int32_t index) { + furi_check(index < MAX_PROTOCOL); + furi_check(reader->protocols[index] == NULL); + reader->protocols[index] = protocol; +} + +void pulse_decoder_process_pulse(PulseDecoder* reader, bool polarity, uint32_t length) { + furi_assert(reader); + for(size_t index = 0; index < MAX_PROTOCOL; index++) { + if(reader->protocols[index] != NULL) { + pulse_protocol_process_pulse(reader->protocols[index], polarity, length); + } + } +} + +int32_t pulse_decoder_get_decoded_index(PulseDecoder* reader) { + furi_assert(reader); + int32_t decoded = -1; + for(size_t index = 0; index < MAX_PROTOCOL; index++) { + if(reader->protocols[index] != NULL) { + if(pulse_protocol_decoded(reader->protocols[index])) { + decoded = index; + break; + } + } + } + + return decoded; +} + +void pulse_decoder_reset(PulseDecoder* reader) { + furi_assert(reader); + for(size_t index = 0; index < MAX_PROTOCOL; index++) { + if(reader->protocols[index] != NULL) { + pulse_protocol_reset(reader->protocols[index]); + } + } +} + +void pulse_decoder_get_data(PulseDecoder* reader, int32_t index, uint8_t* data, size_t length) { + furi_assert(reader); + furi_check(reader->protocols[index] != NULL); + pulse_protocol_get_data(reader->protocols[index], data, length); +} diff --git a/lib/one_wire/pulse_protocols/pulse_decoder.h b/lib/one_wire/pulse_protocols/pulse_decoder.h new file mode 100644 index 00000000..4e9f9d22 --- /dev/null +++ b/lib/one_wire/pulse_protocols/pulse_decoder.h @@ -0,0 +1,70 @@ +/** + * @file pulse_decoder.h + * + * Generic pulse protocol decoder library + */ + +#pragma once +#include +#include +#include "pulse_protocol.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct PulseDecoder PulseDecoder; + +/** + * Allocate decoder + * @return PulseDecoder* + */ +PulseDecoder* pulse_decoder_alloc(); + +/** + * Deallocate decoder + * @param decoder + */ +void pulse_decoder_free(PulseDecoder* decoder); + +/** + * Add protocol to decoder + * @param decoder + * @param protocol protocol implementation + * @param index protocol index, should not be repeated + */ +void pulse_decoder_add_protocol(PulseDecoder* decoder, PulseProtocol* protocol, int32_t index); + +/** + * Push and process pulse with decoder + * @param decoder + * @param polarity + * @param length + */ +void pulse_decoder_process_pulse(PulseDecoder* decoder, bool polarity, uint32_t length); + +/** + * Get indec of decoded protocol + * @param decoder + * @return int32_t, -1 if nothing decoded, or index of decoded protocol + */ +int32_t pulse_decoder_get_decoded_index(PulseDecoder* decoder); + +/** + * Reset all protocols in decoder + * @param decoder + */ +void pulse_decoder_reset(PulseDecoder* decoder); + +/** + * Get decoded data from protocol + * @param decoder + * @param index + * @param data + * @param length + */ +void pulse_decoder_get_data(PulseDecoder* decoder, int32_t index, uint8_t* data, size_t length); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/lib/one_wire/pulse_protocols/pulse_glue.c b/lib/one_wire/pulse_protocols/pulse_glue.c new file mode 100644 index 00000000..9cb914db --- /dev/null +++ b/lib/one_wire/pulse_protocols/pulse_glue.c @@ -0,0 +1,55 @@ +#include "pulse_glue.h" + +struct PulseGlue { + int32_t hi_period; + int32_t low_period; + int32_t next_hi_period; +}; + +PulseGlue* pulse_glue_alloc() { + PulseGlue* pulse_glue = malloc(sizeof(PulseGlue)); + pulse_glue_reset(pulse_glue); + return pulse_glue; +} + +void pulse_glue_free(PulseGlue* pulse_glue) { + free(pulse_glue); +} + +void pulse_glue_reset(PulseGlue* pulse_glue) { + pulse_glue->hi_period = 0; + pulse_glue->low_period = 0; + pulse_glue->next_hi_period = 0; +} + +bool pulse_glue_push(PulseGlue* pulse_glue, bool polarity, uint32_t length) { + bool pop_ready = false; + if(polarity) { + if(pulse_glue->low_period == 0) { + // stage 1, accumulate hi period + pulse_glue->hi_period += length; + } else { + // stage 3, accumulate next hi period and be ready for pulse_glue_pop + pulse_glue->next_hi_period = length; + + // data is ready + pop_ready = true; + } + } else { + if(pulse_glue->hi_period != 0) { + // stage 2, accumulate low period + pulse_glue->low_period += length; + } + } + + return pop_ready; +} + +void pulse_glue_pop(PulseGlue* pulse_glue, uint32_t* length, uint32_t* period) { + *length = pulse_glue->hi_period + pulse_glue->low_period; + *period = pulse_glue->hi_period; + + pulse_glue->hi_period = pulse_glue->next_hi_period; + pulse_glue->low_period = 0; + pulse_glue->next_hi_period = 0; +} diff --git a/lib/one_wire/pulse_protocols/pulse_glue.h b/lib/one_wire/pulse_protocols/pulse_glue.h new file mode 100644 index 00000000..aa58f239 --- /dev/null +++ b/lib/one_wire/pulse_protocols/pulse_glue.h @@ -0,0 +1,26 @@ +/** + * @file pulse_glue.h + * + * Simple tool to glue separated pulses to corret + */ +#pragma once +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct PulseGlue PulseGlue; + +PulseGlue* pulse_glue_alloc(); +void pulse_glue_free(PulseGlue* pulse_glue); +void pulse_glue_reset(PulseGlue* pulse_glue); + +bool pulse_glue_push(PulseGlue* pulse_glue, bool polarity, uint32_t length); +void pulse_glue_pop(PulseGlue* pulse_glue, uint32_t* length, uint32_t* period); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/lib/one_wire/pulse_protocols/pulse_protocol.c b/lib/one_wire/pulse_protocols/pulse_protocol.c new file mode 100644 index 00000000..ac01ea92 --- /dev/null +++ b/lib/one_wire/pulse_protocols/pulse_protocol.c @@ -0,0 +1,67 @@ +#include "pulse_protocol.h" +#include +#include + +struct PulseProtocol { + void* context; + PulseProtocolPulseCallback pulse_cb; + PulseProtocolResetCallback reset_cb; + PulseProtocolGetDataCallback get_data_cb; + PulseProtocolDecodedCallback decoded_cb; +}; + +PulseProtocol* pulse_protocol_alloc() { + PulseProtocol* protocol = malloc(sizeof(PulseProtocol)); + memset(protocol, 0, sizeof(PulseProtocol)); + return protocol; +} + +void pulse_protocol_set_context(PulseProtocol* protocol, void* context) { + protocol->context = context; +} + +void pulse_protocol_set_pulse_cb(PulseProtocol* protocol, PulseProtocolPulseCallback callback) { + protocol->pulse_cb = callback; +} + +void pulse_protocol_set_reset_cb(PulseProtocol* protocol, PulseProtocolResetCallback callback) { + protocol->reset_cb = callback; +} + +void pulse_protocol_set_get_data_cb(PulseProtocol* protocol, PulseProtocolGetDataCallback callback) { + protocol->get_data_cb = callback; +} + +void pulse_protocol_set_decoded_cb(PulseProtocol* protocol, PulseProtocolDecodedCallback callback) { + protocol->decoded_cb = callback; +} + +void pulse_protocol_free(PulseProtocol* protocol) { + free(protocol); +} + +void pulse_protocol_process_pulse(PulseProtocol* protocol, bool polarity, uint32_t length) { + if(protocol->pulse_cb != NULL) { + protocol->pulse_cb(protocol->context, polarity, length); + } +} + +void pulse_protocol_reset(PulseProtocol* protocol) { + if(protocol->reset_cb != NULL) { + protocol->reset_cb(protocol->context); + } +} + +bool pulse_protocol_decoded(PulseProtocol* protocol) { + bool result = false; + if(protocol->decoded_cb != NULL) { + result = protocol->decoded_cb(protocol->context); + } + return result; +} + +void pulse_protocol_get_data(PulseProtocol* protocol, uint8_t* data, size_t length) { + if(protocol->get_data_cb != NULL) { + protocol->get_data_cb(protocol->context, data, length); + } +} \ No newline at end of file diff --git a/lib/one_wire/pulse_protocols/pulse_protocol.h b/lib/one_wire/pulse_protocols/pulse_protocol.h new file mode 100644 index 00000000..01bc14a1 --- /dev/null +++ b/lib/one_wire/pulse_protocols/pulse_protocol.h @@ -0,0 +1,122 @@ +/** + * @file pulse_protocol.h + * + * Generic pulse protocol decoder library, protocol interface + */ + +#pragma once +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Anonymous PulseProtocol struct + */ +typedef struct PulseProtocol PulseProtocol; + +/** + * Process pulse callback + */ +typedef void (*PulseProtocolPulseCallback)(void* context, bool polarity, uint32_t length); + +/** + * Reset protocol callback + */ +typedef void (*PulseProtocolResetCallback)(void* context); + +/** + * Get decoded data callback + */ +typedef void (*PulseProtocolGetDataCallback)(void* context, uint8_t* data, size_t length); + +/** + * Is protocol decoded callback + */ +typedef bool (*PulseProtocolDecodedCallback)(void* context); + +/** + * Allocate protocol + * @return PulseProtocol* + */ +PulseProtocol* pulse_protocol_alloc(); + +/** + * Deallocate protocol + * @param protocol + */ +void pulse_protocol_free(PulseProtocol* protocol); + +/** + * Set context for callbacks + * @param protocol + * @param context + */ +void pulse_protocol_set_context(PulseProtocol* protocol, void* context); + +/** + * Set "Process pulse" callback. Called from the decoder when a new pulse is received. + * @param protocol + * @param callback + */ +void pulse_protocol_set_pulse_cb(PulseProtocol* protocol, PulseProtocolPulseCallback callback); + +/** + * Set "Reset protocol" callback. Called from the decoder when the decoder is reset. + * @param protocol + * @param callback + */ +void pulse_protocol_set_reset_cb(PulseProtocol* protocol, PulseProtocolResetCallback callback); + +/** + * Set "Get decoded data" callback. Called from the decoder when the decoder wants to get decoded data. + * @param protocol + * @param callback + */ +void pulse_protocol_set_get_data_cb(PulseProtocol* protocol, PulseProtocolGetDataCallback callback); + +/** + * Set "Is protocol decoded" callback. Called from the decoder when the decoder wants to know if a protocol has been decoded. + * @param protocol + * @param callback + */ +void pulse_protocol_set_decoded_cb(PulseProtocol* protocol, PulseProtocolDecodedCallback callback); + +/** + * Part of decoder interface. + * @param protocol + * @param polarity + * @param length + */ +void pulse_protocol_process_pulse(PulseProtocol* protocol, bool polarity, uint32_t length); + +/** + * Part of decoder interface. + * @param protocol + * @return true + * @return false + */ +bool pulse_protocol_decoded(PulseProtocol* protocol); + +/** + * Part of decoder interface. + * @param protocol + * @return true + * @return false + */ +void pulse_protocol_get_data(PulseProtocol* protocol, uint8_t* data, size_t length); + +/** + * Part of decoder interface. + * @param protocol + * @return true + * @return false + */ +void pulse_protocol_reset(PulseProtocol* protocol); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/lib/onewire/maxim_crc.cpp b/lib/onewire/maxim_crc.cpp deleted file mode 100644 index f56d84dc..00000000 --- a/lib/onewire/maxim_crc.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "maxim_crc.h" - -uint8_t maxim_crc8(const uint8_t* data, const uint8_t data_size, const uint8_t crc_init) { - uint8_t crc = crc_init; - - for(uint8_t index = 0; index < data_size; ++index) { - uint8_t input_byte = data[index]; - for(uint8_t bit_position = 0; bit_position < 8; ++bit_position) { - const uint8_t mix = (crc ^ input_byte) & static_cast(0x01); - crc >>= 1; - if(mix != 0) crc ^= 0x8C; - input_byte >>= 1; - } - } - return crc; -} - -uint16_t maxim_crc16(const uint8_t* address, const uint8_t length, const uint16_t init) { - uint16_t crc = init; - - static const uint8_t odd_parity[16] = {0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0}; - - for(uint8_t i = 0; i < length; ++i) { - uint16_t cdata = address[i]; - cdata = (cdata ^ crc) & static_cast(0xff); - crc >>= 8; - - if((odd_parity[cdata & 0x0F] ^ odd_parity[cdata >> 4]) != 0) crc ^= 0xC001; - - cdata <<= 6; - crc ^= cdata; - cdata <<= 1; - crc ^= cdata; - } - - return crc; -} - -uint16_t maxim_crc16(uint8_t value, uint16_t crc) { - static const uint8_t odd_parity[16] = {0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0}; - value = (value ^ static_cast(crc)); - crc >>= 8; - if((odd_parity[value & 0x0F] ^ odd_parity[value >> 4]) != 0) crc ^= 0xC001; - uint16_t cdata = (static_cast(value) << 6); - crc ^= cdata; - crc ^= (static_cast(cdata) << 1); - return crc; -} \ No newline at end of file diff --git a/lib/onewire/maxim_crc.h b/lib/onewire/maxim_crc.h deleted file mode 100644 index 1a9569fa..00000000 --- a/lib/onewire/maxim_crc.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once -#include - -uint8_t maxim_crc8(const uint8_t* data, const uint8_t data_size, const uint8_t crc_init = 0); -uint16_t maxim_crc16(const uint8_t* address, const uint8_t length, const uint16_t init = 0); -uint16_t maxim_crc16(uint8_t value, uint16_t crc); \ No newline at end of file diff --git a/lib/onewire/one_wire_device.cpp b/lib/onewire/one_wire_device.cpp deleted file mode 100644 index d1e6319a..00000000 --- a/lib/onewire/one_wire_device.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "one_wire_device.h" - -OneWireDevice::OneWireDevice( - uint8_t id_1, - uint8_t id_2, - uint8_t id_3, - uint8_t id_4, - uint8_t id_5, - uint8_t id_6, - uint8_t id_7) { - id_storage[0] = id_1; - id_storage[1] = id_2; - id_storage[2] = id_3; - id_storage[3] = id_4; - id_storage[4] = id_5; - id_storage[5] = id_6; - id_storage[6] = id_7; - id_storage[7] = maxim_crc8(id_storage, 7); -} - -OneWireDevice::~OneWireDevice() { - if(bus != nullptr) { - bus->deattach(); - } -} - -void OneWireDevice::send_id() const { - if(bus != nullptr) { - bus->send(id_storage, 8); - } -} - -void OneWireDevice::attach(OneWireSlave* _bus) { - bus = _bus; -} - -void OneWireDevice::deattach(void) { - bus = nullptr; -} diff --git a/lib/onewire/one_wire_device.h b/lib/onewire/one_wire_device.h deleted file mode 100644 index 0aff3d28..00000000 --- a/lib/onewire/one_wire_device.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once -#include -#include "maxim_crc.h" -#include "one_wire_slave.h" - -class OneWireDevice { -public: - OneWireDevice( - uint8_t id_1, - uint8_t id_2, - uint8_t id_3, - uint8_t id_4, - uint8_t id_5, - uint8_t id_6, - uint8_t id_7); - - ~OneWireDevice(); - - uint8_t id_storage[8]; - - void send_id() const; - - OneWireSlave* bus = nullptr; - void attach(OneWireSlave* _bus); - void deattach(void); -}; \ No newline at end of file diff --git a/lib/onewire/one_wire_device_ds_1990.cpp b/lib/onewire/one_wire_device_ds_1990.cpp deleted file mode 100644 index cde6134c..00000000 --- a/lib/onewire/one_wire_device_ds_1990.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include "one_wire_device_ds_1990.h" - -DS1990::DS1990( - uint8_t ID1, - uint8_t ID2, - uint8_t ID3, - uint8_t ID4, - uint8_t ID5, - uint8_t ID6, - uint8_t ID7) - : OneWireDevice(ID1, ID2, ID3, ID4, ID5, ID6, ID7) { -} \ No newline at end of file diff --git a/lib/onewire/one_wire_device_ds_1990.h b/lib/onewire/one_wire_device_ds_1990.h deleted file mode 100644 index bf3eb411..00000000 --- a/lib/onewire/one_wire_device_ds_1990.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once -#include "one_wire_device.h" - -class DS1990 : public OneWireDevice { -public: - static constexpr uint8_t family_code{0x01}; - - DS1990( - uint8_t ID1, - uint8_t ID2, - uint8_t ID3, - uint8_t ID4, - uint8_t ID5, - uint8_t ID6, - uint8_t ID7); -}; \ No newline at end of file diff --git a/lib/onewire/one_wire_master.cpp b/lib/onewire/one_wire_master.cpp deleted file mode 100644 index dcea651c..00000000 --- a/lib/onewire/one_wire_master.cpp +++ /dev/null @@ -1,247 +0,0 @@ -#include "one_wire_master.h" -#include "one_wire_timings.h" - -OneWireMaster::OneWireMaster(const GpioPin* one_wire_gpio) { - gpio = one_wire_gpio; - reset_search(); -} - -OneWireMaster::~OneWireMaster() { - stop(); -} - -void OneWireMaster::start(void) { - hal_gpio_init(gpio, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow); -} - -void OneWireMaster::stop(void) { - hal_gpio_init(gpio, GpioModeAnalog, GpioPullNo, GpioSpeedLow); -} - -void OneWireMaster::reset_search() { - // reset the search state - last_discrepancy = 0; - last_device_flag = false; - last_family_discrepancy = 0; - for(int i = 7;; i--) { - saved_rom[i] = 0; - if(i == 0) break; - } -} - -void OneWireMaster::target_search(uint8_t family_code) { - // set the search state to find SearchFamily type devices - saved_rom[0] = family_code; - for(uint8_t i = 1; i < 8; i++) saved_rom[i] = 0; - last_discrepancy = 64; - last_family_discrepancy = 0; - last_device_flag = false; -} - -uint8_t OneWireMaster::search(uint8_t* newAddr, bool search_mode) { - uint8_t id_bit_number; - uint8_t last_zero, rom_byte_number, search_result; - uint8_t id_bit, cmp_id_bit; - - unsigned char rom_byte_mask, search_direction; - - // initialize for search - id_bit_number = 1; - last_zero = 0; - rom_byte_number = 0; - rom_byte_mask = 1; - search_result = 0; - - // if the last call was not the last one - if(!last_device_flag) { - // 1-Wire reset - if(!reset()) { - // reset the search - last_discrepancy = 0; - last_device_flag = false; - last_family_discrepancy = 0; - return false; - } - - // issue the search command - if(search_mode == true) { - write(0xF0); // NORMAL SEARCH - } else { - write(0xEC); // CONDITIONAL SEARCH - } - - // loop to do the search - do { - // read a bit and its complement - id_bit = read_bit(); - cmp_id_bit = read_bit(); - - // check for no devices on 1-wire - if((id_bit == 1) && (cmp_id_bit == 1)) - break; - else { - // all devices coupled have 0 or 1 - if(id_bit != cmp_id_bit) - search_direction = id_bit; // bit write value for search - else { - // if this discrepancy if before the Last Discrepancy - // on a previous next then pick the same as last time - if(id_bit_number < last_discrepancy) - search_direction = ((saved_rom[rom_byte_number] & rom_byte_mask) > 0); - else - // if equal to last pick 1, if not then pick 0 - search_direction = (id_bit_number == last_discrepancy); - - // if 0 was picked then record its position in LastZero - if(search_direction == 0) { - last_zero = id_bit_number; - - // check for Last discrepancy in family - if(last_zero < 9) last_family_discrepancy = last_zero; - } - } - - // set or clear the bit in the ROM byte rom_byte_number - // with mask rom_byte_mask - if(search_direction == 1) - saved_rom[rom_byte_number] |= rom_byte_mask; - else - saved_rom[rom_byte_number] &= ~rom_byte_mask; - - // serial number search direction write bit - write_bit(search_direction); - - // increment the byte counter id_bit_number - // and shift the mask rom_byte_mask - id_bit_number++; - rom_byte_mask <<= 1; - - // if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask - if(rom_byte_mask == 0) { - rom_byte_number++; - rom_byte_mask = 1; - } - } - } while(rom_byte_number < 8); // loop until through all ROM bytes 0-7 - - // if the search was successful then - if(!(id_bit_number < 65)) { - // search successful so set last_Discrepancy, last_device_flag, search_result - last_discrepancy = last_zero; - - // check for last device - if(last_discrepancy == 0) last_device_flag = true; - - search_result = true; - } - } - - // if no device found then reset counters so next 'search' will be like a first - if(!search_result || !saved_rom[0]) { - last_discrepancy = 0; - last_device_flag = false; - last_family_discrepancy = 0; - search_result = false; - } else { - for(int i = 0; i < 8; i++) newAddr[i] = saved_rom[i]; - } - - return search_result; -} - -bool OneWireMaster::reset(void) { - uint8_t r; - uint8_t retries = 125; - - // wait until the gpio is high - hal_gpio_write(gpio, true); - do { - if(--retries == 0) return 0; - delay_us(2); - } while(!hal_gpio_read(gpio)); - - // pre delay - delay_us(OneWireTiming::RESET_DELAY_PRE); - - // drive low - hal_gpio_write(gpio, false); - delay_us(OneWireTiming::RESET_DRIVE); - - // release - hal_gpio_write(gpio, true); - delay_us(OneWireTiming::RESET_RELEASE); - - // read and post delay - r = !hal_gpio_read(gpio); - delay_us(OneWireTiming::RESET_DELAY_POST); - - return r; -} - -bool OneWireMaster::read_bit(void) { - bool result; - - // drive low - hal_gpio_write(gpio, false); - delay_us(OneWireTiming::READ_DRIVE); - - // release - hal_gpio_write(gpio, true); - delay_us(OneWireTiming::READ_RELEASE); - - // read and post delay - result = hal_gpio_read(gpio); - delay_us(OneWireTiming::READ_DELAY_POST); - - return result; -} - -void OneWireMaster::write_bit(bool value) { - if(value) { - // drive low - hal_gpio_write(gpio, false); - delay_us(OneWireTiming::WRITE_1_DRIVE); - - // release - hal_gpio_write(gpio, true); - delay_us(OneWireTiming::WRITE_1_RELEASE); - } else { - // drive low - hal_gpio_write(gpio, false); - delay_us(OneWireTiming::WRITE_0_DRIVE); - - // release - hal_gpio_write(gpio, true); - delay_us(OneWireTiming::WRITE_0_RELEASE); - } -} - -uint8_t OneWireMaster::read(void) { - uint8_t result = 0; - - for(uint8_t bitMask = 0x01; bitMask; bitMask <<= 1) { - if(read_bit()) { - result |= bitMask; - } - } - - return result; -} - -void OneWireMaster::read_bytes(uint8_t* buffer, uint16_t count) { - for(uint16_t i = 0; i < count; i++) { - buffer[i] = read(); - } -} - -void OneWireMaster::write(uint8_t value) { - uint8_t bitMask; - - for(bitMask = 0x01; bitMask; bitMask <<= 1) { - write_bit((bitMask & value) ? 1 : 0); - } -} - -void OneWireMaster::skip(void) { - write(0xCC); -} diff --git a/lib/onewire/one_wire_master.h b/lib/onewire/one_wire_master.h deleted file mode 100644 index 1f00567d..00000000 --- a/lib/onewire/one_wire_master.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once -#include -#include -#include "one_wire_timings.h" - -class OneWireMaster { -private: - const GpioPin* gpio; - - // global search state - unsigned char saved_rom[8]; - uint8_t last_discrepancy; - uint8_t last_family_discrepancy; - bool last_device_flag; - -public: - OneWireMaster(const GpioPin* one_wire_gpio); - ~OneWireMaster(); - bool reset(void); - bool read_bit(void); - uint8_t read(void); - void read_bytes(uint8_t* buf, uint16_t count); - void write_bit(bool value); - void write(uint8_t value); - void skip(void); - void start(void); - void stop(void); - - void reset_search(); - void target_search(uint8_t family_code); - uint8_t search(uint8_t* newAddr, bool search_mode = true); -}; \ No newline at end of file diff --git a/lib/onewire/one_wire_slave.cpp b/lib/onewire/one_wire_slave.cpp deleted file mode 100644 index c0f50caa..00000000 --- a/lib/onewire/one_wire_slave.cpp +++ /dev/null @@ -1,308 +0,0 @@ -#include "one_wire_slave.h" -#include "callback-connector.h" -#include "main.h" -#include "one_wire_device.h" - -#define OWET OneWireEmulateTiming - -void OneWireSlave::start(void) { - // add exti interrupt - hal_gpio_add_int_callback(one_wire_pin_record, exti_cb, this); - - // init gpio - hal_gpio_init(one_wire_pin_record, GpioModeInterruptRiseFall, GpioPullNo, GpioSpeedLow); - pin_set_float(); - - // init instructions per us count - __instructions_per_us = (SystemCoreClock / 1000000.0f); -} - -void OneWireSlave::stop(void) { - // deinit gpio - hal_gpio_init(one_wire_pin_record, GpioModeInput, GpioPullNo, GpioSpeedLow); - // remove exti interrupt - hal_gpio_remove_int_callback(one_wire_pin_record); - - // deattach devices - deattach(); -} - -OneWireSlave::OneWireSlave(const GpioPin* pin) { - one_wire_pin_record = pin; - exti_cb = cbc::obtain_connector(this, &OneWireSlave::exti_callback); -} - -OneWireSlave::~OneWireSlave() { - stop(); -} - -void OneWireSlave::attach(OneWireDevice* attached_device) { - device = attached_device; - device->attach(this); -} - -void OneWireSlave::deattach(void) { - if(device != nullptr) { - device->deattach(); - } - device = nullptr; -} - -void OneWireSlave::set_result_callback(OneWireSlaveResultCallback result_cb, void* ctx) { - this->result_cb = result_cb; - this->result_cb_ctx = ctx; -} - -void OneWireSlave::pin_set_float() { - hal_gpio_write(one_wire_pin_record, true); -} - -void OneWireSlave::pin_set_low() { - hal_gpio_write(one_wire_pin_record, false); -} - -void OneWireSlave::pin_init_interrupt_in_isr_ctx(void) { - hal_gpio_init(one_wire_pin_record, GpioModeInterruptRiseFall, GpioPullNo, GpioSpeedLow); - __HAL_GPIO_EXTI_CLEAR_IT(one_wire_pin_record->pin); -} - -void OneWireSlave::pin_init_opendrain_in_isr_ctx(void) { - hal_gpio_init(one_wire_pin_record, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow); - __HAL_GPIO_EXTI_CLEAR_IT(one_wire_pin_record->pin); -} - -OneWiteTimeType OneWireSlave::wait_while_gpio_is(OneWiteTimeType time, const bool pin_value) { - uint32_t start = DWT->CYCCNT; - uint32_t time_ticks = time * __instructions_per_us; - uint32_t time_captured; - - do { - time_captured = DWT->CYCCNT; - if(hal_gpio_read(one_wire_pin_record) != pin_value) { - OneWiteTimeType remaining_time = time_ticks - (time_captured - start); - remaining_time /= __instructions_per_us; - return remaining_time; - } - } while((time_captured - start) < time_ticks); - - return 0; -} - -bool OneWireSlave::show_presence(void) { - // wait while master delay presence check - wait_while_gpio_is(OWET::PRESENCE_TIMEOUT, true); - - // show presence - pin_set_low(); - delay_us(OWET::PRESENCE_MIN); - pin_set_float(); - - // somebody also can show presence - const OneWiteTimeType wait_low_time = OWET::PRESENCE_MAX - OWET::PRESENCE_MIN; - - // so we will wait - if(wait_while_gpio_is(wait_low_time, false) == 0) { - error = OneWireSlaveError::PRESENCE_LOW_ON_LINE; - return false; - } - - return true; -} - -bool OneWireSlave::receive_bit(void) { - // wait while bus is low - OneWiteTimeType time = OWET::SLOT_MAX; - time = wait_while_gpio_is(time, false); - if(time == 0) { - error = OneWireSlaveError::RESET_IN_PROGRESS; - return false; - } - - // wait while bus is high - time = OWET::MSG_HIGH_TIMEOUT; - time = wait_while_gpio_is(time, true); - if(time == 0) { - error = OneWireSlaveError::AWAIT_TIMESLOT_TIMEOUT_HIGH; - return false; - } - - // wait a time of zero - time = OWET::READ_MIN; - time = wait_while_gpio_is(time, false); - - return (time > 0); -} - -bool OneWireSlave::send_bit(bool value) { - const bool write_zero = !value; - - // wait while bus is low - OneWiteTimeType time = OWET::SLOT_MAX; - time = wait_while_gpio_is(time, false); - if(time == 0) { - error = OneWireSlaveError::RESET_IN_PROGRESS; - return false; - } - - // wait while bus is high - time = OWET::MSG_HIGH_TIMEOUT; - time = wait_while_gpio_is(time, true); - if(time == 0) { - error = OneWireSlaveError::AWAIT_TIMESLOT_TIMEOUT_HIGH; - return false; - } - - // choose write time - if(write_zero) { - pin_set_low(); - time = OWET::WRITE_ZERO; - } else { - time = OWET::READ_MAX; - } - - // hold line for ZERO or ONE time - delay_us(time); - pin_set_float(); - - return true; -} - -bool OneWireSlave::send(const uint8_t* address, const uint8_t data_length) { - uint8_t bytes_sent = 0; - - pin_set_float(); - - // bytes loop - for(; bytes_sent < data_length; ++bytes_sent) { - const uint8_t data_byte = address[bytes_sent]; - - // bit loop - for(uint8_t bit_mask = 0x01; bit_mask != 0; bit_mask <<= 1) { - if(!send_bit(static_cast(bit_mask & data_byte))) { - // if we cannot send first bit - if((bit_mask == 0x01) && (error == OneWireSlaveError::AWAIT_TIMESLOT_TIMEOUT_HIGH)) - error = OneWireSlaveError::FIRST_BIT_OF_BYTE_TIMEOUT; - return false; - } - } - } - return true; -} - -bool OneWireSlave::receive(uint8_t* data, const uint8_t data_length) { - uint8_t bytes_received = 0; - - pin_set_float(); - - for(; bytes_received < data_length; ++bytes_received) { - uint8_t value = 0; - - for(uint8_t bit_mask = 0x01; bit_mask != 0; bit_mask <<= 1) { - if(receive_bit()) value |= bit_mask; - } - - data[bytes_received] = value; - } - return (bytes_received != data_length); -} - -void OneWireSlave::cmd_search_rom(void) { - const uint8_t key_bytes = 8; - uint8_t* key = device->id_storage; - - for(uint8_t i = 0; i < key_bytes; i++) { - uint8_t key_byte = key[i]; - - for(uint8_t j = 0; j < 8; j++) { - bool bit = (key_byte >> j) & 0x01; - - if(!send_bit(bit)) return; - if(!send_bit(!bit)) return; - - receive_bit(); - if(error != OneWireSlaveError::NO_ERROR) return; - } - } -} - -bool OneWireSlave::receive_and_process_cmd(void) { - uint8_t cmd; - receive(&cmd, 1); - - if(error == OneWireSlaveError::RESET_IN_PROGRESS) return true; - if(error != OneWireSlaveError::NO_ERROR) return false; - - switch(cmd) { - case 0xF0: - // SEARCH ROM - cmd_search_rom(); - return true; - - case 0x0F: - case 0x33: - // READ ROM - device->send_id(); - return true; - - default: // Unknown command - error = OneWireSlaveError::INCORRECT_ONEWIRE_CMD; - } - - if(error == OneWireSlaveError::RESET_IN_PROGRESS) return true; - return (error == OneWireSlaveError::NO_ERROR); -} - -bool OneWireSlave::bus_start(void) { - bool result = true; - - if(device == nullptr) { - result = false; - } else { - FURI_CRITICAL_ENTER(); - pin_init_opendrain_in_isr_ctx(); - error = OneWireSlaveError::NO_ERROR; - - if(show_presence()) { - // TODO think about multiple command cycles - receive_and_process_cmd(); - result = - (error == OneWireSlaveError::NO_ERROR || - error == OneWireSlaveError::INCORRECT_ONEWIRE_CMD); - - } else { - result = false; - } - - pin_init_interrupt_in_isr_ctx(); - FURI_CRITICAL_EXIT(); - } - - return result; -} - -void OneWireSlave::exti_callback(void* _ctx) { - OneWireSlave* _this = static_cast(_ctx); - - volatile bool input_state = hal_gpio_read(_this->one_wire_pin_record); - static uint32_t pulse_start = 0; - - if(input_state) { - uint32_t pulse_length = (DWT->CYCCNT - pulse_start) / __instructions_per_us; - if(pulse_length >= OWET::RESET_MIN) { - if(pulse_length <= OWET::RESET_MAX) { - // reset cycle ok - bool result = _this->bus_start(); - if(result && _this->result_cb != nullptr) { - _this->result_cb(result, _this->result_cb_ctx); - } - } else { - error = OneWireSlaveError::VERY_LONG_RESET; - } - } else { - error = OneWireSlaveError::VERY_SHORT_RESET; - } - } else { - //FALL event - pulse_start = DWT->CYCCNT; - } -} diff --git a/lib/onewire/one_wire_slave.h b/lib/onewire/one_wire_slave.h deleted file mode 100644 index 2773d137..00000000 --- a/lib/onewire/one_wire_slave.h +++ /dev/null @@ -1,75 +0,0 @@ -#pragma once -#include -#include -#include "one_wire_timings.h" - -class OneWireDevice; -typedef void (*OneWireSlaveResultCallback)(bool success, void* ctx); - -class OneWireSlave { -private: - enum class OneWireSlaveError : uint8_t { - NO_ERROR = 0, - READ_TIMESLOT_TIMEOUT, - WRITE_TIMESLOT_TIMEOUT, - WAIT_RESET_TIMEOUT, - VERY_LONG_RESET, - VERY_SHORT_RESET, - PRESENCE_LOW_ON_LINE, - READ_TIMESLOT_TIMEOUT_LOW, - AWAIT_TIMESLOT_TIMEOUT_HIGH, - PRESENCE_HIGH_ON_LINE, - INCORRECT_ONEWIRE_CMD, - INCORRECT_SLAVE_USAGE, - TRIED_INCORRECT_WRITE, - FIRST_TIMESLOT_TIMEOUT, - FIRST_BIT_OF_BYTE_TIMEOUT, - RESET_IN_PROGRESS - }; - - const GpioPin* one_wire_pin_record; - - // exti callback and its pointer - void exti_callback(void* _ctx); - void (*exti_cb)(void* _ctx); - - uint32_t __instructions_per_us; - - OneWireSlaveError error; - OneWireDevice* device = nullptr; - - bool bus_start(void); - - void pin_set_float(void); - void pin_set_low(void); - void pin_init_interrupt_in_isr_ctx(void); - void pin_init_opendrain_in_isr_ctx(void); - - OneWiteTimeType wait_while_gpio_is(OneWiteTimeType time, const bool pin_value); - - bool show_presence(void); - bool receive_and_process_cmd(void); - - bool receive_bit(void); - bool send_bit(bool value); - - void cmd_search_rom(void); - - OneWireSlaveResultCallback result_cb = nullptr; - void* result_cb_ctx = nullptr; - -public: - void start(void); - void stop(void); - - bool send(const uint8_t* address, const uint8_t data_length); - bool receive(uint8_t* data, const uint8_t data_length = 1); - - OneWireSlave(const GpioPin* pin); - ~OneWireSlave(); - - void attach(OneWireDevice* device); - void deattach(void); - - void set_result_callback(OneWireSlaveResultCallback result_cb, void* ctx); -}; \ No newline at end of file diff --git a/lib/onewire/one_wire_timings.cpp b/lib/onewire/one_wire_timings.cpp deleted file mode 100644 index 23a4a934..00000000 --- a/lib/onewire/one_wire_timings.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "one_wire_timings.h" - -// fix pre C++17 "undefined reference" errors -constexpr const OneWiteTimeType OneWireEmulateTiming::RESET_MIN; -constexpr const OneWiteTimeType OneWireEmulateTiming::RESET_MAX; - -constexpr const OneWiteTimeType OneWireEmulateTiming::PRESENCE_TIMEOUT; -constexpr const OneWiteTimeType OneWireEmulateTiming::PRESENCE_MIN; -constexpr const OneWiteTimeType OneWireEmulateTiming::PRESENCE_MAX; - -constexpr const OneWiteTimeType OneWireEmulateTiming::MSG_HIGH_TIMEOUT; -constexpr const OneWiteTimeType OneWireEmulateTiming::SLOT_MAX; - -constexpr const OneWiteTimeType OneWireEmulateTiming::READ_MIN; -constexpr const OneWiteTimeType OneWireEmulateTiming::READ_MAX; -constexpr const OneWiteTimeType OneWireEmulateTiming::WRITE_ZERO; diff --git a/lib/onewire/one_wire_timings.h b/lib/onewire/one_wire_timings.h deleted file mode 100644 index 19aa9e03..00000000 --- a/lib/onewire/one_wire_timings.h +++ /dev/null @@ -1,53 +0,0 @@ -#pragma once -#include - -class __OneWireTiming { -public: - constexpr static const uint16_t TIMING_A = 9; - constexpr static const uint16_t TIMING_B = 64; - constexpr static const uint16_t TIMING_C = 64; - constexpr static const uint16_t TIMING_D = 14; - constexpr static const uint16_t TIMING_E = 9; - constexpr static const uint16_t TIMING_F = 55; - constexpr static const uint16_t TIMING_G = 0; - constexpr static const uint16_t TIMING_H = 480; - constexpr static const uint16_t TIMING_I = 70; - constexpr static const uint16_t TIMING_J = 410; -}; - -class OneWireTiming { -public: - constexpr static const uint16_t WRITE_1_DRIVE = __OneWireTiming::TIMING_A; - constexpr static const uint16_t WRITE_1_RELEASE = __OneWireTiming::TIMING_B; - - constexpr static const uint16_t WRITE_0_DRIVE = __OneWireTiming::TIMING_C; - constexpr static const uint16_t WRITE_0_RELEASE = __OneWireTiming::TIMING_D; - - constexpr static const uint16_t READ_DRIVE = 3; - constexpr static const uint16_t READ_RELEASE = __OneWireTiming::TIMING_E; - constexpr static const uint16_t READ_DELAY_POST = __OneWireTiming::TIMING_F; - - constexpr static const uint16_t RESET_DELAY_PRE = __OneWireTiming::TIMING_G; - constexpr static const uint16_t RESET_DRIVE = __OneWireTiming::TIMING_H; - constexpr static const uint16_t RESET_RELEASE = __OneWireTiming::TIMING_I; - constexpr static const uint16_t RESET_DELAY_POST = __OneWireTiming::TIMING_J; -}; - -typedef uint32_t OneWiteTimeType; - -class OneWireEmulateTiming { -public: - constexpr static const OneWiteTimeType RESET_MIN = 270; - constexpr static const OneWiteTimeType RESET_MAX = 960; - - constexpr static const OneWiteTimeType PRESENCE_TIMEOUT = 20; - constexpr static const OneWiteTimeType PRESENCE_MIN = 100; - constexpr static const OneWiteTimeType PRESENCE_MAX = 480; - - constexpr static const OneWiteTimeType MSG_HIGH_TIMEOUT = 15000; - constexpr static const OneWiteTimeType SLOT_MAX = 135; - - constexpr static const OneWiteTimeType READ_MIN = 20; - constexpr static const OneWiteTimeType READ_MAX = 60; - constexpr static const OneWiteTimeType WRITE_ZERO = 30; -}; \ No newline at end of file diff --git a/lib/subghz/protocols/princeton_for_testing.c b/lib/subghz/protocols/princeton_for_testing.c index 0aca55e4..1c4552f4 100644 --- a/lib/subghz/protocols/princeton_for_testing.c +++ b/lib/subghz/protocols/princeton_for_testing.c @@ -75,8 +75,9 @@ void subghz_encoder_princeton_for_testing_set( instance->count_key = instance->count_key_package + 3; - if((millis() - instance->time_stop) < instance->timeout) { - instance->time_stop = (instance->timeout - (millis() - instance->time_stop)) * 1000; + if((furi_hal_get_tick() - instance->time_stop) < instance->timeout) { + instance->time_stop = + (instance->timeout - (furi_hal_get_tick() - instance->time_stop)) * 1000; } else { instance->time_stop = 0; } diff --git a/lib/subghz/subghz_tx_rx_worker.c b/lib/subghz/subghz_tx_rx_worker.c index f137b5fe..aad28b88 100644 --- a/lib/subghz/subghz_tx_rx_worker.c +++ b/lib/subghz/subghz_tx_rx_worker.c @@ -71,7 +71,7 @@ bool subghz_tx_rx_worker_rx(SubGhzTxRxWorker* instance, uint8_t* data, uint8_t* osDelay(1); } //waiting for reception to complete - while(hal_gpio_read(&gpio_cc1101_g0)) { + while(furi_hal_gpio_read(&gpio_cc1101_g0)) { osDelay(1); if(!--timeout) { FURI_LOG_W(TAG, "RX cc1101_g0 timeout"); @@ -102,14 +102,14 @@ void subghz_tx_rx_worker_tx(SubGhzTxRxWorker* instance, uint8_t* data, size_t si furi_hal_subghz_write_packet(data, size); furi_hal_subghz_tx(); //start send instance->status = SubGhzTxRxWorkerStatusTx; - while(!hal_gpio_read(&gpio_cc1101_g0)) { // Wait for GDO0 to be set -> sync transmitted + while(!furi_hal_gpio_read(&gpio_cc1101_g0)) { // Wait for GDO0 to be set -> sync transmitted osDelay(1); if(!--timeout) { FURI_LOG_W(TAG, "TX !cc1101_g0 timeout"); break; } } - while(hal_gpio_read(&gpio_cc1101_g0)) { // Wait for GDO0 to be cleared -> end of packet + while(furi_hal_gpio_read(&gpio_cc1101_g0)) { // Wait for GDO0 to be cleared -> end of packet osDelay(1); if(!--timeout) { FURI_LOG_W(TAG, "TX cc1101_g0 timeout"); @@ -132,7 +132,7 @@ static int32_t subghz_tx_rx_worker_thread(void* context) { furi_hal_subghz_idle(); furi_hal_subghz_load_preset(FuriHalSubGhzPresetGFSK9_99KbAsync); //furi_hal_subghz_load_preset(FuriHalSubGhzPresetMSK99_97KbAsync); - hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); furi_hal_subghz_set_frequency_and_path(instance->frequency); furi_hal_subghz_flush_rx(); diff --git a/lib/u8g2/u8g2_glue.c b/lib/u8g2/u8g2_glue.c index 1ee367d8..550a4610 100644 --- a/lib/u8g2/u8g2_glue.c +++ b/lib/u8g2/u8g2_glue.c @@ -8,16 +8,16 @@ uint8_t u8g2_gpio_and_delay_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, vo /* HAL initialization contains all what we need so we can skip this part. */ break; case U8X8_MSG_DELAY_MILLI: - delay(arg_int); + furi_hal_delay_ms(arg_int); break; case U8X8_MSG_DELAY_10MICRO: - delay_us(10); + furi_hal_delay_us(10); break; case U8X8_MSG_DELAY_100NANO: asm("nop"); break; case U8X8_MSG_GPIO_RESET: - hal_gpio_write(&gpio_display_rst, arg_int); + furi_hal_gpio_write(&gpio_display_rst, arg_int); break; default: return 0; @@ -32,7 +32,7 @@ uint8_t u8x8_hw_spi_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, void* arg_ furi_hal_spi_bus_tx(&furi_hal_spi_bus_handle_display, (uint8_t*)arg_ptr, arg_int, 10000); break; case U8X8_MSG_BYTE_SET_DC: - hal_gpio_write(&gpio_display_di, arg_int); + furi_hal_gpio_write(&gpio_display_di, arg_int); break; case U8X8_MSG_BYTE_INIT: break;