/**
 * power_control.c
 *
 * Enables / disabled power supplies, sequencing turn-on and turn-off, and reset pins for some of the onboard chips.
 * 
 * Copyright (c) 2022 Bigscreen, Inc.
 */

#include <stdbool.h>
#include "asf.h"
#include "displayboard.h"
#include "power_control.h"


// Applies power sequencing and reset for the VXR7200
// According to product training slides from Synaptics:
// - Power up 3.3V before 1.0V (delay >= 0ms, so it could be simultaneous)
// - Reset released >=10ms after 1.0V stable
// - I2C control allowed >= 250ms after reset released
void VXR_Power_Control_On(void) {
	
	// Since this is a reset, let's power down for a moment
	// It could have been previously powered up
	// If this is the first power up, then setting reset and 1.0V enable false will have no effect
	// and that's perfectly fine.
	ioport_set_pin_level(PIN_DDIC_RST, false); // Active low, "false" asserts reset
	vTaskDelay(DDIC_RESET_DELAY_MS);
	ioport_set_pin_level(PIN_EN_1V, false);
	vTaskDelay(DDIC_RESET_DELAY_MS);
	
	// And power back up
	ioport_set_pin_level(PIN_EN_1V, true);
	vTaskDelay(DDIC_RESET_DELAY_MS);
	ioport_set_pin_level(PIN_DDIC_RST, true);
}

void Panel_Power_Control(bool t) {
	if(true == t) {
		// SY103 power up timing:
		// VDDI (1.8V) applied first
		// then AVDD (+6.3V) applied next after a minimum 1ms delay
		// then AVEE (-4.5V) applied after a minimum 2ms delay
		// then minimum 1ms delay before reset is de-asserted
		
		// Apply panel power
		// Reset asserted throughout power application
		ioport_set_pin_level(PIN_OLED_RESX, false); // Active low, "false" = reset asserted
		// 1.8V is applied first
		ioport_set_pin_level(PIN_EN_1V8, true);
		// Then, 1ms delay before AVDD (6.3V)
		vTaskDelay(POWER_SEQUENCE_DELAY_MS);
		ioport_set_pin_level(PIN_EN_VOLEDp, true);
		// And 2ms delay before AVEE (-4.5V)
		vTaskDelay(2*POWER_SEQUENCE_DELAY_MS);
		ioport_set_pin_level(PIN_EN_VOLEDn, true);
		vTaskDelay(POWER_SEQUENCE_DELAY_MS);
		
		// Reset is controlled by the VXR7200 GPIO4/GPIO7 outputs
		
	} else {
		// Disable panel power
		// Can't disable 1.8V without powering down the prox sensor, so this is the best we got
		// Just turn off the +6.3V and -4.5V supplies
		
		// Apply reset first - will keep it asserted as long as power is disabled
		ioport_set_pin_level(PIN_OLED_RESX, false);
		vTaskDelay(POWER_SEQUENCE_DELAY_MS); // 1ms delay after reset asserted to AVEE off
		ioport_set_pin_level(PIN_EN_VOLEDn, false);
		vTaskDelay(2*POWER_SEQUENCE_DELAY_MS); // 2ms delay between AVEE off and AVDD off
		ioport_set_pin_level(PIN_EN_VOLEDp, false);
	}
}


void Panel_Reset(void) {
	ioport_set_pin_level(PIN_OLED_RESX, false);
	vTaskDelay(OLED_RESET_DELAY_MS);
	ioport_set_pin_level(PIN_OLED_RESX, true);
	vTaskDelay(OLED_RESET_DELAY_MS);
}

void Power_Safe_Shutdown(void) {
	// Disables all power supplies in the correct order, with reset pins applied where applicable
	ioport_set_pin_level(PIN_DDIC_RST, false); // Reset the VXR
	Panel_Power_Control(false); // Reset the OLEDs and shut down +6.3V and -4.5V
	vTaskDelay(POWER_SEQUENCE_DELAY_MS);
	ioport_set_pin_level(PIN_EN_1V8, false);
	ioport_set_pin_level(PIN_EN_1V, false);
	
}