diff options
-rw-r--r-- | py/builtineval.c | 5 | ||||
-rw-r--r-- | py/builtinimport.c | 7 | ||||
-rw-r--r-- | py/emitbc.c | 26 | ||||
-rw-r--r-- | py/emitcpy.c | 31 | ||||
-rw-r--r-- | py/lexer.c | 8 | ||||
-rw-r--r-- | py/lexer.h | 4 | ||||
-rw-r--r-- | py/lexerstr.c | 2 | ||||
-rw-r--r-- | py/lexerunix.c | 2 | ||||
-rw-r--r-- | py/obj.h | 1 | ||||
-rw-r--r-- | py/objstr.c | 62 | ||||
-rw-r--r-- | py/parse.c | 38 | ||||
-rw-r--r-- | py/parse.h | 1 | ||||
-rw-r--r-- | py/qstrdefs.h | 1 | ||||
-rw-r--r-- | py/vm.c | 9 | ||||
-rw-r--r-- | stm/adc.c | 231 | ||||
-rw-r--r-- | stm/adc.h | 3 | ||||
-rw-r--r-- | stm/lcd.c | 2 | ||||
-rw-r--r-- | stm/lexerfatfs.c | 2 | ||||
-rw-r--r-- | stm/lib/stm324x7i_eval.c | 2 | ||||
-rw-r--r-- | stm/lib/stm324x7i_eval.h | 2 | ||||
-rw-r--r-- | stm/lib/stm324x7i_eval_sdio_sd.c | 2 | ||||
-rw-r--r-- | stm/main.c | 14 | ||||
-rw-r--r-- | stm/mpconfigport.h | 12 | ||||
-rw-r--r-- | stm/usart.c | 2 | ||||
-rw-r--r-- | stm/usrsw.c | 2 | ||||
-rw-r--r-- | unix/main.c | 4 |
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); } /******************************************************************************/ @@ -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>) @@ -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); } @@ -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); @@ -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); @@ -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); } |