#include "main.h"

#case

#define  REVERS      2     // 2*256 ms = 0,5 s
#define  GO          117   // 117*256 ms = 30 s
#define  GO_ZALUZIE  5     // 5*256 ms = 1,25 s

#define S105A  PIN_A0
#define R110AU PIN_A1
#define R110AD PIN_A2
#define S104A  PIN_A3
#define R104AU PIN_A4
#define R104AD PIN_A5
#define R104BU PIN_A6
#define R104BD PIN_A7

#define S103A  PIN_B0
#define R103AU PIN_B1
#define R103AD PIN_B2
#define S106A  PIN_B3
#define S107A  PIN_B4
#define S109A  PIN_B5

//#define OS101 PIN_C0 
//#define OS105B PIN_C1  
//#define OS105C PIN_C2 
//#define PIN_C3  31763
//#define PIN_C4  31764
//#define PIN_C5  31765

//#define PIN_C6  31766 //TX
//#define PIN_C7  31767 //RX

#define S101A PIN_D0
#define S105D PIN_D1  
#define S102A PIN_D2
#define S110C PIN_D3
#define S108A PIN_D4
#define S201A PIN_D5
#define S110B PIN_D6

/*
#define PIN_E0  31776
#define PIN_E1  31777
#define PIN_E2  31778
#define PIN_E3  31779
#define PIN_E4  31780
#define PIN_E5  31781
#define PIN_E6  31782
#define PIN_E7  31783

#define PIN_F0  31784
#define PIN_F1  31785
#define PIN_F2  31786
#define PIN_F3  31787
#define PIN_F4  31788
#define PIN_F5  31789
#define PIN_F6  31790
#define PIN_F7  31791

#define PIN_G0  31792
#define PIN_G1  31793
#define PIN_G2  31794
#define PIN_G3  31795
#define PIN_G4  31796
#define PIN_G5  31797

#define PIN_H0  31800
#define PIN_H1  31801
#define PIN_H2  31802
#define PIN_H3  31803
#define PIN_H4  31804
#define PIN_H5  31805
#define PIN_H6  31806
#define PIN_H7  31807

#define PIN_J0  31808
#define PIN_J1  31809
#define PIN_J2  31810
#define PIN_J3  31811
#define PIN_J4  31812
#define PIN_J5  31813
#define PIN_J6  31814
#define PIN_J7  31815
*/

#bit CREN = 0xFAB.4      // USART enable register

#define LED1 PIN_J7
#define LED2 PIN_J6 

#define ON(port)  output_low(port);
#define OFF(port) output_high(port);

typedef enum {GO_UP, GO_DOWN, REVERS_UP, REVERS_DOWN, STOP} state;

state r103A, r110A, r104A, r104B;      // Stavy rolet
int8 tr103A, tr110A, tr104A, tr104B;   // Casovace rolet

#int_TIMER0
void  TIMER0_isr(void) 
{
   if(tr103A>0) tr103A--;
   if(tr110A>0) tr110A--;
   if(tr104A>0) tr104A--;
   if(tr104B>0) tr104B--;
output_toggle(LED2);
}

void up(state *status, int8 *timer) // Zmena stavu rolety smer nahoru
{
   switch (*status)
   {
      case STOP:
      case GO_DOWN:
         *status=REVERS_UP;
         *timer=REVERS;
         break;
      case REVERS_UP:
      case GO_UP:
         *status=STOP;
         *timer=0;
         break;
   }
}

void down(state *status, int8 *timer) // Zmena stavu rolety smer dolu
{
   switch (*status)
   {
      case STOP:
      case GO_UP:
         *status=REVERS_DOWN;
         *timer=REVERS;
         break;
      case REVERS_DOWN:
      case GO_DOWN:
         *status=STOP;
         *timer=0;
         break;
   }
}

#define run(x) {                                \
   switch(r##x)                                 \
   {                                            \
      case STOP:                                \
         OFF(R##x##U);                          \
         OFF(R##x##D);                          \
         break;                                 \
      case GO_UP:                               \
         ON(R##x##U);                           \
         OFF(R##x##D);                          \
         if(tr##x==0) {r##x=STOP;}              \
         break;                                 \
      case GO_DOWN:                             \
         OFF(R##x##U);                          \
         ON(R##x##D);                           \
         if(tr##x==0) {r##x=STOP;}              \
         break;                                 \
      case REVERS_UP:                           \
         OFF(R##x##U);                          \
         OFF(R##x##D);                          \
         if(tr##x==0) {r##x=GO_UP; tr##x=GO;}   \
         break;                                 \
      case REVERS_DOWN:                         \
         OFF(R##x##U);                          \
         OFF(R##x##D);                          \
         if(tr##x==0) {r##x=GO_DOWN; tr##x=GO;} \
         break;                                 \
   }                                            \
}      

void main()
{
   char c;
   
   if(restart_cause()!= WDT_TIMEOUT)
   {
      setup_adc_ports(NO_ANALOGS|VSS_VDD);
      setup_adc(ADC_CLOCK_DIV_2);
      setup_psp(PSP_DISABLED);
      setup_spi(SPI_SS_DISABLED);
      setup_wdt(WDT_ON);
      setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
      setup_timer_1(T1_DISABLED);
      setup_timer_2(T2_DISABLED,0,1);
      setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
      setup_ccp1(CCP_OFF);
      setup_comparator(NC_NC_NC_NC);
      setup_vref(FALSE);
   
      OFF(S105A);    // Vsechno zhasni a zastav
      OFF(R110AU);
      OFF(R110AD);
      OFF(S104A);
      OFF(R104AU);
      OFF(R104AD);
      OFF(R104BU);
      OFF(R104BD);
      OFF(S103A);
      OFF(R103AU);
      OFF(R103AD);
      OFF(S106A);
      OFF(S107A);
      OFF(S109A);
      OFF(S101A);
      OFF(S105D);  
      OFF(S102A);
      OFF(S110C);
      OFF(S108A);
      OFF(S201A);
      OFF(S110B);

      r103A=STOP;    // Rolety jsou zastaveny
      r110A=STOP;
      r104A=STOP;
      r104B=STOP;  

      enable_interrupts(INT_TIMER0);
      enable_interrupts(GLOBAL);
   }
   
   CREN=0; CREN=1;               // Reinitialise USART
   
   while(TRUE)
   {
      if(kbhit())
      {
         c=getc();
         if(c=='S')
         {
            if(getc()=='1')
            {
               switch(getc())
               {
                  case '1':
                     output_toggle(S101A);
                     break;
                  case '2':
                     output_toggle(S102A);
                     break;
                  case '3':
                     output_toggle(S103A);
                     break;
                  case '4':
                     output_toggle(S104A);
                     break;
                  case '5':
                     c=getc();
                     if(c=='A') {output_toggle(S105A);}
                     if(c=='D') {output_toggle(S105D);}
                     break;
                  case '6':
                     output_toggle(S106A);
                     break;
                  case '7':
                     output_toggle(S107A);
                     break;
                  case '8':
                     output_toggle(S108A);
                     break;
                  case '9':
                     output_toggle(S109A);
                     break;
                  case 'a':
                     output_toggle(S110B);
                     output_toggle(S110C);
                     break;
               }
            }
         }
         
         if(c=='R')
         {
            if(getc()=='1')
            {
               switch(getc())
               {
                  case '3':
                     getc();  // A
                     if((getc()=='U')) {up(&r103A,&tr103A);} else {down(&r103A,&tr103A);}
                     break;
                  case '4':
                     c=getc();
                     if(c=='A') if((getc()=='U')) {up(&r104A,&tr104A);} else {down(&r104A,&tr104A);}
                     if(c=='B') if((getc()=='U')) {up(&r104B,&tr104B);} else {down(&r104B,&tr104B);}
                     break;
                  case 'a':
                     getc();  // A
                     if((getc()=='U')) {up(&r110A,&tr110A);} else {down(&r110A,&tr110A);}
                     break;
               }
            }
         }

         output_toggle(LED1);  // Prijmuli jsme cely prikaz
      }
      else
      {
         run(103A);
         run(104A);
         run(104B);

         switch(r110A)                                 
         {                                            
            case STOP:                                
               OFF(R110AU);                          
               OFF(R110AD);                          
               break;
            case GO_UP:                               
               ON(R110AU);                           
               OFF(R110AD);                          
               if(tr110A==0) {r110A=STOP;}              
               break;                                 
            case GO_DOWN:                             
               OFF(R110AU);                          
               ON(R110AD);                           
               if(tr110A==0) {r110A=STOP;}              
               break;                                 
            case REVERS_UP:                           
               OFF(R110AU);                          
               OFF(R110AD);                          
               if(tr110A==0) {r110A=GO_UP; tr110A=GO_ZALUZIE;}   
               break;                                 
            case REVERS_DOWN:                         
               OFF(R110AU);                          
               OFF(R110AD);                          
               if(tr110A==0) {r110A=GO_DOWN; tr110A=GO_ZALUZIE;} 
               break;                             
         }                                                    
/*
switch(r110A)
{
   case GO_UP:
      printf("U");
      break;
   case GO_DOWN:
      printf("D");
      break;
   case REVERS_UP:
      printf("R");
      break;
   case REVERS_DOWN:
      printf("E");
      break;
   case STOP:
      printf("S");
      break;     
}
*/
         restart_wdt();
      }
   }
}