Updated teensy to build.

Refactored some stmhal files which are shared with teensy.
crypto-aes
Dave Hylands 9 years ago
parent 2547928148
commit 4f1b7fec9f

@ -97,4 +97,10 @@ print-cfg:
$(ECHO) "OBJ = $(OBJ)"
.PHONY: print-cfg
print-def:
@$(ECHO) "The following defines are built into the $(CC) compiler"
touch __empty__.c
@$(CC) -E -Wp,-dM __empty__.c
@$(RM) -f __empty__.c
-include $(OBJ:.o=.P)

@ -25,8 +25,7 @@
*/
#include <stdio.h>
#include <stm32f4xx_hal.h>
#include <stdint.h>
#include "misc.h"
#include "mpconfig.h"
@ -35,6 +34,8 @@
#include "gc.h"
#include "gccollect.h"
#include HAL_H
machine_uint_t gc_helper_get_regs_and_sp(machine_uint_t *regs);
// obsolete

@ -104,3 +104,11 @@ typedef const void *machine_const_ptr_t; // must be of pointer size
// We need to provide a declaration/definition of alloca()
#include <alloca.h>
#define HAL_H <stm32f4xx_hal.h>
#define PIN_DEFS_PORT_H "pin_defs_stmhal.h"
#define GPIO_read_pin(gpio, pin) (((gpio)->IDR >> (pin)) & 1)
#define GPIO_set_pin(gpio, pin_mask) (((gpio)->BSRRL) = (pin_mask))
#define GPIO_clear_pin(gpio, pin_mask) (((gpio)->BSRRH) = (pin_mask))

@ -28,9 +28,8 @@
#include <stdint.h>
#include <string.h>
#include "stm32f4xx_hal.h"
#include "mpconfig.h"
#include HAL_H
#include "nlr.h"
#include "misc.h"
#include "qstr.h"
@ -310,13 +309,13 @@ STATIC mp_obj_t pin_value(uint n_args, mp_obj_t *args) {
pin_obj_t *self = args[0];
if (n_args == 1) {
// get pin
return MP_OBJ_NEW_SMALL_INT((self->gpio->IDR >> self->pin) & 1);
return MP_OBJ_NEW_SMALL_INT(GPIO_read_pin(self->gpio, self->pin));
} else {
// set pin
if (mp_obj_is_true(args[1])) {
self->gpio->BSRRL = self->pin_mask;
GPIO_set_pin(self->gpio, self->pin_mask);
} else {
self->gpio->BSRRH = self->pin_mask;
GPIO_clear_pin(self->gpio, self->pin_mask);
}
return mp_const_none;
}
@ -327,7 +326,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_value_obj, 1, 2, pin_value);
/// Set the pin to a low logic level.
STATIC mp_obj_t pin_low(mp_obj_t self_in) {
pin_obj_t *self = self_in;
self->gpio->BSRRH = self->pin_mask;
GPIO_clear_pin(self->gpio, self->pin_mask);;
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_low_obj, pin_low);
@ -336,7 +335,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_low_obj, pin_low);
/// Set the pin to a high logic level.
STATIC mp_obj_t pin_high(mp_obj_t self_in) {
pin_obj_t *self = self_in;
self->gpio->BSRRL = self->pin_mask;
GPIO_set_pin(self->gpio, self->pin_mask);;
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_high_obj, pin_high);

@ -24,63 +24,10 @@
* THE SOFTWARE.
*/
enum {
PORT_A,
PORT_B,
PORT_C,
PORT_D,
PORT_E,
PORT_F,
PORT_G,
PORT_H,
PORT_I,
PORT_J,
};
// This file requires pin_defs_xxx.h (which has port specific enums and
// defines, so we include it here. It should never be included directly
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,
};
enum {
PIN_ADC1 = (1 << 0),
PIN_ADC2 = (1 << 1),
PIN_ADC3 = (1 << 2),
};
#include PIN_DEFS_PORT_H
typedef struct {
mp_obj_base_t base;
@ -91,24 +38,21 @@ typedef struct {
union {
void *reg;
TIM_TypeDef *TIM;
I2C_TypeDef *I2C;
USART_TypeDef *USART;
USART_TypeDef *UART;
SPI_TypeDef *SPI;
PIN_DEFS_PORT_AF_UNION
};
} 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 adc_channel : 4;
uint16_t adc_num : 3; // 1 bit per ADC
uint16_t pin_mask;
GPIO_TypeDef *gpio;
uint32_t port : 4;
uint32_t pin : 5; // Some ARM processors use 32 bits/PORT
uint32_t num_af : 4;
uint32_t adc_channel : 5; // Some ARM processors use 32 bits/PORT
uint32_t adc_num : 3; // 1 bit per ADC
uint32_t pin_mask;
pin_gpio_t *gpio;
const pin_af_obj_t *af;
} pin_obj_t;

