'======================================================================= ' ' buffered smart pin serial object for P2 Eval board, buffering rx/tx in the Cog, supporting 2 full-duplex connrction ' '======================================================================= VAR long cog 'cog id of this instance ' '----------------------------------------------------------------------- 'stop cog if already running '----------------------------------------------------------------------- ' PUB stop if cog cogstop(cog-1) cog := 0 ' '----------------------------------------------------------------------- 'start COG with startparameter block address '----------------------------------------------------------------------- ' PUB start(startparameteraddress) 'the first long in the startparameter block contains the address of the later used stop 'Mailbox. So now I use long[long[]] to access the first long in the later used mailbox as Flag long[long[startparameteraddress]] := 0 'set flag (0) to know if the started cog has read its parameters cog := cognew(@cogserial_init,startparameteraddress) + 1 if cog 'if I was able to start the COG repeat until long[long[startparameteraddress]] == -1 'I wait until Flag states cog is done reading parameter and ready to roll (-1) RESULT := 1 'now start done ' '======================================================================= ' ' To use this use cogserial.spin - it will provide usual methods and include this driver. ' ' the description below is just if you want to use this directly from PASM and not SPIN ' '======================================================================= ' 'the PASM code runs in a COG and just needs 1 long for it's id and '8 longs in the HUB for communication. ' 'All code and buffers for 2 full duplex pairs is in the COG. 'The start parameter block ' '----------------------------------------------------------------------- ' ' When starting the driver you need to provide a memory address to read the parameters from. ' After COG start the memory is not needed anymore, so you can use your stack or some other ' Buffer you have. You will need 22 longs for all parameter. ' '----------------------------------------------------------------------- ' ' The first parameter in the start parameter block is the ADDRESS of your 8 long HUB mailbox ' You will use to communicate with the driver, once started. ' ' startparams[0] := @rx1_cmd 'hub address mailbox ' startparams[1] := rxpin1 'pin rx1 ' startparams[2] := 7 + ((CLKFREQ / rxbaudrate1) << 16) 'bitrate rx1 ' startparams[3] := rxmode1 'mode rx1 ' startparams[4] := rxlutstart1 'start lutbuffer rx1 ' startparams[5] := rxlutsize1 'size lutbuffer rx1 ' startparams[6] := txpin1 'pin tx1 ' startparams[7] := 7 + ((CLKFREQ / txbaudrate1) << 16) 'bitrate tx1 ' startparams[8] := txmode1 'mode tx1 ' startparams[9] := txlutstart1 'start lutbuffer tx1 ' startparams[10] := txlutsize1 'size lutbuffer tx1 ' startparams[11] := rxpin2 'pin rx2 ' startparams[12] := 7 + ((CLKFREQ / rxbaudrate2) << 16) 'bitrate rx2 ' startparams[13] := rxmode2 'mode rx2 ' startparams[14] := rxlutstart2 'start lutbuffer rx2 ' startparams[15] := rxlutsize2 'size lutbuffer rx2 ' startparams[16] := txpin2 'pin tx2 ' startparams[17] := 7 + ((CLKFREQ / txbaudrate2) << 16) 'bitrate tx2 ' startparams[18] := txmode2 'mode tx2 ' startparams[19] := txlutstart2 'start lutbuffer tx2 ' startparams[20] := txlutsize2 'size lutbuffer tx2 ' startparams[21] := tx_i_ct1wait 'number of sysclocks to wait between TX interrupts ' '----------------------------------------------------------------------- ' 'The mailbox interface: ' '----------------------------------------------------------------------- ' ' You need to provide 8 longs in HUB to talk to the driver. ' ' long rx1_cmd, rx1_param, tx1_cmd, tx1_param, rx2_cmd, rx2_param, tx2_cmd, tx2_param 'mailbox of this instance 8 longs ' ' and put the ADDRESS of those longs into the first parameter of your startparameter block ' '----------------------------------------------------------------------- ' ' each channel (rx1,tx1,rx2,tx2) has its own mailbox, one long for ' command/status and one long for the parameter ' '----------------------------------------------------------------------- ' ' the usual needed sequence is to ' check if mailbox ready (-1) else wait ' set parameter ' set command ' if you need to wait for a result check if mailbox ready (-1) else wait ' '----------------------------------------------------------------------- ' ' all mailboxes are independent from each other and you can run commands asyncron for each mailbox/channel ' '----------------------------------------------------------------------- ' 'rx1 mailbox ' rx1_cmd rx1_param 'mailbox for rx1 ' -1 --- 'mailbox ready last command finished ' -2 --- 'rxcheck, returns -1 if buffer empty or char in rx1_param ' -3 --- 'rxcount, returns number of bytes waiting in buffer in rx1_param ' -4 --- 'rxsize, returns size of buffer in bytes in rx1_param ' >0 ' size hubaddress 'rxblock, will read size bytes from buffer to hubaddress ' 'tx1 mailbox ' tx1_cmd tx1_param 'mailbox for tx1 ' -1 --- 'mailbox ready last command finished ' -2 --- 'txcheck, returns -1 if buffer full else bytes waiting in buffer in tx1_param ' -3 --- 'txcount, returns number of bytes waiting in buffer in tx1_param ' -4 --- 'txsize, returns size of buffer in bytes in tx1_param ' -5 hubaddress 'str, will write bytes from hubaddress to buffer until reaching a zero byte ' -6 value 'dec, will write value in tx1_param as decimal without leading zero's to buffer ' -(6+(digits<<8) value 'dec, will write last digits chars of value in tx1_param as decimal replacing leading zero's with space to buffer ' -7 value 'dec, will write 10 chars of value in tx1_param as decimal with leading zero's to buffer ' -(7+(digits<<8) value 'dec, will write last digits chars of value in tx1_param as decimal with leading zero's to buffer ' 'all dec routines will put a '-' as first char if value is negative ' -8 value 'hex, will write value in tx1_param as hex without leading zero's to buffer ' -(8+(digits<<8) value 'hex, will write last digits chars of value in tx1_param as hex replacing leading zero's with space to buffer ' -9 value 'hex, will write 8 chars of value in tx1_param as hex with leading zero's to buffer ' -(9+(digits<<8) value 'hex, will write last digits chars of value in tx1_param as hex with leading zero's to buffer ' >0 ' size hubaddress 'txblock, will write size bytes from hubaddress to buffer ' 'rx2 mailbox ' rx2_cmd rx2_param 'mailbox for rx2 ' -1 --- 'mailbox ready last command finished ' -2 --- 'rxcheck, returns -1 if buffer empty or char in rx2_param ' -3 --- 'rxcount, returns number of bytes waiting in buffer in rx2_param ' -4 --- 'rxsize, returns size of buffer in bytes in rx2_param ' >0 ' size hubaddress 'rxblock, will read size bytes from buffer to hubaddress ' 'tx2 mailbox ' tx2_cmd tx2_param 'mailbox for tx2 ' -1 --- 'mailbox ready last command finished ' -2 --- 'txcheck, returns -1 if buffer full else bytes waiting in buffer in tx2_param ' -3 --- 'txcount, returns number of bytes waiting in buffer in tx2_param ' -4 --- 'txsize, returns size of buffer in bytes in tx2_param ' -5 hubaddress 'str, will write bytes from hubaddress to buffer until reaching a zero byte ' -6 value 'dec, will write value in tx2_param as decimal without leading zero's to buffer ' -(6+(digits<<8) value 'dec, will write last digits chars of value in tx2_param as decimal replacing leading zero's with space to buffer ' -7 value 'dec, will write 10 chars of value in tx2_param as decimal with leading zero's to buffer ' -(7+(digits<<8) value 'dec, will write last digits chars of value in tx2_param as decimal with leading zero's to buffer ' 'all dec routines will put a '-' as first char if value is negative ' -8 value 'hex, will write value in tx2_param as hex without leading zero's to buffer ' -(8+(digits<<8) value 'hex, will write last digits chars of value in tx2_param as hex replacing leading zero's with space to buffer ' -9 value 'hex, will write 8 chars of value in tx2_param as hex with leading zero's to buffer ' -(9+(digits<<8) value 'hex, will write last digits chars of value in tx2_param as hex with leading zero's to buffer ' >0 ' size hubaddress 'txblock, will write size bytes from hubaddress to buffer ' '======================================================================= ' ' Now the PASM code ' ' I am reusing most of the initialisation code space for later needed Variables. ' ' Just ignore the labels on the left until the command loop ' '======================================================================= ' DAT org 0 ' cogserial_init ' '----------------------------------------------------------------------- ' 'loading parameters and reusing init code space for variables ' '----------------------------------------------------------------------- rx1_mailbox_ptr rdlong rx1_mailbox_ptr, ptra++ 'pointer to mailbox in hub and rx1 mailbox hub address rx1_pin rdlong rx1_pin, ptra++ 'serial1 rxpin1 rx1_bitperiod rdlong rx1_bitperiod, ptra++ 'bitperiod := 7 + ((CLKFREQ / baudrate) << 16) rx1_mode rdlong rx1_mode, ptra++ 'configure rx1_pin for asynchronous receive, always input rx1_lut_buff rdlong rx1_lut_buff, ptra++ 'lut rx1 receive buffer address in lut rx1_lut_btop rdlong rx1_lut_btop, ptra++ 'lut rx1 receive buffer top address in lut (size for rx1) tx1_pin rdlong tx1_pin, ptra++ 'serial1 txpin tx1_bitperiod rdlong tx1_bitperiod, ptra++ 'bitperiod := 7 + ((CLKFREQ / baudrate) << 16) tx1_mode rdlong tx1_mode, ptra++ 'configure tx1_pin for asynchronous transmit, always output tx1_lut_buff rdlong tx1_lut_buff, ptra++ 'lut tx1 send buffer address in lut tx1_lut_btop rdlong tx1_lut_btop, ptra++ 'lut tx1 send buffer top address in lut (size for tx1) rx2_pin rdlong rx2_pin, ptra++ 'serial1 rx2pin rx2_bitperiod rdlong rx2_bitperiod, ptra++ 'bitperiod := 7 + ((CLKFREQ / baudrate) << 16) rx2_mode rdlong rx2_mode, ptra++ 'configure rx2_pin for asynchronous receive, always input rx2_lut_buff rdlong rx2_lut_buff, ptra++ 'lut rx2 receive buffer address in lut rx2_lut_btop rdlong rx2_lut_btop, ptra++ 'lut rx2 receive buffer top address in lut (size for rx2) tx2_pin rdlong tx2_pin, ptra++ 'serial1 tx2pin tx2_bitperiod rdlong tx2_bitperiod, ptra++ 'bitperiod := 7 + ((CLKFREQ / baudrate) << 16) tx2_mode rdlong tx2_mode, ptra++ 'configure tx2_pin for asynchronous transmit, always output tx2_lut_buff rdlong tx2_lut_buff, ptra++ 'lut tx2 send buffer address in lut tx2_lut_btop rdlong tx2_lut_btop, ptra++ 'lut tx2 send buffer top address in lut (size for tx2) tx_i_ct1wait rdlong tx_i_ct1wait, ptra++ 'sysclocks to wait between calls to tx interrupt '----------------------------------------------------------------------- ' ' adjust tail pointers to bytes ' '----------------------------------------------------------------------- tx_i_char shl rx1_lut_btop, #2 tx_i_address shl rx2_lut_btop, #2 tx_i_lutvalue shl tx1_lut_btop, #2 tx_i_lutbuf shl tx2_lut_btop, #2 '----------------------------------------------------------------------- ' ' calculate mailbox pointers for later use ' '----------------------------------------------------------------------- rx1_param_ptr mov rx1_param_ptr, rx1_mailbox_ptr 'rx1 param hub address rx1_head add rx1_param_ptr, #4 'rx1 head position tx1_mailbox_ptr mov tx1_mailbox_ptr, rx1_param_ptr 'tx1 mailbox hub address rx1_tail add tx1_mailbox_ptr, #4 'rx1 tail position tx1_param_ptr mov tx1_param_ptr, tx1_mailbox_ptr 'tx1 param hub address rx1_i_char add tx1_param_ptr, #4 'tmp char for rx1_isr rx2_mailbox_ptr mov rx2_mailbox_ptr, tx1_param_ptr 'rx2 mailbox hub address rx1_i_address add rx2_mailbox_ptr, #4 'tmp address for rx1_isr rx2_param_ptr mov rx2_param_ptr, rx2_mailbox_ptr 'rx2 param hub address tx1_head add rx2_param_ptr, #4 'tx1 head position tx2_mailbox_ptr mov tx2_mailbox_ptr, rx2_param_ptr 'tx2 mailbox hub address tx1_tail add tx2_mailbox_ptr, #4 'tx1 tail position tx2_param_ptr mov tx2_param_ptr, tx2_mailbox_ptr 'tx2 param hub address tx_i_test add tx2_param_ptr, #4 'tmp char for tx1_send '----------------------------------------------------------------------- ' ' clear mailboxes ' '----------------------------------------------------------------------- tx1_address wrlong minusOne, tx2_param_ptr 'tmp address for tx1_send rx2_head wrlong minusOne, tx2_mailbox_ptr 'rx2 head position rx2_tail wrlong minusOne, rx2_param_ptr 'rx2 tail position rx2_i_char wrlong minusOne, rx2_mailbox_ptr 'tmp char for rx2_isr rx2_i_address wrlong minusOne, tx1_param_ptr 'tmp address for rx2_isr tx2_head wrlong minusOne, tx1_mailbox_ptr 'tx2 head position tx2_tail wrlong minusOne, rx1_param_ptr 'tx2 tail position '----------------------------------------------------------------------- ' ' init used smartpins ' '----------------------------------------------------------------------- tx2_address cmp rx1_pin, minusOne wz 'tmp address for tx2_send 'if rx1_pin == -1 cmd if_z jmp #end_rx1_reset 'tmp cmd used for HEX and DEC out ' skip RX1 setting smart pin '----------------------------------------------------------------------- ' ' Reset rx1 clear buffer pointers enable pin and int1 ' '----------------------------------------------------------------------- decbuf setint1 #0 'decbuf(0) reuses the next 11 longs 'disable int1 dirl rx1_pin 'decbuf(1) 'disable receiver mov rx1_head, #0 'decbuf(2) 'reset serial buffer pointers mov rx1_tail, #0 'decbuf(3) mov rx1_i_char, #%110<<6 'decbuf(4) add rx1_i_char, rx1_pin 'decbuf(5) wrpin rx1_mode, rx1_pin 'decbuf(6) 'configure rx_pin for asynchronous receive, always input wxpin rx1_bitperiod, rx1_pin 'decbuf(7) setse1 rx1_i_char 'decbuf(8) 'set se1 to trigger on rx1_pin (rx1_pin high) mov ijmp1, #rx1_isr 'decbuf(9) 'set int1 jump vector to rx1 ISR setint1 #4 'decbuf(10) 'set int1 to trigger on se1 rx1_param dirh rx1_pin 'tmp parameter for rx1 cmd 'enable receiver end_rx1_reset '----------------------------------------------------------------------- cmdparam cmp tx1_pin, minusOne wz 'blockaddress used in HEX/DEC 'if tx1_pin == -1 pxgetchar if_z jmp #end_tx1_reset 'value used in command loop ' skip setting TX1 smart pin '----------------------------------------------------------------------- ' ' Reset tx1 set tx1_mode and tx1_bitperiod, enable pin ' '----------------------------------------------------------------------- byteindex dirl tx1_pin 'tmp parameter for rx1 cmd 'disable transmitter tx1param mov tx1_head, #0 'tmp parameter for tx1 cmd 'reset serial buffer pointers lutvalue mov tx1_tail, #0 rx2_param wrpin tx1_mode, tx1_pin 'tmp parameter for rx2 cmd 'configure tx1_pin for asynchronous transmit, always output tx_i_tail wxpin tx1_bitperiod, tx1_pin 'tmp parameter for rx2 cmd tx2param dirh tx1_pin 'tmp parameter for tx2 cmd 'enable transmitter end_tx1_reset '----------------------------------------------------------------------- lutaddress cmp rx2_pin, minusOne wz 'lutaddress used in command loop 'if rx2_pin == -1 value if_z jmp #end_rx2_reset 'value used in command loop ' skip RX2 setting smart pin '----------------------------------------------------------------------- ' ' Reset rx2 clear buffer pointers enable pin and int2 ' '----------------------------------------------------------------------- txblock setint2 #0 'tmp parameter for tx2 cmd 'disable int2 pxtail dirl rx2_pin ' 'disable receiver tx_i_ct1 mov rx2_head, #0 'tx_i_ct1 used in tx_isr 'reset serial buffer pointers lutbuff mov rx2_tail, #0 'tx_i_ct1wait used in tx_isr txdec mov rx2_i_char, #%110<<6 'txdec used by HEX/DEC txnumptr add rx2_i_char, rx2_pin 'used as pointer for output of HX/DEC txcogptr wrpin rx2_mode, rx2_pin 'used as pointer for output of HX/DEC 'configure rx_pin for asynchronous receive, always input txloopctr wxpin rx2_bitperiod, rx2_pin tx_i_byteindex setse2 rx2_i_char 'set se1 to trigger on rx1_pin (rx1_pin high) pxdonewritepar mov ijmp2, #rx2_isr 'set int2 jump vector to rx2 ISR pxdone setint2 #5 'set int2 to trigger on se2 lutbtop dirh rx2_pin 'enable receiver end_rx2_reset '----------------------------------------------------------------------- head cmp tx2_pin, minusOne wz 'if tx2_pin == -1 tail if_z jmp #end_tx2_reset ' skip setting TX2 smart pin '----------------------------------------------------------------------- ' ' Reset tx2 set tx2_mode and tx2_bitperiod, enable pin ' '----------------------------------------------------------------------- pxhead dirl tx2_pin 'disable transmitter pxcmd mov tx2_head, #0 'reset serial buffer pointers pxparam mov tx2_tail, #0 cmdparam wrpin tx2_mode, tx2_pin 'configure tx2_pin for asynchronous transmit, always output rx1_i_byte_index wxpin tx2_bitperiod, tx2_pin rx2_i_byte_index dirh tx2_pin 'enable transmitter end_tx2_reset '----------------------------------------------------------------------- ' ' Enable int3 for TX ' '----------------------------------------------------------------------- rx1_i_lut_value mov ijmp3, #tx_isr 'set int3 vector - later sysclocks to wait for in tx_isr rx2_i_lut_value setint3 #1 'set int3 for ct-passed-ct1 event later decimal num to send getct tx_i_ct1 'set initial tx_i_ct1 target addct1 tx_i_ct1, tx_i_ct1wait '----------------------------------------------------------------------- ' ' this tells calling cog we got the parameters and are ready to roll ' '----------------------------------------------------------------------- wrlong minusOne, rx1_mailbox_ptr 'tmp char for tx2_send 'write -1 into rx1_mailbox_ptr in the HUB, now cogstart finished '======================================================================= ' 'command loop ' '======================================================================= rx1_cmd_check cmp rx1_pin, minusOne wz if_z jmp #tx1_cmd_check cmp rx1_cmd, minusOne wz 'old cmd finished? if_z rdlong rx1_cmd, rx1_mailbox_ptr 'cmd from rx1 mailbox if_z rdlong rx1_param, rx1_param_ptr 'param from rx1 mailbox cmp rx1_cmd, minusOne wz if_nz call #rx1_do_cmd 'do it tx1_cmd_check cmp tx1_pin, minusOne wz if_z jmp #rx2_cmd_check cmp tx1cmd, minusOne wz 'old cmd finished? if_z rdlong tx1cmd, tx1_mailbox_ptr 'cmd from tx1 mailbox if_z rdlong tx1param, tx1_param_ptr 'param from tx1 mailbox cmp tx1cmd, minusOne wz if_nz call #tx1_do_cmd 'do it rx2_cmd_check cmp rx2_pin, minusOne wz if_z jmp #tx2_cmd_check cmp rx2_cmd, minusOne wz 'old cmd finished? if_z rdlong rx2_cmd, rx2_mailbox_ptr 'cmd from rx2 mailbox if_z rdlong rx2_param, rx2_param_ptr 'param from rx2 mailbox cmp rx2_cmd, minusOne wz if_nz call #rx2_do_cmd 'do it tx2_cmd_check cmp tx2_pin, minusOne wz if_z jmp #rx1_cmd_check cmp tx2cmd, minusOne wz 'old cmd finished? if_z rdlong tx2cmd, tx2_mailbox_ptr 'cmd from tx2 mailbox if_z rdlong tx2param, tx2_param_ptr 'param from tx2 mailbox cmp tx2cmd, minusOne wz if_nz call #tx2_do_cmd 'do it jmp #rx1_cmd_check '======================================================================= ' ' INT 1 - rx1 read interrupt writes byte in lut buffer, runs if pin receives a char ' '======================================================================= rx1_isr mov rx1_i_char, rx1_head 'do I have space in my buffer? incmod rx1_i_char, rx1_lut_btop cmp rx1_i_char, rx1_tail wz 'hitting tail is bad rdpin rx1_i_char, rx1_pin 'get received chr if_z reti1 'and return if buffer full shr rx1_i_char, #32-8 'shift to lsb justify mov rx1_i_byte_index, rx1_head and rx1_i_byte_index, #%11 'now 0 to 3 mov rx1_i_address, rx1_head 'adjust to buffer start shr rx1_i_address, #2 add rx1_i_address, rx1_lut_buff 'by adding rx1_lut_buff rdlut rx1_i_lut_value, rx1_i_address altsb rx1_i_byte_index, #rx1_i_lut_value setbyte 0, rx1_i_char, #0 wrlut rx1_i_lut_value, rx1_i_address 'write byte to circular buffer in lut incmod rx1_head, rx1_lut_btop 'increment buffer head reti1 'exit '======================================================================= ' ' INT 2 - rx2 read interrupt writes byte as long in lut buffer, runs if pin receives a char ' '======================================================================= rx2_isr mov rx2_i_char, rx2_head 'do I have space in my buffer? incmod rx2_i_char, rx2_lut_btop cmp rx2_i_char, rx2_tail wz 'hitting tail is bad rdpin rx2_i_char, rx2_pin 'get received chr if_z reti2 'and return if buffer full shr rx2_i_char, #32-8 'shift to lsb justify mov rx2_i_byte_index, rx2_head and rx2_i_byte_index, #%11 mov rx2_i_address, rx2_head 'adjust to buffer start shr rx2_i_address, #2 add rx2_i_address, rx2_lut_buff 'by adding rx1_lut_buff rdlut rx2_i_lut_value, rx2_i_address altsb rx2_i_byte_index, #rx2_i_lut_value setbyte 0, rx2_i_char, #0 wrlut rx2_i_lut_value, rx2_i_address 'write byte to circular buffer in lut incmod rx2_head, rx2_lut_btop 'increment buffer head reti2 'exit '======================================================================= ' ' INT 3 - tx write interrupt, reads bytes from longs in lut buffer , runs once every tx_i_ct1wait clocks ' '======================================================================= tx_isr cmp tx1_head, tx1_tail wz 'tx1 byte to send? if_z jmp #.tx2_send 'no wait for next time rdpin tx_i_test, tx1_pin wc 'wait for pin ready? if_c jmp #.tx2_send 'no wait for next time mov tx_i_tail, tx1_tail 'adjust to buffer start mov tx_i_lutbuf, tx1_lut_buff 'by adding tx1_lut_buff call #.txgetlutchar incmod tx1_tail, tx1_lut_btop 'increment buffer tail wypin tx_i_char, tx1_pin 'send byte '.tx1wait waitx #1 ' testp tx1_pin wz ' if_nz jmp #.tx1wait .tx2_send cmp tx2_head, tx2_tail wz 'tx2 byte to send? if_z jmp #.end_isr 'no wait for next time rdpin tx_i_test, tx2_pin wc 'wait for pin ready? if_c jmp #.end_isr 'no wait for next time mov tx_i_tail, tx2_tail 'adjust to buffer start mov tx_i_lutbuf, tx2_lut_buff 'by adding tx2_lut_buff call #.txgetlutchar incmod tx2_tail, tx2_lut_btop 'increment buffer tail wypin tx_i_char, tx2_pin 'send byte '.tx2wait waitx #1 ' testp tx2_pin wz ' if_z jmp #.tx2wait .end_isr addct1 tx_i_ct1, tx_i_ct1wait 'update txct1 target reti3 'return to main program '----------------------------------------------------------------------- .txgetlutchar mov tx_i_byteindex, tx_i_tail and tx_i_byteindex, #%11 mov tx_i_address, tx_i_tail 'adjust to buffer start shr tx_i_address, #2 add tx_i_address, tx_i_lutbuf 'by adding txX_lut_buff rdlut tx_i_lutvalue, tx_i_address 'get byte from circular buffer in lut altgb tx_i_byteindex, #tx_i_lutvalue _ret_ getbyte tx_i_char, tx_i_lutvalue, #0 '======================================================================= ' ' handle rx mailbox ' '======================================================================= rx1_do_cmd mov pxdonewritepar, #rx1_donewritepar mov pxdone, #rx1_done mov pxgetchar, #rx1_get_value mov pxparam, #rx1_param mov pxcmd, #rx1_cmd mov pxtail, #rx1_tail mov lutbuff, rx1_lut_buff mov lutbtop, rx1_lut_btop mov head, rx1_head mov tail, rx1_tail mov cmd, rx1_cmd 'preset cmd jmp #rxdocmd '----------------------------------------------------------------------- rx2_do_cmd mov pxdonewritepar, #rx2_donewritepar mov pxdone, #rx2_done mov pxgetchar, #rx2_get_value mov pxparam, #rx2_param mov pxcmd, #rx2_cmd mov pxtail, #rx1_tail mov lutbuff, rx2_lut_buff mov lutbtop, rx2_lut_btop mov head, rx2_head mov tail, rx2_tail mov cmd, rx2_cmd 'preset cmd '- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - rxdocmd cmps cmd, #0 wc wz '#rx_block if_ge jmp #rxblockread cmp cmd, minusTwo wz '#rx_check if_nz jmp #.negcmd mov value, minusOne '#value cmp head, tail wz 'byte received? if_nz call pxgetchar jmp pxdonewritepar .negcmd neg cmd mov cmdparam, cmd shr cmdparam, #8 and cmd, #$FF cmp cmd, #3 wz 'get count of bytes in rx buffer if_z jmp #rxcount cmp cmd, #4 wz 'get size of rx buffer if_z mov value, lutbtop if_z jmp pxdonewritepar 'returns size of receive buffer jmp pxdone 'clear rx_mailbox - done '----------------------------------------------------------------------- rx1_get_value call #rxgetrxchar _ret_ incmod rx1_tail, rx1_lut_btop 'increment buffer tail '----------------------------------------------------------------------- rx2_get_value call #rxgetrxchar _ret_ incmod rx2_tail, rx2_lut_btop 'increment buffer tail '----------------------------------------------------------------------- rxgetrxchar mov byteindex, tail and byteindex, #%11 mov lutaddress, tail 'adjust to buffer start shr lutaddress, #2 add lutaddress, lutbuff 'by adding rx_lut_buff rxgetlutchar rdlut lutvalue, lutaddress 'get byte from circular buffer in lut altgb byteindex, #lutvalue _ret_ getbyte value, lutvalue, #0 '----------------------------------------------------------------------- rx1_donewritepar wrlong value, rx1_param_ptr 'write rx1 parameter back in HUB rx1_done mov rx1_cmd, minusOne _ret_ wrlong rx1_cmd, rx1_mailbox_ptr 'rx1 command finished '----------------------------------------------------------------------- rx2_donewritepar wrlong value, rx2_param_ptr 'rx2 parameter back in HUB rx2_done mov rx2_cmd, minusOne _ret_ wrlong rx2_cmd, rx2_mailbox_ptr 'rx2 command finished '======================================================================= ' ' handle tx mailbox ' '======================================================================= tx1_do_cmd mov pxdonewritepar, #tx1_donewritepar mov pxdone, #tx1_done mov pxparam, #tx1param mov pxcmd, #tx1cmd mov pxhead, #tx1_head mov pxtail, #tx1_tail mov txdec, tx1param 'preset txdec mov txnumptr, #tx1_write_num_wait 'preset txnumptr mov lutbtop, tx1_lut_btop mov lutbuff, tx1_lut_buff mov head, tx1_head mov tail, tx1_tail mov cmd, tx1cmd 'preset cmd jmp #txdocmd '----------------------------------------------------------------------- tx2_do_cmd mov pxdonewritepar, #tx2_donewritepar mov pxdone, #tx2_done mov pxparam, #tx2param mov pxcmd, #tx2cmd mov pxhead, #tx2_head mov pxtail, #tx2_tail mov txdec, tx2param 'preset txdec mov txnumptr, #tx2_write_num_wait 'preset txnumptr mov lutbtop, tx2_lut_btop mov lutbuff, tx2_lut_buff mov head, tx2_head mov tail, tx2_tail mov cmd, tx2cmd 'preset cmd '- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - txdocmd cmps cmd, #0 wc wz '#txX_block if_ge jmp #txblockwrite neg cmd mov cmdparam, cmd shr cmdparam, #8 and cmd, #$FF cmp cmd, #2 wz 'get count of free bytes in tx buffer or -1 if full if_z jmp #txcheck cmp cmd, #3 wz 'get count of free bytes in tx buffer if_z jmp #txcount cmp cmd, #4 wz 'get size of tx buffer if_z mov value, lutbtop if_z jmp pxdonewritepar cmp cmd, #5 wz 'output str on tx1 if_z jmp #txblockwrite cmp cmd, #6 wz 'output dec without leading zero's on tx if_z jmp #decout cmp cmd, #7 wz 'output dec with leading zero's on tx if_z jmp #decout cmp cmd, #8 wz 'output hex without leading zero's on tx if_z jmp #hexout cmp cmd, #9 wz 'output he with leading zero's on tx if_z jmp #hexout jmp pxdone 'clear tx_mailbox - done '----------------------------------------------------------------------- tx1_write_num_wait 'writes ascii digit to tx1 buffer and waits if buffer full mov head, tx1_head mov tail, tx1_tail call #tx_write_num_wait _ret_ incmod tx1_head, tx1_lut_btop 'increment buffer head '----------------------------------------------------------------------- tx2_write_num_wait 'writes ascii digit to tx2 buffer and waits if buffer full mov head, tx2_head mov tail, tx2_tail call #tx_write_num_wait _ret_ incmod tx2_head, tx2_lut_btop 'increment buffer head '----------------------------------------------------------------------- tx1_donewritepar wrlong value, tx1_param_ptr 'return tx1 result tx1_done mov tx1cmd, minusOne _ret_ wrlong tx1cmd, tx1_mailbox_ptr 'clear tx1_mailbox - tx1_cmd finished '----------------------------------------------------------------------- tx2_donewritepar wrlong value, tx2_param_ptr 'return tx2 result tx2_done mov tx2cmd, minusOne _ret_ wrlong tx2cmd, tx2_mailbox_ptr 'clear tx2_mailbox - tx2_cmd finished '======================================================================= ' ' used by both RX and both TX ports ' '======================================================================= getbufused mov value, head 'returns count of bytes used in given buffe in value cmp head, tail wc wz 'if head0) if_nz mov cmd, #7 'force ouput of zeroes not spaces after first digit cmp txloopctr, #1 wz if_z mov decbuf, #1 'set Flag also for last digit if_z mov cmd, #7 'force ouput of zeroes not spaces for last digit cmp decbuf, #0 wz 'now check Flag if we need to output if_z jmp #.done 'no - done cmp cmdparam, #0 wz 'if no size if_z jmp #.out 'put out char cmp cmd, #6 wz 'is cmd 6? if_z jmp #.replaceZero cmp cmd, #8 wz 'is cmd 8? if_z jmp #.replaceZero jmp #.out 'no - put out char .replaceZero cmp value, #0 wz 'if zero replace by space if_z mov value, #16 '48 - 32 ... space instead of 0 if_z neg value 'now -16 .out call txnumptr 'send char (+48) .done sub txcogptr, #1 'next char djnz txloopctr, #digitoutloop 'next digit jmp pxdone 'clear tx_mailbox '----------------------------------------------------------------------- tx_write_num_wait 'writes ascii digit to tx2 buffer and waits if buffer full add value, #48 'make ascii out of digit .tx_write_byte_wait 'writes byte to tx2 buffer and waits if buffer full alts pxhead mov lutaddress, 0-0 'returns tx2_head+1 incmod lutaddress, lutbtop 'in lutaddress alts pxtail cmp lutaddress, 0-0 wz 'hitting tail is bad if_z jmp #.tx_write_byte_wait 'buffer full - wait ' txputlutchar mov byteindex, head and byteindex, #%11 mov lutaddress, head 'adjust to buffer start shr lutaddress, #2 add lutaddress, lutbuff 'by adding txX_lut_buff rdlut lutvalue, lutaddress altsb byteindex, #lutvalue setbyte 0, value, #0 _ret_ wrlut lutvalue, lutaddress 'write byte to circular buffer in lut '----------------------------------------------------------------------- minusOne long -1 minusTwo long -2 minusFive long -5 ' rx1_cmd long -1 tx1cmd long -1 rx2_cmd long -1 tx2cmd long -1 '----------------------------------------------------------------------- 'fit 0'471 479 466 486 484 476 478 '-----------------------------------------------------------------------