Merge branch 'teensy-new' of github.com:dhylands/micropython into dhylands-teensy-new
Conflicts: stmhal/pin_named_pins.c stmhal/readline.c Renamed HAL_H to MICROPY_HAL_H. Made stmhal/mphal.h which intends to define the generic Micro Python HAL, which in stmhal sits above the ST HAL.
This commit is contained in:
commit
7a37f647a5
|
@ -97,4 +97,10 @@ print-cfg:
|
|||
$(ECHO) "OBJ = $(OBJ)"
|
||||
.PHONY: print-cfg
|
||||
|
||||
print-def:
|
||||
@$(ECHO) "The following defines are built into the $(CC) compiler"
|
||||
touch __empty__.c
|
||||
@$(CC) -E -Wp,-dM __empty__.c
|
||||
@$(RM) -f __empty__.c
|
||||
|
||||
-include $(OBJ:.o=.P)
|
||||
|
|
|
@ -25,8 +25,7 @@
|
|||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <stm32f4xx_hal.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "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);
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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))
|
13
stmhal/pin.c
13
stmhal/pin.c
|
@ -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);
|
||||
|
|
80
stmhal/pin.h
80
stmhal/pin.h
|
@ -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;
|
||||
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
// This file contains pin definitions that are specific to the stmhal port.
|
||||
// This file should only ever be #included by pin.h and not directly.
|
||||
|
||||
enum {
|
||||
PORT_A,
|
||||
PORT_B,
|
||||
PORT_C,
|
||||
PORT_D,
|
||||
PORT_E,
|
||||
PORT_F,
|
||||
PORT_G,
|
||||
PORT_H,
|
||||
PORT_I,
|
||||
PORT_J,
|
||||
};
|
||||
|
||||
enum {
|
||||
AF_FN_TIM,
|
||||
AF_FN_I2C,
|
||||
AF_FN_USART,
|
||||
AF_FN_UART = AF_FN_USART,
|
||||
AF_FN_SPI
|
||||
};
|
||||
|
||||
enum {
|
||||
AF_PIN_TYPE_TIM_CH1 = 0,
|
||||
AF_PIN_TYPE_TIM_CH2,
|
||||
AF_PIN_TYPE_TIM_CH3,
|
||||
AF_PIN_TYPE_TIM_CH4,
|
||||
AF_PIN_TYPE_TIM_CH1N,
|
||||
AF_PIN_TYPE_TIM_CH2N,
|
||||
AF_PIN_TYPE_TIM_CH3N,
|
||||
AF_PIN_TYPE_TIM_CH1_ETR,
|
||||
AF_PIN_TYPE_TIM_ETR,
|
||||
AF_PIN_TYPE_TIM_BKIN,
|
||||
|
||||
AF_PIN_TYPE_I2C_SDA = 0,
|
||||
AF_PIN_TYPE_I2C_SCL,
|
||||
|
||||
AF_PIN_TYPE_USART_TX = 0,
|
||||
AF_PIN_TYPE_USART_RX,
|
||||
AF_PIN_TYPE_USART_CTS,
|
||||
AF_PIN_TYPE_USART_RTS,
|
||||
AF_PIN_TYPE_USART_CK,
|
||||
AF_PIN_TYPE_UART_TX = AF_PIN_TYPE_USART_TX,
|
||||
AF_PIN_TYPE_UART_RX = AF_PIN_TYPE_USART_RX,
|
||||
AF_PIN_TYPE_UART_CTS = AF_PIN_TYPE_USART_CTS,
|
||||
AF_PIN_TYPE_UART_RTS = AF_PIN_TYPE_USART_RTS,
|
||||
|
||||
AF_PIN_TYPE_SPI_MOSI = 0,
|
||||
AF_PIN_TYPE_SPI_MISO,
|
||||
AF_PIN_TYPE_SPI_SCK,
|
||||
AF_PIN_TYPE_SPI_NSS,
|
||||
};
|
||||
|
||||
enum {
|
||||
PIN_ADC1 = (1 << 0),
|
||||
PIN_ADC2 = (1 << 1),
|
||||
PIN_ADC3 = (1 << 2),
|
||||
};
|
||||
|
||||
#define PIN_DEFS_PORT_AF_UNION \
|
||||
TIM_TypeDef *TIM; \
|
||||
I2C_TypeDef *I2C; \
|
||||
USART_TypeDef *USART; \
|
||||
USART_TypeDef *UART; \
|
||||
SPI_TypeDef *SPI;
|
||||
|
||||
typedef GPIO_TypeDef pin_gpio_t;
|
||||
|
|
@ -28,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) {
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
#include <stdint.h>
|
||||
#include <mk20dx128.h>
|
||||
#include "teensy_hal.h"
|
||||
|
||||
#define GPIO_NUMBER 32
|
||||
|
||||
void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
|
||||
{
|
||||
/* Check the parameters */
|
||||
assert_param(IS_GPIO_PIN(GPIO_Init->Pin));
|
||||
assert_param(IS_GPIO_MODE(GPIO_Init->Mode));
|
||||
assert_param(IS_GPIO_PULL(GPIO_Init->Pull));
|
||||
|
||||
/* Configure the port pins */
|
||||
for (uint32_t position = 0; position < GPIO_NUMBER; position++) {
|
||||
uint32_t bitmask = 1 << position;
|
||||
if ((GPIO_Init->Pin & bitmask) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
volatile uint32_t *port_pcr = GPIO_PIN_TO_PORT_PCR(GPIOx, position);
|
||||
|
||||
/*--------------------- GPIO Mode Configuration ------------------------*/
|
||||
/* In case of Alternate function mode selection */
|
||||
if ((GPIO_Init->Mode == GPIO_MODE_AF_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_OD)) {
|
||||
/* Check the Alternate function parameter */
|
||||
assert_param(IS_GPIO_AF(GPIO_Init->Alternate));
|
||||
/* Configure Alternate function mapped with the current IO */
|
||||
|
||||
*port_pcr &= ~PORT_PCR_MUX_MASK;
|
||||
*port_pcr |= PORT_PCR_MUX(GPIO_Init->Alternate);
|
||||
}
|
||||
|
||||
/* Configure IO Direction mode (Input, Output, Alternate or Analog) */
|
||||
if (GPIO_Init->Mode == GPIO_MODE_INPUT || GPIO_Init->Mode == GPIO_MODE_ANALOG) {
|
||||
GPIOx->PDDR &= ~bitmask;
|
||||
} else {
|
||||
GPIOx->PDDR |= bitmask;
|
||||
}
|
||||
|
||||
/* In case of Output or Alternate function mode selection */
|
||||
if ((GPIO_Init->Mode == GPIO_MODE_OUTPUT_PP) || (GPIO_Init->Mode == GPIO_MODE_AF_PP) ||
|
||||
(GPIO_Init->Mode == GPIO_MODE_OUTPUT_OD) || (GPIO_Init->Mode == GPIO_MODE_AF_OD)) {
|
||||
/* Check the Speed parameter */
|
||||
assert_param(IS_GPIO_SPEED(GPIO_Init->Speed));
|
||||
|
||||
/* Configure the IO Speed */
|
||||
if (GPIO_Init->Speed > GPIO_SPEED_MEDIUM) {
|
||||
*port_pcr &= ~PORT_PCR_SRE;
|
||||
} else {
|
||||
*port_pcr |= PORT_PCR_SRE;
|
||||
}
|
||||
|
||||
/* Configure the IO Output Type */
|
||||
if (GPIO_Init->Mode & GPIO_OUTPUT_TYPE) {
|
||||
*port_pcr |= PORT_PCR_ODE;
|
||||
} else {
|
||||
*port_pcr &= ~PORT_PCR_ODE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Activate the Pull-up or Pull down resistor for the current IO */
|
||||
if (GPIO_Init->Pull == GPIO_NOPULL) {
|
||||
*port_pcr &= ~PORT_PCR_PE;
|
||||
} else {
|
||||
*port_pcr |= PORT_PCR_PE;
|
||||
if (GPIO_Init->Pull == GPIO_PULLDOWN) {
|
||||
*port_pcr &= ~PORT_PCR_PS;
|
||||
} else {
|
||||
*port_pcr |= PORT_PCR_PS;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*--------------------- EXTI Mode Configuration ------------------------*/
|
||||
/* Configure the External Interrupt or event for the current IO */
|
||||
if((GPIO_Init->Mode & EXTI_MODE) == EXTI_MODE)
|
||||
{
|
||||
/* Enable SYSCFG Clock */
|
||||
__SYSCFG_CLK_ENABLE();
|
||||
|
||||
temp = ((uint32_t)0x0F) << (4 * (position & 0x03));
|
||||
SYSCFG->EXTICR[position >> 2] &= ~temp;
|
||||
SYSCFG->EXTICR[position >> 2] |= ((uint32_t)(__HAL_GET_GPIO_SOURCE(GPIOx)) << (4 * (position & 0x03)));
|
||||
|
||||
/* Clear EXTI line configuration */
|
||||
EXTI->IMR &= ~((uint32_t)iocurrent);
|
||||
EXTI->EMR &= ~((uint32_t)iocurrent);
|
||||
|
||||
if((GPIO_Init->Mode & GPIO_MODE_IT) == GPIO_MODE_IT)
|
||||
{
|
||||
EXTI->IMR |= iocurrent;
|
||||
}
|
||||
if((GPIO_Init->Mode & GPIO_MODE_EVT) == GPIO_MODE_EVT)
|
||||
{
|
||||
EXTI->EMR |= iocurrent;
|
||||
}
|
||||
|
||||
/* Clear Rising Falling edge configuration */
|
||||
EXTI->RTSR &= ~((uint32_t)iocurrent);
|
||||
EXTI->FTSR &= ~((uint32_t)iocurrent);
|
||||
|
||||
if((GPIO_Init->Mode & RISING_EDGE) == RISING_EDGE)
|
||||
{
|
||||
EXTI->RTSR |= iocurrent;
|
||||
}
|
||||
if((GPIO_Init->Mode & FALLING_EDGE) == FALLING_EDGE)
|
||||
{
|
||||
EXTI->FTSR |= iocurrent;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "mpconfig.h"
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "qstr.h"
|
||||
#include "obj.h"
|
||||
|
||||
STATIC const char *help_text =
|
||||
"Welcome to Micro Python!\n"
|
||||
"\n"
|
||||
"For online help please visit http://micropython.org/help/.\n"
|
||||
"\n"
|
||||
"Quick overview of commands for the board:\n"
|
||||
" pyb.info() -- print some general information\n"
|
||||
" pyb.gc() -- run the garbage collector\n"
|
||||
" pyb.delay(n) -- wait for n milliseconds\n"
|
||||
" pyb.Switch() -- create a switch object\n"
|
||||
" Switch methods: (), callback(f)\n"
|
||||
" pyb.LED(n) -- create an LED object for LED n (n=1,2,3,4)\n"
|
||||
" LED methods: on(), off(), toggle(), intensity(<n>)\n"
|
||||
" pyb.Pin(pin) -- get a pin, eg pyb.Pin('X1')\n"
|
||||
" pyb.Pin(pin, m, [p]) -- get a pin and configure it for IO mode m, pull mode p\n"
|
||||
" Pin methods: init(..), value([v]), high(), low()\n"
|
||||
" pyb.ExtInt(pin, m, p, callback) -- create an external interrupt object\n"
|
||||
" pyb.ADC(pin) -- make an analog object from a pin\n"
|
||||
" ADC methods: read(), read_timed(buf, freq)\n"
|
||||
" pyb.DAC(port) -- make a DAC object\n"
|
||||
" DAC methods: triangle(freq), write(n), write_timed(buf, freq)\n"
|
||||
" pyb.RTC() -- make an RTC object; methods: datetime([val])\n"
|
||||
" pyb.rng() -- get a 30-bit hardware random number\n"
|
||||
" pyb.Servo(n) -- create Servo object for servo n (n=1,2,3,4)\n"
|
||||
" Servo methods: calibration(..), angle([x, [t]]), speed([x, [t]])\n"
|
||||
" pyb.Accel() -- create an Accelerometer object\n"
|
||||
" Accelerometer methods: x(), y(), z(), tilt(), filtered_xyz()\n"
|
||||
"\n"
|
||||
"Pins are numbered X1-X12, X17-X22, Y1-Y12, or by their MCU name\n"
|
||||
"Pin IO modes are: pyb.Pin.IN, pyb.Pin.OUT_PP, pyb.Pin.OUT_OD\n"
|
||||
"Pin pull modes are: pyb.Pin.PULL_NONE, pyb.Pin.PULL_UP, pyb.Pin.PULL_DOWN\n"
|
||||
"Additional serial bus objects: pyb.I2C(n), pyb.SPI(n), pyb.UART(n)\n"
|
||||
"\n"
|
||||
"Control commands:\n"
|
||||
" CTRL-A -- on a blank line, enter raw REPL mode\n"
|
||||
" CTRL-B -- on a blank line, enter normal REPL mode\n"
|
||||
" CTRL-C -- interrupt a running program\n"
|
||||
" CTRL-D -- on a blank line, do a soft reset of the board\n"
|
||||
"\n"
|
||||
"For further help on a specific object, type help(obj)\n"
|
||||
;
|
||||
|
||||
STATIC void pyb_help_print_info_about_object(mp_obj_t name_o, mp_obj_t value) {
|
||||
printf(" ");
|
||||
mp_obj_print(name_o, PRINT_STR);
|
||||
printf(" -- ");
|
||||
mp_obj_print(value, PRINT_STR);
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pyb_help(uint n_args, const mp_obj_t *args) {
|
||||
if (n_args == 0) {
|
||||
// print a general help message
|
||||
printf("%s", help_text);
|
||||
|
||||
} else {
|
||||
// try to print something sensible about the given object
|
||||
|
||||
printf("object ");
|
||||
mp_obj_print(args[0], PRINT_STR);
|
||||
printf(" is of type %s\n", mp_obj_get_type_str(args[0]));
|
||||
|
||||
mp_map_t *map = NULL;
|
||||
if (MP_OBJ_IS_TYPE(args[0], &mp_type_module)) {
|
||||
map = mp_obj_dict_get_map(mp_obj_module_get_globals(args[0]));
|
||||
} else {
|
||||
mp_obj_type_t *type;
|
||||
if (MP_OBJ_IS_TYPE(args[0], &mp_type_type)) {
|
||||
type = args[0];
|
||||
} else {
|
||||
type = mp_obj_get_type(args[0]);
|
||||
}
|
||||
if (type->locals_dict != MP_OBJ_NULL && MP_OBJ_IS_TYPE(type->locals_dict, &mp_type_dict)) {
|
||||
map = mp_obj_dict_get_map(type->locals_dict);
|
||||
}
|
||||
}
|
||||
if (map != NULL) {
|
||||
for (uint i = 0; i < map->alloc; i++) {
|
||||
if (map->table[i].key != MP_OBJ_NULL) {
|
||||
pyb_help_print_info_about_object(map->table[i].key, map->table[i].value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_help_obj, 0, 1, pyb_help);
|
|
@ -0,0 +1,22 @@
|
|||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "qstr.h"
|
||||
#include "lexer.h"
|
||||
|
||||
#include "memzip.h"
|
||||
|
||||
mp_import_stat_t mp_import_stat(const char *path) {
|
||||
MEMZIP_FILE_INFO info;
|
||||
|
||||
if (memzip_stat(path, &info) != MZ_OK) {
|
||||
return MP_IMPORT_STAT_NO_EXIST;
|
||||
}
|
||||
|
||||
if (info.is_dir) {
|
||||
return MP_IMPORT_STAT_DIR;
|
||||
}
|
||||
return MP_IMPORT_STAT_FILE;
|
||||
}
|
|
@ -1,5 +1,10 @@
|
|||
#include "mpconfig.h"
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "../stm/lcd.h"
|
||||
#include "qstr.h"
|
||||
#include "parse.h"
|
||||
#include "obj.h"
|
||||
#include "../stmhal/lcd.h"
|
||||
|
||||
void lcd_init(void) {
|
||||
}
|
||||
|
|
152
teensy/led.c
152
teensy/led.c
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
typedef enum {
|
||||
PYB_LED_BUILTIN = 0,
|
||||
PYB_LED_BUILTIN = 1,
|
||||
} pyb_led_t;
|
||||
|
||||
void led_init(void);
|
||||
void led_state(pyb_led_t led, int state);
|
||||
void led_toggle(pyb_led_t led);
|
||||
|
||||
mp_obj_t pyb_Led(mp_obj_t led_id);
|
||||
extern const mp_obj_type_t pyb_led_type;
|
||||
|
|
|
@ -6,19 +6,10 @@
|
|||
#include "qstr.h"
|
||||
#include "lexer.h"
|
||||
typedef int FIL;
|
||||
#include "../stm/lexerfatfs.h"
|
||||
#include "../stmhal/lexerfatfs.h"
|
||||
|
||||
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
|
||||
printf("import not implemented\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mp_lexer_t *mp_import_open_file(qstr mod_name) {
|
||||
printf("import not implemented\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mp_import_stat_t mp_import_stat(const char *path) {
|
||||
// TODO implement me!
|
||||
return MP_IMPORT_STAT_NO_EXIST;
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include "lexer.h"
|
||||
#include "memzip.h"
|
||||
|
||||
mp_lexer_t *mp_lexer_new_from_memzip_file(const char *filename)
|
||||
mp_lexer_t *mp_lexer_new_from_file(const char *filename)
|
||||
{
|
||||
void *data;
|
||||
size_t len;
|
||||
|
|
411
teensy/main.c
411
teensy/main.c
|
@ -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);
|
||||
|
|
|
@ -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()
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
import pyb
|
||||
print("Executing boot.py")
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
@ -1 +0,0 @@
|
|||
print("Executing /src/test.py")
|
|
@ -1 +0,0 @@
|
|||
print("Executing /test.py")
|
|
@ -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,,
|
|
|
@ -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, \
|
||||
}
|
|
@ -10,10 +10,10 @@
|
|||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* 1. The above copyright notice and this permission notice shall be
|
||||
* 1. The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* 2. If the Software is incorporated into a build system that allows
|
||||
* 2. If the Software is incorporated into a build system that allows
|
||||
* selection among a list of target devices, then similar target
|
||||
* devices manufactured by PJRC.COM must be included in the list of
|
||||
* target devices and selectable in the same manner.
|
||||
|
@ -30,8 +30,8 @@
|
|||
|
||||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K
|
||||
RAM (rwx) : ORIGIN = 0x1FFF8000, LENGTH = 64K
|
||||
FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 256K
|
||||
RAM (rwx) : ORIGIN = 0x1FFF8000, LENGTH = 64K
|
||||
}
|
||||
|
||||
/* produce a link error if there is not this amount of RAM for these sections */
|
||||
|
@ -52,10 +52,10 @@ _minimum_heap_size = 16K;
|
|||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* 1. The above copyright notice and this permission notice shall be
|
||||
* 1. The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* 2. If the Software is incorporated into a build system that allows
|
||||
* 2. If the Software is incorporated into a build system that allows
|
||||
* selection among a list of target devices, then similar target
|
||||
* devices manufactured by PJRC.COM must be included in the list of
|
||||
* target devices and selectable in the same manner.
|
||||
|
@ -74,95 +74,101 @@ _minimum_heap_size = 16K;
|
|||
|
||||
SECTIONS
|
||||
{
|
||||
.text : {
|
||||
. = 0;
|
||||
KEEP(*(.vectors))
|
||||
*(.startup*)
|
||||
/* TODO: does linker detect startup overflow onto flashconfig? */
|
||||
. = 0x400;
|
||||
KEEP(*(.flashconfig*))
|
||||
*(.text*)
|
||||
*(.rodata*)
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.init))
|
||||
. = ALIGN(4);
|
||||
__preinit_array_start = .;
|
||||
KEEP (*(.preinit_array))
|
||||
__preinit_array_end = .;
|
||||
__init_array_start = .;
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array))
|
||||
__init_array_end = .;
|
||||
} > FLASH = 0xFF
|
||||
.text : {
|
||||
. = 0;
|
||||
KEEP(*(.vectors))
|
||||
*(.startup*)
|
||||
/* TODO: does linker detect startup overflow onto flashconfig? */
|
||||
. = 0x400;
|
||||
KEEP(*(.flashconfig*))
|
||||
*(.text*)
|
||||
*(.rodata*)
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.init))
|
||||
. = ALIGN(4);
|
||||
__preinit_array_start = .;
|
||||
KEEP (*(.preinit_array))
|
||||
__preinit_array_end = .;
|
||||
__init_array_start = .;
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array))
|
||||
__init_array_end = .;
|
||||
} > FLASH = 0xFF
|
||||
|
||||
.ARM.exidx : {
|
||||
__exidx_start = .;
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
__exidx_end = .;
|
||||
} > FLASH
|
||||
_etext = .;
|
||||
.ARM.exidx : {
|
||||
__exidx_start = .;
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
__exidx_end = .;
|
||||
} > FLASH
|
||||
_etext = .;
|
||||
|
||||
.usbdescriptortable (NOLOAD) : {
|
||||
/* . = ORIGIN(RAM); */
|
||||
. = ALIGN(512);
|
||||
*(.usbdescriptortable*)
|
||||
} > RAM
|
||||
.usbdescriptortable (NOLOAD) : {
|
||||
/* . = ORIGIN(RAM); */
|
||||
. = ALIGN(512);
|
||||
*(.usbdescriptortable*)
|
||||
} > RAM
|
||||
|
||||
.dmabuffers (NOLOAD) : {
|
||||
. = ALIGN(4);
|
||||
*(.dmabuffers*)
|
||||
} > RAM
|
||||
.dmabuffers (NOLOAD) : {
|
||||
. = ALIGN(4);
|
||||
*(.dmabuffers*)
|
||||
} > RAM
|
||||
|
||||
.usbbuffers (NOLOAD) : {
|
||||
. = ALIGN(4);
|
||||
*(.usbbuffers*)
|
||||
} > RAM
|
||||
.usbbuffers (NOLOAD) : {
|
||||
. = ALIGN(4);
|
||||
*(.usbbuffers*)
|
||||
} > RAM
|
||||
|
||||
.data : AT (_etext) {
|
||||
. = ALIGN(4);
|
||||
_sdata = .;
|
||||
*(.data*)
|
||||
. = ALIGN(4);
|
||||
_edata = .;
|
||||
} > RAM
|
||||
/* used by the startup to initialize data */
|
||||
_sidata = LOADADDR(.data);
|
||||
|
||||
/*
|
||||
* _staticfs is the place in flash where the static filesystem which
|
||||
* is concatenated to the .hex file will wind up.
|
||||
*/
|
||||
_staticfs = LOADADDR(.data) + SIZEOF(.data);
|
||||
.data : AT (_etext) {
|
||||
. = ALIGN(4);
|
||||
_sdata = .;
|
||||
_ram_start = .;
|
||||
*(.data*)
|
||||
. = ALIGN(4);
|
||||
_edata = .;
|
||||
} > RAM
|
||||
|
||||
.noinit (NOLOAD) : {
|
||||
*(.noinit*)
|
||||
} > RAM
|
||||
/*
|
||||
* _staticfs is the place in flash where the static filesystem which
|
||||
* is concatenated to the .hex file will wind up.
|
||||
*/
|
||||
_staticfs = LOADADDR(.data) + SIZEOF(.data);
|
||||
|
||||
.bss : {
|
||||
. = ALIGN(4);
|
||||
_sbss = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
_ebss = .;
|
||||
__bss_end = .;
|
||||
} > RAM
|
||||
.noinit (NOLOAD) : {
|
||||
*(.noinit*)
|
||||
} > RAM
|
||||
|
||||
/* this is to define the start of the heap, and make sure we have a minimum size */
|
||||
.heap :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_heap_start = .; /* define a global symbol at heap start */
|
||||
. = . + _minimum_heap_size;
|
||||
} >RAM
|
||||
.bss : {
|
||||
. = ALIGN(4);
|
||||
_sbss = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
_ebss = .;
|
||||
__bss_end = .;
|
||||
} > RAM
|
||||
|
||||
/* this just checks there is enough RAM for the stack */
|
||||
.stack :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
. = . + _minimum_stack_size;
|
||||
. = ALIGN(4);
|
||||
} >RAM
|
||||
/* this is to define the start of the heap, and make sure we have a minimum size */
|
||||
.heap :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
_heap_start = .; /* define a global symbol at heap start */
|
||||
. = . + _minimum_heap_size;
|
||||
} >RAM
|
||||
|
||||
_estack = ORIGIN(RAM) + LENGTH(RAM);
|
||||
/* this just checks there is enough RAM for the stack */
|
||||
.stack :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
. = . + _minimum_stack_size;
|
||||
. = ALIGN(4);
|
||||
} >RAM
|
||||
|
||||
_estack = ORIGIN(RAM) + LENGTH(RAM);
|
||||
_ram_end = ORIGIN(RAM) + LENGTH(RAM);
|
||||
_heap_end = ORIGIN(RAM) + 0xe000;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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,
|
||||
};
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
|
|
@ -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);
|
||||
}
|
|
@ -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))
|
|
@ -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,
|
||||
};
|
|
@ -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;
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue