diff --git a/.gitignore b/.gitignore index a7f0f16..89cc49c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,68 +1,5 @@ -# ---> VisualStudioCode -.settings - - -# ---> C -# Object files -*.o -*.ko -*.obj -*.elf - -# Precompiled Headers -*.gch -*.pch - -# Libraries -*.lib -*.a -*.la -*.lo - -# Shared objects (inc. Windows DLLs) -*.dll -*.so -*.so.* -*.dylib - -# Executables -*.exe -*.out -*.app -*.i*86 -*.x86_64 -*.hex - -# Debug files -*.dSYM/ - -# ---> C++ -# Compiled Object files -*.slo -*.lo -*.o -*.obj - -# Precompiled Headers -*.gch -*.pch - -# Compiled Dynamic libraries -*.so -*.dylib -*.dll - -# Fortran module files -*.mod - -# Compiled Static libraries -*.lai -*.la -*.a -*.lib - -# Executables -*.exe -*.out -*.app - +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..e80666b --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,7 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..39b720d --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,14 @@ +{ + "files.associations": { + "*.config": "ini", + "array": "cpp", + "*.tcc": "cpp", + "deque": "cpp", + "string": "cpp", + "unordered_map": "cpp", + "vector": "cpp", + "string_view": "cpp", + "memory": "cpp", + "initializer_list": "cpp" + } +} \ No newline at end of file diff --git a/gdbinit b/gdbinit new file mode 100644 index 0000000..348b6c9 --- /dev/null +++ b/gdbinit @@ -0,0 +1,6 @@ + define restart + monitor reset + shell sleep 1 + cont + end + \ No newline at end of file diff --git a/include/README b/include/README new file mode 100644 index 0000000..194dcd4 --- /dev/null +++ b/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/lib/README b/lib/README new file mode 100644 index 0000000..6debab1 --- /dev/null +++ b/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include +#include + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/platformio.ini b/platformio.ini new file mode 100644 index 0000000..fb0053e --- /dev/null +++ b/platformio.ini @@ -0,0 +1,20 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:adafruit_feather_nrf52840] +platform = nordicnrf52 +board = adafruit_feather_nrf52840 +framework = arduino + +monitor_speed = 115200 + +upload_protocol = jlink +build_type = debug +debug_extra_cmds = source gdbinit diff --git a/src/SBrickService.cpp b/src/SBrickService.cpp new file mode 100644 index 0000000..f0d619d --- /dev/null +++ b/src/SBrickService.cpp @@ -0,0 +1,2 @@ +#include "SBrickService.h" + diff --git a/src/SBrickService.h b/src/SBrickService.h new file mode 100644 index 0000000..ae2244f --- /dev/null +++ b/src/SBrickService.h @@ -0,0 +1,55 @@ +#pragma once + +#include + +namespace FeatherBrick { + + constexpr uint8_t const RemoteControlCommandsUuidBytes[16] = { + 0x02, 0xb8, 0xcb, 0xcc, + 0x0e, 0x25, + 0x4b, 0xda, + 0x87, 0x90, + 0xa1, 0x5f, 0x53, 0xe6, 0x01, 0x0f + }; + const BLEUuid RemoteControlCommandsUUID = BLEUuid(RemoteControlCommandsUuidBytes); + + constexpr uint8_t const RemoteControlServiceUuidBytes[16] = { + 0x4d, 0xc5, 0x91, 0xb0, + 0x85, 0x7c, + 0x41, 0xde, + 0xb5, 0xf1, + 0x15, 0xab, 0xda, 0x66, 0x5b, 0x0c + }; + const BLEUuid RemoteControlServiceUUID = BLEUuid(RemoteControlServiceUuidBytes); + + class RemoteControlCommandsCharacteristic: public BLECharacteristic { + public: + RemoteControlCommandsCharacteristic(): BLECharacteristic(RemoteControlCommandsUUID) {} + }; + + class RemoteControlService: public BLEService { + public: + RemoteControlService(): BLEService(RemoteControlServiceUUID) {} + + void setCommandCallback(BLECharacteristic::write_cb_t cb) { + Rccc.setWriteCallback(cb); + } + + err_t begin() { + err_t _error = BLEService::begin(); + if (_error == ERROR_NONE) { + Rccc.setProperties(CHR_PROPS_READ + | CHR_PROPS_WRITE + | CHR_PROPS_WRITE_WO_RESP + | CHR_PROPS_NOTIFY + ); + Rccc.setMaxLen(20); + Rccc.begin(); + } + return _error; + } + private: + RemoteControlCommandsCharacteristic Rccc; + }; + +} \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..ecb59a8 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,87 @@ +#include +#include +#include "SBrickService.h" + +BLEDfu ble_dfu; +BLEDis ble_dis; +FeatherBrick::RemoteControlService ble_rccs; + +void startAdvertising(); +void connectCB(uint16_t conn_handle); +void commandCB(uint16_t conn_hdl, BLECharacteristic* chr, uint8_t* data, uint16_t len); + +void setup() { + Serial.begin(115200); + while (!Serial) + delay(10); // for nrf52840 with native usb + + Serial.println("SBrick"); + Serial.println("--------------------------------"); + + + // Init Bluefruit + Bluefruit.begin(); + Bluefruit.setTxPower(4); // Check bluefruit.h for supported values + Bluefruit.setName("SBrick"); + Bluefruit.Periph.setConnectCallback(connectCB); + + // To be consistent OTA DFU should be added first if it exists + ble_dfu.begin(); + + // Configure and Start Device Information Service + ble_dis.setManufacturer("Vengit Ltd."); + ble_dis.setModel("00"); + ble_dis.setSoftwareRev("13.26"); + ble_dis.setHardwareRev("13.0"); + ble_dis.begin(); + + // Remote Control Service + ble_rccs.setCommandCallback(commandCB); + ble_rccs.begin(); + + startAdvertising(); +} + +void loop() { + // if (Bluefruit.connected() && bleuart.notifyEnabled()) { + // blecobs.update(); + // if (blecobs.overflow()) { + // Serial.print("blecobs OVERFLOW!"); + // } + // } +} + +void startAdvertising() { + Bluefruit.Advertising.addFlags(BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE); + Bluefruit.Advertising.addTxPower(); + Bluefruit.Advertising.addService(ble_rccs); + Bluefruit.ScanResponse.addName(); + + /* Start Advertising + * - Enable auto advertising if disconnected + * - Interval: fast mode = 20 ms, slow mode = 152.5 ms + * - Timeout for fast mode is 30 seconds + * - Start(timeout) with timeout = 0 will advertise forever (until connected) + * + * For recommended advertising interval + * https://developer.apple.com/library/content/qa/qa1931/_index.html + */ + Bluefruit.Advertising.restartOnDisconnect(true); + Bluefruit.Advertising.setInterval(32, 244); // in unit of 0.625 ms + Bluefruit.Advertising.setFastTimeout(30); // number of seconds in fast mode + Bluefruit.Advertising.start(0); // 0 = Don't stop advertising after n seconds +} + +void connectCB(uint16_t conn_handle) { + BLEConnection *connection = Bluefruit.Connection(conn_handle); + char central_name[32] = {0}; + connection->getPeerName(central_name, sizeof(central_name)); + + Serial.print("Connected to "); + Serial.println(central_name); +} + +void commandCB(uint16_t conn_hdl, BLECharacteristic* chr, uint8_t* data, uint16_t len) { + Serial.print("Chr write: "); + Serial.printBuffer(data,len); +} \ No newline at end of file diff --git a/test/README b/test/README new file mode 100644 index 0000000..b94d089 --- /dev/null +++ b/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Unit Testing and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/page/plus/unit-testing.html