From c8d5fe2352e1bc5805af75af7a274f8d358a4223 Mon Sep 17 00:00:00 2001 From: Teufelchen1 Date: Thu, 27 Apr 2023 15:05:47 +0200 Subject: [PATCH] boards/cpu: Add limited GBA boot support to RIOT --- boards/gba_cartridge/Kconfig | 13 + boards/gba_cartridge/Makefile | 3 + boards/gba_cartridge/Makefile.features | 2 + boards/gba_cartridge/Makefile.include | 1 + boards/gba_cartridge/doc.txt | 5 + boards/gba_cartridge/include/board.h | 34 +++ boards/gba_cartridge/include/periph_conf.h | 34 +++ cpu/arm7_common/include/arm_cpu.h | 11 + cpu/arm7tdmi_gba/Makefile | 11 + cpu/arm7tdmi_gba/Makefile.default | 1 + cpu/arm7tdmi_gba/Makefile.dep | 7 + cpu/arm7tdmi_gba/Makefile.features | 10 + cpu/arm7tdmi_gba/Makefile.include | 3 + cpu/arm7tdmi_gba/cartridge_header.s | 54 ++++ cpu/arm7tdmi_gba/cpu.c | 30 +++ cpu/arm7tdmi_gba/doc.txt | 5 + cpu/arm7tdmi_gba/include/cpu.h | 30 +++ cpu/arm7tdmi_gba/include/cpu_conf.h | 94 +++++++ cpu/arm7tdmi_gba/include/periph_cpu.h | 38 +++ cpu/arm7tdmi_gba/include/periph_gba.h | 106 ++++++++ cpu/arm7tdmi_gba/ldscripts/arm7tdmi_gba.ld | 213 +++++++++++++++ cpu/arm7tdmi_gba/startup.s | 92 +++++++ cpu/arm7tdmi_gba/stdio_fb/Makefile | 1 + cpu/arm7tdmi_gba/stdio_fb/font_terminal.h | 286 +++++++++++++++++++++ cpu/arm7tdmi_gba/stdio_fb/stdio_fb.c | 113 ++++++++ cpu/lpc23xx/include/cpu.h | 10 - features.yaml | 5 + makefiles/features_existing.inc.mk | 1 + makefiles/stdio.inc.mk | 1 + 29 files changed, 1204 insertions(+), 10 deletions(-) create mode 100644 boards/gba_cartridge/Kconfig create mode 100644 boards/gba_cartridge/Makefile create mode 100644 boards/gba_cartridge/Makefile.features create mode 100644 boards/gba_cartridge/Makefile.include create mode 100644 boards/gba_cartridge/doc.txt create mode 100644 boards/gba_cartridge/include/board.h create mode 100644 boards/gba_cartridge/include/periph_conf.h create mode 100644 cpu/arm7tdmi_gba/Makefile create mode 100644 cpu/arm7tdmi_gba/Makefile.default create mode 100644 cpu/arm7tdmi_gba/Makefile.dep create mode 100644 cpu/arm7tdmi_gba/Makefile.features create mode 100644 cpu/arm7tdmi_gba/Makefile.include create mode 100644 cpu/arm7tdmi_gba/cartridge_header.s create mode 100644 cpu/arm7tdmi_gba/cpu.c create mode 100644 cpu/arm7tdmi_gba/doc.txt create mode 100644 cpu/arm7tdmi_gba/include/cpu.h create mode 100644 cpu/arm7tdmi_gba/include/cpu_conf.h create mode 100644 cpu/arm7tdmi_gba/include/periph_cpu.h create mode 100644 cpu/arm7tdmi_gba/include/periph_gba.h create mode 100644 cpu/arm7tdmi_gba/ldscripts/arm7tdmi_gba.ld create mode 100644 cpu/arm7tdmi_gba/startup.s create mode 100644 cpu/arm7tdmi_gba/stdio_fb/Makefile create mode 100644 cpu/arm7tdmi_gba/stdio_fb/font_terminal.h create mode 100644 cpu/arm7tdmi_gba/stdio_fb/stdio_fb.c diff --git a/boards/gba_cartridge/Kconfig b/boards/gba_cartridge/Kconfig new file mode 100644 index 0000000000..942683c947 --- /dev/null +++ b/boards/gba_cartridge/Kconfig @@ -0,0 +1,13 @@ +# Copyright (c) 2023 HAW Hamburg +# +# This file is subject to the terms and conditions of the GNU Lesser +# General Public License v2.1. See the file LICENSE in the top level +# directory for more details. + +config BOARD + default "gba" if BOARD_GBA + +config BOARD_GBA + bool + default y + select CPU_MODEL_ARM7TDMI_GBA diff --git a/boards/gba_cartridge/Makefile b/boards/gba_cartridge/Makefile new file mode 100644 index 0000000000..f8fcbb53a0 --- /dev/null +++ b/boards/gba_cartridge/Makefile @@ -0,0 +1,3 @@ +MODULE = board + +include $(RIOTBASE)/Makefile.base diff --git a/boards/gba_cartridge/Makefile.features b/boards/gba_cartridge/Makefile.features new file mode 100644 index 0000000000..e70fc85f8e --- /dev/null +++ b/boards/gba_cartridge/Makefile.features @@ -0,0 +1,2 @@ +CPU = arm7tdmi_gba +CPU_MODEL = arm7tdmi_gba diff --git a/boards/gba_cartridge/Makefile.include b/boards/gba_cartridge/Makefile.include new file mode 100644 index 0000000000..a8ee432a45 --- /dev/null +++ b/boards/gba_cartridge/Makefile.include @@ -0,0 +1 @@ +FLASHFILE = $(BINFILE) diff --git a/boards/gba_cartridge/doc.txt b/boards/gba_cartridge/doc.txt new file mode 100644 index 0000000000..c02fb4b569 --- /dev/null +++ b/boards/gba_cartridge/doc.txt @@ -0,0 +1,5 @@ +/** +@defgroup boards_gba_cartridge GBA +@ingroup boards +@brief Support for the GBA + */ diff --git a/boards/gba_cartridge/include/board.h b/boards/gba_cartridge/include/board.h new file mode 100644 index 0000000000..1b96468332 --- /dev/null +++ b/boards/gba_cartridge/include/board.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2023 Bennet Blischke + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + */ + +/** + * @ingroup boards_gba_cartridge + * @{ + * + * @file + * @brief + * + * @author + */ + +#ifndef BOARD_H +#define BOARD_H + +#include "cpu.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* BOARD_H */ +/** @} */ diff --git a/boards/gba_cartridge/include/periph_conf.h b/boards/gba_cartridge/include/periph_conf.h new file mode 100644 index 0000000000..fd48dc9781 --- /dev/null +++ b/boards/gba_cartridge/include/periph_conf.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2023 Bennet Blischke + * + * This file is subject to the terms and conditions of the GNU Lesser General + * Public License v2.1. See the file LICENSE in the top level directory for more + * details. + */ + +/** + * @ingroup boards_gba_cartridge + * @{ + * + * @file + * @brief + * + * @author + */ + +#ifndef PERIPH_CONF_H +#define PERIPH_CONF_H + +#include "periph_cpu.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* PERIPH_CONF_H */ +/** @} */ diff --git a/cpu/arm7_common/include/arm_cpu.h b/cpu/arm7_common/include/arm_cpu.h index 5e64e2fc12..0885a0a3d6 100644 --- a/cpu/arm7_common/include/arm_cpu.h +++ b/cpu/arm7_common/include/arm_cpu.h @@ -25,6 +25,17 @@ void cpu_clock_scale(uint32_t source, uint32_t target, uint32_t *prescale); void arm_reset(void); +/** + * @brief Returns the current content of the link register (lr) + */ +static inline uintptr_t cpu_get_caller_pc(void) +{ + register uintptr_t lr_ptr; + + __asm__ __volatile__ ("mov %0, lr" : "=r" (lr_ptr)); + return lr_ptr; +} + /** * @brief Interrupt stack canary value * diff --git a/cpu/arm7tdmi_gba/Makefile b/cpu/arm7tdmi_gba/Makefile new file mode 100644 index 0000000000..47f9d0499b --- /dev/null +++ b/cpu/arm7tdmi_gba/Makefile @@ -0,0 +1,11 @@ +MODULE = cpu + +include $(RIOTCPU)/$(CPU)/Makefile.include + +DIRS = $(RIOTCPU)/arm7_common + +ifneq (,$(filter stdio_%,$(USEMODULE))) + DIRS += stdio_fb +endif + +include $(RIOTBASE)/Makefile.base diff --git a/cpu/arm7tdmi_gba/Makefile.default b/cpu/arm7tdmi_gba/Makefile.default new file mode 100644 index 0000000000..aaebee71e9 --- /dev/null +++ b/cpu/arm7tdmi_gba/Makefile.default @@ -0,0 +1 @@ +DISABLE_MODULE += periph_init_leds diff --git a/cpu/arm7tdmi_gba/Makefile.dep b/cpu/arm7tdmi_gba/Makefile.dep new file mode 100644 index 0000000000..51481f9a83 --- /dev/null +++ b/cpu/arm7tdmi_gba/Makefile.dep @@ -0,0 +1,7 @@ +USEMODULE += arm7_common + +ifeq (,$(filter stdio_%,$(USEMODULE))) + USEMODULE += stdio_fb +endif + +include $(RIOTCPU)/arm7_common/Makefile.dep diff --git a/cpu/arm7tdmi_gba/Makefile.features b/cpu/arm7tdmi_gba/Makefile.features new file mode 100644 index 0000000000..08741a5846 --- /dev/null +++ b/cpu/arm7tdmi_gba/Makefile.features @@ -0,0 +1,10 @@ +CPU_ARCH = armv4t +CPU_CORE = arm7tdmi_s + +FEATURES_PROVIDED += arch_32bit +FEATURES_PROVIDED += arch_arm +FEATURES_PROVIDED += arch_arm7 +FEATURES_PROVIDED += cpp +FEATURES_PROVIDED += libstdcpp +FEATURES_PROVIDED += newlib +FEATURES_PROVIDED += picolibc diff --git a/cpu/arm7tdmi_gba/Makefile.include b/cpu/arm7tdmi_gba/Makefile.include new file mode 100644 index 0000000000..bcbaccbdc9 --- /dev/null +++ b/cpu/arm7tdmi_gba/Makefile.include @@ -0,0 +1,3 @@ +MCPU := arm7tdmi + +include $(RIOTCPU)/arm7_common/Makefile.include diff --git a/cpu/arm7tdmi_gba/cartridge_header.s b/cpu/arm7tdmi_gba/cartridge_header.s new file mode 100644 index 0000000000..f3aea69251 --- /dev/null +++ b/cpu/arm7tdmi_gba/cartridge_header.s @@ -0,0 +1,54 @@ +.section .gbaheader + b _startup + // Nintendo Logo data + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + .byte 0x00, 0x00, 0x00, 0x00 + + // ASCII Game title + .ascii "\0\0\0\0\0\0\0\0\0\0\0\0" + + // ASCII Game code + .ascii "\0\0\0\0" + + // ASCII Manufacturer id + .ascii "\0\0" + + // Fixed value + .byte 0x96 + + // Target device (0 = GBA) + .byte 0x00 + + // Reserved + .word 0x00000000 + .word 0x00000000 + + // Version + .byte 0x00 + + // Checksum + .byte 0x51 + + // Reserved + .hword 0x0000 + + // Multiboot header + .zero 36 diff --git a/cpu/arm7tdmi_gba/cpu.c b/cpu/arm7tdmi_gba/cpu.c new file mode 100644 index 0000000000..98aa3b0b85 --- /dev/null +++ b/cpu/arm7tdmi_gba/cpu.c @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2023 HAW Hamburg. All rights reserved. + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup cpu_arm7tdmi_gba + * @{ + */ + +#include +#include "cpu.h" +#include "kernel_init.h" + +/** + * @brief Initialize the CPU, set IRQ priorities, clocks + */ +void cpu_init(void) +{ + extern void board_init(void); + + /* board specific setup of i/o pins */ + board_init(); + + /* initialize stdio prior to periph_init() to allow use of DEBUG() there */ + early_init(); +} diff --git a/cpu/arm7tdmi_gba/doc.txt b/cpu/arm7tdmi_gba/doc.txt new file mode 100644 index 0000000000..359d943c28 --- /dev/null +++ b/cpu/arm7tdmi_gba/doc.txt @@ -0,0 +1,5 @@ +/** + * @defgroup cpu_arm7tdmi_gba GBAs ARM7TDMI + * @ingroup cpu + * @brief Nintendos ARM7TDMI on the GBA + */ diff --git a/cpu/arm7tdmi_gba/include/cpu.h b/cpu/arm7tdmi_gba/include/cpu.h new file mode 100644 index 0000000000..b57b95cdca --- /dev/null +++ b/cpu/arm7tdmi_gba/include/cpu.h @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2023 HAW Hamburg. All rights reserved. + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#ifndef CPU_H +#define CPU_H + +/** + * @ingroup cpu_arm7tdmi_gba + * @{ + */ +#include "arm_cpu.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +extern uintptr_t __stack_start; /**< end of user stack memory space */ + +#ifdef __cplusplus +} +#endif + +/** @} */ +#endif /* CPU_H */ diff --git a/cpu/arm7tdmi_gba/include/cpu_conf.h b/cpu/arm7tdmi_gba/include/cpu_conf.h new file mode 100644 index 0000000000..f52c1ddb16 --- /dev/null +++ b/cpu/arm7tdmi_gba/include/cpu_conf.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2023 HAW Hamburg. All rights reserved. + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +#ifndef CPU_CONF_H +#define CPU_CONF_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @ingroup cpu_arm7tdmi_gba + * + * @{ + */ + +/** + * @file + * @brief ARM7TDMI_GBA CPU configuration + * + * @author + */ + +/** + * @brief This arch uses the inlined irq API. + */ +#define IRQ_API_INLINED (1) + +/** + * @name Kernel configuration + * @{ + */ +#define THREAD_EXTRA_STACKSIZE_PRINTF (512) + +#ifndef THREAD_STACKSIZE_DEFAULT +#define THREAD_STACKSIZE_DEFAULT (1024) +#endif + +#ifndef THREAD_STACKSIZE_IDLE +#define THREAD_STACKSIZE_IDLE (160) +#endif +/** @} */ + +/** + * @brief Stack size used for the undefined instruction interrupt stack + */ +#define UND_STACKSIZE (64) + +/** + * @brief Stack size used for the abort interrupt stack + */ +#define ABT_STACKSIZE (64) + +/** + * @brief Stack size used for the interrupt (ISR) stack + */ +#ifndef ISR_STACKSIZE +#define ISR_STACKSIZE (400) +#endif + +/** + * @brief Stack size used for the fast interrupt (FIQ) stack + */ +#define FIQ_STACKSIZE (64) + +/** + * @brief Stack size used for the supervisor mode (SVC) stack + */ +#define SVC_STACKSIZE (400) + +/** + * @brief Stack size used for the user mode/kernel init stack + */ +#define USR_STACKSIZE (4096) + +/** + * @brief The CPU has 2 blocks of SRAM at different addresses. + * (primary on-chip RAM and external working EWRAM) + */ +#define NUM_HEAPS (2) + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* CPU_CONF_H */ diff --git a/cpu/arm7tdmi_gba/include/periph_cpu.h b/cpu/arm7tdmi_gba/include/periph_cpu.h new file mode 100644 index 0000000000..9e93b4049d --- /dev/null +++ b/cpu/arm7tdmi_gba/include/periph_cpu.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2023 HAW Hamburg. All rights reserved. + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup cpu_arm7tdmi_gba + * @{ + * + * @file + * @brief CPU specific definitions for internal peripheral handling + * + * @author + */ + +#ifndef PERIPH_CPU_H +#define PERIPH_CPU_H +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @brief Clock configuration + */ +#define CLOCK_CORECLOCK (16780000U) /* 16.78MHz */ + +#ifdef __cplusplus +} +#endif + +#endif /* PERIPH_CPU_H */ +/** @} */ diff --git a/cpu/arm7tdmi_gba/include/periph_gba.h b/cpu/arm7tdmi_gba/include/periph_gba.h new file mode 100644 index 0000000000..429b7701b3 --- /dev/null +++ b/cpu/arm7tdmi_gba/include/periph_gba.h @@ -0,0 +1,106 @@ +/* + * Copyright (C) 2023 HAW Hamburg. All rights reserved. + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup cpu_arm7tdmi_gba + * @{ + * + * @file + * @brief GBA specific definitions for internal peripheral handling + * + * @author Bennet Blischke + */ + +#ifndef PERIPH_GBA_H +#define PERIPH_GBA_H + +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + +/** + * @brief Type for 32-bit registers + */ +#define REG32(ADDR) (*(uint32_t volatile (*))(ADDR)) + +/** + * @brief Type for 16-bit registers + */ +#define REG16(ADDR) (*(uint16_t volatile (*))(ADDR)) + +/** + * @brief Type for 16-bit memory addresses + */ +#define MEM16(ADDR) ((uint16_t(*))(ADDR)) + +/** + * @brief Screen dimension in pixel + * @{ + */ +#define GBA_SCREEN_WIDTH (240) /**< width */ +#define GBA_SCREEN_HEIGHT (160) /**< height */ +/** @} */ + +/** + * @brief Display Control register + */ +#define GBA_DISPCNT REG16(0x4000000) + +/** + * @name Settings for GBA_DISPCNT + * @{ + */ +#define GBA_DISPCNT_BGMODE_0 0x0000 /**< Tiled, four layers, up to 1024 tiles */ +#define GBA_DISPCNT_BGMODE_1 0x0001 /**< Tiled, three layers, up to 1024 tiles */ +#define GBA_DISPCNT_BGMODE_2 0x0002 /**< Tiled, two layers, up to 1024 tiles */ +#define GBA_DISPCNT_BGMODE_3 0x0003 /**< Bitmap, 240x160, 15-bit RGB */ +#define GBA_DISPCNT_BGMODE_4 0x0004 /**< Bitmap, 240x160, 8-bit RGB */ +#define GBA_DISPCNT_BGMODE_5 0x0005 /**< Bitmap, 160x128, 15-bit RGB */ + +#define GBA_DISPCNT_SDBG_0 0x0100 /**< Enable display of background 0 */ +#define GBA_DISPCNT_SDBG_1 0x0200 /**< Enable display of background 1 */ +#define GBA_DISPCNT_SDBG_2 0x0400 /**< Enable display of background 2 */ +#define GBA_DISPCNT_SDBG_3 0x0800 /**< Enable display of background 3 */ + +#define GBA_DISPCNT_SDOBJ 0x1000 /**< Enable display of objects */ +/** @} */ + +/** + * @brief General LCD Status register + */ +#define GBA_DISPSTAT REG16(0x4000004) + +/** + * @name LCD background control registers + * @{ + */ +#define GBA_BG0CNT REG16(0x4000008) /**< BG0 */ +#define GBA_BG1CNT REG16(0x400000a) /**< BG1 */ +#define GBA_BG2CNT REG16(0x400000c) /**< BG2 */ +#define GBA_BG3CNT REG16(0x400000e) /**< BG3 */ +/** @} */ + +/** + * @brief VRAM color palette memory + */ +#define GBA_VRAM_PALETTE MEM16(0x5000000) + +/** + * @brief VRAM, 96Kb, 0x6017FFF - size depends on display mode! + */ +#define GBA_VRAM MEM16(0x6000000) + +#ifdef __cplusplus +} +#endif + +#endif /* PERIPH_GBA_H */ +/** @} */ diff --git a/cpu/arm7tdmi_gba/ldscripts/arm7tdmi_gba.ld b/cpu/arm7tdmi_gba/ldscripts/arm7tdmi_gba.ld new file mode 100644 index 0000000000..98c91d1fff --- /dev/null +++ b/cpu/arm7tdmi_gba/ldscripts/arm7tdmi_gba.ld @@ -0,0 +1,213 @@ +/* + * Copyright 2013, Freie Universitaet Berlin (FUB). All rights reserved. + * 2024, HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +MEMORY { + ewram : ORIGIN = 0x2000000, LENGTH = 256K /* on board ram, slower */ + ram (w!rx) : ORIGIN = 0x3000000, LENGTH = 32K /* on chip ram, faster */ + rom (rx) : ORIGIN = 0x8000000, LENGTH = 32M /* on cartridge */ +} + + +SECTIONS +{ + .text : + { + KEEP(*(.gbaheader)) + . = ALIGN(4); + KEEP(*(.init)) + . = ALIGN(4); + KEEP(*(.init0)) /* Start here after reset. */ + . = ALIGN(4); + *(.text .text.* .gnu.linkonce.t.*) + *(.glue_7t) *(.glue_7) + . = ALIGN(4); + *(.rodata .rodata* .gnu.linkonce.r.*) + *(.ARM.extab* .gnu.linkonce.armextab.*) + + /* Support C constructors, and C destructors in both user code + and the C library. This also provides support for C++ code. */ + . = ALIGN(4); + KEEP(*(.init)) + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(0x4); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + KEEP (*(SORT(.roxfa.*))) + + . = ALIGN(4); + _efixed = .; /* End of text section */ + } > rom + + /* + * TLS relocations are offsets relative to the address + * of the first TLS symbol. That means we just need to + * allocate them all together so that the TLS region + * is compact when allocated for each thread. + */ + + /* + * TLS initialization data is loaded into ROM so that + * each thread can get its values initialized from there + * at startup + */ + .tdata : + { + __tdata_start = .; + *(.tdata .tdata.* .gnu.linkonce.td.*) + __tdata_end = .; + } > rom + __tdata_source = LOADADDR(.tdata); + __tdata_size = SIZEOF(.tdata); + + /* + * TLS zeroed data is relocated as if it immediately followed + * the tdata values. However, the linker 'magically' erases the + * memory allocation so that no ROM is consumed by this + * section + */ + .tbss : + { + *(.tbss .tbss.* .gnu.linkonce.tb.*) + *(.tcommon) + __tbss_end = .; + } > rom + __tls_size = __tbss_end - __tdata_start; + __tbss_size = __tls_size - __tdata_size; + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + PROVIDE_HIDDEN (__exidx_start = .); + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > rom + PROVIDE_HIDDEN (__exidx_end = .); + + /* exception handling */ + . = ALIGN(4); + .eh_frame : + { + KEEP (*(.eh_frame)) + } > rom + + . = ALIGN(4); + _etext = .; + +/************************************************************************** + * RAM + **************************************************************************/ + + /* + * Stacks + */ + .stack (NOLOAD) : + { + PROVIDE(__stack_start = .); + KEEP (*(.usr_stack)) + __stack_usr_start = .; + KEEP (*(.und_stack)) + __stack_und_start = .; + KEEP (*(.fiq_stack)) + __stack_fiq_start = .; + KEEP (*(.irq_stack)) + __stack_irq_start = .; + KEEP (*(.abt_stack)) + __stack_abt_start = .; + KEEP (*(.svc_stack)) + __stack_svc_start = .; + + PROVIDE(__stack_end = .); + } > ram + + .relocate : + { + . = ALIGN(4); + _srelocate = .; + *(.ramfunc .ramfunc.*); + *(.data .data.*); + KEEP (*(.openocd .openocd.*)) + KEEP (*(SORT(.xfa.*))) + . = ALIGN(4); + _erelocate = .; + } > ram AT> rom + + /* .bss section which is used for uninitialized data */ + .bss (NOLOAD) : + { + . = ALIGN(4); + _sbss = . ; + _szero = .; + *(.bss .bss.*) + *(COMMON) + . = ALIGN(4); + _ebss = . ; + _ezero = .; + } > ram + + /* + * collect all uninitialized sections that go into RAM + */ + .noinit (NOLOAD) : + { + __noinit_start = .; + PROVIDE(__fiq_handler = .); + *(.fiq) + *(.noinit) + . = ALIGN(4); + __noinit_end = .; + } > ram + + /* heap section */ + . = ALIGN(4); + _sheap = . ; + _eheap = ORIGIN(ram) + LENGTH(ram); + + .heap1 ALIGN(4) (NOLOAD) : + { + _sheap1 = ORIGIN(ewram); + _eheap1 = ORIGIN(ewram) + LENGTH(ewram); + } > ewram + + /* Populate information about ram size */ + _sram = ORIGIN(ram); + _eram = ORIGIN(ram) + LENGTH(ram); + + /* Populate information about rom size */ + _srom = ORIGIN(rom); + _erom = ORIGIN(rom) + LENGTH(rom); + + .end_fw (NOLOAD) : ALIGN(4) { + _end_fw = . ; + } > rom +} diff --git a/cpu/arm7tdmi_gba/startup.s b/cpu/arm7tdmi_gba/startup.s new file mode 100644 index 0000000000..a1aca76fa2 --- /dev/null +++ b/cpu/arm7tdmi_gba/startup.s @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2023 HAW Hamburg + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/* *************************************************************************************************************** + + startup.s STARTUP ASSEMBLY CODE + ----------------------- + + + Module includes the interrupt vectors and start-up code. + + *************************************************************************************************************** */ +.extern __start_start +.extern __stack_end +.extern __fiq_handler + +/* Stack Positions */ +.extern __stack_usr_start +.extern __stack_abt_start +.extern __stack_und_start +.extern __stack_fiq_start +.extern __start_irq_start +.extern __start_svc_start + +/* Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs (program status registers) */ +.set MODE_USR, 0x10 /* Normal User Mode */ +.set MODE_FIQ, 0x11 /* FIQ Processing Fast Interrupts Mode */ +.set MODE_IRQ, 0x12 /* IRQ Processing Standard Interrupts Mode */ +.set MODE_SVC, 0x13 /* Supervisor Processing Software Interrupts Mode */ +.set MODE_ABT, 0x17 /* Abort Processing memory Faults Mode */ +.set MODE_UND, 0x1B /* Undefined Processing Undefined Instructions Mode */ +.set MODE_SYS, 0x1F /* System Running Priviledged Operating System Tasks Mode */ + +.set I_BIT, 0x80 /* when I bit is set, IRQ is disabled (program status registers) */ +.set F_BIT, 0x40 /* when F bit is set, FIQ is disabled (program status registers) */ + +.set REG_IME, 0x4000208 + +.text +.arm + + +/* Begin of boot code */ +.text +.arm +.section .init +.global _startup +.func _startup + +_startup: + ldr pc, =reset_handler + +/*.func reset_handler */ +reset_handler: + +.section .init0 + /* Disable interrupts using the GBA control reg */ + ldr r0, =REG_IME + mov r1, #0 + strh r1, [r0] + + /* Setup a stack for each mode - note that this only sets up a usable stack + for User mode. Also each mode is setup with interrupts initially disabled. */ + ldr r0, = __stack_end + msr CPSR_c, #MODE_UND|I_BIT|F_BIT /* Undefined Instruction Mode */ + ldr sp, =__stack_und_start + msr CPSR_c, #MODE_ABT|I_BIT|F_BIT /* Abort Mode */ + ldr sp, =__stack_abt_start + msr CPSR_c, #MODE_FIQ|I_BIT|F_BIT /* FIQ Mode */ + ldr sp, =__stack_fiq_start + msr CPSR_c, #MODE_IRQ|I_BIT|F_BIT /* IRQ Mode */ + ldr sp, =__stack_irq_start + msr CPSR_c, #MODE_SVC|I_BIT|F_BIT /* Supervisor Mode */ + ldr sp, =__stack_svc_start + msr CPSR_c, #MODE_SYS|I_BIT|F_BIT /* User Mode */ + ldr sp, =__stack_usr_start + + bl bootloader + b kernel_init + + /* Infinite Loop */ +.section .fini0 +__main_exit: B __main_exit + + +.endfunc +.end diff --git a/cpu/arm7tdmi_gba/stdio_fb/Makefile b/cpu/arm7tdmi_gba/stdio_fb/Makefile new file mode 100644 index 0000000000..48422e909a --- /dev/null +++ b/cpu/arm7tdmi_gba/stdio_fb/Makefile @@ -0,0 +1 @@ +include $(RIOTBASE)/Makefile.base diff --git a/cpu/arm7tdmi_gba/stdio_fb/font_terminal.h b/cpu/arm7tdmi_gba/stdio_fb/font_terminal.h new file mode 100644 index 0000000000..0ae779239a --- /dev/null +++ b/cpu/arm7tdmi_gba/stdio_fb/font_terminal.h @@ -0,0 +1,286 @@ +#ifndef FONT_TERMINAL_H +#define FONT_TERMINAL_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define FONT_WIDTH 8 +#define FONT_HEIGHT 8 +#define FONT_VMIRROR 1 +/* + https://github.com/dhepper/font8x8 + ; Summary: font8_8.asm + ; 8x8 monochrome bitmap fonts for rendering + ; + ; Author: + ; Marcel Sondaar + ; International Business Machines (public domain VGA fonts) + ; + ; License: + ; Public Domain + ; + */ +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0000 (nul) +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0001 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0002 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0003 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0004 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0005 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0006 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0007 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0008 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0009 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+000A +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+000B +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+000C +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+000D +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+000E +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+000F +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0010 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0011 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0012 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0013 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0014 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0015 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0016 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0017 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0018 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0019 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+001A +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+001B +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+001C +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+001D +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+001E +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+001F +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0020 (space) +0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00, // U+0021 (!) +0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0022 (") +0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00, // U+0023 (#) +0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00, // U+0024 ($) +0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00, // U+0025 (%) +0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00, // U+0026 (&) +0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0027 (') +0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00, // U+0028 (() +0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00, // U+0029 ()) +0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00, // U+002A (*) +0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00, // U+002B (+) +0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06, // U+002C (,) +0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00, // U+002D (-) +0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00, // U+002E (.) +0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00, // U+002F (/) +0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00, // U+0030 (0) +0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00, // U+0031 (1) +0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00, // U+0032 (2) +0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00, // U+0033 (3) +0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00, // U+0034 (4) +0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00, // U+0035 (5) +0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00, // U+0036 (6) +0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00, // U+0037 (7) +0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00, // U+0038 (8) +0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00, // U+0039 (9) +0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00, // U+003A (:) +0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06, // U+003B (//) +0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00, // U+003C (<) +0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00, // U+003D (=) +0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00, // U+003E (>) +0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00, // U+003F (?) +0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00, // U+0040 (@) +0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00, // U+0041 (A) +0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00, // U+0042 (B) +0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00, // U+0043 (C) +0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00, // U+0044 (D) +0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00, // U+0045 (E) +0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00, // U+0046 (F) +0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00, // U+0047 (G) +0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00, // U+0048 (H) +0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00, // U+0049 (I) +0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00, // U+004A (J) +0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00, // U+004B (K) +0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00, // U+004C (L) +0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00, // U+004D (M) +0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00, // U+004E (N) +0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00, // U+004F (O) +0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00, // U+0050 (P) +0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00, // U+0051 (Q) +0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00, // U+0052 (R) +0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00, // U+0053 (S) +0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00, // U+0054 (T) +0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00, // U+0055 (U) +0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00, // U+0056 (V) +0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00, // U+0057 (W) +0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00, // U+0058 (X) +0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00, // U+0059 (Y) +0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00, // U+005A (Z) +0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00, // U+005B ([) +0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00, // U+005C (\) +0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00, // U+005D (]) +0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00, // U+005E (^) +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, // U+005F (_) +0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0060 (`) +0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00, // U+0061 (a) +0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00, // U+0062 (b) +0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00, // U+0063 (c) +0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00, // U+0064 (d) +0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00, // U+0065 (e) +0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00, // U+0066 (f) +0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F, // U+0067 (g) +0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00, // U+0068 (h) +0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00, // U+0069 (i) +0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, // U+006A (j) +0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00, // U+006B (k) +0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00, // U+006C (l) +0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00, // U+006D (m) +0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00, // U+006E (n) +0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00, // U+006F (o) +0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F, // U+0070 (p) +0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78, // U+0071 (q) +0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00, // U+0072 (r) +0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00, // U+0073 (s) +0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00, // U+0074 (t) +0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00, // U+0075 (u) +0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00, // U+0076 (v) +0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00, // U+0077 (w) +0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00, // U+0078 (x) +0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F, // U+0079 (y) +0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00, // U+007A (z) +0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00, // U+007B ({) +0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, // U+007C (|) +0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00, // U+007D (}) +0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+007E (~) +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+007F +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0080 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0081 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0082 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0083 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0084 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0085 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0086 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0087 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0088 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0089 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+008A +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+008B +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+008C +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+008D +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+008E +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+008F +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0090 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0091 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0092 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0093 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0094 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0095 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0096 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0097 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0098 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+0099 +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+009A +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+009B +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+009C +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+009D +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+009E +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+009F +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+00A0 (no break space) +0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, // U+00A1 (inverted !) +0x18, 0x18, 0x7E, 0x03, 0x03, 0x7E, 0x18, 0x18, // U+00A2 (dollarcents) +0x1C, 0x36, 0x26, 0x0F, 0x06, 0x67, 0x3F, 0x00, // U+00A3 (pound sterling) +0x00, 0x00, 0x63, 0x3E, 0x36, 0x3E, 0x63, 0x00, // U+00A4 (currency mark) +0x33, 0x33, 0x1E, 0x3F, 0x0C, 0x3F, 0x0C, 0x0C, // U+00A5 (yen) +0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, // U+00A6 (broken pipe) +0x7C, 0xC6, 0x1C, 0x36, 0x36, 0x1C, 0x33, 0x1E, // U+00A7 (paragraph) +0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+00A8 (diaeresis) +0x3C, 0x42, 0x99, 0x85, 0x85, 0x99, 0x42, 0x3C, // U+00A9 (copyright symbol) +0x3C, 0x36, 0x36, 0x7C, 0x00, 0x00, 0x00, 0x00, // U+00AA (superscript a) +0x00, 0xCC, 0x66, 0x33, 0x66, 0xCC, 0x00, 0x00, // U+00AB (<<) +0x00, 0x00, 0x00, 0x3F, 0x30, 0x30, 0x00, 0x00, // U+00AC (gun pointing left) +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+00AD (soft hyphen) +0x3C, 0x42, 0x9D, 0xA5, 0x9D, 0xA5, 0x42, 0x3C, // U+00AE (registered symbol) +0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+00AF (macron) +0x1C, 0x36, 0x36, 0x1C, 0x00, 0x00, 0x00, 0x00, // U+00B0 (degree) +0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x7E, 0x00, // U+00B1 (plusminus) +0x1C, 0x30, 0x18, 0x0C, 0x3C, 0x00, 0x00, 0x00, // U+00B2 (superscript 2) +0x1C, 0x30, 0x18, 0x30, 0x1C, 0x00, 0x00, 0x00, // U+00B2 (superscript 3) +0x18, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // U+00B2 (aigu) +0x00, 0x00, 0x66, 0x66, 0x66, 0x3E, 0x06, 0x03, // U+00B5 (mu) +0xFE, 0xDB, 0xDB, 0xDE, 0xD8, 0xD8, 0xD8, 0x00, // U+00B6 (pilcrow) +0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, // U+00B7 (central dot) +0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x1E, // U+00B8 (cedille) +0x08, 0x0C, 0x08, 0x1C, 0x00, 0x00, 0x00, 0x00, // U+00B9 (superscript 1) +0x1C, 0x36, 0x36, 0x1C, 0x00, 0x00, 0x00, 0x00, // U+00BA (superscript 0) +0x00, 0x33, 0x66, 0xCC, 0x66, 0x33, 0x00, 0x00, // U+00BB (>>) +0xC3, 0x63, 0x33, 0xBD, 0xEC, 0xF6, 0xF3, 0x03, // U+00BC (1/4) +0xC3, 0x63, 0x33, 0x7B, 0xCC, 0x66, 0x33, 0xF0, // U+00BD (1/2) +0x03, 0xC4, 0x63, 0xB4, 0xDB, 0xAC, 0xE6, 0x80, // U+00BE (3/4) +0x0C, 0x00, 0x0C, 0x06, 0x03, 0x33, 0x1E, 0x00, // U+00BF (inverted ?) +0x07, 0x00, 0x1C, 0x36, 0x63, 0x7F, 0x63, 0x00, // U+00C0 (A grave) +0x70, 0x00, 0x1C, 0x36, 0x63, 0x7F, 0x63, 0x00, // U+00C1 (A aigu) +0x1C, 0x36, 0x00, 0x3E, 0x63, 0x7F, 0x63, 0x00, // U+00C2 (A circumflex) +0x6E, 0x3B, 0x00, 0x3E, 0x63, 0x7F, 0x63, 0x00, // U+00C3 (A ~) +0x63, 0x1C, 0x36, 0x63, 0x7F, 0x63, 0x63, 0x00, // U+00C4 (A umlaut) +0x0C, 0x0C, 0x00, 0x1E, 0x33, 0x3F, 0x33, 0x00, // U+00C5 (A ring) +0x7C, 0x36, 0x33, 0x7F, 0x33, 0x33, 0x73, 0x00, // U+00C6 (AE) +0x1E, 0x33, 0x03, 0x33, 0x1E, 0x18, 0x30, 0x1E, // U+00C7 (C cedille) +0x07, 0x00, 0x3F, 0x06, 0x1E, 0x06, 0x3F, 0x00, // U+00C8 (E grave) +0x38, 0x00, 0x3F, 0x06, 0x1E, 0x06, 0x3F, 0x00, // U+00C9 (E aigu) +0x0C, 0x12, 0x3F, 0x06, 0x1E, 0x06, 0x3F, 0x00, // U+00CA (E circumflex) +0x36, 0x00, 0x3F, 0x06, 0x1E, 0x06, 0x3F, 0x00, // U+00CB (E umlaut) +0x07, 0x00, 0x1E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00, // U+00CC (I grave) +0x38, 0x00, 0x1E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00, // U+00CD (I aigu) +0x0C, 0x12, 0x00, 0x1E, 0x0C, 0x0C, 0x1E, 0x00, // U+00CE (I circumflex) +0x33, 0x00, 0x1E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00, // U+00CF (I umlaut) +0x3F, 0x66, 0x6F, 0x6F, 0x66, 0x66, 0x3F, 0x00, // U+00D0 (Eth) +0x3F, 0x00, 0x33, 0x37, 0x3F, 0x3B, 0x33, 0x00, // U+00D1 (N ~) +0x0E, 0x00, 0x18, 0x3C, 0x66, 0x3C, 0x18, 0x00, // U+00D2 (O grave) +0x70, 0x00, 0x18, 0x3C, 0x66, 0x3C, 0x18, 0x00, // U+00D3 (O aigu) +0x3C, 0x66, 0x18, 0x3C, 0x66, 0x3C, 0x18, 0x00, // U+00D4 (O circumflex) +0x6E, 0x3B, 0x00, 0x3E, 0x63, 0x63, 0x3E, 0x00, // U+00D5 (O ~) +0xC3, 0x18, 0x3C, 0x66, 0x66, 0x3C, 0x18, 0x00, // U+00D6 (O umlaut) +0x00, 0x36, 0x1C, 0x08, 0x1C, 0x36, 0x00, 0x00, // U+00D7 (multiplicative x) +0x5C, 0x36, 0x73, 0x7B, 0x6F, 0x36, 0x1D, 0x00, // U+00D8 (O stroke) +0x0E, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00, // U+00D9 (U grave) +0x70, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00, // U+00DA (U aigu) +0x3C, 0x66, 0x00, 0x66, 0x66, 0x66, 0x3C, 0x00, // U+00DB (U circumflex) +0x33, 0x00, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x00, // U+00DC (U umlaut) +0x70, 0x00, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x00, // U+00DD (Y aigu) +0x0F, 0x06, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x0F, // U+00DE (Thorn) +0x00, 0x1E, 0x33, 0x1F, 0x33, 0x1F, 0x03, 0x03, // U+00DF (beta) +0x07, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x7E, 0x00, // U+00E0 (a grave) +0x38, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x7E, 0x00, // U+00E1 (a aigu) +0x7E, 0xC3, 0x3C, 0x60, 0x7C, 0x66, 0xFC, 0x00, // U+00E2 (a circumflex) +0x6E, 0x3B, 0x1E, 0x30, 0x3E, 0x33, 0x7E, 0x00, // U+00E3 (a ~) +0x33, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x7E, 0x00, // U+00E4 (a umlaut) +0x0C, 0x0C, 0x1E, 0x30, 0x3E, 0x33, 0x7E, 0x00, // U+00E5 (a ring) +0x00, 0x00, 0xFE, 0x30, 0xFE, 0x33, 0xFE, 0x00, // U+00E6 (ae) +0x00, 0x00, 0x1E, 0x03, 0x03, 0x1E, 0x30, 0x1C, // U+00E7 (c cedille) +0x07, 0x00, 0x1E, 0x33, 0x3F, 0x03, 0x1E, 0x00, // U+00E8 (e grave) +0x38, 0x00, 0x1E, 0x33, 0x3F, 0x03, 0x1E, 0x00, // U+00E9 (e aigu) +0x7E, 0xC3, 0x3C, 0x66, 0x7E, 0x06, 0x3C, 0x00, // U+00EA (e circumflex) +0x33, 0x00, 0x1E, 0x33, 0x3F, 0x03, 0x1E, 0x00, // U+00EB (e umlaut) +0x07, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00, // U+00EC (i grave) +0x1C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00, // U+00ED (i augu) +0x3E, 0x63, 0x1C, 0x18, 0x18, 0x18, 0x3C, 0x00, // U+00EE (i circumflex) +0x33, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00, // U+00EF (i umlaut) +0x1B, 0x0E, 0x1B, 0x30, 0x3E, 0x33, 0x1E, 0x00, // U+00F0 (eth) +0x00, 0x1F, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x00, // U+00F1 (n ~) +0x00, 0x07, 0x00, 0x1E, 0x33, 0x33, 0x1E, 0x00, // U+00F2 (o grave) +0x00, 0x38, 0x00, 0x1E, 0x33, 0x33, 0x1E, 0x00, // U+00F3 (o aigu) +0x1E, 0x33, 0x00, 0x1E, 0x33, 0x33, 0x1E, 0x00, // U+00F4 (o circumflex) +0x6E, 0x3B, 0x00, 0x1E, 0x33, 0x33, 0x1E, 0x00, // U+00F5 (o ~) +0x00, 0x33, 0x00, 0x1E, 0x33, 0x33, 0x1E, 0x00, // U+00F6 (o umlaut) +0x18, 0x18, 0x00, 0x7E, 0x00, 0x18, 0x18, 0x00, // U+00F7 (division) +0x00, 0x60, 0x3C, 0x76, 0x7E, 0x6E, 0x3C, 0x06, // U+00F8 (o stroke) +0x00, 0x07, 0x00, 0x33, 0x33, 0x33, 0x7E, 0x00, // U+00F9 (u grave) +0x00, 0x38, 0x00, 0x33, 0x33, 0x33, 0x7E, 0x00, // U+00FA (u aigu) +0x1E, 0x33, 0x00, 0x33, 0x33, 0x33, 0x7E, 0x00, // U+00FB (u circumflex) +0x00, 0x33, 0x00, 0x33, 0x33, 0x33, 0x7E, 0x00, // U+00FC (u umlaut) +0x00, 0x38, 0x00, 0x33, 0x33, 0x3E, 0x30, 0x1F, // U+00FD (y aigu) +0x00, 0x00, 0x06, 0x3E, 0x66, 0x3E, 0x06, 0x00, // U+00FE (thorn) +0x00, 0x33, 0x00, 0x33, 0x33, 0x3E, 0x30, 0x1F, // U+00FF (y umlaut) + +#ifdef __cplusplus +} +#endif + +#endif /* FONT_TERMINAL_H */ diff --git a/cpu/arm7tdmi_gba/stdio_fb/stdio_fb.c b/cpu/arm7tdmi_gba/stdio_fb/stdio_fb.c new file mode 100644 index 0000000000..f4674fba16 --- /dev/null +++ b/cpu/arm7tdmi_gba/stdio_fb/stdio_fb.c @@ -0,0 +1,113 @@ +/* + * Copyright (C) 2023 Bennet Blischke + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup boards_gba_stdio_fb + * @{ + * + * @file + * @brief STDIO framebuffer driver + * + * This file provides a framebuffer driver for STDIO, implementing stdout only. + * + * @author Bennet Blischke + * + * @} + */ + +#include "stdio_base.h" +#include "periph_gba.h" + +#include + +static const unsigned char systemFont[] = +{ +#include "font_terminal.h" +}; + +#define BLACK 0x0000 +#define WHITE 0x7FFF + +static void clearScreen(void) +{ + /* width * height * two byte per pixel */ + memset(GBA_VRAM, 0x00, GBA_SCREEN_WIDTH * GBA_SCREEN_HEIGHT * 2); +} + +static void drawPixel(unsigned short x, unsigned short y, unsigned short color) +{ + GBA_VRAM[x + y * GBA_SCREEN_WIDTH] = color; +} + +static void drawChar(unsigned char c, int x, int y, unsigned short fgColour, + unsigned short bgColour) +{ + unsigned char mask; + const unsigned char *font = systemFont + (c * FONT_HEIGHT); + unsigned short colourToDraw; + + for (int h = 0; h < FONT_HEIGHT; h++) { + mask = 0x01; + + /* This loop draws 8 pixels at most / 1 byte per line */ + for (int w = 0; w < FONT_WIDTH; w++) { + if ((*font) & mask) { + colourToDraw = fgColour; + } + else { + colourToDraw = bgColour; + } + + drawPixel(x + w, y + h, colourToDraw); + + mask <<= 1; + } + font++; + } +} + +void stdio_init(void) +{ + /* setup bitmap mode */ + GBA_DISPCNT = GBA_DISPCNT_BGMODE_3 | GBA_DISPCNT_SDBG_2; + clearScreen(); +} + +ssize_t stdio_read(void *buffer, size_t count) +{ + (void)buffer; + (void)count; + return 0; +} + +ssize_t stdio_write(const void *buffer, size_t len) +{ + static unsigned short row = 0; + static unsigned short cursor = 0; + + for (size_t i = 0; i < len; i++) { + if (cursor >= (GBA_SCREEN_WIDTH / FONT_WIDTH)) { + cursor = 0; + row++; + } + if (row >= (GBA_SCREEN_HEIGHT / FONT_HEIGHT)) { + clearScreen(); + row = 0; + } + char c = ((char *)buffer)[i]; + if (c == '\n') { + row++; + cursor = 0; + continue; + } + + drawChar(c, cursor * FONT_WIDTH, row * FONT_HEIGHT, WHITE, BLACK); + cursor++; + } + return len; +} diff --git a/cpu/lpc23xx/include/cpu.h b/cpu/lpc23xx/include/cpu.h index 506b3ec7a6..2a765943eb 100644 --- a/cpu/lpc23xx/include/cpu.h +++ b/cpu/lpc23xx/include/cpu.h @@ -57,16 +57,6 @@ bool install_irq(int IntNumber, void (*HandlerAddr)(void), int Priority); void gpio_init_ports(void); #endif -/** - * @brief Returns the current content of the link register (lr) - */ -static inline uintptr_t cpu_get_caller_pc(void) -{ - register uintptr_t lr_ptr; - __asm__ __volatile__("mov %0, lr" : "=r"(lr_ptr)); - return lr_ptr; -} - /** * @brief Returns true if the CPU woke from Deep Sleep */ diff --git a/features.yaml b/features.yaml index a5ca873132..4ac9190fc1 100644 --- a/features.yaml +++ b/features.yaml @@ -276,6 +276,11 @@ groups: - name: cpu_qn908x help: The MCU is part of the NXP QN908x family + - title: Nintendo Grouping + features: + - name: cpu_arm7tdmi_gba + help: The MCU of the Game Boy Advance. + - title: Raspberry Pi Grouping features: - name: cpu_rpx0xx diff --git a/makefiles/features_existing.inc.mk b/makefiles/features_existing.inc.mk index 85c42d6850..66fdfb684f 100644 --- a/makefiles/features_existing.inc.mk +++ b/makefiles/features_existing.inc.mk @@ -48,6 +48,7 @@ FEATURES_EXISTING := \ cortexm_mpu \ cortexm_svc \ cpp \ + cpu_arm7tdmi_gba \ cpu_atmega1281 \ cpu_atmega1284p \ cpu_atmega128rfa1 \ diff --git a/makefiles/stdio.inc.mk b/makefiles/stdio.inc.mk index bfbb9feb70..16ce5902f6 100644 --- a/makefiles/stdio.inc.mk +++ b/makefiles/stdio.inc.mk @@ -12,6 +12,7 @@ STDIO_MODULES = \ stdio_telnet \ stdio_tinyusb_cdc_acm \ stdio_usb_serial_jtag \ + stdio_fb \ # STDIO_LEGACY_MODULES = \