microbit: Conditional compilation on MicroBitConfig

All options defined in MicroBitConfig are now set IFF they already do not have a value.
This allows external configuration of these options much more cleanly. Additional macros
also defined to provide clean implementation for boolean configuration switches.

Also some minor bugfixes:

  - Correction of typo of "Microbit.h" => "MicroBit.h"
  - Fixed heap corruption bug on gcc as a result of a debug printf in an unsafe context.
This commit is contained in:
Joe Finney 2015-09-02 12:42:24 +01:00
parent 857a626ed0
commit 6470b71b1d
16 changed files with 232 additions and 93 deletions

View file

@ -1,5 +1,5 @@
#ifndef MICROBIT_MANAGED_TYPE
#define MICROBIT_MANAGED_TYPE
#ifndef MICROBIT_MANAGED_TYPE_H
#define MICROBIT_MANAGED_TYPE_H
/**
* Class definition for a Generic Managed Type.

View file

@ -81,7 +81,7 @@
#define MICROBIT_PIN_SDA P0_30
#define MICROBIT_PIN_SCL P0_0
#ifdef MICROBIT_DBG
#if CONFIG_ENABLED(MICROBIT_DBG)
extern Serial pc;
#endif
@ -109,7 +109,7 @@ class MicroBit
MicroBitI2C i2c;
// Serial Interface
#ifndef MICROBIT_DBG
#if CONFIG_DISABLED(MICROBIT_DBG)
MicroBitSerial serial;
#endif

View file

@ -12,39 +12,60 @@
//
// Physical address of the top of SRAM.
#ifndef MICROBIT_SRAM_END
#define MICROBIT_SRAM_END 0x20004000
#endif
// Physical address of the top of the system stack (on mbed-classic this is the top of SRAM)
#ifndef CORTEX_M0_STACK_BASE
#define CORTEX_M0_STACK_BASE MICROBIT_SRAM_END
#endif
// Amount of memory reserved for the stack at the end of memory (bytes).
#define MICROBIT_STACK_SIZE 2000
#ifndef MICROBIT_STACK_SIZE
#define MICROBIT_STACK_SIZE 2048
#endif
// Physical address of the end of heap space.
#ifndef MICROBIT_HEAP_END
#define MICROBIT_HEAP_END (CORTEX_M0_STACK_BASE - MICROBIT_STACK_SIZE)
#endif
// Block size used by the allocator in bytes.
// n.b. Currently only 32 bits (4 bytes) is supported.
#ifndef MICROBIT_HEAP_BLOCK_SIZE
#define MICROBIT_HEAP_BLOCK_SIZE 4
#endif
// The proportion of SRAM available on the mbed heap to reserve for the micro:bit heap.
#ifndef MICROBIT_HEAP_SIZE
#define MICROBIT_HEAP_SIZE 0.95
#endif
// if defined, reuse the 8K of SRAM reserved for SoftDevice (Nordic's memory resident BLE stack) as heap memory.
// The amount of memory reused depends upon whether or not BLE is enabled using MICROBIT_BLE_ENABLED.
#define MICROBIT_HEAP_REUSE_SD
// Set '1' to enable.
#ifndef MICROBIT_HEAP_REUSE_SD
#define MICROBIT_HEAP_REUSE_SD 1
#endif
// The lowest address of memory that is safe to use as heap storage when BLE is DISABLED
// Used to define the base of the heap when MICROBIT_HEAP_REUSE_SD is defined.
#ifndef MICROBIT_HEAP_BASE_BLE_DISABLED
#define MICROBIT_HEAP_BASE_BLE_DISABLED 0x20000008
#endif
// The lowest address of memory that is safe to use as heap storage when BLE is ENABLED
// This is permissable if SD is configured to release some of its internal storage that
// is normally reserved for its BLE GATT table.
#ifndef MICROBIT_HEAP_BASE_BLE_ENABLED
#define MICROBIT_HEAP_BASE_BLE_ENABLED 0x20001C00
#endif
// The highest address of memory normally reserved for Soft Device that is safe to use as heap storage
#ifndef MICROBIT_HEAP_SD_LIMIT
#define MICROBIT_HEAP_SD_LIMIT 0x20002000
#endif
//
// Fiber scheduler configuration
@ -52,7 +73,9 @@
// Scheduling quantum (milliseconds)
// Also used to drive the micro:bit runtime system ticker.
#define FIBER_TICK_PERIOD_MS 6
#ifndef FIBER_TICK_PERIOD_MS
#define FIBER_TICK_PERIOD_MS 6
#endif
//
@ -62,12 +85,16 @@
// To reduce memory cost and complexity, the micro:bit allows components to register for
// periodic callback events during interrupt context, which occur every scheduling quantum (FIBER_TICK_PERIOD_MS)
// This defines the maximum size of interrupt callback list.
#ifndef MICROBIT_SYSTEM_COMPONENTS
#define MICROBIT_SYSTEM_COMPONENTS 10
#endif
// To reduce memory cost and complexity, the micro:bit allows components to register for
// periodic callback events when the processor is idle.
// This defines the maximum size of the idle callback list.
#ifndef MICROBIT_IDLE_COMPONENTS
#define MICROBIT_IDLE_COMPONENTS 6
#endif
//
// BLE options
@ -80,29 +107,110 @@
//
// Enable/Disable BLE during normal operation.
#define MICROBIT_BLE_ENABLED
// Set '1' to enable.
#ifndef MICROBIT_BLE_ENABLED
#define MICROBIT_BLE_ENABLED 1
#endif
// Enable/Disable BLUEZONE mode at power up.
#define MICROBIT_BLE_BLUEZONE
// Set '1' to enable.
#ifndef MICROBIT_BLE_BLUEZONE
#define MICROBIT_BLE_BLUEZONE 1
#endif
// Enable/Disable BLE Service: MicroBitDFU
// This allows over the air programming during normal operation.
#define MICROBIT_BLE_DFU_SERVICE
// Set '1' to enable.
#ifndef MICROBIT_BLE_DFU_SERVICE
#define MICROBIT_BLE_DFU_SERVICE 1
#endif
// Enable/Disable BLE Service: MicroBitEventService
// This allows routing of events from the micro:bit message bus over BLE.
#define MICROBIT_BLE_EVENT_SERVICE
// Set '1' to enable.
#ifndef MICROBIT_BLE_EVENT_SERVICE
#define MICROBIT_BLE_EVENT_SERVICE 1
#endif
// Enable/Disable BLE Service: MicroBitDeviceInformationService
// This enables the standard BLE device information service.
#define MICROBIT_BLE_DEVICE_INFORMATION_SERVICE
// Set '1' to enable.
#ifndef MICROBIT_BLE_DEVICE_INFORMATION_SERVICE
#define MICROBIT_BLE_DEVICE_INFORMATION_SERVICE 1
#endif
//
// Accelerometer options
//
// Enable this to read 10 bits of data from the acclerometer.
// Otherwise, 8 bits are used.
// Set '1' to enable.
#ifndef USE_ACCEL_LSB
#define USE_ACCEL_LSB 0
#endif
//
// Display options
//
// Selects the matrix configuration for the display driver.
// Known, acceptable options are:
//
#define MICROBUG_REFERENCE_DEVICE 1
#define MICROBIT_3X9 2
#define MICROBIT_SB1 3
#define MICROBIT_SB2 4
#ifndef MICROBIT_DISPLAY_TYPE
#define MICROBIT_DISPLAY_TYPE MICROBIT_SB2
#endif
// Selects the minimum permissable brightness level for the device
// in the region of 0 (off) to 255 (full brightness)
#ifndef MICROBIT_DISPLAY_MINIMUM_BRIGHTNESS
#define MICROBIT_DISPLAY_MINIMUM_BRIGHTNESS 2
#endif
// Selects the maximum permissable brightness level for the device
// in the region of 0 (off) to 255 (full brightness)
#ifndef MICROBIT_DISPLAY_MAXIMUM_BRIGHTNESS
#define MICROBIT_DISPLAY_MAXIMUM_BRIGHTNESS 255
#endif
// Selects the default brightness for the display
// in the region of zero (off) to 255 (full brightness)
#ifndef MICROBIT_DISPLAY_DEFAULT_BRIGHTNESS
#define MICROBIT_DISPLAY_DEFAULT_BRIGHTNESS ((MICROBIT_DISPLAY_MAXIMUM_BRIGHTNESS - MICROBIT_DISPLAY_MINIMUM_BRIGHTNESS) / 2)
#endif
// Selects the default scroll speed for the display.
// The time taken to move a single pixel (ms).
#ifndef MICROBIT_DEFAULT_SCROLL_SPEED
#define MICROBIT_DEFAULT_SCROLL_SPEED 120
#endif
// Selects the number of pixels a scroll will move in each quantum.
#ifndef MICROBIT_DEFAULT_SCROLL_STRIDE
#define MICROBIT_DEFAULT_SCROLL_STRIDE -1
#endif
// Selects the time each character will be shown on the display during print operations.
// The time each character is shown on the screen (ms).
#ifndef MICROBIT_DEFAULT_PRINT_SPEED
#define MICROBIT_DEFAULT_PRINT_SPEED 400
#endif
//
// Panic options
//
// Enable this to invoke a panic on out of memory conditions.
#define MICROBIT_PANIC_HEAP_FULL
// Set '1' to enable.
#ifndef MICROBIT_PANIC_HEAP_FULL
#define MICROBIT_PANIC_HEAP_FULL 1
#endif
//
// Debug options
@ -110,10 +218,22 @@
// Enable this to route debug messages through the USB serial interface.
// n.b. This also disables the user serial port 'uBit.serial'.
//#define MICROBIT_DBG
// Set '1' to enable.
#ifndef MICROBIT_DBG
#define MICROBIT_DBG 0
#endif
// Enable this to receive diagnostic messages from the heap allocator via the USB serial interface.
// n.b. This requires MICROBIT_DBG to be defined.
//#define MICROBIT_HEAP_DBG
// Set '1' to enable.
#ifndef MICROBIT_HEAP_DBG
#define MICROBIT_HEAP_DBG 0
#endif
//
// Helper macro used by the micro:bit runtime to determine if a boolean configuration option is set.
//
#define CONFIG_ENABLED(X) (X == 1)
#define CONFIG_DISABLED(X) (X != 1)
#endif

View file

@ -13,20 +13,7 @@
/**
* Core Configuration settings.
*/
#define MICROBIT_SB2
#define MICROBIT_DISPLAY_REFRESH_PERIOD 0.006
/**
* Default parameters.
*/
#define MICROBIT_DEFAULT_SCROLL_SPEED 120
#define MICROBIT_DEFAULT_PRINT_SPEED 400
#define MICROBIT_DEFAULT_SCROLL_STRIDE -1
#define MICROBIT_DISPLAY_MAX_BRIGHTNESS 255
#define MICROBIT_DISPLAY_MIN_BRIGHTNESS 2
#define MICROBIT_DEFAULT_BRIGHTNESS (MICROBIT_DISPLAY_MAX_BRIGHTNESS/2)
#define MICROBIT_DISPLAY_REFRESH_PERIOD ((float)FIBER_TICK_PERIOD_MS / (float)1000)
/**
* MessageBus Event Codes
@ -36,44 +23,44 @@
/**
* I/O configurations for common devices.
*/
#ifdef MICROBUG_REFERENCE_DEVICE
#if MICROBIT_DISPLAY_TYPE == MICROBUG_REFERENCE_DEVICE
#define MICROBIT_DISPLAY_ROW_COUNT 5
#define MICROBIT_DISPLAY_ROW_PINS P0_0, P0_1, P0_2, P0_3, P0_4
#define MICROBIT_DISPLAY_COLUMN_COUNT 5
#define MICROBIT_DISPLAY_COLUMN_PINS P0_24, P0_25, P0_28, P0_29, P0_30
#endif
#ifdef MICROBIT_3X9
#if MICROBIT_DISPLAY_TYPE == MICROBIT_3X9
#define MICROBIT_DISPLAY_ROW_COUNT 3
#define MICROBIT_DISPLAY_ROW_PINS P0_12, P0_13, P0_14
#define MICROBIT_DISPLAY_COLUMN_COUNT 9
#define MICROBIT_DISPLAY_COLUMN_PINS P0_15, P0_16, P0_17, P0_18, P0_19, P0_24, P0_25, P0_28, P0_29
#endif
#ifdef MICROBIT_SB1
#if MICROBIT_DISPLAY_TYPE == MICROBIT_SB1
#define MICROBIT_DISPLAY_ROW_COUNT 9
#define MICROBIT_DISPLAY_ROW_PINS P0_15, P0_16, P0_17, P0_18, P0_19, P0_24, P0_25, P0_28, P0_29
#define MICROBIT_DISPLAY_COLUMN_COUNT 3
#define MICROBIT_DISPLAY_COLUMN_PINS P0_12, P0_13, P0_14
#endif
#ifdef MICROBIT_SB2
#if MICROBIT_DISPLAY_TYPE == MICROBIT_SB2
#define MICROBIT_DISPLAY_ROW_COUNT 3
#define MICROBIT_DISPLAY_ROW_PINS P0_13, P0_14, P0_15
#define MICROBIT_DISPLAY_COLUMN_COUNT 9
#define MICROBIT_DISPLAY_COLUMN_PINS P0_4, P0_5, P0_6, P0_7, P0_8, P0_9, P0_10, P0_11, P0_12
#define MICROBIT_DISPLAY_COLUMN_START P0_4
#define MICROBIT_DISPLAY_WIDTH 5
#define MICROBIT_DISPLAY_HEIGHT 5
#endif
#define MICROBIT_DISPLAY_SPACING 1
#define MICROBIT_DISPLAY_ERROR_CHARS 4
#define MICROBIT_DISPLAY_GREYSCALE_BIT_DEPTH 8
#define MICROBIT_DISPLAY_ANIMATE_DEFAULT_POS -255
//
// Internal constants
//
#define MICROBIT_DISPLAY_WIDTH 5
#define MICROBIT_DISPLAY_HEIGHT 5
#define MICROBIT_DISPLAY_SPACING 1
#define MICROBIT_DISPLAY_ERROR_CHARS 4
#define MICROBIT_DISPLAY_GREYSCALE_BIT_DEPTH 8
#define MICROBIT_DISPLAY_ANIMATE_DEFAULT_POS -255
#include "mbed.h"
#include "MicroBit.h"

