/*
 * @file ssd_brd.c
 */

#include "main.h"
#include "ssd_brd.h"
#include "mcp23008_gpio_expander.h"
#include "mcp9843.h"

extern s_mcp23008 hgpio_exp_ssd_16;
extern s_mcp23008 hgpio_exp_ssd_18;

extern mcp9843_dev_t ssd_temp1_hdl;
extern mcp9843_dev_t ssd_temp2_hdl;
extern mcp9843_dev_t ssd_temp3_hdl;
extern mcp9843_dev_t ssd_temp4_hdl;

ssd_temp_info ssd_info;

/*
 *  SSD_BOARD ssd card test function
 */
uint8_t ssd_board_id_test(uint8_t* ssd_brd_id)
{
    uint8_t sts = MCP23008_SCS;
    if(ssd_brd_id != NULL)
    {
        ssd_brd_gpio_exp_test_init(GPIO_EXP_MCP23008_SSD_U16);
        HAL_Delay(1);
        ssd_brd_gpio_exp_test_init(GPIO_EXP_MCP23008_SSD_U18);
        HAL_Delay(1);

        sts |= mcp23008_set_direction(&hgpio_exp_ssd_16,SSD_MUX_SW_IN1|SSD_MUX_SW_IN2|
                CON_MUX_SW_IN1|CON_MUX_SW_IN2|CLK_SSD_EN_A_B|
                ALL_MUX_ENABLE,MCP23008_GPIO_OUTPUT);
        if(sts == MCP23008_SCS)
        {
            printf("GPIO_EXPANDER = U16 PASS \n\r");
        }
        else
        {
            printf("GPIO_EXPANDER = U16 \033[1;31mFAIL \033[0m \n\n\r");
        }

        sts |= mcp23008_set_direction(&hgpio_exp_ssd_18,SSD_EN1|SSD_EN2|SSD_EN3|SSD_EN4|SSD1_SSD3_PD|A_SSD1_SSD2_PD|
                B_SSD1_SSD2_PD|SSD2_SSD4_PD,MCP23008_GPIO_OUTPUT);
        if(sts == MCP23008_SCS)
        {
            printf("GPIO_EXPANDER = U18 PASS \n\r");
        }
        else
        {
            printf("GPIO_EXPANDER = U18 \033[1;31mFAIL \033[0m \n\n\r");
        }

        sts |= mcp23008_write_pin(&hgpio_exp_ssd_16,SSD_MUX_SW_IN1|SSD_MUX_SW_IN2|CON_MUX_SW_IN1|
                CON_MUX_SW_IN2|CLK_SSD_EN_A_B|ALL_MUX_ENABLE,MCP23008_GPIO_LOW);

        sts |= mcp23008_write_pin(&hgpio_exp_ssd_18,SSD_EN1|SSD_EN2|SSD_EN3|SSD_EN4|SSD1_SSD3_PD|A_SSD1_SSD2_PD|
                B_SSD1_SSD2_PD|SSD2_SSD4_PD,MCP23008_GPIO_LOW);

        if(PAYLOAD_A_SSD_0 == *ssd_brd_id)
        {
            sts |= mcp23008_write_pin(&hgpio_exp_ssd_16,ALL_MUX_ENABLE,MCP23008_GPIO_HIGH);  /*!< U16 => GP7*/
            sts |= mcp23008_write_pin(&hgpio_exp_ssd_16,CLK_SSD_EN_A_B,MCP23008_GPIO_HIGH);  /*!< U16 => GP6*/
            sts |= mcp23008_write_pin(&hgpio_exp_ssd_16,SSD_MUX_SW_IN1,MCP23008_GPIO_HIGH);  /*!< U16 => GP0*/
            sts |= mcp23008_write_pin(&hgpio_exp_ssd_16,CON_MUX_SW_IN1,MCP23008_GPIO_HIGH);  /*!< U16 => GP4*/
            sts |= mcp23008_write_pin(&hgpio_exp_ssd_18,SSD_EN1,MCP23008_GPIO_HIGH);         /*!< U18 => GP0 */
            if(sts == MCP23008_SCS)
            {
                printf("PAYLOAD A SSD_0 BOOT SUCCESS \n\n\r");
            }
            else
            {
                printf("PAYLOAD A SSD_0 BOOT \033[1;31mFAIL \033[0m \n\n\r");
            }
        }

        else if(PAYLOAD_A_SSD_1 == *ssd_brd_id)
        {
            sts |= mcp23008_write_pin(&hgpio_exp_ssd_16,ALL_MUX_ENABLE,MCP23008_GPIO_HIGH);  /*!< U16 => GP7*/
            sts |= mcp23008_write_pin(&hgpio_exp_ssd_16,CLK_SSD_EN_A_B,MCP23008_GPIO_HIGH);  /*!< U16 => GP6*/
            sts |= mcp23008_write_pin(&hgpio_exp_ssd_16,SSD_MUX_SW_IN2,MCP23008_GPIO_HIGH);  /*!< U16 => GP1*/
            sts |= mcp23008_write_pin(&hgpio_exp_ssd_16,CON_MUX_SW_IN1,MCP23008_GPIO_LOW);   /*!< U16 => GP4*/
            sts |= mcp23008_write_pin(&hgpio_exp_ssd_18,SSD_EN2,MCP23008_GPIO_HIGH);         /*!< U18 => GP1 */
            if(sts == MCP23008_SCS)
            {
                printf("PAYLOAD A SSD_1 BOOT SUCCESS \n\n\r");
            }
            else
            {
                printf("PAYLOAD A SSD_1 BOOT \033[1;31mFAIL \033[0m \n\n\r");
            }
        }

        else if(PAYLOAD_B_SSD_0 == *ssd_brd_id)
        {
            sts |= mcp23008_write_pin(&hgpio_exp_ssd_16,ALL_MUX_ENABLE,MCP23008_GPIO_HIGH);  /*!< U16 => GP7*/
            sts |= mcp23008_write_pin(&hgpio_exp_ssd_16,CLK_SSD_EN_A_B,MCP23008_GPIO_LOW);   /*!< U16 => GP6*/
            sts |= mcp23008_write_pin(&hgpio_exp_ssd_16,SSD_MUX_SW_IN1,MCP23008_GPIO_LOW);   /*!< U16 => GP0*/
            sts |= mcp23008_write_pin(&hgpio_exp_ssd_16,CON_MUX_SW_IN2,MCP23008_GPIO_HIGH);  /*!< U16 => GP5 */
            sts |= mcp23008_write_pin(&hgpio_exp_ssd_18,SSD_EN1,MCP23008_GPIO_HIGH);         /*!< U18 => GP0 */
            if(sts == MCP23008_SCS)
            {
                printf("PAYLOAD B SSD_0 BOOT SUCCESS \n\n\r");
            }
            else
            {
                printf("PAYLOAD B SSD_0 BOOT \033[1;31mFAIL \033[0m \n\n\r");
            }

        }
        else if(PAYLOAD_B_SSD_1 == *ssd_brd_id)
        {
            sts |= mcp23008_write_pin(&hgpio_exp_ssd_16,ALL_MUX_ENABLE,MCP23008_GPIO_HIGH);  /*!< U16 => GP7*/
            sts |= mcp23008_write_pin(&hgpio_exp_ssd_16,CLK_SSD_EN_A_B,MCP23008_GPIO_LOW);   /*!< U16 => GP6*/
            sts |= mcp23008_write_pin(&hgpio_exp_ssd_16,SSD_MUX_SW_IN2,MCP23008_GPIO_LOW);   /*!< U16 => GP1*/
            sts |= mcp23008_write_pin(&hgpio_exp_ssd_16,CON_MUX_SW_IN2,MCP23008_GPIO_LOW);   /*!< U16 => GP5*/
            sts |= mcp23008_write_pin(&hgpio_exp_ssd_18,SSD_EN2,MCP23008_GPIO_HIGH);         /*!< U18 => GP1 */
            if(sts == MCP23008_SCS)
            {
                printf("PAYLOAD B SSD_1 BOOT SUCCESS \n\n\r");
            }
            else
            {
                printf("PAYLOAD B SSD_1 BOOT \033[1;31mFAIL \033[0m \n\n\r");
            }
        }

        else if(PAYLOAD_SSD_3 == *ssd_brd_id)
        {
            sts |= mcp23008_write_pin(&hgpio_exp_ssd_16,CON_MUX_SW_IN2,MCP23008_GPIO_HIGH);  /*!< U16 => GP5 */
            sts |= mcp23008_write_pin(&hgpio_exp_ssd_18,SSD_EN3,MCP23008_GPIO_HIGH);         /*!< U18 => GP2 */
            if(sts == MCP23008_SCS)
            {
                printf("PAYLOAD SSD SLOT 3 BOOT SUCCESS \n\n\r");
            }
            else
            {
                printf("PAYLOAD SSD SLOT 3 BOOT \033[1;31mFAIL \033[0m \n\n\r");
            }
        }
        else if(PAYLOAD_SSD_4 == *ssd_brd_id)
        {
            sts |= mcp23008_write_pin(&hgpio_exp_ssd_16,CON_MUX_SW_IN1,MCP23008_GPIO_HIGH);  /*!< U16 => GP4 */
            sts |= mcp23008_write_pin(&hgpio_exp_ssd_18,SSD_EN4,MCP23008_GPIO_HIGH);         /*!< U18 => GP3 */
            if(sts == MCP23008_SCS)
            {
                printf("PAYLOAD SSD SLOT 4 BOOT SUCCESS \n\n\r");
            }
            else
            {
                printf("PAYLOAD SSD SLOT 4 BOOT \033[1;31mFAIL \033[0m \n\n\r");
            }
        }
    }
    else
    {
        sts = MCP23008_NULL_PTR;
    }
    return sts;
}

