/
//title:关于I2C控制的一些注意问题
//descrpit:分析I2C总线工作原理和实现方法
//author:Mercury Xu
//date:2008-09-20
/
阅读本文前请先阅读完I2C协议手册,下载地址如下:
http://download.csdn.net/source/315355
最近的开发一直与I2C有关系。以前写过I2C通讯相关东西。但是用的是别人的封装函数。所以没有怎么仔细看。
这次通过开发MTV335这款芯片自己参考了原厂提供的代码写了一个I2C通讯的程序。没有做成类的形式,也是普通的函数调用。应该比较容易理解和使用。具体的操作如下,另外要提得一点是,在做I2C程序之前一定要硬件工程师帮你检查下或者你自己检查下线路是否通畅,上拉电阻是否使用正确,I2C两线的电压是否正常3.3-5V。检查完这些后,尝试送一组值给芯片,看下波型是否正确,如果正确就放心大胆的写东西吧,多话不说了,大家看参考代码吧。其中我使用了一些伪代码来替代一些操作,不同的芯片用不同的方式去替换就好了。
另,参考程序是基于wince5.0下流设备驱动形式编写,请按照各自不同的芯片进行修改。
#ifndef _DEMO_H_
#define _DEMO_H_
#define DELAY_CNT 50 //Delay 50 us
#define DEMO_WriteID 0x4A //[DEMO] Write address
#define DEMO_ReadID 0x4B //[DEMO] Read address
#define TIMERTICK (v_pDriverGlobals->sysclk.dwSystemClock/(1000000*2)) //delay basic num
#define NTSC 1 //set show type
typedef enum OPERA_MODE {
READ = 1,
WRITE = 2
} T_OPERA_MODE;
unsigned char DEMOTable[] = {
0x08,0xC0,0x33,0x00,0x00,0xE9,0x0D,0xB8,0x01,0x80,0x47,0x40,0x00,0x01,0x2A,0x38,
0x0C,0xf7,0x01,0x3E,0x00,0x00,0x02,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x07,
0x80,0x00
};
unsigned char DEMOAddress[] = {
0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,
0x11,0x12,0x13,0x15,0x16,0x17,0x40,0x41,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,
0x4B,0x4C,0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,
0x5B,0x5E
};
// Copyright Mercury's CO.,LTD.2007-2008
// Author : Mercury Xu
// Descript: this file for DEMO chip,it's a dll entry function
// in this file include the DEMO_XXX function for driver the chip
// as a stream device.At the same time,in the bsp package we define
// other function for make suer that this device can reset.use
// centrality define function from gpio.h head file.
//update log
//create by : 2008-03-21 mercury xu
//add by : 2008-04-03 mercury xu add define into the file change old file struct.
//add by : 2008-04-04 mercury xu add some variables for ioctr function
//modify by : 2008-07-30 mercury xu change it for DEMO
/
//=============================================================================
//Title : WrToDEMO
//Detail: Write Data To DEMO
//Input : addr data
//Output: none
//Author: Mercury Xu
//Data : 2008-07-30
//=============================================================================
void WrToDEMO(unsigned char addr,unsigned char data);
//=============================================================================
//Title : initial_DEMO
//Detail: initial DEMO chip
//Input : none
//Output: none
//Author: Mercury Xu
//Data : 2008-07-30
//=============================================================================
void initial_DEMO();
//=============================================================================
//Title : ReceiveAck
//Detail: Receive Ack from DEMO chip
//Input : none
//Output: int
//Author: Mercury Xu
//Data : 2008-07-30
//=============================================================================
int ReceiveAck();
//=============================================================================
//Title : StopBit
//Detail: StopBit from DEMO chip
//Input : none
//Output: none
//Author: Mercury Xu
//Data : 2008-07-30
//=============================================================================
void StopBit();
//=============================================================================
//Title : StartBit
//Detail: StartBit from DEMO chip
//Input : none
//Output: none
//Author: Mercury Xu
//Data : 2008-07-30
//=============================================================================
void StartBit();
//=============================================================================
//Title : WrData
//Detail: WrData to DEMO chip
//Input : none
//Output: none
//Author: Mercury Xu
//Data : 2008-07-30
//=============================================================================
void WrData(unsigned char data);
//=============================================================================
//Title : DEMO_reset
//Detail: DEMO_reset to DEMO chip
//Input : none
//Output: none
//Author: Mercury Xu
//Data : 2008-07-30
//=============================================================================
// void DEMO_reset();
///
//modify by mercury xu Mercury's 20080401
//this segment for define some useful little function.usually use in the program.
//there are including some functions as following words
//sdio_high()
//sdio_low()
//sclk_high()
//sclk_low()
//sdio_output_enable()
//sdio_input_enable()
//sdio_getdata()
///
//update log
//create by mercury xu 20070401
///
void sleepGPIO(long usVal);
///
void sdio_high();
///
void sdio_low();
///
void sclk_high();
///
void sclk_low();
//
void sdio_output_enable();
//
void sdio_input_enable();
//
int sdio_getdata();
//end segment
///
void sdio_reset();
extern "C" unsigned char OperationDEMO(T_OPERA_MODE operation, unsigned char *data, unsigned char numBytes);
/
extern "C" BOOL CALLBACK DllMain(HANDLE hDLL,DWORD dwReason,LPVOID lpvReserved);
//
//------------------------------------------------------------------------------
// @xref <nl>
// <f DEMO_Init>, <nl>
// <f DEMO_Deinit>, <nl>
// <f DEMO_Open>, <nl>
// <f DEMO_Close>, <nl>
// <f DEMO_Read>, <nl>
// <f DEMO_Write>, <nl>
// <f DEMO_Seek>, <nl>
// <f DEMO_PowerUp>, <nl>
// <f DEMO_PowerDown>, <nl>
// <f DEMO_IOControl> <nl>
//
// -----------------------------------------------------------------------------
extern "C" DWORD DEMO_Init(DWORD Index);
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func PVOID | DEMO_Deinit | Device deinitialization routine
//
// @parm DWORD | dwData | value returned from DEMO_Init call
//
// @rdesc Returns TRUE for success, FALSE for failure.
//
// -----------------------------------------------------------------------------
//extern "C" BOOL DEMO_Deinit(DWORD dwData);
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func PVOID | DEMO_Open | Device open routine
//
// @parm DWORD | dwData | Value returned from DEMO_Init call (ignored)
//
// @parm DWORD | dwAccess | Requested access (combination of GENERIC_READ
// and GENERIC_WRITE) (ignored)
//
// @parm DWORD | dwShareMode | Requested share mode (combination of
// FILE_SHARE_READ and FILE_SHARE_WRITE) (ignored)
//
// @rdesc Returns a DWORD which will be passed to Read, Write, etc or NULL if
// unable to open device.
//
// -----------------------------------------------------------------------------
extern "C" PDWORD DEMO_Open( DWORD dwData,
DWORD dwAccess,
DWORD dwShareMode);
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func BOOL | DEMO_Close | Device close routine
//
// @parm DWORD | dwOpenData | Value returned from DEMO_Open call
//
// @rdesc Returns TRUE for success, FALSE for failure
//
// -----------------------------------------------------------------------------
//extern "C" BOOL DEMO_Close(PDWORD pdwData);
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func DWORD | DEMO_Read | Device read routine
//
// @parm DWORD | dwOpenData | Value returned from DEMO_Open call (ignored)
//
// @parm LPVOID | pBuf | Buffer to receive data (ignored)
//
// @parm DWORD | len | Maximum length to read (ignored)
//
// @rdesc Returns 0 always. DEMO_Read should never get called and does
// nothing. Required DEVICE.EXE function, but all data communication
// is handled by <f DEMO_IOControl>.
//
// -----------------------------------------------------------------------------
extern "C" DWORD DEMO_Read(DWORD dwData,
LPVOID pBuf,
DWORD Len);
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func DWORD | DEMO_Write | Device write routine
//
// @parm DWORD | dwOpenData | Value returned from DEMO_Open call (ignored)
//
// @parm LPCVOID | pBuf | Buffer containing data (ignored)
//
// @parm DWORD | len | Maximum length to write (ignored)
//
// @rdesc Returns 0 always. DEMO_Write should never get called and does
// nothing. Required DEVICE.EXE function, but all data communication
// is handled by <f DEMO_IOControl>.
//
// -----------------------------------------------------------------------------
extern "C" DWORD DEMO_Write(DWORD dwData,
LPCVOID pBuf,
DWORD Len);
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func DWORD | DEMO_Seek | Device seek routine
//
// @parm DWORD | dwOpenData | Value returned from DEMO_Open call (ignored)
//
// @parm long | pos | Position to seek to (relative to type) (ignored)
//
// @parm DWORD | type | FILE_BEGIN, FILE_CURRENT, or FILE_END (ignored)
//
// @rdesc Returns -1 always. DEMO_Seek should never get called and does
// nothing. Required DEVICE.EXE function, but all data communication
// is handled by <f DEMO_IOControl>.
//
// -----------------------------------------------------------------------------
extern "C" DWORD DEMO_Seek(DWORD dwData,
long pos,
DWORD type);
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func void | DEMO_PowerUp | Device powerup routine
//
// @comm Called to restore device from suspend mode. Cannot call any
// routines aside from those in the dll in this call.
//
// -----------------------------------------------------------------------------
extern "C" VOID DEMO_PowerUp(VOID);
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func void | DEMO_PowerDown | Device powerdown routine
//
// @comm Called to suspend device. Cannot call any routines aside from
// those in the dll in this call.
//
// -----------------------------------------------------------------------------
//extern "C" VOID DEMO_PowerDown(VOID);
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func BOOL | DEMO_IOControl | Device IO control routine
//
// @parm DWORD | dwOpenData | Value returned from DEMO_Open call
//
// @parm DWORD | dwCode |
// IO control code for the function to be performed. DEMO_IOControl only
// supports one IOCTL value (IOCTL_DEMO_MESSAGE)
//
// @parm PBYTE | pBufIn |
// Pointer to the input parameter structure (<t MMDRV_MESSAGE_PARAMS>).
//
// @parm DWORD | dwLenIn |
// Size in bytes of input parameter structure (sizeof(<t MMDRV_MESSAGE_PARAMS>)).
//
// @parm PBYTE | pBufOut | Pointer to the return value (DWORD).
//
// @parm DWORD | dwLenOut | Size of the return value variable (sizeof(DWORD)).
//
// @parm PDWORD | pdwActualOut | Unused
//
// @rdesc Returns TRUE for success, FALSE for failure
//
// @xref <t DEMOe Input Driver Messages> (WIDM_XXX) <nl>
// <t DEMOe Output Driver Messages> (WODM_XXX)
//
// -----------------------------------------------------------------------------
extern "C" BOOL DEMO_IOControl(PDWORD pdwOpenData,
DWORD dwCode,
PBYTE pBufIn,
DWORD dwLenIn,
PBYTE pBufOut,
DWORD dwLenOut,
PDWORD pdwActualOut);
#endif
以上为头文件部分
// Copyright Mercury's CO.,LTD.2007-2008
// Author : Mercury Xu
// Descript: this file for DEMO chip,it's a dll entry function
// in this file include the DEMO_XXX function for driver the chip
// as a stream device.At the same time,in the bsp package we define
// other function for make suer that this device can reset.use
// centrality define function from gGPIO.h head file.
//update log
//create by : 2008-03-21 mercury xu
//modify : 2008-04-01 mercury xu add little functions segment.as following
//modify : 2008-04-01 mercury xu modify the operation functions.
//add :2008-04-03 mercury xu add some functions and some define
//modify : 2008-07-30 mercury xu change basic drvier to screen driver
/
#include <drvlib.h>
#include <oal_at4x0a.h>
#include <cspregs.h>
#include <nkintr.h>
#include "halio.h"
#include "uhal.h"
#include "drvglob.h"
#include "DEMO.h"
/
//=============================================================================
//Title : WrToDEMO
//Detail: Write Data To DEMO
//Input : addr data
//Output: none
//Author: Mercury Xu
//Data : 2008-07-30
//=============================================================================
void WrToDEMO(unsigned char addr,unsigned char data)
{
StartBit();
RETAILMSG(1,(TEXT("WRITE DEMO address/r/n")));
WrData(DEMO_WriteID);
if ( !ReceiveAck() ) //continue;
{
RETAILMSG(1,(TEXT("WRITE DEMO address/r/n")));
WrData(addr);
}
if ( !ReceiveAck() )// continue;
{
RETAILMSG(1,(TEXT("WRITE DEMO data/r/n")));
WrData(data);
}
if ( !ReceiveAck() )// continue;
{
RETAILMSG(1,(TEXT("Stop!/r/n")));
StopBit();
}
}
//=============================================================================
//Title : initial_DEMO
//Detail: initial DEMO chip
//Input : none
//Output: none
//Author: Mercury Xu
//Data : 2008-07-30
//=============================================================================
void initial_DEMO()
{
int i;
unsigned char address=0x00;
unsigned char error_ind;
unsigned char DEMO_reg_data[98] = {};
unsigned char DEMOdata;
int loop_counter = 0;
//DEMO_reset();
/*
for(i=0; i<50; i++)
{
if(OperationDEMO(WRITE,&DEMOAddress[i] , 1))
RETAILMSG(1,(TEXT("address write ok!/r/n")));
if(OperationDEMO(WRITE,&DEMOTable[i] , 1))
RETAILMSG(1,(TEXT("data write ok!/r/n")));
}
*/
for(i=0; i<50; i++)
{
DEMOdata = DEMOTable[i];
address = DEMOAddress[i];
WrToDEMO(address,DEMOdata);
}
RETAILMSG(1,(TEXT("DEMO_Read!/r/n ")));
do
{
error_ind = OperationDEMO(READ, &(DEMO_reg_data[loop_counter]), 1);
if(error_ind)
{
RETAILMSG(1,(TEXT("power up cts error!/r/n")));
//return (FALSE);
}
RETAILMSG(1,(TEXT("return val =%d/r/n"),DEMO_reg_data[loop_counter]));
loop_counter++;
}
while(((DEMO_reg_data[0]) != 0x80) && (loop_counter < 0x62)); //loop_counter limit should guarantee at least 300us
if(loop_counter >= 0x62)
{
RETAILMSG(1,(TEXT("out...this chip couldn't read any things!!!!/r/n")));
}
else
{
RETAILMSG(1,(TEXT("everything is normal....future is beatuiful...!/r/n ")));
}
}
//=============================================================================
//Title : ReceiveAck
//Detail: Receive Ack from DEMO chip
//Input : none
//Output: int
//Author: Mercury Xu
//Data : 2008-07-30
//=============================================================================
int ReceiveAck()
{
int val;
sdio_input_enable();
sclk_high();
sleepGPIO(100);
val = sdio_getdata();
RETAILMSG(1,(TEXT("return val =%d/r/n"),val));
sclk_low();
sdio_output_enable();
sdio_low();
sleepGPIO(500);
return (val);
}
//=============================================================================
//Title : StopBit
//Detail: StopBit from DEMO chip
//Input : none
//Output: none
//Author: Mercury Xu
//Data : 2008-07-30
//=============================================================================
void StopBit()
{
sdio_high();
sleepGPIO(500);
sclk_high();
}
//=============================================================================
//Title : StartBit
//Detail: StartBit from DEMO chip
//Input : none
//Output: none
//Author: Mercury Xu
//Data : 2008-07-30
//=============================================================================
void StartBit()
{
sdio_low();
sleepGPIO(500);
sclk_low();
}
//=============================================================================
//Title : WrData
//Detail: WrData to DEMO chip
//Input : none
//Output: none
//Author: Mercury Xu
//Data : 2008-07-30
//=============================================================================
void WrData(unsigned char data)
{
int i;
for (i=0; i<8; i++)
{
if (data & 0x80)
sdio_high();
else
sdio_low();
sleepGPIO(500);
sclk_high();
data = (data<<1);
sleepGPIO(500);
sclk_low();
}
// sleepGPIO(5);
}
//
/*
void DEMO_reset()
{
RETAILMSG(1,(TEXT(" DEMO reset begin")));//add by mercury xu Mercury's 20080909
GPIO_OUTPUT_ZERO (GGPIO, GGPIO_GROUP(5), GGPIO_INDEX(17));
GPIO_OUTPUT_ENABLE (GGPIO, GGPIO_GROUP(5), GGPIO_INDEX(17));
sleepGPIO(10);
GPIO_OUTPUT_ONE (GGPIO, GGPIO_GROUP(5), GGPIO_INDEX(17));
GPIO_OUTPUT_ENABLE (GGPIO, GGPIO_GROUP(5), GGPIO_INDEX(17));
RETAILMSG(1,(TEXT(" DEMO reset end")));//add by mercury xu Mercury's 20080909
//DEMO RESET
}
*/
///
//modify by mercury xu Mercury's 20080401
//this segment for define some useful little function.usually use in the program.
//there are including some functions as following words
//sdio_high()
//sdio_low()
//sclk_high()
//sclk_low()
//sdio_output_enable()
//sdio_input_enable()
//sdio_getdata()
///
//update log
//create by mercury xu 20070401
///
void sleepGPIO(long usVal)
{
DWORD StartLo, StartHi, TickCnt;
if (usVal != 0)
{
// Calculate the match tick count first, automatically cut the overflow part of result.
TickCnt = usVal * TIMERTICK;
if (TickCnt == MAXDWORD)
{
DEBUGMSG(1, (TEXT("ERROR: usWait(usVal) input parameter usVal:0x%x too big!!!"), usVal));
return;
}
v_pOSTRegs->ostlatch = 1;
StartLo = v_pOSTRegs->ostlatchlo;
StartHi = v_pOSTRegs->ostlatchhi;
do
{
v_pOSTRegs->ostlatch = 1;
}while ((v_pOSTRegs->ostlatchhi-StartHi)?((DWORD)(MAXDWORD-StartLo + v_pOSTRegs->ostlatchlo) < TickCnt):((DWORD)(v_pOSTRegs->ostlatchlo - StartLo) < TickCnt));
}
//end if
}
///
void sdio_high()
{
GPIO_OUTPUT_ONE ();
GPIO_OUTPUT_ENABLE ();
//modify by mercury for cnd620F 20080730 change the control to i2c
}
///
void sdio_low()
{
GPIO_OUTPUT_ZERO ();
GPIO_OUTPUT_ENABLE ();
//modify by mercury for cnd620F 20080730 change the control to i2c
}
///
void sclk_high()
{
GPIO_OUTPUT_ONE ();
GPIO_OUTPUT_ENABLE ();
//modify by mercury for cnd620F 20080730 change the control to i2c
}
///
void sclk_low()
{
GPIO_OUTPUT_ZERO ();
GPIO_OUTPUT_ENABLE ();
//modify by mercury for cnd620F 20080730 change the control to i2c
}
//
void sdio_output_enable()
{
GPIO_OUTPUT_ENABLE ();
//modify by mercury for cnd620F 20080730 change the control to i2c
}
//
void sdio_input_enable()
{
GPIO_OUTPUT_DISABLE();
GPIO_INT_ENABLE();
//modify by mercury for cnd620F 20080730 change the control to i2c
}
//
int sdio_getdata()
{
GPIO_OUTPUT_DISABLE ();
GPIO_INT_ENABLE();
sleepGPIO(2000);
return (GPIO_READ_INPUT ());
//modify by mercury for cnd620F 20080730 change the control to i2c
}
//end segment
//
// si4730_reset
// this function use to make sure the chip reset when we use it first.
// step like follow descript:
// sdio low->reset low->sclk high->delay->reset high->delay->sdio high->delay
//
//update log
//2008-03-29 add by mercury xu Mercury's for chip si4730 reset
//
void sdio_reset()
{
sdio_low();
GPIO_OUTPUT_ZERO ();
GPIO_OUTPUT_ENABLE ();
//modify by mercury for cnd620F 20080730 change the control to i2c
sclk_high();
sleepGPIO(1000);
GPIO_OUTPUT_ONE ();
GPIO_OUTPUT_ENABLE ();
sleepGPIO(1000);
sdio_high();
sleepGPIO(1000);
}
//end segment
///
/
//modify by mercury xu ,add a function for si4730,this function use to operation this chip
//make sure the chip reset,and then,set a command power it up ,if this function can sent
//command to chip,there will be make out some noises just like radio couldn't get any
//programs,that means this chip can work.all the applcation use in the application .exe
//Mercury's for car v600 2008-03-27
//this segment "as is" silicon lab's function.
//Mercury's co,.ltd.
/
extern "C" unsigned char OperationDEMO(T_OPERA_MODE operation, unsigned char *data, unsigned char numBytes)
{
//define some variables for this function
unsigned char controlword;
unsigned char j;
unsigned error;
int i;
int testNo;
int testNo1;
int returndata;
controlword = 0;
j = 0;
error = 0;
i = 0;
testNo = 0;
testNo1 = 0;
returndata = 0;
//define variable end
//function begin
/***************************************************
START: make sure here SDIO_DIR =OUT, SCLK = 1, SDIO = 1
****************************************************/
sdio_low();
sleepGPIO(500);
sclk_low();
sleepGPIO(500);
RETAILMSG(1,(TEXT("I2C START!/r/n ")));
/***************************************************
WRITE CONTROL DATA: make sure here: SLCK = 0; SDIO = 0
****************************************************/
if(operation == READ)
{
RETAILMSG(1,(TEXT("0x49 READ!/r/n ")));
controlword = 0x4A;
}
else
{
RETAILMSG(1,(TEXT("0x48 WRITE!/r/n ")));
controlword = 0x4B;
}
RETAILMSG(3,(TEXT("Write IIC ADDR: 0x%x/r/n"),controlword));
for(i = 7; i>=0; i--)
{
if((controlword >> i) & 0x01)
sdio_high();
else
sdio_low();
sleepGPIO(500);
sclk_high();
sleepGPIO(500);
sclk_low();
sleepGPIO(500);
}
/***************************
CHECK ACK for control word
***************************/
sdio_input_enable();
sleepGPIO(500);
sclk_high();
sleepGPIO(500);
if(( returndata = sdio_getdata())!= 0)//READ_SDIO
{
error = 1;
RETAILMSG(1,(TEXT("Write add ack error!/r/n ")));
RETAILMSG(3,(TEXT("returndata: %d/r/n"),returndata));
goto STOP;
}
RETAILMSG(1,(TEXT("Write add ack OK!/r/n ")));
sclk_low();
sleepGPIO(500);
/***************************************
WRITE or READ data
****************************************/
if(operation == READ)
RETAILMSG(3,(TEXT("read data show: ")));
else
RETAILMSG(3,(TEXT("write data show: ")));
for(j = 0; j < numBytes; j++, data++)
{
if(operation == WRITE)
sdio_output_enable();
else
sdio_input_enable();
for(i = 7; i>=0; i--)
{
if(operation == WRITE)
if((*data >> i) & 0x01)
sdio_high();
else
sdio_low();
sleepGPIO(50);
sclk_high();
sleepGPIO(50);
if(operation == READ)
*data = ((*data << 1) | (sdio_getdata()));//READ_SDIO
sclk_low();
sleepGPIO(50);
}
if(operation == READ)
RETAILMSG(3,(TEXT(" 0x%x"),*data));
else
RETAILMSG(3,(TEXT(" 0x%x"),*data));
//modify at 20080331
/******************************
CHECK ACK or SEND ACK=0
*******************************/
if(operation == WRITE)
sdio_input_enable();
else
{
sdio_output_enable();
if(j == (numBytes - 1))
sdio_high();
else
sdio_high();
}
sleepGPIO(50);
sclk_high();
sleepGPIO(50);
if(operation == WRITE)
if((sdio_getdata())!= 0)//READ_SDIO
{
RETAILMSG(1,(TEXT(" ACK ERROR,Quit!/r/n")));
error = 1;
goto STOP;
}
RETAILMSG(1,(TEXT(" ACK OK")));
sclk_low();
sleepGPIO(50);
}
/****************************
STOP: make sure here: SCLK = 0
*****************************/
STOP:
sdio_output_enable();
sdio_low();
sleepGPIO(50);
sclk_high();
sleepGPIO(50);
sdio_high();
return(error);
//function end
}
///
//------------------------------------------------------------------------------
// @xref <nl>
// <f DEMO_Init>, <nl>
// <f DEMO_Deinit>, <nl>
// <f DEMO_Open>, <nl>
// <f DEMO_Close>, <nl>
// <f DEMO_Read>, <nl>
// <f DEMO_Write>, <nl>
// <f DEMO_Seek>, <nl>
// <f DEMO_PowerUp>, <nl>
// <f DEMO_PowerDown>, <nl>
// <f DEMO_IOControl> <nl>
//
// -----------------------------------------------------------------------------
/
BOOL CALLBACK DllMain(HANDLE hDLL,
DWORD dwReason,
LPVOID lpvReserved)
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH :
DEBUGREGISTER((HINSTANCE)hDLL);
DisableThreadLibraryCalls((HMODULE) hDLL);
break;
case DLL_PROCESS_DETACH :
break;
case DLL_THREAD_DETACH :
break;
case DLL_THREAD_ATTACH :
break;
default :
break;
}
//end switch
return TRUE;
}
extern "C" DWORD DEMO_Init(DWORD Index)
{
RETAILMSG(1,(TEXT("DEMO_Init!/r/n ")));
//DEMO_reset();
// initial_DEMO();
return TRUE;
}
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func PVOID | DEMO_Deinit | Device deinitialization routine
//
// @parm DWORD | dwData | value returned from DEMO_Init call
//
// @rdesc Returns TRUE for success, FALSE for failure.
//
// -----------------------------------------------------------------------------
extern "C" BOOL DEMO_Deinit(DWORD dwData)
{
RETAILMSG(1,(TEXT("DEMO_DeInit!/r/n ")));
return TRUE;
}
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func PVOID | DEMO_Open | Device open routine
//
// @parm DWORD | dwData | Value returned from DEMO_Init call (ignored)
//
// @parm DWORD | dwAccess | Requested access (combination of GENERIC_READ
// and GENERIC_WRITE) (ignored)
//
// @parm DWORD | dwShareMode | Requested share mode (combination of
// FILE_SHARE_READ and FILE_SHARE_WRITE) (ignored)
//
// @rdesc Returns a DWORD which will be passed to Read, Write, etc or NULL if
// unable to open device.
//
// -----------------------------------------------------------------------------
extern "C" PDWORD DEMO_Open( DWORD dwData,
DWORD dwAccess,
DWORD dwShareMode)
{
RETAILMSG(1,(TEXT("DEMO_OPEN /r/ndwData=%d;AccessCode=%d /r/n"),dwData, dwAccess));
initial_DEMO();
return (PDWORD)TRUE;
//modify by mercury xu Mercury's 2008-04-04
}
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func BOOL | DEMO_Close | Device close routine
//
// @parm DWORD | dwOpenData | Value returned from DEMO_Open call
//
// @rdesc Returns TRUE for success, FALSE for failure
//
// -----------------------------------------------------------------------------
extern "C" BOOL DEMO_Close(PDWORD pdwData)
{
return(FALSE);
}
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func DWORD | DEMO_Read | Device read routine
//
// @parm DWORD | dwOpenData | Value returned from DEMO_Open call (ignored)
//
// @parm LPVOID | pBuf | Buffer to receive data (ignored)
//
// @parm DWORD | len | Maximum length to read (ignored)
//
// @rdesc Returns 0 always. DEMO_Read should never get called and does
// nothing. Required DEVICE.EXE function, but all data communication
// is handled by <f DEMO_IOControl>.
//
// -----------------------------------------------------------------------------
extern "C" DWORD DEMO_Read(DWORD dwData,
LPVOID pBuf,
DWORD Len)
{
return (FALSE);
}
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func DWORD | DEMO_Write | Device write routine
//
// @parm DWORD | dwOpenData | Value returned from DEMO_Open call (ignored)
//
// @parm LPCVOID | pBuf | Buffer containing data (ignored)
//
// @parm DWORD | len | Maximum length to write (ignored)
//
// @rdesc Returns 0 always. DEMO_Write should never get called and does
// nothing. Required DEVICE.EXE function, but all data communication
// is handled by <f DEMO_IOControl>.
//
// -----------------------------------------------------------------------------
extern "C" DWORD DEMO_Write(DWORD dwData,
LPCVOID pBuf,
DWORD Len)
{
unsigned short temp;
temp = *(unsigned short *) pBuf;
RETAILMSG(1,(TEXT("DEMO_write!/r/n ")));
return(TRUE);
}
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func DWORD | DEMO_Seek | Device seek routine
//
// @parm DWORD | dwOpenData | Value returned from DEMO_Open call (ignored)
//
// @parm long | pos | Position to seek to (relative to type) (ignored)
//
// @parm DWORD | type | FILE_BEGIN, FILE_CURRENT, or FILE_END (ignored)
//
// @rdesc Returns -1 always. DEMO_Seek should never get called and does
// nothing. Required DEVICE.EXE function, but all data communication
// is handled by <f DEMO_IOControl>.
//
// -----------------------------------------------------------------------------
extern "C" DWORD DEMO_Seek(DWORD dwData,
long pos,
DWORD type)
{
RETAILMSG(1,(TEXT("DEMO_Seek!/r/n ")));
return(TRUE);
//return((DWORD)DEMO_FM_Tune_DEMO());
}
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func void | DEMO_PowerUp | Device powerup routine
//
// @comm Called to restore device from suspend mode. Cannot call any
// routines aside from those in the dll in this call.
//
// -----------------------------------------------------------------------------
extern "C" VOID DEMO_PowerUp(VOID)
{
//DEMO_reset();
RETAILMSG(1,(TEXT("DEMO_PowerUp!/r/n ")));
// sleepGPIO(800);
}
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func void | DEMO_PowerDown | Device powerdown routine
//
// @comm Called to suspend device. Cannot call any routines aside from
// those in the dll in this call.
//
// -----------------------------------------------------------------------------
extern "C" VOID DEMO_PowerDown(VOID)
{
RETAILMSG(1,(TEXT("DEMO_PowerDown!/r/n ")));
}
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func BOOL | DEMO_IOControl | Device IO control routine
//
// @parm DWORD | dwOpenData | Value returned from DEMO_Open call
//
// @parm DWORD | dwCode |
// IO control code for the function to be performed. DEMO_IOControl only
// supports one IOCTL value (IOCTL_DEMO_MESSAGE)
//
// @parm PBYTE | pBufIn |
// Pointer to the input parameter structure (<t MMDRV_MESSAGE_PARAMS>).
//
// @parm DWORD | dwLenIn |
// Size in bytes of input parameter structure (sizeof(<t MMDRV_MESSAGE_PARAMS>)).
//
// @parm PBYTE | pBufOut | Pointer to the return value (DWORD).
//
// @parm DWORD | dwLenOut | Size of the return value variable (sizeof(DWORD)).
//
// @parm PDWORD | pdwActualOut | Unused
//
// @rdesc Returns TRUE for success, FALSE for failure
//
// @xref <t DEMOe Input Driver Messages> (WIDM_XXX) <nl>
// <t DEMOe Output Driver Messages> (WODM_XXX)
//
// -----------------------------------------------------------------------------
extern "C" BOOL DEMO_IOControl(PDWORD pdwOpenData,
DWORD dwCode,
PBYTE pBufIn,
DWORD dwLenIn,
PBYTE pBufOut,
DWORD dwLenOut,
PDWORD pdwActualOut)
{
RETAILMSG(1,(TEXT("DEMO/r/n pdwOpenData=%d;dwCode=%d/r/n"),pdwOpenData,dwCode));
return(FALSE);
}
以上部分为Cpp部分。
//title:关于I2C控制的一些注意问题
//descrpit:分析I2C总线工作原理和实现方法
//author:Mercury Xu
//date:2008-09-20
/
阅读本文前请先阅读完I2C协议手册,下载地址如下:
http://download.csdn.net/source/315355
最近的开发一直与I2C有关系。以前写过I2C通讯相关东西。但是用的是别人的封装函数。所以没有怎么仔细看。
这次通过开发MTV335这款芯片自己参考了原厂提供的代码写了一个I2C通讯的程序。没有做成类的形式,也是普通的函数调用。应该比较容易理解和使用。具体的操作如下,另外要提得一点是,在做I2C程序之前一定要硬件工程师帮你检查下或者你自己检查下线路是否通畅,上拉电阻是否使用正确,I2C两线的电压是否正常3.3-5V。检查完这些后,尝试送一组值给芯片,看下波型是否正确,如果正确就放心大胆的写东西吧,多话不说了,大家看参考代码吧。其中我使用了一些伪代码来替代一些操作,不同的芯片用不同的方式去替换就好了。
另,参考程序是基于wince5.0下流设备驱动形式编写,请按照各自不同的芯片进行修改。
#ifndef _DEMO_H_
#define _DEMO_H_
#define DELAY_CNT 50 //Delay 50 us
#define DEMO_WriteID 0x4A //[DEMO] Write address
#define DEMO_ReadID 0x4B //[DEMO] Read address
#define TIMERTICK (v_pDriverGlobals->sysclk.dwSystemClock/(1000000*2)) //delay basic num
#define NTSC 1 //set show type
typedef enum OPERA_MODE {
READ = 1,
WRITE = 2
} T_OPERA_MODE;
unsigned char DEMOTable[] = {
0x08,0xC0,0x33,0x00,0x00,0xE9,0x0D,0xB8,0x01,0x80,0x47,0x40,0x00,0x01,0x2A,0x38,
0x0C,0xf7,0x01,0x3E,0x00,0x00,0x02,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x07,
0x80,0x00
};
unsigned char DEMOAddress[] = {
0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,0x10,
0x11,0x12,0x13,0x15,0x16,0x17,0x40,0x41,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4A,
0x4B,0x4C,0x4D,0x4E,0x4F,0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5A,
0x5B,0x5E
};
// Copyright Mercury's CO.,LTD.2007-2008
// Author : Mercury Xu
// Descript: this file for DEMO chip,it's a dll entry function
// in this file include the DEMO_XXX function for driver the chip
// as a stream device.At the same time,in the bsp package we define
// other function for make suer that this device can reset.use
// centrality define function from gpio.h head file.
//update log
//create by : 2008-03-21 mercury xu
//add by : 2008-04-03 mercury xu add define into the file change old file struct.
//add by : 2008-04-04 mercury xu add some variables for ioctr function
//modify by : 2008-07-30 mercury xu change it for DEMO
/
//=============================================================================
//Title : WrToDEMO
//Detail: Write Data To DEMO
//Input : addr data
//Output: none
//Author: Mercury Xu
//Data : 2008-07-30
//=============================================================================
void WrToDEMO(unsigned char addr,unsigned char data);
//=============================================================================
//Title : initial_DEMO
//Detail: initial DEMO chip
//Input : none
//Output: none
//Author: Mercury Xu
//Data : 2008-07-30
//=============================================================================
void initial_DEMO();
//=============================================================================
//Title : ReceiveAck
//Detail: Receive Ack from DEMO chip
//Input : none
//Output: int
//Author: Mercury Xu
//Data : 2008-07-30
//=============================================================================
int ReceiveAck();
//=============================================================================
//Title : StopBit
//Detail: StopBit from DEMO chip
//Input : none
//Output: none
//Author: Mercury Xu
//Data : 2008-07-30
//=============================================================================
void StopBit();
//=============================================================================
//Title : StartBit
//Detail: StartBit from DEMO chip
//Input : none
//Output: none
//Author: Mercury Xu
//Data : 2008-07-30
//=============================================================================
void StartBit();
//=============================================================================
//Title : WrData
//Detail: WrData to DEMO chip
//Input : none
//Output: none
//Author: Mercury Xu
//Data : 2008-07-30
//=============================================================================
void WrData(unsigned char data);
//=============================================================================
//Title : DEMO_reset
//Detail: DEMO_reset to DEMO chip
//Input : none
//Output: none
//Author: Mercury Xu
//Data : 2008-07-30
//=============================================================================
// void DEMO_reset();
///
//modify by mercury xu Mercury's 20080401
//this segment for define some useful little function.usually use in the program.
//there are including some functions as following words
//sdio_high()
//sdio_low()
//sclk_high()
//sclk_low()
//sdio_output_enable()
//sdio_input_enable()
//sdio_getdata()
///
//update log
//create by mercury xu 20070401
///
void sleepGPIO(long usVal);
///
void sdio_high();
///
void sdio_low();
///
void sclk_high();
///
void sclk_low();
//
void sdio_output_enable();
//
void sdio_input_enable();
//
int sdio_getdata();
//end segment
///
void sdio_reset();
extern "C" unsigned char OperationDEMO(T_OPERA_MODE operation, unsigned char *data, unsigned char numBytes);
/
extern "C" BOOL CALLBACK DllMain(HANDLE hDLL,DWORD dwReason,LPVOID lpvReserved);
//
//------------------------------------------------------------------------------
// @xref <nl>
// <f DEMO_Init>, <nl>
// <f DEMO_Deinit>, <nl>
// <f DEMO_Open>, <nl>
// <f DEMO_Close>, <nl>
// <f DEMO_Read>, <nl>
// <f DEMO_Write>, <nl>
// <f DEMO_Seek>, <nl>
// <f DEMO_PowerUp>, <nl>
// <f DEMO_PowerDown>, <nl>
// <f DEMO_IOControl> <nl>
//
// -----------------------------------------------------------------------------
extern "C" DWORD DEMO_Init(DWORD Index);
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func PVOID | DEMO_Deinit | Device deinitialization routine
//
// @parm DWORD | dwData | value returned from DEMO_Init call
//
// @rdesc Returns TRUE for success, FALSE for failure.
//
// -----------------------------------------------------------------------------
//extern "C" BOOL DEMO_Deinit(DWORD dwData);
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func PVOID | DEMO_Open | Device open routine
//
// @parm DWORD | dwData | Value returned from DEMO_Init call (ignored)
//
// @parm DWORD | dwAccess | Requested access (combination of GENERIC_READ
// and GENERIC_WRITE) (ignored)
//
// @parm DWORD | dwShareMode | Requested share mode (combination of
// FILE_SHARE_READ and FILE_SHARE_WRITE) (ignored)
//
// @rdesc Returns a DWORD which will be passed to Read, Write, etc or NULL if
// unable to open device.
//
// -----------------------------------------------------------------------------
extern "C" PDWORD DEMO_Open( DWORD dwData,
DWORD dwAccess,
DWORD dwShareMode);
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func BOOL | DEMO_Close | Device close routine
//
// @parm DWORD | dwOpenData | Value returned from DEMO_Open call
//
// @rdesc Returns TRUE for success, FALSE for failure
//
// -----------------------------------------------------------------------------
//extern "C" BOOL DEMO_Close(PDWORD pdwData);
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func DWORD | DEMO_Read | Device read routine
//
// @parm DWORD | dwOpenData | Value returned from DEMO_Open call (ignored)
//
// @parm LPVOID | pBuf | Buffer to receive data (ignored)
//
// @parm DWORD | len | Maximum length to read (ignored)
//
// @rdesc Returns 0 always. DEMO_Read should never get called and does
// nothing. Required DEVICE.EXE function, but all data communication
// is handled by <f DEMO_IOControl>.
//
// -----------------------------------------------------------------------------
extern "C" DWORD DEMO_Read(DWORD dwData,
LPVOID pBuf,
DWORD Len);
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func DWORD | DEMO_Write | Device write routine
//
// @parm DWORD | dwOpenData | Value returned from DEMO_Open call (ignored)
//
// @parm LPCVOID | pBuf | Buffer containing data (ignored)
//
// @parm DWORD | len | Maximum length to write (ignored)
//
// @rdesc Returns 0 always. DEMO_Write should never get called and does
// nothing. Required DEVICE.EXE function, but all data communication
// is handled by <f DEMO_IOControl>.
//
// -----------------------------------------------------------------------------
extern "C" DWORD DEMO_Write(DWORD dwData,
LPCVOID pBuf,
DWORD Len);
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func DWORD | DEMO_Seek | Device seek routine
//
// @parm DWORD | dwOpenData | Value returned from DEMO_Open call (ignored)
//
// @parm long | pos | Position to seek to (relative to type) (ignored)
//
// @parm DWORD | type | FILE_BEGIN, FILE_CURRENT, or FILE_END (ignored)
//
// @rdesc Returns -1 always. DEMO_Seek should never get called and does
// nothing. Required DEVICE.EXE function, but all data communication
// is handled by <f DEMO_IOControl>.
//
// -----------------------------------------------------------------------------
extern "C" DWORD DEMO_Seek(DWORD dwData,
long pos,
DWORD type);
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func void | DEMO_PowerUp | Device powerup routine
//
// @comm Called to restore device from suspend mode. Cannot call any
// routines aside from those in the dll in this call.
//
// -----------------------------------------------------------------------------
extern "C" VOID DEMO_PowerUp(VOID);
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func void | DEMO_PowerDown | Device powerdown routine
//
// @comm Called to suspend device. Cannot call any routines aside from
// those in the dll in this call.
//
// -----------------------------------------------------------------------------
//extern "C" VOID DEMO_PowerDown(VOID);
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func BOOL | DEMO_IOControl | Device IO control routine
//
// @parm DWORD | dwOpenData | Value returned from DEMO_Open call
//
// @parm DWORD | dwCode |
// IO control code for the function to be performed. DEMO_IOControl only
// supports one IOCTL value (IOCTL_DEMO_MESSAGE)
//
// @parm PBYTE | pBufIn |
// Pointer to the input parameter structure (<t MMDRV_MESSAGE_PARAMS>).
//
// @parm DWORD | dwLenIn |
// Size in bytes of input parameter structure (sizeof(<t MMDRV_MESSAGE_PARAMS>)).
//
// @parm PBYTE | pBufOut | Pointer to the return value (DWORD).
//
// @parm DWORD | dwLenOut | Size of the return value variable (sizeof(DWORD)).
//
// @parm PDWORD | pdwActualOut | Unused
//
// @rdesc Returns TRUE for success, FALSE for failure
//
// @xref <t DEMOe Input Driver Messages> (WIDM_XXX) <nl>
// <t DEMOe Output Driver Messages> (WODM_XXX)
//
// -----------------------------------------------------------------------------
extern "C" BOOL DEMO_IOControl(PDWORD pdwOpenData,
DWORD dwCode,
PBYTE pBufIn,
DWORD dwLenIn,
PBYTE pBufOut,
DWORD dwLenOut,
PDWORD pdwActualOut);
#endif
以上为头文件部分
// Copyright Mercury's CO.,LTD.2007-2008
// Author : Mercury Xu
// Descript: this file for DEMO chip,it's a dll entry function
// in this file include the DEMO_XXX function for driver the chip
// as a stream device.At the same time,in the bsp package we define
// other function for make suer that this device can reset.use
// centrality define function from gGPIO.h head file.
//update log
//create by : 2008-03-21 mercury xu
//modify : 2008-04-01 mercury xu add little functions segment.as following
//modify : 2008-04-01 mercury xu modify the operation functions.
//add :2008-04-03 mercury xu add some functions and some define
//modify : 2008-07-30 mercury xu change basic drvier to screen driver
/
#include <drvlib.h>
#include <oal_at4x0a.h>
#include <cspregs.h>
#include <nkintr.h>
#include "halio.h"
#include "uhal.h"
#include "drvglob.h"
#include "DEMO.h"
/
//=============================================================================
//Title : WrToDEMO
//Detail: Write Data To DEMO
//Input : addr data
//Output: none
//Author: Mercury Xu
//Data : 2008-07-30
//=============================================================================
void WrToDEMO(unsigned char addr,unsigned char data)
{
StartBit();
RETAILMSG(1,(TEXT("WRITE DEMO address/r/n")));
WrData(DEMO_WriteID);
if ( !ReceiveAck() ) //continue;
{
RETAILMSG(1,(TEXT("WRITE DEMO address/r/n")));
WrData(addr);
}
if ( !ReceiveAck() )// continue;
{
RETAILMSG(1,(TEXT("WRITE DEMO data/r/n")));
WrData(data);
}
if ( !ReceiveAck() )// continue;
{
RETAILMSG(1,(TEXT("Stop!/r/n")));
StopBit();
}
}
//=============================================================================
//Title : initial_DEMO
//Detail: initial DEMO chip
//Input : none
//Output: none
//Author: Mercury Xu
//Data : 2008-07-30
//=============================================================================
void initial_DEMO()
{
int i;
unsigned char address=0x00;
unsigned char error_ind;
unsigned char DEMO_reg_data[98] = {};
unsigned char DEMOdata;
int loop_counter = 0;
//DEMO_reset();
/*
for(i=0; i<50; i++)
{
if(OperationDEMO(WRITE,&DEMOAddress[i] , 1))
RETAILMSG(1,(TEXT("address write ok!/r/n")));
if(OperationDEMO(WRITE,&DEMOTable[i] , 1))
RETAILMSG(1,(TEXT("data write ok!/r/n")));
}
*/
for(i=0; i<50; i++)
{
DEMOdata = DEMOTable[i];
address = DEMOAddress[i];
WrToDEMO(address,DEMOdata);
}
RETAILMSG(1,(TEXT("DEMO_Read!/r/n ")));
do
{
error_ind = OperationDEMO(READ, &(DEMO_reg_data[loop_counter]), 1);
if(error_ind)
{
RETAILMSG(1,(TEXT("power up cts error!/r/n")));
//return (FALSE);
}
RETAILMSG(1,(TEXT("return val =%d/r/n"),DEMO_reg_data[loop_counter]));
loop_counter++;
}
while(((DEMO_reg_data[0]) != 0x80) && (loop_counter < 0x62)); //loop_counter limit should guarantee at least 300us
if(loop_counter >= 0x62)
{
RETAILMSG(1,(TEXT("out...this chip couldn't read any things!!!!/r/n")));
}
else
{
RETAILMSG(1,(TEXT("everything is normal....future is beatuiful...!/r/n ")));
}
}
//=============================================================================
//Title : ReceiveAck
//Detail: Receive Ack from DEMO chip
//Input : none
//Output: int
//Author: Mercury Xu
//Data : 2008-07-30
//=============================================================================
int ReceiveAck()
{
int val;
sdio_input_enable();
sclk_high();
sleepGPIO(100);
val = sdio_getdata();
RETAILMSG(1,(TEXT("return val =%d/r/n"),val));
sclk_low();
sdio_output_enable();
sdio_low();
sleepGPIO(500);
return (val);
}
//=============================================================================
//Title : StopBit
//Detail: StopBit from DEMO chip
//Input : none
//Output: none
//Author: Mercury Xu
//Data : 2008-07-30
//=============================================================================
void StopBit()
{
sdio_high();
sleepGPIO(500);
sclk_high();
}
//=============================================================================
//Title : StartBit
//Detail: StartBit from DEMO chip
//Input : none
//Output: none
//Author: Mercury Xu
//Data : 2008-07-30
//=============================================================================
void StartBit()
{
sdio_low();
sleepGPIO(500);
sclk_low();
}
//=============================================================================
//Title : WrData
//Detail: WrData to DEMO chip
//Input : none
//Output: none
//Author: Mercury Xu
//Data : 2008-07-30
//=============================================================================
void WrData(unsigned char data)
{
int i;
for (i=0; i<8; i++)
{
if (data & 0x80)
sdio_high();
else
sdio_low();
sleepGPIO(500);
sclk_high();
data = (data<<1);
sleepGPIO(500);
sclk_low();
}
// sleepGPIO(5);
}
//
/*
void DEMO_reset()
{
RETAILMSG(1,(TEXT(" DEMO reset begin")));//add by mercury xu Mercury's 20080909
GPIO_OUTPUT_ZERO (GGPIO, GGPIO_GROUP(5), GGPIO_INDEX(17));
GPIO_OUTPUT_ENABLE (GGPIO, GGPIO_GROUP(5), GGPIO_INDEX(17));
sleepGPIO(10);
GPIO_OUTPUT_ONE (GGPIO, GGPIO_GROUP(5), GGPIO_INDEX(17));
GPIO_OUTPUT_ENABLE (GGPIO, GGPIO_GROUP(5), GGPIO_INDEX(17));
RETAILMSG(1,(TEXT(" DEMO reset end")));//add by mercury xu Mercury's 20080909
//DEMO RESET
}
*/
///
//modify by mercury xu Mercury's 20080401
//this segment for define some useful little function.usually use in the program.
//there are including some functions as following words
//sdio_high()
//sdio_low()
//sclk_high()
//sclk_low()
//sdio_output_enable()
//sdio_input_enable()
//sdio_getdata()
///
//update log
//create by mercury xu 20070401
///
void sleepGPIO(long usVal)
{
DWORD StartLo, StartHi, TickCnt;
if (usVal != 0)
{
// Calculate the match tick count first, automatically cut the overflow part of result.
TickCnt = usVal * TIMERTICK;
if (TickCnt == MAXDWORD)
{
DEBUGMSG(1, (TEXT("ERROR: usWait(usVal) input parameter usVal:0x%x too big!!!"), usVal));
return;
}
v_pOSTRegs->ostlatch = 1;
StartLo = v_pOSTRegs->ostlatchlo;
StartHi = v_pOSTRegs->ostlatchhi;
do
{
v_pOSTRegs->ostlatch = 1;
}while ((v_pOSTRegs->ostlatchhi-StartHi)?((DWORD)(MAXDWORD-StartLo + v_pOSTRegs->ostlatchlo) < TickCnt):((DWORD)(v_pOSTRegs->ostlatchlo - StartLo) < TickCnt));
}
//end if
}
///
void sdio_high()
{
GPIO_OUTPUT_ONE ();
GPIO_OUTPUT_ENABLE ();
//modify by mercury for cnd620F 20080730 change the control to i2c
}
///
void sdio_low()
{
GPIO_OUTPUT_ZERO ();
GPIO_OUTPUT_ENABLE ();
//modify by mercury for cnd620F 20080730 change the control to i2c
}
///
void sclk_high()
{
GPIO_OUTPUT_ONE ();
GPIO_OUTPUT_ENABLE ();
//modify by mercury for cnd620F 20080730 change the control to i2c
}
///
void sclk_low()
{
GPIO_OUTPUT_ZERO ();
GPIO_OUTPUT_ENABLE ();
//modify by mercury for cnd620F 20080730 change the control to i2c
}
//
void sdio_output_enable()
{
GPIO_OUTPUT_ENABLE ();
//modify by mercury for cnd620F 20080730 change the control to i2c
}
//
void sdio_input_enable()
{
GPIO_OUTPUT_DISABLE();
GPIO_INT_ENABLE();
//modify by mercury for cnd620F 20080730 change the control to i2c
}
//
int sdio_getdata()
{
GPIO_OUTPUT_DISABLE ();
GPIO_INT_ENABLE();
sleepGPIO(2000);
return (GPIO_READ_INPUT ());
//modify by mercury for cnd620F 20080730 change the control to i2c
}
//end segment
//
// si4730_reset
// this function use to make sure the chip reset when we use it first.
// step like follow descript:
// sdio low->reset low->sclk high->delay->reset high->delay->sdio high->delay
//
//update log
//2008-03-29 add by mercury xu Mercury's for chip si4730 reset
//
void sdio_reset()
{
sdio_low();
GPIO_OUTPUT_ZERO ();
GPIO_OUTPUT_ENABLE ();
//modify by mercury for cnd620F 20080730 change the control to i2c
sclk_high();
sleepGPIO(1000);
GPIO_OUTPUT_ONE ();
GPIO_OUTPUT_ENABLE ();
sleepGPIO(1000);
sdio_high();
sleepGPIO(1000);
}
//end segment
///
/
//modify by mercury xu ,add a function for si4730,this function use to operation this chip
//make sure the chip reset,and then,set a command power it up ,if this function can sent
//command to chip,there will be make out some noises just like radio couldn't get any
//programs,that means this chip can work.all the applcation use in the application .exe
//Mercury's for car v600 2008-03-27
//this segment "as is" silicon lab's function.
//Mercury's co,.ltd.
/
extern "C" unsigned char OperationDEMO(T_OPERA_MODE operation, unsigned char *data, unsigned char numBytes)
{
//define some variables for this function
unsigned char controlword;
unsigned char j;
unsigned error;
int i;
int testNo;
int testNo1;
int returndata;
controlword = 0;
j = 0;
error = 0;
i = 0;
testNo = 0;
testNo1 = 0;
returndata = 0;
//define variable end
//function begin
/***************************************************
START: make sure here SDIO_DIR =OUT, SCLK = 1, SDIO = 1
****************************************************/
sdio_low();
sleepGPIO(500);
sclk_low();
sleepGPIO(500);
RETAILMSG(1,(TEXT("I2C START!/r/n ")));
/***************************************************
WRITE CONTROL DATA: make sure here: SLCK = 0; SDIO = 0
****************************************************/
if(operation == READ)
{
RETAILMSG(1,(TEXT("0x49 READ!/r/n ")));
controlword = 0x4A;
}
else
{
RETAILMSG(1,(TEXT("0x48 WRITE!/r/n ")));
controlword = 0x4B;
}
RETAILMSG(3,(TEXT("Write IIC ADDR: 0x%x/r/n"),controlword));
for(i = 7; i>=0; i--)
{
if((controlword >> i) & 0x01)
sdio_high();
else
sdio_low();
sleepGPIO(500);
sclk_high();
sleepGPIO(500);
sclk_low();
sleepGPIO(500);
}
/***************************
CHECK ACK for control word
***************************/
sdio_input_enable();
sleepGPIO(500);
sclk_high();
sleepGPIO(500);
if(( returndata = sdio_getdata())!= 0)//READ_SDIO
{
error = 1;
RETAILMSG(1,(TEXT("Write add ack error!/r/n ")));
RETAILMSG(3,(TEXT("returndata: %d/r/n"),returndata));
goto STOP;
}
RETAILMSG(1,(TEXT("Write add ack OK!/r/n ")));
sclk_low();
sleepGPIO(500);
/***************************************
WRITE or READ data
****************************************/
if(operation == READ)
RETAILMSG(3,(TEXT("read data show: ")));
else
RETAILMSG(3,(TEXT("write data show: ")));
for(j = 0; j < numBytes; j++, data++)
{
if(operation == WRITE)
sdio_output_enable();
else
sdio_input_enable();
for(i = 7; i>=0; i--)
{
if(operation == WRITE)
if((*data >> i) & 0x01)
sdio_high();
else
sdio_low();
sleepGPIO(50);
sclk_high();
sleepGPIO(50);
if(operation == READ)
*data = ((*data << 1) | (sdio_getdata()));//READ_SDIO
sclk_low();
sleepGPIO(50);
}
if(operation == READ)
RETAILMSG(3,(TEXT(" 0x%x"),*data));
else
RETAILMSG(3,(TEXT(" 0x%x"),*data));
//modify at 20080331
/******************************
CHECK ACK or SEND ACK=0
*******************************/
if(operation == WRITE)
sdio_input_enable();
else
{
sdio_output_enable();
if(j == (numBytes - 1))
sdio_high();
else
sdio_high();
}
sleepGPIO(50);
sclk_high();
sleepGPIO(50);
if(operation == WRITE)
if((sdio_getdata())!= 0)//READ_SDIO
{
RETAILMSG(1,(TEXT(" ACK ERROR,Quit!/r/n")));
error = 1;
goto STOP;
}
RETAILMSG(1,(TEXT(" ACK OK")));
sclk_low();
sleepGPIO(50);
}
/****************************
STOP: make sure here: SCLK = 0
*****************************/
STOP:
sdio_output_enable();
sdio_low();
sleepGPIO(50);
sclk_high();
sleepGPIO(50);
sdio_high();
return(error);
//function end
}
///
//------------------------------------------------------------------------------
// @xref <nl>
// <f DEMO_Init>, <nl>
// <f DEMO_Deinit>, <nl>
// <f DEMO_Open>, <nl>
// <f DEMO_Close>, <nl>
// <f DEMO_Read>, <nl>
// <f DEMO_Write>, <nl>
// <f DEMO_Seek>, <nl>
// <f DEMO_PowerUp>, <nl>
// <f DEMO_PowerDown>, <nl>
// <f DEMO_IOControl> <nl>
//
// -----------------------------------------------------------------------------
/
BOOL CALLBACK DllMain(HANDLE hDLL,
DWORD dwReason,
LPVOID lpvReserved)
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH :
DEBUGREGISTER((HINSTANCE)hDLL);
DisableThreadLibraryCalls((HMODULE) hDLL);
break;
case DLL_PROCESS_DETACH :
break;
case DLL_THREAD_DETACH :
break;
case DLL_THREAD_ATTACH :
break;
default :
break;
}
//end switch
return TRUE;
}
extern "C" DWORD DEMO_Init(DWORD Index)
{
RETAILMSG(1,(TEXT("DEMO_Init!/r/n ")));
//DEMO_reset();
// initial_DEMO();
return TRUE;
}
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func PVOID | DEMO_Deinit | Device deinitialization routine
//
// @parm DWORD | dwData | value returned from DEMO_Init call
//
// @rdesc Returns TRUE for success, FALSE for failure.
//
// -----------------------------------------------------------------------------
extern "C" BOOL DEMO_Deinit(DWORD dwData)
{
RETAILMSG(1,(TEXT("DEMO_DeInit!/r/n ")));
return TRUE;
}
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func PVOID | DEMO_Open | Device open routine
//
// @parm DWORD | dwData | Value returned from DEMO_Init call (ignored)
//
// @parm DWORD | dwAccess | Requested access (combination of GENERIC_READ
// and GENERIC_WRITE) (ignored)
//
// @parm DWORD | dwShareMode | Requested share mode (combination of
// FILE_SHARE_READ and FILE_SHARE_WRITE) (ignored)
//
// @rdesc Returns a DWORD which will be passed to Read, Write, etc or NULL if
// unable to open device.
//
// -----------------------------------------------------------------------------
extern "C" PDWORD DEMO_Open( DWORD dwData,
DWORD dwAccess,
DWORD dwShareMode)
{
RETAILMSG(1,(TEXT("DEMO_OPEN /r/ndwData=%d;AccessCode=%d /r/n"),dwData, dwAccess));
initial_DEMO();
return (PDWORD)TRUE;
//modify by mercury xu Mercury's 2008-04-04
}
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func BOOL | DEMO_Close | Device close routine
//
// @parm DWORD | dwOpenData | Value returned from DEMO_Open call
//
// @rdesc Returns TRUE for success, FALSE for failure
//
// -----------------------------------------------------------------------------
extern "C" BOOL DEMO_Close(PDWORD pdwData)
{
return(FALSE);
}
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func DWORD | DEMO_Read | Device read routine
//
// @parm DWORD | dwOpenData | Value returned from DEMO_Open call (ignored)
//
// @parm LPVOID | pBuf | Buffer to receive data (ignored)
//
// @parm DWORD | len | Maximum length to read (ignored)
//
// @rdesc Returns 0 always. DEMO_Read should never get called and does
// nothing. Required DEVICE.EXE function, but all data communication
// is handled by <f DEMO_IOControl>.
//
// -----------------------------------------------------------------------------
extern "C" DWORD DEMO_Read(DWORD dwData,
LPVOID pBuf,
DWORD Len)
{
return (FALSE);
}
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func DWORD | DEMO_Write | Device write routine
//
// @parm DWORD | dwOpenData | Value returned from DEMO_Open call (ignored)
//
// @parm LPCVOID | pBuf | Buffer containing data (ignored)
//
// @parm DWORD | len | Maximum length to write (ignored)
//
// @rdesc Returns 0 always. DEMO_Write should never get called and does
// nothing. Required DEVICE.EXE function, but all data communication
// is handled by <f DEMO_IOControl>.
//
// -----------------------------------------------------------------------------
extern "C" DWORD DEMO_Write(DWORD dwData,
LPCVOID pBuf,
DWORD Len)
{
unsigned short temp;
temp = *(unsigned short *) pBuf;
RETAILMSG(1,(TEXT("DEMO_write!/r/n ")));
return(TRUE);
}
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func DWORD | DEMO_Seek | Device seek routine
//
// @parm DWORD | dwOpenData | Value returned from DEMO_Open call (ignored)
//
// @parm long | pos | Position to seek to (relative to type) (ignored)
//
// @parm DWORD | type | FILE_BEGIN, FILE_CURRENT, or FILE_END (ignored)
//
// @rdesc Returns -1 always. DEMO_Seek should never get called and does
// nothing. Required DEVICE.EXE function, but all data communication
// is handled by <f DEMO_IOControl>.
//
// -----------------------------------------------------------------------------
extern "C" DWORD DEMO_Seek(DWORD dwData,
long pos,
DWORD type)
{
RETAILMSG(1,(TEXT("DEMO_Seek!/r/n ")));
return(TRUE);
//return((DWORD)DEMO_FM_Tune_DEMO());
}
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func void | DEMO_PowerUp | Device powerup routine
//
// @comm Called to restore device from suspend mode. Cannot call any
// routines aside from those in the dll in this call.
//
// -----------------------------------------------------------------------------
extern "C" VOID DEMO_PowerUp(VOID)
{
//DEMO_reset();
RETAILMSG(1,(TEXT("DEMO_PowerUp!/r/n ")));
// sleepGPIO(800);
}
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func void | DEMO_PowerDown | Device powerdown routine
//
// @comm Called to suspend device. Cannot call any routines aside from
// those in the dll in this call.
//
// -----------------------------------------------------------------------------
extern "C" VOID DEMO_PowerDown(VOID)
{
RETAILMSG(1,(TEXT("DEMO_PowerDown!/r/n ")));
}
// -----------------------------------------------------------------------------
//
// @doc WDEV_EXT
//
// @func BOOL | DEMO_IOControl | Device IO control routine
//
// @parm DWORD | dwOpenData | Value returned from DEMO_Open call
//
// @parm DWORD | dwCode |
// IO control code for the function to be performed. DEMO_IOControl only
// supports one IOCTL value (IOCTL_DEMO_MESSAGE)
//
// @parm PBYTE | pBufIn |
// Pointer to the input parameter structure (<t MMDRV_MESSAGE_PARAMS>).
//
// @parm DWORD | dwLenIn |
// Size in bytes of input parameter structure (sizeof(<t MMDRV_MESSAGE_PARAMS>)).
//
// @parm PBYTE | pBufOut | Pointer to the return value (DWORD).
//
// @parm DWORD | dwLenOut | Size of the return value variable (sizeof(DWORD)).
//
// @parm PDWORD | pdwActualOut | Unused
//
// @rdesc Returns TRUE for success, FALSE for failure
//
// @xref <t DEMOe Input Driver Messages> (WIDM_XXX) <nl>
// <t DEMOe Output Driver Messages> (WODM_XXX)
//
// -----------------------------------------------------------------------------
extern "C" BOOL DEMO_IOControl(PDWORD pdwOpenData,
DWORD dwCode,
PBYTE pBufIn,
DWORD dwLenIn,
PBYTE pBufOut,
DWORD dwLenOut,
PDWORD pdwActualOut)
{
RETAILMSG(1,(TEXT("DEMO/r/n pdwOpenData=%d;dwCode=%d/r/n"),pdwOpenData,dwCode));
return(FALSE);
}
以上部分为Cpp部分。