View file

@ -1,5 +1,5 @@
#ifndef MICROBIT_EVENT
#define MICROBIT_EVENT
#ifndef MICROBIT_EVENT_H
#define MICROBIT_EVENT_H
#include "MicroBit.h"

View file

@ -1,5 +1,5 @@
#ifndef MICROBIT_FONT
#define MICROBIT_FONT
#ifndef MICROBIT_FONT_H
#define MICROBIT_FONT_H
#include "mbed.h"

View file

@ -26,7 +26,7 @@
#ifndef MICROBIT_HEAP_ALLOCTOR_H
#define MICROBIT_HEAP_ALLOCTOR_H
#include "Microbit.h"
#include "mbed.h"
#include <new>
// The number of heap segments created.
@ -78,8 +78,10 @@ inline void operator delete(void *ptr) throw()
microbit_free(ptr);
}
// Macros to override overrides the 'malloc' and 'delete' functions globally, and redirects calls
// to the micro:bit theap allocator.
#define malloc(X) microbit_malloc( X )
#define free(X) microbit_free( X )

View file

@ -15,7 +15,7 @@
#define NO_CONN 0
#ifdef MICROBUG_REFERENCE_DEVICE
#if MICROBIT_DISPLAY_TYPE == MICROBUG_REFERENCE_DEVICE
const MatrixPoint MicroBitDisplay::matrixMap[MICROBIT_DISPLAY_COLUMN_COUNT][MICROBIT_DISPLAY_ROW_COUNT] =
{ {MatrixPoint(0,0),MatrixPoint(0,1),MatrixPoint(0,2), MatrixPoint(0,3), MatrixPoint(0,4)},
{MatrixPoint(1,0),MatrixPoint(1,1),MatrixPoint(1,2), MatrixPoint(1,3), MatrixPoint(1,4)},
@ -25,7 +25,7 @@
};
#endif
#ifdef MICROBIT_3X9
#if MICROBIT_DISPLAY_TYPE == MICROBIT_3X9
const MatrixPoint MicroBitDisplay::matrixMap[MICROBIT_DISPLAY_COLUMN_COUNT][MICROBIT_DISPLAY_ROW_COUNT] =
{
{MatrixPoint(0,4),MatrixPoint(0,3),MatrixPoint(1,1)},
@ -40,7 +40,7 @@
};
#endif
#ifdef MICROBIT_SB1
#if MICROBIT_DISPLAY_TYPE == MICROBIT_SB1
const MatrixPoint MicroBitDisplay::matrixMap[MICROBIT_DISPLAY_COLUMN_COUNT][MICROBIT_DISPLAY_ROW_COUNT] =
{
{MatrixPoint(0,4), MatrixPoint(1,4), MatrixPoint(2,4), MatrixPoint(3,4), MatrixPoint(4,4), MatrixPoint(4,3), MatrixPoint(3,3), MatrixPoint(2,3), MatrixPoint(1,3)},
@ -49,7 +49,7 @@
};
#endif
#ifdef MICROBIT_SB2
#if MICROBIT_DISPLAY_TYPE == MICROBIT_SB2
const MatrixPoint MicroBitDisplay::matrixMap[MICROBIT_DISPLAY_COLUMN_COUNT][MICROBIT_DISPLAY_ROW_COUNT] =
{
{MatrixPoint(0,0),MatrixPoint(4,2),MatrixPoint(2,4)},
@ -63,7 +63,6 @@
{MatrixPoint(1,2),MatrixPoint(NO_CONN,NO_CONN),MatrixPoint(3,2)}
};
#endif
const PinName rowPins[MICROBIT_DISPLAY_ROW_COUNT] = {MICROBIT_DISPLAY_ROW_PINS};

