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;
}
}
}