Skip to content

Commit 880ce2d

Browse files
committed
Merge pull request #97 from dhylands/teensy-3.1
Initial support for Teensy 3.1
2 parents ff07bb3 + 297446e commit 880ce2d

File tree

17 files changed

+1809
-0
lines changed

17 files changed

+1809
-0
lines changed

teensy/Makefile

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
ifeq ($(ARDUINO),)
2+
$(error Please define ARDUINO (where TeensyDuino is installed))
3+
endif
4+
TOOLS_PATH = $(ARDUINO)/hardware/tools
5+
COMPILER_PATH = $(TOOLS_PATH)/arm-none-eabi/bin
6+
CORE_PATH = $(ARDUINO)/hardware/teensy/cores/teensy3
7+
8+
PYSRC=../py
9+
BUILD=build
10+
11+
AS = $(COMPILER_PATH)/arm-none-eabi-as
12+
CC = $(COMPILER_PATH)/arm-none-eabi-gcc
13+
LD = $(COMPILER_PATH)/arm-none-eabi-ld
14+
OBJCOPY = $(COMPILER_PATH)/arm-none-eabi-objcopy
15+
SIZE = $(COMPILER_PATH)/arm-none-eabi-size
16+
17+
CFLAGS_TEENSY = -DF_CPU=96000000 -DUSB_SERIAL -DLAYOUT_US_ENGLISH -D__MK20DX256__
18+
CFLAGS_CORTEX_M4 = -mthumb -mtune=cortex-m4 -mcpu=cortex-m4 -fsingle-precision-constant -Wdouble-promotion $(CFLAGS_TEENSY)
19+
CFLAGS = -I. -I$(PYSRC) -I$(CORE_PATH) -Wall -ansi -std=gnu99 -Os -DNDEBUG $(CFLAGS_CORTEX_M4)
20+
LDFLAGS = -nostdlib -T mk20dx256.ld
21+
LIBS = -L $(COMPILER_PATH)/../lib/gcc/arm-none-eabi/4.7.2/thumb2 -lgcc
22+
23+
SRC_C = \
24+
main.c \
25+
lexerteensy.c \
26+
led.c \
27+
malloc0.c \
28+
printf.c \
29+
string0.c \
30+
usb.c \
31+
32+
SRC_S = \
33+
gchelper.s \
34+
35+
PY_O = \
36+
nlrthumb.o \
37+
gc.o \
38+
malloc.o \
39+
qstr.o \
40+
vstr.o \
41+
unicode.o \
42+
lexer.o \
43+
parse.o \
44+
scope.o \
45+
compile.o \
46+
emitcommon.o \
47+
emitpass1.o \
48+
emitbc.o \
49+
asmthumb.o \
50+
emitnthumb.o \
51+
emitinlinethumb.o \
52+
runtime.o \
53+
map.o \
54+
obj.o \
55+
objbool.o \
56+
objboundmeth.o \
57+
objcell.o \
58+
objclass.o \
59+
objclosure.o \
60+
objcomplex.o \
61+
objdict.o \
62+
objexcept.o \
63+
objfloat.o \
64+
objfun.o \
65+
objgenerator.o \
66+
objinstance.o \
67+
objint.o \
68+
objlist.o \
69+
objmodule.o \
70+
objnone.o \
71+
objrange.o \
72+
objset.o \
73+
objslice.o \
74+
objstr.o \
75+
objtuple.o \
76+
objtype.o \
77+
builtin.o \
78+
builtinimport.o \
79+
vm.o \
80+
showbc.o \
81+
repl.o \
82+
83+
SRC_TEENSY = \
84+
mk20dx128.c \
85+
pins_teensy.c \
86+
analog.c \
87+
usb_desc.c \
88+
usb_dev.c \
89+
usb_mem.c \
90+
usb_serial.c \
91+
yield.c \
92+
93+
OBJ = $(addprefix $(BUILD)/, $(SRC_C:.c=.o) $(SRC_S:.s=.o) $(PY_O) $(SRC_TEENSY:.c=.o))
94+
#LIB = -lreadline
95+
# the following is needed for BSD
96+
#LIB += -ltermcap
97+
PROG = micropython
98+
99+
all: hex
100+
hex: $(PROG).hex
101+
102+
post_compile: $(PROG).hex
103+
$(TOOLS_PATH)/teensy_post_compile -file="$(basename $<)" -path="$(CURDIR)" -tools="$(TOOLS_PATH)"
104+
105+
reboot:
106+
-$(TOOLS_PATH)/teensy_reboot
107+
108+
upload: post_compile reboot
109+
110+
$(PROG).elf: $(BUILD) $(OBJ)
111+
$(CC) $(LDFLAGS) -o "$@" -Wl,-Map,$(PROG).map $(OBJ) $(LIBS)
112+
113+
%.hex: %.elf
114+
$(SIZE) "$<"
115+
$(OBJCOPY) -O ihex -R .eeprom "$<" "$@"
116+
117+
$(BUILD):
118+
mkdir -p $@
119+
120+
$(BUILD)/%.o: %.s
121+
$(AS) -o $@ $<
122+
123+
$(BUILD)/%.o: %.c
124+
$(CC) $(CFLAGS) -c -o $@ $<
125+
126+
$(BUILD)/%.o: $(PYSRC)/%.S
127+
$(CC) $(CFLAGS) -c -o $@ $<
128+
129+
$(BUILD)/%.o: $(PYSRC)/%.c mpconfigport.h
130+
$(CC) $(CFLAGS) -c -o $@ $<
131+
132+
$(BUILD)/%.o: $(CORE_PATH)/%.c
133+
$(CC) $(CFLAGS) -c -o $@ $<
134+
135+
$(BUILD)/emitnthumb.o: $(PYSRC)/emitnative.c $(PYSRC)/emit.h
136+
$(CC) $(CFLAGS) -DN_THUMB -c -o $@ $<
137+
138+
# optimising gc for speed; 5ms down to 4ms
139+
$(BUILD)/gc.o: $(PYSRC)/gc.c
140+
$(CC) $(CFLAGS) -O3 -c -o $@ $<
141+
142+
# optimising vm for speed, adds only a small amount to code size but makes a huge difference to speed (20% faster)
143+
$(BUILD)/vm.o: $(PYSRC)/vm.c
144+
$(CC) $(CFLAGS) -O3 -c -o $@ $<
145+
146+
$(BUILD)/main.o: mpconfigport.h
147+
$(BUILD)/parse.o: $(PYSRC)/grammar.h
148+
$(BUILD)/compile.o: $(PYSRC)/grammar.h
149+
$(BUILD)/emitbc.o: $(PYSRC)/emit.h
150+
151+
clean:
152+
/bin/rm -rf $(BUILD)
153+
/bin/rm -f $(PROG).elf $(PROG).hex $(PROG).map
154+
155+
.PHONY: clean

