Merge branch 'dhylands-teensy-new'

This commit is contained in:
Damien George 2014-07-02 13:45:00 +01:00
commit f83debc716
42 changed files with 2533 additions and 601 deletions

View File

@ -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)

View File

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

View File

@ -105,3 +105,6 @@ 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 MICROPY_HAL_H "mphal.h"
#define MICROPY_PIN_DEFS_PORT_H "pin_defs_stmhal.h"

7
stmhal/mphal.h Normal file
View File

@ -0,0 +1,7 @@
// We use the ST Cube HAL library for most hardware peripherals
#include <stm32f4xx_hal.h>
// Basic GPIO functions
#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))

View File

@ -28,14 +28,13 @@
#include <stdint.h>
#include <string.h>
#include "stm32f4xx_hal.h"
#include "mpconfig.h"
#include "nlr.h"
#include "misc.h"
#include "qstr.h"
#include "obj.h"
#include "runtime.h"
#include MICROPY_HAL_H
#include "pin.h"
/// \moduleref pyb
@ -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);

View File

@ -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 MICROPY_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;

96
stmhal/pin_defs_stmhal.h Normal file
View File

@ -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;

View File

@ -28,13 +28,12 @@
#include <stdint.h>
#include <string.h>
#include "stm32f4xx_hal.h"
#include "mpconfig.h"
#include "misc.h"
#include "qstr.h"
#include "obj.h"
#include "runtime.h"
#include MICROPY_HAL_H
#include "pin.h"
STATIC void pin_named_pins_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {

View File

@ -25,8 +25,7 @@
*/
#include <stdio.h>
#include <stm32f4xx_hal.h>
#include <stdint.h>
#include "mpconfig.h"
#include "misc.h"
@ -34,6 +33,7 @@
#include "misc.h"
#include "obj.h"
#include "stream.h"
#include MICROPY_HAL_H
#include "pybstdio.h"
#include "usb.h"
#include "uart.h"

View File

@ -26,8 +26,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <stm32f4xx_hal.h>
#include <stdint.h>
#include "mpconfig.h"
#include "nlr.h"
@ -43,6 +42,7 @@
#include "repl.h"
#include "gc.h"
#include "gccollect.h"
#include MICROPY_HAL_H
#include "systick.h"
#include "pybstdio.h"
#include "readline.h"

View File

@ -25,15 +25,15 @@
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stm32f4xx_hal.h>
#include "mpconfig.h"
#include "misc.h"
#include "qstr.h"
#include "misc.h"
#include "obj.h"
#include MICROPY_HAL_H
#include "pybstdio.h"
#include "readline.h"
#include "usb.h"

View File

@ -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 -nostdlib $(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

115
teensy/hal_gpio.c Normal file
View File

@ -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
}
}

123
teensy/help.c Normal file
View File

@ -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);

22
teensy/import.c Normal file
View File

@ -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;
}

View 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) {
}

View File

@ -1,53 +1,114 @@
#include <stdio.h>
#include "misc.h"
#include "mpconfig.h"
#include "qstr.h"
#include "obj.h"
#include "led.h"
#include "Arduino.h"
#include "mpconfig.h"
#include "nlr.h"
#include "misc.h"
#include "qstr.h"
#include "obj.h"
#include "runtime.h"
#include "led.h"
#include MICROPY_HAL_H
#include "pin.h"
#include "genhdr/pins.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;
}
const pin_obj_t *led_pin = pyb_led_obj[led - 1].led_pin;
GPIO_TypeDef *gpio = led_pin->gpio;
digitalWrite(pin, !digitalRead(pin));
// 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 +121,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);
static const mp_method_t led_methods[] = {
{ "on", &led_obj_on_obj },
{ "off", &led_obj_off_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,
};
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_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_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 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,
.print = led_obj_print,
.make_new = led_obj_make_new,
.locals_dict = (mp_obj_t)&led_locals_dict,
};

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -3,30 +3,33 @@
#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 "servo.h"
#include "usb.h"
#include "gc.h"
#include "led.h"
#include "build/py/py-version.h"
#include "gccollect.h"
#include "pyexec.h"
#include "pybstdio.h"
#include "readline.h"
#include "Arduino.h"
#include MICROPY_HAL_H
#include "servo.h"
#include "usb.h"
#include "led.h"
//#include "pin.h"
extern uint32_t _heap_start;
bool do_file(const char *filename);
void flash_error(int n) {
for (int i = 0; i < n; i++) {
led_state(PYB_LED_BUILTIN, 1);
@ -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,33 +142,16 @@ 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
#if 0
void gc_helper_get_regs_and_clean_stack(machine_uint_t *regs, machine_uint_t heap_end);
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);
}
}
mp_obj_t pyb_gc(void) {
gc_collect();
return mp_const_none;
@ -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 {
// uncaught exception
mp_obj_print((mp_obj_t)nlr.ret_val, PRINT_REPR);
printf("\n");
}
}
}
}
stdout_tx_str("\r\n");
}
int main(void) {
pinMode(LED_BUILTIN, OUTPUT);
#if 0
// Wait for host side to get connected
while (!usb_vcp_is_connected()) {
;
}
#else
delay(1000);
#endif
led_init();
led_state(PYB_LED_BUILTIN, 1);
// int first_soft_reset = true;
soft_reset:
led_state(PYB_LED_BUILTIN, 1);
// GC init
gc_init(&_heap_start, (void*)HEAP_END);
qstr_init();
mp_init();
readline_init();
//pin_init();
#if 0
// add some functions to the python namespace
{
mp_store_name(MP_QSTR_help, mp_make_function_n(0, pyb_help));
@ -478,7 +285,7 @@ soft_reset:
mp_store_attr(m, MP_QSTR_gc, mp_make_function_n(0, pyb_gc));
mp_store_attr(m, MP_QSTR_delay, mp_make_function_n(1, pyb_delay));
mp_store_attr(m, MP_QSTR_led, mp_make_function_n(1, pyb_led));
mp_store_attr(m, MP_QSTR_Led, mp_make_function_n(1, pyb_Led));
mp_store_attr(m, MP_QSTR_LED, (mp_obj_t)&pyb_led_type);
mp_store_attr(m, MP_QSTR_analogRead, mp_make_function_n(1, pyb_analog_read));
mp_store_attr(m, MP_QSTR_analogWrite, mp_make_function_n(2, pyb_analog_write));
mp_store_attr(m, MP_QSTR_analogWriteResolution, mp_make_function_n(1, pyb_analog_write_resolution));
@ -487,15 +294,12 @@ soft_reset:
mp_store_attr(m, MP_QSTR_gpio, (mp_obj_t)&pyb_gpio_obj);
mp_store_attr(m, MP_QSTR_Servo, mp_make_function_n(0, pyb_Servo));
mp_store_name(MP_QSTR_pyb, m);
mp_store_name(MP_QSTR_run, mp_make_function_n(1, pyb_run));
}
#endif
printf("About execute /boot.py\n");
if (!do_file("/boot.py")) {
printf("Unable to open '/boot.py'\n");
if (!pyexec_file("/boot.py")) {
flash_error(4);
}
printf("Done executing /boot.py\n");
// Turn bootup LED off
led_state(PYB_LED_BUILTIN, 0);
@ -504,27 +308,30 @@ soft_reset:
{
vstr_t *vstr = vstr_new();
vstr_add_str(vstr, "/");
if (pyb_config_source_dir == MP_OBJ_NULL) {
vstr_add_str(vstr, "src");
} else {
vstr_add_str(vstr, mp_obj_str_get_str(pyb_config_source_dir));
}
vstr_add_char(vstr, '/');
if (pyb_config_main == MP_OBJ_NULL) {
vstr_add_str(vstr, "main.py");
} else {
vstr_add_str(vstr, mp_obj_str_get_str(pyb_config_main));
}
printf("About execute '%s'\n", vstr_str(vstr));
if (!do_file(vstr_str(vstr))) {
printf("Unable to open '%s'\n", vstr_str(vstr));
if (!pyexec_file(vstr_str(vstr))) {
flash_error(3);
}
printf("Done executing '%s'\n", vstr_str(vstr));
vstr_free(vstr);
}
do_repl();
// enter REPL
// REPL mode can change, or it can request a soft reset
for (;;) {
if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
if (pyexec_raw_repl() != 0) {
break;
}
} else {
if (pyexec_friendly_repl() != 0) {
break;
}
}
}
printf("PYB: soft reboot\n");
@ -532,22 +339,15 @@ soft_reset:
goto soft_reset;
}
double sqrt(double x) {
// TODO
return 0.0;
}
machine_float_t machine_sqrt(machine_float_t x) {
// TODO
return x;
}
// stub out __libc_init_array. It's called by mk20dx128.c and is used to call
// global C++ constructors. Since this is a C-only projects, we don't need to
// call constructors.
void __libc_init_array(void) {
}
// ultoa is used by usb_init_serialnumber. Normally ultoa would be provided
// by nonstd.c from the teensy core, but it conflicts with some of the
// MicroPython functions in string0.c, so we provide ultoa here.
char * ultoa(unsigned long val, char *buf, int radix)
{
unsigned digit;
@ -569,3 +369,12 @@ char * ultoa(unsigned long val, char *buf, int radix)
}
return buf;
}
STATIC NORETURN mp_obj_t mp_sys_exit(uint n_args, const mp_obj_t *args) {
int rc = 0;
if (n_args > 0) {
rc = mp_obj_get_int(args[0]);
}
nlr_raise(mp_obj_new_exception_arg1(&mp_type_SystemExit, mp_obj_new_int(rc)));
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_sys_exit_obj, 0, 1, mp_sys_exit);

326
teensy/make-pins.py Executable file
View File

