summaryrefslogtreecommitdiff
path: root/ports
diff options
context:
space:
mode:
authorDaniel Pollard <daniel@learnweaver.com>2020-05-12 14:41:28 +1000
committerDaniel Pollard <daniel@learnweaver.com>2020-05-12 14:41:28 +1000
commitee2cb703c83ff1c27675e98ce28f4cc49a33ebb9 (patch)
tree989b08a0d3016ac63e254ae44fcb7385bf9fc020 /ports
parente947e4eb580e080d37445240ec88610fc1787975 (diff)
parent62b835ad7637c5336f210ab688289dc607bec661 (diff)
merged master
Diffstat (limited to 'ports')
-rw-r--r--ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk2
-rw-r--r--ports/atmel-samd/common-hal/busio/UART.c3
-rw-r--r--ports/atmel-samd/supervisor/port.c4
-rw-r--r--ports/mimxrt10xx/Makefile4
-rw-r--r--ports/mimxrt10xx/boards/teensy41/board.c39
-rw-r--r--ports/mimxrt10xx/boards/teensy41/board.ld1
-rw-r--r--ports/mimxrt10xx/boards/teensy41/flash_config.c126
-rw-r--r--ports/mimxrt10xx/boards/teensy41/mpconfigboard.h18
-rw-r--r--ports/mimxrt10xx/boards/teensy41/mpconfigboard.mk8
-rw-r--r--ports/mimxrt10xx/boards/teensy41/pins.c116
-rw-r--r--ports/mimxrt10xx/common-hal/busio/SPI.c230
-rw-r--r--ports/mimxrt10xx/common-hal/busio/SPI.h8
-rw-r--r--ports/mimxrt10xx/common-hal/busio/UART.c13
-rw-r--r--ports/mimxrt10xx/common-hal/busio/UART.h2
-rw-r--r--ports/mimxrt10xx/supervisor/port.c3
-rw-r--r--ports/nrf/boards/circuitplayground_bluefruit/mpconfigboard.mk1
-rw-r--r--ports/nrf/boards/pitaya_go/README.md40
-rw-r--r--ports/nrf/boards/pitaya_go/board.c38
-rw-r--r--ports/nrf/boards/pitaya_go/mpconfigboard.h43
-rw-r--r--ports/nrf/boards/pitaya_go/mpconfigboard.mk11
-rw-r--r--ports/nrf/boards/pitaya_go/pins.c64
-rw-r--r--ports/nrf/common-hal/_bleio/Characteristic.c2
-rw-r--r--ports/nrf/common-hal/_bleio/CharacteristicBuffer.c19
-rw-r--r--ports/nrf/common-hal/_bleio/Connection.c18
-rw-r--r--ports/nrf/common-hal/_bleio/Connection.h1
-rw-r--r--ports/nrf/common-hal/_bleio/PacketBuffer.c149
-rw-r--r--ports/nrf/common-hal/_bleio/PacketBuffer.h6
-rw-r--r--ports/nrf/common-hal/_bleio/Service.h2
-rw-r--r--ports/nrf/common-hal/_bleio/__init__.c8
-rw-r--r--ports/nrf/common-hal/busio/UART.c28
-rw-r--r--ports/nrf/common-hal/busio/UART.h2
-rw-r--r--ports/nrf/mpconfigport.mk36
-rw-r--r--ports/stm/boards/STM32F401xd_fs.ld2
-rw-r--r--ports/stm/boards/STM32F401xe_boot.ld2
-rw-r--r--ports/stm/boards/STM32F401xe_fs.ld2
-rw-r--r--ports/stm/boards/STM32F405_boot.ld2
-rw-r--r--ports/stm/boards/STM32F405_default.ld2
-rw-r--r--ports/stm/boards/STM32F405_fs.ld2
-rw-r--r--ports/stm/boards/STM32F407_fs.ld2
-rw-r--r--ports/stm/boards/STM32F411_fs.ld2
-rw-r--r--ports/stm/boards/STM32F411_nvm.ld2
-rw-r--r--ports/stm/boards/STM32F412_fs.ld2
-rw-r--r--ports/stm/boards/STM32F746xG_fs.ld2
-rw-r--r--ports/stm/boards/STM32F767_fs.ld2
-rw-r--r--ports/stm/boards/STM32H743_fs.ld6
-rw-r--r--ports/stm/common-hal/busio/UART.c24
-rw-r--r--ports/stm/common-hal/busio/UART.h2
-rw-r--r--ports/stm/common-hal/microcontroller/Pin.c12
-rw-r--r--ports/stm/common-hal/rgbmatrix/RGBMatrix.c54
-rw-r--r--ports/stm/common-hal/rgbmatrix/RGBMatrix.h35
-rw-r--r--ports/stm/common-hal/rgbmatrix/__init__.c0
-rw-r--r--ports/stm/common-hal/rgbmatrix/__init__.h0
-rw-r--r--ports/stm/mpconfigport.mk16
-rw-r--r--ports/stm/supervisor/internal_flash.h2
-rw-r--r--ports/stm/supervisor/port.c74
55 files changed, 1006 insertions, 288 deletions
diff --git a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk
index 5469f1338..88555655f 100644
--- a/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk
+++ b/ports/atmel-samd/boards/hallowing_m0_express/mpconfigboard.mk
@@ -20,7 +20,7 @@ CIRCUITPY_I2CSLAVE = 0
CIRCUITPY_ROTARYIO = 0
CIRCUITPY_RTC = 0
CIRCUITPY_COUNTIO = 0
-CFLAGS_INLINE_LIMIT = 60
+CFLAGS_INLINE_LIMIT = 55
SUPEROPT_GC = 0
# Include these Python libraries in firmware.
diff --git a/ports/atmel-samd/common-hal/busio/UART.c b/ports/atmel-samd/common-hal/busio/UART.c
index 1f6b75f97..d6c13eb7e 100644
--- a/ports/atmel-samd/common-hal/busio/UART.c
+++ b/ports/atmel-samd/common-hal/busio/UART.c
@@ -45,6 +45,9 @@
#include "samd/sercom.h"
+#define UART_DEBUG(...) (void)0
+// #define UART_DEBUG(...) mp_printf(&mp_plat_print __VA_OPT__(,) __VA_ARGS__)
+
// Do-nothing callback needed so that usart_async code will enable rx interrupts.
// See comment below re usart_async_register_callback()
static void usart_async_rxc_callback(const struct usart_async_descriptor *const descr) {
diff --git a/ports/atmel-samd/supervisor/port.c b/ports/atmel-samd/supervisor/port.c
index b3903bb86..04e2c9191 100644
--- a/ports/atmel-samd/supervisor/port.c
+++ b/ports/atmel-samd/supervisor/port.c
@@ -174,6 +174,10 @@ static void rtc_init(void) {
#endif
NVIC_ClearPendingIRQ(RTC_IRQn);
NVIC_EnableIRQ(RTC_IRQn);
+#if CIRCUITPY_RTC
+ rtc_reset();
+#endif
+
}
safe_mode_t port_init(void) {
diff --git a/ports/mimxrt10xx/Makefile b/ports/mimxrt10xx/Makefile
index 858e92c32..59b833cc5 100644
--- a/ports/mimxrt10xx/Makefile
+++ b/ports/mimxrt10xx/Makefile
@@ -93,6 +93,10 @@ endif
CFLAGS += $(INC) -Wall -Wno-cast-align -std=gnu11 -nostdlib $(BASE_CFLAGS) $(CFLAGS_MOD) $(COPT)
+# TODO: add these when -Werror is applied
+# Disable some warnings, as do most ports. NXP SDK causes undef, tinyusb causes cast-align
+# CFLAGS += -Wno-undef -Wno-cast-align
+
CFLAGS += \
-mthumb \
-mapcs \
diff --git a/ports/mimxrt10xx/boards/teensy41/board.c b/ports/mimxrt10xx/boards/teensy41/board.c
new file mode 100644
index 000000000..52dd498b3
--- /dev/null
+++ b/ports/mimxrt10xx/boards/teensy41/board.c
@@ -0,0 +1,39 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries
+ * Copyright (c) 2019 Artur Pacholec
+ *
+ * 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.
+ */
+
+#include "boards/board.h"
+#include "mpconfigboard.h"
+
+void board_init(void) {
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+}
diff --git a/ports/mimxrt10xx/boards/teensy41/board.ld b/ports/mimxrt10xx/boards/teensy41/board.ld
new file mode 100644
index 000000000..8f19810a3
--- /dev/null
+++ b/ports/mimxrt10xx/boards/teensy41/board.ld
@@ -0,0 +1 @@
+_ld_reserved_flash_size = 4K;
diff --git a/ports/mimxrt10xx/boards/teensy41/flash_config.c b/ports/mimxrt10xx/boards/teensy41/flash_config.c
new file mode 100644
index 000000000..426deb884
--- /dev/null
+++ b/ports/mimxrt10xx/boards/teensy41/flash_config.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2017 NXP
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include "fsl_flexspi_nor_boot.h"
+#include "fsl_flexspi_nor_config.h"
+
+/* Component ID definition, used by tools. */
+#ifndef FSL_COMPONENT_ID
+#define FSL_COMPONENT_ID "platform.drivers.xip_device"
+#endif
+
+__attribute__((section(".boot_hdr.ivt")))
+/*************************************
+ * IVT Data
+ *************************************/
+const ivt image_vector_table = {
+ IVT_HEADER, /* IVT Header */
+ IMAGE_ENTRY_ADDRESS, /* Image Entry Function */
+ IVT_RSVD, /* Reserved = 0 */
+ (uint32_t)DCD_ADDRESS, /* Address where DCD information is stored */
+ (uint32_t)BOOT_DATA_ADDRESS, /* Address where BOOT Data Structure is stored */
+ (uint32_t)&image_vector_table, /* Pointer to IVT Self (absolute address */
+ (uint32_t)CSF_ADDRESS, /* Address where CSF file is stored */
+ IVT_RSVD /* Reserved = 0 */
+};
+
+__attribute__((section(".boot_hdr.boot_data")))
+/*************************************
+ * Boot Data
+ *************************************/
+const BOOT_DATA_T boot_data = {
+ FLASH_BASE, /* boot start location */
+ FLASH_SIZE, /* size */
+ PLUGIN_FLAG, /* Plugin flag*/
+ 0xFFFFFFFF /* empty - extra data word */
+};
+
+__attribute__((section(".boot_hdr.conf")))
+// Values copied from https://github.com/PaulStoffregen/cores/blob/ddb23fa5d97dac763bc06e11b9b41f026bd51f0a/teensy4/bootdata.c#L39
+const flexspi_nor_config_t qspiflash_config = {
+ .memConfig =
+ {
+ .tag = FLEXSPI_CFG_BLK_TAG,
+ .version = FLEXSPI_CFG_BLK_VERSION,
+ .readSampleClkSrc = kFlexSPIReadSampleClk_LoopbackFromDqsPad,
+ .csHoldTime = 1u,
+ .csSetupTime = 2u,
+ // Enable DDR mode, Wordaddressable, Safe configuration, Differential clock
+ .deviceType = kFlexSpiDeviceType_SerialNOR,
+ .sflashPadType = kSerialFlash_4Pads,
+ .serialClkFreq = kFlexSpiSerialClk_60MHz, // 03
+ .sflashA1Size = FLASH_SIZE,
+ .lookupTable =
+ {
+ // FLEXSPI_LUT_SEQ(cmd0, pad0, op0, cmd1, pad1, op1)
+ // (FLEXSPI_LUT_OPERAND0(op0) | FLEXSPI_LUT_NUM_PADS0(pad0) | FLEXSPI_LUT_OPCODE0(cmd0) | FLEXSPI_LUT_OPERAND1(op1) |
+ // FLEXSPI_LUT_NUM_PADS1(pad1) | FLEXSPI_LUT_OPCODE1(cmd1))
+ // Read LUTs
+ FLEXSPI_LUT_SEQ(CMD_SDR, FLEXSPI_1PAD, 0xEB, RADDR_SDR, FLEXSPI_4PAD, 0x18),
+ FLEXSPI_LUT_SEQ(DUMMY_SDR, FLEXSPI_4PAD, 0x06, READ_SDR, FLEXSPI_4PAD, 0x04),
+ 0,
+ 0,
+
+ 0x24040405,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0x00000406,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0x08180420,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0x081804D8,
+ 0,
+ 0,
+ 0,
+
+ 0x08180402,
+ 0x00002004,
+ 0,
+ 0,
+
+ 0,
+ 0,
+ 0,
+ 0,
+
+ 0x00000460,
+ },
+ },
+ .pageSize = 256u,
+ .sectorSize = 4u * 1024u,
+ .ipcmdSerialClkFreq = kFlexSpiSerialClk_30MHz,
+ .blockSize = 0x00010000,
+ .isUniformBlockSize = false,
+};
diff --git a/ports/mimxrt10xx/boards/teensy41/mpconfigboard.h b/ports/mimxrt10xx/boards/teensy41/mpconfigboard.h
new file mode 100644
index 000000000..15b8c0f34
--- /dev/null
+++ b/ports/mimxrt10xx/boards/teensy41/mpconfigboard.h
@@ -0,0 +1,18 @@
+#define MICROPY_HW_BOARD_NAME "Teensy 4.1"
+#define MICROPY_HW_MCU_NAME "IMXRT1062DVJ6A"
+
+// If you change this, then make sure to update the linker scripts as well to
+// make sure you don't overwrite code
+#define CIRCUITPY_INTERNAL_NVM_SIZE 0
+
+#define BOARD_FLASH_SIZE (8 * 1024 * 1024)
+
+#define DEFAULT_I2C_BUS_SCL (&pin_GPIO_AD_B1_00)
+#define DEFAULT_I2C_BUS_SDA (&pin_GPIO_AD_B1_01)
+
+#define DEFAULT_SPI_BUS_SCK (&pin_GPIO_B0_03)
+#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO_B0_02)
+#define DEFAULT_SPI_BUS_MISO (&pin_GPIO_B0_01)
+
+#define DEFAULT_UART_BUS_RX (&pin_GPIO_AD_B0_03)
+#define DEFAULT_UART_BUS_TX (&pin_GPIO_AD_B0_02)
diff --git a/ports/mimxrt10xx/boards/teensy41/mpconfigboard.mk b/ports/mimxrt10xx/boards/teensy41/mpconfigboard.mk
new file mode 100644
index 000000000..201e0e660
--- /dev/null
+++ b/ports/mimxrt10xx/boards/teensy41/mpconfigboard.mk
@@ -0,0 +1,8 @@
+USB_VID = 0x239A
+USB_PID = 0x80AE
+USB_PRODUCT = "Teensy 4.1"
+USB_MANUFACTURER = "PJRC"
+
+CHIP_VARIANT = MIMXRT1062DVJ6A
+CHIP_FAMILY = MIMXRT1062
+FLASH = W25Q64JV
diff --git a/ports/mimxrt10xx/boards/teensy41/pins.c b/ports/mimxrt10xx/boards/teensy41/pins.c
new file mode 100644
index 000000000..5eb5ab0f5
--- /dev/null
+++ b/ports/mimxrt10xx/boards/teensy41/pins.c
@@ -0,0 +1,116 @@
+#include "shared-bindings/board/__init__.h"
+
+#include "boards/board.h"
+
+STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
+ // With USB on left. Bottom edge.
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D0), MP_ROM_PTR(&pin_GPIO_AD_B0_03) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_GPIO_AD_B0_03) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_RX1), MP_ROM_PTR(&pin_GPIO_AD_B0_03) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D1), MP_ROM_PTR(&pin_GPIO_AD_B0_02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_GPIO_AD_B0_02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_TX1), MP_ROM_PTR(&pin_GPIO_AD_B0_02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D2), MP_ROM_PTR(&pin_GPIO_EMC_04) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D3), MP_ROM_PTR(&pin_GPIO_EMC_05) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D4), MP_ROM_PTR(&pin_GPIO_EMC_06) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D5), MP_ROM_PTR(&pin_GPIO_EMC_08) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D6), MP_ROM_PTR(&pin_GPIO_B0_10) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D7), MP_ROM_PTR(&pin_GPIO_B1_01) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D8), MP_ROM_PTR(&pin_GPIO_B1_00) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D9), MP_ROM_PTR(&pin_GPIO_B0_11) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D10), MP_ROM_PTR(&pin_GPIO_B0_00) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D11), MP_ROM_PTR(&pin_GPIO_B0_02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_GPIO_B0_02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D12), MP_ROM_PTR(&pin_GPIO_B0_01) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_GPIO_B0_01) },
+
+ // Bottom Edge extended for 4.1
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D24), MP_ROM_PTR(&pin_GPIO_AD_B0_12) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A10), MP_ROM_PTR(&pin_GPIO_AD_B0_12) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D25), MP_ROM_PTR(&pin_GPIO_AD_B0_13) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A11), MP_ROM_PTR(&pin_GPIO_AD_B0_13) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D26), MP_ROM_PTR(&pin_GPIO_AD_B1_14) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A12), MP_ROM_PTR(&pin_GPIO_AD_B1_14) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D27), MP_ROM_PTR(&pin_GPIO_AD_B1_15) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A13), MP_ROM_PTR(&pin_GPIO_AD_B1_15) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D28), MP_ROM_PTR(&pin_GPIO_EMC_32) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D29), MP_ROM_PTR(&pin_GPIO_EMC_31) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D30), MP_ROM_PTR(&pin_GPIO_EMC_37) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D31), MP_ROM_PTR(&pin_GPIO_EMC_36) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D32), MP_ROM_PTR(&pin_GPIO_B0_12) },
+
+ // Top edge
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D13), MP_ROM_PTR(&pin_GPIO_B0_03) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_GPIO_B0_03) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D14), MP_ROM_PTR(&pin_GPIO_AD_B1_02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A0), MP_ROM_PTR(&pin_GPIO_AD_B1_02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D15), MP_ROM_PTR(&pin_GPIO_AD_B1_03) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A1), MP_ROM_PTR(&pin_GPIO_AD_B1_03) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D16), MP_ROM_PTR(&pin_GPIO_AD_B1_07) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A2), MP_ROM_PTR(&pin_GPIO_AD_B1_07) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D17), MP_ROM_PTR(&pin_GPIO_AD_B1_06) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A3), MP_ROM_PTR(&pin_GPIO_AD_B1_06) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D18), MP_ROM_PTR(&pin_GPIO_AD_B1_01) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A4), MP_ROM_PTR(&pin_GPIO_AD_B1_01) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO_AD_B1_01) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SDA0), MP_ROM_PTR(&pin_GPIO_AD_B1_01) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D19), MP_ROM_PTR(&pin_GPIO_AD_B1_00) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A5), MP_ROM_PTR(&pin_GPIO_AD_B1_00) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_GPIO_AD_B1_00) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_SCL0), MP_ROM_PTR(&pin_GPIO_AD_B1_00) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D20), MP_ROM_PTR(&pin_GPIO_AD_B1_10) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A6), MP_ROM_PTR(&pin_GPIO_AD_B1_10) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D21), MP_ROM_PTR(&pin_GPIO_AD_B1_11) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A7), MP_ROM_PTR(&pin_GPIO_AD_B1_11) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D22), MP_ROM_PTR(&pin_GPIO_AD_B1_08) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A8), MP_ROM_PTR(&pin_GPIO_AD_B1_08) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D23), MP_ROM_PTR(&pin_GPIO_AD_B1_09) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_A9), MP_ROM_PTR(&pin_GPIO_AD_B1_09) },
+
+ // Top edge extended for Teensy 4.1
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D33), MP_ROM_PTR(&pin_GPIO_EMC_07) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D34), MP_ROM_PTR(&pin_GPIO_B1_13) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D35), MP_ROM_PTR(&pin_GPIO_B1_12) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D36), MP_ROM_PTR(&pin_GPIO_B1_02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D37), MP_ROM_PTR(&pin_GPIO_B1_03) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D38), MP_ROM_PTR(&pin_GPIO_AD_B1_12) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D39), MP_ROM_PTR(&pin_GPIO_AD_B1_13) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D40), MP_ROM_PTR(&pin_GPIO_AD_B1_04) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D41), MP_ROM_PTR(&pin_GPIO_AD_B1_05) },
+
+ // SD Card slot
+ { MP_OBJ_NEW_QSTR(MP_QSTR_DAT1), MP_ROM_PTR(&pin_GPIO_SD_B0_03) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D42), MP_ROM_PTR(&pin_GPIO_SD_B0_03) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_DAT0), MP_ROM_PTR(&pin_GPIO_SD_B0_02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D43), MP_ROM_PTR(&pin_GPIO_SD_B0_02) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_CLK), MP_ROM_PTR(&pin_GPIO_SD_B0_01) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D44), MP_ROM_PTR(&pin_GPIO_SD_B0_01) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_CMD), MP_ROM_PTR(&pin_GPIO_SD_B0_00) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D45), MP_ROM_PTR(&pin_GPIO_SD_B0_00) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_DAT3), MP_ROM_PTR(&pin_GPIO_SD_B0_05) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D46), MP_ROM_PTR(&pin_GPIO_SD_B0_05) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_DAT2), MP_ROM_PTR(&pin_GPIO_SD_B0_04) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D47), MP_ROM_PTR(&pin_GPIO_SD_B0_04) },
+
+ // Flash expansion spot and PSRAM expansion spot on a shared QSPI BUS
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D48), MP_ROM_PTR(&pin_GPIO_EMC_24) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_PSRAM_CS), MP_ROM_PTR(&pin_GPIO_EMC_24) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D49), MP_ROM_PTR(&pin_GPIO_EMC_27) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_QSPI_IO1), MP_ROM_PTR(&pin_GPIO_EMC_27) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D50), MP_ROM_PTR(&pin_GPIO_EMC_28) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_QSPI_IO2), MP_ROM_PTR(&pin_GPIO_EMC_28) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D51), MP_ROM_PTR(&pin_GPIO_EMC_22) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_FLASH_CS), MP_ROM_PTR(&pin_GPIO_EMC_22) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D52), MP_ROM_PTR(&pin_GPIO_EMC_26) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_QSPI_IO0), MP_ROM_PTR(&pin_GPIO_EMC_26) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D53), MP_ROM_PTR(&pin_GPIO_EMC_25) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_QSPI_CLK), MP_ROM_PTR(&pin_GPIO_EMC_25) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_D54), MP_ROM_PTR(&pin_GPIO_EMC_29) },
+ { MP_OBJ_NEW_QSTR(MP_QSTR_QSPI_IO3), MP_ROM_PTR(&pin_GPIO_EMC_29) },
+
+
+ { MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
+ { MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
+ { MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
+};
+MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
diff --git a/ports/mimxrt10xx/common-hal/busio/SPI.c b/ports/mimxrt10xx/common-hal/busio/SPI.c
index 24a6dbff6..cc19ba354 100644
--- a/ports/mimxrt10xx/common-hal/busio/SPI.c
+++ b/ports/mimxrt10xx/common-hal/busio/SPI.c
@@ -25,7 +25,6 @@
* THE SOFTWARE.
*/
-//TODO
#include "shared-bindings/busio/SPI.h"
#include "py/mperrno.h"
#include "py/runtime.h"
@@ -35,48 +34,12 @@
#include <stdio.h>
-//bool never_reset_sercoms[SERCOM_INST_NUM];
-//
-//void never_reset_sercom(Sercom* sercom) {
-// // Reset all SERCOMs except the ones being used by on-board devices.
-// Sercom *sercom_instances[SERCOM_INST_NUM] = SERCOM_INSTS;
-// for (int i = 0; i < SERCOM_INST_NUM; i++) {
-// if (sercom_instances[i] == sercom) {
-// never_reset_sercoms[i] = true;
-// break;
-// }
-// }
-//}
-//
-//void allow_reset_sercom(Sercom* sercom) {
-// // Reset all SERCOMs except the ones being used by on-board devices.
-// Sercom *sercom_instances[SERCOM_INST_NUM] = SERCOM_INSTS;
-// for (int i = 0; i < SERCOM_INST_NUM; i++) {
-// if (sercom_instances[i] == sercom) {
-// never_reset_sercoms[i] = false;
-// break;
-// }
-// }
-//}
-//
-//void reset_sercoms(void) {
-// // Reset all SERCOMs except the ones being used by on-board devices.
-// Sercom *sercom_instances[SERCOM_INST_NUM] = SERCOM_INSTS;
-// for (int i = 0; i < SERCOM_INST_NUM; i++) {
-// if (never_reset_sercoms[i]) {
-// continue;
-// }
-// #ifdef MICROPY_HW_APA102_SERCOM
-// if (sercom_instances[i] == MICROPY_HW_APA102_SERCOM) {
-// continue;
-// }
-// #endif
-// // SWRST is same for all modes of SERCOMs.
-// sercom_instances[i]->SPI.CTRLA.bit.SWRST = 1;
-// }
-//}
-
-static void config_periph_pin(const mcu_periph_obj_t *periph) {
+//arrays use 0 based numbering: SPI1 is stored at index 0
+#define MAX_SPI 4
+STATIC bool reserved_spi[MAX_SPI];
+STATIC bool never_reset_spi[MAX_SPI];
+
+STATIC void config_periph_pin(const mcu_periph_obj_t *periph) {
IOMUXC_SetPinMux(
periph->pin->mux_reg, periph->mux_mode,
periph->input_reg, periph->input_idx,
@@ -97,52 +60,117 @@ static void config_periph_pin(const mcu_periph_obj_t *periph) {
#define LPSPI_MASTER_CLK_FREQ (CLOCK_GetFreq(kCLOCK_Usb1PllPfd0Clk) / (CLOCK_GetDiv(kCLOCK_LpspiDiv)))
+void spi_reset(void) {
+ for (int i = 0; i < MAX_SPI; i++) {
+ reserved_spi[i] = false;
+ }
+}
+
void common_hal_busio_spi_construct(busio_spi_obj_t *self,
const mcu_pin_obj_t *clock, const mcu_pin_obj_t *mosi,
const mcu_pin_obj_t *miso) {
- // TODO: Allow none mosi or miso
-
- const uint32_t sck_count = sizeof(mcu_spi_sck_list) / sizeof(mcu_periph_obj_t);
- const uint32_t miso_count = sizeof(mcu_spi_miso_list) / sizeof(mcu_periph_obj_t);
- const uint32_t mosi_count = sizeof(mcu_spi_mosi_list) / sizeof(mcu_periph_obj_t);
+ const uint32_t sck_count = MP_ARRAY_SIZE(mcu_spi_sck_list);
+ const uint32_t miso_count = MP_ARRAY_SIZE(mcu_spi_miso_list);
+ const uint32_t mosi_count = MP_ARRAY_SIZE(mcu_spi_mosi_list);
+ bool spi_taken = false;
- for (uint32_t i = 0; i < sck_count; ++i) {
- if (mcu_spi_sck_list[i].pin != clock)
+ for (uint i = 0; i < sck_count; i++) {
+ if (mcu_spi_sck_list[i].pin != clock) {
continue;
-
- for (uint32_t j = 0; j < miso_count; ++j) {
- if (mcu_spi_miso_list[j].pin != miso)
- continue;
-
- if (mcu_spi_miso_list[j].bank_idx != mcu_spi_sck_list[i].bank_idx)
- continue;
-
- for (uint32_t k = 0; k < mosi_count; ++k) {
- if (mcu_spi_mosi_list[k].pin != mosi)
+ }
+ //if both MOSI and MISO exist, loop search normally
+ if ((mosi != NULL) && (miso != NULL)) {
+ for (uint j = 0; j < mosi_count; j++) {
+ if ((mcu_spi_mosi_list[i].pin != mosi)
+ || (mcu_spi_sck_list[i].bank_idx != mcu_spi_mosi_list[j].bank_idx)){
continue;
-
- if (mcu_spi_mosi_list[k].bank_idx != mcu_spi_miso_list[j].bank_idx)
+ }
+ for (uint k = 0; k < miso_count; k++) {
+ if ((mcu_spi_miso_list[k].pin != miso) //everything needs the same index
+ || (mcu_spi_sck_list[i].bank_idx != mcu_spi_miso_list[k].bank_idx)) {
+ continue;
+ }
+ //keep looking if the SPI is taken, edge case
+ if (reserved_spi[mcu_spi_sck_list[i].bank_idx - 1]) {
+ spi_taken = true;
+ continue;
+ }
+ //store pins if not
+ self->clock = &mcu_spi_sck_list[i];
+ self->mosi = &mcu_spi_mosi_list[j];
+ self->miso = &mcu_spi_miso_list[k];
+ break;
+ }
+ if (self->clock != NULL) {
+ break; // Multi-level break to pick lowest peripheral
+ }
+ }
+ if (self->clock != NULL) {
+ break;
+ }
+ // if just MISO, reduce search
+ } else if (miso != NULL) {
+ for (uint j = 0; j < miso_count; j++) {
+ if ((mcu_spi_miso_list[j].pin != miso) //only SCK and MISO need the same index
+ || (mcu_spi_sck_list[i].bank_idx != mcu_spi_miso_list[j].bank_idx)) {
continue;
-
- self->clock_pin = &mcu_spi_sck_list[i];
- self->miso_pin = &mcu_spi_miso_list[j];
- self->mosi_pin = &mcu_spi_mosi_list[k];
-
+ }
+ if (reserved_spi[mcu_spi_sck_list[i].bank_idx - 1]) {
+ spi_taken = true;
+ continue;
+ }
+ self->clock = &mcu_spi_sck_list[i];
+ self->mosi = NULL;
+ self->miso = &mcu_spi_miso_list[j];
+ break;
+ }
+ if (self->clock != NULL) {
break;
}
+ // if just MOSI, reduce search
+ } else if (mosi != NULL) {
+ for (uint j = 0; j < mosi_count; j++) {
+ if ((mcu_spi_mosi_list[j].pin != mosi) //only SCK and MOSI need the same index
+ || (mcu_spi_sck_list[i].bank_idx != mcu_spi_mosi_list[j].bank_idx)) {
+ continue;
+ }
+ if (reserved_spi[mcu_spi_sck_list[i].bank_idx - 1]) {
+ spi_taken = true;
+ continue;
+ }
+ self->clock = &mcu_spi_sck_list[i];
+ self->mosi = &mcu_spi_mosi_list[j];
+ self->miso = NULL;
+ break;
+ }
+ if (self->clock != NULL) {
+ break;
+ }
+ } else {
+ //throw an error immediately
+ mp_raise_ValueError(translate("Must provide MISO or MOSI pin"));
}
}
- if(self->clock_pin == NULL || self->mosi_pin == NULL || self->miso_pin == NULL) {
- mp_raise_RuntimeError(translate("Invalid SPI pin selection"));
+ if (self->clock != NULL && (self->mosi != NULL || self->miso != NULL)) {
+ self->spi = mcu_spi_banks[self->clock->bank_idx - 1];
} else {
- self->spi = mcu_spi_banks[self->clock_pin->bank_idx - 1];
+ if (spi_taken) {
+ mp_raise_ValueError(translate("Hardware busy, try alternative pins"));
+ } else {
+ mp_raise_ValueError(translate("Invalid SPI pin selection"));
+ }
}
- config_periph_pin(self->mosi_pin);
- config_periph_pin(self->miso_pin);
- config_periph_pin(self->clock_pin);
+ config_periph_pin(self->clock);
+ if (self->mosi != NULL) {
+ config_periph_pin(self->mosi);
+ }
+ if (self->miso != NULL) {
+ config_periph_pin(self->miso);
+ }
+ reserved_spi[self->clock->bank_idx - 1] = true;
lpspi_master_config_t config = { 0 };
LPSPI_MasterGetDefaultConfig(&config);
@@ -150,47 +178,27 @@ void common_hal_busio_spi_construct(busio_spi_obj_t *self,
// Always start at 250khz which is what SD cards need. They are sensitive to
// SPI bus noise before they are put into SPI mode.
config.baudRate = 250000;
-
LPSPI_MasterInit(self->spi, &config, LPSPI_MASTER_CLK_FREQ);
-
LPSPI_Enable(self->spi, false);
uint32_t tcrPrescaleValue;
self->baudrate = LPSPI_MasterSetBaudRate(self->spi, config.baudRate, LPSPI_MASTER_CLK_FREQ, &tcrPrescaleValue);
LPSPI_Enable(self->spi, true);
- claim_pin(self->clock_pin->pin);
-
-// if (mosi_none) {
-// self->MOSI_pin = NO_PIN;
-// } else {
-// gpio_set_pin_direction(mosi->number, GPIO_DIRECTION_OUT);
-// gpio_set_pin_pull_mode(mosi->number, GPIO_PULL_OFF);
-// gpio_set_pin_function(mosi->number, mosi_pinmux);
-// self->MOSI_pin = mosi->number;
- claim_pin(self->mosi_pin->pin);
-// }
-
-// if (miso_none) {
-// self->MISO_pin = NO_PIN;
-// } else {
-// gpio_set_pin_direction(miso->number, GPIO_DIRECTION_IN);
-// gpio_set_pin_pull_mode(miso->number, GPIO_PULL_OFF);
-// gpio_set_pin_function(miso->number, miso_pinmux);
-// self->MISO_pin = miso->number;
- claim_pin(self->miso_pin->pin);
-// }
+ claim_pin(self->clock->pin);
+ if (self->mosi != NULL) {
+ claim_pin(self->mosi->pin);
+ }
+ if (self->miso != NULL) {
+ claim_pin(self->miso->pin);
+ }
}
void common_hal_busio_spi_never_reset(busio_spi_obj_t *self) {
-// never_reset_sercom(self->spi_desc.dev.prvt);
-
-// never_reset_pin_number(self->clock_pin);
-// never_reset_pin_number(self->MOSI_pin);
-// never_reset_pin_number(self->MISO_pin);
+ // TODO
}
bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) {
- return self->clock_pin == NULL;
+ return self->clock == NULL;
}
void common_hal_busio_spi_deinit(busio_spi_obj_t *self) {
@@ -198,14 +206,7 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) {
return;
}
-// allow_reset_sercom(self->spi_desc.dev.prvt);
-
-// spi_m_sync_disable(&self->spi_desc);
-// spi_m_sync_deinit(&self->spi_desc);
-// reset_pin_number(self->clock_pin);
-// reset_pin_number(self->MOSI_pin);
-// reset_pin_number(self->MISO_pin);
- self->clock_pin = NULL;
+ self->clock = NULL;
}
bool common_hal_busio_spi_configure(busio_spi_obj_t *self,
@@ -260,6 +261,9 @@ bool common_hal_busio_spi_write(busio_spi_obj_t *self,
if (len == 0) {
return true;
}
+ if (self->mosi == NULL) {
+ mp_raise_ValueError(translate("No MOSI Pin"));
+ }
lpspi_transfer_t xfer = { 0 };
xfer.txData = (uint8_t*)data;
@@ -278,6 +282,9 @@ bool common_hal_busio_spi_read(busio_spi_obj_t *self,
if (len == 0) {
return true;
}
+ if (self->miso == NULL) {
+ mp_raise_ValueError(translate("No MISO Pin"));
+ }
LPSPI_SetDummyData(self->spi, write_value);
@@ -296,6 +303,9 @@ bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, uint8_t *data_out, uin
if (len == 0) {
return true;
}
+ if (self->miso == NULL || self->mosi == NULL) {
+ mp_raise_ValueError(translate("Missing MISO or MOSI Pin"));
+ }
LPSPI_SetDummyData(self->spi, 0xFF);
diff --git a/ports/mimxrt10xx/common-hal/busio/SPI.h b/ports/mimxrt10xx/common-hal/busio/SPI.h
index 0895e1ddb..f699cd7ad 100644
--- a/ports/mimxrt10xx/common-hal/busio/SPI.h
+++ b/ports/mimxrt10xx/common-hal/busio/SPI.h
@@ -38,9 +38,11 @@ typedef struct {
LPSPI_Type *spi;
bool has_lock;
uint32_t baudrate;
- const mcu_periph_obj_t *clock_pin;
- const mcu_periph_obj_t *mosi_pin;
- const mcu_periph_obj_t *miso_pin;
+ const mcu_periph_obj_t *clock;
+ const mcu_periph_obj_t *mosi;
+ const mcu_periph_obj_t *miso;
} busio_spi_obj_t;
+void spi_reset(void);
+
#endif // MICROPY_INCLUDED_MIMXRT10XX_COMMON_HAL_BUSIO_SPI_H
diff --git a/ports/mimxrt10xx/common-hal/busio/UART.c b/ports/mimxrt10xx/common-hal/busio/UART.c
index 4633507d8..e3642daf5 100644
--- a/ports/mimxrt10xx/common-hal/busio/UART.c
+++ b/ports/mimxrt10xx/common-hal/busio/UART.c
@@ -198,15 +198,18 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
claim_pin(self->tx_pin->pin);
if (self->rx_pin != NULL) {
- ringbuf_alloc(&self->rbuf, receiver_buffer_size, true);
+ // The LPUART ring buffer wastes one byte to distinguish between full and empty.
+ self->ringbuf = gc_alloc(receiver_buffer_size + 1, false, true /*long-lived*/);
- if (!self->rbuf.buf) {
+ if (!self->ringbuf) {
LPUART_Deinit(self->uart);
mp_raise_msg(&mp_type_MemoryError, translate("Failed to allocate RX buffer"));
}
LPUART_TransferCreateHandle(self->uart, &self->handle, LPUART_UserCallback, self);
- LPUART_TransferStartRingBuffer(self->uart, &self->handle, self->rbuf.buf, self->rbuf.size);
+ // Pass actual allocated size; the LPUART routines are cognizant that
+ // the capacity is one less than the size.
+ LPUART_TransferStartRingBuffer(self->uart, &self->handle, self->ringbuf, receiver_buffer_size + 1);
claim_pin(self->rx_pin->pin);
}
@@ -223,9 +226,7 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
LPUART_Deinit(self->uart);
- gc_free(self->rbuf.buf);
- self->rbuf.size = 0;
- self->rbuf.iput = self->rbuf.iget = 0;
+ gc_free(self->ringbuf);
// reset_pin_number(self->rx_pin);
// reset_pin_number(self->tx_pin);
diff --git a/ports/mimxrt10xx/common-hal/busio/UART.h b/ports/mimxrt10xx/common-hal/busio/UART.h
index 9e768db3c..3a326eb3a 100644
--- a/ports/mimxrt10xx/common-hal/busio/UART.h
+++ b/ports/mimxrt10xx/common-hal/busio/UART.h
@@ -40,7 +40,7 @@ typedef struct {
mp_obj_base_t base;
LPUART_Type *uart;
lpuart_handle_t handle;
- ringbuf_t rbuf;
+ uint8_t* ringbuf;
bool rx_ongoing;
uint32_t baudrate;
uint8_t character_bits;
diff --git a/ports/mimxrt10xx/supervisor/port.c b/ports/mimxrt10xx/supervisor/port.c
index 72326363d..18cb408cb 100644
--- a/ports/mimxrt10xx/supervisor/port.c
+++ b/ports/mimxrt10xx/supervisor/port.c
@@ -41,6 +41,7 @@
#include "common-hal/pulseio/PulseOut.h"
#include "common-hal/pulseio/PWMOut.h"
#include "common-hal/rtc/RTC.h"
+#include "common-hal/busio/SPI.h"
#include "reset.h"
@@ -267,7 +268,7 @@ safe_mode_t port_init(void) {
}
void reset_port(void) {
- //reset_sercoms();
+ spi_reset();
#if CIRCUITPY_AUDIOIO
audio_dma_reset();
diff --git a/ports/nrf/boards/circuitplayground_bluefruit/mpconfigboard.mk b/ports/nrf/boards/circuitplayground_bluefruit/mpconfigboard.mk
index f63554e5e..38c993334 100644
--- a/ports/nrf/boards/circuitplayground_bluefruit/mpconfigboard.mk
+++ b/ports/nrf/boards/circuitplayground_bluefruit/mpconfigboard.mk
@@ -11,7 +11,6 @@ EXTERNAL_FLASH_DEVICES = "GD25Q16C"
# Allocate two, not just one I2C peripheral for CPB, so that we have both
# on-board and off-board I2C available.
-# When SPIM3 becomes available we'll be able to have two I2C and two SPI peripherals.
# We use a CFLAGS define here because there are include order issues
# if we try to include "mpconfigport.h" into nrfx_config.h .
CFLAGS += -DCIRCUITPY_NRF_NUM_I2C=2
diff --git a/ports/nrf/boards/pitaya_go/README.md b/ports/nrf/boards/pitaya_go/README.md
new file mode 100644
index 000000000..a58b75289
--- /dev/null
+++ b/ports/nrf/boards/pitaya_go/README.md
@@ -0,0 +1,40 @@
+# Makerdiary Pitaya Go
+
+>Pitaya Go is a compact and versatile development platform for IoT solutions,
+combining the Nordic's high-end multiprotocol SoC nRF52840 and the Microchip's
+extreme low power Wi-Fi® network controller ATWINC1500B. It offers a complete
+solution for wireless connectivity with IEEE 802.11 b/g/n, Bluetooth 5, Thread
+and Zigbee, that is specifically designed for the IoT.
+Pitaya Go features a Battery Charger with power path management, 64Mbit ultra
+low power QSPI Flash memory, additional NFC-A Tag PCB Antenna, user
+programmable RGB LED and Buttons, reversible USB-C Connector and easily
+expandable Header Sockets. All these features above make this board an ideal
+choice for the next IoT project.
+
+from [Makerdiary](https://store.makerdiary.com/products/pitaya-go)
+
+
+## Installing CircuitPython submodules
+
+Before you can build, you will need to run the following commands once, which
+will install the submodules that are part of the CircuitPython ecosystem, and
+build the `mpy-cross` tool:
+
+```
+$ cd circuitpython
+$ git submodule update --init
+$ make -C mpy-cross
+```
+
+
+## Building
+```sh
+$ cd ports/nrf
+$ make BOARD=pitaya_go SD=s140 -V=1 -j4
+```
+
+# Flashing CircuitPython
+
+The Pitaya Go has a pre-programmed bootloader which can be used to program the
+Pitaya Go. Follow [the guide - How to Program Pitaya Go](https://wiki.makerdiary.com/pitaya-go/programming/)
+to flash the CircuitPython firmware.
diff --git a/ports/nrf/boards/pitaya_go/board.c b/ports/nrf/boards/pitaya_go/board.c
new file mode 100644
index 000000000..4421970ee
--- /dev/null
+++ b/ports/nrf/boards/pitaya_go/board.c
@@ -0,0 +1,38 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
+ *
+ * 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.
+ */
+
+#include "boards/board.h"
+
+void board_init(void) {
+}
+
+bool board_requests_safe_mode(void) {
+ return false;
+}
+
+void reset_board(void) {
+
+}
diff --git a/ports/nrf/boards/pitaya_go/mpconfigboard.h b/ports/nrf/boards/pitaya_go/mpconfigboard.h
new file mode 100644
index 000000000..7f9eff716
--- /dev/null
+++ b/ports/nrf/boards/pitaya_go/mpconfigboard.h
@@ -0,0 +1,43 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 Glenn Ruben Bakke
+ * Copyright (c) 2018 Dan Halbert for Adafruit Industries
+ * Copyright (c) 2020 Yihui Xiong
+ *
+ * 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.
+ */
+
+#include "nrfx/hal/nrf_gpio.h"
+
+#define MAKERDIARYPITAYAGO
+
+#define MICROPY_HW_BOARD_NAME "Makerdiary Pitaya Go"
+#define MICROPY_HW_MCU_NAME "nRF52840"
+
+#define MICROPY_QSPI_DATA0 NRF_GPIO_PIN_MAP(1, 6)
+#define MICROPY_QSPI_DATA1 NRF_GPIO_PIN_MAP(1, 1)
+#define MICROPY_QSPI_DATA2 NRF_GPIO_PIN_MAP(1, 5)
+#define MICROPY_QSPI_DATA3 NRF_GPIO_PIN_MAP(1, 2)
+#define MICROPY_QSPI_SCK NRF_GPIO_PIN_MAP(1, 4)
+#define MICROPY_QSPI_CS NRF_GPIO_PIN_MAP(1, 3)
+
+#define BOARD_HAS_CRYSTAL 1
diff --git a/ports/nrf/boards/pitaya_go/mpconfigboard.mk b/ports/nrf/boards/pitaya_go/mpconfigboard.mk
new file mode 100644
index 000000000..247ddd8ac
--- /dev/null
+++ b/ports/nrf/boards/pitaya_go/mpconfigboard.mk
@@ -0,0 +1,11 @@
+# Using Nordic's VID - https://devzone.nordicsemi.com/f/nordic-q-a/50638/usb-pid-for-nrf52840
+USB_VID = 0x1915
+USB_PID = 0xb001
+USB_PRODUCT = "Pitaya Go"
+USB_MANUFACTURER = "Makerdiary"
+
+MCU_CHIP = nrf52840
+
+QSPI_FLASH_FILESYSTEM = 1
+EXTERNAL_FLASH_DEVICE_COUNT = 1
+EXTERNAL_FLASH_DEVICES = "MX25R6435F"
diff --git a/ports/nrf/boards/pitaya_go/pins.c b/ports/nrf/boards/pitaya_go/pins.c
new file mode 100644
index 000000000..92411581b
--- /dev/null
+++ b/ports/nrf/boards/pitaya_go/pins.c
@@ -0,0 +1,64 @@
+#include "shared-bindings/board/__init__.h"
+
+STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
+ { MP_ROM_QSTR(MP_QSTR_AIN0), MP_ROM_PTR(&pin_P0_02) },
+ { MP_ROM_QSTR(MP_QSTR_AIN1), MP_ROM_PTR(&pin_P0_03) },
+ { MP_ROM_QSTR(MP_QSTR_AIN2), MP_ROM_PTR(&pin_P0_04) },
+ { MP_ROM_QSTR(MP_QSTR_AIN3), MP_ROM_PTR(&pin_P0_05) },
+ { MP_ROM_QSTR(MP_QSTR_AIN4), MP_ROM_PTR(&pin_P0_28) },
+ { MP_ROM_QSTR(MP_QSTR_AIN5), MP_ROM_PTR(&pin_P0_29) },
+ { MP_ROM_QSTR(MP_QSTR_AIN6), MP_ROM_PTR(&pin_P0_30) },
+ { MP_ROM_QSTR(MP_QSTR_AIN7), MP_ROM_PTR(&pin_P0_31) },
+
+ { MP_ROM_QSTR(MP_QSTR_AREF), MP_ROM_PTR(&pin_P0_04) },
+ { MP_ROM_QSTR(MP_QSTR_VDIV), MP_ROM_PTR(&pin_P0_05) },
+
+ { MP_ROM_QSTR(MP_QSTR_NFC1), MP_ROM_PTR(&pin_P0_09) },
+ { MP_ROM_QSTR(MP_QSTR_NFC2), MP_ROM_PTR(&pin_P0_10) },
+
+ { MP_ROM_QSTR(MP_QSTR_P2), MP_ROM_PTR(&pin_P0_02) },
+ { MP_ROM_QSTR(MP_QSTR_P3), MP_ROM_PTR(&pin_P0_03) },
+ { MP_ROM_QSTR(MP_QSTR_P4), MP_ROM_PTR(&pin_P0_04) },
+ { MP_ROM_QSTR(MP_QSTR_P5), MP_ROM_PTR(&pin_P0_05) },
+ { MP_ROM_QSTR(MP_QSTR_P6), MP_ROM_PTR(&pin_P0_06) },
+ { MP_ROM_QSTR(MP_QSTR_P7), MP_ROM_PTR(&pin_P0_07) },
+ { MP_ROM_QSTR(MP_QSTR_P8), MP_ROM_PTR(&pin_P0_08) },
+ { MP_ROM_QSTR(MP_QSTR_P9), MP_ROM_PTR(&pin_P0_09) },
+ { MP_ROM_QSTR(MP_QSTR_P10), MP_ROM_PTR(&pin_P0_10) },
+ { MP_ROM_QSTR(MP_QSTR_P11), MP_ROM_PTR(&pin_P0_11) },
+ { MP_ROM_QSTR(MP_QSTR_P12), MP_ROM_PTR(&pin_P0_12) },
+ { MP_ROM_QSTR(MP_QSTR_P13), MP_ROM_PTR(&pin_P0_13) },
+ { MP_ROM_QSTR(MP_QSTR_P14), MP_ROM_PTR(&pin_P0_14) },
+ { MP_ROM_QSTR(MP_QSTR_P15), MP_ROM_PTR(&pin_P0_15) },
+ { MP_ROM_QSTR(MP_QSTR_P16), MP_ROM_PTR(&pin_P0_16) },
+ { MP_ROM_QSTR(MP_QSTR_P17), MP_ROM_PTR(&pin_P0_17) },
+ { MP_ROM_QSTR(MP_QSTR_P18), MP_ROM_PTR(&pin_P0_18) },
+ { MP_ROM_QSTR(MP_QSTR_P19), MP_ROM_PTR(&pin_P0_19) },
+ { MP_ROM_QSTR(MP_QSTR_P20), MP_ROM_PTR(&pin_P0_20) },
+ { MP_ROM_QSTR(MP_QSTR_P21), MP_ROM_PTR(&pin_P0_21) },
+ { MP_ROM_QSTR(MP_QSTR_P22), MP_ROM_PTR(&pin_P0_22) },
+ { MP_ROM_QSTR(MP_QSTR_P23), MP_ROM_PTR(&pin_P0_23) },
+ { MP_ROM_QSTR(MP_QSTR_P24), MP_ROM_PTR(&pin_P0_24) },
+ { MP_ROM_QSTR(MP_QSTR_P25), MP_ROM_PTR(&pin_P0_25) },
+ { MP_ROM_QSTR(MP_QSTR_P26), MP_ROM_PTR(&pin_P0_26) },
+ { MP_ROM_QSTR(MP_QSTR_P27), MP_ROM_PTR(&pin_P0_27) },
+ { MP_ROM_QSTR(MP_QSTR_P28), MP_ROM_PTR(&pin_P0_28) },
+ { MP_ROM_QSTR(MP_QSTR_P29), MP_ROM_PTR(&pin_P0_29) },
+ { MP_ROM_QSTR(MP_QSTR_P30), MP_ROM_PTR(&pin_P0_30) },
+ { MP_ROM_QSTR(MP_QSTR_P31), MP_ROM_PTR(&pin_P0_31) },
+
+ { MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_P1_04) },
+ { MP_ROM_QSTR(MP_QSTR_CSN), MP_ROM_PTR(&pin_P1_03) },
+ { MP_ROM_QSTR(MP_QSTR_IO0), MP_ROM_PTR(&pin_P1_06) },
+ { MP_ROM_QSTR(MP_QSTR_IO1), MP_ROM_PTR(&pin_P1_01) },
+ { MP_ROM_QSTR(MP_QSTR_IO2), MP_ROM_PTR(&pin_P1_05) },
+ { MP_ROM_QSTR(MP_QSTR_IO3), MP_ROM_PTR(&pin_P1_02) },
+
+ { MP_ROM_QSTR(MP_QSTR_LED_RED), MP_ROM_PTR(&pin_P0_10) },
+ { MP_ROM_QSTR(MP_QSTR_LED_GREEN), MP_ROM_PTR(&pin_P0_11) },
+ { MP_ROM_QSTR(MP_QSTR_LED_BLUE), MP_ROM_PTR(&pin_P0_12) },
+
+ { MP_ROM_QSTR(MP_QSTR_USR_BTN), MP_ROM_PTR(&pin_P1_00) },
+};
+
+MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);
diff --git a/ports/nrf/common-hal/_bleio/Characteristic.c b/ports/nrf/common-hal/_bleio/Characteristic.c
index e311aceb9..d507cecca 100644
--- a/ports/nrf/common-hal/_bleio/Characteristic.c
+++ b/ports/nrf/common-hal/_bleio/Characteristic.c
@@ -127,6 +127,7 @@ size_t common_hal_bleio_characteristic_get_value(bleio_characteristic_obj_t *sel
// self->value is set by evt handler.
return common_hal_bleio_gattc_read(self->handle, conn_handle, buf, len);
} else {
+ // conn_handle is ignored for non-system attributes.
return common_hal_bleio_gatts_read(self->handle, conn_handle, buf, len);
}
}
@@ -152,6 +153,7 @@ void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self,
(self->props & CHAR_PROP_WRITE_NO_RESPONSE));
} else {
// Always write the value locally even if no connections are active.
+ // conn_handle is ignored for non-system attributes, so we use BLE_CONN_HANDLE_INVALID.
common_hal_bleio_gatts_write(self->handle, BLE_CONN_HANDLE_INVALID, bufinfo);
// Check to see if we need to notify or indicate any active connections.
for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
diff --git a/ports/nrf/common-hal/_bleio/CharacteristicBuffer.c b/ports/nrf/common-hal/_bleio/CharacteristicBuffer.c
index c562d29e0..132e392dd 100644
--- a/ports/nrf/common-hal/_bleio/CharacteristicBuffer.c
+++ b/ports/nrf/common-hal/_bleio/CharacteristicBuffer.c
@@ -40,13 +40,11 @@
#include "supervisor/shared/tick.h"
#include "common-hal/_bleio/CharacteristicBuffer.h"
+// Push all the data onto the ring buffer. When the buffer is full, new bytes will be dropped.
STATIC void write_to_ringbuf(bleio_characteristic_buffer_obj_t *self, uint8_t *data, uint16_t len) {
- // Push all the data onto the ring buffer.
uint8_t is_nested_critical_region;
sd_nvic_critical_region_enter(&is_nested_critical_region);
- for (size_t i = 0; i < len; i++) {
- ringbuf_put(&self->ringbuf, data[i]);
- }
+ ringbuf_put_n(&self->ringbuf, data, len);
sd_nvic_critical_region_exit(is_nested_critical_region);
}
@@ -98,11 +96,11 @@ void common_hal_bleio_characteristic_buffer_construct(bleio_characteristic_buffe
}
-int common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer_obj_t *self, uint8_t *data, size_t len, int *errcode) {
+uint32_t common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer_obj_t *self, uint8_t *data, size_t len, int *errcode) {
uint64_t start_ticks = supervisor_ticks_ms64();
// Wait for all bytes received or timeout
- while ( (ringbuf_count(&self->ringbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
+ while ( (ringbuf_num_filled(&self->ringbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
RUN_BACKGROUND_TASKS;
// Allow user to break out of a timeout with a KeyboardInterrupt.
if ( mp_hal_is_interrupted() ) {
@@ -114,21 +112,18 @@ int common_hal_bleio_characteristic_buffer_read(bleio_characteristic_buffer_obj_
uint8_t is_nested_critical_region;
sd_nvic_critical_region_enter(&is_nested_critical_region);
- size_t rx_bytes = MIN(ringbuf_count(&self->ringbuf), len);
- for ( size_t i = 0; i < rx_bytes; i++ ) {
- data[i] = ringbuf_get(&self->ringbuf);
- }
+ uint32_t num_bytes_read = ringbuf_get_n(&self->ringbuf, data, len);
// Writes now OK.
sd_nvic_critical_region_exit(is_nested_critical_region);
- return rx_bytes;
+ return num_bytes_read;
}
uint32_t common_hal_bleio_characteristic_buffer_rx_characters_available(bleio_characteristic_buffer_obj_t *self) {
uint8_t is_nested_critical_region;
sd_nvic_critical_region_enter(&is_nested_critical_region);
- uint16_t count = ringbuf_count(&self->ringbuf);
+ uint16_t count = ringbuf_num_filled(&self->ringbuf);
sd_nvic_critical_region_exit(is_nested_critical_region);
return count;
}
diff --git a/ports/nrf/common-hal/_bleio/Connection.c b/ports/nrf/common-hal/_bleio/Connection.c
index d4c7308fd..00c1acd4d 100644
--- a/ports/nrf/common-hal/_bleio/Connection.c
+++ b/ports/nrf/common-hal/_bleio/Connection.c
@@ -371,6 +371,11 @@ mp_float_t common_hal_bleio_connection_get_connection_interval(bleio_connection_
return 1.25f * self->conn_params.min_conn_interval;
}
+// Return the current negotiated MTU length, minus overhead.
+mp_int_t common_hal_bleio_connection_get_max_packet_length(bleio_connection_internal_t *self) {
+ return (self->mtu == 0 ? BLE_GATT_ATT_MTU_DEFAULT : self->mtu) - 3;
+}
+
void common_hal_bleio_connection_set_connection_interval(bleio_connection_internal_t *self, mp_float_t new_interval) {
self->conn_params_updating = true;
uint16_t interval = new_interval / 1.25f;
@@ -752,3 +757,16 @@ mp_obj_t bleio_connection_new_from_internal(bleio_connection_internal_t* interna
return MP_OBJ_FROM_PTR(connection);
}
+
+// Find the connection that uses the given conn_handle. Return NULL if not found.
+bleio_connection_internal_t *bleio_conn_handle_to_connection(uint16_t conn_handle) {
+ bleio_connection_internal_t *connection;
+ for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
+ connection = &bleio_connections[i];
+ if (connection->conn_handle == conn_handle) {
+ return connection;
+ }
+ }
+
+ return NULL;
+}
diff --git a/ports/nrf/common-hal/_bleio/Connection.h b/ports/nrf/common-hal/_bleio/Connection.h
index 282e0c4b5..b051e5c51 100644
--- a/ports/nrf/common-hal/_bleio/Connection.h
+++ b/ports/nrf/common-hal/_bleio/Connection.h
@@ -87,5 +87,6 @@ bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in);
uint16_t bleio_connection_get_conn_handle(bleio_connection_obj_t *self);
mp_obj_t bleio_connection_new_from_internal(bleio_connection_internal_t* connection);
+bleio_connection_internal_t *bleio_conn_handle_to_connection(uint16_t conn_handle);
#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_CONNECTION_H
diff --git a/ports/nrf/common-hal/_bleio/PacketBuffer.c b/ports/nrf/common-hal/_bleio/PacketBuffer.c
index 6c360617f..a8773f961 100644
--- a/ports/nrf/common-hal/_bleio/PacketBuffer.c
+++ b/ports/nrf/common-hal/_bleio/PacketBuffer.c
@@ -41,7 +41,7 @@
#include "supervisor/shared/tick.h"
STATIC void write_to_ringbuf(bleio_packet_buffer_obj_t *self, uint8_t *data, uint16_t len) {
- if (len + sizeof(uint16_t) > self->ringbuf.size) {
+ if (len + sizeof(uint16_t) > ringbuf_capacity(&self->ringbuf)) {
// This shouldn't happen.
return;
}
@@ -49,7 +49,7 @@ STATIC void write_to_ringbuf(bleio_packet_buffer_obj_t *self, uint8_t *data, uin
uint8_t is_nested_critical_region;
sd_nvic_critical_region_enter(&is_nested_critical_region);
// Make room for the new value by dropping the oldest packets first.
- while (self->ringbuf.size - ringbuf_count(&self->ringbuf) < (int) (len + sizeof(uint16_t))) {
+ while (ringbuf_capacity(&self->ringbuf) - ringbuf_num_filled(&self->ringbuf) < len + sizeof(uint16_t)) {
uint16_t packet_length;
ringbuf_get_n(&self->ringbuf, (uint8_t*) &packet_length, sizeof(uint16_t));
for (uint16_t i = 0; i < packet_length; i++) {
@@ -105,12 +105,18 @@ STATIC uint32_t queue_next_write(bleio_packet_buffer_obj_t *self) {
}
STATIC bool packet_buffer_on_ble_client_evt(ble_evt_t *ble_evt, void *param) {
- bleio_packet_buffer_obj_t *self = (bleio_packet_buffer_obj_t *) param;
+ const uint16_t evt_id = ble_evt->header.evt_id;
+ // Check if this is a GATTC event so we can make sure the conn_handle is valid.
+ if (evt_id < BLE_GATTC_EVT_BASE || evt_id > BLE_GATTC_EVT_LAST) {
+ return false;
+ }
+
uint16_t conn_handle = ble_evt->evt.gattc_evt.conn_handle;
+ bleio_packet_buffer_obj_t *self = (bleio_packet_buffer_obj_t *) param;
if (conn_handle != self->conn_handle) {
return false;
}
- switch (ble_evt->header.evt_id) {
+ switch (evt_id) {
case BLE_GATTC_EVT_HVX: {
// A remote service wrote to this characteristic.
ble_gattc_evt_hvx_t* evt_hvx = &ble_evt->evt.gattc_evt.params.hvx;
@@ -140,9 +146,9 @@ STATIC bool packet_buffer_on_ble_client_evt(ble_evt_t *ble_evt, void *param) {
STATIC bool packet_buffer_on_ble_server_evt(ble_evt_t *ble_evt, void *param) {
bleio_packet_buffer_obj_t *self = (bleio_packet_buffer_obj_t *) param;
- uint16_t conn_handle = ble_evt->evt.gatts_evt.conn_handle;
switch (ble_evt->header.evt_id) {
case BLE_GATTS_EVT_WRITE: {
+ uint16_t conn_handle = ble_evt->evt.gatts_evt.conn_handle;
// A client wrote to this server characteristic.
ble_gatts_evt_write_t *evt_write = &ble_evt->evt.gatts_evt.params.write;
@@ -166,7 +172,7 @@ STATIC bool packet_buffer_on_ble_server_evt(ble_evt_t *ble_evt, void *param) {
break;
}
case BLE_GAP_EVT_DISCONNECTED: {
- if (self->conn_handle == conn_handle) {
+ if (self->conn_handle == ble_evt->evt.gap_evt.conn_handle) {
self->conn_handle = BLE_CONN_HANDLE_INVALID;
}
}
@@ -200,10 +206,7 @@ void common_hal_bleio_packet_buffer_construct(
}
if (incoming) {
- // This is a macro.
- ringbuf_alloc(&self->ringbuf, buffer_size * (sizeof(uint16_t) + characteristic->max_length), false);
-
- if (self->ringbuf.buf == NULL) {
+ if (!ringbuf_alloc(&self->ringbuf, buffer_size * (sizeof(uint16_t) + characteristic->max_length), false)) {
mp_raise_ValueError(translate("Buffer too large and unable to allocate"));
}
}
@@ -247,45 +250,66 @@ void common_hal_bleio_packet_buffer_construct(
}
}
-int common_hal_bleio_packet_buffer_readinto(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len) {
- if (ringbuf_count(&self->ringbuf) < 2) {
+mp_int_t common_hal_bleio_packet_buffer_readinto(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len) {
+ if (ringbuf_num_filled(&self->ringbuf) < 2) {
return 0;
}
- uint16_t packet_length;
- ringbuf_get_n(&self->ringbuf, (uint8_t*) &packet_length, sizeof(uint16_t));
-
// Copy received data. Lock out write interrupt handler while copying.
uint8_t is_nested_critical_region;
sd_nvic_critical_region_enter(&is_nested_critical_region);
+ // Get packet length, which is in first two bytes of packet.
+ uint16_t packet_length;
+ ringbuf_get_n(&self->ringbuf, (uint8_t*) &packet_length, sizeof(uint16_t));
+
+ mp_int_t ret;
if (packet_length > len) {
- return len - packet_length;
+ // Packet is longer than requested. Return negative of overrun value.
+ ret = len - packet_length;
+ // Discard the packet if it's too large. Don't fill data.
+ while (packet_length--) {
+ (void) ringbuf_get(&self->ringbuf);
+ }
+ } else {
+ // Read as much as possible, but might be shorter than len.
+ ringbuf_get_n(&self->ringbuf, data, packet_length);
+ ret = packet_length;
}
- ringbuf_get_n(&self->ringbuf, data, packet_length);
-
// Writes now OK.
sd_nvic_critical_region_exit(is_nested_critical_region);
- return packet_length;
+ return ret;
}
-void common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len, uint8_t* header, size_t header_len) {
+mp_int_t common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len, uint8_t* header, size_t header_len) {
if (self->outgoing[0] == NULL) {
mp_raise_bleio_BluetoothError(translate("Writes not supported on Characteristic"));
}
if (self->conn_handle == BLE_CONN_HANDLE_INVALID) {
- return;
+ return -1;
+ }
+ uint16_t outgoing_packet_length = common_hal_bleio_packet_buffer_get_outgoing_packet_length(self);
+
+ if (len + header_len > outgoing_packet_length) {
+ // Supplied data will not fit in a single BLE packet.
+ mp_raise_ValueError(translate("Total data to write is larger than outgoing_packet_length"));
}
- uint16_t packet_size = common_hal_bleio_packet_buffer_get_packet_size(self);
- uint16_t max_size = packet_size - len;
- while (max_size < self->pending_size && self->conn_handle != BLE_CONN_HANDLE_INVALID) {
- RUN_BACKGROUND_TASKS;
+
+ if (len + self->pending_size > outgoing_packet_length) {
+ // No room to append len bytes to packet. Wait until we get a free buffer,
+ // and keep checking that we haven't been disconnected.
+ while (self->pending_size != 0 && self->conn_handle != BLE_CONN_HANDLE_INVALID) {
+ RUN_BACKGROUND_TASKS;
+ }
}
if (self->conn_handle == BLE_CONN_HANDLE_INVALID) {
- return;
+ return -1;
}
+
+ size_t num_bytes_written = 0;
+
uint8_t is_nested_critical_region;
sd_nvic_critical_region_enter(&is_nested_critical_region);
@@ -294,9 +318,11 @@ void common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, uint8
if (self->pending_size == 0) {
memcpy(pending, header, header_len);
self->pending_size += header_len;
+ num_bytes_written += header_len;
}
memcpy(pending + self->pending_size, data, len);
self->pending_size += len;
+ num_bytes_written += len;
sd_nvic_critical_region_exit(is_nested_critical_region);
@@ -304,28 +330,69 @@ void common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, uint8
if (!self->packet_queued) {
queue_next_write(self);
}
+ return num_bytes_written;
}
-uint16_t common_hal_bleio_packet_buffer_get_packet_size(bleio_packet_buffer_obj_t *self) {
- uint16_t mtu;
- if (self->conn_handle == BLE_CONN_HANDLE_INVALID) {
- return 0;
+mp_int_t common_hal_bleio_packet_buffer_get_incoming_packet_length(bleio_packet_buffer_obj_t *self) {
+ // If this PacketBuffer is coming from a remote service via NOTIFY or INDICATE
+ // the maximum size is what can be sent in one
+ // BLE packet. But we must be connected to know that value.
+ //
+ // Otherwise it can be as long as the characteristic
+ // will permit, whether or not we're connected.
+
+ if (self->characteristic == NULL) {
+ return -1;
}
- bleio_connection_internal_t *connection;
- for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) {
- connection = &bleio_connections[i];
- if (connection->conn_handle == self->conn_handle) {
- break;
+
+ if (self->characteristic->service != NULL &&
+ self->characteristic->service->is_remote &&
+ (common_hal_bleio_characteristic_get_properties(self->characteristic) &
+ (CHAR_PROP_INDICATE | CHAR_PROP_NOTIFY))) {
+ // We are talking to a remote service, and data is arriving via NOTIFY or INDICATE.
+ if (self->conn_handle != BLE_CONN_HANDLE_INVALID) {
+ bleio_connection_internal_t *connection = bleio_conn_handle_to_connection(self->conn_handle);
+ if (connection) {
+ return MIN(common_hal_bleio_connection_get_max_packet_length(connection),
+ self->characteristic->max_length);
+ }
}
+ // There's no current connection, so we don't know the MTU, and
+ // we can't tell what the largest incoming packet length would be.
+ return -1;
}
- if (connection->mtu == 0) {
- mtu = BLE_GATT_ATT_MTU_DEFAULT;
+ return self->characteristic->max_length;
+}
+
+mp_int_t common_hal_bleio_packet_buffer_get_outgoing_packet_length(bleio_packet_buffer_obj_t *self) {
+ // If we are sending data via NOTIFY or INDICATE, the maximum size
+ // is what can be sent in one BLE packet. But we must be connected
+ // to know that value.
+ //
+ // Otherwise it can be as long as the characteristic
+ // will permit, whether or not we're connected.
+
+ if (self->characteristic == NULL) {
+ return -1;
}
- if (self->characteristic->max_length > mtu) {
- mtu = self->characteristic->max_length;
+
+ if (self->characteristic->service != NULL &&
+ !self->characteristic->service->is_remote &&
+ (common_hal_bleio_characteristic_get_properties(self->characteristic) &
+ (CHAR_PROP_INDICATE | CHAR_PROP_NOTIFY))) {
+ // We are sending to a client, via NOTIFY or INDICATE.
+ if (self->conn_handle != BLE_CONN_HANDLE_INVALID) {
+ bleio_connection_internal_t *connection = bleio_conn_handle_to_connection(self->conn_handle);
+ if (connection) {
+ return MIN(common_hal_bleio_connection_get_max_packet_length(connection),
+ self->characteristic->max_length);
+ }
+ }
+ // There's no current connection, so we don't know the MTU, and
+ // we can't tell what the largest outgoing packet length would be.
+ return -1;
}
- uint16_t att_overhead = 3;
- return mtu - att_overhead;
+ return self->characteristic->max_length;
}
bool common_hal_bleio_packet_buffer_deinited(bleio_packet_buffer_obj_t *self) {
diff --git a/ports/nrf/common-hal/_bleio/PacketBuffer.h b/ports/nrf/common-hal/_bleio/PacketBuffer.h
index cfccc852e..699291749 100644
--- a/ports/nrf/common-hal/_bleio/PacketBuffer.h
+++ b/ports/nrf/common-hal/_bleio/PacketBuffer.h
@@ -40,8 +40,10 @@ typedef struct {
// Two outgoing buffers to alternate between. One will be queued for transmission by the SD and
// the other is waiting to be queued and can be extended.
uint8_t* outgoing[2];
- uint16_t pending_size;
- uint16_t conn_handle;
+ volatile uint16_t pending_size;
+ // We remember the conn_handle so we can do a NOTIFY/INDICATE to a client.
+ // We can find out the conn_handle on a Characteristic write or a CCCD write (but not a read).
+ volatile uint16_t conn_handle;
uint8_t pending_index;
uint8_t write_type;
bool client;
diff --git a/ports/nrf/common-hal/_bleio/Service.h b/ports/nrf/common-hal/_bleio/Service.h
index f101bc825..6ee9fe63d 100644
--- a/ports/nrf/common-hal/_bleio/Service.h
+++ b/ports/nrf/common-hal/_bleio/Service.h
@@ -39,6 +39,8 @@ typedef struct bleio_service_obj {
bool is_remote;
bool is_secondary;
bleio_uuid_obj_t *uuid;
+ // The connection object is set only when this is a remote service.
+ // A local service doesn't know the connection.
mp_obj_t connection;
mp_obj_list_t *characteristic_list;
// Range of attribute handles of this remote service.
diff --git a/ports/nrf/common-hal/_bleio/__init__.c b/ports/nrf/common-hal/_bleio/__init__.c
index 62a3a9299..e84bba662 100644
--- a/ports/nrf/common-hal/_bleio/__init__.c
+++ b/ports/nrf/common-hal/_bleio/__init__.c
@@ -118,8 +118,8 @@ void common_hal_bleio_check_connected(uint16_t conn_handle) {
// GATTS read of a Characteristic or Descriptor.
size_t common_hal_bleio_gatts_read(uint16_t handle, uint16_t conn_handle, uint8_t* buf, size_t len) {
- // conn_handle might be BLE_CONN_HANDLE_INVALID if we're not connected, but that's OK, because
- // we can still read and write the local value.
+ // conn_handle is ignored unless this is a system attribute.
+ // If we're not connected, that's OK, because we can still read and write the local value.
ble_gatts_value_t gatts_value = {
.p_value = buf,
@@ -132,8 +132,8 @@ size_t common_hal_bleio_gatts_read(uint16_t handle, uint16_t conn_handle, uint8_
}
void common_hal_bleio_gatts_write(uint16_t handle, uint16_t conn_handle, mp_buffer_info_t *bufinfo) {
- // conn_handle might be BLE_CONN_HANDLE_INVALID if we're not connected, but that's OK, because
- // we can still read and write the local value.
+ // conn_handle is ignored unless this is a system attribute.
+ // If we're not connected, that's OK, because we can still read and write the local value.
ble_gatts_value_t gatts_value = {
.p_value = bufinfo->buf,
diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c
index 85626548f..dbf40ea51 100644
--- a/ports/nrf/common-hal/busio/UART.c
+++ b/ports/nrf/common-hal/busio/UART.c
@@ -98,7 +98,7 @@ static void uart_callback_irq (const nrfx_uarte_event_t * event, void * context)
switch ( event->type ) {
case NRFX_UARTE_EVT_RX_DONE:
- ringbuf_put_n(&self->rbuf, event->data.rxtx.p_data, event->data.rxtx.bytes);
+ ringbuf_put_n(&self->ringbuf, event->data.rxtx.p_data, event->data.rxtx.bytes);
// keep receiving
(void) nrfx_uarte_rx(self->uarte, &self->rx_char, 1);
@@ -112,7 +112,7 @@ static void uart_callback_irq (const nrfx_uarte_event_t * event, void * context)
// Possible Error source is Overrun, Parity, Framing, Break
// uint32_t errsrc = event->data.error.error_mask;
- ringbuf_put_n(&self->rbuf, event->data.error.rxtx.p_data, event->data.error.rxtx.bytes);
+ ringbuf_put_n(&self->ringbuf, event->data.error.rxtx.p_data, event->data.error.rxtx.bytes);
// Keep receiving
(void) nrfx_uarte_rx(self->uarte, &self->rx_char, 1);
@@ -190,9 +190,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
// pointers like this are NOT moved, allocating the buffer
// in the long-lived pool is not strictly necessary)
// (This is a macro.)
- ringbuf_alloc(&self->rbuf, receiver_buffer_size, true);
-
- if ( !self->rbuf.buf ) {
+ if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size, true)) {
nrfx_uarte_uninit(self->uarte);
mp_raise_msg(&mp_type_MemoryError, translate("Failed to allocate RX buffer"));
}
@@ -226,10 +224,7 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
reset_pin_number(self->rx_pin_number);
self->tx_pin_number = NO_PIN;
self->rx_pin_number = NO_PIN;
-
- gc_free(self->rbuf.buf);
- self->rbuf.size = 0;
- self->rbuf.iput = self->rbuf.iget = 0;
+ ringbuf_free(&self->ringbuf);
}
}
@@ -239,11 +234,10 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
mp_raise_ValueError(translate("No RX pin"));
}
- size_t rx_bytes = 0;
uint64_t start_ticks = supervisor_ticks_ms64();
// Wait for all bytes received or timeout
- while ( (ringbuf_count(&self->rbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
+ while ( (ringbuf_num_filled(&self->ringbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
RUN_BACKGROUND_TASKS;
// Allow user to break out of a timeout with a KeyboardInterrupt.
if ( mp_hal_is_interrupted() ) {
@@ -254,12 +248,8 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
// prevent conflict with uart irq
NVIC_DisableIRQ(nrfx_get_irq_number(self->uarte->p_reg));
- // copy received data
- rx_bytes = ringbuf_count(&self->rbuf);
- rx_bytes = MIN(rx_bytes, len);
- for ( uint16_t i = 0; i < rx_bytes; i++ ) {
- data[i] = ringbuf_get(&self->rbuf);
- }
+ // Copy as much received data as available, up to len bytes.
+ size_t rx_bytes = ringbuf_get_n(&self->ringbuf, data, len);
NVIC_EnableIRQ(nrfx_get_irq_number(self->uarte->p_reg));
@@ -316,13 +306,13 @@ void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeou
}
uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) {
- return ringbuf_count(&self->rbuf);
+ return ringbuf_num_filled(&self->ringbuf);
}
void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) {
// prevent conflict with uart irq
NVIC_DisableIRQ(nrfx_get_irq_number(self->uarte->p_reg));
- ringbuf_clear(&self->rbuf);
+ ringbuf_clear(&self->ringbuf);
NVIC_EnableIRQ(nrfx_get_irq_number(self->uarte->p_reg));
}
diff --git a/ports/nrf/common-hal/busio/UART.h b/ports/nrf/common-hal/busio/UART.h
index 58432001c..a25116291 100644
--- a/ports/nrf/common-hal/busio/UART.h
+++ b/ports/nrf/common-hal/busio/UART.h
@@ -41,7 +41,7 @@ typedef struct {
uint32_t baudrate;
uint32_t timeout_ms;
- ringbuf_t rbuf;
+ ringbuf_t ringbuf;
uint8_t rx_char; // EasyDMA buf
uint8_t tx_pin_number;
diff --git a/ports/nrf/mpconfigport.mk b/ports/nrf/mpconfigport.mk
index 7939a175b..a9ad11bd4 100644
--- a/ports/nrf/mpconfigport.mk
+++ b/ports/nrf/mpconfigport.mk
@@ -14,39 +14,21 @@ USB_SERIAL_NUMBER_LENGTH = 16
# All nRF ports have longints.
LONGINT_IMPL = MPZ
-# Audio via PWM
-ifndef CIRCUITPY_AUDIOCORE
-CIRCUITPY_AUDIOCORE = 1
-endif
+# The ?='s allow overriding in mpconfigboard.mk.
+# Audio via PWM
CIRCUITPY_AUDIOIO = 0
+CIRCUITPY_AUDIOBUSIO ?= 1
+CIRCUITPY_AUDIOCORE ?= 1
+CIRCUITPY_AUDIOMIXER ?= 1
+CIRCUITPY_AUDIOPWMIO ?= 1
-
-# The ifndef's allow overriding in mpconfigboard.mk.
-
-ifndef
-CIRCUITPY_BLEIO = 1
-endif
-
-ifndef CIRCUITPY_AUDIOMIXER
-CIRCUITPY_AUDIOMIXER = 1
-endif
-
-ifndef CIRCUITPY_AUDIOPWMIO
-CIRCUITPY_AUDIOPWMIO = 1
-endif
-
-ifndef CIRCUITPY_AUDIOBUSIO
-CIRCUITPY_AUDIOBUSIO = 1
-endif
+CIRCUITPY_BLEIO ?= 1
# No I2CSlave implementation
CIRCUITPY_I2CSLAVE = 0
-# enable RTC
-ifndef CIRCUITPY_RTC
-CIRCUITPY_RTC = 1
-endif
+CIRCUITPY_RTC ?= 1
# frequencyio not yet implemented
CIRCUITPY_FREQUENCYIO = 0
@@ -74,8 +56,6 @@ NRF_DEFINES += -DNRF52840_XXAA -DNRF52840
# Defined here because system_nrf52840.c doesn't #include any of our own include files.
CFLAGS += -DCONFIG_NFCT_PINS_AS_GPIOS
-CIRCUITPY_ULAB = 1
-
else
ifeq ($(MCU_CHIP),nrf52833)
MCU_SERIES = m4
diff --git a/ports/stm/boards/STM32F401xd_fs.ld b/ports/stm/boards/STM32F401xd_fs.ld
index 3086c2c6b..69bae46cb 100644
--- a/ports/stm/boards/STM32F401xd_fs.ld
+++ b/ports/stm/boards/STM32F401xd_fs.ld
@@ -13,7 +13,7 @@ MEMORY
}
/* produce a link error if there is not this amount of RAM for these sections */
-_minimum_stack_size = 2K;
+_minimum_stack_size = 24K;
_minimum_heap_size = 16K;
/* Define tho top end of the stack. The stack is full descending so begins just
diff --git a/ports/stm/boards/STM32F401xe_boot.ld b/ports/stm/boards/STM32F401xe_boot.ld
index 040947694..37827c330 100644
--- a/ports/stm/boards/STM32F401xe_boot.ld
+++ b/ports/stm/boards/STM32F401xe_boot.ld
@@ -12,7 +12,7 @@ MEMORY
}
/* produce a link error if there is not this amount of RAM for these sections */
-_minimum_stack_size = 2K;
+_minimum_stack_size = 24K;
_minimum_heap_size = 16K;
/* Define tho top end of the stack. The stack is full descending so begins just
diff --git a/ports/stm/boards/STM32F401xe_fs.ld b/ports/stm/boards/STM32F401xe_fs.ld
index b55bc4bb4..20247930c 100644
--- a/ports/stm/boards/STM32F401xe_fs.ld
+++ b/ports/stm/boards/STM32F401xe_fs.ld
@@ -13,7 +13,7 @@ MEMORY
}
/* produce a link error if there is not this amount of RAM for these sections */
-_minimum_stack_size = 2K;
+_minimum_stack_size = 24K;
_minimum_heap_size = 16K;
/* Define tho top end of the stack. The stack is full descending so begins just
diff --git a/ports/stm/boards/STM32F405_boot.ld b/ports/stm/boards/STM32F405_boot.ld
index 906f56e0d..5768d1a01 100644
--- a/ports/stm/boards/STM32F405_boot.ld
+++ b/ports/stm/boards/STM32F405_boot.ld
@@ -13,7 +13,7 @@ MEMORY
}
/* produce a link error if there is not this amount of RAM for these sections */
-_minimum_stack_size = 2K;
+_minimum_stack_size = 24K;
_minimum_heap_size = 16K;
/* Define the top end of the stack. The stack is full descending so begins just
diff --git a/ports/stm/boards/STM32F405_default.ld b/ports/stm/boards/STM32F405_default.ld
index 0aafdbcac..4c11fd7cf 100644
--- a/ports/stm/boards/STM32F405_default.ld
+++ b/ports/stm/boards/STM32F405_default.ld
@@ -13,7 +13,7 @@ MEMORY
}
/* produce a link error if there is not this amount of RAM for these sections */
-_minimum_stack_size = 2K;
+_minimum_stack_size = 24K;
_minimum_heap_size = 16K;
/* Define tho top end of the stack. The stack is full descending so begins just
diff --git a/ports/stm/boards/STM32F405_fs.ld b/ports/stm/boards/STM32F405_fs.ld
index bff312660..e6c66127f 100644
--- a/ports/stm/boards/STM32F405_fs.ld
+++ b/ports/stm/boards/STM32F405_fs.ld
@@ -14,7 +14,7 @@ MEMORY
}
/* produce a link error if there is not this amount of RAM for these sections */
-_minimum_stack_size = 2K;
+_minimum_stack_size = 24K;
_minimum_heap_size = 16K;
/* Define tho top end of the stack. The stack is full descending so begins just
diff --git a/ports/stm/boards/STM32F407_fs.ld b/ports/stm/boards/STM32F407_fs.ld
index 5330b4116..f06c19d99 100644
--- a/ports/stm/boards/STM32F407_fs.ld
+++ b/ports/stm/boards/STM32F407_fs.ld
@@ -14,7 +14,7 @@ MEMORY
}
/* produce a link error if there is not this amount of RAM for these sections */
-_minimum_stack_size = 2K;
+_minimum_stack_size = 24K;
_minimum_heap_size = 16K;
/* Define tho top end of the stack. The stack is full descending so begins just
diff --git a/ports/stm/boards/STM32F411_fs.ld b/ports/stm/boards/STM32F411_fs.ld
index 82c7aea06..1b45f235f 100644
--- a/ports/stm/boards/STM32F411_fs.ld
+++ b/ports/stm/boards/STM32F411_fs.ld
@@ -13,7 +13,7 @@ MEMORY
}
/* produce a link error if there is not this amount of RAM for these sections */
-_minimum_stack_size = 2K;
+_minimum_stack_size = 24K;
_minimum_heap_size = 16K;
/* Define tho top end of the stack. The stack is full descending so begins just
diff --git a/ports/stm/boards/STM32F411_nvm.ld b/ports/stm/boards/STM32F411_nvm.ld
index 897b99631..5ac3e52a6 100644
--- a/ports/stm/boards/STM32F411_nvm.ld
+++ b/ports/stm/boards/STM32F411_nvm.ld
@@ -14,7 +14,7 @@ MEMORY
}
/* produce a link error if there is not this amount of RAM for these sections */
-_minimum_stack_size = 2K;
+_minimum_stack_size = 24K;
_minimum_heap_size = 16K;
/* Define the top end of the stack. The stack is full descending so begins just
diff --git a/ports/stm/boards/STM32F412_fs.ld b/ports/stm/boards/STM32F412_fs.ld
index afd51c6b1..8837bd87d 100644
--- a/ports/stm/boards/STM32F412_fs.ld
+++ b/ports/stm/boards/STM32F412_fs.ld
@@ -13,7 +13,7 @@ MEMORY
}
/* produce a link error if there is not this amount of RAM for these sections */
-_minimum_stack_size = 2K;
+_minimum_stack_size = 24K;
_minimum_heap_size = 16K;
/* Define tho top end of the stack. The stack is full descending so begins just
diff --git a/ports/stm/boards/STM32F746xG_fs.ld b/ports/stm/boards/STM32F746xG_fs.ld
index f1bd3d5dc..be10a1429 100644
--- a/ports/stm/boards/STM32F746xG_fs.ld
+++ b/ports/stm/boards/STM32F746xG_fs.ld
@@ -38,7 +38,7 @@ MEMORY
}
/* produce a link error if there is not this amount of RAM for these sections */
-_minimum_stack_size = 2K;
+_minimum_stack_size = 24K;
_minimum_heap_size = 16K;
/* Define tho top end of the stack. The stack is full descending so begins just
diff --git a/ports/stm/boards/STM32F767_fs.ld b/ports/stm/boards/STM32F767_fs.ld
index 40e67829b..25322b0b6 100644
--- a/ports/stm/boards/STM32F767_fs.ld
+++ b/ports/stm/boards/STM32F767_fs.ld
@@ -13,7 +13,7 @@ MEMORY
}
/* produce a link error if there is not this amount of RAM for these sections */
-_minimum_stack_size = 2K;
+_minimum_stack_size = 24K;
_minimum_heap_size = 16K;
/* Define tho top end of the stack. The stack is full descending so begins just
diff --git a/ports/stm/boards/STM32H743_fs.ld b/ports/stm/boards/STM32H743_fs.ld
index 251c6cc27..b6c3d5b62 100644
--- a/ports/stm/boards/STM32H743_fs.ld
+++ b/ports/stm/boards/STM32H743_fs.ld
@@ -12,8 +12,8 @@ MEMORY
{
FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K
FLASH_ISR (rx) : ORIGIN = 0x08000000, LENGTH = 128K /* sector 0, 128K */
- FLASH_FS (r) : ORIGIN = 0x08020000, LENGTH = 128K /* sector 1, 128K */
- FLASH_FIRMWARE (rx) : ORIGIN = 0x08040000, LENGTH = 1792K /* sectors 6*128 + 8*128 */
+ FLASH_FS (r) : ORIGIN = 0x08020000, LENGTH = 384K /* sector 1-3, 128K */
+ FLASH_FIRMWARE (rx) : ORIGIN = 0x08080000, LENGTH = 1536K /* sectors 4*128 + 8*128 */
DTCM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
RAM (xrw) : ORIGIN = 0x24000000, LENGTH = 512K /* AXI SRAM */
SRAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K /* AHB1 SRAM */
@@ -22,7 +22,7 @@ MEMORY
}
/* produce a link error if there is not this amount of RAM for these sections */
-_minimum_stack_size = 2K;
+_minimum_stack_size = 24K; /*TODO: this can probably be bigger, but how big?*/
_minimum_heap_size = 16K;
/* brainless copy paste for stack code. Results in ambiguous hard crash */
diff --git a/ports/stm/common-hal/busio/UART.c b/ports/stm/common-hal/busio/UART.c
index 76afa5848..54ac68d73 100644
--- a/ports/stm/common-hal/busio/UART.c
+++ b/ports/stm/common-hal/busio/UART.c
@@ -209,8 +209,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self,
// Init buffer for rx and claim pins
if (self->rx != NULL) {
- ringbuf_alloc(&self->rbuf, receiver_buffer_size, true);
- if (!self->rbuf.buf) {
+ if (!ringbuf_alloc(&self->ringbuf, receiver_buffer_size, true)) {
mp_raise_ValueError(translate("UART Buffer allocation error"));
}
claim_pin(rx);
@@ -246,9 +245,7 @@ void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
reset_pin_number(self->rx->pin->port,self->rx->pin->number);
self->tx = NULL;
self->rx = NULL;
- gc_free(self->rbuf.buf);
- self->rbuf.size = 0;
- self->rbuf.iput = self->rbuf.iget = 0;
+ ringbuf_free(&self->ringbuf);
}
size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) {
@@ -256,11 +253,10 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
mp_raise_ValueError(translate("No RX pin"));
}
- size_t rx_bytes = 0;
uint64_t start_ticks = supervisor_ticks_ms64();
// Wait for all bytes received or timeout, same as nrf
- while ( (ringbuf_count(&self->rbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
+ while ( (ringbuf_num_filled(&self->ringbuf) < len) && (supervisor_ticks_ms64() - start_ticks < self->timeout_ms) ) {
RUN_BACKGROUND_TASKS;
//restart if it failed in the callback
if (errflag != HAL_OK) {
@@ -274,12 +270,8 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t
// Halt reception
HAL_NVIC_DisableIRQ(self->irq);
- // copy received data
- rx_bytes = ringbuf_count(&self->rbuf);
- rx_bytes = MIN(rx_bytes, len);
- for (uint16_t i = 0; i < rx_bytes; i++) {
- data[i] = ringbuf_get(&self->rbuf);
- }
+ // Copy as much received data as available, up to len bytes.
+ size_t rx_bytes = ringbuf_get_n(&self->ringbuf, data, len);
HAL_NVIC_EnableIRQ(self->irq);
if (rx_bytes == 0) {
@@ -319,7 +311,7 @@ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *handle)
if ((HAL_UART_GetState(handle) & HAL_UART_STATE_BUSY_RX) == HAL_UART_STATE_BUSY_RX) {
return;
}
- ringbuf_put_n(&context->rbuf, &context->rx_char, 1);
+ ringbuf_put_n(&context->ringbuf, &context->rx_char, 1);
errflag = HAL_UART_Receive_IT(handle, &context->rx_char, 1);
return;
@@ -378,13 +370,13 @@ void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeou
}
uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) {
- return ringbuf_count(&self->rbuf);
+ return ringbuf_num_filled(&self->ringbuf);
}
void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) {
// Halt reception
HAL_NVIC_DisableIRQ(self->irq);
- ringbuf_clear(&self->rbuf);
+ ringbuf_clear(&self->ringbuf);
HAL_NVIC_EnableIRQ(self->irq);
}
diff --git a/ports/stm/common-hal/busio/UART.h b/ports/stm/common-hal/busio/UART.h
index 5ac1d352c..d1971ce27 100644
--- a/ports/stm/common-hal/busio/UART.h
+++ b/ports/stm/common-hal/busio/UART.h
@@ -47,7 +47,7 @@ typedef struct {
const mcu_periph_obj_t *tx;
const mcu_periph_obj_t *rx;
- ringbuf_t rbuf;
+ ringbuf_t ringbuf;
uint8_t rx_char;
uint32_t baudrate;
diff --git a/ports/stm/common-hal/microcontroller/Pin.c b/ports/stm/common-hal/microcontroller/Pin.c
index 5e131c310..610213497 100644
--- a/ports/stm/common-hal/microcontroller/Pin.c
+++ b/ports/stm/common-hal/microcontroller/Pin.c
@@ -134,3 +134,15 @@ GPIO_TypeDef * pin_port(uint8_t pin_port) {
uint16_t pin_mask(uint8_t pin_number) {
return 1<<pin_number;
}
+
+uint8_t common_hal_mcu_pin_number(const mcu_pin_obj_t* pin) {
+ return pin->port * 16 + pin->number;
+}
+
+void common_hal_mcu_pin_claim(const mcu_pin_obj_t* pin) {
+ claim_pin(pin);
+}
+
+void common_hal_mcu_pin_reset_number(uint8_t pin_no) {
+ reset_pin_number(pin_no / 16, pin_no % 16);
+}
diff --git a/ports/stm/common-hal/rgbmatrix/RGBMatrix.c b/ports/stm/common-hal/rgbmatrix/RGBMatrix.c
new file mode 100644
index 000000000..9e60cc3e6
--- /dev/null
+++ b/ports/stm/common-hal/rgbmatrix/RGBMatrix.c
@@ -0,0 +1,54 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020 Jeff Epler for Adafruit Industries
+ *
+ * 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.
+ */
+
+#include <stddef.h>
+
+#include "common-hal/rgbmatrix/RGBMatrix.h"
+
+#include STM32_HAL_H
+
+extern void _PM_IRQ_HANDLER(void);
+
+void *common_hal_rgbmatrix_timer_allocate() {
+ // TODO(jepler) properly handle resource allocation including never-reset
+ return TIM6;
+}
+
+
+void common_hal_rgbmatrix_timer_enable(void* ptr) {
+ HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);
+}
+
+void common_hal_rgbmatrix_timer_disable(void* ptr) {
+ TIM_TypeDef *tim = (TIM_TypeDef*)ptr;
+ tim->DIER &= ~TIM_DIER_UIE;
+ HAL_NVIC_DisableIRQ(TIM6_DAC_IRQn);
+}
+
+void common_hal_rgbmatrix_timer_free(void* ptr) {
+ common_hal_rgbmatrix_timer_disable(ptr);
+ // TODO(jepler) properly handle resource allocation including never-reset
+}
diff --git a/ports/stm/common-hal/rgbmatrix/RGBMatrix.h b/ports/stm/common-hal/rgbmatrix/RGBMatrix.h
new file mode 100644
index 000000000..48de4dcb2
--- /dev/null
+++ b/ports/stm/common-hal/rgbmatrix/RGBMatrix.h
@@ -0,0 +1,35 @@
+/*
+ * This file is part of the Micro Python project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2020 Jeff Epler for Adafruit Industries
+ *
+ * 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.
+ */
+
+#ifndef MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_RGBMATRIX_RGBMATRIX_H
+#define MICROPY_INCLUDED_ATMEL_SAMD_COMMON_HAL_RGBMATRIX_RGBMATRIX_H
+
+void *common_hal_rgbmatrix_timer_allocate(void);
+void common_hal_rgbmatrix_timer_enable(void*);
+void common_hal_rgbmatrix_timer_disable(void*);
+void common_hal_rgbmatrix_timer_free(void*);
+
+#endif
diff --git a/ports/stm/common-hal/rgbmatrix/__init__.c b/ports/stm/common-hal/rgbmatrix/__init__.c
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/ports/stm/common-hal/rgbmatrix/__init__.c
diff --git a/ports/stm/common-hal/rgbmatrix/__init__.h b/ports/stm/common-hal/rgbmatrix/__init__.h
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/ports/stm/common-hal/rgbmatrix/__init__.h
diff --git a/ports/stm/mpconfigport.mk b/ports/stm/mpconfigport.mk
index ee8b2e160..0c5247d95 100644
--- a/ports/stm/mpconfigport.mk
+++ b/ports/stm/mpconfigport.mk
@@ -3,6 +3,11 @@ LONGINT_IMPL = MPZ
INTERNAL_LIBM = 1
USB_SERIAL_NUMBER_LENGTH = 24
+ifeq ($(MCU_VARIANT),STM32F405xx)
+ CIRCUITPY_FRAMEBUFFERIO = 1
+ CIRCUITPY_RGBMATRIX = 1
+endif
+
ifeq ($(MCU_SERIES),F4)
# Not yet implemented common-hal modules:
CIRCUITPY_AUDIOBUSIO = 0
@@ -23,7 +28,6 @@ ifeq ($(MCU_SERIES),H7)
CIRCUITPY_ANALOGIO = 0
CIRCUITPY_NEOPIXEL_WRITE = 0
CIRCUITPY_PULSEIO = 0
- CIRCUITPY_OS = 1
CIRCUITPY_NVM = 0
CIRCUITPY_AUDIOBUSIO = 0
CIRCUITPY_AUDIOIO = 0
@@ -32,18 +36,12 @@ ifeq ($(MCU_SERIES),H7)
CIRCUITPY_RTC = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_I2CSLAVE = 0
- # shared-module modules that still need prerequisites filled
- CIRCUITPY_DISPLAYIO = 0 # Requires SPI, PulseIO, and common-hal module (stub ok)
- CIRCUITPY_RANDOM = 0 # Requires OS
- CIRCUITPY_STORAGE = 0 # Requires OS, filesystem
endif
ifeq ($(MCU_SERIES),F7)
# Not yet implemented common-hal modules:
CIRCUITPY_ANALOGIO = 0
CIRCUITPY_NEOPIXEL_WRITE = 0
- CIRCUITPY_PULSEIO = 1
- CIRCUITPY_OS = 1
CIRCUITPY_NVM = 0
CIRCUITPY_AUDIOBUSIO = 0
CIRCUITPY_AUDIOIO = 0
@@ -52,8 +50,4 @@ ifeq ($(MCU_SERIES),F7)
CIRCUITPY_RTC = 0
CIRCUITPY_FREQUENCYIO = 0
CIRCUITPY_I2CSLAVE = 0
- # shared-module modules that still need prerequisites filled
- CIRCUITPY_DISPLAYIO = 0 # Requires SPI, PulseIO, and common-hal module (stub ok)
- CIRCUITPY_RANDOM = 0 # Requires OS
- CIRCUITPY_STORAGE = 0 # Requires OS, filesystem
endif
diff --git a/ports/stm/supervisor/internal_flash.h b/ports/stm/supervisor/internal_flash.h
index 97626f9f4..b4d07ff48 100644
--- a/ports/stm/supervisor/internal_flash.h
+++ b/ports/stm/supervisor/internal_flash.h
@@ -83,7 +83,7 @@
#ifdef STM32H743xx
#define STM32_FLASH_SIZE 0x200000 //2MB
-#define INTERNAL_FLASH_FILESYSTEM_SIZE 0x20000 //128KiB
+#define INTERNAL_FLASH_FILESYSTEM_SIZE 0x60000 //384KiB
#define INTERNAL_FLASH_FILESYSTEM_START_ADDR 0x08020000
#endif
diff --git a/ports/stm/supervisor/port.c b/ports/stm/supervisor/port.c
index 779348c02..23ba7d874 100644
--- a/ports/stm/supervisor/port.c
+++ b/ports/stm/supervisor/port.c
@@ -49,7 +49,7 @@
#include STM32_HAL_H
//only enable the Reset Handler overwrite for the H7 for now
-#if defined(STM32H7)
+#if (CPY_STM32H7)
// Device memories must be accessed in order.
#define DEVICE 2
@@ -153,16 +153,16 @@ __attribute__((used, naked)) void Reset_Handler(void) {
static RTC_HandleTypeDef _hrtc;
#if BOARD_HAS_LOW_SPEED_CRYSTAL
-#define RTC_CLOCK_FREQUENCY LSE_VALUE
+static uint32_t rtc_clock_frequency = LSE_VALUE;
#else
-#define RTC_CLOCK_FREQUENCY LSI_VALUE
+static uint32_t rtc_clock_frequency = LSI_VALUE;
#endif
safe_mode_t port_init(void) {
HAL_Init();
__HAL_RCC_SYSCFG_CLK_ENABLE();
- #if defined(STM32F4)
+ #if (CPY_STM32F4)
__HAL_RCC_PWR_CLK_ENABLE();
#endif
@@ -170,24 +170,70 @@ safe_mode_t port_init(void) {
stm32_peripherals_gpio_init();
HAL_PWR_EnableBkUpAccess();
+
+ // TODO: move all of this to clocks.c
#if BOARD_HAS_LOW_SPEED_CRYSTAL
- __HAL_RCC_LSE_CONFIG(RCC_LSE_ON);
- while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) {}
+ uint32_t tickstart = HAL_GetTick();
+
+ // H7/F7 untested with LSE, so autofail them until above move is done
+ #if (CPY_STM32F4)
+ bool lse_setupsuccess = true;
#else
- __HAL_RCC_LSI_ENABLE();
+ bool lse_setupsuccess = false;
#endif
- #if BOARD_HAS_LOW_SPEED_CRYSTAL
- __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSE);
+
+ // Update LSE configuration in Backup Domain control register
+ // Requires to enable write access to Backup Domain of necessary
+ // TODO: should be using the HAL OSC initializer, otherwise we'll need
+ // preprocessor defines for every register to account for F7/H7
+ #if (CPY_STM32F4)
+ if(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
+ {
+ // Enable write access to Backup domain
+ SET_BIT(PWR->CR, PWR_CR_DBP);
+ // Wait for Backup domain Write protection disable
+ tickstart = HAL_GetTick();
+ while(HAL_IS_BIT_CLR(PWR->CR, PWR_CR_DBP))
+ {
+ if((HAL_GetTick() - tickstart) > RCC_DBP_TIMEOUT_VALUE)
+ {
+ lse_setupsuccess = false;
+ }
+ }
+ }
+ #endif
+
+ __HAL_RCC_LSE_CONFIG(RCC_LSE_ON);
+ tickstart = HAL_GetTick();
+ while(__HAL_RCC_GET_FLAG(RCC_FLAG_LSERDY) == RESET) {
+ if((HAL_GetTick() - tickstart ) > LSE_STARTUP_TIMEOUT)
+ {
+ lse_setupsuccess = false;
+ __HAL_RCC_LSE_CONFIG(RCC_LSE_OFF);
+ __HAL_RCC_LSI_ENABLE();
+ rtc_clock_frequency = LSI_VALUE;
+ break;
+ }
+ }
+
+ if (lse_setupsuccess) {
+ __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSE);
+ } else {
+ __HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSI);
+ }
+
#else
+ __HAL_RCC_LSI_ENABLE();
__HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSI);
#endif
+
__HAL_RCC_RTC_ENABLE();
_hrtc.Instance = RTC;
_hrtc.Init.HourFormat = RTC_HOURFORMAT_24;
- // Divide async as little as possible so that we have RTC_CLOCK_FREQUENCY count in subseconds.
+ // Divide async as little as possible so that we have rtc_clock_frequency count in subseconds.
// This ensures our timing > 1 second is correct.
_hrtc.Init.AsynchPrediv = 0x0;
- _hrtc.Init.SynchPrediv = RTC_CLOCK_FREQUENCY - 1;
+ _hrtc.Init.SynchPrediv = rtc_clock_frequency - 1;
_hrtc.Init.OutPut = RTC_OUTPUT_DISABLE;
HAL_RTC_Init(&_hrtc);
@@ -293,7 +339,7 @@ volatile uint32_t cached_date = 0;
volatile uint32_t seconds_to_minute = 0;
volatile uint32_t cached_hours_minutes = 0;
uint64_t port_get_raw_ticks(uint8_t* subticks) {
- uint32_t subseconds = RTC_CLOCK_FREQUENCY - (uint32_t)(RTC->SSR);
+ uint32_t subseconds = rtc_clock_frequency - (uint32_t)(RTC->SSR);
uint32_t time = (uint32_t)(RTC->TR & RTC_TR_RESERVED_MASK);
uint32_t date = (uint32_t)(RTC->DR & RTC_DR_RESERVED_MASK);
if (date != cached_date) {
@@ -341,7 +387,7 @@ void RTC_Alarm_IRQHandler(void) {
// Enable 1/1024 second tick.
void port_enable_tick(void) {
- HAL_RTCEx_SetWakeUpTimer_IT(&_hrtc, RTC_CLOCK_FREQUENCY / 1024 / 2, RTC_WAKEUPCLOCK_RTCCLK_DIV2);
+ HAL_RTCEx_SetWakeUpTimer_IT(&_hrtc, rtc_clock_frequency / 1024 / 2, RTC_WAKEUPCLOCK_RTCCLK_DIV2);
HAL_NVIC_SetPriority(RTC_WKUP_IRQn, 1, 0U);
HAL_NVIC_EnableIRQ(RTC_WKUP_IRQn);
}
@@ -372,7 +418,7 @@ void port_interrupt_after_ticks(uint32_t ticks) {
alarm.AlarmMask = RTC_ALARMMASK_ALL;
}
- alarm.AlarmTime.SubSeconds = RTC_CLOCK_FREQUENCY -
+ alarm.AlarmTime.SubSeconds = rtc_clock_frequency -
((raw_ticks % 1024) * 32);
alarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;
alarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_SET;