/** ****************************************************************************** * @file afe_comm.c * @author AMG Energy Solution Team * @version V1.0.0 * @date 21-Jul-2025 * @brief This file provides all the headers of afe communication functions. ****************************************************************************** * @attention * * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS. * *

© COPYRIGHT 2025 AMG

****************************************************************************** */ /** @addtogroup mBMS3 * @{ */ /* Includes ------------------------------------------------------------------*/ #include #include "afe_comm.h" #include "spi.h" #include "ADBMS181x.h" #include "ADBMS1818.h" #include "usart.h" #include "asutil.h" #include "malloc.h" #include "delay.h" #include "device_param.h" #include "brtc.h" #include "console.h" #include "io.h" /* Private typedef -----------------------------------------------------------*/ typedef struct { uint16_t cvolt[DEVICE_MAX_CELL]; } TPackBuf, *PPackBuf; /* Private define ------------------------------------------------------------*/ #define ENABLED 1 #define DISABLED 0 #define DATALOG_ENABLED 1 #define DATALOG_DISABLED 0 #define BATT_TASK_TIME 30 // 30ms TASK #define DEFAULT_HOST_BALANCING_VOLTAGE 3000 /********************************************************** Setup Variables The following variables can be modified to configure the software. ***********************************************************/ const uint8_t TOTAL_IC = 1;//! 50000) { return; } if (i == 0) { ic[cNo].cells.c_codes[i] += 0; } if (i == (DEVICE_MAX_CELL - 1)) { ic[cNo].cells.c_codes[i] += 0; } } for (int i = 0; i < DEVICE_MAX_CELL; i++) { PackBuf[ch].cvolt[i] = ic[cNo].cells.c_codes[i] / 10; // Cell n } if (PackBuffFlag == false) { PackBuffFlag = true; for (int i = 0; i < DEVICE_MAX_CELL; i++) { for (int j = 0; j < PACK_BUF_MAX; j++) { PackBuf[j].cvolt[i] = ic[cNo].cells.c_codes[i] / 10; // Cell n } } } uint32_t max, min; // Volt Avg for (int i = 0; i < DEVICE_MAX_CELL; i++) { tmp = 0; for (int j = 0; j < PACK_BUF_MAX; j++) { if (j == 0) { max = min = PackBuf[j].cvolt[i]; } else { if (max < PackBuf[j].cvolt[i]) { max = PackBuf[j].cvolt[i];} if (min > PackBuf[j].cvolt[i]) { min = PackBuf[j].cvolt[i];} } tmp += PackBuf[j].cvolt[i]; } if ((GetCB_Rest() == true) || (device_status.battery_status.bit.DCP == true)) { device_value.Cell.voltage[i] = (uint16_t)((tmp - max - min) / (PACK_BUF_MAX - 2)); } } SaveOneBuffTime(); if (PackBufCh == 0) { SaveAllBuffTime(); } PackBufCh++; PackBufCh %= PACK_BUF_MAX; } void MakeCellAvgData(void) { uint32_t sum; TMinMax min, max; sum = 0; memset(&min, 0x00, sizeof(TMinMax)); memset(&max, 0x00, sizeof(TMinMax)); for (int i = 0; i < DEVICE_MAX_CELL; i++) { if (i == 0) { max.value = device_value.Cell.voltage[i]; max.num = i; min.value = device_value.Cell.voltage[i]; min.num = i; } if (max.value < device_value.Cell.voltage[i]) { max.value = device_value.Cell.voltage[i]; max.num = i; } if (min.value > device_value.Cell.voltage[i]) { min.value = device_value.Cell.voltage[i]; min.num = i; } sum += device_value.Cell.voltage[i]; } device_value.BatVoltage = sum / 10; device_value.Cell.avg.Max.value = max.value; device_value.Cell.avg.Max.num = max.num; device_value.Cell.avg.Min.value = min.value; device_value.Cell.avg.Min.num = min.num; device_value.Cell.avg.diff = max.value - min.value; device_value.Cell.avg.avg = (uint16_t)(sum / DEVICE_MAX_CELL); } // Cell Balancing Flag void clear_cb_value(void) { CB_Tick = 0; CB_Rest = 1; CbRestAlarmTick = (1 * 1000 / 5); } void dec_cb_tick(uint16_t tick) { if (CB_Tick > tick) { CB_Tick -= tick; } else { CB_Tick = 0; } if (CbRestAlarmTick > tick) { CbRestAlarmTick -= tick; } else { CbRestAlarmTick = 0; } } uint8_t GetCB_Rest(void) { if (((CB_Rest == 1) || (CB_Rest == 3)) && (CbRestAlarmTick == 0)) { return 1; } else { return 0; } } void CheckAutoBalancingEnable(void) { PDEVICE_PARAM param = &device_param; // Check Cell balanicng Mode (Balancing active or not) if (CellBalancingFlag == true) { // Before cell balancing status is ON if (device_value.Cell.avg.Max.value < param->chg_ctrl.cell_bal_cfg.Cell_Balance_Threshold) { CellBalancingFlag = false; } else if (device_value.Cell.avg.diff < (param->chg_ctrl.cell_bal_cfg.Cell_Balance_Min - 5)) { if (device_status.warning.bit.cell_over_voltage == 0) { CellBalancingFlag = false; } } } else { // Before cell balancing status is OFF if (device_value.Cell.avg.Max.value > (param->chg_ctrl.cell_bal_cfg.Cell_Balance_Threshold + param->chg_ctrl.cell_bal_cfg.Cell_Balance_Window)) { if (device_value.Cell.avg.diff > param->chg_ctrl.cell_bal_cfg.Cell_Balance_Min) { CellBalancingFlag = true; } else if (device_status.warning.bit.cell_over_voltage) { CellBalancingFlag = true; } else { // Host balancing control prio if (HostBalancingVoltage > DEFAULT_HOST_BALANCING_VOLTAGE) { CellBalancingFlag = true; } } } } if (CellBalancingFlag == false) { if ((HostBalancingVoltage > DEFAULT_HOST_BALANCING_VOLTAGE) && (HostBalancingVoltageDiff > 0)) { CellBalancingFlag = true; } } } uint32_t CalcBalancingVolt(void) { uint32_t balancing_avg = 0; if (device_value.Cell.avg.diff > 100) { if ((device_value.Cell.avg.Max.value - device_value.Cell.avg.avg) > (device_value.Cell.avg.avg - device_value.Cell.avg.Min.value)) { balancing_avg = device_value.Cell.avg.avg + 20; } else { balancing_avg = device_value.Cell.avg.avg - 20; } } else if (device_value.Cell.avg.diff > 80) { if ((device_value.Cell.avg.Max.value - device_value.Cell.avg.avg) > (device_value.Cell.avg.avg - device_value.Cell.avg.Min.value)) { balancing_avg = device_value.Cell.avg.avg + 15; } else { balancing_avg = device_value.Cell.avg.avg - 15; } } else if (device_value.Cell.avg.diff > 60) { if ((device_value.Cell.avg.Max.value - device_value.Cell.avg.avg) > (device_value.Cell.avg.avg - device_value.Cell.avg.Min.value)) { balancing_avg = device_value.Cell.avg.avg + 10; } else { balancing_avg = device_value.Cell.avg.avg - 10; } } else if (device_value.Cell.avg.diff > 40) { if ((device_value.Cell.avg.Max.value - device_value.Cell.avg.avg) > (device_value.Cell.avg.avg - device_value.Cell.avg.Min.value)) { balancing_avg = device_value.Cell.avg.avg + 5; } else { balancing_avg = device_value.Cell.avg.avg - 5; } } else if (device_value.Cell.avg.diff > 30) { if ((device_value.Cell.avg.Max.value - device_value.Cell.avg.avg) > (device_value.Cell.avg.avg - device_value.Cell.avg.Min.value)) { balancing_avg = device_value.Cell.avg.avg + 2; } else { balancing_avg = device_value.Cell.avg.avg - 2; } } else if (device_value.Cell.avg.diff > 20) { if ((device_value.Cell.avg.Max.value - device_value.Cell.avg.avg) > (device_value.Cell.avg.avg - device_value.Cell.avg.Min.value)) { balancing_avg = device_value.Cell.avg.avg + 2; } else { balancing_avg = device_value.Cell.avg.avg - 2; } } else if (device_value.Cell.avg.diff > 10) { if ((device_value.Cell.avg.Max.value - device_value.Cell.avg.avg) > (device_value.Cell.avg.avg - device_value.Cell.avg.Min.value)) { balancing_avg = device_value.Cell.avg.avg + 1; } else { balancing_avg = device_value.Cell.avg.avg - 1; } } else { balancing_avg = device_value.Cell.avg.avg; } if ((HostBalancingVoltage > DEFAULT_HOST_BALANCING_VOLTAGE) && (device_value.Cell.avg.diff < HostBalancingVoltageDiff)) { balancing_avg = HostBalancingVoltage; } return balancing_avg; } #define REST_TIME_ADD 2000 uint8_t CheckCbRest(void) { uint8_t setBal = false; if (CellBalancingFlag == true) { if (CB_Tick == 0) { switch (CB_Rest) { case 0: // Work to Rest CB_Rest = 1; setBal = true; CbRestAlarmTick = (1 * 1000 / 2); CB_Tick = 1 * 1000 + REST_TIME_ADD; break; case 1: // Rest to Work CB_Rest = 2; setBal = true; if ((device_value.Cell.avg.diff < 10) && (device_value.Cell.avg.Min.value > 3400)) { CB_Tick = 1 * 1000 / 5; } else { CB_Tick = 1 * 1000 / 2; } break; case 2: // Work to Rest CB_Rest = 3; setBal = true; CbRestAlarmTick = (1 * 1000 / 2); CB_Tick = 1 * 1000 + REST_TIME_ADD; break; case 3: // Rest to Work CB_Rest = 0; setBal = true; if ((device_value.Cell.avg.diff < 10) && (device_value.Cell.avg.Min.value > 3400)) { CB_Tick = 1 * 1000 / 5; } else { CB_Tick = 1 * 1000 / 2; } break; default: // Rest to Work CB_Rest = 0; setBal = true; CbRestAlarmTick = (1 * 1000 / 2); CB_Tick = 1 * 1000 + REST_TIME_ADD; break; } } } else { if ((CB_Rest == 0) || (CB_Rest == 2)) { CB_Rest = 1; CbRestAlarmTick = (1 * 1000 / 2); CB_Tick = 1 * 1000 + REST_TIME_ADD; setBal = true; } } return setBal; } uint8_t CheckCbRest1(void) { uint8_t setBal = false; PDEVICE_PARAM param = &device_param; if (CellBalancingFlag == true) { if (CB_Tick == 0) { switch (CB_Rest) { case 0: // Work to Rest CB_Rest = 1; setBal = true; CbRestAlarmTick = (param->chg_ctrl.cell_bal_cfg.Cell_Balance_Interval * 1000 / 5); CB_Tick = param->chg_ctrl.cell_bal_cfg.Cell_Balance_Interval * 1000 + REST_TIME_ADD; break; case 1: // Rest to Work CB_Rest = 2; setBal = true; if ((device_value.Cell.avg.diff < 10) && (device_value.Cell.avg.Min.value > 3400)) { CB_Tick = param->chg_ctrl.cell_bal_cfg.Cell_Balance_Interval * 1000 / 5; } else { CB_Tick = param->chg_ctrl.cell_bal_cfg.Cell_Balance_Interval * 1000 / 2; } break; case 2: // Work to Rest CB_Rest = 3; setBal = true; CbRestAlarmTick = (param->chg_ctrl.cell_bal_cfg.Cell_Balance_Interval * 1000 / 5); CB_Tick = param->chg_ctrl.cell_bal_cfg.Cell_Balance_Interval * 1000 + REST_TIME_ADD; break; case 3: // Rest to Work CB_Rest = 0; setBal = true; if ((device_value.Cell.avg.diff < 10) && (device_value.Cell.avg.Min.value > 3400)) { CB_Tick = param->chg_ctrl.cell_bal_cfg.Cell_Balance_Interval * 1000 / 5; } else { CB_Tick = param->chg_ctrl.cell_bal_cfg.Cell_Balance_Interval * 1000 / 2; } break; default: // Rest to Work CB_Rest = 0; setBal = true; CbRestAlarmTick = (param->chg_ctrl.cell_bal_cfg.Cell_Balance_Interval * 1000 / 5); CB_Tick = param->chg_ctrl.cell_bal_cfg.Cell_Balance_Interval * 1000 + REST_TIME_ADD; break; } } } else { if ((CB_Rest == 0) || (CB_Rest == 2)) { CB_Rest = 1; CbRestAlarmTick = (param->chg_ctrl.cell_bal_cfg.Cell_Balance_Interval * 1000 / 5); CB_Tick = param->chg_ctrl.cell_bal_cfg.Cell_Balance_Interval * 1000; setBal = true; } } return setBal; } void AutoCellBalancing(uint32_t rBal) { uint32_t bal = rBal; uint8_t setBal = false; setBal = CheckCbRest(); // Check Cell balanicng Mode (Balancing active or not) CheckAutoBalancingEnable(); device_status.battery_status.bit.CB = CellBalancingFlag; if (CellBalancingFlag == true) { if (setBal == true) { setBal = false; if ((CB_Rest == 0) || (CB_Rest == 2)) { Balance_Avg = CalcBalancingVolt(); bal = 0; for (int i = 0; i < DEVICE_MAX_CELL; i++) { if ((device_value.Cell.voltage[i] > Balance_Avg) || ((device_status.cov_warning_cell.uValue >> i) == 1)) { bal = bal | (1 << i); } } // Write Balancing cBal = bal; WriteBalData(cBal); } else { // CB Rest time bal = 0; cBal = bal; WriteBalData(cBal); } } } else { if (setBal) { WriteBalData(0); setBal = false; } } } void WriteBalData(uint32_t wBal) { // dccBits_a = (wBal >> 0) & 0x0FFF; // Cell #1 - #12 // dccBits_b = (wBal >> 12) & 0x0007; // Cell #13 - #15 for (int i = 0; i < 12; i++) { if ((wBal >> (i + 0)) & 0x0001) dccBitsA[i] = 1; else dccBitsA[i] = 0; } for (int i = 0; i < 3; i++) { if ((wBal >> (i + 12)) & 0x0001) dccBitsB[i + 1] = 1; else dccBitsB[i + 1] = 0; } ADBMS1818_set_cfgr (0, bms_ic, REFON, ADCOPT, gpioBitsA, dccBitsA , dctoBits, UV, OV); ADBMS1818_set_cfgrb(0, bms_ic, FDRF , DTMEN , psBits , gpioBitsB, dccBitsB); ADBMS1818_wrcfg (TOTAL_IC, bms_ic); ADBMS1818_wrcfgb(TOTAL_IC, bms_ic); } void SetManualBalancing(uint8_t mode, uint8_t flag, uint32_t cNo) { ManualBalFlag = mode; if (ManualBalFlag == true) { if (cNo == 0) { ManualBalValue = 0; } else { if (flag) { ManualBalValue |= (1 << (cNo - 1)); } else { ManualBalValue &= ~(1 << (cNo - 1)); } } } else { ManualBalValue = 0; } } void ManualCellBalancing(uint32_t rBal) { uint32_t bal = 0; for (int i = 0; i < DEVICE_MAX_CELL; i++) { if ((rBal >> i) & 0x00000001) { bal |= (uint32_t)(1 << i); } } if (ManualBalFlag == true) { if (bakManualBalValue != ManualBalValue) { WriteBalData(ManualBalValue); bakManualBalValue = ManualBalValue; } } else { if (bal != 0) { WriteBalData(0); } } } /* Public Status Function ************************************************************/ uint16_t GetBalanceAvg(void) { return Balance_Avg; } uint16_t GetBalanceFlag(void) { return device_status.battery_status.bit.CB; } /* Display Function ******************************************************************/ #ifdef CONSOLE_DEBUG void AfeDisplayStatus(uint8_t p); void ODisplayBalancingValue(uint8_t p) { float aParam; if (p || (disBalance_Avg != Balance_Avg)) { aParam = (float)Balance_Avg / 1000; FloatNormalOutIntXY(71, 10 , aParam, 5, 3); disBalance_Avg = Balance_Avg; } if (p || (disCellBalancingFlag != GetBalanceFlag())) { if (GetBalanceFlag() == true) YellowOutXY(68, 11, (uint8_t *)"O"); else GreenOutXY(68, 11, (uint8_t *)"X"); disCellBalancingFlag = GetBalanceFlag(); } if (p || ((disCB_Tick / 1000) != (CB_Tick / 1000))) { aParam = (float)(disCB_Tick / 1000); FloatNormalOutIntXY(70, 11,aParam, 6, 0); disCB_Tick = CB_Tick; } // // AfeDisplayStatus(p); } const char AfeMODE_STR[][84] = { // 1 2 3 4 5 6 7 8 // 123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890 "\r\n+--[Battery : ]---+---+---+---+---+---+---+---+---+---+--------------------+", // 2 "\r\n| | B |OCA|TCA|TDA|AFE|RSV|ZVC|F-C|F-D| Warning ( )HEX|", // 3 "\r\n| HeartB ( ) | S |INI|MD |FC |FD |RXM|ZVC|F-C|F-D| Protection( )HEX|", // 4 "\r\n+---------------------+---+---+---+---+---+---+---+---+---+-[CELL AVG ]--------+", // 5 "\r\n| B-Volt ( . )V | W |RSV|RSV|RSV|L-C|LTD|LTC|HTD|HTC| C-MAX ( . )V |", // 6 "\r\n| Current ( . )A | N |RSV|RSV|OCD|OCC|CUV|SUV|COV|SOV| C-AVG ( . )V |", // 7 "\r\n| SOC ( . )% +---+---+---+---+---+---+---+---+---+ C-MIN ( . )V |", // 8 "\r\n| | P |AFE|RSV|SC |RSV|LTD|LTC|HTD|HTC| C-DIFF ( . )V |", // 9 "\r\n+---------------------+ T |RSV|RSV|OCD|OCC|CUV|SUV|COV|SOV| CB AVG ( . )V |", // 0 "\r\n| F-Capa ( . )AH +---+---+---+---+---+---+---+---+---+ [ ] |", // 1 "\r\n+---------------------+ AFE STATUS ( ) UV TRIP ( ) +-[TEMP AVG ]--------+", // 2 "\r\n| Operate( )| CTRL1 ( ) OV TRIP ( ) | T-MAX ( . )C |", // 3 "\r\n| Status ( )| CTRL2 ( ) | T-AVG ( . )C |", // 4 "\r\n| | PROTECT( - - ) | T-MIN ( . )C |", // 5 "\r\n+--[Cell Volt]--------+ M( )| T-DIFF ( . )C |", // 6 "\r\n|( . )( . )( . )+---------+---------+---------+-----+---+----------------+", // 7 "\r\n|( . )( . )( . )|T1( . )|T3( . )|F1( . )| +---+", // 8 "\r\n|( . )( . )( . )| | | | |DATE: / / |", // 9 "\r\n|( . )( . )( . )|T2( . )|T4( . )|F2( . )| |TIME: : : |", // 0 "\r\n|( . )( . )( . )| | | | |L-REBOOT ( )|", // 1 "\r\n+---------------------+---------+---------+---------+---------+----------------+", // 2 "\r\n s : SETTING d : DIAGNOSTIC " // 3 }; void AfemodeScreen(void) { for (int i = 0; i < 22; i++) { printf("%s", AfeMODE_STR[i]); delay_os_ms(2); } } int dis_numberOfCells; uint8_t dis_AfeStatus; uint8_t dis_AfeCtrl1; uint8_t dis_AfeCtrl2; uint8_t dis_AfeUvTrip; uint8_t dis_AfeOvTrip; uint8_t dis_AfeProtect[3]; //int dis_cellVoltages[MAX_NUMBER_OF_CELLS]; // mV //uint32_t dis_batVoltage; // mV //int dis_temperatures[MAX_NUMBER_OF_THERMISTORS]; // //uint8_t dis_balStatus[3]; //int dis_adcGain = 0; // uV/LSB //int dis_adcOffset = 0; // mV //extern int adcGain; // uV/LSB //extern int adcOffset; // mV //void AfeDisplayStatus(uint8_t p) //{ // uint8_t text[20]; // uint32_t sts = 0; // // sts = getAfeStatus(); // if (p || (dis_AfeStatus != sts)) // { // sprintf((char *)text, "%02X", sts); // GreenOutXY(35, 12, text); // dis_AfeStatus = sts; // } // sts = getAfeCtrl1(); // if (p || (dis_AfeCtrl1 != sts)) // { // sprintf((char *)text, "%02X", sts); // GreenOutXY(35, 13, text); // dis_AfeCtrl1 = sts; // } // sts = getAfeCtrl2(); // if (p || (dis_AfeCtrl2 != sts)) // { // sprintf((char *)text, "%02X", sts); // GreenOutXY(35, 14, text); // dis_AfeCtrl2 = sts; // } // // for (int i = 0; i < 3; i++) // { // sts = getAfeProtect(i); // if (p || (dis_AfeProtect[i] != sts)) // { // sprintf((char *)text, "%02X", sts); // GreenOutXY(29 + (i * 3), 15, text); // dis_AfeProtect[i] = sts; // } // } // // sts = getAfeUvTrip(); // if (p || (dis_AfeUvTrip != sts)) // { // sprintf((char *)text, "%02X", sts); // GreenOutXY(55, 12, text); // dis_AfeUvTrip = sts; // } // sts = getAfeOvTrip(); // if (p || (dis_AfeOvTrip != sts)) // { // sprintf((char *)text, "%02X", sts); // GreenOutXY(55, 13, text); // dis_AfeOvTrip = sts; // } // // sts = getBatteryVoltage(); // if (p || (dis_batVoltage != sts)) // { // sprintf((char *)text, "%6.3f", (float)sts / 1000); // GreenOutXY(51, 14, text); // dis_batVoltage = sts; // } // // for (int i = 0; i < 3; i++) // { // if (p || (dis_device_value.SectVoltage[i] != device_value.SectVoltage[i])) // { // sprintf((char *)text, "%7.3f", (float)device_value.SectVoltage[i] / 1000); // GreenOutXY(38 + (i * 7), 15, text); // dis_device_value.SectVoltage[i] = device_value.SectVoltage[i]; // } // } // // if (p || (dis_adcGain != adcGain)) // { // sprintf((char *)text, "%04X", adcGain); // GreenOutXY(32, 16, text); // dis_adcGain = adcGain; // } // if (p || (dis_adcOffset != adcOffset)) // { // sprintf((char *)text, "%04X", adcOffset); // GreenOutXY(40, 16, text); // dis_adcOffset = adcOffset; // } //} uint8_t AfeSetBal(uint8_t *text, uint8_t aDevice) { uint16_t size, i, j; int32_t aParam[4]; uint8_t temp[10]; uint8_t ret; ret = 0; size = 0; while (text[size] != 0x00) size++; /* Measure total string length */ switch (aDevice) { case '0' : // Cell Balance Parameter Setting i = 0; if (size < 1 ) return(1); j = FIND_CHAR((uint8_t *)&text[i], temp, size - i, ' '); i = i + j + 1; temp[j] = 0x00; aParam[0] = StrToInt(temp, j); // SetManualBalancing(true, aParam[0]); break; case '1': // Cellbal off // SetManualBalancing(false, text[2] - 0x30); break; default: ret = 1; break; } return(ret); /* Setting value OK */ } /* Command processing in SETTING STATE */ int8_t Process_DataAfeModeSet(uint8_t *text, uint16_t size) { uint16_t i, ret; /* Invalid command if space is in first position */ if (size > 1) {if (text[1] != ' ') return(0);} text[size] = 0x00; ret = 1; switch (text[0]) { case 'o': /* Switch to operating mode */ screenmode = OP_MODE; ViewScreen(); break; case 's': /* Switch to setting status */ screenmode = SET_MODE; ViewScreen(); break; case 'd': /* Switch to diagnostic mode */ screenmode = DIAG_MODE; ViewScreen(); break; case '0': // OCV Alarm Parameter Setting case '1': // OCV Alarm Parameter Setting i = AfeSetBal(&text[2], text[0]); if (i == 0) UserMessage("COMMAND COMPLETE"); else if (i == 1) UserMessage("COMMAND FORMAT ERROR"); /* setting format error */ else UserMessage("COMMAND LIMIT ERROR"); /* setting limit error */ break; default : ret = 0; break; } return(ret); } #endif // #ifdef CONSOLE_DEBUG /*******************(C)COPYRIGHT 2022 AMG ********************END OF FILE******/