Skip to content

Commit

Permalink
bricks/ev3: New arm none port.
Browse files Browse the repository at this point in the history
This boots all the way up to MicroPython and outputs stdout over UART on sensor port 1.
  • Loading branch information
laurensvalk committed Mar 22, 2024
1 parent 36acb6e commit 911cdab
Show file tree
Hide file tree
Showing 13 changed files with 367 additions and 0 deletions.
14 changes: 14 additions & 0 deletions bricks/_common/arm_none_eabi.mk
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,13 @@ else
ifeq ($(PB_MCU_FAMILY),AT91SAM7)
CFLAGS_MCU = -mthumb -mthumb-interwork -mtune=arm7tdmi -mcpu=arm7tdmi -msoft-float
else
ifeq ($(PB_MCU_FAMILY),TIAM1808)
CFLAGS_MCU =
else
$(error unsupported PB_MCU_FAMILY)
endif
endif
endif

CFLAGS_WARN = -Wall -Werror -Wextra -Wno-unused-parameter -Wno-maybe-uninitialized
CFLAGS = $(INC) -std=c99 -nostdlib -fshort-enums $(CFLAGS_MCU) $(CFLAGS_WARN) $(COPT) $(CFLAGS_EXTRA)
Expand All @@ -181,6 +185,8 @@ CFLAGS += -fsingle-precision-constant -Wdouble-promotion
# Tune for Debugging or Optimization
ifeq ($(DEBUG), 1)
CFLAGS += -Og -ggdb
else ifeq ($(DEBUG), 2)
CFLAGS += -Os -DNDEBUG -flto
else
CFLAGS += -Os -DNDEBUG -flto
CFLAGS += -fdata-sections -ffunction-sections
Expand Down Expand Up @@ -246,6 +252,14 @@ PY_EXTRA_SRC_C += $(addprefix bricks/nxt/,\
SRC_S += shared/runtime/gchelper_thumb1.s
endif

ifeq ($(PB_MCU_FAMILY),TIAM1808)
PY_EXTRA_SRC_C += $(addprefix bricks/ev3/,\
mphalport.c \
)

SRC_S += shared/runtime/gchelper_thumb1.s
endif

# STM32 Bluetooth stack

BLUENRG_SRC_C = $(addprefix lib/BlueNRG-MS/hci/,\
Expand Down
13 changes: 13 additions & 0 deletions bricks/ev3/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
PBIO_PLATFORM = ev3
PB_MCU_FAMILY = TIAM1808

# Disable some options. Can get rid of this once linker file and compile flags
# are properly set up.
DEBUG = 2

include ../_common/arm_none_eabi.mk

$(BUILD)/uImage: $(BUILD)/firmware-base.bin
mkimage -C none -A arm -T kernel -O linux -a 0xC0008000 -e 0xC0008000 -d $< $@

uImage: $(BUILD)/uImage
Empty file added bricks/ev3/ReadMe_OSS.txt
Empty file.
113 changes: 113 additions & 0 deletions bricks/ev3/mpconfigport.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2024 The Pybricks Authors


#define MICROPY_HW_BOARD_NAME "MINDSTORMS EV3 Brick"
#define MICROPY_HW_MCU_NAME "TI Sitara AM1808"

#define PYBRICKS_HUB_NAME "ev3"
#define PYBRICKS_HUB_CLASS_NAME (MP_QSTR_EV3Brick)
#define PYBRICKS_HUB_EV3BRICK (0)

// Pybricks modules
#define PYBRICKS_PY_COMMON (1)
#define PYBRICKS_PY_COMMON_BLE (0)
#define PYBRICKS_PY_COMMON_CHARGER (0)
#define PYBRICKS_PY_COMMON_CONTROL (0)
#define PYBRICKS_PY_COMMON_IMU (0)
#define PYBRICKS_PY_COMMON_KEYPAD (0)
#define PYBRICKS_PY_COMMON_KEYPAD_HUB_BUTTONS (0)
#define PYBRICKS_PY_COMMON_LIGHT_ARRAY (0)
#define PYBRICKS_PY_COMMON_LIGHT_MATRIX (0)
#define PYBRICKS_PY_COMMON_LOGGER (0)
#define PYBRICKS_PY_COMMON_MOTOR_MODEL (0)
#define PYBRICKS_PY_COMMON_MOTORS (0)
#define PYBRICKS_PY_COMMON_SYSTEM (0)
#define PYBRICKS_PY_EXPERIMENTAL (0)
#define PYBRICKS_PY_HUBS (0)
#define PYBRICKS_PY_IODEVICES (0)
#define PYBRICKS_PY_MEDIA (0)
#define PYBRICKS_PY_PARAMETERS (0)
#define PYBRICKS_PY_PARAMETERS_BUTTON (0)
#define PYBRICKS_PY_PARAMETERS_ICON (0)
#define PYBRICKS_PY_DEVICES (0)
#define PYBRICKS_PY_PUPDEVICES (0)
#define PYBRICKS_PY_ROBOTICS (0)
#define PYBRICKS_PY_ROBOTICS_EXTRA (0)
#define PYBRICKS_PY_ROBOTICS_DRIVEBASE_GYRO (0)
#define PYBRICKS_PY_ROBOTICS_DRIVEBASE_SPIKE (0)
#define PYBRICKS_PY_TOOLS (0)
#define PYBRICKS_PY_TOOLS_HUB_MENU (0)

// Pybricks options
#define PYBRICKS_OPT_COMPILER (1)
#define PYBRICKS_OPT_FLOAT (1)
#define PYBRICKS_OPT_TERSE_ERR (0)
#define PYBRICKS_OPT_EXTRA_MOD (1)
#define PYBRICKS_OPT_CUSTOM_IMPORT (1)
#define PYBRICKS_OPT_NATIVE_MOD (1)

// Start with config shared by all Pybricks ports.
#include "../_common/mpconfigport.h"

#define MICROPY_MPHALPORT_H "../_common/mphalport.h"

// type definitions for the specific machine

#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void *)((mp_uint_t)(p) | 1))

// This port is intended to be 32-bit, but unfortunately, int32_t for
// different targets may be defined in different ways - either as int
// or as long. This requires different printf formatting specifiers
// to print such value. So, we avoid int32_t and use int directly.
#define UINT_FMT "%u"
#define INT_FMT "%d"
typedef int mp_int_t; // must be pointer size
typedef unsigned mp_uint_t; // must be pointer size

typedef long mp_off_t;

// We have inlined IRQ functions for efficiency (they are generally
// 1 machine instruction).
//
// Note on IRQ state: you should not need to know the specific
// value of the state variable, but rather just pass the return
// value from disable_irq back to enable_irq. If you really need
// to know the machine-specific values, see irq.h.

static inline void enable_irq(mp_uint_t state) {
// __set_PRIMASK(state);
}

static inline mp_uint_t disable_irq(void) {
// mp_uint_t state = __get_PRIMASK();
// __disable_irq();
// return state;
return 0;
}

#define MICROPY_BEGIN_ATOMIC_SECTION() disable_irq()
#define MICROPY_END_ATOMIC_SECTION(state) enable_irq(state)

#define MICROPY_VM_HOOK_LOOP \
do { \
extern int pbio_do_one_event(void); \
pbio_do_one_event(); \
} while (0);

#define MICROPY_GC_HOOK_LOOP(i) do { \
if ((i & 0xf) == 0) { \
MICROPY_VM_HOOK_LOOP \
} \
} while (0)

#define MICROPY_EVENT_POLL_HOOK \
do { \
extern void pb_event_poll_hook(void); \
pb_event_poll_hook(); \
} while (0);

// We need to provide a declaration/definition of alloca()
#include <alloca.h>

#define MP_STATE_PORT MP_STATE_VM
67 changes: 67 additions & 0 deletions bricks/ev3/mphalport.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2018-2021 The Pybricks Authors
// Copyright (c) 2013, 2014 Damien P. George

#include <stdint.h>

#include <contiki.h>

#include <pbdrv/config.h>
#include <pbio/main.h>
#include <pbsys/bluetooth.h>

#include "py/runtime.h"
#include "py/mphal.h"
#include "py/mpconfig.h"
#include "py/stream.h"

void pb_stack_get_info(char **sstack, char **estack) {

volatile int stack_dummy;
// extern uint32_t _estack;
// extern uint32_t _sstack;
*sstack = (char *)&stack_dummy;
*estack = *sstack + 1024 * 64;
}

void pb_event_poll_hook_leave(void) {
}

void mp_hal_delay_ms(mp_uint_t Delay) {
}


uintptr_t mp_hal_stdio_poll(uintptr_t poll_flags) {
uintptr_t ret = 0;
return ret;
}

int mp_hal_stdin_rx_chr(void) {
uint8_t c = 0;
return c;
}

typedef struct {
volatile uint8_t *thr;
volatile uint8_t *lsr;
} pb_hal_uart_t;

// Sensor port 1
static pb_hal_uart_t UART0 = { .thr = (volatile uint8_t *)0x01D0C000, .lsr = (volatile uint8_t *)0x01D0C014 };

// Define the write_str function
static void write_str(pb_hal_uart_t *uart, const char *s) {
while (*s) {
while ((*uart->lsr & (1 << 5)) == 0) {
}
*uart->thr = *s++;
}
}

void mp_hal_stdout_tx_strn(const char *str, mp_uint_t len) {
write_str(&UART0, str);
MICROPY_EVENT_POLL_HOOK
}

void mp_hal_stdout_tx_flush(void) {
}
2 changes: 2 additions & 0 deletions bricks/ev3/pbsys_app_config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

#define PBSYS_APP_HUB_FEATURE_FLAGS (PBIO_PYBRICKS_FEATURE_USER_PROG_FORMAT_MULTI_MPY_V6)
21 changes: 21 additions & 0 deletions lib/pbio/platform/ev3/contiki-conf.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2018-2021 The Pybricks Authors

#ifndef _PBIO_CONF_H_
#define _PBIO_CONF_H_

#include <stdint.h>

#define CCIF
#define CLIF
#define AUTOSTART_ENABLE 1

typedef uint32_t clock_time_t;
#define CLOCK_CONF_SECOND 1000

#define clock_time pbdrv_clock_get_ms
#define clock_usecs pbdrv_clock_get_us

#define PROCESS_CONF_NO_PROCESS_NAMES 1

#endif /* _PBIO_CONF_H_ */
21 changes: 21 additions & 0 deletions lib/pbio/platform/ev3/pbdrvconfig.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2024 The Pybricks Authors

// platform-specific configuration for LEGO MINDSTORMS EV3

#define PBDRV_CONFIG_CLOCK (1)
#define PBDRV_CONFIG_CLOCK_NONE (1)

#define PBDRV_CONFIG_BLOCK_DEVICE (1)
#define PBDRV_CONFIG_BLOCK_DEVICE_TEST (1)
#define PBDRV_CONFIG_BLOCK_DEVICE_TEST_SIZE (8 * 1024)
#define PBDRV_CONFIG_BLOCK_DEVICE_TEST_SIZE_USER (512)

// FIXME: Can't build without a port
#define PBDRV_CONFIG_HAS_PORT_A (1)
#define PBDRV_CONFIG_HAS_PORT_B (1)
#define PBDRV_CONFIG_HAS_PORT_C (1)
#define PBDRV_CONFIG_HAS_PORT_D (1)

#define PBDRV_CONFIG_FIRST_MOTOR_PORT PBIO_PORT_ID_A
#define PBDRV_CONFIG_LAST_MOTOR_PORT PBIO_PORT_ID_D
4 changes: 4 additions & 0 deletions lib/pbio/platform/ev3/pbioconfig.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2019-2022 The Pybricks Authors

#define PBIO_CONFIG_ENABLE_SYS (1)
13 changes: 13 additions & 0 deletions lib/pbio/platform/ev3/pbsysconfig.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2020-2024 The Pybricks Authors

#define PBSYS_CONFIG_MAIN (1)
#define PBSYS_CONFIG_PROGRAM_LOAD (1)
#define PBSYS_CONFIG_PROGRAM_LOAD_RAM_SIZE (10 * 1024)
#define PBSYS_CONFIG_PROGRAM_LOAD_ROM_SIZE (PBDRV_CONFIG_BLOCK_DEVICE_TEST_SIZE)
#define PBSYS_CONFIG_PROGRAM_LOAD_OVERLAPS_BOOTLOADER_CHECKSUM (0)
#define PBSYS_CONFIG_PROGRAM_LOAD_USER_DATA_SIZE (512)
#define PBSYS_CONFIG_PROGRAM_LOAD_AUTO_START (1)
#define PBSYS_CONFIG_STATUS_LIGHT (0)
#define PBSYS_CONFIG_STATUS_LIGHT_BATTERY (0)
#define PBSYS_CONFIG_PROGRAM_STOP (0)
4 changes: 4 additions & 0 deletions lib/pbio/platform/ev3/platform.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2022 The Pybricks Authors

// This file is unused, but required for the common make file.
47 changes: 47 additions & 0 deletions lib/pbio/platform/ev3/platform.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/* The bootloader will look at this image and start execution at the symbol
designated as the entry point. */
ENTRY(_start)

/* Tell where the various sections of the object files will be put in the final
kernel image. */
SECTIONS
{
/* Begin putting sections at this number, taken from U-boot env */
. = 0xC0008000;
/* Begin putting sections at this number, for use with qemu */
/*. = 0x00010000;*/

/* First put the multiboot header, as it is required to be put very early
early in the image or the bootloader won't recognize the file format.
Next we'll put the .text section. */
.text BLOCK(4K) : ALIGN(4K)
{
KEEP(*(.text.boot))
*(.text)
}

/* Read-only data. */
.rodata BLOCK(4K) : ALIGN(4K)
{
*(.rodata)
}

/* Read-write data (initialized) */
.data BLOCK(4K) : ALIGN(4K)
{
*(.data)
}

/* Read-write data (uninitialized) and stack */
__bss_start = .;
.bss BLOCK(4K) : ALIGN(4K)
{
*(COMMON)
*(.bss)
. += 8K;
}
__bss_end = .;

/* The compiler may produce other sections, by default it will put them in
a segment with the same name. Simply add stuff here as needed. */
}
Loading

0 comments on commit 911cdab

Please sign in to comment.