/***************************************
Project : almy
Version : 3.1
Date    : 10 Dec 2007
Company : Max-Planck-Institut for Physics 
Comments: 

Author  : Varuzhan Danielyan              

Chip type        : ADuc7020
***************************************/
#include "defs.h"

//#define _ExcelTest_
#ifdef  _ExcelTest_
#include <stdlib.h>
#endif

const WORD Version = 3;

int IamSelected;

#define InStrLen 24
char InStr[InStrLen + 1];
char *SPtr;

static int GetInt(void)
{
  int result;
  BYTE neg;
  
  result = 0;
  neg = 0;
  if (*SPtr == '-') {
    neg = 1;
    SPtr++;
  }
  else if (*SPtr == '+')
    SPtr++;
  while (isdigit(*SPtr))
    result = 10*result + (*SPtr++ - '0');
  return neg ? -result : result;
}

static void GetStringEcho(char *str, BYTE len)
{
  BYTE cpos;
  char ch;

  for(cpos = 0; cpos < len;) {
    ch = toupper(getchar());
    switch (ch) {
    case ESC :
      cpos = 0;
    case '\r' :
      goto gsout;
    case '\b' :
      if (cpos > 0)
        cpos--;
      putchar(ch);
    break;
    default :
      str[cpos++] = ch;
      putchar(ch);
    }
  }
gsout:
  str[cpos] = 0;
  rprintf("\n");
}

static void GetString(char *str, BYTE len)
{
  BYTE cpos;
  char ch;

  for(cpos = 0; cpos < len;) {
    ch = toupper(getchar());
    switch (ch) {
    case ESC :
      cpos = 0;
    case '\r' :
      goto gsout;
    case '\b' :
      if (cpos > 0)
        cpos--;
    break;
    default :
      str[cpos++] = ch;
    }
  }
gsout:
  str[cpos] = 0;
}

DWORD Error;

DWORD MyAddress;

//BYTE ResetSource;
DWORD ErrorCode;
#define BadCommand 1

//#define _echo_
//#define _Standalone_

static void InitController(void)
{
  GP0DAT = 0xF0000000;		//	Configure P0.4 - P0.7 as output
  GP1DAT = 0xF0000000;		//	Configure P1.4 - P1.7 as output
  GP4DAT = 0x04000000;		// LED output
  GP4DAT |= 0x00040000;		// Switch off LED  
  T1CON = 0x180;
}

int main(void)
{
  char ch;
  WORD w;
  BYTE i;

//Start:  

  InitController();
  InitADC();
  InitSerial();

  MyAddress = 1;//ReadEEPROM_WORD(aMyAddress);

#ifdef _ExcelTest_
  while (1) {
    switch (rand() & 3) {
	case 0:
	  rprintf("99\r");
	break;
	case 1:
	  rprintf("101\r");
	break;
	default:
	  rprintf("100\r");
	}
	delay(2000);
  }
#endif

  delay(10000);

//  ChDel = ReadEEPROM_WORD(aChDel);
//  Averaging = ReadEEPROM_WORD(aAveraging);

//Unselect:
  IamSelected = 0;

#ifdef _Standalone_
  rprintf("Started\n");
#endif

#ifdef _echo_
  while (1) {
    ch = getchar();
    putchar(ch);
  }
#endif

  while (1) {
//    FeedWatchdog();
    if (IamSelected) {
      ch = toupper(getchar());
      switch (ch) {
      case 'S' :
        goto Select;
      case 'M' :
        goto Measure;
      case 'Z' :
//	    IOCLR0 = Bit(21);
		while(1);
//	    IODIR0 |= Bit(21);
//        goto Start; 
      case 'R' :      
        putchar(ch);
        for (i = 0; i < 64; i++) {
          rprintf("%u %u\n", xs[i], ys[i]);
        }       
        continue;
      }
      putchar(ch);
      GetStringEcho(InStr, InStrLen);
      SPtr = InStr;
      switch (ch) {
      case 'A' :		// Set Averaging value
        w = GetInt();
        if (w && (w != Averaging)) {
          Averaging = w;
        }
        rprintf("A%u\n", Averaging);
      break;
      case 'D' :		// Set Delay value
        w = GetInt();
        if (w && (w != ChDel)) {
          ChDel = w;
        }
        rprintf("D%u\n", ChDel);
      break;       
      case 'L' :
        DumpXY();
      break;
      case 'Z' :		// Reset microcontroller
//	    IOCLR0 = Bit(21);
//	    IODIR0 |= Bit(21);
//        goto Start;
        while(1);		// WDT to be added !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!  
      case 'V' :		// Read firmware version
        w = Version;
        if (*SPtr == 0)
          rprintf("V%u\n", w);
      break;
      default :
        ErrorCode = BadCommand;
        putchar('?');
      }
    }
    else {
      ch = toupper(getchar());
      switch (ch) {
      // Should be called only when single sensor is connected to the RS485 line!
      case 'I' :
        GetString(InStr, InStrLen);
        SPtr = InStr;
        if (*SPtr++ == 'D') {
          if (*SPtr++ == 'N') {
//            w = GetInt();
//            if (w) {
//              MyAddress = w;
//			  WriteEEPROM_WORD(aMyAddress, MyAddress);
//            }
//            else
//              MyAddress = ReadEEPROM_WORD(aMyAddress);
            rprintf("IDN%u\n", MyAddress);
          }
        }
      break;
      case 'M' :
Measure:
        ScanXY();
      break; 
      case 'S' :				// address Select
Select:
        GetString(InStr, InStrLen);
        SPtr = InStr;
        w = GetInt();
        if (w == MyAddress) {
          IamSelected = 1;
          rprintf("S%u\n", w);            
        }
        else
          IamSelected = 0;
      break;
      case 'Z' :
		while(1);
      default :
        Error |= BadCommand; 
      }
    }
  }    
}