teensy/README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
Build Instructions for Teensy 3.1
2+
3+
This assumes that you have TeensyDuino installed and set the ARUINO environment
4+
variable pointing to the where Arduino with TeensyDuino is installed.
5+
6+
```
7+
cd teensy
8+
ARDUINO=~/arduino-1.0.5 make
9+
```
10+
11+
To build the loader
12+
13+
```
14+
cd teensy/loader
15+
make
16+
```
17+
18+
To upload micropython to the Teensy 3.1.
19+
20+
Press the Program button on the Teensy 3.1
21+
```
22+
make upload
23+
```
24+
25+
Currently, the python prompt is through the USB serial interface.
26+
27+
The LED will blink (100 msec on/100 msec off) while waiting for the USB Serial
28+
device to be configured, and will blink (200 msec on/200 msec off) while
29+
sitting at the readline prompt.
30+
31+
Currently, there is no I/O support configured (no GPIO, ADC, etc).

teensy/gchelper.s

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
.syntax unified
2+
.cpu cortex-m4
3+
.thumb
4+
.text
5+
.align 2
6+
7+
@ void gc_helper_get_regs_and_clean_stack(r0=uint regs[10], r1=heap_end)
8+
.global gc_helper_get_regs_and_clean_stack
9+
.thumb
10+
.thumb_func
11+
.type gc_helper_get_regs_and_clean_stack, %function
12+
gc_helper_get_regs_and_clean_stack:
13+
@ store registers into given array
14+
str r4, [r0], #4
15+
str r5, [r0], #4
16+
str r6, [r0], #4
17+
str r7, [r0], #4
18+
str r8, [r0], #4
19+
str r9, [r0], #4
20+
str r10, [r0], #4
21+
str r11, [r0], #4
22+
str r12, [r0], #4
23+
str r13, [r0], #4
24+
25+
@ clean the stack from given pointer up to current sp
26+
movs r0, #0
27+
mov r2, sp
28+
b.n .entry
29+
.loop:
30+
str r0, [r1], #4
31+
.entry:
32+
cmp r1, r2
33+
bcc.n .loop
34+
bx lr
35+
36+
.size gc_helper_get_regs_and_clean_stack, .-gc_helper_get_regs_and_clean_stack

