|
|
View previous topic :: View next topic |
Author |
Message |
berel
Joined: 20 Oct 2011 Posts: 15
|
#use spi with slow baud rates |
Posted: Thu Jul 09, 2020 12:24 am |
|
|
Hello,
In a circuit with a PIC18F45K50 (PCH 5.093) we have several parts with SPI interface.
The communication of one part needs a clock_high = clock_low = 50 µs.
When setting it in the SM stream
Code: | #use delay(int=8MHz, clock=48MHz, USB_FULL, act=USB)
#use spi(Master, stream=EEP1, SPI1, force_sw, CLK=PIN_B1, DO=PIN_B3, DI=PIN_B0,Enable=CS_EEP1, ENABLE_ACTIVE=0, mode = 0, msb_first, bits=8, baud=200000)
#use spi(Master, stream=DAC, SPI1, force_sw, mode = 3, msb_first, bits=12, baud=200000)
#use spi(Master, stream=SM, force_sw, CLK=PIN_B1, DO=PIN_B3, DI=PIN_B0,IDLE=1, SAMPLE_RISE, lsb_first, bits=8, clock_high=50, clock_low=50)
//spi_transfer(SM, buf256, buf256, 2); // old way ?
i16 = spi_xfer(SM, j16, 16); // send one byte, device sends one back |
I found that above a value the clock pulses are much shorter than set:
clock_high = clock_low, Logic 12 MS/s
5 -> 5.3 / 5.7 µs
10 -> 10.4 / 10.6 µs
20 -> 20.3 / 20.8 µs
40 -> 19.0 / 19.0 µs
50 -> 7.75 / 7.75 µs
100 -> 7.75 / 7.75 µs Option invalid Baud too slow: CLOCK_HIGH
Does it mean that for times longer than 20 µs the spi_transfer functions can not be used,
and the SPI communication to be written with own code (done so in the past)? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Thu Jul 09, 2020 1:54 am |
|
|
Yes. What is happening, is that the counter used for the pauses is only
an 8bit counter. Though it gives a number of instruction times per 'loop',
it runs out of range from your 48MHz master clock.
There is a slight assumption that SPI is normally a fairly 'fast' interface...
The actual 'wrap' is quite interesting. If you simply use a baud figure, you
can look at the listing and work out when the wrap should happen, but it
actually seems to go wrong a while before this.
If you build for 100000baud, it is loading 0x13, at 50000baud 0x27, so
you would expect things to go wrong at perhaps 8000baud, but as you
have found it starts to give silly values well before this. I suspect the actual
arithmetic used by the compiler to calculate the divisor overflows
somewhere....
It's probably worth reporting this, since it should at the least give a
warning that this is happening, and it does actually look as the basic code
ought to be able to handle values beyond what it actually does. |
|
|
berel
Joined: 20 Oct 2011 Posts: 15
|
|
Posted: Thu Jul 09, 2020 2:24 am |
|
|
Thanks for further explanation.
It made also no difference if using the baud option or clock_high & clock_low options. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Thu Jul 09, 2020 2:42 am |
|
|
No, I suspect they internally do the same maths.
Suspicion is that it calculates the times, and then multiplies these by the
CPU clock rate. So (say) 0.000050*12000000. If this value is > 256, seems
to be about where it goes wrong. So about 20KHz. Since the count is actually
two instruction times per loop though it ought to be able to cope with
about double this time.... |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|