/**
 * @Author: 李建
 * @Date: 2024/8/13 10:38
 * Description: 
 * Copyright: Copyright (©) 2024 永续绿建. All rights reserved.
 */

#include "slave_485.h"
#include "mb.h"
#include "cmsis_os2.h"
#include "fan.h"
#include "tim.h"
#include "usart.h"
#include "flash.h"
#include "iwdg.h"

osThreadAttr_t task_attributes = {
        .name = "slave_485",
        .stack_size = 128 * 6,
        .priority = (osPriority_t) osPriorityAboveNormal,
};
USHORT usSRegHoldStart = S_REG_HOLDING_START;
USHORT usSRegHoldBuf[S_REG_HOLDING_NREGS] = {0};

static uint8_t wire_controller_acc = 0; // 线控器通讯累加器
eMBRTUSlaveObj wireControllerSlaveObj;
uint8_t test = 0;


static eMBErrorCode RegInputCB(UCHAR *pucRegBuffer, USHORT usAddress, USHORT usNRegs) {
    return MB_ENOERR;
}
static eMBErrorCode RegHoldingCB(UCHAR *pucRegBuffer, USHORT usAddress,
                                 USHORT usNRegs, eMBRegisterMode eMode) {
    eMBErrorCode eStatus = MB_ENOERR;
    USHORT iRegIndex;
    USHORT *pusRegHoldingBuf;
    USHORT REG_HOLDING_START;
    USHORT REG_HOLDING_NREGS;
    USHORT usRegHoldStart;
    pusRegHoldingBuf = usSRegHoldBuf;
    REG_HOLDING_START =S_REG_HOLDING_START;
    REG_HOLDING_NREGS = S_REG_HOLDING_NREGS;
    usRegHoldStart = usSRegHoldStart;

    /* it already plus one in modbus function method. */
    usAddress--;

    if ((usAddress >= REG_HOLDING_START)
        && (usAddress + usNRegs <= REG_HOLDING_START + REG_HOLDING_NREGS)) {
        iRegIndex = usAddress - usRegHoldStart;
        switch (eMode) {
            /* read current register values from the protocol stack. */
            case MB_REG_READ:
                while (usNRegs > 0) {
                    *pucRegBuffer++ = (UCHAR) (pusRegHoldingBuf[iRegIndex] >> 8);
                    *pucRegBuffer++ = (UCHAR) (pusRegHoldingBuf[iRegIndex] & 0xFF);
                    iRegIndex++;
                    usNRegs--;
                }
                break;

                /* write current register values with new values from the protocol stack. */
            case MB_REG_WRITE:
                while (usNRegs > 0) {
//                    if(iRegIndex==0)
//                    {
//                        set_reg_value(FAN1_LEVEL_REG_ADDRESS,0);
//                        set_reg_value(FAN2_LEVEL_REG_ADDRESS,0);
//                        set_reg_value(FAN3_LEVEL_REG_ADDRESS,0);
//                        set_reg_value(FAN4_LEVEL_REG_ADDRESS,0);
//                        set_reg_value(FAN5_LEVEL_REG_ADDRESS,0);
//
//                    }
                    pusRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;
                    pusRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
                    iRegIndex++;
                    usNRegs--;
                }
                break;
        }
    } else {
        eStatus = MB_ENOREG;
    }
    wire_controller_acc = 0;
    return eStatus;
}

/**
 * Modbus slave coils callback function.
 *
 * @param pucRegBuffer coils buffer
 * @param usAddress coils address
 * @param usNCoils coils number
 * @param eMode read or write
 *
 * @return result
 */
eMBErrorCode RegCoilsCB(UCHAR *pucRegBuffer, USHORT usAddress,
                        USHORT usNCoils, eMBRegisterMode eMode) {
    return MB_ENOERR;
}

/**
 * Modbus slave discrete callback function.
 *
 * @param pucRegBuffer discrete buffer
 * @param usAddress discrete address
 * @param usNDiscrete discrete number
 *
 * @return result
 */
eMBErrorCode RegDiscreteCB(UCHAR *pucRegBuffer, USHORT usAddress, USHORT usNDiscrete) {
    return MB_ENOERR;
}


void set_reg_value(uint8_t reg_address, uint16_t reg_value) {
    usSRegHoldBuf[reg_address] = reg_value;
}

void get_reg_value(uint8_t reg_address, uint16_t *reg_value) {
    *reg_value = usSRegHoldBuf[reg_address];
}
uint16_t get_reg_value2(uint8_t reg_address) {
    return usSRegHoldBuf[reg_address];
}

_Noreturn void reg_check_task(void *pv) {
    uint16_t power=0, fan_level=0,dipnum=0;
    for (;;) {
        dipnum=read_dip5();//0 1 2 ,
        get_reg_value(POWER_REG_ADDRESS,&power);
        if(power==0)
        {
            for(int i=0;i<dipnum;i++)
            {
                fan_control(PWMComParam[i],0);
                HAL_TIM_PWM_Stop(PWMComParam[i].htim, PWMComParam[i].timChannel);
            }
        }else {
            for(int i=0;i<dipnum;i++)
            {
                get_reg_value(FAN1_LEVEL_REG_ADDRESS+dipBuf[i],&fan_level);
                if(fan_level<=0)
                {
                    fan_control(PWMComParam[i],0);
                    HAL_TIM_PWM_Stop(PWMComParam[i].htim, PWMComParam[i].timChannel);
                }else{
                    HAL_TIM_PWM_Start(PWMComParam[i].htim, PWMComParam[i].timChannel);
                    fan_control(PWMComParam[i],40+(fan_level/9));
                }

            }
        }

        HAL_IWDG_Refresh(&hiwdg);
        osDelay(500);
    }
}


_Noreturn void slave_485_task(void *pvParameters) {
    // 回调配置
    mb_reg_callback_t calls = {
            .eMbRegHoldingCb = RegHoldingCB,
            .eMbRegInputCb = RegInputCB,
    };
    wireControllerSlaveObj.eMode = MB_RTU;
    wireControllerSlaveObj.ucSlaveAddress = (uint8_t) pvParameters;
    wireControllerSlaveObj.ulBaudRate = 9600;
    wireControllerSlaveObj.eParity = MB_PAR_NONE;
    wireControllerSlaveObj.pTimHandle = htim2;
    wireControllerSlaveObj.pUartHandle = huart2;
    wireControllerSlaveObj.enPort = GPIOA;
    wireControllerSlaveObj.enPin = GPIO_PIN_1;
    wireControllerSlaveObj.callback = &calls;

    eMBInit(&wireControllerSlaveObj);
    eMBEnable(&wireControllerSlaveObj);
    for (;;) {
        eMBPoll(&wireControllerSlaveObj);
        osDelay(5);
    }
}

/**
 * 初始化485从站
 */
void slave_485_init(uint8_t address) {
    osThreadNew(slave_485_task, (void *) address, &task_attributes);
    osThreadNew(reg_check_task, NULL, &task_attributes);
}
