/* --------------------------------------------------------------------------- * adc.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 (MCP3208-CI/SL) * --------------------------------------------------------------------------- * 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 "adc.h" #include "ssp0.h" #include "ElecStatusCache.h" #include "calibrateaio.h" #include "sys_config.h" #include "dio.h" /* --------------------------------------------------------------------------- * Local constant and macro definitions * --------------------------------------------------------------------------- */ #define ADC_CS_DIR_REG FIO1DIR #define ADC_CS_SET_REG FIO1SET #define ADC_CS_CLR_REG FIO1CLR #define ADC_CS_BIT BIT( 25 ) #define ADC_CS_DISABLE (ADC_CS_SET_REG = ADC_CS_BIT) #define ADC_CS_ENABLE (ADC_CS_CLR_REG = ADC_CS_BIT) // \MARK NEW PINSETTINGS FOR TESTER (2) #if (PINSET_TESTER == 2) #define ADC_CV_DIR_REG FIO3DIR #define ADC_CV_PIN_REG FIO3PIN #define ADC_CV_SET_REG FIO3SET #define ADC_CV_CLR_REG FIO3CLR #else #define ADC_CV_DIR_REG_P1 FIO1DIR #define ADC_CV_DIR_REG_P2 FIO2DIR #define ADC_CV_PIN_REG_P1 FIO1PIN #define ADC_CV_PIN_REG_P2 FIO2PIN #define ADC_CV_SET_REG_P1 FIO1SET #define ADC_CV_SET_REG_P2 FIO2SET #define ADC_CV_CLR_REG_P1 FIO1CLR #define ADC_CV_CLR_REG_P2 FIO2CLR #endif // \MARK NEW PINSETTINGS FOR TESTER (2) #if (PINSET_TESTER == 2) #define CURRENT_VOLTAGE_BITS (0x000000FF) #else #define CURRENT_VOLTAGE_BITS_P1 (0x3C000000) #define CURRENT_VOLTAGE_BITS_P2 (0x00000078) #endif // \MARK NEW PINSETTINGS FOR TESTER (2) #if (PINSET_TESTER == 2) #define ADC_MUX_DIR FIO3DIR #define ADC_MUX_SET FIO3SET #define ADC_MUX_CLR FIO3CLR #define ADC_MUX_BIT BIT(23) #define ADC_MUX_EN (ADC_MUX_SET = ADC_MUX_BIT) #define ADC_MUX_DS (ADC_MUX_CLR = ADC_MUX_BIT) #endif #define spiWrite ssp0Write #define spiRead ssp0Read #define spiWriteBuffer ssp0WriteBuffer #define spiReadBuffer ssp0ReadBuffer #define spiTakeBus ssp0TakeBus #define spiReleaseBus ssp0ReleaseBus #define ADC_START_CMD (0x04) #define ADC_SINGLE_ENDED (0x02) #define ADC_DIFFERENTIAL (0x00) /* --------------------------------------------------------------------------- * Global variable definitions * --------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------- * Local variable definitions * --------------------------------------------------------------------------- */ UINT16 InputVoltageCorrection[8]; UINT16 InputCurrentCorrection[8]; /* --------------------------------------------------------------------------- * Local function definitions * --------------------------------------------------------------------------- */ void adcInit (void) { // \MARK NEW PINSETTINGS FOR TESTER (2) #if (PINSET_TESTER == 2) /* TESTER Pins like IO_CTRL REV_B */ ADC_CV_DIR_REG |= CURRENT_VOLTAGE_BITS; #else ADC_CV_DIR_REG_P1 |= CURRENT_VOLTAGE_BITS_P1; ADC_CV_DIR_REG_P2 |= CURRENT_VOLTAGE_BITS_P2; #endif #if (PINSET_TESTER == 2) /* TESTER Pins like IO_CTRL REV_B */ ADC_CV_SET_REG = CURRENT_VOLTAGE_BITS; // Default all bits to current #else ADC_CV_SET_REG_P1 = CURRENT_VOLTAGE_BITS_P1; ADC_CV_SET_REG_P2 = CURRENT_VOLTAGE_BITS_P2; #endif ADC_CS_DIR_REG |= ADC_CS_BIT; ADC_CS_DISABLE; loadCorrectionValue(InputVoltageCorrection, VoltageInput); loadCorrectionValue(InputCurrentCorrection, CurrentInput); // \MARK NEW PINSETTINGS FOR TESTER (2) #if (PINSET_TESTER == 2) ADC_MUX_DIR |= ADC_MUX_BIT; #endif } void adc_MuxEn (BOOLEAN mode) { // \MARK NEW PINSETTINGS FOR TESTER (2) #if (PINSET_TESTER == 2) if (mode == TRUE) { ADC_MUX_EN; /* Set MUX to ExtensionBoard */ } else { ADC_MUX_DS; /* Set MUX to MainBoard */ } #endif } BOOLEAN adc_MuxRB (void) { // \MARK NEW PINSETTINGS FOR TESTER (2) #if (PINSET_TESTER == 2) if (ADC_MUX_SET & ADC_MUX_BIT) { /* Mux is switched to ExtensionBoard */ return (TRUE); } else { /* Mux is switched to MainBoard */ return (FALSE); } #endif } /** \brief Select input mode (Voltage or Current) of a certain channel. */ void adcMode ( UINT8 channel, /**< 0..7 = valid, 8..255 = future use */ t_adc_mode mode ) { #if (PINSET_TESTER == 2) /* TESTER Pins like IO_CTRL REV_B */ if (channel >= maxADC_Channels ) return; // Channel doesn't exist if (mode == adcVOLTAGE) { ADC_CV_CLR_REG = BIT( channel ); } else { ADC_CV_SET_REG = BIT( channel ); } #else if (channel >= maxADC_Channels ) return; // Channel doesn't exist if (mode == adcVOLTAGE) { if (channel <= 3) { ADC_CV_CLR_REG_P1 = BIT (26 + channel); } else { ADC_CV_CLR_REG_P2 = BIT (channel - 1); } } else { if (channel <= 3) { ADC_CV_SET_REG_P1 = BIT (26 + channel); } else { ADC_CV_SET_REG_P2 = BIT (channel - 1); } } #endif } /** \brief Read analog value in mV or uA depending on adcMode \retval value VOLTAGE: 0..10000[mV], CURRENT: 0..20000[uA] */ UINT16 adcRead ( UINT8 device, /**< 0 = Self, 1..32 = Remote device */ UINT8 channel /**< 0..7 = valid, 8..255 = future use */ ) { UINT8 spiAdcCommand[3]; UINT8 spiAdcResponse[3]; UINT16 adcResult; UINT32 range; UINT32 measuredValue; if (device > 0) { measuredValue = bpecAdcRead(device, channel); } else { if (channel >= maxADC_Channels) return 0; spiAdcCommand[0] = (ADC_START_CMD | ADC_SINGLE_ENDED); spiAdcCommand[0] |= (channel >> 2) & 0x01; spiAdcCommand[1] = (channel << 6); spiAdcCommand[2] = 0; spiTakeBus(); { ADC_CS_ENABLE; spiWriteBuffer( spiAdcCommand, 3 ); spiReadBuffer( spiAdcResponse, 3 ); ADC_CS_DISABLE; } spiReleaseBus(); adcResult = (UINT16)(spiAdcResponse[1] & 0x0F) << 8; adcResult |= (UINT16)spiAdcResponse[2]; // Convert ADC value (0-4096) to measured value // Determin range Voltage = 10000 & Ampere = 20000 #if (PINSET_TESTER == 2) /* TESTER Pins like IO_CTRL REV_B */ if ((ADC_CV_PIN_REG & BIT( channel )) == 0) #else if ((((ADC_CV_PIN_REG_P1 & BIT (26 + channel)) == 0) && (channel <= 3)) || (((ADC_CV_PIN_REG_P2 & BIT (channel - 1)) == 0) && (channel >= 4))) #endif { range = 10000; measuredValue = (adcResult * range) / InputVoltageCorrection[channel]; } else { range = 20000; measuredValue = (adcResult * range) / InputCurrentCorrection[channel]; } } return (UINT16)measuredValue; } void adcModeAll (t_adc_mode mode) { adcMode (0, mode); adcMode (1, mode); adcMode (2, mode); adcMode (3, mode); adcMode (4, mode); adcMode (5, mode); adcMode (6, mode); adcMode (7, mode); }