a lot of fixes

This commit is contained in:
Marvin 2025-07-22 16:08:55 +02:00
parent 576b481c13
commit 4989f763c7
10 changed files with 214 additions and 225 deletions

View File

@ -11,6 +11,9 @@
"kernel.h": "c", "kernel.h": "c",
"lora.h": "c", "lora.h": "c",
"spi.h": "c", "spi.h": "c",
"gpio.h": "c" "gpio.h": "c",
"array": "c",
"string": "c",
"string_view": "c"
} }
} }

View File

@ -0,0 +1,51 @@
# SPDX-License-Identifier: Apache-2.0
description: SSD16xx ePaper display controller
compatible: "solomon,ssd1680"
include: [spi-device.yaml, display-controller.yaml]
properties:
dc-gpios:
type: phandle-array
required: true
description: Data/Command control pin
reset-gpios:
type: phandle-array
required: true
description: Reset GPIO
busy-gpios:
type: phandle-array
required: true
description: Busy GPIO
cs-gpios:
type: phandle-array
required: true
description: Chip-Select GPIO
width:
type: int
required: true
description: Width in pixels
height:
type: int
required: true
description: Height in pixels
rotation:
type: int
required: false
enum: [0, 90, 180, 270]
default: 0
description: Display rotation
mipi-max-frequency:
type: int
required: false
description: Max frequency of the MIPI interface in Hz

View File

@ -12,6 +12,7 @@
#define ALLSCREEN_GRAGHBYTES 3904 //(BYTES_PER_LINE * HEIGHT) #define ALLSCREEN_GRAGHBYTES 3904 //(BYTES_PER_LINE * HEIGHT)
void epd_init(void); void epd_init(void);
void epd_update(void); void epd_update(void);
void epd_clear_black(void); void epd_clear_black(void);
void epd_clear_white(void); void epd_clear_white(void);

View File

@ -5,6 +5,8 @@
#include <zephyr/kernel.h> #include <zephyr/kernel.h>
#include <zephyr/drivers/lora.h> #include <zephyr/drivers/lora.h>
void lora_init(void);
// Zugriff auf das LoRa-Device // Zugriff auf das LoRa-Device
extern const struct device *lora_dev; extern const struct device *lora_dev;

11
include/lora/lorapacket.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef LORA_PACKET_H
#define LORA_PACKET_H
#include <stdint.h>
typedef struct {
char message[20];
uint32_t timestamp;
} __attribute__((packed)) DataPacket;
#endif // LORA_PACKET_H

View File

@ -8,5 +8,9 @@ CONFIG_PRINTK=y
CONFIG_LORA=y CONFIG_LORA=y
CONFIG_LORA_SHELL=y CONFIG_LORA_SHELL=y
# Display
CONFIG_DISPLAY=y
CONFIG_SSD16XX=y
# --- Stack Size (unverändert) --- # --- Stack Size (unverändert) ---
CONFIG_MAIN_STACK_SIZE=2048 CONFIG_MAIN_STACK_SIZE=2048

View File

