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.

CCS/TM4C123GE6PM: I2C Slave with Ti_RTOS

Part Number: TM4C123GE6PM
Other Parts Discussed in Thread: SYSCONFIG

Tool/software: Code Composer Studio

Hello all, 

I am looking for a proper way to make an I2C slave with my tiva, on the I2C3, with TI_RTOS. 

I have found a lot of contradictory information about this, especially concerning the API to use.

As I already have some I2C configured in Master mode, as follow :

/*
 *  =============================== I2C ===============================
 */
/* Place into subsections to allow the TI linker to remove items properly */
#if defined(__TI_COMPILER_VERSION__)
#pragma DATA_SECTION(I2C_config, ".const:I2C_config")
#pragma DATA_SECTION(i2cTivaHWAttrs, ".const:i2cTivaHWAttrs")
#endif

#include <ti/drivers/I2C.h>
#include <ti/drivers/i2c/I2CTiva.h>

I2CTiva_Object i2cTivaObjects[EK_TM4C123GXL_I2CCOUNT];

const I2CTiva_HWAttrs i2cTivaHWAttrs[EK_TM4C123GXL_I2CCOUNT] =
{
    {
     .baseAddr = I2C1_BASE,
     .intNum = INT_I2C1,
     .intPriority = (~0)
    },
    {
     .baseAddr = I2C2_BASE,
     .intNum = INT_I2C2,
     .intPriority = (~0)
    },
};

const I2C_Config I2C_config[] =
{
 {
  .fxnTablePtr = &I2CTiva_fxnTable,
  .object = &i2cTivaObjects[0],
  .hwAttrs = &i2cTivaHWAttrs[0]
 },
 {
  .fxnTablePtr = &I2CTiva_fxnTable,
  .object = &i2cTivaObjects[1],
  .hwAttrs = &i2cTivaHWAttrs[1]
 },
 {NULL, NULL, NULL}
};

/*
 *  ======== EK_TM4C123GXL_initI2C ========
 */
 void EK_TM4C123GXL_initI2C(void)
{
    /* I2C1 Init */
    /* Enable the peripheral */
    SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);

    /* Configure the appropriate pins to be I2C instead of GPIO. */
    GPIOPinConfigure(GPIO_PA6_I2C1SCL);
    GPIOPinConfigure(GPIO_PA7_I2C1SDA);
    GPIOPinTypeI2CSCL(GPIO_PORTA_BASE, GPIO_PIN_6);
    GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_7);

    /*
     * NOTE: TI-RTOS examples configure pins PD0 & PD1 for SSI3 or I2C3.  Thus,
     * a conflict occurs when the I2C & SPI drivers are used simultaneously in
     * an application.  Modify the pin mux settings in this file and resolve the
     * conflict before running your the application.
     */
    /*I2C2 Init*/
    /* Enable the peripheral */
    SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C2);

    /* Configure the appropriate pins to be I2C instead of GPIO. */
    GPIOPinConfigure(GPIO_PE4_I2C2SCL);
    GPIOPinConfigure(GPIO_PE5_I2C2SDA);
    GPIOPinTypeI2CSCL(GPIO_PORTE_BASE, GPIO_PIN_4);
    GPIOPinTypeI2C(GPIO_PORTE_BASE, GPIO_PIN_5);

    /*I2C3 Init*/
    SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C3);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    GPIOPinConfigure(GPIO_PD0_I2C3SCL);
    GPIOPinConfigure(GPIO_PD1_I2C3SDA);
    GPIOPinTypeI2CSCL(GPIO_PORTD_BASE, GPIO_PIN_0);
    GPIOPinTypeI2C(GPIO_PORTD_BASE, GPIO_PIN_1);



    /*
     * These GPIOs are connected to PD0 and PD1 and need to be brought into a
     * GPIO input state so they don't interfere with I2C communications.
     */
    GPIOPinTypeGPIOInput(GPIO_PORTB_BASE, GPIO_PIN_6);
    GPIOPinTypeGPIOInput(GPIO_PORTB_BASE, GPIO_PIN_7);

    /****/
    // Enable and initialize the I2C0 master module.  Use the system clock for
    // the I2C0 module.  The last parameter sets the I2C data transfer rate.
    // If false the data rate is set to 100kbps and if true the data rate will
    // be set to 400kbps.
    I2CMasterInitExpClk(I2C1_BASE, SysCtlClockGet(), false);
    I2CMasterInitExpClk(I2C2_BASE, SysCtlClockGet(), false);

    //clear I2C FIFOs
    HWREG(I2C1_BASE + I2C_O_FIFOCTL) = 80008000;
    HWREG(I2C2_BASE + I2C_O_FIFOCTL) = 80008000;
    /****/

    I2C_init();
}


