//  Haybin_Wu
//  Shenitech-RD
//  2016.5
//  Built with IAR Embedded Workbench v6.2
//******************************************************************************
#include <msp430FR2433.h>
#include <stdint.h>
#include "FR2433-RFSX.h"
#include "RF_SX1276.h"

uint32_t t=0;
void FRAM_Write (uint16_t FRAM_START,uint8_t *(Array),uint8_t Array_Long);
void FRAM_Read (uint16_t FRAM_START,uint8_t *(Array),uint8_t Array_Long);
void Set_DT(void);
void Refresh_Date(void);
void UART0_Tx(uint8_t data);

#define FRAM_Date_START 0x1800    //Date 存储起始地址
#define FRAM_ID_START 0x1806    //ID 存储起始地址
#define RTC_Data 1920    //定义RTC定时周期 RTC_Data/32=？s

uint8_t Rx_Buf[64];
uint8_t RF_RxBuf[64];
uint8_t RF_RxBuf_size[1];
uint8_t Rx_Data=0;
uint8_t  Date_Time[6]=
{
  30,//0秒
  16,//1分
  10,//2时
  22,//3日
  05,//4月
  16,//5年
};
uint8_t  Device_ID[4]={0xA6,0x52,0x40,0x01,};//设备ID

  //UART发送
  void UART0_Tx(uint8_t data)
  {  
    UCA0TXBUF = data;
    while((UCTXIFG&UCA0IFG)==0);
    UCA0IFG&=~UCTXIFG;      
  }
  void Refresh_Date(void)
  {
   FRAM_Read(FRAM_Date_START,Date_Time,6);
   Date_Time[0]=RTCCNT/32;
  }
  
////////////////////////////////////////////////////////////////////////////////
//主函数
////////////////////////////////////////////////////////////////////////////////
  int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;               // Stop WDT
    // Port Configuration all un-used pins to output low
    P1DIR = 0xFF; P2DIR = 0xFF; P3DIR = 0xFF;
    P1OUT = 0x00; P2OUT = 0x00; P3OUT = 0x00;
    PM5CTL0 &= ~LOCKLPM5;//开引脚功能
  
  // Configure DCO Clock
//外部时钟源启动
    P2SEL0 |= BIT0 | BIT1;                  // set XT1 pin as second function
    do
    {
        CSCTL7 &= ~(XT1OFFG | DCOFFG);      // Clear XT1 and DCO fault flag
        SFRIFG1 &= ~OFIFG;
    } while (SFRIFG1 & OFIFG);              // Test oscillator fault flag
    //上面清除标志有助于降低功耗
    
    __bis_SR_register(SCG0);                // disable FLL
    CSCTL3 |= SELREF__XT1CLK;              // 外部 32768hz reference source
    CSCTL0 = 0;                             // clear DCO and MOD registers
    CSCTL1 &= ~(DCORSEL_7);                 // Clear DCO frequency select bits first
    CSCTL1 |= DCORSEL_3;       //DCO=8Mhz
    CSCTL2 = FLLD_0 + 243;   // DCODIV = 8MHz
    __delay_cycles(3);
    __bic_SR_register(SCG0);                // enable FLL
    while(CSCTL7 & (FLLUNLOCK0 | FLLUNLOCK1)); // Poll until FLL is locked
    
    CSCTL4 = SELREF__XT1CLK + SELMS__DCOCLKDIV;// set XT1CLK(32768Hz) as ACLK source  &   MCLK/SMCLK=DCO
    



  //Timer0_A3 setup
  TA0CCTL0 = CCIE;                              // TACCR0 interrupt enabled
  TA0CCR0 = 32768;
  TA0CTL = TASSEL_1 | MC_1;                     // ACLK, continuous mode

  // Initialize RTC
  RTCMOD = RTC_Data;
  RTCCTL = (RTCSS__XT1CLK  + RTCPS__1024 + RTCIE);//+ RTCSR// Source = 32kHz crystal, divided by 1024
  if(RTCCNT>RTC_Data){RTCCTL |= RTCSR;WDTCTL=0;}
  Refresh_Date();//复位后刷新时间
  //FRCTL0 = FRCTLPW | NWAITS_1;//FRRAM 
  FRAM_Read(FRAM_ID_START,Device_ID,4);//刷新设备ID
  
  
  // Configure UART pins
  P1SEL0 |= BIT4 | BIT5;                    // set 2-UART pin as second function
  // Configure UART
  UCA0CTLW0 |=(UCSSEL__SMCLK+UCSWRST);//UCPEN+UCPAR+
  // Baud Rate calculation
  UCA0BR0 = 52;   // 8000000/8/9600//这位大于16 UCOS16位要置位
  UCA0BR1 = 0x00;    // Fractional portion = 0.083
  //UCA0MCTLW = 0x11;//微调Baud Rate
  UCA0MCTLW = 0x4900 | UCOS16 | UCBRF_1;//微调Baud Rate
  UCA0CTLW0 &= ~UCSWRST;                    // Initialize eUSCI
  UCA0IE |= UCRXIE;                         // Enable USCI_A0 RX interrupt
  
  _EINT();
  
   //无线模块测试化
  uint8_t RF_error_flag=0;
  for(uint8_t i=0;i<5;i++)//最多初始化3次
  {
  if(SX127x_init(Init_LoRa_0_8K)==NORMAL) break;       //无线模块初始化失败复位
  else RF_error_flag=1;
  }          
  if(RF_error_flag==1) //无线初始化失败处理
   { 
     //P3OUT ^= 0xC0;
     LPM4;
   }
  LSD_RF_RXmode(64);
  //LSD_RF_SleepMode();//深度睡眠1.2uA  
  
  
  __bis_SR_register(LPM3_bits | GIE);     // Enter LPM3
  //uint32_t i=0;
   __no_operation();                         // For debugger
  
  while(1)
  { 
    //for(uint8_t i=0;i<64;i++)Rx_Buf[i-1]=i;
    //LSD_RF_SendPacket(Rx_Buf,64);         //发送64个字节数据测试
    //P3OUT ^= 0xC0;  // Toggle P3.6,7 (LED) every 1s 
    //UART0_Tx(0xE5);
    //if(SX127x_init(Init_LoRa_0_8K)==NORMAL);
    //LSD_RF_SleepMode();
    LSD_RF_RXmode(64);
    __bis_SR_register(LPM3_bits | GIE);     // Enter LPM3
  }  
}


