diff --git a/.vscode/settings.json b/.vscode/settings.json index 70ff48b..7bca0c8 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,6 +5,12 @@ "04_diagonal.h": "c", "epaper.h": "c", "font.h": "c", - "oled.h": "c" + "oled.h": "c", + "leds.h": "c", + "constandvars.h": "c", + "kernel.h": "c", + "lora.h": "c", + "spi.h": "c", + "gpio.h": "c" } } \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index b7ca347..074f2e1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,8 +6,9 @@ FILE(GLOB app_sources src/*.c) target_sources(app PRIVATE src/main.c src/lora/encryption.c - src/lora/synch.c - src/oled/oled.c + src/lora/lora.c + #src/lora/synch.c + src/epaper/epaper.c src/utils/constAndVars.c src/utils/buttons.c src/utils/leds.c diff --git a/boards/nucleo_wl55jc.overlay b/boards/nucleo_wl55jc.overlay index 32e077b..a32b1b0 100644 --- a/boards/nucleo_wl55jc.overlay +++ b/boards/nucleo_wl55jc.overlay @@ -6,7 +6,7 @@ * Finale, funktionierende Konfiguration: Wir weichen dem LED-Konflikt * auf Port B aus, indem wir den sauberen SPI1-Port auf Port A verwenden. */ - +/* / { aliases { oled = &oled; @@ -35,10 +35,10 @@ cs-gpios = <&gpiob 10 GPIO_ACTIVE_LOW>; label = "OLED"; }; -}; +};*/ -/*&spi1{ +&spi1{ status = "okay"; pinctrl-0 = < &spi1_nss_pa4 &spi1_sck_pa5 &spi1_miso_pa6 &spi1_mosi_pa7 >; pinctrl-names = "default"; @@ -56,4 +56,4 @@ busy-gpios = <&gpiob 10 GPIO_ACTIVE_HIGH>; cs-gpios = <&gpioa 4 GPIO_ACTIVE_HIGH>; }; -};*/ \ No newline at end of file +}; \ No newline at end of file diff --git a/frame_5px.h b/frame_5px.h deleted file mode 100644 index e69de29..0000000 diff --git a/include/lora/lora.h b/include/lora/lora.h index b453e63..d0f7ffe 100644 --- a/include/lora/lora.h +++ b/include/lora/lora.h @@ -1,18 +1,24 @@ #ifndef LORA_H #define LORA_H -#define DEFAULT_RADIO_NODE DT_ALIAS(lora0) +#include +#include +#include -const struct device *lora_dev = DEVICE_DT_GET(DEFAULT_RADIO_NODE); +// Zugriff auf das LoRa-Device +extern const struct device *lora_dev; -struct lora_modem_config config = { - .frequency = 868100000, - .bandwidth = BW_125_KHZ, - .datarate = SF_7, - .preamble_len = 8, - .coding_rate = CR_4_5, - .tx_power = 14, - .tx = false, -}; +// Empfangssteuerung +int enable_lora_receive(void); +int disable_lora_receive(void); +void lora_check_fn(struct k_work *work); -#endif \ No newline at end of file +// Buffer-Zugriff +const char *get_last_msg(void); +void clear_msg_buffer(void); + +// Optional: Empfangsdauer definieren +extern struct k_work_delayable lora_check_work; +#define ACTIVE_WINDOW_MS 10000 + +#endif // LORA_H_ \ No newline at end of file diff --git a/src/epaper/epaper.c b/src/epaper/epaper.c index 7399ef0..f8fea6f 100644 --- a/src/epaper/epaper.c +++ b/src/epaper/epaper.c @@ -167,6 +167,36 @@ void EPD_HW_Init(void) { Epaper_READBUSY(); } +void initialise(void){ + + // GPIOs und Geräte-Checks + if (!device_is_ready(spi_dev) || !device_is_ready(epd_cs.port)) { + printk("Gerät nicht bereit\n"); + return; + } + gpio_pin_configure_dt(&epd_cs, GPIO_OUTPUT_ACTIVE); + gpio_pin_configure_dt(&epd_dc, GPIO_OUTPUT_ACTIVE); + gpio_pin_configure_dt(&epd_reset, GPIO_OUTPUT_ACTIVE); + gpio_pin_configure_dt(&epd_busy, GPIO_INPUT); + + // Initialisierungssequent für den Chip + EPD_HW_Init(); + + // 2. 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_W21_CS_1; + +} + void EPD_Update(void) { Epaper_Write_Command(0x22); Epaper_Write_Data(0xFF); @@ -243,52 +273,13 @@ void EPD_Clear(void) { Epaper_READBUSY(); // Warten, bis der Clear-Vorgang abgeschlossen ist } + + void draw_something(char toDraw) { - printk("Starte finalen Display-Test...\n"); + - // --- GPIOs und Geräte-Checks (wie gehabt) --- - if (!device_is_ready(spi_dev) || !device_is_ready(epd_cs.port) /*...usw.*/) { - printk("Gerät nicht bereit\n"); - return; - } - gpio_pin_configure_dt(&epd_cs, GPIO_OUTPUT_ACTIVE); - gpio_pin_configure_dt(&epd_dc, GPIO_OUTPUT_ACTIVE); - gpio_pin_configure_dt(&epd_reset, GPIO_OUTPUT_ACTIVE); - gpio_pin_configure_dt(&epd_busy, GPIO_INPUT); - // ------------------------------------------------ - - EPD_HW_Init(); - - // 2. Display ZWEIMAL explizit reinigen, um Kaltstart-Artefakte zu entfernen - printk("🧹 Führe doppelten Clear-Zyklus für Kaltstart durch...\n"); - EPD_Clear(); // Erster Clear-Durchgang - EPD_Clear(); // Zweiter Clear-Durchgang - - // 3. 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_W21_CS_1; - - - - // 3. Dein gewünschtes Bild vorbereiten (z.B. alles schwarz) - printk("🎨 Erzeuge finales Bild...\n"); - // static uint8_t pattern_buffer[ALLSCREEN_GRAGHBYTES]; - // memset(pattern_buffer, 0xFF, ALLSCREEN_GRAGHBYTES); // 0x00 = Schwarz - - // static uint8_t pattern_buffer[ALLSCREEN_GRAGHBYTES]; - // for (int i = 0; i < ALLSCREEN_GRAGHBYTES; i++) { - // Wir erzeugen ein Muster aus 0xFF und 0x00 - // Das sollte dicke schwarze und weiße Streifen ergeben - // pattern_buffer[i] = ((i / 32) % 2 == 0) ? 0xFF : 0x00; - // } - - // 4. Muster in den Display-RAM schreiben - printk("✍️ Schreibe Bild in den Display-RAM...\n"); + // Muster in den Display-RAM schreiben + printk("Schreibe Bild in den Display-RAM...\n"); EPD_W21_CS_0; Epaper_Write_Command(0x24); for (int i = 0; i < ALLSCREEN_GRAGHBYTES; i++) { @@ -296,8 +287,8 @@ void draw_something(char toDraw) { } EPD_W21_CS_1; - // 5. Physisches Update mit dem finalen Bild - printk("🖼️ Aktualisiere Display...\n"); + // Physisches Update + printk("Aktualisiere Display...\n"); EPD_W21_CS_0; EPD_Update(); EPD_W21_CS_1; diff --git a/src/lora/lora.c b/src/lora/lora.c new file mode 100644 index 0000000..a3e8277 --- /dev/null +++ b/src/lora/lora.c @@ -0,0 +1,110 @@ +#include +#include +#include +#include + +#include "lora/lora.h" + +#define SLEEP_INTERVAL_MS 120000 + +const struct device *lora_dev = DEVICE_DT_GET(DT_ALIAS(lora0)); + +static struct lora_modem_config config = { + .frequency = 868100000, + .bandwidth = BW_125_KHZ, + .datarate = SF_7, + .preamble_len = 8, + .coding_rate = CR_4_5, + .tx_power = 14, + .tx = false, +}; + +static char msg_buffer[8] = {0}; + +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); + } +} + +int enable_lora_receive(void) +{ + // Empfang sicher neu starten + lora_recv_async(lora_dev, NULL, NULL); + + int ret = lora_config(lora_dev, &config); + if (ret != 0) { + printk("❌ LoRa-Konfiguration fehlgeschlagen: %d\n", ret); + return ret; + } + + ret = lora_recv_async(lora_dev, lora_receive_cb, NULL); + if (ret != 0) { + printk("❌ Empfang konnte nicht aktiviert werden: %d\n", ret); + return ret; + } + + printk("📡 LoRa-Empfang aktiviert\n"); + return 0; +} + +int disable_lora_receive(void) +{ + int ret = lora_recv_async(lora_dev, NULL, NULL); + if (ret != 0) { + printk("❌ Empfang konnte nicht deaktiviert werden: %d\n", ret); + return ret; + } + + printk("🔕 LoRa-Empfang deaktiviert\n"); + return 0; +} + +void lora_check_fn(struct k_work *work) +{ + printk("🔔 Starte LoRa-Empfang\n"); + clear_msg_buffer(); + + + enable_lora_receive(); + + if (msg_buffer != ""){ + printk("Nachricht gelesen!"); + disable_lora_receive(); + 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); + } + 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) +{ + return msg_buffer; +} + +void clear_msg_buffer(void) +{ + memset(msg_buffer, 0, sizeof(msg_buffer)); +} diff --git a/src/main.c b/src/main.c index fbf10c3..9c515c1 100644 --- a/src/main.c +++ b/src/main.c @@ -2,13 +2,18 @@ #include #include -//#include "epaper/epaper.h" -#include "oled/oled.h" +#include "epaper/epaper.h" +//#include "oled/oled.h" + +#include "lora/lora.h" #include "utils/buttons.h" #include "utils/leds.h" #include "utils/constAndVars.h" +struct k_work_delayable lora_check_work; + + uint8_t init_led_and_button(void) { uint8_t ret; @@ -44,6 +49,16 @@ int main(void) } }*/ - char toDraw = '4'; - oled_draw_something(toDraw); + initialise(); + + 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 + } + + return 0; }