/*
 * cs5460a.c
 *
 *  Created on: May 21, 2025
 *      Author: electro.design5
 */

#include "cs5460a.h"
#include "spi.h"
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "usart.h"

extern SPI_HandleTypeDef hspi1;

#define VOLTAGE_SCALE_FACTOR    0.00012207f
#define CURRENT_SCALE_FACTOR    0.000061035f
#define POWER_SCALE_FACTOR      0.000030517f

//void CS5460A_Reset(void)		// SPI RESET PIN
//{
//    HAL_GPIO_WritePin(CS5460A_CS_GPIO_Port, CS5460A_CS_Pin, GPIO_PIN_RESET);
//    HAL_Delay(20);
//    HAL_GPIO_WritePin(CS5460A_CS_GPIO_Port, CS5460A_CS_Pin, GPIO_PIN_SET);
//    HAL_Delay(100);
//}

void CS5460A_Init(void)
{
//    CS5460A_Reset();

    // Power up command
    CS5460A_WriteRegister(CS5460A_CFG_POWER_UP, 0);

    // Configure gain settings
    CS5460A_WriteRegister(CS5460A_CFG_GAIN0,
                         (CS5460A_CFG_GAIN0 << 24) |
                         (CS5460A_CFG_GAIN1 << 16) |
                         (CS5460A_CFG_GAIN2 << 8) |
                         CS5460A_CFG_GAIN3);

    // Start continuous conversion
    CS5460A_WriteRegister(CS5460A_START_CONV, 0);
}

void CS5460A_WriteRegister(uint8_t reg, uint32_t value)
{
    uint8_t tx_buffer[5];
    uint8_t rx_buffer[5];

    tx_buffer[0] = reg;
    tx_buffer[1] = (value >> 24) & 0xFF;
    tx_buffer[2] = (value >> 16) & 0xFF;
    tx_buffer[3] = (value >> 8) & 0xFF;
    tx_buffer[4] = value & 0xFF;

    HAL_GPIO_WritePin(CS5460A_CS_GPIO_Port, CS5460A_CS_Pin, GPIO_PIN_RESET);
    HAL_SPI_TransmitReceive(&hspi1, tx_buffer, rx_buffer, 5, HAL_MAX_DELAY);
    HAL_GPIO_WritePin(CS5460A_CS_GPIO_Port, CS5460A_CS_Pin, GPIO_PIN_SET);
}

uint32_t CS5460A_ReadRegister(uint8_t reg)
{
    uint8_t tx_buffer[5] = {0};
    uint8_t rx_buffer[5] = {0};

    tx_buffer[0] = reg;

    HAL_GPIO_WritePin(CS5460A_CS_GPIO_Port, CS5460A_CS_Pin, GPIO_PIN_RESET);
    HAL_SPI_TransmitReceive(&hspi1, tx_buffer, rx_buffer, 5, HAL_MAX_DELAY);
    HAL_GPIO_WritePin(CS5460A_CS_GPIO_Port, CS5460A_CS_Pin, GPIO_PIN_SET);

    return ((uint32_t)rx_buffer[1] << 24) |
           ((uint32_t)rx_buffer[2] << 16) |
           ((uint32_t)rx_buffer[3] << 8) |
           rx_buffer[4];
}

float CS5460A_ReadVoltage(void)
{
    uint32_t raw = CS5460A_ReadRegister(CS5460A_RMS_VOLTAGE);
    return (float)raw * VOLTAGE_SCALE_FACTOR;
}

float CS5460A_ReadCurrent(void)
{
    uint32_t raw = CS5460A_ReadRegister(CS5460A_RMS_CURRENT);
    return (float)raw * CURRENT_SCALE_FACTOR;
}

float CS5460A_ReadPower(void)
{
    uint32_t raw = CS5460A_ReadRegister(CS5460A_TRUE_POWER);

    if (raw & 0x00800000) {
        raw |= 0xFF000000; // Sign extend
        return (float)((int32_t)raw) * POWER_SCALE_FACTOR;
    }
    return (float)raw * POWER_SCALE_FACTOR;
}