// Port 1 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(PORT1_VECTOR))) Port_1 (void)
#else
#error Compiler not supported!
#endif
{
  if(DIO0_IFG&DIO0_BIT)   //数据传输中断处理
    {
      LSD_RF_RxVariPacket(RF_RxBuf,RF_RxBuf_size);   //接收可变数据包，如果速率为大速率，只能用接收固定数据包长度 
      DelayMs(10);
      /*****************************************指令处理************************/
      //if((RF_RxBuf[0]==0x01)&&(RF_RxBuf[1]==0x02))//(RF_rxBuf_size==(RF_RxBuf[3]+6))
      {//判定指令是否有效！！！
       for(uint8_t i=0;i<RF_RxBuf_size[0];i++)
       {UART0_Tx(RF_RxBuf[i]);}
      }
    DIO0_IFG&=~DIO0_BIT; 
    }
                            // Clear P1.3 IFG
    //__bic_SR_register_on_exit(LPM3_bits);   // Exit LPM3
}

// Port 2 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=PORT2_VECTOR
__interrupt void Port_2(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(PORT2_VECTOR))) Port_2 (void)
#else
#error Compiler not supported!
#endif
{
    P2IFG=0;                         // Clear P1.3 IFG
    //__bic_SR_register_on_exit(LPM3_bits);   // Exit LPM3
}
/*
// SPI-B0 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_B0_VECTOR
__interrupt void USCI_B0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B0_VECTOR))) USCI_B0_ISR (void)
#else
#error Compiler not supported!
#endif
{
  while (!(UCB0IFG&UCTXIFG));             // USCI_A0 TX buffer ready?
  UCB0TXBUF = UCB0RXBUF;                  // Echo received data
}
*/

// Timer0 A0 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMER0_A0_VECTOR
__interrupt void Timer0_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMER0_A0_VECTOR))) Timer0_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
  t++;
  if(t>5)
  {
    t=0;//WDTCTL=0;
    //LSD_RF_RxVariPacket(Rxbuffer,Rxbuffer_size);   //接收可变数据包，如果速率为大速率，只能用接收固定数据包长度
    //LSD_RF_RXmode(30);  //每次发送一包数据后，进入接收状态，等待B模块应答
    __bic_SR_register_on_exit(LPM3_bits);   // Exit LPM3 
  }
}
// Timer1 A0 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = TIMER1_A0_VECTOR
__interrupt void Timer1_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(TIMER1_A0_VECTOR))) Timer1_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
  ;
  //if(t>5)WDTCTL=0;//P3OUT ^= 0xC0;
}

// RTC interrupt service routine //一分钟一次
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=RTC_VECTOR
__interrupt void RTC_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(RTC_VECTOR))) RTC_ISR (void)
#else
#error Compiler not supported!
#endif
{
  if(RTCIV&0x02)
  {
    Date_Time[0]=60;
    Set_DT();//万年历
    FRAM_Write (FRAM_Date_START,Date_Time,6);//写入铁电
  } 
}

