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.
Tool/software: TI-RTOS
I have set a sensor LTC4151 at address 0xD0 tied to I2C1 interface of Tiva as master. I am attaching a simple code where I send the address of the register I wish to read from the LTC4151 to the slave LTC4151 device
I see that the code I used has been tried by others but I am not able to read data
#define SLAVE_ADDRESS 0xD0 // Address appears from bits 7:1 D0 shifted 1 place to right is 68
#define NUM_OF_I2CBYTES 2
//*****************************************************************************
//
// Main Program to Configure and Use the I2C Master I2C1
//
//*****************************************************************************
int
main(void)
{
// Setup System Clock for 120MHz
//
ui32SysClock = SysCtlClockFreqSet((SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_XTAL_25MHZ |
SYSCTL_CFG_VCO_480), 120000000);
// Enable GPIO for Configuring the I2C Interface Pins
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
// Wait for the Peripheral to be ready for programming
//
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOG));
//
// Configure Pins for I2C1 Master Interface
//
GPIOPinConfigure(GPIO_PG0_I2C1SCL);
GPIOPinConfigure(GPIO_PG1_I2C1SDA);
GPIOPinTypeI2CSCL(GPIO_PORTG_BASE, GPIO_PIN_1);
GPIOPinTypeI2C(GPIO_PORTG_BASE, GPIO_PIN_0);
//
// Stop the Clock, Reset and Enable I2C Module
// in Master Function
//
SysCtlPeripheralDisable(SYSCTL_PERIPH_I2C1);
SysCtlPeripheralReset(SYSCTL_PERIPH_I2C1);
SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);
//
// Wait for the Peripheral to be ready for programming
//
while(!SysCtlPeripheralReady(SYSCTL_PERIPH_I2C1));
// Initialize and Configure the Master Module
//
I2CMasterInitExpClk(I2C1_BASE, ui32SysClock, true);
// --------------------------To Write before read-----------------------
I2CMasterSlaveAddrSet (I2C1_BASE, SLAVE_ADDRESS, false); //set slave address and initiate with write
I2CMasterControl (I2C1_BASE, I2C_MASTER_CMD_SINGLE_SEND); //Send STOP bit
I2CMasterDataPut (I2C1_BASE, 0x00); //Put 0x00 -- send address of register to be read from SLAVE
while (!(I2CMasterBusy(I2C1_BASE))); //Wait till end of transaction
// while ((I2CMasterBusy(I2C1_BASE))); //Wait till end of transaction
I2CMasterSlaveAddrSet (I2C1_BASE, SLAVE_ADDRESS, true); //set slave address and initiate with read
I2CMasterControl (I2C1_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START); //Read the 1st Byte
pui32DataRx[0] = I2CMasterDataGet(I2C1_BASE);
while (!(I2CMasterBusy(I2C1_BASE))); //Wait till end of transaction
// while ((I2CMasterBusy(I2C1_BASE))); //Wait till end of transaction
I2CMasterControl (I2C1_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH); //Read the 2nd Byte
pui32DataRx[1] = I2CMasterDataGet(I2C1_BASE);
while (!(I2CMasterBusy(I2C1_BASE))); //Wait till end of transaction
// while ((I2CMasterBusy(I2C1_BASE))); //Wait till end of transaction
while (1)
{
}
} //end main
The master bus is stuck after I send the address of the register in the slave I want to read. I2C_MCS is 0x1!
I have a TI RTOS program which reads 20 samples from register 0x00 at the set SLAVE ADDRESS. Here the I2C)MCS is 0x20!
I will put a scope and analyze on Monday.
In the mean time I attach both projects (TIRTOS which reads values and the non TI RTOS code which I pasted yesterday in the forum) for your information.
Regards
Pavitra
This is the driver file for TI RTOS Program which seems to read from my LTC4151 devcice
/* * 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. */ /* * ======== i2ctmp006.c ======== */ /* XDCtools Header files */ #include <xdc/std.h> #include <xdc/runtime/System.h> /* BIOS Header files */ #include <ti/sysbios/BIOS.h> #include <ti/sysbios/knl/Task.h> /* TI-RTOS Header files */ #include <ti/drivers/GPIO.h> #include <ti/drivers/I2C.h> /* Example/Board Header files */ #include "Board.h" /**************************Global Variables ***********************************/ uint32_t voltage; uint8_t txBuffer[1]; uint8_t rxBuffer[2]; #define TASKSTACKSIZE 640 Task_Struct task0Struct; Char task0Stack[TASKSTACKSIZE]; /* * ======== taskFxn ======== * Task for this function is created statically. See the project's .cfg file. */ Void taskFxn(UArg arg0, UArg arg1) { unsigned int i; I2C_Handle i2c; I2C_Params i2cParams; I2C_Transaction i2cTransaction; /* Create I2C for usage */ I2C_Params_init(&i2cParams); i2cParams.bitRate = I2C_400kHz; i2c = I2C_open(Board_I2C_LTC4151, &i2cParams); // This i2c handle was Board_I2C_TMP and now is changed for LTC4151 defined in EK_TM4c1294xl.c if (i2c == NULL) { System_abort("Error Initializing I2C\n"); } else { System_printf("I2C Initialized!\n"); } /* Point to the SENSE registers and read its 2 bytes */ txBuffer[0] = 0x00; // write address of the register you want to read i2cTransaction.slaveAddress = Board_LTC4151_ADDR;//Board_TMP006_ADDR; // Change this to Board_LTC4151_ADDR i2cTransaction.writeBuf = txBuffer; i2cTransaction.writeCount = 1; i2cTransaction.readBuf = rxBuffer; // read back 2 bytes from 00 and 01 Regs: data is in 8 ans 4 bits each reg: check data sheet i2cTransaction.readCount = 2; /* Take 20 samples and print them out onto the console */ for (i = 0; i < 20; i++) { if (I2C_transfer(i2c, &i2cTransaction)) { /* Register 0x00 holds 8 MSBs (M7..M0) Bits 7:4 hold data Register 0x01 holds 4 LSBs (L7..L4 B 0 0 0), where B is a busybit and 0s are reserved To make 12 bits Register 0 must be shifted 4 bits to left Register 1 bits 7:4 hold data and must be shifted 4 positions to right to be ORed with shifted Reg 0 values to get 12 bit result */ // temperature = (rxBuffer[0] << 6) | (rxBuffer[1] >> 2); // 12 bits of ADC values are read in: each bit resolution is 0.5mV 2 power 12 represents 2.048 V voltage = ((rxBuffer[0]) << 4 ) | ((rxBuffer[1] >> 4) ) ; voltage *= 0.5; /* * If the MSB is set '1', then we have a 2's complement * negative value which needs to be sign extended */ // if (rxBuffer[0] & 0x80) { // voltage |= 0xF000; // } /* * For simplicity, divide the temperature value by 32 to get rid of * the decimal precision; see TI's TMP006 datasheet */ // temperature /= 32; System_printf("Sample %u: %d (V)\n", i, voltage); } else { System_printf("I2C Bus fault\n"); } System_flush(); Task_sleep(4000); } /* Deinitialized I2C */ I2C_close(i2c); System_printf("I2C closed!\n"); System_flush(); } /* * ======== main ======== */ int main(void) { Task_Params taskParams; /* Call board init functions */ Board_initGeneral(); Board_initGPIO(); Board_initI2C(); /* Construct tmp006 Task thread */ Task_Params_init(&taskParams); taskParams.stackSize = TASKSTACKSIZE; taskParams.stack = &task0Stack; Task_construct(&task0Struct, (Task_FuncPtr)taskFxn, &taskParams, NULL); /* Turn on user LED */ GPIO_write(Board_LED0, Board_LED_ON); System_printf("Starting the I2C example\nSystem provider is set to SysMin." " Halt the target to view any SysMin contents in ROV.\n"); /* SysMin will only print to the console when you call flush or exit */ System_flush(); /* Start BIOS */ BIOS_start(); return (0); }
This is the non TI RTOS (Tivaware Program) which exhibits bus Busy behavior after the Tiva Master attempts to send the register (0x00) to access information.
/* * main.c * * Created on: Apr 26, 2018 * Author: Pramanujam */ #include <stdint.h> #include <stdbool.h> #include "inc/hw_types.h" #include "inc/hw_ints.h" #include "inc/hw_memmap.h" #include "driverlib/gpio.h" #include "driverlib/i2c.h" #include "driverlib/interrupt.h" #include "driverlib/pin_map.h" #include "driverlib/sysctl.h" #include "driverlib/uart.h" #include "utils/random.h" #include "utils/uartstdio.h" #define SLAVE_ADDRESS 0x68 // Address appears from bits 7:1 D0 shifted 1 place to right is 68 #define NUM_OF_I2CBYTES 2 /***************************************************************************** // // Global variables // //*****************************************************************************/ uint32_t pui32DataRx[NUM_OF_I2CBYTES]; void I2C1IntHandler(void) { } //***************************************************************************** // // This function sets up UART0 to be used for a console to display information // as the example is running. // //***************************************************************************** void InitConsole(void) { // // Enable GPIO port A which is used for UART0 pins. // TODO: change this to whichever GPIO port you are using. // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA); // // Configure the pin muxing for UART0 functions on port A0 and A1. // This step is not necessary if your part does not support pin muxing. // TODO: change this to select the port/pin you are using. // GPIOPinConfigure(GPIO_PA0_U0RX); GPIOPinConfigure(GPIO_PA1_U0TX); // // Enable UART0 so that we can configure the clock. // SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0); // // Use the internal 16MHz oscillator as the UART clock source. // UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC); // // Select the alternate (UART) function for these pins. // TODO: change this to select the port/pin you are using. // GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1); // // Initialize the UART for console I/O. // UARTStdioConfig(0, 115200, 16000000); } //***************************************************************************** // // Main Program to Configure and Use the I2C Master I2C1 // //***************************************************************************** int main(void) { uint32_t ui32SysClock; bool bError; // // Setup System Clock for 120MHz // ui32SysClock = SysCtlClockFreqSet((SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_XTAL_25MHZ | SYSCTL_CFG_VCO_480), 120000000); // Set up the serial console to use for displaying messages. This is // just for this example program and is not needed for EPI operation. // InitConsole(); // // Display the setup on the console. // UARTprintf("\033[2J\033[H"); UARTprintf("\r\nExample Code for Tiva I2C1 Master with LTC4151 as slave\n"); // Enable GPIO for Configuring the I2C Interface Pins // SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG); // Wait for the Peripheral to be ready for programming // while(!SysCtlPeripheralReady(SYSCTL_PERIPH_GPIOG)); // // Configure Pins for I2C1 Master Interface // GPIOPinConfigure(GPIO_PG0_I2C1SCL); GPIOPinConfigure(GPIO_PG1_I2C1SDA); GPIOPinTypeI2CSCL(GPIO_PORTG_BASE, GPIO_PIN_1); GPIOPinTypeI2C(GPIO_PORTG_BASE, GPIO_PIN_0); // // Stop the Clock, Reset and Enable I2C Module // in Master Function // SysCtlPeripheralDisable(SYSCTL_PERIPH_I2C1); SysCtlPeripheralReset(SYSCTL_PERIPH_I2C1); SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1); // // Wait for the Peripheral to be ready for programming // while(!SysCtlPeripheralReady(SYSCTL_PERIPH_I2C1)); // Initialize and Configure the Master Module // I2CMasterInitExpClk(I2C1_BASE, ui32SysClock, true); // --------------------------To Write before read----------------------- I2CMasterSlaveAddrSet (I2C1_BASE, SLAVE_ADDRESS, false); //set slave address and initiate with write I2CMasterControl (I2C1_BASE, I2C_MASTER_CMD_SINGLE_SEND); //Send STOP bit I2CMasterDataPut (I2C1_BASE, 0x00); //Put 0x00 -- send address of register to be read from SLAVE while (!(I2CMasterBusy(I2C1_BASE))); //Wait till end of transaction // while ((I2CMasterBusy(I2C1_BASE))); //Wait till end of transaction I2CMasterSlaveAddrSet (I2C1_BASE, SLAVE_ADDRESS, true); //set slave address and initiate with read I2CMasterControl (I2C1_BASE, I2C_MASTER_CMD_BURST_RECEIVE_START); //Read the 1st Byte pui32DataRx[0] = I2CMasterDataGet(I2C1_BASE); while (!(I2CMasterBusy(I2C1_BASE))); //Wait till end of transaction // while ((I2CMasterBusy(I2C1_BASE))); //Wait till end of transaction I2CMasterControl (I2C1_BASE, I2C_MASTER_CMD_BURST_RECEIVE_FINISH); //Read the 2nd Byte pui32DataRx[1] = I2CMasterDataGet(I2C1_BASE); while (!(I2CMasterBusy(I2C1_BASE))); //Wait till end of transaction // while ((I2CMasterBusy(I2C1_BASE))); //Wait till end of transaction UARTprintf("Receiving data %d and data 2 %d from external Slave...\n\n",pui32DataRx[0],pui32DataRx[1]); while (1) { } } //end main
I have not been able to get around to that task.
It does look a timing issue and analogous TI RTOS program is working but this is not.
Will post next week.
Thanks
Actually the SDA and SCL lines were flipped while configuring in my code. Thats why it did not work previously.
Now its working! Thanks
//
GPIOPinConfigure(GPIO_PG0_I2C1SCL);
GPIOPinConfigure(GPIO_PG1_I2C1SDA);
GPIOPinTypeI2C(GPIO_PORTG_BASE, GPIO_PIN_1); // configure SDA
GPIOPinTypeI2CSCL(GPIO_PORTG_BASE, GPIO_PIN_0); // Configure SCL
In the last two lines I had the pin numbers flipped.