cancel
Showing results for 
Search instead for 
Did you mean: 

PSoC 5, 3 & 1 MCU

New Contributor II

Hello,

When the I2C write to PSoC register from host, host program compared write data and read back data.

Read from I2C slave of EzI2C returns sometimes wrong value (data is Address value) to Host. Frequency is about 1 in 100 times read.

After one or two more write and read after waiting 20ms, I2C slave returned the correct data value.

For find the root cause, we captured I2C signals as attached excel file when it returned wrong value and I thought these signals are a correct normal read operation.

We did not find root cause as of now. I attached the captured signals and main.c. If you have information about it, please let me know.    

0 Likes
Reply
1 Solution
New Contributor II

Hello Sampath-san,

Thank you for sharing above materials.

For result of our long run test of 1 week, Ez I2C slave did not return wrong data after interrupt code change. I realized that it is important to shorten the time of other interrupt programs because the interrupt priority of I2C is low.

Also, I shared the before/after program for reference. Thank you for your help.

(Interrupt timer : change from 765us of 2ms to 67 us of 2ms)

[before]

/*********************************************************

* Timer interrupt handler                               *

*********************************************************/

#pragma interrupt_handler Timer8_2ms_ISR

void Timer8_2ms_ISR(void)

{

  BYTE  i;

  //HDD Detect Check & Auto Power-off Control

  chkHddDetect();

  chkHddDetect();

/********* Decrement Timer *********************/

  if (bLED_timer)   bLED_timer--;

  // deleted no use timer 

  if (wPERST_wait_timerwPERST_wait_timer--;

 

  for (i=0; i<4; i++)

  {

     if (wPG_init_timer[i])  wPG_init_timer[i]--;

  if (wVOL_init_timer[i])  wVOL_init_timer[i]--;

  if (bCURR_Samp_timer[i]) bCURR_Samp_timer[i]--;

  }

/********* Debug LED ***************************/

  if (wCnt_1sec){

  wCnt_1sec--;

  } else{

  if (bDebugLed_Error_Flag) //Error表示

  {

  wCnt_1sec = bwait100ms_timer;

  }else {

  wCnt_1sec = wDEBUG_LED_timer / TIMER_SETTING_VAL;

  }

  DEBUG_LED_Data_ADDR ^= DBG_LED;

   }

}

[After]

/*********************************************************

* Timer interrupt handler                               *

*********************************************************/

#pragma interrupt_handler Timer8_2ms_ISR

void Timer8_2ms_ISR(void)

{

  BYTE  i;

  M8C_EnableGInt;  /* H.H */

  bFlagChkHddDetect = 1;  /* H.H Executing chkHddDetect() timer is time-upped */

/********* Decrement Timer *********************/

  if (bLED_timer)   bLED_timer--;

  if (wPERST_wait_timerwPERST_wait_timer--;

  if (wVOL_init_timer0)  wVOL_init_timer0--;

  if (wVOL_init_timer1)  wVOL_init_timer1--;

  if (wVOL_init_timer2)  wVOL_init_timer2--;

  if (wVOL_init_timer3)  wVOL_init_timer3--;

  if (bCURR_Samp_timer03)  bCURR_Samp_timer03--;

/********* Debug LED ***************************/

  if (wCnt_1sec){

  wCnt_1sec--;

  } else{

  if (bDebugLed_Error_Flag) //Error表示

  {

  wCnt_1sec = WAIT_DEBUG_100ms;

  }else {

  wCnt_1sec = DEBUG_LED_TIME_VALUE / TIMER_SETTING_VAL;

  }

  DEBUG_LED_Data_ADDR ^= DBG_LED;

   }

  PERSTn_1_Data_ADDR &= ~PERSTn_1_MASK;/* H.H PERST#1 negate for debug (A65_2) */

}

View solution in original post

0 Likes
Reply
10 Replies
Moderator
Moderator

Hello Kusa-san,

The C program you have attached is very large. In my opinion, the EzI2C User Module seems to work fine. Can you check if the RAM location itself changes to 0x0f?

Best regards,

Sampath Selvaraj

0 Likes
Reply
New Contributor II

Hello Sampath-san,

Thank you for your reply.

If you can, could you please tell me how to check RAM location and to change location?

Also, we added more read back retry on host program, but other register occured same issue. I'd like to fix this problem seriously.

I have several questions.

1. If PSoC Program will be added the I2C status check and activity check, do you think this issue will be detected?

2. If I2CHW and I2Cm module will be changed from EzI2C, do you think it will be improved?      

0 Likes
Reply
Moderator
Moderator

Hello Kusagaya-san,

If you can add another serial interface, you can periodically output the ExI2C buffer and check if the values change.

To answer your questions:

1. If PSoC Program will be added the I2C status check and activity check, do you think this issue will be detected?

2. If I2CHW and I2Cm module will be changed from EzI2C, do you think it will be improved?

My answer is same for both the questions:

In my opinion, the buffer gets changed by some other code. Hence, adding a monitor or changing the user modules will only report the defect, and may not resolve your issue.

On seeing the contents of your main.c, I think that there have been many version changes. Do you happen to know any version where the I2C communication was proper? If you can debug from that version, you may be able to detect the defect. Do you have our ICE Debugger? Using the ICE Debugger, you can detect changes in the EzI2C RAM buffer.

Best regards,

Sampath Selvaraj

0 Likes
Reply
New Contributor II

Hello Everyone,

Regarding EzI2C.

I would like to know contents of the EzI 2 C hardware (buffer number and interrupt method) and software control method. Would you please provide some information if you can find out?

0 Likes
Reply
New Contributor II

Hello Sampath-san,

Thank you so much for your reply.

I will consider to buy ICE Debugger.

This code was took over from other company and we encounter the problem of I2C wrong read value after we revised it.

Read back mismatch data error occurred 600 of 5000 cycles now and then we are thinking about F/W coding problem, but code bug was not found now.  Also, when host program changes I2C access timing to PSoC, read back error number is changed.

For now, we found the one of the problem for our code. When timer interrupt (Timer8_2ms) was disable, I2C read back error was reduced. If you have a comments, please tell me.

Also, we would like to know details of EzI2C H/W and S/W control for fixing problem. If you have a material, could you please share them?

0 Likes
Reply
Moderator
Moderator

Hello Kusa-san,

Do kindly let me know the variable in the DevCtlRegs which does not read correct. I am listing some possible causes.

- Time8_2 ISR requires more time to finish. This may prevent the updating of the variable.

- CPU time may not be sufficient enough to finish all the processing

- The priority of the EzI2C interrupt may be lower than Time8_2 interrupt

For further resources of ExI2C you may kindly refer to the files EzI2Cs.asm and EzI2Cs_INT.asm which will be available under the library source files of your project. You may refer to the Technical Reference Manual for your device, under section I2C.

Thanks, and regards,

Sampath Selvaraj

0 Likes
Reply
New Contributor II

Hello Sampath-san,

We found the root cause of EzI2C communication issue. The root cause is the length of interrupt time with priority higher than the interrupt of I2C. If you have the related information, please let us know. Also, we wold like to get the explanation doc. for I2C handling buffer and clock stretch time out etc.

[Findings]

  1. I2C interrupt priority is very low (24th)  as referring to AN90833 :  PSoC® 1 Interrupts
  2. Current interrupt time of Timer8_2ms_ISR is so long time (765us of 2000us). interrupt time of "for" statement is main factor of 70%.   
  3. Time between  M8C_DisableGInt and M8C_EnableGInt related I2C read issue as same as timer. 

[Actions]

  1. Added M8C_EnableGint at 1st sentence  in Timer8_2ms_ISR
  2. Deleted "for" statement in Timer8_2ms_ISR
  3. Deleted M8C_DisableGInt and M8C_EnableGInt as much as possible.

Based on the above result, I2C read issue was almost fixed (no error of 10,000 cycle for I2C W/R check) 

0 Likes
Reply
Moderator
Moderator

Hello Kusa-san,

Kindly find the following:

- EzI2C Slave User Module Datasheet

- PSoC1 Technical Reference Manual

In the Technical Reference Manual I2C is described on page 481.

Best regards,

Sampath

0 Likes
Reply
New Contributor II

Hello Sampath-san,

Thank you for sharing above materials.

For result of our long run test of 1 week, Ez I2C slave did not return wrong data after interrupt code change. I realized that it is important to shorten the time of other interrupt programs because the interrupt priority of I2C is low.

Also, I shared the before/after program for reference. Thank you for your help.

(Interrupt timer : change from 765us of 2ms to 67 us of 2ms)

[before]

/*********************************************************

* Timer interrupt handler                               *

*********************************************************/

#pragma interrupt_handler Timer8_2ms_ISR

void Timer8_2ms_ISR(void)

{

  BYTE  i;

  //HDD Detect Check & Auto Power-off Control

  chkHddDetect();

  chkHddDetect();

/********* Decrement Timer *********************/

  if (bLED_timer)   bLED_timer--;

  // deleted no use timer 

  if (wPERST_wait_timerwPERST_wait_timer--;

 

  for (i=0; i<4; i++)

  {

     if (wPG_init_timer[i])  wPG_init_timer[i]--;

  if (wVOL_init_timer[i])  wVOL_init_timer[i]--;

  if (bCURR_Samp_timer[i]) bCURR_Samp_timer[i]--;

  }

/********* Debug LED ***************************/

  if (wCnt_1sec){

  wCnt_1sec--;

  } else{

  if (bDebugLed_Error_Flag) //Error表示

  {

  wCnt_1sec = bwait100ms_timer;

  }else {

  wCnt_1sec = wDEBUG_LED_timer / TIMER_SETTING_VAL;

  }

  DEBUG_LED_Data_ADDR ^= DBG_LED;

   }

}

[After]

/*********************************************************

* Timer interrupt handler                               *

*********************************************************/

#pragma interrupt_handler Timer8_2ms_ISR

void Timer8_2ms_ISR(void)

{

  BYTE  i;

  M8C_EnableGInt;  /* H.H */

  bFlagChkHddDetect = 1;  /* H.H Executing chkHddDetect() timer is time-upped */

/********* Decrement Timer *********************/

  if (bLED_timer)   bLED_timer--;

  if (wPERST_wait_timerwPERST_wait_timer--;

  if (wVOL_init_timer0)  wVOL_init_timer0--;

  if (wVOL_init_timer1)  wVOL_init_timer1--;

  if (wVOL_init_timer2)  wVOL_init_timer2--;

  if (wVOL_init_timer3)  wVOL_init_timer3--;

  if (bCURR_Samp_timer03)  bCURR_Samp_timer03--;

/********* Debug LED ***************************/

  if (wCnt_1sec){

  wCnt_1sec--;

  } else{

  if (bDebugLed_Error_Flag) //Error表示

  {

  wCnt_1sec = WAIT_DEBUG_100ms;

  }else {

  wCnt_1sec = DEBUG_LED_TIME_VALUE / TIMER_SETTING_VAL;

  }

  DEBUG_LED_Data_ADDR ^= DBG_LED;

   }

  PERSTn_1_Data_ADDR &= ~PERSTn_1_MASK;/* H.H PERST#1 negate for debug (A65_2) */

}

View solution in original post

0 Likes
Reply
Moderator
Moderator

Thank you very much Kusagaya-san!!!

0 Likes
Reply