打印
[资料分享]

LMP91300驱动分享

[复制链接]
261|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xyz549040622|  楼主 | 2019-12-21 11:15 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
lm, TI, se, tc, IO
/**
*  \file   swif.c
*
*  \brief  swif APIs.
*
*   This file contains the APIs for swif.
*/

/*
* Copyright (C) 2013 Texas Instruments Incorporated - http://www.ti.com/
*/
/*
*  Redistribution and use in source and binary forms, with or without
*  modification, are permitted provided that the following conditions
*  are met:
*
*    Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
*
*    Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in the
*    documentation and/or other materials provided with the
*    distribution.
*
*    Neither the name of Texas Instruments Incorporated nor the names of
*    its contributors may be used to endorse or promote products derived
*    from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
*  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
*  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
*  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/

#include "..\Common\device.h"
#include "..\Common\types.h"          // Basic Type declarations
#include "..\Common\hal_UCS.h"
#include "..\Common\hal_pmm.h"
#include "usb2any.h"
#include "..\wavevision\_include\fpga.h"




unsigned int DUTY_CYCLE_25,DUTY_CYCLE_50,DUTY_CYCLE_75,DUTY_CYCLE_35,DUTY_CYCLE_65;
#define SWIF_INPUT    0x10
#define SWIF_OUTPUT   0x08


//definition for reading a register
#define RD_TIME_UINT     125000
#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;



//definition for sending a symbol to lmp91300
#define  SET_TX_HIGH  0xF7
#define  SET_TX_LOW  0x08
#define  ZERO_SYM  0
#define  ONE_SYM   1
#define  IDLE_SYM  2


//------------------------------------------------------------------------------
//  reset_swif_for_spi
//
//  DESCRIPTION:
//  initialize the pins for SPI interface
//
//------------------------------------------------------------------------------

void reset_swif_for_spi(void)
{


        P2SEL  &= ~0x08;                         // p2.3 rx
        P2SEL  &= ~0x10;                         // p2.4 tx

        P2DIR  |=  0x18;                        // make it out, in spi mode, these two pin muts be low
        P2OUT &=  ~0x18;                         //        Make Low

}

//------------------------------------------------------------------------------
//  init_swif_set
//
//  DESCRIPTION:
//  initialize the pins for SWIF interface
//  unsigned char swif_clk: SWIF transfer speed(k unit)
//------------------------------------------------------------------------------

void init_swif_set(unsigned char swif_clk)
{
        unsigned int one_time_uint_cycles;


        P2SEL  &= ~0x08;                         // p2.3 tx
        P2SEL  &= ~0x10;                         // p2.4 rx

        P2DIR  &=  ~0x10;                         // make it input
        P2DIR  |=  0x08;                         // make it output

        P2OUT &=  ~0x08;                         //        Make Low

        one_time_uint_cycles = MASTER_CLOCK_KHZ/swif_clk;

        DUTY_CYCLE_50 = one_time_uint_cycles >>1;
        DUTY_CYCLE_25 = DUTY_CYCLE_50>>1;
        DUTY_CYCLE_75 = DUTY_CYCLE_50  + DUTY_CYCLE_25 ;

}

//------------------------------------------------------------------------------
//  delay_cycles
//
//  DESCRIPTION:
//  delay cpu cycles.
//------------------------------------------------------------------------------
void delay_cycles(unsigned int delay_cycles)
{
        unsigned char count[4];
        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 SWIFSendSymbol(uint8_t sym)
//
//  DESCRIPTION:
//  Send symbol "sym" to lmp91300 on the SWIF TX pin.
//------------------------------------------------------------------------------

void SWIF_send_symbol(uint8_t sym)
{

        P2OUT &= SET_TX_HIGH;

        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;
                }
        }

        //        P2OUT &= SET_TX_LOW;       // assert PRI_TX_EN_N
        P2OUT |= SET_TX_LOW;
        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) > RD_TIME_UINT)        //8kbit, 1 time unit is 3125 (125* 25)
                        return 0;

                if ((P2IN & SWIF_INPUT)==0x10)
                        break;

        }while (1);


        do {
               
                {//wait for input become low
                        cur_clk_e = RTCNT2;
                        cur_clk_e <<=8;
                        cur_clk_e |=RTCNT1;


                }


                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);


        one_time_uint_cycles = cur_clk_e  - cur_clk_s-5 ;

        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) > RD_TIME_UINT)        //8kbit, 1 time unit is 3125 (125* 25)
                        return 0xFF;
                //wait for low
                if ((P2IN & SWIF_INPUT)==0x10)
                        break;

        }while (1);

        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) > RD_TIME_UINT) { //8kbit, 1 time unit is 3125 (125* 25)
                        return 0XFF;
                }
                //wait for high
                if ((P2IN & SWIF_INPUT)==0x0)
                        break;

        }while (1);



        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
//------------------------------------------------------------------------------

void SWIF_read_reg(unsigned char cmd,unsigned char swif_capture_data[2])
{
        unsigned char data;
        unsigned int cur_clk;
        int i;



        //send read command
        SWIF_send_symbol(IDLE_SYM);
        SWIF_write_byte(cmd);
        SWIF_send_symbol(IDLE_SYM);

        //end transfer

        P2OUT &= SET_TX_HIGH;
        P2OUT &= SET_TX_HIGH;
        P2OUT &= SET_TX_HIGH;
        P2OUT |= SET_TX_LOW;

        //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 {


                if ((P2IN & SWIF_INPUT)==0x10) {//wait for input become high
                        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;
                        break;
                }

        }while (1);




        if (SWIF_get_idle() ==0) { //for reading, the first symbol must be idle
                return ;
        }

        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);
        }

        swif_capture_data[0] = data;

        //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_cycles(4*125*25);

}

//------------------------------------------------------------------------------
//  void SWIF_read_data
//
//  DESCRIPTION:
//  read data from lmp91300 by swif interface, this is for stream mode
//  unsigned char swif_capture_data[2]: the buffer to store the received data
//  return: none
//------------------------------------------------------------------------------

void SWIF_read_data(unsigned char swif_capture_data[2])
{
        unsigned char data;
        unsigned char cmd;

        unsigned int cur_clk;
        int i;

        //  init_swif_set(ctrl_data[FPGA_SPI_CFG]);
        init_swif_set(7);


        cmd =0xFA;//read address 0x7a|readflag

        //send read command
        SWIF_send_symbol(IDLE_SYM);
        SWIF_write_byte(cmd);
        SWIF_send_symbol(IDLE_SYM);

        //end transfer

        P2OUT &= SET_TX_HIGH;
        P2OUT &= SET_TX_HIGH;
        P2OUT &= SET_TX_HIGH;
        P2OUT |= SET_TX_LOW;

        //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 {


                if ((P2IN & SWIF_INPUT)==0x10) {//wait for input become high
                        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;
                        break;
                }

        }while (1);




        if (SWIF_get_idle() ==0) { //for reading, the first symbol must be idle
                return ;
        }

        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--) {
                data |= (SWIF_get_sym()<< i);
        }

        swif_capture_data[0] = data;

        data  =0;
        for ( i=7; i>=0; i--) {
                //output MSB first
                data |= (SWIF_get_sym()<< i);
        }

        swif_capture_data[1] = 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 SWIF_write_reg(unsigned char cmd, unsigned char data[2], unsigned char data_width)
{

        //send idle
        SWIF_send_symbol(IDLE_SYM);
        //write write command
        SWIF_write_byte(cmd);

        //write data
        SWIF_write_byte(data[0]);

        if (data_width)//if it is 16 bit data
                SWIF_write_byte(data[1]);

        //send idle
        SWIF_send_symbol(IDLE_SYM);

        P2OUT &= SET_TX_HIGH;
        P2OUT &= SET_TX_HIGH;
        P2OUT &= SET_TX_HIGH;
        P2OUT |= SET_TX_LOW;


}
//------------------------------------------------------------------------------
// unsigned char SWIF_Transfer
//
//  DESCRIPTION:
//  perform SWIF transfer
// unsigned char *ctrl_data: data package
//  return: none
//------------------------------------------------------------------------------

unsigned char  SWIF_Transfer(unsigned char *ctrl_data)
{

        unsigned char swif_capture_cmd;
        unsigned char swif_capture_data[2];
        unsigned char rw_flag;
        unsigned char data_width;


        init_swif_set(ctrl_data[FPGA_SPI_CFG]);
        // init_swif_set(7);

        //get address
        swif_capture_cmd = ctrl_data[FPGA_SPI_ADDR_H];

        //get read/write flag
        rw_flag = (ctrl_data[FPGA_SPI_CMD]>>1)&1;

        swif_capture_cmd |= ((( ctrl_data[FPGA_SPI_CMD]>>1)&1 ) <<7);

        data_width = (ctrl_data[FPGA_SPI_CMD]>>3) & 3;
        //get data
        swif_capture_data[0] =  ctrl_data[FPGA_SPI_DATA_H];//if the data is 16 bits, it hold the MSB byte, if it is 8bit, it holds LSB
        swif_capture_data[1] =  ctrl_data[FPGA_SPI_DATA_L];//if the data is 16 bits, it hold the LSB byte,

        if (rw_flag) {// rw_flag ==1: read)
                SWIF_read_reg(swif_capture_cmd,swif_capture_data);

                ctrl_data[FPGA_SPI_DATA_H] = swif_capture_data[0];//if the data is 16 bits, it hold the MSB byte, if it is 8bit, it holds LSB
                ctrl_data[FPGA_SPI_DATA_L] = swif_capture_data[1];//if the data is 16 bits, it hold the LSB byte,

        } else {
                SWIF_write_reg(swif_capture_cmd, swif_capture_data, data_width);
        }


        return 0;


}

//-------------------------------------------------------------------------------------------



使用特权

评论回复

相关帖子

沙发
externally| | 2019-12-23 19:40 | 只看该作者
感谢楼主分享!学习一下

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:qq群: 嵌入式系统arm初学者 224636155←← +→→点击-->小 i 精品课全集,21ic公开课~~←←→→点击-->小 i 精品课全集,给你全方位的技能策划~~←←

2759

主题

19243

帖子

104

粉丝