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.

TMS320F28P650DK: EEPROM Part Number - 24LC256

Part Number: TMS320F28P650DK


Tool/software:

I am currently using the TMS320F28P65DK9 and connecting to an EEPROM (24LC256) through I2C. I am facing an issue with writing and reading data.

I have attached the i2c_driver_lib.c and i2c_driver.c files for your reference.

I have configured the slave address as 0x50.

Write Sequence:

  • START

  • [0xA0] → EEPROM 7-bit address (0x50) << 1 + Write bit (0) = 0xA0

  • [0x00] → High byte of ControlAddr (0x0000 >> 8)

  • [0x00] → Low byte of ControlAddr (0x0000 & 0xFF)

  • [0x46] → Data byte (value 70)

  • STOP

Read Sequence:

  • START

  • [0xA0] → Write mode

  • [0x00]

  • [0x00]

  • REPEATED START

  • [0xA1] → Read mode

  • READ BYTE

  • STOP

    Please guide me to resolve the above issue and tell me where I made the mistake.

     


#include <stdio.h>
#include "driverlib.h"
#include "device.h"
#include "libs/i2c/i2c_driver_lib.h"
#include "libs/i2c/i2c_driver.h"

#define EEPROM_ADDR         0x50      // 7-bit EEPROM I2C address
#define MAX_BUFFER_SIZE     32
#define I2C_SUCCESS         0

int i2c_init()
{
    uint16_t AvailableI2C_slaves[20];

    // Configure GPIOs for I2CB (SDA on GPIO34, SCL on GPIO35)
    GPIO_setDirectionMode(34, GPIO_DIR_MODE_IN);
    GPIO_setPadConfig(34, GPIO_PIN_TYPE_PULLUP);
    GPIO_setQualificationMode(34, GPIO_QUAL_ASYNC);
    GPIO_setPinConfig(GPIO_34_I2CB_SDA);

    GPIO_setDirectionMode(35, GPIO_DIR_MODE_IN);
    GPIO_setPadConfig(35, GPIO_PIN_TYPE_PULLUP);
    GPIO_setQualificationMode(35, GPIO_QUAL_ASYNC);
    GPIO_setPinConfig(GPIO_35_I2CB_SCL);

    // I2C Module Initialization
    I2C_disableModule(I2CB_BASE);
    I2C_initController(I2CB_BASE, DEVICE_SYSCLK_FREQ, 100000, I2C_DUTYCYCLE_50);
    I2C_setConfig(I2CB_BASE, I2C_CONTROLLER_SEND_MODE);
    I2C_disableLoopback(I2CB_BASE);
    I2C_setBitCount(I2CB_BASE, I2C_BITCOUNT_8);
    I2C_setAddressMode(I2CB_BASE, I2C_ADDR_MODE_7BITS);
    I2C_enableFIFO(I2CB_BASE);
    I2C_clearInterruptStatus(I2CB_BASE, I2C_INT_ARB_LOST | I2C_INT_NO_ACK);
    I2C_setFIFOInterruptLevel(I2CB_BASE, I2C_FIFO_TXEMPTY, I2C_FIFO_RX2);
    I2C_enableInterrupt(I2CB_BASE, I2C_INT_ARB_LOST | I2C_INT_NO_ACK | I2C_INT_STOP_CONDITION);
    I2C_setEmulationMode(I2CB_BASE, I2C_EMULATION_FREE_RUN);
    I2C_enableModule(I2CB_BASE);

    // Scan and print found devices
    uint16_t status = I2CBusScan(I2CB_BASE, AvailableI2C_slaves);

    uart_printf("AIN Initialization Successful\r\n");
    uart_printf("[I2C INIT] Found devices:");
    int i;
    for (i= 0; i < 6; i++) {
        uart_printf(" %02x", AvailableI2C_slaves[i]);
    }
    uart_printf("\r\n");

    return status;
}

