cleaner main, random nums, perfect script run

master
Clyne Sullivan 7 years ago
parent 9f61013faf
commit 4614429f57

@ -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 " $<

@ -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);

@ -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_

@ -0,0 +1,8 @@
#ifndef SCRIPT_H_
#define SCRIPT_H_
#include <parser.h>
void script_loadlib(interpreter *it);
#endif // SCRIPT_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_

@ -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.

@ -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)
rand 479 > x
rand 319 > y
rand 479 > i
rand 319 > j
rand 32767 > purple
set y 50
do
line 230 y 250 y fg
set y (y + 20)
while (y < 270)
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)

Binary file not shown.

@ -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

@ -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));

@ -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);

@ -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;
}

@ -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;
}*/

@ -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);
}
}

@ -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;
}

@ -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;
}

@ -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;
}

@ -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));*/
}

Loading…
Cancel
Save