/*
 * VERSION 1.0 Januar 7th 2010 LATE  File: 'one_wire_temperature.c'
 * Author: Linda Fouedjio  based on Michael Traxler based and Giacomo Ortona's hadtempsens
 * modified (heavily rather rebuild): Peter Zumbruch
 */
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <util/delay.h>
#include <avr/pgmspace.h>

#include <avr/io.h>
/*
 * VERSION 1.0 Januar 7th 2010 LATE  File: 'adc.c'
 * Author: Linda Fouedjio  based  Giacomo Ortona
 * modified (heavily rather rebuild): Peter Zumbruch
 */
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/iocan128.h>

#include "api.h"
#include "api_define.h"
#include "api_global.h"
#include "can.h"
#include "led.h"
#include "mem-check.h"
#include "adc.h"

#include "one_wire_adc.h"
#include "one_wire_dualSwitch.h"
#include "one_wire_temperature.h"
#include "read_write_register.h"

#include "OWIDeviceSpecific.h"
#include "OWIHighLevelFunctions.h"
#include "OWIBitFunctions.h"

#define ADC_CYCLES 3 /*the number of ADC conversions done to get an average voltage value*/
#define ADC_TIMEOUT 1000 /*wait ADC_TIMEOUT clock cycles for a single ADC conversion*/


/*this function takes the value of the voltage read from the ADC-channel
 * and convert it in the form of the API
 * as input parameters the function needs a keyword and the number of channel
 * the function has no return parameter
 */

void read_ADC( struct uartStruct *ptr_uartStruct )
{
	for ( uint8_t i = 0 ; i <= 1 ; i++ )
	{
		_delay_ms(10);
	}

    int8_t res = eNoError;

    switch (ptr_uartStruct->Uart_Message_ID)
    {
       case 0:
       case 1:
       case 2:
       case 3:
          res = GetVoltage(ptr_uartStruct->Uart_Message_ID);
          if ( res != eNoError )
          {
             snprintf_P(uart_message_string, BUFFER_SIZE - 1,
                        PSTR("ERRG error in GetVoltage(%i)"), ptr_uartStruct->Uart_Message_ID);
                         UART0_Send_Message_String(NULL,0);
          }
          switch (ptr_uartStruct->Uart_Message_ID)
          {
             case 0:
                res0 = res;
             case 1:
                res1 = res;
             case 2:
                res2 = res;
             case 3:
                res3 = res;
                snprintf_P(uart_message_string, BUFFER_SIZE - 1,
                           PSTR("RECV %d voltage of channel %i"),
                           Voltages[ptr_uartStruct->Uart_Message_ID],
                           ptr_uartStruct->Uart_Message_ID);
                UART0_Send_Message_String(NULL,0);
          }
          break;
       default:
          general_errorCode = CommunicationError(ERRG, GENERAL_ERROR_channel_undefined, 0, NULL, 0);
          break;
    }

	_delay_ms(100);

}//END of read_ADC function

/*this function reads and converts the voltage of the ADC-4 channels
 * as input parameters the function needs number of channel to read a voltage
 * the value returned is the voltage read from the channel
 */

int8_t GetVoltage( unsigned int channel_nr )
{

   uint16_t Timeout;
   uint16_t Value;
   uint16_t iStep;
   int16_t TotalValue;

#ifndef DISABLE_JTAG
   /* we need the JTAG interface, thus do not measure
    *the upper four ADC channels (used for JTAG, too)
    */
   if ( channel_nr > 3 )
   {
      Voltages[channel_nr] = 0;
      return eNoError;
   }
#endif

   /*use 3.3V supply voltage as reference voltage
    * and select the voltage to be measured*/
   ADMUX = 0x40 | (unsigned char) channel_nr;
   /*ADMUX = 0x40 | 0x1B;*/

   TotalValue = 0;
   for ( iStep = 0; iStep < ADC_CYCLES ; iStep++ )
   {
      /* start a new single conversion*/
      ADCSRA |= BIT (ADSC);

      /* wait until conversion is complete*/
      Timeout = ADC_TIMEOUT;
      while ( !( ADCSRA & BIT (ADIF) ) && ( --Timeout > 0 ) )
         ;

      /* clear interrupt flag from former conversion*/
      ADCSRA |= BIT (ADIF);

      if ( Timeout == 0 )
      {
         return eADCTimeout;
      }

      /*one must read ADCL before ADCH!*/
      Value = ADCL;
      Value |= (unsigned int) ( ADCH & 0x03 ) << 8;
      TotalValue += Value;
   }

   TotalValue = TotalValue / ADC_CYCLES;

   /*save results*/
   Voltages[channel_nr] = (uint16_t) TotalValue;

   return eNoError;
}// END of GetVoltage function
