I2C Problems Using CW 10.3 and Processor Expert

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

I2C Problems Using CW 10.3 and Processor Expert

639 Views
chinniwhites
Contributor II

Ok, so I am trying to get IIC between MC9S08AW32 and MC9RS08KB4 using processor expert working.  My SCL freq match exactly at 125 kHz but my SDA is a bit different (1.8 us on Master and 1.75 us on Slave) and perhaps this is an issue.  I am trying to get the 7 analog values from the kb4 to the aw32.  The data is coming over but not perfect.  I get one or two values that seem to be correct but then I get some zeros OR very large numbers mixing inbetween the good data.  I believe errors are happening while transmitting from slave (seems to be tx_buffer_full error) after a few successful transmission.  Below is the I2C code related to Master and Slave.  Please, if anyone can help me out on this one it would be much appreciated.

 

MASTER:

        //if transmit complete

        if (IICTxFlag == 0){

            IICTxError = I2C1_SendBlock(&IICTxData, 2, &IICTxRet);

            if (IICTxError != ERR_OK){

                //handle error

            }

            while ((!IICTxFlag) && (I2C1_CheckBus() == I2C1_BUSY));

            startRx = 1;

        }

        //start reception of data

        if (startRx == 1){

            for (IICLoop; IICLoop < 7; IICLoop++){

                IICRxError = I2C1_RecvBlock(&IICRxData, 2, &IICRxRet);

                if (IICRxError != ERR_OK){

                    //handle error

                }

                while((!IICRxFlag) && (I2C1_CheckBus() == I2C1_BUSY));

               

                //if receive complete

                adRemChannels[IICLoop] = (IICRxData[0] << 8) | IICRxData[1];

                IICRxFlag = 0;

            }

            if (IICLoop >= 7){

                IICLoop = 0;

                IICTxFlag = 0;

                startRx = 0;

                solarV2Counts    = adRemChannels[0];

                solarV1Counts    = adRemChannels[1];

                windV3Counts    = adRemChannels[2];

                windV2Counts    = adRemChannels[3];

                windV1Counts    = adRemChannels[4];

                solarAmpsCounts = adRemChannels[5];

                windAmpsCounts    = adRemChannels[6];

            }

        }

 

SLAVE:

      //receive data on full buffer

      while (!IICRxFlag);

      if ((IICRxFlag == 1) && (startTx == 0)){

          IICRxError = I2C1_RecvBlock(&IICRxData, 2, &IICRxRet);

          if (IICRxError != ERR_OK){

              //handle error

          }

          while((!IICRxFlag) && (I2C1_CheckBus() == I2C1_BUSY));

         

          //if message command good (MM), send data to master

          if ((IICRxData[0] == 0x4D) && (IICRxData[1] == 0x4D)){

              IICRxData[0] = 0;

              IICRxData[1] = 0;

              startTx = 1;

          }

      }

      if (startTx == 1){

          for (loop; loop < 7; loop++){

              IICTxData[0] = (unsigned char)(adChannels[loop] >> 8);

              IICTxData[1] = (unsigned char)adChannels[loop];

             

              IICTxError = I2C1_SendBlock(&IICTxData, 2, &IICTxRet);

              if (IICTxError != ERR_OK){

                  //handle error

              }

              while (((IICTxFlag & TX_EMPTY) == 0) && (I2C1_CheckBus() == I2C1_BUSY));

          }

          if (loop >= 7){

                loop = 0;

              startTx = 0;

              IICRxFlag = 0;

          }

      }

Labels (1)
0 Kudos
3 Replies

293 Views
pavel_sadek
NXP Employee
NXP Employee

Hi

I would clear the loop variable in Slave directly after checking of startTx 

