diff --git a/Makefile b/Makefile index 07af411..777c75f 100644 --- a/Makefile +++ b/Makefile @@ -21,9 +21,6 @@ CROSS = arm-none-eabi- CC = gcc AS = as -AR = tools/rba -OBJCOPY = objcopy -STRIP = strip MCUFLAGS = -mthumb -mcpu=cortex-m4 -mfloat-abi=hard -mfpu=fpv4-sp-d16 AFLAGS = $(MCUFLAGS) @@ -42,15 +39,10 @@ OFILES = $(patsubst src/%.c, $(OUTDIR)/%.o, $(CFILES)) \ $(patsubst src/%.s, $(OUTDIR)/%.asm.o, $(AFILES)) OUT = out/main.elf -INITRD = initrd.img all: $(OUT) -$(OUT): $(OFILES) initrd/* libinterp.a - @echo " INITRD " $(INITRD) - @rm -f $(INITRD) - @$(AR) $(INITRD) initrd/* - @$(CROSS)$(OBJCOPY) -B arm -I binary -O elf32-littlearm $(INITRD) out/initrd.img.o +$(OUT): $(OFILES) @echo " LINK " $(OUT) @$(CROSS)$(CC) $(CFLAGS) $(LFLAGS) out/*.o -o $(OUT) -L. -linterp -lm diff --git a/include/display_text.h b/include/display_text.h index de7ebce..65b0703 100644 --- a/include/display_text.h +++ b/include/display_text.h @@ -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 . + */ + #ifndef 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); + +/** + * 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); + +/** + * 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); +/** + * Clears the display/current buffer. + */ 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); + +/** + * 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); #endif // DISPLAY_TEXT_H_ diff --git a/include/fat32.h b/include/fat32.h index 39d22f6..279b652 100644 --- a/include/fat32.h +++ b/include/fat32.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 . + */ + #ifndef FAT32_H_ #define FAT32_H_ #include +/** + * A structure to store important information for loading a file. + */ typedef struct { - uint32_t size; - uint32_t start; + uint32_t size; /**< The file's size in bytes */ + uint32_t start; /**< The file's first data cluster */ } file_t; /** @@ -22,10 +47,17 @@ int fat_find(void); 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); +/** + * 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); #endif // FAT32_H_ diff --git a/include/sdcard.h b/include/sdcard.h index 8cdef58..3722afc 100644 --- a/include/sdcard.h +++ b/include/sdcard.h @@ -1,5 +1,5 @@ /** - * @file sdcard.c + * @file sdcard.h * Provides a basic library for accessing an SD card * * Copyright (C) 2018 Clyne Sullivan diff --git a/initrd/init b/initrd/init index 7592b4a..feb01f8 100644 --- a/initrd/init +++ b/initrd/init @@ -1,4 +1,5 @@ while (1) { + #tty(1) print("Free mem: ") print(freemem()) print("\n") diff --git a/libinterp.a b/libinterp.a index c5a2337..d016267 100644 Binary files a/libinterp.a and b/libinterp.a differ diff --git a/src/flash.c.bak b/old/flash.c similarity index 100% rename from src/flash.c.bak rename to old/flash.c diff --git a/src/font.c.bak b/old/font.c similarity index 100% rename from src/font.c.bak rename to old/font.c diff --git a/src/inconsolata24.c.bak b/old/inconsolata24.c similarity index 100% rename from src/inconsolata24.c.bak rename to old/inconsolata24.c diff --git a/src/initrd.c b/old/initrd.c similarity index 100% rename from src/initrd.c rename to old/initrd.c diff --git a/include/initrd.h b/old/initrd.h similarity index 100% rename from include/initrd.h rename to old/initrd.h diff --git a/src/lcd.c.bak b/old/lcd.c similarity index 100% rename from src/lcd.c.bak rename to old/lcd.c diff --git a/include/lcd.h b/old/lcd.h similarity index 100% rename from include/lcd.h rename to old/lcd.h diff --git a/src/display_text.c b/src/display_text.c index 8a41fa5..880485e 100644 --- a/src/display_text.c +++ b/src/display_text.c @@ -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 . + */ #include #include @@ -8,8 +27,6 @@ #define WIDTH 40 #define HEIGHT 18 -#define TTY_COUNT 2 - typedef struct { char *buf; uint8_t x; @@ -51,25 +68,19 @@ void text_init(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++) { - int c = text_current->buf[i + j * WIDTH]; - /*if (c == '\0') { - if (++zc == 3) - break; - } else if (zc > 0) { - zc = 0; - }*/ - - dsp_putchar(c, i, j); + for (unsigned int j = 0; j < HEIGHT; j++) { + unsigned int i = WIDTH; + //for (; i > 0 && text_current->buf[j * WIDTH + i - 1] == '\0'; i--); + for (; i > 0; i--) { + int c = text_current->buf[j * WIDTH + i - 1]; + dsp_putchar(c, i - 1, j); } } } void text_switch(unsigned int i) { - if (i >= TTY_COUNT) + if (i >= TTY_COUNT || text_current == text_tty + i) return; text_current = &text_tty[i]; @@ -78,10 +89,14 @@ void text_switch(unsigned int i) void text_clear(void) { - for (unsigned int i = 0; i < WIDTH; i++) { - for (unsigned int j = 0; j < HEIGHT; j++) { - text_current->buf[i + j * WIDTH] = 0; - dsp_putchar(' ', i, j); + + for (unsigned int j = 0; j < HEIGHT; j++) { + 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); + //} } } text_current->x = 0; @@ -131,7 +146,21 @@ void text_putchar(int c) for (int i = 0; i < WIDTH; i++) 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; diff --git a/src/fat32.c b/src/fat32.c index 3c64f52..db2eb60 100644 --- a/src/fat32.c +++ b/src/fat32.c @@ -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 . */ #include diff --git a/src/flash.c b/src/flash.c index 396daaf..c335923 100644 --- a/src/flash.c +++ b/src/flash.c @@ -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 . + */ + #include #include #include diff --git a/src/keypad.c b/src/keypad.c index cb569e1..068850e 100644 --- a/src/keypad.c +++ b/src/keypad.c @@ -61,20 +61,20 @@ static const port_t keypad_cols[COLS] = { 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" - "sin\0" "cos\0" "tan\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" - "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" - ".\0\0\0" "0\0\0\0" "=\0\0\0" "\b\0\0\0" "\n\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" + "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" + ".\0\0\0" "0\0\0\0" "=\0\0\0" "\b\0\0\0" "\n\0\0\0" }; 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" - "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" - "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" - "U\0\0\0" "V\0\0\0" "W\0\0\0" "\b\0\0\0" "\xFF\x01\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" + "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" + "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" "\n\0\0\0" }; #define KEY(r, c, i) map[r * COLS * 4 + c * 4 + i] diff --git a/src/main.c b/src/main.c index b60f626..d232f48 100644 --- a/src/main.c +++ b/src/main.c @@ -26,9 +26,7 @@ #include #include #include -#include #include -#include #include #include #include @@ -55,6 +53,7 @@ int main(void) FLASH->ACR &= ~(FLASH_ACR_LATENCY); FLASH->ACR |= FLASH_ACR_LATENCY_4WS; + // init core components clock_init(); heap_init(&__bss_end__); random_init(); @@ -63,17 +62,14 @@ int main(void) keypad_init(); flash_init(); - //gpio_mode(GPIOA, 5, OUTPUT); // taken by sd - // enable FPU SCB->CPACR |= (0xF << 20); - // enable MPU - //MPU->CTRL |= MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_ENABLE_Msk; task_init(kmain); while (1); } +// enters deep sleep, activated through button press void sleep(void) { dsp_sleep(); @@ -82,6 +78,8 @@ void sleep(void) asm("wfi"); } +// wakes up from sleep, re-initializes components that +// need to be void wakeup(void) { clock_init(); @@ -90,14 +88,17 @@ void wakeup(void) void kmain(void) { + // prepare display dsp_init(); dsp_cursoron(); text_init(); + // prepare SD card and keypad sd_init(); fat_find(); keypad_start(); + // start tasks task_start(task_interpreter, 4096); task_start(task_status, 512); @@ -108,13 +109,18 @@ void kmain(void) while (sleep_pending) delay(1); } - //gpio_dout(GPIOA, 5, 1); - //delay(250); - //gpio_dout(GPIOA, 5, 0); 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) { // load file @@ -157,8 +163,10 @@ fail: return 0; } - - +/** + * Display and update a status bar. + * This currently only has an icon for insert/delete mode. + */ void task_status(void) { 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) { dsp_rect(0, 0, 480, 300, 0); diff --git a/src/script.c b/src/script.c index 65dd5a4..a31630c 100644 --- a/src/script.c +++ b/src/script.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -55,6 +54,7 @@ int script_filemenu(instance *it); int script_program(instance *it); int script_free(instance *it); int script_clear(instance *it); +int script_tty(instance *it); int math_sin(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, "program", script_program); inew_cfunc(it, "freemem", script_free); + inew_cfunc(it, "tty", script_tty); inew_cfunc(it, "sin", math_sin); inew_cfunc(it, "cos", math_cos); @@ -152,8 +153,10 @@ int script_filemenu(instance *it) char listbuf[4]; char *fname; strncpy(listbuf, " : \0", 4); + //text_switch(1); + //text_clear(); 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'; text_puts(listbuf); text_puts(fname); @@ -168,6 +171,7 @@ int script_filemenu(instance *it) variable *v = make_varf(0, isdigit(c) ? c - '0' : -1.0f); ipush(it, (uint32_t)v); + //text_switch(0); return 0; } @@ -222,6 +226,15 @@ int script_gets(instance *it) delay(1); } 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) { it->lnidx = 998; break; @@ -240,10 +253,8 @@ int script_gets(instance *it) } else if (c[0] == K_UP || c[0] == K_DOWN) continue; - if (c[0] == '\n') { - s[furthest] = '\n'; + if (c[0] == '\n') break; - } extern int keypad_insert; if (keypad_insert != 0 && index < furthest) { @@ -355,13 +366,13 @@ int script_pixel(instance *it) extern instance *load_program(const char *name); int script_program(instance *it) { - int initrdOffset = (int)igetarg(it, 0)->value.f; - char *name = fat_getname(initrdOffset); + int offset = (int)igetarg(it, 0)->value.f; + char *name = fat_getname(offset); - text_clear(); instance *it2 = load_program(name); free(name); + text_clear(); int ret = irun(it2); if (ret != 0) return -1; @@ -383,3 +394,9 @@ int script_clear(instance *it) text_clear(); return 0; } + +int script_tty(instance *it) +{ + text_switch(igetarg_integer(it, 0)); + return 0; +} diff --git a/src/svc.c b/src/svc.c index ad6e33f..d68fb72 100644 --- a/src/svc.c +++ b/src/svc.c @@ -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 . + */ + #include #include #include -#include +//#include void SVC_Handler(void) { uint32_t *stack; diff --git a/tools/rba b/tools/rba deleted file mode 100755 index 52f37cb..0000000 Binary files a/tools/rba and /dev/null differ