/*
 * spi_test_v1.c
 *
 *  Created on: Nov 20, 2023
 *      Author: nerod
 */

#include "driverlib.h"
#include "device.h"
#include "board.h"
#include <stdio.h>

// 添加您的其他必要的头文件
#define MAX_DAC_VALUE 4095  // 假设DAC是12位的
#define MIN_DAC_VALUE 0


//__interrupt void sciaTXFIFOISR(void);
//__interrupt void sciaRXFIFOISR(void);
uint16_t adcResult;
float temperature;
void SPI_GPIO_Init();
void spi_init();
void spi_TX(uint16_t data);
uint16_t calculate_DAC_value(float voltage);
short read_current_temperature();
void initADC();
void initADCSOC();
void initEPWM();
__interrupt void adcA1ISR();
//void initSCI(void);
void SCISendData(const char *string);

// PI Controller Variables
volatile short tsvo_pg, tsvo_ig;    // Proportional Gain (PG) and Integral Gain (IG)
volatile short tsvo_setpoint, tsvo_err, tsvo_out;
volatile long tsvo_acc, tsvo_mem;

void spi_initController() {
    Device_init();
    Device_initGPIO();
    //initSCI(); // 初始化SCI
    Interrupt_initModule(); //FOR TEST
    Interrupt_initVectorTable();//FOR TEST
    Interrupt_register(INT_ADCA1, &adcA1ISR);//FOR TEST

    initADC();
    initADCSOC(); // 初始化ADC
    initEPWM();   // 初始化ePWM

    ASysCtl_enableTemperatureSensor();//FOR TEST
    DEVICE_DELAY_US(500);//FOR TEST

    Interrupt_enable(INT_ADCA1);//FOR TEST

    EINT;
    ERTM;

    EPWM_enableADCTrigger(EPWM1_BASE, EPWM_SOC_A);//FOR TEST
    EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_UP);//FOR TEST

    DINT;
    SPI_GPIO_Init();
    spi_init();

    // 初始化PI控制器的参数
    tsvo_pg = 2000;  // Proportional Gain
    tsvo_ig = 200;   // Integral Gain
    tsvo_mem = 0;    // Integral memory initialization

    float target_temperature = 60.0;  // 目标温度60°C
    tsvo_setpoint = calculate_DAC_value(target_temperature);  // 设定点
}


void spi_updateController() {
//        short read_current_temperature = 59;
        short currentTemperature = read_current_temperature();

        tsvo_err = tsvo_setpoint - read_current_temperature();
        tsvo_acc = tsvo_err * tsvo_pg;
        tsvo_acc += tsvo_mem;

        tsvo_out = tsvo_acc >> 16;
        if (tsvo_out > MAX_DAC_VALUE) tsvo_out = MAX_DAC_VALUE;
        if (tsvo_out < MIN_DAC_VALUE) tsvo_out = MIN_DAC_VALUE;

        spi_TX(tsvo_out);

        tsvo_mem += tsvo_err * tsvo_ig;

        // 打印当前温度
        char tempStr[32];
//        sprintf(tempStr, "Current Temp: %d\r\n", currentTemperature);
        sprintf(tempStr, "Temperature: %d\r\n", currentTemperature);
//        sprintf(tempStr, "Temperature: 60\r\n");
        SCISendData(tempStr);
        //SCISendData("Hello World\r\n");
        // 检查SCI接收缓冲区
        //if(SCI_getRxFIFOStatus(SCIA_BASE) > SCI_FIFO_RX0) {
            //char receivedChar = SCI_readCharNonBlocking(SCIA_BASE);
            // 处理接收到的字符
            // 例如：回显接收到的字符
            //char echoStr[2] = {receivedChar, '\0'};
                //SCISendData(echoStr);
                //}
        DEVICE_DELAY_US(40000);
    }

void SPI_GPIO_Init() {
    // GPIO配置代码保持不变
}

void spi_init() {
    // SPI配置代码保持不变
}

void spi_TX(uint16_t data) {
    // SPI发送代码保持不变
}

uint16_t calculate_DAC_value(float voltage) {
    float maxVoltage = 3.7; // 最大电压为3.7伏特

    // 确保输入电压不超出范围
    if (voltage < 0) {
        voltage = 0;
    } else if (voltage > maxVoltage) {
        voltage = maxVoltage;
    }

    // 将电压值映射到DAC值
    uint16_t dacValue = (uint16_t)((voltage / maxVoltage) * MAX_DAC_VALUE);

    return dacValue;
}


