review update, add RP2040 example
This commit is contained in:
parent
1648a3db1e
commit
1e178318cf
|
@ -2140,6 +2140,10 @@ msgstr ""
|
|||
msgid "Unable to access unaliged IO register"
|
||||
msgstr ""
|
||||
|
||||
#: ports/raspberrypi/common-hal/memorymap/AddressRange.c
|
||||
msgid "Unable to access unaligned IO register"
|
||||
msgstr ""
|
||||
|
||||
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
|
||||
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
|
||||
#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c
|
||||
|
@ -4048,6 +4052,10 @@ msgstr ""
|
|||
msgid "source_bitmap must have value_count of 8"
|
||||
msgstr ""
|
||||
|
||||
#: shared-bindings/memorymap/AddressRange.c
|
||||
msgid "start must be an int"
|
||||
msgstr ""
|
||||
|
||||
#: py/objstr.c
|
||||
msgid "start/end indices"
|
||||
msgstr ""
|
||||
|
|
|
@ -90,7 +90,7 @@ void common_hal_memorymap_addressrange_set_bytes(const memorymap_addressrange_ob
|
|||
case IO:
|
||||
if ((size_t)dest_addr & 0x03 || len & 0x03) {
|
||||
// Unaligned access or unaligned length not supported by RP2 for IO registers
|
||||
mp_raise_RuntimeError(translate("Unable to access unaliged IO register"));
|
||||
mp_raise_RuntimeError(translate("Unable to access unaligned IO register"));
|
||||
} else {
|
||||
// Aligned access and length, use 32-bit writes
|
||||
uint32_t *dest_addr32 = (uint32_t *)dest_addr;
|
||||
|
|
|
@ -115,8 +115,6 @@ void mp_arg_parse_all(size_t n_pos, const mp_obj_t *pos, mp_map_t *kws, size_t n
|
|||
out_vals[i].u_bool = mp_obj_is_true(given_arg);
|
||||
} else if ((allowed[i].flags & MP_ARG_KIND_MASK) == MP_ARG_INT) {
|
||||
out_vals[i].u_int = mp_obj_get_int(given_arg);
|
||||
} else if ((allowed[i].flags & MP_ARG_KIND_MASK) == MP_ARG_UINT) {
|
||||
out_vals[i].u_uint = mp_obj_get_uint(given_arg);
|
||||
} else {
|
||||
assert((allowed[i].flags & MP_ARG_KIND_MASK) == MP_ARG_OBJ);
|
||||
out_vals[i].u_obj = given_arg;
|
||||
|
|
15
py/obj.c
15
py/obj.c
|
@ -420,21 +420,6 @@ bool mp_obj_get_int_maybe(mp_const_obj_t arg, mp_int_t *value) {
|
|||
return true;
|
||||
}
|
||||
|
||||
mp_uint_t mp_obj_get_uint(mp_const_obj_t arg) {
|
||||
if (arg == mp_const_false) {
|
||||
return 0;
|
||||
} else if (arg == mp_const_true) {
|
||||
return 1;
|
||||
} else if (mp_obj_is_small_int(arg)) {
|
||||
return MP_OBJ_SMALL_INT_VALUE(arg);
|
||||
} else if (mp_obj_is_type(arg, &mp_type_int)) {
|
||||
return mp_obj_int_get_uint_checked(arg);
|
||||
} else {
|
||||
mp_obj_t res = mp_unary_op(MP_UNARY_OP_INT, (mp_obj_t)arg);
|
||||
return mp_obj_int_get_uint_checked(res);
|
||||
}
|
||||
}
|
||||
|
||||
#if MICROPY_PY_BUILTINS_FLOAT
|
||||
bool mp_obj_get_float_maybe(mp_obj_t arg, mp_float_t *value) {
|
||||
mp_float_t val;
|
||||
|
|
1
py/obj.h
1
py/obj.h
|
@ -939,7 +939,6 @@ static MP_INLINE bool mp_obj_is_integer(mp_const_obj_t o) {
|
|||
mp_int_t mp_obj_get_int(mp_const_obj_t arg);
|
||||
mp_int_t mp_obj_get_int_truncated(mp_const_obj_t arg);
|
||||
bool mp_obj_get_int_maybe(mp_const_obj_t arg, mp_int_t *value);
|
||||
mp_uint_t mp_obj_get_uint(mp_const_obj_t arg);
|
||||
#if MICROPY_PY_BUILTINS_FLOAT
|
||||
mp_float_t mp_obj_get_float(mp_obj_t self_in);
|
||||
bool mp_obj_get_float_maybe(mp_obj_t arg, mp_float_t *value);
|
||||
|
|
|
@ -438,10 +438,6 @@ mp_int_t mp_obj_int_get_checked(mp_const_obj_t self_in) {
|
|||
return MP_OBJ_SMALL_INT_VALUE(self_in);
|
||||
}
|
||||
|
||||
mp_uint_t mp_obj_int_get_uint_checked(mp_const_obj_t self_in) {
|
||||
return MP_OBJ_SMALL_INT_VALUE(self_in);
|
||||
}
|
||||
|
||||
|
||||
#endif // MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_NONE
|
||||
|
||||
|
|
|
@ -45,7 +45,6 @@ typedef enum {
|
|||
MP_ARG_BOOL = 0x001,
|
||||
MP_ARG_INT = 0x002,
|
||||
MP_ARG_OBJ = 0x003,
|
||||
MP_ARG_UINT = 0x004,
|
||||
MP_ARG_KIND_MASK = 0x0ff,
|
||||
MP_ARG_REQUIRED = 0x100,
|
||||
MP_ARG_KW_ONLY = 0x200,
|
||||
|
|
|
@ -47,23 +47,58 @@
|
|||
//| import memorymap
|
||||
//| rtc_slow_mem = memorymap.AddressRange(start=0x50000000, length=0x2000)
|
||||
//| rtc_slow_mem[0:3] = b"\xcc\x10\x00"
|
||||
//|
|
||||
//| Example I/O register usage on RP2040::
|
||||
//|
|
||||
//| import binascii
|
||||
//| import board
|
||||
//| import digitalio
|
||||
//| import memorymap
|
||||
//|
|
||||
//| def rp2040_set_pad_drive(p, d):
|
||||
//| pads_bank0 = memorymap.AddressRange(start=0x4001C000, length=0x4000)
|
||||
//| pad_ctrl = int.from_bytes(pads_bank0[p*4+4:p*4+8], "little")
|
||||
//| # Pad control register is updated using an MP-safe atomic XOR
|
||||
//| pad_ctrl ^= (d << 4)
|
||||
//| pad_ctrl &= 0x00000030
|
||||
//| pads_bank0[p*4+0x3004:p*4+0x3008] = pad_ctrl.to_bytes(4, "little")
|
||||
//|
|
||||
//| def rp2040_get_pad_drive(p):
|
||||
//| pads_bank0 = memorymap.AddressRange(start=0x4001C000, length=0x4000)
|
||||
//| pad_ctrl = int.from_bytes(pads_bank0[p*4+4:p*4+8], "little")
|
||||
//| return (pad_ctrl >> 4) & 0x3
|
||||
//|
|
||||
//| # set GPIO16 pad drive strength to 12 mA
|
||||
//| rp2040_set_pad_drive(16, 3)
|
||||
//|
|
||||
//| # print GPIO16 pad drive strength
|
||||
//| print(rp2040_get_pad_drive(16))
|
||||
//| """
|
||||
|
||||
//| def __init__(self, *, start, length) -> None:
|
||||
//| """Constructs an address range starting at ``start`` and ending at
|
||||
//| ``start + length - 1``. An exception will be raised if any of the
|
||||
//| ``start + length``. An exception will be raised if any of the
|
||||
//| addresses are invalid or protected."""
|
||||
//| ...
|
||||
STATIC mp_obj_t memorymap_addressrange_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
|
||||
enum { ARG_start, ARG_length };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_start, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_UINT },
|
||||
{ MP_QSTR_start, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
|
||||
{ MP_QSTR_length, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT },
|
||||
};
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
size_t start = args[ARG_start].u_uint;
|
||||
// Argument start is a pointer into the address map, so we validate it here because a
|
||||
// signed int argument will overflow if it is in the upper half of the map.
|
||||
size_t start;
|
||||
if (mp_obj_is_small_int(args[ARG_start].u_obj)) {
|
||||
start = MP_OBJ_SMALL_INT_VALUE(args[ARG_start].u_obj);
|
||||
} else if (mp_obj_is_type(args[ARG_start].u_obj, &mp_type_int)) {
|
||||
start = mp_obj_int_get_uint_checked(args[ARG_start].u_obj);
|
||||
} else {
|
||||
mp_raise_TypeError(translate("start must be an int"));
|
||||
}
|
||||
size_t length =
|
||||
mp_arg_validate_int_min(args[ARG_length].u_int, 1, MP_QSTR_length);
|
||||
// Check for address range wrap here as this can break port-specific code due to size_t overflow.
|
||||
|
|
Loading…
Reference in New Issue