summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael J. Chudobiak <mjc@avtechpulse.com>2012-12-07 11:39:09 -0500
committerMichael J. Chudobiak <mjc@avtechpulse.com>2012-12-07 11:39:09 -0500
commit401025aebc02eca587474e094fa50b2939f8a147 (patch)
tree08004457bc209b4bca1ed56b8bcc39560566d54b
parentcf492a7c67e82818e805a67aa5e1b91ec8a595b1 (diff)
modify gpib response sending so it does not hang if read never received
-rw-r--r--globals.h1
-rw-r--r--gpib.c223
-rw-r--r--gpib.h4
-rw-r--r--instr-daemon.c9
4 files changed, 115 insertions, 122 deletions
diff --git a/globals.h b/globals.h
index 5e5885b..2fa3f17 100644
--- a/globals.h
+++ b/globals.h
@@ -276,6 +276,7 @@ typedef struct {
int avrq_reg;
int last_rise_time_relay_setting;
char gpib_input_buffer[max_gpib_input_length];
+ gchar *pending_output_message;
} HWregStruct;
diff --git a/gpib.c b/gpib.c
index 6007cdf..7711e25 100644
--- a/gpib.c
+++ b/gpib.c
@@ -296,7 +296,7 @@ void TNT_4882_Status(int status_register,unsigned int byte,int operation)
if(set_srq) { // If SRQ desired
TNT_Out(R_auxmr,F_reqt); // Set request true
- } else {
+ } else {
TNT_Out(R_auxmr,F_reqf); // Set request false
}
@@ -349,11 +349,11 @@ static int TNT_INT_STATUS(void)
// Get new status
INTERFACE_STATUS|= ((mr_isr0&B_to) ?TIMO :0)|((mr_isr2&B_rem) ?REM :0)
- |((mr_isr1&B_end) ?END :0)|((mr_isr0&B_eos) ?EOS :0)
- |((mr_spsr&B_pend)?RQS :0)|((mr_isr0&B_ifc) ?IFC :0)
- |((mr_isr0&B_stbo)?SPOLL:0)|((mr_isr2&B_lok) ?LOK :0)
- |((mr_isr1&B_det) ?DTAS :0)|((mr_isr1&B_dec) ?DCAS:0)
- |((mr_adsr&B_ta) ?TACS :0)|((mr_adsr&B_la) ?LACS:0);
+ |((mr_isr1&B_end) ?END :0)|((mr_isr0&B_eos) ?EOS :0)
+ |((mr_spsr&B_pend)?RQS :0)|((mr_isr0&B_ifc) ?IFC :0)
+ |((mr_isr0&B_stbo)?SPOLL:0)|((mr_isr2&B_lok) ?LOK :0)
+ |((mr_isr1&B_det) ?DTAS :0)|((mr_isr1&B_dec) ?DCAS:0)
+ |((mr_adsr&B_ta) ?TACS :0)|((mr_adsr&B_la) ?LACS:0);
INTERFACE_STATUS|=((INTERFACE_STATUS&(LACS|TACS)) ? 0:NACS);
@@ -494,7 +494,7 @@ static void TNT_Setup_IO(int IO_type, unsigned long int cnt, int term)
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_auxmr,HR_auxrj|0); // B_to is cleared
switch(IO_type) {
@@ -632,7 +632,13 @@ int GPIB_check_for_device_clear_signal(void)
if (TNT_INT_STATUS() & DCAS) {
TNT_Out(R_auxmr,F_clrDEC);
+
+ TNT_4882_Status(STB,0x10,CLEAR); // Clear MAV bit
+ g_free (globals.Registers.pending_output_message);
+
+ TNT_Holdoff_off();
TNT_INT_STATUS();
+
return TRUE;
} else {
return FALSE;
@@ -648,7 +654,7 @@ int GPIB_check_for_messages(char *gpib_buf)
return FALSE;
}
- // If the GPIB has requested data, and no output messages
+ // If the GPIB has requested data, and no output messages
// are in the TNT4882 FIFOs, generate a query error
if (TNT_update_brq() && !TNT_input_bav() && ib_empty) {
@@ -656,7 +662,7 @@ int GPIB_check_for_messages(char *gpib_buf)
}
// If the TNT4882 is talk addressed, the controller must
- // be still reading output data in the TNT4882 FIFOs.
+ // be still reading output data in the TNT4882 FIFOs.
// Wait until this process has completed and the TNT4882
// is listen addressed.
@@ -702,8 +708,8 @@ int GPIB_handle_new_input(char *gpib_buf)
&& !( !TNT_input_bav() && (INTERFACE_STATUS & END)) // proper transaction end
&& !( !TNT_input_bav() && TNT_In(R_isr3)&B_done) // proper transaction end
&& !( !TNT_input_bav() && (INTERFACE_STATUS & TIMO)) // improper timeout
- && !( !TNT_input_bav() && TNT_update_brq() && ib_empty) // brq message true,
- // GPIB requesting data
+ && !( !TNT_input_bav() && TNT_update_brq() && ib_empty) // brq message true,
+ // GPIB requesting data
) {
// choose the most efficient fifo-emptying method based on FIFO flags
@@ -743,12 +749,12 @@ int GPIB_handle_new_input(char *gpib_buf)
}
if (TNT_update_brq() && !TNT_input_bav() && ib_empty)
- // abandon if brq with no commands to process
+ // abandon if brq with no commands to process
{
queue_error_for_gpib_only(query_error_unterminated);
prev_brq=1; // reset brq
TNT_update_brq(); // update it so that it doesn't get confused
- // in idle state
+ // in idle state
return FALSE;
}
@@ -770,150 +776,141 @@ static void TNT_Holdoff_off()
}
-int GPIB_send_query_response(gpointer *ignore_this, char *in_string)
+void GPIB_start_query_response(gpointer *ignore_this, char *in_string)
{
g_assert (ignore_this == NULL);
g_assert (in_string != NULL);
if (!globals.HWDetect.gpib) {
- return OK;
+ return;
}
- if (GPIB_response_already_pending()) {
- // if MAV already, data will be lost. Set QYE bit in STB.
+ if (globals.Registers.pending_output_message != NULL) {
queue_error_for_gpib_only(query_error_interrupted);
+ g_free (globals.Registers.pending_output_message);
}
- // needs to be freed
- gchar *term_string = g_strdup_printf ("%s\n", in_string);
-
- // just a pointer
- char *out_buffer = term_string;
+ globals.Registers.pending_output_message = g_strdup_printf ("%s\n", in_string);
+ TNT_4882_Status(STB,0x10,SET); // Set MAV bit
+}
- // message must be available if this function has been called
- unsigned long int out_cnt;
- unsigned long int count_sent; // Local count variable
- int i;
+void GPIB_finish_query_response()
+{
+ if (!globals.HWDetect.gpib) {
+ return;
+ }
- out_cnt = strlen (out_buffer);
+ if (globals.Registers.pending_output_message == NULL) {
+ return;
+ }
- TNT_4882_Status(STB,0x10,SET); // Set MAV bit
+ // just a pointer
+ char *out_buffer = globals.Registers.pending_output_message;
+ int i;
+ unsigned long int out_cnt = strlen (out_buffer);
+ unsigned long int count_sent; // Local count variable
TNT_INT_STATUS();
// if the TNT4882 isn't talk addressed, wait until it is, or until the GPIB sends a clear signal,
// or until the GPIB writes more data to the TNT4882, generating a query error.
- while (!(INTERFACE_STATUS&TACS)) {
+ if (!(INTERFACE_STATUS&TACS)) {
TNT_RFD_Holdoff();
- if (INTERFACE_STATUS&DCAS) {
- //* device has been cleared. return to idle state
- TNT_4882_Status(STB,0x10,CLEAR); // Clear MAV bit
- TNT_Holdoff_off();
+ if (GPIB_check_for_device_clear_signal()) {
+ return;
- /* added by MJC - June 20/06 */
- /* reset interface if a device clear is received */
- TNT_Out(R_auxmr,F_clrDEC);
- TNT_INT_STATUS();
-
- return OK;
} else if (!TNT_input_bav()) {
- // if no bytes are available, we're still waiting for the
+ // if no bytes are available, we're still waiting for the
// GPIB to request data. Repeat loop.
TNT_Setup_IO(INPUT,out_cnt,EOI|EOS);
TNT_INT_STATUS();
TNT_Holdoff_off();
+ return;
+
} else {
// abandon if input bytes available, and generate query error
TNT_Holdoff_off();
queue_error_for_gpib_only(query_error_interrupted);
TNT_4882_Status(STB,0x10,CLEAR); // Clear MAV bit
prev_brq=1; // reset brq
- TNT_update_brq(); // update it so that it doesn't get
- // confused in idle state
- return OK;
+ TNT_update_brq(); // update it so that it doesn't get
+ return; // confused in idle state
}
- }
-
- TNT_Setup_IO(OUTPUT,out_cnt,EOI|EOS);
-
- count_sent=0;
- INTERFACE_STATUS=0; // Clear I/O status bits
- DATA_COUNT=0; // Clear count global
+ } else {
+ // We are talk-addressed. Send some data.
- if(out_cnt==0) {
- INTERFACE_STATUS|=UCMPL;
- return OK;
- }
+ TNT_Setup_IO(OUTPUT,out_cnt,EOI|EOS);
- // send data until completed or interrupted
- while( !(INTERFACE_STATUS&(DCAS|TIMO|END|ERR|LACS))
- && !(TNT_In(R_isr3)&B_done)
- ) {
+ count_sent=0;
+ INTERFACE_STATUS=0; // Clear I/O status bits
+ DATA_COUNT=0; // Clear count global
- // choose the most efficient fifo-filling method based on flags
- switch(TNT_In(R_isr3)&(B_nff|B_intsrc2|B_nef)) {
- case (B_nff):
- case (B_nff|B_intsrc2): // 16 words in fifo are empty
- for(i=0; i<16; i++) {
- TNT_Out(R_fifob,*((char *)(out_buffer++)));
- }
- break;
+ if(out_cnt==0) {
+ INTERFACE_STATUS|=UCMPL;
+ return;
+ }
- case (B_nff|B_intsrc2|B_nef): // 8 words in fifo are empty
- for(i=0; i<8; i++) {
+ // send data until completed or interrupted
+ while( !(INTERFACE_STATUS&(DCAS|TIMO|END|ERR|LACS))
+ && !(TNT_In(R_isr3)&B_done)
+ ) {
+
+ // choose the most efficient fifo-filling method based on flags
+ switch(TNT_In(R_isr3)&(B_nff|B_intsrc2|B_nef)) {
+ case (B_nff):
+ case (B_nff|B_intsrc2): // 16 words in fifo are empty
+ for(i=0; i<16; i++) {
+ TNT_Out(R_fifob,*((char *)(out_buffer++)));
+ }
+ break;
+
+ case (B_nff|B_intsrc2|B_nef): // 8 words in fifo are empty
+ for(i=0; i<8; i++) {
+ TNT_Out(R_fifob,*((char *)(out_buffer++)));
+ }
+ break;
+
+ case (B_nff|B_nef): // 1 word in fifo is empty
TNT_Out(R_fifob,*((char *)(out_buffer++)));
+ break;
}
- break;
- case (B_nff|B_nef): // 1 word in fifo is empty
- TNT_Out(R_fifob,*((char *)(out_buffer++)));
- break;
+ TNT_INT_STATUS(); // Get current status
}
- TNT_INT_STATUS(); // Get current status
- }
-
- TNT_DONE_Handler(OUTPUT,&count_sent); // Finish up and get count
- DATA_COUNT+=count_sent; // Update total transfer count
- out_cnt-=count_sent; // Update total requested count
- out_buffer=out_buffer+((int) count_sent); // Update buffer pointer
-
- INTERFACE_STATUS|=UCMPL; // Set the user complete bit
+ TNT_DONE_Handler(OUTPUT,&count_sent); // Finish up and get count
+ DATA_COUNT+=count_sent; // Update total transfer count
+ out_cnt-=count_sent; // Update total requested count
+ out_buffer=out_buffer+((int) count_sent); // Update buffer pointer
- g_free (term_string);
+ INTERFACE_STATUS|=UCMPL; // Set the user complete bit
- if (INTERFACE_STATUS&DCAS) {
- TNT_4882_Status(STB,0x10,CLEAR); // Clear MAV bit
+ g_free (globals.Registers.pending_output_message);
- // added by MJC - June 20/06
- // reset interface if a device clear is received
- TNT_Out(R_auxmr,F_clrDEC);
- TNT_INT_STATUS();
-
- return OK; // abandon if SDC or DCL
- }
+ if (GPIB_check_for_device_clear_signal()) {
+ return;
+ }
- if ((INTERFACE_STATUS&LACS) && (TNT_In(R_isr3)&B_nef)) {
- // abandon gracefully if listen-addressed with data in buffer
- queue_error_for_gpib_only(query_error_interrupted);
- TNT_4882_Status(STB,0x10,CLEAR); // Clear MAV bit
- prev_brq=1; // reset brq
- TNT_update_brq(); // update it so that it doesn't get
- // confused in idle state
- TNT_Setup_IO(INPUT,cnt,EOI|EOS);
- return OK;
- }
+ if ((INTERFACE_STATUS&LACS) && (TNT_In(R_isr3)&B_nef)) {
+ // abandon gracefully if listen-addressed with data in buffer
+ queue_error_for_gpib_only(query_error_interrupted);
+ TNT_4882_Status(STB,0x10,CLEAR); // Clear MAV bit
+ prev_brq=1; // reset brq
+ TNT_update_brq(); // update it so that it doesn't get
+ // confused in idle state
+ TNT_Setup_IO(INPUT,cnt,EOI|EOS);
+ return;
+ }
- if(DATA_COUNT>0) {
- TNT_4882_Status(STB,0x10,CLEAR); // Clear MAV bit
- prev_brq=1; // brq was active during send */
- TNT_update_brq(); // update it so that it doesn't get
- // confused in idle state
+ if(DATA_COUNT>0) {
+ TNT_4882_Status(STB,0x10,CLEAR); // Clear MAV bit
+ prev_brq=1; // brq was active during send */
+ TNT_update_brq(); // update it so that it doesn't get
+ // confused in idle state
+ }
}
-
- return OK;
}
@@ -936,16 +933,6 @@ void GPIB_check_remote_status (int *is_remote, int *is_lockout)
}
-unsigned char GPIB_response_already_pending ()
-{
- if (!globals.HWDetect.gpib) {
- return 0;
- }
-
- return TNT_In(R_spsr) & 0x10;
-}
-
-
void GPIB_go_to_local ()
{
if (!globals.HWDetect.gpib) {
diff --git a/gpib.h b/gpib.h
index 2da0cc1..610d74e 100644
--- a/gpib.h
+++ b/gpib.h
@@ -12,9 +12,9 @@ int GPIB_check_for_device_clear_signal(void);
int GPIB_check_for_device_clear_signal(void);
int GPIB_check_for_messages(char *gpib_buf);
int GPIB_handle_new_input(char *gpib_buf);
-int GPIB_send_query_response(gpointer *ignore_this, char *in_string);
+void GPIB_start_query_response(gpointer *ignore_this, char *in_string);
+void GPIB_finish_query_response();
void GPIB_check_remote_status (int *is_remote, int *is_lockout);
-unsigned char GPIB_response_already_pending ();
void GPIB_go_to_local ();
void GPIB_clear_events ();
unsigned int GPIB_get_ESR ();
diff --git a/instr-daemon.c b/instr-daemon.c
index 255b294..4924961 100644
--- a/instr-daemon.c
+++ b/instr-daemon.c
@@ -413,14 +413,19 @@ static gboolean periodic_poll (void)
globals.VxiLocks.command_in_progress = TRUE;
GPIB_check_for_device_clear_signal();
+
if (GPIB_check_for_messages(globals.Registers.gpib_input_buffer)) {
if (GPIB_handle_new_input(globals.Registers.gpib_input_buffer)) {
- Parser_main(globals.Registers.gpib_input_buffer, 0, GPIB_send_query_response, NULL);
+ Parser_main(globals.Registers.gpib_input_buffer, 0, GPIB_start_query_response, NULL);
}
}
+
+ // send response if appropriate
+ GPIB_finish_query_response();
+
GPIB_check_for_device_clear_signal();
- // tell VXI servers that the 4882 subsystem is avilable again
+ // tell VXI servers that the 4882 subsystem is available again
globals.VxiLocks.command_in_progress = FALSE;
}