// TCBITBUS.C - TCtask - Bitbus Interconnect interface routines. // V1.2 TECON Ltd. #include "tsk.h" #include "bitbus.h" #include "sio.h" //**************************** Bitbus-TCX interface *********************** tlink bitbus_tcx_timer; flag bitbus_tcx_flag; // local debug static word port_base; // bitbus_tcx_install // Creates and initializes objects for connecting via TCX44 device. // Returns 0 if OK, -1 on internal software error, -2 on hardware error. word_s bitbus_tcx_install (word port) { port_base= port; return (bitbus_tcx_flush()); } #define FLUSH_DELAY 1000 // bitbus_tcx_flush // Set connection via TCX44 device to initial state. // Returns 0 if OK, -2 on hardware error. word_s bitbus_tcx_flush (void) { word_s c,cc; tsk_outp( RESET, 0); for (cc= FLUSH_DELAY; cc--; ) for (c= 250; c--; ) ; // delay !!! if (tsk_inp( STATUS) != (byte)(RFNE | RCMD)) return (-2); return (0); } // bitbus_tcx_send // Send message to specifed node via TCX44 device. // Returns 0 if OK, -1 on error. word_s bitbus_tcx_send (bitbus_msg *msg) { word_s c, i= 2; while (1) { for (c= BITBUS_TCX_COUNTOUT; (--c) && (tsk_inp(STATUS) & TFNF); ) ; if (!c) return (-1); if ((byte)i < msg->length) { // for( c=30000;c--;); tsk_outp( DATA, *((byteptr)msg+(i++))); } else { tsk_outp( COMMAND, 0); return (0); } } } // bitbus_tcx_wait // Wait message from TCX44 device. // Returns 0 if OK, -1 on timeout, -2 on protocol error. word_s bitbus_tcx_wait (bitbus_msg *msg, dword timeout) { word_s c, i= 2; dword cc; cc = timeout; while( cc-- // no timeout && ( (tsk_inp(STATUS) & RFNE) // receive fifo empty || !(tsk_inp(STATUS) & RCMD))) ; // receive commamnd if (!cc) return (-1); // timeout while (1) { for (c= BITBUS_TCX_COUNTOUT; (--c) && (tsk_inp(STATUS) & RFNE); ) ; if (!c) return (-2); // error if (tsk_inp(STATUS) & RCMD) { // for( c=30000;c--;); *((byteptr)msg+(i++))= tsk_inp(DATA); } else { tsk_inp(COMMAND); return (0); } } } //**************************** Bitbus-COM interface ************************ #define COM(s,r) v24_send( sio, s, 0L); \ r= v24_receive( sio, BITBUS_COM_TIMEOUT) local tlink bitbus_com_timer; local flag bitbus_com_flag; local sioptr sio; local word rcvbuf [2]; local byte xmtbuf [2]; // bitbus_com_install // Creates and initializes objects for connecting via Bitbus-COM // protocol // Returns 0 if OK, -1 on error. word_s bitbus_com_install (word_s port) { if (!create_flag( &bitbus_com_flag #if (TSK_NAMED) ,"BitCOM_F" #endif )) return (-1); // error while flag creation sio = v24_install (port, 1, rcvbuf, sizeof (rcvbuf), xmtbuf, sizeof (xmtbuf)); if (sio == NULL) {delete_flag( &bitbus_com_flag); return (-1);} v24_change_baud (sio, BITBUS_COM_BAUD); v24_protocol (sio, 0, 0, 0); // No XON/XOFF and RTS/CTS protocol return (0); } // bitbus_com_flush // Set connection via Bitbus-COM protocol to initial state. // Returns 0 if OK, -2 on protocol error. word_s bitbus_com_flush (void) { word_s ch, i; while (~v24_check(sio)) v24_receive (sio, 1L); for (i=0; i < 20; i++) { COM('D',ch); if (ch == -1) return (-2); } if (ch != 'D') return (-2); return (0); } // bitbus_com_send // Send message to specifed node via Bitbus-COM protocol. // Returns 0 if OK, -1 if no free buffers on bitbus device, // -2 on protocol error. word_s bitbus_com_send (bitbus_msg *msg) { word_s ch, i, err=0; COM('I',ch); if (ch == 'N') return (-1); if (ch != 'I') return (-2); for (i=0;i < msg->length-2;i++) { COM(*((byteptr)msg+i+2), ch); if (ch == -1) {err=-2; break;} if ((byte)ch != *((byteptr)msg+i+2)) err=-2; } if (err) { COM('D',ch); return (-2); } COM('E',ch); if (ch != 'E') return (-2); return (0); } // bitbus_com_wait // Wait message via Bitbus-COM protocol. // Returns 0 if OK, -1 on timeout, -2 on protocol error. word_s bitbus_com_wait (bitbus_msg *msg, dword timeout) { word_s ch, len, i, checksum= 0, err= -1; clear_flag( &bitbus_com_flag); create_timer( &bitbus_com_timer, timeout, &bitbus_com_flag, TKIND_FLAG, 0); do { COM('O',ch); if (ch == 'Q') continue; // msg queue in bitbus device empty if (ch == 'O') err= 0; // msg ready! else err= -2; // no or bad echo break; } while ( !check_flag( &bitbus_com_flag)); if (!err) { COM('L',len); if ((len < 7) || (len > 20)) err= -2; else { msg->length= (byte)len; checksum= len; for ( i= 3; i < len; i++) { COM('R',ch); if (ch & 0xff00) {err= -2; break;} *((byteptr)msg + i)= (byte)ch; checksum-= ((checksum+= ch) > 255) ? 255 : 0; } COM((byte)checksum, ch); if ((ch & 0xff00) || ((byte)ch != (byte)checksum)) err= -2; } } delete_timer( &bitbus_com_timer); return (err); }