Skip to content

Commit e528d8d

Browse files
authored
Merge pull request #5002 from tannewt/microbitv2
Create first BLE-only board, Micro:Bit v2
2 parents 0bb21c7 + 4d3a355 commit e528d8d

36 files changed

+419
-570
lines changed

.github/workflows/build.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,7 @@ jobs:
303303
- "metro_m4_express"
304304
- "metro_m7_1011"
305305
- "metro_nrf52840_express"
306+
- "microbit_v2"
306307
- "mini_sam_m4"
307308
- "monster_m4sk"
308309
- "ndgarage_ndbit6"

.github/workflows/ports_windows.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ jobs:
6060
pip install wheel
6161
# requirements_dev.txt doesn't install on windows. (with msys2 python)
6262
# instead, pick a subset for what we want to do
63-
pip install cascadetoml jinja2 typer
63+
pip install cascadetoml jinja2 typer intelhex
6464
# check that installed packages work....?
6565
which python; python --version; python -c "import cascadetoml"
6666
which python3; python3 --version; python3 -c "import cascadetoml"

README.rst

Lines changed: 37 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -14,25 +14,30 @@ CircuitPython
1414
computers called microcontrollers. Microcontrollers are the brains of many electronics including a
1515
wide variety of development boards used to build hobby projects and prototypes. CircuitPython in
1616
electronics is one of the best ways to learn to code because it connects code to reality. Simply
17-
install CircuitPython on a supported board via drag and drop and then edit a ``code.py`` file on
18-
the CIRCUITPY drive. The code will automatically reload. No software installs are needed besides a
19-
text editor (we recommend `Mu <https://codewith.mu/>`_ for beginners.)
17+
install CircuitPython on a supported USB board usually via drag and drop and then edit a ``code.py``
18+
file on the CIRCUITPY drive. The code will automatically reload. No software installs are needed
19+
besides a text editor (we recommend `Mu <https://codewith.mu/>`_ for beginners.)
2020

21-
CircuitPython features unified Python core APIs and a growing list of 150+ device libraries and
21+
Starting with CircuitPython 7.0.0, some boards may only be connectable over Bluetooth Low Energy
22+
(BLE). Those boards provide serial and file access over BLE instead of USB using open protocols.
23+
(Some boards may use both USB and BLE.) BLE access can be done from a variety of apps including
24+
`code.circuitpythonn.org <https://code.circuitpython.org>`_.
25+
26+
CircuitPython features unified Python core APIs and a growing list of 300+ device libraries and
2227
drivers that work with it. These libraries also work on single board computers with regular
2328
Python via the `Adafruit Blinka Library <https://github.com/adafruit/Adafruit_Blinka>`_.
2429

2530
CircuitPython is based on `MicroPython <https://micropython.org>`_. See
26-
`below <#differences-from-micropython>`_ for differences. CircuitPython development is sponsored by
27-
`Adafruit <https://adafruit.com>`_ and is available on their educational development boards. Please
28-
support both MicroPython and Adafruit.
31+
`below <#differences-from-micropython>`_ for differences. Most, but not all, CircuitPython
32+
development is sponsored by `Adafruit <https://adafruit.com>`_ and is available on their educational
33+
development boards. Please support both MicroPython and Adafruit.
2934

3035
Get CircuitPython
3136
------------------
3237

3338
Official binaries for all supported boards are available through
3439
`circuitpython.org/downloads <https://circuitpython.org/downloads>`_. The site includes stable, unstable and
35-
continuous builds. Full release notes and assets are available through
40+
continuous builds. Full release notes are available through
3641
`GitHub releases <https://github.com/adafruit/circuitpython/releases>`_ as well.
3742

3843
Documentation
@@ -85,7 +90,9 @@ If you'd like to use the term "CircuitPython" and Blinka for your product here i
8590
* Your product is listed on `circuitpython.org <https://circuitpython.org>`__ (source
8691
`here <https://github.com/adafruit/circuitpython-org/>`_). This is to ensure that a user of your
8792
product can always download the latest version of CircuitPython from the standard place.
88-
* Your product has a user accessible USB plug which appears as a CIRCUITPY drive when plugged in.
93+
* Your product has a user accessible USB plug which appears as a CIRCUITPY drive when plugged in
94+
AND/OR provides file and serial access over Bluetooth Low Energy. Boards that do not support USB
95+
should be clearly marked as BLE-only CircuitPython.
8996

9097
If you choose not to meet these requirements, then we ask you call your version of CircuitPython
9198
something else (for example, SuperDuperPython) and not use the Blinka logo. You can say it is
@@ -98,10 +105,11 @@ Differences from `MicroPython <https://github.com/micropython/micropython>`__
98105

99106
CircuitPython:
100107

