MTU에 따른 BLE 패킷 분할 - IMU FIFO 응답 패킷
- 협상된 MTU 기준으로 rim: 응답 패킷 크기 판단 - 기존 rim:이 MTU에 들어가지 않으면 ric: chunk 분할 전송
This commit is contained in:
@@ -28,6 +28,8 @@ static uint8_t g_echo_session;
|
|||||||
#define REB_OVERHEAD_SIZE 10U
|
#define REB_OVERHEAD_SIZE 10U
|
||||||
#define REC_OVERHEAD_SIZE 14U
|
#define REC_OVERHEAD_SIZE 14U
|
||||||
#define ECHO_SAMPLE_SIZE 2U
|
#define ECHO_SAMPLE_SIZE 2U
|
||||||
|
#define RIM_OVERHEAD_SIZE 8U
|
||||||
|
#define RIC_OVERHEAD_SIZE 12U
|
||||||
|
|
||||||
uint8_t cmd_next_echo_session(void)
|
uint8_t cmd_next_echo_session(void)
|
||||||
{
|
{
|
||||||
@@ -347,7 +349,7 @@ void cmd_send_response_bundle(uint16_t batt_mv, const int16_t accel[3], const in
|
|||||||
ble_data_send(buf, sizeof(tx_bundle_buf));
|
ble_data_send(buf, sizeof(tx_bundle_buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmd_send_response_rim(const uint8_t *sample_bytes, uint16_t sample_count)
|
static void cmd_send_response_rim_legacy(const uint8_t *sample_bytes, uint16_t sample_count)
|
||||||
{
|
{
|
||||||
uint8_t *buf = tx_rim_buf;
|
uint8_t *buf = tx_rim_buf;
|
||||||
uint16_t payload_len;
|
uint16_t payload_len;
|
||||||
@@ -369,9 +371,98 @@ void cmd_send_response_rim(const uint8_t *sample_bytes, uint16_t sample_count)
|
|||||||
buf[payload_len + 1U] = (uint8_t)(crc >> 8);
|
buf[payload_len + 1U] = (uint8_t)(crc >> 8);
|
||||||
|
|
||||||
DBG_PRINTF("[MTB] tx rim samples=%u len=%u\r\n", sample_count, (uint16_t)(payload_len + 2U));
|
DBG_PRINTF("[MTB] tx rim samples=%u len=%u\r\n", sample_count, (uint16_t)(payload_len + 2U));
|
||||||
|
|
||||||
ble_data_send(buf, (uint16_t)(payload_len + 2U));
|
ble_data_send(buf, (uint16_t)(payload_len + 2U));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint16_t calc_ric_samples_per_packet(uint16_t notify_payload_max)
|
||||||
|
{
|
||||||
|
if (notify_payload_max < (RIC_OVERHEAD_SIZE + IMU_FIFO_SAMPLE_BYTES))
|
||||||
|
{
|
||||||
|
return 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (uint16_t)((notify_payload_max - RIC_OVERHEAD_SIZE) / IMU_FIFO_SAMPLE_BYTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ric: packet layout:
|
||||||
|
* tag (4B): "ric:"
|
||||||
|
* offset (2B): 전체 샘플 배열에서 시작 인덱스
|
||||||
|
* total_samples (2B): 전체 IMU FIFO 샘플 수
|
||||||
|
* chunk_samples (2B): 현재 패킷에 들어간 샘플 수
|
||||||
|
* sample data (N): IMU FIFO samples
|
||||||
|
* crc (2B): tag부터 sample data까지 CRC16
|
||||||
|
*/
|
||||||
|
static void cmd_send_response_rim_ric(const uint8_t *sample_bytes, uint16_t sample_count, uint16_t samples_per_pkt)
|
||||||
|
{
|
||||||
|
uint8_t *buf = tx_rim_buf;
|
||||||
|
|
||||||
|
for (uint16_t off = 0U; off < sample_count; off = (uint16_t)(off + samples_per_pkt))
|
||||||
|
{
|
||||||
|
uint16_t remain = (uint16_t)(sample_count - off);
|
||||||
|
uint16_t chunk_samples = MIN(samples_per_pkt, remain);
|
||||||
|
|
||||||
|
buf[0] = 'r'; buf[1] = 'i'; buf[2] = 'c'; buf[3] = ':';
|
||||||
|
buf[4] = (uint8_t)(off >> 8);
|
||||||
|
buf[5] = (uint8_t)(off & 0xFF);
|
||||||
|
buf[6] = (uint8_t)(sample_count >> 8);
|
||||||
|
buf[7] = (uint8_t)(sample_count & 0xFF);
|
||||||
|
buf[8] = (uint8_t)(chunk_samples >> 8);
|
||||||
|
buf[9] = (uint8_t)(chunk_samples & 0xFF);
|
||||||
|
|
||||||
|
memcpy(&buf[10], &sample_bytes[off * IMU_FIFO_SAMPLE_BYTES], (size_t)chunk_samples * IMU_FIFO_SAMPLE_BYTES);
|
||||||
|
|
||||||
|
uint16_t payload_len = (uint16_t)(RIC_OVERHEAD_SIZE - 2U + (chunk_samples * IMU_FIFO_SAMPLE_BYTES));
|
||||||
|
uint16_t crc = cmd_crc16_compute(buf, payload_len);
|
||||||
|
DBG_PRINTF("[CMD] ric tx off=%u total=%u chunk=%u len=%u\r\n",
|
||||||
|
off, sample_count, chunk_samples, (uint16_t)(payload_len + 2U));
|
||||||
|
|
||||||
|
buf[payload_len] = (uint8_t)(crc & 0xFF);
|
||||||
|
buf[payload_len + 1U] = (uint8_t)(crc >> 8);
|
||||||
|
|
||||||
|
if (ble_data_send(buf, (uint16_t)(payload_len + 2U)) != 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cmd_send_response_rim(const uint8_t *sample_bytes, uint16_t sample_count)
|
||||||
|
{
|
||||||
|
uint16_t notify_payload_max = 0U;
|
||||||
|
uint16_t mtu = ble_current_mtu();
|
||||||
|
|
||||||
|
if (sample_count > IMU_FIFO_RIM_TARGET_SAMPLES)
|
||||||
|
{
|
||||||
|
sample_count = IMU_FIFO_RIM_TARGET_SAMPLES;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t rim_len = (uint16_t)(RIM_OVERHEAD_SIZE + (sample_count * IMU_FIFO_SAMPLE_BYTES));
|
||||||
|
|
||||||
|
if (mtu > ATT_NOTIFY_HEADER_SIZE)
|
||||||
|
{
|
||||||
|
notify_payload_max = (uint16_t)(mtu - ATT_NOTIFY_HEADER_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((notify_payload_max == 0U) || (rim_len <= notify_payload_max))
|
||||||
|
{
|
||||||
|
cmd_send_response_rim_legacy(sample_bytes, sample_count);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t samples_per_pkt = calc_ric_samples_per_packet(notify_payload_max);
|
||||||
|
|
||||||
|
if (samples_per_pkt == 0U)
|
||||||
|
{
|
||||||
|
DBG_ERR("[CMD] ric skip mtu=%u payload=%u samples=%u\r\n", mtu, notify_payload_max, sample_count);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
DBG_PRINTF("[CMD] ric split mtu=%u samples=%u chunk=%u\r\n", mtu, sample_count, samples_per_pkt);
|
||||||
|
cmd_send_response_rim_ric(sample_bytes, sample_count, samples_per_pkt);
|
||||||
|
}
|
||||||
|
|
||||||
void cmd_send_response_piezo_config(const char *tag, uint16_t freq, uint16_t cycles, uint16_t avg, uint16_t delay_us, uint16_t samples)
|
void cmd_send_response_piezo_config(const char *tag, uint16_t freq, uint16_t cycles, uint16_t avg, uint16_t delay_us, uint16_t samples)
|
||||||
{
|
{
|
||||||
uint8_t *buf = tx_cfg_buf;
|
uint8_t *buf = tx_cfg_buf;
|
||||||
|
|||||||
Reference in New Issue
Block a user