/************************************************************************************
* Main file for physical layer in ZigBee.
* Handle initialization, etc.
*
* Author(s): Thomas O. Jensen
*
* (c) Copyright 2004, Freescale, Inc.  All rights reserved.
*
* Freescale Confidential Proprietary
* Digianswer Confidential
*
* No part of this document must be reproduced in any form - including copied,
* transcribed, printed or by any electronic means - without specific written
* permission from Freescale.
************************************************************************************/
#include "DigiType.h"
#include "Target.h"
#include "MacPhy.h"
#include "Phy.h"
#include "NV_Data.h"

#ifdef PLATFORM_WINDOWS
#include "client.h"
#include "HAL.h"
#endif

// **************************************************************************
// Define strings to remove warnings when building
#define VER   " V"
#define BUILD " Build: "
#define SPACE " " 
// **************************************************************************
// Normally it should be enough to change the version numbers.
#if gAspJapanTelecCapability_d
#define PHY_Version_No		"1063T"
#else
#define PHY_Version_No		"1063"
#endif // gAspJapanTelecCapability_d

#pragma PLACE_CONST_SEG(BOOTLOADER_PHY_NV_DATA0)

// DO NOT CHANGE OR REMOVE

// This string will be located in the NV RAM0 section.
// Note!! Check that item is location in the sequence as specified. 
const uint8_t PHY_Version[47] = "PHY " PHY_TYPE VER PHY_Version_No BUILD __DATE__ SPACE __TIME__;

#pragma RESTORE_CONST_SEG

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

void (*mpfPendingSetup)(void);

void (*gpTimer2Isr)(void);

void DummyFastIsr(void)
{
  ;
}

#ifdef RX_TIMING_MEASUREMENT
uint8_t *testString="xxxxxxxxxxx*Testing!*";
rxPacket_t gTestData;
extern void InitRxPointers(void);
extern void InitRxFastAction(void);
#endif

void InitializePhy(void)
{
  mPhyTxRxState = cIdle;
  gpTimer2Isr = IsrTx2prime;

  gIsrFastAction = DummyFastIsr;
  gIsrAsyncTailFunction = DummyFastIsr;
  gIsrSuperFastAction = NULL;
  gIsrEntryCounter = 0;

  mpfPendingSetup = NULL;

  gCurrentPALevel = (NV_RAM_ptr->PA_Level & 0xFF);

#ifdef RX_TIMING_MEASUREMENT
  // Generate dummy packet (10bytes excl header) to check rx filter
  gpPhyRxData = &gTestData;
  {
    uint8_t dummy = (uint8_t) memcpy(&gTestData,&testString,sizeof(testString));
  }
  // Generate dummy header (9 bytes)
  gpPhyRxData->frameLength = 0x13; // PhyLength
  gpPhyRxData->linkQuality = 0xFF; // LQ
  gpPhyRxData->rxData[0]=0x41; // frmCtrl: intra PAN, data
  gpPhyRxData->rxData[1]=0x88; // frmCtrl: src, dst both 16 bit addr
  gpPhyRxData->rxData[2]=42;   // seqn
  gpPhyRxData->rxData[3]=0x12; // dst PAN Id (same as src PAN Id here)
  gpPhyRxData->rxData[4]=0x34;  
  gpPhyRxData->rxData[5]=0xAA; // dst addr
  gpPhyRxData->rxData[6]=0xAA;
  gpPhyRxData->rxData[7]=0xBB; // src addr
  gpPhyRxData->rxData[8]=0xBB;

// Worst Case Packet
/*
  gpPhyRxData->frameLength = 0x13; // PhyLength
  gpPhyRxData->linkQuality = 0xFF; // LQ
  gpPhyRxData->rxData[0]=0x41; // frmCtrl: intra PAN, data
  gpPhyRxData->rxData[1]=0x0C; // frmCtrl: src 16bit, dst 64 bit addr
  gpPhyRxData->rxData[2]=42;   // seqn
  gpPhyRxData->rxData[3]=0x12; // dst PAN Id (same as src PAN Id here)
  gpPhyRxData->rxData[4]=0x34;  
  gpPhyRxData->rxData[5]=0x55; // dst addr
  gpPhyRxData->rxData[6]=0x55; // dst addr
  gpPhyRxData->rxData[7] =0x55; // dst addr 
  gpPhyRxData->rxData[8] =0x55; // dst addr 
  gpPhyRxData->rxData[9] =0x55; // dst addr   
  gpPhyRxData->rxData[10]=0x55; // dst addr
  gpPhyRxData->rxData[11]=0x55; // dst addr
  gpPhyRxData->rxData[12]=0x55; // dst addr
  gpPhyRxData->rxData[13]=0xBB; // src addr
  gpPhyRxData->rxData[14]=0xBB;

*/  
  
// Source ID included in packet
  gpPhyRxData->frameLength = 0x13; // PhyLength
  gpPhyRxData->linkQuality = 0xFF; // LQ
  gpPhyRxData->rxData[0]=0x01; // frmCtrl: inter PAN, data
  gpPhyRxData->rxData[1]=0x8C; // frmCtrl: src 16bit, dst 64 bit addr
  gpPhyRxData->rxData[2]=42;   // seqn
  gpPhyRxData->rxData[3]=0x12; // dst PAN Id (same as src PAN Id here)
  gpPhyRxData->rxData[4]=0x34;  
  gpPhyRxData->rxData[5]=0x55; // dst addr
  gpPhyRxData->rxData[6]=0x55; // dst addr
  gpPhyRxData->rxData[7] =0x55; // dst addr 
  gpPhyRxData->rxData[8] =0x55; // dst addr 
  gpPhyRxData->rxData[9] =0x55; // dst addr   
  gpPhyRxData->rxData[10]=0x55; // dst addr
  gpPhyRxData->rxData[11]=0x55; // dst addr
  gpPhyRxData->rxData[12]=0x55; // dst addr

  gpPhyRxData->rxData[13]=0x12; // src PanId
  gpPhyRxData->rxData[14]=0x34;
  gpPhyRxData->rxData[15]=0xBB; // src addr
  gpPhyRxData->rxData[16]=0xBB;



  gIsrAsyncTailFunction = IrqAsyncRxFilterEntry;
  InitRxFastAction();
  InitRxPointers();

#endif
}


/**
  mPhyTxRxState is used as internal state reference for the PHY layer. Upon reset, the state is 'cIdle'
  State is changed from to either 'cBusy_Rx' or 'cBusy_Tx' by SetRxTxState primitive.
  Next state can be cRxED or xRxCCA or cTxData, depending on sunsequent command. (or return to cIdle)
  Once an action is completed (EOF), cIdle is set again
*/
phyTxRxState_t mPhyTxRxState; // Allowed states: cBusy_Rx, cBusy_Tx, cIdle, cRxED, cRxCCA

int8_t gTxRemainingLength;

uint8_t gPhyMacDataRxIndex;
uint8_t gPhyMacDataTxIndex;

uint8_t *gpPhyTxPacket;

uint8_t *gpPhyPacketHead;
rxPacket_t *gpPhyRxData;

zbClock16_t gRxTimeStamp;
zbClock24_t gRxTimeStamp24;
uint16_t gIsrMask;

uint8_t gIsrEntryCounter;

uint8_t gCurrentPALevel;

void (*gIsrFastAction)(void);
void (*gIsrPendingFastAction)(void);
void (*gIsrAsyncTailFunction)(void);
