Commit f14b92b9 authored by Dave Hylands's avatar Dave Hylands
Browse files

REPl working on UART6 with STMHAL

parent 19438fd3
...@@ -19,6 +19,7 @@ CROSS_COMPILE = arm-none-eabi- ...@@ -19,6 +19,7 @@ CROSS_COMPILE = arm-none-eabi-
INC = -I. INC = -I.
INC += -I$(PY_SRC) INC += -I$(PY_SRC)
INC += -I$(CMSIS_DIR)
INC += -I$(CMSIS_DIR)/inc INC += -I$(CMSIS_DIR)/inc
INC += -I$(CMSIS_DIR)/devinc INC += -I$(CMSIS_DIR)/devinc
INC += -I$(HAL_DIR)/inc INC += -I$(HAL_DIR)/inc
...@@ -54,28 +55,30 @@ LIBS = ...@@ -54,28 +55,30 @@ LIBS =
SRC_C = \ SRC_C = \
main.c \ main.c \
string0.c \
system_stm32f4xx.c \ system_stm32f4xx.c \
stm32f4xx_it.c \ stm32f4xx_it.c \
stm32f4xx_hal_msp.c \ stm32f4xx_hal_msp.c \
systick.c \
led.c \
pin.c \
usart.c \
printf.c \
math.c \
malloc0.c \
gccollect.c \
pyexec.c \
pybmodule.c \
import.c \
lexerfatfs.c \
# printf.c \
# math.c \
# string0.c \
# malloc0.c \
# systick.c \
# pendsv.c \ # pendsv.c \
# gccollect.c \
# lexerfatfs.c \
# import.c \
# pyexec.c \
# led.c \
# gpio.c \ # gpio.c \
# lcd.c \ # lcd.c \
# servo.c \ # servo.c \
# flash.c \ # flash.c \
# storage.c \ # storage.c \
# accel.c \ # accel.c \
# usart.c \
# usb.c \ # usb.c \
# timer.c \ # timer.c \
# audio.c \ # audio.c \
...@@ -84,24 +87,23 @@ SRC_C = \ ...@@ -84,24 +87,23 @@ SRC_C = \
# adc.c \ # adc.c \
# rtc.c \ # rtc.c \
# file.c \ # file.c \
# pin.c \
# pin_named_pins.c \ # pin_named_pins.c \
# pin_map.c \ # pin_map.c \
# exti.c \ # exti.c \
# usrsw.c \ # usrsw.c \
# pybmodule.c \
# pybwlan.c \ # pybwlan.c \
SRC_S = \ SRC_S = \
startup_stm32f40xx.s \ startup_stm32f40xx.s \
gchelper.s \
# gchelper.s \
SRC_HAL = $(addprefix $(HAL_DIR)/src/,\ SRC_HAL = $(addprefix $(HAL_DIR)/src/,\
stm32f4xx_hal.c \ stm32f4xx_hal.c \
stm32f4xx_hal_cortex.c \ stm32f4xx_hal_cortex.c \
stm32f4xx_hal_rcc.c \ stm32f4xx_hal_dma.c \
stm32f4xx_hal_gpio.c \ stm32f4xx_hal_gpio.c \
stm32f4xx_hal_rcc.c \
stm32f4xx_hal_uart.c \
) )
SRC_STMPERIPH = $(addprefix $(STMPERIPH_DIR)/,\ SRC_STMPERIPH = $(addprefix $(STMPERIPH_DIR)/,\
...@@ -182,7 +184,7 @@ SRC_CC3K = $(addprefix $(CC3K_DIR)/,\ ...@@ -182,7 +184,7 @@ SRC_CC3K = $(addprefix $(CC3K_DIR)/,\
) )
OBJ = OBJ =
#OBJ += $(PY_O) OBJ += $(PY_O)
OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_HAL:.c=.o)) OBJ += $(addprefix $(BUILD)/, $(SRC_HAL:.c=.o))
...@@ -191,7 +193,7 @@ OBJ += $(addprefix $(BUILD)/, $(SRC_HAL:.c=.o)) ...@@ -191,7 +193,7 @@ OBJ += $(addprefix $(BUILD)/, $(SRC_HAL:.c=.o))
#OBJ += $(addprefix $(BUILD)/, $(SRC_STMUSBH:.c=.o)) #OBJ += $(addprefix $(BUILD)/, $(SRC_STMUSBH:.c=.o))
#OBJ += $(addprefix $(BUILD)/, $(SRC_FATFS:.c=.o)) #OBJ += $(addprefix $(BUILD)/, $(SRC_FATFS:.c=.o))
#OBJ += $(addprefix $(BUILD)/, $(SRC_CC3K:.c=.o)) #OBJ += $(addprefix $(BUILD)/, $(SRC_CC3K:.c=.o))
#OBJ += $(BUILD)/pins_$(BOARD).o OBJ += $(BUILD)/pins_$(BOARD).o
all: $(BUILD)/flash.dfu all: $(BUILD)/flash.dfu
...@@ -222,7 +224,12 @@ GEN_PINS_HDR = $(BUILD)/pins.h ...@@ -222,7 +224,12 @@ GEN_PINS_HDR = $(BUILD)/pins.h
# any of the objects. The normal dependency generation will deal with the # any of the objects. The normal dependency generation will deal with the
# case when pins.h is modified. But when it doesn't exist, we don't know # case when pins.h is modified. But when it doesn't exist, we don't know
# which source files might need it. # which source files might need it.
#$(OBJ): | $(BUILD)/pins.h $(OBJ): | $(BUILD)/pins.h
# temp hack
$(PY_BUILD):
mkdir -p $@
$(OBJ): | $(PY_BUILD) $(PY_BUILD)/qstrdefs.generated.h
# Use a pattern rule here so that make will only call make-pins.py once to make # Use a pattern rule here so that make will only call make-pins.py once to make
# both pins_$(BOARD).c and pins.h # both pins_$(BOARD).c and pins.h
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdint.h> #include <stdint.h>
#include <stm32f4xx.h> #include <stm32f4xx_hal.h>
#include "misc.h" #include "misc.h"
#include "mpconfig.h" #include "mpconfig.h"
......
#include <stdio.h>
#include <stm32f4xx_hal.h>
#include "misc.h"
#include "mpconfig.h"
#include "qstr.h"
#include "obj.h"
#include "gc.h"
#include "gccollect.h"
machine_uint_t gc_helper_get_regs_and_sp(machine_uint_t *regs);
// obsolete
// void gc_helper_get_regs_and_clean_stack(machine_uint_t *regs, machine_uint_t heap_end);
void gc_collect(void) {
// get current time, in case we want to time the GC
uint32_t start = HAL_GetTick();
// start the GC
gc_collect_start();
// scan everything in RAM before the heap
// this includes the data and bss segments
// TODO possibly don't need to scan data, since all pointers should start out NULL and be in bss
gc_collect_root((void**)&_ram_start, ((uint32_t)&_ebss - (uint32_t)&_ram_start) / sizeof(uint32_t));
// get the registers and the sp
machine_uint_t regs[10];
machine_uint_t sp = gc_helper_get_regs_and_sp(regs);
// trace the stack, including the registers (since they live on the stack in this function)
gc_collect_root((void**)sp, ((uint32_t)&_ram_end - sp) / sizeof(uint32_t));
// end the GC
gc_collect_end();
if (0) {
// print GC info
uint32_t ticks = HAL_GetTick() - start; // TODO implement a function that does this properly
gc_info_t info;
gc_info(&info);
printf("GC@%lu %lums\n", start, ticks);
printf(" %lu total\n", info.total);
printf(" %lu : %lu\n", info.used, info.free);
printf(" 1=%lu 2=%lu m=%lu\n", info.num_1block, info.num_2block, info.max_block);
}
}
static mp_obj_t pyb_gc(void) {
gc_collect();
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_0(pyb_gc_obj, pyb_gc);
// variables defining memory layout
// (these probably belong somewhere else...)
extern uint32_t _etext;
extern uint32_t _sidata;
extern uint32_t _ram_start;
extern uint32_t _sdata;
extern uint32_t _edata;
extern uint32_t _sbss;
extern uint32_t _ebss;
extern uint32_t _heap_start;
extern uint32_t _heap_end;
extern uint32_t _estack;
extern uint32_t _ram_end;
void gc_collect(void);
MP_DECLARE_CONST_FUN_OBJ(pyb_gc_obj);
.syntax unified
.cpu cortex-m4
.thumb
.text
.align 2
@ uint gc_helper_get_regs_and_sp(r0=uint regs[10])
.global gc_helper_get_regs_and_sp
.thumb
.thumb_func
.type gc_helper_get_regs_and_sp, %function
gc_helper_get_regs_and_sp:
@ store registers into given array
str r4, [r0], #4
str r5, [r0], #4
str r6, [r0], #4
str r7, [r0], #4
str r8, [r0], #4
str r9, [r0], #4
str r10, [r0], #4
str r11, [r0], #4
str r12, [r0], #4
str r13, [r0], #4
@ return the sp
mov r0, sp
bx lr
@ this next function is now obsolete
.size gc_helper_get_regs_and_clean_stack, .-gc_helper_get_regs_and_clean_stack
@ void gc_helper_get_regs_and_clean_stack(r0=uint regs[10], r1=heap_end)
.global gc_helper_get_regs_and_clean_stack
.thumb
.thumb_func
.type gc_helper_get_regs_and_clean_stack, %function
gc_helper_get_regs_and_clean_stack:
@ store registers into given array
str r4, [r0], #4
str r5, [r0], #4
str r6, [r0], #4
str r7, [r0], #4
str r8, [r0], #4
str r9, [r0], #4
str r10, [r0], #4
str r11, [r0], #4
str r12, [r0], #4
str r13, [r0], #4
@ clean the stack from given pointer up to current sp
movs r0, #0
mov r2, sp
b.n .entry
.loop:
str r0, [r1], #4
.entry:
cmp r1, r2
bcc.n .loop
bx lr
.size gc_helper_get_regs_and_clean_stack, .-gc_helper_get_regs_and_clean_stack
#include <stdint.h>
#include "misc.h"
#include "mpconfig.h"
#include "qstr.h"
#include "lexer.h"
#if 0
#include "ff.h"
#endif
mp_import_stat_t mp_import_stat(const char *path) {
#if 0
FILINFO fno;
FRESULT res = f_stat(path, &fno);
if (res == FR_OK) {
if ((fno.fattrib & AM_DIR) != 0) {
return MP_IMPORT_STAT_DIR;
} else {
return MP_IMPORT_STAT_FILE;
}
}
#endif
return MP_IMPORT_STAT_NO_EXIST;
}
#include <stdio.h>
#include <stm32f4xx_hal.h>
#include "misc.h"
#include "mpconfig.h"
#include "qstr.h"
#include "obj.h"
#include "led.h"
#include "pin.h"
#include "build/pins.h"
static const pin_obj_t *gLed[] = {
&PYB_LED1,
#if defined(PYB_LED2)
&PYB_LED2,
#if defined(PYB_LED3)
&PYB_LED3,
#if defined(PYB_LED4)
&PYB_LED4,
#endif
#endif
#endif
};
#define NUM_LEDS (sizeof(gLed) / sizeof(gLed[0]))
void led_init(void) {
/* GPIO structure */
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure I/O speed, mode, output type and pull */
GPIO_InitStructure.Speed = GPIO_SPEED_LOW;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL;
/* Turn off LEDs and initialize */
for (int led = 0; led < NUM_LEDS; led++) {
PYB_LED_OFF(gLed[led]);
GPIO_InitStructure.Pin = gLed[led]->pin_mask;
HAL_GPIO_Init(gLed[led]->gpio, &GPIO_InitStructure);
}
}
void led_state(pyb_led_t led, int state) {
if (led < 1 || led > NUM_LEDS) {
return;
}
const pin_obj_t *led_pin = gLed[led - 1];
if (state == 0) {
// turn LED off
PYB_LED_OFF(led_pin);
} else {
// turn LED on
PYB_LED_ON(led_pin);
}
}
void led_toggle(pyb_led_t led) {
if (led < 1 || led > NUM_LEDS) {
return;
}
const pin_obj_t *led_pin = gLed[led - 1];
GPIO_TypeDef *gpio = led_pin->gpio;
// We don't know if we're turning the LED on or off, but we don't really
// care. Just invert the state.
if (gpio->ODR & led_pin->pin_mask) {
// pin is high, make it low
gpio->BSRRH = led_pin->pin_mask;
} else {
// pin is low, make it high
gpio->BSRRL = led_pin->pin_mask;
}
}
#if 0
/******************************************************************************/
/* Micro Python bindings */
typedef struct _pyb_led_obj_t {
mp_obj_base_t base;
uint led_id;
} pyb_led_obj_t;
void led_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
pyb_led_obj_t *self = self_in;
print(env, "<LED %lu>", self->led_id);
}
mp_obj_t led_obj_on(mp_obj_t self_in) {
pyb_led_obj_t *self = self_in;
led_state(self->led_id, 1);
return mp_const_none;
}
mp_obj_t led_obj_off(mp_obj_t self_in) {
pyb_led_obj_t *self = self_in;
led_state(self->led_id, 0);
return mp_const_none;
}
mp_obj_t led_obj_toggle(mp_obj_t self_in) {
pyb_led_obj_t *self = self_in;
led_toggle(self->led_id);
return mp_const_none;
}
static MP_DEFINE_CONST_FUN_OBJ_1(led_obj_on_obj, led_obj_on);
static MP_DEFINE_CONST_FUN_OBJ_1(led_obj_off_obj, led_obj_off);
static MP_DEFINE_CONST_FUN_OBJ_1(led_obj_toggle_obj, led_obj_toggle);
static const mp_method_t led_methods[] = {
{ "on", &led_obj_on_obj },
{ "off", &led_obj_off_obj },
{ "toggle", &led_obj_toggle_obj },
{ NULL, NULL },
};
static const mp_obj_type_t led_obj_type = {
{ &mp_type_type },
.name = MP_QSTR_Led,
.print = led_obj_print,
.methods = led_methods,
};
static mp_obj_t pyb_Led(mp_obj_t led_id) {
pyb_led_obj_t *o = m_new_obj(pyb_led_obj_t);
o->base.type = &led_obj_type;
o->led_id = mp_obj_get_int(led_id);
return o;
}
MP_DEFINE_CONST_FUN_OBJ_1(pyb_Led_obj, pyb_Led);
#endif
typedef enum {
// PYBv3
PYB_LED_R1 = 1,
PYB_LED_R2 = 2,
PYB_LED_G1 = 3,
PYB_LED_G2 = 4,
// PYBv4
PYB_LED_RED = 1,
PYB_LED_GREEN = 2,
PYB_LED_YELLOW = 3,
PYB_LED_BLUE = 4,
//STM32F4DISC
PYB_LED_R = 1,
PYB_LED_G = 2,
PYB_LED_B = 3,
PYB_LED_O = 4,
} pyb_led_t;
void led_init(void);
void led_state(pyb_led_t led, int state);
void led_toggle(pyb_led_t led);
#if 0
MP_DECLARE_CONST_FUN_OBJ(pyb_Led_obj);
#endif
#include <stdint.h>
#include <stdio.h>
#if 0
#include "ff.h"
#endif
#include "misc.h"
#include "mpconfig.h"
#include "qstr.h"
#include "lexer.h"
#include "lexerfatfs.h"
#if 0
typedef struct _mp_lexer_file_buf_t {
FIL fp;
char buf[20];
uint16_t len;
uint16_t pos;
} mp_lexer_file_buf_t;
static unichar file_buf_next_char(mp_lexer_file_buf_t *fb) {
if (fb->pos >= fb->len) {
if (fb->len < sizeof(fb->buf)) {
return MP_LEXER_CHAR_EOF;
} else {
UINT n;
f_read(&fb->fp, fb->buf, sizeof(fb->buf), &n);
if (n == 0) {
return MP_LEXER_CHAR_EOF;
}
fb->len = n;
fb->pos = 0;
}
}
return fb->buf[fb->pos++];
}
static void file_buf_close(mp_lexer_file_buf_t *fb) {
f_close(&fb->fp);
m_del_obj(mp_lexer_file_buf_t, fb);
}
#endif
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
#if 0
mp_lexer_file_buf_t *fb = m_new_obj(mp_lexer_file_buf_t);
FRESULT res = f_open(&fb->fp, filename, FA_READ);
if (res != FR_OK) {
m_del_obj(mp_lexer_file_buf_t, fb);
return NULL;
}
UINT n;
f_read(&fb->fp, fb->buf, sizeof(fb->buf), &n);
fb->len = n;
fb->pos = 0;
return mp_lexer_new(qstr_from_str(filename), fb, (mp_lexer_stream_next_char_t)file_buf_next_char, (mp_lexer_stream_close_t)file_buf_close);
#else
return NULL;
#endif
}
mp_lexer_t *mp_lexer_new_from_file(const char *filename);
...@@ -15,19 +15,18 @@ ...@@ -15,19 +15,18 @@
#include <stm32f4xx_usart.h> #include <stm32f4xx_usart.h>
#include <stm32f4xx_rng.h> #include <stm32f4xx_rng.h>
#include <usbd_storage_msd.h> #include <usbd_storage_msd.h>
#include <stm_misc.h>
#endif #endif
#include "std.h" #include "std.h"
#if 0
#include "misc.h" #include "misc.h"
#include "ff.h" #include "systick.h"
#include "led.h"
#include "usart.h"
#include "mpconfig.h" #include "mpconfig.h"
#include "qstr.h" #include "qstr.h"
#include "nlr.h" #include "nlr.h"
#include "misc.h" #include "misc.h"
#include "lexer.h" #include "lexer.h"
#include "lexerfatfs.h"
#include "parse.h" #include "parse.h"
#include "obj.h" #include "obj.h"
#include "parsehelper.h" #include "parsehelper.h"
...@@ -36,10 +35,12 @@ ...@@ -36,10 +35,12 @@
#include "runtime.h" #include "runtime.h"
#include "gc.h" #include "gc.h"
#include "gccollect.h" #include "gccollect.h"
#include "systick.h"
#include "pendsv.h"
#include "pyexec.h" #include "pyexec.h"
#include "led.h" #include "pybmodule.h"
#if 0
#include "ff.h"
#include "lexerfatfs.h"
#include "pendsv.h"
#include "servo.h" #include "servo.h"
#include "lcd.h" #include "lcd.h"
#include "storage.h" #include "storage.h"
...@@ -53,9 +54,11 @@ ...@@ -53,9 +54,11 @@
#include "file.h" #include "file.h"
#include "pin.h" #include "pin.h"
#include "exti.h" #include "exti.h"
#include "pybmodule.h"
#endif #endif
void SystemClock_Config(void);
int errno; int errno;
#if 0 #if 0
...@@ -65,7 +68,6 @@ static FATFS fatfs1; ...@@ -65,7 +68,6 @@ static FATFS fatfs1;
#endif #endif
#endif #endif
#if 0
void flash_error(int n) { void flash_error(int n) {
for (int i = 0; i < n; i++) { for (int i = 0; i < n; i++) {
led_state(PYB_LED_R1, 1); led_state(PYB_LED_R1, 1);
...@@ -87,9 +89,7 @@ void __fatal_error(const char *msg) { ...@@ -87,9 +89,7 @@ void __fatal_error(const char *msg) {
flash_error(1); flash_error(1);
} }