@ -0,0 +1,96 @@
/*
* This file is part of the Micro Python project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2013, 2014 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
// This file contains pin definitions that are specific to the stmhal port.
// This file should only ever be #included by pin.h and not directly.
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,
};
enum {
PIN_ADC1 = (1 << 0),
PIN_ADC2 = (1 << 1),
PIN_ADC3 = (1 << 2),
};
#define PIN_DEFS_PORT_AF_UNION \
TIM_TypeDef *TIM; \
I2C_TypeDef *I2C; \
USART_TypeDef *USART; \
USART_TypeDef *UART; \
SPI_TypeDef *SPI;
typedef GPIO_TypeDef pin_gpio_t;

@ -28,10 +28,11 @@
#include <stdint.h>
#include <string.h>
#include "stm32f4xx_hal.h"
#include "misc.h"
#include "mpconfig.h"
#include HAL_H
#include "qstr.h"
#include "obj.h"
#include "runtime.h"

@ -25,8 +25,7 @@
*/
#include <stdio.h>
#include <stm32f4xx_hal.h>
#include <stdint.h>
#include "misc.h"
#include "mpconfig.h"
@ -38,6 +37,8 @@
#include "usb.h"
#include "uart.h"
#include HAL_H
// TODO make stdin, stdout and stderr writable objects so they can
// be changed by Python code.

@ -26,8 +26,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <stm32f4xx_hal.h>
#include <stdint.h>
#include "mpconfig.h"
#include "nlr.h"
@ -50,6 +49,8 @@
#include "usb.h"
#include "genhdr/py-version.h"
#include HAL_H
pyexec_mode_kind_t pyexec_mode_kind = PYEXEC_MODE_FRIENDLY_REPL;
STATIC bool repl_display_debugging_info = 0;

@ -25,10 +25,9 @@
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stm32f4xx_hal.h>
#include "misc.h"
#include "mpconfig.h"
#include "qstr.h"
@ -38,6 +37,8 @@
#include "readline.h"
#include "usb.h"
#include HAL_H
#if 0 // print debugging info
#define DEBUG_PRINT (1)
#define DEBUG_printf printf

