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.

PROCESSOR-SDK-AM335X: I2C issue

Part Number: PROCESSOR-SDK-AM335X


Hi,

I am using SKAM335x board.

I am trying to write and read to EEPROM through I2C without interrupt

/**
 * \file   uartEcho.c
 *
 * \brief  This example application demonstrates the working of UART for serial
 *         communication with another device/host by echoing back the data
 *         entered from serial console.
 *
 *         Application Configuration:
 *
 *             Modules Used:
 *                 UART0
 *                 Interrupt Controller
 *
 *             Configurable Parameters:
 *                 1)Baud Rate - 115200 bps to 926100 bps
 *                 2)Word Length - 5,6,7,8 bits
 *                 3)Parity - None, Odd, Even, Mark, Space
 *                 4)Stop Bits - 1, 1.5, 2 stop bits
 *
 *             Hard-coded configuration of other parameters:
 *                 1) FIFO Threshold Levels:
 *                    a) TX Trigger Space value - 56
 *                    b) TX Threshold Level - 8 (TX FIFO Size - TX Trigger Space)
 *                    c) RX Threshold Level - 1
 *
 *         Application Use case:
 *             1) Application demonstrates the Receive/Transmit features
 *                of UART using a FIFO.
 *             2) Interrupt features related to FIFO trigger levels are
 *                demonstrated for reading/writing to the FIFO.
 *             3) Functionality of UART with different Line characterics
 *                and Baud rates are demonstrated.
 *
 *         Running the Example:
 *             On executing the example:
 *             1) The user will be requested to enter 8 bytes of data from the
 *                serial console. The keyed in data will be echoed back
 *                immediately.
 *             2) Then the user will be given options to either re-run the
 *                application using default or non-default Baud Rate and Line
 *                characteristics or quit the application.
 *
 */

/*
* Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
*/
/*
*  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.
*
*/

#include "uart_irda_cir.h"
#include "evmskAM335x.h"
#include "soc_AM335x.h"
#include "interrupt.h"
#include "consoleUtils.h"
#include "hw_types.h"
#include <string.h>
#include "cache.h"
#include "mmu.h"
#include "error.h"
#include "watchdog.h"
#include "hw_control_AM335x.h"
#include "pin_mux.h"
#include "gpio_v2.h"
#include "hsi2c.h"
#include "dmtimer.h"
#include "raster.h"
#include "mcspi.h"
#include "hw_cm_wkup.h"
#include "hw_cm_per.h"
#include "hw_types.h"
#include "main.h"

int i,j;
void delay(void);

/* Page tables start must be aligned in 16K boundary */
#ifdef __TMS470__
#pragma DATA_ALIGN(pageTable, MMU_PAGETABLE_ALIGN_SIZE);
static volatile unsigned int pageTable[MMU_PAGETABLE_NUM_ENTRY];

/*
#elif defined(__IAR_SYSTEMS_ICC__)
#pragma data_alignment=MMU_PAGETABLE_ALIGN_SIZE
static volatile unsigned int pageTable[MMU_PAGETABLE_NUM_ENTRY];

#elif defined(gcc)
static volatile unsigned int pageTable[MMU_PAGETABLE_NUM_ENTRY]
 __attribute__((aligned(MMU_PAGETABLE_ALIGN_SIZE)));

#else
#error "Unsupported Compiler. \r\n"
*/
#endif


/******************************************************************************
**              FUNCTION DEFINITIONS
******************************************************************************/

