How to use the rest of port/pins shared with I2C?

If you have a simple question and just want an answer.
guodian
Member++
Posts: 21
Joined: Sat Nov 12, 2016 10:48 am

How to use the rest of port/pins shared with I2C?

Post by guodian »

Hi,

I use app_usb_aud_xk_216_mc packet code to develop my board. The code declares I2C to the XS1_PORT_4A port as a struct type. And the I2C module just uses the LSB pin and the other three are idle. Now I want to use these three idle pins for another control. But I can't because I know it's can not declare port duplicate and the XS1_PORT_4A port is the narrowest. But I think there must be some ways to resolve it. So who can tell me how can I use the rest three idle pins? Why the I2C uses one pin as we often know I2C relies on SCL and SDA to communicate?

Thanks!


henk
Respected Member
Posts: 347
Joined: Wed Jan 27, 2016 5:21 pm

Post by henk »

Hi guodian,

You may be able to use those pins to drive open-drain outputs.

I don't think that the standard I2C code contains an option to drive the pins, but it shouldn't be hard to add this. (it may have some hardcoded value that you have to remove)

Get the source code for I2C, and edit the module as follows:

- Add a variable to the structure that will hold the value to drive to the remaining 2 pins (e.g., int pin23;)

- Wherever it outputs to the port, make sure it ORs in said variable.

- Add a function to the interface to set pin23 to the desired value (one of 0x0, 0x4, 0x8, or 0xC)

- You could also add a function to the interface to peek at the port and return the value on the pins; anded with 0xC.

Cheers,
Henk
guodian
Member++
Posts: 21
Joined: Sat Nov 12, 2016 10:48 am

Post by guodian »

Thanks henk,

I have tried by this way. It can't add members in the r_i2c struct for that will make errors when build. In fact there

is just one member in the struct and the code use one pin to transfer. That's one what I confused. I don't think it's

a good way to use a 4-bits port to drive the I2C because the other three pins can't access easily.
henk
Respected Member
Posts: 347
Joined: Wed Jan 27, 2016 5:21 pm

Post by henk »

Hi,

There is nothing that stops you from using a 1-bit port for I2C?

Often 4-bit ports are used because I2C is so slow that it can easily be emulated on a 4-bit port, and 1-bit ports are being saved for things that require hi speed (de)serialisation.

There is only a limited number of 1-bit ports, once they are all allocated you start allocating slow tasks to 4-bit ports.

Cheers,
Henk
guodian
Member++
Posts: 21
Joined: Sat Nov 12, 2016 10:48 am

Post by guodian »

Hi henk,
Thank you for your suggestion is helpful. But I don't know if I modify it to 1-bit port will work correctly because it use one line to transfer in the website code. We often know the I2C has two line.
henk
Respected Member
Posts: 347
Joined: Wed Jan 27, 2016 5:21 pm

Post by henk »

You will need to use two 1-bit ports. One for clock and one for data. Have a look at the lib_i2c documentation and let us know if it is unclear
guodian
Member++
Posts: 21
Joined: Sat Nov 12, 2016 10:48 am

Post by guodian »

I didn't add the i2c_lib. I refered to the original code. We can found that It uses the module_i2c_single_port from the Makefile. And the r_i2c struct defined in i2c.h in this module as

/** Struct that holds the data for instantiating the I2C module - it just
* comprises one port (the clock line and the data line are on the same port),
* the only other settable parameter is the speed of the bus which is a compile time
* define.
*/
struct r_i2c {
port p_i2c;
};