View file

@ -2,7 +2,7 @@
char MICROBIT_BLE_DEVICE_NAME[] = "BBC MicroBit [xxxxx]";
#if defined (MICROBIT_BLE_ENABLED) && defined (MICROBIT_BLE_DEVICE_INFORMATION_SERVICE)
#if CONFIG_ENABLED(MICROBIT_BLE_ENABLED) && CONFIG_ENABLED(MICROBIT_BLE_DEVICE_INFORMATION_SERVICE)
const char MICROBIT_BLE_MANUFACTURER[] = "The Cast of W1A";
const char MICROBIT_BLE_MODEL[] = "Microbit SB2";
const char MICROBIT_BLE_SERIAL[] = "SN1";
@ -49,7 +49,7 @@ void bleDisconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t r
MicroBit::MicroBit() :
flags(0x00),
i2c(MICROBIT_PIN_SDA, MICROBIT_PIN_SCL),
#ifndef MICROBIT_DBG
#if CONFIG_DISABLED(MICROBIT_DBG)
serial(USBTX, USBRX),
#endif
MessageBus(),
@ -93,7 +93,7 @@ void MicroBit::init()
// Seed our random number generator
seedRandom();
#ifdef MICROBIT_BLE_ENABLED
#if CONFIG_ENABLED(MICROBIT_BLE_ENABLED)
// Start the BLE stack.
ble = new BLEDevice();
@ -102,24 +102,18 @@ void MicroBit::init()
// Bring up any configured auxiliary services.
#ifdef MICROBIT_BLE_DFU_SERVICE
#if CONFIG_ENABLED(MICROBIT_BLE_DFU_SERVICE)
ble_firmware_update_service = new MicroBitDFUService(*ble);
// Compute our auto-generated MicroBit device name.
ble_firmware_update_service->getName(MICROBIT_BLE_DEVICE_NAME+14);
#endif
#ifdef MICROBIT_BLE_DEVICE_INFORMATION_SERVICE
#ifdef OLD
ble_device_information_service = new DeviceInformationService(*ble, MICROBIT_BLE_MANUFACTURER, MICROBIT_BLE_MODEL, MICROBIT_BLE_SERIAL, MICROBIT_BLE_HARDWARE_VERSION, MICROBIT_BLE_FIRMWARE_VERSION, MICROBIT_BLE_SOFTWARE_VERSION);
#endif
#if CONFIG_ENABLED(MICROBIT_BLE_DEVICE_INFORMATION_SERVICE)
DeviceInformationService ble_device_information_service (*ble, MICROBIT_BLE_MANUFACTURER, MICROBIT_BLE_MODEL, MICROBIT_BLE_SERIAL, MICROBIT_BLE_HARDWARE_VERSION, MICROBIT_BLE_FIRMWARE_VERSION, MICROBIT_BLE_SOFTWARE_VERSION);
#endif
#ifdef MICROBIT_BLE_EVENT_SERVICE
#if CONFIG_ENABLED(MICROBIT_BLE_EVENT_SERVICE)
ble_event_service = new MicroBitEventService(*ble);
#endif

