Fix crash when no VGM. Use void* context (support more input scenarios).

This commit is contained in:
Derek Jamison 2024-03-24 14:15:04 -05:00
parent 05e629786a
commit 00e2574c5a
2 changed files with 42 additions and 40 deletions

View File

@ -35,7 +35,7 @@ struct ImuController {
ImuControllerQueue queue_message;
FuriMutex* mutex;
Imu* imu;
FuriMessageQueue* event_queue;
void* context;
FuriTimer* timer;
uint32_t button_press_tick[InputKeyMAX];
ButtonState button_state[InputKeyMAX];
@ -59,11 +59,11 @@ static void imu_controller_release(ImuController* controller, InputKey key) {
// If the button was pressed, send a InputTypeShort event
// (otherwise we already sent a InputTypeLong event).
if(controller->button_state[key] == ButtonStatePressed) {
controller->queue_message(controller->event_queue, InputTypeShort, key);
controller->queue_message(controller->context, InputTypeShort, key);
}
// Send a InputTypeRelease event
controller->queue_message(controller->event_queue, InputTypeRelease, key);
controller->queue_message(controller->context, InputTypeRelease, key);
// Reset the button state
controller->button_press_tick[key] = 0;
controller->button_state[key] = ButtonStateReleased;
@ -89,7 +89,7 @@ static void imu_controller_press(ImuController* controller, InputKey key) {
(controller->button_state[key] == ButtonStatePressed &&
duration >= controller->config->button_state_long_ms)) {
// Send a InputTypeLong event
controller->queue_message(controller->event_queue, InputTypeLong, key);
controller->queue_message(controller->context, InputTypeLong, key);
// Update the button state
controller->button_press_tick[key] = furi_get_tick();
controller->button_state[key] = ButtonStateLongPressed;
@ -100,7 +100,7 @@ static void imu_controller_press(ImuController* controller, InputKey key) {
(controller->button_state[key] >= ButtonStateLongPressed &&
duration > controller->config->button_state_repeat_ms)) {
// Send a InputTypeRepeat event
controller->queue_message(controller->event_queue, InputTypeRepeat, key);
controller->queue_message(controller->context, InputTypeRepeat, key);
// Update the button state
controller->button_press_tick[key] = furi_get_tick();
controller->button_state[key] = ButtonStateRepeatPressed;
@ -132,7 +132,7 @@ static void imu_controller_press(ImuController* controller, InputKey key) {
}
// Send a InputTypePress event
controller->queue_message(controller->event_queue, InputTypePress, key);
controller->queue_message(controller->context, InputTypePress, key);
// Update the button state
controller->button_press_tick[key] = furi_get_tick();
@ -155,34 +155,36 @@ static void imu_controller_callback(void* context) {
// Acquire the mutex to access the IMU
furi_mutex_acquire(imu_controller->mutex, FuriWaitForever);
// Get the roll (up/down)
float roll = imu_roll_get(imu_controller->imu);
if(roll > imu_controller->config->roll_up) {
imu_controller_press(imu_controller, InputKeyUp);
} else if(roll < imu_controller->config->roll_down) {
imu_controller_press(imu_controller, InputKeyDown);
}
// If the roll is outside the hysteresis range, release the up and down buttons
else if(
roll < imu_controller->config->roll_up - imu_controller->config->roll_hysteresis &&
roll > imu_controller->config->roll_down + imu_controller->config->roll_hysteresis) {
imu_controller_release(imu_controller, InputKeyUp);
imu_controller_release(imu_controller, InputKeyDown);
}
if(imu_present(imu_controller->imu)) {
// Get the roll (up/down)
float roll = imu_roll_get(imu_controller->imu);
if(roll > imu_controller->config->roll_up) {
imu_controller_press(imu_controller, InputKeyUp);
} else if(roll < imu_controller->config->roll_down) {
imu_controller_press(imu_controller, InputKeyDown);
}
// If the roll is outside the hysteresis range, release the up and down buttons
else if(
roll < imu_controller->config->roll_up - imu_controller->config->roll_hysteresis &&
roll > imu_controller->config->roll_down + imu_controller->config->roll_hysteresis) {
imu_controller_release(imu_controller, InputKeyUp);
imu_controller_release(imu_controller, InputKeyDown);
}
// Get the pitch (left/right)
float pitch = imu_pitch_get(imu_controller->imu);
if(pitch > imu_controller->config->pitch_left) {
imu_controller_press(imu_controller, InputKeyLeft);
} else if(pitch < imu_controller->config->pitch_right) {
imu_controller_press(imu_controller, InputKeyRight);
}
// If the pitch is outside the hysteresis range, release the left and right buttons
else if(
pitch < imu_controller->config->pitch_left - imu_controller->config->pitch_hysteresis &&
pitch > imu_controller->config->pitch_right + imu_controller->config->pitch_hysteresis) {
imu_controller_release(imu_controller, InputKeyLeft);
imu_controller_release(imu_controller, InputKeyRight);
// Get the pitch (left/right)
float pitch = imu_pitch_get(imu_controller->imu);
if(pitch > imu_controller->config->pitch_left) {
imu_controller_press(imu_controller, InputKeyLeft);
} else if(pitch < imu_controller->config->pitch_right) {
imu_controller_press(imu_controller, InputKeyRight);
}
// If the pitch is outside the hysteresis range, release the left and right buttons
else if(
pitch < imu_controller->config->pitch_left - imu_controller->config->pitch_hysteresis &&
pitch > imu_controller->config->pitch_right + imu_controller->config->pitch_hysteresis) {
imu_controller_release(imu_controller, InputKeyLeft);
imu_controller_release(imu_controller, InputKeyRight);
}
}
// Release the mutex, so other threads can access the IMU
@ -203,20 +205,20 @@ static void imu_controller_release_buttons(void* context) {
/**
* @brief Allocate a new IMU controller
* @param event_queue The event queue
* @param context The context for callbacks
* @param config The configuration for pitch and roll
* @param queue_message A callback to queue input messages
* @return The new IMU controller
*/
ImuController* imu_controller_alloc(
FuriMessageQueue* event_queue,
void* context,
const ImuControllerConfig* config,
ImuControllerQueue queue_message) {
ImuController* imu_controller = malloc(sizeof(ImuController));
imu_controller->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
imu_controller->queue_message = queue_message;
imu_controller->imu = imu_alloc();
imu_controller->event_queue = event_queue;
imu_controller->context = context;
imu_controller->config = config;
imu_controller->timer =
furi_timer_alloc(imu_controller_callback, FuriTimerTypePeriodic, imu_controller);

View File

@ -40,21 +40,21 @@ extern const ImuControllerConfig IMU_CONTROLLER_DEFAULT_CONFIG;
/**
* @brief A callback to queue input messages from the IMU controller to the event queue
* @param event_queue The event queue
* @param context The context for the callback
* @param type The input type
* @param key The input key
*/
typedef void (*ImuControllerQueue)(FuriMessageQueue* event_queue, InputType type, InputKey key);
typedef void (*ImuControllerQueue)(void* context, InputType type, InputKey key);
/**
* @brief Allocate a new IMU controller
* @param event_queue The event queue
* @param context The context for callbacks
* @param config The configuration for pitch and roll
* @param queue_message A callback to queue input messages
* @return The new IMU controller
*/
ImuController* imu_controller_alloc(
FuriMessageQueue* event_queue,
void* context,
const ImuControllerConfig* config,
ImuControllerQueue queue_message);