Skip to content

Instantly share code, notes, and snippets.

@ce6n
Created August 27, 2012 14:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ce6n/3489186 to your computer and use it in GitHub Desktop.
Save ce6n/3489186 to your computer and use it in GitHub Desktop.
bachlor code
//=============================================================================
// (c) Copyright 2005 Diamond Systems Corporation. Use of this source code
// is subject to the terms of Diamond Systems' Software License Agreement.
// Diamond Systems provides no warranty of proper performance if this
// source code is modified.
//
// File: DSCADScanInt.c v5.9
// Desc: Sample program that demonstrates how to perform an interrupt-based AD
// scan
// Created by KL
//=============================================================================
#include <stdio.h>
#ifdef _WIN32
#ifndef _WIN32_WCE
#include <conio.h>
#endif
#include <windows.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <sys/timeb.h>
#include <time.h>
// diamond driver includes
#include "dscud.h"
#endif
// var declarations
BYTE result; // returned error code
DSCB dscb; // handle used to refer to the board
DSCCB dsccb; // structure containing board settings
DSCS dscs; // structure containing interrupt-based sampling status information
DFLOAT voltage; // actual voltage
DSCAIOINT dscaioint; // structure containing I/O interrupt settings
DSCADSETTINGS dscadsettings; // structure containing A/D conversion settings
ERRPARAMS errparams; // structure for returning error code and error string
int intBuff; // temp variable of size int
long longBuff; // temp variable of size long
float floatBuff; // temp variable of size float
unsigned int i; // miscellaneous counter
DWORD last_total_transfers;
DWORD last_transfers;
unsigned int new_sample_count;
unsigned int num_conversions = 20480;
DWORD stop_after_transfers = 102400;
DWORD sleep_ms = 300;
// actual time
struct _timeb timebuffer;
char *timeline;
//=============================================================================
// Name: main()
// Desc: Starting function that calls the driver functions used
//
// NOTE: By convention, you should capture the BYTE return value for each
// driver API call, and check the error code.
//
// STEPS TO FOLLOW:
//
// I. Driver Initialization
// II. Board Initialization
// III. AD Settings Initialization
// IV. I/O Interrupt Settings Initialization
// V. Sampling and Output
// VI. Cleanup
//
//=============================================================================
int main( void )
{
//=========================================================================
// I. DRIVER INITIALIZATION
//
// Initializes the DSCUD library.
//
// STEPS TO FOLLOW:
//
// 1. initialize the driver, using the driver version for validation
//=========================================================================
if( dscInit( DSC_VERSION ) != DE_NONE )
{
dscGetLastError(&errparams);
fprintf( stderr, "dscInit error: %s %s\n", dscGetErrorString(errparams.ErrCode), errparams.errstring );
return 0;
}
//=========================================================================
// II. BOARD INITIALIZATION
//
// Initialize the DMM-16-AT board. This function passes the various
// hardware parameters to the driver and resets the hardware.
//
// STEPS TO FOLLOW:
//
// 1. set the board type to DSC_DMM16AT for DMM-16-AT board
// 2. set the base address (must be between 0x220-0x3E0)
// 3. set the interrupt level (must be between 3-15)
// 4. intialize and register the board with the driver, after which
// the struct, dscb, now holds the handle for the board
//=========================================================================
printf( "\nDMM16AT BOARD INITIALIZATION:\n" );
//printf("Enter the base address (default 0x300) : ");
//scanf( "%hx", &dsccb.base_address );
dsccb.base_address = 0x300;
//printf("Enter the interrupt level (3-15) : ");
//scanf("%d", &intBuff);
dsccb.int_level = (BYTE) 7;
if(dscInitBoard(DSC_DMM16AT, &dsccb, &dscb)!= DE_NONE)
{
dscGetLastError(&errparams);
fprintf( stderr, "dscInitBoard error: %s %s\n", dscGetErrorString(errparams.ErrCode), errparams.errstring );
return 0;
}
//=========================================================================
// III. AD SETTINGS INITIALIZATION
//
// Initialize the structure containing the AD conversion settings and
// then pass it to the driver.
//
// STEPS TO FOLLOW:
//
// 1. set the range (must be RANGE_5, RANGE_10)
// 2. set the polarity (must be BIPOLAR or UNIPOLAR)
// 3. set the gain (must be GAIN_1, GAIN_2, GAIN_4, or GAIN_8)
// 4. set the load calibration settings flag
// 5. set the current channel to be sampled (must be between 0-15)
// 6. initialize the AD conversion with these settings
//=========================================================================
// PRE-FILLED EXAMPLE
dscadsettings.range = RANGE_10;
dscadsettings.polarity = BIPOLAR;
dscadsettings.gain = GAIN_1;
dscadsettings.load_cal = (BYTE)TRUE;
dscadsettings.current_channel = 0;
//
printf( "\nAD SETTINGS INITIALIZATION\n" );
memset(&dscadsettings, 0, sizeof(DSCADSETTINGS));
if( ( result = dscADSetSettings( dscb, &dscadsettings ) ) != DE_NONE )
{
dscGetLastError(&errparams);
fprintf( stderr, "dscADSetSettings error: %s %s\n", dscGetErrorString(errparams.ErrCode), errparams.errstring );
return 0;
}
//=========================================================================
// IV. I/O INTERRUPT SETTINGS INITIALIZATION
//
// Initialize the structure containing the analog I/O interrupt
// settings.
//
// NOTE: You must allocate space for the buffer holding the returned
// sample values. Also, be generous in allocating storage.
// Allocating insufficient memory to hold sample data will result
// in improper behavior of the driver, such as hanging interrupt
// operations or assertion errors.
//
// STEPS TO FOLLOW:
//
// 1. set the number of conversions (must be a multiple of the fifo
// depth)
// 2. set the conversion rate (must be less than 100 kHz)
// 3. set the cycle flag
// 4. set the internal clock flag
// 5. set the low channel (must be between 0-15)
// 6. set the high channel (must be between 0-15)
// 7. set the external gate enable flag
// 8. set the internal clock gate flag
// 9. set the fifo enable flag
// 10. set the fifo depth (must be 256)
// 11. allocate memory for the sample values
//=========================================================================
// PRE-FILLED EXAMPLE
dscaioint.num_conversions = num_conversions;
dscaioint.conversion_rate = 1000;
dscaioint.cycle = (BYTE)TRUE;
dscaioint.internal_clock = (BYTE)TRUE;
dscaioint.low_channel = 0;
dscaioint.high_channel = 3;
dscaioint.external_gate_enable = (BYTE)FALSE;
dscaioint.internal_clock_gate = (BYTE)FALSE;
dscaioint.fifo_enab = (BYTE)TRUE;
dscaioint.fifo_depth = 256;
dscaioint.dump_threshold = 256;
//
printf( "\nI/O INTERRUPT SETTINGS INITIALIZATION\n" );
//memset(&dscaioint, 0, sizeof(DSCAIOINT));
//getchar();
//=========================================================================
// V. SCANNING AND OUTPUT
//
printf( "\nSAMPLING AND OUTPUT\n" );
dscaioint.sample_values = malloc(num_conversions * sizeof(DSCSAMPLE));
if ( dscaioint.sample_values == NULL ) {
printf("Operation failed: unable to allocate memory\n");
exit(1);
}
if ((result = dscADSampleInt(dscb, &dscaioint)) != DE_NONE)
{
dscGetLastError(&errparams);
fprintf(stderr, "dscADSampleInt failed: %s (%s)\n",
dscGetErrorString(result), errparams.errstring);
return result;
}
last_total_transfers = 0;
last_transfers = 0;
do {
dscSleep(sleep_ms);
dscGetStatus(dscb, &dscs);
if ( dscs.overflows ) {
printf("Operation failed: FIFO overflowed\n");
break;
}
if ( dscs.total_transfers == last_total_transfers ) {
printf("Operation failed: no new samples taken in %d ms\n", sleep_ms);
break;
}
new_sample_count = dscs.total_transfers - last_total_transfers;
/* Number of new samples should never exceed the size of the circular buffer. If
* it does it means that either "sleep_ms" should be smaller so you check status
* more often, or "num_conversions" should be bigger so the circular buffer is bigger
*/
if ( new_sample_count > num_conversions ) {
printf("Operation failed: not processing data fast enough. %d samples lost\n",
new_sample_count - num_conversions);
break;
}
/* The code below uses the "transfers" counter to determine where in the circular
* buffer the new sample data is located. It could be only later in the buffer
* than we already reported. Or it could have looped back around to the start of
* the circular buffer in which case the data to the end of the buffer, plus data
* at the start of the buffer must be reported.
*/
/* Case one: more data has been placed in the circular buffer after the
* "last_transfers" position we checked previously.
*/
if ( dscs.transfers > last_transfers ) {
for ( i = last_transfers; i < dscs.transfers; i++ )
if ( i%4 == 0 ) {
_ftime( &timebuffer );
timeline = ctime( & ( timebuffer.time ) );
printf( "The time is %.19s.%hu %s", timeline, timebuffer.millitm, &timeline[20] );
printf("time: smpls: %5d %5d %5d \n",dscaioint.sample_values[i],dscaioint.sample_values[i+1], dscaioint.sample_values[i+2]);
}
/* Case two: more data has been placed in the circular buffer both after
* the "last_transfers" and before it at the start of the buffer.
*/
} else if ( dscs.transfers <= last_transfers ) {
for ( i = last_transfers; i < num_conversions; i++ )
// printf("A/D sample: %d ADCODE\n", dscaioint.sample_values[i]);
if ( i%4 == 0 ) {
printf("c2 i: %5d t: %5d st: %6d bu: %6d smpls: %5d %5d %5d \n",i,GetTickCount(),last_total_transfers, last_transfers, dscaioint.sample_values[i],dscaioint.sample_values[i+1], dscaioint.sample_values[i+2]);
}
for ( i = 0; i < dscs.transfers; i++ )
// printf("A/D sample: %d ADCODE\n", dscaioint.sample_values[i]);
if ( i%4 == 0 ) {
printf("c3 i: %5d t: %5d st: %6d bu: %6d smpls: %5d %5d %5d \n",i,GetTickCount(),last_total_transfers, last_transfers, dscaioint.sample_values[i],dscaioint.sample_values[i+1], dscaioint.sample_values[i+2]);
}
}
// printf("reseting i, last_transfers: %5d new: %5d \n",last_transfers,dscs.transfers);
last_transfers = dscs.transfers;
last_total_transfers = dscs.total_transfers;
if ( dscs.total_transfers >= stop_after_transfers )
break;
} while ( dscs.op_type != OP_TYPE_NONE );
dscCancelOp(dscb);
//=========================================================================
// VI. CLEANUP
//
// Cleanup any remnants left by the program and free the resources used
// by the driver.
//
// STEPS TO FOLLOW:
//
// 1. free the memory allocated for sample values
// 2. free the driver resources
//=========================================================================
free( dscaioint.sample_values );
dscFree();
printf( "\nDSCADScanInt completed. \n" );
return 0;
} // end main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment