summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2014-04-10 22:46:40 +0100
committerDamien George <damien.p.george@gmail.com>2014-04-10 22:46:40 +0100
commit3f4898456bb1a451e5e6d45cb62c9c718f2b8a76 (patch)
tree2b1208d70e5bf052988e8e550ac0fff594e4654d
parent57e99ebc868aeaae3b0f826beef7f82c01e56405 (diff)
downloadmicropython-3f4898456bb1a451e5e6d45cb62c9c718f2b8a76.tar.gz
micropython-3f4898456bb1a451e5e6d45cb62c9c718f2b8a76.zip
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.
-rw-r--r--stmhal/Makefile3
-rw-r--r--stmhal/modstm.c120
-rw-r--r--stmhal/modstm.h1
-rw-r--r--stmhal/mpconfigport.h7
-rw-r--r--stmhal/qstrdefsport.h16
5 files changed, 146 insertions, 1 deletions
diff --git a/stmhal/Makefile b/stmhal/Makefile
index 064db23c35..9789189946 100644
--- a/stmhal/Makefile
+++ b/stmhal/Makefile
@@ -77,8 +77,9 @@ SRC_C = \
pyexec.c \
help.c \
input.c \
- modpyb.c \
modos.c \
+ modpyb.c \
+ modstm.c \
modtime.c \
import.c \
lexerfatfs.c \
diff --git a/stmhal/modstm.c b/stmhal/modstm.c
new file mode 100644
index 0000000000..5e72a75bb2
--- /dev/null
+++ b/stmhal/modstm.c
@@ -0,0 +1,120 @@
+#include <stdio.h>
+#include <stdint.h>
+
+#include <stm32f4xx_hal.h>
+
+#include "nlr.h"
+#include "misc.h"
+#include "mpconfig.h"
+#include "qstr.h"
+#include "obj.h"
+#include "modstm.h"
+
+STATIC uint32_t get_read_addr(mp_obj_t addr_o, uint align) {
+ uint32_t addr = mp_obj_get_int(addr_o) & 0x7fffffff;
+ if (addr < 0x10000000) {
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "cannot read from address %08x", addr));
+ }
+ if ((addr & (align - 1)) != 0) {
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "address %08x is not aligned to %d bytes", addr, align));
+ }
+ return addr;
+}
+
+STATIC uint32_t get_write_addr(mp_obj_t addr_o, uint align) {
+ uint32_t addr = mp_obj_get_int(addr_o) & 0x7fffffff;
+ if (addr < 0x10000000) {
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "cannot write to address %08x", addr));
+ }
+ if ((addr & (align - 1)) != 0) {
+ nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "address %08x is not aligned to %d bytes", addr, align));
+ }
+ return addr;
+}
+
+STATIC mp_obj_t stm_read8(mp_obj_t addr) {
+ uint32_t a = get_read_addr(addr, 1);
+ uint32_t v = *(uint8_t*)a;
+ return mp_obj_new_int(v);
+}
+
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(stm_read8_obj, stm_read8);
+
+STATIC mp_obj_t stm_read16(mp_obj_t addr) {
+ uint32_t a = get_read_addr(addr, 2);
+ uint32_t v = *(uint16_t*)a;
+ return mp_obj_new_int(v);
+}
+
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(stm_read16_obj, stm_read16);
+
+STATIC mp_obj_t stm_read32(mp_obj_t addr) {
+ uint32_t a = get_read_addr(addr, 4);
+ uint32_t v = *(uint32_t*)a;
+ return mp_obj_new_int(v);
+}
+
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(stm_read32_obj, stm_read32);
+
+STATIC mp_obj_t stm_write8(mp_obj_t addr, mp_obj_t val) {
+ uint32_t a = get_write_addr(addr, 1);
+ uint32_t v = mp_obj_get_int(val);
+ *(uint8_t*)a = v;
+ return mp_const_none;
+}
+
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(stm_write8_obj, stm_write8);
+
+STATIC mp_obj_t stm_write16(mp_obj_t addr, mp_obj_t val) {
+ uint32_t a = get_write_addr(addr, 2);
+ uint32_t v = mp_obj_get_int(val);
+ *(uint16_t*)a = v;
+ return mp_const_none;
+}
+
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(stm_write16_obj, stm_write16);
+
+STATIC mp_obj_t stm_write32(mp_obj_t addr, mp_obj_t val) {
+ uint32_t a = get_write_addr(addr, 4);
+ uint32_t v = mp_obj_get_int(val);
+ *(uint32_t*)a = v;
+ return mp_const_none;
+}
+
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(stm_write32_obj, stm_write32);
+
+STATIC const mp_map_elem_t stm_module_globals_table[] = {
+ { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_stm) },
+
+ { MP_OBJ_NEW_QSTR(MP_QSTR_read8), (mp_obj_t)&stm_read8_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_read16), (mp_obj_t)&stm_read16_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_read32), (mp_obj_t)&stm_read32_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_write8), (mp_obj_t)&stm_write8_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_write16), (mp_obj_t)&stm_write16_obj },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_write32), (mp_obj_t)&stm_write32_obj },
+
+ { MP_OBJ_NEW_QSTR(MP_QSTR_GPIOA), MP_OBJ_NEW_SMALL_INT(GPIOA_BASE) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_GPIOB), MP_OBJ_NEW_SMALL_INT(GPIOB_BASE) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_GPIOC), MP_OBJ_NEW_SMALL_INT(GPIOC_BASE) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_GPIOD), MP_OBJ_NEW_SMALL_INT(GPIOD_BASE) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_GPIO_IDR), MP_OBJ_NEW_SMALL_INT(0x10) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_GPIO_BSRRL), MP_OBJ_NEW_SMALL_INT(0x18) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_GPIO_BSRRH), MP_OBJ_NEW_SMALL_INT(0x1a) },
+};
+
+STATIC const mp_obj_dict_t stm_module_globals = {
+ .base = {&mp_type_dict},
+ .map = {
+ .all_keys_are_qstrs = 1,
+ .table_is_fixed_array = 1,
+ .used = sizeof(stm_module_globals_table) / sizeof(mp_map_elem_t),
+ .alloc = sizeof(stm_module_globals_table) / sizeof(mp_map_elem_t),
+ .table = (mp_map_elem_t*)stm_module_globals_table,
+ },
+};
+
+const mp_obj_module_t stm_module = {
+ .base = { &mp_type_module },
+ .name = MP_QSTR_stm,
+ .globals = (mp_obj_dict_t*)&stm_module_globals,
+};
diff --git a/stmhal/modstm.h b/stmhal/modstm.h
new file mode 100644
index 0000000000..205cdd2a18
--- /dev/null
+++ b/stmhal/modstm.h
@@ -0,0 +1 @@
+extern const mp_obj_module_t stm_module;
diff --git a/stmhal/mpconfigport.h b/stmhal/mpconfigport.h
index 08ba923e40..5529101425 100644
--- a/stmhal/mpconfigport.h
+++ b/stmhal/mpconfigport.h
@@ -31,12 +31,19 @@ extern const struct _mp_obj_fun_native_t mp_builtin_open_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 stm_module;
extern const struct _mp_obj_module_t time_module;
#define MICROPY_EXTRA_BUILTIN_MODULES \
{ MP_OBJ_NEW_QSTR(MP_QSTR_os), (mp_obj_t)&os_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_pyb), (mp_obj_t)&pyb_module }, \
+ { MP_OBJ_NEW_QSTR(MP_QSTR_stm), (mp_obj_t)&stm_module }, \
{ MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_module }, \
+// extra constants
+#define MICROPY_EXTRA_CONSTANTS \
+ { MP_OBJ_NEW_QSTR(MP_QSTR_pyb), (mp_obj_t)&pyb_module }, \
+ { MP_OBJ_NEW_QSTR(MP_QSTR_stm), (mp_obj_t)&stm_module }, \
+
// type definitions for the specific machine
#define BYTES_PER_WORD (4)
diff --git a/stmhal/qstrdefsport.h b/stmhal/qstrdefsport.h
index 4eb6ea12a0..546b5b1430 100644
--- a/stmhal/qstrdefsport.h
+++ b/stmhal/qstrdefsport.h
@@ -130,3 +130,19 @@ Q(sleep)
// for input
Q(input)
+
+// for stm module
+Q(stm)
+Q(read8)
+Q(read16)
+Q(read32)
+Q(write8)
+Q(write16)
+Q(write32)
+Q(GPIOA)
+Q(GPIOB)
+Q(GPIOC)
+Q(GPIOD)
+Q(GPIO_IDR)
+Q(GPIO_BSRRL)
+Q(GPIO_BSRRH)