short read_current_temperature() {
    // 触发ADC转换
    ADC_forceSOC(ADCA_BASE, ADC_SOC_NUMBER0);
    SCISendData("5.ADC conversion triggered\r\n");
    // 等待转换完成
    while(ADC_getInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1) == false) {
    }
    SCISendData("6.ADC conversion complete\r\n");
    // 读取ADC转换结果
    adcResult = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER0);
    char adcResultStr[50];
    sprintf(adcResultStr, "ADC Result: %d\r\n", adcResult);
    SCISendData(adcResultStr);
    // 将ADC结果转换为温度值
    temperature = ADC_getTemperatureC(adcResult, 3.0f);

    // 将温度值转换为DAC值
    return calculate_DAC_value(temperature);
}


void initADC()
{
//    SCISendData("1Starting ADC initialization\r\n");
    //
    // Set ADCDLK divider to /4
    //
    ADC_setPrescaler(ADCA_BASE, ADC_CLK_DIV_4_0);

    //
    // Set resolution and signal mode (see #defines above) and load
    // corresponding trims.
    //
    ADC_setMode(ADCA_BASE, ADC_RESOLUTION_12BIT, ADC_MODE_SINGLE_ENDED);

    //
    // Set pulse positions to late
    //
    ADC_setInterruptPulseMode(ADCA_BASE, ADC_PULSE_END_OF_CONV);

    //
    // Power up the ADC and then delay for 1 ms
    //
    ADC_enableConverter(ADCA_BASE);
    DEVICE_DELAY_US(1000);
    SCISendData("1.ADC initialization complete\r\n");
}


void initADCSOC() {
//    SCISendData("3Starting ADC SOC initialization\r\n");
    // ADC SOC配置代码
    // 从adc_ex3_temp_sensor.c文件中复制对应的配置代码
    ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_EPWM1_SOCA, ADC_CH_ADCIN13, 140);
//    char message[100];
//    sprintf(message, "ADC_SOC_NUMBER0: %d, ADC_TRIGGER_EPWM1_SOCA: %d, ADC_CH_ADCIN13: %d\r\n", ADC_SOC_NUMBER0, ADC_TRIGGER_EPWM1_SOCA, ADC_CH_ADCIN13);
//    SCISendData(message);
//    SCISendData("ADC SOC setup complete\r\n");
    ADC_setInterruptSource(ADCA_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER0);
//    SCISendData("ADC interrupt source set\r\n");
    ADC_enableInterrupt(ADCA_BASE, ADC_INT_NUMBER1);
//    SCISendData("ADC interrupt enabled\r\n");
    ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);
//    SCISendData("ADC interrupt status cleared\r\n");

    SCISendData("2.ADC SOC initialization complete\r\n");
}



void initEPWM() {
    // ePWM初始化代码
    // 从adc_ex3_temp_sensor.c文件中复制对应的配置代码
    EPWM_disableADCTrigger(EPWM1_BASE, EPWM_SOC_A);
    EPWM_setADCTriggerSource(EPWM1_BASE, EPWM_SOC_A, EPWM_SOC_TBCTR_U_CMPA);
    EPWM_setADCTriggerEventPrescale(EPWM1_BASE, EPWM_SOC_A, 1);
    EPWM_setCounterCompareValue(EPWM1_BASE, EPWM_COUNTER_COMPARE_A, 1000);
    EPWM_setTimeBasePeriod(EPWM1_BASE, 1999);
    EPWM_setClockPrescaler(EPWM1_BASE, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1);
    EPWM_setTimeBaseCounterMode(EPWM1_BASE, EPWM_COUNTER_MODE_STOP_FREEZE);
    SCISendData("3.EPWM initialization complete\r\n");
}

__interrupt void adcA1ISR()
{
    //
    // Read the raw result
    //
    SCISendData("ADC ISR triggered\r\n");
    adcResult = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER0);

    //
    // Convert the result to a temperature in degrees C
    //
    temperature = ADC_getTemperatureC(adcResult, 3.0f);

    //
    // Clear the interrupt flag
    //
    ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);

    //
    // Check if overflow has occurred
    //
    if(true == ADC_getInterruptOverflowStatus(ADCA_BASE, ADC_INT_NUMBER1))
    {
        ADC_clearInterruptOverflowStatus(ADCA_BASE, ADC_INT_NUMBER1);
        ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);
    }

    //
    // Acknowledge the interrupt
    //
    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
}


void SCISendData(const char *string) {
    // 使用FIFO发送数据
    while (*string != '\0') {
        SCI_writeCharBlockingFIFO(SCIA_BASE, *string++);
    }
}





