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.

RF430FRL152HEVM: I2C interface with external digital sensors

Part Number: RF430FRL152HEVM
Other Parts Discussed in Thread: RF430FRL152H

Hello,

I work with the RF430FRL152HEVM and wanted to use it to control a digital sensor ENS210, unfortunately I have not yet succeeded in establishing communication there and ideally transfer this via RFID, communication takes place via I2C.
I am not even sure if it is possible with the EVM or if it only works with the SensorPack.

Does anyone have any information or examples on how to establish I2C communication or how to control external sensors with the RF430...?

I am happy about every tip.

Best 

SJ

  • Hello S J,

    It is possible with the EVM. Looking at the device you are using, you will need level translators. The I2C bus of the RF430FRL152H operates at 1.5V with a max of 1.65 which is lower than 1.71V of the ENS210 sensor. If you don't have this in place, that is likely your issue.

    Also, make sure you have pull-up resistors installed for the I2C bus. 

    You should review our FAQ guide for hardware and software guide when it comes to interfacing digital sensors to the RF430FRL152HEVM: https://www.ti.com/lit/pdf/sloa247

  • Hello Ralph, thank you very much for the feedback,

    I think it would work with the EVM, it has a level shifter. The problem is to address the I2C interface, that's on the software side. I already have the ENS210 code and it works with other µCs, but it somehow doesn't work with the RF430. I have adapted the sample code RF430FRL152H SensorHub Project, but neither clock nor signal can get through. The level is always HIGH, measured with a logic analyzer. So I wanted to ask if there are other examples I can use to help me.

    I have uploaded the main file with the code, if you want to have a look at it.

    Best

    SJ

    #include <rf430frl152h.h>
    #include <string.h>
    #include "main.h"
    
    
    //*****************************FUNCTION PROTOTYPES********************************/
    void DeviceInit(void);
    void initISO15693(u16_t parameters );
    void DigitalSensorInit();
    void ens210_meas();
    float get_real_temp();
    float get_real_hum();
    //********************************************************************************/
    
    //*****************************DEFINES *******************************************/
    #define CLEAR_BLOCK_LOCKS                               BIT3
    #define FRAM_LOCK_BLOCK_AREA_SIZE                       38
    #define FRAM_LOCK_BLOCKS                                0xF840  //Address of ISO15693 lock blocks
    
    
    #define ROM_EUSCI_SUPPORT_ENABLED       BIT2
    #define EROM_EUSCI_SUPPORT_DISABLED     0
    #define ROM_SENSOR_SUPPORT_ENABLED      BIT7
    #define ROM_SENSOR_SUPPORT_DISABLED     0
    #define NFC_BRIDGE_DISABLED             BIT6
    #define NFC_BRIDGE_ENABLED              0
    #define EIGHT_BYTE_BLOCK                BIT0
    #define FOUR_BYTE_BLOCK                 0
    #define FIRST_ISO_PAGE                  BIT1
    #define SECOND_ISO_PAGE                 0
    
    /* Firmware System Control Byte
     *
     *     Bit 0:   ISOBlockSize                0 - 4 byte,     1 - 8 byte
     *     Bit 1:   Page                        0 - page 1,     1 - page 0 (Effective only for 4-byte block mode)
     *     Bit 2:   ROMEUSCISupportEnabled      0 - disabled,   1 - enabled (Forced to 0 on RF430FRL153H)
     *     Bit 3-5: ReservedISO
     *     Bit 6:   NFCBridgeDisable            0 - enabled,    1 - disabled (see note below)
     *     Bit 7:   ROMSensorSupportEnable      0 - disabled,   1 - enabled (Forced to 0 on RF430FRL154H)
     *
     *     NFC bridge is recommended to be disabled in this project.  Unexpected behaviour can occur,
     *     trying to use it, due to the configuration being setup here.
     *
     *     If eUSCI host controller portion is needed along with the RF functionality, the default project
     *     must be used.  That is NFC cannot be supported in that application (because the I2C/SPI host controller
     *     control registers are in the same place that the NFC file needs to be).  However the rest of the FRAM
     *     memory can be used for storing and reading using ISO15693.
     */
    
    #define FIRMWARE_CONTROL_ADDRESS    0xF867
    #pragma RETAIN(Firmware_System_Control_Byte);
    #pragma location = FIRMWARE_CONTROL_ADDRESS
    
    /*********************** SUMMARY **************************************************************************************************
     * This project only utilizes the RF stack (ISO15693) on the ROM of the RF430FRL15xH. This setup allows the user to make a
     * custom application that is run from FRAM.  Only the RF13M vector that runs the RF stack needs to be pointing to its
     * ROM location.
     */
    
    
    //**********************Allocate Memory to Store ADC Reading**********************/
    #define ADC_ADDRESS 0xF88C // Block 9
    #pragma RETAIN(ADC_Read);
    #pragma location = ADC_ADDRESS;
    u16_t ADC_Read[2];
    //********************************************************************************/
    
    
    
    //**********************Global variables**********************/
    u32_t t_val = 0;      //variable for temperature
    u32_t h_val = 0;      //variable for humidity
    //************************************************************/
    
    int adcChange = 0;
    
    
    void main(void)
    {
    	WDTCTL = WDTPW | WDTHOLD;	// stop watchdog timer
    
    	// ROM RF13M module setup ** The following three lines are needed for proper RF stack operation
        DS = 1;                                     // ROM variable needs to be initialized here
        asm ( " CALL #0x5CDA ");                    // Call ROM function ( Initialize function pointers)
        asm ( " CALL #0x5CAC ");                    // Call ROM function ( Check part configuration)
    
        initISO15693(CLEAR_BLOCK_LOCKS);
        DeviceInit();
        DigitalSensorInit();
    
        //Setup ADC
        //SD14CTL0 = SD14EN + VIRTGND + SD14IE; //ADC enabled, Virtual Ground enabled, Interrupt enabled.
        SD14CTL1 = SD14RBEN1 + SD14RBEN0 + SD14UNI + SD14GAIN0 + SD14INTDLY0 + THERMISTOR_ADC2_SENSOR; //SD14UNI + SD14INTDLY0;     // Unipolar mode, Interrupt triggered after first sample.
    
            while(1)
            {
                ens210_meas();
    
                //led_blink();
    
                /*switch(adcChange)
                {
                    case 0:
                        SD14CTL1 = SD14RBEN1 + SD14RBEN0 + SD14UNI + SD14GAIN0 + SD14INTDLY0 + THERMISTOR_ADC2_SENSOR; //SD14UNI + SD14INTDLY0;     // Unipolar mode, Interrupt triggered after first sample.
                        adcChange = 1;
    
                        break;
                    case 1:
                        SD14CTL1 = SD14RBEN1 + SD14RBEN0 + SD14UNI + SD14GAIN0 + SD14INTDLY0 + ADC0_SENSOR; //SD14UNI + SD14INTDLY0;     // Unipolar mode, Interrupt triggered after first sample.
                        adcChange = 0;
                        break;
                    default:
                        break;
                }
    */
                //SD14CTL0 |= SD14SC; //begin conversion
                //__bis_SR_register(LPM3_bits + GIE);
            }
    }
    
    #pragma vector=SD_ADC_VECTOR
    interrupt void ADC (void)
    {
        switch(__even_in_range(SD14IV,4))
        {
            case SD14IV__NONE: // no interrupt pending
            {
                break;}
    
            case SD14IV__RES: //ADC Data available
            {
                SD14CTL0 &= ~SD14IFG;   //clear the data available interrupt
                ADC_Read[0] = SD14MEM0; //Read the ADC Data
                __bic_SR_register_on_exit(LPM4_bits);
                break;}
            case SD14IV__OV: //Memory Overflow
            {
                SD14CTL0 &= ~SD14OVIFG; //clear the overflow bit
                 break;}
        }
    }
    
    /**************************************************************************************************************************************************
    *  DeviceInit
    ***************************************************************************************************************************************************
    *
    * Brief : Initialize the clock system and other settings
    *         Patchable function
    *
    * Param[in] :   parameters:  has these independent options
    *                            INITIALIZE_DEVICE_CLOCK_SYSTEM - initializes the clock system
    *                            POPULATE_INTERRUPT_VECTOR_IN_INITIALIZATION - populate the default interrupt vectors and recalculate their CRC
    *
    * Param[out]:  None
    *
    * Return  None
    *
    * Patchable :   Yes
    **************************************************************************************************************************************************/
    void DeviceInit(void)
    {
        P1SEL0 = 0xF0; //keep JTAG
        P1SEL1 = 0xF0; //keep JTAG
        P1DIR &= ~0xEF;
        P1REN = 0;
    
        CCSCTL0 = CCSKEY;                        // Unlock CCS
    
        CCSCTL1 = 0;                             // do not half the clock speed
        CCSCTL4 = SELA_1 + SELM_0 + SELS_0;      // Select VLO for ACLK and select HFCLK/DCO for MCLK, and SMCLK
        CCSCTL5 = DIVA_2 + DIVM_1 + DIVS_1;      // Set the Dividers for ACLK (4), MCLK, and SMCLK to 1
        CCSCTL6 = XTOFF;                         // Turns of the crystal if it is not being used
        CCSCTL8 = ACLKREQEN + MCLKREQEN + SMCLKREQEN; //disable clocks if they are not being used
    
        CCSCTL0_H |= 0xFF;                       // Lock CCS
    
      return;
    }
    
    
    //#pragma CODE_SECTION(RF13M_ISR, ".fram_driver_code")  // comment this line for using ROM's RF13M ISR, uncomment next one, see .cmd file for details
    #pragma CODE_SECTION(RF13M_ISR, ".rf13m_rom_isr")       // comment this line for creating a custom RF13M ISR that will exist in FRAM, bypassing ROM's, uncomment previous
    #pragma vector = RF13M_VECTOR
    __interrupt void RF13M_ISR(void)
    {
        // Right now this vector is pointing to the ROMs firmware location that runs the RF stack.
        // Entering code here will, without changing the CODE_SECTION lines
        // above, will cause an error.
        // Changing the code section above will cause the ROM RF stack to be bypassed.  New handler will need to be created.
    }
    
    /**************************************************************************************************************************************************
    *   DigitalSensorInit
    ***************************************************************************************************************************************************
    *
    * Brief :       Called by the RF430FRL152H ROM code.
    *               Initializes the RF430's eUSCI into master mode, for use with sampling digital sensors
    *               Function extends functionality of the ROM firmware.
    *               Called on reset (PUC) during initialization, only once.
    *
    * Param[in] :   None
    *
    *
    * Param[out]:   None
    *
    * Return :      None
    *
    **************************************************************************************************************************************************/
    
    
    #pragma RETAIN (DigitalSensorInit)  //needed to prevent of optimizing out this function
    //the line below constrains the placement of the function to a specific section of code
    //declared in the .cmd file.  Basically we want the function code to be placed in the end
    // of the FRAM memory to not interfere with the virtual registers and log memory before it
    #pragma CODE_SECTION (DigitalSensorInit, ".fram_driver_code") //see .cmd file for details - all new firmware must go into fram_driver_code memory section space
    void DigitalSensorInit()
    {
        //ROM sets P1OUT = 0x0F, this then consumes some current
        P1OUT = 0x00; // needed to reduce power consumption on RF430FRL152H EVM, since P1.3 is connected to a 2.2K Ohm resistor on the EVM to ground
    
        P1DIR &= ~MASTER_SLAVE_SELECT; // check if digital sensor mode is selected
        if (P1IN & MASTER_SLAVE_SELECT)
        {
            //P1DIR &= ~MASTER_SLAVE_SELECT;  //host controller mode selected, exit
            return;
        }
    
        /* For custom digital sensor initialization, keep the previous code as is and change the following as needed.*/
    
        // Configure P1.0 and P1.1 pins for I2C mode
        PORT_I2C_SEL0 |= SCL + SDA;
        PORT_I2C_SEL1 &= ~(SCL + SDA);
    
        // configure eUSCI for I2C
        UCB0CTL1 |= UCSWRST;                   // Software reset enabled
        UCB0CTLW0 |= UCMODE_3  + UCMST + UCSYNC + UCTR;     // I2C mode, Master mode, sync, transmitter
        UCB0CTLW0 |= UCSSEL_2;                              // select SMCLK at 2MHz
        UCB0BRW = 10;                                       // 2Mhz / 10 = 200kHz
        UCB0I2CSA = 0x0043;                                 // slave address of ENS210, initially
        UCB0CTL1  &= ~UCSWRST;                              // exit reset mode
    }
    
    #pragma RETAIN (ens210_meas)
    #pragma CODE_SECTION (ens210_meas, ".fram_driver_code") //see .cmd file for details - all new firmware must go into fram_driver_code memory section space
    void ens210_meas()
    {
        u08_t wbuf[] = { 0x03 };
        u08_t rbuf[6];
    
        UCB0CTL1 |= UCSWRST;                // Software reset enabled
        UCB0I2CSA  = 0x0043;                // I2C slave address of ens210
        //UCBCTL1  &= ~UCSWRST;           // exit eusci reset
    
        UCB0CTL1  &= ~UCSWRST;          // put eUSCI out of reset mode
        UCB0CTLW1 = UCASTP_1;
        UCB0TBCNT = 0x0001;
        UCB0CTL1 |= UCTXSTT + UCTR;     // start i2c write operation
        //while(!(UCB0IFG & UCTXIFG0));   // wait until transmit is needed
        UCB0TXBUF = 0x86;                // send the command        write command
        UCB0TXBUF = 0x22;                // send the command        start meas ens210
        UCB0TXBUF = wbuf;
    
        while(!(UCB0IFG & UCBCNTIFG));      //stop
    
        _delay_cycles(150000);      //150ms delay
    
        //while(!(UCB0IFG & UCTXIFG0));   // wait until transmit is needed
        UCB0TXBUF = 0x86;                // send the command        write command
        UCB0TXBUF = 0x30;                // send the command        start meas ens210
    
        UCB0CTL1 |= UCTXSTT;            // repeated start
    
        UCB0TXBUF = 0x87;                // send the command        read values
    
    
        u08_t i = 0;
        for(i = 0; i > 6; i++)
        {
            while(!(UCB0IFG & UCRXIFG0));   // wait until read data available
            wbuf[i] = UCB0RXBUF;            // read the MSB
        }
        UCB0CTLW0 |= UCTXSTP;           // send stop after next byte
    
        t_val = (rbuf[2]<<16) + (rbuf[1]<<8) + (rbuf[0]<<0);
        h_val = (rbuf[5]<<16) + (rbuf[4]<<8) + (rbuf[3]<<0);
    
    }
    
    
    float get_real_temp()
    {
            //calc temperature
        u32_t t_data = (t_val>>0 ) & 0xffff;
        float TinK = (float)t_data / 64; // Temperature in Kelvin
        float TinC = TinK - 273.15; // Temperature in Celsius
        //float TinF = TinC * 1.8 + 32.0; // Temperature in Fahrenheit
    
        return TinC;
    }
    
    float get_real_hum()
    {
            //calc humidity
        u32_t h_data = (h_val>>0 ) & 0xffff;
        float H = (float)h_data/512; // relative humidity (in %)
    
        return H;
    }
    
    void led_blink()
    {
    
        //Set Ports to GPIO Mode
        P1SEL0 = 0x00;
        P1SEL1 = 0x00;
        //Set pin 1.4 to output
        P1DIR = 0x10;
    
        //Toggle Output High
        P1OUT = 0x10;
        _delay_cycles(4000000);
        //Toggle Output Low
        P1OUT = 0x00;
        _delay_cycles(4000000);
    
        //Enter Low Power mode
        //__bis_SR_register(LPM3_bits + GIE);
    
    }
    

  • Hello S J,

    Unfortunately no we don't have additional examples for this device.

    I would recommend doing a close comparison of the configurations. Maybe also configure I2C at 100 kHz to start. I would suggest debugging your code to make sure you are getting to the lines where data is supposed to be sent while also monitoring with logic analyzer.