@ -0,0 +1,326 @@
#!/usr/bin/env python
"""Creates the pin file for the Teensy."""
from __future__ import print_function
import argparse
import sys
import csv
SUPPORTED_FN = {
'FTM' : ['CH0', 'CH1', 'CH2', 'CH3',
'QD_PHA', 'QD_PHB'],
'I2C' : ['SDA', 'SCL'],
'UART' : ['RX', 'TX', 'CTS', 'RTS'],
'SPI' : ['NSS', 'SCK', 'MISO', 'MOSI']
}
def parse_port_pin(name_str):
"""Parses a string and returns a (port-num, pin-num) tuple."""
if len(name_str) < 4:
raise ValueError("Expecting pin name to be at least 4 charcters.")
if name_str[0:2] != 'PT':
raise ValueError("Expecting pin name to start with PT")
if name_str[2] not in ('A', 'B', 'C', 'D', 'E', 'Z'):
raise ValueError("Expecting pin port to be between A and E or Z")
port = ord(name_str[2]) - ord('A')
pin_str = name_str[3:].split('/')[0]
if not pin_str.isdigit():
raise ValueError("Expecting numeric pin number.")
return (port, int(pin_str))
def split_name_num(name_num):
num = None
for num_idx in range(len(name_num) - 1, -1, -1):
if not name_num[num_idx].isdigit():
name = name_num[0:num_idx + 1]
num_str = name_num[num_idx + 1:]
if len(num_str) > 0:
num = int(num_str)
break
return name, num
class AlternateFunction(object):
"""Holds the information associated with a pins alternate function."""
def __init__(self, idx, af_str):
self.idx = idx
self.af_str = af_str
self.func = ''
self.fn_num = None
self.pin_type = ''
self.supported = False
af_words = af_str.split('_', 1)
self.func, self.fn_num = split_name_num(af_words[0])
if len(af_words) > 1:
self.pin_type = af_words[1]
if self.func in SUPPORTED_FN:
pin_types = SUPPORTED_FN[self.func]
if self.pin_type in pin_types:
self.supported = True
def is_supported(self):
return self.supported
def ptr(self):
"""Returns the numbered function (i.e. USART6) for this AF."""
if self.fn_num is None:
return self.func
return '{:s}{:d}'.format(self.func, self.fn_num)
def print(self):
"""Prints the C representation of this AF."""
if self.supported:
print(' AF', end='')
else:
print(' //', end='')
fn_num = self.fn_num
if fn_num is None:
fn_num = 0
print('({:2d}, {:8s}, {:2d}, {:10s}, {:8s}), // {:s}'.format(self.idx,
self.func, fn_num, self.pin_type, self.ptr(), self.af_str))
class Pin(object):
"""Holds the information associated with a pin."""
def __init__(self, port, pin):
self.port = port
self.pin = pin
self.alt_fn = []
self.alt_fn_count = 0
self.adc_num = 0
self.adc_channel = 0
self.board_pin = False
def port_letter(self):
return chr(self.port + ord('A'))
def cpu_pin_name(self):
return '{:s}{:d}'.format(self.port_letter(), self.pin)
def is_board_pin(self):
return self.board_pin
def set_is_board_pin(self):
self.board_pin = True
def parse_adc(self, adc_str):
if (adc_str[:3] != 'ADC'):
return
(adc,channel) = adc_str.split('_')
for idx in range(3, len(adc)):
adc_num = int(adc[idx]) # 1, 2, or 3
self.adc_num |= (1 << (adc_num - 1))
self.adc_channel = int(channel[2:])
def parse_af(self, af_idx, af_strs_in):
if len(af_strs_in) == 0:
return
# If there is a slash, then the slash separates 2 aliases for the
# same alternate function.
af_strs = af_strs_in.split('/')
for af_str in af_strs:
alt_fn = AlternateFunction(af_idx, af_str)
self.alt_fn.append(alt_fn)
if alt_fn.is_supported():
self.alt_fn_count += 1
def alt_fn_name(self, null_if_0=False):
if null_if_0 and self.alt_fn_count == 0:
return 'NULL'
return 'pin_{:s}_af'.format(self.cpu_pin_name())
def adc_num_str(self):
str = ''
for adc_num in range(1,4):
if self.adc_num & (1 << (adc_num - 1)):
if len(str) > 0:
str += ' | '
str += 'PIN_ADC'
str += chr(ord('0') + adc_num)
if len(str) == 0:
str = '0'
return str
def print(self):
if self.alt_fn_count == 0:
print("// ", end='')
print('const pin_af_obj_t {:s}[] = {{'.format(self.alt_fn_name()))
for alt_fn in self.alt_fn:
alt_fn.print()
if self.alt_fn_count == 0:
print("// ", end='')
print('};')
print('')
print('const pin_obj_t pin_{:s} = PIN({:s}, {:d}, {:d}, {:s}, {:s}, {:d});'.format(
self.cpu_pin_name(), self.port_letter(), self.pin,
self.alt_fn_count, self.alt_fn_name(null_if_0=True),
self.adc_num_str(), self.adc_channel))
print('')
def print_header(self, hdr_file):
hdr_file.write('extern const pin_obj_t pin_{:s};\n'.
format(self.cpu_pin_name()))
if self.alt_fn_count > 0:
hdr_file.write('extern const pin_af_obj_t pin_{:s}_af[];\n'.
format(self.cpu_pin_name()))
class NamedPin(object):
def __init__(self, name, pin):
self._name = name
self._pin = pin
def pin(self):
return self._pin
def name(self):
return self._name
class Pins(object):
def __init__(self):
self.cpu_pins = [] # list of NamedPin objects
self.board_pins = [] # list of NamedPin objects
def find_pin(self, port_num, pin_num):
for named_pin in self.cpu_pins:
pin = named_pin.pin()
if pin.port == port_num and pin.pin == pin_num:
return pin
def parse_af_file(self, filename, pinname_col, af_col):
with open(filename, 'r') as csvfile:
rows = csv.reader(csvfile)
for row in rows:
try:
(port_num, pin_num) = parse_port_pin(row[pinname_col])
except:
continue
pin = Pin(port_num, pin_num)
for af_idx in range(af_col, len(row)):
if af_idx >= af_col:
pin.parse_af(af_idx - af_col, row[af_idx])
self.cpu_pins.append(NamedPin(pin.cpu_pin_name(), pin))
def parse_board_file(self, filename):
with open(filename, 'r') as csvfile:
rows = csv.reader(csvfile)
for row in rows:
try:
(port_num, pin_num) = parse_port_pin(row[1])
except:
continue
pin = self.find_pin(port_num, pin_num)
if pin:
pin.set_is_board_pin()
self.board_pins.append(NamedPin(row[0], pin))
def print_named(self, label, named_pins):
print('const pin_named_pin_t pin_{:s}_pins[] = {{'.format(label))
for named_pin in named_pins:
pin = named_pin.pin()
if pin.is_board_pin():
print(' {{ "{:s}", &pin_{:s} }},'.format(named_pin.name(), pin.cpu_pin_name()))
print(' { NULL, NULL }')
print('};')
def print(self):
for named_pin in self.cpu_pins:
pin = named_pin.pin()
if pin.is_board_pin():
pin.print()
self.print_named('cpu', self.cpu_pins)
print('')
self.print_named('board', self.board_pins)
def print_adc(self, adc_num):
print('');
print('const pin_obj_t * const pin_adc{:d}[] = {{'.format(adc_num))
for channel in range(16):
adc_found = False
for named_pin in self.cpu_pins:
pin = named_pin.pin()
if (pin.is_board_pin() and
(pin.adc_num & (1 << (adc_num - 1))) and (pin.adc_channel == channel)):
print(' &pin_{:s}, // {:d}'.format(pin.cpu_pin_name(), channel))
adc_found = True
break
if not adc_found:
print(' NULL, // {:d}'.format(channel))
print('};')
def print_header(self, hdr_filename):
with open(hdr_filename, 'wt') as hdr_file:
for named_pin in self.cpu_pins:
pin = named_pin.pin()
if pin.is_board_pin():
pin.print_header(hdr_file)
hdr_file.write('extern const pin_obj_t * const pin_adc1[];\n')
hdr_file.write('extern const pin_obj_t * const pin_adc2[];\n')
hdr_file.write('extern const pin_obj_t * const pin_adc3[];\n')
def main():
parser = argparse.ArgumentParser(
prog="make-pins.py",
usage="%(prog)s [options] [command]",
description="Generate board specific pin file"
)
parser.add_argument(
"-a", "--af",
dest="af_filename",
help="Specifies the alternate function file for the chip",
default="stm32f4xx-af.csv"
)
parser.add_argument(
"-b", "--board",
dest="board_filename",
help="Specifies the board file",
)
parser.add_argument(
"-p", "--prefix",
dest="prefix_filename",
help="Specifies beginning portion of generated pins file",
default="stm32f4xx-prefix.c"
)
parser.add_argument(
"-r", "--hdr",
dest="hdr_filename",
help="Specifies name of generated pin header file",
default="build/pins.h"
)
args = parser.parse_args(sys.argv[1:])
pins = Pins()
print('// This file was automatically generated by make-pins.py')
print('//')
if args.af_filename:
print('// --af {:s}'.format(args.af_filename))
pins.parse_af_file(args.af_filename, 4, 3)
if args.board_filename:
print('// --board {:s}'.format(args.board_filename))
pins.parse_board_file(args.board_filename)
if args.prefix_filename:
print('// --prefix {:s}'.format(args.prefix_filename))
print('')
with open(args.prefix_filename, 'r') as prefix_file:
print(prefix_file.read())
pins.print()
pins.print_adc(1)
pins.print_adc(2)
pins.print_adc(3)
pins.print_header(args.hdr_filename)
if __name__ == "__main__":
main()

View File

@ -1,12 +1,13 @@
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "misc.h"
#include "memzip.h"
extern uint8_t _staticfs[];
MEMZIP_RESULT memzip_locate(const char *filename, void **data, size_t *len)
{
const MEMZIP_FILE_HDR *memzip_find_file_header(const char *filename) {
const MEMZIP_FILE_HDR *file_hdr = (const MEMZIP_FILE_HDR *)_staticfs;
uint8_t *mem_data;
@ -22,16 +23,83 @@ MEMZIP_RESULT memzip_locate(const char *filename, void **data, size_t *len)
mem_data += file_hdr->extra_len;
if (!strncmp(file_hdr_filename, filename, file_hdr->filename_len)) {
/* We found a match */
if (file_hdr->compression_method != 0) {
return MZ_FILE_COMPRESSED;
}
*data = mem_data;
*len = file_hdr->uncompressed_size;
return MZ_OK;
return file_hdr;
}
mem_data += file_hdr->uncompressed_size;
file_hdr = (const MEMZIP_FILE_HDR *)mem_data;
}
return MZ_NO_FILE;
return NULL;
}
bool memzip_is_dir(const char *filename) {
const MEMZIP_FILE_HDR *file_hdr = (const MEMZIP_FILE_HDR *)_staticfs;
uint8_t *mem_data;
if (strcmp(filename, "/") == 0) {
// The root directory is a directory.
return true;
}
// Zip filenames don't have a leading /, so we strip it off
if (*filename == '/') {
filename++;
}
size_t filename_len = strlen(filename);
while (file_hdr->signature == MEMZIP_FILE_HEADER_SIGNATURE) {
const char *file_hdr_filename = (const char *)&file_hdr[1];
if (filename_len < file_hdr->filename_len &&
strncmp(file_hdr_filename, filename, filename_len) == 0 &&
file_hdr_filename[filename_len] == '/') {
return true;
}
mem_data = (uint8_t *)file_hdr_filename;
mem_data += file_hdr->filename_len;
mem_data += file_hdr->extra_len;
mem_data += file_hdr->uncompressed_size;
file_hdr = (const MEMZIP_FILE_HDR *)mem_data;
}
return NULL;
}
MEMZIP_RESULT memzip_locate(const char *filename, void **data, size_t *len)
{
const MEMZIP_FILE_HDR *file_hdr = memzip_find_file_header(filename);
if (file_hdr == NULL) {
return MZ_NO_FILE;
}
if (file_hdr->compression_method != 0) {
return MZ_FILE_COMPRESSED;
}
uint8_t *mem_data;
mem_data = (uint8_t *)&file_hdr[1];
mem_data += file_hdr->filename_len;
mem_data += file_hdr->extra_len;
*data = mem_data;
*len = file_hdr->uncompressed_size;
return MZ_OK;
}
MEMZIP_RESULT memzip_stat(const char *path, MEMZIP_FILE_INFO *info) {
const MEMZIP_FILE_HDR *file_hdr = memzip_find_file_header(path);
if (file_hdr == NULL) {
if (memzip_is_dir(path)) {
info->file_size = 0;
info->last_mod_date = 0;
info->last_mod_time = 0;
info->is_dir = 1;
return MZ_OK;
}
return MZ_NO_FILE;
}
info->file_size = file_hdr->uncompressed_size;
info->last_mod_date = file_hdr->last_mod_date;
info->last_mod_time = file_hdr->last_mod_time;
info->is_dir = 0;
return MZ_OK;
}

View File

@ -70,4 +70,14 @@ typedef enum {
} MEMZIP_RESULT;
typedef struct {
uint32_t file_size;
uint16_t last_mod_date;
uint16_t last_mod_time;
uint8_t is_dir;
} MEMZIP_FILE_INFO;
MEMZIP_RESULT memzip_locate(const char *filename, void **data, size_t *len);
MEMZIP_RESULT memzip_stat(const char *path, MEMZIP_FILE_INFO *info);

