diff --git a/Src/0_Tool/PMIC_Tool/PMIC_Cmd_Tool/PMIC_Cmd_Tool.vcxproj b/Src/0_Tool/PMIC_Tool/PMIC_Cmd_Tool/PMIC_Cmd_Tool.vcxproj index aa3eb7e1..f6120fe2 100644 --- a/Src/0_Tool/PMIC_Tool/PMIC_Cmd_Tool/PMIC_Cmd_Tool.vcxproj +++ b/Src/0_Tool/PMIC_Tool/PMIC_Cmd_Tool/PMIC_Cmd_Tool.vcxproj @@ -165,10 +165,13 @@ xcopy /y /e "$(OutDir)*.*" "%TARGET_PATH%\" + + + diff --git a/Src/0_Tool/PMIC_Tool/PMIC_Cmd_Tool/PMIC_Cmd_Tool.vcxproj.filters b/Src/0_Tool/PMIC_Tool/PMIC_Cmd_Tool/PMIC_Cmd_Tool.vcxproj.filters index 88188ffb..003672f7 100644 --- a/Src/0_Tool/PMIC_Tool/PMIC_Cmd_Tool/PMIC_Cmd_Tool.vcxproj.filters +++ b/Src/0_Tool/PMIC_Tool/PMIC_Cmd_Tool/PMIC_Cmd_Tool.vcxproj.filters @@ -24,10 +24,19 @@ 헤더 파일 + + 헤더 파일 + + + 헤더 파일 + 소스 파일 + + 소스 파일 + \ No newline at end of file diff --git a/Src/0_Tool/PMIC_Tool/PMIC_Cmd_Tool/include/PMIC_Common_Include.h b/Src/0_Tool/PMIC_Tool/PMIC_Cmd_Tool/include/PMIC_Common_Include.h new file mode 100644 index 00000000..59039ad2 --- /dev/null +++ b/Src/0_Tool/PMIC_Tool/PMIC_Cmd_Tool/include/PMIC_Common_Include.h @@ -0,0 +1,23 @@ +#ifndef PMIC_COMMON_INCLUDE_H // Header Guard: ߺ include Ǵ +#define PMIC_COMMON_INCLUDE_H + +#include +#include +#include +#include +#include + +// Լ ̿ +#include +//Sleep(1); // 1ms +//Sleep(10); // 10ms +//Sleep(100); // 100ms +//Sleep(1000); // 1s +//Sleep(10000); // 10s + +// FT4222 +#include "ftd2xx.h" +#include "LibFT4222.h" + + +#endif // PMIC_COMMON_INCLUDE_H diff --git a/Src/0_Tool/PMIC_Tool/PMIC_Cmd_Tool/include/PMIC_Function.h b/Src/0_Tool/PMIC_Tool/PMIC_Cmd_Tool/include/PMIC_Function.h new file mode 100644 index 00000000..7d85703a --- /dev/null +++ b/Src/0_Tool/PMIC_Tool/PMIC_Cmd_Tool/include/PMIC_Function.h @@ -0,0 +1,32 @@ +#ifndef PMIC_FUNCTION_H // Header Guard: ߺ include Ǵ +#define PMIC_FUNCTION_H + +// PMIC Common Include +#include "PMIC_Common_Include.h" + +void toBinaryString(uint8_t val, char* outBuf); // 8Ʈ ͸ "0000_0000" ڿ ȯ +uint8_t calcCRC8(uint8_t addrWithRw, uint8_t* data, int len); // CRC8 (׽ 0x07, ʱⰪ 0x00) +void currentPreciseTime(char* buf, size_t len); // (00) и(000) (: 45.123) +void currentTime(char* buf, size_t len); // ð "HH:MM:SS" buf +void logPacket(const char* dir, uint8_t* data, int size, int hasCrc); // α (Ŀ ) +int parseCommand(const char* dir); // ɾ Ǻ (I2C_WRITE/w, I2C_READ/r) + + +void PMIC_I2C_Write(FT_HANDLE ftHandle, uint8_t slaveAddr, uint8_t regAddr, uint8_t value); // Address 1Ʈ Write with CRC, ׸ Address Readؼ Write +uint8_t PMIC_I2C_Read(FT_HANDLE ftHandle, uint8_t slaveAddr, uint8_t regAddr); // Address 1Ʈ Read (CRC ) + + +bool Run_DebugMode_On(FT_HANDLE ftHandle); // Enter Debug Mode On +bool Run_DebugMode_Off(FT_HANDLE ftHandle); // Enter Debug Mode Off +void Run_CheckFaults(FT_HANDLE ftHandle); // Check All Fault Registers +void Run_ReadChipInfo(FT_HANDLE ftHandle); // Read Chip Information (OTP/Version) +void Irq_Clear(FT_HANDLE ftHandle); // PMIC Irq Clear +void Set_Reset(FT_HANDLE ftHandle); // PMIC Set Reset +void Set_Error(FT_HANDLE ftHandle); // PMIC Set Error +void Set_CRC_On(FT_HANDLE ftHandle); // PMIC Set CRC ON +void Set_CRC_Off(FT_HANDLE ftHandle); // PMIC Set CRC OFF +void Set_FLT_MASK_B(FT_HANDLE ftHandle); // PMIC Set FLT_MASK_B +void Handle_ManualCommand(FT_HANDLE ftHandle, char* line); // Manual Command + + +#endif // PMIC_FUNCTION_H diff --git a/Src/0_Tool/PMIC_Tool/PMIC_Cmd_Tool/include/PMIC_Reg_Map.h b/Src/0_Tool/PMIC_Tool/PMIC_Cmd_Tool/include/PMIC_Reg_Map.h index 6137aacb..ddec0e65 100644 --- a/Src/0_Tool/PMIC_Tool/PMIC_Cmd_Tool/include/PMIC_Reg_Map.h +++ b/Src/0_Tool/PMIC_Tool/PMIC_Cmd_Tool/include/PMIC_Reg_Map.h @@ -1,8 +1,8 @@ -#pragma once +//#pragma once #ifndef PMIC_REG_MAP_H // Header Guard: ߺ include Ǵ #define PMIC_REG_MAP_H -#include +//#include /* ============================================================================ PMIC I2C Slave Addresses diff --git a/Src/0_Tool/PMIC_Tool/PMIC_Cmd_Tool/src/PMIC_Cmd_Tool.cpp b/Src/0_Tool/PMIC_Tool/PMIC_Cmd_Tool/src/PMIC_Cmd_Tool.cpp index 0884d1a8..563322ed 100644 --- a/Src/0_Tool/PMIC_Tool/PMIC_Cmd_Tool/src/PMIC_Cmd_Tool.cpp +++ b/Src/0_Tool/PMIC_Tool/PMIC_Cmd_Tool/src/PMIC_Cmd_Tool.cpp @@ -1,61 +1,10 @@ -#include -#include -#include -#include -#include - -// 딜레이 함수 이용을 위해 -#include -//Sleep(1); // 1ms 딜레이 -//Sleep(10); // 10ms 딜레이 -//Sleep(100); // 100ms 딜레이 -//Sleep(1000); // 1s 딜레이 -//Sleep(10000); // 10s 딜레이 - -// FT4222 헤더 -#include "ftd2xx.h" -#include "LibFT4222.h" - -// PMIC Register Map -#include "PMIC_Reg_Map.h" - -typedef enum { - MENU_EXIT = 0, - MENU_DEBUG_MODE = 1, - MENU_CHECK_FAULTS = 2, - MENU_READ_INFO = 3, - // Add more features here... -} PMIC_MENU; + +#include "PMIC_Common_Include.h" +#include "PMIC_Function.h" // Function Prototypes FT_HANDLE InitializeFT4222(); -void currentPreciseTime(char* buf, size_t len); // 초(00)와 밀리초(000) 포맷으로 저장 (예: 45.123) -void currentTime(char* buf, size_t len); // 현재 시간을 "HH:MM:SS" 형식으로 buf에 저장 -void logPacket(const char* dir, uint8_t* data, int size, int hasCrc); // 로그 출력 (커스텀 포맷) -uint8_t calcCRC8(uint8_t addrWithRw, uint8_t* data, int len); // CRC8 계산 (다항식 0x07, 초기값 0x00) -int parseCommand(const char* dir); // 명령어 판별 (I2C_WRITE/w, I2C_READ/r) - -void PMIC_I2C_Write(FT_HANDLE ftHandle, uint8_t slaveAddr, uint8_t regAddr, uint8_t value); // Address에 1바이트 Write with CRC, 그리고 Address를 Read해서 Write한 값과 비교 -uint8_t PMIC_I2C_Read(FT_HANDLE ftHandle, uint8_t slaveAddr, uint8_t regAddr); // Address에서 1바이트 Read (CRC 계산 없음) - -void toBinaryString(uint8_t val, char* outBuf); // 8비트 데이터를 "0000_0000" 형식의 문자열로 변환 -bool Run_DebugMode_On(FT_HANDLE ftHandle); // Enter Debug Mode On -bool Run_DebugMode_Off(FT_HANDLE ftHandle); // Enter Debug Mode Off -void Run_CheckFaults(FT_HANDLE ftHandle); // Check All Fault Registers -void Run_ReadChipInfo(FT_HANDLE ftHandle); // Read Chip Information (OTP/Version) -void Irq_Clear(FT_HANDLE ftHandle); // PMIC Irq Clear -void Set_Reset(FT_HANDLE ftHandle); // PMIC Set Reset -void Set_Error(FT_HANDLE ftHandle); // PMIC Set Error -void Set_CRC_On(FT_HANDLE ftHandle); // PMIC Set CRC ON -void Set_CRC_Off(FT_HANDLE ftHandle); // PMIC Set CRC OFF - -void Set_FLT_MASK_B(FT_HANDLE ftHandle); // PMIC Set FLT_MASK_B - - - -void Handle_ManualCommand(FT_HANDLE ftHandle, char* line); // Manual Command - int main() { char line[256]; @@ -262,545 +211,3 @@ FT_HANDLE InitializeFT4222() { return handle; #endif } - -// 초(00)와 밀리초(000) 포맷으로 저장 (예: 45.123) -void currentPreciseTime(char* buf, size_t len) -{ - SYSTEMTIME st; - GetLocalTime(&st); // 시스템의 현재 지역 시간(밀리초 포함)을 가져옴 - - sprintf_s(buf, len, "%02d.%03d", st.wSecond, st.wMilliseconds); -} - -// 현재 시간을 "HH:MM:SS" 형식으로 buf에 저장 -void currentTime(char* buf, size_t len) -{ - if (buf == nullptr || len == 0) - return; - - time_t now = time(nullptr); - struct tm tm_buf; - -#ifdef _WIN32 - localtime_s(&tm_buf, &now); // Windows 안전 버전 -#else - localtime_r(&now, &tm_buf); // Linux/Unix 안전 버전 -#endif - - strftime(buf, len, "%H:%M:%S", &tm_buf); -} - -// 로그 출력 (커스텀 포맷) -void logPacket(const char* dir, uint8_t* data, int size, int hasCrc) -{ - if (dir == nullptr || data == nullptr || size <= 0) - return; - - char timeBuf[16]; // ss.fff 형식이므로 16바이트면 충분합니다. - currentPreciseTime(timeBuf, sizeof(timeBuf)); // 수정된 시간 함수 호출 - //currentTime(timeBuf, sizeof(timeBuf)); - - // 1. PMIC I2C WRITE (보통 RegAddr + Value + CRC 순서) - if (strcmp(dir, "PMIC I2C WRITE") == 0 && size >= 3) { - printf("[%s] [%s] [RegAddr: 0x%02X] [Value: 0x%02X] [CRC: 0x%02X]\n", - timeBuf, dir, data[0], data[1], data[2]); - return; - } - - // 2. PMIC I2C READ (보통 Value + CRC 순서) - if (strcmp(dir, "PMIC I2C READ") == 0 && size >= 2) { - printf("[%s] [%s] [Value: 0x%02X] [CRC: 0x%02X]\n", - timeBuf, dir, data[0], data[1]); - return; - } - - // 3. 기본 출력 (위의 조건에 해당하지 않는 기타 패킷) - printf("[%s] [%s] ", timeBuf, dir); - for (int i = 0; i < size; i++) { - if (hasCrc && i == size - 1) - printf("[CRC: 0x%02X] ", data[i]); - else if (i == 0 && size > 1) // 첫 바이트를 Value로 가정할 경우 - printf("[Value: 0x%02X] ", data[i]); - else - printf("0x%02X ", data[i]); - } - - printf("\n"); -} - -// CRC8 계산 (다항식 0x07, 초기값 0x00) -uint8_t calcCRC8(uint8_t addrWithRw, uint8_t* data, int len) -{ - uint8_t crc = 0x00; - - for (int j = -1; j < len; j++) { - uint8_t b = (j == -1) ? addrWithRw : data[j]; - crc ^= b; - for (int i = 0; i < 8; i++) { - if (crc & 0x80) - crc = (crc << 1) ^ 0x07; - else - crc <<= 1; - } - } - return crc; -} - -// 명령어 판별 (I2C_WRITE/w, I2C_READ/r) -int parseCommand(const char* dir) -{ - if (strcmp(dir, "I2C_WRITE") == 0 || strcmp(dir, "W") == 0) - return 1; - if (strcmp(dir, "I2C_READ") == 0 || strcmp(dir, "R") == 0) - return 2; - return 0; -} - -// Address에 1바이트 Write with CRC, 그리고 Address를 Read해서 Write한 값과 비교 -void PMIC_I2C_Write(FT_HANDLE ftHandle, uint8_t slaveAddr, uint8_t regAddr, uint8_t value) -{ - uint8_t bytes[3]; - int len = 0; - - // Write 패킷: [RegAddr] [Value] [CRC] - bytes[len++] = regAddr; - bytes[len++] = value; - - uint8_t addrWithRw = (slaveAddr << 1) | 0x00; // Write 주소 - uint8_t crc = calcCRC8(addrWithRw, bytes, len); - bytes[len++] = crc; - - uint16 transferred = 0; - FT4222_STATUS st = FT4222_I2CMaster_Write(ftHandle, slaveAddr, bytes, (uint16)len, &transferred); - - if (st != FT4222_OK) { - printf("I2C Write Fail\n"); - return; - } - else { - //logPacket("PMIC I2C WRITE", bytes, len, 1); - } - - // Read 해서 값 비교하기 OFF -#if 0 - // Register Address 다시 Write (Read 시작 위치 지정) - uint8_t regOnly[1] = { regAddr }; - st = FT4222_I2CMaster_Write(ftHandle, slaveAddr, regOnly, 1, &transferred); - - if (st != FT4222_OK) { - printf("Read용 Address Write Fail\n"); - return; - } - - // Register Address에서 2바이트 Read - uint8_t rx[2] = { 0 }; - st = FT4222_I2CMaster_Read(ftHandle, slaveAddr, rx, 2, &transferred); - - if (st != FT4222_OK) { - printf("I2C Read Fail\n"); - return; - } - else { - logPacket("PMIC I2C READ ", rx, transferred, 0); - - // 첫 번째 바이트와 Write 값 비교 - if (rx[0] == value) { - printf("OK Pass: [Write Value = 0x%02X], [Read Value = 0x%02X]\n", value, rx[0]); - } - else { - printf("NG: [Write Value = 0x%02X], [Read Value = 0x%02X]\n", value, rx[0]); - } - } -#endif - -} - -// Address에서 1바이트 Read (CRC 계산 없음) -uint8_t PMIC_I2C_Read(FT_HANDLE ftHandle, uint8_t slaveAddr, uint8_t regAddr) -{ - uint16 transferred = 0; - FT4222_STATUS st; - uint8_t rx[2] = { 0xFF, 0xFF }; // 초기값 에러 설정 - - // 1.Register Address를 먼저 Write (Read 시작 위치 지정) - uint8_t regOnly[1] = { regAddr }; - st = FT4222_I2CMaster_Write(ftHandle, slaveAddr, regOnly, 1, &transferred); - - if (st != FT4222_OK) { - printf("Read Address Write Fail\n"); - return 0xFF; - } - - // 2.Register Address에서 2바이트 Read (Value + CRC) - st = FT4222_I2CMaster_Read(ftHandle, slaveAddr, rx, 2, &transferred); - - if (st != FT4222_OK) { - printf("I2C Read Fail\n"); - return 0xFF; - } - else { - // 2진수 변환 로직 적용 - char binStr[10]; // "0000_0000" + null - toBinaryString(rx[0], binStr); - - printf("Read [Addr: 0x%02X] [Value Hex: 0x%02X -> Bin: %s] [CRC: 0x%02X]\n", regAddr, rx[0], binStr, rx[1]); - - return rx[0]; - } - -} - -// 8비트 데이터를 "0000_0000" 형식의 문자열로 변환 -void toBinaryString(uint8_t val, char* outBuf) -{ - for (int i = 0; i < 8; i++) { - // 상위 비트부터 검사하여 '1' 또는 '0' 채우기 - outBuf[i + (i >= 4 ? 1 : 0)] = (val & (1 << (7 - i))) ? '1' : '0'; - } - outBuf[4] = '_'; // 가독성을 위한 언더바 삽입 - outBuf[9] = '\0'; // 문자열 끝 지정 -} - -// Set Debug Mode On -bool Run_DebugMode_On(FT_HANDLE ftHandle) { - uint8_t readVal = 0; - int retryCount = 0; - const int maxRetries = 300; // 과도한 반복 방지 (50회면 충분합니다) - - printf("\n[PROCESS] Checking PMIC Communication..."); - - // 사전 통신 검사: 정상적인 리드 값이 올 때까지 무한 대기 (또는 특정 횟수) - while (1) { - readVal = PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x02); //0x102 - IO_MODECTRL Read시 디폴트 0x65 - - if (readVal != 0xFF) { - printf("\n[SUCCESS] Device detected! (Current Reg 0x02: 0x%02X)\n", readVal); - break; // 통신 성공 시 검사 루프 탈출 - } - - printf("."); // 대기 중임을 알리는 점 표시 - Sleep(1000); // 1초 간격으로 확인 - - // 만약 무한 대기가 싫다면 별도의 카운터를 써서 break - } - - // 실제 디버그 모드 진입 시퀀스 시작 - printf("[PROCESS] Attempting to Enter Debug Mode On\n"); - - do { - retryCount++; - - // Page01 선택 - PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x01); - PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x01); - - // 디버그 모드 진입 명령 (0x25) - PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x02, 0x25); //0x102 - IO_MODECTRL - - // 딜레이 및 확인 (Verification) - Sleep(50); - - // 직접 읽어서 확인 - readVal = PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x02); - - if (readVal == 0x25) {; - printf(" >>> Success! Debug Mode On[0x%02X] at cycle %d. <<<\n", readVal, retryCount); - return true; - } - - printf("[Retry %d]...\n", retryCount); - - } while (retryCount < maxRetries); - - printf("\n[ERRPR] Failed to enter Debug Mode On\n"); - - return false; -} - -// Set Debug Mode Off -bool Run_DebugMode_Off(FT_HANDLE ftHandle) { - uint8_t readVal = 0; - int retryCount = 0; - const int maxRetries = 100; // 과도한 반복 방지 (50회면 충분합니다) - - printf("\n[PROCESS] Checking PMIC Communication..."); - - // 사전 통신 검사: 정상적인 리드 값이 올 때까지 무한 대기 (또는 특정 횟수) - while (1) { - readVal = PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x02); //0x102 - IO_MODECTRL Read시 Debug On으로 0x25 - - if (readVal != 0xFF) { - printf("\n[SUCCESS] Device detected! (Current Reg 0x02: 0x%02X)\n", readVal); - break; // 통신 성공 시 검사 루프 탈출 - } - - printf("."); // 대기 중임을 알리는 점 표시 - Sleep(1000); // 1초 간격으로 확인 - - // 만약 무한 대기가 싫다면 별도의 카운터를 써서 break - } - - // 실제 디버그 모드 진입 시퀀스 시작 - printf("[PROCESS] Attempting to Enter Debug Mode Off...\n"); - - do { - retryCount++; - - // Page01 선택 - PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x01); - PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x01); - - // 디버그 모드 해제 명령 (0x65) - PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x02, 0x65); //0x102 - IO_MODECTRL - - // 딜레이 및 확인 (Verification) - Sleep(50); - - // 직접 읽어서 확인 - readVal = PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x02); - - if (readVal == 0x65) { - printf(" >>> Success! Debug Mode Off[0x%02X] at cycle %d. <<<\n", readVal, retryCount); - return true; - } - - printf("[Retry %d]...\n", retryCount); - - } while (retryCount < maxRetries); - - printf("\n[ERRPR] Failed Debug Mode Off\n"); - - return false; -} - -// Check All Fault Registers -void Run_CheckFaults(FT_HANDLE ftHandle) -{ - printf("\n[PROCESS] Scanning all Fault Registers...\n"); - - /////////////////////// - //Regulation Register// - /////////////////////// - - printf("[OTP Version]\n"); - //OTP Version - PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x00, 0x02); //0x00 - Page0x02 - PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x00, 0x02); //0x00 - Page0x02 - PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x22); //0x222 - OTP_VERSION_REGU - PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x23); //0x223 - OTP_VERSION_REGU - - //Fault register data: Regulation Register, Address 0x040 ~ 0x049 - printf("[Regulation FLT Register]\n"); - PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x00, 0x00); //0x00 - Page0x00 - PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x00, 0x00); //0x00 - Page0x00 - PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x40); //0x040 - FLT_RECORD_OTP - PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x41); //0x041 - FLT_RECORD_TEMP - PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x42); //0x042 - FLT_RECORD_BUCK1 - PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x43); //0x043 - FLT_RECORD_BUCK2 - PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x44); //0x044 - FLT_RECORD_BUCK3 - PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x45); //0x045 - FLT_RECORD_BUCK4 - PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x46); //0x046 - FLT_RECORD_BUCK5 - PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x47); //0x047 - FLT_RECORD_LDO - PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x48); //0x048 - FLT_RECORD_IF - PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x49); //0x049 - FLT_RECORD_LDO_DISC_DET - - /////////////////////// - //Protection Register// - /////////////////////// - - //Fault register data: Protection Register, Address 0x010 ~0x014, 0x019 ~0x021 - printf("[Protection FLT Register]\n"); - PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x00); //0x00 - Page0x00 - PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x00); //0x00 - Page0x00 - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x10); //0x010 - FUSA_STATUS_1 - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x11); //0x011 - FUSA_STATUS_2 - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x12); //0x012 - FUSA_STATUS_2A - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x13); //0x013 - FUSA_STATUS_3 - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x14); //0x014 - FUSA_STATUS_4 - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x19); //0x019 - FLT_RECORD_A - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x1A); //0x01A - FLT_RECORD_B - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x1B); //0x01B - FLT_RECORD_GND_AVIN - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x1C); //0x01C - FLT_RECORD_BG_Temp - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x1D); //0x01D - FLT_RECORD_IntLDOs - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x1E); //0x01E - FLT_RECORD_ExtLDOs - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x1F); //0x01F - FLT_RECORD_BUCKS_B - - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x20); //0x020 - FLT_RECORD_BUCKS_A - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x21); //0x021 - FLT_RECORD_ExtINPs_7_0 - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x28); //0x028 - OTP_RWADDR - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x2A); //0x02A - OTP_FLT_RECORD - - PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x01); //0x00 - Page0x01 - PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x01); //0x00 - Page0x01 - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x02); //0x102 - IO_MODECTRL - - /////////////////////// - // Debug Register // - /////////////////////// - - //Debug Regulation Chip Name etc - printf("[Regulation Chip ID]\n"); - PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x00, 0x00); //0x00 - Page0x00 - PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x00, 0x00); //0x00 - Page0x00 - PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x00); //0x000 - IO_PAGE_REGU - PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x01); //0x001 - IO_CHIPNAME_REGU - PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x02); //0x002 - IO_CHIPVERSION_REGU - PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x03); //0x003 - IO_DIEID3_REGU - PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x04); //0x004 - IO_DIEID2_REGU - PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x05); //0x005 - IO_DIEID1_REGU - PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x06); //0x006 - IO_DIEID0_REGU - PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x0A); //0x00A - OTP_VERSION_REGU - - //Debug Protection Chip Name etc - printf("[Protection Chip ID]\n"); - PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x00); //0x00 - Page0x00 - PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x00); //0x00 - Page0x00 - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x00); //0x000 - IO_PAGE_REGU - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x01); //0x001 - IO_CHIPNAME_REGU - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x02); //0x002 - IO_CHIPVERSION_REGU - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x03); //0x003 - IO_DIEID3_REGU - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x04); //0x004 - IO_DIEID2_REGU - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x05); //0x005 - IO_DIEID1_REGU - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x06); //0x006 - IO_DIEID0_REGU - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x0A); //0x00A - OTP_VERSION_REGU -} - -// Read Chip Information (OTP/Version) -void Run_ReadChipInfo(FT_HANDLE ftHandle) -{ - //Regulation Register - printf("[OTP Version]\n"); - //OTP Version - PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x00, 0x02); //0x00 - Page0x02 - PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x00, 0x02); //0x00 - Page0x02 - PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x22); //0x222 - OTP_VERSION_REGU - PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x23); //0x223 - OTP_VERSION_REGU - - //Debug Regulation Chip Name etc - printf("[Regulation Chip ID]\n"); - PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x00, 0x00); //0x00 - Page0x00 - PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x00, 0x00); //0x00 - Page0x00 - PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x00); //0x000 - IO_PAGE_REGU - PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x01); //0x001 - IO_CHIPNAME_REGU - PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x02); //0x002 - IO_CHIPVERSION_REGU - PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x03); //0x003 - IO_DIEID3_REGU - PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x04); //0x004 - IO_DIEID2_REGU - PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x05); //0x005 - IO_DIEID1_REGU - PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x06); //0x006 - IO_DIEID0_REGU - PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x0A); //0x00A - OTP_VERSION_REGU - - //Debug Protection Chip Name etc - printf("[Protection Chip ID]\n"); - PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x00); //0x00 - Page0x00 - PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x00); //0x00 - Page0x00 - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x00); //0x000 - IO_PAGE_REGU - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x01); //0x001 - IO_CHIPNAME_REGU - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x02); //0x002 - IO_CHIPVERSION_REGU - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x03); //0x003 - IO_DIEID3_REGU - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x04); //0x004 - IO_DIEID2_REGU - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x05); //0x005 - IO_DIEID1_REGU - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x06); //0x006 - IO_DIEID0_REGU - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x0A); //0x00A - OTP_VERSION_REGU -} - -// PMIC Irq Clear -void Irq_Clear(FT_HANDLE ftHandle) -{ - //Regulation Fault Register Clear : Regulation Register, Address 0x040 ~ 0x049 - printf("[Regulation FLT Register Clear]\n"); - PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x00, 0x00); //0x00 - Page0x00 - PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x00, 0x00); //0x00 - Page0x00 - PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x40, 0x00); //0x040 - FLT_RECORD_OTP - PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x41, 0x00); //0x041 - FLT_RECORD_TEMP - PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x42, 0x00); //0x042 - FLT_RECORD_BUCK1 - PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x43, 0x00); //0x043 - FLT_RECORD_BUCK2 - PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x44, 0x00); //0x044 - FLT_RECORD_BUCK3 - PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x45, 0x00); //0x045 - FLT_RECORD_BUCK4 - PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x46, 0x00); //0x046 - FLT_RECORD_BUCK5 - PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x47, 0x00); //0x047 - FLT_RECORD_LDO - PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x48, 0x00); //0x048 - FLT_RECORD_IF - PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x49, 0x00); //0x049 - FLT_RECORD_LDO_DISC_DET - - - //Fault register data: Protection Register, Address 0x010 ~0x014, 0x019 ~0x021 - printf("[Protection FLT Register Clear]\n"); - PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x00); //0x00 - Page0x00 - PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x00); //0x00 - Page0x00 - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x14); //0x014 - FUSA_STATUS_4 - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x19); //0x019 - FLT_RECORD_A - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x1A); //0x01A - FLT_RECORD_B - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x1B); //0x01B - FLT_RECORD_GND_AVIN - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x1C); //0x01C - FLT_RECORD_BG_Temp - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x1D); //0x01D - FLT_RECORD_IntLDOs - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x1E); //0x01E - FLT_RECORD_ExtLDOs - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x1F); //0x01F - FLT_RECORD_BUCKS_B - - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x20); //0x020 - FLT_RECORD_BUCKS_A - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x21); //0x021 - FLT_RECORD_ExtINPs_7_0 - PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x2A); //0x02A - OTP_FLT_RECORD -} - -// PMIC Set Reset -void Set_Reset(FT_HANDLE ftHandle) -{ - printf("PMIC Set Reset\n"); - PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x00); //0x00 - Page0x00 - PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x00); //0x00 - Page0x00 - PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x0C, 0x00); //0x0C - FUSA_CTRL_5 - PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x0C, 0x05); //0x0C - FUSA_CTRL_5 -} - -// PMIC Set Error -void Set_Error(FT_HANDLE ftHandle) -{ - printf("PMIC Set Error\n"); - PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x00); //0x00 - Page0x00 - PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x00); //0x00 - Page0x00 - PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x0C, 0x00); //0x0C - FUSA_CTRL_5 - PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x0C, 0x06); //0x0C - FUSA_CTRL_5 -} - -// PMIC Set FLT_MASK_B -void Set_FLT_MASK_B(FT_HANDLE ftHandle) -{ - printf("PMIC Set FLT_MASK_B\n"); - PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x01); //0x00 - Page0x01 - PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x01); //0x00 - Page0x01 - PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x2C, 0x3F); //0x2C - FLT_MASK_B -} - -// PMIC Set CRC On -void Set_CRC_On(FT_HANDLE ftHandle) -{ - printf("PMIC Set CRC ON\n"); - PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x01); //0x00 - Page0x01 - PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x01); //0x00 - Page0x01 - PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x05, 0x01); //0x05 - IO_FUNC_CFG -} - -// PMIC Set CRC Off -void Set_CRC_Off(FT_HANDLE ftHandle) -{ - printf("PMIC Set CRC OFF\n"); - PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x01); //0x00 - Page0x01 - PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x01); //0x00 - Page0x01 - PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x05, 0x00); //0x05 - IO_FUNC_CFG -} - -// Manual Command -void Handle_ManualCommand(FT_HANDLE ftHandle, char* line) -{ - char* context = NULL; - char* token = strtok_s(line, " ", &context); - if (!token) return; - - int command = parseCommand(token); // 1: WRITE, 2: READ - if (command == 1 || command == 2) { - printf("\n[MANUAL] Executing I2C %s...\n", (command == 1) ? "WRITE" : "READ"); - // 여기에 기존에 작성하셨던 w/r 파싱 및 실행 로직을 넣으시면 됩니다. - // 예: 토큰을 계속 잘라서 주소와 데이터를 추출 후 FT4222_I2CMaster_... 호출 - } - else { - printf("\n[ERROR] Invalid command or menu number. Please try again.\n"); - } -} \ No newline at end of file diff --git a/Src/0_Tool/PMIC_Tool/PMIC_Cmd_Tool/src/PMIC_Function.cpp b/Src/0_Tool/PMIC_Tool/PMIC_Cmd_Tool/src/PMIC_Function.cpp new file mode 100644 index 00000000..304a9587 --- /dev/null +++ b/Src/0_Tool/PMIC_Tool/PMIC_Cmd_Tool/src/PMIC_Function.cpp @@ -0,0 +1,550 @@ + +#include "PMIC_Common_Include.h" +#include "PMIC_Reg_Map.h" +#include "PMIC_Function.h" + +// 8Ʈ ͸ "0000_0000" ڿ ȯ +void toBinaryString(uint8_t val, char* outBuf) +{ + for (int i = 0; i < 8; i++) { + // Ʈ ˻Ͽ '1' Ǵ '0' ä + outBuf[i + (i >= 4 ? 1 : 0)] = (val & (1 << (7 - i))) ? '1' : '0'; + } + outBuf[4] = '_'; // + outBuf[9] = '\0'; // ڿ +} + +// CRC8 (׽ 0x07, ʱⰪ 0x00) +uint8_t calcCRC8(uint8_t addrWithRw, uint8_t* data, int len) +{ + uint8_t crc = 0x00; + + for (int j = -1; j < len; j++) { + uint8_t b = (j == -1) ? addrWithRw : data[j]; + crc ^= b; + for (int i = 0; i < 8; i++) { + if (crc & 0x80) + crc = (crc << 1) ^ 0x07; + else + crc <<= 1; + } + } + return crc; +} + + +// (00) и(000) (: 45.123) +void currentPreciseTime(char* buf, size_t len) +{ + SYSTEMTIME st; + GetLocalTime(&st); // ý ð(и ) + + sprintf_s(buf, len, "%02d.%03d", st.wSecond, st.wMilliseconds); +} + +// ð "HH:MM:SS" buf +void currentTime(char* buf, size_t len) +{ + if (buf == nullptr || len == 0) + return; + + time_t now = time(nullptr); + struct tm tm_buf; + +#ifdef _WIN32 + localtime_s(&tm_buf, &now); // Windows +#else + localtime_r(&now, &tm_buf); // Linux/Unix +#endif + + strftime(buf, len, "%H:%M:%S", &tm_buf); +} + +// α (Ŀ ) +void logPacket(const char* dir, uint8_t* data, int size, int hasCrc) +{ + if (dir == nullptr || data == nullptr || size <= 0) + return; + + char timeBuf[16]; // ss.fff ̹Ƿ 16Ʈ մϴ. + currentPreciseTime(timeBuf, sizeof(timeBuf)); // ð Լ ȣ + //currentTime(timeBuf, sizeof(timeBuf)); + + // 1. PMIC I2C WRITE ( RegAddr + Value + CRC ) + if (strcmp(dir, "PMIC I2C WRITE") == 0 && size >= 3) { + printf("[%s] [%s] [RegAddr: 0x%02X] [Value: 0x%02X] [CRC: 0x%02X]\n", + timeBuf, dir, data[0], data[1], data[2]); + return; + } + + // 2. PMIC I2C READ ( Value + CRC ) + if (strcmp(dir, "PMIC I2C READ") == 0 && size >= 2) { + printf("[%s] [%s] [Value: 0x%02X] [CRC: 0x%02X]\n", + timeBuf, dir, data[0], data[1]); + return; + } + + // 3. ⺻ ( ǿ ش ʴ Ÿ Ŷ) + printf("[%s] [%s] ", timeBuf, dir); + for (int i = 0; i < size; i++) { + if (hasCrc && i == size - 1) + printf("[CRC: 0x%02X] ", data[i]); + else if (i == 0 && size > 1) // ù Ʈ Value + printf("[Value: 0x%02X] ", data[i]); + else + printf("0x%02X ", data[i]); + } + + printf("\n"); +} + + +// ɾ Ǻ (I2C_WRITE/w, I2C_READ/r) +int parseCommand(const char* dir) +{ + if (strcmp(dir, "I2C_WRITE") == 0 || strcmp(dir, "W") == 0) + return 1; + if (strcmp(dir, "I2C_READ") == 0 || strcmp(dir, "R") == 0) + return 2; + return 0; +} + +// Address 1Ʈ Write with CRC, ׸ Address Readؼ Write +void PMIC_I2C_Write(FT_HANDLE ftHandle, uint8_t slaveAddr, uint8_t regAddr, uint8_t value) +{ + uint8_t bytes[3]; + int len = 0; + + // Write Ŷ: [RegAddr] [Value] [CRC] + bytes[len++] = regAddr; + bytes[len++] = value; + + uint8_t addrWithRw = (slaveAddr << 1) | 0x00; // Write ּ + uint8_t crc = calcCRC8(addrWithRw, bytes, len); + bytes[len++] = crc; + + uint16 transferred = 0; + FT4222_STATUS st = FT4222_I2CMaster_Write(ftHandle, slaveAddr, bytes, (uint16)len, &transferred); + + if (st != FT4222_OK) { + printf("I2C Write Fail\n"); + return; + } + else { + //logPacket("PMIC I2C WRITE", bytes, len, 1); + } + + // Read ؼ ϱ OFF +#if 0 + // Register Address ٽ Write (Read ġ ) + uint8_t regOnly[1] = { regAddr }; + st = FT4222_I2CMaster_Write(ftHandle, slaveAddr, regOnly, 1, &transferred); + + if (st != FT4222_OK) { + printf("Read Address Write Fail\n"); + return; + } + + // Register Address 2Ʈ Read + uint8_t rx[2] = { 0 }; + st = FT4222_I2CMaster_Read(ftHandle, slaveAddr, rx, 2, &transferred); + + if (st != FT4222_OK) { + printf("I2C Read Fail\n"); + return; + } + else { + logPacket("PMIC I2C READ ", rx, transferred, 0); + + // ù ° Ʈ Write + if (rx[0] == value) { + printf("OK Pass: [Write Value = 0x%02X], [Read Value = 0x%02X]\n", value, rx[0]); + } + else { + printf("NG: [Write Value = 0x%02X], [Read Value = 0x%02X]\n", value, rx[0]); + } + } +#endif + +} + +// Address 1Ʈ Read (CRC ) +uint8_t PMIC_I2C_Read(FT_HANDLE ftHandle, uint8_t slaveAddr, uint8_t regAddr) +{ + uint16 transferred = 0; + FT4222_STATUS st; + uint8_t rx[2] = { 0xFF, 0xFF }; // ʱⰪ + + // 1.Register Address Write (Read ġ ) + uint8_t regOnly[1] = { regAddr }; + st = FT4222_I2CMaster_Write(ftHandle, slaveAddr, regOnly, 1, &transferred); + + if (st != FT4222_OK) { + printf("Read Address Write Fail\n"); + return 0xFF; + } + + // 2.Register Address 2Ʈ Read (Value + CRC) + st = FT4222_I2CMaster_Read(ftHandle, slaveAddr, rx, 2, &transferred); + + if (st != FT4222_OK) { + printf("I2C Read Fail\n"); + return 0xFF; + } + else { + // 2 ȯ + char binStr[10]; // "0000_0000" + null + toBinaryString(rx[0], binStr); + + printf("Read [Addr: 0x%02X] [Value Hex: 0x%02X -> Bin: %s] [CRC: 0x%02X]\n", regAddr, rx[0], binStr, rx[1]); + + return rx[0]; + } + +} + +// Set Debug Mode On +bool Run_DebugMode_On(FT_HANDLE ftHandle) { + uint8_t readVal = 0; + int retryCount = 0; + const int maxRetries = 300; // ݺ (50ȸ մϴ) + + printf("\n[PROCESS] Checking PMIC Communication..."); + + // ˻: (Ǵ Ư Ƚ) + while (1) { + readVal = PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x02); //0x102 - IO_MODECTRL Read Ʈ 0x65 + + if (readVal != 0xFF) { + printf("\n[SUCCESS] Device detected! (Current Reg 0x02: 0x%02X)\n", readVal); + break; // ˻ Ż + } + + printf("."); // ˸ ǥ + Sleep(1000); // 1 Ȯ + + // Ⱑ ȴٸ ī͸ Ἥ break + } + + // + printf("[PROCESS] Attempting to Enter Debug Mode On\n"); + + do { + retryCount++; + + // Page01 + PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x01); + PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x01); + + // (0x25) + PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x02, 0x25); //0x102 - IO_MODECTRL + + // Ȯ (Verification) + Sleep(50); + + // о Ȯ + readVal = PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x02); + + if (readVal == 0x25) { + ; + printf(" >>> Success! Debug Mode On[0x%02X] at cycle %d. <<<\n", readVal, retryCount); + return true; + } + + printf("[Retry %d]...\n", retryCount); + + } while (retryCount < maxRetries); + + printf("\n[ERRPR] Failed to enter Debug Mode On\n"); + + return false; +} + + +// Set Debug Mode Off +bool Run_DebugMode_Off(FT_HANDLE ftHandle) { + uint8_t readVal = 0; + int retryCount = 0; + const int maxRetries = 100; // ݺ (50ȸ մϴ) + + printf("\n[PROCESS] Checking PMIC Communication..."); + + // ˻: (Ǵ Ư Ƚ) + while (1) { + readVal = PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x02); //0x102 - IO_MODECTRL Read Debug On 0x25 + + if (readVal != 0xFF) { + printf("\n[SUCCESS] Device detected! (Current Reg 0x02: 0x%02X)\n", readVal); + break; // ˻ Ż + } + + printf("."); // ˸ ǥ + Sleep(1000); // 1 Ȯ + + // Ⱑ ȴٸ ī͸ Ἥ break + } + + // + printf("[PROCESS] Attempting to Enter Debug Mode Off...\n"); + + do { + retryCount++; + + // Page01 + PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x01); + PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x01); + + // (0x65) + PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x02, 0x65); //0x102 - IO_MODECTRL + + // Ȯ (Verification) + Sleep(50); + + // о Ȯ + readVal = PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x02); + + if (readVal == 0x65) { + printf(" >>> Success! Debug Mode Off[0x%02X] at cycle %d. <<<\n", readVal, retryCount); + return true; + } + + printf("[Retry %d]...\n", retryCount); + + } while (retryCount < maxRetries); + + printf("\n[ERRPR] Failed Debug Mode Off\n"); + + return false; +} + +// Check All Fault Registers +void Run_CheckFaults(FT_HANDLE ftHandle) +{ + printf("\n[PROCESS] Scanning all Fault Registers...\n"); + + /////////////////////// + //Regulation Register// + /////////////////////// + + printf("[OTP Version]\n"); + //OTP Version + PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x00, 0x02); //0x00 - Page0x02 + PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x00, 0x02); //0x00 - Page0x02 + PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x22); //0x222 - OTP_VERSION_REGU + PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x23); //0x223 - OTP_VERSION_REGU + + //Fault register data: Regulation Register, Address 0x040 ~ 0x049 + printf("[Regulation FLT Register]\n"); + PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x00, 0x00); //0x00 - Page0x00 + PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x00, 0x00); //0x00 - Page0x00 + PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x40); //0x040 - FLT_RECORD_OTP + PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x41); //0x041 - FLT_RECORD_TEMP + PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x42); //0x042 - FLT_RECORD_BUCK1 + PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x43); //0x043 - FLT_RECORD_BUCK2 + PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x44); //0x044 - FLT_RECORD_BUCK3 + PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x45); //0x045 - FLT_RECORD_BUCK4 + PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x46); //0x046 - FLT_RECORD_BUCK5 + PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x47); //0x047 - FLT_RECORD_LDO + PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x48); //0x048 - FLT_RECORD_IF + PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x49); //0x049 - FLT_RECORD_LDO_DISC_DET + + /////////////////////// + //Protection Register// + /////////////////////// + + //Fault register data: Protection Register, Address 0x010 ~0x014, 0x019 ~0x021 + printf("[Protection FLT Register]\n"); + PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x00); //0x00 - Page0x00 + PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x00); //0x00 - Page0x00 + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x10); //0x010 - FUSA_STATUS_1 + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x11); //0x011 - FUSA_STATUS_2 + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x12); //0x012 - FUSA_STATUS_2A + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x13); //0x013 - FUSA_STATUS_3 + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x14); //0x014 - FUSA_STATUS_4 + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x19); //0x019 - FLT_RECORD_A + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x1A); //0x01A - FLT_RECORD_B + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x1B); //0x01B - FLT_RECORD_GND_AVIN + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x1C); //0x01C - FLT_RECORD_BG_Temp + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x1D); //0x01D - FLT_RECORD_IntLDOs + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x1E); //0x01E - FLT_RECORD_ExtLDOs + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x1F); //0x01F - FLT_RECORD_BUCKS_B + + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x20); //0x020 - FLT_RECORD_BUCKS_A + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x21); //0x021 - FLT_RECORD_ExtINPs_7_0 + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x28); //0x028 - OTP_RWADDR + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x2A); //0x02A - OTP_FLT_RECORD + + PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x01); //0x00 - Page0x01 + PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x01); //0x00 - Page0x01 + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x02); //0x102 - IO_MODECTRL + + /////////////////////// + // Debug Register // + /////////////////////// + + //Debug Regulation Chip Name etc + printf("[Regulation Chip ID]\n"); + PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x00, 0x00); //0x00 - Page0x00 + PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x00, 0x00); //0x00 - Page0x00 + PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x00); //0x000 - IO_PAGE_REGU + PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x01); //0x001 - IO_CHIPNAME_REGU + PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x02); //0x002 - IO_CHIPVERSION_REGU + PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x03); //0x003 - IO_DIEID3_REGU + PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x04); //0x004 - IO_DIEID2_REGU + PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x05); //0x005 - IO_DIEID1_REGU + PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x06); //0x006 - IO_DIEID0_REGU + PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x0A); //0x00A - OTP_VERSION_REGU + + //Debug Protection Chip Name etc + printf("[Protection Chip ID]\n"); + PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x00); //0x00 - Page0x00 + PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x00); //0x00 - Page0x00 + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x00); //0x000 - IO_PAGE_REGU + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x01); //0x001 - IO_CHIPNAME_REGU + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x02); //0x002 - IO_CHIPVERSION_REGU + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x03); //0x003 - IO_DIEID3_REGU + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x04); //0x004 - IO_DIEID2_REGU + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x05); //0x005 - IO_DIEID1_REGU + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x06); //0x006 - IO_DIEID0_REGU + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x0A); //0x00A - OTP_VERSION_REGU +} + +// Read Chip Information (OTP/Version) +void Run_ReadChipInfo(FT_HANDLE ftHandle) +{ + //Regulation Register + printf("[OTP Version]\n"); + //OTP Version + PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x00, 0x02); //0x00 - Page0x02 + PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x00, 0x02); //0x00 - Page0x02 + PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x22); //0x222 - OTP_VERSION_REGU + PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x23); //0x223 - OTP_VERSION_REGU + + //Debug Regulation Chip Name etc + printf("[Regulation Chip ID]\n"); + PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x00, 0x00); //0x00 - Page0x00 + PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x00, 0x00); //0x00 - Page0x00 + PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x00); //0x000 - IO_PAGE_REGU + PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x01); //0x001 - IO_CHIPNAME_REGU + PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x02); //0x002 - IO_CHIPVERSION_REGU + PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x03); //0x003 - IO_DIEID3_REGU + PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x04); //0x004 - IO_DIEID2_REGU + PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x05); //0x005 - IO_DIEID1_REGU + PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x06); //0x006 - IO_DIEID0_REGU + PMIC_I2C_Read(ftHandle, PMIC_ADDR_REGULATION, 0x0A); //0x00A - OTP_VERSION_REGU + + //Debug Protection Chip Name etc + printf("[Protection Chip ID]\n"); + PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x00); //0x00 - Page0x00 + PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x00); //0x00 - Page0x00 + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x00); //0x000 - IO_PAGE_REGU + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x01); //0x001 - IO_CHIPNAME_REGU + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x02); //0x002 - IO_CHIPVERSION_REGU + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x03); //0x003 - IO_DIEID3_REGU + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x04); //0x004 - IO_DIEID2_REGU + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x05); //0x005 - IO_DIEID1_REGU + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x06); //0x006 - IO_DIEID0_REGU + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x0A); //0x00A - OTP_VERSION_REGU +} + +// PMIC Irq Clear +void Irq_Clear(FT_HANDLE ftHandle) +{ + //Regulation Fault Register Clear : Regulation Register, Address 0x040 ~ 0x049 + printf("[Regulation FLT Register Clear]\n"); + PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x00, 0x00); //0x00 - Page0x00 + PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x00, 0x00); //0x00 - Page0x00 + PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x40, 0x00); //0x040 - FLT_RECORD_OTP + PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x41, 0x00); //0x041 - FLT_RECORD_TEMP + PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x42, 0x00); //0x042 - FLT_RECORD_BUCK1 + PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x43, 0x00); //0x043 - FLT_RECORD_BUCK2 + PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x44, 0x00); //0x044 - FLT_RECORD_BUCK3 + PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x45, 0x00); //0x045 - FLT_RECORD_BUCK4 + PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x46, 0x00); //0x046 - FLT_RECORD_BUCK5 + PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x47, 0x00); //0x047 - FLT_RECORD_LDO + PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x48, 0x00); //0x048 - FLT_RECORD_IF + PMIC_I2C_Write(ftHandle, PMIC_ADDR_REGULATION, 0x49, 0x00); //0x049 - FLT_RECORD_LDO_DISC_DET + + + //Fault register data: Protection Register, Address 0x010 ~0x014, 0x019 ~0x021 + printf("[Protection FLT Register Clear]\n"); + PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x00); //0x00 - Page0x00 + PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x00); //0x00 - Page0x00 + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x14); //0x014 - FUSA_STATUS_4 + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x19); //0x019 - FLT_RECORD_A + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x1A); //0x01A - FLT_RECORD_B + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x1B); //0x01B - FLT_RECORD_GND_AVIN + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x1C); //0x01C - FLT_RECORD_BG_Temp + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x1D); //0x01D - FLT_RECORD_IntLDOs + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x1E); //0x01E - FLT_RECORD_ExtLDOs + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x1F); //0x01F - FLT_RECORD_BUCKS_B + + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x20); //0x020 - FLT_RECORD_BUCKS_A + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x21); //0x021 - FLT_RECORD_ExtINPs_7_0 + PMIC_I2C_Read(ftHandle, PMIC_ADDR_PROTECTION, 0x2A); //0x02A - OTP_FLT_RECORD +} + +// PMIC Set Reset +void Set_Reset(FT_HANDLE ftHandle) +{ + printf("PMIC Set Reset\n"); + PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x00); //0x00 - Page0x00 + PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x00); //0x00 - Page0x00 + PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x0C, 0x00); //0x0C - FUSA_CTRL_5 + PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x0C, 0x05); //0x0C - FUSA_CTRL_5 +} + +// PMIC Set Error +void Set_Error(FT_HANDLE ftHandle) +{ + printf("PMIC Set Error\n"); + PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x00); //0x00 - Page0x00 + PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x00); //0x00 - Page0x00 + PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x0C, 0x00); //0x0C - FUSA_CTRL_5 + PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x0C, 0x06); //0x0C - FUSA_CTRL_5 +} + +// PMIC Set FLT_MASK_B +void Set_FLT_MASK_B(FT_HANDLE ftHandle) +{ + printf("PMIC Set FLT_MASK_B\n"); + PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x01); //0x00 - Page0x01 + PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x01); //0x00 - Page0x01 + PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x2C, 0x3F); //0x2C - FLT_MASK_B +} + +// PMIC Set CRC On +void Set_CRC_On(FT_HANDLE ftHandle) +{ + printf("PMIC Set CRC ON\n"); + PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x01); //0x00 - Page0x01 + PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x01); //0x00 - Page0x01 + PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x05, 0x01); //0x05 - IO_FUNC_CFG +} + +// PMIC Set CRC Off +void Set_CRC_Off(FT_HANDLE ftHandle) +{ + printf("PMIC Set CRC OFF\n"); + PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x01); //0x00 - Page0x01 + PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x00, 0x01); //0x00 - Page0x01 + PMIC_I2C_Write(ftHandle, PMIC_ADDR_PROTECTION, 0x05, 0x00); //0x05 - IO_FUNC_CFG +} + +// Manual Command +void Handle_ManualCommand(FT_HANDLE ftHandle, char* line) +{ + char* context = NULL; + char* token = strtok_s(line, " ", &context); + if (!token) return; + + int command = parseCommand(token); // 1: WRITE, 2: READ + if (command == 1 || command == 2) { + printf("\n[MANUAL] Executing I2C %s...\n", (command == 1) ? "WRITE" : "READ"); + // ⿡ ۼϼ̴ w/r Ľ ø ˴ϴ. + // : ū ߶ ּҿ ͸ FT4222_I2CMaster_... ȣ + } + else { + printf("\n[ERROR] Invalid command or menu number. Please try again.\n"); + } +}