//*****************************************************************************
//
// mSPI.c - Driver for the double line spi link.
//
//*****************************************************************************

//*****************************************************************************
//
//! \use only control by msp430 bsp device
//! @{
//
//*****************************************************************************
#include "bsp.h"
#include "mSPI.h"
/* ----------------------- Platform includes --------------------------------*/
#define  SPI_PORT_1              (GPIO_PORT_P1)
#define  SPI_MOSI_1              (GPIO_PIN3)
#define  SPI_MISO_1              (GPIO_PIN4)
#define  SPI_MISO_1_INPUT        (0x10)

#define  SPI_MOSI_1_HIGH         0xF7
#define  SPI_MOSI_1_LOW          0x08

#define  SPI_MOSI_2              (GPIO_PIN5)
#define  SPI_MISO_2              (GPIO_PIN7)
#define  SPI_MISO_2_INPUT        (0x80)

#define  SPI_MOSI_2_HIGH         (0xDF)     // High trans data
#define  SPI_MOSI_2_LOW          (0x20)
/*******    2   ********/

#define SPI_PORT_2              (GPIO_PORT_P2)
#define SPI_MOSI_3              (GPIO_PIN0)
#define SPI_MISO_3              (GPIO_PIN1)
#define SPI_MOSI_3_HIGH         (0xFE)     // High trans data
#define SPI_MOSI_3_LOW          (0x01)     // low trans data
#define SPI_MISO_3_INPUT        (0x02)

#define SPI_MOSI_4              (GPIO_PIN3)
#define SPI_MISO_4              (GPIO_PIN4)
#define SPI_MOSI_4_HIGH         (0xF7)     // High trans data
#define SPI_MOSI_4_LOW          (0x08)     // low trans data
#define SPI_MISO_4_INPUT        (0x10)

/*******   3    ******/

#define SPI_PORT_3              (GPIO_PORT_P3)
#define SPI_MOSI_5              (GPIO_PIN5)
#define SPI_MISO_5              (GPIO_PIN6)
#define SPI_MOSI_5_HIGH         (0xDF)     // High trans data
#define SPI_MOSI_5_LOW          (0x20)     // low trans data
#define SPI_MISO_5_INPUT        (0x40)

#define SPI_PORT_5              (GPIO_PORT_P5)

#define SPI_MOSI_6              (GPIO_PIN7)
#define SPI_MOSI_6_HIGH         (0x7F)     // High trans data
#define SPI_MOSI_6_LOW          (0x80)     // low trans data


#define SPI_PORT_7              (GPIO_PORT_P7)
#define SPI_MISO_6              (GPIO_PIN4)
#define SPI_MISO_6_INPUT        (0x10)

#define SPI_MOSI_7              (GPIO_PIN5)
#define SPI_MISO_7              (GPIO_PIN6)
#define SPI_MOSI_7_HIGH         (0xDF)     // High trans data
#define SPI_MOSI_7_LOW          (0x20)     // low trans data
#define SPI_MISO_7_INPUT        (0x40)

//Load 负载回路要置0
/* ----------------------- Regsform includes --------------------------------*/
#define PULSE_Wind              (85UL)          // Ti 单字节脉冲宽度 为 85 us
#define READ_PULSE_Wind         (37UL)
#define READ_WAIT_Wind          (45UL)
#define PULSE_DoubleWind        (170UL)          // Ti 单字节脉冲宽度 为 85 us
#define PULSE_TripleWind        (253UL)
#define Write                   (true)
#define Read                    (false)
#define LUT_GAIN_MSB            (0X00)
#define MASTER_CLOCK_KHZ        (20000)         // 20MHZ
#define SPI_CFG                 (3)             //传输速率

#define  ZERO_SYM               (0)
#define  ONE_SYM                (1)
#define  IDLE_SYM               (2)
#define RD_TIME_UINT            (25000) //3125 * 8 bit
#define RD_TIME_UINT_25         (781)
#define RD_TIME_UINT_35         (1093)
#define RD_TIME_UINT_50         (1562)
#define RD_TIME_UINT_65         (2031)
#define RD_TIME_UINT_75         (2381)


static unsigned int cur_clk_s;
unsigned int DUTY_CYCLE_25,DUTY_CYCLE_50,DUTY_CYCLE_75,DUTY_CYCLE_35,DUTY_CYCLE_65 = 0;
static unsigned int DUTY_CYCLE_100  = 10000;

