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.

RTOS/TM4C123GH6PM: Does TI RTOS I2C API support I2C high speed mode (3.3MHz) for TM4C ?

Part Number: TM4C123GH6PM
Other Parts Discussed in Thread: SYSBIOS

Tool/software: TI-RTOS

Hi,

  I have successfully access an external I2C nvSRAM (Cypress FM24V01A) on my Tiva-C launchpad  in 100KHz, 400KHZ and 1MHz speed with I2C APIs of TI-RTOS (v2.16). But due to bandwidth limitation of the project, I need to access with high-speed mode (3.3MHz). 

  I followed section 16.3.2.2 and 16.4.2 of TM4C datasheet to configure in I2C high-speed mode, but it always halts at exception. I attach my code here below and the CCS screen shot when halts. 

  Please help to advise how to fix this issue , or  does TI RTOS I2C API support I2C high speed mode (3.3MHz) for TM4C ?

  Thanks in advance.

Eric

"i2c_rtos_main.c"

/*
 * Copyright (c) 2015, Texas Instruments Incorporated
 * All rights reserved.
 *
 * 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.
 */


/* XDCtools Header files */
#include <Board_EQU.h>
#include <xdc/std.h>
#include <xdc/cfg/global.h>
#include <xdc/runtime/System.h>
#include <xdc/runtime/Timestamp.h>
#include <xdc/runtime/Log.h>

/* BIOS Header files */
#include <ti/sysbios/BIOS.h>


/* TI-RTOS Header files */
#include <ti/drivers/GPIO.h>
#include <ti/drivers/I2C.h>



/* Example/Board Header files */
#include "inc/hw_gpio.h"
#include "inc/hw_memmap.h"
#include "inc/hw_sysctl.h"
#include "inc/hw_types.h"
#include "inc/hw_i2c.h"


//============================================================================
//
// Project target: access external I2C nvSRAM (FM24V01A) using TM4C I2C high-speed mode (3.3MHz) under TI RTOS
// H/W: Tiva-C launchpad
// MCU Working Freq: 80MHz
// CCS ver: v6.12
// TI RTOS ver: v2.16
//
// Note: this program accesses the nvSRAM like a champ in 100KHz, 400KHz, and 1MHz mode, but halts at exception
//          when executing in high speed mode (3.3MHz), no matter the high speed master code is sent
//          before entering BIOS or during BIOS. (refer to the following "conditional compile setting" section )
//         
//============================================================================

// === conditional compile setting =======================================================
//#define DEF_I2C_HIGH_SPEED_3M3_BEFORE_BIOS    1    // send high speed master code before entering TI RTOS
#define DEF_I2C_HIGH_SPEED_3M3_IN_BIOS        1    // send high speed master code while TI RTOS running

// === defined parameters ============================================================
#define I2C_SLAVE_ADDR_FRAM        (0xa0 >>1)    // slave device address for FRAM
#define MASTER_CODE_BYTE_HS        0x08            // refet to TM4C datasheet 16.3.2.2
#define CONTROL_BYTE_HS            0x13            // refet to TM4C datasheet 16.3.2.2
        
// === global variables ===============================================================
I2C_Handle          handle;
I2C_Params          i2cParams;
I2C_Transaction     i2cTransaction;

// === code starts here ===============================================================
void    Send_I2C_High_Speed_Master_Code( void )
{            
    HWREG(I2C0_BASE + I2C_O_MSA) = MASTER_CODE_BYTE_HS;            
    HWREG(I2C0_BASE + I2C_O_MCS) = CONTROL_BYTE_HS ;                                                        
}

void    Init_I2C_FRAM( void )
{                
    I2C_Params_init(&i2cParams);
    
    i2cParams.bitRate = I2C_400kHz;
    
    handle = I2C_open( Board_I2C0, &i2cParams );

    if (handle == NULL)
        System_abort("I2C was not opened");    
    else
    {                    
                                
        #ifdef DEF_I2C_HIGH_SPEED_3M3_BEFORE_BIOS                                                                                                                                                            
            Send_I2C_High_Speed_Master_Code();                
        #endif
                                        
        // set timer period for 1MHz when fast plus mode, or 3.3MHz when high speed mode
        HWREG(I2C0_BASE + I2C_O_MTPR) &= 0x00;
        HWREG(I2C0_BASE + I2C_O_MTPR) |= 0x03;                    
                    
    }                    
}

