]> code.bitgloo.com Git - clyne/calculator.git/commitdiff
initrd, lcd, file cleanup
authorClyne Sullivan <tullivan99@gmail.com>
Thu, 4 Jan 2018 16:47:43 +0000 (11:47 -0500)
committerClyne Sullivan <tullivan99@gmail.com>
Thu, 4 Jan 2018 16:47:43 +0000 (11:47 -0500)
28 files changed:
Makefile
README.md
clock.c [deleted file]
heap.c [deleted file]
include/gpio.h [new file with mode: 0644]
include/initrd.h [new file with mode: 0644]
include/lcd.h [new file with mode: 0644]
initrd/test.txt [new file with mode: 0644]
initrd/two.bin [new file with mode: 0644]
lib/liblua.a [new file with mode: 0644]
link.ld
main.c [deleted file]
mkinitrd.sh [new file with mode: 0755]
src/clock.c [new file with mode: 0644]
src/gpio.c [new file with mode: 0644]
src/heap.c [new file with mode: 0644]
src/initrd.c [new file with mode: 0644]
src/lcd.c [new file with mode: 0644]
src/main.c [new file with mode: 0644]
src/startup_stm32l476xx.s [new file with mode: 0644]
src/stdlib.c [new file with mode: 0644]
src/stm32l4xx_it.c [new file with mode: 0644]
src/system_stm32l4xx.c [new file with mode: 0644]
src/task.c [new file with mode: 0644]
startup_stm32l476xx.s [deleted file]
stm32l4xx_it.c [deleted file]
system_stm32l4xx.c [deleted file]
task.c [deleted file]

index 48175ff0fb1c518fd086d852aee74670289d1484..87dd3a0906f0b2b1613cd108871403b58f592717 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,16 +1,44 @@
+CROSS = arm-none-eabi-
+CC = gcc
+AS = as
+AR = ar
+OBJCOPY = objcopy
+
 MCUFLAGS = -mthumb -mcpu=cortex-m4
-CFLAGS = -Iinclude $(MCUFLAGS)
-
-all:
-       arm-none-eabi-as $(MCUFLAGS) startup_stm32l476xx.s -c -o out/startup_stm32l476xx.o
-       arm-none-eabi-gcc $(CFLAGS) system_stm32l4xx.c -c -o out/system_stm32l4xx.o
-       arm-none-eabi-gcc $(CFLAGS) stm32l4xx_it.c -c -o out/stm32l4xx_it.o
-       arm-none-eabi-gcc $(CFLAGS) clock.c -c -o out/clock.o
-       arm-none-eabi-gcc $(CFLAGS) heap.c -c -o out/heap.o
-       arm-none-eabi-gcc $(CFLAGS) task.c -c -o out/task.o
-       arm-none-eabi-gcc $(CFLAGS) main.c -c -o out/main.o
-       arm-none-eabi-gcc $(CFLAGS) -T link.ld out/*.o -o out/main.elf
-       arm-none-eabi-objcopy -O ihex out/main.elf main.hex
+AFLAGS = $(MCUFLAGS) 
+CFLAGS = $(MCUFLAGS) -Iinclude -ffreestanding -Wall -Werror -Wextra
+OFLAGS = -O ihex
+
+CFILES = $(wildcard src/*.c)
+AFILES = $(wildcard src/*.s) 
+
+OUTDIR = out
+OFILES = $(patsubst src/%.c, $(OUTDIR)/%.o, $(CFILES)) \
+        $(patsubst src/%.s, $(OUTDIR)/%.asm.o, $(AFILES))
+
+LIBDIR = -Llib
+LIBS = -llua
+
+HEX = main.hex
+
+all: $(HEX)
+
+$(HEX): $(OFILES)
+       @echo "  LINK   " $(HEX)
+       @$(CROSS)$(OBJCOPY) -B arm -I binary -O elf32-littlearm initrd.img out/initrd.img.o
+       @$(CROSS)$(CC) $(CFLAGS) $(LIBDIR) $(LIBS) -T link.ld out/*.o -o out/main.elf
+       @$(CROSS)$(OBJCOPY) $(OFLAGS) out/main.elf $(HEX)
+
+$(OUTDIR)/%.o: src/%.c
+       @echo "  CC     " $<
+       @$(CROSS)$(CC) $(CFLAGS) -c $< -o $@
+
+$(OUTDIR)/%.asm.o: src/%.s
+       @echo "  AS     " $<
+       @$(CROSS)$(AS) $(AFLAGS) -c $< -o $@
 
 clean:
-       rm -rf out/*
+       @echo "  CLEAN"
+       @rm -rf out/*
+
+
index 56c56fd481bcdfa309add8d96140a3c601be3c18..f2e4a048523ec50287121d91a9a2108d03df935e 100644 (file)
--- a/README.md
+++ b/README.md
@@ -8,4 +8,6 @@ Required packages:
 * openocd
 * make
   
-Use run.sh to upload the final output to the processor.
+Use ```run.sh``` to upload the final output to the processor.  
+  
+To make an initrd, add files to ```initrd/``` and then run ```./mkinitrd.sh```.
diff --git a/clock.c b/clock.c
deleted file mode 100644 (file)
index ab92386..0000000
--- a/clock.c
+++ /dev/null
@@ -1,62 +0,0 @@
-#include <clock.h>
-#include <stm32l476xx.h>
-
-#define STK_CTRL       *((uint32_t *)0xE000E010)
-#define STK_LOAD       *((uint32_t *)0xE000E014)
-#define STK_VAL                *((uint32_t *)0xE000E018)
-#define STK_CALIB      *((uint32_t *)0xE000E01C)
-
-// ticks since init
-static uint32_t ticks = 0;
-
-void clock_init(void)
-{
-       // turn on HSI (16MHz)
-       RCC->CR |= RCC_CR_HSION;
-       while ((RCC->CR & RCC_CR_HSIRDY) != RCC_CR_HSIRDY);
-
-       // get PLLR to 80MHz (max)
-       // VCO = C * (N/M) -> 16 * (10/1) = 160
-       // SCLK = VCO / R = 160 / 2 = 80 MHz
-       RCC->PLLCFGR &= ~(RCC_PLLCFGR_PLLSRC);
-       RCC->PLLCFGR |= RCC_PLLCFGR_PLLSRC_HSI;
-       RCC->PLLCFGR &= ~(RCC_PLLCFGR_PLLN | RCC_PLLCFGR_PLLM);
-       RCC->PLLCFGR |= 10 << RCC_PLLCFGR_PLLN_Pos;
-       RCC->PLLCFGR &= ~(RCC_PLLCFGR_PLLR);    // /2
-       RCC->PLLCFGR |= RCC_PLLCFGR_PLLREN;             // PLLR on
-
-       // start PLL
-       RCC->CR |= RCC_CR_PLLON;
-       while ((RCC->CR & RCC_CR_PLLRDY) != RCC_CR_PLLRDY);
-
-       // set system clock to PLL
-       RCC->CFGR &= ~(RCC_CFGR_SW);
-       RCC->CFGR |= RCC_CFGR_SW_PLL;
-       while ((RCC->CFGR & RCC_CFGR_SWS_PLL) != RCC_CFGR_SWS_PLL);
-
-       // SysTick init. 80MHz / 80000 = 1kHz, ms precision
-       STK_LOAD = 80000;
-       STK_CTRL |= 0x07; // no div, interrupt, enable
-}
-
-void delay(uint32_t count)
-{
-       uint32_t target = ticks + count;
-       while (ticks < target);
-}
-
-__attribute__ ((naked))
-void SysTick_Handler(void)
-{
-       uint32_t lr;
-       asm("mov %0, lr" : "=r" (lr));
-
-       // just keep counting
-       ticks++;
-
-       if (!(ticks % 10))
-               SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk;
-
-       asm("mov lr, %0; bx lr" :: "r" (lr));
-}
-
diff --git a/heap.c b/heap.c
deleted file mode 100644 (file)
index 0433a1f..0000000
--- a/heap.c
+++ /dev/null
@@ -1,38 +0,0 @@
-#include <heap.h>
-#include <stm32l476xx.h>
-
-#define RAM_END 0x20018000
-
-//extern void *end;
-//extern uint32_t _total_ram;
-static uint32_t offset = 0;
-
-__attribute__ ((section(".data")))
-uint8_t heap[8192];
-void *end = heap;
-
-void heap_init(void)
-{
-       // what to do...
-}
-
-uint32_t heap_available(void)
-{
-       return 0;//     return _total_ram - offset;
-}
-
-void *hmalloc(uint32_t size)
-{
-       void *alloc = end + offset;
-       offset += size;
-       return alloc;
-}
-
-void *hcalloc(uint32_t count, uint32_t size)
-{
-       uint32_t total = count * size;
-       void *alloc = hmalloc(total);
-       for (uint32_t i = 0; i < total; i++)
-               ((uint8_t *)alloc)[i] = 0;
-       return alloc;
-}
diff --git a/include/gpio.h b/include/gpio.h
new file mode 100644 (file)
index 0000000..25b32fe
--- /dev/null
@@ -0,0 +1,45 @@
+#ifndef GPIO_H_
+#define GPIO_H_
+
+#include <stm32l476xx.h>
+
+#define GPIO_PORT(p, b) GPIO##p, b
+
+enum GPIO_MODE
+{
+       INPUT = 0,
+       OUTPUT,
+       ALTERNATE,
+       ANALOG
+};
+
+enum GPIO_TYPE
+{
+       PUSHPULL = 0,
+       OPENDRAIN
+};
+
+enum GPIO_SPEED
+{
+       LOW = 0,
+       MEDIUM,
+       HIGH,
+       VERYHIGH
+};
+
+enum GPIO_PUPD
+{
+       NOPUPD,
+       PULLUP,
+       PULLDOWN
+};
+
+void gpio_init(void);
+
+void gpio_pupd(GPIO_TypeDef *port, uint8_t pin, uint8_t pupd);
+void gpio_type(GPIO_TypeDef *port, uint8_t pin, uint8_t type);
+void gpio_mode(GPIO_TypeDef *port, uint8_t pin, uint8_t mode);
+void gpio_dout(GPIO_TypeDef *port, uint8_t pin, uint8_t val);
+uint8_t gpio_din(GPIO_TypeDef *port, uint8_t pin);
+
+#endif // GPIO_H_
diff --git a/include/initrd.h b/include/initrd.h
new file mode 100644 (file)
index 0000000..9c7a9de
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef INITRD_H_
+#define INITRD_H_
+
+#include <stdint.h>
+
+typedef struct
+{
+       char signature[8];
+} __attribute__ ((packed)) initrd_header;
+
+typedef struct 
+{
+       char name[16];
+       uint8_t unused[32];
+       char size[10];
+       char sig[2];
+} __attribute__ ((packed)) initrd_file;
+
+uint8_t initrd_validate(void);
+char *initrd_getfile(const char *name);
+uint32_t initrd_getfilesize(const char *name);
+
+#endif // INITRD_H_
diff --git a/include/lcd.h b/include/lcd.h
new file mode 100644 (file)
index 0000000..0962e08
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef LCD_H_
+#define LCD_H_
+
+#include <stdint.h>
+
+void lcd_init(void);
+
+void lcd_puts(const char *s);
+void lcd_puti(int i);
+void lcd_puth(int h);
+void lcd_putb(uint8_t b);
+void lcd_clear(void);
+
+#endif // LCD_H_
diff --git a/initrd/test.txt b/initrd/test.txt
new file mode 100644 (file)
index 0000000..af5626b
--- /dev/null
@@ -0,0 +1 @@
+Hello, world!
diff --git a/initrd/two.bin b/initrd/two.bin
new file mode 100644 (file)
index 0000000..b3f1928
--- /dev/null
@@ -0,0 +1,3 @@
+print "yay"
+
+yesyesye
diff --git a/lib/liblua.a b/lib/liblua.a
new file mode 100644 (file)
index 0000000..d5a4c6b
Binary files /dev/null and b/lib/liblua.a differ
diff --git a/link.ld b/link.ld
index 8877898f6b5ab44f34e252c635f255340ee51300..13e5ccadb3c4645804eee3c7e48155ed25823aed 100644 (file)
--- a/link.ld
+++ b/link.ld
@@ -35,9 +35,6 @@ ENTRY(Reset_Handler)
 /* Highest address of the user mode stack */\r
 _estack = 0x20018000;    /* end of RAM */\r
 \r
