#include <xc.h>
#include <stdint.h>

#define _XTAL_FREQ 16000000   // 16 MHz system clock
#define SINE_TABLE_SIZE 256   // Size of the sine lookup table
#define DESIRED_FREQUENCY 50  // Desired sine wave frequency in Hz
#define TIMER1_FREQ 12800     // 12.8 kHz timer interrupt frequency
#define MAX_AMPLITUDE 255     // Maximum amplitude (full scale)

const unsigned int sine_table[SINE_TABLE_SIZE] = {
    // Populate with 256 sine values scaled to 0-255
    // e.g., sine_table[i] = 128 + 127 * sin(2 * PI * i / SINE_TABLE_SIZE)
};

volatile float sineIndex = 0.0; // Fractional index for sine table
unsigned int phaseShift = SINE_TABLE_SIZE / 3;  // 120 degrees phase shift
unsigned char amplitude = MAX_AMPLITUDE;

void setupPWM()
{
    // Set PWM pins as output
    TRISC5 = 0;
    TRISC3 = 0;
    TRISA2 = 0;
    
    // Configure Timer2 for PWM frequency (20 kHz)
    PR2 = (_XTAL_FREQ / (PWM_FREQUENCY * 4)) - 1;  // Prescaler = 1
    T2CON = 0x04;  // Timer2 on, prescaler 1
    PWM1CON = 0xC0;
    PWM2CON = 0xC0;
    PWM3CON = 0xC0;
    
    // Start Timer2
    TMR2ON = 1;
}

void setPWMDutyCycle(unsigned char dutyA, unsigned char dutyB, unsigned char dutyC)
{
    // Set PWM1 Duty Cycle
    PWM1DCH = (dutyA & 0x03FC) >> 2;  // 8 MSB
    PWM1DCL = (dutyA & 0x0003) << 6;  // 2 LSB
    
    // Set PWM2 Duty Cycle
    PWM2DCH = (dutyB & 0x03FC) >> 2;
    PWM2DCL = (dutyB & 0x0003) << 6;
    
    // Set PWM3 Duty Cycle
    PWM3DCH = (dutyC & 0x03FC) >> 2;
    PWM3DCL = (dutyC & 0x0003) << 6;
}

void setupTimer1()
{
    // Configure Timer1 for the desired interrupt frequency (TIMER1_FREQ)
    T1CON = 0x00;          // Clear Timer1 control register
    T1CKPS1 = 0;           // Prescaler set to 1:1
    T1CKPS0 = 0;
    TMR1CS = 0;            // Select internal clock (Fosc/4)
    
    // Calculate preload value for Timer1 to overflow at TIMER1_FREQ
    unsigned int preload = 65536 - (_XTAL_FREQ / (4 * TIMER1_FREQ));
    TMR1 = preload;        // Preload Timer1 with the calculated value
    
    TMR1IF = 0;            // Clear Timer1 interrupt flag
    TMR1IE = 1;            // Enable Timer1 interrupt
    PEIE = 1;              // Enable peripheral interrupts
    GIE = 1;               // Enable global interrupts
    
    TMR1ON = 1;            // Start Timer1
}

void __interrupt() ISR()
{
    if (TMR1IF)  // Check if Timer1 caused the interrupt
    {
        TMR1IF = 0;  // Clear the interrupt flag
        
        // Reload Timer1 with the same preload value
        TMR1 = 65536 - (_XTAL_FREQ / (4 * TIMER1_FREQ));
        
        // Increment the sine table index with fractional step size
        sineIndex += 0.64;  // Adjust this step size to fine-tune synchronization
        if (sineIndex >= SINE_TABLE_SIZE) sineIndex -= SINE_TABLE_SIZE;
        
        // Calculate indices for each phase
        unsigned char dutyA = (sine_table[(unsigned int)sineIndex] * amplitude) / 255;
        unsigned char dutyB = (sine_table[((unsigned int)(sineIndex + phaseShift)) % SINE_TABLE_SIZE] * amplitude) / 255;
        unsigned char dutyC = (sine_table[((unsigned int)(sineIndex + 2 * phaseShift)) % SINE_TABLE_SIZE] * amplitude) / 255;

        // Set PWM duty cycles for the three phases
        setPWMDutyCycle(dutyA, dutyB, dutyC);
    }
}

void main()
{
    OSCCON = 0x7A;  // Set the internal oscillator to 16 MHz
    setupPWM();     // Initialize the PWM module
    setupTimer1();  // Initialize Timer1 for interrupt-based duty cycle updates

    // Main loop remains empty as all processing is done in the ISR
    while (1)
    {
        // No processing required in the main loop
    }
} find eror in this code and refind it