1143 lines
24 KiB
C
1143 lines
24 KiB
C
/** ##########################################################################
|
||
** Filename :
|
||
** Project :
|
||
** Module :
|
||
** Processor :
|
||
** Version :
|
||
** Compiler :
|
||
** Date/Time :
|
||
** Abstract :
|
||
** Contents :
|
||
** Note :
|
||
**
|
||
** (c) Copyright dmdz Co.,Ltd
|
||
** --------------------------------------------------------------------------
|
||
** R E V I S I O N H I S T O R Y
|
||
** --------------------------------------------------------------------------
|
||
** Date Ver Author Description
|
||
|
||
** -20230602- --V1.0-- --mingyea--- --修改--
|
||
|
||
** #########################################################################*/
|
||
|
||
/*---------------------------------------------------------------------------
|
||
- I N C L U D E F I L E S
|
||
----------------------------------------------------------------------------*/
|
||
#include "common_cfg.h"
|
||
#include "common_memory.h"
|
||
#include "i2c.h"
|
||
#include "nvic.h"
|
||
#include "gpio_cfg.h"
|
||
#include "i2c_simu.h"
|
||
|
||
/*---------------------------------------------------------------------------
|
||
- D E F I N E S / M A C R O S
|
||
----------------------------------------------------------------------------*/
|
||
#define I2C_ADDR_TEST_MAX 4
|
||
|
||
|
||
/*---------------------------------------------------------------------------
|
||
- T Y P E D E F I N I T I O N S
|
||
----------------------------------------------------------------------------*/
|
||
typedef struct
|
||
{
|
||
u8 cmd; //写还是读;
|
||
u8 state;
|
||
u8 sub_state;
|
||
u16 slave_addr;
|
||
u8 slave_addr_len;
|
||
u8 tx_count;
|
||
u8 rx_count;
|
||
u8 tx_len;
|
||
u8 rx_len;
|
||
u8 cmd_result;
|
||
u8 result_temp;
|
||
u8 result;
|
||
u8 flag_nack;
|
||
u16 timecount;
|
||
u16 time_total;
|
||
u8 *p_len;
|
||
u8 *p_recv_data;
|
||
u8 slave_addr_index;
|
||
u8 slave_addr_tx[2]; //将地址,0表示高8位,1表示低8位
|
||
u8 tx_data[I2C_FRAME_MAX_SIZE];
|
||
u8 rx_data[I2C_FRAME_MAX_SIZE];
|
||
|
||
#ifdef I2C_DEBUG_EN
|
||
u8 test_state;
|
||
u8 test_len;
|
||
volatile u8 test_addr;
|
||
volatile u8 test_count;
|
||
volatile u8 test_data[I2C_FRAME_MAX_SIZE];
|
||
volatile u8 test[80];
|
||
#else
|
||
volatile u8 test_count;
|
||
#endif
|
||
}i2c_s;
|
||
|
||
|
||
/*---------------------------------------------------------------------------
|
||
- S T A T I C V A R I A B L E S
|
||
----------------------------------------------------------------------------*/
|
||
static i2c_s g_i2c;
|
||
|
||
|
||
/*---------------------------------------------------------------------------
|
||
* G L O B A L V A R I A B L E S
|
||
----------------------------------------------------------------------------*/
|
||
|
||
|
||
/*---------------------------------------------------------------------------
|
||
- C O N S T A N T S
|
||
----------------------------------------------------------------------------*/
|
||
const u8 g_addr_test[I2C_ADDR_TEST_MAX] =
|
||
{
|
||
#if 1
|
||
0x08,
|
||
0x08,
|
||
0x08,
|
||
0x08,
|
||
#else
|
||
0x44,
|
||
0x45,
|
||
0x46,
|
||
0x47,
|
||
#endif
|
||
};
|
||
|
||
|
||
/*---------------------------------------------------------------------------
|
||
- F U N C T I O N P R O T O T Y P E
|
||
----------------------------------------------------------------------------*/
|
||
static void i2c_goto_stop_bit_state(void);
|
||
static void i2c_calulate_addr(u8 cmd);
|
||
static void i2c_rx_data_task(void);
|
||
static void i2c_rx_data_start(void);
|
||
static void i2c_tx_data_task(void);
|
||
static void i2c_operate_result(u8 cmd);
|
||
|
||
/*---------------------------------------------------------------------------
|
||
|Prototype :
|
||
|Called by :
|
||
|Preconditions :
|
||
|Input parameters :
|
||
|Output parameters :
|
||
|Return value :
|
||
|Description :
|
||
----------------------------------------------------------------------------*/
|
||
void i2c_init(void)
|
||
{
|
||
common_memory_clear((u8*)&g_i2c,sizeof(g_i2c));
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test_addr=0u;
|
||
#endif
|
||
|
||
#ifdef I2C_MADE_BY_SIMU
|
||
i2c_simu_init();
|
||
#else
|
||
g_i2c.slave_addr = 0x00u;
|
||
FL_I2C_MasterMode_Init(I2C, (FL_I2C_MasterMode_InitTypeDef*)&g_IICInitStructer);
|
||
#ifdef I2C_INTERRUPT_EN
|
||
/* NVIC中断配置 */
|
||
NVIC_ClearPendingIRQ(I2C_IRQn);
|
||
NVIC_DisableIRQ(I2C_IRQn);
|
||
NVIC_SetPriority(I2C_IRQn, NVIC_PRIORITY_I2C);
|
||
NVIC_EnableIRQ(I2C_IRQn);
|
||
#endif
|
||
#endif
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------
|
||
|Prototype :
|
||
|Called by :
|
||
|Preconditions :
|
||
|Input parameters :
|
||
|Output parameters :
|
||
|Return value :
|
||
|Description :
|
||
----------------------------------------------------------------------------*/
|
||
void i2c_re_init_para(void)
|
||
{
|
||
//gpio_i2c_recovery_init();
|
||
//gpio_i2c_init();
|
||
|
||
g_i2c.timecount = 0u;
|
||
g_i2c.cmd = I2C_CMD_NULL;
|
||
g_i2c.rx_count = 0u;
|
||
g_i2c.tx_count = 0u;
|
||
g_i2c.rx_len = 0u;
|
||
g_i2c.tx_len = 0u;
|
||
g_i2c.cmd_result = I2C_CMD_RESULT_INIT;
|
||
g_i2c.result_temp = I2C_RESULT_INIT;
|
||
g_i2c.result = I2C_RESULT_INIT;
|
||
FL_I2C_Master_ClearFlag_TXComplete(I2C);
|
||
FL_I2C_Master_ClearFlag_RXComplete(I2C);
|
||
FL_I2C_Master_ClearFlag_NACK(I2C);
|
||
FL_I2C_Master_ClearFlag_Timeout(I2C);
|
||
FL_I2C_Master_DisableIT_NACK(I2C);
|
||
FL_I2C_Master_DisableIT_TXComplete(I2C);
|
||
FL_I2C_Master_DisableIT_RXComplete(I2C);
|
||
FL_I2C_Master_DisableIT_Stop(I2C);
|
||
FL_I2C_Master_DisableIT_Start(I2C);
|
||
//FL_I2C_Master_EnableI2CRestart(I2C);
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[0]++;
|
||
#endif
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------
|
||
|Prototype :
|
||
|Called by :
|
||
|Preconditions :
|
||
|Input parameters :
|
||
|Output parameters :
|
||
|Return value :
|
||
|Description :
|
||
----------------------------------------------------------------------------*/
|
||
void i2c_task(void)
|
||
{
|
||
#ifdef I2C_MADE_BY_SIMU
|
||
#else
|
||
switch(g_i2c.state)
|
||
{
|
||
case I2C_STATE_IDLE:
|
||
break;
|
||
case I2C_STATE_START_BIT:
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[1]++;
|
||
#endif
|
||
g_i2c.timecount++;
|
||
if(g_i2c.timecount>=g_i2c_time_total[I2C_TIME_TOTAL_ID_START_BIT])
|
||
{
|
||
g_i2c.timecount=0u;
|
||
i2c_re_init_para();
|
||
g_i2c.result = I2C_RESULT_FAILED_TIMEOUT;
|
||
g_i2c.state = I2C_STATE_IDLE;
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[2]++;
|
||
#endif
|
||
}
|
||
break;
|
||
case I2C_STATE_SEND_ADDR:
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[3]++;
|
||
#endif
|
||
g_i2c.timecount++;
|
||
if(g_i2c.timecount>=g_i2c_time_total[I2C_TIME_TOTAL_ID_ADDR])
|
||
{
|
||
g_i2c.timecount=0u;
|
||
i2c_re_init_para();
|
||
g_i2c.result = I2C_RESULT_FAILED_TIMEOUT;
|
||
g_i2c.state = I2C_STATE_IDLE;
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[4]++;
|
||
#endif
|
||
}
|
||
break;
|
||
case I2C_STATE_WRITE:
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[5]++;
|
||
#endif
|
||
g_i2c.timecount++;
|
||
if(g_i2c.timecount>=g_i2c_time_total[I2C_TIME_TOTAL_ID_WRITE])
|
||
{
|
||
g_i2c.timecount=0u;
|
||
i2c_re_init_para();
|
||
g_i2c.result = I2C_RESULT_FAILED_TIMEOUT;
|
||
g_i2c.state = I2C_STATE_IDLE;
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[6]++;
|
||
#endif
|
||
}
|
||
break;
|
||
case I2C_STATE_READ:
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[7]++;
|
||
#endif
|
||
g_i2c.timecount++;
|
||
if(g_i2c.timecount>=g_i2c_time_total[I2C_TIME_TOTAL_ID_READ])
|
||
{
|
||
g_i2c.timecount=0u;
|
||
i2c_re_init_para();
|
||
g_i2c.result = I2C_RESULT_FAILED_TIMEOUT;
|
||
g_i2c.state = I2C_STATE_IDLE;
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[8]++;
|
||
#endif
|
||
}
|
||
break;
|
||
case I2C_STATE_STOP_BIT:
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[9]++;
|
||
#endif
|
||
g_i2c.timecount++;
|
||
if(g_i2c.timecount>=g_i2c_time_total[I2C_TIME_TOTAL_ID_STOP_BIT])
|
||
{
|
||
g_i2c.timecount=0u;
|
||
i2c_re_init_para();
|
||
g_i2c.result = I2C_RESULT_FAILED_TIMEOUT;
|
||
g_i2c.state = I2C_STATE_IDLE;
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[10]++;
|
||
#endif
|
||
}
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
#endif
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------
|
||
|Prototype :
|
||
|Called by :
|
||
|Preconditions :
|
||
|Input parameters :
|
||
|Output parameters :
|
||
|Return value :
|
||
|Description :
|
||
----------------------------------------------------------------------------*/
|
||
static void i2c_calulate_addr(u8 cmd)
|
||
{
|
||
if(g_i2c.slave_addr_len==I2C_ADDR_10BIT)
|
||
{
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[11]++;
|
||
#endif
|
||
g_i2c.slave_addr_tx[0] = ((g_i2c.slave_addr & 0x300) >> 7) | 0XF0;
|
||
if(cmd == I2C_CMD_READ)
|
||
{
|
||
g_i2c.slave_addr_tx[0] = g_i2c.slave_addr_tx[0] | 1u;
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[12]++;
|
||
#endif
|
||
}
|
||
g_i2c.slave_addr_tx[1] = (g_i2c.slave_addr & 0xFF);
|
||
g_i2c.slave_addr_index=0u;
|
||
g_i2c.sub_state=0u;
|
||
}
|
||
else
|
||
{
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[13]++;
|
||
#endif
|
||
g_i2c.slave_addr_tx[1] = (g_i2c.slave_addr << 1u);
|
||
if(cmd == I2C_CMD_READ)
|
||
{
|
||
g_i2c.slave_addr_tx[1] = g_i2c.slave_addr_tx[1] | 1u;
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[14]++;
|
||
#endif
|
||
}
|
||
g_i2c.slave_addr_index=1u;
|
||
g_i2c.sub_state=1u;
|
||
}
|
||
}
|
||
|
||
|
||
/*---------------------------------------------------------------------------
|
||
|Prototype :
|
||
|Called by :
|
||
|Preconditions :
|
||
|Input parameters :
|
||
|Output parameters :
|
||
|Return value :
|
||
|Description :
|
||
----------------------------------------------------------------------------*/
|
||
static void i2c_operate_result(u8 cmd)
|
||
{
|
||
i2c_len_type i;
|
||
i2c_len_type l_len;
|
||
if(cmd==I2C_CMD_READ)
|
||
{
|
||
*g_i2c.p_len = g_i2c.rx_count;
|
||
if(g_i2c.rx_count>I2C_FRAME_MAX_SIZE)
|
||
{
|
||
l_len = I2C_FRAME_MAX_SIZE;
|
||
}
|
||
else
|
||
{
|
||
l_len=g_i2c.rx_count;
|
||
}
|
||
for(i = 0; i < l_len; i++)
|
||
{
|
||
g_i2c.p_recv_data[i] =g_i2c.rx_data[i];
|
||
}
|
||
i2c_recv_block_successful_callback();
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[15]++;
|
||
#endif
|
||
}
|
||
else
|
||
{
|
||
*g_i2c.p_len = g_i2c.tx_count;
|
||
i2c_send_block_successful_callback();
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[16]++;
|
||
#endif
|
||
}
|
||
}
|
||
|
||
|
||
/*---------------------------------------------------------------------------
|
||
|Prototype :
|
||
|Called by :
|
||
|Preconditions :
|
||
|Input parameters :
|
||
|Output parameters :
|
||
|Return value :
|
||
|Description :
|
||
----------------------------------------------------------------------------*/
|
||
uint8_t i2c_send_block(u8 *p_buf, i2c_len_type len,i2c_len_type *p_real_len)
|
||
{
|
||
u8 i;
|
||
u8 l_len;
|
||
u8 status = I2C_CMD_RESULT_OK;
|
||
|
||
#ifdef I2C_MADE_BY_SIMU
|
||
|
||
*p_real_len=0u;
|
||
i2c_simu_start();
|
||
i2c_simu_send_byte((g_i2c.slave_addr << 1));
|
||
if(i2c_simu_wait_ack())
|
||
{
|
||
status = I2C_CMD_RESULT_FAILED;
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[18]++;
|
||
#endif
|
||
return status;
|
||
}
|
||
*p_real_len++;
|
||
for(i = 0u; i < len; i++)
|
||
{
|
||
i2c_simu_send_byte(p_buf[i]);
|
||
if(i2c_simu_wait_ack())
|
||
{
|
||
status = I2C_CMD_RESULT_FAILED;
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[19]++;
|
||
#endif
|
||
return status;
|
||
}
|
||
*p_real_len++;
|
||
}
|
||
i2c_simu_stop();
|
||
|
||
i2c_recv_block_successful_callback();
|
||
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[17]++;
|
||
#endif
|
||
//return status;
|
||
|
||
#else
|
||
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[17]++;
|
||
#endif
|
||
//只有空闲时,才能
|
||
if(g_i2c.state == I2C_STATE_IDLE)
|
||
{
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[18]++;
|
||
#endif
|
||
if(len<I2C_FRAME_MAX_SIZE)
|
||
{
|
||
l_len = len;
|
||
}
|
||
else
|
||
{
|
||
l_len = I2C_FRAME_MAX_SIZE;
|
||
}
|
||
for(i = 0u; i < l_len; i++)
|
||
{
|
||
g_i2c.tx_data[i] = p_buf[i];
|
||
}
|
||
g_i2c.p_len = p_real_len;
|
||
*g_i2c.p_len = 0u;
|
||
g_i2c.tx_count = 0u;
|
||
g_i2c.tx_len = l_len;
|
||
g_i2c.sub_state =0u;
|
||
g_i2c.result_temp = I2C_RESULT_INIT;
|
||
g_i2c.result = I2C_RESULT_INIT;
|
||
g_i2c.timecount = 0u;
|
||
g_i2c.state = I2C_STATE_START_BIT;
|
||
g_i2c.cmd = I2C_CMD_WRITE;
|
||
i2c_calulate_addr(I2C_CMD_WRITE);
|
||
FL_I2C_Master_EnableI2CStart(I2C);
|
||
FL_I2C_Master_EnableIT_Start(I2C);
|
||
}
|
||
else
|
||
{
|
||
status = I2C_CMD_RESULT_FAILED;
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[18]++;
|
||
#endif
|
||
}
|
||
|
||
#endif
|
||
|
||
return(status);
|
||
}
|
||
|
||
/*---------------------------------------------------------------------------
|
||
|Prototype :
|
||
|Called by :
|
||
|Preconditions :
|
||
|Input parameters :
|
||
|Output parameters :
|
||
|Return value :
|
||
|Description :
|
||
----------------------------------------------------------------------------*/
|
||
uint8_t i2c_recv_block(u8 *p_buf, i2c_len_type len,i2c_len_type *p_real_len)
|
||
{
|
||
u8 i;
|
||
//u8 l_len;
|
||
u8 status = I2C_CMD_RESULT_OK;
|
||
u8 l_ack = 0;
|
||
|
||
#ifdef I2C_MADE_BY_SIMU
|
||
|
||
*p_real_len=0u;
|
||
i2c_simu_start();
|
||
i2c_simu_send_byte((g_i2c.slave_addr << 1u)|0x01);
|
||
if(i2c_simu_wait_ack())
|
||
{
|
||
status = I2C_CMD_RESULT_FAILED;
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[21]++;
|
||
#endif
|
||
return status;
|
||
}
|
||
*p_real_len++;
|
||
for(i = 0u; i < len; i++)
|
||
{
|
||
if(i==(len-1u))
|
||
{
|
||
l_ack=0u;
|
||
}
|
||
else
|
||
{
|
||
l_ack=1u;
|
||
}
|
||
p_buf[i] = i2c_simu_read_byte(l_ack);
|
||
#if 0
|
||
if(i2c_simu_wait_ack())
|
||
{
|
||
status = I2C_CMD_RESULT_FAILED;
|
||
return status;
|
||
}
|
||
#endif
|
||
*p_real_len++;
|
||
}
|
||
i2c_simu_stop();
|
||
|
||
i2c_recv_block_successful_callback();
|
||
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[20]++;
|
||
#endif
|
||
|
||
#else
|
||
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[20]++;
|
||
#endif
|
||
|
||
//只有空闲时,才能
|
||
if(g_i2c.state == I2C_STATE_IDLE)
|
||
{
|
||
g_i2c.p_len = p_real_len;
|
||
*g_i2c.p_len = 0u;
|
||
g_i2c.p_recv_data = p_buf;
|
||
g_i2c.rx_count = 0u;
|
||
g_i2c.rx_len =len;
|
||
g_i2c.sub_state =0u;
|
||
g_i2c.result_temp = I2C_RESULT_INIT;
|
||
g_i2c.result = I2C_RESULT_INIT;
|
||
g_i2c.timecount = 0u;
|
||
g_i2c.state = I2C_STATE_START_BIT;
|
||
g_i2c.cmd = I2C_CMD_READ;
|
||
i2c_calulate_addr(I2C_CMD_READ);
|
||
FL_I2C_Master_EnableI2CStart(I2C);
|
||
FL_I2C_Master_EnableIT_Start(I2C);
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[21]++;
|
||
#endif
|
||
}
|
||
else
|
||
{
|
||
status = I2C_CMD_RESULT_FAILED;
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[22]++;
|
||
#endif
|
||
}
|
||
|
||
#endif
|
||
|
||
return(status);
|
||
}
|
||
|
||
|
||
/*---------------------------------------------------------------------------
|
||
|Prototype :
|
||
|Called by :
|
||
|Preconditions :
|
||
|Input parameters :
|
||
|Output parameters :
|
||
|Return value :
|
||
|Description :
|
||
----------------------------------------------------------------------------*/
|
||
void i2c_sel_slave_addr(u16 addr)
|
||
{
|
||
g_i2c.slave_addr = addr;
|
||
if(addr>0x7f)
|
||
{
|
||
g_i2c.slave_addr_len =I2C_ADDR_10BIT;
|
||
}
|
||
else
|
||
{
|
||
g_i2c.slave_addr_len =I2C_ADDR_7BIT;
|
||
}
|
||
}
|
||
|
||
|
||
/*---------------------------------------------------------------------------
|
||
|Prototype :
|
||
|Called by :
|
||
|Preconditions :
|
||
|Input parameters :
|
||
|Output parameters :
|
||
|Return value :
|
||
|Description :
|
||
----------------------------------------------------------------------------*/
|
||
static void i2c_goto_stop_bit_state(void)
|
||
{
|
||
//跳到 stop
|
||
FL_I2C_Master_DisableIT_NACK(I2C);
|
||
FL_I2C_Master_DisableIT_TXComplete(I2C);
|
||
FL_I2C_Master_DisableIT_RXComplete(I2C);
|
||
//发完--数据,接下来,发stop bit;
|
||
g_i2c.timecount = 0u;
|
||
g_i2c.sub_state = 0u;
|
||
g_i2c.state = I2C_STATE_STOP_BIT;
|
||
FL_I2C_Master_EnableI2CStop(I2C);
|
||
FL_I2C_Master_EnableIT_Stop(I2C);
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[23]++;
|
||
#endif
|
||
}
|
||
|
||
|
||
/*---------------------------------------------------------------------------
|
||
|Prototype :
|
||
|Called by :
|
||
|Preconditions :
|
||
|Input parameters :
|
||
|Output parameters :
|
||
|Return value :
|
||
|Description : I2C中断
|
||
----------------------------------------------------------------------------*/
|
||
void I2C_IRQHandler(void)
|
||
{
|
||
u8 l_addr_id=0u;
|
||
|
||
//start bit 成功
|
||
if( (FL_I2C_Master_IsEnabledIT_Start(I2C) == FL_ENABLE)
|
||
&& (FL_I2C_Master_IsActiveFlag_Start(I2C)==FL_SET)
|
||
)
|
||
{
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[24]++;
|
||
#endif
|
||
/* -------------- disable read ---------- */
|
||
FL_I2C_Master_DisableRX(I2C);
|
||
FL_I2C_Master_DisableIT_Start(I2C);
|
||
FL_I2C_Master_DisableIT_Stop(I2C);
|
||
g_i2c.timecount = 0u;
|
||
if(g_i2c.state==I2C_STATE_START_BIT)
|
||
{
|
||
g_i2c.state = I2C_STATE_SEND_ADDR;
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[25]++;
|
||
#endif
|
||
}
|
||
//开始传输地址--
|
||
FL_I2C_Master_WriteTXBuff(I2C, g_i2c.slave_addr_tx[g_i2c.slave_addr_index]);
|
||
FL_I2C_Master_EnableIT_TXComplete(I2C);
|
||
}
|
||
if( (FL_I2C_Master_IsEnabledIT_TXComplete(I2C) == FL_ENABLE)
|
||
&& (FL_I2C_Master_IsActiveFlag_TXComplete(I2C) == FL_SET)
|
||
)
|
||
{
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[26]++;
|
||
#endif
|
||
FL_I2C_Master_ClearFlag_TXComplete(I2C);
|
||
g_i2c.timecount = 0u;
|
||
//判斷,有沒有ack
|
||
if(FL_I2C_Master_IsActiveFlag_NACK(I2C)==FL_SET)
|
||
{
|
||
g_i2c.result_temp=I2C_RESULT_FAILED_NACK;
|
||
i2c_goto_stop_bit_state();
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[27]++;
|
||
#endif
|
||
}
|
||
else
|
||
{
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[28]++;
|
||
#endif
|
||
}
|
||
#if 1
|
||
if(g_i2c.state == I2C_STATE_SEND_ADDR)
|
||
{
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[29]++;
|
||
#endif
|
||
if(g_i2c.sub_state==0u) //繼續發送低地址
|
||
{
|
||
g_i2c.slave_addr_index=1;
|
||
FL_I2C_Master_WriteTXBuff(I2C, g_i2c.slave_addr_tx[g_i2c.slave_addr_index]);
|
||
FL_I2C_Master_EnableIT_TXComplete(I2C);
|
||
g_i2c.sub_state=1u;
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[30]++;
|
||
#endif
|
||
}
|
||
else //可以發送數據DATA
|
||
{
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[31]++;
|
||
#endif
|
||
if(g_i2c.cmd == I2C_CMD_WRITE)
|
||
{
|
||
i2c_tx_data_task();
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[32]++;
|
||
#endif
|
||
}
|
||
else if(g_i2c.cmd == I2C_CMD_READ)
|
||
{
|
||
i2c_rx_data_start();
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[33]++;
|
||
#endif
|
||
}
|
||
}
|
||
}
|
||
else if (g_i2c.state == I2C_STATE_WRITE)
|
||
{
|
||
//开始发送数据内容
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[34]++;
|
||
#endif
|
||
i2c_tx_data_task();
|
||
//FL_I2C_Master_EnableIT_TXComplete(I2C);
|
||
}
|
||
else
|
||
{
|
||
//
|
||
}
|
||
#endif
|
||
}
|
||
if( (FL_I2C_Master_IsEnabledIT_RXComplete(I2C) == FL_ENABLE)
|
||
&& (FL_I2C_Master_IsActiveFlag_RXComplete(I2C)==FL_SET)
|
||
)
|
||
{
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[35]++;
|
||
#endif
|
||
g_i2c.timecount = 0u;
|
||
//if (g_i2c.state == I2C_STATE_READ)
|
||
FL_I2C_Master_ClearFlag_RXComplete(I2C);
|
||
i2c_rx_data_task();
|
||
//if(l_nack==0u)
|
||
{
|
||
i2c_rx_data_start();
|
||
}
|
||
}
|
||
if( (FL_I2C_Master_IsEnabledIT_Stop(I2C) == FL_ENABLE)
|
||
&& (FL_I2C_Master_IsActiveFlag_Stop(I2C)==FL_SET)
|
||
)
|
||
{
|
||
g_i2c.timecount = 0u;
|
||
FL_I2C_Master_DisableIT_NACK(I2C);
|
||
FL_I2C_Master_DisableIT_TXComplete(I2C);
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[36]++;
|
||
#endif
|
||
|
||
if(g_i2c.result_temp == I2C_RESULT_FAILED_NACK)
|
||
{
|
||
g_i2c.result = I2C_RESULT_FAILED_NACK;
|
||
g_i2c.state = I2C_STATE_IDLE;
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[37]++;
|
||
#endif
|
||
}
|
||
else if(g_i2c.result_temp == I2C_RESULT_OK)
|
||
{
|
||
g_i2c.result = I2C_RESULT_OK;
|
||
i2c_operate_result(g_i2c.cmd);
|
||
g_i2c.state = I2C_STATE_IDLE;
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[38]++;
|
||
#endif
|
||
}
|
||
else
|
||
{
|
||
//
|
||
}
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[39]++;
|
||
#endif
|
||
//
|
||
}
|
||
if( (FL_I2C_Master_IsEnabledIT_Timeout(I2C) == FL_ENABLE)
|
||
&& (FL_I2C_Master_IsActiveFlag_Timeout(I2C)==FL_SET)
|
||
)
|
||
{
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[40]++;
|
||
#endif
|
||
FL_I2C_Master_ClearFlag_Timeout(I2C);
|
||
FL_I2C_Master_ClearFlag_TXComplete(I2C);
|
||
}
|
||
if( (FL_I2C_Master_IsEnabledIT_WriteConflict(I2C) == FL_ENABLE)
|
||
&& (FL_I2C_Master_IsActiveFlag_WriteConflict(I2C)==FL_SET)
|
||
)
|
||
{
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[41]++;
|
||
#endif
|
||
}
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[42]++;
|
||
#endif
|
||
}
|
||
|
||
|
||
/*---------------------------------------------------------------------------
|
||
|Prototype :
|
||
|Called by :
|
||
|Preconditions :
|
||
|Input parameters :
|
||
|Output parameters :
|
||
|Return value :
|
||
|Description :發送數據
|
||
----------------------------------------------------------------------------*/
|
||
static void i2c_tx_data_task(void)
|
||
{
|
||
u8 l_nack;
|
||
u16 l_count =0u;
|
||
g_i2c.state = I2C_STATE_WRITE;
|
||
//if(g_i2c.mode == I2C_CMD_WRITE)
|
||
{
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[43]++;
|
||
#endif
|
||
if(g_i2c.tx_count<g_i2c.tx_len)
|
||
{
|
||
//l_nack = i2c_judge_nack_and_stop();
|
||
//if(l_nack == I2C_JUDGE_ACK)
|
||
{
|
||
//g_i2c.flag_nack = 0u;
|
||
FL_I2C_Master_WriteTXBuff(I2C, g_i2c.tx_data[g_i2c.tx_count]);
|
||
FL_I2C_Master_EnableIT_TXComplete(I2C);
|
||
}
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[44]++;
|
||
#endif
|
||
}
|
||
else
|
||
{
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[45]++;
|
||
#endif
|
||
g_i2c.result_temp=I2C_RESULT_OK;
|
||
i2c_goto_stop_bit_state();
|
||
}
|
||
g_i2c.tx_count++;
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[46]++;
|
||
#endif
|
||
}
|
||
}
|
||
|
||
|
||
/*---------------------------------------------------------------------------
|
||
|Prototype :
|
||
|Called by :
|
||
|Preconditions :
|
||
|Input parameters :
|
||
|Output parameters :
|
||
|Return value :
|
||
|Description :接收收據--的開始
|
||
----------------------------------------------------------------------------*/
|
||
static void i2c_rx_data_start(void)
|
||
{
|
||
u16 l_count =0u;
|
||
g_i2c.state = I2C_STATE_READ;
|
||
FL_I2C_Master_DisableIT_NACK(I2C);
|
||
FL_I2C_Master_DisableIT_TXComplete(I2C);
|
||
//if(g_i2c.mode == I2C_CMD_READ)
|
||
{
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[47]++;
|
||
#endif
|
||
if(g_i2c.rx_count<g_i2c.rx_len)
|
||
{
|
||
g_i2c.flag_nack = 0u;
|
||
if(g_i2c.rx_count<(g_i2c.rx_len-1u))
|
||
{
|
||
FL_I2C_Master_SetRespond(I2C, FL_I2C_MASTER_RESPOND_ACK);
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[48]++;
|
||
#endif
|
||
}
|
||
else
|
||
{
|
||
FL_I2C_Master_SetRespond(I2C, FL_I2C_MASTER_RESPOND_NACK);
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[49]++;
|
||
#endif
|
||
}
|
||
FL_I2C_Master_EnableIT_RXComplete(I2C);
|
||
/* i2c en, rcen */
|
||
FL_I2C_Master_EnableRX(I2C);
|
||
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[50]++;
|
||
#endif
|
||
}
|
||
else
|
||
{
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[51]++;
|
||
#endif
|
||
g_i2c.result_temp=I2C_RESULT_OK;
|
||
i2c_goto_stop_bit_state();
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
/*---------------------------------------------------------------------------
|
||
|Prototype :
|
||
|Called by :
|
||
|Preconditions :
|
||
|Input parameters :
|
||
|Output parameters :
|
||
|Return value :
|
||
|Description :接收收據-
|
||
----------------------------------------------------------------------------*/
|
||
static void i2c_rx_data_task(void)
|
||
{
|
||
//u8 l_result=0u;
|
||
u16 l_count =0u;
|
||
g_i2c.state = I2C_STATE_READ;
|
||
//if(g_i2c.mode == I2C_CMD_READ)
|
||
{
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[52]++;
|
||
#endif
|
||
if(g_i2c.rx_count<g_i2c.rx_len)
|
||
{
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[53]++;
|
||
#endif
|
||
g_i2c.rx_data[g_i2c.rx_count] = FL_I2C_Master_ReadRXBuff(I2C);
|
||
}
|
||
else
|
||
{
|
||
#if 0
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[13]++;
|
||
#endif
|
||
i2c_goto_stop_bit_state();
|
||
#endif
|
||
}
|
||
g_i2c.rx_count++;
|
||
}
|
||
//return l_result;
|
||
}
|
||
|
||
|
||
|
||
|
||
/*---------------------------------------------------------------------------
|
||
|Prototype :
|
||
|Called by :
|
||
|Preconditions :
|
||
|Input parameters :
|
||
|Output parameters :
|
||
|Return value :
|
||
|Description :接收收據-
|
||
----------------------------------------------------------------------------*/
|
||
void i2c_test(void)
|
||
{
|
||
u8 i;
|
||
#ifdef I2C_DEBUG_EN
|
||
switch(g_i2c.test_state)
|
||
{
|
||
case 0:
|
||
i2c_re_init_para();
|
||
g_i2c.test_len=0u;
|
||
g_i2c.test_data[0] =0x21;
|
||
g_i2c.test_data[1] =0x21;
|
||
g_i2c.result = I2C_RESULT_INIT;
|
||
//i2c_sel_slave_addr(DEVICE_ADD);
|
||
i2c_sel_slave_addr(g_addr_test[g_i2c.test_addr]);
|
||
g_i2c.cmd_result = i2c_send_block((u8*)&g_i2c.test_data[0],2u,&g_i2c.test_len);
|
||
g_i2c.test_state=1u;
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[55]++;
|
||
#endif
|
||
break;
|
||
|
||
case 1:
|
||
//判断有没有发成功
|
||
if(g_i2c.result == I2C_RESULT_OK)
|
||
{
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[56]++;
|
||
#endif
|
||
//地址正确
|
||
g_i2c.test_state=2u;
|
||
}
|
||
else if(g_i2c.result == I2C_RESULT_FAILED_TIMEOUT)
|
||
{
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[57]++;
|
||
#endif
|
||
}
|
||
else if(g_i2c.result == I2C_RESULT_FAILE_TOHER)
|
||
{
|
||
}
|
||
else if(g_i2c.result == I2C_RESULT_FAILED_NACK)
|
||
{
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[58]++;
|
||
#endif
|
||
g_i2c.test_addr++;
|
||
if(g_i2c.test_addr>=I2C_ADDR_TEST_MAX)
|
||
{
|
||
g_i2c.test_addr=0u;
|
||
g_i2c.test_state=2u;
|
||
}
|
||
else
|
||
{
|
||
g_i2c.test_state=0u;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[69]++;
|
||
#endif
|
||
}
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[60]++;
|
||
#endif
|
||
break;
|
||
|
||
|
||
case 2:
|
||
g_i2c.cmd = I2C_CMD_NULL;
|
||
i2c_re_init_para();
|
||
g_i2c.test_len=0u;
|
||
g_i2c.test_data[0] =0x21;
|
||
g_i2c.test_data[1] =0x21;
|
||
for(i = 0; i < I2C_FRAME_MAX_SIZE; i++)
|
||
{
|
||
g_i2c.test_data[i] =0xcc;
|
||
}
|
||
g_i2c.result = I2C_RESULT_INIT;
|
||
//i2c_sel_slave_addr(DEVICE_ADD);
|
||
i2c_sel_slave_addr(g_addr_test[g_i2c.test_addr]);
|
||
//uint8_t i2c_recv_block(uint16_t Device, uint8_t AddrLen, uint8_t *Buf, uint8_t Len)
|
||
g_i2c.cmd_result = i2c_recv_block((u8*)&g_i2c.test_data[0], 6u ,&g_i2c.test_len);
|
||
g_i2c.test_state=3u;
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[61]++;
|
||
#endif
|
||
break;
|
||
|
||
case 3:
|
||
//判断有没有发成功
|
||
if(g_i2c.result == I2C_RESULT_OK)
|
||
{
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[62]++;
|
||
#endif
|
||
g_i2c.test_addr=0u;
|
||
g_i2c.test_state=0u;
|
||
}
|
||
else if(g_i2c.result == I2C_RESULT_FAILED_TIMEOUT)
|
||
{
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[63]++;
|
||
#endif
|
||
}
|
||
else if(g_i2c.result == I2C_RESULT_FAILE_TOHER)
|
||
{
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[64]++;
|
||
#endif
|
||
}
|
||
else if(g_i2c.result == I2C_RESULT_FAILED_NACK)
|
||
{
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[65]++;
|
||
#endif
|
||
g_i2c.test_addr++;
|
||
if(g_i2c.test_addr>=I2C_ADDR_TEST_MAX)
|
||
{
|
||
g_i2c.test_addr=0u;
|
||
g_i2c.test_state=2u;
|
||
}
|
||
else
|
||
{
|
||
g_i2c.test_state=2u;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[66]++;
|
||
#endif
|
||
}
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[67]++;
|
||
#endif
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
#endif
|
||
#if 0
|
||
if(g_i2c.test_state==0)
|
||
{
|
||
|
||
}
|
||
else
|
||
{
|
||
g_i2c.test_state=0u;
|
||
g_i2c.rx_len=7u;
|
||
common_memory_clear(&g_i2c.rx_data[0],20);
|
||
l_result = i2c_recv_block(Device, AddrLen, &g_i2c.rx_data[0], g_i2c.rx_len);
|
||
#ifdef I2C_DEBUG_EN
|
||
g_i2c.test[1]++;
|
||
#endif
|
||
}
|
||
#endif
|
||
//return l_result;
|
||
}
|
||
|
||
/* END i2c.h. */
|
||
|
||
|