PDA

View Full Version : SHIFTOUT Clock rate



Brock
- 8th July 2006, 00:44
Is there any way to get the clock rate higher than 50kHz? Has anyone
contacted ME Labs about this? I need more speed!!! Just checking before I
change the design to use the hardware MSSP.

SteveB
- 8th July 2006, 04:41
Brock,
I am curious about this as I plan on using this feature, but have not gotten to that point in my project yet. The manual is a bit vague in it's statement "The shift clock runs at about 50KHz dependent on the oscillator". Have you tested the actual speed?

Here's why I ask. Looking at the ASM produced by PBP, the SHIFTIN/SHIFTOUT seem to control the speed of the clock using the same subroutine ("shifttoggle"). This routine adds dummy BRA calls based on the defined OSC. If I've counted correctly the "shifttoggle" routine takes 6 instructions cycles for OCS 4MHz (6us), and 24 instructions cycles for 40MHz (2.4us). There are about 14 or so additional instructions in the SHIFTOUT routine. So for 4MHz, 20 total instruction cycles (20us) would result in around 50kHz. But, at 40MHz, 38 instruction cycles (3.8us) would be about 263KHz. Which leads me to believe that at faster OSC, the actual frequency of the clock would be faster (otherwise I would have expected the routine to have 60 instruction cycles for 40MHz OSC). I may have missed something, but don't have the time to actually check it out and measure it on a scope at this time.

I'm already using the MSSP for I2C and, like you, would have to change my design to accomadate using the MSSP for SPI.

Curiously,
Steve

Brock
- 8th July 2006, 11:54
That's interesting. I will check it with a scope today. I run the circuit at 20MHz
right now and didn't want to bump it to 40MHz because it would completely
change my datalogging scheme which uses the overflow of Timer 1. But is still
easier than changing to the MSSP. I'll post results of the clock after I check it.

Brock
- 8th July 2006, 16:05
OK, at 20MHz with a PIC18F2520, the clock rate for SHIFTOUT is 5.2 us or
192 KHz. It would be nice to get this clock rate up to 500 kHz or even 1 MHz.
I'm open to ideas or suggestions.

[Edit] Just checked it at 40 MHz and the clock rate is 3.6 us or 278 kHz.

I sure would like to get a faster clock without increasing to 40 MHz.

Charles Linquis
- 8th July 2006, 17:28
An assembly-language subroutine would certainly allow for a faster SHIFTOUT.

Brock
- 8th July 2006, 18:11
It would be no small task inserting an assembly routine... I would have to insert
many routines. I also don't know assembly very well. Speaking of assembly, is
it possible to modify the PBPPIC18.LIB file (shiftout routine)?

If I could double the speed of the shiftout clock, that would do it.

SteveB
- 8th July 2006, 19:42
Speaking of assembly, is it possible to modify the PBPPIC18.LIB file (shiftout routine)?

I'm sure it is possible. If you do a Find... on the term "ifdef SHIFTTOGGLE_USED", you should be able to find the right section.

ifdef SHIFTTOGGLE_USED
LIST
shifttoggle
movf RM2, W ; Get clock bit mask
xorwf INDF1, F ; Toggle clock
ifdef SHIFT_PAUSEUS
movf R0, W ; Save shift data
movwf R1
movf R0 + 1, W
movwf R1 + 1
movlw (SHIFT_PAUSEUS) >> 8 ; Slow down transfer
movwf R0 + 1
movlw low (SHIFT_PAUSEUS)
call PAUSEUSL
movf R1, W ; Restore shift data
movwf R0
movf R1 + 1, W
movwf R0 + 1
movf RM2, W ; Get clock bit mask
PAUSEUS_USED = 1
else
nop ; Slow down transfer
if (OSC > 4)
bra $ + 2
endif
if (OSC > 8)
bra $ + 2
endif
if (OSC > 12)
bra $ + 2
endif
if (OSC > 16)
bra $ + 2
endif
if (OSC > 20)
bra $ + 2
endif
if (OSC > 25)
bra $ + 2
bra $ + 2
endif
if (OSC > 33)
bra $ + 2
bra $ + 2
endif
if (OSC > 40)
bra $ + 2
endif
endif
xorwf INDF1, F
return
NOLIST
endif
The bold text is the stuff you need to tweek. If I were doing it, I would start with the "if (OSC > XX)...endif" statement which would be just below the OSC value your using (if (OSC > 16)), comment it out (add a semi-colon), and see how it runs. Then do the same for the next "if (OSC > XX)...endif", and so on. You coud even remove the "nop ; Slow down transfer".

