Shop OBEX P1 Docs P2 Docs Learn Events
setse1-setse4 - how to configure interrupts — Parallax Forums

setse1-setse4 - how to configure interrupts

msrobotsmsrobots Posts: 3,701
edited 2019-01-26 02:07 in Propeller 2
OK, I am able to use this by stealing from the rombooter.spin2 for serial receive.
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

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
		call	#tx1_send				' hitchhiking here every receive interrupt allows fo a send
		reti1						'2/4	..exit


And that one works

Now I am trying to get a interrupt if my TX pin is either done with sending or ready to get the next byte. Either or would help.

I tried
tx1_reset	setint2		#0			'disable int2
		dirl	tx1_pin					'disable transmitter
		mov	tx1_head,	#0			'reset serial buffer pointers
		mov	tx1_tail,	#0
		wrpin	tx1_mode,	tx1_pin			'configure tx1_pin for asynchronous transmit, always output
		wxpin	tx1_bitperiod, 	tx1_pin
		
		mov	tx1_char,	#%100<<6
		add	tx1_char, 	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		#5			'set int2 to trigger on se2
 
	_ret_	dirh	tx1_pin					'enable transmitter

tx1_isr	cmp	tx1_head, 	tx1_tail 	wz	'byte to send?
	if_z	reti2 						'no wait for next time
		rdpin	tx1_char,	tx1_pin		wc	'wait for transmit done
	if_c	reti2					
		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
		wypin	tx1_char,	tx1_pin			'send byte
		ret12


But that seems not to work. The interrupt isn't firing on tx done but on rx? Where do I find setse1-4 documented?

It would be nice to have tx interrupt driven too, so that my serial cog can communicate with the program while the transfer is done in the background.

Any clues out there how to bind a tx serial smart pin to a interrupt source?

Enjoy!

Mike

