Skip to content

Instantly share code, notes, and snippets.

@fanoush
Last active April 12, 2021 13:27
Show Gist options
  • Save fanoush/74c17abed6cfc809d153d76b6752e1f1 to your computer and use it in GitHub Desktop.
Save fanoush/74c17abed6cfc809d153d76b6752e1f1 to your computer and use it in GitHub Desktop.
make MTU configurable , needs in board file something like 'DEFINES+=-DNRF_BLE_GATT_MAX_MTU_SIZE=59 -DNRF_BLE_MAX_MTU_SIZE=59', 'LDFLAGS += -Xlinker --defsym=LD_APP_RAM_BASE=0x2d18',
diff --git a/src/jswrap_process.c b/src/jswrap_process.c
index f6c738c3..21470116 100644
--- a/src/jswrap_process.c
+++ b/src/jswrap_process.c
@@ -126,6 +126,9 @@ JsVar *jswrap_process_env() {
#ifndef SAVE_ON_FLASH
// Pointer to a list of predefined exports - eventually we'll get rid of the array above
jsvObjectSetChildAndUnLock(obj, "EXPTR", jsvNewFromInteger((JsVarInt)(size_t)exportPtrs));
+extern uint32_t app_ram_base;
+ jsvObjectSetChildAndUnLock(obj, "APP_RAM_BASE", jsvNewFromInteger((JsVarInt)app_ram_base));
+
#endif
return obj;
}
diff --git a/targetlibs/nrf5x_12/components/ble/ble_services/ble_nus/ble_nus.h b/targetlibs/nrf5x_12/components/ble/ble_services/ble_nus/ble_nus.h
index aeda92f3..536aad46 100644
--- a/targetlibs/nrf5x_12/components/ble/ble_services/ble_nus/ble_nus.h
+++ b/targetlibs/nrf5x_12/components/ble/ble_services/ble_nus/ble_nus.h
@@ -70,7 +70,11 @@ extern "C" {
#endif
#define BLE_UUID_NUS_SERVICE 0x0001 /**< The UUID of the Nordic UART Service. */
+#ifdef NRF_BLE_MAX_MTU_SIZE
+#define BLE_NUS_MAX_DATA_LEN (NRF_BLE_MAX_MTU_SIZE - 3) /**< Maximum length of data (in bytes) that can be transmitted to the peer by the Nordic UART service module. */
+#else
#define BLE_NUS_MAX_DATA_LEN (GATT_MTU_SIZE_DEFAULT - 3) /**< Maximum length of data (in bytes) that can be transmitted to the peer by the Nordic UART service module. */
+#endif
/* Forward declaration of the ble_nus_t type. */
typedef struct ble_nus_s ble_nus_t;
diff --git a/targetlibs/nrf5x_12/nrf5x_linkers/linker_nrf52_ble_espruino.ld b/targetlibs/nrf5x_12/nrf5x_linkers/linker_nrf52_ble_espruino.ld
index 7e0ef8a6..e1fa87c0 100644
--- a/targetlibs/nrf5x_12/nrf5x_linkers/linker_nrf52_ble_espruino.ld
+++ b/targetlibs/nrf5x_12/nrf5x_linkers/linker_nrf52_ble_espruino.ld
@@ -4,7 +4,7 @@ SEARCH_DIR(.)
GROUP(-lgcc -lc -lnosys)
MEM_SRAM_SIZE = DEFINED( LD_SRAM_SIZE ) ? LD_SRAM_SIZE : 0x10000 ;
-MEM_SRAM_SD_OFFSET = 0x2c40; /* memory allocated for SoftDevice */
+MEM_SRAM_SD_OFFSET = DEFINED( LD_APP_RAM_BASE ) ? LD_APP_RAM_BASE :0x2c40; /* memory allocated for SoftDevice */
MEM_NOINIT_SIZE = 16;
MEMORY
diff --git a/targetlibs/nrf5x_12/nrf5x_linkers/linker_nrf52_ble_espruino_bootloader.ld b/targetlibs/nrf5x_12/nrf5x_linkers/linker_nrf52_ble_espruino_bootloader.ld
index b65ca893..3ca2c35f 100644
--- a/targetlibs/nrf5x_12/nrf5x_linkers/linker_nrf52_ble_espruino_bootloader.ld
+++ b/targetlibs/nrf5x_12/nrf5x_linkers/linker_nrf52_ble_espruino_bootloader.ld
@@ -3,11 +3,15 @@
SEARCH_DIR(.)
GROUP(-lgcc -lc -lnosys)
+MEM_SRAM_SIZE = DEFINED( LD_SRAM_SIZE ) ? LD_SRAM_SIZE : 0x10000 ;
+MEM_SRAM_SD_OFFSET = DEFINED( LD_APP_RAM_BASE ) ? LD_APP_RAM_BASE :0x2c40; /* memory allocated for SoftDevice */
+MEM_NOINIT_SIZE = 16;
+
MEMORY
{
FLASH (rx) : ORIGIN = 0x1f000, LENGTH = 0x55000 /* 0x77000 and above is reserved for the bootloader+fs, then there's saved JS code. see Makefile, secure_dfu_gcc_nrf52.ld, linker_nrf52_ble_espruino_bootloader.ld and dfu_types.h, BOARD.py */
- RAM (rwx) : ORIGIN = 0x20002c40, LENGTH = 0xd3b0
- NOINIT (rwx) : ORIGIN = 0x2000fff0, LENGTH = 16
+ RAM (rwx) : ORIGIN = 0x20000000 + MEM_SRAM_SD_OFFSET, LENGTH = MEM_SRAM_SIZE - MEM_SRAM_SD_OFFSET - MEM_NOINIT_SIZE
+ NOINIT (rwx) : ORIGIN = 0x20000000 + MEM_SRAM_SIZE - MEM_NOINIT_SIZE , LENGTH = MEM_NOINIT_SIZE
}
SECTIONS
diff --git a/targetlibs/nrf5x_15/nrf5x_linkers/linker_nrf52840_ble_espruino.ld b/targetlibs/nrf5x_15/nrf5x_linkers/linker_nrf52840_ble_espruino.ld
index 36b05619..258c6ffd 100644
--- a/targetlibs/nrf5x_15/nrf5x_linkers/linker_nrf52840_ble_espruino.ld
+++ b/targetlibs/nrf5x_15/nrf5x_linkers/linker_nrf52840_ble_espruino.ld
@@ -3,15 +3,15 @@
SEARCH_DIR(.)
GROUP(-lgcc -lc -lnosys)
+MEM_SRAM_SIZE = DEFINED( LD_SRAM_SIZE ) ? LD_SRAM_SIZE : 0x40000 ;
+MEM_SRAM_SD_OFFSET = DEFINED( LD_APP_RAM_BASE ) ? LD_APP_RAM_BASE :0x3c8d0; /* FIXME - can do way less */ /* memory allocated for SoftDevice */
+MEM_NOINIT_SIZE = 24;
+
MEMORY
{
FLASH (rx) : ORIGIN = 0x26000, LENGTH = 0xda000
- RAM (rwx) : ORIGIN = 0x20003720, LENGTH = 0x3c8d0 /* FIXME - can do way less */
- NOINIT (rwx) : ORIGIN = 0x2003fff0, LENGTH = 16
-}
-
-SECTIONS
-{
+ RAM (rwx) : ORIGIN = 0x20000000 + MEM_SRAM_SD_OFFSET, LENGTH = MEM_SRAM_SIZE - MEM_SRAM_SD_OFFSET - MEM_NOINIT_SIZE
+ NOINIT (rwx) : ORIGIN = 0x20000000 + MEM_SRAM_SIZE - MEM_NOINIT_SIZE , LENGTH = MEM_NOINIT_SIZE
}
SECTIONS
diff --git a/targets/nrf5x/bluetooth.c b/targets/nrf5x/bluetooth.c
index 27df1212..b9b2067b 100644
--- a/targets/nrf5x/bluetooth.c
+++ b/targets/nrf5x/bluetooth.c
@@ -97,11 +97,16 @@ __ALIGN(4) static ble_gap_lesc_dhkey_t m_lesc_dhkey; /**< LESC ECC DH Key*/
// -----------------------------------------------------------------------------------
#if NRF_SD_BLE_API_VERSION < 5
+#ifndef NRF_BLE_MAX_MTU_SIZE
#define NRF_BLE_MAX_MTU_SIZE GATT_MTU_SIZE_DEFAULT /**< MTU size used in the softdevice enabling and to reply to a BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST event. */
+#endif
#define FIRST_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(100, APP_TIMER_PRESCALER) /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (5 seconds). */
#define NEXT_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(10000, APP_TIMER_PRESCALER) /**< Time between each call to sd_ble_gap_conn_param_update after the first call (30 seconds). */
#define MAX_CONN_PARAMS_UPDATE_COUNT 3 /**< Number of attempts before giving up the connection parameter negotiation. */
#else
+#ifndef GATT_MTU_SIZE_DEFAULT
+#define GATT_MTU_SIZE_DEFAULT BLE_GATT_ATT_MTU_DEFAULT
+#endif
#define NRF_BLE_MAX_MTU_SIZE NRF_SDH_BLE_GATT_MAX_MTU_SIZE /**< MTU size used in the softdevice enabling and to reply to a BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST event. */
#define FIRST_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(100) /**< Time from initiating event (connect or start of notification) to first time sd_ble_gap_conn_param_update is called (5 seconds). */
#define NEXT_CONN_PARAMS_UPDATE_DELAY APP_TIMER_TICKS(10000) /**< Time between each call to sd_ble_gap_conn_param_update after the first call (30 seconds). */
@@ -170,8 +175,10 @@ static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;
#endif
volatile uint16_t m_peripheral_conn_handle = BLE_CONN_HANDLE_INVALID; /**< Handle of the current connection. */
+volatile uint16_t m_peripheral_effective_mtu;
#if CENTRAL_LINK_COUNT>0
volatile uint16_t m_central_conn_handle = BLE_CONN_HANDLE_INVALID; /**< Handle for central mode connection */
+volatile uint16_t m_central_effective_mtu;
#endif
#ifdef USE_NFC
volatile bool nfcEnabled = false;
@@ -965,6 +972,7 @@ void nus_transmit_string() {
* do 5, but it seems some things have issues with
* this (eg nRF cloud gateways) so only send 1 packet
* for now. */
+ int max_data_len = MIN((m_peripheral_effective_mtu-3),BLE_NUS_MAX_DATA_LEN);
for (int packet=0;packet<1;packet++) {
// No data? try and get some from our queue
if (!nuxTxBufLength) {
@@ -972,7 +980,7 @@ void nus_transmit_string() {
int ch = jshGetCharToTransmit(EV_BLUETOOTH);
while (ch>=0) {
nusTxBuf[nuxTxBufLength++] = ch;
- if (nuxTxBufLength>=BLE_NUS_MAX_DATA_LEN) break;
+ if (nuxTxBufLength>=max_data_len) break;
ch = jshGetCharToTransmit(EV_BLUETOOTH);
}
}
@@ -1118,6 +1126,7 @@ static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context) {
case BLE_GAP_EVT_CONNECTED:
if (p_ble_evt->evt.gap_evt.params.connected.role == BLE_GAP_ROLE_PERIPH) {
m_peripheral_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
+ m_peripheral_effective_mtu = GATT_MTU_SIZE_DEFAULT;
#ifdef DYNAMIC_INTERVAL_ADJUSTMENT
bleIdleCounter = 0;
#endif
@@ -1135,6 +1144,13 @@ static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context) {
#if CENTRAL_LINK_COUNT>0
if (p_ble_evt->evt.gap_evt.params.connected.role == BLE_GAP_ROLE_CENTRAL) {
m_central_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
+ m_central_effective_mtu = GATT_MTU_SIZE_DEFAULT;
+#if NRF_SD_BLE_API_VERSION>=3
+#if (NRF_BLE_MAX_MTU_SIZE > GATT_MTU_SIZE_DEFAULT)
+ err_code = sd_ble_gattc_exchange_mtu_request(p_ble_evt->evt.gap_evt.conn_handle, NRF_BLE_MAX_MTU_SIZE);
+ APP_ERROR_CHECK_NOT_URGENT(err_code);
+#endif
+#endif
bleSetActiveBluetoothGattServer(bleTaskInfo);
jsble_queue_pending(BLEP_TASK_CENTRAL_CONNECTED, 0);
}
@@ -1304,7 +1320,47 @@ static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context) {
} break; // BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST
#if (NRF_SD_BLE_API_VERSION >= 3)
+
+ case BLE_GATTC_EVT_EXCHANGE_MTU_RSP: {
+ uint16_t conn_handle = p_ble_evt->evt.gattc_evt.conn_handle;
+ uint16_t effective_mtu = p_ble_evt->evt.gattc_evt.params.exchange_mtu_rsp.server_rx_mtu;
+ effective_mtu = MIN(MAX(GATT_MTU_SIZE_DEFAULT,effective_mtu),NRF_BLE_MAX_MTU_SIZE);
+#if CENTRAL_LINK_COUNT>0
+ if (m_central_conn_handle == conn_handle) {
+ m_central_effective_mtu = effective_mtu;
+#if (NRF_SD_BLE_API_VERSION > 3)
+ if (effective_mtu > GATT_MTU_SIZE_DEFAULT){
+ ble_gap_data_length_params_t const dlp =
+ {
+ .max_rx_octets = effective_mtu + 4,
+ .max_tx_octets = effective_mtu + 4,
+ };
+ err_code = sd_ble_gap_data_length_update(conn_handle, &dlp, NULL);
+ APP_ERROR_CHECK_NOT_URGENT(err_code);
+
+ }
+#endif
+ } else
+#endif
+ if (m_peripheral_conn_handle == conn_handle){
+ m_peripheral_effective_mtu = effective_mtu;
+ }
+ } break; // BLE_GATTC_EVT_EXCHANGE_MTU_RSP
+
+
case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST: {
+ uint16_t conn_handle = p_ble_evt->evt.gatts_evt.conn_handle;
+ uint16_t effective_mtu = p_ble_evt->evt.gatts_evt.params.exchange_mtu_request.client_rx_mtu;
+ effective_mtu = MIN(MAX(GATT_MTU_SIZE_DEFAULT,effective_mtu),NRF_BLE_MAX_MTU_SIZE);
+#if CENTRAL_LINK_COUNT>0
+ if (m_central_conn_handle == conn_handle) {
+ m_central_effective_mtu = effective_mtu;
+ } else
+#endif
+ if (m_peripheral_conn_handle == conn_handle){
+ m_peripheral_effective_mtu = effective_mtu;
+ }
+
err_code = sd_ble_gatts_exchange_mtu_reply(p_ble_evt->evt.gatts_evt.conn_handle,
NRF_BLE_MAX_MTU_SIZE);
// This can return an error when connecting to EQ3 CC-RT-BLE (which requests an MTU of 0!!)
@@ -2246,8 +2302,17 @@ static void services_init() {
#endif
}
+uint32_t app_ram_base;
+
/// Function for the SoftDevice initialization.
static void ble_stack_init() {
+#if defined ( __GNUC__ )
+ extern uint32_t __data_start__;
+ app_ram_base = (uint32_t) &__data_start__;
+#else
+#error "unsupported compiler"
+#endif
+
#if NRF_SD_BLE_API_VERSION<5
uint32_t err_code;
@@ -2289,9 +2354,21 @@ static void ble_stack_init() {
#if (NRF_SD_BLE_API_VERSION >= 3)
ble_enable_params.gatt_enable_params.att_mtu = NRF_BLE_MAX_MTU_SIZE;
#endif
- err_code = softdevice_enable(&ble_enable_params);
+
+ err_code = sd_ble_enable(&ble_enable_params,&app_ram_base);
APP_ERROR_CHECK(err_code);
+#if (NRF_BLE_MAX_MTU_SIZE > GATT_MTU_SIZE_DEFAULT)
+ {
+ ble_opt_t gap_opt;
+ gap_opt.gap_opt.ext_len.rxtx_max_pdu_payload_size = NRF_BLE_MAX_MTU_SIZE+4;
+ err_code = sd_ble_opt_set(BLE_GAP_OPT_EXT_LEN, &gap_opt);
+ APP_ERROR_CHECK(err_code);
+ gap_opt.common_opt.conn_evt_ext.enable = 1;
+ err_code = sd_ble_opt_set(BLE_COMMON_OPT_CONN_EVT_EXT, &gap_opt); // enable DLE
+ APP_ERROR_CHECK(err_code);
+ }
+#endif
// Subscribe for BLE events.
err_code = softdevice_ble_evt_handler_set(ble_evt_dispatch);
APP_ERROR_CHECK(err_code);
@@ -2312,9 +2389,19 @@ static void ble_stack_init() {
uint32_t ram_start = 0;
err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
APP_ERROR_CHECK(err_code);
+#if (NRF_BLE_MAX_MTU_SIZE > GATT_MTU_SIZE_DEFAULT)
+ {
+ ble_cfg_t cfg;
+ memset(&cfg, 0, sizeof(ble_cfg_t));
+ cfg.conn_cfg.conn_cfg_tag = APP_BLE_CONN_CFG_TAG;
+ cfg.conn_cfg.params.gatt_conn_cfg.att_mtu = NRF_BLE_MAX_MTU_SIZE;
+ err_code = sd_ble_cfg_set(BLE_CONN_CFG_GATT, &cfg, app_ram_base);
+ APP_ERROR_CHECK(err_code);
+ }
+#endif
// Enable BLE stack.
- err_code = nrf_sdh_ble_enable(&ram_start);
+ err_code = nrf_sdh_ble_enable(&app_ram_base);
APP_ERROR_CHECK(err_code);
// Register a handler for BLE events.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment