Skip to content

Commit

Permalink
refactor MhZ19App
Browse files Browse the repository at this point in the history
  • Loading branch information
GLinnik21 committed Aug 27, 2023
1 parent 7e494a4 commit 8a9e9a0
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 69 deletions.
66 changes: 33 additions & 33 deletions mh_z19_app.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@

#include "mh_z19_uart_tools.h"

static void mh_z19_app_run(MhZ19App* const context) {
static void mh_z19_app_run(MhZ19App* const app) {
for(bool isRunning = true; isRunning;) {
InputEvent event;
const FuriStatus status =
furi_message_queue_get(context->event_queue, &event, FuriWaitForever);
furi_message_queue_get(app->event_queue, &event, FuriWaitForever);

if((status != FuriStatusOk) || (event.type != InputTypeShort)) {
continue;
Expand All @@ -27,69 +27,69 @@ static void mh_z19_app_run(MhZ19App* const context) {
isRunning = false;
break;
case InputKeyOk:
furi_hal_uart_tx(context->uart_channel, data, sizeof(data));
furi_hal_uart_tx(app->uart.channel, data, sizeof(data));
break;
default:
break;
}
view_port_update(context->view_port);
view_port_update(app->gui_data.view_port);
}
}

MhZ19App* mh_z19_app_init() {
MhZ19App* context = (MhZ19App*)malloc(sizeof(MhZ19App));
MhZ19App* app = (MhZ19App*)malloc(sizeof(MhZ19App));

context->event_queue = furi_message_queue_alloc(8, sizeof(InputEvent));
app->event_queue = furi_message_queue_alloc(8, sizeof(InputEvent));

context->view_port = view_port_alloc();
view_port_draw_callback_set(context->view_port, mh_z19_app_draw_callback, context);
view_port_input_callback_set(context->view_port, mh_z19_app_input_callback, context);
app->gui_data.view_port = view_port_alloc();
view_port_draw_callback_set(app->gui_data.view_port, mh_z19_app_draw_callback, app);
view_port_input_callback_set(app->gui_data.view_port, mh_z19_app_input_callback, app);

context->gui = furi_record_open(RECORD_GUI);
gui_add_view_port(context->gui, context->view_port, GuiLayerFullscreen);
app->gui_data.gui = furi_record_open(RECORD_GUI);
gui_add_view_port(app->gui_data.gui, app->gui_data.view_port, GuiLayerFullscreen);

mh_z19_app_uart_init(context);
mh_z19_app_uart_init(app);

context->rx_stream = furi_stream_buffer_alloc(126, 1);
app->uart.rx_stream = furi_stream_buffer_alloc(126, 1);

context->mutex = furi_mutex_alloc(FuriMutexTypeNormal);
app->thread_data.mutex = furi_mutex_alloc(FuriMutexTypeNormal);

context->worker_thread =
furi_thread_alloc_ex("UARTListenerWorker", 1024, mh_z19_app_uart_listener_worker, context);
furi_thread_start(context->worker_thread);
app->thread_data.worker_thread =
furi_thread_alloc_ex("UARTListenerWorker", 1024, mh_z19_app_uart_listener_worker, app);
furi_thread_start(app->thread_data.worker_thread);

context->ppm = 0;
app->ppm = 0;

return context;
return app;
}

void mh_z19_app_free(MhZ19App* context) {
furi_thread_flags_set(furi_thread_get_id(context->worker_thread), WorkerEventStop);
furi_thread_join(context->worker_thread);
furi_thread_free(context->worker_thread);
void mh_z19_app_free(MhZ19App* app) {
furi_thread_flags_set(furi_thread_get_id(app->thread_data.worker_thread), WorkerEventStop);
furi_thread_join(app->thread_data.worker_thread);
furi_thread_free(app->thread_data.worker_thread);

furi_mutex_free(context->mutex);
furi_mutex_free(app->thread_data.mutex);

furi_stream_buffer_free(context->rx_stream);
furi_stream_buffer_free(app->uart.rx_stream);

mh_z19_app_uart_deinit(context);
mh_z19_app_uart_deinit(app);

furi_record_close(RECORD_GUI);

gui_remove_view_port(context->gui, context->view_port);
view_port_free(context->view_port);
gui_remove_view_port(app->gui_data.gui, app->gui_data.view_port);
view_port_free(app->gui_data.view_port);

furi_message_queue_free(context->event_queue);
furi_message_queue_free(app->event_queue);

free(context);
free(app);
}

int32_t mh_z19_app(void* p) {
UNUSED(p);

MhZ19App* context = mh_z19_app_init();
mh_z19_app_run(context);
mh_z19_app_free(context);
MhZ19App* app = mh_z19_app_init();
mh_z19_app_run(app);
mh_z19_app_free(app);

return 0;
}
32 changes: 24 additions & 8 deletions mh_z19_app_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,34 @@ typedef enum MhZ19UartState {
MhZ19UartStateCollectPacket,
} MhZ19UartState;

struct MhZ19App {
FuriMessageQueue* event_queue;
ViewPort* view_port;
Gui* gui;
FuriHalUartId uart_channel;
MhZ19UartState uart_state;
typedef struct MhZ19Uart {
FuriHalUartId channel;
MhZ19UartState state;
FuriStreamBuffer* rx_stream;
} MhZ19Uart;

typedef struct MhZ19ThreadData {
FuriMutex* mutex;
FuriThread* worker_thread;
uint32_t ppm;
} MhZ19ThreadData;

typedef struct MhZ19GuiData {
ViewPort* view_port;
Gui* gui;
} MhZ19GuiData;

typedef struct MhZ19PowerData {
bool otg_was_previously_enabled;
bool is_5V_enabled;
} MhZ19PowerData;

struct MhZ19App {
FuriMessageQueue* event_queue;
uint32_t ppm;
MhZ19Uart uart;
MhZ19ThreadData thread_data;
MhZ19GuiData gui_data;
MhZ19PowerData power_data;
};

typedef enum MhZ19WorkerEventFlags {
Expand All @@ -31,5 +47,5 @@ typedef enum MhZ19WorkerEventFlags {
} MhZ19WorkerEventFlags;

MhZ19App* mh_z19_app_init();
void mh_z19_app_free(MhZ19App* context);
void mh_z19_app_free(MhZ19App* app);
int32_t mh_z19_app(void* p);
53 changes: 27 additions & 26 deletions mh_z19_uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,62 +5,63 @@
#include "mh_z19_app_i.h"
#include "mh_z19_uart_tools.h"

static void mh_z19_app_uart_enable_5V(MhZ19App* app) {
app->otg_was_previously_enabled = furi_hal_power_is_otg_enabled();
static void mh_z19_app_uart_power_enable(MhZ19PowerData* power_data) {
power_data->otg_was_previously_enabled = furi_hal_power_is_otg_enabled();
furi_hal_power_enable_otg();
app->is_5V_enabled = furi_hal_power_is_otg_enabled() || furi_hal_power_is_charging();
power_data->is_5V_enabled = furi_hal_power_is_otg_enabled() || furi_hal_power_is_charging();
}

static void mh_z19_app_uart_restore_5V_state(MhZ19App* app) {
if(app->is_5V_enabled && !app->otg_was_previously_enabled) {
static void mh_z19_app_uart_power_restore(MhZ19PowerData* power_data) {
if(power_data->is_5V_enabled && !power_data->otg_was_previously_enabled) {
furi_hal_power_disable_otg();
}
}

void mh_z19_app_uart_init(MhZ19App* app) {
app->uart_state = MhZ19UartStateWaitStart;
app->uart.state = MhZ19UartStateWaitStart;
furi_hal_console_disable();

mh_z19_app_uart_enable_5V(app);
mh_z19_app_uart_power_enable(&(app->power_data));

furi_hal_uart_deinit((app->uart_channel = FuriHalUartIdUSART1));
furi_hal_uart_init(app->uart_channel, MH_Z19_BAUDRATE);
furi_hal_uart_set_irq_cb(app->uart_channel, mh_z19_app_uart_callback, app);
furi_hal_uart_deinit((app->uart.channel = FuriHalUartIdUSART1));
furi_hal_uart_init(app->uart.channel, MH_Z19_BAUDRATE);
furi_hal_uart_set_irq_cb(app->uart.channel, mh_z19_app_uart_callback, app);
}

void mh_z19_app_uart_deinit(MhZ19App* app) {
mh_z19_app_uart_restore_5V_state(app);
mh_z19_app_uart_power_restore(&(app->power_data));
furi_hal_console_enable();
furi_hal_uart_deinit(app->uart_channel);
furi_hal_uart_deinit(app->uart.channel);
}

void mh_z19_app_uart_callback(UartIrqEvent event, uint8_t data, void* context) {
furi_assert(context);
MhZ19App* app = context;

if(event == UartIrqEventRXNE) {
switch(app->uart_state) {
switch(app->uart.state) {
case MhZ19UartStateWaitStart:
if(data == MH_Z19_START_BYTE) {
furi_stream_buffer_send(app->rx_stream, &data, 1, 0);
app->uart_state = MhZ19UartStateCollectPacket;
furi_stream_buffer_send(app->uart.rx_stream, &data, 1, 0);
app->uart.state = MhZ19UartStateCollectPacket;
}
break;

case MhZ19UartStateCollectPacket:
furi_stream_buffer_send(app->rx_stream, &data, 1, 0);
furi_stream_buffer_send(app->uart.rx_stream, &data, 1, 0);

static size_t byte_count = 0;
furi_mutex_acquire(app->mutex, FuriWaitForever);
byte_count = furi_stream_buffer_bytes_available(app->rx_stream);
furi_mutex_release(app->mutex);
furi_mutex_acquire(app->thread_data.mutex, FuriWaitForever);
furi_mutex_release(app->thread_data.mutex);
byte_count = furi_stream_buffer_bytes_available(app->uart.rx_stream);

if(data == MH_Z19_START_BYTE && byte_count != 1) {
furi_stream_buffer_reset(app->rx_stream);
furi_stream_buffer_send(app->rx_stream, &data, 1, 0);
furi_stream_buffer_reset(app->uart.rx_stream);
furi_stream_buffer_send(app->uart.rx_stream, &data, 1, 0);
} else if(byte_count == MH_Z19_COMMAND_SIZE) {
furi_thread_flags_set(furi_thread_get_id(app->worker_thread), WorkerEventReserved);
app->uart_state = MhZ19UartStateWaitStart;
furi_thread_flags_set(
furi_thread_get_id(app->thread_data.worker_thread), WorkerEventReserved);
app->uart.state = MhZ19UartStateWaitStart;
}
break;
}
Expand All @@ -79,12 +80,12 @@ int32_t mh_z19_app_uart_listener_worker(void* context) {
break;
}
if(flags & WorkerEventReserved) {
furi_mutex_acquire(app->mutex, FuriWaitForever);
length = furi_stream_buffer_receive(app->rx_stream, data, MH_Z19_COMMAND_SIZE, 0);
furi_mutex_acquire(app->thread_data.mutex, FuriWaitForever);
length = furi_stream_buffer_receive(app->uart.rx_stream, data, MH_Z19_COMMAND_SIZE, 0);
if(length == MH_Z19_COMMAND_SIZE) {
app->ppm = mh_z19_decode_co2_concentration(data);
}
furi_mutex_release(app->mutex);
furi_mutex_release(app->thread_data.mutex);
}
}
return 0;
Expand Down
4 changes: 2 additions & 2 deletions mh_z19_ui.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ void mh_z19_app_draw_callback(Canvas* canvas, void* context) {
canvas_set_font(canvas, FontPrimary);
static char buffer[50];

furi_mutex_acquire(app->mutex, FuriWaitForever);
furi_mutex_acquire(app->thread_data.mutex, FuriWaitForever);
snprintf(buffer, sizeof(buffer), "ppm: %lu", app->ppm);
furi_mutex_release(app->mutex);
furi_mutex_release(app->thread_data.mutex);

canvas_draw_str(canvas, 0, 10, buffer);
}

0 comments on commit 8a9e9a0

Please sign in to comment.