Hello everybody, due to different voltage levels of some I2C slave devices I need to implement a secondary I2C master on the GPIO_51 (SCL) and GPIO_52 (SDA) on a CX3 device. Usually these pins are shared with the I2S block I2S_SD and I2S_WD but it seems that they can be used as GPIO as well.
I was wondering if there is any configuration in the I/O matrix that can reassign the CX3 hardware I2C master signals to these two pins and if not (most likely not possible ) what will be the best strategy of use for a bit-banging I2C master.
I have seen from some other knowledge base articles methods of increasing the bit-bang I2C clock by calling functions that bypass the libraries checks when toggling SCL.
I didn't see any advice of switching the SDA pin form input to output and vice-versa.
Can some of the Cypress staff or forum members offer some advice or even better, direct me to some sample code if that exists.
Many tanks, MC
Please note that the dedicated I2C Pins can range from 1.6V to 3.3V. The same voltage range applies for the pins 51 and 52 too. So, I think you can implement your master with the Dedicated I2C Block itself.
Yes, there is an option for overriding pins 51 and 52 as GPIOs using the CyU3PDeviceGpioOverride API (refre Fx3 API guide for more details).
You can configure them as GPIOs and use them. We do have an example project in which an SPI Master is implemented using Bit banging. You can refer the same for I2C to know how the GPIOs the controlled. It is available in "C:\Program Files (x86)\Cypress\EZ-USB FX3 SDK\1.3\firmware\serialif_examples\cyfxusbspigpiomode".
For configuring the GPIOs, we use the CyU3PGpioSetSimpleConfig API. Here we can specify that the GPIO can be used as both input and output (For the SDA pin). Please note that bit banging will take all CPUs time and other operations of FX3 will be affected when the Bit Banged I2C master is in operation.
Dear Madhu, first thank you for your quick reply, now some explanation:
I'm forced to use a software I2C master because I need to talk to two different I2C set of devices, one that has the Vcc = 1.8V and another set that has the Vcc = 2.5V. As we don't want to use extra I2C level translators (that are problematic at best ) and one of slave sets has very few registers and they are not time critical ( the usage is of type "set and forget" at power-up ) I've decided to do a bit-bang I2C master using the I2S pins configured as GPIOs, that have a different voltage domain than the hardware I2C master.
In the CX3 datasheet I2C block has the voltage defined by VddIO1 and the I2S block has the voltage defined by VddIO2 except for the I2S_Clk pin that has the voltage defined by the VddIO3 but that is not used in my software defined I2C master.
So if possible please explain your assertion that "Please note that the dedicated I2C Pins can range from 1.6V to 3.3V. The same voltage range applies for the pins 51 and 52 too." I hope you wanted to say that the voltage range it's the same but I hope that they are on the different VDDs as described in the datasheet.
From your response I understand that I can configure the GPIO_52 pin in a way that is compatible with the SDA pin of an I2C master, meaning that the firmware does not need to switch the pin configuration in between Input and Output modes during operation and the I2C slaves will be able to pull down the pin and when I read it I will actually read the electrical state of the pin.
Please confirm this to me as it is very important and not obvious, the SPI example can't be used as an SPI device has separate Input and Output pins.
A short code example for the pin configuration and setting the state to 0 and 1 will be most appreciated.
(I believe that when the pin it's used for input it has to be set to 1 for the slave to be able to pull it down, is this correct ?)
Best regards, MC
Hi Madhu, are there any news on my question: what is the correct configuration for a GPIO pin to be able to use it as SDA pin in a bit-banging I2C master implemented in software ?
I has to be something that pulls down strong when in 0 but doesn't pull up and in 1 must let the bus resistor to pull up so the slave devices can pull down.
You have said that "CyU3PGpioSetSimpleConfig API. Here we can specify that the GPIO can be used as both input and output (For the SDA pin)."
But in the description of the CyU3PGpioSetSimpleConfig parameters we have: "For use as a normal output pin, both driveLowEn and driveHighEn need to be CyTrue and inputEn needs to be CyFalse. Similarly for use as a normal input pin, inputEn must be CyTrue and both driveLowEn and driveHighEn should be CyFalse."
So for an I/O pin with O of type open_drain(collector) what should be right values for:
• CyBool_t outValue
• CyBool_t driveLowEn
• CyBool_t driveHighEn
• CyBool_t inputEn
• CyU3PGpioIntrMode_t intrMode
( I don't need any interrupts associated to this pin)
Many thanks, MCM