📄 i2c_func.c
字号:
///////////////////////////////////////////////////////////////////////////////////////////
/////////////////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 + -