Instrument Control (GPIB, Serial, VISA, IVI)

cancel
Showing results for 
Search instead for 
Did you mean: 

TNT4882: No interrupt on NEF

Thanks for straightening me out on the END issue. I have re-written my receive code, and queries seem to work as desired.

I am still stuck on the ENOL issue (a write is still successful only on every other try). I am confused by your statement regarding "both NRFD and NDAC were unasserted." Shouldn't both of these signal be unasserted if the instrument (i.e., my board) is ready to listen? What do you suggest I monitor to see what is happening? I can look at the TNT4882 registers via my code, monitor bus traffic via NI Spy, and look at the handshake lines with a scope.

Thanks again,

Steve
0 Kudos
Message 11 of 19
(2,838 Views)
If a device is ready to accept a data byte, NRFD* should be unasserted and NDAC* should be asserted. Those two signals, along with DAV* make up a 3-wire interlocked handshake. By interlocked, once DAV asserts, NRFD will then assert, then NDAC will unasssert. Then DAV will unassert, NDAC will assert followed by NRFD unasserting (once the device is ready for the subsequent data byte). In other words, at the start of a transfer, all listening devices must assert NDAC. If nobody is asserting NDAC, then both NRFD and NDAC will be unasserted at the beginning of a transfer and the host will assume that there are no listeners.

As far as ENOL issue is concerned, I would first start to use NI Spy
since this error should not really be possible. I would like to see what exactly the error is (feel free to post the NI Spy log). The reason it is odd is because you are trying to make a talker out of the device, not a listener.
0 Kudos
Message 12 of 19
(2,838 Views)
Attached is a NI Spy log file that shows the good and the bad. The first several entries are the results of queries, all successful. The next few entries are the results of writes followed by reads, again all successful. The last group are repetitive writes. As you will see, every other one is successful, with those in between generating ENOL.
0 Kudos
Message 13 of 19
(2,592 Views)
I think I know what is going on. What does your device do when it recevies the "online" command. My assumption is that it is going to write eitehr 00 or 02 to the AUXMR register. If it does that, you will reset all of your state machines. This will make your device LIDS instead of LACS (like it was). The NI-488.2 device-level calls by default use a smart readdressing scheme. If the bus is already addressed like the call needs it to be, it will not send out the command bytes to readdress the bus.

Well, when you send the online command, the NI-488.2 driver knows that the controller is a talker and the device is a listener. Therefore, when you send the subsequent online c
ommand, it does not readdress the bus. However, if you have reset the TNT and move the TNT into LIDS, the TNT is now not addressed as a listener anymore and you get an ENOL error. The next time you send the online command, NI-488.2 will readdress the bus since the last call returned an error.

Ideally, you would not have a method that actually resets the hardware to that extent. The other option is to make the NI-488.2 application perform readdressing always (ibconfig IbcREADDR). This is not as nice of a on option since that is not the default behavior of NI-488.2 so your device may not be as portable.
0 Kudos
Message 14 of 19
(2,591 Views)
You _are_ the GPIB Guru! I did not understand the default addressing scheme, and your good explanation helped immensely. As you deduced, I was setting and clearing pon after a read. I was under the impression that this was the preferred approach to clearing interrupts. I deleted the pon calls and now read the interrupt registers to clear them, and things now seem to be working.

Your patience and help is greatly appreciated. My interface still needs polishing, but it now functions.

Thanks again,

Steve
0 Kudos
Message 15 of 19
(2,591 Views)
Excellent news! There are two ways to clear interrupt register. In normal mode, if you read ISR0,ISR1, or ISR2 it will clear. If you use static bits (SISB bit in AUXRI) you must manually clear each bit with a call to the AUXMR.

I have typically used static bits becuase it gives you a bit more control. If you do not use static bits, you need to make sure that you handle all interrupts since they will disappear once read. However, both ways are successful and typically depend on programming style.

Good luck completing your project.
0 Kudos
Message 16 of 19
(2,592 Views)

I have the same trouble with my designed TNT4882 Board like this, with M&A Explorer and ENOL Error. I have had developed GPIB Talkter/listener Card based on TNT4882 Chip. Till developement process i did used an Agilent GPIB-USB controller and all things were fine. Since I use  NI  controller and M&A Explorer I found this error. This problem seems to be controller idepended but depended on used Software. Agilent Connection Expert is able to write more than one message without reads (its doesnt matter if I use Agilent or NI GPIB-USB controller). NI M&A Ex. throws an Error if I try one new write without read.

 

 


// main.c   
gpib_addr_state = TNT_In(R_ADSR);
if(gpib_addr_state & B_TA)    {                    //  addressed to talk    
      tnt4882_send_data();
}
else
if(gpib_addr_state & B_LA) {                    //  addressed to listen
      tnt4882_receive_data();
}
 //#########################################################
