diff --git a/ports/nrf/Makefile b/ports/nrf/Makefile index ae2f895030f7e..563578d1030bf 100644 --- a/ports/nrf/Makefile +++ b/ports/nrf/Makefile @@ -6,7 +6,8 @@ $(error Invalid BOARD specified) endif # If SoftDevice is selected, try to use that one. -SD ?= +# Default to SD132 (exact version can be set with SOFTDEV_VERSION) +SD ?= s132 SD_LOWER = $(shell echo $(SD) | tr '[:upper:]' '[:lower:]') # TODO: Verify that it is a valid target. diff --git a/ports/nrf/boards/feather52/README.md b/ports/nrf/boards/feather52/README.md index d5e00262256a5..c98f54614ff61 100644 --- a/ports/nrf/boards/feather52/README.md +++ b/ports/nrf/boards/feather52/README.md @@ -55,6 +55,26 @@ To build a CircuitPython binary with default settings for the $ make BOARD=feather52 V=1 ``` +#### REPL over BLE UART (AKA 'NUS') + +To build a CircuitPython binary that uses the Nordic UART Service (AKA 'NUS' or +'BLEUART'), modify `/ports/nrf/bluetooth_conf.h` to have the following macro +set to `1` in the `#elif (BLUETOOTH_SD == 132)` section: + +``` +#define MICROPY_PY_BLE_NUS (1) +``` + +... then build as normal, via: + +``` +$ make BOARD=feather52 V=1 +``` + +You can then connect over BLE UART using an application like Bluefruit LE +Connect, available for Android, iOS and OS X, or any other application that +supports the NUS service and allows you to send the corrent EOL sequence. + ## Flashing binaries with `nrfutil` ### 1. **Update bootloader** to single-bank version @@ -91,7 +111,7 @@ $ make BOARD=feather52 SERIAL=/dev/tty.SLAB_USBtoUART SOFTDEV_VERSION=5.0.0 boot The following command will package and flash the CircuitPython binary using the appropriate bootloader mentionned above. -This command assumes you have already build a valid circuitpython +This command assumes you have already built a valid circuitpython image, as described earlier in this readme. > The name of the serial port target will vary, depending on your OS. @@ -100,11 +120,12 @@ image, as described earlier in this readme. $ make BOARD=feather52 SERIAL=/dev/tty.SLAB_USBtoUART dfu-gen dfu-flash ``` -If you built your CircuitPython binary with **BLE** support you will need to -add the `SD=s132` flag as shown below: +By default, CircuitPython will build with **BLE** support enabled using +`SD=s132` and the `SOFTDEV_VERSION=2.0.1`. If you wish to specify a different +SD family or version you can enter the optional fields as shown below: ``` -$ make BOARD=feather52 SERIAL=/dev/tty.SLAB_USBtoUART SD=s132 dfu-gen dfu-flash +$ make BOARD=feather52 SERIAL=/dev/tty.SLAB_USBtoUART SD=s132 SOFTDEV_VERSION=5.0.0 dfu-gen dfu-flash ``` ## Working with CircuitPython diff --git a/ports/nrf/boards/feather52/custom_nrf52832_dfu_app_2.0.1.ld b/ports/nrf/boards/feather52/custom_nrf52832_dfu_app_2.0.1.ld index 183822f92a81c..a1c128e377e2d 100644 --- a/ports/nrf/boards/feather52/custom_nrf52832_dfu_app_2.0.1.ld +++ b/ports/nrf/boards/feather52/custom_nrf52832_dfu_app_2.0.1.ld @@ -25,7 +25,7 @@ MEMORY FLASH_ISR (rx) : ORIGIN = 0x0001c000, LENGTH = 0x001000 /* sector 0, 4 KiB */ FLASH_TEXT (rx) : ORIGIN = 0x0001d000, LENGTH = 0x03C000 /* APP - ISR, 240 KiB */ FLASH_FATFS (r) : ORIGIN = 0x00059000, LENGTH = 0x019000 /* File system 100KB KB */ - RAM (xrw) : ORIGIN = 0x200039c0, LENGTH = 0x0c640 /* 49.5 KiB, give 8KiB headroom for softdevice */ + RAM (xrw) : ORIGIN = 0x20003000, LENGTH = 0x0D000 /* 52 KiB, give 8KiB headroom for softdevice */ } /* produce a link error if there is not this amount of RAM for these sections */ diff --git a/ports/nrf/boards/feather52/examples/ble_scan.py b/ports/nrf/boards/feather52/examples/ble_scan.py new file mode 100644 index 0000000000000..9cacbe6f42872 --- /dev/null +++ b/ports/nrf/boards/feather52/examples/ble_scan.py @@ -0,0 +1,26 @@ +from ubluepy import Scanner, constants + +def display_scan_results(scan_entries): + for e in scan_entries: + print("ADDR: ", e.addr()) + print("TYPE: ", e.addr_type()) + print("RSSI: ", e.rssi()) + + # Parse the contents of the advertising packet + scan = e.getScanData() + if scan: + for s in scan: + # Convert byte array to hex format string + hex = ' '.join('0x%02X' % b for b in s[2]) + # Display enum value and hex string together + print('\t{}: {}'.format(s[1], hex)) + + # Line break between record sets + print("") + +# Scan 1s for advertising devices in range +s = Scanner() +scan_res = s.scan(1000) + +# Display the scan results +display_scan_results(scan_res) diff --git a/ports/nrf/drivers/bluetooth/ble_uart.c b/ports/nrf/drivers/bluetooth/ble_uart.c index cc829750cd7cb..069d71589ba53 100644 --- a/ports/nrf/drivers/bluetooth/ble_uart.c +++ b/ports/nrf/drivers/bluetooth/ble_uart.c @@ -30,6 +30,7 @@ #include "ble_uart.h" #include "ringbuffer.h" #include "hal/hal_time.h" +#include "lib/utils/interrupt_char.h" #if MICROPY_PY_BLE_NUS @@ -105,6 +106,10 @@ int mp_hal_stdin_rx_chr(void) { return (int)byte; } +bool mp_hal_stdin_any(void) { + return !isBufferEmpty(mp_rx_ring_buffer); +} + void mp_hal_stdout_tx_strn(const char *str, size_t len) { uint8_t *buf = (uint8_t *)str; size_t send_len; @@ -141,6 +146,7 @@ STATIC void gap_event_handler(mp_obj_t self_in, uint16_t event_id, uint16_t conn } else if (event_id == 17) { // disconnect event self->conn_handle = 0xFFFF; // invalid connection handle m_connected = false; + ble_uart_advertise(); } } @@ -153,7 +159,14 @@ STATIC void gatts_event_handler(mp_obj_t self_in, uint16_t event_id, uint16_t at m_cccd_enabled = true; } else if (ble_uart_char_rx.handle == attr_handle) { for (uint16_t i = 0; i < length; i++) { - bufferWrite(mp_rx_ring_buffer, data[i]); + #if MICROPY_KBD_EXCEPTION + if (data[i] == mp_interrupt_char) { + mp_keyboard_interrupt(); + } else + #endif + { + bufferWrite(mp_rx_ring_buffer, data[i]); + } } } } diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h index 7e23486adbc0c..6530bb28a23b0 100644 --- a/ports/nrf/mpconfigport.h +++ b/ports/nrf/mpconfigport.h @@ -273,8 +273,8 @@ extern const struct _mp_obj_module_t ble_module; { MP_ROM_QSTR (MP_QSTR_utime ), MP_ROM_PTR(&mp_module_utime) }, \ MUSIC_MODULE \ RANDOM_MODULE \ - /*BLE_MODULE \ - UBLUEPY_MODULE \*/ + BLE_MODULE \ + UBLUEPY_MODULE \ #define MICROPY_PORT_BUILTIN_MODULE_WEAK_LINKS \ diff --git a/ports/nrf/supervisor/serial.c b/ports/nrf/supervisor/serial.c index 465c8394c5f0c..51e61bce7cc1d 100644 --- a/ports/nrf/supervisor/serial.c +++ b/ports/nrf/supervisor/serial.c @@ -32,15 +32,18 @@ #include "pins.h" #include "hal_uart.h" +#if (MICROPY_PY_BLE_NUS) +#include "ble_uart.h" +#endif + void serial_init(void) { -// uart_init0(); -// -// mp_obj_t args[2] = { -// MP_OBJ_NEW_SMALL_INT(0), -// MP_OBJ_NEW_SMALL_INT(115200), -// }; -// MP_STATE_PORT(pyb_stdio_uart) = machine_hard_uart_type.make_new((mp_obj_t)&machine_hard_uart_type, MP_ARRAY_SIZE(args), 0, args); +#if MICROPY_PY_BLE_NUS + ble_uart_init0(); + while (!ble_uart_enabled()) { + ; + } +#else hal_uart_init_t param = { .id = 0, @@ -56,6 +59,7 @@ void serial_init(void) { }; hal_uart_init( UART_BASE(0), ¶m); +#endif } diff --git a/tools/build_adafruit_bins.sh b/tools/build_adafruit_bins.sh index 4c5be2c85a131..cf4b48bd22dc9 100755 --- a/tools/build_adafruit_bins.sh +++ b/tools/build_adafruit_bins.sh @@ -47,7 +47,7 @@ fi for board in $boards; do mkdir -p bin/$board/ if [ $board == "feather52" ]; then - cp ports/nrf/build-$board/firmware.bin bin/$board/adafruit-circuitpython-$board-$version.bin + cp ports/nrf/build-$board-s132/firmware.bin bin/$board/adafruit-circuitpython-$board-$version.bin (( exit_status = exit_status || $? )) else cp ports/atmel-samd/build-$board/firmware.bin bin/$board/adafruit-circuitpython-$board-$version.bin