static int LinkID = 1;

void
SetLinkID(int ID){
    LinkID = ID;
}
/******************************************************************************
* Function Name  : mSPI_Init
* Description    : simulating SPI by software Init.
* Input          : NULL
* Return         : NULL
* Author&Version : 2021-11-16 by czc;
******************************************************************************/
int
mSPI_Init(){
    //每个引脚均初始化
    GPIO_setAsOutputPin(SPI_PORT_1, SPI_MOSI_1);
    GPIO_setAsInputPin(SPI_PORT_1,SPI_MISO_1);
    GPIO_setAsOutputPin(SPI_PORT_1, SPI_MOSI_2);
    GPIO_setAsInputPin(SPI_PORT_1,SPI_MISO_2);

    GPIO_setAsOutputPin(SPI_PORT_2, SPI_MOSI_3);
    GPIO_setAsInputPin(SPI_PORT_2,SPI_MISO_3);
    GPIO_setAsOutputPin(SPI_PORT_2, SPI_MOSI_4);
    GPIO_setAsInputPin(SPI_PORT_2,SPI_MISO_4);

    GPIO_setAsOutputPin(SPI_PORT_3, SPI_MOSI_5);
    GPIO_setAsInputPin(SPI_PORT_3,SPI_MISO_5);

    GPIO_setAsOutputPin(SPI_PORT_5, SPI_MOSI_6);
    GPIO_setAsInputPin(SPI_PORT_7,SPI_MISO_6);

    GPIO_setAsOutputPin(SPI_PORT_7, SPI_MOSI_7);
    GPIO_setAsInputPin(SPI_PORT_7,SPI_MISO_7);
    //RTC Init
    init_swif_set(SPI_CFG);
    return 0;
}

//------------------------------------------------------------------------------
//  delay_cycles
//
//  DESCRIPTION:
//  delay cpu cycles.
//------------------------------------------------------------------------------
void delay_cycles(unsigned int delay_cycles)
{
    unsigned int cur_clk;


    RTCCTL01 = 0;
    RTCCTL01 |= RTCHOLD;                    // Make sure  RTC_A is stopped
    RTCNT1 = 10;                           // Load RTC_A (4 bytes to make a 32-bit)
    RTCNT2 = 0;
    //RTCNT3 = 0;
    //RTCNT4 = 0;
    RTCCTL01 =  RTCSSEL_1 + RTCTEV_3;   // CTR_A: Counter Mode, Enable Interrupt, MCLK Input, 32-bit overflow, Start counter


    do {
        cur_clk = 0;
        cur_clk = RTCNT2;
        cur_clk <<=8;
        cur_clk |= RTCNT1;

    }while (cur_clk < delay_cycles );

}

void init_swif_set(unsigned char swif_clk)
{
    unsigned int one_time_uint_cycles;

    one_time_uint_cycles = MASTER_CLOCK_KHZ/swif_clk;
    DUTY_CYCLE_100 = one_time_uint_cycles;
    DUTY_CYCLE_50 = one_time_uint_cycles >>1;
    DUTY_CYCLE_25 = DUTY_CYCLE_50>>1;
    DUTY_CYCLE_75 = DUTY_CYCLE_50  + DUTY_CYCLE_25 ;

}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//  void SWIFSendSymbol(uint8_t sym)
//
//  DESCRIPTION:
//  Send symbol "sym" to lmp91300 on the SWIF TX pin.
//------------------------------------------------------------------------------

