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(®ionDdr);
MMUMemRegionMap(®ionOcmc);
MMUMemRegionMap(®ionDev);
/* 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 *********************************/
Thanks
Gaurav