diff --git a/Makefile b/Makefile index 8b0d09b..b5b2f21 100644 --- a/Makefile +++ b/Makefile @@ -3,11 +3,12 @@ CC = gcc AS = as AR = ar OBJCOPY = objcopy +STRIP = strip MCUFLAGS = -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 AFLAGS = $(MCUFLAGS) CFLAGS = $(MCUFLAGS) -ggdb \ - -Iinclude -Iinclude/it \ + -Iinclude -Iinclude/it -Iinclude/cmsis \ -fno-builtin -fsigned-char -ffreestanding \ -Wall -Werror -Wextra -pedantic \ -Wno-overlength-strings -Wno-discarded-qualifiers @@ -21,13 +22,17 @@ OFILES = $(patsubst src/%.c, $(OUTDIR)/%.o, $(CFILES)) \ $(patsubst src/%.s, $(OUTDIR)/%.asm.o, $(AFILES)) OUT = out/main.elf +INITRD = initrd.img all: $(OUT) +#@$(CROSS)$(STRIP) --only-keep-debug $(OUT) $(OUT): $(OFILES) initrd/init libinterp.a + @echo " INITRD " $(INITRD) + @rm -f $(INITRD) + @$(CROSS)$(AR) r $(INITRD) initrd/* + @$(CROSS)$(OBJCOPY) -B arm -I binary -O elf32-littlearm $(INITRD) out/initrd.img.o @echo " LINK " $(OUT) - @./mkinitrd.sh - @$(CROSS)$(OBJCOPY) -B arm -I binary -O elf32-littlearm initrd.img out/initrd.img.o @$(CROSS)$(CC) $(CFLAGS) $(LFLAGS) out/*.o -o $(OUT) -L. -linterp $(OUTDIR)/%.o: src/%.c diff --git a/include/cmsis_gcc.h b/include/cmsis/cmsis_gcc.h similarity index 100% rename from include/cmsis_gcc.h rename to include/cmsis/cmsis_gcc.h diff --git a/include/core_cm4.h b/include/cmsis/core_cm4.h similarity index 100% rename from include/core_cm4.h rename to include/cmsis/core_cm4.h diff --git a/include/core_cmFunc.h b/include/cmsis/core_cmFunc.h similarity index 100% rename from include/core_cmFunc.h rename to include/cmsis/core_cmFunc.h diff --git a/include/core_cmInstr.h b/include/cmsis/core_cmInstr.h similarity index 100% rename from include/core_cmInstr.h rename to include/cmsis/core_cmInstr.h diff --git a/include/core_cmSimd.h b/include/cmsis/core_cmSimd.h similarity index 100% rename from include/core_cmSimd.h rename to include/cmsis/core_cmSimd.h diff --git a/include/gpio.h b/include/gpio.h index 524b791..46a8e15 100644 --- a/include/gpio.h +++ b/include/gpio.h @@ -1,46 +1,116 @@ +/** + * @file gpio.h + * Abstracts gpio access, makes things easier + */ + #ifndef GPIO_H_ #define GPIO_H_ #include +/** + * Helps simplify gpio calls. + * @param p port, e.g. GPIOA + * @param b pin, e.g. 4 + */ #define GPIO_PORT(p, b) GPIO##p, b +/** + * Defines possible modes for a gpio pin + */ enum GPIO_MODE { - INPUT = 0, - OUTPUT, - ALTERNATE, - ANALOG + INPUT = 0, /**< digital input */ + OUTPUT, /**< digital output */ + ALTERNATE, /**< alternate function */ + ANALOG /**< analog function */ }; +/** + * Defines whether to use push-pull or open drain. + */ enum GPIO_TYPE { - PUSHPULL = 0, - OPENDRAIN + PUSHPULL = 0, /**< push-pull */ + OPENDRAIN /**< open drain */ }; +/** + * Defines the pin's speed + */ enum GPIO_SPEED { - LOW = 0, - MEDIUM, - HIGH, - VERYHIGH + LOW = 0, /**< low */ + MEDIUM, /**< medium */ + HIGH, /**< high */ + VERYHIGH /**< very high/maximum */ }; +/** + * Defines if a pullup or pulldown should be used. + */ enum GPIO_PUPD { - NOPUPD, - PULLUP, - PULLDOWN + NOPUPD, /**< no pullup/pulldown */ + PULLUP, /**< use pullup */ + PULLDOWN /**< use pulldown */ }; +/** + * Initializes the gpio. + */ void gpio_init(void); +/** + * Enables or disables pullup/pulldown for the given pin. + * @param port the port, e.g. GPIOA + * @param pin the pin + * @param pupd pullup/pulldown enable + * @see GPIO_PUPD + */ void gpio_pupd(GPIO_TypeDef *port, uint8_t pin, uint8_t pupd); + +/** + * Sets whether to use push-pull or open drain for the given pin. + * @param port the port + * @param pin the pin + * @param type what to use + * @see GPIO_TYPE + */ void gpio_type(GPIO_TypeDef *port, uint8_t pin, uint8_t type); + +/** + * Sets the pin's speed. + * @param port the port + * @param pin the pin + * @param speed the speed to use + * @see GPIO_SPEED + */ void gpio_speed(GPIO_TypeDef *port, uint8_t pin, uint8_t speed); + +/** + * Sets the pin's i/o mode. + * @param port the port + * @param pin the pin + * @param mode the mode to use + * @see GPIO_MODE + */ void gpio_mode(GPIO_TypeDef *port, uint8_t pin, uint8_t mode); + +/** + * Sets the state of a digital output pin. + * @param port the port + * @param pin the pin + * @param val non-zero for high, zero for low + */ void gpio_dout(GPIO_TypeDef *port, uint8_t pin, uint8_t val); + +/** + * Reads a digital input pin. + * @param port the port + * @param pin the pin + * @return non-zero for high, zero for low + */ uint8_t gpio_din(GPIO_TypeDef *port, uint8_t pin); #endif // GPIO_H_ diff --git a/include/heap.h b/include/heap.h index c93eb8e..e8cd9c1 100644 --- a/include/heap.h +++ b/include/heap.h @@ -1,12 +1,40 @@ +/** + * @file heap.h + * A basic memory manager + */ + #ifndef HEAP_H_ #define HEAP_H_ #include +/** + * Initializes memory management of the given heap. + * No overflow stuff is done, so... + * @param buf the heap to use for allocations + */ void heap_init(void *buf); +/** + * Allocates a chunk of memory. + * @param size how many bytes to claim + * @return pointer to the allocated buffer + */ void *malloc(uint32_t size); + +/** + * Allocates and zeros a chunk of memory. + * @param count how many of whatever to allocate + * @param size byte count of each whatever + * @return pointer to the allocated buffer + */ void *calloc(uint32_t count, uint32_t size); + +/** + * Frees the buffer allocated through malloc/calloc. + * Please don't double-free. + * @param the buffer to release + */ void free(void *buf); #endif // HEAP_H_ diff --git a/include/keypad.h b/include/keypad.h new file mode 100644 index 0000000..83e0626 --- /dev/null +++ b/include/keypad.h @@ -0,0 +1,24 @@ +#ifndef KEYPAD_H_ +#define KEYPAD_H_ + +#include + +#define K0 (1 << 0) +#define K1 (1 << 1) +#define K2 (1 << 2) +#define K3 (1 << 3) +#define K4 (1 << 4) +#define K5 (1 << 5) +#define K6 (1 << 6) +#define K7 (1 << 7) +#define K8 (1 << 8) +#define K9 (1 << 9) +#define KS (1 << 10) +#define KP (1 << 11) + +void keypad_init(void); + +uint16_t keypad_get(void); +uint8_t keypad_isdown(uint16_t); + +#endif // KEYPAD_H_ diff --git a/include/random.h b/include/random.h index 6485f26..a1868f6 100644 --- a/include/random.h +++ b/include/random.h @@ -1,9 +1,22 @@ +/** + * @file random.h + * Provides true random number generation functionality + */ + #ifndef RANDOM_H_ #define RANDOM_H_ #include +/** + * Initializes the STM's true random number generator. + */ void random_init(void); + +/** + * Gets the next random number from the generator. + * @return the random number + */ uint32_t random_get(void); #endif // RANDOM_H_ diff --git a/include/script.h b/include/script.h index dc8c590..7901c9c 100644 --- a/include/script.h +++ b/include/script.h @@ -1,8 +1,17 @@ +/** + * @file script.h + * Provides script library for using calculator hardware + */ + #ifndef SCRIPT_H_ #define SCRIPT_H_ #include +/** + * Loads the library for the given interpreter. + * @param it the interpreter to use + */ void script_loadlib(interpreter *it); #endif // SCRIPT_H_ diff --git a/include/task.h b/include/task.h index 1ef8639..6456bdc 100644 --- a/include/task.h +++ b/include/task.h @@ -28,6 +28,12 @@ void task_init(void (*init)(void)); */ void task_start(void (*task)(void), uint16_t stackSize); +/** + * Allows task switching to be disabled, for low-level actions. + * Multiple holds can be placed, and all must be removed to continue task + * switching. + * @param hold non-zero for hold, zero to remove hold + */ void task_hold(uint8_t hold); #endif // TASK_H_ diff --git a/initrd/init b/initrd/init index 9f6a9cf..fcf9ec2 100644 --- a/initrd/init +++ b/initrd/init @@ -1,11 +1,14 @@ do - rand 479 > x - rand 319 > y - rand 479 > i - rand 319 > j - rand 32767 > purple + getkey > input + if (input & 4) + rand 479 > x + rand 319 > y + rand 479 > i + rand 319 > j + rand 32767 > purple - line x y i j purple + line x y i j purple + end while (1) print "done" diff --git a/mkinitrd.sh b/mkinitrd.sh deleted file mode 100755 index eb47fd8..0000000 --- a/mkinitrd.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -echo "Making initrd.img..." -rm -f initrd.img -arm-none-eabi-ar r initrd.img initrd/* diff --git a/src/clock.c b/src/clock.c index 3d31f91..0c8ca7c 100644 --- a/src/clock.c +++ b/src/clock.c @@ -7,7 +7,7 @@ #define STK_CALIB *((uint32_t *)0xE000E01C) // ticks since init -static uint32_t ticks = 0; +volatile uint32_t ticks = 0; void clock_init(void) { @@ -31,6 +31,7 @@ void clock_init(void) // set system clock to PLL RCC->CFGR &= ~(RCC_CFGR_SW); + RCC->CFGR &= ~(RCC_CFGR_HPRE_Msk); RCC->CFGR |= RCC_CFGR_SW_PLL; while ((RCC->CFGR & RCC_CFGR_SWS_PLL) != RCC_CFGR_SWS_PLL); @@ -45,18 +46,12 @@ void delay(uint32_t 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 & 3)) SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk; - - asm("mov lr, %0; bx lr" :: "r" (lr)); } diff --git a/src/display_draw.c b/src/display_draw.c index 27ed796..a315bf7 100644 --- a/src/display_draw.c +++ b/src/display_draw.c @@ -92,12 +92,12 @@ void dsp_rect(int x, int y, int w, int h, uint16_t color) { dsp_set_addr(x, y, x + w - 1, y + h - 1); int countdown = w * h; + LOCK; 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) diff --git a/src/gpio.c b/src/gpio.c index c2617ee..900a3f1 100644 --- a/src/gpio.c +++ b/src/gpio.c @@ -32,10 +32,7 @@ void gpio_mode(GPIO_TypeDef *port, uint8_t pin, uint8_t mode) void gpio_dout(GPIO_TypeDef *port, uint8_t pin, uint8_t val) { - if (val) - port->BSRR |= (1 << pin); - else - port->BRR |= (1 << pin); + port->BSRR |= (1 << (val ? pin : pin + 16)); } uint8_t gpio_din(GPIO_TypeDef *port, uint8_t pin) diff --git a/src/keypad.c b/src/keypad.c new file mode 100644 index 0000000..41fc924 --- /dev/null +++ b/src/keypad.c @@ -0,0 +1,63 @@ +#include +#include + +#define PIN_0 GPIO_PORT(A, 11) +#define PIN_1 GPIO_PORT(B, 13) +#define PIN_2 GPIO_PORT(B, 2) +#define PIN_3 GPIO_PORT(A, 12) +#define PIN_4 GPIO_PORT(B, 14) +#define PIN_5 GPIO_PORT(B, 11) +#define PIN_6 GPIO_PORT(C, 5) +#define PIN_7 GPIO_PORT(B, 15) +#define PIN_8 GPIO_PORT(B, 12) +#define PIN_9 GPIO_PORT(C, 6) +#define PIN_S GPIO_PORT(B, 1) +#define PIN_P GPIO_PORT(C, 8) + +typedef struct { + GPIO_TypeDef *port; + uint16_t pin; + uint16_t keycode; +} key_t; + +static const key_t keypad_map[12] = { + { PIN_0, K0 }, + { PIN_1, K1 }, + { PIN_2, K2 }, + { PIN_3, K3 }, + { PIN_4, K4 }, + { PIN_5, K5 }, + { PIN_6, K6 }, + { PIN_7, K7 }, + { PIN_8, K8 }, + { PIN_9, K9 }, + { PIN_S, KS }, + { PIN_P, KP } +}; + +void keypad_init(void) +{ + for (uint8_t i = 0; i < 12; i++) { + GPIO_TypeDef *p = keypad_map[i].port; + uint16_t pin = keypad_map[i].pin; + gpio_mode(p, pin, OUTPUT); + gpio_dout(p, pin, 0); + gpio_mode(p, pin, INPUT); + gpio_pupd(p, pin, PULLDOWN); + } +} + +uint16_t keypad_get(void) +{ + uint16_t state = 0; + for (uint8_t i = 0; i < 12; i++) { + if (gpio_din(keypad_map[i].port, keypad_map[i].pin)) + state |= keypad_map[i].keycode; + } + return state; +} + +uint8_t keypad_isdown(uint16_t keycode) +{ + return (keypad_get() & keycode); +} diff --git a/src/main.c b/src/main.c index 54c2403..abcb8e6 100644 --- a/src/main.c +++ b/src/main.c @@ -12,6 +12,7 @@ #include #include #include +#include extern uint8_t _ebss; extern char *itoa(int, char *, int); @@ -22,24 +23,27 @@ void task_interpreter(void); int main(void) { asm("cpsid i"); - // disable write buffer - *((uint32_t *)0xE000E008) |= 2; // 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(); heap_init(&_ebss); gpio_init(); + keypad_init(); serial_init(); random_init(); + //extern void keypad_init(void); + //keypad_init(); + gpio_mode(GPIOA, 5, OUTPUT); // enable FPU SCB->CPACR |= (0xF << 20); + // enable MPU + //MPU->CTRL |= MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_ENABLE_Msk; task_init(kmain); while (1); @@ -47,17 +51,18 @@ int main(void) void kmain(void) { - 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); while (1) { - gpio_dout(GPIOA, 5, 1); + gpio_dout(GPIOA, 5, + (keypad_isdown(K0))); + /*gpio_dout(GPIOA, 5, 1); delay(250); gpio_dout(GPIOA, 5, 0); - delay(250); + delay(250);*/ } } diff --git a/src/script.c b/src/script.c index adf402b..78165b0 100644 --- a/src/script.c +++ b/src/script.c @@ -8,6 +8,7 @@ #include #include #include +#include int script_puts(interpreter *it); int script_gets(interpreter *it); @@ -17,6 +18,7 @@ int script_ppos(interpreter *it); int script_line(interpreter *it); int script_color(interpreter *it); int script_rand(interpreter *it); +int script_getkey(interpreter *it); void script_loadlib(interpreter *it) { @@ -28,6 +30,7 @@ void script_loadlib(interpreter *it) inew_cfunc(it, "line", script_line); inew_cfunc(it, "color", script_color); inew_cfunc(it, "rand", script_rand); + inew_cfunc(it, "getkey", script_getkey); } int script_puts(interpreter *it) @@ -118,3 +121,16 @@ int script_rand(interpreter *it) free(v); return 0; } + +int script_getkey(interpreter *it) +{ + variable *v = (variable *)malloc(sizeof(variable)); + v->valtype = INTEGER; + INT(v) = keypad_get(); + v->svalue = 0; + isetstr(v); + iret(it, v); + free(v->svalue); + free(v); + return 0; +} diff --git a/src/stm32l4xx_it.c b/src/stm32l4xx_it.c index f643db3..e54a192 100644 --- a/src/stm32l4xx_it.c +++ b/src/stm32l4xx_it.c @@ -12,12 +12,12 @@ void serial_puts(const char *s) void perror(const char *s) { - extern task_t *current; + //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); + //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)) @@ -27,7 +27,7 @@ __attribute__ ((naked)) void HardFault_Handler(void) { GPIOA->BSRR |= (1 << 5); - //perror("Hard Fault!"); + perror("Hard Fault!"); while (1); } diff --git a/src/task.c b/src/task.c index 6a755de..537785d 100644 --- a/src/task.c +++ b/src/task.c @@ -34,12 +34,6 @@ task_t *task_create(void (*code)(void), uint32_t stackSize) 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; } @@ -53,7 +47,8 @@ void task_init(void (*init)(void)) asm("\ msr psp, %0; \ mrs r0, control; \ - orr r0, r0, #2; \ + orr r0, r0, #3; \ + cpsie i; \ msr control, r0; \ isb; \ bx %1; \