An I use it like this :

 I2C_Params_init(&DRI_astrI2CConfig[idx].I2cParams);
        DRI_astrI2CConfig[idx].I2cParams.transferMode = I2C_MODE_BLOCKING;
        DRI_astrI2CConfig[idx].I2cParams.transferCallbackFxn = NULL;
        DRI_astrI2CConfig[idx].I2cParams.bitRate = I2C_100kHz;
        DRI_astrI2CConfig[idx].I2cHandle = I2C_open(DRI_astrI2CConfig[idx].PeripheralNum, &DRI_astrI2CConfig[idx].I2cParams);
        if (DRI_astrI2CConfig[idx].I2cHandle == NULL)
        {
            /* Error opening I2C */
            System_printf("I2C was not opened");
            System_flush();
        }
I2C_transfer(handle, i2c);

I would like to add in a similar way my I2CSlave. So I have found this driver http://dev.ti.com/tirex/content/simplelink_msp432_sdk_1_30_00_40/docs/tidrivers/doxygen/html/_i2_c_slave_8h.html#a4adcea9698de83af86f5d9d4e4331977 That seemed to correspond to my needs, but I don't know if it is possible to use it in my case and how to install it.

So I look for an other solution, to use only the functions contained in driverlib/i2c.h, such as I2CSlaveInit, I2CSlaveDataGet., as in the examples contained in ti/TivaWare_C_Series../examples/peripherals/ i2c/ but I am not sure either it is the right way to do this.

Could anyone explain me the difference between the two methods, and which one I must use ? 

Any example would be welcome! 

Thank you,

