/********************************************************************************
 * @file    TWI_Communication.c
 * @author  SOC AE Team
 * @version V1.1
 * @date    2025-06-27
 * @brief   TWI0作为主机，TWI1作为从机，两者互相通信。（主从机模式请在宏定义进行选择，TWI_Mode=0为主机代码，TWI_Mode=1为从机代码）
 *
 *******************************************************************************/
#include "sc32_conf.h"
#include "Function_Init.h"

/* 选择主从机代码 */
#define TWI_Mode 0

#if (TWI_Mode == 0)
static volatile FlagStatus TWI0_Flag1 = RESET, TWI0_Flag2 = RESET;
uint8_t TWI0_SendData[4] = {0x12, 0x34, 0x56, 0x78};
uint8_t TWI0_ReceiveData[4];

#elif(TWI_Mode == 1)
static volatile FlagStatus TWI1_Flag1 = RESET;
uint8_t TWI1_SendData[4] = {0xAB, 0xCD, 0xEF, 0xAC};
uint8_t TWI1_ReceiveData[5];
uint8_t Status  = 0xff;
uint8_t Recebuffcount = 0x00;
uint8_t Slave_ReceFlag = 0;
#endif

void TWI_Communication_Function(void)
{
  
  uint8_t i;
  TWI_InitTypeDef TWI_InitStruct; //定义TWI初始化结构体变量
  
#if (TWI_Mode == 0)

  /* 使能TWI0的时钟 */
  RCC_APB0Cmd(ENABLE);  //TWI0外设挂载在APB0时钟上
#if defined(SC32f10xx)||defined(SC32f12xx)
  RCC_APB0PeriphClockCmd(RCC_APB0Periph_TWI0, ENABLE);
#endif
  TWI_StructInit(&TWI_InitStruct);
  
  /* 配置TWI0作为主机 */
  TWI_InitStruct.TWI_Ack = TWI_Ack_Enable;
#if defined(SC32f10xx)||defined(SC32f12xx)
  TWI_InitStruct.TWI_Prescaler = TWI_PRESCALER_256;

#endif
  TWI_Init(TWI0, &TWI_InitStruct);
#if defined(SC32f10xx)||defined(SC32f12xx)
  /* 使能TWI中断 */
  TWI_ITConfig(TWI0, TWI_IT_INT, ENABLE);
	 NVIC_EnableIRQ(TWI0_IRQn);
#endif
#if defined(SC32f12xx)
   TWI_PinRemapConfig(TWI0,TWI_PinRemap_A);
#endif
  /* 使能接收发送口 */
  TWI_Cmd(TWI0, ENABLE);
  
#elif(TWI_Mode == 1)
  /* 使能TWI1的时钟 */
  RCC_APB1Cmd(ENABLE);  //TWI1外设挂载在APB1时钟上
#if defined(SC32f10xx)||defined(SC32f12xx)
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TWI1, ENABLE);
#endif
  TWI_StructInit(&TWI_InitStruct);
  
  /* 配置TWI1作为从机 */
  TWI_InitStruct.TWI_Ack = TWI_Ack_Enable;
  TWI_InitStruct.TWI_Stretch = TWI_Stretch_Enable;//使能时钟延展
#if defined(SC32f10xx)||defined(SC32f12xx)
    TWI_InitStruct.TWI_Prescaler = TWI_PRESCALER_128;
#endif
  TWI_InitStruct.TWI_GeneralCall = TWI_GeneralCall_Disable;
 
  TWI_InitStruct.TWI_SlaveAdress = 0x50;
  TWI_Init(TWI1, &TWI_InitStruct);
  /* 使能TWI中断 */
  
#if defined(SC32f10xx)||defined(SC32f12xx)
  TWI_ITConfig(TWI1, TWI_IT_INT, ENABLE);  
  NVIC_EnableIRQ(TWI1_IRQn);
#endif
  /* 使能接收发送口 */
  TWI_Cmd(TWI1, ENABLE);
