/*-----------------------------------------------------------------------------------*/
/* Nuvoton Technology Corporation confidential */
/* */
/* Copyright (c) 2008 by Nuvoton Technology Corporation */
/* All rights reserved */
/* */
/*-----------------------------------------------------------------------------------*/
/* File Contents: */
/* i2c_24LC64.c */
/* */
/* This file contains: */
/* */
/* Project: */
/* */
/* Description: */
/* This file is a sample program used to access EEPROM (24LC64) on W90P910 */
/* EV Board. */
/* */
/* Remark: */
/* 1. Execute this program on 910 EV board that should set slave addr 0x50 for */
/* I2C0 and set slave addr 0x51 for I2C1. It's H/W disign issue. */
/* 2. Microchip 24LC64 is EEPROM, 64K bits size, page-write buffer for up to */
/* 32bytes. */
/* */
/*-----------------------------------------------------------------------------------*/
#ifdef ECOS
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
#include "kapi.h"
#include "diag.h"
#include "wbio.h"
#else
#include <stdio.h>
#include <string.h>
#include "wblib.h"
#endif
#include "NUC900_i2c.h"
/* If test I2C on module board, should configure switch of GPIOH pins. */
//#define MODULE_BOARD
#define I2CNUM_0 0
#define I2CNUM_1 1
#define RETRY 1000 /* Programming cycle may be in progress. Please refer to 24LC64 datasheet */
#define TXSIZE 512
#define ADDROFFSET 1024
#ifdef MODULE_BOARD
#define REG_GPIOH_DIR 0xB8003054
#define REG_GPIOH_DATAOUT 0xB8003058
#endif
#ifdef ECOS
#define i2cprintf diag_printf
#define i2cgetchar diag_getc
#else
#define i2cprintf sysprintf
#define i2cgetchar sysGetChar
#endif
#ifdef ECOS
static cyg_handle_t thread_handle;
static cyg_thread thread;
#define STACKSIZE (128*1024)
static UINT8 _Statck[STACKSIZE];
#endif
//------------------------- Program -------------------------//
#ifdef ECOS
void i2cExample (cyg_addrword_t tdata)
#else
void i2cExample (VOID)
#endif
{
unsigned char data[TXSIZE], value[TXSIZE];
int i, j, err, cnt;
INT32 rtval;
#ifdef MODULE_BOARD
/* control GPIOH[7:4], 1 0 1 0 */
outpw(REG_MFSEL, inpw(REG_MFSEL) & ~(1 << 25));
outpw(REG_GPIOH_DIR, inpw(REG_GPIOH_DIR) | 0xF0);
outpw(REG_GPIOH_DATAOUT, ( inpw(REG_GPIOH_DATAOUT) & (~0xF0) ) | 0xA0 );
#endif
/* initialize test data */
for(i = 0 ; i < TXSIZE ; i++)
data[i] = i + 1;
i2cInit();
/* I2C channel 0 Test, Byte Write/Random Read */
i2cprintf("\nI2C0 Byte Write/Random Read ...\n");
rtval = i2cOpen((PVOID)I2CNUM_0);
if(rtval < 0)
{
i2cprintf("Open I2C0 error!\n");
goto i2c1_test;
}
i2cIoctl(I2CNUM_0, I2C_IOC_SET_DEV_ADDRESS, 0x50, 0); /* On 910 EV board, set 0x50 for I2C0 */
i2cIoctl(I2CNUM_0, I2C_IOC_SET_SPEED, 100, 0);
/* Tx porcess */
i2cprintf("Start Tx\n");
for(i = 0 ; i < TXSIZE ; i++)
{
i2cIoctl(I2CNUM_0, I2C_IOC_SET_SUB_ADDRESS, i, 2);
j = RETRY;
while(j-- > 0)
{
if(i2cWrite(I2CNUM_0, &data[i], 1) == 1)
break;
}
if(j <= 0)
i2cprintf("WRITE ERROR [%d]!\n", i);
}
/* Rx porcess */
i2cprintf("Start Rx\n");
memset(value, 0 , TXSIZE);
for(i = 0 ; i < TXSIZE ; i++)
{
i2cIoctl(I2CNUM_0, I2C_IOC_SET_SUB_ADDRESS, i, 2);
j = RETRY;
while(j-- > 0)
{
if(i2cRead(I2CNUM_0, &value[i], 1) == 1)
break;
}
if(j <= 0)
i2cprintf("Read ERROR [%d]!\n", i);
}
/* Compare process */
i2cprintf("Compare data\n");
err = 0;
cnt = 0;
for(i = 0 ; i < TXSIZE ; i++)
{
if(value[i] != data[i])
{
i2cprintf("[%d] addr = 0x%08x, val = 0x%02x (should be 0x%02x)\n", i, i + ADDROFFSET, value[i], data[i]);
err = 1;
cnt++;
}
}
if(err)
i2cprintf("Test failed [%d]!\n\n", cnt);
else
i2cprintf("Test success\n\n");
i2cClose(I2CNUM_0);
/* I2C0 Test End */
/* I2C channel 1 Test, Page Write/Sequential Read */
i2c1_test:
i2cprintf("\nI2C1 Page Write/Sequential Read ...\n");
rtval = i2cOpen((PVOID)I2CNUM_1);
if(rtval < 0)
{
i2cprintf("Open I2C1 error!\n");
goto exit_test;
}
i2cIoctl(I2CNUM_1, I2C_IOC_SET_DEV_ADDRESS, 0x51, 0); /* On 910 EV board, set 0x51 for I2C1 */
i2cIoctl(I2CNUM_1, I2C_IOC_SET_SPEED, 100, 0);
/* Tx porcess */
i2cprintf("Start Tx\n");
for(i = 0 ; i < (TXSIZE / 32) ; i++)
{
i2cIoctl(I2CNUM_1, I2C_IOC_SET_SUB_ADDRESS, ADDROFFSET + (i*32), 2);
j = RETRY;
while(j-- > 0)
{
if(i2cWrite(I2CNUM_1, &data[i*32], 32) == 32)
break;
}
if(j <= 0)
i2cprintf("WRITE ERROR [%d]!\n", i);
}
/* Rx porcess */
i2cprintf("Start Rx\n");
memset(value, 0 , TXSIZE);
for(i = 0 ; i < (TXSIZE / 32) ; i++)
{
i2cIoctl(I2CNUM_1, I2C_IOC_SET_SUB_ADDRESS, ADDROFFSET + (i*32), 2);
j = RETRY;
while(j-- > 0)
{
if(i2cRead(I2CNUM_1, &value[i*32], 32) == 32)
break;
}
if(j <= 0)
i2cprintf("Read ERROR [%d]!\n", i);
}
/* Compare process */
i2cprintf("Compare data\n");
err = 0;
cnt = 0;
for(i = 0 ; i < TXSIZE ; i++)
{
if(value[i] != data[i])
{
i2cprintf("[%d] addr = 0x%08x, val = 0x%02x (should be 0x%02x)\n", i, i + ADDROFFSET, value[i], data[i]);
err = 1;
cnt++;
}
}
if(err)
i2cprintf("Test failed [%d]!\n\n", cnt);
else
i2cprintf("Test success\n\n");
i2cClose(I2CNUM_1);
/* I2C1 Test End */
exit_test:
i2cprintf("\nTest finish ...\n");
i2cExit();
return;
}
int main (VOID)
{
#ifdef ECOS
cyg_thread_create(21, i2cExample, 0, "i2cEEPROM", _Statck, STACKSIZE, &thread_handle, &thread);
cyg_thread_resume(thread_handle);
#else
i2cExample();
#endif
return 0;
}