Elisabeth

  • Hi Tixier,

    We did not implement a I2C Slave driver in TI-RTOS for TivaC. You can implement a I2C Slave driver yourself using the driverlib calls in TI-RTOS for TivaC. The MSP432E4 device has the same I2C peripheral (and very similar driverlib). You can use the I2C Slave driver in the SimpleLink MSP432E4 SDK as a model for writing your own I2C Slave driver for TI-RTOS for TivaC. 

    The main differences between TI-RTOS for TivaC Drivers and SimpleLink drivers are

    - The SimpleLink Drivers use DPL (Driver Porting Level) to support different RTOS's. The difference is pretty obvious though (e.g. HwiP_disable in DPL vs Hwi_disable in TI-RTOS). DPL APIs are basically TI-RTOS calls with a "P" in them, so you can just use the native TI-RTOS API instead.

    - The newest SimpleLink SDK uses SysConfig to generate the "Board" files. To eliminate that, I'd look at the SimpleLink MSP432E4 SDK version 3.20. That way to can easily see how to configure the I2C Slave driver in the SimpleLink SDK.

    Key point: I'm talking about the MSP432E4 above...not the MSP432P4 or sometimes called just MSP432 (since it came out first).

    Todd

  • Hi Todd, 

    I am not sure to understand well everything:

    You suggest I used the driver located in this directory C:\ti\simplelink_msp432e4_sdk_3_20_00_10\source\ti\drivers\i2c \I2CMSP432E4. cand .h to create an I2CSlave dirver for TivaC ? 

    I can't see any slave specific driver there ...

    Other point : Is there a problem to simply use the I2CSlaveInit, I2CSlaveDataGet api with TiRTOS ? Could this generate conflicts ? 

    Thank you for your help ! 

    Elisabeth

  • Elisabeth,

    Sorry! My bad! It's the SimpleLink MSP432P4 SDK that has the I2C Slave driver. The MSP432E4 (which is similar to the TivaC) does not. The MSP432P4's I2C perpherial (and driverlib) is different than the TivaC so it will not be a slam-dunk.

    So let me try this again...

    You can look at the I2CSlave..c/.h and I2CSlaveMSP432.c/.h file in the SimpleLink MSP432P4 SDK. You can use that code as a reference to write your own RTOS aware driver. The driverlib calls will be different, so you cannot just re-use the code as is. Instead maybe use it as a template.

    Todd

  • Hello Todd, 

    As you suggested, I remake the I2Cslave driver for tiRtos with the driver from  SimpleLink MSP432P4 SDK. 

    I am now facing an issue with the build of this new files : 

    I have added them as they were added in the simpleLink SDK, which means I have put two new files (I2CSlave.c and I2CSlave.h)on the directory C:\ti\tirtos_tivac_2_16_00_08\products\tidrivers_tivac_2_16_00_08\packages\ti\drivers, and the two others (that I renamed I2CSlaveTiva.c, .h) in the same directory/i2cslave/ folder. 

    At linking time, some symbols coming from I2CSlave.c aren't found : I2CSlave_Params_init, I2CSlave_open...

    So I think there is a missing step, probably the new files that aren't build. 

    Do you know how to solve this ? A way to rebuild toRtos ? 

    Thank you for your help !

    Elisabeth

  • Can you post your exported CCS project?

    [11/18 update: Marking as TI Thinks Resolved due to no activity from original poster.]

  • Hello Todd,

    Sorry for the delay, I had to work on an other project, but I am back on this now. 

    I enclose the project settings, is this what you want or do you want me to join the whole project ? 

    Thank you for your help ! 

    Elisabeth

    <?xml version="1.0" encoding="UTF-8"?>
    <cdtprojectproperties>
    <section name="org.eclipse.cdt.internal.ui.wizards.settingswizards.IncludePaths">
    <language name="C Source File">
    <includepath>Debug/${COM_TI_RTSC_TIRTOSTIVAC_INCLUDE_PATH}</includepath>
    <includepath>C:/Users/etixier/git/proj2961_t27371002_isc_p3_sofa</includepath>
    <includepath workspace_path="true">/${ProjName}</includepath>
    <includepath>C:/ti/tirtos_tivac_2_16_00_08/products/TivaWare_C_Series-2.1.1.71b</includepath>
    <includepath>C:/ti/tirtos_tivac_2_16_00_08/products/bios_6_45_01_29/packages/ti/sysbios/posix</includepath>
    <includepath>C:/ti/ccsv8/tools/compiler/ti-cgt-arm_19.6.0.STS/include</includepath>
    
    </language>
    <language name="Assembly Source File">
    <includepath>Debug/${COM_TI_RTSC_TIRTOSTIVAC_INCLUDE_PATH}</includepath>
    <includepath>C:/Users/etixier/git/proj2961_t27371002_isc_p3_sofa</includepath>
    <includepath workspace_path="true">/${ProjName}</includepath>
    <includepath>C:/ti/tirtos_tivac_2_16_00_08/products/TivaWare_C_Series-2.1.1.71b</includepath>
    <includepath>C:/ti/tirtos_tivac_2_16_00_08/products/bios_6_45_01_29/packages/ti/sysbios/posix</includepath>
    <includepath>C:/ti/ccsv8/tools/compiler/ti-cgt-arm_19.6.0.STS/include</includepath>
    
    </language>
    <language name="Assembly Source File">
    <includepath>Debug/${COM_TI_RTSC_TIRTOSTIVAC_INCLUDE_PATH}</includepath>
    <includepath>C:/Users/etixier/git/proj2961_t27371002_isc_p3_sofa</includepath>
    <includepath workspace_path="true">/${ProjName}</includepath>
    <includepath>C:/ti/tirtos_tivac_2_16_00_08/products/TivaWare_C_Series-2.1.1.71b</includepath>
    <includepath>C:/ti/tirtos_tivac_2_16_00_08/products/bios_6_45_01_29/packages/ti/sysbios/posix</includepath>
    <includepath>C:/ti/ccsv8/tools/compiler/ti-cgt-arm_19.6.0.STS/include</includepath>
    
    </language>
    <language name="C++ Source File">
    <includepath>Debug/${COM_TI_RTSC_TIRTOSTIVAC_INCLUDE_PATH}</includepath>
    <includepath>C:/Users/etixier/git/proj2961_t27371002_isc_p3_sofa</includepath>
    <includepath workspace_path="true">/${ProjName}</includepath>
    <includepath>C:/ti/tirtos_tivac_2_16_00_08/products/TivaWare_C_Series-2.1.1.71b</includepath>
    <includepath>C:/ti/tirtos_tivac_2_16_00_08/products/bios_6_45_01_29/packages/ti/sysbios/posix</includepath>
    <includepath>C:/ti/ccsv8/tools/compiler/ti-cgt-arm_19.6.0.STS/include</includepath>
    
    </language>
    <language name="Linker Command File">
    
    </language>
    <language name="Linker Command File">
    
    </language>
    <language name="Linker Command File">
    
    </language>
    </section>
    <section name="org.eclipse.cdt.internal.ui.wizards.settingswizards.Macros">
    <language name="C Source File">
    <macro>
    <name>${COM_TI_RTSC_TIRTOSTIVAC_SYMBOLS}</name><value/>
    </macro>
    <macro>
    <name>ccs</name><value/>
    </macro>
    <macro>
    <name>PART_TM4C123GH6PM</name><value/>
    </macro>
    <macro>
    <name>TIVAWARE</name><value/>
    </macro>
    
    </language>
    <language name="Assembly Source File">
    <macro>
    <name>${COM_TI_RTSC_TIRTOSTIVAC_SYMBOLS}</name><value/>
    </macro>
    <macro>
    <name>ccs</name><value/>
    </macro>
    <macro>
    <name>PART_TM4C123GH6PM</name><value/>
    </macro>
    <macro>
    <name>TIVAWARE</name><value/>
    </macro>
    
    </language>
    <language name="Assembly Source File">
    <macro>
    <name>${COM_TI_RTSC_TIRTOSTIVAC_SYMBOLS}</name><value/>
    </macro>
    <macro>
    <name>ccs</name><value/>
    </macro>
    <macro>
    <name>PART_TM4C123GH6PM</name><value/>
    </macro>
    <macro>
    <name>TIVAWARE</name><value/>
    </macro>
    
    </language>
    <language name="C++ Source File">
    <macro>
    <name>${COM_TI_RTSC_TIRTOSTIVAC_SYMBOLS}</name><value/>
    </macro>
    <macro>
    <name>ccs</name><value/>
    </macro>
    <macro>
    <name>PART_TM4C123GH6PM</name><value/>
    </macro>
    <macro>
    <name>TIVAWARE</name><value/>
    </macro>
    
    </language>
    <language name="Linker Command File">
    
    </language>
    <language name="Linker Command File">
    
    </language>
    <language name="Linker Command File">
    
    </language>
    </section>
    </cdtprojectproperties>
    

  • It would be better to export and attach the whole project (assuming there is no intellectual property in it). 

  • Hello Todd, 

    Please find enclose a zip of my project. I add too the I2C slave driver I have made that are located for me in C:\ti\tirtos_tivac_2_16_00_08\products\tidrivers_tivac_2_16_00_08\packages\ti\drivers

    Thank you again for your help ! 

    Elisabeth

    I2CSlave.hi2cslave.zip

    /*
     * Copyright (c) 2015-2017, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    /*
     *  ======== I2CSlave.c ========
     */
    
    #include <stdbool.h>
    #include <stddef.h>
    #include <stdint.h>
    #include <stdlib.h>
    
    #include <ti/drivers/dpl/HwiP.h>
    #include <ti/drivers/I2CSlave.h>
    
    extern const I2CSlave_Config I2CSlave_config[];
    extern const uint_least8_t I2CSlave_count;
    
    /* Default I2CSlave parameters structure */
    const I2CSlave_Params I2CSlave_defaultParams = {
        I2CSLAVE_MODE_BLOCKING,  /* transferMode */
        NULL,                    /* transferCallbackFxn */
        NULL                     /* custom */
    };
    
    /* I2C function table for I2CSlave implementation */
    const I2C_FxnTable I2CSlave_fxnTable = {
        I2CSlave_close,
        I2CSlave_control,
        I2CSlave_init,
        I2CSlave_open,
        I2CSlave_transfer
    };
    
    static bool isInitialized = false;
    
    /*
     *  ======== I2CSlave_close ========
     */
    void I2CSlave_close(I2CSlave_Handle handle)
    {
        handle->fxnTablePtr->closeFxn(handle);
    }
    
    /*
     *  ======== I2CSlave_control ========
     */
    int_fast16_t I2CSlave_control(I2CSlave_Handle handle, uint_fast16_t cmd, void *arg)
    {
        return (handle->fxnTablePtr->controlFxn(handle, cmd, arg));
    }
    
    /*
     *  ======== I2CSlave_init ========
     */
    void I2CSlave_init(void)
    {
        uint_least8_t i;
        uint_fast32_t key;
    
        key = HwiP_disable();
    
        if (!isInitialized) {
            isInitialized = (bool) true;
    
            /* Call each driver's init function */
            for (i = 0; i < I2CSlave_count; i++) {
                I2CSlave_config[i].fxnTablePtr->initFxn((I2CSlave_Handle)&(I2CSlave_config[i]));
            }
        }
    
        HwiP_restore(key);
    }
    
    /*
     *  ======== I2CSlave_open ========
     */
    I2CSlave_Handle I2CSlave_open(uint_least8_t index, I2CSlave_Params *params)
    {
        I2CSlave_Handle handle = NULL;
    
        /* Verify driver index and state */
        if (isInitialized && (index < I2CSlave_count)) {
            /* Use defaults if params are NULL. */
            if (params == NULL) {
                params = (I2CSlave_Params *) &I2CSlave_defaultParams;
            }
    
            /* Get handle for this driver instance */
            handle = (I2CSlave_Handle)&(I2CSlave_config[index]);
            handle = handle->fxnTablePtr->openFxn(handle, params);
        }
    
        return (handle);
    }
    
    /*
     *  ======== I2CSlave_Params_init =======
     */
    void I2CSlave_Params_init(I2CSlave_Params *params)
    {
    
        *params = I2CSlave_defaultParams;
    
    }
    
    /*
     *  ======== I2CSlave_read ========
     */
    bool I2CSlave_read(I2CSlave_Handle handle, void *buffer, size_t size)
    {
        return (handle->fxnTablePtr->readFxn(handle, buffer, size));
    }
    
    /*
     *  ======== I2CSlave_write ========
     */
    bool I2CSlave_write(I2CSlave_Handle handle, const void *buffer, size_t size)
    {
        return (handle->fxnTablePtr->writeFxn(handle, buffer, size));
    }
    
    proj2961_t27371002_isc_p3_sofa.zip

  • I would just add the files (i2cslave*) into the project instead of the driver directory. That way they get included into your project. I expect you did not add the I2CSlave files into the build flow of TI-RTOS and then rebuild the driver library.

  • Hello Todd, 

    I try including these files in my project as you suggest and it works indeed better !

    But I of course still have issue on my I2C Slave driver, especially on the following point :

    In the I2CSlaveMSP432.c file, the function I2CSlaveMSP432_hwiIntFxn is written as follow :

    /*
     *  ======== I2CSlaveMSP432_hwiIntFxn ========
     *  Hwi interrupt handler to service the I2CSLAVE peripheral
     *
     *  The handler is a generic handler for a I2CSLAVE object.
     */
    void I2CSlaveMSP432_hwiIntFxn(uintptr_t arg)
    {
        uint16_t                     intStatus;
        I2CSlaveMSP432_Object        *object = ((I2CSlave_Handle) arg)->object;
        I2CSlaveMSP432_HWAttrs const *hwAttrs = ((I2CSlave_Handle) arg)->hwAttrs;
    
        /* Get the interrupt status of the I2CSlave controller */
        intStatus = MAP_I2C_getEnabledInterruptStatus(hwAttrs->baseAddr);
        MAP_I2C_clearInterruptFlag(hwAttrs->baseAddr, intStatus);
    
        /* Filter any spurious interrupts */
        if (!(intStatus & ALL_INTERRUPTS)) {
            return;
        }
    
        /* Check for I2CSlave Errors */
        if ((intStatus & ERROR_INTERRUPTS)) {
            /* Some sort of error occurred */
            object->mode = I2CSLAVE_ERROR;
    
            DebugP_log2("I2CSlave:(%p) ISR I2CSlave Bus fault (Status Reg: 0x%x)",
                hwAttrs->baseAddr, intStatus);
        }
    
        if(intStatus & EUSCI_B_I2C_RECEIVE_INTERRUPT0 )
                object->mode = I2CSLAVE_READ_MODE;
             else if(intStatus & EUSCI_B_I2C_TRANSMIT_INTERRUPT0 )
                    object->mode = I2CSLAVE_WRITE_MODE;
                  else if(intStatus & EUSCI_B_I2C_START_INTERRUPT )
                               object->mode = I2CSLAVE_START_MODE;
                       else if(intStatus & EUSCI_B_I2C_STOP_INTERRUPT )
                           object->mode = I2CSLAVE_IDLE_MODE;
    
    
        /* No errors, now check what we need to do next */
        switch (object->mode) {
            case I2CSLAVE_ERROR:
            case I2CSLAVE_IDLE_MODE:
                completeTransfer((I2CSlave_Handle) arg);
                break;
            case I2CSLAVE_START_MODE:
                if(object->transferInProgress)
                {
                    completeTransfer((I2CSlave_Handle) arg);
                    object->mode = I2CSLAVE_IDLE_MODE;
                }
                    break;
    
            case I2CSLAVE_WRITE_MODE:
                object->transferInProgress = true;
                  if (object->countIdx){
                      /* Write data contents into data register */
                    MAP_I2C_clearInterruptFlag(hwAttrs->baseAddr,
                        EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
                    MAP_I2C_slavePutData(hwAttrs->baseAddr,
                                         *(object->writeBufferIdx));
                    DebugP_log2("I2CSlave:(%p) ISR I2CSLAVE_WRITE_MODE: "
                        "Data to write: 0x%x",
                        hwAttrs->baseAddr, *(object->writeBufferIdx));
    
                    object->writeBufferIdx++;
                    object->countIdx--;
                }
                else {
                        DebugP_log1("I2CSlave:(%p) ISR I2CSLAVE_WRITE_MODE: "
                            "No more bytes available to write From slave: 0xFF",
                            hwAttrs->baseAddr);
                        object->mode = I2CSLAVE_ERROR;
                        MAP_I2C_clearInterruptFlag(hwAttrs->baseAddr,
                            EUSCI_B_I2C_TRANSMIT_INTERRUPT0);
                        MAP_I2C_slavePutData(hwAttrs->baseAddr, 0xFF);
                        DebugP_log2("I2CSlave:(%p) ISR I2CSLAVE_WRITE_MODE: "
                            "Data to write: 0x%x",
                            hwAttrs->baseAddr, *(object->writeBufferIdx));
                }
                break; /* I2CSLAVE_WRITE_MODE */
    
            case I2CSLAVE_READ_MODE:
                object->transferInProgress = true;
                /* Data read from RXBUF and next byte has already been shifted */
                if(object->countIdx) {
                    *(object->readBufferIdx) =
                        MAP_I2C_slaveGetData(hwAttrs->baseAddr);
    
                    DebugP_log2("I2CSlave:(%p) ISR I2CSLAVE_READ_MODE: "
                        "Read data byte: 0x%x",
                        hwAttrs->baseAddr, *(object->readBufferIdx));
    
                    if(object->countIdx > 0)
                        object->readBufferIdx++;
    
                    object->countIdx--;
                }
                else {
                    DebugP_log1("I2CSlave:(%p) ISR I2CSLAVE_READ_MODE: "
                            "Buffer overrun. Please increase the buffer size",
                            hwAttrs->baseAddr);
                    object->mode = I2CSLAVE_ERROR;
                    MAP_I2C_slaveSendNAK(hwAttrs->baseAddr);
                    MAP_I2C_slaveGetData(hwAttrs->baseAddr);
                    completeTransfer((I2CSlave_Handle) arg);
                }
                break; /* I2CSLAVE_READ_MODE */
    
    
            default:
                object->mode = I2CSLAVE_ERROR;
                break;
        }
    }

    From this I have written mine I2CSlaveTivaC, by modifying hw calls as follow :

    /*
     *  ======== I2CSlaveTivaC_hwiIntFxn ========
     *  Hwi interrupt handler to service the I2CSLAVE peripheral
     *
     *  The handler is a generic handler for a I2CSLAVE object.
     */
    void I2CSlaveTivaC_hwiIntFxn(uintptr_t arg)
    {
    //    uint16_t                     slaveStatus;
        uint16_t                     intStatus;
        I2CSlaveTivaC_Object        *object = ((I2CSlave_Handle) arg)->object;
        I2CSlaveTivaC_HWAttrs const *hwAttrs = ((I2CSlave_Handle) arg)->hwAttrs;
    
    
        /* Get the interrupt status of the I2CSlave controller */
    //    slaveStatus = I2CSlaveStatus(hwAttrs->baseAddr);
    //    I2CSlaveIntClearEx(hwAttrs->baseAddr, intStatus);
        intStatus = I2CSlaveIntStatus(hwAttrs->baseAddr, NULL);
    
        I2CSlaveIntClear(hwAttrs->baseAddr);
        /*TODO : check if correct : no slave errors in int defines ??
         * Other errors type to generate object->mode
         * */
    //    /* Check for I2CSlave Errors */
    //    if (object->mode = I2CSLAVE_ERROR) {
    //        Log_print2(Diags_USER2,"I2CSlave:(%p) ISR I2CSlave Bus fault (Status Reg: 0x%x)",
    //                   hwAttrs->baseAddr, slaveStatus);
    //    }
    
    
    
        /* No errors, now check what we need to do next */
        switch (object->mode) {
        case I2CSLAVE_ERROR:
        case I2CSLAVE_IDLE_MODE:
            System_printf("I2CSlaveTivaC_hwiIntFxn : I2CSLAVE_IDLE_MODE\n");
            System_flush();
            completeTransfer((I2CSlave_Handle) arg);
            break;
        case I2CSLAVE_START_MODE:
            if(object->transferInProgress)
            {
                completeTransfer((I2CSlave_Handle) arg);
                object->mode = I2CSLAVE_IDLE_MODE;
            }
            break;
    
        case I2CSLAVE_WRITE_MODE:
            System_printf("I2CSlaveTivaC_hwiIntFxn : I2CSLAVE_WRITE_MODE\n");
            System_flush();
            object->transferInProgress = true;
            if (object->countIdx){
                /* Write data contents into data register */
                I2CSlaveIntClear(hwAttrs->baseAddr);
                I2CSlaveDataPut(hwAttrs->baseAddr,
                                *(object->writeBufferIdx));
                Log_print2(Diags_USER2,"I2CSlave:(%p) ISR I2CSLAVE_WRITE_MODE: "
                           "Data to write: 0x%x",
                           hwAttrs->baseAddr, *(object->writeBufferIdx));
    
                object->writeBufferIdx++;
                object->countIdx--;
            }
            else {
                Log_print2(Diags_USER2,"I2CSlave:(%p) ISR I2CSLAVE_WRITE_MODE: "
                           "No more bytes available to write From slave: 0xFF",
                           hwAttrs->baseAddr, *(object->writeBufferIdx));
                object->mode = I2CSLAVE_ERROR;
                I2CSlaveIntClear(hwAttrs->baseAddr);
                I2CSlaveDataPut(hwAttrs->baseAddr, 0xFF);
                Log_print2(Diags_USER2,"I2CSlave:(%p) ISR I2CSLAVE_WRITE_MODE: "
                           "Data to write: 0x%x",
                           hwAttrs->baseAddr, *(object->writeBufferIdx));
            }
            break; /* I2CSLAVE_WRITE_MODE */
    
        case I2CSLAVE_READ_MODE:
            System_printf("I2CSlaveTivaC_hwiIntFxn : I2CSLAVE_READ_MODE\n");
            System_flush();
            object->transferInProgress = true;
            /* Data read from RXBUF and next byte has already been shifted */
            if(object->countIdx) {
                *(object->readBufferIdx) =
                        I2CSlaveDataGet(hwAttrs->baseAddr);
                    System_printf("ISR I2CSLAVE_READ_MODE: Read data byte: 0x%d", *(object->readBufferIdx));
                    System_flush();
    //            Log_print2(Diags_USER2,"I2CSlave:(%p) ISR I2CSLAVE_READ_MODE: "
    //                       "Read data byte: 0x%x",
    //                       hwAttrs->baseAddr, *(object->readBufferIdx));
    
                if(object->countIdx > 0)
                    object->readBufferIdx++;
    
                object->countIdx--;
            }
            else {
                Log_print1(Diags_USER1,"I2CSlave:(%p) ISR I2CSLAVE_READ_MODE: "
                           "Buffer overrun. Please increase the buffer size",
                           hwAttrs->baseAddr);
                object->mode = I2CSLAVE_ERROR;
                I2CSlaveACKValueSet(hwAttrs->baseAddr, false);
                I2CSlaveDataGet(hwAttrs->baseAddr);
                completeTransfer((I2CSlave_Handle) arg);
            }
            break; /* I2CSLAVE_READ_MODE */
    
    
        default:
            object->mode = I2CSLAVE_ERROR;
            break;
        }
    }
    

    I don't know how to replace the 

    EUSCI_B_I2C_RECEIVE_INTERRUPT0, 
    EUSCI_B_I2C_TRANSMIT_INTERRUPT0 ...
    in the "if...else " at the begining of the function
    What is the equivalent in tiRTOS ?
    I tried using the I2CSlaveStatus (true if interrupt is active, false otherwise) but it of course didn't match the needs, 
    so I tried with the I2CSlaveStatus (that return I2C_SLAVE_ACT_NONE, I2C_SLAVE_ACT_RREQ, I2C_SLAVE_ACT_TREQ... ) but there was still an issue...
    Do you have any idea ? 
    Please find enclose my I2CSlave driver. 
    Thank you in advance for your help !
    Elisabeth1145.i2cslave.zip  
  • Tixier Elisabeth said:
    EUSCI_B_I2C_RECEIVE_INTERRUPT0, 
    EUSCI_B_I2C_TRANSMIT_INTERRUPT0 

    Tixier Elisabeth said:
    EUSCI_B_I2C_RECEIVE_INTERRUPT0, 
    EUSCI_B_I2C_TRANSMIT_INTERRUPT0 

    Are part of the driverlib for the MSP432P4 device. You need to look in the TivaWare driverlib to see how it is done there. I'd look at the I2C Slave driverlib examples to see how it was done there. Note: basically all the driverlib calls in the example will be the same in the TI-RTOS based driver except the plugging of the vector table.

    Todd