UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Explorer
Explorer
5,259 Views
Registered: ‎02-17-2017

How to configure the SPI clock for desired frequency and verify using spidev_test.c in zynq 7000

Dear Xilinx Community,

 

I'm trying to change the SPI clock frequency to different values( ie., static uint32_t speed = 500000; in the attched spidev_test application), Does changing the clock freq 500000 hz does it mean the zynq spi clock runs at 500 Khz ?

 

But in logic analyzer instead of 500Khz, it shows 651 khz and the next clock cycle freq it shows 643khz??,  Could you pls let me know why this erratic behavior seen in the SPI clock freq?

 

But when I change this clock freq to 250 Khz it does not seems to change to 250 khz it still shows  651khz instead of 250 khz in logic analyzer??

 

Could you please let me know why am seeing this behavior and unable to change SPI clock freq to 250 Khz or to different clock frequencies??

 

Also could you please let me know how this SPI clock freq can  be configured to different values and verified from userspace?

 

I have attached the files for your reference

 

Kindly do the needful as early as possible

Awaiting for your replies

Many Thanks in advance

0 Kudos
6 Replies
Scholar rfs613
Scholar
5,233 Views
Registered: ‎05-28-2013

Re: How to configure the SPI clock for desired frequency and verify using spidev_test.c in zynq 7000

The behaviour you are seeing is most likely due to "rounding". The SPI clock rate is derived from one of the 3 main PLL on the Zynq, followed by a several dividers. When software requests a specific clock rate, the driver will compute an appropriate clock divider. However, not all speeds can be achieved. Please refer to the Zynq TRM, chapter 25, to understand the clocking.

 

For SPI, there is a divider in the SPI controller (register name Config_reg0), which can divide by certain powers-of-two (4, 8,16, 32, 64, 128, 256). This register is modified by the SPI driver when you set the speed in spidev.c ioctl() operation.

 

The clock feeding the SPI comes from one of the 3 primary PLLs (ARM, I/O or DDR), followed by a 6-bit programmable divider. See register SPI_CLK_CTRL, and note this is shared by both SPI controllers. This register must be set manually (usually done by the FSBL, eg. using settings from Vivado).

 

0 Kudos
Explorer
Explorer
5,220 Views
Registered: ‎02-17-2017

Re: How to configure the SPI clock for desired frequency and verify using spidev_test.c in zynq 7000

Thanks for info,

 

1. Could you please provide some example Is it possible to configure  to 500 KHz & 250 Khz?,

Is 166 Mhz is the SPI ref clock freq? because I see from vivado it is 166 Mhz is this the SPI ref clock freq (IO PLL) ??

 

2.Could you please let me know which is the file path in which SPI_CLK_CTRL is being configured in linux Kernel?  what does that 0x3F means , Does this divisor selects the BAUD_RATE_DIV in SPI_Config_reg0 ??

DIVISOR 13:8 rw 0x3F Provides the divisor used to divide the source
clock to generate the required generated clock
frequency.

 

Kindly do the needful as early as possible

Awaiting for your replies

Many Thanks in advance

SPI_clk.png
0 Kudos
Scholar rfs613
Scholar
5,211 Views
Registered: ‎05-28-2013

Re: How to configure the SPI clock for desired frequency and verify using spidev_test.c in zynq 7000


srinivasan wrote:

1. Could you please provide some example Is it possible to configure  to 500 KHz & 250 Khz?,

Is 166 Mhz is the SPI ref clock freq? because I see from vivado it is 166 Mhz is this the SPI ref clock freq (IO PLL) ??


Dividing 166MHz by 500 kHz gives 332. However the SPI clock divider can only be specific values, powers of two starting from 4, and going up to maximum of 256. So you cannot quite reach value of 332. (Note that dividing 166MHz by 256 gives 648kHz, which is what you observed on your analyzer.)

 

To get 500k or 250k, you will need to change the 166MHz to something that can be divided by a power of two. For example if you change it to 125MHz, then with a divider of 256, you will be pretty close to 500kHz. (Exact divider would be 250).


srinivasan wrote:

2.Could you please let me know which is the file path in which SPI_CLK_CTRL is being configured in linux Kernel?  what does that 0x3F means , Does this divisor selects the BAUD_RATE_DIV in SPI_Config_reg0 ??

DIVISOR 13:8 rw 0x3F Provides the divisor used to divide the source
clock to generate the required generated clock frequency.


