⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c_func.c

📁 sigmatel 软件模拟i2c驱动,此源码是配合touch pad使用案例.enjoy
💻 C
📖 第 1 页 / 共 2 页
字号:
///////////////////////////////////////////////////////////////////////////////////////////
/////////////////eric.wu with steve
///////////////////////////////////////////////////////////////////////////////////////////


#include <types.h>
#include <os\tx_api.h>
#include <string.h>
#include "components\ui_messages.h"
#include <registers\regspinctrl.h>
#include <registers\regsdigctl.h>
#include <drivers\ddi_icoll.h>
#include <registers\hw_irq.h>
#include <registers\regspinctrl.h>
#include <registers\regslradc.h>
#include <hw\hw_uartapp.h>
#include "btn_translation.h"
//#include "UARTKey.h"
#include <drivers\ddi_gpio.h> 
#include "i2c_func.h"
#define I2CKey_SDO      UARTAP_RX//SSP_DATA3   //UARTAP_RX
#define I2CKey_SCK      UARTAP_TX//SSP_DATA0   //UARTAP_TX
#define I2CKey_INT      SSP_CMD
#define I2CKey_RST      SSP_SCK

#define sda_pin	I2CKey_SDO
#define scl_pin	I2CKey_SCK


extern TX_QUEUE *g_ptx_queue_ui;

unsigned char LastButtonValue = 0;
unsigned int ui_KeyHoldCnt = 0;
unsigned char FirKeySliderValue = 0, SecKeySliderValue = 0, ThirdKeySliderValue = 0;

bool g_bIOHadInit = FALSE;


#define I2C_INTERRUPT_MODE(x)	hw_gpio_SetMode(x,3);\
									hw_gpio_SetIrqEnable(x, FALSE);\
									hw_gpio_SetOutputEnable(x,FALSE);\
									hw_gpio_SetInterruptLevel(x, TRUE);\
									hw_gpio_SetInterruptPolarity(x, TRUE);\
									hw_gpio_ClrIRQstat(x);\
									hw_gpio_SetInterruptSelect(x, TRUE);\
									hw_gpio_SetIrqEnable(x, TRUE);




struct clock_timing {
    uint32_t low_count;
    uint32_t high_count;

    uint32_t rcv_count;
    uint32_t xmit_count;

    uint32_t lead_in_count;
};

BOOL g_bUpdataFlag=FALSE;
extern void I2c_Read_key(void);
const static struct clock_timing ClockTiming[2] = {
    { 3, 3, 2, 2, 5 },  // 100KHz
    { 0, 0, 0, 0, 0 }   // 400KHz
};

static void delay(uint32_t us)
{
    /*uint32_t t = hw_digctl_GetCurrentTime();

    while (!hw_digctl_CheckTimeOut(t, us));*/
    uint32_t delay = HW_DIGCTL_MICROSECONDS.U + us;
    
    while(HW_DIGCTL_MICROSECONDS.U < delay);
}
BOOL i2c_set_clck_high_and_check_clk_holding(hw_gpio_Pin_t gpio_pin)
{
	uint32_t timeout = 5000/20;
	hw_gpio_SetOutputEnable(gpio_pin, false);
#if 1	
	//----------------ClockStretching--------------------
	//here should deal with the clock hold set by i2C slave
     // while((hw_gpio_ReadBit(gpio_pin) == 0) && (timeout))
      while((hw_gpio_ReadBit(gpio_pin) == 0))
	{
		delay(20);
		if (timeout)
			timeout --;
		else
			return FALSE;
	}
	  return TRUE;
	//the slave had release the clock
	//------------------ClockStretching------------------
#endif	
}
static bool ReadACK(const struct clock_timing* timing)
{
    uint8_t bit;

    hw_gpio_SetOutputEnable(sda_pin, false);

    delay(timing->low_count + timing->xmit_count);
//kentest_touchkey    hw_gpio_SetOutputEnable(scl_pin, false);  //kentest_touchkey
     i2c_set_clck_high_and_check_clk_holding(scl_pin);

    delay(timing->rcv_count);

    bit = hw_gpio_ReadBit(sda_pin);

    delay(timing->high_count);

    /* Drive the clock line low so that we retain ownership of the i2c bus. */
    hw_gpio_SetOutputEnable(scl_pin, true);

    /* Some devices seem to require the SDA to be low on entry into the
     * next byte.
     */
    hw_gpio_SetOutputEnable(sda_pin, true);

    return (bit == 0);
}//ReadACK

