Add module object, to be used eventually for import.
This commit is contained in:
parent
0ff883904a
commit
2870862601
11
py/obj.h
11
py/obj.h
@ -87,9 +87,9 @@ struct _mp_obj_type_t {
|
||||
dynamic_type instance
|
||||
|
||||
compare_op
|
||||
load_attr instance class list
|
||||
load_attr module instance class list
|
||||
load_method instance str gen list user
|
||||
store_attr instance class
|
||||
store_attr module instance class
|
||||
store_subscr list dict
|
||||
|
||||
len str tuple list map
|
||||
@ -147,6 +147,7 @@ mp_obj_t mp_obj_new_set(int n_args, mp_obj_t *items);
|
||||
mp_obj_t mp_obj_new_bound_meth(mp_obj_t self, mp_obj_t meth);
|
||||
mp_obj_t mp_obj_new_class(struct _mp_map_t *class_locals);
|
||||
mp_obj_t mp_obj_new_instance(mp_obj_t clas);
|
||||
mp_obj_t mp_obj_new_module(qstr module_name);
|
||||
|
||||
const char *mp_obj_get_type_str(mp_obj_t o_in);
|
||||
|
||||
@ -238,5 +239,7 @@ mp_obj_t mp_obj_instance_load_attr(mp_obj_t self_in, qstr attr);
|
||||
void mp_obj_instance_load_method(mp_obj_t self_in, qstr attr, mp_obj_t *dest);
|
||||
void mp_obj_instance_store_attr(mp_obj_t self_in, qstr attr, mp_obj_t value);
|
||||
|
||||
// temporary way of making C modules
|
||||
mp_obj_t mp_module_new(void);
|
||||
// module
|
||||
extern const mp_obj_type_t module_type;
|
||||
mp_obj_t mp_obj_new_module(qstr module_name);
|
||||
struct _mp_map_t *mp_obj_module_get_globals(mp_obj_t self_in);
|
||||
|
48
py/objmodule.c
Normal file
48
py/objmodule.c
Normal file
@ -0,0 +1,48 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "nlr.h"
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
#include "map.h"
|
||||
|
||||
typedef struct _mp_obj_module_t {
|
||||
mp_obj_base_t base;
|
||||
qstr name;
|
||||
mp_map_t *globals;
|
||||
} mp_obj_module_t;
|
||||
|
||||
void module_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in) {
|
||||
mp_obj_module_t *self = self_in;
|
||||
print(env, "<module '%s' from '-unknown-file-'>", qstr_str(self->name));
|
||||
}
|
||||
|
||||
const mp_obj_type_t module_type = {
|
||||
{ &mp_const_type },
|
||||
"module",
|
||||
module_print, // print
|
||||
NULL, // call_n
|
||||
NULL, // unary_op
|
||||
NULL, // binary_op
|
||||
NULL, // getiter
|
||||
NULL, // iternext
|
||||
{{NULL, NULL},}, // method list
|
||||
};
|
||||
|
||||
mp_obj_t mp_obj_new_module(qstr module_name) {
|
||||
mp_obj_module_t *o = m_new_obj(mp_obj_module_t);
|
||||
o->base.type = &module_type;
|
||||
o->name = module_name;
|
||||
o->globals = mp_map_new(MP_MAP_QSTR, 0);
|
||||
return o;
|
||||
}
|
||||
|
||||
mp_map_t *mp_obj_module_get_globals(mp_obj_t self_in) {
|
||||
assert(MP_OBJ_IS_TYPE(self_in, &module_type));
|
||||
mp_obj_module_t *self = self_in;
|
||||
return self->globals;
|
||||
}
|
16
py/runtime.c
16
py/runtime.c
@ -779,11 +779,19 @@ mp_obj_t rt_load_attr(mp_obj_t base, qstr attr) {
|
||||
if (MP_OBJ_IS_TYPE(base, &class_type)) {
|
||||
mp_map_elem_t *elem = mp_qstr_map_lookup(mp_obj_class_get_locals(base), attr, false);
|
||||
if (elem == NULL) {
|
||||
nlr_jump(mp_obj_new_exception_msg_2_args(rt_q_AttributeError, "'%s' object has no attribute '%s'", mp_obj_get_type_str(base), qstr_str(attr)));
|
||||
// TODO what about generic method lookup?
|
||||
goto no_attr;
|
||||
}
|
||||
return elem->value;
|
||||
} else if (MP_OBJ_IS_TYPE(base, &instance_type)) {
|
||||
return mp_obj_instance_load_attr(base, attr);
|
||||
} else if (MP_OBJ_IS_TYPE(base, &module_type)) {
|
||||
mp_map_elem_t *elem = mp_qstr_map_lookup(mp_obj_module_get_globals(base), attr, false);
|
||||
if (elem == NULL) {
|
||||
// TODO what about generic method lookup?
|
||||
goto no_attr;
|
||||
}
|
||||
return elem->value;
|
||||
} else if (MP_OBJ_IS_OBJ(base)) {
|
||||
// generic method lookup
|
||||
mp_obj_base_t *o = base;
|
||||
@ -794,6 +802,8 @@ mp_obj_t rt_load_attr(mp_obj_t base, qstr attr) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
no_attr:
|
||||
nlr_jump(mp_obj_new_exception_msg_2_args(rt_q_AttributeError, "'%s' object has no attribute '%s'", mp_obj_get_type_str(base), qstr_str(attr)));
|
||||
}
|
||||
|
||||
@ -832,6 +842,10 @@ void rt_store_attr(mp_obj_t base, qstr attr, mp_obj_t value) {
|
||||
mp_qstr_map_lookup(locals, attr, true)->value = value;
|
||||
} else if (MP_OBJ_IS_TYPE(base, &instance_type)) {
|
||||
mp_obj_instance_store_attr(base, attr, value);
|
||||
} else if (MP_OBJ_IS_TYPE(base, &module_type)) {
|
||||
// TODO CPython allows STORE_ATTR to a module, but is this the correct implementation?
|
||||
mp_map_t *globals = mp_obj_module_get_globals(base);
|
||||
mp_qstr_map_lookup(globals, attr, true)->value = value;
|
||||
} else {
|
||||
nlr_jump(mp_obj_new_exception_msg_2_args(rt_q_AttributeError, "'%s' object has no attribute '%s'", mp_obj_get_type_str(base), qstr_str(attr)));
|
||||
}
|
||||
|
@ -72,6 +72,7 @@ PY_O = \
|
||||
objgenerator.o \
|
||||
objinstance.o \
|
||||
objlist.o \
|
||||
objmodule.o \
|
||||
objnone.o \
|
||||
objrange.o \
|
||||
objset.o \
|
||||
|
126
stm/main.c
126
stm/main.c
@ -453,7 +453,7 @@ int readline(vstr_t *line, const char *prompt) {
|
||||
}
|
||||
|
||||
void do_repl(void) {
|
||||
stdout_tx_str("Micro Python 0.1; STM32F405RG; PYBv3\r\n");
|
||||
stdout_tx_str("Micro Python build <git hash> on 2/1/2014; PYBv3 with STM32F405RG\r\n");
|
||||
stdout_tx_str("Type \"help()\" for more information.\r\n");
|
||||
|
||||
vstr_t line;
|
||||
@ -587,38 +587,53 @@ mp_obj_t pyb_gc(void) {
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
#define MMA_ADDR (0x4c)
|
||||
mp_obj_t pyb_gpio(int n_args, mp_obj_t *args) {
|
||||
//assert(1 <= n_args && n_args <= 2);
|
||||
|
||||
int mma_buf[12];
|
||||
|
||||
mp_obj_t pyb_mma_read(void) {
|
||||
for (int i = 0; i <= 6; i += 3) {
|
||||
mma_buf[0 + i] = mma_buf[0 + i + 3];
|
||||
mma_buf[1 + i] = mma_buf[1 + i + 3];
|
||||
mma_buf[2 + i] = mma_buf[2 + i + 3];
|
||||
const char *pin_name = qstr_str(mp_obj_get_qstr(args[0]));
|
||||
GPIO_TypeDef *port;
|
||||
switch (pin_name[0]) {
|
||||
case 'A': case 'a': port = GPIOA; break;
|
||||
case 'B': case 'b': port = GPIOB; break;
|
||||
case 'C': case 'c': port = GPIOC; break;
|
||||
default: goto pin_error;
|
||||
}
|
||||
uint pin_num = 0;
|
||||
for (const char *s = pin_name + 1; *s; s++) {
|
||||
if (!('0' <= *s && *s <= '9')) {
|
||||
goto pin_error;
|
||||
}
|
||||
pin_num = 10 * pin_num + *s - '0';
|
||||
}
|
||||
if (!(0 <= pin_num && pin_num <= 15)) {
|
||||
goto pin_error;
|
||||
}
|
||||
|
||||
mma_start(MMA_ADDR, 1);
|
||||
mma_send_byte(0);
|
||||
mma_restart(MMA_ADDR, 0);
|
||||
for (int i = 0; i <= 2; i++) {
|
||||
int v = mma_read_ack() & 0x3f;
|
||||
if (v & 0x20) {
|
||||
v |= ~0x1f;
|
||||
if (n_args == 1) {
|
||||
// get pin
|
||||
if ((port->IDR & (1 << pin_num)) != (uint32_t)Bit_RESET) {
|
||||
return MP_OBJ_NEW_SMALL_INT(1);
|
||||
} else {
|
||||
return MP_OBJ_NEW_SMALL_INT(0);
|
||||
}
|
||||
mma_buf[9 + i] = v;
|
||||
} else {
|
||||
// set pin
|
||||
if (rt_is_true(args[1])) {
|
||||
// set pin high
|
||||
port->BSRRL = 1 << pin_num;
|
||||
} else {
|
||||
// set pin low
|
||||
port->BSRRH = 1 << pin_num;
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
int jolt_info = mma_read_nack();
|
||||
|
||||
mp_obj_t data[4];
|
||||
data[0] = mp_obj_new_int(jolt_info);
|
||||
data[1] = mp_obj_new_int(mma_buf[2] + mma_buf[5] + mma_buf[8] + mma_buf[11]);
|
||||
data[2] = mp_obj_new_int(mma_buf[1] + mma_buf[4] + mma_buf[7] + mma_buf[10]);
|
||||
data[3] = mp_obj_new_int(mma_buf[0] + mma_buf[3] + mma_buf[6] + mma_buf[9]);
|
||||
|
||||
return rt_build_tuple(4, data); // items in reverse order in data
|
||||
pin_error:
|
||||
nlr_jump(mp_obj_new_exception_msg_1_arg(rt_q_ValueError, "pin %s does not exist", pin_name));
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_gpio_obj, 1, 2, pyb_gpio);
|
||||
|
||||
mp_obj_t pyb_hid_send_report(mp_obj_t arg) {
|
||||
mp_obj_t *items = mp_obj_get_array_fixed_n(arg, 4);
|
||||
uint8_t data[4];
|
||||
@ -855,7 +870,7 @@ soft_reset:
|
||||
{
|
||||
rt_store_name(qstr_from_str_static("help"), rt_make_function_0(pyb_help));
|
||||
|
||||
mp_obj_t m = mp_module_new();
|
||||
mp_obj_t m = mp_obj_new_module(qstr_from_str_static("pyb"));
|
||||
rt_store_attr(m, qstr_from_str_static("info"), rt_make_function_0(pyb_info));
|
||||
rt_store_attr(m, qstr_from_str_static("sd_test"), rt_make_function_0(pyb_sd_test));
|
||||
rt_store_attr(m, qstr_from_str_static("stop"), rt_make_function_0(pyb_stop));
|
||||
@ -869,7 +884,9 @@ soft_reset:
|
||||
rt_store_attr(m, qstr_from_str_static("switch"), rt_make_function_0(pyb_sw));
|
||||
rt_store_attr(m, qstr_from_str_static("servo"), rt_make_function_2(pyb_servo_set));
|
||||
rt_store_attr(m, qstr_from_str_static("pwm"), rt_make_function_2(pyb_pwm_set));
|
||||
rt_store_attr(m, qstr_from_str_static("accel"), rt_make_function_0(pyb_mma_read));
|
||||
rt_store_attr(m, qstr_from_str_static("accel"), (mp_obj_t)&pyb_mma_read_obj);
|
||||
rt_store_attr(m, qstr_from_str_static("mma_read"), (mp_obj_t)&pyb_mma_read_all_obj);
|
||||
rt_store_attr(m, qstr_from_str_static("mma_mode"), (mp_obj_t)&pyb_mma_write_mode_obj);
|
||||
rt_store_attr(m, qstr_from_str_static("hid"), rt_make_function_1(pyb_hid_send_report));
|
||||
rt_store_attr(m, qstr_from_str_static("time"), rt_make_function_0(pyb_rtc_read));
|
||||
rt_store_attr(m, qstr_from_str_static("uout"), rt_make_function_1(pyb_usart_send));
|
||||
@ -879,6 +896,7 @@ soft_reset:
|
||||
rt_store_attr(m, qstr_from_str_static("Led"), rt_make_function_1(pyb_Led));
|
||||
rt_store_attr(m, qstr_from_str_static("Servo"), rt_make_function_1(pyb_Servo));
|
||||
rt_store_attr(m, qstr_from_str_static("I2C"), rt_make_function_2(pyb_I2C));
|
||||
rt_store_attr(m, qstr_from_str_static("gpio"), (mp_obj_t)&pyb_gpio_obj);
|
||||
rt_store_name(qstr_from_str_static("pyb"), m);
|
||||
|
||||
rt_store_name(qstr_from_str_static("open"), rt_make_function_2(pyb_io_open));
|
||||
@ -985,56 +1003,6 @@ soft_reset:
|
||||
if (first_soft_reset) {
|
||||
// init and reset address to zero
|
||||
mma_init();
|
||||
mma_start(MMA_ADDR, 1);
|
||||
mma_send_byte(0);
|
||||
mma_stop();
|
||||
|
||||
/*
|
||||
// read and print all 11 registers
|
||||
mma_start(MMA_ADDR, 1);
|
||||
mma_send_byte(0);
|
||||
mma_restart(MMA_ADDR, 0);
|
||||
for (int i = 0; i <= 0xa; i++) {
|
||||
int data;
|
||||
if (i == 0xa) {
|
||||
data = mma_read_nack();
|
||||
} else {
|
||||
data = mma_read_ack();
|
||||
}
|
||||
printf(" %02x", data);
|
||||
}
|
||||
printf("\n");
|
||||
*/
|
||||
|
||||
// put into active mode
|
||||
mma_start(MMA_ADDR, 1);
|
||||
mma_send_byte(7); // mode
|
||||
mma_send_byte(1); // active mode
|
||||
mma_stop();
|
||||
|
||||
/*
|
||||
// infinite loop to read values
|
||||
for (;;) {
|
||||
sys_tick_delay_ms(500);
|
||||
|
||||
mma_start(MMA_ADDR, 1);
|
||||
mma_send_byte(0);
|
||||
mma_restart(MMA_ADDR, 0);
|
||||
for (int i = 0; i <= 3; i++) {
|
||||
int data;
|
||||
if (i == 3) {
|
||||
data = mma_read_nack();
|
||||
printf(" %02x\n", data);
|
||||
} else {
|
||||
data = mma_read_ack() & 0x3f;
|
||||
if (data & 0x20) {
|
||||
data |= ~0x1f;
|
||||
}
|
||||
printf(" % 2d", data);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// turn boot-up LED off
|
||||
@ -1220,9 +1188,9 @@ soft_reset:
|
||||
} else {
|
||||
data[0] = 0x00;
|
||||
}
|
||||
mma_start(MMA_ADDR, 1);
|
||||
mma_start(0x4c /* MMA_ADDR */, 1);
|
||||
mma_send_byte(0);
|
||||
mma_restart(MMA_ADDR, 0);
|
||||
mma_restart(0x4c /* MMA_ADDR */, 0);
|
||||
for (int i = 0; i <= 1; i++) {
|
||||
int v = mma_read_ack() & 0x3f;
|
||||
if (v & 0x20) {
|
||||
|
119
stm/mma.c
119
stm/mma.c
@ -5,9 +5,14 @@
|
||||
#include <stm32f4xx_gpio.h>
|
||||
|
||||
#include "misc.h"
|
||||
#include "mpconfig.h"
|
||||
#include "systick.h"
|
||||
#include "obj.h"
|
||||
#include "runtime.h"
|
||||
#include "mma.h"
|
||||
|
||||
#define MMA_ADDR (0x4c)
|
||||
|
||||
void mma_init(void) {
|
||||
RCC->APB1ENR |= RCC_APB1ENR_I2C1EN; // enable I2C1
|
||||
|
||||
@ -67,6 +72,58 @@ void mma_init(void) {
|
||||
sys_tick_delay_ms(20);
|
||||
|
||||
// set START bit in CR1 to generate a start cond!
|
||||
|
||||
// init the chip via I2C commands
|
||||
mma_start(MMA_ADDR, 1);
|
||||
mma_send_byte(0);
|
||||
mma_stop();
|
||||
|
||||
/*
|
||||
// read and print all 11 registers
|
||||
mma_start(MMA_ADDR, 1);
|
||||
mma_send_byte(0);
|
||||
mma_restart(MMA_ADDR, 0);
|
||||
for (int i = 0; i <= 0xa; i++) {
|
||||
int data;
|
||||
if (i == 0xa) {
|
||||
data = mma_read_nack();
|
||||
} else {
|
||||
data = mma_read_ack();
|
||||
}
|
||||
printf(" %02x", data);
|
||||
}
|
||||
printf("\n");
|
||||
*/
|
||||
|
||||
// put into active mode
|
||||
mma_start(MMA_ADDR, 1);
|
||||
mma_send_byte(7); // mode
|
||||
mma_send_byte(1); // active mode
|
||||
mma_stop();
|
||||
|
||||
/*
|
||||
// infinite loop to read values
|
||||
for (;;) {
|
||||
sys_tick_delay_ms(500);
|
||||
|
||||
mma_start(MMA_ADDR, 1);
|
||||
mma_send_byte(0);
|
||||
mma_restart(MMA_ADDR, 0);
|
||||
for (int i = 0; i <= 3; i++) {
|
||||
int data;
|
||||
if (i == 3) {
|
||||
data = mma_read_nack();
|
||||
printf(" %02x\n", data);
|
||||
} else {
|
||||
data = mma_read_ack() & 0x3f;
|
||||
if (data & 0x20) {
|
||||
data |= ~0x1f;
|
||||
}
|
||||
printf(" % 2d", data);
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
static uint32_t i2c_get_sr(void) {
|
||||
@ -179,3 +236,65 @@ void mma_stop(void) {
|
||||
// send stop condition
|
||||
I2C1->CR1 |= I2C_CR1_STOP;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
/* Micro Python bindings */
|
||||
|
||||
int mma_buf[12];
|
||||
|
||||
mp_obj_t pyb_mma_read(void) {
|
||||
for (int i = 0; i <= 6; i += 3) {
|
||||
mma_buf[0 + i] = mma_buf[0 + i + 3];
|
||||
mma_buf[1 + i] = mma_buf[1 + i + 3];
|
||||
mma_buf[2 + i] = mma_buf[2 + i + 3];
|
||||
}
|
||||
|
||||
mma_start(MMA_ADDR, 1);
|
||||
mma_send_byte(0);
|
||||
mma_restart(MMA_ADDR, 0);
|
||||
for (int i = 0; i <= 2; i++) {
|
||||
int v = mma_read_ack() & 0x3f;
|
||||
if (v & 0x20) {
|
||||
v |= ~0x1f;
|
||||
}
|
||||
mma_buf[9 + i] = v;
|
||||
}
|
||||
int jolt_info = mma_read_nack();
|
||||
|
||||
mp_obj_t data[4];
|
||||
data[0] = mp_obj_new_int(jolt_info);
|
||||
data[1] = mp_obj_new_int(mma_buf[2] + mma_buf[5] + mma_buf[8] + mma_buf[11]);
|
||||
data[2] = mp_obj_new_int(mma_buf[1] + mma_buf[4] + mma_buf[7] + mma_buf[10]);
|
||||
data[3] = mp_obj_new_int(mma_buf[0] + mma_buf[3] + mma_buf[6] + mma_buf[9]);
|
||||
|
||||
return rt_build_tuple(4, data); // items in reverse order in data
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(pyb_mma_read_obj, pyb_mma_read);
|
||||
|
||||
mp_obj_t pyb_mma_read_all(void) {
|
||||
mp_obj_t data[11];
|
||||
mma_start(MMA_ADDR, 1);
|
||||
mma_send_byte(0);
|
||||
mma_restart(MMA_ADDR, 0);
|
||||
for (int i = 0; i <= 9; i++) {
|
||||
data[10 - i] = mp_obj_new_int(mma_read_ack());
|
||||
}
|
||||
data[0] = mp_obj_new_int(mma_read_nack());
|
||||
|
||||
return rt_build_tuple(11, data); // items in reverse order in data
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(pyb_mma_read_all_obj, pyb_mma_read_all);
|
||||
|
||||
mp_obj_t pyb_mma_write_mode(mp_obj_t o_int, mp_obj_t o_mode) {
|
||||
mma_start(MMA_ADDR, 1);
|
||||
mma_send_byte(6); // start at int
|
||||
mma_send_byte(mp_obj_get_int(o_int));
|
||||
mma_send_byte(mp_obj_get_int(o_mode));
|
||||
mma_stop();
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
MP_DEFINE_CONST_FUN_OBJ_2(pyb_mma_write_mode_obj, pyb_mma_write_mode);
|
||||
|
||||
|
@ -5,3 +5,7 @@ void mma_send_byte(uint8_t data);
|
||||
uint8_t mma_read_ack(void);
|
||||
uint8_t mma_read_nack(void);
|
||||
void mma_stop(void);
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_mma_read_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_mma_read_all_obj);
|
||||
MP_DECLARE_CONST_FUN_OBJ(pyb_mma_write_mode_obj);
|
||||
|
@ -39,6 +39,7 @@ PY_O = \
|
||||
objgenerator.o \
|
||||
objinstance.o \
|
||||
objlist.o \
|
||||
objmodule.o \
|
||||
objnone.o \
|
||||
objrange.o \
|
||||
objset.o \
|
||||
|
@ -46,6 +46,7 @@ PY_O = \
|
||||
objgenerator.o \
|
||||
objinstance.o \
|
||||
objlist.o \
|
||||
objmodule.o \
|
||||
objnone.o \
|
||||
objrange.o \
|
||||
objset.o \
|
||||
|
Loading…
x
Reference in New Issue
Block a user