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)
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 " $<
#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);
--- /dev/null
+#ifndef RANDOM_H_
+#define RANDOM_H_
+
+#include <stdint.h>
+
+void random_init(void);
+uint32_t random_get(void);
+
+#endif // RANDOM_H_
--- /dev/null
+#ifndef SCRIPT_H_
+#define SCRIPT_H_
+
+#include <parser.h>
+
+void script_loadlib(interpreter *it);
+
+#endif // SCRIPT_H_
--- /dev/null
+#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_
#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.
-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)
#!/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
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;
// just keep counting
ticks++;
- if (!(ticks % 4))
+ if (!(ticks & 3))
SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk;
asm("mov lr, %0; bx lr" :: "r" (lr));
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);
void dsp_putchar(int c)
{
+ LOCK;
if (c == '\n') {
curx = 0;
if (++cury == 12) {
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)
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)
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;
y += sy;
}
}
- UNLOCK;
}
#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)
{
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;
}
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) {
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;
}
#include <display.h>\r
#include <display_draw.h>\r
#include <initrd.h>\r
-#include <serial.h>\r
#include <parser.h>\r
-#include <builtins.h>\r
-#include <stack.h>\r
+#include <serial.h>\r
#include <string.h>\r
+#include <script.h>\r
+#include <random.h>\r
\r
+extern uint8_t _ebss;\r
extern char *itoa(int, char *, int);\r
\r
void kmain(void);\r
+void task_interpreter(void);\r
\r
int main(void)\r
{\r
asm("cpsid i");\r
+ // disable write buffer\r
+ *((uint32_t *)0xE000E008) |= 2;\r
\r
- // prepare flash latency for 40MHz operation\r
+ // prepare flash latency for 80MHz 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
- extern uint8_t _ebss;\r
heap_init(&_ebss);\r
gpio_init();\r
+ serial_init();\r
+ random_init();\r
\r
gpio_mode(GPIOA, 5, OUTPUT);\r
\r
- serial_init();\r
-\r
// enable FPU\r
SCB->CPACR |= (0xF << 20);\r
\r
task_init(kmain);\r
-\r
while (1);\r
}\r
\r
-int script_puts(interpreter *it)\r
-{\r
- char *s = igetarg_string(it, 0);\r
- dsp_puts(s);\r
- //dsp_puts("\n");\r
- //asm("mov r0, %0; svc 2" :: "r" (s));\r
- return 0;\r
-}\r
-\r
-int script_gets(interpreter *it)\r
-{\r
- char *s = malloc(64), c[2] = {0, 0};\r
- uint16_t index = 0;\r
-\r
- do {\r
- c[0] = serial_get();\r
- s[index] = c[0];\r
- if (c[0] != '\r')\r
- dsp_puts(c);\r
- } while (s[index] != '\r' && index++ < 23);\r
- s[index] = '\0';\r
-\r
- variable *v = igetarg(it, 0);\r
- v->valtype = STRING;\r
- v->svalue = s;\r
- return 0;\r
-}\r
-\r
-int script_delay(interpreter *it)\r
-{\r
- int ms = igetarg_integer(it, 0);\r
- delay(ms);\r
- return 0;\r
-}\r
-\r
-int script_rect(interpreter *it)\r
-{\r
- dsp_rect(igetarg_integer(it, 0), igetarg_integer(it, 1),\r
- igetarg_integer(it, 2), igetarg_integer(it, 3),\r
- igetarg_integer(it, 4));\r
- return 0;\r
-}\r
-\r
-int script_line(interpreter *it)\r
-{\r
- dsp_line(igetarg_integer(it, 0), igetarg_integer(it, 1),\r
- igetarg_integer(it, 2), igetarg_integer(it, 3),\r
- igetarg_integer(it, 4));\r
- return 0;\r
-}\r
-\r
-int script_ppos(interpreter *it)\r
-{\r
- dsp_cpos(0, 0);\r
- dsp_coff(igetarg_integer(it, 0), igetarg_integer(it, 1));\r
- return 0;\r
-}\r
-\r
-int script_color(interpreter *it)\r
+void kmain(void)\r
{\r
- uint16_t c = dsp_color(igetarg_integer(it, 0), igetarg_integer(it, 1),\r
- igetarg_integer(it, 2));\r
- variable v;\r
- v.valtype = INTEGER;\r
- INT(&v) = c;\r
- v.svalue = 0;\r
- isetstr(&v);\r
- iret(it, &v);\r
- return 0;\r
-}\r
+ asm("cpsie i");\r
+ dsp_init();\r
+ dsp_rect(0, 0, LCD_WIDTH, LCD_HEIGHT, dsp_color(0, 0, 0));\r
+ dsp_cursoron();\r
+ task_start(task_interpreter, 4096);\r
\r
-int script_rand(interpreter *it)\r
-{\r
- static uint32_t next = 1;\r
- next = (next * 182 + 1829) % igetarg_integer(it, 0);\r
- variable v;\r
- v.valtype = INTEGER;\r
- INT(&v) = next;\r
- v.svalue = 0;\r
- isetstr(&v);\r
- iret(it, &v);\r
- return 0;\r
+ while (1) {\r
+ gpio_dout(GPIOA, 5, 1);\r
+ delay(250);\r
+ gpio_dout(GPIOA, 5, 0);\r
+ delay(250);\r
+ }\r
}\r
\r
void task_interpreter(void)\r
{\r
interpreter it;\r
iinit(&it);\r
- inew_cfunc(&it, "print", script_puts);\r
- inew_cfunc(&it, "gets", script_gets);\r
- inew_cfunc(&it, "delay", script_delay);\r
- inew_cfunc(&it, "rect", script_rect);\r
- inew_cfunc(&it, "ppos", script_ppos);\r
- inew_cfunc(&it, "line", script_line);\r
- inew_cfunc(&it, "color", script_color);\r
- inew_cfunc(&it, "rand", script_rand);\r
-\r
- /*int ret = 0;\r
- char *linebuf = malloc(100), c[2] = {0, 0};\r
- while (1) {\r
- uint16_t index = 0;\r
- if (it.indent > 0)\r
- dsp_puts(">");\r
- dsp_puts("> ");\r
- do {\r
- c[0] = serial_get();\r
- if (c[0] >= ' ' || c[0] == '\r') {\r
- linebuf[index] = c[0];\r
- if (c[0] >= ' ')\r
- dsp_puts(c);\r
- }\r
- } while (linebuf[index] != '\r' && index++ < 100);\r
- linebuf[index] = '\0';\r
- dsp_puts("\n");\r
- ret = idoline(&it, linebuf);\r
- if (ret < 0)\r
- break;\r
- }*/\r
+ script_loadlib(&it);\r
\r
char *s = initrd_getfile("init");\r
if (s == 0) {\r
char *linebuf = (char *)malloc(120);\r
uint32_t i = 0, prev = 0, lc;\r
uint32_t size = initrd_getfilesize("init");\r
- int ret;\r
+ int ret = 0;\r
while (i < size) {\r
for (; s[i] != '\n' && s[i] != '\0'; i++);\r
lc = i - prev;\r
}\r
strncpy(linebuf, s + prev, lc + 1);\r
linebuf[lc] = '\0';\r
- //task_hold(1);\r
ret = idoline(&it, linebuf);\r
- //task_hold(0);\r
if (ret < 0)\r
break;\r
prev = ++i;\r
delay(10);\r
}\r
\r
-void kmain(void)\r
-{\r
- asm("cpsie i");\r
- dsp_init();\r
- dsp_rect(0, 0, LCD_WIDTH, LCD_HEIGHT, dsp_color(0, 0, 0));\r
- dsp_cursoron();\r
- //dsp_puts("Hey.");\r
- task_start(task_interpreter, 4096);\r
-\r
- while (1) {\r
- gpio_dout(GPIOA, 5, 1);\r
- delay(500);\r
- gpio_dout(GPIOA, 5, 0);\r
- delay(500);\r
- }\r
-}\r
+// for interactive use\r
+/*int ret = 0;\r
+char *linebuf = malloc(100), c[2] = {0, 0};\r
+while (1) {\r
+ uint16_t index = 0;\r
+ if (it.indent > 0)\r
+ dsp_puts(">");\r
+ dsp_puts("> ");\r
+ do {\r
+ c[0] = serial_get();\r
+ if (c[0] >= ' ' || c[0] == '\r') {\r
+ linebuf[index] = c[0];\r
+ if (c[0] >= ' ')\r
+ dsp_puts(c);\r
+ }\r
+ } while (linebuf[index] != '\r' && index++ < 100);\r
+ linebuf[index] = '\0';\r
+ dsp_puts("\n");\r
+ ret = idoline(&it, linebuf);\r
+ if (ret < 0)\r
+ break;\r
+}*/\r
\r
+++ /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 <display.h>\r
-#include <display_draw.h>\r
-#include <initrd.h>\r
-#include <serial.h>\r
-#include <parser.h>\r
-#include <stack.h>\r
-\r
-#include <stdlib.h>\r
-#include <string.h>\r
-\r
-void kmain(void);\r
-void task_interpreter(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
- serial_init();\r
-\r
- // enable FPU\r
- SCB->CPACR |= (0xF << 20);\r
-\r
- task_init(kmain);\r
-\r
- while (1);\r
-}\r
-\r
-int script_puts(interpreter *it)\r
-{\r
- char *s = igetarg_string(it, 0);\r
- dsp_puts(s);\r
- //dsp_puts("\n");\r
- //asm("mov r0, %0; svc 2" :: "r" (s));\r
- return 0;\r
-}\r
-\r
-int script_gets(interpreter *it)\r
-{\r
- char *s = malloc(64), c[2] = {0, 0};\r
- uint16_t index = 0;\r
-\r
- do {\r
- c[0] = serial_get();\r
- s[index] = c[0];\r
- if (c[0] != '\r')\r
- dsp_puts(c);\r
- } while (s[index] != '\r' && index++ < 23);\r
- s[index] = '\0';\r
-\r
- variable *v = igetarg(it, 0);\r
- v->valtype = STRING;\r
- v->svalue = s;\r
- return 0;\r
-}\r
-\r
-int script_delay(interpreter *it)\r
-{\r
- int ms = igetarg_integer(it, 0);\r
- delay(ms);\r
- return 0;\r
-}\r
-\r
-int script_rect(interpreter *it)\r
-{\r
- dsp_rect(igetarg_integer(it, 0), igetarg_integer(it, 1),\r
- igetarg_integer(it, 2), igetarg_integer(it, 3),\r
- igetarg_integer(it, 4));\r
- return 0;\r
-}\r
-\r
-int script_line(interpreter *it)\r
-{\r
- dsp_line(igetarg_integer(it, 0), igetarg_integer(it, 1),\r
- igetarg_integer(it, 2), igetarg_integer(it, 3),\r
- igetarg_integer(it, 4));\r
- return 0;\r
-}\r
-\r
-int script_ppos(interpreter *it)\r
-{\r
- dsp_cpos(0, 0);\r
- dsp_coff(igetarg_integer(it, 0), igetarg_integer(it, 1));\r
- return 0;\r
-}\r
-\r
-void task_interpreter(void)\r
-{\r
- interpreter it;\r
- iinit(&it);\r
- inew_cfunc(&it, "print", script_puts);\r
- inew_cfunc(&it, "gets", script_gets);\r
- inew_cfunc(&it, "delay", script_delay);\r
- inew_cfunc(&it, "rect", script_rect);\r
- inew_cfunc(&it, "ppos", script_ppos);\r
- inew_cfunc(&it, "line", script_line);\r
-\r
- /*int ret = 0;\r
- char *linebuf = malloc(100), c[2] = {0, 0};\r
- while (1) {\r
- uint16_t index = 0;\r
- if (it.indent > 0)\r
- dsp_puts(">");\r
- dsp_puts("> ");\r
- do {\r
- c[0] = serial_get();\r
- if (c[0] >= ' ' || c[0] == '\r') {\r
- linebuf[index] = c[0];\r
- if (c[0] >= ' ')\r
- dsp_puts(c);\r
- }\r
- } while (linebuf[index] != '\r' && index++ < 100);\r
- linebuf[index] = '\0';\r
- dsp_puts("\n");\r
- ret = idoline(&it, linebuf);\r
- if (ret < 0)\r
- break;\r
- }*/\r
-\r
- char *s = initrd_getfile("init");\r
- if (s == 0)\r
- goto end;\r
-\r
- char *linebuf = (char *)malloc(120);\r
- uint32_t i = 0, prev = 0, lc;\r
- uint32_t size = initrd_getfilesize("init");\r
- int ret;\r
- while (i < size) {\r
- for (; s[i] != '\n' && s[i] != '\0'; i++);\r
- lc = i - prev;\r
- if (lc == 0) {\r
- prev = ++i;\r
- continue;\r
- }\r
- strncpy(linebuf, s + prev, lc + 1);\r
- linebuf[lc] = '\0';\r
- ret = idoline(&it, linebuf);\r
- if (ret < 0)\r
- break;\r
- prev = ++i;\r
- }\r
-\r
- if (ret < 0) {\r
- dsp_puts("\nError: ");\r
- dsp_puts(itoa(ret, linebuf, 10));\r
- }\r
- free(linebuf);\r
- //iend(&it); // nah\r
-\r
-end:\r
- while (1)\r
- delay(10);\r
-}\r
-\r
-void kmain(void)\r
-{\r
- asm("cpsie i");\r
-\r
- dsp_init();\r
-\r
- //dsp_rect(0, 0, 40, 40, dsp_color(0x7F, 0, 0x7F));\r
-\r
- //dsp_set_addr_read(0, 0, 39, 39);\r
- //dsp_dmode(INPUT);\r
- //uint8_t *buf = (uint8_t *)malloc(40 * 40 * 2);\r
- //for (int i = 0; i < 180; i++)\r
- // buf[i] = dsp_read_data();\r
- //dsp_dmode(OUTPUT);\r
- //dsp_set_addr(40, 40, 79, 79);\r
- //for (int i = 0; i < 320; i++)\r
- // dsp_write_data(buf[i]);\r
- //dsp_rect(80, 80, 40, 40, dsp_color(0x7F, 0x7F, 0));\r
-\r
- dsp_rect(0, 0, LCD_WIDTH, LCD_HEIGHT, dsp_color(0, 0, 0));\r
- dsp_cursoron();\r
-\r
- task_start(task_interpreter, 4096);\r
-\r
- //char *s = initrd_getfile("test.txt");\r
-\r
- while (1) {\r
- gpio_dout(GPIOA, 5, 1);\r
- delay(500);\r
- gpio_dout(GPIOA, 5, 0);\r
- delay(500);\r
- }\r
-}\r
-\r
--- /dev/null
+#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;
+}
--- /dev/null
+#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;
+}
+#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;
+}
#include <stm32l476xx.h>\r
-#include <lcd.h>\r
+#include <serial.h>\r
+#include <stdlib.h>\r
+#include <task.h>\r
+\r
+void serial_puts(const char *s)\r
+{\r
+ int i = 0;\r
+ while (s[i] != 0)\r
+ serial_put(s[i++]);\r
+}\r
\r
void perror(const char *s)\r
{\r
- (void)s;//lcd_puts(s);\r
+ extern task_t *current;\r
+ serial_puts(s);\r
+ char buf[200];\r
+ snprintf(buf, 200, "xPSR: %x\r\nPC: %x\r\nLR: %x\r\n", current->sp[0],\r
+ current->sp[1], current->sp[2]);\r
+ serial_puts(buf);\r
}\r
\r
+__attribute__ ((naked))\r
void NMI_Handler(void) {}\r
\r
+__attribute__ ((naked))\r
void HardFault_Handler(void)\r
{\r
GPIOA->BSRR |= (1 << 5);\r
- perror("Hard Fault!");\r
+ //perror("Hard Fault!");\r
while (1);\r
}\r
\r
+__attribute__ ((naked))\r
void MemManage_Handler(void)\r
{\r
GPIOA->BSRR |= (1 << 5);\r
while (1);\r
}\r
\r
+__attribute__ ((naked))\r
void BusFault_Handler(void)\r
{\r
GPIOA->BSRR |= (1 << 5);\r
while (1);\r
}\r
\r
+__attribute__ ((naked))\r
void UsageFault_Handler(void)\r
{\r
GPIOA->BSRR |= (1 << 5);\r
while (1);\r
}\r
\r
+__attribute__ ((naked))\r
void DebugMon_Handler(void) {}\r
\r
#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)
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;
}
{
current = task_create(init, 4096);
current->next = current;
+ task_disable = 0;
+
// bit 0 - priv, bit 1 - psp/msp
asm("\
msr psp, %0; \
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)
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));
// 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));*/
}