Jump to content

Sub-millisecond wait routine


freddy

Recommended Posts

Hello,

during programming of digipot chips connected to DOUT pins I have the need to trigger CLK signal for a particular time. Calling 1ms MIOS_Delay is much too long (updating 16 digitpots with 6 registers each with 11 bit words just takes much too long), using no delay at all (i.e. triggering the pin to 1 followed by 0) is much too fast for my logic analyzer. How to achieve e.g. 1us delay (doesn't need much too precise, +/- 100ns is more than enough)?

I cannot imagime how this might work with timer and within an interrupt-serve routine. I've tried to look through forums but couldn't find anything that might help me.

Thanks,

freddy

Link to comment
Share on other sites

How to achieve e.g. 1us delay (doesn't need much too precise, +/- 100ns is more than enough)?

The PIC runs 10,000,000 instructions per second, that's 10,000 instructions per ms or 10 instructions per µs. If you want to wait for 1us you'll have to do nothing for 10 instructions. This can be easily done by simply doing NOP ten times.


bsf PORTA, 7 ; set pin high
nop ; start waiting
nop ; 2
nop ; 3
nop ; 4
nop ; 5
nop ; 6
nop ; 7
nop ; 8
nop ; 9
nop ; 10
bcf PORTA, 7 ; set pin low
[/code]

The code above will set Port A 7 high for exactly 1us. If you wrap that into a macro it'll look much nicer ;)

Link to comment
Share on other sites

The PIC runs 10,000,000 instructions per second, that's 10,000 instructions per ms or 10 instructions per µs. If you want to wait for 1us you'll have to do nothing for 10 instructions. This can be easily done by simply doing NOP ten times.


bsf PORTA, 7 ; set pin high
nop ; start waiting
nop ; 2
nop ; 3
nop ; 4
nop ; 5
nop ; 6
nop ; 7
nop ; 8
nop ; 9
nop ; 10
bcf PORTA, 7 ; set pin low
[/code] The code above will set Port A 7 high for exactly 1us. If you wrap that into a macro it'll look much nicer ;) The pin is set high or low at the end of an instruction (or at least at some consistent time within the instruction), thus that would be exactly 1.1 µs. Or another way of looking at it, this code will set Port A 7 high for exactly .1 µs.
[code]
bsf PORTA, 7 ; set pin high
bcf PORTA, 7 ; set pin low

:thumbsup:

Link to comment
Share on other sites

nILS,

The PIC runs 10,000,000 instructions per second, that's 10,000 instructions per ms or 10 instructions per µs. If you want to wait for 1us you'll have to do nothing for 10 instructions. This can be easily done by simply doing NOP ten times.


bsf PORTA, 7 ; set pin high

nop ; start waiting 

nop ; 2

nop ; 3

nop ; 4

nop ; 5

nop ; 6

nop ; 7

nop ; 8

nop ; 9

nop ; 10

bcf PORTA, 7 ; set pin low

The code above will set Port A 7 high for exactly 1us. If you wrap that into a macro it'll look much nicer ;)

yeah, dirty, but works. It's supposed to be a real delay so I don't really care about ineffectiveness of the code and see no reason to mess with interrupts for this. I'll make a label with a counter allowing me to set different delays.

Thanks for the hint! :rolleyes:

Link to comment
Share on other sites

Or another way of looking at it, this code will set Port A 7 high for exactly .1 µs.


bsf PORTA, 7 ; set pin high

bcf PORTA, 7 ; set pin low

:thumbsup:

This is not direct port setting but using SRIO, so I suppose the time will vary in my case. But knowing that NOP will take 1/10th of usec definitely helps.

Thanks again.

Link to comment
Share on other sites

Some instruction take 2 cycles (jumps for instance) be sure to consider that ;)

What exactly are you doing? The SRIO is usually updated at 1ms intervals, so I don't quite get what you're trying to do here :)

nILS,

by lacking free pins I need to employ DOUT to interface digipot chips using SPI interface, this makes 2 wires + /CS signal. The code doesn't really work as expected so I need to hook my logic analyzer to the bus. The "logic analyzer" is built from LPT port (I had trouble to find it these days :rolleyes:) and therefore .1us (or similiar) delays are not really seeable by the LPT (I only got some 800kHz sampling rate).

I'm using MIOS_DOUT_PinSet0/1 routines to set the SRIO value (so it takes definitely more time than .1us) but I still can't see the toggling signal, so I need to insert some delays in order to be able to monitor the SPI and debug further. But inserting MIOS_Delay of 1ms is too much since there are tons of bits and then the MIOS is really slow and busy spending time in delay loops. That's the point, once the code is tuned and verified I'll probably abandon the delays if the digipot chips are able to react (the CLK rate must be at least 20ns according to the datasheet so it should be no problem).

Does the 1ms SRIO mode refresh time mean that I can't really toggle DOUT pins faster than in 1ms interval?!

Edited by freddy
Link to comment
Share on other sites

by lacking free pins I need to employ DOUT to interface digipot chips using SPI interface, this makes 2 wires + /CS signal. The code doesn't really work as expected so I need to hook my logic analyzer to the bus. The "logic analyzer"

Hi Freddy.

This is what we discussed on the other thread. To be able to do this i'm afraid you are going to have to use assembler. (the sample code from the dog_g driver that I sent in the other message is a good start!)

I'm using MIOS_DOUT_PinSet0/1 routines to set the SRIO value (so it takes definitely more time than .1us) but I still can't see the toggling signal, so I need to insert some delays in order to be able to monitor the SPI and debug further. But inserting MIOS_Delay of 1ms is too much since there are tons of bits and then the MIOS is really slow and busy spending time in delay loops. That's the point, once the code is tuned and verified I'll probably abandon the delays if the digipot chips are able to react (the CLK rate must be at least 20ns according to the datasheet so it should be no problem).

Does the 1ms SRIO mode refresh time mean that I can't really toggle DOUT pins faster than in 1ms interval?!

The problem is that MIOS_DOUT_PinSet takes quite a few instructions:


	andlw	0x7f

	lfsr	FSR1, MIOS_SR_DOUT_0

	rgoto	MIOS_SRIO_Set1


MIOS_SRIO_Set1

	movwf	MIOS_PARAMETER1


	rlf	WREG, F

	swapf	WREG, W

	andlw	0x0f

	addwf	FSR1L, F


	movf	MIOS_PARAMETER1, W

	andlw	0x07

	call	MIOS_HLP_GetBitORMask

	iorwf	INDF1, F

	return

I haven't counted but this is at least 10 clock cycles on its own!

If you take a look at the dog_g driver in more detail you should see how SPI in software can be achieved.... You can also look at the sdcard driver for 2 way communication.

Thanks

phil

Edited by philetaylor
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...