#include #include #include #include #include "bsp.h" #include "utils.h" /////////////////////////////////////////////////////////////////////////////// #define SencondsPerMinute 60 #define SencondsPerHour 3600 #define SencondsPerDay 86400 #define NormalDayInYear 365 #define YearCentry 2000 #define YearUtcStart 1970 #define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400) #define LEAP_YEAR(year) ((!((year) % 4) && ((year) % 100)) || !((year) % 400)) static const unsigned char rtc_days_in_month[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; static const unsigned short rtc_ydays[2][13] = { /* Normal years */ { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, /* Leap years */ { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } }; //CRC High bytes table const unsigned char auchCRCHi[]={ 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0, 0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41, 0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0, 0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40, 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x00,0xC1, 0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41, 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x00,0xC1, 0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41, 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0, 0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40, 0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1, 0x81,0x40,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40, 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0, 0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40, 0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0, 0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40, 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0, 0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41, 0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0, 0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41, 0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x01,0xC0, 0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40, 0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1, 0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41, 0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0, 0x80,0x41,0x00,0xC1,0x81,0x40 }; //CRC Low bytes table const unsigned char auchCRCLo[]={ 0x00,0xC0,0xC1,0x01,0xC3,0x03,0x02,0xC2,0xC6,0x06, 0x07,0xC7,0x05,0xC5,0xC4,0x04,0xCC,0x0C,0x0D,0xCD, 0x0F,0xCF,0xCE,0x0E,0x0A,0xCA,0xCB,0x0B,0xC9,0x09, 0x08,0xC8,0xD8,0x18,0x19,0xD9,0x1B,0xDB,0xDA,0x1A, 0x1E,0xDE,0xDF,0x1F,0xDD,0x1D,0x1C,0xDC,0x14,0xD4, 0xD5,0x15,0xD7,0x17,0x16,0xD6,0xD2,0x12,0x13,0xD3, 0x11,0xD1,0xD0,0x10,0xF0,0x30,0x31,0xF1,0x33,0xF3, 0xF2,0x32,0x36,0xF6,0xF7,0x37,0xF5,0x35,0x34,0xF4, 0x3C,0xFC,0xFD,0x3D,0xFF,0x3F,0x3E,0xFE,0xFA,0x3A, 0x3B,0xFB,0x39,0xF9,0xF8,0x38,0x28,0xE8,0xE9,0x29, 0xEB,0x2B,0x2A,0xEA,0xEE,0x2E,0x2F,0xEF,0x2D,0xED, 0xEC,0x2C,0xE4,0x24,0x25,0xE5,0x27,0xE7,0xE6,0x26, 0x22,0xE2,0xE3,0x23,0xE1,0x21,0x20,0xE0,0xA0,0x60, 0x61,0xA1,0x63,0xA3,0xA2,0x62,0x66,0xA6,0xA7,0x67, 0xA5,0x65,0x64,0xA4,0x6C,0xAC,0xAD,0x6D,0xAF,0x6F, 0x6E,0xAE,0xAA,0x6A,0x6B,0xAB,0x69,0xA9,0xA8,0x68, 0x78,0xB8,0xB9,0x79,0xBB,0x7B,0x7A,0xBA,0xBE,0x7E, 0x7F,0xBF,0x7D,0xBD,0xBC,0x7C,0xB4,0x74,0x75,0xB5, 0x77,0xB7,0xB6,0x76,0x72,0xB2,0xB3,0x73,0xB1,0x71, 0x70,0xB0,0x50,0x90,0x91,0x51,0x93,0x53,0x52,0x92, 0x96,0x56,0x57,0x97,0x55,0x95,0x94,0x54,0x9C,0x5C, 0x5D,0x9D,0x5F,0x9F,0x9E,0x5E,0x5A,0x9A,0x9B,0x5B, 0x99,0x59,0x58,0x98,0x88,0x48,0x49,0x89,0x4B,0x8B, 0x8A,0x4A,0x4E,0x8E,0x8F,0x4F,0x8D,0x4D,0x4C,0x8C, 0x44,0x84,0x85,0x45,0x87,0x47,0x46,0x86,0x82,0x42, 0x43,0x83,0x41,0x81,0x80,0x40 }; /////////////////////////////////////////////////////////////////////////////// /* int tm_sec:0~59; int tm_min:0~59; int tm_hour:0~59; int tm_mday:1~31; int tm_mon:0~11; int tm_year:0~255; int tm_wday:0~6; int tm_yday:0~365; */ stRtcTime rtcTime = {0}; /*The seconds from 2000-01-01 00:00:00*/ volatile stTimeSetValue g_stTimeValue = {0}; //static unsigned char fac_us=0;//us //static unsigned short fac_ms=0;//ms #define KEYSCAN_PEROID 53 #define TCPFLUSH_PEROID 1000 #define RECORD_PEROID 500 #define SECOND_PEROID 1000 #define HALF_MINUTE_PEROID 30000 volatile stTickTimer keyScanTimer = { .limit = KEYSCAN_PEROID, .enabled = 1, }; volatile stTickTimer rakTimer = { .limit = 100, .enabled = 1, }; volatile stTickTimer senderTimer={ //.limit = 50, .limit = 30, .enabled = 1, }; volatile stTickTimer tcpFlushTimer={ .limit = TCPFLUSH_PEROID, .enabled = 1, }; volatile stTickTimer recordTimer = { .limit = RECORD_PEROID, .enabled = 1, }; volatile stTickTimer secondTimer = { .limit = SECOND_PEROID, .enabled = 1, }; volatile stTickTimer halfMntTimer = { .limit = HALF_MINUTE_PEROID, .enabled = 1, }; /////////////////////////////////////////////////////////////////////////////// void RefreshTimer(void) { if(keyScanTimer.enabled) { if(keyScanTimer.count++>keyScanTimer.limit) { keyScanTimer.flag=1; } } if(rakTimer.enabled) { if(++rakTimer.count >= rakTimer.limit) { rakTimer.flag=1; } } if(senderTimer.enabled) { if(++senderTimer.count >= senderTimer.limit) { senderTimer.flag=1; } } if(recordTimer.enabled) { if(++recordTimer.count >= recordTimer.limit) { recordTimer.flag = 1; } } if (secondTimer.enabled) { if(++secondTimer.count >= secondTimer.limit) { secondTimer.flag = 1; } } if (halfMntTimer.enabled) { if(++halfMntTimer.count >= halfMntTimer.limit) { halfMntTimer.flag = 1; } } } void StartTimer(pTickTimer timer, uint32_t period) { timer->enabled=1; timer->limit = period; } void StopTimer(pTickTimer timer) { timer->enabled=0; ClearTimer(timer); } void ClearTimer(pTickTimer timer ) { timer->count=0; timer->flag=0; } /////////////////////////////////////////////////////////////////////////////// #ifdef __GNUC__ #pragma GCC optimize ("O0") #elif defined(__ICCARM__) #pragma optimize=none #endif void Delay_s( unsigned int time_s ) { for(;time_s>0;time_s--) { Delay_ms(1000); } } #ifdef __GNUC__ #pragma GCC optimize ("O0") #elif defined(__ICCARM__) #pragma optimize=none #endif void Delay_ms( unsigned int time_ms ) { unsigned int temp=0; unsigned int start = HAL_GetTick(); do { temp = HAL_GetTick(); } while(time_ms > temp - start);//wait here } #ifdef __GNUC__ #pragma GCC optimize ("O0") #elif defined(__ICCARM__) #pragma optimize=none #endif void Delay_us( unsigned int time_us ) { unsigned int temp=0; do { temp = 160; while(temp-->0) { ; } //temp++; } while(time_us-->0); } /* #define _clock(x) clock(x) unsigned int __weak sleep(unsigned int seconds) { clock_t t0 = _clock(); clock_t dt = seconds * CLOCKS_PER_SEC; while (_clock() - t0 < dt); return 0; } int __weak usleep(useconds_t useconds) { clock_t t0 = _clock(); clock_t dt = useconds / (1000000/CLOCKS_PER_SEC); clock_t tc = _clock(); while (tc - t0 < dt) { tc =_clock(); } return 0; }*/ /////////////////////////////////////////////////////////////////////////////// unsigned short ATOI(char* str,unsigned char base) { unsigned int num = 0; while (*str !=0) { num = num * base + C2D(*str++); } return num; } unsigned int ATOI32(char* str,unsigned char base) { unsigned int num = 0; while (*str !=0) { num = num * base + C2D(*str++); } return num; } void itoa(unsigned int n, char* str, unsigned char len) { unsigned char i=len-1; memset(str,0x20,len); do{ str[i--]=n%10+'0'; }while((n/=10)>0); return; } int ValidATOI(char* str, int base,int* ret) { int c; char* tstr = str; if(str == 0 || *str == '\0') return 0; while(*tstr != '\0') { c = C2D(*tstr); if( c >= 0 && c < base) tstr++; else return 0; } *ret = ATOI(str,base); return 1; } void replacetochar(char * str, char oldchar,char newchar ) { int x; for (x = 0; str[x]; x++) if (str[x] == oldchar) str[x] = newchar; } char C2D(unsigned char c ) { if (c >= '0' && c <= '9') return c - '0'; if (c >= 'a' && c <= 'f') return 10 + c -'a'; if (c >= 'A' && c <= 'F') return 10 + c -'A'; return (char)c; } uint16_t swaps(uint16_t i) { uint16_t ret=0; ret = (i & 0xFF) << 8; ret |= ((i >> 8)& 0xFF); return ret; } unsigned int swapl(unsigned int l) { unsigned int ret=0; ret = (l & 0xFF) << 24; ret |= ((l >> 8) & 0xFF) << 16; ret |= ((l >> 16) & 0xFF) << 8; ret |= ((l >> 24) & 0xFF); return ret; } //get mid str void mid(char* src, char* s1, char* s2, char* sub) { char* sub1; char* sub2; unsigned short n; sub1=strstr(src,s1); sub1+=strlen(s1); sub2=strstr(sub1,s2); n=sub2-sub1; strncpy(sub,sub1,n); sub[n]=0; } void inet_addr_(unsigned char* addr,unsigned char *ip) { int i; char taddr[30]; char * nexttok; char num; strcpy(taddr,(char *)addr); nexttok = taddr; for(i = 0; i < 4 ; i++) { nexttok = strtok(nexttok,"."); if(nexttok[0] == '0' && nexttok[1] == 'x') num = ATOI(nexttok+2,0x10); else num = ATOI(nexttok,10); ip[i] = num; nexttok = NULL; } } /////////////////////////////////////////////////////////////////////////////// /* * The number of days in the month. */ int rtc_month_days(unsigned int month, unsigned int year) { return rtc_days_in_month[month] + (LEAP_YEAR(year) && month == 1); } /* * The number of days since January 1. (0 to 365) */ int rtc_year_days(unsigned int day, unsigned int month, unsigned int year) { return rtc_ydays[LEAP_YEAR(year)][month] + day-1; } /* * Convert seconds since 01-01-1970 00:00:00 to Gregorian date. */ void rtc_time_to_tm(unsigned long time, stRtcTime *tm) { int days, month, year; days = time / SencondsPerDay; time -= days * SencondsPerDay; /* day of the week, 1970-01-01 was a Thursday */ tm->tm_wday = (days + 4) % 7; year = YearUtcStart + days / NormalDayInYear; days -= (year - YearUtcStart) * NormalDayInYear + LEAPS_THRU_END_OF(year - 1) - LEAPS_THRU_END_OF(YearUtcStart - 1); if (days < 0) { year -= 1; days += NormalDayInYear + LEAP_YEAR(year); } tm->tm_year = year - 1900; tm->tm_yday = days + 1; for (month = 0; month < 11; month++) { int newdays; newdays = days - rtc_month_days(month, year); if (newdays < 0) break; days = newdays; } tm->tm_mon = month; tm->tm_mday = days + 1; tm->tm_hour = time / SencondsPerHour; time -= tm->tm_hour * SencondsPerHour; tm->tm_min = time / SencondsPerMinute; tm->tm_sec = time - tm->tm_min * SencondsPerMinute; } void utc_tm_to_time(const stRtcTime *tm, unsigned long * time) { unsigned long days; int temp; temp = LEAPS_THRU_END_OF(tm->tm_year - 1); temp -= LEAPS_THRU_END_OF(YearUtcStart - 1); days = (tm->tm_year - YearUtcStart) * NormalDayInYear; days += temp; temp = rtc_year_days(tm->tm_mday, tm->tm_mon, tm->tm_year); days += temp; *time = days * SencondsPerDay; *time += tm->tm_hour *SencondsPerHour+tm->tm_min *SencondsPerMinute+tm->tm_sec; } void rtcBySecondFromCentry(uint32_t time, stRtcTime *tm) { int days, month, year; days = time / SencondsPerDay; time -= days * SencondsPerDay; /* day of the week, 2000-01-01 was a Satarday */ tm->tm_wday = (days + 6) % 7; year = YearCentry + days / NormalDayInYear; days -= (year - YearCentry) * NormalDayInYear + LEAPS_THRU_END_OF(year - 1) - LEAPS_THRU_END_OF(YearCentry - 1); if (days < 0) { year -= 1; days += NormalDayInYear + LEAP_YEAR(year); } tm->tm_year = year - YearCentry; tm->tm_yday = days + 1; for (month = 0; month < 11; month++) { int newdays; newdays = days - rtc_month_days(month, year); if (newdays < 0) break; days = newdays; } tm->tm_mon = month + 1; tm->tm_mday = days + 1; tm->tm_hour = time / SencondsPerHour; time -= tm->tm_hour * SencondsPerHour; tm->tm_min = time / SencondsPerMinute; tm->tm_sec = time - tm->tm_min * SencondsPerMinute; } void secondsFromCentry(const stRtcTime *tm, unsigned int * time) { unsigned long days; int temp; unsigned int years = tm->tm_year + YearCentry; //days = (tm->tm_year - YearCentry) * NormalDayInYear; days = (tm->tm_year) * NormalDayInYear; temp = LEAPS_THRU_END_OF(years - 1); temp -= LEAPS_THRU_END_OF(YearCentry - 1); days += temp; temp = rtc_year_days(tm->tm_mday, tm->tm_mon-1, years); days += temp; *time = days * SencondsPerDay; *time += tm->tm_hour * SencondsPerHour + tm->tm_min * SencondsPerMinute + tm->tm_sec; } uint8_t BCC_CheckSum(uint8_t *buf, uint8_t len) { uint8_t i; uint8_t checksum = 0; for(i = 0; i < len; i++) { checksum ^= *buf++; } return checksum; } /* * CRC_modbus: little-endian; in modbus protocol, the crc value is big-endian. * If changed to big-endian, exchange the uchCRCHi/uchCRCLo locations in the while(){}; */ static unsigned char uchCRCHi = 0xff; static unsigned char uchCRCLo = 0xff; static unsigned char crc16_flag = 0; unsigned int CalculateCRC16(unsigned char *updata, unsigned int len) { unsigned int uindex; crc16_flag = 1; uchCRCHi = 0xff; uchCRCLo = 0xff; while(len--) { uindex = uchCRCHi ^ *updata++; uchCRCHi = uchCRCLo ^ auchCRCHi[uindex]; uchCRCLo = auchCRCLo[uindex]; } crc16_flag = 0; return (uchCRCHi<<8 | uchCRCLo); } /* * CRC16 data calculate * return: -1, fails; 0, ongoing; >0: finish; * * */ int CRC16_Start() { if(crc16_flag)return -1; crc16_flag = 1 ; uchCRCHi = 0xff; uchCRCLo = 0xff; return 0; } int CRC16_AddData(unsigned char *updata, unsigned int len) { if(!crc16_flag)return -1; unsigned int uindex; while(len--) { uindex = uchCRCHi ^ *updata++; uchCRCHi = uchCRCLo ^ auchCRCHi[uindex]; uchCRCLo = auchCRCLo[uindex]; } return 0; } int CRC16_Finish() { if(!crc16_flag) return -1; crc16_flag = 0; return (uchCRCHi<<8 | uchCRCLo); } /////////////////////////////////////////////////////////////////////////////// #ifdef USE_FULL_ASSERT void assert_failed(uint8_t* file, uint32_t line) { while (1) { ; } } #endif /*************************************************************************************************/