/*
* XIOHV5.12 power sequence
* Copyright (C) 2012 Avencall
* Authors:
* Jean Marc Ouvrard
* Noe Rubinstein
* Guillaume Knispel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#include
#include
#include
#include "def.h"
#include "hardware.h"
static void InitPorts(void);
static void GlobalInit(void);
volatile u16 Timer1;
volatile u16 SW1State;
volatile u16 SW2State;
#ifdef CAN_WAIT_TENSION
//has to be coded on real board
volatile u8 bV1P0 = true;
volatile u8 bV1P2 = true;
volatile u8 bV1P8_DDR = true;
volatile u8 bV2P5 = true;
volatile u8 bVCC3 = true;
#define TENSION_EXPIRED (SW1State || Timer1 == 0)
#define TENSION_WAIT(t) (t)
#else
#define TENSION_EXPIRED (SW1State)
#define TENSION_WAIT(t) (Timer1 == 0)
#endif
#define STOP 10
#define WAIT_START 20
#define WAIT_ATX_OK 30
#define WAIT_V1P0 40
#define WAIT_V1P2 50
#define WAIT_V1P8 60
#define WAIT_RSMRST 70
#define CK410_VTT_GD 80
#define CPU_RUN 90
#define WAIT_STOP 100
int main(void)
{
u16 state;
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer to prevent time out reset
__disable_interrupt();
InitPorts();
GlobalInit();
__enable_interrupt();
state = WAIT_START;
while (1) {
switch (state) {
case WAIT_START:
if (SW1State > 30) // SW1 pressed for at least 30ms
state = WAIT_START + 1;
break;
case WAIT_START + 1: // wait for release SW1 before real Start
if (SW1State == 0) {
SetBit(P4OUT, CMDPWR); // Start Atx Power Supply
Timer1 = 2000;
state = WAIT_ATX_OK;
}
break;
case WAIT_ATX_OK:
if (TENSION_EXPIRED)
state = STOP; // if SW1 just pressed during power or ATX didn't set up
// ATX power OK, stop
if ((P4IN & ATX_PWROK) && TENSION_WAIT(bV2P5 && bVCC3)) {
// atx power Ok & V2P5 Ok
SetBit(P1DIR, V1P2_CORE_EN_N); // enable V1P2 (V1P2_CORE_EN_N go from
// Hz to Out Low)
Timer1 = 30; // set Timer1 @ 30 milli seconde to get V1P2 stable
state = WAIT_V1P2;
}
break;
case WAIT_V1P2:
if (TENSION_EXPIRED)
state = STOP;
if (TENSION_WAIT(bV1P2)) { // Got V1P2 stable
Timer1 = 30; // set Timer1 @ 30 milli seconde to get V1P8-DDR stable
SetBit(P4OUT, V1P8_CMD); // enable V1P8-DDR
state = WAIT_RSMRST;
}
break;
case WAIT_RSMRST:
if (SW1State)
state = STOP;
if (Timer1 < 20) {
SetBit(P2DIR, IMCH_RSMRST_N);
ClrBit(P2OUT, IMCH_RSMRST_N);
state = WAIT_V1P8;
}
break;
case WAIT_V1P8:
if (TENSION_EXPIRED)
state = STOP;
if (TENSION_WAIT(bV1P8)) {
ClrBit(P2OUT, CPU_VCCP_EN_N); // enable V1P0
Timer1 = 30; // set Timer1 @ 30 milli seconde to get V1P0 stable
state = WAIT_V1P0;
}
break;
case WAIT_V1P0:
if (TENSION_EXPIRED)
state = STOP;
if (TENSION_WAIT(bV1P0)) { // Got V1P0 stable and all other supplies too
SetBit(P3OUT, VRMPWRGD);
ClrBit(P2OUT, GREEN_LED_N); // set GREEN_LED_N to show Power Seq Ok
Timer1 = 3; // set Timer1 @ 3ms instead of 2 before assserted
// CK410_PWR_GD_N Low
state = CK410_VTT_GD;
}
break;
case CK410_VTT_GD:
if (Timer1 == 0) {
SetBit(P2DIR, CK410_PWR_GD_N); // asssert CK410_PWR_GD_N As output
ClrBit(P2OUT, CK410_PWR_GD_N); // asssert CK410_PWR_GD_N Low
Timer1 = 300; // set Timer1 @ 300 ms before starting Tolapai
state = CPU_RUN;
}
break;
case CPU_RUN:
if (SW1State) // if SW1 just pressed during power up go STOP
state = STOP;
if (Timer1 == 0) {
SetBit(P2DIR, IMCH_PWRBTN_N); // Start Tolapai
Timer1 = 200; // pour relācher le bouton comme un humain
state = CPU_RUN + 1;
}
break;
case CPU_RUN + 1:
if (SW1State != 0) // if SW1 just pressed during power up go STOP
state = STOP;
if (Timer1 == 0) {
ClrBit(P2DIR, IMCH_PWRBTN_N); // Release IMCH-PWRBTN-N signal after 200
// milli-secondes
state = WAIT_STOP;
}
break;
case WAIT_STOP:
if (SW1State >= 6000) // Sw1 button press for more than 6 secondes
state = STOP;
break;
case STOP:
InitPorts();
Timer1 = 10000; // set Timer1 @ 10s before any other Power up
ClrBit(P2OUT, RED_LED_N); // To show no restart is possible for now
state = STOP + 1;
break;
case STOP + 1:
InitPorts();
if (Timer1 == 0) {
SetBit(P2OUT, RED_LED_N); // To show restart is possible now
state = WAIT_START;
}
break;
}
}
}
#pragma vector = TIMERA1_VECTOR
__interrupt void Timer_A(void)
{
if (!(P1IN & START_SW1_N))
SW1State++;
else
SW1State = 0;
if (!(P1IN & RST_SW2_N))
SW2State++;
else
SW2State = 0;
if (Timer1)
Timer1--;
}
static void InitPorts(void)
{
/* DIR: direction: 0 input 1 output
* SEL: function: 0 gpio
* REN: resistor enabled
* OUT: output when REN=0 and DIR=1
* 0 pull-down 1 pull-up if REN=1
* IES: Interrupt Edge Select
* IE: Interrupt Enable
*/
P1DIR = P1DIR_INIT;
P1SEL = P1SEL_INIT;
P1REN = P1REN_INIT;
P1OUT = P1OUT_INIT;
P1IES = P1IES_INIT;
P1IE = P1IE_INIT;
P2OUT = P2OUT_INIT;
P2SEL = P2SEL_INIT;
P2REN = P2REN_INIT;
P2DIR = P2DIR_INIT;
P2IES = P2IES_INIT;
P2IE = P2IE_INIT;
P3OUT = P3OUT_INIT;
P3SEL = P3SEL_INIT;
P3DIR = P3DIR_INIT;
P4OUT = P4OUT_INIT;
P4SEL = P4SEL_INIT;
P4DIR = P4DIR_INIT;
P4REN = P4REN_INIT;
}
static void GlobalInit(void)
{
DCOCTL = CALDCO_12MHZ;
BCSCTL1 = CALBC1_12MHZ;
BCSCTL2 |= DIVS_3; // DIVS_3 => 1/8; SMCLK = 12/8 = 1.5Mhz
// Set timer A so that Timer_A is called every 1.00266 ms (nominal)
TACTL = TASSEL_2 + ID_3 + TACLR + TAIE + MC_1; // SMCLK + divise 8 + reset +
// enable intterupt + UP
// 188/187500.0 = 0.001002666666666666
TACCR0 = 188;
}