Don't see why it wouldn't work. But the suggestion comes with all the standard disclaimers:D.
Save a copy of the original file if you plan on doing this.
Just had to say it.

Let us know how it goes!
Steve

Brock
- 8th July 2006, 21:59
Success!!!

First, I tried deleting the whole "else" section with the delays. My circuit worked
OK, but the active pulse width was less than 400ns. Too short for me to feel
comfortable about reliability. So then I tried changing all the "2"s to "1"s in the
"else" section. I got errors when I compiled. So, I deleted the "if" statements
for the lower speed oscillators and it looks pretty good now. I still wish it was
faster, but speeding it up seems to shrink the active pulse width too much.

For reference:

No delays (removing all the "else" statements): 3.6us clock (278kHz)
No delays up to 16MHz: 4us clock (250kHz)

Here is what I have:

ifdef SHIFTTOGGLE_USED
LIST
shifttoggle
movf RM2, W ; Get clock bit mask
xorwf INDF1, F ; Toggle clock
ifdef SHIFT_PAUSEUS
movf R0, W ; Save shift data
movwf R1
movf R0 + 1, W
movwf R1 + 1
movlw (SHIFT_PAUSEUS) >> 8 ; Slow down transfer
movwf R0 + 1
movlw low (SHIFT_PAUSEUS)
call PAUSEUSL
movf R1, W ; Restore shift data
movwf R0
movf R1 + 1, W
movwf R0 + 1
movf RM2, W ; Get clock bit mask
PAUSEUS_USED = 1
else
nop ; Slow down transfer
if (OSC > 16)
bra $ + 2
endif
if (OSC > 20)
bra $ + 2
endif
if (OSC > 25)
bra $ + 2
bra $ + 2
endif
if (OSC > 33)
bra $ + 2
bra $ + 2
endif
if (OSC > 40)
bra $ + 2
endif
endif
xorwf INDF1, F
return
NOLIST
endif

SteveB
- 8th July 2006, 22:19
Success!!!

First, I tried deleting the whole "else" section with the delays

This eliminates the xorwf INDF1, F statement, so not a great idea.


So then I tried changing all the "2"s to "1"s in the "else" section. I got errors when I compiled.
Yea, the BRA $ + 2 are relative branches and it won't work properly on a PIC18F with $ + 1. The reason for this is the PC18F instructions are two bytes long, so a $+1 will branch to the middle of an instruction. $+2 branches to the next instruction. It has the simple effect of causeing a 2 instruction cycle delay with one command (in lieu of using 2 nop commands).


So, I deleted the "if" statementsfor the lower speed oscillators and it looks pretty good now. I still wish it was faster, but speeding it up seems to shrink the active pulse width too much.

This is what I was getting at. I think with a little tinkering, the active pulse could be lengthened, while keeping the inactive state short, but I can't go there now. Maybe if I get to it in the future I'll follow up in this thread (who knows when that may be!). Besides, I'd want to take a good look at the timing specs before fiddling with this too much. But it is good to know what you have confirmed already.

Steve

SteveB
- 8th July 2006, 23:25
After re-reading the code, my previous statement was incorrect:

This eliminates the xorwf INDF1, F statement, so not a great idea.

the xorwf falls just after the if..else..endif statement, otherwise when you deleted the whole else portion it would not have worked.

Brock
- 8th July 2006, 23:42
After re-reading the code, my previous statement was incorrect:

the xorwf falls just after the if..else..endif statement, otherwise when you deleted the whole else portion it would not have worked.

Yeah, I didn't delete that part.

Thanks for the help!