// tnt4882_driver.c
unsigned char tnt4882_receive_data(void) {
    
    static u16 counted_bytes = 0;
    u8 isr3;
    u16 max_trials = 500;


    // printf("\r\nListen: ");
    tnt4882_setup_read();
    
    while(!(TNT_In(R_ISR3) & E_DONE) ){

        while (((isr3 = TNT_In(R_ISR3)) & E_NEF) && max_trials > 0) {
            char_arr[counted_bytes] = TNT_In(R_FIFOB);
            counted_bytes++;
            max_trials--;
        }
    }
    isr3 = TNT_In(R_ISR3);

    if (isr3 & E_DONE) {
        if ((char_arr[counted_bytes - 1] == '\r') || (char_arr[counted_bytes - 1] == '\n')) {
            char_arr[counted_bytes - 1] = '\0';    // replace '\n' with '\0'
        }
        else {
            char_arr[counted_bytes] = '\0';
        }

        if (!global_flag.received) {
            gpib_cmd = &char_arr[0];
        
            global_flag.received     = 1;
            global_flag.gpib_rxrdy     = 1;
        }

        counted_bytes = 0;
    }
    
    TNT_Out(R_CMDR, STOP);
    TNT_Out(R_CMDR,    RstFIFO);
    
    // Clear Error status bit               
       TNT_Out(R_AUXMR, ClrERR);
    // Clear End status bit  
    TNT_Out(R_AUXMR, ClrEND);   
    // clear time out condition            
    TNT_Out(R_AUXRJ, 0x00);

    // Clear Power-On Local message
    TNT_Out(R_AUXMR, 0x00);  
   
    if (!max_trials) tnt4882_init();

    return 1;
}
 
 void tnt4882_setup_read(void) {

    //######## 1) Reset Fifo Register
    TNT_Out(R_CMDR,    RstFIFO);
    //######## 2) Set B_tlchlte to halt when interrupt condition sets and B-in for In
    TNT_Out(R_CFG,    (B_tlchlte | B_in));
    //######## 3) Load Data Count Registers: max. 128 bytes
    TNT_Out(R_CNT0,    0x01);
    TNT_Out(R_CNT1,    0x00);

    TNT_Out(R_AUXMR, 0x86);            // holdoff on EOS
    //######## 4)
    TNT_Out(R_IMR1, E_END);            // End byte detection
    //######## 5) Send Go Command
    TNT_Out(R_CMDR,    0x04);
    //######## 6) Send Go Command
    TNT_Out(R_IMR3, (E_TLCINT | E_NEF | E_DONE));        // Enable Intrrupts from ISR0 and ISR1    
    //######## 7) Issue Release Holdoff
    TNT_Out(R_AUXMR, RHDF);

    //######## Set Timeout Condition to 1ms
    TNT_Out (R_AUXRJ, 0x05);
}

The programming of tnt4882 makes me creasy so I was very happy about since I was ready, but now...

 

I tried to read ISR2  but this seems not to be usefull for my problem. Someone an idea?

 

thx.

Message Edited by Artur Funk on 05-25-2009 08:14 AM
0 Kudos
Message 17 of 19
(2,126 Views)

I found following things:

 

TNT4882 is not responsible for new data if tnt4882_init() condition is not done.

here are the TNT4882 Register Bytes captchured in read function after "TNT_Out(R_AUXMR, ClrEND);"

 


Addr 0(0)      Byte: 0XA
Addr 1(0X1)    Byte: 0XFF
Addr 2(0X2)    Byte: 0X2
Addr 3(0X3)    Byte: 0XFF
Addr 4(0X4)    Byte: 0X13
Addr 5(0X5)    Byte: 0XFF
Addr 6(0X6)    Byte: 0X99
Addr 7(0X7)    Byte: 0XFF
Addr 8(0X8)    Byte: 0X4A
Addr 9(0X9)    Byte: 0XFF
Addr 10(0XA)   Byte: 0X2A
Addr 11(0XB)   Byte: 0XFF
Addr 12(0XC)   Byte: 0X7
Addr 13(0XD)   Byte: 0XFF
Addr 14(0XE)   Byte: 0XE0
Addr 15(0XF)   Byte: 0XFF
Addr 16(0X10)  Byte: 0XAB
Addr 17(0X11)  Byte: 0X2A
Addr 18(0X12)  Byte: 0X7
Addr 19(0X13)  Byte: 0
Addr 20(0X14)  Byte: 0X7
Addr 21(0X15)  Byte: 0
Addr 22(0X16)  Byte: 0
Addr 23(0X17)  Byte: 0X3C
Addr 24(0X18)  Byte: 0X2A
Addr 25(0X19)  Byte: 0XFF
Addr 26(0X1A)  Byte: 0X99
Addr 27(0X1B)  Byte: 0X60
Addr 28(0X1C)  Byte: 0X9A
Addr 29(0X1D)  Byte: 0X3D
Addr 30(0X1E)  Byte: 0
Addr 31(0X1F)  Byte: 0X21

 

0 Kudos
Message 18 of 19
(2,118 Views)
Now I have the same problem as you. That is with agilent VISA I can wirte command every time, but with NI488.2 only succeed in writing command every other time. I want to know how you solved the problem. Can you share your success? Thanks!
0 Kudos
Message 19 of 19
(2,035 Views)