/* ---------------------------------------------------------------------------
 * calibrateaio.c                                       (c) 2008 Micro-key bv
 * ---------------------------------------------------------------------------
 * Micro-key bv
 * Industrieweg 28, 9804 TG Noordhorn
 * Postbus 92, 9800 AB Zuidhorn
 * The Netherlands
 * Tel: +31 594 503020
 * Fax: +31 594 505825
 * Email: support@microkey.nl  
 * Web: www.microkey.nl
 * ---------------------------------------------------------------------------
 * Description: 
 * ---------------------------------------------------------------------------
 * Version(s):  0.1, Mei 22, 2008, MMi
 *                   Creation.
 * ---------------------------------------------------------------------------
 */


/* APPLICATION NOTES:
 * Voltage Input Calibration:   All Inputs need to be connected to the defined,
 *                              preset Voltage Value (e.g. 10 V).
 * 
 * Voltage Output Calibration:  Output 0-3 need to be connected to own Inputs
 *                              0-3.
 * 
 * Current Input Calibration:   All Inputs need to be connected to the defined,
 *                              preset Current Value (e.g. 20 mA per channel)
 * 
 * Current Output Calibration:  Output 0-3 need to be connected to own Inputs
 *                              0-3. All other Connections must be removed.
 */


/* ---------------------------------------------------------------------------
 * System include files
 * ---------------------------------------------------------------------------
 */
#include <stdlib.h>

#include "lpc23xx.h"
#include "types.h"

/* FreeRTOS includes */
#include "FreeRTOS.h"
#include "Task.h"
#include "semphr.h"
/* ---------------------------------------------------------------------------
 * Application include files
 * ---------------------------------------------------------------------------
 */
#include "calibrateaio.h"
#include "adc.h"
#include "dac.h"
#include "dio.h"
#include "eeprom.h"
#include "ssp0.h"
#include "BusProtocol.h"
#include "serial.h"
#include "SerOut.h"

/* ---------------------------------------------------------------------------
 * Local constant and macro definitions
 * ---------------------------------------------------------------------------
 */
#define NumberOfOutputChannels  maxDAC_Channels /* See dac.h                */ 
#define NumberOfInputChannels   maxADC_Channels /* See adc.h                */

#define MaximumCurrent          20000       /* Maximum driveable Current    */
#define MaximumVoltage          10000       /* Maximum driveable Voltage    */

/* Addresses, where correction factors are stored in the EEPROM             */
#define VI_Address              0x00    /* Adress of Voltage Input Factor   */
#define CI_Address              0x10    /* Adress of Current Input Factor   */
#define VO_Address              0x20    /* Adress of Voltage Output Factor  */
// \MARK NEW PINSETTINGS FOR TESTER (2)
#if (PINSET_TESTER == 2)
#define CO_Address              0x30    /* Adress of Current Output Factor  */
#else
#define CO_Address              0x28    /* Adress of Current Output Factor  */
#endif

#define VI_ByteLength           0x10    /* Length of VI Entry in Bytes      */
#define CI_ByteLength           0x10    /* Length of CI Entry in Bytes      */
// \MARK NEW PINSETTINGS FOR TESTER (2)
#if (PINSET_TESTER == 2)
#define VO_ByteLength           0x10    /* Length of VO Entry in Bytes      */
#define CO_ByteLength           0x10    /* Length of CO Entry in Bytes      */
#else
#define VO_ByteLength           0x08    /* Length of VO Entry in Bytes      */
#define CO_ByteLength           0x08    /* Length of CO Entry in Bytes      */
#endif

// \MARK NEW PINSETTINGS FOR TESTER (2)
#if (PINSET_TESTER == 2)
#define ident_VoltageInput      0x40    /* Stat of Volt. Input Calibration  */
#define ident_VoltageOutput     0x41    /* Stat of Volt. Output Calibration */
#define ident_CurrentInput      0x42    /* Stat of Curr. Input Calibration  */
#define ident_CurrentOutput     0x43    /* Stat of Curr. Output Calibration */
#else
#define ident_VoltageInput      0x30    /* Stat of Volt. Input Calibration  */
#define ident_VoltageOutput     0x31    /* Stat of Volt. Output Calibration */
#define ident_CurrentInput      0x32    /* Stat of Curr. Input Calibration  */
#define ident_CurrentOutput     0x33    /* Stat of Curr. Output Calibration */
#endif

