I2C's IO port Initialize

10 posts / 0 new
Last post
jamesleo-konka
Offline
Last seen:3 years 9 months ago
Joined:2017-01-22 02:42
I2C's IO port Initialize

Hi, Dialog
I'm studying peripherals_demo, and find the initializing of UART's GPIO ports/pins.
But thers is no code doing the I2C's GPIO port/pins.
Should I do the initializing of I2C's GPIO port/pins ? How to ? Or I miss something?

Thanks

Keywords:
Device:
MT_dialog
Offline
Last seen:1 week 5 hours ago
Staff
Joined:2015-06-08 11:34
Hi jamesleo-konka,

Hi jamesleo-konka,

Please check in the gpio_setup.h file in the peripherals_demo\config\default directory, there you will find the definitions for every gpio used and then the peirph_setup() function in the periph_setup.c you will find the initialization of the pins by the hw_gpio_configure() function.

Thanks MT_dialog

jamesleo-konka
Offline
Last seen:3 years 9 months ago
Joined:2017-01-22 02:42
Hi MT_Dialog,

Hi MT_Dialog,
Sorry I missed the GPIO config code, they are redefined as CFG_GPIO_I2C1_SCL_PORT, and use the macro HW_GPIO_PINCONFIG to initialize.

Thanks

jamesleo-konka
Offline
Last seen:3 years 9 months ago
Joined:2017-01-22 02:42
Hi MT_Dialog,

Hi MT_Dialog,
I put the following code in periph_setup in project hrp_sensor:
//------------------------------
/ /——I2C端口/销配置——P3.5 = sci, P1.2 = SDA--------
hw_gpio_configure_pin(HW_GPIO_PORT_3,HW_GPIO_PIN_5, HW_GPIO_MODE_OUTPUT,HW_GPIO_FUNC_GPIO,true);
hw_gpio_configure_pin(HW_GPIO_PORT_1,HW_GPIO_PIN_2, HW_GPIO_MODE_INPUT_PULLUP,HW_GPIO_FUNC_GPIO,true);

hw_gpio_set_pin_function(HW_GPIO_PORT_3, HW_GPIO_PIN_5, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_I2C_SCL);
hw_gpio_set_pin_function(HW_GPIO_PORT_1, HW_GPIO_PIN_2, HW_GPIO_MODE_INPUT_PULLUP, HW_GPIO_FUNC_I2C_SDA);
//------------------------------
Is it right?
I'm a bit confused about the 2 init functions: hw_gpio_configure_pin, hw_gpio_set_pin_function.
For a pin, we can set it as input/output (with/without pull, or push_pull, or speed), and then we set the alternal functions.
Why should I set the mode (input/output) two times in the 2 functions?

Why the RX pin is set as output:
hw_gpio_configure_pin(HW_GPIO_PORT_2, HW_GPIO_PIN_3, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_GPIO, 1);
hw_gpio_set_pin_function(HW_GPIO_PORT_2, HW_GPIO_PIN_3, HW_GPIO_MODE_OUTPUT, HW_GPIO_FUNC_UART2_RX); ?

in platform_devices.h, there are many line to init the I2C devices ,like:
I2C_SLAVE_DEVICE(I2C1, BH1750, 0x23, HW_I2C_ADDRESSING_7B, HW_I2C_SPEED_FAST);

but I can't find the definning of BH1750, MEM_24LC256,FM75,,,, --they are used in ad_i2c_open() also.

Thanks

MT_dialog
Offline
Last seen:1 week 5 hours ago
Staff
Joined:2015-06-08 11:34
Hi jamesleo-konka,

Hi jamesleo-konka,

The hw_gpio_configure_pin() includes the hw_gpio_set_pin_function() you can have a look at the code or at the doxygen for the description of each function. The hw_gpio_set_pin_function() is enough to configure your pins, the hw_gpio_configure_pin() does the same thing but it additionally sets a default state of the pin if its going to be active of inactive. Regarding the reason for the setting of the UART RX as output and using both of the gpio function in order to set the RX of the UART i suppose that you saw this in the periph_init() function of the hrp_sensor project, so, right above the settings of the pin there is an explanation for this, in short, this is workaround for the Jlink emulated serial port.

There is no definition they are just names used by the macro I2C_SLAVE_DEVICE and after doing that you will be able to use them in order to open the adapter.

Thanks MT_dialog

jamesleo-konka
Offline
Last seen:3 years 9 months ago
Joined:2017-01-22 02:42
Hi MT_Dialog,

Hi MT_Dialog,
Is the following the right sequence for use of I2C adapter:
1. first declaring the I2C devices:
I2C_BUS(I2C1)
I2C_SLAVE_DEVICE(I2C1, BME280, 0x76, HW_I2C_ADDRESSING_7B, HW_I2C_SPEED_STANDARD); //
I2C_BUS_END
2. operate I2C devices
i2c_device dev;
static char wbuf[5] = „Test”;
char rbuf[5];
dev = ad_i2c_open(BME280); /* Open selected device */
ad_i2c_bus_acquire(dev); /* Acquire access to bus */
ad_i2c_write(dev, wbuf, sizeof(wbuf)); /* Write synchronously some data to I2C device *///--this will generate START,send SLAVE address(W),send reg address,write data
ad_i2c_read(dev, rbuf, sizeof(rbuf), 100); /* Read synchronously the data from I2C device */ // I2C change direction,generate RESTART, send SLAVE address(R),send reg address,read data , generate STOP
ad_i2c_bus_release(dev); /*Release the I2C
ad_i2c_close(dev); /* Close selected device */