/*
** This function will setup the MMU. The function maps three regions -
** 1. DDR
** 2. OCMC RAM
** 3. Device memory
** The function also enables the MMU.
*/
void MMUConfigAndEnable(void)
{
    /*
    ** Define DDR memory region of AM335x. DDR can be configured as Normal
    ** memory with R/W access in user/privileged modes. The cache attributes
    ** specified here are,
    ** Inner - Write through, No Write Allocate
    ** Outer - Write Back, Write Allocate
    */
    REGION regionDdr = {
                        MMU_PGTYPE_SECTION, START_ADDR_DDR, NUM_SECTIONS_DDR,
                        MMU_MEMTYPE_NORMAL_NON_SHAREABLE(MMU_CACHE_WT_NOWA,
                                                         MMU_CACHE_WB_WA),
                        MMU_REGION_NON_SECURE, MMU_AP_PRV_RW_USR_RW,
                        (unsigned int*)pageTable
                       };
    /*
    ** Define OCMC RAM region of AM335x. Same Attributes of DDR region given.
    */
    REGION regionOcmc = {
                         MMU_PGTYPE_SECTION, START_ADDR_OCMC, NUM_SECTIONS_OCMC,
                         MMU_MEMTYPE_NORMAL_NON_SHAREABLE(MMU_CACHE_WT_NOWA,
                                                          MMU_CACHE_WB_WA),
                         MMU_REGION_NON_SECURE, MMU_AP_PRV_RW_USR_RW,
                         (unsigned int*)pageTable
                        };

    /*
    ** Define Device Memory Region. The region between OCMC and DDR is
    ** configured as device memory, with R/W access in user/privileged modes.
    ** Also, the region is marked 'Execute Never'.
    */
    REGION regionDev = {
                        MMU_PGTYPE_SECTION, START_ADDR_DEV, NUM_SECTIONS_DEV,
                        MMU_MEMTYPE_DEVICE_SHAREABLE,
                        MMU_REGION_NON_SECURE,
                        MMU_AP_PRV_RW_USR_RW  | MMU_SECTION_EXEC_NEVER,
                        (unsigned int*)pageTable
                       };

    /* Initialize the page table and MMU */
    MMUInit((unsigned int*)pageTable);

    /* Map the defined regions */
    MMUMemRegionMap(&regionDdr);
    MMUMemRegionMap(&regionOcmc);
    MMUMemRegionMap(&regionDev);

    /* Now Safe to enable MMU */
    MMUEnable((unsigned int*)pageTable);
}




int main(void)
{



    /* Setup the MMU and do necessary MMU configurations. */
    MMUConfigAndEnable();

    /* Enable all levels of CACHE. */
    CacheEnable(CACHE_ALL);

    /* Initialize the UART console */
    ConsoleUtilsInit();

    /*Select the console type based on compile time check*/
    ConsoleUtilsSetType(CONSOLE_UART);

    // Enabling IRQ in CPSR of ARM processor.
    IntMasterIRQEnable();


    I2C_EEPROM_TEST();


}

void delay()
{
    for(i=0;i<1000;i++)
        for(j=0;j<1000;j++);
}




void I2C_EEPROM_TEST()
{

      unsigned char nibbleData = 0;
      unsigned char choice = 0;
      unsigned int lIndex2;
      unsigned int lIndex;
      unsigned char OP = 0;


    /* Enable the clock for I2C0. */
    I2C0ModuleClkConfig();

    /* Performing Pin Multiplexing for I2C0 instance. */
    I2CPinMuxSetup(0);

    ConsoleUtilsPrintf("StarterWare HSI2C EEPROM example application.\r\n");
    ConsoleUtilsPrintf(
                 "\r\nThis application reads data from EEPROM which is 32KB ");
    ConsoleUtilsPrintf(
                      "in size. The addressable memory range is from 0x0000 ");
    ConsoleUtilsPrintf(
                  "to 0x7FFF. Make sure the reads are within this range.\r\n");
    ConsoleUtilsPrintf(
                   "\r\nEnter the bus frequency(in KHz) at which I2C has to ");


    /* Configures INTC to receive I2C interrupts. */
       //I2CINTCConfigure();

       /* Enable IRQ in CPSR */
       //IntMasterIRQEnable();

       /* Configure the Bus Frequency, Slave address and enable the I2C. */
       SetupI2C();



        ConsoleUtilsPrintf(
              "\r\n\r\nEnter an address in EEPROM starting from which ");
        ConsoleUtilsPrintf(
               "data have to be read(Address range: 0x0000 - 0x7FFF): ");

        ConsoleUtilsScanf("%X", &addEeprom);

        ConsoleUtilsPrintf(
                         "\r\n\r\nEnter the number of data bytes to be read");
        ConsoleUtilsPrintf("(Range: 1 - %d): ", NUM_BYTES_READ);

        ConsoleUtilsScanf("%u", &numBytesRead);

        ConsoleUtilsPrintf("\r\n\r\nData write to EEPROM AND Data read from EEPROM:\r\n");


              EEPROMWrite();


               /* Read data from the specified address of EEPROM. */
               EEPROMRead();


               ConsoleUtilsPrintf("%d", dataFromSlave[0]);
               /*for(lIndex = 0; lIndex < numBytesRead; lIndex++)
               {
                    Collect the most significant nibble from the read data.
                   nibbleData = ((dataFromSlave[lIndex] & 0xf0) >> 4);

                   for(lIndex2 = 0; lIndex2 < 2; lIndex2++)
                   {
                        Check if the value is a numeric value.
                       if(nibbleData < 10)
                       {
                           ConsoleUtilsPrintf("%c", (nibbleData + 0x30));
                       }

                        The value is a alpha-numeric value.
                       else
                       {
                           ConsoleUtilsPrintf("%c", (nibbleData + 0x37));
                       }

                        Collect the least significant nibble from the read data.
                       nibbleData = dataFromSlave[lIndex] & 0x0f;
                   }

                   if(lIndex != (numBytesRead - 1))
                   {
                       ConsoleUtilsPrintf("%c", ',');
                   }
                   else
                   {
                       ConsoleUtilsPrintf("%c", '.');
                   }
               }

               ConsoleUtilsPrintf("\r\n\r\n");
               ConsoleUtilsPrintf(
                               "Do you want to read more data from EEPROM ? (y/n): ");
               ConsoleUtilsScanf("%c", &choice);

           }while(('y' == choice) || ('Y' == choice));

           ConsoleUtilsPrintf("\r\n");
           PRINT_STATUS(S_PASS);
*/
          // while(1);

}
static void SetupI2C(void)
{
    /* Put I2C in reset/disabled state. */
    I2CMasterDisable(I2C_INST_BASE);

    /* Disable Auto-Idle functionality. */
    I2CAutoIdleDisable(I2C_INST_BASE);

    /* Configure I2C bus frequency. */
    I2CMasterInitExpClk(I2C_INST_BASE,
                        I2C_SYS_CLK_48MHZ,
                        I2C_INTERNAL_CLK_12MHZ,
                        BUS_FREQ * 1000);   // 400 or 100 hz

    /* Set I2C slave address. */
    I2CMasterSlaveAddrSet(I2C_INST_BASE, I2C_SLAVE_ADDR);

    /* Bring I2C out of reset. */
    I2CMasterEnable(I2C_INST_BASE);
}
static void EEPROMWrite(void)
{
    dataToSlave[0] = (unsigned char)((addEeprom & 0xFF00) >> 8);
    dataToSlave[1] = (unsigned char)(addEeprom & 0x00FF);
    dataToSlave[2] = 0x5A;

     txCount = 0;

         /* Data Count specifies the number of bytes to be transmitted */
         I2CSetDataCount(I2C_INST_BASE, 3);

         numOfBytes = I2CDataCountGet(I2C_INST_BASE);

         while((HWREG(I2C_INST_BASE + I2C_IRQSTATUS_RAW))&(0<<12));

         /* Configure I2C controller in Master Transmitter mode */
         I2CMasterControl(I2C_INST_BASE, I2C_CFG_MST_TX|I2C_CFG_STOP);

         /* Transmit and Stop condition interrupt is enabled */
         //I2CMasterIntEnableEx(I2C_INST_BASE, I2C_INT_TRANSMIT_READY |
                                              //I2C_INT_STOP_CONDITION );

         /* Generate Start Condition over I2C bus */
         I2CMasterStart(I2C_INST_BASE);

         //while(complFlag);

         /* Wait untill I2C registers are ready to access */
         //while(!(I2CMasterIntRawStatus(I2C_INST_BASE) & (I2C_INT_TRANSMIT_READY)));

         //complFlag = 1;

     while(txCount<=2)
     {
     I2CMasterDataPut(I2C_INST_BASE, dataToSlave[txCount++]);

     }
    }