#define DAC_CHANNEL_A          (0x8000) 
#define DAC_CHANNEL_B          (0x0000) 


#define spiWriteBuffer        	ssp0WriteBuffer
#define spiReadBuffer         	ssp0ReadBuffer


/* ---------------------------------------------------------------------------
 * Global variable definitions
 * ---------------------------------------------------------------------------
 */
/* External Arrays where system stores calibration values for temporary use */
extern UINT16 OutputVoltageCorrection[NumberOfOutputChannels];
extern UINT16 OutputCurrentCorrection[NumberOfOutputChannels];
extern UINT16 InputVoltageCorrection[NumberOfInputChannels];
extern UINT16 InputCurrentCorrection[NumberOfInputChannels];


/* ---------------------------------------------------------------------------
 * Local variable definitions
 * ---------------------------------------------------------------------------
 */


/* ---------------------------------------------------------------------------
 * Local function definitions
 * ---------------------------------------------------------------------------
 */

void killStats (void)
{
    eepromWrite(ident_VoltageInput, 0x00);  /* Write 0x00 to EEPROM Adress  */
    eepromWrite(ident_VoltageOutput, 0x00);
    eepromWrite(ident_CurrentInput, 0x00);
    eepromWrite(ident_CurrentOutput, 0x00);    
}

void defaultStats (void)
{
    eepromWrite(ident_VoltageInput, ident_default); /* Write DEFAULT Value  */
    eepromWrite(ident_VoltageOutput, ident_default);
    eepromWrite(ident_CurrentInput, ident_default);
    eepromWrite(ident_CurrentOutput, ident_default);    
}

void calibratedStats (void)
{
    eepromWrite(ident_VoltageInput, ident_calibrated); /* Write CALIBRATED  */
    eepromWrite(ident_VoltageOutput, ident_calibrated);
    eepromWrite(ident_CurrentInput, ident_calibrated);
    eepromWrite(ident_CurrentOutput, ident_calibrated);    
}


void calibrationInit (void)
{
    UINT8 volin;
    UINT8 volout;
    UINT8 curin;
    UINT8 curout;

    /* Readout Stats from EEPROM                                            */
    eepromRead(ident_VoltageInput, &volin);
    eepromRead(ident_VoltageOutput, &volout);
    eepromRead(ident_CurrentInput, &curin);
    eepromRead(ident_CurrentOutput, &curout);

    /* If a Stat is not defined, delete the Values and reset them to DEFAULT*/
    if ((volin != ident_default) && (volin != ident_calibrated))
        {
        deleteCorrectionValue(VoltageInput); 
        loadCorrectionValue_defaultTarget(VoltageInput);
        }
    if ((volout != ident_default) && (volout != ident_calibrated))
        {
        deleteCorrectionValue(VoltageOutput); 
        loadCorrectionValue_defaultTarget(VoltageOutput);
        }
    if ((curin != ident_default) && (curin != ident_calibrated))
        {
        deleteCorrectionValue(CurrentInput); 
        loadCorrectionValue_defaultTarget(CurrentInput);
        }
    if ((curout != ident_default) && (curout != ident_calibrated))
        {
        deleteCorrectionValue(CurrentOutput); 
        loadCorrectionValue_defaultTarget(CurrentOutput);
        }
    
}

UINT8 returnCalibrationStatus (daadCorrection_t correctionType)
{
    UINT8 readback;

    /* read corresponding Stats from EEPROM                                 */
    switch (correctionType)
        {
        case VoltageInput: eepromRead(ident_VoltageInput, &readback);
        break;
        case VoltageOutput: eepromRead(ident_VoltageOutput, &readback);
        break;
        case CurrentInput: eepromRead(ident_CurrentInput, &readback);
        break;
        case CurrentOutput: eepromRead(ident_CurrentOutput, &readback);
        break;
        }
    
    return (readback);                      /* Return read Value to Caller  */
}


