diff --git a/chainloader/src/kernel/mini_uart.c b/chainloader/src/kernel/mini_uart.c index 1068ebf..80ab5b6 100644 --- a/chainloader/src/kernel/mini_uart.c +++ b/chainloader/src/kernel/mini_uart.c @@ -1,13 +1,13 @@ #include "kernel/mini_uart.h" void uart_send (char c) { - while (!((*(unsigned int *) AUX_MU_LSR_REG) & 0x20)) + while (! ((*(unsigned int *) AUX_MU_LSR_REG) & 0x20)) ; *(unsigned int *) AUX_MU_IO_REG = c; } char uart_recv (void) { - while (!((*(unsigned int *) AUX_MU_LSR_REG) & 0x01)) + while (! ((*(unsigned int *) AUX_MU_LSR_REG) & 0x01)) ; return ((*(unsigned int *) AUX_MU_IO_REG) & 0xFF); } diff --git a/thorn/include/common/font.h b/thorn/include/common/font.h index b732416..b11ad30 100644 --- a/thorn/include/common/font.h +++ b/thorn/include/common/font.h @@ -2,7 +2,7 @@ #define _ROSE_C_FONT_H #define FONT_SIZE 8 -#define FONT_FACTOR 2 +#define FONT_FACTOR 3 #define FONT_REAL_WIDTH (FONT_SIZE * FONT_FACTOR) // Spacing between lines in pixels @@ -20,6 +20,7 @@ #include "common/gpu.h" #include "common/screen.h" +#include "kernel/mini_uart.h" #include "kernel/mm.h" static point_t cursor = {0, 0}; @@ -29,10 +30,11 @@ static volatile color_t font_normal_fg = {0xC0, 0xC0, 0xC0, 0x00}; static volatile color_t font_error_fg = {0x00, 0x00, 0xC0, 0x00}; static volatile color_t font_fg; -const unsigned long long int * font (int c); +unsigned char const * font (unsigned char c); void printc (char c); void printc_location (point_t point, char c); +void prints_location (point_t point, char const * s); void putc_screen (void * p, char c); diff --git a/thorn/include/common/screen.h b/thorn/include/common/screen.h index cb6dda9..347e1e4 100644 --- a/thorn/include/common/screen.h +++ b/thorn/include/common/screen.h @@ -3,6 +3,9 @@ #include "common/geometry.h" #include "common/gpu.h" +#include "common/logging.h" +#include "common/math.h" +#include "common/printf.h" void drawpx (point_t p, color_t color); @@ -16,6 +19,7 @@ void drawline_grid (point_t p0, point_t p1, color_t color); void drawrec (point_t p0, point_t p1, color_t color); void drawcircle (point_t p, int radius, color_t color); void draw_all_octant_points (point_t p, point_t offset, color_t color); +void fillrec (point_t pp0, point_t p1, color_t color); void test_drawing (); diff --git a/thorn/include/common/temperature.h b/thorn/include/common/temperature.h new file mode 100644 index 0000000..6528640 --- /dev/null +++ b/thorn/include/common/temperature.h @@ -0,0 +1,50 @@ +#ifndef _ROSE_C_TEMPERATURE_H +#define _ROSE_C_TEMPERATURE_H + +#include "common/font.h" +#include "common/screen.h" +#include "common/stdbool.h" +#include "kernel/fork.h" +#include "kernel/gpio.h" +#include "kernel/mailbox.h" + +#define GPIO_FAN 18 + +// Temperature the system tries to keep. Turns off cooling if it falls below. +// NOTE: The pi hits a 'soft' limit at 70 °C, reducing clock frequency. +// This value is defined in the config.txt and defaults to 60 °C if not set +#define TEMPERATURE_FAN_OFF 47500 +#define TEMPERATURE_FAN_ON 50000 +#define TEMPERATURE_MAX 80000 + +#define TEMPERATURE_CHECK_DELAY 2000 + +#define TEMPERATURE_POINTS 200 + +#define TEMPERATURE_GRAPH_LOW 45000 +#define TEMPERATURE_GRAPH_HIGH 55000 + +static volatile unsigned int __attribute__ ((aligned (16))) temperature_request[8]; + +static unsigned int temperatures[TEMPERATURE_POINTS] = {0}; +static unsigned int current_temperature_index = 0; + +// Max temperature in degree milliCelsius. +// USB + Ethernet are designed up to 70 °C but unlikely to overheat. +// CPU is designed up to 85 °C so 80 is probably a reasonable upper limit. +// Consider reducing to 70 °C if the workload on the ports increases +static int max_temperature; + +bool init_temperature (void); + +void regulate_temperature (void); + +int get_max_temperature (void); + +int get_temperature (void); + +void set_fan (bool enable); + +void draw_temp_graph (void); + +#endif//_ROSE_C_TEMPERATURE_H \ No newline at end of file diff --git a/thorn/include/kernel/irq.h b/thorn/include/kernel/irq.h index d95cc0b..7997206 100644 --- a/thorn/include/kernel/irq.h +++ b/thorn/include/kernel/irq.h @@ -13,7 +13,7 @@ void enable_interrupt_controller (void); -void show_invalid_entry_message (int type, ptr_t esr, ptr_t address); +void show_invalid_entry_message (int type, ptr_t esr, ptr_t address, ptr_t far); void irq_vector_init (void); diff --git a/thorn/include/kernel/timer.h b/thorn/include/kernel/timer.h index f5cd0b8..bfc59ce 100644 --- a/thorn/include/kernel/timer.h +++ b/thorn/include/kernel/timer.h @@ -1,6 +1,12 @@ #ifndef _ROSE_K_TIMER_H #define _ROSE_K_TIMER_H +#include "common/printf.h" +#include "common/status_led.h" +#include "common/utils.h" +#include "kernel/peripherals/timer.h" +#include "kernel/sched.h" + void timer_init (void); void handle_timer_irq (void); diff --git a/thorn/src/common/debug.c b/thorn/src/common/debug.c index 4a65209..25750ce 100644 --- a/thorn/src/common/debug.c +++ b/thorn/src/common/debug.c @@ -15,7 +15,7 @@ void hex_dump (byte_t * array) { print_hex (array[i - j]); } printf (" "); - if (!(i % 32)) + if (! (i % 32)) printf ("\r\n"); } printf ("\r\n"); diff --git a/thorn/src/common/font.c b/thorn/src/common/font.c index 86addf5..fe134ea 100644 --- a/thorn/src/common/font.c +++ b/thorn/src/common/font.c @@ -1,9 +1,9 @@ #include "common/font.h" /* From https://github.com/dhepper/font8x8/blob/master/font8x8_block.h */ -const unsigned long long int * font (int c) { - static const char f[128][FONT_SIZE] = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},// U+0000 (nul) +unsigned char const * font (unsigned char c) { + static unsigned char const f[256][FONT_SIZE] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},// U+0000 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},// U+0001 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},// U+0002 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},// U+0003 @@ -62,7 +62,7 @@ const unsigned long long int * font (int c) { {0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00},// U+0038 (8) {0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00},// U+0039 (9) {0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00},// U+003A (:) - {0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06},// U+003B (//) + {0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06},// U+003B (;) {0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00},// U+003C (<) {0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00},// U+003D (=) {0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00},// U+003E (>) @@ -130,13 +130,130 @@ const unsigned long long int * font (int c) { {0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00},// U+007C (|) {0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00},// U+007D (}) {0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},// U+007E (~) - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // U+007F - }; - return (unsigned long long int *) f[c]; + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},// U+007F + {0x1E, 0x33, 0x03, 0x33, 0x1E, 0x18, 0x30, 0x1E},// U+00C7 (C cedille) + {0x00, 0x33, 0x00, 0x33, 0x33, 0x33, 0x7E, 0x00},// U+00FC (u umlaut) + {0x38, 0x00, 0x1E, 0x33, 0x3F, 0x03, 0x1E, 0x00},// U+00E9 (e aigu) + {0x7E, 0xC3, 0x3C, 0x60, 0x7C, 0x66, 0xFC, 0x00},// U+00E2 (a circumflex) + {0x33, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x7E, 0x00},// U+00E4 (a umlaut) + {0x07, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x7E, 0x00},// U+00E0 (a grave) + {0x0C, 0x0C, 0x1E, 0x30, 0x3E, 0x33, 0x7E, 0x00},// U+00E5 (a ring) + {0x00, 0x00, 0x1E, 0x03, 0x03, 0x1E, 0x30, 0x1C},// U+00E7 (c cedille) + {0x7E, 0xC3, 0x3C, 0x66, 0x7E, 0x06, 0x3C, 0x00},// U+00EA (e circumflex) + {0x33, 0x00, 0x1E, 0x33, 0x3F, 0x03, 0x1E, 0x00},// U+00EB (e umlaut) + {0x07, 0x00, 0x1E, 0x33, 0x3F, 0x03, 0x1E, 0x00},// U+00E8 (e grave) + {0x33, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},// U+00EF (i umlaut) + {0x3E, 0x63, 0x1C, 0x18, 0x18, 0x18, 0x3C, 0x00},// U+00EE (i circumflex) + {0x07, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},// U+00EC (i grave) + {0x63, 0x1C, 0x36, 0x63, 0x7F, 0x63, 0x63, 0x00},// U+00C4 (A umlaut) + {0x0C, 0x0C, 0x00, 0x1E, 0x33, 0x3F, 0x33, 0x00},// U+00C5 (A ring) + {0x07, 0x00, 0x3F, 0x06, 0x1E, 0x06, 0x3F, 0x00},// U+00C8 (E grave) + {0x00, 0x00, 0xFE, 0x30, 0xFE, 0x33, 0xFE, 0x00},// U+00E6 (ae) + {0x7C, 0x36, 0x33, 0x7F, 0x33, 0x33, 0x73, 0x00},// U+00C6 (AE) + {0x1E, 0x33, 0x00, 0x1E, 0x33, 0x33, 0x1E, 0x00},// U+00F4 (o circumflex) + {0x00, 0x33, 0x00, 0x1E, 0x33, 0x33, 0x1E, 0x00},// U+00F6 (o umlaut) + {0x00, 0x07, 0x00, 0x1E, 0x33, 0x33, 0x1E, 0x00},// U+00F2 (o grave) + {0x1E, 0x33, 0x00, 0x33, 0x33, 0x33, 0x7E, 0x00},// U+00FB (u circumflex) + {0x00, 0x07, 0x00, 0x33, 0x33, 0x33, 0x7E, 0x00},// U+00F9 (u grave) + {0x00, 0x33, 0x00, 0x33, 0x33, 0x3E, 0x30, 0x1F},// U+00FF (y umlaut) + {0xC3, 0x18, 0x3C, 0x66, 0x66, 0x3C, 0x18, 0x00},// U+00D6 (O umlaut) + {0x33, 0x00, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x00},// U+00DC (U umlaut) + {0x18, 0x18, 0x7E, 0x03, 0x03, 0x7E, 0x18, 0x18},// U+00A2 (dollarcents) + {0x1C, 0x36, 0x26, 0x0F, 0x06, 0x67, 0x3F, 0x00},// U+00A3 (pound sterling) + {0x33, 0x33, 0x1E, 0x3F, 0x0C, 0x3F, 0x0C, 0x0C},// U+00A5 (yen) + {0x7C, 0xC6, 0x1C, 0x36, 0x36, 0x1C, 0x33, 0x1E},// U+00A7 (paragraph) + {0x70, 0xD8, 0x18, 0x3C, 0x18, 0x18, 0x1B, 0x0E},// U+0192 (dutch florijn) + {0x38, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x7E, 0x00},// U+00E1 (a aigu) + {0x1C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00},// U+00ED (i augu) + {0x00, 0x38, 0x00, 0x1E, 0x33, 0x33, 0x1E, 0x00},// U+00F3 (o aigu) + {0x00, 0x38, 0x00, 0x33, 0x33, 0x33, 0x7E, 0x00},// U+00FA (u aigu) + {0x00, 0x1F, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x00},// U+00F1 (n ~) + {0x3F, 0x00, 0x33, 0x37, 0x3F, 0x3B, 0x33, 0x00},// U+00D1 (N ~) + {0x3C, 0x36, 0x36, 0x7C, 0x00, 0x00, 0x00, 0x00},// U+00AA (superscript a) + {0x1C, 0x36, 0x36, 0x1C, 0x00, 0x00, 0x00, 0x00},// U+00BA (superscript 0) + {0x0C, 0x00, 0x0C, 0x06, 0x03, 0x33, 0x1E, 0x00},// U+00BF (inverted ?) + {0x00, 0x00, 0x00, 0x3F, 0x03, 0x03, 0x00, 0x00},// U+2310 (gun pointing right) + {0x00, 0x00, 0x00, 0x3F, 0x30, 0x30, 0x00, 0x00},// U+00AC (gun pointing left) + {0xC3, 0x63, 0x33, 0x7B, 0xCC, 0x66, 0x33, 0xF0},// U+00BD (1/2) + {0xC3, 0x63, 0x33, 0xBD, 0xEC, 0xF6, 0xF3, 0x03},// U+00BC (1/4) + {0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00},// U+00A1 (inverted !) + {0x00, 0xCC, 0x66, 0x33, 0x66, 0xCC, 0x00, 0x00},// U+00AB (<<) + {0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00},// U+00BB (>>) + {0x55, 0x00, 0xAA, 0x00, 0x55, 0x00, 0xAA, 0x00},// U+2591 (25% solid) + {0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA},// U+2592 (50% solid) + {0xFF, 0xAA, 0xFF, 0x55, 0xFF, 0xAA, 0xFF, 0x55},// U+2593 (75% solid) + {0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08},// U+2502 (thin vertical) + {0x08, 0x08, 0x08, 0x08, 0x0f, 0x08, 0x08, 0x08},// U+2524 (down L, left L, up L) + {0x08, 0x08, 0x08, 0x0F, 0x08, 0x0F, 0x08, 0x08},// U+2561 (up L, down L, left D) + {0x14, 0x14, 0x14, 0x14, 0x17, 0x14, 0x14, 0x14},// U+2562 (up D, down D, left L) + {0x00, 0x00, 0x00, 0x00, 0x1F, 0x14, 0x14, 0x14},// U+2556 (down D, left L) + {0x00, 0x00, 0x00, 0x0F, 0x08, 0x0F, 0x08, 0x08},// U+2555 (down L, left D) + {0x14, 0x14, 0x14, 0x17, 0x10, 0x17, 0x14, 0x14},// U+2563 (up D, down D, left D) + {0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14},// U+2551 (double vertical) + {0x00, 0x00, 0x00, 0x1F, 0x10, 0x17, 0x14, 0x14},// U+2557 (down D, left D) + {0x14, 0x14, 0x14, 0x17, 0x10, 0x1F, 0x00, 0x00},// U+255D (up D, left D) + {0x14, 0x14, 0x14, 0x14, 0x1F, 0x00, 0x00, 0x00},// U+255C (up D, left L) + {0x08, 0x08, 0x08, 0x0F, 0x08, 0x0F, 0x00, 0x00},// U+255B (up L, left D) + {0x00, 0x00, 0x00, 0x00, 0x0f, 0x08, 0x08, 0x08},// U+2510 (down L, left L) + {0x08, 0x08, 0x08, 0x08, 0xf8, 0x00, 0x00, 0x00},// U+2514 (up L, right L) + {0x08, 0x08, 0x08, 0x08, 0xff, 0x00, 0x00, 0x00},// U+2534 (up L, right L, left L) + {0x00, 0x00, 0x00, 0x00, 0xff, 0x08, 0x08, 0x08},// U+252C (down L, right L, left L) + {0x08, 0x08, 0x08, 0x08, 0xf8, 0x08, 0x08, 0x08},// U+251C (down L, right L, up L) + {0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00},// U+2500 (thin horizontal) + {0x08, 0x08, 0x08, 0x08, 0xff, 0x08, 0x08, 0x08},// U+253C (up L, right L, left L, down L) + {0x08, 0x08, 0x08, 0xF8, 0x08, 0xF8, 0x08, 0x08},// U+255E (up L, down L, right D) + {0x14, 0x14, 0x14, 0x14, 0xF4, 0x14, 0x14, 0x14},// U+255F (up D, down D, right L) + {0x14, 0x14, 0x14, 0xF4, 0x04, 0xFC, 0x00, 0x00},// U+255A (up D, right D) + {0x00, 0x00, 0x00, 0xFC, 0x04, 0xF4, 0x14, 0x14},// U+2554 (down D, right D) + {0x14, 0x14, 0x14, 0xF7, 0x00, 0xFF, 0x00, 0x00},// U+2569 (left D, right D, up D) + {0x00, 0x00, 0x00, 0xFF, 0x00, 0xF7, 0x14, 0x14},// U+2566 (left D, right D, down D) + {0x14, 0x14, 0x14, 0xF4, 0x04, 0xF4, 0x14, 0x14},// U+2560 (up D, down D, right D) + {0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00},// U+2550 (double horizontal) + {0x14, 0x14, 0x14, 0xF7, 0x00, 0xF7, 0x14, 0x14},// U+256C (left D, right D, down D, up D) + {0x08, 0x08, 0x08, 0xFF, 0x00, 0xFF, 0x00, 0x00},// U+2567 (left D, right D, up L) + {0x14, 0x14, 0x14, 0x14, 0xFF, 0x00, 0x00, 0x00},// U+2568 (left L, right L, up D) + {0x00, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x08, 0x08},// U+2564 (left D, right D, down L) + {0x00, 0x00, 0x00, 0x00, 0xFF, 0x14, 0x14, 0x14},// U+2565 (left L, right L, down D) + {0x14, 0x14, 0x14, 0x14, 0xFC, 0x00, 0x00, 0x00},// U+2559 (up D, right L) + {0x08, 0x08, 0x08, 0xF8, 0x08, 0xF8, 0x00, 0x00},// U+2558 (up L, right D) + {0x00, 0x00, 0x00, 0xF8, 0x08, 0xF8, 0x08, 0x08},// U+2552 (down L, right D) + {0x00, 0x00, 0x00, 0x00, 0xFC, 0x14, 0x14, 0x14},// U+2553 (down D, right L) + {0x14, 0x14, 0x14, 0x14, 0xFF, 0x14, 0x14, 0x14},// U+256B (left L, right L, down D, up D) + {0x08, 0x08, 0x08, 0xFF, 0x08, 0xFF, 0x08, 0x08},// U+256A (left D, right D, down L, up L) + {0x08, 0x08, 0x08, 0x08, 0x0f, 0x00, 0x00, 0x00},// U+2518 (up L, left L) + {0x00, 0x00, 0x00, 0x00, 0xf8, 0x08, 0x08, 0x08},// U+250C (down L, right L) + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},// U+2588 (solid) + {0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF},// U+2584 (bottom half) + {0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F},// U+258C (left half) + {0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0},// U+2590 (right half) + {0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00},// U+2580 (top half) + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x1C, 0x36, 0x36, 0x1C, 0x00, 0x00, 0x00, 0x00},// U+00BA (degree) + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; + return f[c]; } void printc_location (point_t point, char c) { - unsigned char const * bitmap = (unsigned char const *) font (c); + unsigned char const * bitmap = font (c); for (int i = 0; i < FONT_SIZE; i++) { for (int j = 0; j < FONT_SIZE; j++) { bool is_on = bitmap[i] & (1 << j); @@ -152,6 +269,12 @@ void printc_location (point_t point, char c) { } } } +void prints_location (point_t point, char const * s) { + while (*s) { + printc_location (point, *s++); + point.x += FONT_REAL_WIDTH; + } +} void printc (char c) { // Handle special characters, print otherwise @@ -177,11 +300,11 @@ void printc (char c) { cursor.y += FONT_REAL_HEIGHT; } // If next line would overflow screen height (ignoring line spacing) move to beginning of screen - if (cursor.y + FONT_REAL_WIDTH - FONT_SPACING >= get_max_height ()) { + if (cursor.y + FONT_REAL_WIDTH - FONT_SPACING > get_max_height () / 2) { #ifdef FONT_SCROLLBACK cursor.y -= FONT_SB_LINES * FONT_REAL_HEIGHT; - unsigned int remove_size = FONT_SB_LINES * FONT_REAL_HEIGHT * get_fb_info ()->pitch; - unsigned int scroll_size = get_fb_info ()->fb_size - remove_size; + unsigned int remove_size = FONT_SB_LINES * FONT_REAL_HEIGHT * get_fb_info ()->pitch - FONT_SPACING; + unsigned int scroll_size = get_fb_info ()->fb_size / 2 - remove_size; memcpy ((ptr_t) get_fb (), (ptr_t) get_fb () + remove_size, scroll_size); memzero ((ptr_t) get_fb () + scroll_size, remove_size); #else diff --git a/thorn/src/common/gpu.c b/thorn/src/common/gpu.c index b7a6a95..1c54019 100644 --- a/thorn/src/common/gpu.c +++ b/thorn/src/common/gpu.c @@ -15,7 +15,7 @@ bool init_gpu () { gpu_msg_buffer[0] = (4 * ++c);// Write message size at the beginning of the buffer // If reading physical screen dimension fails exit function - if (!mailbox_request (gpu_msg_buffer, PROPERTY_ARM_VC)) + if (! mailbox_request (gpu_msg_buffer, PROPERTY_ARM_VC)) return false; } { // Second message: request frame buffer @@ -23,11 +23,13 @@ bool init_gpu () { gpu_msg_buffer[++c] = 0;// Response - will be 0x80000000 for SUCCESS or 0x80000001 for FAILURE #ifdef GPU_OVERRIDE_PHYSICAL_SCREEN // If this is set, update physical /virtual dimensions based on constants - gpu_msg_buffer[++c] = 0x00048003; // Tag to set virtual display width / height - gpu_msg_buffer[++c] = 8; // Size of value buffer - gpu_msg_buffer[++c] = 0; // Response & value buffer size written will be written here - gpu_msg_buffer[++c] = GPU_SCREEN_WIDTH; // Set virtual screen width | Overwritten by actual virtual width - gpu_msg_buffer[++c] = GPU_SCREEN_HEIGHT;// Set virtual screen height | Overwritten by actual virtual height + gpu_msg_buffer[++c] = 0x00048003; // Tag to set virtual display width / height + gpu_msg_buffer[++c] = 8; // Size of value buffer + gpu_msg_buffer[++c] = 0; // Response & value buffer size written will be written here + gpu_msg_buffer[++c] = GPU_SCREEN_WIDTH;// Set virtual screen width | Overwritten by actual virtual width + int index_gpu_width = c; + gpu_msg_buffer[++c] = GPU_SCREEN_HEIGHT;// Set virtual screen height | Overwritten by actual virtual height + int index_gpu_height = c; gpu_msg_buffer[++c] = 0x00048004; // Tag to set virtual display width / height gpu_msg_buffer[++c] = 8; // Size of value buffer @@ -67,7 +69,7 @@ bool init_gpu () { gpu_msg_buffer[0] = (4 * ++c);// Write message size at the beginning of the buffer // If message failed exit - if (!mailbox_request (gpu_msg_buffer, PROPERTY_ARM_VC)) + if (! mailbox_request (gpu_msg_buffer, PROPERTY_ARM_VC)) return false; // Since message succeeded, update frame buffer and its size @@ -95,7 +97,7 @@ bool init_gpu () { gpu_msg_buffer[0] = (4 * ++c);// Write message size at the beginning of the buffer // If message failed exit - if (!mailbox_request (gpu_msg_buffer, PROPERTY_ARM_VC)) + if (! mailbox_request (gpu_msg_buffer, PROPERTY_ARM_VC)) return false; // Else write pitch appropriately diff --git a/thorn/src/common/screen.c b/thorn/src/common/screen.c index 9dbc0c5..3e3d738 100644 --- a/thorn/src/common/screen.c +++ b/thorn/src/common/screen.c @@ -1,6 +1,4 @@ #include "common/screen.h" -#include "common/font.h" -#include "common/math.h" void drawpx (point_t p, color_t color) { unsigned long int location = p.y * (get_fb_info ()->pitch) / sizeof (color_t) + p.x; @@ -10,6 +8,14 @@ void drawpx (point_t p, color_t color) { // Bresenham's line algorithm void drawline (point_t p0, point_t p1, color_t color) { + if (p0.x > get_max_width () + || p0.y > get_max_height () + || p1.x > get_max_width () + || p1.y > get_max_height ()) { + ERROR ("Couldn't draw line"); + printf ("Offending points: {%u, %u} - {%u, %u}\r\n", p0.x, p0.y, p1.x, p1.y); + return; + } if (p1.y == p0.y) { if (p0.x < p1.x) @@ -149,6 +155,16 @@ short get_max_height () { return get_fb_info ()->virtual_height - 1; } +void fillrec (point_t p0, point_t p1, color_t color) { + unsigned int startx = p0.x > p1.x ? p1.x : p0.x; + unsigned int starty = p0.y > p1.y ? p1.y : p0.y; + unsigned int endx = p0.x < p1.x ? p1.x : p0.x; + unsigned int endy = p0.y < p1.y ? p1.y : p0.y; + for (unsigned int i = starty; i <= endy; i++) { + drawline_grid ((point_t) {startx, i}, (point_t) {endx, i}, color); + } +} + void test_drawing () { color_t white_color = {0xff, 0xff, 0xff, 0xff}; color_t blue_color = {0xff, 0x00, 0x00, 0xff}; @@ -234,4 +250,12 @@ void test_drawing () { drawcircle (POINT (1128, 428), 50, red_color); + + fillrec (POINT (800, 800), + POINT (900, 900), + blue_color); + + fillrec (POINT (800, 800), + POINT (850, 850), + red_color); } diff --git a/thorn/src/common/status_led.c b/thorn/src/common/status_led.c index b8b1b03..f0b961f 100644 --- a/thorn/src/common/status_led.c +++ b/thorn/src/common/status_led.c @@ -16,10 +16,10 @@ bool get_led (int pin) { led_msg_buffer[0] = (4 * ++c);// Write message size at the beginning of the buffer - if (! mailbox_request (led_msg_buffer, PROPERTY_ARM_VC)) { + if (!mailbox_request (led_msg_buffer, PROPERTY_ARM_VC)) { printf ("ERROR\r\n"); }; - return ! led_msg_buffer[index_led]; + return !led_msg_buffer[index_led]; } /** @@ -49,7 +49,7 @@ void set_led (bool status, int pin) { } bool toggle_led (int pin) { - bool status = get_led (pin); + bool status = get_led (pin); set_led (status, pin); return status; } diff --git a/thorn/src/common/temperature.c b/thorn/src/common/temperature.c new file mode 100644 index 0000000..09f9343 --- /dev/null +++ b/thorn/src/common/temperature.c @@ -0,0 +1,133 @@ +#include "common/temperature.h" + +bool init_temperature () { + gpio_mode (GPIO_FAN, GPIO_OUTPUT); + { // Read out maximum temperature + int c = 0;// Message size; increment while we write + temperature_request[++c] = 0;// Response - will be 0x80000000 for SUCCESS or 0x80000001 for FAILURE + + temperature_request[++c] = 0x0003000a;// Tag to get maximum temperature + temperature_request[++c] = 8; // Size of value buffer + temperature_request[++c] = 0; // Response & value buffer size written will be written here + temperature_request[++c] = 0; // Temperature (device?) ID, should stay 0 + temperature_request[++c] = 0; // Will be overwritten by maximum temperature + int index_max_temperature = c; + + temperature_request[++c] = 0;// End tag + + temperature_request[0] = (4 * ++c);// Write message size at the beginning of the buffer + + // If reading maximum temperature fails, keep default + if (!mailbox_request (temperature_request, PROPERTY_ARM_VC)) + return false; + // Else update temperature + max_temperature = temperature_request[index_max_temperature] ?: TEMPERATURE_MAX; + } + + // Start regulate_temperature service here + copy_process (PF_KTHREAD, (unsigned long) ®ulate_temperature, 0, 0); + return true; +} + +void regulate_temperature () { + while (1) { + delay (TEMPERATURE_CHECK_DELAY); + unsigned int previous = temperatures[current_temperature_index]; + current_temperature_index = (current_temperature_index + 1) % TEMPERATURE_POINTS; + temperatures[current_temperature_index] = get_temperature (); + unsigned int current = temperatures[current_temperature_index]; + + if (current >= TEMPERATURE_FAN_ON) { + set_fan (1); + } else if (current <= TEMPERATURE_FAN_OFF) { + set_fan (0); + } + + previous = (previous + 50) / 100 * 100; + current = (current + 50) / 100 * 100; + printf ("\rCurrent temperature: %d,%d C. Change since last iteration: %d mC ", current / 1000, current % 1000 / 100, current - previous); + + draw_temp_graph (); + } +} + +int get_max_temperature () { + return max_temperature; +} + +int get_temperature () { + { // Read out current temperature + int c = 0;// Message size; increment while we write + temperature_request[++c] = 0;// Response - will be 0x80000000 for SUCCESS or 0x80000001 for FAILURE + + temperature_request[++c] = 0x00030006;// Tag to get current temperature + temperature_request[++c] = 8; // Size of value buffer + temperature_request[++c] = 4; // Response & value buffer size written will be written here + temperature_request[++c] = 0; // Temperature (device?) ID, should stay 0 + temperature_request[++c] = 0; // Will be overwritten by current temperature + int index_temperature = c; + + temperature_request[++c] = 0;// End tag + + temperature_request[0] = (4 * ++c);// Write message size at the beginning of the buffer + + // If reading maximum temperature fails, keep default + if (!mailbox_request (temperature_request, PROPERTY_ARM_VC)) + return max_temperature; + // Else return temperature + return temperature_request[index_temperature]; + } +} + +void set_fan (bool enable) { + gpio_set (GPIO_FAN, !enable); +} + +void draw_temp_graph () { + // Corners of graph + point_t OO = {0, get_max_height () / 2}; + point_t OY = {0, get_max_height ()}; + point_t XO = {get_max_width (), get_max_height () / 2}; + point_t XY = {get_max_width (), get_max_height ()}; + + // Clear lower half of screen + unsigned int pitch = get_fb_info ()->pitch; + unsigned int size = get_fb_info ()->fb_size; + unsigned long fb = (unsigned long) get_fb (); + memzero (fb + size / 8 * 4 - 7 * pitch, size / 4 - 5 * pitch); + memzero (fb + size / 8 * 6 - 11 * pitch, size / 8 - 3 * pitch); + memzero (fb + size / 8 * 7 - 13 * pitch, size / 8 - 22 * pitch); + + // Draw frame, legend and orientation lines + drawline_grid ((point_t) {0, get_max_height () / 8 * 6}, (point_t) {get_max_width (), get_max_height () / 8 * 6}, (color_t) {0, 128, 255, 0}); + drawline_grid ((point_t) {0, get_max_height () / 8 * 7}, (point_t) {get_max_width (), get_max_height () / 8 * 7}, (color_t) {0, 128, 0, 0}); + + drawline_grid ((point_t) {0, get_max_height () / 8 * 4}, (point_t) {get_max_width (), get_max_height () / 8 * 4}, (color_t) {255, 128, 0, 0}); + drawline_grid ((point_t) {4 * FONT_REAL_WIDTH, get_max_height () / 8 * 8}, (point_t) {get_max_width (), get_max_height () / 8 * 8}, (color_t) {255, 128, 0, 0}); + + char buf[5] = {0}; + sprintf (buf, "%d C", TEMPERATURE_GRAPH_HIGH / 1000); + prints_location (POINT (OO.x, OO.y - FONT_REAL_WIDTH - 3), buf); + sprintf (buf, "%d C", TEMPERATURE_GRAPH_LOW / 1000); + prints_location ((point_t) {OY.x, OY.y - FONT_REAL_WIDTH}, buf); + + // Draw lines between data points + color_t const red = {0, 0, 255, 0}; + color_t const blue = {196, 0, 0, 0}; + int factor_x = get_fb_info ()->virtual_width / TEMPERATURE_POINTS; + int divisor_y = (TEMPERATURE_GRAPH_HIGH - TEMPERATURE_GRAPH_LOW) / (get_fb_info ()->virtual_height / 2); + color_t current = red; + for (int j = 0; j < TEMPERATURE_POINTS; j++) { + unsigned int i0 = (current_temperature_index + j + 1) % TEMPERATURE_POINTS; + unsigned int i1 = (i0 + 1) % TEMPERATURE_POINTS; + if (!temperatures[i0] || !temperatures[i1]) + continue; + if (temperatures[i0] >= TEMPERATURE_FAN_ON) + current = red; + else if (temperatures[i0] <= TEMPERATURE_FAN_OFF) + current = blue; + point_t a = {j * factor_x, OY.y - (temperatures[i0] - TEMPERATURE_GRAPH_LOW) / divisor_y}; + point_t b = {(j + 1) * factor_x, OY.y - (temperatures[i1] - TEMPERATURE_GRAPH_LOW) / divisor_y}; + drawline (a, b, current); + } +} \ No newline at end of file diff --git a/thorn/src/config.txt b/thorn/src/config.txt index 1cb4eed..e187384 100644 --- a/thorn/src/config.txt +++ b/thorn/src/config.txt @@ -1,2 +1,3 @@ enable_uart=1 dtparam=watchdog=on +temp_soft_limit=70 \ No newline at end of file diff --git a/thorn/src/kernel/entry.S b/thorn/src/kernel/entry.S index 4f44a25..4fe363a 100644 --- a/thorn/src/kernel/entry.S +++ b/thorn/src/kernel/entry.S @@ -7,6 +7,7 @@ mov x0, #\type mrs x1, esr_el1 mrs x2, elr_el1 + mrs x3, far_el1 bl show_invalid_entry_message b err_hang .endm diff --git a/thorn/src/kernel/fork.c b/thorn/src/kernel/fork.c index 799f931..8072f83 100644 --- a/thorn/src/kernel/fork.c +++ b/thorn/src/kernel/fork.c @@ -10,7 +10,7 @@ int copy_process (ptr_t clone_flags, ptr_t fn, ptr_t arg, ptr_t stack) { struct task_struct * p; p = (struct task_struct *) get_free_page (); - if (!p) { + if (! p) { return -1; } @@ -49,7 +49,7 @@ int move_to_user_mode (ptr_t pc) { regs->pc = pc; regs->pstate = PSR_MODE_EL0t; ptr_t stack = get_free_page ();//allocate new user stack - if (!stack) { + if (! stack) { return -1; } regs->sp = stack + PAGE_SIZE; diff --git a/thorn/src/kernel/irq.c b/thorn/src/kernel/irq.c index b893bda..bab9f1f 100644 --- a/thorn/src/kernel/irq.c +++ b/thorn/src/kernel/irq.c @@ -19,8 +19,8 @@ void assign_target (unsigned int irq, unsigned int cpu) { put32 (targetRegister, get32 (targetRegister) | (1 << 8)); } -void show_invalid_entry_message (int type, ptr_t esr, ptr_t address) { - printf ("Type %s, ESR: %p, address, %p\r\n", entry_error_messages[type], (void *) esr, (void *) address); +void show_invalid_entry_message (int type, ptr_t esr, ptr_t address, ptr_t far) { + printf ("Type %s, ESR: %p, ELR: %p, FAR: %p\r\n", entry_error_messages[type], (void *) esr, (void *) address, (void *) far); } void enable_interrupt_controller () { diff --git a/thorn/src/kernel/kernel.c b/thorn/src/kernel/kernel.c index bfa13f6..c5af6ec 100644 --- a/thorn/src/kernel/kernel.c +++ b/thorn/src/kernel/kernel.c @@ -1,3 +1,5 @@ +#include "kernel/mini_uart.h"// needs to be above kernel/irq.h + #include "common/font.h" #include "common/gpu.h" #include "common/logging.h" @@ -6,10 +8,10 @@ #include "common/rng.h" #include "common/screen.h" #include "common/status_led.h" +#include "common/temperature.h" #include "common/utils.h" #include "kernel/fork.h" #include "kernel/irq.h" -#include "kernel/mini_uart.h" #include "kernel/mm.h" #include "kernel/sched.h" #include "kernel/sys.h" @@ -54,7 +56,7 @@ void user_process () { } void kernel_process () { - // printf ("Kernel process started. EL %d\r\n", get_el ()); + printf ("Kernel process started. EL %d\r\n", get_el ()); int err = move_to_user_mode ((unsigned long) &user_process); if (err < 0) { printf ("Error while moving process to user mode\n\r"); @@ -90,10 +92,9 @@ void kernel_init (void) { printf ("Height resolution: %d\r\n", get_fb_info ()->virtual_height); } } - - printf ("|...|...|...|...|\r\n"); - printf ("|\t|\t|\t|\t|\r\n"); - + // Temperature + printf ("Initialising temperature %s. Max temperature set to %d C.\r\n", + init_temperature () ? "succeeded" : "failed", get_max_temperature () / 1000); LOG ("Initialisation done"); ERROR ("I'm important!"); } @@ -113,27 +114,26 @@ void kernel_main (int processor_id) { switch (processor_id) { case 0: { - int res = copy_process (PF_KTHREAD, (unsigned long) &kernel_process, 0, 0); - if (res < 0) { - ERROR ("Can't start kernel process"); - break; - } + // int res = copy_process (PF_KTHREAD, (unsigned long) &kernel_process, 0, 0); + // if (res < 0) { + // ERROR ("Can't start kernel process"); + // break; + // } while (1) { schedule (); } break; } case 1: - if (get_fb ()) { - test_drawing (); + while (get_fb ()) { + // Do screen work here + // test_drawing (); + // break; } - break; case 2: case 3: - break; default: - while (1) - ; + while (1) {} printf ("Undefined behaviour on processor %d\r\n", processor_id); } printf ("Processor %d going out of scope\r\n", processor_id); diff --git a/thorn/src/kernel/mini_uart.c b/thorn/src/kernel/mini_uart.c index 8f6c2bf..44c3174 100644 --- a/thorn/src/kernel/mini_uart.c +++ b/thorn/src/kernel/mini_uart.c @@ -29,7 +29,7 @@ void mini_uart_init (void) { static volatile bool init_done = false; if (init_progress) { - while (! init_done) + while (!init_done) ; return; } @@ -71,7 +71,7 @@ void handle_mini_uart_irq (void) { case 19: toggle_blank_screen (); default: - mini_uart_send (c_event); + printf ("%c", c_event); } } diff --git a/thorn/src/kernel/sys.c b/thorn/src/kernel/sys.c index f6bcb70..0a677e9 100644 --- a/thorn/src/kernel/sys.c +++ b/thorn/src/kernel/sys.c @@ -15,7 +15,7 @@ int sys_clone (ptr_t stack) { ptr_t sys_malloc () { ptr_t addr = get_free_page (); - if (!addr) { + if (! addr) { return -1; } return addr; diff --git a/thorn/src/kernel/timer.c b/thorn/src/kernel/timer.c index 0fe4556..94950df 100644 --- a/thorn/src/kernel/timer.c +++ b/thorn/src/kernel/timer.c @@ -1,8 +1,4 @@ -#include "kernel/peripherals/timer.h" -#include "common/printf.h" -#include "common/status_led.h" -#include "common/utils.h" -#include "kernel/sched.h" +#include "kernel/timer.h" const unsigned int interval = 200000; unsigned int curVal = 0; diff --git a/thorn/src/kernel/uart.c b/thorn/src/kernel/uart.c index a148522..72a16c8 100644 --- a/thorn/src/kernel/uart.c +++ b/thorn/src/kernel/uart.c @@ -23,7 +23,7 @@ void _uart_init (void) { static volatile bool init_done = false; if (init_progress) { - while (!init_done) + while (! init_done) ; return; }