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.

MSP430FR2633: CAPTIVATE-Raw Data Register I2C

Part Number: MSP430FR2633

Hi all,

I have an MSP CapTIvate MCU Development Kit. In my application, I would like to have a host microcontroller (e.g. an Arduino) that can talk to the MSP430 to get information from the sensor board, including the raw measurement data. In the CapTivate Design Center, I set the Communication Interface to REGISTER_I2C.  I found a way of using REGISTER_I2C here:

software-dl.ti.com/.../ch_library.html

After following the instructions in the link above, my host microcontroller can access the wheel position. However, I haven't found any information regarding using REGISTER_I2C for accessing raw data.

Is there a simple way of accessing raw capacitance data (delta or count) with REGISTER_I2C?

Kind regards,

Hermawan Mulyono

  • Sorry, my bad! Apparently the cycle packets format gives me this functionality.
  • Correct, the LTA and filtered count values are made available in the cycle packets.

    Walter
  • Hi Walter,

    Thank you for confirming. May I also ask if it is possible to obtain the unfiltered and filtered count values simultaneously?

    I was considering doing this by switching on and off the filter count. However, according to the link below, the filter is actually a simple IIR low pass filter. Therefore, I am afraid that when the filter is switched off and on again, it will reset the PrevFiltered variable to 0. Is this really the case?

    software-dl.ti.com/.../Count_Filter.html
  • hermawan mulyono said:
    Thank you for confirming. May I also ask if it is possible to obtain the unfiltered and filtered count values simultaneously?

    You can read out the unfiltered and filtered count values, but you'll need to set up a command listener for the unfiltered values yourself.

    hermawan mulyono said:
    I was considering doing this by switching on and off the filter count. However, according to the link below, the filter is actually a simple IIR low pass filter. Therefore, I am afraid that when the filter is switched off and on again, it will reset the PrevFiltered variable to 0. Is this really the case?

    If you disable the count filter, read the count value, and re-enable it, you won't see any change vs. reading the values when filtering is enabled (the values are only refreshed when the sensor is updating).  You can, if you so choose, disable the filtering dynamically at run-time.  The filter is seeded based on the first measurement result after calibration.  After that, you can disable the filtering and your next sample which is updated will simply be equivalent to the raw result.  If you re-enable filtering later, it will take affect on the first measurement/update that happens after you re-enable it.  At that point, it would take the new raw sample and filter it with your previous raw sample, and then you would start building out a historical average of samples after that.

    If your intent is simply to view the unfiltered and filtered result, I recommend you just leave the filtering enabled and set up the SW to allow you to read the raw count from the pRawCount[] array in each element.

    To expand the functionality of the register I2C driver, you'll want to open the CAPT_Interface.c file and make some edits.  This file is located under /project_name/captivate/COMM/CAPT_Interface.c.  The function of interest is the I2C register receive handler, which interprets requests on the I2C interface and provides responses for the host (master) device to read back.  Below is this function as-is from TI in CAPT_Interface.c.

    static bool CAPT_I2CRegisterReceiveHandler(uint16_t ui16Cnt)
    {
        tTLParameterAccessResult actionAfterParamterAccess;
        
        if (ui16Cnt < 2)
        {
            return false;
        }

        //
        // If the master is requesting a sensor packet, enter here
        //
        if (g_ui8I2CDataBuffer[TL_PCKT_CMD_FIELD] == TL_SENSOR_PACKET_CMD)
        {
            (void)MAP_CAPT_getSensorPacket(
                    g_pApp->pSensorList,
                    g_ui8I2CDataBuffer[TL_SENSOR_PCKT_ID_FIELD],
                    g_ui8I2CDataBuffer
                );
        }

        //
        // Else, if the master is requesting a cycle packet, enter here
        //
        else if (g_ui8I2CDataBuffer[TL_PCKT_CMD_FIELD] == TL_CYCLE_PACKET_CMD)
        {
            (void)MAP_CAPT_getCyclePacket(
                    g_pApp->pSensorList,
                    g_ui8I2CDataBuffer[TL_CYCLE_PCKT_ID_FIELD],
                    g_ui8I2CDataBuffer[TL_CYCLE_PCKT_CYCLE_FIELD],
                    g_ui8I2CDataBuffer
                );
        }

        //
        // Else, assume the master is requesting a parameter packet and enter here
        //
        else
        {
            if (g_ui8I2CDataBuffer[TL_PCKT_CMD_FIELD] < TL_PARAM_CMD_CTRL_MASK)
            {
                actionAfterParamterAccess = MAP_CAPT_accessSensorParameter(
                        g_pApp->pSensorList,
                        (tParameterPacket*)g_ui8I2CDataBuffer
                    );
            }
            else
            {
                actionAfterParamterAccess = CAPT_accessControllerParameter((tParameterPacket*)g_ui8I2CDataBuffer);
            }

            if (actionAfterParamterAccess == eValidCmdWithReCalibrate)
            {
                g_bReCalibrationRequired = true;
            }
        }

        //
        // Return false to exit with the CPU in its previous state.
        // Since the response packet generation was handled immediately here,
        // there is no need to exit active.
        //
        return false;
    }

    Note that compares g_ui8I2CDataBuffer[TL_PCKT_CMD_FIELD] with several CMD values in an attempt to match the request from the master with a packet type/CMD type that the library understands.  You'll need to create a command ID for sensor raw data, and come up with a way to serve that data to the host via the g_ui8I2CDataBuffer.

    The data you want to look up would be the raw count information, which could look like this:

    else if (g_ui8I2CDataBuffer[TL_PCKT_CMD_FIELD] == 0x20)
    {
        // Treat this as a custom CMD to get raw data
        for (i=0; i<g_pApp->pSensorList[g_ui8I2CDataBuffer[TL_CYCLE_PCKT_ID_FIELD]]->pCycle[g_ui8I2CDataBuffer[TL_CYCLE_PCKT_CYCLE_FIELD]]->ui8NrOfElements; i++)
        {
            // Get raw data for current element and append to data buffer for host to read
            raw = g_pApp->pSensorList[g_ui8I2CDataBuffer[TL_CYCLE_PCKT_ID_FIELD]]->pCycle[g_ui8I2CDataBuffer[TL_CYCLE_PCKT_CYCLE_FIELD]]->pElements[i]->pRawCount[0];
            g_ui8I2CDataBuffer[6 + (i*2)] = (uint8_t)(raw & 0x00FF);
            g_ui8I2CDataBuffer[7 + (i*2)] = (uint8_t)((raw >> 8) & 0x00FF);
        }
    }

    Here I add a new CMD ID (0x20) for accessing a cycle's raw data.  We iterate for-each element in the cycle, and append the raw count value to the I2C data buffer for the host to read.  You would need to insert this code after the if(){} for the SENSOR packet CMD or the if(){} for the CYCLE packet CMD.

    Regards,
    Walter

  • Hi Walter,

    Thank you very much for your detailed response. I will give it a go! At the moment, this solution looks plausible to me.

    Many thanks,

    Hermawan Mulyono
  • Hi Walter,

    I am glad to tell you that your solution works. Thank you very much!

    Regards,

    Hermawan Mulyono
  • Great, no problem!  Happy developing.


    Walter

**Attention** This is a public forum