Cleaning Up etc
This commit is contained in:
parent
e64477b9f0
commit
3c824eaa73
@ -16,7 +16,7 @@ void epd_init(void);
|
||||
|
||||
void epd_update(void);
|
||||
void epd_clear_black(void);
|
||||
void epd_clear_white(void);
|
||||
void epd_clear();
|
||||
void epd_display_buffer(const unsigned char *buffer);
|
||||
|
||||
void epd_draw_something(char toDraw);
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
extern const uint8_t XOR_KEY;
|
||||
|
||||
void xorCrypt(const char *input, char *output, uint8_t key);
|
||||
uint16_t computeCRC16(const char *data);
|
||||
size_t xorCryptBytes(const uint8_t *in, uint8_t *out, size_t len, uint8_t key);
|
||||
uint16_t computeCRC16(const uint8_t *data, size_t len);
|
||||
|
||||
#endif
|
@ -3,9 +3,13 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define MAX_MSG 64
|
||||
|
||||
typedef struct {
|
||||
char message[20];
|
||||
uint32_t timestamp;
|
||||
uint16_t len; // Länge der Nutzdaten
|
||||
uint16_t crc; // CRC über message[0..len-1]
|
||||
uint32_t timestamp; // z.B. Restzeit / Marker
|
||||
uint8_t message[MAX_MSG];
|
||||
} __attribute__((packed)) DataPacket;
|
||||
|
||||
#endif // LORA_PACKET_H
|
@ -5,7 +5,6 @@
|
||||
|
||||
#define MAX_SAMPLES 10
|
||||
|
||||
// Vorwärtsdeklarationen
|
||||
void synchronite(struct k_work *work);
|
||||
|
||||
#endif
|
@ -5,8 +5,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Deklarationen der Bitmaps mit 'extern'
|
||||
// 'extern' sagt dem Compiler: "Diese Variable existiert, aber sie ist in einer anderen .c-Datei definiert."
|
||||
// Deklarationen der Bitmaps
|
||||
extern const uint8_t oled_fullscreen_A[];
|
||||
extern const uint8_t oled_fullscreen_B[];
|
||||
extern const uint8_t oled_fullscreen_C[];
|
||||
@ -34,7 +33,6 @@ extern const uint8_t oled_fullscreen_Y[];
|
||||
extern const uint8_t oled_fullscreen_X[];
|
||||
extern const uint8_t oled_fullscreen_Z[];
|
||||
|
||||
// Falls du diese auch hast:
|
||||
extern const uint8_t oled_fullscreen_allArray_LEN;
|
||||
extern const uint8_t* oled_fullscreen_allArray[];
|
||||
|
||||
|
@ -3,16 +3,13 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// ## 1. Konstanten ##
|
||||
#define CHAR_WIDTH 32
|
||||
#define CHAR_HEIGHT 16
|
||||
#define CHAR_BYTES 64
|
||||
|
||||
// ## 2. Globale Variablen (mit "extern") ##
|
||||
extern const uint8_t fullscreen_allArray_LEN;
|
||||
extern const unsigned char* fullscreen_allArray[36];
|
||||
|
||||
// ## 3. Funktions-Prototypen ##
|
||||
typedef void (*set_pixel_func_t)(uint8_t* framebuffer, int fb_width, int x, int y);
|
||||
void set_pixel(uint8_t* framebuffer, int fb_width, int x, int y);
|
||||
void create_fullscreen_char(char character, uint8_t* framebuffer, int fb_width, int fb_height, uint8_t scale);
|
||||
|
@ -32,13 +32,13 @@ static struct spi_config spi_cfg = {
|
||||
};
|
||||
|
||||
// GPIO Makros
|
||||
#define EPD_W21_CS_0 gpio_pin_set_dt(&epd_cs, 0)
|
||||
#define EPD_W21_CS_1 gpio_pin_set_dt(&epd_cs, 1)
|
||||
#define EPD_W21_DC_0 gpio_pin_set_dt(&epd_dc, 0)
|
||||
#define EPD_W21_DC_1 gpio_pin_set_dt(&epd_dc, 1)
|
||||
#define EPD_W21_RST_0 gpio_pin_set_dt(&epd_reset, 0)
|
||||
#define EPD_W21_RST_1 gpio_pin_set_dt(&epd_reset, 1)
|
||||
#define isEPD_W21_BUSY gpio_pin_get_dt(&epd_busy)
|
||||
#define EPD_CS_0 gpio_pin_set_dt(&epd_cs, 0)
|
||||
#define EPD_CS_1 gpio_pin_set_dt(&epd_cs, 1)
|
||||
#define EPD_DC_0 gpio_pin_set_dt(&epd_dc, 0)
|
||||
#define EPD_DC_1 gpio_pin_set_dt(&epd_dc, 1)
|
||||
#define EPD_RST_0 gpio_pin_set_dt(&epd_reset, 0)
|
||||
#define EPD_RST_1 gpio_pin_set_dt(&epd_reset, 1)
|
||||
#define isEPD_BUSY gpio_pin_get_dt(&epd_busy)
|
||||
|
||||
const uint8_t lut_full_update[] = {
|
||||
0xA0, 0x99, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
@ -56,7 +56,7 @@ void driver_delay_xms(int32_t xms) {
|
||||
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
|
||||
tx_data[0] = value;
|
||||
|
||||
struct spi_buf buf = {
|
||||
.buf = (uint8_t *)tx_data, // explizit casten
|
||||
@ -75,25 +75,26 @@ void epd_spi_writeByte(uint8_t value) {
|
||||
|
||||
|
||||
void epd_readbusy(void) {
|
||||
while (isEPD_W21_BUSY) {
|
||||
while (isEPD_BUSY) {
|
||||
k_msleep(100);
|
||||
}
|
||||
}
|
||||
|
||||
void epd_write_command(uint8_t cmd) {
|
||||
EPD_W21_DC_0; // DC auf Command setzen
|
||||
EPD_DC_0; // DC auf Command setzen
|
||||
epd_spi_writeByte(cmd);
|
||||
}
|
||||
|
||||
void epd_write_data(uint8_t data) {
|
||||
EPD_W21_DC_1; // DC auf Data setzen
|
||||
EPD_DC_1; // DC auf Data setzen
|
||||
epd_spi_writeByte(data);
|
||||
}
|
||||
|
||||
void epd_init_sequence(void) {
|
||||
EPD_W21_RST_0;
|
||||
|
||||
EPD_RST_0;
|
||||
k_msleep(10); // Ein kurzer Reset-Puls ist oft besser
|
||||
EPD_W21_RST_1;
|
||||
EPD_RST_1;
|
||||
k_msleep(100);
|
||||
|
||||
epd_readbusy();
|
||||
@ -138,7 +139,7 @@ void epd_init_sequence(void) {
|
||||
epd_write_command(0x18); // Temperature Sensor Control
|
||||
epd_write_data(0x80); // Internen Sensor verwenden
|
||||
|
||||
// Schreibe die finale LUT in den Controller
|
||||
// Schreibe die LUT in den Controller
|
||||
epd_write_command(0x32);
|
||||
for (int i = 0; i < sizeof(lut_full_update); i++) {
|
||||
epd_write_data(lut_full_update[i]);
|
||||
@ -174,127 +175,106 @@ void epd_init(void){
|
||||
epd_clear(); // Zweiter Clear-Durchgang
|
||||
|
||||
// vor dem Malen den Cursor auf den Anfang (0,0) setzen
|
||||
EPD_W21_CS_0;
|
||||
EPD_CS_0;
|
||||
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;
|
||||
EPD_CS_1;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void epd_update(void) {
|
||||
epd_write_command(0x22);
|
||||
epd_write_data(0xC7); //war FF
|
||||
epd_write_data(0xFF); //war FF
|
||||
epd_write_command(0x20);
|
||||
epd_readbusy();
|
||||
}
|
||||
|
||||
// Beispiel für das Senden eines Bildes
|
||||
void epd_whitescreen_all(const uint8_t *datas) {
|
||||
void epd_setPosition(void) {
|
||||
// sicheres Set vor 0x24
|
||||
//epd_write_command(0x11); epd_write_data(0x01); // zeilenweise
|
||||
epd_write_command(0x11); epd_write_data(0x01); // zeilenweise
|
||||
|
||||
//epd_write_command(0x44); epd_write_data(0x00); epd_write_data(0x1F); // X: 0..31 (Bytes)
|
||||
//epd_write_command(0x45); epd_write_data(0x00); epd_write_data(0x00);
|
||||
// epd_write_data(0x79); epd_write_data(0x00); // Y: 0..121 (Zeilen)
|
||||
epd_write_command(0x44); epd_write_data(0x00); epd_write_data(0x1F); // X: 0..31 (Bytes)
|
||||
epd_write_command(0x45); epd_write_data(0x00); epd_write_data(0x00);
|
||||
epd_write_data(0x79); epd_write_data(0x00); // Y: 0..121 (Zeilen)
|
||||
|
||||
//epd_write_command(0x4E); epd_write_data(0x00); // X-Zähler = 0
|
||||
//epd_write_command(0x4F); epd_write_data(0x00); epd_write_data(0x00); // Y-Zähler = 0
|
||||
EPD_W21_CS_0; // <-- CS hier aktivieren (LOW)
|
||||
epd_write_command(0x4E); epd_write_data(0x00); // X-Zähler = 0
|
||||
epd_write_command(0x4F); epd_write_data(0x00); epd_write_data(0x00); // Y-Zähler = 0
|
||||
}
|
||||
|
||||
void epd_whitescreen_all(const uint8_t *datas) {
|
||||
epd_setPosition();
|
||||
EPD_CS_0; // <-- CS hier aktivieren (LOW)
|
||||
|
||||
epd_write_command(0x24); // Command: write RAM for black/white image
|
||||
for (int i = 0; i < ALLSCREEN_GRAGHBYTES; i++) {
|
||||
epd_write_data(datas[i]);
|
||||
}
|
||||
|
||||
EPD_W21_CS_1; // <-- CS hier deaktivieren (HIGH)
|
||||
EPD_CS_1; // <-- CS hier deaktivieren (HIGH)
|
||||
|
||||
// Der Update-Befehl ist eine eigene Transaktion
|
||||
EPD_W21_CS_0;
|
||||
EPD_CS_0;
|
||||
epd_update();
|
||||
EPD_W21_CS_1;
|
||||
EPD_CS_1;
|
||||
}
|
||||
|
||||
// Beispiel für das komplette Löschen des Bildschirms
|
||||
void epd_whitescreen_black(void) {
|
||||
EPD_W21_CS_0; // <-- CS hier aktivieren (LOW)
|
||||
epd_setPosition();
|
||||
EPD_CS_0; // <-- CS hier aktivieren (LOW)
|
||||
|
||||
epd_write_command(0x24);
|
||||
for (int i = 0; i < ALLSCREEN_GRAGHBYTES; i++) {
|
||||
epd_write_data(0x00); // Schwarz
|
||||
}
|
||||
|
||||
EPD_W21_CS_1; // <-- CS hier deaktivieren (HIGH)
|
||||
EPD_CS_1; // <-- CS hier deaktivieren (HIGH)
|
||||
|
||||
// Der Update-Befehl ist eine eigene Transaktion
|
||||
EPD_W21_CS_0;
|
||||
EPD_CS_0;
|
||||
epd_update();
|
||||
EPD_W21_CS_1;
|
||||
}
|
||||
// Dasselbe musst du für EPD_WhiteScreen_White() machen.
|
||||
|
||||
|
||||
void epd_whitescreen_white(void) {
|
||||
EPD_W21_CS_0; // <-- CS hier aktivieren (LOW)
|
||||
epd_write_command(0x24);
|
||||
for (int i = 0; i < ALLSCREEN_GRAGHBYTES; i++) {
|
||||
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_W21_CS_1;
|
||||
EPD_CS_1;
|
||||
}
|
||||
|
||||
void epd_clear(void) {
|
||||
epd_setPosition();
|
||||
printk("Clearing display...\n");
|
||||
// sicheres Set vor 0x24
|
||||
//epd_write_command(0x11); epd_write_data(0x01); // zeilenweise
|
||||
|
||||
//epd_write_command(0x44); epd_write_data(0x00); epd_write_data(0x1F); // X: 0..31 (Bytes)
|
||||
//epd_write_command(0x45); epd_write_data(0x00); epd_write_data(0x00);
|
||||
// epd_write_data(0x79); epd_write_data(0x00); // Y: 0..121 (Zeilen)
|
||||
|
||||
//epd_write_command(0x4E); epd_write_data(0x00); // X-Zähler = 0
|
||||
//epd_write_command(0x4F); epd_write_data(0x00); epd_write_data(0x00); // Y-Zähler = 0
|
||||
|
||||
// RAM für das Bild mit "Weiß" füllen
|
||||
EPD_W21_CS_0;
|
||||
EPD_CS_0;
|
||||
epd_write_command(0x24); // Schreibe in den RAM
|
||||
for (int i = 0; i < ALLSCREEN_GRAGHBYTES; i++) {
|
||||
epd_write_data(0xFF); // 0xFF = Weiß
|
||||
}
|
||||
EPD_W21_CS_1;
|
||||
EPD_CS_1;
|
||||
|
||||
// Physisches Update starten, um den Bildschirm zu reinigen
|
||||
EPD_W21_CS_0;
|
||||
EPD_CS_0;
|
||||
epd_update();
|
||||
EPD_W21_CS_1;
|
||||
EPD_CS_1;
|
||||
|
||||
epd_readbusy(); // Warten, bis der Clear-Vorgang abgeschlossen ist
|
||||
}
|
||||
|
||||
void epd_draw_something(char toDraw) {
|
||||
draw_char(toDraw, epaper_framebuffer, 256, HEIGHT, 17);
|
||||
epd_whitescreen_all(epaper_framebuffer);
|
||||
draw_char('K', epaper_framebuffer, 256, HEIGHT, 17);
|
||||
|
||||
EPD_W21_CS_0;
|
||||
epd_write_command(0x24);
|
||||
for (int i = 0; i < ALLSCREEN_GRAGHBYTES; i++) {
|
||||
epd_write_data(epaper_framebuffer[i]);
|
||||
}
|
||||
EPD_W21_CS_1;
|
||||
|
||||
|
||||
// Physisches Update
|
||||
printk("Aktualisiere Display...\n");
|
||||
EPD_W21_CS_0;
|
||||
epd_update();
|
||||
EPD_W21_CS_1;
|
||||
|
||||
printk("Display-Finish.\n");
|
||||
|
||||
epd_readbusy(); // BUSY = 0 → bereit
|
||||
|
||||
epd_write_command(0x02); // POWER_OFF
|
||||
epd_readbusy(); // warten bis off
|
||||
|
||||
epd_write_command(0x10); // DEEP_SLEEP
|
||||
epd_write_data(0x01);
|
||||
k_msleep(5);
|
||||
|
||||
gpio_pin_set_dt(&epd_cs, 0);
|
||||
gpio_pin_set_dt(&epd_dc, 0);
|
||||
gpio_pin_set_dt(&epd_reset, 0);
|
||||
}
|
@ -10,61 +10,61 @@ const unsigned char font5x7[] = {
|
||||
0x00, 0x00, 0x5F, 0x00, 0x00, // !
|
||||
0x00, 0x07, 0x00, 0x07, 0x00, // "
|
||||
0x14, 0x7F, 0x14, 0x7F, 0x14, // #
|
||||
0x24, 0x2A, 0x7F, 0x2A, 0x12, // $
|
||||
0x23, 0x13, 0x08, 0x64, 0x62, // %
|
||||
0x36, 0x49, 0x55, 0x22, 0x50, // &
|
||||
0x00, 0x05, 0x03, 0x00, 0x00, // '
|
||||
0x00, 0x1C, 0x22, 0x41, 0x00, // (
|
||||
0x00, 0x41, 0x22, 0x1C, 0x00, // )
|
||||
0x12, 0x2A, 0x7F, 0x2A, 0x24, // $
|
||||
0x62, 0x64, 0x08, 0x13, 0x23, // %
|
||||
0x50, 0x22, 0x55, 0x49, 0x36, // &
|
||||
0x00, 0x00, 0x03, 0x05, 0x00, // '
|
||||
0x00, 0x41, 0x22, 0x1C, 0x00, // (
|
||||
0x00, 0x1C, 0x22, 0x41, 0x00, // )
|
||||
0x08, 0x2A, 0x1C, 0x2A, 0x08, // *
|
||||
0x08, 0x08, 0x3E, 0x08, 0x08, // +
|
||||
0x00, 0x50, 0x30, 0x00, 0x00, // ,
|
||||
0x00, 0x00, 0x30, 0x50, 0x00, // ,
|
||||
0x08, 0x08, 0x08, 0x08, 0x08, // -
|
||||
0x00, 0x60, 0x60, 0x00, 0x00, // .
|
||||
0x20, 0x10, 0x08, 0x04, 0x02, // /
|
||||
0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
|
||||
0x00, 0x42, 0x7F, 0x40, 0x00, // 1
|
||||
0x42, 0x61, 0x51, 0x49, 0x46, // 2
|
||||
0x21, 0x41, 0x45, 0x4B, 0x31, // 3
|
||||
0x18, 0x14, 0x12, 0x7F, 0x10, // 4
|
||||
0x27, 0x45, 0x45, 0x45, 0x39, // 5
|
||||
0x3C, 0x4A, 0x49, 0x49, 0x30, // 6
|
||||
0x01, 0x71, 0x09, 0x05, 0x03, // 7
|
||||
0x00, 0x00, 0x60, 0x60, 0x00, // .
|
||||
0x02, 0x04, 0x08, 0x10, 0x20, // /
|
||||
0x3E, 0x45, 0x49, 0x51, 0x3E, // 0
|
||||
0x00, 0x40, 0x7F, 0x42, 0x00, // 1
|
||||
0x46, 0x49, 0x51, 0x61, 0x42, // 2
|
||||
0x31, 0x4B, 0x45, 0x41, 0x21, // 3
|
||||
0x10, 0x7F, 0x12, 0x14, 0x18, // 4
|
||||
0x39, 0x45, 0x45, 0x45, 0x27, // 5
|
||||
0x3C, 0x66, 0x66, 0x49, 0x3C, // 6
|
||||
0x03, 0x05, 0x09, 0x71, 0x01, // 7
|
||||
0x36, 0x49, 0x49, 0x49, 0x36, // 8
|
||||
0x06, 0x49, 0x49, 0x29, 0x1E, // 9
|
||||
0x00, 0x36, 0x36, 0x00, 0x00, // :
|
||||
0x00, 0x56, 0x36, 0x00, 0x00, // ;
|
||||
0x00, 0x08, 0x14, 0x22, 0x41, // <
|
||||
0x1E, 0x29, 0x49, 0x49, 0x06, // 9
|
||||
0x00, 0x00, 0x36, 0x36, 0x00, // :
|
||||
0x00, 0x00, 0x36, 0x56, 0x00, // ;
|
||||
0x41, 0x22, 0x14, 0x08, 0x00, // <
|
||||
0x14, 0x14, 0x14, 0x14, 0x14, // =
|
||||
0x41, 0x22, 0x14, 0x08, 0x00, // >
|
||||
0x02, 0x01, 0x51, 0x09, 0x06, // ?
|
||||
0x32, 0x49, 0x79, 0x41, 0x3E, // @
|
||||
0x00, 0x08, 0x14, 0x22, 0x41, // >
|
||||
0x06, 0x09, 0x51, 0x01, 0x02, // ?
|
||||
0x3E, 0x41, 0x79, 0x49, 0x32, // @
|
||||
0x7E, 0x11, 0x11, 0x11, 0x7E, // A
|
||||
0x7F, 0x49, 0x49, 0x49, 0x36, // B
|
||||
0x3E, 0x41, 0x41, 0x41, 0x22, // C
|
||||
0x7F, 0x41, 0x41, 0x22, 0x1C, // D
|
||||
0x7F, 0x49, 0x49, 0x49, 0x41, // E
|
||||
0x7F, 0x09, 0x09, 0x01, 0x01, // F
|
||||
0x3E, 0x41, 0x41, 0x51, 0x32, // G
|
||||
0x36, 0x49, 0x49, 0x49, 0x7F, // B
|
||||
0x22, 0x41, 0x41, 0x41, 0x3E, // C
|
||||
0x1C, 0x22, 0x41, 0x41, 0x7F, // D
|
||||
0x41, 0x49, 0x49, 0x49, 0x7F, // E
|
||||
0x01, 0x01, 0x09, 0x09, 0x7F, // F
|
||||
0x32, 0x51, 0x41, 0x41, 0x3E, // G
|
||||
0x7F, 0x08, 0x08, 0x08, 0x7F, // H
|
||||
0x00, 0x41, 0x7F, 0x41, 0x00, // I
|
||||
0x20, 0x40, 0x41, 0x3F, 0x01, // J
|
||||
0x7F, 0x08, 0x14, 0x22, 0x41, // K
|
||||
0x7F, 0x40, 0x40, 0x40, 0x40, // L
|
||||
0x01, 0x3F, 0x41, 0x40, 0x20, // J
|
||||
0x41, 0x22, 0x14, 0x08, 0x7F, // K
|
||||
0x40, 0x40, 0x40, 0x40, 0x7F, // L
|
||||
0x7F, 0x02, 0x04, 0x02, 0x7F, // M
|
||||
0x7F, 0x04, 0x08, 0x10, 0x7F, // N
|
||||
0x7F, 0x10, 0x08, 0x04, 0x7F, // N
|
||||
0x3E, 0x41, 0x41, 0x41, 0x3E, // O
|
||||
0x7F, 0x09, 0x09, 0x09, 0x06, // P
|
||||
0x3E, 0x41, 0x51, 0x21, 0x5E, // Q
|
||||
0x7F, 0x09, 0x19, 0x29, 0x46, // R
|
||||
0x46, 0x49, 0x49, 0x49, 0x31, // S
|
||||
0x06, 0x09, 0x09, 0x09, 0x7F, // P
|
||||
0x5E, 0x21, 0x51, 0x41, 0x3E, // Q
|
||||
0x46, 0x29, 0x19, 0x09, 0x7F, // R
|
||||
0x31, 0x49, 0x49, 0x49, 0x46, // S
|
||||
0x01, 0x01, 0x7F, 0x01, 0x01, // T
|
||||
0x3F, 0x40, 0x40, 0x40, 0x3F, // U
|
||||
0x1F, 0x20, 0x40, 0x20, 0x1F, // V
|
||||
0x3F, 0x40, 0x38, 0x40, 0x3F, // W
|
||||
0x63, 0x14, 0x08, 0x14, 0x63, // X
|
||||
0x03, 0x04, 0x78, 0x04, 0x03, // Y
|
||||
0x61, 0x51, 0x49, 0x45, 0x43, // Z
|
||||
0x43, 0x45, 0x49, 0x51, 0x61, // Z
|
||||
};
|
||||
|
||||
void draw_char(char character, uint8_t* framebuffer, int fb_width, int fb_height, uint8_t scale) {
|
||||
@ -77,10 +77,8 @@ void draw_char(char character, uint8_t* framebuffer, int fb_width, int fb_height
|
||||
}
|
||||
const uint8_t* font_ptr = font5x7 + (character - ' ') * 5;
|
||||
|
||||
int scaled_width = 5 * scale;
|
||||
int scaled_height = 7 * scale;
|
||||
int start_x = 0;//(fb_width - scaled_width) / 2;
|
||||
int start_y = 0;//(fb_height - scaled_height) / 2;
|
||||
int start_x = 0;
|
||||
int start_y = 0;
|
||||
|
||||
// Zeichen Pixel für Pixel malen
|
||||
for (int y = 0; y < 7; y++) { // Höhe des Fonts ist 7
|
||||
|
@ -7,25 +7,19 @@
|
||||
|
||||
#include "lora/encryption.h"
|
||||
|
||||
const uint8_t XOR_KEY = 0x5Au;
|
||||
|
||||
void xorCrypt(const char *input, char *output, uint8_t key) {
|
||||
size_t len = strlen(input);
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
output[i] = input[i] ^ key;
|
||||
}
|
||||
output[len] = '\0'; // Null-Terminierung für gültige C-Strings
|
||||
size_t xorCryptBytes(const uint8_t *in, uint8_t *out, size_t len, uint8_t key) {
|
||||
for (size_t i = 0; i < len; i++) out[i] = in[i] ^ key;
|
||||
return len;
|
||||
}
|
||||
|
||||
uint16_t computeCRC16(const char *data) {
|
||||
|
||||
uint16_t computeCRC16(const uint8_t *data, size_t len) {
|
||||
uint16_t crc = 0xFFFF;
|
||||
for (size_t i = 0; i < strlen(data); i++) {
|
||||
crc ^= (uint8_t)data[i] << 8;
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
crc ^= (uint16_t)data[i] << 8;
|
||||
for (int j = 0; j < 8; j++) {
|
||||
if (crc & 0x8000)
|
||||
crc = (crc << 1) ^ 0x1021;
|
||||
else
|
||||
crc <<= 1;
|
||||
crc = (crc & 0x8000) ? (uint16_t)((crc << 1) ^ 0x1021) : (uint16_t)(crc << 1);
|
||||
}
|
||||
}
|
||||
return crc;
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/sys/printk.h>
|
||||
#include <zephyr/drivers/lora.h>
|
||||
#include <zephyr/sys/byteorder.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "utils/displayController.h"
|
||||
@ -17,7 +18,7 @@ const struct device *lora_dev = DEVICE_DT_GET(DT_ALIAS(lora0));
|
||||
|
||||
static volatile int rx_count = 0;
|
||||
static volatile bool message_received = false;
|
||||
char decoded[128];
|
||||
static char decoded[MAX_MSG + 1];
|
||||
uint32_t sleep_intervall_ms = 1;
|
||||
uint32_t start = 0;
|
||||
|
||||
@ -36,26 +37,41 @@ static struct lora_modem_config config = {
|
||||
.tx = false,
|
||||
};
|
||||
|
||||
static DataPacket packet;
|
||||
|
||||
void lora_receive_cb(const struct device *dev,
|
||||
uint8_t *data, uint16_t size,
|
||||
int16_t rssi, int8_t snr)
|
||||
{
|
||||
if (size == sizeof(DataPacket)) {
|
||||
memcpy(&packet, data, sizeof(DataPacket));
|
||||
rx_count++;
|
||||
sleep_intervall_ms = (120000 + packet.timestamp);
|
||||
printk("timestamp: %d, next: %d\n", packet.timestamp, sleep_intervall_ms);
|
||||
printk("Nachricht empfangen (%d Bytes): %s\n", rx_count, packet.message);
|
||||
uint32_t stop = k_uptime_get() - start;
|
||||
// Minimaler Header: 2(len)+2(crc)+4(ts) = 8
|
||||
if (size < 8) return;
|
||||
|
||||
xorCrypt(data, decoded, 0x5A);
|
||||
message_received = true;
|
||||
// Felder aus Big-Endian lesen
|
||||
uint16_t len = sys_get_be16(&data[0]);
|
||||
uint16_t rx_crc = sys_get_be16(&data[2]);
|
||||
uint32_t ts_ms = sys_get_be32(&data[4]);
|
||||
|
||||
printk("Zeitpunkt: %d\n", stop);
|
||||
disable_lora_receive();
|
||||
if (len > MAX_MSG) return;
|
||||
if (size < 8 + len) return; // unvollständig
|
||||
|
||||
const uint8_t *msg = &data[8];
|
||||
|
||||
// CRC prüfen (über verschlüsselte Payload)
|
||||
uint16_t calc = computeCRC16(msg, len);
|
||||
if (calc != rx_crc) {
|
||||
printk("CRC-Fehler: %04x != %04x\n", rx_crc, calc);
|
||||
return;
|
||||
}
|
||||
|
||||
// Entschlüsseln (erst NACH erfolgreicher CRC)
|
||||
size_t out_len = xorCryptBytes(msg, (uint8_t*)decoded, len, 0x5A);
|
||||
decoded[out_len] = '\0';
|
||||
|
||||
sleep_intervall_ms = (120000 + ts_ms);
|
||||
|
||||
message_received = true;
|
||||
disable_lora_receive();
|
||||
|
||||
|
||||
}
|
||||
|
||||
int enable_lora_receive(void)
|
||||
@ -103,11 +119,18 @@ void lora_thread(void *p1, void *p2, void *p3)
|
||||
|
||||
disable_lora_receive();
|
||||
|
||||
int64_t t0 = k_uptime_get();
|
||||
|
||||
if (message_received) {
|
||||
dc_draw_something(decoded);
|
||||
}
|
||||
|
||||
k_msleep(sleep_intervall_ms);
|
||||
int64_t timeToDraw = k_uptime_get() - t0;
|
||||
int64_t to_sleep = (int64_t)sleep_intervall_ms - timeToDraw;
|
||||
|
||||
if (to_sleep > 0) {
|
||||
k_msleep((int32_t)to_sleep);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
#include <zephyr/console/console.h>
|
||||
#include <zephyr/drivers/uart.h>
|
||||
#include <zephyr/kernel.h>
|
||||
#include <zephyr/sys/printk.h>
|
||||
#include <zephyr/device.h>
|
||||
#include <zephyr/sys/printk.h>
|
||||
#include <zephyr/drivers/uart.h>
|
||||
#include <zephyr/drivers/lora.h>
|
||||
#include <zephyr/sys/byteorder.h> // sys_cpu_to_be16/32, sys_be16_to_cpu
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@ -11,27 +12,30 @@
|
||||
#include "lora/lorapacket.h"
|
||||
|
||||
#define DEFAULT_RADIO_NODE DT_ALIAS(lora0)
|
||||
#define SEND_INTERVAL_MS 1000 // Sendeintervall in ms
|
||||
|
||||
#define SLEEP_INTERVAL_MS 120000
|
||||
#define UART_DEVICE_NODE DT_CHOSEN(zephyr_console)
|
||||
|
||||
#define STACK_SIZE 1024
|
||||
#define INPUT_STACK_SIZE 1024
|
||||
#define INPUT_PRIORITY 5
|
||||
|
||||
struct k_thread send_thread_data;
|
||||
#define ACTIVE_TIME_MS 10000
|
||||
#define SEND_INTERVAL_MS 1000
|
||||
#define SLEEP_INTERVAL_MS 120000
|
||||
|
||||
#define MAX_MSG 64
|
||||
|
||||
const struct device *lora_dev_master = DEVICE_DT_GET(DEFAULT_RADIO_NODE);
|
||||
const struct device *uart_console = DEVICE_DT_GET(UART_DEVICE_NODE);
|
||||
|
||||
K_THREAD_STACK_DEFINE(send_stack_area, STACK_SIZE);
|
||||
K_THREAD_STACK_DEFINE(input_stack_area, INPUT_STACK_SIZE);
|
||||
struct k_thread input_thread_data;
|
||||
static struct k_thread send_thread_data;
|
||||
static struct k_thread input_thread_data;
|
||||
static struct k_mutex word_mutex;
|
||||
|
||||
char latest_word[32] = "Hello!";
|
||||
char encrypted[64];
|
||||
struct k_mutex word_mutex;
|
||||
static char latest_word[32] = "HALLO!";
|
||||
|
||||
struct lora_modem_config tx_config_master = {
|
||||
static struct lora_modem_config tx_config_master = {
|
||||
.frequency = 868100000,
|
||||
.bandwidth = BW_125_KHZ,
|
||||
.datarate = SF_7,
|
||||
@ -41,99 +45,112 @@ struct lora_modem_config tx_config_master = {
|
||||
.tx = true,
|
||||
};
|
||||
|
||||
#define UART_DEVICE_NODE DT_CHOSEN(zephyr_console)
|
||||
const struct device *uart_console = DEVICE_DT_GET(UART_DEVICE_NODE);
|
||||
|
||||
void uart_input_get_line(char *buf, size_t max_len)
|
||||
static void uart_input_get_line(char *buf, size_t max_len)
|
||||
{
|
||||
size_t len = 0;
|
||||
char c;
|
||||
|
||||
while (len < max_len - 1) {
|
||||
if (uart_poll_in(uart_console, &c) == 0) {
|
||||
if (c == '\r' || c == '\n') {
|
||||
break;
|
||||
}
|
||||
if (c == '\r' || c == '\n') break;
|
||||
buf[len++] = c;
|
||||
printk("%c", c); // Echo
|
||||
}
|
||||
k_msleep(1);
|
||||
}
|
||||
|
||||
buf[len] = '\0';
|
||||
printk("\n");
|
||||
}
|
||||
|
||||
|
||||
void send_lora_message(const char* text, uint32_t timer)
|
||||
static int build_packet_snapshot(DataPacket *out_pkt, uint32_t timer_ms, char *dbg_plain, size_t dbg_sz)
|
||||
{
|
||||
int ret = lora_config(lora_dev_master, &tx_config_master);
|
||||
if (ret != 0) {
|
||||
printk("LoRa-Konfiguration fehlgeschlagen: %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
DataPacket pkt;
|
||||
|
||||
memset(&pkt, 0, sizeof(pkt));
|
||||
strncpy(pkt.message, encrypted, sizeof(pkt.message));
|
||||
pkt.timestamp = timer;
|
||||
|
||||
ret = lora_send(lora_dev_master, (uint8_t *)&pkt, sizeof(pkt));
|
||||
if (ret < 0) {
|
||||
printk("Senden fehlgeschlagen: %d\n", ret);
|
||||
} else {
|
||||
printk("Gesendet: \"%s\"\n", encrypted);
|
||||
}
|
||||
}
|
||||
|
||||
void send_loop_thread(void *p1, void *p2, void *p3)
|
||||
{
|
||||
const int active_time_ms = 10000;
|
||||
const int interval_ms = 1000;
|
||||
|
||||
char local_copy[32];
|
||||
|
||||
while (1) {
|
||||
|
||||
printk("Sendephase gestartet\n");
|
||||
|
||||
// Wort einfrieren
|
||||
char local_plain[sizeof(latest_word)];
|
||||
k_mutex_lock(&word_mutex, K_FOREVER);
|
||||
strncpy(local_copy, encrypted, sizeof(local_copy));
|
||||
local_copy[sizeof(local_copy) - 1] = '\0';
|
||||
strncpy(local_plain, latest_word, sizeof(local_plain));
|
||||
local_plain[sizeof(local_plain)-1] = '\0';
|
||||
k_mutex_unlock(&word_mutex);
|
||||
|
||||
for (size_t i = 0; local_plain[i] != '\0'; ++i) {
|
||||
local_plain[i] = (char)toupper((unsigned char)local_plain[i]);
|
||||
}
|
||||
|
||||
uint8_t local_enc[MAX_MSG];
|
||||
size_t plain_len = strnlen(local_plain, sizeof(local_plain));
|
||||
if (plain_len > MAX_MSG) plain_len = MAX_MSG;
|
||||
|
||||
size_t local_len = xorCryptBytes((const uint8_t*)local_plain, local_enc, plain_len, 0x5A);
|
||||
uint16_t local_crc = computeCRC16(local_enc, local_len);
|
||||
|
||||
memset(out_pkt, 0, sizeof(*out_pkt));
|
||||
out_pkt->len = sys_cpu_to_be16((uint16_t)local_len);
|
||||
out_pkt->crc = sys_cpu_to_be16(local_crc);
|
||||
out_pkt->timestamp = sys_cpu_to_be32(timer_ms);
|
||||
memcpy(out_pkt->message, local_enc, local_len);
|
||||
|
||||
if (dbg_plain && dbg_sz) {
|
||||
strncpy(dbg_plain, local_plain, dbg_sz);
|
||||
dbg_plain[dbg_sz - 1] = '\0';
|
||||
}
|
||||
return (int)local_len;
|
||||
}
|
||||
|
||||
static int send_packet_snapshot(const DataPacket *pkt, size_t payload_len)
|
||||
{
|
||||
size_t total = sizeof(pkt->len) + sizeof(pkt->crc) + sizeof(pkt->timestamp) + payload_len;
|
||||
return lora_send(lora_dev_master, (uint8_t *)pkt, total);
|
||||
}
|
||||
|
||||
static void send_loop_thread(void *p1, void *p2, void *p3)
|
||||
{
|
||||
DataPacket snapshot;
|
||||
size_t snap_len = 0;
|
||||
|
||||
while (1) {
|
||||
printk("Sendephase gestartet\n");
|
||||
|
||||
uint32_t start = k_uptime_get();
|
||||
while ((k_uptime_get() - start) < active_time_ms) {
|
||||
send_lora_message(local_copy, (active_time_ms - (k_uptime_get() - start)));
|
||||
k_msleep(interval_ms);
|
||||
|
||||
// Vor dem aktiven Fenster: Snapshot bauen
|
||||
char dbg[33];
|
||||
snap_len = (size_t)build_packet_snapshot(&snapshot, /*timer*/ACTIVE_TIME_MS, dbg, sizeof(dbg));
|
||||
printk("Snapshot von \"%s\" (len=%u)\n", dbg, (unsigned)snap_len);
|
||||
|
||||
while ((k_uptime_get() - start) < ACTIVE_TIME_MS) {
|
||||
uint32_t remaining = ACTIVE_TIME_MS - (k_uptime_get() - start);
|
||||
|
||||
((DataPacket*)&snapshot)->timestamp = sys_cpu_to_be32(remaining);
|
||||
|
||||
int ret = send_packet_snapshot(&snapshot, snap_len);
|
||||
if (ret < 0) {
|
||||
printk("Senden fehlgeschlagen: %d\n", ret);
|
||||
}
|
||||
k_msleep(SEND_INTERVAL_MS);
|
||||
}
|
||||
|
||||
printk("Sendephase beendet\n");
|
||||
printk("Warte 120 Sekunden...\n");
|
||||
printk("Schlafe %u ms…\n", (unsigned)SLEEP_INTERVAL_MS);
|
||||
k_msleep(SLEEP_INTERVAL_MS);
|
||||
}
|
||||
}
|
||||
|
||||
void input_thread(void *p1, void *p2, void *p3)
|
||||
static void input_thread(void *p1, void *p2, void *p3)
|
||||
{
|
||||
char buffer[32];
|
||||
char buffer[sizeof(latest_word)];
|
||||
|
||||
while (1) {
|
||||
printk("Neues Wort eingeben:\n");
|
||||
uart_input_get_line(buffer, sizeof(buffer));
|
||||
|
||||
for (size_t i = 0; buffer[i] != '\0'; ++i) {
|
||||
buffer[i] = (char)toupper((unsigned char)buffer[i]);
|
||||
}
|
||||
|
||||
k_mutex_lock(&word_mutex, K_FOREVER);
|
||||
strncpy(latest_word, buffer, sizeof(latest_word));
|
||||
latest_word[sizeof(latest_word) - 1] = '\0';
|
||||
k_mutex_unlock(&word_mutex);
|
||||
|
||||
printk("Neues Wort gespeichert: \"%s\"\n", latest_word);
|
||||
xorCrypt(latest_word, encrypted, 0x5A);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void master_init(void)
|
||||
@ -142,11 +159,24 @@ void master_init(void)
|
||||
printk("LoRa-Gerät nicht bereit\n");
|
||||
return;
|
||||
}
|
||||
if (!device_is_ready(uart_console)) {
|
||||
printk("UART-Konsole nicht bereit\n");
|
||||
return;
|
||||
}
|
||||
|
||||
int ret = lora_config(lora_dev_master, &tx_config_master);
|
||||
if (ret) {
|
||||
printk("LoRa-Konfiguration fehlgeschlagen: %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
k_mutex_init(&word_mutex);
|
||||
xorCrypt(latest_word, encrypted, 0x5A);
|
||||
|
||||
k_thread_create(&input_thread_data, input_stack_area, INPUT_STACK_SIZE,
|
||||
input_thread, NULL, NULL, NULL, INPUT_PRIORITY, 0, K_NO_WAIT);
|
||||
input_thread, NULL, NULL, NULL,
|
||||
INPUT_PRIORITY, 0, K_NO_WAIT);
|
||||
|
||||
k_thread_create(&send_thread_data, send_stack_area, STACK_SIZE,
|
||||
send_loop_thread, NULL, NULL, NULL, INPUT_PRIORITY, 0, K_NO_WAIT);
|
||||
send_loop_thread, NULL, NULL, NULL,
|
||||
INPUT_PRIORITY, 0, K_NO_WAIT);
|
||||
}
|
||||
|
@ -108,12 +108,12 @@ void oled_init(void) {
|
||||
oled_write_cmd(0xDA); // Set COM Pins
|
||||
oled_write_cmd(0x12);
|
||||
oled_write_cmd(0x81); // Set Contrast
|
||||
oled_write_cmd(0xCF);
|
||||
oled_write_cmd(0x80);
|
||||
oled_write_cmd(0xD9); // Set Pre-charge Period
|
||||
oled_write_cmd(0xF1);
|
||||
oled_write_cmd(0x22);
|
||||
oled_write_cmd(0xDB); // Set VCOMH
|
||||
oled_write_cmd(0x40);
|
||||
oled_write_cmd(0xA4); // Entire Display ON
|
||||
oled_write_cmd(0x34); // Entire Display ON
|
||||
oled_write_cmd(0xA6); // Normal Display
|
||||
oled_write_cmd(0x8D); // Charge Pump
|
||||
oled_write_cmd(0x14); // Enable
|
||||
|
@ -51,6 +51,7 @@ void dc_draw_something(const char *message) {
|
||||
switch (display_type) {
|
||||
case DISPLAY_EPD:
|
||||
#if DT_NODE_EXISTS(DT_NODELABEL(epd))
|
||||
epd_init();
|
||||
epd_draw_something(to_draw);
|
||||
break;
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user