teensy/led.c

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#include <stdio.h>
2+
3+
#include "misc.h"
4+
#include "mpconfig.h"
5+
#include "obj.h"
6+
#include "led.h"
7+
8+
#include "Arduino.h"
9+
10+
void led_init(void) {
11+
}
12+
13+
void led_state(pyb_led_t led, int state) {
14+
uint8_t pin;
15+
16+
if (led == 0) {
17+
pin = LED_BUILTIN;
18+
} else {
19+
return;
20+
}
21+
digitalWrite(pin, state);
22+
}
23+
24+
void led_toggle(pyb_led_t led) {
25+
uint8_t pin;
26+
27+
if (led == 0) {
28+
pin = LED_BUILTIN;
29+
} else {
30+
return;
31+
}
32+
33+
digitalWrite(pin, !digitalRead(pin));
34+
}
35+
36+
/******************************************************************************/
37+
/* Micro Python bindings */
38+
39+
typedef struct _pyb_led_obj_t {
40+
mp_obj_base_t base;
41+
uint led_id;
42+
} pyb_led_obj_t;
43+
44+
void led_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
45+
pyb_led_obj_t *self = self_in;
46+
print(env, "<LED %lu>", self->led_id);
47+
}
48+
49+
mp_obj_t led_obj_on(mp_obj_t self_in) {
50+
pyb_led_obj_t *self = self_in;
51+
led_state(self->led_id, 1);
52+
return mp_const_none;
53+
}
54+
55+
mp_obj_t led_obj_off(mp_obj_t self_in) {
56+
pyb_led_obj_t *self = self_in;
57+
led_state(self->led_id, 0);
58+
return mp_const_none;
59+
}
60+
61+
static MP_DEFINE_CONST_FUN_OBJ_1(led_obj_on_obj, led_obj_on);
62+
static MP_DEFINE_CONST_FUN_OBJ_1(led_obj_off_obj, led_obj_off);
63+
64+
static const mp_obj_type_t led_obj_type = {
65+
{ &mp_const_type },
66+
"Led",
67+
led_obj_print, // print
68+
NULL, // make_new
69+
NULL, // call_n
70+
NULL, // unary_op
71+
NULL, // binary_op
72+
NULL, // getiter
73+
NULL, // iternext
74+
{ // method list
75+
{ "on", &led_obj_on_obj },
76+
{ "off", &led_obj_off_obj },
77+
{ NULL, NULL },
78+
}
79+
};
80+
81+
mp_obj_t pyb_Led(mp_obj_t led_id) {
82+
pyb_led_obj_t *o = m_new_obj(pyb_led_obj_t);
83+
o->base.type = &led_obj_type;
84+
o->led_id = mp_obj_get_int(led_id);
85+
return o;
86+
}

teensy/led.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
typedef enum {
2+
PYB_LED_BUILTIN = 0,
3+
} pyb_led_t;
4+
5+
void led_init(void);
6+
void led_state(pyb_led_t led, int state);
7+
void led_toggle(pyb_led_t led);
8+
9+
mp_obj_t pyb_Led(mp_obj_t led_id);

teensy/lexerteensy.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#include <stdint.h>
2+
#include <stdio.h>
3+
4+
#include "misc.h"
5+
#include "lexer.h"
6+
#include "lexerteensy.h"
7+
8+
unichar str_buf_next_char(mp_lexer_str_buf_t *sb) {
9+
if (sb->src_cur < sb->src_end) {
10+
return *sb->src_cur++;
11+
} else {
12+
return MP_LEXER_CHAR_EOF;
13+
}
14+
}
15+
16+
void str_buf_free(mp_lexer_str_buf_t *sb) {
17+
if (sb->free) {
18+
m_del(char, (char*)sb->src_beg, 0 /* don't know allocated size of src */);
19+
}
20+
}
21+
22+
mp_lexer_t *mp_lexer_new_from_str_len(const char *src_name, const char *str, uint len, bool free_str, mp_lexer_str_buf_t *sb) {
23+
sb->free = free_str;
24+
sb->src_beg = str;
25+
sb->src_cur = str;
26+
sb->src_end = str + len;
27+
return mp_lexer_new(src_name, sb, (mp_lexer_stream_next_char_t)str_buf_next_char, (mp_lexer_stream_close_t)str_buf_free);
28+
}
29+
30+
mp_lexer_t *mp_import_open_file(qstr mod_name) {
31+
printf("import not implemented\n");
32+
return NULL;
33+
}

teensy/lexerteensy.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
typedef struct _py_lexer_str_buf_t {
2+
bool free; // free src_beg when done
3+
const char *src_beg; // beginning of source
4+
const char *src_cur; // current location in source
5+
const char *src_end; // end (exclusive) of source
6+
} mp_lexer_str_buf_t;
7+
8+
mp_lexer_t *mp_lexer_new_from_str_len(const char *src_name, const char *str, uint len, bool free_str, mp_lexer_str_buf_t *sb);

0 commit comments

Comments
 (0)