View File

@ -1 +1,2 @@
import pyb
print("Executing boot.py")

View File

@ -1,11 +1,13 @@
print("Executing main.py")
x=pyb.led(1)
led = pyb.LED(1)
led.on()
pyb.delay(100)
x=pyb.led(0)
led.off()
pyb.delay(100)
x=pyb.led(1)
led.on()
pyb.delay(100)
x=pyb.led(0)
led.off()

View File

@ -1 +0,0 @@
print("Executing /src/test.py")

View File

@ -1 +0,0 @@
print("Executing /test.py")

65
teensy/mk20dx256-af.csv Normal file
View File

@ -0,0 +1,65 @@
Pin,Name,Default,ALT0,ALT1,ALT2,ALT3,ALT4,ALT5,ALT6,ALT7,EzPort
1,PTE0,ADC1_SE4a,ADC1_SE4a,PTE0,SPI1_PCS1,UART1_TX,,,I2C1_SDA,RTC_CLKOUT,
2,PTE1/LLWU_P0,ADC1_SE5a,ADC1_SE5a,PTE1/LLWU_P0,SPI1_SOUT,UART1_RX,,,I2C1_SCL,SPI1_SIN,
3,VDD,VDD,VDD,,,,,,,,
4,VSS,VSS,VSS,,,,,,,,
5,USB0_DP,USB0_DP,USB0_DP,,,,,,,,
6,USB0_DM,USB0_DM,USB0_DM,,,,,,,,
7,VOUT33,VOUT33,VOUT33,,,,,,,,
8,VREGIN,VREGIN,VREGIN,,,,,,,,
9,PGA0_DP/ADC0_DP0/ADC1_DP3,PGA0_DP/ADC0_DP0/ADC1_DP3,PGA0_DP/ADC0_DP0/ADC1_DP3,PTZ0,,,,,,,
10,PGA0_DM/ADC0_DM0/ADC1_DM3,PGA0_DM/ADC0_DM0/ADC1_DM3,PGA0_DM/ADC0_DM0/ADC1_DM3,PTZ1,,,,,,,
11,PGA1_DP/ADC1_DP0/ADC0_DP3,PGA1_DP/ADC1_DP0/ADC0_DP3,PGA1_DP/ADC1_DP0/ADC0_DP3,PTZ2,,,,,,,
12,PGA1_DM/ADC1_DM0/ADC0_DM3,PGA1_DM/ADC1_DM0/ADC0_DM3,PGA1_DM/ADC1_DM0/ADC0_DM3,PTZ3,,,,,,,
13,VDDA,VDDA,VDDA,,,,,,,,
14,VREFH,VREFH,VREFH,,,,,,,,
15,VREFL,VREFL,VREFL,,,,,,,,
16,VSSA,VSSA,VSSA,,,,,,,,
17,VREF_OUT/CMP1_IN5/CMP0_IN5/ADC1_SE18,VREF_OUT/CMP1_IN5/CMP0_IN5/ADC1_SE18,VREF_OUT/CMP1_IN5/CMP0_IN5/ADC1_SE18,PTZ4,,,,,,,
18,DAC0_OUT/CMP1_IN3/ADC0_SE23,DAC0_OUT/CMP1_IN3/ADC0_SE23,DAC0_OUT/CMP1_IN3/ADC0_SE23,PTZ5,,,,,,,
19,XTAL32,XTAL32,XTAL32,,,,,,,,
20,EXTAL32,EXTAL32,EXTAL32,,,,,,,,
21,VBAT,VBAT,VBAT,,,,,,,,
22,PTA0,JTAG_TCLK/SWD_CLK/EZP_CLK,TSI0_CH1,PTA0,UART0_CTS_b/UART0_COL_b,FTM0_CH5,,,,JTAG_TCLK/SWD_CLK,EZP_CLK
23,PTA1,JTAG_TDI/EZP_DI,TSI0_CH2,PTA1,UART0_RX,FTM0_CH6,,,,JTAG_TDI,EZP_DI
24,PTA2,JTAG_TDO/TRACE_SWO/EZP_DO,TSI0_CH3,PTA2,UART0_TX,FTM0_CH7,,,,JTAG_TDO/TRACE_SWO,EZP_DO
25,PTA3,JTAG_TMS/SWD_DIO,TSI0_CH4,PTA3,UART0_RTS_b,FTM0_CH0,,,,JTAG_TMS/SWD_DIO,
26,PTA4/LLWU_P3,NMI_b/EZP_CS_b,TSI0_CH5,PTA4/LLWU_P3,,FTM0_CH1,,,NMI_b,EZP_CS_b,
27,PTA5,DISABLED,,PTA5,USB_CLKIN,FTM0_CH2,,CMP2_OUT,I2S0_TX_BCLK,JTAG_TRST_b,
28,PTA12,CMP2_IN0,CMP2_IN0,PTA12,CAN0_TX,FTM1_CH0,,,I2S0_TXD0,FTM1_QD_PHA,
29,PTA13/LLWU_P4,CMP2_IN1,CMP2_IN1,PTA13/LLWU_P4,CAN0_RX,FTM1_CH1,,,I2S0_TX_FS,FTM1_QD_PHB,
30,VDD,VDD,VDD,,,,,,,,
31,VSS,VSS,VSS,,,,,,,,
32,PTA18,EXTAL0,EXTAL0,PTA18,,FTM0_FLT2,FTM_CLKIN0,,,,
33,PTA19,XTAL0,XTAL0,PTA19,,FTM1_FLT0,FTM_CLKIN1,,LPTMR0_ALT1,,
34,RESET_b,RESET_b,RESET_b,,,,,,,,
35,PTB0/LLWU_P5,ADC0_SE8/ADC1_SE8/TSI0_CH0,ADC0_SE8/ADC1_SE8/TSI0_CH0,PTB0/LLWU_P5,I2C0_SCL,FTM1_CH0,,,FTM1_QD_PHA,,
36,PTB1,ADC0_SE9/ADC1_SE9/TSI0_CH6,ADC0_SE9/ADC1_SE9/TSI0_CH6,PTB1,I2C0_SDA,FTM1_CH1,,,FTM1_QD_PHB,,
37,PTB2,ADC0_SE12/TSI0_CH7,ADC0_SE12/TSI0_CH7,PTB2,I2C0_SCL,UART0_RTS_b,,,FTM0_FLT3,,
38,PTB3,ADC0_SE13/TSI0_CH8,ADC0_SE13/TSI0_CH8,PTB3,I2C0_SDA,UART0_CTS_b/UART0_COL_b,,,FTM0_FLT0,,
39,PTB16,TSI0_CH9,TSI0_CH9,PTB16,SPI1_SOUT,UART0_RX,,FB_AD17,EWM_IN,,
40,PTB17,TSI0_CH10,TSI0_CH10,PTB17,SPI1_SIN,UART0_TX,,FB_AD16,EWM_OUT_b,,
41,PTB18,TSI0_CH11,TSI0_CH11,PTB18,CAN0_TX,FTM2_CH0,I2S0_TX_BCLK,FB_AD15,FTM2_QD_PHA,,
42,PTB19,TSI0_CH12,TSI0_CH12,PTB19,CAN0_RX,FTM2_CH1,I2S0_TX_FS,FB_OE_b,FTM2_QD_PHB,,
43,PTC0,ADC0_SE14/TSI0_CH13,ADC0_SE14/TSI0_CH13,PTC0,SPI0_PCS4,PDB0_EXTRG,,FB_AD14,I2S0_TXD1,,
44,PTC1/LLWU_P6,ADC0_SE15/TSI0_CH14,ADC0_SE15/TSI0_CH14,PTC1/LLWU_P6,SPI0_PCS3,UART1_RTS_b,FTM0_CH0,FB_AD13,I2S0_TXD0,,
45,PTC2,ADC0_SE4b/CMP1_IN0/TSI0_CH15,ADC0_SE4b/CMP1_IN0/TSI0_CH15,PTC2,SPI0_PCS2,UART1_CTS_b,FTM0_CH1,FB_AD12,I2S0_TX_FS,,
46,PTC3/LLWU_P7,CMP1_IN1,CMP1_IN1,PTC3/LLWU_P7,SPI0_PCS1,UART1_RX,FTM0_CH2,CLKOUT,I2S0_TX_BCLK,,
47,VSS,VSS,VSS,,,,,,,,
48,VDD,VDD,VDD,,,,,,,,
49,PTC4/LLWU_P8,DISABLED,,PTC4/LLWU_P8,SPI0_PCS0,UART1_TX,FTM0_CH3,FB_AD11,CMP1_OUT,,
50,PTC5/LLWU_P9,DISABLED,,PTC5/LLWU_P9,SPI0_SCK,LPTMR0_ALT2,I2S0_RXD0,FB_AD10,CMP0_OUT,,
51,PTC6/LLWU_P10,CMP0_IN0,CMP0_IN0,PTC6/LLWU_P10,SPI0_SOUT,PDB0_EXTRG,I2S0_RX_BCLK,FB_AD9,I2S0_MCLK,,
52,PTC7,CMP0_IN1,CMP0_IN1,PTC7,SPI0_SIN,USB_SOF_OUT,I2S0_RX_FS,FB_AD8,,,
53,PTC8,ADC1_SE4b/CMP0_IN2,ADC1_SE4b/CMP0_IN2,PTC8,,,I2S0_MCLK,FB_AD7,,,
54,PTC9,ADC1_SE5b/CMP0_IN3,ADC1_SE5b/CMP0_IN3,PTC9,,,I2S0_RX_BCLK,FB_AD6,FTM2_FLT0,,
55,PTC10,ADC1_SE6b,ADC1_SE6b,PTC10,I2C1_SCL,,I2S0_RX_FS,FB_AD5,,,
56,PTC11/LLWU_P11,ADC1_SE7b,ADC1_SE7b,PTC11/LLWU_P11,I2C1_SDA,,I2S0_RXD1,FB_RW_b,,,
57,PTD0/LLWU_P12,DISABLED,,PTD0/LLWU_P12,SPI0_PCS0,UART2_RTS_b,,FB_ALE/FB_CS1_b/FB_TS_b,,,
58,PTD1,ADC0_SE5b,ADC0_SE5b,PTD1,SPI0_SCK,UART2_CTS_b,,FB_CS0_b,,,
59,PTD2/LLWU_P13,DISABLED,,PTD2/LLWU_P13,SPI0_SOUT,UART2_RX,,FB_AD4,,,
60,PTD3,DISABLED,,PTD3,SPI0_SIN,UART2_TX,,FB_AD3,,,
61,PTD4/LLWU_P14,DISABLED,,PTD4/LLWU_P14,SPI0_PCS1,UART0_RTS_b,FTM0_CH4,FB_AD2,EWM_IN,,
62,PTD5,ADC0_SE6b,ADC0_SE6b,PTD5,SPI0_PCS2,UART0_CTS_b/UART0_COL_b,FTM0_CH5,FB_AD1,EWM_OUT_b,,
63,PTD6/LLWU_P15,ADC0_SE7b,ADC0_SE7b,PTD6/LLWU_P15,SPI0_PCS3,UART0_RX,FTM0_CH6,FB_AD0,FTM0_FLT0,,
64,PTD7,DISABLED,,PTD7,CMT_IRO,UART0_TX,FTM0_CH7,,FTM0_FLT1,,
1 Pin Name Default ALT0 ALT1 ALT2 ALT3 ALT4 ALT5 ALT6 ALT7 EzPort
2 1 PTE0 ADC1_SE4a ADC1_SE4a PTE0 SPI1_PCS1 UART1_TX I2C1_SDA RTC_CLKOUT
3 2 PTE1/LLWU_P0 ADC1_SE5a ADC1_SE5a PTE1/LLWU_P0 SPI1_SOUT UART1_RX I2C1_SCL SPI1_SIN
4 3 VDD VDD VDD
5 4 VSS VSS VSS
6 5 USB0_DP USB0_DP USB0_DP
7 6 USB0_DM USB0_DM USB0_DM
8 7 VOUT33 VOUT33 VOUT33
9 8 VREGIN VREGIN VREGIN
10 9 PGA0_DP/ADC0_DP0/ADC1_DP3 PGA0_DP/ADC0_DP0/ADC1_DP3 PGA0_DP/ADC0_DP0/ADC1_DP3 PTZ0
11 10 PGA0_DM/ADC0_DM0/ADC1_DM3 PGA0_DM/ADC0_DM0/ADC1_DM3 PGA0_DM/ADC0_DM0/ADC1_DM3 PTZ1
12 11 PGA1_DP/ADC1_DP0/ADC0_DP3 PGA1_DP/ADC1_DP0/ADC0_DP3 PGA1_DP/ADC1_DP0/ADC0_DP3 PTZ2
13 12 PGA1_DM/ADC1_DM0/ADC0_DM3 PGA1_DM/ADC1_DM0/ADC0_DM3 PGA1_DM/ADC1_DM0/ADC0_DM3 PTZ3
14 13 VDDA VDDA VDDA
15 14 VREFH VREFH VREFH
16 15 VREFL VREFL VREFL
17 16 VSSA VSSA VSSA
18 17 VREF_OUT/CMP1_IN5/CMP0_IN5/ADC1_SE18 VREF_OUT/CMP1_IN5/CMP0_IN5/ADC1_SE18 VREF_OUT/CMP1_IN5/CMP0_IN5/ADC1_SE18 PTZ4
19 18 DAC0_OUT/CMP1_IN3/ADC0_SE23 DAC0_OUT/CMP1_IN3/ADC0_SE23 DAC0_OUT/CMP1_IN3/ADC0_SE23 PTZ5
20 19 XTAL32 XTAL32 XTAL32
21 20 EXTAL32 EXTAL32 EXTAL32
22 21 VBAT VBAT VBAT
23 22 PTA0 JTAG_TCLK/SWD_CLK/EZP_CLK TSI0_CH1 PTA0 UART0_CTS_b/UART0_COL_b FTM0_CH5 JTAG_TCLK/SWD_CLK EZP_CLK
24 23 PTA1 JTAG_TDI/EZP_DI TSI0_CH2 PTA1 UART0_RX FTM0_CH6 JTAG_TDI EZP_DI
25 24 PTA2 JTAG_TDO/TRACE_SWO/EZP_DO TSI0_CH3 PTA2 UART0_TX FTM0_CH7 JTAG_TDO/TRACE_SWO EZP_DO
26 25 PTA3 JTAG_TMS/SWD_DIO TSI0_CH4 PTA3 UART0_RTS_b FTM0_CH0 JTAG_TMS/SWD_DIO
27 26 PTA4/LLWU_P3 NMI_b/EZP_CS_b TSI0_CH5 PTA4/LLWU_P3 FTM0_CH1 NMI_b EZP_CS_b
28 27 PTA5 DISABLED PTA5 USB_CLKIN FTM0_CH2 CMP2_OUT I2S0_TX_BCLK JTAG_TRST_b
29 28 PTA12 CMP2_IN0 CMP2_IN0 PTA12 CAN0_TX FTM1_CH0 I2S0_TXD0 FTM1_QD_PHA
30 29 PTA13/LLWU_P4 CMP2_IN1 CMP2_IN1 PTA13/LLWU_P4 CAN0_RX FTM1_CH1 I2S0_TX_FS FTM1_QD_PHB
31 30 VDD VDD VDD
32 31 VSS VSS VSS
33 32 PTA18 EXTAL0 EXTAL0 PTA18 FTM0_FLT2 FTM_CLKIN0
34 33 PTA19 XTAL0 XTAL0 PTA19 FTM1_FLT0 FTM_CLKIN1 LPTMR0_ALT1
35 34 RESET_b RESET_b RESET_b
36 35 PTB0/LLWU_P5 ADC0_SE8/ADC1_SE8/TSI0_CH0 ADC0_SE8/ADC1_SE8/TSI0_CH0 PTB0/LLWU_P5 I2C0_SCL FTM1_CH0 FTM1_QD_PHA
37 36 PTB1 ADC0_SE9/ADC1_SE9/TSI0_CH6 ADC0_SE9/ADC1_SE9/TSI0_CH6 PTB1 I2C0_SDA FTM1_CH1 FTM1_QD_PHB
38 37 PTB2 ADC0_SE12/TSI0_CH7 ADC0_SE12/TSI0_CH7 PTB2 I2C0_SCL UART0_RTS_b FTM0_FLT3
39 38 PTB3 ADC0_SE13/TSI0_CH8 ADC0_SE13/TSI0_CH8 PTB3 I2C0_SDA UART0_CTS_b/UART0_COL_b FTM0_FLT0
40 39 PTB16 TSI0_CH9 TSI0_CH9 PTB16 SPI1_SOUT UART0_RX FB_AD17 EWM_IN
41 40 PTB17 TSI0_CH10 TSI0_CH10 PTB17 SPI1_SIN UART0_TX FB_AD16 EWM_OUT_b
42 41 PTB18 TSI0_CH11 TSI0_CH11 PTB18 CAN0_TX FTM2_CH0 I2S0_TX_BCLK FB_AD15 FTM2_QD_PHA
43 42 PTB19 TSI0_CH12 TSI0_CH12 PTB19 CAN0_RX FTM2_CH1 I2S0_TX_FS FB_OE_b FTM2_QD_PHB
44 43 PTC0 ADC0_SE14/TSI0_CH13 ADC0_SE14/TSI0_CH13 PTC0 SPI0_PCS4 PDB0_EXTRG FB_AD14 I2S0_TXD1
45 44 PTC1/LLWU_P6 ADC0_SE15/TSI0_CH14 ADC0_SE15/TSI0_CH14 PTC1/LLWU_P6 SPI0_PCS3 UART1_RTS_b FTM0_CH0 FB_AD13 I2S0_TXD0
46 45 PTC2 ADC0_SE4b/CMP1_IN0/TSI0_CH15 ADC0_SE4b/CMP1_IN0/TSI0_CH15 PTC2 SPI0_PCS2 UART1_CTS_b FTM0_CH1 FB_AD12 I2S0_TX_FS
47 46 PTC3/LLWU_P7 CMP1_IN1 CMP1_IN1 PTC3/LLWU_P7 SPI0_PCS1 UART1_RX FTM0_CH2 CLKOUT I2S0_TX_BCLK
48 47 VSS VSS VSS
49 48 VDD VDD VDD
50 49 PTC4/LLWU_P8 DISABLED PTC4/LLWU_P8 SPI0_PCS0 UART1_TX FTM0_CH3 FB_AD11 CMP1_OUT
51 50 PTC5/LLWU_P9 DISABLED PTC5/LLWU_P9 SPI0_SCK LPTMR0_ALT2 I2S0_RXD0 FB_AD10 CMP0_OUT
52 51 PTC6/LLWU_P10 CMP0_IN0 CMP0_IN0 PTC6/LLWU_P10 SPI0_SOUT PDB0_EXTRG I2S0_RX_BCLK FB_AD9 I2S0_MCLK
53 52 PTC7 CMP0_IN1 CMP0_IN1 PTC7 SPI0_SIN USB_SOF_OUT I2S0_RX_FS FB_AD8
54 53 PTC8 ADC1_SE4b/CMP0_IN2 ADC1_SE4b/CMP0_IN2 PTC8 I2S0_MCLK FB_AD7
55 54 PTC9 ADC1_SE5b/CMP0_IN3 ADC1_SE5b/CMP0_IN3 PTC9 I2S0_RX_BCLK FB_AD6 FTM2_FLT0
56 55 PTC10 ADC1_SE6b ADC1_SE6b PTC10 I2C1_SCL I2S0_RX_FS FB_AD5
57 56 PTC11/LLWU_P11 ADC1_SE7b ADC1_SE7b PTC11/LLWU_P11 I2C1_SDA I2S0_RXD1 FB_RW_b
58 57 PTD0/LLWU_P12 DISABLED PTD0/LLWU_P12 SPI0_PCS0 UART2_RTS_b FB_ALE/FB_CS1_b/FB_TS_b
59 58 PTD1 ADC0_SE5b ADC0_SE5b PTD1 SPI0_SCK UART2_CTS_b FB_CS0_b
60 59 PTD2/LLWU_P13 DISABLED PTD2/LLWU_P13 SPI0_SOUT UART2_RX FB_AD4
61 60 PTD3 DISABLED PTD3 SPI0_SIN UART2_TX FB_AD3
62 61 PTD4/LLWU_P14 DISABLED PTD4/LLWU_P14 SPI0_PCS1 UART0_RTS_b FTM0_CH4 FB_AD2 EWM_IN
63 62 PTD5 ADC0_SE6b ADC0_SE6b PTD5 SPI0_PCS2 UART0_CTS_b/UART0_COL_b FTM0_CH5 FB_AD1 EWM_OUT_b
64 63 PTD6/LLWU_P15 ADC0_SE7b ADC0_SE7b PTD6/LLWU_P15 SPI0_PCS3 UART0_RX FTM0_CH6 FB_AD0 FTM0_FLT0
65 64 PTD7 DISABLED PTD7 CMT_IRO UART0_TX FTM0_CH7 FTM0_FLT1

