file cleanup, better text, documentation

master
Clyne Sullivan 7 years ago
parent 5df5c67397
commit c47485371a

@ -21,9 +21,6 @@
CROSS = arm-none-eabi- CROSS = arm-none-eabi-
CC = gcc CC = gcc
AS = as AS = as
AR = tools/rba
OBJCOPY = objcopy
STRIP = strip
MCUFLAGS = -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 MCUFLAGS = -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16
AFLAGS = $(MCUFLAGS) AFLAGS = $(MCUFLAGS)
@ -42,15 +39,10 @@ OFILES = $(patsubst src/%.c, $(OUTDIR)/%.o, $(CFILES)) \
$(patsubst src/%.s, $(OUTDIR)/%.asm.o, $(AFILES)) $(patsubst src/%.s, $(OUTDIR)/%.asm.o, $(AFILES))
OUT = out/main.elf OUT = out/main.elf
INITRD = initrd.img
all: $(OUT) all: $(OUT)
$(OUT): $(OFILES) initrd/* libinterp.a $(OUT): $(OFILES)
@echo " INITRD " $(INITRD)
@rm -f $(INITRD)
@$(AR) $(INITRD) initrd/*
@$(CROSS)$(OBJCOPY) -B arm -I binary -O elf32-littlearm $(INITRD) out/initrd.img.o
@echo " LINK " $(OUT) @echo " LINK " $(OUT)
@$(CROSS)$(CC) $(CFLAGS) $(LFLAGS) out/*.o -o $(OUT) -L. -linterp -lm @$(CROSS)$(CC) $(CFLAGS) $(LFLAGS) out/*.o -o $(OUT) -L. -linterp -lm

@ -1,13 +1,71 @@
/*
* @file display_text.h
* A text-rendering/managing library to work with the display
*
* Copyright (C) 2018 Clyne Sullivan
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef DISPLAY_TEXT_H_ #ifndef DISPLAY_TEXT_H_
#define DISPLAY_TEXT_H_ #define DISPLAY_TEXT_H_
/**
* The number of existing buffers.
*/
#define TTY_COUNT 2
/**
* Initializes text buffers and starts the blinking cursor.
* Must call before using other functions in this file.
*/
void text_init(void); void text_init(void);
/**
* Switches to the i'th buffer.
* The display shows text from a buffer that has data and a position. By
* switching buffers, current text (and position in the text) can be preserved
* and switched back to later.
* @param i the buffer to switch to
*/
void text_switch(unsigned int i); void text_switch(unsigned int i);
/**
* Puts a string of text to the display/current buffer.
* The cursor advances, and the buffer scrolls if the end of it is reached.
* @param s the string to put
*/
void text_puts(const char *s); void text_puts(const char *s);
/**
* Clears the display/current buffer.
*/
void text_clear(void); void text_clear(void);
/**
* Sets the cursor's position.
* @param x the x position to move to
* @param y the y position to move to
*/
void text_setpos(uint8_t x, uint8_t y); void text_setpos(uint8_t x, uint8_t y);
/**
* Moves the cursor relative to its current position.
* Can move in both positive and negative directions.
* @param x how many characters to move in the x direction
* @param y how many characters to move in the y direction
*/
void text_relpos(int8_t x, int8_t y); void text_relpos(int8_t x, int8_t y);
#endif // DISPLAY_TEXT_H_ #endif // DISPLAY_TEXT_H_

@ -1,11 +1,36 @@
/**
* @file fat32.h
* A very basic FAT32 reading implementation
* This only supports reading files in the root directory. Currently, the files
* must also have a name under eight characters, with no extension.
*
* Copyright (C) 2018 Clyne Sullivan
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef FAT32_H_ #ifndef FAT32_H_
#define FAT32_H_ #define FAT32_H_
#include <stdint.h> #include <stdint.h>
/**
* A structure to store important information for loading a file.
*/
typedef struct { typedef struct {
uint32_t size; uint32_t size; /**< The file's size in bytes */
uint32_t start; uint32_t start; /**< The file's first data cluster */
} file_t; } file_t;
/** /**
@ -22,10 +47,17 @@ int fat_find(void);
file_t *fat_findfile(const char *name); file_t *fat_findfile(const char *name);
/** /**
* * Reads given file into an allocated buffer.
* @param file the file's data structure from fat_findfile()
* @return a malloc'd buffer containing the file's data
*/ */
char *fat_readfile(file_t *file); char *fat_readfile(file_t *file);
/**
* Gets the name of the nth file in the root directory.
* @param index n, the index of the file
* @return the file's name, in a malloc'd buffer
*/
char *fat_getname(uint32_t index); char *fat_getname(uint32_t index);
#endif // FAT32_H_ #endif // FAT32_H_

