Instrument Control (GPIB, Serial, VISA, IVI)

cancel
Showing results for 
Search instead for 
Did you mean: 

How to function GPIB interface based on TNT4882 in embedded linux?

Hi everyone,

 

     I`m developing a device with a GPIB interface based on TNT4882 chip, but now I got caught up in some difficulties and could not move forward. Because of my poor linux knowlege and english, I`m very appreciated if someone give me some advice.

 

Situation is:

         The device is runnig an embedded linux system having 2.6.13 kernel and its mcu is Samsung 2440 arm9. TNT4882 chip is controlled by the 2440 mcu on the board in generic pin mode,   Now I have already realized a tnt4882 linux driver, and write a typical program app for my device to configure the tnt4882 according to TNT4882 Programmer Reference Manual in Chapter 4. The program app`s function includes initializing the chip, setting tnt4882 gpib address, enabling irq..., then initializing READ data transferring to prepare the device for receving data througth GPIB capble. If the devie receives some data string like "*IDN?", the app would print the data string "*IDN?" and write "AAAA,1.0.0-0.0" to gpib as a talker. After sending out the string, the app would go to READ status as a listener, in other word the app is in a dead loop.

 

        The GPIB caple is an  Agilent 82357A USB-GPIB cable. I pluged the usb of 82357A to my PC and the gpib of 82357A to my device. After that I started up the Agilent IO Expert to auto-find my device with GIPB connection. The IO expert found my device, showing the address "GPIB::10::INSTR" up quickly and then crossed the gpib address to say the device is not available. On my device side, my device  printed the receiving data string "*D?",  though not the complete "*IDN?". 

        I also use another Windows app based on VISA library to connect my device at the address "GPIB::10::INSTR", but the Windows app failed to open the connection with VISA error "VI_ERROR_INV_OBJECT" in viOpen.

 

My question is:

1, Could anybody give me some advice that how to program an proper app to enable my GPIB function on my device side basing on embedded linux?

2, Whether it is enough to program my device side`s  app  by referencing to TNT4882 Programmer Reference Manual for my embedded 2.6 linux to make the device to be found by Agilent IO Expert or NI MAX?

3, As you know, my device read the "*D?" string, but not "*IDN?". How to receive the right data?

4, I have the NI-Device DDK 1.6 code, I think it is a little complicated. Could it give me some tips to realize my GPIB function on my embedded linux device? you know DDK1.6 is just for 2.4 kernel and it`s written in C++, not in C.

5, I have doubt that my device app runing in embedded linux does not deal with GPIB connection properly, could you give me some advice on doing with that?

 

Many many Thanks for your great help.

 

0 Kudos
Message 1 of 12
(6,405 Views)

Hello,

 

Thank you for your complete system description.  I don't think that you are having hardware problems, but it may be useful if this problem continues.

 

1, Could anybody give me some advice that how to program an proper app to enable my GPIB function on my device side basing on embedded linux?

 

We do not have an embedded linux example, but we do have one that is used in Windows...It is a source code package that you can use as an example.

 

http://joule.ni.com/nidu/cds/view/p/id/223/lang/en 

 

2, Whether it is enough to program my device side`s  app  by referencing to TNT4882 Programmer Reference Manual for my embedded 2.6 linux to make the device to be found by Agilent IO Expert or NI MAX?

 

I don't have any experience with Agilent IO software, but if it is giving you an identification query, all your device must do is send something that the agilent software expects.  Basically, you are almost there...once you receive the full string from Agilent and send a proper response, I would expect it to show up.

 

3, As you know, my device read the "*D?" string, but not "*IDN?". How to receive the right data?

 

This is likely happening for two reasons. The FIFO is probably set in 16-bit mode, but you are only reading the first 8 bits...That is why you are only receiving every other byte.  Either chagne the FIFO to 8-bit or read 16 bits at a time....I'm not sure what the source code package does.  If you follow the source code, it will be set up correctly.

 

I don't really have answers to your other questions.  I'm hoping that this is enough to get you started.  Let me know if you get stuck or have additional questions.

 

Steven T.

0 Kudos
Message 2 of 12
(6,362 Views)

Hi Steven,
    Thank you for your great help.


    Your advice is just the key to some of my questions. Now my device could receive

the right "*IDN?" from Agilent IO Expert after I read FIFOB,then FIFOA when TNT works in

16-bit mode, this is because the offsets of all TNT4882 registers are the twice of