37
teensy/mk20dx256-prefix.c Normal file
View File

@ -0,0 +1,37 @@
// stm32fxx-prefix.c becomes the initial portion of the generated pins file.
#include <stdio.h>
#include <stdint.h>
#include <mk20dx128.h>
#include "teensy_hal.h"
#include "misc.h"
#include "mpconfig.h"
#include "qstr.h"
#include "obj.h"
#include "pin.h"
#define AF(af_idx, af_fn, af_unit, af_type, af_ptr) \
{ \
{ &pin_af_type }, \
.idx = (af_idx), \
.fn = AF_FN_ ## af_fn, \
.unit = (af_unit), \
.type = AF_PIN_TYPE_ ## af_fn ## _ ## af_type, \
.af_fn = (af_ptr) \
}
#define PIN(p_port, p_pin, p_num_af, p_af, p_adc_num, p_adc_channel) \
{ \
{ &pin_type }, \
.name = #p_port #p_pin, \
.port = PORT_ ## p_port, \
.pin = (p_pin), \
.num_af = (p_num_af), \
.pin_mask = (1 << (p_pin)), \
.gpio = GPIO ## p_port, \
.af = p_af, \
.adc_num = p_adc_num, \
.adc_channel = p_adc_channel, \
}

View File

@ -118,9 +118,13 @@ SECTIONS
*(.usbbuffers*)
} > RAM
/* used by the startup to initialize data */
_sidata = LOADADDR(.data);
.data : AT (_etext) {
. = ALIGN(4);
_sdata = .;
_ram_start = .;
*(.data*)
. = ALIGN(4);
_edata = .;
@ -163,6 +167,8 @@ SECTIONS
} >RAM
_estack = ORIGIN(RAM) + LENGTH(RAM);
_ram_end = ORIGIN(RAM) + LENGTH(RAM);
_heap_end = ORIGIN(RAM) + 0xe000;
}

