Compare commits
2 Commits
a805c0ab78
...
ed3a8d7acd
| Author | SHA1 | Date | |
|---|---|---|---|
| ed3a8d7acd | |||
| 7b8103a530 |
@@ -119,20 +119,20 @@ int setup_imu_device(struct inv_imu_serif *icm_serif)
|
||||
/* IMU 드라이버 초기화 — 시리얼 인터페이스 연결 및 콜백 함수 등록 */
|
||||
rc = inv_imu_init(&icm_driver, icm_serif, imu_callback);
|
||||
if (rc != INV_ERROR_SUCCESS) {
|
||||
printf("!!! ERROR : Failed to initialize IMU!\r\n");
|
||||
DBG_PRINTF("!!! ERROR : Failed to initialize IMU!\r\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* WHOAMI 레지스터 읽기 — 디바이스 존재 및 통신 확인 */
|
||||
rc = inv_imu_get_who_am_i(&icm_driver, &who_am_i);
|
||||
if (rc != INV_ERROR_SUCCESS) {
|
||||
printf("!!! ERROR : Failed to read whoami!\r\n");
|
||||
DBG_PRINTF("!!! ERROR : Failed to read whoami!\r\n");
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* WHOAMI 값 검증 — ICM42670P의 경우 0x67이어야 함 */
|
||||
if (who_am_i != ICM_WHOAMI) {
|
||||
printf("!!! ERROR : Bad WHOAMI value! Read 0x%02x, expected 0x%02x\r\n", who_am_i, ICM_WHOAMI);
|
||||
DBG_PRINTF("!!! ERROR : Bad WHOAMI value! Read 0x%02x, expected 0x%02x\r\n", who_am_i, ICM_WHOAMI);
|
||||
return INV_ERROR;
|
||||
}
|
||||
|
||||
@@ -354,7 +354,7 @@ void imu_callback(inv_imu_sensor_event_t *event)
|
||||
* 스케일링된 데이터를 UART로 출력
|
||||
*/
|
||||
if (event->sensor_mask & (1 << INV_SENSOR_ACCEL) && event->sensor_mask & (1 << INV_SENSOR_GYRO))
|
||||
printf("%u: %.3f, \t%.3f, \t%.3f, \t%.3f, \t%.3f, \t%.3f, \t%.3f\r\n",
|
||||
DBG_PRINTF("%u: %.3f, \t%.3f, \t%.3f, \t%.3f, \t%.3f, \t%.3f, \t%.3f\r\n",
|
||||
(uint32_t)timestamp,
|
||||
accel_g[0], accel_g[1], accel_g[2],
|
||||
temp_degc,
|
||||
@@ -381,7 +381,7 @@ void imu_callback(inv_imu_sensor_event_t *event)
|
||||
|
||||
/* UART 모드: "Tp" 접두사로 6축 데이터를 텍스트 형식으로 출력 */
|
||||
else if(cmd_type_t == CMD_UART) {
|
||||
printf("Tp%d,%d,%d,%d,%d,%d\r\n\r\n", accel[0], accel[1], accel[2], gyro[0], gyro[1], gyro[2]);
|
||||
DBG_PRINTF("Tp%d,%d,%d,%d,%d,%d\r\n\r\n", accel[0], accel[1], accel[2], gyro[0], gyro[1], gyro[2]);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -399,7 +399,7 @@ void imu_callback(inv_imu_sensor_event_t *event)
|
||||
ssp_data[5] = (uint16_t)gyro[2];
|
||||
|
||||
format_data(imu_bin_buffer, "rsp:", ssp_data,12);
|
||||
printf("Tp%d,%d,%d,%d,%d,%d\r\n\r\n", accel[0], accel[1], accel[2], gyro[0], gyro[1], gyro[2]);
|
||||
DBG_PRINTF("Tp%d,%d,%d,%d,%d,%d\r\n\r\n", accel[0], accel[1], accel[2], gyro[0], gyro[1], gyro[2]);
|
||||
dr_binary_tx_safe(imu_bin_buffer,8);
|
||||
|
||||
if(custom_add_data==true) {
|
||||
|
||||
@@ -271,6 +271,11 @@ bool erase_bonds; /* 본딩 삭제 플래그 (부팅 시 버튼 상
|
||||
volatile bool ble_connection_st; /* BLE 연결 상태 (1=연결됨, 0=미연결) */
|
||||
volatile bool data_tx_in_progress = false; /* 바이너리 TX 진행 중 플래그 */
|
||||
|
||||
/* ── BLE TX 비동기 재시도 상태 ── */
|
||||
static volatile bool s_tx_pending = false; /* TX 재시도 대기 중 */
|
||||
static uint8_t s_tx_pending_buf[BLE_NUS_MAX_DATA_LEN]; /* 대기 중인 패킷 (CRC 포함) */
|
||||
static uint16_t s_tx_pending_len = 0; /* 대기 중인 패킷 길이 */
|
||||
|
||||
|
||||
char m_static_passkey[PASSKEY_LENGTH] = "123456"; /* 정적 패스키 (6자리, FDS에서 로드) */
|
||||
char SERIAL_NO[SERIAL_NO_LENGTH]; /* 시리얼 번호 (BLE 디바이스 이름으로 사용) */
|
||||
@@ -651,6 +656,17 @@ static void nus_data_handler(ble_nus_evt_t * p_evt)
|
||||
{
|
||||
maa_async_on_tx_ready();
|
||||
}
|
||||
/* pending 패킷 재시도 (dr_binary_tx_safe 비동기) */
|
||||
else if (s_tx_pending)
|
||||
{
|
||||
uint16_t send_len = s_tx_pending_len;
|
||||
uint32_t err = ble_nus_data_send(&m_nus, s_tx_pending_buf, &send_len, m_conn_handle);
|
||||
if (err == NRF_SUCCESS)
|
||||
{
|
||||
s_tx_pending = false;
|
||||
}
|
||||
/* NRF_ERROR_RESOURCES → 다음 TX_RDY에서 다시 시도 */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1041,6 +1057,7 @@ static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
|
||||
m_tx_in_progress = false;
|
||||
|
||||
maa_async_abort(); // 비동기 측정 상태에 의한 먹통 현상 방지
|
||||
s_tx_pending = false; // pending TX 클리어
|
||||
|
||||
if (device_status == true)
|
||||
{
|
||||
@@ -1530,78 +1547,55 @@ void param_error(const char *cmd)
|
||||
dr_binary_tx_safe(ble_bin_buffer, 3);
|
||||
}
|
||||
|
||||
/* 기존 binary_tx_handler 함수 삭제 및 호출처 교체 - jhChun 26.03.16 */
|
||||
void dr_binary_tx_safe(uint8_t const *ble_bin_buff, uint16_t length) // BLE로 바이너리 데이터를 안전하게 전송하는 함수
|
||||
void 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 retry_count = 0;
|
||||
const uint16_t MAX_RETRIES = 100; /* 최대 재시도 횟수 (~500ms, 5ms x 100) */
|
||||
const uint16_t MAX_RETRIES = 20; /* 최대 재시도: 2ms × 20 = 40ms (기존 5ms × 100 = 500ms) */
|
||||
|
||||
if (ble_connection_st == 0) return; // 연결 확인
|
||||
if (ble_connection_st == 0) return;
|
||||
|
||||
data_tx_in_progress = true;
|
||||
|
||||
if (length * sizeof(uint16_t) > (BLE_NUS_MAX_DATA_LEN - 2)) { // 길이 검증 (CRC 2바이트 공간 확보)
|
||||
data_tx_in_progress = false;
|
||||
return;
|
||||
}
|
||||
if (length * sizeof(uint16_t) > (BLE_NUS_MAX_DATA_LEN - 2)) return;
|
||||
|
||||
if (ble_connection_st == BLE_CONNECTED_ST)
|
||||
{
|
||||
memcpy(tx_buffer, ble_bin_buff, length * sizeof(uint16_t));
|
||||
uint16_t crc = crc16_compute(tx_buffer, length * sizeof(uint16_t), NULL); // 버퍼 복사
|
||||
uint16_t crc = crc16_compute(tx_buffer, length * sizeof(uint16_t), NULL);
|
||||
tx_buffer[length * sizeof(uint16_t)] = (uint8_t)(crc & 0xFF);
|
||||
tx_buffer[length * sizeof(uint16_t) + 1] = (uint8_t)((crc >> 8) & 0xFF); // CRC16 2바이트 추가
|
||||
tx_buffer[length * sizeof(uint16_t) + 1] = (uint8_t)((crc >> 8) & 0xFF);
|
||||
|
||||
uint16_t total_len = length * sizeof(uint16_t) + 2;
|
||||
|
||||
/* 재시도 루프 - 재시도 사이에 SoftDevice가 이벤트를 처리할 수 있도록 함 */
|
||||
do {
|
||||
uint16_t send_len = total_len; /* 매 반복마다 리셋 필수 - ble_nus_data_send()가 값을 변경함! */
|
||||
uint16_t send_len = total_len;
|
||||
err_code = ble_nus_data_send(&m_nus, tx_buffer, &send_len, m_conn_handle);
|
||||
|
||||
if (err_code == NRF_SUCCESS) // 전송 성공 시 루프 탈출
|
||||
if (err_code == NRF_SUCCESS)
|
||||
{
|
||||
break;
|
||||
return;
|
||||
}
|
||||
else if (err_code == NRF_ERROR_RESOURCES) // TX 큐가 가득 찬 경우 5ms 대기 후 재시도 (최대 100회, ~500ms)
|
||||
else if (err_code == NRF_ERROR_RESOURCES)
|
||||
{
|
||||
/* BLE TX 큐 가득 참 - 연결 이벤트가 TX를 완료할 때까지 대기 */
|
||||
/* BLE 스택이 TX 완료 이벤트를 처리할 수 있도록 짧은 딜레이 */
|
||||
nrf_delay_ms(5); /* ~5ms 대기하여 TX 슬롯 확보 -> 대기 중 3.2mA 전력 소모 */
|
||||
|
||||
nrf_delay_ms(2); /* 기존 5ms → 2ms */
|
||||
retry_count++;
|
||||
}
|
||||
else if (err_code == NRF_ERROR_INVALID_STATE || err_code == NRF_ERROR_NOT_FOUND) // 연결 끊김, 리턴
|
||||
else if (err_code == NRF_ERROR_INVALID_STATE || err_code == NRF_ERROR_NOT_FOUND)
|
||||
{
|
||||
DBG_PRINTF("[BLE TX] Disconnected\r\n");
|
||||
data_tx_in_progress = false;
|
||||
return;
|
||||
}
|
||||
else // 기타 에러 -> 로그 출력 후 리턴
|
||||
else
|
||||
{
|
||||
DBG_PRINTF("[BLE TX] Err:0x%X\r\n", err_code);
|
||||
data_tx_in_progress = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
while (retry_count < MAX_RETRIES);
|
||||
} while (retry_count < MAX_RETRIES);
|
||||
|
||||
if (retry_count > 0)
|
||||
if (retry_count >= MAX_RETRIES)
|
||||
{
|
||||
DBG_PRINTF("[BLE TX] retry=%u (+%ums)\r\n", retry_count, retry_count * 5);
|
||||
}
|
||||
|
||||
if (retry_count >= MAX_RETRIES){ // 최대 재시도(100회) 초과 시 해당 패킷 드롭, 연결은 유지
|
||||
|
||||
DBG_PRINTF("[BLE TX] FAIL %u retries\r\n", retry_count);
|
||||
data_tx_in_progress = false;
|
||||
/* ble_connection_st = 0 설정하지 않음 - 해당 패킷만 드롭하고 연결은 유지 */
|
||||
return;
|
||||
}
|
||||
|
||||
data_tx_in_progress = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user