38 return (high << 32) | low;
41uint32_t
mult_calc(uint32_t multiplicand, uint32_t multiplier)
54 if (result == NULL || divisor == 0)
142void spi_set_clock_offset(uint32_t offset)
155 else if (divider != 0)
157 offset = 1 << (divider - 1);
160 spi_set_clock_offset(offset);
205 uint32_t start_time =
millis();
209 if ((
millis() - start_time) >= timeout_ms)
213 __asm__
volatile(
"nop");
220 uint32_t tx_word = (uint32_t)data;
221 uint32_t start_time =
millis();
224 if ((
millis() - start_time) >= timeout_ms)
228 __asm__
volatile(
"nop");
237 uint32_t re_data = (uint32_t)data | 0x00000100;
238 uint32_t start_time =
millis();
241 if ((
millis() - start_time) >= timeout_ms)
245 __asm__
volatile(
"nop");
263 for (uint32_t i = 0; i < length; i++)
277 buf[0] = (uint8_t)((value >> 24) & 0xFF);
278 buf[1] = (uint8_t)((value >> 16) & 0xFF);
279 buf[2] = (uint8_t)((value >> 8) & 0xFF);
280 buf[3] = (uint8_t)(value & 0xFF);
290 for (uint32_t i = 0; i < length; i++)
313 uint32_t color_val = ((uint32_t)color.
g << 16) | ((uint32_t)color.
r << 8) | color.
b;
326 color.
g = (color_val >> 16) & 0xFF;
327 color.
r = (color_val >> 8) & 0xFF;
328 color.
b = color_val & 0xFF;
338 for (uint8_t i = 0; i < 8; i++)
351 for (uint8_t i = 0; i < 8; i++)
365 for (uint8_t i = 0; i < 8; i++)
381#error "Requires malloc. Define MALLOC to use PWM_NOTES."
385static uint32_t *note_buffer = 0;
406 if (note_buffer == NULL)
408 note_buffer = (uint32_t *)
malloc(12 *
sizeof(uint32_t));
415 for (
int i = 0; i < 12; i++)
432 uint16_t prescaler = 0;
434 if (note < NOTE_C || note >
NOTE_B)
441 period = note_buffer[note] >> 10;
442 period = period ? period : 1;
447 period = note_buffer[note] >> (octave - 2);
452 period = note_buffer[note];
453 prescaler = 1 << (2 - octave);
482typedef int ptrdiff_t;
489extern char _heap_start;
490extern char _heap_end;
492static char *heap_ptr = &_heap_start;
502static void *sbrk(int32_t incr)
504 char *prev = heap_ptr;
505 if (heap_ptr + incr > &_heap_end)
535 uint32_t free_space = (uint32_t)(&_heap_end - heap_ptr);
548static Header *morecore(uint32_t nu)
552 char *cp = sbrk(nu *
sizeof(
Header));
553 if (cp == (
char *)-1)
559 free((
void *)(up + 1));
566 uint32_t nunits = (nbytes +
sizeof(
Header) - 1) /
sizeof(
Header) + 1;
567 if ((prevp = freep) == 0)
569 base.s.next = freep = &base;
572 for (p = freep->s.next;; prevp = p, p = p->s.next)
574 if (p->s.size >= nunits)
576 if (p->s.size == nunits)
577 prevp->s.next = p->s.next;
585 return (
void *)(p + 1);
589 p = morecore(nunits);
607 for (p = freep; !(bp > p && bp < p->s.next); p = p->s.next)
609 if (p >= p->s.next && (bp > p || bp < p->s.next))
613 if ((bp + bp->s.size) == p->s.next)
615 bp->s.size += p->s.next->s.size;
616 bp->s.next = p->s.next->s.next;
620 bp->s.next = p->s.next;
623 if ((p + p->s.size) == bp)
625 p->s.size += bp->s.size;
626 p->s.next = bp->s.next;
647 uint32_t old_data_size = (old_hdr->s.size - 1) *
sizeof(
Header);
648 void *newptr =
malloc(size);
651 char *src = (
char *)ptr;
652 char *dst = (
char *)newptr;
654 uint32_t copy_bytes = (size < old_data_size) ? size : old_data_size;
655 for (uint32_t i = 0; i < copy_bytes; i++)
662void *
calloc(uint32_t nmemb, uint32_t size)
664 uint32_t total = nmemb * size;
665 void *ptr =
malloc(total);
668 char *p = (
char *)ptr;
669 for (uint32_t i = 0; i < total; i++)
686static const uint8_t ssd1351_init_cmds[] = {
698 0xB2, 3, 0xA4, 0x00, 0x00,
699 0xB4, 3, 0xA0, 0xB5, 0x55,
701 0xC1, 3, 0xC8, 0x80, 0xC8,
709static uint32_t oled_inv = 0;
710static uint32_t scroll_line = 0;
711static uint32_t term_cursor_x = 0;
712static uint32_t term_cursor_y =
TOTAL_ROWS - 1;
714static uint16_t __attribute__((aligned(4))) term_text_color =
COLOR_WHITE;
715static uint16_t __attribute__((aligned(4))) term_bg_color =
COLOR_BLACK;
716static uint16_t __attribute__((aligned(4))) cursor_visible = true;
720 uint32_t last_hk_time = 0;
731 cursor_visible = !cursor_visible;
789 uint8_t cmd = buf[i++];
790 uint8_t dataLen = buf[i++];
821 uint8_t colArgs[2] = {x, (uint8_t)(x + w - 1)};
822 uint8_t rowArgs[2] = {y, (uint8_t)(y + h - 1)};
835 if (c < 32 || c > 127)
839 const uint8_t *glyph = font5x7[c - 32];
851 for (uint8_t cx = 0; cx < 5; cx++)
853 uint8_t bits = glyph[cx];
854 for (uint8_t cy = 0; cy < 7; cy++)
856 if (bits & (1 << cy))
872 for (uint8_t col = 0; col <
TERM_COLS; col++)
895 lineBuf[i] = bg_color;
911 uint8_t pixelOffset = (uint8_t)(scroll_line *
CHAR_HEIGHT);
919 for (uint8_t col = 0; col <
TERM_COLS; col++)
925 uint8_t physicalBottom = (scroll_line + (scrollable_rows - 1)) % scrollable_rows +
STATUS_BAR_ROWS;
927 bottom_row = physicalBottom;
929 term_cursor_y = bottom_row;
950 if (term_cursor_x > 0)
978 uint16_t previous_color = term_text_color;
1004 term_text_color = color;
1009 term_bg_color = color;
1054 term_cursor_y = bottom_row;
1059 return term_cursor_x;
Struktur zur Rückgabe eines Divisionsergebnisses.
Struktur zur Darstellung einer RGB-Farbe.
void pwm_set_mode(uint8_t enable_pwm)
Aktiviert oder deaktiviert den PWM-Modus.
void pwm_set_50_percent_mode(uint8_t enable)
Aktiviert oder deaktiviert den 50%-Modus des PWM.
void gpio_write_pin(uint8_t pin, uint8_t value)
Schreibt einen Wert auf einen GPIO-Pin.
uint32_t get_sys_clk(void)
Liest die Systemtaktfrequenz.
void int_to_str(int32_t num, int base, char *str)
Konvertiert eine Ganzzahl in einen String.
int32_t uart_putchar(char c, uint32_t timeout_ms)
Sendet ein Zeichen über die UART-Schnittstelle.
void pwm_set_period(uint32_t period)
Setzt die PWM-Periode.
void pwm_set_pre_counter(uint16_t pre_counter)
Setzt den Pre-Counter für PWM.
void debug_write(uint32_t value)
Schreibt einen Wert in das Debug-Register.
void delay(uint32_t ms)
Verzögert die Ausführung um eine bestimmte Anzahl an Millisekunden.
uint32_t millis(void)
Liest den aktuellen Millisekunden-Zähler (32-Bit).
Headerdatei der WGRHAL-Bibliothek.
#define HWREG32(addr)
Makro zur Adressierung von speicherabgebildeten Registern.
uint32_t spi_is_ready(void)
Prüft, ob die SPI-Schnittstelle bereit ist.
uint32_t div_calc_quotient(uint32_t dividend, uint32_t divisor)
Berechnet den Quotienten einer Division.
uint32_t spi_rx_empty(void)
Prüft, ob der SPI-Empfangspuffer leer ist.
void ws2812_clear(void)
Schaltet alle WS2812B LEDs aus.
void * malloc(uint32_t nbytes)
Allokiert einen Speicherblock.
void terminal_set_bg_color(uint16_t color)
Setzt die Hintergrundfarbe des Terminals.
void terminal_native_scroll(void)
Scrollt das Terminal um eine Zeile.
void clear_terminal_row(uint8_t row)
Löscht eine bestimmte Terminalzeile.
void ssd1351_send_data(const uint8_t *data, size_t len)
Sendet einen Datenpuffer an das SSD1351 Display.
uint32_t spi_rx_full(void)
Prüft, ob der SPI-Empfangspuffer voll ist.
int32_t spi_write_byte(uint8_t data, uint32_t timeout_ms)
Sendet ein Byte über die SPI-Schnittstelle.
void ssd1351_inv(void)
Schaltet den Invertierungsmodus des Displays um.
int32_t spi_read_byte(uint8_t *data, uint32_t timeout_ms)
Liest ein Byte von der SPI-Schnittstelle.
const uint8_t note_freq_halfbase[12]
Frequenztabelle für Noten (Halbton-Basis).
void print_error(const char *label)
Gibt ein Label als Fehlernachricht aus.
int32_t ws2812_write_all(const rgb_color_t colors[8])
Schreibt die Farben aller 8 WS2812B LEDs.
void ssd1351_init(void)
Initialisiert das SSD1351 Display.
int32_t ws2812_fill(rgb_color_t color)
Füllt alle WS2812B LEDs mit einer einheitlichen Farbe.
int32_t spi_write_buffer(const uint8_t *buf, uint32_t length, uint32_t timeout_ms)
Sendet einen Datenpuffer über SPI.
void * realloc(void *ptr, uint32_t size)
Ändert die Größe eines allokierten Speicherblocks.
void terminal_draw_text(uint8_t row, uint8_t col, const char *str, uint16_t fg, uint16_t bg)
Zeichnet einen Text an einer bestimmten Terminalposition mit definierten Vorder- und Hintergrundfarbe...
void terminal_init(void)
Initialisiert das Terminal (Display) des SSD1351.
void clear_terminal(void)
Löscht das gesamte Terminal.
int32_t spi_write_uint32(uint32_t value, uint32_t timeout_ms)
Sendet einen 32-Bit-Wert über SPI.
int32_t ws2812_set_color(uint8_t led, rgb_color_t color)
Setzt die Farbe einer WS2812B LED.
int32_t spi_wait_rx_data(uint32_t timeout_ms)
Wartet darauf, dass Daten im SPI-Empfangspuffer verfügbar sind.
void print_ok(const char *label)
Gibt ein Label als OK-Nachricht aus.
void ssd1351_set_position(uint8_t x, uint8_t y, uint8_t w, uint8_t h)
Setzt die Schreibposition und den Bereich im SSD1351 Display.
void ssd1351_send_commands(const uint8_t *buf, size_t len)
Sendet eine Folge von Befehlen an das SSD1351 Display.
void ssd1351_fill_screen(uint16_t color)
Füllt das gesamte Display mit einer Farbe.
void spi_enable(void)
Aktiviert die SPI-Schnittstelle.
void draw_status_bar(const char *text, uint16_t bg_color, uint16_t fg_color)
Zeichnet eine Statusleiste am oberen Displayrand.
uint32_t div_calc_remainder(uint32_t dividend, uint32_t divisor)
Berechnet den Rest einer Division.
void pwm_free_note_buffer(void)
Gibt den für PWM-Noten reservierten Speicher frei.
void pwm_play_note(note_t note, uint32_t octave)
Spielt eine bestimmte Note in einer festgelegten Oktave über den PWM aus.
int32_t div_calc(uint32_t dividend, uint32_t divisor, div_result_t *result)
Führt eine Division durch und liefert Quotient und Rest.
void terminal_print_col(const char *text, uint16_t color)
Gibt einen String im Terminal mit einer bestimmten Textfarbe aus.
uint32_t mult_calc(uint32_t multiplicand, uint32_t multiplier)
Berechnet das 32-Bit-Ergebnis einer Multiplikation.
uint32_t heap_free_space(void)
Ermittelt den aktuell freien Heap-Speicher.
void spi_automatic_cs(bool active)
Aktiviert oder deaktiviert den automatischen Chipselect (CS) der SPI-Schnittstelle.
int pwm_precompute_notes(void)
Berechnet Notenparameter für den PWM-Modus.
void ssd1351_draw_pixel(uint8_t x, uint8_t y, uint16_t color)
Zeichnet einen einzelnen Pixel an einer bestimmten Position.
void print_ok_res(const char *label, int32_t value)
Gibt ein Label und einen numerischen Wert (als String) aus, farblich als OK markiert.
void terminal_print(const char *str)
Gibt einen String im Terminal aus.
void terminal_put_char(char c)
Gibt ein einzelnes Zeichen im Terminal aus und aktualisiert den Cursor.
void spi_disable(void)
Deaktiviert die SPI-Schnittstelle.
rgb_color_t ws2812_get_color(uint8_t led)
Liest die aktuell gesetzte Farbe einer WS2812B LED.
void terminal_set_text_color(uint16_t color)
Setzt die Textfarbe des Terminals.
int32_t spi_read_buffer(uint8_t *buf, uint32_t length, uint32_t timeout_ms)
Liest einen Datenpuffer von der SPI-Schnittstelle.
void spi_set_clock_divider(uint32_t divider)
Konfiguriert den Taktteiler der SPI-Schnittstelle.
void ssd1351_send_command(uint8_t cmd)
Sendet einen einzelnen Befehl an das SSD1351 Display.
void terminal_draw_text_default(uint8_t row, uint8_t col, const char *str)
Zeichnet einen Text an einer bestimmten Terminalposition mit Standardfarben.
uint32_t spi_tx_full(void)
Prüft, ob der SPI-Sende-Puffer voll ist.
uint32_t spi_tx_empty(void)
Prüft, ob der SPI-Sende-Puffer leer ist.
uint32_t ssd1351_cursor_x(void)
Gibt die aktuelle X-Position des Cursors im SSD1351 Terminal zurück.
uint32_t spi_is_busy(void)
Prüft, ob die SPI-Schnittstelle beschäftigt ist.
uint32_t spi_get_status(void)
Liest den aktuellen Status der SPI-Schnittstelle.
void free(void *ap)
Gibt einen zuvor allokierten Speicherblock frei.
void ssd1351_send_command_with_data(uint8_t cmd, const uint8_t *data, size_t len)
Sendet einen Befehl mit zugehörigen Daten an das SSD1351 Display.
void * calloc(uint32_t nmemb, uint32_t size)
Allokiert einen Speicherblock für ein Array und initialisiert diesen mit 0.
void spi_cs(uint32_t active)
Setzt den SPI-Chipselect-Zustand.
void draw_char_cell(uint8_t row, uint8_t col, char c)
Zeichnet ein einzelnes Zeichen in einer Terminalzelle.
void draw_char_cell_custom(uint8_t row, uint8_t col, char c, uint16_t fg, uint16_t bg)
Zeichnet ein einzelnes Zeichen in einer Terminalzelle mit individuellen Farben.
uint64_t mult_calc_64(uint32_t multiplicand, uint32_t multiplier)
Berechnet das 64-Bit-Ergebnis einer Multiplikation.
uint32_t spi_fifo_full(void)
Prüft, ob das SPI-FIFO voll ist.
Erweiterte Funktionen und Hardwarezugriffe für den WGR-V-Prozessor.
#define RESL_OFFSET
Offset für die niederwertigen 32-Bit des 64-Bit-Ergebnisses.
#define SPI_CTRL_OFFSET
Offset für das SPI-Steuerregister.
#define DIV_INFO_OFFSET
Offset für das Informationsregister des Dividers.
#define DIV_SOR_OFFSET
Offset für den Divisor.
#define DIV_BASE_ADDR
Basisadresse für den Hardware-Divider.
#define TERM_COLS
Anzahl der Spalten im Terminal.
#define WS_BASE_ADDR
Basisadresse für die WS2812B LED-Steuerung.
#define MUL2_OFFSET
Offset für den zweiten Multiplikanden.
void housekeeping(void)
Führt periodische Wartungsarbeiten am SSD1351 Display durch (z.B. Cursor-Blinken).
#define SSD1351_SPI_TIMEOUT
SPI-Zeitlimit in Millisekunden für das Display.
#define MUL1_OFFSET
Offset für den ersten Multiplikanden.
note_t
Aufzählung der Noten im Halbtonsystem.
#define SPI_RX_OFFSET
Offset für das SPI-Empfangsregister.
#define SPI_STATUS_OFFSET
Offset für das SPI-Statusregister.
#define CHAR_WIDTH
Breite eines Zeichens in Pixel.
#define SPI_TX_OFFSET
Offset für das SPI-Sende-Register.
#define SSD1351_WIDTH
Breite des SSD1351 Displays in Pixel.
#define SSD1351_HEIGHT
Höhe des SSD1351 Displays in Pixel.
#define SPI_CS_OFFSET
Offset für die SPI-Chipselect-Steuerung.
#define TOTAL_ROWS
Gesamte Anzahl der Textzeilen auf dem Display.
#define DIV_REM_OFFSET
Offset für den Rest.
#define MULT_INFO_OFFSET
Offset für das Informationsregister des Multiplikators.
#define DIV_QUO_OFFSET
Offset für den Quotienten.
#define RESH_OFFSET
Offset für die höheren 32-Bit des 64-Bit-Ergebnisses.
#define COLOR_WHITE
Farbe: Weiß.
#define STATUS_BAR_ROWS
Anzahl der Zeilen für die Statusleiste.
#define HOUSEKEEPING_MS
Intervall für Display-Housekeeping in Millisekunden.
#define COLOR_BLACK
Farbe: Schwarz.
#define MULT_BASE_ADDR
Basisadresse für den Hardware-Multiplikator.
#define COLOR_RED
Farbe: Rot.
#define DIV_END_OFFSET
Offset für den Dividend.
#define CHAR_HEIGHT
Höhe eines Zeichens in Pixel.
#define SPI_CLK_OFFSET
Offset für das SPI-Taktregister.
#define SPI_BASE_ADDR
Basisadresse für die SPI-Schnittstelle.
#define COLOR_GREEN
Farbe: Grün.