Driver Development Kit (DDK)

cancel
Showing results for 
Search instead for 
Did you mean: 

EEPROM register control for PCI-6034E

Tom,

    I have the following code written in order to read the year of fabrication register from the EEPROM in the PCI-6034E; could you please make sure that this appears to function correctly, as I never had to interface with EEPROM that could render my card useless if I mess up this part of the programming?

Thanks,
Joe

inline void cycleClock(tESeries *board, int c)
{
    for (c=0;c<2;c++)
        board->SerialCommandRegister.writeSerialClock(board->SerialCommandRegister.kSerialClockLow);    // low clock
    for (c=0;c<4;c++)
        board->SerialCommandRegister.writeSerialClock(board->SerialCommandRegister.kSerialClockHigh);    // high clock
    for (c=0;c<2;c++)
        board->SerialCommandRegister.writeSerialClock(board->SerialCommandRegister.kSerialClockLow);    // low clock
}

void readEEPROM(iBus *bus)
{
    tAddressSpace  Bar1;
    tESeries *board;
    tSTC *theSTC;
    int c, i;
    unsigned short int data = 0, temp;

    Bar1 = bus->createAddressSpace(kPCI_BAR1);
    board = new tESeries(Bar1);
    theSTC = new tSTC(Bar1);
   
    theSTC->flushBus();
    theSTC->reset();

    // read EEPROM registers
    board->SerialCommandRegister.setRegister(0);            // clear softcopy
    board->SerialCommandRegister.writeEEPromChipSelect(board->SerialCommandRegister.kEEPromChipSelectHigh);    // enable EEPROM
    // shift in address
    for (i=0;i<3;i++)
    {
        board->SerialCommandRegister.setSerialData(0);        // send 0
        cycleClock(board, c);
    }
    board->SerialCommandRegister.setSerialData(0);            // A8 = 0
    cycleClock(board, c);
    for (i=0;i<2;i++)
    {
        board->SerialCommandRegister.setSerialData(1);        // send 1
        cycleClock(board, c);                                // forget the second 1, and you will destroy the card
    }
    for (i=0;i<6;i++)
    {
        board->SerialCommandRegister.setSerialData(1);        // A7..A2 = 1
        cycleClock(board, c);
    }
    for (i=0;i<2;i++)
    {
        board->SerialCommandRegister.setSerialData(0);        // A1..A0 = 0
        cycleClock(board, c);
    }
    // shift out data
    for (i=0;i<8;i++)
    {
    for (c=0;c<2;c++)
        board->SerialCommandRegister.writeSerialClock(board->SerialCommandRegister.kSerialClockLow);    // low clock
    for (c=0;c<4;c++)
        board->SerialCommandRegister.writeSerialClock(board->SerialCommandRegister.kSerialClockHigh);    // high clock
        temp = board->SerialStatus.readRegister();            // get bit 0 from data out
        data = ((data << 1) & 0xfe) | (temp & 0x01);        // assemble data byte
    for (c=0;c<2;c++)
        board->SerialCommandRegister.writeSerialClock(board->SerialCommandRegister.kSerialClockLow);    // low clock
    }
    board->SerialCommandRegister.writeEEPromChipSelect(board->SerialCommandRegister.kEEPromChipSelectLow);    // forget this, you destroy the card

    delete theSTC;
    delete board;
    bus->destroyAddressSpace(Bar1);
}           

0 Kudos
Message 1 of 5
(7,754 Views)

Hi Joe-

I have attached a snippet from another device DDK to show examples of EEPROM and CalDAC access on an STC-based device.  I have tested this on an STC-based S Series board with good results, so perhaps you can use it as well (or at least use it as a point of comparison for your code).

Hopefully this helps-

Tom W
National Instruments
0 Kudos
Message 2 of 5
(7,746 Views)
Thanks, Tom; that almost helped.  Now, I can bring the ADC values for zero voltage input down from 340 to 40, but the Windows test panel still gets the dead value down to -5.  I don't understand how I can load all CALDAC registers from the EEPROM as instructed and still get a different result.  This is my code so far; please tell me why my 6034E still behaves differently:

    //Calling test function
    copyEEPROM(bus);

inline void cycleClock(tESeries *board, const timespec * nap_p)
{
    board->SerialCommandRegister.writeSerialClock(
        board->SerialCommandRegister.kSerialClockLow);    // low clock
    clock_nanosleep(CLOCK_MONOTONIC,0,nap_p,NULL);
    board->SerialCommandRegister.writeSerialClock(
        board->SerialCommandRegister.kSerialClockHigh);    // high clock
    clock_nanosleep(CLOCK_MONOTONIC,0,nap_p,NULL);
    board->SerialCommandRegister.writeSerialClock(
        board->SerialCommandRegister.kSerialClockLow);    // low clock
    clock_nanosleep(CLOCK_MONOTONIC,0,nap_p,NULL);
}

void copyEEPROM(iBus *bus)
{
    tAddressSpace  Bar1;
    tESeries *board;
    tSTC *theSTC;
    u8 data[4];

    Bar1 = bus->createAddressSpace(kPCI_BAR1);
    board = new tESeries(Bar1);
    theSTC = new tSTC(Bar1);
   
    theSTC->flushBus();
    theSTC->reset();

    printf("EEPROM\treg\tvalue\tCALDAC reg\n");
    readEEPROM(board, data);
    printf("\t%d\t%d\t%d\n", 439, data[0], 2);
    printf("\t%d\t%d\t%d\n", 440, data[1], 1);
    printf("\t%d\t%d\t%d\n", 441, data[2], 11);
    printf("\t%d\t%d\t%d\n", 442, data[3], 4);
    writeCALDAC(board, data);

    delete theSTC;
    delete board;
    bus->destroyAddressSpace(Bar1);
}           

