Merge pull request #243 from Flipper-Zero/ibutton-app
iButton app, read mode
This commit is contained in:
		
						commit
						64961f5ae1
					
				@ -35,6 +35,7 @@ void power_task(void* p);
 | 
				
			|||||||
void sd_card_test(void* p);
 | 
					void sd_card_test(void* p);
 | 
				
			||||||
void application_vibro(void* p);
 | 
					void application_vibro(void* p);
 | 
				
			||||||
void app_gpio_test(void* p);
 | 
					void app_gpio_test(void* p);
 | 
				
			||||||
 | 
					void app_ibutton(void* p);
 | 
				
			||||||
void cli_task(void* p);
 | 
					void cli_task(void* p);
 | 
				
			||||||
void music_player(void* p);
 | 
					void music_player(void* p);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -126,13 +127,14 @@ const FlipperStartupApp FLIPPER_STARTUP[] = {
 | 
				
			|||||||
    {.app = music_player, .name = "music player", .libs = {1, FURI_LIB{"gui_task"}}},
 | 
					    {.app = music_player, .name = "music player", .libs = {1, FURI_LIB{"gui_task"}}},
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef APP_GPIO_DEMO
 | 
					#ifdef APP_IBUTTON
 | 
				
			||||||
    {
 | 
					    {.app = app_ibutton, .name = "ibutton", .libs = {1, FURI_LIB{"gui_task"}}},
 | 
				
			||||||
        .app = app_gpio_test,
 | 
					 | 
				
			||||||
        .name = "gpio test",
 | 
					 | 
				
			||||||
        .libs = {1, FURI_LIB{"gui_task"}},
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    };
 | 
					
 | 
				
			||||||
 | 
					#ifdef APP_GPIO_DEMO
 | 
				
			||||||
 | 
					    {.app = app_gpio_test, .name = "gpio test", .libs = {1, FURI_LIB{"gui_task"}}},
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const FlipperStartupApp FLIPPER_APPS[] = {
 | 
					const FlipperStartupApp FLIPPER_APPS[] = {
 | 
				
			||||||
#ifdef BUILD_EXAMPLE_BLINK
 | 
					#ifdef BUILD_EXAMPLE_BLINK
 | 
				
			||||||
@ -175,6 +177,10 @@ const FlipperStartupApp FLIPPER_APPS[] = {
 | 
				
			|||||||
    {.app = app_gpio_test, .name = "gpio test", .libs = {1, FURI_LIB{"gui_task"}}},
 | 
					    {.app = app_gpio_test, .name = "gpio test", .libs = {1, FURI_LIB{"gui_task"}}},
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef BUILD_IBUTTON
 | 
				
			||||||
 | 
					    {.app = app_ibutton, .name = "ibutton", .libs = {1, FURI_LIB{"gui_task"}}},
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef BUILD_MUSIC_PLAYER
 | 
					#ifdef BUILD_MUSIC_PLAYER
 | 
				
			||||||
    {.app = music_player, .name = "music player", .libs = {1, FURI_LIB{"gui_task"}}},
 | 
					    {.app = music_player, .name = "music player", .libs = {1, FURI_LIB{"gui_task"}}},
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
@ -24,6 +24,7 @@ BUILD_VIBRO_DEMO = 1
 | 
				
			|||||||
BUILD_SD_TEST = 1
 | 
					BUILD_SD_TEST = 1
 | 
				
			||||||
BUILD_GPIO_DEMO = 1
 | 
					BUILD_GPIO_DEMO = 1
 | 
				
			||||||
BUILD_MUSIC_PLAYER = 1
 | 
					BUILD_MUSIC_PLAYER = 1
 | 
				
			||||||
 | 
					BUILD_IBUTTON = 1
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
APP_NFC ?= 0
 | 
					APP_NFC ?= 0
 | 
				
			||||||
@ -258,6 +259,17 @@ CFLAGS		+= -DBUILD_MUSIC_PLAYER
 | 
				
			|||||||
C_SOURCES	+= $(wildcard $(APP_DIR)/music-player/*.c)
 | 
					C_SOURCES	+= $(wildcard $(APP_DIR)/music-player/*.c)
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					APP_IBUTTON ?= 0
 | 
				
			||||||
 | 
					ifeq ($(APP_IBUTTON), 1)
 | 
				
			||||||
 | 
					CFLAGS		+= -DAPP_IBUTTON
 | 
				
			||||||
 | 
					BUILD_IBUTTON = 1
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					BUILD_IBUTTON ?= 0
 | 
				
			||||||
 | 
					ifeq ($(BUILD_IBUTTON), 1)
 | 
				
			||||||
 | 
					CFLAGS		+= -DBUILD_IBUTTON
 | 
				
			||||||
 | 
					CPP_SOURCES	+= $(wildcard $(APP_DIR)/ibutton/ibutton.cpp)
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# device drivers
 | 
					# device drivers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
APP_GUI	?= 0
 | 
					APP_GUI	?= 0
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										113
									
								
								applications/ibutton/ibutton.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										113
									
								
								applications/ibutton/ibutton.cpp
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,113 @@
 | 
				
			|||||||
 | 
					#include "ibutton.h"
 | 
				
			||||||
 | 
					#include "ibutton_mode_dallas_read.h"
 | 
				
			||||||
 | 
					#include "ibutton_mode_dallas_emulate.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// start app
 | 
				
			||||||
 | 
					void AppiButton::run() {
 | 
				
			||||||
 | 
					    acquire_state();
 | 
				
			||||||
 | 
					    mode[0] = new AppiButtonModeDallasRead(this);
 | 
				
			||||||
 | 
					    mode[1] = new AppiButtonModeDallasEmulate(this);
 | 
				
			||||||
 | 
					    release_state();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    switch_to_mode(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // create pin
 | 
				
			||||||
 | 
					    GpioPin red_led = led_gpio[0];
 | 
				
			||||||
 | 
					    GpioPin green_led = led_gpio[1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // TODO open record
 | 
				
			||||||
 | 
					    red_led_record = &red_led;
 | 
				
			||||||
 | 
					    green_led_record = &green_led;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // configure pin
 | 
				
			||||||
 | 
					    gpio_init(red_led_record, GpioModeOutputOpenDrain);
 | 
				
			||||||
 | 
					    gpio_init(green_led_record, GpioModeOutputOpenDrain);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    AppiButtonEvent event;
 | 
				
			||||||
 | 
					    while(1) {
 | 
				
			||||||
 | 
					        osStatus_t event_status = osMessageQueueGet(event_queue, &event, NULL, 100);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(event_status == osOK) {
 | 
				
			||||||
 | 
					            if(event.type == AppiButtonEvent::EventTypeKey) {
 | 
				
			||||||
 | 
					                // press events
 | 
				
			||||||
 | 
					                if(event.value.input.state && event.value.input.input == InputBack) {
 | 
				
			||||||
 | 
					                    printf("[ibutton] bye!\n");
 | 
				
			||||||
 | 
					                    // TODO remove all widgets create by app
 | 
				
			||||||
 | 
					                    widget_enabled_set(widget, false);
 | 
				
			||||||
 | 
					                    furiac_exit(NULL);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if(event.value.input.state && event.value.input.input == InputLeft) {
 | 
				
			||||||
 | 
					                    decrease_mode();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if(event.value.input.state && event.value.input.input == InputRight) {
 | 
				
			||||||
 | 
					                    increase_mode();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            event.type = AppiButtonEvent::EventTypeTick;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        acquire_state();
 | 
				
			||||||
 | 
					        mode[state.mode_index]->event(&event, &state);
 | 
				
			||||||
 | 
					        release_state();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        widget_update(widget);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// render app
 | 
				
			||||||
 | 
					void AppiButton::render(CanvasApi* canvas) {
 | 
				
			||||||
 | 
					    canvas->set_color(canvas, ColorBlack);
 | 
				
			||||||
 | 
					    canvas->set_font(canvas, FontPrimary);
 | 
				
			||||||
 | 
					    canvas->draw_str(canvas, 2, 12, "iButton");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    mode[state.mode_index]->render(canvas, &state);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AppiButton::blink_red() {
 | 
				
			||||||
 | 
					    gpio_write(red_led_record, 0);
 | 
				
			||||||
 | 
					    delay(10);
 | 
				
			||||||
 | 
					    gpio_write(red_led_record, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AppiButton::blink_green() {
 | 
				
			||||||
 | 
					    gpio_write(green_led_record, 0);
 | 
				
			||||||
 | 
					    delay(10);
 | 
				
			||||||
 | 
					    gpio_write(green_led_record, 1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AppiButton::increase_mode() {
 | 
				
			||||||
 | 
					    acquire_state();
 | 
				
			||||||
 | 
					    if(state.mode_index < (modes_count - 1)) {
 | 
				
			||||||
 | 
					        mode[state.mode_index]->release();
 | 
				
			||||||
 | 
					        state.mode_index++;
 | 
				
			||||||
 | 
					        mode[state.mode_index]->acquire();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    release_state();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AppiButton::decrease_mode() {
 | 
				
			||||||
 | 
					    acquire_state();
 | 
				
			||||||
 | 
					    if(state.mode_index > 0) {
 | 
				
			||||||
 | 
					        mode[state.mode_index]->release();
 | 
				
			||||||
 | 
					        state.mode_index--;
 | 
				
			||||||
 | 
					        mode[state.mode_index]->acquire();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    release_state();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AppiButton::switch_to_mode(uint8_t mode_index) {
 | 
				
			||||||
 | 
					    acquire_state();
 | 
				
			||||||
 | 
					    mode[state.mode_index]->release();
 | 
				
			||||||
 | 
					    state.mode_index = mode_index;
 | 
				
			||||||
 | 
					    mode[state.mode_index]->acquire();
 | 
				
			||||||
 | 
					    release_state();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// app enter function
 | 
				
			||||||
 | 
					extern "C" void app_ibutton(void* p) {
 | 
				
			||||||
 | 
					    AppiButton* app = new AppiButton();
 | 
				
			||||||
 | 
					    app->run();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										56
									
								
								applications/ibutton/ibutton.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								applications/ibutton/ibutton.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,56 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					#include "app-template.h"
 | 
				
			||||||
 | 
					#include "ibutton_mode_template.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// event enumeration type
 | 
				
			||||||
 | 
					typedef uint8_t event_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AppiButtonState {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    // state data
 | 
				
			||||||
 | 
					    // test key = {0x01, 0xFD, 0x0E, 0x84, 0x01, 0x00, 0x00, 0xDB};
 | 
				
			||||||
 | 
					    uint8_t dallas_address[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
 | 
				
			||||||
 | 
					    uint8_t mode_index;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // state initializer
 | 
				
			||||||
 | 
					    AppiButtonState() {
 | 
				
			||||||
 | 
					        mode_index = 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// events class
 | 
				
			||||||
 | 
					class AppiButtonEvent {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    // events enum
 | 
				
			||||||
 | 
					    static const event_t EventTypeTick = 0;
 | 
				
			||||||
 | 
					    static const event_t EventTypeKey = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // payload
 | 
				
			||||||
 | 
					    union {
 | 
				
			||||||
 | 
					        InputEvent input;
 | 
				
			||||||
 | 
					    } value;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // event type
 | 
				
			||||||
 | 
					    event_t type;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// our app derived from base AppTemplate class
 | 
				
			||||||
 | 
					// with template variables <state, events>
 | 
				
			||||||
 | 
					class AppiButton : public AppTemplate<AppiButtonState, AppiButtonEvent> {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    GpioPin* red_led_record;
 | 
				
			||||||
 | 
					    GpioPin* green_led_record;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static const uint8_t modes_count = 2;
 | 
				
			||||||
 | 
					    AppTemplateMode<AppiButtonState, AppiButtonEvent>* mode[modes_count];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void run();
 | 
				
			||||||
 | 
					    void render(CanvasApi* canvas);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void blink_red();
 | 
				
			||||||
 | 
					    void blink_green();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void increase_mode();
 | 
				
			||||||
 | 
					    void decrease_mode();
 | 
				
			||||||
 | 
					    void switch_to_mode(uint8_t mode_index);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										64
									
								
								applications/ibutton/ibutton_mode_dallas_emulate.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								applications/ibutton/ibutton_mode_dallas_emulate.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,64 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					#include "ibutton.h"
 | 
				
			||||||
 | 
					#include "one_wire_slave_gpio.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AppiButtonModeDallasEmulate : public AppTemplateMode<AppiButtonState, AppiButtonEvent> {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    const char* name = "dallas emulate";
 | 
				
			||||||
 | 
					    AppiButton* app;
 | 
				
			||||||
 | 
					    OneWireGpioSlave* onewire_slave;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void event(AppiButtonEvent* event, AppiButtonState* state);
 | 
				
			||||||
 | 
					    void render(CanvasApi* canvas, AppiButtonState* state);
 | 
				
			||||||
 | 
					    void acquire();
 | 
				
			||||||
 | 
					    void release();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    AppiButtonModeDallasEmulate(AppiButton* parent_app) {
 | 
				
			||||||
 | 
					        app = parent_app;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // TODO open record
 | 
				
			||||||
 | 
					        GpioPin one_wire_pin = ibutton_gpio;
 | 
				
			||||||
 | 
					        GpioPin* one_wire_pin_record = &one_wire_pin;
 | 
				
			||||||
 | 
					        onewire_slave = new OneWireGpioSlave(one_wire_pin_record);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AppiButtonModeDallasEmulate::event(AppiButtonEvent* event, AppiButtonState* state) {
 | 
				
			||||||
 | 
					    if(event->type == AppiButtonEvent::EventTypeTick) {
 | 
				
			||||||
 | 
					        app->blink_red();
 | 
				
			||||||
 | 
					        /*if(onewire_slave->emulate(state->dallas_address, 8)) {
 | 
				
			||||||
 | 
					            app->blink_green();
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					        }*/
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AppiButtonModeDallasEmulate::render(CanvasApi* canvas, AppiButtonState* state) {
 | 
				
			||||||
 | 
					    canvas->set_font(canvas, FontSecondary);
 | 
				
			||||||
 | 
					    canvas->draw_str(canvas, 2, 25, "< dallas emulate");
 | 
				
			||||||
 | 
					    canvas->draw_str(canvas, 2, 37, "unimplemented");
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        char buf[24];
 | 
				
			||||||
 | 
					        sprintf(
 | 
				
			||||||
 | 
					            buf,
 | 
				
			||||||
 | 
					            "%x:%x:%x:%x:%x:%x:%x:%x",
 | 
				
			||||||
 | 
					            state->dallas_address[0],
 | 
				
			||||||
 | 
					            state->dallas_address[1],
 | 
				
			||||||
 | 
					            state->dallas_address[2],
 | 
				
			||||||
 | 
					            state->dallas_address[3],
 | 
				
			||||||
 | 
					            state->dallas_address[4],
 | 
				
			||||||
 | 
					            state->dallas_address[5],
 | 
				
			||||||
 | 
					            state->dallas_address[6],
 | 
				
			||||||
 | 
					            state->dallas_address[7]);
 | 
				
			||||||
 | 
					        canvas->draw_str(canvas, 2, 50, buf);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AppiButtonModeDallasEmulate::acquire() {
 | 
				
			||||||
 | 
					    onewire_slave->start();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AppiButtonModeDallasEmulate::release() {
 | 
				
			||||||
 | 
					    onewire_slave->stop();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										119
									
								
								applications/ibutton/ibutton_mode_dallas_read.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								applications/ibutton/ibutton_mode_dallas_read.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,119 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					#include "ibutton.h"
 | 
				
			||||||
 | 
					#include "one_wire_gpio.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class AppiButtonModeDallasRead : public AppTemplateMode<AppiButtonState, AppiButtonEvent> {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    const char* name = "dallas read";
 | 
				
			||||||
 | 
					    AppiButton* app;
 | 
				
			||||||
 | 
					    OneWireGpio* onewire;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void event(AppiButtonEvent* event, AppiButtonState* state);
 | 
				
			||||||
 | 
					    void render(CanvasApi* canvas, AppiButtonState* state);
 | 
				
			||||||
 | 
					    void acquire();
 | 
				
			||||||
 | 
					    void release();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    AppiButtonModeDallasRead(AppiButton* parent_app) {
 | 
				
			||||||
 | 
					        app = parent_app;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // TODO open record
 | 
				
			||||||
 | 
					        GpioPin one_wire_pin = ibutton_gpio;
 | 
				
			||||||
 | 
					        GpioPin* one_wire_pin_record = &one_wire_pin;
 | 
				
			||||||
 | 
					        onewire = new OneWireGpio(one_wire_pin_record);
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint8_t crc_8(uint8_t* buffer, uint8_t count);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AppiButtonModeDallasRead::event(AppiButtonEvent* event, AppiButtonState* state) {
 | 
				
			||||||
 | 
					    if(event->type == AppiButtonEvent::EventTypeTick) {
 | 
				
			||||||
 | 
					        bool result = 0;
 | 
				
			||||||
 | 
					        uint8_t address[8];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        osKernelLock();
 | 
				
			||||||
 | 
					        result = onewire->reset();
 | 
				
			||||||
 | 
					        osKernelUnlock();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(result) {
 | 
				
			||||||
 | 
					            printf("device on line\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            delay(50);
 | 
				
			||||||
 | 
					            osKernelLock();
 | 
				
			||||||
 | 
					            onewire->write(0x33);
 | 
				
			||||||
 | 
					            onewire->read_bytes(address, 8);
 | 
				
			||||||
 | 
					            osKernelUnlock();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            printf("address: %x", address[0]);
 | 
				
			||||||
 | 
					            for(uint8_t i = 1; i < 8; i++) {
 | 
				
			||||||
 | 
					                printf(":%x", address[i]);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            printf("\n");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            printf("crc8: %x\n", crc_8(address, 7));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(crc_8(address, 8) == 0) {
 | 
				
			||||||
 | 
					                printf("CRC valid\n");
 | 
				
			||||||
 | 
					                memcpy(app->state.dallas_address, address, 8);
 | 
				
			||||||
 | 
					                app->blink_green();
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                printf("CRC invalid\n");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AppiButtonModeDallasRead::render(CanvasApi* canvas, AppiButtonState* state) {
 | 
				
			||||||
 | 
					    canvas->set_font(canvas, FontSecondary);
 | 
				
			||||||
 | 
					    canvas->draw_str(canvas, 2, 25, "dallas read >");
 | 
				
			||||||
 | 
					    canvas->draw_str(canvas, 2, 37, "touch me, iButton");
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        char buf[24];
 | 
				
			||||||
 | 
					        sprintf(
 | 
				
			||||||
 | 
					            buf,
 | 
				
			||||||
 | 
					            "%x:%x:%x:%x:%x:%x:%x:%x",
 | 
				
			||||||
 | 
					            state->dallas_address[0],
 | 
				
			||||||
 | 
					            state->dallas_address[1],
 | 
				
			||||||
 | 
					            state->dallas_address[2],
 | 
				
			||||||
 | 
					            state->dallas_address[3],
 | 
				
			||||||
 | 
					            state->dallas_address[4],
 | 
				
			||||||
 | 
					            state->dallas_address[5],
 | 
				
			||||||
 | 
					            state->dallas_address[6],
 | 
				
			||||||
 | 
					            state->dallas_address[7]);
 | 
				
			||||||
 | 
					        canvas->draw_str(canvas, 2, 50, buf);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint8_t AppiButtonModeDallasRead::crc_8(uint8_t* buffer, uint8_t count) {
 | 
				
			||||||
 | 
					    const uint8_t maxim_crc8_table[256] = {
 | 
				
			||||||
 | 
					        0,   94,  188, 226, 97,  63,  221, 131, 194, 156, 126, 32,  163, 253, 31,  65,  157, 195,
 | 
				
			||||||
 | 
					        33,  127, 252, 162, 64,  30,  95,  1,   227, 189, 62,  96,  130, 220, 35,  125, 159, 193,
 | 
				
			||||||
 | 
					        66,  28,  254, 160, 225, 191, 93,  3,   128, 222, 60,  98,  190, 224, 2,   92,  223, 129,
 | 
				
			||||||
 | 
					        99,  61,  124, 34,  192, 158, 29,  67,  161, 255, 70,  24,  250, 164, 39,  121, 155, 197,
 | 
				
			||||||
 | 
					        132, 218, 56,  102, 229, 187, 89,  7,   219, 133, 103, 57,  186, 228, 6,   88,  25,  71,
 | 
				
			||||||
 | 
					        165, 251, 120, 38,  196, 154, 101, 59,  217, 135, 4,   90,  184, 230, 167, 249, 27,  69,
 | 
				
			||||||
 | 
					        198, 152, 122, 36,  248, 166, 68,  26,  153, 199, 37,  123, 58,  100, 134, 216, 91,  5,
 | 
				
			||||||
 | 
					        231, 185, 140, 210, 48,  110, 237, 179, 81,  15,  78,  16,  242, 172, 47,  113, 147, 205,
 | 
				
			||||||
 | 
					        17,  79,  173, 243, 112, 46,  204, 146, 211, 141, 111, 49,  178, 236, 14,  80,  175, 241,
 | 
				
			||||||
 | 
					        19,  77,  206, 144, 114, 44,  109, 51,  209, 143, 12,  82,  176, 238, 50,  108, 142, 208,
 | 
				
			||||||
 | 
					        83,  13,  239, 177, 240, 174, 76,  18,  145, 207, 45,  115, 202, 148, 118, 40,  171, 245,
 | 
				
			||||||
 | 
					        23,  73,  8,   86,  180, 234, 105, 55,  213, 139, 87,  9,   235, 181, 54,  104, 138, 212,
 | 
				
			||||||
 | 
					        149, 203, 41,  119, 244, 170, 72,  22,  233, 183, 85,  11,  136, 214, 52,  106, 43,  117,
 | 
				
			||||||
 | 
					        151, 201, 74,  20,  246, 168, 116, 42,  200, 150, 21,  75,  169, 247, 182, 232, 10,  84,
 | 
				
			||||||
 | 
					        215, 137, 107, 53};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    uint8_t crc = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while(count--) {
 | 
				
			||||||
 | 
					        crc = maxim_crc8_table[(crc ^ *buffer++)];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return crc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AppiButtonModeDallasRead::acquire() {
 | 
				
			||||||
 | 
					    onewire->start();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AppiButtonModeDallasRead::release() {
 | 
				
			||||||
 | 
					    onewire->stop();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										11
									
								
								applications/ibutton/ibutton_mode_template.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								applications/ibutton/ibutton_mode_template.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// template for modes
 | 
				
			||||||
 | 
					template <class TState, class TEvents> class AppTemplateMode {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    const char* name;
 | 
				
			||||||
 | 
					    virtual void event(TEvents* event, TState* state) = 0;
 | 
				
			||||||
 | 
					    virtual void render(CanvasApi* canvas, TState* state) = 0;
 | 
				
			||||||
 | 
					    virtual void acquire() = 0;
 | 
				
			||||||
 | 
					    virtual void release() = 0;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
							
								
								
									
										130
									
								
								applications/ibutton/one_wire_gpio.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								applications/ibutton/one_wire_gpio.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,130 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					#include "flipper.h"
 | 
				
			||||||
 | 
					#include "flipper_v2.h"
 | 
				
			||||||
 | 
					#include "one_wire_timings.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class OneWireGpio {
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    GpioPin* gpio;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    OneWireGpio(GpioPin* one_wire_gpio);
 | 
				
			||||||
 | 
					    ~OneWireGpio();
 | 
				
			||||||
 | 
					    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 start(void);
 | 
				
			||||||
 | 
					    void stop(void);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OneWireGpio::OneWireGpio(GpioPin* one_wire_gpio) {
 | 
				
			||||||
 | 
					    gpio = one_wire_gpio;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OneWireGpio::~OneWireGpio() {
 | 
				
			||||||
 | 
					    stop();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OneWireGpio::start(void) {
 | 
				
			||||||
 | 
					    gpio_init(gpio, GpioModeOutputOpenDrain);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OneWireGpio::stop(void) {
 | 
				
			||||||
 | 
					    gpio_init(gpio, GpioModeAnalog);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool OneWireGpio::reset(void) {
 | 
				
			||||||
 | 
					    uint8_t r;
 | 
				
			||||||
 | 
					    uint8_t retries = 125;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // wait until the gpio is high
 | 
				
			||||||
 | 
					    gpio_write(gpio, true);
 | 
				
			||||||
 | 
					    do {
 | 
				
			||||||
 | 
					        if(--retries == 0) return 0;
 | 
				
			||||||
 | 
					        delay_us(2);
 | 
				
			||||||
 | 
					    } while(!gpio_read(gpio));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // pre delay
 | 
				
			||||||
 | 
					    delay_us(OneWireTiming::RESET_DELAY_PRE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // drive low
 | 
				
			||||||
 | 
					    gpio_write(gpio, false);
 | 
				
			||||||
 | 
					    delay_us(OneWireTiming::RESET_DRIVE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // release
 | 
				
			||||||
 | 
					    gpio_write(gpio, true);
 | 
				
			||||||
 | 
					    delay_us(OneWireTiming::RESET_RELEASE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // read and post delay
 | 
				
			||||||
 | 
					    r = !gpio_read(gpio);
 | 
				
			||||||
 | 
					    delay_us(OneWireTiming::RESET_DELAY_POST);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return r;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool OneWireGpio::read_bit(void) {
 | 
				
			||||||
 | 
					    bool result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // drive low
 | 
				
			||||||
 | 
					    gpio_write(gpio, false);
 | 
				
			||||||
 | 
					    delay_us(OneWireTiming::READ_DRIVE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // release
 | 
				
			||||||
 | 
					    gpio_write(gpio, true);
 | 
				
			||||||
 | 
					    delay_us(OneWireTiming::READ_RELEASE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // read and post delay
 | 
				
			||||||
 | 
					    result = gpio_read(gpio);
 | 
				
			||||||
 | 
					    delay_us(OneWireTiming::READ_DELAY_POST);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OneWireGpio::write_bit(bool value) {
 | 
				
			||||||
 | 
					    if(value) {
 | 
				
			||||||
 | 
					        // drive low
 | 
				
			||||||
 | 
					        gpio_write(gpio, false);
 | 
				
			||||||
 | 
					        delay_us(OneWireTiming::WRITE_1_DRIVE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // release
 | 
				
			||||||
 | 
					        gpio_write(gpio, true);
 | 
				
			||||||
 | 
					        delay_us(OneWireTiming::WRITE_1_RELEASE);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        // drive low
 | 
				
			||||||
 | 
					        gpio_write(gpio, false);
 | 
				
			||||||
 | 
					        delay_us(OneWireTiming::WRITE_0_DRIVE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // release
 | 
				
			||||||
 | 
					        gpio_write(gpio, true);
 | 
				
			||||||
 | 
					        delay_us(OneWireTiming::WRITE_0_RELEASE);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					uint8_t OneWireGpio::read(void) {
 | 
				
			||||||
 | 
					    uint8_t result = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for(uint8_t bitMask = 0x01; bitMask; bitMask <<= 1) {
 | 
				
			||||||
 | 
					        if(read_bit()) {
 | 
				
			||||||
 | 
					            result |= bitMask;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OneWireGpio::read_bytes(uint8_t* buffer, uint16_t count) {
 | 
				
			||||||
 | 
					    for(uint16_t i = 0; i < count; i++) {
 | 
				
			||||||
 | 
					        buffer[i] = read();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OneWireGpio::write(uint8_t value) {
 | 
				
			||||||
 | 
					    uint8_t bitMask;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for(bitMask = 0x01; bitMask; bitMask <<= 1) {
 | 
				
			||||||
 | 
					        write_bit((bitMask & value) ? 1 : 0);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										177
									
								
								applications/ibutton/one_wire_slave_gpio.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										177
									
								
								applications/ibutton/one_wire_slave_gpio.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,177 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					#include "flipper.h"
 | 
				
			||||||
 | 
					#include "flipper_v2.h"
 | 
				
			||||||
 | 
					#include "one_wire_timings.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class OneWireGpioSlave {
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    GpioPin* gpio;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    OneWireGpioSlave(GpioPin* one_wire_gpio);
 | 
				
			||||||
 | 
					    ~OneWireGpioSlave();
 | 
				
			||||||
 | 
					    void start(void);
 | 
				
			||||||
 | 
					    void stop(void);
 | 
				
			||||||
 | 
					    bool emulate(uint8_t* buffer, uint8_t length);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool check_reset(void);
 | 
				
			||||||
 | 
					    bool show_presence(void);
 | 
				
			||||||
 | 
					    bool receive_and_process_cmd(void);
 | 
				
			||||||
 | 
					    bool receive(uint8_t* data, const uint8_t data_length);
 | 
				
			||||||
 | 
					    bool receiveBit(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool overdrive_mode = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    OneWiteTimeType wait_while_gpio(volatile OneWiteTimeType retries, const bool pin_value);
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OneWireGpioSlave::OneWireGpioSlave(GpioPin* one_wire_gpio) {
 | 
				
			||||||
 | 
					    gpio = one_wire_gpio;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OneWireGpioSlave::~OneWireGpioSlave() {
 | 
				
			||||||
 | 
					    stop();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OneWireGpioSlave::start(void) {
 | 
				
			||||||
 | 
					    gpio_init(gpio, GpioModeOutputOpenDrain);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void OneWireGpioSlave::stop(void) {
 | 
				
			||||||
 | 
					    gpio_init(gpio, GpioModeAnalog);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool OneWireGpioSlave::emulate(uint8_t* buffer, uint8_t length) {
 | 
				
			||||||
 | 
					    if(!check_reset()) {
 | 
				
			||||||
 | 
					        printf("reset error\n");
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(!show_presence()) {
 | 
				
			||||||
 | 
					        printf("presence error\n");
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(!receive_and_process_cmd()) {
 | 
				
			||||||
 | 
					        printf("receive_and_process_cmd error\n");
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    printf("ok\n");
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					OneWiteTimeType OneWireGpioSlave::wait_while_gpio(OneWiteTimeType time, const bool pin_value) {
 | 
				
			||||||
 | 
					    uint32_t start = DWT->CYCCNT;
 | 
				
			||||||
 | 
					    uint32_t time_ticks = time * (SystemCoreClock / 1000000.0f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    while(((DWT->CYCCNT - start) < time_ticks)) {
 | 
				
			||||||
 | 
					        if(gpio_read(gpio) != pin_value) {
 | 
				
			||||||
 | 
					            uint32_t time = (DWT->CYCCNT - start);
 | 
				
			||||||
 | 
					            time /= (SystemCoreClock / 1000000.0f);
 | 
				
			||||||
 | 
					            return time;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool OneWireGpioSlave::check_reset(void) {
 | 
				
			||||||
 | 
					    while(gpio_read(gpio) == true) {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /*if(wait_while_gpio(OneWireEmulateTiming::RESET_TIMEOUT * 20, true) == 0) {
 | 
				
			||||||
 | 
					        printf("RESET_TIMEOUT\n");
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const OneWiteTimeType time_remaining =
 | 
				
			||||||
 | 
					        wait_while_gpio(OneWireEmulateTiming::RESET_MAX[0], false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(time_remaining == 0) {
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(overdrive_mode && ((OneWireEmulateTiming::RESET_MAX[0] -
 | 
				
			||||||
 | 
					                           OneWireEmulateTiming::RESET_MIN[0]) <= time_remaining)) {
 | 
				
			||||||
 | 
					        // normal reset detected
 | 
				
			||||||
 | 
					        overdrive_mode = false;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool result = (time_remaining <= OneWireEmulateTiming::RESET_MAX[0]) &&
 | 
				
			||||||
 | 
					                  time_remaining >= OneWireEmulateTiming::RESET_MIN[overdrive_mode];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool OneWireGpioSlave::show_presence(void) {
 | 
				
			||||||
 | 
					    wait_while_gpio(OneWireEmulateTiming::PRESENCE_TIMEOUT, true);
 | 
				
			||||||
 | 
					    gpio_write(gpio, false);
 | 
				
			||||||
 | 
					    delay_us(OneWireEmulateTiming::PRESENCE_MIN[overdrive_mode]);
 | 
				
			||||||
 | 
					    gpio_write(gpio, true);
 | 
				
			||||||
 | 
					    /*OneWiteTimeType wait_time = OneWireEmulateTiming::PRESENCE_MAX[overdrive_mode] -
 | 
				
			||||||
 | 
					                                OneWireEmulateTiming::PRESENCE_MIN[overdrive_mode];
 | 
				
			||||||
 | 
					    if(wait_while_gpio(wait_time, false) == 0) {
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool OneWireGpioSlave::receive_and_process_cmd(void) {
 | 
				
			||||||
 | 
					    uint8_t cmd;
 | 
				
			||||||
 | 
					    receive(&cmd, 1);
 | 
				
			||||||
 | 
					    printf("cmd %x\n", cmd);
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool OneWireGpioSlave::receiveBit(void) {
 | 
				
			||||||
 | 
					    // wait while bus is HIGH
 | 
				
			||||||
 | 
					    OneWiteTimeType time = OneWireEmulateTiming::SLOT_MAX[overdrive_mode];
 | 
				
			||||||
 | 
					    time = wait_while_gpio(time, true);
 | 
				
			||||||
 | 
					    if(time == 0) {
 | 
				
			||||||
 | 
					        printf("RESET_IN_PROGRESS\n");
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    /*while ((DIRECT_READ(pin_baseReg, pin_bitMask) == 0) && (--retries != 0));
 | 
				
			||||||
 | 
					    if (retries == 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        _error = Error::RESET_IN_PROGRESS;
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // wait while bus is LOW
 | 
				
			||||||
 | 
					    time = OneWireEmulateTiming::MSG_HIGH_TIMEOUT;
 | 
				
			||||||
 | 
					    time = wait_while_gpio(time, false);
 | 
				
			||||||
 | 
					    if(time == 0) {
 | 
				
			||||||
 | 
					        printf("TIMEOUT_HIGH\n");
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    /*while ((DIRECT_READ(pin_baseReg, pin_bitMask) != 0) && (--retries != 0));
 | 
				
			||||||
 | 
					    if (retries == 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        _error = Error::AWAIT_TIMESLOT_TIMEOUT_HIGH;
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    }*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // wait a specific time to do a read (data is valid by then), // first difference to inner-loop of write()
 | 
				
			||||||
 | 
					    time = OneWireEmulateTiming::READ_MIN[overdrive_mode];
 | 
				
			||||||
 | 
					    time = wait_while_gpio(time, true);
 | 
				
			||||||
 | 
					    //while ((DIRECT_READ(pin_baseReg, pin_bitMask) == 0) && (--retries != 0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return (time > 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool OneWireGpioSlave::receive(uint8_t* data, const uint8_t data_length) {
 | 
				
			||||||
 | 
					    uint8_t bytes_received = 0;
 | 
				
			||||||
 | 
					    for(; bytes_received < data_length; ++bytes_received) {
 | 
				
			||||||
 | 
					        uint8_t value = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for(uint8_t bitMask = 0x01; bitMask != 0; bitMask <<= 1) {
 | 
				
			||||||
 | 
					            if(receiveBit()) value |= bitMask;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        data[bytes_received] = value;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return (bytes_received != data_length);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										54
									
								
								applications/ibutton/one_wire_timings.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								applications/ibutton/one_wire_timings.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,54 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class __OneWireTiming {
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
					    constexpr static const uint16_t TIMING_A = 6;
 | 
				
			||||||
 | 
					    constexpr static const uint16_t TIMING_B = 64;
 | 
				
			||||||
 | 
					    constexpr static const uint16_t TIMING_C = 60;
 | 
				
			||||||
 | 
					    constexpr static const uint16_t TIMING_D = 10;
 | 
				
			||||||
 | 
					    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 = __OneWireTiming::TIMING_A;
 | 
				
			||||||
 | 
					    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_TIMEOUT = {5000};
 | 
				
			||||||
 | 
					    constexpr static const OneWiteTimeType RESET_MIN[2] = {430, 48};
 | 
				
			||||||
 | 
					    constexpr static const OneWiteTimeType RESET_MAX[2] = {960, 80};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    constexpr static const OneWiteTimeType PRESENCE_TIMEOUT = {20};
 | 
				
			||||||
 | 
					    constexpr static const OneWiteTimeType PRESENCE_MIN[2] = {160, 8};
 | 
				
			||||||
 | 
					    constexpr static const OneWiteTimeType PRESENCE_MAX[2] = {480, 32};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    constexpr static const OneWiteTimeType MSG_HIGH_TIMEOUT = {15000};
 | 
				
			||||||
 | 
					    constexpr static const OneWiteTimeType SLOT_MAX[2] = {135, 30};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    constexpr static const OneWiteTimeType READ_MIN[2] = {20, 4};
 | 
				
			||||||
 | 
					    constexpr static const OneWiteTimeType READ_MAX[2] = {60, 10};
 | 
				
			||||||
 | 
					    constexpr static const OneWiteTimeType WRITE_ZERO[2] = {30, 8};
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
@ -394,6 +394,11 @@ void music_player(void* p) {
 | 
				
			|||||||
    MusicDemoContext context = {.state_mutex = &state_mutex, .event_queue = event_queue};
 | 
					    MusicDemoContext context = {.state_mutex = &state_mutex, .event_queue = event_queue};
 | 
				
			||||||
    osThreadId_t player = osThreadNew(music_player_thread, &context, &player_attr);
 | 
					    osThreadId_t player = osThreadNew(music_player_thread, &context, &player_attr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if(player == NULL) {
 | 
				
			||||||
 | 
					        printf("cannot create player thread\n");
 | 
				
			||||||
 | 
					        furiac_exit(NULL);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    MusicDemoEvent event;
 | 
					    MusicDemoEvent event;
 | 
				
			||||||
    while(1) {
 | 
					    while(1) {
 | 
				
			||||||
        osStatus_t event_status = osMessageQueueGet(event_queue, &event, NULL, 100);
 | 
					        osStatus_t event_status = osMessageQueueGet(event_queue, &event, NULL, 100);
 | 
				
			||||||
 | 
				
			|||||||
@ -29,3 +29,4 @@ const GpioPin led_gpio[3] = {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const GpioPin backlight_gpio = {DISPLAY_BACKLIGHT_GPIO_Port, DISPLAY_BACKLIGHT_Pin};
 | 
					const GpioPin backlight_gpio = {DISPLAY_BACKLIGHT_GPIO_Port, DISPLAY_BACKLIGHT_Pin};
 | 
				
			||||||
const GpioPin vibro_gpio = {VIBRO_GPIO_Port, VIBRO_Pin};
 | 
					const GpioPin vibro_gpio = {VIBRO_GPIO_Port, VIBRO_Pin};
 | 
				
			||||||
 | 
					const GpioPin ibutton_gpio = {iButton_GPIO_Port, iButton_Pin};
 | 
				
			||||||
 | 
				
			|||||||
@ -11,3 +11,4 @@ extern const bool input_invert[GPIO_INPUT_PINS_COUNT];
 | 
				
			|||||||
extern const GpioPin led_gpio[3];
 | 
					extern const GpioPin led_gpio[3];
 | 
				
			||||||
extern const GpioPin backlight_gpio;
 | 
					extern const GpioPin backlight_gpio;
 | 
				
			||||||
extern const GpioPin vibro_gpio;
 | 
					extern const GpioPin vibro_gpio;
 | 
				
			||||||
 | 
					extern const GpioPin ibutton_gpio;
 | 
				
			||||||
@ -27,3 +27,4 @@ const GpioPin led_gpio[3] = {
 | 
				
			|||||||
const GpioPin backlight_gpio = {DISPLAY_BACKLIGHT_GPIO_Port, DISPLAY_BACKLIGHT_Pin};
 | 
					const GpioPin backlight_gpio = {DISPLAY_BACKLIGHT_GPIO_Port, DISPLAY_BACKLIGHT_Pin};
 | 
				
			||||||
const GpioPin sd_cs_gpio = {SD_CS_GPIO_Port, SD_CS_Pin};
 | 
					const GpioPin sd_cs_gpio = {SD_CS_GPIO_Port, SD_CS_Pin};
 | 
				
			||||||
const GpioPin vibro_gpio = {VIBRO_GPIO_Port, VIBRO_Pin};
 | 
					const GpioPin vibro_gpio = {VIBRO_GPIO_Port, VIBRO_Pin};
 | 
				
			||||||
 | 
					const GpioPin ibutton_gpio = {iBTN_GPIO_Port, iBTN_Pin};
 | 
				
			||||||
 | 
				
			|||||||
@ -12,3 +12,4 @@ extern const GpioPin led_gpio[3];
 | 
				
			|||||||
extern const GpioPin backlight_gpio;
 | 
					extern const GpioPin backlight_gpio;
 | 
				
			||||||
extern const GpioPin sd_cs_gpio;
 | 
					extern const GpioPin sd_cs_gpio;
 | 
				
			||||||
extern const GpioPin vibro_gpio;
 | 
					extern const GpioPin vibro_gpio;
 | 
				
			||||||
 | 
					extern const GpioPin ibutton_gpio;
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user