Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
ff7c2fa
Echo example working
hubmartin Aug 5, 2021
5620ab8
WIP: Save conn handle, add print
hubmartin Aug 5, 2021
1a5de5e
Trying to add Console class
hubmartin Aug 7, 2021
ae4b46a
Move Console to Components
hubmartin Aug 8, 2021
bc0f7c1
Working console.Print concept
hubmartin Aug 8, 2021
2a0754b
WIP
hubmartin Aug 9, 2021
8d12806
RX callback registration
hubmartin Aug 10, 2021
7ebe928
Add VSCode ST-link debug config
hubmartin Aug 9, 2021
0fa1587
Merge branch 'bootloop' into ble-nus
hubmartin Aug 10, 2021
8c95f55
First commands working
hubmartin Aug 10, 2021
18c0f46
Move console processing to SystemTask
hubmartin Aug 11, 2021
774e2f8
Add MotionController debug output
hubmartin Aug 11, 2021
6f84ecd
Merge branch 'develop' into ble-nus
hubmartin Aug 11, 2021
e560bc9
Cleanup
hubmartin Aug 11, 2021
7191bb5
Add rxPos len check
hubmartin Aug 11, 2021
6ec3aa4
Cleanup
hubmartin Aug 11, 2021
0170cfe
Add hatmajster suggestions
hubmartin Aug 11, 2021
eeda7ad
Clean commented NRF log block
hubmartin Aug 11, 2021
f15ce01
Move acc debug cmd & lvgl info to funtions
hubmartin Aug 13, 2021
a3317d8
Compare with \r & \n
hubmartin Aug 13, 2021
e94d0fd
Handle console by event Messages::ConsoleProcess
hubmartin Aug 13, 2021
b1304e9
Comment LVGL commands because of recovery FW does not compiled
hubmartin Aug 21, 2021
e019aa0
Merge branch 'develop' into ble-nus
hubmartin Aug 21, 2021
1dcbeac
Merge branch 'develop' into ble-nus
hubmartin Aug 30, 2021
0de7822
Update vibrations to RunForDuration
hubmartin Sep 11, 2021
dcc4a6e
Merge branch 'develop' into ble-nus
hubmartin Oct 3, 2021
2ad36ad
Clean code, lower rx buffer
hubmartin Oct 22, 2021
f667aab
Remove console.Print examples
hubmartin Oct 22, 2021
7f18a01
Merge branch 'develop' into ble-nus
hubmartin Oct 22, 2021
16736d5
clang-format
hubmartin Oct 22, 2021
94215c7
Run clang-tidy
hubmartin Oct 28, 2021
946867e
Merge branch 'develop' into ble-nus
hubmartin Oct 28, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,5 @@
"target/nrf52.cfg"
],
}

]
}
5 changes: 4 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,7 @@ list(APPEND SOURCE_FILES
components/motion/MotionController.cpp
components/ble/NimbleController.cpp
components/ble/DeviceInformationService.cpp
components/ble/BleNus.cpp
components/ble/CurrentTimeClient.cpp
components/ble/AlertNotificationClient.cpp
components/ble/DfuService.cpp
Expand Down Expand Up @@ -506,7 +507,7 @@ list(APPEND SOURCE_FILES
components/heartrate/Biquad.cpp
components/heartrate/Ptagc.cpp
components/heartrate/HeartRateController.cpp

components/console/Console.cpp
touchhandler/TouchHandler.cpp
)

Expand Down Expand Up @@ -535,6 +536,7 @@ list(APPEND RECOVERY_SOURCE_FILES
components/motion/MotionController.cpp
components/ble/NimbleController.cpp
components/ble/DeviceInformationService.cpp
components/ble/BleNus.cpp
components/ble/CurrentTimeClient.cpp
components/ble/AlertNotificationClient.cpp
components/ble/DfuService.cpp
Expand Down Expand Up @@ -567,6 +569,7 @@ list(APPEND RECOVERY_SOURCE_FILES
components/heartrate/Ptagc.cpp
components/motor/MotorController.cpp
components/fs/FS.cpp
components/console/Console.cpp
touchhandler/TouchHandler.cpp
)

Expand Down
87 changes: 87 additions & 0 deletions src/components/ble/BleNus.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#include "BleNus.h"
#include "components/console/Console.h"

using namespace Pinetime::Controllers;

constexpr ble_uuid128_t BleNus::nusServiceUuid;
constexpr ble_uuid128_t BleNus::rxCharacteristicUuid;
constexpr ble_uuid128_t BleNus::txCharacteristicUuid;
uint16_t BleNus::attributeReadHandle;

int BleNusCallback(uint16_t connectionHandle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt, void* arg) {
auto *deviceInformationService = static_cast<BleNus*>(arg);
return deviceInformationService->OnDeviceInfoRequested(connectionHandle, attr_handle, ctxt);
}

void BleNus::Init() {
int res = 0;
res = ble_gatts_count_cfg(serviceDefinition);
ASSERT(res == 0);

res = ble_gatts_add_svcs(serviceDefinition);
ASSERT(res == 0);
}

void BleNus::SetConnectionHandle(uint16_t connection_handle) {
connectionHandle = connection_handle;
}

void BleNus::Print(const std::string str) {
os_mbuf* om;
om = ble_hs_mbuf_from_flat(str.c_str(), str.length());

if (om) {
ble_gattc_notify_custom(connectionHandle, attributeReadHandle, om);
}
}

void BleNus::RegisterRxCallback(std::function<void(char*, int)> f) {
this->rxDataFunction = f;
}

int BleNus::OnDeviceInfoRequested(uint16_t connectionHandle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt) {
(void) connectionHandle;
(void) attr_handle;

os_mbuf* om = ctxt->om;

switch (ctxt->op) {
case BLE_GATT_ACCESS_OP_WRITE_CHR:
while (om) {

// Test BLE console it with Bluefruit, NRF Toolbox (you must add enter before hitting send!
// https://devzone.nordicsemi.com/f/nordic-q-a/33687/nrf-toolbox-2-6-0-uart-does-not-send-lf-cr-or-cr-lf-as-eol) on the phone, or in
// any Chromium-based web browser https://terminal.hardwario.com/

rxDataFunction((char*) om->om_data, (int) om->om_len);

om = SLIST_NEXT(om, om_next);
}
return 0;
default:
assert(0);
return BLE_ATT_ERR_UNLIKELY;
}
}

BleNus::BleNus()
: characteristicDefinition {{
.uuid = &rxCharacteristicUuid.u,
.access_cb = BleNusCallback,
.arg = this,
.flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_WRITE_NO_RSP,
},
{.uuid = &txCharacteristicUuid.u,
.access_cb = BleNusCallback,
.arg = this,
.flags = BLE_GATT_CHR_F_NOTIFY,
.val_handle = &attributeReadHandle},
{0}},
serviceDefinition {
{/* Device Information Service */
.type = BLE_GATT_SVC_TYPE_PRIMARY,
.uuid = &nusServiceUuid.u,
.characteristics = characteristicDefinition},
{0},
} {
}
49 changes: 49 additions & 0 deletions src/components/ble/BleNus.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#pragma once
#define min // workaround: nimble's min/max macros conflict with libstdc++
#define max
#include <host/ble_gap.h>
#undef max
#undef min
#include "Version.h"
#include <functional>

namespace Pinetime {
namespace Components {
class Console;
}
namespace Controllers {
class BleNus {
public:
BleNus();
void Init();
void SetConnectionHandle(uint16_t connection_handle);
void Print(const std::string str);

void RegisterRxCallback(std::function<void(char*, int)> f);

int OnDeviceInfoRequested(uint16_t connectionHandle, uint16_t attr_handle, struct ble_gatt_access_ctxt* ctxt);

private:
static uint16_t attributeReadHandle;
uint16_t connectionHandle;

std::function<void(char*, int)> rxDataFunction;

// 6E400001-B5A3-F393-E0A9-E50E24DCCA9E
static constexpr ble_uuid128_t nusServiceUuid {
.u {.type = BLE_UUID_TYPE_128},
.value = {0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0, 0x93, 0xf3, 0xa3, 0xb5, 0x01, 0x00, 0x40, 0x6e}};
// 6E400002-B5A3-F393-E0A9-E50E24DCCA9E
static constexpr ble_uuid128_t rxCharacteristicUuid {
.u {.type = BLE_UUID_TYPE_128},
.value = {0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0, 0x93, 0xf3, 0xa3, 0xb5, 0x02, 0x00, 0x40, 0x6e}};
// 6E400003-B5A3-F393-E0A9-E50E24DCCA9E
static constexpr ble_uuid128_t txCharacteristicUuid {
.u {.type = BLE_UUID_TYPE_128},
.value = {0x9e, 0xca, 0xdc, 0x24, 0x0e, 0xe5, 0xa9, 0xe0, 0x93, 0xf3, 0xa3, 0xb5, 0x03, 0x00, 0x40, 0x6e}};

struct ble_gatt_chr_def characteristicDefinition[3];
struct ble_gatt_svc_def serviceDefinition[2];
};
}
}
7 changes: 6 additions & 1 deletion src/components/ble/NimbleController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "components/ble/NotificationManager.h"
#include "components/datetime/DateTimeController.h"
#include "systemtask/SystemTask.h"
#include "components/ble/BleNus.h"

using namespace Pinetime::Controllers;

Expand Down Expand Up @@ -74,6 +75,7 @@ void NimbleController::Init() {
ble_svc_gatt_init();

deviceInformationService.Init();
bleNusService.Init();
currentTimeClient.Init();
currentTimeService.Init();
musicService.Init();
Expand Down Expand Up @@ -181,7 +183,9 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) {
connectionHandle = event->connect.conn_handle;
bleController.Connect();
systemTask.PushMessage(Pinetime::System::Messages::BleConnected);
// Service discovery is deferred via systemtask
connectionHandle = event->connect.conn_handle;
bleNusService.SetConnectionHandle(event->connect.conn_handle);
// Service discovery is deffered via systemtask
}
break;

Expand Down Expand Up @@ -292,3 +296,4 @@ void NimbleController::NotifyBatteryLevel(uint8_t level) {
batteryInformationService.NotifyBatteryLevel(connectionHandle, level);
}
}

6 changes: 6 additions & 0 deletions src/components/ble/NimbleController.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "CurrentTimeClient.h"
#include "CurrentTimeService.h"
#include "DeviceInformationService.h"
#include "BleNus.h"
#include "DfuService.h"
#include "ImmediateAlertService.h"
#include "MusicService.h"
Expand Down Expand Up @@ -71,6 +72,10 @@ namespace Pinetime {
return anService;
};

Pinetime::Controllers::BleNus& bleNus() {
return bleNusService;
};

uint16_t connHandle();
void NotifyBatteryLevel(uint8_t level);

Expand All @@ -88,6 +93,7 @@ namespace Pinetime {
Pinetime::Controllers::DfuService dfuService;

DeviceInformationService deviceInformationService;
BleNus bleNusService;
CurrentTimeClient currentTimeClient;
AlertNotificationService anService;
AlertNotificationClient alertNotificationClient;
Expand Down
101 changes: 101 additions & 0 deletions src/components/console/Console.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
#include "Console.h"
#include "components/ble/BleNus.h"
#include "components/ble/NimbleController.h"
#include "systemtask/SystemTask.h"

using namespace Pinetime::Components;

Console::Console(Pinetime::System::SystemTask& systemTask,
Pinetime::Controllers::NimbleController& nimbleController,
Pinetime::Controllers::FS& fs,
Pinetime::Components::LittleVgl& lvgl,
Pinetime::Controllers::MotorController& motorController,
Pinetime::Drivers::Cst816S& touchPanel,
Pinetime::Drivers::SpiNorFlash& spiNorFlash,
Pinetime::Drivers::TwiMaster& twiMaster,
Pinetime::Controllers::MotionController& motionController)
: systemTask {systemTask},
nimbleController {nimbleController},
fs {fs},
lvgl {lvgl},
motorController {motorController},
touchPanel {touchPanel},
spiNorFlash {spiNorFlash},
twiMaster {twiMaster},
motionController {motionController} {
}

void Console::Init() {
auto rxCallback = [this](char* str, int length) {
this->Received(str, length);
};

nimbleController.bleNus().RegisterRxCallback(rxCallback);
}

void Console::Print(const std::string str) {
nimbleController.bleNus().Print(str);
}

static bool cmdCmp(char* buffer, const std::string search) {
return strncmp(buffer, search.c_str(), search.length()) == 0;
}

void Console::Process() {
static constexpr int maxArgumentsCount = 4;
static constexpr int maxBufferLength = 64;

char arg_buffer[maxBufferLength];
const char* args[maxArgumentsCount];

// Copy string, becase we replace ' ' with '\0' for proper string termination
strncpy(arg_buffer, rxBuffer, sizeof(arg_buffer));

// First argument is always command name itself
uint16_t argc = 1;
args[0] = arg_buffer;

uint16_t param_len = strlen(rxBuffer);

for (uint16_t i = 0; i < param_len; i++) {
if (rxBuffer[i] == ' ' && param_len > (i + 1)) {
arg_buffer[i] = '\0';
args[argc++] = &arg_buffer[i + 1];
}

if (argc == maxArgumentsCount) {
// Max argument count reached
break;
}
}

(void) args;
(void) argc;

// Simple stupid command comparison, later would be nice to add commands lookup table with argument parsing
if (cmdCmp(rxBuffer, "VIBRATE")) {
motorController.RunForDuration(100);
} else if (cmdCmp(rxBuffer, "WKUP")) {
systemTask.PushMessage(Pinetime::System::Messages::GoToRunning);
} else if (cmdCmp(rxBuffer, "SLEEP")) {
systemTask.PushMessage(Pinetime::System::Messages::GoToSleep);
}
}

void Console::Received(char* str, int length) {
for (int i = 0; i < length; i++) {
// Wrap if input is too long without CR/LN
if (rxPos == bufferSize - 1) {
rxPos = 0;
}

rxBuffer[rxPos++] = str[i];
rxBuffer[rxPos] = '\0'; // terminate for debug print

if (str[i] == '\n' || str[i] == '\r') {
rxPos = 0;
systemTask.PushMessage(System::Messages::ConsoleProcess);
break;
}
}
}
Loading