App accessor: init (#433)
This commit is contained in:
		
							
								
								
									
										176
									
								
								applications/accessor/accessor-app.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										176
									
								
								applications/accessor/accessor-app.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,176 @@
 | 
				
			|||||||
 | 
					#include "accessor-app.h"
 | 
				
			||||||
 | 
					#include <furi.h>
 | 
				
			||||||
 | 
					#include <api-hal.h>
 | 
				
			||||||
 | 
					#include <stdarg.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AccessorApp::run(void) {
 | 
				
			||||||
 | 
					    AccessorEvent event;
 | 
				
			||||||
 | 
					    bool consumed;
 | 
				
			||||||
 | 
					    bool exit = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    notify_init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    wiegand.begin();
 | 
				
			||||||
 | 
					    onewire_master.start();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    scenes[current_scene]->on_enter(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while(!exit) {
 | 
				
			||||||
 | 
					        view.receive_event(&event);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        consumed = scenes[current_scene]->on_event(this, &event);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(!consumed) {
 | 
				
			||||||
 | 
					            if(event.type == AccessorEvent::Type::Back) {
 | 
				
			||||||
 | 
					                exit = switch_to_previous_scene();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    scenes[current_scene]->on_exit(this);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AccessorApp::AccessorApp()
 | 
				
			||||||
 | 
					    : onewire_master{&ibutton_gpio} {
 | 
				
			||||||
 | 
					    api_hal_power_insomnia_enter();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AccessorApp::~AccessorApp() {
 | 
				
			||||||
 | 
					    api_hal_power_insomnia_exit();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AccessorAppViewManager* AccessorApp::get_view_manager() {
 | 
				
			||||||
 | 
					    return &view;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AccessorApp::switch_to_next_scene(Scene next_scene) {
 | 
				
			||||||
 | 
					    previous_scenes_list.push_front(current_scene);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(next_scene != Scene::Exit) {
 | 
				
			||||||
 | 
					        scenes[current_scene]->on_exit(this);
 | 
				
			||||||
 | 
					        current_scene = next_scene;
 | 
				
			||||||
 | 
					        scenes[current_scene]->on_enter(this);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AccessorApp::search_and_switch_to_previous_scene(std::initializer_list<Scene> scenes_list) {
 | 
				
			||||||
 | 
					    Scene previous_scene = Scene::Start;
 | 
				
			||||||
 | 
					    bool scene_found = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while(!scene_found) {
 | 
				
			||||||
 | 
					        previous_scene = get_previous_scene();
 | 
				
			||||||
 | 
					        for(Scene element : scenes_list) {
 | 
				
			||||||
 | 
					            if(previous_scene == element || previous_scene == Scene::Start) {
 | 
				
			||||||
 | 
					                scene_found = true;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    scenes[current_scene]->on_exit(this);
 | 
				
			||||||
 | 
					    current_scene = previous_scene;
 | 
				
			||||||
 | 
					    scenes[current_scene]->on_enter(this);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool AccessorApp::switch_to_previous_scene(uint8_t count) {
 | 
				
			||||||
 | 
					    Scene previous_scene = Scene::Start;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for(uint8_t i = 0; i < count; i++) {
 | 
				
			||||||
 | 
					        previous_scene = get_previous_scene();
 | 
				
			||||||
 | 
					        if(previous_scene == Scene::Exit) break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(previous_scene == Scene::Exit) {
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        scenes[current_scene]->on_exit(this);
 | 
				
			||||||
 | 
					        current_scene = previous_scene;
 | 
				
			||||||
 | 
					        scenes[current_scene]->on_enter(this);
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AccessorApp::Scene AccessorApp::get_previous_scene() {
 | 
				
			||||||
 | 
					    Scene scene = previous_scenes_list.front();
 | 
				
			||||||
 | 
					    previous_scenes_list.pop_front();
 | 
				
			||||||
 | 
					    return scene;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/***************************** NOTIFY *******************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AccessorApp::notify_init() {
 | 
				
			||||||
 | 
					    // TODO open record
 | 
				
			||||||
 | 
					    const GpioPin* vibro_record = &vibro_gpio;
 | 
				
			||||||
 | 
					    gpio_init(vibro_record, GpioModeOutputPushPull);
 | 
				
			||||||
 | 
					    gpio_write(vibro_record, false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GPIO_InitTypeDef GPIO_InitStruct = {0};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GPIO_InitStruct.Pin = PB3_Pin;
 | 
				
			||||||
 | 
					    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 | 
				
			||||||
 | 
					    GPIO_InitStruct.Pull = GPIO_NOPULL;
 | 
				
			||||||
 | 
					    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
 | 
				
			||||||
 | 
					    GPIO_InitStruct.Alternate = GPIO_AF1_TIM2;
 | 
				
			||||||
 | 
					    HAL_GPIO_Init(PB3_GPIO_Port, &GPIO_InitStruct);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AccessorApp::notify_green_blink() {
 | 
				
			||||||
 | 
					    api_hal_light_set(LightGreen, 0xFF);
 | 
				
			||||||
 | 
					    delay(10);
 | 
				
			||||||
 | 
					    api_hal_light_set(LightGreen, 0x00);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AccessorApp::notify_green_on() {
 | 
				
			||||||
 | 
					    api_hal_light_set(LightGreen, 0xFF);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AccessorApp::notify_green_off() {
 | 
				
			||||||
 | 
					    api_hal_light_set(LightGreen, 0x00);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AccessorApp::notify_success() {
 | 
				
			||||||
 | 
					    api_hal_light_set(LightBacklight, 0xFF);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    hal_pwm_set(0.5, 1760 / 2, &htim2, TIM_CHANNEL_2);
 | 
				
			||||||
 | 
					    notify_green_on();
 | 
				
			||||||
 | 
					    delay(100);
 | 
				
			||||||
 | 
					    hal_pwm_stop(&htim2, TIM_CHANNEL_2);
 | 
				
			||||||
 | 
					    notify_green_off();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    delay(100);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    hal_pwm_set(0.5, 1760, &htim2, TIM_CHANNEL_2);
 | 
				
			||||||
 | 
					    notify_green_on();
 | 
				
			||||||
 | 
					    delay(100);
 | 
				
			||||||
 | 
					    hal_pwm_stop(&htim2, TIM_CHANNEL_2);
 | 
				
			||||||
 | 
					    notify_green_off();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*************************** TEXT STORE *****************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char* AccessorApp::get_text_store() {
 | 
				
			||||||
 | 
					    return text_store;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint8_t AccessorApp::get_text_store_size() {
 | 
				
			||||||
 | 
					    return text_store_size;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AccessorApp::set_text_store(const char* text...) {
 | 
				
			||||||
 | 
					    va_list args;
 | 
				
			||||||
 | 
					    va_start(args, text);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    vsnprintf(text_store, text_store_size, text, args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    va_end(args);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*************************** APP RESOURCES *****************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					WIEGAND* AccessorApp::get_wiegand() {
 | 
				
			||||||
 | 
					    return &wiegand;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OneWireMaster* AccessorApp::get_one_wire() {
 | 
				
			||||||
 | 
					    return &onewire_master;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										58
									
								
								applications/accessor/accessor-app.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								applications/accessor/accessor-app.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					#include <map>
 | 
				
			||||||
 | 
					#include <list>
 | 
				
			||||||
 | 
					#include "accessor-view-manager.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "scene/accessor-scene-start.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "helpers/wiegand.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <one_wire_master.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AccessorApp {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    void run(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    AccessorApp();
 | 
				
			||||||
 | 
					    ~AccessorApp();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    enum class Scene : uint8_t {
 | 
				
			||||||
 | 
					        Exit,
 | 
				
			||||||
 | 
					        Start,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    AccessorAppViewManager* get_view_manager();
 | 
				
			||||||
 | 
					    void switch_to_next_scene(Scene index);
 | 
				
			||||||
 | 
					    void search_and_switch_to_previous_scene(std::initializer_list<Scene> scenes_list);
 | 
				
			||||||
 | 
					    bool switch_to_previous_scene(uint8_t count = 1);
 | 
				
			||||||
 | 
					    Scene get_previous_scene();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void notify_init();
 | 
				
			||||||
 | 
					    void notify_green_blink();
 | 
				
			||||||
 | 
					    void notify_green_on();
 | 
				
			||||||
 | 
					    void notify_green_off();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void notify_success();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    char* get_text_store();
 | 
				
			||||||
 | 
					    uint8_t get_text_store_size();
 | 
				
			||||||
 | 
					    void set_text_store(const char* text...);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    WIEGAND* get_wiegand();
 | 
				
			||||||
 | 
					    OneWireMaster* get_one_wire();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    std::list<Scene> previous_scenes_list = {Scene::Exit};
 | 
				
			||||||
 | 
					    Scene current_scene = Scene::Start;
 | 
				
			||||||
 | 
					    AccessorAppViewManager view;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::map<Scene, AccessorScene*> scenes = {
 | 
				
			||||||
 | 
					        {Scene::Start, new AccessorSceneStart()},
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static const uint8_t text_store_size = 128;
 | 
				
			||||||
 | 
					    char text_store[text_store_size + 1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    WIEGAND wiegand;
 | 
				
			||||||
 | 
					    OneWireMaster onewire_master;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										19
									
								
								applications/accessor/accessor-event.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								applications/accessor/accessor-event.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AccessorEvent {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    // events enum
 | 
				
			||||||
 | 
					    enum class Type : uint8_t {
 | 
				
			||||||
 | 
					        Tick,
 | 
				
			||||||
 | 
					        Back,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // payload
 | 
				
			||||||
 | 
					    union {
 | 
				
			||||||
 | 
					        uint32_t menu_index;
 | 
				
			||||||
 | 
					    } payload;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // event type
 | 
				
			||||||
 | 
					    Type type;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										79
									
								
								applications/accessor/accessor-view-manager.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								applications/accessor/accessor-view-manager.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,79 @@
 | 
				
			|||||||
 | 
					#include "accessor-view-manager.h"
 | 
				
			||||||
 | 
					#include "accessor-event.h"
 | 
				
			||||||
 | 
					#include <callback-connector.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AccessorAppViewManager::AccessorAppViewManager() {
 | 
				
			||||||
 | 
					    event_queue = osMessageQueueNew(10, sizeof(AccessorEvent), NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    view_dispatcher = view_dispatcher_alloc();
 | 
				
			||||||
 | 
					    auto callback = cbc::obtain_connector(this, &AccessorAppViewManager::previous_view_callback);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // allocate views
 | 
				
			||||||
 | 
					    submenu = submenu_alloc();
 | 
				
			||||||
 | 
					    add_view(ViewType::Submenu, submenu_get_view(submenu));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    popup = popup_alloc();
 | 
				
			||||||
 | 
					    add_view(ViewType::Popup, popup_get_view(popup));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    gui = static_cast<Gui*>(furi_record_open("gui"));
 | 
				
			||||||
 | 
					    view_dispatcher_attach_to_gui(view_dispatcher, gui, ViewDispatcherTypeFullscreen);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // set previous view callback for all views
 | 
				
			||||||
 | 
					    view_set_previous_callback(submenu_get_view(submenu), callback);
 | 
				
			||||||
 | 
					    view_set_previous_callback(popup_get_view(popup), callback);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					AccessorAppViewManager::~AccessorAppViewManager() {
 | 
				
			||||||
 | 
					    // remove views
 | 
				
			||||||
 | 
					    view_dispatcher_remove_view(
 | 
				
			||||||
 | 
					        view_dispatcher, static_cast<uint32_t>(AccessorAppViewManager::ViewType::Submenu));
 | 
				
			||||||
 | 
					    view_dispatcher_remove_view(
 | 
				
			||||||
 | 
					        view_dispatcher, static_cast<uint32_t>(AccessorAppViewManager::ViewType::Popup));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // free view modules
 | 
				
			||||||
 | 
					    submenu_free(submenu);
 | 
				
			||||||
 | 
					    popup_free(popup);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // free dispatcher
 | 
				
			||||||
 | 
					    view_dispatcher_free(view_dispatcher);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // free event queue
 | 
				
			||||||
 | 
					    osMessageQueueDelete(event_queue);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AccessorAppViewManager::switch_to(ViewType type) {
 | 
				
			||||||
 | 
					    view_dispatcher_switch_to_view(view_dispatcher, static_cast<uint32_t>(type));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Submenu* AccessorAppViewManager::get_submenu() {
 | 
				
			||||||
 | 
					    return submenu;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Popup* AccessorAppViewManager::get_popup() {
 | 
				
			||||||
 | 
					    return popup;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AccessorAppViewManager::receive_event(AccessorEvent* event) {
 | 
				
			||||||
 | 
					    if(osMessageQueueGet(event_queue, event, NULL, 100) != osOK) {
 | 
				
			||||||
 | 
					        event->type = AccessorEvent::Type::Tick;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AccessorAppViewManager::send_event(AccessorEvent* event) {
 | 
				
			||||||
 | 
					    osStatus_t result = osMessageQueuePut(event_queue, event, 0, 0);
 | 
				
			||||||
 | 
					    furi_check(result == osOK);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint32_t AccessorAppViewManager::previous_view_callback(void* context) {
 | 
				
			||||||
 | 
					    if(event_queue != NULL) {
 | 
				
			||||||
 | 
					        AccessorEvent event;
 | 
				
			||||||
 | 
					        event.type = AccessorEvent::Type::Back;
 | 
				
			||||||
 | 
					        send_event(&event);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return VIEW_IGNORE;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AccessorAppViewManager::add_view(ViewType view_type, View* view) {
 | 
				
			||||||
 | 
					    view_dispatcher_add_view(view_dispatcher, static_cast<uint32_t>(view_type), view);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										39
									
								
								applications/accessor/accessor-view-manager.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								applications/accessor/accessor-view-manager.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					#include <furi.h>
 | 
				
			||||||
 | 
					#include <gui/view_dispatcher.h>
 | 
				
			||||||
 | 
					#include <gui/modules/submenu.h>
 | 
				
			||||||
 | 
					#include <gui/modules/popup.h>
 | 
				
			||||||
 | 
					#include "accessor-event.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AccessorAppViewManager {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    enum class ViewType : uint8_t {
 | 
				
			||||||
 | 
					        Submenu,
 | 
				
			||||||
 | 
					        Popup,
 | 
				
			||||||
 | 
					        Tune,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    osMessageQueueId_t event_queue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    AccessorAppViewManager();
 | 
				
			||||||
 | 
					    ~AccessorAppViewManager();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void switch_to(ViewType type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void receive_event(AccessorEvent* event);
 | 
				
			||||||
 | 
					    void send_event(AccessorEvent* event);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Submenu* get_submenu();
 | 
				
			||||||
 | 
					    Popup* get_popup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    ViewDispatcher* view_dispatcher;
 | 
				
			||||||
 | 
					    Gui* gui;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint32_t previous_view_callback(void* context);
 | 
				
			||||||
 | 
					    void add_view(ViewType view_type, View* view);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // view elements
 | 
				
			||||||
 | 
					    Submenu* submenu;
 | 
				
			||||||
 | 
					    Popup* popup;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										10
									
								
								applications/accessor/accessor.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								applications/accessor/accessor.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					#include "accessor-app.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// app enter function
 | 
				
			||||||
 | 
					extern "C" int32_t app_accessor(void* p) {
 | 
				
			||||||
 | 
					    AccessorApp* app = new AccessorApp();
 | 
				
			||||||
 | 
					    app->run();
 | 
				
			||||||
 | 
					    delete app;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 255;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										221
									
								
								applications/accessor/helpers/wiegand.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										221
									
								
								applications/accessor/helpers/wiegand.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,221 @@
 | 
				
			|||||||
 | 
					#include "wiegand.h"
 | 
				
			||||||
 | 
					#include <furi.h>
 | 
				
			||||||
 | 
					#include <api-hal.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					volatile unsigned long WIEGAND::_cardTempHigh = 0;
 | 
				
			||||||
 | 
					volatile unsigned long WIEGAND::_cardTemp = 0;
 | 
				
			||||||
 | 
					volatile unsigned long WIEGAND::_lastWiegand = 0;
 | 
				
			||||||
 | 
					unsigned long WIEGAND::_code = 0;
 | 
				
			||||||
 | 
					unsigned long WIEGAND::_codeHigh = 0;
 | 
				
			||||||
 | 
					volatile int WIEGAND::_bitCount = 0;
 | 
				
			||||||
 | 
					int WIEGAND::_wiegandType = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					constexpr uint32_t clocks_in_ms = 64 * 1000;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					WIEGAND::WIEGAND() {
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned long WIEGAND::getCode() {
 | 
				
			||||||
 | 
					    return _code;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned long WIEGAND::getCodeHigh() {
 | 
				
			||||||
 | 
					    return _codeHigh;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int WIEGAND::getWiegandType() {
 | 
				
			||||||
 | 
					    return _wiegandType;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool WIEGAND::available() {
 | 
				
			||||||
 | 
					    bool ret;
 | 
				
			||||||
 | 
					    __disable_irq();
 | 
				
			||||||
 | 
					    ret = DoWiegandConversion();
 | 
				
			||||||
 | 
					    __enable_irq();
 | 
				
			||||||
 | 
					    return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void input_isr(void* _pin, void* _ctx) {
 | 
				
			||||||
 | 
					    // interrupt manager get us pin constant, so...
 | 
				
			||||||
 | 
					    uint32_t pin = (uint32_t)_pin;
 | 
				
			||||||
 | 
					    WIEGAND* _this = static_cast<WIEGAND*>(_ctx);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(pin == ext_pa6_gpio.pin) {
 | 
				
			||||||
 | 
					        _this->ReadD0();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(pin == ext_pa7_gpio.pin) {
 | 
				
			||||||
 | 
					        _this->ReadD1();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void WIEGAND::begin() {
 | 
				
			||||||
 | 
					    _lastWiegand = 0;
 | 
				
			||||||
 | 
					    _cardTempHigh = 0;
 | 
				
			||||||
 | 
					    _cardTemp = 0;
 | 
				
			||||||
 | 
					    _code = 0;
 | 
				
			||||||
 | 
					    _wiegandType = 0;
 | 
				
			||||||
 | 
					    _bitCount = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const GpioPin* pinD0 = &ext_pa6_gpio;
 | 
				
			||||||
 | 
					    const GpioPin* pinD1 = &ext_pa7_gpio;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    gpio_init(pinD0, GpioModeInterruptFall); // Set D0 pin as input
 | 
				
			||||||
 | 
					    gpio_init(pinD1, GpioModeInterruptFall); // Set D1 pin as input
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    api_interrupt_add(
 | 
				
			||||||
 | 
					        input_isr, InterruptTypeExternalInterrupt, this); // Hardware interrupt - high to low pulse
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void WIEGAND::ReadD0() {
 | 
				
			||||||
 | 
					    _bitCount++; // Increament bit count for Interrupt connected to D0
 | 
				
			||||||
 | 
					    if(_bitCount > 31) // If bit count more than 31, process high bits
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        _cardTempHigh |= ((0x80000000 & _cardTemp) >> 31); //	shift value to high bits
 | 
				
			||||||
 | 
					        _cardTempHigh <<= 1;
 | 
				
			||||||
 | 
					        _cardTemp <<= 1;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        _cardTemp <<= 1; // D0 represent binary 0, so just left shift card data
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    _lastWiegand = DWT->CYCCNT; // Keep track of last wiegand bit received
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void WIEGAND::ReadD1() {
 | 
				
			||||||
 | 
					    _bitCount++; // Increment bit count for Interrupt connected to D1
 | 
				
			||||||
 | 
					    if(_bitCount > 31) // If bit count more than 31, process high bits
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        _cardTempHigh |= ((0x80000000 & _cardTemp) >> 31); // shift value to high bits
 | 
				
			||||||
 | 
					        _cardTempHigh <<= 1;
 | 
				
			||||||
 | 
					        _cardTemp |= 1;
 | 
				
			||||||
 | 
					        _cardTemp <<= 1;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        _cardTemp |= 1; // D1 represent binary 1, so OR card data with 1 then
 | 
				
			||||||
 | 
					        _cardTemp <<= 1; // left shift card data
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    _lastWiegand = DWT->CYCCNT; // Keep track of last wiegand bit received
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					unsigned long WIEGAND::GetCardId(
 | 
				
			||||||
 | 
					    volatile unsigned long* codehigh,
 | 
				
			||||||
 | 
					    volatile unsigned long* codelow,
 | 
				
			||||||
 | 
					    char bitlength) {
 | 
				
			||||||
 | 
					    if(bitlength == 26) // EM tag
 | 
				
			||||||
 | 
					        return (*codelow & 0x1FFFFFE) >> 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(bitlength == 24) return (*codelow & 0x7FFFFE) >> 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(bitlength == 34) // Mifare
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        *codehigh = *codehigh & 0x03; // only need the 2 LSB of the codehigh
 | 
				
			||||||
 | 
					        *codehigh <<= 30; // shift 2 LSB to MSB
 | 
				
			||||||
 | 
					        *codelow >>= 1;
 | 
				
			||||||
 | 
					        return *codehigh | *codelow;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(bitlength == 32) {
 | 
				
			||||||
 | 
					        return (*codelow & 0x7FFFFFFE) >> 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return *codelow; // EM tag or Mifare without parity bits
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char translateEnterEscapeKeyPress(char originalKeyPress) {
 | 
				
			||||||
 | 
					    switch(originalKeyPress) {
 | 
				
			||||||
 | 
					    case 0x0b: // 11 or * key
 | 
				
			||||||
 | 
					        return 0x0d; // 13 or ASCII ENTER
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    case 0x0a: // 10 or # key
 | 
				
			||||||
 | 
					        return 0x1b; // 27 or ASCII ESCAPE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					        return originalKeyPress;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool WIEGAND::DoWiegandConversion() {
 | 
				
			||||||
 | 
					    unsigned long cardID;
 | 
				
			||||||
 | 
					    unsigned long sysTick = DWT->CYCCNT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if((sysTick - _lastWiegand) >
 | 
				
			||||||
 | 
					       (25 * clocks_in_ms)) // if no more signal coming through after 25ms
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        if((_bitCount == 24) || (_bitCount == 26) || (_bitCount == 32) || (_bitCount == 34) ||
 | 
				
			||||||
 | 
					           (_bitCount == 37) || (_bitCount == 40) || (_bitCount == 8) ||
 | 
				
			||||||
 | 
					           (_bitCount ==
 | 
				
			||||||
 | 
					            4)) // bitCount for keypress=4 or 8, Wiegand 26=24 or 26, Wiegand 34=32 or 34
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _codeHigh = 0;
 | 
				
			||||||
 | 
					            // shift right 1 bit to get back the real value - interrupt done 1 left shift in advance
 | 
				
			||||||
 | 
					            _cardTemp >>= 1;
 | 
				
			||||||
 | 
					            // bit count more than 32 bits, shift high bits right to make adjustment
 | 
				
			||||||
 | 
					            if(_bitCount > 32) _cardTempHigh >>= 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(_bitCount == 8) // keypress wiegand with integrity
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                // 8-bit Wiegand keyboard data, high nibble is the "NOT" of low nibble
 | 
				
			||||||
 | 
					                // eg if key 1 pressed, data=E1 in binary 11100001 , high nibble=1110 , low nibble = 0001
 | 
				
			||||||
 | 
					                char highNibble = (_cardTemp & 0xf0) >> 4;
 | 
				
			||||||
 | 
					                char lowNibble = (_cardTemp & 0x0f);
 | 
				
			||||||
 | 
					                _wiegandType = _bitCount;
 | 
				
			||||||
 | 
					                _bitCount = 0;
 | 
				
			||||||
 | 
					                _cardTemp = 0;
 | 
				
			||||||
 | 
					                _cardTempHigh = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if(lowNibble ==
 | 
				
			||||||
 | 
					                   (~highNibble & 0x0f)) // check if low nibble matches the "NOT" of high nibble.
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    _code = (int)translateEnterEscapeKeyPress(lowNibble);
 | 
				
			||||||
 | 
					                    return true;
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    _lastWiegand = sysTick;
 | 
				
			||||||
 | 
					                    _bitCount = 0;
 | 
				
			||||||
 | 
					                    _cardTemp = 0;
 | 
				
			||||||
 | 
					                    _cardTempHigh = 0;
 | 
				
			||||||
 | 
					                    return false;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                // TODO: Handle validation failure case!
 | 
				
			||||||
 | 
					            } else if(4 == _bitCount) {
 | 
				
			||||||
 | 
					                // 4-bit Wiegand codes have no data integrity check so we just
 | 
				
			||||||
 | 
					                // read the LOW nibble.
 | 
				
			||||||
 | 
					                _code = (int)translateEnterEscapeKeyPress(_cardTemp & 0x0000000F);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                _wiegandType = _bitCount;
 | 
				
			||||||
 | 
					                _bitCount = 0;
 | 
				
			||||||
 | 
					                _cardTemp = 0;
 | 
				
			||||||
 | 
					                _cardTempHigh = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return true;
 | 
				
			||||||
 | 
					            } else if(40 == _bitCount) {
 | 
				
			||||||
 | 
					                _cardTempHigh >>= 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                _code = _cardTemp;
 | 
				
			||||||
 | 
					                _codeHigh = _cardTempHigh;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                _wiegandType = _bitCount;
 | 
				
			||||||
 | 
					                _bitCount = 0;
 | 
				
			||||||
 | 
					                _cardTemp = 0;
 | 
				
			||||||
 | 
					                _cardTempHigh = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return true;
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                // wiegand 26 or wiegand 34
 | 
				
			||||||
 | 
					                cardID = GetCardId(&_cardTempHigh, &_cardTemp, _bitCount);
 | 
				
			||||||
 | 
					                _wiegandType = _bitCount;
 | 
				
			||||||
 | 
					                _bitCount = 0;
 | 
				
			||||||
 | 
					                _cardTemp = 0;
 | 
				
			||||||
 | 
					                _cardTempHigh = 0;
 | 
				
			||||||
 | 
					                _code = cardID;
 | 
				
			||||||
 | 
					                return true;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            // well time over 25 ms and bitCount !=8 , !=26, !=34 , must be noise or nothing then.
 | 
				
			||||||
 | 
					            _lastWiegand = sysTick;
 | 
				
			||||||
 | 
					            _bitCount = 0;
 | 
				
			||||||
 | 
					            _cardTemp = 0;
 | 
				
			||||||
 | 
					            _cardTempHigh = 0;
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    } else
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										27
									
								
								applications/accessor/helpers/wiegand.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								applications/accessor/helpers/wiegand.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,27 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class WIEGAND {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    WIEGAND();
 | 
				
			||||||
 | 
					    void begin();
 | 
				
			||||||
 | 
					    bool available();
 | 
				
			||||||
 | 
					    unsigned long getCode();
 | 
				
			||||||
 | 
					    unsigned long getCodeHigh();
 | 
				
			||||||
 | 
					    int getWiegandType();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static void ReadD0();
 | 
				
			||||||
 | 
					    static void ReadD1();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    static bool DoWiegandConversion();
 | 
				
			||||||
 | 
					    static unsigned long
 | 
				
			||||||
 | 
					    GetCardId(volatile unsigned long* codehigh, volatile unsigned long* codelow, char bitlength);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static volatile unsigned long _cardTempHigh;
 | 
				
			||||||
 | 
					    static volatile unsigned long _cardTemp;
 | 
				
			||||||
 | 
					    static volatile unsigned long _lastWiegand;
 | 
				
			||||||
 | 
					    static volatile int _bitCount;
 | 
				
			||||||
 | 
					    static int _wiegandType;
 | 
				
			||||||
 | 
					    static unsigned long _code;
 | 
				
			||||||
 | 
					    static unsigned long _codeHigh;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										13
									
								
								applications/accessor/scene/accessor-scene-generic.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								applications/accessor/scene/accessor-scene-generic.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					#include "../accessor-app.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AccessorApp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AccessorScene {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    virtual void on_enter(AccessorApp* app) = 0;
 | 
				
			||||||
 | 
					    virtual bool on_event(AccessorApp* app, AccessorEvent* event) = 0;
 | 
				
			||||||
 | 
					    virtual void on_exit(AccessorApp* app) = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										88
									
								
								applications/accessor/scene/accessor-scene-start.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								applications/accessor/scene/accessor-scene-start.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,88 @@
 | 
				
			|||||||
 | 
					#include "../accessor-app.h"
 | 
				
			||||||
 | 
					#include "../accessor-view-manager.h"
 | 
				
			||||||
 | 
					#include "../accessor-event.h"
 | 
				
			||||||
 | 
					#include <callback-connector.h>
 | 
				
			||||||
 | 
					#include "accessor-scene-start.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AccessorSceneStart::on_enter(AccessorApp* app) {
 | 
				
			||||||
 | 
					    AccessorAppViewManager* view_manager = app->get_view_manager();
 | 
				
			||||||
 | 
					    Popup* popup = view_manager->get_popup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    popup_set_header(popup, "Accessor App", 64, 16, AlignCenter, AlignBottom);
 | 
				
			||||||
 | 
					    app->set_text_store("[??????]");
 | 
				
			||||||
 | 
					    popup_set_text(popup, app->get_text_store(), 64, 22, AlignCenter, AlignTop);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    view_manager->switch_to(AccessorAppViewManager::ViewType::Popup);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool AccessorSceneStart::on_event(AccessorApp* app, AccessorEvent* event) {
 | 
				
			||||||
 | 
					    bool consumed = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    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();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        uint8_t data[8] = {0, 0, 0, 0, 0, 0, 0, 0};
 | 
				
			||||||
 | 
					        uint8_t type = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(wiegand->available()) {
 | 
				
			||||||
 | 
					            type = wiegand->getWiegandType();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            for(uint8_t i = 0; i < 4; i++) {
 | 
				
			||||||
 | 
					                data[i] = wiegand->getCode() >> (i * 8);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            for(uint8_t i = 4; i < 8; i++) {
 | 
				
			||||||
 | 
					                data[i] = wiegand->getCodeHigh() >> ((i - 4) * 8);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            __disable_irq();
 | 
				
			||||||
 | 
					            if(onewire->reset()) {
 | 
				
			||||||
 | 
					                type = 255;
 | 
				
			||||||
 | 
					                onewire->write(0x33);
 | 
				
			||||||
 | 
					                for(uint8_t i = 0; i < 8; i++) {
 | 
				
			||||||
 | 
					                    data[i] = onewire->read();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                for(uint8_t i = 0; i < 7; i++) {
 | 
				
			||||||
 | 
					                    data[i] = data[i + 1];
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            __enable_irq();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(type > 0) {
 | 
				
			||||||
 | 
					            if(type == 255) {
 | 
				
			||||||
 | 
					                app->set_text_store(
 | 
				
			||||||
 | 
					                    "[%02X %02X %02X %02X %02X %02X DS]",
 | 
				
			||||||
 | 
					                    data[5],
 | 
				
			||||||
 | 
					                    data[4],
 | 
				
			||||||
 | 
					                    data[3],
 | 
				
			||||||
 | 
					                    data[2],
 | 
				
			||||||
 | 
					                    data[1],
 | 
				
			||||||
 | 
					                    data[0]);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                app->set_text_store(
 | 
				
			||||||
 | 
					                    "[%02X %02X %02X %02X %02X %02X W%u]",
 | 
				
			||||||
 | 
					                    data[5],
 | 
				
			||||||
 | 
					                    data[4],
 | 
				
			||||||
 | 
					                    data[3],
 | 
				
			||||||
 | 
					                    data[2],
 | 
				
			||||||
 | 
					                    data[1],
 | 
				
			||||||
 | 
					                    data[0],
 | 
				
			||||||
 | 
					                    type);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            popup_set_text(popup, app->get_text_store(), 64, 22, AlignCenter, AlignTop);
 | 
				
			||||||
 | 
					            app->notify_success();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return consumed;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AccessorSceneStart::on_exit(AccessorApp* app) {
 | 
				
			||||||
 | 
					    Popup* popup = app->get_view_manager()->get_popup();
 | 
				
			||||||
 | 
					    popup_set_header(popup, NULL, 0, 0, AlignCenter, AlignBottom);
 | 
				
			||||||
 | 
					    popup_set_text(popup, NULL, 0, 0, AlignCenter, AlignTop);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										9
									
								
								applications/accessor/scene/accessor-scene-start.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								applications/accessor/scene/accessor-scene-start.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					#include "accessor-scene-generic.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AccessorSceneStart : public AccessorScene {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    void on_enter(AccessorApp* app) final;
 | 
				
			||||||
 | 
					    bool on_event(AccessorApp* app, AccessorEvent* event) final;
 | 
				
			||||||
 | 
					    void on_exit(AccessorApp* app) final;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@@ -35,6 +35,7 @@ int32_t gui_test(void* p);
 | 
				
			|||||||
int32_t keypad_test(void* p);
 | 
					int32_t keypad_test(void* p);
 | 
				
			||||||
int32_t scene_app(void* p);
 | 
					int32_t scene_app(void* p);
 | 
				
			||||||
int32_t passport(void* p);
 | 
					int32_t passport(void* p);
 | 
				
			||||||
 | 
					int32_t app_accessor(void* p);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const FlipperApplication FLIPPER_SERVICES[] = {
 | 
					const FlipperApplication FLIPPER_SERVICES[] = {
 | 
				
			||||||
#ifdef APP_CLI
 | 
					#ifdef APP_CLI
 | 
				
			||||||
@@ -149,6 +150,10 @@ const FlipperApplication FLIPPER_SERVICES[] = {
 | 
				
			|||||||
    {.app = keypad_test, .name = "keypad_test", .icon = A_Plugins_14},
 | 
					    {.app = keypad_test, .name = "keypad_test", .icon = A_Plugins_14},
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef APP_ACCESSOR
 | 
				
			||||||
 | 
					    {.app = app_accessor, .name = "accessor", .stack_size = 4096, .icon = A_Plugins_14},
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const size_t FLIPPER_SERVICES_COUNT = sizeof(FLIPPER_SERVICES) / sizeof(FlipperApplication);
 | 
					const size_t FLIPPER_SERVICES_COUNT = sizeof(FLIPPER_SERVICES) / sizeof(FlipperApplication);
 | 
				
			||||||
@@ -230,6 +235,10 @@ const FlipperApplication FLIPPER_DEBUG_APPS[] = {
 | 
				
			|||||||
    {.app = keypad_test, .name = "keypad_test", .icon = A_Plugins_14},
 | 
					    {.app = keypad_test, .name = "keypad_test", .icon = A_Plugins_14},
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef BUILD_ACCESSOR
 | 
				
			||||||
 | 
					    {.app = app_accessor, .name = "accessor", .stack_size = 4096, .icon = A_Plugins_14},
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const size_t FLIPPER_DEBUG_APPS_COUNT = sizeof(FLIPPER_DEBUG_APPS) / sizeof(FlipperApplication);
 | 
					const size_t FLIPPER_DEBUG_APPS_COUNT = sizeof(FLIPPER_DEBUG_APPS) / sizeof(FlipperApplication);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,6 +25,7 @@ BUILD_GPIO_DEMO = 1
 | 
				
			|||||||
BUILD_MUSIC_PLAYER = 1
 | 
					BUILD_MUSIC_PLAYER = 1
 | 
				
			||||||
BUILD_FLOOPPER_BLOOPPER = 1
 | 
					BUILD_FLOOPPER_BLOOPPER = 1
 | 
				
			||||||
BUILD_IBUTTON = 1
 | 
					BUILD_IBUTTON = 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
APP_DEBUG ?=0
 | 
					APP_DEBUG ?=0
 | 
				
			||||||
@@ -32,6 +33,7 @@ ifeq ($(APP_DEBUG), 1)
 | 
				
			|||||||
CFLAGS		+= -DAPP_DEBUG
 | 
					CFLAGS		+= -DAPP_DEBUG
 | 
				
			||||||
BUILD_GUI_TEST = 1
 | 
					BUILD_GUI_TEST = 1
 | 
				
			||||||
BUILD_KEYPAD_TEST = 1
 | 
					BUILD_KEYPAD_TEST = 1
 | 
				
			||||||
 | 
					BUILD_ACCESSOR = 1
 | 
				
			||||||
BUILD_SD_TEST = 1
 | 
					BUILD_SD_TEST = 1
 | 
				
			||||||
BUILD_VIBRO_DEMO = 1
 | 
					BUILD_VIBRO_DEMO = 1
 | 
				
			||||||
BUILD_SPEAKER_DEMO = 1
 | 
					BUILD_SPEAKER_DEMO = 1
 | 
				
			||||||
@@ -209,6 +211,17 @@ CFLAGS		+= -DBUILD_KEYPAD_TEST
 | 
				
			|||||||
BUILD_KEYPAD_TEST = 1
 | 
					BUILD_KEYPAD_TEST = 1
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					APP_ACCESSOR ?= 0
 | 
				
			||||||
 | 
					ifeq ($(APP_ACCESSOR), 1)
 | 
				
			||||||
 | 
					CFLAGS		+= -DAPP_ACCESSOR
 | 
				
			||||||
 | 
					BUILD_ACCESSOR = 1
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					BUILD_ACCESSOR ?= 0
 | 
				
			||||||
 | 
					ifeq ($(BUILD_ACCESSOR), 1)
 | 
				
			||||||
 | 
					CFLAGS		+= -DBUILD_ACCESSOR
 | 
				
			||||||
 | 
					BUILD_ACCESSOR = 1
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
APP_GPIO_DEMO ?= 0
 | 
					APP_GPIO_DEMO ?= 0
 | 
				
			||||||
ifeq ($(APP_GPIO_DEMO), 1)
 | 
					ifeq ($(APP_GPIO_DEMO), 1)
 | 
				
			||||||
CFLAGS		+= -DAPP_GPIO_DEMO
 | 
					CFLAGS		+= -DAPP_GPIO_DEMO
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -42,3 +42,13 @@ const GpioPin gpio_spi_d_sck = { .port=SPI_D_SCK_GPIO_Port, .pin=SPI_D_SCK_Pin }
 | 
				
			|||||||
const GpioPin gpio_spi_r_miso = { .port=SPI_R_MISO_GPIO_Port, .pin=SPI_R_MISO_Pin };
 | 
					const GpioPin gpio_spi_r_miso = { .port=SPI_R_MISO_GPIO_Port, .pin=SPI_R_MISO_Pin };
 | 
				
			||||||
const GpioPin gpio_spi_r_mosi = { .port=SPI_R_MOSI_GPIO_Port, .pin=SPI_R_MOSI_Pin };
 | 
					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_spi_r_sck = { .port=SPI_R_SCK_GPIO_Port, .pin=SPI_R_SCK_Pin };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// external gpio's
 | 
				
			||||||
 | 
					const GpioPin ext_pc0_gpio = {.port = GPIOC, .pin = GPIO_PIN_0};
 | 
				
			||||||
 | 
					const GpioPin ext_pc1_gpio = {.port = GPIOC, .pin = GPIO_PIN_1};
 | 
				
			||||||
 | 
					const GpioPin ext_pc3_gpio = {.port = GPIOC, .pin = GPIO_PIN_3};
 | 
				
			||||||
 | 
					const GpioPin ext_pb2_gpio = {.port = GPIOB, .pin = GPIO_PIN_2};
 | 
				
			||||||
 | 
					const GpioPin ext_pb3_gpio = {.port = GPIOB, .pin = GPIO_PIN_3};
 | 
				
			||||||
 | 
					const GpioPin ext_pa4_gpio = {.port = GPIOA, .pin = GPIO_PIN_4};
 | 
				
			||||||
 | 
					const GpioPin ext_pa6_gpio = {.port = GPIOA, .pin = GPIO_PIN_6};
 | 
				
			||||||
 | 
					const GpioPin ext_pa7_gpio = {.port = GPIOA, .pin = GPIO_PIN_7};
 | 
				
			||||||
@@ -74,6 +74,14 @@ extern const GpioPin gpio_spi_r_miso;
 | 
				
			|||||||
extern const GpioPin gpio_spi_r_mosi;
 | 
					extern const GpioPin gpio_spi_r_mosi;
 | 
				
			||||||
extern const GpioPin gpio_spi_r_sck;
 | 
					extern const GpioPin gpio_spi_r_sck;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					extern const GpioPin ext_pc0_gpio;
 | 
				
			||||||
 | 
					extern const GpioPin ext_pc1_gpio;
 | 
				
			||||||
 | 
					extern const GpioPin ext_pc3_gpio;
 | 
				
			||||||
 | 
					extern const GpioPin ext_pb2_gpio;
 | 
				
			||||||
 | 
					extern const GpioPin ext_pb3_gpio;
 | 
				
			||||||
 | 
					extern const GpioPin ext_pa4_gpio;
 | 
				
			||||||
 | 
					extern const GpioPin ext_pa6_gpio;
 | 
				
			||||||
 | 
					extern const GpioPin ext_pa7_gpio;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user