


/* Copyright (c) 2009 Atmel Corporation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * 3. The name of Atmel may not be used to endorse or promote products derived
 * from this software without specific prior written permission.
 *
 * 4. This software may only be redistributed and used in connection with an Atmel
 * AVR product.
 *
 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
 *
 */



#include "compiler.h"
#include "gpio.h"
#include "board.h"
#include "intc.h"
#include "pwm.h"
#include "tc.h"
#include "pm.h"
#include "adc.h"
#include "rtc.h"
#include "project_motor.h"

#define ADC_MOTOR_CURRENT_CHANNEL   0
#define ADC_MOTOR_CURRENT_PIN       AVR32_ADC_AD_0_PIN		//Pin PC05 on STK600, connect to pin 1 on L298N
#define ADC_MOTOR_CURRENT_FUNCTION  AVR32_ADC_AD_0_FUNCTION

#define ADC_TEMP_SENSOR_CHANNEL   	1
#define ADC_TEMP_SENSOR_PIN       	AVR32_ADC_AD_1_PIN		//Pin PC06 on STK600, connect to pin 2 on temp sensor
#define ADC_TEMP_SENSOR_FUNCTION  	AVR32_ADC_AD_1_FUNCTION

const double adc_resolution = 3.3;				//ADC uses 3.3V as reference and is only 10-bit (1024)
const double current_sense_res = 1.380;



/*
 *
 * Convert Celsius to Fahrenheit
 *
 */
int cel2Fahr(double celsius){

	int fahr = celsius*(1.8) + 32;

	return fahr;

}



/*
 * Important notes
 * - Remove the jumper for AREF0 in the blue zone
 * - Provide the AREF0 pin on the STK600 with 3.3V with 1.0uF and 10nF bypass capacitors
 * - Connect ground of the STK600 with ground of power supply
 * - 10 bit ADC, return value range from 0 - 1023
 *
 */
signed short readADC(unsigned int ADC_CHANNEL, unsigned int ADC_PIN, unsigned int ADC_FUNCTION){

	  // GPIO pin/adc-function map.
	  const gpio_map_t ADC_GPIO_MAP = {ADC_PIN, ADC_FUNCTION};

	  volatile avr32_adc_t *adc = &AVR32_ADC;

	  signed short adc_value = -1;

	  unsigned short adc_channel = ADC_CHANNEL;

	  // switch to oscillator 0
	  pm_switch_to_osc0(&AVR32_PM, FOSC0, OSC0_STARTUP);


	  // Assign and enable GPIO pins to the ADC function.
	  gpio_enable_module(ADC_GPIO_MAP, sizeof(ADC_GPIO_MAP) / sizeof(ADC_GPIO_MAP[0]));

	  // configure ADC
	  // Lower the ADC clock to match the ADC characteristics (because we configured
	  // the CPU clock to 20MHz, and the ADC clock characteristics are usually lower;
	  // cf. the ADC Characteristic section in the datasheet).
	  AVR32_ADC.mr |= 0x1 << AVR32_ADC_MR_PRESCAL_OFFSET;
	  adc_configure(adc);

	  adc_enable(adc,adc_channel);

	  int ready = 0;

	  adc_start(adc);

	  //Wait until the conversion is completed
	  while(ready == 0){

		  if(adc_check_eoc(adc, adc_channel) == 1){
			  ready = 1;
		  }

	  }

	  adc_value = adc_get_value(adc, adc_channel);

	  adc_disable(adc,adc_channel);

	  return adc_value;
}



/*
 *
 * Read temperature from temp sensor
 *
 */
int readTemp(void){

	//These parameters will need to be confirmed by testing with using the STK600
	const double temp_sensor_bias = 424;//452.8;			// at zero degrees celsius, temp sensor outputs 424mV
	const double temp_sensor_slope = 6.42;//5.125;		// rate of 6.25mV/celsius


	signed short adc_value = readADC(ADC_TEMP_SENSOR_CHANNEL, ADC_TEMP_SENSOR_PIN, ADC_TEMP_SENSOR_FUNCTION);

	double temp_sensor_volt = (adc_value*adc_resolution);

	double temp_celsius = (temp_sensor_volt - temp_sensor_bias)/temp_sensor_slope;

	int temp_fahr = cel2Fahr(temp_celsius);

	return temp_fahr;

}

int readCurrent(void){

	signed short adc_value = readADC(ADC_MOTOR_CURRENT_CHANNEL, ADC_MOTOR_CURRENT_PIN, ADC_MOTOR_CURRENT_FUNCTION);


	int motor_current = ((adc_resolution*adc_value)/current_sense_res);

	return motor_current;

}


