+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/*
+
+
* 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```.
+++ /dev/null
-#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));
-}
-
+++ /dev/null
-#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;
-}
--- /dev/null
+#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_
--- /dev/null
+#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_
--- /dev/null
+#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_
--- /dev/null
+Hello, world!
--- /dev/null
+print "yay"
+
+yesyesye
/* 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
. = 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
._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
.ARM.attributes 0 : { *(.ARM.attributes) }\r
}\r
\r
-_total_ram = _estack - _end;\r
+++ /dev/null
-#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
--- /dev/null
+#!/bin/bash
+echo "Making initrd.img..."
+rm -f initrd.img
+arm-none-eabi-ar r initrd.img initrd/*
--- /dev/null
+#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));
+}
+
--- /dev/null
+#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);
+}
--- /dev/null
+#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;
+}
--- /dev/null
+#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);
+}
+
--- /dev/null
+#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();
+}
--- /dev/null
+#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
--- /dev/null
+/**\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>© 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
--- /dev/null
+#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;
+}
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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; \
+ ");
+}
+
+++ /dev/null
-/**\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>© 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
+++ /dev/null
-#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
+++ /dev/null
-#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
+++ /dev/null
-#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; \
- ");
-}
-