- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi all,
I am working on a custom PSoC board and I am having trouble with I2C. I am pretty sure it is a software issue, as I have tested my pins with digital output pin components sending HIGH signals every 500ms and everythiing works fine.. The problem occurs when I try to use I2C on these pins. I do not read any voltage on the oscilloscope in that case.
I have tried a very simple project where I add a SCB block as I2C master, and I send it through the I2C on pins 0.0 and 0.1
I am using PSoC4100S (precisely chip CY8C4125AZI-S433) and I believe I just dont know how to use the API for the SCB blocks.
I am attaching my project file.
I think the problem might be that I am not starting the I2C correctly, or sending data. Here is what I am trying to do:
Thanks a lot for your help!
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
The first problem was my bad.
I included i2c_api_utils.h and modified i2c_api_utils.c in the previous project,
but somehow those files were missing from the archive.
Note: For this project I changed the following line in i2c_api_utils.c
> extern int i2c_dleay ;
< int i2c_delay = 50 ; /* delay in Us */
So I moved them from sources/i2c folder to project folder and made today's archive.
Hopefully it will work without modification (for i2c_delay)
For the second question, in the i2c_api_utils there already is i2c_readRegs() and i2c_writeRegs(),
which will take care of receiving/sending array of data.
I modified the sample as follows,
(And to make sure it is working, I changed the delta for r,g,b, from 10 to 20
and it is working on my desk with CY8CKIT-062-BLE)
========================
for(;;)
{
// i2c_writeReg(0, r) ;
// i2c_writeReg(1, g) ;
// i2c_writeReg(2, b) ;
data[0] = r ;
data[1] = g ;
data[2] = b ;
i2c_writeRegs(0, data, 3) ;
r += 0x20 ;
if (r >= 0x100) {
r = 0 ;
g += 0x20 ;
if (g >= 0x100) {
g = 0 ;
b += 0x20 ;
if (b >= 0x100) {
b = 0 ;
}
}
}
ledPin_Write(~ledPin_Read()) ;
CyDelay(100);
}
========================
moto
P.S.
One more thing, as you tried, depending on the slave device, the delay in i2c_readReg() may need to be longer.
Although I use CyDelayUs(i2c_delay), which is delay of 50 us, you may need longer delay for a particular slave.
So using CyDelay(1), which is 1000us (1ms) could be safer, make the application slower though.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
Maybe I missed something but usually I2C pins are open drain (driving Low).
So we need pull-up resistors for both SCL and SDA.
How about adding resistors of 2K ~10K between SCL and VDD and SDA and VDD?
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I hadn't soldered the pullups on my custom PCB, but I just did this morning and I can see the output I2C pins work. I mean I see a clock signal and a SDA signal on the scope when when running this code
But now, I am trying to get the sent data on another psoc slave device. This slave is a PSoC6 dev kit (062-BLE) and I hooked up the I2C pins from my custom PCB to the dev kit. I need help in designing the software, because I see my buffer remains empty!
GaneshD_41 I tried using the example projects but I cannot read my custom master project with them! I need to modify my slave code so it can populate the buffer and fprint it... I am sure it is very simple but I cannot find the error in my slave code!
I am attaching the 2 projects just in case. I just dont see why my buffer isnt filling up since I have set it and started the i2c in the slave main...
Thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
For me the good news was that your master program on PSoC 4 seemed to be working OK,
but the bad news was that I can not manage the PSoC 6 part working.
So I just borrowed the working CE of PSoC 6, CE220541.
And for the PSoC 4 part, I cheated by using i2c utils from my sample code MCU Tester (TSoC version)
Re: MCU Tester, a Swiss Army Knife for PSoC (TSoC version)
So I replaced the EZI2C in the schematic to I2C
and since CY8C4146LQI-S433 was the closest device I have an evaluation board,
I changed the device to CY8C4146LQI-S433.
I tried to keep the pins, so hopefully if you change the device to CY8C4125AZI-S422, it will also work on your board.
pins
Note: I tried not to change the pins, but please double check them to match with your board.
main.c
============================
#include <project.h>
#include "i2c_api_utils.h"
/* LED constants for turning the RGB LED on and off */
#define LED_ON (0xFFu)
#define LED_OFF (0x00u)
void init_hardware(void)
{
CyGlobalIntEnable;
I2C_Start() ;
i2c_set_slave_address(0x08) ;
}
int main()
{
int i = 0 ;
int r = 0 ;
int g = 0 ;
int b = 0 ;
init_hardware() ;
ledPin_Write(1);
ledPin2_Write(1);
CyDelay(500);
ledPin_Write(0);
ledPin2_Write(0);
for(;;)
{
i2c_writeReg(0, r) ;
i2c_writeReg(1, g) ;
i2c_writeReg(2, b) ;
r += 0x10 ;
if (r >= 0x100) {
r = 0 ;
g += 0x10 ;
if (g >= 0x100) {
g = 0 ;
b += 0x10 ;
if (b >= 0x100) {
b = 0 ;
}
}
}
ledPin_Write(~ledPin_Read()) ;
CyDelay(100);
}
}
============================
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
The write access code of your I2C master is 1-byte transfer.
However, write access to EZ-I2C slave requires at least 2-bytes (subaddress and data).
Your buffer remains empty because you are only writing the subaddress.
Motoo's slave sample project is not EZ-I2C, so it works fine with 1-byte write access.
See page 17 of the EZ-I2C component datasheet for more detail.
https://www.cypress.com/documentation/component-datasheets/ezi2c-slave
Thanks
Omoi
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you so much, I managed to make it work with the projects you shared. I really like your i2c utils, it makes it easy to understand. There was an error when building at first, there is an external reference to a i2c_delay variable in your library, and I needed to replace CyDelay(i2c_delay); with CyDelay(1);
1. I was wondering why a delay is necessary after all, it seems to work with a delay of 1ms but what was the intended value of i2c_delay? and could I just remove the delay while still having a robust communication?
2. I have problems trying to send multiple byte variables with your library. Ultimately I want to send capsense data to the psoc 6 through I2C. And capsense sensor values are stored in uint32_t. Do you have an example of how you would send this with your library? I could also just parse the uint32 into an array of uint8 and send them individually with your writeReg function like so
but it doesnt seem very efficient, especially if I have to send uint32 variables for each of my 49 sensors in my 7x7 capsense trackpad.. I was thinking writeRegs might be the way you would do it?
Thanks again!!
HiOm_1802421 I replaced the ezi2c for an i2c scb as motoo did. Thanks for this clarification.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi,
The first problem was my bad.
I included i2c_api_utils.h and modified i2c_api_utils.c in the previous project,
but somehow those files were missing from the archive.
Note: For this project I changed the following line in i2c_api_utils.c
> extern int i2c_dleay ;
< int i2c_delay = 50 ; /* delay in Us */
So I moved them from sources/i2c folder to project folder and made today's archive.
Hopefully it will work without modification (for i2c_delay)
For the second question, in the i2c_api_utils there already is i2c_readRegs() and i2c_writeRegs(),
which will take care of receiving/sending array of data.
I modified the sample as follows,
(And to make sure it is working, I changed the delta for r,g,b, from 10 to 20
and it is working on my desk with CY8CKIT-062-BLE)
========================
for(;;)
{
// i2c_writeReg(0, r) ;
// i2c_writeReg(1, g) ;
// i2c_writeReg(2, b) ;
data[0] = r ;
data[1] = g ;
data[2] = b ;
i2c_writeRegs(0, data, 3) ;
r += 0x20 ;
if (r >= 0x100) {
r = 0 ;
g += 0x20 ;
if (g >= 0x100) {
g = 0 ;
b += 0x20 ;
if (b >= 0x100) {
b = 0 ;
}
}
}
ledPin_Write(~ledPin_Read()) ;
CyDelay(100);
}
========================
moto
P.S.
One more thing, as you tried, depending on the slave device, the delay in i2c_readReg() may need to be longer.
Although I use CyDelayUs(i2c_delay), which is delay of 50 us, you may need longer delay for a particular slave.
So using CyDelay(1), which is 1000us (1ms) could be safer, make the application slower though.