/****************************************************************************
Range Demo Plus - Receiver

 $Author: b06900 $
 $Date: 2008/03/05 22:49:11 $
 $Name:  $

****************************************************************************/

#include "timer.h"
#include <string.h>
#include <hidef.h> /* for EnableInterrupts macro */
#include "pub_def.h"
#include "APP_SMAC_API.h"
#include "freescale_radio_hardware.h"
#include "LCD.h"
#include "SCI.h"
#include "range_demo_plus_rx.h"
#if SMAC_FEATURE_OTAP == TRUE
#include "APP_OTAP_API.h"
#endif // SMAC_FEATURE_OTAP == TRUE
#if SMAC_FEATURE_SECURITY == TRUE
#include "APP_security_API.h"
#endif // SMAC_FEATURE_SECURITY == TRUE
#if (EMBEDDED_BOOTLOADER == TRUE)  
#include "bootloader user api.h"
#endif

#if SMAC_FEATURE_OTAP == TRUE
#include "APP_OTAP_API.h"
#endif // SMAC_FEATURE_OTAP == TRUE

#if SMAC_FEATURE_SECURITY == TRUE
#include "APP_security_API.h"
#endif // SMAC_FEATURE_SECURITY == TRUE

/* Global Variables */
UINT8 gu8RTxMode; /* needed for s-mac, application can read this variable */
                /* gu8RTxMode is the software state variable of the radio */
                /* This variable reflects the current state of MC13192 */
INT8 gi8AppStatus = 0;    /*State machine variable for the application    */
UINT8 gu8LedStatus = 0;    /*led status reflects which power setting should be set.  */
UINT8 link_quality;    /*Holds the link quality of the last received ZigBee Packet.*/
UINT32 pocet_good = 0; /* pocet dobrych packetov */
UINT32 pocet_bad = 0;   /* pocet zlych packetov */
UINT32 pocet_zprav = 0;
UINT32 kanal;
UINT32 vykon;
UINT8 tx_count = 0;

void AppInit(void);

static UINT8 gau8TxDataBuffer[20];
static UINT8 gau8RxDataBuffer[20];
static tTxPacket gsTxPacket;
static tRxPacket gsRxPacket;
UINT8 channel = 0;
UINT8 adjust= 10;
UINT32 cas_prenosu_ms;
UINT32 cas_prenosu_s;
UINT8 SaveRxBuffer[4];
char string_sci[10]; /* string*/
char string_sci2[50]; /* string*/

UINT32 crc_f(UINT32 sprava);
interrupt void IRQTimer1(void);

char string_buff[40];

extern UINT8 gu8SCIData[2];
extern UINT8 gu8SCIDataFlag;
    