static void SendStart(const struct clock_timing* timing)
{
    hw_gpio_SetOutputEnable(sda_pin, true);
    delay(timing->lead_in_count);
    hw_gpio_SetOutputEnable(scl_pin, true);
}//SendStart

static void SendStop(const struct clock_timing* timing)
{
    delay(timing->low_count + timing->xmit_count);

    hw_gpio_SetOutputEnable(scl_pin, false);
    delay(timing->lead_in_count);
    hw_gpio_SetOutputEnable(sda_pin, false);
}//SendStop


static RtStatus_t SendByte(const struct clock_timing* timing, uint8_t byte)
{
    uint32_t mask = 0x80;

    for (mask = 0x80; mask != 0; mask >>= 1) {
	delay(timing->xmit_count);

	if (byte & mask) hw_gpio_SetOutputEnable(sda_pin, false);
	else hw_gpio_SetOutputEnable(sda_pin, true);

	delay(timing->low_count);
//kentest_touchkey	hw_gpio_SetOutputEnable(scl_pin, false);
	i2c_set_clck_high_and_check_clk_holding(scl_pin);   //kentest_touchkey

	delay(timing->high_count + timing->rcv_count);
	hw_gpio_SetOutputEnable(scl_pin, true);
    }//for

    return (ReadACK(timing) == true) ? SUCCESS : ERROR_DDI_I2C_NO_SLAVE_ACK;
}//SendByte

static uint8_t ReadByte(const struct clock_timing* timing, bool send_ack)
{
    int i;
    uint8_t byte = 0;

    hw_gpio_SetOutputEnable(sda_pin, false);

    for (i = 7; i >= 0; i--) {
	delay(timing->xmit_count + timing->low_count);
//kentest_touchkey	hw_gpio_SetOutputEnable(scl_pin, false);
	i2c_set_clck_high_and_check_clk_holding(scl_pin);   //kentest_touchkey	

	delay(timing->rcv_count);

	byte |= hw_gpio_ReadBit(sda_pin) << i;

	delay(timing->high_count);	
	hw_gpio_SetOutputEnable(scl_pin, true);	
    }//for

    /* We have read 8-bits so now perform the ACK/NAK.  */
    delay(timing->xmit_count);

    hw_gpio_SetOutputEnable(sda_pin, send_ack);

    delay(timing->low_count);

//kentest_touchkey	 hw_gpio_SetOutputEnable(scl_pin, false);
	i2c_set_clck_high_and_check_clk_holding(scl_pin); //kentest_touchkey 

    delay(timing->high_count + timing->rcv_count);
    hw_gpio_SetOutputEnable(scl_pin, true);

    hw_gpio_SetOutputEnable(sda_pin, false);

    return byte;
}//ReadByte

RtStatus_t ddi_i2c_bitbang_write(uint32_t eFrequency,
				 uint8_t u8SlaveAddress,
				 const void* pData,
				 uint16_t u16Size,
				 bool bStop,
				 void* private_data)
{
    const uint8_t* transfer_data = pData;
    const struct clock_timing* timing = &ClockTiming[eFrequency];
	int timeout=250;
    RtStatus_t ret;

    hw_gpio_SetOutputEnable(scl_pin, false);
    hw_gpio_SetOutputEnable(sda_pin, false);

    hw_gpio_ClrBit(scl_pin);
    hw_gpio_ClrBit(sda_pin);

    SendStart(timing);

	
    ret =ERROR1;
    while (ret != SUCCESS)
    	{
    	ret = SendByte(timing, u8SlaveAddress);
	if (timeout)
		timeout--;
	else
		break;
    	}
//    if (ret != SUCCESS) {
//	SendStop(timing);
//
//	return ret;
//    }//if

    while (u16Size--) {
	ret = SendByte(timing, *transfer_data++);
	if (ret != SUCCESS) {
	    SendStop(timing);

	    return ret;
	}//if
    }//while

    if (bStop) SendStop(timing);

    return SUCCESS;
}//ddi_i2c_bitbang_write