void SWIF_send_symbol(uint8_t sym)
{
    switch (LinkID)
    {
        case 1:
            P1OUT &= SPI_MOSI_1_HIGH;
            break;
        case 2:
            P1OUT &= SPI_MOSI_2_HIGH;
            break;
        case 3:
            P2OUT &= SPI_MOSI_3_HIGH;
            break;
        case 4:
            P2OUT &= SPI_MOSI_4_HIGH;
            break;
        case 5:
            P3OUT &= SPI_MOSI_5_HIGH;
            break;
        case 6:
            P5OUT &= SPI_MOSI_6_HIGH;
            break;
        case 7:
            P7OUT &= SPI_MOSI_7_HIGH;
            break;
    }
    switch (sym) {
    case ZERO_SYM:
        {
            delay_cycles(DUTY_CYCLE_25);                                           // high period for symbol 0
            break;
        }
    case ONE_SYM:
        {
            delay_cycles(DUTY_CYCLE_75);                                           // high period for symbol 1
            break;
        }
    case IDLE_SYM:
        {
            delay_cycles(DUTY_CYCLE_50);                                           // high period for symbol idle
            break;
        }
    default:
        {
            delay_cycles(DUTY_CYCLE_50);                                           // all low period
            break;
        }
    }
    switch (LinkID)
    {
        case 1:
            P1OUT &= SPI_MOSI_1_LOW;       // assert PRI_TX_EN_N
            P1OUT |= SPI_MOSI_1_LOW;
            break;
        case 2:
            P1OUT &= SPI_MOSI_2_LOW;       // assert PRI_TX_EN_N
            P1OUT |= SPI_MOSI_2_LOW;
            break;
        case 3:
            P2OUT &= SPI_MOSI_3_LOW;       // assert PRI_TX_EN_N
            P2OUT |= SPI_MOSI_3_LOW;
            break;
        case 4:
            P2OUT &= SPI_MOSI_4_LOW;       // assert PRI_TX_EN_N
            P2OUT |= SPI_MOSI_4_LOW;
            break;
        case 5:
            P3OUT &= SPI_MOSI_5_LOW;       // assert PRI_TX_EN_N
            P3OUT |= SPI_MOSI_5_LOW;
            break;
        case 6:
            P5OUT &= SPI_MOSI_6_LOW;       // assert PRI_TX_EN_N
            P5OUT |= SPI_MOSI_6_LOW;
            break;
        case 7:
            P7OUT &= SPI_MOSI_7_LOW;       // assert PRI_TX_EN_N
            P7OUT |= SPI_MOSI_7_LOW;
            break;
    }
    switch (sym) {
    case ZERO_SYM:
        {
            delay_cycles(DUTY_CYCLE_75);                                           // low period for symbol 0
            break;
        }
    case ONE_SYM:
        {
            delay_cycles(DUTY_CYCLE_25);                                           // low period for symbol 1
            break;
        }
    case IDLE_SYM:
        {
            delay_cycles(DUTY_CYCLE_50);                                           // low period for idle symbol
            break;
        }
    default:
        {
            delay_cycles(DUTY_CYCLE_50);                                           // all low period
            break;
        }
    }
}

//------------------------------------------------------------------------------
//  void SWIF_write_byte
//
//  DESCRIPTION:
//  Send a byte to lmp91300 by swif interface
//  unsigned char data: the data written to lmp91300 via swif
//------------------------------------------------------------------------------

void SWIF_write_byte(unsigned char data)
{
    int i;
    for ( i=7; i>=0; i--) {
        //output MSB first
        SWIF_send_symbol((data>>i) & 1 );
    }

}

//------------------------------------------------------------------------------
//  void SWIF_get_idle
//
//  DESCRIPTION:
//  wait for a idle coming and measure a idle time unit
//  return: true, if the symbol is idle
//------------------------------------------------------------------------------

