summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'main.c')
-rw-r--r--main.c183
1 files changed, 156 insertions, 27 deletions
diff --git a/main.c b/main.c
index b3842d3..106079d 100644
--- a/main.c
+++ b/main.c
@@ -21,6 +21,7 @@
*/
#include <stdbool.h>
+#include <string.h>
#include <io430.h>
#include <intrinsics.h>
@@ -29,45 +30,149 @@
#include "hardware.h"
static void InitPorts(void);
+
static void GlobalInit(void);
volatile u16 Timer1;
volatile u16 SW1State;
volatile u16 SW2State;
+enum state {
+ STOP = 10,
+ WAIT_VREF = 15,
+ WAIT_START = 20,
+ WAIT_ATX_OK = 30,
+ WAIT_V1P0 = 40,
+ WAIT_V1P2 = 50,
+ WAIT_V1P8 = 60,
+ WAIT_RSMRST = 70,
+ CK410_VTT_GD = 80,
+ CPU_RUN = 90,
+ WAIT_STOP = 100,
+};
+
+static u16 state;
+
#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;
+static void InitADC10(void);
+static void start_conversion(void);
+static void get_conversion_result(void);
+
+# define TENSION_EXPIRED (Timer1 == 0)
+# define TENSION_WAIT(t) (tension_ok[t])
+
+enum tensions {
+ VCC3,
+ V1P8_PGOOD,
+ V1P0,
+ V1P2,
+ V1P8_DDR,
+ V2P5,
+ TEMP,
+ TENSIONS_NUM
+};
+
+static const u16 inch[] = {
+ [VCC3] = INCH_5,
+ [V1P8_PGOOD] = INCH_6,
+ [V1P0] = INCH_12,
+ [V1P2] = INCH_13,
+ [V1P8_DDR] = INCH_14,
+ [V2P5] = INCH_15,
+ [TEMP] = INCH_10,
+};
+
+static unsigned cidx;
+static bool tension_ok[TENSIONS_NUM];
+
+# ifdef MONITOR_TENSIONS
+
+static bool monitoring[TENSIONS_NUM];
+
+# define init_monitoring() memset(monitoring, 0, sizeof(monitoring))
+# define start_monitoring(t) (monitoring[t] = true)
+# define check_tension(t, min, max) \
+ case t: \
+ tension_ok[t] = ADC10MEM < min || ADC10MEM > max; \
+ if (monitoring[t] && !tension_ok[t]) \
+ state = STOP; \
+ break;
+
+# else
+
+# define init_monitoring()
+# define start_monitoring(t)
+# define check_tension(t, min, max) \
+ case t: \
+ tension_ok[t] = ADC10MEM < min || ADC10MEM > max; \
+ break;
+
+# endif
+
+static void InitADC10(void)
+{
+ // Ports are already initiated with correct values
-#define TENSION_EXPIRED (Timer1 == 0)
-#define TENSION_WAIT(t) (t)
+ // ADC10SHT <- what kind of conversion time do we need?
-#else
+ ADC10CTL0 = SREF_1 | ADC10SHT_2 | REFON | REF2_5V | ADC10ON | ADC10IE;
+ // wait 30ms here
-#define TENSION_EXPIRED (0)
-#define TENSION_WAIT(t) (Timer1 == 0)
+ ADC10AE0 = BIT5 | BIT6;
+ ADC10AE1 = BIT4 | BIT5 | BIT6 | BIT7; // A12 A13 A14 A15
+}
+
+static void start_conversion(void)
+{
+ ADC10CTL1 = ADC10CTL1 & ~INCH_15 | inch[cidx];
+ ADC10CTL0 |= ENC | ADC10SC;
+}
+
+static void get_conversion_result(void)
+{
+ switch (cidx) {
+ /* See the ADC10 notes and InfosPowerSeq.ods for these values */
+#ifdef BRIDGE_5_PERCENT
+ check_tension(V1P0 , 180, 233)
+ check_tension(V1P2 , 209, 288)
+ check_tension(V1P8_DDR, 314, 432)
+ check_tension(V2P5 , 435, 600)
+ check_tension(VCC3 , 575, 792)
+#else
+ check_tension(V1P0 , 187, 224)
+ check_tension(V1P2 , 218, 277)
+ check_tension(V1P8_DDR, 327, 415)
+ check_tension(V2P5 , 454, 577)
+ check_tension(VCC3 , 599, 762)
#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
+ case V1P8_PGOOD:
+ tension_ok[V1P8_PGOOD] = ADC10MEM > 368;
+ break;
+ case TEMP:
+ break;
+ }
+
+ cidx = (cidx + 1) % ARRAY_SIZE(inch);
+}
+
+#else
+
+# define InitADC10()
+# define start_conversion()
+# define get_conversion_result()
+# define init_monitoring()
+# define start_monitoring(t)
+
+# define TENSION_EXPIRED (0)
+# define TENSION_WAIT(t) (Timer1 == 0)
+
+#endif
int main(void)
{
- u16 state;
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer to prevent time out reset
@@ -75,12 +180,21 @@ int main(void)
InitPorts();
GlobalInit();
+ InitADC10();
__enable_interrupt();
- state = WAIT_START;
+ Timer1 = 30; // to allow Vref to settle
+ state = WAIT_VREF;
while (1) {
switch (state) {
+ case WAIT_VREF:
+ if (Timer1 == 0) {
+ start_conversion();
+ state = WAIT_START;
+ }
+ break;
+
case WAIT_START:
if (SW1State > 30)
state = WAIT_START + 1;
@@ -96,7 +210,9 @@ int main(void)
case WAIT_ATX_OK:
if (SW1State || TENSION_EXPIRED)
state = STOP;
- if ((P4IN & ATX_PWROK) && TENSION_WAIT(bV2P5 && bVCC3)) {
+ if ((P4IN & ATX_PWROK) && TENSION_WAIT(V2P5) && TENSION_WAIT(VCC3)) {
+ start_monitoring(V2P5);
+ start_monitoring(VCC3);
ClrBit(P1OUT, V1P2_CORE_EN_N);
Timer1 = 30;
state = WAIT_V1P2;
@@ -106,7 +222,8 @@ int main(void)
case WAIT_V1P2:
if (SW1State || TENSION_EXPIRED)
state = STOP;
- if (TENSION_WAIT(bV1P2)) {
+ if (TENSION_WAIT(V1P2)) {
+ start_monitoring(V1P2);
Timer1 = 30;
SetBit(P4OUT, V1P8_CMD);
state = WAIT_RSMRST;
@@ -126,7 +243,9 @@ int main(void)
case WAIT_V1P8:
if (SW1State || TENSION_EXPIRED)
state = STOP;
- if (TENSION_WAIT(bV1P8)) {
+ if (TENSION_WAIT(V1P8_DDR) && TENSION_WAIT(V1P8_PGOOD)) {
+ start_monitoring(V1P8_DDR);
+ start_monitoring(V1P8_PGOOD);
ClrBit(P2OUT, CPU_VCCP_EN_N);
Timer1 = 30;
state = WAIT_V1P0;
@@ -136,7 +255,8 @@ int main(void)
case WAIT_V1P0:
if (SW1State || TENSION_EXPIRED)
state = STOP;
- if (TENSION_WAIT(bV1P0)) {
+ if (TENSION_WAIT(V1P0)) {
+ start_monitoring(V1P0);
SetBit(P3OUT, VRMPWRGD);
ClrBit(P2OUT, GREEN_LED_N);
Timer1 = 3;
@@ -253,6 +373,13 @@ static void InitPorts(void)
}
+#pragma vector=ADC10_VECTOR
+__interrupt void ADC10_ISR(void)
+{
+ get_conversion_result();
+ start_conversion();
+}
+
static void GlobalInit(void)
{
DCOCTL = CALDCO_12MHZ;
@@ -266,3 +393,5 @@ static void GlobalInit(void)
// 188/187500.0 = 0.001002666666666666
TACCR0 = 188;
}
+
+// vim: et:sw=2:sts=2