UINT8 showLocalCalibrationStatus (INT32 correctionType)
{
    UINT8 readback;
    
    readback = returnCalibrationStatus (correctionType);
    
    if (readback & ident_default)
        {
        sendString (SerOutPort, FALSE, importantMessage,
                "Values are in DEFAULT Mode", Dummy, Dummy);
        }
    else if (readback & ident_calibrated)
        {
        sendString (SerOutPort, FALSE, importantMessage,
                "Values are in CALIBRATED Mode", Dummy, Dummy);
        }
    else
        {
        sendString (SerOutPort, FALSE, importantMessage,
                "NO VALID VALUES IN EEPROM", Dummy, Dummy);
        }
    
    return (readback);
}



/* Calibration of Analogue Inputs in Voltage Mode:
 * Attach Voltage Supply with Calibration Value (recommended: 10,000 V) to
 * the Input(s) you want to calibrate. Software will read out the real,
 * digital Value from the ADC and uses this as Point of Calibration. Value
 * will be stored in EEPROM (Adresses see above).
 */

void calibrateVoltageInput(void)
{
    /* Local Variable Declaration                                           */
    UINT32 adcResult;
    UINT32 loopcnt;
    UINT16 VoltageInputCorrection[8];
    UINT8 spiAdcCommand[3];
    UINT8 spiAdcResponse[3];
     
    /* Delete/Reset old Calibration Values                                  */
    deleteCorrectionValue (VoltageInput);
    /* Load default Calibration Values from EEPROM                          */
    loadCorrectionValue(InputVoltageCorrection, VoltageInput);
    
    adcModeAll (adcVOLTAGE);            /* Set ADC to Mode VOLTAGE          */
    
    loopcnt = 0;
    
    do                                  /* Do single for every Input        */
        {
        /* Reset readback Variables                                         */
        adcResult = 0;
        spiAdcResponse[0] = 0;
        spiAdcResponse[1] = 0;
        spiAdcResponse[2] = 0;
        
        /* Build SPI Command                                                */
        spiAdcCommand[0] = 0x06; 
        spiAdcCommand[0] |= (loopcnt >> 2) & 0x01;
        spiAdcCommand[1] = (loopcnt << 6);
        spiAdcCommand[2] = 0;
        
        FIO1CLR = BIT( 25 );            /* Enable Chipselect of ADC         */
        
        spiWriteBuffer( spiAdcCommand, 3 ); /* send Command                 */
        spiReadBuffer( spiAdcResponse, 3 ); /* receive Response             */
        
        FIO1SET = BIT( 25 );            /* Disbale Chipselect of ADC        */
        
        /* Build 12 Bit Result out of 8 and 4 Bit readBack                  */
        adcResult = (UINT16)(spiAdcResponse[1] & 0x0F) << 8;
        adcResult |= (UINT16)spiAdcResponse[2];

        
        /* Store result in Array for Voltage Input Correction               */
        VoltageInputCorrection[loopcnt] = adcResult;
        
        loopcnt++;
        } while (loopcnt < NumberOfInputChannels);

    
    /* Save Correction Values to EEPROM                                     */
    saveCorrectionValue(VoltageInputCorrection, VoltageInput);
    /* Load new Calibration Values from EEPROM                              */
    loadCorrectionValue(InputVoltageCorrection, VoltageInput);
}


/* Calibration of Analogue Outputs in Voltage Mode:
 * Attach the Output you want to calibrate to its corresponding Input
 * (e.g. Output 1 to Input 1). Software will set up In- and Outputs
 * automatically. The Correction Value will be calculated and stored in 
 * the EEPROM (Adresses see above).
 */