unsigned char SWIF_get_idle()
{
    unsigned int cur_clk_d, cur_clk_e;
    unsigned int one_time_uint_cycles;

    do {

        {//wait for input become low
            cur_clk_d = RTCNT2;
            cur_clk_d <<=8;
            cur_clk_d |=RTCNT1;

        }
        if (cur_clk_d < cur_clk_s)
            cur_clk_d |= 0xFF;
        if ((cur_clk_d - cur_clk_s) > RD_TIME_UINT) //8kbit, 1 time unit is 3125 (125* 25)
            return 0;
        switch (LinkID){
            case 1 :
                if ((P1IN & SPI_MISO_1_INPUT)==SPI_MISO_1_INPUT)
                    goto Hm;
                break;
            case 2 :
                if ((P1IN & SPI_MISO_2_INPUT)==SPI_MISO_2_INPUT)
                    goto Hm;
                break;
            case 3 :
                if ((P2IN & SPI_MISO_3_INPUT)==SPI_MISO_3_INPUT)
                    goto Hm;
                break;
            case 4 :
                if ((P2IN & SPI_MISO_4_INPUT)==SPI_MISO_4_INPUT)
                    goto Hm;
                break;
            case 5 :
                if ((P3IN & SPI_MISO_5_INPUT)==SPI_MISO_5_INPUT)
                    goto Hm;
                break;
            case 6 :
                if ((P7IN & SPI_MISO_6_INPUT)==SPI_MISO_6_INPUT)
                    goto Hm;
                break;
            case 7 :
                if ((P7IN & SPI_MISO_7_INPUT)==SPI_MISO_7_INPUT)
                    goto Hm;
                break;
        }
    }while (1);
    Hm:
    do {
        switch (LinkID){
            case 1:
                if ((P1IN & SPI_MISO_1_INPUT)== 0x0)
                    goto Ht;
                else
                {//wait for input become low
                    cur_clk_e = RTCNT2;
                    cur_clk_e <<=8;
                    cur_clk_e |=RTCNT1;
                }
                break;
            case 2:
                if ((P1IN & SPI_MISO_2_INPUT)== 0x0)
                    goto Ht;
                else
                {//wait for input become low
                    cur_clk_e = RTCNT2;
                    cur_clk_e <<=8;
                    cur_clk_e |=RTCNT1;
                }
                break;
            case 3:
                if ((P2IN & SPI_MISO_3_INPUT)== 0x0)
                    goto Ht;
                else
                {//wait for input become low
                    cur_clk_e = RTCNT2;
                    cur_clk_e <<=8;
                    cur_clk_e |=RTCNT1;
                }
                break;
            case 4:
                if ((P2IN & SPI_MISO_4_INPUT)== 0x0)
                    goto Ht;
                else
                {//wait for input become low
                    cur_clk_e = RTCNT2;
                    cur_clk_e <<=8;
                    cur_clk_e |=RTCNT1;
                }
                break;
            case 5:
                if ((P3IN & SPI_MISO_5_INPUT)== 0x0)
                    goto Ht;
                else
                {//wait for input become low
                    cur_clk_e = RTCNT2;
                    cur_clk_e <<=8;
                    cur_clk_e |=RTCNT1;
                }
                break;
            case 6:
                if ((P7IN & SPI_MISO_6_INPUT)== 0x0)
                    goto Ht;
                else
                {//wait for input become low
                    cur_clk_e = RTCNT2;
                    cur_clk_e <<=8;
                    cur_clk_e |=RTCNT1;
                }
                break;
            case 7:
                if ((P7IN & SPI_MISO_7_INPUT)== 0x0)
                    goto Ht;
                else
                {//wait for input become low
                    cur_clk_e = RTCNT2;
                    cur_clk_e <<=8;
                    cur_clk_e |=RTCNT1;
                }
                break;
        }
        //溢出处理
        if (cur_clk_d < cur_clk_s)
            cur_clk_d |= 0xFF;
        if ((cur_clk_e - cur_clk_d) > RD_TIME_UINT) //8kbit, 1 time unit is 3125 (125* 25)
            return 0;
        //wait for high
        //if ((P2IN & SWIF_INPUT)==0x0)
        //    break;

    }while (1);
    Ht:
    one_time_uint_cycles = cur_clk_e  - cur_clk_s-5 ;
    DUTY_CYCLE_100 = one_time_uint_cycles;
    DUTY_CYCLE_50 = one_time_uint_cycles >>1;
    DUTY_CYCLE_25 = DUTY_CYCLE_50>>1;
    DUTY_CYCLE_75 = DUTY_CYCLE_50  + DUTY_CYCLE_25 ;

    DUTY_CYCLE_35 = DUTY_CYCLE_25 + (DUTY_CYCLE_25>>1);//adjust 150 clk.

    DUTY_CYCLE_65 = DUTY_CYCLE_50 + (DUTY_CYCLE_25>>1);

    //keep the current change point

    if (((cur_clk_d- cur_clk_s) > DUTY_CYCLE_35 ) && ((cur_clk_d- cur_clk_s) < DUTY_CYCLE_65) ) {
        cur_clk_s = cur_clk_e;
        return 1;
    }

    return 0;
}

//------------------------------------------------------------------------------
//  void SWIF_get_sym
//
//  DESCRIPTION:
//  read a sym
//  return : a sym
//------------------------------------------------------------------------------