101-
- Supports native USB on all boards, allowing file editing without special tools.
108+
- Supports native USB on most boards and BLE otherwise, allowing file editing without special tools.
102109
- Floats (aka decimals) are enabled for all builds.
103110
- Error messages are translated into 10+ languages.
104-
- Does not support concurrency within Python (including interrupts and threading). Some concurrency
111+
- Concurrenncy within Python is not well supported. Interrupts and threading are disabled.
112+
async/await keywords are available on some boards for cooperative multitasking. Some concurrency
105113
is achieved with native modules for tasks that require it such as audio file playback.
106114

107115
Behavior
@@ -110,23 +118,23 @@ Behavior
110118
- The order that files are run and the state that is shared between
111119
them. CircuitPython's goal is to clarify the role of each file and
112120
make each file independent from each other.
113-
- ``boot.py`` (or ``settings.py``) runs only once on start up before
114-
USB is initialized. This lays the ground work for configuring USB at
115-
startup rather than it being fixed. Since serial is not available,
116-
output is written to ``boot_out.txt``.
117-
- ``code.py`` (or ``main.py``) is run after every reload until it
118-
finishes or is interrupted. After it is done running, the vm and
119-
hardware is reinitialized. **This means you cannot read state from**
120-
``code.py`` **in the REPL anymore, as the REPL is a fresh vm.** CircuitPython's goal for this
121-
change includes reducing confusion about pins and memory being used.
122-
- After the main code is finished the REPL can be entered by pressing any key.
123-
- Autoreload state will be maintained across reload.
124-
- Adds a safe mode that does not run user code after a hard crash or
125-
brown out. The hope is that this will make it easier to fix code that
126-
causes nasty crashes by making it available through mass storage
127-
after the crash. A reset (the button) is needed after it's fixed to
128-
get back into normal mode.
129-
- RGB status LED indicating CircuitPython state, and errors through a sequence of colored flashes.
121+
122+
- ``boot.py`` (or ``settings.py``) runs only once on start up before
123+
USB is initialized. This lays the ground work for configuring USB at
124+
startup rather than it being fixed. Since serial is not available,
125+
output is written to ``boot_out.txt``.
126+
- ``code.py`` (or ``main.py``) is run after every reload until it
127+
finishes or is interrupted. After it is done running, the vm and
128+
hardware is reinitialized. **This means you cannot read state from**
129+
``code.py`` **in the REPL anymore, as the REPL is a fresh vm.** CircuitPython's goal for this
130+
change includes reducing confusion about pins and memory being used.
131+
- After the main code is finished the REPL can be entered by pressing any key.
132+
- Autoreload state will be maintained across reload.
133+
134+
- Adds a safe mode that does not run user code after a hard crash or brown out. This makes it
135+
possible to fix code that causes nasty crashes by making it available through mass storage after
136+
the crash. A reset (the button) is needed after it's fixed to get back into normal mode.
137+
- RGB status LED indicating CircuitPython state.
130138
- Re-runs ``code.py`` or other main file after file system writes over USB mass storage. (Disable with
131139
``supervisor.disable_autoreload()``)
132140
- Autoreload is disabled while the REPL is active.
@@ -140,7 +148,7 @@ API
140148

141149
- Unified hardware APIs. Documented on
142150
`ReadTheDocs <https://circuitpython.readthedocs.io/en/latest/shared-bindings/index.html>`_.
143-
- API docs are rST within the C files in ``shared-bindings``.
151+
- API docs are Python stubs within the C files in ``shared-bindings``.
144152
- No ``machine`` API.
145153

146154
Modules

main.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,14 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
348348
#endif
349349
}
350350

351+
// Print done before resetting everything so that we get the message over
352+
// BLE before it is reset and we have a delay before reconnect.
353+
if (reload_requested && result.return_code == PYEXEC_EXCEPTION) {
354+
serial_write_compressed(translate("\nCode stopped by auto-reload.\n"));
355+
} else {
356+
serial_write_compressed(translate("\nCode done running.\n"));
357+
}
358+
351359
// Finished executing python code. Cleanup includes a board reset.
352360
cleanup_after_vm(heap);
353361

@@ -361,15 +369,13 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
361369

