SEC-232m Manual Version of September 3, 1994 Corresponding to ROM of this date. Fischer Computer Systems 445 Bay Street Angwin, CA 94508 (707) 965-2414 (707) 965-3687 fax (800) 362-8998 sales A. Purpose This device is a serial peripheral which can be connected to any of various computers having RS-232 serial ports. It is to provide input from up to three shaft encoders (one axis somewhat restricted in speed), up to eight parallel bits of either input or output, and additional future devices via the SPI port. It also correlates and responds to input data for the purpose of making communication delays irrelevant. B. Functions 1. Initialization a) Hardware setup b) Data structure setup 2. Input data packets to host a) Packet structure 1) X encoder count a> Four characters, biased binary 2) Y encoder count a> Four characters, biased binary 3) Z encoder count or time count a> Four characters, biased binary 4) Multiple purpose number a> Two characters, biased binary 5) New line a> Carriage return b> Line feed b) Biased binary format 1) Representation Binary data to be represented in biased binary format are first separated into six bit nibbles, with values from 00 to 63 (3Fh). Each nibble is added to 32 (20h) to make a printable ASCII character in the range of 32 (20h) through 95 (5Fh). These characters are transmitted with the most significant character first. Thus, four characters convey three bytes of binary data and two characters convey twelve bits, with values from 0 to 4095 (0FFFh). 2) Decoding Binary data can be extracted from biased binary characters as follows: Start with a zero. For each new character, multiply the accumulated value by 64 (40h), add the new character, and subtract 32 (20h). The result may need to be sign extended. c) Multiple purpose number 1) Encoding The 12 bit multipurpose number may be considered a most significant nibble and a least significant byte. The nibble specifies one of sixteen categories of meaning of the byte. 2) Priorities Unlike previous models in the serial SEC family, this product does not prioritize data for transmission. Instead, every packet is formed with the then current axis data. These packets are then held in a short queue to be transmitted in chronological sequence. 3) Categories a> Category 0, No News This category indicates that the packet queue was empty when a packet was needed for transmission. This means that the axis data in this packet were valid just before this packet was sent. The byte is the current parallel i/o bits. b> Category 1, New Parallel I/O Bits This category indicates a change in the parallel i/o data. The byte is the new parallel data. And the axis data in the same packet show what the counts were when this change was detected. Only specified changes of interest are reported this way. Uninteresting changes are reported in category 0 as not newsworthy and without axis counts necessarily as they were when the change was detected. c> Category 2, Acknowledgments 1> 200h, Time to Z Axis Acknowledgment This packet was formed in response to a Time to Z Axis command. Regardless of the previous setting, the third axis data in this packet is time and in subsequent packets will be the Z axis. 2> 201h, Z Axis to Time Acknowledgment This packet was formed in response to a Z Axis to Time command. Regardless of the previous setting, the third axisdata in this packet is the Z axis and in subsequent packets will be time. 3> 220h thru 22Fh, Axis Rezero Acknowledgment This packet is formed whenever one or more axes are reset to zero in response to an Axis Rezero Command. The bits b0 thru b3 correspond to x, y, z, and t respectively. More than on of these bits can be set if more than one axis is reset by one command. When one or more axes is zeroed, the corresponding axis data in this packet will not necessarily be zero but will show the count that was discarded. 4> 230h thru 23Fh, Axis Index Acknowledgment This packet is formed whenever one or more axes are reset to zero in response to a signal on the parallel port. The bits b0 thru b3 correspond to x, y, z, and t respectively. More than one of these bits can be set if more than one of the input signals were detected simultaneously. When one or more axes is zeroed, the corresponding axis data in this packet will not necessarily be zero but will show the count that was discarded. d> Category 3, Exception Flags 1> 301h, Packet Queue Overflow Flag This is an error condition which results when a packet is formed which fills the last available space in memory for pending packets. The condition which caused this packet to be formed may be reported later. But the axis data reported with it will very likely be wrong. Axis data in subsequent packets should be taken with a grain of salt until the next No News packet is received. 2> 340h thru 34Fh, Rate Error Flags Although there are no rate error detectors on the encoder inputs, the routines that extend the precision of the counts to 24 bits can detect if they have not been executed frequently enough to work correctly. Such errors should only be possible when many packet causing events occur close enough together to keep the MiniSEC processor extremely busy and then only when an axis count is changing at nearly its maximum possible rate. Bits b0, b1, b2, and b3 correspond to the x, y, z, and t axes, respectively. Any combination of these errors can be detected and reported simultaneously. e> Category 4, Label String A byte of the label string, when requested, is sent in this category. The label string is null terminated, does not exceed 255 bytes, may include control characters, and repeats indefinitely. f> Category 5, Requested Data Byte Requested data other than the label string, such as debugging information, is sent in this category. It is the responsibility of the host to keep track of the sequence if multiple requests are made between occurrences of No News packets. d) Protocol Packets are sent as asynchronous serial data with one start bit, eight data bits, and one stop bit per byte. A packet is sent only when a poll command has been received since transmission of the preceding packet began. 3. Commands from host a) Command syntax Commands are received as asynchronous serial data with one start bit, eight data bits, and one stop bit per byte. Every command consists of a single byte. A special subset of commands enters four bit nibbles on a LIFO stack to be used as parameters by subsequent commands. These commands can be sent in any sequence and at any time, although caution should be exercised to avoid filling the packet queue. b) Command set (Undefined commands are ignored.) 1) 0xh - No operation At least 00h, 0Ah, and 0Dh will always be ignored. 2) 1xh - Save nibble for subsequent use The nibble, x, is saved on a LIFO stack for subsequent use. This stack holds eight nibbles. When overflowed or under-flowed, this stack simply wraps around. Overflow or underflow of this stack is not reported as an error. 3) General commands a> 21h '!' - Store a byte Using the four latest saved nibbles as a memory address, high nibble sent first, and the two preceding save nibbles as data, also high nibble sent first, this command allows any byte of data to be written to any address in the MiniSEC processor's address space. For obvious reasons, great care should be taken to avoid ever using this command. b> 2Eh '.' - Report a byte Using the two latest saved nibbles as a data byte, high nibble sent first, this command causes a new packet to be formed including this byte in the category of a requested data byte. This is not a poll command. To receive the requested byte, poll commands must be sent until one invokes the packet containing that byte. c> 30h thru 39h, '0' thru '9' - Hex input As an alternative to the 1xh commands, parameter nibbles can be entered onto the same stack in hexadecimal. When this nibble is used to specify a set of axes, the bits b0 through b3 correspond to x, y, z, and t respectively. In such cases, the commands to specify a single axis would, therefore, be '1', '2', '4', and '8' respectively; the command to specify x and y would be '3'; etc. d> 3Fh '?' - Report arbitrary memory byte Using the four latest saved nibbles as a memory address, high nibble sent first, any specified cell in the MiniSEC processor's address space will be read and its value returned in a new packet as a requested data byte. This command is the equivalent of '@' followed by '.'. This is not a poll command. To receive the requested byte, poll commands must be sent until one invokes the packet containing that byte. e> 40h '@' - Fetch a byte Using the four latest saved nibbles as a memory address, high nibble sent first, any specified cell in the MiniSEC processor's address space will be read and its value will be left on the nibble stack as though its high nibble had been sent first. However, the meaning of all of these bytes remains undocumented. f> 41h thru 46h, 'A' thru 'F' - Hex input As an alternative to the 1xh commands, parameter nibbles can be entered onto the same stack in hexadecimal. g> 49h 'I' - Ignore input bit This command takes a previously entered nibble and clears one of the sixteen watch status bits. See the 'V' command. Bits b0 through b2 of the nibble specify a bit on the input port and b3 specifies whether rising or falling edges of that bit should subsequently be ignored. Thus, two 'I' commands are needed in order to specify that an input bit should be completely ignored. Ignore command Table. (not setup in text format) h> 4Ch 'L' - Label query This command requests the next byte of the label string, which uniquely identifies the revision and customization, if any, of the MiniSEC processor in use. The label string is null terminated, does not exceed 255 bytes, may include control characters, and repeats indefinitely. This is not a poll command. To receive the requested byte, poll commands must be sent until one invokes the packet containing that byte. i> 4Fh 'O' - Output a byte This command takes two previously entered nibbles with the most significant nibble sent first. See the 1xh command. The specified byte is latched on the parallel i/o port. However, each of the eight bits so latched remains invisible and ineffective until and unless it is set for use as an output rather than as an input. See the 'U' command. I/O Bit Output Table. (not setup in text format) Setting a bit to 1 makes the bit high, a bit set to 0 is an low. FFO would set all bits HIGH based on Usage. j> 50h 'P' - Poll command Solicit a packet. If no packets are waiting in the packet queue, a No News packet will be formed. k> 51h 'Q' - Quick or Quiet Poll command This variation of the poll command can be used while waiting for one or more axes to be rezeroed by an index signal connected to the parallel port. The advantage of this over the standard poll command is that it does not cause the formation of a new packet if the packet queue is empty. Instead, it causes the most recently sent packet to be resent. In this way it leaves the MiniSEC processor ready to detect the awaited index signal with less latency. l> 52h 'R' - Reset This does not really reset the MiniSEC processor, or even all of it's variables. But it does clear all pending axis index and watch status bits and the label string character counter. See the 'I', 'L', 'V', 'W', and 'X' commands. This command does not cancel pending polls, change the third axis selection, or clear or tristate the parallel output port. See the 'O', 'P', 'Q', 'S', 'T', 'U', and 'Y' commands. m> 53h 'S' - Switch third axis to Z count This is not a poll command but does cause an acknowledging packet to be formed. This command may also be useful when the third axis is already set to the Z count because the acknowledging packet contains the time instead. n> 54h 'T' - Switch third axis to time This is not a poll command but does cause an acknowledging packet to be formed. This command may also be useful when the third axis is already set to time because the acknowledging packet contains the Z count instead. o> 55h 'U' - Set usage of i/o bits for input or output This command takes two previously entered nibbles with the most significant nibble sent first. See the 1xh command. The specified bit pattern is stored in the data direction register of the parallel i/o port. The one bits become outputs and the zero bits become inputs. I/O Bit Usage (Table not available in text format Setting a bit to 1 makes the bit output, a bit set to 0 is an input. Thus FFU is all bits set to output. p> 56h 'V' - View command This command takes four previously entered nibbles with the most significant nibble sent first. See the 1xh command. The two bytes thus formed replace any previous settings of all sixteen watch status bits. The first byte entered sets the watch status for rising edges and the second for falling edges. When an input bit's watch status is set, a rising or falling transition on that bit will cause a new packet to be formed with the axis data that existed when that edge was detected. However, to avoid a probable overflow of the packet queue, the watch status of each edge of each bit that causes a packet to be formed will be suppressed until the next time the packet queue is completely emptied. Caution: Setting the watch status of any input bit that is used as an index for its corresponding axis or as an input for the z axis encoder will impair performance by causing the formation of unnecessary extra packets. View command bit layout table... (Stack 1 entered first) (table not visible in Text format) 1248V.... Watches rising edges on bits 4 & 1 and falling edges on bits 6 & 3. Changes on these bits cause I/O data to be reported in Cat. 1 data packets. NOTE: These bit's are set and reset individually with the Watch & Ignore Commands. q> 57h 'W' - Watch an input bit This command takes a previously entered nibble and sets one of the sixteen watch status bits. See the 'V' command. Bits b0 through b2 of the nibble specify a bit on the input port and b3 specifies whether rising or falling edges of that bit should subsequently be reported. Thus, two 'W' commands are needed in order to specify that an input bit should be watched for any change of state. Watch command table. (not setup in TEXT format) r> 58h 'X' - Arm one axis to be rezeroed once or repeatedly This command takes one previously entered nibble. See the 1xh command. The bits b0 and b1 specify one of the four axes to be armed for rezeroing by the corresponding one of bits b0 through b3 on the parallel input port. However, of the z and t axes, only the one that will appear in new packets can be rezeroed. If bit b2 of the parameter is set, this axis will remain armed to be rezeroed repeatedly by the same edge of the same input bit. To avoid overflowing the packet queue with the acknowledgment packets, the axis is not rearmed immediately following each index but only when the packet queue is next emptied. If bit b2 of the parameter is clear, the axis will be armed to be rezeroed only once and subsequent rearming will be stopped. Bit b3 of the parameter specifies whether this axis is to be rezeroed by the rising or falling edge of the corresponding input bit. Both arming and rearming of axes are handled separately for rising and falling edges. This means that stopping the rearming of an axis for one edge does not necessarily stop it from being continuously rezeroed by the other edge. When the specified edge on the input bit is detected and the axis is rezeroed, an acknowledgment packet will be formed. If more than one axis is armed and the specified edges are detected simultaneously, more than one acknowledgment will be returned in a single packet. This is not a poll command. To receive the acknowledgment packet, poll commands must be sent until one invokes that packet. eXecute a rezero on the selected axis command table. (not visible in text format) s> 59h 'Y' - Yank an output bit high or low This command takes one previously entered nibble. See the 1xh command. The lower three bits of the parameter nibble specify one of the bits on the parallel port. The remaining bit specifies the new state for that bit to take if and when it is an output. See the 55h 'U' command for controlling which bits are outputs. Yank I/O bits command Table. (not visible in text format) t> 5Ah 'Z' - Rezero one or more axes immediately. This command takes one previously entered nibble. See the 1xh command. The bits b0 thru b3 correspond to x, y, z, and t, respectively. The specified axis or axes are rezeroed and an acknowledgment packet is formed. However, of the z and t axes, only the one that will appear in new packets can be rezeroed. This is not a poll command. To receive the requested byte, poll commands must be sent until one invokes the packet containing that byte. Zero axis immediately. Bits may be combined to zero multipul axis. C. Structure 1. Reprogramability The entry points for reset, interrupts, and some major subroutines start with a three byte, do nothing instruction, such as AND extended, with zero as its 16 bit parameter. This instruction is always one that can be overwritten with either a JMP or a JSR instruction to any address without first erasing the PROM. In this way, any portion of the code can be replaced, if necessary. The version number should also be overwritten whenever this is done. This may necessitate the use of some version numbers out of sequence. 2. Multitasking Forth The highest priority tasks are coded in machine code. The Forth inner interpreter is a lower priority task. The host command interpreter takes the place of the Forth outer interpreter. 3. Interrupts a) Clock Not used. b) Serial I/O Not used. c) External Not implemented. 4. Tasks a) Monitor Z Axis b) Accept incoming commands c) Test for Parallel I/O Changes d) Transmit data packets e) Interpret incoming commands f) Monitor x, y, z, and t axis extension to 24 Bits g) Test for excessive delay of lowest priority tasks D. Design Issues 1. Encoder alignment It would be very valuable if this product could measure the quadrature alignment of the encoders. This is a mechanical adjustment which must be made on installation and corrected if it shifts. Bad alignment causes rate errors at lower speeds than could otherwise be handled. It could be measured by comparing the velocities of alternate steps or by comparing the average frequency of occurrence of each of an encoders four states. It appears that the frequency of occurrence method of measuring encoder alignment is the easiest and most effective method. And there is no obvious change that could be made to the design of the MiniSEC to make this process any easier for a host system programmer to use. 2. Input ring buffer It has not yet been determined whether or not an input ring buffer will be needed to ensure that no command bytes will be lost. A change in prioritization has been made which should force the serial input to be serviced often enough when serial data has been received. It should not now be possible to overrun the serial input of the MiniSEC except when it is reporting rate errors. Connector wiring diagram Serial RS-232 Female (DB-25) 1 - o o - 14 Out Transmit Data - o o - 15 IN Received Data - o o - 16 4 - o o - 17 Nulled1 - o o - PD7 DS LSB2 Nulled1 - o o - PD5 \ SS2 Signal Ground - o o - Nulled1 Nulled1 - o o - 21 Reserved PD4\SCK2 - o o - 22 Reserved PD2\MSIO2 - o o - PD3 \ MOSI2 11 - o o - 24 12 - o o - 25 13 - o 1 Nulled pins are connected together. 2 These Pins are connected to Control signals comming directly from the Microprocesser and are reserved for programming & future expansion. Unmarked pins have no connection. Connector wiring diagram Encoder Interface Male (DB-25) +5vdc 1 - o o - 14 +5vdc +5vdc 2 - o o - 15 Ground +5vdc 3 - o o - 16 TCAP VPP 4 - o o - 17 IRQ PA7 5 - o o - 18 PA6 PA5 6 - o o - 19 PA4 PA3 7 - o o - 20 PA2 PA1 8 - o o - 21 PA0 NC 9 - o o - 22 Ground XA 10 - o o - 23 Ground XB 11 - o o - 24 Ground YA 12 - o o - 25 Ground YB 13 - o PA6 & PA7 Optional Z axis Channel A & B. PA0 - PA3 Axis Function Input. Clear, Read Counter / Timer Functions. PA4 - PA5 I/O bits with no defined alternate functions. Default Foot Switch inputs. REM SEC-232m Demo Program 11-Sep-94 REM By Randy Fischer, Fischer Computer Systems DIM x, y, z, m, maxcount, midcount AS LONG maxcount = 2 ^ 24 midcount = 2 ^ 23 xSCALE = 10000: REM Divisor for SCALING x Counts ySCALE = 10000: REM Divisor for SCALING y Counts zSCALE = 10000: REM Divisor for SCALING z Counts xoffset = 0: REM Offset for x COUNTS yoffset = 0: REM Offset for y COUNTS zoffset = 0: REM Offset for z COUNTS ON KEY(1) GOSUB 1000: KEY(1) ON: REM Clear Catagory table CLS OPEN "com1:9600,n,8,1,bin,cd0,cs0,ds0,op0,rs" FOR RANDOM AS #1 CLOSE #1: REM CLEAR INPUT BUFFERS OPEN "com1:9600,n,8,1,bin,cd0,cs0,ds0,op0,rs" FOR RANDOM AS #1 LOCATE 3, 29, 0: PRINT "FISCHER COMPUTER SYSTEMS" LOCATE 4, 37, 0: PRINT "SEC-232m" LOCATE 5, 35, 0: PRINT "ENCODER DEMO" LOCATE 11, 34, 0: PRINT "3Z to Zero X,Y" LOCATE 7, 29, 0: PRINT "X" LOCATE 7, 50, 0: PRINT "Y" LOCATE 22, 34, 0: PRINT "Escape to Exit"; LOCATE 14, 20, 0: PRINT "1Z = Zero X"; LOCATE 14, 50, 0: PRINT "2Z = Zero Y"; GOSUB 1000: REM Place empty Catagory Table WHILE keyboard$ <> CHR$(27) keyboard$ = INKEY$: IF keyboard$ = "" THEN 100 PRINT #1, keyboard$; : REM Send data to SEC-232m (Caution) 100 PRINT #1, "P"; : REM POLL 232m sec$ = INPUT$(16, 1): REM Get 16 bytes IF ASC(MID$(sec$, 15, 1)) <> 13 THEN 100: REM Valid Packet?? x = 0 x = x * 64 + (ASC(MID$(sec$, 1, 1)) - 32) x = x * 64 + (ASC(MID$(sec$, 2, 1)) - 32) x = x * 64 + (ASC(MID$(sec$, 3, 1)) - 32) x = x * 64 + (ASC(MID$(sec$, 4, 1)) - 32) IF x >= midcount THEN x = x - maxcount LOCATE 8, 24, 0: PRINT USING "####.####"; (x / xSCALE) + xoffset; y = 0 y = y * 64 + (ASC(MID$(sec$, 5, 1)) - 32) y = y * 64 + (ASC(MID$(sec$, 6, 1)) - 32) y = y * 64 + (ASC(MID$(sec$, 7, 1)) - 32) y = y * 64 + (ASC(MID$(sec$, 8, 1)) - 32) IF y >= midcount THEN y = y - maxcount LOCATE 8, 45, 0: PRINT USING "####.####"; (y / ySCALE) + yoffset; z = 0 z = z * 64 + (ASC(MID$(sec$, 9, 1)) - 32) z = z * 64 + (ASC(MID$(sec$, 10, 1)) - 32) z = z * 64 + (ASC(MID$(sec$, 11, 1)) - 32) z = z * 64 + (ASC(MID$(sec$, 12, 1)) - 32) IF z >= midcount THEN z = z - maxcount LOCATE 20, 29, 0: PRINT USING "########"; z; PRINT " Timer / Z-Axis." m = 0 m = m * 64 + (ASC(MID$(sec$, 13, 1)) - 32) m = m * 64 + (ASC(MID$(sec$, 14, 1)) - 32) d = m MOD 256 SELECT CASE INT(m / 256) CASE IS = 0 LOCATE 19, 30, 0: PRINT USING "#####"; d; PRINT " I/O Bits (CAT.0)"; CASE IS = 1 c1 = c1 + 1 LOCATE 20, 1, 0: PRINT " 1>. "; PRINT USING "#####"; d; c1; CASE IS = 2 c2 = c2 + 1 LOCATE 21, 1, 0: PRINT " 2>. "; PRINT USING "#####"; d; c2; CASE IS = 3 c3 = c3 + 1 LOCATE 22, 1, 0: PRINT " 3>. "; PRINT USING "#####"; d; c3; CASE IS = 4 c4 = c4 + 1 LOCATE 23, 1, 0: PRINT " 4>. "; PRINT USING "#####"; d; c4; : PRINT " "; CHR$(d); CASE IS = 5 c5 = c5 + 1 LOCATE 24, 1, 0: PRINT " 5>. "; PRINT USING "#####"; d; c5; CASE ELSE END SELECT WEND LOCATE 23, 33, 0: PRINT " Done ..... "; END 1000 REM Setup a Clear Catagory Display c1 = 0: c2 = 0: c3 = 0: c4 = 0: c5 = 0: d = 0 LOCATE 17, 3, 0: PRINT " Catagory Table"; LOCATE 18, 3, 0: PRINT " (F1. to clear)"; LOCATE 19, 3, 0: PRINT "Cat. DATA Hits"; LOCATE 20, 1, 0: PRINT " 1>. "; PRINT USING "#####"; d; c1 LOCATE 21, 1, 0: PRINT " 2>. "; PRINT USING "#####"; d; c2 LOCATE 22, 1, 0: PRINT " 3>. "; PRINT USING "#####"; d; c3 LOCATE 23, 1, 0: PRINT " 4>. "; PRINT USING "#####"; d; c4; : PRINT " "; CHR$(d); LOCATE 24, 1, 0: PRINT " 5>. "; PRINT USING "#####"; d; c5; RETURN