/*
 * PeipherialFunctions.c
 *
 * Created: 28.8.2015 20:53:31
 *  Author: Chenda
 */ 	

#include <avr/io.h>
#include <stdint.h>

#include "../conf/conf_brd.h"
#include "PeipherialFunctions.h"
#include <util/delay.h>

#include <avr/wdt.h>

/************************************************************************/
/* private functions                                                    */
/************************************************************************/
void wdt_init(void) __attribute__((naked)) __attribute__((section(".init3")));		// disabling wdt even before main() func start after reset necessary to prevent continous reseting



uint16_t UART_CalculateBaudRate(uint32_t BaudRate)		// TESTED - OK
{
	uint32_t uiTmp;
	uiTmp = F_CPU/BaudRate;
	uiTmp = uiTmp/16;
	uiTmp -= 1;
	return (uint16_t) uiTmp;
}

uint16_t TWI_CalculateBitRate(uint16_t SCL_freq)
{
	/*
	*					CPU clock frequency
	*	SCL frequency = ------------------------
	*					16 + 2 * TWBR * 4^TWPS
	*	TWPS (Prescaler) {0=1,1=4,2=16,3=64}
	*/
	uint32_t uiTmp;
	uiTmp = F_CPU/SCL_freq;
	uiTmp -= 16;
	uiTmp /= 2;
	if ((uiTmp / 64) > 0) {
		uiTmp /= 64;
		uiTmp |= (3<<8);
	}
	else if ((uiTmp / 16) > 0) {
		uiTmp /= 16;
		uiTmp |= (2<<8);
	}
	else if ((uiTmp / 4) > 0) {
		uiTmp /= 4;
		uiTmp |= (1<<8);
	}
	return (uint16_t) uiTmp;
}

// TODO - expand to support more prescalers
uint16_t TIMER_CalculateValue(uint16_t time_ms)			// TESTED - OK
{
	// only for CTC or Normal mode and defined prescaler
	/*
	*				       F_CPU * T
	*		OCRnA = (-------------------) - 1
	*				     2 * N * 1000
	* N - prescaler	supported only 64
	* T - time period in [ms]
	*/
	uint32_t uiTmp;
	uint16_t uiPrescaler = 64;
	uiTmp = F_CPU / 2;
	uiTmp = uiTmp / uiPrescaler;
	uiTmp = uiTmp * time_ms;
	uiTmp = uiTmp / 1000;
	uiTmp = uiTmp - 1;
	return (uint16_t)uiTmp;
}


void BlinkLed(uint8_t BlinkCounts)			// TESTED - OK
{
	
	while (BlinkCounts-- > 0) {
		mStatusLed_On();
		_delay_ms(300);	
		mStatusLed_Off();
		_delay_ms(300);
	}
	_delay_ms(300);
}


// Watch dog - for reset purpose
void wdt_init(void)
{
	MCUSR = 0;
	wdt_disable();
	return;
}

void soft_reset(void)
{
	//mStatusLed_On();
	do {                           
		wdt_enable(WDTO_15MS);  
		for(;;) {                       
		}                       
	} while(0);
}