diff options
Diffstat (limited to 'src/cortexelf-v1')
-rw-r--r-- | src/cortexelf-v1/Makefile | 137 | ||||
-rw-r--r-- | src/cortexelf-v1/ao_1802.c | 328 | ||||
-rw-r--r-- | src/cortexelf-v1/ao_1802.h | 129 | ||||
-rw-r--r-- | src/cortexelf-v1/ao_cortexelf.c | 291 | ||||
-rw-r--r-- | src/cortexelf-v1/ao_flip_bits.5c | 24 | ||||
-rw-r--r-- | src/cortexelf-v1/ao_hex.c | 36 | ||||
-rw-r--r-- | src/cortexelf-v1/ao_hex.h | 21 | ||||
-rw-r--r-- | src/cortexelf-v1/ao_lisp_os.h | 65 | ||||
-rw-r--r-- | src/cortexelf-v1/ao_lisp_os_save.c | 53 | ||||
-rw-r--r-- | src/cortexelf-v1/ao_pins.h | 265 | ||||
-rw-r--r-- | src/cortexelf-v1/cortexelf.ld | 101 | ||||
-rw-r--r-- | src/cortexelf-v1/flash-loader/Makefile | 8 | ||||
-rw-r--r-- | src/cortexelf-v1/flash-loader/ao_pins.h | 35 |
13 files changed, 1493 insertions, 0 deletions
diff --git a/src/cortexelf-v1/Makefile b/src/cortexelf-v1/Makefile new file mode 100644 index 00000000..8cc6ce31 --- /dev/null +++ b/src/cortexelf-v1/Makefile @@ -0,0 +1,137 @@ +# +# AltOS build +# +# + +include ../stm/Makefile.defs +LDFLAGS=-L../stm -Wl,-Tcortexelf.ld + +INC = \ + ao.h \ + ao_arch.h \ + ao_arch_funcs.h \ + ao_boot.h \ + ao_pins.h \ + ao_kalman.h \ + ao_product.h \ + ao_profile.h \ + ao_task.h \ + math.h \ + ao_mpu.h \ + stm32l.h \ + math.h \ + ao_vga.h \ + ao_draw.h \ + ao_draw_int.h \ + ao_font.h \ + ao_ps2.h \ + ao_lisp.h \ + ao_lisp_const.h \ + ao_lisp_os.h \ + ao_flip_bits.h \ + Makefile + +#PROFILE=ao_profile.c +#PROFILE_DEF=-DAO_PROFILE=1 + +#STACK_GUARD=ao_mpu_stm.c +#STACK_GUARD_DEF=-DHAS_STACK_GUARD=1 + + +ALTOS_SRC = \ + ao_boot_chain.c \ + ao_interrupt.c \ + ao_product.c \ + ao_romconfig.c \ + ao_cmd.c \ + ao_config.c \ + ao_task.c \ + ao_stdio.c \ + ao_panic.c \ + ao_timer.c \ + ao_mutex.c \ + ao_serial_stm.c \ + ao_dma_stm.c \ + ao_spi_stm.c \ + ao_usb_stm.c \ + ao_exti_stm.c \ + ao_i2c_stm.c \ + ao_as1107.c \ + ao_matrix.c \ + ao_vga.c \ + ao_blt.c \ + ao_copy.c \ + ao_rect.c \ + ao_text.c \ + ao_line.c \ + ao_ps2.c \ + ao_console.c \ + ao_sdcard.c \ + ao_bufio.c \ + ao_fat.c \ + ao_flash_stm.c \ + ao_button.c \ + ao_event.c \ + ao_1802.c \ + ao_hex.c \ + ao_lisp_lex.c \ + ao_lisp_mem.c \ + ao_lisp_cons.c \ + ao_lisp_eval.c \ + ao_lisp_string.c \ + ao_lisp_atom.c \ + ao_lisp_int.c \ + ao_lisp_poly.c \ + ao_lisp_builtin.c \ + ao_lisp_read.c \ + ao_lisp_rep.c \ + ao_lisp_frame.c \ + ao_lisp_error.c \ + ao_lisp_lambda.c \ + ao_lisp_save.c \ + ao_lisp_stack.c \ + ao_lisp_os_save.c \ + $(PROFILE) \ + $(SAMPLE_PROFILE) \ + $(STACK_GUARD) + +PRODUCT=CortexELF-v1 +PRODUCT_DEF=-DCORTEXELF +IDPRODUCT=0x000a + +CFLAGS = $(PRODUCT_DEF) $(STM_CFLAGS) $(PROFILE_DEF) $(SAMPLE_PROFILE_DEF) $(STACK_GUARD_DEF) -Os -g + +PROGNAME=cortexelf-v1 +PROG=$(PROGNAME)-$(VERSION).elf +HEX=$(PROGNAME)-$(VERSION).ihx + +SRC=$(ALTOS_SRC) ao_cortexelf.c +OBJ=$(SRC:.c=.o) + +all:: $(PROG) $(HEX) + +$(PROG): Makefile $(OBJ) cortexelf.ld + $(call quiet,CC) $(LDFLAGS) $(CFLAGS) -o $(PROG) $(OBJ) $(LIBS) + +../altitude-pa.h: make-altitude-pa + nickle $< > $@ + +$(OBJ): $(INC) + +ao_product.h: ao-make-product.5c ../Version + $(call quiet,NICKLE,$<) $< -m altusmetrum.org -i $(IDPRODUCT) -p $(PRODUCT) -v $(VERSION) > $@ + +distclean: clean + +clean:: + rm -f *.o $(PROGNAME)-*.elf $(PROGNAME)-*.ihx + rm -f ao_product.h ao_flip_bits.h + +ao_flip_bits.h: ao_flip_bits.5c + nickle ao_flip_bits.5c > $@ + +include ../lisp/Makefile-lisp + +install: + +uninstall: diff --git a/src/cortexelf-v1/ao_1802.c b/src/cortexelf-v1/ao_1802.c new file mode 100644 index 00000000..9fb36595 --- /dev/null +++ b/src/cortexelf-v1/ao_1802.c @@ -0,0 +1,328 @@ +/* + * Copyright © 2017 Keith Packard <keithp@keithp.com> + * + * 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 2 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. + */ + +#include <ao.h> +#include <ao_flip_bits.h> +#include <ao_1802.h> +#include <ao_exti.h> + +/* Decoded address driven by TPA/TPB signals */ +uint16_t ADDRESS; + +/* Decoded data, driven by TPB signal */ +uint8_t DATA; + +/* Mux control */ +#define _MUX_1802 0 +#define _MUX_STM 1 + +uint8_t MUX_CONTROL; + +/* Signals muxed between 1802 and STM */ +uint8_t +MRD(void) { + return ao_gpio_get(MRD_PORT, MRD_BIT, MRD_PIN); +} + +void +MRD_set(uint8_t value) { + ao_gpio_set(MRD_PORT, MRD_BIT, MRD_PIN, value); +} + +uint8_t +MWR(void) { + return ao_gpio_get(MWR_PORT, MWR_BIT, MWR_PIN); +} + +void +MWR_set(uint8_t value) { + ao_gpio_set(MWR_PORT, MWR_BIT, MWR_PIN, value); +} + +static void +TPA_rising(void) +{ + ADDRESS = (ADDRESS & 0x00ff) | ((uint16_t) MA() << 8); + ao_wakeup(&ADDRESS); +} + +uint8_t +TPA(void) { + return ao_gpio_get(TPA_PORT, TPA_BIT, TPA_PIN); +} + +void +TPA_set(uint8_t tpa) { + ao_gpio_set(TPA_PORT, TPA_BIT, TPA_PIN, tpa); + if (tpa) + TPA_rising(); +} + +static void +TPB_rising(void) +{ + ADDRESS = (ADDRESS & 0xff00) | MA(); + if (MWR() == 0 || MRD() == 0) + DATA = BUS(); + ao_wakeup(&ADDRESS); +} + +static void +TPB_falling(void) +{ +} + +uint8_t +TPB(void) { + return ao_gpio_get(TPB_PORT, TPB_BIT, TPB_PIN); +} + +void +TPB_set(uint8_t tpb) { + ao_gpio_set(TPB_PORT, TPB_BIT, TPB_PIN, tpb); + if (tpb) + TPB_rising(); + else + TPB_falling(); +} + +uint8_t +MA(void) { + return (ao_gpio_get_all(MA_PORT) >> MA_SHIFT) & MA_MASK; +} + +void +MA_set(uint8_t ma) { + ao_gpio_set_mask(MA_PORT, ((uint16_t) ma) << MA_SHIFT, MA_MASK << MA_SHIFT); +} + +/* Tri-state data bus */ + +uint8_t +BUS(void) { + return ao_flip_bits_8[(ao_gpio_get_all(BUS_PORT) >> BUS_SHIFT) & BUS_MASK]; +} + +void +BUS_set(uint8_t bus) { + ao_gpio_set_mask(BUS_PORT, ao_flip_bits_8[bus] << BUS_SHIFT, BUS_MASK << BUS_SHIFT); +} + +void +BUS_stm(void) +{ + ao_set_output_mask(BUS_PORT, BUS_MASK << BUS_SHIFT); +} + +void +BUS_1802(void) +{ + ao_set_input_mask(BUS_PORT, BUS_MASK << BUS_SHIFT); +} + +/* Pins controlled by 1802 */ +uint8_t +SC(void) { + return ao_flip_bits_2[(ao_gpio_get_all(SC_PORT) >> SC_SHIFT) & SC_MASK]; +} + +uint8_t +Q(void) { + return ao_gpio_get(Q_PORT, Q_BIT, Q_PIN); +} + +uint8_t +N(void) { + return (ao_gpio_get_all(N_PORT) >> N_SHIFT) & N_MASK; +} + +/* Pins controlled by STM */ +uint8_t +EF(void) { + return (ao_gpio_get_all(EF_PORT) >> EF_SHIFT) & EF_MASK; +} + +void +EF_set(uint8_t ef) { + ao_gpio_set_mask(EF_PORT, ef << EF_SHIFT, EF_MASK << EF_SHIFT); +} + +uint8_t +DMA_IN(void) { + return ao_gpio_get(DMA_IN_PORT, DMA_IN_BIT, DMA_IN_PIN); +} + +void +DMA_IN_set(uint8_t dma_in) { + ao_gpio_set(DMA_IN_PORT, DMA_IN_BIT, DMA_IN_PIN, dma_in); +} + +uint8_t +DMA_OUT(void) { + return ao_gpio_get(DMA_OUT_PORT, DMA_OUT_BIT, DMA_OUT_PIN); +} + +void +DMA_OUT_set(uint8_t dma_out) { + ao_gpio_set(DMA_OUT_PORT, DMA_OUT_BIT, DMA_OUT_PIN, dma_out); +} + +uint8_t +INT(void) { + return ao_gpio_get(INT_PORT, INT_BIT, INT_PIN); +} + +void +INT_set(uint8_t dma_out) { + ao_gpio_set(INT_PORT, INT_BIT, INT_PIN, dma_out); +} + +uint8_t +CLEAR(void) { + return ao_gpio_get(CLEAR_PORT, CLEAR_BIT, CLEAR_PIN); +} + +void +CLEAR_set(uint8_t dma_out) { + ao_gpio_set(CLEAR_PORT, CLEAR_BIT, CLEAR_PIN, dma_out); +} + +uint8_t +WAIT(void) { + return ao_gpio_get(WAIT_PORT, WAIT_BIT, WAIT_PIN); +} + +void +WAIT_set(uint8_t dma_out) { + ao_gpio_set(WAIT_PORT, WAIT_BIT, WAIT_PIN, dma_out); +} + +void +tpb_isr(void) { + /* Latch low address and data on rising edge of TPB */ + if (TPB()) + TPB_rising(); + else + TPB_falling(); +} + +void +tpa_isr(void) { + /* Latch high address on rising edge of TPA */ + if (TPA()) + TPA_rising(); +} + +#define ao_1802_in(port, bit, mode) do { \ + ao_gpio_set_mode(port, bit, mode); \ + ao_set_input(port, bit); \ + } while (0) + +#define ao_1802_in_isr(port, bit, mode) do { \ + ao_gpio_set_mode(port, bit, mode); \ + ao_set_input(port, bit); \ + ao_exti_enable(port, bit); \ + } while (0) + +#define ao_1802_out_isr(port, bit) do { \ + ao_exti_disable(port, bit); \ + ao_set_output(port, bit); \ + } while (0) + +void +MUX_1802(void) +{ + if (MUX_CONTROL != _MUX_1802) { + /* Set pins to input, but pulled to idle value */ + ao_1802_in(MRD_PORT, MRD_BIT, AO_EXTI_MODE_PULL_UP); + ao_1802_in(MWR_PORT, MWR_BIT, AO_EXTI_MODE_PULL_UP); + ao_1802_in_isr(TPB_PORT, TPB_BIT, AO_EXTI_MODE_PULL_DOWN); + ao_1802_in_isr(TPA_PORT, TPA_BIT, AO_EXTI_MODE_PULL_DOWN); + ao_set_input_mask(MA_PORT, MA_MASK << MA_SHIFT); + + ao_gpio_set(MUX_PORT, MUX_BIT, MUX_PIN, 0); + + /* Now change the pins to eliminate the pull up/down */ + ao_gpio_set_mode(MRD_PORT, MRD_BIT, 0); + ao_gpio_set_mode(MWR_PORT, MWR_BIT, 0); + ao_gpio_set_mode(TPB_PORT, TPB_BIT, 0); + ao_gpio_set_mode(TPA_PORT, TPA_BIT, 0); + + MUX_CONTROL = _MUX_1802; + } +} + +void +MUX_stm(void) +{ + if (MUX_CONTROL != _MUX_STM) { + /* Set the pins back to pull to the idle value */ + ao_gpio_set_mode(MRD_PORT, MRD_BIT, AO_EXTI_MODE_PULL_UP); + ao_gpio_set_mode(MWR_PORT, MWR_BIT, AO_EXTI_MODE_PULL_UP); + ao_gpio_set_mode(TPB_PORT, TPB_BIT, AO_EXTI_MODE_PULL_DOWN); + ao_gpio_set_mode(TPA_PORT, TPA_BIT, AO_EXTI_MODE_PULL_DOWN); + + ao_gpio_set(MUX_PORT, MUX_BIT, MUX_PIN, 1); + + /* Now set the pins as output, driven to the idle value */ + ao_set_output(MRD_PORT, MRD_BIT, MRD_PIN, 1); + ao_set_output(MWR_PORT, MWR_BIT, MWR_PIN, 1); + ao_set_output(TPB_PORT, TPB_BIT, TPB_PIN, 0); + ao_set_output(TPA_PORT, TPA_BIT, TPA_PIN, 0); + ao_set_output_mask(MA_PORT, MA_MASK << MA_SHIFT); + MUX_CONTROL = _MUX_STM; + } +} + +void +ao_1802_init(void) +{ + /* Multiplexed signals*/ + + /* active low signals */ + ao_enable_input(MRD_PORT, MRD_BIT, AO_EXTI_MODE_PULL_UP); + ao_enable_input(MWR_PORT, MWR_BIT, AO_EXTI_MODE_PULL_UP); + + /* active high signals with interrupts */ + ao_exti_setup(TPA_PORT, TPA_BIT, + AO_EXTI_MODE_PULL_DOWN | AO_EXTI_MODE_RISING | AO_EXTI_MODE_FALLING, + tpa_isr); + ao_exti_setup(TPB_PORT, TPB_BIT, + AO_EXTI_MODE_PULL_DOWN | AO_EXTI_MODE_RISING | AO_EXTI_MODE_FALLING, + tpb_isr); + + /* multiplexed address bus */ + ao_enable_input_mask(MA_PORT, MA_MASK << MA_SHIFT, 0); + + /* Data bus */ + + ao_enable_input_mask(BUS_PORT, BUS_MASK << BUS_SHIFT, 0); + + /* Pins controlled by 1802 */ + ao_enable_input_mask(SC_PORT, SC_MASK << SC_SHIFT, 0); + ao_enable_input(Q_PORT, Q_BIT, 0); + ao_enable_input_mask(N_PORT, N_MASK << N_SHIFT, 0); + + /* Pins controlled by STM */ + ao_enable_output_mask(EF_PORT, 0, EF_MASK << EF_SHIFT); + ao_enable_output(DMA_IN_PORT, DMA_IN_BIT, DMA_IN_PIN, 1); + ao_enable_output(DMA_OUT_PORT, DMA_OUT_BIT, DMA_OUT_PIN, 1); + ao_enable_output(INT_PORT, INT_BIT, INT_PIN, 1); + ao_enable_output(CLEAR_PORT, CLEAR_BIT, CLEAR_PIN, 1); + ao_enable_output(WAIT_PORT, WAIT_BIT, WAIT_PIN, 1); + + /* Force configuration to STM so that MUX_1802 will do something */ + MUX_CONTROL = _MUX_STM; + MUX_1802(); +} diff --git a/src/cortexelf-v1/ao_1802.h b/src/cortexelf-v1/ao_1802.h new file mode 100644 index 00000000..5ea89fee --- /dev/null +++ b/src/cortexelf-v1/ao_1802.h @@ -0,0 +1,129 @@ +/* + * Copyright © 2017 Keith Packard <keithp@keithp.com> + * + * 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 2 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. + */ + +#ifndef _AO_1802_H_ +#define _AO_1802_H_ + +/* Decoded address driven by TPA/TPB signals */ +extern uint16_t ADDRESS; + +/* Decoded data, driven by TPB signal */ +extern uint8_t DATA; + +uint8_t +MRD(void); + +void +MRD_set(uint8_t value); + +uint8_t +MWR(void); + +void +MWR_set(uint8_t value); + +uint8_t +TPA(void); + +void +TPA_set(uint8_t tpa); + +uint8_t +TPB(void); + +void +TPB_set(uint8_t tpb); + +uint8_t +MA(void); + +void +MA_set(uint8_t ma); + +/* Tri-state data bus */ + +uint8_t +BUS(void); + +void +BUS_set(uint8_t bus); + +void +BUS_stm(void); + +void +BUS_1802(void); + +/* Pins controlled by 1802 */ +uint8_t +SC(void); + +uint8_t +Q(void); + +uint8_t +N(void); + +/* Pins controlled by STM */ +uint8_t +EF(void); + +void +EF_set(uint8_t ef); + +uint8_t +DMA_IN(void); + +void +DMA_IN_set(uint8_t dma_in); + +uint8_t +DMA_OUT(void); + +void +DMA_OUT_set(uint8_t dma_out); + +uint8_t +INT(void); + +void +INT_set(uint8_t dma_out); + +uint8_t +CLEAR(void); + +void +CLEAR_set(uint8_t dma_out); + +uint8_t +WAIT(void); + +void +WAIT_set(uint8_t dma_out); + +#define SC_FETCH 0 +#define SC_EXECUTE 1 +#define SC_DMA 2 +#define SC_INTERRUPT 3 + +void +MUX_1802(void); + +void +MUX_stm(void); + +void +ao_1802_init(void); + +#endif /* _AO_1802_H_ */ diff --git a/src/cortexelf-v1/ao_cortexelf.c b/src/cortexelf-v1/ao_cortexelf.c new file mode 100644 index 00000000..61a9d219 --- /dev/null +++ b/src/cortexelf-v1/ao_cortexelf.c @@ -0,0 +1,291 @@ +/* + * Copyright © 2011 Keith Packard <keithp@keithp.com> + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include <ao.h> +#include <ao_exti.h> +#include <ao_profile.h> +#if HAS_STACK_GUARD +#include <ao_mpu.h> +#endif +#include <ao_ps2.h> +#include <ao_vga.h> +#include <ao_console.h> +#include <ao_sdcard.h> +#include <ao_fat.h> +#include <ao_lisp.h> +#include <ao_button.h> +#include <ao_event.h> +#include <ao_as1107.h> +#include <ao_hex.h> +#include <ao_1802.h> + +struct ao_task ball_task; + +#define BALL_WIDTH 5 +#define BALL_HEIGHT 5 + +static int ball_x; +static int ball_y; +static int ball_dx, ball_dy; + +uint8_t ball_enable; + +void +ao_ball(void) +{ + ball_dx = 1; + ball_dy = 1; + ball_x = 0; + ball_y = 0; + for (;;) { + while (!ball_enable) + ao_sleep(&ball_enable); + for (;;) { + ao_line(&ao_vga_bitmap, + -100, -100, ball_x*2, ball_y*2, + 1, AO_XOR); + ao_text(&ao_vga_bitmap, + ball_x, ball_y - 10, + "Hello, Bdale!", + 1, AO_XOR); + ao_rect(&ao_vga_bitmap, + ball_x, ball_y, + BALL_WIDTH, + BALL_HEIGHT, + 1, + AO_XOR); + ao_delay(AO_MS_TO_TICKS(10)); + ao_rect(&ao_vga_bitmap, + ball_x, ball_y, + BALL_WIDTH, + BALL_HEIGHT, + 1, + AO_XOR); + ao_text(&ao_vga_bitmap, + ball_x, ball_y - 10, + "Hello, Bdale!", + 1, AO_XOR); + ao_line(&ao_vga_bitmap, + -100, -100, ball_x*2, ball_y*2, + 1, AO_XOR); + if (!ball_enable) + break; + ball_x += ball_dx; + ball_y += ball_dy; + if (ball_x + BALL_WIDTH > AO_VGA_WIDTH) { + ball_x = AO_VGA_WIDTH - BALL_WIDTH; + ball_dx = -ball_dx; + } + if (ball_x < 0) { + ball_x = -ball_x; + ball_dx = -ball_dx; + } + if (ball_y + BALL_HEIGHT > AO_VGA_HEIGHT) { + ball_y = AO_VGA_HEIGHT - BALL_HEIGHT; + ball_dy = -ball_dy; + } + if (ball_y < 0) { + ball_y = -ball_y; + ball_dy = -ball_dy; + } + } + } +} + +static void +ao_fb_init(void) +{ + ao_rect(&ao_vga_bitmap, + 0, 0, AO_VGA_WIDTH, AO_VGA_HEIGHT, + 1, AO_COPY); + + ao_rect(&ao_vga_bitmap, + 10, 10, 10, 10, + 0, AO_COPY); + + ao_rect(&ao_vga_bitmap, + AO_VGA_WIDTH - 20, 10, 10, 10, + 0, AO_COPY); + + ao_rect(&ao_vga_bitmap, + 10, AO_VGA_HEIGHT - 20, 10, 10, + 0, AO_COPY); + + ao_rect(&ao_vga_bitmap, + AO_VGA_WIDTH - 20, AO_VGA_HEIGHT - 20, 10, 10, + 0, AO_COPY); + + ao_text(&ao_vga_bitmap, + 20, 100, + "Hello, Bdale!", + 0, AO_COPY); + + ao_text(&ao_vga_bitmap, + 1, ao_font.ascent, + "UL", + 0, AO_COPY); + + ao_text(&ao_vga_bitmap, + 1, AO_VGA_HEIGHT - ao_font.descent, + "BL", + 0, AO_COPY); +} + +static void +ao_video_toggle(void) +{ + ao_cmd_decimal(); + if (ao_cmd_lex_i) + ao_fb_init(); + ao_vga_enable(ao_cmd_lex_i); +} + +static void +ao_ball_toggle(void) +{ + ao_cmd_decimal(); + ball_enable = ao_cmd_lex_i; + ao_wakeup(&ball_enable); +} + +static void +ao_ps2_read_keys(void) +{ + char c; + + for (;;) { + c = ao_ps2_getchar(); + printf("%02x %c\n", c, ' ' <= c && c < 0x7f ? c : '.'); + flush(); + if (c == ' ') + break; + } +} + +static void +ao_console_send(void) +{ + char c; + + while ((c = getchar()) != '~') { + ao_console_putchar(c); + flush(); + } +} + +static void lisp_cmd() { + ao_lisp_read_eval_print(); +} + +static void +ao_serial_blather(void) +{ + char c; + + while ((c = getchar()) != '~') { + ao_serial1_putchar(c); + ao_serial2_putchar(c); + } +} + +static void +led_cmd(void) +{ + uint8_t start; + uint8_t value; + ao_cmd_decimal(); + + start = ao_cmd_lex_i; + ao_cmd_hex(); + value = ao_cmd_lex_i; + if (ao_cmd_status != ao_cmd_success) + return; + ao_as1107_write_8(start, value); +} + +__code struct ao_cmds ao_demo_cmds[] = { + { ao_video_toggle, "V\0Toggle video" }, + { ao_ball_toggle, "B\0Toggle ball" }, + { ao_ps2_read_keys, "K\0Read keys from keyboard" }, + { ao_console_send, "C\0Send data to console, end with ~" }, + { ao_serial_blather, "S\0Blather on serial ports briefly" }, + { lisp_cmd, "l\0Run lisp interpreter" }, + { led_cmd, "L start value\0Show value (byte) at digit start" }, + { 0, NULL } +}; + +static struct ao_task event_task; + +static void +ao_event_loop(void) +{ + for (;;) { + struct ao_event ev; + + ao_event_get(&ev); + printf("type %d uint %d tick %d value %d\n", + ev.type, ev.unit, ev.tick, ev.value); + flush(); + } +} + +int +main(void) +{ + ao_clock_init(); + +#if HAS_STACK_GUARD + ao_mpu_init(); +#endif + + ao_task_init(); + ao_serial_init(); + ao_timer_init(); + + ao_spi_init(); + ao_dma_init(); + ao_exti_init(); + + ao_sdcard_init(); + ao_fat_init(); + + ao_ps2_init(); + ao_vga_init(); + ao_console_init(); + + ao_cmd_init(); + + ao_usb_init(); + + ao_button_init(); + + ao_as1107_init(); + ao_matrix_init(); + ao_1802_init(); + + ao_hex_init(); + + ao_config_init(); + + ao_add_task(&ball_task, ao_ball, "ball"); + ao_add_task(&event_task, ao_event_loop, "events"); + ao_cmd_register(&ao_demo_cmds[0]); + + ao_start_scheduler(); + return 0; +} diff --git a/src/cortexelf-v1/ao_flip_bits.5c b/src/cortexelf-v1/ao_flip_bits.5c new file mode 100644 index 00000000..cd5507cc --- /dev/null +++ b/src/cortexelf-v1/ao_flip_bits.5c @@ -0,0 +1,24 @@ +#!/usr/bin/nickle + +int flip_bits(int a, int n) +{ + int result = 0; + for (int pos = 0; pos < n; pos++) + if ((a & (1 << pos)) != 0) + result |= (1 << (n - 1 - pos)); + return result; +} + +void print_flip_bits(string name, int n) { + printf ("static const uint8_t %s_%d[%d] = {\n", name, n, 1 << n); + + for (int i = 0; i < 1 << n; i++) { + printf (" 0x%02x,", flip_bits(i, n)); + if ((i & 0xf) == 0xf) + printf("\n"); + } + printf("};\n"); +} + +print_flip_bits("ao_flip_bits", 8); +print_flip_bits("ao_flip_bits", 2); diff --git a/src/cortexelf-v1/ao_hex.c b/src/cortexelf-v1/ao_hex.c new file mode 100644 index 00000000..1507407b --- /dev/null +++ b/src/cortexelf-v1/ao_hex.c @@ -0,0 +1,36 @@ +/* + * Copyright © 2017 Keith Packard <keithp@keithp.com> + * + * 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 2 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. + */ + +#include <ao.h> +#include "ao_hex.h" +#include "ao_as1107.h" +#include "ao_1802.h" + +static struct ao_task ao_hex_task; + +static void +ao_hex(void) +{ + for (;;) { + ao_as1107_write_16(0, ADDRESS); + ao_as1107_write_8(6, DATA); + ao_sleep(&ADDRESS); + } +} + +void +ao_hex_init(void) +{ + ao_add_task(&ao_hex_task, ao_hex, "hex"); +} diff --git a/src/cortexelf-v1/ao_hex.h b/src/cortexelf-v1/ao_hex.h new file mode 100644 index 00000000..674c1eee --- /dev/null +++ b/src/cortexelf-v1/ao_hex.h @@ -0,0 +1,21 @@ +/* + * Copyright © 2017 Keith Packard <keithp@keithp.com> + * + * 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 2 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. + */ + +#ifndef _AO_HEX_H_ +#define _AO_HEX_H_ + +void +ao_hex_init(void); + +#endif /* _AO_HEX_H_ */ diff --git a/src/cortexelf-v1/ao_lisp_os.h b/src/cortexelf-v1/ao_lisp_os.h new file mode 100644 index 00000000..d0c1f7b7 --- /dev/null +++ b/src/cortexelf-v1/ao_lisp_os.h @@ -0,0 +1,65 @@ +/* + * Copyright © 2016 Keith Packard <keithp@keithp.com> + * + * 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; version 2 of the License. + * + * 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, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_LISP_OS_H_ +#define _AO_LISP_OS_H_ + +#include "ao.h" + +#define AO_LISP_POOL_TOTAL 16384 +#define AO_LISP_SAVE 1 + +static inline int +ao_lisp_getc() { + static uint8_t at_eol; + int c; + + if (at_eol) { + ao_cmd_readline(); + at_eol = 0; + } + c = ao_cmd_lex(); + if (c == '\n') + at_eol = 1; + return c; +} + +static inline void +ao_lisp_os_flush(void) +{ + flush(); +} + +static inline void +ao_lisp_abort(void) +{ + ao_panic(1); +} + +static inline void +ao_lisp_os_led(int led) +{ + (void) led; +} + +static inline void +ao_lisp_os_delay(int delay) +{ + ao_delay(AO_MS_TO_TICKS(delay)); +} + +#endif diff --git a/src/cortexelf-v1/ao_lisp_os_save.c b/src/cortexelf-v1/ao_lisp_os_save.c new file mode 100644 index 00000000..7c853990 --- /dev/null +++ b/src/cortexelf-v1/ao_lisp_os_save.c @@ -0,0 +1,53 @@ +/* + * Copyright © 2016 Keith Packard <keithp@keithp.com> + * + * 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 2 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. + */ + +#include <ao.h> +#include <ao_lisp.h> +#include <ao_flash.h> + +extern uint8_t __flash__[]; + +/* saved variables to rebuild the heap + + ao_lisp_atoms + ao_lisp_frame_global + */ + +int +ao_lisp_os_save(void) +{ + int i; + + for (i = 0; i < AO_LISP_POOL_TOTAL; i += 256) { + uint32_t *dst = (uint32_t *) (void *) &__flash__[i]; + uint32_t *src = (uint32_t *) (void *) &ao_lisp_pool[i]; + + ao_flash_page(dst, src); + } + return 1; +} + +int +ao_lisp_os_restore_save(struct ao_lisp_os_save *save, int offset) +{ + memcpy(save, &__flash__[offset], sizeof (struct ao_lisp_os_save)); + return 1; +} + +int +ao_lisp_os_restore(void) +{ + memcpy(ao_lisp_pool, __flash__, AO_LISP_POOL_TOTAL); + return 1; +} diff --git a/src/cortexelf-v1/ao_pins.h b/src/cortexelf-v1/ao_pins.h new file mode 100644 index 00000000..258ffe31 --- /dev/null +++ b/src/cortexelf-v1/ao_pins.h @@ -0,0 +1,265 @@ +/* + * Copyright © 2012 Keith Packard <keithp@keithp.com> + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_PINS_H_ +#define _AO_PINS_H_ + +#define HAS_TASK_QUEUE 1 + +/* 8MHz High speed external crystal */ +#define AO_HSE 8000000 + +/* PLLVCO = 96MHz (so that USB will work) */ +#define AO_PLLMUL 12 +#define AO_RCC_CFGR_PLLMUL (STM_RCC_CFGR_PLLMUL_12) + +/* SYSCLK = 24MHz */ +#define AO_PLLDIV 4 +#define AO_RCC_CFGR_PLLDIV (STM_RCC_CFGR_PLLDIV_4) + +/* HCLK = 24MHz (CPU clock) */ +#define AO_AHB_PRESCALER 1 +#define AO_RCC_CFGR_HPRE_DIV STM_RCC_CFGR_HPRE_DIV_1 + +/* Run APB1 at HCLK/1 */ +#define AO_APB1_PRESCALER 1 +#define AO_RCC_CFGR_PPRE1_DIV STM_RCC_CFGR_PPRE1_DIV_1 + +/* Run APB2 at HCLK/1 */ +#define AO_APB2_PRESCALER 1 +#define AO_RCC_CFGR_PPRE2_DIV STM_RCC_CFGR_PPRE2_DIV_1 + +/* Allow for non-maskable interrupts at priority 0 */ +#define AO_NONMASK_INTERRUPT 1 + +/* PS/2 keyboard connection */ +#define AO_PS2_CLOCK_PORT (&stm_gpiod) +#define AO_PS2_CLOCK_BIT 9 +#define AO_PS2_DATA_PORT (&stm_gpiod) +#define AO_PS2_DATA_BIT 8 + +#define HAS_SERIAL_1 1 +#define USE_SERIAL_1_STDIN 1 +#define SERIAL_1_PB6_PB7 1 +#define SERIAL_1_PA9_PA10 0 + +#define HAS_SERIAL_2 1 +#define USE_SERIAL_2_STDIN 1 +#define SERIAL_2_PA2_PA3 0 +#define SERIAL_2_PD5_PD6 1 + +#define HAS_SERIAL_3 0 +#define USE_SERIAL_3_STDIN 0 +#define SERIAL_3_PB10_PB11 0 +#define SERIAL_3_PC10_PC11 0 +#define SERIAL_3_PD8_PD9 0 + +#define HAS_EEPROM 0 +#define USE_INTERNAL_FLASH 0 +#define USE_EEPROM_CONFIG 0 +#define USE_STORAGE_CONFIG 0 +#define HAS_USB 1 +#define HAS_BEEP 0 +#define HAS_BATTERY_REPORT 0 +#define HAS_RADIO 0 +#define HAS_TELEMETRY 0 +#define HAS_APRS 0 +#define HAS_COMPANION 0 + +#define HAS_SPI_1 0 +#define SPI_1_PA5_PA6_PA7 0 +#define SPI_1_PB3_PB4_PB5 0 +#define SPI_1_PE13_PE14_PE15 0 +#define SPI_1_OSPEEDR STM_OSPEEDR_10MHz + +#define HAS_SPI_2 1 +#define SPI_2_PB13_PB14_PB15 0 +#define SPI_2_PD1_PD3_PD4 1 /* LED displays, microSD */ +#define SPI_2_OSPEEDR STM_OSPEEDR_40MHz + +#define SPI_2_PORT (&stm_gpiod) +//#define SPI_2_SCK_PIN 1 +//#define SPI_2_MISO_PIN 3 +//#define SPI_2_MOSI_PIN 4 + +#define HAS_I2C_1 0 +#define I2C_1_PB8_PB9 0 + +#define HAS_I2C_2 0 +#define I2C_2_PB10_PB11 0 + +#define PACKET_HAS_SLAVE 0 +#define PACKET_HAS_MASTER 0 + +#define LOW_LEVEL_DEBUG 0 + +#define HAS_GPS 0 +#define HAS_FLIGHT 0 +#define HAS_ADC 0 +#define HAS_ADC_TEMP 0 +#define HAS_LOG 0 + +#define NUM_CMDS 16 + +/* SD card */ +#define AO_SDCARD_SPI_BUS AO_SPI_2_PD1_PD3_PD4 +#define AO_SDCARD_SPI_CS_PORT (&stm_gpiod) +#define AO_SDCARD_SPI_CS_PIN 2 +#define AO_SDCARD_SPI_PORT (&stm_gpiod) +#define AO_SDCARD_SPI_SCK_PIN 1 +#define AO_SDCARD_SPI_MISO_PIN 3 +#define AO_SDCARD_SPI_MOSI_PIN 4 + +/* VGA */ +#define STM_DMA1_3_STOLEN 1 +/* Buttons */ + +#define AO_EVENT 1 + +#define AO_BUTTON_COUNT 4 +#define AO_BUTTON_MODE AO_EXTI_MODE_PULL_DOWN +#define AO_BUTTON_INVERTED 0 + +/* INPUT */ +#define AO_BUTTON_0_PORT (&stm_gpioc) +#define AO_BUTTON_0 8 + +/* MP */ +#define AO_BUTTON_1_PORT (&stm_gpioc) +#define AO_BUTTON_1 9 + +/* RUN */ +#define AO_BUTTON_2_PORT (&stm_gpioc) +#define AO_BUTTON_2 10 + +/* LOAD */ +#define AO_BUTTON_3_PORT (&stm_gpioc) +#define AO_BUTTON_3 11 + +/* AS1107 */ +#define AO_AS1107_NUM_DIGITS 8 + +/* Set the hex digits up for decode, leave the extra leds alone */ + +#define AO_AS1107_DECODE ((1 << 7) | \ + (1 << 6) | \ + (1 << 4) | \ + (1 << 3) | \ + (1 << 1) | \ + (1 << 0)) + +#define AO_AS1107_SPI_INDEX AO_SPI_2_PD1_PD3_PD4 +#define AO_AS1107_SPI_SPEED AO_SPI_SPEED_8MHz +#define AO_AS1107_CS_PORT (&stm_gpiod) +#define AO_AS1107_CS_PIN 0 + +/* Hex keypad */ + +#define AO_MATRIX_ROWS 4 +#define AO_MATRIX_COLS 4 + +#define AO_MATRIX_KEYCODES { \ + { 0x0, 0x1, 0x2, 0x3 }, \ + { 0x4, 0x5, 0x6, 0x7 }, \ + { 0x8, 0x9, 0xa, 0xb }, \ + { 0xc, 0xd, 0xe, 0xf } \ + } + +#include <ao_matrix.h> + +#define AO_TIMER_HOOK ao_matrix_poll() + +#define AO_MATRIX_ROW_0_PORT (&stm_gpioc) +#define AO_MATRIX_ROW_0_PIN 4 + +#define AO_MATRIX_ROW_1_PORT (&stm_gpioc) +#define AO_MATRIX_ROW_1_PIN 1 + +#define AO_MATRIX_ROW_2_PORT (&stm_gpioc) +#define AO_MATRIX_ROW_2_PIN 7 + +#define AO_MATRIX_ROW_3_PORT (&stm_gpioc) +#define AO_MATRIX_ROW_3_PIN 0 + +#define AO_MATRIX_COL_0_PORT (&stm_gpioc) +#define AO_MATRIX_COL_0_PIN 2 + +#define AO_MATRIX_COL_1_PORT (&stm_gpioc) +#define AO_MATRIX_COL_1_PIN 3 + +#define AO_MATRIX_COL_2_PORT (&stm_gpioc) +#define AO_MATRIX_COL_2_PIN 5 + +#define AO_MATRIX_COL_3_PORT (&stm_gpioc) +#define AO_MATRIX_COL_3_PIN 6 + +/* 1802 connections */ +#define MRD_PORT (&stm_gpiob) +#define MRD_BIT 15 + +#define MWR_PORT (&stm_gpioa) +#define MWR_BIT 3 + +#define TPB_PORT (&stm_gpioa) +#define TPB_BIT 7 + +#define TPA_PORT (&stm_gpioa) +#define TPA_BIT 6 + +#define MA_PORT (&stm_gpioe) +#define MA_SHIFT 0 +#define MA_MASK 0xff + +#define BUS_PORT (&stm_gpioe) +#define BUS_SHIFT 8 +#define BUS_MASK 0xff + +#define SC_PORT (&stm_gpiob) +#define SC_SHIFT 13 +#define SC_MASK 3 + +#define Q_PORT (&stm_gpiob) +#define Q_BIT 12 + +#define N_PORT (&stm_gpiod) +#define N_SHIFT 13 +#define N_MASK 7 + +#define EF_PORT (&stm_gpiob) +#define EF_SHIFT 8 +#define EF_MASK 0xf + +#define DMA_IN_PORT (&stm_gpioa) +#define DMA_IN_BIT 0 + +#define DMA_OUT_PORT (&stm_gpioa) +#define DMA_OUT_BIT 9 + +#define INT_PORT (&stm_gpioa) +#define INT_BIT 2 + +#define CLEAR_PORT (&stm_gpioa) +#define CLEAR_BIT 10 + +#define WAIT_PORT (&stm_gpioa) +#define WAIT_BIT 4 + +#define MUX_PORT (&stm_gpiob) +#define MUX_BIT 1 + +#endif /* _AO_PINS_H_ */ diff --git a/src/cortexelf-v1/cortexelf.ld b/src/cortexelf-v1/cortexelf.ld new file mode 100644 index 00000000..6ad2a679 --- /dev/null +++ b/src/cortexelf-v1/cortexelf.ld @@ -0,0 +1,101 @@ +/* + * Copyright © 2017 Keith Packard <keithp@keithp.com> + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +MEMORY { + rom (rx) : ORIGIN = 0x08001000, LENGTH = 492K + flash (r) : ORIGIN = 0x0807c000, LENGTH = 16K + ram (!w) : ORIGIN = 0x20000000, LENGTH = 81408 + stack (!w) : ORIGIN = 0x20013e00, LENGTH = 512 +} + +INCLUDE registers.ld + +EXTERN (stm_interrupt_vector) + +SECTIONS { + /* + * Rom contents + */ + + .text ORIGIN(rom) : { + __text_start__ = .; + *(.interrupt) /* Interrupt vectors */ + + . = ORIGIN(rom) + 0x100; + + + /* Ick. What I want is to specify the + * addresses of some global constants so + * that I can find them across versions + * of the application. I can't figure out + * how to make gnu ld do that, so instead + * we just load the two files that include + * these defines in the right order here and + * expect things to 'just work'. Don't change + * the contents of those files, ok? + */ + ao_romconfig.o(.romconfig*) + ao_product.o(.romconfig*) + *(.text*) /* Executable code */ + *(.rodata*) /* Constants */ + + } > rom + + .ARM.exidx : { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > rom + __text_end__ = .; + + /* Boot data which must live at the start of ram so that + * the application and bootloader share the same addresses. + * This must be all uninitialized data + */ + .boot (NOLOAD) : { + __boot_start__ = .; + *(.boot) + . = ALIGN(4); + __boot_end__ = .; + } >ram + + /* Data -- relocated to RAM, but written to ROM + */ + .data : { + __data_start__ = .; + *(.data) /* initialized data */ + . = ALIGN(4); + __data_end__ = .; + } >ram AT>rom + + .bss : { + __bss_start__ = .; + *(.bss) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + } >ram + + PROVIDE(end = .); + + PROVIDE(__stack__ = ORIGIN(stack) + LENGTH(stack)); + + __flash__ = ORIGIN(flash); +} + +ENTRY(start); + + diff --git a/src/cortexelf-v1/flash-loader/Makefile b/src/cortexelf-v1/flash-loader/Makefile new file mode 100644 index 00000000..19cf84e4 --- /dev/null +++ b/src/cortexelf-v1/flash-loader/Makefile @@ -0,0 +1,8 @@ +# +# AltOS flash loader build +# +# + +TOPDIR=../.. +HARDWARE=cortexelf-v1 +include $(TOPDIR)/stm/Makefile-flash.defs diff --git a/src/cortexelf-v1/flash-loader/ao_pins.h b/src/cortexelf-v1/flash-loader/ao_pins.h new file mode 100644 index 00000000..5d63dc2c --- /dev/null +++ b/src/cortexelf-v1/flash-loader/ao_pins.h @@ -0,0 +1,35 @@ +/* + * Copyright © 2013 Keith Packard <keithp@keithp.com> + * + * 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 2 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, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#ifndef _AO_PINS_H_ +#define _AO_PINS_H_ + +/* External crystal at 8MHz */ +#define AO_HSE 8000000 + +#include <ao_flash_stm_pins.h> + +/* MP switch, gpioc 9 */ + +#define AO_BOOT_PIN 1 +#define AO_BOOT_APPLICATION_GPIO stm_gpioc +#define AO_BOOT_APPLICATION_PIN 9 +#define AO_BOOT_APPLICATION_VALUE 1 +#define AO_BOOT_APPLICATION_MODE 0 + +#endif /* _AO_PINS_H_ */ |