mirror of
https://github.com/UberGuidoZ/Flipper.git
synced 2026-09-18 18:41:31 +00:00
Removing FAP files (use FlipC or Official store!)
This commit is contained in:
@@ -0,0 +1,149 @@
|
||||
#include "gpio_simple_motor.h"
|
||||
#include "../fbp.h"
|
||||
|
||||
static const uint16_t BT_SERIAL_BUFFER_SIZE = 128;
|
||||
static const uint32_t DEFAULT_FREQ = 1000;
|
||||
static const FuriHalPwmOutputId DEFAULT_PWM_OUTPUT_ID = FuriHalPwmOutputIdTim1PA7;
|
||||
|
||||
struct GPIOSimpleMotor {
|
||||
View* view;
|
||||
FBP* fbp;
|
||||
|
||||
uint8_t current_pwm_duty;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char* display_text_1;
|
||||
char* display_text_2;
|
||||
char* display_text_3;
|
||||
} GPIOSimpleMotorModel;
|
||||
|
||||
|
||||
static void process_general_command(TCodeCommand command, GPIOSimpleMotor* motor) {
|
||||
if (command.command_type == Magnitude && command.data.magnitude_command.motion_type == Vibrate && command.data.magnitude_command.channel_id == 0) {
|
||||
// just enable vibration on X
|
||||
uint8_t new_duty = (uint8_t) (command.data.magnitude_command.magnitude * 100);
|
||||
if (new_duty > 100) {
|
||||
new_duty = 100;
|
||||
}
|
||||
FURI_LOG_D(TAG, "Setting vibration power on %u", new_duty);
|
||||
|
||||
// using Pulse-Widht Modulation to control a motor via a transistor
|
||||
// just google for a typical arduino + PWM + motor scheme
|
||||
if (new_duty == 0) {
|
||||
furi_hal_pwm_stop(DEFAULT_PWM_OUTPUT_ID);
|
||||
} else if (motor->current_pwm_duty == 0) {
|
||||
furi_hal_pwm_start(DEFAULT_PWM_OUTPUT_ID, DEFAULT_FREQ, new_duty);
|
||||
} else {
|
||||
furi_hal_pwm_set_params(DEFAULT_PWM_OUTPUT_ID, DEFAULT_FREQ, new_duty);
|
||||
}
|
||||
motor->current_pwm_duty = new_duty;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static uint16_t bt_serial_event_callback(SerialServiceEvent event, void* context) {
|
||||
furi_assert(context);
|
||||
GPIOSimpleMotor* motor = context;
|
||||
|
||||
if(event.event == SerialServiceEventTypeDataReceived) {
|
||||
TCodeCommandArray commands = tcode_decode(event.data.buffer, event.data.size);
|
||||
FURI_LOG_D(TAG, "Decoded commands array size: %u", commands.size);
|
||||
for (uint16_t i = 0; i < commands.size; i++) {
|
||||
FURI_LOG_D(TAG, "Command #%u, type: %u\n", i, commands.commands[i].command_type);
|
||||
}
|
||||
for (uint16_t i = 0; i < commands.size; i++) {
|
||||
// looking for first vibro command to execute
|
||||
TCodeCommand current_command = commands.commands[i];
|
||||
TCodeCommandType type = current_command.command_type;
|
||||
if ((type == Magnitude || type == MagnitudeSpeed || type == MagnitudeTimeInterval)) {
|
||||
process_general_command(current_command, motor);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool input_callback(InputEvent* event, void* ctx) {
|
||||
furi_assert(ctx);
|
||||
GPIOSimpleMotor* motor = ctx;
|
||||
if(event->key == InputKeyBack) {
|
||||
furi_hal_bt_serial_set_event_callback(0, NULL, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (event->key == InputKeyOk) {
|
||||
if (furi_hal_bt_is_active()) {
|
||||
FURI_LOG_D(TAG, "BT is working, hijacking the serial connection...");
|
||||
furi_hal_bt_start_advertising();
|
||||
furi_hal_bt_serial_set_event_callback(BT_SERIAL_BUFFER_SIZE, bt_serial_event_callback, motor);
|
||||
|
||||
with_view_model(
|
||||
motor->view,
|
||||
GPIOSimpleMotorModel * model,
|
||||
{
|
||||
model->display_text_1 = "";
|
||||
model->display_text_2 = "Ready ^_^";
|
||||
model->display_text_3 = "";
|
||||
},
|
||||
true);
|
||||
|
||||
} else {
|
||||
FURI_LOG_E(TAG, "Please, enable the Bluetooth and restart the app");
|
||||
|
||||
with_view_model(
|
||||
motor->view,
|
||||
GPIOSimpleMotorModel * model,
|
||||
{
|
||||
model->display_text_1 = "Error:";
|
||||
model->display_text_2 = "Bluetooth is not enabled";
|
||||
model->display_text_3 = "";
|
||||
},
|
||||
true);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void draw_callback(Canvas* canvas, void* ctx) {
|
||||
furi_assert(ctx);
|
||||
GPIOSimpleMotorModel* app = ctx;
|
||||
canvas_draw_str_aligned(canvas, 64, 24, AlignCenter, AlignCenter, (char*)app->display_text_1);
|
||||
canvas_draw_str_aligned(canvas, 64, 32, AlignCenter, AlignCenter, (char*)app->display_text_2);
|
||||
canvas_draw_str_aligned(canvas, 64, 40, AlignCenter, AlignCenter, (char*)app->display_text_3);
|
||||
}
|
||||
|
||||
GPIOSimpleMotor* gpio_simple_motor_alloc(FBP* fbp) {
|
||||
furi_assert(fbp);
|
||||
GPIOSimpleMotor* motor = malloc(sizeof(GPIOSimpleMotor));
|
||||
motor->view = view_alloc();
|
||||
motor->fbp = fbp;
|
||||
view_set_context(motor->view, motor);
|
||||
view_allocate_model(motor->view, ViewModelTypeLocking, sizeof(GPIOSimpleMotorModel));
|
||||
view_set_draw_callback(motor->view, draw_callback);
|
||||
view_set_input_callback(motor->view, input_callback);
|
||||
|
||||
with_view_model(
|
||||
motor->view,
|
||||
GPIOSimpleMotorModel * model,
|
||||
{
|
||||
model->display_text_1 = "Please, connect the";
|
||||
model->display_text_2 = "transistor base to pin A7!";
|
||||
model->display_text_3 = "Press OK to start";
|
||||
},
|
||||
true);
|
||||
|
||||
return motor;
|
||||
}
|
||||
|
||||
void gpio_simple_motor_free(GPIOSimpleMotor* motor) {
|
||||
furi_assert(motor);
|
||||
furi_hal_pwm_stop(DEFAULT_PWM_OUTPUT_ID);
|
||||
view_free(motor->view);
|
||||
free(motor);
|
||||
}
|
||||
|
||||
View* gpio_simple_motor_get_view(GPIOSimpleMotor* motor) {
|
||||
furi_assert(motor);
|
||||
return motor->view;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#include <gui/view.h>
|
||||
#include <furi_hal_gpio.h>
|
||||
#include <furi_hal_pwm.h>
|
||||
|
||||
typedef struct FBP FBP;
|
||||
typedef struct GPIOSimpleMotor GPIOSimpleMotor;
|
||||
|
||||
GPIOSimpleMotor* gpio_simple_motor_alloc(FBP* fbp);
|
||||
|
||||
void gpio_simple_motor_free(GPIOSimpleMotor* motor_app);
|
||||
|
||||
View* gpio_simple_motor_get_view(GPIOSimpleMotor* motor_app);
|
||||
@@ -0,0 +1,133 @@
|
||||
#include "internal.h"
|
||||
#include "../fbp.h"
|
||||
|
||||
static const uint16_t BT_SERIAL_BUFFER_SIZE = 128;
|
||||
|
||||
struct FlipperVibrator {
|
||||
View* view;
|
||||
FBP* fbp;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char* display_text;
|
||||
} FlipperVibratorModel;
|
||||
|
||||
|
||||
static void process_general_command(TCodeCommand command) {
|
||||
if (command.command_type == Magnitude && command.data.magnitude_command.motion_type == Vibrate && command.data.magnitude_command.channel_id == 0) {
|
||||
furi_hal_vibro_on(command.data.magnitude_command.magnitude > 0.1f);
|
||||
return;
|
||||
}
|
||||
|
||||
if (command.command_type == MagnitudeSpeed && command.data.magnitude_speed_command.motion_type == Vibrate && command.data.magnitude_speed_command.channel_id == 0) {
|
||||
furi_hal_vibro_on(command.data.magnitude_speed_command.magnitude > 0.1f);
|
||||
return;
|
||||
}
|
||||
|
||||
if (command.command_type == MagnitudeTimeInterval && command.data.magnitude_time_interval_command.motion_type == Vibrate && command.data.magnitude_time_interval_command.channel_id == 0) {
|
||||
furi_hal_vibro_on(command.data.magnitude_time_interval_command.magnitude > 0.1f);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint16_t bt_serial_event_callback(SerialServiceEvent event, void* context) {
|
||||
furi_assert(context);
|
||||
FlipperVibrator* flipper_vibrator = context;
|
||||
UNUSED(flipper_vibrator);
|
||||
|
||||
if(event.event == SerialServiceEventTypeDataReceived) {
|
||||
FURI_LOG_D(TAG, "SerialServiceEventTypeDataReceived");
|
||||
FURI_LOG_D(TAG, "Size: %u", event.data.size);
|
||||
FURI_LOG_D(TAG, "Data: ");
|
||||
for (size_t i = 0; i < event.data.size; i++)
|
||||
{
|
||||
printf("%X ", event.data.buffer[i]);
|
||||
}
|
||||
printf("\r\n");
|
||||
|
||||
TCodeCommandArray commands = tcode_decode(event.data.buffer, event.data.size);
|
||||
FURI_LOG_D(TAG, "Decoded commands array size: %u", commands.size);
|
||||
for (uint16_t i = 0; i < commands.size; i++) {
|
||||
FURI_LOG_D(TAG, "Command #%u, type: %u\n", i, commands.commands[i].command_type);
|
||||
}
|
||||
for (uint16_t i = 0; i < commands.size; i++) {
|
||||
// looking for first vibro command to execute
|
||||
TCodeCommand current_command = commands.commands[i];
|
||||
TCodeCommandType type = current_command.command_type;
|
||||
if ((type == Magnitude || type == MagnitudeSpeed || type == MagnitudeTimeInterval)) {
|
||||
process_general_command(current_command);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool input_callback(InputEvent* event, void* ctx) {
|
||||
furi_assert(ctx);
|
||||
FlipperVibrator* flipper_vibrator = ctx;
|
||||
if(event->key == InputKeyBack) {
|
||||
furi_hal_bt_serial_set_event_callback(0, NULL, NULL);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (event->key == InputKeyOk) {
|
||||
if (furi_hal_bt_is_active()) {
|
||||
FURI_LOG_D(TAG, "BT is working, hijacking the serial connection...");
|
||||
furi_hal_bt_start_advertising();
|
||||
furi_hal_bt_serial_set_event_callback(BT_SERIAL_BUFFER_SIZE, bt_serial_event_callback, flipper_vibrator);
|
||||
|
||||
with_view_model(
|
||||
flipper_vibrator->view,
|
||||
FlipperVibratorModel * model,
|
||||
{ model->display_text = "Ready ^_^"; },
|
||||
true);
|
||||
|
||||
} else {
|
||||
FURI_LOG_E(TAG, "Please, enable the Bluetooth and restart the app");
|
||||
|
||||
with_view_model(
|
||||
flipper_vibrator->view,
|
||||
FlipperVibratorModel * model,
|
||||
{ model->display_text = "Error: Bluetooth not enabled"; },
|
||||
true);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void draw_callback(Canvas* canvas, void* ctx) {
|
||||
furi_assert(ctx);
|
||||
FlipperVibratorModel* app = ctx;
|
||||
canvas_draw_str_aligned(canvas, 64, 32, AlignCenter, AlignCenter, (char*)app->display_text);
|
||||
}
|
||||
|
||||
FlipperVibrator* flipper_vibrator_alloc(FBP* fbp) {
|
||||
furi_assert(fbp);
|
||||
FlipperVibrator* flipper_vibrator = malloc(sizeof(FlipperVibrator));
|
||||
flipper_vibrator->view = view_alloc();
|
||||
flipper_vibrator->fbp = fbp;
|
||||
view_set_context(flipper_vibrator->view, flipper_vibrator);
|
||||
view_allocate_model(flipper_vibrator->view, ViewModelTypeLocking, sizeof(FlipperVibratorModel));
|
||||
view_set_draw_callback(flipper_vibrator->view, draw_callback);
|
||||
view_set_input_callback(flipper_vibrator->view, input_callback);
|
||||
|
||||
with_view_model(
|
||||
flipper_vibrator->view,
|
||||
FlipperVibratorModel * model,
|
||||
{ model->display_text = "Press OK to start"; },
|
||||
true);
|
||||
|
||||
return flipper_vibrator;
|
||||
}
|
||||
|
||||
void flipper_vibrator_free(FlipperVibrator* flipper_vibrator) {
|
||||
furi_assert(flipper_vibrator);
|
||||
view_free(flipper_vibrator->view);
|
||||
free(flipper_vibrator);
|
||||
}
|
||||
|
||||
View* flipper_vibrator_get_view(FlipperVibrator* flipper_vibrator) {
|
||||
furi_assert(flipper_vibrator);
|
||||
return flipper_vibrator->view;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
#include <gui/view.h>
|
||||
#include <furi_hal_vibro.h>
|
||||
|
||||
typedef struct FBP FBP;
|
||||
typedef struct FlipperVibrator FlipperVibrator;
|
||||
|
||||
FlipperVibrator* flipper_vibrator_alloc(FBP* fbp);
|
||||
|
||||
void flipper_vibrator_free(FlipperVibrator* flipper_vibrator);
|
||||
|
||||
View* flipper_vibrator_get_view(FlipperVibrator* flipper_vibrator);
|
||||
Reference in New Issue
Block a user