/*
 * @Author: mypx
 * @Email: mypx_coder@163.com
 * @Date: 2025-06-19 12:29:17
 * @LastEditors: mypx mypx_coder@163.com
 * @Description: 
 */
#include "bsp_misc.h"
#include "ad7793.h"
#include "adc.h"
#include "dma.h"
#include "et_log.h"
#include "gpio.h"
#include "i2c.h"
#include "rtdef.h"
#include "rthw.h"

#include "usart.h"
#include "tim.h"

#include <stdbool.h>
#include <string.h>

#define AT24C128_I2C_ADDR 0xA0

void bsp_system_led_toggle(void)
{
    HAL_GPIO_TogglePin(PE5_LED1_GPIO_Port, PE5_LED1_Pin);
}

void bsp_system_led_on(void)
{
    HAL_GPIO_WritePin(PE5_LED1_GPIO_Port, PE5_LED1_Pin, GPIO_PIN_SET);
}

void bsp_system_led_off(void)
{
    HAL_GPIO_WritePin(PE5_LED1_GPIO_Port, PE5_LED1_Pin, GPIO_PIN_RESET);
}

void bsp_error_led_on(void)
{
    HAL_GPIO_WritePin(PE6_LED2_GPIO_Port, PE6_LED2_Pin, GPIO_PIN_SET);
}

void bsp_error_led_off(void)
{
    HAL_GPIO_WritePin(PE6_LED2_GPIO_Port, PE6_LED2_Pin, GPIO_PIN_RESET);
}

void bsp_error_led_toggle(void)
{
    HAL_GPIO_TogglePin(PE6_LED2_GPIO_Port, PE6_LED2_Pin);
}

int bsp_i2c_write_bytes(uint16_t dev_addr, uint16_t mem_addr, uint8_t *data, uint16_t len)
{
    HAL_StatusTypeDef res;

    // AT24C128 单页为 64 字节，写入时建议不要跨页，否则需要拆包
    if (len > 64)
        return HAL_ERROR;

    res = HAL_I2C_Mem_Write(&hi2c2, dev_addr, mem_addr, I2C_MEMADD_SIZE_16BIT, data, len, HAL_MAX_DELAY);

    HAL_Delay(5); // EEPROM写入周期，典型为5ms

    return res;
}

int bsp_i2c_read_bytes(uint16_t dev_addr, uint16_t mem_addr, uint8_t *data, uint16_t len)
{
    return HAL_I2C_Mem_Read(&hi2c2, dev_addr, mem_addr, I2C_MEMADD_SIZE_16BIT, data, len, HAL_MAX_DELAY);
}


void bsp_uart_print_send(const uint8_t *data, uint16_t len)
{
#ifdef USING_RTT_AS_CONSOLE
#warning "USING_RTT_AS_CONSOLE defined, use uart1 as hmi interface"

#else
    HAL_UART_Transmit(&huart1, data, len, 1000);
#endif
}

float bsp_sampling_tim_get_freq(void)
{
    uint32_t pclk1 = HAL_RCC_GetPCLK1Freq();
    uint32_t timer_clk;

    // 获取APB1预分频系数（来自RCC配置寄存器）
    uint32_t apb1_prescaler = (RCC->CFGR & RCC_CFGR_PPRE1) >> RCC_CFGR_PPRE1_Pos;

    // 根据APB1预分频计算定时器时钟源
    if (apb1_prescaler == RCC_HCLK_DIV1)
    {
        // APB1预分频=1，定时器时钟=PCLK1
        timer_clk = pclk1;
    }
    else
    {
        // APB1预分频>1，定时器时钟=2×PCLK1
        timer_clk = pclk1 * 2;
    }

    // 计算定时器计数频率（经过PSC分频后）
    uint32_t counter_freq = timer_clk / (COLLECT_TIM.Init.Prescaler + 1);

    // 计算最终输出频率（周期触发频率 = 计数频率 / (Period + 1)）
    // 注意：如果是向上计数模式，完整周期是从0到Period，共Period+1个计数
    return (float)counter_freq / (COLLECT_TIM.Init.Period + 1);
}

int pm_board_init(void)
{
    MX_GPIO_Init();
    // MX_USART1_UART_Init();

    return 0;
}
