Skip to content

Commit 3abcc6a

Browse files
committed
Add memorymap support for the nRF processors.
This gives very permissive access to the internals of the microprocessor. It needs the user to be **very** careful that they do not break things
1 parent e4c6d76 commit 3abcc6a

File tree

4 files changed

+178
-0
lines changed

4 files changed

+178
-0
lines changed
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2020 microDev
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#include <string.h>
28+
#include "nrf.h"
29+
30+
#include "shared-bindings/memorymap/AddressRange.h"
31+
32+
#include "py/runtime.h"
33+
34+
35+
#ifdef NRF51_SERIES
36+
size_t allow_ranges[][2] = {
37+
// FLASH
38+
{0x00000000, 0x00040000},
39+
// FICR & UICR ranges
40+
{0x10000000, 0x10002000},
41+
// RAM
42+
{0x20000000, 0x20010000},
43+
// PERIPHERALS
44+
{0x40000000, 0x60000000}
45+
};
46+
#elif defined NRF52_SERIES
47+
size_t allow_ranges[][2] = {
48+
// FLASH
49+
{0x00000000, 0x00100000},
50+
// FICR & UICR ranges
51+
{0x10000000, 0x10002000},
52+
// RAM
53+
{0x20000000, 0x20040000},
54+
// PERIPHERALS
55+
{0x40000000, 0x60000000}
56+
};
57+
#elif defined NRF53_SERIES
58+
size_t allow_ranges[][2] = {
59+
// FLASH
60+
{0x00000000, 0x00100000},
61+
// FICR & UICR ranges
62+
{0x00FF0000, 0x01000000},
63+
// RAM
64+
{0x20000000, 0x20080000},
65+
// PERIPHERALS
66+
{0x40000000, 0x60000000},
67+
{0xE0000000, 0xE0100000}
68+
};
69+
#else
70+
#error "Unsupported nRF variant"
71+
#endif
72+
73+
void common_hal_memorymap_addressrange_construct(memorymap_addressrange_obj_t *self, uint8_t *start_address, size_t length) {
74+
bool allowed = false;
75+
for (size_t i = 0; i < MP_ARRAY_SIZE(allow_ranges); i++) {
76+
uint8_t *allowed_start = (uint8_t *)allow_ranges[i][0];
77+
uint8_t *allowed_end = (uint8_t *)allow_ranges[i][1];
78+
if (allowed_start <= start_address &&
79+
(start_address + length) <= allowed_end) {
80+
allowed = true;
81+
break;
82+
}
83+
}
84+
85+
if (!allowed) {
86+
mp_raise_ValueError(translate("Address range not allowed"));
87+
}
88+
89+
self->start_address = start_address;
90+
self->len = length;
91+
}
92+
93+
uint32_t common_hal_memorymap_addressrange_get_length(const memorymap_addressrange_obj_t *self) {
94+
return self->len;
95+
}
96+
97+
98+
bool common_hal_memorymap_addressrange_set_bytes(const memorymap_addressrange_obj_t *self,
99+
uint32_t start_index, uint8_t *values, uint32_t len) {
100+
uint8_t *address = self->start_address + start_index;
101+
#pragma GCC diagnostic push
102+
#pragma GCC diagnostic ignored "-Wcast-align"
103+
if (len == 1) {
104+
*((uint8_t *)address) = values[0];
105+
} else if (len == sizeof(uint16_t) && (((size_t)address) % sizeof(uint16_t)) == 0) {
106+
*((uint16_t *)address) = ((uint16_t *)values)[0];
107+
} else if (len == sizeof(uint32_t) && (((size_t)address) % sizeof(uint32_t)) == 0) {
108+
*((uint32_t *)address) = ((uint32_t *)values)[0];
109+
} else if (len == sizeof(uint64_t) && (((size_t)address) % sizeof(uint64_t)) == 0) {
110+
*((uint64_t *)address) = ((uint64_t *)values)[0];
111+
} else {
112+
memcpy(address, values, len);
113+
}
114+
#pragma GCC diagnostic pop
115+
116+
return true;
117+
}
118+
119+
void common_hal_memorymap_addressrange_get_bytes(const memorymap_addressrange_obj_t *self,
120+
uint32_t start_index, uint32_t len, uint8_t *values) {
121+
uint8_t *address = self->start_address + start_index;
122+
#pragma GCC diagnostic push
123+
#pragma GCC diagnostic ignored "-Wcast-align"
124+
if (len == 1) {
125+
values[0] = *((uint8_t *)address);
126+
} else if (len == sizeof(uint16_t) && (((size_t)address) % sizeof(uint16_t)) == 0) {
127+
((uint16_t *)values)[0] = *((uint16_t *)address);
128+
} else if (len == sizeof(uint32_t) && (((size_t)address) % sizeof(uint32_t)) == 0) {
129+
((uint32_t *)values)[0] = *((uint32_t *)address);
130+
} else if (len == sizeof(uint64_t) && (((size_t)address) % sizeof(uint64_t)) == 0) {
131+
((uint64_t *)values)[0] = *((uint64_t *)address);
132+
} else {
133+
memcpy(values, address, len);
134+
}
135+
#pragma GCC diagnostic pop
136+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2020 microDev
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_MEMORYMAP_ADDRESSRANGE_H
28+
#define MICROPY_INCLUDED_NRF_COMMON_HAL_MEMORYMAP_ADDRESSRANGE_H
29+
30+
#include "py/obj.h"
31+
32+
typedef struct {
33+
mp_obj_base_t base;
34+
uint8_t *start_address;
35+
size_t len;
36+
} memorymap_addressrange_obj_t;
37+
38+
#endif // MICROPY_INCLUDED_ESPRESSIF_COMMON_HAL_MEMORYMAP_ADDRESSRANGE_H
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
// No memorymap module functions.

ports/nrf/mpconfigport.mk

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ CIRCUITPY_BLE_FILE_SERVICE ?= 1
4646
CIRCUITPY_SERIAL_BLE ?= 1
4747

4848
CIRCUITPY_COMPUTED_GOTO_SAVE_SPACE ?= 1
49+
CIRCUITPY_MEMORYMAP ?= 1
50+
4951

5052
# nRF52840-specific
5153

@@ -69,6 +71,7 @@ SOFTDEV_VERSION ?= 6.1.0
6971
BOOT_SETTING_ADDR = 0xFF000
7072
NRF_DEFINES += -DNRF52840_XXAA -DNRF52840
7173

74+
7275
# CircuitPython doesn't yet support NFC so force the NFC antenna pins to be GPIO.
7376
# See https://github.com/adafruit/circuitpython/issues/1300
7477
# Defined here because system_nrf52840.c doesn't #include any of our own include files.

0 commit comments

Comments
 (0)