Twi/i2c comms between sc573 and sc589

Hello,

I've been trying to get an i2c link between the sc573 and sc589 ARM processors working on our custom board where we have both the chips (and I assume the hw connections are done correctly for this), but haven't managed to get it working yet. Eventually the sc589 side will be running on linux (using the i2c driver provided in the linux addin) but for now I am trying to get it working with bare metal applications on both the processors.

So to start with I have created 2 projects and added the TWI addin. After I added it I noticed there is example code for: TWI driver blocking mode write, TWI driver non-blocking callback mode, TWI driver non-blocking mode write. But nothing for reading, so I just copied the write example and changed the write call to a read. My code looks like this:

SC589 (master):

    /* TWI driver handle */
	ADI_TWI_HANDLE hDevice;

	/* TWI driver memory */
	uint8_t driverMemory[ADI_TWI_MEMORY_SIZE];

	/* driver API result code */
	ADI_TWI_RESULT result;

	/* open the TWI driver in master mode */
	result = adi_twi_Open(0, ADI_TWI_MASTER, driverMemory, ADI_TWI_MEMORY_SIZE, &hDevice);
	if (result != ADI_TWI_SUCCESS)
	{
		printTwiResult("SC589 adi_twi_Open", result);
	}

	result = adi_twi_SetBitRate(hDevice, 100);
	if (result != ADI_TWI_SUCCESS)
	{
		printTwiResult("SC589 adi_twi_SetBitRate", result);
	}

	result = adi_twi_SetDutyCycle(hDevice, 50);
	if (result != ADI_TWI_SUCCESS)
	{
		printTwiResult("SC589 adi_twi_SetDutyCycle", result);
	}

	result = adi_twi_SetPrescale(hDevice, 10);
	if (result != ADI_TWI_SUCCESS)
	{
		printTwiResult("SC589 adi_twi_SetPrescale", result);
	}

	result = adi_twi_SetHardwareAddress(hDevice, 0x5C);
	if (result != ADI_TWI_SUCCESS)
	{
		printTwiResult("SC589 adi_twi_SetHardwareAddress", result);
	}

	uint16_t slaveAddr = 0x5A;

	uint8_t val = 2;

	/* buffer which holds data to transfer over TWI */
	uint8_t buf[3];
	buf[0] = slaveAddr >> 8;
	buf[1] = slaveAddr & 0xff;
	buf[2] = val;

	/* write data to the TWI device using a blocking write */
	result = adi_twi_Write(hDevice, buf, sizeof(buf), false);
	if (result != ADI_TWI_SUCCESS)
	{
		printTwiResult("SC589 adi_twi_Write", result);
	}

	/* close the TWI driver */
	result = adi_twi_Close(hDevice);
	if (result != ADI_TWI_SUCCESS)
	{
		printTwiResult("SC589 adi_twi_Close", result);
	}

SC573 (slave):

    /* TWI driver handle */
    ADI_TWI_HANDLE hDevice;

    /* TWI driver memory */
    uint8_t driverMemory[ADI_TWI_MEMORY_SIZE];

    /* driver API result code */
	ADI_TWI_RESULT result;

	/* buffer which holds data to transfer over TWI */
	uint8_t buffer[] = {0, 0, 0};

    /* open the TWI driver in master mode */
    result = adi_twi_Open(0, ADI_TWI_SLAVE, driverMemory, ADI_TWI_MEMORY_SIZE, &hDevice);
	if (result != ADI_TWI_SUCCESS)
	{
		printTwiResult("SC573 adi_twi_Open", result);
	}

	result = adi_twi_SetBitRate(hDevice, 100);
	if (result != ADI_TWI_SUCCESS)
	{
		printTwiResult("SC573 adi_twi_SetBitRate", result);
	}

	result = adi_twi_SetDutyCycle(hDevice, 50);
	if (result != ADI_TWI_SUCCESS)
	{
		printTwiResult("SC573 adi_twi_SetDutyCycle", result);
	}

	result = adi_twi_SetPrescale(hDevice, 10);
	if (result != ADI_TWI_SUCCESS)
	{
		printTwiResult("SC573 adi_twi_SetPrescale", result);
	}

	result = adi_twi_SetHardwareAddress(hDevice, 0x5A);
	if (result != ADI_TWI_SUCCESS)
	{
		printTwiResult("SC573 adi_twi_SetHardwareAddress", result);
	}

	while (1)
	{
		/* write data to the TWI device using a blocking write */
		result = adi_twi_Read(hDevice, buffer, sizeof(buffer), false);
		if (result != ADI_TWI_SUCCESS)
		{
			printTwiResult("SC573 adi_twi_Read", result);
		}
		else
		{
			printf("SC573 received: %s\n", buffer);
		}
	}

But I'm getting a ADI_TWI_BUFFER_ERROR error on the sc589 side, which I can't understand what it means exactly in this case.

So a few questions I have:

Is there a more full example for TWI code for these processors?

Also would I need to use specific addresses for each of the chips? I have basically just picked 2 that are within the valid range, not sure if I should be using specific ones (although the adi_twi_SetHardwareAddress calls are successful from what I see).

  • I just got this working. Sorry for the post, it seems I was just using the wrong device index. On the sc589 I should be using TWI2 (i.e. first argument in the adi_twi_open should be 2) and on the sc573 its device 1 (so first arg in adi_twi_open on sc573 is 1). Also I don't need to be adding the slave's address to the send buffer, I just need to use it in the adi_twi_SetHardwareAdress call on the master (sc589).

    So the working code on sc589 looks like:

       /* TWI driver handle */
    	ADI_TWI_HANDLE hDevice;
    
    	/* TWI driver memory */
    	uint8_t driverMemory[ADI_TWI_MEMORY_SIZE];
    
    	/* driver API result code */
    	ADI_TWI_RESULT result;
    
    	/* open the TWI driver in master mode */
    	result = adi_twi_Open(2, ADI_TWI_MASTER, driverMemory, ADI_TWI_MEMORY_SIZE, &hDevice);
    	if (result != ADI_TWI_SUCCESS)
    	{
    		printTwiResult("SC589 adi_twi_Open", result);
    	}
    
    	result = adi_twi_SetBitRate(hDevice, 100);
    	if (result != ADI_TWI_SUCCESS)
    	{
    		printTwiResult("SC589 adi_twi_SetBitRate", result);
    	}
    
    	result = adi_twi_SetDutyCycle(hDevice, 50);
    	if (result != ADI_TWI_SUCCESS)
    	{
    		printTwiResult("SC589 adi_twi_SetDutyCycle", result);
    	}
    
    	result = adi_twi_SetPrescale(hDevice, 10);
    	if (result != ADI_TWI_SUCCESS)
    	{
    		printTwiResult("SC589 adi_twi_SetPrescale", result);
    	}
    
    	result = adi_twi_SetHardwareAddress(hDevice, 0x5A);
    	if (result != ADI_TWI_SUCCESS)
    	{
    		printTwiResult("SC589 adi_twi_SetHardwareAddress", result);
    	}
    
    	/* buffer which holds data to transfer over TWI */
    	uint8_t buf[3];
    	buf[0] = 1;
    	buf[1] = 1;
    	buf[2] = 2;
    
    	/* write data to the TWI device using a blocking write */
    	result = adi_twi_Write(hDevice, buf, sizeof(buf), false);
    	if (result != ADI_TWI_SUCCESS)
    	{
    		printTwiResult("SC589 adi_twi_Write", result);
    	}

    Apologies for the self-replied post! Will mark it as answered/closed.