RtStatus_t ddi_i2c_bitbang_read(uint32_t eFrequency,
				uint8_t u8SlaveAddress,
				void* pData,
				uint16_t u16Size,
				void* private_data)
{
    uint8_t* transfer_data = pData;
    const struct clock_timing* timing = &ClockTiming[eFrequency];

    RtStatus_t ret;

    hw_gpio_SetOutputEnable(scl_pin, false);
    hw_gpio_SetOutputEnable(sda_pin, false);

    hw_gpio_ClrBit(scl_pin);
    hw_gpio_ClrBit(sda_pin);

    SendStart(timing);

    ret = SendByte(timing, u8SlaveAddress /*| 0x01*/);
    if (ret != SUCCESS) {
	SendStop(timing);

	return ret;
    }//if

    while (u16Size--) {
	/* The last byte in the transfer must NAK the byte.  This tells
	 * the slave device that the transfer is finished.
	 */
	*transfer_data++ = ReadByte(timing, (u16Size != 0));
    }//while

    //hw_gpio_SetOutputEnable(sda_pin, false);

    SendStop(timing);

    return SUCCESS;
}//ddi_i2c_bitbang_read


extern BOOL UI_Init_Complete;
//extern BOOL g_bUpdataFlag;
void ddi_I2c_Read_Handler(void* pData)
{
	//I2c_Key_MsgDeal();
	if ((UI_Init_Complete) &&(!g_bUpdataFlag))
	{
#if 1
		I2c_Read_key();
#else
		os_msg_struct_t RotMsg;
		BUILD_NONALLOCATED_MSG(&RotMsg, OS_MSG_UI_GROUP, MSG_UI_BTN_EVENT,BTN_EVENT_IS(BTN_FF,EVENT_CLICK));
	       tx_queue_send(g_ptx_queue_ui, &RotMsg, TX_NO_WAIT); 
#endif
	}
	hw_gpio_ClrIRQstat(I2CKey_INT);
	hw_icoll_EnableVector((ICOLL_IRQ_enums_t)(VECTOR_IRQ_GPIO0), TRUE);
}

void Init_I2c_Interrupt(void)
{
	I2C_INTERRUPT_MODE(I2CKey_INT);
	ddi_icoll_RegisterIrqHandler(VECTOR_IRQ_GPIO0,
		&ddi_I2c_Read_Handler,
		(void*) NULL,
		IRQ_HANDLER_DEFERRED,
		ICOLL_PRIORITY_LEVEL_0/*ICOLL_PRIORITY_LEVEL_0*/);
	hw_icoll_EnableVector((ICOLL_IRQ_enums_t)(VECTOR_IRQ_GPIO0), TRUE);
}
#if 0
void POSC_XREST()

