This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

How To Operate I2C On DSP Side In DM6467

I have some trouble in DM6467 about operating I2C on DSP side

I am acknowledged that there is no address mapping for I2C on DSP side through TI's datasheet for DM6467

But I must operate I2C on DSP side as my boss's command.

In my DM6467's project : drivers, applictions are working on ARM side, algrithm is working on DSP side. And, now, I must operate I2C in algrithm(DSP side). 

So, I want to grab some help from TI's experts. Is there any suggestion?

  • Is there anyone would give me some suggestion?

  • As per the datasheet (http://www.ti.com/lit/gpn/tms320dm6467), I2C is not accessble from DSP. For example, look at the Memory Map Table (Page 23). The I2C memory range (0x01C2 1000 to 0x01C2 13FF) is not accessble from DSP.

    Regards, Srirami.

  • I have read these content before.

    But my boss require me operating I2C from DSP, he give me a third-part's sample(some codes in the following), and he say it can work on their DM6467

    I found it can work normally after planting and experiment.

    I am confused by this experiment and TI's description from the datasheet : why it can work normally ?

    I am not sure that is there any potential danger. Is there any conflict with ARM's I2C operating, or other errors ?

    So, Please TI's experts check these codes.

    I2C define header file:

    /*
     *  Copyright 2007 by Spectrum Digital Incorporated.
     *  All rights reserved. Property of Spectrum Digital Incorporated.
     */

    /*
     *  I2C header file
     *
     */

    #ifndef I2C_
    #define I2C_

    #ifdef __cplusplus
    extern "C" {
    #endif

    #include "evmdm6467.h"

    /* ------------------------------------------------------------------------ *
     *  I2C Controller                                                          *
     * ------------------------------------------------------------------------ */
    #define I2C_BASE                0x01c21000
    #define I2C_OAR                 *( volatile Uint32* )( I2C_BASE + 0x0 )
    #define I2C_ICIMR               *( volatile Uint32* )( I2C_BASE + 0x4 )
    #define I2C_ICSTR               *( volatile Uint32* )( I2C_BASE + 0x8 )
    #define I2C_ICCLKL              *( volatile Uint32* )( I2C_BASE + 0xc )
    #define I2C_ICCLKH              *( volatile Uint32* )( I2C_BASE + 0x10 )
    #define I2C_ICCNT               *( volatile Uint32* )( I2C_BASE + 0x14 )
    #define I2C_ICDRR               *( volatile Uint32* )( I2C_BASE + 0x18 )
    #define I2C_ICSAR               *( volatile Uint32* )( I2C_BASE + 0x1c )
    #define I2C_ICDXR               *( volatile Uint32* )( I2C_BASE + 0x20 )
    #define I2C_ICMDR               *( volatile Uint32* )( I2C_BASE + 0x24 )
    #define I2C_ICIVR               *( volatile Uint32* )( I2C_BASE + 0x28 )
    #define I2C_ICEMDR              *( volatile Uint32* )( I2C_BASE + 0x2c )
    #define I2C_ICPSC               *( volatile Uint32* )( I2C_BASE + 0x30 )
    #define I2C_ICPID1              *( volatile Uint32* )( I2C_BASE + 0x34 )
    #define I2C_ICPID2              *( volatile Uint32* )( I2C_BASE + 0x38 )

    /* ------------------------------------------------------------------------ *
     *  I2C Status                                                              *
     * ------------------------------------------------------------------------ */
    #define ICSTR_SDIR              0x4000
    #define ICSTR_NACKINT           0x2000
    #define ICSTR_BB                0x1000
    #define ICSTR_RSFULL            0x0800
    #define ICSTR_XSMT              0x0400
    #define ICSTR_AAS               0x0200
    #define ICSTR_AD0               0x0100
    #define ICSTR_SCD               0x0020
    #define ICSTR_ICXRDY            0x0010
    #define ICSTR_ICRRDY            0x0008
    #define ICSTR_ARDY              0x0004
    #define ICSTR_NACK              0x0002
    #define ICSTR_AL                0x0001

    /* ------------------------------------------------------------------------ *
     *  I2C Commands                                                            *
     * ------------------------------------------------------------------------ */
    #define ICMDR_NACKMOD           0x8000
    #define ICMDR_FREE              0x4000
    #define ICMDR_STT               0x2000
    #define ICMDR_IDLEEN            0x1000
    #define ICMDR_STP               0x0800
    #define ICMDR_MST               0x0400
    #define ICMDR_TRX               0x0200
    #define ICMDR_XA                0x0100
    #define ICMDR_RM                0x0080
    #define ICMDR_DLB               0x0040
    #define ICMDR_IRS               0x0020
    #define ICMDR_STB               0x0010
    #define ICMDR_FDF               0x0008
    #define ICMDR_BC_MASK           0x0007

    /* ------------------------------------------------------------------------ *
     *  Prototypes                                                              *
     * ------------------------------------------------------------------------ */
    /* Setup & Quit */
    Int16 EVMDM6467_I2C_init ( );
    Int16 EVMDM6467_I2C_close( );

    /* Read & Write */
    Int16 EVMDM6467_I2C_read ( Uint16 address, Uint8* rx, Uint16 len );
    Int16 EVMDM6467_I2C_write( Uint16 address, Uint8* tx, Uint16 len );

    #ifdef __cplusplus
    }
    #endif

    #endif

    I2C operating .cpp file

    #include "stdio.h"
    #include "evmdm6467_i2c.h"

    /* I2C Address */
    #define DS28CN_I2C_ADDR             0x55


    static Int32 i2c_timeout = ( 0x00010000 );

    /* ------------------------------------------------------------------------ *
     *                                                                          *
     *  _wait( delay )                                                          *
     *      Wait in a software loop for 'x' delay                               *
     *                                                                          *
     * ------------------------------------------------------------------------ */
    void EVMDM6467_wait( Uint32 delay )
    {
        volatile Uint32 i;
        for ( i = 0 ; i < delay ; i++ ){ };
    }

    /* ------------------------------------------------------------------------ *
     *                                                                          *
     *  _waitusec( usec )                                                       *
     *      Wait in a software loop for 'x' microseconds                        *
     *                                                                          *
     * ------------------------------------------------------------------------ */
    void EVMDM6467_waitusec( Uint32 usec )
    {
        #ifdef ARM_SIDE
            EVMDM6467_wait( usec * 2 );
        #elif DSP_SIDE
            EVMDM6467_wait( usec * 28 );
        #endif
    }

    /* ------------------------------------------------------------------------ *
     *                                                                          *
     *  _waitmsec( msec )                                                       *
     *      Wait in a software loop for 'x' milliseconds                        *
     *                                                                          *
     * ------------------------------------------------------------------------ */
    void EVMDM6467_waitmsec( Uint32 msec )
    {
        _waitusec( 1000 * msec );
    }
    /* ------------------------------------------------------------------------ *
     *                                                                          *
     *  _I2C_init( )                                                            *
     *      Setup I2C module                                                    *
     *                                                                          *
     * ------------------------------------------------------------------------ */
    Int16 EVMDM6467_I2C_init( )
    {
        /* Reset I2C */
        I2C_ICMDR = 0;

        /*
         *  Setup I2C SCL clock
         *      [ 27 MHz input ] -> [ 100 kHz output ]
         */
        I2C_ICPSC = 337;
        I2C_ICCLKL = 4;
        I2C_ICCLKH = 4;

        /* Release from Reset */
        I2C_ICMDR |= ICMDR_IRS;
        return 0;
    }

    /* ------------------------------------------------------------------------ *
     *                                                                          *
     *  _I2C_close( )                                                           *
     *      Close I2C module                                                    *
     *                                                                          *
     * ------------------------------------------------------------------------ */
    Int16 EVMDM6467_I2C_close( )
    {
        /* Reset I2C */
        I2C_ICMDR = 0;
        return 0;
    }

    /* ------------------------------------------------------------------------ *
     *                                                                          *
     *  _I2C_reset( )                                                           *
     *      Reset I2C module.                                                   *
     *                                                                          *
     *      Used in order to bring SDA & SCL to HIGH.  This can be used after   *
     *      issuing a command to an I2C device, but sends back no response to   *
     *      the host.                                                           *
     *                                                                          *
     * ------------------------------------------------------------------------ */
    static Int16 _I2C_reset( )
    {
        /* Reset I2C */
        EVMDM6467_I2C_init( );
        return -1;
    }

    /* ------------------------------------------------------------------------ *
     *                                                                          *
     *  _I2C_tx_ready( timeout )                                                *
     *      Wait for TX ready, if not then return timeout.                      *
     *                                                                          *
     *      Returns:                                                            *
     *              0 -> I2C TX Ready                                           *
     *             -1 -> I2C Timeout                                            *
     *                                                                          *
     * ------------------------------------------------------------------------ */
    static Int16 _I2C_tx_ready( Int32 timeout )
    {
        while ( ! ( I2C_ICSTR & ICSTR_ICXRDY ) )// Wait while not Ready
            if ( timeout-- <= 0  )
                return _I2C_reset( );           // Reset I2C

        return 0;                               // TX Ready
    }

    /* ------------------------------------------------------------------------ *
     *                                                                          *
     *  _I2C_write( address, tx, len )                                          *
     *      Write to I2C device                                                 *
     *                                                                          *
     *      Inputs:                                                             *
     *              address     <- device address                               *
     *              tx          <- data                                         *
     *              len         <- #bytes to write                              *
     *                                                                          *
     *      Returns:                                                            *
     *              0 -> Pass                                                   *
     *             +1 -> Fail                                                   *
     *                                                                          *
     * ------------------------------------------------------------------------ */
    Int16 EVMDM6467_I2C_write( Uint16 address, Uint8* tx, Uint16 len )
    {
        Int16 i;
        Uint8* tx8 = tx;

        I2C_ICCNT = len;                        // Set length
        I2C_ICSAR = address;                    // Set I2C slave address
        I2C_ICMDR = ICMDR_STT                   // Set DSP for Master Write
                  | ICMDR_TRX                   // START
                  | ICMDR_MST
                  | ICMDR_IRS
                  | ICMDR_FREE;

        _wait( 10 );

        for ( i = 1 ; i <= len ; i++ )          // Write from 1 byte onward
        {
            I2C_ICDXR = *tx8++;                 // Write 1 byte
            if ( _I2C_tx_ready( i2c_timeout ) ) // Wait for TX Ready
                return i;
        }
        EVMDM6467_waitmsec(30);
        I2C_ICMDR |= ICMDR_STP;                 // STOP
        return 0;
    }

    /* ------------------------------------------------------------------------ *
     *                                                                          *
     *  _I2C_rx_ready( timeout )                                                *
     *      Wait for RX ready, if not then return timeout.                      *
     *                                                                          *
     *      Returns:                                                            *
     *              0 -> I2C Rx Ready                                           *
     *             -1 -> I2C Timeout                                            *
     *                                                                          *
     * ------------------------------------------------------------------------ */
    static Int16 _I2C_rx_ready( Int32 timeout )
    {
        while ( ! ( I2C_ICSTR & ICSTR_ICRRDY ) )// Wait while not Ready
            if ( timeout-- < 0 )
                return _I2C_reset( );           // Reset I2C

        return 0;                               // RX Ready
    }

    /* ------------------------------------------------------------------------ *
     *                                                                          *
     *  _I2C_read( address, rx, len )                                           *
     *      Read from I2C device                                                *
     *                                                                          *
     *      Inputs:                                                             *
     *              address     <- device address                               *
     *              rx          <- data                                         *
     *              len         <- #bytes to read                               *
     *                                                                          *
     *      Returns:                                                            *
     *              0 -> Pass                                                   *
     *             +1 -> Fail                                                   *
     *                                                                          *
     * ------------------------------------------------------------------------ */
    Int16 EVMDM6467_I2C_read( Uint16 address, Uint8* rx, Uint16 len )
    {
        Int16 i;
        Uint8* rx8 = rx;

        I2C_ICCNT = len;                        // Set length
        I2C_ICSAR = address;                    // Set I2C address
        I2C_ICMDR = ICMDR_STT                   // Set for Master Read
                  | ICMDR_MST                   // START
                  | ICMDR_IRS
                  | ICMDR_FREE;

        _wait( 10 );

        for ( i = 1 ; i <= len ; i++ )          // Read from 1 byte onward
        {
            if ( _I2C_rx_ready( i2c_timeout ) ) // Wait for Rx Ready
                return i;

            *rx8++ = I2C_ICDRR;                 // Read 1 byte
        }

        I2C_ICMDR |= ICMDR_STP;                 // STOP
        return 0;
    }

    /* ------------------------------------------------------------------------ *
     *                                                                          *
     *  DAVINCIEVM_DS28CN_init( )                                               *
     *                                                                          *
     *      Initialize the I2C DS28CN                                           *
     *                                                                          *
     * ------------------------------------------------------------------------ */
    Int16 DAVINCIEVM_DS28CN_init( )
    {
        return 0;
    }

    /* ------------------------------------------------------------------------ *
     *                                                                          *
     *  DAVINCIEVM_DS28CN_read( src, dst, length )                              *
     *                                                                          *
     *      Read from the I2C DS28CN                                            *
     *                                                                          *
     * ------------------------------------------------------------------------ */
    Int16 DAVINCIEVM_DS28CN_read( Uint8 src, Uint8 dst, Uint8 length)
    {
      
        Uint8 addr,flag;
        flag=0;
        addr = src;         // register address
        /* Send 8-bit address */
    //    flag|=DAVINCIEVM_I2C_write( DS28CN_I2C_ADDR,  &addr, 1 );
        flag|=EVMDM6467_I2C_write(DS28CN_I2C_ADDR,&addr,1);
        /* Wait for DS28CN to process */
    //    DAVINCIEVM_waitusec( 10 );

        /* Read data */
    //    flag|=DAVINCIEVM_I2C_read ( DS28CN_I2C_ADDR,  &dst , length );
        flag|=EVMDM6467_I2C_read(DS28CN_I2C_ADDR, &dst,length);
         return dst;  
    }

    /* ------------------------------------------------------------------------ *
     *                                                                          *
     *  DAVINCIEVM_DS28CN_write( src, dst,length )                              *
     *                                                                          *
     *      Write to the I2C DS28CN                                             *
     *                                                                          *
     * ------------------------------------------------------------------------ */
    Int16 DAVINCIEVM_DS28CN_write( Uint8 *src, Uint8 Command, Uint8 dst)
    {
        Uint8 data[8+2];
        Uint8 i,flag;


        Uint8* psrc8 = ( Uint8* )src;
        Uint8* pdst8 = &data[2];
        flag=0;
      
     data[1] = Command;
        data[0] = dst;       // low address

            
        /* Fill in data */
        for ( i = 0 ; i < 8 ; i++ )
            *pdst8++ = *psrc8++;

        /* Send 8-bit address and data */
       
        flag|=EVMDM6467_I2C_write(DS28CN_I2C_ADDR,data,10);
        return 0;
    }


    void ReadDS28RomID(unsigned char *p)
    {
        short i;

    //  read rom id
        for(i=0;i<8;i++)
        {
      p[i]=DAVINCIEVM_DS28CN_read(0xA0+i, p[i],1); 
        }
    }


    #define ID_TOTAL 9
    int CheckDS28CNRomID(void)
    {
     int i,j;
     static unsigned char ID[ID_TOTAL][8]=
      {{0x70,0x55,0xc5,0x1f,00,00,00,0x44},
       {0x70,0x07,0x6c,0x1f,00,00,00,0xc4},
       {0x70,0xfc,0x6b,0x1f,00,00,00,0x1f},
       {0x70,0x10,0x6c,0x1f,00,00,00,0x1a},
       {0x70,0xaf,0xc5,0x1f,00,00,00,0xf9},
       {0x70,0xe1,0x6e,0x1f,00,00,00,0xdc},
       {0x70,0xfc,0x6b,0x1f,00,00,00,0x1f},
       {0x70,0x26,0x79,0x1f,00,00,00,0xeb},
       {0x70,0xd4,0xc5,0x1f,00,00,00,0x99}};

     unsigned char buf[8];

     ReadDS28RomID(buf);
     for(i=0;i<ID_TOTAL;i++) {
      for(j=0;j<8;j++)
       if (buf[j]!=ID[i][j]) break;
      
      if (j==8) return 1;
     }
     return 0;
    }

    //Read DS28CN01 memory data
    //MemoryAddress:initial read address
    //GetPageData:the data read from DS28CN01
    //DataLength:read data number

    int ReadMemoryPage(unsigned char MemoryAddress, unsigned char *GetPageData, unsigned char DataLength)
    {
        short i;      
        for(i=0;i<DataLength;i++)
     {
      GetPageData[i]=DAVINCIEVM_DS28CN_read(MemoryAddress+i, GetPageData[i],1);
     }
     
     return *GetPageData; 
    }

    void HardIDInit(void)
    {
        unsigned char data[3];
     
        EVMDM6467_I2C_init( );
    //    EVMDM6467_init( );
     
      /*配置DS28CN01为IIC工作方式*/
        data[1]=0xA8;
        data[0]=0x00;
        EVMDM6467_I2C_write(DS28CN_I2C_ADDR,data,2);
    }

    int GetHardID(unsigned char *pLicence)
    {
     ReadDS28RomID(pLicence);
     return 0;
    }

    int GetLicence(unsigned char *pLicence)
    {
        int ret;

        ReadMemoryPage(0, pLicence, 32);
        ReadMemoryPage(0x20, pLicence+32, 32);

     return 0;
    }

    /*
    DS28CN_test( )
    {  
     
        unsigned char data[3];
        unsigned char AcctPageNum, TargetAddress;   //Authenticated page number
     unsigned char PageData[32]; 
     
    //  配置DS28CN01为IIC工作方式

        data[1]=0xA8;
        data[0]=0x00;

      
    //    DAVINCIEVM_I2C_write(DS28CN_I2C_ADDR,data,2);
     
    //     if( ReadRomID()==1)
           if (1)
           {
             printf("it's right devince\n"); 

     

       
         TargetAddress=0x00;   //the target address to be written with the new data
         AcctPageNum=TargetAddress/0x20;
         ReadMemoryPage(AcctPageNum*0x20, PageData, 32);
          
        printf("PageData 0 is %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
        PageData[0],PageData[1],PageData[2],PageData[3],PageData[4],PageData[5],PageData[6],PageData[7],
        PageData[8],PageData[9],PageData[10],PageData[11],PageData[12],PageData[13],PageData[14],PageData[15],
        PageData[16],PageData[17],PageData[18],PageData[19],PageData[20],PageData[21],PageData[22],PageData[23],
        PageData[24],PageData[25],PageData[26],PageData[27],PageData[28],PageData[29],PageData[30],PageData[31]);
       
       
        TargetAddress=0x20;   //the target address to be written with the new data
        AcctPageNum=TargetAddress/0x20;
        ReadMemoryPage(AcctPageNum*0x20, PageData, 32);
        printf("PageData 1 is %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
        PageData[0],PageData[1],PageData[2],PageData[3],PageData[4],PageData[5],PageData[6],PageData[7],
        PageData[8],PageData[9],PageData[10],PageData[11],PageData[12],PageData[13],PageData[14],PageData[15],
        PageData[16],PageData[17],PageData[18],PageData[19],PageData[20],PageData[21],PageData[22],PageData[23],
        PageData[24],PageData[25],PageData[26],PageData[27],PageData[28],PageData[29],PageData[30],PageData[31]);
      
        TargetAddress=0x40;   //the target address to be written with the new data
        AcctPageNum=TargetAddress/0x20;
        ReadMemoryPage(AcctPageNum * 0x20, PageData, 32);      
        printf("PageData 2 is %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
        PageData[0],PageData[1],PageData[2],PageData[3],PageData[4],PageData[5],PageData[6],PageData[7],
        PageData[8],PageData[9],PageData[10],PageData[11],PageData[12],PageData[13],PageData[14],PageData[15],
        PageData[16],PageData[17],PageData[18],PageData[19],PageData[20],PageData[21],PageData[22],PageData[23],
        PageData[24],PageData[25],PageData[26],PageData[27],PageData[28],PageData[29],PageData[30],PageData[31]);
       
        TargetAddress=0x60;   //the target address to be written with the new data
        AcctPageNum=TargetAddress/0x20;
        ReadMemoryPage(AcctPageNum * 0x20, PageData, 32);      
        printf("PageData 3 is %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n",
        PageData[0],PageData[1],PageData[2],PageData[3],PageData[4],PageData[5],PageData[6],PageData[7],
        PageData[8],PageData[9],PageData[10],PageData[11],PageData[12],PageData[13],PageData[14],PageData[15],
        PageData[16],PageData[17],PageData[18],PageData[19],PageData[20],PageData[21],PageData[22],PageData[23],
        PageData[24],PageData[25],PageData[26],PageData[27],PageData[28],PageData[29],PageData[30],PageData[31]);
        }   
         else
           printf("it's not right devince\n"); 
         return 0;
    }
    */