void    fun_write_FRAM( uint8_t *data_ptr, uint16_t fram_addr, uint16_t transfer_cnt )
{
    unsigned int        i = 0;
    uint8_t                 txBuffer[256+3];

    #ifdef DEF_I2C_HIGH_SPEED_3M3_IN_BIOS
        Send_I2C_High_Speed_Master_Code();
    #endif
                
    i2cTransaction.slaveAddress = I2C_SLAVE_ADDR_FRAM;

    i2cTransaction.readCount = 0;                // clear read-parameters when not read access
    i2cTransaction.readBuf = NULL;
    
    txBuffer[0] = (uint8_t) (fram_addr >> 8);   //HB Addr
    txBuffer[1] = (uint8_t) (fram_addr & 0xff);  //LB Addr
    
    for( i=0; i< transfer_cnt; i++ )        
        txBuffer[i+2] = *(data_ptr+i);        
    
    i2cTransaction.writeBuf = txBuffer;         // set valid write-parameters for write access    
    i2cTransaction.writeCount = transfer_cnt+2;
    
    if (!I2C_transfer(handle, &i2cTransaction))
    {
        System_printf("Bad I2C transfer ( I2C Write) !");
        System_flush();
    }                
    
}

void    fun_read_FRAM( uint8_t *data_ptr, uint16_t fram_addr, uint16_t transfer_cnt )
{

    uint8_t                txBuffer[3];

    #ifdef DEF_I2C_HIGH_SPEED_3M3_IN_BIOS
        Send_I2C_High_Speed_Master_Code();
    #endif
    
    i2cTransaction.slaveAddress = I2C_SLAVE_ADDR_FRAM;

    txBuffer[0] = (uint8_t) (fram_addr >> 8);   //HB Addr
    txBuffer[1] = (uint8_t) (fram_addr & 0xff);  //LB Addr
    
    i2cTransaction.writeBuf = txBuffer;            // clear write-parameters when not write access
    i2cTransaction.writeCount = 2;
    
    i2cTransaction.readBuf = data_ptr ;
    i2cTransaction.readCount = transfer_cnt;        // set valid read-parameters for read access
    
    
                    
    if (!I2C_transfer(handle, &i2cTransaction))
    {
        System_printf("Bad I2C transfer ( I2C Read) !");
        System_flush();

    }                
    
}
    
void    fun_Access_FRAM( void )
{                
    
        uint16_t    i;
        unsigned char    FRAM_pattern[16], FRAM_rd_byte[16];
    
        unsigned char    flag;
        
        for( i=0; i < 16; i++ )        
            FRAM_pattern[i]= ( i&0x01) ? i : ~i ;
                            
        fun_write_FRAM( FRAM_pattern, 0,  16 );    // write 16-byte test pattern to FRAM        
        fun_read_FRAM( FRAM_rd_byte,  0, 16 );    // read 16-byte test pattern to FRAM and verfiy
        
        for( i=0, flag=TRUE; flag==TRUE && i < 16; i++ )
        {
            if( FRAM_rd_byte[i] != FRAM_pattern[i] )
                flag= FALSE;                                                                                                                                                                            
                
        }        
}
        

void Task_FRAM(void)
{
    while(1)
    {
        Task_sleep(10);
        fun_Access_FRAM();
    }
}