void calibrateVoltageOutput (void)
{
    UINT16 spiCommand;
    UINT16 channel = 0;
    UINT16 value = 0xF80;
    UINT16 readVoltage;
    UINT16 VoltageOutputCorrection[4];
    BOOLEAN leaveloop = FALSE;
    
    /* Delete/Reset old Calibration Values                                  */
    deleteCorrectionValue (VoltageOutput);
    /* Load default Calibration Values from EEPROM                          */
    loadCorrectionValue(OutputVoltageCorrection, VoltageOutput);

    
    dacModeAll (dacVOLTAGE);            /* Set Output Types to Voltage      */
    adcModeAll (dacVOLTAGE);            /* Set Input Types to Voltage       */
    vTaskDelay (100);
       
    do                                  /* Single for every Channel         */
        {   
        do                              /* As long as false channel Result  */
            {
            /* Build and send SPI Command                                   */
            spiCommand = 0x3000;
            spiCommand |= ((channel & 0x01) == 
                0x01 ? DAC_CHANNEL_B : DAC_CHANNEL_A);
            spiCommand |= (UINT16) value;
            WriteDacCommand( spiCommand, (channel >> 1));
            
            vTaskDelay (50);
                    
            readVoltage = adcRead (0, channel);

            /* Is Result exactly 10000?
             * If so, wait for 1 Second and test again. If no change, Result
             * is OK and Correction Value is stored. If not, test further
             */            
            if (readVoltage == 10000)
                {
                vTaskDelay (1000);
                if ((readVoltage = adcRead (0, channel)) == 10000)
                    {
                    VoltageOutputCorrection[channel] = value;
                    leaveloop = TRUE;
                    }
                }
            
            /* If Readback is too:
             * LOW: increase Output and try again
             * HIGH: decrease Output and try again
             */
            else if (readVoltage > 10000)
                {
                value -= 0x01;
                }
            else if (readVoltage < 10000)
                {
                value += 0x01;
                }
          
            } while (leaveloop == FALSE);
        
        /* Reset loop Values for next Channel                               */
        leaveloop = FALSE;
        value = 0xF80;
        channel++;
        } while (channel < NumberOfOutputChannels);
    
    /* Save Correction Values to EEPROM                                     */
    saveCorrectionValue(VoltageOutputCorrection, VoltageOutput);
    /* Load new Calibration Values from EEPROM                              */
    loadCorrectionValue(OutputVoltageCorrection, VoltageOutput);
}

/* Calibration of Analogue Inputs in Current Mode:
 * Attach Current Supply with Calibration Value (recommended: 20,000 mA) to
 * the first Input you want to calibrate. Software will read out the real,
 * digital Value from the ADC and uses this as Point of Calibration. Continue
 * with the next channel when software prompts to press enter.
 * Value will be stored in EEPROM (Adresses see above).
 * NEVER CONNECT MORE THAN ONE CHANNEL TO CURRENT SUPPLY ONCE
 */
void calibrateCurrentInput (void)
{
    UINT32 channel = 0;
    UINT16 adcResult;
    UINT16 CurrentInputCorrection[8];
    UINT8 buffer;
    UINT8 spiAdcCommand[3];
    UINT8 spiAdcResponse[3];
    BOOLEAN receive;
    
    /* Delete/Reset old Calibration Values                                  */
    deleteCorrectionValue (CurrentInput);
    /* Load default Calibration Values from EEPROM                          */
    loadCorrectionValue(InputCurrentCorrection, CurrentInput);

    
    adcModeAll (adcCURRENT);            /* Set ADC Mode to CURRENT          */
    vTaskDelay (100);
    
        
    do                                  /* Single for every Channel         */
        {
        /* Just for Testing!!!                                              */
        receive = FALSE;
        buffer = 0;
        sendString (SerOutPort, TRUE, importantMessage,
                "Press ENTER to continue with Channel ", ItoDStr (channel), Dummy);
        do                              /* do-while loop for String input   */
            {
            vTaskDelay (10);
            receive = serGet(MenuPort, &buffer);
            } while ((buffer != 13) && (buffer != 32));
        
       
        /* Reset readback Variables                                         */
        adcResult = 0x00;
        spiAdcResponse[0] = 0;
        spiAdcResponse[1] = 0;
        spiAdcResponse[2] = 0;
        
        /* Build SPI Command                                                */
        spiAdcCommand[0] = 0x06;
        spiAdcCommand[0] |= (channel >> 2) & 0x01;
        spiAdcCommand[1] = (channel << 6);
        spiAdcCommand[2] = 0;
        
        FIO1CLR = BIT( 25 );            /* ADC chipselect enable            */
    
        spiWriteBuffer( spiAdcCommand, 3 ); /* Send SPI Command             */
        spiReadBuffer( spiAdcResponse, 3 ); /* Receive Response             */

        FIO1SET = BIT( 25 );            /* ADC Chipselect disable           */
        
        /* Build 12 Bit Result out of 8 and 4 Bit readBack                  */
        adcResult = (UINT16)(spiAdcResponse[1] & 0x0F) << 8;
        adcResult |= (UINT16)spiAdcResponse[2];


        /* Store Value to Array                                             */
        CurrentInputCorrection[channel] = adcResult;

        channel++;                      /* Test next Channel                */
        } while (channel < 8);

    /* Save Correction Values to EEPROM                                     */
    saveCorrectionValue(CurrentInputCorrection, CurrentInput);
    /* Load new Calibration Values from EEPROM                              */
    loadCorrectionValue(InputCurrentCorrection, CurrentInput);
}