int write_eeprom()
{
    uart_printf("[EEPROM WRITE] Initializing I2C...\r\n");

    uint16_t TX_MsgBuffer[MAX_BUFFER_SIZE] = {0};
    uint32_t ControlAddr = 0x0000;
    uint16_t status;

    struct I2CHandle EEPROM = {
        .SlaveAddr = EEPROM_ADDR,
        .base = I2CB_BASE,
        .pControlAddr = &ControlAddr,
        .NumOfAddrBytes = 2,
        .pTX_MsgBuffer = TX_MsgBuffer,
        .NumOfDataBytes = 1,
        .NumOfAttempts = 5,
        .Delay_us = 10,
        .WriteCycleTime_in_us = 10000  // EEPROM write cycle time
    };

    TX_MsgBuffer[0] = 70;

    uart_printf("[EEPROM WRITE] Writing value: %d to EEPROM address: 0x%04X\r\n",
                TX_MsgBuffer[0], ControlAddr);

    status = I2C_MasterTransmitter(&EEPROM);

    if (status == I2C_SUCCESS) {
        uart_printf("[EEPROM WRITE] Write successful.\r\n");
    } else {
        uart_printf("[EEPROM WRITE] Write failed. Status = %d (0x%X)\r\n", status, status);
        uart_printf("[EEPROM WRITE] I2C getStatus = 0x%X\r\n", I2C_getStatus(I2CB_BASE));
    }

    DEVICE_DELAY_US(EEPROM.WriteCycleTime_in_us);
    uart_printf("[EEPROM WRITE] EEPROM write delay complete.\r\n");

    return status;
}

int read_eeprom()
{
    uart_printf("[EEPROM READ] Initializing I2C...\r\n");

    uint16_t RX_MsgBuffer[MAX_BUFFER_SIZE] = {0};
    uint32_t ControlAddr = 0x0000;
    uint16_t status;

    struct I2CHandle EEPROM = {
        .SlaveAddr = EEPROM_ADDR,
        .base = I2CB_BASE,
        .pControlAddr = &ControlAddr,
        .NumOfAddrBytes = 2,
        .pRX_MsgBuffer = RX_MsgBuffer,
        .NumOfDataBytes = 1,
        .NumOfAttempts = 5,
        .Delay_us = 10,
        .WriteCycleTime_in_us = 10000
    };

    uart_printf("[EEPROM READ] Reading from EEPROM address: 0x%04X\r\n", ControlAddr);

    status = I2C_MasterReceiver(&EEPROM);

    if (status == I2C_SUCCESS) {
        uart_printf("[EEPROM READ] Read successful.\r\n");
        uart_printf("[EEPROM READ] Received data: %d from EEPROM address: 0x%04X\r\n",
                    RX_MsgBuffer[0], ControlAddr);
    } else {
        uart_printf("[EEPROM READ] Read failed. Status = %d (0x%X)\r\n", status, status);
        uart_printf("[EEPROM READ] I2C getStatus = 0x%X\r\n", I2C_getStatus(I2CB_BASE));
    }

    while (I2C_getStatus(I2CB_BASE) & I2C_STS_BUS_BUSY);

    uart_printf("[EEPROM READ] Read complete.\r\n");
    return status;
}

void pass(void)
{
    asm(" ESTOP0");
    for (;;);
}

void fail(void)
{
    asm(" ESTOP0");
    for (;;);
}
#include <stdio.h>
#include "driverlib.h"
#include "device.h"
#include "libs/i2c/i2c_driver.h"
#include "drivers_internal/uart/uart_driver.h"


uint16_t I2CBusScan(uint32_t base, uint16_t *pAvailableI2C_slaves)
{
	uint16_t status;
	uint16_t probeSlaveAddress, i;

	//Disable interrupts on Stop condition, NACK and arbitration lost condition
	I2C_disableInterrupt(base, (I2C_INT_ADDR_TARGET|I2C_INT_STOP_CONDITION | I2C_INT_ARB_LOST | I2C_INT_NO_ACK));

	i = 0;
	for(probeSlaveAddress=1;probeSlaveAddress<=MAX_10_BIT_ADDRESS;probeSlaveAddress++)
	{
		//Check I2C bus status
		status = checkBusStatus(base);
		if(status)
		{
			ESTOP0;
			return status;
		}

		I2C_setConfig(base, (I2C_CONTROLLER_SEND_MODE | I2C_REPEAT_MODE));

		//Enable 10-bit addressing if probeSlaveAddress is greater than 127U
		if(probeSlaveAddress > MAX_7_BIT_ADDRESS)
		{
			//10-bit addressing
			I2C_setAddressMode(base, I2C_ADDR_MODE_10BITS);
		}

		// Setup slave address
		I2C_setTargetAddress(base, probeSlaveAddress);


		I2C_sendStartCondition(base);

		//Wait for the slave address to be transmitted
		while(!(I2C_getStatus(base) & I2C_STS_REG_ACCESS_RDY));

		//Generate STOP condition
		I2C_sendStopCondition(base);

		//Wait for the I2CMDR.STP to be cleared
		while(I2C_getStopConditionStatus(base));

		//Wait for the Bus busy bit to be cleared
		while(I2C_isBusBusy(base));

		uint16_t I2CStatus = I2C_getStatus(base);

		//If Slave address is acknowledged, store slave address
		//in pAvailableI2C_slaves
		if(!(I2CStatus & I2C_STS_NO_ACK))
		{
			pAvailableI2C_slaves[i++] = probeSlaveAddress;
		}
		//Clear NACK bit in I2CSTR
		I2C_clearStatus(base,I2C_STS_NO_ACK|I2C_STS_ARB_LOST|I2C_STS_REG_ACCESS_RDY|I2C_STS_STOP_CONDITION);
	}

	I2C_setConfig(base, (I2C_CONTROLLER_SEND_MODE));
	I2C_setAddressMode(base, I2C_ADDR_MODE_7BITS); //7-bit addressing
	I2C_enableInterrupt(base, (I2C_INT_ADDR_TARGET|I2C_INT_STOP_CONDITION | I2C_INT_ARB_LOST | I2C_INT_NO_ACK));
	return SUCCESS;
}

