Skip to content

SPIM3 buffer must be in first 64kB of RAM #3281

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions ports/nrf/boards/arduino_nano_33_ble/mpconfigboard.mk
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,3 @@ USB_MANUFACTURER = "Arduino"
MCU_CHIP = nrf52840

INTERNAL_FLASH_FILESYSTEM = 1

# Allocate two, not just one I2C peripheral, 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
6 changes: 0 additions & 6 deletions ports/nrf/boards/circuitplayground_bluefruit/mpconfigboard.mk
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,3 @@ MCU_CHIP = nrf52840
QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 1
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.
# 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
35 changes: 19 additions & 16 deletions ports/nrf/boards/common.template.ld
Original file line number Diff line number Diff line change
Expand Up @@ -18,30 +18,33 @@ MEMORY
FLASH_BOOTLOADER_SETTINGS (r) : ORIGIN = ${BOOTLOADER_SETTINGS_START_ADDR}, LENGTH = ${BOOTLOADER_SETTINGS_SIZE}


/* 0x2000000 - RAM:ORIGIN is reserved for Softdevice */
/* SoftDevice 6.1.0 with 5 connections and various increases takes just under 64kiB.
/* To measure the minimum required amount of memory for given configuration, set this number
high enough to work and then check the mutation of the value done by sd_ble_enable. */
SPIM3_RAM (rw) : ORIGIN = 0x20000000 + ${SOFTDEVICE_RAM_SIZE}, LENGTH = ${SPIM3_BUFFER_SIZE}
RAM (xrw) : ORIGIN = 0x20000000 + ${SOFTDEVICE_RAM_SIZE} + ${SPIM3_BUFFER_SIZE}, LENGTH = ${RAM_SIZE} - ${SOFTDEVICE_RAM_SIZE} -${SPIM3_BUFFER_SIZE}

/* SoftDevice RAM must start at the beginning of RAM: 0x2000000 (RAM_START_ADDR).
On nRF52840, the first 64kB of RAM is composed of 8 8kB RAM blocks. Above those is
RAM block 8, which is 192kB.
If SPIM3_BUFFER_RAM_SIZE is 8kB, as opposed to zero, it must be in the first 64kB of RAM.
So the amount of RAM reserved for the SoftDevice must be no more than 56kB.
*/
RAM (xrw) : ORIGIN = ${RAM_START_ADDR}, LENGTH = ${RAM_SIZE}
SD_RAM (rw) : ORIGIN = ${SOFTDEVICE_RAM_START_ADDR}, LENGTH = ${SOFTDEVICE_RAM_SIZE}
SPIM3_RAM (rw) : ORIGIN = ${SPIM3_BUFFER_RAM_START_ADDR}, LENGTH = ${SPIM3_BUFFER_RAM_SIZE}
APP_RAM (xrw) : ORIGIN = ${APP_RAM_START_ADDR}, LENGTH = ${APP_RAM_SIZE}
}

/* produce a link error if there is not this amount of RAM available */
_minimum_heap_size = 0;

/* top end of the stack */

/*_stack_end = ORIGIN(RAM) + LENGTH(RAM);*/
_estack = ORIGIN(RAM) + LENGTH(RAM);
/*_stack_end = ORIGIN(APP_RAM) + LENGTH(APP_RAM);*/
_estack = ORIGIN(APP_RAM) + LENGTH(APP_RAM);

/* RAM extents for the garbage collector */
_ram_end = ORIGIN(RAM) + LENGTH(RAM);
_ram_end = ORIGIN(APP_RAM) + LENGTH(APP_RAM);
_heap_end = 0x20020000; /* tunable */

/* nrf52840 SPIM3 needs its own area to work around hardware problems. Nothing else may use this space. */
_spim3_ram = ORIGIN(SPIM3_RAM);
_spim3_ram_end = ORIGIN(SPIM3_RAM) + LENGTH(RAM);
_spim3_ram_end = ORIGIN(SPIM3_RAM) + LENGTH(SPIM3_RAM);

/* define output sections */
SECTIONS
Expand Down Expand Up @@ -87,7 +90,7 @@ SECTIONS

. = ALIGN(4);
_edata = .; /* define a global symbol at data end; used by startup code in order to initialise the .data section in RAM */
} >RAM
} >APP_RAM

