Skip to content

Commit 3f48984

Browse files
committed
stmhal: Add stm module, which contains some constants for the MCU.
Also contains raw memory read/write functions, read8, read16, read32, write8, write16, write32. Can now do: stm.write16(stm.GPIOA + stm.GPIO_BSRRL, 1 << 13) This turns on the red LED. With the new constant folding, the above constants for the GPIO address are actually compiled to constants (and the addition done) at compile time. For viper code and inline assembler, this optimisation will make a big difference. In the inline assembler, using these constants would not be possible without this constant folding.
1 parent 57e99eb commit 3f48984

5 files changed

Lines changed: 146 additions & 1 deletion

File tree

stmhal/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,9 @@ SRC_C = \
7777
pyexec.c \
7878
help.c \
7979
input.c \
80-
modpyb.c \
8180
modos.c \
81+
modpyb.c \
82+
modstm.c \
8283
modtime.c \
8384
import.c \
8485
lexerfatfs.c \

stmhal/modstm.c

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
#include <stdio.h>
2+
#include <stdint.h>
3+
4+
#include <stm32f4xx_hal.h>
5+
6+
#include "nlr.h"
7+
#include "misc.h"
8+
#include "mpconfig.h"
9+
#include "qstr.h"
10+
#include "obj.h"
11+
#include "modstm.h"
12+
13+
STATIC uint32_t get_read_addr(mp_obj_t addr_o, uint align) {
14+
uint32_t addr = mp_obj_get_int(addr_o) & 0x7fffffff;
15+
if (addr < 0x10000000) {
16+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "cannot read from address %08x", addr));
17+
}
18+
if ((addr & (align - 1)) != 0) {
19+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "address %08x is not aligned to %d bytes", addr, align));
20+
}
21+
return addr;
22+
}
23+
24+
STATIC uint32_t get_write_addr(mp_obj_t addr_o, uint align) {
25+
uint32_t addr = mp_obj_get_int(addr_o) & 0x7fffffff;
26+
if (addr < 0x10000000) {
27+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "cannot write to address %08x", addr));
28+
}
29+
if ((addr & (align - 1)) != 0) {
30+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "address %08x is not aligned to %d bytes", addr, align));
31+
}
32+
return addr;
33+
}
34+
35+
STATIC mp_obj_t stm_read8(mp_obj_t addr) {
36+
uint32_t a = get_read_addr(addr, 1);
37+
uint32_t v = *(uint8_t*)a;
38+
return mp_obj_new_int(v);
39+
}
40+
41+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(stm_read8_obj, stm_read8);
42+
43+
STATIC mp_obj_t stm_read16(mp_obj_t addr) {
44+
uint32_t a = get_read_addr(addr, 2);
45+
uint32_t v = *(uint16_t*)a;
46+
return mp_obj_new_int(v);
47+
}
48+
49+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(stm_read16_obj, stm_read16);
50+
51+
STATIC mp_obj_t stm_read32(mp_obj_t addr) {
52+
uint32_t a = get_read_addr(addr, 4);
53+
uint32_t v = *(uint32_t*)a;
54+
return mp_obj_new_int(v);
55+
}
56+
57+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(stm_read32_obj, stm_read32);
58+
59+
STATIC mp_obj_t stm_write8(mp_obj_t addr, mp_obj_t val) {
60+
uint32_t a = get_write_addr(addr, 1);
61+
uint32_t v = mp_obj_get_int(val);
62+
*(uint8_t*)a = v;
63+
return mp_const_none;
64+
}
65+
66+
STATIC MP_DEFINE_CONST_FUN_OBJ_2(stm_write8_obj, stm_write8);
67+
68+
STATIC mp_obj_t stm_write16(mp_obj_t addr, mp_obj_t val) {
69+
uint32_t a = get_write_addr(addr, 2);
70+
uint32_t v = mp_obj_get_int(val);
71+
*(uint16_t*)a = v;
72+
return mp_const_none;
73+
}
74+
75+
STATIC MP_DEFINE_CONST_FUN_OBJ_2(stm_write16_obj, stm_write16);
76+
77+
STATIC mp_obj_t stm_write32(mp_obj_t addr, mp_obj_t val) {
78+
uint32_t a = get_write_addr(addr, 4);
79+
uint32_t v = mp_obj_get_int(val);
80+
*(uint32_t*)a = v;
81+
return mp_const_none;
82+
}
83+
84+
STATIC MP_DEFINE_CONST_FUN_OBJ_2(stm_write32_obj, stm_write32);
85+
86+
STATIC const mp_map_elem_t stm_module_globals_table[] = {
87+
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_stm) },
88+
89+
{ MP_OBJ_NEW_QSTR(MP_QSTR_read8), (mp_obj_t)&stm_read8_obj },
90+
{ MP_OBJ_NEW_QSTR(MP_QSTR_read16), (mp_obj_t)&stm_read16_obj },
91+
{ MP_OBJ_NEW_QSTR(MP_QSTR_read32), (mp_obj_t)&stm_read32_obj },
92+
{ MP_OBJ_NEW_QSTR(MP_QSTR_write8), (mp_obj_t)&stm_write8_obj },
93+
{ MP_OBJ_NEW_QSTR(MP_QSTR_write16), (mp_obj_t)&stm_write16_obj },
94+
{ MP_OBJ_NEW_QSTR(MP_QSTR_write32), (mp_obj_t)&stm_write32_obj },
95+
96+
{ MP_OBJ_NEW_QSTR(MP_QSTR_GPIOA), MP_OBJ_NEW_SMALL_INT(GPIOA_BASE) },
97+
{ MP_OBJ_NEW_QSTR(MP_QSTR_GPIOB), MP_OBJ_NEW_SMALL_INT(GPIOB_BASE) },
98+
{ MP_OBJ_NEW_QSTR(MP_QSTR_GPIOC), MP_OBJ_NEW_SMALL_INT(GPIOC_BASE) },
99+
{ MP_OBJ_NEW_QSTR(MP_QSTR_GPIOD), MP_OBJ_NEW_SMALL_INT(GPIOD_BASE) },
100+
{ MP_OBJ_NEW_QSTR(MP_QSTR_GPIO_IDR), MP_OBJ_NEW_SMALL_INT(0x10) },
101+
{ MP_OBJ_NEW_QSTR(MP_QSTR_GPIO_BSRRL), MP_OBJ_NEW_SMALL_INT(0x18) },
102+
{ MP_OBJ_NEW_QSTR(MP_QSTR_GPIO_BSRRH), MP_OBJ_NEW_SMALL_INT(0x1a) },
103+
};
104+
105+
STATIC const mp_obj_dict_t stm_module_globals = {
106+
.base = {&mp_type_dict},
107+
.map = {
108+
.all_keys_are_qstrs = 1,
109+
.table_is_fixed_array = 1,
110+
.used = sizeof(stm_module_globals_table) / sizeof(mp_map_elem_t),
111+
.alloc = sizeof(stm_module_globals_table) / sizeof(mp_map_elem_t),
112+
.table = (mp_map_elem_t*)stm_module_globals_table,
113+
},
114+
};
115+
116+
const mp_obj_module_t stm_module = {
117+
.base = { &mp_type_module },
118+
.name = MP_QSTR_stm,
119+
.globals = (mp_obj_dict_t*)&stm_module_globals,
120+
};

