2023-04-13 22:45:31 +00:00
|
|
|
#include "../wiegand.h"
|
2023-04-07 03:46:18 +00:00
|
|
|
|
2023-11-21 21:08:54 +00:00
|
|
|
void wiegand_isr_d0(void *context)
|
|
|
|
{
|
2023-04-07 03:46:18 +00:00
|
|
|
UNUSED(context);
|
|
|
|
uint32_t time = DWT->CYCCNT;
|
|
|
|
bool rise = furi_hal_gpio_read(pinD0);
|
|
|
|
|
|
|
|
data[bit_count] = 0;
|
|
|
|
|
2023-11-21 21:08:54 +00:00
|
|
|
if (rise)
|
|
|
|
{
|
2023-04-07 03:46:18 +00:00
|
|
|
data_rise[bit_count] = time;
|
2023-11-21 21:08:54 +00:00
|
|
|
if (bit_count < MAX_BITS)
|
|
|
|
{
|
2023-04-07 03:46:18 +00:00
|
|
|
bit_count++;
|
|
|
|
}
|
2023-11-21 21:08:54 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2023-04-07 03:46:18 +00:00
|
|
|
data_fall[bit_count] = time;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-21 21:08:54 +00:00
|
|
|
void wiegand_isr_d1(void *context)
|
|
|
|
{
|
2023-04-07 03:46:18 +00:00
|
|
|
UNUSED(context);
|
|
|
|
uint32_t time = DWT->CYCCNT;
|
|
|
|
bool rise = furi_hal_gpio_read(pinD1);
|
|
|
|
|
|
|
|
data[bit_count] = 1;
|
|
|
|
|
2023-11-21 21:08:54 +00:00
|
|
|
if (rise)
|
|
|
|
{
|
2023-04-07 03:46:18 +00:00
|
|
|
data_rise[bit_count] = time;
|
2023-11-21 21:08:54 +00:00
|
|
|
if (bit_count < MAX_BITS)
|
|
|
|
{
|
2023-04-07 03:46:18 +00:00
|
|
|
bit_count++;
|
|
|
|
}
|
2023-11-21 21:08:54 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2023-04-07 03:46:18 +00:00
|
|
|
data_fall[bit_count] = time;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-11-21 21:08:54 +00:00
|
|
|
void wiegand_start_read(void *context)
|
|
|
|
{
|
|
|
|
App *app = context;
|
2023-04-07 03:46:18 +00:00
|
|
|
data_saved = false;
|
|
|
|
bit_count = 0;
|
2024-01-23 01:25:44 +00:00
|
|
|
furi_hal_power_enable_otg();
|
2023-04-07 03:46:18 +00:00
|
|
|
furi_hal_gpio_init_simple(pinD0, GpioModeInterruptRiseFall);
|
|
|
|
furi_hal_gpio_init_simple(pinD1, GpioModeInterruptRiseFall);
|
|
|
|
furi_hal_gpio_add_int_callback(pinD0, wiegand_isr_d0, NULL);
|
|
|
|
furi_hal_gpio_add_int_callback(pinD1, wiegand_isr_d1, NULL);
|
|
|
|
furi_timer_start(app->timer, 100);
|
|
|
|
}
|
|
|
|
|
2023-11-21 21:08:54 +00:00
|
|
|
void wiegand_stop_read(void *context)
|
|
|
|
{
|
|
|
|
App *app = context;
|
2023-04-07 03:46:18 +00:00
|
|
|
furi_hal_gpio_remove_int_callback(pinD0);
|
|
|
|
furi_hal_gpio_remove_int_callback(pinD1);
|
|
|
|
furi_hal_gpio_init_simple(pinD0, GpioModeAnalog);
|
|
|
|
furi_hal_gpio_init_simple(pinD1, GpioModeAnalog);
|
|
|
|
furi_timer_stop(app->timer);
|
|
|
|
}
|
|
|
|
|
2023-11-21 21:08:54 +00:00
|
|
|
void wiegand_timer_callback(void *context)
|
|
|
|
{
|
|
|
|
App *app = context;
|
2023-04-07 03:46:18 +00:00
|
|
|
uint32_t duration = DWT->CYCCNT;
|
|
|
|
const uint32_t one_millisecond = 64000;
|
|
|
|
|
2023-11-21 21:08:54 +00:00
|
|
|
if (bit_count == 0)
|
|
|
|
{
|
2023-04-07 03:46:18 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
duration -= data_fall[bit_count - 1];
|
|
|
|
|
|
|
|
FURI_CRITICAL_ENTER();
|
2023-11-21 21:08:54 +00:00
|
|
|
if (duration > 25 * one_millisecond)
|
|
|
|
{
|
|
|
|
if (bit_count == 4 || bit_count == 8 || bit_count == 24 || bit_count == 26 ||
|
|
|
|
bit_count == 32 || bit_count == 34 || bit_count == 35 || bit_count == 36 ||
|
|
|
|
bit_count == 37 || bit_count == 40 || bit_count == 48)
|
|
|
|
{
|
2023-04-07 03:46:18 +00:00
|
|
|
wiegand_stop_read(app);
|
|
|
|
scene_manager_next_scene(app->scene_manager, WiegandDataScene);
|
2023-11-21 21:08:54 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2023-04-07 03:46:18 +00:00
|
|
|
// No data, clear
|
|
|
|
bit_count = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
FURI_CRITICAL_EXIT();
|
|
|
|
}
|
|
|
|
|
2023-11-21 21:08:54 +00:00
|
|
|
void wiegand_read_scene_on_enter(void *context)
|
|
|
|
{
|
|
|
|
App *app = context;
|
2023-04-07 03:46:18 +00:00
|
|
|
widget_reset(app->widget);
|
|
|
|
widget_add_string_element(app->widget, 0, 0, AlignLeft, AlignTop, FontPrimary, "Read Wiegand");
|
|
|
|
widget_add_string_element(
|
|
|
|
app->widget, 0, 25, AlignLeft, AlignTop, FontSecondary, "Waiting for signal...");
|
|
|
|
widget_add_string_element(
|
|
|
|
app->widget, 0, 45, AlignLeft, AlignTop, FontSecondary, "D0/Green/A4");
|
|
|
|
widget_add_string_element(
|
|
|
|
app->widget, 0, 53, AlignLeft, AlignTop, FontSecondary, "D1/White/A7");
|
|
|
|
wiegand_start_read(app);
|
|
|
|
view_dispatcher_switch_to_view(app->view_dispatcher, WiegandWidgetView);
|
|
|
|
}
|
|
|
|
|
2023-11-21 21:08:54 +00:00
|
|
|
void wiegand_read_scene_on_exit(void *context)
|
|
|
|
{
|
|
|
|
App *app = context;
|
2023-04-07 03:46:18 +00:00
|
|
|
wiegand_stop_read(app);
|
|
|
|
}
|