#include "bsp_gpio.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x.h"
#include "stdint.h"
// #include "public_diy.h"

/* 按键口对应的RCC时钟 */
// #define RCC_ALL_LED 	(RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOB)	
// #define RCC_GPIO_LED1	RCC_APB2Periph_GPIOC
#define GPIO_PORT_LED1  GPIOC
#define GPIO_PIN_LED1	GPIO_Pin_13

// #define RCC_GPIO_LED2	RCC_APB2Periph_GPIOB
// #define GPIO_PORT_LED2  GPIOB
// #define GPIO_PIN_LED2	GPIO_Pin_9
// #define 
/* A IN1 */
#define TB6612_AIN1_GPIO_PORT	(GPIOA)
#define TB6612_AIN1_GPIO_PIN	(GPIO_Pin_4)
/* A IN2 */
#define TB6612_AIN2_GPIO_PORT	(GPIOA)
#define TB6612_AIN2_GPIO_PIN	(GPIO_Pin_5)
/* B IN1 */
#define TB6612_BIN1_GPIO_PORT	(GPIOA)
#define TB6612_BIN1_GPIO_PIN	(GPIO_Pin_1)
/* B IN2 */
#define TB6612_BIN2_GPIO_PORT	(GPIOA)
#define TB6612_BIN2_GPIO_PIN	(GPIO_Pin_8)

/* PWMA */
// #define TIM_MOTOR_PWMA_GPIO_RCC          RCC_APB2Periph_GPIOB
#define TB6612_PWMA_GPIO_PORT         (GPIOB)
#define TB6612_PWMA_GPIO_PIN          (GPIO_Pin_8)
/* PWMB */
// #define TIM_MOTOR_PWMB_GPIO_RCC          RCC_APB2Periph_GPIOB
#define TB6612_PWMB_GPIO_PORT         (GPIOB)
#define TB6612_PWMB_GPIO_PIN          (GPIO_Pin_9)
/* OLED SCL */
#define OLED_SCL_GPIO_PORT	(GPIOB)
#define OLED_SCL_GPIO_PIN	(GPIO_Pin_3)
#define OLED_SCL_GPIO_RCC	(RCC_APB2Periph_GPIOB)
/* OLED SDA */
#define OLED_SDA_GPIO_PORT	(GPIOB)
#define OLED_SDA_GPIO_PIN	(GPIO_Pin_4)
#define OLED_SDA_GPIO_RCC	(RCC_APB2Periph_GPIOB)

static void bsp_gpio_rcc_enable(GPIO_TypeDef * gpio_port)
{
    // 时钟初始化
	if(gpio_port == GPIOA)
	{
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	}
	else if(gpio_port == GPIOB)
	{
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	}
	else if(gpio_port == GPIOC)
    {
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
    }
	else if(gpio_port == GPIOD)
    {
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);
    }
	else if(gpio_port == GPIOE)
    {
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
    }
	else if(gpio_port == GPIOF)
    {
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOF, ENABLE);
    }
	else if(gpio_port == GPIOG)
    {
		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG, ENABLE);
    }
}



/*************************************************************************************
 * @brief    led1 初始化
 * 
 * @warning  【不可重入,阻塞等警告】
 * @note     【重大修改】
  *************************************************************************************/
void bsp_gpio_led1_init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
	/* 打开GPIO时钟 */
	// RCC_APB2PeriphClockCmd(RCC_GPIO_LED1, ENABLE);
    bsp_gpio_rcc_enable(GPIO_PORT_LED1);
	/*
		配置所有的LED指示灯GPIO为推挽输出模式
		由于将GPIO设置为输出时，GPIO输出寄存器的值缺省是0，因此会驱动LED点亮.
		这是我不希望的，因此在改变GPIO为输出前，先关闭LED指示灯
	*/
    // bsp_led_off(LED1);
    
    /* LED 1*/
	GPIO_InitStructure.GPIO_Pin = GPIO_PIN_LED1;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;		/* 设为 输出推挽模式 */
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	/* IO口最大速度 */
	GPIO_Init(GPIO_PORT_LED1, &GPIO_InitStructure);
}

/*************************************************************************************
 * @brief    led1 亮
 * 
 * @warning  【不可重入,阻塞等警告】
 * @note     【重大修改】
  *************************************************************************************/
void bsp_gpio_led1_on(void)
{
    // STM32F103C8T6开发板 1是亮，0是灭
    // GPIO_PORT_LED1->BRR = GPIO_PIN_LED1;
    GPIO_PORT_LED1->BSRR |= GPIO_PIN_LED1;
}

/*************************************************************************************
 * @brief    led1 灭
 * 
 * @warning  【不可重入,阻塞等警告】
 * @note     【重大修改】
  *************************************************************************************/
void bsp_gpio_led1_off(void)
{
    // STM32F103C8T6开发板 1是亮，0是灭
    GPIO_PORT_LED1->BRR = GPIO_PIN_LED1;
}
/*************************************************************************************
 * @brief    获取led1的状态
 * @return uint16_t    【返回值注释】
 * 
 * @warning  【不可重入,阻塞等警告】
 * @note     【重大修改】
  *************************************************************************************/