void main(void) 
{
    
    
    
    UINT32 u32loop;
    UINT16 u16loop;
    UINT32 message, crc_b; 
    
    //EnableInterrupts; /* enable interrupts */
    /* include your code here */
    /* Init LED's */

    char string_buff[40];
    
    

        /*Initialize the packet.*/
    gsTxPacket.u8DataLength = 0;        /*Set TX default length to 0*/
    gsTxPacket.pu8Data = &gau8TxDataBuffer[0];    /*Load the address of our txbuffer into the tx structure*/
    gsRxPacket.u8DataLength = 0;        /*Set RX default length to 0*/
    gsRxPacket.pu8Data = &gau8RxDataBuffer[0];    /*Load the address of our rxbuffer into the rx structure*/
    gsRxPacket.u8MaxDataLength = 100;        /*Define the max buffer we are interested in.*/
    gsRxPacket.u8Status = 0;                    /*initial status variable for rx to 0.*/
    MCUInit();            /*Initialize the mcu, setup GPIOs, SPI, clock scheme, etc.*/
    RadioInit();
    AppInit();
    SCIInit();
    
    tim_init(); // nastavit TOF pro pravidelne vycitani dat

  	   



#if (EMBEDDED_BOOTLOADER == TRUE)
  boot_init(); /*Initialize the bootloader...in bootloader user api.c*/
#endif 
#if (EMBEDDED_BOOTLOADER == TRUE)
  boot_call();  /*Checks for user request for bootloader.
                 *Runs bootloader if requested.  Code will not return.
                 */
#endif 

    (void)MLMESetMC13192ClockRate(0);  /* Set initial Clk speed */
    UseExternalClock();    /* switch clock sources */
    
    
    /* include your start up code here */    


  EnableInterrupts; /* Turn on system interrupts */
  (void)MLMESetChannelRequest(channel);    /*Set channel to 0 (2.405GHz)  */
  /******************************************************************
  To adjust output power call the MLME_MC13192_PA_output_adjust() with:
  
  MAX_POWER     (+3 to +5dBm)
  NOMINAL_POWER (0 dBm)
  MIN_POWER     ~(-16dBm)
  
  or somewhere custom ? (0-15, 11 (NOMINAL_POWER) being Default power)

    ******************************************************************/
    (void)MLMEMC13192PAOutputAdjust(adjust);    /*Set MAX power setting*/
  //MLME_MC13192_PA_output_adjust(MIN_POWER);    /*Set MIN power setting*/
  //MLME_MC13192_PA_output_adjust(NOMINAL_POWER);    /*Set Nominal power setting*/


    #if(EMBEDDED_BOOTLOADER == TRUE)
      boot_call();  /*Checks for user request for bootloader.
                     *Runs bootloader if requested.  Code will not return.
                     */
  #endif 
    
    gi8AppStatus = INITIAL_STATE;
    
    
        
    /*Loop forever*/
    for (;;) {

        /* include your regular code here */
        switch (gi8AppStatus ) {
            case INITIAL_STATE:
                /*For RX*/
                LED1 = LED_ON;
                LED2 = LED_ON; 
                LED3 = LED_ON; 
                for (u32loop = 0; u32loop < LED_DELAY; u32loop++);

                LED1 = LED_OFF; 
                LED2 = LED_OFF; 
                LED3 = LED_OFF; 
                for (u32loop = 0; u32loop < LED_DELAY; u32loop++);

                LED1 = LED_ON; 
                LED2 = LED_ON; 
                LED3 = LED_ON; 
                for (u32loop = 0; u32loop < LED_DELAY; u32loop++);    

                LED1 = LED_OFF; 
                LED2 = LED_OFF; 
                LED3 = LED_OFF; 
                for (u32loop = 0; u32loop < LED_DELAY; u32loop++);
                
                channel = 0;
                adjust = 10;
                (void)MLMESetChannelRequest(channel);
                (void)MLMEMC13192PAOutputAdjust(adjust); /* 0 dB*/
                
                gi8AppStatus  = TX_STATE;    /*Since we are tx...Set TX_STATE*/
                break;
                                
            case TX_STATE:
                
                tx_count++;
                if (tx_count == 200){
                  tx_count = 0;
                  gi8AppStatus = INITIAL_STATE;
                  break;
                }
                  
                gau8TxDataBuffer[0] = 'G';
                
                
                gsTxPacket.u8DataLength = 1;    /*Set the data length of the packet.  in this case, 6.*/
                
                if (MCPSDataRequest(&gsTxPacket) == SUCCESS)    /*TX Packet, Blocking will stay here until the packet is in the air*/
                  LED1 ^=1; 
                
                gi8AppStatus = RX_STATE;
                
                break;  
                
            case RX_STATE:
                 
                
                MLMERXEnableRequest(&gsRxPacket,0xFF5); /*Zero means wait forever with RX ON.*/
                gi8AppStatus= WAITING_FOR_ACK;
                
                break;
           
            case WAITING_FOR_ACK:
            /* At this point only two things happen, 1-we receive the ack packet or 2-timeout.
             * Either way the RX will leave this state and continue. Low power mode could be placed here
             * because both 1 and 2 are interrupt driven, in this case we keep it simple 
             */
            break;
                
            case RESET_STATE:
                RadioInit();
                gi8AppStatus = INITIAL_STATE;
                break;
            
            case GOOD_PACKET:
                
                  gau8TxDataBuffer[0] = 'G';
                  
                
                  gsTxPacket.u8DataLength = 1; 
                                
                  if (MCPSDataRequest(&gsTxPacket) == SUCCESS)    /*TX Packet, Blocking will stay here until the packet is in the air*/
                    LED2 ^=1; 
                
                  gi8AppStatus= RX_STATE;
                
                break;
               
            case BAD_PACKET:
                
                gau8TxDataBuffer[0] = 'B';
                                    
                gsTxPacket.u8DataLength = 1; 
                                                  
                if (MCPSDataRequest(&gsTxPacket) == SUCCESS)    /*TX Packet, Blocking will stay here until the packet is in the air*/
                    LED3 ^=1; 
                
                 gi8AppStatus = RX_STATE;
                 
                  
                break;
               
            case TEST:
                                   
                  
                  message = 0;
		              message = SaveRxBuffer[0];
		              message <<= 8;
		              message |= SaveRxBuffer[1];
		              message <<=8;
		              message |= SaveRxBuffer[2];
		              message <<=8;
		              message |= SaveRxBuffer[3];
    
                  crc_b = crc_f(message);
    
                  if (crc_b == 0){
                    gi8AppStatus = GOOD_PACKET;
                    pocet_good++;
                    if (pocet_good == 1){
                      sys_time_ms = 0;
                      sys_time_s = 0;
                    }
                    
                  } else {
                    gi8AppStatus = BAD_PACKET;
                    pocet_bad++;
                  }
                  
                  pocet_zprav++;
                  
                  if (pocet_zprav == 2500){
                    gi8AppStatus = UART;
                    cas_prenosu_ms = sys_time_ms;
                    cas_prenosu_s = sys_time_s;
                  }
                  
                  SaveRxBuffer[0] = 0;
                  SaveRxBuffer[1] = 0;
                  SaveRxBuffer[2] = 0;
                  SaveRxBuffer[3] = 0; 
                  
                                
               
               break;
                           
            case UART:
                
                /*kanal = channel;
                (void)int2string(kanal, string_sci);
                trimWhiteSpace(string_sci);
                string_sci2[0] = '*';
                strcat(string_sci2,string_sci);
                strcat(string_sci2,"#");
                
                switch (adjust){
                  case 5:  
                    strcat(string_sci2,"-8,8"); 
                    strcat(string_sci2,"#");
                    break;
                  case 10: 
                    strcat(string_sci2,"0");    
                    strcat(string_sci2,"#");
                    break; 
                  case 15: 
                    strcat(string_sci2,"3,6");  
                    strcat(string_sci2,"#");
                    break;
                }
                
                link_quality = MLMELinkQuality();
                link_quality = link_quality/2; 
                (void)int2string((UINT32)link_quality, string_sci);
                trimWhiteSpace(string_sci);
                strcat(string_sci2,"-");
                strcat(string_sci2,string_sci); //musi byt zaporna hodnota
                strcat(string_sci2,"#");
                
                (void)int2string(pocet_zprav, string_sci);
                trimWhiteSpace(string_sci);
                strcat(string_sci2,string_sci);
                strcat(string_sci2,"#");
                pocet_zprav = 0; 
                
                (void)int2string(pocet_good, string_sci);
                trimWhiteSpace(string_sci);
                strcat(string_sci2,string_sci); 
                strcat(string_sci2,"#");
                pocet_good=0;
                
                (void)int2string(pocet_bad, string_sci);
                trimWhiteSpace(string_sci);
                strcat(string_sci2,string_sci);                                
                strcat(string_sci2,"#");
                pocet_bad=0;
                
                (void)int2string(cas_prenosu_s, string_sci);
                trimWhiteSpace(string_sci);
                strcat(string_sci,",");
                strcat(string_sci2,string_sci);
                (void)int2string(cas_prenosu_ms, string_sci);
                trimWhiteSpace(string_sci);
                strcat(string_sci2,string_sci);
                strcat(string_sci2,string_sci);
                strcat(string_sci2,"#");
                strcat(string_sci2,"@");
                SCITransmitStr(string_sci2); */
                
                kanal = channel;
                (void)int2string(kanal, string_sci);
                trimWhiteSpace(string_sci);
                SCITransmitStr("*");
                SCITransmitStr(string_sci);
                SCITransmitStr("#");
                
                switch (adjust){
                  case 5:  
                    SCITransmitStr("-8,8"); 
                    SCITransmitStr("#");
                    break;
                  case 10: 
                    SCITransmitStr("0");    
                    SCITransmitStr("#");
                    break; 
                  case 15: 
                    SCITransmitStr("3,6");  
                    SCITransmitStr("#");
                    break;
                }
                
                link_quality = MLMELinkQuality();
                link_quality = link_quality/2; 
                (void)int2string((UINT32)link_quality, string_sci);
                trimWhiteSpace(string_sci);
                SCITransmitStr("-");
                SCITransmitStr(string_sci); //musi byt zaporna hodnota
                SCITransmitStr("#");
                
                (void)int2string(pocet_zprav, string_sci);
                trimWhiteSpace(string_sci);
                SCITransmitStr(string_sci);
                SCITransmitStr("#");
                pocet_zprav = 0; 
                
                (void)int2string(pocet_good, string_sci);
                trimWhiteSpace(string_sci);
                SCITransmitStr(string_sci); 
                SCITransmitStr("#");
                pocet_good=0;
                
                (void)int2string(pocet_bad, string_sci);
                trimWhiteSpace(string_sci);
                SCITransmitStr(string_sci);                                
                SCITransmitStr("#");
                pocet_bad=0; 
                
                /*SCITransmitStr("Tx count: ");
                (void)int2string((UINT32)tx_count, string_sci);
                trimWhiteSpace(string_sci);
                SCITransmitStr(string_sci);
                SCITransmitStr("\r\n");*/
                
                (void)int2string(cas_prenosu_s, string_sci);
                trimWhiteSpace(string_sci);
                (void)int2string(cas_prenosu_ms, string_sci2);
                trimWhiteSpace(string_sci2);
                strcat(string_sci,",");
                strcat(string_sci,string_sci2);
                SCITransmitStr(string_sci);
                SCITransmitStr("#");
                SCITransmitStr("@"); 
                               
                gi8AppStatus = CHANNEL_SET; 
                
                break;
                
            case CHANNEL_SET:
              
              channel++;
              tx_count = 0;
              if (channel == 16){
                channel = 0;
                gi8AppStatus = ADJUST_SET;
                break;
              }
              
              gi8AppStatus = SEND_SET;  
              break;
             
            case ADJUST_SET:
              
              /* 5  ... -8,8 dB
               * 10 ...  0   dB
               * 15 ...  3,6 dB */
              
              switch (adjust){
                case 5:
                 gi8AppStatus = DELAY_STATE; 
                 break;
                
                case 10:
                  adjust = 15;
                  gi8AppStatus = SEND_SET;
                  break;
                
                case 15:
                  adjust = 5;
                  gi8AppStatus = SEND_SET;
                  break;
              }
                              
              break;
              
             case DELAY_STATE:
                  
                 
                 //SCITransmitStr("******* round *******");
                 
                  sys_time_ms = 0;
                  sys_time_s = 0;
                  while (sys_time_s < 60){  /*1 min*/
                  }
                  sys_time_ms = 0;
                  sys_time_s = 0;
                  while (sys_time_s < 60){  /*1 min*/
                  }
                  sys_time_ms = 0;
                  sys_time_s = 0;
                  while (sys_time_s < 60){  /*1 min*/
                  }
                  sys_time_ms = 0;
                  sys_time_s = 0;
                  while (sys_time_s < 60){  /*1 min*/
                  }
                  sys_time_ms = 0;
                  sys_time_s = 0;
                  while (sys_time_s < 60){  /*1 min*/
                  }
                  
                 gi8AppStatus = INITIAL_STATE;
                 
                 break;
                 
            case SEND_SET:
                
                 gau8TxDataBuffer[0] = 'S'; 
                 gau8TxDataBuffer[1] = channel;
                 gau8TxDataBuffer[2] = adjust;
                  
                  
                 gsTxPacket.u8DataLength = 3; 
                  
                 if (MCPSDataRequest(&gsTxPacket) == SUCCESS) /*TX Packet, Blocking will stay here until the packet is in the air*/
                   LED3 ^= 1;    
                 
                 (void)MLMESetChannelRequest(channel);
                 (void)MLMEMC13192PAOutputAdjust(adjust);   
                  
                 sys_time_ms = 0;
                 sys_time_s = 0;
                 while (sys_time_s < 2){  /* 2 s */
                 }
                                   
                 gi8AppStatus = TX_STATE;
            
            default:
                break;
        }
    }
}