@ -17,6 +17,8 @@
#define EPD_NODE DT_NODELABEL(epd) #define EPD_NODE DT_NODELABEL(epd)
#define SPI_BUS DT_BUS(EPD_NODE) #define SPI_BUS DT_BUS(EPD_NODE)
void epd_clear(void);
// GPIOs // GPIOs
static const struct gpio_dt_spec epd_cs = GPIO_DT_SPEC_GET(EPD_NODE, cs_gpios); static const struct gpio_dt_spec epd_cs = GPIO_DT_SPEC_GET(EPD_NODE, cs_gpios);
static const struct gpio_dt_spec epd_dc = GPIO_DT_SPEC_GET(EPD_NODE, dc_gpios); static const struct gpio_dt_spec epd_dc = GPIO_DT_SPEC_GET(EPD_NODE, dc_gpios);
@ -26,17 +28,10 @@ static const struct gpio_dt_spec epd_busy = GPIO_DT_SPEC_GET(EPD_NODE, busy_gpi
// SPI // SPI
static const struct device *spi_dev = DEVICE_DT_GET(SPI_BUS); static const struct device *spi_dev = DEVICE_DT_GET(SPI_BUS);
static struct display_buffer_descriptor desc = {
.width = 250,
.height = 122,
.pitch = 32, // WICHTIG!
.buf_size = 3904,
};
static struct spi_config spi_cfg = { static struct spi_config spi_cfg = {
.frequency = 2000000, .frequency = 2000000,
.operation = SPI_OP_MODE_MASTER | SPI_WORD_SET(8) | SPI_TRANSFER_MSB, .operation = SPI_OP_MODE_MASTER | SPI_WORD_SET(8) | SPI_TRANSFER_MSB,
.cs = NULL//{.gpio = {0}}, //war NULL .cs = { .gpio = {0}, .delay = 0 },
}; };
@ -50,9 +45,6 @@ static struct spi_config spi_cfg = {
#define isEPD_W21_BUSY gpio_pin_get_dt(&epd_busy) #define isEPD_W21_BUSY gpio_pin_get_dt(&epd_busy)
const uint8_t lut_full_update[] = { const uint8_t lut_full_update[] = {
//0x02, 0x02, 0x01, 0x11, 0x12, 0x12, 0x22, 0x22, 0x66, 0x69,
//0x69, 0x59, 0x58, 0x99, 0x99, 0x88, 0x00, 0x00, 0x00, 0x00,
//0xF8, 0xB4, 0x13, 0x51, 0x35, 0x51, 0x51, 0x19, 0x01, 0x00
0xA0, 0x99, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x99, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x50, 0x99, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x99, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@ -64,7 +56,7 @@ void driver_delay_xms(int32_t xms) {
k_msleep(xms); k_msleep(xms);
} }
void Epaper_Spi_WriteByte(uint8_t value) { void epd_spi_writeByte(uint8_t value) {
// Lokaler, nicht optimierbarer Puffer mit expliziter Größe // Lokaler, nicht optimierbarer Puffer mit expliziter Größe
volatile uint8_t tx_data[1]; // Deklariere tx_data lokal, ohne static volatile uint8_t tx_data[1]; // Deklariere tx_data lokal, ohne static
tx_data[0] = value; // Initialisiere den Puffer JEDES Mal tx_data[0] = value; // Initialisiere den Puffer JEDES Mal
@ -85,89 +77,89 @@ void Epaper_Spi_WriteByte(uint8_t value) {
} }
void Epaper_READBUSY(void) { void epd_readbusy(void) {
while (isEPD_W21_BUSY) { while (isEPD_W21_BUSY) {
k_msleep(100); k_msleep(100);
} }
} }
void Epaper_Write_Command(uint8_t cmd) { void epd_write_command(uint8_t cmd) {
EPD_W21_DC_0; // DC auf Command setzen EPD_W21_DC_0; // DC auf Command setzen
Epaper_Spi_WriteByte(cmd); epd_spi_writeByte(cmd);
} }
void Epaper_Write_Data(uint8_t data) { void epd_write_data(uint8_t data) {
EPD_W21_DC_1; // DC auf Data setzen EPD_W21_DC_1; // DC auf Data setzen
Epaper_Spi_WriteByte(data); epd_spi_writeByte(data);
} }
void EPD_HW_Init(void) { void edp_hw_init(void) {
EPD_W21_RST_0; EPD_W21_RST_0;
k_msleep(10); // Ein kurzer Reset-Puls ist oft besser k_msleep(10); // Ein kurzer Reset-Puls ist oft besser
EPD_W21_RST_1; EPD_W21_RST_1;
k_msleep(100); k_msleep(100);
Epaper_READBUSY(); epd_readbusy();
Epaper_Write_Command(0x12); // Software Reset epd_write_command(0x12); // Software Reset
Epaper_READBUSY(); epd_readbusy();
// NEUE, ERGÄNZTE BEFEHLE FÜR BILDQUALITÄT // NEUE, ERGÄNZTE BEFEHLE FÜR BILDQUALITÄT
Epaper_Write_Command(0x0C); // Booster Soft Start Control epd_write_command(0x0C); // Booster Soft Start Control
Epaper_Write_Data(0xD7); epd_write_data(0xD7);
Epaper_Write_Data(0xD6); epd_write_data(0xD6);
Epaper_Write_Data(0x9D); epd_write_data(0x9D);
Epaper_Write_Command(0x2C); // VCOM-Spannung einstellen epd_write_command(0x2C); // VCOM-Spannung einstellen
Epaper_Write_Data(0xA8); // VCOM-Wert, sehr wichtig für den Kontrast epd_write_data(0xA8); // VCOM-Wert, sehr wichtig für den Kontrast
Epaper_Write_Command(0x3A); // Setzt die Dauer eines Frames epd_write_command(0x3A); // Setzt die Dauer eines Frames
Epaper_Write_Data(0x1A); // 50Hz epd_write_data(0x1A); // 50Hz
Epaper_Write_Command(0x3B); // Setzt die Gate-Breite epd_write_command(0x3B); // Setzt die Gate-Breite
Epaper_Write_Data(0x08); epd_write_data(0x08);
// BEKANNTE BEFEHLE // BEKANNTE BEFEHLE
Epaper_Write_Command(0x01); // Driver output control epd_write_command(0x01); // Driver output control
Epaper_Write_Data(0x79); // Höhe (122-1) epd_write_data(0x79); // Höhe (122-1)
Epaper_Write_Data(0x00); epd_write_data(0x00);
Epaper_Write_Data(0x00); epd_write_data(0x00);
Epaper_Write_Command(0x11); // Data entry mode epd_write_command(0x11); // Data entry mode
Epaper_Write_Data(0x01); // X-increment, Y-increment epd_write_data(0x01); // X-increment, Y-increment
Epaper_Write_Command(0x44); // RAM X start/end epd_write_command(0x44); // RAM X start/end
Epaper_Write_Data(0x00); epd_write_data(0x00);
Epaper_Write_Data(0x1F); // 31 (für 32 Bytes Breite) epd_write_data(0x1F); // 31 (für 32 Bytes Breite)
Epaper_Write_Command(0x45); // RAM Y start/end epd_write_command(0x45); // RAM Y start/end
Epaper_Write_Data(0x00); epd_write_data(0x00);
Epaper_Write_Data(0x00); epd_write_data(0x00);
Epaper_Write_Data(0x79); // 121 epd_write_data(0x79); // 121
Epaper_Write_Data(0x00); epd_write_data(0x00);
Epaper_Write_Command(0x3C); // BorderWaveform epd_write_command(0x3C); // BorderWaveform
Epaper_Write_Data(0x05); // VBD transition epd_write_data(0x05); // VBD transition
Epaper_Write_Command(0x18); // Temperature Sensor Control epd_write_command(0x18); // Temperature Sensor Control
Epaper_Write_Data(0x80); // Internen Sensor verwenden epd_write_data(0x80); // Internen Sensor verwenden
// Schreibe die finale LUT in den Controller // Schreibe die finale LUT in den Controller
Epaper_Write_Command(0x32); epd_write_command(0x32);
for (int i = 0; i < sizeof(lut_full_update); i++) { for (int i = 0; i < sizeof(lut_full_update); i++) {
Epaper_Write_Data(lut_full_update[i]); epd_write_data(lut_full_update[i]);
} }
// Setze die RAM-Adresszähler auf den Anfang // Setze die RAM-Adresszähler auf den Anfang
Epaper_Write_Command(0x4E); // RAM X addr count epd_write_command(0x4E); // RAM X addr count
Epaper_Write_Data(0x00); epd_write_data(0x00);
Epaper_Write_Command(0x4F); // RAM Y addr count epd_write_command(0x4F); // RAM Y addr count
Epaper_Write_Data(0x00); epd_write_data(0x00);
Epaper_Write_Data(0x00); epd_write_data(0x00);
Epaper_READBUSY(); epd_readbusy();
} }
void initialise(void){ void epd_init(void){
// GPIOs und Geräte-Checks // GPIOs und Geräte-Checks
if (!device_is_ready(spi_dev) || !device_is_ready(epd_cs.port)) { if (!device_is_ready(spi_dev) || !device_is_ready(epd_cs.port)) {
@ -180,97 +172,97 @@ void initialise(void){
gpio_pin_configure_dt(&epd_busy, GPIO_INPUT); gpio_pin_configure_dt(&epd_busy, GPIO_INPUT);
// Initialisierungssequent für den Chip // Initialisierungssequent für den Chip
EPD_HW_Init(); edp_hw_init();
// 2. Display ZWEIMAL explizit reinigen, um Kaltstart-Artefakte zu entfernen // Display ZWEIMAL explizit reinigen, um Kaltstart-Artefakte zu entfernen
EPD_Clear(); // Erster Clear-Durchgang epd_clear(); // Erster Clear-Durchgang
EPD_Clear(); // Zweiter Clear-Durchgang epd_clear(); // Zweiter Clear-Durchgang
// vor dem Malen den Cursor auf den Anfang (0,0) setzen // vor dem Malen den Cursor auf den Anfang (0,0) setzen
EPD_W21_CS_0; EPD_W21_CS_0;
Epaper_Write_Command(0x4E); // Setze X-Adress-Zähler auf 0 epd_write_command(0x4E); // Setze X-Adress-Zähler auf 0
Epaper_Write_Data(0x00); epd_write_data(0x00);
Epaper_Write_Command(0x4F); // Setze Y-Adress-Zähler auf 0 epd_write_command(0x4F); // Setze Y-Adress-Zähler auf 0
Epaper_Write_Data(0x00); epd_write_data(0x00);
Epaper_Write_Data(0x00); epd_write_data(0x00);
EPD_W21_CS_1; EPD_W21_CS_1;
} }
void EPD_Update(void) { void epd_update(void) {
Epaper_Write_Command(0x22); epd_write_command(0x22);
Epaper_Write_Data(0xFF); epd_write_data(0xFF);
Epaper_Write_Command(0x20); epd_write_command(0x20);
Epaper_READBUSY(); epd_readbusy();
} }
// Beispiel für das Senden eines Bildes // Beispiel für das Senden eines Bildes
void EPD_WhiteScreen_ALL(const uint8_t *datas) { void epd_whitescreen_all(const uint8_t *datas) {
EPD_W21_CS_0; // <-- CS hier aktivieren (LOW) EPD_W21_CS_0; // <-- CS hier aktivieren (LOW)
Epaper_Write_Command(0x24); // Command: write RAM for black/white image epd_write_command(0x24); // Command: write RAM for black/white image
for (int i = 0; i < ALLSCREEN_GRAGHBYTES; i++) { for (int i = 0; i < ALLSCREEN_GRAGHBYTES; i++) {
Epaper_Write_Data(datas[i]); epd_write_data(datas[i]);
} }
EPD_W21_CS_1; // <-- CS hier deaktivieren (HIGH) EPD_W21_CS_1; // <-- CS hier deaktivieren (HIGH)
// Der Update-Befehl ist eine eigene Transaktion // Der Update-Befehl ist eine eigene Transaktion
EPD_W21_CS_0; EPD_W21_CS_0;
EPD_Update(); epd_update();
EPD_W21_CS_1; EPD_W21_CS_1;
} }
// Beispiel für das komplette Löschen des Bildschirms // Beispiel für das komplette Löschen des Bildschirms
void EPD_WhiteScreen_Black(void) { void epd_whitescreen_black(void) {
EPD_W21_CS_0; // <-- CS hier aktivieren (LOW) EPD_W21_CS_0; // <-- CS hier aktivieren (LOW)
Epaper_Write_Command(0x24); epd_write_command(0x24);
for (int i = 0; i < ALLSCREEN_GRAGHBYTES; i++) { for (int i = 0; i < ALLSCREEN_GRAGHBYTES; i++) {
Epaper_Write_Data(0x00); // Schwarz epd_write_data(0x00); // Schwarz
} }
EPD_W21_CS_1; // <-- CS hier deaktivieren (HIGH) EPD_W21_CS_1; // <-- CS hier deaktivieren (HIGH)
// Der Update-Befehl ist eine eigene Transaktion // Der Update-Befehl ist eine eigene Transaktion
EPD_W21_CS_0; EPD_W21_CS_0;
EPD_Update(); epd_update();
EPD_W21_CS_1; EPD_W21_CS_1;
} }
// Dasselbe musst du für EPD_WhiteScreen_White() machen. // Dasselbe musst du für EPD_WhiteScreen_White() machen.
void EPD_WhiteScreen_White(void) { void epd_whitescreen_white(void) {
EPD_W21_CS_0; // <-- CS hier aktivieren (LOW) EPD_W21_CS_0; // <-- CS hier aktivieren (LOW)
Epaper_Write_Command(0x24); epd_write_command(0x24);
for (int i = 0; i < ALLSCREEN_GRAGHBYTES; i++) { for (int i = 0; i < ALLSCREEN_GRAGHBYTES; i++) {
Epaper_Write_Data(0xFF); // Weiß epd_write_data(0xFF); // Weiß
} }
EPD_W21_CS_1; // <-- CS hier deaktivieren (HIGH) EPD_W21_CS_1; // <-- CS hier deaktivieren (HIGH)
// Der Update-Befehl ist eine eigene Transaktion // Der Update-Befehl ist eine eigene Transaktion
EPD_W21_CS_0; EPD_W21_CS_0;
EPD_Update(); epd_update();
EPD_W21_CS_1; EPD_W21_CS_1;
} }
void EPD_Clear(void) { void epd_clear(void) {
printk("🧹 Clearing display...\n"); printk("🧹 Clearing display...\n");
// RAM für das Bild mit "Weiß" füllen // RAM für das Bild mit "Weiß" füllen
EPD_W21_CS_0; EPD_W21_CS_0;
Epaper_Write_Command(0x24); // Schreibe in den RAM epd_write_command(0x24); // Schreibe in den RAM
for (int i = 0; i < ALLSCREEN_GRAGHBYTES; i++) { for (int i = 0; i < ALLSCREEN_GRAGHBYTES; i++) {
Epaper_Write_Data(0xFF); // 0xFF = Weiß epd_write_data(0xFF); // 0xFF = Weiß
} }
EPD_W21_CS_1; EPD_W21_CS_1;
// Physisches Update starten, um den Bildschirm zu reinigen // Physisches Update starten, um den Bildschirm zu reinigen
EPD_W21_CS_0; EPD_W21_CS_0;
EPD_Update(); epd_update();
EPD_W21_CS_1; EPD_W21_CS_1;
Epaper_READBUSY(); // Warten, bis der Clear-Vorgang abgeschlossen ist epd_readbusy(); // Warten, bis der Clear-Vorgang abgeschlossen ist
} }
@ -281,16 +273,16 @@ void draw_something(char toDraw) {
// Muster in den Display-RAM schreiben // Muster in den Display-RAM schreiben
printk("Schreibe Bild in den Display-RAM...\n"); printk("Schreibe Bild in den Display-RAM...\n");
EPD_W21_CS_0; EPD_W21_CS_0;
Epaper_Write_Command(0x24); epd_write_command(0x24);
for (int i = 0; i < ALLSCREEN_GRAGHBYTES; i++) { for (int i = 0; i < ALLSCREEN_GRAGHBYTES; i++) {
Epaper_Write_Data(HALLO[i]); epd_write_data(HALLO[i]);
} }
EPD_W21_CS_1; EPD_W21_CS_1;
// Physisches Update // Physisches Update
printk("Aktualisiere Display...\n"); printk("Aktualisiere Display...\n");
EPD_W21_CS_0; EPD_W21_CS_0;
EPD_Update(); epd_update();
EPD_W21_CS_1; EPD_W21_CS_1;
printk("✅ Display-Finish! Das Ergebnis sollte jetzt immer perfekt sein.\n"); printk("✅ Display-Finish! Das Ergebnis sollte jetzt immer perfekt sein.\n");

View File

@ -3,12 +3,27 @@
#include <zephyr/drivers/lora.h> #include <zephyr/drivers/lora.h>
#include <string.h> #include <string.h>
#include "epaper/epaper.h"
#include "lora/synch.h"
#include "lora/lora.h" #include "lora/lora.h"
#include "lora/lorapacket.h"
#define SLEEP_INTERVAL_MS 120000 #define SLEEP_INTERVAL_MS 120000
#define STACK_SIZE 1024
#define PRIORITY 5
const struct device *lora_dev = DEVICE_DT_GET(DT_ALIAS(lora0)); const struct device *lora_dev = DEVICE_DT_GET(DT_ALIAS(lora0));
static volatile int rx_count = 0;
static volatile bool message_received = false;
K_THREAD_STACK_DEFINE(lora_stack_area, STACK_SIZE);
struct k_thread lora_thread_data;
uint32_t samples[MAX_SAMPLES];
static struct lora_modem_config config = { static struct lora_modem_config config = {
.frequency = 868100000, .frequency = 868100000,
.bandwidth = BW_125_KHZ, .bandwidth = BW_125_KHZ,
@ -19,15 +34,16 @@ static struct lora_modem_config config = {
.tx = false, .tx = false,
}; };
static char msg_buffer[8] = {0}; static DataPacket packet;
void lora_receive_cb(const struct device *dev, uint8_t *data, uint16_t size, void lora_receive_cb(const struct device *dev, uint8_t *data, uint16_t size,
int16_t rssi, int8_t snr, void *user_data) int16_t rssi, int8_t snr, void *user_data)
{ {
if (size > 0 && size < sizeof(msg_buffer)) { if (size == sizeof(DataPacket)) {
memcpy(msg_buffer, data, size); memcpy(&packet, data, sizeof(DataPacket));
msg_buffer[size] = '\0'; rx_count++;
printk("📡 Nachricht empfangen (%d Bytes): %s\n", size, msg_buffer); message_received = true;
printk("📡 [%d]Nachricht empfangen (%d Bytes): %s\n", rx_count, size, packet.message);
} }
} }
@ -35,6 +51,7 @@ int enable_lora_receive(void)
{ {
// Empfang sicher neu starten // Empfang sicher neu starten
lora_recv_async(lora_dev, NULL, NULL); lora_recv_async(lora_dev, NULL, NULL);
memset(&samples, 0, sizeof(samples));
int ret = lora_config(lora_dev, &config); int ret = lora_config(lora_dev, &config);
if (ret != 0) { if (ret != 0) {
@ -64,47 +81,29 @@ int disable_lora_receive(void)
return 0; return 0;
} }
void lora_check_fn(struct k_work *work) void lora_thread(void *p1, void *p2, void *p3)
{ {
printk("🔔 Starte LoRa-Empfang\n"); while (1) {
clear_msg_buffer(); message_received = false;
enable_lora_receive();
k_msleep(10); // Stabilisierung
k_msleep(ACTIVE_WINDOW_MS);
enable_lora_receive();
if (msg_buffer != ""){
printk("Nachricht gelesen!");
disable_lora_receive(); disable_lora_receive();
draw_something('4');
}
k_work_schedule(&lora_check_work, K_MSEC(SLEEP_INTERVAL_MS)); if (message_received) {
draw_something('4');
/* if (enable_lora_receive() == 0) {
for (int i = 0; i < ACTIVE_WINDOW_MS / 100; i++) {
k_msleep(100);
} }
disable_lora_receive();
k_msleep(SLEEP_INTERVAL_MS);
} }
const char *msg = get_last_msg();
if (msg[0] != '\0') {
printk("📨 Neue Nachricht: %s\n", msg);
draw_something(msg[0]);
} else {
printk("📭 Keine Nachricht empfangen\n");
}
k_work_schedule(&lora_check_work, K_MSEC(SLEEP_INTERVAL_MS));*/
} }
void lora_init(void)
const char *get_last_msg(void)
{ {
return msg_buffer; lora_recv_async(lora_dev, NULL, NULL); // sicher deaktivieren
} k_thread_create(&lora_thread_data, lora_stack_area, STACK_SIZE,
lora_thread, NULL, NULL, NULL,
void clear_msg_buffer(void) PRIORITY, 0, K_NO_WAIT);
{ }
memset(msg_buffer, 0, sizeof(msg_buffer));
}

View File

@ -8,101 +8,37 @@
#include "utils/buttons.h" #include "utils/buttons.h"
#include "utils/leds.h" #include "utils/leds.h"
#include "lora/lora.h"
#include "lora/synch.h" #include "lora/synch.h"
K_WORK_DEFINE(sync_work, synchronite);
// Sync-Variablen // Sync-Variablen
uint32_t offsets[MAX_SAMPLES];
uint8_t offset_count = 0; uint8_t offset_count = 0;
uint32_t sync_offset = 0; uint32_t sync_offset = 0;
uint32_t sync_offset_s = 0; uint32_t sync_offset_s = 0;
uint32_t samples[MAX_SAMPLES];
BUILD_ASSERT(DT_NODE_HAS_STATUS_OKAY(DEFAULT_RADIO_NODE),
"No default LoRa radio specified in DT");
// 📡 Callback uint32_t calculate_offset(uint32_t samples[MAX_SAMPLES])
void lora_receive_cb(const struct device *dev, uint8_t *data, uint16_t size,
int16_t rssi, int8_t snr, void *user_data)
{ {
if ((size >= 4) && (!synchronized)) { uint32_t offsets = 0;
uint32_t master_timer_value = sys_get_le32(data); //uint8_t master_timer_value = data[0] % 60;
uint32_t local_now = k_uptime_get();
printk("📡 Empfangen: %u ms\n", master_timer_value); printk("Intervall: %d: %d: %d\n",(MAX_SAMPLES/5), (MAX_SAMPLES*4/5), (MAX_SAMPLES * 3/5));
//gpio_pin_toggle_dt(&led_green); for (int i = (MAX_SAMPLES/5); i < (MAX_SAMPLES*4/5); i++) {
offsets += samples[i];
if (offset_count < MAX_SAMPLES) {
samples[offset_count] = local_now + master_timer_value;
offset_count++;
}
if (offset_count >= MAX_SAMPLES) {
uint32_t offsets = 0;
printk("Intervall: %d: %d: %d\n",(MAX_SAMPLES/5), (MAX_SAMPLES*4/5), (MAX_SAMPLES * 3/5));
for (int i = (MAX_SAMPLES/5); i < (MAX_SAMPLES*4/5); i++) {
offsets += samples[i];
}
sync_offset_s = offsets /( MAX_SAMPLES * 3/5);
sync_offset_s -= local_now;
synchronized = true;
int ret = lora_recv_async(lora_dev, NULL, NULL);
if (ret != 0){
printk("Problem beim deaktivieren der Synchronsation: %d\n", ret);
}
printk("✅ Synchronisiert! Offset: %u Sekunden\n", sync_offset_s);
return;
}
} }
sync_offset_s = offsets /( MAX_SAMPLES * 3/5);
sync_offset_s -= k_uptime_get();
synchronized = true;
printk("✅ Synchronisiert! Offset: %u Sekunden\n", sync_offset_s);
return;
} }
// 🕒 Hilfsfunktion: synchronisierter Timerwert uint32_t synchronite(uint32_t samples[MAX_SAMPLES]){
uint32_t get_synced_timer() {
if (!synchronized) return 0;
uint32_t now = k_uptime_get();
return (sync_offset > now) ? (sync_offset - now) : 0;
}
// 🔘 Button Interrupt
void button_pressed(const struct device *dev, struct gpio_callback *cb,
uint32_t pins)
{
printk("🔘 Button gedrückt\n");
k_work_submit(&sync_work); // startet synchronite()
}
void synchronite(struct k_work *work){
offset_count = 0; offset_count = 0;
synchronized = false; synchronized = false;
memset(offsets, 0, sizeof(offsets));
printk("Initilisierung abgeschlossen");
int ret = lora_config(lora_dev, &config);
ret = lora_recv_async(lora_dev, lora_receive_cb, NULL); return calculate_offset(samples);
printk("Empfang gestartet (ret = %d)\n", ret);
} }
// 🚀 Main
int init(void) {
printk("🔋 Starte LoRa-Empfänger\n");
if (!device_is_ready(lora_dev)) {
printk("❌ LoRa nicht bereit\n");
return -1;
}
while (1) {
k_msleep(1000);
}
}

View File

@ -42,20 +42,10 @@ int main(void)
return -1; return -1;
} }
/*while(1){ epd_init();
if(nextSynchro > 0){
uint32_t sleepTimer = k_uptime_get() - nextSynchro;
k_msleep(sleepTimer);
}
}*/
initialise();
lora_recv_async(lora_dev, NULL, NULL); // sicher deaktivieren lora_init();
k_work_init_delayable(&lora_check_work, lora_check_fn);
k_work_schedule(&lora_check_work, K_NO_WAIT);
// Event Loop (muss da sein für Timer und Arbeiten im Hintergrund)
while (1) { while (1) {
k_sleep(K_SECONDS(1)); // Energiesparend schlafen k_sleep(K_SECONDS(1)); // Energiesparend schlafen
} }