341
teensy/modpyb.c Normal file
View File

@ -0,0 +1,341 @@
/*
* 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 <stdint.h>
#include <stdio.h>
#include <mk20dx128.h>
#include "Arduino.h"
#include "misc.h"
#include "mpconfig.h"
#include "teensy_hal.h"
#include "qstr.h"
#include "obj.h"
#include "gc.h"
#include "gccollect.h"
#include "systick.h"
#include "pybstdio.h"
#include "pyexec.h"
#include "led.h"
#include "pin.h"
//#include "timer.h"
#include "extint.h"
#include "usrsw.h"
#include "rng.h"
//#include "rtc.h"
//#include "i2c.h"
//#include "spi.h"
#include "uart.h"
#include "adc.h"
#include "storage.h"
#include "sdcard.h"
#include "accel.h"
#include "servo.h"
#include "dac.h"
#include "usb.h"
#include "portmodules.h"
/// \module pyb - functions related to the pyboard
///
/// The `pyb` module contains specific functions related to the pyboard.
/// \function bootloader()
/// Activate the bootloader without BOOT* pins.
STATIC mp_obj_t pyb_bootloader(void) {
printf("bootloader command not current supported\n");
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_bootloader_obj, pyb_bootloader);
/// \function info([dump_alloc_table])
/// Print out lots of information about the board.
STATIC mp_obj_t pyb_info(uint n_args, const mp_obj_t *args) {
// get and print unique id; 96 bits
{
byte *id = (byte*)0x40048058;
printf("ID=%02x%02x%02x%02x:%02x%02x%02x%02x:%02x%02x%02x%02x\n", id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7], id[8], id[9], id[10], id[11]);
}
// get and print clock speeds
printf("CPU=%u\nBUS=%u\nMEM=%u\n", F_CPU, F_BUS, F_MEM);
// to print info about memory
{
printf("_etext=%p\n", &_etext);
printf("_sidata=%p\n", &_sidata);
printf("_sdata=%p\n", &_sdata);
printf("_edata=%p\n", &_edata);
printf("_sbss=%p\n", &_sbss);
printf("_ebss=%p\n", &_ebss);
printf("_estack=%p\n", &_estack);
printf("_ram_start=%p\n", &_ram_start);
printf("_heap_start=%p\n", &_heap_start);
printf("_heap_end=%p\n", &_heap_end);
printf("_ram_end=%p\n", &_ram_end);
}
// qstr info
{
uint n_pool, n_qstr, n_str_data_bytes, n_total_bytes;
qstr_pool_info(&n_pool, &n_qstr, &n_str_data_bytes, &n_total_bytes);
printf("qstr:\n n_pool=%u\n n_qstr=%u\n n_str_data_bytes=%u\n n_total_bytes=%u\n", n_pool, n_qstr, n_str_data_bytes, n_total_bytes);
}
// GC info
{
gc_info_t info;
gc_info(&info);
printf("GC:\n");
printf(" " UINT_FMT " total\n", info.total);
printf(" " UINT_FMT " : " UINT_FMT "\n", info.used, info.free);
printf(" 1=" UINT_FMT " 2=" UINT_FMT " m=" UINT_FMT "\n", info.num_1block, info.num_2block, info.max_block);
}
if (n_args == 1) {
// arg given means dump gc allocation table
gc_dump_alloc_table();
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_info_obj, 0, 1, pyb_info);
/// \function unique_id()
/// Returns a string of 12 bytes (96 bits), which is the unique ID for the MCU.
STATIC mp_obj_t pyb_unique_id(void) {
byte *id = (byte*)0x40048058;
return mp_obj_new_bytes(id, 12);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_unique_id_obj, pyb_unique_id);
/// \function freq()
/// Return a tuple of clock frequencies: (SYSCLK, HCLK, PCLK1, PCLK2).
// TODO should also be able to set frequency via this function
STATIC mp_obj_t pyb_freq(void) {
mp_obj_t tuple[3] = {
mp_obj_new_int(F_CPU),
mp_obj_new_int(F_BUS),
mp_obj_new_int(F_MEM),
};
return mp_obj_new_tuple(3, tuple);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_freq_obj, pyb_freq);
/// \function sync()
/// Sync all file systems.
STATIC mp_obj_t pyb_sync(void) {
printf("sync not currently implemented\n");
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_sync_obj, pyb_sync);
/// \function millis()
/// Returns the number of milliseconds since the board was last reset.
STATIC mp_obj_t pyb_millis(void) {
return mp_obj_new_int(HAL_GetTick());
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_millis_obj, pyb_millis);
/// \function delay(ms)
/// Delay for the given number of milliseconds.
STATIC mp_obj_t pyb_delay(mp_obj_t ms_in) {
machine_int_t ms = mp_obj_get_int(ms_in);
if (ms >= 0) {
HAL_Delay(ms);
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_delay_obj, pyb_delay);
/// \function udelay(us)
/// Delay for the given number of microseconds.
STATIC mp_obj_t pyb_udelay(mp_obj_t usec_in) {
machine_int_t usec = mp_obj_get_int(usec_in);
delayMicroseconds(usec);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_udelay_obj, pyb_udelay);
/// \function wfi()
/// Wait for an interrupt.
/// This executies a `wfi` instruction which reduces power consumption
/// of the MCU until an interrupt occurs, at which point execution continues.
STATIC mp_obj_t pyb_wfi(void) {
__WFI();
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_0(pyb_wfi_obj, pyb_wfi);
/// \function disable_irq()
/// Disable interrupt requests.
STATIC mp_obj_t pyb_disable_irq(void) {
__disable_irq();
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_0(pyb_disable_irq_obj, pyb_disable_irq);
/// \function enable_irq()
/// Enable interrupt requests.
STATIC mp_obj_t pyb_enable_irq(void) {
__enable_irq();
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_0(pyb_enable_irq_obj, pyb_enable_irq);
STATIC mp_obj_t pyb_stop(void) {
printf("stop not currently implemented\n");
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_0(pyb_stop_obj, pyb_stop);
STATIC mp_obj_t pyb_standby(void) {
printf("standby not currently implemented\n");
return mp_const_none;
}
MP_DEFINE_CONST_FUN_OBJ_0(pyb_standby_obj, pyb_standby);
/// \function have_cdc()
/// Return True if USB is connected as a serial device, False otherwise.
STATIC mp_obj_t pyb_have_cdc(void ) {
return MP_BOOL(usb_vcp_is_connected());
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(pyb_have_cdc_obj, pyb_have_cdc);
/// \function hid((buttons, x, y, z))
/// Takes a 4-tuple (or list) and sends it to the USB host (the PC) to
/// signal a HID mouse-motion event.
STATIC mp_obj_t pyb_hid_send_report(mp_obj_t arg) {
#if 1
printf("hid_send_report not currently implemented\n");
#else
mp_obj_t *items;
mp_obj_get_array_fixed_n(arg, 4, &items);
uint8_t data[4];
data[0] = mp_obj_get_int(items[0]);
data[1] = mp_obj_get_int(items[1]);
data[2] = mp_obj_get_int(items[2]);
data[3] = mp_obj_get_int(items[3]);
usb_hid_send_report(data);
#endif
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_hid_send_report_obj, pyb_hid_send_report);
MP_DECLARE_CONST_FUN_OBJ(pyb_source_dir_obj); // defined in main.c
MP_DECLARE_CONST_FUN_OBJ(pyb_main_obj); // defined in main.c
MP_DECLARE_CONST_FUN_OBJ(pyb_usb_mode_obj); // defined in main.c
STATIC const mp_map_elem_t pyb_module_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_pyb) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_bootloader), (mp_obj_t)&pyb_bootloader_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_info), (mp_obj_t)&pyb_info_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_unique_id), (mp_obj_t)&pyb_unique_id_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_freq), (mp_obj_t)&pyb_freq_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_repl_info), (mp_obj_t)&pyb_set_repl_info_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_wfi), (mp_obj_t)&pyb_wfi_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_disable_irq), (mp_obj_t)&pyb_disable_irq_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_enable_irq), (mp_obj_t)&pyb_enable_irq_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_stop), (mp_obj_t)&pyb_stop_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_standby), (mp_obj_t)&pyb_standby_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_source_dir), (mp_obj_t)&pyb_source_dir_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_main), (mp_obj_t)&pyb_main_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_usb_mode), (mp_obj_t)&pyb_usb_mode_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_have_cdc), (mp_obj_t)&pyb_have_cdc_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_hid), (mp_obj_t)&pyb_hid_send_report_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_millis), (mp_obj_t)&pyb_millis_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_delay), (mp_obj_t)&pyb_delay_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_udelay), (mp_obj_t)&pyb_udelay_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_sync), (mp_obj_t)&pyb_sync_obj },
// { MP_OBJ_NEW_QSTR(MP_QSTR_Timer), (mp_obj_t)&pyb_timer_type },
//#if MICROPY_HW_ENABLE_RNG
// { MP_OBJ_NEW_QSTR(MP_QSTR_rng), (mp_obj_t)&pyb_rng_get_obj },
//#endif
//#if MICROPY_HW_ENABLE_RTC
// { MP_OBJ_NEW_QSTR(MP_QSTR_RTC), (mp_obj_t)&pyb_rtc_type },
//#endif
{ MP_OBJ_NEW_QSTR(MP_QSTR_Pin), (mp_obj_t)&pin_type },
// { MP_OBJ_NEW_QSTR(MP_QSTR_ExtInt), (mp_obj_t)&extint_type },
#if MICROPY_HW_ENABLE_SERVO
{ MP_OBJ_NEW_QSTR(MP_QSTR_pwm), (mp_obj_t)&pyb_pwm_set_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_servo), (mp_obj_t)&pyb_servo_set_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_Servo), (mp_obj_t)&pyb_servo_type },
#endif
#if MICROPY_HW_HAS_SWITCH
{ MP_OBJ_NEW_QSTR(MP_QSTR_Switch), (mp_obj_t)&pyb_switch_type },
#endif
//#if MICROPY_HW_HAS_SDCARD
// { MP_OBJ_NEW_QSTR(MP_QSTR_SD), (mp_obj_t)&pyb_sdcard_obj },
//#endif
{ MP_OBJ_NEW_QSTR(MP_QSTR_LED), (mp_obj_t)&pyb_led_type },
// { MP_OBJ_NEW_QSTR(MP_QSTR_I2C), (mp_obj_t)&pyb_i2c_type },
// { MP_OBJ_NEW_QSTR(MP_QSTR_SPI), (mp_obj_t)&pyb_spi_type },
{ MP_OBJ_NEW_QSTR(MP_QSTR_UART), (mp_obj_t)&pyb_uart_type },
// { MP_OBJ_NEW_QSTR(MP_QSTR_ADC), (mp_obj_t)&pyb_adc_type },
// { MP_OBJ_NEW_QSTR(MP_QSTR_ADCAll), (mp_obj_t)&pyb_adc_all_type },
//#if MICROPY_HW_ENABLE_DAC
// { MP_OBJ_NEW_QSTR(MP_QSTR_DAC), (mp_obj_t)&pyb_dac_type },
//#endif
//#if MICROPY_HW_HAS_MMA7660
// { MP_OBJ_NEW_QSTR(MP_QSTR_Accel), (mp_obj_t)&pyb_accel_type },
//#endif
};
STATIC const mp_obj_dict_t pyb_module_globals = {
.base = {&mp_type_dict},
.map = {
.all_keys_are_qstrs = 1,
.table_is_fixed_array = 1,
.used = ARRAY_SIZE(pyb_module_globals_table),
.alloc = ARRAY_SIZE(pyb_module_globals_table),
.table = (mp_map_elem_t*)pyb_module_globals_table,
},
};
const mp_obj_module_t pyb_module = {
.base = { &mp_type_module },
.name = MP_QSTR_pyb,
.globals = (mp_obj_dict_t*)&pyb_module_globals,
};

View File

@ -2,20 +2,98 @@
// options to control how Micro Python is built
#define MICROPY_ALLOC_PATH_MAX (128)
#define MICROPY_EMIT_THUMB (1)
#define MICROPY_EMIT_INLINE_THUMB (1)
#define MICROPY_ENABLE_GC (1)
#define MICROPY_ENABLE_FINALISER (1)
#define MICROPY_HELPER_REPL (1)
#define MICROPY_PY_BUILTINS_FLOAT (1)
#define MICROPY_ENABLE_SOURCE_LINE (1)
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ)
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT)
#define MICROPY_OPT_COMPUTED_GOTO (1)
#define MICROPY_PY_IO (0)
#define MICROPY_PY_FROZENSET (1)
#define MICROPY_PY_SYS_EXIT (1)
#define MICROPY_PY_SYS_STDFILES (1)
#define MICROPY_PY_CMATH (1)
// extra built in names to add to the global namespace
extern const struct _mp_obj_fun_native_t mp_builtin_help_obj;
extern const struct _mp_obj_fun_native_t mp_builtin_input_obj;
extern const struct _mp_obj_fun_native_t mp_builtin_open_obj;
#define MICROPY_PORT_BUILTINS \
{ MP_OBJ_NEW_QSTR(MP_QSTR_help), (mp_obj_t)&mp_builtin_help_obj }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_input), (mp_obj_t)&mp_builtin_input_obj }, \
// extra built in modules to add to the list of known ones
extern const struct _mp_obj_module_t os_module;
extern const struct _mp_obj_module_t pyb_module;
extern const struct _mp_obj_module_t time_module;
#define MICROPY_PORT_BUILTIN_MODULES \
{ MP_OBJ_NEW_QSTR(MP_QSTR_pyb), (mp_obj_t)&pyb_module }, \
// extra constants
#define MICROPY_PORT_CONSTANTS \
{ MP_OBJ_NEW_QSTR(MP_QSTR_pyb), (mp_obj_t)&pyb_module }, \
// type definitions for the specific machine
#define BYTES_PER_WORD (4)
#define UINT_FMT "%u"
#define INT_FMT "%d"
typedef int32_t machine_int_t; // must be pointer size
typedef uint32_t machine_uint_t; // must be pointer size
typedef unsigned int 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
typedef float machine_float_t;
machine_float_t machine_sqrt(machine_float_t x);
// 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
// We need to provide a declaration/definition of alloca()
#include <alloca.h>
// The following would be from a board specific file, if one existed
#define MICROPY_HW_BOARD_NAME "Teensy-3.1"
#define MICROPY_HW_HAS_SWITCH (0)
#define MICROPY_HW_HAS_SDCARD (0)
#define MICROPY_HW_HAS_MMA7660 (0)
#define MICROPY_HW_HAS_LIS3DSH (0)
#define MICROPY_HW_HAS_LCD (0)
#define MICROPY_HW_ENABLE_RNG (0)
#define MICROPY_HW_ENABLE_RTC (0)
#define MICROPY_HW_ENABLE_TIMER (0)
#define MICROPY_HW_ENABLE_SERVO (0)
#define MICROPY_HW_ENABLE_DAC (0)
#define MICROPY_HW_ENABLE_I2C1 (0)
#define MICROPY_HW_ENABLE_SPI1 (0)
#define MICROPY_HW_ENABLE_SPI3 (0)
#define MICROPY_HW_ENABLE_CC3K (0)
#define MICROPY_HW_LED1 (pin_C5)
#define MICROPY_HW_LED_OTYPE (GPIO_MODE_OUTPUT_PP)
#define MICROPY_HW_LED_ON(pin) (pin->gpio->PSOR = pin->pin_mask)
#define MICROPY_HW_LED_OFF(pin) (pin->gpio->PCOR = pin->pin_mask)
#if 0
// SD card detect switch
#define MICROPY_HW_SDCARD_DETECT_PIN (pin_A8)
#define MICROPY_HW_SDCARD_DETECT_PULL (GPIO_PULLUP)
#define MICROPY_HW_SDCARD_DETECT_PRESENT (GPIO_PIN_RESET)
#endif
#define MICROPY_MATH_SQRT_ASM (1)
#define MICROPY_HAL_H "teensy_hal.h"
#define MICROPY_PIN_DEFS_PORT_H "pin_defs_teensy.h"

46
teensy/pin_defs_teensy.h Normal file
View File

@ -0,0 +1,46 @@
enum {
PORT_A,
PORT_B,
PORT_C,
PORT_D,
PORT_E,
PORT_Z,
};
enum {
AF_FN_FTM,
AF_FN_I2C,
AF_FN_UART,
AF_FN_SPI
};
enum {
AF_PIN_TYPE_FTM_CH0 = 0,
AF_PIN_TYPE_FTM_CH1,
AF_PIN_TYPE_FTM_CH2,
AF_PIN_TYPE_FTM_CH3,
AF_PIN_TYPE_FTM_QD_PHA,
AF_PIN_TYPE_FTM_QD_PHB,
AF_PIN_TYPE_I2C_SDA = 0,
AF_PIN_TYPE_I2C_SCL,
AF_PIN_TYPE_SPI_MOSI = 0,
AF_PIN_TYPE_SPI_MISO,
AF_PIN_TYPE_SPI_SCK,
AF_PIN_TYPE_SPI_NSS,
AF_PIN_TYPE_UART_TX = 0,
AF_PIN_TYPE_UART_RX,
AF_PIN_TYPE_UART_CTS,
AF_PIN_TYPE_UART_RTS,
};
#define PIN_DEFS_PORT_AF_UNION \
FTM_TypeDef *FTM; \
I2C_TypeDef *I2C; \
UART_TypeDef *UART; \
SPI_TypeDef *SPI;
typedef GPIO_TypeDef pin_gpio_t;

View File

@ -20,7 +20,7 @@ Q(mma_mode)
Q(hid)
Q(time)
Q(rand)
Q(Led)
Q(LED)
Q(led)
Q(Servo)
Q(I2C)
@ -32,5 +32,63 @@ Q(analogRead)
Q(analogWrite)
Q(analogWriteResolution)
Q(analogWriteFrequency)
Q(run)
Q(on)
Q(off)
Q(toggle)
Q(readall)
Q(readline)
Q(FileIO)
Q(input)
Q(os)
Q(bootloader)
Q(unique_id)
Q(freq)
Q(repl_info)
Q(wfi)
Q(disable_irq)
Q(enable_irq)
Q(usb_mode)
Q(have_cdc)
Q(millis)
Q(udelay)
Q(UART)
// for Pin class
Q(Pin)
Q(PinAF)
Q(PinNamed)
Q(init)
Q(value)
Q(low)
Q(high)
Q(name)
Q(port)
Q(pin)
Q(mapper)
Q(dict)
Q(debug)
Q(board)
Q(cpu)
Q(IN)
Q(OUT_PP)
Q(OUT_OD)
Q(AF_PP)
Q(AF_OD)
Q(ANALOG)
Q(PULL_NONE)
Q(PULL_UP)
Q(PULL_DOWN)
// for UART class
Q(UART)
Q(baudrate)
Q(bits)
Q(stop)
Q(parity)
Q(init)
Q(deinit)
Q(all)
Q(send)
Q(recv)
Q(timeout)

View File

@ -1,2 +1,7 @@
mp_obj_t pyb_Servo(void);
void servo_init(void);
extern const mp_obj_type_t pyb_servo_type;
MP_DECLARE_CONST_FUN_OBJ(pyb_servo_set_obj);
MP_DECLARE_CONST_FUN_OBJ(pyb_pwm_set_obj);

55
teensy/teensy-pins.csv Normal file
View File

@ -0,0 +1,55 @@
D0,PTB16
D1,PTB17
D2,PTD0
D3,PTA12
D4,PTA13
D5,PTD7
D6,PTD4
D7,PTD2
D8,PTD3
D9,PTC3
D10,PTC4
D11,PTC6
D12,PTC7
D13,PTC5
D14,PTD1
D15,PTC0
D16,PTB0
D17,PTB1
D18,PTB3
D19,PTB2
D20,PTD5
D21,PTD6
D22,PTC1
D23,PTC2
D24,PTA5
D25,PTB19
D26,PTE1
D27,PTC9
D28,PTC8
D29,PTC10
D30,PTC11
D31,PTE0
D32,PTB18
D33,PTA4
A0,PTD1
A1,PTC0
A2,PTB0
A3,PTB1
A4,PTB3
A5,PTB2
A6,PTD5
A7,PTD6
A8,PTC1
A9,PTC2
A10,PTZ0
A11,PTZ1
A12,PTZ2
A13,PTZ3
A14,PTZ5
A15,PTE1
A16,PTC9
A17,PTC8
A18,PTC10
A19,PTC11
A20,PTE0
1 D0 PTB16
2 D1 PTB17
3 D2 PTD0
4 D3 PTA12
5 D4 PTA13
6 D5 PTD7
7 D6 PTD4
8 D7 PTD2
9 D8 PTD3
10 D9 PTC3
11 D10 PTC4
12 D11 PTC6
13 D12 PTC7
14 D13 PTC5
15 D14 PTD1
16 D15 PTC0
17 D16 PTB0
18 D17 PTB1
19 D18 PTB3
20 D19 PTB2
21 D20 PTD5
22 D21 PTD6
23 D22 PTC1
24 D23 PTC2
25 D24 PTA5
26 D25 PTB19
27 D26 PTE1
28 D27 PTC9
29 D28 PTC8
30 D29 PTC10
31 D30 PTC11
32 D31 PTE0
33 D32 PTB18
34 D33 PTA4
35 A0 PTD1
36 A1 PTC0
37 A2 PTB0
38 A3 PTB1
39 A4 PTB3
40 A5 PTB2
41 A6 PTD5
42 A7 PTD6
43 A8 PTC1
44 A9 PTC2
45 A10 PTZ0
46 A11 PTZ1
47 A12 PTZ2
48 A13 PTZ3
49 A14 PTZ5
50 A15 PTE1
51 A16 PTC9
52 A17 PTC8
53 A18 PTC10
54 A19 PTC11
55 A20 PTE0

16
teensy/teensy_hal.c Normal file
View File

@ -0,0 +1,16 @@
#include <stdio.h>
#include <stdint.h>
#include "mpconfig.h"
#include "Arduino.h"
#include MICROPY_HAL_H
uint32_t HAL_GetTick(void) {
return micros();
}
void HAL_Delay(uint32_t Delay) {
delay(Delay);
}

111
teensy/teensy_hal.h Normal file
View File

@ -0,0 +1,111 @@
#ifdef USE_FULL_ASSERT
#define assert_param(expr) ((expr) ? (void)0 : assert_failed((uint8_t *)__FILE__, __LINE__))
void assert_failed(uint8_t* file, uint32_t line);
#else
#define assert_param(expr) ((void)0)
#endif /* USE_FULL_ASSERT */
#define FTM0 ((FTM_TypeDef *)&FTM0_SC)
#define FTM1 ((FTM_TypeDef *)&FTM1_SC)
#define FTM2 ((FTM_TypeDef *)&FTM2_SC)
#define GPIOA ((GPIO_TypeDef *)&GPIOA_PDOR)
#define GPIOB ((GPIO_TypeDef *)&GPIOB_PDOR)
#define GPIOC ((GPIO_TypeDef *)&GPIOC_PDOR)
#define GPIOD ((GPIO_TypeDef *)&GPIOD_PDOR)
#define GPIOE ((GPIO_TypeDef *)&GPIOE_PDOR)
#define GPIOZ ((GPIO_TypeDef *)NULL)
#define I2C0 ((I2C_TypeDef *)0x40066000)
#define I2C1 ((I2C_TypeDef *)0x40067000)
#undef SPI0
#define SPI0 ((SPI_TypeDef *)0x4002C000)
#define SPI1 ((SPI_TypeDef *)0x4002D000)
#define UART0 ((UART_TypeDef *)&UART0_BDH)
#define UART1 ((UART_TypeDef *)&UART1_BDH)
#define UART2 ((UART_TypeDef *)&UART2_BDH)
typedef struct {
uint32_t dummy;
} FTM_TypeDef;
typedef struct {
uint32_t dummy;
} I2C_TypeDef;
typedef struct {
uint32_t dummy;
} UART_TypeDef;
typedef struct {
uint32_t dummy;
} SPI_TypeDef;
typedef struct {
volatile uint32_t PDOR; // Output register
volatile uint32_t PSOR; // Set output register
volatile uint32_t PCOR; // Clear output register
volatile uint32_t PTOR; // Toggle output register
volatile uint32_t PDIR; // Data Input register
volatile uint32_t PDDR; // Data Direction register
} GPIO_TypeDef;
#define GPIO_OUTPUT_TYPE ((uint32_t)0x00000010) // Indicates OD
#define GPIO_MODE_INPUT ((uint32_t)0x00000000)
#define GPIO_MODE_OUTPUT_PP ((uint32_t)0x00000001)
#define GPIO_MODE_OUTPUT_OD ((uint32_t)0x00000011)
#define GPIO_MODE_AF_PP ((uint32_t)0x00000002)
#define GPIO_MODE_AF_OD ((uint32_t)0x00000012)
#define GPIO_MODE_ANALOG ((uint32_t)0x00000003)
#define IS_GPIO_MODE(MODE) (((MODE) == GPIO_MODE_INPUT) ||\
((MODE) == GPIO_MODE_OUTPUT_PP) ||\
((MODE) == GPIO_MODE_OUTPUT_OD) ||\
((MODE) == GPIO_MODE_AF_PP) ||\
((MODE) == GPIO_MODE_AF_OD) ||\
((MODE) == GPIO_MODE_ANALOG))
#define GPIO_NOPULL ((uint32_t)0)
#define GPIO_PULLUP ((uint32_t)1)
#define GPIO_PULLDOWN ((uint32_t)2)
#define IS_GPIO_PULL(PULL) (((PULL) == GPIO_NOPULL) || ((PULL) == GPIO_PULLUP) || \
((PULL) == GPIO_PULLDOWN))
#define GPIO_SPEED_LOW ((uint32_t)0)
#define GPIO_SPEED_MEDIUM ((uint32_t)1)
#define GPIO_SPEED_FAST ((uint32_t)2)
#define GPIO_SPEED_HIGH ((uint32_t)3)
typedef struct {
uint32_t Pin;
uint32_t Mode;
uint32_t Pull;
uint32_t Speed;
uint32_t Alternate;
} GPIO_InitTypeDef;
#define GPIO_PORT_TO_PORT_NUM(GPIOx) \
((GPIOx->PDOR - GPIOA_PDOR) / (GPIOB_PDOR - GPIOA_PDOR))
#define GPIO_PIN_TO_PORT_PCR(GPIOx, pin) \
(&PORTA_PCR0 + GPIO_PORT_TO_PORT_NUM(GPIOx) * 32 + (pin))
__attribute__(( always_inline )) static inline void __WFI(void)
{
__asm volatile ("wfi");
}
uint32_t HAL_GetTick(void);
void HAL_Delay(uint32_t Delay);
void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *init);
#define GPIO_read_pin(gpio, pin) (((gpio)->PDIR >> (pin)) & 1)
#define GPIO_set_pin(gpio, pin_mask) (((gpio)->PSOR) = (pin_mask))
#define GPIO_clear_pin(gpio, pin_mask) (((gpio)->PCOR) = (pin_mask))

