- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi All,
I tried to implement I2C communication between Cy8C4025AZI-S412( Slave ) and Pic Microcontroller(Master). The speed is 100kbps and used polling method. When button not pressed then it will sent 0xFF. The polling time is 100msec by PIC controller.
The issue is,
1) Sometimes acknowledge not given by Slave.(need to sent data 3 to 4 times or delay of 30ms then it gives ack ).
I used one example code to develop I2C.
My code is below,
#include <project.h>
/* Macro Declaration */
#define BUFFER_SIZE (1u)
#define PACKET_SIZE (BUFFER_SIZE)
/* The I2C Slave read and write buffers */
uint8 i2cReadBuffer [BUFFER_SIZE] = {0};
uint8 i2cWriteBuffer[BUFFER_SIZE]= {0};
uint8_t flag1=0;
uint8_t flag3=0;
void Received_Data_From_Master1();
int main()
{
/* Eneble Global Interrupt */
CyGlobalIntEnable;
CapSense_Start();
CapSense_ScanAllWidgets();
/* Start the I2C Slave And I2C Address Setting*/
I2CS_I2CSlaveInitReadBuf(i2cReadBuffer, BUFFER_SIZE);
I2CS_I2CSlaveInitWriteBuf(i2cWriteBuffer, BUFFER_SIZE);
I2CS_I2CSlaveSetAddress(0x08);
I2CS_Start();
for (;;)
{
CyDelay(2);
/* With Respect to Master i.e Checked Whether the Master Write Complted Or Not */
if (0u != (I2CS_I2CSlaveStatus() & I2CS_I2C_SSTAT_WR_CMPLT))
{
/* Calling Function to Collect The Data From Master */
Received_Data_From_Master1();
/* Enable this above function when we used the data On Switch Function */
/* Clear the slave write buffer and status */
I2CS_I2CSlaveClearWriteBuf();
(void) I2CS_I2CSlaveClearWriteStatus();
}
if(CapSense_NOT_BUSY == CapSense_IsBusy())
{
/* API For Capsense Update Scanning And Process */
CapSense_ProcessAllWidgets(); /* Process all widgets */
CapSense_RunTuner(); /* To sync with Tuner application */
/* Checked whether Left Button Active or Not*/
if((flag3==0)&&(CapSense_IsWidgetActive(CapSense_BUTTON2_WDGT_ID)) )
{
flag3=1; /* Reseting Left Button Flag */
i2cReadBuffer[0] = 0x01;
while (I2CS_I2C_SSTAT_RD_CMPLT!=(I2CS_I2CSlaveStatus()));
/* Clear the slave read buffer and status */
I2CS_I2CSlaveClearReadBuf();
(void) I2CS_I2CSlaveClearReadStatus();
i2cReadBuffer[0] = 0xFF;
}
else if((flag3==1) && (!(CapSense_IsWidgetActive(CapSense_BUTTON2_WDGT_ID))))
{
flag3=0; /* Setting Left Button Flag */
i2cReadBuffer[0] = 0xFF;
}
/* Checking Right Button active or not */
if((flag1==0)&&(CapSense_IsWidgetActive(CapSense_BUTTON0_WDGT_ID)))
{
flag1=1; /* Reseting the flag*/
i2cReadBuffer[0] = 0x06;
while (I2CS_I2C_SSTAT_RD_CMPLT!=(I2CS_I2CSlaveStatus()));
/* Clear the slave read buffer and status */
I2CS_I2CSlaveClearReadBuf();
( void) I2CS_I2CSlaveClearReadStatus();
i2cReadBuffer[0] = 0xFF;
}
else if((flag1==1)&& (!(CapSense_IsWidgetActive(CapSense_BUTTON0_WDGT_ID))))
{
flag1=0;
}
}
}
}
void Received_Data_From_Master1()
{
switch(i2cWriteBuffer[0])
{
/* After Receiving 00 touch will be Ready to Work */
case 0x00:
i2cReadBuffer[0] = 0x19; /*According to New Document Wants to transmit new data acknowledgement */
POWER_LED_Write(0);
break;
}
}
Any Help will be highly appreciated .
Thanks & Regards,
AsDh
Solved! Go to Solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The issue is caused mostly due to the delay at the beginning of the loop. I modified the code to the following:
#include <project.h>
/* Macro Declaration */
#define BUFFER_SIZE (1u)
#define PACKET_SIZE (BUFFER_SIZE)
/* The I2C Slave read and write buffers */
uint8 i2cReadBuffer [BUFFER_SIZE] = {0};
uint8 i2cWriteBuffer[BUFFER_SIZE]= {0};
uint8_t flag1=0;
uint8_t flag3=0;
void Received_Data_From_Master1();
int main()
{
/* Eneble Global Interrupt */
CyGlobalIntEnable;
CapSense_Start();
CapSense_ScanAllWidgets();
/* Start the I2C Slave And I2C Address Setting*/
I2CS_I2CSlaveInitReadBuf(i2cReadBuffer, BUFFER_SIZE);
I2CS_I2CSlaveInitWriteBuf(i2cWriteBuffer, BUFFER_SIZE);
I2CS_I2CSlaveSetAddress(0x08);
I2CS_Start();
for (;;)
{
//CyDelay(2);
/* With Respect to Master i.e Checked Whether the Master Write Complted Or Not */
if (0u != (I2CS_I2CSlaveStatus() & I2CS_I2C_SSTAT_WR_CMPLT))
{
/* Calling Function to Collect The Data From Master */
Received_Data_From_Master1();
/* Enable this above function when we used the data On Switch Function */
/* Clear the slave write buffer and status */
I2CS_I2CSlaveClearWriteBuf();
(void) I2CS_I2CSlaveClearWriteStatus();
}
if (0u != (I2CS_I2CSlaveStatus() & I2CS_I2C_SSTAT_RD_CMPLT))
{
/* Clear the slave read buffer and status */
I2CS_I2CSlaveClearReadBuf();
(void) I2CS_I2CSlaveClearReadStatus();
}
if(CapSense_NOT_BUSY == CapSense_IsBusy())
{
/* API For Capsense Update Scanning And Process */
CapSense_ProcessAllWidgets(); /* Process all widgets */
CapSense_RunTuner(); /* To sync with Tuner application */
/* Checked whether Left Button Active or Not*/
if((flag3==0)&&(CapSense_IsWidgetActive(CapSense_BUTTON2_WDGT_ID)) )
{
POWER_LED_Write(0);
flag3=1; /* Reseting Left Button Flag */
i2cReadBuffer[0] = 0x01;
// while (I2CS_I2C_SSTAT_RD_CMPLT!=(I2CS_I2CSlaveStatus()));
// /* Clear the slave read buffer and status */
// I2CS_I2CSlaveClearReadBuf();
// (void) I2CS_I2CSlaveClearReadStatus();
//i2cReadBuffer[0] = 0xFF;
}
else if((flag3==1) && (!(CapSense_IsWidgetActive(CapSense_BUTTON2_WDGT_ID))))
{
flag3=0; /* Setting Left Button Flag */
i2cReadBuffer[0] = 0xFF;
}
/* Checking Right Button active or not */
if((flag1==0)&&(CapSense_IsWidgetActive(CapSense_BUTTON0_WDGT_ID)))
{
flag1=1; /* Reseting the flag*/
i2cReadBuffer[0] = 0x06;
// while (I2CS_I2C_SSTAT_RD_CMPLT!=(I2CS_I2CSlaveStatus()));
// /* Clear the slave read buffer and status */
// I2CS_I2CSlaveClearReadBuf();
// ( void) I2CS_I2CSlaveClearReadStatus();
i2cReadBuffer[0] = 0xFF;
}
else if((flag1==1)&& (!(CapSense_IsWidgetActive(CapSense_BUTTON0_WDGT_ID))))
{
flag1=0;
}
CapSense_ScanAllWidgets();
}
}
}
void Received_Data_From_Master1()
{
switch(i2cWriteBuffer[0])
{
/* After Receiving 00 touch will be Ready to Work */
case 0x00:
i2cReadBuffer[0] = 0x19; /*According to New Document Wants to transmit new data acknowledgement */
POWER_LED_Write(0);
break;
}
}
/* [] END OF FILE */
The major difference is the I2C receiver code at the beginning of the loop to clear after a transaction and the CapSense_ScanAllWidgets() API at the end of the CapSense_IsBusy() condition.
I tried this out with Bridge control panel (Which is installed along with PSoC Creator) as the host and there was no NACK by the slave. Please try this out and let me know if this works.
Best regards,
Hari
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The issue is caused mostly due to the delay at the beginning of the loop. I modified the code to the following:
#include <project.h>
/* Macro Declaration */
#define BUFFER_SIZE (1u)
#define PACKET_SIZE (BUFFER_SIZE)
/* The I2C Slave read and write buffers */
uint8 i2cReadBuffer [BUFFER_SIZE] = {0};
uint8 i2cWriteBuffer[BUFFER_SIZE]= {0};
uint8_t flag1=0;
uint8_t flag3=0;
void Received_Data_From_Master1();
int main()
{
/* Eneble Global Interrupt */
CyGlobalIntEnable;
CapSense_Start();
CapSense_ScanAllWidgets();
/* Start the I2C Slave And I2C Address Setting*/
I2CS_I2CSlaveInitReadBuf(i2cReadBuffer, BUFFER_SIZE);
I2CS_I2CSlaveInitWriteBuf(i2cWriteBuffer, BUFFER_SIZE);
I2CS_I2CSlaveSetAddress(0x08);
I2CS_Start();
for (;;)
{
//CyDelay(2);
/* With Respect to Master i.e Checked Whether the Master Write Complted Or Not */
if (0u != (I2CS_I2CSlaveStatus() & I2CS_I2C_SSTAT_WR_CMPLT))
{
/* Calling Function to Collect The Data From Master */
Received_Data_From_Master1();
/* Enable this above function when we used the data On Switch Function */
/* Clear the slave write buffer and status */
I2CS_I2CSlaveClearWriteBuf();
(void) I2CS_I2CSlaveClearWriteStatus();
}
if (0u != (I2CS_I2CSlaveStatus() & I2CS_I2C_SSTAT_RD_CMPLT))
{
/* Clear the slave read buffer and status */
I2CS_I2CSlaveClearReadBuf();
(void) I2CS_I2CSlaveClearReadStatus();
}
if(CapSense_NOT_BUSY == CapSense_IsBusy())
{
/* API For Capsense Update Scanning And Process */
CapSense_ProcessAllWidgets(); /* Process all widgets */
CapSense_RunTuner(); /* To sync with Tuner application */
/* Checked whether Left Button Active or Not*/
if((flag3==0)&&(CapSense_IsWidgetActive(CapSense_BUTTON2_WDGT_ID)) )
{
POWER_LED_Write(0);
flag3=1; /* Reseting Left Button Flag */
i2cReadBuffer[0] = 0x01;
// while (I2CS_I2C_SSTAT_RD_CMPLT!=(I2CS_I2CSlaveStatus()));
// /* Clear the slave read buffer and status */
// I2CS_I2CSlaveClearReadBuf();
// (void) I2CS_I2CSlaveClearReadStatus();
//i2cReadBuffer[0] = 0xFF;
}
else if((flag3==1) && (!(CapSense_IsWidgetActive(CapSense_BUTTON2_WDGT_ID))))
{
flag3=0; /* Setting Left Button Flag */
i2cReadBuffer[0] = 0xFF;
}
/* Checking Right Button active or not */
if((flag1==0)&&(CapSense_IsWidgetActive(CapSense_BUTTON0_WDGT_ID)))
{
flag1=1; /* Reseting the flag*/
i2cReadBuffer[0] = 0x06;
// while (I2CS_I2C_SSTAT_RD_CMPLT!=(I2CS_I2CSlaveStatus()));
// /* Clear the slave read buffer and status */
// I2CS_I2CSlaveClearReadBuf();
// ( void) I2CS_I2CSlaveClearReadStatus();
i2cReadBuffer[0] = 0xFF;
}
else if((flag1==1)&& (!(CapSense_IsWidgetActive(CapSense_BUTTON0_WDGT_ID))))
{
flag1=0;
}
CapSense_ScanAllWidgets();
}
}
}
void Received_Data_From_Master1()
{
switch(i2cWriteBuffer[0])
{
/* After Receiving 00 touch will be Ready to Work */
case 0x00:
i2cReadBuffer[0] = 0x19; /*According to New Document Wants to transmit new data acknowledgement */
POWER_LED_Write(0);
break;
}
}
/* [] END OF FILE */
The major difference is the I2C receiver code at the beginning of the loop to clear after a transaction and the CapSense_ScanAllWidgets() API at the end of the CapSense_IsBusy() condition.
I tried this out with Bridge control panel (Which is installed along with PSoC Creator) as the host and there was no NACK by the slave. Please try this out and let me know if this works.
Best regards,
Hari
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Hari,
Master(PIC) polling time is every 100ms .
when button not pressed, I need to sent 0xFF and button pressed then sent particular button data like 0x01,0x06 etc.
I have run one timer in Cy8C4025AZI-S412 of 100ms for sending data 0xFF when button not pressed .
but sometimes data got missing...
Any Solution to achieved the proper communication.
Thanks & Regards,
AsDh
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Hari,
In Above scenario, I found the NAK Signal During the write frame.
I have attached the logic analyzer observation result for the same.
Master Device:- PIC Controller
Slave Device :- Cy8C4025AZI-S413
My Slave Address is 0x08
Ideally After Address byte their should be ACK From Slave but I observed NAK Signal.
I am not getting where is the exact mistake?
Any help will be highly appreciated.
Regards,
AsDh
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Can you try sending the master's command using Bridge control panel? This program is automatically installed with PSoC creator and emulates an I2C master. You can use any USB to I2C bridge and send the commands.
Best regards,
Hari