Comments

  • cgraceycgracey Posts: 14,133
    You'll have to set up an IN interrupt using SETSEx. It's in the big Google Doc. Have you been looking in there?
  • well I do not find setex at all in the docs, it is just referenced in the Parallax Propeller 2 Documentation v32 in the interrupt section and where wait and poll is described but the command itself is nowhere to be found.

    Maybe this needs more explanation

    so my guess now is that
    mov	tx1_char,	#%110<<6
    		add	tx1_char, 	tx1_pin 
    setse2	tx1_char
    

    raises a out interrupt, since I stole it from the rx setup in the rom

    what would be the in interrupt?

    Mike
  • cgraceycgracey Posts: 14,133
    edited 2019-01-26 01:46
    Look under 'EVENTS".

    It's just above the interrupt section.
  • msrobotsmsrobots Posts: 3,701
    edited 2019-01-26 02:08
    OK further testing
    with
    mov	tx1_char,	#%100<<6
    		add	tx1_char, 	tx1_pin 
    setse2	tx1_char
    and setting
    setint2		#5			'set int2 to trigger on se2
    
    

    I get ONE byte out, then it stops.

    I updated the code of the first post to where I am at right now

    something is missing...

    Mike
  • cgraceycgracey Posts: 14,133
    Try loading TWO bytes, initially. It's double-buffered.
  • msrobotsmsrobots Posts: 3,701
    edited 2019-01-26 03:03
    cgracey wrote: »
    Try loading TWO bytes, initially. It's double-buffered.

    well the code is like this and I have a string in my buffer and it does put out the first byte then stops.

    if I use #4 for tx also I get a byte transmitted every time I send one, so the tx_isr is working properly, just not on its own...
    '
    ' tx1 write interrupt, reads long in lut buffer
    ' 
    tx1_isr		cmp	tx1_head, 	tx1_tail 	wz	'byte to send?
    	if_z	reti2 						'no wait for next time
    		rdpin	tx1_char,	tx1_pin		wc	'wait for transmit done
    	if_c	reti2					
    		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
    		wypin	tx1_char,	tx1_pin			'send byte
    		reti2
    '
    ' 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
    
    '
    ' 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,	#%100<<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 low?)
    		mov	ijmp2,		#tx1_isr		'set int2 jump vector to tx1 ISR
    		setint2	#5					'set int2 to trigger on se2 
    	_ret_	dirh	tx1_pin					'enable transmitter
    

    something is missing

    I attach the current file just outputting the first "H" of hello world

    Enjoy!

    Mike
  • cgraceycgracey Posts: 14,133
    I'm not on my computer, so I don't see the controlling code, but you should do two initial WYPIN's to prime the system.
  • evanhevanh Posts: 15,126
    Mike,
    What you've got is complicated. Only way to initiate a transmit is from tx1_send routine. There's something fragile looking about the logic for deciding to call tx1_send from the command loop. Having a potentially infinite looping wait when servicing many real-time actions is ill advised.

    There looks to be duplication of function between tx1_send routine and tx1_isr routine. Any chance they are competing?

  • I sadly do not really understand what you are saying, but I think my idea of sending out a byte from my buffer as soon as the pin can handle it is not so smart at all anyways, because it would stress the receiving device without breaks in between. And adding a character delay in the interrupt would stall the system

    I got around it by using int3 in mode #1 every #500 clock ticks and just check my tx buffer(s) if anything there to transmit. This leaves int 1 and int 2 for two RX channels, and the rest of the cog free to talk to the main program and deliver/read data from the hub to the lut buffers.

    So cogserial has now two fullduplex channels, each receiving on their own interrupt and sharing int 3 for checking if transmit is possible.
    Seems to work fine right now, needs some more testing. Right now I 'wait' 500 sysclocks between int3's checking for transmit, this might need some more thought.

    So my failure to use a interrupt on the tx pin lead to having a serial driver for two full duplex connections instead of one and tx for both on a sysclock based interrupt.

    I am not used to use interrupts, it is kind of interesting.

    So - problem solved on different ways but still eager to find out how a TX interrupt could work for fastest possible transmission.

    Enjoy!

    Mike
  • cgraceycgracey Posts: 14,133
    The serial smart pin modes are designed to transmit and receive without any gaps between data. You need to write two transmit data values, initially, via WYPIN to get the transmitter rolling, though.
  • evanhevanh Posts: 15,126
    msrobots wrote: »
    I sadly do not really understand what you are saying,

    I'll have a shot at expanding:
    Only way to initiate a transmit is from tx1_send routine.
    That was a tad brief. What was meant here is the ISR has to be prompted so to speak. So some initial character has to be transmitted before an interrupt gets generated. The only way you have for this is via the tx1_send routine.


    The fragile looking logic in the command loop is in respect to both, the jump to #.tx1send causing a potential infinite wait loop, and also the looping of trying to send every character instead of letting the ISR take over after first character. The tx_loopcount shenanigans can vanish then.

  • evanhevanh Posts: 15,126
    The logic should probably be something like this:
    		call	#tx1_count
    		cmp	tx_char,	#0		wz	'bytes to send?
    		rdpin	tx1_char,	tx1_pin		wc	'transmitting?
    if_z_and_nc	call	#tx1_send				'bytes to send and not transmitting
    		jmp	#rx1_cmd_check
    
    
  • evanh wrote: »
    The logic should probably be something like this:
    		call	#tx1_count
    		cmp	tx_char,	#0		wz	'bytes to send?
    		rdpin	tx1_char,	tx1_pin		wc	'transmitting?
    if_z_and_nc	call	#tx1_send				'bytes to send and not transmitting
    		jmp	#rx1_cmd_check
    
    
    Yeah, I was pondering that too, that I need to start the first one by hand crancing or a trigintx. but I found a nicer solution allaowing 2 pairs of full duplex with 3 interrupts.
    2 int's for 2 rx lines an int 3 running mode #1 and just checking if something needs to be send. Works nice so far, will post soon.

    Doing it this way gets rid of all of the 'fragile looking logic in the command loop'. :smile:

    I just need to change a couple of lines of code and then I post the new version... (famous words, indeed)

    Enjoy!

    Mike
  • I post the current working code of cogserial in the cogserial thread.
    So no NEED for a solution. But I still need to figure out how to do that, with tx as source for a interrupt., it like itching.
    Right now I will try to build some multi-cog-testharness to check and validate my cogserial driver. And find (hopefully) out how fast it can talk to copies of itself running in other cogs.

    Enjoy!

    Mike
Sign In or Register to comment.