keypad support, making stuff good

master
Clyne Sullivan 7 years ago
parent 4614429f57
commit 51b884c44c

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

@ -1,46 +1,116 @@
/**
* @file gpio.h
* Abstracts gpio access, makes things easier
*/
#ifndef GPIO_H_
#define GPIO_H_
#include <stm32l476xx.h>
/**
* 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_

@ -1,12 +1,40 @@
/**
* @file heap.h
* A basic memory manager
*/
#ifndef HEAP_H_
#define HEAP_H_
#include <stdint.h>
/**
* 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_

@ -0,0 +1,24 @@
#ifndef KEYPAD_H_
#define KEYPAD_H_
#include <stdint.h>
#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_

@ -1,9 +1,22 @@
/**
* @file random.h
* Provides true random number generation functionality
*/
#ifndef RANDOM_H_
#define RANDOM_H_
#include <stdint.h>
/**
* 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_

@ -1,8 +1,17 @@
/**
* @file script.h
* Provides script library for using calculator hardware
*/
#ifndef SCRIPT_H_
#define SCRIPT_H_
#include <parser.h>
/**
* Loads the library for the given interpreter.
* @param it the interpreter to use
*/
void script_loadlib(interpreter *it);
#endif // SCRIPT_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_

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

@ -1,4 +0,0 @@
#!/bin/bash
echo "Making initrd.img..."
rm -f initrd.img
arm-none-eabi-ar r initrd.img initrd/*

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

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

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

@ -0,0 +1,63 @@
#include <keypad.h>
#include <gpio.h>
#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);
}

@ -12,6 +12,7 @@
#include <string.h>
#include <script.h>
#include <random.h>
#include <keypad.h>
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);*/
}
}

@ -8,6 +8,7 @@
#include <random.h>
#include <serial.h>
#include <stack.h>
#include <keypad.h>
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;
}

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

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

Loading…
Cancel
Save