Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e9788b10df | |||
| c933e15399 | |||
| ef19d6b72f | |||
| 089114368e | |||
| 27560b237d | |||
| fe55899830 | |||
| 14a4dec57b | |||
| d3812a8b72 | |||
| df70d69851 | |||
| 440f443a99 | |||
| 32f5fee764 | |||
| 7fc5b54c47 | |||
| 370d6cc80f | |||
| d99848592b | |||
| 401c592281 | |||
| 415f4adfe9 | |||
| 9fc58b51fe | |||
| 508ac99c0d | |||
| 6158961dcf | |||
| be584e2900 |
+1
-1
@@ -63,7 +63,7 @@
|
||||
#define configTICK_RATE_HZ 1024
|
||||
#define configMAX_PRIORITIES ( 6 )
|
||||
#define configMINIMAL_STACK_SIZE ( 192 )
|
||||
#define configTOTAL_HEAP_SIZE ( 32 * 1024 )
|
||||
#define configTOTAL_HEAP_SIZE ( 64 * 1024 )
|
||||
#define configMAX_TASK_NAME_LEN ( 16 )
|
||||
#define configUSE_16_BIT_TICKS 0
|
||||
#define configIDLE_SHOULD_YIELD 1
|
||||
|
||||
+15
-15
@@ -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
|
||||
@@ -160,7 +160,7 @@ extern "C"
|
||||
// Determines the supervision time-out in units of 10 millisecond.
|
||||
#define NRF_BLE_SCAN_SUPERVISION_TIMEOUT 4000
|
||||
// Determines minimum connection interval in milliseconds.
|
||||
#define NRF_BLE_SCAN_MIN_CONNECTION_INTERVAL 7.5
|
||||
#define NRF_BLE_SCAN_MIN_CONNECTION_INTERVAL 8
|
||||
// Determines maximum connection interval in milliseconds.
|
||||
#define NRF_BLE_SCAN_MAX_CONNECTION_INTERVAL 20
|
||||
// Determines the slave latency in counts of connection events.
|
||||
@@ -183,15 +183,15 @@ extern "C"
|
||||
|
||||
#define NRF_BLE_GQ_ENABLED 1
|
||||
// Default size of a single element in the pool of memory objects.
|
||||
#define NRF_BLE_GQ_DATAPOOL_ELEMENT_SIZE 20
|
||||
#define NRF_BLE_GQ_DATAPOOL_ELEMENT_SIZE 256
|
||||
// Default number of elements in the pool of memory objects.
|
||||
#define NRF_BLE_GQ_DATAPOOL_ELEMENT_COUNT 8
|
||||
#define NRF_BLE_GQ_DATAPOOL_ELEMENT_COUNT 32
|
||||
// Maximal size of the data inside GATTC write request (in bytes).
|
||||
#define NRF_BLE_GQ_GATTC_WRITE_MAX_DATA_LEN 2
|
||||
#define NRF_BLE_GQ_GATTC_WRITE_MAX_DATA_LEN 256
|
||||
// Maximal size of the data inside GATTC notification or indication request (in bytes).
|
||||
#define NRF_BLE_GQ_GATTS_HVX_MAX_DATA_LEN 16
|
||||
#define NRF_BLE_GQ_GATTS_HVX_MAX_DATA_LEN 256
|
||||
// Queue size for BLE GATT Queue module.
|
||||
#define NRF_BLE_GQ_QUEUE_SIZE 6
|
||||
#define NRF_BLE_GQ_QUEUE_SIZE 256
|
||||
// Priority with which BLE events are dispatched to the GATT Queue module.
|
||||
#define NRF_BLE_GQ_BLE_OBSERVER_PRIO 1
|
||||
|
||||
@@ -212,15 +212,15 @@ extern "C"
|
||||
#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
|
||||
#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 BLE_UUID_CUSTOM_SERVICE 0xFFF0
|
||||
#define BLE_UUID_SIMPLEPROFILECHAR(n) (BLE_UUID_CUSTOM_SERVICE + n)
|
||||
|
||||
// Uart UUID service & char
|
||||
#define BLE_UUID_UART_SERVICE 0xFFF8
|
||||
#define BLE_UUID_UART_CHAR(n) (BLE_UUID_UART_SERVICE + n)
|
||||
|
||||
#define COUNTOF(x) (sizeof(x) / sizeof(x[0]))
|
||||
|
||||
|
||||
@@ -95,15 +95,17 @@
|
||||
<EnableAsyncExecutionMode>false</EnableAsyncExecutionMode>
|
||||
<AsyncModeSupportsBreakpoints>true</AsyncModeSupportsBreakpoints>
|
||||
<TemporaryBreakConsolidationTimeout>0</TemporaryBreakConsolidationTimeout>
|
||||
<BacktraceFrameLimit>0</BacktraceFrameLimit>
|
||||
<EnableNonStopMode>false</EnableNonStopMode>
|
||||
<MaxBreakpointLimit>0</MaxBreakpointLimit>
|
||||
<EnableVerboseMode>true</EnableVerboseMode>
|
||||
<EnablePrettyPrinters>false</EnablePrettyPrinters>
|
||||
<EnableAbsolutePathReporting>true</EnableAbsolutePathReporting>
|
||||
</AdditionalGDBSettings>
|
||||
<DebugMethod>
|
||||
<ID>jlink-jtag</ID>
|
||||
<InterfaceID>com.sysprogs.debug.jlink.jlinksw</InterfaceID>
|
||||
<InterfaceSerialNumber>000682409936</InterfaceSerialNumber>
|
||||
<InterfaceSerialNumber>000601012352</InterfaceSerialNumber>
|
||||
<Configuration xsi:type="com.visualgdb.edp.segger.settings">
|
||||
<CommandLine>-select USB -device $$SYS:MCU_ID$$ -speed auto -if SWD</CommandLine>
|
||||
<ProgramMode>Enabled</ProgramMode>
|
||||
@@ -130,7 +132,7 @@
|
||||
<EndOfStackSymbol>_estack</EndOfStackSymbol>
|
||||
<TimestampProviderTicksPerSecond>0</TimestampProviderTicksPerSecond>
|
||||
<KeepConsoleAfterExit>false</KeepConsoleAfterExit>
|
||||
<UnusedStackFillPattern xsi:nil="true" />
|
||||
<UnusedStackFillPattern>2779096485</UnusedStackFillPattern>
|
||||
<CheckInterfaceDrivers>true</CheckInterfaceDrivers>
|
||||
</Debug>
|
||||
</VisualGDBProjectSettings2>
|
||||
@@ -32,13 +32,15 @@
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|VisualGDB'">
|
||||
<GNUConfigurationType>Debug</GNUConfigurationType>
|
||||
<ToolchainID>com.visualgdb.arm-eabi</ToolchainID>
|
||||
<ToolchainVersion>12.2.1/12.2/r2</ToolchainVersion>
|
||||
<ToolchainVersion>14.2.1/15.2/r2</ToolchainVersion>
|
||||
<MCUPropertyListFile>$(ProjectDir)nrf5x.props</MCUPropertyListFile>
|
||||
<UseCCache>true</UseCCache>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|VisualGDB'">
|
||||
<ToolchainID>com.visualgdb.arm-eabi</ToolchainID>
|
||||
<ToolchainVersion>12.2.1/12.2/r2</ToolchainVersion>
|
||||
<ToolchainVersion>14.2.1/15.2/r2</ToolchainVersion>
|
||||
<MCUPropertyListFile>$(ProjectDir)nrf5x.props</MCUPropertyListFile>
|
||||
<UseCCache>true</UseCCache>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|VisualGDB'">
|
||||
<ClCompile>
|
||||
@@ -49,6 +51,8 @@
|
||||
<SupportRTTI>false</SupportRTTI>
|
||||
<AdditionalOptions />
|
||||
<CPPLanguageStandard />
|
||||
<Optimization>O0</Optimization>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<LinkerScript>nRF52811_XXAA_s140.lds</LinkerScript>
|
||||
@@ -66,6 +70,7 @@
|
||||
<CLanguageStandard>GNU99</CLanguageStandard>
|
||||
<SupportExceptions>false</SupportExceptions>
|
||||
<SupportRTTI>false</SupportRTTI>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<LinkerScript>nRF52811_XXAA_s140.lds</LinkerScript>
|
||||
@@ -79,6 +84,7 @@
|
||||
<ItemGroup>
|
||||
<ClCompile Include="host_tasks.c" />
|
||||
<ClCompile Include="le_gatt_c.c" />
|
||||
<ClCompile Include="le_uart_c.c" />
|
||||
<ClCompile Include="mem_drv.c" />
|
||||
<ClCompile Include="sram_drv.c" />
|
||||
<ClCompile Include="syscalls.c" />
|
||||
|
||||
@@ -1685,6 +1685,9 @@
|
||||
<ClCompile Include="syscalls.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="le_uart_c.c">
|
||||
<Filter>Source files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\bmd380_sdk\components\ble\ble_services\ble_dis_c\ble_dis_c.h">
|
||||
|
||||
+78
-31
@@ -125,28 +125,44 @@ static void success_ack(void)
|
||||
uart_drv_tx(ack, sizeof(ack));
|
||||
}
|
||||
|
||||
static void disconnect_and_timeout_ack(void)
|
||||
{
|
||||
uint8_t ack[] = { 0x04, 0x00, 0x01, 0xFF };
|
||||
uart_drv_tx(ack, sizeof(ack));
|
||||
}
|
||||
|
||||
static void on_ins_scan(ins_scan_t *p_ins)
|
||||
{
|
||||
extern void le_scan_start(void);
|
||||
le_scan_start();
|
||||
}
|
||||
|
||||
bool connect_start = false;
|
||||
static void on_ins_connect(ins_connect_t *p_ins)
|
||||
{
|
||||
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];
|
||||
peer_addr.addr_id_peer = 0;
|
||||
peer_addr.addr_type = BLE_GAP_ADDR_TYPE_ANONYMOUS;
|
||||
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];
|
||||
|
||||
extern void le_scan_stop(void);
|
||||
le_scan_stop();
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(5));
|
||||
vTaskDelay(pdMS_TO_TICKS(3));
|
||||
|
||||
extern void le_scan_get_peer_addr(ble_gap_addr_t * p_peer_addr);
|
||||
le_scan_get_peer_addr(&peer_addr);
|
||||
|
||||
if (peer_addr.addr_type == BLE_GAP_ADDR_TYPE_ANONYMOUS)
|
||||
{
|
||||
extern void le_scan_start(void);
|
||||
le_scan_start();
|
||||
return;
|
||||
}
|
||||
|
||||
extern void le_gap_connet(ble_gap_addr_t * p_peer_addr);
|
||||
le_gap_connet(&peer_addr);
|
||||
@@ -158,14 +174,28 @@ static void on_ins_connect(ins_connect_t *p_ins)
|
||||
|
||||
static void on_ins_write_char(ins_write_char_t *p_ins)
|
||||
{
|
||||
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)
|
||||
NRF_LOG_INFO("write handle: 0x%02X", p_ins->handle);
|
||||
{
|
||||
success_ack();
|
||||
uint8_t *p_start = (void *)p_ins->write_data;
|
||||
uint32_t loop = write_size / 8;
|
||||
uint32_t remain = write_size % 8;
|
||||
for (int i = 0; i < loop; i++)
|
||||
{
|
||||
NRF_LOG_HEXDUMP_INFO(p_start, 8);
|
||||
p_start += 8;
|
||||
}
|
||||
if (remain)
|
||||
{
|
||||
NRF_LOG_HEXDUMP_INFO(p_start, remain);
|
||||
}
|
||||
}
|
||||
|
||||
extern ret_code_t le_gatt_c_write_req(uint32_t handle, void *, uint16_t);
|
||||
ret_code_t err_code = le_gatt_c_write_req(p_ins->handle, p_ins->write_data, write_size);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
success_ack();
|
||||
}
|
||||
|
||||
static void on_ins_read_char(ins_read_char_t *p_ins)
|
||||
@@ -186,22 +216,38 @@ static void on_ins_survive(ins_survive_t *p_ins)
|
||||
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);
|
||||
static union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint16_t rsp_code;
|
||||
uint8_t payload[];
|
||||
};
|
||||
uint8_t arr[256];
|
||||
} read_char_rsp = {
|
||||
.rsp_code = 0x0004
|
||||
};
|
||||
|
||||
memcpy(read_char_rsp.payload, p_data, len);
|
||||
|
||||
uart_drv_tx(&read_char_rsp, sizeof(read_char_rsp.rsp_code) + len);
|
||||
|
||||
{
|
||||
uint8_t *p_start = p_data;
|
||||
uint32_t loop = len / 8;
|
||||
uint32_t remain = len % 8;
|
||||
for (int i = 0; i < loop; i++)
|
||||
{
|
||||
NRF_LOG_HEXDUMP_INFO(p_start, 8);
|
||||
p_start += 8;
|
||||
}
|
||||
if (remain)
|
||||
{
|
||||
NRF_LOG_HEXDUMP_INFO(p_start, remain);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct
|
||||
@@ -365,7 +411,8 @@ static void host_tasks_handler(ble_evt_t const *p_ble_evt, void *p_context)
|
||||
case BLE_GAP_EVT_CONNECTED:
|
||||
break;
|
||||
case BLE_GAP_EVT_DISCONNECTED:
|
||||
success_ack();
|
||||
case BLE_GAP_EVT_TIMEOUT:
|
||||
disconnect_and_timeout_ack();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -375,8 +422,8 @@ static void host_tasks_handler(ble_evt_t const *p_ble_evt, void *p_context)
|
||||
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_recv_task, "cmd_recv", 128, NULL, 3, 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);
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@ static void db_disc_handler(ble_db_discovery_evt_t *p_evt)
|
||||
le_dis_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);
|
||||
extern void le_uart_c_on_db_disc_evt(ble_db_discovery_evt_t * p_evt);
|
||||
le_uart_c_on_db_disc_evt(p_evt);
|
||||
break;
|
||||
case BLE_DB_DISCOVERY_ERROR:
|
||||
NRF_LOG_INFO("BLE_DB_DISCOVERY_ERROR");
|
||||
|
||||
@@ -26,13 +26,37 @@ extern "C"
|
||||
}
|
||||
#endif
|
||||
|
||||
bool is_connected = false;
|
||||
|
||||
static void le_gap_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_CONNECTED:
|
||||
is_connected = true;
|
||||
break;
|
||||
case BLE_GAP_EVT_DISCONNECTED:
|
||||
is_connected = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void le_gap_init(const char *device_name, uint16_t usAppearance)
|
||||
{
|
||||
// TODO...
|
||||
// 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 (is_connected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If address is correct, stop scanning and initiate connection with peripheral device.
|
||||
const ble_gap_conn_params_t conn_params = {
|
||||
.conn_sup_timeout =
|
||||
@@ -44,11 +68,13 @@ void le_gap_connet(ble_gap_addr_t *p_peer_addr)
|
||||
.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,
|
||||
le_scan_params(),
|
||||
&conn_params,
|
||||
APP_BLE_CONN_CFG_TAG);
|
||||
|
||||
APP_ERROR_CHECK(err_code);
|
||||
}
|
||||
|
||||
@@ -73,10 +99,15 @@ void le_gap_conn_param_update(uint16_t conn_handle)
|
||||
NRF_LOG_INFO("Central Preferred Connection Parameters.");
|
||||
// Set GAP Central Preferred Connection Parameters.
|
||||
ble_gap_conn_params_t const gap_conn_params = {
|
||||
.min_conn_interval = MSEC_TO_UNITS(8, UNIT_1_25_MS), /**< Minimum connection interval (7.5 ms) */
|
||||
.max_conn_interval = MSEC_TO_UNITS(20, UNIT_1_25_MS), /**< Maximum connection interval (20 ms). */
|
||||
.min_conn_interval = MSEC_TO_UNITS(8, UNIT_1_25_MS), /**< Minimum connection interval ( 7.5 ms) */
|
||||
.max_conn_interval = MSEC_TO_UNITS(10, UNIT_1_25_MS), /**< Maximum connection interval (10.0 ms). */
|
||||
.slave_latency = 8, /**< Slave latency. */
|
||||
.conn_sup_timeout = MSEC_TO_UNITS(10000, UNIT_10_MS) /**< Connection supervisory timeout (10s). */
|
||||
};
|
||||
sd_ble_gap_conn_param_update(conn_handle, &gap_conn_params);
|
||||
}
|
||||
|
||||
bool le_gap_is_connected(void)
|
||||
{
|
||||
return is_connected;
|
||||
}
|
||||
|
||||
+35
-57
@@ -21,27 +21,18 @@ extern "C"
|
||||
}
|
||||
#endif
|
||||
|
||||
#define MAX_CHAR_CNT 16
|
||||
|
||||
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 conn_handle;
|
||||
uint16_t char_handles[MAX_CHAR_CNT];
|
||||
};
|
||||
|
||||
uint16_t handle_mapping[5];
|
||||
uint16_t handle_mapping[MAX_CHAR_CNT];
|
||||
|
||||
typedef struct ble_gatt_c_s ble_gatt_c_t;
|
||||
|
||||
@@ -49,11 +40,11 @@ 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;
|
||||
p_ble_gatt_c->conn_handle = BLE_CONN_HANDLE_INVALID;
|
||||
for (int i = 0; i < COUNTOF(p_ble_gatt_c->char_handles); i++)
|
||||
{
|
||||
p_ble_gatt_c->char_handles[i] = BLE_GATT_HANDLE_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t hvx_cnt = 0;
|
||||
@@ -62,14 +53,17 @@ 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 = p_ble_evt->evt.gattc_evt.params.hvx.data;
|
||||
NRF_LOG_INFO("=======================================");
|
||||
NRF_LOG_HEXDUMP_INFO(p, len);
|
||||
ble_gattc_evt_hvx_t *hvx = (void *)&p_ble_evt->evt.gattc_evt.params.hvx;
|
||||
uint32_t len = hvx->len;
|
||||
uint8_t *p = (uint8_t *)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)
|
||||
@@ -226,11 +220,10 @@ static void le_gatt_c_evt_handler(ble_evt_t const *p_ble_evt, void *p_context)
|
||||
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);
|
||||
for (int i = 0; i < COUNTOF(m_gatt_c.char_handles); i++)
|
||||
{
|
||||
le_gatt_ccdc_configure(m_gatt_c.conn_handle, m_gatt_c.char_handles[i], true);
|
||||
}
|
||||
NRF_LOG_INFO("Enable notifications. ");
|
||||
}
|
||||
|
||||
@@ -238,12 +231,13 @@ 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;
|
||||
m_gatt_c.evt_handler = le_gatt_c_evt_handler;
|
||||
m_gatt_c.conn_handle = BLE_CONN_HANDLE_INVALID;
|
||||
for (int i = 0; i < COUNTOF(m_gatt_c.char_handles); i++)
|
||||
{
|
||||
m_gatt_c.char_handles[i] = BLE_GATT_HANDLE_INVALID;
|
||||
}
|
||||
|
||||
ret_code_t err_code;
|
||||
uint8_t uuid_type;
|
||||
ble_uuid_t uuid = {
|
||||
@@ -275,32 +269,16 @@ void le_gatt_c_on_db_disc_evt(ble_db_discovery_evt_t *p_evt)
|
||||
{
|
||||
m_gatt_c.conn_handle = p_evt->conn_handle;
|
||||
|
||||
for (uint32_t i = 0; i < p_evt->params.discovered_db.char_count; i++)
|
||||
for (int i = 0; i < p_evt->params.discovered_db.char_count; i++)
|
||||
{
|
||||
switch (p_chars[i].characteristic.uuid.uuid)
|
||||
for (int j = 0; j < COUNTOF(m_gatt_c.char_handles); j++)
|
||||
{
|
||||
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:
|
||||
if (p_chars[i].characteristic.uuid.uuid == BLE_UUID_SIMPLEPROFILECHAR(j + 1))
|
||||
{
|
||||
m_gatt_c.char_handles[j] = p_chars[i].characteristic.handle_value;
|
||||
handle_mapping[j] = m_gatt_c.char_handles[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,14 +78,14 @@ static void on_adv_report(ble_gap_evt_adv_report_t const *p_adv_report)
|
||||
p_adv_report->rssi);
|
||||
}
|
||||
|
||||
|
||||
|
||||
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;
|
||||
static uint32_t peer_addr_idx = 0;
|
||||
static ble_gap_addr_t peer_addr_list[16];
|
||||
|
||||
static uint64_t mac = 0;
|
||||
void le_scan_handler(ble_evt_t const *p_ble_evt, void *p_context)
|
||||
{
|
||||
ret_code_t err_code;
|
||||
@@ -99,14 +99,13 @@ void le_scan_handler(ble_evt_t const *p_ble_evt, void *p_context)
|
||||
{
|
||||
mac = u64_peer_addr;
|
||||
|
||||
char peer_addr_str[(2 + 1) * BLE_GAP_ADDR_LEN + 1] = { 0 };
|
||||
|
||||
if (peer_addr)
|
||||
{
|
||||
char peer_addr_str[(2 + 1) * BLE_GAP_ADDR_LEN + 1] = { 0 };
|
||||
peer_addr_list[peer_addr_idx++ % COUNTOF(peer_addr_list)] = *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]);
|
||||
NRF_LOG_INFO("%s", peer_addr_str);
|
||||
}
|
||||
|
||||
NRF_LOG_INFO("%s", peer_addr_str);
|
||||
}
|
||||
else if (mac == u64_peer_addr)
|
||||
{
|
||||
@@ -116,6 +115,18 @@ void le_scan_handler(ble_evt_t const *p_ble_evt, void *p_context)
|
||||
sd_ble_gap_scan_start(NULL, &adv_report_buffer);
|
||||
}
|
||||
|
||||
void le_scan_get_peer_addr(ble_gap_addr_t *p_peer_addr)
|
||||
{
|
||||
for (uint32_t i = 0; i < COUNTOF(peer_addr_list); i++)
|
||||
{
|
||||
if (memcmp(peer_addr_list[i].addr, p_peer_addr->addr, BLE_GAP_ADDR_LEN) == 0)
|
||||
{
|
||||
p_peer_addr->addr_type = peer_addr_list[i].addr_type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static ble_gap_scan_params_t scan_params = {
|
||||
.active = 1,
|
||||
.interval = NRF_BLE_SCAN_SCAN_INTERVAL,
|
||||
@@ -141,7 +152,9 @@ void le_scan_start(void)
|
||||
{
|
||||
NRF_LOG_INFO("Start scanning for UUID service 0x%04X.",
|
||||
BLE_UUID_CUSTOM_SERVICE);
|
||||
is_scanning = true;
|
||||
is_scanning = true;
|
||||
peer_addr_idx = 0;
|
||||
memset(peer_addr_list, 0x00, sizeof(peer_addr_list));
|
||||
sd_ble_gap_scan_start(&scan_params, &adv_report_buffer);
|
||||
}
|
||||
}
|
||||
@@ -156,4 +169,4 @@ void le_scan_stop(void)
|
||||
ble_gap_scan_params_t *le_scan_params(void)
|
||||
{
|
||||
return &scan_params;
|
||||
}
|
||||
}
|
||||
|
||||
+466
@@ -0,0 +1,466 @@
|
||||
#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 "message_buffer.h"
|
||||
#include "semphr.h"
|
||||
#include "task.h"
|
||||
#include "timers.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#define MAX_CHAR_CNT 4
|
||||
|
||||
extern nrf_ble_gq_t *le_gap_queue(void);
|
||||
|
||||
struct le_uart_c_s
|
||||
{
|
||||
void (*evt_handler)(ble_evt_t const *p_ble_evt, void *p_context);
|
||||
uint16_t conn_handle;
|
||||
uint16_t char_handles[MAX_CHAR_CNT];
|
||||
|
||||
TimerHandle_t le_uart_c_cccd_timer;
|
||||
|
||||
MessageBufferHandle_t rx_msg;
|
||||
|
||||
SemaphoreHandle_t baud_sem;
|
||||
uint32_t baud_rate;
|
||||
};
|
||||
|
||||
#define UART_TX_HAND_IDX 0
|
||||
#define UART_RX_HAND_IDX 1
|
||||
#define UART_BAUD_HAND_IDX 2
|
||||
|
||||
typedef struct le_uart_c_s le_uart_c_t;
|
||||
|
||||
static le_uart_c_t m_le_uart_c;
|
||||
|
||||
static void on_disconnected(le_uart_c_t *p_le_uart_c, ble_evt_t const *p_ble_evt)
|
||||
{
|
||||
p_le_uart_c->conn_handle = BLE_CONN_HANDLE_INVALID;
|
||||
for (int i = 0; i < COUNTOF(p_le_uart_c->char_handles); i++)
|
||||
{
|
||||
p_le_uart_c->char_handles[i] = BLE_GATT_HANDLE_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
static void on_connected(le_uart_c_t *p_le_uart_c, ble_evt_t const *p_ble_evt)
|
||||
{
|
||||
xTimerStart(p_le_uart_c->le_uart_c_cccd_timer, 0);
|
||||
}
|
||||
|
||||
static void on_hvx(le_uart_c_t *p_le_uart_c, ble_evt_t const *p_ble_evt)
|
||||
{
|
||||
ble_gattc_evt_hvx_t *hvx = (void *)&p_ble_evt->evt.gattc_evt.params.hvx;
|
||||
if (p_le_uart_c->rx_msg)
|
||||
{
|
||||
taskENTER_CRITICAL();
|
||||
xMessageBufferSend(p_le_uart_c->rx_msg, (void *)hvx->data, hvx->len, 0);
|
||||
taskEXIT_CRITICAL();
|
||||
}
|
||||
}
|
||||
|
||||
static void on_read_rsp(le_uart_c_t *p_le_uart_c, ble_evt_t const *p_ble_evt)
|
||||
{
|
||||
uint16_t handle = p_ble_evt->evt.gattc_evt.params.read_rsp.handle;
|
||||
ble_gattc_evt_read_rsp_t const *p_rsp = &p_ble_evt->evt.gattc_evt.params.read_rsp;
|
||||
|
||||
if (handle == p_le_uart_c->char_handles[UART_RX_HAND_IDX])
|
||||
{
|
||||
}
|
||||
else if (handle == p_le_uart_c->char_handles[UART_BAUD_HAND_IDX])
|
||||
{
|
||||
xSemaphoreGive(m_le_uart_c.baud_sem);
|
||||
m_le_uart_c.baud_rate = *(uint32_t *)p_rsp->data;
|
||||
}
|
||||
}
|
||||
|
||||
ret_code_t le_uart_ccdc_configure(uint16_t conn_handle, uint16_t char_handle, bool notification_enable)
|
||||
{
|
||||
if (conn_handle == BLE_CONN_HANDLE_INVALID)
|
||||
{
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if (char_handle == BLE_GATT_HANDLE_INVALID)
|
||||
{
|
||||
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_uart_c_cccd_timer_cb(TimerHandle_t xTimer)
|
||||
{
|
||||
xTimerStop(xTimer, pdMS_TO_TICKS(0));
|
||||
|
||||
extern ret_code_t le_uart_rx_notify(bool enable);
|
||||
le_uart_rx_notify(true);
|
||||
|
||||
xMessageBufferReset(m_le_uart_c.rx_msg);
|
||||
}
|
||||
|
||||
static void le_uart_c_evt_handler(ble_evt_t const *p_ble_evt, void *p_context)
|
||||
{
|
||||
le_uart_c_t *p_le_uart_c = (le_uart_c_t *)p_context;
|
||||
|
||||
if ((p_le_uart_c == NULL) || (p_ble_evt == NULL))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
switch (p_ble_evt->header.evt_id)
|
||||
{
|
||||
case BLE_GAP_EVT_DISCONNECTED:
|
||||
on_disconnected(p_le_uart_c, p_ble_evt);
|
||||
break;
|
||||
case BLE_GAP_EVT_CONNECTED:
|
||||
on_connected(p_le_uart_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_le_uart_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_le_uart_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_uart_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_le_uart_c.evt_handler == NULL || m_le_uart_c.conn_handle == p_evt->conn_handle)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if the uart service was discovered.
|
||||
if ((p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE) &&
|
||||
(p_evt->params.discovered_db.srv_uuid.uuid == BLE_UUID_UART_SERVICE) &&
|
||||
(p_evt->params.discovered_db.srv_uuid.type == BLE_UUID_TYPE_BLE))
|
||||
{
|
||||
m_le_uart_c.conn_handle = p_evt->conn_handle;
|
||||
|
||||
for (int i = 0; i < p_evt->params.discovered_db.char_count; i++)
|
||||
{
|
||||
for (int j = 0; j < COUNTOF(m_le_uart_c.char_handles); j++)
|
||||
{
|
||||
if (p_chars[i].characteristic.uuid.uuid == BLE_UUID_UART_CHAR(j + 1))
|
||||
{
|
||||
m_le_uart_c.char_handles[j] = p_chars[i].characteristic.handle_value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void le_uart_c_error_handler(uint32_t nrf_error, void *p_contex, uint16_t conn_handle)
|
||||
{
|
||||
UNUSED_PARAMETER(conn_handle);
|
||||
__BKPT(255);
|
||||
}
|
||||
|
||||
ret_code_t le_uart_tx(uint8_t const *p_data, uint16_t len)
|
||||
{
|
||||
if (m_le_uart_c.conn_handle == BLE_CONN_HANDLE_INVALID)
|
||||
{
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
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_uart_c_error_handler;
|
||||
gq_req.error_handler.p_ctx = &m_le_uart_c;
|
||||
gq_req.params.gattc_write.handle = m_le_uart_c.char_handles[UART_TX_HAND_IDX];
|
||||
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, m_le_uart_c.conn_handle);
|
||||
}
|
||||
|
||||
ret_code_t le_uart_rx_notify(bool enable)
|
||||
{
|
||||
if (m_le_uart_c.conn_handle == BLE_CONN_HANDLE_INVALID)
|
||||
{
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
if (m_le_uart_c.char_handles[UART_RX_HAND_IDX] == BLE_GATT_HANDLE_INVALID)
|
||||
{
|
||||
return NRF_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
ret_code_t ret = le_uart_ccdc_configure(m_le_uart_c.conn_handle, m_le_uart_c.char_handles[UART_RX_HAND_IDX], enable);
|
||||
|
||||
if (ret == NRF_SUCCESS)
|
||||
{
|
||||
NRF_LOG_INFO(enable == true ? "Enable Rx notifications." : "Disable Rx notifications.");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret_code_t le_uart_rx(uint8_t *p_data, uint16_t len, uint32_t timeout)
|
||||
{
|
||||
size_t recv_size = 0;
|
||||
if (timeout)
|
||||
{
|
||||
recv_size = xMessageBufferReceive(m_le_uart_c.rx_msg, p_data, len, timeout);
|
||||
}
|
||||
else
|
||||
{
|
||||
taskENTER_CRITICAL();
|
||||
recv_size = xMessageBufferReceive(m_le_uart_c.rx_msg, p_data, len, 0);
|
||||
taskEXIT_CRITICAL();
|
||||
}
|
||||
if (recv_size)
|
||||
{
|
||||
return recv_size;
|
||||
}
|
||||
return NRF_ERROR_TIMEOUT;
|
||||
}
|
||||
|
||||
ret_code_t le_uart_baudrate_get(uint32_t *baudrate)
|
||||
{
|
||||
ret_code_t ret;
|
||||
|
||||
if (m_le_uart_c.conn_handle == BLE_CONN_HANDLE_INVALID)
|
||||
{
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
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_uart_c_error_handler;
|
||||
gq_req.error_handler.p_ctx = &m_le_uart_c;
|
||||
gq_req.params.gattc_read.handle = m_le_uart_c.char_handles[UART_BAUD_HAND_IDX];
|
||||
|
||||
ret = nrf_ble_gq_item_add(le_gap_queue(), &gq_req, m_le_uart_c.conn_handle);
|
||||
|
||||
if (ret == NRF_SUCCESS)
|
||||
{
|
||||
if (xSemaphoreTake(m_le_uart_c.baud_sem, pdMS_TO_TICKS(100)) == pdFALSE)
|
||||
{
|
||||
return NRF_ERROR_TIMEOUT;
|
||||
}
|
||||
*baudrate = m_le_uart_c.baud_rate;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret_code_t le_uart_baudrate_set(uint32_t baudrate)
|
||||
{
|
||||
if (m_le_uart_c.conn_handle == BLE_CONN_HANDLE_INVALID)
|
||||
{
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
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_uart_c_error_handler;
|
||||
gq_req.error_handler.p_ctx = &m_le_uart_c;
|
||||
gq_req.params.gattc_write.handle = m_le_uart_c.char_handles[UART_BAUD_HAND_IDX];
|
||||
gq_req.params.gattc_write.p_value = (void *)&baudrate;
|
||||
gq_req.params.gattc_write.len = sizeof(baudrate);
|
||||
gq_req.params.gattc_write.write_op = BLE_GATT_OP_WRITE_REQ;
|
||||
return nrf_ble_gq_item_add(le_gap_queue(), &gq_req, m_le_uart_c.conn_handle);
|
||||
}
|
||||
|
||||
static void ble_uart_echo(void *p_arg)
|
||||
{
|
||||
void le_scan_start(void);
|
||||
le_scan_start();
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(3000));
|
||||
|
||||
void le_scan_stop(void);
|
||||
le_scan_stop();
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
|
||||
ble_gap_addr_t peer_addr;
|
||||
peer_addr.addr_id_peer = 0;
|
||||
peer_addr.addr_type = BLE_GAP_ADDR_TYPE_ANONYMOUS;
|
||||
peer_addr.addr[0] = 0xDA;
|
||||
peer_addr.addr[1] = 0x71;
|
||||
peer_addr.addr[2] = 0x1F;
|
||||
peer_addr.addr[3] = 0x1F;
|
||||
peer_addr.addr[4] = 0x05;
|
||||
peer_addr.addr[5] = 0xDC;
|
||||
|
||||
extern void le_scan_get_peer_addr(ble_gap_addr_t * p_peer_addr);
|
||||
le_scan_get_peer_addr(&peer_addr);
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
|
||||
extern void le_gap_connet(ble_gap_addr_t * p_peer_addr);
|
||||
le_gap_connet(&peer_addr);
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
|
||||
uint32_t get_baud = 1000000;
|
||||
uint32_t set_baud = 115200;
|
||||
extern ret_code_t le_uart_baudrate_get(uint32_t * baudrate);
|
||||
le_uart_baudrate_get(&get_baud);
|
||||
NRF_LOG_INFO("Get Baud rate: %d", get_baud);
|
||||
|
||||
extern ret_code_t le_uart_baudrate_set(uint32_t baudrate);
|
||||
le_uart_baudrate_set(set_baud);
|
||||
NRF_LOG_INFO("Set Baud rate: %d", set_baud);
|
||||
|
||||
le_uart_baudrate_get(&get_baud);
|
||||
NRF_LOG_INFO("Get Baud rate: %d", get_baud);
|
||||
|
||||
extern ret_code_t le_uart_tx(uint8_t const *p_data, uint16_t len);
|
||||
uint8_t str[] = "ABCDEF";
|
||||
le_uart_tx(str, strlen(str));
|
||||
|
||||
for (;;)
|
||||
{
|
||||
uint8_t recv[256];
|
||||
uint32_t size;
|
||||
size = le_uart_rx(recv, sizeof(recv), portMAX_DELAY);
|
||||
le_uart_tx(recv, size);
|
||||
}
|
||||
}
|
||||
|
||||
void le_uart_c_init(void)
|
||||
{
|
||||
m_le_uart_c.rx_msg = xMessageBufferCreate(4096);
|
||||
m_le_uart_c.baud_sem = xSemaphoreCreateBinary();
|
||||
m_le_uart_c.evt_handler = le_uart_c_evt_handler;
|
||||
m_le_uart_c.conn_handle = BLE_CONN_HANDLE_INVALID;
|
||||
for (int i = 0; i < COUNTOF(m_le_uart_c.char_handles); i++)
|
||||
{
|
||||
m_le_uart_c.char_handles[i] = 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_UART_SERVICE,
|
||||
};
|
||||
err_code = ble_db_discovery_evt_register(&uuid);
|
||||
APP_ERROR_CHECK(err_code);
|
||||
|
||||
NRF_SDH_BLE_OBSERVER(m_uart_c_observer, 1, le_uart_c_evt_handler, &m_le_uart_c);
|
||||
|
||||
m_le_uart_c.le_uart_c_cccd_timer = xTimerCreate("Timer", pdMS_TO_TICKS(1000), pdTRUE, (void *)1, le_uart_c_cccd_timer_cb);
|
||||
|
||||
#if 1
|
||||
xTaskCreate(ble_uart_echo, "ble uart echo", 2048, NULL, 3, NULL);
|
||||
#endif
|
||||
}
|
||||
@@ -102,80 +102,6 @@ static void le_stack_Init(void)
|
||||
NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, le_evt_handler, NULL);
|
||||
}
|
||||
|
||||
|
||||
#define ROY_MEM_SEL NRF_GPIO_PIN_MAP(1, 9)
|
||||
#define ROY_MEM_BZY NRF_GPIO_PIN_MAP(0, 8)
|
||||
#define ROY_MEM_REQ NRF_GPIO_PIN_MAP(0, 6)
|
||||
#define ROY_RAM_SEL NRF_GPIO_PIN_MAP(0, 5)
|
||||
#define ROY_MEM_TEST_01 NRF_GPIO_PIN_MAP(0, 26)
|
||||
#define ROY_MEM_TEST_02 NRF_GPIO_PIN_MAP(0, 17)
|
||||
#define ROY_MEM_TEST_03 NRF_GPIO_PIN_MAP(0, 21)
|
||||
#define ROY_MEM_TEST_04 NRF_GPIO_PIN_MAP(0, 19)
|
||||
#define ROY_MEM_TEST_05 NRF_GPIO_PIN_MAP(0, 22)
|
||||
#define ROY_LED1 NRF_GPIO_PIN_MAP(1, 10)
|
||||
|
||||
static void mem_pin(void *p_arg)
|
||||
{
|
||||
nrf_gpio_cfg_output(ROY_MEM_SEL);
|
||||
nrf_gpio_cfg_output(ROY_MEM_BZY);
|
||||
nrf_gpio_cfg_output(ROY_MEM_REQ);
|
||||
nrf_gpio_cfg_output(ROY_RAM_SEL);
|
||||
|
||||
static uint8_t time = 0;
|
||||
for (;;) {
|
||||
|
||||
NRF_LOG_INFO("mem_pin %d", time);
|
||||
time++;
|
||||
nrf_gpio_pin_set(ROY_MEM_SEL);
|
||||
nrf_gpio_pin_set(ROY_MEM_BZY);
|
||||
nrf_gpio_pin_set(ROY_MEM_REQ);
|
||||
nrf_gpio_pin_set(ROY_RAM_SEL);
|
||||
NRF_LOG_INFO("mem_pin on");
|
||||
nrf_delay_ms(2000);
|
||||
|
||||
nrf_gpio_pin_clear(ROY_MEM_SEL);
|
||||
nrf_gpio_pin_clear(ROY_MEM_BZY);
|
||||
nrf_gpio_pin_clear(ROY_MEM_REQ);
|
||||
nrf_gpio_pin_clear(ROY_RAM_SEL);
|
||||
NRF_LOG_INFO("mem_pin off");
|
||||
nrf_delay_ms(2000);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_pin(void *p_arg)
|
||||
{
|
||||
nrf_gpio_cfg_output(ROY_MEM_TEST_01);
|
||||
nrf_gpio_cfg_output(ROY_MEM_TEST_02);
|
||||
nrf_gpio_cfg_output(ROY_MEM_TEST_03);
|
||||
nrf_gpio_cfg_output(ROY_MEM_TEST_04);
|
||||
nrf_gpio_cfg_output(ROY_MEM_TEST_05);
|
||||
nrf_gpio_cfg_output(ROY_LED1);
|
||||
|
||||
static uint8_t time = 0;
|
||||
for (;;) {
|
||||
|
||||
NRF_LOG_INFO("test_pin %d", time);
|
||||
time++;
|
||||
nrf_gpio_pin_set(ROY_MEM_TEST_01);
|
||||
nrf_gpio_pin_set(ROY_MEM_TEST_02);
|
||||
nrf_gpio_pin_set(ROY_MEM_TEST_03);
|
||||
nrf_gpio_pin_set(ROY_MEM_TEST_04);
|
||||
nrf_gpio_pin_set(ROY_MEM_TEST_05);
|
||||
nrf_gpio_pin_set(ROY_LED1);
|
||||
NRF_LOG_INFO("test_pin on");
|
||||
nrf_delay_ms(1000);
|
||||
|
||||
nrf_gpio_pin_clear(ROY_MEM_TEST_01);
|
||||
nrf_gpio_pin_clear(ROY_MEM_TEST_02);
|
||||
nrf_gpio_pin_clear(ROY_MEM_TEST_03);
|
||||
nrf_gpio_pin_clear(ROY_MEM_TEST_04);
|
||||
nrf_gpio_pin_clear(ROY_MEM_TEST_05);
|
||||
nrf_gpio_pin_clear(ROY_LED1);
|
||||
NRF_LOG_INFO("test_pin off");
|
||||
nrf_delay_ms(1000);
|
||||
}
|
||||
}
|
||||
|
||||
static void initialize(void *p_context)
|
||||
{
|
||||
extern void uart_drv_init(void);
|
||||
@@ -193,6 +119,9 @@ static void initialize(void *p_context)
|
||||
extern void le_gatt_c_init(void);
|
||||
le_gatt_c_init();
|
||||
|
||||
extern void le_uart_c_init(void);
|
||||
le_uart_c_init();
|
||||
|
||||
extern void le_gap_init(void);
|
||||
le_gap_init();
|
||||
|
||||
@@ -208,7 +137,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__);
|
||||
|
||||
@@ -216,9 +145,6 @@ int main(void)
|
||||
|
||||
nrf_sdh_freertos_init(initialize, NULL);
|
||||
|
||||
//xTaskCreate(mem_pin, "mem_pin", 512, NULL, 5, NULL);
|
||||
//xTaskCreate(test_pin, "test_pin", 512, NULL, 5, NULL);
|
||||
|
||||
vTaskStartScheduler();
|
||||
|
||||
for (;;)
|
||||
|
||||
@@ -10,7 +10,9 @@ extern "C"
|
||||
#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"
|
||||
@@ -33,17 +35,44 @@ extern "C"
|
||||
#define MEM_TEST_04_PIN NRF_GPIO_PIN_MAP(0, 19)
|
||||
#define MEM_TEST_05_PIN NRF_GPIO_PIN_MAP(0, 22)
|
||||
|
||||
#define MEM_REQ_GPIOTE_ID 0
|
||||
#define MEM_SEL_GPIOTE_ID 0
|
||||
#define MEM_REQ_GPIOTE_ID 1
|
||||
|
||||
static int ram_sel_signal = 0;
|
||||
#define MEM_DATA_UNIT 40
|
||||
|
||||
static SemaphoreHandle_t mem_drv_semphr = NULL;
|
||||
static TaskHandle_t mem_drv_task_handle = NULL;
|
||||
#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_req;
|
||||
uint32_t mem_sel;
|
||||
|
||||
void mem_ram_select(int select)
|
||||
{
|
||||
ram_sel_signal = select;
|
||||
switch (ram_sel_signal)
|
||||
ram_sel = select;
|
||||
switch (ram_sel)
|
||||
{
|
||||
case 0:
|
||||
nrf_gpio_pin_clear(RAM_SEL_PIN);
|
||||
@@ -54,48 +83,139 @@ void mem_ram_select(int select)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
NRF_LOG_INFO("Select SRAM: %d", ram_sel);
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
/* sync mem_req status */
|
||||
mem_req = nrf_gpio_pin_read(MEM_REQ_PIN);
|
||||
|
||||
if (mem_req != ram_sel)
|
||||
{
|
||||
*new_ram_sel = mem_req;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
static void mem_drv_task(void *p_arg)
|
||||
{
|
||||
static uint32_t sel = 0;
|
||||
|
||||
extern void sram_drv_init(void);
|
||||
sram_drv_init();
|
||||
|
||||
extern void sram_drv_reset(void);
|
||||
extern int sram_drv_write(uint32_t addr, void *p_dest, uint32_t len);
|
||||
NRF_LOG_INFO("build----1")
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
sel ^= 1;
|
||||
mem_ram_select(sel);
|
||||
sram_drv_reset();
|
||||
|
||||
if (sel) {
|
||||
uint8_t buf_1[12] = {1,2,2,6,5,6,7,8,9,0};
|
||||
sram_drv_write(0x0000, buf_1, sizeof(buf_1));
|
||||
} else {
|
||||
uint8_t buf_0[12] = {9,9,8,8,7,7,6,6,5,5,0};
|
||||
sram_drv_write(0x0000, buf_0, sizeof(buf_0));
|
||||
}
|
||||
}
|
||||
mem_ram_select(0);
|
||||
sram_drv_reset();
|
||||
mem_ram_select(1);
|
||||
sram_drv_reset();
|
||||
mem_ram_select(0);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
extern int sram_drv_read(uint32_t addr, void *p_dest, uint32_t len);
|
||||
uint32_t new_ram_sel;
|
||||
|
||||
uint8_t buf[4];
|
||||
xSemaphoreTake(mem_sel_semphr, portMAX_DELAY);
|
||||
|
||||
xSemaphoreTake(mem_drv_semphr, portMAX_DELAY);
|
||||
if (chk_sram_swtich_evt(&new_ram_sel) == false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
sel ^= 0x01;
|
||||
mem_ram_select(sel);
|
||||
sram_drv_read(0x0000, buf, sizeof(buf));
|
||||
NRF_LOG_INFO("mem_sel[%d]: 0x%02X, 0x%02X, 0x%02X, 0x%02X", sel, buf[0], buf[1], buf[2], buf[3]);
|
||||
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;
|
||||
|
||||
/* read red frame data from streambuffer */
|
||||
taskENTER_CRITICAL();
|
||||
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: %4d bytes, and switch sram done!!!", total_size);
|
||||
}
|
||||
}
|
||||
|
||||
void mem_board_reset(void)
|
||||
{
|
||||
mem_notify_cnt = 0;
|
||||
xStreamBufferReset(mem_drv_stream);
|
||||
}
|
||||
|
||||
void mem_notify_cb(uint8_t *p, uint32_t len)
|
||||
{
|
||||
/* write red frame data to streambuffer */
|
||||
|
||||
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;
|
||||
|
||||
taskENTER_CRITICAL();
|
||||
xStreamBufferSend(mem_drv_stream, &swap_buf, 3 + len + 6, 0);
|
||||
taskEXIT_CRITICAL();
|
||||
}
|
||||
|
||||
void mem_board_init(void)
|
||||
{
|
||||
// Config RAM test pin
|
||||
@@ -112,35 +232,52 @@ void mem_board_init(void)
|
||||
// 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_drv_semphr = xSemaphoreCreateBinary();
|
||||
mem_sel_semphr = xSemaphoreCreateBinary();
|
||||
mem_drv_stream = xStreamBufferCreate(4096, 1);
|
||||
xTaskCreate(mem_drv_task, "mem_drv", 256, NULL, 5, NULL);
|
||||
|
||||
sd_nvic_SetPriority(GPIOTE_IRQn, _PRIO_APP_HIGH);
|
||||
sd_nvic_SetPriority(GPIOTE_IRQn, _PRIO_APP_MID);
|
||||
sd_nvic_EnableIRQ(GPIOTE_IRQn);
|
||||
}
|
||||
|
||||
static void mem_req_int_callback(void)
|
||||
static void mem_sel_isr(void)
|
||||
{
|
||||
uint32_t mem_sel = nrf_gpio_pin_read(MEM_SEL_PIN);
|
||||
uint32_t mem_req = nrf_gpio_pin_read(MEM_REQ_PIN);
|
||||
if (mem_sel != mem_req)
|
||||
mem_sel = nrf_gpio_pin_read(MEM_SEL_PIN);
|
||||
if (mem_sel == 0)
|
||||
{
|
||||
BaseType_t xHigherPriorityTaskWoken;
|
||||
xSemaphoreGiveFromISR(mem_drv_semphr, &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_int_callback();
|
||||
mem_req_isr();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
<EmbeddedProfile xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<ToolchainID>com.visualgdb.arm-eabi</ToolchainID>
|
||||
<ToolchainVersion>
|
||||
<GCC>12.2.1</GCC>
|
||||
<GDB>12.2</GDB>
|
||||
<GCC>14.2.1</GCC>
|
||||
<GDB>15.2</GDB>
|
||||
<Revision>2</Revision>
|
||||
</ToolchainVersion>
|
||||
<BspID>com.sysprogs.arm.nordic.nrf5x</BspID>
|
||||
|
||||
Reference in New Issue
Block a user