/* --------------------------------------------------------------------------- * dac.c - v0.1 (c) 2007 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: ADC-driver * --------------------------------------------------------------------------- * Version(s): 0.1, 28-11-2007, fvds. * Creation. * * Calibration updates by MMi * --------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------- * System include files * --------------------------------------------------------------------------- */ #include "LPC23xx.h" #include "types.h" /* FreeRTOS includes */ #include "FreeRTOS.h" /* --------------------------------------------------------------------------- * Application include files * --------------------------------------------------------------------------- */ #include "dac.h" #include "sys_config.h" #include "ssp0.h" #include "dio.h" #include "calibrateaio.h" #include "ElecStatusCache.h" /* --------------------------------------------------------------------------- * Local constant and macro definitions * --------------------------------------------------------------------------- */ #define DAC_CS_DIR_REG FIO1DIR #define DAC_CS_SET_REG FIO1SET #define DAC_CS_CLR_REG FIO1CLR #define DAC1_CS_BIT BIT( 21 ) #define DAC2_CS_BIT BIT( 22 ) // \MARK NEW PINSETTINGS FOR TESTER (2) #if (PINSET_TESTER == 2) #define DAC3_CS_BIT BIT( 19) #endif // \MARK NEW PINSETTINGS FOR TESTER (2) #if (PINSET_TESTER == 2) #define DACS_CS_BITS (DAC1_CS_BIT | DAC2_CS_BIT | DAC3_CS_BIT) #else #define DACS_CS_BITS (DAC1_CS_BIT | DAC2_CS_BIT) #endif #define DAC1_CS_DISABLE (DAC_CS_SET_REG = DAC1_CS_BIT) #define DAC1_CS_ENABLE (DAC_CS_CLR_REG = DAC1_CS_BIT) #define DAC2_CS_DISABLE (DAC_CS_SET_REG = DAC2_CS_BIT) #define DAC2_CS_ENABLE (DAC_CS_CLR_REG = DAC2_CS_BIT) // \MARK NEW PINSETTINGS FOR TESTER (2) #if (PINSET_TESTER == 2) #define DAC3_CS_DISABLE (DAC_CS_SET_REG = DAC3_CS_BIT) #define DAC3_CS_ENABLE (DAC_CS_CLR_REG = DAC3_CS_BIT) #endif // \MARK NEW PINSETTINGS FOR TESTER (2) #if (PINSET_TESTER == 2) #define DAC_CV_DIR_REG FIO4DIR #define DAC_CV_SET_REG FIO4SET #define DAC_CV_CLR_REG FIO4CLR #else #define DAC_CV_DIR_REG FIO3DIR #define DAC_CV_SET_REG FIO3SET #define DAC_CV_CLR_REG FIO3CLR #endif // \MARK NEW PINSETTINGS FOR TESTER (2) #if (PINSET_TESTER == 2) #define CURRENT_VOLTAGE_BITS (0x0000003F) #else #define CURRENT_VOLTAGE_BITS (0x07800000) #endif // \MARK NEW PINSETTINGS FOR TESTER (2) #if (PINSET_TESTER == 2) #define DAC_MUX_DIR FIO3DIR #define DAC_MUX_SET FIO3SET #define DAC_MUX_CLR FIO3CLR #define DAC_MUX_BIT BIT(24) #define DAC_MUX_EN (DAC_MUX_SET = DAC_MUX_BIT) #define DAC_MUX_DS (DAC_MUX_CLR = DAC_MUX_BIT) #endif #define spiWrite ssp0Write #define spiRead ssp0Read #define spiWriteBuffer ssp0WriteBuffer #define spiReadBuffer ssp0ReadBuffer #define spiTakeBus ssp0TakeBus #define spiReleaseBus ssp0ReleaseBus #define DAC_CHANNEL_A (0x8000) #define DAC_CHANNEL_B (0x0000) #define DAC_OUTPUT_BUFFERED (0x4000) #define DAC_OUTPUT_UNBUFFERED (0x0000) #define DAC_OUTPUT_GAIN_1x (0x2000) #define DAC_OUTPUT_GAIN_2x (0x0000) #define DAC_SHDN_OPDC (0x1000) #define DAC_SHDN_DISABLED (0x0000) #define DAC_MAX_SETTING (4095) #define DAC_MAX_CURRENT (20000) #define DAC_MAX_VOLTAGE (10000) /* --------------------------------------------------------------------------- * Global variable definitions * --------------------------------------------------------------------------- */ UINT16 OutputVoltageCorrection[maxDAC_Channels]; UINT16 OutputCurrentCorrection[maxDAC_Channels]; /* --------------------------------------------------------------------------- * Local variable definitions * --------------------------------------------------------------------------- */ // \MARK NEW PINSETTINGS FOR TESTER (2) #if (PINSET_TESTER == 2) t_dac_mode channelModes[maxDAC_Channels] = { dacCURRENT, dacCURRENT, dacCURRENT, dacCURRENT, dacCURRENT, dacCURRENT }; UINT16 channelSetting[maxDAC_Channels] = { 0, 0, 0, 0, 0, 0 }; #else t_dac_mode channelModes[maxDAC_Channels] = { dacCURRENT, dacCURRENT, dacCURRENT, dacCURRENT }; UINT16 channelSetting[maxDAC_Channels] = { 0, 0, 0, 0 }; #endif /* --------------------------------------------------------------------------- * Local function definitions * --------------------------------------------------------------------------- */ void dacInit (void) { DAC_CV_DIR_REG |= CURRENT_VOLTAGE_BITS; DAC_CV_CLR_REG = CURRENT_VOLTAGE_BITS; // Default all bits to current DAC_CS_DIR_REG |= DACS_CS_BITS; DAC1_CS_DISABLE; DAC2_CS_DISABLE; // \MARK NEW PINSETTINGS FOR TESTER (2) #if (PINSET_TESTER == 2) DAC3_CS_DISABLE; DAC_MUX_DIR |= DAC_MUX_BIT; #endif loadCorrectionValue(OutputVoltageCorrection, VoltageOutput); loadCorrectionValue(OutputCurrentCorrection, CurrentOutput); } void dac_MuxEn (BOOLEAN mode) { // \MARK NEW PINSETTINGS FOR TESTER (2) #if (PINSET_TESTER == 2) if (mode == TRUE) { DAC_MUX_EN; /* Set MUX to ExtensionBoard */ } else { DAC_MUX_DS; /* Set MUX to MainBoard */ } #endif } BOOLEAN dac_MuxRB (void) { // \MARK NEW PINSETTINGS FOR TESTER (2) #if (PINSET_TESTER == 2) if (DAC_MUX_SET & DAC_MUX_BIT) { /* Mux is switched to ExtensionBoard */ return (TRUE); } else { /* Mux is switched to MainBoard */ return (FALSE); } #endif } /** \brief Select output mode (Voltage or Current) of a certain channel. */ void dacMode ( UINT8 channel, /*< 0..5 = valid */ t_dac_mode mode ) { UINT32 channelMask; if (channel >= maxDAC_Channels ) return; // Channel doesn't exist channelModes[channel] = mode; // \MARK NEW PINSETTINGS FOR TESTER (2) #if (PINSET_TESTER == 2) channelMask = BIT( (UINT32)(channel) ); /* channel bit + offset */ #else channelMask = BIT( (UINT32)(channel + 23) ); /* channel bit + offset */ #endif if (mode == dacVOLTAGE) { DAC_CV_SET_REG = channelMask; } else { DAC_CV_CLR_REG = channelMask; } } /** \brief Write analog value in mV or uA depending on dacMode */ void dacWrite( UINT8 device, /**< 0 = Self, valid */ UINT8 channel, /**< 0..5 = valid */ UINT16 value /*< VOLTAGE: 0..10000[mV], CURRENT: 0..20000[uA] */ ) { UINT16 spiCommand; UINT32 dacSetting; UINT32 divideValue; if (device == 0) { if (channel >= maxDAC_Channels ) return; // Channel doesn't exist channelSetting[ channel] = value; // Assemble DAC command spiCommand = DAC_OUTPUT_UNBUFFERED | DAC_OUTPUT_GAIN_1x | DAC_SHDN_OPDC; spiCommand |= ( (channel & 0x01) == 0x01 ? DAC_CHANNEL_B : DAC_CHANNEL_A); divideValue = (channelModes[channel] == dacVOLTAGE ? DAC_MAX_VOLTAGE : DAC_MAX_CURRENT); // dacSetting = ((UINT32)value * DAC_MAX_SETTING) / divideValue; if (channelModes[channel] == dacVOLTAGE) { dacSetting = (UINT32)value * OutputVoltageCorrection[channel] / divideValue; } else { dacSetting = (UINT32)value * OutputCurrentCorrection[channel] / divideValue; } if (dacSetting > DAC_MAX_SETTING) return; spiCommand |= (UINT16) dacSetting; /* devide channel by 2 on send the SPI command with WriteDacCommand * channel 0-1: dac0 * channel 2-3: dac1 * channel 4-5: dac2 */ WriteDacCommand( spiCommand, (channel >> 1)); } else { bpecWriteDacValue(device, channel, value); } } UINT16 dacReadBack ( UINT8 device, /**< 0 = Self, 1..32 = Remote device */ UINT8 channel /**< 0..3 = valid, 8..255 = future use */ ) { if (device == 0) { if (channel >= maxDAC_Channels ) return 0; // Channel doesn't exist) return channelSetting[ channel ]; } else { return bpecDacReadBack(device, channel); } } void WriteDacCommand( UINT16 spiCommand, UINT8 dacNr ) { UINT8 spiCommandArray[2]; UINT8 spiResponse[2]; spiTakeBus(); { // dacNr 0: DAC 0 // dacNr 1: DAC 1 // dacNr 2: DAC 2 // Enable correct ChipSelect switch (dacNr) { case 0: DAC1_CS_ENABLE; break; case 1: DAC2_CS_ENABLE; break; // \MARK NEW PINSETTINGS FOR TESTER (2) #if (PINSET_TESTER == 2) case 2: DAC3_CS_ENABLE; break; #endif } // if (dacNr == 0) // { // DAC1_CS_ENABLE; // } else // { // DAC2_CS_ENABLE; // } spiCommandArray[0] = (spiCommand >> 8) & 0xFF; spiCommandArray[1] = spiCommand & 0xFF; spiWriteBuffer( spiCommandArray, 2); spiReadBuffer( spiResponse, 2 ); // dacNr 0: DAC 0 // dacNr 1: DAC 1 // dacNr 2: DAC 2 // Enable correct ChipSelect switch (dacNr) { case 0: DAC1_CS_DISABLE; break; case 1: DAC2_CS_DISABLE; break; // \MARK NEW PINSETTINGS FOR TESTER (2) #if (PINSET_TESTER == 2) case 2: DAC3_CS_DISABLE; break; #endif } // if (dacNr == 0) // { // DAC1_CS_DISABLE; // } else // { // DAC2_CS_DISABLE; // } } spiReleaseBus(); } void dacModeAll (t_dac_mode mode) { dacMode(0, mode); dacMode(1, mode); dacMode(2, mode); dacMode(3, mode); // \MARK NEW PINSETTINGS FOR TESTER (2) #if (PINSET_TESTER == 2) dacMode(4, mode); dacMode(5, mode); #endif }