/* Zero-initialized data section */
.bss :
Expand All @@ -100,7 +103,7 @@ SECTIONS

. = ALIGN(4);
_ebss = .; /* define a global symbol at bss end; used by startup code and GC */
} >RAM
} >APP_RAM

/* Uninitialized data section
Data placed into this section will remain unchanged across reboots. */
Expand All @@ -113,7 +116,7 @@ SECTIONS

. = ALIGN(4);
_euninitialized = .; /* define a global symbol at uninitialized end; currently unused */
} >RAM
} >APP_RAM

/* this is to define the start of the heap, and make sure we have a minimum size */
.heap :
Expand All @@ -123,15 +126,15 @@ SECTIONS
PROVIDE ( _end = . );
_heap_start = .; /* define a global symbol at heap start */
. = . + _minimum_heap_size;
} >RAM
} >APP_RAM

/* this just checks there is enough RAM for the stack */
.stack :
{
. = ALIGN(4);
. = . + ${CIRCUITPY_DEFAULT_STACK_SIZE};
. = ALIGN(4);
} >RAM
} >APP_RAM

/* Remove exception unwinding information, since Circuit Python
does not support this GCC feature. */
Expand Down
7 changes: 0 additions & 7 deletions ports/nrf/boards/hiibot_bluefi/mpconfigboard.mk
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,3 @@ MCU_CHIP = nrf52840
QSPI_FLASH_FILESYSTEM = 1
EXTERNAL_FLASH_DEVICE_COUNT = 1
EXTERNAL_FLASH_DEVICES = "W25Q16JV_IQ"

# Allocate two, not just one I2C peripheral for Bluefi, 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
2 changes: 2 additions & 0 deletions ports/nrf/boards/pca10100/mpconfigboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,3 +46,5 @@
#define BLEIO_PERIPH_ROLE_COUNT 2
#define BLEIO_TOTAL_CONNECTION_COUNT 2
#define BLEIO_ATTR_TAB_SIZE (BLE_GATTS_ATTR_TAB_SIZE_DEFAULT * 2)

#define SOFTDEVICE_RAM_SIZE (32*1024)
4 changes: 0 additions & 4 deletions ports/nrf/boards/pca10100/mpconfigboard.mk
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,5 @@ CIRCUITPY_ULAB = 0

SUPEROPT_GC = 0

# These defines must be overridden before mpconfigboard.h is included, which is
# why they are passed on the command line.
CFLAGS += -DSPIM3_BUFFER_SIZE=0 -DSOFTDEVICE_RAM_SIZE='(32*1024)'

# Override optimization to keep binary small
OPTIMIZATION_FLAGS = -Os
2 changes: 2 additions & 0 deletions ports/nrf/boards/simmel/mpconfigboard.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,5 @@
#define BLEIO_PERIPH_ROLE_COUNT 2
#define BLEIO_TOTAL_CONNECTION_COUNT 2
#define BLEIO_ATTR_TAB_SIZE (BLE_GATTS_ATTR_TAB_SIZE_DEFAULT * 2)

#define SOFTDEVICE_RAM_SIZE (32*1024)
4 changes: 0 additions & 4 deletions ports/nrf/boards/simmel/mpconfigboard.mk
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,5 @@ CIRCUITPY_WATCHDOG = 1
# Enable micropython.native
#CIRCUITPY_ENABLE_MPY_NATIVE = 1

# These defines must be overridden before mpconfigboard.h is included, which is
# why they are passed on the command line.
CFLAGS += -DSPIM3_BUFFER_SIZE=0 -DSOFTDEVICE_RAM_SIZE='(32*1024)' -DNRFX_SPIM3_ENABLED=0

# Override optimization to keep binary small
OPTIMIZATION_FLAGS = -Os
28 changes: 15 additions & 13 deletions ports/nrf/common-hal/_bleio/Adapter.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
#endif

#ifndef BLEIO_HVN_TX_QUEUE_SIZE
#define BLEIO_HVN_TX_QUEUE_SIZE 9
#define BLEIO_HVN_TX_QUEUE_SIZE 5
#endif