View file

@ -118,7 +118,7 @@ void MicroBitAccelerometer::update()
// We ignore the LSB bits for now, as they're just noise...
// TODO: Revist this when we have working samples to see if additional resolution is needed.
#ifdef USE_ACCEL_LSB
#if CONFIG_ENABLED(USE_ACCEL_LSB)
// Add in LSB values.
sample.x += (data[1] / 64);
sample.y += (data[3] / 64);

View file

@ -1,7 +1,7 @@
/**
* Compatibility / portability funcitons and constants for the MicroBit DAL.
*/
#include "MicroBit.h"
#include "mbed.h"
/**
@ -59,3 +59,4 @@ void itoa(int n, char *s)
// Flip the order.
string_reverse(s);
}

View file

@ -152,7 +152,7 @@ void MicroBitDFUService::onDataWritten(const GattWriteCallbackParams *params)
if (authenticated)
{
#ifdef MICROBIT_DBG
#if CONFIG_ENABLED(MICROBIT_DBG)
pc.printf(" ACTIVATING BOOTLOADER.\n");
#endif
bootloader_start();
@ -175,7 +175,7 @@ void MicroBitDFUService::onDataWritten(const GattWriteCallbackParams *params)
memcpy(&lockCode, params->data, 4);
if (lockCode == NRF_FICR->DEVICEID[0])
{
#ifdef MICROBIT_DBG
#if CONFIG_ENABLED(MICROBIT_DBG)
pc.printf("MicroBitDFU: FLASHCODE AUTHENTICATED\n");
#endif
authenticated = true;

View file

@ -51,7 +51,7 @@ MicroBitDisplay::MicroBitDisplay(uint16_t id, uint8_t x, uint8_t y) :
this->greyscaleBitMsk = 0x01;
this->timingCount = 0;
this->setBrightness(MICROBIT_DEFAULT_BRIGHTNESS);
this->setBrightness(MICROBIT_DISPLAY_DEFAULT_BRIGHTNESS);
this->mode = DISPLAY_MODE_BLACK_AND_WHITE;
this->animationMode = ANIMATION_MODE_NONE;
@ -149,11 +149,11 @@ void MicroBitDisplay::render()
nrf_gpio_port_write(NRF_GPIO_PORT_SELECT_PORT1, strobeBitMsk | (~coldata>>4 & 0x1F));
//timer does not have enough resolution for brightness of 1. 23.53 us
if(brightness != MICROBIT_DISPLAY_MAX_BRIGHTNESS && brightness > MICROBIT_DISPLAY_MIN_BRIGHTNESS)
renderTimer.attach(this, &MicroBitDisplay::renderFinish, (((float)brightness) / ((float)MICROBIT_DISPLAY_MAX_BRIGHTNESS)) * (float)MICROBIT_DISPLAY_REFRESH_PERIOD);
if(brightness != MICROBIT_DISPLAY_MAXIMUM_BRIGHTNESS && brightness > MICROBIT_DISPLAY_MINIMUM_BRIGHTNESS)
renderTimer.attach(this, &MicroBitDisplay::renderFinish, (((float)brightness) / ((float)MICROBIT_DISPLAY_MAXIMUM_BRIGHTNESS)) * (float)MICROBIT_DISPLAY_REFRESH_PERIOD);
//this will take around 23us to execute
if(brightness <= MICROBIT_DISPLAY_MIN_BRIGHTNESS)
if(brightness <= MICROBIT_DISPLAY_MINIMUM_BRIGHTNESS)
renderFinish();
}

View file

@ -19,9 +19,16 @@
*
* We could compress further, but the complexity of decode would likely outweigh the gains.
*/
const unsigned char defaultFontArray[475] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0x8, 0xa, 0x4a, 0x40, 0x0, 0x0, 0xa, 0x5f, 0xea, 0x5f, 0xea, 0xe, 0xd9, 0x2e, 0xd3, 0x6e, 0x19, 0x32, 0x44, 0x89, 0x33, 0xc, 0x92, 0x4c, 0x92, 0x4d, 0x8, 0x8, 0x0, 0x0, 0x0, 0x4, 0x88, 0x8, 0x8, 0x4, 0x8, 0x4, 0x84, 0x84, 0x88, 0x0, 0xa, 0x44, 0x8a, 0x40, 0x0, 0x4, 0x8e, 0xc4, 0x80, 0x0, 0x0, 0x0, 0x4, 0x88, 0x0, 0x0, 0xe, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x0, 0x1, 0x22, 0x44, 0x88, 0x10, 0xe, 0xd3, 0x75, 0xb9, 0x2e, 0x1c, 0x84, 0x84, 0x84, 0x9f, 0xe, 0xd1, 0x26, 0xd0, 0x1f, 0x1e, 0xc1, 0x2e, 0xc1, 0x3e, 0x2, 0x46, 0xca, 0x5f, 0xe2, 0x1f, 0xf0, 0x1e, 0xc1, 0x3e, 0xe, 0xd0, 0x1e, 0xd1, 0x2e, 0x1f, 0xe1, 0x22, 0x44, 0x88, 0xe, 0xd1, 0x2e, 0xd1, 0x2e, 0xe, 0xd1, 0x2f, 0xe1, 0x2e, 0x0, 0x8, 0x0, 0x8, 0x0, 0x0, 0x4, 0x80, 0x4, 0x88, 0x2, 0x44, 0x88, 0x4, 0x82, 0x0, 0xe, 0xc0, 0xe, 0xc0, 0x8, 0x4, 0x82, 0x44, 0x88, 0xe, 0xd1, 0x26, 0xc0, 0x4, 0xe, 0xd1, 0x35, 0xb3, 0x6c, 0xe, 0xd1, 0x3f, 0xf1, 0x31, 0x1e, 0xd1, 0x3e, 0xd1, 0x3e, 0xf, 0xf0, 0x10, 0x10, 0xf, 0x1e, 0xd1, 0x31, 0x31, 0x3e, 0x1f, 0xf0, 0x1e, 0xd0, 0x1f, 0x1f, 0xf0, 0x1e, 0xd0, 0x10, 0xf, 0xf0, 0x13, 0x71, 0x2f, 0x11, 0x31, 0x3f, 0xf1, 0x31, 0x1f, 0xe4, 0x84, 0x84, 0x9f, 0x1f, 0xe1, 0x21, 0x31, 0x2e, 0x11, 0x31, 0x3e, 0xd1, 0x31, 0x10, 0x10, 0x10, 0x10, 0x1f, 0x11, 0x3b, 0x75, 0xb5, 0xb1, 0x11, 0x39, 0x35, 0xb3, 0x71, 0xe, 0xd1, 0x31, 0x31, 0x2e, 0x1e, 0xd1, 0x3e, 0xd0, 0x10, 0xe, 0xd1, 0x35, 0xae, 0xc4, 0x1e, 0xd1, 0x3e, 0xd2, 0x51, 0xf, 0xf0, 0xe, 0xc1, 0x3e, 0x1f, 0xe4, 0x84, 0x84, 0x84, 0x11, 0x31, 0x31, 0x31, 0x2e, 0x11, 0x31, 0x31, 0x2a, 0x44, 0x11, 0x35, 0xb5, 0xb5, 0xaa, 0x11, 0x31, 0x2e, 0xd1, 0x31, 0x11, 0x31, 0x2a, 0x44, 0x84, 0x1f, 0xe2, 0x44, 0x88, 0x1f, 0xe, 0xc8, 0x8, 0x8, 0xe, 0x10, 0x8, 0x4, 0x82, 0x41, 0xe, 0xc2, 0x42, 0x42, 0x4e, 0x4, 0x8a, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0x8, 0x4, 0x80, 0x0, 0x0, 0xe, 0xd1, 0x2f, 0xf1, 0x2f, 0x1e, 0xd1, 0x3e, 0xd1, 0x3e, 0xe, 0xd1, 0x30, 0x11, 0x2e, 0x1e, 0xd1, 0x31, 0x31, 0x3e, 0xe, 0xd1, 0x3f, 0xf0, 0xf, 0x1f, 0xf0, 0x1e, 0xd0, 0x10, 0xf, 0xf0, 0x13, 0x71, 0x2f, 0x11, 0x31, 0x3f, 0xf1, 0x31, 0x1c, 0x84, 0x84, 0x84, 0x9f, 0x1e, 0xc2, 0x42, 0x52, 0x4c, 0x11, 0x31, 0x3e, 0xd1, 0x31, 0x10, 0x10, 0x10, 0x10, 0x1f, 0x15, 0xbf, 0xf5, 0xb5, 0xb5, 0x16, 0xd9, 0x31, 0x31, 0x31, 0xe, 0xd1, 0x31, 0x31, 0x2e, 0x1e, 0xd1, 0x3e, 0xd0, 0x10, 0xe, 0xd1, 0x35, 0xae, 0xc4, 0x1b, 0x6c, 0x88, 0x8, 0x1e, 0xf, 0xf0, 0xe, 0xc1, 0x3e, 0x1f, 0xe4, 0x84, 0x84, 0x84, 0x11, 0x31, 0x31, 0x33, 0x6d, 0x11, 0x31, 0x2a, 0x4a, 0x44, 0x11, 0x35, 0xb5, 0xaa, 0x4a, 0x11, 0x31, 0x2e, 0xd1, 0x31, 0x11, 0x31, 0x2a, 0x44, 0x84, 0x1f, 0xe2, 0x44, 0x88, 0x1f, 0x6, 0xc4, 0x8c, 0x84, 0x86, 0x8, 0x8, 0x8, 0x8, 0x8, 0x18, 0x8, 0xc, 0x88, 0x18, 0x0, 0x0, 0xc, 0x83, 0x60};
const unsigned char* MicroBitFont::defaultFont = defaultFontArray;
/*
const unsigned char bpdotunicase[475] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0x8, 0xa, 0x4a, 0x40, 0x0, 0x0, 0xa, 0x5f, 0xea, 0x5f, 0xea, 0xe, 0xd9, 0x2e, 0xd3, 0x6e, 0x19, 0x32, 0x44, 0x89, 0x33, 0xc, 0x92, 0x4c, 0x92, 0x4d, 0x8, 0x8, 0x0, 0x0, 0x0, 0x4, 0x88, 0x8, 0x8, 0x4, 0x8, 0x4, 0x84, 0x84, 0x88, 0x0, 0xa, 0x44, 0x8a, 0x40, 0x0, 0x4, 0x8e, 0xc4, 0x80, 0x0, 0x0, 0x0, 0x4, 0x88, 0x0, 0x0, 0xe, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x0, 0x1, 0x22, 0x44, 0x88, 0x10, 0xe, 0xd3, 0x75, 0xb9, 0x2e, 0x1c, 0x84, 0x84, 0x84, 0x9f, 0xe, 0xd1, 0x26, 0xd0, 0x1f, 0x1e, 0xc1, 0x2e, 0xc1, 0x3e, 0x2, 0x46, 0xca, 0x5f, 0xe2, 0x1f, 0xf0, 0x1e, 0xc1, 0x3e, 0xe, 0xd0, 0x1e, 0xd1, 0x2e, 0x1f, 0xe1, 0x22, 0x44, 0x88, 0xe, 0xd1, 0x2e, 0xd1, 0x2e, 0xe, 0xd1, 0x2f, 0xe1, 0x2e, 0x0, 0x8, 0x0, 0x8, 0x0, 0x0, 0x4, 0x80, 0x4, 0x88, 0x2, 0x44, 0x88, 0x4, 0x82, 0x0, 0xe, 0xc0, 0xe, 0xc0, 0x8, 0x4, 0x82, 0x44, 0x88, 0xe, 0xd1, 0x26, 0xc0, 0x4, 0xe, 0xd1, 0x35, 0xb3, 0x6c, 0xe, 0xd1, 0x3f, 0xf1, 0x31, 0x1e, 0xd1, 0x3e, 0xd1, 0x3e, 0xf, 0xf0, 0x10, 0x10, 0xf, 0x1e, 0xd1, 0x31, 0x31, 0x3e, 0x1f, 0xf0, 0x1e, 0xd0, 0x1f, 0x1f, 0xf0, 0x1e, 0xd0, 0x10, 0xf, 0xf0, 0x13, 0x71, 0x2f, 0x11, 0x31, 0x3f, 0xf1, 0x31, 0x1f, 0xe4, 0x84, 0x84, 0x9f, 0x1f, 0xe1, 0x21, 0x31, 0x2e, 0x11, 0x31, 0x3e, 0xd1, 0x31, 0x10, 0x10, 0x10, 0x10, 0x1f, 0x11, 0x3b, 0x75, 0xb5, 0xb1, 0x11, 0x39, 0x35, 0xb3, 0x71, 0xe, 0xd1, 0x31, 0x31, 0x2e, 0x1e, 0xd1, 0x3e, 0xd0, 0x10, 0xe, 0xd1, 0x35, 0xae, 0xc4, 0x1e, 0xd1, 0x3e, 0xd2, 0x51, 0xf, 0xf0, 0xe, 0xc1, 0x3e, 0x1f, 0xe4, 0x84, 0x84, 0x84, 0x11, 0x31, 0x31, 0x31, 0x2e, 0x11, 0x31, 0x31, 0x2a, 0x44, 0x11, 0x35, 0xb5, 0xb5, 0xaa, 0x11, 0x31, 0x2e, 0xd1, 0x31, 0x11, 0x31, 0x2a, 0x44, 0x84, 0x1f, 0xe2, 0x44, 0x88, 0x1f, 0xe, 0xc8, 0x8, 0x8, 0xe, 0x10, 0x8, 0x4, 0x82, 0x41, 0xe, 0xc2, 0x42, 0x42, 0x4e, 0x4, 0x8a, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0x8, 0x4, 0x80, 0x0, 0x0, 0xe, 0xd1, 0x2f, 0xf1, 0x2f, 0x1e, 0xd1, 0x3e, 0xd1, 0x3e, 0xe, 0xd1, 0x30, 0x11, 0x2e, 0x1e, 0xd1, 0x31, 0x31, 0x3e, 0xe, 0xd1, 0x3f, 0xf0, 0xf, 0x1f, 0xf0, 0x1e, 0xd0, 0x10, 0xf, 0xf0, 0x13, 0x71, 0x2f, 0x11, 0x31, 0x3f, 0xf1, 0x31, 0x1c, 0x84, 0x84, 0x84, 0x9f, 0x1e, 0xc2, 0x42, 0x52, 0x4c, 0x11, 0x31, 0x3e, 0xd1, 0x31, 0x10, 0x10, 0x10, 0x10, 0x1f, 0x15, 0xbf, 0xf5, 0xb5, 0xb5, 0x16, 0xd9, 0x31, 0x31, 0x31, 0xe, 0xd1, 0x31, 0x31, 0x2e, 0x1e, 0xd1, 0x3e, 0xd0, 0x10, 0xe, 0xd1, 0x35, 0xae, 0xc4, 0x1b, 0x6c, 0x88, 0x8, 0x1e, 0xf, 0xf0, 0xe, 0xc1, 0x3e, 0x1f, 0xe4, 0x84, 0x84, 0x84, 0x11, 0x31, 0x31, 0x33, 0x6d, 0x11, 0x31, 0x2a, 0x4a, 0x44, 0x11, 0x35, 0xb5, 0xaa, 0x4a, 0x11, 0x31, 0x2e, 0xd1, 0x31, 0x11, 0x31, 0x2a, 0x44, 0x84, 0x1f, 0xe2, 0x44, 0x88, 0x1f, 0x6, 0xc4, 0x8c, 0x84, 0x86, 0x8, 0x8, 0x8, 0x8, 0x8, 0x18, 0x8, 0xc, 0x88, 0x18, 0x0, 0x0, 0xc, 0x83, 0x60};
*/
const unsigned char pendolino3[475] = {
0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x0, 0x8, 0xa, 0x4a, 0x40, 0x0, 0x0, 0xa, 0x5f, 0xea, 0x5f, 0xea, 0xe, 0xd9, 0x2e, 0xd3, 0x6e, 0x19, 0x32, 0x44, 0x89, 0x33, 0xc, 0x92, 0x4c, 0x92, 0x4d, 0x8, 0x8, 0x0, 0x0, 0x0, 0x4, 0x88, 0x8, 0x8, 0x4, 0x8, 0x4, 0x84, 0x84, 0x88, 0x0, 0xa, 0x44, 0x8a, 0x40, 0x0, 0x4, 0x8e, 0xc4, 0x80, 0x0, 0x0, 0x0, 0x4, 0x88, 0x0, 0x0, 0xe, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x0, 0x1, 0x22, 0x44, 0x88, 0x10, 0xc, 0x92, 0x52, 0x52, 0x4c, 0x4, 0x8c, 0x84, 0x84, 0x8e, 0x1c, 0x82, 0x4c, 0x90, 0x1e, 0x1e, 0xc2, 0x44, 0x92, 0x4c, 0x6, 0xca, 0x52, 0x5f, 0xe2, 0x1f, 0xf0, 0x1e, 0xc1, 0x3e, 0x2, 0x44, 0x8e, 0xd1, 0x2e, 0x1f, 0xe2, 0x44, 0x88, 0x10, 0xe, 0xd1, 0x2e, 0xd1, 0x2e, 0xe, 0xd1, 0x2e, 0xc4, 0x88, 0x0, 0x8, 0x0, 0x8, 0x0, 0x0, 0x4, 0x80, 0x4, 0x88, 0x2, 0x44, 0x88, 0x4, 0x82, 0x0, 0xe, 0xc0, 0xe, 0xc0, 0x8, 0x4, 0x82, 0x44, 0x88, 0xe, 0xd1, 0x26, 0xc0, 0x4, 0xe, 0xd1, 0x35, 0xb3, 0x6c, 0xc, 0x92, 0x5e, 0xd2, 0x52, 0x1c, 0x92, 0x5c, 0x92, 0x5c, 0xe, 0xd0, 0x10, 0x10, 0xe, 0x1c, 0x92, 0x52, 0x52, 0x5c, 0x1e, 0xd0, 0x1c, 0x90, 0x1e, 0x1e, 0xd0, 0x1c, 0x90, 0x10, 0xe, 0xd0, 0x13, 0x71, 0x2e, 0x12, 0x52, 0x5e, 0xd2, 0x52, 0x1c, 0x88, 0x8, 0x8, 0x1c, 0x1f, 0xe2, 0x42, 0x52, 0x4c, 0x12, 0x54, 0x98, 0x14, 0x92, 0x10, 0x10, 0x10, 0x10, 0x1e, 0x11, 0x3b, 0x75, 0xb1, 0x31, 0x11, 0x39, 0x35, 0xb3, 0x71, 0xc, 0x92, 0x52, 0x52, 0x4c, 0x1c, 0x92, 0x5c, 0x90, 0x10, 0xc, 0x92, 0x52, 0x4c, 0x86, 0x1c, 0x92, 0x5c, 0x92, 0x51, 0xe, 0xd0, 0xc, 0x82, 0x5c, 0x1f, 0xe4, 0x84, 0x84, 0x84, 0x12, 0x52, 0x52, 0x52, 0x4c, 0x11, 0x31, 0x31, 0x2a, 0x44, 0x11, 0x31, 0x35, 0xbb, 0x71, 0x12, 0x52, 0x4c, 0x92, 0x52, 0x11, 0x2a, 0x44, 0x84, 0x84, 0x1e, 0xc4, 0x88, 0x10, 0x1e, 0xe, 0xc8, 0x8, 0x8, 0xe, 0x10, 0x8, 0x4, 0x82, 0x41, 0xe, 0xc2, 0x42, 0x42, 0x4e, 0x4, 0x8a, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0x8, 0x4, 0x80, 0x0, 0x0, 0x0, 0xe, 0xd2, 0x52, 0x4f, 0x10, 0x10, 0x1c, 0x92, 0x5c, 0x0, 0xe, 0xd0, 0x10, 0xe, 0x2, 0x42, 0x4e, 0xd2, 0x4e, 0xc, 0x92, 0x5c, 0x90, 0xe, 0x6, 0xc8, 0x1c, 0x88, 0x8, 0xe, 0xd2, 0x4e, 0xc2, 0x4c, 0x10, 0x10, 0x1c, 0x92, 0x52, 0x8, 0x0, 0x8, 0x8, 0x8, 0x2, 0x40, 0x2, 0x42, 0x4c, 0x10, 0x14, 0x98, 0x14, 0x92, 0x8, 0x8, 0x8, 0x8, 0x6, 0x0, 0x1b, 0x75, 0xb1, 0x31, 0x0, 0x1c, 0x92, 0x52, 0x52, 0x0, 0xc, 0x92, 0x52, 0x4c, 0x0, 0x1c, 0x92, 0x5c, 0x90, 0x0, 0xe, 0xd2, 0x4e, 0xc2, 0x0, 0xe, 0xd0, 0x10, 0x10, 0x0, 0x6, 0xc8, 0x4, 0x98, 0x8, 0x8, 0xe, 0xc8, 0x7, 0x0, 0x12, 0x52, 0x52, 0x4f, 0x0, 0x11, 0x31, 0x2a, 0x44, 0x0, 0x11, 0x31, 0x35, 0xbb, 0x0, 0x12, 0x4c, 0x8c, 0x92, 0x0, 0x11, 0x2a, 0x44, 0x98, 0x0, 0x1e, 0xc4, 0x88, 0x1e, 0x6, 0xc4, 0x8c, 0x84, 0x86, 0x8, 0x8, 0x8, 0x8, 0x8, 0x18, 0x8, 0xc, 0x88, 0x18, 0x0, 0x0, 0xc, 0x83, 0x60};
const unsigned char* MicroBitFont::defaultFont = pendolino3;
/**
* Constructor.

View file

@ -32,10 +32,24 @@ struct HeapDefinition
// Create the necessary heap definitions.
// We use two heaps by default: one for SoftDevice reuse, and one to run inside the mbed heap.
HeapDefinition heap[MICROBIT_HEAP_COUNT] = {NULL};
HeapDefinition heap[MICROBIT_HEAP_COUNT] = { NULL };
// Scans the status of the heap definition table, and returns the number of INITIALISED heaps.
int microbit_active_heaps()
{
int heapCount = 0;
for (int i=0; i < MICROBIT_HEAP_COUNT; i++)
{
if(heap[i].heap_start != NULL)
heapCount++;
}
return heapCount;
}
#if CONFIG_ENABLED(MICROBIT_DBG) && CONFIG_ENABLED(MICROBIT_HEAP_DBG)
#if defined(MICROBIT_DBG) && defined(MICROBIT_HEAP_DBG)
// Internal diagnostics function.
// Diplays a usage summary about a given heap...
void microbit_heap_print(HeapDefinition &heap)
@ -52,13 +66,13 @@ void microbit_heap_print(HeapDefinition &heap)
return;
}
// Disable IRQ temporarily to ensure no race conditions!
__disable_irq();
pc.printf("heap_start : %p\n", heap.heap_start);
pc.printf("heap_end : %p\n", heap.heap_end);
pc.printf("heap_size : %d\n", (int)heap.heap_end - (int)heap.heap_start);
// Disable IRQ temporarily to ensure no race conditions!
__disable_irq();
block = heap.heap_start;
while (block < heap.heap_end)
{
@ -77,6 +91,10 @@ void microbit_heap_print(HeapDefinition &heap)
block += blockSize;
}
// Enable Interrupts
__enable_irq();
pc.printf("\n");
pc.printf("mb_total_free : %d\n", totalFreeBlock*4);
@ -107,13 +125,13 @@ void microbit_initialise_heap(HeapDefinition &heap)
int
microbit_create_sd_heap(HeapDefinition &heap)
{
#if !defined(MICROBIT_HEAP_REUSE_SD)
#if CONFIG_DISABLED(MICROBIT_HEAP_REUSE_SD)
// We're not configure to use memory of this sort.
return 0;
#endif
// OK, see how much of the RAM assigned to Soft Device we can reclaim.
#ifdef MICROBIT_BLE_ENABLED
#if CONFIG_ENABLED(MICROBIT_BLE_ENABLED)
heap.heap_start = (uint32_t *)MICROBIT_HEAP_BASE_BLE_ENABLED;
heap.heap_end = (uint32_t *)MICROBIT_HEAP_SD_LIMIT;
#else
@ -129,9 +147,14 @@ int
microbit_create_nested_heap(HeapDefinition &heap)
{
uint32_t mb_heap_max;
void *p;
// Ensure we're configured to use this heap at all. If not, we can safely return.
if (MICROBIT_HEAP_SIZE <= 0)
return 0;
// Snapshot something at the top of the main heap.
void *p = native_malloc(sizeof(uint32_t));
p = native_malloc(sizeof(uint32_t));
// Compute the size left in our heap, taking care to ensure it lands on a word boundary.
mb_heap_max = (uint32_t) (((float)(MICROBIT_HEAP_END - (uint32_t)p)) * MICROBIT_HEAP_SIZE);
@ -181,7 +204,7 @@ microbit_heap_init()
// Enable Interrupts
__enable_irq();
#if defined(MICROBIT_DBG) && defined(MICROBIT_HEAP_DBG)
#if CONFIG_ENABLED(MICROBIT_DBG) && CONFIG_ENABLED(MICROBIT_HEAP_DBG)
microbit_heap_print();
#endif
return r;
@ -293,7 +316,7 @@ void *microbit_malloc(size_t size)
p = microbit_malloc(size, heap[i]);
if (p != NULL)
{
#ifdef MICROBIT_HEAP_DBG
#if CONFIG_ENABLED(MICROBIT_DBG) && CONFIG_ENABLED(MICROBIT_HEAP_DBG)
pc.printf("microbit_malloc: ALLOCATED: %d [%p]\n", size, p);
#endif
return p;
@ -307,18 +330,22 @@ void *microbit_malloc(size_t size)
p = native_malloc(size);
if (p!= NULL)
{
#ifdef MICROBIT_HEAP_DBG
pc.printf("microbit_malloc: NATIVE ALLOCATED: %d [%p]\n", size, p);
#if CONFIG_ENABLED(MICROBIT_DBG) && CONFIG_ENABLED(MICROBIT_HEAP_DBG)
// Keep everything trasparent if we've not been initialised yet
if (microbit_active_heaps())
pc.printf("microbit_malloc: NATIVE ALLOCATED: %d [%p]\n", size, p);
#endif
return p;
}
// We're totally out of options (and memory!).
#ifdef MICROBIT_HEAP_DBG
#if CONFIG_ENABLED(MICROBIT_DBG) && CONFIG_ENABLED(MICROBIT_HEAP_DBG)
// Keep everything trasparent if we've not been initialised yet
if (microbit_active_heaps())
pc.printf("microbit_malloc: OUT OF MEMORY\n");
#endif
#ifdef MICROBIT_PANIC_HEAP_FULL
#if CONFIG_ENABLED(MICROBIT_PANIC_HEAP_FULL)
panic(MICROBIT_OOM);
#endif
@ -334,8 +361,9 @@ void microbit_free(void *mem)
uint32_t *memory = (uint32_t *)mem;
uint32_t *cb = memory-1;
#ifdef MICROBIT_HEAP_DBG
pc.printf("microbit_free: %p\n", mem);
#if CONFIG_ENABLED(MICROBIT_DBG) && CONFIG_ENABLED(MICROBIT_HEAP_DBG)
if (microbit_active_heaps())
pc.printf("microbit_free: %p\n", mem);
#endif
// Sanity check.
if (memory == NULL)

View file

@ -1,6 +1,6 @@
#include "MicroBit.h"
#ifdef MICROBIT_DBG
#if CONFIG_ENABLED(MICROBIT_DBG)
Serial pc(USBTX, USBRX);
#endif
@ -13,13 +13,14 @@ reset()
NVIC_SystemReset();
}
int main()
{
// Bring up soft reset button.
resetButton.mode(PullUp);
resetButton.fall(reset);
#ifdef MICROBIT_DBG
#if CONFIG_ENABLED(MICROBIT_DBG)
pc.baud(115200);
// For diagnostics. Gives time to open the console window. :-)
@ -42,7 +43,7 @@ int main()
// Provide time for all threaded initialisers to complete.
uBit.sleep(100);
#ifdef MICROBIT_BLE_BLUEZONE
#if CONFIG_ENABLED(MICROBIT_BLE_BLUEZONE)
// Test if we need to enter BLE pairing mode...
int i=0;
while (uBit.buttonA.isPressed() && uBit.buttonB.isPressed() && i<10)