diff --git a/app_config.h b/app_config.h
index 98be0a4..46fadb9 100644
--- a/app_config.h
+++ b/app_config.h
@@ -15,9 +15,9 @@ extern "C"
#define NRF_LOG_BACKEND_UART_ENABLED 0
#define NRF_LOG_BACKEND_RTT_TX_RETRY_DELAY_MS 1
#define NRF_LOG_BACKEND_RTT_TX_RETRY_CNT 3
-#define NRF_LOG_BACKEND_RTT_TEMP_BUFFER_SIZE 64
+#define NRF_LOG_BACKEND_RTT_TEMP_BUFFER_SIZE 256
#define NRF_LOG_DEFERRED 0
-#define NRF_LOG_USES_TIMESTAMP 0
+#define NRF_LOG_USES_TIMESTAMP 1
#define NRF_FPRINTF_FLAG_AUTOMATIC_CR_ON_LF_ENABLED 0
// SEGGER-RTT
@@ -152,11 +152,11 @@ extern "C"
// Priority for dispatching the BLE events to the Scanning Module.
#define NRF_BLE_SCAN_OBSERVER_PRIO 1
// Scanning interval. Determines the scan interval in units of 0.625 millisecond.
-#define NRF_BLE_SCAN_SCAN_INTERVAL 160
+#define NRF_BLE_SCAN_SCAN_INTERVAL 600
// Duration of a scanning session in units of 10 ms. Range: 0x0001 - 0xFFFF (10 ms to 10.9225 ms). If set to 0x0000, the scanning continues until it is explicitly disabled.
#define NRF_BLE_SCAN_SCAN_DURATION 0
// Scanning window. Determines the scanning window in units of 0.625 millisecond.
-#define NRF_BLE_SCAN_SCAN_WINDOW 80
+#define NRF_BLE_SCAN_SCAN_WINDOW 400
// Determines the supervision time-out in units of 10 millisecond.
#define NRF_BLE_SCAN_SUPERVISION_TIMEOUT 4000
// Determines minimum connection interval in milliseconds.
@@ -168,9 +168,9 @@ extern "C"
// Enabling filters for the Scanning Module.
#define NRF_BLE_SCAN_FILTER_ENABLE 1
// Number of filters for UUIDs.
-#define NRF_BLE_SCAN_UUID_CNT 0
+#define NRF_BLE_SCAN_UUID_CNT 1
// Number of name filters.
-#define NRF_BLE_SCAN_NAME_CNT 2
+#define NRF_BLE_SCAN_NAME_CNT 0
// Number of short name filters.
#define NRF_BLE_SCAN_SHORT_NAME_CNT 0
// Number of address filters.
@@ -211,6 +211,17 @@ extern "C"
// Enable GATT MTU exchange initiation
#define NRF_BLE_GATT_MTU_EXCHANGE_INITIATION_ENABLED 1
+// The maximum number of characteristics present in a service record
+#define BLE_GATT_DB_MAX_CHARS 16
+
+// Custom UUID service & char
+#define BLE_UUID_CUSTOM_SERVICE 0xFFF0
+#define BLE_UUID_REGULAR_DATA_CHAR 0xFFF1
+#define BLE_UUID_LOW_FREQ_DATA_CHAR 0xFFF2
+#define BLE_UUID_AUXILIARY_DATA_CHAR 0xFFF3
+#define BLE_UUID_STATUS_CHAR 0xFFF4
+#define BLE_UUID_EVENT_CHAR 0xFFF5
+
#define COUNTOF(x) (sizeof(x) / sizeof(x[0]))
#ifdef __cplusplus
diff --git a/bmd380_central-Debug.vgdbsettings b/bmd380_central-Debug.vgdbsettings
index 7e6ce67..984c5c6 100644
--- a/bmd380_central-Debug.vgdbsettings
+++ b/bmd380_central-Debug.vgdbsettings
@@ -25,6 +25,7 @@
bmd380_central.vcxproj
+
1
true
@@ -129,7 +130,7 @@
_estack
0
false
-
+ 2779096485
true
\ No newline at end of file
diff --git a/bmd380_central.vcxproj b/bmd380_central.vcxproj
index 3e27aea..2a18caf 100644
--- a/bmd380_central.vcxproj
+++ b/bmd380_central.vcxproj
@@ -32,12 +32,12 @@
Debug
com.visualgdb.arm-eabi
- 10.3.1/10.2.90/r1
+ 12.2.1/12.2/r2
$(ProjectDir)nrf5x.props
com.visualgdb.arm-eabi
- 10.3.1/10.2.90/r1
+ 12.2.1/12.2/r2
$(ProjectDir)nrf5x.props
@@ -55,7 +55,8 @@
%(Link.LibrarySearchDirectories)
%(Link.AdditionalLibraryNames)
%(Link.AdditionalLinkerInputs)
-
+
+
@@ -77,7 +78,10 @@
+
+
+
@@ -380,7 +384,6 @@
-
diff --git a/bmd380_central.vcxproj.filters b/bmd380_central.vcxproj.filters
index 1ba2644..d7aa174 100644
--- a/bmd380_central.vcxproj.filters
+++ b/bmd380_central.vcxproj.filters
@@ -1667,9 +1667,6 @@
Source files
-
- Source files
-
Source files
@@ -1679,6 +1676,15 @@
Source files
+
+ Source files
+
+
+ Source files
+
+
+ Source files
+
diff --git a/host_tasks.c b/host_tasks.c
index 40b0556..93756ef 100644
--- a/host_tasks.c
+++ b/host_tasks.c
@@ -33,13 +33,13 @@ typedef struct
{
uint8_t opcode;
uint8_t len;
-} host_cmd_survive_t;
+} ins_survive_t;
typedef struct
{
uint8_t opcode;
uint8_t len;
-} host_cmd_scan_t;
+} ins_scan_t;
typedef struct
{
@@ -47,28 +47,28 @@ typedef struct
uint8_t len;
uint8_t addr_type;
uint8_t addr[6];
-} host_cmd_connect_t;
+} ins_connect_t;
typedef struct
{
uint8_t opcode;
uint8_t len;
-} host_cmd_disconnect_t;
+} ins_disconnect_t;
typedef struct
{
uint8_t opcode;
uint8_t len;
uint8_t handle;
- uint8_t write_date[0];
-} host_cmd_write_char_t;
+ uint8_t write_data[255];
+} ins_write_char_t;
typedef struct
{
uint8_t opcode;
uint8_t len;
uint8_t handle;
-} host_cmd_read_char_t;
+} ins_read_char_t;
typedef union
{
@@ -81,80 +81,126 @@ typedef union
uint8_t payload[255];
};
} raw;
+ ins_survive_t survive;
+ ins_scan_t scan;
+ ins_connect_t connect;
+ ins_disconnect_t disconnect;
+ ins_write_char_t write_char;
+ ins_read_char_t read_char;
+} host_ins_t;
- host_cmd_survive_t survive;
- host_cmd_scan_t scan;
- host_cmd_connect_t connect;
- host_cmd_disconnect_t disconnect;
- host_cmd_write_char_t write_char;
- host_cmd_read_char_t read_char;
+#define EVT_ALL 0xFFFF
+#define EVT_MEM_RETURN_DATA 0x0010
+#define EVT_MEM_NOTIFY_HANDLE 0x0040
+#define EVT_MEM_UART_ROUTINE 0x0080
+#define EVT_MEM_INS_SCAN 0x0100
+#define EVT_MEM_INS_CONNECT 0x0200
+#define EVT_MEM_INS_WRITE 0x0400
+#define EVT_MEM_INS_READ 0x0800
+#define EVT_MEM_INS_DISCONNECT 0x1000
+#define EVT_MEM_INS_CHECK_SURVIVE 0x2000
-} host_command_t;
+typedef enum
+{
+ INS_IDLE = 0x00,
+ INS_RESET = 0x01,
+ INS_KEY = 0x02,
+ INS_SCAN = 0x03,
+ INS_SCAN_RESPONSE = 0x04,
+ INS_CONNECT = 0x05,
+ INS_WRITE_CHAR = 0x06,
+ INS_READ_CHAR = 0x07,
+ INS_DISCONNECT = 0x08,
+ INS_PREPARE_CONNECT = 0x09,
+ INS_CHECK_SURVIVE = 0x0A
+} ctrl_instr_t;
-#define CMD_NULL 0x00
-#define CMD_SURVIVE 0x0A
-#define CMD_SCAN 0x03
-#define CMD_CONNECT 0x05
-#define CMD_DISCONNECT 0x08
-#define CMD_WR_CHAR 0x06
-#define CMD_RD_CHAR 0x07
-#define CMD_SUFFIX 0xF1
+#define INST_SUFFIX 0xF1
static MessageBufferHandle_t host_cmd_msg;
-static void survive_ack(void)
+static void success_ack(void)
{
uint8_t ack[] = { 0x04, 0x00, 0x01, 0x03 };
uart_drv_tx(ack, sizeof(ack));
}
-void on_survive(host_cmd_survive_t *p_cmd)
+static void on_ins_scan(ins_scan_t *p_ins)
{
- survive_ack();
+ extern void le_scan_start(void);
+ le_scan_start();
}
-static void connect_ack(void)
+static void on_ins_connect(ins_connect_t *p_ins)
{
- uint8_t ack[] = { 0x04, 0x00, 0x04, 0x2E, 0x50, 0x30, 0x04 };
- uart_drv_tx(ack, sizeof(ack));
-}
+ ble_gap_addr_t peer_addr;
+ memset(&peer_addr, 0x00, sizeof(peer_addr));
+ peer_addr.addr[0] = p_ins->addr[5];
+ peer_addr.addr[1] = p_ins->addr[4];
+ peer_addr.addr[2] = p_ins->addr[3];
+ peer_addr.addr[3] = p_ins->addr[2];
+ peer_addr.addr[4] = p_ins->addr[1];
+ peer_addr.addr[5] = p_ins->addr[0];
-static void on_connect(host_cmd_connect_t *p_cmd)
-{
extern void le_scan_stop(void);
- extern void le_gap_connet(ble_gap_addr_t * p_peer_addr, nrf_ble_scan_t * p_scan);
- extern const nrf_ble_scan_t *le_scan_obj(void);
+ le_scan_stop();
- ble_gap_addr_t gap_addr;
- gap_addr.addr_type = BLE_GAP_ADDR_TYPE_RANDOM_STATIC;
- gap_addr.addr_id_peer = 0;
- for (int i = 0; i < COUNTOF(gap_addr.addr); i++)
- {
- gap_addr.addr[i] = p_cmd->addr[COUNTOF(gap_addr.addr) - i - 1];
- }
- le_gap_connet((void *)&gap_addr, (void *)le_scan_obj());
+ vTaskDelay(pdMS_TO_TICKS(5));
+
+ extern void le_gap_connet(ble_gap_addr_t * p_peer_addr);
+ le_gap_connet(&peer_addr);
char rsp_buf[64];
- sprintf(rsp_buf, "%s(%02X:%02X:%02X:%02X:%02X:%02X)\r\n", __FUNCTION__, gap_addr.addr[5], gap_addr.addr[4], gap_addr.addr[3], gap_addr.addr[2], gap_addr.addr[1], gap_addr.addr[0]);
+ sprintf(rsp_buf, "%s: %02X:%02X:%02X:%02X:%02X:%02X", "Connect to", peer_addr.addr[5], peer_addr.addr[4], peer_addr.addr[3], peer_addr.addr[2], peer_addr.addr[1], peer_addr.addr[0]);
NRF_LOG_INFO("%s", rsp_buf);
}
-static void disconnect_ack(void)
+static void on_ins_write_char(ins_write_char_t *p_ins)
{
- uint8_t ack[] = { 0x04, 0x00, 0x01, 0x03 };
- uart_drv_tx(ack, sizeof(ack));
+ NRF_LOG_INFO("write handle: 0x%02X", p_ins->handle);
+ uint16_t write_size = p_ins->len - sizeof(p_ins->handle) - 1;
+ extern ret_code_t le_gatt_c_write_req(uint32_t handle, void *, uint16_t);
+ ret_code_t ret_code = le_gatt_c_write_req(p_ins->handle, p_ins->write_data, write_size);
+ if (ret_code == NRF_SUCCESS)
+ {
+ success_ack();
+ }
}
-static void on_disconnect(host_cmd_disconnect_t *p_cmd)
+static void on_ins_read_char(ins_read_char_t *p_ins)
+{
+ NRF_LOG_INFO("read handle: 0x%02X", p_ins->handle);
+ extern ret_code_t le_gatt_c_read_char_req(uint32_t handle);
+ ret_code_t ret_code = le_gatt_c_read_char_req(p_ins->handle);
+}
+
+static void on_ins_disconnect(ins_disconnect_t *p_ins)
{
extern void le_gap_disconnet(uint16_t);
le_gap_disconnet(0);
}
-static void on_scan(host_cmd_scan_t *p_cmd)
+static void on_ins_survive(ins_survive_t *p_ins)
{
- extern void le_scan_start(void);
- le_scan_start();
+ success_ack();
+}
+
+typedef struct
+{
+ uint16_t rsp_code;
+ union
+ {
+ uint8_t len;
+ uint8_t payload[256];
+ };
+} __PACKED read_char_rsp_t;
+
+read_char_rsp_t read_char_rsp;
+void host_read_char_cb(uint8_t *p_data, uint16_t len)
+{
+ read_char_rsp.rsp_code = 0x0004;
+ memcpy(&read_char_rsp.len, p_data, len);
+ uart_drv_tx(&read_char_rsp, offsetof(read_char_rsp_t, payload) + len);
}
typedef struct
@@ -176,63 +222,43 @@ void host_scan_filter_match_cb(
ble_gap_addr_t const *peer_addr,
int16_t rssi)
{
-
typedef struct
{
uint16_t hci_packet_event;
uint8_t len;
uint8_t addr[6];
- uint8_t product_module[4];
- uint32_t hw_ver;
- uint8_t buid_time[2];
- uint8_t parameter[3];
- uint16_t bat_volt;
- uint8_t dev_name[11];
+ uint8_t manu_spec_data[15];
+ uint8_t dev_name[21];
} __PACKED host_scan_rsp_t;
- volatile host_scan_rsp_t host_scan_rsp = {
- .hci_packet_event = 0x0004,
- .product_module = { 'B', 'P', 'H', 'S' },
- .parameter = { 'B', 'A', 'T' },
- .buid_time = { 0x17, 0x06 },
- };
+ static host_scan_rsp_t host_scan_rsp;
+
+ memset(&host_scan_rsp, 0x00, sizeof(host_scan_rsp));
+
+ host_scan_rsp.hci_packet_event = 0x0004;
+
+ host_scan_rsp.len = sizeof(host_scan_rsp_t) - offsetof(host_scan_rsp_t, addr);
+
+ memcpy(host_scan_rsp.addr, peer_addr->addr, sizeof(host_scan_rsp.addr));
+
+ memcpy((void *)&host_scan_rsp.manu_spec_data, p_manu_spec_data, sizeof(host_scan_rsp.manu_spec_data));
+
+ memcpy((void *)host_scan_rsp.dev_name, p_device_name, device_name_len);
+
+ uart_drv_tx(&host_scan_rsp, sizeof(host_scan_rsp));
char peer_addr_str[(2 + 1) * BLE_GAP_ADDR_LEN + 1] = { 0 };
- if (peer_addr)
- {
- for (int i = 0; i < BLE_GAP_ADDR_LEN; i++)
- {
- host_scan_rsp.addr[i] = peer_addr->addr[(BLE_GAP_ADDR_LEN - 1) - i];
- }
- sprintf(peer_addr_str, "%02X:%02X:%02X:%02X:%02X:%02X", host_scan_rsp.addr[0], host_scan_rsp.addr[1], host_scan_rsp.addr[2], host_scan_rsp.addr[3], host_scan_rsp.addr[4], host_scan_rsp.addr[5]);
- }
- if (p_manu_spec_data)
- {
- manu_spec_data_t *p = p_manu_spec_data;
- memcpy((void *)&host_scan_rsp.hw_ver, &p->data.hw_ver[0], sizeof(p->data.hw_ver));
- uint16_t voltage = p->data.battery_level * 37;
- host_scan_rsp.bat_volt = __REVSH(voltage);
- }
+ sprintf(peer_addr_str, "%02X:%02X:%02X:%02X:%02X:%02X", host_scan_rsp.addr[5], host_scan_rsp.addr[4], host_scan_rsp.addr[3], host_scan_rsp.addr[2], host_scan_rsp.addr[1], host_scan_rsp.addr[0]);
- host_scan_rsp.len = offsetof(host_scan_rsp_t, dev_name) - offsetof(host_scan_rsp_t, addr);
- if (p_device_name)
- {
- uint32_t len;
- len = sizeof(host_scan_rsp.dev_name);
- len = len > device_name_len ? device_name_len : len;
- memcpy((void *)host_scan_rsp.dev_name, p_device_name, len);
- host_scan_rsp.len += len;
- }
-
- NRF_LOG_INFO("Found: %s [%s, %s, %08X, %d, %ddb]",
+ NRF_LOG_INFO("Found: %s [%s, %ddb]",
host_scan_rsp.dev_name,
peer_addr_str,
- host_scan_rsp.product_module,
- __REV(host_scan_rsp.hw_ver),
- __REVSH(host_scan_rsp.bat_volt),
rssi);
- uint32_t tx_len = offsetof(host_scan_rsp_t, addr) + host_scan_rsp.len;
- uart_drv_tx((void *)&host_scan_rsp, offsetof(host_scan_rsp_t, addr) + host_scan_rsp.len);
+}
+
+void host_connected_cb(void)
+{
+ success_ack();
}
static void host_cmd_exec_task(void *p_arg)
@@ -240,26 +266,32 @@ static void host_cmd_exec_task(void *p_arg)
for (;;)
{
static uint8_t buf[256] = { 0 };
- host_command_t *p_cmd = (void *)buf;
+ host_ins_t *p_ins = (void *)buf;
- p_cmd->raw.opcode = CMD_NULL;
- p_cmd->raw.len = 0;
+ p_ins->raw.opcode = INS_IDLE;
+ p_ins->raw.len = 0;
size_t recv = xMessageBufferReceive(host_cmd_msg, buf, sizeof(buf), portMAX_DELAY);
- switch (p_cmd->raw.opcode)
+ switch (p_ins->raw.opcode)
{
- case CMD_SURVIVE:
- on_survive(&p_cmd->survive);
+ case INS_SCAN:
+ on_ins_scan(&p_ins->scan);
break;
- case CMD_CONNECT:
- on_connect(&p_cmd->connect);
+ case INS_CONNECT:
+ on_ins_connect(&p_ins->connect);
break;
- case CMD_DISCONNECT:
- on_disconnect(&p_cmd->disconnect);
+ case INS_WRITE_CHAR:
+ on_ins_write_char(&p_ins->write_char);
break;
- case CMD_SCAN:
- on_scan(&p_cmd->scan);
+ case INS_READ_CHAR:
+ on_ins_read_char(&p_ins->read_char);
+ break;
+ case INS_DISCONNECT:
+ on_ins_disconnect(&p_ins->disconnect);
+ break;
+ case INS_CHECK_SURVIVE:
+ on_ins_survive(&p_ins->survive);
break;
default:
break;
@@ -278,29 +310,37 @@ static void host_cmd_recv_task(void *p_arg)
while (offset < recv)
{
- host_command_t *p_cmd = (void *)&buf[offset];
+ host_ins_t *p_ins = (void *)&buf[offset];
taskENTER_CRITICAL();
- if (p_cmd->raw.payload[p_cmd->raw.len] == CMD_SUFFIX)
+ if (p_ins->raw.payload[p_ins->raw.len] == INST_SUFFIX)
{
- switch (p_cmd->raw.opcode)
+ switch (p_ins->raw.opcode)
{
- case CMD_SURVIVE:
- xMessageBufferSend(host_cmd_msg, p_cmd, sizeof(host_cmd_survive_t), pdMS_TO_TICKS(0));
- offset += sizeof(host_cmd_survive_t);
+ case INS_CHECK_SURVIVE:
+ xMessageBufferSend(host_cmd_msg, p_ins, sizeof(ins_survive_t), pdMS_TO_TICKS(0));
+ offset += sizeof(ins_survive_t);
break;
- case CMD_CONNECT:
- xMessageBufferSend(host_cmd_msg, p_cmd, sizeof(host_cmd_connect_t), pdMS_TO_TICKS(0));
- offset += sizeof(host_cmd_connect_t);
+ case INS_CONNECT:
+ xMessageBufferSend(host_cmd_msg, p_ins, sizeof(ins_connect_t), pdMS_TO_TICKS(0));
+ offset += sizeof(ins_connect_t);
break;
- case CMD_DISCONNECT:
- xMessageBufferSend(host_cmd_msg, p_cmd, sizeof(host_cmd_disconnect_t), pdMS_TO_TICKS(0));
- offset += sizeof(host_cmd_disconnect_t);
+ case INS_DISCONNECT:
+ xMessageBufferSend(host_cmd_msg, p_ins, sizeof(ins_disconnect_t), pdMS_TO_TICKS(0));
+ offset += sizeof(ins_disconnect_t);
break;
- case CMD_SCAN:
- xMessageBufferSend(host_cmd_msg, p_cmd, sizeof(host_cmd_scan_t), pdMS_TO_TICKS(0));
- offset += sizeof(host_cmd_scan_t);
+ case INS_SCAN:
+ xMessageBufferSend(host_cmd_msg, p_ins, sizeof(ins_scan_t), pdMS_TO_TICKS(0));
+ offset += sizeof(ins_scan_t);
+ break;
+ case INS_READ_CHAR:
+ xMessageBufferSend(host_cmd_msg, p_ins, sizeof(ins_read_char_t), pdMS_TO_TICKS(0));
+ offset += sizeof(ins_read_char_t);
+ break;
+ case INS_WRITE_CHAR:
+ xMessageBufferSend(host_cmd_msg, p_ins, offsetof(ins_write_char_t, handle) + p_ins->write_char.len, pdMS_TO_TICKS(0));
+ offset += offsetof(ins_write_char_t, handle) + p_ins->write_char.len;
break;
default:
offset++;
@@ -322,10 +362,9 @@ static void host_tasks_handler(ble_evt_t const *p_ble_evt, void *p_context)
switch (p_ble_evt->header.evt_id)
{
case BLE_GAP_EVT_CONNECTED:
- connect_ack();
break;
case BLE_GAP_EVT_DISCONNECTED:
- disconnect_ack();
+ success_ack();
break;
default:
break;
@@ -336,7 +375,7 @@ void host_tasks_init(void)
{
host_cmd_msg = xMessageBufferCreate(1024);
xTaskCreate(host_cmd_recv_task, "cmd_recv", 128, NULL, 5, NULL);
- xTaskCreate(host_cmd_exec_task, "cmd_exec", 512, NULL, 2, NULL);
+ xTaskCreate(host_cmd_exec_task, "cmd_exec", 512, NULL, 3, NULL);
// Register a handler for BLE events.
NRF_SDH_BLE_OBSERVER(m_tasks_observer, 3, host_tasks_handler, NULL);
}
diff --git a/le_db_discovery.c b/le_db_discovery.c
index 6681667..7f45723 100644
--- a/le_db_discovery.c
+++ b/le_db_discovery.c
@@ -26,8 +26,8 @@ static void db_disc_handler(ble_db_discovery_evt_t *p_evt)
NRF_LOG_INFO("BLE_DB_DISCOVERY_COMPLETE");
extern void le_dis_c_on_db_disc_evt(ble_db_discovery_evt_t * p_evt);
le_dis_c_on_db_disc_evt(p_evt);
- extern void le_eis_c_on_db_disc_evt(ble_db_discovery_evt_t * p_evt);
- le_eis_c_on_db_disc_evt(p_evt);
+ extern void le_gatt_c_on_db_disc_evt(ble_db_discovery_evt_t * p_evt);
+ le_gatt_c_on_db_disc_evt(p_evt);
break;
case BLE_DB_DISCOVERY_ERROR:
NRF_LOG_INFO("BLE_DB_DISCOVERY_ERROR");
@@ -37,6 +37,8 @@ static void db_disc_handler(ble_db_discovery_evt_t *p_evt)
break;
case BLE_DB_DISCOVERY_AVAILABLE:
NRF_LOG_INFO("BLE_DB_DISCOVERY_AVAILABLE");
+ extern void host_connected_cb(void);
+ host_connected_cb();
break;
default:
break;
diff --git a/le_eis_c.c b/le_eis_c.c
deleted file mode 100644
index 50352f1..0000000
--- a/le_eis_c.c
+++ /dev/null
@@ -1,303 +0,0 @@
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-#include "ble_db_discovery.h"
-#include "ble_gattc.h"
-#include "ble_srv_common.h"
-
-#include "nrf_ble_gq.h"
-
-#include "nrf_log.h"
-#include "nrf_log_ctrl.h"
-#include "nrf_log_default_backends.h"
-
-#include "FreeRTOS.h"
-#include "task.h"
-#include "timers.h"
-
-#ifdef __cplusplus
-}
-#endif
-
-/**< Used vendor specific UUID. */
-#define BLE_EIS_BASE_UUID \
- { \
- 0x4D, 0x3C, 0x56, 0x45, 0x12, 0x8B, 0x44, 0x1D, 0x8D, 0x6F, 0xC5, 0x95, 0x00, 0x00, 0x9B, 0xD8 \
- }
-#define BLE_UUID_EIS_SERVICE 0x0001
-#define BLE_UUID_EIS_REGULAR_DATA_CHAR 0x0002
-#define BLE_UUID_EIS_LOW_FREQ_DATA_CHAR 0x0003
-#define BLE_UUID_EIS_AUXILIARY_DATA_CHAR 0x0004
-#define BLE_UUID_EIS_STATUS_CHAR 0x0005
-#define BLE_UUID_EIS_EVENT_CHAR 0x0006
-
-struct ble_eis_c_s
-{
- uint16_t conn_handle;
- void (*evt_handler)(ble_evt_t const *p_ble_evt, void *p_context);
- uint16_t regular_data_char_handle;
- uint16_t low_freq_data_char_handle;
- uint16_t auxiliary_data_char_handle;
- uint16_t status_char_handle;
- uint16_t event_char_handle;
-};
-
-typedef struct ble_eis_c_s ble_eis_c_t;
-
-static ble_eis_c_t m_eis_c;
-
-static void on_disconnected(ble_eis_c_t *p_ble_eis_c, ble_evt_t const *p_ble_evt)
-{
- p_ble_eis_c->conn_handle = BLE_CONN_HANDLE_INVALID;
- p_ble_eis_c->regular_data_char_handle = BLE_GATT_HANDLE_INVALID;
- p_ble_eis_c->auxiliary_data_char_handle = BLE_GATT_HANDLE_INVALID;
- p_ble_eis_c->status_char_handle = BLE_GATT_HANDLE_INVALID;
- p_ble_eis_c->event_char_handle = BLE_GATT_HANDLE_INVALID;
-}
-
-static uint32_t hvx_cnt = 0;
-static TickType_t hvx_begin = 0;
-static void on_connected(ble_eis_c_t *p_ble_eis_c, ble_evt_t const *p_ble_evt)
-{
- hvx_cnt = 0;
- hvx_begin = 0;
-}
-
-static void on_hvx(ble_eis_c_t *p_ble_eis_c, ble_evt_t const *p_ble_evt)
-{
- hvx_cnt++;
- if (hvx_begin == 0)
- {
- hvx_begin = xTaskGetTickCount();
- }
- else
- {
- static char str[64];
- float kb = 8 * hvx_cnt * 240 / 1024.0;
- float timespan = (xTaskGetTickCount() - hvx_begin) / 1000.0;
- snprintf(str, sizeof(str), "%s(): %.2fkbps", __FUNCTION__, kb / timespan);
- NRF_LOG_INFO("%s", str);
- }
-}
-
-static void on_read_rsp(ble_eis_c_t *p_ble_eis_c, ble_evt_t const *p_ble_evt)
-{
-}
-
-ret_code_t le_eis_ccdc_configure(uint16_t conn_handle, uint16_t char_handle, bool notification_enable)
-{
- if (conn_handle == BLE_CONN_HANDLE_INVALID)
- {
- __BKPT(255);
- return NRF_ERROR_INVALID_PARAM;
- }
-
- if (char_handle == BLE_GATT_HANDLE_INVALID)
- {
- __BKPT(255);
- return NRF_ERROR_INVALID_PARAM;
- }
-
- NRF_LOG_INFO("Configuring CCCD Handle = 0x%04X, Connection Handle = 0x%04X",
- char_handle + 1,
- conn_handle);
-
- nrf_ble_gq_req_t cccd_req;
- uint16_t cccd_val = notification_enable ? BLE_GATT_HVX_NOTIFICATION : BLE_GATT_HVX_INVALID;
- uint8_t cccd[BLE_CCCD_VALUE_LEN];
-
- cccd[0] = LSB_16(cccd_val);
- cccd[1] = MSB_16(cccd_val);
-
- memset(&cccd_req, 0, sizeof(nrf_ble_gq_req_t));
-
- cccd_req.type = NRF_BLE_GQ_REQ_GATTC_WRITE;
- cccd_req.params.gattc_write.handle = char_handle + 1;
- cccd_req.params.gattc_write.len = BLE_CCCD_VALUE_LEN;
- cccd_req.params.gattc_write.offset = 0;
- cccd_req.params.gattc_write.p_value = cccd;
- cccd_req.params.gattc_write.write_op = BLE_GATT_OP_WRITE_REQ;
-
- extern nrf_ble_gq_t *le_gap_queue(void);
- return nrf_ble_gq_item_add(le_gap_queue(), &cccd_req, conn_handle);
-}
-
-static void le_eis_c_evt_handler(ble_evt_t const *p_ble_evt, void *p_context)
-{
- ble_eis_c_t *p_ble_eis_c = (ble_eis_c_t *)p_context;
-
- if ((p_ble_eis_c == NULL) || (p_ble_evt == NULL))
- {
- return;
- }
-
- switch (p_ble_evt->header.evt_id)
- {
- case BLE_GAP_EVT_DISCONNECTED:
- on_disconnected(p_ble_eis_c, p_ble_evt);
- break;
- case BLE_GAP_EVT_CONNECTED:
- on_connected(p_ble_eis_c, p_ble_evt);
- break;
- case BLE_GATTC_EVT_HVX:
- /*
- Handle Value Notification or Indication event.
- Confirm indication with @ref sd_ble_gattc_hv_confirm.
- See @ref ble_gattc_evt_hvx_t. */
- on_hvx(p_ble_eis_c, p_ble_evt);
- break;
-
- case BLE_GATTC_EVT_READ_RSP:
- /*
- Read Response event.
- See @ref ble_gattc_evt_read_rsp_t. */
- on_read_rsp(p_ble_eis_c, p_ble_evt);
- break;
-
- case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
- /*
- Primary Service Discovery Response event.
- See @ref ble_gattc_evt_prim_srvc_disc_rsp_t. */
- break;
- case BLE_GATTC_EVT_REL_DISC_RSP:
- /*
- Relationship Discovery Response event.
- See @ref ble_gattc_evt_rel_disc_rsp_t. */
- __BKPT(255);
- break;
- case BLE_GATTC_EVT_CHAR_DISC_RSP:
- /*
- Characteristic Discovery Response event.
- See @ref ble_gattc_evt_char_disc_rsp_t. */
- break;
- case BLE_GATTC_EVT_DESC_DISC_RSP:
- /*
- Descriptor Discovery Response event.
- See @ref ble_gattc_evt_desc_disc_rsp_t. */
- break;
- case BLE_GATTC_EVT_ATTR_INFO_DISC_RSP:
- /*
- Attribute Information Response event.
- See @ref ble_gattc_evt_attr_info_disc_rsp_t. */
- __BKPT(255);
- break;
- case BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP:
- /*
- Read By UUID Response event.
- See @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t. */
- __BKPT(255);
- break;
- case BLE_GATTC_EVT_CHAR_VALS_READ_RSP:
- /*
- Read multiple Response event.
- See @ref ble_gattc_evt_char_vals_read_rsp_t. */
- __BKPT(255);
- break;
- case BLE_GATTC_EVT_WRITE_RSP:
- /*
- Write Response event.
- See @ref ble_gattc_evt_write_rsp_t. */
- break;
- case BLE_GATTC_EVT_EXCHANGE_MTU_RSP:
- /*
- Exchange MTU Response event.
- See @ref ble_gattc_evt_exchange_mtu_rsp_t. */
- break;
- case BLE_GATTC_EVT_TIMEOUT:
- /*
- Timeout event.
- See @ref ble_gattc_evt_timeout_t. */
- __BKPT(255);
- break;
- case BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE:
- /*
- Write without Response transmission complete. */
- __BKPT(255);
- break;
- default:
- // No implementation needed.
- break;
- }
-}
-
-void le_eis_c_cccd_timer_cb(TimerHandle_t xTimer)
-{
- xTimerStop(xTimer, pdMS_TO_TICKS(0));
- le_eis_ccdc_configure(m_eis_c.conn_handle, m_eis_c.regular_data_char_handle, true);
- le_eis_ccdc_configure(m_eis_c.conn_handle, m_eis_c.low_freq_data_char_handle, true);
- le_eis_ccdc_configure(m_eis_c.conn_handle, m_eis_c.auxiliary_data_char_handle, true);
- le_eis_ccdc_configure(m_eis_c.conn_handle, m_eis_c.status_char_handle, true);
- le_eis_ccdc_configure(m_eis_c.conn_handle, m_eis_c.event_char_handle, true);
- NRF_LOG_INFO("Enable notifications. ");
-}
-
-static TimerHandle_t le_eis_c_cccd_timer = NULL;
-
-void le_eis_c_init(void)
-{
- m_eis_c.evt_handler = le_eis_c_evt_handler;
- m_eis_c.conn_handle = BLE_CONN_HANDLE_INVALID;
- m_eis_c.regular_data_char_handle = BLE_GATT_HANDLE_INVALID;
- m_eis_c.auxiliary_data_char_handle = BLE_GATT_HANDLE_INVALID;
- m_eis_c.status_char_handle = BLE_GATT_HANDLE_INVALID;
- m_eis_c.event_char_handle = BLE_GATT_HANDLE_INVALID;
- ble_uuid128_t base_uuid = { .uuid128 = BLE_EIS_BASE_UUID };
- ret_code_t err_code;
- uint8_t uuid_type;
- ble_uuid_t eis_uuid = {
- .type = BLE_UUID_TYPE_UNKNOWN,
- .uuid = BLE_UUID_EIS_SERVICE,
- };
- err_code = sd_ble_uuid_vs_add(&base_uuid, &eis_uuid.type);
- ble_db_discovery_evt_register(&eis_uuid);
-
- NRF_SDH_BLE_OBSERVER(m_eis_c_observer, BLE_DIS_C_BLE_OBSERVER_PRIO, le_eis_c_evt_handler, &m_eis_c);
-
- le_eis_c_cccd_timer = xTimerCreate("Timer", pdMS_TO_TICKS(1000), pdTRUE, (void *)0, le_eis_c_cccd_timer_cb);
-}
-
-void le_eis_c_on_db_disc_evt(ble_db_discovery_evt_t *p_evt)
-{
- ble_gatt_db_char_t *p_chars = p_evt->params.discovered_db.charateristics;
-
- // Check if the service discovery is necessary for the link and if the event handler is present.
- if (m_eis_c.evt_handler == NULL || m_eis_c.conn_handle == p_evt->conn_handle)
- {
- return;
- }
-
- // Check if the eis service was discovered.
- if ((p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE) &&
- (p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_EIS_SERVICE) &&
- (p_evt->params.discovered_db.srv_uuid.type == BLE_UUID_TYPE_VENDOR_BEGIN))
- {
- m_eis_c.conn_handle = p_evt->conn_handle;
-
- for (uint32_t i = 0; i < p_evt->params.discovered_db.char_count; i++)
- {
- switch (p_chars[i].characteristic.uuid.uuid)
- {
- case BLE_UUID_EIS_REGULAR_DATA_CHAR:
- m_eis_c.regular_data_char_handle = p_chars[i].characteristic.handle_value;
- break;
- case BLE_UUID_EIS_LOW_FREQ_DATA_CHAR:
- m_eis_c.low_freq_data_char_handle = p_chars[i].characteristic.handle_value;
- break;
- case BLE_UUID_EIS_AUXILIARY_DATA_CHAR:
- m_eis_c.auxiliary_data_char_handle = p_chars[i].characteristic.handle_value;
- break;
- case BLE_UUID_EIS_STATUS_CHAR:
- m_eis_c.status_char_handle = p_chars[i].characteristic.handle_value;
- break;
- case BLE_UUID_EIS_EVENT_CHAR:
- m_eis_c.event_char_handle = p_chars[i].characteristic.handle_value;
- break;
- default:
- break;
- }
- }
- xTimerStart(le_eis_c_cccd_timer, 0);
- }
-}
diff --git a/le_gap.c b/le_gap.c
index f8b09fd..b960676 100644
--- a/le_gap.c
+++ b/le_gap.c
@@ -26,18 +26,48 @@ extern "C"
}
#endif
-void le_gap_init(const char *device_name, uint16_t usAppearance)
+bool is_connected = false;
+
+static void le_gap_handler(ble_evt_t const *p_ble_evt, void *p_context)
{
- // TODO...
+ ret_code_t err_code;
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ is_connected = true;
+ break;
+ case BLE_GAP_EVT_DISCONNECTED:
+ is_connected = false;
+ break;
+ default:
+ break;
+ }
}
-void le_gap_connet(ble_gap_addr_t *p_peer_addr, nrf_ble_scan_t *p_scan)
+void le_gap_init(const char *device_name, uint16_t usAppearance)
+{
+
+ // Register a handler for BLE events.
+ NRF_SDH_BLE_OBSERVER(m_gap_observer, 3, le_gap_handler, NULL);
+}
+
+void le_gap_connet(ble_gap_addr_t *p_peer_addr)
{
// If address is correct, stop scanning and initiate connection with peripheral device.
-
+ const ble_gap_conn_params_t conn_params = {
+ .conn_sup_timeout =
+ (uint16_t)MSEC_TO_UNITS(NRF_BLE_SCAN_SUPERVISION_TIMEOUT, UNIT_10_MS),
+ .min_conn_interval =
+ (uint16_t)MSEC_TO_UNITS(NRF_BLE_SCAN_MIN_CONNECTION_INTERVAL, UNIT_1_25_MS),
+ .max_conn_interval =
+ (uint16_t)MSEC_TO_UNITS(NRF_BLE_SCAN_MAX_CONNECTION_INTERVAL, UNIT_1_25_MS),
+ .slave_latency =
+ (uint16_t)NRF_BLE_SCAN_SLAVE_LATENCY,
+ };
+ extern ble_gap_scan_params_t *le_scan_params(void);
ret_code_t err_code = sd_ble_gap_connect(p_peer_addr,
- &p_scan->scan_params,
- &p_scan->conn_params,
+ le_scan_params(),
+ &conn_params,
APP_BLE_CONN_CFG_TAG);
APP_ERROR_CHECK(err_code);
}
@@ -70,3 +100,8 @@ void le_gap_conn_param_update(uint16_t conn_handle)
};
sd_ble_gap_conn_param_update(conn_handle, &gap_conn_params);
}
+
+bool le_gap_is_connected(void)
+{
+ return is_connected;
+}
diff --git a/le_gatt_c.c b/le_gatt_c.c
new file mode 100644
index 0000000..88f35ff
--- /dev/null
+++ b/le_gatt_c.c
@@ -0,0 +1,375 @@
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "ble_db_discovery.h"
+#include "ble_gattc.h"
+#include "ble_srv_common.h"
+
+#include "nrf_ble_gq.h"
+
+#include "nrf_log.h"
+#include "nrf_log_ctrl.h"
+#include "nrf_log_default_backends.h"
+
+#include "FreeRTOS.h"
+#include "task.h"
+#include "timers.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+extern nrf_ble_gq_t *le_gap_queue(void);
+
+struct ble_gatt_c_s
+{
+ uint16_t conn_handle;
+ void (*evt_handler)(ble_evt_t const *p_ble_evt, void *p_context);
+ union
+ {
+ uint16_t char_handles[5];
+ struct
+ {
+ uint16_t regular_data_char_handle;
+ uint16_t low_freq_data_char_handle;
+ uint16_t auxiliary_data_char_handle;
+ uint16_t status_char_handle;
+ uint16_t event_char_handle;
+ };
+ };
+};
+
+uint16_t handle_mapping[5];
+
+typedef struct ble_gatt_c_s ble_gatt_c_t;
+
+static ble_gatt_c_t m_gatt_c;
+
+static void on_disconnected(ble_gatt_c_t *p_ble_gatt_c, ble_evt_t const *p_ble_evt)
+{
+ p_ble_gatt_c->conn_handle = BLE_CONN_HANDLE_INVALID;
+ p_ble_gatt_c->regular_data_char_handle = BLE_GATT_HANDLE_INVALID;
+ p_ble_gatt_c->auxiliary_data_char_handle = BLE_GATT_HANDLE_INVALID;
+ p_ble_gatt_c->status_char_handle = BLE_GATT_HANDLE_INVALID;
+ p_ble_gatt_c->event_char_handle = BLE_GATT_HANDLE_INVALID;
+}
+
+static uint32_t hvx_cnt = 0;
+static TickType_t hvx_begin = 0;
+static void on_connected(ble_gatt_c_t *p_ble_gatt_c, ble_evt_t const *p_ble_evt)
+{
+ hvx_cnt = 0;
+ hvx_begin = 0;
+ extern void mem_board_reset(void);
+ mem_board_reset();
+}
+
+static void on_hvx(ble_gatt_c_t *p_ble_gatt_c, ble_evt_t const *p_ble_evt)
+{
+ uint32_t len = p_ble_evt->evt.gattc_evt.params.hvx.len;
+ uint8_t *p = (uint8_t *)p_ble_evt->evt.gattc_evt.params.hvx.data;
+ extern void mem_notify_cb(uint8_t *p, uint32_t len);
+ mem_notify_cb(p, len);
+}
+
+static void on_read_rsp(ble_gatt_c_t *p_le_gatt_c, ble_evt_t const *p_ble_evt)
+{
+ extern void host_read_char_cb(uint8_t * p_data, uint16_t len);
+ uint16_t handle = p_ble_evt->evt.gattc_evt.params.read_rsp.handle;
+
+ for (int i = 0; i < COUNTOF(p_le_gatt_c->char_handles); i++)
+ {
+ if (handle_mapping[i] == handle)
+ {
+ ble_gattc_evt_read_rsp_t const *p_response = &p_ble_evt->evt.gattc_evt.params.read_rsp;
+ host_read_char_cb((uint8_t *)p_response->data, p_response->len);
+ break;
+ }
+ }
+}
+
+ret_code_t le_gatt_ccdc_configure(uint16_t conn_handle, uint16_t char_handle, bool notification_enable)
+{
+ if (conn_handle == BLE_CONN_HANDLE_INVALID)
+ {
+ __BKPT(255);
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ if (char_handle == BLE_GATT_HANDLE_INVALID)
+ {
+ __BKPT(255);
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ NRF_LOG_INFO("Configuring CCCD Handle = 0x%04X, Connection Handle = 0x%04X",
+ char_handle + 1,
+ conn_handle);
+
+ nrf_ble_gq_req_t cccd_req;
+ uint16_t cccd_val = notification_enable ? BLE_GATT_HVX_NOTIFICATION : BLE_GATT_HVX_INVALID;
+ uint8_t cccd[BLE_CCCD_VALUE_LEN];
+
+ cccd[0] = LSB_16(cccd_val);
+ cccd[1] = MSB_16(cccd_val);
+
+ memset(&cccd_req, 0, sizeof(nrf_ble_gq_req_t));
+
+ cccd_req.type = NRF_BLE_GQ_REQ_GATTC_WRITE;
+ cccd_req.params.gattc_write.handle = char_handle + 1;
+ cccd_req.params.gattc_write.len = BLE_CCCD_VALUE_LEN;
+ cccd_req.params.gattc_write.offset = 0;
+ cccd_req.params.gattc_write.p_value = cccd;
+ cccd_req.params.gattc_write.write_op = BLE_GATT_OP_WRITE_REQ;
+
+ return nrf_ble_gq_item_add(le_gap_queue(), &cccd_req, conn_handle);
+}
+
+static void le_gatt_c_evt_handler(ble_evt_t const *p_ble_evt, void *p_context)
+{
+ ble_gatt_c_t *p_ble_gatt_c = (ble_gatt_c_t *)p_context;
+
+ if ((p_ble_gatt_c == NULL) || (p_ble_evt == NULL))
+ {
+ return;
+ }
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_DISCONNECTED:
+ on_disconnected(p_ble_gatt_c, p_ble_evt);
+ break;
+ case BLE_GAP_EVT_CONNECTED:
+ on_connected(p_ble_gatt_c, p_ble_evt);
+ break;
+ case BLE_GATTC_EVT_HVX:
+ /*
+ Handle Value Notification or Indication event.
+ Confirm indication with @ref sd_ble_gattc_hv_confirm.
+ See @ref ble_gattc_evt_hvx_t. */
+ on_hvx(p_ble_gatt_c, p_ble_evt);
+ break;
+
+ case BLE_GATTC_EVT_READ_RSP:
+ /*
+ Read Response event.
+ See @ref ble_gattc_evt_read_rsp_t. */
+ on_read_rsp(p_ble_gatt_c, p_ble_evt);
+ break;
+
+ case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
+ /*
+ Primary Service Discovery Response event.
+ See @ref ble_gattc_evt_prim_srvc_disc_rsp_t. */
+ break;
+ case BLE_GATTC_EVT_REL_DISC_RSP:
+ /*
+ Relationship Discovery Response event.
+ See @ref ble_gattc_evt_rel_disc_rsp_t. */
+ __BKPT(255);
+ break;
+ case BLE_GATTC_EVT_CHAR_DISC_RSP:
+ /*
+ Characteristic Discovery Response event.
+ See @ref ble_gattc_evt_char_disc_rsp_t. */
+ break;
+ case BLE_GATTC_EVT_DESC_DISC_RSP:
+ /*
+ Descriptor Discovery Response event.
+ See @ref ble_gattc_evt_desc_disc_rsp_t. */
+ break;
+ case BLE_GATTC_EVT_ATTR_INFO_DISC_RSP:
+ /*
+ Attribute Information Response event.
+ See @ref ble_gattc_evt_attr_info_disc_rsp_t. */
+ __BKPT(255);
+ break;
+ case BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP:
+ /*
+ Read By UUID Response event.
+ See @ref ble_gattc_evt_char_val_by_uuid_read_rsp_t. */
+ __BKPT(255);
+ break;
+ case BLE_GATTC_EVT_CHAR_VALS_READ_RSP:
+ /*
+ Read multiple Response event.
+ See @ref ble_gattc_evt_char_vals_read_rsp_t. */
+ __BKPT(255);
+ break;
+ case BLE_GATTC_EVT_WRITE_RSP:
+ /*
+ Write Response event.
+ See @ref ble_gattc_evt_write_rsp_t. */
+ break;
+ case BLE_GATTC_EVT_EXCHANGE_MTU_RSP:
+ /*
+ Exchange MTU Response event.
+ See @ref ble_gattc_evt_exchange_mtu_rsp_t. */
+ break;
+ case BLE_GATTC_EVT_TIMEOUT:
+ /*
+ Timeout event.
+ See @ref ble_gattc_evt_timeout_t. */
+ __BKPT(255);
+ break;
+ case BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE:
+ /*
+ Write without Response transmission complete. */
+ __BKPT(255);
+ break;
+ default:
+ // No implementation needed.
+ break;
+ }
+}
+
+void le_gatt_c_cccd_timer_cb(TimerHandle_t xTimer)
+{
+ xTimerStop(xTimer, pdMS_TO_TICKS(0));
+ le_gatt_ccdc_configure(m_gatt_c.conn_handle, m_gatt_c.regular_data_char_handle, true);
+ le_gatt_ccdc_configure(m_gatt_c.conn_handle, m_gatt_c.low_freq_data_char_handle, true);
+ le_gatt_ccdc_configure(m_gatt_c.conn_handle, m_gatt_c.auxiliary_data_char_handle, true);
+ le_gatt_ccdc_configure(m_gatt_c.conn_handle, m_gatt_c.status_char_handle, true);
+ le_gatt_ccdc_configure(m_gatt_c.conn_handle, m_gatt_c.event_char_handle, true);
+ NRF_LOG_INFO("Enable notifications. ");
+}
+
+static TimerHandle_t le_gatt_c_cccd_timer = NULL;
+
+void le_gatt_c_init(void)
+{
+ m_gatt_c.evt_handler = le_gatt_c_evt_handler;
+ m_gatt_c.conn_handle = BLE_CONN_HANDLE_INVALID;
+ m_gatt_c.regular_data_char_handle = BLE_GATT_HANDLE_INVALID;
+ m_gatt_c.auxiliary_data_char_handle = BLE_GATT_HANDLE_INVALID;
+ m_gatt_c.status_char_handle = BLE_GATT_HANDLE_INVALID;
+ m_gatt_c.event_char_handle = BLE_GATT_HANDLE_INVALID;
+ ret_code_t err_code;
+ uint8_t uuid_type;
+ ble_uuid_t uuid = {
+ .type = BLE_UUID_TYPE_BLE,
+ .uuid = BLE_UUID_CUSTOM_SERVICE,
+ };
+ err_code = ble_db_discovery_evt_register(&uuid);
+ APP_ERROR_CHECK(err_code);
+
+ NRF_SDH_BLE_OBSERVER(m_gatt_c_observer, BLE_DIS_C_BLE_OBSERVER_PRIO, le_gatt_c_evt_handler, &m_gatt_c);
+
+ le_gatt_c_cccd_timer = xTimerCreate("Timer", pdMS_TO_TICKS(1000), pdTRUE, (void *)0, le_gatt_c_cccd_timer_cb);
+}
+
+void le_gatt_c_on_db_disc_evt(ble_db_discovery_evt_t *p_evt)
+{
+ ble_gatt_db_char_t *p_chars = p_evt->params.discovered_db.charateristics;
+
+ // Check if the service discovery is necessary for the link and if the event handler is present.
+ if (m_gatt_c.evt_handler == NULL || m_gatt_c.conn_handle == p_evt->conn_handle)
+ {
+ return;
+ }
+
+ // Check if the custom service was discovered.
+ if ((p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE) &&
+ (p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_CUSTOM_SERVICE) &&
+ (p_evt->params.discovered_db.srv_uuid.type == BLE_UUID_TYPE_BLE))
+ {
+ m_gatt_c.conn_handle = p_evt->conn_handle;
+
+ for (uint32_t i = 0; i < p_evt->params.discovered_db.char_count; i++)
+ {
+ switch (p_chars[i].characteristic.uuid.uuid)
+ {
+ case BLE_UUID_REGULAR_DATA_CHAR:
+ m_gatt_c.regular_data_char_handle = p_chars[i].characteristic.handle_value;
+ handle_mapping[0] = m_gatt_c.regular_data_char_handle;
+ break;
+ case BLE_UUID_LOW_FREQ_DATA_CHAR:
+ m_gatt_c.low_freq_data_char_handle = p_chars[i].characteristic.handle_value;
+ handle_mapping[1] = m_gatt_c.low_freq_data_char_handle;
+ break;
+ case BLE_UUID_AUXILIARY_DATA_CHAR:
+ m_gatt_c.auxiliary_data_char_handle = p_chars[i].characteristic.handle_value;
+ handle_mapping[2] = m_gatt_c.auxiliary_data_char_handle;
+ break;
+ case BLE_UUID_STATUS_CHAR:
+ m_gatt_c.status_char_handle = p_chars[i].characteristic.handle_value;
+ handle_mapping[3] = m_gatt_c.status_char_handle;
+ break;
+ case BLE_UUID_EVENT_CHAR:
+ m_gatt_c.event_char_handle = p_chars[i].characteristic.handle_value;
+ handle_mapping[4] = m_gatt_c.event_char_handle;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+}
+
+static void le_gatt_c_error_handler(uint32_t nrf_error, void *p_contex, uint16_t conn_handle)
+{
+ UNUSED_PARAMETER(conn_handle);
+ __BKPT(255);
+}
+
+ret_code_t le_gatt_c_read_char_req(uint32_t handle)
+{
+ ble_gatt_c_t *p_le_gatt_c = &m_gatt_c;
+
+ if (p_le_gatt_c->conn_handle == BLE_CONN_HANDLE_INVALID)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ for (int i = 0; i < COUNTOF(p_le_gatt_c->char_handles); i++)
+ {
+ if (handle_mapping[i] == handle)
+ {
+ nrf_ble_gq_req_t gq_req;
+ memset(&gq_req, 0, sizeof(gq_req));
+ gq_req.type = NRF_BLE_GQ_REQ_GATTC_READ;
+ gq_req.error_handler.cb = le_gatt_c_error_handler;
+ gq_req.error_handler.p_ctx = p_le_gatt_c;
+ gq_req.params.gattc_read.handle = p_le_gatt_c->char_handles[i];
+ return nrf_ble_gq_item_add(le_gap_queue(), &gq_req, p_le_gatt_c->conn_handle);
+ }
+ }
+
+ return NRF_ERROR_INVALID_PARAM;
+}
+
+ret_code_t le_gatt_c_write_req(uint32_t handle, uint8_t const *p_data, uint16_t len)
+{
+ ble_gatt_c_t *p_le_gatt_c = &m_gatt_c;
+
+ if (p_le_gatt_c->conn_handle == BLE_CONN_HANDLE_INVALID)
+ {
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ for (int i = 0; i < COUNTOF(p_le_gatt_c->char_handles); i++)
+ {
+ if (handle_mapping[i] == handle)
+ {
+ nrf_ble_gq_req_t gq_req;
+ memset(&gq_req, 0, sizeof(gq_req));
+ gq_req.type = NRF_BLE_GQ_REQ_GATTC_WRITE;
+ gq_req.error_handler.cb = le_gatt_c_error_handler;
+ gq_req.error_handler.p_ctx = p_le_gatt_c;
+ gq_req.params.gattc_write.handle = p_le_gatt_c->char_handles[i];
+ gq_req.params.gattc_write.p_value = p_data;
+ gq_req.params.gattc_write.len = len;
+ gq_req.params.gattc_write.write_op = BLE_GATT_OP_WRITE_REQ;
+ return nrf_ble_gq_item_add(le_gap_queue(), &gq_req, p_le_gatt_c->conn_handle);
+ }
+ else if (handle_mapping[i] + 1 == handle)
+ {
+ uint16_t enable = *(uint16_t *)p_data & 0x0001;
+ return le_gatt_ccdc_configure(m_gatt_c.conn_handle, handle_mapping[i], enable);
+ }
+ }
+
+ return NRF_ERROR_INVALID_PARAM;
+}
diff --git a/le_scan.c b/le_scan.c
index 75c45bd..691973c 100644
--- a/le_scan.c
+++ b/le_scan.c
@@ -22,14 +22,13 @@ extern "C"
#include "nrf_sdh_freertos.h"
#include "ble_advdata.h"
+#include "ble_gap.h"
#include "nrf_ble_scan.h"
#ifdef __cplusplus
}
#endif
-NRF_BLE_SCAN_DEF(m_scan); /**< Scanning Module instance. */
-
#define MAX_DEV_NAME_LEN ((BLE_GAP_ADV_SET_DATA_SIZE_MAX + 1) - AD_DATA_OFFSET)
static void on_adv_report(ble_gap_evt_adv_report_t const *p_adv_report)
@@ -41,16 +40,6 @@ static void on_adv_report(ble_gap_evt_adv_report_t const *p_adv_report)
char dev_name[MAX_DEV_NAME_LEN];
memset(dev_name, 0x00, MAX_DEV_NAME_LEN);
- // Search for advertising manufacturer spec data
- uint32_t manu_spec_data_len = ble_advdata_search(p_adv_report->data.p_data,
- p_adv_report->data.len,
- &offset,
- BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA);
- if (manu_spec_data_len)
- {
- p_manu_spec_data = &p_adv_report->data.p_data[offset];
- }
-
// Search for advertising names.
uint32_t device_name_len = ble_advdata_search(p_adv_report->data.p_data,
p_adv_report->data.len,
@@ -61,6 +50,17 @@ static void on_adv_report(ble_gap_evt_adv_report_t const *p_adv_report)
uint8_t *p = (uint8_t *)p_adv_report->data.p_data;
memcpy(dev_name, &p[offset], device_name_len);
}
+
+ // Search for advertising manufacturer spec data
+ offset = 0;
+ uint32_t manu_spec_data_len =
+ ble_advdata_search(p_adv_report->data.p_data, p_adv_report->data.len, &offset, BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA);
+
+ if (manu_spec_data_len)
+ {
+ p_manu_spec_data = &p_adv_report->data.p_data[offset];
+ }
+
extern void host_scan_filter_match_cb(
void *p_manu_spec_data,
uint32_t manu_spec_data_len,
@@ -68,6 +68,7 @@ static void on_adv_report(ble_gap_evt_adv_report_t const *p_adv_report)
uint32_t device_name_len,
ble_gap_addr_t const *peer_addr,
int16_t rssi);
+
host_scan_filter_match_cb(
p_manu_spec_data,
manu_spec_data_len,
@@ -77,86 +78,82 @@ static void on_adv_report(ble_gap_evt_adv_report_t const *p_adv_report)
p_adv_report->rssi);
}
-static void scan_evt_handler(scan_evt_t const *p_scan_evt)
+
+
+static uint8_t scan_buffer[BLE_GAP_SCAN_BUFFER_MAX];
+static ble_data_t const adv_report_buffer = { .p_data = scan_buffer,
+ .len = BLE_GAP_SCAN_BUFFER_MAX };
+static ble_uuid_t const filter_uuid = { .type = BLE_UUID_TYPE_BLE, .uuid = 0xFFF0 };
+
+static uint64_t mac = 0;
+void le_scan_handler(ble_evt_t const *p_ble_evt, void *p_context)
{
ret_code_t err_code;
+ ble_gap_evt_adv_report_t const *p_adv_report = &p_ble_evt->evt.gap_evt.params.adv_report;
+ uint16_t data_len = p_ble_evt->evt.gap_evt.params.adv_report.data.len;
+ ble_gap_addr_t const *peer_addr = &p_ble_evt->evt.gap_evt.params.adv_report.peer_addr;
+ uint64_t u64_peer_addr = 0;
+ memcpy(&u64_peer_addr, peer_addr, sizeof(peer_addr->addr));
- switch (p_scan_evt->scan_evt_id)
+ if (ble_advdata_uuid_find(p_adv_report->data.p_data, data_len, &filter_uuid))
{
- case NRF_BLE_SCAN_EVT_CONNECTING_ERROR: {
- /**< Error occurred when establishing the connection.
- In this event, an error is passed from the function call @ref sd_ble_gap_connect. */
- err_code = p_scan_evt->params.connecting_err.err_code;
- APP_ERROR_CHECK(err_code);
+ mac = u64_peer_addr;
+
+ char peer_addr_str[(2 + 1) * BLE_GAP_ADDR_LEN + 1] = { 0 };
+
+ if (peer_addr)
+ {
+ sprintf(peer_addr_str, "%02X:%02X:%02X:%02X:%02X:%02X", peer_addr->addr[5], peer_addr->addr[4], peer_addr->addr[3], peer_addr->addr[2], peer_addr->addr[1], peer_addr->addr[0]);
}
- break;
- case NRF_BLE_SCAN_EVT_FILTER_MATCH: {
- /**< A filter is matched or all filters are matched in the multifilter mode. */
- on_adv_report(p_scan_evt->params.filter_match.p_adv_report);
- }
- break;
- case NRF_BLE_SCAN_EVT_CONNECTED:
- /**< Connected to device. */
- break;
- case NRF_BLE_SCAN_EVT_WHITELIST_REQUEST:
- /**< Request the whitelist from the main application. For whitelist scanning to work, the whitelist must be set when this event occurs. */
- break;
- case NRF_BLE_SCAN_EVT_WHITELIST_ADV_REPORT:
- /**< Send notification to the main application when a device from the whitelist is found. */
- break;
- case NRF_BLE_SCAN_EVT_NOT_FOUND:
- /**< The filter was not matched for the scan data. */
- break;
- case NRF_BLE_SCAN_EVT_SCAN_TIMEOUT:
- /**< Scan timeout. */
- break;
- default:
- break;
+
+ NRF_LOG_INFO("%s", peer_addr_str);
}
+ else if (mac == u64_peer_addr)
+ {
+ on_adv_report(p_adv_report);
+ }
+
+ sd_ble_gap_scan_start(NULL, &adv_report_buffer);
}
-static char const *m_target_periph_name[] = ELITE_DEVICE_NAME_LIST;
+static ble_gap_scan_params_t scan_params = {
+ .active = 1,
+ .interval = NRF_BLE_SCAN_SCAN_INTERVAL,
+ .window = NRF_BLE_SCAN_SCAN_WINDOW,
+ .filter_policy = BLE_GAP_SCAN_FP_ACCEPT_ALL,
+ .scan_phys = BLE_GAP_PHY_1MBPS,
+ .timeout = BLE_GAP_SCAN_TIMEOUT_UNLIMITED,
+ .channel_mask = {0, 0, 0, 0, 0},
+ .report_incomplete_evts = 0,
+ .extended = 0,
+};
void le_scan_init(void)
{
- ret_code_t err_code;
-
- nrf_ble_scan_init_t init_scan;
- memset(&init_scan, 0, sizeof(init_scan));
- init_scan.connect_if_match = false;
- init_scan.conn_cfg_tag = APP_BLE_CONN_CFG_TAG;
-
- err_code = nrf_ble_scan_init(&m_scan, &init_scan, scan_evt_handler);
- APP_ERROR_CHECK(err_code);
-
- for (int i = 0; i < COUNTOF(m_target_periph_name); i++)
- {
- err_code = nrf_ble_scan_filter_set(&m_scan, SCAN_NAME_FILTER, m_target_periph_name[i]);
- APP_ERROR_CHECK(err_code);
- }
-
- err_code = nrf_ble_scan_filters_enable(&m_scan, NRF_BLE_SCAN_NAME_FILTER, false);
-
- APP_ERROR_CHECK(err_code);
+ // TODO...
}
+bool is_scanning = false;
+
void le_scan_start(void)
{
- ret_code_t ret;
- NRF_LOG_INFO("Start scanning for device name \"%s\", \"%s\".",
- (uint32_t)m_target_periph_name[0],
- (uint32_t)m_target_periph_name[1]);
- ret = nrf_ble_scan_start(&m_scan);
- APP_ERROR_CHECK(ret);
+ if (is_scanning != true)
+ {
+ NRF_LOG_INFO("Start scanning for UUID service 0x%04X.",
+ BLE_UUID_CUSTOM_SERVICE);
+ is_scanning = true;
+ sd_ble_gap_scan_start(&scan_params, &adv_report_buffer);
+ }
}
void le_scan_stop(void)
{
NRF_LOG_INFO("Stop scanning.");
- nrf_ble_scan_stop();
+ sd_ble_gap_scan_stop();
+ is_scanning = false;
}
-const nrf_ble_scan_t *le_scan_obj(void)
+ble_gap_scan_params_t *le_scan_params(void)
{
- return &m_scan;
-}
+ return &scan_params;
+}
\ No newline at end of file
diff --git a/main.c b/main.c
index 27e4327..5cf16d6 100644
--- a/main.c
+++ b/main.c
@@ -40,8 +40,11 @@ static void le_evt_handler(ble_evt_t const *p_ble_evt, void *p_context)
ret_code_t err_code;
switch (p_ble_evt->header.evt_id)
{
- case BLE_GAP_EVT_ADV_REPORT:
- break;
+ case BLE_GAP_EVT_ADV_REPORT: {
+ extern void le_scan_handler(ble_evt_t const *p_ble_evt, void *p_context);
+ le_scan_handler(p_ble_evt, p_context);
+ }
+ break;
case BLE_GAP_EVT_PHY_UPDATE:
NRF_LOG_INFO("PHY update procedure is complete.");
break;
@@ -50,7 +53,6 @@ static void le_evt_handler(ble_evt_t const *p_ble_evt, void *p_context)
break;
case BLE_GAP_EVT_CONNECTED:
NRF_LOG_INFO("Connected to peer.");
- le_scan_stop();
le_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle);
le_gap_conn_param_update(p_ble_evt->evt.gap_evt.conn_handle);
le_db_discovery_start(p_ble_evt->evt.gap_evt.conn_handle);
@@ -62,7 +64,8 @@ static void le_evt_handler(ble_evt_t const *p_ble_evt, void *p_context)
le_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle);
break;
case BLE_GATTS_EVT_SYS_ATTR_MISSING: {
- ret_code_t err_code = sd_ble_gatts_sys_attr_set(p_ble_evt->evt.gatts_evt.conn_handle, NULL, 0, 0);
+ ret_code_t err_code = sd_ble_gatts_sys_attr_set(
+ p_ble_evt->evt.gatts_evt.conn_handle, NULL, 0, 0);
APP_ERROR_CHECK(err_code);
}
break;
@@ -104,17 +107,17 @@ static void initialize(void *p_context)
extern void uart_drv_init(void);
uart_drv_init();
- extern void sram_drv_init(void);
- sram_drv_init();
-
+ extern void mem_board_init(void);
+ mem_board_init();
+
extern void le_db_discovery_init(void);
le_db_discovery_init();
extern void le_dis_c_init(void);
le_dis_c_init();
- extern void le_eis_c_init(void);
- le_eis_c_init();
+ extern void le_gatt_c_init(void);
+ le_gatt_c_init();
extern void le_gap_init(void);
le_gap_init();
@@ -131,7 +134,7 @@ static void initialize(void *p_context)
int main(void)
{
- NRF_LOG_INIT(NULL, 0);
+ NRF_LOG_INIT(xTaskGetTickCount, configTICK_RATE_HZ);
NRF_LOG_DEFAULT_BACKENDS_INIT();
NRF_LOG_INFO("%s Build: %s %s", LE_DEVICE_NAME, __TIME__, __DATE__);
diff --git a/mem_drv.c b/mem_drv.c
new file mode 100644
index 0000000..4a15802
--- /dev/null
+++ b/mem_drv.c
@@ -0,0 +1,290 @@
+#include
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include "nrf_gpio.h"
+#include "nrf_gpiote.h"
+#include "nrf_spim.h"
+
+#include "FreeRTOS.h"
+#include "message_buffer.h"
+#include "semphr.h"
+#include "stream_buffer.h"
+#include "task.h"
+
+#include "nrf_log.h"
+#include "nrf_log_ctrl.h"
+#include "nrf_log_default_backends.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#define MEM_SEL_PIN NRF_GPIO_PIN_MAP(1, 9)
+#define MEM_BZY_PIN NRF_GPIO_PIN_MAP(0, 8)
+#define MEM_REQ_PIN NRF_GPIO_PIN_MAP(0, 6)
+
+#define RAM_SEL_PIN NRF_GPIO_PIN_MAP(0, 5)
+
+#define MEM_TEST_01_PIN NRF_GPIO_PIN_MAP(0, 26)
+#define MEM_TEST_02_PIN NRF_GPIO_PIN_MAP(0, 17)
+#define MEM_TEST_03_PIN NRF_GPIO_PIN_MAP(0, 21)
+#define MEM_TEST_04_PIN NRF_GPIO_PIN_MAP(0, 19)
+#define MEM_TEST_05_PIN NRF_GPIO_PIN_MAP(0, 22)
+
+#define MEM_SEL_GPIOTE_ID 0
+#define MEM_REQ_GPIOTE_ID 1
+
+#define MEM_DATA_UNIT 40
+
+#define MEM_DUMP 0
+
+static int ram_sel = 0;
+
+static SemaphoreHandle_t mem_sel_semphr = NULL;
+static TaskHandle_t mem_drv_task_handle = NULL;
+static StreamBufferHandle_t mem_drv_stream = NULL;
+
+typedef struct
+{
+ struct
+ {
+ union
+ {
+ uint32_t val;
+ struct
+ {
+ uint16_t len;
+ uint16_t marker;
+ } __PACKED;
+ } header[3];
+ } green_frame;
+ uint8_t red_frame[2048];
+} mem_data_t;
+mem_data_t mem_data;
+uint32_t mem_notify_cnt = 0;
+uint32_t mem_available_cnt = 0;
+uint32_t mem_req;
+uint32_t mem_sel;
+
+void mem_ram_select(int select)
+{
+ ram_sel = select;
+ switch (ram_sel)
+ {
+ case 0:
+ nrf_gpio_pin_clear(RAM_SEL_PIN);
+ break;
+ case 1:
+ nrf_gpio_pin_set(RAM_SEL_PIN);
+ break;
+ default:
+ break;
+ }
+ NRF_LOG_INFO("Select SRAM: %d", ram_sel);
+}
+
+void mem_ram_toggle(void)
+{
+ mem_ram_select(ram_sel ^ 1);
+}
+
+extern int sram_drv_write(uint32_t addr, void *p_dest, uint32_t len);
+extern int sram_drv_read(uint32_t addr, void *p_dest, uint32_t len);
+
+static bool chk_sram_swtich_evt(uint32_t *new_ram_sel)
+{
+ /************************************************
+ * When the mem_sel is in a low-level state,
+ * the state of mem_req is considered valid.
+ ************************************************/
+ while (mem_sel == false)
+ {
+ vTaskDelay(pdMS_TO_TICKS(5));
+ if (mem_req != ram_sel)
+ {
+ *new_ram_sel = mem_req;
+ return true;
+ }
+ }
+
+ return false;
+}
+static void mem_drv_task(void *p_arg)
+{
+ extern void sram_drv_init(void);
+ sram_drv_init();
+
+ extern void sram_drv_reset(void);
+ for (int i = 0; i < 2; i++)
+ {
+ mem_ram_toggle();
+ sram_drv_reset();
+ }
+
+ for (;;)
+ {
+ uint32_t new_ram_sel;
+
+ xSemaphoreTake(mem_sel_semphr, portMAX_DELAY);
+
+ if (chk_sram_swtich_evt(&new_ram_sel) == false)
+ {
+ NRF_LOG_INFO("no switch sram");
+ continue;
+ }
+
+ NRF_LOG_INFO("found ram sel != mem req, delay 100ms");
+ vTaskDelay(pdMS_TO_TICKS(100));
+
+ uint32_t green_frame_size = sizeof(mem_data.green_frame);
+ uint32_t red_frame_size = 0;
+ uint32_t total_size = 0;
+ if (mem_available_cnt > 3)
+ {
+ /* read red frame data from streambuffer */
+ taskENTER_CRITICAL();
+ mem_available_cnt = 0;
+ red_frame_size = xStreamBufferReceive(mem_drv_stream, mem_data.red_frame, sizeof(mem_data.red_frame), 0);
+ taskEXIT_CRITICAL();
+ }
+
+ /* write green & red frame data to sram */
+ total_size = green_frame_size + red_frame_size;
+ mem_data.green_frame.header[0].len = __REVSH(total_size);
+ mem_data.green_frame.header[0].marker = __REVSH(0xA55A);
+ mem_data.green_frame.header[1].val = mem_data.green_frame.header[0].val;
+ mem_data.green_frame.header[2].val = mem_data.green_frame.header[0].val;
+ sram_drv_write(0x0000, &mem_data, total_size);
+
+ /* switch sram */
+ mem_ram_select(new_ram_sel);
+
+#if MEM_DUMP
+ for (uint32_t i = 0; i < total_size / 32; i++)
+ {
+ uint8_t *p = (uint8_t *)&mem_data;
+ NRF_LOG_HEXDUMP_INFO(&p[i * 32], 32);
+ }
+ if (total_size % 32)
+ {
+ uint8_t *p = (uint8_t *)&mem_data;
+ NRF_LOG_HEXDUMP_INFO(&p[(total_size / 32) * 32], total_size % 32);
+ }
+#endif
+ NRF_LOG_INFO("Write: %d bytes, and switch sram done!!!", total_size);
+ }
+}
+
+void mem_board_reset(void)
+{
+ mem_available_cnt = 0;
+ mem_notify_cnt = 0;
+ xStreamBufferReset(mem_drv_stream);
+}
+
+void mem_notify_cb(uint8_t *p, uint32_t len)
+{
+ /* write red frame data to streambuffer */
+ taskENTER_CRITICAL();
+ static struct
+ {
+ uint8_t prefix;
+ uint8_t cnt;
+ uint8_t len;
+ uint8_t content[64];
+ } swap_buf;
+
+ swap_buf.prefix = 0xFF;
+ swap_buf.cnt = mem_notify_cnt++;
+ swap_buf.len = len;
+ memcpy(swap_buf.content, p, len);
+
+ swap_buf.content[len + 0] = 0;
+ swap_buf.content[len + 1] = 0;
+ swap_buf.content[len + 2] = 0;
+ swap_buf.content[len + 3] = 0;
+ swap_buf.content[len + 4] = 0;
+
+ uint32_t sum = 0;
+ for (int i = 0; i < len; i++)
+ {
+ sum += p[i];
+ }
+ sum += swap_buf.prefix;
+ sum += swap_buf.cnt;
+ sum += swap_buf.len;
+ swap_buf.content[len + 5] = sum & 0xFF;
+ xStreamBufferSend(mem_drv_stream, &swap_buf, 3 + len + 6, 0);
+ mem_available_cnt++;
+ taskEXIT_CRITICAL();
+}
+
+void mem_board_init(void)
+{
+ // Config RAM test pin
+ nrf_gpio_cfg_input(MEM_TEST_01_PIN, NRF_GPIO_PIN_PULLUP);
+ nrf_gpio_cfg_input(MEM_TEST_02_PIN, NRF_GPIO_PIN_PULLUP);
+ nrf_gpio_cfg_input(MEM_TEST_03_PIN, NRF_GPIO_PIN_PULLUP);
+ nrf_gpio_cfg_input(MEM_TEST_04_PIN, NRF_GPIO_PIN_PULLUP);
+ nrf_gpio_cfg_input(MEM_TEST_05_PIN, NRF_GPIO_PIN_PULLUP);
+
+ // Config RAM select pin
+ nrf_gpio_cfg_output(RAM_SEL_PIN);
+ nrf_gpio_pin_clear(RAM_SEL_PIN);
+
+ // Config PI Ctrl pin
+ nrf_gpio_cfg_input(MEM_SEL_PIN, NRF_GPIO_PIN_NOPULL);
+ nrf_gpio_cfg_input(MEM_REQ_PIN, NRF_GPIO_PIN_NOPULL);
+
+ nrf_gpiote_event_configure(MEM_SEL_GPIOTE_ID, MEM_SEL_PIN, NRF_GPIOTE_POLARITY_TOGGLE);
+ nrf_gpiote_event_enable(MEM_SEL_GPIOTE_ID);
+ nrf_gpiote_int_enable(0x01 << MEM_SEL_GPIOTE_ID);
+
+ nrf_gpiote_event_configure(MEM_REQ_GPIOTE_ID, MEM_REQ_PIN, NRF_GPIOTE_POLARITY_TOGGLE);
+ nrf_gpiote_event_enable(MEM_REQ_GPIOTE_ID);
+ nrf_gpiote_int_enable(0x01 << MEM_REQ_GPIOTE_ID);
+
+ // Create Semphr & Task
+ mem_sel_semphr = xSemaphoreCreateBinary();
+ mem_drv_stream = xStreamBufferCreate(MEM_DATA_UNIT * 32, 1);
+ xTaskCreate(mem_drv_task, "mem_drv", 256, NULL, 5, NULL);
+
+ sd_nvic_SetPriority(GPIOTE_IRQn, _PRIO_APP_HIGH);
+ sd_nvic_EnableIRQ(GPIOTE_IRQn);
+}
+
+static void mem_sel_isr(void)
+{
+ mem_sel = nrf_gpio_pin_read(MEM_SEL_PIN);
+ if (mem_sel == 0)
+ {
+ BaseType_t xHigherPriorityTaskWoken;
+ xSemaphoreGiveFromISR(mem_sel_semphr, &xHigherPriorityTaskWoken);
+ portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
+ }
+}
+
+static void mem_req_isr(void)
+{
+ mem_req = nrf_gpio_pin_read(MEM_REQ_PIN);
+}
+
+void GPIOTE_IRQHandler(void)
+{
+ if (NRF_GPIOTE->EVENTS_IN[MEM_SEL_GPIOTE_ID])
+ {
+ NRF_GPIOTE->EVENTS_IN[MEM_SEL_GPIOTE_ID] = 0;
+ mem_sel_isr();
+ return;
+ }
+ if (NRF_GPIOTE->EVENTS_IN[MEM_REQ_GPIOTE_ID])
+ {
+ NRF_GPIOTE->EVENTS_IN[MEM_REQ_GPIOTE_ID] = 0;
+ mem_req_isr();
+ return;
+ }
+}
diff --git a/nrf5x.props b/nrf5x.props
index c0a601e..81a25dd 100644
--- a/nrf5x.props
+++ b/nrf5x.props
@@ -18,7 +18,7 @@
$(BSP_ROOT)/nRF5x/LinkerScripts/nRF52840_XXAA_S140_reserve.lds
$(BSP_ROOT)/nRF5x/SoftdeviceLibraries/hard;$(BSP_ROOT)/nRF5x/LinkerScripts;%(Link.LibrarySearchDirectories)
- --specs=nano.specs -u _printf_float --specs=nosys.specs -mabi=aapcs %(Link.AdditionalOptions)
+ --specs=nano.specs -u _printf_float --specs=nosys.specs -Wl,--no-warn-rwx-segments -mabi=aapcs %(Link.AdditionalOptions)
diff --git a/nrf5x.xml b/nrf5x.xml
index 0f8259b..b56714d 100644
--- a/nrf5x.xml
+++ b/nrf5x.xml
@@ -2,9 +2,9 @@
com.visualgdb.arm-eabi
- 10.3.1
- 10.2.90
- 1
+ 12.2.1
+ 12.2
+ 2
com.sysprogs.arm.nordic.nrf5x
17.0
diff --git a/scripts/host_cmd.py b/scripts/host_cmd.py
index 25c919c..4370974 100644
--- a/scripts/host_cmd.py
+++ b/scripts/host_cmd.py
@@ -7,12 +7,13 @@ def survive_cmd(ser):
send = [0x0A, 0x01, 0xF1]
ser.write(send)
read = ser.read(4)
- print("recv: "+" ".join("%02X" % b for b in read))
+ print("recv: " + " ".join("%02X" % b for b in read))
-def scan_cmd(ser, is_raw_data = True):
+
+def scan_cmd(ser, is_raw_data=True):
send = [0x03, 0x01, 0xF1]
ser.write(send)
- peer_addr = []
+ peer_addr = []
for i in range(10):
hci_packet_event = ser.read(2)
if int.from_bytes(hci_packet_event, "little") != 0x0004:
@@ -36,38 +37,76 @@ def scan_cmd(ser, is_raw_data = True):
print(" hw version: " + " ".join("%02X" % b for b in payload[10:14]))
print(" build time: " + " ".join("%02X" % b for b in payload[14:16]))
print(" Parameter1: " + str(payload[16:19], "utf-8"))
- print(" battery volt: " + str(int.from_bytes(payload[19:21], "big")/1000.0) + "V")
- print(" device name: " + str(payload[21:], "utf-8"))
+ print(
+ " battery volt: "
+ + str(int.from_bytes(payload[19:21], "big") / 1000.0)
+ + "V"
+ )
+ print(" device name: " + str(payload[21:], "utf-8"))
return peer_addr
-def connect(ser, peer_addr = []):
+
+def connect(ser, peer_addr=[]):
send = [0x05, 0x08, 0x00]
send += peer_addr
send += [0xF1]
ser.write(send)
- read = ser.read(7)
- print("recv: "+" ".join("%02X" % b for b in read))
+ read = ser.read(4)
+ print("recv: " + " ".join("%02X" % b for b in read))
+
def disconnect(ser):
send = [0x08, 0x01, 0xF1]
ser.write(send)
read = ser.read(4)
- print("recv: "+" ".join("%02X" % b for b in read))
+ print("recv: " + " ".join("%02X" % b for b in read))
+
+
+def write_char(ser: serial.Serial, handle: int, write_data: tuple):
+ send = [0x06, len(write_data)+2, handle]
+ send += write_data
+ send += [0xF1]
+ ser.write(send)
+
+def read_char(ser: serial.Serial, handle: int):
+ send = [0x07, 0x02, handle, 0xF1]
+ ser.write(send)
+ read = ser.read(0xFFFF)
+ print("recv: " + " ".join("%02X" % b for b in read))
def main():
# set comport
- ser = serial.Serial("COM12", 57600, 8)
+ ser = serial.Serial("COM15", 57600, 8, inter_byte_timeout=0.01)
# send survive cmd
- survive_cmd(ser)
+ survive_cmd(ser)
# send scan cmd
- peer_addr = scan_cmd(ser, False)
-
+ peer_addr = scan_cmd(ser, False)
+ time.sleep(10)
+ return
# send connect cmd with peer addr
connect(ser, peer_addr)
- time.sleep(10)
+ time.sleep(3)
+
+ # send write char to enable notify
+ write_char(ser, 0x0024, [0xc4,0xf0,0xf1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00])
+ time.sleep(0.1)
+ write_char(ser, 0x0024, [0x74,0x10,0xf1,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00])
+ time.sleep(0.1)
+ read_char(ser, 0x0021)
+ # 130500040000000000000000000000000000001c
+ time.sleep(0.2)
+ # send write char to enable notify
+ #write_char(ser, 0x0028, 1)
+ #time.sleep(5)
+
+ # send write char to disable notify
+ #write_char(ser, 0x0028, 0)
+
+ # send read char to disable notify
+ #read_char(ser, 0x0027)
# send disconnect cmd
disconnect(ser)
diff --git a/sram_drv.c b/sram_drv.c
index d1f5dfc..de21fa2 100644
--- a/sram_drv.c
+++ b/sram_drv.c
@@ -29,10 +29,12 @@ extern "C"
#define READ_STATUS_CMD (0b00000101)
#define WRITE_STATUS_CMD (0b00000001)
-#define BYTE_MODE (0b00)
-#define PAGE_MODE (0b10)
-#define SEQ_MODE (0b01)
-#define RESVD_MODE (0b11)
+#define BYTE_MODE (0b00000010)
+#define PAGE_MODE (0b10000010)
+#define SEQ_MODE (0b01000010)
+#define RESVD_MODE (0b11000010)
+
+#define HOLD_DISABLE (0b00000001)
#if (SRAM_DEVICE == SRAM_23K640)
#define SRAM_SIZE (64 * 1024 / 8)
@@ -43,20 +45,14 @@ extern "C"
#endif
#define SRAM_SPIM (NRF_SPIM3)
-#define CS0_PIN NRF_GPIO_PIN_MAP(1, 11)
-#define CS1_PIN NRF_GPIO_PIN_MAP(1, 12)
-#define SCLK_PIN NRF_GPIO_PIN_MAP(1, 13)
-#define MOSI_PIN NRF_GPIO_PIN_MAP(1, 14)
-#define MISO_PIN NRF_GPIO_PIN_MAP(1, 15)
+#define CS_PIN NRF_GPIO_PIN_MAP(0, 7)
+#define SCLK_PIN NRF_GPIO_PIN_MAP(0, 12)
+#define MOSI_PIN NRF_GPIO_PIN_MAP(0, 14)
+#define MISO_PIN NRF_GPIO_PIN_MAP(0, 11)
static SemaphoreHandle_t txrx_end_sem;
static SemaphoreHandle_t sram_mutex;
-const uint8_t cs_bank[SRAM_BANK_NUM] = {
- CS0_PIN,
- CS1_PIN
-};
-
static void write_bytes(void *p, uint32_t len)
{
nrf_spim_tx_buffer_set(SRAM_SPIM, p, len);
@@ -73,6 +69,16 @@ static void read_bytes(void *p, uint32_t len)
xSemaphoreTake(txrx_end_sem, portMAX_DELAY);
}
+static void read_write_bytes(void *tx, uint32_t tx_len, void *rx, uint32_t rx_len)
+{
+ static uint8_t recv[256];
+ nrf_spim_tx_buffer_set(SRAM_SPIM, tx, tx_len);
+ nrf_spim_rx_buffer_set(SRAM_SPIM, recv, tx_len + rx_len);
+ nrf_spim_task_trigger(SRAM_SPIM, NRF_SPIM_TASK_START);
+ xSemaphoreTake(txrx_end_sem, portMAX_DELAY);
+ memcpy(rx, &recv[tx_len], rx_len);
+}
+
static void write_status(uint8_t mode)
{
uint8_t buf[] = {
@@ -80,6 +86,14 @@ static void write_status(uint8_t mode)
};
write_bytes(buf, sizeof(buf));
}
+
+static void read_status(uint8_t *mode)
+{
+ uint8_t send[] = {
+ READ_STATUS_CMD
+ };
+ read_write_bytes(send, sizeof(send), mode, sizeof(*mode));
+}
static void write_inst_addr(uint32_t inst, uint32_t addr)
{
uint8_t buf[] = {
@@ -90,37 +104,57 @@ static void write_inst_addr(uint32_t inst, uint32_t addr)
write_bytes(buf, sizeof(buf));
}
-void sram_drv_write_status(uint32_t bank, uint8_t mode)
+void sram_drv_write_status(uint8_t mode)
{
xSemaphoreTake(sram_mutex, portMAX_DELAY);
- nrf_gpio_pin_clear(cs_bank[bank & 0x01]);
- write_status(mode);
- nrf_gpio_pin_set(cs_bank[bank & 0x01]);
+ nrf_gpio_pin_clear(CS_PIN);
+ write_status(mode | HOLD_DISABLE);
+ nrf_gpio_pin_set(CS_PIN);
xSemaphoreGive(sram_mutex);
}
-int sram_drv_write(uint32_t bank, uint32_t addr, void *p_dest, uint32_t len)
+void sram_drv_read_status(uint8_t *mode)
{
xSemaphoreTake(sram_mutex, portMAX_DELAY);
- nrf_gpio_pin_clear(cs_bank[bank & 0x01]);
+ nrf_gpio_pin_clear(CS_PIN);
+ read_status(mode);
+ nrf_gpio_pin_set(CS_PIN);
+ xSemaphoreGive(sram_mutex);
+}
+int sram_drv_write(uint32_t addr, void *p_dest, uint32_t len)
+{
+ xSemaphoreTake(sram_mutex, portMAX_DELAY);
+ nrf_gpio_pin_clear(CS_PIN);
write_inst_addr(WRITE_CMD, addr);
write_bytes(p_dest, len);
- nrf_gpio_pin_set(cs_bank[bank & 0x01]);
+ nrf_gpio_pin_set(CS_PIN);
xSemaphoreGive(sram_mutex);
return 0;
}
-int sram_drv_read(uint32_t bank, uint32_t addr, void *p_dest, uint32_t len)
+int sram_drv_read(uint32_t addr, void *p_dest, uint32_t len)
{
xSemaphoreTake(sram_mutex, portMAX_DELAY);
- nrf_gpio_pin_clear(cs_bank[bank & 0x01]);
+ nrf_gpio_pin_clear(CS_PIN);
write_inst_addr(READ_CMD, addr);
read_bytes(p_dest, len);
- nrf_gpio_pin_set(cs_bank[bank & 0x01]);
+ nrf_gpio_pin_set(CS_PIN);
xSemaphoreGive(sram_mutex);
return 0;
}
+static uint8_t dummy[32] = { 0 };
+void sram_drv_reset(void)
+{
+ sram_drv_write_status(SEQ_MODE);
+ memset(dummy, 0x00, COUNTOF(dummy));
+ for (int i = 0; i < SRAM_SIZE / COUNTOF(dummy); i++)
+ {
+ uint32_t addr = i * COUNTOF(dummy);
+ sram_drv_write(addr, dummy, sizeof(dummy));
+ }
+}
+
void sram_drv_init(void)
{
txrx_end_sem = xSemaphoreCreateBinary();
@@ -133,12 +167,9 @@ void sram_drv_init(void)
// Config SPI clk pin
nrf_gpio_cfg_output(SCLK_PIN);
nrf_gpio_pin_clear(SCLK_PIN);
- // Config SPI cs0 pin
- nrf_gpio_cfg_output(CS0_PIN);
- nrf_gpio_pin_set(CS0_PIN);
- // Config SPI cs1 pin
- nrf_gpio_cfg_output(CS1_PIN);
- nrf_gpio_pin_set(CS1_PIN);
+ // Config SPI cs pin
+ nrf_gpio_cfg_output(CS_PIN);
+ nrf_gpio_pin_set(CS_PIN);
// Config SPI module
nrf_spim_configure(SRAM_SPIM, NRF_SPIM_MODE_0, NRF_SPIM_BIT_ORDER_MSB_FIRST);
@@ -153,9 +184,6 @@ void sram_drv_init(void)
sd_nvic_SetPriority(SPIM3_IRQn, _PRIO_APP_MID);
sd_nvic_EnableIRQ(SPIM3_IRQn);
nrf_spim_int_enable(SRAM_SPIM, NRF_SPIM_INT_END_MASK);
-
- sram_drv_write_status(0, SEQ_MODE);
- sram_drv_write_status(1, SEQ_MODE);
}
void SPIM3_IRQHandler(void)
diff --git a/syscalls.c b/syscalls.c
new file mode 100644
index 0000000..fadb992
--- /dev/null
+++ b/syscalls.c
@@ -0,0 +1,155 @@
+/**
+ ******************************************************************************
+ * @file syscalls.c
+ * @author Auto-generated by STM32CubeIDE
+ * @brief STM32CubeIDE Minimal System calls file
+ *
+ * For more information about which c-functions
+ * need which of these lowlevel functions
+ * please consult the Newlib libc-manual
+ ******************************************************************************
+ * @attention
+ *
+ * Copyright (c) 2022 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software is licensed under terms that can be found in the LICENSE file
+ * in the root directory of this software component.
+ * If no LICENSE file comes with this software, it is provided AS-IS.
+ *
+ ******************************************************************************
+ */
+
+/* Includes */
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+
+/* Variables */
+extern int __io_putchar(int ch) __attribute__((weak));
+extern int __io_getchar(void) __attribute__((weak));
+
+
+char *__env[1] = { 0 };
+char **environ = __env;
+
+
+/* Functions */
+void initialise_monitor_handles()
+{
+}
+
+int _getpid(void)
+{
+ return 1;
+}
+
+int _kill(int pid, int sig)
+{
+ errno = EINVAL;
+ return -1;
+}
+
+void _exit (int status)
+{
+ _kill(status, -1);
+ while (1) {} /* Make sure we hang here */
+}
+
+__attribute__((weak)) int _read(int file, char *ptr, int len)
+{
+ int DataIdx;
+
+ for (DataIdx = 0; DataIdx < len; DataIdx++)
+ {
+ *ptr++ = __io_getchar();
+ }
+
+return len;
+}
+
+__attribute__((weak)) int _write(int file, char *ptr, int len)
+{
+ int DataIdx;
+
+ for (DataIdx = 0; DataIdx < len; DataIdx++)
+ {
+ __io_putchar(*ptr++);
+ }
+ return len;
+}
+
+int _close(int file)
+{
+ return -1;
+}
+
+
+int _fstat(int file, struct stat *st)
+{
+ st->st_mode = S_IFCHR;
+ return 0;
+}
+
+int _isatty(int file)
+{
+ return 1;
+}
+
+int _lseek(int file, int ptr, int dir)
+{
+ return 0;
+}
+
+int _open(char *path, int flags, ...)
+{
+ /* Pretend like we always fail */
+ return -1;
+}
+
+int _wait(int *status)
+{
+ errno = ECHILD;
+ return -1;
+}
+
+int _unlink(char *name)
+{
+ errno = ENOENT;
+ return -1;
+}
+
+int _times(struct tms *buf)
+{
+ return -1;
+}
+
+int _stat(char *file, struct stat *st)
+{
+ st->st_mode = S_IFCHR;
+ return 0;
+}
+
+int _link(char *old, char *new)
+{
+ errno = EMLINK;
+ return -1;
+}
+
+int _fork(void)
+{
+ errno = EAGAIN;
+ return -1;
+}
+
+int _execve(char *name, char **argv, char **env)
+{
+ errno = ENOMEM;
+ return -1;
+}
diff --git a/uart_drv.c b/uart_drv.c
index ce30ae3..75a2fa9 100644
--- a/uart_drv.c
+++ b/uart_drv.c
@@ -21,8 +21,8 @@ extern "C"
#endif
#define HOST_UART (NRF_UARTE0)
-#define HOST_UART_DRV_TX_PIN 6
-#define HOST_UART_DRV_RX_PIN 8
+#define HOST_UART_DRV_TX_PIN NRF_GPIO_PIN_MAP(0, 4)
+#define HOST_UART_DRV_RX_PIN NRF_GPIO_PIN_MAP(0, 27)
static SemaphoreHandle_t uart_drv_tx_sem;
static SemaphoreHandle_t uart_drv_rx_sem;
@@ -76,7 +76,7 @@ void uart_drv_init(void)
nrf_gpio_cfg_output(HOST_UART_DRV_TX_PIN);
nrf_gpio_cfg_input(HOST_UART_DRV_RX_PIN, NRF_GPIO_PIN_NOPULL);
nrf_uarte_configure(HOST_UART, NRF_UARTE_PARITY_EXCLUDED, NRF_UARTE_HWFC_DISABLED);
- nrf_uarte_baudrate_set(HOST_UART, NRF_UARTE_BAUDRATE_57600);
+ nrf_uarte_baudrate_set(HOST_UART, NRF_UARTE_BAUDRATE_115200);
nrf_uarte_txrx_pins_set(HOST_UART, HOST_UART_DRV_TX_PIN, HOST_UART_DRV_RX_PIN);
nrf_uarte_hwfc_pins_disconnect(HOST_UART);
nrf_uarte_enable(HOST_UART);