1
0

fix(MP/daemon): oled and app files

This commit is contained in:
2026-06-06 13:06:21 +02:00
committed by Fastium
parent fa58b76bcd
commit d515871987
9 changed files with 231 additions and 100 deletions

View File

@@ -0,0 +1,138 @@
#include "app.h"
#include "sysfs.h"
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
static led_t* led;
/* Threads objects */
static pthread_t anim_thread_id;
static pthread_mutex_t anim_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t anim_condition = PTHREAD_COND_INITIALIZER; // SHARED RESOURCES
/* The counter of pending animations */
static int pending_animations = 0; // SHARED RESOURCES
static int keep_running = 1;
void btn_set_led(led_t* l) {
if (l != NULL) {
led = l;
}
}
void set_period(uint32_t period_ms){
sysfs_set_period(period_ms);
}
uint32_t get_period() {
return sysfs_get_period();
}
void increase_period() {
uint32_t current_period = sysfs_get_period();
set_period(current_period + GAP_PERIOD_MS);
}
void decrease_period() {
uint32_t current_period = sysfs_get_period();
set_period(current_period - GAP_PERIOD_MS);
}
int get_mode() {
return sysfs_get_mode();
}
void set_mode(int mode) {
sysfs_set_mode(mode);
}
void mode_toggle() {
int current_mode = sysfs_get_mode();
set_mode(current_mode ^ 1);
}
float get_temperature() {
return sysfs_get_temperature();
}
/**
* animation_worker() - The single thread that processes the queue
*/
static void* animation_worker(void* arg) {
while (keep_running) {
// ENTER CRITICAL SECTION
pthread_mutex_lock(&anim_lock);
/*
* As long as there are no animations to do, the thread sleeps here.
* It consumes 0% CPU while waiting.
*/
while (pending_animations == 0 && keep_running) {
/*
* Wait signal to make animation.
* The function unlocks the mutex to allow another process to add an animation.
* The function forces the thread to sleep until a signal is received.
*/
pthread_cond_wait(&anim_condition, &anim_lock);
}
if (!keep_running) {
pthread_mutex_unlock(&anim_lock);
break;
}
/* We take one animation from the queue */
pending_animations--;
pthread_mutex_unlock(&anim_lock);
// LEAVE CRITICAL SECTION
/* Perform the visual task */
if (led != NULL) {
led_on(led);
usleep(150000);
led_off(led);
usleep(100000); /* Small delay between consecutive pulses */
}
}
return NULL;
}
/**
* init_animations() - To be called once during daemon startup
*/
void init_animations(void) {
pthread_create(&anim_thread_id, NULL, animation_worker, NULL);
}
/**
* trigger_pulse() - Increments the counter and wakes up the thread
*/
static void trigger_pulse(void) {
// ENTER CRITICAL SECTION
pthread_mutex_lock(&anim_lock);
pending_animations++;
/* Signal the thread that there is work to do */
pthread_cond_signal(&anim_condition);
pthread_mutex_unlock(&anim_lock);
// LEAVE CRITICAL SECTION
}
void btn_increase_period() {
trigger_pulse();
increase_period();
}
void btn_decrease_period() {
trigger_pulse();
decrease_period();
}

View File

@@ -0,0 +1,37 @@
#ifndef APP_H
#define APP_H
#include <stdint.h>
#include "../gpio/led.h"
#define DEFAULT_PERIOD_MS 1000
#define GAP_PERIOD_MS 50
/* --- Period functions --- */
void increase_period();
void decrease_period();
void set_period(uint32_t period_ms);
uint32_t get_period();
/* --- Mode functions --- */
void mode_toggle();
void set_mode(int mode);
int get_mode();
/* --- Temperature functions --- */
float get_temperature();
/* --- Button specific function --- */
void btn_set_led(led_t* l);
void init_animations(void);
void btn_increase_period();
void btn_decrease_period();
#endif /* APP_H */

View File