-_Min_Stack_Size = 0x0400; /* 1k min. stack */\r
-_Min_Heap_Size = 0x0400; /* 1k min. heap */\r
-\r
 /* Specify the memory areas */\r
 MEMORY\r
 {\r
@@ -82,14 +79,14 @@ SECTIONS
     . = ALIGN(8);\r
   } >FLASH\r
 \r
-  .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH\r
+  .ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH\r
   .ARM : {\r
     __exidx_start = .;\r
     *(.ARM.exidx*)\r
     __exidx_end = .;\r
   } >FLASH\r
 \r
-  .preinit_array     :\r
+  .preinit_array :\r
   {\r
     PROVIDE_HIDDEN (__preinit_array_start = .);\r
     KEEP (*(.preinit_array*))\r
@@ -146,10 +143,7 @@ SECTIONS
   ._user_heap_stack :\r
   {\r
     . = ALIGN(4);\r
-    PROVIDE ( end = . );\r
-    PROVIDE ( _end = . );\r
-    . = . + _Min_Heap_Size;\r
-    . = . + _Min_Stack_Size;\r
+    *(._user_heap_stack)\r
     . = ALIGN(4);\r
   } >RAM\r
 \r
@@ -166,4 +160,3 @@ SECTIONS
   .ARM.attributes 0 : { *(.ARM.attributes) }\r
 }\r
 \r
