#include #include #include "stm32f10x.h" #include "I2C.h" #include "define_globals.h" #include "Subroutines.h" #include "RTC.h" /*----------------------------------------------------------------------------- // init_i2c // -------------------- // Input: none // // Output: none // // This function configures the I2C interface. // // Date: 9.7.2013 // // Author: B.Binggeli //---------------------------------------------------------------------------*/ void init_i2c() { I2C_InitTypeDef I2C_InitStructure; I2C_Cmd(I2C1, ENABLE); // I2C1 configuration for EEPROM I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; // Working in Fast Mode I2C_InitStructure.I2C_OwnAddress1 = 0x30; // Own I2C Adress I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; // Enables the acknowledgement I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; //Acknowledge 7-bit address I2C_InitStructure.I2C_ClockSpeed = 100000; // Clock frequency 400kHz I2C_Init(I2C1, &I2C_InitStructure); } /*----------------------------------------------------------------------------- // EEPROM_write_bytes // -------------------- // Input: AddressI2C: Address of the EEPROM and the Block // AddressMEM: Address where the data were stored // NumByte: Number of Bytes // pBuffer: Pointer to Address where the data were coming from // // Output: the function retuns a zero if the hole function is executet. If there // are Problems the return value is 1. // // This function write the Bytes form pBuffer (pBuffer is a Pointer to u8) in to the EEPROM. // pBuffer -> AddressMEM // pBuffer+1 -> AddressMEM+1 // pBuffer+2 -> AddressMEM+3 // pBuffer+3 -> AddressMEM+3 // : : : // pBuffer+NumByte -> AddressMEM+NumByte // when there is a boundary of a block reached, it will create a new instance and writes there first the data till to the boundary then it goes back to the initial function and continue with writing the bytes in the next block. This is solved with modulo 128 // // Date: 9.7.2013 // // Author: B.Binggeli //---------------------------------------------------------------------------*/ unsigned char eeprom_write_bytes(int AddressMEM,int NumByte,unsigned char* pBuffer) { u16 timeout=0; char temp; int AddressI2C=I2C1_ADDRESS_EEPROM1_BLOCK0; //If Adress not in EEPROM1_BLOCK0 if(AddressMEM>=65536) { temp=AddressMEM>>16; AddressI2C=AddressI2C|((temp&0x01)<<3); //select Block AddressI2C=AddressI2C|(temp&0x06); //select EEPROM } //If Address is too high if(AddressMEM>=524288) { return FAILED; } //If there is a boundary of a block reached or the message has more than 128 Bytes while((AddressMEM%128)+NumByte>128) { //write the last bytes which are below the boundary or below 128 bytes in the next instance of eeprom_write_bytes if(eeprom_write_bytes(AddressMEM,(128-(AddressMEM%128)),pBuffer)){return FAILED;} //now we are back in the instance wich can continue with the next bytes: //increment the pointer of the buffer, decrement the NumByte and increment the address. //that will be written in the actual instance pBuffer = pBuffer+(128-(AddressMEM%128)); NumByte = NumByte-(128-(AddressMEM%128)); AddressMEM = AddressMEM+(128-(AddressMEM%128)); } timeout=0; //turn off interrupts to prevent breaks while the message is sent // USART_ITConfig(USART1, USART_IT_TXE, DISABLE); USART_ITConfig(USART2, USART_IT_TXE, DISABLE); USART_ITConfig(USART3, USART_IT_TXE, DISABLE); CAN_ITConfig(CAN1,CAN_IT_FMP0, DISABLE); CAN_ITConfig(CAN1,CAN_IT_FMP1, DISABLE); //wait until I2C slave is ready----------------------------------------------------------------------------------------------------- if(i2c_wait_until_ready(AddressI2C)){return FAILED;} //Send START condition--------------------------------------------------------------------------------------------------------------- I2C_GenerateSTART(I2C1, ENABLE); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)&& timeout<0xFFFF){timeout++;} if(timeout==0xFFFF){return FAILED;} //Send Control Byte--------------------------------------------------------------------------------------------------------------- I2C_Send7bitAddress(I2C1, AddressI2C, I2C_Direction_Transmitter); timeout=0; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)&& timeout<0xFFFF){timeout++;} if(timeout==0xFFFF){return FAILED;} //Send Address High Byte--------------------------------------------------------------------------------------------------------------- I2C_SendData(I2C1,AddressMEM>>8); timeout=0; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)&& timeout<0xFFFF){timeout++;} if(timeout==0xFFFF) {return FAILED;} //Send Address Low Byte--------------------------------------------------------------------------------------------------------------- I2C_SendData(I2C1,AddressMEM); timeout=0; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)&& timeout<0xFFFF){timeout++;} if(timeout==0xFFFF) {return FAILED;} // While there is data to be written--------------------------------------------------------------------------------------------------- while(NumByte--) { timeout=0; //Send the current byte I2C_SendData(I2C1, *pBuffer); //Point to the next byte to be written pBuffer++; //wait until transmission is ended while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)&& timeout<0xFFFF){timeout++;} if(timeout==0xFFFF){return FAILED;} } // Send STOP condition-------------------------------------------------------------------------------------------------------------- I2C_GenerateSTOP(I2C1, ENABLE); //turn on interrupts after the message was sent // USART_ITConfig(USART1, USART_IT_TXE, ENABLE); USART_ITConfig(USART2, USART_IT_TXE, ENABLE); USART_ITConfig(USART3, USART_IT_TXE, ENABLE); CAN_ITConfig(CAN1,CAN_IT_FMP0, ENABLE); CAN_ITConfig(CAN1,CAN_IT_FMP1, ENABLE); return SUCCESSFUL; } /*----------------------------------------------------------------------------- // EEPROM_read_bytes // -------------------- // Input: AddressI2C: Address of the EEPROM and the Block // AddressMEM: Address where the data were coming from // NumByte: Number of Bytes // pBuffer: Pointer to Address where the data were stored // // Output: the function retuns a zero if the hole function is executet. If there // are Problems the return value is 1. // // This function read the Bytes in the EEPROM and store it into pBuffer (pBuffer is a Pointer to u8). // pBuffer <- AddressMEM // pBuffer+1 <- AddressMEM+1 // pBuffer+2 <- AddressMEM+3 // pBuffer+3 <- AddressMEM+3 // : : : // pBuffer+NumByte <- AddressMEM+NumByte // // Date: 9.7.2013 // // Author: B.Binggeli //---------------------------------------------------------------------------*/ unsigned char eeprom_read_bytes(int AddressMEM,int NumByte,u8* pBuffer) { int temp; u16 timeout=0; int AddressI2C=I2C1_ADDRESS_EEPROM1_BLOCK0; //If Adress not in EEPROM1_BLOCK0 if(AddressMEM>=65536) { temp=AddressMEM>>16; AddressI2C=AddressI2C|((temp&0x01)<<3); //select Block AddressI2C=AddressI2C|(temp&0x06); //select EEPROM } //If Address is too high if(AddressMEM>=524288) { return FAILED; } while((AddressMEM%65536)+NumByte>65536) { if(eeprom_read_bytes(AddressMEM,(65536-(AddressMEM%65536)),pBuffer)){return FAILED;} pBuffer = pBuffer+(65536-(AddressMEM%65536)); NumByte = NumByte-(65536-(AddressMEM%65536)); AddressMEM = AddressMEM+(65536-(AddressMEM%65536)); } //turn off interrupts to prevent breaks while the message is sent // USART_ITConfig(USART1, USART_IT_TXE, DISABLE); USART_ITConfig(USART2, USART_IT_TXE, DISABLE); USART_ITConfig(USART3, USART_IT_TXE, DISABLE); CAN_ITConfig(CAN1,CAN_IT_FMP0, DISABLE); CAN_ITConfig(CAN1,CAN_IT_FMP1, DISABLE); //wait until I2C slave is ready----------------------------------------------------------------------------------------------------- if(i2c_wait_until_ready(AddressI2C)){return FAILED;} //Send STRAT condition--------------------------------------------------------------------------------------------------------------- I2C_GenerateSTART(I2C1, ENABLE); timeout=0; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)&& timeout<0xFFFF){timeout++;} if(timeout>0xFFFF) {return FAILED;} //Send Control Byte--------------------------------------------------------------------------------------------------------------- I2C_Send7bitAddress(I2C1, AddressI2C, I2C_Direction_Transmitter); timeout=0; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)&& timeout<0xFFFF){timeout++;} if(timeout==0xFFFF) {return FAILED;} I2C_Cmd(I2C1, ENABLE); //Send Address High Byte--------------------------------------------------------------------------------------------------------------- I2C_SendData(I2C1,AddressMEM>>8); timeout=0; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)&& timeout<0xFFFF){timeout++;} if(timeout==0xFFFF) {return FAILED;} //Send Address Low Byte--------------------------------------------------------------------------------------------------------------- I2C_SendData(I2C1,AddressMEM); timeout=0; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)&& timeout<0xFFFF){timeout++;} if(timeout==0xFFFF) {return FAILED;} //Send STRAT condition--------------------------------------------------------------------------------------------------------------- I2C_GenerateSTART(I2C1, ENABLE); timeout=0; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)&& timeout<0xFFFF){timeout++;} if(timeout==0xFFFF) {return FAILED;} //Send Control Byte--------------------------------------------------------------------------------------------------------------- I2C_Send7bitAddress(I2C1, AddressI2C, I2C_Direction_Receiver); timeout=0; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)&& timeout<0xFFFF) if(timeout==0xFFFF) {return FAILED;} //Read Bytes until NumByte is reached--------------------------------------------------------------------------------------------------- while(NumByte) { if(NumByte == 1) { // Disable Acknowledgement I2C_AcknowledgeConfig(I2C1, DISABLE); // Send STOP Condition I2C_GenerateSTOP(I2C1, ENABLE); } //Test if Data-Byte is recived if(I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)) { I2C_AcknowledgeConfig(I2C1, ENABLE); // Read a byte from the EEPROM *pBuffer = I2C_ReceiveData(I2C1); //Point to the next location where the byte read will be saved pBuffer++; // Decrement the read bytes counter NumByte--; } } // Send STOP condition-------------------------------------------------------------------------------------------------------------- //I2C_GenerateSTOP(I2C1, ENABLE); //turn on interrupts after the message was sent // USART_ITConfig(USART1, USART_IT_TXE, ENABLE); USART_ITConfig(USART2, USART_IT_TXE, ENABLE); USART_ITConfig(USART3, USART_IT_TXE, ENABLE); CAN_ITConfig(CAN1,CAN_IT_FMP0, ENABLE); CAN_ITConfig(CAN1,CAN_IT_FMP1, ENABLE); return SUCCESSFUL; } /*----------------------------------------------------------------------------- // rtc_read_time // -------------------- // Input: AddressI2C: Address of the rtc // AddressMEM: Address where the data were coming from // NumByte: Number of Bytes // pBuffer: Pointer to Address where the data were stored // // Output: the function retuns a zero if the hole function is executet. If there // are Problems the return value is 1. // // This function read the Bytes in the rtc and store it into pBuffer (pBuffer is a Pointer to u8). // // Date: 29.10.2013 // // Author: B.Binggeli //---------------------------------------------------------------------------*/ unsigned char rtc_read_time(int AddressI2C,int AddressMEM,int NumByte,u8* pBuffer) { u16 timeout=0; //turn off interrupts to prevent breaks while the message is sent // USART_ITConfig(USART1, USART_IT_TXE, DISABLE); USART_ITConfig(USART2, USART_IT_TXE, DISABLE); //Provisorisch ausgeschaltet!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! USART_ITConfig(USART3, USART_IT_TXE, DISABLE); CAN_ITConfig(CAN1,CAN_IT_FMP0, DISABLE); CAN_ITConfig(CAN1,CAN_IT_FMP1, DISABLE); //wait until I2C slave is ready----------------------------------------------------------------------------------------------------- if(i2c_wait_until_ready(AddressI2C)){return FAILED;} //Send STRAT condition--------------------------------------------------------------------------------------------------------------- I2C_GenerateSTART(I2C1, ENABLE); timeout=0; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)&& timeout<0xFFFF){timeout++;} if(timeout>0xFFFF) {return FAILED;} //Send Control Byte--------------------------------------------------------------------------------------------------------------- I2C_Send7bitAddress(I2C1, AddressI2C, I2C_Direction_Transmitter); timeout=0; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)&& timeout<0xFFFF){timeout++;} if(timeout==0xFFFF) {return FAILED;} I2C_Cmd(I2C1, ENABLE); //Send Address -------------------------------------------------------------------------------------------------------------------- I2C_SendData(I2C1,AddressMEM); timeout=0; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)&& timeout<0xFFFF){timeout++;} if(timeout==0xFFFF) {return FAILED;} //Send STRAT condition--------------------------------------------------------------------------------------------------------------- I2C_GenerateSTART(I2C1, ENABLE); timeout=0; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)&& timeout<0xFFFF){timeout++;} if(timeout==0xFFFF) {return FAILED;} //Send Control Byte--------------------------------------------------------------------------------------------------------------- I2C_Send7bitAddress(I2C1, AddressI2C, I2C_Direction_Receiver); timeout=0; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)&& timeout<0xFFFF) if(timeout==0xFFFF) {return FAILED;} //Read Bytes until NumByte is reached--------------------------------------------------------------------------------------------------- while(NumByte) { if(NumByte == 1) { // Disable Acknowledgement I2C_AcknowledgeConfig(I2C1, DISABLE); // Send STOP Condition I2C_GenerateSTOP(I2C1, ENABLE); } //Test if Data-Byte is recived if(I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)) { I2C_AcknowledgeConfig(I2C1, ENABLE); // Read a byte from the EEPROM *pBuffer = I2C_ReceiveData(I2C1); //Point to the next location where the byte read will be saved pBuffer++; // Decrement the read bytes counter NumByte--; } } // Send STOP condition-------------------------------------------------------------------------------------------------------------- //I2C_GenerateSTOP(I2C1, ENABLE); //turn on interrupts after the message was sent // USART_ITConfig(USART1, USART_IT_TXE, ENABLE); USART_ITConfig(USART2, USART_IT_TXE, ENABLE); USART_ITConfig(USART3, USART_IT_TXE, ENABLE); CAN_ITConfig(CAN1,CAN_IT_FMP0, ENABLE); CAN_ITConfig(CAN1,CAN_IT_FMP1, ENABLE); return SUCCESSFUL; } /*----------------------------------------------------------------------------- // rtc_write_time // -------------------- // Input: AddressI2C: Address of the rtc // AddressMEM: Address where the data were stored // NumByte: Number of Bytes // pBuffer: Pointer to Address where the data were coming from // // Output: the function retuns a zero if the hole function is executet. If there // are Problems the return value is 1. // // This function write the Bytes form pBuffer (pBuffer is a Pointer to u8) in to the rtc. // // Date: 29.10.2013 // // Author: B.Binggeli //---------------------------------------------------------------------------*/ unsigned char rtc_write_time(int AddressI2C,int AddressMEM,int NumByte,u8* pBuffer) { u16 timeout=0; //turn off interrupts to prevent breaks while the message is sent // USART_ITConfig(USART1, USART_IT_TXE, DISABLE); USART_ITConfig(USART2, USART_IT_TXE, DISABLE); //Provisorisch Ausgeschaltet!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! USART_ITConfig(USART3, USART_IT_TXE, DISABLE); CAN_ITConfig(CAN1,CAN_IT_FMP0, DISABLE); CAN_ITConfig(CAN1,CAN_IT_FMP1, DISABLE); //wait until I2C slave is ready----------------------------------------------------------------------------------------------------- if(i2c_wait_until_ready(AddressI2C)){return FAILED;} //Send STRAT condition--------------------------------------------------------------------------------------------------------------- I2C_GenerateSTART(I2C1, ENABLE); while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)&& timeout<0xFFFF){timeout++;} if(timeout==0xFFFF){return FAILED;} //Send Control Byte--------------------------------------------------------------------------------------------------------------- I2C_Send7bitAddress(I2C1, AddressI2C, I2C_Direction_Transmitter); timeout=0; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)&& timeout<0xFFFF){timeout++;} if(timeout==0xFFFF){return FAILED;} //Send Address --------------------------------------------------------------------------------------------------------------------- I2C_SendData(I2C1,AddressMEM); timeout=0; while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)&& timeout<0xFFFF){timeout++;} if(timeout==0xFFFF) {return FAILED;} // While there is data to be written--------------------------------------------------------------------------------------------------- while(NumByte--) { timeout=0; //Send the current byte I2C_SendData(I2C1, *pBuffer); //Point to the next byte to be written pBuffer++; //wait until transmission is ended while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)&& timeout<0xFFFF){timeout++;} if(timeout==0xFFFF){return FAILED;} } // Send STOP condition-------------------------------------------------------------------------------------------------------------- I2C_GenerateSTOP(I2C1, ENABLE); //turn on interrupts after the message was sent // USART_ITConfig(USART1, USART_IT_TXE, ENABLE); USART_ITConfig(USART2, USART_IT_TXE, ENABLE); USART_ITConfig(USART3, USART_IT_TXE, ENABLE); CAN_ITConfig(CAN1,CAN_IT_FMP0, ENABLE); CAN_ITConfig(CAN1,CAN_IT_FMP1, ENABLE); return SUCCESSFUL; } unsigned char i2c_wait_until_ready(char I2C_EEAddress) { volatile uint16_t SR1_Tmp = 0; volatile uint16_t SR2_Tmp = 0; u32 timeout=0; int x; do { /*!< Send START condition */ I2C_GenerateSTART(I2C1, ENABLE); /*!< Read sEE SR1 + SR2 registers to clear pending flags (ADDR Flag) */ SR1_Tmp = I2C_ReadRegister(I2C1, I2C_Register_SR1); //SR2_Tmp = I2C_ReadRegister(I2C1, I2C_Register_SR2); /*!< Send EEPROM address for write */ I2C_Send7bitAddress(I2C1, I2C_EEAddress, I2C_Direction_Transmitter); timeout++; }while(!(I2C_ReadRegister(I2C1, I2C_Register_SR1) & 0x0002) && timeout<0xFFF); //ADDR bit the I2C_SR1 Register is set after //the ACK of the byte is received. //While the EEPROM is in standby, he return a NACK if(timeout==0xFFF) { return FAILED; } /*!< Clear AF flag */ I2C_ClearFlag(I2C1, I2C_FLAG_AF); /*!< STOP condition */ I2C_GenerateSTOP(I2C1, ENABLE); /*!< wait for Bus free time see datasheet of 24AA1025*/ for(x=0;x<1500;x++){} return SUCCESSFUL; } /*----------------------------------------------------------------------------- // log_date // -------------------- // Input: none // // Output: none // // This function logs the date in the EEPROM // // Date: 13.02.2014 // // Author: S.Weyeneth //---------------------------------------------------------------------------*/ void log_date(){ g_Log_array[0] = 1; //Msg ID g_Log_array[1] = g_date; //date g_Log_array[2] = g_month; //month g_Log_array[3] = g_year & 0xFF; //first byte of the year g_Log_array[4] = g_year >> 8; //second byte of the year //delete other positions g_Log_array[5] = 0; g_Log_array[6] = 0; g_Log_array[7] = 0; write_log_data_EEPROM(); } /*----------------------------------------------------------------------------- // log_login // -------------------- // Input: unsigned char user // // Output: none // // This function logs the login (User ID) in the EEPROM. // // Date: 13.02.2014 // // Author: S.Weyeneth //---------------------------------------------------------------------------*/ void log_login(unsigned char user){ g_Log_array[0] = 2; //Msg ID g_Log_array[1] = user; //User ID g_Log_array[2] = g_hour; //hour g_Log_array[3] = g_minute; //minute //delete other positions g_Log_array[4] = 0; g_Log_array[5] = 0; g_Log_array[6] = 0; g_Log_array[7] = 0; write_log_data_EEPROM(); } /*----------------------------------------------------------------------------- // log_prog_start // -------------------- // Input: unsigned char station. unsigned char prog_Nr = program number unsigned int ref_Nr = Reference number // // Output: none // // This function logs the data of a started program in the EEPROM // // Date: 13.02.2014 // // Author: S.Weyeneth //---------------------------------------------------------------------------*/ void log_prog_start(unsigned char station, unsigned char prog_Nr, unsigned int ref_Nr){ g_Log_array[0] = 3; //Msg ID g_Log_array[1] = station; //station g_Log_array[2] = prog_Nr; //program number g_Log_array[3] = g_hour; //hour g_Log_array[4] = g_minute; //minute g_Log_array[5] = ref_Nr & 0xFF; //fist byte of reference number g_Log_array[6] = (ref_Nr >> 8) & 0xFF; //second byte of reference number g_Log_array[7] = (ref_Nr >> 16) & 0xFF; //third byte of reference number write_log_data_EEPROM(); } /*----------------------------------------------------------------------------- // log_prog_stop // -------------------- // Input: unsigned char station. unsigned char prog_Nr = program number // // Output: none // // This function logs the data of a stopped program in the EEPROM // // Date: 13.02.2014 // // Author: S.Weyeneth //---------------------------------------------------------------------------*/ void log_prog_stop(unsigned char station, unsigned char prog_Nr){ g_Log_array[0] = 4; //Msg ID g_Log_array[1] = station; //station g_Log_array[2] = prog_Nr; //program number g_Log_array[3] = g_hour; //hour g_Log_array[4] = g_minute; //minute //delete old values g_Log_array[5] = 0; g_Log_array[6] = 0; g_Log_array[7] = 0; write_log_data_EEPROM(); } /*----------------------------------------------------------------------------- // log_finished_step // -------------------- // Input: unsigned char station. unsigned char prog_Nr = program number unsigned char step_Nr = step number int av_power = average power of the step int av_temperature = average temperature of a step in °C int nom_freq = nominal frequency of the first generator of a station in Hz (but logged in 0.1 kHz rounded) // // Output: none // // This function logs the data of a finished step of a running program in the EEPROM // // Date: 19.02.2014 // // Author: S.Weyeneth //---------------------------------------------------------------------------*/ void log_finished_step(unsigned char station, unsigned char prog_Nr, unsigned char step_Nr,int step_time, unsigned char av_power, unsigned char av_temperature, int nom_freq){ char temp; //round nominal frequency and divide by 1000, so that we log 0.1 kHz nom_freq = (int)(((double)nom_freq + 50.0)/100.0); //Byte 0 temp = 5; //Bit 0-4 = Msg_ID temp = ((station & 7)<<5) | temp; //Bit 0-2 of station = Bit 5-7 of Byte 0 g_Log_array[0] = temp; //Byte 1 temp = station >> 3; //Bit 3 of station = Bit 0 of Byte 1 temp = ((prog_Nr & 0X7F) << 1) | temp; //Bit 0-6 of prog_Nr = Bit 1-7 of Byte 1 g_Log_array[1] = temp; //Byte 2 temp = step_Nr & 0x7F; //Bit 0-6 of step_Nr = Bit 0-6 of Byte 2 temp = ((step_time & 1) << 7) | temp; //Bit 0 of step_time = Bit 7 of Byte 2 g_Log_array[2] = temp; //Byte 3 g_Log_array[3] = (step_time >> 1) & 0xFF; //Bit 1-8 of step_time = Byte 3 //Byte 4 temp = (step_time >> 9) & 0X7; //Bit 9-11 of step_time = Bit 0-2 of Byte 4 temp = ((av_power & 0X1F) << 4) | temp; //Bit 0-4 of av_power = Bit 3-7 of Byte 4 g_Log_array[4] = temp; //Byte 5 temp = (av_power >> 5) & 3; //Bit 5-6 of av_power = Bit 0-1 of Byte 5 temp = ((av_temperature & 0X3F) << 2) | temp; //Bit 0-5 of nom_freq = Bit 2-7 of Byte 5 g_Log_array[5] = temp; //Byte 6 temp = (av_temperature >> 6) & 1; //Bit 6 of av_temperature = Bit 0 of Byte 6 temp = ((nom_freq & 0x7F) << 1) | temp; //Bit 0-6 of nom_freq = bit 1-7 of Byte 6 g_Log_array[6] = temp; //Byte 7 g_Log_array[7] = nom_freq >> 7; write_log_data_EEPROM(); } /*----------------------------------------------------------------------------- // log_prog_stop // -------------------- // Input: unsigned int error_ID = Error ID unsigned char generator_ID = Generator ID. ID = 0, when it's an error of the BG // Output: none // // This function logs an occured error in the EEPROM. It saves the message in the log data memory and in the error log data memory twice. // Both memories have a pointer in EEPROM which shows, where the next entry has to be written. If there is an overflow, it starts at begin of the // ring memory. // // Date: 18.02.2014 // // Author: S.Weyeneth //---------------------------------------------------------------------------*/ void log_error_msg(unsigned char error_ID, unsigned char generator_ID){ // unsigned char EEPROM_value_errorlog_pointer[4]; //temporary used variable to read the value of the address of the error log data pointer in the EEPROM unsigned char error=0; //write error parameters also in modbus registers and set error bit in system bits g_modbus_registers[ERROR_MSG_HOUR_ADDR - ADDRESS_MIN_MOD] = g_hour; g_modbus_registers[ERROR_MSG_MIN_ADDR - ADDRESS_MIN_MOD] = g_minute; g_modbus_registers[ERROR_MSG_ERR_ID_ADDR - ADDRESS_MIN_MOD] = error_ID; g_modbus_registers[ERROR_MSG_GEN_ID_ADDR - ADDRESS_MIN_MOD] = generator_ID; g_modbus_registers[SYSTEM_BITS_ADDR - ADDRESS_MIN_MOD] |= (1<<2); g_Log_array[0] = 6; //Msg ID g_Log_array[1] = g_hour; //hour g_Log_array[2] = g_minute; //minute g_Log_array[3] = error_ID; //error ID g_Log_array[4] = generator_ID; //generator ID //delete old values g_Log_array[5] = 0; g_Log_array[6] = 0; g_Log_array[7] = 0; //save firstly the error log message in the "normal" log data write_log_data_EEPROM(); //log the error also in the error log data memory______________________________________ //read error log data pointer in EEPROM //solved with ADC. This value is read in aa_init and saved in EEPROM, when the power supply is switched off. // error = eeprom_read_bytes(EEPROM_ERROR_LOG_POINTER, 4, EEPROM_value_errorlog_pointer); // g_error_log_data_pointer = (EEPROM_value_errorlog_pointer[3] << 24) + (EEPROM_value_errorlog_pointer[2] << 16) + (EEPROM_value_errorlog_pointer[1] << 8) + (EEPROM_value_errorlog_pointer[0]); //if the pointer is not in the addresses of the ring memory or it's not in a correct address of the form (start address + n*datalength), then set it to start address if(g_error_log_data_pointer < EEPROM_ERROR_LOG_BEGIN || g_error_log_data_pointer > EEPROM_ERROR_LOG_END || ((g_error_log_data_pointer - EEPROM_ERROR_LOG_BEGIN)%LOG_DATA_MESSAGE_LENGTH != 0)){ g_error_log_data_pointer = EEPROM_ERROR_LOG_BEGIN; } // -1 because the address itself is also a Byte if(g_error_log_data_pointer + (LOG_DATA_MESSAGE_LENGTH - 1) < EEPROM_ERROR_LOG_END){ //checks whether there is an overflow if(!error){ error = eeprom_write_bytes(g_error_log_data_pointer, LOG_DATA_MESSAGE_LENGTH, g_Log_array); //No overflow } else { eeprom_write_bytes(g_error_log_data_pointer, LOG_DATA_MESSAGE_LENGTH, g_Log_array); //No voerflow } g_error_log_data_pointer = g_error_log_data_pointer + LOG_DATA_MESSAGE_LENGTH; } else { //log g_Log_array which is saved in the global variable g_Log_array at start address of error log data memory if(!error){ error = eeprom_write_bytes(EEPROM_ERROR_LOG_BEGIN, LOG_DATA_MESSAGE_LENGTH, g_Log_array); } else { eeprom_write_bytes(EEPROM_ERROR_LOG_BEGIN, LOG_DATA_MESSAGE_LENGTH, g_Log_array); } g_error_log_data_pointer = EEPROM_ERROR_LOG_BEGIN + LOG_DATA_MESSAGE_LENGTH; } //actualize the log data pointer in the EEPROM //solved with ADC. This value is read in aa_init and saved in EEPROM, when the power supply is switched off. // EEPROM_value_errorlog_pointer[0] = g_error_log_data_pointer & 0xFF; // EEPROM_value_errorlog_pointer[1] = (g_error_log_data_pointer >> 8) & 0xFF; // EEPROM_value_errorlog_pointer[2] = (g_error_log_data_pointer >> 16) & 0xFF; // EEPROM_value_errorlog_pointer[3] = (g_error_log_data_pointer >> 24) & 0xFF; // if(!error){ // error = eeprom_write_bytes(EEPROM_ERROR_LOG_POINTER, 4, EEPROM_value_errorlog_pointer); // } else { // eeprom_write_bytes(EEPROM_ERROR_LOG_POINTER, 4, EEPROM_value_errorlog_pointer); // } if(error){error_handler(EEPROM_ERROR, 0);} } /*----------------------------------------------------------------------------- // write_log_data_EEPROM // -------------------- // Input: // Output: none // // This function writes the log data to EEPROM. When there is an overflow, it starts from beginning of the memory which is used for log data (ring memory). This function is called for every log entry. So it actualize every time the modbus registers "Log-Message" and set the bit "Log-msg-pending" in system bits // Date: 02.07.2014 // // Author: S.Weyeneth //---------------------------------------------------------------------------*/ void write_log_data_EEPROM(){ //variables for sending over USB static char send [SEND_LOGDATA_BUFFER_SIZE]; int n, length; unsigned char i; unsigned char error=0; unsigned char Write_array[8]; // the value is only read in aa_init and then in RAM. Otherwise it writes too much to the same address in EEPROM // unsigned char EEPROM_value_datalog_pointer[4]; //temporary used variable to read the value of the address of the log data pointer in the EEPROM //actualize modbus registers "Log-message" and set the bit "log-msg-bit" in system bits for(i=0; i < (LOG_DATA_MESSAGE_LENGTH >> 1); i++){ //division of 2 because modbus registers are unsigned short and g_Log_array has unsigned char format g_modbus_registers[LOG_MSG_ADDR - ADDRESS_MIN_MOD + i] = (unsigned short)(g_Log_array[2*i]) + ((unsigned short)(g_Log_array[2*i+1])<<8); //Or is used as addition } //set bit "log message pending" in system bits g_modbus_registers[SYSTEM_BITS_ADDR - ADDRESS_MIN_MOD] |= (1<<3); //read log data pointer in EEPROM // Solved with ADC and RAM!!!!!! the value is only read in aa_init and then in RAM. Otherwise it writes too much to the same address in EEPROM // error = eeprom_read_bytes(EEPROM_DATALOG_POINTER, 4, EEPROM_value_datalog_pointer); // g_log_data_pointer = (EEPROM_value_datalog_pointer[3] << 24) + (EEPROM_value_datalog_pointer[2] << 16) + (EEPROM_value_datalog_pointer[1] << 8) + (EEPROM_value_datalog_pointer[0]); //if the pointer is not in the addresses of the ring memory or it's not in a correct address of the form (start address + n*datalength), then set it to start address if(g_log_data_pointer < EEPROM_DATALOG_BEGIN || g_log_data_pointer > EEPROM_DATALOG_END || ((g_log_data_pointer - EEPROM_DATALOG_BEGIN)%LOG_DATA_MESSAGE_LENGTH != 0)){ g_log_data_pointer = EEPROM_DATALOG_BEGIN; } // -1 because g_log_data_pointer itself is also a byte if(g_log_data_pointer + LOG_DATA_MESSAGE_LENGTH < EEPROM_DATALOG_END){ //checks whether there is an overflow if(!error){ error = eeprom_write_bytes(g_log_data_pointer, LOG_DATA_MESSAGE_LENGTH, g_Log_array); //No overflow } else { eeprom_write_bytes(g_log_data_pointer, LOG_DATA_MESSAGE_LENGTH, g_Log_array); //No overflow } g_log_data_pointer = g_log_data_pointer + LOG_DATA_MESSAGE_LENGTH; } else { // on every start of the ring memory the date has to be logged, so that one entry is a date at least Write_array[0] = '\0'; Write_array[0] = 1; //Msg ID Write_array[1] = g_date; //date Write_array[2] = g_month; //month Write_array[3] = g_year & 0xFF; //first byte of the year Write_array[4] = g_year >> 8; //second byte of the year if(!error){ error = eeprom_write_bytes(EEPROM_DATALOG_BEGIN, LOG_DATA_MESSAGE_LENGTH, Write_array); //overflow -> start from begin } else { eeprom_write_bytes(EEPROM_DATALOG_BEGIN, LOG_DATA_MESSAGE_LENGTH, Write_array); //overflow -> start from begin } // on every start of the ring memory the user ID has to be logged, so that one entry is the User ID at least Write_array[0] = '\0'; Write_array[0] = 2; //Msg ID Write_array[1] = g_user_ID; //User ID Write_array[2] = g_hour; //hour Write_array[3] = g_minute; //minute if(!error){ error = eeprom_write_bytes(EEPROM_DATALOG_BEGIN+LOG_DATA_MESSAGE_LENGTH, LOG_DATA_MESSAGE_LENGTH, Write_array); //overflow -> start from begin } else { eeprom_write_bytes(EEPROM_DATALOG_BEGIN+LOG_DATA_MESSAGE_LENGTH, LOG_DATA_MESSAGE_LENGTH, Write_array); //overflow -> start from begin } //log g_Log_array which is saved in the global variable g_Log_array g_log_data_pointer = EEPROM_DATALOG_BEGIN + 2*LOG_DATA_MESSAGE_LENGTH; if(!error){ error = eeprom_write_bytes(g_log_data_pointer, LOG_DATA_MESSAGE_LENGTH, g_Log_array); } else { eeprom_write_bytes(g_log_data_pointer, LOG_DATA_MESSAGE_LENGTH, g_Log_array); } } //actualize the log data pointer in the EEPROM // Solved with ADC and RAM!!!!!!!!! the value is only read in aa_init and then in RAM. Otherwise it writes too much to the same address in EEPROM // EEPROM_value_datalog_pointer[0] = g_log_data_pointer & 0xFF; // EEPROM_value_datalog_pointer[1] = (g_log_data_pointer >> 8) & 0xFF; // EEPROM_value_datalog_pointer[2] = (g_log_data_pointer >> 16) & 0xFF; // EEPROM_value_datalog_pointer[3] = (g_log_data_pointer >> 24) & 0xFF; // if(!error){ // error = eeprom_write_bytes(EEPROM_DATALOG_POINTER, 4, EEPROM_value_datalog_pointer); // } else { // eeprom_write_bytes(EEPROM_DATALOG_POINTER, 4, EEPROM_value_datalog_pointer); // } if(error){error_handler(EEPROM_ERROR, 0);} //send also the data over USB*********************************************************************** //decode the entry. Send is an array of 100, so the maximum length is 100 log_data_decoder(g_Log_array, send); //calculate length of the string, that has to be sent length = strlen(send); //when log-message is too big, make an error if(length >= SEND_LOGDATA_BUFFER_SIZE){ error_handler(ERROR_UART3, 0); } //Send the data //Because of possible interrupts of UART the position-pointers could be faulty USART_ITConfig(USART3, USART_IT_TXE, DISABLE); for(n=0;n < length; n++) { //write data into uart buffer //increnment byte in buffer counter g_tx_data3[(g_tx_position3+g_tx_counter3)%USART3_TX_BUFFER_SIZE]= (unsigned char)send [n]; g_tx_counter3++; //if buffer full create error if(g_tx_counter3>=USART3_TX_BUFFER_SIZE){ error_handler(UART3_BUFFER_OVERFLOW, 0); } } //enable UART-Interrupt again USART_ITConfig(USART3, USART_IT_TXE, ENABLE); /************************** END OF USB Transmission *******************************************/ } /*----------------------------------------------------------------------------- // clear_log_data_memory // -------------------- // Input: // Output: none // // This function clears the log data memory and sets the corresponding LOG_DATA_POINTER to the start addresses // Date: 25.02.2014 // // Author: S.Weyeneth -------------------------------------------------------------------------------*/ void clear_log_data_memory(){ unsigned int address; unsigned char write_array[16]; unsigned char write_array_8[LOG_DATA_MESSAGE_LENGTH]; unsigned char error=0; unsigned char i; for(i=0; i> 8) & 0xFF; write_array[2+i] = (address >> 16) & 0xFF; write_array[3+i] = (address >> 24) & 0xFF; i=i+4; } if(!error){ error = eeprom_write_bytes(EEPROM_DATALOG_POINTER, 16, write_array); g_log_data_pointer = EEPROM_DATALOG_BEGIN; } else { eeprom_write_bytes(EEPROM_DATALOG_POINTER, 16, write_array); g_log_data_pointer = EEPROM_DATALOG_BEGIN; } //set the error_log_data_pointer to start address address = EEPROM_ERROR_LOG_BEGIN; while (i<16) { write_array[0+i] = address & 0xFF; write_array[1+i] = (address >> 8) & 0xFF; write_array[2+i] = (address >> 16) & 0xFF; write_array[3+i] = (address >> 24) & 0xFF; i=i+4; } if(!error){ error = eeprom_write_bytes(EEPROM_ERROR_LOG_POINTER, 16, write_array); g_error_log_data_pointer = EEPROM_ERROR_LOG_BEGIN; } else { eeprom_write_bytes(EEPROM_ERROR_LOG_POINTER, 16, write_array); g_error_log_data_pointer = EEPROM_ERROR_LOG_BEGIN; } //log an occured error if(error){error_handler(EEPROM_ERROR, 0);} } /*----------------------------------------------------------------------------- // clear_passwords // -------------------- // Input: // Output: none // // This function clears the user and supervisor passwords // Date: 25.02.2014 // // Author: S.Weyeneth -------------------------------------------------------------------------------*/ void clear_passwords(){ unsigned int address; unsigned char write_array[4] = {0,0,0,0}; unsigned char error=0; //clear user passwords address = EEPROM_USER_PW_BEGIN; while(address <= EEPROM_USER_PW_END - 4){ if(!error){ error = eeprom_write_bytes(address, 4, write_array); } else { eeprom_write_bytes(address, 4, write_array); } address = address + 4; } //clear supervisor password if(!error){ error = eeprom_write_bytes(EEPROM_SUPERVISOR_PW, 4, write_array); } else { eeprom_write_bytes(EEPROM_SUPERVISOR_PW, 4, write_array); } //log an occured error if(error){error_handler(EEPROM_ERROR, 0);} } /*----------------------------------------------------------------------------- // save_RAM_variables // -------------------- // Input: // Output: none // // This function saves periodicly the RAM-values. These values must be saved, so that they are present // after power off. // Date: 21.01.2016 // // Author: S.Weyeneth -------------------------------------------------------------------------------*/ void save_RAM_variables (void) { static int counter=0; int value; int i; static char xInit=0; unsigned char write_array[16]; //read the first time the clock. Otherwise it may save 0, what is not good! if (xInit == 0) { get_time(); xInit=1; } //save the values every 10 minutes to EEPROM if (!(counter % 600)) { //calculate every cycle the correct time, so that it saves the value, when the power is switched off //EEPROM_DATALOG_POINTER //save the value 4x i=0; while (i<16) { write_array[i+0] = g_log_data_pointer & 0xFF; write_array[i+1] = (g_log_data_pointer >> 8) & 0xFF; write_array[i+2] = (g_log_data_pointer >> 16) & 0xFF; write_array[i+3] = (g_log_data_pointer >> 24) & 0xFF; i=i+4; } eeprom_write_bytes(EEPROM_DATALOG_POINTER, 16, write_array); //EEPROM_ERROR_LOG_POINTER //save the value 4x i=0; while (i<16) { write_array[i+0] = g_error_log_data_pointer & 0xFF; write_array[i+1] = (g_error_log_data_pointer >> 8) & 0xFF; write_array[i+2] = (g_error_log_data_pointer >> 16) & 0xFF; write_array[i+3] = (g_error_log_data_pointer >> 24) & 0xFF; i=i+4; } eeprom_write_bytes(EEPROM_ERROR_LOG_POINTER, 16, write_array); //EEPROM_EXPIRY_COUNTER //save the value 4x i=0; while (i<16) { write_array[i+0] = giExpiryDateCounter & 0xFF; write_array[i+1] = (giExpiryDateCounter >> 8) & 0xFF; write_array[i+2] = (giExpiryDateCounter >> 16) & 0xFF; write_array[i+3] = (giExpiryDateCounter >> 24) & 0xFF; i=i+4; } eeprom_write_bytes(EEPROM_EXPIRY_COUNTER, 16, write_array); //EEPROM_OPERATION_HOURS //save the value 4x i=0; while (i<16) { write_array[i+0] = g_iOperatingHours & 0xFF; write_array[i+1] = (g_iOperatingHours >> 8) & 0xFF; write_array[i+2] = (g_iOperatingHours >> 16) & 0xFF; write_array[i+3] = (g_iOperatingHours >> 24) & 0xFF; i=i+4; } eeprom_write_bytes(EEPROM_OPERATION_HOURS, 16, write_array); //EEPROM_ABSOLUTE_TIME //save the value 4x i=0; value = (g_day_number_of_the_year - 1)*86400 + g_time_in_seconds; while (i<16) { write_array[i+0] = value & 0xFF; write_array[i+1] = (value >> 8) & 0xFF; write_array[i+2] = (value >> 16) & 0xFF; write_array[i+3] = (value >> 24) & 0xFF; i=i+4; } eeprom_write_bytes(EEPROM_ABSOLUTE_TIME, 16, write_array); } counter++; }