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.

LAUNCHXL-CC1310: PinInterrupt & I2C conflict

Part Number: LAUNCHXL-CC1310

Hello,

I'm using one I2C LCD driver and I need to add some buttons to in my project.

When I2C funtions called in main function, it works well. It never stucks.

On the other hand, when I called I2C functions in the buttonCallbackFxn function it stucks after I2C_open function. When I2C_open function called, I2CHandle parameter values changed to 0xBE.. like pictures in below.

Could yoou please help me to solve the issue.? Any help will be appreciated.

Thanks in advance.

Best Regards,

  • Hi Enez,

    Please can you answer the following.

    1. Are you calling I2C_open() from the button callback? 

    2. Is the I2C_init() called before the i2C_open() function?

    Regards,

    Siddanth

  • Hello Siddanth,

    Thanks for reply.

    Yes, I2C_init and I2C_open functions are called before the buttonCallback function respectively. 

    Best kind regards.

    Enez

  • Hi Enez,

    If possible, please can you provide the code where you are seeing the issue. It seems hard to comment on what exactly could be wrong. 

    Regards,
    Siddanth

  • Hello Siddanth,

    Thanks for help. I share the functions I used below.

    Also in order to see detailed I've uploaded the project to github.

    https://github.com/enezbaglama/PCA8561_LCDdriver-HCD1080_sensor__CC1310_CCS/tree/main/pinInterrupt_CC1310_LAUNCHXL_tirtos_ccs

    I2C stucks when called from buttonCallback function.

    /*
     *  ======== main ========
     */
    int main(void)
    {
        pthread_t           thread;
        pthread_attr_t      attrs;
        struct sched_param  priParam;
        int                 retc;
    
        /* Call driver init functions */
        Board_init();
    
        /* Initialize the attributes structure with default values */
        pthread_attr_init(&attrs);
    
        /* Set priority, detach state, and stack size attributes */
        priParam.sched_priority = 1;
        retc = pthread_attr_setschedparam(&attrs, &priParam);
        retc |= pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_DETACHED);
        retc |= pthread_attr_setstacksize(&attrs, THREADSTACKSIZE);
        if (retc != 0) {
            /* failed to set attributes */
            while (1) {}
        }
    
        retc = pthread_create(&thread, &attrs, mainThread, NULL);
        if (retc != 0) {
            /* pthread_create() failed */
            while (1) {}
        }
    
        BIOS_start();
    
        return (0);
    }
    
    /*
     *  ======== mainThread ========
     */
    void *mainThread(void *arg0)
    {
    
        buttonPinHandle = PIN_open(&buttonPinState, buttonPinTable);
        if(!buttonPinHandle) {
            /* Error initializing button pins */
            while(1);
        }
    
        /* Setup callback for button pins */
        if (PIN_registerIntCb(buttonPinHandle, &buttonCallbackFxn) != 0) {
            /* Error registering button callback function */
            while(1);
        }
    
        LCD_software_reset();
        LCD_software_reset_release();
        LCD_set_ctrl_registers();
    
        /* Loop forever */
        while(1) {
            sleep(1);
    
        }
    }
    
    /*
     *  ======== buttonCallbackFxn ========
     *
     *
     */
    void buttonCallbackFxn(PIN_Handle handle, PIN_Id pinId) {
    
        /* Debounce logic, only toggle if the button is still pushed (low) */
        CPUdelay(8000*50);
        if (!PIN_getInputValue(pinId)) {
            
            switch (pinId) {
                case Board_PIN_BUTTON0:
                    LCD_update_flame_segment(enabled);
                    break;
    
                case Board_PIN_BUTTON1:
                    LCD_update_flame_segment(disabled);
                    break;
    
                default:
                    /* Do nothing */
                    break;
            }
        }
    }
    
    /*
     *********************************************************************************************************************************************
     *                      update_flame_segment
     *********************************************************************************************************************************************
     */
    void LCD_update_flame_segment(uint8_t flame_segment_value)
    {
        I2C_ready2operation();
    
        uint8_t flame_segment_buffer[2];
    
        i2cTransaction.slaveAddress = LCD_ADDR;
        i2cTransaction.writeBuf = flame_segment_buffer;
        i2cTransaction.writeCount = 2;
        i2cTransaction.readBuf = NULL;
        i2cTransaction.readCount = 0;
    
        switch (flame_segment_value)
        {
        case 0:
            COM0_SEG8_15.SEG15_flame = disabled;
            flame_segment_buffer[0] = COM0_SEG8_15_REG_ADDR;
            flame_segment_buffer[1] = COM0_SEG8_15.value;
            if (!I2C_transfer(i2cHandle, &i2cTransaction))
            {
                // Error. No i2c device found!
                while(1);
            }
            break;
        case 1:
            COM0_SEG8_15.SEG15_flame = enabled;
            flame_segment_buffer[0] = COM0_SEG8_15_REG_ADDR;
            flame_segment_buffer[1] = COM0_SEG8_15.value;
            if (!I2C_transfer(i2cHandle, &i2cTransaction))
            {
                // Error. No i2c device found!
                while(1);
    
            }
            break;
        }
        I2C_close(i2cHandle);
    }
    
    /*
     *************************************************************************
     *                      I2C_ready2operation
     *************************************************************************
     */
    void I2C_ready2operation(void)
    {
        I2C_init();
        /* Create I2C for usage */
        I2C_Params_init(&i2cParams);
        i2cParams.bitRate = I2C_400kHz;
        i2cHandle = I2C_open(Board_I2C0, &i2cParams);
        if (i2cHandle == NULL)
        {
            //Error Initializing I2C
            while (1);
        }
    }
    
    /*
     *************************************************************************
     *                      software_reset
     *************************************************************************
     */
    void LCD_software_reset(void)
    {
        I2C_ready2operation();
    
        uint8_t swRESET_buffer[2];
    
        swRESET_buffer[0] = SW_RESET_REG_ADDR;
        swRESET_buffer[1] = SW_RESET;
    
    
        i2cTransaction.slaveAddress = LCD_ADDR;
        i2cTransaction.writeBuf = swRESET_buffer;
        i2cTransaction.writeCount = 2;
        i2cTransaction.readBuf = NULL;
        i2cTransaction.readCount = 0;
    
        if (!I2C_transfer(i2cHandle, &i2cTransaction))
        {
            // Error. No i2c device found!
            while(1);
        }
    
        I2C_close(i2cHandle);
    }
    
    
    
    
    
    
    
    /*
     *************************************************************************
     *                      software_reset_release
     *************************************************************************
     */
    void LCD_software_reset_release(void)
    {
        I2C_ready2operation();
    
        uint8_t swRESET_buffer[2];
    
        swRESET_buffer[0] = SW_RESET_REG_ADDR;
        swRESET_buffer[1] = NO_RESET;
    
    
        i2cTransaction.slaveAddress = LCD_ADDR;
        i2cTransaction.writeBuf = swRESET_buffer;
        i2cTransaction.writeCount = 2;
        i2cTransaction.readBuf = NULL;
        i2cTransaction.readCount = 0;
    
        if (!I2C_transfer(i2cHandle, &i2cTransaction))
        {
            // Error. No i2c device found!
            while(1);
        }
        I2C_close(i2cHandle);
    }
    
    
    
    
    
    
    
    /*
     *************************************************************************
     *                      set_ctrl_registers
     *************************************************************************
     */
    void LCD_set_ctrl_registers(void)
    {
        I2C_ready2operation();
    
        CTRL.FrameFreq = _32Hz;
        CTRL.OSC = 0 ;
        CTRL.COE = 0;
    
        CTRL_1.Display_enable = enabled;
        CTRL_1.Bias = _1_3bias;
        CTRL_1.MUX = _1_4mux;
        CTRL_1.Boost = disabled;
    
        CTRL_2.INV = lineInversion;
        CTRL_2.BlinkControl = blinkOFF;
    
    
        uint8_t CTRL_buffer[4];
    
        CTRL_buffer[0] = DEVICE_CTRL_REG_ADDR;
        CTRL_buffer[1] = CTRL.CTRL_value;
        CTRL_buffer[2] = CTRL_1.CTRL1_value;
        CTRL_buffer[3] = CTRL_2.CTRL2_value;
    
        i2cTransaction.slaveAddress = LCD_ADDR;
        i2cTransaction.writeBuf = CTRL_buffer;
        i2cTransaction.writeCount = 4;
        i2cTransaction.readBuf = NULL;
        i2cTransaction.readCount = 0;
    
        if (!I2C_transfer(i2cHandle, &i2cTransaction))
        {
            // Error. No i2c device found!
            while(1);
        }
    
        I2C_close(i2cHandle);
    
    }

    Best regards,

    Enez 

  • Calling I2C functions from the callback(interrupt context) doesn't seem like a good idea. Maybe use a flag in the callback and then call the I2C functions from the task context itself.