void MCPSDataIndication(tRxPacket *gsRxPacket) {

    if (gsRxPacket->u8Status == TIMEOUT) {

        /* Put timeout condition code here */
     gi8AppStatus = TX_STATE;    /*Should not get here.*/

    }
    
   if (gsRxPacket->u8Status == SUCCESS) {   
    if (gsRxPacket->pu8Data[0] == 0 &&
        gsRxPacket->pu8Data[1] == 0 &&
        gsRxPacket->pu8Data[2] == 0 &&
        gsRxPacket->pu8Data[3] == 0 ){
      
        gi8AppStatus = TX_STATE;
      
        } else {
          
        SaveRxBuffer[0] = gsRxPacket->pu8Data[0];
        SaveRxBuffer[1] = gsRxPacket->pu8Data[1];
        SaveRxBuffer[2] = gsRxPacket->pu8Data[2];
        SaveRxBuffer[3] = gsRxPacket->pu8Data[3];
        gi8AppStatus = TEST;
        }
   }
    
    
}

void MLMEMC13192ResetIndication() {
    /* Notifies you that the MC13192 has been reset.
     * Application must handle this here.
     */
    gi8AppStatus = RESET_STATE;
}

void AppInit(void) {
  
  /* Init LED's */
    LED1 = 1; /* Default is off */
    LED2 = 1;
    LED3 = 1;
    LED4 = 1;

    LED1DIR = 1; /*Set the DDIR register as Outputs for the LED pins*/
    LED2DIR = 1;
    LED3DIR = 1;
    LED4DIR = 1;
    
    /*Pull up the pushbuttons.*/
    PB0PU = 1;
    PB1PU = 1;
    PB2PU = 1;
    PB3PU = 1;
    
  #if SMAC_FEATURE_OTAP == TRUE
  if (PB0 == 0){
    KBI1SC = 0x00; /* Turn On Interrupts */
    OTAPActivate();
  }
  #endif // SMAC_FEATURE_OTAP == TRUE    
}


/********************************
 *                              *
 *funkcia pre tvorenie crc kodu:*
 *                              *
 ********************************/


UINT32 crc_f(UINT32 sprava){
	UINT32 gp=0xC6800000, crc; /*11000110100000000000000000000000*/
	UINT8 i;
	
	crc = sprava;
	for (i=0; i<24; i++){
		if (crc & 0x80000000){
			crc ^= gp;
			
		}
		crc <<=1;
	}
	crc >>=24;
	return crc;					 
}


