WGR-V
 
Lade ...
Suche ...
Keine Treffer
wgrhal_ext.c
gehe zur Dokumentation dieser Datei
1
18#include "wgrhal.h"
19#include "wgrhal_ext.h"
20
21// ----------------------- WGR-V -----------------------
22//
23// Hardware Multiplikation und Division
24//
25//------------------------------------------------------
26
27uint64_t mult_calc_64(uint32_t multiplicand, uint32_t multiplier)
28{
29 HWREG32(MULT_BASE_ADDR + MUL1_OFFSET) = multiplicand;
30 HWREG32(MULT_BASE_ADDR + MUL2_OFFSET) = multiplier;
31
33 ;
34
35 uint64_t high = (uint64_t)HWREG32(MULT_BASE_ADDR + RESH_OFFSET);
36 uint64_t low = (uint64_t)HWREG32(MULT_BASE_ADDR + RESL_OFFSET);
37
38 return (high << 32) | low;
39}
40
41uint32_t mult_calc(uint32_t multiplicand, uint32_t multiplier)
42{
43 HWREG32(MULT_BASE_ADDR + MUL1_OFFSET) = multiplicand;
44 HWREG32(MULT_BASE_ADDR + MUL2_OFFSET) = multiplier;
45
47 ;
48
50}
51
52int32_t div_calc(uint32_t dividend, uint32_t divisor, div_result_t *result)
53{
54 if (result == NULL || divisor == 0)
55 {
56 return -1;
57 }
58
61
63 ;
64
67
68 return 0;
69}
70
71uint32_t div_calc_quotient(uint32_t dividend, uint32_t divisor)
72{
73 if (divisor == 0)
74 {
75 return -1;
76 }
77
80
82 ;
83
85}
86
87uint32_t div_calc_remainder(uint32_t dividend, uint32_t divisor)
88{
89 if (divisor == 0)
90 {
91 return -1;
92 }
93
96
98 ;
99
101}
102
103// ----------------------- WGR-V -----------------------
104//
105// SPI Funktionen
106//
107//------------------------------------------------------
108
109void spi_enable(void)
110{
111 uint32_t reg = HWREG32(SPI_BASE_ADDR + SPI_CTRL_OFFSET);
112 reg |= 1U;
114}
115
116void spi_disable(void)
117{
118 uint32_t reg = HWREG32(SPI_BASE_ADDR + SPI_CTRL_OFFSET);
119 reg &= ~1U;
121}
122
123void spi_automatic_cs(bool active)
124{
125 uint32_t reg = HWREG32(SPI_BASE_ADDR + SPI_CTRL_OFFSET);
126 if (active)
127 {
128 reg |= 2U;
129 }
130 else
131 {
132 reg &= ~2U;
133 }
135}
136
137void spi_cs(uint32_t active)
138{
140}
141
142void spi_set_clock_offset(uint32_t offset)
143{
145}
146
147void spi_set_clock_divider(uint32_t divider)
148{
149 uint32_t offset = 0;
150
151 if (divider > 15)
152 {
153 offset = 0x8000;
154 }
155 else if (divider != 0)
156 {
157 offset = 1 << (divider - 1);
158 }
159
160 spi_set_clock_offset(offset);
161}
162
163uint32_t spi_get_status(void)
164{
166}
167
168uint32_t spi_fifo_full(void)
169{
170 return ((spi_get_status() >> 6) & (uint32_t)1);
171}
172
173uint32_t spi_is_ready(void)
174{
175 return ((spi_get_status() >> 5) & (uint32_t)1);
176}
177
178uint32_t spi_is_busy(void)
179{
180 return ((spi_get_status() >> 4) & (uint32_t)1);
181}
182
183uint32_t spi_rx_full(void)
184{
185 return ((spi_get_status() >> 3) & (uint32_t)1);
186}
187
188uint32_t spi_rx_empty(void)
189{
190 return ((spi_get_status() >> 2) & (uint32_t)1);
191}
192
193uint32_t spi_tx_full(void)
194{
195 return ((spi_get_status() >> 1) & (uint32_t)1);
196}
197
198uint32_t spi_tx_empty(void)
199{
200 return ((spi_get_status() >> 0) & (uint32_t)1);
201}
202
203int32_t spi_wait_rx_data(uint32_t timeout_ms)
204{
205 uint32_t start_time = millis();
206
207 while (spi_rx_empty())
208 {
209 if ((millis() - start_time) >= timeout_ms)
210 {
211 return -1;
212 }
213 __asm__ volatile("nop");
214 }
215 return 0;
216}
217
218int32_t spi_write_byte(uint8_t data, uint32_t timeout_ms)
219{
220 uint32_t tx_word = (uint32_t)data;
221 uint32_t start_time = millis();
222 while (spi_tx_full())
223 {
224 if ((millis() - start_time) >= timeout_ms)
225 {
226 return -1;
227 }
228 __asm__ volatile("nop");
229 }
230
232 return 0;
233}
234
235int32_t spi_read_byte(uint8_t *data, uint32_t timeout_ms)
236{
237 uint32_t re_data = (uint32_t)data | 0x00000100;
238 uint32_t start_time = millis();
239 while (spi_fifo_full())
240 {
241 if ((millis() - start_time) >= timeout_ms)
242 {
243 return -1;
244 }
245 __asm__ volatile("nop");
246 }
248 int32_t ret = spi_wait_rx_data(timeout_ms);
249 if (ret != 0)
250 {
251 return ret;
252 }
253 *data = (uint8_t)(HWREG32(SPI_BASE_ADDR + SPI_RX_OFFSET) & 0xFF);
254 return 0;
255}
256
257int32_t spi_write_buffer(const uint8_t *buf, uint32_t length, uint32_t timeout_ms)
258{
259 if (buf == 0)
260 {
261 return -1;
262 }
263 for (uint32_t i = 0; i < length; i++)
264 {
265 int32_t ret = spi_write_byte(buf[i], timeout_ms);
266 if (ret != 0)
267 {
268 return ret;
269 }
270 }
271 return 0;
272}
273
274int32_t spi_write_uint32(uint32_t value, uint32_t timeout_ms)
275{
276 uint8_t buf[4];
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);
281 return spi_write_buffer(buf, 4, timeout_ms);
282}
283
284int32_t spi_read_buffer(uint8_t *buf, uint32_t length, uint32_t timeout_ms)
285{
286 if (buf == 0)
287 {
288 return -1;
289 }
290 for (uint32_t i = 0; i < length; i++)
291 {
292 int32_t ret = spi_read_byte(&buf[i], timeout_ms);
293 if (ret < 0)
294 {
295 return ret;
296 }
297 }
298 return 0;
299}
300
301// ----------------------- WGR-V -----------------------
302//
303// WS2812B Funktionen
304//
305//------------------------------------------------------
306
307int32_t ws2812_set_color(uint8_t led, rgb_color_t color)
308{
309 if (led > 7)
310 {
311 return -1;
312 }
313 uint32_t color_val = ((uint32_t)color.g << 16) | ((uint32_t)color.r << 8) | color.b;
314 HWREG32(WS_BASE_ADDR + (led << 2)) = color_val;
315 return 0;
316}
317
319{
320 rgb_color_t color = {0, 0, 0};
321 if (led > 7)
322 {
323 return color;
324 }
325 uint32_t color_val = HWREG32(WS_BASE_ADDR + (led << 2));
326 color.g = (color_val >> 16) & 0xFF;
327 color.r = (color_val >> 8) & 0xFF;
328 color.b = color_val & 0xFF;
329 return color;
330}
331
332int32_t ws2812_write_all(const rgb_color_t colors[8])
333{
334 if (colors == NULL)
335 {
336 return -1;
337 }
338 for (uint8_t i = 0; i < 8; i++)
339 {
340 int32_t ret = ws2812_set_color(i, colors[i]);
341 if (ret != 0)
342 {
343 return ret;
344 }
345 }
346 return 0;
347}
348
350{
351 for (uint8_t i = 0; i < 8; i++)
352 {
353 int32_t ret = ws2812_set_color(i, color);
354 if (ret != 0)
355 {
356 return ret;
357 }
358 }
359 return 0;
360}
361
362void ws2812_clear(void)
363{
364 rgb_color_t off = {0, 0, 0};
365 for (uint8_t i = 0; i < 8; i++)
366 {
367 ws2812_set_color(i, off);
368 }
369}
370
371#ifdef PWM_NOTES
372
373// ----------------------- WGR-V -----------------------
374//
375// Frequenzen und Noten per PWM abspielen
376//
377//------------------------------------------------------
378
379#ifdef PWM_NOTES
380#ifndef MALLOC
381#error "Requires malloc. Define MALLOC to use PWM_NOTES."
382#endif
383#endif
384
385static uint32_t *note_buffer = 0;
386
387const uint8_t note_freq_halfbase[12] = {
388 131,
389 139,
390 147,
391 156,
392 165,
393 175,
394 185,
395 196,
396 208,
397 220,
398 233,
399 247};
400
402{
403 uint32_t sys_clk = get_sys_clk();
404 debug_write(sys_clk);
405
406 if (note_buffer == NULL)
407 {
408 note_buffer = (uint32_t *)malloc(12 * sizeof(uint32_t));
409 if (!note_buffer)
410 {
411 return -1;
412 }
413 }
414
415 for (int i = 0; i < 12; i++)
416 {
417 note_buffer[i] = (uint32_t)(sys_clk / note_freq_halfbase[i]);
418 debug_write(note_buffer[i]);
419 }
420
421 return 0;
422}
423
424void pwm_play_note(note_t note, uint32_t octave)
425{
426 if (!note_buffer)
427 {
428 return;
429 }
430
431 uint32_t period = 0;
432 uint16_t prescaler = 0;
433
434 if (note < NOTE_C || note > NOTE_B)
435 {
436 return;
437 }
438
439 if (octave > 10)
440 {
441 period = note_buffer[note] >> 10;
442 period = period ? period : 1;
443 prescaler = 1;
444 }
445 else if (octave > 2)
446 {
447 period = note_buffer[note] >> (octave - 2);
448 prescaler = 1;
449 }
450 else
451 {
452 period = note_buffer[note];
453 prescaler = 1 << (2 - octave);
454 }
455
456 pwm_set_mode(1);
458
459 pwm_set_period(period);
460 pwm_set_pre_counter(prescaler);
461}
462
464{
465 if (note_buffer)
466 {
467 free(note_buffer);
468 note_buffer = 0;
469 }
470}
471
472#endif
473
474#ifdef MALLOC
475
476// ----------------------- WGR-V -----------------------
477//
478// malloc
479//
480//------------------------------------------------------
481
482typedef int ptrdiff_t;
483
484void free(void *ap);
485
486int errno;
487#define ENOMEM 12
488
489extern char _heap_start;
490extern char _heap_end;
491
492static char *heap_ptr = &_heap_start;
493
502static void *sbrk(int32_t incr)
503{
504 char *prev = heap_ptr;
505 if (heap_ptr + incr > &_heap_end)
506 {
507 errno = ENOMEM;
508 return (void *)-1;
509 }
510 heap_ptr += incr;
511 return prev;
512}
513
514typedef long Align;
515
517{
518 struct
519 {
520 union header *next;
521 uint32_t size;
522 } s;
523 Align x;
524};
525
526typedef union header Header;
527
528static Header base;
529static Header *freep = 0;
530
531#define NALLOC 1024
532
533uint32_t heap_free_space(void)
534{
535 uint32_t free_space = (uint32_t)(&_heap_end - heap_ptr);
536 return free_space;
537}
538
548static Header *morecore(uint32_t nu)
549{
550 if (nu < NALLOC)
551 nu = NALLOC;
552 char *cp = sbrk(nu * sizeof(Header));
553 if (cp == (char *)-1)
554 {
555 return 0;
556 }
557 Header *up = (Header *)cp;
558 up->s.size = nu;
559 free((void *)(up + 1));
560 return freep;
561}
562
563void *malloc(uint32_t nbytes)
564{
565 Header *p, *prevp;
566 uint32_t nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1;
567 if ((prevp = freep) == 0)
568 {
569 base.s.next = freep = &base;
570 base.s.size = 0;
571 }
572 for (p = freep->s.next;; prevp = p, p = p->s.next)
573 {
574 if (p->s.size >= nunits)
575 {
576 if (p->s.size == nunits)
577 prevp->s.next = p->s.next;
578 else
579 {
580 p->s.size -= nunits;
581 p += p->s.size;
582 p->s.size = nunits;
583 }
584 freep = prevp;
585 return (void *)(p + 1);
586 }
587 if (p == freep)
588 {
589 p = morecore(nunits);
590 if (p == 0)
591 {
592 return 0;
593 }
594 }
595 }
596}
597
598void free(void *ap)
599{
600 if (!ap)
601 {
602 return;
603 }
604 Header *bp = (Header *)ap - 1;
605 Header *p;
606
607 for (p = freep; !(bp > p && bp < p->s.next); p = p->s.next)
608 {
609 if (p >= p->s.next && (bp > p || bp < p->s.next))
610 break;
611 }
612
613 if ((bp + bp->s.size) == p->s.next)
614 {
615 bp->s.size += p->s.next->s.size;
616 bp->s.next = p->s.next->s.next;
617 }
618 else
619 {
620 bp->s.next = p->s.next;
621 }
622
623 if ((p + p->s.size) == bp)
624 {
625 p->s.size += bp->s.size;
626 p->s.next = bp->s.next;
627 }
628 else
629 {
630 p->s.next = bp;
631 }
632 freep = p;
633}
634
635void *realloc(void *ptr, uint32_t size)
636{
637 if (!ptr)
638 return malloc(size);
639 if (size == 0)
640 {
641 free(ptr);
642 return 0;
643 }
644
645 Header *old_hdr = (Header *)ptr - 1;
646
647 uint32_t old_data_size = (old_hdr->s.size - 1) * sizeof(Header);
648 void *newptr = malloc(size);
649 if (newptr)
650 {
651 char *src = (char *)ptr;
652 char *dst = (char *)newptr;
653
654 uint32_t copy_bytes = (size < old_data_size) ? size : old_data_size;
655 for (uint32_t i = 0; i < copy_bytes; i++)
656 dst[i] = src[i];
657 }
658 free(ptr);
659 return newptr;
660}
661
662void *calloc(uint32_t nmemb, uint32_t size)
663{
664 uint32_t total = nmemb * size;
665 void *ptr = malloc(total);
666 if (ptr)
667 {
668 char *p = (char *)ptr;
669 for (uint32_t i = 0; i < total; i++)
670 p[i] = 0;
671 }
672 return ptr;
673}
674
675#endif
676
677#ifdef SSD1351
678
679// ----------------------- WGR-V -----------------------
680//
681// SSD1351 Display mit Terminal Funktionalitäten
682//
683//------------------------------------------------------
684
685// SSD1351 Init Sequence
686static const uint8_t ssd1351_init_cmds[] = {
687 0xFD, 1, 0x12,
688 0xFD, 1, 0xB1,
689 0xAE, 0,
690 0xB3, 1, 0xF1,
691 0xCA, 1, 0x7F,
692 0xA0, 1, 0x74,
693 0xA1, 1, 0x00,
694 0xA2, 1, 0x00,
695 0xA6, 0,
696 0xAB, 1, 0x01,
697 0xB1, 1, 0x32,
698 0xB2, 3, 0xA4, 0x00, 0x00,
699 0xB4, 3, 0xA0, 0xB5, 0x55,
700 0xB6, 1, 0x01,
701 0xC1, 3, 0xC8, 0x80, 0xC8,
702 0xC7, 1, 0x0F,
703 0xBE, 1, 0x05,
704 0x15, 2, 0x00, 0x7F,
705 0x75, 2, 0x00, 0x7F,
706 0xA3, 2, 0x08, 0x78,
707 0xAF, 0};
708
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;
713static uint32_t bottom_row = 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;
717
718void housekeeping(void)
719{
720 uint32_t last_hk_time = 0;
721
722 if ((millis() - last_hk_time) < HOUSEKEEPING_MS)
723 {
724 return;
725 }
726 last_hk_time = millis();
727
728 if (term_cursor_x >= TERM_COLS)
729 return;
730
731 cursor_visible = !cursor_visible;
732
733 draw_char_cell_custom(term_cursor_y, term_cursor_x, ' ', COLOR_WHITE, COLOR_BLACK);
734
735 if (cursor_visible)
736 {
737 draw_char_cell_custom(term_cursor_y, term_cursor_x, '_', COLOR_WHITE, COLOR_BLACK);
738 }
739}
740
741void ssd1351_inv(void)
742{
743 if (oled_inv)
744 {
746 oled_inv = 0;
747 }
748 else
749 {
751 oled_inv = 1;
752 }
753}
754
755void ssd1351_send_data(const uint8_t *data, size_t len)
756{
757 gpio_write_pin(0, 1);
758 spi_cs(1);
760 spi_cs(0);
761}
762
763void ssd1351_send_command(uint8_t cmd)
764{
765 gpio_write_pin(0, 0);
766 spi_cs(1);
768 spi_cs(0);
769}
770
771void ssd1351_send_command_with_data(uint8_t cmd, const uint8_t *data, size_t len)
772{
773 spi_cs(1);
774 gpio_write_pin(0, 0);
776 if (len > 0)
777 {
778 gpio_write_pin(0, 1);
780 }
781 spi_cs(0);
782}
783
784void ssd1351_send_commands(const uint8_t *buf, size_t len)
785{
786 size_t i = 0;
787 while (i < len)
788 {
789 uint8_t cmd = buf[i++];
790 uint8_t dataLen = buf[i++];
791 ssd1351_send_command_with_data(cmd, &buf[i], dataLen);
792 i += dataLen;
793 }
794}
795
796void ssd1351_init(void)
797{
798 spi_cs(0);
799
800 gpio_write_pin(1, 0);
801 delay(100);
802 gpio_write_pin(1, 1);
803 delay(100);
804
805 ssd1351_send_commands(ssd1351_init_cmds, sizeof(ssd1351_init_cmds));
806 delay(100);
807
808 uint8_t scroll_area[2] = {CHAR_HEIGHT, (uint8_t)(SSD1351_HEIGHT - CHAR_HEIGHT)};
810 ssd1351_send_data(scroll_area, 2);
811
812 scroll_line = 0;
813
814 uint8_t scroll_start = (uint8_t)(scroll_line * CHAR_HEIGHT) + CHAR_HEIGHT;
816 ssd1351_send_data(&scroll_start, 1);
817}
818
819void ssd1351_set_position(uint8_t x, uint8_t y, uint8_t w, uint8_t h)
820{
821 uint8_t colArgs[2] = {x, (uint8_t)(x + w - 1)};
822 uint8_t rowArgs[2] = {y, (uint8_t)(y + h - 1)};
823
825 ssd1351_send_data(colArgs, 2);
826
828 ssd1351_send_data(rowArgs, 2);
829
831}
832
833void draw_char_cell_custom(uint8_t row, uint8_t col, char c, uint16_t fg, uint16_t bg)
834{
835 if (c < 32 || c > 127)
836 {
837 c = '?';
838 }
839 const uint8_t *glyph = font5x7[c - 32];
840
841 uint8_t x = (uint8_t)(col * CHAR_WIDTH);
842 uint8_t y = (uint8_t)(row * CHAR_HEIGHT);
843
845
846 uint16_t cell[CHAR_WIDTH * CHAR_HEIGHT];
847 for (int i = 0; i < (CHAR_WIDTH * CHAR_HEIGHT); i++)
848 {
849 cell[i] = bg;
850 }
851 for (uint8_t cx = 0; cx < 5; cx++)
852 {
853 uint8_t bits = glyph[cx];
854 for (uint8_t cy = 0; cy < 7; cy++)
855 {
856 if (bits & (1 << cy))
857 {
858 cell[(cy * CHAR_WIDTH) + cx] = fg;
859 }
860 }
861 }
862 ssd1351_send_data((const uint8_t *)cell, sizeof(cell));
863}
864
865void draw_char_cell(uint8_t row, uint8_t col, char c)
866{
868}
869
870void clear_terminal_row(uint8_t row)
871{
872 for (uint8_t col = 0; col < TERM_COLS; col++)
873 {
874 draw_char_cell_custom(row, col, ' ', term_text_color, term_bg_color);
875 }
876}
877
879{
880 for (uint8_t r = STATUS_BAR_ROWS; r < TOTAL_ROWS; r++)
881 {
883 }
884 term_cursor_x = 0;
885 term_cursor_y = TOTAL_ROWS - 1;
886}
887
888void draw_status_bar(const char *text, uint16_t bg_color, uint16_t fg_color)
889{
891
892 uint16_t lineBuf[SSD1351_WIDTH * CHAR_HEIGHT];
893 for (int i = 0; i < SSD1351_WIDTH * CHAR_HEIGHT; i++)
894 {
895 lineBuf[i] = bg_color;
896 }
897 ssd1351_send_data((uint8_t *)lineBuf, sizeof(lineBuf));
898
899 uint8_t col = 0;
900 while (*text && col < TERM_COLS)
901 {
902 draw_char_cell_custom(0, col, *text++, fg_color, bg_color);
903 col++;
904 }
905}
906
908{
909 scroll_line = (scroll_line + 1) % (TOTAL_ROWS - STATUS_BAR_ROWS);
910
911 uint8_t pixelOffset = (uint8_t)(scroll_line * CHAR_HEIGHT);
912 uint8_t scroll_start = (uint8_t)(pixelOffset + (STATUS_BAR_ROWS * CHAR_HEIGHT));
913
915 ssd1351_send_data(&scroll_start, 1);
916
917 uint8_t newlyRevealedRow = (scroll_line + 0) % (TOTAL_ROWS - STATUS_BAR_ROWS) + STATUS_BAR_ROWS;
918
919 for (uint8_t col = 0; col < TERM_COLS; col++)
920 {
921 draw_char_cell_custom(newlyRevealedRow, col, ' ', term_text_color, term_bg_color);
922 }
923
924 uint8_t scrollable_rows = (TOTAL_ROWS - STATUS_BAR_ROWS);
925 uint8_t physicalBottom = (scroll_line + (scrollable_rows - 1)) % scrollable_rows + STATUS_BAR_ROWS;
926
927 bottom_row = physicalBottom;
928 term_cursor_x = 0;
929 term_cursor_y = bottom_row;
930
931 delay(100);
932}
933
935{
936 uart_putchar(c, 10);
937
938 if (c == '\n')
939 {
940 if (term_cursor_x < TERM_COLS)
941 {
942 draw_char_cell_custom(term_cursor_y, term_cursor_x, ' ', COLOR_WHITE, COLOR_BLACK);
943 }
945 return;
946 }
947
948 if (c == '\b')
949 {
950 if (term_cursor_x > 0)
951 {
952 term_cursor_x--;
953 draw_char_cell_custom(term_cursor_y, term_cursor_x, ' ', term_text_color, term_bg_color);
954 draw_char_cell_custom(term_cursor_y, term_cursor_x + 1, ' ', term_text_color, term_bg_color);
955 }
956 return;
957 }
958
959 draw_char_cell_custom(term_cursor_y, term_cursor_x, c, term_text_color, term_bg_color);
960 term_cursor_x++;
961
962 if (term_cursor_x >= TERM_COLS)
963 {
965 }
966}
967
968void terminal_print(const char *str)
969{
970 while (*str)
971 {
972 terminal_put_char(*str++);
973 }
974}
975
976void terminal_print_col(const char *text, uint16_t color)
977{
978 uint16_t previous_color = term_text_color;
980 terminal_print(text);
981 terminal_set_text_color(previous_color);
982}
983
984void print_ok_res(const char *label, int32_t value)
985{
986 char numStr[16];
987 int_to_str(value, 10, numStr);
990}
991
992void print_ok(const char *label)
993{
995}
996
997void print_error(const char *label)
998{
1000}
1001
1002void terminal_set_text_color(uint16_t color)
1003{
1004 term_text_color = color;
1005}
1006
1007void terminal_set_bg_color(uint16_t color)
1008{
1009 term_bg_color = color;
1010}
1011
1012void terminal_draw_text(uint8_t row, uint8_t col, const char *str, uint16_t fg, uint16_t bg)
1013{
1014 while (*str && col < TERM_COLS)
1015 {
1016 draw_char_cell_custom(row, col, *str++, fg, bg);
1017 col++;
1018 }
1019}
1020
1021void terminal_draw_text_default(uint8_t row, uint8_t col, const char *str)
1022{
1024}
1025
1026void ssd1351_fill_screen(uint16_t color)
1027{
1029 uint16_t lineBuf[SSD1351_WIDTH];
1030 for (int i = 0; i < SSD1351_WIDTH; i++)
1031 {
1032 lineBuf[i] = color;
1033 }
1034 for (int r = 0; r < SSD1351_HEIGHT; r++)
1035 {
1036 ssd1351_send_data((uint8_t *)lineBuf, sizeof(lineBuf));
1037 }
1038}
1039
1040void ssd1351_draw_pixel(uint8_t x, uint8_t y, uint16_t color)
1041{
1042 ssd1351_set_position(x, y, 1, 1);
1043 ssd1351_send_data((uint8_t *)&color, 2);
1044}
1045
1047{
1048 ssd1351_init();
1049 for (uint8_t r = STATUS_BAR_ROWS; r < TOTAL_ROWS; r++)
1050 {
1052 }
1053 term_cursor_x = 0;
1054 term_cursor_y = bottom_row;
1055}
1056
1057uint32_t ssd1351_cursor_x(void)
1058{
1059 return term_cursor_x;
1060}
1061
1062#endif
Struktur zur Rückgabe eines Divisionsergebnisses.
Definition wgrhal_ext.h:115
uint32_t remainder
Definition wgrhal_ext.h:119
uint32_t quotient
Definition wgrhal_ext.h:118
Struktur zur Darstellung einer RGB-Farbe.
Definition wgrhal_ext.h:106
uint8_t g
Definition wgrhal_ext.h:108
uint8_t b
Definition wgrhal_ext.h:109
uint8_t r
Definition wgrhal_ext.h:107
void pwm_set_mode(uint8_t enable_pwm)
Aktiviert oder deaktiviert den PWM-Modus.
Definition wgrhal.c:604
void pwm_set_50_percent_mode(uint8_t enable)
Aktiviert oder deaktiviert den 50%-Modus des PWM.
Definition wgrhal.c:614
void gpio_write_pin(uint8_t pin, uint8_t value)
Schreibt einen Wert auf einen GPIO-Pin.
Definition wgrhal.c:643
uint32_t get_sys_clk(void)
Liest die Systemtaktfrequenz.
Definition wgrhal.c:492
void int_to_str(int32_t num, int base, char *str)
Konvertiert eine Ganzzahl in einen String.
Definition wgrhal.c:122
int32_t uart_putchar(char c, uint32_t timeout_ms)
Sendet ein Zeichen über die UART-Schnittstelle.
Definition wgrhal.c:359
void pwm_set_period(uint32_t period)
Setzt die PWM-Periode.
Definition wgrhal.c:569
void pwm_set_pre_counter(uint16_t pre_counter)
Setzt den Pre-Counter für PWM.
Definition wgrhal.c:624
void debug_write(uint32_t value)
Schreibt einen Wert in das Debug-Register.
Definition wgrhal.c:246
void delay(uint32_t ms)
Verzögert die Ausführung um eine bestimmte Anzahl an Millisekunden.
Definition wgrhal.c:545
uint32_t millis(void)
Liest den aktuellen Millisekunden-Zähler (32-Bit).
Definition wgrhal.c:516
Headerdatei der WGRHAL-Bibliothek.
#define HWREG32(addr)
Makro zur Adressierung von speicherabgebildeten Registern.
Definition wgrhal.h:27
uint32_t spi_is_ready(void)
Prüft, ob die SPI-Schnittstelle bereit ist.
Definition wgrhal_ext.c:173
uint32_t div_calc_quotient(uint32_t dividend, uint32_t divisor)
Berechnet den Quotienten einer Division.
Definition wgrhal_ext.c:71
uint32_t spi_rx_empty(void)
Prüft, ob der SPI-Empfangspuffer leer ist.
Definition wgrhal_ext.c:188
void ws2812_clear(void)
Schaltet alle WS2812B LEDs aus.
Definition wgrhal_ext.c:362
void * malloc(uint32_t nbytes)
Allokiert einen Speicherblock.
Definition wgrhal_ext.c:563
void terminal_set_bg_color(uint16_t color)
Setzt die Hintergrundfarbe des Terminals.
void terminal_native_scroll(void)
Scrollt das Terminal um eine Zeile.
Definition wgrhal_ext.c:907
void clear_terminal_row(uint8_t row)
Löscht eine bestimmte Terminalzeile.
Definition wgrhal_ext.c:870
void ssd1351_send_data(const uint8_t *data, size_t len)
Sendet einen Datenpuffer an das SSD1351 Display.
Definition wgrhal_ext.c:755
uint32_t spi_rx_full(void)
Prüft, ob der SPI-Empfangspuffer voll ist.
Definition wgrhal_ext.c:183
int32_t spi_write_byte(uint8_t data, uint32_t timeout_ms)
Sendet ein Byte über die SPI-Schnittstelle.
Definition wgrhal_ext.c:218
void ssd1351_inv(void)
Schaltet den Invertierungsmodus des Displays um.
Definition wgrhal_ext.c:741
int32_t spi_read_byte(uint8_t *data, uint32_t timeout_ms)
Liest ein Byte von der SPI-Schnittstelle.
Definition wgrhal_ext.c:235
const uint8_t note_freq_halfbase[12]
Frequenztabelle für Noten (Halbton-Basis).
Definition wgrhal_ext.c:387
void print_error(const char *label)
Gibt ein Label als Fehlernachricht aus.
Definition wgrhal_ext.c:997
int32_t ws2812_write_all(const rgb_color_t colors[8])
Schreibt die Farben aller 8 WS2812B LEDs.
Definition wgrhal_ext.c:332
void ssd1351_init(void)
Initialisiert das SSD1351 Display.
Definition wgrhal_ext.c:796
int32_t ws2812_fill(rgb_color_t color)
Füllt alle WS2812B LEDs mit einer einheitlichen Farbe.
Definition wgrhal_ext.c:349
int32_t spi_write_buffer(const uint8_t *buf, uint32_t length, uint32_t timeout_ms)
Sendet einen Datenpuffer über SPI.
Definition wgrhal_ext.c:257
void * realloc(void *ptr, uint32_t size)
Ändert die Größe eines allokierten Speicherblocks.
Definition wgrhal_ext.c:635
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.
Definition wgrhal_ext.c:878
int32_t spi_write_uint32(uint32_t value, uint32_t timeout_ms)
Sendet einen 32-Bit-Wert über SPI.
Definition wgrhal_ext.c:274
int32_t ws2812_set_color(uint8_t led, rgb_color_t color)
Setzt die Farbe einer WS2812B LED.
Definition wgrhal_ext.c:307
int32_t spi_wait_rx_data(uint32_t timeout_ms)
Wartet darauf, dass Daten im SPI-Empfangspuffer verfügbar sind.
Definition wgrhal_ext.c:203
void print_ok(const char *label)
Gibt ein Label als OK-Nachricht aus.
Definition wgrhal_ext.c:992
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.
Definition wgrhal_ext.c:819
void ssd1351_send_commands(const uint8_t *buf, size_t len)
Sendet eine Folge von Befehlen an das SSD1351 Display.
Definition wgrhal_ext.c:784
void ssd1351_fill_screen(uint16_t color)
Füllt das gesamte Display mit einer Farbe.
void spi_enable(void)
Aktiviert die SPI-Schnittstelle.
Definition wgrhal_ext.c:109
void draw_status_bar(const char *text, uint16_t bg_color, uint16_t fg_color)
Zeichnet eine Statusleiste am oberen Displayrand.
Definition wgrhal_ext.c:888
uint32_t div_calc_remainder(uint32_t dividend, uint32_t divisor)
Berechnet den Rest einer Division.
Definition wgrhal_ext.c:87
void pwm_free_note_buffer(void)
Gibt den für PWM-Noten reservierten Speicher frei.
Definition wgrhal_ext.c:463
void pwm_play_note(note_t note, uint32_t octave)
Spielt eine bestimmte Note in einer festgelegten Oktave über den PWM aus.
Definition wgrhal_ext.c:424
int32_t div_calc(uint32_t dividend, uint32_t divisor, div_result_t *result)
Führt eine Division durch und liefert Quotient und Rest.
Definition wgrhal_ext.c:52
void terminal_print_col(const char *text, uint16_t color)
Gibt einen String im Terminal mit einer bestimmten Textfarbe aus.
Definition wgrhal_ext.c:976
uint32_t mult_calc(uint32_t multiplicand, uint32_t multiplier)
Berechnet das 32-Bit-Ergebnis einer Multiplikation.
Definition wgrhal_ext.c:41
uint32_t heap_free_space(void)
Ermittelt den aktuell freien Heap-Speicher.
Definition wgrhal_ext.c:533
void spi_automatic_cs(bool active)
Aktiviert oder deaktiviert den automatischen Chipselect (CS) der SPI-Schnittstelle.
Definition wgrhal_ext.c:123
int pwm_precompute_notes(void)
Berechnet Notenparameter für den PWM-Modus.
Definition wgrhal_ext.c:401
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.
Definition wgrhal_ext.c:984
void terminal_print(const char *str)
Gibt einen String im Terminal aus.
Definition wgrhal_ext.c:968
void terminal_put_char(char c)
Gibt ein einzelnes Zeichen im Terminal aus und aktualisiert den Cursor.
Definition wgrhal_ext.c:934
void spi_disable(void)
Deaktiviert die SPI-Schnittstelle.
Definition wgrhal_ext.c:116
rgb_color_t ws2812_get_color(uint8_t led)
Liest die aktuell gesetzte Farbe einer WS2812B LED.
Definition wgrhal_ext.c:318
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.
Definition wgrhal_ext.c:284
void spi_set_clock_divider(uint32_t divider)
Konfiguriert den Taktteiler der SPI-Schnittstelle.
Definition wgrhal_ext.c:147
void ssd1351_send_command(uint8_t cmd)
Sendet einen einzelnen Befehl an das SSD1351 Display.
Definition wgrhal_ext.c:763
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.
Definition wgrhal_ext.c:193
uint32_t spi_tx_empty(void)
Prüft, ob der SPI-Sende-Puffer leer ist.
Definition wgrhal_ext.c:198
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.
Definition wgrhal_ext.c:178
uint32_t spi_get_status(void)
Liest den aktuellen Status der SPI-Schnittstelle.
Definition wgrhal_ext.c:163
void free(void *ap)
Gibt einen zuvor allokierten Speicherblock frei.
Definition wgrhal_ext.c:598
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.
Definition wgrhal_ext.c:771
void * calloc(uint32_t nmemb, uint32_t size)
Allokiert einen Speicherblock für ein Array und initialisiert diesen mit 0.
Definition wgrhal_ext.c:662
void spi_cs(uint32_t active)
Setzt den SPI-Chipselect-Zustand.
Definition wgrhal_ext.c:137
void draw_char_cell(uint8_t row, uint8_t col, char c)
Zeichnet ein einzelnes Zeichen in einer Terminalzelle.
Definition wgrhal_ext.c:865
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.
Definition wgrhal_ext.c:833
uint64_t mult_calc_64(uint32_t multiplicand, uint32_t multiplier)
Berechnet das 64-Bit-Ergebnis einer Multiplikation.
Definition wgrhal_ext.c:27
uint32_t spi_fifo_full(void)
Prüft, ob das SPI-FIFO voll ist.
Definition wgrhal_ext.c:168
Erweiterte Funktionen und Hardwarezugriffe für den WGR-V-Prozessor.
#define RESL_OFFSET
Offset für die niederwertigen 32-Bit des 64-Bit-Ergebnisses.
Definition wgrhal_ext.h:42
#define SPI_CTRL_OFFSET
Offset für das SPI-Steuerregister.
Definition wgrhal_ext.h:76
#define DIV_INFO_OFFSET
Offset für das Informationsregister des Dividers.
Definition wgrhal_ext.h:51
#define DIV_SOR_OFFSET
Offset für den Divisor.
Definition wgrhal_ext.h:59
#define DIV_BASE_ADDR
Basisadresse für den Hardware-Divider.
Definition wgrhal_ext.h:47
#define TERM_COLS
Anzahl der Spalten im Terminal.
Definition wgrhal_ext.h:589
#define WS_BASE_ADDR
Basisadresse für die WS2812B LED-Steuerung.
Definition wgrhal_ext.h:101
#define MUL2_OFFSET
Offset für den zweiten Multiplikanden.
Definition wgrhal_ext.h:34
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.
Definition wgrhal_ext.h:597
#define MUL1_OFFSET
Offset für den ersten Multiplikanden.
Definition wgrhal_ext.h:30
note_t
Aufzählung der Noten im Halbtonsystem.
Definition wgrhal_ext.h:364
@ NOTE_B
Definition wgrhal_ext.h:376
#define SPI_RX_OFFSET
Offset für das SPI-Empfangsregister.
Definition wgrhal_ext.h:92
#define SPI_STATUS_OFFSET
Offset für das SPI-Statusregister.
Definition wgrhal_ext.h:84
#define CHAR_WIDTH
Breite eines Zeichens in Pixel.
Definition wgrhal_ext.h:573
#define SPI_TX_OFFSET
Offset für das SPI-Sende-Register.
Definition wgrhal_ext.h:88
#define SSD1351_WIDTH
Breite des SSD1351 Displays in Pixel.
Definition wgrhal_ext.h:565
#define SSD1351_HEIGHT
Höhe des SSD1351 Displays in Pixel.
Definition wgrhal_ext.h:569
#define SPI_CS_OFFSET
Offset für die SPI-Chipselect-Steuerung.
Definition wgrhal_ext.h:96
#define TOTAL_ROWS
Gesamte Anzahl der Textzeilen auf dem Display.
Definition wgrhal_ext.h:585
#define DIV_REM_OFFSET
Offset für den Rest.
Definition wgrhal_ext.h:67
#define MULT_INFO_OFFSET
Offset für das Informationsregister des Multiplikators.
Definition wgrhal_ext.h:26
#define DIV_QUO_OFFSET
Offset für den Quotienten.
Definition wgrhal_ext.h:63
#define RESH_OFFSET
Offset für die höheren 32-Bit des 64-Bit-Ergebnisses.
Definition wgrhal_ext.h:38
#define COLOR_WHITE
Farbe: Weiß.
Definition wgrhal_ext.h:610
#define STATUS_BAR_ROWS
Anzahl der Zeilen für die Statusleiste.
Definition wgrhal_ext.h:581
#define HOUSEKEEPING_MS
Intervall für Display-Housekeeping in Millisekunden.
Definition wgrhal_ext.h:601
#define COLOR_BLACK
Farbe: Schwarz.
Definition wgrhal_ext.h:606
#define MULT_BASE_ADDR
Basisadresse für den Hardware-Multiplikator.
Definition wgrhal_ext.h:22
#define COLOR_RED
Farbe: Rot.
Definition wgrhal_ext.h:614
#define DIV_END_OFFSET
Offset für den Dividend.
Definition wgrhal_ext.h:55
#define CHAR_HEIGHT
Höhe eines Zeichens in Pixel.
Definition wgrhal_ext.h:577
#define SPI_CLK_OFFSET
Offset für das SPI-Taktregister.
Definition wgrhal_ext.h:80
#define SPI_BASE_ADDR
Basisadresse für die SPI-Schnittstelle.
Definition wgrhal_ext.h:72
#define COLOR_GREEN
Farbe: Grün.
Definition wgrhal_ext.h:618