@@ -5,7 +5,7 @@
float get_temperature() {
float sysfs_get_temperature() {
FILE *f = fopen(PATH_TEMPERATURE, "r");
if (f == NULL) {
return 0.0f; /* Return 0.0 if the kernel module is not loaded */
@@ -26,7 +26,7 @@ float get_temperature() {
return 0.0f;
}
uint32_t get_mode() {
uint32_t sysfs_get_mode() {
FILE *f = fopen(PATH_MODE, "r");
if (f == NULL) return 0;
@@ -37,7 +37,7 @@ uint32_t get_mode() {
return mode;
}
void set_mode(uint32_t mode) {
void sysfs_set_mode(uint32_t mode) {
FILE *f = fopen(PATH_MODE, "w");
if (f == NULL) return;
@@ -46,7 +46,7 @@ void set_mode(uint32_t mode) {
fclose(f);
}
uint32_t get_period() {
uint32_t sysfs_get_period() {
FILE *f = fopen(PATH_PERIOD_ST, "r");
if (f == NULL) return 0;
@@ -57,7 +57,7 @@ uint32_t get_period() {
return period;
}
void set_period(uint32_t period) {
void sysfs_set_period(uint32_t period) {
FILE *f = fopen(PATH_PERIOD_SET, "w");
if (f == NULL) return;

View File

@@ -10,11 +10,11 @@
#define PATH_PERIOD_ST SYSFS_BASE_PATH "/period_status"
#define PATH_PERIOD_SET SYSFS_BASE_PATH "/period_set"
float get_temperature();
uint32_t get_mode();
void set_mode(uint32_t mode);
uint32_t get_period();
void set_period(uint32_t period);
float sysfs_get_temperature();
uint32_t sysfs_get_mode();
void sysfs_set_mode(uint32_t mode);
uint32_t sysfs_get_period();
void sysfs_set_period(uint32_t period);
#endif /* SYSFS_H */

View File

@@ -1 +0,0 @@
#include "app.h"

View File

@@ -1,25 +0,0 @@
#ifndef APP_H
#define APP_H
#include "../gpio/led.h"
#define DEFAULT_PERIOD_MS 1000
void set_led(
void increase_period();
void decrease_period();
void set_period(int period_ms);
void mode_toggle();
void set_mode(int mode);
float get_temperature();
/* Button specific function */
void btn_increase_period();
void btn_decrease_period();
#endif /* APP_H */

View File

@@ -14,38 +14,12 @@
#include "gpio/led.h"
#include "gpio/button.h"
#include "ipc/ipc_server.h"
#include "oled/oled.h"
#include "application/app.h"
#define DEFAULT_TIME_MS 1000
#define DUTY_CYCLE_PERCENT 2
void set_mode(int mode) {
printf("set_mode: %d\n", mode);
}
void set_period(int period) {
printf("set_period: %d\n", period);
}
uint32_t get_period() {
printf("get_period\n");
return 200;
}
void period_inc() {
printf("period_inc\n");
}
void period_dec() {
printf("period_dec\n");
}
void period_reset() {
printf("period_reset\n");
}
void get_temp() {
printf("get_temp\n");
}
int main(void) {
@@ -56,23 +30,34 @@ int main(void) {
led_t* led_power = led_init(LED_POWER);
btn_set_callback(btn_inc, period_inc);
btn_set_callback(btn_dec, period_dec);
btn_set_callback(btn_mode, period_reset);
btn_set_callback(btn_inc, btn_decrease_period);
btn_set_callback(btn_dec, btn_decrease_period);
btn_set_callback(btn_mode, set_mode);
struct ipc_callbacks_t ipc_cbs = {
.on_dec_frequency = period_dec,
.on_inc_frequency = period_inc,
.on_set_frequency = set_period,
.on_dec_frequency = decrease_period,
.on_inc_frequency = increase_period,
// .on_set_frequency = set_period,
.on_set_mode = set_mode,
};
struct oled_callbacks_t oled_cbs = {
.get_mode = get_mode,
.get_period = get_period,
.get_temperature = get_temperature,
};
int ret = start_ipc_server(&ipc_cbs);
if (ret < 0) {
fprintf(stderr, "Failed to start IPC server: %d\n", ret);
return 1;
}
init_oled(&oled_cbs);
btn_set_led(led_power);
init_animations();
while (1) {
sleep(1);
}

View File

@@ -26,26 +26,26 @@ static void display(int mode, float temp, uint32_t period_ms) {
/* Static header rows */
ssd1306_set_position(0, 0);
ssd1306_puts("CSEL1a - SP.07");
ssd1306_set_position(0, 1);
ssd1306_puts(" WATCHDOG CPU ");
ssd1306_set_position(0, 2);
ssd1306_puts("--------------");
// ssd1306_set_position(0, 1);
// ssd1306_puts(" WATCHDOG CPU ");
// ssd1306_set_position(0, 2);
// ssd1306_puts("--------------");
/* Mode display: switches between AUTO and MANU strings */
ssd1306_set_position(0, 3);
snprintf(buffer, sizeof(buffer), "Mode: %s", mode ? "AUTO" : "MANU");
ssd1306_puts(buffer);
// /* Mode display: switches between AUTO and MANU strings */
// ssd1306_set_position(0, 3);
// snprintf(buffer, sizeof(buffer), "Mode: %s", mode ? "AUTO" : "MANU");
// ssd1306_puts(buffer);
/* Temperature display: formatted with one decimal precision */
ssd1306_set_position(0, 4);
snprintf(buffer, sizeof(buffer), "Temp: %.1f'C", temp);
ssd1306_puts(buffer);
// /* Temperature display: formatted with one decimal precision */
// ssd1306_set_position(0, 4);
// snprintf(buffer, sizeof(buffer), "Temp: %.1f'C", temp);
// ssd1306_puts(buffer);
/* Period/Frequency display: shows the value in milliseconds */
ssd1306_set_position(0, 5);
float freq = 1.0f / (period_ms / 1000.0f);
snprintf(buffer, sizeof(buffer), "Freq: %.1fHz", freq);
ssd1306_puts(buffer);
// /* Period/Frequency display: shows the value in milliseconds */
// ssd1306_set_position(0, 5);
// float freq = 1.0f / (period_ms / 1000.0f);
// snprintf(buffer, sizeof(buffer), "Freq: %.1fHz", freq);
// ssd1306_puts(buffer);
}
/**
@@ -65,7 +65,7 @@ static void *update_oled_thread(void* arg) {
);
}
/* Sleep to control refresh rate and save CPU cycles */
usleep(250000);
usleep(1000000);
}
return NULL;
}

View File

@@ -14,11 +14,11 @@
#define ARRAY_OF(x) (sizeof(x)/sizeof(x[0]))
#define I2C_BUS "/dev/i2c-0"
#define OLED_ADDR 0x3c
#define I2C_BUS "/dev/i2c-1"
#define OLED_ADDR 0x3c
#define OLED_COMMAND_MODE 0x00
#define OLED_DATA_MODE 0x40
#define OLED_DISPLAY_OFF_CMD 0xae
#define OLED_DATA_MODE 0x40
#define OLED_DISPLAY_OFF_CMD 0xae
#define OLED_DISPLAY_ON_CMD 0xaf
static const uint8_t font[][8] = {
@@ -163,7 +163,7 @@ static void send_command(uint8_t cmd)
}
}
void send_data(uint8_t byte)
void send_data(uint8_t byte)
{
uint8_t buf[2] = {
[0] = OLED_DATA_MODE,
@@ -181,7 +181,7 @@ void ssd1306_set_position (uint32_t column, uint32_t row)
send_command(0x10 + ((8*column>>4)&0x0f)); //set column higher address
}
void ssd1306_putc(char c)
void ssd1306_putc(char c)
{
if ((c<32) || (c>127)) // Ignore non-printable ASCII characters
c=' ';
@@ -193,7 +193,7 @@ void ssd1306_putc(char c)
}
}
void ssd1306_puts(const char* str)
void ssd1306_puts(const char* str)
{
while (*str != 0)
ssd1306_putc(*str++);
@@ -203,7 +203,7 @@ void ssd1306_clear_display()
{
send_command(OLED_DISPLAY_OFF_CMD);// display off
for (int j=0; j<8; j++) {
ssd1306_set_position(0,j);
ssd1306_set_position(0,j);
for (int i=0; i<16; i++) //clear all columns
ssd1306_putc(' ');
}
@@ -218,7 +218,7 @@ int ssd1306_init()
printf("ERROR: unable to open i2c bus interface (%s)\n", I2C_BUS);
return -1;
}
if (ioctl(fd, I2C_SLAVE, OLED_ADDR) < 0) {
if (ioctl(fd, I2C_SLAVE, OLED_ADDR) < 0) {
printf("ERROR: unable to access OLED as slave\n");
return -1;
}
@@ -231,6 +231,3 @@ int ssd1306_init()
return 0;
}