I2C Interrupt Tx/Rx

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

I2C Interrupt Tx/Rx

1,364 Views
josepgorgues
Contributor II

Hello,

 

I am working on MPC5606s Controller. I am trying to implement a I2C RX/TX driver using interrupt vectors. I have an I2C library that works successfully without interrupts, using only "whiles".

 

Using this following functions the controller does not execute the interrupt. I add the functions that we use to write data.

 

void I2C0_init(void) {   uint8_t i=0;    CGM.SC_SS.R = 0x04000000;               // MPC56xxS: Select Periph. set 1 clock to be FMPLL0, SEL1 = 0100 Primary FMPLL   CGM.SC_DC[0].B.DE = 1;                  // MPC56xxS: Enable Periph. set 1 clock to I2C       //SIU.PCR[I2C0_SDA].R = 0x0527;         // PF6 pin as I2C0 SDA, open-drain, weak pull up   //SIU.PCR[I2C0_SCL].R = 0x0527;       // PF7 pin as I2C0 SCL, open-drain, weak pull up   SIU.PCR[I2C0_SDA].R = 0x0520;           // PF6 pin as I2C0 SDA, open-drain,   SIU.PCR[I2C0_SCL].R = 0x0520;         // PF7 pin as I2C0 SCL, open-drain,         //I2C_0.IBFD.B.IBC = 0x2D;            // SCL div = 640, 64Mhz / 620 = 103226Hz, 100KHz aprox   //I2C_0.IBFD.B.IBC = 0x2E;            // SCL div = 768, 64Mhz / 768 = 83333Hz, 83KHz aprox   I2C_0.IBFD.B.IBC = 0x65;              // SCL div = 640, 64Mhz / 640 = 100000Hz, 100KHz aprox      I2C_0.IBAD.R = 0x00;                     // Set module's I2C address to 0x00      I2C_0.IBCR.B.MDIS = 0;                   // Clear Module Disable / Enable I2C operations, NO IRQ   I2C_0.IBSR.B.IBAL = 1;                   // Clear the IBAL flag;      // Reset I2C bus by sending 9xCLK with SDA at low level    I2C_0.IBCR.B.MS = 1;                  // Set IBCR, Master mode select   I2C_0.IBCR.B.TX = 1;                  // Set IBCR, Transmit mode select   I2C_0.IBDR.R = 0x00;                  // Update IBDR, Send slave I2C address    while (I2C_0.IBSR.B.IBIF==0){};       // Check IBSR, Wait until IBIF (byte TX complete) or a timeout expires   I2C_0.IBSR.B.IBIF=1;                  // Set IBSR, Clear the interrupt event flag   I2C_0.IBCR.B.MS = 0;                              // Set IBCR, Generate stop signal;      I2C_0.IBCR.B.IBIE = 1;                    // Enable interrupt   INTC_InstallINTCInterruptHandler(I2C_Interupt,125,1); }

 

uint8_t I2C_write(uint8_t dev,uint8_t addr,uint8_t *pData, uint8_t nBytes) {     uint8_t i = 0;     i2cWrite_cnt = 0;                   while ((I2C_0.IBSR.B.IBB == 1)){};   // Check IBSR, Wait whiel IBB == 1 (bus busy)               I2C_0.IBCR.B.MS = 1;                                      // Set IBCR, Master mode select     I2C_0.IBCR.B.TX = 1;                                      // Set IBCR, Transmit mode select     I2C_0.IBCR.B.NOACK = 0;                 I2C_0.IBSR.B.TCF = 1;                                    /* Transfer in progress */                I2C_0.IBDR.R = dev;                                       // Update IBDR, Send slave I2C address      iic_addr = addr;                                          // Copy address -> iic_addr      iic_len  = nBytes;                                        // Byes to send in interrupt = len      for(i=0; i<nBytes; i++)     {       iic_buffer[i] = *(pData + i);     }     entery = 0;         }

 

void I2C_Interupt(void) {  // uint8_t entery = 0;   uint8_t i = 0;   if((I2C_0.IBSR.B.TCF == 1) && (ack_flag==1))     /*  If transfer is completed    */   { entery++;     ack_flag= 0;     if(entery == 1)     {       I2C_0.IBDR.R = iic_addr;    /* Update IBDR, send internal address of I2C slave   */     }     else if (entery <= iic_len)     {       I2C_0.IBDR.R = iic_buffer[entery-2];             }     else     {       entery = 0;       I2C_0.IBCR.B.MS = 0;             /* Set IBCR, Generate stop signal; */     }        }       I2C_0.IBCR.B.MDIS = 0;                   // Clear Module Enable I2C operations, NO IRQ }

 

Thank

Josep

Labels (1)
0 Kudos
1 Reply

795 Views
davidtosenovjan
NXP TechSupport
NXP TechSupport

I suppose you are using CodeWarrior.

1) Macro “#define CALL_USR_INIT 1” must be defined in C/C++ preprocessor to properly initialized interrupts and exception.

2) After calling INTC_InstallINTCInterruptHandler, current interrupt priority must be decreased to unmask interrupt.

  1. INTC.CPR.R = 0;

3) I see potential issues in using of .B instance during access to status registers. Pay attention to following document, especially section 3.2: 

http://cache.nxp.com/files/32bit/doc/eng_bulletin/EB758.pdf

0 Kudos