diff options
39 files changed, 760 insertions, 758 deletions
diff --git a/CODECONVENTIONS.md b/CODECONVENTIONS.md index a0e0fc7ab2..c8dbdae3d3 100644 --- a/CODECONVENTIONS.md +++ b/CODECONVENTIONS.md @@ -1,7 +1,21 @@ -Code conventions -================ +Python code conventions +======================= -When writing new code, please adhere to the following conventions. +Python code follows [PEP 8](http://legacy.python.org/dev/peps/pep-0008/). + +Naming conventions: +- Module names are short and all lowercase; eg pyb, stm. +- Class names are CamelCase, with abreviations all uppercase; eg I2C, not + I2c. +- Function and method names are all lowercase with words separated by + a single underscore as necessary to improve readability; eg mem_read. +- Constants are all uppercase with words separated by a single underscore; + eg GPIO_IDR. + +C code conventions +================== + +When writing new C code, please adhere to the following conventions. White space: - Expand tabs to 4 spaces. @@ -18,8 +32,10 @@ Braces: - For else-statements, put the else on the same line as the previous closing brace. -Include directives: -- Don't include within a header file. +Header files: +- Try to stick to the Plan 9 header style, where header files do not + include other header files. +- Don't protect a header file from multiple inclusion with #if directives. Type names and declarations: - When defining a type, put '_t' after it. diff --git a/py/asmthumb.c b/py/asmthumb.c index 6bf6d66584..7037ac5187 100644 --- a/py/asmthumb.c +++ b/py/asmthumb.c @@ -121,22 +121,6 @@ STATIC void asm_thumb_write_byte_1(asm_thumb_t *as, byte b1) { } */ -STATIC void asm_thumb_write_op16(asm_thumb_t *as, uint op) { - byte *c = asm_thumb_get_cur_to_write_bytes(as, 2); - // little endian - c[0] = op; - c[1] = op >> 8; -} - -STATIC void asm_thumb_write_op32(asm_thumb_t *as, uint op1, uint op2) { - byte *c = asm_thumb_get_cur_to_write_bytes(as, 4); - // little endian, op1 then op2 - c[0] = op1; - c[1] = op1 >> 8; - c[2] = op2; - c[3] = op2 >> 8; -} - /* #define IMM32_L0(x) ((x) & 0xff) #define IMM32_L1(x) (((x) >> 8) & 0xff) @@ -196,9 +180,9 @@ void asm_thumb_entry(asm_thumb_t *as, int num_locals) { stack_adjust = ((num_locals - 3) + 1) & (~1); break; } - asm_thumb_write_op16(as, OP_PUSH_RLIST_LR(reglist)); + asm_thumb_op16(as, OP_PUSH_RLIST_LR(reglist)); if (stack_adjust > 0) { - asm_thumb_write_op16(as, OP_SUB_SP(stack_adjust)); + asm_thumb_op16(as, OP_SUB_SP(stack_adjust)); } as->push_reglist = reglist; as->stack_adjust = stack_adjust; @@ -207,9 +191,9 @@ void asm_thumb_entry(asm_thumb_t *as, int num_locals) { void asm_thumb_exit(asm_thumb_t *as) { if (as->stack_adjust > 0) { - asm_thumb_write_op16(as, OP_ADD_SP(as->stack_adjust)); + asm_thumb_op16(as, OP_ADD_SP(as->stack_adjust)); } - asm_thumb_write_op16(as, OP_POP_RLIST_PC(as->push_reglist)); + asm_thumb_op16(as, OP_POP_RLIST_PC(as->push_reglist)); } void asm_thumb_label_assign(asm_thumb_t *as, uint label) { @@ -230,19 +214,35 @@ STATIC int get_label_dest(asm_thumb_t *as, uint label) { return as->label_offsets[label]; } +void asm_thumb_op16(asm_thumb_t *as, uint op) { + byte *c = asm_thumb_get_cur_to_write_bytes(as, 2); + // little endian + c[0] = op; + c[1] = op >> 8; +} + +void asm_thumb_op32(asm_thumb_t *as, uint op1, uint op2) { + byte *c = asm_thumb_get_cur_to_write_bytes(as, 4); + // little endian, op1 then op2 + c[0] = op1; + c[1] = op1 >> 8; + c[2] = op2; + c[3] = op2 >> 8; +} + #define OP_FORMAT_2(op, rlo_dest, rlo_src, src_b) ((op) | ((src_b) << 6) | ((rlo_src) << 3) | (rlo_dest)) void asm_thumb_format_2(asm_thumb_t *as, uint op, uint rlo_dest, uint rlo_src, int src_b) { assert(rlo_dest < REG_R8); assert(rlo_src < REG_R8); - asm_thumb_write_op16(as, OP_FORMAT_2(op, rlo_dest, rlo_src, src_b)); + asm_thumb_op16(as, OP_FORMAT_2(op, rlo_dest, rlo_src, src_b)); } #define OP_FORMAT_3(op, rlo, i8) ((op) | ((rlo) << 8) | (i8)) void asm_thumb_format_3(asm_thumb_t *as, uint op, uint rlo, int i8) { assert(rlo < REG_R8); - asm_thumb_write_op16(as, OP_FORMAT_3(op, rlo, i8)); + asm_thumb_op16(as, OP_FORMAT_3(op, rlo, i8)); } #define OP_FORMAT_4(op, rlo_dest, rlo_src) ((op) | ((rlo_src) << 3) | (rlo_dest)) @@ -250,13 +250,13 @@ void asm_thumb_format_3(asm_thumb_t *as, uint op, uint rlo, int i8) { void asm_thumb_format_4(asm_thumb_t *as, uint op, uint rlo_dest, uint rlo_src) { assert(rlo_dest < REG_R8); assert(rlo_src < REG_R8); - asm_thumb_write_op16(as, OP_FORMAT_4(op, rlo_dest, rlo_src)); + asm_thumb_op16(as, OP_FORMAT_4(op, rlo_dest, rlo_src)); } #define OP_FORMAT_9_10(op, rlo_dest, rlo_base, offset) ((op) | (((offset) << 6) & 0x07c0) | ((rlo_base) << 3) | (rlo_dest)) void asm_thumb_format_9_10(asm_thumb_t *as, uint op, uint rlo_dest, uint rlo_base, uint offset) { - asm_thumb_write_op16(as, OP_FORMAT_9_10(op, rlo_dest, rlo_base, offset)); + asm_thumb_op16(as, OP_FORMAT_9_10(op, rlo_dest, rlo_base, offset)); } void asm_thumb_mov_reg_reg(asm_thumb_t *as, uint reg_dest, uint reg_src) { @@ -272,7 +272,7 @@ void asm_thumb_mov_reg_reg(asm_thumb_t *as, uint reg_dest, uint reg_src) { op_lo |= 0x80 | (reg_dest - 8); } // mov reg_dest, reg_src - asm_thumb_write_op16(as, 0x4600 | op_lo); + asm_thumb_op16(as, 0x4600 | op_lo); } #define OP_MOVW (0xf240) @@ -282,7 +282,7 @@ void asm_thumb_mov_reg_reg(asm_thumb_t *as, uint reg_dest, uint reg_src) { STATIC void asm_thumb_mov_reg_i16(asm_thumb_t *as, uint mov_op, uint reg_dest, int i16_src) { assert(reg_dest < REG_R15); // mov[wt] reg_dest, #i16_src - asm_thumb_write_op32(as, mov_op | ((i16_src >> 1) & 0x0400) | ((i16_src >> 12) & 0xf), ((i16_src << 4) & 0x7000) | (reg_dest << 8) | (i16_src & 0xff)); + asm_thumb_op32(as, mov_op | ((i16_src >> 1) & 0x0400) | ((i16_src >> 12) & 0xf), ((i16_src << 4) & 0x7000) | (reg_dest << 8) | (i16_src & 0xff)); } // the i16_src value will be zero extended into the r32 register! @@ -296,7 +296,7 @@ void asm_thumb_movt_reg_i16(asm_thumb_t *as, uint reg_dest, int i16_src) { } void asm_thumb_ite_ge(asm_thumb_t *as) { - asm_thumb_write_op16(as, 0xbfac); + asm_thumb_op16(as, 0xbfac); } #define OP_B_N(byte_offset) (0xe000 | (((byte_offset) >> 1) & 0x07ff)) @@ -306,7 +306,7 @@ void asm_thumb_b_n(asm_thumb_t *as, uint label) { int rel = dest - as->code_offset; rel -= 4; // account for instruction prefetch, PC is 4 bytes ahead of this instruction if (SIGNED_FIT12(rel)) { - asm_thumb_write_op16(as, OP_B_N(rel)); + asm_thumb_op16(as, OP_B_N(rel)); } else { printf("asm_thumb_b_n: branch does not fit in 12 bits\n"); } @@ -319,7 +319,7 @@ void asm_thumb_bcc_n(asm_thumb_t *as, int cond, uint label) { int rel = dest - as->code_offset; rel -= 4; // account for instruction prefetch, PC is 4 bytes ahead of this instruction if (SIGNED_FIT9(rel)) { - asm_thumb_write_op16(as, OP_BCC_N(cond, rel)); + asm_thumb_op16(as, OP_BCC_N(cond, rel)); } else { printf("asm_thumb_bcc_n: branch does not fit in 9 bits\n"); } @@ -350,14 +350,14 @@ void asm_thumb_mov_local_reg(asm_thumb_t *as, int local_num, uint rlo_src) { assert(rlo_src < REG_R8); int word_offset = as->num_locals - local_num - 1; assert(as->pass < ASM_THUMB_PASS_3 || word_offset >= 0); - asm_thumb_write_op16(as, OP_STR_TO_SP_OFFSET(rlo_src, word_offset)); + asm_thumb_op16(as, OP_STR_TO_SP_OFFSET(rlo_src, word_offset)); } void asm_thumb_mov_reg_local(asm_thumb_t *as, uint rlo_dest, int local_num) { assert(rlo_dest < REG_R8); int word_offset = as->num_locals - local_num - 1; assert(as->pass < ASM_THUMB_PASS_3 || word_offset >= 0); - asm_thumb_write_op16(as, OP_LDR_FROM_SP_OFFSET(rlo_dest, word_offset)); + asm_thumb_op16(as, OP_LDR_FROM_SP_OFFSET(rlo_dest, word_offset)); } #define OP_ADD_REG_SP_OFFSET(rlo_dest, word_offset) (0xa800 | ((rlo_dest) << 8) | ((word_offset) & 0x00ff)) @@ -366,7 +366,7 @@ void asm_thumb_mov_reg_local_addr(asm_thumb_t *as, uint rlo_dest, int local_num) assert(rlo_dest < REG_R8); int word_offset = as->num_locals - local_num - 1; assert(as->pass < ASM_THUMB_PASS_3 || word_offset >= 0); - asm_thumb_write_op16(as, OP_ADD_REG_SP_OFFSET(rlo_dest, word_offset)); + asm_thumb_op16(as, OP_ADD_REG_SP_OFFSET(rlo_dest, word_offset)); } // this could be wrong, because it should have a range of +/- 16MiB... @@ -381,14 +381,14 @@ void asm_thumb_b_label(asm_thumb_t *as, uint label) { // is a backwards jump, so we know the size of the jump on the first pass // calculate rel assuming 12 bit relative jump if (SIGNED_FIT12(rel)) { - asm_thumb_write_op16(as, OP_B_N(rel)); + asm_thumb_op16(as, OP_B_N(rel)); } else { goto large_jump; } } else { // is a forwards jump, so need to assume it's large large_jump: - asm_thumb_write_op32(as, OP_BW_HI(rel), OP_BW_LO(rel)); + asm_thumb_op32(as, OP_BW_HI(rel), OP_BW_LO(rel)); } } @@ -404,14 +404,14 @@ void asm_thumb_bcc_label(asm_thumb_t *as, int cond, uint label) { // is a backwards jump, so we know the size of the jump on the first pass // calculate rel assuming 9 bit relative jump if (SIGNED_FIT9(rel)) { - asm_thumb_write_op16(as, OP_BCC_N(cond, rel)); + asm_thumb_op16(as, OP_BCC_N(cond, rel)); } else { goto large_jump; } } else { // is a forwards jump, so need to assume it's large large_jump: - asm_thumb_write_op32(as, OP_BCC_W_HI(cond, rel), OP_BCC_W_LO(rel)); + asm_thumb_op32(as, OP_BCC_W_HI(cond, rel), OP_BCC_W_LO(rel)); } } @@ -423,22 +423,22 @@ void asm_thumb_bl_ind(asm_thumb_t *as, void *fun_ptr, uint fun_id, uint reg_temp uint rlo_base = REG_R3; uint rlo_dest = REG_R7; uint word_offset = 4; - asm_thumb_write_op16(as, 0x0000); - asm_thumb_write_op16(as, 0x6800 | (word_offset << 6) | (rlo_base << 3) | rlo_dest); // ldr rlo_dest, [rlo_base, #offset] - asm_thumb_write_op16(as, 0x4780 | (REG_R9 << 3)); // blx reg + asm_thumb_op16(as, 0x0000); + asm_thumb_op16(as, 0x6800 | (word_offset << 6) | (rlo_base << 3) | rlo_dest); // ldr rlo_dest, [rlo_base, #offset] + asm_thumb_op16(as, 0x4780 | (REG_R9 << 3)); // blx reg */ if (0) { // load ptr to function into register using immediate, then branch // not relocatable asm_thumb_mov_reg_i32(as, reg_temp, (machine_uint_t)fun_ptr); - asm_thumb_write_op16(as, OP_BLX(reg_temp)); + asm_thumb_op16(as, OP_BLX(reg_temp)); } else if (1) { - asm_thumb_write_op16(as, OP_FORMAT_9_10(ASM_THUMB_FORMAT_9_LDR | ASM_THUMB_FORMAT_9_WORD_TRANSFER, reg_temp, REG_R7, fun_id)); - asm_thumb_write_op16(as, OP_BLX(reg_temp)); + asm_thumb_op16(as, OP_FORMAT_9_10(ASM_THUMB_FORMAT_9_LDR | ASM_THUMB_FORMAT_9_WORD_TRANSFER, reg_temp, REG_R7, fun_id)); + asm_thumb_op16(as, OP_BLX(reg_temp)); } else { // use SVC - asm_thumb_write_op16(as, OP_SVC(fun_id)); + asm_thumb_op16(as, OP_SVC(fun_id)); } } diff --git a/py/asmthumb.h b/py/asmthumb.h index 6b4f5506b6..ca81b847f4 100644 --- a/py/asmthumb.h +++ b/py/asmthumb.h @@ -58,6 +58,14 @@ void asm_thumb_label_assign(asm_thumb_t *as, uint label); // argument order follows ARM, in general dest is first // note there is a difference between movw and mov.w, and many others! +#define ASM_THUMB_OP_NOP (0xbf00) +#define ASM_THUMB_OP_WFI (0xbf30) +#define ASM_THUMB_OP_CPSID_I (0xb672) // cpsid i, disable irq +#define ASM_THUMB_OP_CPSIE_I (0xb662) // cpsie i, enable irq + +void asm_thumb_op16(asm_thumb_t *as, uint op); +void asm_thumb_op32(asm_thumb_t *as, uint op1, uint op2); + // FORMAT 2: add/subtract #define ASM_THUMB_FORMAT_2_ADD (0x1800) diff --git a/py/binary.c b/py/binary.c index 1ddf4569b9..d3dd009546 100644 --- a/py/binary.c +++ b/py/binary.c @@ -151,11 +151,21 @@ mp_obj_t mp_binary_get_val(char struct_type, char val_type, byte **ptr) { } void mp_binary_set_val_array(char typecode, void *p, int index, mp_obj_t val_in) { - machine_int_t val = 0; - if (MP_OBJ_IS_INT(val_in)) { - val = mp_obj_int_get(val_in); + switch (typecode) { +#if MICROPY_ENABLE_FLOAT + case 'f': + ((float*)p)[index] = mp_obj_float_get(val_in); + break; + case 'd': + ((double*)p)[index] = mp_obj_float_get(val_in); + break; +#endif + default: + mp_binary_set_val_array_from_int(typecode, p, index, mp_obj_get_int(val_in)); } +} +void mp_binary_set_val_array_from_int(char typecode, void *p, int index, machine_int_t val) { switch (typecode) { case 'b': ((int8_t*)p)[index] = val; @@ -187,10 +197,10 @@ void mp_binary_set_val_array(char typecode, void *p, int index, mp_obj_t val_in) #endif #if MICROPY_ENABLE_FLOAT case 'f': - ((float*)p)[index] = mp_obj_float_get(val_in); + ((float*)p)[index] = val; break; case 'd': - ((double*)p)[index] = mp_obj_float_get(val_in); + ((double*)p)[index] = val; break; #endif } diff --git a/py/binary.h b/py/binary.h index e9fb38f13f..538d6e7f29 100644 --- a/py/binary.h +++ b/py/binary.h @@ -6,3 +6,4 @@ int mp_binary_get_size(char typecode); mp_obj_t mp_binary_get_val_array(char typecode, void *p, int index); mp_obj_t mp_binary_get_val(char struct_type, char val_type, byte **ptr); void mp_binary_set_val_array(char typecode, void *p, int index, mp_obj_t val_in); +void mp_binary_set_val_array_from_int(char typecode, void *p, int index, machine_int_t val); diff --git a/py/emitinlinethumb.c b/py/emitinlinethumb.c index 812e702af6..dabd5a8831 100644 --- a/py/emitinlinethumb.c +++ b/py/emitinlinethumb.c @@ -235,7 +235,11 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, int n_args, m uint op_len = strlen(op_str); if (n_args == 0) { - if (strcmp(op_str, "ite.ge") == 0) { // TODO correct name for this op? + if (strcmp(op_str, "nop") == 0) { + asm_thumb_op16(emit->as, ASM_THUMB_OP_NOP); + } else if (strcmp(op_str, "wfi") == 0) { + asm_thumb_op16(emit->as, ASM_THUMB_OP_WFI); + } else if (strcmp(op_str, "ite.ge") == 0) { // TODO correct name for this op? asm_thumb_ite_ge(emit->as); } else { goto unknown_op; @@ -259,6 +263,12 @@ STATIC void emit_inline_thumb_op(emit_inline_asm_t *emit, qstr op, int n_args, m int label_num = get_arg_label(emit, op_str, pn_args[0]); // TODO check that this succeeded, ie branch was within range asm_thumb_bcc_n(emit->as, cc, label_num); + } else if (strcmp(op_str, "cpsid")) { + // TODO check pn_args[0] == i + asm_thumb_op16(emit->as, ASM_THUMB_OP_CPSID_I); + } else if (strcmp(op_str, "cpsie")) { + // TODO check pn_args[0] == i + asm_thumb_op16(emit->as, ASM_THUMB_OP_CPSIE_I); } else { goto unknown_op; } diff --git a/py/modstruct.c b/py/modstruct.c index 3b9679a4c2..cd2516b240 100644 --- a/py/modstruct.c +++ b/py/modstruct.c @@ -55,8 +55,8 @@ STATIC mp_obj_t struct_unpack(mp_obj_t fmt_in, mp_obj_t data_in) { char fmt_type = get_fmt_type(&fmt); uint size = calcsize_items(fmt); mp_obj_tuple_t *res = mp_obj_new_tuple(size, NULL); - buffer_info_t bufinfo; - mp_get_buffer_raise(data_in, &bufinfo); + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(data_in, &bufinfo, MP_BUFFER_READ); byte *p = bufinfo.buf; for (uint i = 0; i < size; i++) { @@ -357,20 +357,20 @@ mp_obj_t mp_identity(mp_obj_t self) { } MP_DEFINE_CONST_FUN_OBJ_1(mp_identity_obj, mp_identity); -bool mp_get_buffer(mp_obj_t obj, buffer_info_t *bufinfo) { +bool mp_get_buffer(mp_obj_t obj, mp_buffer_info_t *bufinfo, int flags) { mp_obj_type_t *type = mp_obj_get_type(obj); if (type->buffer_p.get_buffer == NULL) { return false; } - type->buffer_p.get_buffer(obj, bufinfo, BUFFER_READ); - if (bufinfo->buf == NULL) { + int ret = type->buffer_p.get_buffer(obj, bufinfo, flags); + if (ret != 0 || bufinfo->buf == NULL) { return false; } return true; } -void mp_get_buffer_raise(mp_obj_t obj, buffer_info_t *bufinfo) { - if (!mp_get_buffer(obj, bufinfo)) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "Object with buffer protocol required")); +void mp_get_buffer_raise(mp_obj_t obj, mp_buffer_info_t *bufinfo, int flags) { + if (!mp_get_buffer(obj, bufinfo, flags)) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "object with buffer protocol required")); } } @@ -189,32 +189,28 @@ typedef struct _mp_method_t { } mp_method_t; // Buffer protocol -typedef struct _buffer_info_t { +typedef struct _mp_buffer_info_t { // if we'd bother to support various versions of structure // (with different number of fields), we can distinguish // them with ver = sizeof(struct). Cons: overkill for *micro*? //int ver; // ? void *buf; - machine_int_t len; - - // Rationale: have array.array and have SIMD operations on them - // Cons: users can pass item size to processing functions themselves, - // though that's not "plug&play" - // int itemsize; + machine_int_t len; // in bytes + int typecode; // as per binary.h // Rationale: to load arbitrary-sized sprites directly to LCD // Cons: a bit adhoc usecase // int stride; -} buffer_info_t; -#define BUFFER_READ (1) -#define BUFFER_WRITE (2) -#define BUFFER_RW (BUFFER_READ | BUFFER_WRITE) +} mp_buffer_info_t; +#define MP_BUFFER_READ (1) +#define MP_BUFFER_WRITE (2) +#define MP_BUFFER_RW (MP_BUFFER_READ | MP_BUFFER_WRITE) typedef struct _mp_buffer_p_t { - machine_int_t (*get_buffer)(mp_obj_t obj, buffer_info_t *bufinfo, int flags); + machine_int_t (*get_buffer)(mp_obj_t obj, mp_buffer_info_t *bufinfo, int flags); } mp_buffer_p_t; -bool mp_get_buffer(mp_obj_t obj, buffer_info_t *bufinfo); -void mp_get_buffer_raise(mp_obj_t obj, buffer_info_t *bufinfo); +bool mp_get_buffer(mp_obj_t obj, mp_buffer_info_t *bufinfo, int flags); +void mp_get_buffer_raise(mp_obj_t obj, mp_buffer_info_t *bufinfo, int flags); // Stream protocol typedef struct _mp_stream_p_t { diff --git a/py/objarray.c b/py/objarray.c index 5c160bfabb..c6da45728a 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -35,7 +35,7 @@ STATIC void array_print(void (*print)(void *env, const char *fmt, ...), void *en } else { print(env, "array('%c'", o->typecode); if (o->len > 0) { - print(env, ", [", o->typecode); + print(env, ", ["); for (int i = 0; i < o->len; i++) { if (i > 0) { print(env, ", "); @@ -75,32 +75,37 @@ STATIC mp_obj_t array_construct(char typecode, mp_obj_t initializer) { } STATIC mp_obj_t array_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { - if (n_args < 1 || n_args > 2) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "unexpected # of arguments, %d given", n_args)); - } - // TODO check args + mp_check_nargs(n_args, 1, 2, n_kw, false); + + // get typecode uint l; const char *typecode = mp_obj_str_get_data(args[0], &l); + if (n_args == 1) { + // 1 arg: make an empty array return array_new(*typecode, 0); + } else { + // 2 args: construct the array from the given iterator + return array_construct(*typecode, args[1]); } - - return array_construct(*typecode, args[1]); } STATIC mp_obj_t bytearray_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { - if (n_args > 1) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "unexpected # of arguments, %d given", n_args)); - } + mp_check_nargs(n_args, 0, 1, n_kw, false); - if (MP_OBJ_IS_SMALL_INT(args[0])) { + if (n_args == 0) { + // no args: construct an empty bytearray + return array_new(BYTEARRAY_TYPECODE, 0); + } else if (MP_OBJ_IS_SMALL_INT(args[0])) { + // 1 arg, an integer: construct a blank bytearray of that length uint len = MP_OBJ_SMALL_INT_VALUE(args[0]); mp_obj_array_t *o = array_new(BYTEARRAY_TYPECODE, len); memset(o->items, 0, len); return o; + } else { + // 1 arg, an iterator: construct the bytearray from that + return array_construct(BYTEARRAY_TYPECODE, args[0]); } - - return array_construct(BYTEARRAY_TYPECODE, args[0]); } STATIC mp_obj_t array_unary_op(int op, mp_obj_t o_in) { @@ -129,7 +134,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(array_append_obj, array_append); STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) { if (value == MP_OBJ_NULL) { - // delete item; does this need to be implemented? + // delete item + // TODO implement return MP_OBJ_NOT_SUPPORTED; } else { mp_obj_array_t *o = self_in; @@ -145,10 +151,11 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value } } -STATIC machine_int_t array_get_buffer(mp_obj_t o_in, buffer_info_t *bufinfo, int flags) { +STATIC machine_int_t array_get_buffer(mp_obj_t o_in, mp_buffer_info_t *bufinfo, int flags) { mp_obj_array_t *o = o_in; bufinfo->buf = o->items; bufinfo->len = o->len * mp_binary_get_size(o->typecode); + bufinfo->typecode = o->typecode; return 0; } @@ -183,12 +190,16 @@ const mp_obj_type_t mp_type_bytearray = { }; STATIC mp_obj_array_t *array_new(char typecode, uint n) { + int typecode_size = mp_binary_get_size(typecode); + if (typecode_size <= 0) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "bad typecode")); + } mp_obj_array_t *o = m_new_obj(mp_obj_array_t); o->base.type = (typecode == BYTEARRAY_TYPECODE) ? &mp_type_bytearray : &mp_type_array; o->typecode = typecode; o->free = 0; o->len = n; - o->items = m_malloc(mp_binary_get_size(typecode) * o->len); + o->items = m_malloc(typecode_size * o->len); return o; } diff --git a/py/objfun.c b/py/objfun.c index 07d6606c53..ab6326057f 100644 --- a/py/objfun.c +++ b/py/objfun.c @@ -30,26 +30,27 @@ STATIC void check_nargs(mp_obj_fun_native_t *self, int n_args, int n_kw) { } void mp_check_nargs(int n_args, machine_uint_t n_args_min, machine_uint_t n_args_max, int n_kw, bool is_kw) { + // TODO maybe take the function name as an argument so we can print nicer error messages + if (n_kw && !is_kw) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, - "function does not take keyword arguments")); + nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "function does not take keyword arguments")); } if (n_args_min == n_args_max) { if (n_args != n_args_min) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "function takes %d positional arguments but %d were given", - n_args_min, n_args)); + "function takes %d positional arguments but %d were given", + n_args_min, n_args)); } } else { if (n_args < n_args_min) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "<fun name>() missing %d required positional arguments: <list of names of params>", + "function missing %d required positional arguments", n_args_min - n_args)); } else if (n_args > n_args_max) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, - "<fun name> expected at most %d arguments, got %d", - n_args_max, n_args)); + "function expected at most %d arguments, got %d", + n_args_max, n_args)); } } } @@ -425,8 +426,8 @@ STATIC machine_uint_t convert_obj_for_inline_asm(mp_obj_t obj) { mp_obj_list_get(obj, &len, &items); return (machine_uint_t)items; } else { - buffer_info_t bufinfo; - if (mp_get_buffer(obj, &bufinfo)) { + mp_buffer_info_t bufinfo; + if (mp_get_buffer(obj, &bufinfo, MP_BUFFER_WRITE)) { // supports the buffer protocol, return a pointer to the data return (machine_uint_t)bufinfo.buf; } else { diff --git a/py/objint.c b/py/objint.c index 2c71f51cd1..110876e003 100644 --- a/py/objint.c +++ b/py/objint.c @@ -272,8 +272,8 @@ STATIC mp_obj_t int_from_bytes(uint n_args, const mp_obj_t *args) { // TODO: Support signed param (assumes signed=False at the moment) // get the buffer info - buffer_info_t bufinfo; - mp_get_buffer_raise(args[1], &bufinfo); + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ); // convert the bytes to an integer machine_uint_t value = 0; diff --git a/py/objstr.c b/py/objstr.c index e444ec7d41..a682144b8f 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -1326,16 +1326,18 @@ STATIC mp_obj_t str_encode(uint n_args, const mp_obj_t *args) { } #endif -STATIC machine_int_t str_get_buffer(mp_obj_t self_in, buffer_info_t *bufinfo, int flags) { - if (flags == BUFFER_READ) { +STATIC machine_int_t str_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, int flags) { + if (flags == MP_BUFFER_READ) { GET_STR_DATA_LEN(self_in, str_data, str_len); bufinfo->buf = (void*)str_data; bufinfo->len = str_len; + bufinfo->typecode = 'b'; return 0; } else { // can't write to a string bufinfo->buf = NULL; bufinfo->len = 0; + bufinfo->typecode = -1; return 1; } } diff --git a/stmhal/Makefile b/stmhal/Makefile index 5501c4b8d9..dcffd164af 100644 --- a/stmhal/Makefile +++ b/stmhal/Makefile @@ -65,7 +65,6 @@ SRC_C = \ timer.c \ led.c \ pin.c \ - pin_map.c \ pin_named_pins.c \ usart.c \ usb.c \ @@ -84,8 +83,7 @@ SRC_C = \ modtime.c \ import.c \ lexerfatfs.c \ - gpio.c \ - exti.c \ + extint.c \ usrsw.c \ rng.c \ rtc.c \ diff --git a/stmhal/adc.c b/stmhal/adc.c index b0a7a0749a..be83b03ad7 100644 --- a/stmhal/adc.c +++ b/stmhal/adc.c @@ -8,6 +8,7 @@ #include "qstr.h" #include "obj.h" #include "runtime.h" +#include "binary.h" #include "adc.h" #include "pin.h" #include "genhdr/pins.h" @@ -18,7 +19,7 @@ // adc = pyb.ADC(pin) // val = adc.read() // -// adc = pyb.ADC_all(resolution) +// adc = pyb.ADCAll(resolution) // val = adc.read_channel(channel) // val = adc.read_core_temp() // val = adc.read_core_vbat() @@ -129,7 +130,7 @@ STATIC mp_obj_t adc_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_ if (MP_OBJ_IS_INT(pin_obj)) { channel = mp_obj_get_int(pin_obj); } else { - const pin_obj_t *pin = pin_map_user_obj(pin_obj); + const pin_obj_t *pin = pin_find(pin_obj); if ((pin->adc_num & PIN_ADC1) == 0) { // No ADC1 function on that pin nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "pin %s does not have ADC capabilities", pin->name)); @@ -138,10 +139,10 @@ STATIC mp_obj_t adc_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_ } if (!IS_ADC_CHANNEL(channel)) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Not a valid ADC Channel: %d", channel)); + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "not a valid ADC Channel: %d", channel)); } if (pin_adc1[channel] == NULL) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Channel %d not available on this board", channel)); + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "channel %d not available on this board", channel)); } pyb_obj_adc_t *o = m_new_obj(pyb_obj_adc_t); @@ -166,8 +167,9 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_read_obj, adc_read); STATIC mp_obj_t adc_read_timed(mp_obj_t self_in, mp_obj_t buf_in, mp_obj_t freq_in) { pyb_obj_adc_t *self = self_in; - buffer_info_t bufinfo; - mp_get_buffer_raise(buf_in, &bufinfo); + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_WRITE); + int typesize = mp_binary_get_size(bufinfo.typecode); // Init TIM6 at the required frequency (in Hz) timer_tim6_init(mp_obj_get_int(freq_in)); @@ -176,13 +178,17 @@ STATIC mp_obj_t adc_read_timed(mp_obj_t self_in, mp_obj_t buf_in, mp_obj_t freq_ HAL_TIM_Base_Start(&TIM6_Handle); // This uses the timer in polling mode to do the sampling - // TODO use DMA - for (uint i = 0; i < bufinfo.len; i++) { + // We could use DMA, but then we can't convert the values correctly for the buffer + for (uint index = 0; index < bufinfo.len; index++) { // Wait for the timer to trigger while (__HAL_TIM_GET_FLAG(&TIM6_Handle, TIM_FLAG_UPDATE) == RESET) { } __HAL_TIM_CLEAR_FLAG(&TIM6_Handle, TIM_FLAG_UPDATE); - ((byte*)bufinfo.buf)[i] = adc_read_channel(&self->handle) >> 4; + uint value = adc_read_channel(&self->handle); + if (typesize == 1) { + value >>= 4; + } + mp_binary_set_val_array_from_int(bufinfo.typecode, bufinfo.buf, index, value); } // Stop timer @@ -211,12 +217,12 @@ const mp_obj_type_t pyb_adc_type = { /******************************************************************************/ /* adc all object */ -typedef struct _pyb_obj_adc_all_t { +typedef struct _pyb_adc_all_obj_t { mp_obj_base_t base; ADC_HandleTypeDef handle; -} pyb_obj_adc_all_t; +} pyb_adc_all_obj_t; -void adc_init_all(pyb_obj_adc_all_t *adc_all, uint32_t resolution) { +void adc_init_all(pyb_adc_all_obj_t *adc_all, uint32_t resolution) { switch (resolution) { case 6: resolution = ADC_RESOLUTION6b; break; @@ -314,46 +320,49 @@ float adc_read_core_vref(ADC_HandleTypeDef *adcHandle) { /******************************************************************************/ /* Micro Python bindings : adc_all object */ -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_all_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { + // check number of arguments + mp_check_nargs(n_args, 1, 1, n_kw, false); + + // make ADCAll object + pyb_adc_all_obj_t *o = m_new_obj(pyb_adc_all_obj_t); + o->base.type = &pyb_adc_all_type; + adc_init_all(o, mp_obj_get_int(args[0])); // args[0] is the resolution + + return o; } 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; - + pyb_adc_all_obj_t *self = self_in; uint32_t chan = mp_obj_get_int(channel); uint32_t data = adc_config_and_read_channel(&self->handle, chan); return mp_obj_new_int(data); } +STATIC MP_DEFINE_CONST_FUN_OBJ_2(adc_all_read_channel_obj, adc_all_read_channel); STATIC mp_obj_t adc_all_read_core_temp(mp_obj_t self_in) { - pyb_obj_adc_all_t *self = self_in; - + pyb_adc_all_obj_t *self = self_in; int data = adc_read_core_temp(&self->handle); return mp_obj_new_int(data); } +STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_all_read_core_temp_obj, adc_all_read_core_temp); STATIC mp_obj_t adc_all_read_core_vbat(mp_obj_t self_in) { - pyb_obj_adc_all_t *self = self_in; - + pyb_adc_all_obj_t *self = self_in; float data = adc_read_core_vbat(&self->handle); return mp_obj_new_float(data); } +STATIC MP_DEFINE_CONST_FUN_OBJ_1(adc_all_read_core_vbat_obj, adc_all_read_core_vbat); STATIC mp_obj_t adc_all_read_core_vref(mp_obj_t self_in) { - pyb_obj_adc_all_t *self = self_in; - + pyb_adc_all_obj_t *self = self_in; float data = adc_read_core_vref(&self->handle); return mp_obj_new_float(data); } - -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_map_elem_t adc_all_locals_dict_table[] = { - { MP_OBJ_NEW_QSTR(MP_QSTR_read_channel), (mp_obj_t) &adc_all_read_channel_obj}, + { MP_OBJ_NEW_QSTR(MP_QSTR_read_channel), (mp_obj_t)&adc_all_read_channel_obj}, { MP_OBJ_NEW_QSTR(MP_QSTR_read_core_temp), (mp_obj_t)&adc_all_read_core_temp_obj}, { MP_OBJ_NEW_QSTR(MP_QSTR_read_core_vbat), (mp_obj_t)&adc_all_read_core_vbat_obj}, { MP_OBJ_NEW_QSTR(MP_QSTR_read_core_vref), (mp_obj_t)&adc_all_read_core_vref_obj}, @@ -361,18 +370,9 @@ STATIC const mp_map_elem_t adc_all_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(adc_all_locals_dict, adc_all_locals_dict_table); -STATIC const mp_obj_type_t adc_all_type = { +const mp_obj_type_t pyb_adc_all_type = { { &mp_type_type }, - .name = MP_QSTR_ADC, - .print = adc_all_print, + .name = MP_QSTR_ADCAll, + .make_new = adc_all_make_new, .locals_dict = (mp_obj_t)&adc_all_locals_dict, }; - -STATIC mp_obj_t pyb_ADC_all(mp_obj_t resolution) { - pyb_obj_adc_all_t *o = m_new_obj(pyb_obj_adc_all_t); - o->base.type = &adc_all_type; - adc_init_all(o, mp_obj_get_int(resolution)); - return o; -} - -MP_DEFINE_CONST_FUN_OBJ_1(pyb_ADC_all_obj, pyb_ADC_all); diff --git a/stmhal/adc.h b/stmhal/adc.h index c9f16932eb..deedac0112 100644 --- a/stmhal/adc.h +++ b/stmhal/adc.h @@ -1,3 +1,2 @@ extern const mp_obj_type_t pyb_adc_type; - -MP_DECLARE_CONST_FUN_OBJ(pyb_ADC_all_obj); +extern const mp_obj_type_t pyb_adc_all_type; diff --git a/stmhal/boards/stm32f4xx-prefix.c b/stmhal/boards/stm32f4xx-prefix.c index 989b8f0048..4d2313075a 100644 --- a/stmhal/boards/stm32f4xx-prefix.c +++ b/stmhal/boards/stm32f4xx-prefix.c @@ -2,18 +2,18 @@ #include <stdio.h> #include <stdint.h> -#include <stm32f4xx_hal.h> + +#include "stm32f4xx_hal.h" #include "misc.h" #include "mpconfig.h" #include "qstr.h" #include "obj.h" - #include "pin.h" #define AF(af_idx, af_fn, af_unit, af_type, af_ptr) \ { \ - { &pin_af_obj_type }, \ + { &pin_af_type }, \ .idx = (af_idx), \ .fn = AF_FN_ ## af_fn, \ .unit = (af_unit), \ @@ -23,7 +23,7 @@ #define PIN(p_port, p_pin, p_num_af, p_af, p_adc_num, p_adc_channel) \ { \ - { &pin_obj_type }, \ + { &pin_type }, \ .name = #p_port #p_pin, \ .port = PORT_ ## p_port, \ .pin = (p_pin), \ diff --git a/stmhal/cmsis/devinc/stm32f405xx.h b/stmhal/cmsis/devinc/stm32f405xx.h index 99a54bf22b..9e50eff7ea 100644 --- a/stmhal/cmsis/devinc/stm32f405xx.h +++ b/stmhal/cmsis/devinc/stm32f405xx.h @@ -9,7 +9,7 @@ * This file contains:
* - Data structures and the address mapping for all peripherals
* - Peripheral's registers declarations and bits definition
- * - Macros to access peripheral’s registers hardware
+ * - Macros to access peripheral's registers hardware
*
******************************************************************************
* @attention
diff --git a/stmhal/dac.c b/stmhal/dac.c index c018a4046a..5b2d17d889 100644 --- a/stmhal/dac.c +++ b/stmhal/dac.c @@ -169,8 +169,8 @@ mp_obj_t pyb_dac_dma(uint n_args, const mp_obj_t *args, mp_map_t *kw_args) { // set TIM6 to trigger the DAC at the given frequency TIM6_Config(mp_obj_get_int(args[2])); - buffer_info_t bufinfo; - mp_get_buffer_raise(args[1], &bufinfo); + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ); __DMA1_CLK_ENABLE(); diff --git a/stmhal/exti.c b/stmhal/extint.c index 5ea3db62bb..9ec599cf13 100644 --- a/stmhal/exti.c +++ b/stmhal/extint.c @@ -13,7 +13,7 @@ #include "runtime.h" #include "pin.h" -#include "exti.h" +#include "extint.h" // Usage Model: // @@ -27,8 +27,8 @@ // def callback(line): // print("line =", line) // -// # Note: Exti will automatically configure the gpio line as an input. -// exti = pyb.Exti(pin, pyb.Exti.MODE_IRQ_FALLING, pyb.PULLUP, callback) +// # Note: ExtInt will automatically configure the gpio line as an input. +// extint = pyb.ExtInt(pin, pyb.ExtInt.MODE_IRQ_FALLING, pyb.GPIO.PULL_UP, callback) // // Now every time a falling edge is seen on the X1 pin, the callback will be // called. Caution: mechanical pushbuttons have "bounce" and pushing or @@ -44,27 +44,27 @@ // All other pin objects go through the pin mapper to come up with one of the // gpio pins. // -// exti = pyb.Exti(pin, mode, pull, callback) +// extint = pyb.ExtInt(pin, mode, pull, callback) // -// Valid modes are pyb.Exti.MODE_IRQ_RISING, pyb.Exti.MODE_IRQ_FALLING, -// pyb.Exti.MODE_IRQ_RISING_FALLING, pyb.Exti.MODE_EVT_RISING, -// pyb.Exti.MODE_EVT_FALLING, and pyb.Exti.MODE_EVT_RISING_FALLING. +// Valid modes are pyb.ExtInt.MODE_IRQ_RISING, pyb.ExtInt.MODE_IRQ_FALLING, +// pyb.ExtInt.MODE_IRQ_RISING_FALLING, pyb.ExtInt.MODE_EVT_RISING, +// pyb.ExtInt.MODE_EVT_FALLING, and pyb.ExtInt.MODE_EVT_RISING_FALLING. // -// Only the MODE_IRQ_xxx modes have been tested. The MODE_EVENT_xxx modes have -// something to do with sleep mode and he WFE instruction. +// Only the MODE_IRQ_xxx modes have been tested. The MODE_EVT_xxx modes have +// something to do with sleep mode and the WFE instruction. // -// Valid pull values are pyb.PULL_UP, pyb.PULL_DOWN, pyb.PULL_NONE. +// Valid pull values are pyb.GPIO.PULL_UP, pyb.GPIO.PULL_DOWN, pyb.GPIO.PULL_NONE. // -// exti.line() will return the line number that pin was mapped to. -// exti.disable() can be use to disable the interrupt associated with a given -// exti object. This could be useful for debouncing. -// exti.enable() enables a disabled interrupt -// exti.swint() will allow the callback to be triggered from software. +// extint.line() will return the line number that pin was mapped to. +// extint.disable() can be use to disable the interrupt associated with a given +// exti object. This could be useful for debouncing. +// extint.enable() enables a disabled interrupt +// extint.swint() will allow the callback to be triggered from software. // -// pyb.Exti.regs() will dump the values of the EXTI registers. +// pyb.ExtInt.regs() will dump the values of the EXTI registers. // // There is also a C API, so that drivers which require EXTI interrupt lines -// can also use this code. See exti.h for the available functions and +// can also use this code. See extint.h for the available functions and // usrsw.h for an example of using this. // // TODO Add python method to change callback object. @@ -83,15 +83,15 @@ typedef struct { mp_obj_base_t base; mp_small_int_t line; -} exti_obj_t; +} extint_obj_t; typedef struct { mp_obj_t callback_obj; void *param; uint32_t mode; -} exti_vector_t; +} extint_vector_t; -STATIC exti_vector_t exti_vector[EXTI_NUM_VECTORS]; +STATIC extint_vector_t extint_vector[EXTI_NUM_VECTORS]; #if !defined(ETH) #define ETH_WKUP_IRQn 62 // The 405 doesn't have ETH, but we want a value to put in our table @@ -110,7 +110,7 @@ STATIC const uint8_t nvic_irq_channel[EXTI_NUM_VECTORS] = { // // NOTE: param is for C callers. Python can use closure to get an object bound // with the function. -uint exti_register(mp_obj_t pin_obj, mp_obj_t mode_obj, mp_obj_t pull_obj, mp_obj_t callback_obj, bool override_callback_obj, void *param) { +uint extint_register(mp_obj_t pin_obj, mp_obj_t mode_obj, mp_obj_t pull_obj, mp_obj_t callback_obj, bool override_callback_obj, void *param) { const pin_obj_t *pin = NULL; uint v_line; @@ -120,13 +120,13 @@ uint exti_register(mp_obj_t pin_obj, mp_obj_t mode_obj, mp_obj_t pull_obj, mp_ob // get both the port number and line number. v_line = mp_obj_get_int(pin_obj); if (v_line < 16) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "EXTI vector %d < 16, use a Pin object", v_line)); + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "ExtInt vector %d < 16, use a Pin object", v_line)); } if (v_line >= EXTI_NUM_VECTORS) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "EXTI vector %d >= max of %d", v_line, EXTI_NUM_VECTORS)); + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "ExtInt vector %d >= max of %d", v_line, EXTI_NUM_VECTORS)); } } else { - pin = pin_map_user_obj(pin_obj); + pin = pin_find(pin_obj); v_line = pin->pin; } int mode = mp_obj_get_int(mode_obj); @@ -136,24 +136,24 @@ uint exti_register(mp_obj_t pin_obj, mp_obj_t mode_obj, mp_obj_t pull_obj, mp_ob mode != GPIO_MODE_EVT_RISING && mode != GPIO_MODE_EVT_FALLING && mode != GPIO_MODE_EVT_RISING_FALLING) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Invalid EXTI Mode: %d", mode)); + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Invalid ExtInt Mode: %d", mode)); } int pull = mp_obj_get_int(pull_obj); if (pull != GPIO_NOPULL && pull != GPIO_PULLUP && pull != GPIO_PULLDOWN) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Invalid EXTI Pull: %d", pull)); + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Invalid ExtInt Pull: %d", pull)); } - exti_vector_t *v = &exti_vector[v_line]; + extint_vector_t *v = &extint_vector[v_line]; if (!override_callback_obj && v->callback_obj != mp_const_none && callback_obj != mp_const_none) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "EXTI vector %d is already in use", v_line)); + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "ExtInt vector %d is already in use", v_line)); } // We need to update callback and param atomically, so we disable the line // before we update anything. - exti_disable(v_line); + extint_disable(v_line); v->callback_obj = callback_obj; v->param = param; @@ -169,7 +169,7 @@ uint exti_register(mp_obj_t pin_obj, mp_obj_t mode_obj, mp_obj_t pull_obj, mp_ob exti.Speed = GPIO_SPEED_FAST; HAL_GPIO_Init(pin->gpio, &exti); - // Calling HAL_GPIO_Init does an implicit exti_enable + // Calling HAL_GPIO_Init does an implicit extint_enable /* Enable and set NVIC Interrupt to the lowest priority */ HAL_NVIC_SetPriority(nvic_irq_channel[v_line], 0x0F, 0x0F); @@ -178,17 +178,17 @@ uint exti_register(mp_obj_t pin_obj, mp_obj_t mode_obj, mp_obj_t pull_obj, mp_ob return v_line; } -void exti_enable(uint line) { +void extint_enable(uint line) { if (line >= EXTI_NUM_VECTORS) { return; } // Since manipulating IMR/EMR is a read-modify-write, and we want this to // be atomic, we use the bit-band area to just affect the bit we're // interested in. - EXTI_MODE_BB(exti_vector[line].mode, line) = 1; + EXTI_MODE_BB(extint_vector[line].mode, line) = 1; } -void exti_disable(uint line) { +void extint_disable(uint line) { if (line >= EXTI_NUM_VECTORS) { return; } @@ -199,37 +199,37 @@ void exti_disable(uint line) { EXTI_MODE_BB(EXTI_Mode_Event, line) = 0; } -void exti_swint(uint line) { +void extint_swint(uint line) { if (line >= EXTI_NUM_VECTORS) { return; } EXTI->SWIER = (1 << line); } -STATIC mp_obj_t exti_obj_line(mp_obj_t self_in) { - exti_obj_t *self = self_in; +STATIC mp_obj_t extint_obj_line(mp_obj_t self_in) { + extint_obj_t *self = self_in; return MP_OBJ_NEW_SMALL_INT(self->line); } -STATIC mp_obj_t exti_obj_enable(mp_obj_t self_in) { - exti_obj_t *self = self_in; - exti_enable(self->line); +STATIC mp_obj_t extint_obj_enable(mp_obj_t self_in) { + extint_obj_t *self = self_in; + extint_enable(self->line); return mp_const_none; } -STATIC mp_obj_t exti_obj_disable(mp_obj_t self_in) { - exti_obj_t *self = self_in; - exti_disable(self->line); +STATIC mp_obj_t extint_obj_disable(mp_obj_t self_in) { + extint_obj_t *self = self_in; + extint_disable(self->line); return mp_const_none; } -STATIC mp_obj_t exti_obj_swint(mp_obj_t self_in) { - exti_obj_t *self = self_in; - exti_swint(self->line); +STATIC mp_obj_t extint_obj_swint(mp_obj_t self_in) { + extint_obj_t *self = self_in; + extint_swint(self->line); return mp_const_none; } -STATIC mp_obj_t exti_regs(void) { +STATIC mp_obj_t extint_regs(void) { printf("EXTI_IMR %08lx\n", EXTI->IMR); printf("EXTI_EMR %08lx\n", EXTI->EMR); printf("EXTI_RTSR %08lx\n", EXTI->RTSR); @@ -239,62 +239,62 @@ STATIC mp_obj_t exti_regs(void) { return mp_const_none; } -STATIC MP_DEFINE_CONST_FUN_OBJ_1(exti_obj_line_obj, exti_obj_line); -STATIC MP_DEFINE_CONST_FUN_OBJ_1(exti_obj_enable_obj, exti_obj_enable); -STATIC MP_DEFINE_CONST_FUN_OBJ_1(exti_obj_disable_obj, exti_obj_disable); -STATIC MP_DEFINE_CONST_FUN_OBJ_1(exti_obj_swint_obj, exti_obj_swint); -STATIC MP_DEFINE_CONST_FUN_OBJ_0(exti_regs_fun_obj, exti_regs); -STATIC MP_DEFINE_CONST_STATICMETHOD_OBJ(exti_regs_obj, (mp_obj_t)&exti_regs_fun_obj); - -STATIC const mp_map_elem_t exti_locals_dict_table[] = { - { MP_OBJ_NEW_QSTR(MP_QSTR_line), (mp_obj_t)&exti_obj_line_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_enable), (mp_obj_t)&exti_obj_enable_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_disable), (mp_obj_t)&exti_obj_disable_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_swint), (mp_obj_t)&exti_obj_swint_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_regs), (mp_obj_t)&exti_regs_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MODE_IRQ_RISING), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_IT_RISING) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MODE_IRQ_FALLING), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_IT_FALLING) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MODE_IRQ_RISING_FALLING), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_IT_RISING_FALLING) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MODE_EVT_RISING), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_EVT_RISING) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MODE_EVT_FALLING), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_EVT_FALLING) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_MODE_EVT_RISING_FALLING), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_EVT_RISING_FALLING) }, -}; - -STATIC MP_DEFINE_CONST_DICT(exti_locals_dict, exti_locals_dict_table); - -// line_obj = pyb.Exti(pin, mode, trigger, callback) +// line_obj = pyb.ExtInt(pin, mode, trigger, callback) -STATIC mp_obj_t exti_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { - // type_in == exti_obj_type +STATIC mp_obj_t extint_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { + // type_in == extint_obj_type mp_check_nargs(n_args, 4, 4, n_kw, false); - exti_obj_t *self = m_new_obj(exti_obj_t); + extint_obj_t *self = m_new_obj(extint_obj_t); self->base.type = type_in; mp_obj_t line_obj = args[0]; mp_obj_t mode_obj = args[1]; mp_obj_t trigger_obj = args[2]; mp_obj_t callback_obj = args[3]; - self->line = exti_register(line_obj, mode_obj, trigger_obj, callback_obj, false, NULL); + self->line = extint_register(line_obj, mode_obj, trigger_obj, callback_obj, false, NULL); return self; } -STATIC void exti_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { - exti_obj_t *self = self_in; - print(env, "<Exti line=%u>", self->line); +STATIC void extint_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { + extint_obj_t *self = self_in; + print(env, "<ExtInt line=%u>", self->line); } -const mp_obj_type_t exti_obj_type = { +STATIC MP_DEFINE_CONST_FUN_OBJ_1(extint_obj_line_obj, extint_obj_line); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(extint_obj_enable_obj, extint_obj_enable); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(extint_obj_disable_obj, extint_obj_disable); +STATIC MP_DEFINE_CONST_FUN_OBJ_1(extint_obj_swint_obj, extint_obj_swint); +STATIC MP_DEFINE_CONST_FUN_OBJ_0(extint_regs_fun_obj, extint_regs); +STATIC MP_DEFINE_CONST_STATICMETHOD_OBJ(extint_regs_obj, (mp_obj_t)&extint_regs_fun_obj); + +STATIC const mp_map_elem_t extint_locals_dict_table[] = { + { MP_OBJ_NEW_QSTR(MP_QSTR_line), (mp_obj_t)&extint_obj_line_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_enable), (mp_obj_t)&extint_obj_enable_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_disable), (mp_obj_t)&extint_obj_disable_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_swint), (mp_obj_t)&extint_obj_swint_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_regs), (mp_obj_t)&extint_regs_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_IRQ_RISING), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_IT_RISING) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_IRQ_FALLING), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_IT_FALLING) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_IRQ_RISING_FALLING), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_IT_RISING_FALLING) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_EVT_RISING), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_EVT_RISING) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_EVT_FALLING), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_EVT_FALLING) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_EVT_RISING_FALLING), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_EVT_RISING_FALLING) }, +}; + +STATIC MP_DEFINE_CONST_DICT(extint_locals_dict, extint_locals_dict_table); + +const mp_obj_type_t extint_type = { { &mp_type_type }, - .name = MP_QSTR_Exti, - .print = exti_obj_print, - .make_new = exti_make_new, - .locals_dict = (mp_obj_t)&exti_locals_dict, + .name = MP_QSTR_ExtInt, + .print = extint_obj_print, + .make_new = extint_make_new, + .locals_dict = (mp_obj_t)&extint_locals_dict, }; -void exti_init(void) { - for (exti_vector_t *v = exti_vector; v < &exti_vector[EXTI_NUM_VECTORS]; v++) { +void extint_init(void) { + for (extint_vector_t *v = extint_vector; v < &extint_vector[EXTI_NUM_VECTORS]; v++) { v->callback_obj = mp_const_none; v->param = NULL; v->mode = EXTI_Mode_Interrupt; @@ -306,7 +306,7 @@ void Handle_EXTI_Irq(uint32_t line) { if (__HAL_GPIO_EXTI_GET_FLAG(1 << line)) { __HAL_GPIO_EXTI_CLEAR_FLAG(1 << line); if (line < EXTI_NUM_VECTORS) { - exti_vector_t *v = &exti_vector[line]; + extint_vector_t *v = &extint_vector[line]; if (v->callback_obj != mp_const_none) { // When executing code within a handler we must lock the GC to prevent // any memory allocations. We must also catch any exceptions. @@ -318,8 +318,8 @@ void Handle_EXTI_Irq(uint32_t line) { } else { // Uncaught exception; disable the callback so it doesn't run again. v->callback_obj = mp_const_none; - exti_disable(line); - printf("Uncaught exception in EXTI interrupt handler line %lu\n", line); + extint_disable(line); + printf("Uncaught exception in ExtInt interrupt handler line %lu\n", line); mp_obj_print_exception((mp_obj_t)nlr.ret_val); } gc_unlock(); diff --git a/stmhal/exti.h b/stmhal/extint.h index 6feb9dceaf..c64931211f 100644 --- a/stmhal/exti.h +++ b/stmhal/extint.h @@ -20,19 +20,14 @@ #define EXTI_TRIGGER_FALLING (offsetof(EXTI_TypeDef, FTSR)) #define EXTI_TRIGGER_RISING_FALLING (EXTI_TRIGGER_RISING + EXTI_TRIGGER_FALLING) // just different from RISING or FALLING -void exti_init(void); +void extint_init(void); -uint exti_register(mp_obj_t pin_obj, mp_obj_t mode_obj, mp_obj_t trigger_obj, mp_obj_t callback_obj, bool override_callback_obj, void *param); +uint extint_register(mp_obj_t pin_obj, mp_obj_t mode_obj, mp_obj_t trigger_obj, mp_obj_t callback_obj, bool override_callback_obj, void *param); -void exti_enable(uint line); -void exti_disable(uint line); -void exti_swint(uint line); +void extint_enable(uint line); +void extint_disable(uint line); +void extint_swint(uint line); void Handle_EXTI_Irq(uint32_t line); -typedef struct { - mp_obj_t callback; - void *param; -} exti_t; - -extern const mp_obj_type_t exti_obj_type; +extern const mp_obj_type_t extint_type; diff --git a/stmhal/gpio.c b/stmhal/gpio.c deleted file mode 100644 index 4548dca587..0000000000 --- a/stmhal/gpio.c +++ /dev/null @@ -1,72 +0,0 @@ -// This is a woefully inadequate set of bindings for GPIO control, and -// needs to be replaced with something much better. - -#include <stdio.h> -#include <string.h> -#include <stm32f4xx_hal.h> - -#include "nlr.h" -#include "misc.h" -#include "mpconfig.h" -#include "qstr.h" -#include "misc.h" -#include "parse.h" -#include "obj.h" -#include "compile.h" -#include "runtime0.h" -#include "runtime.h" -#include "systick.h" -#include "gpio.h" -#include "pin.h" - -mp_obj_t pyb_gpio(uint n_args, mp_obj_t *args) { - const pin_obj_t *pin = pin_map_user_obj(args[0]); - if (n_args == 1) { - // get pin - return MP_OBJ_NEW_SMALL_INT(HAL_GPIO_ReadPin(pin->gpio, pin->pin_mask)); - } - - // set pin - HAL_GPIO_WritePin(pin->gpio, pin->pin_mask, mp_obj_is_true(args[1])); - return mp_const_none; -} - -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_gpio_obj, 1, 2, pyb_gpio); - -mp_obj_t pyb_gpio_input(uint n_args, mp_obj_t *args) { - const pin_obj_t *pin = pin_map_user_obj(args[0]); - - uint32_t pull = GPIO_NOPULL; - if (n_args > 1) { - pull = mp_obj_get_int(args[1]); - } - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.Pin = pin->pin_mask; - GPIO_InitStructure.Mode = GPIO_MODE_INPUT; - GPIO_InitStructure.Pull = pull; - HAL_GPIO_Init(pin->gpio, &GPIO_InitStructure); - - return mp_const_none; -} - -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_gpio_input_obj, 1, 2, pyb_gpio_input); - -mp_obj_t pyb_gpio_output(uint n_args, mp_obj_t *args) { - const pin_obj_t *pin = pin_map_user_obj(args[0]); - - uint32_t mode = GPIO_MODE_OUTPUT_PP; - if (n_args > 1) { - mode = mp_obj_get_int(args[1]) == GPIO_MODE_OUTPUT_OD ? - GPIO_MODE_OUTPUT_OD: GPIO_MODE_OUTPUT_PP; - } - GPIO_InitTypeDef GPIO_InitStructure; - GPIO_InitStructure.Pin = pin->pin_mask; - GPIO_InitStructure.Mode = mode; - GPIO_InitStructure.Speed = GPIO_SPEED_FAST; - GPIO_InitStructure.Pull = GPIO_NOPULL; - HAL_GPIO_Init(pin->gpio, &GPIO_InitStructure); - - return mp_const_none; -} - -MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_gpio_output_obj, 1, 2, pyb_gpio_output); diff --git a/stmhal/gpio.h b/stmhal/gpio.h deleted file mode 100644 index f43adfdac0..0000000000 --- a/stmhal/gpio.h +++ /dev/null @@ -1,7 +0,0 @@ -mp_obj_t pyb_gpio(uint n_args, mp_obj_t *args); -mp_obj_t pyb_gpio_output(uint n_args, mp_obj_t *args); -mp_obj_t pyb_gpio_input(uint n_args, mp_obj_t *args); - -MP_DECLARE_CONST_FUN_OBJ(pyb_gpio_obj); -MP_DECLARE_CONST_FUN_OBJ(pyb_gpio_input_obj); -MP_DECLARE_CONST_FUN_OBJ(pyb_gpio_output_obj); diff --git a/stmhal/help.c b/stmhal/help.c index 76dcb2f4ee..1dabd9cc83 100644 --- a/stmhal/help.c +++ b/stmhal/help.c @@ -21,21 +21,20 @@ STATIC const char *help_text = " pyb.switch(f) -- call the given function when the switch is pressed\n" " pyb.Led(n) -- create Led object for LED n (n=1,2,3,4)\n" " Led methods: on(), off(), toggle(), intensity(<n>)\n" +" pyb.Pin(pin) -- get a pin\n" +" pyb.Pin(pin, m, [p]) -- get a pin and configure it for IO mode m, pull mode p\n" +" Pin methods: value([v]), high(), low()\n" " pyb.Servo(n) -- create Servo object for servo n (n=1,2,3,4)\n" " Servo methods: calibrate(...), pulse_width([p]), angle([x, [t]]), speed([x, [t]])\n" " pyb.Accel() -- create an Accelerometer object\n" " Accelerometer methods: x(), y(), z(), tilt(), filtered_xyz()\n" " pyb.rng() -- get a 30-bit hardware random number\n" -" pyb.gpio_in(port, [m]) -- set IO port to input, mode m\n" -" pyb.gpio_out(port, [m]) -- set IO port to output, mode m\n" -" pyb.gpio(port) -- get digital port value\n" -" pyb.gpio(port, val) -- set digital port value, True or False, 1 or 0\n" " pyb.ADC(port) -- make an analog port object\n" " ADC methods: read()\n" "\n" "Ports are numbered X1-X12, X17-X22, Y1-Y12, or by their MCU name\n" -"Port input modes are: pyb.PULL_NONE, pyb.PULL_UP, pyb.PULL_DOWN\n" -"Port output modes are: pyb.PUSH_PULL, pyb.OPEN_DRAIN\n" +"Port IO modes are: pyb.Pin.IN, pyb.Pin.OUT_PP, pyb.Pin.OUT_OD\n" +"Port pull modes are: pyb.Pin.PULL_NONE, pyb.Pin.PULL_UP, pyb.Pin.PULL_DOWN\n" "\n" "Control commands:\n" " CTRL-A -- on a blank line, enter raw REPL mode\n" diff --git a/stmhal/i2c.c b/stmhal/i2c.c index 780d4fb498..4bbfec3ea8 100644 --- a/stmhal/i2c.c +++ b/stmhal/i2c.c @@ -163,8 +163,8 @@ STATIC mp_obj_t pyb_i2c_write(mp_obj_t self_in, mp_obj_t i2c_addr_in, mp_obj_t d uint8_t data[1] = {mp_obj_get_int(data_in)}; status = HAL_I2C_Master_Transmit(self->i2c_handle, i2c_addr, data, 1, 500); } else { - buffer_info_t bufinfo; - mp_get_buffer_raise(data_in, &bufinfo); + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(data_in, &bufinfo, MP_BUFFER_READ); status = HAL_I2C_Master_Transmit(self->i2c_handle, i2c_addr, bufinfo.buf, bufinfo.len, 500); } @@ -209,8 +209,8 @@ STATIC mp_obj_t pyb_i2c_mem_write(uint n_args, const mp_obj_t *args) { uint8_t data[1] = {mp_obj_get_int(args[3])}; status = HAL_I2C_Mem_Write(self->i2c_handle, i2c_addr, mem_addr, I2C_MEMADD_SIZE_8BIT, data, 1, 200); } else { - buffer_info_t bufinfo; - mp_get_buffer_raise(args[3], &bufinfo); + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[3], &bufinfo, MP_BUFFER_READ); status = HAL_I2C_Mem_Write(self->i2c_handle, i2c_addr, mem_addr, I2C_MEMADD_SIZE_8BIT, bufinfo.buf, bufinfo.len, 200); } diff --git a/stmhal/main.c b/stmhal/main.c index 4fa5b2a436..5d405453b1 100644 --- a/stmhal/main.c +++ b/stmhal/main.c @@ -21,7 +21,8 @@ #include "usart.h" #include "timer.h" #include "led.h" -#include "exti.h" +#include "pin.h" +#include "extint.h" #include "usrsw.h" #include "usb.h" #include "rtc.h" @@ -34,7 +35,6 @@ #include "accel.h" #include "servo.h" #include "dac.h" -#include "pin.h" #if 0 #include "pybwlan.h" #endif @@ -292,10 +292,11 @@ soft_reset: readline_init(); - exti_init(); + pin_init(); + extint_init(); #if MICROPY_HW_HAS_SWITCH - // must come after exti_init + // must come after extint_init switch_init(); #endif @@ -304,8 +305,6 @@ soft_reset: lcd_init(); #endif - pin_map_init(); - // local filesystem init { // try to mount the flash diff --git a/stmhal/math.c b/stmhal/math.c index 75a5aeb2ee..5fb9c4ba16 100644 --- a/stmhal/math.c +++ b/stmhal/math.c @@ -20,6 +20,10 @@ typedef union { }; } double_s_t; +double __attribute__((pcs("aapcs"))) __aeabi_i2d(int32_t x) { + return (float)x; +} + double __attribute__((pcs("aapcs"))) __aeabi_f2d(float x) { float_s_t fx={0}; double_s_t dx={0}; diff --git a/stmhal/modpyb.c b/stmhal/modpyb.c index be747958ef..c17c64202a 100644 --- a/stmhal/modpyb.c +++ b/stmhal/modpyb.c @@ -1,7 +1,7 @@ #include <stdint.h> #include <stdio.h> -#include <stm32f4xx_hal.h> +#include "stm32f4xx_hal.h" #include "misc.h" #include "mpconfig.h" @@ -13,9 +13,8 @@ #include "pybstdio.h" #include "pyexec.h" #include "led.h" -#include "gpio.h" #include "pin.h" -#include "exti.h" +#include "extint.h" #include "usrsw.h" #include "rng.h" #include "rtc.h" @@ -139,6 +138,20 @@ STATIC mp_obj_t pyb_wfi(void) { MP_DEFINE_CONST_FUN_OBJ_0(pyb_wfi_obj, pyb_wfi); +STATIC mp_obj_t pyb_disable_irq(void) { + __disable_irq(); + return mp_const_none; +} + +MP_DEFINE_CONST_FUN_OBJ_0(pyb_disable_irq_obj, pyb_disable_irq); + +STATIC mp_obj_t pyb_enable_irq(void) { + __enable_irq(); + return mp_const_none; +} + +MP_DEFINE_CONST_FUN_OBJ_0(pyb_enable_irq_obj, pyb_enable_irq); + #if 0 STATIC void SYSCLKConfig_STOP(void) { /* After wake-up from STOP reconfigure the system clock */ @@ -235,6 +248,9 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_repl_info), (mp_obj_t)&pyb_set_repl_info_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_wfi), (mp_obj_t)&pyb_wfi_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_disable_irq), (mp_obj_t)&pyb_disable_irq_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_enable_irq), (mp_obj_t)&pyb_enable_irq_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_stop), (mp_obj_t)&pyb_stop_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_standby), (mp_obj_t)&pyb_standby_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_source_dir), (mp_obj_t)&pyb_source_dir_obj }, @@ -258,6 +274,9 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_rtc_info), (mp_obj_t)&pyb_rtc_info_obj }, #endif + { MP_OBJ_NEW_QSTR(MP_QSTR_Pin), (mp_obj_t)&pin_type }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ExtInt), (mp_obj_t)&extint_type }, + #if MICROPY_HW_ENABLE_SERVO { MP_OBJ_NEW_QSTR(MP_QSTR_pwm), (mp_obj_t)&pyb_pwm_set_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_servo), (mp_obj_t)&pyb_servo_set_obj }, @@ -274,10 +293,10 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_Led), (mp_obj_t)&pyb_led_type }, { MP_OBJ_NEW_QSTR(MP_QSTR_I2C), (mp_obj_t)&pyb_i2c_type }, - { MP_OBJ_NEW_QSTR(MP_QSTR_Usart), (mp_obj_t)&pyb_usart_type }, + { MP_OBJ_NEW_QSTR(MP_QSTR_USART), (mp_obj_t)&pyb_usart_type }, { MP_OBJ_NEW_QSTR(MP_QSTR_ADC), (mp_obj_t)&pyb_adc_type }, - { MP_OBJ_NEW_QSTR(MP_QSTR_ADC_all), (mp_obj_t)&pyb_ADC_all_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ADCAll), (mp_obj_t)&pyb_adc_all_type }, #if MICROPY_HW_ENABLE_DAC { MP_OBJ_NEW_QSTR(MP_QSTR_DAC), (mp_obj_t)&pyb_dac_type }, @@ -290,21 +309,6 @@ STATIC const mp_map_elem_t pyb_module_globals_table[] = { // input { MP_OBJ_NEW_QSTR(MP_QSTR_input), (mp_obj_t)&pyb_input_obj }, - // pin mapper - { MP_OBJ_NEW_QSTR(MP_QSTR_Pin), (mp_obj_t)&pin_map_obj }, - - // GPIO bindings - { MP_OBJ_NEW_QSTR(MP_QSTR_gpio), (mp_obj_t)&pyb_gpio_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_gpio_in), (mp_obj_t)&pyb_gpio_input_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_gpio_out), (mp_obj_t)&pyb_gpio_output_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_PULL_NONE), MP_OBJ_NEW_SMALL_INT(GPIO_NOPULL) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_PULL_UP), MP_OBJ_NEW_SMALL_INT(GPIO_PULLUP) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_PULL_DOWN), MP_OBJ_NEW_SMALL_INT(GPIO_PULLDOWN) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_PUSH_PULL), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_OUTPUT_PP) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_OPEN_DRAIN), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_OUTPUT_OD) }, - - // EXTI bindings - { MP_OBJ_NEW_QSTR(MP_QSTR_Exti), (mp_obj_t)&exti_obj_type }, }; STATIC const mp_obj_dict_t pyb_module_globals = { diff --git a/stmhal/modstm.c b/stmhal/modstm.c index 5e72a75bb2..9134063428 100644 --- a/stmhal/modstm.c +++ b/stmhal/modstm.c @@ -1,7 +1,7 @@ #include <stdio.h> #include <stdint.h> -#include <stm32f4xx_hal.h> +#include "stm32f4xx_hal.h" #include "nlr.h" #include "misc.h" @@ -10,11 +10,17 @@ #include "obj.h" #include "modstm.h" +// To use compile-time constants we are restricted to 31-bit numbers (a small int, +// so it fits in a Micro Python object pointer). Thus, when extracting a constant +// from an object, we must clear the MSB. + STATIC uint32_t get_read_addr(mp_obj_t addr_o, uint align) { uint32_t addr = mp_obj_get_int(addr_o) & 0x7fffffff; + /* if (addr < 0x10000000) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "cannot read from address %08x", addr)); } + */ if ((addr & (align - 1)) != 0) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "address %08x is not aligned to %d bytes", addr, align)); } @@ -24,6 +30,8 @@ STATIC uint32_t get_read_addr(mp_obj_t addr_o, uint align) { STATIC uint32_t get_write_addr(mp_obj_t addr_o, uint align) { uint32_t addr = mp_obj_get_int(addr_o) & 0x7fffffff; if (addr < 0x10000000) { + // Everything below 0x10000000 is either ROM or aliased to something higher, so we don't + // lose anything by restricting writes to this area, and we gain some safety. nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "cannot write to address %08x", addr)); } if ((addr & (align - 1)) != 0) { @@ -32,66 +40,62 @@ STATIC uint32_t get_write_addr(mp_obj_t addr_o, uint align) { return addr; } -STATIC mp_obj_t stm_read8(mp_obj_t addr) { - uint32_t a = get_read_addr(addr, 1); - uint32_t v = *(uint8_t*)a; - return mp_obj_new_int(v); -} - -STATIC MP_DEFINE_CONST_FUN_OBJ_1(stm_read8_obj, stm_read8); - -STATIC mp_obj_t stm_read16(mp_obj_t addr) { - uint32_t a = get_read_addr(addr, 2); - uint32_t v = *(uint16_t*)a; - return mp_obj_new_int(v); -} - -STATIC MP_DEFINE_CONST_FUN_OBJ_1(stm_read16_obj, stm_read16); - -STATIC mp_obj_t stm_read32(mp_obj_t addr) { - uint32_t a = get_read_addr(addr, 4); - uint32_t v = *(uint32_t*)a; - return mp_obj_new_int(v); -} - -STATIC MP_DEFINE_CONST_FUN_OBJ_1(stm_read32_obj, stm_read32); +typedef struct _stm_mem_obj_t { + mp_obj_base_t base; + uint32_t elem_size; // in bytes +} stm_mem_obj_t; -STATIC mp_obj_t stm_write8(mp_obj_t addr, mp_obj_t val) { - uint32_t a = get_write_addr(addr, 1); - uint32_t v = mp_obj_get_int(val); - *(uint8_t*)a = v; - return mp_const_none; +STATIC void stm_mem_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { + stm_mem_obj_t *self = self_in; + print(env, "<%u-bit memory>", 8 * self->elem_size); } -STATIC MP_DEFINE_CONST_FUN_OBJ_2(stm_write8_obj, stm_write8); - -STATIC mp_obj_t stm_write16(mp_obj_t addr, mp_obj_t val) { - uint32_t a = get_write_addr(addr, 2); - uint32_t v = mp_obj_get_int(val); - *(uint16_t*)a = v; - return mp_const_none; +STATIC mp_obj_t stm_mem_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { + // TODO support slice index to read/write multiple values at once + stm_mem_obj_t *self = self_in; + if (value == MP_OBJ_NULL) { + // delete + return MP_OBJ_NOT_SUPPORTED; + } else if (value == MP_OBJ_SENTINEL) { + // load + uint32_t addr = get_read_addr(index, self->elem_size); + uint32_t val; + switch (self->elem_size) { + case 1: val = (*(uint8_t*)addr); break; + case 2: val = (*(uint16_t*)addr); break; + default: val = (*(uint32_t*)addr); break; + } + return mp_obj_new_int(val); + } else { + // store + uint32_t addr = get_write_addr(index, self->elem_size); + uint32_t val = mp_obj_get_int(value); + switch (self->elem_size) { + case 1: (*(uint8_t*)addr) = val; break; + case 2: (*(uint16_t*)addr) = val; break; + default: (*(uint32_t*)addr) = val; break; + } + return mp_const_none; + } } -STATIC MP_DEFINE_CONST_FUN_OBJ_2(stm_write16_obj, stm_write16); - -STATIC mp_obj_t stm_write32(mp_obj_t addr, mp_obj_t val) { - uint32_t a = get_write_addr(addr, 4); - uint32_t v = mp_obj_get_int(val); - *(uint32_t*)a = v; - return mp_const_none; -} +STATIC const mp_obj_type_t stm_mem_type = { + { &mp_type_type }, + .name = MP_QSTR_mem, + .print = stm_mem_print, + .subscr = stm_mem_subscr, +}; -STATIC MP_DEFINE_CONST_FUN_OBJ_2(stm_write32_obj, stm_write32); +STATIC const stm_mem_obj_t stm_mem8_obj = {{&stm_mem_type}, 1}; +STATIC const stm_mem_obj_t stm_mem16_obj = {{&stm_mem_type}, 2}; +STATIC const stm_mem_obj_t stm_mem32_obj = {{&stm_mem_type}, 4}; STATIC const mp_map_elem_t stm_module_globals_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_stm) }, - { MP_OBJ_NEW_QSTR(MP_QSTR_read8), (mp_obj_t)&stm_read8_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_read16), (mp_obj_t)&stm_read16_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_read32), (mp_obj_t)&stm_read32_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_write8), (mp_obj_t)&stm_write8_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_write16), (mp_obj_t)&stm_write16_obj }, - { MP_OBJ_NEW_QSTR(MP_QSTR_write32), (mp_obj_t)&stm_write32_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_mem8), (mp_obj_t)&stm_mem8_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_mem16), (mp_obj_t)&stm_mem16_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_mem32), (mp_obj_t)&stm_mem32_obj }, { MP_OBJ_NEW_QSTR(MP_QSTR_GPIOA), MP_OBJ_NEW_SMALL_INT(GPIOA_BASE) }, { MP_OBJ_NEW_QSTR(MP_QSTR_GPIOB), MP_OBJ_NEW_SMALL_INT(GPIOB_BASE) }, diff --git a/stmhal/pin.c b/stmhal/pin.c index 735901c306..ce66a7ad67 100644 --- a/stmhal/pin.c +++ b/stmhal/pin.c @@ -1,78 +1,330 @@ #include <stdio.h> #include <stdint.h> #include <string.h> -#include <stm32f4xx_hal.h> +#include "stm32f4xx_hal.h" + +#include "nlr.h" #include "misc.h" #include "mpconfig.h" #include "qstr.h" #include "obj.h" - +#include "runtime.h" #include "pin.h" -#if 0 -void pin_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { +// Usage Model: +// +// All Board Pins are predefined as pyb.Pin.board.Name +// +// x1_pin = pyb.Pin.board.X1 +// +// g = pyb.Pin(pyb.Pin.board.X1, pyb.Pin.IN) +// +// CPU pins which correspond to the board pins are available +// as pyb.cpu.Name. For the CPU pins, the names are the port letter +// followed by the pin number. On the PYBV4, pyb.Pin.board.X1 and +// pyb.Pin.cpu.B6 are the same pin. +// +// You can also use strings: +// +// g = pyb.Pin('X1', pyb.Pin.OUT_PP) +// +// Users can add their own names: +// +// pyb.Pin.dict["LeftMotorDir"] = pyb.Pin.cpu.C12 +// g = pyb.Pin("LeftMotorDir", pyb.Pin.OUT_OD) +// +// and can query mappings +// +// pin = pyb.Pin("LeftMotorDir") +// +// Users can also add their own mapping function: +// +// def MyMapper(pin_name): +// if pin_name == "LeftMotorDir": +// return pyb.Pin.cpu.A0 +// +// pyb.Pin.mapper(MyMapper) +// +// So, if you were to call: pyb.Pin("LeftMotorDir", pyb.Pin.OUT_PP) +// then "LeftMotorDir" is passed directly to the mapper function. +// +// To summarize, the following order determines how things get mapped into +// an ordinal pin number: +// +// 1 - Directly specify a pin object +// 2 - User supplied mapping function +// 3 - User supplied mapping (object must be usable as a dictionary key) +// 4 - Supply a string which matches a board pin +// 5 - Supply a string which matches a CPU port/pin +// +// You can set pyb.Pin.debug(True) to get some debug information about +// how a particular object gets mapped to a pin. + +// Pin class variables +STATIC mp_obj_t pin_class_mapper; +STATIC mp_obj_t pin_class_map_dict; +STATIC bool pin_class_debug; + +void pin_init(void) { + pin_class_mapper = MP_OBJ_NULL; + pin_class_map_dict = MP_OBJ_NULL; + pin_class_debug = false; +} + +// C API used to convert a user-supplied pin name into an ordinal pin number. +const pin_obj_t *pin_find(mp_obj_t user_obj) { + const pin_obj_t *pin_obj; + + // If a pin was provided, then use it + if (MP_OBJ_IS_TYPE(user_obj, &pin_type)) { + pin_obj = user_obj; + if (pin_class_debug) { + printf("Pin map passed pin "); + mp_obj_print((mp_obj_t)pin_obj, PRINT_STR); + printf("\n"); + } + return pin_obj; + } + + if (pin_class_mapper != MP_OBJ_NULL) { + pin_obj = mp_call_function_1(pin_class_mapper, user_obj); + if (pin_obj != mp_const_none) { + if (!MP_OBJ_IS_TYPE(pin_obj, &pin_type)) { + nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Pin.mapper didn't return a Pin object")); + } + if (pin_class_debug) { + printf("Pin.mapper maps "); + mp_obj_print(user_obj, PRINT_REPR); + printf(" to "); + mp_obj_print((mp_obj_t)pin_obj, PRINT_STR); + printf("\n"); + } + return pin_obj; + } + // The pin mapping function returned mp_const_none, fall through to + // other lookup methods. + } + + if (pin_class_map_dict != MP_OBJ_NULL) { + mp_map_t *pin_map_map = mp_obj_dict_get_map(pin_class_map_dict); + mp_map_elem_t *elem = mp_map_lookup(pin_map_map, user_obj, MP_MAP_LOOKUP); + if (elem != NULL && elem->value != NULL) { + pin_obj = elem->value; + if (pin_class_debug) { + printf("Pin.map_dict maps "); + mp_obj_print(user_obj, PRINT_REPR); + printf(" to "); + mp_obj_print((mp_obj_t)pin_obj, PRINT_STR); + printf("\n"); + } + return pin_obj; + } + } + + // See if the pin name matches a board pin + const char *pin_name = mp_obj_str_get_str(user_obj); + pin_obj = pin_find_named_pin(pin_board_pins, pin_name); + if (pin_obj) { + if (pin_class_debug) { + printf("Pin.board maps "); + mp_obj_print(user_obj, PRINT_REPR); + printf(" to "); + mp_obj_print((mp_obj_t)pin_obj, PRINT_STR); + printf("\n"); + } + return pin_obj; + } + + // See if the pin name matches a cpu pin + pin_obj = pin_find_named_pin(pin_cpu_pins, pin_name); + if (pin_obj) { + if (pin_class_debug) { + printf("Pin.cpu maps "); + mp_obj_print(user_obj, PRINT_REPR); + printf(" to "); + mp_obj_print((mp_obj_t)pin_obj, PRINT_STR); + printf("\n"); + } + return pin_obj; + } + + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "pin '%s' not a valid pin identifier", pin_name)); +} + +STATIC void pin_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { pin_obj_t *self = self_in; print(env, "<Pin %s>", self->name); } -mp_obj_t pin_obj_name(mp_obj_t self_in) { +// Pin constructor +STATIC mp_obj_t pin_make_new(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *args) { + mp_check_nargs(n_args, 1, 3, n_kw, false); + + // Run an argument through the mapper and return the result. + const pin_obj_t *pin = pin_find(args[0]); + + if (n_args >= 2) { + // pin mode given, so configure this GPIO + + // get io mode + uint mode = mp_obj_get_int(args[1]); + if (!IS_GPIO_MODE(mode)) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid pin mode: %d", mode)); + } + + // get pull mode + uint pull = GPIO_NOPULL; + if (n_args >= 3) { + pull = mp_obj_get_int(args[2]); + if (!IS_GPIO_PULL(pull)) { + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid pin pull: %d", pull)); + } + } + + // configure the GPIO as requested + GPIO_InitTypeDef GPIO_InitStructure; + GPIO_InitStructure.Pin = pin->pin_mask; + GPIO_InitStructure.Mode = mode; + GPIO_InitStructure.Pull = pull; + GPIO_InitStructure.Speed = GPIO_SPEED_FAST; + GPIO_InitStructure.Alternate = 0; + HAL_GPIO_Init(pin->gpio, &GPIO_InitStructure); + } + + return (mp_obj_t)pin; +} + +// class method +STATIC mp_obj_t pin_mapper(uint n_args, mp_obj_t *args) { + if (n_args > 1) { + pin_class_mapper = args[1]; + return mp_const_none; + } + return pin_class_mapper; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_mapper_fun_obj, 1, 2, pin_mapper); +STATIC MP_DEFINE_CONST_CLASSMETHOD_OBJ(pin_mapper_obj, (mp_obj_t)&pin_mapper_fun_obj); + +// class method +STATIC mp_obj_t pin_map_dict(uint n_args, mp_obj_t *args) { + if (n_args > 1) { + pin_class_map_dict = args[1]; + return mp_const_none; + } + return pin_class_map_dict; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_map_dict_fun_obj, 1, 2, pin_map_dict); +STATIC MP_DEFINE_CONST_CLASSMETHOD_OBJ(pin_map_dict_obj, (mp_obj_t)&pin_map_dict_fun_obj); + +// class method +STATIC mp_obj_t pin_debug(uint n_args, mp_obj_t *args) { + if (n_args > 1) { + pin_class_debug = mp_obj_is_true(args[1]); + return mp_const_none; + } + return MP_BOOL(pin_class_debug); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_debug_fun_obj, 1, 2, pin_debug); +STATIC MP_DEFINE_CONST_CLASSMETHOD_OBJ(pin_debug_obj, (mp_obj_t)&pin_debug_fun_obj); + +STATIC mp_obj_t pin_value(uint n_args, mp_obj_t *args) { + pin_obj_t *self = args[0]; + if (n_args == 1) { + // get pin + return MP_OBJ_NEW_SMALL_INT((self->gpio->IDR >> self->port) & 1); + } else { + // set pin + if (mp_obj_is_true(args[1])) { + self->gpio->BSRRL = self->pin_mask; + } else { + self->gpio->BSRRH = self->pin_mask; + } + return mp_const_none; + } +} +STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_value_obj, 1, 2, pin_value); + +STATIC mp_obj_t pin_low(mp_obj_t self_in) { + pin_obj_t *self = self_in; + self->gpio->BSRRH = self->pin_mask; + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_low_obj, pin_low); + +STATIC mp_obj_t pin_high(mp_obj_t self_in) { + pin_obj_t *self = self_in; + self->gpio->BSRRL = self->pin_mask; + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_high_obj, pin_high); + +STATIC mp_obj_t pin_name(mp_obj_t self_in) { pin_obj_t *self = self_in; return MP_OBJ_NEW_QSTR(qstr_from_str(self->name)); } +STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_name_obj, pin_name); -mp_obj_t pin_obj_port(mp_obj_t self_in) { +STATIC mp_obj_t pin_port(mp_obj_t self_in) { pin_obj_t *self = self_in; return MP_OBJ_NEW_SMALL_INT((mp_small_int_t)self->port); } +STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_port_obj, pin_port); -mp_obj_t pin_obj_pin(mp_obj_t self_in) { +STATIC mp_obj_t pin_pin(mp_obj_t self_in) { pin_obj_t *self = self_in; return MP_OBJ_NEW_SMALL_INT((mp_small_int_t)self->pin); } +STATIC MP_DEFINE_CONST_FUN_OBJ_1(pin_pin_obj, pin_pin); + +STATIC const mp_map_elem_t pin_locals_dict_table[] = { + // instance methods + { MP_OBJ_NEW_QSTR(MP_QSTR_value), (mp_obj_t)&pin_value_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_low), (mp_obj_t)&pin_low_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_high), (mp_obj_t)&pin_high_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_name), (mp_obj_t)&pin_name_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_port), (mp_obj_t)&pin_port_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_pin), (mp_obj_t)&pin_pin_obj }, + + // class methods + { MP_OBJ_NEW_QSTR(MP_QSTR_mapper), (mp_obj_t)&pin_mapper_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_dict), (mp_obj_t)&pin_map_dict_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_debug), (mp_obj_t)&pin_debug_obj }, -static MP_DEFINE_CONST_FUN_OBJ_1(pin_obj_name_obj, pin_obj_name); -static MP_DEFINE_CONST_FUN_OBJ_1(pin_obj_port_obj, pin_obj_port); -static MP_DEFINE_CONST_FUN_OBJ_1(pin_obj_pin_obj, pin_obj_pin); + // class attributes + { MP_OBJ_NEW_QSTR(MP_QSTR_board), (mp_obj_t)&pin_board_pins_obj }, + { MP_OBJ_NEW_QSTR(MP_QSTR_cpu), (mp_obj_t)&pin_cpu_pins_obj }, -static const mp_method_t pin_methods[] = { - { "name", &pin_obj_name_obj }, - { "port", &pin_obj_port_obj }, - { "pin", &pin_obj_pin_obj }, - { NULL, NULL }, + // class constants + { MP_OBJ_NEW_QSTR(MP_QSTR_IN), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_INPUT) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_OUT_PP), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_OUTPUT_PP) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_OUT_OD), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_OUTPUT_OD) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_AF_PP), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_AF_PP) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_AF_OD), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_AF_OD) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_ANALOG), MP_OBJ_NEW_SMALL_INT(GPIO_MODE_ANALOG) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PULL_NONE), MP_OBJ_NEW_SMALL_INT(GPIO_NOPULL) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PULL_UP), MP_OBJ_NEW_SMALL_INT(GPIO_PULLUP) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_PULL_DOWN), MP_OBJ_NEW_SMALL_INT(GPIO_PULLDOWN) }, }; -#endif -const mp_obj_type_t pin_obj_type = { -#if 0 +STATIC MP_DEFINE_CONST_DICT(pin_locals_dict, pin_locals_dict_table); + +const mp_obj_type_t pin_type = { { &mp_type_type }, -#else - { NULL }, -#endif .name = MP_QSTR_Pin, -#if 0 - .print = pin_obj_print, - .methods = pin_methods, -#endif + .print = pin_print, + .make_new = pin_make_new, + .locals_dict = (mp_obj_t)&pin_locals_dict, }; -#if 0 -void pin_af_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { +STATIC void pin_af_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { pin_af_obj_t *self = self_in; print(env, "<Pin AF %d fn:%d unit:%d typ:%d>", self->idx, self->fn, self->unit, self->type); } -#endif -const mp_obj_type_t pin_af_obj_type = { -#if 0 +const mp_obj_type_t pin_af_type = { { &mp_type_type }, -#else - { NULL }, -#endif .name = MP_QSTR_PinAF, -#if 0 .print = pin_af_obj_print, -#endif }; - diff --git a/stmhal/pin.h b/stmhal/pin.h index 2aa50655b4..0617b13a72 100644 --- a/stmhal/pin.h +++ b/stmhal/pin.h @@ -86,40 +86,29 @@ typedef struct { const pin_af_obj_t *af; } pin_obj_t; -extern const mp_obj_type_t pin_obj_type; -extern const mp_obj_type_t pin_af_obj_type; +extern const mp_obj_type_t pin_type; +extern const mp_obj_type_t pin_af_type; typedef struct { - const char *name; + const char *name; const pin_obj_t *pin; } pin_named_pin_t; extern const pin_named_pin_t pin_board_pins[]; extern const pin_named_pin_t pin_cpu_pins[]; -typedef struct { - mp_obj_base_t base; - mp_obj_t mapper; - mp_obj_t map_dict; - bool debug; -} pin_map_obj_t; - -extern pin_map_obj_t pin_map_obj; +//extern pin_map_obj_t pin_map_obj; typedef struct { mp_obj_base_t base; - const char *name; + qstr name; const pin_named_pin_t *named_pins; } pin_named_pins_obj_t; extern const pin_named_pins_obj_t pin_board_pins_obj; extern const pin_named_pins_obj_t pin_cpu_pins_obj; +void pin_init(void); +const pin_obj_t *pin_find(mp_obj_t user_obj); const pin_obj_t *pin_find_named_pin(const pin_named_pin_t *pins, const char *name); const pin_af_obj_t *pin_find_af(const pin_obj_t *pin, uint8_t fn, uint8_t unit, uint8_t pin_type); - -void pin_map_init(void); - -// C function for mapping python pin identifier into an ordinal pin number. -const pin_obj_t *pin_map_user_obj(mp_obj_t user_obj); - diff --git a/stmhal/pin_map.c b/stmhal/pin_map.c deleted file mode 100644 index c0c6910b2e..0000000000 --- a/stmhal/pin_map.c +++ /dev/null @@ -1,226 +0,0 @@ -#include <stdio.h> -#include <stdint.h> -#include <string.h> -#include <stm32f4xx_hal.h> - -#include "misc.h" -#include "mpconfig.h" -#include "qstr.h" -#include "obj.h" -#include "runtime.h" -#include "nlr.h" - -#include "pin.h" - -// Usage Model: -// -// All Board Pins are predefined as pyb.Pin.board.Name -// -// x1_pin = pyb.Pin.board.X1 -// -// g = pyb.gpio(pyb.Pin.board.X1, 0) -// -// CPU pins which correspond to the board pins are available -// as pyb.cpu.Name. For the CPU pins, the names are the port letter -// followed by the pin number. On the PYBV4, pyb.Pin.board.X1 and -// pyb.Pin.cpu.B6 are the same pin. -// -// You can also use strings: -// -// g = pyb.gpio('X1', 0) -// -// Users can add their own names: -// -// pyb.Pin("LeftMotorDir", pyb.Pin.cpu.C12) -// g = pyb.gpio("LeftMotorDir", 0) -// -// and can query mappings -// -// pin = pyb.Pin("LeftMotorDir"); -// -// Users can also add their own mapping function: -// -// def MyMapper(pin_name): -// if pin_name == "LeftMotorDir": -// return pyb.Pin.cpu.A0 -// -// pyb.Pin.mapper(MyMapper) -// -// So, if you were to call: pyb.gpio("LeftMotorDir", 0) -// then "LeftMotorDir" is passed directly to the mapper function. -// -// To summarize, the following order determines how things get mapped into -// an ordinal pin number: -// -// 1 - Directly specify a pin object -// 2 - User supplied mapping function -// 3 - User supplied mapping (object must be usable as a dictionary key) -// 4 - Supply a string which matches a board pin -// 5 - Supply a string which matches a CPU port/pin -// -// You can set pyb.Pin.debug(True) to get some debug information about -// how a particular object gets mapped to a pin. - -static void pin_map_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { - (void)self_in; - print(env, "<PinMap>"); -} - -static mp_obj_t pin_map_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *args) { - pin_map_obj_t *self = self_in; - mp_check_nargs(n_args, 1, 2, n_kw, false); - - if (n_args > 1) { - if (!self->map_dict) { - self->map_dict = mp_obj_new_dict(1); - } - mp_obj_dict_store(self->map_dict, args[0], args[1]); - return mp_const_none; - } - - // Run an argument through the mapper and return the result. - return (mp_obj_t)pin_map_user_obj(args[0]); -} - -static mp_obj_t pin_map_obj_mapper(uint n_args, mp_obj_t *args) { - pin_map_obj_t *self = args[0]; - if (n_args > 1) { - self->mapper = args[1]; - return mp_const_none; - } - return self->mapper; -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_map_obj_mapper_obj, 1, 2, pin_map_obj_mapper); - -static mp_obj_t pin_map_obj_debug(uint n_args, mp_obj_t *args) { - pin_map_obj_t *self = args[0]; - if (n_args > 1) { - self->debug = mp_obj_is_true(args[1]); - return mp_const_none; - } - return MP_BOOL(self->debug); -} -static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_map_obj_debug_obj, 1, 2, pin_map_obj_debug); - -static void pin_map_load_attr(mp_obj_t self_in, qstr attr_qstr, mp_obj_t *dest) { - (void)self_in; - const char *attr = qstr_str(attr_qstr); - - if (strcmp(attr, "mapper") == 0) { - dest[0] = (mp_obj_t)&pin_map_obj_mapper_obj; - dest[1] = self_in; - } - if (strcmp(attr, "debug") == 0) { - dest[0] = (mp_obj_t)&pin_map_obj_debug_obj; - dest[1] = self_in; - } - if (strcmp(attr, pin_board_pins_obj.name) == 0) { - dest[0] = (mp_obj_t)&pin_board_pins_obj; - dest[1] = MP_OBJ_NULL; - } - if (strcmp(attr, pin_cpu_pins_obj.name) == 0) { - dest[0] = (mp_obj_t)&pin_cpu_pins_obj; - dest[1] = MP_OBJ_NULL; - } -} - -static const mp_obj_type_t pin_map_obj_type = { - { &mp_type_type }, - .name = MP_QSTR_PinMap, - .print = pin_map_obj_print, - .call = pin_map_call, - .load_attr = pin_map_load_attr, -}; - -static const pin_map_obj_t pin_map_obj_init = { - { &pin_map_obj_type }, - .mapper = MP_OBJ_NULL, - .map_dict = MP_OBJ_NULL, - .debug = false, -}; - -pin_map_obj_t pin_map_obj; - -void pin_map_init(void) { - pin_map_obj = pin_map_obj_init; -} - -// C API used to convert a user-supplied pin name into an ordinal pin number. -const pin_obj_t *pin_map_user_obj(mp_obj_t user_obj) { - const pin_obj_t *pin_obj; - - // If a pin was provided, then use it - if (MP_OBJ_IS_TYPE(user_obj, &pin_obj_type)) { - pin_obj = user_obj; - if (pin_map_obj.debug) { - printf("Pin map passed pin "); - mp_obj_print((mp_obj_t)pin_obj, PRINT_STR); - printf("\n"); - } - return pin_obj; - } - - if (pin_map_obj.mapper) { - pin_obj = mp_call_function_1(pin_map_obj.mapper, user_obj); - if (pin_obj != mp_const_none) { - if (!MP_OBJ_IS_TYPE(pin_obj, &pin_obj_type)) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Pin.mapper didn't return a Pin object")); - } - if (pin_map_obj.debug) { - printf("Pin.mapper maps "); - mp_obj_print(user_obj, PRINT_REPR); - printf(" to "); - mp_obj_print((mp_obj_t)pin_obj, PRINT_STR); - printf("\n"); - } - return pin_obj; - } - // The pin mapping function returned mp_const_none, fall through to - // other lookup methods. - } - - if (pin_map_obj.map_dict) { - mp_map_t *pin_map_map = mp_obj_dict_get_map(pin_map_obj.map_dict); - mp_map_elem_t *elem = mp_map_lookup(pin_map_map, user_obj, MP_MAP_LOOKUP); - if (elem != NULL && elem->value != NULL) { - pin_obj = elem->value; - if (pin_map_obj.debug) { - printf("Pin.map_dict maps "); - mp_obj_print(user_obj, PRINT_REPR); - printf(" to "); - mp_obj_print((mp_obj_t)pin_obj, PRINT_STR); - printf("\n"); - } - return pin_obj; - } - } - - // See if the pin name matches a board pin - const char *pin_name = mp_obj_str_get_str(user_obj); - pin_obj = pin_find_named_pin(pin_board_pins, pin_name); - if (pin_obj) { - if (pin_map_obj.debug) { - printf("Pin.board maps "); - mp_obj_print(user_obj, PRINT_REPR); - printf(" to "); - mp_obj_print((mp_obj_t)pin_obj, PRINT_STR); - printf("\n"); - } - return pin_obj; - } - - // See if the pin name matches a cpu pin - pin_obj = pin_find_named_pin(pin_cpu_pins, pin_name); - if (pin_obj) { - if (pin_map_obj.debug) { - printf("Pin.cpu maps "); - mp_obj_print(user_obj, PRINT_REPR); - printf(" to "); - mp_obj_print((mp_obj_t)pin_obj, PRINT_STR); - printf("\n"); - } - return pin_obj; - } - - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "pin '%s' not a valid pin identifier", pin_name)); -} diff --git a/stmhal/pin_named_pins.c b/stmhal/pin_named_pins.c index 48906ad800..6e81bb7424 100644 --- a/stmhal/pin_named_pins.c +++ b/stmhal/pin_named_pins.c @@ -1,22 +1,22 @@ #include <stdio.h> #include <stdint.h> #include <string.h> -#include <stm32f4xx_hal.h> + +#include "stm32f4xx_hal.h" #include "misc.h" #include "mpconfig.h" #include "qstr.h" #include "obj.h" #include "runtime.h" - #include "pin.h" -static void pin_named_pins_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { +STATIC void pin_named_pins_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { pin_named_pins_obj_t *self = self_in; - print(env, "<Pin.%s>", self->name); + print(env, "<Pin.%s>", qstr_str(self->name)); } -static void pin_named_pins_obj_load_attr(mp_obj_t self_in, qstr attr_qstr, mp_obj_t *dest) { +STATIC void pin_named_pins_obj_load_attr(mp_obj_t self_in, qstr attr_qstr, mp_obj_t *dest) { pin_named_pins_obj_t *self = self_in; const char *attr = qstr_str(attr_qstr); const pin_obj_t *pin = pin_find_named_pin(self->named_pins, attr); @@ -35,13 +35,13 @@ static const mp_obj_type_t pin_named_pins_obj_type = { const pin_named_pins_obj_t pin_board_pins_obj = { { &pin_named_pins_obj_type }, - .name = "board", + .name = MP_QSTR_board, .named_pins = pin_board_pins, }; const pin_named_pins_obj_t pin_cpu_pins_obj = { { &pin_named_pins_obj_type }, - .name = "cpu", + .name = MP_QSTR_cpu, .named_pins = pin_cpu_pins, }; diff --git a/stmhal/qstrdefsport.h b/stmhal/qstrdefsport.h index d64b0c2ddb..e77f85bff7 100644 --- a/stmhal/qstrdefsport.h +++ b/stmhal/qstrdefsport.h @@ -7,6 +7,8 @@ Q(sd_test) Q(present) Q(power) Q(wfi) +Q(disable_irq) +Q(enable_irq) Q(stop) Q(standby) Q(source_dir) @@ -32,25 +34,37 @@ Q(rng) Q(LCD) Q(SD) Q(SDcard) -Q(gpio) -Q(gpio_in) -Q(gpio_out) Q(FileIO) // Entries for sys.path Q(0:/) -Q(0:/src) Q(0:/lib) +Q(rtc_info) +Q(millis) + +// for Pin class Q(Pin) -Q(PinMap) Q(PinAF) Q(PinNamed) -Q(rtc_info) -Q(millis) +Q(value) +Q(low) +Q(high) +Q(name) +Q(port) +Q(pin) +Q(mapper) +Q(dict) +Q(debug) +Q(board) +Q(cpu) +Q(IN) +Q(OUT_PP) +Q(OUT_OD) +Q(AF_PP) +Q(AF_OD) +Q(ANALOG) Q(PULL_NONE) Q(PULL_UP) Q(PULL_DOWN) -Q(PUSH_PULL) -Q(OPEN_DRAIN) // for Led object Q(Led) @@ -59,26 +73,26 @@ Q(off) Q(toggle) Q(intensity) -// for Usart object -Q(Usart) +// for USART object +Q(USART) Q(status) Q(recv_chr) Q(send_chr) Q(send) -// for exti object -Q(Exti) +// for ExtInt class +Q(ExtInt) Q(line) Q(enable) Q(disable) Q(swint) Q(regs) -Q(MODE_IRQ_RISING) -Q(MODE_IRQ_FALLING) -Q(MODE_IRQ_RISING_FALLING) -Q(MODE_EVT_RISING) -Q(MODE_EVT_FALLING) -Q(MODE_EVT_RISING_FALLING) +Q(IRQ_RISING) +Q(IRQ_FALLING) +Q(IRQ_RISING_FALLING) +Q(EVT_RISING) +Q(EVT_FALLING) +Q(EVT_RISING_FALLING) // for I2C object Q(I2C) @@ -97,7 +111,7 @@ Q(filtered_xyz) // for ADC object Q(ADC) -Q(ADC_all) +Q(ADCAll) Q(read_timed) Q(read_channel) Q(read_core_temp) @@ -137,12 +151,10 @@ Q(input) // for stm module Q(stm) -Q(read8) -Q(read16) -Q(read32) -Q(write8) -Q(write16) -Q(write32) +Q(mem) +Q(mem8) +Q(mem16) +Q(mem32) Q(GPIOA) Q(GPIOB) Q(GPIOC) diff --git a/stmhal/stm32f4xx_it.c b/stmhal/stm32f4xx_it.c index df69f52b8e..9b64f6165c 100644 --- a/stmhal/stm32f4xx_it.c +++ b/stmhal/stm32f4xx_it.c @@ -47,7 +47,7 @@ #include "mpconfig.h"
#include "qstr.h"
#include "obj.h"
-#include "exti.h"
+#include "extint.h"
#include "timer.h"
#include "storage.h"
diff --git a/stmhal/usart.c b/stmhal/usart.c index cc0a6112e6..89770942be 100644 --- a/stmhal/usart.c +++ b/stmhal/usart.c @@ -165,13 +165,13 @@ void usart_tx_strn_cooked(pyb_usart_obj_t *usart_obj, const char *str, uint len) STATIC void usart_obj_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) { pyb_usart_obj_t *self = self_in; - print(env, "<Usart %lu>", self->usart_id); + print(env, "<USART %lu>", self->usart_id); } STATIC mp_obj_t usart_obj_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) { // check arguments if (!(n_args == 2 && n_kw == 0)) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Usart accepts 2 arguments")); + nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "USART accepts 2 arguments")); } // create object @@ -194,7 +194,7 @@ STATIC mp_obj_t usart_obj_make_new(mp_obj_t type_in, uint n_args, uint n_kw, con o->usart_id = PYB_USART_YB; #endif } else { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Usart port %s does not exist", port)); + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "USART port %s does not exist", port)); } } else { o->usart_id = mp_obj_get_int(args[0]); @@ -202,7 +202,7 @@ STATIC mp_obj_t usart_obj_make_new(mp_obj_t type_in, uint n_args, uint n_kw, con // init USART (if it fails, it's because the port doesn't exist) if (!usart_init(o, mp_obj_get_int(args[1]))) { - nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "Usart port %d does not exist", o->usart_id)); + nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "USART port %d does not exist", o->usart_id)); } o->is_enabled = true; @@ -267,7 +267,7 @@ STATIC MP_DEFINE_CONST_DICT(usart_locals_dict, usart_locals_dict_table); const mp_obj_type_t pyb_usart_type = { { &mp_type_type }, - .name = MP_QSTR_Usart, + .name = MP_QSTR_USART, .print = usart_obj_print, .make_new = usart_obj_make_new, .locals_dict = (mp_obj_t)&usart_locals_dict, diff --git a/stmhal/usrsw.c b/stmhal/usrsw.c index 0ab407cd96..0d5d7e9b0c 100644 --- a/stmhal/usrsw.c +++ b/stmhal/usrsw.c @@ -6,12 +6,10 @@ #include "qstr.h" #include "obj.h" #include "runtime.h" -#include "usrsw.h" - -#include "exti.h" -#include "gpio.h" +#include "extint.h" #include "pin.h" #include "genhdr/pins.h" +#include "usrsw.h" // Usage Model: // @@ -70,12 +68,11 @@ static mp_obj_t pyb_switch(uint n_args, mp_obj_t *args) { // Init the EXTI each time this function is called, since the EXTI // may have been disabled by an exception in the interrupt, or the // user disabling the line explicitly. - exti_register((mp_obj_t)&MICROPY_HW_USRSW_PIN, - MP_OBJ_NEW_SMALL_INT(MICROPY_HW_USRSW_EXTI_MODE), - MP_OBJ_NEW_SMALL_INT(MICROPY_HW_USRSW_PULL), - switch_user_callback_obj == mp_const_none ? mp_const_none : (mp_obj_t)&switch_callback_obj, - true, - NULL); + extint_register((mp_obj_t)&MICROPY_HW_USRSW_PIN, + MP_OBJ_NEW_SMALL_INT(MICROPY_HW_USRSW_EXTI_MODE), + MP_OBJ_NEW_SMALL_INT(MICROPY_HW_USRSW_PULL), + switch_user_callback_obj == mp_const_none ? mp_const_none : (mp_obj_t)&switch_callback_obj, + true, NULL); return mp_const_none; } } diff --git a/unix/modffi.c b/unix/modffi.c index fd48aa17ec..7b8e43874b 100644 --- a/unix/modffi.c +++ b/unix/modffi.c @@ -268,9 +268,9 @@ mp_obj_t ffifunc_call(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t * values[i] = (ffi_arg)s; } else if (((mp_obj_base_t*)a)->type->buffer_p.get_buffer != NULL) { mp_obj_base_t *o = (mp_obj_base_t*)a; - buffer_info_t bufinfo; - o->type->buffer_p.get_buffer(o, &bufinfo, BUFFER_READ); // TODO: BUFFER_READ? - if (bufinfo.buf == NULL) { + mp_buffer_info_t bufinfo; + int ret = o->type->buffer_p.get_buffer(o, &bufinfo, MP_BUFFER_READ); // TODO: MP_BUFFER_READ? + if (ret != 0 || bufinfo.buf == NULL) { goto error; } values[i] = (ffi_arg)bufinfo.buf; diff --git a/unix/modsocket.c b/unix/modsocket.c index 7b1aaa975d..bfa5849c86 100644 --- a/unix/modsocket.c +++ b/unix/modsocket.c @@ -80,8 +80,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(socket_fileno_obj, socket_fileno); STATIC mp_obj_t socket_connect(mp_obj_t self_in, mp_obj_t addr_in) { mp_obj_socket_t *self = self_in; - buffer_info_t bufinfo; - mp_get_buffer_raise(addr_in, &bufinfo); + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(addr_in, &bufinfo, MP_BUFFER_READ); int r = connect(self->fd, (const struct sockaddr *)bufinfo.buf, bufinfo.len); RAISE_ERRNO(r, errno); return mp_const_none; @@ -90,8 +90,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(socket_connect_obj, socket_connect); STATIC mp_obj_t socket_bind(mp_obj_t self_in, mp_obj_t addr_in) { mp_obj_socket_t *self = self_in; - buffer_info_t bufinfo; - mp_get_buffer_raise(addr_in, &bufinfo); + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(addr_in, &bufinfo, MP_BUFFER_READ); int r = bind(self->fd, (const struct sockaddr *)bufinfo.buf, bufinfo.len); RAISE_ERRNO(r, errno); return mp_const_none; @@ -168,8 +168,8 @@ STATIC mp_obj_t socket_setsockopt(uint n_args, const mp_obj_t *args) { optval = &val; optlen = sizeof(val); } else { - buffer_info_t bufinfo; - mp_get_buffer_raise(args[3], &bufinfo); + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(args[3], &bufinfo, MP_BUFFER_READ); optval = bufinfo.buf; optlen = bufinfo.len; } |