unsigned char SWIF_get_sym()
{
    unsigned char one_sym = 0xFF;
    unsigned int cur_clk_d, cur_clk_e;
    do {

        {//wait for input become low
            cur_clk_d = RTCNT2;
            cur_clk_d <<=8;
            cur_clk_d |=RTCNT1;
        }

        if (cur_clk_d < cur_clk_s)
            cur_clk_d |= 0xFF;
        if ((cur_clk_d - cur_clk_s) > RD_TIME_UINT) //8kbit, 1 time unit is 3125 (125* 25)
        {
            return 0xFF;

        }
        //wait for low
        switch (LinkID){
            case 1:
                if ((P1IN & SPI_MISO_1_INPUT)==SPI_MISO_1_INPUT)
                    goto Hk;
                break;
            case 2:
                if ((P1IN & SPI_MISO_2_INPUT)==SPI_MISO_2_INPUT)
                    goto Hk;
                break;
            case 3:
                if ((P2IN & SPI_MISO_3_INPUT)==SPI_MISO_3_INPUT)
                    goto Hk;
                break;
            case 4:
                if ((P2IN & SPI_MISO_4_INPUT)==SPI_MISO_4_INPUT)
                    goto Hk;
                break;
            case 5:
                if ((P3IN & SPI_MISO_5_INPUT)==SPI_MISO_5_INPUT)
                    goto Hk;
                break;
            case 6:
                if ((P7IN & SPI_MISO_6_INPUT)==SPI_MISO_6_INPUT)
                    goto Hk;
                break;
            case 7:
                if ((P7IN & SPI_MISO_7_INPUT)==SPI_MISO_7_INPUT)
                    goto Hk;
                break;
        }
//        if ((P2IN & SWIF_INPUT)==0x10)
//            break;

    }while (1);
    Hk:
    do {

        {//wait for input become high
            cur_clk_e = RTCNT2;
            cur_clk_e <<=8;
            cur_clk_e |=RTCNT1;
        }
        if (cur_clk_e < cur_clk_d)
            cur_clk_e |= 0xFF;

        if ((cur_clk_e - cur_clk_d) > RD_TIME_UINT) { //8kbit, 1 time unit is 3125 (125* 25)

            return 0XFF;
        }
        //wait for high
        switch (LinkID)
        {
            case 1:
                if ((P1IN & SPI_MISO_1_INPUT)== 0x0)
                    goto Tk;
                break;
            case 2:
                if ((P1IN & SPI_MISO_2_INPUT)== 0x0)
                    goto Tk;
                break;
            case 3:
                if ((P2IN & SPI_MISO_3_INPUT)== 0x0)
                    goto Tk;
                break;
            case 4:
                if ((P2IN & SPI_MISO_4_INPUT)== 0x0)
                    goto Tk;
                break;
            case 5:
                if ((P3IN & SPI_MISO_5_INPUT)== 0x0)
                    goto Tk;
                break;
            case 6:
                if ((P7IN & SPI_MISO_6_INPUT)== 0x0)
                    goto Tk;
                break;
            case 7:
                if ((P7IN & SPI_MISO_7_INPUT)== 0x0)
                    goto Tk;
                break;
        }
    }while (1);
    Tk:
    if (((cur_clk_d- cur_clk_s) < DUTY_CYCLE_35 ) && ((cur_clk_e- cur_clk_d) > DUTY_CYCLE_65) )
        one_sym = ZERO_SYM;
    else    one_sym = ONE_SYM;

    //keep the current change point
    cur_clk_s = cur_clk_e;

    return one_sym;
}
//------------------------------------------------------------------------------
//  void SWIF_read_reg
//
//  DESCRIPTION:
//  read a register from lmp91300 by swif interface
//  unsigned char cmd: the register address
//  unsigned char swif_capture_data[2]: the buffer to store the received data
//  return: none
//------------------------------------------------------------------------------

