summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--py/builtineval.c5
-rw-r--r--py/builtinimport.c7
-rw-r--r--py/emitbc.c26
-rw-r--r--py/emitcpy.c31
-rw-r--r--py/lexer.c8
-rw-r--r--py/lexer.h4
-rw-r--r--py/lexerstr.c2
-rw-r--r--py/lexerunix.c2
-rw-r--r--py/obj.h1
-rw-r--r--py/objstr.c62
-rw-r--r--py/parse.c38
-rw-r--r--py/parse.h1
-rw-r--r--py/qstrdefs.h1
-rw-r--r--py/vm.c9
-rw-r--r--stm/adc.c231
-rw-r--r--stm/adc.h3
-rw-r--r--stm/lcd.c2
-rw-r--r--stm/lexerfatfs.c2
-rw-r--r--stm/lib/stm324x7i_eval.c2
-rw-r--r--stm/lib/stm324x7i_eval.h2
-rw-r--r--stm/lib/stm324x7i_eval_sdio_sd.c2
-rw-r--r--stm/main.c14
-rw-r--r--stm/mpconfigport.h12
-rw-r--r--stm/usart.c2
-rw-r--r--stm/usrsw.c2
-rw-r--r--unix/main.c4
26 files changed, 345 insertions, 130 deletions
diff --git a/py/builtineval.c b/py/builtineval.c
index 0e8f9e31d2..49d2bf16a2 100644
--- a/py/builtineval.c
+++ b/py/builtineval.c
@@ -24,13 +24,13 @@ static mp_obj_t mp_builtin_eval(mp_obj_t o_in) {
const byte *str = mp_obj_str_get_data(o_in, &str_len);
// create the lexer
- mp_lexer_t *lex = mp_lexer_new_from_str_len("<string>", (const char*)str, str_len, 0);
+ mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_string_gt_, (const char*)str, str_len, 0);
+ qstr source_name = mp_lexer_source_name(lex);
// parse the string
qstr parse_exc_id;
const char *parse_exc_msg;
mp_parse_node_t pn = mp_parse(lex, MP_PARSE_EVAL_INPUT, &parse_exc_id, &parse_exc_msg);
- qstr source_name = mp_lexer_source_name(lex);
mp_lexer_free(lex);
if (pn == MP_PARSE_NODE_NULL) {
@@ -40,6 +40,7 @@ static mp_obj_t mp_builtin_eval(mp_obj_t o_in) {
// compile the string
mp_obj_t module_fun = mp_compile(pn, source_name, false);
+ mp_parse_node_free(pn);
if (module_fun == mp_const_none) {
// TODO handle compile error correctly
diff --git a/py/builtinimport.c b/py/builtinimport.c
index 3cfd64e887..35e7dcbb88 100644
--- a/py/builtinimport.c
+++ b/py/builtinimport.c
@@ -29,9 +29,7 @@ mp_obj_t mp_builtin___import__(int n_args, mp_obj_t *args) {
}
*/
- uint mod_name_l;
- const byte *mod_name_s = mp_obj_str_get_data(args[0], &mod_name_l);
- qstr mod_name = qstr_from_strn((const char*)mod_name_s, mod_name_l);
+ qstr mod_name = mp_obj_str_get_qstr(args[0]);
mp_obj_t loaded = mp_obj_module_get(mod_name);
if (loaded != MP_OBJ_NULL) {
@@ -44,6 +42,7 @@ mp_obj_t mp_builtin___import__(int n_args, mp_obj_t *args) {
// TODO handle lexer error correctly
return mp_const_none;
}
+ qstr source_name = mp_lexer_source_name(lex);
// create a new module object
mp_obj_t module_obj = mp_obj_new_module(mod_name);
@@ -60,7 +59,6 @@ mp_obj_t mp_builtin___import__(int n_args, mp_obj_t *args) {
qstr parse_exc_id;
const char *parse_exc_msg;
mp_parse_node_t pn = mp_parse(lex, MP_PARSE_FILE_INPUT, &parse_exc_id, &parse_exc_msg);
- qstr source_name = mp_lexer_source_name(lex);
mp_lexer_free(lex);
if (pn == MP_PARSE_NODE_NULL) {
@@ -72,6 +70,7 @@ mp_obj_t mp_builtin___import__(int n_args, mp_obj_t *args) {
// compile the imported script
mp_obj_t module_fun = mp_compile(pn, source_name, false);
+ mp_parse_node_free(pn);
if (module_fun == mp_const_none) {
// TODO handle compile error correctly
diff --git a/py/emitbc.c b/py/emitbc.c
index 10a95fbcfa..9fa2880ecb 100644
--- a/py/emitbc.c
+++ b/py/emitbc.c
@@ -71,10 +71,14 @@ static void emit_write_code_info_qstr(emit_t* emit, qstr qstr) {
c[3] = (qstr >> 24) & 0xff;
}
-static void emit_write_code_info_byte_byte(emit_t* emit, byte b1, uint b2) {
- byte* c = emit_get_cur_to_write_code_info(emit, 2);
- c[0] = b1;
- c[1] = b2;
+static void emit_write_code_info_bytes_lines(emit_t* emit, uint bytes_to_skip, uint lines_to_skip) {
+ for (; bytes_to_skip > 31; bytes_to_skip -= 31) {
+ *emit_get_cur_to_write_code_info(emit, 1) = 31;
+ }
+ for (; lines_to_skip > 7; lines_to_skip -= 7) {
+ *emit_get_cur_to_write_code_info(emit, 1) = 7 << 5;
+ }
+ *emit_get_cur_to_write_code_info(emit, 1) = bytes_to_skip | (lines_to_skip << 5);
}
// all functions must go through this one to emit byte code
@@ -218,7 +222,7 @@ static void emit_bc_end_pass(emit_t *emit) {
printf("ERROR: stack size not back to zero; got %d\n", emit->stack_size);
}
- emit_write_code_info_byte_byte(emit, 0, 0); // end of line number info
+ emit_write_code_info_bytes_lines(emit, 0, 0); // end of line number info
if (emit->pass == PASS_2) {
// calculate size of code in bytes
@@ -246,15 +250,9 @@ static void emit_bc_set_stack_size(emit_t *emit, int size) {
static void emit_bc_set_source_line(emit_t *emit, int source_line) {
//printf("source: line %d -> %d offset %d -> %d\n", emit->last_source_line, source_line, emit->last_source_line_offset, emit->byte_code_offset);
if (source_line > emit->last_source_line) {
- int bytes_to_skip = emit->byte_code_offset - emit->last_source_line_offset;
- for (; bytes_to_skip > 255; bytes_to_skip -= 255) {
- emit_write_code_info_byte_byte(emit, 255, 0);
- }
- int lines_to_skip = source_line - emit->last_source_line;
- for (; lines_to_skip > 255; lines_to_skip -= 255) {
- emit_write_code_info_byte_byte(emit, 0, 255);
- }
- emit_write_code_info_byte_byte(emit, bytes_to_skip, lines_to_skip);
+ uint bytes_to_skip = emit->byte_code_offset - emit->last_source_line_offset;
+ uint lines_to_skip = source_line - emit->last_source_line;
+ emit_write_code_info_bytes_lines(emit, bytes_to_skip, lines_to_skip);
//printf(" %d %d\n", bytes_to_skip, lines_to_skip);
emit->last_source_line_offset = emit->byte_code_offset;
emit->last_source_line = source_line;
diff --git a/py/emitcpy.c b/py/emitcpy.c
index de2a5784db..71861c918d 100644
--- a/py/emitcpy.c
+++ b/py/emitcpy.c
@@ -192,29 +192,26 @@ static void print_quoted_str(qstr qstr, bool bytes) {
if (bytes) {
printf("b");
}
- bool quote_single = false;
+ int quote_char = '\'';
if (has_single_quote && !has_double_quote) {
- printf("\"");
- } else {
- quote_single = true;
- printf("'");
+ quote_char = '"';
}
- for (int i = 0; i < len; i++) {
- if (str[i] == '\n') {
- printf("\\n");
- } else if (str[i] == '\\') {
+ printf("%c", quote_char);
+ for (const char *s = str, *top = str + len; s < top; s++) {
+ if (*s == quote_char) {
+ printf("\\%c", quote_char);
+ } else if (*s == '\\') {
printf("\\\\");
- } else if (str[i] == '\'' && quote_single) {
- printf("\\'");
+ } else if (32 <= *s && *s <= 126) {
+ printf("%c", *s);
+ } else if (*s == '\n') {
+ printf("\\n");
+ // TODO add more escape codes here
} else {
- printf("%c", str[i]);
+ printf("\\x%02x", (*s) & 0xff);
}
}
- if (has_single_quote && !has_double_quote) {
- printf("\"");
- } else {
- printf("'");
- }
+ printf("%c", quote_char);
}
static void emit_cpy_load_const_str(emit_t *emit, qstr qstr, bool bytes) {
diff --git a/py/lexer.c b/py/lexer.c
index 9911da33d9..f71e355476 100644
--- a/py/lexer.c
+++ b/py/lexer.c
@@ -493,8 +493,8 @@ static void mp_lexer_next_token_into(mp_lexer_t *lex, mp_token_t *tok, bool firs
}
c = num;
} else {
- // TODO error message
- assert(0);
+ // unrecognised escape character; CPython lets this through verbatim as '\' and then the character
+ vstr_add_char(&lex->vstr, '\\');
}
break;
}
@@ -644,10 +644,10 @@ static void mp_lexer_next_token_into(mp_lexer_t *lex, mp_token_t *tok, bool firs
}
}
-mp_lexer_t *mp_lexer_new(const char *src_name, void *stream_data, mp_lexer_stream_next_char_t stream_next_char, mp_lexer_stream_close_t stream_close) {
+mp_lexer_t *mp_lexer_new(qstr src_name, void *stream_data, mp_lexer_stream_next_char_t stream_next_char, mp_lexer_stream_close_t stream_close) {
mp_lexer_t *lex = m_new(mp_lexer_t, 1);
- lex->source_name = qstr_from_str(src_name);
+ lex->source_name = src_name;
lex->stream_data = stream_data;
lex->stream_next_char = stream_next_char;
lex->stream_close = stream_close;
diff --git a/py/lexer.h b/py/lexer.h
index 69e97329b6..13fbfb5d33 100644
--- a/py/lexer.h
+++ b/py/lexer.h
@@ -124,8 +124,8 @@ typedef struct _mp_lexer_t mp_lexer_t;
void mp_token_show(const mp_token_t *tok);
-mp_lexer_t *mp_lexer_new(const char *src_name, void *stream_data, mp_lexer_stream_next_char_t stream_next_char, mp_lexer_stream_close_t stream_close);
-mp_lexer_t *mp_lexer_new_from_str_len(const char *src_name, const char *str, uint len, uint free_len);
+mp_lexer_t *mp_lexer_new(qstr src_name, void *stream_data, mp_lexer_stream_next_char_t stream_next_char, mp_lexer_stream_close_t stream_close);
+mp_lexer_t *mp_lexer_new_from_str_len(qstr src_name, const char *str, uint len, uint free_len);
void mp_lexer_free(mp_lexer_t *lex);
qstr mp_lexer_source_name(mp_lexer_t *lex);
diff --git a/py/lexerstr.c b/py/lexerstr.c
index 1e105d8645..d53a47d0c9 100644
--- a/py/lexerstr.c
+++ b/py/lexerstr.c
@@ -28,7 +28,7 @@ static void str_buf_free(mp_lexer_str_buf_t *sb) {
m_del_obj(mp_lexer_str_buf_t, sb);
}
-mp_lexer_t *mp_lexer_new_from_str_len(const char *src_name, const char *str, uint len, uint free_len) {
+mp_lexer_t *mp_lexer_new_from_str_len(qstr src_name, const char *str, uint len, uint free_len) {
mp_lexer_str_buf_t *sb = m_new_obj(mp_lexer_str_buf_t);
sb->free_len = free_len;
sb->src_beg = str;
diff --git a/py/lexerunix.c b/py/lexerunix.c
index 7846120a4a..5d96c468f8 100644
--- a/py/lexerunix.c
+++ b/py/lexerunix.c
@@ -28,7 +28,7 @@ mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
return NULL;
}
- return mp_lexer_new_from_str_len(filename, data, size, size);
+ return mp_lexer_new_from_str_len(qstr_from_str(filename), data, size, size);
}
/******************************************************************************/
diff --git a/py/obj.h b/py/obj.h
index e122f5a2bf..b33e3c5981 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -287,6 +287,7 @@ mp_obj_t mp_obj_str_builder_end(mp_obj_t o_in);
bool mp_obj_str_equal(mp_obj_t s1, mp_obj_t s2);
uint mp_obj_str_get_hash(mp_obj_t self_in);
uint mp_obj_str_get_len(mp_obj_t self_in);
+qstr mp_obj_str_get_qstr(mp_obj_t self_in); // use this if you will anyway convert the string to a qstr
const char *mp_obj_str_get_str(mp_obj_t self_in); // use this only if you need the string to be null terminated
const byte *mp_obj_str_get_data(mp_obj_t self_in, uint *len);
diff --git a/py/objstr.c b/py/objstr.c
index 3a4d69cfcc..84ac74bab9 100644
--- a/py/objstr.c
+++ b/py/objstr.c
@@ -40,11 +40,39 @@ void str_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj
if (kind == PRINT_STR && !is_bytes) {
print(env, "%.*s", str_len, str_data);
} else {
+ // this escapes characters, but it will be very slow to print (calling print many times)
+ bool has_single_quote = false;
+ bool has_double_quote = false;
+ for (const byte *s = str_data, *top = str_data + str_len; (!has_single_quote || !has_double_quote) && s < top; s++) {
+ if (*s == '\'') {
+ has_single_quote = true;
+ } else if (*s == '"') {
+ has_double_quote = true;
+ }
+ }
if (is_bytes) {
print(env, "b");
}
- // TODO need to escape chars etc
- print(env, "'%.*s'", str_len, str_data);
+ int quote_char = '\'';
+ if (has_single_quote && !has_double_quote) {
+ quote_char = '"';
+ }
+ print(env, "%c", quote_char);
+ for (const byte *s = str_data, *top = str_data + str_len; s < top; s++) {
+ if (*s == quote_char) {
+ print(env, "\\%c", quote_char);
+ } else if (*s == '\\') {
+ print(env, "\\\\");
+ } else if (32 <= *s && *s <= 126) {
+ print(env, "%c", *s);
+ } else if (*s == '\n') {
+ print(env, "\\n");
+ // TODO add more escape codes here if we want to match CPython
+ } else {
+ print(env, "\\x%02x", *s);
+ }
+ }
+ print(env, "%c", quote_char);
}
}
@@ -474,13 +502,17 @@ bool mp_obj_str_equal(mp_obj_t s1, mp_obj_t s2) {
}
}
+void bad_implicit_conversion(mp_obj_t self_in) __attribute__((noreturn));
+void bad_implicit_conversion(mp_obj_t self_in) {
+ nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "Can't convert '%s' object to str implicitly", mp_obj_get_type_str(self_in)));
+}
+
uint mp_obj_str_get_hash(mp_obj_t self_in) {
if (MP_OBJ_IS_STR(self_in)) {
GET_STR_HASH(self_in, h);
return h;
} else {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "Can't convert '%s' object to str implicitly",
- mp_obj_get_type_str(self_in)));
+ bad_implicit_conversion(self_in);
}
}
@@ -489,8 +521,20 @@ uint mp_obj_str_get_len(mp_obj_t self_in) {
GET_STR_LEN(self_in, l);
return l;
} else {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "Can't convert '%s' object to str implicitly",
- mp_obj_get_type_str(self_in)));
+ bad_implicit_conversion(self_in);
+ }
+}
+
+// use this if you will anyway convert the string to a qstr
+// will be more efficient for the case where it's already a qstr
+qstr mp_obj_str_get_qstr(mp_obj_t self_in) {
+ if (MP_OBJ_IS_QSTR(self_in)) {
+ return MP_OBJ_QSTR_VALUE(self_in);
+ } else if (MP_OBJ_IS_TYPE(self_in, &str_type)) {
+ mp_obj_str_t *self = self_in;
+ return qstr_from_strn((char*)self->data, self->len);
+ } else {
+ bad_implicit_conversion(self_in);
}
}
@@ -502,8 +546,7 @@ const char *mp_obj_str_get_str(mp_obj_t self_in) {
(void)l; // len unused
return (const char*)s;
} else {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "Can't convert '%s' object to str implicitly",
- mp_obj_get_type_str(self_in)));
+ bad_implicit_conversion(self_in);
}
}
@@ -513,8 +556,7 @@ const byte *mp_obj_str_get_data(mp_obj_t self_in, uint *len) {
*len = l;
return s;
} else {
- nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError, "Can't convert '%s' object to str implicitly",
- mp_obj_get_type_str(self_in)));
+ bad_implicit_conversion(self_in);
}
}
diff --git a/py/parse.c b/py/parse.c
index 3cf909d752..d9969d6785 100644
--- a/py/parse.c
+++ b/py/parse.c
@@ -26,6 +26,8 @@
#define RULE_ARG_OPT_TOK (0x3000)
#define RULE_ARG_OPT_RULE (0x4000)
+#define ADD_BLANK_NODE(rule_id) ((rule_id) == RULE_funcdef || (rule_id) == RULE_classdef || (rule_id) == RULE_comp_for || (rule_id) == RULE_lambdef || (rule_id) == RULE_lambdef_nocond)
+
// (un)comment to use rule names; for debugging
//#define USE_RULE_NAME (1)
@@ -135,6 +137,28 @@ mp_parse_node_struct_t *parse_node_new_struct(int src_line, int rule_id, int num
return pn;
}
+uint mp_parse_node_free(mp_parse_node_t pn) {
+ uint cnt = 0;
+ if (MP_PARSE_NODE_IS_STRUCT(pn)) {
+ mp_parse_node_struct_t *pns = (mp_parse_node_struct_t *)pn;
+ uint n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns);
+ uint rule_id = MP_PARSE_NODE_STRUCT_KIND(pns);
+ bool adjust = ADD_BLANK_NODE(rule_id);
+ if (adjust) {
+ n--;
+ }
+ for (uint i = 0; i < n; i++) {
+ cnt += mp_parse_node_free(pns->nodes[i]);
+ }
+ if (adjust) {
+ n++;
+ }
+ m_del_var(mp_parse_node_struct_t, mp_parse_node_t, n, pns);
+ cnt++;
+ }
+ return cnt;
+}
+
#if MICROPY_DEBUG_PRINTERS
void mp_parse_node_print(mp_parse_node_t pn, int indent) {
if (MP_PARSE_NODE_IS_STRUCT(pn)) {
@@ -160,15 +184,15 @@ void mp_parse_node_print(mp_parse_node_t pn, int indent) {
default: assert(0);
}
} else {
- mp_parse_node_struct_t *pns2 = (mp_parse_node_struct_t*)pn;
- int n = pns2->kind_num_nodes >> 8;
+ mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn;
+ uint n = MP_PARSE_NODE_STRUCT_NUM_NODES(pns);
#ifdef USE_RULE_NAME
- printf("%s(%d) (n=%d)\n", rules[MP_PARSE_NODE_STRUCT_KIND(pns2)]->rule_name, MP_PARSE_NODE_STRUCT_KIND(pns2), n);
+ printf("%s(%d) (n=%d)\n", rules[MP_PARSE_NODE_STRUCT_KIND(pns)]->rule_name, MP_PARSE_NODE_STRUCT_KIND(pns), n);
#else
- printf("rule(%u) (n=%d)\n", (uint)MP_PARSE_NODE_STRUCT_KIND(pns2), n);
+ printf("rule(%u) (n=%d)\n", (uint)MP_PARSE_NODE_STRUCT_KIND(pns), n);
#endif
- for (int i = 0; i < n; i++) {
- mp_parse_node_print(pns2->nodes[i], indent + 2);
+ for (uint i = 0; i < n; i++) {
+ mp_parse_node_print(pns->nodes[i], indent + 2);
}
}
}
@@ -458,7 +482,7 @@ mp_parse_node_t mp_parse(mp_lexer_t *lex, mp_parse_input_kind_t input_kind, qstr
}
// always emit these rules, and add an extra blank node at the end (to be used by the compiler to store data)
- if (rule->rule_id == RULE_funcdef || rule->rule_id == RULE_classdef || rule->rule_id == RULE_comp_for || rule->rule_id == RULE_lambdef || rule->rule_id == RULE_lambdef_nocond) {
+ if (ADD_BLANK_NODE(rule->rule_id)) {
emit_rule = true;
push_result_node(parser, MP_PARSE_NODE_NULL);
i += 1;
diff --git a/py/parse.h b/py/parse.h
index 2801f414ee..9797873d1b 100644
--- a/py/parse.h
+++ b/py/parse.h
@@ -53,6 +53,7 @@ typedef struct _mp_parse_node_struct_t {
#define MP_PARSE_NODE_STRUCT_NUM_NODES(pns) ((pns)->kind_num_nodes >> 8)
mp_parse_node_t mp_parse_node_new_leaf(machine_int_t kind, machine_int_t arg);
+uint mp_parse_node_free(mp_parse_node_t pn);
void mp_parse_node_print(mp_parse_node_t pn, int indent);
diff --git a/py/qstrdefs.h b/py/qstrdefs.h
index e76efaf0e0..81706841cd 100644
--- a/py/qstrdefs.h
+++ b/py/qstrdefs.h
@@ -91,4 +91,5 @@ Q(<listcomp>)
Q(<dictcomp>)
Q(<setcomp>)
Q(<genexpr>)
+Q(<string>)
Q(<stdin>)
diff --git a/py/vm.c b/py/vm.c
index affa5943bd..82a9f893f3 100644
--- a/py/vm.c
+++ b/py/vm.c
@@ -550,12 +550,9 @@ bool mp_execute_byte_code_2(const byte *code_info, const byte **ip_in_out, mp_ob
machine_uint_t source_line = 1;
machine_uint_t bc = save_ip - code_info - code_info_size;
//printf("find %lu %d %d\n", bc, code_info[12], code_info[13]);
- for (const byte* ci = code_info + 12; bc >= ci[0]; ci += 2) {
- bc -= ci[0];
- source_line += ci[1];
- if (ci[0] == 0 && ci[1] == 0) {
- break;
- }
+ for (const byte* ci = code_info + 12; *ci && bc >= ((*ci) & 31); ci++) {
+ bc -= *ci & 31;
+ source_line += *ci >> 5;
}
mp_obj_exception_add_traceback(nlr.ret_val, source_file, source_line, block_name);
}
diff --git a/stm/adc.c b/stm/adc.c
index e54a464a84..a5cdc0e3e8 100644
--- a/stm/adc.c
+++ b/stm/adc.c
@@ -2,6 +2,7 @@
#include <stm32f4xx.h>
#include "misc.h"
+#include "nlr.h"
#include "mpconfig.h"
#include "qstr.h"
#include "obj.h"
@@ -41,7 +42,7 @@ typedef struct {
} gpio_t;
/* ADC GPIOs */
-static gpio_t adc_gpio[] = {
+static const gpio_t adc_gpio[] = {
{GPIOA, GPIO_Pin_0}, /* ADC123_IN0 */
{GPIOA, GPIO_Pin_1}, /* ADC123_IN1 */
{GPIOA, GPIO_Pin_2}, /* ADC123_IN2 */
@@ -61,7 +62,7 @@ static gpio_t adc_gpio[] = {
};
-void adc_init(uint32_t resolution) {
+void adc_init_all(uint32_t resolution) {
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
@@ -111,6 +112,54 @@ void adc_init(uint32_t resolution) {
ADC_TempSensorVrefintCmd(ENABLE);
}
+void adc_init_single(uint32_t channel) {
+ ADC_InitTypeDef ADC_InitStructure;
+ GPIO_InitTypeDef GPIO_InitStructure;
+ ADC_CommonInitTypeDef ADC_CommonInitStructure;
+
+ /* Enable ADCx, DMA and GPIO clocks */
+#if 0
+ /* GPIO clocks enabled in main */
+ RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA |
+ RCC_AHB1Periph_GPIOB |
+ RCC_AHB1Periph_GPIOC, ENABLE);
+#endif
+ RCC_APB2PeriphClockCmd(ADCx_CLK, ENABLE);
+
+ /* ADC Common Init */
+ ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
+ ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
+ ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
+ ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
+ ADC_CommonInit(&ADC_CommonInitStructure);
+
+ /* Configure ADC GPIO for the single channel */
+ GPIO_InitStructure.GPIO_Pin = adc_gpio[channel].pin;
+ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
+ GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
+ GPIO_Init(adc_gpio[channel].port, &GPIO_InitStructure);
+
+ /* ADCx Init */
+// ADC_DeInit();
+ ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
+ ADC_InitStructure.ADC_ScanConvMode = DISABLE;
+ ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
+ ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
+ ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
+ ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
+ ADC_InitStructure.ADC_NbrOfConversion = 1;
+ ADC_Init(ADCx, &ADC_InitStructure);
+
+ /* Enable ADCx */
+ ADC_Cmd(ADCx, ENABLE);
+
+ /* Enable VBAT/VREF monitor */
+ ADC_VBATCmd(ENABLE);
+
+ /* Enable temperature sensor */
+ ADC_TempSensorVrefintCmd(ENABLE);
+}
+
uint32_t adc_read_channel(int channel)
{
int timeout = 10000;
@@ -213,91 +262,183 @@ float adc_read_core_vref()
}
/******************************************************************************/
-/* Micro Python bindings */
+/* Micro Python bindings : adc_all object */
-typedef struct _pyb_adc_obj_t {
+typedef struct _pyb_obj_adc_all_t {
mp_obj_base_t base;
- int adc_id;
bool is_enabled;
-} pyb_adc_obj_t;
+} pyb_obj_adc_all_t;
+
+static void adc_all_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
+ print(env, "<ADC all>");
+}
-static mp_obj_t adc_obj_read_channel(mp_obj_t self_in, mp_obj_t channel) {
- mp_obj_t ret = mp_const_none;
- pyb_adc_obj_t *self = self_in;
+static mp_obj_t adc_all_read_channel(mp_obj_t self_in, mp_obj_t channel) {
+ pyb_obj_adc_all_t *self = self_in;
if (self->is_enabled) {
uint32_t chan = mp_obj_get_int(channel);
uint32_t data = adc_read_channel(chan);
- ret = mp_obj_new_int(data);
+ return mp_obj_new_int(data);
+ } else {
+ return mp_const_none;
}
- return ret;
}
-static mp_obj_t adc_obj_read_core_temp(mp_obj_t self_in) {
- mp_obj_t ret = mp_const_none;
- pyb_adc_obj_t *self = self_in;
+static mp_obj_t adc_all_read_core_temp(mp_obj_t self_in) {
+ pyb_obj_adc_all_t *self = self_in;
if (self->is_enabled) {
int data = adc_read_core_temp();
- ret = mp_obj_new_int(data);
+ return mp_obj_new_int(data);
+ } else {
+ return mp_const_none;
}
- return ret;
}
-static mp_obj_t adc_obj_read_core_vbat(mp_obj_t self_in) {
- mp_obj_t ret = mp_const_none;
- pyb_adc_obj_t *self = self_in;
+static mp_obj_t adc_all_read_core_vbat(mp_obj_t self_in) {
+ pyb_obj_adc_all_t *self = self_in;
if (self->is_enabled) {
float data = adc_read_core_vbat();
- ret = mp_obj_new_float(data);
+ return mp_obj_new_float(data);
+ } else {
+ return mp_const_none;
}
- return ret;
}
-static mp_obj_t adc_obj_read_core_vref(mp_obj_t self_in) {
- mp_obj_t ret = mp_const_none;
- pyb_adc_obj_t *self = self_in;
+static mp_obj_t adc_all_read_core_vref(mp_obj_t self_in) {
+ pyb_obj_adc_all_t *self = self_in;
if (self->is_enabled) {
float data = adc_read_core_vref();
- ret = mp_obj_new_float(data);
+ return mp_obj_new_float(data);
+ } else {
+ return mp_const_none;
}
- return ret;
}
-static void adc_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
- pyb_adc_obj_t *self = self_in;
- print(env, "<ADC %lu>", self->adc_id);
+static MP_DEFINE_CONST_FUN_OBJ_2(adc_all_read_channel_obj, adc_all_read_channel);
+static MP_DEFINE_CONST_FUN_OBJ_1(adc_all_read_core_temp_obj, adc_all_read_core_temp);
+static MP_DEFINE_CONST_FUN_OBJ_1(adc_all_read_core_vbat_obj, adc_all_read_core_vbat);
+static MP_DEFINE_CONST_FUN_OBJ_1(adc_all_read_core_vref_obj, adc_all_read_core_vref);
+
+static const mp_method_t adc_all_methods[] = {
+ { "read_channel", &adc_all_read_channel_obj},
+ { "read_core_temp", &adc_all_read_core_temp_obj},
+ { "read_core_vbat", &adc_all_read_core_vbat_obj},
+ { "read_core_vref", &adc_all_read_core_vref_obj},
+ { NULL, NULL },
+};
+
+static const mp_obj_type_t adc_all_type = {
+ { &mp_const_type },
+ "ADC_all",
+ .print = adc_all_print,
+ .methods = adc_all_methods,
+};
+
+mp_obj_t pyb_ADC_all(mp_obj_t resolution) {
+ /* init ADC */
+ adc_init_all(mp_obj_get_int(resolution));
+
+ pyb_obj_adc_all_t *o = m_new_obj(pyb_obj_adc_all_t);
+ o->base.type = &adc_all_type;
+ o->is_enabled = true;
+ return o;
}
-static MP_DEFINE_CONST_FUN_OBJ_2(adc_obj_read_channel_obj, adc_obj_read_channel);
-static MP_DEFINE_CONST_FUN_OBJ_1(adc_obj_read_core_temp_obj, adc_obj_read_core_temp);
-static MP_DEFINE_CONST_FUN_OBJ_1(adc_obj_read_core_vbat_obj, adc_obj_read_core_vbat);
-static MP_DEFINE_CONST_FUN_OBJ_1(adc_obj_read_core_vref_obj, adc_obj_read_core_vref);
+MP_DEFINE_CONST_FUN_OBJ_1(pyb_ADC_all_obj, pyb_ADC_all);
+
+/******************************************************************************/
+/* Micro Python bindings : adc object (single channel) */
+
+typedef struct _pyb_obj_adc_t {
+ mp_obj_base_t base;
+ mp_obj_t pin_name;
+ int channel;
+ bool is_enabled;
+} pyb_obj_adc_t;
+
+static void adc_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
+ pyb_obj_adc_t *self = self_in;
+ print(env, "<ADC on ");
+ mp_obj_print_helper(print, env, self->pin_name, PRINT_STR);
+ print(env, " channel=%lu>", self->channel);
+}
+
+static mp_obj_t adc_read(mp_obj_t self_in) {
+ pyb_obj_adc_t *self = self_in;
+
+ if (self->is_enabled) {
+ uint32_t data = adc_read_channel(self->channel);
+ return mp_obj_new_int(data);
+ } else {
+ return mp_const_none;
+ }
+}
+
+static MP_DEFINE_CONST_FUN_OBJ_1(adc_read_obj, adc_read);
static const mp_method_t adc_methods[] = {
- { "read_channel", &adc_obj_read_channel_obj},
- { "read_core_temp", &adc_obj_read_core_temp_obj},
- { "read_core_vbat", &adc_obj_read_core_vbat_obj},
- { "read_core_vref", &adc_obj_read_core_vref_obj},
+ { "read", &adc_read_obj},
{ NULL, NULL },
};
-static const mp_obj_type_t adc_obj_type = {
+static const mp_obj_type_t adc_type = {
{ &mp_const_type },
"ADC",
- .print = adc_obj_print,
+ .print = adc_print,
.methods = adc_methods,
};
-mp_obj_t pyb_ADC(mp_obj_t resolution) {
- /* init ADC */
- adc_init(mp_obj_get_int(resolution));
+mp_obj_t pyb_ADC(mp_obj_t pin_name_obj) {
+
+ pyb_obj_adc_t *o = m_new_obj(pyb_obj_adc_t);
+ o->base.type = &adc_type;
+ o->pin_name = pin_name_obj;
+
+ // work out the channel from the pin name
+ const char *pin_name = mp_obj_str_get_str(pin_name_obj);
+ 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;
+ }
+
+ int i;
+ for (i = 0; i < ADC_NUM_CHANNELS; i++) {
+ if (adc_gpio[i].port == port && adc_gpio[i].pin == (1 << pin_num)) {
+ o->channel = i;
+ break;
+ }
+ }
+
+ if (i == ADC_NUM_CHANNELS) {
+ nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_ValueError, "pin %s does not have ADC capabilities", pin_name));
+ }
+
+ // init ADC just for this channel
+ adc_init_single(o->channel);
- pyb_adc_obj_t *o = m_new_obj(pyb_adc_obj_t);
- o->base.type = &adc_obj_type;
- o->adc_id = 1;
o->is_enabled = true;
+
return o;
+
+pin_error:
+ nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_ValueError, "pin %s does not exist", pin_name));
}
+
+MP_DEFINE_CONST_FUN_OBJ_1(pyb_ADC_obj, pyb_ADC);
diff --git a/stm/adc.h b/stm/adc.h
index 5805aef42c..502da20dde 100644
--- a/stm/adc.h
+++ b/stm/adc.h
@@ -1 +1,2 @@
-mp_obj_t pyb_ADC(mp_obj_t resolution);
+MP_DECLARE_CONST_FUN_OBJ(pyb_ADC_all_obj);
+MP_DECLARE_CONST_FUN_OBJ(pyb_ADC_obj);
diff --git a/stm/lcd.c b/stm/lcd.c
index a7d473bf6a..e8553a69e3 100644
--- a/stm/lcd.c
+++ b/stm/lcd.c
@@ -13,7 +13,7 @@
#include "font_petme128_8x8.h"
#include "lcd.h"
-#if defined(PYBOARD)
+#if defined(PYBOARD3)
#define PYB_LCD_PORT (GPIOA)
#define PYB_LCD_CS1_PIN (GPIO_Pin_0)
#define PYB_LCD_RST_PIN (GPIO_Pin_1)
diff --git a/stm/lexerfatfs.c b/stm/lexerfatfs.c
index bf82349f35..026173db25 100644
--- a/stm/lexerfatfs.c
+++ b/stm/lexerfatfs.c
@@ -49,7 +49,7 @@ mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
f_read(&fb->fp, fb->buf, sizeof(fb->buf), &n);
fb->len = n;
fb->pos = 0;
- return mp_lexer_new(filename, fb, (mp_lexer_stream_next_char_t)file_buf_next_char, (mp_lexer_stream_close_t)file_buf_close);
+ return mp_lexer_new(qstr_from_str(filename), fb, (mp_lexer_stream_next_char_t)file_buf_next_char, (mp_lexer_stream_close_t)file_buf_close);
}
/******************************************************************************/
diff --git a/stm/lib/stm324x7i_eval.c b/stm/lib/stm324x7i_eval.c
index fa9fff31fe..c1be681f1d 100644
--- a/stm/lib/stm324x7i_eval.c
+++ b/stm/lib/stm324x7i_eval.c
@@ -122,7 +122,7 @@ void SD_LowLevel_Init(void)
GPIO_Init(GPIOC, &GPIO_InitStructure);
/*!< Configure SD_SPI_DETECT_PIN pin: SD Card detect pin */
-#if defined(PYBOARD)
+#if defined(PYBOARD3)
// dpgeorge: PYBv2-v3: switch is normally open, connected to VDD when card inserted
GPIO_InitStructure.GPIO_Pin = SD_DETECT_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; // needs to be 2MHz due to restrictions on PC13
diff --git a/stm/lib/stm324x7i_eval.h b/stm/lib/stm324x7i_eval.h
index a7df96acb0..9adeecb16e 100644
--- a/stm/lib/stm324x7i_eval.h
+++ b/stm/lib/stm324x7i_eval.h
@@ -41,7 +41,7 @@
/**
* @brief SD FLASH SDIO Interface
*/
-#if defined(PYBOARD)
+#if defined(PYBOARD3)
#define SD_DETECT_PIN GPIO_Pin_13 /* PC.13 */
#define SD_DETECT_GPIO_PORT GPIOC /* GPIOC */
#define SD_DETECT_GPIO_CLK RCC_AHB1Periph_GPIOC
diff --git a/stm/lib/stm324x7i_eval_sdio_sd.c b/stm/lib/stm324x7i_eval_sdio_sd.c
index f0e2ffc3e2..2d6f4b8c94 100644
--- a/stm/lib/stm324x7i_eval_sdio_sd.c
+++ b/stm/lib/stm324x7i_eval_sdio_sd.c
@@ -518,7 +518,7 @@ uint8_t SD_Detect(void)
__IO uint8_t status = SD_PRESENT;
/*!< Check GPIO to detect SD */
-#if defined(PYBOARD)
+#if defined(PYBOARD3)
if (GPIO_ReadInputDataBit(SD_DETECT_GPIO_PORT, SD_DETECT_PIN) != Bit_SET)
#elif defined(PYBOARD4)
if (GPIO_ReadInputDataBit(SD_DETECT_GPIO_PORT, SD_DETECT_PIN) == Bit_SET)
diff --git a/stm/main.c b/stm/main.c
index 4114ec1979..1388a1d900 100644
--- a/stm/main.c
+++ b/stm/main.c
@@ -137,8 +137,10 @@ static const char *help_text =
" pyb.switch() -- return True/False if switch pressed or not\n"
" pyb.accel() -- get accelerometer values\n"
" pyb.rand() -- get a 16-bit random number\n"
-" pyb.gpio(<port>) -- get port value (port='a4' for example)\n"
+" pyb.gpio(<port>) -- get port value (port='A4' for example)\n"
" pyb.gpio(<port>, <val>) -- set port value, True or False, 1 or 0\n"
+" pyb.ADC(<port>) -- make an analog port object (port='C0' for example)\n"
+" ADC methods: read()\n"
;
// get some help about available functions
@@ -348,7 +350,7 @@ int readline(vstr_t *line, const char *prompt) {
}
void do_repl(void) {
- stdout_tx_str("Micro Python build <git hash> on 2/1/2014; PYBv3 with STM32F405RG\r\n");
+ stdout_tx_str("Micro Python build <git hash> on 25/1/2014; " MICROPY_HW_BOARD_NAME " with STM32F405RG\r\n");
stdout_tx_str("Type \"help()\" for more information.\r\n");
vstr_t line;
@@ -378,7 +380,7 @@ void do_repl(void) {
}
}
- mp_lexer_t *lex = mp_lexer_new_from_str_len("<stdin>", vstr_str(&line), vstr_len(&line), 0);
+ mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, vstr_str(&line), vstr_len(&line), 0);
qstr parse_exc_id;
const char *parse_exc_msg;
mp_parse_node_t pn = mp_parse(lex, MP_PARSE_SINGLE_INPUT, &parse_exc_id, &parse_exc_msg);
@@ -393,6 +395,7 @@ void do_repl(void) {
// parse okay
mp_lexer_free(lex);
mp_obj_t module_fun = mp_compile(pn, source_name, true);
+ mp_parse_node_free(pn);
if (module_fun != mp_const_none) {
nlr_buf_t nlr;
uint32_t start = sys_tick_counter;
@@ -439,6 +442,8 @@ bool do_file(const char *filename) {
mp_lexer_free(lex);
mp_obj_t module_fun = mp_compile(pn, source_name, false);
+ mp_parse_node_free(pn);
+
if (module_fun == mp_const_none) {
return false;
}
@@ -651,7 +656,8 @@ soft_reset:
rt_store_attr(m, MP_QSTR_I2C, rt_make_function_n(2, pyb_I2C));
rt_store_attr(m, MP_QSTR_gpio, (mp_obj_t)&pyb_gpio_obj);
rt_store_attr(m, MP_QSTR_Usart, rt_make_function_n(2, pyb_Usart));
- rt_store_attr(m, MP_QSTR_ADC, rt_make_function_n(1, pyb_ADC));
+ rt_store_attr(m, qstr_from_str("ADC_all"), (mp_obj_t)&pyb_ADC_all_obj);
+ rt_store_attr(m, MP_QSTR_ADC, (mp_obj_t)&pyb_ADC_obj);
rt_store_name(MP_QSTR_pyb, m);
rt_store_name(MP_QSTR_open, rt_make_function_n(2, pyb_io_open));
diff --git a/stm/mpconfigport.h b/stm/mpconfigport.h
index 2851c1ad12..028aea0f19 100644
--- a/stm/mpconfigport.h
+++ b/stm/mpconfigport.h
@@ -23,11 +23,13 @@ machine_float_t machine_sqrt(machine_float_t x);
// board specific definitions
// choose 1 of these boards
-//#define PYBOARD
-#define PYBOARD4
+#define PYBOARD3
+//#define PYBOARD4
//#define STM32F4DISC
-#if defined (PYBOARD)
+#if defined (PYBOARD3)
+ #define MICROPY_HW_BOARD_NAME "PYBv3"
+
#define MICROPY_HW_HAS_SWITCH (1)
#define MICROPY_HW_HAS_SDCARD (1)
#define MICROPY_HW_HAS_MMA7660 (1)
@@ -68,6 +70,8 @@ machine_float_t machine_sqrt(machine_float_t x);
#define PYB_LED_OFF(port, pin) (port->BSRRL = pin)
#elif defined (PYBOARD4)
+ #define MICROPY_HW_BOARD_NAME "PYBv4"
+
#define MICROPY_HW_HAS_SWITCH (1)
#define MICROPY_HW_HAS_SDCARD (1)
#define MICROPY_HW_HAS_MMA7660 (1)
@@ -108,6 +112,8 @@ machine_float_t machine_sqrt(machine_float_t x);
#define PYB_LED_OFF(port, pin) (port->BSRRH = pin)
#elif defined (STM32F4DISC)
+ #define MICROPY_HW_BOARD_NAME "F4DISC"
+
#define MICROPY_HW_HAS_SWITCH (1)
#define MICROPY_HW_HAS_SDCARD (0)
#define MICROPY_HW_HAS_MMA7660 (0)
diff --git a/stm/usart.c b/stm/usart.c
index 1ab385174d..d9de599c46 100644
--- a/stm/usart.c
+++ b/stm/usart.c
@@ -77,7 +77,7 @@ void usart_init(pyb_usart_t usart_id, uint32_t baudrate) {
case PYB_USART_3:
USARTx = USART3;
-#if defined(PYBOARD4)
+#if defined(PYBOARD3) || defined(PYBOARD4)
GPIO_Port = GPIOB;
GPIO_AF_USARTx = GPIO_AF_USART3;
GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
diff --git a/stm/usrsw.c b/stm/usrsw.c
index 162cecfcf0..c3374b847e 100644
--- a/stm/usrsw.c
+++ b/stm/usrsw.c
@@ -44,7 +44,7 @@ void switch_init(void) {
}
int switch_get(void) {
-#if defined (PYBOARD) || defined (PYBOARD4)
+#if defined (PYBOARD3) || defined (PYBOARD4)
if (USRSW_PORT->IDR & USRSW_PIN) {
// pulled high, so switch is not pressed
return 0;
diff --git a/unix/main.c b/unix/main.c
index 681bf2aa20..212bbe877e 100644
--- a/unix/main.c
+++ b/unix/main.c
@@ -138,7 +138,7 @@ static void do_repl(void) {
}
}
- mp_lexer_t *lex = mp_lexer_new_from_str_len("<stdin>", line, strlen(line), false);
+ mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, line, strlen(line), false);
execute_from_lexer(lex, MP_PARSE_SINGLE_INPUT, true);
free(line);
}
@@ -162,7 +162,7 @@ static void do_file(const char *file) {
}
static void do_str(const char *str) {
- mp_lexer_t *lex = mp_lexer_new_from_str_len("<stdin>", str, strlen(str), false);
+ mp_lexer_t *lex = mp_lexer_new_from_str_len(MP_QSTR__lt_stdin_gt_, str, strlen(str), false);
execute_from_lexer(lex, MP_PARSE_SINGLE_INPUT, false);
}