Driver Development Kit (DDK)

cancel
Showing results for 
Search instead for 
Did you mean: 

Configuring PCI-MIO-16E-1 from DDK and performing DIO

I think you have BAR0 and BAR1 swapped. Rather than comparing the addresses in HandleStartDevice, I would assume that the first memory resource is BAR0 and the second is BAR1.

Also, how is pPartialDescriptor assigned in HandleStartDevice?

geoff
--
Geoff Schmit
Huskie Robotics, FIRST Team 3061 Lead Mentor
http://team3061.org/
@team3061
0 Kudos
Message 11 of 23
(6,207 Views)

When I switched the bases (by assigning the first one to  baseBAR0 and the second to baseBAR1), I read

the value 40133111.

Looking at Memory usage
BAR0 Logical Base is: 0xFEAFD000
BAR0 Virtual Base is: 0xF8C27000
Length of mapping is 4096
Iterating through resource number 1
Iterating through resource number 2
Looking at Memory usage
BAR1 Logical Base is: 0xFEAFC000
BAR1 Virtual Base is: 0xF8BBA000
Length of mapping is 4096
...

Attempting to read address F8C27460
Read  40133111

0 Kudos
Message 12 of 23
(6,207 Views)
This is the beginning of my HandleStartDevice where I do the assignment to pPartialDescriptor:
 