/*
 *  SSD_BOARD gpio expander test function
 */
uint8_t ssd_board_gpio_exp_test()
{
    uint8_t sts = MCP23008_SCS;
    ssd_brd_gpio_exp_test_init(GPIO_EXP_MCP23008_SSD_U16);
    HAL_Delay(1);
    ssd_brd_gpio_exp_test_init(GPIO_EXP_MCP23008_SSD_U18);
    HAL_Delay(1);

    sts |= mcp23008_set_direction(&hgpio_exp_ssd_16,SSD_MUX_SW_IN1|SSD_MUX_SW_IN2|
            CON_MUX_SW_IN1|CON_MUX_SW_IN2|CLK_SSD_EN_A_B|
            ALL_MUX_ENABLE,MCP23008_GPIO_OUTPUT);
    sts |= mcp23008_self_test(&hgpio_exp_ssd_16);
    if(sts == MCP23008_SCS)
    {
        printf("GPIO_EXPANDER = U16 SELF TEST SUCCESS \n\n\r");
    }
    else
    {
        printf("GPIO_EXPANDER = U16 SELF TEST \033[1;31mFAIL \033[0m \n\n\r");
    }

    sts |= mcp23008_set_direction(&hgpio_exp_ssd_18,SSD_EN1|SSD_EN2|SSD_EN3|SSD_EN4|SSD1_SSD3_PD|A_SSD1_SSD2_PD|
            B_SSD1_SSD2_PD|SSD2_SSD4_PD,MCP23008_GPIO_OUTPUT);
    sts |= mcp23008_self_test(&hgpio_exp_ssd_18);
    if(sts == MCP23008_SCS)
    {
        printf("GPIO_EXPANDER = U18 SELF TEST SUCCESS \n\n\r");
    }
    else
    {
        printf("GPIO_EXPANDER = U18 SELF TEST \033[1;31mFAIL \033[0m \n\n\r");
        printf("\033[1;31mI2C COMMUNICATION FAIL\033[0m \n\n\r");
    }
    return sts;
}

/*
 * SSD BOARD get temperature function.
 */
uint8_t ssd_brd_get_tempreature(ssd_temp_info *temperature)
{
    uint8_t sts = MCP9843_ERR;
    if(temperature != NULL)
    {
        temp_sensor_init(TEMP_SENSOR_MCP9843_SSD_U23);
        HAL_Delay(1);
        sts = mcp9843_gettemperature(&ssd_temp1_hdl,&temperature->ssd_temp1);

        temp_sensor_init(TEMP_SENSOR_MCP9843_SSD_U24);
        HAL_Delay(1);
        sts |= mcp9843_gettemperature(&ssd_temp2_hdl,&temperature->ssd_temp2);

        temp_sensor_init(TEMP_SENSOR_MCP9843_SSD_U26);
        HAL_Delay(1);
        sts |= mcp9843_gettemperature(&ssd_temp3_hdl,&temperature->ssd_temp3);

        temp_sensor_init(TEMP_SENSOR_MCP9843_SSD_U27);
        HAL_Delay(1);
        sts |= mcp9843_gettemperature(&ssd_temp4_hdl,&temperature->ssd_temp4);
    }
    else
    {
        sts = MCP9843_E_NULL_PTR;
    }
    return sts;
}