@ -20,12 +20,15 @@ CFLAGS_CORTEX_M4 = -mthumb -mtune=cortex-m4 -mcpu=cortex-m4 -fsingle-precision-c
INC = -I.
INC += -I$(PY_SRC)
INC += -I../stmhal
INC += -I$(BUILD)
INC += -I$(CORE_PATH)
CFLAGS = $(INC) -Wall -ansi -std=gnu99 $(CFLAGS_CORTEX_M4)
LDFLAGS = -nostdlib -T mk20dx256.ld
LIBS = -L $(COMPILER_PATH)/../lib/gcc/arm-none-eabi/4.7.2/thumb2 -lgcc
LIBS = -L $(COMPILER_PATH)/../arm-none-eabi/lib/thumb2 -lm
LIBS += -L $(COMPILER_PATH)/../arm-none-eabi/lib/thumb2 -lc
LIBS += -L $(COMPILER_PATH)/../lib/gcc/arm-none-eabi/4.7.2/thumb2 -lgcc
#Debugging/Optimization
ifdef DEBUG
@ -35,23 +38,32 @@ CFLAGS += -Os #-DNDEBUG
endif
SRC_C = \
hal_gpio.c \
help.c \
import.c \
main.c \
lcd.c \
led.c \
lexerfatfs.c \
lexermemzip.c \
memzip.c \
servo.c \
usart.c \
modpyb.c \
teensy_hal.c \
uart.c \
usb.c \
STM_SRC_C = $(addprefix stm/,\
malloc0.c \
STM_SRC_C = $(addprefix stmhal/,\
gccollect.c \
input.c \
pin.c \
pin_named_pins.c \
printf.c \
pyexec.c \
pybstdio.c \
readline.c \
string0.c \
)
STM_SRC_S = $(addprefix stm/,\
STM_SRC_S = $(addprefix stmhal/,\
gchelper.s \
)
@ -66,9 +78,7 @@ SRC_TEENSY = \
yield.c \
OBJ = $(PY_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o) $(STM_SRC_C:.c=.o) $(STM_SRC_S:.s=.o) $(SRC_TEENSY:.c=.o))
#LIB = -lreadline
# the following is needed for BSD
#LIB += -ltermcap
OBJ += $(BUILD)/pins_gen.o
all: hex
hex: $(BUILD)/micropython-mz.hex
@ -84,7 +94,7 @@ reboot:
upload: post_compile reboot
$(BUILD)/micropython.elf: $(OBJ)
$(ECHO) "LINK $<"
$(ECHO) "LINK $@"
$(Q)$(CC) $(LDFLAGS) -o "$@" -Wl,-Map,$(@:.elf=.map) $(OBJ) $(LIBS)
$(Q)$(SIZE) $@
@ -103,4 +113,31 @@ $(BUILD)/%.hex: $(BUILD)/%.elf
$(BUILD)/%.o: $(CORE_PATH)/%.c
$(call compile_c)
MAKE_PINS = make-pins.py
BOARD_PINS = teensy-pins.csv
AF_FILE = mk20dx256-af.csv
PREFIX_FILE = mk20dx256-prefix.c
GEN_PINS_SRC = $(BUILD)/pins_gen.c
GEN_PINS_HDR = $(HEADER_BUILD)/pins.h
# Making OBJ use an order-only depenedency on the generated pins.h file
# has the side effect of making the pins.h file before we actually compile
# 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): | $(HEADER_BUILD)/pins.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
$(BUILD)/%_gen.c $(HEADER_BUILD)/%.h: teensy-%.csv $(MAKE_PINS) $(AF_FILE) $(PREFIX_FILE)
$(ECHO) "Create $@"
$(Q)$(PYTHON) $(MAKE_PINS) --board $(BOARD_PINS) --af $(AF_FILE) --prefix $(PREFIX_FILE) --hdr $(GEN_PINS_HDR) > $(GEN_PINS_SRC)
$(BUILD)/pins_gen.o: $(BUILD)/pins_gen.c
$(call compile_c)
$(BUILD)/%.pp: $(BUILD)/%.c
$(ECHO) "PreProcess $<"
$(Q)$(CC) $(CFLAGS) -E -Wp,-C,-dD,-dI -o $@ $<
include ../py/mkrules.mk

@ -0,0 +1,115 @@
#include <stdint.h>
#include <mk20dx128.h>
#include "teensy_hal.h"
#define GPIO_NUMBER 32
void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
{
/* Check the parameters */
assert_param(IS_GPIO_PIN(GPIO_Init->Pin));
assert_param(IS_GPIO_MODE(GPIO_Init->Mode));
assert_param(IS_GPIO_PULL(GPIO_Init->Pull));
/* Configure the port pins */
for (uint32_t position = 0; position < GPIO_NUMBER; position++) {
uint32_t bitmask = 1 << position;
if ((GPIO_Init->Pin & bitmask) == 0) {
continue;
}
volatile uint32_t *port_pcr = GPIO_PIN_TO_PORT_PCR(GPIOx, position);
/*--------------------- GPIO Mode Configuration ------------------------*/
/* In case of Alternate function mode selection */
if ((GPIO_Init->Mode == GPIO_MODE_AF_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_OD)) {
/* Check the Alternate function parameter */
assert_param(IS_GPIO_AF(GPIO_Init->Alternate));
/* Configure Alternate function mapped with the current IO */
*port_pcr &= ~PORT_PCR_MUX_MASK;
*port_pcr |= PORT_PCR_MUX(GPIO_Init->Alternate);
}
/* Configure IO Direction mode (Input, Output, Alternate or Analog) */
if (GPIO_Init->Mode == GPIO_MODE_INPUT || GPIO_Init->Mode == GPIO_MODE_ANALOG) {
GPIOx->PDDR &= ~bitmask;
} else {
GPIOx->PDDR |= bitmask;
}
/* In case of Output or Alternate function mode selection */
if ((GPIO_Init->Mode == GPIO_MODE_OUTPUT_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_PP) ||
(GPIO_Init->Mode == GPIO_MODE_OUTPUT_OD) || (GPIO_Init->Mode == GPIO_MODE_AF_OD)) {
/* Check the Speed parameter */
assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
/* Configure the IO Speed */
if (GPIO_Init->Speed > GPIO_SPEED_MEDIUM) {
*port_pcr &= ~PORT_PCR_SRE;
} else {
*port_pcr |= PORT_PCR_SRE;
}
/* Configure the IO Output Type */
if (GPIO_Init->Mode & GPIO_OUTPUT_TYPE) {
*port_pcr |= PORT_PCR_ODE;
} else {
*port_pcr &= ~PORT_PCR_ODE;
}
}
/* Activate the Pull-up or Pull down resistor for the current IO */
if (GPIO_Init->Pull == GPIO_NOPULL) {
*port_pcr &= ~PORT_PCR_PE;
} else {
*port_pcr |= PORT_PCR_PE;
if (GPIO_Init->Pull == GPIO_PULLDOWN) {
*port_pcr &= ~PORT_PCR_PS;
} else {
*port_pcr |= PORT_PCR_PS;
}
}
#if 0
/*--------------------- EXTI Mode Configuration ------------------------*/
/* Configure the External Interrupt or event for the current IO */
if((GPIO_Init->Mode & EXTI_MODE) == EXTI_MODE)
{
/* Enable SYSCFG Clock */
__SYSCFG_CLK_ENABLE();
temp = ((uint32_t)0x0F) << (4 * (position & 0x03));
SYSCFG->EXTICR[position >> 2] &= ~temp;
SYSCFG->EXTICR[position >> 2] |= ((uint32_t)(__HAL_GET_GPIO_SOURCE(GPIOx)) << (4 * (position & 0x03)));
/* Clear EXTI line configuration */
EXTI->IMR &= ~((uint32_t)iocurrent);
EXTI->EMR &= ~((uint32_t)iocurrent);
if((GPIO_Init->Mode & GPIO_MODE_IT) == GPIO_MODE_IT)
{
EXTI->IMR |= iocurrent;
}
if((GPIO_Init->Mode & GPIO_MODE_EVT) == GPIO_MODE_EVT)
{
EXTI->EMR |= iocurrent;
}
/* Clear Rising Falling edge configuration */
EXTI->RTSR &= ~((uint32_t)iocurrent);
EXTI->FTSR &= ~((uint32_t)iocurrent);
if((GPIO_Init->Mode & RISING_EDGE) == RISING_EDGE)
{
EXTI->RTSR |= iocurrent;
}
if((GPIO_Init->Mode & FALLING_EDGE) == FALLING_EDGE)
{
EXTI->FTSR |= iocurrent;
}
}
#endif
}
}

@ -0,0 +1,123 @@
/*
* This file is part of the Micro Python project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2013, 2014 Damien P. George
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <stdio.h>
#include "mpconfig.h"
#include "nlr.h"
#include "misc.h"
#include "qstr.h"
#include "obj.h"
STATIC const char *help_text =
"Welcome to Micro Python!\n"
"\n"
"For online help please visit http://micropython.org/help/.\n"
"\n"
"Quick overview of commands for the board:\n"
" pyb.info() -- print some general information\n"
" pyb.gc() -- run the garbage collector\n"
" pyb.delay(n) -- wait for n milliseconds\n"
" pyb.Switch() -- create a switch object\n"
" Switch methods: (), callback(f)\n"
" pyb.LED(n) -- create an LED object for LED n (n=1,2,3,4)\n"
" LED methods: on(), off(), toggle(), intensity(<n>)\n"
" pyb.Pin(pin) -- get a pin, eg pyb.Pin('X1')\n"
" pyb.Pin(pin, m, [p]) -- get a pin and configure it for IO mode m, pull mode p\n"
" Pin methods: init(..), value([v]), high(), low()\n"
" pyb.ExtInt(pin, m, p, callback) -- create an external interrupt object\n"
" pyb.ADC(pin) -- make an analog object from a pin\n"
" ADC methods: read(), read_timed(buf, freq)\n"
" pyb.DAC(port) -- make a DAC object\n"
" DAC methods: triangle(freq), write(n), write_timed(buf, freq)\n"
" pyb.RTC() -- make an RTC object; methods: datetime([val])\n"
" pyb.rng() -- get a 30-bit hardware random number\n"
" pyb.Servo(n) -- create Servo object for servo n (n=1,2,3,4)\n"
" Servo methods: calibration(..), angle([x, [t]]), speed([x, [t]])\n"
" pyb.Accel() -- create an Accelerometer object\n"
" Accelerometer methods: x(), y(), z(), tilt(), filtered_xyz()\n"
"\n"
"Pins are numbered X1-X12, X17-X22, Y1-Y12, or by their MCU name\n"
"Pin IO modes are: pyb.Pin.IN, pyb.Pin.OUT_PP, pyb.Pin.OUT_OD\n"
"Pin pull modes are: pyb.Pin.PULL_NONE, pyb.Pin.PULL_UP, pyb.Pin.PULL_DOWN\n"
"Additional serial bus objects: pyb.I2C(n), pyb.SPI(n), pyb.UART(n)\n"
"\n"
"Control commands:\n"
" CTRL-A -- on a blank line, enter raw REPL mode\n"
" CTRL-B -- on a blank line, enter normal REPL mode\n"
" CTRL-C -- interrupt a running program\n"
" CTRL-D -- on a blank line, do a soft reset of the board\n"
"\n"
"For further help on a specific object, type help(obj)\n"
;
STATIC void pyb_help_print_info_about_object(mp_obj_t name_o, mp_obj_t value) {
printf(" ");
mp_obj_print(name_o, PRINT_STR);
printf(" -- ");
mp_obj_print(value, PRINT_STR);
printf("\n");
}
STATIC mp_obj_t pyb_help(uint n_args, const mp_obj_t *args) {
if (n_args == 0) {
// print a general help message
printf("%s", help_text);
} else {
// try to print something sensible about the given object
printf("object ");
mp_obj_print(args[0], PRINT_STR);
printf(" is of type %s\n", mp_obj_get_type_str(args[0]));
mp_map_t *map = NULL;
if (MP_OBJ_IS_TYPE(args[0], &mp_type_module)) {
map = mp_obj_dict_get_map(mp_obj_module_get_globals(args[0]));
} else {
mp_obj_type_t *type;
if (MP_OBJ_IS_TYPE(args[0], &mp_type_type)) {
type = args[0];
} else {
type = mp_obj_get_type(args[0]);
}
if (type->locals_dict != MP_OBJ_NULL && MP_OBJ_IS_TYPE(type->locals_dict, &mp_type_dict)) {
map = mp_obj_dict_get_map(type->locals_dict);
}
}
if (map != NULL) {
for (uint i = 0; i < map->alloc; i++) {
if (map->table[i].key != MP_OBJ_NULL) {
pyb_help_print_info_about_object(map->table[i].key, map->table[i].value);
}
}
}
}
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_help_obj, 0, 1, pyb_help);

@ -0,0 +1,22 @@
#include <stdio.h>
#include <stdint.h>
#include "misc.h"
#include "mpconfig.h"
#include "qstr.h"
#include "lexer.h"
#include "memzip.h"
mp_import_stat_t mp_import_stat(const char *path) {
MEMZIP_FILE_INFO info;
if (memzip_stat(path, &info) != MZ_OK) {
return MP_IMPORT_STAT_NO_EXIST;
}
if (info.is_dir) {
return MP_IMPORT_STAT_DIR;
}
return MP_IMPORT_STAT_FILE;
}

@ -1,5 +1,10 @@
#include "mpconfig.h"
#include "nlr.h"
#include "misc.h"
#include "../stm/lcd.h"
#include "qstr.h"
#include "parse.h"
#include "obj.h"
#include "../stmhal/lcd.h"
void lcd_init(void) {
}

@ -1,53 +1,115 @@
#include <stdio.h>
#include "misc.h"
#include "Arduino.h"
#include "mpconfig.h"
#include HAL_H
#include "nlr.h"
#include "misc.h"
#include "qstr.h"
#include "obj.h"
#include "runtime.h"
#include "led.h"
#include "pin.h"
#include "genhdr/pins.h"
#include "Arduino.h"
typedef struct _pyb_led_obj_t {
mp_obj_base_t base;
machine_uint_t led_id;
const pin_obj_t *led_pin;
} pyb_led_obj_t;
STATIC const pyb_led_obj_t pyb_led_obj[] = {
{{&pyb_led_type}, 1, &MICROPY_HW_LED1},
#if defined(MICROPY_HW_LED2)
{{&pyb_led_type}, 2, &MICROPY_HW_LED2},
#if defined(MICROPY_HW_LED3)
{{&pyb_led_type}, 3, &MICROPY_HW_LED3},
#if defined(MICROPY_HW_LED4)
{{&pyb_led_type}, 4, &MICROPY_HW_LED4},
#endif
#endif
#endif
};
#define NUM_LEDS ARRAY_SIZE(pyb_led_obj)
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 = MICROPY_HW_LED_OTYPE;
GPIO_InitStructure.Pull = GPIO_NOPULL;
/* Turn off LEDs and initialize */
for (int led = 0; led < NUM_LEDS; led++) {
const pin_obj_t *led_pin = pyb_led_obj[led].led_pin;
MICROPY_HW_LED_OFF(led_pin);
GPIO_InitStructure.Pin = led_pin->pin_mask;
HAL_GPIO_Init(led_pin->gpio, &GPIO_InitStructure);
}
}
void led_state(pyb_led_t led, int state) {
uint8_t pin;
if (led == 0) {
pin = LED_BUILTIN;
} else {
if (led < 1 || led > NUM_LEDS) {
return;
}
digitalWrite(pin, state);
const pin_obj_t *led_pin = pyb_led_obj[led - 1].led_pin;
//printf("led_state(%d,%d)\n", led, state);
if (state == 0) {
// turn LED off
MICROPY_HW_LED_OFF(led_pin);
} else {
// turn LED on
MICROPY_HW_LED_ON(led_pin);
}
}
void led_toggle(pyb_led_t led) {
uint8_t pin;
if (led == 0) {
pin = LED_BUILTIN;
} else {
if (led < 1 || led > NUM_LEDS) {
return;
}
digitalWrite(pin, !digitalRead(pin));
const pin_obj_t *led_pin = pyb_led_obj[led - 1].led_pin;
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->PDOR & led_pin->pin_mask) {
// pin is high, make it low
gpio->PCOR = led_pin->pin_mask;
} else {
// pin is low, make it high
gpio->PSOR = led_pin->pin_mask;
}
}
/******************************************************************************/
/* 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;
(void)kind;
print(env, "<LED %lu>", self->led_id);
}
STATIC mp_obj_t led_obj_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
// check arguments
mp_arg_check_num(n_args, n_kw, 1, 1, false);
// get led number
machine_int_t led_id = mp_obj_get_int(args[0]);
// check led number
if (!(1 <= led_id && led_id <= NUM_LEDS)) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "LED %d does not exist", led_id));
}
// return static led object
return (mp_obj_t)&pyb_led_obj[led_id - 1];
}
mp_obj_t led_obj_on(mp_obj_t self_in) {
pyb_led_obj_t *self = self_in;
led_state(self->led_id, 1);
@ -60,25 +122,28 @@ mp_obj_t led_obj_off(mp_obj_t self_in) {
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);
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 const mp_method_t led_methods[] = {
{ "on", &led_obj_on_obj },
{ "off", &led_obj_off_obj },
{ NULL, NULL },
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_map_elem_t led_locals_dict_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_on), (mp_obj_t)&led_obj_on_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_off), (mp_obj_t)&led_obj_off_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_toggle), (mp_obj_t)&led_obj_toggle_obj },
};
static const mp_obj_type_t led_obj_type = {
STATIC MP_DEFINE_CONST_DICT(led_locals_dict, led_locals_dict_table);
const mp_obj_type_t pyb_led_type = {
{ &mp_type_type },
.name = MP_QSTR_Led,
.name = MP_QSTR_LED,
.print = led_obj_print,
.methods = led_methods,
.make_new = led_obj_make_new,
.locals_dict = (mp_obj_t)&led_locals_dict,
};
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;
}

@ -1,9 +1,9 @@
typedef enum {
PYB_LED_BUILTIN = 0,
PYB_LED_BUILTIN = 1,
} pyb_led_t;
void led_init(void);
void led_state(pyb_led_t led, int state);
void led_toggle(pyb_led_t led);
mp_obj_t pyb_Led(mp_obj_t led_id);
extern const mp_obj_type_t pyb_led_type;

@ -6,19 +6,10 @@
#include "qstr.h"
#include "lexer.h"
typedef int FIL;
#include "../stm/lexerfatfs.h"
#include "../stmhal/lexerfatfs.h"
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
printf("import not implemented\n");
return NULL;
}
mp_lexer_t *mp_import_open_file(qstr mod_name) {
printf("import not implemented\n");
return NULL;
}
mp_import_stat_t mp_import_stat(const char *path) {
// TODO implement me!
return MP_IMPORT_STAT_NO_EXIST;
}

@ -7,7 +7,7 @@
#include "lexer.h"
#include "memzip.h"
mp_lexer_t *mp_lexer_new_from_memzip_file(const char *filename)
mp_lexer_t *mp_lexer_new_from_file(const char *filename)
{
void *data;
size_t len;

@ -3,29 +3,32 @@
#include <string.h>
#include <stdlib.h>
#include "nlr.h"
#include "misc.h"
#include "mpconfig.h"
#include "qstr.h"
#include "nlr.h"
#include "lexer.h"
#include "lexermemzip.h"
#include "parse.h"
#include "obj.h"
#include "compile.h"
#include "runtime0.h"
#include "runtime.h"
#include "repl.h"
#include "gc.h"
#include "gccollect.h"
#include "pyexec.h"
#include "pybstdio.h"
#include "readline.h"
#include "Arduino.h"
#include HAL_H
#include "servo.h"
#include "usb.h"
#include "gc.h"
#include "led.h"
#include "build/py/py-version.h"
#include "Arduino.h"
//#include "pin.h"
extern uint32_t _heap_start;
bool do_file(const char *filename);
extern uint32_t _heap_start;
void flash_error(int n) {
for (int i = 0; i < n; i++) {
@ -36,25 +39,36 @@ void flash_error(int n) {
}
}
static const char *help_text =
"Welcome to Micro Python!\n\n"
"This is a *very* early version of Micro Python and has minimal functionality.\n\n"
"Specific commands for the board:\n"
" pyb.info() -- print some general information\n"
" pyb.gc() -- run the garbage collector\n"
" pyb.delay(<n>) -- wait for n milliseconds\n"
" pyb.Led(<n>) -- create Led object for LED n (n=0)\n"
" Led methods: on(), off()\n"
" pyb.gpio(<pin>) -- read gpio pin\n"
" pyb.gpio(<pin>, <val>) -- set gpio pin\n"
#if 0
" pyb.Servo(<n>) -- create Servo object for servo n (n=1,2,3,4)\n"
" Servo methods: angle(<x>)\n"
" pyb.switch() -- return True/False if switch pressed or not\n"
" pyb.accel() -- get accelerometer values\n"
" pyb.rand() -- get a 16-bit random number\n"
#endif
;
void __fatal_error(const char *msg) {
for (volatile uint delay = 0; delay < 10000000; delay++) {
}
led_state(1, 1);
led_state(2, 1);
led_state(3, 1);
led_state(4, 1);
stdout_tx_strn("\nFATAL ERROR:\n", 14);
stdout_tx_strn(msg, strlen(msg));
for (uint i = 0;;) {
led_toggle(((i++) & 3) + 1);
for (volatile uint delay = 0; delay < 10000000; delay++) {
}
if (i >= 16) {
// to conserve power
__WFI();
}
}
}
void nlr_jump_fail(void *val) {
printf("FATAL: uncaught exception %p\n", val);
__fatal_error("");
}
void __assert_func(const char *file, int line, const char *func, const char *expr) {
printf("Assertion failed: %s, file %s, line %d\n", expr, file, line);
__fatal_error("");
}
mp_obj_t pyb_analog_read(mp_obj_t pin_obj) {
uint pin = mp_obj_get_int(pin_obj);
@ -82,12 +96,7 @@ mp_obj_t pyb_analog_write_frequency(mp_obj_t pin_obj, mp_obj_t freq_obj) {
return mp_const_none;
}
// get some help about available functions
static mp_obj_t pyb_help(void) {
printf("%s", help_text);
return mp_const_none;
}
#if 0
// get lots of info about the board
static mp_obj_t pyb_info(void) {
// get and print unique id; 96 bits
@ -101,12 +110,6 @@ static mp_obj_t pyb_info(void) {
// to print info about memory
{
extern void *_sdata;
extern void *_edata;
extern void *_sbss;
extern void *_ebss;
extern void *_estack;
extern void *_etext;
printf("_sdata=%p\n", &_sdata);
printf("_edata=%p\n", &_edata);
printf("_sbss=%p\n", &_sbss);
@ -121,9 +124,9 @@ static mp_obj_t pyb_info(void) {
gc_info_t info;
gc_info(&info);
printf("GC:\n");
printf(" %lu total\n", info.total);
printf(" %lu used %lu free\n", info.used, info.free);
printf(" 1=%lu 2=%lu m=%lu\n", info.num_1block, info.num_2block, info.max_block);
printf(" %u total\n", info.total);
printf(" %u used %u free\n", info.used, info.free);
printf(" 1=%u 2=%u m=%u\n", info.num_1block, info.num_2block, info.max_block);
}
#if 0
@ -139,32 +142,15 @@ static mp_obj_t pyb_info(void) {
return mp_const_none;
}
#endif
#define RAM_START (0x1FFF8000) // fixed for chip
#define HEAP_END (0x20006000) // tunable
#define RAM_END (0x20008000) // fixed for chip
void gc_helper_get_regs_and_clean_stack(machine_uint_t *regs, machine_uint_t heap_end);
#if 0
void gc_collect(void) {
uint32_t start = micros();
gc_collect_start();
gc_collect_root((void**)RAM_START, (((uint32_t)&_heap_start) - RAM_START) / 4);
machine_uint_t regs[10];
gc_helper_get_regs_and_clean_stack(regs, HEAP_END);
gc_collect_root((void**)HEAP_END, (RAM_END - HEAP_END) / 4); // will trace regs since they now live in this function on the stack
gc_collect_end();
uint32_t ticks = micros() - start; // TODO implement a function that does this properly
if (0) {
// print GC info
gc_info_t info;
gc_info(&info);
printf("GC@%lu %luus\n", start, ticks);
printf(" %lu total\n", info.total);
printf(" %lu used %lu free\n", info.used, info.free);
printf(" 1=%lu 2=%lu m=%lu\n", info.num_1block, info.num_2block, info.max_block);
}
}
void gc_helper_get_regs_and_clean_stack(machine_uint_t *regs, machine_uint_t heap_end);
mp_obj_t pyb_gc(void) {
gc_collect();
@ -191,7 +177,7 @@ mp_obj_t pyb_gpio(int n_args, mp_obj_t *args) {
return mp_const_none;
pin_error:
nlr_raise(mp_obj_new_exception_msg_varg(MP_QSTR_ValueError, "pin %d does not exist", pin));
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "pin %d does not exist", pin));
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_gpio_obj, 1, 2, pyb_gpio);
@ -209,29 +195,41 @@ mp_obj_t pyb_hid_send_report(mp_obj_t arg) {
}
#endif
static mp_obj_t pyb_config_source_dir = MP_OBJ_NULL;
static mp_obj_t pyb_config_main = MP_OBJ_NULL;
#endif // 0
STATIC mp_obj_t pyb_config_source_dir = MP_OBJ_NULL;
STATIC mp_obj_t pyb_config_main = MP_OBJ_NULL;
STATIC mp_obj_t pyb_config_usb_mode = MP_OBJ_NULL;
mp_obj_t pyb_source_dir(mp_obj_t source_dir) {
if (MP_OBJ_IS_STR(source_dir)) {
pyb_config_source_dir = source_dir;
printf("source_dir = '");
mp_obj_print(source_dir, PRINT_STR);
printf("'\n");
}
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_1(pyb_source_dir_obj, pyb_source_dir);
mp_obj_t pyb_main(mp_obj_t main) {
if (MP_OBJ_IS_STR(main)) {
pyb_config_main = main;
printf("main = '");
mp_obj_print(main, PRINT_STR);
printf("'\n");
}
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_1(pyb_main_obj, pyb_main);
STATIC mp_obj_t pyb_usb_mode(mp_obj_t usb_mode) {
if (MP_OBJ_IS_STR(usb_mode)) {
pyb_config_usb_mode = usb_mode;
}
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_1(pyb_usb_mode_obj, pyb_usb_mode);
#if 0
mp_obj_t pyb_delay(mp_obj_t count) {
delay(mp_obj_get_int(count));
return mp_const_none;
@ -242,12 +240,9 @@ mp_obj_t pyb_led(mp_obj_t state) {
return state;
}
mp_obj_t pyb_run(mp_obj_t filename_obj) {
const char *filename = qstr_str(mp_obj_str_get_qstr(filename_obj));
do_file(filename);
return mp_const_none;
}
#endif // 0
#if 0
char *strdup(const char *str) {
uint32_t len = strlen(str);
char *s2 = m_new(char, len + 1);
@ -255,219 +250,31 @@ char *strdup(const char *str) {
s2[len] = 0;
return s2;
}
#define READLINE_HIST_SIZE (8)
static const char *readline_hist[READLINE_HIST_SIZE] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
void stdout_tx_str(const char *str) {
// usart_tx_str(str);
usb_vcp_send_str(str);
}
int readline(vstr_t *line, const char *prompt) {
stdout_tx_str(prompt);
int len = vstr_len(line);
int escape = 0;
int hist_num = 0;
for (;;) {
char c;
for (;;) {
if (usb_vcp_rx_any() != 0) {
c = usb_vcp_rx_get();
break;
#if 0
} else if (usart_rx_any()) {
c = usart_rx_char();
break;
#endif
}
//delay(1);
//if (storage_needs_flush()) {
// storage_flush();
//}
}
if (escape == 0) {
if (c == 4 && vstr_len(line) == len) {
return 0;
} else if (c == '\r') {
stdout_tx_str("\r\n");
for (int i = READLINE_HIST_SIZE - 1; i > 0; i--) {
readline_hist[i] = readline_hist[i - 1];
}
readline_hist[0] = strdup(vstr_str(line));
return 1;
} else if (c == 27) {
escape = true;
} else if (c == 127) {
if (vstr_len(line) > len) {
vstr_cut_tail(line, 1);
stdout_tx_str("\b \b");
}
} else if (32 <= c && c <= 126) {
vstr_add_char(line, c);
stdout_tx_str(line->buf + line->len - 1);
}
} else if (escape == 1) {
if (c == '[') {
escape = 2;
} else {
escape = 0;
}
} else if (escape == 2) {
escape = 0;
if (c == 'A') {
// up arrow
if (hist_num < READLINE_HIST_SIZE && readline_hist[hist_num] != NULL) {
// erase line
for (int i = line->len - len; i > 0; i--) {
stdout_tx_str("\b \b");
}
// set line to history
line->len = len;
vstr_add_str(line, readline_hist[hist_num]);
// draw line
stdout_tx_str(readline_hist[hist_num]);
// increase hist num
hist_num += 1;
}
}
} else {
escape = 0;
}
delay(10);
}
}
bool do_file(const char *filename) {
mp_lexer_t *lex = mp_lexer_new_from_memzip_file(filename);
if (lex == NULL) {
printf("could not open file '%s' for reading\n", filename);
return false;
}
mp_parse_error_kind_t parse_error_kind;
mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT, &parse_error_kind);
qstr source_name = mp_lexer_source_name(lex);
if (pn == MP_PARSE_NODE_NULL) {
// parse error
mp_parse_show_exception(lex, parse_error_kind);
mp_lexer_free(lex);
return false;
}
mp_lexer_free(lex);
mp_obj_t module_fun = mp_compile(pn, source_name, MP_EMIT_OPT_NONE, false);
mp_parse_node_free(pn);
if (module_fun == mp_const_none) {
return false;
}
nlr_buf_t nlr;
if (nlr_push(&nlr) == 0) {
mp_call_function_0(module_fun);
nlr_pop();
return true;
} else {
// uncaught exception
mp_obj_print((mp_obj_t)nlr.ret_val, PRINT_REPR);
printf("\n");
return false;
}
}
void do_repl(void) {
stdout_tx_str("Micro Python build " MICROPY_GIT_HASH " on " MICROPY_BUILD_DATE "; Teensy 3.1 version\n");
stdout_tx_str("Type \"help()\" for more information.\r\n");
vstr_t line;
vstr_init(&line, 32);
for (;;) {
vstr_reset(&line);
int ret = readline(&line, ">>> ");
if (ret == 0) {
// EOF
break;
}
if (vstr_len(&line) == 0) {
continue;
}
while (mp_repl_continue_with_input(vstr_str(&line))) {
vstr_add_char(&line, '\n');
int ret = readline(&line, "... ");
if (ret == 0) {
// stop entering compound statement
break;
}
}
mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, vstr_str(&line), vstr_len(&line), 0);
mp_parse_error_kind_t parse_error_kind;
mp_parse_node_t pn = mp_parse(lex, MP_PARSE_SINGLE_INPUT, &parse_error_kind);
qstr source_name = mp_lexer_source_name(lex);
if (pn == MP_PARSE_NODE_NULL) {
// parse error
mp_parse_show_exception(lex, parse_error_kind);
mp_lexer_free(lex);
} else {
// parse okay
mp_lexer_free(lex);
mp_obj_t module_fun = mp_compile(pn, source_name, MP_EMIT_OPT_NONE, true);
if (module_fun != mp_const_none) {
nlr_buf_t nlr;
uint32_t start = micros();
if (nlr_push(&nlr) == 0) {
mp_call_function_0(module_fun);
nlr_pop();
// optional timing
if (0) {
uint32_t ticks = micros() - start; // TODO implement a function that does this properly
printf("(took %lu ms)\n", ticks);
}
} else {