// UAR0 interrupt service routine
#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector=USCI_A0_VECTOR
__interrupt void USCI_A0_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_A0_VECTOR))) USCI_A0_ISR (void)
#else
#error Compiler not supported!
#endif
{
  uint8_t CS=0;
  if((UCA0IV&USCI_UART_UCRXIFG)==USCI_UART_UCRXIFG)
  {
    Rx_Buf[Rx_Data++] = UCA0RXBUF;
    //UCA0IFG&=~UCRXIFG;
  }
  if(Rx_Data>=10)
  {
    for(uint8_t i=0;i<(Rx_Buf[3]+1);i++)
    CS+=Rx_Buf[i+2];
    if((Rx_Buf[0]==0x4D)&&(Rx_Buf[1]==0x4B)&&(Rx_Buf[Rx_Data-2]==0x55)&&(Rx_Buf[Rx_Data-1]==0x16))
    {
      FRAM_Read(FRAM_ID_START,Device_ID,4);//刷新设备ID
      //功能码01 设置ID//4D 4B 01 08 00 00 00 00 ID ID ID ID CS 16
      if((Rx_Buf[2]==0x01)&&(Rx_Buf[4]==Device_ID[0])&&(Rx_Buf[5]==Device_ID[1])&&(Rx_Buf[6]==Device_ID[2])&&(Rx_Buf[7]==Device_ID[3]))
      {
        Device_ID[0]=Rx_Buf[8];Device_ID[1]=Rx_Buf[9];Device_ID[2]=Rx_Buf[10];Device_ID[3]=Rx_Buf[11];
        FRAM_Write(FRAM_ID_START,Device_ID,4);
        //FRAM_Read(FRAM_ID_START,Device_ID,4);//刷新设备ID
        UART0_Tx(0xE5);
        Rx_Data=0;
      } 
      //功能码06 读设备RTC//4D 4B 06 04 00 00 00 00 CS 16
      if((Rx_Buf[2]==0x06)&&(Rx_Buf[4]==Device_ID[0])&&(Rx_Buf[5]==Device_ID[1])&&(Rx_Buf[6]==Device_ID[2])&&(Rx_Buf[7]==Device_ID[3]))
      {
        Refresh_Date();//refresh time
        //Return 4D 4B 06 A0 ID ID ID ID DT DT DT DT DT DT E5 16
        UART0_Tx(0x4D);UART0_Tx(0x4B);UART0_Tx(0x06);UART0_Tx(0xA0);UART0_Tx(Device_ID[0]);UART0_Tx(Device_ID[1]);UART0_Tx(Device_ID[2]);UART0_Tx(Device_ID[3]);
        UART0_Tx(Date_Time[0]);UART0_Tx(Date_Time[1]);UART0_Tx(Date_Time[2]);UART0_Tx(Date_Time[3]);UART0_Tx(Date_Time[4]);UART0_Tx(Date_Time[5]);
        UART0_Tx(0xE5);UART0_Tx(0x16);
        Rx_Data=0;
      }
      //功能码07 同步RTC//4D 4B 06 04 00 00 00 00 CS 16
      if((Rx_Buf[2]==0x07)&&(Rx_Buf[4]==Device_ID[0])&&(Rx_Buf[5]==Device_ID[1])&&(Rx_Buf[6]==Device_ID[2])&&(Rx_Buf[7]==Device_ID[3]))
      {
        ;
      }
    }
  }
}


//万年历程序
void Set_DT(void)
{
  
  if(Date_Time[0]>59)//秒进位
  {
    Date_Time[1]++;
    Date_Time[0]=0;
  }
  if(Date_Time[1]>59)//分进位
  {
    Date_Time[2]++;
    Date_Time[1]=0;
  }
  if(Date_Time[2]>23)//小时进位
  {
    Date_Time[3]++;
    Date_Time[2]=0;
  }
//常31天情况
if((Date_Time[4]==1)||(Date_Time[4]==3)||(Date_Time[4]==5)||(Date_Time[4]==7)||(Date_Time[4]==8)||(Date_Time[4]==10)||(Date_Time[4]==12))
{
  if(Date_Time[3]>31)
  { 
    Date_Time[3]=1; 
    Date_Time[4]++;
  } 
  if(Date_Time[4]>12) 
  { 
    Date_Time[4]=1;
    Date_Time[5]++;
  }
  if(Date_Time[5]>99)Date_Time[5]=0;
}
//常30天情况
if((Date_Time[4]==4)||(Date_Time[4]==6)||(Date_Time[4]==9)||(Date_Time[4]==11))
{
  if(Date_Time[3]>30) 
  {
    Date_Time[3]=1; 
    Date_Time[4]++; 
  }
}
//2月特殊情况
if(Date_Time[4]==2)
{ 
  if((Date_Time[5]%4==0&&Date_Time[5]%100!=0) ||(Date_Time[5]%400==0))//闰年
  { 
    if(Date_Time[3]>29)
    { 
      Date_Time[3]=1; 
      Date_Time[4]++;
    } 
  }
  else
  {
    if(Date_Time[3]>28)
    { 
      Date_Time[3]=1; 
      Date_Time[4]++;
    }
  }
 }
}

void FRAM_Write (uint16_t FRAM_START,uint8_t *(Array),uint8_t Array_Long)
{  
  SYSCFG0 &= ~DFWP;    //Close FRAM Write Protection
  //FRAM_Date_START=*0x1800;
  for (uint8_t i = 0; i < Array_Long; i++)
  {
    *(uint8_t *)(FRAM_START+i)=Array[i];//
  }
  SYSCFG0 |= DFWP;  //Open FRAM Write Protection
}

void FRAM_Read (uint16_t FRAM_START,uint8_t *(Array),uint8_t Array_Long)
{
  for (uint8_t i = 0; i < Array_Long; i++)
  {
   Array[i]=*(uint8_t *)(FRAM_START+i);
  }
}
