Removing this constraint in the driver, gives at least 32000 speeds to choose from. I haven't tried them all, but these are my findings.
Using the Bus Pirate I have measured some low speeds
This table shows which speed was asked for, what divisor was used, the resulting theoretical speed and the measured speed.
Code: Select all
asked cdiv given measured
-----------------------------------------
4000 62500 4000 4760
5000 50000 5000 5940
6000 41667 5999 7130
7000 35715 6999 8310
8000 31250 8000 9510
9000 27778 8999 10700
10000 25000 10000 11880
80000 3125 80000 94590
100000 2500 100000 118640
This table shows which speed was asked for, the resulting theoretical speed and the measured frames per second.
Code: Select all
asked given fps
-----------------------
12 11.9 31
16 15.6 38
20 19.2 48
24 22.7 59
32 31.2 65
Techincal information
The datasheet has this to say about the CDIV (Clock Divider) field of the CLK register (page 156):
This is the codesnippet from the driver that sets the divisor.SCLK = Core Clock / CDIV
If CDIV is set to 0, the divisor is 65536. The divisor must be a power of 2. Odd numbers rounded down. The maximum SPI clock rate is of the APB clock.
From bcm2708_setup_state()
Code: Select all
bus_hz = clk_get_rate(bs->clk);
if (hz >= bus_hz) {
cdiv = 2; /* bus_hz / 2 is as fast as we can go */
} else if (hz) {
cdiv = DIV_ROUND_UP(bus_hz, hz);
/* CDIV must be a power of 2, so round up */
cdiv = roundup_pow_of_two(cdiv);
if (cdiv > 65536) {
dev_dbg(dev,
"setup: %d Hz too slow, cdiv %u; min %ld Hz\n",
hz, cdiv, bus_hz / 65536);
return -EINVAL;
} else if (cdiv == 65536) {
cdiv = 0;
} else if (cdiv == 1) {
cdiv = 2; /* 1 gets rounded down to 0; == 65536 */
}
} else {
cdiv = 0;
}
What I have done, is to remove the roundup_pow_of_two() statement.
I don't know if this has some unknown side effects, but I was hoping that someone could help test this more thoroughly.
For instance I don't have any equipment to test SPI reading.
For those that use 2013-02-09-wheezy-raspbian.img, I have made a binary (with DEBUG enabled) for download:
Code: Select all
uname -a
Linux raspberrypi 3.6.11+ #371 PREEMPT Thu Feb 7 16:31:35 GMT 2013 armv6l GNU/Linux
sudo rmmod spi_bcm2708
wget http://tronnes.org/downloads/2013-05-10-no-power-of-two-spi-bcm2708.zip
unzip 2013-05-10-no-power-of-two-spi-bcm2708.zip
dmesg -C
sudo insmod spi-bcm2708.ko
dmesg
bcm2708_spi bcm2708_spi.0: master is unqueued, this is deprecated
spi spi0.0: setup: want 500000 Hz; bus_hz=250000000 / cdiv=500 == 500000 Hz; mode 0: cs 0x00000000
spi spi0.0: setup: cd 0: 500000 Hz, bpw 8, mode 0x0 -> CS=00000000 CDIV=01f4
spi spi0.1: setup: want 500000 Hz; bus_hz=250000000 / cdiv=500 == 500000 Hz; mode 0: cs 0x00000001
spi spi0.1: setup: cd 1: 500000 Hz, bpw 8, mode 0x0 -> CS=00000001 CDIV=01f4
bcm2708_spi bcm2708_spi.0: SPI Controller at 0x20204000 (irq 80)
# I used this to test different speeds with the Bus Pirate
wget https://raw.github.com/torvalds/linux/master/Documentation/spi/spidev_test.c
gcc -o spidev_test spidev_test.c
sudo ./spidev_test -D /dev/spidev0.0 -s 80000
dmesg
spidev spi0.0: setup: want 80000 Hz; bus_hz=250000000 / cdiv=3125 == 80000 Hz; mode 0: cs 0x00000000
spidev spi0.0: setup: cd 0: 80000 Hz, bpw 8, mode 0x0 -> CS=00000000 CDIV=0c35
spidev spi0.0: setup: want 80000 Hz; bus_hz=250000000 / cdiv=3125 == 80000 Hz; mode 0: cs 0x00000000
* Datasheet: http://www.raspberrypi.org/wp-content/u ... herals.pdf
* SPI driver source: https://github.com/raspberrypi/linux/bl ... -bcm2708.c
* Bus Pirate: http://dangerousprototypes.com/docs/Bus_Pirate
* Bus Pirate Logic Analyzer mode: http://dangerousprototypes.com/docs/Logic_analyzer_mode