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