-_total_ram = _estack - _end;\r
diff --git a/main.c b/main.c
deleted file mode 100644 (file)
index 9a95465..0000000
--- a/main.c
+++ /dev/null
@@ -1,75 +0,0 @@
-#include <stm32l476xx.h>\r
-#include <clock.h>\r
-#include <heap.h>\r
-#include <task.h>\r
-\r
-/**\r
- * Accomplishments:\r
- *   - GPIO in/out\r
- *   - got to 80MHz clock\r
- *   - basic heap\r
- *   - multitask, can exit\r
- */\r
-\r
-void pulse(uint8_t byte);\r
-void kmain(void);\r
-\r
-int main(void)\r
-{\r
-       asm("cpsid i");\r
-\r
-       // prepare flash latency for 40MHz operation\r
-       FLASH->ACR &= ~(FLASH_ACR_LATENCY);\r
-       FLASH->ACR |= FLASH_ACR_LATENCY_4WS;\r
-\r
-       RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN;    // A clk enable\r
-       GPIOA->MODER &= ~(GPIO_MODER_MODE5 | GPIO_MODER_MODE6); // A5 -> output, A0 input\r
-       GPIOA->MODER |= GPIO_MODER_MODE5_0 | GPIO_MODER_MODE6_0;\r
-       GPIOA->PUPDR &= ~(GPIO_PUPDR_PUPD5 | GPIO_PUPDR_PUPD6);\r
-       GPIOA->PUPDR |= GPIO_PUPDR_PUPD5_0 | GPIO_PUPDR_PUPD6_0; // pulldown for button (1)\r
-       //if (GPIOA->IDR & 0x01)\r
-\r
-       clock_init();\r
-       task_init(kmain);\r
-\r
-       while (1);\r
-}\r
-\r
-void task(void);\r
-void kmain(void)\r
-{\r
-       asm("cpsie i");\r
-\r
-       task_start(task, 1024);\r
-       while (1) {\r
-               GPIOA->BSRR |= 1 << 6;\r
-               delay(500);\r
-               GPIOA->BRR |= 1 << 6;\r
-               delay(500);\r
-       }\r
-}\r
-\r
-void task(void)\r
-{\r
-       while (1) {\r
-               GPIOA->BSRR |= 1 << 5;\r
-               delay(200);\r
-               GPIOA->BRR |= 1 << 5;\r
-               delay(200);\r
-       }\r
-}\r
-\r
-\r
-void _exit(int code)\r
-{ for (;;); }\r
-\r
-void pulse(uint8_t byte)\r
-{\r
-       int8_t i = 7;\r
-       do {\r
-               GPIOA->BSRR |= 1 << 5;\r
-               delay((byte & (1 << i)) ? 400 : 100);\r
-               GPIOA->BRR |= 1 << 5;\r
-               delay((byte & (1 << i)) ? 100 : 400);\r
-       } while (--i >= 0);\r
-}\r
diff --git a/mkinitrd.sh b/mkinitrd.sh
new file mode 100755 (executable)
index 0000000..eb47fd8
--- /dev/null
@@ -0,0 +1,4 @@
+#!/bin/bash
+echo "Making initrd.img..."
+rm -f initrd.img
+arm-none-eabi-ar r initrd.img initrd/*
diff --git a/src/clock.c b/src/clock.c
new file mode 100644 (file)
index 0000000..ab92386
--- /dev/null
@@ -0,0 +1,62 @@
+#include <clock.h>
+#include <stm32l476xx.h>
+
+#define STK_CTRL       *((uint32_t *)0xE000E010)
+#define STK_LOAD       *((uint32_t *)0xE000E014)
+#define STK_VAL                *((uint32_t *)0xE000E018)
+#define STK_CALIB      *((uint32_t *)0xE000E01C)
+
+// ticks since init
+static uint32_t ticks = 0;
+
+void clock_init(void)
+{
+       // turn on HSI (16MHz)
+       RCC->CR |= RCC_CR_HSION;
+       while ((RCC->CR & RCC_CR_HSIRDY) != RCC_CR_HSIRDY);
+
+       // get PLLR to 80MHz (max)
+       // VCO = C * (N/M) -> 16 * (10/1) = 160
+       // SCLK = VCO / R = 160 / 2 = 80 MHz
+       RCC->PLLCFGR &= ~(RCC_PLLCFGR_PLLSRC);
+       RCC->PLLCFGR |= RCC_PLLCFGR_PLLSRC_HSI;
+       RCC->PLLCFGR &= ~(RCC_PLLCFGR_PLLN | RCC_PLLCFGR_PLLM);
+       RCC->PLLCFGR |= 10 << RCC_PLLCFGR_PLLN_Pos;
+       RCC->PLLCFGR &= ~(RCC_PLLCFGR_PLLR);    // /2
+       RCC->PLLCFGR |= RCC_PLLCFGR_PLLREN;             // PLLR on
+
+       // start PLL
+       RCC->CR |= RCC_CR_PLLON;
+       while ((RCC->CR & RCC_CR_PLLRDY) != RCC_CR_PLLRDY);
+
+       // set system clock to PLL
+       RCC->CFGR &= ~(RCC_CFGR_SW);
+       RCC->CFGR |= RCC_CFGR_SW_PLL;
+       while ((RCC->CFGR & RCC_CFGR_SWS_PLL) != RCC_CFGR_SWS_PLL);
+
+       // SysTick init. 80MHz / 80000 = 1kHz, ms precision
+       STK_LOAD = 80000;
+       STK_CTRL |= 0x07; // no div, interrupt, enable
+}
+
+void delay(uint32_t count)
+{
+       uint32_t target = ticks + count;
+       while (ticks < target);
+}
+
+__attribute__ ((naked))
+void SysTick_Handler(void)
+{
+       uint32_t lr;
+       asm("mov %0, lr" : "=r" (lr));
+
+       // just keep counting
+       ticks++;
+
+       if (!(ticks % 10))
+               SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk;
+
+       asm("mov lr, %0; bx lr" :: "r" (lr));
+}
+
diff --git a/src/gpio.c b/src/gpio.c
new file mode 100644 (file)
index 0000000..c2617ee
--- /dev/null
@@ -0,0 +1,44 @@
+#include <gpio.h>
+
+void gpio_init(void)
+{
+       // enable clocks
+       RCC->AHB2ENR |= 0xFF;
+}
+
+void gpio_pupd(GPIO_TypeDef *port, uint8_t pin, uint8_t pupd)
+{
+       port->PUPDR &= ~(0x03 << (2 * pin));
+       port->PUPDR |= pupd << (2 * pin);
+}
+
+void gpio_speed(GPIO_TypeDef *port, uint8_t pin, uint8_t speed)
+{
+       port->OSPEEDR &= ~(0x03 << (2 * pin));
+       port->OSPEEDR |= speed << (2 * pin);
+}
+
+void gpio_type(GPIO_TypeDef *port, uint8_t pin, uint8_t type)
+{
+       port->OTYPER &= ~(1 << pin);
+       port->OTYPER |= type << pin;
+}
+
+void gpio_mode(GPIO_TypeDef *port, uint8_t pin, uint8_t mode)
+{
+       port->MODER &= ~(0x03 << (2 * pin));
+       port->MODER |= mode << (2 * pin);
+}
+
+void gpio_dout(GPIO_TypeDef *port, uint8_t pin, uint8_t val)
+{
+       if (val)
+               port->BSRR |= (1 << pin);
+       else
+               port->BRR |= (1 << pin);
+}
+
+uint8_t gpio_din(GPIO_TypeDef *port, uint8_t pin)
+{
+       return port->IDR & (1 << pin);
+}
diff --git a/src/heap.c b/src/heap.c
new file mode 100644 (file)
index 0000000..1eba901
--- /dev/null
@@ -0,0 +1,38 @@
+#include <heap.h>
+#include <stm32l476xx.h>
+
+#define RAM_END 0x20018000
+
+#define HEAP_SIZE (16 * 1024)
+
+static uint32_t offset = 0;
+
+__attribute__ ((section("._user_heap_stack")))
+uint8_t heap[HEAP_SIZE];
+void *end = heap;
+
+void heap_init(void)
+{
+       // what to do...
+}
+
+uint32_t heap_available(void)
+{
+       return HEAP_SIZE - offset;
+}
+
+void *hmalloc(uint32_t size)
+{
+       void *alloc = end + offset;
+       offset += size;
+       return alloc;
+}
+
+void *hcalloc(uint32_t count, uint32_t size)
+{
+       uint32_t total = count * size;
+       void *alloc = hmalloc(total);
+       for (uint32_t i = 0; i < total; i++)
+               ((uint8_t *)alloc)[i] = 0;
+       return alloc;
+}
diff --git a/src/initrd.c b/src/initrd.c
new file mode 100644 (file)
index 0000000..7b68c40
--- /dev/null
@@ -0,0 +1,90 @@
+#include <initrd.h>
+
+extern uint8_t _binary_initrd_img_start[];
+extern uint8_t _binary_initrd_img_size[];
+
+static const void *initrd_start = (void *)_binary_initrd_img_start;
+static const uint32_t initrd_size = (uint32_t)_binary_initrd_img_size;
+
+static const char *initrd_sig = "!<arch>\n";
+
+uint8_t initrd_validate(void)
+{
+       initrd_header *header = (initrd_header *)initrd_start;
+       for (uint8_t i = 0; i < 8; i++) {
+               if (header->signature[i] != initrd_sig[i])
+                       return 0;
+       }
+
+       return 1;
+}
+
+uint8_t initrd_nametest(char *file, const char *want)
+{
+       for (uint8_t i = 0; i < 16; i++) {
+               if (want[i] == '\0')
+                       return (file[i] == '/');
+               else if (want[i] != file[i])
+                       return 0;
+       }
+
+       return 0;
+}
+
+uint32_t pow10(uint8_t n)
+{
+       uint32_t i = 1;
+       while (n--)
+               i *= 10;
+       return i;
+}
+
+uint32_t initrd_getsize(initrd_file *file)
+{
+       uint32_t size = 0;
+       char *p = file->size + 10;
+       while (*--p == ' ');
+
+       for (int8_t i = p - file->size, j = 0; i >= 0; i--, j++)
+               size += (*p-- - '0') * pow10(j);
+
+       return size;
+}
+
+initrd_file *initrd_getfileptr(const char *name)
+{
+       initrd_file *file = (initrd_file *)(initrd_start + sizeof(initrd_header));
+       uint32_t offset = sizeof(initrd_header);
+
+       while (offset < initrd_size) {
+               if (initrd_nametest(file->name, name))
+                       return file;
+               uint32_t size = initrd_getsize(file) + sizeof(initrd_file);
+               offset += size;
+               file += size;
+       }
+
+       return 0;
+}
+
+char *initrd_getfile(const char *name)
+{
+       initrd_file *file = initrd_getfileptr(name);
+       if (file == 0)
+               return 0;
+
+
+       char *ptr = (char *)((void *)file + sizeof(initrd_file));
+       ptr[initrd_getsize(file) - 1] = 0;
+       return ptr;
+}
+
+uint32_t initrd_getfilesize(const char *name)
+{
+       initrd_file *file = initrd_getfileptr(name);
+       if (file == 0)
+               return 0;
+
+       return initrd_getsize(file);
+}
+
diff --git a/src/lcd.c b/src/lcd.c
new file mode 100644 (file)
index 0000000..ca1c1a6
--- /dev/null
+++ b/src/lcd.c
@@ -0,0 +1,117 @@
+#include <lcd.h>
+#include <clock.h>
+#include <gpio.h>
+
+#define LCD_D0 GPIO_PORT(A, 0)
+#define LCD_D1 GPIO_PORT(A, 1)
+#define LCD_D2 GPIO_PORT(A, 4)
+#define LCD_D3 GPIO_PORT(B, 0)
+#define LCD_D4 GPIO_PORT(C, 1)
+#define LCD_D5 GPIO_PORT(C, 0)
+#define LCD_D6 GPIO_PORT(C, 2)
+#define LCD_D7 GPIO_PORT(C, 3)
+#define LCD_E  GPIO_PORT(C, 12)
+#define LCD_RS GPIO_PORT(C, 10)
+
+#define lcd_data() gpio_dout(LCD_RS, 1)
+
+void lcd_pulse(void)
+{
+       gpio_dout(LCD_E, 1);
+       delay(1);
+       gpio_dout(LCD_E, 0);
+}
+
+void lcd_byte(uint8_t byte)
+{
+       gpio_dout(LCD_D0, byte & 0x01);
+       gpio_dout(LCD_D1, byte & 0x02);
+       gpio_dout(LCD_D2, byte & 0x04);
+       gpio_dout(LCD_D3, byte & 0x08);
+       gpio_dout(LCD_D4, byte & 0x10);
+       gpio_dout(LCD_D5, byte & 0x20);
+       gpio_dout(LCD_D6, byte & 0x40);
+       gpio_dout(LCD_D7, byte & 0x80);
+}
+
+void lcd_cmd(uint8_t cmd)
+{
+       gpio_dout(LCD_RS, 0);
+       lcd_byte(cmd);
+       lcd_pulse();
+}
+
+void lcd_putchar(int c)
+{
+       lcd_data();
+       lcd_byte((uint8_t)c);
+       lcd_pulse();
+}
+
+static int lcd_index = 0;
+void lcd_puts(const char *s)
+{
+       lcd_cmd(0x06);
+       while (*s) {
+               lcd_putchar(*s++);
+               if (++lcd_index == 0x10) {
+                       lcd_cmd(0x80 | 0x40);
+               } else if (lcd_index == 0x20) {
+                       lcd_cmd(0x80);
+                       lcd_index = 0;
+               }
+       }
+}
+
+extern char *itoa(int n, int base);
+void lcd_puti(int i)
+{
+       lcd_puts(itoa(i, 10));
+}
+
+void lcd_puth(int h)
+{
+       lcd_puts(itoa(h, 16));
+}
+
+void lcd_putb(uint8_t b)
+{
+       lcd_puts(itoa(b, 2));
+}
+
+void lcd_clear(void)
+{
+       lcd_cmd(0x01);
+       delay(2);
+       lcd_index = 0;
+}
+
+void lcd_init(void)
+{
+       gpio_mode(LCD_D0, OUTPUT);
+       gpio_mode(LCD_D1, OUTPUT);
+       gpio_mode(LCD_D2, OUTPUT);
+       gpio_mode(LCD_D3, OUTPUT);
+       gpio_mode(LCD_D4, OUTPUT);
+       gpio_mode(LCD_D5, OUTPUT);
+       gpio_mode(LCD_D6, OUTPUT);
+       gpio_mode(LCD_D7, OUTPUT);
+       gpio_mode(LCD_E,  OUTPUT);
+       gpio_mode(LCD_RS, OUTPUT);
+       gpio_dout(LCD_D0, 0);
+       gpio_dout(LCD_D1, 0);
+       gpio_dout(LCD_D2, 0);
+       gpio_dout(LCD_D3, 0);
+       gpio_dout(LCD_D4, 0);
+       gpio_dout(LCD_D5, 0);
+       gpio_dout(LCD_D6, 0);
+       gpio_dout(LCD_D7, 0);
+       gpio_dout(LCD_E,  0);
+       gpio_dout(LCD_RS, 0);
+
+       lcd_cmd(0x38);
+       lcd_cmd(0x10);
+       lcd_cmd(0x0D);
+       delay(5);
+       lcd_clear();
+}
diff --git a/src/main.c b/src/main.c
new file mode 100644 (file)
index 0000000..e71e712
--- /dev/null
@@ -0,0 +1,56 @@
+#include <stm32l476xx.h>\r
+#include <clock.h>\r
+#include <heap.h>\r
+#include <task.h>\r
+#include <gpio.h>\r
+#include <lcd.h>\r
+#include <initrd.h>\r
+\r
+/**\r
+ * Accomplishments:\r
+ *   - GPIO in/out\r
+ *   - got to 80MHz clock\r
+ *   - basic heap\r
+ *   - multitask, can exit\r
+ *   - gpio lib\r
+ *   - lcd support\r
+ *   - initrd support\r
+ *   - lua?\r
+ */\r
+\r
+void pulse(uint8_t byte);\r
+void kmain(void);\r
+\r
+int main(void)\r
+{\r
+       asm("cpsid i");\r
+\r
+       // prepare flash latency for 40MHz operation\r
+       FLASH->ACR &= ~(FLASH_ACR_LATENCY);\r
+       FLASH->ACR |= FLASH_ACR_LATENCY_4WS;\r
+\r
+       //MPU->CTRL |= MPU_CTRL_ENABLE_Msk | MPU_CTRL_PRIVDEFENA_Msk;\r
+       clock_init();\r
+       gpio_init();\r
+\r
+       gpio_mode(GPIOA, 5, OUTPUT);\r
+\r
+       task_init(kmain);\r
+\r
+       while (1);\r
+}\r
+\r
+void task(void);\r
+void kmain(void)\r
+{\r
+       asm("cpsie i");\r
+\r
+       lcd_init();\r
+\r
+       char *s = initrd_getfile("test.txt");\r
+       lcd_puts(s);\r
+\r
+       while (1)\r
+               delay(100);\r
+}\r
+\r
diff --git a/src/startup_stm32l476xx.s b/src/startup_stm32l476xx.s
new file mode 100644 (file)
index 0000000..57b11cb
--- /dev/null
@@ -0,0 +1,524 @@
+/**\r
+  ******************************************************************************\r
+  * @file      startup_stm32l476xx.s\r
+  * @author    MCD Application Team\r
+  * @brief     STM32L476xx devices vector table GCC toolchain.\r
+  *            This module performs:\r
+  *                - Set the initial SP\r
+  *                - Set the initial PC == Reset_Handler,\r
+  *                - Set the vector table entries with the exceptions ISR address,\r
+  *                - Configure the clock system  \r
+  *                - Branches to main in the C library (which eventually\r
+  *                  calls main()).\r
+  *            After Reset the Cortex-M4 processor is in Thread mode,\r
+  *            priority is Privileged, and the Stack is set to Main.\r
+  ******************************************************************************\r
+  * @attention\r
+  *\r
+  * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>\r
+  *\r
+  * Redistribution and use in source and binary forms, with or without modification,\r
+  * are permitted provided that the following conditions are met:\r
+  *   1. Redistributions of source code must retain the above copyright notice,\r
+  *      this list of conditions and the following disclaimer.\r
+  *   2. Redistributions in binary form must reproduce the above copyright notice,\r
+  *      this list of conditions and the following disclaimer in the documentation\r
+  *      and/or other materials provided with the distribution.\r
+  *   3. Neither the name of STMicroelectronics nor the names of its contributors\r
+  *      may be used to endorse or promote products derived from this software\r
+  *      without specific prior written permission.\r
+  *\r
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\r
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\r
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\r
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+  *\r
+  ******************************************************************************\r
+  */\r
+\r
+  .syntax unified\r
+       .cpu cortex-m4\r
+       .fpu softvfp\r
+       .thumb\r
+\r
+.global        g_pfnVectors\r
+.global        Default_Handler\r
+\r
+/* start address for the initialization values of the .data section.\r
+defined in linker script */\r
+.word  _sidata\r
+/* start address for the .data section. defined in linker script */\r
+.word  _sdata\r
+/* end address for the .data section. defined in linker script */\r
+.word  _edata\r
+/* start address for the .bss section. defined in linker script */\r
+.word  _sbss\r
+/* end address for the .bss section. defined in linker script */\r
+.word  _ebss\r
+\r
+//.equ  BootRAM,        0xF1E0F85F\r
+/**\r
+ * @brief  This is the code that gets called when the processor first\r
+ *          starts execution following a reset event. Only the absolutely\r
+ *          necessary set is performed, after which the application\r
+ *          supplied main() routine is called.\r
+ * @param  None\r
+ * @retval : None\r
+*/\r
+\r
+    .section   .text.Reset_Handler\r
+       .weak   Reset_Handler\r
+       .type   Reset_Handler, %function\r
+Reset_Handler:\r
+  ldr   sp, =_estack    /* Atollic update: set stack pointer */\r
+\r
+/* Copy the data segment initializers from flash to SRAM */\r
+  movs r1, #0\r
+  b    LoopCopyDataInit\r
+\r
+CopyDataInit:\r
+       ldr     r3, =_sidata\r
+       ldr     r3, [r3, r1]\r
+       str     r3, [r0, r1]\r
+       adds    r1, r1, #4\r
+\r
+LoopCopyDataInit:\r
+       ldr     r0, =_sdata\r
+       ldr     r3, =_edata\r
+       adds    r2, r0, r1\r
+       cmp     r2, r3\r
+       bcc     CopyDataInit\r
+       ldr     r2, =_sbss\r
+       b       LoopFillZerobss\r
+/* Zero fill the bss segment. */\r
+FillZerobss:\r
+       movs    r3, #0\r
+       str     r3, [r2], #4\r
+\r
+LoopFillZerobss:\r
+       ldr     r3, = _ebss\r
+       cmp     r2, r3\r
+       bcc     FillZerobss\r
+\r
+/* Call the clock system intitialization function.*/\r
+    bl  SystemInit\r
+/* Call static constructors */\r
+    bl __libc_init_array\r
+/* Call the application's entry point.*/\r
+       bl      main\r
+\r
+LoopForever:\r
+    b LoopForever\r
+    \r
+.size  Reset_Handler, .-Reset_Handler\r
+\r
+/**\r
+ * @brief  This is the code that gets called when the processor receives an\r
+ *         unexpected interrupt.  This simply enters an infinite loop, preserving\r
+ *         the system state for examination by a debugger.\r
+ *\r
+ * @param  None\r
+ * @retval : None\r
+*/\r
+    .section   .text.Default_Handler,"ax",%progbits\r
+Default_Handler:\r
+Infinite_Loop:\r
+       b       Infinite_Loop\r
+       .size   Default_Handler, .-Default_Handler\r
+/******************************************************************************\r
+*\r
+* The minimal vector table for a Cortex-M4.  Note that the proper constructs\r
+* must be placed on this to ensure that it ends up at physical address\r
+* 0x0000.0000.\r
+*\r
+******************************************************************************/\r
+       .section        .isr_vector,"a",%progbits\r
+       .type   g_pfnVectors, %object\r
+       .size   g_pfnVectors, .-g_pfnVectors\r
+\r
+\r
+g_pfnVectors:\r
+       .word   _estack\r
+       .word   Reset_Handler\r
+       .word   NMI_Handler\r
+       .word   HardFault_Handler\r
+       .word   MemManage_Handler\r
+       .word   BusFault_Handler\r
+       .word   UsageFault_Handler\r
+       .word   0\r
+       .word   0\r
+       .word   0\r
+       .word   0\r
+       .word   SVC_Handler\r
+       .word   DebugMon_Handler\r
+       .word   0\r
+       .word   PendSV_Handler\r
+       .word   SysTick_Handler\r
+       .word   WWDG_IRQHandler\r
+       .word   PVD_PVM_IRQHandler\r
+       .word   TAMP_STAMP_IRQHandler\r
+       .word   RTC_WKUP_IRQHandler\r
+       .word   FLASH_IRQHandler\r
+       .word   RCC_IRQHandler\r
+       .word   EXTI0_IRQHandler\r
+       .word   EXTI1_IRQHandler\r
+       .word   EXTI2_IRQHandler\r
+       .word   EXTI3_IRQHandler\r
+       .word   EXTI4_IRQHandler\r
+       .word   DMA1_Channel1_IRQHandler\r
+       .word   DMA1_Channel2_IRQHandler\r
+       .word   DMA1_Channel3_IRQHandler\r
+       .word   DMA1_Channel4_IRQHandler\r
+       .word   DMA1_Channel5_IRQHandler\r
+       .word   DMA1_Channel6_IRQHandler\r
+       .word   DMA1_Channel7_IRQHandler\r
+       .word   ADC1_2_IRQHandler\r
+       .word   CAN1_TX_IRQHandler\r
+       .word   CAN1_RX0_IRQHandler\r
+       .word   CAN1_RX1_IRQHandler\r
+       .word   CAN1_SCE_IRQHandler\r
+       .word   EXTI9_5_IRQHandler\r
+       .word   TIM1_BRK_TIM15_IRQHandler\r
+       .word   TIM1_UP_TIM16_IRQHandler\r
+       .word   TIM1_TRG_COM_TIM17_IRQHandler\r
+       .word   TIM1_CC_IRQHandler\r
+       .word   TIM2_IRQHandler\r
+       .word   TIM3_IRQHandler\r
+       .word   TIM4_IRQHandler\r
+       .word   I2C1_EV_IRQHandler\r
+       .word   I2C1_ER_IRQHandler\r
+       .word   I2C2_EV_IRQHandler\r
+       .word   I2C2_ER_IRQHandler\r
+       .word   SPI1_IRQHandler\r
+       .word   SPI2_IRQHandler\r
+       .word   USART1_IRQHandler\r
+       .word   USART2_IRQHandler\r
+       .word   USART3_IRQHandler\r
+       .word   EXTI15_10_IRQHandler\r
+       .word   RTC_Alarm_IRQHandler\r
+       .word   DFSDM1_FLT3_IRQHandler\r
+       .word   TIM8_BRK_IRQHandler\r
+       .word   TIM8_UP_IRQHandler\r
+       .word   TIM8_TRG_COM_IRQHandler\r
+       .word   TIM8_CC_IRQHandler\r
+       .word   ADC3_IRQHandler\r
+       .word   FMC_IRQHandler\r
+       .word   SDMMC1_IRQHandler\r
+       .word   TIM5_IRQHandler\r
+       .word   SPI3_IRQHandler\r
+       .word   UART4_IRQHandler\r
+       .word   UART5_IRQHandler\r
+       .word   TIM6_DAC_IRQHandler\r
+       .word   TIM7_IRQHandler\r
+       .word   DMA2_Channel1_IRQHandler\r
+       .word   DMA2_Channel2_IRQHandler\r
+       .word   DMA2_Channel3_IRQHandler\r
+       .word   DMA2_Channel4_IRQHandler\r
+       .word   DMA2_Channel5_IRQHandler\r
+       .word   DFSDM1_FLT0_IRQHandler\r
+       .word   DFSDM1_FLT1_IRQHandler\r
+       .word   DFSDM1_FLT2_IRQHandler\r
+       .word   COMP_IRQHandler\r
+       .word   LPTIM1_IRQHandler\r
+       .word   LPTIM2_IRQHandler\r
+       .word   OTG_FS_IRQHandler\r
+       .word   DMA2_Channel6_IRQHandler\r
+       .word   DMA2_Channel7_IRQHandler\r
+       .word   LPUART1_IRQHandler\r
+       .word   QUADSPI_IRQHandler\r
+       .word   I2C3_EV_IRQHandler\r
+       .word   I2C3_ER_IRQHandler\r
+       .word   SAI1_IRQHandler\r
+       .word   SAI2_IRQHandler\r
+       .word   SWPMI1_IRQHandler\r
+       .word   TSC_IRQHandler\r
+       .word   LCD_IRQHandler\r
+       .word 0\r
+       .word   RNG_IRQHandler\r
+       .word   FPU_IRQHandler\r
+\r
+\r
+/*******************************************************************************\r
+*\r
+* Provide weak aliases for each Exception handler to the Default_Handler.\r
+* As they are weak aliases, any function with the same name will override\r
+* this definition.\r
+*\r
+*******************************************************************************/\r
+\r
+  .weak        NMI_Handler\r
+       .thumb_set NMI_Handler,Default_Handler\r
+\r
+  .weak        HardFault_Handler\r
+       .thumb_set HardFault_Handler,Default_Handler\r
+\r
+  .weak        MemManage_Handler\r
+       .thumb_set MemManage_Handler,Default_Handler\r
+\r
+  .weak        BusFault_Handler\r
+       .thumb_set BusFault_Handler,Default_Handler\r
+\r
+       .weak   UsageFault_Handler\r
+       .thumb_set UsageFault_Handler,Default_Handler\r
+\r
+       .weak   SVC_Handler\r
+       .thumb_set SVC_Handler,Default_Handler\r
+\r
+       .weak   DebugMon_Handler\r
+       .thumb_set DebugMon_Handler,Default_Handler\r
+\r
+       .weak   PendSV_Handler\r
+       .thumb_set PendSV_Handler,Default_Handler\r
+\r
+       .weak   SysTick_Handler\r
+       .thumb_set SysTick_Handler,Default_Handler\r
+\r
+       .weak   WWDG_IRQHandler\r
+       .thumb_set WWDG_IRQHandler,Default_Handler\r
+\r
+       .weak   PVD_PVM_IRQHandler\r
+       .thumb_set PVD_PVM_IRQHandler,Default_Handler\r
+\r
+       .weak   TAMP_STAMP_IRQHandler\r
+       .thumb_set TAMP_STAMP_IRQHandler,Default_Handler\r
+\r
+       .weak   RTC_WKUP_IRQHandler\r
+       .thumb_set RTC_WKUP_IRQHandler,Default_Handler\r
+\r
+       .weak   FLASH_IRQHandler\r
+       .thumb_set FLASH_IRQHandler,Default_Handler\r
+\r
+       .weak   RCC_IRQHandler\r
+       .thumb_set RCC_IRQHandler,Default_Handler\r
+\r
+       .weak   EXTI0_IRQHandler\r
+       .thumb_set EXTI0_IRQHandler,Default_Handler\r
+\r
+       .weak   EXTI1_IRQHandler\r
+       .thumb_set EXTI1_IRQHandler,Default_Handler\r
+\r
+       .weak   EXTI2_IRQHandler\r
+       .thumb_set EXTI2_IRQHandler,Default_Handler\r
+\r
+       .weak   EXTI3_IRQHandler\r
+       .thumb_set EXTI3_IRQHandler,Default_Handler\r
+\r
+       .weak   EXTI4_IRQHandler\r
+       .thumb_set EXTI4_IRQHandler,Default_Handler\r
+\r
+       .weak   DMA1_Channel1_IRQHandler\r
+       .thumb_set DMA1_Channel1_IRQHandler,Default_Handler\r
+\r
+       .weak   DMA1_Channel2_IRQHandler\r
+       .thumb_set DMA1_Channel2_IRQHandler,Default_Handler\r
+\r
+       .weak   DMA1_Channel3_IRQHandler\r
+       .thumb_set DMA1_Channel3_IRQHandler,Default_Handler\r
+\r
+       .weak   DMA1_Channel4_IRQHandler\r
+       .thumb_set DMA1_Channel4_IRQHandler,Default_Handler\r
+\r
+       .weak   DMA1_Channel5_IRQHandler\r
+       .thumb_set DMA1_Channel5_IRQHandler,Default_Handler\r
+\r
+       .weak   DMA1_Channel6_IRQHandler\r
+       .thumb_set DMA1_Channel6_IRQHandler,Default_Handler\r
+\r
+       .weak   DMA1_Channel7_IRQHandler\r
+       .thumb_set DMA1_Channel7_IRQHandler,Default_Handler\r
+\r
+       .weak   ADC1_2_IRQHandler\r
+       .thumb_set ADC1_2_IRQHandler,Default_Handler\r
+\r
+       .weak   CAN1_TX_IRQHandler\r
+       .thumb_set CAN1_TX_IRQHandler,Default_Handler\r
+\r
+       .weak   CAN1_RX0_IRQHandler\r
+       .thumb_set CAN1_RX0_IRQHandler,Default_Handler\r
+\r
+       .weak   CAN1_RX1_IRQHandler\r
+       .thumb_set CAN1_RX1_IRQHandler,Default_Handler\r
+\r
+       .weak   CAN1_SCE_IRQHandler\r
+       .thumb_set CAN1_SCE_IRQHandler,Default_Handler\r
+\r
+       .weak   EXTI9_5_IRQHandler\r
+       .thumb_set EXTI9_5_IRQHandler,Default_Handler\r
+\r
+       .weak   TIM1_BRK_TIM15_IRQHandler\r
+       .thumb_set TIM1_BRK_TIM15_IRQHandler,Default_Handler\r
+\r
+       .weak   TIM1_UP_TIM16_IRQHandler\r
+       .thumb_set TIM1_UP_TIM16_IRQHandler,Default_Handler\r
+\r
+       .weak   TIM1_TRG_COM_TIM17_IRQHandler\r
+       .thumb_set TIM1_TRG_COM_TIM17_IRQHandler,Default_Handler\r
+\r
+       .weak   TIM1_CC_IRQHandler\r
+       .thumb_set TIM1_CC_IRQHandler,Default_Handler\r
+\r
+       .weak   TIM2_IRQHandler\r
+       .thumb_set TIM2_IRQHandler,Default_Handler\r
+\r
+       .weak   TIM3_IRQHandler\r
+       .thumb_set TIM3_IRQHandler,Default_Handler\r
+\r
+       .weak   TIM4_IRQHandler\r
+       .thumb_set TIM4_IRQHandler,Default_Handler\r
+\r
+       .weak   I2C1_EV_IRQHandler\r
+       .thumb_set I2C1_EV_IRQHandler,Default_Handler\r
+\r
+       .weak   I2C1_ER_IRQHandler\r
+       .thumb_set I2C1_ER_IRQHandler,Default_Handler\r
+\r
+       .weak   I2C2_EV_IRQHandler\r
+       .thumb_set I2C2_EV_IRQHandler,Default_Handler\r
+\r
+       .weak   I2C2_ER_IRQHandler\r
+       .thumb_set I2C2_ER_IRQHandler,Default_Handler\r
+\r
+       .weak   SPI1_IRQHandler\r
+       .thumb_set SPI1_IRQHandler,Default_Handler\r
+\r
+       .weak   SPI2_IRQHandler\r
+       .thumb_set SPI2_IRQHandler,Default_Handler\r
+\r
+       .weak   USART1_IRQHandler\r
+       .thumb_set USART1_IRQHandler,Default_Handler\r
+\r
+       .weak   USART2_IRQHandler\r
+       .thumb_set USART2_IRQHandler,Default_Handler\r
+\r
+       .weak   USART3_IRQHandler\r
+       .thumb_set USART3_IRQHandler,Default_Handler\r
+\r
+       .weak   EXTI15_10_IRQHandler\r
+       .thumb_set EXTI15_10_IRQHandler,Default_Handler\r
+\r
+       .weak   RTC_Alarm_IRQHandler\r
+       .thumb_set RTC_Alarm_IRQHandler,Default_Handler\r
+\r
+       .weak   DFSDM1_FLT3_IRQHandler\r
+       .thumb_set DFSDM1_FLT3_IRQHandler,Default_Handler\r
+\r
+       .weak   TIM8_BRK_IRQHandler\r
+       .thumb_set TIM8_BRK_IRQHandler,Default_Handler\r
+\r
+       .weak   TIM8_UP_IRQHandler\r
+       .thumb_set TIM8_UP_IRQHandler,Default_Handler\r
+\r
+       .weak   TIM8_TRG_COM_IRQHandler\r
+       .thumb_set TIM8_TRG_COM_IRQHandler,Default_Handler\r
+\r
+       .weak   TIM8_CC_IRQHandler\r
+       .thumb_set TIM8_CC_IRQHandler,Default_Handler\r
+\r
+       .weak   ADC3_IRQHandler\r
+       .thumb_set ADC3_IRQHandler,Default_Handler\r
+\r
+       .weak   FMC_IRQHandler\r
+       .thumb_set FMC_IRQHandler,Default_Handler\r
+\r
+       .weak   SDMMC1_IRQHandler\r
+       .thumb_set SDMMC1_IRQHandler,Default_Handler\r
+\r
+       .weak   TIM5_IRQHandler\r
+       .thumb_set TIM5_IRQHandler,Default_Handler\r
+\r
+       .weak   SPI3_IRQHandler\r
+       .thumb_set SPI3_IRQHandler,Default_Handler\r
+\r
+       .weak   UART4_IRQHandler\r
+       .thumb_set UART4_IRQHandler,Default_Handler\r
+\r
+       .weak   UART5_IRQHandler\r
+       .thumb_set UART5_IRQHandler,Default_Handler\r
+\r
+       .weak   TIM6_DAC_IRQHandler\r
+       .thumb_set TIM6_DAC_IRQHandler,Default_Handler\r
+\r
+       .weak   TIM7_IRQHandler\r
+       .thumb_set TIM7_IRQHandler,Default_Handler\r
+\r
+       .weak   DMA2_Channel1_IRQHandler\r
+       .thumb_set DMA2_Channel1_IRQHandler,Default_Handler\r
+\r
+       .weak   DMA2_Channel2_IRQHandler\r
+       .thumb_set DMA2_Channel2_IRQHandler,Default_Handler\r
+\r
+       .weak   DMA2_Channel3_IRQHandler\r
+       .thumb_set DMA2_Channel3_IRQHandler,Default_Handler\r
+\r
+       .weak   DMA2_Channel4_IRQHandler\r
+       .thumb_set DMA2_Channel4_IRQHandler,Default_Handler\r
+\r
+       .weak   DMA2_Channel5_IRQHandler\r
+       .thumb_set DMA2_Channel5_IRQHandler,Default_Handler\r
+\r
+       .weak   DFSDM1_FLT0_IRQHandler\r
+       .thumb_set DFSDM1_FLT0_IRQHandler,Default_Handler       \r
+       \r
+       .weak   DFSDM1_FLT1_IRQHandler\r
+       .thumb_set DFSDM1_FLT1_IRQHandler,Default_Handler       \r
+       \r
+       .weak   DFSDM1_FLT2_IRQHandler\r
+       .thumb_set DFSDM1_FLT2_IRQHandler,Default_Handler       \r
+       \r
+       .weak   COMP_IRQHandler\r
+       .thumb_set COMP_IRQHandler,Default_Handler\r
+       \r
+       .weak   LPTIM1_IRQHandler\r
+       .thumb_set LPTIM1_IRQHandler,Default_Handler\r
+       \r
+       .weak   LPTIM2_IRQHandler\r
+       .thumb_set LPTIM2_IRQHandler,Default_Handler    \r
+       \r
+       .weak   OTG_FS_IRQHandler\r
+       .thumb_set OTG_FS_IRQHandler,Default_Handler    \r
+       \r
+       .weak   DMA2_Channel6_IRQHandler\r
+       .thumb_set DMA2_Channel6_IRQHandler,Default_Handler     \r
+       \r
+       .weak   DMA2_Channel7_IRQHandler\r
+       .thumb_set DMA2_Channel7_IRQHandler,Default_Handler     \r
+       \r
+       .weak   LPUART1_IRQHandler\r
+       .thumb_set LPUART1_IRQHandler,Default_Handler   \r
+       \r
+       .weak   QUADSPI_IRQHandler\r
+       .thumb_set QUADSPI_IRQHandler,Default_Handler   \r
+       \r
+       .weak   I2C3_EV_IRQHandler\r
+       .thumb_set I2C3_EV_IRQHandler,Default_Handler   \r
+       \r
+       .weak   I2C3_ER_IRQHandler\r
+       .thumb_set I2C3_ER_IRQHandler,Default_Handler   \r
+       \r
+       .weak   SAI1_IRQHandler\r
+       .thumb_set SAI1_IRQHandler,Default_Handler\r
+       \r
+       .weak   SAI2_IRQHandler\r
+       .thumb_set SAI2_IRQHandler,Default_Handler\r
+       \r
+       .weak   SWPMI1_IRQHandler\r
+       .thumb_set SWPMI1_IRQHandler,Default_Handler\r
+       \r
+       .weak   TSC_IRQHandler\r
+       .thumb_set TSC_IRQHandler,Default_Handler\r
+       \r
+       .weak   LCD_IRQHandler\r
+       .thumb_set LCD_IRQHandler,Default_Handler\r
+       \r
+       .weak   RNG_IRQHandler\r
+       .thumb_set RNG_IRQHandler,Default_Handler\r
+       \r
+       .weak   FPU_IRQHandler\r
+       .thumb_set FPU_IRQHandler,Default_Handler\r
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/\r
diff --git a/src/stdlib.c b/src/stdlib.c
new file mode 100644 (file)
index 0000000..e7bf622
--- /dev/null
@@ -0,0 +1,17 @@
+#include <stdint.h>
+
+void _exit(int code)
+{
+       (void)code;
+       for (;;);
+}
+
+char *itoa(int n, int base)
+{
+       static char buf[16];
+       char *p = buf + 15;
+       *p = '\0';
+       do *--p = "0123456789ABCDEF"[n % base];
+       while (n /= base);
+       return p;
+}
diff --git a/src/stm32l4xx_it.c b/src/stm32l4xx_it.c
new file mode 100644 (file)
index 0000000..2aac023
--- /dev/null
@@ -0,0 +1,34 @@
+#include <stm32l476xx.h>\r
+\r
+void NMI_Handler(void) {}\r
+\r
+void HardFault_Handler(void)\r
+{\r
+       GPIOA->BSRR |= (1 << 5) | (1 << 6);\r
+       while (1);\r
+}\r
+\r
+void MemManage_Handler(void)\r
+{\r
+       GPIOA->BSRR |= (1 << 5) | (1 << 6);\r
+       while (1);\r
+}\r
+\r
+void BusFault_Handler(void)\r
+{\r
+       GPIOA->BSRR |= (1 << 5) | (1 << 6);\r
+       while (1);\r
+}\r
+\r
+void UsageFault_Handler(void)\r
+{\r
+       GPIOA->BSRR |= (1 << 5) | (1 << 6);\r
+       while (1);\r
+}\r
+\r
+void SVC_Handler(void) {\r
+\r
+}\r
+\r
+void DebugMon_Handler(void) {}\r
+\r
diff --git a/src/system_stm32l4xx.c b/src/system_stm32l4xx.c
new file mode 100644 (file)
index 0000000..4c22bfe
--- /dev/null
@@ -0,0 +1,44 @@
+#include "stm32l476xx.h"\r
+\r
+/************************* Miscellaneous Configuration ************************/\r
+/*!< Uncomment the following line if you need to relocate your vector Table in\r
+     Internal SRAM. */\r
+/* #define VECT_TAB_SRAM */\r
+#define VECT_TAB_OFFSET  0x00 /*!< Vector Table base offset field.\r
+                                   This value must be a multiple of 0x200. */\r
+/******************************************************************************/\r
+\r
+void SystemInit(void)\r
+{\r
+  /* FPU settings ------------------------------------------------------------*/\r
+  #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)\r
+    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */\r
+  #endif\r
+\r
+  /* Reset the RCC clock configuration to the default reset state ------------*/\r
+  /* Set MSION bit */\r
+  RCC->CR |= RCC_CR_MSION;\r
+\r
+  /* Reset CFGR register */\r
+  RCC->CFGR = 0x00000000U;\r
+\r
+  /* Reset HSEON, CSSON , HSION, and PLLON bits */\r
+  RCC->CR &= 0xEAF6FFFFU;\r
+\r
+  /* Reset PLLCFGR register */\r
+  RCC->PLLCFGR = 0x00001000U;\r
+\r
+  /* Reset HSEBYP bit */\r
+  RCC->CR &= 0xFFFBFFFFU;\r
+\r
+  /* Disable all interrupts */\r
+  RCC->CIER = 0x00000000U;\r
+\r
+  /* Configure the Vector Table location add offset address ------------------*/\r
+#ifdef VECT_TAB_SRAM\r
+  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */\r
+#else\r
+  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */\r
+#endif\r
+}\r
+\r
diff --git a/src/task.c b/src/task.c
new file mode 100644 (file)
index 0000000..a34988a
--- /dev/null
@@ -0,0 +1,108 @@
+#include <task.h>
+#include <heap.h>
+#include <stm32l476xx.h>
+
+typedef struct {
+       uint32_t *sp;
+       uint8_t use;
+       uint32_t *stack;
+       void (*code)(void);
+} task_t;
+
+#define MAX_TASKS      4
+
+static task_t tasks[MAX_TASKS];
+static volatile int next_idx = 0;
+
+static uint8_t task_enable = 0;
+
+void task_init(void (*init)(void))
+{
+       for (int i = 0; i < MAX_TASKS; i++)
+               tasks[i].use = 0;
+
+       task_start(init, 1024);
+       asm("\
+               msr psp, %0; \
+               mrs r0, control; \
+               orr r0, r0, #3; \
+               msr control, r0; \
+               isb; \
+       " :: "r" (tasks[0].sp));
+
+       task_enable = 1;
+       init();
+}
+
+extern void _exit(int);
+void task_exit(void)
+{
+       // TODO free stack?
+       asm("cpsid i"); // hope to catch next_idx
+       tasks[next_idx].use = 0;
+       asm("cpsie i");
+       while (1); // bye
+}
+
+void task_start(void (*task)(void), uint16_t stackSize)
+{
+       asm("cpsid i"); // just to be safe
+
+       for (int i = 0; i < MAX_TASKS; i++) {
+               if (tasks[i].use == 0) {
+                       tasks[i].stack = hmalloc(stackSize);
+                       tasks[i].sp = tasks[i].stack + stackSize - 16;
+                       tasks[i].sp[13] = (uint32_t)task_exit;
+                       tasks[i].sp[14] = (uint32_t)task;
+                       tasks[i].sp[15] = 0x01000000;
+                       tasks[i].use = 1;
+                       tasks[i].code = task;
+                       asm("cpsie i");
+                       return;
+               }
+       }
+
+       // TODO handle error
+}
+
+__attribute__ ((naked))
+void PendSV_Handler(void) 
+{
+       if (task_enable == 0)
+               asm("bx lr");
+
+       // save state
+       asm("\
+               cpsid i; \
+               isb; \
+               dsb; \
+               mrs r0, psp; \
+               stmdb r0!, {r4-r11}; \
+               mov %0, r0; \
+       " : "=r" (tasks[next_idx].sp));
+
+       // find next task (round-robin style)
+       do {
+               if (++next_idx == MAX_TASKS) {
+                       next_idx = 0;
+                       break; // task 0 better exist
+               }
+       } while (tasks[next_idx].use == 0);
+
+       // restore
+       asm("\
+               mov r0, %0; \
+               ldmia r0!, {r4-r11}; \
+               msr psp, r0; \
+               isb; \
+               dsb; \
+       " :: "r" (tasks[next_idx].sp));
+
+       // end
+       asm("\
+               mov r0, #0xFFFFFFFD; \
+               cpsie i; \
+               bx r0; \
+       ");
+}
+
diff --git a/startup_stm32l476xx.s b/startup_stm32l476xx.s
deleted file mode 100644 (file)
index 57b11cb..0000000
+++ /dev/null
@@ -1,524 +0,0 @@
-/**\r
-  ******************************************************************************\r
-  * @file      startup_stm32l476xx.s\r
-  * @author    MCD Application Team\r
-  * @brief     STM32L476xx devices vector table GCC toolchain.\r
-  *            This module performs:\r
-  *                - Set the initial SP\r
-  *                - Set the initial PC == Reset_Handler,\r
-  *                - Set the vector table entries with the exceptions ISR address,\r
-  *                - Configure the clock system  \r
-  *                - Branches to main in the C library (which eventually\r
-  *                  calls main()).\r
-  *            After Reset the Cortex-M4 processor is in Thread mode,\r
-  *            priority is Privileged, and the Stack is set to Main.\r
-  ******************************************************************************\r
-  * @attention\r
-  *\r
-  * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>\r
-  *\r
-  * Redistribution and use in source and binary forms, with or without modification,\r
-  * are permitted provided that the following conditions are met:\r
-  *   1. Redistributions of source code must retain the above copyright notice,\r
-  *      this list of conditions and the following disclaimer.\r
-  *   2. Redistributions in binary form must reproduce the above copyright notice,\r
-  *      this list of conditions and the following disclaimer in the documentation\r
-  *      and/or other materials provided with the distribution.\r
-  *   3. Neither the name of STMicroelectronics nor the names of its contributors\r
-  *      may be used to endorse or promote products derived from this software\r
-  *      without specific prior written permission.\r
-  *\r
-  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"\r
-  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
-  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\r
-  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\r
-  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
-  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\r
-  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\r
-  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\r
-  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\r
-  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
-  *\r
-  ******************************************************************************\r
-  */\r
-\r
-  .syntax unified\r
-       .cpu cortex-m4\r
-       .fpu softvfp\r
-       .thumb\r
-\r
-.global        g_pfnVectors\r
-.global        Default_Handler\r
-\r
-/* start address for the initialization values of the .data section.\r
-defined in linker script */\r
-.word  _sidata\r
-/* start address for the .data section. defined in linker script */\r
-.word  _sdata\r
-/* end address for the .data section. defined in linker script */\r
-.word  _edata\r
-/* start address for the .bss section. defined in linker script */\r
-.word  _sbss\r
-/* end address for the .bss section. defined in linker script */\r
-.word  _ebss\r
-\r
-//.equ  BootRAM,        0xF1E0F85F\r
-/**\r
- * @brief  This is the code that gets called when the processor first\r
- *          starts execution following a reset event. Only the absolutely\r
- *          necessary set is performed, after which the application\r
- *          supplied main() routine is called.\r
- * @param  None\r
- * @retval : None\r
-*/\r
-\r
-    .section   .text.Reset_Handler\r
-       .weak   Reset_Handler\r
-       .type   Reset_Handler, %function\r
-Reset_Handler:\r
-  ldr   sp, =_estack    /* Atollic update: set stack pointer */\r
-\r
-/* Copy the data segment initializers from flash to SRAM */\r
-  movs r1, #0\r
-  b    LoopCopyDataInit\r
-\r
-CopyDataInit:\r
-       ldr     r3, =_sidata\r
-       ldr     r3, [r3, r1]\r
-       str     r3, [r0, r1]\r
-       adds    r1, r1, #4\r
-\r
-LoopCopyDataInit:\r
-       ldr     r0, =_sdata\r
-       ldr     r3, =_edata\r
-       adds    r2, r0, r1\r
-       cmp     r2, r3\r
-       bcc     CopyDataInit\r
-       ldr     r2, =_sbss\r
-       b       LoopFillZerobss\r
-/* Zero fill the bss segment. */\r
-FillZerobss:\r
-       movs    r3, #0\r
-       str     r3, [r2], #4\r
-\r
-LoopFillZerobss:\r
-       ldr     r3, = _ebss\r
-       cmp     r2, r3\r
-       bcc     FillZerobss\r
-\r
-/* Call the clock system intitialization function.*/\r
-    bl  SystemInit\r
-/* Call static constructors */\r
-    bl __libc_init_array\r
-/* Call the application's entry point.*/\r
-       bl      main\r
-\r
-LoopForever:\r
-    b LoopForever\r
-    \r
-.size  Reset_Handler, .-Reset_Handler\r
-\r
-/**\r
- * @brief  This is the code that gets called when the processor receives an\r
- *         unexpected interrupt.  This simply enters an infinite loop, preserving\r
- *         the system state for examination by a debugger.\r
- *\r
- * @param  None\r
- * @retval : None\r
-*/\r
-    .section   .text.Default_Handler,"ax",%progbits\r
-Default_Handler:\r
-Infinite_Loop:\r
-       b       Infinite_Loop\r
-       .size   Default_Handler, .-Default_Handler\r
-/******************************************************************************\r
-*\r
-* The minimal vector table for a Cortex-M4.  Note that the proper constructs\r
-* must be placed on this to ensure that it ends up at physical address\r
-* 0x0000.0000.\r
-*\r
-******************************************************************************/\r
-       .section        .isr_vector,"a",%progbits\r
-       .type   g_pfnVectors, %object\r
-       .size   g_pfnVectors, .-g_pfnVectors\r
-\r
-\r
-g_pfnVectors:\r
-       .word   _estack\r
-       .word   Reset_Handler\r
-       .word   NMI_Handler\r
-       .word   HardFault_Handler\r
-       .word   MemManage_Handler\r
-       .word   BusFault_Handler\r
-       .word   UsageFault_Handler\r
-       .word   0\r
-       .word   0\r
-       .word   0\r
-       .word   0\r
-       .word   SVC_Handler\r
-       .word   DebugMon_Handler\r
-       .word   0\r
-       .word   PendSV_Handler\r
-       .word   SysTick_Handler\r
-       .word   WWDG_IRQHandler\r
-       .word   PVD_PVM_IRQHandler\r
-       .word   TAMP_STAMP_IRQHandler\r
-       .word   RTC_WKUP_IRQHandler\r
-       .word   FLASH_IRQHandler\r
-       .word   RCC_IRQHandler\r
-       .word   EXTI0_IRQHandler\r
-       .word   EXTI1_IRQHandler\r
-       .word   EXTI2_IRQHandler\r
-       .word   EXTI3_IRQHandler\r
-       .word   EXTI4_IRQHandler\r
-       .word   DMA1_Channel1_IRQHandler\r
-       .word   DMA1_Channel2_IRQHandler\r
-       .word   DMA1_Channel3_IRQHandler\r
-       .word   DMA1_Channel4_IRQHandler\r
-       .word   DMA1_Channel5_IRQHandler\r
-       .word   DMA1_Channel6_IRQHandler\r
-       .word   DMA1_Channel7_IRQHandler\r
-       .word   ADC1_2_IRQHandler\r
-       .word   CAN1_TX_IRQHandler\r
-       .word   CAN1_RX0_IRQHandler\r
-       .word   CAN1_RX1_IRQHandler\r
-       .word   CAN1_SCE_IRQHandler\r
-       .word   EXTI9_5_IRQHandler\r
-       .word   TIM1_BRK_TIM15_IRQHandler\r
-       .word   TIM1_UP_TIM16_IRQHandler\r
-       .word   TIM1_TRG_COM_TIM17_IRQHandler\r
-       .word   TIM1_CC_IRQHandler\r
-       .word   TIM2_IRQHandler\r
-       .word   TIM3_IRQHandler\r
-       .word   TIM4_IRQHandler\r
-       .word   I2C1_EV_IRQHandler\r
-       .word   I2C1_ER_IRQHandler\r
-       .word   I2C2_EV_IRQHandler\r
-       .word   I2C2_ER_IRQHandler\r
-       .word   SPI1_IRQHandler\r
-       .word   SPI2_IRQHandler\r
-       .word   USART1_IRQHandler\r
-       .word   USART2_IRQHandler\r
-       .word   USART3_IRQHandler\r
-       .word   EXTI15_10_IRQHandler\r
-       .word   RTC_Alarm_IRQHandler\r
-       .word   DFSDM1_FLT3_IRQHandler\r
-       .word   TIM8_BRK_IRQHandler\r
-       .word   TIM8_UP_IRQHandler\r
-       .word   TIM8_TRG_COM_IRQHandler\r
-       .word   TIM8_CC_IRQHandler\r
-       .word   ADC3_IRQHandler\r
-       .word   FMC_IRQHandler\r
-       .word   SDMMC1_IRQHandler\r
-       .word   TIM5_IRQHandler\r
-       .word   SPI3_IRQHandler\r
-       .word   UART4_IRQHandler\r
-       .word   UART5_IRQHandler\r
-       .word   TIM6_DAC_IRQHandler\r
-       .word   TIM7_IRQHandler\r
-       .word   DMA2_Channel1_IRQHandler\r
-       .word   DMA2_Channel2_IRQHandler\r
-       .word   DMA2_Channel3_IRQHandler\r
-       .word   DMA2_Channel4_IRQHandler\r
-       .word   DMA2_Channel5_IRQHandler\r
-       .word   DFSDM1_FLT0_IRQHandler\r
-       .word   DFSDM1_FLT1_IRQHandler\r
-       .word   DFSDM1_FLT2_IRQHandler\r
-       .word   COMP_IRQHandler\r
-       .word   LPTIM1_IRQHandler\r
-       .word   LPTIM2_IRQHandler\r
-       .word   OTG_FS_IRQHandler\r
-       .word   DMA2_Channel6_IRQHandler\r
-       .word   DMA2_Channel7_IRQHandler\r
-       .word   LPUART1_IRQHandler\r
-       .word   QUADSPI_IRQHandler\r
-       .word   I2C3_EV_IRQHandler\r
-       .word   I2C3_ER_IRQHandler\r
-       .word   SAI1_IRQHandler\r
-       .word   SAI2_IRQHandler\r
-       .word   SWPMI1_IRQHandler\r
-       .word   TSC_IRQHandler\r
-       .word   LCD_IRQHandler\r
-       .word 0\r
-       .word   RNG_IRQHandler\r
-       .word   FPU_IRQHandler\r
-\r
-\r
-/*******************************************************************************\r
-*\r
-* Provide weak aliases for each Exception handler to the Default_Handler.\r
-* As they are weak aliases, any function with the same name will override\r
-* this definition.\r
-*\r
-*******************************************************************************/\r
-\r
-  .weak        NMI_Handler\r
-       .thumb_set NMI_Handler,Default_Handler\r
-\r
-  .weak        HardFault_Handler\r
-       .thumb_set HardFault_Handler,Default_Handler\r
-\r
-  .weak        MemManage_Handler\r
-       .thumb_set MemManage_Handler,Default_Handler\r
-\r
-  .weak        BusFault_Handler\r
-       .thumb_set BusFault_Handler,Default_Handler\r
-\r
-       .weak   UsageFault_Handler\r
-       .thumb_set UsageFault_Handler,Default_Handler\r
-\r
-       .weak   SVC_Handler\r
-       .thumb_set SVC_Handler,Default_Handler\r
-\r
-       .weak   DebugMon_Handler\r
-       .thumb_set DebugMon_Handler,Default_Handler\r
-\r
-       .weak   PendSV_Handler\r
-       .thumb_set PendSV_Handler,Default_Handler\r
-\r
-       .weak   SysTick_Handler\r
-       .thumb_set SysTick_Handler,Default_Handler\r
-\r
-       .weak   WWDG_IRQHandler\r
-       .thumb_set WWDG_IRQHandler,Default_Handler\r
-\r
-       .weak   PVD_PVM_IRQHandler\r
-       .thumb_set PVD_PVM_IRQHandler,Default_Handler\r
-\r
-       .weak   TAMP_STAMP_IRQHandler\r
-       .thumb_set TAMP_STAMP_IRQHandler,Default_Handler\r
-\r
-       .weak   RTC_WKUP_IRQHandler\r
-       .thumb_set RTC_WKUP_IRQHandler,Default_Handler\r
-\r
-       .weak   FLASH_IRQHandler\r
-       .thumb_set FLASH_IRQHandler,Default_Handler\r
-\r
-       .weak   RCC_IRQHandler\r
-       .thumb_set RCC_IRQHandler,Default_Handler\r
-\r
-       .weak   EXTI0_IRQHandler\r
-       .thumb_set EXTI0_IRQHandler,Default_Handler\r
-\r
-       .weak   EXTI1_IRQHandler\r
-       .thumb_set EXTI1_IRQHandler,Default_Handler\r
-\r
-       .weak   EXTI2_IRQHandler\r
-       .thumb_set EXTI2_IRQHandler,Default_Handler\r
-\r
-       .weak   EXTI3_IRQHandler\r
-       .thumb_set EXTI3_IRQHandler,Default_Handler\r
-\r
-       .weak   EXTI4_IRQHandler\r
-       .thumb_set EXTI4_IRQHandler,Default_Handler\r
-\r
-       .weak   DMA1_Channel1_IRQHandler\r
-       .thumb_set DMA1_Channel1_IRQHandler,Default_Handler\r
-\r
-       .weak   DMA1_Channel2_IRQHandler\r
-       .thumb_set DMA1_Channel2_IRQHandler,Default_Handler\r
-\r
-       .weak   DMA1_Channel3_IRQHandler\r
-       .thumb_set DMA1_Channel3_IRQHandler,Default_Handler\r
-\r
-       .weak   DMA1_Channel4_IRQHandler\r
-       .thumb_set DMA1_Channel4_IRQHandler,Default_Handler\r
-\r
-       .weak   DMA1_Channel5_IRQHandler\r
-       .thumb_set DMA1_Channel5_IRQHandler,Default_Handler\r
-\r
-       .weak   DMA1_Channel6_IRQHandler\r
-       .thumb_set DMA1_Channel6_IRQHandler,Default_Handler\r
-\r
-       .weak   DMA1_Channel7_IRQHandler\r
-       .thumb_set DMA1_Channel7_IRQHandler,Default_Handler\r
-\r
-       .weak   ADC1_2_IRQHandler\r
-       .thumb_set ADC1_2_IRQHandler,Default_Handler\r
-\r
-       .weak   CAN1_TX_IRQHandler\r
-       .thumb_set CAN1_TX_IRQHandler,Default_Handler\r
-\r
-       .weak   CAN1_RX0_IRQHandler\r
-       .thumb_set CAN1_RX0_IRQHandler,Default_Handler\r
-\r
-       .weak   CAN1_RX1_IRQHandler\r
-       .thumb_set CAN1_RX1_IRQHandler,Default_Handler\r
-\r
-       .weak   CAN1_SCE_IRQHandler\r
-       .thumb_set CAN1_SCE_IRQHandler,Default_Handler\r
-\r
-       .weak   EXTI9_5_IRQHandler\r
-       .thumb_set EXTI9_5_IRQHandler,Default_Handler\r
-\r
-       .weak   TIM1_BRK_TIM15_IRQHandler\r
-       .thumb_set TIM1_BRK_TIM15_IRQHandler,Default_Handler\r
-\r
-       .weak   TIM1_UP_TIM16_IRQHandler\r
-       .thumb_set TIM1_UP_TIM16_IRQHandler,Default_Handler\r
-\r
-       .weak   TIM1_TRG_COM_TIM17_IRQHandler\r
-       .thumb_set TIM1_TRG_COM_TIM17_IRQHandler,Default_Handler\r
-\r
-       .weak   TIM1_CC_IRQHandler\r
-       .thumb_set TIM1_CC_IRQHandler,Default_Handler\r
-\r
-       .weak   TIM2_IRQHandler\r
-       .thumb_set TIM2_IRQHandler,Default_Handler\r
-\r
-       .weak   TIM3_IRQHandler\r
-       .thumb_set TIM3_IRQHandler,Default_Handler\r
-\r
-       .weak   TIM4_IRQHandler\r
-       .thumb_set TIM4_IRQHandler,Default_Handler\r
-\r
-       .weak   I2C1_EV_IRQHandler\r
-       .thumb_set I2C1_EV_IRQHandler,Default_Handler\r
-\r
-       .weak   I2C1_ER_IRQHandler\r
-       .thumb_set I2C1_ER_IRQHandler,Default_Handler\r
-\r
-       .weak   I2C2_EV_IRQHandler\r
-       .thumb_set I2C2_EV_IRQHandler,Default_Handler\r
-\r
-       .weak   I2C2_ER_IRQHandler\r
-       .thumb_set I2C2_ER_IRQHandler,Default_Handler\r
-\r
-       .weak   SPI1_IRQHandler\r
-       .thumb_set SPI1_IRQHandler,Default_Handler\r
-\r
-       .weak   SPI2_IRQHandler\r
-       .thumb_set SPI2_IRQHandler,Default_Handler\r
-\r
-       .weak   USART1_IRQHandler\r
-       .thumb_set USART1_IRQHandler,Default_Handler\r
-\r
-       .weak   USART2_IRQHandler\r
-       .thumb_set USART2_IRQHandler,Default_Handler\r
-\r
-       .weak   USART3_IRQHandler\r
-       .thumb_set USART3_IRQHandler,Default_Handler\r
-\r
-       .weak   EXTI15_10_IRQHandler\r
-       .thumb_set EXTI15_10_IRQHandler,Default_Handler\r
-\r
-       .weak   RTC_Alarm_IRQHandler\r
-       .thumb_set RTC_Alarm_IRQHandler,Default_Handler\r
-\r
-       .weak   DFSDM1_FLT3_IRQHandler\r
-       .thumb_set DFSDM1_FLT3_IRQHandler,Default_Handler\r
-\r
-       .weak   TIM8_BRK_IRQHandler\r
-       .thumb_set TIM8_BRK_IRQHandler,Default_Handler\r
-\r
-       .weak   TIM8_UP_IRQHandler\r
-       .thumb_set TIM8_UP_IRQHandler,Default_Handler\r
-\r
-       .weak   TIM8_TRG_COM_IRQHandler\r
-       .thumb_set TIM8_TRG_COM_IRQHandler,Default_Handler\r
-\r
-       .weak   TIM8_CC_IRQHandler\r
-       .thumb_set TIM8_CC_IRQHandler,Default_Handler\r
-\r
-       .weak   ADC3_IRQHandler\r
-       .thumb_set ADC3_IRQHandler,Default_Handler\r
-\r
-       .weak   FMC_IRQHandler\r
-       .thumb_set FMC_IRQHandler,Default_Handler\r
-\r
-       .weak   SDMMC1_IRQHandler\r
-       .thumb_set SDMMC1_IRQHandler,Default_Handler\r
-\r
-       .weak   TIM5_IRQHandler\r
-       .thumb_set TIM5_IRQHandler,Default_Handler\r
-\r
-       .weak   SPI3_IRQHandler\r
-       .thumb_set SPI3_IRQHandler,Default_Handler\r
-\r
-       .weak   UART4_IRQHandler\r
-       .thumb_set UART4_IRQHandler,Default_Handler\r
-\r
-       .weak   UART5_IRQHandler\r
-       .thumb_set UART5_IRQHandler,Default_Handler\r
-\r
-       .weak   TIM6_DAC_IRQHandler\r
-       .thumb_set TIM6_DAC_IRQHandler,Default_Handler\r
-\r
-       .weak   TIM7_IRQHandler\r
-       .thumb_set TIM7_IRQHandler,Default_Handler\r
-\r
-       .weak   DMA2_Channel1_IRQHandler\r
-       .thumb_set DMA2_Channel1_IRQHandler,Default_Handler\r
-\r
-       .weak   DMA2_Channel2_IRQHandler\r
-       .thumb_set DMA2_Channel2_IRQHandler,Default_Handler\r
-\r
-       .weak   DMA2_Channel3_IRQHandler\r
-       .thumb_set DMA2_Channel3_IRQHandler,Default_Handler\r
-\r
-       .weak   DMA2_Channel4_IRQHandler\r
-       .thumb_set DMA2_Channel4_IRQHandler,Default_Handler\r
-\r
-       .weak   DMA2_Channel5_IRQHandler\r
-       .thumb_set DMA2_Channel5_IRQHandler,Default_Handler\r
-\r
-       .weak   DFSDM1_FLT0_IRQHandler\r
-       .thumb_set DFSDM1_FLT0_IRQHandler,Default_Handler       \r
-       \r
-       .weak   DFSDM1_FLT1_IRQHandler\r
-       .thumb_set DFSDM1_FLT1_IRQHandler,Default_Handler       \r
-       \r
-       .weak   DFSDM1_FLT2_IRQHandler\r
-       .thumb_set DFSDM1_FLT2_IRQHandler,Default_Handler       \r
-       \r
-       .weak   COMP_IRQHandler\r
-       .thumb_set COMP_IRQHandler,Default_Handler\r
-       \r
-       .weak   LPTIM1_IRQHandler\r
-       .thumb_set LPTIM1_IRQHandler,Default_Handler\r
-       \r
-       .weak   LPTIM2_IRQHandler\r
-       .thumb_set LPTIM2_IRQHandler,Default_Handler    \r
-       \r
-       .weak   OTG_FS_IRQHandler\r
-       .thumb_set OTG_FS_IRQHandler,Default_Handler    \r
-       \r
-       .weak   DMA2_Channel6_IRQHandler\r
-       .thumb_set DMA2_Channel6_IRQHandler,Default_Handler     \r
-       \r
-       .weak   DMA2_Channel7_IRQHandler\r
-       .thumb_set DMA2_Channel7_IRQHandler,Default_Handler     \r
-       \r
-       .weak   LPUART1_IRQHandler\r
-       .thumb_set LPUART1_IRQHandler,Default_Handler   \r
-       \r
-       .weak   QUADSPI_IRQHandler\r
-       .thumb_set QUADSPI_IRQHandler,Default_Handler   \r
-       \r
-       .weak   I2C3_EV_IRQHandler\r
-       .thumb_set I2C3_EV_IRQHandler,Default_Handler   \r
-       \r
-       .weak   I2C3_ER_IRQHandler\r
-       .thumb_set I2C3_ER_IRQHandler,Default_Handler   \r
-       \r
-       .weak   SAI1_IRQHandler\r
-       .thumb_set SAI1_IRQHandler,Default_Handler\r
-       \r
-       .weak   SAI2_IRQHandler\r
-       .thumb_set SAI2_IRQHandler,Default_Handler\r
-       \r
-       .weak   SWPMI1_IRQHandler\r
-       .thumb_set SWPMI1_IRQHandler,Default_Handler\r
-       \r
-       .weak   TSC_IRQHandler\r
-       .thumb_set TSC_IRQHandler,Default_Handler\r
-       \r
-       .weak   LCD_IRQHandler\r
-       .thumb_set LCD_IRQHandler,Default_Handler\r
-       \r
-       .weak   RNG_IRQHandler\r
-       .thumb_set RNG_IRQHandler,Default_Handler\r
-       \r
-       .weak   FPU_IRQHandler\r
-       .thumb_set FPU_IRQHandler,Default_Handler\r
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/\r
diff --git a/stm32l4xx_it.c b/stm32l4xx_it.c
deleted file mode 100644 (file)
index dc6dc16..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-#include <stm32l476xx.h>\r
-\r
-void NMI_Handler(void) {}\r
-\r
-void HardFault_Handler(void)\r
-{\r
-       GPIOA->BSRR |= (1 << 5) | (1 << 6);\r
-       while (1);\r
-}\r
-\r
-void MemManage_Handler(void)\r
-{\r
-       GPIOA->BSRR |= (1 << 5) | (1 << 6);\r
-       while (1);\r
-}\r
-\r
-void BusFault_Handler(void)\r
-{\r
-       GPIOA->BSRR |= (1 << 5) | (1 << 6);\r
-       while (1);\r
-}\r
-\r
-void UsageFault_Handler(void)\r
-{\r
-       GPIOA->BSRR |= (1 << 5) | (1 << 6);\r
-       while (1);\r
-}\r
-\r
-void SVC_Handler(void) {}\r
-\r
-void DebugMon_Handler(void) {}\r
-\r
diff --git a/system_stm32l4xx.c b/system_stm32l4xx.c
deleted file mode 100644 (file)
index 4c22bfe..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-#include "stm32l476xx.h"\r
-\r
-/************************* Miscellaneous Configuration ************************/\r
-/*!< Uncomment the following line if you need to relocate your vector Table in\r
-     Internal SRAM. */\r
-/* #define VECT_TAB_SRAM */\r
-#define VECT_TAB_OFFSET  0x00 /*!< Vector Table base offset field.\r
-                                   This value must be a multiple of 0x200. */\r
-/******************************************************************************/\r
-\r
-void SystemInit(void)\r
-{\r
-  /* FPU settings ------------------------------------------------------------*/\r
-  #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)\r
-    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */\r
-  #endif\r
-\r
-  /* Reset the RCC clock configuration to the default reset state ------------*/\r
-  /* Set MSION bit */\r
-  RCC->CR |= RCC_CR_MSION;\r
-\r
-  /* Reset CFGR register */\r
-  RCC->CFGR = 0x00000000U;\r
-\r
-  /* Reset HSEON, CSSON , HSION, and PLLON bits */\r
-  RCC->CR &= 0xEAF6FFFFU;\r
-\r
-  /* Reset PLLCFGR register */\r
-  RCC->PLLCFGR = 0x00001000U;\r
-\r
-  /* Reset HSEBYP bit */\r
-  RCC->CR &= 0xFFFBFFFFU;\r
-\r
-  /* Disable all interrupts */\r
-  RCC->CIER = 0x00000000U;\r
-\r
-  /* Configure the Vector Table location add offset address ------------------*/\r
-#ifdef VECT_TAB_SRAM\r
-  SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */\r
-#else\r
-  SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */\r
-#endif\r
-}\r
-\r
diff --git a/task.c b/task.c
deleted file mode 100644 (file)
index b77d4f5..0000000
--- a/task.c
+++ /dev/null
@@ -1,108 +0,0 @@
-#include <task.h>
-#include <heap.h>
-#include <stm32l476xx.h>
-
-typedef struct {
-       uint32_t *sp;
-       uint8_t use;
-       uint32_t *stack;
-       void (*code)(void);
-} task_t;
-
-#define MAX_TASKS      4
-
-static task_t tasks[MAX_TASKS];
-static int next_idx = 0;
-
-void task_init(void (*init)(void))
-{
-       for (int i = 0; i < MAX_TASKS; i++)
-               tasks[i].use = 0;
-
-       task_start(init, 1024);
-       asm("\
-               msr psp, %0; \
-               mrs r0, control; \
-               orr r0, r0, #2; \
-               msr control, r0; \
-               isb; \
-       " :: "r" (tasks[0].sp));
-
-       init();
-
-       // force switch to tasking, call pendsv
-       //SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk;
-}
-
-extern void _exit(int);
-void task_exit(void)
-{
-       // TODO free stack?
-       asm("cpsid i"); // hope to catch next_idx
-       tasks[next_idx].use = 0;
-       asm("cpsie i");
-       while (1); // bye
-       //_exit(0);
-}
-
-void task_start(void (*task)(void), uint16_t stackSize)
-{
-       asm("cpsid i"); // just to be safe
-
-       for (int i = 0; i < MAX_TASKS; i++) {
-               if (tasks[i].use == 0) {
-                       tasks[i].stack = hmalloc(stackSize);
-                       tasks[i].sp = tasks[i].stack + stackSize - 16;
-                       tasks[i].sp[13] = (uint32_t)task_exit;
-                       tasks[i].sp[14] = (uint32_t)task;
-                       tasks[i].sp[15] = 0x01000000;
-                       tasks[i].use = 1;
-                       tasks[i].code = task;
-                       asm("cpsie i");
-                       return;
-               }
-       }
-
-       // TODO handle error
-}
-
-__attribute__ ((naked))
-void PendSV_Handler(void) 
-{
-       // save state
-       //stmdb r0!, {r4-r11};
-       asm("\
-               cpsid i; \
-               isb; \
-               dsb; \
-               mrs r0, psp; \
-               stmdb r0!, {r4-r11}; \
-               mov %0, r0; \
-       " : "=r" (tasks[next_idx].sp));
-
-       // find next task (round-robin style)
-       do {
-               if (++next_idx == MAX_TASKS) {
-                       next_idx = 0;
-                       break; // task 0 better exist
-               }
-       } while (tasks[next_idx].use == 0);
-
-       // restore
-       //ldmia r0!, {r4-r11};
-       asm("\
-               mov r0, %0; \
-               ldmia r0!, {r4-r11}; \
-               msr psp, r0; \
-               isb; \
-               dsb; \
-       " :: "r" (tasks[next_idx].sp));
-
-       // end
-       asm("\
-               mov r0, #0xFFFFFFFD; \
-               cpsie i; \
-               bx r0; \
-       ");
-}
-