Instrument Control (GPIB, Serial, VISA, IVI)

cancel
Showing results for 
Search instead for 
Did you mean: 

TNT4882 / 8051 Programming

I've been struggling with the TNT4882 for a little while now, trying to get basic communication working over GPIB. I seem to be able to receive GPIB data now, but my current issue is that the TNT seems to stay addressed as a listener, whereas I would think that status should clear after I empty the FIFO. I've read through the Programmer Reference Manual, but it's tough to navigate, and it seems to be vague in key places (especially for the data transferring). I'd be greatly appreciative if someone could help show me how to get the status cleared so the TNT can then be configured as a talker and I can send responses to queries back. Also, if anyone cares to point out better ways to do things and other issues in my code, I'm all ears. This is test code, so some stuff is hard-coded now that won't be later.

Sorry the formatting is so messy, I attached a file so it'll be easier to read.


void init_tnt(void)
{
UCHAR i;
volatile xdat UINT16 *xptr;
UINT16 xval;
volatile xdat UCHAR *xchr;
UCHAR xcval;
UCHAR status, isr;
UCHAR buf[10];
char idn[] = "SBIR Infinity Controller\n";

for(i = 0; i < 10; i++)
buf[i] = 0;

i = 0;

LED1 = 0; LED2 = 0;

P3 = 0xFF;

TNTSRST = 1; //chip reset, active low

//printc('\r');
//printc('\n');
//printc('>');

xchr = (xdat UCHAR *)0x2000; //set base address of xchr pointer

xchr[CMDR] = 0x22; //soft reset

xchr[SPMR] = 0x80; //place chip in turbo+7210 mode
xchr[AUXMR] = 0x80;
xchr[SPMR] = 0x99;
xchr[AUXMR] = 0x99;

xchr[KEYREG] = 0x00; //0x00 to KEYREG

xchr[HSSEL] = 0x01; //put in one-chip mode
//xchr[HSSEL] = 0x00;

xchr[AUXMR] = 0x02; //assert local pon message

xchr[ADMR] = 0x31; //dual primary addressing mode

xchr[ADR] = 0x07; //set primary GPIB address as 7

xchr[ADR] = 0xE0; //disable secondary address
/*
xchr[SPMR] = 0x00; //initial serial poll response

xchr[AUXMR] = 0xE1; //remote config mode
xchr[AUXMR] = 0x60; //initial parallel response (clear PPR reg)

xchr[IMR0] = 0x00;//0x8D;//0x81; //IMR0 (interrupt 0)
xchr[IMR1] = 0x00;//0xDC;//0x9E; //IMR1 (interrupt 1)
xchr[IMR2] = 0x00;//0x03; //IMR2 (interrupt 2)
xchr[IMR3] = 0x00;//0x07; //IMR3 (interrupt 3)
*/

//xchr[HIER] = 0x00; //deglitching

/*xchr[AUXMR] = 0xC0;
xchr[AUXMR] = 0xD0;*/

xchr[AUXMR] = 0x00; //clear local power-on message
//xcval = xchr[CSR];
// xchr[IMR3] = 0x04;

/*for(xcval = 0; xcval < 16; xcval++)
xchr[FIFOA] = xcval*2;
for(xcval = 0; xcval < 16; xcval++)
xchr[FIFOB] = xcval*2+1;
for(xval = 0; xval < 16; xval++)
{
xcval = xchr[FIFOA];
//xcval = xchr[FIFOB];
LED1 = ~LED1;
}*/

for(xcval = 0; xcval < 240; xcval += 16)
{
for(i = 0+xcval; i < 16+xcval; i++)
{
xchr[FIFOA] = i;
}

for(i = 0+xcval; i < 16+xcval; i++)
{
xval = xchr[FIFOA];
if(xval != i)
{
LED1 = 1;
}
}
}

for(xcval = 0; xcval < 240; xcval += 16)
{
for(i = 0+xcval; i < 16+xcval; i++)
{
xchr[FIFOB] = i;
}

for(i = 0+xcval; i < 16+xcval; i++)
{
xval = xchr[FIFOB];
if(xval != i)
{
LED2 = 1;
}
}
}

//xchr[IMR3] = 0x0C;

/*for(i = 0; i < 8; i++)
{
xchr[BCR] = (0x01 << i);
}
xchr[BCR] = 0xA5;*/

while(1)
{
status = xchr[ADSR];

if(status & 0x02) //addressed as talker
{
//gpib_write

//first setup fifos,interrupts,etc
xchr[CMDR] = RESETFIFO; //reset FIFOA and FIFOB
xchr[CFG] = 0;//&= (UCHAR)~IN;
xchr[CNT0] = 0xE7; //2s complement of -25
xchr[CNT1] = 0xFF;
xchr[IMR1] |= ERR_IE; //set ERR_IE to detect no Listener errors
xchr[IMR2] &= 0x07; //clear DMAO and DMAI bits in IMR2
xchr[CMDR] = 0x04; //send GO command
xchr[IMR3] |= 0x0B; //set NFF IE, TLCINT IE, and DONE IE in IMR3

isr = xchr[ISR3];
i = 0;
while( ((xchr[CNT1] << 😎 + xchr[CNT0]) != 0x0000 )
{
if(isr & NFF)
xchr[FIFOB] = idn[i++];

isr = xchr[ISR3];
}

xchr[CMDR] = STOP;
xchr[CMDR] = RESETFIFO;

if(xchr[ISR1] & END_RX)
xchr[AUXMR] = CLR_END;
if(xchr[ISR1] & ERR_IE)
xchr[AUXMR] = CLR_ERR;
}
else if(status & 0x04) //addressed as listener
{
//gpib_read

//first setup fifos,interrupts,etc
xchr[CMDR] = RESETFIFO; //reset FIFOA and FIFOB
xchr[CFG] = IN; //set IN bit (not setting TLCHLTE-HALT bit for now)
xchr[CNT0] = 0x00; //write largest negative value to CNT regs because...
xchr[CNT1] = 0x80; //...they want a negative value which they upcount to zero
xchr[IMR1] |= END_RX; //set END IE bit to detect end END byte
xchr[IMR2] &= 0x07; //clear DMAO and DMAI bits in IMR2
xchr[IMR0] |= 0x02; //set timeout interrupt enable (TO IE)
xchr[CMDR] = 0x04; //send GO command
xchr[IMR3] |= 0x07; //set NEF IE, TLCINT IE, and DONE IE in IMR3

//wait for initial ready
//while(!(xchr[ISR3] & NEF));

//next we actually conduct the transfer:
isr = xchr[ISR3]; //read status, we're READY if NEF bit is set
i = 0;
while(isr & NEF)
{
buf[i++] = xchr[FIFOB];

isr = xchr[ISR3];
}


xcval = xchr[STS1];

xchr[CMDR] = STOP; //send STOP command
xval = (((xchr[CNT1] << 😎 + xchr[CNT0])) - 0x8000; //read bytes transferred
//xchr[CMDR] = RESETFIFO;
xcval = xchr[ISR3];

if(xchr[ISR1] & END_RX)
xchr[AUXMR] = CLR_END;
if(xchr[ISR1] & ERR_IE)
xchr[AUXMR] = CLR_ERR;
}
}
}
0 Kudos
Message 1 of 6
(5,109 Views)
Hey Yertle,
I found some information that you might find helpful in the programmer reference manual.  You mentioned that you find it tough to navigate sometimes so you may or may not have come across this inforamation.  In chapter 4 on page 166 (http://www.ni.com/pdf/manuals/370872a.pdf) there is a section on GPIB talker and listener conditions.  In this section they cite some commands such as "disable listener" and "disable talker" that may be helpful.
Scott G.
AE Specialist
National Instruments
0 Kudos
Message 2 of 6
(5,093 Views)
Thanks for the reference, but I don't think that's quite what I'm looking for. I hadn't seen those settings, but the way I'm reading them is that it will prohibit the TNT from being addressed as a talker or a listener. My particular problem is that after I am addressed as a listener and empty the FIFO and see the DONE bit, the TNT stays addressed as a listener. I don't know if I'm not properly finishing the transaction, or if there is a manual clearing of the listener state that I have to do.

Thanks.
0 Kudos
Message 3 of 6
(5,090 Views)
Hello yertle,
 
It depends on which register bit you are referring to.  There are a couple bits in combination that will tell if you have data ready at the fifo, if the fifo is not empty, or if the instrument is currently addressed as listener. 
 
If you are talking about being addressed as listener after you get the message and clear the FIFO, this is completely normal.  There are times when talkers will send communications to several listeners at a time.  There is a possibility that your instrument will simply receive more than one communication.  The state of the instrument is set by the controller on the GPIB bus.  Your instrument should be listening mode until the controller says otherwise.
 
If you are relying on the LACS bit to determine when a message is ready, I would recommend changing to checking for Not empty fifo and interrupts.
 
A sample TNT4882 driver can also be found here if you are interested:  http://joule.ni.com/nidu/cds/view/p/id/223/lang/en
 
Steven T.
0 Kudos
Message 4 of 6
(5,080 Views)
The one thing I'm not doing that that driver does is raising the MAV bit in the STB. Does this somehow signify the CIC that the TNT is done with the transfer? Do I stuff a special status byte there to tell the CIC the TNT is ready?

There is nothing else on the GPIB bus right now, just my computer and the TNT.

I can send data across from the CIC to the TNT, it's just I can't seem to get a reply. When I do a "Send and Read" from my computer (CIC), it sends and the TNT receives the command, but then it just sits there in the listener state. It never seems to get addressed as a talker, which I'm assuming means that the CIC doesn't know that the TNT has finished receiving the command...
0 Kudos
Message 5 of 6
(5,078 Views)

Yertle,

The MAV bit only lets the controller know that there is a message available when it is serial polled (see service requests in the TNT4882 programmers manual).  This doesn't send any signals to the CIC to let it know that everything finished.  You can check your controller side program to make sure that the write finished correctly.  If you are using the NI-488.2 driver, use NI-Spy to see if any errors are happening with the ibwrt.  If there are no errors and the ibrd executes, this means that the controller knows that the transfer has finished.

What error do you get from the ibrd when you are expecting a response?  If it is EABO (timeout), the instrument received the command, but is not outputting correctly.  The TNT4882 was successfully sent a talker command, but is for some reason not responding.  Make sure you are interrupting on ADSC in IMR2.  It lets you know when you have been addressed in a different way.  Then you can check ADSR to see if you are addressed as talker.

If you are receiving ENOL (no listeners), this means that the talk command never makes it to the instrument.

I hope this helps,
Steven T.

0 Kudos
Message 6 of 6
(5,061 Views)