summaryrefslogtreecommitdiffstatshomepage
path: root/teensy
diff options
context:
space:
mode:
authorDave Hylands <dhylands@gmail.com>2014-07-22 07:57:36 -0700
committerDave Hylands <dhylands@gmail.com>2014-08-07 23:15:41 -0700
commit6f418fc1b068c1a41113bb2b019a5803765e1deb (patch)
tree79477835459eb424012f58d77a150bdf9a80eed5 /teensy
parent3ef911345c94a6d612ab50c1e912e81cb2cc3f71 (diff)
downloadmicropython-6f418fc1b068c1a41113bb2b019a5803765e1deb.tar.gz
micropython-6f418fc1b068c1a41113bb2b019a5803765e1deb.zip
Add support for selecting pin alternate functions from python.
Converts generted pins to use qstrs instead of string pointers. This patch also adds the following functions: pyb.Pin.names() pyb.Pin.af_list() pyb.Pin.gpio() dir(pyb.Pin.board) and dir(pyb.Pin.cpu) also produce useful results. pyb.Pin now takes kw args. pyb.Pin.__str__ now prints more useful information about the pin configuration. I found the following functions in my boot.py to be useful: ```python def pins(): for pin_name in dir(pyb.Pin.board): pin = pyb.Pin(pin_name) print('{:10s} {:s}'.format(pin_name, str(pin))) def af(): for pin_name in dir(pyb.Pin.board): pin = pyb.Pin(pin_name) print('{:10s} {:s}'.format(pin_name, str(pin.af_list()))) ```
Diffstat (limited to 'teensy')
-rw-r--r--teensy/Makefile9
-rw-r--r--teensy/hal_gpio.c15
-rw-r--r--teensy/main.c4
-rwxr-xr-xteensy/make-pins.py67
-rw-r--r--teensy/memzip_files/boot.py10
-rw-r--r--teensy/mk20dx256-prefix.c3
-rw-r--r--teensy/pin_defs_teensy.c61
-rw-r--r--teensy/pin_defs_teensy.h1
-rw-r--r--teensy/qstrdefsport.h8
-rw-r--r--teensy/teensy_hal.h18
10 files changed, 181 insertions, 15 deletions
diff --git a/teensy/Makefile b/teensy/Makefile
index 54e6ef050e..5b8e266219 100644
--- a/teensy/Makefile
+++ b/teensy/Makefile
@@ -1,7 +1,7 @@
include ../py/mkenv.mk
# qstr definitions (must come before including py.mk)
-QSTR_DEFS = qstrdefsport.h
+QSTR_DEFS = qstrdefsport.h $(BUILD)/pins_qstr.h
# include py core make definitions
include ../py/py.mk
@@ -53,6 +53,7 @@ SRC_C = \
lexermemzip.c \
memzip.c \
modpyb.c \
+ pin_defs_teensy.c \
teensy_hal.c \
uart.c \
usb.c \
@@ -137,6 +138,8 @@ AF_FILE = mk20dx256-af.csv
PREFIX_FILE = mk20dx256-prefix.c
GEN_PINS_SRC = $(BUILD)/pins_gen.c
GEN_PINS_HDR = $(HEADER_BUILD)/pins.h
+GEN_PINS_QSTR = $(BUILD)/pins_qstr.h
+GEN_PINS_AF_CONST = $(HEADER_BUILD)/pins-af-const.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
@@ -147,9 +150,9 @@ $(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)
+$(BUILD)/%_gen.c $(HEADER_BUILD)/%.h $(HEADER_BUILD)/%-af-const.h $(BUILD)/%_qstr.h: teensy-%.csv $(MAKE_PINS) $(AF_FILE) $(PREFIX_FILE) | $(HEADER_BUILD)
$(ECHO) "Create $@"
- $(Q)$(PYTHON) $(MAKE_PINS) --board $(BOARD_PINS) --af $(AF_FILE) --prefix $(PREFIX_FILE) --hdr $(GEN_PINS_HDR) > $(GEN_PINS_SRC)
+ $(Q)$(PYTHON) $(MAKE_PINS) --board $(BOARD_PINS) --af $(AF_FILE) --prefix $(PREFIX_FILE) --hdr $(GEN_PINS_HDR) --qstr $(GEN_PINS_QSTR) --af-const $(GEN_PINS_AF_CONST) > $(GEN_PINS_SRC)
$(BUILD)/pins_gen.o: $(BUILD)/pins_gen.c
$(call compile_c)
diff --git a/teensy/hal_gpio.c b/teensy/hal_gpio.c
index 0811f76fda..218560e29b 100644
--- a/teensy/hal_gpio.c
+++ b/teensy/hal_gpio.c
@@ -25,12 +25,18 @@ void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
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);
+ }
+ else if (GPIO_Init->Mode == GPIO_MODE_ANALOG) {
+ GPIO_Init->Alternate = 0;
+ }
+ else {
+ GPIO_Init->Alternate = 1;
}
+ /* 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;
@@ -112,4 +118,3 @@ void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init)
#endif
}
}
-
diff --git a/teensy/main.c b/teensy/main.c
index 53f500d571..8de26f25e8 100644
--- a/teensy/main.c
+++ b/teensy/main.c
@@ -24,7 +24,7 @@
#include "usb.h"
#include "led.h"
#include "uart.h"
-//#include "pin.h"
+#include "pin.h"
#include "pybstdio.h"
@@ -272,7 +272,7 @@ soft_reset:
readline_init0();
- //pin_init();
+ pin_init0();
#if 0
// add some functions to the python namespace
diff --git a/teensy/make-pins.py b/teensy/make-pins.py
index 1fd05ec207..6df1e4162b 100755
--- a/teensy/make-pins.py
+++ b/teensy/make-pins.py
@@ -71,6 +71,9 @@ class AlternateFunction(object):
return self.func
return '{:s}{:d}'.format(self.func, self.fn_num)
+ def mux_name(self):
+ return 'AF{:d}_{:s}'.format(self.idx, self.ptr())
+
def print(self):
"""Prints the C representation of this AF."""
if self.supported:
@@ -83,6 +86,9 @@ class AlternateFunction(object):
print('({:2d}, {:8s}, {:2d}, {:10s}, {:8s}), // {:s}'.format(self.idx,
self.func, fn_num, self.pin_type, self.ptr(), self.af_str))
+ def qstr_list(self):
+ return [self.mux_name()]
+
class Pin(object):
"""Holds the information associated with a pin."""
@@ -169,6 +175,14 @@ class Pin(object):
hdr_file.write('extern const pin_af_obj_t pin_{:s}_af[];\n'.
format(self.cpu_pin_name()))
+ def qstr_list(self):
+ result = []
+ for alt_fn in self.alt_fn:
+ if alt_fn.is_supported():
+ result += alt_fn.qstr_list()
+ return result
+
+
class NamedPin(object):
def __init__(self, name, pin):
@@ -222,13 +236,13 @@ class Pins(object):
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))
+ print('STATIC const mp_map_elem_t pin_{:s}_pins_locals_dict_table[] = {{'.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(' {{ MP_OBJ_NEW_QSTR(MP_QSTR_{:s}), (mp_obj_t)&pin_{:s} }},'.format(named_pin.name(), pin.cpu_pin_name()))
print('};')
+ print('MP_DEFINE_CONST_DICT(pin_{:s}_pins_locals_dict, pin_{:s}_pins_locals_dict_table);'.format(label, label));
def print(self):
for named_pin in self.cpu_pins:
@@ -266,6 +280,39 @@ class Pins(object):
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 print_qstr(self, qstr_filename):
+ with open(qstr_filename, 'wt') as qstr_file:
+ qstr_set = set([])
+ for named_pin in self.cpu_pins:
+ pin = named_pin.pin()
+ if pin.is_board_pin():
+ qstr_set |= set(pin.qstr_list())
+ qstr_set |= set([named_pin.name()])
+ for named_pin in self.board_pins:
+ qstr_set |= set([named_pin.name()])
+ for qstr in sorted(qstr_set):
+ print('Q({})'.format(qstr), file=qstr_file)
+
+
+ def print_af_hdr(self, af_const_filename):
+ with open(af_const_filename, 'wt') as af_const_file:
+ af_hdr_set = set([])
+ mux_name_width = 0
+ for named_pin in self.cpu_pins:
+ pin = named_pin.pin()
+ if pin.is_board_pin():
+ for af in pin.alt_fn:
+ if af.is_supported():
+ mux_name = af.mux_name()
+ af_hdr_set |= set([mux_name])
+ if len(mux_name) > mux_name_width:
+ mux_name_width = len(mux_name)
+ for mux_name in sorted(af_hdr_set):
+ key = 'MP_OBJ_NEW_QSTR(MP_QSTR_{}),'.format(mux_name)
+ val = 'MP_OBJ_NEW_SMALL_INT(GPIO_{})'.format(mux_name)
+ print(' { %-*s %s },' % (mux_name_width + 26, key, val),
+ file=af_const_file)
+
def main():
parser = argparse.ArgumentParser(
@@ -280,6 +327,12 @@ def main():
default="stm32f4xx-af.csv"
)
parser.add_argument(
+ "--af-const",
+ dest="af_const_filename",
+ help="Specifies header file for alternate function constants.",
+ default="build/pins-af-const.h"
+ )
+ parser.add_argument(
"-b", "--board",
dest="board_filename",
help="Specifies the board file",
@@ -291,6 +344,12 @@ def main():
default="stm32f4xx-prefix.c"
)
parser.add_argument(
+ "-q", "--qstr",
+ dest="qstr_filename",
+ help="Specifies name of generated qstr header file",
+ default="build/pins-qstr.h"
+ )
+ parser.add_argument(
"-r", "--hdr",
dest="hdr_filename",
help="Specifies name of generated pin header file",
@@ -320,6 +379,8 @@ def main():
pins.print_adc(2)
pins.print_adc(3)
pins.print_header(args.hdr_filename)
+ pins.print_qstr(args.qstr_filename)
+ pins.print_af_hdr(args.af_const_filename)
if __name__ == "__main__":
diff --git a/teensy/memzip_files/boot.py b/teensy/memzip_files/boot.py
index 4702d7b5d3..6dd5516a97 100644
--- a/teensy/memzip_files/boot.py
+++ b/teensy/memzip_files/boot.py
@@ -1,2 +1,12 @@
import pyb
print("Executing boot.py")
+
+def pins():
+ for pin_name in dir(pyb.Pin.board):
+ pin = pyb.Pin(pin_name)
+ print('{:10s} {:s}'.format(pin_name, str(pin)))
+
+def af():
+ for pin_name in dir(pyb.Pin.board):
+ pin = pyb.Pin(pin_name)
+ print('{:10s} {:s}'.format(pin_name, str(pin.af_list())))
diff --git a/teensy/mk20dx256-prefix.c b/teensy/mk20dx256-prefix.c
index 2485dc01ab..048b64316a 100644
--- a/teensy/mk20dx256-prefix.c
+++ b/teensy/mk20dx256-prefix.c
@@ -15,6 +15,7 @@
#define AF(af_idx, af_fn, af_unit, af_type, af_ptr) \
{ \
{ &pin_af_type }, \
+ .name = MP_QSTR_AF ## af_idx ## _ ## af_fn ## af_unit, \
.idx = (af_idx), \
.fn = AF_FN_ ## af_fn, \
.unit = (af_unit), \
@@ -25,7 +26,7 @@
#define PIN(p_port, p_pin, p_num_af, p_af, p_adc_num, p_adc_channel) \
{ \
{ &pin_type }, \
- .name = #p_port #p_pin, \
+ .name = MP_QSTR_ ## p_port ## p_pin, \
.port = PORT_ ## p_port, \
.pin = (p_pin), \
.num_af = (p_num_af), \
diff --git a/teensy/pin_defs_teensy.c b/teensy/pin_defs_teensy.c
new file mode 100644
index 0000000000..dd2f0dc21f
--- /dev/null
+++ b/teensy/pin_defs_teensy.c
@@ -0,0 +1,61 @@
+#include <stdint.h>
+#include <mk20dx128.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"
+
+// Returns the pin mode. This value returned by this macro should be one of:
+// GPIO_MODE_INPUT, GPIO_MODE_OUTPUT_PP, GPIO_MODE_OUTPUT_OD,
+// GPIO_MODE_AF_PP, GPIO_MODE_AF_OD, or GPIO_MODE_ANALOG.
+
+uint32_t pin_get_mode(const pin_obj_t *pin) {
+ volatile uint32_t *port_pcr = GPIO_PIN_TO_PORT_PCR(pin->gpio, pin->pin);
+ uint32_t pcr = *port_pcr;
+ uint32_t af = (*port_pcr & PORT_PCR_MUX_MASK) >> 8;;
+
+ if (af == 0) {
+ return GPIO_MODE_ANALOG;
+ }
+ if (af == 1) {
+ if (pin->gpio->PDDR & (1 << pin->pin)) {
+ if (pcr & PORT_PCR_ODE) {
+ return GPIO_MODE_OUTPUT_OD;
+ }
+ return GPIO_MODE_OUTPUT_PP;
+ }
+ return GPIO_MODE_INPUT;
+ }
+
+ if (pcr & PORT_PCR_ODE) {
+ return GPIO_MODE_AF_OD;
+ }
+ return GPIO_MODE_AF_PP;
+}
+
+// Returns the pin pullup/pulldown. The value returned by this macro should
+// be one of GPIO_NOPULL, GPIO_PULLUP, or GPIO_PULLDOWN.
+
+uint32_t pin_get_pull(const pin_obj_t *pin) {
+ volatile uint32_t *port_pcr = GPIO_PIN_TO_PORT_PCR(pin->gpio, pin->pin);
+
+ uint32_t pcr = *port_pcr;
+ if (pcr & PORT_PCR_PE) {
+ if (pcr & PORT_PCR_PS) {
+ return GPIO_PULLUP;
+ }
+ return GPIO_PULLDOWN;
+ }
+ return GPIO_NOPULL;
+}
+
+// Returns the af (alternate function) index currently set for a pin.
+
+uint32_t pin_get_af(const pin_obj_t *pin) {
+ volatile uint32_t *port_pcr = GPIO_PIN_TO_PORT_PCR(pin->gpio, pin->pin);
+ return (*port_pcr & PORT_PCR_MUX_MASK) >> 8;
+}
diff --git a/teensy/pin_defs_teensy.h b/teensy/pin_defs_teensy.h
index 66942c2ea8..70fd47d8fd 100644
--- a/teensy/pin_defs_teensy.h
+++ b/teensy/pin_defs_teensy.h
@@ -43,4 +43,3 @@ enum {
SPI_TypeDef *SPI;
typedef GPIO_TypeDef pin_gpio_t;
-
diff --git a/teensy/qstrdefsport.h b/teensy/qstrdefsport.h
index 2fb70af7b4..bdafd14286 100644
--- a/teensy/qstrdefsport.h
+++ b/teensy/qstrdefsport.h
@@ -62,13 +62,21 @@ Q(value)
Q(low)
Q(high)
Q(name)
+Q(names)
+Q(af)
+Q(af_list)
Q(port)
Q(pin)
+Q(gpio)
Q(mapper)
Q(dict)
Q(debug)
Q(board)
Q(cpu)
+Q(mode)
+Q(pull)
+Q(index)
+Q(reg)
Q(IN)
Q(OUT_PP)
Q(OUT_OD)
diff --git a/teensy/teensy_hal.h b/teensy/teensy_hal.h
index ff16c98c5c..9c9e628424 100644
--- a/teensy/teensy_hal.h
+++ b/teensy/teensy_hal.h
@@ -81,6 +81,7 @@ typedef struct {
#define GPIO_SPEED_FAST ((uint32_t)2)
#define GPIO_SPEED_HIGH ((uint32_t)3)
+#define IS_GPIO_AF(af) ((af) >= 0 && (af) <= 7)
typedef struct {
uint32_t Pin;
@@ -96,6 +97,22 @@ typedef struct {
#define GPIO_PIN_TO_PORT_PCR(GPIOx, pin) \
(&PORTA_PCR0 + GPIO_PORT_TO_PORT_NUM(GPIOx) * 32 + (pin))
+#define GPIO_AF2_I2C0 2
+#define GPIO_AF2_I2C1 2
+#define GPIO_AF2_SPI0 2
+#define GPIO_AF3_FTM0 3
+#define GPIO_AF3_FTM1 3
+#define GPIO_AF3_FTM2 3
+#define GPIO_AF3_UART0 3
+#define GPIO_AF3_UART1 3
+#define GPIO_AF3_UART2 3
+#define GPIO_AF4_FTM0 4
+#define GPIO_AF6_FTM1 6
+#define GPIO_AF6_FTM2 6
+#define GPIO_AF6_I2C1 6
+#define GPIO_AF7_FTM1 7
+
+
__attribute__(( always_inline )) static inline void __WFI(void)
{
__asm volatile ("wfi");
@@ -109,3 +126,4 @@ 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))
+#define GPIO_read_output_pin(gpio, pin) (((gpio)->PDOR >> (pin)) & 1)