This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Bug found in I2C interrupt Service Routine

Other Parts Discussed in Thread: MSP430F5438A

Hello Everyone!

MSP430f5438A

tirtos_msp430_2_00_02_36

I have found a bug in I2C Interrupt service routine in CallBack mode.

I2CUSCIB.c

        case I2C_READ_MODE:
            /*
             * Data has been read from RXBUF, but the next byte is
             * already been shifted
             */
            object->readCountIdx--;

            if (object->readCountIdx > 1)
            {
                *(object->readBufIdx) = USCI_B_I2C_slaveDataGet(hwAttrs->baseAddr);
            }
            else if (object->readCountIdx == 1)
            {
                key = Hwi_disable();
                *(object->readBufIdx) = USCI_B_I2C_masterMultiByteReceiveFinish(hwAttrs->baseAddr);
                Hwi_restore(key);
            }
            else
            {
                /* Next state: Idle mode */
                object->mode = I2C_IDLE_MODE;

                *(object->readBufIdx) = USCI_B_I2C_slaveDataGet(hwAttrs->baseAddr);

                I2CUSCIB_completeTransfer((I2C_Handle)&I2C_config[index]);
            }

            Log_print2(Diags_USER2, "I2C:(%p) ISR I2C_READ_MODE: "
                                    "Read data byte: 0x%x ",
                                     hwAttrs->baseAddr,
                                    *(object->readBufIdx));

            object->readBufIdx++;
            break; /* I2C_READ_MODE */

So in CallBack mode, I2CUSCIB_completeTransfer() function calls I2CUSCIB_primeTransfer() function that sets the object->readBufIdx. So after returning from the I2CUSCIB_completeTransfer() function, object->readBufIdx++; increments the readBufIdx pointer and the pointer points to the next memory location that saves the data at the new memory location instead of the original location.

This is how I fix it

        case I2C_READ_MODE:
            /*
             * Data has been read from RXBUF, but the next byte is
             * already been shifted
             */
            object->readCountIdx--;

            if (object->readCountIdx > 1)
            {
                *(object->readBufIdx) = USCI_B_I2C_slaveDataGet(hwAttrs->baseAddr);
                object->readBufIdx++;
            }
            else if (object->readCountIdx == 1)
            {
                key = Hwi_disable();
                *(object->readBufIdx) = USCI_B_I2C_masterMultiByteReceiveFinish(hwAttrs->baseAddr);
                Hwi_restore(key);
                object->readBufIdx++;
            }
            else
            {
                /* Next state: Idle mode */
                object->mode = I2C_IDLE_MODE;

                *(object->readBufIdx) = USCI_B_I2C_slaveDataGet(hwAttrs->baseAddr);

                I2CUSCIB_completeTransfer((I2C_Handle)&I2C_config[index]);
            }

            Log_print2(Diags_USER2, "I2C:(%p) ISR I2C_READ_MODE: "
                                    "Read data byte: 0x%x ",
                                     hwAttrs->baseAddr,
                                    *(object->readBufIdx));

            
            break; /* I2C_READ_MODE */

Regards

Arslan