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.

help! I'm trying i2c communication between two kits Tiva use i2c interrupt. Please give me code or idia. Thank!

help!  I'm trying i2c communication between two kits Tiva use i2c interrupt. Please give me code or idia. Thank!

  • Code in master but code not work!
    /*
    * main.c
    */
    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_memmap.h"
    #include "inc/hw_gpio.h"
    #include "inc/hw_i2c.h"
    #include "inc/hw_types.h"
    #include "inc/hw_ints.h"
    #include "inc/hw_nvic.h"
    #include "driverlib/i2c.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/gpio.h"
    #include "driverlib/interrupt.h"

    void main(void) {

    SysCtlClockSet(SYSCTL_SYSDIV_4|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);

    SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);

    GPIOPinTypeI2CSCL(GPIO_PORTB_BASE, GPIO_PIN_2);
    GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_3);


    GPIOPinTypeGPIOOutput(GPIO_PORTG_BASE,GPIO_PIN_2);

    I2CMasterInitExpClk(I2C0_BASE, SysCtlClockGet() , false);
    I2CMasterSlaveAddrSet(I2C0_BASE, 0x3B, false);


    while(1) {
    I2CMasterDataPut(I2C0_BASE, 'Q');
    I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND);
    GPIOPinWrite(GPIO_PORTG_BASE, GPIO_PIN_2, 0x04);
    while(I2CMasterBusBusy(I2C0_BASE))
    {
    //
    }
    SysCtlDelay(5000000);
    GPIOPinWrite(GPIO_PORTG_BASE, GPIO_PIN_2, 0x00);
    SysCtlDelay(5000000);
    }
    }
  • //*****************************************************************************
    // code in slave
    //*****************************************************************************


    #include <stdbool.h>
    #include <stdint.h>
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "inc/hw_i2c.h"
    #include "inc/hw_ints.h"
    #include "inc/hw_nvic.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/i2c.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/gpio.h"
    #include "utils/uartstdio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/uart.h"
    #include "driverlib/rom.h"

    //*****************************************************************************
    //
    //! \addtogroup i2c_examples_list

    //! This example uses the following peripherals and I/O signals. You must
    //! review these and change as needed for your own board:
    //! - I2C0 peripheral
    //! - GPIO Port B peripheral (for I2C0 pins)
    //! - I2C0SCL - PB2
    //! - I2C0SDA - PB3
    //!
    //! The following UART signals are configured only for displaying console
    //! messages for this example. These are not required for operation of I2C.
    //! - UART0 peripheral
    //! - GPIO Port A peripheral (for UART0 pins)
    //! - UART0RX - PA0
    //! - UART0TX - PA1

    //!
    //
    //*****************************************************************************

    //*****************************************************************************
    //
    // Number of I2C data packets to send.
    //
    //*****************************************************************************
    #define NUM_I2C_DATA 3

    //*****************************************************************************
    //
    // Set the address for slave module. This is a 7-bit address sent in the
    // following format:
    // [A6:A5:A4:A3:A2:A1:A0:RS]
    //
    // A zero in the R/S position of the first byte means that the master
    // transmits (sends) data to the selected slave, and a one in this position
    // means that the master receives data from the slave.
    //
    //*****************************************************************************
    #define SLAVE_ADDRESS 0x3C

    //*****************************************************************************
    //
    // Global variable to hold the I2C data that has been received.
    //
    //*****************************************************************************
    static unsigned long g_ulDataRx;

    //*****************************************************************************
    //
    // This is a flag that gets set in the interrupt handler to indicate that an
    // interrupt occurred.
    //
    //*****************************************************************************
    //static unsigned long g_ulIntFlag = 0;
    static volatile unsigned long g_ulIntFlag = 0; // added volatile xxxx

    //*****************************************************************************
    //
    // Configure the UART and its pins. This must be called before UARTprintf().
    //
    //*****************************************************************************
    void
    ConfigureUART(void)
    {
    //
    // Enable the GPIO Peripheral used by the UART.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

    //
    // Enable UART0
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);

    //
    // Configure GPIO Pins for UART mode.
    //
    ROM_GPIOPinConfigure(GPIO_PA0_U0RX);
    ROM_GPIOPinConfigure(GPIO_PA1_U0TX);
    ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    //
    // Use the internal 16MHz oscillator as the UART clock source.
    //
    UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);

    //
    // Initialize the UART for console I/O.
    //
    UARTStdioConfig(0, 115200, 16000000);
    }

    //*****************************************************************************
    //
    // The interrupt handler for the for I2C0 data slave interrupt.
    //
    //*****************************************************************************
    void irq_I2C0SlaveIntHandler(void)
    {
    //
    // Clear the I2C0 interrupt flag.
    //
    I2CSlaveIntClear(I2C0_BASE);

    //
    // Read the data from the slave.
    //
    g_ulDataRx = I2CSlaveDataGet(I2C0_BASE);

    //
    // Set a flag to indicate that the interrupt occurred.
    //
    g_ulIntFlag = 1;
    }

    //*****************************************************************************
    //
    // Configure the I2C0 master and slave and connect them using loopback mode.
    //
    //*****************************************************************************
    int
    main(void)
    {
    unsigned long ulDataTx;


    //
    // Set the clocking to run directly from the external crystal/oscillator.
    // TODO: The SYSCTL_XTAL_ value must be changed to match the value of the
    // crystal on your board.
    //
    SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN |
    SYSCTL_XTAL_16MHZ);

    //
    // The I2C0 peripheral must be enabled before use.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C0);

    //
    // For this example I2C0 is used with PortB[3:2]. The actual port and
    // pins used may be different on your part, consult the data sheet for
    // more information. GPIO port B needs to be enabled so these pins can
    // be used.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);

    //
    // Configure the pin muxing for I2C0 functions on port B2 and B3.
    // This step is not necessary if your part does not support pin muxing.
    //
    GPIOPinConfigure(GPIO_PB2_I2C0SCL);
    GPIOPinConfigure(GPIO_PB3_I2C0SDA);

    //
    // Select the I2C function for these pins. This function will also
    // configure the GPIO pins pins for I2C operation, setting them to
    // open-drain operation with weak pull-ups. Consult the data sheet
    // to see which functions are allocated per pin.
    // TODO: change this to select the port/pin you are using.
    //
    GPIOPinTypeI2C(GPIO_PORTB_BASE, GPIO_PIN_2 | GPIO_PIN_3);

    //
    // Enable loopback mode. Loopback mode is a built in feature that is
    // useful for debugging I2C operations. It internally connects the I2C
    // master and slave terminals, which effectively let's you send data as
    // a master and receive data as a slave.
    // NOTE: For external I2C operation you will need to use external pullups
    // that are stronger than the internal pullups. Refer to the datasheet for
    // more information.
    //
    HWREG(I2C0_BASE + I2C_O_MCR) |= 0x01;

    //
    // Enable the I2C0 interrupt on the processor (NVIC).
    //
    IntEnable(INT_I2C0);

    //
    // Configure and turn on the I2C0 slave interrupt. The I2CSlaveIntEnableEx()
    // gives you the ability to only enable specific interrupts. For this case
    // we are only interrupting when the slave device receives data.
    //
    I2CSlaveIntEnableEx(I2C0_BASE, I2C_SLAVE_INT_DATA);

    //
    // 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. For this example we will use a data rate of 100kbps.
    //
    I2CMasterInitExpClk(I2C0_BASE, SysCtlClockGet(), false);

    //
    // Enable the I2C0 slave module.
    //
    I2CSlaveEnable(I2C0_BASE);

    //
    // Set the slave address to SLAVE_ADDRESS. In loopback mode, it's an
    // arbitrary 7-bit number (set in a macro above) that is sent to the
    // I2CMasterSlaveAddrSet function.
    //
    I2CSlaveInit(I2C0_BASE, SLAVE_ADDRESS);

    //
    // Tell the master module what address it will place on the bus when
    // communicating with the slave. Set the address to SLAVE_ADDRESS
    // (as set in the slave module). The receive parameter is set to false
    // which indicates the I2C Master is initiating a writes to the slave. If
    // true, that would indicate that the I2C Master is initiating reads from
    // the slave.
    //
    I2CMasterSlaveAddrSet(I2C0_BASE, SLAVE_ADDRESS, false);

    //
    // Set up the serial console to use for displaying messages. This is just
    // for this example program and is not needed for proper I2C operation.
    //
    ConfigureUART();

    //
    // Enable interrupts to the processor.
    //
    IntMasterEnable();

    //
    // Display the example setup on the console.
    //
    UARTprintf("I2C Slave Interrupt Example ->");
    UARTprintf("\n Module = I2C0");
    UARTprintf("\n Mode = Receive interrupt on the Slave module");
    UARTprintf("\n Rate = 100kbps\n\n");

    //
    // Initialize the data to send.
    //
    ulDataTx = 'I';

    //
    // Indicate the direction of the data.
    //
    UARTprintf("Transferring from: Master -> Slave\n");

    //
    // Display the data that I2C0 is transferring.
    //
    UARTprintf(" Sending: '%c'", ulDataTx);

    //
    // Place the data to be sent in the data register.
    //
    I2CMasterDataPut(I2C0_BASE, ulDataTx);

    //
    // Initiate send of single piece of data from the master. Since the
    // loopback mode is enabled, the Master and Slave units are connected
    // allowing us to receive the same data that we sent out.
    //
    I2CMasterControl(I2C0_BASE, I2C_MASTER_CMD_SINGLE_SEND);

    //
    // Wait for interrupt to occur.
    //
    while(!g_ulIntFlag)
    {
    }

    //
    // Display that interrupt was received.
    //
    UARTprintf("\n Slave Interrupt Received!\n");

    //
    // Display the data that the slave has received.
    //
    UARTprintf(" Received: '%c'\n\n", g_ulDataRx);

    //
    // Loop forever.
    //
    while(1)
    {
    }
    }
  • Can you tell me why is code not work?
  • Hello Tran,

    1. which code is master code and which is slave code?
    2. In the "supposed master" code the Loopback mode is enabled?
    3. Slave do not work with a Control Word. It requires only setup of the Slave Address and then the CPU must poll the SCSR register for any valid transaction.

    I would suggest a good study of the I2C Data sheet before attempt to write the code. We can discuss the Master and Slave "pseudo" code first.

    Regards
    Amit