/* Connect Analogue Outputs to the corresponding analogue Inputs. Software
 * will prevent of double-usage of channels.
 * Values will be stored in EEPROM automatically
 */
void calibrateCurrentOutput (void)
{
    UINT16 spiCommand;
    UINT16 channel = 0;
    UINT16 value = 0xF80;
    UINT16 readCurrent;
    UINT16 CurrentOutputCorrection[4];
    BOOLEAN leaveloop = FALSE;
    
    /* Delete/Reset old Calibration Values                                  */
    deleteCorrectionValue (CurrentOutput);
    /* Load default Calibration Values from EEPROM                          */
    loadCorrectionValue(OutputCurrentCorrection, CurrentOutput);

    
    dacModeAll (dacCURRENT);            /* Set Output Types to Voltage      */

    adcMode(0, adcCURRENT);
    adcMode(1, adcCURRENT);
    adcMode(2, adcCURRENT);
    adcMode(3, adcCURRENT);
    adcMode(4, adcVOLTAGE);
    adcMode(5, adcVOLTAGE);
    adcMode(6, adcVOLTAGE);
    adcMode(7, adcVOLTAGE);
    
    vTaskDelay (100);
       
    do                                  /* Single for every Channel         */
        {   
        do                              /* As long as false channel Result  */
            {
            /* Build and send SPI Command                                   */
            spiCommand = 0x3000;
            spiCommand |= ((channel & 0x01) == 
                0x01 ? DAC_CHANNEL_B : DAC_CHANNEL_A);
            spiCommand |= (UINT16) value;
            WriteDacCommand( spiCommand, (channel >> 1));
            
            vTaskDelay (50);
                    
            readCurrent = adcRead (0, channel);
            
            /* Is Result exactly 20000?
             * If so, wait for 1 Second and test again. If no change, Result
             * is OK and Correction Value is stored. If not, test further
             */            
            
            if (readCurrent == 20000)
                {
                vTaskDelay (1000);
                if ((readCurrent = adcRead (0, channel)) == 20000)
                    {
                    CurrentOutputCorrection[channel] = value;
                    leaveloop = TRUE;
                    }
                }
            
            /* If Readback is too:
             * LOW: increase Output and try again
             * HIGH: decrease Output and try again
             */
            else if (readCurrent > 20000)
                {
                value -= 0x01;
                }
            else if (readCurrent < 20000)
                {
                value += 0x01;
                }
          
            } while (leaveloop == FALSE);
        
        /* Reset loop Values for next Channel                               */
        leaveloop = FALSE;
        value = 0xF80;
        channel++;
        } while (channel < NumberOfOutputChannels);
    
    /* Save Correction Values to EEPROM                                     */
    saveCorrectionValue(CurrentOutputCorrection, CurrentOutput);
    /* Load new Calibration Values from EEPROM                              */
    loadCorrectionValue(OutputCurrentCorrection, CurrentOutput);
}


void saveCorrectionValue(pUINT16 CorrectionValueArray,
        daadCorrection_t correctionType)
{
    UINT32 loopcnt = 0;
    UINT8 sendBuffer[16];
    
    switch (correctionType)
        {
        case VoltageInput:              /* Voltage Input Correction         */
            while (loopcnt < NumberOfInputChannels)
                {
                /* Build 8Bit Array out of 16Bit Array                      */
                sendBuffer [2*loopcnt] = (CorrectionValueArray[loopcnt]
                        & 0x00FF);
                sendBuffer [2*loopcnt+1] = ((CorrectionValueArray[loopcnt]
                        & 0xFF00) >> 8);
                loopcnt++;
                }
            /* Send built Array to EEPROM with specific Address and Length  */
            eepromWriteBuffer(VI_Address, sendBuffer, VI_ByteLength);
            eepromWrite(ident_VoltageInput, ident_calibrated);
            break;

        case VoltageOutput:             /* Voltage Output Correction        */
            while (loopcnt < NumberOfOutputChannels)
                {
                sendBuffer [2*loopcnt] = (CorrectionValueArray[loopcnt]
                        & 0x00FF);
                sendBuffer [2*loopcnt+1] = ((CorrectionValueArray[loopcnt]
                        & 0xFF00) >> 8);
                loopcnt++;
                }
            
            eepromWriteBuffer(VO_Address, sendBuffer, VO_ByteLength);
            eepromWrite(ident_VoltageOutput, ident_calibrated);
            break;

        case CurrentInput:              /* Current Input Correction         */
            while (loopcnt < NumberOfInputChannels)
                {
                sendBuffer [2*loopcnt] = (CorrectionValueArray[loopcnt]
                        & 0x00FF);
                sendBuffer [2*loopcnt+1] = ((CorrectionValueArray[loopcnt]
                        & 0xFF00) >> 8);
                loopcnt++;
                }
            
            eepromWriteBuffer(CI_Address, sendBuffer, CI_ByteLength);
            eepromWrite(ident_CurrentInput, ident_calibrated);
            break;

        case CurrentOutput:             /* Current Output Correction        */
            while (loopcnt < NumberOfOutputChannels)
                {
                sendBuffer [2*loopcnt] = (CorrectionValueArray[loopcnt]
                        & 0x00FF);
                sendBuffer [2*loopcnt+1] = ((CorrectionValueArray[loopcnt]
                        & 0xFF00) >> 8);
                loopcnt++;
                }
            
            eepromWriteBuffer(CO_Address, sendBuffer, CO_ByteLength);
            eepromWrite(ident_CurrentOutput, ident_calibrated);
            break;
        }
    
}

void loadCorrectionValue_defaultTarget (daadCorrection_t correctionType)
{
    UINT32 loopcnt = 0;
    UINT8 receiveArray[16];
    
    switch (correctionType)
        {
        case VoltageInput:              /* Voltage Input Correction         */
            /* Read EEPROM entry on specific Address and Length             */
            eepromReadBuffer(VI_Address, receiveArray, VI_ByteLength);
            
            /* Build 16 Bit Array out of 8 Bit Array                        */
            while (loopcnt < NumberOfInputChannels)
                {
                InputVoltageCorrection[loopcnt] = (receiveArray[2*loopcnt]&0xFF)
                        | ((receiveArray[2*loopcnt+1]&0xFF) << 8);
                loopcnt++;
                }
            break;
        
        case VoltageOutput:             /* Voltage Output Correction        */
            eepromReadBuffer(VO_Address, receiveArray, VO_ByteLength);
            while (loopcnt < NumberOfOutputChannels)
                {
                OutputVoltageCorrection[loopcnt] = (receiveArray[2*loopcnt]&0xFF)
                        | ((receiveArray[2*loopcnt+1]&0xFF) << 8);
                loopcnt++;
                }
            break;
        
        case CurrentInput:              /* Current Input Correction         */
            eepromReadBuffer(CI_Address, receiveArray, CI_ByteLength);
            while (loopcnt < NumberOfInputChannels)
                {
                InputCurrentCorrection[loopcnt] = (receiveArray[2*loopcnt]&0xFF)
                        | ((receiveArray[2*loopcnt+1]&0xFF) << 8);
                loopcnt++;
                }
            break;
        
        case CurrentOutput:             /* Current Output Correction        */
            eepromReadBuffer(CO_Address, receiveArray, CO_ByteLength);
            while (loopcnt < NumberOfOutputChannels)
                {
                OutputCurrentCorrection[loopcnt] = (receiveArray[2*loopcnt]&0xFF)
                        | ((receiveArray[2*loopcnt+1]&0xFF) << 8);
                loopcnt++;
                }
            break;
        }

}