#endif
  
  while(1)
  {
    
#if (TWI_Mode == 0)
	GPIO_InitTypeDef GPIO_InitStruct; //定义TWI初始化结构体变量
  GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_PU;
  GPIO_Init(GPIOB, &GPIO_InitStruct);
	PB_BIT(8)=0;    
    /* 主机发送 */
    /* 发送起始信号 */
    TWI_GenerateSTART(TWI0, ENABLE);
    {
      uint32_t delay_time = 100;
      while(delay_time--);
    }
    while(TWI0_Flag1 == RESET);	//等待起始信号发送完成
    TWI0_Flag1 = RESET;
    /* 发送地址 */
    TWI_Send7bitAddress(TWI0, 0x50, TWI_Command_Write);
    while(TWI0_Flag1 == RESET);	//等待地址发送完成
    TWI0_Flag1 = RESET;
    {
      uint32_t delay_time = 100;
      while(delay_time--);
    }
    /* 主机发送地址帧（写），且收到从机的ACK */
    while(TWI0_Flag2 != SET);
    TWI0_Flag2 = RESET;
    /* 主机发送数据 */
    for(i = 0; i < 4; i++)
    {
      TWI_SendData(TWI0, TWI0_SendData[i]);  //对TWIDAT写数据，同时清TXnE/RXnE标志
      while(TWI0_Flag1 == RESET);	//等待数据发送完成
      TWI0_Flag1 = RESET;
      {
        uint32_t delay_time = 100;
        while(delay_time--);
      }
    }
    /* 发送停止信号 */
    TWI_GenerateSTOP(TWI0, ENABLE);
    printf(" TWI0主机发送数据成功！\r\n ");
    while(TWI_GetStateMachine(TWI0) != TWI_Master_Idle);  //等待主机恢复为空闲状态
    
    //延时
    {
      uint32_t delay_time = 100;
      while(delay_time--);
    }
    
    
    /* 主机接收 */
    
    TWI_AcknowledgeConfig(TWI0, ENABLE);//使能Ack应答
    /* 发送起始信号 */
    TWI_GenerateSTART(TWI0, ENABLE);
    {
      uint32_t delay_time = 100;
      while(delay_time--);
    }
    while(TWI0_Flag1 == RESET);	//等待起始信号发送完成
    TWI0_Flag1 = RESET;
    /* 发送地址 */
    TWI_Send7bitAddress(TWI0, 0x50, TWI_Command_Read);
    while(TWI0_Flag1 == RESET);	//等待地址发送完成
    TWI0_Flag1 = RESET;
    {
      uint32_t delay_time = 100;
      while(delay_time--);
    }
    /* 主机发送地址帧（读），且收到从机的ACK */
    while((TWI0_Flag2 != SET));
    TWI0_Flag2 = RESET;
    /* 主机接收数据 */
    for(i = 0; i < 4; i++)
    {
      while(TWI0_Flag1 != SET);//等待1byte接收完成
      TWI0_Flag1 = RESET;
      TWI0_ReceiveData[i] = (unsigned char)TWI_ReceiveData(TWI0);
      if(i >= 2)
      {
        TWI_AcknowledgeConfig(TWI0, DISABLE);//倒数第二byte关闭Ack应答
      }
    }
    /* 发送停止信号 */
    TWI_GenerateSTOP(TWI0, ENABLE);
    printf(" TWI0主机接收到的数据是0x%x,0x%x,0x%x,0x%x。\r\n ", TWI0_ReceiveData[0], TWI0_ReceiveData[1], TWI0_ReceiveData[2], TWI0_ReceiveData[3]);
    while(TWI_GetStateMachine(TWI0) != TWI_Master_Idle);  //等待主机恢复为空闲状态
    
    //延时
    {
      uint32_t delay_time = 1000;
      while(delay_time--);
    }
    
#elif(TWI_Mode == 1)
    
    /* 从机接收 */
    if(Slave_ReceFlag == 1)//从机接收完成
    {
      Slave_ReceFlag = 0;
      printf(" TWI1从机接收到数据是0x%x,0x%x,0x%x 0x%x。\r\n ", TWI1_ReceiveData[1], TWI1_ReceiveData[2], TWI1_ReceiveData[3], TWI1_ReceiveData[4]);
    }
    
    //延时
    {
      uint32_t delay_time = 100;
      while(delay_time--);
    }
    
    /* 从机发送 */
    
    while(TWI_GetStateMachine(TWI1) !=  TWI_Slave_SendData);//等待从机变为发送数据状态      
    TWI1_Flag1 = RESET;
    
    TWI_SendData(TWI1, TWI1_SendData[0]); //在主机发送接收信号前写入数据
    while(TWI1_Flag1 != SET); //等待数据发送完成
    TWI1_Flag1 = RESET;
    
    for(i = 1; i < 4; i++)
    {
      while(TWI_GetStateMachine(TWI1) !=  TWI_Slave_SendData);//等待从机变为发送数据状态
      
      TWI_SendData(TWI1, TWI1_SendData[i]);//在主机发送接收信号前写入数据
      while(TWI1_Flag1 != SET);//等待数据发送完成
      TWI1_Flag1 = RESET;
    }
    printf(" TWI1从机发送数据成功！\r\n ");
#endif
    
  }
}

void TWI_Communication_TWI0Handler(void)
{
#if (TWI_Mode == 0)
#if defined(SC32f10xx)||defined(SC32f12xx)
  if(TWI_GetFlagStatus(TWI0, TWI_FLAG_TWIF))//主机发送启动信号/发送完地址帧/接收或发送完数据帧
  {
    TWI_ClearFlag(TWI0, TWI_FLAG_TWIF);
    TWI0_Flag1 = SET;
    if(TWI_GetFlagStatus(TWI0, TWI_FLAG_TXRXnE))//主机发送地址帧（写），且收到从机的ACK；主机发送完数据，且接收到从机ACK；主机接收到数据，且主机回从机ACK
      TWI0_Flag2 = SET;
  }

#endif	
#endif
}

void TWI_Communication_TWI1Handler(void)
{
 #if defined(SC32f10xx)||defined(SC32f12xx)
#if (TWI_Mode == 1)
  if(TWI_GetFlagStatus(TWI1, TWI_FLAG_TWIF))//从机第一帧地址匹配成功/成功接收或发送8位数据/接收到重复起始条件/从机收到停止信号
  {
    TWI_ClearFlag(TWI1, TWI_FLAG_TWIF);
    TWI1_Flag1 = SET;
  }
  
  Status = (unsigned char)(TWI_GetStateMachine(TWI1) >> 8); //从机状态获取
  
  switch(Status)
  {
  case 0:
    break;
    
  case 1:
    break;
    
  case 2:	//从机接收状态
    {
      TWI1_ReceiveData[Recebuffcount] = (unsigned char)TWI_ReceiveData(TWI1);//从机接收数据
      Recebuffcount ++;
      if(Recebuffcount > 4) //从机接收完地址帧+4个数据
      {
        Recebuffcount = 0;
        Slave_ReceFlag = 1;
      }
    }
  case 3:	
    break;
    
  case 4:
    break;
    
  default:
    break;
  }
  


#endif
#endif
}

