REPl working on UART6 with STMHAL
This commit is contained in:
parent
19438fd30a
commit
f14b92b9e1
|
@ -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"
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
#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);
|
|
@ -0,0 +1,17 @@
|
|||
// 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);
|
|
@ -0,0 +1,62 @@
|
|||
.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
|
|
@ -0,0 +1,24 @@
|
|||
#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;
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
#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
|
|
@ -0,0 +1,25 @@
|
|||
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
|
|
@ -0,0 +1,61 @@
|
|||
#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
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
mp_lexer_t *mp_lexer_new_from_file(const char *filename);
|
158
stmhal/main.c
158
stmhal/main.c
|
@ -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 (;;) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
|
||||
clocks dividers */
|
||||
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
|
||||
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
|
||||
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
|
||||
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
|
||||
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
|
||||
if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
|
||||
{
|
||||
/* Initialization Error */
|
||||
for (;;) {
|
||||
}
|
||||
}
|
||||
|
||||
// Make SysTick interrupt have the highest priority
|
||||
// This is needed so that SysTick runs in all ISRs.
|
||||
NVIC_SetPriority(SysTick_IRQn, 0);
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
// TODO disable JTAG
|
||||
|
@ -279,15 +192,13 @@ int main(void) {
|
|||
led_state(1, 0);
|
||||
led_state(2, 1);
|
||||
|
||||
#if 0
|
||||
for (;;) {
|
||||
HAL_Delay(500);
|
||||
led_state(1, 1);
|
||||
HAL_Delay(500);
|
||||
led_state(1, 0);
|
||||
}
|
||||
|
||||
#if 0
|
||||
_fatal_error("done");
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
|
@ -328,29 +239,57 @@ int main(void) {
|
|||
GPIO_Init(GPIOB, &GPIO_InitStructure);
|
||||
GPIO_WriteBit(GPIOB, GPIO_Pin_2, Bit_SET);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// basic sub-system init
|
||||
sys_tick_init();
|
||||
#if 0
|
||||
pendsv_init();
|
||||
#endif
|
||||
led_init();
|
||||
|
||||
#if 0
|
||||
#if MICROPY_HW_ENABLE_RTC
|
||||
rtc_init();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// turn on LED to indicate bootup
|
||||
led_state(PYB_LED_G1, 1);
|
||||
|
||||
#if 0
|
||||
// more sub-system init
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
sdcard_init();
|
||||
#endif
|
||||
storage_init();
|
||||
#endif
|
||||
|
||||
// uncomment these 2 lines if you want REPL on USART_6 (or another usart) as well as on USB VCP
|
||||
//pyb_usart_global_debug = PYB_USART_YA;
|
||||
//usart_init(pyb_usart_global_debug, 115200);
|
||||
pyb_usart_global_debug = PYB_USART_YA;
|
||||
usart_init(pyb_usart_global_debug, 115200);
|
||||
|
||||
#if 0
|
||||
pyb_led_t led = 1;
|
||||
while (1) {
|
||||
led_state(led, 1);
|
||||
usart_tx_strn_cooked(pyb_usart_global_debug, "on\n", 3);
|
||||
sys_tick_delay_ms(100);
|
||||
led_state(led, 0);
|
||||
usart_tx_strn_cooked(pyb_usart_global_debug, "off\n", 4);
|
||||
sys_tick_delay_ms(100);
|
||||
led_state(led, 1);
|
||||
usart_tx_strn_cooked(pyb_usart_global_debug, "on\n", 3);
|
||||
sys_tick_delay_ms(100);
|
||||
led_state(led, 0);
|
||||
usart_tx_strn_cooked(pyb_usart_global_debug, "off\n", 4);
|
||||
sys_tick_delay_ms(700);
|
||||
|
||||
led = (led % 4) + 1;
|
||||
}
|
||||
__fatal_error("done");
|
||||
#endif
|
||||
|
||||
int first_soft_reset = true;
|
||||
|
||||
|
@ -368,6 +307,7 @@ soft_reset:
|
|||
def_path[2] = MP_OBJ_NEW_QSTR(MP_QSTR_0_colon__slash_lib);
|
||||
sys_path = mp_obj_new_list(3, def_path);
|
||||
|
||||
#if 0
|
||||
exti_init();
|
||||
|
||||
#if MICROPY_HW_HAS_SWITCH
|
||||
|
@ -396,15 +336,19 @@ soft_reset:
|
|||
#endif
|
||||
|
||||
pin_map_init();
|
||||
#endif
|
||||
|
||||
// add some functions to the builtin Python namespace
|
||||
rt_store_name(MP_QSTR_help, rt_make_function_n(0, pyb_help));
|
||||
#if 0
|
||||
rt_store_name(MP_QSTR_open, rt_make_function_n(2, pyb_io_open));
|
||||
#endif
|
||||
|
||||
// we pre-import the pyb module
|
||||
// probably shouldn't do this, so we are compatible with CPython
|
||||
rt_store_name(MP_QSTR_pyb, (mp_obj_t)&pyb_module);
|
||||
|
||||
#if 0
|
||||
// check if user switch held (initiates reset of filesystem)
|
||||
bool reset_filesystem = false;
|
||||
#if MICROPY_HW_HAS_SWITCH
|
||||
|
@ -497,16 +441,20 @@ soft_reset:
|
|||
flash_error(4);
|
||||
}
|
||||
|
||||
#endif
|
||||
if (first_soft_reset) {
|
||||
#if 0
|
||||
#if MICROPY_HW_HAS_MMA7660
|
||||
// MMA accel: init and reset address to zero
|
||||
accel_init();
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
// turn boot-up LED off
|
||||
led_state(PYB_LED_G1, 0);
|
||||
|
||||
#if 0
|
||||
#if MICROPY_HW_HAS_SDCARD
|
||||
// if an SD card is present then mount it on 1:/
|
||||
if (sdcard_is_present()) {
|
||||
|
@ -591,16 +539,18 @@ soft_reset:
|
|||
// wifi
|
||||
pyb_wlan_init();
|
||||
pyb_wlan_start();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
pyexec_repl();
|
||||
|
||||
#if 0
|
||||
printf("PYB: sync filesystems\n");
|
||||
storage_flush();
|
||||
#endif
|
||||
|
||||
printf("PYB: soft reboot\n");
|
||||
|
||||
first_soft_reset = false;
|
||||
goto soft_reset;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
#include <stdint.h>
|
||||
#include "std.h"
|
||||
#include "mpconfig.h"
|
||||
#include "gc.h"
|
||||
|
||||
#if 0
|
||||
static uint32_t mem = 0;
|
||||
|
||||
void *malloc(size_t n) {
|
||||
if (mem == 0) {
|
||||
extern uint32_t _heap_start;
|
||||
mem = (uint32_t)&_heap_start; // need to use big ram block so we can execute code from it (is it true that we can't execute from CCM?)
|
||||
}
|
||||
void *ptr = (void*)mem;
|
||||
mem = (mem + n + 3) & (~3);
|
||||
if (mem > 0x20000000 + 0x18000) {
|
||||
void __fatal_error(const char*);
|
||||
__fatal_error("out of memory");
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void free(void *ptr) {
|
||||
}
|
||||
|
||||
void *realloc(void *ptr, size_t n) {
|
||||
return malloc(n);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void __assert_func(void) {
|
||||
printf("\nASSERT FAIL!");
|
||||
for (;;) {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,407 @@
|
|||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
|
||||
// these 2 functions seem to actually work... no idea why
|
||||
// replacing with libgcc does not work (probably due to wrong calling conventions)
|
||||
double __aeabi_f2d(float x) {
|
||||
// TODO
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
float __aeabi_d2f(double x) {
|
||||
// TODO
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/*
|
||||
double sqrt(double x) {
|
||||
// TODO
|
||||
return 0.0;
|
||||
}
|
||||
*/
|
||||
|
||||
float sqrtf(float x) {
|
||||
asm volatile (
|
||||
"vsqrt.f32 %[r], %[x]\n"
|
||||
: [r] "=t" (x)
|
||||
: [x] "t" (x));
|
||||
return x;
|
||||
}
|
||||
|
||||
// TODO we need import these functions from some library (eg musl or newlib)
|
||||
float powf(float x, float y) { return 0.0; }
|
||||
float logf(float x) { return 0.0; }
|
||||
float log2f(float x) { return 0.0; }
|
||||
float log10f(float x) { return 0.0; }
|
||||
float tanhf(float x) { return 0.0; }
|
||||
float acoshf(float x) { return 0.0; }
|
||||
float asinhf(float x) { return 0.0; }
|
||||
float atanhf(float x) { return 0.0; }
|
||||
float cosf(float x) { return 0.0; }
|
||||
float sinf(float x) { return 0.0; }
|
||||
float tanf(float x) { return 0.0; }
|
||||
float acosf(float x) { return 0.0; }
|
||||
float asinf(float x) { return 0.0; }
|
||||
float atanf(float x) { return 0.0; }
|
||||
float atan2f(float x, float y) { return 0.0; }
|
||||
|
||||
/*****************************************************************************/
|
||||
// from musl-0.9.15 libm.h
|
||||
|
||||
/* origin: FreeBSD /usr/src/lib/msun/src/math_private.h */
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
#define FORCE_EVAL(x) do { \
|
||||
if (sizeof(x) == sizeof(float)) { \
|
||||
volatile float __x; \
|
||||
__x = (x); \
|
||||
(void)__x; \
|
||||
} else if (sizeof(x) == sizeof(double)) { \
|
||||
volatile double __x; \
|
||||
__x = (x); \
|
||||
(void)__x; \
|
||||
} else { \
|
||||
volatile long double __x; \
|
||||
__x = (x); \
|
||||
(void)__x; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
/* Get a 32 bit int from a float. */
|
||||
#define GET_FLOAT_WORD(w,d) \
|
||||
do { \
|
||||
union {float f; uint32_t i;} __u; \
|
||||
__u.f = (d); \
|
||||
(w) = __u.i; \
|
||||
} while (0)
|
||||
|
||||
/* Set a float from a 32 bit int. */
|
||||
#define SET_FLOAT_WORD(d,w) \
|
||||
do { \
|
||||
union {float f; uint32_t i;} __u; \
|
||||
__u.i = (w); \
|
||||
(d) = __u.f; \
|
||||
} while (0)
|
||||
|
||||
/*****************************************************************************/
|
||||
// scalbnf from musl-0.9.15
|
||||
|
||||
float scalbnf(float x, int n)
|
||||
{
|
||||
union {float f; uint32_t i;} u;
|
||||
float_t y = x;
|
||||
|
||||
if (n > 127) {
|
||||
y *= 0x1p127f;
|
||||
n -= 127;
|
||||
if (n > 127) {
|
||||
y *= 0x1p127f;
|
||||
n -= 127;
|
||||
if (n > 127)
|
||||
n = 127;
|
||||
}
|
||||
} else if (n < -126) {
|
||||
y *= 0x1p-126f;
|
||||
n += 126;
|
||||
if (n < -126) {
|
||||
y *= 0x1p-126f;
|
||||
n += 126;
|
||||
if (n < -126)
|
||||
n = -126;
|
||||
}
|
||||
}
|
||||
u.i = (uint32_t)(0x7f+n)<<23;
|
||||
x = y * u.f;
|
||||
return x;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
// expf from musl-0.9.15
|
||||
|
||||
/* origin: FreeBSD /usr/src/lib/msun/src/e_expf.c */
|
||||
/*
|
||||
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
|
||||
*/
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
static const float
|
||||
half[2] = {0.5,-0.5},
|
||||
ln2hi = 6.9314575195e-1f, /* 0x3f317200 */
|
||||
ln2lo = 1.4286067653e-6f, /* 0x35bfbe8e */
|
||||
invln2 = 1.4426950216e+0f, /* 0x3fb8aa3b */
|
||||
/*
|
||||
* Domain [-0.34568, 0.34568], range ~[-4.278e-9, 4.447e-9]:
|
||||
* |x*(exp(x)+1)/(exp(x)-1) - p(x)| < 2**-27.74
|
||||
*/
|
||||
P1 = 1.6666625440e-1f, /* 0xaaaa8f.0p-26 */
|
||||
P2 = -2.7667332906e-3f; /* -0xb55215.0p-32 */
|
||||
|
||||
float expf(float x)
|
||||
{
|
||||
float_t hi, lo, c, xx, y;
|
||||
int k, sign;
|
||||
uint32_t hx;
|
||||
|
||||
GET_FLOAT_WORD(hx, x);
|
||||
sign = hx >> 31; /* sign bit of x */
|
||||
hx &= 0x7fffffff; /* high word of |x| */
|
||||
|
||||
/* special cases */
|
||||
if (hx >= 0x42aeac50) { /* if |x| >= -87.33655f or NaN */
|
||||
if (hx >= 0x42b17218 && !sign) { /* x >= 88.722839f */
|
||||
/* overflow */
|
||||
x *= 0x1p127f;
|
||||
return x;
|
||||
}
|
||||
if (sign) {
|
||||
/* underflow */
|
||||
FORCE_EVAL(-0x1p-149f/x);
|
||||
if (hx >= 0x42cff1b5) /* x <= -103.972084f */
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* argument reduction */
|
||||
if (hx > 0x3eb17218) { /* if |x| > 0.5 ln2 */
|
||||
if (hx > 0x3f851592) /* if |x| > 1.5 ln2 */
|
||||
k = invln2*x + half[sign];
|
||||
else
|
||||
k = 1 - sign - sign;
|
||||
hi = x - k*ln2hi; /* k*ln2hi is exact here */
|
||||
lo = k*ln2lo;
|
||||
x = hi - lo;
|
||||
} else if (hx > 0x39000000) { /* |x| > 2**-14 */
|
||||
k = 0;
|
||||
hi = x;
|
||||
lo = 0;
|
||||
} else {
|
||||
/* raise inexact */
|
||||
FORCE_EVAL(0x1p127f + x);
|
||||
return 1 + x;
|
||||
}
|
||||
|
||||
/* x is now in primary range */
|
||||
xx = x*x;
|
||||
c = x - xx*(P1+xx*P2);
|
||||
y = 1 + (x*c/(2-c) - lo + hi);
|
||||
if (k == 0)
|
||||
return y;
|
||||
return scalbnf(y, k);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
// expm1f from musl-0.9.15
|
||||
|
||||
/* origin: FreeBSD /usr/src/lib/msun/src/s_expm1f.c */
|
||||
/*
|
||||
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
|
||||
*/
|
||||
/*
|
||||
* ====================================================
|
||||
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
|
||||
*
|
||||
* Developed at SunPro, a Sun Microsystems, Inc. business.
|
||||
* Permission to use, copy, modify, and distribute this
|
||||
* software is freely granted, provided that this notice
|
||||
* is preserved.
|
||||
* ====================================================
|
||||
*/
|
||||
|
||||
static const float
|
||||
o_threshold = 8.8721679688e+01, /* 0x42b17180 */
|
||||
ln2_hi = 6.9313812256e-01, /* 0x3f317180 */
|
||||
ln2_lo = 9.0580006145e-06, /* 0x3717f7d1 */
|
||||
//invln2 = 1.4426950216e+00, /* 0x3fb8aa3b */
|
||||
/*
|
||||
* Domain [-0.34568, 0.34568], range ~[-6.694e-10, 6.696e-10]:
|
||||
* |6 / x * (1 + 2 * (1 / (exp(x) - 1) - 1 / x)) - q(x)| < 2**-30.04
|
||||
* Scaled coefficients: Qn_here = 2**n * Qn_for_q (see s_expm1.c):
|
||||
*/
|
||||
Q1 = -3.3333212137e-2, /* -0x888868.0p-28 */
|
||||
Q2 = 1.5807170421e-3; /* 0xcf3010.0p-33 */
|
||||
|
||||
float expm1f(float x)
|
||||
{
|
||||
float_t y,hi,lo,c,t,e,hxs,hfx,r1,twopk;
|
||||
union {float f; uint32_t i;} u = {x};
|
||||
uint32_t hx = u.i & 0x7fffffff;
|
||||
int k, sign = u.i >> 31;
|
||||
|
||||
/* filter out huge and non-finite argument */
|
||||
if (hx >= 0x4195b844) { /* if |x|>=27*ln2 */
|
||||
if (hx > 0x7f800000) /* NaN */
|
||||
return x;
|
||||
if (sign)
|
||||
return -1;
|
||||
if (x > o_threshold) {
|
||||
x *= 0x1p127f;
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
/* argument reduction */
|
||||
if (hx > 0x3eb17218) { /* if |x| > 0.5 ln2 */
|
||||
if (hx < 0x3F851592) { /* and |x| < 1.5 ln2 */
|
||||
if (!sign) {
|
||||
hi = x - ln2_hi;
|
||||
lo = ln2_lo;
|
||||
k = 1;
|
||||
} else {
|
||||
hi = x + ln2_hi;
|
||||
lo = -ln2_lo;
|
||||
k = -1;
|
||||
}
|
||||
} else {
|
||||
k = invln2*x + (sign ? -0.5f : 0.5f);
|
||||
t = k;
|
||||
hi = x - t*ln2_hi; /* t*ln2_hi is exact here */
|
||||
lo = t*ln2_lo;
|
||||
}
|
||||
x = hi-lo;
|
||||
c = (hi-x)-lo;
|
||||
} else if (hx < 0x33000000) { /* when |x|<2**-25, return x */
|
||||
if (hx < 0x00800000)
|
||||
FORCE_EVAL(x*x);
|
||||
return x;
|
||||
} else
|
||||
k = 0;
|
||||
|
||||
/* x is now in primary range */
|
||||
hfx = 0.5f*x;
|
||||
hxs = x*hfx;
|
||||
r1 = 1.0f+hxs*(Q1+hxs*Q2);
|
||||
t = 3.0f - r1*hfx;
|
||||
e = hxs*((r1-t)/(6.0f - x*t));
|
||||
if (k == 0) /* c is 0 */
|
||||
return x - (x*e-hxs);
|
||||
e = x*(e-c) - c;
|
||||
e -= hxs;
|
||||
/* exp(x) ~ 2^k (x_reduced - e + 1) */
|
||||
if (k == -1)
|
||||
return 0.5f*(x-e) - 0.5f;
|
||||
if (k == 1) {
|
||||
if (x < -0.25f)
|
||||
return -2.0f*(e-(x+0.5f));
|
||||
return 1.0f + 2.0f*(x-e);
|
||||
}
|
||||
u.i = (0x7f+k)<<23; /* 2^k */
|
||||
twopk = u.f;
|
||||
if (k < 0 || k > 56) { /* suffice to return exp(x)-1 */
|
||||
y = x - e + 1.0f;
|
||||
if (k == 128)
|
||||
y = y*2.0f*0x1p127f;
|
||||
else
|
||||
y = y*twopk;
|
||||
return y - 1.0f;
|
||||
}
|
||||
u.i = (0x7f-k)<<23; /* 2^-k */
|
||||
if (k < 23)
|
||||
y = (x-e+(1-u.f))*twopk;
|
||||
else
|
||||
y = (x-(e+u.f)+1)*twopk;
|
||||
return y;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
// __expo2f from musl-0.9.15
|
||||
|
||||
/* k is such that k*ln2 has minimal relative error and x - kln2 > log(FLT_MIN) */
|
||||
static const int k = 235;
|
||||
static const float kln2 = 0x1.45c778p+7f;
|
||||
|
||||
/* expf(x)/2 for x >= log(FLT_MAX), slightly better than 0.5f*expf(x/2)*expf(x/2) */
|
||||
float __expo2f(float x)
|
||||
{
|
||||
float scale;
|
||||
|
||||
/* note that k is odd and scale*scale overflows */
|
||||
SET_FLOAT_WORD(scale, (uint32_t)(0x7f + k/2) << 23);
|
||||
/* exp(x - k ln2) * 2**(k-1) */
|
||||
return expf(x - kln2) * scale * scale;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
// coshf from musl-0.9.15
|
||||
|
||||
float coshf(float x)
|
||||
{
|
||||
union {float f; uint32_t i;} u = {.f = x};
|
||||
uint32_t w;
|
||||
float t;
|
||||
|
||||
/* |x| */
|
||||
u.i &= 0x7fffffff;
|
||||
x = u.f;
|
||||
w = u.i;
|
||||
|
||||
/* |x| < log(2) */
|
||||
if (w < 0x3f317217) {
|
||||
if (w < 0x3f800000 - (12<<23)) {
|
||||
FORCE_EVAL(x + 0x1p120f);
|
||||
return 1;
|
||||
}
|
||||
t = expm1f(x);
|
||||
return 1 + t*t/(2*(1+t));
|
||||
}
|
||||
|
||||
/* |x| < log(FLT_MAX) */
|
||||
if (w < 0x42b17217) {
|
||||
t = expf(x);
|
||||
return 0.5f*(t + 1/t);
|
||||
}
|
||||
|
||||
/* |x| > log(FLT_MAX) or nan */
|
||||
t = __expo2f(x);
|
||||
return t;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
// sinhf from musl-0.9.15
|
||||
|
||||
float sinhf(float x)
|
||||
{
|
||||
union {float f; uint32_t i;} u = {.f = x};
|
||||
uint32_t w;
|
||||
float t, h, absx;
|
||||
|
||||
h = 0.5;
|
||||
if (u.i >> 31)
|
||||
h = -h;
|
||||
/* |x| */
|
||||
u.i &= 0x7fffffff;
|
||||
absx = u.f;
|
||||
w = u.i;
|
||||
|
||||
/* |x| < log(FLT_MAX) */
|
||||
if (w < 0x42b17217) {
|
||||
t = expm1f(absx);
|
||||
if (w < 0x3f800000) {
|
||||
if (w < 0x3f800000 - (12<<23))
|
||||
return x;
|
||||
return h*(2*t - t*t/(t+1));
|
||||
}
|
||||
return h*(t + t/(t+1));
|
||||
}
|
||||
|
||||
/* |x| > logf(FLT_MAX) or nan */
|
||||
t = 2*h*__expo2f(absx);
|
||||
return t;
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
#include <stdint.h>
|
||||
|
||||
// options to control how Micro Python is built
|
||||
|
||||
#define MICROPY_EMIT_THUMB (1)
|
||||
#define MICROPY_EMIT_INLINE_THUMB (1)
|
||||
#define MICROPY_ENABLE_GC (1)
|
||||
#define MICROPY_ENABLE_REPL_HELPERS (1)
|
||||
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ)
|
||||
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT)
|
||||
#define MICROPY_PATH_MAX (128)
|
||||
/* Enable FatFS LFNs
|
||||
0: Disable LFN feature.
|
||||
1: Enable LFN with static working buffer on the BSS. Always NOT reentrant.
|
||||
2: Enable LFN with dynamic working buffer on the STACK.
|
||||
3: Enable LFN with dynamic working buffer on the HEAP.
|
||||
*/
|
||||
#define MICROPY_ENABLE_LFN (0)
|
||||
#define MICROPY_LFN_CODE_PAGE (1) /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */
|
||||
|
||||
// type definitions for the specific machine
|
||||
|
||||
#define BYTES_PER_WORD (4)
|
||||
|
||||
#define UINT_FMT "%lu"
|
||||
#define INT_FMT "%ld"
|
||||
|
||||
typedef int32_t machine_int_t; // must be pointer size
|
||||
typedef uint32_t machine_uint_t; // must be pointer size
|
||||
typedef void *machine_ptr_t; // must be of pointer size
|
||||
typedef const void *machine_const_ptr_t; // must be of pointer size
|
||||
|
||||
// There is no classical C heap in bare-metal ports, only Python
|
||||
// garbage-collected heap. For completeness, emulate C heap via
|
||||
// GC heap. Note that MicroPython core never uses malloc() and friends,
|
||||
// so these defines are mostly to help extension module writers.
|
||||
#define malloc gc_alloc
|
||||
#define free gc_free
|
||||
#define realloc gc_realloc
|
||||
|
||||
// board specific definitions
|
||||
|
||||
#include "mpconfigboard.h"
|
||||
|
||||
#define STM32F40_41xxx
|
||||
#define USE_STDPERIPH_DRIVER
|
||||
#if !defined(HSE_VALUE)
|
||||
#define HSE_VALUE (8000000)
|
||||
#endif
|
||||
#define USE_DEVICE_MODE
|
||||
//#define USE_HOST_MODE
|
|
@ -0,0 +1,78 @@
|
|||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stm32f4xx_hal.h>
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
|
||||
#include "pin.h"
|
||||
|
||||
#if 0
|
||||
void pin_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pin_obj_t *self = self_in;
|
||||
print(env, "<Pin %s>", self->name);
|
||||
}
|
||||
|
||||
mp_obj_t pin_obj_name(mp_obj_t self_in) {
|
||||
pin_obj_t *self = self_in;
|
||||
return MP_OBJ_NEW_QSTR(qstr_from_str(self->name));
|
||||
}
|
||||
|
||||
mp_obj_t pin_obj_port(mp_obj_t self_in) {
|
||||
pin_obj_t *self = self_in;
|
||||
return MP_OBJ_NEW_SMALL_INT((mp_small_int_t)self->port);
|
||||
}
|
||||
|
||||
mp_obj_t pin_obj_pin(mp_obj_t self_in) {
|
||||
pin_obj_t *self = self_in;
|
||||
return MP_OBJ_NEW_SMALL_INT((mp_small_int_t)self->pin);
|
||||
}
|
||||
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(pin_obj_name_obj, pin_obj_name);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(pin_obj_port_obj, pin_obj_port);
|
||||
static MP_DEFINE_CONST_FUN_OBJ_1(pin_obj_pin_obj, pin_obj_pin);
|
||||
|
||||
static const mp_method_t pin_methods[] = {
|
||||
{ "name", &pin_obj_name_obj },
|
||||
{ "port", &pin_obj_port_obj },
|
||||
{ "pin", &pin_obj_pin_obj },
|
||||
{ NULL, NULL },
|
||||
};
|
||||
#endif
|
||||
|
||||
const mp_obj_type_t pin_obj_type = {
|
||||
#if 0
|
||||
{ &mp_type_type },
|
||||
#else
|
||||
{ NULL },
|
||||
#endif
|
||||
.name = MP_QSTR_Pin,
|
||||
#if 0
|
||||
.print = pin_obj_print,
|
||||
.methods = pin_methods,
|
||||
#endif
|
||||
};
|
||||
|
||||
#if 0
|
||||
void pin_af_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pin_af_obj_t *self = self_in;
|
||||
print(env, "<Pin AF %d fn:%d unit:%d typ:%d>", self->idx, self->fn,
|
||||
self->unit, self->type);
|
||||
}
|
||||
#endif
|
||||
|
||||
const mp_obj_type_t pin_af_obj_type = {
|
||||
#if 0
|
||||
{ &mp_type_type },
|
||||
#else
|
||||
{ NULL },
|
||||
#endif
|
||||
.name = MP_QSTR_PinAF,
|
||||
#if 0
|
||||
.print = pin_af_obj_print,
|
||||
#endif
|
||||
};
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
enum {
|
||||
PORT_A,
|
||||
PORT_B,
|
||||
PORT_C,
|
||||
PORT_D,
|
||||
PORT_E,
|
||||
PORT_F,
|
||||
PORT_G,
|
||||
PORT_H,
|
||||
PORT_I,
|
||||
PORT_J,
|
||||
};
|
||||
|
||||
enum {
|
||||
AF_FN_TIM,
|
||||
AF_FN_I2C,
|
||||
AF_FN_USART,
|
||||
AF_FN_UART = AF_FN_USART,
|
||||
AF_FN_SPI
|
||||
};
|
||||
|
||||
enum {
|
||||
AF_PIN_TYPE_TIM_CH1 = 0,
|
||||
AF_PIN_TYPE_TIM_CH2,
|
||||
AF_PIN_TYPE_TIM_CH3,
|
||||
AF_PIN_TYPE_TIM_CH4,
|
||||
AF_PIN_TYPE_TIM_CH1N,
|
||||
AF_PIN_TYPE_TIM_CH2N,
|
||||
AF_PIN_TYPE_TIM_CH3N,
|
||||
AF_PIN_TYPE_TIM_CH1_ETR,
|
||||
AF_PIN_TYPE_TIM_ETR,
|
||||
AF_PIN_TYPE_TIM_BKIN,
|
||||
|
||||
AF_PIN_TYPE_I2C_SDA = 0,
|
||||
AF_PIN_TYPE_I2C_SCL,
|
||||
|
||||
AF_PIN_TYPE_USART_TX = 0,
|
||||
AF_PIN_TYPE_USART_RX,
|
||||
AF_PIN_TYPE_USART_CTS,
|
||||
AF_PIN_TYPE_USART_RTS,
|
||||
AF_PIN_TYPE_USART_CK,
|
||||
AF_PIN_TYPE_UART_TX = AF_PIN_TYPE_USART_TX,
|
||||
AF_PIN_TYPE_UART_RX = AF_PIN_TYPE_USART_RX,
|
||||
AF_PIN_TYPE_UART_CTS = AF_PIN_TYPE_USART_CTS,
|
||||
AF_PIN_TYPE_UART_RTS = AF_PIN_TYPE_USART_RTS,
|
||||
|
||||
AF_PIN_TYPE_SPI_MOSI = 0,
|
||||
AF_PIN_TYPE_SPI_MISO,
|
||||
AF_PIN_TYPE_SPI_SCK,
|
||||
AF_PIN_TYPE_SPI_NSS,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
uint8_t idx;
|
||||
uint8_t fn;
|
||||
uint8_t unit;
|
||||
uint8_t type;
|
||||
|
||||
union {
|
||||
void *reg;
|
||||
TIM_TypeDef *TIM;
|
||||
I2C_TypeDef *I2C;
|
||||
USART_TypeDef *USART;
|
||||
USART_TypeDef *UART;
|
||||
SPI_TypeDef *SPI;
|
||||
};
|
||||
} pin_af_obj_t;
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
const char *name;
|
||||
uint16_t port : 4;
|
||||
uint16_t pin : 4;
|
||||
uint16_t num_af : 4;
|
||||
uint16_t pin_mask;
|
||||
GPIO_TypeDef *gpio;
|
||||
const pin_af_obj_t *af;
|
||||
} pin_obj_t;
|
||||
|
||||
extern const mp_obj_type_t pin_obj_type;
|
||||
extern const mp_obj_type_t pin_af_obj_type;
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
const pin_obj_t *pin;
|
||||