' ' buffered smart pin serial object for P2 Eval board, buffering rx/tx in the Cog ' CON _txmode = %0000_0000_000_0000000000000_01_11110_0 'async tx mode, output enabled for smart output _rxmode = %0000_0000_000_0000000000000_00_11111_0 'async rx mode, input enabled for smart input VAR long cog PUB stop if cog cogstop(cog) PUB start(rxpin, txpin, mode, baudrate) return startExt(rxpin, txpin, baudrate, baudrate, _rxmode, _txmode) PUB startExt(rxpin, txpin, rxbaudrate, txbaudrate, rxmode, txmode) stop rx1_mailbox_ptr := @rx1_cmd rx1_param_ptr := @rx1_param rx1_bitperiod := 7 + ((CLKFREQ / rxbaudrate) << 16) rx1_pin := rxpin tx1_mailbox_ptr := @tx1_cmd tx1_param_ptr := @tx1_param tx1_bitperiod := 7 + ((CLKFREQ / txbaudrate) << 16) tx1_pin := txpin cog := coginit(1,@rx1_init,@rx1_cmd) + 1 return 1 ' check if byte received (never waits) ' returns -1 if no byte, otherwise byte PUB rxcheck : rxbyte repeat until rx1_cmd == -1 rx1_param := -1 rx1_cmd := -2 repeat until rx1_cmd == -1 rxbyte := rx1_param ' receive a byte (waits until done) ' returns received byte PUB rx : rxbyte rx_read(@rxbyte,1) ' returns number of bytes of receive buffer PUB rx_size repeat until rx1_cmd == -1 rx1_param := 0 rx1_cmd := -4 repeat until rx1_cmd == -1 RESULT := rx1_param ' returns number of bytes waiting in receive buffer PUB rx_count repeat until rx1_cmd == -1 rx1_param := 0 rx1_cmd := -3 repeat until rx1_cmd == -1 RESULT := rx1_param ' receive a block from serial to memory of given size in bytes (waits until done) PUB rx_read(hubaddress, size) rx_read_async(hubaddress, size) repeat until rx1_cmd == -1 ' receive a block from serial to memory of given size in bytes (does not wait for completion - you may need to check rx1_cmd if done or not later in your code) PUB rx_read_async(hubaddress, size) repeat until rx1_cmd == -1 rx1_param := hubaddress rx1_cmd := size ' check if byte can be send (never waits) ' returns -1 if no space in buffer otherwise number of free bytes in send buffer PUB txcheck repeat until rx1_cmd == -1 tx1_param := -1 tx1_cmd := -2 repeat until tx1_cmd == -1 RESULT := tx1_param ' sends a byte (waits until done) PUB tx(val) tx_write(@val,1) PUB tx_async(val) tx_write_async(@val,1) ' returns number of bytes of send buffer PUB tx_size repeat until tx1_cmd == -1 tx1_param := 0 tx1_cmd := -4 repeat until tx1_cmd == -1 RESULT := tx1_param ' returns number of free bytes in send buffer PUB tx_count repeat until tx1_cmd == -1 tx1_param := 0 tx1_cmd := -3 repeat until tx1_cmd == -1 RESULT := tx1_param ' sends a block from memory to serial of given size in bytes (waits until done) PUB tx_write(hubaddress, size) tx_write_async(hubaddress, size) repeat until tx1_cmd == -1 ' sends a block from memory to serial of given size in bytes (does not wait for completion - you may need to check tx1_cmd if done or not later in your code) PUB tx_write_async(hubaddress, size) repeat until tx1_cmd == -1 tx1_param := hubaddress tx1_cmd := size ' transmit a string (waits until done) PUB str(s) | c tx_write(s, strsize(s)) ' transmit a string (does not wait for completion - you may need to check tx1_cmd if done or not later in your code) PUB str_async(s) | c tx_write_async(s, strsize(s)) PUB dec(value) | i, x '' Print a decimal number result := 0 x := value == NEGX 'Check for max negative if value < 0 value := ||(value+x) 'If negative, make positive; adjust for max negative tx_async("-") 'and output sign i := 1_000_000_000 'Initialize divisor repeat 10 'Loop for 10 digits if value => i tx_async(value / i + "0" + x*(i == 1)) 'If non-zero digit, output digit; adjust for max negative value //= i 'and digit from value result~~ 'flag non-zero found elseif result or i == 1 tx_async("0") 'If zero digit (or only digit) output it i /= 10 'Update divisor PUB hex(val, digits) | shft, x shft := (digits - 1) << 2 repeat digits x := (val >> shft) & $F shft -= 4 if (x => 10) x := (x - 10) + "A" else x := x + "0" tx_async(x) DAT rx1_cmd long -1 rx1_param long -1 tx1_cmd long -1 tx1_param long -1 DAT org 0 'mov rx1_mailbox_ptr, ptra 'mov tx1_mailbox_ptr, ptra 'add tx1_mailbox_ptr, #4 rx1_init cmp rx1_pin, minusOne wz if_nz call #rx1_reset tx1_init cmp tx1_pin, minusOne wz if_nz call #tx1_reset ' 'command loop ' rx1_cmd_test rdlong cmd, rx1_mailbox_ptr cmp cmd, minusOne wz if_nz call #rx1_do_cmd tx1_cmd_test rdlong cmd, tx1_mailbox_ptr cmp cmd, minusOne wz if_nz call #tx1_do_cmd .tx1send call #tx1_send if_z jmp #rx1_cmd_test if_c jmp #rx1_cmd_test jmp #.tx1send ' ' tx1 try to send, reads long in lut buffer ' tx1_send cmp tx1_head, tx1_tail wz 'byte to send? if_z ret 'no wait for next time rdpin tx1_char, tx1_pin wc 'wait for transmit done if_c ret mov tx1_address, tx1_tail 'adjust to buffer start add tx1_address, tx1_lut_buff 'by adding rx1_lut_buff rdlut tx1_char, tx1_address 'get byte from circular buffer in lut incmod tx1_tail, tx1_lut_btop 'increment buffer tail _ret_ wypin tx1_char, tx1_pin 'send byte ' ' rx1 read interrupt writes byte in lut buffer ' rx1_isr rdpin rx1_char, rx1_pin '2 get received chr shr rx1_char, #32-8 '2 shift to lsb justify mov rx1_address, rx1_head '2 adjust to buffer start add rx1_address, rx1_lut_buff '2 by adding rx1_lut_buff wrlut rx1_char, rx1_address '2 write byte to circular buffer in lut incmod rx1_head, rx1_lut_btop '2 ..increment buffer head reti1 '2/4 ..exit ' ' Reset rx1 clear buffer pointers enable pin and int1 ' rx1_reset setint1 #0 'disable int1 dirl rx1_pin 'disable receiver mov rx1_head, #0 'reset serial buffer pointers mov rx1_tail, #0 mov rx1_char, #%110<<6 add rx1_char, rx1_pin wrpin rx1_mode, rx1_pin 'configure rx_pin for asynchronous receive, always input wxpin rx1_bitperiod, rx1_pin setse1 rx1_char 'set se1 to trigger on rx1_pin (rx1_pin high) mov ijmp1, #rx1_isr 'set int1 jump vector to rx1 ISR setint1 #4 'set int1 to trigger on se1 _ret_ dirh rx1_pin 'enable receiver ' ' handle rx1 mailbox ' rx1_do_cmd cmps cmd, #0 wcz if_ge jmp #.rx1block cmp cmd, minusTwo wz '#rx1_check if_z jmp #.rx1check cmp cmd, minusThree wz '#rx1_count if_z jmp #.rx1count cmp cmd, minusFour wz '#rx1_size if_z jmp #.rx1size jmp #.done .rx1block rdlong blockaddress, rx1_param_ptr 'cmd is current count .rx1BlockLoop cmp cmd, #0 wz if_z jmp #.done cmp rx1_head, rx1_tail wz 'byte received? if_z wrlong blockaddress, rx1_param_ptr 'no - save back current Block address if_z wrlong cmd, rx1_mailbox_ptr 'no - save back current count if_z ret 'noting there try again next round mov rx_address, rx1_tail 'adjust to buffer start add rx_address, rx1_lut_buff 'by adding rx1_lut_buff rdlut rx_char, rx_address 'get byte from circular buffer in lut incmod rx1_tail, rx1_lut_btop 'increment buffer tail wrbyte rx_char, blockaddress 'write byte to Block add blockaddress, #1 'adjust Block address sub cmd, #1 'adjust count jmp #.rx1BlockLoop 'and get next byte .rx1check mov rx_char, minusOne cmp rx1_head, rx1_tail wz 'byte received? if_z jmp #.donewritepar .rx1get cmp rx1_head, rx1_tail wz 'byte received? if_z jmp #.rx1get rdlut rx_char, rx1_tail 'get byte from circular buffer in lut incmod rx1_tail, rx1_lut_btop 'increment buffer tail jmp #.donewritepar .rx1count cmp rx1_head, rx1_tail wcz if_le mov rx_char, rx1_tail if_le sub rx_char, rx1_head if_le jmp #.donewritepar if_ge mov rx_char, rx1_lut_btop if_ge sub rx_char, rx1_head if_ge add rx_char, rx1_tail jmp #.donewritepar .rx1size mov rx_char, rx1_lut_btop .donewritepar wrlong rx_char, rx1_param_ptr .done _ret_ wrlong minusOne, rx1_mailbox_ptr ' ' Reset tx1 set tx1_mode and tx1_bitperiod, enable pin ' tx1_reset 'setint2 #0 'disable int2 dirl tx1_pin 'disable transmitter mov tx1_head, #0 'reset serial buffer pointers mov tx1_tail, #0 'mov tx1_char, #%110<<6 'add tx1_char, tx1_pin wrpin tx1_mode, tx1_pin 'configure tx1_pin for asynchronous transmit, always output wxpin tx1_bitperiod, tx1_pin 'setse2 tx1_char 'set se2 to trigger on tx1_pin (tx1_pin high) 'mov ijmp2, #tx1_isr 'set int2 jump vector to tx1 ISR 'setint2 #4 'set int2 to trigger on se2 _ret_ dirh tx1_pin 'enable transmitter ' ' handle tx1 mailbox ' tx1_do_cmd cmps cmd, #0 wcz if_ge jmp #.tx1block cmp cmd, minusTwo wz '#tx1_check if_z jmp #.tx1check cmp cmd, minusThree wz '#tx1_count if_z jmp #.tx1count cmp cmd, minusFour wz '#tx1_size if_z jmp #.tx1size jmp #.done .tx1block rdlong blockaddress, tx1_param_ptr 'cmd is current count .tx1BlockLoop cmp cmd, #0 wz if_z jmp #.done mov tx_address, tx1_head incmod tx_address, tx1_lut_btop cmp tx_address, tx1_tail wz if_z wrlong blockaddress, tx1_param_ptr 'no - save back current Block address if_z wrlong cmd, tx1_mailbox_ptr 'no - save back current count if_z ret 'no space there try again next round mov tx_char, #0 rdbyte tx_char, blockaddress mov tx_address, tx1_head 'adjust to buffer start add tx_address, tx1_lut_buff 'by adding tx1_lut_buff wrlut tx_char, tx_address 'write byte to circular buffer in lut incmod tx1_head, tx1_lut_btop '..increment buffer head add blockaddress, #1 'adjust Block address sub cmd, #1 'adjust count jmp #.tx1BlockLoop 'and put next byte .tx1check mov tx_char, minusOne mov tx_address, tx1_head incmod tx_address, tx1_lut_btop cmp tx_address, tx1_tail wz if_z jmp #.donewritepar .tx1count cmp tx1_head, tx1_tail wcz if_le mov tx_char, tx1_tail if_le sub tx_char, tx1_head if_le jmp #.donewritepar if_ge mov tx_char, tx1_lut_btop if_ge sub tx_char, tx1_head if_ge add tx_char, tx1_tail jmp #.donewritepar .tx1size mov tx_char, tx1_lut_btop .donewritepar wrlong tx_char, tx1_param_ptr .done _ret_ wrlong minusOne, tx1_mailbox_ptr ' ' data ' minusOne long -1 minusTwo long -2 minusThree long -3 minusFour long -4 ' rx1_mailbox_ptr long -1 rx1_param_ptr long -1 rx1_pin long -1 'serial1 rxpin rx1_mode long %00_11111_0 'configure rx1_pin for asynchronous receive, always input rx1_bitperiod long 0 'bitperiod := 7 + ((CLKFREQ / baudrate) << 16) rx1_lut_buff long $000 'lut rx1 receive buffer address in lut rx1_lut_btop long $0FF 'lut rx1 receive buffer top address in lut (size for rx1) ' tx1_mailbox_ptr long -1 tx1_param_ptr long -1 tx1_pin long -1 'serial1 txpin tx1_mode long %01_11110_0 'configure tx1_pin for asynchronous transmit, always output tx1_bitperiod long 0 'bitperiod := 7 + ((CLKFREQ / baudrate) << 16) tx1_lut_buff long $100 'lut rx1 receive buffer address in lut tx1_lut_btop long $0FF 'lut rx1 receive buffer top address in lut (size for rx1) ' rx1_head res 1 'serial1 rxhead address rx1_tail res 1 'serial1 rxtail address tx1_head res 1 'serial1 txhead address tx1_tail res 1 'serial1 txtail address blockaddress res 1 cmd res 1 rx_char res 1 rx_address res 1 tx_char res 1 tx_address res 1 ' tx1_char res 1 'tmp char for tx1_send tx1_address res 1 'tmp address for tx1_send ' rx1_char res 1 'tmp char for rx1_isr rx1_address res 1 'tmp address for rx1_isr