uint8_t
Read_LmpRegCmd(uint8_t address)
{
    unsigned char data;
    unsigned int cur_clk = 0;
    int i;
    init_swif_set(3);
    //send read command
    SWIF_send_symbol(IDLE_SYM);
    SWIF_write_byte((address | 0x80));  //Read command
    SWIF_send_symbol(IDLE_SYM);

    //end transfer
    switch (LinkID)
    {
        case 1:
            P1OUT &= SPI_MOSI_1_HIGH;
            P1OUT &= SPI_MOSI_1_HIGH;
            P1OUT &= SPI_MOSI_1_HIGH;
            P1OUT |= SPI_MOSI_1_LOW;
            break;
        case 2:
            P1OUT &= SPI_MOSI_2_HIGH;
            P1OUT &= SPI_MOSI_2_HIGH;
            P1OUT &= SPI_MOSI_2_HIGH;
            P1OUT |= SPI_MOSI_2_LOW;
            break;
        case 3:
            P2OUT &= SPI_MOSI_3_HIGH;
            P2OUT &= SPI_MOSI_3_HIGH;
            P2OUT &= SPI_MOSI_3_HIGH;
            P2OUT |= SPI_MOSI_3_LOW;
            break;
        case 4:
            P2OUT &= SPI_MOSI_4_HIGH;
            P2OUT &= SPI_MOSI_4_HIGH;
            P2OUT &= SPI_MOSI_4_HIGH;
            P2OUT |= SPI_MOSI_4_LOW;
            break;
        case 5:
            P3OUT &= SPI_MOSI_5_HIGH;
            P3OUT &= SPI_MOSI_5_HIGH;
            P3OUT &= SPI_MOSI_5_HIGH;
            P3OUT |= SPI_MOSI_5_LOW;
            break;
        case 6:
            P5OUT &= SPI_MOSI_6_HIGH;
            P5OUT &= SPI_MOSI_6_HIGH;
            P5OUT &= SPI_MOSI_6_HIGH;
            P5OUT |= SPI_MOSI_6_LOW;
            break;
        case 7:
            P7OUT &= SPI_MOSI_7_HIGH;
            P7OUT &= SPI_MOSI_7_HIGH;
            P7OUT &= SPI_MOSI_7_HIGH;
            P7OUT |= SPI_MOSI_7_LOW;
            break;
    }

    //start time clk
    RTCCTL01 = 0;
    RTCCTL01 |= RTCHOLD;                  // Make sure  RTC_A is stopped
    RTCNT1 = 0;                          // Load RTC_A (4 bytes to make a 32-bit)
    RTCNT2 = 0;
    RTCNT3 = 0;
    RTCNT4 = 0;
    RTCCTL01 =  RTCSSEL_1 + RTCTEV_3;     // CTR_A: Counter Mode, Enable Interrupt, MCLK Input, 32-bit overflow, Start counter

    //wait for getting the idle start point.
    do {
        switch (LinkID)
        {
            case 1:
                if ((P1IN & SPI_MISO_1_INPUT)==SPI_MISO_1_INPUT)
                {
                    cur_clk = RTCNT2;
                    cur_clk <<=8;
                    cur_clk |=RTCNT1;
                } else {
                    //reset the clk count
                    RTCCTL01 = 0;
                    RTCCTL01 |= RTCHOLD;                  // Make sure  RTC_A is stopped
                    RTCNT1 = 0;                          // Load RTC_A (4 bytes to make a 32-bit)
                    RTCNT2 = 0;
                    RTCNT3 = 0;
                    RTCNT4 = 0;
                    RTCCTL01 =  RTCSSEL_1 + RTCTEV_3;     // CTR_A: Counter Mode, Enable Interrupt, MCLK Input, 32-bit overflow, Start counter
                    //initialize start point clk
                    cur_clk_s = 0;
                    goto Ts;
                }
                break;
            case 2:
                if ((P1IN & SPI_MISO_2_INPUT)==SPI_MISO_2_INPUT)
                {
                    cur_clk = RTCNT2;
                    cur_clk <<=8;
                    cur_clk |=RTCNT1;
                } else {
                    //reset the clk count
                    RTCCTL01 = 0;
                    RTCCTL01 |= RTCHOLD;                  // Make sure  RTC_A is stopped
                    RTCNT1 = 0;                          // Load RTC_A (4 bytes to make a 32-bit)
                    RTCNT2 = 0;
                    RTCNT3 = 0;
                    RTCNT4 = 0;
                    RTCCTL01 =  RTCSSEL_1 + RTCTEV_3;     // CTR_A: Counter Mode, Enable Interrupt, MCLK Input, 32-bit overflow, Start counter
                    //initialize start point clk
                    cur_clk_s = 0;
                    goto Ts;
                }
                break;
            case 3:
                if ((P2IN & SPI_MISO_3_INPUT)==SPI_MISO_3_INPUT)
                {
                    cur_clk = RTCNT2;
                    cur_clk <<=8;
                    cur_clk |=RTCNT1;
                } else {
                    //reset the clk count
                    RTCCTL01 = 0;
                    RTCCTL01 |= RTCHOLD;                  // Make sure  RTC_A is stopped
                    RTCNT1 = 0;                          // Load RTC_A (4 bytes to make a 32-bit)
                    RTCNT2 = 0;
                    RTCNT3 = 0;
                    RTCNT4 = 0;
                    RTCCTL01 =  RTCSSEL_1 + RTCTEV_3;     // CTR_A: Counter Mode, Enable Interrupt, MCLK Input, 32-bit overflow, Start counter
                    //initialize start point clk
                    cur_clk_s = 0;
                    goto Ts;
                }
                break;
            case 4:
                if ((P2IN & SPI_MISO_4_INPUT)==SPI_MISO_4_INPUT)
                {
                    cur_clk = RTCNT2;
                    cur_clk <<=8;
                    cur_clk |=RTCNT1;
                } else {
                    //reset the clk count
                    RTCCTL01 = 0;
                    RTCCTL01 |= RTCHOLD;                  // Make sure  RTC_A is stopped
                    RTCNT1 = 0;                          // Load RTC_A (4 bytes to make a 32-bit)
                    RTCNT2 = 0;
                    RTCNT3 = 0;
                    RTCNT4 = 0;
                    RTCCTL01 =  RTCSSEL_1 + RTCTEV_3;     // CTR_A: Counter Mode, Enable Interrupt, MCLK Input, 32-bit overflow, Start counter
                    //initialize start point clk
                    cur_clk_s = 0;
                    goto Ts;
                }
                break;
            case 5:
                if ((P3IN & SPI_MISO_5_INPUT)==SPI_MISO_5_INPUT)
                {
                    cur_clk = RTCNT2;
                    cur_clk <<=8;
                    cur_clk |=RTCNT1;
                } else {
                    //reset the clk count
                    RTCCTL01 = 0;
                    RTCCTL01 |= RTCHOLD;                  // Make sure  RTC_A is stopped
                    RTCNT1 = 0;                          // Load RTC_A (4 bytes to make a 32-bit)
                    RTCNT2 = 0;
                    RTCNT3 = 0;
                    RTCNT4 = 0;
                    RTCCTL01 =  RTCSSEL_1 + RTCTEV_3;     // CTR_A: Counter Mode, Enable Interrupt, MCLK Input, 32-bit overflow, Start counter
                    //initialize start point clk
                    cur_clk_s = 0;
                    goto Ts;
                }
                break;
            case 6:
                if ((P7IN & SPI_MISO_6_INPUT)==SPI_MISO_6_INPUT)
                {
                    cur_clk = RTCNT2;
                    cur_clk <<=8;
                    cur_clk |=RTCNT1;
                } else {
                    //reset the clk count
                    RTCCTL01 = 0;
                    RTCCTL01 |= RTCHOLD;                  // Make sure  RTC_A is stopped
                    RTCNT1 = 0;                          // Load RTC_A (4 bytes to make a 32-bit)
                    RTCNT2 = 0;
                    RTCNT3 = 0;
                    RTCNT4 = 0;
                    RTCCTL01 =  RTCSSEL_1 + RTCTEV_3;     // CTR_A: Counter Mode, Enable Interrupt, MCLK Input, 32-bit overflow, Start counter
                    //initialize start point clk
                    cur_clk_s = 0;
                    goto Ts;
                }
                break;
            case 7:
                if ((P7IN & SPI_MISO_7_INPUT)==SPI_MISO_7_INPUT)
                {
                    cur_clk = RTCNT2;
                    cur_clk <<=8;
                    cur_clk |=RTCNT1;
                } else {
                    //reset the clk count
                    RTCCTL01 = 0;
                    RTCCTL01 |= RTCHOLD;                  // Make sure  RTC_A is stopped
                    RTCNT1 = 0;                          // Load RTC_A (4 bytes to make a 32-bit)
                    RTCNT2 = 0;
                    RTCNT3 = 0;
                    RTCNT4 = 0;
                    RTCCTL01 =  RTCSSEL_1 + RTCTEV_3;     // CTR_A: Counter Mode, Enable Interrupt, MCLK Input, 32-bit overflow, Start counter
                    //initialize start point clk
                    cur_clk_s = 0;
                    goto Ts;
                }
                break;
        }
        if (cur_clk > DUTY_CYCLE_25)
            return 0xFF;
    }while (1);
    Ts:
    if (SWIF_get_idle() == 0) { //for reading, the first symbol must be idle
        return 0xFF;
    }

    RTCCTL01 = 0;
    RTCCTL01 |= RTCHOLD;                  // Make sure  RTC_A is stopped
    RTCNT1 = 0;                          // Load RTC_A (4 bytes to make a 32-bit)
    RTCNT2 = 0;
    RTCNT3 = 0;
    RTCNT4 = 0;
    RTCCTL01 =  RTCSSEL_1 + RTCTEV_3;     // CTR_A: Counter Mode, Enable Interrupt, MCLK Input, 32-bit overflow, Start counter
    //initialize start point clk
    cur_clk_s = 0;


    data = 0;
    for ( i=7; i>=0; i--) {
        //output MSB first
        //reset the clk count
        data |= (SWIF_get_sym()<< i);
    }
    //don't read the second byte because some register only outputs a byte
#if 0
    data  =0;
    for ( i=7; i>=0; i--) {
        //output MSB first
        data |= (SWIF_get_sym()<< i);
    }

    swif_capture_data[1] = data;
#endif
    //wait for the read done (8*8*125*25), one bit:125us
    //delay_ms(20);
    __delay_cycles(4*125*25);
    return data;
}
//------------------------------------------------------------------------------
//  void SWIF_write_reg
//
//  DESCRIPTION:
//  write the value to  a register  by swif interface
//  unsigned char cmd: the register address
//  unsigned char data[2]: the value to write to register
//  unsigned char data_width: 0 8 bits, 1: 16 bits
//  return: none
//------------------------------------------------------------------------------

