I2C to EEPROM memory, XMClib and XMC1300

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

cross mob
User12776
Level 1
Level 1
Hi

Im doing a little program using the USIC module as I2C. For this mi using the XMC1200 boot kit.
I need to do a driver to control a I2C serial EEPROM (24LC16B).
I did two functions, one for write and another to read the momery. In link is the component datasheet.

http://www.microchip.com/wwwproducts/en/24LC16B

I think I configure properly but it doesn't run. Can someone help?? I cant see the I2C signals with the oscilloscope.


This is my code:

#include "xmc_scu.h"
#include "xmc_gpio.h"
#include "xmc_i2c.h"


#define EEPROM_I2C_ADR 0xA0

#define SDA_PIN P0_7
#define SCL_PIN P0_8

void EEPROM_SendByte (void);
void EEPROM_ReadByte (void);

uint8_t DataToSend = 0x55;
uint8_t ReceivedData;
uint8_t MemoryAddress = 0x00;

XMC_SCU_CLOCK_CONFIG_t clock_config;

XMC_GPIO_CONFIG_t led1_config;

XMC_GPIO_CONFIG_t sda_pin_config;
XMC_GPIO_CONFIG_t scl_pin_config;

/* I2C configuration */
XMC_USIC_CH_t *i2c = XMC_I2C0_CH1;

XMC_I2C_CH_CONFIG_t i2c_cfg;

void EEPROM_SendByte (void){
XMC_I2C_CH_MasterStart(i2c, EEPROM_I2C_ADR, XMC_I2C_CH_CMD_WRITE); // I2C send repeated start command (with slave address) to write Data to PCA9502
while((XMC_I2C_CH_GetStatusFlag(i2c) & XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED) == 0U){} // wait until ACK
XMC_I2C_CH_ClearStatusFlag(i2c, XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED); // clear ACK flag in register PSR

XMC_I2C_CH_MasterTransmit(i2c, MemoryAddress); // I2C send TxData=IO_STATE
while((XMC_I2C_CH_GetStatusFlag(i2c) & XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED) == 0U){} // wait until ACK
XMC_I2C_CH_ClearStatusFlag(i2c, XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED);

XMC_I2C_CH_MasterTransmit(i2c, DataToSend); // I2C send TxData=IO_STATE
while((XMC_I2C_CH_GetStatusFlag(i2c) & XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED) == 0U){} // wait until ACK
XMC_I2C_CH_ClearStatusFlag(i2c, XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED);

XMC_I2C_CH_MasterStop(i2c);
}

void EEPROM_ReadByte (void){
//Random read operations allow the master to access any memory location in a random manner
XMC_I2C_CH_MasterStart(i2c, EEPROM_I2C_ADR, XMC_I2C_CH_CMD_WRITE); // I2C send repeated start command (with slave address) to write Data to PCA9502
while((XMC_I2C_CH_GetStatusFlag(i2c) & XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED) == 0U){} // wait until ACK
XMC_I2C_CH_ClearStatusFlag(i2c, XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED); // clear ACK flag in register PSR

XMC_I2C_CH_MasterTransmit(i2c, MemoryAddress); // I2C send TxData=IO_STATE
while((XMC_I2C_CH_GetStatusFlag(i2c) & XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED) == 0U){} // wait until ACK
XMC_I2C_CH_ClearStatusFlag(i2c, XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED); // clear ACK flag in register PSR

XMC_I2C_CH_MasterStop(i2c);

XMC_I2C_CH_MasterStart(i2c, EEPROM_I2C_ADR, XMC_I2C_CH_CMD_READ); // I2C send repeated start command (with slave address) to Read Data from PCA9502
while((XMC_I2C_CH_GetStatusFlag(i2c) & XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED) == 0U){} // wait until ACK
XMC_I2C_CH_ClearStatusFlag(i2c, XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED); // clear ACK flag in register PSR

XMC_I2C_CH_MasterReceiveNack(i2c); // I2C send dummy with NACK to read only one byte
while((XMC_I2C_CH_GetStatusFlag(i2c) & (XMC_I2C_CH_STATUS_FLAG_RECEIVE_INDICATION |
XMC_I2C_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION)) == 0U){} // wait until AIR or RI ('USIC_AI.007')
XMC_I2C_CH_ClearStatusFlag(i2c, XMC_I2C_CH_STATUS_FLAG_RECEIVE_INDICATION |
XMC_I2C_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION); // clear both AIR and RI

ReceivedData = XMC_I2C_CH_GetReceivedData(i2c); // get RxData from RBUF

XMC_I2C_CH_MasterStop(i2c);
}

