From b03798cd63d71e6515b9d494e323d8032531ed11 Mon Sep 17 00:00:00 2001 From: Torsten Curdt Date: Mon, 19 Feb 2018 09:52:05 +0100 Subject: [PATCH 01/28] added the interpreter --- build-docker.sh | 3 + source/BluetoothServiceDebug.cpp | 115 ++++ source/BluetoothServiceDebug.h | 29 + source/BluetoothServiceNotify.cpp | 64 +++ source/BluetoothServiceNotify.h | 26 + source/BluetoothServiceProgram.cpp | 135 +++++ source/BluetoothServiceProgram.h | 26 + source/Bytes.h | 8 + source/Images.h | 149 +++++ source/Instruction.cpp | 837 +++++++++++++++++++++++++++++ source/Instruction.h | 57 ++ source/Interpreter.cpp | 529 ++++++++++++++++++ source/Interpreter.h | 132 +++++ source/Slice.cpp | 42 ++ source/Slice.h | 18 + 15 files changed, 2170 insertions(+) create mode 100644 build-docker.sh create mode 100644 source/BluetoothServiceDebug.cpp create mode 100644 source/BluetoothServiceDebug.h create mode 100644 source/BluetoothServiceNotify.cpp create mode 100644 source/BluetoothServiceNotify.h create mode 100644 source/BluetoothServiceProgram.cpp create mode 100644 source/BluetoothServiceProgram.h create mode 100644 source/Bytes.h create mode 100644 source/Images.h create mode 100644 source/Instruction.cpp create mode 100644 source/Instruction.h create mode 100644 source/Interpreter.cpp create mode 100644 source/Interpreter.h create mode 100644 source/Slice.cpp create mode 100644 source/Slice.h diff --git a/build-docker.sh b/build-docker.sh new file mode 100644 index 0000000..d9091ac --- /dev/null +++ b/build-docker.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +docker run -v $(pwd):/project:rw -it calliope/build yotta build \ No newline at end of file diff --git a/source/BluetoothServiceDebug.cpp b/source/BluetoothServiceDebug.cpp new file mode 100644 index 0000000..e7b72c8 --- /dev/null +++ b/source/BluetoothServiceDebug.cpp @@ -0,0 +1,115 @@ +#include "BluetoothServiceDebug.h" +#include "MicroBit.h" +#include "ble/UUID.h" +#include "Bytes.h" + +extern MicroBit uBit; + +static const uint8_t BluetoothServiceDebugUUID[] = { + 0xff,0x44,0xdd,0xee, + 0x25,0x1d, + 0x47,0x0a, + 0xa0,0x62, + 0xfa,0x19,0x22,0xdf,0xa9,0xa8 +}; + + +BluetoothServiceDebug::BluetoothServiceDebug(Interpreter &_interpreter) : + interpreter(_interpreter), + ble(*uBit.ble), + characteristic( + BluetoothServiceDebugUUID, + (uint8_t *)&characteristicsBuffer, 0, sizeof(characteristicsBuffer), + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ + ) +{ + characteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL); + characteristic.setReadAuthorizationCallback(this, &BluetoothServiceDebug::onDataRead); + + GattCharacteristic *characteristics[] = { + &characteristic + }; + + GattService service( + BluetoothServiceDebugUUID, + characteristics, + sizeof(characteristics) / sizeof(GattCharacteristic *)); + + ble.addService(service); + + characteristicsHandle = characteristic.getValueHandle(); + + ble.onDataWritten(this, &BluetoothServiceDebug::onDataWritten); +} + +void BluetoothServiceDebug::onDataWritten(const GattWriteCallbackParams *params) +{ + if (params->handle == characteristicsHandle) { + const uint8_t *data = params->data; + const uint8_t len = params->len; + + // set selector, hi(address), lo(address) + if (len == 3) { + selector = data[0]; + address = BYTES_TO_UINT16(data[1], data[2]); + } + } +} + +#define MIN(a, b) ((a)<(b)?(a):(b)) + +void BluetoothServiceDebug::onDataRead(GattReadAuthCallbackParams *params) +{ + if (params->handle == characteristicsHandle) { + + // get code at address + if (selector == 0x00) { + + const uint8_t *buffer = (uint8_t*)&interpreter.code[0]; + + const uint16_t start = MIN(address, CODE_LEN); + const uint16_t stop = MIN(address+16, CODE_LEN); + const uint16_t len = stop - start; + + uint8_t data[1+2+16]; + data[0] = 0x00; + data[1] = HI16(address); + data[2] = LO16(address); + + if (len > 0) { + memcpy(&data[3], buffer+start, len); + } + + ble.gattServer().write( + characteristicsHandle, + data, 3 + len); + + + } else + + // get methods at address + if (selector == 0x01) { + + const uint8_t *buffer = (uint8_t*)&interpreter.methods[0]; + + const uint16_t start = MIN(address, METHODS_COUNT*2); + const uint16_t stop = MIN(address+2, METHODS_COUNT*2); + const uint16_t len = stop - start; + + uint8_t data[1+2+2]; + data[0] = 0x01; + data[1] = HI16(address); + data[2] = LO16(address); + + if (len > 0) { + memcpy(&data[3], buffer+start, len); + } + + ble.gattServer().write( + characteristicsHandle, + data, 3 + len); + } + + } +} \ No newline at end of file diff --git a/source/BluetoothServiceDebug.h b/source/BluetoothServiceDebug.h new file mode 100644 index 0000000..06bd0fa --- /dev/null +++ b/source/BluetoothServiceDebug.h @@ -0,0 +1,29 @@ +#ifndef INTERPRETER_BLUETOOTH_DEBUG_H +#define INTERPRETER_BLUETOOTH_DEBUG_H + +#include "ble/BLE.h" +#include "Interpreter.h" + +class BluetoothServiceDebug +{ + public: + + BluetoothServiceDebug(Interpreter &interpreter); + + void onDataWritten(const GattWriteCallbackParams *params); + void onDataRead(GattReadAuthCallbackParams *params); + + private: + + Interpreter &interpreter; + BLEDevice &ble; + + GattAttribute::Handle_t characteristicsHandle; + GattCharacteristic characteristic; + uint8_t characteristicsBuffer[CHARACTERISTICS_BUFFER_LEN]; + + uint8_t selector; + uint16_t address; +}; + +#endif diff --git a/source/BluetoothServiceNotify.cpp b/source/BluetoothServiceNotify.cpp new file mode 100644 index 0000000..0fdf59f --- /dev/null +++ b/source/BluetoothServiceNotify.cpp @@ -0,0 +1,64 @@ +#include "BluetoothServiceNotify.h" +#include "MicroBit.h" +#include "ble/UUID.h" +#include "Bytes.h" + +extern MicroBit uBit; + +static const uint8_t BluetoothServiceNotifyUUID[] = { + 0xff,0x55,0xdd,0xee, + 0x25,0x1d, + 0x47,0x0a, + 0xa0,0x62, + 0xfa,0x19,0x22,0xdf,0xa9,0xa8 +}; + + +BluetoothServiceNotify::BluetoothServiceNotify(Interpreter &_interpreter) : + interpreter(_interpreter), + ble(*uBit.ble), + characteristic( + BluetoothServiceNotifyUUID, + (uint8_t *)&characteristicsBuffer, 0, sizeof(characteristicsBuffer), + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY + ) +{ + characteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL); + characteristic.setReadAuthorizationCallback(this, &BluetoothServiceNotify::onDataRead); + + GattCharacteristic *characteristics[] = { + &characteristic + }; + + GattService service( + BluetoothServiceNotifyUUID, + characteristics, + sizeof(characteristics) / sizeof(GattCharacteristic *)); + + ble.addService(service); + + characteristicsHandle = characteristic.getValueHandle(); +} + +void BluetoothServiceNotify::onDataRead(GattReadAuthCallbackParams *params) +{ + if (params->handle == characteristicsHandle) { + } +} + +void BluetoothServiceNotify::send(uint16_t address, uint16_t value) +{ + if (ble.getGapState().connected) { + + uint8_t buffer[4]; + buffer[0] = HI16(address); + buffer[1] = LO16(address); + buffer[2] = HI16(value); + buffer[3] = LO16(value); + + ble.gattServer().notify( + characteristicsHandle, + (uint8_t *)buffer, sizeof(buffer)); + } +} \ No newline at end of file diff --git a/source/BluetoothServiceNotify.h b/source/BluetoothServiceNotify.h new file mode 100644 index 0000000..dd23085 --- /dev/null +++ b/source/BluetoothServiceNotify.h @@ -0,0 +1,26 @@ +#ifndef INTERPRETER_BLUETOOTH_NOTIFY_H +#define INTERPRETER_BLUETOOTH_NOTIFY_H + +#include "ble/BLE.h" +#include "Interpreter.h" + +class BluetoothServiceNotify +{ + public: + + BluetoothServiceNotify(Interpreter &interpreter); + + void onDataRead(GattReadAuthCallbackParams *params); + void send(uint16_t address, uint16_t value); + + private: + + Interpreter &interpreter; + BLEDevice &ble; + + GattAttribute::Handle_t characteristicsHandle; + GattCharacteristic characteristic; + uint8_t characteristicsBuffer[CHARACTERISTICS_BUFFER_LEN]; +}; + +#endif diff --git a/source/BluetoothServiceProgram.cpp b/source/BluetoothServiceProgram.cpp new file mode 100644 index 0000000..c6e9c27 --- /dev/null +++ b/source/BluetoothServiceProgram.cpp @@ -0,0 +1,135 @@ +#include "BluetoothServiceProgram.h" +#include "MicroBit.h" +#include "ble/UUID.h" +#include "Bytes.h" + +extern MicroBit uBit; + +static const uint8_t BluetoothServiceProgramUUID[] = { + 0xff,0x66,0xdd,0xee, + 0x25,0x1d, + 0x47,0x0a, + 0xa0,0x62, + 0xfa,0x19,0x22,0xdf,0xa9,0xa8 +}; + + +BluetoothServiceProgram::BluetoothServiceProgram(Interpreter &_interpreter) : + interpreter(_interpreter), + ble(*uBit.ble), + characteristic( + BluetoothServiceProgramUUID, + (uint8_t *)&characteristicsBuffer, 0, sizeof(characteristicsBuffer), + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ + ) +{ + characteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL); + characteristic.setReadAuthorizationCallback(this, &BluetoothServiceProgram::onDataRead); + + GattCharacteristic *characteristics[] = { + &characteristic + }; + + GattService service( + BluetoothServiceProgramUUID, + characteristics, + sizeof(characteristics) / sizeof(GattCharacteristic *)); + + ble.addService(service); + + characteristicsHandle = characteristic.getValueHandle(); + + ble.onDataWritten(this, &BluetoothServiceProgram::onDataWritten); +} + +void BluetoothServiceProgram::onDataWritten(const GattWriteCallbackParams *params) +{ + if (params->handle == characteristicsHandle) { + + const uint8_t *data = params->data; + const uint8_t len = params->len; + + if (len < 2*2) { + interpreter.status = INTERPRETER_KO_LEN_TOO_SHORT; + return; + } + + const uint16_t length = BYTES_TO_UINT16(data[0],data[1]); + + if (length == 0) { + // end of upload + + const uint16_t hash_sh = BYTES_TO_UINT16(data[2],data[3]); + const uint16_t hash_is = interpreter_calculate_hash(); + + // verify hash + if (hash_is != hash_sh) { + interpreter.status = INTERPRETER_KO_HASH_INVALID; + return; + } + + if (len != 2*2 + METHODS_COUNT*2) { + interpreter.status = INTERPRETER_KO_METHODS_TOO_SHORT; + return; + } + + // copy methods + for(int i=0, o=4; i= CODE_LEN) { + interpreter.status = INTERPRETER_KO_CODE_START_OUT_OF_BOUNDS; + return; + } + + if (position+length > CODE_LEN) { + interpreter.status = INTERPRETER_KO_CODE_STOP_OUT_OF_BOUNDS; + return; + } + + // copy length bytes to position + memcpy((void*)&interpreter.code[position], (const void*)&data[4], length); + } +} + +void BluetoothServiceProgram::onDataRead(GattReadAuthCallbackParams *params) +{ + if (params->handle == characteristicsHandle) { + + const uint16_t hash_is = interpreter_calculate_hash(); + + const uint8_t data[] = { + VERSION_MAJOR, + VERSION_MINOR, + HI16(CODE_LEN), + LO16(CODE_LEN), + HI16(hash_is), + LO16(hash_is), + interpreter.status + }; + + ble.gattServer().write( + characteristicsHandle, + data, sizeof(data)); + + } +} \ No newline at end of file diff --git a/source/BluetoothServiceProgram.h b/source/BluetoothServiceProgram.h new file mode 100644 index 0000000..918503b --- /dev/null +++ b/source/BluetoothServiceProgram.h @@ -0,0 +1,26 @@ +#ifndef INTERPRETER_BLUETOOTH_LINK_H +#define INTERPRETER_BLUETOOTH_LINK_H + +#include "ble/BLE.h" +#include "Interpreter.h" + +class BluetoothServiceProgram +{ + public: + + BluetoothServiceProgram(Interpreter &interpreter); + + void onDataWritten(const GattWriteCallbackParams *params); + void onDataRead(GattReadAuthCallbackParams *params); + + private: + + Interpreter &interpreter; + BLEDevice &ble; + + GattAttribute::Handle_t characteristicsHandle; + GattCharacteristic characteristic; + uint8_t characteristicsBuffer[CHARACTERISTICS_BUFFER_LEN]; +}; + +#endif diff --git a/source/Bytes.h b/source/Bytes.h new file mode 100644 index 0000000..2ecff09 --- /dev/null +++ b/source/Bytes.h @@ -0,0 +1,8 @@ +#ifndef BYTES_H +#define BYTES_H + +#define HI16(i) (uint8_t)(((i)>>8)&0xff) +#define LO16(i) (uint8_t)((i)&0xff) +#define BYTES_TO_UINT16(hi,lo) (uint16_t)(((hi)<<8)|(lo)) + +#endif diff --git a/source/Images.h b/source/Images.h new file mode 100644 index 0000000..33a3bd8 --- /dev/null +++ b/source/Images.h @@ -0,0 +1,149 @@ +#ifndef IMAGES_H +#define IMAGES_H + +static const uint8_t pixels_smiley[25] = { + 0, 1, 0, 1, 0, + 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, + 0, 1, 1, 1, 0 +}; + +static const uint8_t pixels_sadly[25] = { + 0, 1, 0, 1, 0, + 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, + 1, 0, 0, 0, 1 +}; + +static const uint8_t pixels_heart[25] = { + 0, 1, 0, 1, 0, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 0, 1, 1, 1, 0, + 0, 0, 1, 0, 0 +}; + +static const uint8_t pixels_arrow_left[25] = { + 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, + 1, 1, 1, 1, 1, + 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0 +}; +static const uint8_t pixels_arrow_right[25] = { + 0, 0, 1, 0, 0, + 0, 0, 0, 1, 0, + 1, 1, 1, 1, 1, + 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0 +}; +static const uint8_t pixels_arrow_leftright[25] = { + 0, 0, 1, 0, 0, + 0, 1, 0, 1, 0, + 1, 0, 0, 0, 1, + 0, 1, 0, 1, 0, + 0, 0, 1, 0, 0 +}; + + +const MicroBitImage images[] = { + MicroBitImage(5, 5, pixels_smiley), + MicroBitImage(5, 5, pixels_sadly), + MicroBitImage(5, 5, pixels_heart), + MicroBitImage(5, 5, pixels_arrow_left), + MicroBitImage(5, 5, pixels_arrow_right), + MicroBitImage(5, 5, pixels_arrow_leftright), +}; + + +/* +const uint8_t full[25] = {1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 +}; +const uint8_t dot[25] = {0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 +}; +const uint8_t small[25] = {0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, + 0, 1, 0, 1, 0, + 0, 1, 1, 1, 0, + 0, 0, 0, 0, 0 +}; +const uint8_t large[25] = {1, 1, 1, 1, 1, + 1, 0, 0, 0, 1, + 1, 0, 0, 0, 1, + 1, 0, 0, 0, 1, + 1, 1, 1, 1, 1, +}; +const uint8_t double_row[25] = {0, 1, 1, 0, 0, + 0, 1, 1, 0, 0, + 0, 1, 1, 0, 0, + 0, 1, 1, 0, 0, + 0, 1, 1, 0, 0 +}; +const uint8_t tick[25] = {0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, + 0, 0, 0, 1, 0, + 1, 0, 1, 0, 0, + 0, 1, 0, 0, 0 +}; +const uint8_t rock[25] = {0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, + 0, 1, 1, 1, 0, + 0, 1, 1, 1, 0, + 0, 0, 0, 0, 0 +}; +const uint8_t scissors[25] = {1, 0, 0, 0, 1, + 0, 1, 0, 1, 0, + 0, 0, 1, 0, 0, + 0, 1, 0, 1, 0, + 1, 0, 0, 0, 1 +}; +const uint8_t well[25] = {0, 1, 1, 1, 0, + 1, 0, 0, 0, 1, + 1, 0, 0, 0, 1, + 1, 0, 0, 0, 1, + 0, 1, 1, 1, 0 +}; +const uint8_t flash[25] = {0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, + 1, 1, 1, 1, 1, + 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, + +}; +const uint8_t wave[7 * 5] = {0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, + 1, 0, 0, 1, 0, 0, 1, + 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0 +}; + +const MicroBitImage Full(5, 5, full); +const MicroBitImage Dot(5, 5, dot); +const MicroBitImage SmallRect(5, 5, small); +const MicroBitImage LargeRect(5, 5, large); +const MicroBitImage ArrowLeft(5, 5, arrow_left); +const MicroBitImage ArrowRight(5, 5, arrow_right); +const MicroBitImage ArrowLeftRight(5, 5, arrow_leftright); +const MicroBitImage DoubleRow(5, 5, double_row); +const MicroBitImage Tick(5, 5, tick); +const MicroBitImage Heart(5, 5, heart); +const MicroBitImage Smiley(5, 5, smiley); +const MicroBitImage Sadly(5, 5, sadly); +const MicroBitImage Rock(5, 5, rock); +const MicroBitImage Scissors(5, 5, scissors); +const MicroBitImage Well(5, 5, well); +const MicroBitImage Flash(5, 5, flash); +const MicroBitImage Wave(7, 5, wave); +*/ + +#endif \ No newline at end of file diff --git a/source/Instruction.cpp b/source/Instruction.cpp new file mode 100644 index 0000000..f5b93ef --- /dev/null +++ b/source/Instruction.cpp @@ -0,0 +1,837 @@ +#include "Instruction.h" +#include "MicroBit.h" +#include "Images.h" +#include "BluetoothServiceNotify.h" + +#define UNUSED __attribute__((unused)) + +extern MicroBit uBit; +extern BluetoothServiceNotify *notify; + +typedef struct { + InterpreterStatus error; + uint16_t *value; +} Register; + +static Register register_read(Slice &code, RunState &state) +{ + Register result; + + if (slice_available(code) < 1) { + result.error = INTERPRETER_KO_INSTRUCTION_INVALID; + return result; + } + + const uint8_t reg = slice_read8(code); + + if (reg >= REGISTER_COUNT) { + result.error = INTERPRETER_KO_INSTRUCTION_INVALID; + return result; + } + + result.error = INTERPRETER_OK; + result.value = &state.reg[reg]; + + return result; +} + +static void compare(uint16_t a, uint16_t b, RunState &state) +{ + state.cs = + (a == b) ? COMPARED_EQ : + ((a < b) ? COMPARED_LT : COMPARED_GT); +} + +static void ret(Slice &code, Interpreter &interpreter UNUSED, RunState &state, bool comparison) +{ + state.pc = comparison ? state.stack : code.position; + state.stack = code.stop; +} + +static void bra(Slice &code, Interpreter &interpreter, RunState &state, bool comparison) +{ + if (slice_available(code) < 1) { + interpreter.status = INTERPRETER_KO_INSTRUCTION_INVALID; + return; + } + + const uint8_t value = slice_read8(code); + const int8_t offset = value; + + uBit.sleep(5); + + state.pc = comparison ? code.position + offset : code.position; +} + +void instruction_ret(Slice &code, Interpreter &interpreter, RunState &state) +{ + ret(code, interpreter, state, + true); +} + +void instruction_req(Slice &code, Interpreter &interpreter, RunState &state) +{ + ret(code, interpreter, state, + state.cs == COMPARED_EQ); +} + +void instruction_rne(Slice &code, Interpreter &interpreter, RunState &state) +{ + ret(code, interpreter, state, + state.cs != COMPARED_EQ); +} + +void instruction_rgt(Slice &code, Interpreter &interpreter, RunState &state) +{ + ret(code, interpreter, state, + state.cs == COMPARED_GT); +} + +void instruction_rlt(Slice &code, Interpreter &interpreter, RunState &state) +{ + ret(code, interpreter, state, + state.cs == COMPARED_LT); +} + +void instruction_rge(Slice &code, Interpreter &interpreter, RunState &state) +{ + ret(code, interpreter, state, + state.cs == COMPARED_GT || + state.cs == COMPARED_EQ); +} + +void instruction_rle(Slice &code, Interpreter &interpreter, RunState &state) +{ + ret(code, interpreter, state, + state.cs == COMPARED_LT || + state.cs == COMPARED_EQ); +} + +void instruction_jsr(Slice &code, Interpreter &interpreter, RunState &state) +{ + if (slice_available(code) < 1) { + interpreter.status = INTERPRETER_KO_INSTRUCTION_INVALID; + return; + } + + const uint8_t value = slice_read8(code); + const int8_t offset = value; + const uint16_t address = code.position + offset; + + // this should be push + state.stack = code.position; + + state.pc = address; +} + + +void instruction_bra(Slice &code, Interpreter &interpreter, RunState &state) +{ + bra(code, interpreter, state, + true); +} + +void instruction_beq(Slice &code, Interpreter &interpreter, RunState &state) +{ + // #ifdef LOG + // switch(state.cs) { + // case COMPARED_EQ: uBit.serial.printf("CS=EQ\n\r"); break; + // case COMPARED_LT: uBit.serial.printf("CS=LT\n\r"); break; + // case COMPARED_GT: uBit.serial.printf("CS=GT\n\r"); break; + // } + // #endif + + bra(code, interpreter, state, + state.cs == COMPARED_EQ); +} + +void instruction_bne(Slice &code, Interpreter &interpreter, RunState &state) +{ + // #ifdef LOG + // switch(state.cs) { + // case COMPARED_EQ: uBit.serial.printf("CS=EQ\n\r"); break; + // case COMPARED_LT: uBit.serial.printf("CS=LT\n\r"); break; + // case COMPARED_GT: uBit.serial.printf("CS=GT\n\r"); break; + // } + // #endif + + bra(code, interpreter, state, + state.cs != COMPARED_EQ); +} + +void instruction_bgt(Slice &code, Interpreter &interpreter, RunState &state) +{ + // #ifdef LOG + // switch(state.cs) { + // case COMPARED_EQ: uBit.serial.printf("CS=EQ\n\r"); break; + // case COMPARED_LT: uBit.serial.printf("CS=LT\n\r"); break; + // case COMPARED_GT: uBit.serial.printf("CS=GT\n\r"); break; + // } + // #endif + + bra(code, interpreter, state, + state.cs == COMPARED_GT); +} + +void instruction_blt(Slice &code, Interpreter &interpreter, RunState &state) +{ + // #ifdef LOG + // switch(state.cs) { + // case COMPARED_EQ: uBit.serial.printf("CS=EQ\n\r"); break; + // case COMPARED_LT: uBit.serial.printf("CS=LT\n\r"); break; + // case COMPARED_GT: uBit.serial.printf("CS=GT\n\r"); break; + // } + // #endif + + bra(code, interpreter, state, + state.cs == COMPARED_LT); +} + +void instruction_bge(Slice &code, Interpreter &interpreter, RunState &state) +{ + // #ifdef LOG + // switch(state.cs) { + // case COMPARED_EQ: uBit.serial.printf("CS=EQ\n\r"); break; + // case COMPARED_LT: uBit.serial.printf("CS=LT\n\r"); break; + // case COMPARED_GT: uBit.serial.printf("CS=GT\n\r"); break; + // } + // #endif + + bra(code, interpreter, state, + state.cs == COMPARED_GT || + state.cs == COMPARED_EQ); +} + +void instruction_ble(Slice &code, Interpreter &interpreter, RunState &state) +{ + // #ifdef LOG + // switch(state.cs) { + // case COMPARED_EQ: uBit.serial.printf("CS=EQ\n\r"); break; + // case COMPARED_LT: uBit.serial.printf("CS=LT\n\r"); break; + // case COMPARED_GT: uBit.serial.printf("CS=GT\n\r"); break; + // } + // #endif + + bra(code, interpreter, state, + state.cs == COMPARED_LT || + state.cs == COMPARED_EQ); +} + +void instruction_bra16(Slice &code, Interpreter &interpreter, RunState &state) +{ + if (slice_available(code) < 2) { + interpreter.status = INTERPRETER_KO_INSTRUCTION_INVALID; + return; + } + + const uint16_t value = slice_read16(code); + const int16_t offset = value; + + state.pc = code.position + offset; +} + + + + +void instruction_cmp(Slice &code, Interpreter &interpreter, RunState &state) +{ + Register ra = register_read(code, state); + if (ra.error) { + interpreter.status = ra.error; + return; + } + + Register rb = register_read(code, state); + if (rb.error) { + interpreter.status = rb.error; + return; + } + + // uBit.serial.printf("cmp 0x%x vs 0x%x\n\r", *ra.value, *rb.value); + + compare(*ra.value, *rb.value, state); + + state.pc = code.position; +} + +void instruction_cmpi(Slice &code, Interpreter &interpreter, RunState &state) +{ + if (slice_available(code) < 2) { + interpreter.status = INTERPRETER_KO_INSTRUCTION_INVALID; + return; + } + + const uint16_t a = slice_read16(code); + + Register rb = register_read(code, state); + if (rb.error) { + interpreter.status = rb.error; + return; + } + + compare(a, *rb.value, state); + + state.pc = code.position; +} + +void instruction_mov(Slice &code, Interpreter &interpreter, RunState &state) +{ + Register src = register_read(code, state); + if (src.error) { + interpreter.status = src.error; + return; + } + + Register dst = register_read(code, state); + if (dst.error) { + interpreter.status = dst.error; + return; + } + + const uint16_t value = *src.value; + + *dst.value = value; + + compare(0, value, state); + + state.pc = code.position; +} + +void instruction_movi(Slice &code, Interpreter &interpreter, RunState &state) +{ + if (slice_available(code) < 2) { + interpreter.status = INTERPRETER_KO_INSTRUCTION_INVALID; + return; + } + + const uint16_t value = slice_read16(code); + + Register dst = register_read(code, state); + if (dst.error) { + interpreter.status = dst.error; + return; + } + + *dst.value = value; + + compare(0, value, state); + + state.pc = code.position; +} + + +void instruction_add(Slice &code, Interpreter &interpreter, RunState &state) +{ + Register src = register_read(code, state); + if (src.error) { + interpreter.status = src.error; + return; + } + + Register dst = register_read(code, state); + if (dst.error) { + interpreter.status = dst.error; + return; + } + + const uint16_t value = *dst.value + *src.value; + + *dst.value = value; + + compare(0, value, state); + + state.pc = code.position; +} + +void instruction_sub(Slice &code, Interpreter &interpreter, RunState &state) +{ + Register src = register_read(code, state); + if (src.error) { + interpreter.status = src.error; + return; + } + + Register dst = register_read(code, state); + if (dst.error) { + interpreter.status = dst.error; + return; + } + + const uint16_t value = *dst.value - *src.value; + + *dst.value = value; + + compare(0, value, state); + + state.pc = code.position; +} + +void instruction_mul(Slice &code, Interpreter &interpreter, RunState &state) +{ + Register src = register_read(code, state); + if (src.error) { + interpreter.status = src.error; + return; + } + + Register dst = register_read(code, state); + if (dst.error) { + interpreter.status = dst.error; + return; + } + + const uint16_t value = *dst.value * *src.value; + + *dst.value = value; + + compare(0, value, state); + + state.pc = code.position; +} + +void instruction_div(Slice &code, Interpreter &interpreter, RunState &state) +{ + Register src = register_read(code, state); + if (src.error) { + interpreter.status = src.error; + return; + } + + Register dst = register_read(code, state); + if (dst.error) { + interpreter.status = dst.error; + return; + } + + if (*src.value == 0) { + interpreter.status = INTERPRETER_KO_DIVISION_BY_ZERO; + return; + } + + const uint16_t value = *dst.value / *src.value; + + *dst.value = value; + + compare(0, value, state); + + state.pc = code.position; +} + + +void instruction_sleep(Slice &code, Interpreter &interpreter, RunState &state) +{ + Register time = register_read(code, state); + if (time.error) { + interpreter.status = time.error; + return; + } + + uBit.sleep(*time.value); + + state.pc = code.position; +} + +void instruction_random(Slice &code, Interpreter &interpreter, RunState &state) +{ + Register r = register_read(code, state); + if (r.error) { + interpreter.status = r.error; + return; + } + + const uint16_t value = uBit.random(*r.value); + + *r.value = value; + + compare(0, value, state); + + state.pc = code.position; +} + +void instruction_time(Slice &code, Interpreter &interpreter, RunState &state) +{ + Register r = register_read(code, state); + if (r.error) { + interpreter.status = r.error; + return; + } + + const uint16_t value = uBit.systemTime(); + + *r.value = value; + + compare(0, value, state); + + state.pc = code.position; +} + + +void instruction_temperature(Slice &code, Interpreter &interpreter, RunState &state) +{ + Register r = register_read(code, state); + if (r.error) { + interpreter.status = r.error; + return; + } + + const uint16_t value = uBit.thermometer.getTemperature(); + + *r.value = value; + + compare(0, value, state); + + state.pc = code.position; +} + +void instruction_noise(Slice &code, Interpreter &interpreter, RunState &state) +{ + Register r = register_read(code, state); + if (r.error) { + interpreter.status = r.error; + return; + } + + const int value = uBit.io.P21.getAnalogValue(); + + if (value > 512) { + const int gauge = ((log2(value - 511) * 4) / 9); + + *r.value = gauge; + } else { + *r.value = 0; + } + + compare(0, value, state); + + state.pc = code.position; +} + +void instruction_brightness(Slice &code, Interpreter &interpreter, RunState &state) +{ + Register r = register_read(code, state); + if (r.error) { + interpreter.status = r.error; + return; + } + + const uint16_t value = uBit.display.readLightLevel(); + + *r.value = value; + + compare(0, value, state); + + state.pc = code.position; +} + + +void instruction_button(Slice &code, Interpreter &interpreter, RunState &state) +{ + Register r = register_read(code, state); + if (r.error) { + interpreter.status = r.error; + return; + } + + uint16_t value; + + switch(*r.value) { + case 0x01: + value = uBit.buttonA.isPressed(); + break; + case 0x02: + value = uBit.buttonB.isPressed(); + break; + case 0x03: + value = uBit.buttonAB.isPressed(); + break; + default: + interpreter.status = INTERPRETER_KO_INSTRUCTION_INVALID; + return; + } + + *r.value = value; + + compare(0, value, state); + + state.pc = code.position; +} + +static uint8_t pins[] = { 12, 0, 1, 16 }; + +void instruction_pin(Slice &code, Interpreter &interpreter, RunState &state) +{ + Register r = register_read(code, state); + if (r.error) { + interpreter.status = r.error; + return; + } + + const uint16_t i = *r.value; + if (i >= sizeof(pins)) { + interpreter.status = INTERPRETER_KO_INSTRUCTION_INVALID; + return; + } + + const uint16_t value = uBit.io.pin[pins[i]].isTouched(); + + *r.value = value; + + compare(0, value, state); + + state.pc = code.position; +} + + +void instruction_display_clear(Slice &code, Interpreter &interpreter UNUSED, RunState &state) +{ + uBit.display.clear(); + + state.pc = code.position; +} + +void instruction_display_show_number(Slice &code, Interpreter &interpreter, RunState &state) +{ + Register number = register_read(code, state); + if (number.error) { + interpreter.status = number.error; + return; + } + + uBit.display.print(ManagedString(*number.value)); + + state.pc = code.position; +} + +void instruction_display_show_image(Slice &code, Interpreter &interpreter, RunState &state) +{ + Register image = register_read(code, state); + if (image.error) { + interpreter.status = image.error; + return; + } + + const uint16_t i = *image.value; + if (i >= sizeof(images)) { + interpreter.status = INTERPRETER_KO_INSTRUCTION_INVALID; + return; + } + + uBit.display.print(images[i]); + + state.pc = code.position; +} + +void instruction_display_show_grid(Slice &code, Interpreter &interpreter, RunState &state) +{ + uint8_t pixels[25]; + + if (slice_available(code) < sizeof(pixels)) { + interpreter.status = INTERPRETER_KO_INSTRUCTION_INVALID; + return; + } + + for(unsigned int i=0; i code.stop) { + interpreter.status = INTERPRETER_KO_INSTRUCTION_INVALID; + return; + } + + // Important: The mind numbingly stupid implementation of ManagedString + // requires a null terminated string (despite the given length). + // So make sure to also send the 0 byte. For security reasons we force it. + code.buffer[code.position+len-1] = 0; + + const ManagedString text = ManagedString((char*)&code.buffer[code.position]); + + uBit.display.scroll(ManagedString(text)); + + state.pc = code.position + len; +} + + +void instruction_rgb_off(Slice &code, Interpreter &interpreter UNUSED, RunState &state) +{ + if (uBit.rgb.isOn()) { + uBit.rgb.off(); + } + + state.pc = code.position; +} + +void instruction_rgb_on(Slice &code, Interpreter &interpreter, RunState &state) +{ + if (slice_available(code) < 4) { + interpreter.status = INTERPRETER_KO_INSTRUCTION_INVALID; + return; + } + + const uint8_t r = slice_read8(code); + const uint8_t g = slice_read8(code); + const uint8_t b = slice_read8(code); + const uint8_t w = slice_read8(code); + + uBit.rgb.setColour(r, g, b, w); + + state.pc = code.position; +} + + +void instruction_sound_off(Slice &code, Interpreter &interpreter UNUSED, RunState &state) +{ + uBit.soundmotor.soundOff(); + + state.pc = code.position; +} + +void instruction_sound_on(Slice &code, Interpreter &interpreter, RunState &state) +{ + Register freq = register_read(code, state); + if (freq.error) { + interpreter.status = freq.error; + return; + } + + uBit.soundmotor.soundOn(*freq.value); + + state.pc = code.position; +} + + +void instruction_gesture(Slice &code, Interpreter &interpreter, RunState &state) +{ + Register r = register_read(code, state); + if (r.error) { + interpreter.status = r.error; + return; + } + + const uint16_t value = uBit.accelerometer.getGesture(); + + *r.value = value; + + compare(0, value, state); + + state.pc = code.position; +} + +void instruction_pitch(Slice &code, Interpreter &interpreter, RunState &state) +{ + Register r = register_read(code, state); + if (r.error) { + interpreter.status = r.error; + return; + } + + const uint16_t value = uBit.accelerometer.getPitch(); + + *r.value = value; + + compare(0, value, state); + + state.pc = code.position; +} + +void instruction_roll(Slice &code, Interpreter &interpreter, RunState &state) +{ + Register r = register_read(code, state); + if (r.error) { + interpreter.status = r.error; + return; + } + + const uint16_t value = uBit.accelerometer.getRoll(); + + *r.value = value; + + compare(0, value, state); + + state.pc = code.position; +} + +void instruction_position(Slice &code, Interpreter &interpreter, RunState &state) +{ + Register x = register_read(code, state); + if (x.error) { + interpreter.status = x.error; + return; + } + Register y = register_read(code, state); + if (y.error) { + interpreter.status = y.error; + return; + } + Register z = register_read(code, state); + if (z.error) { + interpreter.status = z.error; + return; + } + + *x.value = uBit.accelerometer.getX(); + *y.value = uBit.accelerometer.getY(); + *z.value = uBit.accelerometer.getZ(); + + state.pc = code.position; +} + + +void instruction_notify(Slice &code, Interpreter &interpreter, RunState &state) +{ + Register address = register_read(code, state); + if (address.error) { + interpreter.status = address.error; + return; + } + + Register value = register_read(code, state); + if (value.error) { + interpreter.status = value.error; + return; + } + + if (notify != NULL) { + notify->send(*address.value, *value.value); + } + + state.pc = code.position; +} + +void instruction_debug(Slice &code, Interpreter &interpreter, RunState &state) +{ + Register r = register_read(code, state); + if (r.error) { + interpreter.status = r.error; + return; + } + + uBit.serial.printf("debug: 0x%x\n\r", *r.value); + + state.pc = code.position; +} \ No newline at end of file diff --git a/source/Instruction.h b/source/Instruction.h new file mode 100644 index 0000000..c6fd5e5 --- /dev/null +++ b/source/Instruction.h @@ -0,0 +1,57 @@ +#ifndef INSTRUCTION_H +#define INSTRUCTION_H + +#include "Slice.h" +#include "Interpreter.h" + + +void instruction_ret(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_req(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_rne(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_rgt(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_rlt(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_rge(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_rle(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_jsr(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_bra(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_beq(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_bne(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_bgt(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_blt(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_bge(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_ble(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_bra16(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_cmp(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_cmpi(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_mov(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_movi(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_add(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_sub(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_mul(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_div(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_sleep(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_random(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_time(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_temperature(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_noise(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_brightness(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_button(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_pin(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_display_clear(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_display_show_number(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_display_show_image(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_display_show_grid(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_display_show_text(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_rgb_off(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_rgb_on(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_sound_off(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_sound_on(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_gesture(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_pitch(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_roll(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_position(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_notify(Slice &code, Interpreter &interpreter, RunState &state); +void instruction_debug(Slice &code, Interpreter &interpreter, RunState &state); + + +#endif \ No newline at end of file diff --git a/source/Interpreter.cpp b/source/Interpreter.cpp new file mode 100644 index 0000000..ada8816 --- /dev/null +++ b/source/Interpreter.cpp @@ -0,0 +1,529 @@ +#include "Interpreter.h" +#include "MicroBit.h" +#include "BluetoothServiceDebug.h" +#include "BluetoothServiceProgram.h" +#include "BluetoothServiceNotify.h" +#include "Instruction.h" + +extern MicroBit uBit; + +static Interpreter interpreter; +BluetoothServiceNotify *notify; + +static uint16_t find_stop(InterpreterMethod method) +{ + for(uint8_t i = method + 1; i < METHODS_COUNT; i++) { + uint16_t stop = interpreter.methods[i]; + if (stop != METHOD_UNUSED) { + return stop; + } + } + return CODE_LEN; +} + +#ifdef LOG +static uint8_t running = 0; +#endif +static void interpreter_run(InterpreterMethod method, uint16_t r0 = 0, uint16_t r1 = 0, uint16_t r2 = 0) +{ + uint16_t start = interpreter.methods[method]; + + if (start == METHOD_UNUSED) { + return; + } + + uint16_t stop = find_stop(method); + + #ifdef LOG + running += 1; + uint8_t id = running; + #endif + + // initialize interpreter state + RunState state; + state.pc = start; + state.cs = COMPARED_EQ; + state.stack = stop; + memset(state.reg, 0, REGISTER_COUNT * sizeof(state.reg[0])); + state.reg[0] = r0; + state.reg[1] = r1; + state.reg[2] = r2; + + Slice code = slice_create(interpreter.code, start, stop); + + #ifdef LOG + uBit.serial.printf("%d: run 0x%x-0x%x start\n\r", id, start, stop); + #endif + + while(interpreter.status == INTERPRETER_OK) { + + uint8_t instruction = slice_read8(code); + + // #ifdef LOG + // uBit.serial.printf("%d: @0x%x ins 0x%x\n\r", id, code.position-1, instruction); + // #endif + + switch(instruction) { + case INS_RET: + instruction_ret(code, interpreter, state); + break; + case INS_REQ: + instruction_req(code, interpreter, state); + break; + case INS_RNE: + instruction_rne(code, interpreter, state); + break; + case INS_RGT: + instruction_rgt(code, interpreter, state); + break; + case INS_RLT: + instruction_rlt(code, interpreter, state); + break; + case INS_RGE: + instruction_rge(code, interpreter, state); + break; + case INS_RLE: + instruction_rle(code, interpreter, state); + break; + + case INS_JSR: + instruction_jsr(code, interpreter, state); + break; + + case INS_BRA: + instruction_bra(code, interpreter, state); + break; + case INS_BEQ: + instruction_beq(code, interpreter, state); + break; + case INS_BNE: + instruction_bne(code, interpreter, state); + break; + case INS_BGT: + instruction_bgt(code, interpreter, state); + break; + case INS_BLT: + instruction_blt(code, interpreter, state); + break; + case INS_BGE: + instruction_bge(code, interpreter, state); + break; + case INS_BLE: + instruction_ble(code, interpreter, state); + break; + case INS_BRA16: + instruction_bra16(code, interpreter, state); + break; + + + case INS_CMP: + instruction_cmp(code, interpreter, state); + break; + case INS_CMPI: + instruction_cmpi(code, interpreter, state); + break; + case INS_MOV: + instruction_mov(code, interpreter, state); + break; + case INS_MOVI: + instruction_movi(code, interpreter, state); + break; + + case INS_ADD: + instruction_add(code, interpreter, state); + break; + case INS_SUB: + instruction_sub(code, interpreter, state); + break; + case INS_MUL: + instruction_mul(code, interpreter, state); + break; + case INS_DIV: + instruction_div(code, interpreter, state); + break; + + case INS_SLEEP: + instruction_sleep(code, interpreter, state); + break; + case INS_RANDOM: + instruction_random(code, interpreter, state); + break; + case INS_TIME: + instruction_time(code, interpreter, state); + break; + + case INS_TEMPERATURE: + instruction_temperature(code, interpreter, state); + break; + case INS_NOISE: + instruction_noise(code, interpreter, state); + break; + case INS_BRIGHTNESS: + instruction_brightness(code, interpreter, state); + break; + + case INS_BUTTON: + instruction_button(code, interpreter, state); + break; + case INS_PIN: + instruction_pin(code, interpreter, state); + break; + + case INS_DISPLAY_CLEAR: + instruction_display_clear(code, interpreter, state); + break; + case INS_DISPLAY_SHOW_NUMBER: + instruction_display_show_number(code, interpreter, state); + break; + case INS_DISPLAY_SHOW_IMAGE: + instruction_display_show_image(code, interpreter, state); + break; + case INS_DISPLAY_SHOW_GRID: + instruction_display_show_grid(code, interpreter, state); + break; + case INS_DISPLAY_SHOW_TEXT: + instruction_display_show_text(code, interpreter, state); + break; + + case INS_RGB_OFF: + instruction_rgb_off(code, interpreter, state); + break; + case INS_RGB_ON: + instruction_rgb_on(code, interpreter, state); + break; + + case INS_SOUND_OFF: + instruction_sound_off(code, interpreter, state); + break; + case INS_SOUND_ON: + instruction_sound_on(code, interpreter, state); + break; + + case INS_ACC_GESTURE: + instruction_gesture(code, interpreter, state); + break; + case INS_ACC_PITCH: + instruction_pitch(code, interpreter, state); + break; + case INS_ACC_ROLL: + instruction_roll(code, interpreter, state); + break; + case INS_ACC_POSITION: + instruction_position(code, interpreter, state); + break; + + case INS_NOTIFY: + instruction_notify(code, interpreter, state); + break; + case INS_DEBUG: + instruction_debug(code, interpreter, state); + break; + + default: + interpreter.status = INTERPRETER_KO_INSTRUCTION_UNKNOWN; + } + + code.position = state.pc; + + if (slice_available(code) < 1) { + #ifdef LOG + uBit.serial.printf("%d: run 0x%x-0x%x stop\n\r", id, start, stop); + #endif + return; + } + } +} + +static void interpreter_on_button(MicroBitEvent event) +{ + #ifdef LOG + uBit.serial.printf("button 0x%x 0x%x start\n\r", event.source, event.value); + #endif + + interpreter_run(METHOD_ON_BUTTON, event.source, event.value); + + #ifdef LOG + uBit.serial.printf("button 0x%x 0x%x stop\n\r", event.source, event.value); + #endif +} + +static void interpreter_on_pin(MicroBitEvent event) +{ + uint8_t source; + switch(event.source) { + case MICROBIT_ID_IO_P12: source = 0; break; + case MICROBIT_ID_IO_P0: source = 1; break; + case MICROBIT_ID_IO_P1: source = 2; break; + case MICROBIT_ID_IO_P16: source = 3; break; + default: return; + } + + #ifdef LOG + uBit.serial.printf("pin 0x%x 0x%x start\n\r", source, event.value); + #endif + + interpreter_run(METHOD_ON_PIN, source, event.value); + + #ifdef LOG + uBit.serial.printf("pin 0x%x 0x%x stop\n\r", source, event.value); + #endif +} + +static void interpreter_on_gesture(MicroBitEvent event) +{ + #ifdef LOG + uBit.serial.printf("gesture 0x%x 0x%x start\n\r", event.source, event.value); + #endif + + interpreter_run(METHOD_ON_GESTURE, event.source, event.value); + + #ifdef LOG + uBit.serial.printf("gesture 0x%x 0x%x stop\n\r", event.source, event.value); + #endif + } + +static void interpreter_startup_sound() +{ + uBit.soundmotor.soundOn(262); + uBit.sleep(125); + uBit.soundmotor.soundOff(); + + uBit.sleep(63); + + uBit.soundmotor.soundOn(784); + uBit.sleep(500); + uBit.soundmotor.soundOff(); +} + +static void interpreter_reset_hardware() +{ + uBit.rgb.off(); + uBit.display.clear(); + uBit.soundmotor.soundOff(); +} + +static void interpreter_fiber() +{ + while(true) { + interpreter_startup_sound(); + interpreter_reset_hardware(); + + #ifdef LOG + uBit.serial.send("start\n\r"); + #endif + + interpreter_run(METHOD_STARTUP); + + #ifdef LOG + uBit.serial.send("forever\n\r"); + #endif + + while(interpreter.status == INTERPRETER_OK) { + interpreter_run(METHOD_FOREVER); + uBit.sleep(10); + } + + #ifdef LOG + uBit.serial.send("rx\n\r"); + #endif + + while(interpreter.status != INTERPRETER_RD) { + uBit.sleep(10); + } + + interpreter.status = INTERPRETER_OK; + + #ifdef LOG + uBit.serial.send("reset\n\r"); + #endif + } +} + +void interpreter_reset() +{ + memset(interpreter.code, 0, CODE_LEN * sizeof(interpreter.code[0])); + memset(interpreter.methods, METHOD_UNUSED, METHODS_COUNT * sizeof(interpreter.methods[0])); + interpreter.status = INTERPRETER_OK; + +/* + const uint8_t program[] = { +0x23, +0x01, +0x00, +0x01, +0x23, +0x00, +0x03, +0x00, +0x71, +0x00, +0x40, +0x01, +0x23, +0x00, +0x02, +0x00, +0x71, +0x00, +0x40, +0x01, +0x23, +0x00, +0x01, +0x00, +0x71, +0x00, +0x40, +0x01, +0x74, +0x00, +0x04, +0x48, +0x69, +0x21, +0x00, +0x23, +0x10, +0x00, +0x00, +0x81, +0xff, +0x00, +0x00, +0x00, +0x40, +0x00, +0x80, +0x40, +0x00, +0x00, +0x23, +0x03, +0x00, +0x00, +0x23, +0x03, +0x00, +0x01, +0x91, +0x01, +0x40, +0x00, +0x90, +0x40, +0x00 + }; + memcpy(&interpreter.code[0], program, sizeof(program)); + + const uint16_t methods[] = { +0x0000, +0x0023, +0x0032, +0xffff, +0xffff + }; + memcpy(&interpreter.methods[0], methods, sizeof(methods)); +*/ + + // // test program + // const uint8_t program[] = { + // 0x21, 0x00, 0x01, 0x00, + // 0x02, + // 0x23, 0x00, 0x00, 0x00, + // 0x72, 0x00, + // 0x23, 0x00, 0x10, 0x00, + // 0x40, 0x00, + // 0x70, + // }; + // memcpy(&interpreter.code[0], program, sizeof(program)); + + // const uint16_t methods[] = { + // 0xffff, + // 0xffff, + // 0x0000, + // 0xffff, + // 0xffff, + // }; + // memcpy(&interpreter.methods[0], methods, sizeof(methods)); + +} + +void interpreter_start() +{ + // uBit.messageBus.listen(MICROBIT_ID_ANY, MICROBIT_EVT_ANY, onEvent); + + uBit.messageBus.listen(MICROBIT_ID_BUTTON_A, + MICROBIT_BUTTON_EVT_CLICK, + interpreter_on_button); + + uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, + MICROBIT_BUTTON_EVT_CLICK, + interpreter_on_button); + + uBit.messageBus.listen(MICROBIT_ID_BUTTON_AB, + MICROBIT_BUTTON_EVT_CLICK, + interpreter_on_button); + // MESSAGE_BUS_LISTENER_DROP_IF_BUSY); + + // MICROBIT_ACCELEROMETER_EVT_TILT_UP + // MICROBIT_ACCELEROMETER_EVT_TILT_DOWN + // MICROBIT_ACCELEROMETER_EVT_TILT_LEFT + // MICROBIT_ACCELEROMETER_EVT_TILT_RIGHT + // MICROBIT_ACCELEROMETER_EVT_FACE_UP + // MICROBIT_ACCELEROMETER_EVT_FACE_DOWN + // MICROBIT_ACCELEROMETER_EVT_FREEFALL + // MICROBIT_ACCELEROMETER_EVT_3G + // MICROBIT_ACCELEROMETER_EVT_6G + // MICROBIT_ACCELEROMETER_EVT_8G + // MICROBIT_ACCELEROMETER_EVT_SHAKE + + uBit.messageBus.listen(MICROBIT_ID_GESTURE, + MICROBIT_ACCELEROMETER_EVT_SHAKE, + interpreter_on_gesture); + + uBit.io.P12.isTouched(); + uBit.io.P0.isTouched(); + uBit.io.P1.isTouched(); + uBit.io.P16.isTouched(); + + // uBit.messageBus.listen(MICROBIT_ID_IO_P12, MICROBIT_EVT_ANY, onButton0); + // uBit.messageBus.listen(MICROBIT_ID_IO_P0, MICROBIT_EVT_ANY, onButton1); + // uBit.messageBus.listen(MICROBIT_ID_IO_P1, MICROBIT_EVT_ANY, onButton2); + // uBit.messageBus.listen(MICROBIT_ID_IO_P16, MICROBIT_EVT_ANY, onButton3); + + // Pin 0 + uBit.messageBus.listen(MICROBIT_ID_IO_P12, + MICROBIT_EVT_ANY, + interpreter_on_pin); + + // Pin 1 + uBit.messageBus.listen(MICROBIT_ID_IO_P0, + MICROBIT_EVT_ANY, + interpreter_on_pin); + + // Pin 2 + uBit.messageBus.listen(MICROBIT_ID_IO_P1, + MICROBIT_EVT_ANY, + interpreter_on_pin); + + // Pin 3 + uBit.messageBus.listen(MICROBIT_ID_IO_P16, + MICROBIT_EVT_ANY, + interpreter_on_pin); + + + interpreter_reset(); + + // new BluetoothServiceDebug(interpreter); + new BluetoothServiceProgram(interpreter); + notify = new BluetoothServiceNotify(interpreter); + + uBit.sleep(100); + + invoke(interpreter_fiber); +} + +uint16_t interpreter_calculate_hash() +{ + return 0; +} diff --git a/source/Interpreter.h b/source/Interpreter.h new file mode 100644 index 0000000..1d59957 --- /dev/null +++ b/source/Interpreter.h @@ -0,0 +1,132 @@ +#ifndef INTERPRETER_H +#define INTERPRETER_H + +#include + +#define VERSION_MAJOR 0 +#define VERSION_MINOR 0 + +#define METHODS_COUNT 5 +#define CODE_LEN 180 +#define REGISTER_COUNT 5 +#define CHARACTERISTICS_BUFFER_LEN 40 + +//#define LOG + +typedef enum { + INTERPRETER_OK = 0x00, + INTERPRETER_RX = 0x01, + INTERPRETER_RD = 0x02, + + INTERPRETER_KO_LEN_TOO_SHORT = 0x03, + INTERPRETER_KO_HASH_INVALID = 0x04, + INTERPRETER_KO_METHODS_TOO_SHORT = 0x05, + INTERPRETER_KO_METHODS_START_OUT_OF_BOUNDS = 0x06, + INTERPRETER_KO_METHODS_STOP_OUT_OF_BOUNDS = 0x07, + INTERPRETER_KO_CODE_TOO_SHORT = 0x08, + INTERPRETER_KO_CODE_START_OUT_OF_BOUNDS = 0x09, + INTERPRETER_KO_CODE_STOP_OUT_OF_BOUNDS = 0x0a, + INTERPRETER_KO_INSTRUCTION_UNKNOWN = 0x0b, + INTERPRETER_KO_INSTRUCTION_INVALID = 0x0c, + INTERPRETER_KO_DIVISION_BY_ZERO = 0x0d + +} InterpreterStatus; + +typedef struct { + InterpreterStatus status; + uint8_t code[CODE_LEN]; + uint16_t methods[METHODS_COUNT]; +} Interpreter; + +typedef enum { + COMPARED_EQ = 0, + COMPARED_GT = 1, + COMPARED_LT = 2 +} CompareState; + +typedef struct { + uint16_t pc; + uint16_t reg[REGISTER_COUNT]; + uint16_t stack; // this should be a stack, for now one address is enough + CompareState cs; +} RunState; + +typedef enum { + METHOD_STARTUP = 0, + METHOD_FOREVER = 1, + METHOD_ON_BUTTON = 2, + METHOD_ON_PIN = 3, + METHOD_ON_GESTURE = 4 +} InterpreterMethod; + +#define METHOD_UNUSED 0xffff + +typedef enum { + INS_RET = 0x00, + INS_REQ = 0x01, + INS_RNE = 0x02, + INS_RGT = 0x03, + INS_RLT = 0x04, + INS_RGE = 0x05, + INS_RLE = 0x06, + + INS_JSR = 0x07, + + INS_BRA = 0x10, + INS_BEQ = 0x11, + INS_BNE = 0x12, + INS_BGT = 0x13, + INS_BLT = 0x14, + INS_BGE = 0x15, + INS_BLE = 0x16, + INS_BRA16 = 0x17, + + INS_CMP = 0x20, + INS_CMPI = 0x21, + INS_MOV = 0x22, + INS_MOVI = 0x23, + + INS_ADD = 0x30, + INS_SUB = 0x31, + INS_MUL = 0x32, + INS_DIV = 0x33, + + INS_SLEEP = 0x40, + INS_RANDOM = 0x41, + INS_TIME = 0x42, + + INS_TEMPERATURE = 0x50, + INS_NOISE = 0x51, + INS_BRIGHTNESS = 0x52, + + INS_BUTTON = 0x60, + INS_PIN = 0x61, + + INS_DISPLAY_CLEAR = 0x70, + INS_DISPLAY_SHOW_NUMBER = 0x71, + INS_DISPLAY_SHOW_IMAGE = 0x72, + INS_DISPLAY_SHOW_GRID = 0x73, + INS_DISPLAY_SHOW_TEXT = 0x74, + + INS_RGB_OFF = 0x80, + INS_RGB_ON = 0x81, + + INS_SOUND_OFF = 0x90, + INS_SOUND_ON = 0x91, + + INS_ACC_GESTURE = 0xa0, + INS_ACC_PITCH = 0xa1, + INS_ACC_ROLL = 0xa2, + INS_ACC_POSITION = 0xa3, + + INS_NOTIFY = 0xf0, + INS_DEBUG = 0xf1 + +} InterpreterInstruction; + + +void interpreter_start(); +void interpreter_reset(); +uint16_t interpreter_calculate_hash(); + +#endif \ No newline at end of file diff --git a/source/Slice.cpp b/source/Slice.cpp new file mode 100644 index 0000000..0a7816f --- /dev/null +++ b/source/Slice.cpp @@ -0,0 +1,42 @@ +#include "Slice.h" + +Slice slice_create(uint8_t *buffer, uint16_t start, uint16_t stop) +{ + Slice slice; + slice.buffer = buffer; + slice.start = start; + slice.position = start; + slice.stop = stop; + return slice; +} + +uint16_t slice_available(Slice &slice) +{ + if (slice.position < slice.start) { + return 0; + } + if (slice.position >= slice.stop) { + return 0; + } + return slice.stop - slice.position; +} + +uint8_t slice_read8(Slice &slice) +{ + if (slice.position < slice.start) { + // assert + return 0; + } + if (slice.position >= slice.stop) { + // assert + return 0; + } + return slice.buffer[slice.position++]; +} + +uint16_t slice_read16(Slice &slice) +{ + uint8_t hi = slice_read8(slice); + uint8_t lo = slice_read8(slice); + return hi << 8 | lo; +} diff --git a/source/Slice.h b/source/Slice.h new file mode 100644 index 0000000..bad5c81 --- /dev/null +++ b/source/Slice.h @@ -0,0 +1,18 @@ +#ifndef SLICE_H +#define SLICE_H + +#include + +typedef struct { + uint8_t *buffer; + uint16_t start; + uint16_t position; + uint16_t stop; +} Slice; + +Slice slice_create(uint8_t *buffer, uint16_t start, uint16_t stop); +uint16_t slice_available(Slice &slice); +uint8_t slice_read8(Slice &slice); +uint16_t slice_read16(Slice &slice); + +#endif From 0dea9612f745ed3c3f132d080121cdf4ee2c4231 Mon Sep 17 00:00:00 2001 From: Torsten Curdt Date: Thu, 22 Feb 2018 11:00:43 +0100 Subject: [PATCH 02/28] big cleanup and refactoring session --- build-docker.sh | 3 - config.json | 7 +- contrib/copy.sh | 13 + contrib/log.sh | 9 + contrib/memsum.py | 65 ++ contrib/openocd.cfg | 10 + contrib/upload.sh | 3 + contrib/yotta.sh | 3 + source/CalliopeDemo.cpp | 781 ------------------ source/CalliopeDemo.h | 44 - source/CalliopeDemoMaster.cpp | 81 -- source/Images.cpp | 159 ++++ source/Images.h | 172 +--- source/Instruction.cpp | 55 +- source/Interpreter.cpp | 319 +++---- source/Interpreter.h | 10 +- source/Localization.h | 8 + source/Main.cpp | 103 +++ source/Menu.cpp | 66 ++ source/Menu.h | 13 + source/RunDemo.cpp | 123 +++ source/RunDemo.h | 3 + source/RunLoveMeter.cpp | 92 +++ source/RunLoveMeter.h | 3 + source/RunOracle.cpp | 74 ++ source/RunOracle.h | 3 + source/RunRockPaperScissors.cpp | 58 ++ source/RunRockPaperScissors.h | 3 + source/{Snake.cpp => RunSnake.cpp} | 188 +++-- source/RunSnake.h | 3 + .../{CalliopeTestBoard.cpp => RunTests.cpp} | 80 +- source/RunTests.h | 3 + source/Storage.h | 27 + source/Utils.cpp | 67 ++ source/Utils.h | 23 + 35 files changed, 1221 insertions(+), 1453 deletions(-) delete mode 100644 build-docker.sh create mode 100755 contrib/copy.sh create mode 100755 contrib/log.sh create mode 100644 contrib/memsum.py create mode 100644 contrib/openocd.cfg create mode 100755 contrib/upload.sh create mode 100755 contrib/yotta.sh delete mode 100644 source/CalliopeDemo.cpp delete mode 100644 source/CalliopeDemo.h delete mode 100644 source/CalliopeDemoMaster.cpp create mode 100644 source/Images.cpp create mode 100644 source/Localization.h create mode 100644 source/Main.cpp create mode 100644 source/Menu.cpp create mode 100644 source/Menu.h create mode 100644 source/RunDemo.cpp create mode 100644 source/RunDemo.h create mode 100644 source/RunLoveMeter.cpp create mode 100644 source/RunLoveMeter.h create mode 100644 source/RunOracle.cpp create mode 100644 source/RunOracle.h create mode 100644 source/RunRockPaperScissors.cpp create mode 100644 source/RunRockPaperScissors.h rename source/{Snake.cpp => RunSnake.cpp} (56%) create mode 100644 source/RunSnake.h rename source/{CalliopeTestBoard.cpp => RunTests.cpp} (75%) create mode 100644 source/RunTests.h create mode 100644 source/Storage.h create mode 100644 source/Utils.cpp create mode 100644 source/Utils.h diff --git a/build-docker.sh b/build-docker.sh deleted file mode 100644 index d9091ac..0000000 --- a/build-docker.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -docker run -v $(pwd):/project:rw -it calliope/build yotta build \ No newline at end of file diff --git a/config.json b/config.json index 6eb31ec..8856e57 100644 --- a/config.json +++ b/config.json @@ -4,7 +4,7 @@ "enabled": 1, "pairing_mode": 1, "private_addressing": 0, - "open": 0, + "open": 1, "whitelist": 1, "advertising_timeout": 0, "tx_power": 6, @@ -13,7 +13,8 @@ "device_info_service": 1, "security_level": "SECURITY_MODE_ENCRYPTION_NO_MITM" }, - "gatt_table_size": "0x700", - "debug": 0 + "gatt_table_size": "0x400", + "debug": 1, + "heap_debug": 1 } } diff --git a/contrib/copy.sh b/contrib/copy.sh new file mode 100755 index 0000000..2a73d04 --- /dev/null +++ b/contrib/copy.sh @@ -0,0 +1,13 @@ +#!/bin/sh + +SRC=../../calliope_playbook_mini/source/ +DST=`pwd`/source/ + +rsync -rtuv --progress $SRC $DST --exclude Main.* +#rsync -rtuv --progress $DST $SRC --exclude Main.* + +SRC=../../calliope_playbook_mini/contrib/ +DST=`pwd`/contrib/ + +rsync -rtuv --progress $SRC $DST +#rsync -rtuv --progress $DST $SRC diff --git a/contrib/log.sh b/contrib/log.sh new file mode 100755 index 0000000..9db7224 --- /dev/null +++ b/contrib/log.sh @@ -0,0 +1,9 @@ + +#!/bin/sh + +ROOT="$( cd "$(dirname "$0")" ; pwd -P )" +DEVICE=/dev/cu.usbmodem1422 + +#( stty speed 115200 cs8 1>/dev/null 2>&1; cat ) <$DEVICE +#( stty speed 115200 cs8 1>/dev/null 2>&1; hexdump -C ) <$DEVICE +( stty speed 115200 cs8 1>/dev/null 2>&1; python2 $ROOT/memsum.py Calliope) <$DEVICE diff --git a/contrib/memsum.py b/contrib/memsum.py new file mode 100644 index 0000000..bf85dff --- /dev/null +++ b/contrib/memsum.py @@ -0,0 +1,65 @@ +import re +import sys +import time + + +mem = {} +allocated = 0 + +reset = None +if len(sys.argv) > 1: + reset = sys.argv[1] + print("RESETTING tracer on '%s'" % reset) + +r_malloc = re.compile("^(microbit_)malloc:\\s+(NATIVE\\s+)?(ALLOCATED:)\\s+(\\d+)\\s+\\[(0x[0-9a-f]+)\\]") +r_free = re.compile("^(microbit_)free:\\s+(0x[0-9a-f]+)") + +partial = "" +#broken in python2 +#for line in sys.stdin: +for line in iter(sys.stdin.readline, ''): + # we sometimes get incomplete lines, wait for a full line + if not (line[-1] == '\n' or line[-1] == '\r'): + partial = line + continue + else: + line = partial + line + partial = "" + + # strip newline and carriage return + line = line.rstrip('\n').rstrip('\r') + + # if we detect the reset keyword, rest the map and memory counter + if reset != None and reset in line: + mem = {} + allocated = 0 + # print("\n\n\033[91m>> RESET >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\033[0m") + print("\033[H\033[J") + + # match malloc, realloc and free + m = r_malloc.search(line) + if m: + mem[m.group(5)] = int(m.group(4)) + allocated += int(m.group(4)) + print("\033[1m== (%03d) \033[34m%8d\033[0m [%8x] \033[31m+%-6d\033[0m (%s)" % \ + (len(mem), allocated, allocated, int(m.group(4)), + m.group(0).replace(m.group(1), "").replace(m.group(3), ""))) + continue + + m = r_free.search(line) + if m: + # print "f", m.group(3) + freed = 0 + if mem.has_key(m.group(2)): + freed = mem[m.group(2)] + allocated -= freed + del mem[m.group(2)] + else: + print ("\033[33m!! WARN: %s\033[0m" % (line)) + print ("\033[1m== (%03d) \033[34m%8d\033[0m [%8x] \033[92m-%-6d\033[0m (%s)" % \ + (len(mem), allocated, allocated, freed, m.group(0).replace(m.group(1), ""))) + continue + + # print all other lines as is, so we can still use the log functionality + print(line) + sys.stdout.flush() diff --git a/contrib/openocd.cfg b/contrib/openocd.cfg new file mode 100644 index 0000000..3a90556 --- /dev/null +++ b/contrib/openocd.cfg @@ -0,0 +1,10 @@ +source [find interface/cmsis-dap.cfg] +source [find target/nrf51.cfg] + +$_TARGETNAME configure -event gdb-attach { + reset init +} + +$_TARGETNAME configure -event gdb-flash-write-end { + reset init +} \ No newline at end of file diff --git a/contrib/upload.sh b/contrib/upload.sh new file mode 100755 index 0000000..a9be492 --- /dev/null +++ b/contrib/upload.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +cp build/calliope-mini-classic-gcc/source/*-combined.hex /Volumes/MINI/ diff --git a/contrib/yotta.sh b/contrib/yotta.sh new file mode 100755 index 0000000..825e040 --- /dev/null +++ b/contrib/yotta.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +docker run -v $(pwd):/project:rw -it calliope/build yotta $1 diff --git a/source/CalliopeDemo.cpp b/source/CalliopeDemo.cpp deleted file mode 100644 index f7fb3ca..0000000 --- a/source/CalliopeDemo.cpp +++ /dev/null @@ -1,781 +0,0 @@ -/** - * Calliope Demo Code. - * - * The code contains is the wrapper for the main functionality found after - * unpacking the Calliope mini. It contains the basic test functionality for - * in-production testing, as well as some small demo programs that can be - * selected using A and B buttons. - * - * - Oracle (press a button and get a smiley or sad face) - * - Rock, Paper, Scissors, Well - * - Love Meter (Pin 1 and 2) - * - Snake (adapted from the original microbit-samples) - * - ((game of life)) - * - ((proximty hearts)) - * - * The last two require the CalliopeDemoMaster to be compiled and put on - * an extra board. Then those games can be activated via Radio. - * - * @copyright (c) Calliope gGmbH. - * - * Licensed under the Apache Software License 2.0 (ASL 2.0) - * Portions (c) Copyright British Broadcasting Corporation under MIT License. - * - * @author Matthias L. Jugel - * @author Stephan Noller - * @author Franka Futterlieb - * @author Niranjan Rao - */ - -#include "MicroBit.h" -#include "CalliopeDemo.h" - -#ifndef COMPILE_FIRMWARE_MASTER - -const uint8_t full[25] = {1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 -}; -const uint8_t dot[25] = {0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0 -}; -const uint8_t small[25] = {0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, - 0, 1, 0, 1, 0, - 0, 1, 1, 1, 0, - 0, 0, 0, 0, 0 -}; -const uint8_t large[25] = {1, 1, 1, 1, 1, - 1, 0, 0, 0, 1, - 1, 0, 0, 0, 1, - 1, 0, 0, 0, 1, - 1, 1, 1, 1, 1, -}; -const uint8_t arrow_left[25] = {0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, - 1, 1, 1, 1, 1, - 0, 1, 0, 0, 0, - 0, 0, 1, 0, 0 -}; -const uint8_t arrow_right[25] = {0, 0, 1, 0, 0, - 0, 0, 0, 1, 0, - 1, 1, 1, 1, 1, - 0, 0, 0, 1, 0, - 0, 0, 1, 0, 0 -}; -const uint8_t arrow_leftright[25] = {0, 0, 1, 0, 0, - 0, 1, 0, 1, 0, - 1, 0, 0, 0, 1, - 0, 1, 0, 1, 0, - 0, 0, 1, 0, 0 -}; -const uint8_t double_row[25] = {0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0 -}; -const uint8_t tick[25] = {0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, - 0, 0, 0, 1, 0, - 1, 0, 1, 0, 0, - 0, 1, 0, 0, 0 -}; -const uint8_t heart[25] = {0, 1, 0, 1, 0, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 0, 1, 1, 1, 0, - 0, 0, 1, 0, 0 -}; -const uint8_t smiley[25] = {0, 1, 0, 1, 0, - 0, 1, 0, 1, 0, - 0, 0, 0, 0, 0, - 1, 0, 0, 0, 1, - 0, 1, 1, 1, 0 -}; -const uint8_t sadly[25] = {0, 1, 0, 1, 0, - 0, 1, 0, 1, 0, - 0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, - 1, 0, 0, 0, 1 -}; -const uint8_t rock[25] = {0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, - 0, 1, 1, 1, 0, - 0, 1, 1, 1, 0, - 0, 0, 0, 0, 0 -}; -const uint8_t scissors[25] = {1, 0, 0, 0, 1, - 0, 1, 0, 1, 0, - 0, 0, 1, 0, 0, - 0, 1, 0, 1, 0, - 1, 0, 0, 0, 1 -}; -const uint8_t well[25] = {0, 1, 1, 1, 0, - 1, 0, 0, 0, 1, - 1, 0, 0, 0, 1, - 1, 0, 0, 0, 1, - 0, 1, 1, 1, 0 -}; -const uint8_t flash[25] = {0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, - 1, 1, 1, 1, 1, - 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, - -}; -const uint8_t wave[7 * 5] = {0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 1, 0, 0, 1, 0, 0, 1, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0 -}; - -const MicroBitImage Full(5, 5, full); -const MicroBitImage Dot(5, 5, dot); -const MicroBitImage SmallRect(5, 5, small); -const MicroBitImage LargeRect(5, 5, large); -const MicroBitImage ArrowLeft(5, 5, arrow_left); -const MicroBitImage ArrowRight(5, 5, arrow_right); -const MicroBitImage ArrowLeftRight(5, 5, arrow_leftright); -const MicroBitImage DoubleRow(5, 5, double_row); -const MicroBitImage Tick(5, 5, tick); -const MicroBitImage Heart(5, 5, heart); -const MicroBitImage Smiley(5, 5, smiley); -const MicroBitImage Sadly(5, 5, sadly); -const MicroBitImage Rock(5, 5, rock); -const MicroBitImage Scissors(5, 5, scissors); -const MicroBitImage Well(5, 5, well); -const MicroBitImage Flash(5, 5, flash); -const MicroBitImage Wave(7, 5, wave); - -MicroBit uBit; - -// DEMO 0 - 3 -static const int MAX_DEMOS = 3; -static const int DEFAULT_PAUSE = 300; - -volatile bool eventOK = false; -volatile static bool introEventSkip = false; - -void simpleEventHandler(MicroBitEvent event) { - (void) event; - eventOK = true; -} - -void leaveBeep() { - uBit.soundmotor.soundOn(784); - uBit.sleep(125); - uBit.soundmotor.soundOff(); -} - -void introSkipEventHandler(MicroBitEvent event) { - (void)event; - leaveBeep(); - uBit.display.stopAnimation(); - introEventSkip = true; - eventOK = true; -} - -static bool on = true; - -void blinkImage(const MicroBitImage &image, int interval, int rate) { - if (rate % interval == 0) { - if (on) uBit.display.printAsync(image, 0, 0, 0, 100); - else uBit.display.clear(); - on = !on; - } - uBit.sleep(100); -} - -void introBlinkImage(const MicroBitImage &image, int interval) { - int rate = 0; - do blinkImage(image, interval, ++rate); while (!eventOK); - uBit.display.clear(); -} - -void introAnimateImage(const MicroBitImage &image, int interval, int pos1, int pos2) { - int rate = 0; - bool on = true; - do { - if (++rate % interval == 0) { - uBit.display.clear(); - if (on) uBit.display.print(image, pos1, 0, 0, 200); - else uBit.display.print(image, pos2, 0, 0, 200); - on = !on; - } - uBit.sleep(100); - } while (!eventOK); - uBit.display.clear(); -} - -void dadadada() { - for (int i = 0; i < 3; i++) { - uBit.soundmotor.soundOn(392); - fiber_sleep(125); - uBit.soundmotor.soundOff(); - fiber_sleep(63); - } - uBit.soundmotor.soundOn(311); - fiber_sleep(1500); - uBit.soundmotor.soundOff(); - fiber_sleep(63); - for (int i = 0; i < 3; i++) { - uBit.soundmotor.soundOn(349); - fiber_sleep(125); - uBit.soundmotor.soundOff(); - fiber_sleep(63); - } - uBit.soundmotor.soundOn(294); - fiber_sleep(1500); - uBit.soundmotor.soundOff(); -} - -void freeFall(MicroBitEvent event) { - if (event.source == MICROBIT_ID_GESTURE && event.value == MICROBIT_ACCELEROMETER_EVT_FREEFALL) { - invoke(dadadada); - } -} - -void startSound() { - uBit.soundmotor.soundOn(262); - fiber_sleep(125); - uBit.soundmotor.soundOff(); - fiber_sleep(63); - uBit.soundmotor.soundOn(784); - fiber_sleep(500); - uBit.soundmotor.soundOff(); -} - -void showIntro() { - uBit.messageBus.listen(MICROBIT_ID_BUTTON_AB, MICROBIT_BUTTON_EVT_LONG_CLICK, introSkipEventHandler); - - invoke(startSound); - - uBit.display.scroll(DISPLAY_HELLO); - // press A - uBit.display.print("A"); - uBit.sleep(DEFAULT_PAUSE); - uBit.messageBus.listen(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK, simpleEventHandler); - introBlinkImage(ArrowLeft, 4); - if (introEventSkip) return; - uBit.messageBus.ignore(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK, simpleEventHandler); - eventOK = false; - uBit.display.print(Tick); - uBit.sleep(DEFAULT_PAUSE); - uBit.display.clear(); - - // press B - uBit.display.print("B"); - uBit.sleep(DEFAULT_PAUSE); - uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, simpleEventHandler); - introBlinkImage(ArrowRight, 4); - if (introEventSkip) return; - uBit.messageBus.ignore(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, simpleEventHandler); - eventOK = false; - uBit.display.print(Tick); - uBit.sleep(DEFAULT_PAUSE); - uBit.display.clear(); - - // press A+B - uBit.display.scroll("A+B"); - uBit.messageBus.listen(MICROBIT_ID_BUTTON_AB, MICROBIT_BUTTON_EVT_CLICK, simpleEventHandler); - introBlinkImage(ArrowLeftRight, 4); - if (introEventSkip) return; - leaveBeep(); - uBit.messageBus.ignore(MICROBIT_ID_BUTTON_AB, MICROBIT_BUTTON_EVT_CLICK, simpleEventHandler); - eventOK = false; - uBit.display.print(Tick); - uBit.sleep(DEFAULT_PAUSE); - uBit.display.clear(); - - // shake - uBit.display.scroll(DISPLAY_SHAKE); - uBit.messageBus.listen(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_SHAKE, simpleEventHandler); - introAnimateImage(DoubleRow, 2, -1, 2); - if (introEventSkip) return; - uBit.messageBus.ignore(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_SHAKE, simpleEventHandler); - eventOK = false; - uBit.display.print(Tick); - uBit.sleep(DEFAULT_PAUSE); - uBit.display.clear(); - uBit.display.scroll(DISPLAY_SUPER); - - // show heart and change RGB led colors randomly - - on = true; - for (int rate = 0; rate < 25; rate++) { - if (introEventSkip) return; - blinkImage(Heart, 2, rate); - uBit.seedRandom(); - if (rate % 2 == 0) { - int r = uBit.random(DEFAULT_PAUSE); - if (r < 100) uBit.rgb.setColour(0xFF, 0xA5, 0x00, 0x00); - else if (r < 200) uBit.rgb.setColour(0x00, 0xFF, 0x00, 0x00); - else if (r < 300) uBit.rgb.setColour(0xFF, 0xA5, 0x00, 0x000); - } - uBit.sleep(100); - } - uBit.rgb.off(); - uBit.display.clear(); - - if (introEventSkip) return; - uBit.display.print(Smiley); - uBit.sleep(1000); -} - - -// MENU handling -volatile state_t state = Intro; - -static int selectedDemo = 0; - -void menuDown(MicroBitEvent event) { - (void)event; - selectedDemo--; - if (selectedDemo < 0) selectedDemo = MAX_DEMOS; - uBit.display.print(ManagedString(selectedDemo + 1)); -} - -void menuUp(MicroBitEvent event) { - (void)event; - selectedDemo++; - if (selectedDemo > MAX_DEMOS) selectedDemo = 0; - uBit.display.print(ManagedString(selectedDemo + 1)); -} - -void menuAnimateEnter() { - uBit.display.print(Dot, 0, 0, 0, 200); - uBit.display.print(SmallRect, 0, 0, 0, 200); - uBit.display.print(LargeRect, 0, 0, 0, 200); - uBit.display.clear(); -} - -void menuAnimateLeave() { - uBit.display.print(LargeRect, 0, 0, 0, 200); - uBit.display.print(SmallRect, 0, 0, 0, 200); - uBit.display.print(Dot, 0, 0, 0, 200); - uBit.display.clear(); -} - -// Oracle Demo -void leaveOracle(MicroBitEvent event) { - (void)event; - uBit.messageBus.ignore(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK, simpleEventHandler); - uBit.messageBus.ignore(MICROBIT_ID_BUTTON_AB, MICROBIT_BUTTON_EVT_CLICK, leaveOracle); - leaveBeep(); - state = Menu; - eventOK = true; -} - -void oracle() { - uBit.messageBus.listen(MICROBIT_ID_BUTTON_AB, MICROBIT_BUTTON_EVT_CLICK, leaveOracle); - - uBit.display.scroll(DISPLAY_ORACLE); - uBit.messageBus.listen(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK, simpleEventHandler); - do { - eventOK = false; - introBlinkImage(ArrowLeft, 4); - if (state != Oracle) break; - for (int i = 0; i < 5; i++) { - uBit.display.print(Dot, 0, 0, 0, DEFAULT_PAUSE); - uBit.display.clear(); - uBit.sleep(200); - } - int r = uBit.random(100); - if (r < 50) uBit.display.print(Smiley); - else uBit.display.print(Sadly); - uBit.sleep(3000); - uBit.display.clear(); - } while (state == Oracle); -} - -// Rock Paper Scissors Well Demo -void leaveRockPaperScissors(MicroBitEvent event) { - (void)event; - uBit.messageBus.ignore(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_SHAKE, simpleEventHandler); - uBit.messageBus.ignore(MICROBIT_ID_BUTTON_AB, MICROBIT_BUTTON_EVT_CLICK, leaveRockPaperScissors); - leaveBeep(); - state = Menu; - eventOK = true; -} - -void rockPaperScissors() { - uBit.messageBus.listen(MICROBIT_ID_BUTTON_AB, MICROBIT_BUTTON_EVT_CLICK, leaveRockPaperScissors); - - uBit.display.print(Rock, 0, 0, 0, DEFAULT_PAUSE * 2); - uBit.display.print(Full, 0, 0, 0, DEFAULT_PAUSE * 2); - uBit.display.print(Scissors, 0, 0, 0, DEFAULT_PAUSE * 2); - uBit.display.print(Well, 0, 0, 0, DEFAULT_PAUSE * 2); - uBit.display.clear(); - uBit.sleep(DEFAULT_PAUSE); - - uBit.messageBus.listen(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_SHAKE, simpleEventHandler); - do { - eventOK = false; - introAnimateImage(DoubleRow, 2, -1, 2); - if (state != RockPaperScissors) break; - int r = uBit.random(400); - if (r < 100) uBit.display.print(Rock); - else if (r < 200) uBit.display.print(Full); - else if (r < 300) uBit.display.print(Scissors); - else uBit.display.print(Well); - uBit.sleep(3000); - uBit.display.clear(); - } while (state == RockPaperScissors); -} - -// Love Meter Demo -int touch_p1 = 0; -int touch_p2 = 0; - -// a little co-routing that does the measuring while we are waiting for both pins touched -void loveMeterMeasuring() { - touch_p1 = uBit.io.P1.getAnalogValue(); - touch_p2 = uBit.io.P2.getAnalogValue(); - do { - fiber_sleep(300); - int p1 = uBit.io.P1.getAnalogValue(); - int p2 = uBit.io.P2.getAnalogValue(); - eventOK = (abs(touch_p1 - p1) > 20 && abs(touch_p2 - p2) > 20); - } while (state == LoveMeter); -} - -void leaveLoveMeter(MicroBitEvent event) { - (void)event; - uBit.messageBus.ignore(MICROBIT_ID_BUTTON_AB, MICROBIT_BUTTON_EVT_CLICK, leaveLoveMeter); - leaveBeep(); - state = Menu; - eventOK = true; -} - -void loveMeter() { - uBit.messageBus.listen(MICROBIT_ID_BUTTON_AB, MICROBIT_BUTTON_EVT_CLICK, leaveLoveMeter); - - uBit.display.print(Heart, 0, 0, 0, DEFAULT_PAUSE); - invoke(loveMeterMeasuring); - - uBit.io.P1.isTouched(); - uBit.io.P2.isTouched(); - - do { - eventOK = false; - introAnimateImage(Wave, 2, -1, -2); - if (state != LoveMeter) break; - int p1 = uBit.io.P1.getAnalogValue(); - int p2 = uBit.io.P2.getAnalogValue(); - int v1 = (int) (p1 * 9.0 / 1023.0); - int v2 = (int) (p2 * 9.0 / 1023.0); - int v3 = 9 - abs(v1 - v2); - uBit.display.print(v3); - uBit.sleep(1000); - if (v3 > 6) { - uBit.display.print(Heart); - uBit.soundmotor.soundOn(1000); - uBit.sleep(100); - uBit.soundmotor.soundOn(2000); - uBit.sleep(100); - uBit.soundmotor.soundOn(3000); - uBit.sleep(300); - uBit.soundmotor.soundOff(); - uBit.sleep(4000); - } else { - uBit.display.print(Flash); - uBit.soundmotor.soundOn(1000); - uBit.sleep(100); - uBit.soundmotor.soundOn(500); - uBit.sleep(100); - uBit.soundmotor.soundOn(100); - uBit.sleep(300); - uBit.soundmotor.soundOff(); - uBit.sleep(4000); - } - uBit.display.clear(); - } while (state == LoveMeter); -} - -// Snake Demo -void leaveSnake(MicroBitEvent event) { - (void)event; - uBit.messageBus.ignore(MICROBIT_ID_BUTTON_AB, MICROBIT_BUTTON_EVT_CLICK, leaveSnake); - leaveBeep(); - state = Menu; - eventOK = true; -} - -void runSnake() { - uBit.messageBus.listen(MICROBIT_ID_BUTTON_AB, MICROBIT_BUTTON_EVT_CLICK, leaveLoveMeter); - eventOK = false; - snake(); -} - -bool specialAttachmentActive = false; -bool foundPartner = false; -int specialAttachmentTransmitPower = 1; - -bool takeOverActive = false; -bool takeOverState = false; -uint8_t neighbors = 0; -uint8_t neighborIndex = 0; - -void onData(MicroBitEvent event) { - (void)event; - PacketBuffer packet = uBit.radio.datagram.recv(); - uBit.serial.send(packet); - - if (specialAttachmentActive) { - if (packet.getByte(0) == 'E') { - specialAttachmentTransmitPower = min(packet.getByte(1) - '0', 7); - state = Menu; - specialAttachmentActive = false; - selectedDemo = 0; - // proxy end of game - uBit.radio.setTransmitPower(7); - uBit.radio.datagram.send("E"); - } else { - const int signalStrength = packet.getRSSI(); - uBit.serial.send(ManagedString(signalStrength)); - uBit.serial.send("\r\n"); - foundPartner = packet.getByte(0) == '!' && signalStrength < 75; - } - } else if (takeOverActive) { - if (packet.getByte(0) == 'E') { - state = Menu; - takeOverActive = false; - neighborIndex = 99; - selectedDemo = 0; - // proxy end of game - uBit.radio.datagram.send("E"); - } else if (neighborIndex < 8) { - switch (packet.getByte(0)) { - case '0': - neighborIndex++; - break; - case '1': - neighbors++; - neighborIndex++; - break; - default: - break; - } - } - } else { - if (packet.getByte(0) == 'H') { - specialAttachmentActive = true; - state = Menu; - eventOK = true; - selectedDemo = 5; - uBit.radio.setTransmitPower(7); - uBit.radio.datagram.send("H"); - uBit.messageBus.send(MicroBitEvent(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_SHAKE)); - } else if (packet.getByte(0) == 'S') { - takeOverActive = true; - state = Menu; - eventOK = true; - selectedDemo = 4; - uBit.messageBus.send(MicroBitEvent(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_SHAKE)); - uBit.radio.setTransmitPower(7); - uBit.radio.datagram.send("S"); - } else if (packet.getByte(0) == 'E') { - // proxy end of game - takeOverActive = false; - specialAttachmentActive = false; - uBit.radio.setTransmitPower(7); - uBit.radio.datagram.send("E"); - } - } -} - -void liveOrDead() { - uBit.display.image.setPixelValue(1, 1, (uint8_t) (takeOverState ? 255 : 0)); - uBit.display.image.setPixelValue(1, 2, (uint8_t) (takeOverState ? 255 : 0)); - uBit.display.image.setPixelValue(1, 3, (uint8_t) (takeOverState ? 255 : 0)); - uBit.display.image.setPixelValue(2, 1, (uint8_t) (takeOverState ? 255 : 0)); - uBit.display.image.setPixelValue(2, 2, (uint8_t) (takeOverState ? 255 : 0)); - uBit.display.image.setPixelValue(2, 3, (uint8_t) (takeOverState ? 255 : 0)); - uBit.display.image.setPixelValue(3, 1, (uint8_t) (takeOverState ? 255 : 0)); - uBit.display.image.setPixelValue(3, 2, (uint8_t) (takeOverState ? 255 : 0)); - uBit.display.image.setPixelValue(3, 3, (uint8_t) (takeOverState ? 255 : 0)); -} - -void takeOver() { - int displayMode = uBit.display.getDisplayMode(); - uBit.display.setDisplayMode(DISPLAY_MODE_GREYSCALE); - - neighborIndex = 0; - neighbors = 0; - takeOverState = uBit.random(100) > 20; - liveOrDead(); - - uBit.soundmotor.soundOn(262); - uBit.sleep(125); - uBit.soundmotor.soundOff(); - uBit.sleep(63); - uBit.soundmotor.soundOn(784); - uBit.sleep(125); - uBit.soundmotor.soundOff(); - - uBit.display.clear(); - while (state == TakeOver) { - unsigned long timeout = uBit.systemTime() + 5000; - uBit.serial.send(neighborIndex); - - int x = 0, y = 0; - uBit.display.image.setPixelValue(x, y, 64); - while (neighborIndex < 8 && timeout > uBit.systemTime()) { - uBit.sleep(200); - uBit.display.image.setPixelValue(x, y, 0); - if (y == 0 && x < 4) x++; - else if (x == 4 && y < 4) y++; - else if (y == 4 && x > 0) x--; - else if (x == 0 && y > 0) y--; - uBit.display.image.setPixelValue(x, y, 64); - } - uBit.display.image.setPixelValue(x, y, 0); - // only act if takeover is active - if (takeOverActive) { - if (takeOverState && (neighbors < 2 || neighbors > 3)) takeOverState = false; - else if (!takeOverState && neighbors == 3) takeOverState = true; - - liveOrDead(); - - neighbors = 0; - neighborIndex = 0; - uBit.radio.datagram.send(takeOverState ? "1" : "0"); - } - uBit.sleep(DEFAULT_PAUSE); - } - uBit.soundmotor.soundOn(784); - uBit.sleep(125); - uBit.soundmotor.soundOff(); - uBit.sleep(63); - uBit.soundmotor.soundOn(262); - uBit.sleep(125); - uBit.soundmotor.soundOff(); - - uBit.display.setDisplayMode((DisplayMode) displayMode); -} - -void specialAttachment() { - uBit.soundmotor.soundOn(262); - uBit.sleep(125); - uBit.soundmotor.soundOff(); - uBit.sleep(63); - uBit.soundmotor.soundOn(784); - uBit.sleep(125); - uBit.soundmotor.soundOff(); - - uBit.display.clear(); - while (state == SpecialAttachment) { - if (uBit.systemTime() % 1000 < 500) uBit.display.clear(); - else if (foundPartner) uBit.display.print(Heart); - else uBit.display.image.setPixelValue(2, 2, 255); - uBit.radio.setTransmitPower(specialAttachmentTransmitPower); - uBit.radio.datagram.send("!"); - uBit.sleep(DEFAULT_PAUSE); - } - - uBit.soundmotor.soundOn(784); - uBit.sleep(125); - uBit.soundmotor.soundOff(); - uBit.sleep(63); - uBit.soundmotor.soundOn(262); - uBit.sleep(125); - uBit.soundmotor.soundOff(); -} - -// Menu Selection -void menuSelect(MicroBitEvent event); - -void initializeMenu() { - uBit.messageBus.listen(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK, menuDown); - uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, menuUp); - uBit.messageBus.listen(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_SHAKE, menuSelect); - uBit.display.print(ManagedString(selectedDemo + 1)); -} - -void menuSelect(MicroBitEvent event) { - (void)event; - uBit.messageBus.ignore(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK, menuDown); - uBit.messageBus.ignore(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, menuUp); - uBit.messageBus.ignore(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_SHAKE, menuSelect); - - menuAnimateEnter(); - switch (selectedDemo) { - case 0: - state = Oracle; - oracle(); - break; - case 1: - state = RockPaperScissors; - rockPaperScissors(); - break; - case 2: - state = LoveMeter; - loveMeter(); - break; - case 3: - state = Snake; - runSnake(); - break; - case 4: - state = TakeOver; - takeOver(); - break; - case 5: - state = SpecialAttachment; - specialAttachment(); - break; - default: - state = Menu; - uBit.display.scroll(DISPLAY_ERROR); - selectedDemo = 0; - uBit.messageBus.send(MicroBitEvent(MICROBIT_ID_BUTTON_AB, MICROBIT_BUTTON_EVT_CLICK)); - break; - } - menuAnimateLeave(); - initializeMenu(); -} - -int main() { - // Initialise the micro:bit runtime. - uBit.init(); - uBit.serial.baud(115200); - uBit.serial.send("Calliope Demo v1.0\r\n"); - // disabled the test board procedure as it may confuse users who burn the initial firmware - // call the test board procedure, will return if done already - testBoard(); - - // initialize random - uBit.seedRandom(); - - showIntro(); - uBit.messageBus.ignore(MICROBIT_ID_BUTTON_AB, MICROBIT_BUTTON_EVT_LONG_CLICK, introSkipEventHandler); - uBit.messageBus.listen(MICROBIT_ID_GESTURE, MICROBIT_EVT_ANY, freeFall); - - state = Menu; - - uBit.display.clear(); - on = true; - for (int i = 0; i < 5; i++) { - blinkImage(Dot, 2, 2); - uBit.sleep(DEFAULT_PAUSE); - } - uBit.display.clear(); - - // init take over - uBit.messageBus.listen(MICROBIT_ID_RADIO, MICROBIT_RADIO_EVT_DATAGRAM, onData); - uBit.radio.enable(); - uBit.radio.setGroup(227); - - initializeMenu(); - - while (true) uBit.sleep(100); -} - -#endif diff --git a/source/CalliopeDemo.h b/source/CalliopeDemo.h deleted file mode 100644 index d696e20..0000000 --- a/source/CalliopeDemo.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef CALLOPE_DEMO_H -#define CALLOPE_DEMO_H - - -// MENU HANDLING -typedef volatile enum State { - Intro = 0, - Menu, - Oracle, - RockPaperScissors, - LoveMeter, - Snake, - SpecialAttachment = 55, - TakeOver = 99, -} state_t; - -extern const MicroBitImage Full; -extern const MicroBitImage Tick; - -void testBoard(); -void snake(); - -#ifdef YOTTA_CFG_COMPILE_MASTER -#define COMPILE_FIRMWARE_MASTER 0 -#endif - -// localization -#ifdef YOTTA_CFG_USE_ENGLISH -#define DISPLAY_HELLO "Hello!" -#define DISPLAY_SHAKE "SHAKE" -#define DISPLAY_ORACLE "Oracle" -#define DISPLAY_SUPER "SUPER!" -#define DISPLAY_THEEND "THE END" -#define DISPLAY_ERROR "Oops?" -#else -#define DISPLAY_HELLO "Hallo!" -#define DISPLAY_SHAKE "SCHUETTELN" -#define DISPLAY_ORACLE "Orakel" -#define DISPLAY_SUPER "SUPER!" -#define DISPLAY_THEEND "ENDE" -#define DISPLAY_ERROR "Huch?" -#endif - -#endif diff --git a/source/CalliopeDemoMaster.cpp b/source/CalliopeDemoMaster.cpp deleted file mode 100644 index d0736f3..0000000 --- a/source/CalliopeDemoMaster.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/** - * Callipe Demo Master - * - * This is a special master program that can be flashed onto - * an extra board and used to activate the hidden games in the - * official firmware. - * - * Press A to activate Conways game of life in all minis found. - * Press B to acticate Priximity Hearts in all minis found. - * Press A+B to stop the games. - * - * The minis will proxy the start and stop codes. - * - * @copyright (c) Calliope gGmbH. - * - * Licensed under the Apache Software License 2.0 (ASL 2.0) - * - * @author Matthias L. Jugel - */ - -#include "MicroBit.h" -#include "CalliopeDemo.h" -#include "nrf_delay.h" -#include "nrf_gpio.h" - - -#ifdef COMPILE_FIRMWARE_MASTER - -MicroBit uBit; - - -void buttonA(MicroBitEvent event) { - (void)event; - uBit.serial.send("START\r\n"); - uBit.radio.datagram.send("S"); -} - -void buttonB(MicroBitEvent event) { - (void)event; - uBit.serial.send("START 1\r\n"); - uBit.radio.datagram.send("H1"); -} - -void buttonB1(MicroBitEvent event) { - (void)event; - uBit.serial.send("RANDOM SEED\r\n"); - uBit.radio.datagram.send(uBit.random(100) > 20 ? "1" : "0"); -} - -void buttonAB(MicroBitEvent event) { - (void)event; - uBit.serial.send("END\r\n"); - uBit.radio.datagram.send("E"); -} - - -void onData(MicroBitEvent event) { - (void)event; - PacketBuffer packet = uBit.radio.datagram.recv(); - uBit.serial.send("RECEIVED\r\n"); - uBit.serial.send(packet); - uBit.display.print(packet); -} - -int main() { - uBit.init(); - - uBit.messageBus.listen(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK, buttonA); - uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, buttonB); - uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_LONG_CLICK, buttonB1); - uBit.messageBus.listen(MICROBIT_ID_BUTTON_AB, MICROBIT_BUTTON_EVT_CLICK, buttonAB); - - uBit.messageBus.listen(MICROBIT_ID_RADIO, MICROBIT_RADIO_EVT_DATAGRAM, onData); - - if(uBit.radio.enable() == MICROBIT_OK) uBit.display.scroll("RDY"); - uBit.radio.setGroup(227); - - while(true) uBit.sleep(100); -} - -#endif diff --git a/source/Images.cpp b/source/Images.cpp new file mode 100644 index 0000000..4968f37 --- /dev/null +++ b/source/Images.cpp @@ -0,0 +1,159 @@ +#include "Images.h" + +static const uint8_t pixel_full[25] = { + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 +}; +static const uint8_t pixel_dot[25] = { + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 +}; +static const uint8_t pixel_small[25] = { + 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, + 0, 1, 0, 1, 0, + 0, 1, 1, 1, 0, + 0, 0, 0, 0, 0 +}; +static const uint8_t pixel_large[25] = { + 1, 1, 1, 1, 1, + 1, 0, 0, 0, 1, + 1, 0, 0, 0, 1, + 1, 0, 0, 0, 1, + 1, 1, 1, 1, 1, +}; +static const uint8_t pixel_arrow_left[25] = { + 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, + 1, 1, 1, 1, 1, + 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0 +}; +static const uint8_t pixel_arrow_right[25] = { + 0, 0, 1, 0, 0, + 0, 0, 0, 1, 0, + 1, 1, 1, 1, 1, + 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0 +}; +static const uint8_t pixel_arrow_leftright[25] = { + 0, 0, 1, 0, 0, + 0, 1, 0, 1, 0, + 1, 0, 0, 0, 1, + 0, 1, 0, 1, 0, + 0, 0, 1, 0, 0 +}; +static const uint8_t pixel_double_row[25] = { + 0, 1, 1, 0, 0, + 0, 1, 1, 0, 0, + 0, 1, 1, 0, 0, + 0, 1, 1, 0, 0, + 0, 1, 1, 0, 0 +}; +static const uint8_t pixel_tick[25] = { + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, + 0, 0, 0, 1, 0, + 1, 0, 1, 0, 0, + 0, 1, 0, 0, 0 +}; +static const uint8_t pixel_heart[25] = { + 0, 1, 0, 1, 0, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 0, 1, 1, 1, 0, + 0, 0, 1, 0, 0 +}; +static const uint8_t pixel_smiley[25] = { + 0, 1, 0, 1, 0, + 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, + 0, 1, 1, 1, 0 +}; +static const uint8_t pixel_sadly[25] = { + 0, 1, 0, 1, 0, + 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, + 1, 0, 0, 0, 1 +}; +static const uint8_t pixel_rock[25] = { + 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, + 0, 1, 1, 1, 0, + 0, 1, 1, 1, 0, + 0, 0, 0, 0, 0 +}; +static const uint8_t pixel_scissors[25] = { + 1, 0, 0, 0, 1, + 0, 1, 0, 1, 0, + 0, 0, 1, 0, 0, + 0, 1, 0, 1, 0, + 1, 0, 0, 0, 1 +}; +static const uint8_t pixel_well[25] = { + 0, 1, 1, 1, 0, + 1, 0, 0, 0, 1, + 1, 0, 0, 0, 1, + 1, 0, 0, 0, 1, + 0, 1, 1, 1, 0 +}; +static const uint8_t pixel_flash[25] = { + 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, + 1, 1, 1, 1, 1, + 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, +}; +static const uint8_t pixel_wave[7 * 5] = { + 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, + 1, 0, 0, 1, 0, 0, 1, + 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0 +}; + +const MicroBitImage ImageSmiley(5, 5, pixel_smiley); +const MicroBitImage ImageSadly(5, 5, pixel_sadly); +const MicroBitImage ImageHeart(5, 5, pixel_heart); +const MicroBitImage ImageArrowLeft(5, 5, pixel_arrow_left); +const MicroBitImage ImageArrowRight(5, 5, pixel_arrow_right); +const MicroBitImage ImageArrowLeftRight(5, 5, pixel_arrow_leftright); +const MicroBitImage ImageFull(5, 5, pixel_full); +const MicroBitImage ImageDot(5, 5, pixel_dot); +const MicroBitImage ImageSmallRect(5, 5, pixel_small); +const MicroBitImage ImageLargeRect(5, 5, pixel_large); +const MicroBitImage ImageDoubleRow(5, 5, pixel_double_row); +const MicroBitImage ImageTick(5, 5, pixel_tick); +const MicroBitImage ImageRock(5, 5, pixel_rock); +const MicroBitImage ImageScissors(5, 5, pixel_scissors); +const MicroBitImage ImageWell(5, 5, pixel_well); +const MicroBitImage ImageFlash(5, 5, pixel_flash); +const MicroBitImage ImageWave(7, 5, pixel_wave); + +const MicroBitImage *images[17] = { + &ImageSmiley, + &ImageSadly, + &ImageHeart, + &ImageArrowLeft, + &ImageArrowRight, + &ImageArrowLeftRight, + &ImageFull, + &ImageDot, + &ImageSmallRect, + &ImageLargeRect, + &ImageDoubleRow, + &ImageTick, + &ImageRock, + &ImageScissors, + &ImageWell, + &ImageFlash, + &ImageWave, +}; diff --git a/source/Images.h b/source/Images.h index 33a3bd8..64abce4 100644 --- a/source/Images.h +++ b/source/Images.h @@ -1,149 +1,23 @@ -#ifndef IMAGES_H -#define IMAGES_H - -static const uint8_t pixels_smiley[25] = { - 0, 1, 0, 1, 0, - 0, 1, 0, 1, 0, - 0, 0, 0, 0, 0, - 1, 0, 0, 0, 1, - 0, 1, 1, 1, 0 -}; - -static const uint8_t pixels_sadly[25] = { - 0, 1, 0, 1, 0, - 0, 1, 0, 1, 0, - 0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, - 1, 0, 0, 0, 1 -}; - -static const uint8_t pixels_heart[25] = { - 0, 1, 0, 1, 0, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 0, 1, 1, 1, 0, - 0, 0, 1, 0, 0 -}; - -static const uint8_t pixels_arrow_left[25] = { - 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, - 1, 1, 1, 1, 1, - 0, 1, 0, 0, 0, - 0, 0, 1, 0, 0 -}; -static const uint8_t pixels_arrow_right[25] = { - 0, 0, 1, 0, 0, - 0, 0, 0, 1, 0, - 1, 1, 1, 1, 1, - 0, 0, 0, 1, 0, - 0, 0, 1, 0, 0 -}; -static const uint8_t pixels_arrow_leftright[25] = { - 0, 0, 1, 0, 0, - 0, 1, 0, 1, 0, - 1, 0, 0, 0, 1, - 0, 1, 0, 1, 0, - 0, 0, 1, 0, 0 -}; - - -const MicroBitImage images[] = { - MicroBitImage(5, 5, pixels_smiley), - MicroBitImage(5, 5, pixels_sadly), - MicroBitImage(5, 5, pixels_heart), - MicroBitImage(5, 5, pixels_arrow_left), - MicroBitImage(5, 5, pixels_arrow_right), - MicroBitImage(5, 5, pixels_arrow_leftright), -}; - - -/* -const uint8_t full[25] = {1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 -}; -const uint8_t dot[25] = {0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0 -}; -const uint8_t small[25] = {0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, - 0, 1, 0, 1, 0, - 0, 1, 1, 1, 0, - 0, 0, 0, 0, 0 -}; -const uint8_t large[25] = {1, 1, 1, 1, 1, - 1, 0, 0, 0, 1, - 1, 0, 0, 0, 1, - 1, 0, 0, 0, 1, - 1, 1, 1, 1, 1, -}; -const uint8_t double_row[25] = {0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0 -}; -const uint8_t tick[25] = {0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, - 0, 0, 0, 1, 0, - 1, 0, 1, 0, 0, - 0, 1, 0, 0, 0 -}; -const uint8_t rock[25] = {0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, - 0, 1, 1, 1, 0, - 0, 1, 1, 1, 0, - 0, 0, 0, 0, 0 -}; -const uint8_t scissors[25] = {1, 0, 0, 0, 1, - 0, 1, 0, 1, 0, - 0, 0, 1, 0, 0, - 0, 1, 0, 1, 0, - 1, 0, 0, 0, 1 -}; -const uint8_t well[25] = {0, 1, 1, 1, 0, - 1, 0, 0, 0, 1, - 1, 0, 0, 0, 1, - 1, 0, 0, 0, 1, - 0, 1, 1, 1, 0 -}; -const uint8_t flash[25] = {0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, - 1, 1, 1, 1, 1, - 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, - -}; -const uint8_t wave[7 * 5] = {0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 1, 0, 0, 1, 0, 0, 1, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0 -}; - -const MicroBitImage Full(5, 5, full); -const MicroBitImage Dot(5, 5, dot); -const MicroBitImage SmallRect(5, 5, small); -const MicroBitImage LargeRect(5, 5, large); -const MicroBitImage ArrowLeft(5, 5, arrow_left); -const MicroBitImage ArrowRight(5, 5, arrow_right); -const MicroBitImage ArrowLeftRight(5, 5, arrow_leftright); -const MicroBitImage DoubleRow(5, 5, double_row); -const MicroBitImage Tick(5, 5, tick); -const MicroBitImage Heart(5, 5, heart); -const MicroBitImage Smiley(5, 5, smiley); -const MicroBitImage Sadly(5, 5, sadly); -const MicroBitImage Rock(5, 5, rock); -const MicroBitImage Scissors(5, 5, scissors); -const MicroBitImage Well(5, 5, well); -const MicroBitImage Flash(5, 5, flash); -const MicroBitImage Wave(7, 5, wave); -*/ - -#endif \ No newline at end of file +#pragma once + +#include "MicroBitImage.h" + +extern const MicroBitImage *images[17]; + +extern const MicroBitImage ImageSmiley; +extern const MicroBitImage ImageSadly; +extern const MicroBitImage ImageHeart; +extern const MicroBitImage ImageArrowLeft; +extern const MicroBitImage ImageArrowRight; +extern const MicroBitImage ImageArrowLeftRight; +extern const MicroBitImage ImageFull; +extern const MicroBitImage ImageDot; +extern const MicroBitImage ImageSmallRect; +extern const MicroBitImage ImageLargeRect; +extern const MicroBitImage ImageDoubleRow; +extern const MicroBitImage ImageTick; +extern const MicroBitImage ImageRock; +extern const MicroBitImage ImageScissors; +extern const MicroBitImage ImageWell; +extern const MicroBitImage ImageFlash; +extern const MicroBitImage ImageWave; diff --git a/source/Instruction.cpp b/source/Instruction.cpp index f5b93ef..659fb7d 100644 --- a/source/Instruction.cpp +++ b/source/Instruction.cpp @@ -133,70 +133,30 @@ void instruction_bra(Slice &code, Interpreter &interpreter, RunState &state) void instruction_beq(Slice &code, Interpreter &interpreter, RunState &state) { - // #ifdef LOG - // switch(state.cs) { - // case COMPARED_EQ: uBit.serial.printf("CS=EQ\n\r"); break; - // case COMPARED_LT: uBit.serial.printf("CS=LT\n\r"); break; - // case COMPARED_GT: uBit.serial.printf("CS=GT\n\r"); break; - // } - // #endif - bra(code, interpreter, state, state.cs == COMPARED_EQ); } void instruction_bne(Slice &code, Interpreter &interpreter, RunState &state) { - // #ifdef LOG - // switch(state.cs) { - // case COMPARED_EQ: uBit.serial.printf("CS=EQ\n\r"); break; - // case COMPARED_LT: uBit.serial.printf("CS=LT\n\r"); break; - // case COMPARED_GT: uBit.serial.printf("CS=GT\n\r"); break; - // } - // #endif - bra(code, interpreter, state, state.cs != COMPARED_EQ); } void instruction_bgt(Slice &code, Interpreter &interpreter, RunState &state) { - // #ifdef LOG - // switch(state.cs) { - // case COMPARED_EQ: uBit.serial.printf("CS=EQ\n\r"); break; - // case COMPARED_LT: uBit.serial.printf("CS=LT\n\r"); break; - // case COMPARED_GT: uBit.serial.printf("CS=GT\n\r"); break; - // } - // #endif - bra(code, interpreter, state, state.cs == COMPARED_GT); } void instruction_blt(Slice &code, Interpreter &interpreter, RunState &state) { - // #ifdef LOG - // switch(state.cs) { - // case COMPARED_EQ: uBit.serial.printf("CS=EQ\n\r"); break; - // case COMPARED_LT: uBit.serial.printf("CS=LT\n\r"); break; - // case COMPARED_GT: uBit.serial.printf("CS=GT\n\r"); break; - // } - // #endif - bra(code, interpreter, state, state.cs == COMPARED_LT); } void instruction_bge(Slice &code, Interpreter &interpreter, RunState &state) { - // #ifdef LOG - // switch(state.cs) { - // case COMPARED_EQ: uBit.serial.printf("CS=EQ\n\r"); break; - // case COMPARED_LT: uBit.serial.printf("CS=LT\n\r"); break; - // case COMPARED_GT: uBit.serial.printf("CS=GT\n\r"); break; - // } - // #endif - bra(code, interpreter, state, state.cs == COMPARED_GT || state.cs == COMPARED_EQ); @@ -204,14 +164,6 @@ void instruction_bge(Slice &code, Interpreter &interpreter, RunState &state) void instruction_ble(Slice &code, Interpreter &interpreter, RunState &state) { - // #ifdef LOG - // switch(state.cs) { - // case COMPARED_EQ: uBit.serial.printf("CS=EQ\n\r"); break; - // case COMPARED_LT: uBit.serial.printf("CS=LT\n\r"); break; - // case COMPARED_GT: uBit.serial.printf("CS=GT\n\r"); break; - // } - // #endif - bra(code, interpreter, state, state.cs == COMPARED_LT || state.cs == COMPARED_EQ); @@ -247,8 +199,6 @@ void instruction_cmp(Slice &code, Interpreter &interpreter, RunState &state) return; } - // uBit.serial.printf("cmp 0x%x vs 0x%x\n\r", *ra.value, *rb.value); - compare(*ra.value, *rb.value, state); state.pc = code.position; @@ -611,12 +561,12 @@ void instruction_display_show_image(Slice &code, Interpreter &interpreter, RunSt } const uint16_t i = *image.value; - if (i >= sizeof(images)) { + if (i >= (sizeof(images)/sizeof(images[0]))) { interpreter.status = INTERPRETER_KO_INSTRUCTION_INVALID; return; } - uBit.display.print(images[i]); + uBit.display.print(*images[i]); state.pc = code.position; } @@ -679,6 +629,7 @@ void instruction_display_show_text(Slice &code, Interpreter &interpreter, RunSta void instruction_rgb_off(Slice &code, Interpreter &interpreter UNUSED, RunState &state) { + // if the rg.off is called to frequently it begins to flicker if (uBit.rgb.isOn()) { uBit.rgb.off(); } diff --git a/source/Interpreter.cpp b/source/Interpreter.cpp index ada8816..eb37a3c 100644 --- a/source/Interpreter.cpp +++ b/source/Interpreter.cpp @@ -21,11 +21,14 @@ static uint16_t find_stop(InterpreterMethod method) return CODE_LEN; } -#ifdef LOG +//extern void microbit_heap_print(); +#ifdef DEBUG static uint8_t running = 0; #endif -static void interpreter_run(InterpreterMethod method, uint16_t r0 = 0, uint16_t r1 = 0, uint16_t r2 = 0) +static void interpreter_run_method(InterpreterMethod method, uint16_t r0 = 0, uint16_t r1 = 0, uint16_t r2 = 0) { + //microbit_heap_print(); + uint16_t start = interpreter.methods[method]; if (start == METHOD_UNUSED) { @@ -34,7 +37,7 @@ static void interpreter_run(InterpreterMethod method, uint16_t r0 = 0, uint16_t uint16_t stop = find_stop(method); - #ifdef LOG + #ifdef DEBUG running += 1; uint8_t id = running; #endif @@ -51,17 +54,13 @@ static void interpreter_run(InterpreterMethod method, uint16_t r0 = 0, uint16_t Slice code = slice_create(interpreter.code, start, stop); - #ifdef LOG - uBit.serial.printf("%d: run 0x%x-0x%x start\n\r", id, start, stop); - #endif + // LOG("%d: run 0x%x-0x%x start\n\r", id, start, stop); while(interpreter.status == INTERPRETER_OK) { uint8_t instruction = slice_read8(code); - // #ifdef LOG - // uBit.serial.printf("%d: @0x%x ins 0x%x\n\r", id, code.position-1, instruction); - // #endif + // LOG("%d: @0x%x ins 0x%x\n\r", id, code.position-1, instruction); switch(instruction) { case INS_RET: @@ -226,25 +225,39 @@ static void interpreter_run(InterpreterMethod method, uint16_t r0 = 0, uint16_t code.position = state.pc; if (slice_available(code) < 1) { - #ifdef LOG - uBit.serial.printf("%d: run 0x%x-0x%x stop\n\r", id, start, stop); - #endif + LOG("%d: run 0x%x-0x%x stop\n\r", id, start, stop); return; } } } +static void interpreter_reset_hardware() +{ + uBit.rgb.off(); + uBit.display.clear(); + uBit.soundmotor.soundOff(); +} + +static void interpreter_startup_sound() +{ + uBit.soundmotor.soundOn(262); + uBit.sleep(125); + uBit.soundmotor.soundOff(); + + uBit.sleep(63); + + uBit.soundmotor.soundOn(784); + uBit.sleep(500); + uBit.soundmotor.soundOff(); +} + static void interpreter_on_button(MicroBitEvent event) { - #ifdef LOG - uBit.serial.printf("button 0x%x 0x%x start\n\r", event.source, event.value); - #endif + LOG("button 0x%x 0x%x start\n\r", event.source, event.value); - interpreter_run(METHOD_ON_BUTTON, event.source, event.value); + interpreter_run_method(METHOD_ON_BUTTON, event.source, event.value); - #ifdef LOG - uBit.serial.printf("button 0x%x 0x%x stop\n\r", event.source, event.value); - #endif + LOG("button 0x%x 0x%x stop\n\r", event.source, event.value); } static void interpreter_on_pin(MicroBitEvent event) @@ -258,74 +271,72 @@ static void interpreter_on_pin(MicroBitEvent event) default: return; } - #ifdef LOG - uBit.serial.printf("pin 0x%x 0x%x start\n\r", source, event.value); - #endif + LOG("pin 0x%x 0x%x start\n\r", source, event.value); - interpreter_run(METHOD_ON_PIN, source, event.value); + interpreter_run_method(METHOD_ON_PIN, source, event.value); - #ifdef LOG - uBit.serial.printf("pin 0x%x 0x%x stop\n\r", source, event.value); - #endif + LOG("pin 0x%x 0x%x stop\n\r", source, event.value); } static void interpreter_on_gesture(MicroBitEvent event) { - #ifdef LOG - uBit.serial.printf("gesture 0x%x 0x%x start\n\r", event.source, event.value); - #endif + LOG("gesture 0x%x 0x%x start\n\r", event.source, event.value); - interpreter_run(METHOD_ON_GESTURE, event.source, event.value); + interpreter_run_method(METHOD_ON_GESTURE, event.source, event.value); - #ifdef LOG - uBit.serial.printf("gesture 0x%x 0x%x stop\n\r", event.source, event.value); - #endif + LOG("gesture 0x%x 0x%x stop\n\r", event.source, event.value); } -static void interpreter_startup_sound() -{ - uBit.soundmotor.soundOn(262); - uBit.sleep(125); - uBit.soundmotor.soundOff(); - - uBit.sleep(63); - - uBit.soundmotor.soundOn(784); - uBit.sleep(500); - uBit.soundmotor.soundOff(); -} - -static void interpreter_reset_hardware() -{ - uBit.rgb.off(); - uBit.display.clear(); - uBit.soundmotor.soundOff(); -} +// static void interpreter_event(MicroBitEvent event) +// { +// if (event.source == MICROBIT_ID_GESTURE && event.value == MICROBIT_ACCELEROMETER_EVT_SHAKE) { +// interpreter_on_gesture(event); +// } else + +// if (event.source == MICROBIT_ID_BUTTON_A && event.value == MICROBIT_BUTTON_EVT_CLICK) { +// interpreter_on_button(event); +// } else +// if (event.source == MICROBIT_ID_BUTTON_B && event.value == MICROBIT_BUTTON_EVT_CLICK) { +// interpreter_on_button(event); +// } else +// if (event.source == MICROBIT_ID_BUTTON_AB && event.value == MICROBIT_BUTTON_EVT_CLICK) { +// interpreter_on_button(event); +// } else + +// if (event.source == MICROBIT_ID_IO_P12 && event.value == MICROBIT_PIN_EVENT_ON_TOUCH) { // P0 +// interpreter_on_pin(event); +// } else +// if (event.source == MICROBIT_ID_IO_P0 && event.value == MICROBIT_PIN_EVENT_ON_TOUCH) { // P1 +// interpreter_on_pin(event); +// } else +// if (event.source == MICROBIT_ID_IO_P1 && event.value == MICROBIT_PIN_EVENT_ON_TOUCH) { // P2 +// interpreter_on_pin(event); +// } else +// if (event.source == MICROBIT_ID_IO_P16 && event.value == MICROBIT_PIN_EVENT_ON_TOUCH) { // P3 +// interpreter_on_pin(event); +// } +// } static void interpreter_fiber() { + LOG("interpreter\n\r"); + while(true) { interpreter_startup_sound(); interpreter_reset_hardware(); - #ifdef LOG - uBit.serial.send("start\n\r"); - #endif + LOG("start\n\r"); - interpreter_run(METHOD_STARTUP); + interpreter_run_method(METHOD_STARTUP); - #ifdef LOG - uBit.serial.send("forever\n\r"); - #endif + LOG("forever\n\r"); while(interpreter.status == INTERPRETER_OK) { - interpreter_run(METHOD_FOREVER); + interpreter_run_method(METHOD_FOREVER); uBit.sleep(10); } - #ifdef LOG - uBit.serial.send("rx\n\r"); - #endif + LOG("rx\n\r"); while(interpreter.status != INTERPRETER_RD) { uBit.sleep(10); @@ -333,9 +344,7 @@ static void interpreter_fiber() interpreter.status = INTERPRETER_OK; - #ifdef LOG - uBit.serial.send("reset\n\r"); - #endif + LOG("reset\n\r"); } } @@ -344,174 +353,68 @@ void interpreter_reset() memset(interpreter.code, 0, CODE_LEN * sizeof(interpreter.code[0])); memset(interpreter.methods, METHOD_UNUSED, METHODS_COUNT * sizeof(interpreter.methods[0])); interpreter.status = INTERPRETER_OK; - -/* - const uint8_t program[] = { -0x23, -0x01, -0x00, -0x01, -0x23, -0x00, -0x03, -0x00, -0x71, -0x00, -0x40, -0x01, -0x23, -0x00, -0x02, -0x00, -0x71, -0x00, -0x40, -0x01, -0x23, -0x00, -0x01, -0x00, -0x71, -0x00, -0x40, -0x01, -0x74, -0x00, -0x04, -0x48, -0x69, -0x21, -0x00, -0x23, -0x10, -0x00, -0x00, -0x81, -0xff, -0x00, -0x00, -0x00, -0x40, -0x00, -0x80, -0x40, -0x00, -0x00, -0x23, -0x03, -0x00, -0x00, -0x23, -0x03, -0x00, -0x01, -0x91, -0x01, -0x40, -0x00, -0x90, -0x40, -0x00 - }; - memcpy(&interpreter.code[0], program, sizeof(program)); - - const uint16_t methods[] = { -0x0000, -0x0023, -0x0032, -0xffff, -0xffff - }; - memcpy(&interpreter.methods[0], methods, sizeof(methods)); -*/ - - // // test program - // const uint8_t program[] = { - // 0x21, 0x00, 0x01, 0x00, - // 0x02, - // 0x23, 0x00, 0x00, 0x00, - // 0x72, 0x00, - // 0x23, 0x00, 0x10, 0x00, - // 0x40, 0x00, - // 0x70, - // }; - // memcpy(&interpreter.code[0], program, sizeof(program)); - - // const uint16_t methods[] = { - // 0xffff, - // 0xffff, - // 0x0000, - // 0xffff, - // 0xffff, - // }; - // memcpy(&interpreter.methods[0], methods, sizeof(methods)); - } -void interpreter_start() + +static void interpreter_init() { - // uBit.messageBus.listen(MICROBIT_ID_ANY, MICROBIT_EVT_ANY, onEvent); + uBit.io.P12.isTouched(); + uBit.io.P0.isTouched(); + uBit.io.P1.isTouched(); + uBit.io.P16.isTouched(); - uBit.messageBus.listen(MICROBIT_ID_BUTTON_A, + // uBit.messageBus.listen( + // MICROBIT_ID_ANY, + // MICROBIT_EVT_ANY, + // interpreter_event); + + + uBit.messageBus.listen( + MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK, interpreter_on_button); - uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, + uBit.messageBus.listen( + MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, interpreter_on_button); - uBit.messageBus.listen(MICROBIT_ID_BUTTON_AB, + uBit.messageBus.listen( + MICROBIT_ID_BUTTON_AB, MICROBIT_BUTTON_EVT_CLICK, interpreter_on_button); - // MESSAGE_BUS_LISTENER_DROP_IF_BUSY); - - // MICROBIT_ACCELEROMETER_EVT_TILT_UP - // MICROBIT_ACCELEROMETER_EVT_TILT_DOWN - // MICROBIT_ACCELEROMETER_EVT_TILT_LEFT - // MICROBIT_ACCELEROMETER_EVT_TILT_RIGHT - // MICROBIT_ACCELEROMETER_EVT_FACE_UP - // MICROBIT_ACCELEROMETER_EVT_FACE_DOWN - // MICROBIT_ACCELEROMETER_EVT_FREEFALL - // MICROBIT_ACCELEROMETER_EVT_3G - // MICROBIT_ACCELEROMETER_EVT_6G - // MICROBIT_ACCELEROMETER_EVT_8G - // MICROBIT_ACCELEROMETER_EVT_SHAKE - - uBit.messageBus.listen(MICROBIT_ID_GESTURE, - MICROBIT_ACCELEROMETER_EVT_SHAKE, - interpreter_on_gesture); - - uBit.io.P12.isTouched(); - uBit.io.P0.isTouched(); - uBit.io.P1.isTouched(); - uBit.io.P16.isTouched(); - // uBit.messageBus.listen(MICROBIT_ID_IO_P12, MICROBIT_EVT_ANY, onButton0); - // uBit.messageBus.listen(MICROBIT_ID_IO_P0, MICROBIT_EVT_ANY, onButton1); - // uBit.messageBus.listen(MICROBIT_ID_IO_P1, MICROBIT_EVT_ANY, onButton2); - // uBit.messageBus.listen(MICROBIT_ID_IO_P16, MICROBIT_EVT_ANY, onButton3); // Pin 0 - uBit.messageBus.listen(MICROBIT_ID_IO_P12, + uBit.messageBus.listen( + MICROBIT_ID_IO_P12, MICROBIT_EVT_ANY, interpreter_on_pin); // Pin 1 - uBit.messageBus.listen(MICROBIT_ID_IO_P0, + uBit.messageBus.listen( + MICROBIT_ID_IO_P0, MICROBIT_EVT_ANY, interpreter_on_pin); // Pin 2 - uBit.messageBus.listen(MICROBIT_ID_IO_P1, + uBit.messageBus.listen( + MICROBIT_ID_IO_P1, MICROBIT_EVT_ANY, interpreter_on_pin); // Pin 3 - uBit.messageBus.listen(MICROBIT_ID_IO_P16, + uBit.messageBus.listen( + MICROBIT_ID_IO_P16, MICROBIT_EVT_ANY, interpreter_on_pin); + uBit.messageBus.listen( + MICROBIT_ID_GESTURE, + MICROBIT_ACCELEROMETER_EVT_SHAKE, + interpreter_on_gesture); + interpreter_reset(); // new BluetoothServiceDebug(interpreter); @@ -519,7 +422,17 @@ void interpreter_start() notify = new BluetoothServiceNotify(interpreter); uBit.sleep(100); +} +void interpreter_run() +{ + interpreter_init(); + interpreter_fiber(); +} + +void interpreter_start() +{ + interpreter_init(); invoke(interpreter_fiber); } diff --git a/source/Interpreter.h b/source/Interpreter.h index 1d59957..8e595f3 100644 --- a/source/Interpreter.h +++ b/source/Interpreter.h @@ -11,7 +11,13 @@ #define REGISTER_COUNT 5 #define CHARACTERISTICS_BUFFER_LEN 40 -//#define LOG +//#define DEBUG + +#ifdef DEBUG +#define LOG(format, ...) uBit.serial.printf(format, ##__VA_ARGS__) +#else +#define LOG(format, ...) ; +#endif typedef enum { INTERPRETER_OK = 0x00, @@ -124,7 +130,7 @@ typedef enum { } InterpreterInstruction; - +void interpreter_run(); void interpreter_start(); void interpreter_reset(); uint16_t interpreter_calculate_hash(); diff --git a/source/Localization.h b/source/Localization.h new file mode 100644 index 0000000..91b0fdd --- /dev/null +++ b/source/Localization.h @@ -0,0 +1,8 @@ +#pragma once + +#define LS_DEMO_HELLO "Hallo!" +#define LS_DEMO_BUTTON_A "A" +#define LS_DEMO_BUTTON_B "B" +#define LS_DEMO_BUTTON_AB "A+B" +#define LS_DEMO_SHAKE "SCHUETTELN" +#define LS_DEMO_GREAT "SUPER!" diff --git a/source/Main.cpp b/source/Main.cpp new file mode 100644 index 0000000..cc7171c --- /dev/null +++ b/source/Main.cpp @@ -0,0 +1,103 @@ +#include "Menu.h" +#include "MicroBit.h" +#include "Images.h" +#include "Storage.h" +#include "RunTests.h" +#include "RunDemo.h" +#include "RunOracle.h" +#include "RunRockPaperScissors.h" +#include "RunLoveMeter.h" +#include "RunSnake.h" +#include "Interpreter.h" + +MicroBit uBit; + +static inline void waitForever() +{ + while (true) { + uBit.sleep(1000); + } +} + +static void menuAnimateEnter() { + uBit.display.print(ImageDot); + uBit.sleep(200); + uBit.display.print(ImageSmallRect); + uBit.sleep(200); + uBit.display.print(ImageLargeRect); + uBit.sleep(200); + uBit.display.clear(); +} + +static void menuAnimateLeave() { + uBit.display.print(ImageLargeRect); + uBit.sleep(200); + uBit.display.print(ImageSmallRect); + uBit.sleep(200); + uBit.display.print(ImageDot); + uBit.sleep(200); + uBit.display.clear(); +} + +int main() +{ + uBit.init(); + + uBit.serial.send("Calliope Demo v1.1\r\n"); + + // mimimize serial buffer + uBit.serial.setTxBufferSize(0); + + uBit.accelerometer.updateSample(); + + if (!hasStorageKey(KEY_TEST)) { + setStorageKey(KEY_TEST); + tests_run(); + // not required - just to make it obvious this does not return + waitForever(); + } + + if (!hasStorageKey(KEY_DEMO)) { + setStorageKey(KEY_DEMO); + demo_run(); + } + + // start state + menustate_t state = MenuStateOracle; + + while (true) { + state = menuWaitForChoice(state); + switch (state) { + // 1 + case MenuStateOracle: + menuAnimateEnter(); + oracle_run(); + menuAnimateLeave(); + break; + // 2 + case MenuStateRockPaperScissors: + menuAnimateEnter(); + rockpaperscissors_run(); + menuAnimateLeave(); + break; + // 3 + case MenuStateLoveMeter: + menuAnimateEnter(); + lovemeter_run(); + menuAnimateLeave(); + break; + // 4 + case MenuStateSnake: + menuAnimateEnter(); + snake_run(); + menuAnimateLeave(); + break; + // 5 + case MenuStateInterpreter: + interpreter_run(); + // not required - just to make it obvious this does not return + waitForever(); + break; + } + } +} \ No newline at end of file diff --git a/source/Menu.cpp b/source/Menu.cpp new file mode 100644 index 0000000..d9b2686 --- /dev/null +++ b/source/Menu.cpp @@ -0,0 +1,66 @@ +#include "Menu.h" +#include "MicroBit.h" + +extern MicroBit uBit; + +menustate_t menuWaitForChoice(menustate_t start) +{ + menustate_t state = start; + while (true) { + if (state == MenuStateInterpreter) { + + static const uint8_t pixels[25] = { + 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, + 0, 0, 1, 0, 1, + 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0 + }; + const MicroBitImage Image(5, 5, pixels); + + uBit.display.print(Image); + + } else { + + uBit.display.print(ManagedString(state)); + + } + + // event loop + while (true) { + // button A + if (uBit.buttonA.isPressed()) { + while (uBit.buttonA.isPressed()) { + uBit.sleep(10); + } + + if (state > MenuStateMin) { + state = menustate_t(state - 1); + break; + } + } + + // button B + if (uBit.buttonB.isPressed()) { + while (uBit.buttonB.isPressed()) { + uBit.sleep(10); + } + + if (state < MenuStateMax) { + state = menustate_t(state + 1); + break; + } + } + + // gesture + if (uBit.accelerometer.getGesture() == MICROBIT_ACCELEROMETER_EVT_SHAKE) { + while (uBit.accelerometer.getGesture() == MICROBIT_ACCELEROMETER_EVT_SHAKE) { + uBit.sleep(10); + } + return state; + } + + uBit.sleep(10); + } + } +} \ No newline at end of file diff --git a/source/Menu.h b/source/Menu.h new file mode 100644 index 0000000..8ff76ca --- /dev/null +++ b/source/Menu.h @@ -0,0 +1,13 @@ +#pragma once + +typedef enum MenuState { + MenuStateOracle = 1, + MenuStateRockPaperScissors, + MenuStateLoveMeter, + MenuStateSnake, + MenuStateInterpreter, + MenuStateMin = MenuStateOracle, + MenuStateMax = MenuStateInterpreter +} menustate_t; + +menustate_t menuWaitForChoice(menustate_t start); diff --git a/source/RunDemo.cpp b/source/RunDemo.cpp new file mode 100644 index 0000000..d84356a --- /dev/null +++ b/source/RunDemo.cpp @@ -0,0 +1,123 @@ +#include "RunDemo.h" +#include "Images.h" +#include "MicroBit.h" +#include "Utils.h" +#include "Localization.h" + +extern MicroBit uBit; + +static void beep() +{ + uBit.soundmotor.soundOn(784); + uBit.sleep(125); + uBit.soundmotor.soundOff(); +} + +static void startSound() +{ + uBit.soundmotor.soundOn(262); + uBit.sleep(125); + uBit.soundmotor.soundOff(); + uBit.sleep(63); + uBit.soundmotor.soundOn(784); + uBit.sleep(500); + uBit.soundmotor.soundOff(); +} + +void demo_run() +{ + const uint16_t pause = 300; + + uBit.sleep(200); + + invoke(startSound); + + uBit.display.scroll(LS_DEMO_HELLO); + + // press A + uBit.display.print(LS_DEMO_BUTTON_A); + uBit.sleep(pause); + blinkImageUntilEvent( + MICROBIT_ID_BUTTON_A, + MICROBIT_BUTTON_EVT_CLICK, + ImageArrowLeft); + uBit.display.print(ImageTick); + uBit.sleep(pause); + uBit.display.clear(); + + // press B + uBit.display.print(LS_DEMO_BUTTON_B); + uBit.sleep(pause); + blinkImageUntilEvent( + MICROBIT_ID_BUTTON_B, + MICROBIT_BUTTON_EVT_CLICK, + ImageArrowRight); + uBit.display.print(ImageTick); + uBit.sleep(pause); + uBit.display.clear(); + + // press A+B + uBit.display.scroll(LS_DEMO_BUTTON_AB); + uBit.sleep(pause); + blinkImageUntilEvent( + MICROBIT_ID_BUTTON_AB, + MICROBIT_BUTTON_EVT_CLICK, + ImageArrowLeftRight); + beep(); + uBit.display.print(ImageTick); + uBit.sleep(pause); + uBit.display.clear(); + + // shake + uBit.display.scroll(LS_DEMO_SHAKE); + blinkImageUntilEvent( + MICROBIT_ID_GESTURE, + MICROBIT_ACCELEROMETER_EVT_SHAKE, + ImageDoubleRow, + -1, + 2, + 100); + uBit.display.print(ImageTick); + uBit.sleep(pause); + uBit.display.clear(); + + uBit.display.scroll(LS_DEMO_GREAT); + + uBit.messageBus.listen( + MICROBIT_ID_BUTTON_A, + MICROBIT_BUTTON_EVT_CLICK, + leaveHandler); + uBit.messageBus.listen( + MICROBIT_ID_BUTTON_B, + MICROBIT_BUTTON_EVT_CLICK, + leaveHandler); + + for (uint8_t i = 0; i < 5 && !leave; i++) { + + int r = uBit.random(pause); + if (r < 100) { + uBit.rgb.setColour(0xFF, 0xA5, 0x00, 0x00); + } else if (r < 200) { + uBit.rgb.setColour(0x00, 0xFF, 0x00, 0x00); + } else if (r < 300) { + uBit.rgb.setColour(0x00, 0xA5, 0xFF, 0x00); + } + + blinkImage(ImageHeart, 0, 200); + } + + uBit.messageBus.ignore( + MICROBIT_ID_BUTTON_A, + MICROBIT_BUTTON_EVT_CLICK, + leaveHandler); + uBit.messageBus.ignore( + MICROBIT_ID_BUTTON_B, + MICROBIT_BUTTON_EVT_CLICK, + leaveHandler); + + uBit.rgb.off(); + uBit.display.clear(); + + uBit.display.print(ImageSmiley); + uBit.sleep(1000); +} \ No newline at end of file diff --git a/source/RunDemo.h b/source/RunDemo.h new file mode 100644 index 0000000..7eca6d5 --- /dev/null +++ b/source/RunDemo.h @@ -0,0 +1,3 @@ +#pragma once + +void demo_run(); \ No newline at end of file diff --git a/source/RunLoveMeter.cpp b/source/RunLoveMeter.cpp new file mode 100644 index 0000000..a56cccf --- /dev/null +++ b/source/RunLoveMeter.cpp @@ -0,0 +1,92 @@ +#include "RunLoveMeter.h" +#include "MicroBit.h" +#include "Images.h" +#include "Utils.h" + +extern MicroBit uBit; + +static int touch_p1 = 0; +static int touch_p2 = 0; + +static void lovemeter_fiber() +{ + touch_p1 = uBit.io.P1.getAnalogValue(); + touch_p2 = uBit.io.P2.getAnalogValue(); + + while(!leave) { + uBit.sleep(300); + + int p1 = uBit.io.P1.getAnalogValue(); + int p2 = uBit.io.P2.getAnalogValue(); + + if (abs(touch_p1 - p1) > 20 && abs(touch_p2 - p2) > 20) { + event = true; + } + } +} + +void lovemeter_run() +{ + uBit.messageBus.listen( + MICROBIT_ID_BUTTON_AB, + MICROBIT_BUTTON_EVT_CLICK, + leaveHandler); + + uBit.io.P1.isTouched(); + uBit.io.P2.isTouched(); + + uBit.display.print(ImageHeart); + + invoke(lovemeter_fiber); + + leave = false; + while (!leave) { + + event = false; + for (uint8_t i = 0; !leave && !event; i++) { + blinkImage(ImageWave, (i % 2) == 0 ? -1 : -2, 200); + } + + if (leave) { + break; + } + + int p1 = uBit.io.P1.getAnalogValue(); + int p2 = uBit.io.P2.getAnalogValue(); + int v1 = (int)(p1 * 9.0 / 1023.0); + int v2 = (int)(p2 * 9.0 / 1023.0); + int v3 = 9 - abs(v1 - v2); + uBit.display.print(v3); + + uBit.sleep(1000); + + if (v3 > 6) { + uBit.display.print(ImageHeart); + uBit.soundmotor.soundOn(1000); + uBit.sleep(100); + uBit.soundmotor.soundOn(2000); + uBit.sleep(100); + uBit.soundmotor.soundOn(3000); + uBit.sleep(300); + uBit.soundmotor.soundOff(); + uBit.sleep(4000); + } else { + uBit.display.print(ImageFlash); + uBit.soundmotor.soundOn(1000); + uBit.sleep(100); + uBit.soundmotor.soundOn(500); + uBit.sleep(100); + uBit.soundmotor.soundOn(100); + uBit.sleep(300); + uBit.soundmotor.soundOff(); + uBit.sleep(4000); + } + + uBit.display.clear(); + } + + uBit.messageBus.ignore( + MICROBIT_ID_BUTTON_AB, + MICROBIT_BUTTON_EVT_CLICK, + leaveHandler); +} \ No newline at end of file diff --git a/source/RunLoveMeter.h b/source/RunLoveMeter.h new file mode 100644 index 0000000..1e177b4 --- /dev/null +++ b/source/RunLoveMeter.h @@ -0,0 +1,3 @@ +#pragma once + +void lovemeter_run(); \ No newline at end of file diff --git a/source/RunOracle.cpp b/source/RunOracle.cpp new file mode 100644 index 0000000..bf7ecee --- /dev/null +++ b/source/RunOracle.cpp @@ -0,0 +1,74 @@ +#include "RunOracle.h" +#include "MicroBit.h" +#include "Images.h" +#include "Utils.h" + +extern MicroBit uBit; + +void oracle_run() +{ + uBit.messageBus.listen( + MICROBIT_ID_BUTTON_AB, + MICROBIT_BUTTON_EVT_CLICK, + leaveHandler); + uBit.messageBus.listen( + MICROBIT_ID_BUTTON_A, + MICROBIT_BUTTON_EVT_CLICK, + eventHandler); + + leave = false; + while(!leave) { + + event = false; + + leave = false; + while(!leave) { + + uBit.display.print(ImageArrowLeft); + + for(int t=0, i=10; t<400 && !leave && !event; t+=i) { + uBit.sleep(i); + } + + if (leave || event) { + break; + } + + uBit.sleep(10); + uBit.display.clear(); + + for(int t=0, i=10; t<400 && !leave && !event; t+=i) { + uBit.sleep(i); + } + } + + if (leave) { + break; + } + + for (int i = 0; i < 5; i++) { + uBit.display.print(ImageDot); + uBit.sleep(200); + uBit.display.clear(); + uBit.sleep(50); + } + + int r = uBit.random(100); + uBit.display.print((r < 50) + ? ImageSmiley + : ImageSadly + ); + + uBit.sleep(3000); + uBit.display.clear(); + } + + uBit.messageBus.ignore( + MICROBIT_ID_BUTTON_AB, + MICROBIT_BUTTON_EVT_CLICK, + leaveHandler); + uBit.messageBus.ignore( + MICROBIT_ID_BUTTON_A, + MICROBIT_BUTTON_EVT_CLICK, + eventHandler); +} \ No newline at end of file diff --git a/source/RunOracle.h b/source/RunOracle.h new file mode 100644 index 0000000..0648841 --- /dev/null +++ b/source/RunOracle.h @@ -0,0 +1,3 @@ +#pragma once + +void oracle_run(); \ No newline at end of file diff --git a/source/RunRockPaperScissors.cpp b/source/RunRockPaperScissors.cpp new file mode 100644 index 0000000..080eb05 --- /dev/null +++ b/source/RunRockPaperScissors.cpp @@ -0,0 +1,58 @@ +#include "RunRockPaperScissors.h" +#include "Images.h" +#include "MicroBit.h" +#include "Utils.h" + +extern MicroBit uBit; + +void rockpaperscissors_run() +{ + const uint16_t pause = 200; + + uBit.messageBus.listen( + MICROBIT_ID_BUTTON_AB, + MICROBIT_BUTTON_EVT_CLICK, + leaveHandler); + + uBit.display.print(ImageRock, 0, 0, 0, pause * 2); + uBit.display.print(ImageFull, 0, 0, 0, pause * 2); + uBit.display.print(ImageScissors, 0, 0, 0, pause * 2); + uBit.display.print(ImageWell, 0, 0, 0, pause * 2); + uBit.display.clear(); + uBit.sleep(pause); + + leave = false; + while (!leave) { + + blinkImageUntilEvent( + MICROBIT_ID_GESTURE, + MICROBIT_ACCELEROMETER_EVT_SHAKE, + ImageDoubleRow, + -1, + 2, + 100); + + if (leave) { + break; + } + + int r = uBit.random(400); + if (r < 100) { + uBit.display.print(ImageRock); + } else if (r < 200) { + uBit.display.print(ImageFull); + } else if (r < 300) { + uBit.display.print(ImageScissors); + } else { + uBit.display.print(ImageWell); + } + + uBit.sleep(3000); + uBit.display.clear(); + } + + uBit.messageBus.ignore( + MICROBIT_ID_BUTTON_AB, + MICROBIT_BUTTON_EVT_CLICK, + leaveHandler); +} \ No newline at end of file diff --git a/source/RunRockPaperScissors.h b/source/RunRockPaperScissors.h new file mode 100644 index 0000000..36a7fed --- /dev/null +++ b/source/RunRockPaperScissors.h @@ -0,0 +1,3 @@ +#pragma once + +void rockpaperscissors_run(); diff --git a/source/Snake.cpp b/source/RunSnake.cpp similarity index 56% rename from source/Snake.cpp rename to source/RunSnake.cpp index 0e332de..bf1568a 100644 --- a/source/Snake.cpp +++ b/source/RunSnake.cpp @@ -1,56 +1,31 @@ -/* -The MIT License (MIT) - -Adapted for Calliope by Matthias L. Jugel -Copyright (c) 2016 British Broadcasting Corporation. -This software is provided by Lancaster University by arrangement with the BBC. - -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 "RunSnake.h" #include "MicroBit.h" -#include "CalliopeDemo.h" +#include "Images.h" +#include "Utils.h" + +extern MicroBit uBit; #define SNAKE_EMPTY 0 -#define SNAKE_UP 1 -#define SNAKE_LEFT 2 +#define SNAKE_UP 1 +#define SNAKE_LEFT 2 #define SNAKE_RIGHT 3 -#define SNAKE_DOWN 4 +#define SNAKE_DOWN 4 -#define SNAKE_FRAME_DELAY 85 -#define GROWTH_SPEED 3 - -extern MicroBit uBit; -extern state_t state; -extern bool eventOK; +#define SNAKE_FRAME_DELAY 85 +#define GROWTH_SPEED 3 struct Point { int x; int y; }; -static Point head; // Location of the head of our snake. -static Point tail; // Location of the tail of our snake. -static Point food; // Location of food. +static Point head; +static Point tail; +static Point food; static MicroBitImage map(5, 5); -void place_food() { +static void placeFood() +{ int r = uBit.random(24); int x = 0; int y = 0; @@ -68,38 +43,42 @@ void place_food() { food.y = y; } +static void eatFood() +{ + uBit.rgb.setColour(0xff, 0x00, 0x00, 0x00); + uBit.soundmotor.soundOn(392); + fiber_sleep(500); + uBit.soundmotor.soundOn(440); + fiber_sleep(125); + uBit.soundmotor.soundOff(); + uBit.rgb.off(); +} + static bool accel_disabled = false; static bool a_pressed = false; static bool b_pressed = false; -void buttonAPressed(MicroBitEvent event) { - (void)event; +static void buttonAPressed(MicroBitEvent) +{ accel_disabled = true; a_pressed = true; } -void buttonBPressed(MicroBitEvent event) { - (void)event; +static void buttonBPressed(MicroBitEvent) +{ accel_disabled = true; b_pressed = true; } -void eatFood() { - uBit.rgb.setColour(0xff, 0x00, 0x00, 0x00); - uBit.soundmotor.soundOn(392); - fiber_sleep(500); - uBit.soundmotor.soundOn(440); - fiber_sleep(125); - uBit.soundmotor.soundOff(); - uBit.rgb.off(); -} +void snake_run() +{ + uBit.display.clear(); -void snake() { - Point newHead; // Calculated placement of new head position based on user input. - int hdirection = SNAKE_UP; // Head's direction of travel - int tdirection; // Tail's direction of travel - int snakeLength; // number of segments in the snake. - int growing; // boolean state indicating if we've just eaten some food. + Point newHead; // Calculated placement of new head position based on user input. + int hdirection = SNAKE_UP; // Head's direction of travel + int tdirection; // Tail's direction of travel + int snakeLength; // number of segments in the snake. + int growing; // boolean state indicating if we've just eaten some food. int score; int steps = 0; @@ -111,19 +90,30 @@ void snake() { score = 0; map.clear(); - uBit.messageBus.listen(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK, buttonAPressed); - uBit.messageBus.listen(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, buttonBPressed); + uBit.messageBus.listen( + MICROBIT_ID_BUTTON_A, + MICROBIT_BUTTON_EVT_CLICK, + buttonAPressed); + uBit.messageBus.listen( + MICROBIT_ID_BUTTON_B, + MICROBIT_BUTTON_EVT_CLICK, + buttonBPressed); + uBit.messageBus.listen( + MICROBIT_ID_BUTTON_AB, + MICROBIT_BUTTON_EVT_CLICK, + leaveHandler); uBit.display.image.setPixelValue(head.x, head.y, 255); - // Add some random food. - place_food(); + // Add some random food. + placeFood(); - while (state == Snake) { - // Flash the food is necessary; + leave = false; + while (!leave) { + // Flash the food is necessary; uBit.display.image.setPixelValue(food.x, food.y, uBit.systemTime() % 500 < 250 ? 0 : 255); - if(steps++ % 4 == 0) { + if (steps++ % 4 == 0) { newHead.x = head.x; newHead.y = head.y; @@ -132,41 +122,40 @@ void snake() { // switch direction according to buttons if (a_pressed || b_pressed) { switch (hdirection) { - case SNAKE_LEFT: - hdirection = (a_pressed ? SNAKE_DOWN : (b_pressed ? SNAKE_UP : SNAKE_LEFT)); - break; - case SNAKE_RIGHT: - hdirection = (a_pressed ? SNAKE_UP : (b_pressed ? SNAKE_DOWN : SNAKE_RIGHT)); - break; - case SNAKE_UP: - hdirection = (a_pressed ? SNAKE_LEFT : (b_pressed ? SNAKE_RIGHT : SNAKE_UP)); - break; - case SNAKE_DOWN: - hdirection = (a_pressed ? SNAKE_RIGHT : (b_pressed ? SNAKE_LEFT : SNAKE_DOWN)); - break; - default: - break; - } - } - - // do the actual move - switch (hdirection) { case SNAKE_LEFT: - newHead.x = newHead.x == 0 ? 4 : newHead.x - 1; + hdirection = (a_pressed ? SNAKE_DOWN : (b_pressed ? SNAKE_UP : SNAKE_LEFT)); break; case SNAKE_RIGHT: - newHead.x = newHead.x == 4 ? 0 : newHead.x + 1; + hdirection = (a_pressed ? SNAKE_UP : (b_pressed ? SNAKE_DOWN : SNAKE_RIGHT)); break; case SNAKE_UP: - newHead.y = newHead.y == 0 ? 4 : newHead.y - 1; + hdirection = (a_pressed ? SNAKE_LEFT : (b_pressed ? SNAKE_RIGHT : SNAKE_UP)); break; case SNAKE_DOWN: - newHead.y = newHead.y == 4 ? 0 : newHead.y + 1; + hdirection = (a_pressed ? SNAKE_RIGHT : (b_pressed ? SNAKE_LEFT : SNAKE_DOWN)); break; default: break; + } } + // do the actual move + switch (hdirection) { + case SNAKE_LEFT: + newHead.x = newHead.x == 0 ? 4 : newHead.x - 1; + break; + case SNAKE_RIGHT: + newHead.x = newHead.x == 4 ? 0 : newHead.x + 1; + break; + case SNAKE_UP: + newHead.y = newHead.y == 0 ? 4 : newHead.y - 1; + break; + case SNAKE_DOWN: + newHead.y = newHead.y == 4 ? 0 : newHead.y + 1; + break; + default: + break; + } } else { int dx = uBit.accelerometer.getX(); @@ -196,9 +185,8 @@ void snake() { int status = map.getPixelValue(newHead.x, newHead.y); if (status == SNAKE_UP || status == SNAKE_DOWN || status == SNAKE_LEFT || status == SNAKE_RIGHT) { - uBit.display.scroll(DISPLAY_THEEND); + uBit.display.scroll("The End"); uBit.display.scroll(score); - return; } @@ -243,7 +231,7 @@ void snake() { invoke(eatFood); growing++; score++; - place_food(); + placeFood(); } } @@ -251,7 +239,17 @@ void snake() { } uBit.display.clear(); - uBit.messageBus.ignore(MICROBIT_ID_BUTTON_A, MICROBIT_BUTTON_EVT_CLICK, buttonAPressed); - uBit.messageBus.ignore(MICROBIT_ID_BUTTON_B, MICROBIT_BUTTON_EVT_CLICK, buttonBPressed); -} + uBit.messageBus.ignore( + MICROBIT_ID_BUTTON_A, + MICROBIT_BUTTON_EVT_CLICK, + buttonAPressed); + uBit.messageBus.ignore( + MICROBIT_ID_BUTTON_B, + MICROBIT_BUTTON_EVT_CLICK, + buttonBPressed); + uBit.messageBus.ignore( + MICROBIT_ID_BUTTON_AB, + MICROBIT_BUTTON_EVT_CLICK, + leaveHandler); +} \ No newline at end of file diff --git a/source/RunSnake.h b/source/RunSnake.h new file mode 100644 index 0000000..4670149 --- /dev/null +++ b/source/RunSnake.h @@ -0,0 +1,3 @@ +#pragma once + +void snake_run(); \ No newline at end of file diff --git a/source/CalliopeTestBoard.cpp b/source/RunTests.cpp similarity index 75% rename from source/CalliopeTestBoard.cpp rename to source/RunTests.cpp index 91c88d1..028457a 100644 --- a/source/CalliopeTestBoard.cpp +++ b/source/RunTests.cpp @@ -1,91 +1,92 @@ -#include -#include "CalliopeDemo.h" +#include "RunTests.h" +#include "MicroBit.h" +#include "MicroBitSerial.h" +#include "Images.h" +#include "Utils.h" extern MicroBit uBit; -void onButtonA(MicroBitEvent event) { - (void) event; +void onButtonA(MicroBitEvent) +{ uBit.display.print("A"); uBit.rgb.off(); uBit.rgb.setColour(0, 0, 255, 0); } -void onButtonB(MicroBitEvent event) { - (void) event; +void onButtonB(MicroBitEvent) +{ uBit.display.print("B"); uBit.rgb.off(); uBit.rgb.setColour(255, 0, 0, 0); - } -void onButtonAB(MicroBitEvent event) { - (void) event; +void onButtonAB(MicroBitEvent) +{ uBit.display.print("#"); uBit.rgb.off(); uBit.rgb.setColour(0, 255, 0, 0); } -void onButton0(MicroBitEvent event) { - (void) event; +void onButton0(MicroBitEvent) +{ uBit.display.print("0"); } -void onButton1(MicroBitEvent event) { - (void) event; +void onButton1(MicroBitEvent) +{ uBit.display.print("1"); } -void onButton2(MicroBitEvent event) { - (void) event; +void onButton2(MicroBitEvent) +{ uBit.display.print("2"); } -void onButton3(MicroBitEvent event) { - (void) event; +void onButton3(MicroBitEvent) +{ uBit.display.print("3"); } -void onShake(MicroBitEvent event) { - (void) event; +void onShake(MicroBitEvent) +{ uBit.display.print("S"); } -void onFaceUp(MicroBitEvent event) { - (void) event; +void onFaceUp(MicroBitEvent) +{ uBit.display.print("+"); } -void onFaceDown(MicroBitEvent event) { - (void) event; +void onFaceDown(MicroBitEvent) +{ uBit.display.print("-"); } -void onTiltUp(MicroBitEvent event) { - (void) event; +void onTiltUp(MicroBitEvent) +{ uBit.display.print("U"); } -void onTiltDown(MicroBitEvent event) { - (void) event; +void onTiltDown(MicroBitEvent) +{ uBit.display.print("D"); } -void onTiltLeft(MicroBitEvent event) { - (void) event; +void onTiltLeft(MicroBitEvent) +{ uBit.display.print("L"); } -void onTiltRight(MicroBitEvent event) { - (void) event; +void onTiltRight(MicroBitEvent) +{ uBit.display.print("R"); } -void testBoard() { - KeyValuePair *firstTime = uBit.storage.get("initial"); +void tests_run() +{ + uBit.serial.setTxBufferSize(MICROBIT_SERIAL_DEFAULT_BUFFER_SIZE); - if (firstTime != NULL) return; - uint8_t done = 1; - uBit.storage.put("initial", &done, sizeof(int)); + uBit.sleep(200); uBit.serial.send("sound\r\n"); uBit.soundmotor.setSoundSilentMode(true); @@ -100,7 +101,7 @@ void testBoard() { uBit.serial.send("display\r\n"); uBit.display.clear(); - uBit.display.print(Full); + uBit.display.print(ImageFull); for (int i = 255; i > 0; i -= 2) { uBit.display.setBrightness(i); uBit.sleep(3); @@ -129,9 +130,8 @@ void testBoard() { uBit.accelerometer.getY(); uBit.accelerometer.getZ(); } - uBit.display.print(Tick); + uBit.display.print(ImageTick); - // we need to trigger touch sensing uBit.io.P12.isTouched(); uBit.io.P0.isTouched(); uBit.io.P1.isTouched(); @@ -153,7 +153,7 @@ void testBoard() { uBit.messageBus.listen(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_TILT_LEFT, onTiltLeft); uBit.messageBus.listen(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_TILT_RIGHT, onTiltRight); - while (1) { + while (true) { int mic = uBit.io.P21.getAnalogValue(); // ((value - fromLow) * (toHigh - toLow)) / (fromHigh - fromLow) + toLow if (mic > 512) { diff --git a/source/RunTests.h b/source/RunTests.h new file mode 100644 index 0000000..6467d02 --- /dev/null +++ b/source/RunTests.h @@ -0,0 +1,3 @@ +#pragma once + +void tests_run(); \ No newline at end of file diff --git a/source/Storage.h b/source/Storage.h new file mode 100644 index 0000000..0fe7cd3 --- /dev/null +++ b/source/Storage.h @@ -0,0 +1,27 @@ +#pragma once + +#define KEY_TEST "initial" +#define KEY_DEMO "demo" + +extern MicroBit uBit; + +inline bool hasStorageKey(const char* name) +{ + void* value = uBit.storage.get(name); + if (value != NULL) { + free(value); + return true; + } else { + return false; + } +} + +inline void setStorageKey(const char* name, bool state = true) +{ + if (state) { + uint8_t done = 1; + uBit.storage.put(name, &done, sizeof(uint8_t)); + } else { + uBit.storage.remove(name); + } +} \ No newline at end of file diff --git a/source/Utils.cpp b/source/Utils.cpp new file mode 100644 index 0000000..456312b --- /dev/null +++ b/source/Utils.cpp @@ -0,0 +1,67 @@ +#include "Utils.h" +#include "MicroBit.h" +#include "MicroBitImage.h" + +extern MicroBit uBit; + +bool event = false; +void eventHandler(MicroBitEvent) +{ + event = true; +} + +bool leave = false; +void leaveHandler(MicroBitEvent) +{ + leave = true; +} + +void blinkImage( + const MicroBitImage& image, + const int pos, + const uint16_t delay) +{ + + event = false; + + uBit.display.print(image, pos); + + for (int t = 0, i = 10; t < delay && !leave && !event; t += i) { + uBit.sleep(i); + } + + if (event) { + return; + } + + uBit.display.clear(); + + for (int t = 0, i = 10; t < delay && !leave && !event; t += i) { + uBit.sleep(i); + } +} + +void blinkImageUntilEvent( + const uint16_t source, + const uint16_t value, + const MicroBitImage& image, + const int pos1, + const int pos2, + const uint16_t delay) +{ + uBit.messageBus.listen( + source, + value, + eventHandler); + + event = false; + + for (uint8_t i = 0; !leave && !event; i++) { + blinkImage(image, (i % 2) == 0 ? pos1 : pos2, delay); + } + + uBit.messageBus.ignore( + source, + value, + eventHandler); +} \ No newline at end of file diff --git a/source/Utils.h b/source/Utils.h new file mode 100644 index 0000000..0d5085b --- /dev/null +++ b/source/Utils.h @@ -0,0 +1,23 @@ +#pragma once + +#include "MicroBit.h" + +extern bool event; +void leaveHandler(MicroBitEvent); + +extern bool leave; +void eventHandler(MicroBitEvent); + +void blinkImage( + const MicroBitImage& image, + const int pos = 0, + const uint16_t delay = 200); + +void blinkImageUntilEvent( + const uint16_t source, + const uint16_t value, + const MicroBitImage& image, + const int pos1 = 0, + const int pos2 = 0, + const uint16_t delay = 200); + From e134c06039f7190a6141c649a3545d47a46673ee Mon Sep 17 00:00:00 2001 From: Torsten Curdt Date: Thu, 22 Feb 2018 11:54:58 +0100 Subject: [PATCH 03/28] boot into interpreter --- source/Main.cpp | 22 ++++++++++++++++------ source/Storage.h | 15 ++++++++------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/source/Main.cpp b/source/Main.cpp index cc7171c..e219053 100644 --- a/source/Main.cpp +++ b/source/Main.cpp @@ -42,23 +42,34 @@ static void menuAnimateLeave() { int main() { uBit.init(); + uBit.accelerometer.updateSample(); uBit.serial.send("Calliope Demo v1.1\r\n"); - // mimimize serial buffer - uBit.serial.setTxBufferSize(0); + if (hasStorageKey(KEY_INTERPRETER)) { + removeStorageKey(KEY_INTERPRETER); - uBit.accelerometer.updateSample(); + // mimimize serial buffer + uBit.serial.setTxBufferSize(0); + + interpreter_run(); + + // not required - just to make it obvious this does not return + waitForever(); + } if (!hasStorageKey(KEY_TEST)) { setStorageKey(KEY_TEST); + tests_run(); + // not required - just to make it obvious this does not return waitForever(); } if (!hasStorageKey(KEY_DEMO)) { setStorageKey(KEY_DEMO); + demo_run(); } @@ -94,9 +105,8 @@ int main() break; // 5 case MenuStateInterpreter: - interpreter_run(); - // not required - just to make it obvious this does not return - waitForever(); + setStorageKey(KEY_INTERPRETER); + uBit.reset(); break; } } diff --git a/source/Storage.h b/source/Storage.h index 0fe7cd3..2b634a9 100644 --- a/source/Storage.h +++ b/source/Storage.h @@ -2,6 +2,7 @@ #define KEY_TEST "initial" #define KEY_DEMO "demo" +#define KEY_INTERPRETER "interpreter" extern MicroBit uBit; @@ -16,12 +17,12 @@ inline bool hasStorageKey(const char* name) } } -inline void setStorageKey(const char* name, bool state = true) +inline void setStorageKey(const char* name, uint8_t value = 1) { - if (state) { - uint8_t done = 1; - uBit.storage.put(name, &done, sizeof(uint8_t)); - } else { - uBit.storage.remove(name); - } + uBit.storage.put(name, &value, sizeof(uint8_t)); +} + +inline void removeStorageKey(const char* name) +{ + uBit.storage.remove(name); } \ No newline at end of file From f80f7dbb89e2699147e3c16b321730f7827fb34b Mon Sep 17 00:00:00 2001 From: Torsten Curdt Date: Sun, 25 Feb 2018 14:13:25 +0100 Subject: [PATCH 04/28] cleanup, internal upgrade to int32 --- config.json | 4 +- source/BluetoothServiceDebug.cpp | 80 +++++++++++++++--------------- source/BluetoothServiceDebug.h | 37 ++++++-------- source/BluetoothServiceNotify.cpp | 5 +- source/BluetoothServiceNotify.h | 6 +-- source/BluetoothServiceProgram.cpp | 7 +-- source/BluetoothServiceProgram.h | 6 +-- source/Bytes.h | 12 ++--- source/Images.cpp | 1 + source/Images.h | 1 - source/Instruction.cpp | 64 +++++++++++++----------- source/Instruction.h | 6 +-- source/Interpreter.cpp | 8 +-- source/Interpreter.h | 10 ++-- source/Main.cpp | 18 ++++--- source/Menu.cpp | 11 ++-- source/RunDemo.cpp | 2 +- source/RunOracle.cpp | 4 +- source/RunSnake.cpp | 2 +- source/RunTests.cpp | 14 ++++-- source/Slice.cpp | 2 +- source/Utils.cpp | 8 +-- 22 files changed, 147 insertions(+), 161 deletions(-) diff --git a/config.json b/config.json index 8856e57..128e15e 100644 --- a/config.json +++ b/config.json @@ -14,7 +14,7 @@ "security_level": "SECURITY_MODE_ENCRYPTION_NO_MITM" }, "gatt_table_size": "0x400", - "debug": 1, - "heap_debug": 1 + "debug": 0, + "heap_debug": 0 } } diff --git a/source/BluetoothServiceDebug.cpp b/source/BluetoothServiceDebug.cpp index e7b72c8..2fc3c2e 100644 --- a/source/BluetoothServiceDebug.cpp +++ b/source/BluetoothServiceDebug.cpp @@ -1,40 +1,40 @@ #include "BluetoothServiceDebug.h" #include "MicroBit.h" -#include "ble/UUID.h" +//#include "ble/UUID.h" #include "Bytes.h" extern MicroBit uBit; -static const uint8_t BluetoothServiceDebugUUID[] = { - 0xff,0x44,0xdd,0xee, - 0x25,0x1d, - 0x47,0x0a, - 0xa0,0x62, - 0xfa,0x19,0x22,0xdf,0xa9,0xa8 +static const uint8_t BluetoothServiceDebugUUID[] = { + 0xff, 0x44, 0xdd, 0xee, + 0x25, 0x1d, + 0x47, 0x0a, + 0xa0, 0x62, + 0xfa, 0x19, 0x22, 0xdf, 0xa9, 0xa8 }; - -BluetoothServiceDebug::BluetoothServiceDebug(Interpreter &_interpreter) : - interpreter(_interpreter), - ble(*uBit.ble), - characteristic( - BluetoothServiceDebugUUID, - (uint8_t *)&characteristicsBuffer, 0, sizeof(characteristicsBuffer), - GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | - GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ - ) +BluetoothServiceDebug::BluetoothServiceDebug(Interpreter& _interpreter) + : interpreter(_interpreter) + , ble(*uBit.ble) + , characteristic( + BluetoothServiceDebugUUID, + (uint8_t*)&characteristicsBuffer, 0, sizeof(characteristicsBuffer), + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ) + , characteristicsBuffer() + , selector() + , address() { characteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL); characteristic.setReadAuthorizationCallback(this, &BluetoothServiceDebug::onDataRead); - GattCharacteristic *characteristics[] = { + GattCharacteristic* characteristics[] = { &characteristic }; GattService service( BluetoothServiceDebugUUID, characteristics, - sizeof(characteristics) / sizeof(GattCharacteristic *)); + sizeof(characteristics) / sizeof(GattCharacteristic*)); ble.addService(service); @@ -43,11 +43,11 @@ BluetoothServiceDebug::BluetoothServiceDebug(Interpreter &_interpreter) : ble.onDataWritten(this, &BluetoothServiceDebug::onDataWritten); } -void BluetoothServiceDebug::onDataWritten(const GattWriteCallbackParams *params) +void BluetoothServiceDebug::onDataWritten(const GattWriteCallbackParams* params) { if (params->handle == characteristicsHandle) { - const uint8_t *data = params->data; - const uint8_t len = params->len; + const uint8_t* data = params->data; + const uint16_t len = params->len; // set selector, hi(address), lo(address) if (len == 3) { @@ -57,59 +57,59 @@ void BluetoothServiceDebug::onDataWritten(const GattWriteCallbackParams *params) } } -#define MIN(a, b) ((a)<(b)?(a):(b)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) -void BluetoothServiceDebug::onDataRead(GattReadAuthCallbackParams *params) +void BluetoothServiceDebug::onDataRead(GattReadAuthCallbackParams* params) { if (params->handle == characteristicsHandle) { // get code at address if (selector == 0x00) { - const uint8_t *buffer = (uint8_t*)&interpreter.code[0]; + const uint8_t* buffer = &interpreter.code[0]; - const uint16_t start = MIN(address, CODE_LEN); - const uint16_t stop = MIN(address+16, CODE_LEN); + const uint16_t start = static_cast MIN(address, CODE_LEN); + const uint16_t stop = static_cast MIN(address + 16, CODE_LEN); const uint16_t len = stop - start; - uint8_t data[1+2+16]; + uint8_t data[1 + 2 + 16]; data[0] = 0x00; data[1] = HI16(address); data[2] = LO16(address); if (len > 0) { - memcpy(&data[3], buffer+start, len); + memcpy(&data[3], buffer + start, len); } ble.gattServer().write( characteristicsHandle, - data, 3 + len); - + data, + static_cast(3 + len)); } else - // get methods at address - if (selector == 0x01) { + // get methods at address + if (selector == 0x01) { - const uint8_t *buffer = (uint8_t*)&interpreter.methods[0]; + const uint8_t* buffer = (uint8_t*)&interpreter.methods[0]; - const uint16_t start = MIN(address, METHODS_COUNT*2); - const uint16_t stop = MIN(address+2, METHODS_COUNT*2); + const uint16_t start = static_cast MIN(address, METHODS_COUNT * 2); + const uint16_t stop = static_cast MIN(address + 2, METHODS_COUNT * 2); const uint16_t len = stop - start; - uint8_t data[1+2+2]; + uint8_t data[1 + 2 + 2]; data[0] = 0x01; data[1] = HI16(address); data[2] = LO16(address); if (len > 0) { - memcpy(&data[3], buffer+start, len); + memcpy(&data[3], buffer + start, len); } ble.gattServer().write( characteristicsHandle, - data, 3 + len); + data, + static_cast(3 + len)); } - } } \ No newline at end of file diff --git a/source/BluetoothServiceDebug.h b/source/BluetoothServiceDebug.h index 06bd0fa..38d0200 100644 --- a/source/BluetoothServiceDebug.h +++ b/source/BluetoothServiceDebug.h @@ -1,29 +1,22 @@ -#ifndef INTERPRETER_BLUETOOTH_DEBUG_H -#define INTERPRETER_BLUETOOTH_DEBUG_H - -#include "ble/BLE.h" +#pragma once #include "Interpreter.h" +#include "ble/BLE.h" -class BluetoothServiceDebug -{ - public: - - BluetoothServiceDebug(Interpreter &interpreter); - - void onDataWritten(const GattWriteCallbackParams *params); - void onDataRead(GattReadAuthCallbackParams *params); +class BluetoothServiceDebug { +public: + BluetoothServiceDebug(Interpreter& interpreter); - private: + void onDataWritten(const GattWriteCallbackParams* params); + void onDataRead(GattReadAuthCallbackParams* params); - Interpreter &interpreter; - BLEDevice &ble; +private: + Interpreter& interpreter; + BLEDevice& ble; - GattAttribute::Handle_t characteristicsHandle; - GattCharacteristic characteristic; - uint8_t characteristicsBuffer[CHARACTERISTICS_BUFFER_LEN]; + GattAttribute::Handle_t characteristicsHandle; + GattCharacteristic characteristic; + uint8_t characteristicsBuffer[CHARACTERISTICS_BUFFER_LEN]; - uint8_t selector; - uint16_t address; + uint8_t selector; + uint16_t address; }; - -#endif diff --git a/source/BluetoothServiceNotify.cpp b/source/BluetoothServiceNotify.cpp index 0fdf59f..ff27017 100644 --- a/source/BluetoothServiceNotify.cpp +++ b/source/BluetoothServiceNotify.cpp @@ -1,6 +1,6 @@ #include "BluetoothServiceNotify.h" #include "MicroBit.h" -#include "ble/UUID.h" +//#include "ble/UUID.h" #include "Bytes.h" extern MicroBit uBit; @@ -22,7 +22,8 @@ BluetoothServiceNotify::BluetoothServiceNotify(Interpreter &_interpreter) : (uint8_t *)&characteristicsBuffer, 0, sizeof(characteristicsBuffer), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY - ) + ), + characteristicsBuffer() { characteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL); characteristic.setReadAuthorizationCallback(this, &BluetoothServiceNotify::onDataRead); diff --git a/source/BluetoothServiceNotify.h b/source/BluetoothServiceNotify.h index dd23085..8708c95 100644 --- a/source/BluetoothServiceNotify.h +++ b/source/BluetoothServiceNotify.h @@ -1,6 +1,4 @@ -#ifndef INTERPRETER_BLUETOOTH_NOTIFY_H -#define INTERPRETER_BLUETOOTH_NOTIFY_H - +#pragma once #include "ble/BLE.h" #include "Interpreter.h" @@ -22,5 +20,3 @@ class BluetoothServiceNotify GattCharacteristic characteristic; uint8_t characteristicsBuffer[CHARACTERISTICS_BUFFER_LEN]; }; - -#endif diff --git a/source/BluetoothServiceProgram.cpp b/source/BluetoothServiceProgram.cpp index c6e9c27..7bff9d2 100644 --- a/source/BluetoothServiceProgram.cpp +++ b/source/BluetoothServiceProgram.cpp @@ -1,6 +1,6 @@ #include "BluetoothServiceProgram.h" #include "MicroBit.h" -#include "ble/UUID.h" +//#include "ble/UUID.h" #include "Bytes.h" extern MicroBit uBit; @@ -22,7 +22,8 @@ BluetoothServiceProgram::BluetoothServiceProgram(Interpreter &_interpreter) : (uint8_t *)&characteristicsBuffer, 0, sizeof(characteristicsBuffer), GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ - ) + ), + characteristicsBuffer() { characteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL); characteristic.setReadAuthorizationCallback(this, &BluetoothServiceProgram::onDataRead); @@ -48,7 +49,7 @@ void BluetoothServiceProgram::onDataWritten(const GattWriteCallbackParams *param if (params->handle == characteristicsHandle) { const uint8_t *data = params->data; - const uint8_t len = params->len; + const uint16_t len = params->len; if (len < 2*2) { interpreter.status = INTERPRETER_KO_LEN_TOO_SHORT; diff --git a/source/BluetoothServiceProgram.h b/source/BluetoothServiceProgram.h index 918503b..86a93e7 100644 --- a/source/BluetoothServiceProgram.h +++ b/source/BluetoothServiceProgram.h @@ -1,6 +1,4 @@ -#ifndef INTERPRETER_BLUETOOTH_LINK_H -#define INTERPRETER_BLUETOOTH_LINK_H - +#pragma once #include "ble/BLE.h" #include "Interpreter.h" @@ -22,5 +20,3 @@ class BluetoothServiceProgram GattCharacteristic characteristic; uint8_t characteristicsBuffer[CHARACTERISTICS_BUFFER_LEN]; }; - -#endif diff --git a/source/Bytes.h b/source/Bytes.h index 2ecff09..6951eb1 100644 --- a/source/Bytes.h +++ b/source/Bytes.h @@ -1,8 +1,6 @@ -#ifndef BYTES_H -#define BYTES_H +#pragma once +#include -#define HI16(i) (uint8_t)(((i)>>8)&0xff) -#define LO16(i) (uint8_t)((i)&0xff) -#define BYTES_TO_UINT16(hi,lo) (uint16_t)(((hi)<<8)|(lo)) - -#endif +#define HI16(i) static_cast(((i)>>8)&0xff) +#define LO16(i) static_cast((i)&0xff) +#define BYTES_TO_UINT16(hi,lo) static_cast(((hi)<<8)|(lo)) diff --git a/source/Images.cpp b/source/Images.cpp index 4968f37..128284a 100644 --- a/source/Images.cpp +++ b/source/Images.cpp @@ -1,4 +1,5 @@ #include "Images.h" +#include static const uint8_t pixel_full[25] = { 1, 1, 1, 1, 1, diff --git a/source/Images.h b/source/Images.h index 64abce4..3685848 100644 --- a/source/Images.h +++ b/source/Images.h @@ -1,5 +1,4 @@ #pragma once - #include "MicroBitImage.h" extern const MicroBitImage *images[17]; diff --git a/source/Instruction.cpp b/source/Instruction.cpp index 659fb7d..8087734 100644 --- a/source/Instruction.cpp +++ b/source/Instruction.cpp @@ -1,3 +1,4 @@ +#include #include "Instruction.h" #include "MicroBit.h" #include "Images.h" @@ -10,12 +11,12 @@ extern BluetoothServiceNotify *notify; typedef struct { InterpreterStatus error; - uint16_t *value; + int32_t *value; } Register; static Register register_read(Slice &code, RunState &state) { - Register result; + Register result = {}; if (slice_available(code) < 1) { result.error = INTERPRETER_KO_INSTRUCTION_INVALID; @@ -35,7 +36,7 @@ static Register register_read(Slice &code, RunState &state) return result; } -static void compare(uint16_t a, uint16_t b, RunState &state) +static void compare(int32_t a, int32_t b, RunState &state) { state.cs = (a == b) ? COMPARED_EQ : @@ -176,10 +177,9 @@ void instruction_bra16(Slice &code, Interpreter &interpreter, RunState &state) return; } - const uint16_t value = slice_read16(code); - const int16_t offset = value; + const int16_t value = slice_read16(code); - state.pc = code.position + offset; + state.pc = code.position + value; } @@ -211,7 +211,7 @@ void instruction_cmpi(Slice &code, Interpreter &interpreter, RunState &state) return; } - const uint16_t a = slice_read16(code); + const int32_t a = slice_read16(code); Register rb = register_read(code, state); if (rb.error) { @@ -238,7 +238,7 @@ void instruction_mov(Slice &code, Interpreter &interpreter, RunState &state) return; } - const uint16_t value = *src.value; + const int32_t value = *src.value; *dst.value = value; @@ -254,7 +254,7 @@ void instruction_movi(Slice &code, Interpreter &interpreter, RunState &state) return; } - const uint16_t value = slice_read16(code); + const int32_t value = slice_read16(code); Register dst = register_read(code, state); if (dst.error) { @@ -284,7 +284,7 @@ void instruction_add(Slice &code, Interpreter &interpreter, RunState &state) return; } - const uint16_t value = *dst.value + *src.value; + const int32_t value = *dst.value + *src.value; *dst.value = value; @@ -307,7 +307,7 @@ void instruction_sub(Slice &code, Interpreter &interpreter, RunState &state) return; } - const uint16_t value = *dst.value - *src.value; + const int32_t value = *dst.value - *src.value; *dst.value = value; @@ -330,7 +330,7 @@ void instruction_mul(Slice &code, Interpreter &interpreter, RunState &state) return; } - const uint16_t value = *dst.value * *src.value; + const int32_t value = *dst.value * *src.value; *dst.value = value; @@ -358,7 +358,7 @@ void instruction_div(Slice &code, Interpreter &interpreter, RunState &state) return; } - const uint16_t value = *dst.value / *src.value; + const int32_t value = *dst.value / *src.value; *dst.value = value; @@ -376,7 +376,7 @@ void instruction_sleep(Slice &code, Interpreter &interpreter, RunState &state) return; } - uBit.sleep(*time.value); + uBit.sleep(static_cast(*time.value)); state.pc = code.position; } @@ -389,7 +389,7 @@ void instruction_random(Slice &code, Interpreter &interpreter, RunState &state) return; } - const uint16_t value = uBit.random(*r.value); + const int32_t value = uBit.random(*r.value); *r.value = value; @@ -406,7 +406,7 @@ void instruction_time(Slice &code, Interpreter &interpreter, RunState &state) return; } - const uint16_t value = uBit.systemTime(); + const int32_t value = uBit.systemTime(); *r.value = value; @@ -424,7 +424,7 @@ void instruction_temperature(Slice &code, Interpreter &interpreter, RunState &st return; } - const uint16_t value = uBit.thermometer.getTemperature(); + const int32_t value = uBit.thermometer.getTemperature(); *r.value = value; @@ -444,7 +444,8 @@ void instruction_noise(Slice &code, Interpreter &interpreter, RunState &state) const int value = uBit.io.P21.getAnalogValue(); if (value > 512) { - const int gauge = ((log2(value - 511) * 4) / 9); + // we do not support double and int32 should be enough + const int32_t gauge = static_cast((log2(value - 511) * 4) / 9); *r.value = gauge; } else { @@ -464,7 +465,7 @@ void instruction_brightness(Slice &code, Interpreter &interpreter, RunState &sta return; } - const uint16_t value = uBit.display.readLightLevel(); + const int32_t value = uBit.display.readLightLevel(); *r.value = value; @@ -482,7 +483,7 @@ void instruction_button(Slice &code, Interpreter &interpreter, RunState &state) return; } - uint16_t value; + int32_t value; switch(*r.value) { case 0x01: @@ -516,13 +517,13 @@ void instruction_pin(Slice &code, Interpreter &interpreter, RunState &state) return; } - const uint16_t i = *r.value; - if (i >= sizeof(pins)) { + const int32_t i = *r.value; + if (i < 0 || static_cast(i) >= sizeof(pins)) { interpreter.status = INTERPRETER_KO_INSTRUCTION_INVALID; return; } - const uint16_t value = uBit.io.pin[pins[i]].isTouched(); + const int32_t value = uBit.io.pin[pins[i]].isTouched(); *r.value = value; @@ -547,7 +548,9 @@ void instruction_display_show_number(Slice &code, Interpreter &interpreter, RunS return; } - uBit.display.print(ManagedString(*number.value)); + const int value = *number.value; + + uBit.display.print(ManagedString(value)); state.pc = code.position; } @@ -560,7 +563,7 @@ void instruction_display_show_image(Slice &code, Interpreter &interpreter, RunSt return; } - const uint16_t i = *image.value; + const int32_t i = *image.value; if (i >= (sizeof(images)/sizeof(images[0]))) { interpreter.status = INTERPRETER_KO_INSTRUCTION_INVALID; return; @@ -670,7 +673,7 @@ void instruction_sound_on(Slice &code, Interpreter &interpreter, RunState &state return; } - uBit.soundmotor.soundOn(*freq.value); + uBit.soundmotor.soundOn(static_cast(*freq.value)); state.pc = code.position; } @@ -701,7 +704,7 @@ void instruction_pitch(Slice &code, Interpreter &interpreter, RunState &state) return; } - const uint16_t value = uBit.accelerometer.getPitch(); + const int32_t value = uBit.accelerometer.getPitch(); *r.value = value; @@ -718,7 +721,7 @@ void instruction_roll(Slice &code, Interpreter &interpreter, RunState &state) return; } - const uint16_t value = uBit.accelerometer.getRoll(); + const int32_t value = uBit.accelerometer.getRoll(); *r.value = value; @@ -767,8 +770,9 @@ void instruction_notify(Slice &code, Interpreter &interpreter, RunState &state) return; } - if (notify != NULL) { - notify->send(*address.value, *value.value); + if (notify != nullptr) { + // the protocol is allows only for the lower 16 bit + notify->send(static_cast(*address.value), static_cast(*value.value)); } state.pc = code.position; diff --git a/source/Instruction.h b/source/Instruction.h index c6fd5e5..32afd4e 100644 --- a/source/Instruction.h +++ b/source/Instruction.h @@ -1,5 +1,4 @@ -#ifndef INSTRUCTION_H -#define INSTRUCTION_H +#pragma once #include "Slice.h" #include "Interpreter.h" @@ -52,6 +51,3 @@ void instruction_roll(Slice &code, Interpreter &interpreter, RunState &state); void instruction_position(Slice &code, Interpreter &interpreter, RunState &state); void instruction_notify(Slice &code, Interpreter &interpreter, RunState &state); void instruction_debug(Slice &code, Interpreter &interpreter, RunState &state); - - -#endif \ No newline at end of file diff --git a/source/Interpreter.cpp b/source/Interpreter.cpp index eb37a3c..8d00925 100644 --- a/source/Interpreter.cpp +++ b/source/Interpreter.cpp @@ -1,6 +1,6 @@ #include "Interpreter.h" #include "MicroBit.h" -#include "BluetoothServiceDebug.h" +//#include "BluetoothServiceDebug.h" #include "BluetoothServiceProgram.h" #include "BluetoothServiceNotify.h" #include "Instruction.h" @@ -25,7 +25,7 @@ static uint16_t find_stop(InterpreterMethod method) #ifdef DEBUG static uint8_t running = 0; #endif -static void interpreter_run_method(InterpreterMethod method, uint16_t r0 = 0, uint16_t r1 = 0, uint16_t r2 = 0) +static void interpreter_run_method(InterpreterMethod method, int32_t r0 = 0, int32_t r1 = 0, int32_t r2 = 0) { //microbit_heap_print(); @@ -43,7 +43,7 @@ static void interpreter_run_method(InterpreterMethod method, uint16_t r0 = 0, ui #endif // initialize interpreter state - RunState state; + RunState state = {}; state.pc = start; state.cs = COMPARED_EQ; state.stack = stop; @@ -421,7 +421,7 @@ static void interpreter_init() new BluetoothServiceProgram(interpreter); notify = new BluetoothServiceNotify(interpreter); - uBit.sleep(100); + uBit.sleep(200); } void interpreter_run() diff --git a/source/Interpreter.h b/source/Interpreter.h index 8e595f3..aac76c2 100644 --- a/source/Interpreter.h +++ b/source/Interpreter.h @@ -1,13 +1,11 @@ -#ifndef INTERPRETER_H -#define INTERPRETER_H - +#pragma once #include #define VERSION_MAJOR 0 #define VERSION_MINOR 0 #define METHODS_COUNT 5 -#define CODE_LEN 180 +#define CODE_LEN 200 #define REGISTER_COUNT 5 #define CHARACTERISTICS_BUFFER_LEN 40 @@ -52,8 +50,8 @@ typedef enum { typedef struct { uint16_t pc; - uint16_t reg[REGISTER_COUNT]; uint16_t stack; // this should be a stack, for now one address is enough + int32_t reg[REGISTER_COUNT]; CompareState cs; } RunState; @@ -134,5 +132,3 @@ void interpreter_run(); void interpreter_start(); void interpreter_reset(); uint16_t interpreter_calculate_hash(); - -#endif \ No newline at end of file diff --git a/source/Main.cpp b/source/Main.cpp index e219053..5c3c6a5 100644 --- a/source/Main.cpp +++ b/source/Main.cpp @@ -1,14 +1,14 @@ +#include "Images.h" +#include "Interpreter.h" #include "Menu.h" #include "MicroBit.h" -#include "Images.h" -#include "Storage.h" -#include "RunTests.h" #include "RunDemo.h" +#include "RunLoveMeter.h" #include "RunOracle.h" #include "RunRockPaperScissors.h" -#include "RunLoveMeter.h" #include "RunSnake.h" -#include "Interpreter.h" +#include "RunTests.h" +#include "Storage.h" MicroBit uBit; @@ -19,7 +19,8 @@ static inline void waitForever() } } -static void menuAnimateEnter() { +static void menuAnimateEnter() +{ uBit.display.print(ImageDot); uBit.sleep(200); uBit.display.print(ImageSmallRect); @@ -29,7 +30,8 @@ static void menuAnimateEnter() { uBit.display.clear(); } -static void menuAnimateLeave() { +static void menuAnimateLeave() +{ uBit.display.print(ImageLargeRect); uBit.sleep(200); uBit.display.print(ImageSmallRect); @@ -49,7 +51,7 @@ int main() if (hasStorageKey(KEY_INTERPRETER)) { removeStorageKey(KEY_INTERPRETER); - // mimimize serial buffer + // minimize serial buffer uBit.serial.setTxBufferSize(0); interpreter_run(); diff --git a/source/Menu.cpp b/source/Menu.cpp index d9b2686..b0e7498 100644 --- a/source/Menu.cpp +++ b/source/Menu.cpp @@ -10,11 +10,11 @@ menustate_t menuWaitForChoice(menustate_t start) if (state == MenuStateInterpreter) { static const uint8_t pixels[25] = { - 0, 0, 1, 1, 1, - 0, 0, 0, 1, 1, - 0, 0, 1, 0, 1, - 0, 1, 0, 0, 0, - 1, 0, 0, 0, 0 + 0, 0, 1, 1, 1, + 0, 0, 0, 1, 1, + 0, 0, 1, 0, 1, + 0, 1, 0, 0, 0, + 1, 0, 0, 0, 0 }; const MicroBitImage Image(5, 5, pixels); @@ -23,7 +23,6 @@ menustate_t menuWaitForChoice(menustate_t start) } else { uBit.display.print(ManagedString(state)); - } // event loop diff --git a/source/RunDemo.cpp b/source/RunDemo.cpp index d84356a..e2edc8a 100644 --- a/source/RunDemo.cpp +++ b/source/RunDemo.cpp @@ -1,8 +1,8 @@ #include "RunDemo.h" #include "Images.h" +#include "Localization.h" #include "MicroBit.h" #include "Utils.h" -#include "Localization.h" extern MicroBit uBit; diff --git a/source/RunOracle.cpp b/source/RunOracle.cpp index bf7ecee..a8c026e 100644 --- a/source/RunOracle.cpp +++ b/source/RunOracle.cpp @@ -26,7 +26,7 @@ void oracle_run() uBit.display.print(ImageArrowLeft); - for(int t=0, i=10; t<400 && !leave && !event; t+=i) { + for(uint32_t t=0, i=10; t<400 && !leave && !event; t+=i) { uBit.sleep(i); } @@ -37,7 +37,7 @@ void oracle_run() uBit.sleep(10); uBit.display.clear(); - for(int t=0, i=10; t<400 && !leave && !event; t+=i) { + for(uint32_t t=0, i=10; t<400 && !leave && !event; t+=i) { uBit.sleep(i); } } diff --git a/source/RunSnake.cpp b/source/RunSnake.cpp index bf1568a..8f5d12f 100644 --- a/source/RunSnake.cpp +++ b/source/RunSnake.cpp @@ -1,6 +1,6 @@ #include "RunSnake.h" #include "MicroBit.h" -#include "Images.h" +//#include "Images.h" #include "Utils.h" extern MicroBit uBit; diff --git a/source/RunTests.cpp b/source/RunTests.cpp index 028457a..3a194b5 100644 --- a/source/RunTests.cpp +++ b/source/RunTests.cpp @@ -1,8 +1,9 @@ +#include #include "RunTests.h" #include "MicroBit.h" -#include "MicroBitSerial.h" +//#include "MicroBitSerial.h" #include "Images.h" -#include "Utils.h" +//#include "Utils.h" extern MicroBit uBit; @@ -157,10 +158,13 @@ void tests_run() int mic = uBit.io.P21.getAnalogValue(); // ((value - fromLow) * (toHigh - toLow)) / (fromHigh - fromLow) + toLow if (mic > 512) { - const int gauge = ((log2(mic - 511) * 4) / 9); + const int gauge = static_cast((log2(mic - 511) * 4) / 9); - for (int i = 0; i <= 4; i++) { - uBit.display.image.setPixelValue(4, 4 - i, i > gauge ? 0 : 255); + for (uint8_t i = 0; i <= 4; i++) { + const int16_t x = static_cast(4); + const int16_t y = static_cast(4 - i); + const uint8_t t = static_cast(i > gauge ? 0 : 255); + uBit.display.image.setPixelValue(x, y, t); } uBit.sleep(10); diff --git a/source/Slice.cpp b/source/Slice.cpp index 0a7816f..5069035 100644 --- a/source/Slice.cpp +++ b/source/Slice.cpp @@ -2,7 +2,7 @@ Slice slice_create(uint8_t *buffer, uint16_t start, uint16_t stop) { - Slice slice; + Slice slice = {}; slice.buffer = buffer; slice.start = start; slice.position = start; diff --git a/source/Utils.cpp b/source/Utils.cpp index 456312b..b539bc1 100644 --- a/source/Utils.cpp +++ b/source/Utils.cpp @@ -1,6 +1,6 @@ #include "Utils.h" -#include "MicroBit.h" -#include "MicroBitImage.h" +//#include "MicroBit.h" +//#include "MicroBitImage.h" extern MicroBit uBit; @@ -26,7 +26,7 @@ void blinkImage( uBit.display.print(image, pos); - for (int t = 0, i = 10; t < delay && !leave && !event; t += i) { + for (uint32_t t = 0, i = 10; t < delay && !leave && !event; t += i) { uBit.sleep(i); } @@ -36,7 +36,7 @@ void blinkImage( uBit.display.clear(); - for (int t = 0, i = 10; t < delay && !leave && !event; t += i) { + for (uint32_t t = 0, i = 10; t < delay && !leave && !event; t += i) { uBit.sleep(i); } } From 99a328eb911c6c8f546358330bddcb59205920b0 Mon Sep 17 00:00:00 2001 From: Torsten Curdt Date: Mon, 26 Feb 2018 00:06:22 +0100 Subject: [PATCH 05/28] map the buttons --- source/Interpreter.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/source/Interpreter.cpp b/source/Interpreter.cpp index 8d00925..3a185c3 100644 --- a/source/Interpreter.cpp +++ b/source/Interpreter.cpp @@ -253,11 +253,19 @@ static void interpreter_startup_sound() static void interpreter_on_button(MicroBitEvent event) { - LOG("button 0x%x 0x%x start\n\r", event.source, event.value); + uint8_t source; + switch(event.source) { + case MICROBIT_ID_BUTTON_A: source = 1; break; + case MICROBIT_ID_BUTTON_B: source = 2; break; + case MICROBIT_ID_BUTTON_AB: source = 3; break; + default: return; + } + + LOG("button 0x%x 0x%x start\n\r", source, event.value); - interpreter_run_method(METHOD_ON_BUTTON, event.source, event.value); + interpreter_run_method(METHOD_ON_BUTTON, source, event.value); - LOG("button 0x%x 0x%x stop\n\r", event.source, event.value); + LOG("button 0x%x 0x%x stop\n\r", source, event.value); } static void interpreter_on_pin(MicroBitEvent event) From 053f940c93ea0603c342f0c07ba4e3b8679904cd Mon Sep 17 00:00:00 2001 From: Torsten Curdt Date: Mon, 26 Feb 2018 13:37:19 +0100 Subject: [PATCH 06/28] have log and memsum --- contrib/log.sh | 3 +-- contrib/memsum.sh | 7 +++++++ 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 contrib/memsum.sh diff --git a/contrib/log.sh b/contrib/log.sh index 9db7224..db155fb 100755 --- a/contrib/log.sh +++ b/contrib/log.sh @@ -4,6 +4,5 @@ ROOT="$( cd "$(dirname "$0")" ; pwd -P )" DEVICE=/dev/cu.usbmodem1422 -#( stty speed 115200 cs8 1>/dev/null 2>&1; cat ) <$DEVICE +( stty speed 115200 cs8 1>/dev/null 2>&1; cat ) <$DEVICE #( stty speed 115200 cs8 1>/dev/null 2>&1; hexdump -C ) <$DEVICE -( stty speed 115200 cs8 1>/dev/null 2>&1; python2 $ROOT/memsum.py Calliope) <$DEVICE diff --git a/contrib/memsum.sh b/contrib/memsum.sh new file mode 100644 index 0000000..1d972ea --- /dev/null +++ b/contrib/memsum.sh @@ -0,0 +1,7 @@ + +#!/bin/sh + +ROOT="$( cd "$(dirname "$0")" ; pwd -P )" +DEVICE=/dev/cu.usbmodem1422 + +( stty speed 115200 cs8 1>/dev/null 2>&1; python2 $ROOT/memsum.py Calliope) <$DEVICE From a0465ab2d2fdc42aa2fe0242a3ff8d6363881bc3 Mon Sep 17 00:00:00 2001 From: Torsten Curdt Date: Mon, 26 Feb 2018 13:37:51 +0100 Subject: [PATCH 07/28] indent --- source/Images.cpp | 204 +++++++++++++++++++++++----------------------- 1 file changed, 102 insertions(+), 102 deletions(-) diff --git a/source/Images.cpp b/source/Images.cpp index 128284a..793debb 100644 --- a/source/Images.cpp +++ b/source/Images.cpp @@ -2,123 +2,123 @@ #include static const uint8_t pixel_full[25] = { - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1 }; static const uint8_t pixel_dot[25] = { - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0 }; static const uint8_t pixel_small[25] = { - 0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, - 0, 1, 0, 1, 0, - 0, 1, 1, 1, 0, - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, + 0, 1, 0, 1, 0, + 0, 1, 1, 1, 0, + 0, 0, 0, 0, 0 }; static const uint8_t pixel_large[25] = { - 1, 1, 1, 1, 1, - 1, 0, 0, 0, 1, - 1, 0, 0, 0, 1, - 1, 0, 0, 0, 1, - 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 1, 0, 0, 0, 1, + 1, 0, 0, 0, 1, + 1, 0, 0, 0, 1, + 1, 1, 1, 1, 1, }; static const uint8_t pixel_arrow_left[25] = { - 0, 0, 1, 0, 0, - 0, 1, 0, 0, 0, - 1, 1, 1, 1, 1, - 0, 1, 0, 0, 0, - 0, 0, 1, 0, 0 + 0, 0, 1, 0, 0, + 0, 1, 0, 0, 0, + 1, 1, 1, 1, 1, + 0, 1, 0, 0, 0, + 0, 0, 1, 0, 0 }; static const uint8_t pixel_arrow_right[25] = { - 0, 0, 1, 0, 0, - 0, 0, 0, 1, 0, - 1, 1, 1, 1, 1, - 0, 0, 0, 1, 0, - 0, 0, 1, 0, 0 + 0, 0, 1, 0, 0, + 0, 0, 0, 1, 0, + 1, 1, 1, 1, 1, + 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0 }; static const uint8_t pixel_arrow_leftright[25] = { - 0, 0, 1, 0, 0, - 0, 1, 0, 1, 0, - 1, 0, 0, 0, 1, - 0, 1, 0, 1, 0, - 0, 0, 1, 0, 0 + 0, 0, 1, 0, 0, + 0, 1, 0, 1, 0, + 1, 0, 0, 0, 1, + 0, 1, 0, 1, 0, + 0, 0, 1, 0, 0 }; static const uint8_t pixel_double_row[25] = { - 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0, - 0, 1, 1, 0, 0 + 0, 1, 1, 0, 0, + 0, 1, 1, 0, 0, + 0, 1, 1, 0, 0, + 0, 1, 1, 0, 0, + 0, 1, 1, 0, 0 }; static const uint8_t pixel_tick[25] = { - 0, 0, 0, 0, 0, - 0, 0, 0, 0, 1, - 0, 0, 0, 1, 0, - 1, 0, 1, 0, 0, - 0, 1, 0, 0, 0 + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 1, + 0, 0, 0, 1, 0, + 1, 0, 1, 0, 0, + 0, 1, 0, 0, 0 }; static const uint8_t pixel_heart[25] = { - 0, 1, 0, 1, 0, - 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, - 0, 1, 1, 1, 0, - 0, 0, 1, 0, 0 + 0, 1, 0, 1, 0, + 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, + 0, 1, 1, 1, 0, + 0, 0, 1, 0, 0 }; static const uint8_t pixel_smiley[25] = { - 0, 1, 0, 1, 0, - 0, 1, 0, 1, 0, - 0, 0, 0, 0, 0, - 1, 0, 0, 0, 1, - 0, 1, 1, 1, 0 + 0, 1, 0, 1, 0, + 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, + 1, 0, 0, 0, 1, + 0, 1, 1, 1, 0 }; static const uint8_t pixel_sadly[25] = { - 0, 1, 0, 1, 0, - 0, 1, 0, 1, 0, - 0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, - 1, 0, 0, 0, 1 + 0, 1, 0, 1, 0, + 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, + 1, 0, 0, 0, 1 }; static const uint8_t pixel_rock[25] = { - 0, 0, 0, 0, 0, - 0, 1, 1, 1, 0, - 0, 1, 1, 1, 0, - 0, 1, 1, 1, 0, - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, + 0, 1, 1, 1, 0, + 0, 1, 1, 1, 0, + 0, 1, 1, 1, 0, + 0, 0, 0, 0, 0 }; static const uint8_t pixel_scissors[25] = { - 1, 0, 0, 0, 1, - 0, 1, 0, 1, 0, - 0, 0, 1, 0, 0, - 0, 1, 0, 1, 0, - 1, 0, 0, 0, 1 + 1, 0, 0, 0, 1, + 0, 1, 0, 1, 0, + 0, 0, 1, 0, 0, + 0, 1, 0, 1, 0, + 1, 0, 0, 0, 1 }; static const uint8_t pixel_well[25] = { - 0, 1, 1, 1, 0, - 1, 0, 0, 0, 1, - 1, 0, 0, 0, 1, - 1, 0, 0, 0, 1, - 0, 1, 1, 1, 0 + 0, 1, 1, 1, 0, + 1, 0, 0, 0, 1, + 1, 0, 0, 0, 1, + 1, 0, 0, 0, 1, + 0, 1, 1, 1, 0 }; static const uint8_t pixel_flash[25] = { - 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, - 1, 1, 1, 1, 1, - 0, 0, 1, 1, 0, - 0, 1, 1, 0, 0, + 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, + 1, 1, 1, 1, 1, + 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, }; static const uint8_t pixel_wave[7 * 5] = { - 0, 0, 0, 0, 0, 0, 0, - 0, 1, 1, 0, 0, 0, 0, - 1, 0, 0, 1, 0, 0, 1, - 0, 0, 0, 0, 1, 1, 0, - 0, 0, 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 0, 0, 0, 0, + 1, 0, 0, 1, 0, 0, 1, + 0, 0, 0, 0, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0 }; const MicroBitImage ImageSmiley(5, 5, pixel_smiley); @@ -140,21 +140,21 @@ const MicroBitImage ImageFlash(5, 5, pixel_flash); const MicroBitImage ImageWave(7, 5, pixel_wave); const MicroBitImage *images[17] = { - &ImageSmiley, - &ImageSadly, - &ImageHeart, - &ImageArrowLeft, - &ImageArrowRight, - &ImageArrowLeftRight, - &ImageFull, - &ImageDot, - &ImageSmallRect, - &ImageLargeRect, - &ImageDoubleRow, - &ImageTick, - &ImageRock, - &ImageScissors, - &ImageWell, - &ImageFlash, - &ImageWave, + &ImageSmiley, + &ImageSadly, + &ImageHeart, + &ImageArrowLeft, + &ImageArrowRight, + &ImageArrowLeftRight, + &ImageFull, + &ImageDot, + &ImageSmallRect, + &ImageLargeRect, + &ImageDoubleRow, + &ImageTick, + &ImageRock, + &ImageScissors, + &ImageWell, + &ImageFlash, + &ImageWave, }; From 19be44f8df824d459ed870125e0c6b80047c864a Mon Sep 17 00:00:00 2001 From: Torsten Curdt Date: Mon, 26 Feb 2018 13:38:05 +0100 Subject: [PATCH 08/28] lower buffer size to 180 --- source/Interpreter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Interpreter.h b/source/Interpreter.h index aac76c2..f0e9d29 100644 --- a/source/Interpreter.h +++ b/source/Interpreter.h @@ -5,7 +5,7 @@ #define VERSION_MINOR 0 #define METHODS_COUNT 5 -#define CODE_LEN 200 +#define CODE_LEN 180 #define REGISTER_COUNT 5 #define CHARACTERISTICS_BUFFER_LEN 40 From b676a1007f75d2dfc9b1e64ec8c6e5d07ad33a36 Mon Sep 17 00:00:00 2001 From: Torsten Curdt Date: Mon, 26 Feb 2018 13:38:21 +0100 Subject: [PATCH 09/28] text for every language --- source/Localization.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/Localization.h b/source/Localization.h index 91b0fdd..ec099fc 100644 --- a/source/Localization.h +++ b/source/Localization.h @@ -1,8 +1,8 @@ #pragma once -#define LS_DEMO_HELLO "Hallo!" +#define LS_DEMO_HELLO "Hi!" #define LS_DEMO_BUTTON_A "A" #define LS_DEMO_BUTTON_B "B" #define LS_DEMO_BUTTON_AB "A+B" -#define LS_DEMO_SHAKE "SCHUETTELN" -#define LS_DEMO_GREAT "SUPER!" +//#define LS_DEMO_SHAKE "SCHUETTELN" +#define LS_DEMO_GREAT "OK!" From 8e7d965da16724c3f6f21c9e23f140bdee7c53e7 Mon Sep 17 00:00:00 2001 From: Torsten Curdt Date: Mon, 26 Feb 2018 13:38:40 +0100 Subject: [PATCH 10/28] no shake text --- source/RunDemo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/RunDemo.cpp b/source/RunDemo.cpp index e2edc8a..3b58caa 100644 --- a/source/RunDemo.cpp +++ b/source/RunDemo.cpp @@ -69,7 +69,7 @@ void demo_run() uBit.display.clear(); // shake - uBit.display.scroll(LS_DEMO_SHAKE); + //uBit.display.scroll(LS_DEMO_SHAKE); blinkImageUntilEvent( MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_SHAKE, From 3c1379b8e858d0d0ff142353b6921831c17325aa Mon Sep 17 00:00:00 2001 From: Torsten Curdt Date: Mon, 26 Feb 2018 13:38:58 +0100 Subject: [PATCH 11/28] clear before mic test --- source/RunTests.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/RunTests.cpp b/source/RunTests.cpp index 3a194b5..51d24fe 100644 --- a/source/RunTests.cpp +++ b/source/RunTests.cpp @@ -154,17 +154,21 @@ void tests_run() uBit.messageBus.listen(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_TILT_LEFT, onTiltLeft); uBit.messageBus.listen(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_TILT_RIGHT, onTiltRight); + uBit.sleep(500); + uBit.serial.send("microphone\r\n"); + uBit.display.clear(); + while (true) { int mic = uBit.io.P21.getAnalogValue(); // ((value - fromLow) * (toHigh - toLow)) / (fromHigh - fromLow) + toLow if (mic > 512) { - const int gauge = static_cast((log2(mic - 511) * 4) / 9); + const int gauge = static_cast((log2(mic - 511) * 4) / 9); for (uint8_t i = 0; i <= 4; i++) { const int16_t x = static_cast(4); const int16_t y = static_cast(4 - i); const uint8_t t = static_cast(i > gauge ? 0 : 255); - uBit.display.image.setPixelValue(x, y, t); + uBit.display.image.setPixelValue(x, y, t); } uBit.sleep(10); From 0765b982d4322f391d2142a96dfabadd1b870d11 Mon Sep 17 00:00:00 2001 From: Torsten Curdt Date: Mon, 26 Feb 2018 13:39:17 +0100 Subject: [PATCH 12/28] 1x1 and volume meter --- source/Main.cpp | 22 ++++---- source/Menu.h | 4 +- source/RunMultiplication.cpp | 99 ++++++++++++++++++++++++++++++++++++ source/RunMultiplication.h | 3 ++ source/RunVolumeMeter.cpp | 84 ++++++++++++++++++++++++++++++ source/RunVolumeMeter.h | 3 ++ 6 files changed, 202 insertions(+), 13 deletions(-) create mode 100644 source/RunMultiplication.cpp create mode 100644 source/RunMultiplication.h create mode 100644 source/RunVolumeMeter.cpp create mode 100644 source/RunVolumeMeter.h diff --git a/source/Main.cpp b/source/Main.cpp index 5c3c6a5..c481895 100644 --- a/source/Main.cpp +++ b/source/Main.cpp @@ -1,14 +1,14 @@ -#include "Images.h" -#include "Interpreter.h" -#include "Menu.h" #include "MicroBit.h" +#include "Storage.h" +#include "Images.h" +#include "RunTests.h" #include "RunDemo.h" -#include "RunLoveMeter.h" +#include "Menu.h" #include "RunOracle.h" #include "RunRockPaperScissors.h" -#include "RunSnake.h" -#include "RunTests.h" -#include "Storage.h" +#include "RunMultiplication.h" +#include "RunVolumeMeter.h" +#include "Interpreter.h" MicroBit uBit; @@ -94,15 +94,15 @@ int main() menuAnimateLeave(); break; // 3 - case MenuStateLoveMeter: + case MenuStateMultiplication: menuAnimateEnter(); - lovemeter_run(); + multiplication_run(); menuAnimateLeave(); break; // 4 - case MenuStateSnake: + case MenuStateVolumeMeter: menuAnimateEnter(); - snake_run(); + volumemeter_run(); menuAnimateLeave(); break; // 5 diff --git a/source/Menu.h b/source/Menu.h index 8ff76ca..516638c 100644 --- a/source/Menu.h +++ b/source/Menu.h @@ -3,8 +3,8 @@ typedef enum MenuState { MenuStateOracle = 1, MenuStateRockPaperScissors, - MenuStateLoveMeter, - MenuStateSnake, + MenuStateMultiplication, + MenuStateVolumeMeter, MenuStateInterpreter, MenuStateMin = MenuStateOracle, MenuStateMax = MenuStateInterpreter diff --git a/source/RunMultiplication.cpp b/source/RunMultiplication.cpp new file mode 100644 index 0000000..d668003 --- /dev/null +++ b/source/RunMultiplication.cpp @@ -0,0 +1,99 @@ +#include "RunMultiplication.h" +#include "MicroBit.h" +#include "Utils.h" + +extern MicroBit uBit; + +static const uint8_t pixel_multiplier[25] = { + 0, 0, 0, 0, 0, + 0, 1, 0, 1, 0, + 0, 0, 1, 0, 0, + 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0 +}; +static const MicroBitImage ImageMultiplier(5, 5, pixel_multiplier); + + +static int factor1 = 0; +static int factor2 = 0; +static bool ready = false; + +static void factor1Handler(MicroBitEvent) +{ + factor1 = uBit.random(10); + uBit.display.print(factor1); + + ready = false; +} + +static void factor2Handler(MicroBitEvent) +{ + uBit.display.print(ImageMultiplier); + uBit.sleep(300); + + factor2 = uBit.random(10); + uBit.display.print(factor2); + + ready = true; +} + +static void helpHandler(MicroBitEvent) +{ + if (!ready) { + return; + } + + int result = factor1 * factor2; + uBit.display.scroll(result); + uBit.sleep(300); + uBit.display.clear(); +} + +void multiplication_run() { + + uBit.messageBus.listen( + MICROBIT_ID_BUTTON_AB, + MICROBIT_BUTTON_EVT_CLICK, + leaveHandler); + + uBit.messageBus.listen( + MICROBIT_ID_BUTTON_A, + MICROBIT_BUTTON_EVT_CLICK, + factor1Handler); + + uBit.messageBus.listen( + MICROBIT_ID_BUTTON_B, + MICROBIT_BUTTON_EVT_CLICK, + factor2Handler); + + uBit.messageBus.listen( + MICROBIT_ID_GESTURE, + MICROBIT_ACCELEROMETER_EVT_SHAKE, + helpHandler); + + + leave = false; + while(!leave) { + uBit.sleep(100); + } + + uBit.messageBus.ignore( + MICROBIT_ID_BUTTON_AB, + MICROBIT_BUTTON_EVT_CLICK, + leaveHandler); + + uBit.messageBus.ignore( + MICROBIT_ID_BUTTON_A, + MICROBIT_BUTTON_EVT_CLICK, + factor1Handler); + + uBit.messageBus.ignore( + MICROBIT_ID_BUTTON_B, + MICROBIT_BUTTON_EVT_CLICK, + factor2Handler); + + uBit.messageBus.ignore( + MICROBIT_ID_GESTURE, + MICROBIT_ACCELEROMETER_EVT_SHAKE, + helpHandler); +} \ No newline at end of file diff --git a/source/RunMultiplication.h b/source/RunMultiplication.h new file mode 100644 index 0000000..8173225 --- /dev/null +++ b/source/RunMultiplication.h @@ -0,0 +1,3 @@ +#pragma once + +void multiplication_run(); \ No newline at end of file diff --git a/source/RunVolumeMeter.cpp b/source/RunVolumeMeter.cpp new file mode 100644 index 0000000..8b4d43a --- /dev/null +++ b/source/RunVolumeMeter.cpp @@ -0,0 +1,84 @@ +#include +#include "RunVolumeMeter.h" +#include "MicroBit.h" +#include "Utils.h" + +extern MicroBit uBit; + +const int threshold = 519; + +static int read() +{ + int mic = 0; + const int n = 30; + for (uint8_t i = 0; i < n; i++) { + const int v = uBit.io.P21.getAnalogValue(); + if (v > mic) mic = v; + } + + if (mic < threshold) { + return 0; + } + + // mic 512...900 ~> 0...5 + const int gauge = static_cast((log2(mic - threshold + 1) * 5) / 8); + + // uBit.serial.printf("m:%d -> g:%d\n", mic, gauge); + + if (gauge < 0) { + return 0; + } + + if (gauge > 5) { + return 5; + } + + return gauge; +} + +void volumemeter_run() +{ + uBit.messageBus.listen( + MICROBIT_ID_BUTTON_AB, + MICROBIT_BUTTON_EVT_CLICK, + leaveHandler); + + int gauges[5] = {}; + + leave = false; + while (!leave) { + + // shift values + for (uint8_t i = 0; i < (5-1); i++) { + gauges[i] = gauges[i+1]; + } + + gauges[4] = read(); + + for (uint16_t x = 0; x < 5; x++) { + const int gauge = gauges[x]; + for (uint16_t y = 0; y < 5; y++) { + const uint8_t t = static_cast(gauge > y ? 255 : 0); + uBit.display.image.setPixelValue(x, 4-y, t); + } + } + + int sum = 0; + for (uint8_t i = 0; i < 5; i++) { + sum += gauges[i]; + } + + if (sum > 5*2.5) { + uBit.rgb.setColour(0xFF, 0x00, 0x00, 0x00); + } else { + uBit.rgb.off(); + } + + uBit.sleep(100); + } + + uBit.messageBus.ignore( + MICROBIT_ID_BUTTON_AB, + MICROBIT_BUTTON_EVT_CLICK, + leaveHandler); +} \ No newline at end of file diff --git a/source/RunVolumeMeter.h b/source/RunVolumeMeter.h new file mode 100644 index 0000000..1d2dd78 --- /dev/null +++ b/source/RunVolumeMeter.h @@ -0,0 +1,3 @@ +#pragma once + +void volumemeter_run(); \ No newline at end of file From a3ecfe707a2051868a43b40fd6ba53d9cc379035 Mon Sep 17 00:00:00 2001 From: Torsten Curdt Date: Mon, 26 Feb 2018 14:40:42 +0100 Subject: [PATCH 13/28] volume low -> green, --- source/RunVolumeMeter.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/RunVolumeMeter.cpp b/source/RunVolumeMeter.cpp index 8b4d43a..af5abab 100644 --- a/source/RunVolumeMeter.cpp +++ b/source/RunVolumeMeter.cpp @@ -71,12 +71,14 @@ void volumemeter_run() if (sum > 5*2.5) { uBit.rgb.setColour(0xFF, 0x00, 0x00, 0x00); } else { - uBit.rgb.off(); + uBit.rgb.setColour(0x00, 0xFF, 0x00, 0x00); } uBit.sleep(100); } + uBit.rgb.off(); + uBit.messageBus.ignore( MICROBIT_ID_BUTTON_AB, MICROBIT_BUTTON_EVT_CLICK, From 956e0abc50d4251b32defe250bf91848d859d789 Mon Sep 17 00:00:00 2001 From: Torsten Curdt Date: Mon, 26 Feb 2018 14:40:59 +0100 Subject: [PATCH 14/28] show arrow as instruction --- source/RunMultiplication.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/source/RunMultiplication.cpp b/source/RunMultiplication.cpp index d668003..c41b429 100644 --- a/source/RunMultiplication.cpp +++ b/source/RunMultiplication.cpp @@ -1,15 +1,16 @@ #include "RunMultiplication.h" #include "MicroBit.h" #include "Utils.h" +#include "Images.h" extern MicroBit uBit; static const uint8_t pixel_multiplier[25] = { - 0, 0, 0, 0, 0, - 0, 1, 0, 1, 0, - 0, 0, 1, 0, 0, - 0, 1, 0, 1, 0, - 0, 0, 0, 0, 0 + 0, 0, 0, 0, 0, + 0, 1, 0, 1, 0, + 0, 0, 1, 0, 0, + 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0 }; static const MicroBitImage ImageMultiplier(5, 5, pixel_multiplier); @@ -46,7 +47,8 @@ static void helpHandler(MicroBitEvent) int result = factor1 * factor2; uBit.display.scroll(result); uBit.sleep(300); - uBit.display.clear(); + + uBit.display.print(ImageArrowLeft); } void multiplication_run() { @@ -71,6 +73,7 @@ void multiplication_run() { MICROBIT_ACCELEROMETER_EVT_SHAKE, helpHandler); + uBit.display.print(ImageArrowLeft); leave = false; while(!leave) { From 89e7eb8c088a1c5082c43d6743c964fea2d2336e Mon Sep 17 00:00:00 2001 From: Torsten Curdt Date: Mon, 26 Feb 2018 15:00:06 +0100 Subject: [PATCH 15/28] silence warning --- source/Instruction.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Instruction.cpp b/source/Instruction.cpp index 8087734..27f3043 100644 --- a/source/Instruction.cpp +++ b/source/Instruction.cpp @@ -564,7 +564,7 @@ void instruction_display_show_image(Slice &code, Interpreter &interpreter, RunSt } const int32_t i = *image.value; - if (i >= (sizeof(images)/sizeof(images[0]))) { + if (static_cast(i) >= sizeof(images)/sizeof(images[0])) { interpreter.status = INTERPRETER_KO_INSTRUCTION_INVALID; return; } From efeb1803af7bd2ae6f4104f90d8d14715cecea48 Mon Sep 17 00:00:00 2001 From: Torsten Curdt Date: Mon, 26 Feb 2018 15:00:33 +0100 Subject: [PATCH 16/28] being lazy --- contrib/copy.sh | 6 +++--- contrib/upload.sh | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/contrib/copy.sh b/contrib/copy.sh index 2a73d04..3f0ca6c 100755 --- a/contrib/copy.sh +++ b/contrib/copy.sh @@ -4,10 +4,10 @@ SRC=../../calliope_playbook_mini/source/ DST=`pwd`/source/ rsync -rtuv --progress $SRC $DST --exclude Main.* -#rsync -rtuv --progress $DST $SRC --exclude Main.* +# rsync -rtuv --progress $DST $SRC --exclude Main.* --exclude Run*.* --exclude Localization.* --exclude Utils*.* --exclude Menu.* --exclude Storage.* SRC=../../calliope_playbook_mini/contrib/ DST=`pwd`/contrib/ -rsync -rtuv --progress $SRC $DST -#rsync -rtuv --progress $DST $SRC +# rsync -rtuv --progress $SRC $DST +# rsync -n -rtuv --progress $DST $SRC diff --git a/contrib/upload.sh b/contrib/upload.sh index a9be492..6380108 100755 --- a/contrib/upload.sh +++ b/contrib/upload.sh @@ -1,3 +1,7 @@ #!/bin/sh cp build/calliope-mini-classic-gcc/source/*-combined.hex /Volumes/MINI/ + +if [ -x $HOME/Shared/Manolis ]; then + cp build/calliope-mini-classic-gcc/source/*-combined.hex $HOME/Shared/Manolis +fi From 9db8b48a82236f4310f053bb3c3efffa82f3b796 Mon Sep 17 00:00:00 2001 From: Torsten Curdt Date: Mon, 26 Feb 2018 15:31:53 +0100 Subject: [PATCH 17/28] show histogram --- source/Menu.cpp | 47 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/source/Menu.cpp b/source/Menu.cpp index b0e7498..ef1311c 100644 --- a/source/Menu.cpp +++ b/source/Menu.cpp @@ -1,24 +1,53 @@ #include "Menu.h" #include "MicroBit.h" +#include "nrf.h" extern MicroBit uBit; +static void showNameHistogram(MicroBitDisplay &display) +{ + NRF_FICR_Type *ficr = NRF_FICR; + uint32_t n = ficr->DEVICEID[1]; + uint32_t ld = 1; + uint32_t d = MICROBIT_DFU_HISTOGRAM_HEIGHT; + uint32_t h; + + display.clear(); + for (uint32_t i = 0; i < MICROBIT_DFU_HISTOGRAM_WIDTH; i++) + { + h = (n % d) / ld; + + n -= h; + d *= MICROBIT_DFU_HISTOGRAM_HEIGHT; + ld *= MICROBIT_DFU_HISTOGRAM_HEIGHT; + + for (uint32_t j = 0; j < h + 1; j++) + display.image.setPixelValue( + static_cast(MICROBIT_DFU_HISTOGRAM_WIDTH - i - 1), + static_cast(MICROBIT_DFU_HISTOGRAM_HEIGHT - j - 1), + 255); + } +} + + menustate_t menuWaitForChoice(menustate_t start) { menustate_t state = start; while (true) { if (state == MenuStateInterpreter) { - static const uint8_t pixels[25] = { - 0, 0, 1, 1, 1, - 0, 0, 0, 1, 1, - 0, 0, 1, 0, 1, - 0, 1, 0, 0, 0, - 1, 0, 0, 0, 0 - }; - const MicroBitImage Image(5, 5, pixels); + showNameHistogram(uBit.display); + + // static const uint8_t pixels[25] = { + // 0, 0, 1, 1, 1, + // 0, 0, 0, 1, 1, + // 0, 0, 1, 0, 1, + // 0, 1, 0, 0, 0, + // 1, 0, 0, 0, 0 + // }; + // const MicroBitImage Image(5, 5, pixels); - uBit.display.print(Image); + // uBit.display.print(Image); } else { From 2a488d847a9f5803592d5a99def00e7dbd7be4fa Mon Sep 17 00:00:00 2001 From: Torsten Curdt Date: Tue, 27 Feb 2018 00:50:37 +0100 Subject: [PATCH 18/28] longer code buffer --- source/Interpreter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Interpreter.h b/source/Interpreter.h index f0e9d29..9cc0285 100644 --- a/source/Interpreter.h +++ b/source/Interpreter.h @@ -5,7 +5,7 @@ #define VERSION_MINOR 0 #define METHODS_COUNT 5 -#define CODE_LEN 180 +#define CODE_LEN 256 #define REGISTER_COUNT 5 #define CHARACTERISTICS_BUFFER_LEN 40 From 9b67c071c2f67a42c69fe38d2c01beb476c3cf23 Mon Sep 17 00:00:00 2001 From: Torsten Curdt Date: Tue, 27 Feb 2018 14:13:32 +0100 Subject: [PATCH 19/28] use official docker image --- contrib/yotta.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/yotta.sh b/contrib/yotta.sh index 825e040..51138eb 100755 --- a/contrib/yotta.sh +++ b/contrib/yotta.sh @@ -1,3 +1,3 @@ #!/bin/sh -docker run -v $(pwd):/project:rw -it calliope/build yotta $1 +docker run -v $(pwd):/project:rw -it calliopeedu/yotta yotta $1 From cc6427e715ef07edb907f392a1877b671f472aed Mon Sep 17 00:00:00 2001 From: Torsten Curdt Date: Tue, 27 Feb 2018 14:14:01 +0100 Subject: [PATCH 20/28] show code at interpreter start, no special treatment in menu --- source/Interpreter.cpp | 18 ++++++++++++- source/Main.cpp | 27 +++++++++++++++++++ source/Menu.cpp | 60 +++++++++++------------------------------- 3 files changed, 60 insertions(+), 45 deletions(-) diff --git a/source/Interpreter.cpp b/source/Interpreter.cpp index 3a185c3..b162821 100644 --- a/source/Interpreter.cpp +++ b/source/Interpreter.cpp @@ -325,12 +325,26 @@ static void interpreter_on_gesture(MicroBitEvent event) // } // } +static bool nothingToRun() +{ + for(uint8_t i = 0; i < METHODS_COUNT; i++) { + uint16_t method = interpreter.methods[i]; + if (method != METHOD_UNUSED) { + return false; + } + } + return true; +} + static void interpreter_fiber() { LOG("interpreter\n\r"); + while(nothingToRun()) { + uBit.sleep(100); + } + while(true) { - interpreter_startup_sound(); interpreter_reset_hardware(); LOG("start\n\r"); @@ -353,6 +367,8 @@ static void interpreter_fiber() interpreter.status = INTERPRETER_OK; LOG("reset\n\r"); + + interpreter_startup_sound(); } } diff --git a/source/Main.cpp b/source/Main.cpp index c481895..64f3bcf 100644 --- a/source/Main.cpp +++ b/source/Main.cpp @@ -9,9 +9,35 @@ #include "RunMultiplication.h" #include "RunVolumeMeter.h" #include "Interpreter.h" +#include "nrf.h" MicroBit uBit; +static void showNameHistogram(MicroBitDisplay &display) +{ + NRF_FICR_Type *ficr = NRF_FICR; + uint32_t n = ficr->DEVICEID[1]; + uint32_t ld = 1; + uint32_t d = MICROBIT_DFU_HISTOGRAM_HEIGHT; + uint32_t h; + + display.clear(); + for (uint32_t i = 0; i < MICROBIT_DFU_HISTOGRAM_WIDTH; i++) + { + h = (n % d) / ld; + + n -= h; + d *= MICROBIT_DFU_HISTOGRAM_HEIGHT; + ld *= MICROBIT_DFU_HISTOGRAM_HEIGHT; + + for (uint32_t j = 0; j < h + 1; j++) + display.image.setPixelValue( + static_cast(MICROBIT_DFU_HISTOGRAM_WIDTH - i - 1), + static_cast(MICROBIT_DFU_HISTOGRAM_HEIGHT - j - 1), + 255); + } +} + static inline void waitForever() { while (true) { @@ -54,6 +80,7 @@ int main() // minimize serial buffer uBit.serial.setTxBufferSize(0); + showNameHistogram(uBit.display); interpreter_run(); // not required - just to make it obvious this does not return diff --git a/source/Menu.cpp b/source/Menu.cpp index ef1311c..95c81bd 100644 --- a/source/Menu.cpp +++ b/source/Menu.cpp @@ -1,58 +1,30 @@ #include "Menu.h" #include "MicroBit.h" -#include "nrf.h" extern MicroBit uBit; -static void showNameHistogram(MicroBitDisplay &display) -{ - NRF_FICR_Type *ficr = NRF_FICR; - uint32_t n = ficr->DEVICEID[1]; - uint32_t ld = 1; - uint32_t d = MICROBIT_DFU_HISTOGRAM_HEIGHT; - uint32_t h; - - display.clear(); - for (uint32_t i = 0; i < MICROBIT_DFU_HISTOGRAM_WIDTH; i++) - { - h = (n % d) / ld; - - n -= h; - d *= MICROBIT_DFU_HISTOGRAM_HEIGHT; - ld *= MICROBIT_DFU_HISTOGRAM_HEIGHT; - - for (uint32_t j = 0; j < h + 1; j++) - display.image.setPixelValue( - static_cast(MICROBIT_DFU_HISTOGRAM_WIDTH - i - 1), - static_cast(MICROBIT_DFU_HISTOGRAM_HEIGHT - j - 1), - 255); - } -} - menustate_t menuWaitForChoice(menustate_t start) { menustate_t state = start; while (true) { - if (state == MenuStateInterpreter) { - showNameHistogram(uBit.display); - - // static const uint8_t pixels[25] = { - // 0, 0, 1, 1, 1, - // 0, 0, 0, 1, 1, - // 0, 0, 1, 0, 1, - // 0, 1, 0, 0, 0, - // 1, 0, 0, 0, 0 - // }; - // const MicroBitImage Image(5, 5, pixels); - - // uBit.display.print(Image); - - } else { - - uBit.display.print(ManagedString(state)); - } + // if (state == MenuStateInterpreter) { + // showNameHistogram(uBit.display); + // // static const uint8_t pixels[25] = { + // // 0, 0, 1, 1, 1, + // // 0, 0, 0, 1, 1, + // // 0, 0, 1, 0, 1, + // // 0, 1, 0, 0, 0, + // // 1, 0, 0, 0, 0 + // // }; + // // const MicroBitImage Image(5, 5, pixels); + // // uBit.display.print(Image); + // } else { + // uBit.display.print(ManagedString(state)); + // } + + uBit.display.print(ManagedString(state)); // event loop while (true) { From 239d94019af5af245d233215d9173a45c52fbe4d Mon Sep 17 00:00:00 2001 From: Torsten Curdt Date: Tue, 27 Feb 2018 14:18:57 +0100 Subject: [PATCH 21/28] cleanup sync --- contrib/copy.sh | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/contrib/copy.sh b/contrib/copy.sh index 3f0ca6c..c83ba88 100755 --- a/contrib/copy.sh +++ b/contrib/copy.sh @@ -3,11 +3,5 @@ SRC=../../calliope_playbook_mini/source/ DST=`pwd`/source/ -rsync -rtuv --progress $SRC $DST --exclude Main.* -# rsync -rtuv --progress $DST $SRC --exclude Main.* --exclude Run*.* --exclude Localization.* --exclude Utils*.* --exclude Menu.* --exclude Storage.* - -SRC=../../calliope_playbook_mini/contrib/ -DST=`pwd`/contrib/ - -# rsync -rtuv --progress $SRC $DST -# rsync -n -rtuv --progress $DST $SRC +rsync -rtuv --progress $SRC $DST \ + --exclude Main.* From 4c091013f1146439dc82bba59018be60acd0cea5 Mon Sep 17 00:00:00 2001 From: wowa Date: Wed, 16 May 2018 15:30:22 +0200 Subject: [PATCH 22/28] modified stack size to make it work --- config.json | 32 +++++++++++++++++----- contrib/memsum.sh | 2 +- module.json | 4 +-- source/BluetoothServiceDebug.cpp | 1 - source/BluetoothServiceDebug.h | 22 +++++++++++++++- source/BluetoothServiceNotify.cpp | 1 - source/BluetoothServiceNotify.h | 44 +++++++++++++++++++++++-------- source/BluetoothServiceProgram.h | 41 ++++++++++++++++++++-------- source/Bytes.h | 6 ++++- source/Images.cpp | 1 - source/Images.h | 6 ++++- source/Instruction.h | 5 +++- source/Interpreter.cpp | 1 - source/Interpreter.h | 6 ++++- source/Localization.h | 5 +++- source/Menu.h | 5 +++- source/RunDemo.h | 7 +++-- 17 files changed, 144 insertions(+), 45 deletions(-) mode change 100644 => 100755 contrib/memsum.sh diff --git a/config.json b/config.json index 128e15e..a3d227d 100644 --- a/config.json +++ b/config.json @@ -4,17 +4,35 @@ "enabled": 1, "pairing_mode": 1, "private_addressing": 0, - "open": 1, + "open": 0, + "security_level": "SECURITY_MODE_ENCRYPTION_NO_MITM", "whitelist": 1, "advertising_timeout": 0, - "tx_power": 6, + "tx_power": 7, "dfu_service": 1, - "event_service": 0, - "device_info_service": 1, - "security_level": "SECURITY_MODE_ENCRYPTION_NO_MITM" + "event_service": 1, + "device_info_service": 1 }, - "gatt_table_size": "0x400", + "gatt_table_size": "0x600", "debug": 0, - "heap_debug": 0 + "reuse_sd": 0, + "heap_debug": 0, + "default_pullmode": "PullDown", + "heap_allocator": 1, + "nested_heap_proportion": 0.75, + "system_tick_period": 6, + "system_components": 10, + "idle_components": 6, + "use_accel_lsb": 0, + "min_display_brightness": 1, + "max_display_brightness": 255, + "display_scroll_speed": 120, + "display_scroll_stride": -1, + "display_print_speed": 400, + "panic_on_heap_full": 1, + "stack_size": 3072, + "sram_base": "0x20000008", + "sram_end": "0x20004000", + "sd_limit": "0x20002800" } } diff --git a/contrib/memsum.sh b/contrib/memsum.sh old mode 100644 new mode 100755 index 1d972ea..73a470d --- a/contrib/memsum.sh +++ b/contrib/memsum.sh @@ -2,6 +2,6 @@ #!/bin/sh ROOT="$( cd "$(dirname "$0")" ; pwd -P )" -DEVICE=/dev/cu.usbmodem1422 +DEVICE=/dev/ttyACM0 ( stty speed 115200 cs8 1>/dev/null 2>&1; python2 $ROOT/memsum.py Calliope) <$DEVICE diff --git a/module.json b/module.json index 291eb96..bc086c4 100644 --- a/module.json +++ b/module.json @@ -4,8 +4,8 @@ "description": "Calliope mini Demo", "license": "Apache 2.0", "dependencies": { - "microbit": "calliope-mini/microbit#v2.0.0-rc8-calliope-1.0.2" + "microbit": "calliope-mini/microbit#v2.0.0-calliope-1.0.5" }, "targetDependencies": {}, "bin": "./source" -} +} \ No newline at end of file diff --git a/source/BluetoothServiceDebug.cpp b/source/BluetoothServiceDebug.cpp index 2fc3c2e..a254b1a 100644 --- a/source/BluetoothServiceDebug.cpp +++ b/source/BluetoothServiceDebug.cpp @@ -1,6 +1,5 @@ #include "BluetoothServiceDebug.h" #include "MicroBit.h" -//#include "ble/UUID.h" #include "Bytes.h" extern MicroBit uBit; diff --git a/source/BluetoothServiceDebug.h b/source/BluetoothServiceDebug.h index 38d0200..7234e5e 100644 --- a/source/BluetoothServiceDebug.h +++ b/source/BluetoothServiceDebug.h @@ -1,12 +1,30 @@ -#pragma once +#ifndef BLUETOOTH_SERVICE_DEBUG_H +#define BLUETOOTH_SERVICE_DEBUG_H + #include "Interpreter.h" #include "ble/BLE.h" +/*! + * @class BluetoothServiceDebug + * + */ class BluetoothServiceDebug { public: + /*! + * Constructor. + * Create a representation of BluetoothServiceDebug + * @param interpreter Reference to an Interpreter + */ BluetoothServiceDebug(Interpreter& interpreter); + /*! + * Callback. Invoked when any of our attributes are written via BLE. + */ void onDataWritten(const GattWriteCallbackParams* params); + + /*! + * Callback. Invoked when any of our attributes are read via BLE. + */ void onDataRead(GattReadAuthCallbackParams* params); private: @@ -20,3 +38,5 @@ class BluetoothServiceDebug { uint8_t selector; uint16_t address; }; + +#endif //BLUETOOTH_SERVICE_DEBUG_H \ No newline at end of file diff --git a/source/BluetoothServiceNotify.cpp b/source/BluetoothServiceNotify.cpp index ff27017..2e7b02c 100644 --- a/source/BluetoothServiceNotify.cpp +++ b/source/BluetoothServiceNotify.cpp @@ -1,6 +1,5 @@ #include "BluetoothServiceNotify.h" #include "MicroBit.h" -//#include "ble/UUID.h" #include "Bytes.h" extern MicroBit uBit; diff --git a/source/BluetoothServiceNotify.h b/source/BluetoothServiceNotify.h index 8708c95..2ba2e47 100644 --- a/source/BluetoothServiceNotify.h +++ b/source/BluetoothServiceNotify.h @@ -1,22 +1,44 @@ -#pragma once + +#ifndef BLUETOOTH_SERVICE_NOTIFY_H +#define BLUETOOTH_SERVICE_NOTIFY_H + #include "ble/BLE.h" #include "Interpreter.h" +/*! + * @class BluetoothServiceNotify + */ class BluetoothServiceNotify { - public: +public: - BluetoothServiceNotify(Interpreter &interpreter); + /*! + * Constructor. + * Create a representation of BluetoothServiceNotify + * @param interpreter Reference to an Interpreter instance + */ + BluetoothServiceNotify(Interpreter &interpreter); - void onDataRead(GattReadAuthCallbackParams *params); - void send(uint16_t address, uint16_t value); + /*! + * Callback. Invoked when any of our attributes are read via BLE. + */ + void onDataRead(GattReadAuthCallbackParams *params); - private: + /*! + * Send data via BLE. + * @param address + * @param value + */ + void send(uint16_t address, uint16_t value); - Interpreter &interpreter; - BLEDevice &ble; +private: - GattAttribute::Handle_t characteristicsHandle; - GattCharacteristic characteristic; - uint8_t characteristicsBuffer[CHARACTERISTICS_BUFFER_LEN]; + Interpreter &interpreter; + BLEDevice &ble; + + GattAttribute::Handle_t characteristicsHandle; + GattCharacteristic characteristic; + uint8_t characteristicsBuffer[CHARACTERISTICS_BUFFER_LEN]; }; + +#endif // BLUETOOTH_SERVICE_NOTIFY_H \ No newline at end of file diff --git a/source/BluetoothServiceProgram.h b/source/BluetoothServiceProgram.h index 86a93e7..7522188 100644 --- a/source/BluetoothServiceProgram.h +++ b/source/BluetoothServiceProgram.h @@ -1,22 +1,41 @@ -#pragma once +#ifndef BLUETOOTH_SERVICE_PROGRAM_H +#define BLUETOOTH_SERVICE_PROGRAM_H + #include "ble/BLE.h" #include "Interpreter.h" +/*! + * @class BluetoothServiceProgram + */ class BluetoothServiceProgram { - public: +public: + + /*! + * Constructor. + * Create a representation of BluetoothServiceProgram + * @param interpreter + */ + BluetoothServiceProgram(Interpreter &interpreter); - BluetoothServiceProgram(Interpreter &interpreter); + /*! + * Callback. Invoked when any of our attributes are written via BLE. + */ + void onDataWritten(const GattWriteCallbackParams *params); - void onDataWritten(const GattWriteCallbackParams *params); - void onDataRead(GattReadAuthCallbackParams *params); + /*! + * Callback. Invoked when any of our attributes are read via BLE. + */ + void onDataRead(GattReadAuthCallbackParams *params); - private: +private: - Interpreter &interpreter; - BLEDevice &ble; + Interpreter &interpreter; + BLEDevice &ble; - GattAttribute::Handle_t characteristicsHandle; - GattCharacteristic characteristic; - uint8_t characteristicsBuffer[CHARACTERISTICS_BUFFER_LEN]; + GattAttribute::Handle_t characteristicsHandle; + GattCharacteristic characteristic; + uint8_t characteristicsBuffer[CHARACTERISTICS_BUFFER_LEN]; }; + +#endif // BLUETOOTH_SERVICE_PROGRAM_H \ No newline at end of file diff --git a/source/Bytes.h b/source/Bytes.h index 6951eb1..0f3faa6 100644 --- a/source/Bytes.h +++ b/source/Bytes.h @@ -1,6 +1,10 @@ -#pragma once +#ifndef BYTES_H +#define BYTES_H + #include #define HI16(i) static_cast(((i)>>8)&0xff) #define LO16(i) static_cast((i)&0xff) #define BYTES_TO_UINT16(hi,lo) static_cast(((hi)<<8)|(lo)) + +#endif // BYTES_H \ No newline at end of file diff --git a/source/Images.cpp b/source/Images.cpp index 793debb..90e2506 100644 --- a/source/Images.cpp +++ b/source/Images.cpp @@ -1,5 +1,4 @@ #include "Images.h" -#include static const uint8_t pixel_full[25] = { 1, 1, 1, 1, 1, diff --git a/source/Images.h b/source/Images.h index 3685848..a054fb7 100644 --- a/source/Images.h +++ b/source/Images.h @@ -1,4 +1,6 @@ -#pragma once +#ifndef IMAGES_H +#define IMAGES_H + #include "MicroBitImage.h" extern const MicroBitImage *images[17]; @@ -20,3 +22,5 @@ extern const MicroBitImage ImageScissors; extern const MicroBitImage ImageWell; extern const MicroBitImage ImageFlash; extern const MicroBitImage ImageWave; + +#endif // IMAGES_H \ No newline at end of file diff --git a/source/Instruction.h b/source/Instruction.h index 32afd4e..e5e0ce6 100644 --- a/source/Instruction.h +++ b/source/Instruction.h @@ -1,4 +1,5 @@ -#pragma once +#ifndef INSTRUCTION_H +#define INSTRUCTION_H #include "Slice.h" #include "Interpreter.h" @@ -51,3 +52,5 @@ void instruction_roll(Slice &code, Interpreter &interpreter, RunState &state); void instruction_position(Slice &code, Interpreter &interpreter, RunState &state); void instruction_notify(Slice &code, Interpreter &interpreter, RunState &state); void instruction_debug(Slice &code, Interpreter &interpreter, RunState &state); + +#endif // INSTRUCTION_H \ No newline at end of file diff --git a/source/Interpreter.cpp b/source/Interpreter.cpp index b162821..d545767 100644 --- a/source/Interpreter.cpp +++ b/source/Interpreter.cpp @@ -1,6 +1,5 @@ #include "Interpreter.h" #include "MicroBit.h" -//#include "BluetoothServiceDebug.h" #include "BluetoothServiceProgram.h" #include "BluetoothServiceNotify.h" #include "Instruction.h" diff --git a/source/Interpreter.h b/source/Interpreter.h index 9cc0285..f3e27eb 100644 --- a/source/Interpreter.h +++ b/source/Interpreter.h @@ -1,4 +1,6 @@ -#pragma once +#ifndef INTERPRETER_H +#define INTERPRETER_H + #include #define VERSION_MAJOR 0 @@ -132,3 +134,5 @@ void interpreter_run(); void interpreter_start(); void interpreter_reset(); uint16_t interpreter_calculate_hash(); + +#endif // INTERPRETER_H \ No newline at end of file diff --git a/source/Localization.h b/source/Localization.h index ec099fc..88f4060 100644 --- a/source/Localization.h +++ b/source/Localization.h @@ -1,4 +1,5 @@ -#pragma once +#ifndef LOCALIZATION_H +#define LOCALIZATION_H #define LS_DEMO_HELLO "Hi!" #define LS_DEMO_BUTTON_A "A" @@ -6,3 +7,5 @@ #define LS_DEMO_BUTTON_AB "A+B" //#define LS_DEMO_SHAKE "SCHUETTELN" #define LS_DEMO_GREAT "OK!" + +#endif // LOCALIZATION_H \ No newline at end of file diff --git a/source/Menu.h b/source/Menu.h index 516638c..cfa3b0e 100644 --- a/source/Menu.h +++ b/source/Menu.h @@ -1,4 +1,5 @@ -#pragma once +#ifndef MENU_H +#define MENU_H typedef enum MenuState { MenuStateOracle = 1, @@ -11,3 +12,5 @@ typedef enum MenuState { } menustate_t; menustate_t menuWaitForChoice(menustate_t start); + +#endif // MENU_H \ No newline at end of file diff --git a/source/RunDemo.h b/source/RunDemo.h index 7eca6d5..ff533fc 100644 --- a/source/RunDemo.h +++ b/source/RunDemo.h @@ -1,3 +1,6 @@ -#pragma once +#ifndef DEMO_H +#define DEMO_H -void demo_run(); \ No newline at end of file +void demo_run(); + +#endif // DEMO_H \ No newline at end of file From 88630e4f9deeaa7b663f20b5bc01a73994b16c6a Mon Sep 17 00:00:00 2001 From: wowa Date: Fri, 18 May 2018 17:33:31 +0200 Subject: [PATCH 23/28] modified stack size to make it work --- .yotta_ignore | 2 ++ README-STACK.md | 61 +++++++++++++++++++++++++++++++++++ config.json | 10 +++--- source/Main.cpp | 24 +++++++------- source/RunLoveMeter.h | 7 ++-- source/RunMultiplication.h | 7 ++-- source/RunOracle.h | 7 ++-- source/RunRockPaperScissors.h | 5 ++- source/RunSnake.cpp | 2 +- source/RunSnake.h | 7 ++-- source/RunTests.cpp | 4 +-- source/RunTests.h | 7 ++-- source/RunVolumeMeter.h | 7 ++-- source/Slice.h | 2 +- source/Storage.h | 7 ++-- source/Utils.cpp | 4 +-- source/Utils.h | 4 ++- 17 files changed, 128 insertions(+), 39 deletions(-) create mode 100644 .yotta_ignore create mode 100644 README-STACK.md diff --git a/.yotta_ignore b/.yotta_ignore new file mode 100644 index 0000000..c8da81a --- /dev/null +++ b/.yotta_ignore @@ -0,0 +1,2 @@ +cmake-build-debug/* +CMakeLists.txt diff --git a/README-STACK.md b/README-STACK.md new file mode 100644 index 0000000..6a8641f --- /dev/null +++ b/README-STACK.md @@ -0,0 +1,61 @@ +#How to configure the Stack and heap + +The Stack and the heap are configured in 2 different ways. + +## 1: Standard memory configuration +The basic file is [startup_NRF51822.S](yotta_modules/mbed-classic/targets/cmsis/TARGET_NORDIC/TARGET_MCU_NRF51822/TOOLCHAIN_GCC_ARM/startup_NRF51822.S), +which should not be modified, if you do not exactly know what to do. + +However in this file there are two defines, `__STACK_SIZE` and `__HEAP_SIZE` +which can be used to modify the stack and the heap from outside this function. + +To do so, the file [toolchain.cmake](yotta_targets/calliope-mini-classic-gcc/CMake/toolchain.cmake) +can be extended. Add `-D__STACK_SIZE=2632 -D__HEAP_SIZE=1464` at the end of `add_definitions("...` +and the stack will have the size of 2632 Bytes and the heap will have the size of 1464 Bytes. +**note: The size of Stack + Heap has to be 4096 Bytes or less** + +## 2: MicroBit custom heap configuration +Since the [microbit-dal](yotta_modules/microbit-dal) +has a custom heap allocator [MicroBitHeapAllocator.cpp](yotta_modules/microbit-dal/source/core/MicroBitHeapAllocator.cpp) +and [MicroBitHeapAllocator.h](yotta_modules/microbit-dal/inc/core/MicroBitHeapAllocator.h), +which is configured from [config.json](config.json), this file has to be modified to fit the standard configuration, +by adding + +```[bash] +"microbit-dal": { + ... + "nested_heap_proportion": 0.6, + "stack_size": 2632, + ... + } +``` + +### 2.1: Calculation of the custom heap configuration +(this chapter is based on my findings and has to be approved by the people who made coded the microbit-dal) + +Currently the custom heap assumes that Heap + Stack = 4672 Bytes. +Unfortunatelly this seems to be not the case. + +Running the [memsum.py](contrib/memsum.py) script with debug and hepa-debug enabled, +it shows that the custom heap starts from `0x200030F0` and from [MicroBitConfig.h](yotta_modules/microbit-dal/inc/core/MicroBitConfig.h) +we know that the Stack ends at `0x20004000` which is the upper bound of the RAM. + +This means the real space for Heap + Stack is 3856 Bytes. + +During testing, I found out, that whenever the Heap goes out of bounds, the controller crashes. +Also the overlapping of the stack and the Heap region brings the controller to crash sometimes. + +The calculation follows: + +`heap_size = (4672 - stack_size) * nested_heap_proportion` + +However with the given knowledge the calculation should be: +`nested_heap_proportion' = (stack_size - 3856) / (stack_size - 4672)` +in which case the stack and the nested heap will not overlap. + + +## Further remarks +The option `"reuse_sd": 0` has to be 0 if BLE is used, otherwise heap will be allocated in the Softdevice RAM region, +for BLE nad thus this region will be overriden by the Softdevice and caus the controller to crash. + + diff --git a/config.json b/config.json index a3d227d..2e6f31e 100644 --- a/config.json +++ b/config.json @@ -15,11 +15,11 @@ }, "gatt_table_size": "0x600", "debug": 0, - "reuse_sd": 0, "heap_debug": 0, + "reuse_sd": 0, "default_pullmode": "PullDown", "heap_allocator": 1, - "nested_heap_proportion": 0.75, + "nested_heap_proportion": 0.6, "system_tick_period": 6, "system_components": 10, "idle_components": 6, @@ -29,10 +29,10 @@ "display_scroll_speed": 120, "display_scroll_stride": -1, "display_print_speed": 400, - "panic_on_heap_full": 1, - "stack_size": 3072, + "panic_on_heap_full": 0, + "stack_size": 2632, "sram_base": "0x20000008", "sram_end": "0x20004000", - "sd_limit": "0x20002800" + "sd_limit": "0x20002000" } } diff --git a/source/Main.cpp b/source/Main.cpp index 64f3bcf..a8b9efd 100644 --- a/source/Main.cpp +++ b/source/Main.cpp @@ -110,27 +110,27 @@ int main() switch (state) { // 1 case MenuStateOracle: - menuAnimateEnter(); - oracle_run(); - menuAnimateLeave(); +// menuAnimateEnter(); +// oracle_run(); +// menuAnimateLeave(); break; // 2 case MenuStateRockPaperScissors: - menuAnimateEnter(); - rockpaperscissors_run(); - menuAnimateLeave(); +// menuAnimateEnter(); +// rockpaperscissors_run(); +// menuAnimateLeave(); break; // 3 case MenuStateMultiplication: - menuAnimateEnter(); - multiplication_run(); - menuAnimateLeave(); +// menuAnimateEnter(); +// multiplication_run(); +// menuAnimateLeave(); break; // 4 case MenuStateVolumeMeter: - menuAnimateEnter(); - volumemeter_run(); - menuAnimateLeave(); +// menuAnimateEnter(); +// volumemeter_run(); +// menuAnimateLeave(); break; // 5 case MenuStateInterpreter: diff --git a/source/RunLoveMeter.h b/source/RunLoveMeter.h index 1e177b4..a049003 100644 --- a/source/RunLoveMeter.h +++ b/source/RunLoveMeter.h @@ -1,3 +1,6 @@ -#pragma once +#ifndef RUN_LOVE_METER_H +#define RUN_LOVE_METER_H -void lovemeter_run(); \ No newline at end of file +void lovemeter_run(); + +#endif // RUN_LOVE_METER_H \ No newline at end of file diff --git a/source/RunMultiplication.h b/source/RunMultiplication.h index 8173225..9820f7d 100644 --- a/source/RunMultiplication.h +++ b/source/RunMultiplication.h @@ -1,3 +1,6 @@ -#pragma once +#ifndef RUN_MULTIPLICATION_H +#define RUN_MULTIPLICATION_H -void multiplication_run(); \ No newline at end of file +void multiplication_run(); + +#endif // RUN_MULTIPLICATION_H \ No newline at end of file diff --git a/source/RunOracle.h b/source/RunOracle.h index 0648841..92f7dbb 100644 --- a/source/RunOracle.h +++ b/source/RunOracle.h @@ -1,3 +1,6 @@ -#pragma once +#ifndef RUN_ORACLE_H +#define RUN_ORACLE_H -void oracle_run(); \ No newline at end of file +void oracle_run(); + +#endif // RUN_ORACLE_H \ No newline at end of file diff --git a/source/RunRockPaperScissors.h b/source/RunRockPaperScissors.h index 36a7fed..a2d147c 100644 --- a/source/RunRockPaperScissors.h +++ b/source/RunRockPaperScissors.h @@ -1,3 +1,6 @@ -#pragma once +#ifndef RUN_ROCK_PAPER_SCISSORS_H +#define RUN_ROCK_PAPER_SCISSORS_H void rockpaperscissors_run(); + +#endif // RUN_ROCK_PAPER_SCISSORS_H \ No newline at end of file diff --git a/source/RunSnake.cpp b/source/RunSnake.cpp index 8f5d12f..bf1568a 100644 --- a/source/RunSnake.cpp +++ b/source/RunSnake.cpp @@ -1,6 +1,6 @@ #include "RunSnake.h" #include "MicroBit.h" -//#include "Images.h" +#include "Images.h" #include "Utils.h" extern MicroBit uBit; diff --git a/source/RunSnake.h b/source/RunSnake.h index 4670149..e56695a 100644 --- a/source/RunSnake.h +++ b/source/RunSnake.h @@ -1,3 +1,6 @@ -#pragma once +#ifndef RUN_SNAKE_H +#define RUN_SNAKE_H -void snake_run(); \ No newline at end of file +void snake_run(); + +#endif // RUN_SNAKE_H \ No newline at end of file diff --git a/source/RunTests.cpp b/source/RunTests.cpp index 51d24fe..a8cd072 100644 --- a/source/RunTests.cpp +++ b/source/RunTests.cpp @@ -1,9 +1,9 @@ #include #include "RunTests.h" #include "MicroBit.h" -//#include "MicroBitSerial.h" +#include "MicroBitSerial.h" #include "Images.h" -//#include "Utils.h" +#include "Utils.h" extern MicroBit uBit; diff --git a/source/RunTests.h b/source/RunTests.h index 6467d02..9b41379 100644 --- a/source/RunTests.h +++ b/source/RunTests.h @@ -1,3 +1,6 @@ -#pragma once +#ifndef RUN_TESTS_H +#define RUN_TESTS_H -void tests_run(); \ No newline at end of file +void tests_run(); + +#endif // RUN_TESTS_H \ No newline at end of file diff --git a/source/RunVolumeMeter.h b/source/RunVolumeMeter.h index 1d2dd78..276e5fe 100644 --- a/source/RunVolumeMeter.h +++ b/source/RunVolumeMeter.h @@ -1,3 +1,6 @@ -#pragma once +#ifndef RUN_VOLUME_METER_H +#define RUN_VOLUME_METER_H -void volumemeter_run(); \ No newline at end of file +void volumemeter_run(); + +#endif // RUN_VOLUME_METER_H \ No newline at end of file diff --git a/source/Slice.h b/source/Slice.h index bad5c81..2b2be62 100644 --- a/source/Slice.h +++ b/source/Slice.h @@ -15,4 +15,4 @@ uint16_t slice_available(Slice &slice); uint8_t slice_read8(Slice &slice); uint16_t slice_read16(Slice &slice); -#endif +#endif // SLICE_H diff --git a/source/Storage.h b/source/Storage.h index 2b634a9..675a578 100644 --- a/source/Storage.h +++ b/source/Storage.h @@ -1,4 +1,5 @@ -#pragma once +#ifndef STORAGE_H +#define STORAGE_H #define KEY_TEST "initial" #define KEY_DEMO "demo" @@ -25,4 +26,6 @@ inline void setStorageKey(const char* name, uint8_t value = 1) inline void removeStorageKey(const char* name) { uBit.storage.remove(name); -} \ No newline at end of file +} + +#endif // STORAGE_H \ No newline at end of file diff --git a/source/Utils.cpp b/source/Utils.cpp index b539bc1..a331d1f 100644 --- a/source/Utils.cpp +++ b/source/Utils.cpp @@ -1,6 +1,6 @@ #include "Utils.h" -//#include "MicroBit.h" -//#include "MicroBitImage.h" +#include "MicroBit.h" +#include "MicroBitImage.h" extern MicroBit uBit; diff --git a/source/Utils.h b/source/Utils.h index 0d5085b..e18c2c7 100644 --- a/source/Utils.h +++ b/source/Utils.h @@ -1,4 +1,5 @@ -#pragma once +#ifndef UTILS_H +#define UTILS_H #include "MicroBit.h" @@ -21,3 +22,4 @@ void blinkImageUntilEvent( const int pos2 = 0, const uint16_t delay = 200); +#endif // UTILS_H \ No newline at end of file From 2e6136a488335b486a9f2cdbfec5f1ad0b5dd8a5 Mon Sep 17 00:00:00 2001 From: wowa Date: Tue, 22 May 2018 14:30:59 +0200 Subject: [PATCH 24/28] added defines.json for dynamic stak / heap configuration, also extended the README-STACK.md --- README-STACK.md | 19 ++++++++++++++++--- config.json | 2 +- defines.json | 4 ++++ 3 files changed, 21 insertions(+), 4 deletions(-) create mode 100644 defines.json diff --git a/README-STACK.md b/README-STACK.md index 6a8641f..63c693d 100644 --- a/README-STACK.md +++ b/README-STACK.md @@ -9,10 +9,23 @@ which should not be modified, if you do not exactly know what to do. However in this file there are two defines, `__STACK_SIZE` and `__HEAP_SIZE` which can be used to modify the stack and the heap from outside this function. -To do so, the file [toolchain.cmake](yotta_targets/calliope-mini-classic-gcc/CMake/toolchain.cmake) -can be extended. Add `-D__STACK_SIZE=2632 -D__HEAP_SIZE=1464` at the end of `add_definitions("...` +### 1.1: Modifying toolchain.cmake +One option to do so, is to extend the file [toolchain.cmake](yotta_targets/calliope-mini-classic-gcc/CMake/toolchain.cmake). Add `-D__STACK_SIZE=2632 -D__HEAP_SIZE=1464` at the end of `add_definitions("...` and the stack will have the size of 2632 Bytes and the heap will have the size of 1464 Bytes. -**note: The size of Stack + Heap has to be 4096 Bytes or less** + +### 1.2: Adding defines.json +The alternative option is to add a [defines.json](defines.json) file to the same directory, where [module.json](module.json) is located. +Therein macro definitions can be added for the application. In this case the file would look like this: +```[bash] +{ + "__STACK_SIZE": 2632, + "__HEAP_SIZE": 1464 +} +``` +The advantage of this option is, that you do not have to modify any dependencies, but can add extra definitions to the application. +The disadvantage is, that these definitions will apply to all application code, which can lead multiple definitions. + +**NOTE: The size of Stack + Heap has to be 4096 Bytes or less** ## 2: MicroBit custom heap configuration Since the [microbit-dal](yotta_modules/microbit-dal) diff --git a/config.json b/config.json index 2e6f31e..436b673 100644 --- a/config.json +++ b/config.json @@ -10,7 +10,7 @@ "advertising_timeout": 0, "tx_power": 7, "dfu_service": 1, - "event_service": 1, + "event_service": 0, "device_info_service": 1 }, "gatt_table_size": "0x600", diff --git a/defines.json b/defines.json new file mode 100644 index 0000000..48a4d0d --- /dev/null +++ b/defines.json @@ -0,0 +1,4 @@ +{ + "__STACK_SIZE": 2632, + "__HEAP_SIZE": 1464 +} From 2cd1b6a852f85e0f9912a70ebf611741dcef93c3 Mon Sep 17 00:00:00 2001 From: wowa Date: Wed, 23 May 2018 18:00:12 +0200 Subject: [PATCH 25/28] interpreter ohne pairing der rest mit pairing --- config.json | 2 +- source/BluetoothServiceNotify.cpp | 2 +- source/BluetoothServiceProgram.cpp | 2 +- source/Main.cpp | 24 ++++++++++++------------ 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/config.json b/config.json index 436b673..acff7c0 100644 --- a/config.json +++ b/config.json @@ -6,7 +6,7 @@ "private_addressing": 0, "open": 0, "security_level": "SECURITY_MODE_ENCRYPTION_NO_MITM", - "whitelist": 1, + "whitelist": 0, "advertising_timeout": 0, "tx_power": 7, "dfu_service": 1, diff --git a/source/BluetoothServiceNotify.cpp b/source/BluetoothServiceNotify.cpp index 2e7b02c..4ca60ca 100644 --- a/source/BluetoothServiceNotify.cpp +++ b/source/BluetoothServiceNotify.cpp @@ -24,7 +24,7 @@ BluetoothServiceNotify::BluetoothServiceNotify(Interpreter &_interpreter) : ), characteristicsBuffer() { - characteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL); + characteristic.requireSecurity(SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK);//MICROBIT_BLE_SECURITY_LEVEL); characteristic.setReadAuthorizationCallback(this, &BluetoothServiceNotify::onDataRead); GattCharacteristic *characteristics[] = { diff --git a/source/BluetoothServiceProgram.cpp b/source/BluetoothServiceProgram.cpp index 7bff9d2..ee2ed95 100644 --- a/source/BluetoothServiceProgram.cpp +++ b/source/BluetoothServiceProgram.cpp @@ -25,7 +25,7 @@ BluetoothServiceProgram::BluetoothServiceProgram(Interpreter &_interpreter) : ), characteristicsBuffer() { - characteristic.requireSecurity(SecurityManager::MICROBIT_BLE_SECURITY_LEVEL); + characteristic.requireSecurity(SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK);//MICROBIT_BLE_SECURITY_LEVEL); characteristic.setReadAuthorizationCallback(this, &BluetoothServiceProgram::onDataRead); GattCharacteristic *characteristics[] = { diff --git a/source/Main.cpp b/source/Main.cpp index a8b9efd..b18a56a 100644 --- a/source/Main.cpp +++ b/source/Main.cpp @@ -110,27 +110,27 @@ int main() switch (state) { // 1 case MenuStateOracle: -// menuAnimateEnter(); -// oracle_run(); -// menuAnimateLeave(); + menuAnimateEnter(); + oracle_run(); + menuAnimateLeave(); break; // 2 case MenuStateRockPaperScissors: -// menuAnimateEnter(); -// rockpaperscissors_run(); -// menuAnimateLeave(); + menuAnimateEnter(); + rockpaperscissors_run(); + menuAnimateLeave(); break; // 3 case MenuStateMultiplication: -// menuAnimateEnter(); -// multiplication_run(); -// menuAnimateLeave(); + menuAnimateEnter(); + multiplication_run(); + menuAnimateLeave(); break; // 4 case MenuStateVolumeMeter: -// menuAnimateEnter(); -// volumemeter_run(); -// menuAnimateLeave(); + menuAnimateEnter(); + volumemeter_run(); + menuAnimateLeave(); break; // 5 case MenuStateInterpreter: From ade3b036ce41866de821193186f6280ea88a02f7 Mon Sep 17 00:00:00 2001 From: wowa Date: Tue, 29 May 2018 14:39:20 +0200 Subject: [PATCH 26/28] maximum possible stack heap sizes --- config.json | 6 ++--- defines.json | 4 ++-- source/BluetoothServiceNotify.cpp | 35 +++++++++++++++++++++++++++++- source/BluetoothServiceNotify.h | 3 ++- source/BluetoothServiceProgram.cpp | 18 +++++++++------ source/BluetoothServiceProgram.h | 9 ++++++++ source/Interpreter.cpp | 2 +- source/Main.cpp | 2 +- 8 files changed, 63 insertions(+), 16 deletions(-) diff --git a/config.json b/config.json index acff7c0..28ec4ae 100644 --- a/config.json +++ b/config.json @@ -13,12 +13,12 @@ "event_service": 0, "device_info_service": 1 }, - "gatt_table_size": "0x600", + "gatt_table_size": "0x300", "debug": 0, "heap_debug": 0, "reuse_sd": 0, "default_pullmode": "PullDown", - "heap_allocator": 1, + "heap_allocator": 0, "nested_heap_proportion": 0.6, "system_tick_period": 6, "system_components": 10, @@ -30,7 +30,7 @@ "display_scroll_stride": -1, "display_print_speed": 400, "panic_on_heap_full": 0, - "stack_size": 2632, + "stack_size": 2672, "sram_base": "0x20000008", "sram_end": "0x20004000", "sd_limit": "0x20002000" diff --git a/defines.json b/defines.json index 48a4d0d..ba6701c 100644 --- a/defines.json +++ b/defines.json @@ -1,4 +1,4 @@ { - "__STACK_SIZE": 2632, - "__HEAP_SIZE": 1464 + "__STACK_SIZE": 2672, + "__HEAP_SIZE": 2672 } diff --git a/source/BluetoothServiceNotify.cpp b/source/BluetoothServiceNotify.cpp index 4ca60ca..0db089f 100644 --- a/source/BluetoothServiceNotify.cpp +++ b/source/BluetoothServiceNotify.cpp @@ -1,6 +1,8 @@ #include "BluetoothServiceNotify.h" #include "MicroBit.h" #include "Bytes.h" +#include "BluetoothServiceProgram.h" + extern MicroBit uBit; @@ -11,7 +13,7 @@ static const uint8_t BluetoothServiceNotifyUUID[] = { 0xa0,0x62, 0xfa,0x19,0x22,0xdf,0xa9,0xa8 }; - +extern const uint8_t BluetoothServiceProgramUUID[]; BluetoothServiceNotify::BluetoothServiceNotify(Interpreter &_interpreter) : interpreter(_interpreter), @@ -38,6 +40,37 @@ BluetoothServiceNotify::BluetoothServiceNotify(Interpreter &_interpreter) : ble.addService(service); + // TODO make this configuration dependent +#ifdef TARGET_NRF51_CALLIOPE + ManagedString namePrefix("Calliope mini ["); +#else + ManagedString namePrefix("BBC micro:bit ["); +#endif + ManagedString namePostfix("]"); + +// this->deviceName = microbit_friendly_name(); + ManagedString BLEName = namePrefix + microbit_friendly_name() + namePostfix; + + +// // Update the advertised name of this micro:bit to include the device name + ble.clearAdvertisingPayload(); + + ble.accumulateAdvertisingPayload( + GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); + ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *) BLEName.toCharArray(), + BLEName.length()); + + ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, BluetoothServiceNotifyUUID, + 16); + ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, BluetoothServiceProgramUUID, + 16); + + ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); + ble.setAdvertisingInterval(200); + + ble.setAdvertisingTimeout(0); + ble.startAdvertising(); + characteristicsHandle = characteristic.getValueHandle(); } diff --git a/source/BluetoothServiceNotify.h b/source/BluetoothServiceNotify.h index 2ba2e47..251f477 100644 --- a/source/BluetoothServiceNotify.h +++ b/source/BluetoothServiceNotify.h @@ -2,6 +2,7 @@ #ifndef BLUETOOTH_SERVICE_NOTIFY_H #define BLUETOOTH_SERVICE_NOTIFY_H +//#include "ManagedString.h" #include "ble/BLE.h" #include "Interpreter.h" @@ -38,7 +39,7 @@ class BluetoothServiceNotify GattAttribute::Handle_t characteristicsHandle; GattCharacteristic characteristic; - uint8_t characteristicsBuffer[CHARACTERISTICS_BUFFER_LEN]; + uint8_t characteristicsBuffer[16]; }; #endif // BLUETOOTH_SERVICE_NOTIFY_H \ No newline at end of file diff --git a/source/BluetoothServiceProgram.cpp b/source/BluetoothServiceProgram.cpp index ee2ed95..17a9fb4 100644 --- a/source/BluetoothServiceProgram.cpp +++ b/source/BluetoothServiceProgram.cpp @@ -5,13 +5,13 @@ extern MicroBit uBit; -static const uint8_t BluetoothServiceProgramUUID[] = { - 0xff,0x66,0xdd,0xee, - 0x25,0x1d, - 0x47,0x0a, - 0xa0,0x62, - 0xfa,0x19,0x22,0xdf,0xa9,0xa8 -}; +//static const uint8_t BluetoothServiceProgramUUID[] = { +// 0xff,0x66,0xdd,0xee, +// 0x25,0x1d, +// 0x47,0x0a, +// 0xa0,0x62, +// 0xfa,0x19,0x22,0xdf,0xa9,0xa8 +//}; BluetoothServiceProgram::BluetoothServiceProgram(Interpreter &_interpreter) : @@ -39,6 +39,10 @@ BluetoothServiceProgram::BluetoothServiceProgram(Interpreter &_interpreter) : ble.addService(service); +// ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, BluetoothServiceProgramUUID, 16); +// ble.gap().updateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, BluetoothServiceProgramUUID,16); + + characteristicsHandle = characteristic.getValueHandle(); ble.onDataWritten(this, &BluetoothServiceProgram::onDataWritten); diff --git a/source/BluetoothServiceProgram.h b/source/BluetoothServiceProgram.h index 7522188..2865b84 100644 --- a/source/BluetoothServiceProgram.h +++ b/source/BluetoothServiceProgram.h @@ -38,4 +38,13 @@ class BluetoothServiceProgram uint8_t characteristicsBuffer[CHARACTERISTICS_BUFFER_LEN]; }; + +const uint8_t BluetoothServiceProgramUUID[] = { + 0xff, 0x66, 0xdd, 0xee, + 0x25, 0x1d, + 0x47, 0x0a, + 0xa0, 0x62, + 0xfa, 0x19, 0x22, 0xdf, 0xa9, 0xa8 +}; + #endif // BLUETOOTH_SERVICE_PROGRAM_H \ No newline at end of file diff --git a/source/Interpreter.cpp b/source/Interpreter.cpp index d545767..1778c78 100644 --- a/source/Interpreter.cpp +++ b/source/Interpreter.cpp @@ -6,7 +6,7 @@ extern MicroBit uBit; -static Interpreter interpreter; +Interpreter interpreter; BluetoothServiceNotify *notify; static uint16_t find_stop(InterpreterMethod method) diff --git a/source/Main.cpp b/source/Main.cpp index b18a56a..8c374a4 100644 --- a/source/Main.cpp +++ b/source/Main.cpp @@ -78,7 +78,7 @@ int main() removeStorageKey(KEY_INTERPRETER); // minimize serial buffer - uBit.serial.setTxBufferSize(0); +// uBit.serial.setTxBufferSize(0); showNameHistogram(uBit.display); interpreter_run(); From 6952b3f287f2a4eaa96132a77fbec26f6538dd66 Mon Sep 17 00:00:00 2001 From: wowa Date: Fri, 1 Jun 2018 13:24:17 +0200 Subject: [PATCH 27/28] added discription to current settings in README-STACK.md --- README-STACK.md | 70 +++++++++++++++++++++++++++++- config.json | 4 +- defines.json | 4 +- source/BluetoothServiceNotify.cpp | 16 +++---- source/BluetoothServiceProgram.cpp | 9 ---- 5 files changed, 78 insertions(+), 25 deletions(-) diff --git a/README-STACK.md b/README-STACK.md index 63c693d..caebe80 100644 --- a/README-STACK.md +++ b/README-STACK.md @@ -13,7 +13,7 @@ which can be used to modify the stack and the heap from outside this function. One option to do so, is to extend the file [toolchain.cmake](yotta_targets/calliope-mini-classic-gcc/CMake/toolchain.cmake). Add `-D__STACK_SIZE=2632 -D__HEAP_SIZE=1464` at the end of `add_definitions("...` and the stack will have the size of 2632 Bytes and the heap will have the size of 1464 Bytes. -### 1.2: Adding defines.json +### 1.2: Adding defines.json The alternative option is to add a [defines.json](defines.json) file to the same directory, where [module.json](module.json) is located. Therein macro definitions can be added for the application. In this case the file would look like this: ```[bash] @@ -25,7 +25,73 @@ Therein macro definitions can be added for the application. In this case the fil The advantage of this option is, that you do not have to modify any dependencies, but can add extra definitions to the application. The disadvantage is, that these definitions will apply to all application code, which can lead multiple definitions. -**NOTE: The size of Stack + Heap has to be 4096 Bytes or less** +**NOTE: The size of Stack + Heap has to fit into the RAM** + +#### 1.2.1 How much space for Heap and Stack is in the RAM + +To find out how much space is in the RAM, you have to read the [calliope-demo.elf](build/calliope-mini-classic-gcc/source/calliope-demo) +file. Therefore enter the following command in the terminal: +```[bash] +$ readelf -S calliope-demo +``` +The output will look like this: +```[bash] +There are 22 section headers, starting at offset 0x326b10: + +Section Headers: + [Nr] Name Type Addr Off Size ES Flg Lk Inf Al + [ 0] NULL 00000000 000000 000000 00 0 0 0 + [ 1] .text PROGBITS 00018000 008000 016494 00 AX 0 0 8 + [ 2] .ARM.exidx ARM_EXIDX 0002e494 01e494 000008 00 AL 1 0 4 + [ 3] .data PROGBITS 20002000 022000 0000fc 00 WA 0 0 4 + [ 4] .bss NOBITS 20002100 022100 000a20 00 WA 0 0 8 + [ 5] .heap PROGBITS 20002b20 022100 000acc 00 0 0 8 + [ 6] .stack_dummy PROGBITS 20002b20 022bd0 000a00 00 0 0 8 + [ 7] .ARM.attributes ARM_ATTRIBUTES 00000000 0235d0 000028 00 0 0 1 + [ 8] .comment PROGBITS 00000000 0235f8 00007e 01 MS 0 0 1 + [ 9] .debug_info PROGBITS 00000000 023676 220d76 00 0 0 1 + [10] .debug_abbrev PROGBITS 00000000 2443ec 028b2e 00 0 0 1 + [11] .debug_loc PROGBITS 00000000 26cf1a 02800e 00 0 0 1 + [12] .debug_aranges PROGBITS 00000000 294f28 003268 00 0 0 8 + [13] .debug_ranges PROGBITS 00000000 298190 006958 00 0 0 1 + [14] .debug_line PROGBITS 00000000 29eae8 035e48 00 0 0 1 + [15] .debug_str PROGBITS 00000000 2d4930 02f121 01 MS 0 0 1 + [16] .debug_frame PROGBITS 00000000 303a54 009790 00 0 0 4 + [17] .stab PROGBITS 00000000 30d1e4 00003c 0c 18 0 4 + [18] .stabstr STRTAB 00000000 30d220 000076 00 0 0 1 + [19] .symtab SYMTAB 00000000 30d298 00dac0 10 20 2352 4 + [20] .strtab STRTAB 00000000 31ad58 00bcde 00 0 0 1 + [21] .shstrtab STRTAB 00000000 326a36 0000d8 00 0 0 1 +Key to Flags: + W (write), A (alloc), X (execute), M (merge), S (strings) + I (info), L (link order), G (group), T (TLS), E (exclude), x (unknown) + O (extra OS processing required) o (OS specific), p (processor specific) +``` +The important number here is at `[ 5] .heap PROGBITS 20002b20`, +which is the hexadecimal address = **0x2002b20** where the **Heap starts**. Since the **Stack ends** at the address **0x20004000**, +the space in beetween can be used for Heap and Stack and defined in [defines.json](defines.json) and [config.json](config.json) + +**Important for config.json:** +The following settings have to be set: + + +```[bash] +{ + ... + "debug": 0, + "heap_debug": 0, + "reuse_sd": 0, + "heap_allocator": 0, + "stack_size": 2560, + } +} +``` +where `stack_size` has to be the same as `__STACK_SIZE` + + + + +# !!!DEPRECATED!!! ## 2: MicroBit custom heap configuration Since the [microbit-dal](yotta_modules/microbit-dal) diff --git a/config.json b/config.json index 28ec4ae..e43f3d0 100644 --- a/config.json +++ b/config.json @@ -13,7 +13,7 @@ "event_service": 0, "device_info_service": 1 }, - "gatt_table_size": "0x300", + "gatt_table_size": "0x600", "debug": 0, "heap_debug": 0, "reuse_sd": 0, @@ -30,7 +30,7 @@ "display_scroll_stride": -1, "display_print_speed": 400, "panic_on_heap_full": 0, - "stack_size": 2672, + "stack_size": 2560, "sram_base": "0x20000008", "sram_end": "0x20004000", "sd_limit": "0x20002000" diff --git a/defines.json b/defines.json index ba6701c..e3fd193 100644 --- a/defines.json +++ b/defines.json @@ -1,4 +1,4 @@ { - "__STACK_SIZE": 2672, - "__HEAP_SIZE": 2672 + "__STACK_SIZE": 2560, + "__HEAP_SIZE": 2764 } diff --git a/source/BluetoothServiceNotify.cpp b/source/BluetoothServiceNotify.cpp index 0db089f..7455dd2 100644 --- a/source/BluetoothServiceNotify.cpp +++ b/source/BluetoothServiceNotify.cpp @@ -13,7 +13,6 @@ static const uint8_t BluetoothServiceNotifyUUID[] = { 0xa0,0x62, 0xfa,0x19,0x22,0xdf,0xa9,0xa8 }; -extern const uint8_t BluetoothServiceProgramUUID[]; BluetoothServiceNotify::BluetoothServiceNotify(Interpreter &_interpreter) : interpreter(_interpreter), @@ -26,7 +25,7 @@ BluetoothServiceNotify::BluetoothServiceNotify(Interpreter &_interpreter) : ), characteristicsBuffer() { - characteristic.requireSecurity(SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK);//MICROBIT_BLE_SECURITY_LEVEL); + characteristic.requireSecurity(SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK); characteristic.setReadAuthorizationCallback(this, &BluetoothServiceNotify::onDataRead); GattCharacteristic *characteristics[] = { @@ -47,27 +46,24 @@ BluetoothServiceNotify::BluetoothServiceNotify(Interpreter &_interpreter) : ManagedString namePrefix("BBC micro:bit ["); #endif ManagedString namePostfix("]"); - -// this->deviceName = microbit_friendly_name(); ManagedString BLEName = namePrefix + microbit_friendly_name() + namePostfix; -// // Update the advertised name of this micro:bit to include the device name + // Update the advertised name of this micro:bit to include the device name ble.clearAdvertisingPayload(); ble.accumulateAdvertisingPayload( GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *) BLEName.toCharArray(), BLEName.length()); - - ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, BluetoothServiceNotifyUUID, + ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, + BluetoothServiceNotifyUUID, 16); - ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, BluetoothServiceProgramUUID, + ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, + BluetoothServiceProgramUUID, 16); - ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); ble.setAdvertisingInterval(200); - ble.setAdvertisingTimeout(0); ble.startAdvertising(); diff --git a/source/BluetoothServiceProgram.cpp b/source/BluetoothServiceProgram.cpp index 17a9fb4..1a329bd 100644 --- a/source/BluetoothServiceProgram.cpp +++ b/source/BluetoothServiceProgram.cpp @@ -5,15 +5,6 @@ extern MicroBit uBit; -//static const uint8_t BluetoothServiceProgramUUID[] = { -// 0xff,0x66,0xdd,0xee, -// 0x25,0x1d, -// 0x47,0x0a, -// 0xa0,0x62, -// 0xfa,0x19,0x22,0xdf,0xa9,0xa8 -//}; - - BluetoothServiceProgram::BluetoothServiceProgram(Interpreter &_interpreter) : interpreter(_interpreter), ble(*uBit.ble), From 98e23e13d1eca2719d3e74a674ee95f931e6dd82 Mon Sep 17 00:00:00 2001 From: wowa Date: Wed, 27 Jun 2018 18:13:18 +0200 Subject: [PATCH 28/28] Configuration of heap and stack, flexible and equal to the branch "" --- README-UUIDS.md | 42 ++++++++++++++++++++++++++++++++++++++++++ config.json | 4 ++-- 2 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 README-UUIDS.md diff --git a/README-UUIDS.md b/README-UUIDS.md new file mode 100644 index 0000000..3582d8d --- /dev/null +++ b/README-UUIDS.md @@ -0,0 +1,42 @@ +[BluetoothServiceNotify](source/BluetoothServiceNotify.cpp) + +BluetoothServiceNotifyUUID = 0xff,0x55,0xdd,0xee, 0x25,0x1d, 0x47,0x0a, 0xa0,0x62, 0xfa,0x19,0x22,0xdf,0xa9,0xa8 + +[BluetoothServiceProgram](source/BluetoothServiceProgram.h) + +BluetoothServiceProgramUUID = 0xff, 0x66, 0xdd, 0xee, 0x25, 0x1d, 0x47, 0x0a, 0xa0, 0x62, 0xfa, 0x19, 0x22, 0xdf, 0xa9, 0xa8 + +[MicroBitAccelerometerService](yotta_modules/microbit-dal/source/bluetooth/MicroBitAccelerometerService.cpp) + +MicroBitAccelerometerServiceUUID = 0xe9,0x5d,0x07,0x53,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8 + +MicroBitAccelerometerServiceDataUUID = 0xe9,0x5d,0xca,0x4b,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8 + +MicroBitAccelerometerServicePeriodUUID = 0xe9,0x5d,0xfb,0x24,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8 + +[MicroBitDFUService](yotta_modules/microbit-dal/source/bluetooth/MicroBitDFUService.cpp) + +MicroBitDFUServiceUUID = 0xe9,0x5d,0x93,0xb0,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8 + +MicroBitDFUServiceControlCharacteristicUUID = 0xe9,0x5d,0x93,0xb1,0x25,0x1d,0x47,0x0a,0xa0,0x62,0xfa,0x19,0x22,0xdf,0xa9,0xa8 + +[DeviceInfoService](yotta_modules/ble/ble/GattCharacteristic.h) + +UUID_DEVICE_INFORMATION_SERVICE = 0x180A + +UUID_MANUFACTURER_NAME_STRING_CHAR = 0x2A29 +UUID_MODEL_NUMBER_STRING_CHAR = 0x2A24 +UUID_SERIAL_NUMBER_STRING_CHAR = 0x2A25 +UUID_HARDWARE_REVISION_STRING_CHAR = 0x2A27 +UUID_FIRMWARE_REVISION_STRING_CHAR = 0x2A26 +UUID_SOFTWARE_REVISION_STRING_CHAR = 0x2A28 + + + +**Currently not in Use** + + +[BluetoothServiceDebug](source/BluetoothServiceDebug.cpp) + +BluetoothServiceDebugUUID = 0xff, 0x44, 0xdd, 0xee, 0x25, 0x1d, 0x47, 0x0a, 0xa0, 0x62, 0xfa, 0x19, 0x22, 0xdf, 0xa9, 0xa8 + diff --git a/config.json b/config.json index e43f3d0..c8012e2 100644 --- a/config.json +++ b/config.json @@ -4,8 +4,8 @@ "enabled": 1, "pairing_mode": 1, "private_addressing": 0, - "open": 0, - "security_level": "SECURITY_MODE_ENCRYPTION_NO_MITM", + "open": 1, + "security_level": "SECURITY_MODE_ENCRYPTION_OPEN_LINK", "whitelist": 0, "advertising_timeout": 0, "tx_power": 7,