void readEEPROM(tESeries *board, u8 data[4])
{
    int i, id;
    u8 temp;
    u16 command = 0, eeprom_reg = 439;
    const timespec nap = {0, 1000};

    // create data to send
    for (i=0;i<8;i++)
        command = (command << 1) + ( (eeprom_reg >> i) & 1 );    // A7:A0
    command = (command<<8) + 0xD0;                                // A8 = 1
    printf("command = %d\n", command);
    // read EEPROM registers
    board->SerialCommandRegister.setRegister(0);                // clear softcopy
    board->SerialCommandRegister.writeEEPromChipSelect(
        board->SerialCommandRegister.kEEPromChipSelectHigh);    // enable EEPROM
    // shift in address
    for (i=0;i<16;i++)
    {
        board->SerialCommandRegister.writeSerialData((u8)((command >> i) & 1));
        cycleClock(board, &nap);
    }
    // shift out data
    for (id=0;id<4;id++)
        for (i=0;i<8;i++)
        {
            board->SerialCommandRegister.writeSerialClock(
                board->SerialCommandRegister.kSerialClockLow);    // low clock
            clock_nanosleep(CLOCK_MONOTONIC,0,&nap,NULL);
            board->SerialCommandRegister.writeSerialClock(
                board->SerialCommandRegister.kSerialClockHigh);    // high clock
            clock_nanosleep(CLOCK_MONOTONIC,0,&nap,NULL);
            temp = board->SerialStatus.readEEPROMOut();            // get bit 0 from EEPROM out
            data[id] = (data[id] << 1) + temp;                    // assemble data byte
            board->SerialCommandRegister.writeSerialClock(
                board->SerialCommandRegister.kSerialClockLow);    // low clock
            clock_nanosleep(CLOCK_MONOTONIC,0,&nap,NULL);
        }
    board->SerialCommandRegister.writeEEPromChipSelect(
        board->SerialCommandRegister.kEEPromChipSelectLow);        // forget this and you destroy the card
}

void writeCALDAC(tESeries *board, u8 data[4])
{
    int i, id;
    u16 command;
    const timespec nap = {0, 1000};
    const u8 address[4] = {2, 1, 11, 4};

    board->SerialCommandRegister.setRegister(0);                // clear softcopy
    board->SerialCommandRegister.writeEEPromChipSelect(
        board->SerialCommandRegister.kEEPromChipSelectLow);        // forget this and you destroy the card

    for (id=0;id<4;id++)
    {
        command = 0;
        for(i=0;i<8;i++)
            command = (command << 1) + ((data[id] >> i) & 1);
        command = (command << 4) + address[id];
        for(i=0;i<12;i++)
        {
            board->SerialCommandRegister.writeSerialData((u8)((command >> i) & 1));
            clock_nanosleep(CLOCK_MONOTONIC,0,&nap,NULL);
            board->SerialCommandRegister.writeSerialClock(
                board->SerialCommandRegister.kSerialClockLow);    // low clock
            clock_nanosleep(CLOCK_MONOTONIC,0,&nap,NULL);
            board->SerialCommandRegister.writeSerialClock(
                board->SerialCommandRegister.kSerialClockHigh);    // high clock
            clock_nanosleep(CLOCK_MONOTONIC,0,&nap,NULL);
        }
        board->SerialCommandRegister.writeSerialDacLoadNum(1);
        clock_nanosleep(CLOCK_MONOTONIC,0,&nap,NULL);
        board->SerialCommandRegister.writeSerialDacLoadNum(0);
        clock_nanosleep(CLOCK_MONOTONIC,0,&nap,NULL);
    }

    board->SerialCommandRegister.writeRegister(0);    // low clock

    return;
}
0 Kudos
Message 3 of 5
(7,726 Views)

Hi Joe-

It looks like you're reading from the factory CalDAC section of the EEPROM.  DAQmx uses the user section instead, and it could potentially be more up to date in the event that you performed a self calibration or other adjustment to the device after the most recent factory calibration.  Instead of EEPROM offsets 439-442, try using 366-369 instead.  For best results (since it sounds like you have a Windows system running NI-DAQmx), you can perform a self calibration in MAX before trying to perform your own adjustments using the DDK.

Please give this a shot and let me know how it goes-

Tom W
National Instruments
0 Kudos
Message 4 of 5
(7,723 Views)
Tom,

I tried both register groups--the one documented in the RLP manual, yet still not advertised for my specific card, and the other, which you mentioned but the documentation doesn't--and I get no different results (in fact, both groups of registers contain identical values).

I understand that NI-DAQmx can do its own zeroing, and I can't use that but can still load in my own calibration coefficients. What really bothers me is that, after DAmx initialized the board in Windows and I reboot and load my own calibration values, the zero values for the acquired channel do not change. When I then clear the CALDACs, I now have an offset in the zero values (this difference between pre- and post-DAQmx calibration with the CALDACs cleared is equal to the difference between pre- and post-DAQmx calibration with the CALDACs set to the 366-series EEPROM registers). How can I clear or alter all four CALDAC channels and yet still see remnants of the DAQmx session from before? What else is being altered in the card, if not these four channels?

Thanks,

Joe
0 Kudos
Message 5 of 5
(7,719 Views)