int main(void)
{
/* Configure Clock */
clock_config.pclk_src = XMC_SCU_CLOCK_PCLKSRC_MCLK; /*PCLK = MCLK*/
clock_config.fdiv = 0; /**< Fractional divider */
clock_config.idiv = 0; /**MCLK = 32MHz */

XMC_SCU_CLOCK_Init(&clock_config);

/* Configure LED1 */
led1_config.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL;
XMC_GPIO_Init(XMC_GPIO_PORT0,6, &led1_config);

/* I2C configuration */
i2c_cfg.baudrate = 400000U;

XMC_I2C_CH_Init(i2c, &i2c_cfg);
XMC_I2C_CH_Start(i2c);

/* I2C initialization sequence*/
XMC_I2C_CH_SetInputSource(i2c, XMC_I2C_CH_INPUT_SDA , USIC0_C0_DX1_P0_7);
XMC_I2C_CH_SetInputSource(i2c, XMC_I2C_CH_INPUT_SCL , USIC0_C0_DX1_P0_8);

/* I2C port pin configuration*/
sda_pin_config.mode = XMC_GPIO_MODE_OUTPUT_OPEN_DRAIN_ALT7;
XMC_GPIO_Init(SDA_PIN, &sda_pin_config);
scl_pin_config.mode = XMC_GPIO_MODE_OUTPUT_OPEN_DRAIN_ALT7;
XMC_GPIO_Init(SCL_PIN, &scl_pin_config);

while(1U){
ReceivedData = 0;
EEPROM_SendByte();
EEPROM_ReadByte();
if (DataToSend==ReceivedData){
XMC_GPIO_ToggleOutput(XMC_GPIO_PORT0,6);
}
}
}



Regards
Paul
0 Likes
6 Replies
User12775
Level 5
Level 5
First solution authored First like received
Are you using DAVE, Please see this :
2576.attach
EEPROM Example for XMC1300.

For your reference.

Edit: It is a simulated EEPROM project.
0 Likes
User12776
Level 1
Level 1
My eeprom memory is an external one. I communicate with that chip using the I2C protocol.

My problem is that a follow one I2C example to do the code but i cant get the output signals.
0 Likes
DRubeša
Employee
Employee
First solution authored First like received
Hi Paul90,

so you need to change the parameters that you pass to "XMC_I2C_CH_SetInputSource()" function.
Currently you´re using something like USIC0_C0_DX1_P0_7 for both cases. First of all this USIC0_C0 is wrong because you are using USIC0_C1 (this is what variable i2c equals in your case). Also SDA signal should use DX0 input and SCL signal DX1 input (table 15-2 in XMC1200 Reference Manual). Still you could be really lucky while USIC0_C0_DX1_P0_7 is just a macro and maybe this and proper one has same value but that´s not case here 😛
So, one SDA signal should have USIC0_C1_DX0_P0_7 as a parameter and SCL signal USIC0_C1_DX1_P0_8.

Additional, define output levels for both pins "high"; something like sda_pin_config.output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH;

That should be enough to be able to generate signals properly and to see them on oscilloscope...maybe there is additional issue in accessing EEPROM but try this first and let me know do you have some more issues.

Best regards,
Deni

P.S. Maybe you are wondering why I said to set the output level to high. This is because in I2C protocol start of transmission is when SCL changes from level high to level low ("1"->"0"). Maybe hardware will pull up pin levels just before transmission should start but you cannot rely on "maybe" so set them high by default.
0 Likes
lock attach
Attachments are accessible only for community members.
User12775
Level 5
Level 5
First solution authored First like received
Oh, Sorry, Could you use this example?

0 Likes
User12776
Level 1
Level 1
Hello,

i changed the software parts DRubeša and now i cant see the signals with the osciloscope.

2546.attach

there is the full signal of EEPROM_SendByte() function.

this new program can exit from this function, i think something is bad. Can someone help?

This is my code:

#include "xmc_scu.h"
#include "xmc_gpio.h"
#include "xmc_i2c.h"


#define EEPROM_I2C_ADR 0xA1

#define SDA_PIN P0_7
#define SCL_PIN P0_8

void Init_I2C (void);
void EEPROM_SendByte (uint8_t MemoryAddress, uint8_t DataToSend);
uint8_t EEPROM_ReadByte (uint8_t MemoryAddress);

uint8_t ReceivedData;

XMC_SCU_CLOCK_CONFIG_t clock_config;

XMC_GPIO_CONFIG_t led1_config;

XMC_GPIO_CONFIG_t sda_pin_config;
XMC_GPIO_CONFIG_t scl_pin_config;

/* I2C configuration */
XMC_USIC_CH_t *i2c = XMC_I2C0_CH1;

XMC_I2C_CH_CONFIG_t i2c_cfg;