Another Question:
1. when to use ad_i2c_init()?
2. should ad_i2c_xx be called after starting the task ? Can I do the I2C device initialization after power on reset (no task running)?
4. to write one data into I2C device's register, may I refer to the following:
ad_i2c_write(dev, wbuf, 2); // 2 byte,first= reg address, second= data

Thanks

jamesleo-konka
Offline
Last seen:3 years 9 months ago
Joined:2017-01-22 02:42
Hi MT_dialog

Hi MT_dialog
Thanks a lot.
There are too much Macros and it's not easy to analyse/trace the source code.

The sample project peripherals_demo make user confused with hw_i2c_xx and ad_i2c_xx, especialy in eeprom_24xx256.c . Both hw_i2c_xx and ad_i2c_xx are used at the same time.

When will user call the ad_i2c_init() ? I don't find the code which calling ad_i2c_init().

James

MT_dialog
Offline
Last seen:1 week 5 hours ago
Staff
Joined:2015-06-08 11:34
Hi jamesleo-konka,

Hi jamesleo-konka,

That sequence of the commands that you invoke depends on the SDK that you are using, for example on the latest SDK:

1) Yes, your assignment of the device on the I2C bus is proper.

2) Getting the handle of the device when you are about to start a transaction is proper (ad_i2c_open(BME280)) is also proper, the ad_i2c_bus_aquire() is not a necessity since the ad_i2c_write() and ad_i2c_read() perform the aquire of the bus and the device and also the release of the bus and the device.

Also, just to get things straight since you would like to generate a restart condition, the restart condition is generated when you read from the bus, that means that you will have to provide (therefore write on the i2c bus) the address of the register that you would like to read, the above code i dont think that produces a restart condition between the ad_i2c_write() and the ad_i2c_read() (the RESTART condition is triggered between the write and the read on bus during the ad_i2c_read() operation). Between the ad_i2c_write and the ad_i2c_read there should be a STOP condition as far as i can tell. The restart condition is generated is where you mentioning it in your post.

Regarding your other questions:

1) The ad_i2c_init() is invoked during the system_init() function in the prvSetupHardware(), in the pm_system_init() function there is an additional function called init_adapters() and from that function all the enabled adapters are being initialized.

2)系统将让适配器know for the wake up or power up and the adapters will initialize the hw as long as you have configured them, that happens when the system is powering up or waking up by default.

3) Yes i suppose that you can do that.

Thanks MT_dialog

jamesleo-konka
Offline
Last seen:3 years 9 months ago
Joined:2017-01-22 02:42
Hi, MT_Dialog,

Hi, MT_Dialog,
Thanks for your help, my ad_i2c_xx has begun and I got the output of I2C port.
It seems like that ad_i2c_write() and ad_i2c_read() can't generate RESTART signal because both of them has done the complete steps of an I2C operation: START, SLAVE address (W/R), data(W/R),,,,STOP.
Should the user use hw_i2c_xx to generate RESTART signal? pls show me a sample code.

Thanks

MT_dialog
Offline
Last seen:1 week 5 hours ago
Staff
Joined:2015-06-08 11:34
Hi jamesleo-konka,

Hi jamesleo-konka,

As mentioned above, usually the RESTART condition is generated when you would like to read out a value from the I2C slave (the I2C master will write on the bus the address of the register that it would like to read and then issue a RESTART in order to start reading). The ad_i2c_write() and ad_i2c_read() will execute a seperate write and read. With the current I2C module that the 68x is equipped you wont be able to write and then force a restart condition in order to write the address for a read operation. The reason for that is that, as mentioned the I2C module will automatically generate the STOP condition when its FIFO is emtpy and the RESTART condition when you change operation.

So lets assume that you start writing data at your slave and you decide that you would like to read, so you will have to write the register address of the slave, that you would like to read, on the bus, so you will provide the address that you would like to read to the I2C FIFO in order not to generate a STOP (remember if your FIFO is empty the I2C will send a STOP condition). If you provide the address of the I2C slave that you would like to read the module doesn't have a way of knowing that this is an address and that you would like to read now, and will send the address on the same transaction as data, since you didn't switch from write to read in order to generate a restart.

So to sum up there is no way that i am aware of in order to force a RESTART condition on the I2C (perhaps you could make a dummy read in order to force the RESTART and then start the proper reading transaction, write the address and read again, but this will cause two RESTART conditions as far as i can tell and i am not sure how any slave will handle that) although i am not able to see what is wrong with the STOP condition between the actual reads and writes ?

Thanks MT_dialog