@ -1,5 +1,5 @@
/** /**
* @file sdcard.c * @file sdcard.h
* Provides a basic library for accessing an SD card * Provides a basic library for accessing an SD card
* *
* Copyright (C) 2018 Clyne Sullivan * Copyright (C) 2018 Clyne Sullivan

@ -1,4 +1,5 @@
while (1) { while (1) {
#tty(1)
print("Free mem: ") print("Free mem: ")
print(freemem()) print(freemem())
print("\n") print("\n")

Binary file not shown.

@ -1,3 +1,22 @@
/*
* @file display_text.c
* A text-rendering/managing library to work with the display
*
* Copyright (C) 2018 Clyne Sullivan
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <clock.h> #include <clock.h>
#include <task.h> #include <task.h>
@ -8,8 +27,6 @@
#define WIDTH 40 #define WIDTH 40
#define HEIGHT 18 #define HEIGHT 18
#define TTY_COUNT 2
typedef struct { typedef struct {
char *buf; char *buf;
uint8_t x; uint8_t x;
@ -51,25 +68,19 @@ void text_init(void)
void text_redraw(void) void text_redraw(void)
{ {
for (unsigned int i = 0; i < WIDTH; i++) {
//unsigned int zc = 0;
for (unsigned int j = 0; j < HEIGHT; j++) { for (unsigned int j = 0; j < HEIGHT; j++) {
int c = text_current->buf[i + j * WIDTH]; unsigned int i = WIDTH;
/*if (c == '\0') { //for (; i > 0 && text_current->buf[j * WIDTH + i - 1] == '\0'; i--);
if (++zc == 3) for (; i > 0; i--) {
break; int c = text_current->buf[j * WIDTH + i - 1];
} else if (zc > 0) { dsp_putchar(c, i - 1, j);
zc = 0;
}*/
dsp_putchar(c, i, j);
} }
} }
} }
void text_switch(unsigned int i) void text_switch(unsigned int i)
{ {
if (i >= TTY_COUNT) if (i >= TTY_COUNT || text_current == text_tty + i)
return; return;
text_current = &text_tty[i]; text_current = &text_tty[i];
@ -78,10 +89,14 @@ void text_switch(unsigned int i)
void text_clear(void) void text_clear(void)
{ {
for (unsigned int i = 0; i < WIDTH; i++) {
for (unsigned int j = 0; j < HEIGHT; j++) { for (unsigned int j = 0; j < HEIGHT; j++) {
text_current->buf[i + j * WIDTH] = 0; for (unsigned int i = 0; i < WIDTH; i++) {
//int c = text_current->buf[j * WIDTH + 1];
//if (c != 0) {
text_current->buf[j * WIDTH + i] = 0;
dsp_putchar(' ', i, j); dsp_putchar(' ', i, j);
//}
} }
} }
text_current->x = 0; text_current->x = 0;
@ -131,7 +146,21 @@ void text_putchar(int c)
for (int i = 0; i < WIDTH; i++) for (int i = 0; i < WIDTH; i++)
text_current->buf[i + y * WIDTH] = 0; text_current->buf[i + y * WIDTH] = 0;
text_redraw(); for (int j = HEIGHT - 1; j >= 0; j--) {
int i = WIDTH - 1;
if (j > 0) {
for (; i >= 0; i--) {
int p = text_current->buf[(j - 1) * WIDTH + i];
int c = text_current->buf[j * WIDTH + i];
if (p != '\0' || c != '\0')
break;
}
}
for (; i >= 0; i--) {
int c = text_current->buf[j * WIDTH + i];
dsp_putchar(c, i, j);
}
}
} }
text_current->x = x; text_current->x = x;

@ -1,5 +1,21 @@
/** /**
* Implementation of a driver to read a FAT32 filesystem. * @file fat32.h
* A very basic FAT32 reading implementation
*
* Copyright (C) 2018 Clyne Sullivan
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
#include <ctype.h> #include <ctype.h>

@ -1,3 +1,23 @@
/**
* @file flash.c
* Provides functionality for using an external SPI flash
*
* Copyright (C) 2018 Clyne Sullivan
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <clock.h> #include <clock.h>
#include <gpio.h> #include <gpio.h>
#include <heap.h> #include <heap.h>

@ -61,7 +61,7 @@ static const port_t keypad_cols[COLS] = {
static const char keypad_map[ROWS * COLS * 4] = { static const char keypad_map[ROWS * COLS * 4] = {
"\x7F\0\0\0" "\xFF\0\0\0" "\xFF\x02\0\0" "\x19\0\0\0" "\x18\0\0\0" "\x7F\0\0\0" "\xFF\0\0\0" "\xFF\x02\0\0" "\x19\0\0\0" "\x18\0\0\0"
"sin\0" "cos\0" "tan\0" "\x1B\0\0\0" "\x1A\0\0\0" "\x11\0\0\0" "\x12\0\0\0" "\x13\0\0\0" "\x1B\0\0\0" "\x1A\0\0\0"
"7\0\0\0" "8\0\0\0" "9\0\0\0" "(\0\0\0" ")\0\0\0" "7\0\0\0" "8\0\0\0" "9\0\0\0" "(\0\0\0" ")\0\0\0"
"4\0\0\0" "5\0\0\0" "6\0\0\0" "/\0\0\0" "*\0\0\0" "4\0\0\0" "5\0\0\0" "6\0\0\0" "/\0\0\0" "*\0\0\0"
"1\0\0\0" "2\0\0\0" "3\0\0\0" "-\0\0\0" "+\0\0\0" "1\0\0\0" "2\0\0\0" "3\0\0\0" "-\0\0\0" "+\0\0\0"
@ -69,12 +69,12 @@ static const char keypad_map[ROWS * COLS * 4] = {
}; };
static const char keypad_map_2nd[ROWS * COLS * 4] = { static const char keypad_map_2nd[ROWS * COLS * 4] = {
"\x7F\0\0\0" "pi\0\0" "X\0\0\0" "Y\0\0\0" "Z\0\0\0" "\x7F\0\0\0" "\xFF\x01\0\0" "X\0\0\0" "Y\0\0\0" "Z\0\0\0"
"A\0\0\0" "B\0\0\0" "C\0\0\0" "D\0\0\0" "E\0\0\0" "A\0\0\0" "B\0\0\0" "C\0\0\0" "D\0\0\0" "E\0\0\0"
"F\0\0\0" "G\0\0\0" "H\0\0\0" "I\0\0\0" "J\0\0\0" "F\0\0\0" "G\0\0\0" "H\0\0\0" "I\0\0\0" "J\0\0\0"
"K\0\0\0" "L\0\0\0" "M\0\0\0" "N\0\0\0" "O\0\0\0" "K\0\0\0" "L\0\0\0" "M\0\0\0" "N\0\0\0" "O\0\0\0"
"P\0\0\0" "Q\0\0\0" "R\0\0\0" "S\0\0\0" "T\0\0\0" "P\0\0\0" "Q\0\0\0" "R\0\0\0" "S\0\0\0" "T\0\0\0"
"U\0\0\0" "V\0\0\0" "W\0\0\0" "\b\0\0\0" "\xFF\x01\0\0" "U\0\0\0" "V\0\0\0" "W\0\0\0" "\b\0\0\0" "\n\0\0\0"
}; };
#define KEY(r, c, i) map[r * COLS * 4 + c * 4 + i] #define KEY(r, c, i) map[r * COLS * 4 + c * 4 + i]

@ -26,9 +26,7 @@
#include <flash.h> #include <flash.h>
#include <gpio.h> #include <gpio.h>
#include <heap.h> #include <heap.h>
#include <initrd.h>
#include <keypad.h> #include <keypad.h>
#include <lcd.h>
#include <it/parser.h> #include <it/parser.h>
#include <random.h> #include <random.h>
#include <script.h> #include <script.h>
@ -55,6 +53,7 @@ int main(void)
FLASH->ACR &= ~(FLASH_ACR_LATENCY); FLASH->ACR &= ~(FLASH_ACR_LATENCY);
FLASH->ACR |= FLASH_ACR_LATENCY_4WS; FLASH->ACR |= FLASH_ACR_LATENCY_4WS;
// init core components
clock_init(); clock_init();
heap_init(&__bss_end__); heap_init(&__bss_end__);
random_init(); random_init();
@ -63,17 +62,14 @@ int main(void)
keypad_init(); keypad_init();
flash_init(); flash_init();
//gpio_mode(GPIOA, 5, OUTPUT); // taken by sd
// enable FPU // enable FPU
SCB->CPACR |= (0xF << 20); SCB->CPACR |= (0xF << 20);
// enable MPU
//MPU->CTRL |= MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_ENABLE_Msk;
task_init(kmain); task_init(kmain);
while (1); while (1);
} }
// enters deep sleep, activated through button press
void sleep(void) void sleep(void)
{ {
dsp_sleep(); dsp_sleep();
@ -82,6 +78,8 @@ void sleep(void)
asm("wfi"); asm("wfi");
} }
// wakes up from sleep, re-initializes components that
// need to be
void wakeup(void) void wakeup(void)
{ {
clock_init(); clock_init();
@ -90,14 +88,17 @@ void wakeup(void)
void kmain(void) void kmain(void)
{ {
// prepare display
dsp_init(); dsp_init();
dsp_cursoron(); dsp_cursoron();
text_init(); text_init();
// prepare SD card and keypad
sd_init(); sd_init();
fat_find(); fat_find();
keypad_start(); keypad_start();
// start tasks
task_start(task_interpreter, 4096); task_start(task_interpreter, 4096);
task_start(task_status, 512); task_start(task_status, 512);
@ -108,13 +109,18 @@ void kmain(void)
while (sleep_pending) while (sleep_pending)
delay(1); delay(1);
} }
//gpio_dout(GPIOA, 5, 1);
//delay(250);
//gpio_dout(GPIOA, 5, 0);
delay(100); delay(100);
} }
} }
/**
* Loads the given script on SD card into an interpreter instance.
* @param name the file's name
* @return a new, loaded instance
* Files are expected to be in the root directory of the filesystem.
* See fat32.h for more info.
* Pass the returned instance to irun() to start the script.
*/
instance *load_program(const char *name) instance *load_program(const char *name)
{ {
// load file // load file
@ -157,8 +163,10 @@ fail:
return 0; return 0;
} }
/**
* Display and update a status bar.
* This currently only has an icon for insert/delete mode.
*/
void task_status(void) void task_status(void)
{ {
extern int keypad_insert; extern int keypad_insert;
@ -185,6 +193,9 @@ void task_status(void)
} }
} }
/**
* Loads the initial program from the SD card and runs it.
*/
void task_interpreter(void) void task_interpreter(void)
{ {
dsp_rect(0, 0, 480, 300, 0); dsp_rect(0, 0, 480, 300, 0);

@ -27,7 +27,6 @@
#include <display_draw.h> #include <display_draw.h>
#include <display_text.h> #include <display_text.h>
#include <heap.h> #include <heap.h>
#include <initrd.h>
#include <it/string.h> #include <it/string.h>
#include <keypad.h> #include <keypad.h>
#include <math.h> #include <math.h>
@ -55,6 +54,7 @@ int script_filemenu(instance *it);
int script_program(instance *it); int script_program(instance *it);
int script_free(instance *it); int script_free(instance *it);
int script_clear(instance *it); int script_clear(instance *it);
int script_tty(instance *it);
int math_sin(instance *it); int math_sin(instance *it);
int math_cos(instance *it); int math_cos(instance *it);
@ -85,6 +85,7 @@ void script_loadlib(instance *it)
inew_cfunc(it, "filemenu", script_filemenu); inew_cfunc(it, "filemenu", script_filemenu);
inew_cfunc(it, "program", script_program); inew_cfunc(it, "program", script_program);
inew_cfunc(it, "freemem", script_free); inew_cfunc(it, "freemem", script_free);
inew_cfunc(it, "tty", script_tty);
inew_cfunc(it, "sin", math_sin); inew_cfunc(it, "sin", math_sin);
inew_cfunc(it, "cos", math_cos); inew_cfunc(it, "cos", math_cos);
@ -152,8 +153,10 @@ int script_filemenu(instance *it)
char listbuf[4]; char listbuf[4];
char *fname; char *fname;
strncpy(listbuf, " : \0", 4); strncpy(listbuf, " : \0", 4);
//text_switch(1);
//text_clear();
text_puts("Choose a file: \n"); text_puts("Choose a file: \n");
for (unsigned int i = 0; (fname = /*initrd*/fat_getname(i)) != 0; i++) { for (unsigned int i = 0; (fname = fat_getname(i)) != 0; i++) {
listbuf[0] = i + '0'; listbuf[0] = i + '0';
text_puts(listbuf); text_puts(listbuf);
text_puts(fname); text_puts(fname);
@ -168,6 +171,7 @@ int script_filemenu(instance *it)
variable *v = make_varf(0, isdigit(c) ? c - '0' : -1.0f); variable *v = make_varf(0, isdigit(c) ? c - '0' : -1.0f);
ipush(it, (uint32_t)v); ipush(it, (uint32_t)v);
//text_switch(0);
return 0; return 0;
} }
@ -222,6 +226,15 @@ int script_gets(instance *it)
delay(1); delay(1);
} while (c[0] == 0); } while (c[0] == 0);
// fn keys
if (c[0] == 0x11 || c[0] == 0x12 || c[0] == 0x13) {
/*s[index] = c[0];
if (furthest == 0)
furthest = 1;
break;*/
continue;
}
if (c[0] == 0x7F) { if (c[0] == 0x7F) {
it->lnidx = 998; it->lnidx = 998;
break; break;
@ -240,10 +253,8 @@ int script_gets(instance *it)
} else if (c[0] == K_UP || c[0] == K_DOWN) } else if (c[0] == K_UP || c[0] == K_DOWN)
continue; continue;
if (c[0] == '\n') { if (c[0] == '\n')
s[furthest] = '\n';
break; break;
}
extern int keypad_insert; extern int keypad_insert;
if (keypad_insert != 0 && index < furthest) { if (keypad_insert != 0 && index < furthest) {
@ -355,13 +366,13 @@ int script_pixel(instance *it)
extern instance *load_program(const char *name); extern instance *load_program(const char *name);
int script_program(instance *it) int script_program(instance *it)
{ {
int initrdOffset = (int)igetarg(it, 0)->value.f; int offset = (int)igetarg(it, 0)->value.f;
char *name = fat_getname(initrdOffset); char *name = fat_getname(offset);
text_clear();
instance *it2 = load_program(name); instance *it2 = load_program(name);
free(name); free(name);
text_clear();
int ret = irun(it2); int ret = irun(it2);
if (ret != 0) if (ret != 0)
return -1; return -1;
@ -383,3 +394,9 @@ int script_clear(instance *it)
text_clear(); text_clear();
return 0; return 0;
} }
int script_tty(instance *it)
{
text_switch(igetarg_integer(it, 0));
return 0;
}

@ -1,7 +1,28 @@
/**
* @file svc.c
* An unused handler for SVC calls
* TODO: use SVC calls, possibly allowing for switch to unprivileged mode?
*
* Copyright (C) 2018 Clyne Sullivan
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <stdint.h> #include <stdint.h>
#include <gpio.h> #include <gpio.h>
#include <clock.h> #include <clock.h>
#include <lcd.h> //#include <lcd.h>
void SVC_Handler(void) { void SVC_Handler(void) {
uint32_t *stack; uint32_t *stack;

Binary file not shown.
Loading…
Cancel
Save