XMC4500 I2C page read

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Not applicable
Hi,
i am trying to write an application emulating a I2C EEPROM (two byte addresses). As a starting point I used the one of the I2C slave apps.

I succeeded in implementing:

* slave single byte write (master => slave)
* slave single byte read (slave => master)
* slave multi byte write (master => slave)

I am unable to get the multi byte read running. The master succesfully transfers the two address bytes and the slave answers with the first data byte. After this the i2c bus is silent, but the SCL line is low.
I don't know wether the master or slave keeps this line low. Below you see the bus traffix shown by the i2c analyser.

1098.attach

I add the code of the two ISRs:

/*
* @brief User defined function which is called
* when data is received in the receive FIFO of I2C slave
*
* @param[in]: void
* @return: void
**/
void slave_Rx_handler(void)
{
uint32_t test;

test = USIC1_CH0->PSR_IICMode;

//Clear all interrupt flags
USIC1_CH0->PSCR = test;

//Write data to master
if((test & USIC_CH_PSR_IICMode_SRR_Msk) &&
(test & USIC_CH_PSR_IICMode_RSCR_Msk))
{
SlaveTxData.TDF_Type = I2C003_TDF_STXDATA;
SlaveTxData.Payload = eeprom_data.eeprom_data[eeprom_address];

// write data to tbuf depending on transmit mode
I2C003_WriteData(&I2C003_Handle0,&SlaveTxData);

//Increment address counter
eeprom_address++;
}

#ifdef IRQ_TRACKING
irq_array[irq_count].irq_data = test;
irq_array[irq_count].irq_type = IRQ_TYPE_RX;
irq_array[irq_count].data = SlaveTxData.Payload;
irq_array[irq_count].eep_address = eeprom_address - 1;
irq_count++;
#endif
}

/*
* @brief User defined protocol interrupt function which is
* called when the I2C slave receives read request from I2C master.
*
* @param[in]: void
* @return: void
**/
void slave_Read_Req_handler(void)
{
uint32_t test;
uint8_t data;
bool result = true;

i = 0;

test = USIC1_CH0->PSR_IICMode;

// Clear address byte count when we are selected as slave
if(test & USIC_CH_PSR_IICMode_SLSEL_Msk)
{
//Be ready for new address bytes
eeprom_address_count = 0;
}

if(eeprom_address_count == 2)
{
result = I2C003_ReadData(&I2C003_Handle0, &data);
eeprom_data.eeprom_data[eeprom_address] = data;

#ifdef IRQ_TRACKING
irq_array[irq_count].i2c_read = data;
i++;
#endif
}

// Read data (address) received from master
if(test & USIC_CH_PSR_IICMode_RSIF_Msk)
{
result = I2C003_ReadData(&I2C003_Handle0, &data);
#ifdef IRQ_TRACKING
irq_array[irq_count].i2c_read = data;
i++;
#endif

if(eeprom_address_count == 1)
{
eeprom_address_l = data;
}

if(eeprom_address_count == 0)
{
eeprom_address_h = data;
eeprom_address_l = 0;
}

eeprom_address_count++;
eeprom_address = (eeprom_address_h << 😎 | eeprom_address_l;
}

//Clear all interrupt flags
USIC1_CH0->PSCR = test;

#ifdef IRQ_TRACKING
irq_array[irq_count].irq_data = test;
irq_array[irq_count].irq_type = IRQ_TYPE_RREQ;
irq_array[irq_count].eep_address = eeprom_address;
irq_array[irq_count].i2c_read_count = i;
irq_count++;
#endif
}


Do you have any idea what I am doing wrong.

I am using XMC4500 relax kit.

Thank you very much.

Wolfram
0 Likes
0 Replies