BLE TX pending queue 확장 및 ADC 패킷 재시도 처리, Ver116 업데이트
- BLE TX pending slot을 1개에서 8개로 확장 - dr_binary_tx_safe()에서 TX 결과 반환 - maa_async TX 실패 시 상태 유지 후 TX ready에서 재시도
This commit is contained in:
@@ -229,9 +229,12 @@ volatile bool ble_connection_st; /* BLE connection state (1=co
|
||||
volatile bool data_tx_in_progress = false; /* Binary TX in progress flag */
|
||||
|
||||
/* -- BLE TX async retry state -- */
|
||||
static volatile bool s_tx_pending = false; /* TX retry pending */
|
||||
static uint8_t s_tx_pending_buf[BLE_NUS_MAX_DATA_LEN] = {0}; /* Pending packet (with CRC) */
|
||||
static uint16_t s_tx_pending_len = 0; /* Pending packet length */
|
||||
#define BLE_TX_PENDING_QUEUE_SIZE 8U
|
||||
static uint8_t s_tx_pending_buf[BLE_TX_PENDING_QUEUE_SIZE][BLE_NUS_MAX_DATA_LEN] = {{0}}; /* Pending packets (with CRC) */
|
||||
static uint16_t s_tx_pending_len[BLE_TX_PENDING_QUEUE_SIZE] = {0}; /* Pending packet lengths */
|
||||
static volatile uint8_t s_tx_pending_head = 0; /* Next packet to retry */
|
||||
static volatile uint8_t s_tx_pending_tail = 0; /* Next enqueue slot */
|
||||
static volatile uint8_t s_tx_pending_count = 0; /* Queued packet count */
|
||||
|
||||
char m_static_passkey[PASSKEY_LENGTH] = DEFAULT_PASSKEY; /* Static passkey (6 digits, loaded from FDS) */
|
||||
char SERIAL_NO[SERIAL_NO_LENGTH] = {0}; /* Serial number (used as BLE device name) */
|
||||
@@ -562,47 +565,88 @@ extern void maa_async_abort(void);
|
||||
static volatile uint8_t pending_cmd_buf[BLE_NUS_MAX_DATA_LEN] = {0};
|
||||
static volatile uint8_t pending_cmd_len = 0;
|
||||
|
||||
static bool ble_tx_pending_has_data(void)
|
||||
{
|
||||
return (s_tx_pending_count > 0);
|
||||
}
|
||||
|
||||
static void ble_tx_pending_clear(void)
|
||||
{
|
||||
s_tx_pending_head = 0;
|
||||
s_tx_pending_tail = 0;
|
||||
s_tx_pending_count = 0;
|
||||
}
|
||||
|
||||
static bool ble_tx_pending_enqueue(uint8_t const *p_data, uint16_t len)
|
||||
{
|
||||
if (s_tx_pending_count >= BLE_TX_PENDING_QUEUE_SIZE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
memcpy(s_tx_pending_buf[s_tx_pending_tail], p_data, len);
|
||||
s_tx_pending_len[s_tx_pending_tail] = len;
|
||||
s_tx_pending_tail = (uint8_t)((s_tx_pending_tail + 1U) % BLE_TX_PENDING_QUEUE_SIZE);
|
||||
s_tx_pending_count++;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ble_tx_pending_pop(void)
|
||||
{
|
||||
if (s_tx_pending_count == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
s_tx_pending_len[s_tx_pending_head] = 0;
|
||||
s_tx_pending_head = (uint8_t)((s_tx_pending_head + 1U) % BLE_TX_PENDING_QUEUE_SIZE);
|
||||
s_tx_pending_count--;
|
||||
}
|
||||
|
||||
static bool ble_retry_pending_tx(void)
|
||||
{
|
||||
uint16_t send_len;
|
||||
uint32_t err;
|
||||
bool freed_slot = false;
|
||||
|
||||
if (!s_tx_pending)
|
||||
if (!ble_tx_pending_has_data())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (ble_connection_st != BLE_CONNECTED_ST)
|
||||
{
|
||||
s_tx_pending = false;
|
||||
s_tx_pending_len = 0;
|
||||
ble_tx_pending_clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
send_len = s_tx_pending_len;
|
||||
err = ble_nus_data_send(&m_nus, s_tx_pending_buf, &send_len, m_conn_handle);
|
||||
while (ble_tx_pending_has_data())
|
||||
{
|
||||
send_len = s_tx_pending_len[s_tx_pending_head];
|
||||
err = ble_nus_data_send(&m_nus, s_tx_pending_buf[s_tx_pending_head], &send_len, m_conn_handle);
|
||||
|
||||
if (err == NRF_SUCCESS)
|
||||
{
|
||||
s_tx_pending = false;
|
||||
s_tx_pending_len = 0;
|
||||
return true;
|
||||
}
|
||||
if (err == NRF_ERROR_RESOURCES)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (err == NRF_ERROR_INVALID_STATE || err == NRF_ERROR_NOT_FOUND)
|
||||
{
|
||||
DBG_PRINTF("[BLE TX] Pending send aborted\r\n");
|
||||
s_tx_pending = false;
|
||||
s_tx_pending_len = 0;
|
||||
return false;
|
||||
if (err == NRF_SUCCESS)
|
||||
{
|
||||
ble_tx_pending_pop();
|
||||
freed_slot = true;
|
||||
continue;
|
||||
}
|
||||
if (err == NRF_ERROR_RESOURCES)
|
||||
{
|
||||
return freed_slot;
|
||||
}
|
||||
if (err == NRF_ERROR_INVALID_STATE || err == NRF_ERROR_NOT_FOUND)
|
||||
{
|
||||
DBG_PRINTF("[BLE TX] Pending send aborted\r\n");
|
||||
ble_tx_pending_clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
DBG_PRINTF("[BLE TX] Pending err:0x%X\r\n", err);
|
||||
ble_tx_pending_pop();
|
||||
freed_slot = true;
|
||||
}
|
||||
|
||||
DBG_PRINTF("[BLE TX] Pending err:0x%X\r\n", err);
|
||||
s_tx_pending = false;
|
||||
s_tx_pending_len = 0;
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -652,7 +696,7 @@ static void nus_data_handler(ble_nus_evt_t * p_evt)
|
||||
else if (p_evt->type == BLE_NUS_EVT_TX_RDY)
|
||||
{
|
||||
/* First drain any queued packet that previously hit NRF_ERROR_RESOURCES. */
|
||||
if (s_tx_pending)
|
||||
if (ble_tx_pending_has_data())
|
||||
{
|
||||
if (!ble_retry_pending_tx())
|
||||
{
|
||||
@@ -1072,7 +1116,7 @@ static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
|
||||
m_tx_in_progress = false;
|
||||
|
||||
maa_async_abort(); // Prevent hang caused by async measurement state
|
||||
s_tx_pending = false; // Clear pending TX
|
||||
ble_tx_pending_clear(); // Clear pending TX
|
||||
|
||||
/* Adjust advertising duration at runtime based on disconnect reason */
|
||||
(void)sd_ble_gap_adv_stop(m_advertising.adv_handle);
|
||||
@@ -1554,16 +1598,16 @@ void param_error(const char *cmd)
|
||||
dr_binary_tx_safe(ble_bin_buffer, 3);
|
||||
}
|
||||
|
||||
void dr_binary_tx_safe(uint8_t const *ble_bin_buff, uint16_t length)
|
||||
uint32_t dr_binary_tx_safe(uint8_t const *ble_bin_buff, uint16_t length)
|
||||
{
|
||||
uint32_t err_code;
|
||||
static uint8_t tx_buffer[BLE_NUS_MAX_DATA_LEN] = {0};
|
||||
uint16_t send_len;
|
||||
uint16_t total_len;
|
||||
|
||||
if (ble_connection_st == 0) return;
|
||||
if (ble_connection_st == 0) return NRF_ERROR_INVALID_STATE;
|
||||
|
||||
if (length * sizeof(uint16_t) > (BLE_NUS_MAX_DATA_LEN - 2)) return;
|
||||
if (length * sizeof(uint16_t) > (BLE_NUS_MAX_DATA_LEN - 2)) return NRF_ERROR_DATA_SIZE;
|
||||
|
||||
if (ble_connection_st == BLE_CONNECTED_ST)
|
||||
{
|
||||
@@ -1573,37 +1617,48 @@ void dr_binary_tx_safe(uint8_t const *ble_bin_buff, uint16_t length)
|
||||
tx_buffer[length * sizeof(uint16_t) + 1] = (uint8_t)((crc >> 8) & 0xFF);
|
||||
|
||||
total_len = length * sizeof(uint16_t) + 2;
|
||||
|
||||
if (ble_tx_pending_has_data())
|
||||
{
|
||||
if (!ble_tx_pending_enqueue(tx_buffer, total_len))
|
||||
{
|
||||
DBG_PRINTF("[BLE TX] Pending queue full, dropping new packet\r\n");
|
||||
return NRF_ERROR_NO_MEM;
|
||||
}
|
||||
|
||||
return NRF_ERROR_RESOURCES;
|
||||
}
|
||||
|
||||
send_len = total_len;
|
||||
err_code = ble_nus_data_send(&m_nus, tx_buffer, &send_len, m_conn_handle);
|
||||
|
||||
if (err_code == NRF_SUCCESS)
|
||||
{
|
||||
return;
|
||||
return NRF_SUCCESS;
|
||||
}
|
||||
else if (err_code == NRF_ERROR_RESOURCES)
|
||||
{
|
||||
if (s_tx_pending)
|
||||
if (!ble_tx_pending_enqueue(tx_buffer, total_len))
|
||||
{
|
||||
DBG_PRINTF("[BLE TX] Pending queue busy, dropping new packet\r\n");
|
||||
return;
|
||||
DBG_PRINTF("[BLE TX] Pending queue full, dropping new packet\r\n");
|
||||
return NRF_ERROR_NO_MEM;
|
||||
}
|
||||
|
||||
memcpy(s_tx_pending_buf, tx_buffer, total_len);
|
||||
s_tx_pending_len = total_len;
|
||||
s_tx_pending = true;
|
||||
return;
|
||||
return NRF_ERROR_RESOURCES;
|
||||
}
|
||||
else if (err_code == NRF_ERROR_INVALID_STATE || err_code == NRF_ERROR_NOT_FOUND)
|
||||
{
|
||||
DBG_PRINTF("[BLE TX] Disconnected\r\n");
|
||||
return;
|
||||
return err_code;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG_PRINTF("[BLE TX] Err:0x%X\r\n", err_code);
|
||||
return;
|
||||
return err_code;
|
||||
}
|
||||
}
|
||||
|
||||
return NRF_ERROR_INVALID_STATE;
|
||||
}
|
||||
|
||||
/*==============================================================================
|
||||
|
||||
Reference in New Issue
Block a user