The linux kernel does not configure SPI_CLK_CTRL at all. It is handled by the FSLB (first stage boot loader) based on the settings in Vivado. The proper method is to change it in Vivado, and then regenerate the FSBL. However, as a shortcut for testing, you can also modify the divisor manually after linux has booted.

 

The value 0x3F is the default value for this divisor. This is applied to either the IOPLL, ARMPLL, or DDRPLL (controlled by bits 5:4 in the same register) to produce the SPI_reference clock. In your case according to Vivado it is operating at 166MHz, so you are probably using a divisor of 6 rather than 0x3F (assuming IOPLL is running at 1000 MHz).

 

0 Kudos
Explorer
Explorer
5,180 Views
Registered: ‎02-17-2017

Re: How to configure the SPI clock for desired frequency and verify using spidev_test.c in zynq 7000

Appreciate for your prompt responses

 

1.  Could you please let me know as a shortcut for testing, How the divisor can be modified manually after linux has booted is it using /dev/mem could you please provide some example

 

2 Could you please let me know where and how can I verify that IOPLL is running at 1000 MHz??

 

3.For 250Khz when I change the 166Mhz to 64Mhz, I see the below error, could you please let me know why am I seeing this error? as attached in the snapshot below

 

Kindly do the needful as early as possible

Awaiting for your replies

Many Many Thanks in advance

64_unable_to_configurefor250Khz.png
0 Kudos
Explorer
Explorer
5,171 Views
Registered: ‎02-17-2017

Re: How to configure the SPI clock for desired frequency and verify using spidev_test.c in zynq 7000

 

Appreciate for your prompt responses

 

1.  Could you please let me know as a shortcut for testing, How the divisor can be modified manually after linux has booted is it using /dev/mem could you please provide some example

 

2 Could you please let me know where and how can I verify that IOPLL is running at 1000 MHz??

 

3.For 250Khz when I change the 166Mhz to 64Mhz, I see the below error, could you please let me know why am I seeing this error? as attached in the snapshot below

 

4. Could you please correct my understanding if it is wrong, ie., Even though I configured in Vivado to 125Mhz (as attached in the snapshot) instead of 166Mhz, but still I'm seeing roughly around 650Khz in logic analyser, I feel that the divisor also needs to be changed to 8 instead of 6 and just by only changing in vivado to 125Mhz is not effective as am still seeing 650Khz in logic analyser

 

Could you please let me know how the divisor needs to changed once linux is booted using /dev/mem or pls let me know if there any other some other means of changing the divisor to 8 once linux is booted

 

5. Could you please let me know is that the difference/variations that am seeing between the clock cycles ie., 642,1Khz, 643.1Khz and 651.9Khz (as attched  is going to create the problem for my slave device (even though my slave device max supporting freq is 5.5Mhz)

 

Kindly do the needful as early as possible

Awaiting for your replies

Many Many Thanks in advance

64_unable_to_configurefor250Khz.png
0 Kudos
Scholar rfs613
Scholar
5,154 Views
Registered: ‎05-28-2013

Re: How to configure the SPI clock for desired frequency and verify using spidev_test.c in zynq 7000

Some quick replies to your questions:

 

  1. The SPI_CLK_CTRL register is located at physical address 0xF8000158 (this comes from the Zynq TRM manual, Appendix B. You can use the "devmem" program to read/modify this register temporarily:
    # Read the current value
    devmem 0xF8000158
    0x00003F00
    
    # As you can see, the divisor in bits[13:8] is at its default value of 0x3F.
    # To change it, you can again use devmem:
    devmen 0xF8000158 32 0x00000500
    
    Note that changing the clock while the SPI device is operating may cause problems.
    The proper way to to this is to change the clock while SPI is in reset.
  2. All the clock rates can be checked in Vivado, under Processor/Memory (it is almost visible in your screenshot).
  3. Please see section 17.4.2 of the Zynq TRM. There is a restriction that SPI_Ref_Clock must always be higher than CPU_1x clock frequency. So you cannot use 64MHz as it is less than your CPU_1X clock.
  4. I suspect you did not rebuild the FSBL/uboot and deploy it to the target. After changing Vivido settings, it is necessary to export the project for SDK, and the rebuild FSBL/uboot in the SDK (will use the updated clock divisor settings). The copy the new FSBL/uboot to the hardware.
    As show in 1. above you can temporarily change the divider using devmem.
    This could also be done from uboot using the "mm" command.
  5. I am not certain where those numbers are coming from, sorry. I suspect some clock setting / divisor is being changed. However it could also be a measurement error.
0 Kudos