Need Help! Weird counter behavior at PLL16X only!
lonesock
Posts: 917
Hi, All.
I've been working on some fast SPI routines for SD card access, and I have code that works fine at RCFAST, and PLL1X through PLL8X, but bombs on PLL16X. I thought maybe I was violating the SD timing spec at the fast rates, but all the data-sheets I could get my hands looked like I was well within my timing "rights". So I boiled it down to the simplest test case I could think of...
TEST CASE:
* Set Counter A to "LOGIC A" mode, with pinCLK as my input
* Set Counter B to "NCO single ended" mode, with pinCLK as my output
* set the dira register to allow pinCLK as an output
* Have Counter B clock out 8 pulses (2 clocks high, 2 clocks low)
* Start FRQA at 1<<14
* After each clock pulse, shr frqa by 2
* This should give me 2 accumulations per clock pulse, then shift my frqa down by 2 bits
* NOTE: because "LOGIC A" mode in fact reads A1, or the pin delayed by one clock, I had to have the clock line look like 0110, instead of 0011, otherwise the clock pulse would straddle each "shr frqa".
RESULTS:
Can anyone help me understand why PLL16X would yield different results? (Note: nothing is connected to the pin)
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
lonesock
Piranha are people too.
I've been working on some fast SPI routines for SD card access, and I have code that works fine at RCFAST, and PLL1X through PLL8X, but bombs on PLL16X. I thought maybe I was violating the SD timing spec at the fast rates, but all the data-sheets I could get my hands looked like I was well within my timing "rights". So I boiled it down to the simplest test case I could think of...
TEST CASE:
* Set Counter A to "LOGIC A" mode, with pinCLK as my input
* Set Counter B to "NCO single ended" mode, with pinCLK as my output
* set the dira register to allow pinCLK as an output
* Have Counter B clock out 8 pulses (2 clocks high, 2 clocks low)
* Start FRQA at 1<<14
* After each clock pulse, shr frqa by 2
* This should give me 2 accumulations per clock pulse, then shift my frqa down by 2 bits
* NOTE: because "LOGIC A" mode in fact reads A1, or the pin delayed by one clock, I had to have the clock line look like 0110, instead of 0011, otherwise the clock pulse would straddle each "shr frqa".
RESULTS:
PLL1X - PLL8X: "Counter Feedback = 01010101010101010" (as expected) PLL16X only: "Counter Feedback = 00110101010101011" (the weirdness)
Can anyone help me understand why PLL16X would yield different results? (Note: nothing is connected to the pin)
{{ Testing a PLL16X weirdness Jonathan Dummer }} CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 pinCLK = 27 OBJ term : "FullDuplexSerial" VAR long feedback PUB StartTest ' set up my serial link to use the same pins as the programmer term.start( 31, 30, 0, 19200 ) ' I will use 2 counters to drive and monitor pinCLK ' set the clock mode to "Numerically Controlled Oscilator, Single Ended", driving pinCLK clockMode := (%00100 << 26) | (pinCLK << 0) ' set the reader mode to "LOCIG A", where A is pinCLK readerMode := (%11010 << 26) | (pinCLK << 0) ' and the mask for output? feedback := |<pinCLK ' start my test assembly cog cognew( @test_asm_entry, @feedback ) ' now do infinite status updates repeat term.str( string( "Counter Feedback = " ) ) term.bin( feedback, 17 ) term.tx( 13 ) waitcnt( (clkfreq << 1) + cnt ) DAT ORG 0 test_asm_entry ' read in the bitmask for the clock line rdlong dira,par ' set up my counters mov ctra,readerMode mov ctrb,clockMode ' clear my mask mov value,#0 test_loop ' update our main feedback variable wrlong value,par mov value,#0 ' set up my input timer, done outside mov frqa,#1 shl frqa,#14 mov phsa,#0 ' set up my clock, and start it movi phsb,#%01_0000000 ' works for 5MHz PLL1x to PLL8x movi frqb,#%01_0000000 ' keep reading in my value shr frqa,#2 shr frqa,#2 shr frqa,#2 shr frqa,#2 shr frqa,#2 shr frqa,#2 shr frqa,#2 mov frqb,#0 ' stop the clock mov value,phsa mov frqa,#0 ' start over jmp #test_loop {=== PASM Variables ===} clockMode long 0 readerMode long 0 {=== PASM scratch variables ===} value res 1 FIT 476
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
lonesock
Piranha are people too.
Comments
after all we're multiplying by 16 here. with 8x and lower, there's going to be a divider that makes the high and low time 50-50.
just a thought.
pressing on...
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
lonesock
Piranha are people too.
Thanks very much for trying it out for me,
Jonathan
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
lonesock
Piranha are people too.
The LOGIC A&B counter would end up sampling twice because the clock line is high for 2 counts out of every 4, but that is easily fixed by dividing by 2 at the end. This limits me to reading 31 bits, but I was just reading 2 16-bit words and combining for the final long. However in the 16X PLL, it seemed that the timing shifts for one of the counters (it was as if it was doing LOGIC A2&B2, instead of A1&B1).
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
lonesock
Piranha are people too.
Re: 16X PLL that certainly looks odd, I had the impression that the first bit was only added once (%01) and the last bit 3 times (%11). But even with the 20MHz clock that shouldn't be an issue.
thanks,
Jonathan
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
lonesock
Piranha are people too.
thanks,
Jonathan
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
lonesock
Piranha are people too.
Add at last 2 Tantalum Caps with voltage regs in holes betwen GND and 5V, GND and 3.3V. (22-47uF)
For correctness one more betwen GND and IN Voltage (it may be Electrolitic 100uF) but be sure it havs dual voltage spec that Yours IN Voltage to protoboard.
and test if it helps.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Nothing is impossible, there are only different degrees of difficulty.
For every stupid question there is at least one intelligent answer.
Don't guess - ask instead.
If you don't ask you won't know.
If your gonna construct something, make it·as simple as·possible yet as versatile as posible.
Sapieha
Does anyone have docs on on when counters sample a pin? (beginning of a clock, middle, end, variable, throughout?) I know about accumulation happening one clock after the sampling.
thanks,
Jonathan
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
lonesock
Piranha are people too.
Thanks so much for your help and suggestions...I got it working using kuroneko's elegant suggestion (checking the MMC spec, 25% duty cycle is still within spec at 100MHz operation...10ns high time minimum). I'm still going to try the tantalum caps, per Sapieha's recommendation, because I really want to find out why the counters' behavior changed at PLL16x, but that will probably be next week some time.
thanks again,
Jonathan
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
lonesock
Piranha are people too.
- If I keep the clock running (20MHz ctrb) rather than switching it on/off around the byte it gets rid of the top bit error (%01)
- The lower bit is still %11 but that is I believe due to the way the clock is placed in relation to when phsa is sampled. I.e. if I simply remove the stop the clock bit then it accumulates once, placing a nop gives you 2 more accumulations.
- An 8th shr frqa, #2 will resolve that problem (this won't accumulate anything but keeps the relevant bits in sync).
I did some more tests and what it boils down to is that unclean pins can delay your signal by as much as one clock cycle (in terms of getting sampled or not). I also confirmed A1 being used to trigger accumulation (not that I doubted it). Well, that leaves quite a bit of thinking on your part as to how you want to handle this issue. Keep us informed!Also, the counter application note has some basic schematics which suggests sampling with L/H clock edge (around page 15).
Post Edited (kuroneko) : 6/28/2009 4:10:25 AM GMT