Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
A
advLigoRTS
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Deploy
Releases
Container Registry
Model registry
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
CDS
software
advLigoRTS
Commits
79829187
Commit
79829187
authored
5 years ago
by
Rolf Bork
Browse files
Options
Downloads
Patches
Plain Diff
Added driver code for General Standards 18AI32 ADC module.
parent
b0e15281
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/include/drv/gsc18ai32.c
+272
-0
272 additions, 0 deletions
src/include/drv/gsc18ai32.c
src/include/drv/gsc18ai32.h
+78
-0
78 additions, 0 deletions
src/include/drv/gsc18ai32.h
with
350 additions
and
0 deletions
src/include/drv/gsc18ai32.c
0 → 100644
+
272
−
0
View file @
79829187
/// \file gsc16ai64.c
/// \brief File contains the initialization routine and various register read/write
///< operations for the General Standards 16bit, 32 channel ADC modules. \n
///< For board info, see
///< <a href="http://www.generalstandards.com/view-products2.php?BD_family=16ai64ssc">GSC 16AI64SSC Manual</a>
#include
"gsc18ai32.h"
// *****************************************************************************
/// \brief Routine to initialize GSC 16bit, 32 channel ADC modules
/// @param[in,out] *pHardware Pointer to global data structure for storing I/O
///< register mapping information.
/// @param[in] *adcdev PCI address information passed by the mapping code in map.c
/// @return Status from board enable command.
// *****************************************************************************
int
gsc18ai32Init
(
CDS_HARDWARE
*
pHardware
,
struct
pci_dev
*
adcdev
)
{
static
unsigned
int
pci_io_addr
;
/// @param pci_io_addr Bus address of PCI card I/O register.
int
devNum
;
/// @param devNum Index into CDS_HARDWARE struct for adding board info.
char
*
_adc_add
;
/// @param *_adc_add ADC register address space
int
pedStatus
;
/// @param pedStatus Status return from call to enable device.
volatile
GSA_ADC_18BIT_REG
*
adc18Ptr
;
/// Get index into CDS_HARDWARE struct based on total number of ADC cards found by mapping routine
/// in map.c
devNum
=
pHardware
->
adcCount
;
/// Enable the module.
pedStatus
=
pci_enable_device
(
adcdev
);
/// Enable device to be DMA master.
pci_set_master
(
adcdev
);
/// Get the PLX chip address
pci_read_config_dword
(
adcdev
,
PCI_BASE_ADDRESS_0
,
&
pci_io_addr
);
printk
(
"pci0 = 0x%x
\n
"
,
pci_io_addr
);
/// Map module DMA space directly to computer memory space.
_adc_add
=
ioremap_nocache
((
unsigned
long
)
pci_io_addr
,
0x200
);
/// Map the module DMA control registers via PLX chip registers
adcDma
[
devNum
]
=
(
PLX_9056_DMA
*
)
_adc_add
;
if
(
devNum
==
0
)
plxIcr
=
(
PLX_9056_INTCTRL
*
)
_adc_add
;
/// Get the ADC register address
pci_read_config_dword
(
adcdev
,
PCI_BASE_ADDRESS_2
,
&
pci_io_addr
);
printk
(
"pci2 = 0x%x
\n
"
,
pci_io_addr
);
/// Map the module control register so local memory space.
_adc_add
=
ioremap_nocache
((
unsigned
long
)
pci_io_addr
,
0x200
);
printk
(
"ADC 18 I/O address=0x%x 0x%lx
\n
"
,
pci_io_addr
,(
long
)
_adc_add
);
/// Set global ptr to control register memory space.
adc18Ptr
=
(
GSA_ADC_18BIT_REG
*
)
_adc_add
;
adcPtr
[
devNum
]
=
(
GSA_ADC_REG
*
)
_adc_add
;
printk
(
"ADC pointer init at 0x%lx
\n
"
,(
long
)
adcPtr
[
devNum
]);
printk
(
"BCR = 0x%x
\n
"
,
adc18Ptr
->
BCR
);
/// Reset the ADC board
adc18Ptr
->
BCR
|=
GSAF_RESET
;
do
{
}
while
((
adc18Ptr
->
BCR
&
GSAF_RESET
)
!=
0
);
/// Write in a sync word
adc18Ptr
->
SMUW
=
0x0000
;
adc18Ptr
->
SMLW
=
0x0000
;
/// Set ADC to 64 channel = 32 differential channels
// Don't need this for this board
#ifdef ADC_EXTERNAL_SYNC
// This is for the external connector use
adc18Ptr
->
BCR
|=
(
GSAF_ENABLE_X_SYNC
);
// 0x80
adc18Ptr
->
AUX_SIO
|=
0x80
;
#endif
/// Set sample rate close to 16384Hz
/// Unit runs with external clock, so this probably not necessary
adc18Ptr
->
RAG
=
0x117D8
;
printk
(
"RAG = 0x%x
\n
"
,
adc18Ptr
->
RAG
);
printk
(
"BCR = 0x%x
\n
"
,
adc18Ptr
->
BCR
);
adc18Ptr
->
RAG
&=
~
(
GSAF_SAMPLE_START
);
// 0x10000
/// Initiate board calibration
adc18Ptr
->
BCR
|=
GSAF_AUTO_CAL
;
/// Wait for internal calibration to complete.
do
{
}
while
((
adc18Ptr
->
BCR
&
GSAF_AUTO_CAL
)
!=
0
);
// 0x2000
adc18Ptr
->
RAG
|=
GSAF_SAMPLE_START
;
// 0x10000
adc18Ptr
->
IDBC
=
(
GSAF_CLEAR_BUFFER
|
GSAF_THRESHOLD
);
// 0x40000 | 0x001f
adc18Ptr
->
SSC
=
(
GSAF_32_CHANNEL
);
// 0x5 Sets 32 channels and external clock
printk
(
"SSC = 0x%x
\n
"
,
adc18Ptr
->
SSC
);
printk
(
"IDBC = 0x%x
\n
"
,
adc18Ptr
->
IDBC
);
/// Fill in CDS_HARDWARE structure with ADC information.
pHardware
->
pci_adc
[
devNum
]
=
(
long
)
pci_alloc_consistent
(
adcdev
,
0x2000
,
&
adc_dma_handle
[
devNum
]);
pHardware
->
adcType
[
devNum
]
=
GSC_18AI32SSC1M
;
pHardware
->
adcConfig
[
devNum
]
=
adc18Ptr
->
ASSC
;
pHardware
->
adcCount
++
;
/// Return board enable status.
return
(
pedStatus
);
/*
SSC Register
- Byte 0 = Active channels + lower sample source bit
- 0x5
- Byte 1 = upper sample source + enable clocking + enable clock divider + burst busy
- 0x20
*/
}
// *****************************************************************************
/// \brief Function checks status of DMA DONE bit for an ADC module.
/// @param[in] module ID of ADC board to read.
/// @return Status of ADC module DMA DONE bit (0=not complete, 1= complete)
// *****************************************************************************
int
gsc18ai32CheckDmaDone
(
int
module
)
{
// Return 0 if DMA not complete
if
((
adcDma
[
module
]
->
DMA_CSR
&
GSAF_DMA_DONE
)
==
0
)
return
(
0
);
// Return 1 if DMA is complete
else
return
(
1
);
}
// *****************************************************************************
/// \brief Function if DMA from ADC module is complete.
///< Code will remain in loop until DMA is complete.
/// @param[in] module ID of ADC board to read.
/// @param[out] data Status of DMA DONE bit.
/// @return ADC DMA Status (0=not complete, 16=complete
/// Note: This function not presently used.
// *****************************************************************************
int
gsc18ai32WaitDmaDone
(
int
module
,
int
*
data
)
{
do
{
}
while
((
adcDma
[
module
]
->
DMA_CSR
&
GSAF_DMA_DONE
)
==
0
);
// First channel should be marked with an upper bit set
if
(
*
data
==
0
)
return
0
;
else
return
16
;
}
// *****************************************************************************
/// \brief Function clears ADC buffer and starts acquisition via external clock.
///< Also sets up ADC for Demand DMA mode and set GO bit in DMA Mode Register.
///< NOTE: In normal operation, this code should only be called while the clocks from
///< the timing slave are turned OFF ie during initialization process.
/// @param[in] adcCount Total number of ADC modules to start DMA.
// *****************************************************************************
int
gsc18ai32Enable
(
CDS_HARDWARE
*
pHardware
)
{
int
ii
;
volatile
GSA_ADC_18BIT_REG
*
adc18Ptr
;
for
(
ii
=
0
;
ii
<
pHardware
->
adcCount
;
ii
++
)
{
if
(
pHardware
->
adcType
[
ii
]
==
GSC_18AI32SSC1M
)
{
adc18Ptr
=
(
volatile
GSA_ADC_18BIT_REG
*
)
adcPtr
[
ii
];
/// Enable demand DMA mode ie auto DMA data to computer memory when
///< GSAI_THRESHOLD data points in ADC FIFO.
adc18Ptr
->
BCR
&=
~
(
GSAF_DMA_DEMAND_MODE
);
/// Set DMA mode and direction in PLX controller chip on module.
adcDma
[
ii
]
->
DMA0_MODE
=
GSAF_DMA_MODE_NO_INTR
|
0x1000
;
/// Enable DMA
adcDma
[
ii
]
->
DMA_CSR
=
GSAF_DMA_START
;
/// Clear the FIFO and set demand DMA to start after all 32 channels have 1 sample
adc18Ptr
->
IDBC
=
(
GSAF_CLEAR_BUFFER
|
GSAF_THRESHOLD
);
/// Enable sync via external clock input.
adc18Ptr
->
SSC
|=
GSAF_ENABLE_CLOCK
;
}
}
return
(
0
);
}
#if 0
// *****************************************************************************
int gsc18ai32Enable1PPS(CDS_HARDWARE *pHardware, int ii)
{
/// Enable demand DMA mode ie auto DMA data to computer memory when
///< GSAI_THRESHOLD data points in ADC FIFO.
volatile GSA_ADC_18BIT_REG *adc18Ptr;
if(pHardware->adcType[ii] == GSC_18AI32SSC1M)
{
adc18Ptr = (volatile GSA_ADC_18BIT_REG *) adcPtr[ii];
adc18Ptr->BCR &= ~(GSAF_DMA_DEMAND_MODE);
/// Set DMA mode and direction in PLX controller chip on module.
adcDma->DMA0_MODE = GSAF_DMA_MODE_NO_INTR | 0x1000;
/// Enable DMA
adcDma->DMA_CSR = GSAF_DMA_START;
/// Clear the FIFO and set demand DMA to start after all 32 channels have 1 sample
adc18Ptr->IDBC = (GSAF_CLEAR_BUFFER | GSAF_THRESHOLD);
/// Enable sync via external clock input.
adc18Ptr->BCR |= GSAF_ENABLE_X_SYNC;
}
return(0);
}
// *****************************************************************************
/// \brief Function stops ADC acquisition by removing the clocking signal.
// *****************************************************************************
int gsc18ai32AdcStop()
{
adc18Ptr[0]->BCR &= ~(GSAF_ENABLE_X_SYNC);
return(0);
}
#endif
// *****************************************************************************
/// \brief Routine reads number of samples in ADC FIFO.
/// @param[in] numAdc The ID number of the ADC module to read.
/// @return The number of samples presently in the ADC FIFO.
// *****************************************************************************
int
gsc18ai32CheckAdcBuffer
(
CDS_HARDWARE
*
pHardware
,
int
numAdc
)
{
volatile
GSA_ADC_18BIT_REG
*
adc18Ptr
;
int
dataCount
=
0
;
if
(
pHardware
->
adcType
[
numAdc
]
==
GSC_18AI32SSC1M
)
{
adc18Ptr
=
(
volatile
GSA_ADC_18BIT_REG
*
)
adcPtr
[
numAdc
];
dataCount
=
adc18Ptr
->
BUF_SIZE
;
}
return
(
dataCount
);
}
// *****************************************************************************
/// \brief This routine sets up the ADC DMA registers once on code initialization.
/// @param[in] modNum The ID number of the ADC module to read.
// *****************************************************************************
int
gsc18ai32DmaSetup
(
int
modNum
)
{
/// Set DMA mode such that completion does not cause interrupt on bus.
adcDma
[
modNum
]
->
DMA0_MODE
=
GSAF_DMA_MODE_NO_INTR
;
/// Load PCI address (remapped local memory) to which data is to be delivered.
adcDma
[
modNum
]
->
DMA0_PCI_ADD
=
(
int
)
adc_dma_handle
[
modNum
];
/// Set the PCI address of board where data will be transferred from.
adcDma
[
modNum
]
->
DMA0_LOC_ADD
=
GSAF_DMA_LOCAL_ADDR
;
/// Set the number of bytes to be transferred.
adcDma
[
modNum
]
->
DMA0_BTC
=
GSAF_DMA_BYTE_COUNT
;
/// Set the DMA direction ie ADC to computer memory.
adcDma
[
modNum
]
->
DMA0_DESC
=
GSAF_DMA_TO_PCI
;
return
(
1
);
}
// *****************************************************************************
/// \brief This routine sets up the ADC DMA registers once on code initialization.
/// @param[in] modNum The ID number of the ADC module to read.
// *****************************************************************************
#if 0
int gsc18ai32DmaSetup32(int modNum)
{
/// Set DMA mode such that completion does not cause interrupt on bus.
adcDma[modNum]->DMA0_MODE = GSAF_DMA_MODE_NO_INTR;
/// Load PCI address (remapped local memory) to which data is to be delivered.
adcDma[modNum]->DMA0_PCI_ADD = (int)adc_dma_handle[modNum];
/// Set the PCI address of board where data will be transferred from.
adcDma[modNum]->DMA0_LOC_ADD = GSAF_DMA_LOCAL_ADDR;
/// Set the number of bytes to be transferred.
adcDma[modNum]->DMA0_BTC = 0x100;
/// Set the DMA direction ie ADC to computer memory.
adcDma[modNum]->DMA0_DESC = GSAF_DMA_TO_PCI;
return(1);
}
#endif
// *****************************************************************************
/// \brief This routine starts an ADC DMA operation. It must first be setup by
///< the gsc16ai64DmaSetup routine.
/// @param[in] modNum The ID number of the ADC module to read.
// *****************************************************************************
void
gsc18ai32DmaEnable
(
int
modNum
)
{
adcDma
[
modNum
]
->
DMA_CSR
=
GSAF_DMA_START
;
}
This diff is collapsed.
Click to expand it.
src/include/drv/gsc18ai32.h
0 → 100644
+
78
−
0
View file @
79829187
// \file gsc16ai64.h
/// \brief GSC 16bit, 32 channel ADC Module Definitions. See
///< <a href="http://www.generalstandards.com/view-products2.php?BD_family=16ai64ssc">GSC 16AI64SSC Manual</a>
///< for more info on board registers.
#define ADC_18AI32_SS_ID 0x3431 ///< Subsystem ID to identify and locate module on PCI bus
int
gsc18ai32Init
(
CDS_HARDWARE
*
,
struct
pci_dev
*
);
int
gsc18ai32CheckDmaDone
(
int
);
int
gsc18ai32WaitDmaDone
(
int
,
int
*
);
int
gsc18ai32Enable
(
CDS_HARDWARE
*
);
int
gsc18ai32Enable1PPS
(
CDS_HARDWARE
*
,
int
);
// int gsc18ai32AdcStop(void);
/// Structure defining ADC module PCI register layout as per user manual
typedef
struct
GSA_ADC_18BIT_REG
{
unsigned
int
BCR
;
///< Board Control Register at 0x0
unsigned
int
INTCR
;
///< Interrupt Control Register at 0x4
unsigned
int
IDB
;
///< Input Data Buffer at 0x8
unsigned
int
IDBC
;
///< Input Buffer Control at 0xc */
unsigned
int
RAG
;
///< Rate A Generator at 0x10
unsigned
int
RBG
;
///< Rate B Generator at 0x14
unsigned
int
BUF_SIZE
;
///< Buffer Size at 0x18
unsigned
int
BRT_SIZE
;
///< Burst Size at 0x1c
unsigned
int
SSC
;
///< Scan and Sync Control at 0x20
unsigned
int
ACA
;
///< Active Channel Assignment Register at 0x24
unsigned
int
ASSC
;
///< Board Configuration Register at 0x28
unsigned
int
AC_VAL
;
///< Autocal Values register at 0x2c
unsigned
int
AUX_RWR
;
///< Auxillary Read/Write Register at 0x30
unsigned
int
AUX_SIO
;
///< Auxillary Sync Control Register at 0x34
unsigned
int
SMUW
;
///< Scan Marker Upper Word 0x38
unsigned
int
SMLW
;
///< Scan Maker Lower Word at 0x3c
unsigned
int
TUR
;
///< Test utility register at 0x40
unsigned
int
PTCL
;
///< Pretrigger counter low at 0x44
unsigned
int
PTCH
;
///< Pretrigger counter high at 0x48
unsigned
int
RSV1
;
///< Reserved 1 at 0x4C
unsigned
int
RSV2
;
///< Reserved 2 at 0x50
unsigned
int
ECD
;
///< External Clock Divisor at 0x54
}
GSA_ADC_18BIT_REG
;
#define GSAF_FULL_DIFFERENTIAL 0x200
#define GSAF_64_CHANNEL 0x6
#define GSAF_32_CHANNEL 0x5
#define GSAF_8_CHANNEL 0x3
#define GSAF_8_OFFSET (8 * UNDERSAMPLE - 1)
#define GSAF_SOFT_TRIGGER 0x1000
#define GSAF_ENABLE_CLOCK 0x20
#define GSAF_RESET 0x8000
#define GSAF_DATA_PACKING 0x40000
#define GSAF_DMA_MODE_NO_INTR 0x10943
#define GSAF_DMA_MODE_NO_INTR_DEMAND 0x20943
#define GSAF_DMA_MODE_INTR 0x10D43
#define GSAF_DMA_LOCAL_ADDR 0x8
#define GSAF_DMA_TO_PCI 0xA
#define GSAF_DMA_START 0x3
#define GSAF_DMA1_START 0x300
#define GSAF_DMA_DONE 0x10
// #define GSAF_DMA_BYTE_COUNT 0x80
// #define GSAF_DMA_BYTE_COUNT 0x100
#define GSAF_DMA_BYTE_COUNT (32 * UNDERSAMPLE)
#define GSAF_ISR_ON_SAMPLE 0x3
// #define PLX_INT_ENABLE 0x900
// #define PLX_INT_DISABLE 0x800
#define GSAF_SAMPLE_START 0x10000
#define GSAF_SET_2S_COMP 0x40
#define GSAF_EXTERNAL_SYNC 0x10
#define GSAF_ENABLE_X_SYNC 0x80
#define GSAF_CLEAR_BUFFER 0x40000
#define GSAF_THRESHOLD 0x001f
#define GSAF_AUTO_CAL 0x2000
#define GSAF_DMA_DEMAND_MODE 0x80000
#define GSAF_18BIT_DATA 0x100000
#define GSAF_DATA_CODE_OFFSET 0x8000
#define GSAF_DATA_MASK 0xffff
#define GSAF_CHAN_COUNT 32
#define GSAF_CHAN_COUNT_M1 31
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment