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-
INC = -I.
INC += -I$(PY_SRC)
INC += -I$(CMSIS_DIR)
INC += -I$(CMSIS_DIR)/inc
INC += -I$(CMSIS_DIR)/devinc
INC += -I$(HAL_DIR)/inc
......@@ -54,28 +55,30 @@ LIBS =
SRC_C = \
main.c \
string0.c \
system_stm32f4xx.c \
stm32f4xx_it.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 \
# gccollect.c \
# lexerfatfs.c \
# import.c \
# pyexec.c \
# led.c \
# gpio.c \
# lcd.c \
# servo.c \
# flash.c \
# storage.c \
# accel.c \
# usart.c \
# usb.c \
# timer.c \
# audio.c \
......@@ -84,24 +87,23 @@ SRC_C = \
# adc.c \
# rtc.c \
# file.c \
# pin.c \
# pin_named_pins.c \
# pin_map.c \
# exti.c \
# usrsw.c \
# pybmodule.c \
# pybwlan.c \
SRC_S = \
startup_stm32f40xx.s \
# gchelper.s \
gchelper.s \
SRC_HAL = $(addprefix $(HAL_DIR)/src/,\
stm32f4xx_hal.c \
stm32f4xx_hal_cortex.c \
stm32f4xx_hal_rcc.c \
stm32f4xx_hal_dma.c \
stm32f4xx_hal_gpio.c \
stm32f4xx_hal_rcc.c \
stm32f4xx_hal_uart.c \
)
SRC_STMPERIPH = $(addprefix $(STMPERIPH_DIR)/,\
......@@ -182,7 +184,7 @@ SRC_CC3K = $(addprefix $(CC3K_DIR)/,\
)
OBJ =
#OBJ += $(PY_O)
OBJ += $(PY_O)
OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o))
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_FATFS:.c=.o))
#OBJ += $(addprefix $(BUILD)/, $(SRC_CC3K:.c=.o))
#OBJ += $(BUILD)/pins_$(BOARD).o
OBJ += $(BUILD)/pins_$(BOARD).o
all: $(BUILD)/flash.dfu
......@@ -222,7 +224,12 @@ GEN_PINS_HDR = $(BUILD)/pins.h
# 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
# 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
# both pins_$(BOARD).c and pins.h
......
......@@ -2,7 +2,7 @@
#include <stdio.h>
#include <stdint.h>
#include <stm32f4xx.h>
#include <stm32f4xx_hal.h>
#include "misc.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 @@
#include <stm32f4xx_usart.h>
#include <stm32f4xx_rng.h>
#include <usbd_storage_msd.h>
#include <stm_misc.h>
#endif
#include "std.h"
#if 0
#include "misc.h"
#include "ff.h"
#include "systick.h"
#include "led.h"
#include "usart.h"
#include "mpconfig.h"
#include "qstr.h"
#include "nlr.h"
#include "misc.h"
#include "lexer.h"
#include "lexerfatfs.h"
#include "parse.h"
#include "obj.h"
#include "parsehelper.h"
......@@ -36,10 +35,12 @@
#include "runtime.h"
#include "gc.h"
#include "gccollect.h"
#include "systick.h"
#include "pendsv.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 "lcd.h"
#include "storage.h"
......@@ -53,9 +54,11 @@
#include "file.h"
#include "pin.h"
#include "exti.h"
#include "pybmodule.h"
#endif
void SystemClock_Config(void);
int errno;
#if 0
......@@ -65,7 +68,6 @@ static FATFS fatfs1;
#endif
#endif
#if 0
void flash_error(int n) {
for (int i = 0; i < n; i++) {
led_state(PYB_LED_R1, 1);
......@@ -87,9 +89,7 @@ void __fatal_error(const char *msg) {
flash_error(1);
}
}
#endif
#if 0
STATIC mp_obj_t pyb_config_source_dir = MP_OBJ_NULL;
STATIC mp_obj_t pyb_config_main = MP_OBJ_NULL;
......@@ -161,93 +161,6 @@ static mp_obj_t pyb_help(void) {
printf("%s", help_text);
return mp_const_none;
}
#endif
void led_init(void) {
/* GPIO structure */
GPIO_InitTypeDef GPIO_InitStructure;
/* Configure I/O speed, mode, output type and pull */
GPIO_InitStructure.Pin = GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_LOW;
GPIO_InitStructure.Alternate = 0; // unused
/* initialize */
HAL_GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void led_state(int led_id, int state) {
HAL_GPIO_WritePin(GPIOA, 1 << (13 + led_id), state);
}
/**
* @brief System Clock Configuration
* The system Clock is configured as follow :
* System Clock source = PLL (HSE)
* SYSCLK(Hz) = 168000000
* HCLK(Hz) = 168000000
* AHB Prescaler = 1
* APB1 Prescaler = 4
* APB2 Prescaler = 2
* HSE Frequency(Hz) = 8000000
* PLL_M = 8
* PLL_N = 336
* PLL_P = 2
* PLL_Q = 7
* VDD(V) = 3.3
* Main regulator output voltage = Scale1 mode
* Flash Latency(WS) = 5
* @param None
* @retval None
*/
static void SystemClock_Config(void) {
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
/* Enable Power Control clock */
__PWR_CLK_ENABLE();
/* The voltage scaling allows optimizing the power consumption when the device is
clocked below the maximum system frequency, to update the voltage scaling value
regarding system frequency refer to product datasheet. */
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/* Enable HSE Oscillator and activate PLL with HSE as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 8;
RCC_OscInitStruct.PLL.PLLN = 336;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7;
if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
/* Initialization Error */
for (;;) {