I2C problem

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

cross mob
lock attach
Attachments are accessible only for community members.
eeEn_4618901
Level 4
Level 4
5 likes given First like received First like given

Dear,

I want to do a study with the color sensor.

There is sample code in datasheet. I created a library for them. but it doesn't work. Should I use a different command for i2c?

Sample Code:

#define I2C_AS72XX_SLAVE_STATUS_REG 0x00

#define I2C_AS72XX_SLAVE_WRITE_REG 0x01

#define I2C_AS72XX_SLAVE_READ_REG 0x02

#define I2C_AS72XX_SLAVE_TX_VALID 0x02

#define I2C_AS72XX_SLAVE_RX_VALID 0x01

void i2cm_AS72xx_write(uint8_t virtualReg, uint8_t d)

{

volatile uint8_t status;

while (1)

{

// Read slave I²C status to see if the write buffer is ready.

status = i2cm_read(I2C_AS72XX_SLAVE_STATUS_REG);

if ((status & I2C_AS72XX_SLAVE_TX_VALID) == 0)

// No inbound TX pending at slave. Okay to write now.

break,

}

// Send the virtual register address (setting bit 7 to indicate a pending write).

i2cm_write(I2C_AS72XX_SLAVE_WRITE_REG, (virtualReg | 0x80)) ;

while (1)

{

// Read the slave I²C status to see if the write buffer is ready.

status = i2cm_read(I2C_AS72XX_SLAVE_STATUS_REG) ;

if ((status & I2C_AS72XX_SLAVE_TX_VALID) == 0)

// No inbound TX pending at slave. Okay to write data now.

break;

}

//Send the data to complete the operation.

i2cm_write(I2C_AS72XX_SLAVE_WRITE_REG, d) ;

}

I

0 Likes
1 Solution
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

Sorry, it was my bad.

my "i2c_readreg()" takes 2 argument, address and *value to utilize the return value as status.

So please try,

===============

uint8_t value ;

int    status ;

status = i2c_read_reg(REG_ADDRESS, &value) ;

