
//##############################################################################
//    filename:        MCP4822.c
// ##############################################################################
//    LCD library for MCP4822 SPI DAC
//##############################################################################
//      Author:            	P.Prosser
//      Company:        	
//      Adapted:            AS
//      Revision:           0.0 (for XC32)
//      Date:         	    Aug 2024
//     	Compiler            XC32 
//      MPLAB X             
//      MCC                 
//##############################################################################


#include "MCP4822.h"
#include <assert.h>
#include "Inductor_Tester.h"
#include "definitions.h"
#include <xc.h>            
#include <sys/attribs.h> 
//#############################################################################
//
//  MCP4822 is a dual 12 bit Voltage output DAC
//  Internal voltage reference 2.048 Volts DC when operating from 3.3V (can set to 4.096)
//  Variants
//      - 4802 = 8 bit
//      - 4812 = 10 bit
//      - 4822 = 12 bit
//
//  Data Wrt:
//      - CS low
//      - Clock idle low
//      - Data in MSB first, rising edge of clock latches
//      - LDAC idle high
//      - LDAC latches both registers data through on high to low transition
//      - We update one at a time so leave low
//  Control Word
//      - Bit 15 = DAC Select: 0 = DAC A, 1 = DAC B
//      - Bit 14 = Dont care 
//      - Bit 13 = GA_L: 1 = gain = 1, 0 = gain = 2 
//      - Bit 12 = SHDN_L: 0 = Shut Down, 1 = the DAC is active
//      - Bit 11-0 = Voltage word  (for 10 and 8 bit devices, lower bits are X)
//#############################################################################
void MCP4822_setValue(int Output_Sel, int Gain_L, int Shut_Down_L, int Value_To_Write) {
    uint8_t data[2];

    if (Value_To_Write < 0)
        Value_To_Write = 0;
    else if (Value_To_Write > DAC_Full_Scale)
        Value_To_Write = DAC_Full_Scale;
                
    MCP4822_CS_Assert;
//    MCP4822_LDAC_Clear;

    data[0] = (Output_Sel << 7) | (Gain_L << 5) | (Shut_Down_L << 4) | ((Value_To_Write >> 8) & 0xF);
    data[1] = Value_To_Write & 0xFF;

    SPI1_Write(data, 2);

    MCP4822_LDAC_Assert;
    CORETIMER_DelayUs(DAC_Time_us);
//    MCP4822_LDAC_Clear;
    CORETIMER_DelayUs(DAC_Time_us);
    MCP4822_CS_Clear;
    /* and settle*/
    CORETIMER_DelayUs(MCP4822_Settle_Us);
}

//#############################################################################
//
//  MCP4822 is a dual 12 bit Voltage output DAC
//  Internal voltage reference 2.048 Volts DC when operating from 3.3V (can set to 4.096)
//
//  Control Word
//      - DAC Select: 0 = DAC A, 1 = DAC B
//      - Fix Gain = 1 for this function
//      - Voltage 
//#############################################################################
void MCP4822_setVoltage(int Channel, float Voltage) {
    int rawVal;

    /* just to be sure */
    if (Voltage < 0)
        Voltage = 0;
    else if (Voltage > (float)Max_Voltage)
        Voltage = Max_Voltage;

    rawVal = (int) ((Voltage / (float)Max_Voltage) * ((1<<(NumBits))-1)); 

    MCP4822_setValue(Channel, MCP4822_Gain_1, MCP4822_Active, rawVal);
}


//#############################################################################
//
//  MCP4822 is a dual 12 bit Voltage output DAC
//  Internal voltage reference 2.048 Volts DC when operating from 3.3V (can set to 4.096)
//
//  Control Word
//      - DAC Select: 0 = DAC A, 1 = DAC B
//      - Fix Gain = 2 for this function
//      - Voltage 
//#############################################################################
void MCP4822_set_DAC_VAL(int Channel, int Value) {
    int rawVal;

    /* just to be sure */
    if (Value < 0)
        Value = 0;
    else if (Value > DAC_Full_Scale)
        Value = DAC_Full_Scale;

    rawVal = Value; 

    MCP4822_setValue(Channel, MCP4822_Gain_1, MCP4822_Active, rawVal);
}


//#############################################################################
//
//  MCP4822 is a dual 12 bit Voltage output DAC
//  Internal voltage reference 2.048 Volts DC when operating from 3.3V (can set to 4.096)
//
//  This function sets it up for operation
//      - DAC Select: 0 = DAC A, 1 = DAC B
//      - Fix Gain = 2 for this function
//      - Voltage = 0V
//#############################################################################
void MCP4822_Init() {
    int rawVal;

    rawVal = 0; // Digital Value for DAC

    MCP4822_setValue(MCP4822_Channel_A, MCP4822_Gain_1, MCP4822_Active, rawVal);
    MCP4822_setValue(MCP4822_Channel_B, MCP4822_Gain_1, MCP4822_Active, rawVal);
}

//#############################################################################
//
//  MCP4822 is a dual 12 bit Voltage output DAC
//  Internal voltage reference 2.048 Volts DC when operating from 3.3V (can set to 4.096)
//
//  This function sets it up for operation
//      - DAC Select: 0 = DAC A, 1 = DAC B
//      - Fix Gain = 2 for this function
//      - Voltage = 0V
//#############################################################################
void MCP4822_Shut_Down() {
    int rawVal;

    rawVal = 0; // Digital Value for DAC

    MCP4822_setValue(MCP4822_Channel_A, MCP4822_Gain_1, MCP4822_Active, rawVal);
    MCP4822_setValue(MCP4822_Channel_B, MCP4822_Gain_1, MCP4822_InActive, rawVal);
}
