/***************************************************************************** * * MSO Corporation * * File : asutil.c * Compiler : IAR C 5.10C Kickstart * Revision : $Revision: 1.0 $ * Date : $Date: 2010 / 07 / 16 * Updated by : $Author: Jongkwang Woo * * Support mail : spirit0305@naver.com * * Target platform : STM32F4 Cortex-M4 support * * AppNote : BPCB Application * * Description : Utility routines * ****************************************************************************/ #define _ASUTIL_ #include "includes.h" #include "asutil.h" #include "brtc.h" #include "date_calc.h" #include "console.h" #include "usart.h" #include "app_ver.h" #include "delay.h" u16 reverse16(u16 data) { return ((data >> 8) & 0x00FF) + ((data << 8) & 0xFF00); } u32 reverse32(u32 data) { return ((data >> 24) & 0x000000FF) + ((data >> 8) & 0x0000FF00) + ((data << 8) & 0x00FF0000) + ((data << 24) & 0xFF000000); } #ifndef CONSOLE_DEBUG void UART_DATA_PRINT(u16 port, u8 * buf, u16 len, u8 mode) { } void CAN_DATA_PRINT(u16 port, CanRxMsg* buf, u8 mode) { } void CAN_TX_DATA_PRINT(u16 port, CanTxMsg* buf) { } void UserMessage(char *str) { } #endif // #ifndef CONSOLE_DEBUG #ifdef CONSOLE_DEBUG u8 *dump_addr = 0; void ClearConsol(void) { printf("%1c[ ; H [32;40m", 0x1b); printf("%1c[2J%1c[0;0H%1c[2;37;40m", 0x1b, 0x1b, 0x1b); } void UserMessage(char *str) { char DisplayStr[81]; s16 i; printf("%1c[s", 0x1b); printf("%1c[24;01H%1c[34;47m", 0x1b, 0x1b); for (i = 0; i < 80; i++) { DisplayStr[i] = ' '; } i = 0; while ((str[i] != '\0') && (i < 80)) { DisplayStr[i] = str[i]; i ++; } DisplayStr[80] = 0x00; printf("%s", DisplayStr); printf("%1c[37;40m%1c[23;8H", 0x1b, 0x1b); printf("%1c[u", 0x1b); } void NormalOutXY(u16 x, u16 y, u8 *msg) { printf("%1c[s%1c[%02d;%02dH%1c[1m", 0x1b, 0x1b, y, x, 0x1b); printf("%s", msg); printf("%1c[23;8H%1c[u", 0x1b, 0x1b); } void GreenOutXY(u16 x,u16 y, u8 *msg) { printf("%1c[s%1c[%02d;%02dH%1c[1;32;40m", 0x1b, 0x1b, y, x, 0x1b); printf("%s", msg); printf("%1c[37;40m%1c[23;8H%1c[u", 0x1b, 0x1b, 0x1b); } void RedOutXY(u16 x,u16 y, u8 *msg) { printf("%1c[s%1c[%02d;%02dH%1c[1;31;40m", 0x1b, 0x1b, y, x, 0x1b); printf("%s", msg); printf("%1c[37;40m%1c[23;8H%1c[u", 0x1b, 0x1b, 0x1b); } void YellowOutXY(u16 x,u16 y, u8 *msg) { printf("%1c[s%1c[%02d;%02dH%1c[1;33;40m", 0x1b, 0x1b, y, x, 0x1b); printf("%s", msg); printf("%1c[37;40m%1c[23;8H%1c[u", 0x1b, 0x1b, 0x1b); } void ColorOutXY(u8 aColor, u16 x, u16 y, u8 *Text) { switch (aColor) { case DISPLAY_NORMAL: NormalOutXY(x, y, Text); break; case DISPLAY_RED: RedOutXY(x, y, Text); break; case DISPLAY_GREEN: GreenOutXY(x, y, Text); break; case DISPLAY_YELLOW: YellowOutXY(x, y, Text); break; } } void dump_mem(u32 addr) { u8 ASC[20]; s16 a,b; if (addr != 0) { dump_addr = (u8 *)(addr); } printf("\r\n"); for (a = 0; a < 8; a++) { printf("%08lX ", (unsigned long)(dump_addr)); for (b = 0; b < 16; b++) { printf("%02X ", dump_addr[0]); if (dump_addr[0] <' ') ASC[b] = '.'; else if (dump_addr[0] == 0xFF) ASC[b] = '.'; else { if ((b == 15)&&(dump_addr[0] > 128)) ASC[b] = '.'; else ASC[b] = dump_addr[0]; } dump_addr++; } printf(" "); ASC[16] = 0x00; printf("%s", ASC); printf("\r\n"); } } u32 TextToAddr(u8 *data) { u32 l; int a,b, c; a = 0; while ((!(data[a] < '0')) && (!(data[a] > '9')) || (!(data[a] < 'A')) && (!(data[a] > 'F')) || (!(data[a] < 'a')) && (!(data[a] > 'f'))) { a++; } l = 0; for (b = 0; b < a; b++) { if (data[b] > 'F') {c = data[b] - 'a' + 10; } else { if (data[b] > '9') { c = data[b] - 'A' + 10;} else { c = data[b] - '0';} } l = l * 16 + c; } return(l); } u8 WaitUserCMD(u8 *cmd) { u32 waittime; u8 ret; u8 one[2]; u16 i, len; for (i = 0; i < 20; i++) { if (cmd[i] == '\0') break; } len = i; waittime = Get_Local_Time() + 5000; ret = 0; while (waittime > Get_Local_Time()) { if (debug_recv_data(one)) { // if (UART1_GetChar(one)) for (i = 0; i < len; i++) { if (one[0] == cmd[i]) return (i + 1); } } IWDG_ReloadCounter(); delay_os_ms(1); } position = 0; return(ret); } void data_print(u8 *data, u16 len) { u8 ASC[20]; u16 i, j; for (i = 0; i < (len/16 + 1); i++) { printf("0x%04X ", (u32)(data + (i*16))); for (j = 0; j < 16; j++) { if ((i*16 + j) >= len) { printf(" "); ASC[j] = ' '; } else { printf("%02X ", data[(i*16)+j]); if (data[i*16 + j] <' ') ASC[j] = '.'; else { if ((j == 15)&&(data[i*16 + j] > 128)) ASC[j] = '.'; else ASC[j] = data[i*16 + j]; } } } ASC[16] = 0x00; printf(" %s\r\n", ASC); } } void UART_DATA_PRINT(u16 port, u8 * buf, u16 len, u8 mode) { if (screenmode != DIAG_MODE) return; if (len > 0) { switch (mode) { case RX_PRINT: printf("\r\nCOM%1d RX LEN:(%04d)", port, len); break; case TX_PRINT: printf("\r\nCOM%1d TX LEN:(%04d)", port, len); break; } printf(" [%04d/%02d/%02d %02d:%02d:%02d %03d]\r\n", DEVICE_TIME.year + UTC_YEAR, DEVICE_TIME.month, DEVICE_TIME.date, DEVICE_TIME.hour, DEVICE_TIME.min, DEVICE_TIME.sec, DEVICE_TIME.sub_sec ); data_print(buf, len); } } void CAN_DATA_PRINT(u16 port, CanRxMsg* buf, u8 mode) { if (screenmode != DIAG_MODE) return; switch (mode) { case RX_PRINT: printf("\r\nCAN%d RX: ID(0x%08X): DLC(%d): ", port, buf->ExtId, buf->DLC); break; case TX_PRINT: printf("\r\nCAN%d RX: ID(0x%08X): DLC(%d): ", port, buf->ExtId, buf->DLC); break; } printf(" [%04d/%02d/%02d %02d:%02d:%02d %03d]\r\n", DEVICE_TIME.year + UTC_YEAR, DEVICE_TIME.month, DEVICE_TIME.date, DEVICE_TIME.hour, DEVICE_TIME.min, DEVICE_TIME.sec, DEVICE_TIME.sub_sec ); data_print(buf->Data, buf->DLC); } void CAN_TX_DATA_PRINT(u16 port, CanTxMsg* buf) { if (screenmode != DIAG_MODE) return; printf("\r\nCAN%d RX: ID(0x%08X): DLC(%d): ", port, buf->ExtId, buf->DLC); printf(" [%04d/%02d/%02d %02d:%02d:%02d %03d]\r\n", DEVICE_TIME.year + UTC_YEAR, DEVICE_TIME.month, DEVICE_TIME.date, DEVICE_TIME.hour, DEVICE_TIME.min, DEVICE_TIME.sec, DEVICE_TIME.sub_sec ); data_print(buf->Data, buf->DLC); } void DebugMessage(u8 *msg) { if (screenmode == DIAG_MODE) { printf("%s", msg); } } u8 FIND_CHAR(u8 *in, u8 *out, s16 max, u8 fdata) { u8 i; if (max <= 0) return 0; for (i = 0; i < max; i++) { if (in[i] == fdata) break; // not found out[i] = in[i]; } return(i); } u8 FIND_DATA(u8 *in, u8 *out, u16 max, u8 fdata, u16 count) { u16 i, j, k, ret; i = 0; j = 0; k = 0; ret = 0; for (i = 0; i < max; i++) { if (in[i] == 0x00) break; if (in[i] == 0x03) break; if (in[i] == fdata) { j++; if (j == count) { ret = k; break; } k = 0; } else { out[k++] = in[i]; } } return ret; } void va_catA(char *buf, char const * format, ...) { va_list args; va_start(args, format); vsprintf(buf, format, args); /* buf contains the formatted string */ /* Send formatted string to display - hardware dependent */ va_end(args); /* Clean up. Do NOT omit */ } void FloatToStrA(float ins, u8 *text, u16 size, u16 point) { u8 s[10]; sprintf((char *)s, "%%%d.%df", size, point); // va_catA((char *)text, (char *)s, ins); sprintf((char *)text, (char *)s, ins); } void FloatToStr(float ins, u8 *text, u16 size, u16 point) { u32 a = 1; s32 b, x; u32 y, k, i; if (ins < 0) k = true; else k = false; if (point > 0) { for (i = 0; i < point; i++) { a *= 10; } b = (s32)(ins * a); if (b < 0) b *= -1; x = (s32)ins; y = (u32)(b % a); } else { x = (s32)ins; y = 0; } text[0] = 0x00; switch (size) { case 0: break; case 1: sprintf((char *)text, "%1d", x); break; case 2: sprintf((char *)text, "%2d", x); break; case 3: switch (point) { case 0: sprintf((char *)text, "%3d", x); break; case 1: sprintf((char *)text, "%1d.%01d", x, y); break; } break; case 4: switch (point) { case 0: sprintf((char *)text, "%4d", x); break; case 1: sprintf((char *)text, "%2d.%01d", x, y); break; case 2: sprintf((char *)text, "%1d.%02d", x, y); break; } break; case 5: switch (point) { case 0: sprintf((char *)text, "%5d", x); break; case 1: sprintf((char *)text, "%3d.%01d", x, y); break; case 2: sprintf((char *)text, "%2d.%02d", x, y); break; case 3: sprintf((char *)text, "%1d.%03d", x, y); break; } break; case 6: switch (point) { case 0: sprintf((char *)text, "%6d", x); break; case 1: sprintf((char *)text, "%4d.%01d", x, y); break; case 2: sprintf((char *)text, "%3d.%02d", x, y); break; case 3: sprintf((char *)text, "%2d.%03d", x, y); break; case 4: sprintf((char *)text, "%1d.%04d", x, y); break; } break; case 7: switch (point) { case 0: sprintf((char *)text, "%7d", x); break; case 1: sprintf((char *)text, "%5d.%01d", x, y); break; case 2: sprintf((char *)text, "%4d.%02d", x, y); break; case 3: sprintf((char *)text, "%3d.%03d", x, y); break; case 4: sprintf((char *)text, "%2d.%04d", x, y); break; case 5: sprintf((char *)text, "%1d.%05d", x, y); break; } break; case 8: switch (point) { case 0: sprintf((char *)text, "%7d", x); break; case 1: sprintf((char *)text, "%5d.%01d", x, y); break; case 2: sprintf((char *)text, "%4d.%02d", x, y); break; case 3: sprintf((char *)text, "%3d.%03d", x, y); break; case 4: sprintf((char *)text, "%2d.%04d", x, y); break; case 5: sprintf((char *)text, "%1d.%05d", x, y); break; case 6: sprintf((char *)text, "%1d.%06d", x, y); break; } break; } if ((x == 0)&&(k == true)) text[0] = '-'; } void FloatColorOutIntXY(u8 Color, u16 x,u16 y, float Value, u16 Length, u16 Point) { u8 temp[10]; FloatToStr(Value, temp, Length, Point); temp[Length] = 0x00; ColorOutXY(Color, x, y, temp); } /* Decimal point = Point */ void FloatNormalOutIntXY(u16 x,u16 y, float Value, u16 Length, u16 Point) { u8 temp[10]; FloatToStrA(Value, temp, Length, Point); temp[Length] = 0x00; GreenOutXY(x,y,temp); } void FloatRedOutIntXY(u16 x,u16 y, float Value, s16 Length, u16 Point) { u8 temp[10]; FloatToStr(Value, temp, Length, Point); temp[Length] = 0x00; RedOutXY(x, y, temp); } void TempIntToStr(s16 Value, u8 *Text, u16 Length) { sprintf("%5.1f", (char *)Text, (float)((float)Value/10)); } void RedOutIntXY(u16 x, u16 y, s16 Value, s16 Length) { u8 temp[10]; TempIntToStr(Value, temp,Length); RedOutXY(x,y,temp); } void NormalOutIntXY(u16 x, u16 y, s16 Value, s16 Length) { u8 temp[10]; TempIntToStr(Value, temp, Length); NormalOutXY(x,y,temp); } void GreenOutIntXY(u16 x, u16 y, s16 Value, s16 Length) { u8 temp[20]; sprintf((char *)temp, "%4d", Value); GreenOutXY(x,y,temp); } char digit2ascii(u8 t) { char k; if (t<10 ) k = '0' + (char)t; else if( t == 10) k = 'A'; else if( t == 11) k = 'B'; else if( t == 12) k = 'C'; else if( t == 13) k = 'D'; else if( t == 14) k = 'E'; else if( t == 15) k = 'F'; return(k); } s16 ascii2digit(u8 t) { s16 k; k = 0; switch (t) { case '0' : k = 0; break; case '1' : k = 1; break; case '2' : k = 2; break; case '3' : k = 3; break; case '4' : k = 4; break; case '5' : k = 5; break; case '6' : k = 6; break; case '7' : k = 7; break; case '8' : k = 8; break; case '9' : k = 9; break; case 'a' : case 'A' : k =10; break; case 'b' : case 'B' : k =11; break; case 'c' : case 'C' : k =12; break; case 'd' : case 'D' : k =13; break; case 'e' : case 'E' : k =14; break; case 'f' : case 'F' : k =15; break; } return(k); } void IntToStr(s16 ins, u8 *text, s16 size) { s16 i, one, two, a; a = 1; if (ins < 0) { one = -1* ins; a = -1; } else { one = ins; } for(i = (size - 1); i >= 0; i--) { two = one / 10; text[i] = one % 10 + '0'; one = two; } if (a < 0) { text[0] = '-'; } } void Int32ToStr(u32 ins, u8 *text, u16 size) { s16 i; u32 one, two; one = ins; for(i = (size - 1); i >= 0; i--) { two = one / 10; text[i] = one % 10 + '0'; one = two; } } s16 StrToInt(u8 *text, u16 size) { s16 a = 1, i, k = 0; for (i = (size -1); i >= 0; i--) { if (text[i] != '-') { k += (text[i] - '0') * a; a *= 10; } else { k = -1 * k; } } return(k); } u8 Str2ToHex(u8 *text, u16 size) { s16 a = 1, i, k = 0; for (i = (size -1); i >= 0; i--) { if ((text[i] >= '0')&&(text[i] <= '9')) { k += (text[i] - '0') * a; a *= 16; } else if ((text[i] >= 'A')&&(text[i] <= 'F')) { k += (text[i] - 'A' + 10) *a; a *= 16; } else if ((text[i] >= 'a')&&(text[i] <= 'f')) { k += (text[i] - 'a' + 10) *a; a *= 16; } } return(k); } u32 strtohex(char *string, int size) { int i, sh; u32 result = 0; char *ptr = string; for (i = 0; i < size; i++) { sh = (size - i - 1) * 4; result += ascii2digit(ptr[i]) << sh; } return result; } u32 StrToInt32(u8 *text, u16 size) { s16 i; u32 a = 1, k = 0; for (i = (size -1); i >= 0; i--) { // if ((text[i] >= '0')&&(text[i] < '9')) // { k += (text[i] - '0') * a; a *= 10; // } } return(k); } void Int2Hex(u8 c, u8 *temp) { s16 a,b; a = c / 16; b = c % 16; if (a > 9) {temp[0] = a + 'A' - 10;} else{temp[0] = a + '0';} if (b > 9) {temp[1] = b + 'A' - 10;} else{temp[1] = b + '0';} } void IntOneHex(u8 c, u8 *temp) { if (c > 9) {temp[0] = c + 'A' - 10;} else{temp[0] = c + '0';} } void LongToStr(u16 a, u16 b, u8 *temp) { u16 t; u16 j; for (j = 8 - b; j < 8; j++) { t = (a >> (28 - (4 * j))) & 0x0f; temp[j] = digit2ascii(t); } temp[8] = ' '; temp[9] = 0x00; } u8 str2bcd(u8 *a) { u8 i, j; j = 0; for (i = 0; i < 2; i++) { if ((a[i] <= '9') && (a[i] >= '0')) j = j + (a[i] - '0'); if ((a[i] <= 'F') && (a[i] >= 'A')) j = j + (a[i] - 'A') + 10; if ((a[i] <= 'f') && (a[i] >= 'a')) j = j + (a[i] - 'a') + 10; if (i == 0) j <<= 4; } return j; } void bcdstr2(u8 in, u8 *out) { u8 i, j; i = (in >> 4)& 0xF; j = (in)& 0xF; out[0] = i + '0'; out[1] = j + '0'; } void StrToBCD(u8 *in, u8 *out, u16 size) { u16 i; for (i = 0; i < size; i++) { out[i] = str2bcd(&in[i * 2]); } } u8 Make_BCC(u8 *data, u16 len) { u16 i; u8 bcc = 0; for (i = 0; i < (len - 2); i++) { bcc ^= data[1 + i]; } return bcc; } u8 MakeCheckSum(u8 *data, u8 size) { u8 i, sum; sum = 0; for (i = 4; i < (size - 2); i++) { sum += data[i]; } return sum; } u16 StrToF2P(u8 *text, u16 size) { u16 i, j; u8 temp[20]; u16 aParam[2]; u16 result; i = 0; j = FIND_CHAR((u8 *)&text[i], temp, size - i, '.'); i = i + j + 1; aParam[0] = StrToInt(temp, j); temp[j] = 0x00; j = FIND_CHAR((u8 *)&text[i], temp, size - i, '.'); i = i + j + 1; aParam[1] = StrToInt(temp, j); temp[j] = 0x00; switch (j) { case 0: result = aParam[0] * 100; break; case 1: result = ((aParam[0] * 10) + aParam[1]) * 10; break; case 2: result = (aParam[0] * 100) + aParam[1]; break; case 3: result = ((aParam[0] * 1000) + aParam[1]) / 10; break; } return result; } u8 SSetParam(u8 *text, u8 aDevice) { u16 size, i, j; u16 aParam[4]; u8 temp[10]; u8 ret; ret = 0; size = 0; while (text[size] != 0x00) size++; /* Measure total string length */ // if (size == 0) return 1; switch (aDevice) { case '1' : // OCV Alarm Parameter Setting case '2' : // OCV Shutdown Parameter Setting case '3' : // ODV Alarm Parameter Setting case '4' : // ODV Shutdown Parameter Setting case '5' : // Cell Balance Parameter Setting i = 0; if (size < 7 ) return(1); j = FIND_CHAR((u8 *)&text[i], temp, size - i, ' '); i = i + j + 1; aParam[0] = StrToF2P(temp, j); /* IP a */ temp[j] = 0x00; j = FIND_CHAR((u8 *)&text[i], temp, size - i, ' '); i = i + j + 1; aParam[1] = StrToF2P(temp, j); /* IP b */ temp[j] = 0x00; // ParamSave(); // ParamLoad(); break; case '6': // High Temp Parameter Setting case '7': // Low Temp Parameter Setting i = 0; if (size < 3 ) return(1); j = FIND_CHAR((u8 *)&text[i], temp, size - i, ' '); i = i + j + 1; aParam[0] = StrToInt(temp, j); /* IP a */ temp[j] = 0x00; j = FIND_CHAR((u8 *)&text[i], temp, size - i, ' '); i = i + j + 1; aParam[1] = StrToInt(temp, j); /* IP b */ temp[j] = 0x00; aParam[0] = aParam[1]; case 'A': // OCC Shutdown Parameter Setting case 'B': // ODC Shutdown Parameter Setting i = 0; if (size < 3 ) return(1); j = FIND_CHAR((u8 *)&text[i], temp, size - i, ' '); i = i + j + 1; aParam[0] = StrToInt(temp, j); /* IP a */ temp[j] = 0x00; j = FIND_CHAR((u8 *)&text[i], temp, size - i, ' '); i = i + j + 1; aParam[1] = StrToInt(temp, j); /* IP b */ temp[j] = 0x00; // ParamSave(); // ParamLoad(); break; case 'E': // ups volt offset case 'F': // batt volt offset i = 0; if (size < 2 ) return(1); j = FIND_CHAR((u8 *)&text[i], temp, size - i, ' '); i = i + j + 1; aParam[0] = StrToInt(temp, j); /* IP a */ temp[j] = 0x00; // ParamSave(); // ParamLoad(); break; default: ret = 1; break; } return(ret); /* Setting value OK */ } #endif // #ifdef CONSOLE_DEBUG /****************** End of Asutil.c *********************/