Using the SPIdev, I have setup the SPI clock frequency, but measuring the real signal frequency using oscilloscope shows, it differs extremely to the expectations. How is this possible?

spi_fd = open(device, O_WRONLY);
ret = ioctl(spi_fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed_hz);


uname -a
Linux zero2 4.9.22+ #987 Fri Apr 14 23:13:48 BST 2017 armv6l GNU/Linux

lsmod | grep spi
spidev                  7034  0
spi_bcm2835             7424  0

cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq
cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq
  • 1
    I can't say I have noticed any particular problem. Which speeds have you set and what was the measured speed?
    – joan
    Apr 17, 2017 at 10:50
  • On 700MHz it's 62.5% of requested speed (625kHz for 1MHz, 1.25 MHz for 2MHz etc). On 1GHz it is 100%.
    – sharpener
    Apr 17, 2017 at 13:41
  • It may be because you are overclocking. I would sort of expect timings to be a bit iffy in that case. I tend to only use slow speeds when I'm testing and haven't seen discrepancies. When I get a chance I'll connect a logic analyser and try at a few megahertz.
    – joan
    Apr 17, 2017 at 14:11
  • The clocking setup is default, until now I wasn't aware of the fact also RPi suffers from the overclocking obsession
    – sharpener
    Apr 17, 2017 at 14:22
  • The zero looks overclocked because it runs by default at 1 Ghz. I suspect this is just the result of binning.
    – goldilocks
    Apr 17, 2017 at 15:10

1 Answer 1


There are at least following reasons for this:

  1. Considering the ioctl name, looks like the speed is only guaranteed not to be greater than the value requested.

  2. Due to some confusings in the Broadcom datasheets, the older SPI driver spi-bcm2708 calculated the clock multiplier to be power of two instead of multiply of two. So the range of possible values was strongly reduced. This should be ok in the current driver spi-bcm2835. Check the current module loaded via lsmod.

  3. Not sure why, but the SPI clock depends on the CPU clock. At least on my raspbian system, using the spi-bcm2835 driver, the real clock frequency meets the expectations on full speed only (1GHz). At the default idle speed (700MHz) the SPI clock is lower (e.g. 12.5MHz real for 20MHz request). Check/change the current CPU speed settings:

    cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor                #current policy
    echo performance > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor #max performance
    cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq    #min CPU clock frequency
    cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_cur_freq    #current CPU clock frequency
    cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq    #max CPU clock frequency


After some more research, regarding the overclocking, following parameters in /boot/config.txt affect the SPI clock. Using the values provided the real timing meets the expectations.

arm_freq_min=700   #effectively disable scaling
core_freq=200      #not sure about exact meaning, but this allows precise SPI clock setup

There is a tool able to determine either configured or real clock values of the overclocking parameters:

vcgencmd get_config arm_freq
vcgencmd get_config core_freq
vcgencmd measure_clock arm
vcgencmd measure_clock core

So the overclocked system in full performance mode (correct SPI setting) is 1000(arm)/400(core)MHz.

Nice summary for raspberry pi config options


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.