stmhal/modstm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
extern const mp_obj_module_t stm_module;

stmhal/mpconfigport.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,19 @@ extern const struct _mp_obj_fun_native_t mp_builtin_open_obj;
3131
// extra built in modules to add to the list of known ones
3232
extern const struct _mp_obj_module_t os_module;
3333
extern const struct _mp_obj_module_t pyb_module;
34+
extern const struct _mp_obj_module_t stm_module;
3435
extern const struct _mp_obj_module_t time_module;
3536
#define MICROPY_EXTRA_BUILTIN_MODULES \
3637
{ MP_OBJ_NEW_QSTR(MP_QSTR_os), (mp_obj_t)&os_module }, \
3738
{ MP_OBJ_NEW_QSTR(MP_QSTR_pyb), (mp_obj_t)&pyb_module }, \
39+
{ MP_OBJ_NEW_QSTR(MP_QSTR_stm), (mp_obj_t)&stm_module }, \
3840
{ MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_module }, \
3941

42+
// extra constants
43+
#define MICROPY_EXTRA_CONSTANTS \
44+
{ MP_OBJ_NEW_QSTR(MP_QSTR_pyb), (mp_obj_t)&pyb_module }, \
45+
{ MP_OBJ_NEW_QSTR(MP_QSTR_stm), (mp_obj_t)&stm_module }, \
46+
4047
// type definitions for the specific machine
4148

4249
#define BYTES_PER_WORD (4)

stmhal/qstrdefsport.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,3 +130,19 @@ Q(sleep)
130130

131131
// for input
132132
Q(input)
133+
134+
// for stm module
135+
Q(stm)
136+
Q(read8)
137+
Q(read16)
138+
Q(read32)
139+
Q(write8)
140+
Q(write16)
141+
Q(write32)
142+
Q(GPIOA)
143+
Q(GPIOB)
144+
Q(GPIOC)
145+
Q(GPIOD)
146+
Q(GPIO_IDR)
147+
Q(GPIO_BSRRL)
148+
Q(GPIO_BSRRH)

0 commit comments

Comments
 (0)