#ifndef BLEIO_CENTRAL_ROLE_COUNT
Expand Down Expand Up @@ -120,11 +120,11 @@ STATIC uint32_t ble_stack_enable(void) {
// Start with no event handlers, etc.
ble_drv_reset();

// Set everything up to have one persistent code editing connection and one user managed
// connection. In the future we could move .data and .bss to the other side of the stack and
// In the future we might move .data and .bss to the other side of the stack and
// dynamically adjust for different memory requirements of the SD based on boot.py
// configuration.
uint32_t app_ram_start = (uint32_t) &_ram_start;
// configuration. But we still need to keep the SPIM3 buffer (if needed) in the first 64kB of RAM.

uint32_t sd_ram_end = SOFTDEVICE_RAM_START_ADDR + SOFTDEVICE_RAM_SIZE;

ble_cfg_t ble_conf;
ble_conf.conn_cfg.conn_cfg_tag = BLE_CONN_CFG_TAG_CUSTOM;
Expand All @@ -135,7 +135,7 @@ STATIC uint32_t ble_stack_enable(void) {
// Event length here can influence throughput so perhaps make multiple connection profiles
// available.
ble_conf.conn_cfg.params.gap_conn_cfg.event_length = BLE_GAP_EVENT_LENGTH_DEFAULT;
err_code = sd_ble_cfg_set(BLE_CONN_CFG_GAP, &ble_conf, app_ram_start);
err_code = sd_ble_cfg_set(BLE_CONN_CFG_GAP, &ble_conf, sd_ram_end);
if (err_code != NRF_SUCCESS) {
return err_code;
}
Expand All @@ -147,7 +147,7 @@ STATIC uint32_t ble_stack_enable(void) {
ble_conf.gap_cfg.role_count_cfg.periph_role_count = BLEIO_PERIPH_ROLE_COUNT;
// central_role_count costs 648 bytes for 1 to 2, then ~1250 for each further increment.
ble_conf.gap_cfg.role_count_cfg.central_role_count = BLEIO_CENTRAL_ROLE_COUNT;
err_code = sd_ble_cfg_set(BLE_GAP_CFG_ROLE_COUNT, &ble_conf, app_ram_start);
err_code = sd_ble_cfg_set(BLE_GAP_CFG_ROLE_COUNT, &ble_conf, sd_ram_end);
if (err_code != NRF_SUCCESS) {
return err_code;
}
Expand All @@ -158,7 +158,7 @@ STATIC uint32_t ble_stack_enable(void) {
// DevZone recommends not setting this directly, but instead changing gap_conn_cfg.event_length.
// However, we are setting connection extension, so this seems to make sense.
ble_conf.conn_cfg.params.gatts_conn_cfg.hvn_tx_queue_size = BLEIO_HVN_TX_QUEUE_SIZE;
err_code = sd_ble_cfg_set(BLE_CONN_CFG_GATTS, &ble_conf, app_ram_start);
err_code = sd_ble_cfg_set(BLE_CONN_CFG_GATTS, &ble_conf, sd_ram_end);
if (err_code != NRF_SUCCESS) {
return err_code;
}
Expand All @@ -167,7 +167,7 @@ STATIC uint32_t ble_stack_enable(void) {
memset(&ble_conf, 0, sizeof(ble_conf));
ble_conf.conn_cfg.conn_cfg_tag = BLE_CONN_CFG_TAG_CUSTOM;
ble_conf.conn_cfg.params.gatt_conn_cfg.att_mtu = BLE_GATTS_VAR_ATTR_LEN_MAX;
err_code = sd_ble_cfg_set(BLE_CONN_CFG_GATT, &ble_conf, app_ram_start);
err_code = sd_ble_cfg_set(BLE_CONN_CFG_GATT, &ble_conf, sd_ram_end);
if (err_code != NRF_SUCCESS) {
return err_code;
}
Expand All @@ -177,7 +177,7 @@ STATIC uint32_t ble_stack_enable(void) {
memset(&ble_conf, 0, sizeof(ble_conf));
// Each increment to the BLE_GATTS_ATTR_TAB_SIZE_DEFAULT multiplier costs 1408 bytes.
ble_conf.gatts_cfg.attr_tab_size.attr_tab_size = BLEIO_ATTR_TAB_SIZE;
err_code = sd_ble_cfg_set(BLE_GATTS_CFG_ATTR_TAB_SIZE, &ble_conf, app_ram_start);
err_code = sd_ble_cfg_set(BLE_GATTS_CFG_ATTR_TAB_SIZE, &ble_conf, sd_ram_end);
if (err_code != NRF_SUCCESS) {
return err_code;
}
Expand All @@ -187,13 +187,15 @@ STATIC uint32_t ble_stack_enable(void) {
memset(&ble_conf, 0, sizeof(ble_conf));
// Each additional vs_uuid_count costs 16 bytes.
ble_conf.common_cfg.vs_uuid_cfg.vs_uuid_count = BLEIO_VS_UUID_COUNT; // Defaults to 10.
err_code = sd_ble_cfg_set(BLE_COMMON_CFG_VS_UUID, &ble_conf, app_ram_start);
err_code = sd_ble_cfg_set(BLE_COMMON_CFG_VS_UUID, &ble_conf, sd_ram_end);
if (err_code != NRF_SUCCESS) {
return err_code;
}

// This sets app_ram_start to the minimum value needed for the settings set above.
err_code = sd_ble_enable(&app_ram_start);
// This sets sd_ram_end to the minimum value needed for the settings set above.
// You can set a breakpoint just after this call and examine sd_ram_end to see
// how much RAM the SD needs with the configuration above.
err_code = sd_ble_enable(&sd_ram_end);
if (err_code != NRF_SUCCESS) {
return err_code;
}
Expand Down
5 changes: 2 additions & 3 deletions ports/nrf/common-hal/busio/SPI.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ STATIC spim_peripheral_t spim_peripherals[] = {
// Allocate SPIM3 first.
{ .spim = NRFX_SPIM_INSTANCE(3),
.max_frequency = 32000000,
.max_xfer_size = MIN(SPIM3_BUFFER_SIZE, (1UL << SPIM3_EASYDMA_MAXCNT_SIZE) - 1)
.max_xfer_size = MIN(SPIM3_BUFFER_RAM_SIZE, (1UL << SPIM3_EASYDMA_MAXCNT_SIZE) - 1)
},
#endif
#if NRFX_CHECK(NRFX_SPIM2_ENABLED)
Expand Down Expand Up @@ -71,8 +71,7 @@ STATIC bool never_reset[MP_ARRAY_SIZE(spim_peripherals)];

// Separate RAM area for SPIM3 transmit buffer to avoid SPIM3 hardware errata.
// https://infocenter.nordicsemi.com/index.jsp?topic=%2Ferrata_nRF52840_Rev2%2FERR%2FnRF52840%2FRev2%2Flatest%2Fanomaly_840_198.html
extern uint32_t _spim3_ram;
STATIC uint8_t *spim3_transmit_buffer = (uint8_t *) &_spim3_ram;
STATIC uint8_t *spim3_transmit_buffer = (uint8_t *) SPIM3_BUFFER_RAM_START_ADDR;

void spi_reset(void) {
for (size_t i = 0 ; i < MP_ARRAY_SIZE(spim_peripherals); i++) {
Expand Down
9 changes: 8 additions & 1 deletion ports/nrf/ld_defines.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
// START_LD_DEFINES

/*FLASH_SIZE=*/ FLASH_SIZE;
/*RAM_START_ADDR=*/ RAM_START_ADDR;
/*RAM_SIZE=*/ RAM_SIZE;

/*MBR_START_ADDR=*/ MBR_START_ADDR;
Expand Down Expand Up @@ -41,5 +42,11 @@
/*BOOTLOADER_SETTINGS_START_ADDR=*/ BOOTLOADER_SETTINGS_START_ADDR;
/*BOOTLOADER_SETTINGS_SIZE=*/ BOOTLOADER_SETTINGS_SIZE;

/*SOFTDEVICE_RAM_START_ADDR=*/ SOFTDEVICE_RAM_START_ADDR;
/*SOFTDEVICE_RAM_SIZE=*/ SOFTDEVICE_RAM_SIZE;
/*SPIM3_BUFFER_SIZE=*/ SPIM3_BUFFER_SIZE;

/*SPIM3_BUFFER_RAM_START_ADDR=*/ SPIM3_BUFFER_RAM_START_ADDR;
/*SPIM3_BUFFER_RAM_SIZE=*/ SPIM3_BUFFER_RAM_SIZE;

/*APP_RAM_START_ADDR=*/ APP_RAM_START_ADDR;
/*APP_RAM_SIZE=*/ APP_RAM_SIZE;
Loading