origin in my device. So I think my device could receive data through GPIB interface properly.  Now I used the

ESP-488 (http://joule.ni.com/nidu/cds/view/p/id/223/lang/en) source code NGPIB_IO.c and

EX5.c in the directory of ESP-488\NOTNT\ as an example when I debug the sending-data

function of my device. But I failed to send any data like "Acery,XXXXX,NX100023,1.0-0-

0.0" to Agilent IO Expert or my Windows VISA app using viScanf.


      Values of some registers are below when my device was trying to send data to my

Windows VISA app:
ADSR  0X4A
SASR  0X70
STS1  0X10
STS2  0XDA
BSR   0X21
ISR3  0X48
ISR1  0X2


      The code of sending function of my device just followed the example "NGPIB_IO.c

and EX5.c". But I don`t know why.
      I`m very appreciated for your help.

0 Kudos
Message 3 of 12
(6,355 Views)

           The code of sending function of my device just followed the example "NGPIB_IO.c

and EX5.c". The TNT was also working in 16-bit mode, when I send out my data from my

device, I firstly write the 1st byte to FIFOB, then the 2nd byte to FIFOA, But I don`t

know why it cannot send out any data to my app.

0 Kudos
Message 4 of 12
(6,351 Views)

Hi,


        Thanks everybody for paying attention to my questions.
        Until then, my device could receive data like "*IDN?" and send data like "ACERY\n" to my VISA app using viRead function. Every time, my device writed data out to my VISA app through GPIB, my VISA app would pop up an error named Reading-TIMEOUT, then I disply the maybe receiving data and the data was just the string sent out by my device like "ACERY".  Could anybody give me some suggestions about how to solve this problem.Thank you very much.

        Some registers` value were below after my device sent out the data:
isr0    0x25
isr1    0x0
isr3    0x19
adsr   0x4a
sasr   0x70
sts1   0x8b
sts2   0xda
bsr     0x31

0 Kudos
Message 5 of 12
(6,334 Views)

Hi Steven,

    Could you give me some another suggestion?  Thanks very much sincerely!

0 Kudos
Message 6 of 12
(6,329 Views)

Hello,

 

Again, thank you for such a complete register dump.  Based on the information you provided I think that I see where the hang-up could be.

 

Observations:

1.  nba - New Byte Available is not set.  From what I can tell, this gets set after performing the configuration required for sending data.

2.  FIFOB - I see that FIFOB is not empty, however...FIFOA is empty.  Since the FIFO is set to 16-bit mode, this could be a problem.

3.  DMA - I also see that you may be attempting to perform DMA...is that the case?

 

From the data you gave, I think that there is a problem with the way that the FIFOs are getting used.  You can always limit the FIFO to 8 bit mode and perform the reads/writes on only one register.  If you are using programmed IO, you can use the GPIB Transfers section as a guide along with the example code (page 4-7 of the TNT4882 Programmer Reference Manual). 

 

We may be able to find the problem if you are comfortable with attaching your initialization code for the transfer as well as the code that performs the transfer.  I can tell that there is not a problem with the controller because the TNT4882 is correctly addressed to talk.

 

Steven T.

 

0 Kudos
Message 7 of 12
(6,328 Views)

Hi Steven,

 

     Thanks for your expert advice.


     I`m just programing TNT4882 working in Programmed-I/O mode (not DMA) to transfer

data. The code for Programmed-I/O is coded following ESP-488 source code(NGPIB_IO.c and

EX5.c) (http://joule.ni.com/nidu/cds/view/p/id/223/lang/en) in the dir of ESP-488\NOTNT\ as

an example, referencing Chapter 4 in TNT4882 Programmer Reference Manual. I`m sorry I cannot

show you original source code, but I would show my register-configuration sequence to you.
 
     The offsets of all the registers in TNT4882 in our device is just as twice as the

offsets specified in page 3-2, 3-3 of TNT4882 Programmer Reference Manual. So the offset of

FIFOB would be 0x30, then FIFOA is 0x32. In TNT4882 reading and writing, I use 16-bit mode

to read and write data. When I read data from TNT4882, I first read FIFOB then FIFOA to get

a complete word, and I can get the right data from TNT4882. As same as the reading, when I

write data to TNT4882, I first write the 1st byte to FIFOB, then the 2nd byte to FIFOA to send a complete word. Here maybe it has something wrong with my operation when I write data.
 
      Now I would show the write-data code sequence:
When I detect the TNT4882 is in Talker mode from ADSR, I will call the initializing writing

code for writing-data-transfer:

  TNT_Out(R_cmdr,F_resetfifo);

  TNT_Out(R_cnt0, (char)(twos_cnt));      /* Load twos compliment count     */
  TNT_Out(R_cnt1, (char)(twos_cnt>>8));   /*  into TNT count registers      */
  TNT_Out(R_cnt2, (char)(twos_cnt>>16));
  TNT_Out(R_cnt3, (char)(twos_cnt>>24));

  TNT_Out(R_imr0,B_glint);              /* Set write to imr0 to be sure   */
  TNT_Out(R_auxmr,HR_auxrj|0);          /*   B_to is cleared              */

  TNT_Out(R_imr1, B_err);       /* End transfer on err            */
  TNT_Out(R_eosr, 0);     /* Set EOS byte                   */
  TNT_Out(R_auxmr,HR_auxra|F_hlda)
  TNT_Out(R_cfg , (B_tlchlte|B_16bit));  // I don`t set time-out attribute.
  TNT_Out(R_auxmr,F_hldi);               /* Hold off immediately           */
  TNT_Out(R_cmdr, F_go);
--------------------------------------------
       During the writing-data-transfer, I use the status of END|EOS|ERR|B_done|B_tlcint to

control the data transfer. Such as if I transfer the "ACER\n", I write the data out use the

following code(16-bit mode):
TNT_Out(FIFOB,'A');
TNT_Out(FIFOA,'C');
TNT_Out(FIFOB,'E');
TNT_Out(FIFOA,'R');
TNT_Out(FIFOB,'\n');
--------------------------------------------
       After aborting transfer of writing:
 TNT_Out(R_cmdr,F_stop);
 TNT_Out(R_cmdr,F_resetfifo);

 if(TNT_In(R_isr1)&B_end)                /* If we received an END          */
    TNT_Out(R_auxmr,F_clrEND);            /*   Clear status bit             */

 if(TNT_In(R_isr1)&B_err) {
    TNT_Out(R_auxmr,F_clrERR);            /* Clear error bit                */
   
 if(io_type==OUTPUT) {
      TNT_Out(R_hssel,F_onechip|B_go2sids); /* if error set to idle state.    */
    }
-------------------------------------------
      I have to notice that during the chip-initializing after power on, I set the T1 delay to 1100ns.

 

Thanks for your great help again.
Have a good day.

0 Kudos
Message 8 of 12
(6,323 Views)

Hi sir,
       As what you said, I has modified the code of performing transferring data for write operation. I set

the CFG register to 8-bit mode and filled the outputting data into FIFOB by byte. The code of initializing of

the write-transfer and the code of Post termination is the same as the code in the last response. Now my device

can write data successfully to my VISA app with viRead through GPIB, such as the data

"Acery,XXXXX,xxxxxxxxx,2.5-5.20-23", but my VISA app still pops up the TIMEOUT on the function of viRead, in

other words, my device program doesn`t solve the problem that you pointed yesterday. I tried a few of method to

solve the problem, following the ESP-488 source code example, but all still failed. I dumped some registers

after initialization of write-transfter and the same registers after write-transfer. I really wish you or

others could help me to solve this problem. Thanks very much!

 

registers after initialization of write-transfer and before write-transfer:
isr0 0x21
isr1 0x0
isr3 0x48
------------
adsr ox4a
sasr 0x70
sts1 0x10
sts2 0x9a
bsr  0x21

 

registers after write-transfer:
isr0 0x21
isr1 0x2
isr3 0x48
------------
adsr ox4a
sasr 0x70
sts1 0x10
sts2 0x9a
bsr  0x21

 

registers after a few seconds(TNT was still Talker):
isr0 0x21
isr1 0x0
isr3 0x48
------------
adsr ox4a
sasr 0x70
sts1 0x10
sts2 0x9a
bsr  0x31


       After write-transfer, my device program cannot detect any condition of ERR,END,EOS,DONE,TLCINT in

isr0,isr1,isr2, isr3 to do the post-termination action.


       As you can see, some registers above almost donn`t change. I really donn`t know how to solve the

TIMEOUT problem and how to notify my VISA app that the transfer is completed.


 At last could you give me an example of how to initialize the write-transfer?

 

 Thanks!

0 Kudos
Message 9 of 12
(6,283 Views)

Hi,

 

Could any NI engineer give me some advice?

 

Thanks very much!  

 

0 Kudos
Message 10 of 12
(6,271 Views)