/*
 * heaters.c
 *
 *  Created on: Mar 11, 2012
 *      Author: qwer1
 */

#include "heaters.h"
#include "process.h"
#include "pid.h"

U8 heaters_pwm_set[T_TC_NUM];
U8 heaters_pwm_cnt;

void setup_heaters(void) {
	GPIO_InitTypeDef GPIO_InitStructure;

	// initialize GPIO
	GPIO_StructInit(&GPIO_InitStructure);

	//heaters ON/OFF
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_8;
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	//heaters enable
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_1 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12;
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);

	//switch off all heaters
	heaters_set(0);

	//start heaters control thread
	ptx_add( pt_heaters, NULL, PTX_FLAG_RUN | PTX_FLAG_SYNC_1MS);
}

//check if heater N enabled
U8 heater_enabled(U8 n) {
	U8 all_en = *BITP(&GPIOA->IDR, 7);
	U8 en = 0;
	switch (n) {
		case 0:
			en = *BITP(&GPIOB->IDR, 11);
			break;
		case 1:
			en = *BITP(&GPIOB->IDR, 12);
			break;
		case 2:
			en = *BITP(&GPIOB->IDR, 1);
			break;
		case 3:
			en = *BITP(&GPIOB->IDR, 10);
			break;
	}
	return all_en && en;
}

void heater_set(U8 n, U8 state) {
	state = state && heater_enabled(n);
	switch ( n ) {
		case 0:
			*BITP(&GPIOB->ODR, 15) = state;
			break;
		case 1:
			*BITP(&GPIOA->ODR, 8) = state;
			break;
		case 2:
			*BITP(&GPIOB->ODR, 13) = state;
			break;
		case 3:
			*BITP(&GPIOB->ODR, 14) = state;
			break;
	}
}

void heaters_set(U8 state) {
	for (U8 i=0; i<HEATERS; i++)
		heater_set(i, state);
}

PT_THREAD( pt_heaters( struct pt *pt, struct ptx *ptx ) ) {
	PT_BEGIN(pt);
	while (1) {
		//in STOP/PAUSE mode switch off all heaters
		if ((!process.run)||(process.pause)) {
			heaters_set(0);
			heaters_pwm_cnt = 0;
		} else {
			for (U8 i=0; i<T_TC_NUM; i++) {
				//calculate current set value
				if (heaters_pwm_cnt == 0)
					heaters_pwm_set[i] = (pids[i].out - pids[i].out_min) *
						HEATERS_PWM_TICKS / (pids[i].out_max - pids[i].out_min);
				//update heater OUT port
				if (heaters_pwm_cnt < heaters_pwm_set[i]) heater_set(i, 1);
				else heater_set(i, 0);
			}
			heaters_pwm_cnt++;
			if (heaters_pwm_cnt >= HEATERS_PWM_TICKS)
				heaters_pwm_cnt = 0;
		}
		PT_YIELD(pt);
	}
	PT_END(pt);
}

