Files
diplomarbeit/Tester/SW/lib/Drivers/adc.c
T
Matthias 373a8c32b2 Added Software projects
git-svn-id: file:///srv/dev-disk-by-uuid-17e88007-4d0c-45e0-8757-cacfcc458630/repositories/svn/Diplomarbeit@55 9fe90eed-be63-e94b-8204-d34ff4c2ff93
2008-12-23 10:34:08 +00:00

304 lines
8.9 KiB
C

/* ---------------------------------------------------------------------------
* 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.
* ---------------------------------------------------------------------------
*/
/* ---------------------------------------------------------------------------
* 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);
}