/*=========================================================================== Combined Charging System (CCS): SECC main.c initiated by Vern, Joseph (since 2019/07/19) =============================================================================*/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //for pow #include #include "define.h" #include "main.h" #define Debug struct SysConfigAndInfo *ShmSysConfigAndInfo; struct StatusCodeData *ShmStatusCodeData; struct CcsData *ShmCcsData; struct InternalComm *ShmInternalComm; #ifdef SystemLogMessage int StoreLogMsg(unsigned char *DataString); #endif void System_Init(); void CreateShareMemory_Init(); void GPIO_Init(); void PWM_Init(); void Confinguration_Init(); int DiffTimeb(struct timeb ST, struct timeb ET); int CreatShareMemory(); int LoadSysConfigAndInfo(struct SysConfigData *ptr); int SpawnTask(); int StoreUsrConfigData(struct SysConfigData *UsrData); /*=========================================================================== FUNCTION: main DESCRIPTION: 1. This main routine will be executed by the "rcS" when linux is booting up. /opt/ti-processor-sdk-linux-am335x-evm-04.02.00.09/EVSE/rootfs/etc/init.d/rcS PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int main(int argc, char *argv[]) { //int Rtn = 0; //unsigned int StartTime; //struct timeb StartChargingTime, CurrentChargingTime, ChargingLoopTime; //float ChargingPower, ChargingEnergy; //CSU Initialization System_Init(); //task spawn //SpawnTask(); /**************************************************************/ /************** main Loop********************************/ /*****************************************************************/ while(1) { sleep(5); }//main while } /*=========================================================================== FUNCTION: System_Init DESCRIPTION: PRE-CONDITION: 1. Pin Assignment Configuration board-support/linux-4.9.59+gitAUTOINC+a75d8e9305-ga75d8e9305/ arch/arm/boot/dts/[CCS]am335x-evm.dts INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ void System_Init() { // ---------- Hardware Init ---------- //Init GPIO GPIO_Init(); //Init ecap0 PWM_Init(); // ---------- Software Init ---------- //Create all share memory CreateShareMemory_Init(); //Init System Confinguration Confinguration_Init(); #ifdef SystemLogMessage StoreLogMsg("--------------------------"); StoreLogMsg("[main] System_Init(): DONE"); #endif } /*=========================================================================== FUNCTION: CreateShareMemory_Init DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ void CreateShareMemory_Init() { if(CreatShareMemory() == 0) { #ifdef SystemLogMessage StoreLogMsg("[main] CreateShareMemory_Init(): NG"); #endif if(ShmStatusCodeData != NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.FailToCreateShareMemory = 1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } else { #ifdef SystemLogMessage StoreLogMsg("[main] CreateShareMemory_Init(): DONE"); #endif } } /**************************************************************************************/ /**************************Create all share memory *********************************/ /**************************************************************************************/ /*=========================================================================== FUNCTION: CreatShareMemory DESCRIPTION: There are 4 share memory created here, which are listed as below. 1) ShmSysConfigAndInfo 2) ShmStatusCodeData 3) ShmCcsData 4) ShmInternalComm PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int CreatShareMemory() { int MeterSMId; //creat ShmSysConfigAndInfo if((MeterSMId = shmget(ShmSysConfigAndInfoKey, sizeof(struct SysConfigAndInfo), IPC_CREAT | 0777)) < 0) { #ifdef SystemLogMessage StoreLogMsg("[main]CreatShareMemory:shmget ShmSysConfigAndInfo NG"); #endif return 0; } else if((ShmSysConfigAndInfo = shmat(MeterSMId, NULL, 0)) == (void *)-1) { #ifdef SystemLogMessage StoreLogMsg("[main]CreatShareMemory:shmat ShmSysConfigAndInfo NG"); #endif return 0; } memset(ShmSysConfigAndInfo, 0, sizeof(struct SysConfigAndInfo)); //creat ShmStatusCodeData if((MeterSMId = shmget(ShmStatusCodeKey, sizeof(struct StatusCodeData), IPC_CREAT | 0777)) < 0) { #ifdef SystemLogMessage StoreLogMsg("[main]CreatShareMemory:shmget ShmStatusCodeData NG"); #endif return 0; } else if((ShmStatusCodeData = shmat(MeterSMId, NULL, 0)) == (void *)-1) { #ifdef SystemLogMessage StoreLogMsg("[main]CreatShareMemory:shmat ShmStatusCodeData NG"); #endif return 0; } memset(ShmStatusCodeData, 0, sizeof(struct StatusCodeData)); //creat ShmCcsData if((MeterSMId = shmget(ShmCcsCommKey, sizeof(struct CcsData), IPC_CREAT | 0777)) < 0) { #ifdef SystemLogMessage StoreLogMsg("[main]CreatShareMemory:shmget ShmCcsData NG"); #endif return 0; } else if((ShmCcsData = shmat(MeterSMId, NULL, 0)) == (void *)-1) { #ifdef SystemLogMessage StoreLogMsg("[main]CreatShareMemory:shmat ShmCcsData NG"); #endif return 0; } memset(ShmCcsData, 0, sizeof(struct CcsData)); //creat ShmInternalComm if((MeterSMId = shmget(ShmInternalCommKey, sizeof(struct InternalComm), IPC_CREAT | 0777)) < 0) { #ifdef SystemLogMessage StoreLogMsg("[main]CreatShareMemory:shmget ShmInternalComm NG"); #endif return 0; } else if((ShmInternalComm = shmat(MeterSMId, NULL, 0)) == (void *)-1) { #ifdef SystemLogMessage StoreLogMsg("[main]CreatShareMemory:shmat ShmInternalComm NG"); #endif return 0; } return 1; } /*=========================================================================== FUNCTION: GPIO_Init DESCRIPTION: 1. GPIO (input) x 1 * gpio2_0(gpio64): QCA7000 interrupt 2. GPIO (output) x 4 * gpio2_25 (gpio89): reserved (default = 0) * gpio2_23 (gpio87): reserved (default = 0) * gpio2_24 (gpio88): power reset QCA7000 (default = 0) * gpio2_22 (gpio86): Pilot Status E control (0V) (default = 0) PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ void GPIO_Init() { /*****************0~3, 4 bank, bank x 32+ num*********************/ /*****************************************************************/ /*************** INPUT PIN ***************************************/ /*****************************************************************/ /*GPIO2_0: QCA7000 interrupt */ system("echo 64 > /sys/class/gpio/export"); system("echo \"in\" > /sys/class/gpio/gpio64/direction"); /***************************************************************/ /*************** OUTPUT PIN ************************************/ /***************************************************************/ //IO port for Communication Board.(reserved for emergency shutdown PSU, i.e. PSKILL) /*GPIO2_25: AM_IO_2, H: ?; L: ?*/ system("echo 89 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio89/direction"); system("echo 0 > /sys/class/gpio/gpio89/value"); //IO port for Communication Board.(reserved for emergency shutdown PSU, i.e. PSKILL) /*GPIO2_23: AM_IO_1, H: ?; L: ?*/ system("echo 87 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio87/direction"); system("echo 0 > /sys/class/gpio/gpio87/value"); //Power Reset QCA7000 /*GPIO2_24: AM_QCA_PWR_RST, H: reset, L: noraml*/ system("echo 88 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio88/direction"); system("echo 0 > /sys/class/gpio/gpio88/value"); //Pilot Status E control (0V) /*GPIO2_22: Pilot_state E, H: state E, L: normal*/ system("echo 86 > /sys/class/gpio/export"); system("echo \"out\" > /sys/class/gpio/gpio86/direction"); system("echo 0 > /sys/class/gpio/gpio86/value"); #ifdef SystemLogMessage StoreLogMsg("[main] GPIO_Init(): DONE"); #endif } /*=========================================================================== FUNCTION: PWM_Init DESCRIPTION: - Initialize the PWM channel by the following configuration. * Frequency = 1KHz * Duty = 100% - The default voltage should be as below. * 12V: unplugged * 9V: plugged - Check Mechanism (to-do) * Read CP Voltage and PWM by AIN3: // cat /sys/bus/iio/devices/iio\\:device0/in_voltage3_raw; PRE-CONDITION: INPUT: OUTPUT: - PWM = 100% at 1KHz GLOBAL VARIABLES: =============================================================================*/ void PWM_Init() { //unsigned char str[256]; //init ecap0 //memset(str, 0, sizeof(str)); system("echo 0 > /sys/class/pwm/pwmchip0/export"); system("echo 1000000 > /sys/class/pwm/pwmchip0/pwm0/period");// nano seconds =>1k Hz system("echo 1000000 > /sys/class/pwm/pwmchip0/pwm0/duty_cycle"); //default 100% system("echo 1 > /sys/class/pwm/pwmchip0/pwm0/enable"); //system("echo 1 > /sys /class/pwm/pwmchip0/pwm0/polarity"); //PWM_Init_Check(); //Checking if the PWM analog signal is well-initialized //as 1KHz,100%, and 12V/9V. #ifdef SystemLogMessage StoreLogMsg("[main] PWM_Init(): DONE"); #endif } /*=========================================================================== FUNCTION: DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ void Confinguration_Init() { //Load System Confinguration LoadSysConfigAndInfo(&ShmSysConfigAndInfo->SysConfig); #ifdef SystemLogMessage StoreLogMsg("[main] Confinguration_Init(): DONE"); #endif } /*=========================================================================== FUNCTION: DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ #ifdef SystemLogMessage int StoreLogMsg(unsigned char *DataString) { unsigned char Buf[256]; time_t CurrentTime; struct tm *tm; struct timeval tv; gettimeofday(&tv, NULL); // get microseconds, 10^-6 //Get uptime in nano-second precision //struct timespec elapsed_from_boot; //clock_gettime(CLOCK_BOOTTIME, &elapsed_from_boot); //Need GLIBC_2.17 memset(Buf, 0, sizeof(Buf)); CurrentTime = time(NULL); tm = localtime(&CurrentTime); sprintf(Buf, "echo \"[%04d.%02d.%02d-%02d:%02d:%02d.%06d] @ %s\" >> /Storage/SystemLog/[%04d.%02d]SystemLog", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec, DataString, tm->tm_year + 1900, tm->tm_mon + 1); system(Buf); #ifdef Debug printf("[%04d.%02d.%02d-%02d:%02d:%02d.%06d] @ %s \n", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec, DataString); #endif } #endif /*=========================================================================== FUNCTION: DiffTimeb DESCRIPTION: Caculating the time difference in ms precision (milli-second). PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int DiffTimeb(struct timeb ST, struct timeb ET) { //return milli-second unsigned int StartTime, StopTime; StartTime = (unsigned int)ST.time; StopTime = (unsigned int)ET.time; return (StopTime - StartTime) * 1000 + ET.millitm - ST.millitm; } /**************************************************************************************/ /****************Following functions are CSU initialization***************************/ /**************************************************************************************/ /*=========================================================================== FUNCTION: DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int SpawnTask() { system("/root/EventLogging &"); system("/root/CsuComm &"); system("/root/EvComm &"); } /*=========================================================================== FUNCTION: DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int StoreUsrConfigData(struct SysConfigData *UsrData) { int fd, wrd; unsigned int i, Chk; unsigned char *ptr; Chk = 0; ptr = (unsigned char *)UsrData; for(i = 0; i < sizeof(struct SysConfigData) - 4; i++) { Chk += *(ptr + i); } UsrData->Checksum = Chk; fd = open("/dev/mtdblock10", O_RDWR); if(fd < 0) { #ifdef SystemLogMessage StoreLogMsg("[main]StoreUsrConfigData: open /dev/mtdblock10 NG"); #endif return 0; } wrd = write(fd, UsrData, sizeof(struct SysConfigData)); close(fd); if(wrd != (sizeof(struct SysConfigData))) { #ifdef SystemLogMessage StoreLogMsg("[main]StoreUsrConfigData: write /dev/mtdblock10 NG"); #endif return 0; } fd = open("/dev/mtdblock11", O_RDWR); if(fd < 0) { #ifdef SystemLogMessage StoreLogMsg("[main]StoreUsrConfigData: open /dev/mtdblock11(backup) NG"); #endif return 0; } wrd = write(fd, UsrData, sizeof(struct SysConfigData)); close(fd); if(wrd != (sizeof(struct SysConfigData))) { #ifdef SystemLogMessage StoreLogMsg("[main]StoreUsrConfigData: write /dev/mtdblock11(backup) NG"); #endif return 0; } return 1; } /*=========================================================================== FUNCTION: LoadSysConfigAndInfo DESCRIPTION: PRE-CONDITION: INPUT: OUTPUT: GLOBAL VARIABLES: =============================================================================*/ int LoadSysConfigAndInfo(struct SysConfigData *ptr) { int fd, wrd; struct SysConfigData *buf; unsigned char *PtrBuf; unsigned int ChkSum, ChkSumOrg; if((buf = malloc(sizeof(struct SysConfigData))) == NULL) { #ifdef SystemLogMessage StoreLogMsg("[main] LoadSysConfigAndInfo(): malloc buffer NG,rebooting.."); #endif if(ShmStatusCodeData != NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed = 1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } memset(buf, 0, sizeof(struct SysConfigData)); fd = open("/dev/mtdblock10", O_RDWR); if(fd < 0) { free(buf); #ifdef SystemLogMessage StoreLogMsg("[main] LoadSysConfigAndInfo():open mtdblock10 NG,rebooting.."); #endif if(ShmStatusCodeData != NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed = 1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } wrd = read(fd, buf, sizeof(struct SysConfigData)); close(fd); if(wrd != (sizeof(struct SysConfigData))) { free(buf); #ifdef SystemLogMessage StoreLogMsg("[main] LoadSysConfigAndInfo(): read SysConfigData data NG,rebooting.."); #endif if(ShmStatusCodeData != NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed = 1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } PtrBuf = (unsigned char *)buf; ChkSum = 0; for(wrd = 0; wrd < (sizeof(struct SysConfigData) - 4); wrd++) { ChkSum += PtrBuf[wrd]; } ChkSumOrg = buf->Checksum; if(ChkSum != ChkSumOrg) { #ifdef SystemLogMessage StoreLogMsg("[main] LoadSysConfigAndInfo(): Primary SysConfigData checksum NG, read backup"); #endif fd = open("/dev/mtdblock11", O_RDWR); if(fd < 0) { free(buf); #ifdef SystemLogMessage StoreLogMsg("[main] LoadSysConfigAndInfo(): open mtdblock11 (backup) NG,rebooting.."); #endif if(ShmStatusCodeData != NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed = 1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } memset(buf, 0, sizeof(struct SysConfigData)); wrd = read(fd, buf, sizeof(struct SysConfigData)); close(fd); if(wrd != sizeof(struct SysConfigData)) { free(buf); #ifdef SystemLogMessage StoreLogMsg("[main] LoadSysConfigAndInfo(): read backup SysConfigData data NG,rebooting.."); #endif if(ShmStatusCodeData != NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed = 1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } PtrBuf = (unsigned char *)buf; ChkSum = 0; for(wrd = 0; wrd < (sizeof(struct SysConfigData) - 4); wrd++) { ChkSum += PtrBuf[wrd]; } ChkSumOrg = buf->Checksum; if(ChkSum != ChkSumOrg) { #ifdef SystemLogMessage StoreLogMsg("[main] LoadSysConfigAndInfo(): backup SysConfigData checksum NG, read Factory default"); #endif fd = open("/dev/mtdblock12", O_RDWR); if(fd < 0) { free(buf); #ifdef SystemLogMessage StoreLogMsg("[main] LoadSysConfigAndInfo(): open mtdblock12 (Factory default) NG,rebooting.."); #endif if(ShmStatusCodeData != NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed = 1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } memset(buf, 0, sizeof(struct SysConfigData)); wrd = read(fd, buf, sizeof(struct SysConfigData)); close(fd); if(wrd != sizeof(struct SysConfigData)) { free(buf); #ifdef SystemLogMessage StoreLogMsg("[main] LoadSysConfigAndInfo(): read factory default SysConfigData data NG,rebooting.."); #endif if(ShmStatusCodeData != NULL) { ShmStatusCodeData->AlarmCode.AlarmEvents.bits.CsuInitFailed = 1; } sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); } PtrBuf = (unsigned char *)buf; ChkSum = 0; for(wrd = 0; wrd < (sizeof(struct SysConfigData) - 4); wrd++) { ChkSum += PtrBuf[wrd]; } ChkSumOrg = buf->Checksum; if(ChkSum != ChkSumOrg) { #ifdef SystemLogMessage StoreLogMsg("[main] LoadSysConfigAndInfo(): factory default SysConfigData checksum NG, restore factory default"); #endif goto DefaultShm; } } } //load OK memcpy((struct SysConfigData *)ptr, (struct SysConfigData *)buf, sizeof(struct SysConfigData)); free(buf); #ifdef SystemLogMessage StoreLogMsg("[main]LoadSysConfigAndInfo(): Load SysConfigData OK"); #endif return 1; DefaultShm: system("cd /root;./FactoryConfig"); system("sync"); sleep(5); system("reboot -f"); sleep(5); system("reboot -f"); }