for (loop=0;loop<7;loop++) {...

to be sure about data alignment

Pavel

0 Kudos

293 Views
chinniwhites
Contributor II

Ok, so I made loop = 0 before entering startTx on slave as you suggested.  It helped but comm not totally ironed out.  I get all the information coming back from my other micro, but something (error) is causing the info to get out of order (solarCounts will show windampCounts and the like).  I am using PE on both master and slave.  On slave, i have my input buffer at 2 and output buffer at 3 (per example via help component).  On master, the length of buffer arrays are 2.  Is this where my problem could be?  Am I not making room for the empty character somewhere those causing sporadic transmission buffer full errors that then gets the comm out of order?  I am pulling hairs now because code looks correct but functionality is not (very very very close though).  Perhaps someone with experience can point me in the right direction.

Thanks

MASTER:

unsigned char IICTxFlag = 0;

unsigned char IICTxError = 0;

unsigned char IICTxData[2];

unsigned int IICTxRet = 0;

unsigned char IICRxFlag = 0;

unsigned char IICRxError = 0;

unsigned char IICRxData[2];

unsigned int IICRxRet = 0;

unsigned char startRx = 0;

unsigned int RxData;

.

.

.

        //if transmit complete

        if (IICTxFlag == 0){

            IICTxError = I2C1_SendBlock(&IICTxData, 2, &IICTxRet);

            if (IICTxError != ERR_OK){

                //handle error

                while (I2C1_CheckBus() == I2C1_BUSY);

                IICTxFlag = 0;

            }

            else{

                while ((!IICTxFlag) || (I2C1_CheckBus() == I2C1_BUSY));

                IICLoop = 0;

                startRx = 1;

            }

        }

        //start reception of data

        if (startRx == 1){

            for (IICLoop; IICLoop < 7; IICLoop++){

                IICRxError = I2C1_RecvBlock(&IICRxData, 2, &IICRxRet);

                //below is needed

                if (IICRxError != ERR_OK){

                    while (I2C1_CheckBus() == I2C1_BUSY);

                    IICRxFlag = 0;

                    break;

                }

                while ((!IICRxFlag) || (I2C1_CheckBus() == I2C1_BUSY));

               

                //if receive complete

                adRemChannels[IICLoop] = (IICRxData[0] << 8) | IICRxData[1];

                IICRxFlag = 0;

            }

            if (IICLoop >= 7){

                IICLoop = 0;

                IICTxFlag = 0;

                startRx = 0;

                solarV2Counts    = adRemChannels[0];

                solarV1Counts    = adRemChannels[1];

                windV3Counts    = adRemChannels[2];

                windV2Counts    = adRemChannels[3];

                windV1Counts    = adRemChannels[4];

                solarAmpsCounts = adRemChannels[5];

                windAmpsCounts    = adRemChannels[6];

            }

        }

SLAVE:

#define   TX_CHAR   1
#define   BUFFER_FREE   2
#define   TX_EMPTY   4

unsigned int adChannels[7] = { 0, 0, 0, 0, 0, 0, 0 };

unsigned char IICTxFlag = 0;

unsigned char IICRxFlag = 0;

unsigned char IICTxError = 0;

unsigned char IICRxError = 0;

unsigned char IICErrorFlag = 0;

unsigned char IICTxData[2];

unsigned char IICRxData[2];

unsigned int IICTxRet = 0;

unsigned int IICRxRet = 0;

unsigned char IICReadFlag = 0;

unsigned char IICWriteFlag = 0;

unsigned char startTx = 0;

unsigned char loop = 0;

void main(void)

{

  /* Write your local variable definition here */

  /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/

  PE_low_level_init();

  /*** End of Processor Expert internal initialization.                ***/

  IICRxData[0] = 0;

  IICRxData[1] = 0;

  IICTxData[0] = 0;

  IICTxData[1] = 0;

  /* Write your code here */

  (void)AD1_Measure(1);

  (void)AD1_GetValue(adChannels);

 

  I2C1_ClearRxBuf();

  I2C1_ClearTxBuf();

 

  /* For example: for(;;) { } */

  for(;;){

      //receive data on full buffer

      while (!IICRxFlag);

      if ((IICRxFlag == 1) && (startTx == 0)){

      IICRxError = I2C1_RecvBlock(&IICRxData, 2, &IICRxRet);
      if (IICRxError != ERR_OK){
      //handle error
      while(I2C1_CheckBus() == I2C1_BUSY);
      IICRxFlag = 0;
      (void)I2C1_ClearRxBuf();
      (void)I2C1_ClearTxBuf();
      }
      else{
      while((!IICRxFlag) || (I2C1_CheckBus() == I2C1_BUSY));
     
      //if message command good (MM), send data to master
      if ((IICRxData[0] == 0x4D) && (IICRxData[1] == 0x4D)){
      (void)I2C1_ClearRxBuf();
      IICRxData[0] = 0;
      IICRxData[1] = 0;
      startTx = 1;
      loop = 0;
      }
      }

      }

      if (startTx == 1){

      for (loop; loop < 7; loop++){
      IICTxData[0] = adChannels[loop] >> 8;
      IICTxData[1] = (unsigned char)(adChannels[loop]);
     
      IICTxFlag = 0;
      IICTxError = I2C1_SendBlock(&IICTxData, 2, &IICTxRet);
      if (IICTxError != ERR_OK){
      //handle error
      while (I2C1_CheckBus() == I2C1_BUSY);
      (void)I2C1_ClearTxBuf();
      break;
      }
      //while ((IICTxFlag & TX_EMPTY) == 0);
      //while (((IICTxFlag & TX_EMPTY) == 0) || (I2C1_CheckBus() == I2C1_BUSY));
      while (I2C1_CheckBus() == I2C1_BUSY);
      }
      if (loop >= 7){
        loop = 0;
      startTx = 0;
      IICRxFlag = 0;
      }

      }

  }

0 Kudos

293 Views
chinniwhites
Contributor II

Also, the slave code below never seems to set my IICTxFlag.  I followed example on help component and via interrupts, IICTxFlag |= TX_EMPTY, TX_CHAR, and BUFFER_FREE.  If I use the commented out code "while ((IICTxFlag & TX_EMPTY) == 0);" after send block command, i never make it past the statement in code as if that flag is never setting.  I dont know how this is possible.  I altered that specific statement for each state of IICTxFlag and none of them made it past that line of code.

if (startTx == 1){

          for (loop; loop < 7; loop++){

              IICTxData[0] = adChannels[loop] >> 8;

              IICTxData[1] = (unsigned char)(adChannels[loop]);

             

              IICTxFlag = 0;

              IICTxError = I2C1_SendBlock(&IICTxData, 2, &IICTxRet);

              if (IICTxError != ERR_OK){

                  //handle error

                  while (I2C1_CheckBus() == I2C1_BUSY);

                  (void)I2C1_ClearTxBuf();

                  break;

              }

              //while ((IICTxFlag & TX_EMPTY) == 0);

              //while (((IICTxFlag & TX_EMPTY) == 0) || (I2C1_CheckBus() == I2C1_BUSY));

              while (I2C1_CheckBus() == I2C1_BUSY);

          }

          if (loop >= 7){

                loop = 0;

              startTx = 0;

              IICRxFlag = 0;

          }

      }

0 Kudos