diff --git a/ports/nrf/boards/SUPERMINI_NRF52840/board.json b/ports/nrf/boards/SUPERMINI_NRF52840/board.json new file mode 100644 index 0000000000000..2cee9d477d790 --- /dev/null +++ b/ports/nrf/boards/SUPERMINI_NRF52840/board.json @@ -0,0 +1,17 @@ +{ + "deploy": [ + "deploy.md" + ], + "docs": "", + "features": [ + "BLE", + "Battery Charging", + "USB-C" + ], + "images": [], + "mcu": "nrf52", + "product": "SuperMini / Nice!Nano nRF52840", + "thumbnail": "", + "url": "https://wiki.icbbuy.com/doku.php?id=developmentboard:nrf52840", + "vendor": "" +} diff --git a/ports/nrf/boards/SUPERMINI_NRF52840/bootloader.ld b/ports/nrf/boards/SUPERMINI_NRF52840/bootloader.ld new file mode 100644 index 0000000000000..0ff02f2182c29 --- /dev/null +++ b/ports/nrf/boards/SUPERMINI_NRF52840/bootloader.ld @@ -0,0 +1,4 @@ +/* GNU linker script for Adafruit nrf52840 Bootloader */ + +_bootloader_head_size = 0x1000; /* MBR */ +_bootloader_tail_size = 0xC000; /* Bootloader start address 0x000F4000 */ diff --git a/ports/nrf/boards/SUPERMINI_NRF52840/deploy.md b/ports/nrf/boards/SUPERMINI_NRF52840/deploy.md new file mode 100644 index 0000000000000..ecbbdafe8cfea --- /dev/null +++ b/ports/nrf/boards/SUPERMINI_NRF52840/deploy.md @@ -0,0 +1,31 @@ +The steps below let you create and install the firmware file. For +a .uf2 type file taken from the MicroPython downloads source only +step 4 is needed. For the .hex version of the firmware file, steps +1, 3 and 4 are required. + +1. Download and install u2fconv.py. It is available e.g. in the tools + directory of MicroPython. + +2. Create a firmware for the SuperMini/Nice!Nano nrf52840 if needed, with the command + + `make BOARD=SUPERMINI_NRF52840` + + in the directory build-SUPERMINI_NRF52840-s140. The firmware file will have the + name firmware.uf2. + +3. Create the .uf2 file if needed in the build directory with the command: + + `uf2conv.py -c -f 0xADA52840 -o firmware.uf2 firmware.hex` + + It must report the start address as 0x26000. (see https://github.com/adafruit/Adafruit_nRF52_Bootloader for details). If you omit the -o option, + the output file will have the name flash.uf2. + +4. Enable the upload mode by connecting RST to GND twice within 0.5 s or calling + machine.bootloader() and copy the file firmware.uf2 to the board drive, + which will pop up on your Mac as /Volume/NICENANO . + +In case the SuperMini bootloader is lost or overwritten, it can be found +at https://github.com/adafruit/Adafruit_nRF52_Bootloader/releases in different +formats. Using a JLINK adapter or interface, it can be uploaded as hex version. +The bootloader is as well available through the Arduino IDE. + diff --git a/ports/nrf/boards/SUPERMINI_NRF52840/machine_bitstream.c b/ports/nrf/boards/SUPERMINI_NRF52840/machine_bitstream.c new file mode 100644 index 0000000000000..6bd7a3a02a76b --- /dev/null +++ b/ports/nrf/boards/SUPERMINI_NRF52840/machine_bitstream.c @@ -0,0 +1,155 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2021 Jim Mussared + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +// This is a translation of the cycle counter implementation in ports/stm32/machine_bitstream.c. +// part of the code from robert-h w600 micropython port + +#include "py/mpconfig.h" +#include "py/mphal.h" + +#if MICROPY_PY_MACHINE_BITSTREAM + +#define mp_hal_quiet_timing_enter() MICROPY_BEGIN_ATOMIC_SECTION() +#define mp_hal_quiet_timing_exit(irq_state) MICROPY_END_ATOMIC_SECTION(irq_state) + +// NRF52840 @ 64MHz (cycle=15.625ns) +#define NS_CYCLES_PER_ITER_HIGH (4) // 6 => 4 +#define NS_CYCLES_PER_ITER_LOW (4) // 6 => 4 +#define NS_OVERHEAD_CYCLES_HIGH (16) // 12 => 16 +#define NS_OVERHEAD_CYCLES_LOW (12) // 18 => 12 + +uint32_t mp_hal_delay_ns_calc(uint32_t ns, bool high) { + uint32_t ncycles = 64 * ns / 1000; // hard coded system clock 64MHz for NRF52. the system clock cannot be change anyway + uint32_t overhead = MIN(ncycles, high ? NS_OVERHEAD_CYCLES_HIGH : NS_OVERHEAD_CYCLES_LOW); + return MAX(1, MP_ROUND_DIVIDE(ncycles - overhead, high ? NS_CYCLES_PER_ITER_HIGH : NS_CYCLES_PER_ITER_LOW)); +} + +void machine_bitstream_high_low(mp_hal_pin_obj_t p, uint32_t *timing_ns, const uint8_t *buf, size_t len) { + uint32_t pin = p->pin; + uint32_t reg; + if (pin >= 32) { + pin -= 32; + reg = NRF_P1_BASE + 0x504; + NRF_P1->DIRSET = (1 << pin); + } else { + reg = NRF_P0_BASE + 0x504; + NRF_P0->DIRSET = (1 << pin); + } + uint32_t lo_mask = ~(1 << pin); + uint32_t hi_mask = 1 << pin; + + // Convert ns to loop iterations [high_time_0, low_time_0, high_time_1, low_time_1]. + + for (size_t i = 0; i < 4; ++i) { + timing_ns[i] = mp_hal_delay_ns_calc(timing_ns[i], i % 2 == 0); + } + + uint32_t irq_state = mp_hal_quiet_timing_enter(); + + __asm volatile ( + // Force consistent register assignment. + // r6 = len + "ldr r6, %0\n" + // r4 = buf + "ldr r4, %1\n" + // r5 = timing_ms + "ldr r5, %2\n" + // r1 = GPIO reg + "ldr r1, %5\n" + // r8 GPIO reg value + "ldr r8, [r1, #0]\n" + // r9 Hi-Mask + "ldr r9, %3\n" + // r10 Lo-Mask + "ldr r10, %4\n" + + // // Must align for consistent timing. + ".align 4\n" + + // Don't increment/decrement before first iteration. + "b .outer2\n" + ".outer:\n" + // ++buf, --len + " add r4, #1\n" + " sub r6, #1\n" + + // len iterations + ".outer2:\n" + " cmp r6, #0\n" + " beq .done\n" + // r0 = *buf + " ldrb r0, [r4, #0]\n" + + // 8 bits in byte + " mov r7, #8\n" + // Reload the port value at every byte + " ldr r8, [r1, #0]\n" + " .inner:\n" + // *(TLS_REG *)reg |= hi_mask; + " orr r8, r9\n" + " str r8, [r1, #0]\n" + + // r3 = (r0 >> 4) & 8 (r0 is 8 if high bit is 1 else 0) + " mov r2, r6\n" + " lsr r3, r0, #4\n" + " mov r6, #8\n" + " and r3, r6\n" + " mov r6, r2\n" + + // r2 = timing_ns[r3] + " ldr r2, [r5, r3]\n" + " .loop1:\n sub r2, #1\n cmp r2, #0\n bne .loop1\n" + + // *(TLS_REG *)reg &= lo_mask; + " and r8, r10\n" + " str r8, [r1, #0]\n" + + // r2 = timing_ns[r3 + 4] + " add r3, #4\n" + " ldr r2, [r5, r3]\n" + " .loop2:\n sub r2, #1\n cmp r2, #0\n bne .loop2\n" + + // b >>= 1 + " lsl r0, r0, #1\n" + " sub r7, #1\n" + // continue inner loop + " cmp r7, #0\n" + " bne .inner\n" + // continue outer loop + " b .outer\n" + + ".done:\n" + : + : "m" (len), "m" (buf), "m" (timing_ns), "m" (hi_mask), "m" (lo_mask), "m" (reg) + : "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10" + ); + + mp_hal_quiet_timing_exit(irq_state); + +} + + +#endif // MICROPY_PY_MACHINE_BITSTREAM diff --git a/ports/nrf/boards/SUPERMINI_NRF52840/manifest.py b/ports/nrf/boards/SUPERMINI_NRF52840/manifest.py new file mode 100644 index 0000000000000..028e5bc986e6f --- /dev/null +++ b/ports/nrf/boards/SUPERMINI_NRF52840/manifest.py @@ -0,0 +1,4 @@ +include("$(PORT_DIR)/modules/manifest.py") + +# Utils +require("neopixel") diff --git a/ports/nrf/boards/SUPERMINI_NRF52840/mpconfigboard.h b/ports/nrf/boards/SUPERMINI_NRF52840/mpconfigboard.h new file mode 100644 index 0000000000000..c77964f183912 --- /dev/null +++ b/ports/nrf/boards/SUPERMINI_NRF52840/mpconfigboard.h @@ -0,0 +1,70 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2017 Glenn Ruben Bakke + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#define MICROPY_HW_BOARD_NAME "SuperMini / Nice!Nano / Pro Micro nRF52840" +#define MICROPY_HW_MCU_NAME "NRF52840" +#define MICROPY_PY_SYS_PLATFORM "nrf52" + +#define MICROPY_PY_MACHINE_UART (1) +#define MICROPY_PY_MACHINE_HW_PWM (1) +#define MICROPY_PY_MACHINE_HW_SPI (1) +#define MICROPY_PY_MACHINE_RTCOUNTER (1) +#define MICROPY_PY_MACHINE_I2C (1) +#define MICROPY_PY_MACHINE_ADC (1) +#define MICROPY_PY_MACHINE_TEMP (1) +#define MICROPY_PY_FRAMEBUF (1) +#define MICROPY_PY_MACHINE_BITSTREAM (1) +#define MICROPY_PY_MUSIC (1) +#define MICROPY_PY_MACHINE_SOFT_PWM (1) + +#define MICROPY_HW_ENABLE_RNG (1) + +#define MICROPY_HW_ENABLE_USBDEV (1) +#define MICROPY_HW_USB_CDC (1) + +#define MICROPY_HW_HAS_LED (1) +#define MICROPY_HW_LED_COUNT (1) +#define MICROPY_HW_LED_PULLUP (0) +#define MICROPY_HW_LED1 (15) +#define HELP_TEXT_BOARD_LED "1" + +#define MICROPY_HW_UART1_RX (8) +#define MICROPY_HW_UART1_TX (6) + +#define MICROPY_HW_SPI0_NAME "SPI0" +#define MICROPY_HW_SPI0_SCK (32 + 13) +#define MICROPY_HW_SPI0_MOSI (10) +#define MICROPY_HW_SPI0_MISO (32 + 11) + +#define MICROPY_HW_PWM0_NAME "PWM0" +#define MICROPY_HW_PWM1_NAME "PWM1" +#define MICROPY_HW_PWM2_NAME "PWM2" + +#define MICROPY_HW_MUSIC_PIN (32 + 6) + +#define MICROPY_HW_USB_VID (0x239A) +#define MICROPY_HW_USB_PID (0x8052) +#define MICROPY_HW_USB_CDC_1200BPS_TOUCH (1) diff --git a/ports/nrf/boards/SUPERMINI_NRF52840/mpconfigboard.mk b/ports/nrf/boards/SUPERMINI_NRF52840/mpconfigboard.mk new file mode 100644 index 0000000000000..9d9758c8dd7c2 --- /dev/null +++ b/ports/nrf/boards/SUPERMINI_NRF52840/mpconfigboard.mk @@ -0,0 +1,18 @@ +MCU_SERIES = m4 +MCU_VARIANT = nrf52 +MCU_SUB_VARIANT = nrf52840 +SOFTDEV_VERSION = 6.1.1 +SD=s140 +LD_FILES += $(BOARD_DIR)/bootloader.ld boards/nrf52840_1M_256k.ld + +NRF_DEFINES += -DNRF52840_XXAA + +MICROPY_VFS_LFS2 = 1 +FS_SIZE = 256k + +# DEBUG ?= 1 + +FROZEN_MANIFEST ?= $(BOARD_DIR)/manifest.py + +uf2: hex + python3 $(TOP)/tools/uf2conv.py -c -o $(BUILD)/firmware.uf2 -f 0xADA52840 $(BUILD)/firmware.hex diff --git a/ports/nrf/boards/SUPERMINI_NRF52840/pins.csv b/ports/nrf/boards/SUPERMINI_NRF52840/pins.csv new file mode 100644 index 0000000000000..001e7c2a72603 --- /dev/null +++ b/ports/nrf/boards/SUPERMINI_NRF52840/pins.csv @@ -0,0 +1,59 @@ +P0_01,P1 +P0_02,P2 +AIN0,P2 +P0_03,P3 +P0_04,P4 +AIN2,P4 +P0_05,P5 +V_BAT,P4 +P0_06,P6 +UART1_TX,P6 +P0_07,P7 +P0_08,P8 +UART1_RX,P8 +P0_09,P9 +NFC1,P9 +NFC2,P10 +SPI0_MOSI,P10 +P0_10,P10 +P0_11,P11 +P0_12,P12 +VCC_OFF,P13 +P0_13,P13 +P0_14,P14 +LED,P15 +P0_15,P15 +P0_16,P16 +I2C_SDA,P17 +P0_17,P17 +P0_18,P18 +P0_19,P19 +I2C_SCL,P20 +P0_20,P20 +P0_21,P21 +P0_22,P22 +P0_23,P23 +P0_24,P24 +P0_25,P25 +P0_26,P26 +P0_27,P27 +P0_28,P28 +P0_29,P29 +AIN5,P29 +P0_30,P30 +AIN7,P31 +P0_31,P31 +P1_00,P32 +P1_01,P33 +P1_02,P34 +P1_04,P35 +P1_06,P38 +P1_07,P39 +P1_08,P40 +P1_09,P41 +P1_10,P42 +P1_11,P43 +SPI0_MISO,P43 +SPI0_SCK,P45 +P1_13,P45 +P1_15,P47