uint16_t I2C_TransmitSlaveAddress_ControlBytes(struct I2CHandle *I2C_Params)
{
	uint16_t status, attemptCount=1;

	uint32_t base = I2C_Params->base;

	status = 1;

	while(status & (attemptCount <= I2C_Params->NumOfAttempts))
	{
		status = checkBusStatus(base);
		attemptCount++;
		DEVICE_DELAY_US(I2C_Params->Delay_us);
	}

	if(status)
	{
		return status;
	}

	I2C_setConfig(base, (I2C_CONTROLLER_SEND_MODE|I2C_REPEAT_MODE));

	if((I2C_Params->SlaveAddr) > MAX_7_BIT_ADDRESS)
	{
		//10-bit addressing
		I2C_setAddressMode(base, I2C_ADDR_MODE_10BITS);
	}

}

	// Setup slave address
	//I2C_setSlaveAddress(base, I2C_Params->SlaveAddr);
//I2C_setTargetAddress(base, 2C_Params->SlaveAddr)
int I2C_setSlaveAddress(uint32_t base,uint16_t SlaveAddr) {
//	int attemptCount = 0;
//	int i;
//	uint32_t temp = *(I2C_Params->pControlAddr);
//
//	for(i=I2C_Params->NumOfAddrBytes-1;i>=0;i--)
//	{
//		I2C_putData(base, (temp >> (i*8U)) & 0xFF);
//	}
//
//	I2C_sendStartCondition(base);
//
//	DEVICE_DELAY_US(150U);
//
//	status = handleNACK(base);
//	if(status)
//	{
//		if(attemptCount <= (I2C_Params->NumOfAttempts))
//		{
//			attemptCount++;
//			I2C_setConfig(base, (I2C_CONTROLLER_SEND_MODE));
//			I2C_sendStartCondition(base);
//			DEVICE_DELAY_US(I2C_Params->Delay_us);
//		}
//		else
//		{
//			return status;
//		}
//	}
//
//	attemptCount = 1;
//
//	while(I2C_getTxFIFOStatus(base) && attemptCount <= 9 * (I2C_Params->NumOfAddrBytes + 2U))
//	{
//		status = handleNACK(base);
//		if(status)
//		{
//			return status;
//		}
//		attemptCount++;
//		DEVICE_DELAY_US(I2C_Params->Delay_us);
//	}
//
//	return 0;
}

uint16_t I2C_MasterTransmitter(struct I2CHandle *I2C_Params)
{
    uint16_t status, attemptCount;
    uint32_t base = I2C_Params->base;

    uart_printf("[I2C TX] Starting transmission\r\n");

    I2C_disableFIFO(base);
    I2C_enableFIFO(base);

    status = I2C_TransmitSlaveAddress_ControlBytes(I2C_Params);
    uart_printf("[I2C TX] Transmit control bytes status = 0x%X\r\n", status);

    if(status) return status;

    I2C_setDataCount(base, (I2C_Params->NumOfAddrBytes + I2C_Params->NumOfDataBytes));
    I2C_setFIFOInterruptLevel(base, I2C_FIFO_TXEMPTY, I2C_FIFO_RXFULL);
    I2C_enableInterrupt(base, I2C_INT_TXFF);

    uint16_t numofSixteenByte  = (I2C_Params->NumOfDataBytes) / I2C_FIFO_LEVEL;
    uint16_t remainingBytes    = (I2C_Params->NumOfDataBytes) % I2C_FIFO_LEVEL;

    uint16_t i, count = 0, buff_pos = 0;

    while(count < numofSixteenByte)
    {
        for(i = 1; i <= I2C_FIFO_LEVEL; i++)
        {
            I2C_putData(base, I2C_Params->pTX_MsgBuffer[buff_pos++]);
        }

        attemptCount = 1;
        while(I2C_getTxFIFOStatus(base) && attemptCount <= 9 * (I2C_FIFO_LEVEL + 2U))
        {
            status = handleNACK(base);
            if(status)
            {
                uart_printf("[I2C TX] NACK received during burst write. Status = 0x%X\r\n", status);
                return status;
            }
            attemptCount++;
            DEVICE_DELAY_US(I2C_Params->Delay_us);
        }

        count++;
    }

    for(i = 0; i < remainingBytes; i++)
    {
        I2C_putData(base, I2C_Params->pTX_MsgBuffer[buff_pos++]);
    }

    attemptCount = 1;
    while(I2C_getTxFIFOStatus(base) && attemptCount <= 9 * (remainingBytes + 2U))
    {
        status = handleNACK(base);
        if(status)
        {
            uart_printf("[I2C TX] NACK received during remaining byte write. Status = 0x%X\r\n", status);
            return status;
        }
        attemptCount++;
        DEVICE_DELAY_US(I2C_Params->Delay_us);
    }

    I2C_sendStopCondition(base);

    attemptCount = 1;
    while(I2C_getStopConditionStatus(base) && attemptCount <= 3U)
    {
        DEVICE_DELAY_US(I2C_Params->Delay_us);
        attemptCount++;
    }

    uart_printf("[I2C TX] Transmission complete. Status = 0x%X\r\n", SUCCESS);
    return SUCCESS;
}