void
Write_LmpRegCmd(uint8_t address, uint8_t data)
{

    //send idle
    SWIF_send_symbol(IDLE_SYM);
    //write write command
    SWIF_write_byte(address);
    //write data
    SWIF_write_byte(data);
    //send idle
    SWIF_send_symbol(IDLE_SYM);
    switch (LinkID)
    {
        case 1:
            P1OUT &= SPI_MOSI_1_HIGH;
            P1OUT &= SPI_MOSI_1_HIGH;
            P1OUT &= SPI_MOSI_1_HIGH;
            P1OUT |= SPI_MOSI_1_LOW;
            break;
        case 2:
            P1OUT &= SPI_MOSI_2_HIGH;
            P1OUT &= SPI_MOSI_2_HIGH;
            P1OUT &= SPI_MOSI_2_HIGH;
            P1OUT |= SPI_MOSI_2_LOW;
            break;
        case 3:
            P2OUT &= SPI_MOSI_3_HIGH;
            P2OUT &= SPI_MOSI_3_HIGH;
            P2OUT &= SPI_MOSI_3_HIGH;
            P2OUT |= SPI_MOSI_3_LOW;
            break;
        case 4:
            P2OUT &= SPI_MOSI_4_HIGH;
            P2OUT &= SPI_MOSI_4_HIGH;
            P2OUT &= SPI_MOSI_4_HIGH;
            P2OUT |= SPI_MOSI_4_LOW;
            break;
        case 5:
            P3OUT &= SPI_MOSI_5_HIGH;
            P3OUT &= SPI_MOSI_5_HIGH;
            P3OUT &= SPI_MOSI_5_HIGH;
            P3OUT |= SPI_MOSI_5_LOW;
            break;
        case 6:
            P5OUT &= SPI_MOSI_6_HIGH;
            P5OUT &= SPI_MOSI_6_HIGH;
            P5OUT &= SPI_MOSI_6_HIGH;
            P5OUT |= SPI_MOSI_6_LOW;
            break;
        case 7:
            P7OUT &= SPI_MOSI_7_HIGH;
            P7OUT &= SPI_MOSI_7_HIGH;
            P7OUT &= SPI_MOSI_7_HIGH;
            P7OUT |= SPI_MOSI_7_LOW;
            break;
    }
}
