a lot of fixes
This commit is contained in:
parent
576b481c13
commit
4989f763c7
5
.vscode/settings.json
vendored
5
.vscode/settings.json
vendored
@ -11,6 +11,9 @@
|
||||
"kernel.h": "c",
|
||||
"lora.h": "c",
|
||||
"spi.h": "c",
|
||||
"gpio.h": "c"
|
||||
"gpio.h": "c",
|
||||
"array": "c",
|
||||
"string": "c",
|
||||
"string_view": "c"
|
||||
}
|
||||
}
|
51
dts/bindings/display/ssd16xx.yaml
Normal file
51
dts/bindings/display/ssd16xx.yaml
Normal 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
|
@ -12,6 +12,7 @@
|
||||
#define ALLSCREEN_GRAGHBYTES 3904 //(BYTES_PER_LINE * HEIGHT)
|
||||
|
||||
void epd_init(void);
|
||||
|
||||
void epd_update(void);
|
||||
void epd_clear_black(void);
|
||||
void epd_clear_white(void);
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/drivers/lora.h>
|
||||
|
||||
void lora_init(void);
|
||||
|
||||
// Zugriff auf das LoRa-Device
|
||||
extern const struct device *lora_dev;
|
||||
|
||||
|
11
include/lora/lorapacket.h
Normal file
11
include/lora/lorapacket.h
Normal 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
|
4
prj.conf
4
prj.conf
@ -8,5 +8,9 @@ CONFIG_PRINTK=y
|
||||
CONFIG_LORA=y
|
||||
CONFIG_LORA_SHELL=y
|
||||
|
||||
# Display
|
||||
CONFIG_DISPLAY=y
|
||||
CONFIG_SSD16XX=y
|
||||
|
||||
# --- Stack Size (unverändert) ---
|
||||
CONFIG_MAIN_STACK_SIZE=2048
|
@ -17,6 +17,8 @@
|
||||
#define EPD_NODE DT_NODELABEL(epd)
|
||||
#define SPI_BUS DT_BUS(EPD_NODE)
|
||||
|
||||
void epd_clear(void);
|
||||
|
||||
// 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);
|
||||
@ -26,17 +28,10 @@ static const struct gpio_dt_spec epd_busy = GPIO_DT_SPEC_GET(EPD_NODE, busy_gpi
|
||||
// SPI
|
||||
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 = {
|
||||
.frequency = 2000000,
|
||||
.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)
|
||||
|
||||
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,
|
||||
0x00, 0x00, 0x00, 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);
|
||||
}
|
||||
|
||||
void Epaper_Spi_WriteByte(uint8_t value) {
|
||||
void epd_spi_writeByte(uint8_t value) {
|
||||
// Lokaler, nicht optimierbarer Puffer mit expliziter Größe
|
||||
volatile uint8_t tx_data[1]; // Deklariere tx_data lokal, ohne static
|
||||
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) {
|
||||
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
|
||||
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
|
||||
Epaper_Spi_WriteByte(data);
|
||||
epd_spi_writeByte(data);
|
||||
}
|
||||
|
||||
void EPD_HW_Init(void) {
|
||||
void edp_hw_init(void) {
|
||||
EPD_W21_RST_0;
|
||||
k_msleep(10); // Ein kurzer Reset-Puls ist oft besser
|
||||
EPD_W21_RST_1;
|
||||
k_msleep(100);
|
||||
|
||||
Epaper_READBUSY();
|
||||
Epaper_Write_Command(0x12); // Software Reset
|
||||
Epaper_READBUSY();
|
||||
epd_readbusy();
|
||||
epd_write_command(0x12); // Software Reset
|
||||
epd_readbusy();
|
||||
|
||||
// NEUE, ERGÄNZTE BEFEHLE FÜR BILDQUALITÄT
|
||||
Epaper_Write_Command(0x0C); // Booster Soft Start Control
|
||||
Epaper_Write_Data(0xD7);
|
||||
Epaper_Write_Data(0xD6);
|
||||
Epaper_Write_Data(0x9D);
|
||||
epd_write_command(0x0C); // Booster Soft Start Control
|
||||
epd_write_data(0xD7);
|
||||
epd_write_data(0xD6);
|
||||
epd_write_data(0x9D);
|
||||
|
||||
Epaper_Write_Command(0x2C); // VCOM-Spannung einstellen
|
||||
Epaper_Write_Data(0xA8); // VCOM-Wert, sehr wichtig für den Kontrast
|
||||
epd_write_command(0x2C); // VCOM-Spannung einstellen
|
||||
epd_write_data(0xA8); // VCOM-Wert, sehr wichtig für den Kontrast
|
||||
|
||||
Epaper_Write_Command(0x3A); // Setzt die Dauer eines Frames
|
||||
Epaper_Write_Data(0x1A); // 50Hz
|
||||
epd_write_command(0x3A); // Setzt die Dauer eines Frames
|
||||
epd_write_data(0x1A); // 50Hz
|
||||
|
||||
Epaper_Write_Command(0x3B); // Setzt die Gate-Breite
|
||||
Epaper_Write_Data(0x08);
|
||||
epd_write_command(0x3B); // Setzt die Gate-Breite
|
||||
epd_write_data(0x08);
|
||||
|
||||
// BEKANNTE BEFEHLE
|
||||
Epaper_Write_Command(0x01); // Driver output control
|
||||
Epaper_Write_Data(0x79); // Höhe (122-1)
|
||||
Epaper_Write_Data(0x00);
|
||||
Epaper_Write_Data(0x00);
|
||||
epd_write_command(0x01); // Driver output control
|
||||
epd_write_data(0x79); // Höhe (122-1)
|
||||
epd_write_data(0x00);
|
||||
epd_write_data(0x00);
|
||||
|
||||
Epaper_Write_Command(0x11); // Data entry mode
|
||||
Epaper_Write_Data(0x01); // X-increment, Y-increment
|
||||
epd_write_command(0x11); // Data entry mode
|
||||
epd_write_data(0x01); // X-increment, Y-increment
|
||||
|
||||
Epaper_Write_Command(0x44); // RAM X start/end
|
||||
Epaper_Write_Data(0x00);
|
||||
Epaper_Write_Data(0x1F); // 31 (für 32 Bytes Breite)
|
||||
epd_write_command(0x44); // RAM X start/end
|
||||
epd_write_data(0x00);
|
||||
epd_write_data(0x1F); // 31 (für 32 Bytes Breite)
|
||||
|
||||
Epaper_Write_Command(0x45); // RAM Y start/end
|
||||
Epaper_Write_Data(0x00);
|
||||
Epaper_Write_Data(0x00);
|
||||
Epaper_Write_Data(0x79); // 121
|
||||
Epaper_Write_Data(0x00);
|
||||
epd_write_command(0x45); // RAM Y start/end
|
||||
epd_write_data(0x00);
|
||||
epd_write_data(0x00);
|
||||
epd_write_data(0x79); // 121
|
||||
epd_write_data(0x00);
|
||||
|
||||
Epaper_Write_Command(0x3C); // BorderWaveform
|
||||
Epaper_Write_Data(0x05); // VBD transition
|
||||
epd_write_command(0x3C); // BorderWaveform
|
||||
epd_write_data(0x05); // VBD transition
|
||||
|
||||
Epaper_Write_Command(0x18); // Temperature Sensor Control
|
||||
Epaper_Write_Data(0x80); // Internen Sensor verwenden
|
||||
epd_write_command(0x18); // Temperature Sensor Control
|
||||
epd_write_data(0x80); // Internen Sensor verwenden
|
||||
|
||||
// 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++) {
|
||||
Epaper_Write_Data(lut_full_update[i]);
|
||||
epd_write_data(lut_full_update[i]);
|
||||
}
|
||||
|
||||
// Setze die RAM-Adresszähler auf den Anfang
|
||||
Epaper_Write_Command(0x4E); // RAM X addr count
|
||||
Epaper_Write_Data(0x00);
|
||||
Epaper_Write_Command(0x4F); // RAM Y addr count
|
||||
Epaper_Write_Data(0x00);
|
||||
Epaper_Write_Data(0x00);
|
||||
epd_write_command(0x4E); // RAM X addr count
|
||||
epd_write_data(0x00);
|
||||
epd_write_command(0x4F); // RAM Y addr count
|
||||
epd_write_data(0x00);
|
||||
epd_write_data(0x00);
|
||||
|
||||
Epaper_READBUSY();
|
||||
epd_readbusy();
|
||||
}
|
||||
|
||||
void initialise(void){
|
||||
void epd_init(void){
|
||||
|
||||
// GPIOs und Geräte-Checks
|
||||
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);
|
||||
|
||||
// Initialisierungssequent für den Chip
|
||||
EPD_HW_Init();
|
||||
edp_hw_init();
|
||||
|
||||
// 2. Display ZWEIMAL explizit reinigen, um Kaltstart-Artefakte zu entfernen
|
||||
EPD_Clear(); // Erster Clear-Durchgang
|
||||
EPD_Clear(); // Zweiter Clear-Durchgang
|
||||
// Display ZWEIMAL explizit reinigen, um Kaltstart-Artefakte zu entfernen
|
||||
epd_clear(); // Erster Clear-Durchgang
|
||||
epd_clear(); // Zweiter Clear-Durchgang
|
||||
|
||||
// vor dem Malen den Cursor auf den Anfang (0,0) setzen
|
||||
EPD_W21_CS_0;
|
||||
Epaper_Write_Command(0x4E); // Setze X-Adress-Zähler auf 0
|
||||
Epaper_Write_Data(0x00);
|
||||
Epaper_Write_Command(0x4F); // Setze Y-Adress-Zähler auf 0
|
||||
Epaper_Write_Data(0x00);
|
||||
Epaper_Write_Data(0x00);
|
||||
epd_write_command(0x4E); // Setze X-Adress-Zähler auf 0
|
||||
epd_write_data(0x00);
|
||||
epd_write_command(0x4F); // Setze Y-Adress-Zähler auf 0
|
||||
epd_write_data(0x00);
|
||||
epd_write_data(0x00);
|
||||
EPD_W21_CS_1;
|
||||
|
||||
}
|
||||
|
||||
void EPD_Update(void) {
|
||||
Epaper_Write_Command(0x22);
|
||||
Epaper_Write_Data(0xFF);
|
||||
Epaper_Write_Command(0x20);
|
||||
Epaper_READBUSY();
|
||||
void epd_update(void) {
|
||||
epd_write_command(0x22);
|
||||
epd_write_data(0xFF);
|
||||
epd_write_command(0x20);
|
||||
epd_readbusy();
|
||||
}
|
||||
|
||||
// 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)
|
||||
|
||||
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++) {
|
||||
Epaper_Write_Data(datas[i]);
|
||||
epd_write_data(datas[i]);
|
||||
}
|
||||
|
||||
EPD_W21_CS_1; // <-- CS hier deaktivieren (HIGH)
|
||||
|
||||
// Der Update-Befehl ist eine eigene Transaktion
|
||||
EPD_W21_CS_0;
|
||||
EPD_Update();
|
||||
epd_update();
|
||||
EPD_W21_CS_1;
|
||||
}
|
||||
|
||||
// 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)
|
||||
|
||||
Epaper_Write_Command(0x24);
|
||||
epd_write_command(0x24);
|
||||
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)
|
||||
|
||||
// Der Update-Befehl ist eine eigene Transaktion
|
||||
EPD_W21_CS_0;
|
||||
EPD_Update();
|
||||
epd_update();
|
||||
EPD_W21_CS_1;
|
||||
}
|
||||
// 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)
|
||||
Epaper_Write_Command(0x24);
|
||||
epd_write_command(0x24);
|
||||
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)
|
||||
|
||||
// Der Update-Befehl ist eine eigene Transaktion
|
||||
EPD_W21_CS_0;
|
||||
EPD_Update();
|
||||
epd_update();
|
||||
EPD_W21_CS_1;
|
||||
}
|
||||
|
||||
void EPD_Clear(void) {
|
||||
void epd_clear(void) {
|
||||
printk("🧹 Clearing display...\n");
|
||||
|
||||
// RAM für das Bild mit "Weiß" füllen
|
||||
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++) {
|
||||
Epaper_Write_Data(0xFF); // 0xFF = Weiß
|
||||
epd_write_data(0xFF); // 0xFF = Weiß
|
||||
}
|
||||
EPD_W21_CS_1;
|
||||
|
||||
// Physisches Update starten, um den Bildschirm zu reinigen
|
||||
EPD_W21_CS_0;
|
||||
EPD_Update();
|
||||
epd_update();
|
||||
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
|
||||
printk("Schreibe Bild in den Display-RAM...\n");
|
||||
EPD_W21_CS_0;
|
||||
Epaper_Write_Command(0x24);
|
||||
epd_write_command(0x24);
|
||||
for (int i = 0; i < ALLSCREEN_GRAGHBYTES; i++) {
|
||||
Epaper_Write_Data(HALLO[i]);
|
||||
epd_write_data(HALLO[i]);
|
||||
}
|
||||
EPD_W21_CS_1;
|
||||
|
||||
// Physisches Update
|
||||
printk("Aktualisiere Display...\n");
|
||||
EPD_W21_CS_0;
|
||||
EPD_Update();
|
||||
epd_update();
|
||||
EPD_W21_CS_1;
|
||||
|
||||
printk("✅ Display-Finish! Das Ergebnis sollte jetzt immer perfekt sein.\n");
|
||||
|
@ -3,12 +3,27 @@
|
||||
#include <zephyr/drivers/lora.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "epaper/epaper.h"
|
||||
|
||||
#include "lora/synch.h"
|
||||
#include "lora/lora.h"
|
||||
#include "lora/lorapacket.h"
|
||||
|
||||
#define SLEEP_INTERVAL_MS 120000
|
||||
|
||||
#define STACK_SIZE 1024
|
||||
#define PRIORITY 5
|
||||
|
||||
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 = {
|
||||
.frequency = 868100000,
|
||||
.bandwidth = BW_125_KHZ,
|
||||
@ -19,15 +34,16 @@ static struct lora_modem_config config = {
|
||||
.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,
|
||||
int16_t rssi, int8_t snr, void *user_data)
|
||||
{
|
||||
if (size > 0 && size < sizeof(msg_buffer)) {
|
||||
memcpy(msg_buffer, data, size);
|
||||
msg_buffer[size] = '\0';
|
||||
printk("📡 Nachricht empfangen (%d Bytes): %s\n", size, msg_buffer);
|
||||
if (size == sizeof(DataPacket)) {
|
||||
memcpy(&packet, data, sizeof(DataPacket));
|
||||
rx_count++;
|
||||
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
|
||||
lora_recv_async(lora_dev, NULL, NULL);
|
||||
memset(&samples, 0, sizeof(samples));
|
||||
|
||||
int ret = lora_config(lora_dev, &config);
|
||||
if (ret != 0) {
|
||||
@ -64,47 +81,29 @@ int disable_lora_receive(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lora_check_fn(struct k_work *work)
|
||||
void lora_thread(void *p1, void *p2, void *p3)
|
||||
{
|
||||
printk("🔔 Starte LoRa-Empfang\n");
|
||||
clear_msg_buffer();
|
||||
|
||||
while (1) {
|
||||
message_received = false;
|
||||
|
||||
enable_lora_receive();
|
||||
k_msleep(10); // Stabilisierung
|
||||
k_msleep(ACTIVE_WINDOW_MS);
|
||||
|
||||
if (msg_buffer != ""){
|
||||
printk("Nachricht gelesen!");
|
||||
disable_lora_receive();
|
||||
|
||||
if (message_received) {
|
||||
draw_something('4');
|
||||
}
|
||||
|
||||
k_work_schedule(&lora_check_work, K_MSEC(SLEEP_INTERVAL_MS));
|
||||
|
||||
/* if (enable_lora_receive() == 0) {
|
||||
for (int i = 0; i < ACTIVE_WINDOW_MS / 100; i++) {
|
||||
k_msleep(100);
|
||||
k_msleep(SLEEP_INTERVAL_MS);
|
||||
}
|
||||
disable_lora_receive();
|
||||
}
|
||||
|
||||
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));*/
|
||||
}
|
||||
|
||||
|
||||
const char *get_last_msg(void)
|
||||
void lora_init(void)
|
||||
{
|
||||
return msg_buffer;
|
||||
}
|
||||
|
||||
void clear_msg_buffer(void)
|
||||
{
|
||||
memset(msg_buffer, 0, sizeof(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,
|
||||
PRIORITY, 0, K_NO_WAIT);
|
||||
}
|
@ -8,39 +8,17 @@
|
||||
|
||||
#include "utils/buttons.h"
|
||||
#include "utils/leds.h"
|
||||
#include "lora/lora.h"
|
||||
#include "lora/synch.h"
|
||||
|
||||
|
||||
K_WORK_DEFINE(sync_work, synchronite);
|
||||
|
||||
// Sync-Variablen
|
||||
uint32_t offsets[MAX_SAMPLES];
|
||||
uint8_t offset_count = 0;
|
||||
uint32_t sync_offset = 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
|
||||
void lora_receive_cb(const struct device *dev, uint8_t *data, uint16_t size,
|
||||
int16_t rssi, int8_t snr, void *user_data)
|
||||
uint32_t calculate_offset(uint32_t samples[MAX_SAMPLES])
|
||||
{
|
||||
if ((size >= 4) && (!synchronized)) {
|
||||
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);
|
||||
//gpio_pin_toggle_dt(&led_green);
|
||||
|
||||
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));
|
||||
@ -50,59 +28,17 @@ void lora_receive_cb(const struct device *dev, uint8_t *data, uint16_t size,
|
||||
|
||||
sync_offset_s = offsets /( MAX_SAMPLES * 3/5);
|
||||
|
||||
sync_offset_s -= local_now;
|
||||
sync_offset_s -= k_uptime_get();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 🕒 Hilfsfunktion: synchronisierter Timerwert
|
||||
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){
|
||||
uint32_t synchronite(uint32_t samples[MAX_SAMPLES]){
|
||||
offset_count = 0;
|
||||
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);
|
||||
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);
|
||||
}
|
||||
return calculate_offset(samples);
|
||||
}
|
14
src/main.c
14
src/main.c
@ -42,20 +42,10 @@ int main(void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*while(1){
|
||||
if(nextSynchro > 0){
|
||||
uint32_t sleepTimer = k_uptime_get() - nextSynchro;
|
||||
k_msleep(sleepTimer);
|
||||
}
|
||||
}*/
|
||||
epd_init();
|
||||
|
||||
initialise();
|
||||
lora_init();
|
||||
|
||||
lora_recv_async(lora_dev, NULL, NULL); // sicher deaktivieren
|
||||
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) {
|
||||
k_sleep(K_SECONDS(1)); // Energiesparend schlafen
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user