uint16_t I2C_MasterReceiver(struct I2CHandle *I2C_Params)
{
    uint16_t status, attemptCount;
    uint32_t base = I2C_Params->base;

    uart_printf("[I2C RX] Starting reception\r\n");

    I2C_disableFIFO(base);
    I2C_enableFIFO(base);

    status = I2C_TransmitSlaveAddress_ControlBytes(I2C_Params);
    uart_printf("[I2C RX] Transmit control bytes status = 0x%X\r\n", status);
    if(status) return status;

    uint16_t numofSixteenByte  = (I2C_Params->NumOfDataBytes) / I2C_FIFO_LEVEL;
    uint16_t remainingBytes    = (I2C_Params->NumOfDataBytes) % I2C_FIFO_LEVEL;

    I2C_setConfig(base, (I2C_CONTROLLER_RECEIVE_MODE | I2C_REPEAT_MODE));
    I2C_sendStartCondition(base);

    uint16_t i, count = 0, buff_pos = 0;
    while(count < numofSixteenByte)
    {
        status = handleNACK(base);
        if(status)
        {
            uart_printf("[I2C RX] NACK during burst receive. Status = 0x%X\r\n", status);
            return status;
        }

        count++;

        attemptCount = 1;
        while(!(I2C_getRxFIFOStatus(base) == I2C_FIFO_RXFULL) && attemptCount <= 9 * (I2C_FIFO_RXFULL + 2U))
        {
            DEVICE_DELAY_US(I2C_Params->Delay_us);
            attemptCount++;
        }

        for(i = 0; i < I2C_FIFO_LEVEL; i++)
        {
            I2C_Params->pRX_MsgBuffer[buff_pos++] = I2C_getData(base);
        }
    }

    attemptCount = 1;
    while(!(I2C_getRxFIFOStatus(base) == remainingBytes) && attemptCount <= 9 * (remainingBytes + 2U))
    {
        DEVICE_DELAY_US(I2C_Params->Delay_us);
        attemptCount++;
    }

    I2C_sendStopCondition(base);

    for(i = 0; i < remainingBytes; i++)
    {
        I2C_Params->pRX_MsgBuffer[buff_pos++] = I2C_getData(base);
    }

    status = handleNACK(base);
    if(status)
    {
        uart_printf("[I2C RX] NACK after receive. Status = 0x%X\r\n", status);
        return status;
    }

    I2C_disableFIFO(base);

    attemptCount = 1;
    while(I2C_getStopConditionStatus(base) && attemptCount <= 3U)
    {
        DEVICE_DELAY_US(I2C_Params->Delay_us);
        attemptCount++;
    }

    uart_printf("[I2C RX] Reception complete. Status = 0x%X\r\n", SUCCESS);
    return SUCCESS;
}


uint16_t checkBusStatus(uint32_t base)
{

	if(I2C_isBusBusy(base))
	{
		return ERROR_BUS_BUSY;
	}

	if(I2C_getStopConditionStatus(base))
	{
		return ERROR_STOP_NOT_READY;
	}

	return SUCCESS;
}

uint16_t handleNACK(uint32_t base)
{
	if(I2C_getStatus(base) & I2C_STS_NO_ACK)
	{
		I2C_clearStatus(base, I2C_STS_NO_ACK);
		I2C_sendStopCondition(base);

		return ERROR_NACK_RECEIVED;
	}

	return SUCCESS;
}