void loadCorrectionValue(pUINT16 CorrectionValueArray,
        daadCorrection_t correctionType)
{
    UINT32 loopcnt = 0;
    UINT8 receiveArray[16];
    
    switch (correctionType)
        {
        case VoltageInput:              /* Voltage Input Correction         */
            /* Read EEPROM entry on specific Address and Length             */
            eepromReadBuffer(VI_Address, receiveArray, VI_ByteLength);
            
            /* Build 16 Bit Array out of 8 Bit Array                        */
            while (loopcnt < NumberOfInputChannels)
                {
                CorrectionValueArray[loopcnt] = (receiveArray[2*loopcnt]&0xFF)
                        | ((receiveArray[2*loopcnt+1]&0xFF) << 8);
                loopcnt++;
                }
            break;
        
        case VoltageOutput:             /* Voltage Output Correction        */
            eepromReadBuffer(VO_Address, receiveArray, VO_ByteLength);
            while (loopcnt < NumberOfOutputChannels)
                {
                CorrectionValueArray[loopcnt] = (receiveArray[2*loopcnt]&0xFF)
                        | ((receiveArray[2*loopcnt+1]&0xFF) << 8);
                loopcnt++;
                }
            break;
        
        case CurrentInput:              /* Current Input Correction         */
            eepromReadBuffer(CI_Address, receiveArray, CI_ByteLength);
            while (loopcnt < NumberOfInputChannels)
                {
                CorrectionValueArray[loopcnt] = (receiveArray[2*loopcnt]&0xFF)
                        | ((receiveArray[2*loopcnt+1]&0xFF) << 8);
                loopcnt++;
                }
            break;
        
        case CurrentOutput:             /* Current Output Correction        */
            eepromReadBuffer(CO_Address, receiveArray, CO_ByteLength);
            while (loopcnt < NumberOfOutputChannels)
                {
                CorrectionValueArray[loopcnt] = (receiveArray[2*loopcnt]&0xFF)
                        | ((receiveArray[2*loopcnt+1]&0xFF) << 8);
                loopcnt++;
                }
            break;
        }

}


void deleteCorrectionValue (daadCorrection_t correctionType)
{
    UINT32 loopcnt;
    UINT8 emptyBuffer[16];
    
    /* Build NULL-Array                                                     */
    for (loopcnt = 0; loopcnt < NumberOfInputChannels; loopcnt++)
        {
        emptyBuffer[2*loopcnt]    = 0xFF;
        emptyBuffer[2*loopcnt+1]  = 0x0F;
        }
    
    switch (correctionType)
        {
        case VoltageInput:
            eepromWriteBuffer (VI_Address, emptyBuffer, VI_ByteLength);
            eepromWrite(ident_VoltageInput, ident_default);
            break;
        case VoltageOutput:
            eepromWriteBuffer (VO_Address, emptyBuffer, VO_ByteLength);
            eepromWrite(ident_VoltageOutput, ident_default);
            break;
        case CurrentInput:
            eepromWriteBuffer (CI_Address, emptyBuffer, CI_ByteLength);
            eepromWrite(ident_CurrentInput, ident_default);
            break;
        case CurrentOutput:
            eepromWriteBuffer (CO_Address, emptyBuffer, CO_ByteLength);
            eepromWrite(ident_CurrentOutput, ident_default);
            break;
        }
}