if (status == I2C_MSTR_NO_ERROR) {

    snprintf(str, STR_BUF_LEN, "%d\n\r", value) ;

    pritn(str) ;

} else {

    print("I2C Read Reg Error\n\r') ;

}

===============

moto

View solution in original post

0 Likes
14 Replies
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

As usual, writing "it does not work" does not provide information.

Please specify what is the problem and/or how far have you tried to debug or trouble shoot.

Having written above,

(1) Please attach your project using either of the following methods

Note: Your attachment did not have the whole project to check.

Sharing Community Code - Best Practices

How to attach a project archive file to a question?

(2) Try my sample to check if the I2C sensor is working

MCU Tester, a Swiss Army Knife for PSoC (CY8CKIT-059 version)

(3) If the sensor is not working with (2)

Probably a hardware problem.

Check if appropriate pull-up resistors are applied to the SCL and SDA.

If the sensor is working with (2)

Probably a software problem.

Check my code in the sample of (2) or you can also check the code for CardKb, too.

I2C Full Keyboard Sample (CardKb)

moto

0 Likes

Dear Moto-san,

I try to to MCU Tester, a Swiss Army Knife for PSoC (CY8CKIT-059 version).

I think. no hardware problems.

pastedImage_0.png

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

I think that is a hardware trouble.

The scan command should show the address of the sensor.

There should be addresses shown between the line

     Scanning I2C Addresses ...

and

     Scan completed.

In the following example,

the program found a device at the address 0x48

Then setting salve address to 0x48 by typing

     slave 0x48

After that you can use readreg or readregs commands.

000-MCU_Tester_I2C.JPG

So please make sure that SDA/SCL/GND pins are connected to your sensor's SDA/SCL/GND.

And both SDA and SCAL are pulled-up with 2K ~ 10K resistor to the VDD.

moto

0 Likes

Dear Moto-san,

I chose i2c with solder on the sensor.

now it is 0x49 with scan.

but when i write the slave 0x49 it is just waiting.

pastedImage_0.png

0 Likes
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

I am very sorry, I introduced a bug when I implemented loop in i2c.

Please use the attached version 200716.

Meantime, please change the Receive in "Terminal setup" to "AUTO" so that you can see the prompt.

001-teraterm-terminal.JPG

moto

MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

One more thing.

If you are using CY8CKTI-059 and P12[0] for SCL and P12[1] for SDA,

you don't need to apply pull-up resistors.

moto

0 Likes

Hi,

Thank you. it is ok.

What should I do to run the sample code in psoc?

"i2cm_read"==>I2C_MasterReadByte(reg_address, &value)   is it enough to change it to?

Ekran Alıntısı.JPG

Sample Code:

#define I2C_AS72XX_SLAVE_STATUS_REG 0x00

#define I2C_AS72XX_SLAVE_WRITE_REG 0x01

#define I2C_AS72XX_SLAVE_READ_REG 0x02

#define I2C_AS72XX_SLAVE_TX_VALID 0x02

#define I2C_AS72XX_SLAVE_RX_VALID 0x01

void i2cm_AS72xx_write(uint8_t virtualReg, uint8_t d)

{

volatile uint8_t status;

while (1)

{

// Read slave I²C status to see if the write buffer is ready.

status = i2cm_read(I2C_AS72XX_SLAVE_STATUS_REG);

if ((status & I2C_AS72XX_SLAVE_TX_VALID) == 0)

// No inbound TX pending at slave. Okay to write now.

break,

}

// Send the virtual register address (setting bit 7 to indicate a pending write).

i2cm_write(I2C_AS72XX_SLAVE_WRITE_REG, (virtualReg | 0x80)) ;

while (1)

{

// Read the slave I²C status to see if the write buffer is ready.

status = i2cm_read(I2C_AS72XX_SLAVE_STATUS_REG) ;

if ((status & I2C_AS72XX_SLAVE_TX_VALID) == 0)

// No inbound TX pending at slave. Okay to write data now.

break;

}

//Send the data to complete the operation.

i2cm_write(I2C_AS72XX_SLAVE_WRITE_REG, d) ;

}

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

> What should I do to run the sample code in psoc?

> "i2cm_read"==>I2C_MasterReadByte(reg_address, &value)   is it enough to change it to?

Please try following steps

(1) copy i2c_utils.c and i2c_utils.h from mcu_test_059_200716.cydsn\sources\i2c to your project folder

(2) From PSoC Creator Workspace Explorer, add i2c_utils.h in the "Header Files" folder

(3) From PSoC Creator Workspace Explorer, add i2c_utils.c in the "Source Files" folder

(4) include "i2c_utils.h" in your main.c or where you call i2cm functions.

(5) call i2c_set_slave_address(0x49) before using any other i2c functions from the i2c_utils.h

(6) replace your i2cm_read with i2c_read_reg

moto

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

After posting my previous response, I noticed a few things to mention.

(1) My i2c_utils.h and i2c_utils.c assume that instance name of I2C component is "i2c"

you may need to change i2cm to i2c or change i2c in my sample source to i2cm

(2) If you have 2 or more i2c devices connected, may be doing something like below is a good idea

void i2cm_AS72xx_write(uint8_t virtualReg, uint8_t d)

{

   i2c_set_slave_address(0x49) ; /* or use AS72XX_I2C_ADDRESS, after dfinining it */

    i2c_write_reg(virtualReg, d) ;

}

Last but not least, please study my code and understand it before using it.

moto

0 Likes
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

I checked your project.

And I noticed that I should have mentioned that all do_xxx are not required for usual program.

So all you needs are

==================

void i2c_set_slave_address(uint8_t address) ;

int i2c_test_address(uint8_t address) ;

int i2c_read_byte(uint8_t *value) ;

int i2c_write_byte(uint8_t value) ;

int i2c_read_reg(uint8_t reg_address, uint8_t *value) ;

int i2c_write_reg(uint8_t reg_address, uint8_t value) ;

int i2c_read_regs(uint8_t regaddress, uint8_t *value, int num) ;

==================

And I modified your main.c as follows

==================

#include "project.h"

#include "tty_utils.h"

#include "i2c_utils.h"

#define I2C_AS72XX_SLAVE_STATUS_REG 0x00

#define I2C_AS72XX_SLAVE_WRITE_REG 0x01

#define I2C_AS72XX_SLAVE_READ_REG 0x02

#define I2C_AS72XX_SLAVE_TX_VALID 0x02

#define I2C_AS72XX_SLAVE_RX_VALID 0x01

#define I2C_AS72XX_SLAVE_ADDRESS 0x49

void i2cm_AS72xx_write(uint8_t virtualReg, uint8_t d)

{

    i2c_set_slave_address(I2C_AS72XX_SLAVE_ADDRESS) ;

    i2c_write_reg(virtualReg, d) ;

}

int main(void)

{

    CyGlobalIntEnable; /* Enable global interrupts. */

    I2C_Start();

    for(;;)

    {

        /* Place your application code here. */

    }

}

==================

The project is now compile-able.

So please add other functions required for AS72xx and call it from main()

moto

Hi,

I try to  read reg.

print(i2c_read_byte(0x00));==>Can't I get the information at 0x00?

but the teraterm or putty screen looks blank.

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

My print() function prints only c strings (array of char with 0 terminator).

So please try,

snprintf(str, STR_LEN, "%d\n\r", i2c_read_reg(0x00)) ;

print(str) ;

i2c_read_byte() reads raw data from I2C, which assume that the slave is ready to send data.

But I think that you need to specify the register address to read the value of that register.

moto

0 Likes

Hi,

There  are Errors.

Build error: too few arguments to function 'i2c_read_reg'

Build error: The command 'arm-none-eabi-gcc.exe' failed with exit code '1'.

0 Likes
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

Sorry, it was my bad.

my "i2c_readreg()" takes 2 argument, address and *value to utilize the return value as status.

So please try,

===============

uint8_t value ;

int    status ;

status = i2c_read_reg(REG_ADDRESS, &value) ;

if (status == I2C_MSTR_NO_ERROR) {

    snprintf(str, STR_BUF_LEN, "%d\n\r", value) ;

    pritn(str) ;

} else {

    print("I2C Read Reg Error\n\r') ;

}

===============

moto

0 Likes