/*
** Reads data from EEPROM starting from the specified address.
*/
static void EEPROMRead(void)
{
    dataToSlave[0] = (unsigned char)((addEeprom & 0xFF00) >> 8);
    dataToSlave[1] = (unsigned char)(addEeprom & 0x00FF);
    txCount = 0;
    rxCount = 0;

    SetupI2CReception(numBytesRead);

    while(numBytesRead--)
    {

        /* Receive data from data receive register */
                dataFromSlave[rxCount++] = I2CMasterDataGet(I2C_INST_BASE);
                if(rxCount==numBytesRead)
                {
                I2CMasterStop(I2C_INST_BASE);
                }
    }

}

/*
** Configure the Interrupt Controller(INTC) to receive I2C interrupts.
*/
/*static void I2CINTCConfigure(void)
{
     Intialize the ARM Interrupt Controller(AINTC)
    IntAINTCInit();

     Registering the Interrupt Service Routine(ISR).
    IntRegister(I2C_INT_NUM, I2CIsr);

     Setting the priority for the system interrupt in AINTC.
    IntPrioritySet(I2C_INT_NUM, 0, AINTC_HOSTINT_ROUTE_IRQ );

     Enabling the system interrupt in AINTC.
    IntSystemEnable(I2C_INT_NUM);
}*/

/*
** Transmits and Receives data over I2C bus.
*/

static void SetupI2CTransmit(unsigned int dcount)
{
    /* Data Count specifies the number of bytes to be transmitted */
    I2CSetDataCount(I2C_INST_BASE, dcount);

    numOfBytes = I2CDataCountGet(I2C_INST_BASE);


    /* Configure I2C controller in Master Transmitter mode */
    I2CMasterControl(I2C_INST_BASE, I2C_CFG_MST_TX);// | I2C_CFG_STOP);

    while((HWREG(I2C_INST_BASE + I2C_IRQSTATUS_RAW))&(0<<12));

    I2CMasterControl(I2C_INST_BASE, I2C_CFG_STOP);

    /* Transmit and Stop condition interrupt is enabled */
    //I2CMasterIntEnableEx(I2C_INST_BASE, I2C_INT_TRANSMIT_READY |
                                         //I2C_INT_STOP_CONDITION );

    /* Generate Start Condition over I2C bus */
    I2CMasterStart(I2C_INST_BASE);

    //while(complFlag);

    /* Wait untill I2C registers are ready to access */
    //while(!(I2CMasterIntRawStatus(I2C_INST_BASE) & (I2C_INT_TRANSMIT_READY)));

    //complFlag = 1;
}
static void SetupI2CReception(unsigned int dataCountVal)
{
    /** I2C as a Master-Transmitter transmits data to EEPROM(Slave). **/

    /*
    ** Data Count specifies the number of bytes to be transmitted.
    ** The two bytes transmitted account for the EEPROM address which is
    ** 16 bits in length. This is the address starting from which the
    ** specified number of bytes have to be read.
    */
    I2CSetDataCount(I2C_INST_BASE, 0x02);

    /* Reading the value of Data Count that was set above. */
    numOfBytes = I2CDataCountGet(I2C_INST_BASE);

    /* Clear status of all interrupts */
    //I2CMasterIntClearEx(I2C_INST_BASE, 0x7FF);

    /* Configure I2C controller in Master Transmitter mode. */
    I2CMasterControl(I2C_INST_BASE, I2C_CFG_MST_TX);

    /* Transmit interrupt is enabled. */
  //  I2CMasterIntEnableEx(I2C_INST_BASE, I2C_INT_TRANSMIT_READY);

    /* Generate Start Condition over I2C bus. */
    I2CMasterStart(I2C_INST_BASE);

    while(I2CMasterBusBusy(I2C_INST_BASE) == 0);

    while(txCount != numOfBytes)
    {

             I2CMasterDataPut(I2C_INST_BASE, dataToSlave[txCount++]);
    }




    //complFlag = 1;

    /* Wait until I2C registers are ready to be accessed. */
  //  while(!(I2CMasterIntRawStatus(I2C_INST_BASE) & (I2C_INT_ADRR_READY_ACESS)));

    /** I2C as a Master-Receiver receives data from EEPROM. **/

    /* Data Count specifies the number of bytes to be received. */
    I2CSetDataCount(I2C_INST_BASE, dataCountVal);

    /* Reading the value of Data Count that was set above. */
    numOfBytes = I2CDataCountGet(I2C_INST_BASE);

    /* Clear status of all interrupts */
    //I2CMasterIntClearEx(I2C_INST_BASE, 0x7FF);

    /* Configure I2C controller in Master Receiver mode. */
    I2CMasterControl(I2C_INST_BASE, I2C_CFG_MST_RX);

    /* Receive and Stop Condition Interrupts are enabled. */
    //I2CMasterIntEnableEx(I2C_INST_BASE, I2C_INT_RECV_READY |
                                        //I2C_INT_STOP_CONDITION);

    /* Generate Start Condition over I2C bus */
    I2CMasterStart(I2C_INST_BASE);

    while(I2CMasterBusBusy(I2C_INST_BASE) == 0);

    //while(complFlag);

    //complFlag = 1;
}