{

    // XRES pin : 

    // Active high pin reset with internal pull down

    // Reset time = 8 Sleep Clock Cycles ( 200us )

         XRES_PORT |=  XRES_PIN;  

           delay100us();

           delay100us();

           delay100us();

           XRES_PORT &=  ~XRES_PIN;                                                                

}
#endif
void ShutdownTouchKeyIO(void)
{
	ddi_gpio_PinMask_t  GpioMask;
	memset(&GpioMask, 0, sizeof(ddi_gpio_PinMask_t));
	ddi_gpio_SetMask(I2CKey_SDO, &GpioMask);
	ddi_gpio_SetMask(I2CKey_SCK, &GpioMask);

	hw_gpio_SetIrqEnable(I2CKey_INT, FALSE);
	hw_icoll_EnableVector((ICOLL_IRQ_enums_t)(VECTOR_IRQ_GPIO0), FALSE);
	ddi_gpio_SetMask(I2CKey_INT, &GpioMask);
}
void power_down_reinit_Int(void)
{
    ddi_gpio_Cfg_t cfg;
    RtStatus_t RetCode = SUCCESS;
    
    cfg.pin_drive = GPIO_8MA;
    cfg.pin_IO = GPIO_OUTPUT; 
    cfg.pin_irq_capable = GPIO_IRQ_INCAPABLE;
    cfg.pin_irq_enable = GPIO_IRQ_DISABLED;
    cfg.pin_irq_level = GPIO_IRQ_EDGE;
    cfg.pin_irq_polarity = GPIO_IRQ_POLARITY_LO; 
    cfg.pin_mux = GPIO_MODE3;
    hw_icoll_EnableVector((ICOLL_IRQ_enums_t)(VECTOR_IRQ_GPIO0), FALSE);
    RetCode = ddi_gpio_Config((hw_gpio_Pin_t)I2CKey_INT,cfg);
    if(SUCCESS != RetCode)
        SystemHalt();
}
void power_down_SetHi_Int(void)
{
	hw_gpio_SetBit((hw_gpio_Pin_t)I2CKey_INT);
}
void power_down_SetLo_Int(void)
{
	hw_gpio_ClrBit((hw_gpio_Pin_t)I2CKey_INT);
}
void InitTouchKeyIO(void)
{
    hw_gpio_Pin_t pin;
    ddi_gpio_Cfg_t cfg;
    RtStatus_t RetCode = SUCCESS;
    
    cfg.pin_drive = GPIO_8MA;
    cfg.pin_IO = GPIO_OUTPUT; 
    cfg.pin_irq_capable = GPIO_IRQ_INCAPABLE;
    cfg.pin_irq_enable = GPIO_IRQ_DISABLED;
    cfg.pin_irq_level = GPIO_IRQ_EDGE;
    cfg.pin_irq_polarity = GPIO_IRQ_POLARITY_LO; 
    cfg.pin_mux = GPIO_MODE3;

    pin = I2CKey_SDO;
    RetCode = ddi_gpio_Config(pin,cfg);
    if(SUCCESS != RetCode)
        SystemHalt();

    pin = I2CKey_SCK;
    RetCode = ddi_gpio_Config(pin,cfg);
    if(SUCCESS != RetCode)
        SystemHalt();
	Init_I2c_Interrupt();
/*    pin = I2CKey_RST;
    RetCode = ddi_gpio_Config(pin,cfg);
    if(SUCCESS != RetCode)
        SystemHalt();
        
    hw_gpio_SetBit(I2CKey_RST);
    
    cfg.pin_drive = GPIO_4MA;
    cfg.pin_IO = GPIO_INPUT; 
    
    pin = I2CKey_INT;
    RetCode = ddi_gpio_Config(pin,cfg);
    if(SUCCESS != RetCode)
        SystemHalt();*/
    
}//end void InitTouchKeyIO(void)
#if 0
#define I2C_SDO_H           hw_gpio_SetBit(I2CKey_SDO)
#define I2C_SCK_H           hw_gpio_SetBit(I2CKey_SCK)
#define I2C_SDO_L           hw_gpio_ClrBit(I2CKey_SDO)
#define I2C_SCK_L           hw_gpio_ClrBit(I2CKey_SCK)
#define I2C_SDO_FOR_OUTPUT  hw_gpio_SetOutputEnable(I2CKey_SDO, true)
#define I2C_SDO_FOR_INPUT   hw_gpio_SetOutputEnable(I2CKey_SDO, false)
#define I2C_SDO_DATA        (uint8_t)hw_gpio_ReadBit(I2CKey_SDO)

////////////////////////////////////////////////////////////////////////////////
//
//>  Name:          void I2cDelay(void)
//
//   Type:          Function
//
//   Description:   I2C delay
//
//   Inputs:        none used.
//
//   Outputs:       none used
//

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -