+/**
+ * @file clock.h
+ * Basic clock utilities
+ */
+
#ifndef CLOCK_H_
#define CLOCK_H_
/**
* Sets HCLK (system clock) to 80MHz, the maximum.
+ * @param none
*/
extern void clock_init(void);
/**
- * Sleeps for given milliseconds.
+ * Sleeps for given amount of milliseconds.
+ * @param ms number of milliseconds to sleep for
*/
void delay(uint32_t ms);
#define COLOR_MAX 31
uint16_t dsp_color(uint8_t r, uint8_t g, uint8_t b);
+
+void dsp_dmode(int mode);
void dsp_write_cmd(uint8_t data);
void dsp_write_data(uint8_t data);
+uint8_t dsp_read_data(void);
+
void dsp_set_addr(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
+void dsp_set_addr_read(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
+
void dsp_init(void);
#endif // DISPLAY_H_
#ifndef DISPLAY_DRAW_H_
#define DISPLAY_DRAW_H_
+#include <stdint.h>
+
+void dsp_cursoron(void);
+
+void dsp_line(int x, int y, int i, int j, uint16_t color);
void dsp_rect(int x, int y, int w, int h, uint16_t color);
void dsp_cpos(int x, int y);
+void dsp_coff(int x, int y);
void dsp_puts(const char *s);
#endif // DISPLAY_DRAW_H_
#ifndef HEAP_H_
#define HEAP_H_
-//#include <stdint.h>
+#include <stdint.h>
-//uint32_t heap_available(void);
+void heap_init(void *buf);
-//void *malloc(uint32_t size);
-//void *calloc(uint32_t count, uint32_t size);
-//void free(void *buf);
+void *malloc(uint32_t size);
+void *calloc(uint32_t count, uint32_t size);
+void free(void *buf);
#endif // HEAP_H_
+/**
+ * @file initrd.h
+ * Initrd image support
+ * An archive file (made with ar) can be linked into the final executable to
+ * allow files to be loaded in memory on boot. See mkinitrd.sh or the Makefile
+ * for more info.
+ */
+
#ifndef INITRD_H_
#define INITRD_H_
#include <stdint.h>
+/**
+ * Structure for the archive's header.
+ */
typedef struct
{
- char signature[8];
+ char signature[8]; /**< The archive's signature. */
} __attribute__ ((packed)) initrd_header;
+/**
+ * Structure for a file entry in the archive.
+ */
typedef struct
{
- char name[16];
- uint8_t unused[32];
- char size[10];
- char sig[2];
+ char name[16]; /**< The name of the file. */
+ uint8_t unused[32]; /**< Unused information. */
+ char size[10]; /**< The file's size in bytes (as string). */
+ char sig[2]; /**< A signature to start file data. */
} __attribute__ ((packed)) initrd_file;
+/**
+ * Confirms the initrd image is loaded and valid.
+ * @return non-zero if valid image found
+ */
uint8_t initrd_validate(void);
+
+/**
+ * Gets contents of the given file.
+ * @param name the file's name
+ * @return pointer to file data, null if not found
+ */
char *initrd_getfile(const char *name);
+
+/**
+ * Gets the size of the given file.
+ * @param name the file's name
+ * @return the file's size, in bytes
+ */
uint32_t initrd_getfilesize(const char *name);
#endif // INITRD_H_
+/**
+ * @file lcd.h
+ * A basic library for writing a 16x2 text LCD.
+ */
+
#ifndef LCD_H_
#define LCD_H_
#include <stdint.h>
/**
- * Direct access
+ * A handler/task to manage asyncronous LCD writes.
+ */
+void lcd_handler(void);
+
+/**
+ * Writes a string asyncronously to the LCD.
+ * The lcd_handler task must be running for the string to actually be printed.
+ * @param s the string to write
+ */
+void lcd_put(const char *s);
+
+//
+// The following functions do not support asyncronous calls.
+//
+
+/**
+ * Initializes the LCD.
*/
void lcd_init(void);
+/**
+ * Writes a string to the LCD.
+ * A cursor position is kept internally. When the end of the screen is reached,
+ * writing resumes at the first position.
+ * @param s the string to write
+ */
void lcd_puts(const char *s);
+
+/**
+ * Writes a base 10 integer to the screen.
+ * @param i the integer to print
+ */
void lcd_puti(int i);
+
+/**
+ * Writes a base 16 integer to the screen.
+ * @param h the integer to print
+ */
void lcd_puth(int h);
+
+/**
+ * Writes a byte in binary to the screen.
+ * @param b the byte to print
+ */
void lcd_putb(uint8_t b);
-void lcd_clear(void);
/**
- * Buffered/async access
+ * Clears the LCD.
*/
-void lcd_handler(void);
-void lcd_put(const char *s);
+void lcd_clear(void);
#endif // LCD_H_
+/**
+ * @file serial.h
+ * Provides basic serial IO (through STM debug stuff)
+ */
+
#ifndef SERIAL_H_
#define SERIAL_H_
+/**
+ * Initializes the serial device.
+ */
void serial_init(void);
+
+/**
+ * Puts the given character through serial.
+ * @param c the character to send
+ */
void serial_put(int c);
+/**
+ * Gets a character from serial.
+ * @return the character
+ */
char serial_get(void);
+
+/**
+ * Gets a string from serial, cut off by a newline.
+ * @param buf the initialized buffer to fill
+ * @param max the max amount of bytes to write to the buffer
+ */
void serial_gets(char *buf, int max);
#endif // SERIAL_H_
+/**
+ * @file task.h
+ * Provides multitasking functionality
+ */
+
#ifndef TASK_H_
#define TASK_H_
#include <stdint.h>
+/**
+ * Enters multitasking mode. The given function acts as the initial thread.
+ * This task is given a 4kb stack.
+ * @param init the initial thread to run
+ */
void task_init(void (*init)(void));
+/**
+ * Starts a new task.
+ * @param task the code to run
+ * @param stackSize how many bytes of stack to give the thread
+ */
void task_start(void (*task)(void), uint16_t stackSize);
#endif // TASK_H_
-func div9
- if ((arg0 % 9) == 0)
- ret 1
- end
- ret 0
-end
+print "Hello."
-set a 0
-set b 0
-do
- set a (a + 1)
- div9 a > b
- if (b)
- print a
- print ", "
- end
- delay 1
-while (a < 100)
+set fg 32767
-if (a == 100)
- print " All good!"
-end
+# 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
+# delay 10
+# line x 170 x 150 fg
+# set x (x + 20)
+#while (x < 430)
+
+#set y 50
+#do
+# delay 10
+# line 230 y 250 y fg
+# set y (y + 20)
+#while (y < 270)
#!/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 \
+# -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
+openocd -f /usr/share/openocd/scripts/board/st_nucleo_l476rg.cfg > /dev/null &
+gdb-multiarch
#define LCD_D6 GPIO_PORT(B, 10)
#define LCD_D7 GPIO_PORT(A, 8)
-// bbbbbggg gggrrrrr
+void dsp_dmode(int mode)
+{
+ static int old = 0;
-// 00000000
+ if (mode != old) {
+ gpio_mode(LCD_D0, mode);
+ gpio_mode(LCD_D1, mode);
+ gpio_mode(LCD_D2, mode);
+ gpio_mode(LCD_D3, mode);
+ gpio_mode(LCD_D4, mode);
+ gpio_mode(LCD_D5, mode);
+ gpio_mode(LCD_D6, mode);
+ gpio_mode(LCD_D7, mode);
+ old = mode;
+ }
+}
+// bbbbbggg gggrrrrr
uint16_t dsp_color(uint8_t r, uint8_t g, uint8_t b)
{
r &= 0x1F;
gpio_dout(LCD_WR, 1);
}
+uint8_t dsp_read_data(void)
+{
+ uint8_t ret = 0;
+ gpio_dout(LCD_RD, 0);
+ ret |= gpio_din(LCD_D0);
+ ret |= gpio_din(LCD_D1) << 1;
+ ret |= gpio_din(LCD_D2) << 2;
+ ret |= gpio_din(LCD_D3) << 3;
+ ret |= gpio_din(LCD_D4) << 4;
+ ret |= gpio_din(LCD_D5) << 5;
+ ret |= gpio_din(LCD_D6) << 6;
+ ret |= gpio_din(LCD_D7) << 7;
+ gpio_dout(LCD_RD, 1);
+ return ret;
+}
+
void dsp_write_cmd(uint8_t data)
{
gpio_dout(LCD_RS, 0);
gpio_dout(LCD_RS, 1);
}
-void dsp_set_addr(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
+void dsp_set_addr_base(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
{
dsp_write_cmd(0x2A);
dsp_write_data(x1 >> 8);
dsp_write_data(y1 & 0xFF);
dsp_write_data(y2 >> 8);
dsp_write_data(y2 & 0xFF);
+}
+
+void dsp_set_addr(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
+{
+ dsp_set_addr_base(x1, y1, x2, y2);
dsp_write_cmd(0x2C); // begin writing
}
+void dsp_set_addr_read(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
+{
+ dsp_set_addr_base(x1, y1, x2, y2);
+ dsp_write_cmd(0x2E); // begin reading
+}
+
void dsp_init(void)
{
gpio_mode(LCD_CS, OUTPUT);
gpio_mode(LCD_RD, OUTPUT);
gpio_mode(LCD_WR, OUTPUT);
gpio_mode(LCD_RST, OUTPUT);
- gpio_mode(LCD_D0, OUTPUT);
- gpio_mode(LCD_D1, OUTPUT);
- gpio_mode(LCD_D2, OUTPUT);
- gpio_mode(LCD_D3, OUTPUT);
- gpio_mode(LCD_D4, OUTPUT);
- gpio_mode(LCD_D5, OUTPUT);
- gpio_mode(LCD_D6, OUTPUT);
- gpio_mode(LCD_D7, OUTPUT);
+ dsp_dmode(OUTPUT);
gpio_speed(LCD_CS, LOW);
gpio_speed(LCD_RS, LOW);
gpio_speed(LCD_RD, LOW);
+#include <display_draw.h>
#include <display.h>
+#include <task.h>
+#include <clock.h>
+
+volatile uint8_t lock = 0;
+#define LOCK while (lock) { delay(5); } lock = 1
+#define UNLOCK lock = 0
static unsigned int curx = 0;
static unsigned int cury = 0;
+static unsigned int curxo = 0;
+static unsigned int curyo = 0;
extern const unsigned char inconsolata24[192 * 156 * 2 + 1];
+void task_cursor(void)
+{
+ while (1) {
+ int x = curxo + curx * 12;
+ int y = curyo + cury * 26;
+ dsp_rect(x, y + 24, 12, 1, 0xFFFF);
+ delay(300);
+ dsp_rect(x, y + 24, 12, 1, 0);
+ delay(300);
+ }
+}
+
+void dsp_cursoron(void)
+{
+ task_start(task_cursor, 512);
+}
+
void dsp_putchar(int c)
{
+ if (c == '\n') {
+ curx = 0;
+ if (++cury == 12) {
+ UNLOCK;
+ dsp_rect(0, 0, LCD_WIDTH, LCD_HEIGHT, 0);
+ LOCK;
+ cury = 0;
+ }
+ return;
+ }
+
unsigned int start = ((c - ' ') / 16 * 192 * 26 + (c % 16) * 12) * 2;
- dsp_set_addr(curx * 12, cury * 26, curx * 12 + 11, cury * 26 + 25);
+ unsigned int x = curxo + curx * 12;
+ unsigned int y = curyo + cury * 26;
+ dsp_set_addr(x, y, x + 11, y + 25);
// for each row
for (unsigned int i = 0; i < 26; i++) {
// for each column
if (++curx == 40) {
curx = 0;
- if (++cury == 10)
+ if (++cury == 12) {
+ UNLOCK;
+ dsp_rect(0, 0, LCD_WIDTH, LCD_HEIGHT, 0);
+ LOCK;
cury = 0;
+ }
}
}
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)
cury = y;
}
+void dsp_coff(int x, int y)
+{
+ curxo = x;
+ curyo = 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 {
dsp_write_data(color >> 8);
dsp_write_data(color & 0xFF);
} while (countdown--);
+ UNLOCK;
+}
+
+void dsp_line(int x, int y, int i, int j, uint16_t color)
+{
+ int dx = i - x;
+ int sx = dx >= 0 ? 1 : -1;
+ int dy = j - y;
+ int sy = dy >= 0 ? 1 : -1;
+
+ if (dx < 0)
+ dx *= -1;
+ if (dy < 0)
+ dy *= -1;
+ int err = (dx > dy ? dx : -dy) / 2;
+ int e2;
+
+ LOCK;
+ while (1) {
+ dsp_set_addr(x, y, x, y);
+ dsp_write_data(color >> 8);
+ dsp_write_data(color & 0xFF);
+ if (x == i && y == j)
+ break;
+ e2 = err;
+ if (e2 > -dx) {
+ err -= dy;
+ x += sx;
+ }
+ if (e2 < dy) {
+ err += dx;
+ y += sy;
+ }
+ }
+ UNLOCK;
}
+
-#include <heap.h>
-#include <stm32l476xx.h>
+#include "heap.h"
-#define HEAP_SIZE (64 * 1024)
+#define HEAP_ALIGN 16
-uint8_t heap[HEAP_SIZE];
+typedef struct {
+ uint32_t next;
+ uint32_t size;
+} __attribute__ ((packed)) alloc_t;
-void *_sbrk(int inc)
-{
- static uint8_t *hend;
- uint8_t *prev;
-
- if (hend == 0)
- hend = heap;
-
- prev = hend;
- hend += inc;
-
- return prev;
-}
+static alloc_t root;
+static void *heap_end;
-//void heap_init(void)
-//{
+void heap_init(void *buf)
+{
+ heap_end = buf;
+ root.next = 1;
+ root.size = 0;
// what to do...
-//}
-
-//uint32_t heap_available(void)
-//{
-// return HEAP_SIZE - offset;
-//}
+}
-/*void *malloc(uint32_t size)
+void *malloc(uint32_t size)
{
- void *alloc = &heap[offset];
- offset += size;
- return alloc;
+ 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 += 2 * HEAP_ALIGN + size;
+ node = (void *)(node->next & ~(1));
+ node->next = 0;
+ node->size = size;
+ break;
+ }
+ node = (void *)(node->next & ~(1));
+ }
+
+ node->next |= 1;
+
+ return (void *)((uint32_t)node + sizeof(alloc_t));
}
void *calloc(uint32_t count, uint32_t size)
{
- //uint32_t total = count * size;
- //void *alloc = hmalloc(total);
- //for (uint32_t i = 0; i < total; i++)
- // ((uint8_t *)alloc)[i] = 0;
- //return alloc;
-
- // calloc broke
- return malloc(count * size);
+ uint8_t *buf = malloc(count * size);
+ for (uint8_t i = 0; i < count * size; i++)
+ buf[i] = 0;
+ return buf;
}
-void free(void *ptr)
+void free(void *buf)
{
- (void)ptr;
-}*/
+ if (buf == 0)
+ return;
+ alloc_t *alloc = (alloc_t *)((uint32_t)buf - sizeof(alloc_t));
+ alloc->next &= ~(1);
+}
+
+++ /dev/null
-#include <lcd.h>
-#include <clock.h>
-#include <gpio.h>
-#include <string.h>
-
-//#define USE_DELAY
-
-#define LCD_D0 GPIO_PORT(A, 0)
-#define LCD_D1 GPIO_PORT(A, 1)
-#define LCD_D2 GPIO_PORT(A, 4)
-#define LCD_D3 GPIO_PORT(B, 0)
-#define LCD_D4 GPIO_PORT(C, 1)
-#define LCD_D5 GPIO_PORT(C, 0)
-#define LCD_D6 GPIO_PORT(C, 2)
-#define LCD_D7 GPIO_PORT(C, 3)
-#define LCD_E GPIO_PORT(C, 12)
-#define LCD_RS GPIO_PORT(C, 10)
-
-#define lcd_data() gpio_dout(LCD_RS, 1)
-
-void lcd_pulse(void)
-{
- gpio_dout(LCD_E, 1);
-#ifdef USE_DELAY
- delay(1);
-#else
- for (uint16_t i = 0; i < 10000; i++)
- asm("");
-#endif // USE_DELAY
- gpio_dout(LCD_E, 0);
-}
-
-void lcd_byte(uint8_t byte)
-{
- gpio_dout(LCD_D0, byte & 0x01);
- gpio_dout(LCD_D1, byte & 0x02);
- gpio_dout(LCD_D2, byte & 0x04);
- gpio_dout(LCD_D3, byte & 0x08);
- gpio_dout(LCD_D4, byte & 0x10);
- gpio_dout(LCD_D5, byte & 0x20);
- gpio_dout(LCD_D6, byte & 0x40);
- gpio_dout(LCD_D7, byte & 0x80);
-}
-
-void lcd_cmd(uint8_t cmd)
-{
- gpio_dout(LCD_RS, 0);
- lcd_byte(cmd);
- lcd_pulse();
-}
-
-void lcd_putchar(int c)
-{
- lcd_data();
- lcd_byte((uint8_t)c);
- lcd_pulse();
-}
-
-static int lcd_index = 0;
-void lcd_puts(const char *s)
-{
- lcd_cmd(0x06);
- while (*s) {
- lcd_putchar(*s++);
- if (++lcd_index == 0x10) {
- lcd_cmd(0x80 | 0x40);
- } else if (lcd_index == 0x20) {
- lcd_cmd(0x80);
- lcd_index = 0;
- }
- }
-}
-
-extern char *itoa(int n, int base);
-void lcd_puti(int i)
-{
- lcd_puts(itoa(i, 10));
-}
-
-void lcd_puth(int h)
-{
- lcd_puts(itoa(h, 16));
-}
-
-void lcd_putb(uint8_t b)
-{
- lcd_puts(itoa(b, 2));
-}
-
-void lcd_clear(void)
-{
- lcd_cmd(0x01);
- delay(2);
- lcd_index = 0;
-}
-
-void lcd_init(void)
-{
- gpio_mode(LCD_D0, OUTPUT);
- gpio_mode(LCD_D1, OUTPUT);
- gpio_mode(LCD_D2, OUTPUT);
- gpio_mode(LCD_D3, OUTPUT);
- gpio_mode(LCD_D4, OUTPUT);
- gpio_mode(LCD_D5, OUTPUT);
- gpio_mode(LCD_D6, OUTPUT);
- gpio_mode(LCD_D7, OUTPUT);
- gpio_mode(LCD_E, OUTPUT);
- gpio_mode(LCD_RS, OUTPUT);
- gpio_dout(LCD_D0, 0);
- gpio_dout(LCD_D1, 0);
- gpio_dout(LCD_D2, 0);
- gpio_dout(LCD_D3, 0);
- gpio_dout(LCD_D4, 0);
- gpio_dout(LCD_D5, 0);
- gpio_dout(LCD_D6, 0);
- gpio_dout(LCD_D7, 0);
- gpio_dout(LCD_E, 0);
- gpio_dout(LCD_RS, 0);
-
- lcd_cmd(0x38);
- lcd_cmd(0x10);
- lcd_cmd(0x0D);
- delay(5);
- lcd_clear();
-}
-
-/**
- * Task code
- */
-
-volatile int bufpos = 0;
-volatile char buf[32];
-volatile uint8_t using = 0;
-
-void lcd_clearbuf(void)
-{
- bufpos = 0;
- for (int i = 0; i < 32; i++)
- buf[i] = 0;
-}
-
-void lcd_put(const char *s)
-{
- int len = strlen(s);
- int i;
-
- using = 1;
- for (i = 0; i < len; bufpos++, i++) {
- if (bufpos > 31)
- bufpos = 0;
- buf[bufpos] = s[i];
- }
- using = 0;
-}
-
-void lcd_handler(void)
-{
- lcd_init();
- lcd_clearbuf();
-
- while (1) {
- if (!using && buf[0] != '\0') {
- lcd_puts(buf);
- lcd_clearbuf();
- }
- delay(100);
- }
-}
--- /dev/null
+#include <lcd.h>
+#include <clock.h>
+#include <gpio.h>
+#include <string.h>
+
+//#define USE_DELAY
+
+#define LCD_D0 GPIO_PORT(A, 0)
+#define LCD_D1 GPIO_PORT(A, 1)
+#define LCD_D2 GPIO_PORT(A, 4)
+#define LCD_D3 GPIO_PORT(B, 0)
+#define LCD_D4 GPIO_PORT(C, 1)
+#define LCD_D5 GPIO_PORT(C, 0)
+#define LCD_D6 GPIO_PORT(C, 2)
+#define LCD_D7 GPIO_PORT(C, 3)
+#define LCD_E GPIO_PORT(C, 12)
+#define LCD_RS GPIO_PORT(C, 10)
+
+#define lcd_data() gpio_dout(LCD_RS, 1)
+
+void lcd_pulse(void)
+{
+ gpio_dout(LCD_E, 1);
+#ifdef USE_DELAY
+ delay(1);
+#else
+ for (uint16_t i = 0; i < 10000; i++)
+ asm("");
+#endif // USE_DELAY
+ gpio_dout(LCD_E, 0);
+}
+
+void lcd_byte(uint8_t byte)
+{
+ gpio_dout(LCD_D0, byte & 0x01);
+ gpio_dout(LCD_D1, byte & 0x02);
+ gpio_dout(LCD_D2, byte & 0x04);
+ gpio_dout(LCD_D3, byte & 0x08);
+ gpio_dout(LCD_D4, byte & 0x10);
+ gpio_dout(LCD_D5, byte & 0x20);
+ gpio_dout(LCD_D6, byte & 0x40);
+ gpio_dout(LCD_D7, byte & 0x80);
+}
+
+void lcd_cmd(uint8_t cmd)
+{
+ gpio_dout(LCD_RS, 0);
+ lcd_byte(cmd);
+ lcd_pulse();
+}
+
+void lcd_putchar(int c)
+{
+ lcd_data();
+ lcd_byte((uint8_t)c);
+ lcd_pulse();
+}
+
+static int lcd_index = 0;
+void lcd_puts(const char *s)
+{
+ lcd_cmd(0x06);
+ while (*s) {
+ lcd_putchar(*s++);
+ if (++lcd_index == 0x10) {
+ lcd_cmd(0x80 | 0x40);
+ } else if (lcd_index == 0x20) {
+ lcd_cmd(0x80);
+ lcd_index = 0;
+ }
+ }
+}
+
+extern char *itoa(int n, int base);
+void lcd_puti(int i)
+{
+ lcd_puts(itoa(i, 10));
+}
+
+void lcd_puth(int h)
+{
+ lcd_puts(itoa(h, 16));
+}
+
+void lcd_putb(uint8_t b)
+{
+ lcd_puts(itoa(b, 2));
+}
+
+void lcd_clear(void)
+{
+ lcd_cmd(0x01);
+ delay(2);
+ lcd_index = 0;
+}
+
+void lcd_init(void)
+{
+ gpio_mode(LCD_D0, OUTPUT);
+ gpio_mode(LCD_D1, OUTPUT);
+ gpio_mode(LCD_D2, OUTPUT);
+ gpio_mode(LCD_D3, OUTPUT);
+ gpio_mode(LCD_D4, OUTPUT);
+ gpio_mode(LCD_D5, OUTPUT);
+ gpio_mode(LCD_D6, OUTPUT);
+ gpio_mode(LCD_D7, OUTPUT);
+ gpio_mode(LCD_E, OUTPUT);
+ gpio_mode(LCD_RS, OUTPUT);
+ gpio_dout(LCD_D0, 0);
+ gpio_dout(LCD_D1, 0);
+ gpio_dout(LCD_D2, 0);
+ gpio_dout(LCD_D3, 0);
+ gpio_dout(LCD_D4, 0);
+ gpio_dout(LCD_D5, 0);
+ gpio_dout(LCD_D6, 0);
+ gpio_dout(LCD_D7, 0);
+ gpio_dout(LCD_E, 0);
+ gpio_dout(LCD_RS, 0);
+
+ lcd_cmd(0x38);
+ lcd_cmd(0x10);
+ lcd_cmd(0x0D);
+ delay(5);
+ lcd_clear();
+}
+
+/**
+ * Task code
+ */
+
+volatile int bufpos = 0;
+volatile char buf[32];
+volatile uint8_t using = 0;
+
+void lcd_clearbuf(void)
+{
+ bufpos = 0;
+ for (int i = 0; i < 32; i++)
+ buf[i] = 0;
+}
+
+void lcd_put(const char *s)
+{
+ int len = strlen(s);
+ int i;
+
+ using = 1;
+ for (i = 0; i < len; bufpos++, i++) {
+ if (bufpos > 31)
+ bufpos = 0;
+ buf[bufpos] = s[i];
+ }
+ using = 0;
+}
+
+void lcd_handler(void)
+{
+ lcd_init();
+ lcd_clearbuf();
+
+ while (1) {
+ if (!using && buf[0] != '\0') {
+ lcd_puts(buf);
+ lcd_clearbuf();
+ }
+ delay(100);
+ }
+}
#include <serial.h>\r
#include <parser.h>\r
#include <stack.h>\r
-\r
-#include <stdlib.h>\r
#include <string.h>\r
\r
+extern char *itoa(int, char *, int);\r
+\r
void kmain(void);\r
-void task_interpreter(void);\r
\r
int main(void)\r
{\r
\r
//MPU->CTRL |= MPU_CTRL_ENABLE_Msk | MPU_CTRL_PRIVDEFENA_Msk;\r
clock_init();\r
+ extern uint8_t _ebss;\r
+ heap_init(&_ebss);\r
gpio_init();\r
\r
gpio_mode(GPIOA, 5, OUTPUT);\r
{\r
char *s = igetarg_string(it, 0);\r
dsp_puts(s);\r
+ //dsp_puts("\n");\r
//asm("mov r0, %0; svc 2" :: "r" (s));\r
return 0;\r
}\r
\r
+int script_gets(interpreter *it)\r
+{\r
+ char *s = malloc(64), c[2] = {0, 0};\r
+ uint16_t index = 0;\r
+\r
+ do {\r
+ c[0] = serial_get();\r
+ s[index] = c[0];\r
+ if (c[0] != '\r')\r
+ dsp_puts(c);\r
+ } while (s[index] != '\r' && index++ < 23);\r
+ s[index] = '\0';\r
+\r
+ variable *v = igetarg(it, 0);\r
+ v->valtype = STRING;\r
+ v->svalue = s;\r
+ return 0;\r
+}\r
+\r
int script_delay(interpreter *it)\r
{\r
int ms = igetarg_integer(it, 0);\r
return 0;\r
}\r
\r
+int script_rect(interpreter *it)\r
+{\r
+ dsp_rect(igetarg_integer(it, 0), igetarg_integer(it, 1),\r
+ igetarg_integer(it, 2), igetarg_integer(it, 3),\r
+ igetarg_integer(it, 4));\r
+ return 0;\r
+}\r
+\r
+int script_line(interpreter *it)\r
+{\r
+ dsp_line(igetarg_integer(it, 0), igetarg_integer(it, 1),\r
+ igetarg_integer(it, 2), igetarg_integer(it, 3),\r
+ igetarg_integer(it, 4));\r
+ return 0;\r
+}\r
+\r
+int script_ppos(interpreter *it)\r
+{\r
+ dsp_cpos(0, 0);\r
+ dsp_coff(igetarg_integer(it, 0), igetarg_integer(it, 1));\r
+ return 0;\r
+}\r
+\r
void task_interpreter(void)\r
{\r
interpreter it;\r
iinit(&it);\r
inew_cfunc(&it, "print", script_puts);\r
+ inew_cfunc(&it, "gets", script_gets);\r
inew_cfunc(&it, "delay", script_delay);\r
+ inew_cfunc(&it, "rect", script_rect);\r
+ inew_cfunc(&it, "ppos", script_ppos);\r
+ inew_cfunc(&it, "line", script_line);\r
+\r
+ /*int ret = 0;\r
+ char *linebuf = malloc(100), c[2] = {0, 0};\r
+ while (1) {\r
+ uint16_t index = 0;\r
+ if (it.indent > 0)\r
+ dsp_puts(">");\r
+ dsp_puts("> ");\r
+ do {\r
+ c[0] = serial_get();\r
+ if (c[0] >= ' ' || c[0] == '\r') {\r
+ linebuf[index] = c[0];\r
+ if (c[0] >= ' ')\r
+ dsp_puts(c);\r
+ }\r
+ } while (linebuf[index] != '\r' && index++ < 100);\r
+ linebuf[index] = '\0';\r
+ dsp_puts("\n");\r
+ ret = idoline(&it, linebuf);\r
+ if (ret < 0)\r
+ break;\r
+ }*/\r
\r
char *s = initrd_getfile("init");\r
if (s == 0)\r
}\r
\r
if (ret < 0) {\r
- lcd_puts("Error: ");\r
- lcd_puts(itoa(ret, linebuf, 10));\r
+ dsp_puts("\nError: ");\r
+ dsp_puts(itoa(ret, linebuf, 10));\r
}\r
free(linebuf);\r
//iend(&it); // nah\r
asm("cpsie i");\r
\r
dsp_init();\r
-\r
- dsp_rect(0, 0, LCD_WIDTH, 105, dsp_color(0xFF, 0, 0));\r
- dsp_rect(0, 105, LCD_WIDTH, 105, dsp_color(0, 0xFF, 0));\r
- dsp_rect(0, 210, LCD_WIDTH, 110, dsp_color(0, 0, 0xFF));\r
-\r
- //dsp_puts("Hello, world! My name is Clyne. I enjoy car rides and long \r
-//walks on the beach");\r
-\r
- //task_start(lcd_handler, 128);\r
- //delay(200);\r
+ dsp_rect(0, 0, LCD_WIDTH, LCD_HEIGHT, dsp_color(0, 0, 0));\r
+ dsp_cursoron();\r
+ //dsp_puts("Hey.");\r
task_start(task_interpreter, 4096);\r
\r
- //char *s = initrd_getfile("test.txt");\r
-\r
while (1) {\r
gpio_dout(GPIOA, 5, 1);\r
delay(500);\r
--- /dev/null
+#include <stm32l476xx.h>\r
+#include <clock.h>\r
+#include <heap.h>\r
+#include <task.h>\r
+#include <gpio.h>\r
+#include <lcd.h>\r
+#include <display.h>\r
+#include <display_draw.h>\r
+#include <initrd.h>\r
+#include <serial.h>\r
+#include <parser.h>\r
+#include <stack.h>\r
+\r
+#include <stdlib.h>\r
+#include <string.h>\r
+\r
+void kmain(void);\r
+void task_interpreter(void);\r
+\r
+int main(void)\r
+{\r
+ asm("cpsid i");\r
+\r
+ // prepare flash latency for 40MHz operation\r
+ FLASH->ACR &= ~(FLASH_ACR_LATENCY);\r
+ FLASH->ACR |= FLASH_ACR_LATENCY_4WS;\r
+\r
+ //MPU->CTRL |= MPU_CTRL_ENABLE_Msk | MPU_CTRL_PRIVDEFENA_Msk;\r
+ clock_init();\r
+ gpio_init();\r
+\r
+ gpio_mode(GPIOA, 5, OUTPUT);\r
+\r
+ serial_init();\r
+\r
+ // enable FPU\r
+ SCB->CPACR |= (0xF << 20);\r
+\r
+ task_init(kmain);\r
+\r
+ while (1);\r
+}\r
+\r
+int script_puts(interpreter *it)\r
+{\r
+ char *s = igetarg_string(it, 0);\r
+ dsp_puts(s);\r
+ //dsp_puts("\n");\r
+ //asm("mov r0, %0; svc 2" :: "r" (s));\r
+ return 0;\r
+}\r
+\r
+int script_gets(interpreter *it)\r
+{\r
+ char *s = malloc(64), c[2] = {0, 0};\r
+ uint16_t index = 0;\r
+\r
+ do {\r
+ c[0] = serial_get();\r
+ s[index] = c[0];\r
+ if (c[0] != '\r')\r
+ dsp_puts(c);\r
+ } while (s[index] != '\r' && index++ < 23);\r
+ s[index] = '\0';\r
+\r
+ variable *v = igetarg(it, 0);\r
+ v->valtype = STRING;\r
+ v->svalue = s;\r
+ return 0;\r
+}\r
+\r
+int script_delay(interpreter *it)\r
+{\r
+ int ms = igetarg_integer(it, 0);\r
+ delay(ms);\r
+ return 0;\r
+}\r
+\r
+int script_rect(interpreter *it)\r
+{\r
+ dsp_rect(igetarg_integer(it, 0), igetarg_integer(it, 1),\r
+ igetarg_integer(it, 2), igetarg_integer(it, 3),\r
+ igetarg_integer(it, 4));\r
+ return 0;\r
+}\r
+\r
+int script_line(interpreter *it)\r
+{\r
+ dsp_line(igetarg_integer(it, 0), igetarg_integer(it, 1),\r
+ igetarg_integer(it, 2), igetarg_integer(it, 3),\r
+ igetarg_integer(it, 4));\r
+ return 0;\r
+}\r
+\r
+int script_ppos(interpreter *it)\r
+{\r
+ dsp_cpos(0, 0);\r
+ dsp_coff(igetarg_integer(it, 0), igetarg_integer(it, 1));\r
+ return 0;\r
+}\r
+\r
+void task_interpreter(void)\r
+{\r
+ interpreter it;\r
+ iinit(&it);\r
+ inew_cfunc(&it, "print", script_puts);\r
+ inew_cfunc(&it, "gets", script_gets);\r
+ inew_cfunc(&it, "delay", script_delay);\r
+ inew_cfunc(&it, "rect", script_rect);\r
+ inew_cfunc(&it, "ppos", script_ppos);\r
+ inew_cfunc(&it, "line", script_line);\r
+\r
+ /*int ret = 0;\r
+ char *linebuf = malloc(100), c[2] = {0, 0};\r
+ while (1) {\r
+ uint16_t index = 0;\r
+ if (it.indent > 0)\r
+ dsp_puts(">");\r
+ dsp_puts("> ");\r
+ do {\r
+ c[0] = serial_get();\r
+ if (c[0] >= ' ' || c[0] == '\r') {\r
+ linebuf[index] = c[0];\r
+ if (c[0] >= ' ')\r
+ dsp_puts(c);\r
+ }\r
+ } while (linebuf[index] != '\r' && index++ < 100);\r
+ linebuf[index] = '\0';\r
+ dsp_puts("\n");\r
+ ret = idoline(&it, linebuf);\r
+ if (ret < 0)\r
+ break;\r
+ }*/\r
+\r
+ char *s = initrd_getfile("init");\r
+ if (s == 0)\r
+ goto end;\r
+\r
+ char *linebuf = (char *)malloc(120);\r
+ uint32_t i = 0, prev = 0, lc;\r
+ uint32_t size = initrd_getfilesize("init");\r
+ int ret;\r
+ while (i < size) {\r
+ for (; s[i] != '\n' && s[i] != '\0'; i++);\r
+ lc = i - prev;\r
+ if (lc == 0) {\r
+ prev = ++i;\r
+ continue;\r
+ }\r
+ strncpy(linebuf, s + prev, lc + 1);\r
+ linebuf[lc] = '\0';\r
+ ret = idoline(&it, linebuf);\r
+ if (ret < 0)\r
+ break;\r
+ prev = ++i;\r
+ }\r
+\r
+ if (ret < 0) {\r
+ dsp_puts("\nError: ");\r
+ dsp_puts(itoa(ret, linebuf, 10));\r
+ }\r
+ free(linebuf);\r
+ //iend(&it); // nah\r
+\r
+end:\r
+ while (1)\r
+ delay(10);\r
+}\r
+\r
+void kmain(void)\r
+{\r
+ asm("cpsie i");\r
+\r
+ dsp_init();\r
+\r
+ //dsp_rect(0, 0, 40, 40, dsp_color(0x7F, 0, 0x7F));\r
+\r
+ //dsp_set_addr_read(0, 0, 39, 39);\r
+ //dsp_dmode(INPUT);\r
+ //uint8_t *buf = (uint8_t *)malloc(40 * 40 * 2);\r
+ //for (int i = 0; i < 180; i++)\r
+ // buf[i] = dsp_read_data();\r
+ //dsp_dmode(OUTPUT);\r
+ //dsp_set_addr(40, 40, 79, 79);\r
+ //for (int i = 0; i < 320; i++)\r
+ // dsp_write_data(buf[i]);\r
+ //dsp_rect(80, 80, 40, 40, dsp_color(0x7F, 0x7F, 0));\r
+\r
+ dsp_rect(0, 0, LCD_WIDTH, LCD_HEIGHT, dsp_color(0, 0, 0));\r
+ dsp_cursoron();\r
+\r
+ task_start(task_interpreter, 4096);\r
+\r
+ //char *s = initrd_getfile("test.txt");\r
+\r
+ while (1) {\r
+ gpio_dout(GPIOA, 5, 1);\r
+ delay(500);\r
+ gpio_dout(GPIOA, 5, 0);\r
+ delay(500);\r
+ }\r
+}\r
+\r
do {
buf[index] = serial_get();
serial_put(buf[index]);
- } while (index++ < max && buf[index] != '\r');
-
- buf[index - 1] = '\0';
- //return buf;
+ } while (buf[index] != '\r' && index++ < max);
+ buf[index] = '\0';
}
\r
void perror(const char *s)\r
{\r
- lcd_puts(s);\r
+ (void)s;//lcd_puts(s);\r
}\r
\r
void NMI_Handler(void) {}\r
gpio_dout(GPIOA, 6, 0);
break;
case 2:
- lcd_put((char *)stack[0]);
+ // lcd_put((char *)stack[0]);
break;
default:
break;
#include <task.h>
-#include <stdlib.h>
+#include <heap.h>
#include <stm32l476xx.h>
typedef struct {