aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/kern/init.h7
-rw-r--r--linker/linker_script.ld83
-rw-r--r--src/kern/init.c97
-rw-r--r--src/kern/main.c105
4 files changed, 159 insertions, 133 deletions
diff --git a/include/kern/init.h b/include/kern/init.h
index 0ebbeac..7c40d19 100644
--- a/include/kern/init.h
+++ b/include/kern/init.h
@@ -64,6 +64,13 @@
void(*init7_ptr)() = init7fn; \
static void init7fn
+#define entry_point(fn) \
+ static __attribute((__section__(".entry_point"))) __attribute((__used__)) \
+ struct { \
+ uint32_t _unused; \
+ uint32_t entry_point; \
+ } c = { 0x2000c000, (uint32_t) &fn }
+
typedef enum {
INIT_LEVEL_0,
INIT_LEVEL_1,
diff --git a/linker/linker_script.ld b/linker/linker_script.ld
index ea6fc8a..8497768 100644
--- a/linker/linker_script.ld
+++ b/linker/linker_script.ld
@@ -8,66 +8,77 @@ MEMORY
SECTIONS
{
/* This is where the code goes. */
- WAT = ORIGIN(flash);
. = ORIGIN(flash);
- TEXT_START = .;
.text ALIGN(0x04) : {
+ . = ALIGN(0x04);
+ VECTORS_START = .;
*(.vectors); /* All .vector sections go here. */
- *(.text); /* All .text sections go here. */
- } >flash
- TEXT_STOP = .;
- . = ALIGN(0x04);
-
- .data : ALIGN(0x04) {
- /* Data segment as defined in the flash. */
- INIT_DATA_VALUES = LOADADDR(.data);
+ VECTORS_END = .;
- /* Data segment where it will be in memory. */
- . = ALIGN(0x04);
- DATA_SEGMENT_START = .;
- *(.data);
- . = ALIGN(0x1c);
- DATA_SEGMENT_STOP = .;
+ TEXT_START = .;
+ *(.text); /* All .text sections go here. */
+ TEXT_END = .;
- INIT_ROUTINES_FLASH_START =
- LOADADDR(.data) + (DATA_SEGMENT_STOP - DATA_SEGMENT_START);
+ /* Start the init sections. The inits sections are text sections which are
+ * executed in order during startup. */
INITS_START = .;
+ INIT_0_START = .;
*(.init0);
- INIT_0_END = ABSOLUTE(INIT_ROUTINES_FLASH_START) + (. - INITS_START);
+ INIT_0_END = .;
+ INIT_1_START = .;
*(.init1);
- INIT_1_END = ABSOLUTE(INIT_ROUTINES_FLASH_START) + (. - INITS_START);
+ INIT_1_END = .;
+ INIT_2_START = .;
*(.init2);
- INIT_2_END = ABSOLUTE(INIT_ROUTINES_FLASH_START) + (. - INITS_START);
+ INIT_2_END = .;
+ INIT_3_START = .;
*(.init3);
- INIT_3_END = ABSOLUTE(INIT_ROUTINES_FLASH_START) + (. - INITS_START);
+ INIT_3_END = .;
+ INIT_4_START = .;
*(.init4);
- INIT_4_END = ABSOLUTE(INIT_ROUTINES_FLASH_START) + (. - INITS_START);
+ INIT_4_END = .;
+ INIT_5_START = .;
*(.init5);
- INIT_5_END = ABSOLUTE(INIT_ROUTINES_FLASH_START) + (. - INITS_START);
+ INIT_5_END = .;
+ INIT_6_START = .;
*(.init6);
- INIT_6_END = ABSOLUTE(INIT_ROUTINES_FLASH_START) + (. - INITS_START);
+ INIT_6_END = .;
+ INIT_7_START = .;
*(.init7);
- INIT_7_END = ABSOLUTE(INIT_ROUTINES_FLASH_START) + (. - INITS_START);
+ INIT_7_END = .;
INITS_END = .;
- INIT_ROUTINES_FLASH_STOP =
- LOADADDR(.data) + (INITS_END - DATA_SEGMENT_START);
+ FLASH_STOP = .;
+ } >flash AT >flash
+
+ /* Data segment as defined in the flash. */
+ DATA_VALUES_IN_FLASH = LOADADDR(.data);
+
+ .data : ALIGN(0x04) {
+
+ /* Data segment where it will be in memory. */
+ . = ALIGN(0x04);
+ DATA_SEGMENT_START = .;
+ *(.data);
+ DATA_SEGMENT_STOP = .;
/* Align by 4 so we can optimize the copier to use uint32's. */
. = ALIGN(0x04);
*(.noinit);
- } >sram1 AT>flash
+ } >sram2 AT>flash
- . = ALIGN(0x04);
- BSS_START = .;
- .bss : {
+ .bss : ALIGN(0x04){
+ . = ALIGN(0x04);
+ BSS_START = .;
*(.bss);
. = ALIGN(0x04);
- } > sram1
- BSS_END = .;
+ BSS_END = .;
+ } > sram2
- HEAP_START = .;
- HEAP_STOP = ORIGIN(sram1) + LENGTH(sram1);
+ .heap : ALIGN(0x04) {
+ HEAP_START = .;
+ HEAP_STOP = ABSOLUTE(ORIGIN(sram1) + LENGTH(sram1));
+ } > sram1
}
diff --git a/src/kern/init.c b/src/kern/init.c
index 550fea0..0267b7b 100644
--- a/src/kern/init.c
+++ b/src/kern/init.c
@@ -18,16 +18,15 @@ int main();
/* These are defined in the linker script. */
#ifdef ARCH_STM32L4
-extern uint32_t INIT_DATA_VALUES;
+
+extern uint32_t DATA_VALUES_IN_FLASH;
extern uint32_t DATA_SEGMENT_START;
extern uint32_t DATA_SEGMENT_STOP;
-extern uint32_t TEXT_START;
-extern uint32_t TEXT_STOP;
extern uint32_t BSS_START;
extern uint32_t BSS_END;
-extern void (*INIT_ROUTINES_FLASH_START)();
-extern void (*INIT_ROUTINES_FLASH_STOP)();
+extern void (*INITS_START)();
+extern void (*INITS_END)();
extern uint32_t INIT_0_END;
extern uint32_t INIT_1_END;
@@ -38,19 +37,27 @@ extern uint32_t INIT_5_END;
extern uint32_t INIT_6_END;
extern uint32_t INIT_7_END;
-extern uint32_t WAT;
-
-#define MAGIC_COOKIE 0xDEADBEEF
-/* Test that data segment is properly set. */
-static uint32_t magic_cookie = MAGIC_COOKIE;
+extern uint32_t INIT_0_START;
+extern uint32_t INIT_1_START;
+extern uint32_t INIT_2_START;
+extern uint32_t INIT_3_START;
+extern uint32_t INIT_4_START;
+extern uint32_t INIT_5_START;
+extern uint32_t INIT_6_START;
+extern uint32_t INIT_7_START;
+
+extern uint32_t VECTORS_START;
+extern uint32_t VECTORS_END;
+extern uint32_t TEXT_START;
+extern uint32_t TEXT_END;
-void panic(const char*);
+extern uint32_t FLASH_STOP;
init2()
{
volatile uint32_t bss_start_ptr = (uint32_t)&BSS_START;
volatile uint32_t bss_end_ptr = (uint32_t)&BSS_END;
- volatile uint32_t init_data_values_ptr = (uint32_t)&INIT_DATA_VALUES;
+ volatile uint32_t init_data_values_ptr = (uint32_t)&DATA_VALUES_IN_FLASH;
volatile uint32_t data_segment_start_ptr = (uint32_t)&DATA_SEGMENT_START;
volatile uint32_t data_segment_stop_ptr = (uint32_t)&DATA_SEGMENT_STOP;
@@ -58,7 +65,7 @@ init2()
klogf(" .data ...\n");
klogf(" set (%p - %p)\n", &DATA_SEGMENT_START, &DATA_SEGMENT_STOP);
- klogf(" from (%p)\n", &INIT_DATA_VALUES);
+ klogf(" from (%p)\n", &DATA_VALUES_IN_FLASH);
if ((data_segment_start_ptr | data_segment_start_ptr) & 3) {
panic(".data segment not aligned with sizeof(uint32_t)!\n");
@@ -72,7 +79,7 @@ init2()
uint32_t* src;
uint32_t* dest;
- src = &INIT_DATA_VALUES;
+ src = &DATA_VALUES_IN_FLASH;
dest = &DATA_SEGMENT_START;
/* Copy the values from flash into the data segment. */
@@ -94,11 +101,6 @@ init2()
*(dest++) = 0;
}
- if (magic_cookie != MAGIC_COOKIE) {
- panic("Data Segment Initialization Failed!");
- }
-
- klogf("Magic Cookie Matches!\n");
klogf("Done!\n");
}
@@ -106,11 +108,23 @@ init3()
{
/* Set the vector offset table to be at the start
* of FLASH memory. */
- SCB.vto_r = 0x08000000;
+ SCB.vto_r = (uint32_t) &VECTORS_START;
+
+ klogf("Vector offset table set to %p\n", &VECTORS_START);
}
void run_init_routines()
{
+ void* init_starts[] = {
+ &INIT_0_START,
+ &INIT_1_START,
+ &INIT_2_START,
+ &INIT_3_START,
+ &INIT_4_START,
+ &INIT_5_START,
+ &INIT_6_START,
+ &INIT_7_START,
+ };
void* init_boundaries[] = {
&INIT_0_END,
&INIT_1_END,
@@ -124,55 +138,40 @@ void run_init_routines()
void (**initfn)();
- klogf("WAT: %p\n", &WAT);
+ klogf(".vectors:\n at (%p - %p)\n", &VECTORS_START, &VECTORS_END);
+ klogf(".text:\n at (%p - %p)\n", &TEXT_START, &TEXT_END);
- klogf(
- "Init routines at (%p - %p)\n",
- &INIT_ROUTINES_FLASH_START,
- &INIT_ROUTINES_FLASH_STOP);
+ klogf("inits: (%p - %p)\n", &INITS_START, &INIT_7_END);
+
+ for (size_t i = 0; i < 8; ++i) {
+ klogf(".init%d\n at (%p - %p)\n", i, init_starts[i], init_boundaries[i]);
+ }
klogf(
- "Data segment at (%p - %p) from (%p)\n",
+ ".data:\n at (%p - %p)\n from (%p)\n",
&DATA_SEGMENT_START,
&DATA_SEGMENT_STOP,
- &INIT_DATA_VALUES);
+ &DATA_VALUES_IN_FLASH);
klogf(
- "Bss segment at (%p - %p)\n",
- &BSS_START,
- &BSS_END);
-
- klogf(
- "Heap at (%p - %p)\n",
+ ".heap:\n at (%p - %p) size %d bytes\n",
&HEAP_START,
- &HEAP_STOP);
-
- klogf(
- "Text at (%p - %p)\n",
- &TEXT_START,
- &TEXT_STOP);
-
- klogf( "Init Boundary 0: %p\n", &INIT_0_END);
- klogf( "Init Boundary 1: %p\n", &INIT_1_END);
- klogf( "Init Boundary 2: %p\n", &INIT_2_END);
+ &HEAP_STOP,
+ (uint32_t)(&HEAP_STOP - &HEAP_START));
- // for (size_t i = 0; i < sizeof(init_boundaries) / sizeof(void*); ++ i) {
- // klogf("Init Boundary %d at %p\n", i, init_boundaries[i]);
- // }
+ klogf(".bss:\n at (%p - %p)\n", &BSS_START, &BSS_END);
/* Enable a higher clock speed. This is the first thing we do
* beacuse it will boost the boot up time. */
set_system_clock_MHz(80);
klogf("[Init Level 0]\n");
- for (initfn = &INIT_ROUTINES_FLASH_START; initfn < &INIT_ROUTINES_FLASH_STOP;
- ++initfn) {
+ for (initfn = &INITS_START; initfn < &INITS_END; ++initfn) {
while (initfn >= init_boundaries[initlevel] && initlevel < INIT_LEVEL_7) {
++initlevel;
klogf("[Init Level %d]\n", initlevel);
}
- klogf("Calling (%p)\n", initfn);
(*initfn)();
}
}
diff --git a/src/kern/main.c b/src/kern/main.c
index 61e60c9..7c0b65d 100644
--- a/src/kern/main.c
+++ b/src/kern/main.c
@@ -35,7 +35,7 @@ volatile struct {
signed int timetick;
ws2812b_t* drv;
uint8_t brightness;
- uint8_t n_leds;
+ uint16_t n_leds;
uint8_t off;
uint8_t n_snow;
uint8_t n_red;
@@ -201,7 +201,8 @@ static void reset_state()
memset((void*)&state, 0, sizeof(state));
state.drv = tmp;
state.brightness = 255;
- state.n_leds = 250;
+ state.n_leds = 300;
+ state.n_red = 100;
state.off = 8;
state.timetick = 10;
state.power = 1;
@@ -211,52 +212,60 @@ static void reset_state()
/* Main function. This gets executed from the interrupt vector defined above. */
int main()
{
- klogf("Entering Main (%p).\n", main);
-
- // systick_add_callback(on_systick, NULL);
- // enable_systick(10000);
- // configure_gpio();
-
- // ir_begin_listen();
- // enable_ir_control();
-
- // add_ir_code_callback(RC_HIGH, printit, "RC_HIGH");
- // add_ir_code_callback(RC_TEMP_UP, timetick_up, NULL);
- // add_ir_code_callback(RC_DRY, set_red, NULL);
- // add_ir_code_callback(RC_LOW, printit, "RC_LOW");
- // add_ir_code_callback(RC_TEMP_DOWN, timetick_down, NULL);
- // add_ir_code_callback(RC_COOL, toggle_cool, NULL);
- // add_ir_code_callback(RC_CONTINUOUS, set_snow, "RC_CONTINUOUS");
- // add_ir_code_callback(RC_FAN, toggle_brightness, NULL);
- // add_ir_code_callback(RC_SLEEP, toggle_sleep, NULL);
- // add_ir_code_callback(RC_UNITS, printit, "RC_UNITS");
- // add_ir_code_callback(RC_TIMER, reset_state, NULL);
- // add_ir_code_callback(RC_POWER, toggle_power, NULL);
-
- // int ec;
- // state.drv = ws2812b_new(SPI_SELECT_SPI1, &ec);
-
- // if (ec || !state.drv) {
- // panic("Unable to create WS2812b driver :( (%d)\n", ec);
- // }
-
- // reset_state();
-
- // for (int i = 0; i < state.n_leds; ++i) {
- // /* Clear the LED strip. */
- // disable_all_interrupts();
- // ws2812b_write_rgb_sync(state.drv, 0, 0, 0);
- // enable_all_interrupts();
- // }
- // ws2812b_latch(state.drv);
-
- // for (;;) {
- // // while (!do_redraw)
- // // ;
- // // do_redraw = 0;
- // if (!state.sleep) redraw();
- // }
- for (;;);
+ klogf("Entering Main\n");
+
+ gpio_reserved_pin_t pin3 = get_sysled();
+
+ systick_add_callback(on_systick, NULL);
+ enable_systick(10000);
+ configure_gpio();
+
+ ir_begin_listen();
+ enable_ir_control();
+
+ add_ir_code_callback(RC_HIGH, printit, "RC_HIGH");
+ add_ir_code_callback(RC_TEMP_UP, timetick_up, NULL);
+ add_ir_code_callback(RC_DRY, set_red, NULL);
+ add_ir_code_callback(RC_LOW, printit, "RC_LOW");
+ add_ir_code_callback(RC_TEMP_DOWN, timetick_down, NULL);
+ add_ir_code_callback(RC_COOL, toggle_cool, NULL);
+ add_ir_code_callback(RC_CONTINUOUS, set_snow, "RC_CONTINUOUS");
+ add_ir_code_callback(RC_FAN, toggle_brightness, NULL);
+ add_ir_code_callback(RC_SLEEP, toggle_sleep, NULL);
+ add_ir_code_callback(RC_UNITS, printit, "RC_UNITS");
+ add_ir_code_callback(RC_TIMER, reset_state, NULL);
+ add_ir_code_callback(RC_POWER, toggle_power, NULL);
+
+ int ec;
+ state.drv = ws2812b_new(SPI_SELECT_SPI1, &ec);
+
+ if (ec || !state.drv) {
+ panic("Unable to create WS2812b driver :( (%d)\n", ec);
+ }
+
+ reset_state();
+
+ for (int i = 0; i < state.n_leds; ++i) {
+ /* Clear the LED strip. */
+ disable_all_interrupts();
+ ws2812b_write_rgb_sync(state.drv, 0, 0, 0);
+ enable_all_interrupts();
+ }
+ ws2812b_latch(state.drv);
+
+ for (int i = 0; ; ++ i) {
+ if (i % 64 == 0) {
+ set_gpio_pin_high(pin3);
+ }
+ // while (!do_redraw)
+ // ;
+ // do_redraw = 0;
+ if (!state.sleep) redraw();
+
+ if (i % 64 == 0) {
+ set_gpio_pin_low(pin3);
+ }
+ }
}
#endif