Merging everything
This commit is contained in:
parent
de18d1a5c4
commit
5089614205
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@ -7,7 +7,6 @@
|
|||||||
"font.h": "c",
|
"font.h": "c",
|
||||||
"oled.h": "c",
|
"oled.h": "c",
|
||||||
"leds.h": "c",
|
"leds.h": "c",
|
||||||
"constandvars.h": "c",
|
|
||||||
"kernel.h": "c",
|
"kernel.h": "c",
|
||||||
"lora.h": "c",
|
"lora.h": "c",
|
||||||
"spi.h": "c",
|
"spi.h": "c",
|
||||||
|
@ -1,4 +1,11 @@
|
|||||||
cmake_minimum_required(VERSION 3.20.0)
|
cmake_minimum_required(VERSION 3.20.0)
|
||||||
|
|
||||||
|
if(DEFINED EXTRA_CONF_FILE AND EXTRA_CONF_FILE MATCHES "EPD")
|
||||||
|
set(DTC_OVERLAY_FILE ${CMAKE_CURRENT_SOURCE_DIR}/boards/nucleo_wl55jc_epd.overlay)
|
||||||
|
elseif(DEFINED EXTRA_CONF_FILE AND EXTRA_CONF_FILE MATCHES "OLED")
|
||||||
|
set(DTC_OVERLAY_FILE ${CMAKE_CURRENT_SOURCE_DIR}/boards/nucleo_wl55jc_oled.overlay)
|
||||||
|
endif()
|
||||||
|
|
||||||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||||
project(EdSaGfmvA)
|
project(EdSaGfmvA)
|
||||||
|
|
||||||
@ -7,16 +14,23 @@ target_sources(app PRIVATE
|
|||||||
src/main.c
|
src/main.c
|
||||||
src/lora/encryption.c
|
src/lora/encryption.c
|
||||||
src/lora/lora.c
|
src/lora/lora.c
|
||||||
#src/lora/synch.c
|
|
||||||
src/master/master.c
|
src/master/master.c
|
||||||
src/epaper/epaper.c
|
|
||||||
src/utils/constAndVars.c
|
|
||||||
src/utils/buttons.c
|
src/utils/buttons.c
|
||||||
|
src/utils/displayController.c
|
||||||
src/utils/leds.c
|
src/utils/leds.c
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if(CONFIG_SLAVE_DISPLAY_TYPE STREQUAL "EPD")
|
||||||
|
target_sources(app PRIVATE src/epaper/epaper.c)
|
||||||
|
elseif(CONFIG_SLAVE_DISPLAY_TYPE STREQUAL "OLED")
|
||||||
|
target_sources(app PRIVATE
|
||||||
|
src/oled/oled.c
|
||||||
|
src/oled/font.c
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
set(DTC_EXTRA_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/dts/bindings")
|
set(DTC_EXTRA_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/dts/bindings")
|
||||||
|
|
||||||
target_include_directories(app PRIVATE
|
target_include_directories(app PRIVATE
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||||
)
|
)
|
||||||
|
23
Kconfig
23
Kconfig
@ -11,4 +11,25 @@ config DEVICE_MODE_MASTER
|
|||||||
config DEVICE_MODE_SLAVE
|
config DEVICE_MODE_SLAVE
|
||||||
bool "Build as slave"
|
bool "Build as slave"
|
||||||
|
|
||||||
endchoice
|
endchoice
|
||||||
|
choice DEVICE_MODE
|
||||||
|
prompt "Device Mode"
|
||||||
|
default DEVICE_MODE_MASTER
|
||||||
|
|
||||||
|
config DEVICE_MODE_MASTER
|
||||||
|
bool "Build as master"
|
||||||
|
|
||||||
|
config DEVICE_MODE_SLAVE
|
||||||
|
bool "Build as slave"
|
||||||
|
|
||||||
|
endchoice
|
||||||
|
|
||||||
|
config SLAVE_DISPLAY_TYPE
|
||||||
|
string "Display type (e.g., EPD, OLED)"
|
||||||
|
depends on DEVICE_MODE_SLAVE
|
||||||
|
default "UNDEFINED"
|
||||||
|
|
||||||
|
config SLAVE_DISPLAY_SLOT
|
||||||
|
int "Display Slot"
|
||||||
|
depends on DEVICE_MODE_SLAVE
|
||||||
|
default 0
|
||||||
|
17
README.rst
17
README.rst
@ -12,20 +12,21 @@ BUSY (lila) CN9:7 GPIO B10
|
|||||||
|
|
||||||
OLED
|
OLED
|
||||||
Ports: Anschluss Port
|
Ports: Anschluss Port
|
||||||
VCC VDD (braun) CN6:4 5V
|
VCC (rot) CN6:4 3,3V
|
||||||
GND VSS (grau) CN6:6 GND
|
GND (schwarz) CN6:6 GND
|
||||||
DIN D0 (blau) CN5:4 GPIO A7
|
DIN (blau) CN5:4 GPIO A7
|
||||||
CLK D1 (gelb) CN5:6 GPIO A5
|
CLK (gelb) CN5:6 GPIO A5
|
||||||
CS CS (orange) CN9:7 GPIO B10 !! A8
|
CS (orange) CN5:3 GPIO A4
|
||||||
DC A0 (grün) CN9:6 GPIO B8 !! A9
|
DC (grün) CN9:6 GPIO B8
|
||||||
RST RST (weiß) CN9:8 GPIO C1 !! A10
|
RST (weiß) CN9:8 GPIO C1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Bei start:
|
Bei start:
|
||||||
source zephyrproject/.venv/bin/activate
|
source zephyrproject/.venv/bin/activate
|
||||||
cd zephyrproject/EdSaGfmvA/
|
cd zephyrproject/EdSaGfmvA/
|
||||||
|
|
||||||
west build -p always -b nucleo_wl55jc .
|
west build -b <board> -- -DEXTRA_CONF_FILE=conf_EPD.conf
|
||||||
west flash
|
west flash
|
||||||
|
|
||||||
minicom:
|
minicom:
|
||||||
|
25
boards/nucleo_wl55jc_epd.overlay
Normal file
25
boards/nucleo_wl55jc_epd.overlay
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2024 Marvin Herold
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
&spi1{
|
||||||
|
status = "okay";
|
||||||
|
pinctrl-0 = < &spi1_nss_pa4 &spi1_sck_pa5 &spi1_miso_pa6 &spi1_mosi_pa7 >;
|
||||||
|
pinctrl-names = "default";
|
||||||
|
|
||||||
|
epd: epd@0 {
|
||||||
|
compatible = "solomon,ssd1680";
|
||||||
|
reg = <0>;
|
||||||
|
spi-max-frequency = <2000000>;
|
||||||
|
mipi-max-frequency = <2000000>;
|
||||||
|
width = <250>;
|
||||||
|
height = <122>;
|
||||||
|
rotation = <0>;
|
||||||
|
dc-gpios = <&gpiob 8 GPIO_ACTIVE_HIGH>;
|
||||||
|
reset-gpios = <&gpioc 1 GPIO_ACTIVE_HIGH>;
|
||||||
|
busy-gpios = <&gpiob 10 GPIO_ACTIVE_HIGH>;
|
||||||
|
cs-gpios = <&gpioa 4 GPIO_ACTIVE_HIGH>;
|
||||||
|
};
|
||||||
|
};
|
@ -6,7 +6,7 @@
|
|||||||
* Finale, funktionierende Konfiguration: Wir weichen dem LED-Konflikt
|
* Finale, funktionierende Konfiguration: Wir weichen dem LED-Konflikt
|
||||||
* auf Port B aus, indem wir den sauberen SPI1-Port auf Port A verwenden.
|
* auf Port B aus, indem wir den sauberen SPI1-Port auf Port A verwenden.
|
||||||
*/
|
*/
|
||||||
/*
|
|
||||||
/ {
|
/ {
|
||||||
aliases {
|
aliases {
|
||||||
oled = &oled;
|
oled = &oled;
|
||||||
@ -32,28 +32,7 @@
|
|||||||
// Die anderen GPIOs bleiben unverändert, sie sind nicht im Konflikt.
|
// Die anderen GPIOs bleiben unverändert, sie sind nicht im Konflikt.
|
||||||
dc-gpios = <&gpiob 8 GPIO_ACTIVE_HIGH>;
|
dc-gpios = <&gpiob 8 GPIO_ACTIVE_HIGH>;
|
||||||
reset-gpios = <&gpioc 1 GPIO_ACTIVE_LOW>;
|
reset-gpios = <&gpioc 1 GPIO_ACTIVE_LOW>;
|
||||||
cs-gpios = <&gpiob 10 GPIO_ACTIVE_LOW>;
|
cs-gpios = <&gpioa 4 GPIO_ACTIVE_LOW>;
|
||||||
label = "OLED";
|
label = "OLED";
|
||||||
};
|
};
|
||||||
};*/
|
};
|
||||||
|
|
||||||
|
|
||||||
&spi1{
|
|
||||||
status = "okay";
|
|
||||||
pinctrl-0 = < &spi1_nss_pa4 &spi1_sck_pa5 &spi1_miso_pa6 &spi1_mosi_pa7 >;
|
|
||||||
pinctrl-names = "default";
|
|
||||||
|
|
||||||
epd: epd@0 {
|
|
||||||
compatible = "solomon,ssd1680";
|
|
||||||
reg = <0>;
|
|
||||||
spi-max-frequency = <2000000>;
|
|
||||||
mipi-max-frequency = <2000000>;
|
|
||||||
width = <250>;
|
|
||||||
height = <122>;
|
|
||||||
rotation = <0>;
|
|
||||||
dc-gpios = <&gpiob 8 GPIO_ACTIVE_HIGH>;
|
|
||||||
reset-gpios = <&gpioc 1 GPIO_ACTIVE_HIGH>;
|
|
||||||
busy-gpios = <&gpiob 10 GPIO_ACTIVE_HIGH>;
|
|
||||||
cs-gpios = <&gpioa 4 GPIO_ACTIVE_HIGH>;
|
|
||||||
};
|
|
||||||
};
|
|
4
conf_EPD.conf
Normal file
4
conf_EPD.conf
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# Konfig für das E-Paper
|
||||||
|
CONFIG_DEVICE_MODE_SLAVE=y
|
||||||
|
CONFIG_SLAVE_DISPLAY_TYPE="EPD"
|
||||||
|
CONFIG_SLAVE_DISPLAY_SLOT=0
|
4
conf_OLED.conf
Normal file
4
conf_OLED.conf
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# Konfig für das OLED-Display
|
||||||
|
CONFIG_DEVICE_MODE_SLAVE=y
|
||||||
|
CONFIG_SLAVE_DISPLAY_TYPE="OLED"
|
||||||
|
CONFIG_SLAVE_DISPLAY_SLOT=0
|
@ -18,6 +18,6 @@ void epd_clear_black(void);
|
|||||||
void epd_clear_white(void);
|
void epd_clear_white(void);
|
||||||
void epd_display_buffer(const unsigned char *buffer);
|
void epd_display_buffer(const unsigned char *buffer);
|
||||||
|
|
||||||
void draw_something(char toDraw);
|
void epd_draw_something(char toDraw);
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
#include <zephyr/kernel.h>
|
#include <zephyr/kernel.h>
|
||||||
#include "utils/leds.h"
|
#include "utils/leds.h"
|
||||||
#include "utils/constAndVars.h"
|
|
||||||
|
|
||||||
#define MAX_SAMPLES 10
|
#define MAX_SAMPLES 10
|
||||||
|
|
||||||
|
89
include/oled/lv_font.h
Normal file
89
include/oled/lv_font.h
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
// File: lv_font.h (muss unter include/oled/lv_font.h liegen)
|
||||||
|
#ifndef LV_FONT_H
|
||||||
|
#define LV_FONT_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
// Makro-Definitionen, die in der generierten font.c verwendet werden
|
||||||
|
#define LV_VERSION_CHECK(major, minor, patch) 0
|
||||||
|
#ifndef LV_ATTRIBUTE_LARGE_CONST
|
||||||
|
#define LV_ATTRIBUTE_LARGE_CONST
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Enum für den Font-Subpixel-Typ
|
||||||
|
enum { LV_FONT_SUBPX_NONE };
|
||||||
|
|
||||||
|
// Enum für den CMap-Typ
|
||||||
|
typedef uint8_t lv_font_fmt_txt_cmap_type_t;
|
||||||
|
enum { LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY };
|
||||||
|
|
||||||
|
/* Vordeklaration der Haupt-Struktur */
|
||||||
|
struct _lv_font_t;
|
||||||
|
|
||||||
|
/* Struktur zur Beschreibung eines einzelnen Zeichens (Glyph) */
|
||||||
|
typedef struct {
|
||||||
|
uint32_t bitmap_index;
|
||||||
|
uint32_t adv_w;
|
||||||
|
uint16_t box_w;
|
||||||
|
uint16_t box_h;
|
||||||
|
int16_t ofs_x;
|
||||||
|
int16_t ofs_y;
|
||||||
|
} lv_font_glyph_dsc_t;
|
||||||
|
|
||||||
|
/* Struktur für das Character-Mapping */
|
||||||
|
typedef struct {
|
||||||
|
uint32_t range_start;
|
||||||
|
uint16_t range_length;
|
||||||
|
uint16_t glyph_id_start;
|
||||||
|
const void * unicode_list;
|
||||||
|
const void * glyph_id_ofs_list;
|
||||||
|
uint16_t list_length;
|
||||||
|
lv_font_fmt_txt_cmap_type_t type;
|
||||||
|
} lv_font_fmt_txt_cmap_t;
|
||||||
|
|
||||||
|
/* Struktur für Kerning-Paare */
|
||||||
|
typedef struct {
|
||||||
|
const void * glyph_ids;
|
||||||
|
const int8_t * values;
|
||||||
|
uint16_t pair_cnt;
|
||||||
|
uint8_t glyph_ids_size;
|
||||||
|
} lv_font_fmt_txt_kern_pair_t;
|
||||||
|
|
||||||
|
/* Haupt-Datenstruktur der Schriftart */
|
||||||
|
typedef struct {
|
||||||
|
const uint8_t * glyph_bitmap;
|
||||||
|
const lv_font_glyph_dsc_t * glyph_dsc;
|
||||||
|
const lv_font_fmt_txt_cmap_t * cmaps;
|
||||||
|
const void * kern_dsc;
|
||||||
|
uint16_t kern_scale;
|
||||||
|
uint16_t cmap_num;
|
||||||
|
uint16_t bpp;
|
||||||
|
uint16_t kern_classes;
|
||||||
|
uint8_t bitmap_format;
|
||||||
|
void* cache;
|
||||||
|
} lv_font_fmt_txt_dsc_t;
|
||||||
|
|
||||||
|
/* Die Haupt-Schriftart-Struktur, die Ihr Code verwendet */
|
||||||
|
typedef struct _lv_font_t {
|
||||||
|
bool (*get_glyph_dsc)(const struct _lv_font_t *, lv_font_glyph_dsc_t *, uint32_t, uint32_t);
|
||||||
|
const uint8_t * (*get_glyph_bitmap)(const struct _lv_font_t *, uint32_t);
|
||||||
|
int16_t line_height;
|
||||||
|
int16_t base_line;
|
||||||
|
uint8_t subpx;
|
||||||
|
int8_t underline_position;
|
||||||
|
int8_t underline_thickness;
|
||||||
|
const void * dsc;
|
||||||
|
const struct _lv_font_t * fallback;
|
||||||
|
void * user_data;
|
||||||
|
} lv_font_t;
|
||||||
|
|
||||||
|
/* Funktionsprototypen, die in font.c existieren */
|
||||||
|
bool lv_font_get_glyph_dsc_fmt_txt(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, uint32_t unicode_letter_next);
|
||||||
|
const uint8_t * lv_font_get_bitmap_fmt_txt(const lv_font_t * font, uint32_t unicode_letter);
|
||||||
|
|
||||||
|
/* Makro, um die Schriftart aus Ihrer font.c bekannt zu machen */
|
||||||
|
#define LV_FONT_DECLARE(font_name) extern const lv_font_t font_name;
|
||||||
|
|
||||||
|
#endif /*LV_FONT_H*/
|
@ -1,17 +1,7 @@
|
|||||||
#ifndef OLED_H
|
#ifndef OLED_H
|
||||||
#define OLED_H
|
#define OLED_H
|
||||||
|
|
||||||
#include <zephyr/kernel.h>
|
void oled_init(void);
|
||||||
#include <zephyr/device.h>
|
|
||||||
#include <zephyr/drivers/spi.h>
|
|
||||||
#include <zephyr/drivers/gpio.h>
|
|
||||||
|
|
||||||
#define WIDTH 128
|
|
||||||
#define HEIGHT 64
|
|
||||||
#define BYTES_PER_LINE 16 // ((WIDTH + 7) / 8)
|
|
||||||
#define ALLSCREEN_GRAGHBYTES 1024 //(BYTES_PER_LINE * HEIGHT)
|
|
||||||
|
|
||||||
|
|
||||||
void oled_draw_something(char toDraw);
|
void oled_draw_something(char toDraw);
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -1,13 +0,0 @@
|
|||||||
#ifndef CONSTANDVARS_H
|
|
||||||
#define CONSTANDVARS_H
|
|
||||||
|
|
||||||
#include <zephyr/kernel.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
extern bool slave;
|
|
||||||
extern bool error;
|
|
||||||
extern bool synchronized;
|
|
||||||
extern uint32_t nextSynchro;
|
|
||||||
|
|
||||||
#endif // CONSTANDVARS_H
|
|
7
include/utils/displayController.h
Normal file
7
include/utils/displayController.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#ifndef DISPLAY_CONTROLLER_H
|
||||||
|
#define DISPLAY_CONTROLLER_H
|
||||||
|
|
||||||
|
void dc_init(const char *type_str, int slot);
|
||||||
|
void dc_draw_something(char to_draw);
|
||||||
|
|
||||||
|
#endif
|
@ -5,7 +5,6 @@
|
|||||||
#include <zephyr/drivers/gpio.h>
|
#include <zephyr/drivers/gpio.h>
|
||||||
|
|
||||||
#include "lora/synch.h"
|
#include "lora/synch.h"
|
||||||
#include "utils/constAndVars.h"
|
|
||||||
|
|
||||||
//#define LED0_NODE DT_ALIAS(led0)
|
//#define LED0_NODE DT_ALIAS(led0)
|
||||||
|
|
||||||
|
1
prj.conf
1
prj.conf
@ -12,5 +12,6 @@ CONFIG_LORA_SHELL=y
|
|||||||
CONFIG_DISPLAY=y
|
CONFIG_DISPLAY=y
|
||||||
CONFIG_SSD16XX=y
|
CONFIG_SSD16XX=y
|
||||||
|
|
||||||
|
|
||||||
# --- Stack Size (unverändert) ---
|
# --- Stack Size (unverändert) ---
|
||||||
CONFIG_MAIN_STACK_SIZE=2048
|
CONFIG_MAIN_STACK_SIZE=2048
|
||||||
|
@ -267,7 +267,7 @@ void epd_clear(void) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void draw_something(char toDraw) {
|
void epd_draw_something(char toDraw) {
|
||||||
|
|
||||||
|
|
||||||
// Muster in den Display-RAM schreiben
|
// Muster in den Display-RAM schreiben
|
||||||
|
@ -250,10 +250,4 @@ const unsigned char HALLO [] = {
|
|||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0,
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc0
|
||||||
};
|
};
|
||||||
|
|
||||||
// Array of all bitmaps for convenience. (Total bytes used to store images in PROGMEM = 3920)
|
|
||||||
const int HALLO_LEN = 3920;
|
|
||||||
//const unsigned char* HALLO[1] = {
|
|
||||||
// HALLO
|
|
||||||
//};
|
|
@ -1,3 +1,4 @@
|
|||||||
|
#include <string.h>
|
||||||
#include <zephyr/device.h>
|
#include <zephyr/device.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <zephyr/sys/util.h>
|
#include <zephyr/sys/util.h>
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include <zephyr/drivers/lora.h>
|
#include <zephyr/drivers/lora.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "epaper/epaper.h"
|
#include "utils/displayController.h"
|
||||||
|
|
||||||
#include "lora/synch.h"
|
#include "lora/synch.h"
|
||||||
#include "lora/lora.h"
|
#include "lora/lora.h"
|
||||||
@ -36,8 +36,9 @@ static struct lora_modem_config config = {
|
|||||||
|
|
||||||
static DataPacket packet;
|
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,
|
||||||
int16_t rssi, int8_t snr, void *user_data)
|
uint8_t *data, uint16_t size,
|
||||||
|
int16_t rssi, int8_t snr)
|
||||||
{
|
{
|
||||||
if (size == sizeof(DataPacket)) {
|
if (size == sizeof(DataPacket)) {
|
||||||
memcpy(&packet, data, sizeof(DataPacket));
|
memcpy(&packet, data, sizeof(DataPacket));
|
||||||
@ -50,7 +51,7 @@ void lora_receive_cb(const struct device *dev, uint8_t *data, uint16_t size,
|
|||||||
int enable_lora_receive(void)
|
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);
|
||||||
memset(&samples, 0, sizeof(samples));
|
memset(&samples, 0, sizeof(samples));
|
||||||
|
|
||||||
int ret = lora_config(lora_dev, &config);
|
int ret = lora_config(lora_dev, &config);
|
||||||
@ -59,7 +60,7 @@ int enable_lora_receive(void)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = lora_recv_async(lora_dev, lora_receive_cb, NULL);
|
ret = lora_recv_async(lora_dev, lora_receive_cb);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
printk("❌ Empfang konnte nicht aktiviert werden: %d\n", ret);
|
printk("❌ Empfang konnte nicht aktiviert werden: %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
@ -71,7 +72,7 @@ int enable_lora_receive(void)
|
|||||||
|
|
||||||
int disable_lora_receive(void)
|
int disable_lora_receive(void)
|
||||||
{
|
{
|
||||||
int ret = lora_recv_async(lora_dev, NULL, NULL);
|
int ret = lora_recv_async(lora_dev, NULL);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
printk("❌ Empfang konnte nicht deaktiviert werden: %d\n", ret);
|
printk("❌ Empfang konnte nicht deaktiviert werden: %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
@ -93,7 +94,7 @@ void lora_thread(void *p1, void *p2, void *p3)
|
|||||||
disable_lora_receive();
|
disable_lora_receive();
|
||||||
|
|
||||||
if (message_received) {
|
if (message_received) {
|
||||||
draw_something('4');
|
dc_draw_something('4');
|
||||||
}
|
}
|
||||||
|
|
||||||
k_msleep(SLEEP_INTERVAL_MS);
|
k_msleep(SLEEP_INTERVAL_MS);
|
||||||
@ -102,7 +103,7 @@ void lora_thread(void *p1, void *p2, void *p3)
|
|||||||
|
|
||||||
void lora_init(void)
|
void lora_init(void)
|
||||||
{
|
{
|
||||||
lora_recv_async(lora_dev, NULL, NULL); // sicher deaktivieren
|
lora_recv_async(lora_dev, NULL); // sicher deaktivieren
|
||||||
k_thread_create(&lora_thread_data, lora_stack_area, STACK_SIZE,
|
k_thread_create(&lora_thread_data, lora_stack_area, STACK_SIZE,
|
||||||
lora_thread, NULL, NULL, NULL,
|
lora_thread, NULL, NULL, NULL,
|
||||||
PRIORITY, 0, K_NO_WAIT);
|
PRIORITY, 0, K_NO_WAIT);
|
||||||
|
@ -26,13 +26,12 @@ uint32_t calculate_offset(uint32_t samples[MAX_SAMPLES])
|
|||||||
offsets += samples[i];
|
offsets += samples[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
sync_offset_s = offsets /( MAX_SAMPLES * 3/5);
|
sync_offset_s = offsets /( MAX_SAMPLES * 3/5)
|
||||||
|
|
||||||
sync_offset_s -= k_uptime_get();
|
sync_offset_s -= k_uptime_get();
|
||||||
|
|
||||||
synchronized = true;
|
synchronized = true;
|
||||||
|
|
||||||
printk("✅ Synchronisiert! Offset: %u Sekunden\n", sync_offset_s);
|
printk("Synchronisiert! Offset: %u Sekunden\n", sync_offset_s);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
20
src/main.c
20
src/main.c
@ -2,7 +2,7 @@
|
|||||||
#include <zephyr/kernel.h>
|
#include <zephyr/kernel.h>
|
||||||
#include <zephyr/sys/printk.h>
|
#include <zephyr/sys/printk.h>
|
||||||
|
|
||||||
#include "epaper/epaper.h"
|
#include "utils/displayController.h"
|
||||||
//#include "oled/oled.h"
|
//#include "oled/oled.h"
|
||||||
|
|
||||||
#include "lora/lora.h"
|
#include "lora/lora.h"
|
||||||
@ -11,7 +11,6 @@
|
|||||||
|
|
||||||
#include "utils/buttons.h"
|
#include "utils/buttons.h"
|
||||||
#include "utils/leds.h"
|
#include "utils/leds.h"
|
||||||
#include "utils/constAndVars.h"
|
|
||||||
|
|
||||||
struct k_work_delayable lora_check_work;
|
struct k_work_delayable lora_check_work;
|
||||||
|
|
||||||
@ -42,17 +41,16 @@ void run_master(void) {
|
|||||||
// Master-spezifische Logik
|
// Master-spezifische Logik
|
||||||
}
|
}
|
||||||
|
|
||||||
int run_slave(void)
|
int run_slave(const char *display_type, int display_slot)
|
||||||
{
|
{
|
||||||
printk("Running as SLAVE\n");
|
printk("Running as SLAVE\n");
|
||||||
if (init_led_and_button() != 0) {
|
if (init_led_and_button() != 0) {
|
||||||
printk("❌ GPIO-Initialisierung fehlgeschlagen\n");
|
printk("❌ GPIO-Initialisierung fehlgeschlagen\n");
|
||||||
error = true;
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
epd_init();
|
|
||||||
|
|
||||||
|
dc_init(display_type, display_slot);
|
||||||
|
|
||||||
lora_init();
|
lora_init();
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
@ -62,12 +60,18 @@ int run_slave(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void main(void) {
|
int main(void) {
|
||||||
#if IS_ENABLED(CONFIG_DEVICE_MODE_MASTER)
|
#if IS_ENABLED(CONFIG_DEVICE_MODE_MASTER)
|
||||||
run_master();
|
run_master();
|
||||||
|
return 0;
|
||||||
#elif IS_ENABLED(CONFIG_DEVICE_MODE_SLAVE)
|
#elif IS_ENABLED(CONFIG_DEVICE_MODE_SLAVE)
|
||||||
run_slave();
|
const char *display_type = CONFIG_SLAVE_DISPLAY_TYPE;
|
||||||
|
int display_slot = CONFIG_SLAVE_DISPLAY_SLOT;
|
||||||
|
printk("Running slave mode with display type %s (Slot %d)\n", display_type, display_slot);
|
||||||
|
run_slave(display_type, display_slot);
|
||||||
|
return 0;
|
||||||
#else
|
#else
|
||||||
#error "No device mode selected. Please enable one mode in prj.conf or via build flags."
|
#error "No device mode selected. Please enable one mode in prj.conf or via build flags."
|
||||||
|
return -1;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
@ -29,7 +29,8 @@ struct k_thread input_thread_data;
|
|||||||
char latest_word[32] = "Hello!";
|
char latest_word[32] = "Hello!";
|
||||||
struct k_mutex word_mutex;
|
struct k_mutex word_mutex;
|
||||||
|
|
||||||
static DataPacket packet;
|
//static DataPacket packet;
|
||||||
|
|
||||||
struct lora_modem_config tx_config_master = {
|
struct lora_modem_config tx_config_master = {
|
||||||
.frequency = 868100000,
|
.frequency = 868100000,
|
||||||
.bandwidth = BW_125_KHZ,
|
.bandwidth = BW_125_KHZ,
|
||||||
|
4160
src/oled/font.c
Normal file
4160
src/oled/font.c
Normal file
File diff suppressed because it is too large
Load Diff
297
src/oled/oled.c
297
src/oled/oled.c
@ -4,11 +4,32 @@
|
|||||||
#include <zephyr/drivers/gpio.h>
|
#include <zephyr/drivers/gpio.h>
|
||||||
#include <zephyr/sys/printk.h>
|
#include <zephyr/sys/printk.h>
|
||||||
|
|
||||||
#include "oled/oled.h"
|
#include "oled/lv_font.h"
|
||||||
|
|
||||||
#define OLED_NODE DT_NODELABEL(oled)
|
#define OLED_NODE DT_NODELABEL(oled)
|
||||||
#define SPI_BUS DT_BUS(OLED_NODE)
|
#define SPI_BUS DT_BUS(OLED_NODE)
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t bitmap_index;
|
||||||
|
uint32_t adv_w;
|
||||||
|
uint16_t box_w;
|
||||||
|
uint16_t box_h;
|
||||||
|
int16_t ofs_x;
|
||||||
|
int16_t ofs_y;
|
||||||
|
} my_glyph_dsc_t;
|
||||||
|
|
||||||
|
#define OLED_W 128
|
||||||
|
#define OLED_H 64
|
||||||
|
#define OLED_PAGES (OLED_H/8)
|
||||||
|
|
||||||
|
/* ---- Cursor-Verwaltung --------------------------------------------------- */
|
||||||
|
static uint8_t cursor_x = 0; /* Pixel */
|
||||||
|
static uint8_t cursor_y = 0; /* Baseline in Pixel (0..63) */
|
||||||
|
|
||||||
|
extern bool my_font_get_glyph_dsc(uint8_t code, my_glyph_dsc_t *out);
|
||||||
|
extern const uint8_t *my_font_get_bitmap (uint8_t code);
|
||||||
|
|
||||||
// GPIOs
|
// GPIOs
|
||||||
static const struct gpio_dt_spec oled_cs = GPIO_DT_SPEC_GET(OLED_NODE, cs_gpios);
|
static const struct gpio_dt_spec oled_cs = GPIO_DT_SPEC_GET(OLED_NODE, cs_gpios);
|
||||||
static const struct gpio_dt_spec oled_dc = GPIO_DT_SPEC_GET(OLED_NODE, dc_gpios);
|
static const struct gpio_dt_spec oled_dc = GPIO_DT_SPEC_GET(OLED_NODE, dc_gpios);
|
||||||
@ -30,6 +51,11 @@ static struct spi_config spi_cfg = {
|
|||||||
#define OLED_RST_ASSERT gpio_pin_set_raw(oled_reset.port, oled_reset.pin, 0)
|
#define OLED_RST_ASSERT gpio_pin_set_raw(oled_reset.port, oled_reset.pin, 0)
|
||||||
#define OLED_RST_DEASSERT gpio_pin_set_raw(oled_reset.port, oled_reset.pin, 1)
|
#define OLED_RST_DEASSERT gpio_pin_set_raw(oled_reset.port, oled_reset.pin, 1)
|
||||||
|
|
||||||
|
// ---- prototypes (oberhalb von OLED_Show_Char) ----
|
||||||
|
static void oled_blit_rowpacked_to_pages(int x0, int y0,
|
||||||
|
int w, int h,
|
||||||
|
const uint8_t *bmp);
|
||||||
|
|
||||||
|
|
||||||
void oled_driver_delay_xms(uint32_t ms) {
|
void oled_driver_delay_xms(uint32_t ms) {
|
||||||
k_msleep(ms);
|
k_msleep(ms);
|
||||||
@ -58,7 +84,7 @@ void OLED_Write_Data(uint8_t *data, size_t len) {
|
|||||||
void OLED_Reset(void) {
|
void OLED_Reset(void) {
|
||||||
printk("Führe Hardware-Reset durch (Raw-Modus)...\n");
|
printk("Führe Hardware-Reset durch (Raw-Modus)...\n");
|
||||||
OLED_RST_ASSERT;
|
OLED_RST_ASSERT;
|
||||||
oled_driver_delay_xms(50);
|
oled_driver_delay_xms(100);
|
||||||
OLED_RST_DEASSERT;
|
OLED_RST_DEASSERT;
|
||||||
oled_driver_delay_xms(100);
|
oled_driver_delay_xms(100);
|
||||||
}
|
}
|
||||||
@ -68,65 +94,9 @@ void OLED_Reset(void) {
|
|||||||
* NEUE, ROBUSTERE INITIALISIERUNGSSEQUENZ (abgeleitet von U8g2 für SSD1309)
|
* NEUE, ROBUSTERE INITIALISIERUNGSSEQUENZ (abgeleitet von U8g2 für SSD1309)
|
||||||
* ========================================================================
|
* ========================================================================
|
||||||
*/
|
*/
|
||||||
void OLED_HW_Init(void) {
|
|
||||||
OLED_Reset();
|
|
||||||
printk("Sende ROBUSTERE Initialisierungssequenz...\n");
|
|
||||||
|
|
||||||
OLED_Write_Command(0xAE); // Display OFF
|
|
||||||
|
|
||||||
OLED_Write_Command(0xD5); // Set Display Clock Divide Ratio
|
|
||||||
OLED_Write_Command(0xA0); // Ein anderer, oft stabilerer Wert
|
|
||||||
|
|
||||||
OLED_Write_Command(0xA8); // Set Multiplex Ratio
|
|
||||||
OLED_Write_Command(0x3F); // 64 MUX
|
|
||||||
|
|
||||||
OLED_Write_Command(0xD3); // Set Display Offset
|
|
||||||
OLED_Write_Command(0x00); // No offset
|
|
||||||
|
|
||||||
OLED_Write_Command(0x40); // Set Start Line (0)
|
|
||||||
|
|
||||||
OLED_Write_Command(0x20); // Set Memory Addressing Mode
|
|
||||||
OLED_Write_Command(0x00); // Horizontal Addressing Mode
|
|
||||||
|
|
||||||
OLED_Write_Command(0xA1); // Set Segment Re-map (column address 127 is mapped to SEG0)
|
void oled_init(void) {
|
||||||
OLED_Write_Command(0xC8); // Set COM Output Scan Direction (scanned from COM[N-1] to COM0)
|
|
||||||
|
|
||||||
OLED_Write_Command(0xDA); // Set COM Pins Hardware Configuration
|
|
||||||
OLED_Write_Command(0x12);
|
|
||||||
|
|
||||||
OLED_Write_Command(0x81); // Set Contrast Control
|
|
||||||
OLED_Write_Command(0x80); // Ein mittlerer Wert
|
|
||||||
|
|
||||||
OLED_Write_Command(0xD9); // Set Pre-charge Period
|
|
||||||
OLED_Write_Command(0x22); // Ein anderer, oft stabilerer Wert
|
|
||||||
|
|
||||||
OLED_Write_Command(0xDB); // Set VCOMH Deselect Level
|
|
||||||
OLED_Write_Command(0x34); // ~0.83 x VCC
|
|
||||||
|
|
||||||
OLED_Write_Command(0xA4); // Entire Display ON, Output follows RAM content
|
|
||||||
OLED_Write_Command(0xA6); // Set Normal Display
|
|
||||||
|
|
||||||
OLED_Write_Command(0x8D); // Charge Pump Setting
|
|
||||||
OLED_Write_Command(0x14); // Enable Charge Pump
|
|
||||||
|
|
||||||
OLED_Write_Command(0xAF); // Display ON
|
|
||||||
|
|
||||||
printk("Initialisierung gesendet.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void OLED_WhiteScreen_White(void) {
|
|
||||||
uint8_t buffer[128];
|
|
||||||
memset(buffer, 0x00, sizeof(buffer)); // Alles auf 1 setzen für Weiß
|
|
||||||
for (uint8_t page = 0; page < 8; page++) {
|
|
||||||
OLED_Write_Command(0xB0 + page); // Set Page Address
|
|
||||||
OLED_Write_Command(0x00); // Lower column start address
|
|
||||||
OLED_Write_Command(0x10); // Higher column start address
|
|
||||||
OLED_Write_Data(buffer, sizeof(buffer));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void oled_draw_something(char toDraw) {
|
|
||||||
printk("OLED Init (Raw-Modus)...\n");
|
printk("OLED Init (Raw-Modus)...\n");
|
||||||
|
|
||||||
if (!device_is_ready(spi_dev)) {
|
if (!device_is_ready(spi_dev)) {
|
||||||
@ -149,12 +119,213 @@ void oled_draw_something(char toDraw) {
|
|||||||
|
|
||||||
k_msleep(100);
|
k_msleep(100);
|
||||||
|
|
||||||
OLED_HW_Init();
|
OLED_Reset();
|
||||||
|
printk("Sende ROBUSTERE Initialisierungssequenz...\n");
|
||||||
|
|
||||||
|
OLED_Write_Command(0xAE); // Display OFF
|
||||||
|
|
||||||
|
OLED_Write_Command(0xD5); // Set Display Clock Divide Ratio
|
||||||
|
OLED_Write_Command(0xA0); // Ein anderer, oft stabilerer Wert
|
||||||
|
|
||||||
|
OLED_Write_Command(0xA8); // Set Multiplex Ratio
|
||||||
|
OLED_Write_Command(0x3F); // 64 MUX
|
||||||
|
|
||||||
|
OLED_Write_Command(0xD3); // Set Display Offset
|
||||||
|
OLED_Write_Command(0x00); // No offset
|
||||||
|
|
||||||
|
OLED_Write_Command(0x40); // Set Start Line (0)
|
||||||
|
|
||||||
|
OLED_Write_Command(0x20); // Set Memory Addressing Mode
|
||||||
|
OLED_Write_Command(0x00); // Horizontal Addressing Mode
|
||||||
|
|
||||||
k_msleep(100); // Kleiner Delay nach der Initialisierung
|
OLED_Write_Command(0xA1); // Set Segment Re-map (column address 127 is mapped to SEG0)
|
||||||
|
OLED_Write_Command(0xC8); // Set COM Output Scan Direction (scanned from COM[N-1] to COM0)
|
||||||
|
|
||||||
printk("Display initialisiert. Fülle jetzt den Bildschirm weiß...\n");
|
OLED_Write_Command(0xDA); // Set COM Pins Hardware Configuration
|
||||||
OLED_WhiteScreen_White();
|
OLED_Write_Command(0x12);
|
||||||
|
|
||||||
|
OLED_Write_Command(0x81); // Set Contrast Control
|
||||||
|
OLED_Write_Command(0x80); // Ein mittlerer Wert
|
||||||
|
|
||||||
|
OLED_Write_Command(0xD9); // Set Pre-charge Period
|
||||||
|
OLED_Write_Command(0x22); // Ein anderer, oft stabilerer Wert
|
||||||
|
|
||||||
|
OLED_Write_Command(0xDB); // Set VCOMH Deselect Level
|
||||||
|
OLED_Write_Command(0x34); // ~0.83 x VCC
|
||||||
|
|
||||||
|
OLED_Write_Command(0xA4); // Entire Display ON, Output follows RAM content
|
||||||
|
OLED_Write_Command(0xA6); // Set Normal Display
|
||||||
|
|
||||||
|
OLED_Write_Command(0x8D); // Charge Pump Setting
|
||||||
|
OLED_Write_Command(0x14); // Enable Charge Pump
|
||||||
|
|
||||||
|
OLED_Write_Command(0xAF); // Display ON
|
||||||
|
|
||||||
|
k_msleep(100);
|
||||||
|
printk("Initialisierung gesendet.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OLED_WhiteScreen_White(void) {
|
||||||
|
uint8_t buffer[128];
|
||||||
|
memset(buffer, 0xFF, sizeof(buffer)); // Alles auf 1 setzen für Weiß
|
||||||
|
for (uint8_t page = 0; page < 8; page++) {
|
||||||
|
OLED_Write_Command(0xB0 + page); // Set Page Address
|
||||||
|
OLED_Write_Command(0x00); // Lower column start address
|
||||||
|
OLED_Write_Command(0x10); // Higher column start address
|
||||||
|
OLED_Write_Data(buffer, sizeof(buffer));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OLED_WhiteScreen_Black(void) {
|
||||||
|
uint8_t buffer[128];
|
||||||
|
memset(buffer, 0x00, sizeof(buffer)); // Alles auf 1 setzen für Weiß
|
||||||
|
for (uint8_t page = 0; page < 8; page++) {
|
||||||
|
OLED_Write_Command(0xB0 + page); // Set Page Address
|
||||||
|
OLED_Write_Command(0x00); // Lower column start address
|
||||||
|
OLED_Write_Command(0x10); // Higher column start address
|
||||||
|
OLED_Write_Data(buffer, sizeof(buffer));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OLED_Testpaints() {
|
||||||
|
for (uint8_t page = 0; page < 8; page++) {
|
||||||
|
OLED_Write_Command(0xB0 + page); // Set Page Address
|
||||||
|
OLED_Write_Command(0x00); // Lower Column Start
|
||||||
|
OLED_Write_Command(0x10); // Higher Column Start
|
||||||
|
|
||||||
|
uint8_t line_data[128];
|
||||||
|
if (page % 2 == 0) {
|
||||||
|
memset(line_data, 0xFF, sizeof(line_data)); // Voll (alle Pixel an)
|
||||||
|
} else {
|
||||||
|
memset(line_data, 0x00, sizeof(line_data)); // Leer
|
||||||
|
}
|
||||||
|
|
||||||
|
OLED_Write_Data(line_data, sizeof(line_data));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OLED_SetCursor(uint8_t x, uint8_t baseline_y) {
|
||||||
|
cursor_x = x;
|
||||||
|
cursor_y = baseline_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- Hilfsfunktionen ----------------------------------------------------- */
|
||||||
|
|
||||||
|
/* liest 1bpp-Pixel (MSB-first) aus einer zeilenweise gepackten Bitmap */
|
||||||
|
static inline uint8_t read_pixel_1bpp(const uint8_t *bmp,
|
||||||
|
uint16_t bw, uint16_t bh,
|
||||||
|
uint16_t x, uint16_t y)
|
||||||
|
{
|
||||||
|
if (x >= bw || y >= bh) return 0;
|
||||||
|
uint16_t bytes_per_row = (bw + 7) / 8;
|
||||||
|
uint16_t byte_index = y * bytes_per_row + (x >> 3);
|
||||||
|
uint8_t bit_mask = (uint8_t)(0x80u >> (x & 7)); /* MSB-first */
|
||||||
|
return (bmp[byte_index] & bit_mask) ? 1u : 0u;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* setzt die Spalten-/Pageadresse im SSD1306 */
|
||||||
|
static inline void ssd1306_set_pos(uint8_t page, uint8_t col)
|
||||||
|
{
|
||||||
|
OLED_Write_Command(0xB0 | (page & 0x07)); /* Page Address */
|
||||||
|
OLED_Write_Command(0x00 | (col & 0x0F)); /* Low Col Addr */
|
||||||
|
OLED_Write_Command(0x10 | (col >> 4)); /* High Col Addr */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- Zeichen-Ausgabe ----------------------------------------------------- */
|
||||||
|
|
||||||
|
void OLED_Show_Char(char ch)
|
||||||
|
{
|
||||||
|
my_glyph_dsc_t gd;
|
||||||
|
if (!my_font_get_glyph_dsc((uint8_t)ch, &gd)) return;
|
||||||
|
const uint8_t *bmp = my_font_get_bitmap((uint8_t)ch);
|
||||||
|
if (!bmp) return;
|
||||||
|
|
||||||
|
// x,y nach Wunsch; Bounds prüfen (128x64 anpassen)
|
||||||
|
int x = 16;
|
||||||
|
int y = 8;
|
||||||
|
if (x < 0 || x + gd.box_w > 128 || y < 0 || y + gd.box_h > 64) return;
|
||||||
|
|
||||||
|
oled_blit_rowpacked_to_pages(x, y, gd.box_w, gd.box_h, bmp);
|
||||||
|
|
||||||
|
|
||||||
|
// Jetzt korrekt umgepackt blitten
|
||||||
|
oled_blit_rowpacked_to_pages(x, y, gd.box_w, gd.box_h, bmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Praktisch: String-Ausgabe mit einfacher Zeilenumbruch-Logik */
|
||||||
|
void OLED_Puts(const char *s)
|
||||||
|
{
|
||||||
|
while (*s) {
|
||||||
|
if (*s == '\n') {
|
||||||
|
cursor_x = 0;
|
||||||
|
/* eine Zeile = 8 Pixel Pages; nimm z.B. 16px Zeilenhöhe */
|
||||||
|
if (cursor_y + 16 < OLED_H) cursor_y += 16;
|
||||||
|
++s;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
OLED_Show_Char(*s++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// liest ein Bit aus der zeilenweise (row-packed) LVGL-Bitmap
|
||||||
|
static inline uint8_t get_bit_rowpacked(const uint8_t *bmp, int x, int y, int w) {
|
||||||
|
int bit_index = y * w + x; // 1bpp
|
||||||
|
return (bmp[bit_index >> 3] >> (7 - (bit_index & 7))) & 1;
|
||||||
|
}
|
||||||
|
// Quell-Bitmap: row-packed (MSB links), Größe w x h
|
||||||
|
static void oled_blit_rowpacked_to_pages(int x0, int y0,
|
||||||
|
int w, int h,
|
||||||
|
const uint8_t *bmp)
|
||||||
|
{
|
||||||
|
if (!bmp || w <= 0 || h <= 0) return;
|
||||||
|
|
||||||
|
const int bpr = (w + 7) / 8; // Bytes pro Quellzeile
|
||||||
|
int page0 = y0 >> 3; // erste Ziel-Page
|
||||||
|
int y_off = y0 & 7; // vertikaler Bit-Offset innerhalb der Page
|
||||||
|
int pages = (h + y_off + 7) / 8; // wie viele Pages werden berührt
|
||||||
|
|
||||||
|
for (int p = 0; p < pages; p++) {
|
||||||
|
// Page + Spaltenadresse setzen
|
||||||
|
OLED_Write_Command(0xB0 + (page0 + p));
|
||||||
|
OLED_Write_Command(0x00 | (x0 & 0x0F));
|
||||||
|
OLED_Write_Command(0x10 | ((x0 >> 4) & 0x0F));
|
||||||
|
|
||||||
|
// Für jede Spalte ein Byte aufbauen (8 vertikale Pixel)
|
||||||
|
for (int x = 0; x < w; x++) {
|
||||||
|
uint8_t out = 0;
|
||||||
|
|
||||||
|
for (int bit = 0; bit < 8; bit++) {
|
||||||
|
int src_y = p * 8 + bit - y_off; // dazugehörige Quellzeile
|
||||||
|
if ((unsigned)src_y < (unsigned)h) {
|
||||||
|
// Bit aus row-packed Zeile holen (MSB = linkes Pixel)
|
||||||
|
int byte_idx = src_y * bpr + (x >> 3);
|
||||||
|
uint8_t mask = 0x80u >> (x & 7);
|
||||||
|
if (bmp[byte_idx] & mask) {
|
||||||
|
out |= (1u << bit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OLED_Write_Data(&out, 1); // exakt 1 Byte pro Spalte!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void oled_draw_something(char toDraw) {
|
||||||
|
OLED_Testpaints();
|
||||||
|
|
||||||
|
k_msleep(2000);
|
||||||
|
OLED_WhiteScreen_Black();
|
||||||
|
k_msleep(1000);
|
||||||
|
|
||||||
|
|
||||||
|
OLED_Show_Char('L');
|
||||||
|
|
||||||
printk("Display-Finish! Der Bildschirm sollte jetzt weiß sein.\n");
|
printk("Display-Finish! Der Bildschirm sollte jetzt weiß sein.\n");
|
||||||
}
|
}
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
#include "utils/constAndVars.h"
|
|
||||||
|
|
||||||
bool slave = false;
|
|
||||||
bool error = false;
|
|
||||||
uint32_t nextSynchro = -1;
|
|
||||||
bool synchronized = false;
|
|
64
src/utils/displayController.c
Normal file
64
src/utils/displayController.c
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#include <zephyr/kernel.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "utils/displayController.h"
|
||||||
|
#include "epaper/epaper.h"
|
||||||
|
#include "oled/oled.h"
|
||||||
|
|
||||||
|
static enum display_type_e {
|
||||||
|
DISPLAY_NONE,
|
||||||
|
DISPLAY_OLED,
|
||||||
|
DISPLAY_EPD
|
||||||
|
} display_type = DISPLAY_NONE;
|
||||||
|
|
||||||
|
static int display_slot = 0;
|
||||||
|
static bool initialized = false;
|
||||||
|
|
||||||
|
void dc_init(const char *type_str, int slot) {
|
||||||
|
if (initialized) return;
|
||||||
|
|
||||||
|
display_slot = slot;
|
||||||
|
|
||||||
|
if (strcmp(type_str, "EPD") == 0) {
|
||||||
|
#if DT_NODE_EXISTS(DT_NODELABEL(epd))
|
||||||
|
epd_init();
|
||||||
|
display_type = DISPLAY_EPD;
|
||||||
|
printk("EPD Display initialisiert (Slot %d)\n", slot);
|
||||||
|
#else
|
||||||
|
printk("Fehler: EPD ausgewählt, aber nicht im Devicetree vorhanden!\n");
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
} else if (strcmp(type_str, "OLED") == 0) {
|
||||||
|
#if DT_NODE_EXISTS(DT_NODELABEL(oled))
|
||||||
|
oled_init();
|
||||||
|
oled_draw_something('4');
|
||||||
|
display_type = DISPLAY_OLED;
|
||||||
|
printk("OLED Display initialisiert (Slot %d)\n", slot);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
display_type = DISPLAY_NONE;
|
||||||
|
printk("Unbekannter Displaytyp: %s\n", type_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void dc_draw_something(char to_draw) {
|
||||||
|
switch (display_type) {
|
||||||
|
case DISPLAY_EPD:
|
||||||
|
#if DT_NODE_EXISTS(DT_NODELABEL(epd))
|
||||||
|
epd_draw_something(to_draw);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case DISPLAY_OLED:
|
||||||
|
#if DT_NODE_EXISTS(DT_NODELABEL(oled))
|
||||||
|
oled_draw_something(to_draw);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
printk("Kein gültiges Display initialisiert\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user