522
teensy/uart.c Normal file
View File

@ -0,0 +1,522 @@
/*
* 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 <string.h>
#include "mpconfig.h"
#include "nlr.h"
#include "misc.h"
#include "qstr.h"
#include "obj.h"
#include "runtime.h"
#include MICROPY_HAL_H
#include "bufhelper.h"
#include "uart.h"
/// \moduleref pyb
/// \class UART - duplex serial communication bus
///
/// UART implements the standard UART/USART duplex serial communications protocol. At
/// the physical level it consists of 2 lines: RX and TX.
///
/// See usage model of I2C. UART is very similar. Main difference is
/// parameters to init the UART bus:
///
/// from pyb import UART
///
/// uart = UART(1, 9600) # init with given baudrate
/// uart.init(9600, bits=8, stop=1, parity=None) # init with given parameters
///
/// Bits can be 8 or 9, stop can be 1 or 2, parity can be None, 0 (even), 1 (odd).
///
/// Extra method:
///
/// uart.any() # returns True if any characters waiting
struct _pyb_uart_obj_t {
mp_obj_base_t base;
pyb_uart_t uart_id;
bool is_enabled;
// UART_HandleTypeDef uart;
};
pyb_uart_obj_t *pyb_uart_global_debug = NULL;
// assumes Init parameters have been set up correctly
bool uart_init2(pyb_uart_obj_t *uart_obj) {
#if 0
USART_TypeDef *UARTx = NULL;
uint32_t GPIO_Pin = 0;
uint8_t GPIO_AF_UARTx = 0;
GPIO_TypeDef* GPIO_Port = NULL;
switch (uart_obj->uart_id) {
// USART1 is on PA9/PA10 (CK on PA8), PB6/PB7
case PYB_UART_1:
UARTx = USART1;
GPIO_AF_UARTx = GPIO_AF7_USART1;
#if defined (PYBV4) || defined(PYBV10)
GPIO_Port = GPIOB;
GPIO_Pin = GPIO_PIN_6 | GPIO_PIN_7;
#else
GPIO_Port = GPIOA;
GPIO_Pin = GPIO_PIN_9 | GPIO_PIN_10;
#endif
__USART1_CLK_ENABLE();
break;
// USART2 is on PA2/PA3 (CK on PA4), PD5/PD6 (CK on PD7)
case PYB_UART_2:
UARTx = USART2;
GPIO_AF_UARTx = GPIO_AF7_USART2;
GPIO_Port = GPIOA;
GPIO_Pin = GPIO_PIN_2 | GPIO_PIN_3;
__USART2_CLK_ENABLE();
break;
// USART3 is on PB10/PB11 (CK on PB12), PC10/PC11 (CK on PC12), PD8/PD9 (CK on PD10)
case PYB_UART_3:
UARTx = USART3;
GPIO_AF_UARTx = GPIO_AF7_USART3;
#if defined(PYBV3) || defined(PYBV4) | defined(PYBV10)
GPIO_Port = GPIOB;
GPIO_Pin = GPIO_PIN_10 | GPIO_PIN_11;
#else
GPIO_Port = GPIOD;
GPIO_Pin = GPIO_PIN_8 | GPIO_PIN_9;
#endif
__USART3_CLK_ENABLE();
break;
// UART4 is on PA0/PA1, PC10/PC11
case PYB_UART_4:
UARTx = UART4;
GPIO_AF_UARTx = GPIO_AF8_UART4;
GPIO_Port = GPIOA;
GPIO_Pin = GPIO_PIN_0 | GPIO_PIN_1;
__UART4_CLK_ENABLE();
break;
// USART6 is on PC6/PC7 (CK on PC8)
case PYB_UART_6:
UARTx = USART6;
GPIO_AF_UARTx = GPIO_AF8_USART6;
GPIO_Port = GPIOC;
GPIO_Pin = GPIO_PIN_6 | GPIO_PIN_7;
__USART6_CLK_ENABLE();
break;
default:
return false;
}
// init GPIO
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.Pin = GPIO_Pin;
GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.Pull = GPIO_PULLUP;
GPIO_InitStructure.Alternate = GPIO_AF_UARTx;
HAL_GPIO_Init(GPIO_Port, &GPIO_InitStructure);
// init UARTx
uart_obj->uart.Instance = UARTx;
HAL_UART_Init(&uart_obj->uart);
uart_obj->is_enabled = true;
#endif
return true;
}
bool uart_init(pyb_uart_obj_t *uart_obj, uint32_t baudrate) {
#if 0
UART_HandleTypeDef *uh = &uart_obj->uart;
memset(uh, 0, sizeof(*uh));
uh->Init.BaudRate = baudrate;
uh->Init.WordLength = UART_WORDLENGTH_8B;
uh->Init.StopBits = UART_STOPBITS_1;
uh->Init.Parity = UART_PARITY_NONE;
uh->Init.Mode = UART_MODE_TX_RX;
uh->Init.HwFlowCtl = UART_HWCONTROL_NONE;
uh->Init.OverSampling = UART_OVERSAMPLING_16;
#endif
return uart_init2(uart_obj);
}
void uart_deinit(pyb_uart_obj_t *uart_obj) {
#if 0
uart_obj->is_enabled = false;
UART_HandleTypeDef *uart = &uart_obj->uart;
HAL_UART_DeInit(uart);
if (uart->Instance == USART1) {
__USART1_FORCE_RESET();
__USART1_RELEASE_RESET();
__USART1_CLK_DISABLE();
} else if (uart->Instance == USART2) {
__USART2_FORCE_RESET();
__USART2_RELEASE_RESET();
__USART2_CLK_DISABLE();
} else if (uart->Instance == USART3) {
__USART3_FORCE_RESET();
__USART3_RELEASE_RESET();
__USART3_CLK_DISABLE();
} else if (uart->Instance == UART4) {
__UART4_FORCE_RESET();
__UART4_RELEASE_RESET();
__UART4_CLK_DISABLE();
} else if (uart->Instance == USART6) {
__USART6_FORCE_RESET();
__USART6_RELEASE_RESET();
__USART6_CLK_DISABLE();
}
#endif
}
bool uart_rx_any(pyb_uart_obj_t *uart_obj) {
#if 0
return __HAL_UART_GET_FLAG(&uart_obj->uart, UART_FLAG_RXNE);
#else
return false;
#endif
}
int uart_rx_char(pyb_uart_obj_t *uart_obj) {
uint8_t ch;
#if 0
if (HAL_UART_Receive(&uart_obj->uart, &ch, 1, 0) != HAL_OK) {
ch = 0;
}
#else
ch = 'A';
#endif
return ch;
}
void uart_tx_char(pyb_uart_obj_t *uart_obj, int c) {
#if 0
uint8_t ch = c;
HAL_UART_Transmit(&uart_obj->uart, &ch, 1, 100000);
#endif
}
void uart_tx_str(pyb_uart_obj_t *uart_obj, const char *str) {
#if 0
HAL_UART_Transmit(&uart_obj->uart, (uint8_t*)str, strlen(str), 100000);
#endif
}
void uart_tx_strn(pyb_uart_obj_t *uart_obj, const char *str, uint len) {
#if 0
HAL_UART_Transmit(&uart_obj->uart, (uint8_t*)str, len, 100000);
#endif
}
void uart_tx_strn_cooked(pyb_uart_obj_t *uart_obj, const char *str, uint len) {
for (const char *top = str + len; str < top; str++) {
if (*str == '\n') {
uart_tx_char(uart_obj, '\r');
}
uart_tx_char(uart_obj, *str);
}
}
/******************************************************************************/
/* Micro Python bindings */
STATIC void pyb_uart_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
pyb_uart_obj_t *self = self_in;
if (!self->is_enabled) {
print(env, "UART(%lu)", self->uart_id);
} else {
#if 0
print(env, "UART(%lu, baudrate=%u, bits=%u, stop=%u",
self->uart_id, self->uart.Init.BaudRate,
self->uart.Init.WordLength == UART_WORDLENGTH_8B ? 8 : 9,
self->uart.Init.StopBits == UART_STOPBITS_1 ? 1 : 2);
if (self->uart.Init.Parity == UART_PARITY_NONE) {
print(env, ", parity=None)");
} else {
print(env, ", parity=%u)", self->uart.Init.Parity == UART_PARITY_EVEN ? 0 : 1);
}
#endif
}
}
/// \method init(baudrate, *, bits=8, stop=1, parity=None)
///
/// Initialise the SPI bus with the given parameters:
///
/// - `baudrate` is the clock rate.
/// - `bits` is the number of bits per byte, 8 or 9.
/// - `stop` is the number of stop bits, 1 or 2.
/// - `parity` is the parity, `None`, 0 (even) or 1 (odd).
STATIC const mp_arg_t pyb_uart_init_args[] = {
{ MP_QSTR_baudrate, MP_ARG_REQUIRED | MP_ARG_INT, {.u_int = 9600} },
{ MP_QSTR_bits, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 8} },
{ MP_QSTR_stop, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
{ MP_QSTR_parity, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
};
#define PYB_UART_INIT_NUM_ARGS ARRAY_SIZE(pyb_uart_init_args)
STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
// parse args
mp_arg_val_t vals[PYB_UART_INIT_NUM_ARGS];
mp_arg_parse_all(n_args, args, kw_args, PYB_UART_INIT_NUM_ARGS, pyb_uart_init_args, vals);
#if 0
// set the UART configuration values
memset(&self->uart, 0, sizeof(self->uart));
UART_InitTypeDef *init = &self->uart.Init;
init->BaudRate = vals[0].u_int;
init->WordLength = vals[1].u_int == 8 ? UART_WORDLENGTH_8B : UART_WORDLENGTH_9B;
switch (vals[2].u_int) {
case 1: init->StopBits = UART_STOPBITS_1; break;
default: init->StopBits = UART_STOPBITS_2; break;
}
if (vals[3].u_obj == mp_const_none) {
init->Parity = UART_PARITY_NONE;
} else {
machine_int_t parity = mp_obj_get_int(vals[3].u_obj);
init->Parity = (parity & 1) ? UART_PARITY_ODD : UART_PARITY_EVEN;
}
init->Mode = UART_MODE_TX_RX;
init->HwFlowCtl = UART_HWCONTROL_NONE;
init->OverSampling = UART_OVERSAMPLING_16;
// init UART (if it fails, it's because the port doesn't exist)
if (!uart_init2(self)) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "UART port %d does not exist", self->uart_id));
}
#endif
return mp_const_none;
}
/// \classmethod \constructor(bus, ...)
///
/// Construct a UART object on the given bus. `bus` can be 1-6, or 'XA', 'XB', 'YA', or 'YB'.
/// With no additional parameters, the UART object is created but not
/// initialised (it has the settings from the last initialisation of
/// the bus, if any). If extra arguments are given, the bus is initialised.
/// See `init` for parameters of initialisation.
///
/// The physical pins of the UART busses are:
///
/// - `UART(4)` is on `XA`: `(TX, RX) = (X1, X2) = (PA0, PA1)`
/// - `UART(1)` is on `XB`: `(TX, RX) = (X9, X10) = (PB6, PB7)`
/// - `UART(6)` is on `YA`: `(TX, RX) = (Y1, Y2) = (PC6, PC7)`
/// - `UART(3)` is on `YB`: `(TX, RX) = (Y9, Y10) = (PB10, PB11)`
/// - `UART(2)` is on: `(TX, RX) = (X3, X4) = (PA2, PA3)`
STATIC mp_obj_t pyb_uart_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, MP_OBJ_FUN_ARGS_MAX, true);
// create object
pyb_uart_obj_t *o = m_new_obj(pyb_uart_obj_t);
o->base.type = &pyb_uart_type;
// work out port
o->uart_id = 0;
#if 0
if (MP_OBJ_IS_STR(args[0])) {
const char *port = mp_obj_str_get_str(args[0]);
if (0) {
#if defined(PYBV10)
} else if (strcmp(port, "XA") == 0) {
o->uart_id = PYB_UART_XA;
} else if (strcmp(port, "XB") == 0) {
o->uart_id = PYB_UART_XB;
} else if (strcmp(port, "YA") == 0) {
o->uart_id = PYB_UART_YA;
} else if (strcmp(port, "YB") == 0) {
o->uart_id = PYB_UART_YB;
#endif
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "UART port %s does not exist", port));
}
} else {
o->uart_id = mp_obj_get_int(args[0]);
}
#endif
if (n_args > 1 || n_kw > 0) {
// start the peripheral
mp_map_t kw_args;
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
pyb_uart_init_helper(o, n_args - 1, args + 1, &kw_args);
}
return o;
}
STATIC mp_obj_t pyb_uart_init(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
return pyb_uart_init_helper(args[0], n_args - 1, args + 1, kw_args);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_uart_init_obj, 1, pyb_uart_init);
/// \method deinit()
/// Turn off the UART bus.
STATIC mp_obj_t pyb_uart_deinit(mp_obj_t self_in) {
pyb_uart_obj_t *self = self_in;
uart_deinit(self);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_deinit_obj, pyb_uart_deinit);
/// \method any()
/// Return `True` if any characters waiting, else `False`.
STATIC mp_obj_t pyb_uart_any(mp_obj_t self_in) {
pyb_uart_obj_t *self = self_in;
if (uart_rx_any(self)) {
return mp_const_true;
} else {
return mp_const_false;
}
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_any_obj, pyb_uart_any);
/// \method send(send, *, timeout=5000)
/// Send data on the bus:
///
/// - `send` is the data to send (an integer to send, or a buffer object).
/// - `timeout` is the timeout in milliseconds to wait for the send.
///
/// Return value: `None`.
STATIC const mp_arg_t pyb_uart_send_args[] = {
{ MP_QSTR_send, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5000} },
};
#define PYB_UART_SEND_NUM_ARGS ARRAY_SIZE(pyb_uart_send_args)
STATIC mp_obj_t pyb_uart_send(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
// TODO assumes transmission size is 8-bits wide
pyb_uart_obj_t *self = args[0];
// parse args
mp_arg_val_t vals[PYB_UART_SEND_NUM_ARGS];
mp_arg_parse_all(n_args - 1, args + 1, kw_args, PYB_UART_SEND_NUM_ARGS, pyb_uart_send_args, vals);
#if 0
// get the buffer to send from
mp_buffer_info_t bufinfo;
uint8_t data[1];
pyb_buf_get_for_send(vals[0].u_obj, &bufinfo, data);
// send the data
HAL_StatusTypeDef status = HAL_UART_Transmit(&self->uart, bufinfo.buf, bufinfo.len, vals[1].u_int);
if (status != HAL_OK) {
// TODO really need a HardwareError object, or something
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_Exception, "HAL_UART_Transmit failed with code %d", status));
}
#else
(void)self;
#endif
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_uart_send_obj, 1, pyb_uart_send);
/// \method recv(recv, *, timeout=5000)
///
/// Receive data on the bus:
///
/// - `recv` can be an integer, which is the number of bytes to receive,
/// or a mutable buffer, which will be filled with received bytes.
/// - `timeout` is the timeout in milliseconds to wait for the receive.
///
/// Return value: if `recv` is an integer then a new buffer of the bytes received,
/// otherwise the same buffer that was passed in to `recv`.
STATIC const mp_arg_t pyb_uart_recv_args[] = {
{ MP_QSTR_recv, MP_ARG_REQUIRED | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 5000} },
};
#define PYB_UART_RECV_NUM_ARGS ARRAY_SIZE(pyb_uart_recv_args)
STATIC mp_obj_t pyb_uart_recv(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) {
// TODO assumes transmission size is 8-bits wide
pyb_uart_obj_t *self = args[0];
#if 0
// parse args
mp_arg_val_t vals[PYB_UART_RECV_NUM_ARGS];
mp_arg_parse_all(n_args - 1, args + 1, kw_args, PYB_UART_RECV_NUM_ARGS, pyb_uart_recv_args, vals);
// get the buffer to receive into
mp_buffer_info_t bufinfo;
mp_obj_t o_ret = pyb_buf_get_for_recv(vals[0].u_obj, &bufinfo);
// receive the data
HAL_StatusTypeDef status = HAL_UART_Receive(&self->uart, bufinfo.buf, bufinfo.len, vals[1].u_int);
if (status != HAL_OK) {
// TODO really need a HardwareError object, or something
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_Exception, "HAL_UART_Receive failed with code %d", status));
}
// return the received data
if (o_ret == MP_OBJ_NULL) {
return vals[0].u_obj;
} else {
return mp_obj_str_builder_end(o_ret);
}
#else
(void)self;
return mp_const_none;
#endif
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_uart_recv_obj, 1, pyb_uart_recv);
STATIC const mp_map_elem_t pyb_uart_locals_dict_table[] = {
// instance methods
{ MP_OBJ_NEW_QSTR(MP_QSTR_init), (mp_obj_t)&pyb_uart_init_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_deinit), (mp_obj_t)&pyb_uart_deinit_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_any), (mp_obj_t)&pyb_uart_any_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_send), (mp_obj_t)&pyb_uart_send_obj },
{ MP_OBJ_NEW_QSTR(MP_QSTR_recv), (mp_obj_t)&pyb_uart_recv_obj },
};
STATIC MP_DEFINE_CONST_DICT(pyb_uart_locals_dict, pyb_uart_locals_dict_table);
const mp_obj_type_t pyb_uart_type = {
{ &mp_type_type },
.name = MP_QSTR_UART,
.print = pyb_uart_print,
.make_new = pyb_uart_make_new,
.locals_dict = (mp_obj_t)&pyb_uart_locals_dict,
};

