Skip to content

Commit 1e17831

Browse files
author
Bob Abeles
committed
review update, add RP2040 example
1 parent 1648a3d commit 1e17831

File tree

8 files changed

+47
-27
lines changed

8 files changed

+47
-27
lines changed

locale/circuitpython.pot

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2140,6 +2140,10 @@ msgstr ""
21402140
msgid "Unable to access unaliged IO register"
21412141
msgstr ""
21422142

2143+
#: ports/raspberrypi/common-hal/memorymap/AddressRange.c
2144+
msgid "Unable to access unaligned IO register"
2145+
msgstr ""
2146+
21432147
#: ports/atmel-samd/common-hal/audiobusio/I2SOut.c
21442148
#: ports/atmel-samd/common-hal/audioio/AudioOut.c
21452149
#: ports/raspberrypi/common-hal/audiobusio/I2SOut.c
@@ -4048,6 +4052,10 @@ msgstr ""
40484052
msgid "source_bitmap must have value_count of 8"
40494053
msgstr ""
40504054

4055+
#: shared-bindings/memorymap/AddressRange.c
4056+
msgid "start must be an int"
4057+
msgstr ""
4058+
40514059
#: py/objstr.c
40524060
msgid "start/end indices"
40534061
msgstr ""

ports/raspberrypi/common-hal/memorymap/AddressRange.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ void common_hal_memorymap_addressrange_set_bytes(const memorymap_addressrange_ob
9090
case IO:
9191
if ((size_t)dest_addr & 0x03 || len & 0x03) {
9292
// Unaligned access or unaligned length not supported by RP2 for IO registers
93-
mp_raise_RuntimeError(translate("Unable to access unaliged IO register"));
93+
mp_raise_RuntimeError(translate("Unable to access unaligned IO register"));
9494
} else {
9595
// Aligned access and length, use 32-bit writes
9696
uint32_t *dest_addr32 = (uint32_t *)dest_addr;

py/argcheck.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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
115115
out_vals[i].u_bool = mp_obj_is_true(given_arg);
116116
} else if ((allowed[i].flags & MP_ARG_KIND_MASK) == MP_ARG_INT) {
117117
out_vals[i].u_int = mp_obj_get_int(given_arg);
118-
} else if ((allowed[i].flags & MP_ARG_KIND_MASK) == MP_ARG_UINT) {
119-
out_vals[i].u_uint = mp_obj_get_uint(given_arg);
120118
} else {
121119
assert((allowed[i].flags & MP_ARG_KIND_MASK) == MP_ARG_OBJ);
122120
out_vals[i].u_obj = given_arg;

py/obj.c

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -420,21 +420,6 @@ bool mp_obj_get_int_maybe(mp_const_obj_t arg, mp_int_t *value) {
420420
return true;
421421
}
422422

423-
mp_uint_t mp_obj_get_uint(mp_const_obj_t arg) {
424-
if (arg == mp_const_false) {
425-
return 0;
426-
} else if (arg == mp_const_true) {
427-
return 1;
428-
} else if (mp_obj_is_small_int(arg)) {
429-
return MP_OBJ_SMALL_INT_VALUE(arg);
430-
} else if (mp_obj_is_type(arg, &mp_type_int)) {
431-
return mp_obj_int_get_uint_checked(arg);
432-
} else {
433-
mp_obj_t res = mp_unary_op(MP_UNARY_OP_INT, (mp_obj_t)arg);
434-
return mp_obj_int_get_uint_checked(res);
435-
}
436-
}
437-
438423
#if MICROPY_PY_BUILTINS_FLOAT
439424
bool mp_obj_get_float_maybe(mp_obj_t arg, mp_float_t *value) {
440425
mp_float_t val;

py/obj.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -939,7 +939,6 @@ static MP_INLINE bool mp_obj_is_integer(mp_const_obj_t o) {
939939
mp_int_t mp_obj_get_int(mp_const_obj_t arg);
940940
mp_int_t mp_obj_get_int_truncated(mp_const_obj_t arg);
941941
bool mp_obj_get_int_maybe(mp_const_obj_t arg, mp_int_t *value);
942-
mp_uint_t mp_obj_get_uint(mp_const_obj_t arg);
943942
#if MICROPY_PY_BUILTINS_FLOAT
944943
mp_float_t mp_obj_get_float(mp_obj_t self_in);
945944
bool mp_obj_get_float_maybe(mp_obj_t arg, mp_float_t *value);

py/objint.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -438,10 +438,6 @@ mp_int_t mp_obj_int_get_checked(mp_const_obj_t self_in) {
438438
return MP_OBJ_SMALL_INT_VALUE(self_in);
439439
}
440440

441-
mp_uint_t mp_obj_int_get_uint_checked(mp_const_obj_t self_in) {
442-
return MP_OBJ_SMALL_INT_VALUE(self_in);
443-
}
444-
445441

446442
#endif // MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_NONE
447443

py/runtime.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ typedef enum {
4545
MP_ARG_BOOL = 0x001,
4646
MP_ARG_INT = 0x002,
4747
MP_ARG_OBJ = 0x003,
48-
MP_ARG_UINT = 0x004,
4948
MP_ARG_KIND_MASK = 0x0ff,
5049
MP_ARG_REQUIRED = 0x100,
5150
MP_ARG_KW_ONLY = 0x200,

shared-bindings/memorymap/AddressRange.c

Lines changed: 38 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,23 +47,58 @@
4747
//| import memorymap
4848
//| rtc_slow_mem = memorymap.AddressRange(start=0x50000000, length=0x2000)
4949
//| rtc_slow_mem[0:3] = b"\xcc\x10\x00"
50+
//|
51+
//| Example I/O register usage on RP2040::
52+
//|
53+
//| import binascii
54+
//| import board
55+
//| import digitalio
56+
//| import memorymap
57+
//|
58+
//| def rp2040_set_pad_drive(p, d):
59+
//| pads_bank0 = memorymap.AddressRange(start=0x4001C000, length=0x4000)
60+
//| pad_ctrl = int.from_bytes(pads_bank0[p*4+4:p*4+8], "little")
61+
//| # Pad control register is updated using an MP-safe atomic XOR
62+
//| pad_ctrl ^= (d << 4)
63+
//| pad_ctrl &= 0x00000030
64+
//| pads_bank0[p*4+0x3004:p*4+0x3008] = pad_ctrl.to_bytes(4, "little")
65+
//|
66+
//| def rp2040_get_pad_drive(p):
67+
//| pads_bank0 = memorymap.AddressRange(start=0x4001C000, length=0x4000)
68+
//| pad_ctrl = int.from_bytes(pads_bank0[p*4+4:p*4+8], "little")
69+
//| return (pad_ctrl >> 4) & 0x3
70+
//|
71+
//| # set GPIO16 pad drive strength to 12 mA
72+
//| rp2040_set_pad_drive(16, 3)
73+
//|
74+
//| # print GPIO16 pad drive strength
75+
//| print(rp2040_get_pad_drive(16))
5076
//| """
5177

5278
//| def __init__(self, *, start, length) -> None:
5379
//| """Constructs an address range starting at ``start`` and ending at
54-
//| ``start + length - 1``. An exception will be raised if any of the
80+
//| ``start + length``. An exception will be raised if any of the
5581
//| addresses are invalid or protected."""
5682
//| ...
5783
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) {
5884
enum { ARG_start, ARG_length };
5985
static const mp_arg_t allowed_args[] = {
60-
{ MP_QSTR_start, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_UINT },
86+
{ MP_QSTR_start, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_OBJ },
6187
{ MP_QSTR_length, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT },
6288
};
6389
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
6490
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
6591

66-
size_t start = args[ARG_start].u_uint;
92+
// Argument start is a pointer into the address map, so we validate it here because a
93+
// signed int argument will overflow if it is in the upper half of the map.
94+
size_t start;
95+
if (mp_obj_is_small_int(args[ARG_start].u_obj)) {
96+
start = MP_OBJ_SMALL_INT_VALUE(args[ARG_start].u_obj);
97+
} else if (mp_obj_is_type(args[ARG_start].u_obj, &mp_type_int)) {
98+
start = mp_obj_int_get_uint_checked(args[ARG_start].u_obj);
99+
} else {
100+
mp_raise_TypeError(translate("start must be an int"));
101+
}
67102
size_t length =
68103
mp_arg_validate_int_min(args[ARG_length].u_int, 1, MP_QSTR_length);
69104
// Check for address range wrap here as this can break port-specific code due to size_t overflow.

0 commit comments

Comments
 (0)