Bit-bang SPI(8MHz)에서 HW SPI(SPIM3, 16MHz)로 변경

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
jhChun
2026-03-19 18:04:04 +09:00
parent aa3c040ae0
commit 75ee2187d6
4 changed files with 226 additions and 341 deletions

View File

@@ -408,6 +408,8 @@ static int Cmd_mpc(const ParsedCmd *cmd); /* mpc? 피에조 버스트 발생 (
static int Cmd_mec(const ParsedCmd *cmd); /* mec? 피에조 버스트 + 에코 캡처 (16비트 원시) */
static int Cmd_maa(const ParsedCmd *cmd); /* maa? 6채널 전체 캡처 (비동기 전송) */
static int Cmd_mbb(const ParsedCmd *cmd); /* mbb? 6채널 캡처 + 센서 측정 (배터리 + 온도 + IMU) */
static int Cmd_mcf(const ParsedCmd *cmd); /* mcf? 피에조 파라미터 읽기 (FDS) */
static int Cmd_mcs(const ParsedCmd *cmd); /* mcs? 피에조 파라미터 쓰기 (FDS) */
/* ---- 명령 테이블 ---- */
@@ -451,6 +453,8 @@ static CmdEntry g_cmd_table[] = {
{ "mec?", true, Cmd_mec },
{ "maa?", true, Cmd_maa },
{ "mbb?", true, Cmd_mbb },
{ "mcf?", true, Cmd_mcf },
{ "mcs?", true, Cmd_mcs },
};
/* 명령 테이블 엔트리 수 (컴파일 타임 계산) */
@@ -838,12 +842,10 @@ static int Cmd_mec(const ParsedCmd *cmd)
uint16_t averaging = 1; /* 기본 1 (평균화 없음), 최대 1000 */
uint16_t piezo_ch = 0; /* 기본 채널 0 (유효: 0~7) */
/* 피에조 전원이 꺼져 있으면 자동으로 켜기 */
bool auto_powered = false;
/* 피에조 전원이 꺼져 있으면 켜기 */
if (!dr_piezo_is_power_on()) {
if (g_plat.log) g_plat.log("[Cmd_mec] TX/RX Sleep -> Active\r\n");
dr_piezo_system_init();
auto_powered = true;
}
/* 6개 파라미터 순서대로 추출 (데이터 부족 시 기본값 유지) */
@@ -884,13 +886,20 @@ static int Cmd_mec(const ParsedCmd *cmd)
if (g_plat.log && g_log_enable) {
g_plat.log("[Cmd_mec] result=%d\r\n", err);
/* raw 데이터 덤프 */
const uint16_t *buf = dr_adc_get_echo_buffer();
g_plat.log("[mec] CH%u raw (%u samples):\r\n", piezo_ch, num_samples);
for (uint16_t i = 0; i < num_samples; i++) {
g_plat.log("%u ", buf[i]);
if ((i + 1) % 16 == 0) g_plat.log("\r\n");
}
if (num_samples % 16 != 0) g_plat.log("\r\n");
}
/* 자동으로 켰으면 완료 후 전원 OFF */
if (auto_powered) {
if (g_plat.log) g_plat.log("[Cmd_mec] TX/RX Active -> Sleep\r\n");
dr_piezo_power_off();
}
/* 측정 완료 후 무조건 전원 OFF */
if (g_plat.log) g_plat.log("[Cmd_mec] TX/RX Active -> Sleep\r\n");
dr_piezo_power_off();
return 1;
}
@@ -1007,14 +1016,11 @@ static int Cmd_maa(const ParsedCmd *cmd)
return 1;
}
/* 피에조 전원이 꺼져 있으면 자동으로 켜기 */
bool auto_powered = false;
bool pwr = dr_piezo_is_power_on();
if (g_plat.log) g_plat.log("[Cmd_maa] piezo_power=%u\r\n", pwr);
if (!pwr) {
/* 피에조 전원: OFF일 경우 ON → 완료 후 OFF */
if (!dr_piezo_is_power_on())
{
if (g_plat.log) g_plat.log("[Cmd_maa] TX/RX Sleep -> Active\r\n");
dr_piezo_system_init();
auto_powered = true;
}
/*=======================================================================
@@ -1038,12 +1044,13 @@ static int Cmd_maa(const ParsedCmd *cmd)
if (g_plat.log) g_plat.log("[Cmd_maa] start failed err=%d\r\n", err);
single_format_data(ble_bin_buffer, "raa:", (uint16_t)(0xFF00 | err));
dr_binary_tx_safe(ble_bin_buffer, 3);
if (auto_powered) dr_piezo_power_off();
dr_piezo_power_off();
return 1;
}
/* 자동 전원 플래그 설정 → 비동기 완료 시 자동 OFF */
maa_async_set_auto_power(auto_powered);
/* 측정 완료 시 무조건 전원 OFF */
//maa_async_set_auto_power(true);
//dr_piezo_power_off();
/* 즉시 반환 → 비동기 전송 진행 중 */
/* 전체 완료 시 상태 머신이 "raa:" 응답 + 자동 power off 처리 */
@@ -1086,7 +1093,7 @@ static void all_sensors(void)
dr_sd_delay_ms(50); /* SAADC 콜백 완료 대기 */
info4 = false;
/* rbb: 패킷 조립 및 전송 : [TAG 4B] [배터리 2B] [IMU 12B] [온도 2B] = 20바이트 = 10워드 */
uint8_t *buf = ble_bin_buffer;
@@ -1094,7 +1101,8 @@ static void all_sensors(void)
buf[4] = (uint8_t)(info_batt & 0xFF);
buf[5] = (uint8_t)(info_batt >> 8);
for (int i = 0; i < 6; i++) {
for (int i = 0; i < 6; i++)
{
buf[6 + i * 2] = (uint8_t)(info_imu[i] & 0xFF);
buf[6 + i * 2 + 1] = (uint8_t)(info_imu[i] >> 8);
}
@@ -1119,11 +1127,18 @@ static void all_sensors(void)
* 2) 각 채널(CH0~CH5): reb: [헤더] → red: [데이터...]
* 3) 캡처 완료: raa: [상태]
*/
static int Cmd_mbb(const ParsedCmd *cmd)
{
dr_adc_err_t err;
/* 파라미터 5개 수신 시 FDS에 저장 — 디버그 중 비활성화
if (g_plat.log) g_plat.log("[Cmd_mbb] params updated: freq=%u cyc=%u avg=%u delay=%u samples=%u\r\n",
m_config.piezo_freq_option, m_config.piezo_cycles,
m_config.piezo_averaging, m_config.piezo_delay_us,
m_config.piezo_num_samples);
// 파라미터 5개 수신 시 FDS에 저장 — 디버그 중 비활성화
/*
if (cmd->data_len >= 10) {
uint16_t freq, cycles, averaging, delay_us, num_samples;
dr_get_u16(cmd, 0, &freq);
@@ -1138,23 +1153,19 @@ static int Cmd_mbb(const ParsedCmd *cmd)
m_config.piezo_delay_us = delay_us;
m_config.piezo_num_samples = num_samples;
config_save();
if (g_plat.log) g_plat.log("[Cmd_mbb] params updated: freq=%u cyc=%u avg=%u delay=%u samples=%u\r\n",
m_config.piezo_freq_option, m_config.piezo_cycles,
m_config.piezo_averaging, m_config.piezo_delay_us,
m_config.piezo_num_samples);
}
*/
}*/
all_sensors();
dr_sd_delay_ms(20); /* SoftDevice 이벤트 정리 후 캡처 시작 */
if (maa_async_is_busy())
{
dr_ble_return_1("raa:", 0xFFFE);
return 1;
}
/* 피에조 전원: OFF일 경우 ON → 완료 후 OFF */
/* 피에조 전원: OFF일 경우 ON */
if (!dr_piezo_is_power_on())
{
if (g_plat.log) g_plat.log("[Cmd_mbb] TX/RX Sleep -> Active\r\n");
@@ -1166,6 +1177,9 @@ static int Cmd_mbb(const ParsedCmd *cmd)
m_config.piezo_averaging, m_config.piezo_delay_us,
m_config.piezo_num_samples);
/* 전채널 선캡처 모드: 모든 채널 캡처 완료 후 BLE 전송 */
maa_async_set_pre_capture_all(true);
/* 비동기 6채널 캡처 시작 (m_config 파라미터 사용) */
err = maa_async_start(
m_config.piezo_freq_option,
@@ -1185,8 +1199,81 @@ static int Cmd_mbb(const ParsedCmd *cmd)
return 1;
}
/* 완료 시 무조건 전원 OFF (전체 측정 사이클) */
maa_async_set_auto_power(true);
/* 완료 시 자동 전원 OFF */
//maa_async_set_auto_power(true);
return 1;
}
/**
* @brief mcf? - 피에조 파라미터 읽기 (FDS)
*
* 응답: rcf: [freq(2)] [cycles(2)] [avg(2)] [delay_us(2)] [num_samples(2)] = 14바이트 = 7워드
*/
static int Cmd_mcf(const ParsedCmd *cmd)
{
(void)cmd;
uint8_t *buf = ble_bin_buffer;
buf[0] = 'r'; buf[1] = 'c'; buf[2] = 'f'; buf[3] = ':';
buf[4] = m_config.piezo_freq_option; buf[5] = 0;
buf[6] = m_config.piezo_cycles; buf[7] = 0;
buf[8] = (uint8_t)(m_config.piezo_averaging & 0xFF); buf[9] = (uint8_t)(m_config.piezo_averaging >> 8);
buf[10] = (uint8_t)(m_config.piezo_delay_us & 0xFF); buf[11] = (uint8_t)(m_config.piezo_delay_us >> 8);
buf[12] = (uint8_t)(m_config.piezo_num_samples & 0xFF); buf[13] = (uint8_t)(m_config.piezo_num_samples >> 8);
dr_binary_tx_safe(buf, 7); /* 14바이트 = 7워드 */
if (g_plat.log) g_plat.log("[Cmd_mcf] freq=%u cyc=%u avg=%u delay=%u samples=%u\r\n",
m_config.piezo_freq_option, m_config.piezo_cycles,
m_config.piezo_averaging, m_config.piezo_delay_us,
m_config.piezo_num_samples);
return 1;
}
/**
* @brief mcs? - 피에조 파라미터 쓰기 (FDS)
*
* 파라미터: [freq(2)] [cycles(2)] [avg(2)] [delay_us(2)] [num_samples(2)] = 10바이트
* 응답: rcs: [저장된 5개 값] = 14바이트 = 7워드
*/
static int Cmd_mcs(const ParsedCmd *cmd)
{
if (cmd->data_len < 10) {
if (g_plat.log) g_plat.log("[Cmd_mcs] missing params (data_len=%u)\r\n", cmd->data_len);
dr_ble_return_1("rcs:", 0xFFFF);
return 1;
}
uint16_t freq, cycles, averaging, delay_us, num_samples;
dr_get_u16(cmd, 0, &freq);
dr_get_u16(cmd, 1, &cycles);
dr_get_u16(cmd, 2, &averaging);
dr_get_u16(cmd, 3, &delay_us);
dr_get_u16(cmd, 4, &num_samples);
m_config.piezo_freq_option = (uint8_t)freq;
m_config.piezo_cycles = (uint8_t)cycles;
m_config.piezo_averaging = averaging;
m_config.piezo_delay_us = delay_us;
m_config.piezo_num_samples = num_samples;
config_save();
if (g_plat.log) g_plat.log("[Cmd_mcs] saved: freq=%u cyc=%u avg=%u delay=%u samples=%u\r\n",
m_config.piezo_freq_option, m_config.piezo_cycles,
m_config.piezo_averaging, m_config.piezo_delay_us,
m_config.piezo_num_samples);
uint8_t *buf = ble_bin_buffer;
buf[0] = 'r'; buf[1] = 'c'; buf[2] = 's'; buf[3] = ':';
buf[4] = m_config.piezo_freq_option; buf[5] = 0;
buf[6] = m_config.piezo_cycles; buf[7] = 0;
buf[8] = (uint8_t)(m_config.piezo_averaging & 0xFF); buf[9] = (uint8_t)(m_config.piezo_averaging >> 8);
buf[10] = (uint8_t)(m_config.piezo_delay_us & 0xFF); buf[11] = (uint8_t)(m_config.piezo_delay_us >> 8);
buf[12] = (uint8_t)(m_config.piezo_num_samples & 0xFF); buf[13] = (uint8_t)(m_config.piezo_num_samples >> 8);
dr_binary_tx_safe(buf, 7); /* 14바이트 = 7워드 */
return 1;
}
@@ -1319,8 +1406,6 @@ static int Cmd_mqz(const ParsedCmd *cmd)
return 1;
}
/* 2026-03-17: mxz?, myz? 삭제 */
/*==============================================================================
* IMU: 6축 원시 데이터 (단발 읽기)
*============================================================================*/