
// XBee wireless connection
#include "config.h"
#include <stdio.h>
#include <string.h>

#define BUF_SIZE 10000
void UsbToSerialTask( void* p );
void DataMonitorTask( void* p );
void BlinkTask( void* p );

void Run( ) // this task gets called as soon as we boot up.
{
  Usb_SetActive( 1 );
  TaskCreate( UsbToSerialTask, "USB-Ser", BUF_SIZE + 1200, 0, 3 );
}

#define START 0
#define RESET 1
#define DATA_0 2
#define DATA_1 3
#define DATA_2 4
#define DATA_3 5

void UsbToSerialTask( void *p)
{
  (void)p;
  char readBuf[BUF_SIZE];
  char currentAtCmd[50];
  char *atP = currentAtCmd;

  int available, read;
  Serial_SetActive( true );
  Io_Start(IO_PA03, 0);
  Io_PioEnable(IO_PA03);
  Io_SetPullup(IO_PA03, 0);
  Io_SetOutput(IO_PA03);
  Io_SetValue(IO_PA03, 1); // RTS
  Io_SetPullup(IO_PA00, 1); // pull up the RX line

  int state = START;

  while( 1 )
  {
    Serial_ClearErrors( );
    available = Serial_GetReadable( );
    if( available )
    {
      read = Serial_Read( (uchar*)readBuf, available, 0 );
      switch( state )
      {
        case RESET:
          if( *readBuf == 0x0D )
          { // we received an OK after the reset command
            Serial_SetBaud( 38400 );
            Serial_StartBreak( );
            Sleep( 2000 );
            Serial_StopBreak( );
            state = DATA_0;
          }
          break;
        case DATA_1:
          if( *readBuf == 'U' )
            state = DATA_2;
          else
            state = DATA_0;
          break;
        case DATA_3:
          if( *readBuf == 'U' )
          {
            Serial_SetBaud( 9600 );
            state = START;
          }
          else
            state = DATA_0;
          break;
      }
      Usb_Write( (char*)readBuf, read );
    }
    read = Usb_Read( (char*)readBuf, BUF_SIZE );
    if( read )
    {
      int i;
      char* readP = readBuf;
      for( i = 0; i < read; i++ )
      {
        switch( state )
        {
          case START:
          {
            if( *readP == 0x0D ) // linefeed, end of an AT cmd
            {
              *atP = 0;
              if( 0 == strcmp( currentAtCmd, "ATFR" ) )
                state = RESET; // we received a reset command
              atP = currentAtCmd; // reset
            }
            else
              *atP++ = *readP;
            readP++;
            break;
          }
          case DATA_0:
          {
            if( *readP++ == 'F' )
              state = DATA_1;
            break;
          }
          case DATA_2:
          {
            if( *readP++ == 'C' )
              state = DATA_3;
            else
              state = DATA_0;
            break;
          }
        }
      }
      Serial_Write( (uchar*)readBuf, read, 3000 );
    }
  }
}