/*
** I2C Interrupt Service Routine. This function will read and write
** data through I2C bus.
*/
/*
static void I2CIsr(void)
{
    unsigned int status = 0;

     Get only Enabled interrupt status
    status = I2CMasterIntStatus(I2C_INST_BASE);


    ** Clear all enabled interrupt status except receive ready and
    ** transmit ready interrupt status

    I2CMasterIntClearEx(I2C_INST_BASE,
                        (status & ~(I2C_INT_RECV_READY | I2C_INT_TRANSMIT_READY)));

    if(status & I2C_INT_RECV_READY)
    {
         Receive data from data receive register
        dataFromSlave[rxCount++] = I2CMasterDataGet(I2C_INST_BASE);

         Clear receive ready interrupt status
        I2CMasterIntClearEx(I2C_INST_BASE,  I2C_INT_RECV_READY);

        if(rxCount == numOfBytes)
        {
             Disable the receive ready interrupt
            I2CMasterIntDisableEx(I2C_INST_BASE, I2C_INT_RECV_READY);
             Generate a STOP
            I2CMasterStop(I2C_INST_BASE);
        }
    }

    if (status & I2C_INT_TRANSMIT_READY)
    {
         Put data to data transmit register of i2c
        I2CMasterDataPut(I2C_INST_BASE, dataToSlave[txCount++]);

         Clear Transmit interrupt status
        I2CMasterIntClearEx(I2C_INST_BASE, I2C_INT_TRANSMIT_READY);

        if(txCount == numOfBytes)
        {
             Disable the transmit ready interrupt
            I2CMasterIntDisableEx(I2C_INST_BASE, I2C_INT_TRANSMIT_READY);
        }
    }

    if (status & I2C_INT_STOP_CONDITION)
    {
         Disable transmit data ready and receive data read interupt
        I2CMasterIntDisableEx(I2C_INST_BASE, I2C_INT_TRANSMIT_READY |
                                             I2C_INT_RECV_READY     |
                                             I2C_INT_STOP_CONDITION);
         complFlag = 0;
    }

    if(status & I2C_INT_NO_ACK)
    {
        I2CMasterIntDisableEx(I2C_INST_BASE, I2C_INT_TRANSMIT_READY  |
                                             I2C_INT_RECV_READY      |
                                             I2C_INT_NO_ACK          |
                                             I2C_INT_STOP_CONDITION);
         Generate a STOP
        I2CMasterStop(I2C_INST_BASE);

        complFlag = 0;
    }

    ConsoleUtilsPrintf("I2C INTERRUPT occurred\n");
}
*/














/******************************* End of file *********************************/
3286.main.hbut it's not working correctly. I am attaching main.c and main.h files. Could you please verify it and tell me If I did something wrong.

Thanks

Gaurav