NTSTATUS HandleStartDevice( IN PDEVICE_OBJECT pDO,
       IN PIRP pIrp ) {

 DebugPrint(INFO,"Enter HandleStartDevice \n");
 //
    // The device is starting.
    //
    // We cannot touch the device (send it any non pnp irps) until a
    // start device has been passed down to the lower drivers.
    // First pass the IRP down.
    //
 NTSTATUS  status = STATUS_SUCCESS;
 POWER_STATE powerState;
 PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDO->DeviceExtension;
 // The stack location contains the Parameter info
 PIO_STACK_LOCATION pIrpStack =
      IoGetCurrentIrpStackLocation( pIrp );
 status =
  PassDownPnPSynchronously(pDevExt->pNextLowerDevice, pIrp);
    if (NT_SUCCESS (status)) {
        //
        // Lower drivers have finished their start operation, so now
        // we can finish ours.
        //
 
 PCM_RESOURCE_LIST pRawResourceList,pTranslatedResourceList;    
 PCM_FULL_RESOURCE_DESCRIPTOR pRawFullDescriptor, pTranslatedFullDescriptor;
 PCM_PARTIAL_RESOURCE_LIST raw, translated;
 PCM_PARTIAL_RESOURCE_DESCRIPTOR pPartialDescriptor;  <-----------------------
 int i;
 //
    // Do whatever initialization needed when starting the device:
    // gather information about it,  update the registry, etc.
    // At this point, the lower level drivers completed the IRP
    //
    if ((NULL != pIrpStack->Parameters.StartDevice.AllocatedResources) &&
        (NULL != pIrpStack->Parameters.StartDevice.AllocatedResourcesTranslated)) {
  
 pTranslatedResourceList = 
  pIrpStack->Parameters.StartDevice.
     AllocatedResourcesTranslated;
 pRawResourceList = 
  pIrpStack->Parameters.StartDevice.
    AllocatedResources;
 pTranslatedFullDescriptor =
  pTranslatedResourceList->List;
 pRawFullDescriptor =
  pRawResourceList->List;
 raw = &pRawFullDescriptor->PartialResourceList;
 translated =
  &pTranslatedFullDescriptor->PartialResourceList;
 DbgPrint("Iterating through number resources %d\n",
  (int)translated->Count);
 for (i=0; i<(int)translated->Count; i++) {
  DbgPrint("Iterating through resource number %d\n",
   i);
  pPartialDescriptor =
   &translated->PartialDescriptors[i];
  switch (pPartialDescriptor->Type) {
   ...
}
}
0 Kudos
Message 13 of 23
(6,205 Views)
Congratulations! That is the expected value. You are now reading from BAR0. Now, try to put back you DIO code that writes to BAR1. If it doesn't work, please post the code and the debug output.

Also, while it probably doesn't matter, it would be best to use the raw resource list to obtain information about the BARs. I expect the raw and translated information is the same, but this may not always be the case. However, the translated resource list should be used for query information about interrupts.

geoff
--
Geoff Schmit
Huskie Robotics, FIRST Team 3061 Lead Mentor
http://team3061.org/
@team3061
0 Kudos
Message 14 of 23
(6,194 Views)
I assume I should see the DIO lights changing patterns, right? From debug output, I know
my user code calls DispatchWrite, but I don't see the lights going on.
I used both WRITE_REGISTER_USHORT and WRITE_REGISTER_ULONG,
but neither seem to work.
 
 
// offsets for registers from base
#define WINDOW_ADDRESS_REG     0x00    // 16-bit register
#define STATUS_REG              1    //  8-bit register
#define WINDOW_DATA_REG         0x01*2    // 16-bit register
#define DIO_PARALLEL_INPUT_REG 14    // 16-bit register
#define DIO_CONTROL_REG 0x0B
#define DIO_OUTPUT_REG 0x0A
//
// Define access functions for device registers.
//
void WriteWindowData( PDEVICE_EXTENSION pDevExt, USHORT bData ) {
 PUSHORT o = (PUSHORT)((PUCHAR) pDevExt->baseBAR1 + (USHORT) WINDOW_DATA_REG);
(WRITE_REGISTER_USHORT( o, bData ));
}
void WriteWindowAddress(PDEVICE_EXTENSION pDevExt, USHORT bData ) {
PUSHORT o = (PUSHORT)((PUCHAR) pDevExt->baseBAR1 + (USHORT) WINDOW_ADDRESS_REG);
(WRITE_REGISTER_USHORT( o, bData ));
}
 
NTSTATUS DispatchWrite (
  IN PDEVICE_OBJECT pDevObj,
  IN PIRP    pIrp   ) {
 DebugPrint(INFO,"Write Operation requested (DispatchWrite)\n");
 NTSTATUS status = STATUS_SUCCESS;
 PDEVICE_EXTENSION pDevExt =
  (PDEVICE_EXTENSION) pDevObj->DeviceExtension;
 PIO_STACK_LOCATION stack =
  IoGetCurrentIrpStackLocation(pIrp);
 // Access to DIO only in the windowed mode.
 // In this mode, the address of the register is first written
 // to the Window Address Register.
 // Configure all the digital lines as outputs.
 WriteWindowAddress(pDevExt,DIO_CONTROL_REG);
 WriteWindowData(pDevExt,0xFF);
  
 // Output the digital patterns.
 for (int i=0;i<=255;i++)
 {
  WriteWindowAddress(pDevExt,DIO_OUTPUT_REG);
  WriteWindowData(pDevExt,i);
 }
 return status;
}
0 Kudos
Message 15 of 23
(6,192 Views)
At this point you should be able to read and write to BAR1. Try reading the digital port rather than writing to it. Connect the +5V terminal to one or more of the digital lines and connect GND to some others. This removes any potential problems with whatever lights you are connecting to the digital lines.


geoff

--
Geoff Schmit
Huskie Robotics, FIRST Team 3061 Lead Mentor
http://team3061.org/
@team3061
0 Kudos
Message 16 of 23
(6,161 Views)

I connected DI 3 and 4 to +15V, and the rest of the DIs to Ground. I have connected LEDs to DIs 3 and 4 which are on. When I try to read the lines, I expect a digital pattern 0b00011000 corresponding to this input configuration. I read a different value.  

In particular, my register map for this E-series device (PCI-MIO-16E-1 or NI-Elvis) is:

// defines offsets for registers from base
#define WINDOW_ADDRESS_REG     0x00     // 16-bit register
#define WINDOW_DATA_REG              0x01*2  // 16-bit register

#define DIO_PARALLEL_INPUT_REG 7   
#define DIO_OUTPUT_REG                10
#define DIO_CONTROL_REG             11

There is a conflict between the DAQ-STC manual and the E-series RLPM. The E-Series RLPM indicates  DIO_PARALLEL_INPUT_REG to be 14. In the DAQ-STC, WINDOW_DATA_REG is 1 on page B-3 (Appendix B), but an example on page 7-7 uses 2 for WINDOW_DATA_REG. Also in DAQ-STC, DIO_PARALLEL_INPUT_REG  is 7 on page B-3. The E-series RLPM does not have any information for  DIO_OUTPUT_REG and DIO_CONTROL_REG. There differences are due to byte addressing of memory, but which one is correct?

My access functions for device registers are:

void WriteWindowData( PDEVICE_EXTENSION pDevExt, USHORT bData ) {
PUSHORT o = (PUSHORT)((PUCHAR) pDevExt->baseBAR1 + WINDOW_DATA_REG);
(WRITE_REGISTER_USHORT( o, bData ));
}

USHORT ReadWindowData( PDEVICE_EXTENSION pDevExt) {
 PUSHORT o = (PUSHORT)((PUCHAR) pDevExt->baseBAR1 + WINDOW_DATA_REG);
 return READ_REGISTER_USHORT( o );
}

void WriteWindowAddress(PDEVICE_EXTENSION pDevExt, USHORT bData ) {
PUSHORT o = (PUSHORT)((PUCHAR) pDevExt->baseBAR1 + WINDOW_ADDRESS_REG);
(WRITE_REGISTER_USHORT( o, bData ));
}

My dispatchRead looks like:
 
NTSTATUS DispatchRead (
  IN PDEVICE_OBJECT pDevObj,
  IN PIRP    pIrp   ) {
 ...
 // Configure all the digital lines as inputs.
 WriteWindowAddress(pDevExt,DIO_CONTROL_REG);
 WriteWindowData(pDevExt,0x00);
 WriteWindowAddress(pDevExt,DIO_PARALLEL_INPUT_REG);
 USHORT read = ReadWindowData(pDevExt);
 DebugPrint(INFO, "Read %hx\n", read);
 
 return status;
}
 
The value read is bc4c.
0 Kudos
Message 17 of 23
(6,139 Views)
First, please don't connect +15V to an digital input on an E-Series device. I would recommend simply connecting to the +5V terminal.

Second, appendix B of the DAQ STC manual specifies offset in in terms of 16-bit words which is why they are half what is specified in the E-Series RLP manual. So, they both are correct.

Third, the DIO_PARALLEL_INPUT_REG can be read directly. That is, without using the window registers. For example: READ_REGISTER_USHORT((PUSHORT)(((PUCHAR) pDevExt->baseBAR1) + DIO_PARALLEL_INPUT_REG)). However, DIO_PARALLEL_INPUT_REG should be defined to 14 since I'm casting the base address to a PUCHAR.

Hope this helps,

geoff
--
Geoff Schmit
Huskie Robotics, FIRST Team 3061 Lead Mentor
http://team3061.org/
@team3061
0 Kudos
Message 18 of 23
(6,128 Views)
I followed these steps, but I still I get a similar value back: I get *c4c where * changes every run.  
 *c4c is returned even if I disconnect the power source.  I wonder if I am printing correctly?
(I make sure the board is configured correctly by outputting the registers on BAR0).
 
// defines offsets for registers from base in terms of 8-bit words
#define WINDOW_ADDRESS_REG       0x00*2    // 16-bit register
#define WINDOW_DATA_REG               0x01*2    // 16-bit register
#define DIO_PARALLEL_INPUT_REG         7*2
 
#define DIO_OUTPUT_REG                          10
#define DIO_CONTROL_REG                       11
 
In my dispatchRead(), I now have.

 WriteWindowAddress(pDevExt,DIO_CONTROL_REG);
 WriteWindowData(pDevExt,0x00);
 USHORT read = READ_REGISTER_USHORT((PUSHORT)(((PUCHAR) pDevExt->baseBAR1) + DIO_PARALLEL_INPUT_REG));
 DebugPrint(INFO, "Read %hx\n", read);
0 Kudos
Message 19 of 23
(6,125 Views)
I'm running out of ideas. At this point it may be best for you to download the Measurements Hardware DDK and compare that code to your code.

geoff
--
Geoff Schmit
Huskie Robotics, FIRST Team 3061 Lead Mentor
http://team3061.org/
@team3061
0 Kudos
Message 20 of 23
(6,113 Views)