362370
if (reload_requested) {
363371
next_code_stickiness_situation |= SUPERVISOR_NEXT_CODE_OPT_STICKY_ON_RELOAD;
364-
}
365-
else if (result.return_code == 0) {
372+
} else if (result.return_code == 0) {
366373
next_code_stickiness_situation |= SUPERVISOR_NEXT_CODE_OPT_STICKY_ON_SUCCESS;
367374
if (next_code_options & SUPERVISOR_NEXT_CODE_OPT_RELOAD_ON_SUCCESS) {
368375
skip_repl = true;
369376
skip_wait = true;
370377
}
371-
}
372-
else {
378+
} else {
373379
next_code_stickiness_situation |= SUPERVISOR_NEXT_CODE_OPT_STICKY_ON_ERROR;
374380
// Deep sleep cannot be skipped
375381
// TODO: settings in deep sleep should persist, using a new sleep memory API
@@ -383,12 +389,6 @@ STATIC bool run_code_py(safe_mode_t safe_mode) {
383389
skip_repl = reload_requested;
384390
skip_wait = true;
385391
}
386-
387-
if (reload_requested && result.return_code == PYEXEC_EXCEPTION) {
388-
serial_write_compressed(translate("\nCode stopped by auto-reload.\n"));
389-
} else {
390-
serial_write_compressed(translate("\nCode done running.\n"));
391-
}
392392
}
393393

394394
// Program has finished running.

ports/nrf/Makefile

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,6 @@ endif
9696

9797
ifeq ($(NRF_DEBUG_PRINT), 1)
9898
CFLAGS += -DNRF_DEBUG_PRINT=1
99-
SRC_SUPERVISOR += supervisor/debug_uart.c
10099
endif
101100

102101
# option to override compiler optimization level, set in boards/$(BOARD)/mpconfigboard.mk
@@ -248,7 +247,7 @@ SRC_QSTR += $(SRC_C) $(SRC_SUPERVISOR) $(SRC_MOD) $(SRC_COMMON_HAL_EXPANDED) $(S
248247
SRC_QSTR_PREPROCESSOR +=
249248

250249

251-
all: $(BUILD)/firmware.bin $(BUILD)/firmware.uf2
250+
all: $(BUILD)/firmware.bin $(BUILD)/firmware.uf2 $(BUILD)/firmware.combined.hex
252251

253252
$(BUILD)/firmware.elf: $(OBJ) $(GENERATED_LD_FILE)
254253
$(STEPECHO) "LINK $@"
@@ -266,6 +265,10 @@ $(BUILD)/firmware.hex: $(BUILD)/firmware.elf
266265
$(Q)$(OBJCOPY) -O ihex $^ $@
267266
# $(Q)$(OBJCOPY) -O ihex -j .vectors -j .text -j .data $^ $@
268267

268+
$(BUILD)/firmware.combined.hex: $(BUILD)/firmware.hex $(SOFTDEV_HEX)
269+
$(STEPECHO) "Create $@"
270+
$(Q)hexmerge.py -o $@ $^
271+
269272
$(BUILD)/firmware.uf2: $(BUILD)/firmware.hex
270273
$(ECHO) "Create $@"
271274
$(PYTHON3) $(TOP)/tools/uf2/utils/uf2conv.py -f 0xADA52840 -c -o "$(BUILD)/firmware.uf2" $^

ports/nrf/bluetooth/ble_drv.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838
#include "py/misc.h"
3939
#include "py/mpstate.h"
4040

41+
#if CIRCUITPY_SERIAL_BLE && CIRCUITPY_VERBOSE_BLE
42+
#include "supervisor/shared/bluetooth/serial.h"
43+
#endif
44+
4145
nrf_nvic_state_t nrf_nvic_state = { 0 };
4246

4347
// Flag indicating progress of internal flash operation.
@@ -132,6 +136,9 @@ void SD_EVT_IRQHandler(void) {
132136
}
133137
}
134138

139+
#if CIRCUITPY_SERIAL_BLE && CIRCUITPY_VERBOSE_BLE
140+
ble_serial_disable();
141+
#endif
135142
while (1) {
136143
uint16_t evt_len = sizeof(m_ble_evt_buf);
137144
const uint32_t err_code = sd_ble_evt_get(m_ble_evt_buf, &evt_len);
@@ -173,4 +180,7 @@ void SD_EVT_IRQHandler(void) {
173180
}
174181
#endif
175182
}
183+
#if CIRCUITPY_SERIAL_BLE && CIRCUITPY_VERBOSE_BLE
184+
ble_serial_enable();
185+
#endif
176186
}

supervisor/stub/serial.c renamed to ports/nrf/boards/microbit_v2/board.c

Lines changed: 5 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* The MIT License (MIT)
55
*
6-
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
6+
* Copyright (c) 2021 Scott Shawcroft for Adafruit Industries
77
*
88
* Permission is hereby granted, free of charge, to any person obtaining a copy
99
* of this software and associated documentation files (the "Software"), to deal
@@ -24,36 +24,15 @@
2424
* THE SOFTWARE.
2525
*/
2626

27-
#include "supervisor/serial.h"
28-
#include "supervisor/workflow.h"
29-
30-
void serial_early_init(void) {
31-
32-
}
33-
34-
void serial_init(void) {
27+
#include "supervisor/board.h"
3528

29+
void board_init(void) {
3630
}
3731

38-
bool serial_connected(void) {
32+
bool board_requests_safe_mode(void) {
3933
return false;
4034
}
4135

42-
char serial_read(void) {
43-
return 0;
44-
}
36+
void reset_board(void) {
4537

46-
bool serial_bytes_available(void) {
47-
return false;
48-
}
49-
50-
void serial_write(const char *text) {
51-
(void)text;
52-
}
53-
54-
void supervisor_workflow_reset(void) {
55-
}
56-
57-
bool supervisor_workflow_active(void) {
58-
return false;
5938
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2016 Glenn Ruben Bakke
7+
* Copyright (c) 2018 Dan Halbert for Adafruit Industries
8+
*
9+
* Permission is hereby granted, free of charge, to any person obtaining a copy
10+
* of this software and associated documentation files (the "Software"), to deal
11+
* in the Software without restriction, including without limitation the rights
12+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13+
* copies of the Software, and to permit persons to whom the Software is
14+
* furnished to do so, subject to the following conditions:
15+
*
16+
* The above copyright notice and this permission notice shall be included in
17+
* all copies or substantial portions of the Software.
18+
*
19+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25+
* THE SOFTWARE.
26+
*/
27+
28+
#include "nrfx/hal/nrf_gpio.h"
29+
30+
#define MICROPY_HW_BOARD_NAME "micro:bit v2"
31+
#define MICROPY_HW_MCU_NAME "nRF52833"
32+
33+
#define CIRCUITPY_INTERNAL_NVM_SIZE 0
34+
#define CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE (60 * 1024)
35+
36+
#define CIRCUITPY_BLE_CONFIG_SIZE (12 * 1024)
37+
38+
// The RUN_MIC pin
39+
#define MICROPY_HW_LED_STATUS (&pin_P0_20)
40+
41+
// Reduce nRF SoftRadio memory usage
42+
#define BLEIO_VS_UUID_COUNT 10
43+
#define BLEIO_HVN_TX_QUEUE_SIZE 2
44+
#define BLEIO_CENTRAL_ROLE_COUNT 2
45+
#define BLEIO_PERIPH_ROLE_COUNT 2
46+
#define BLEIO_TOTAL_CONNECTION_COUNT 2
47+
#define BLEIO_ATTR_TAB_SIZE (BLE_GATTS_ATTR_TAB_SIZE_DEFAULT * 2)
48+
49+
#define SOFTDEVICE_RAM_SIZE (32 * 1024)
50+
51+
#define BOOTLOADER_SIZE (0)
52+
#define BOOTLOADER_SETTING_SIZE (0)
53+
54+
#define BOARD_HAS_32KHZ_XTAL (0)
55+
#define DEBUG_UART_TX (&pin_P0_06)
56+
#define DEBUG_UART_RX (&pin_P1_08)
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
CIRCUITPY_CREATOR_ID = 0x239A
2+
CIRCUITPY_CREATION_ID = 0x80D8
3+
4+
MCU_CHIP = nrf52833
5+
6+
INTERNAL_FLASH_FILESYSTEM = 1
7+
8+
CIRCUITPY_ALARM = 0
9+
CIRCUITPY_AUDIOMP3 = 0
10+
CIRCUITPY_BINASCII = 0
11+
CIRCUITPY_BITBANGIO = 0
12+
CIRCUITPY_BUILTINS_POW3=0
13+
CIRCUITPY_BUSDEVICE = 0
14+
CIRCUITPY_COUNTIO = 0
15+
CIRCUITPY_DISPLAYIO = 0
16+
CIRCUITPY_FRAMEBUFFERIO = 0
17+
CIRCUITPY_FREQUENCYIO = 0
18+
CIRCUITPY_I2CPERIPHERAL = 0
19+
CIRCUITPY_JSON = 0
20+
CIRCUITPY_KEYPAD = 0
21+
CIRCUITPY_MSGPACK = 0
22+
CIRCUITPY_NEOPIXEL_WRITE = 0
23+
CIRCUITPY_NVM = 0
24+
CIRCUITPY_PIXELBUF = 0
25+
CIRCUITPY_RE = 0
26+
CIRCUITPY_RGBMATRIX = 0
27+
CIRCUITPY_SDCARDIO = 0
28+
CIRCUITPY_ULAB = 0
29+
CIRCUITPY_USB = 0
30+
31+
MICROPY_PY_ASYNC_AWAIT = 0
32+
33+
# Override optimization to keep binary small
34+
OPTIMIZATION_FLAGS = -Os
35+
SUPEROPT_VM = 0
36+
SUPEROPT_GC = 0

0 commit comments

Comments
 (0)