uint8_t bsp_gpio_led1_status(void)
{
    uint8_t retVal = 0;
    retVal = GPIO_PORT_LED1->ODR & GPIO_PIN_LED1;
    return retVal;
}

/*************************************************************************************
 * @brief    TB6612 gpio初始化
 * 
 * @warning  【不可重入,阻塞等警告】
 * @note     【重大修改】
  *************************************************************************************/
void bsp_gpio_tb6612_init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    
	/* AIN1 初始化 */
    bsp_gpio_rcc_enable(TB6612_AIN1_GPIO_PORT);
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = TB6612_AIN1_GPIO_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(TB6612_AIN1_GPIO_PORT, &GPIO_InitStructure);
	/* AIN2 初始化 */
    bsp_gpio_rcc_enable(TB6612_AIN2_GPIO_PORT);
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = TB6612_AIN2_GPIO_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(TB6612_AIN2_GPIO_PORT, &GPIO_InitStructure);
	/* BIN1 初始化 */
    bsp_gpio_rcc_enable(TB6612_BIN1_GPIO_PORT);
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = TB6612_BIN1_GPIO_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(TB6612_BIN1_GPIO_PORT, &GPIO_InitStructure);
	/* BIN2 初始化 */
    bsp_gpio_rcc_enable(TB6612_BIN2_GPIO_PORT);
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = TB6612_BIN2_GPIO_PIN;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(TB6612_BIN2_GPIO_PORT, &GPIO_InitStructure);
    /* PWMA */
    GPIO_Init(TB6612_PWMA_GPIO_PORT, &GPIO_InitStructure);              //初始化
    bsp_gpio_rcc_enable(TB6612_PWMA_GPIO_PORT); 
    GPIO_InitStructure.GPIO_Pin = TB6612_PWMA_GPIO_PIN;           
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   //IO 口速度为 50MHz
    GPIO_Init(TB6612_PWMA_GPIO_PORT, &GPIO_InitStructure);             
    /* PWMB */
    GPIO_Init(TB6612_PWMB_GPIO_PORT, &GPIO_InitStructure);              //初始化 
    bsp_gpio_rcc_enable(TB6612_PWMB_GPIO_PORT);
    GPIO_InitStructure.GPIO_Pin = TB6612_PWMB_GPIO_PIN;           
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;   //IO 口速度为 50MHz
    GPIO_Init(TB6612_PWMB_GPIO_PORT, &GPIO_InitStructure);      
}

void bsp_gpio_tb6612_AIN1_enable(void)
{
    TB6612_AIN1_GPIO_PORT->BSRR |= TB6612_AIN1_GPIO_PIN;
}
void bsp_gpio_tb6612_AIN1_disable(void)
{
    TB6612_AIN1_GPIO_PORT->BRR = TB6612_AIN1_GPIO_PIN;
}

void bsp_gpio_tb6612_AIN2_enable(void)
{
    TB6612_AIN2_GPIO_PORT->BSRR |= TB6612_AIN2_GPIO_PIN;
}
void bsp_gpio_tb6612_AIN2_disable(void)
{
    TB6612_AIN2_GPIO_PORT->BRR = TB6612_AIN2_GPIO_PIN;
}

void bsp_gpio_tb6612_BIN1_enable(void)
{
    TB6612_BIN1_GPIO_PORT->BSRR |= TB6612_BIN1_GPIO_PIN;
}
void bsp_gpio_tb6612_BIN1_disable(void)
{
    TB6612_BIN1_GPIO_PORT->BRR = TB6612_BIN1_GPIO_PIN;
}

void bsp_gpio_tb6612_BIN2_enable(void)
{
    TB6612_BIN2_GPIO_PORT->BSRR |= TB6612_BIN2_GPIO_PIN;
}
void bsp_gpio_tb6612_BIN2_disable(void)
{
    TB6612_BIN2_GPIO_PORT->BRR = TB6612_BIN2_GPIO_PIN;
}


void bsp_gpio_oled_write_scl(uint8_t x)
{
    GPIO_WriteBit(OLED_SCL_GPIO_PORT, OLED_SCL_GPIO_PIN, (BitAction)(x));
}

void bsp_gpio_oled_write_sda(uint8_t x)
{
    GPIO_WriteBit(OLED_SDA_GPIO_PORT, OLED_SDA_GPIO_PIN, (BitAction)(x));
}

void bsp_gpio_oled_init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
	
	// 开启 AFIO 时钟（必须）
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);

	// 禁用 JTAG 功能，保留 SWD 调试（PA13/PA14 仍可用）
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);

	
    RCC_APB2PeriphClockCmd(OLED_SCL_GPIO_RCC, ENABLE);
    RCC_APB2PeriphClockCmd(OLED_SDA_GPIO_RCC, ENABLE);
	
	
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Pin = OLED_SCL_GPIO_PIN;
 	GPIO_Init(OLED_SCL_GPIO_PORT, &GPIO_InitStructure);

	
	GPIO_InitStructure.GPIO_Pin = OLED_SDA_GPIO_PIN;
 	GPIO_Init(OLED_SDA_GPIO_PORT, &GPIO_InitStructure);
}
