void sns_power_Process(void)
{
	if (StoreInEEPROM == 1)
	{
		StoreInEEPROM = 0;
		
		eeprom_write_word_crc(EEDATA16.EnergyCounterUpper, (uint16_t)((EnergyCounter>>16) & 0xffff), WITHOUT_CRC);
		eeprom_write_word_crc(EEDATA16.EnergyCounterLower, (uint16_t)(EnergyCounter & 0xffff), WITH_CRC);
	#ifdef POWER_SNS_PIN_ch2
		eeprom_write_word_crc(EEDATA16.EnergyCounterUpper_ch2, (uint16_t)((EnergyCounter_ch2>>16) & 0xffff), WITHOUT_CRC);
		eeprom_write_word_crc(EEDATA16.EnergyCounterLower_ch2, (uint16_t)(EnergyCounter_ch2 & 0xffff), WITH_CRC);
	#endif
	}
void act_linearAct_Init(void)
{
#if act_linearAct_USEEEPROM==1
	if (EEDATA_OK)
	{
	  ///TODO: Use stored data to set initial values for the module
	  pulses = eeprom_read_word(EEDATA16.pulses_ee);
	  min = eeprom_read_word(EEDATA16.min_ee);
	  low = eeprom_read_word(EEDATA16.low_ee);
	  high = eeprom_read_word(EEDATA16.high_ee);
	  max = eeprom_read_word(EEDATA16.max_ee);
	} else
	{	//The CRC of the EEPROM is not correct, store default values and update CRC
	  eeprom_write_word_crc(EEDATA16.pulses_ee, 1200, WITHOUT_CRC);
	  eeprom_write_word_crc(EEDATA16.min_ee, 300, WITHOUT_CRC);
	  eeprom_write_word_crc(EEDATA16.low_ee, 815, WITHOUT_CRC);
	  eeprom_write_word_crc(EEDATA16.high_ee, 5600, WITHOUT_CRC);
	  eeprom_write_word_crc(EEDATA16.max_ee, 6100, WITHOUT_CRC);
	  EEDATA_UPDATE_CRC;
	}
#else	
	// Only for testing/debugging...
	pulses = 1200;
	min = 300;
	low = 815;
	high = 5600;
	max = 6100;
#endif
	
	// PD5 (EXP_G) is used as Timer1 input. Hardwired, no move possible!
	gpio_set_in(EXP_G);
	gpio_set_pullup(EXP_G);
	
	//PORTD &= ~(_BV(DIR_RELAY) | _BV(ON_RELAY));
	gpio_clr_pin(RELAY_ON);
	gpio_clr_pin(RELAY_DIR);
	
	// initiera utgångar 
	//DDRD = (_BV(DIR_RELAY) | _BV(ON_RELAY));
	gpio_set_out(RELAY_ON);
	gpio_set_out(RELAY_DIR);

	// Start report timer
	Timer_SetTimeout(act_linearAct_TIMER_report, act_linearAct_ReportInterval*1000 , TimerTypeFreeRunning, 0);
#if (USE_STIMULI == 1)	
	// Set stimuli as an output
	gpio_set_out(STIMULI);
	Timer_SetTimeout(act_linearAct_TIMER_stimuli, 10, TimerTypeFreeRunning,0);
#endif
}
void linearAct_cleanUp (uint8_t dummy) {
	if (stopfactor) {
		stopfactor = 0;
		// Add number of pulses
		if (direction == UP) {
			pulses += TCNT1;		// adjust official counter
			// keep track on how far beyond target we have moved
			if (TCNT1 > OCR1A) latest_stop_pulses_up = (uint8_t) TCNT1 - OCR1A;
			else latest_stop_pulses_up = 0;
		}
		else {
			pulses -= TCNT1;
			// keep track on how far beyond target we have moved
			if (TCNT1 > OCR1A) latest_stop_pulses_down = (uint8_t) TCNT1 - OCR1A;
			else latest_stop_pulses_down = 0;
		}
		TCCR1B = 0;	
		TCNT1 = 0;							// reset counter before next run
		direction = 0;
		eeprom_write_word_crc(EEDATA16.pulses_ee, pulses, WITH_CRC);
		//printf("In linearAct_cleanUp\n");
		Timer_SetTimeout(act_linearAct_TIMER_report, act_linearAct_ReportInterval*1000 , TimerTypeFreeRunning, 0);
		linearAct_sendPosition(0);
	}
}
void sns_VoltageCurrent_Init(void)
{
#ifdef sns_VoltageCurrent_USEEEPROM
	if (EEDATA_OK)
	{
	  ///TODO: Use stored data to set initial values for the module
	  blablaX = eeprom_read_byte(EEDATA.x);
	  blablaY = eeprom_read_word(EEDATA.y);
	} else
	{	//The CRC of the EEPROM is not correct, store default values and update CRC
	  eeprom_write_byte_crc(EEDATA.x, 0xAB, WITHOUT_CRC);
	  eeprom_write_word_crc(EEDATA.y, 0x1234, WITHOUT_CRC);
	  EEDATA_UPDATE_CRC;
	}
#endif  

	// to use PCINt lib, call this function: (the callback function look as a timer callback function)
	// Pcint_SetCallbackPin(sns_VoltageCurrent_PCINT, EXP_C , &sns_VoltageCurrent_pcint_callback);

	ADC_Init();
#ifdef sns_VoltageCurrent_SEND_PERIOD
	Timer_SetTimeout(sns_VoltageCurrent_TIMER, sns_VoltageCurrent_SEND_PERIOD*1000 , TimerTypeFreeRunning, 0);
#else
#ifdef sns_VoltageCurrent_SEND_PERIOD_MS
	Timer_SetTimeout(sns_VoltageCurrent_TIMER, sns_VoltageCurrent_SEND_PERIOD_MS , TimerTypeFreeRunning, 0);
#endif
#endif
	

}
void sns_power_Init(void)
{
#ifdef sns_power_USEEEPROM
	if (EEDATA_OK)
	{
	  ///TODO: Use stored data to set initial values for the module
	  sns_power_ReportInterval = eeprom_read_byte(EEDATA.reportInterval);
	  EnergyCounter = eeprom_read_word(EEDATA16.EnergyCounterLower);
	  EnergyCounter += (((uint32_t)(eeprom_read_word(EEDATA16.EnergyCounterUpper)))<<16);
	    #ifdef POWER_SNS_PIN_ch2
	      EnergyCounter_ch2 = eeprom_read_word(EEDATA16.EnergyCounterLower_ch2);
	      EnergyCounter_ch2 += (((uint32_t)(eeprom_read_word(EEDATA16.EnergyCounterUpper_ch2)))<<16);
	    #endif
	} else
	{	//The CRC of the EEPROM is not correct, store default values and update CRC
	  eeprom_write_byte_crc(EEDATA.reportInterval, sns_power_SEND_PERIOD, WITHOUT_CRC);
	  eeprom_write_word_crc(EEDATA16.EnergyCounterUpper, 0, WITHOUT_CRC);
	  eeprom_write_word_crc(EEDATA16.EnergyCounterLower, 0, WITHOUT_CRC);
	  #ifdef POWER_SNS_PIN_ch2
	    eeprom_write_word_crc(EEDATA16.EnergyCounterUpper_ch2, 0, WITHOUT_CRC);
	    eeprom_write_word_crc(EEDATA16.EnergyCounterLower_ch2, 0, WITHOUT_CRC);
	  #endif
	  EEDATA_UPDATE_CRC;
	  sns_power_ReportInterval = eeprom_read_byte(EEDATA.reportInterval);
	}
#endif  
	///Initialize hardware etc
	gpio_set_in(POWER_SNS_PIN);	// Set to input
	gpio_set_pin(POWER_SNS_PIN);	// Enable pull-up
	
	Pcint_SetCallbackPin(sns_power_PCINT, POWER_SNS_PIN, &sns_power_pcint_callback);

	MeasurmentBufferPointer = 0;
#ifdef POWER_SNS_PIN_ch2
	gpio_set_in(POWER_SNS_PIN_ch2);	// Set to input
	gpio_set_pin(POWER_SNS_PIN_ch2);	// Enable pull-up
	
	Pcint_SetCallbackPin(sns_power_PCINT_ch2, POWER_SNS_PIN_ch2, &sns_power_pcint_callback_ch2);

	MeasurmentBufferPointer_ch2 = 0;
#endif
	Timer_SetTimeout(sns_power_SEND_TIMER, sns_power_ReportInterval*1000 , TimerTypeFreeRunning, 0);
#if sns_power_SEND_1_MIN_AVG == 1
	Timer_SetTimeout(sns_power_SEND_TIMER_1_MIN_AVG, 60000-10 , TimerTypeFreeRunning, &sns_power_timer_callback);
#endif
}
void chn_ChnMaster_Init(void)
{
#ifdef chn_ChnMaster_USEEEPROM
    if (EEDATA_OK)
    {
      ///TODO: Use stored data to set initial values for the module
      blablaX = eeprom_read_byte(EEDATA.x);
      blablaY = eeprom_read_word(EEDATA.y);
    } else
    {    //The CRC of the EEPROM is not correct, store default values and update CRC
      eeprom_write_byte_crc(EEDATA.x, 0xAB, WITHOUT_CRC);
      eeprom_write_word_crc(EEDATA.y, 0x1234, WITHOUT_CRC);
      EEDATA_UPDATE_CRC;
    }
#endif  
    ///TODO: Initialize hardware etc here

    // to use PCINt lib, call this function: (the callback function look as a timer callback function)
    // Pcint_SetCallbackPin(chn_ChnMaster_PCINT, EXP_C , &chn_ChnMaster_pcint_callback);

}
void act_linearAct_HandleMessage(StdCan_Msg_t *rxMsg)
{
	uint16_t i;
	
	if (	StdCan_Ret_class(rxMsg->Header) == CAN_MODULE_CLASS_ACT && 
		StdCan_Ret_direction(rxMsg->Header) == DIRECTIONFLAG_TO_OWNER &&		  
		rxMsg->Header.ModuleType == CAN_MODULE_TYPE_ACT_LINEARACT && 
		rxMsg->Header.ModuleId == act_linearAct_ID)
	{
		switch (rxMsg->Header.Command) {
		case CAN_MODULE_CMD_GLOBAL_REPORT_INTERVAL:
			act_linearAct_ReportInterval = rxMsg->Data[0];
			Timer_SetTimeout(act_linearAct_TIMER_report, act_linearAct_ReportInterval*1000 , TimerTypeFreeRunning, 0);
			break;
		case CAN_MODULE_CMD_LINEARACT_POSITION:
			if (rxMsg->Length >= 3) {		// remain forward compatible by allowing longer messages, but not shorter
				if (rxMsg->Data[2] != 0) {
					Timer_SetTimeout(act_linearAct_TIMER_report, 750 , TimerTypeFreeRunning, 0);
					linearAct_setPosition(((uint16_t)rxMsg->Data[0] << 8) + rxMsg->Data[1]);
				} else {	// Data[2] signals moving speed, where zero stands for stop and also triggers transmission of limits
					linearAct_stop();
					// wait until complete stop (with timeout)
					i = 0;
					do {
						if (direction == 0) break;
						_delay_ms(10);
						i++;	
					} while (i < 200);
					
					linearAct_sendPosition(0);
					linearAct_sendLimits(0);
				}
			}
			break;
		case CAN_MODULE_CMD_LINEARACT_LIMITS:
			if (rxMsg->Length == 8) {
			
				min = (rxMsg->Data[0] << 8) + rxMsg->Data[1];		
				low = (rxMsg->Data[2] << 8) + rxMsg->Data[3];
				high = (rxMsg->Data[4] << 8) + rxMsg->Data[5];
				max = (rxMsg->Data[6] << 8) + rxMsg->Data[7];
			
				// pulses are already saved. eeprom_write_word_crc(EEDATA16.pulses_ee, 1200, WITHOUT_CRC);
	  			eeprom_write_word_crc(EEDATA16.min_ee, min, WITHOUT_CRC);
	  			eeprom_write_word_crc(EEDATA16.low_ee, low, WITHOUT_CRC);
	  			eeprom_write_word_crc(EEDATA16.high_ee, high, WITHOUT_CRC);
	  			eeprom_write_word_crc(EEDATA16.max_ee, max, WITHOUT_CRC);
	  			EEDATA_UPDATE_CRC;			
				
			}
			break;
		case CAN_MODULE_CMD_LINEARACT_CALIBRATION:		// set limits to absolute maximum to allow full movement
		   min = 0;
		   low = 0;
		   high = 0xFFFF;
		   max = 0xFFFF;
		   if (rxMsg->Length >= 2) {		// optional: set start position. Note! This will definitly ruin the old calibration.
		   	pulses = (rxMsg->Data[0] << 8) + rxMsg->Data[1];
		   }
		   break;
		default:
		   break;
		}
	} 
}