diff options
-rw-r--r-- | Makefile | 20 | ||||
-rw-r--r-- | include/heap.h | 1 | ||||
-rw-r--r-- | include/random.h | 9 | ||||
-rw-r--r-- | include/script.h | 8 | ||||
-rw-r--r-- | include/stdlib.h | 8 | ||||
-rw-r--r-- | include/task.h | 6 | ||||
-rw-r--r-- | initrd/init | 39 | ||||
-rw-r--r-- | libinterp.a | bin | 61980 -> 62140 bytes | |||
-rwxr-xr-x | run.sh | 3 | ||||
-rw-r--r-- | src/clock.c | 6 | ||||
-rw-r--r-- | src/display.c | 26 | ||||
-rw-r--r-- | src/display_draw.c | 12 | ||||
-rw-r--r-- | src/heap.c | 67 | ||||
-rw-r--r-- | src/initrd.c | 4 | ||||
-rw-r--r-- | src/main.c | 183 | ||||
-rw-r--r-- | src/main.c.bak | 203 | ||||
-rw-r--r-- | src/random.c | 24 | ||||
-rw-r--r-- | src/script.c | 120 | ||||
-rw-r--r-- | src/stdlib.c | 74 | ||||
-rw-r--r-- | src/stm32l4xx_it.c | 26 | ||||
-rw-r--r-- | src/task.c | 62 |
21 files changed, 435 insertions, 466 deletions
@@ -6,9 +6,12 @@ OBJCOPY = objcopy MCUFLAGS = -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 AFLAGS = $(MCUFLAGS) -CFLAGS = $(MCUFLAGS) -Iinclude -Iinclude/it -fno-builtin -fsigned-char -ffreestanding -Wall -Werror -Wextra -Wno-discarded-qualifiers -ggdb -LFLAGS = -OFLAGS = -O ihex +CFLAGS = $(MCUFLAGS) -ggdb \ + -Iinclude -Iinclude/it \ + -fno-builtin -fsigned-char -ffreestanding \ + -Wall -Werror -Wextra -pedantic \ + -Wno-overlength-strings -Wno-discarded-qualifiers +LFLAGS = -T link.ld CFILES = $(wildcard src/*.c) AFILES = $(wildcard src/*.s) @@ -17,16 +20,15 @@ OUTDIR = out OFILES = $(patsubst src/%.c, $(OUTDIR)/%.o, $(CFILES)) \ $(patsubst src/%.s, $(OUTDIR)/%.asm.o, $(AFILES)) -HEX = main.hex +OUT = out/main.elf -all: $(HEX) +all: $(OUT) -$(HEX): $(OFILES) initrd/init - @echo " LINK " $(HEX) +$(OUT): $(OFILES) initrd/init libinterp.a + @echo " LINK " $(OUT) @./mkinitrd.sh @$(CROSS)$(OBJCOPY) -B arm -I binary -O elf32-littlearm initrd.img out/initrd.img.o - @$(CROSS)$(CC) $(CFLAGS) $(LFLAGS) -T link.ld out/*.o -o out/main.elf -L. -linterp - @$(CROSS)$(OBJCOPY) $(OFLAGS) out/main.elf $(HEX) + @$(CROSS)$(CC) $(CFLAGS) $(LFLAGS) out/*.o -o $(OUT) -L. -linterp $(OUTDIR)/%.o: src/%.c @echo " CC " $< diff --git a/include/heap.h b/include/heap.h index 8118384..c93eb8e 100644 --- a/include/heap.h +++ b/include/heap.h @@ -4,7 +4,6 @@ #include <stdint.h> void heap_init(void *buf); -uint32_t heap_used(void); void *malloc(uint32_t size); void *calloc(uint32_t count, uint32_t size); diff --git a/include/random.h b/include/random.h new file mode 100644 index 0000000..6485f26 --- /dev/null +++ b/include/random.h @@ -0,0 +1,9 @@ +#ifndef RANDOM_H_ +#define RANDOM_H_ + +#include <stdint.h> + +void random_init(void); +uint32_t random_get(void); + +#endif // RANDOM_H_ diff --git a/include/script.h b/include/script.h new file mode 100644 index 0000000..dc8c590 --- /dev/null +++ b/include/script.h @@ -0,0 +1,8 @@ +#ifndef SCRIPT_H_ +#define SCRIPT_H_ + +#include <parser.h> + +void script_loadlib(interpreter *it); + +#endif // SCRIPT_H_ diff --git a/include/stdlib.h b/include/stdlib.h new file mode 100644 index 0000000..c2658d6 --- /dev/null +++ b/include/stdlib.h @@ -0,0 +1,8 @@ +#ifndef STDLIB_H_ +#define STDLIB_H_ + +char *snprintf(char *buf, unsigned int max, const char *format, ...); +float strtof(const char *s, char **endptr); +int atoi(const char *s); + +#endif // STDLIB_H_ diff --git a/include/task.h b/include/task.h index 7077b00..1ef8639 100644 --- a/include/task.h +++ b/include/task.h @@ -8,6 +8,12 @@ #include <stdint.h> +typedef struct { + void *next; + uint32_t *stack; + uint32_t *sp; +} task_t; + /** * Enters multitasking mode. The given function acts as the initial thread. * This task is given a 4kb stack. diff --git a/initrd/init b/initrd/init index 694c151..9f6a9cf 100644 --- a/initrd/init +++ b/initrd/init @@ -1,33 +1,12 @@ -print "Hello." - -set fg 32767 - -# draw bg, lines -rect 50 50 380 220 6375 -line 50 160 430 160 fg -line 240 50 240 270 fg - -set x 50 -do - line x 170 x 150 fg - set x (x + 20) -while (x < 430) - -set y 50 do - line 230 y 250 y fg - set y (y + 20) -while (y < 270) + rand 479 > x + rand 319 > y + rand 479 > i + rand 319 > j + rand 32767 > purple + + line x y i j purple +while (1) -#line 80 250 380 90 511 -set purple 511 -do - rand 219 > x - rand 379 > y - rand 219 > i - rand 379 > j +print "done" - line (x + 50) (y + 50) (i + 50) (j + 50) purple - delay 1000 - set purple (purple + 11) -while (1) diff --git a/libinterp.a b/libinterp.a Binary files differindex 7884542..561bb11 100644 --- a/libinterp.a +++ b/libinterp.a @@ -1,7 +1,4 @@ #!/bin/bash -#openocd -f /usr/share/openocd/scripts/board/st_nucleo_l476rg.cfg \ -# -c "init; reset halt; flash write_image erase main.hex; reset run; exit" - openocd -f /usr/share/openocd/scripts/board/st_nucleo_l476rg.cfg > /dev/null & gdb-multiarch -iex "target remote localhost:3333" out/main.elf diff --git a/src/clock.c b/src/clock.c index 7cb4ecf..3d31f91 100644 --- a/src/clock.c +++ b/src/clock.c @@ -22,8 +22,8 @@ void clock_init(void) 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 + RCC->PLLCFGR &= ~(RCC_PLLCFGR_PLLR | RCC_PLLCFGR_PLLQ); // /2 + RCC->PLLCFGR |= RCC_PLLCFGR_PLLREN | RCC_PLLCFGR_PLLQEN; // start PLL RCC->CR |= RCC_CR_PLLON; @@ -54,7 +54,7 @@ void SysTick_Handler(void) // just keep counting ticks++; - if (!(ticks % 4)) + if (!(ticks & 3)) SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; asm("mov lr, %0; bx lr" :: "r" (lr)); diff --git a/src/display.c b/src/display.c index 955cf8f..163a742 100644 --- a/src/display.c +++ b/src/display.c @@ -117,19 +117,19 @@ void dsp_init(void) gpio_mode(LCD_WR, OUTPUT); gpio_mode(LCD_RST, OUTPUT); dsp_dmode(OUTPUT); - gpio_speed(LCD_CS, LOW); - gpio_speed(LCD_RS, LOW); - gpio_speed(LCD_RD, LOW); - gpio_speed(LCD_WR, LOW); - gpio_speed(LCD_RST, LOW); - gpio_speed(LCD_D0, LOW); - gpio_speed(LCD_D1, LOW); - gpio_speed(LCD_D2, LOW); - gpio_speed(LCD_D3, LOW); - gpio_speed(LCD_D4, LOW); - gpio_speed(LCD_D5, LOW); - gpio_speed(LCD_D6, LOW); - gpio_speed(LCD_D7, LOW); + gpio_speed(LCD_CS, VERYHIGH); + gpio_speed(LCD_RS, VERYHIGH); + gpio_speed(LCD_RD, VERYHIGH); + gpio_speed(LCD_WR, VERYHIGH); + gpio_speed(LCD_RST, VERYHIGH); + gpio_speed(LCD_D0, VERYHIGH); + gpio_speed(LCD_D1, VERYHIGH); + gpio_speed(LCD_D2, VERYHIGH); + gpio_speed(LCD_D3, VERYHIGH); + gpio_speed(LCD_D4, VERYHIGH); + gpio_speed(LCD_D5, VERYHIGH); + gpio_speed(LCD_D6, VERYHIGH); + gpio_speed(LCD_D7, VERYHIGH); gpio_dout(LCD_CS, 0); gpio_dout(LCD_RS, 1); gpio_dout(LCD_RD, 1); diff --git a/src/display_draw.c b/src/display_draw.c index be4becf..27ed796 100644 --- a/src/display_draw.c +++ b/src/display_draw.c @@ -33,6 +33,7 @@ void dsp_cursoron(void) void dsp_putchar(int c) { + LOCK; if (c == '\n') { curx = 0; if (++cury == 12) { @@ -65,15 +66,14 @@ void dsp_putchar(int c) cury = 0; } } + UNLOCK; } void dsp_puts(const char *s) { unsigned int i = 0; - LOCK; while (s[i]) dsp_putchar(s[i++]); - UNLOCK; } void dsp_cpos(int x, int y) @@ -90,14 +90,14 @@ void dsp_coff(int x, int y) void dsp_rect(int x, int y, int w, int h, uint16_t color) { - LOCK; dsp_set_addr(x, y, x + w - 1, y + h - 1); int countdown = w * h; do { + LOCK; dsp_write_data(color >> 8); dsp_write_data(color & 0xFF); + UNLOCK; } while (countdown--); - UNLOCK; } void dsp_line(int x, int y, int i, int j, uint16_t color) @@ -114,11 +114,12 @@ void dsp_line(int x, int y, int i, int j, uint16_t color) int err = (dx > dy ? dx : -dy) / 2; int e2; - LOCK; while (1) { + LOCK; dsp_set_addr(x, y, x, y); dsp_write_data(color >> 8); dsp_write_data(color & 0xFF); + UNLOCK; if (x == i && y == j) break; e2 = err; @@ -131,6 +132,5 @@ void dsp_line(int x, int y, int i, int j, uint16_t color) y += sy; } } - UNLOCK; } @@ -4,54 +4,52 @@ #define HEAP_ALIGN 16 typedef struct { - uint32_t next; uint32_t size; + void *next; } __attribute__ ((packed)) alloc_t; -static alloc_t root; +static alloc_t *free_blocks; static void *heap_end; +static uint32_t heap_used; void heap_init(void *buf) { heap_end = buf; - root.next = 1; - root.size = 0; - // what to do... -} - -uint32_t heap_used(void) -{ - uint32_t total = 0; - alloc_t *a = &root; - while (a->next > 1) { - total += a->size; - a = (void *)(a->next & ~(1)); - } - return total; + free_blocks = 0; + heap_used = 0; } void *malloc(uint32_t size) { - task_hold(1); - if (size < HEAP_ALIGN) - size = HEAP_ALIGN; - alloc_t *node = &root; - while (node->next & 1 || node->size < size) { - if ((node->next & ~(1)) == 0) { - node->next |= (uint32_t)(heap_end + HEAP_ALIGN) & ~(HEAP_ALIGN - 1); - heap_end += HEAP_ALIGN + size; - node = (void *)(node->next & ~(1)); + //task_hold(1); + size = (size + sizeof(alloc_t) + HEAP_ALIGN) & ~(HEAP_ALIGN - 1); + + alloc_t *node = free_blocks; + alloc_t *prev = 0; + while (node != 0) { + if (node->size >= size) { + if (prev != 0) + prev->next = node->next; + else + free_blocks = node->next; node->next = 0; - node->size = size; - break; + heap_used += node->size; + return (void *)((uint8_t *)node + sizeof(alloc_t)); } - node = (void *)(node->next & ~(1)); + + prev = node; + node = node->next; } - node->next |= 1; - task_hold(0); + node = (alloc_t *)heap_end; + node->size = size; + node->next = 0; - return (void *)((uint32_t)node + sizeof(alloc_t)); + heap_end = (void *)((uint8_t *)heap_end + size); + heap_used += size; + + //task_hold(0); + return (void *)((uint8_t *)node + sizeof(alloc_t)); } void *calloc(uint32_t count, uint32_t size) @@ -66,6 +64,9 @@ void free(void *buf) { if (buf == 0) return; - alloc_t *alloc = (alloc_t *)((uint32_t)buf - sizeof(alloc_t)); - alloc->next &= ~(1); + + alloc_t *alloc = (alloc_t *)((uint8_t *)buf - sizeof(alloc_t)); + heap_used -= alloc->size; + alloc->next = free_blocks; + free_blocks = alloc; } diff --git a/src/initrd.c b/src/initrd.c index 54bdc4b..e90f9f0 100644 --- a/src/initrd.c +++ b/src/initrd.c @@ -53,7 +53,7 @@ uint32_t initrd_getsize(initrd_file *file) initrd_file *initrd_getfileptr(const char *name) { - initrd_file *file = (initrd_file *)(initrd_start + sizeof(initrd_header)); + initrd_file *file = (initrd_file *)((uint8_t *)initrd_start + sizeof(initrd_header)); uint32_t offset = sizeof(initrd_header); while (offset < initrd_size) { @@ -74,7 +74,7 @@ char *initrd_getfile(const char *name) return 0; - char *ptr = (char *)((void *)file + sizeof(initrd_file)); + char *ptr = (char *)file + sizeof(initrd_file); ptr[initrd_getsize(file) - 1] = 0; return ptr; } @@ -7,160 +7,65 @@ #include <display.h>
#include <display_draw.h>
#include <initrd.h>
-#include <serial.h>
#include <parser.h>
-#include <builtins.h>
-#include <stack.h>
+#include <serial.h>
#include <string.h>
+#include <script.h>
+#include <random.h>
+extern uint8_t _ebss;
extern char *itoa(int, char *, int);
void kmain(void);
+void task_interpreter(void);
int main(void)
{
asm("cpsid i");
+ // disable write buffer
+ *((uint32_t *)0xE000E008) |= 2;
- // prepare flash latency for 40MHz operation
+ // prepare flash latency for 80MHz operation
FLASH->ACR &= ~(FLASH_ACR_LATENCY);
FLASH->ACR |= FLASH_ACR_LATENCY_4WS;
//MPU->CTRL |= MPU_CTRL_ENABLE_Msk | MPU_CTRL_PRIVDEFENA_Msk;
clock_init();
- extern uint8_t _ebss;
heap_init(&_ebss);
gpio_init();
+ serial_init();
+ random_init();
gpio_mode(GPIOA, 5, OUTPUT);
- serial_init();
-
// enable FPU
SCB->CPACR |= (0xF << 20);
task_init(kmain);
-
while (1);
}
-int script_puts(interpreter *it)
-{
- char *s = igetarg_string(it, 0);
- dsp_puts(s);
- //dsp_puts("\n");
- //asm("mov r0, %0; svc 2" :: "r" (s));
- return 0;
-}
-
-int script_gets(interpreter *it)
-{
- char *s = malloc(64), c[2] = {0, 0};
- uint16_t index = 0;
-
- do {
- c[0] = serial_get();
- s[index] = c[0];
- if (c[0] != '\r')
- dsp_puts(c);
- } while (s[index] != '\r' && index++ < 23);
- s[index] = '\0';
-
- variable *v = igetarg(it, 0);
- v->valtype = STRING;
- v->svalue = s;
- return 0;
-}
-
-int script_delay(interpreter *it)
-{
- int ms = igetarg_integer(it, 0);
- delay(ms);
- return 0;
-}
-
-int script_rect(interpreter *it)
-{
- dsp_rect(igetarg_integer(it, 0), igetarg_integer(it, 1),
- igetarg_integer(it, 2), igetarg_integer(it, 3),
- igetarg_integer(it, 4));
- return 0;
-}
-
-int script_line(interpreter *it)
-{
- dsp_line(igetarg_integer(it, 0), igetarg_integer(it, 1),
- igetarg_integer(it, 2), igetarg_integer(it, 3),
- igetarg_integer(it, 4));
- return 0;
-}
-
-int script_ppos(interpreter *it)
-{
- dsp_cpos(0, 0);
- dsp_coff(igetarg_integer(it, 0), igetarg_integer(it, 1));
- return 0;
-}
-
-int script_color(interpreter *it)
+void kmain(void)
{
- uint16_t c = dsp_color(igetarg_integer(it, 0), igetarg_integer(it, 1),
- igetarg_integer(it, 2));
- variable v;
- v.valtype = INTEGER;
- INT(&v) = c;
- v.svalue = 0;
- isetstr(&v);
- iret(it, &v);
- return 0;
-}
+ asm("cpsie i");
+ dsp_init();
+ dsp_rect(0, 0, LCD_WIDTH, LCD_HEIGHT, dsp_color(0, 0, 0));
+ dsp_cursoron();
+ task_start(task_interpreter, 4096);
-int script_rand(interpreter *it)
-{
- static uint32_t next = 1;
- next = (next * 182 + 1829) % igetarg_integer(it, 0);
- variable v;
- v.valtype = INTEGER;
- INT(&v) = next;
- v.svalue = 0;
- isetstr(&v);
- iret(it, &v);
- return 0;
+ while (1) {
+ gpio_dout(GPIOA, 5, 1);
+ delay(250);
+ gpio_dout(GPIOA, 5, 0);
+ delay(250);
+ }
}
void task_interpreter(void)
{
interpreter it;
iinit(&it);
- inew_cfunc(&it, "print", script_puts);
- inew_cfunc(&it, "gets", script_gets);
- inew_cfunc(&it, "delay", script_delay);
- inew_cfunc(&it, "rect", script_rect);
- inew_cfunc(&it, "ppos", script_ppos);
- inew_cfunc(&it, "line", script_line);
- inew_cfunc(&it, "color", script_color);
- inew_cfunc(&it, "rand", script_rand);
-
- /*int ret = 0;
- char *linebuf = malloc(100), c[2] = {0, 0};
- while (1) {
- uint16_t index = 0;
- if (it.indent > 0)
- dsp_puts(">");
- dsp_puts("> ");
- do {
- c[0] = serial_get();
- if (c[0] >= ' ' || c[0] == '\r') {
- linebuf[index] = c[0];
- if (c[0] >= ' ')
- dsp_puts(c);
- }
- } while (linebuf[index] != '\r' && index++ < 100);
- linebuf[index] = '\0';
- dsp_puts("\n");
- ret = idoline(&it, linebuf);
- if (ret < 0)
- break;
- }*/
+ script_loadlib(&it);
char *s = initrd_getfile("init");
if (s == 0) {
@@ -171,7 +76,7 @@ void task_interpreter(void) char *linebuf = (char *)malloc(120);
uint32_t i = 0, prev = 0, lc;
uint32_t size = initrd_getfilesize("init");
- int ret;
+ int ret = 0;
while (i < size) {
for (; s[i] != '\n' && s[i] != '\0'; i++);
lc = i - prev;
@@ -181,9 +86,7 @@ void task_interpreter(void) }
strncpy(linebuf, s + prev, lc + 1);
linebuf[lc] = '\0';
- //task_hold(1);
ret = idoline(&it, linebuf);
- //task_hold(0);
if (ret < 0)
break;
prev = ++i;
@@ -201,20 +104,26 @@ end: delay(10);
}
-void kmain(void)
-{
- asm("cpsie i");
- dsp_init();
- dsp_rect(0, 0, LCD_WIDTH, LCD_HEIGHT, dsp_color(0, 0, 0));
- dsp_cursoron();
- //dsp_puts("Hey.");
- task_start(task_interpreter, 4096);
-
- while (1) {
- gpio_dout(GPIOA, 5, 1);
- delay(500);
- gpio_dout(GPIOA, 5, 0);
- delay(500);
- }
-}
+// for interactive use
+/*int ret = 0;
+char *linebuf = malloc(100), c[2] = {0, 0};
+while (1) {
+ uint16_t index = 0;
+ if (it.indent > 0)
+ dsp_puts(">");
+ dsp_puts("> ");
+ do {
+ c[0] = serial_get();
+ if (c[0] >= ' ' || c[0] == '\r') {
+ linebuf[index] = c[0];
+ if (c[0] >= ' ')
+ dsp_puts(c);
+ }
+ } while (linebuf[index] != '\r' && index++ < 100);
+ linebuf[index] = '\0';
+ dsp_puts("\n");
+ ret = idoline(&it, linebuf);
+ if (ret < 0)
+ break;
+}*/
diff --git a/src/main.c.bak b/src/main.c.bak deleted file mode 100644 index 95f3210..0000000 --- a/src/main.c.bak +++ /dev/null @@ -1,203 +0,0 @@ -#include <stm32l476xx.h>
-#include <clock.h>
-#include <heap.h>
-#include <task.h>
-#include <gpio.h>
-#include <lcd.h>
-#include <display.h>
-#include <display_draw.h>
-#include <initrd.h>
-#include <serial.h>
-#include <parser.h>
-#include <stack.h>
-
-#include <stdlib.h>
-#include <string.h>
-
-void kmain(void);
-void task_interpreter(void);
-
-int main(void)
-{
- asm("cpsid i");
-
- // prepare flash latency for 40MHz operation
- FLASH->ACR &= ~(FLASH_ACR_LATENCY);
- FLASH->ACR |= FLASH_ACR_LATENCY_4WS;
-
- //MPU->CTRL |= MPU_CTRL_ENABLE_Msk | MPU_CTRL_PRIVDEFENA_Msk;
- clock_init();
- gpio_init();
-
- gpio_mode(GPIOA, 5, OUTPUT);
-
- serial_init();
-
- // enable FPU
- SCB->CPACR |= (0xF << 20);
-
- task_init(kmain);
-
- while (1);
-}
-
-int script_puts(interpreter *it)
-{
- char *s = igetarg_string(it, 0);
- dsp_puts(s);
- //dsp_puts("\n");
- //asm("mov r0, %0; svc 2" :: "r" (s));
- return 0;
-}
-
-int script_gets(interpreter *it)
-{
- char *s = malloc(64), c[2] = {0, 0};
- uint16_t index = 0;
-
- do {
- c[0] = serial_get();
- s[index] = c[0];
- if (c[0] != '\r')
- dsp_puts(c);
- } while (s[index] != '\r' && index++ < 23);
- s[index] = '\0';
-
- variable *v = igetarg(it, 0);
- v->valtype = STRING;
- v->svalue = s;
- return 0;
-}
-
-int script_delay(interpreter *it)
-{
- int ms = igetarg_integer(it, 0);
- delay(ms);
- return 0;
-}
-
-int script_rect(interpreter *it)
-{
- dsp_rect(igetarg_integer(it, 0), igetarg_integer(it, 1),
- igetarg_integer(it, 2), igetarg_integer(it, 3),
- igetarg_integer(it, 4));
- return 0;
-}
-
-int script_line(interpreter *it)
-{
- dsp_line(igetarg_integer(it, 0), igetarg_integer(it, 1),
- igetarg_integer(it, 2), igetarg_integer(it, 3),
- igetarg_integer(it, 4));
- return 0;
-}
-
-int script_ppos(interpreter *it)
-{
- dsp_cpos(0, 0);
- dsp_coff(igetarg_integer(it, 0), igetarg_integer(it, 1));
- return 0;
-}
-
-void task_interpreter(void)
-{
- interpreter it;
- iinit(&it);
- inew_cfunc(&it, "print", script_puts);
- inew_cfunc(&it, "gets", script_gets);
- inew_cfunc(&it, "delay", script_delay);
- inew_cfunc(&it, "rect", script_rect);
- inew_cfunc(&it, "ppos", script_ppos);
- inew_cfunc(&it, "line", script_line);
-
- /*int ret = 0;
- char *linebuf = malloc(100), c[2] = {0, 0};
- while (1) {
- uint16_t index = 0;
- if (it.indent > 0)
- dsp_puts(">");
- dsp_puts("> ");
- do {
- c[0] = serial_get();
- if (c[0] >= ' ' || c[0] == '\r') {
- linebuf[index] = c[0];
- if (c[0] >= ' ')
- dsp_puts(c);
- }
- } while (linebuf[index] != '\r' && index++ < 100);
- linebuf[index] = '\0';
- dsp_puts("\n");
- ret = idoline(&it, linebuf);
- if (ret < 0)
- break;
- }*/
-
- char *s = initrd_getfile("init");
- if (s == 0)
- goto end;
-
- char *linebuf = (char *)malloc(120);
- uint32_t i = 0, prev = 0, lc;
- uint32_t size = initrd_getfilesize("init");
- int ret;
- while (i < size) {
- for (; s[i] != '\n' && s[i] != '\0'; i++);
- lc = i - prev;
- if (lc == 0) {
- prev = ++i;
- continue;
- }
- strncpy(linebuf, s + prev, lc + 1);
- linebuf[lc] = '\0';
- ret = idoline(&it, linebuf);
- if (ret < 0)
- break;
- prev = ++i;
- }
-
- if (ret < 0) {
- dsp_puts("\nError: ");
- dsp_puts(itoa(ret, linebuf, 10));
- }
- free(linebuf);
- //iend(&it); // nah
-
-end:
- while (1)
- delay(10);
-}
-
-void kmain(void)
-{
- asm("cpsie i");
-
- dsp_init();
-
- //dsp_rect(0, 0, 40, 40, dsp_color(0x7F, 0, 0x7F));
-
- //dsp_set_addr_read(0, 0, 39, 39);
- //dsp_dmode(INPUT);
- //uint8_t *buf = (uint8_t *)malloc(40 * 40 * 2);
- //for (int i = 0; i < 180; i++)
- // buf[i] = dsp_read_data();
- //dsp_dmode(OUTPUT);
- //dsp_set_addr(40, 40, 79, 79);
- //for (int i = 0; i < 320; i++)
- // dsp_write_data(buf[i]);
- //dsp_rect(80, 80, 40, 40, dsp_color(0x7F, 0x7F, 0));
-
- dsp_rect(0, 0, LCD_WIDTH, LCD_HEIGHT, dsp_color(0, 0, 0));
- dsp_cursoron();
-
- task_start(task_interpreter, 4096);
-
- //char *s = initrd_getfile("test.txt");
-
- while (1) {
- gpio_dout(GPIOA, 5, 1);
- delay(500);
- gpio_dout(GPIOA, 5, 0);
- delay(500);
- }
-}
-
diff --git a/src/random.c b/src/random.c new file mode 100644 index 0000000..9c1e0d1 --- /dev/null +++ b/src/random.c @@ -0,0 +1,24 @@ +#include <random.h> + +#include <stm32l476xx.h> +#include <clock.h> + +void random_init(void) +{ + // setup and enable RNG clock + RCC->CCIPR &= ~(RCC_CCIPR_CLK48SEL); + RCC->CCIPR |= RCC_CCIPR_CLK48SEL_1; + RCC->AHB2ENR |= RCC_AHB2ENR_RNGEN; + RNG->CR |= RNG_CR_RNGEN; +} + +uint32_t random_get(void) +{ + if (RNG->SR & (RNG_SR_SEIS | RNG_SR_CEIS)) + return 0; + + while (!(RNG->SR & RNG_SR_DRDY)) + delay(1); + + return RNG->DR; +} diff --git a/src/script.c b/src/script.c new file mode 100644 index 0000000..adf402b --- /dev/null +++ b/src/script.c @@ -0,0 +1,120 @@ +#include <script.h> + +#include <builtins.h> +#include <clock.h> +#include <display.h> +#include <display_draw.h> +#include <heap.h> +#include <random.h> +#include <serial.h> +#include <stack.h> + +int script_puts(interpreter *it); +int script_gets(interpreter *it); +int script_delay(interpreter *it); +int script_rect(interpreter *it); +int script_ppos(interpreter *it); +int script_line(interpreter *it); +int script_color(interpreter *it); +int script_rand(interpreter *it); + +void script_loadlib(interpreter *it) +{ + inew_cfunc(it, "print", script_puts); + inew_cfunc(it, "gets", script_gets); + inew_cfunc(it, "delay", script_delay); + inew_cfunc(it, "rect", script_rect); + inew_cfunc(it, "ppos", script_ppos); + inew_cfunc(it, "line", script_line); + inew_cfunc(it, "color", script_color); + inew_cfunc(it, "rand", script_rand); +} + +int script_puts(interpreter *it) +{ + char *s = igetarg_string(it, 0); + dsp_puts(s); + //dsp_puts("\n"); + //asm("mov r0, %0; svc 2" :: "r" (s)); + return 0; +} + +int script_gets(interpreter *it) +{ + char *s = malloc(64), c[2] = {0, 0}; + uint16_t index = 0; + + do { + c[0] = serial_get(); + s[index] = c[0]; + if (c[0] != '\r') + dsp_puts(c); + } while (s[index] != '\r' && index++ < 23); + s[index] = '\0'; + + variable *v = igetarg(it, 0); + v->valtype = STRING; + v->svalue = s; + return 0; +} + +int script_delay(interpreter *it) +{ + int ms = igetarg_integer(it, 0); + delay(ms); + return 0; +} + +int script_rect(interpreter *it) +{ + dsp_rect(igetarg_integer(it, 0), igetarg_integer(it, 1), + igetarg_integer(it, 2), igetarg_integer(it, 3), + igetarg_integer(it, 4)); + return 0; +} + +int script_line(interpreter *it) +{ + int x = igetarg_integer(it, 0); + int y = igetarg_integer(it, 1); + int i = igetarg_integer(it, 2); + int j = igetarg_integer(it, 3); + int c = igetarg_integer(it, 4); + dsp_line(x, y, i, j, c); + return 0; +} + +int script_ppos(interpreter *it) +{ + dsp_cpos(0, 0); + dsp_coff(igetarg_integer(it, 0), igetarg_integer(it, 1)); + return 0; +} + +int script_color(interpreter *it) +{ + uint16_t c = dsp_color(igetarg_integer(it, 0), igetarg_integer(it, 1), + igetarg_integer(it, 2)); + variable v; + v.valtype = INTEGER; + INT(&v) = c; + v.svalue = 0; + isetstr(&v); + iret(it, &v); + return 0; +} + +int script_rand(interpreter *it) +{ + variable *v = (variable *)malloc(sizeof(variable)); + unsigned int mod = igetarg_integer(it, 0); + unsigned int val = random_get(); + v->valtype = INTEGER; + INT(v) = val % mod; + v->svalue = 0; + isetstr(v); + iret(it, v); + free(v->svalue); + free(v); + return 0; +} diff --git a/src/stdlib.c b/src/stdlib.c index 3f11d57..303db4d 100644 --- a/src/stdlib.c +++ b/src/stdlib.c @@ -1,6 +1,80 @@ +#include <stdlib.h> + +#include <ctype.h> +#include <stdarg.h> +#include <stdint.h> +#include <string.h> + +extern char *itoa(int, char *, int); + void _exit(int code) { (void)code; for (;;); } +char *snprintf(char *buf, unsigned int max, const char *format, ...) +{ + va_list args; + va_start(args, format); + + if (buf == 0 || max == 0) + return 0; + + static char nbuf[32]; + unsigned int off = 0; + for (unsigned int i = 0; format[i] != '\0' && off < max; i++) { + if (format[i] == '%') { + i++; + nbuf[0] = '\0'; + switch (format[i]) { + case 'd': + itoa(va_arg(args, int), nbuf, 10); + break; + case 'u': + itoa(va_arg(args, unsigned int), nbuf, 10); + break; + case 'x': + case 'p': + itoa(va_arg(args, unsigned int), nbuf, 16); + break; + case 'f': + itoa((int)va_arg(args, double), nbuf, 10); + break; + default: + buf[off++] = format[i]; + nbuf[0] = '\0'; + break; + } + if (nbuf[0] != '\0') { + for (unsigned int j = 0; off < max && + nbuf[j] != '\0'; off++, j++) + buf[off] = nbuf[j]; + } + } else { + buf[off++] = format[i]; + } + } + + + buf[off >= max ? max - 1 : off] = '\0'; + va_end(args); + return buf; +} + +float strtof(const char *s, char **endptr) +{ + (void)s; + (void)endptr; + return 0.0f; +} + +int atoi(const char *s) +{ + int n = 0; + for (unsigned int i = 0; isdigit(s[i]); i++) { + n *= 10; + n += s[i] - '0'; + } + return n; +} diff --git a/src/stm32l4xx_it.c b/src/stm32l4xx_it.c index ef10406..f643db3 100644 --- a/src/stm32l4xx_it.c +++ b/src/stm32l4xx_it.c @@ -1,20 +1,37 @@ #include <stm32l476xx.h>
-#include <lcd.h>
+#include <serial.h>
+#include <stdlib.h>
+#include <task.h>
+
+void serial_puts(const char *s)
+{
+ int i = 0;
+ while (s[i] != 0)
+ serial_put(s[i++]);
+}
void perror(const char *s)
{
- (void)s;//lcd_puts(s);
+ extern task_t *current;
+ serial_puts(s);
+ char buf[200];
+ snprintf(buf, 200, "xPSR: %x\r\nPC: %x\r\nLR: %x\r\n", current->sp[0],
+ current->sp[1], current->sp[2]);
+ serial_puts(buf);
}
+__attribute__ ((naked))
void NMI_Handler(void) {}
+__attribute__ ((naked))
void HardFault_Handler(void)
{
GPIOA->BSRR |= (1 << 5);
- perror("Hard Fault!");
+ //perror("Hard Fault!");
while (1);
}
+__attribute__ ((naked))
void MemManage_Handler(void)
{
GPIOA->BSRR |= (1 << 5);
@@ -22,6 +39,7 @@ void MemManage_Handler(void) while (1);
}
+__attribute__ ((naked))
void BusFault_Handler(void)
{
GPIOA->BSRR |= (1 << 5);
@@ -29,6 +47,7 @@ void BusFault_Handler(void) while (1);
}
+__attribute__ ((naked))
void UsageFault_Handler(void)
{
GPIOA->BSRR |= (1 << 5);
@@ -36,5 +55,6 @@ void UsageFault_Handler(void) while (1);
}
+__attribute__ ((naked))
void DebugMon_Handler(void) {}
@@ -2,13 +2,7 @@ #include <heap.h> #include <stm32l476xx.h> -typedef struct { - void *next; - uint32_t *stack; - uint32_t *sp; -} task_t; - -static task_t *current; +task_t *current; static uint8_t task_disable = 0; void task_hold(uint8_t hold) @@ -32,10 +26,20 @@ task_t *task_create(void (*code)(void), uint32_t stackSize) task_t *t = (task_t *)malloc(sizeof(task_t)); t->next = 0; t->stack = (uint32_t *)malloc(stackSize); - t->sp = (void *)t->stack + stackSize - 64;//16; - t->sp[13] = (uint32_t)task_exit; - t->sp[14] = (uint32_t)code; - t->sp[15] = 0x01000000; + void *sp = (uint8_t *)t->stack + stackSize - 68; // excep. stack + regs + t->sp = (uint32_t *)sp; + for (uint8_t i = 0; i < 14; i++) + t->sp[i] = 0; + t->sp[8] = 0xFFFFFFFD; + t->sp[14] = 0xFFFFFFFD; + t->sp[15] = (uint32_t)code; + t->sp[16] = 0x01000000; + + //void *sp = (uint8_t *)t->stack + stackSize - 64; // 16 words + //t->sp = (uint32_t *)sp; + //t->sp[13] = (uint32_t)task_exit; + //t->sp[14] = (uint32_t)code; + //t->sp[15] = 0x01000000; return t; } @@ -43,6 +47,8 @@ void task_init(void (*init)(void)) { current = task_create(init, 4096); current->next = current; + task_disable = 0; + // bit 0 - priv, bit 1 - psp/msp asm("\ msr psp, %0; \ @@ -50,14 +56,8 @@ void task_init(void (*init)(void)) orr r0, r0, #2; \ msr control, r0; \ isb; \ - " :: "r" (current->sp)); - - task_disable = 0; - init(); - /*asm("\ - cpsie i; \ - mov pc, %0; \ - " :: "r" (init + 4));*/ + bx %1; \ + " :: "r" (current->sp), "r" (init)); } void task_start(void (*task)(void), uint16_t stackSize) @@ -75,13 +75,29 @@ void PendSV_Handler(void) if (task_disable != 0) asm("bx lr"); - // save state + asm("\ + mrs r0, psp; \ + isb; \ + ldr r1, =current; \ + ldr r2, [r1]; \ + stmdb r0!, {r4-r11, r14}; \ + str r0, [r2, #8]; \ + ldr r0, [r2, #0]; \ + str r0, [r1]; \ + ldr r2, [r1]; \ + ldr r0, [r2, #8]; \ + ldmia r0!, {r4-r11, r14}; \ + msr psp, r0; \ + bx lr; \ + "); + + /*// save state asm("\ cpsid i; \ isb; \ dsb; \ mrs r0, psp; \ - stmdb r0!, {r4-r11}; \ + stmdb r0!, {r4-r11, lr}; \ mov %0, r0; \ " : "=r" (current->sp)); @@ -90,12 +106,12 @@ void PendSV_Handler(void) // restore asm("\ mov r0, %0; \ - ldmia r0!, {r4-r11}; \ + ldmia r0!, {r4-r11, lr}; \ msr psp, r0; \ isb; \ dsb; \ cpsie i; \ bx lr; \ - " :: "r" (current->sp)); + " :: "r" (current->sp));*/ } |