void Init_I2C (void){
/* Configure Clock */
clock_config.pclk_src = XMC_SCU_CLOCK_PCLKSRC_MCLK; /*PCLK = MCLK*/
clock_config.fdiv = 0; /**< Fractional divider */
clock_config.idiv = 0; /**MCLK = 32MHz */

XMC_SCU_CLOCK_Init(&clock_config);

/* Configure LED1 */
led1_config.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL;
XMC_GPIO_Init(XMC_GPIO_PORT0,6, &led1_config);

/* I2C configuration */
i2c_cfg.baudrate = 320000U;

XMC_I2C_CH_Init(i2c, &i2c_cfg);
XMC_I2C_CH_Start(i2c);

/* I2C initialization sequence*/
XMC_I2C_CH_SetInputSource(i2c, XMC_I2C_CH_INPUT_SDA , USIC0_C1_DX0_P0_7);
XMC_I2C_CH_SetInputSource(i2c, XMC_I2C_CH_INPUT_SCL , USIC0_C1_DX1_P0_8);

/* I2C port pin configuration*/
sda_pin_config.mode = XMC_GPIO_MODE_OUTPUT_OPEN_DRAIN_ALT7;
sda_pin_config.output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH;
XMC_GPIO_Init(SDA_PIN, &sda_pin_config);
scl_pin_config.mode = XMC_GPIO_MODE_OUTPUT_OPEN_DRAIN_ALT7;
scl_pin_config.output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH;
XMC_GPIO_Init(SCL_PIN, &scl_pin_config);

}


void EEPROM_SendByte (uint8_t MemoryAddress, uint8_t DataToSend){
XMC_I2C_CH_MasterStart(i2c, EEPROM_I2C_ADR, XMC_I2C_CH_CMD_WRITE); // I2C send repeated start command (with slave address) to write Data to PCA9502
while((XMC_I2C_CH_GetStatusFlag(i2c) & XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED) == 1U){} // wait until ACK
XMC_I2C_CH_ClearStatusFlag(i2c, XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED); // clear ACK flag in register PSR

XMC_I2C_CH_MasterTransmit(i2c, MemoryAddress); // I2C send
while((XMC_I2C_CH_GetStatusFlag(i2c) & XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED) == 1U){} // wait until ACK
XMC_I2C_CH_ClearStatusFlag(i2c, XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED);

XMC_I2C_CH_MasterTransmit(i2c, DataToSend); // I2C send TxData=IO_STATE
while((XMC_I2C_CH_GetStatusFlag(i2c) & XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED) == 1U){} // wait until ACK
XMC_I2C_CH_ClearStatusFlag(i2c, XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED);

XMC_I2C_CH_MasterStop(i2c);
}

uint8_t EEPROM_ReadByte (uint8_t MemoryAddress){
uint8_t data = 0;

XMC_I2C_CH_MasterStart(i2c, EEPROM_I2C_ADR, XMC_I2C_CH_CMD_WRITE); // I2C send repeated start command (with slave address) to write Data to PCA9502
while((XMC_I2C_CH_GetStatusFlag(i2c) & XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED) == 1U){} // wait until ACK
XMC_I2C_CH_ClearStatusFlag(i2c, XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED); // clear ACK flag in register PSR

XMC_I2C_CH_MasterTransmit(i2c, MemoryAddress); // I2C send
while((XMC_I2C_CH_GetStatusFlag(i2c) & XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED) == 1U){} // wait until ACK
XMC_I2C_CH_ClearStatusFlag(i2c, XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED); // clear ACK flag in register PSR

XMC_I2C_CH_MasterStop(i2c);

XMC_I2C_CH_MasterStart(i2c, EEPROM_I2C_ADR, XMC_I2C_CH_CMD_READ); // I2C send repeated start command (with slave address) to Read Data from PCA9502
while((XMC_I2C_CH_GetStatusFlag(i2c) & XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED) == 1U){} // wait until ACK
XMC_I2C_CH_ClearStatusFlag(i2c, XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED); // clear ACK flag in register PSR

XMC_I2C_CH_MasterReceiveNack(i2c); // I2C send dummy with NACK to read only one byte
while((XMC_I2C_CH_GetStatusFlag(i2c) & (XMC_I2C_CH_STATUS_FLAG_RECEIVE_INDICATION |
XMC_I2C_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION)) == 1U){} // wait until AIR or RI
XMC_I2C_CH_ClearStatusFlag(i2c, XMC_I2C_CH_STATUS_FLAG_RECEIVE_INDICATION |
XMC_I2C_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION); // clear both AIR and RI

data = XMC_I2C_CH_GetReceivedData(i2c); // get RxData from RBUF

XMC_I2C_CH_MasterStop(i2c);

return data;
}

int main(void)
{
Init_I2C();

while(1U)
{
ReceivedData = 0;
EEPROM_SendByte(0x55, 0x20);
ReceivedData = EEPROM_ReadByte(0x55);
if (ReceivedData==0x20){
XMC_GPIO_ToggleOutput(XMC_GPIO_PORT0,6);
}
}
}

Best regards,
Paul
0 Likes
Not applicable
Hi all

got the same problem, with XMC1300 boot kit

can someone help?
0 Likes