View File

@ -1,38 +0,0 @@
#include "misc.h"
#include "mpconfig.h"
#include "qstr.h"
#include "obj.h"
#include "../stm/usart.h"
pyb_usart_t pyb_usart_global_debug = PYB_USART_NONE;
void usart_init(pyb_usart_t usart_id, uint32_t baudrate)
{
(void)usart_id;
(void)baudrate;
}
bool usart_rx_any(pyb_usart_t usart_id)
{
(void)usart_id;
return false;
}
int usart_rx_char(pyb_usart_t usart_id)
{
(void)usart_id;
return 0;
}
void usart_tx_str(pyb_usart_t usart_id, const char *str)
{
(void)usart_id;
(void)str;
}
void usart_tx_strn_cooked(pyb_usart_t usart_id, const char *str, int len)
{
(void)usart_id;
(void)str;
(void)len;
}

View File

@ -13,8 +13,13 @@ int usb_vcp_is_enabled(void)
return 1;
}
int usb_vcp_rx_any(void)
{
void usb_vcp_set_interrupt_char(int c) {
// The teensy 3.1 usb stack doesn't currently have the notion of generating
// an exception when a certain character is received. That just means that
// you can't press Control-C and get your python script to stop.
}
int usb_vcp_rx_num(void) {
return usb_serial_available();
}