int main(void)
{
    /* Call board init functions. */
    Board_initGeneral();
    Board_initGPIO();
    Board_initSPI();
    Board_initI2C();
        
    Init_I2C_FRAM();            
        
    
    System_printf("TI-RTOS I2C High-speed Test v1.0.0 ... \n");
    System_flush();
    
        
    /* Start BIOS */
    BIOS_start();
    
    return (0);
}


  • Hi Eric,

    Can you post the error message you are receiving?

    Regards,

    -- Emmanuel

  • Hi, Emmanuel:
    I did paste the error screen shot (JPG) in CCS, but not sure why it's gone in the post. The exception traps at " length = _CIOBUF_[0];" in the "trgmsg.c" as in the following,

    Eric

    /***************************************************************************/
    /* */
    /* __TI_readmsg() - Reads the data and parameters passed from the host. */
    /* */
    /***************************************************************************/
    void __TI_readmsg(register unsigned char *parm,
    register char *data)
    {
    volatile unsigned char *p = (volatile unsigned char *)(_CIOBUF_+1);
    unsigned int i;
    unsigned int length;

    /***********************************************************************/
    /* THE LENGTH IS READ AS A TARGET INT */
    /***********************************************************************/
    length = _CIOBUF_[0]; //<<<<< CCS exception traps Here if I2C_Transfer() in high speed mode (3.3MHz)

    /***********************************************************************/
    /* UNPACK THE PARAMETERS AND DATA */
    /***********************************************************************/
    for (i = 0; i < 8; i++) *parm++ = UNPACKCHAR(p, i);
    if (data != NULL)
    for (i = 0; i < length; i++) *data++ = UNPACKCHAR(p, i+8);
    }
  • Eric Chen49 said:
    The exception traps at " length = _CIOBUF_[0];" in the "trgmsg.c" as in the following,

    That code in trgmsg.c is used as the CIO mechanism used to report System_printf() output to the CIO console in the CCS debugger.

    Not sure why the debugger is stopping there, but if you place a breakpoint on the System_printf("Bad I2C transfer ( I2C Write) !"); and System_printf("Bad I2C transfer ( I2C Read) !"); statements does the breakpoint get hit? i.e. meaning has an I2C transfer failed?

  • breakpoint set at 2 different conditions and lead to different weird result as below,


    1) breakpoints at both "System_printf("Bad I2C transfer ( I2C Write) !");"  & "System_printf("Bad I2C transfer ( I2C Read) !");"

        result: CCS debugger stops and shows "No source available for "0x3b70",   click "View Disassembly" and the "Disassembly" tab shows the following


             
              ti_sysbios_family_arm_lm4_Timer_Module_startup__E():
    00003b18:   E92D43F8            push.w     {r3, r4, r5, r6, r7, r8, r9, lr}
     202          if (Timer_startupNeeded) {
    00003b1c:   4815                ldr        r0, [pc, #0x54]
    00003b1e:   4914                ldr        r1, [pc, #0x50]
    00003b20:   6800                ldr        r0, [r0]
    00003b22:   6809                ldr        r1, [r1]
    00003b24:   4688                mov        r8, r1
    00003b26:   B1F0                cbz        r0, #0x3b66
     203              for (i = 0; i < Timer_numTimerDevices; i++) {
    00003b28:   F1B80F00            cmp.w      r8, #0
    00003b2c:   DD1B                ble        $C$L392
    00003b2e:   2400                movs       r4, #0
    00003b30:   4625                mov        r5, r4
    00003b32:   EA4F0808            mov.w      r8, r8
    00003b36:   46C0                mov        r8, r8
     206                  if ((obj != NULL) && (obj->staticInst)) {
              $C$L390:
    00003b38:   480F                ldr        r0, [pc, #0x3c]
    00003b3a:   6880                ldr        r0, [r0, #8]
    00003b3c:   5821                ldr        r1, [r4, r0]
    00003b3e:   B171                cbz        r1, #0x3b5e
    00003b40:   8888                ldrh       r0, [r1, #4]
    00003b42:   B160                cbz        r0, #0x3b5e
     445          hwiKey = Hwi_disable();
    00003b44:   2220                movs       r2, #0x20
     207                      Timer_postInit(obj, NULL);
    00003b46:   4608                mov        r0, r1
     445          hwiKey = Hwi_disable();
    00003b48:   F3EF8911           .word       0x8911f3ef
    00003b4c:   F3828811           .word       0x8811f382
    00003b50:   460F                mov        r7, r1
     447          Timer_setPeriod(obj, obj->period);
    00003b52:   693E                ldr        r6, [r7, #0x10]
     645          Timer_stop(obj);
    00003b54:   F001FA0C            bl         #0x4f70
     646          obj->period = period;
    00003b58:   613E                str        r6, [r7, #0x10]
     449          Hwi_restore(hwiKey);
    00003b5a:   F3898811           .word       0x8811f389
     203              for (i = 0; i < Timer_numTimerDevices; i++) {
              $C$L391:
    00003b5e:   1C6D                adds       r5, r5, #1
    00003b60:   1D24                adds       r4, r4, #4
    00003b62:   4545                cmp        r5, r8
    00003b64:   DBE8                blt        $C$L390
     211          return (Startup_DONE);
              $C$L392:
    00003b66:   F04F30FF            mov.w      r0, #-1
    00003b6a:   E8BD83F8            pop.w      {r3, r4, r5, r6, r7, r8, r9, pc}
    00003b6e:   46C0                mov        r8, r8
              $C$CON535:
    00003b70:   7DA4                ldrb       r4, [r4, #0x16]                <<<=== exception traps here if breakpoints at "System_printf("Bad I2C transfer ( I2C Write) !");"  & "System_printf("Bad I2C transfer ( I2C Read) !");"
    00003b72:   0000                movs       r0, r0
              $C$CON536:
    00003b74:   7DA8                ldrb       r0, [r5, #0x16]
    00003b76:   0000                movs       r0, r0
              $C$CON537:
    00003b78:   3CE4                subs       r4, #0xe4
    00003b7a:   2000                movs       r0, #0
    15501     {
              ti_sysbios_family_arm_m3_Hwi_create():
    00003b7c:   E92D41F0            push.w     {r4, r5, r6, r7, r8, lr}
    15507         __newobj = xdc_runtime_Core_createObject__I(&ti_sysbios_family_arm_m3_Hwi_Object__DESC__C, 0, &__prms, (xdc_Ptr)__paramsPtr, sizeof(ti_sysbios_family_arm_m3_Hwi_Params), __eb);
    00003b80:   4C15                ldr        r4, [pc, #0x54]
    15501     {



    2) breakpoint at " if (!I2C_transfer(handle, &i2cTransaction)) "
        
        result:  CCS debugger stops and traps in "C:\ti\tirtos_tivac_2_14_00_10\products\bios_6_42_01_20\packages\ti\sysbios\family\arm\lm4\Timer.c" as below
        
        Void Timer_setPeriod(Timer_Object *obj, UInt32 period)    
        {
            Timer_stop(obj);            <<<===  exception trrap here if breakpoint at " if (!I2C_transfer(handle, &i2cTransaction)) "
            obj->period = period;
        }