/******************************************************************************* * @file i2c_manager.c * @brief Reliable HW↔SW I2C Switching Logic (with Mode Set Logging) ******************************************************************************/ #include "i2c_manager.h" #include "debug_print.h" #include "nrf_delay.h" #include "nrf_drv_twi.h" #include "nrfx_twi.h" #include "boards.h" #include "system_interface.h" bool HW_I2C_FRQ = true; bool SW_I2C_FRQ = false; #define TWI_INSTANCE 0 /* TWI (I2C) 하드웨어 인스턴스 : IMU 드라이버에서 사용 - jhChun 26.03.16 */ const nrfx_twi_t m_twi = NRFX_TWI_INSTANCE(TWI_INSTANCE); /* TWI (I2C) 해제 - jhChun 26.03.16 */ static void twi_uninitialize(void){ nrfx_twi_disable(&m_twi); nrfx_twi_uninit(&m_twi); } /* TWI (I2C) 하드웨어 초기화 (SCL/SDA핀, 400kHz) - jhChun 26.03.16 */ static void twi_initialize(void){ ret_code_t err_code; const nrfx_twi_config_t twi_config = { .scl = ICM42670_I2C_SCL_PIN, .sda = ICM42670_I2C_SDA_PIN, .frequency = NRF_TWI_FREQ_400K, .interrupt_priority = APP_IRQ_PRIORITY_HIGH, }; err_code = nrfx_twi_init(&m_twi, &twi_config, NULL, NULL); APP_ERROR_CHECK(err_code); nrfx_twi_enable(&m_twi); } /* -------------------------------------------------------------------------- */ /* HW (TWI) 초기화 */ /* -------------------------------------------------------------------------- */ void hw_i2c_init_once(void) { // SW 모드일 경우 강제 해제 후 HW 전환 if (SW_I2C_FRQ) { //DBG_PRINTF("[I2C]SW→HW\r\n"); // SW 리소스 해제 (필요 시 추가) SW_I2C_FRQ = false; nrf_delay_ms(2); } // 이미 HW면 스킵 if (HW_I2C_FRQ) { // DBG_PRINTF("[I2C] HW I2C set\r\n"); return; } // 실제 HW 초기화 twi_initialize(); nrf_delay_ms(2); HW_I2C_FRQ = true; SW_I2C_FRQ = false; // DBG_PRINTF("[I2C] HW I2C Mode set!\r\n"); } /* -------------------------------------------------------------------------- */ /* SW (Port Bang-Bang) 초기화 */ /* -------------------------------------------------------------------------- */ void sw_i2c_init_once(void) { // HW 모드일 경우 강제 해제 후 SW 전환 if (HW_I2C_FRQ) { //DBG_PRINTF("[I2C]HW→SW\r\n"); nrfx_twi_disable(&m_twi); nrfx_twi_uninit(&m_twi); nrf_delay_ms(2); HW_I2C_FRQ = false; } // 이미 SW 모드면 재실행 금지 if (SW_I2C_FRQ) { // DBG_PRINTF("[I2C] SWI2C already initialized\r\n"); return; } // 실제 SW 초기화 twi_uninitialize(); // TWI 라인 해제 nrf_delay_ms(1); SW_I2C_FRQ = true; HW_I2C_FRQ = false; // DBG_PRINTF("[I2C] SW I2C Mode set!\r\n"); } /* -------------------------------------------------------------------------- */ /* 전체 리셋 */ /* -------------------------------------------------------------------------- */ void i2c_reset_state(void) { HW_I2C_FRQ = false; SW_I2C_FRQ = false; DBG_PRINTF("Flags reset\r\n"); }