Add module object, to be used eventually for import.

This commit is contained in:
Damien George 2014-01-02 21:30:26 +00:00
parent 0ff883904a
commit 2870862601
9 changed files with 243 additions and 84 deletions

View File

@ -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
View 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;
}

View File

@ -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)));
}

View File

@ -72,6 +72,7 @@ PY_O = \
objgenerator.o \
objinstance.o \
objlist.o \
objmodule.o \
objnone.o \
objrange.o \
objset.o \

View File

@ -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;
}
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;
uint pin_num = 0;
for (const char *s = pin_name + 1; *s; s++) {
if (!('0' <= *s && *s <= '9')) {
goto pin_error;
}
mma_buf[9 + i] = v;
pin_num = 10 * pin_num + *s - '0';
}
if (!(0 <= pin_num && pin_num <= 15)) {
goto pin_error;
}
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]);
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);
}
} 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;
}
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
View File

@ -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);

View File

@ -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);

View File

@ -39,6 +39,7 @@ PY_O = \
objgenerator.o \
objinstance.o \
objlist.o \
objmodule.o \
objnone.o \
objrange.o \
objset.o \

View File

@ -46,6 +46,7 @@ PY_O = \
objgenerator.o \
objinstance.o \
objlist.o \
objmodule.o \
objnone.o \
objrange.o \
objset.o \