julyjim
Posts: 117
Joined: Tue Jan 31, 2017 5:04 am

SPI CLK divisor ?

Fri Jun 15, 2018 6:48 pm

There is a note in BCM2835 datasheet / errata about SPI clock.

Just for kicks I run this simple code

uint32_t divisor = 2;
cout << " BCM2835_CORE_CLK_HZ " << dec << +BCM2835_CORE_CLK_HZ << endl;
do {
cout << " divisor " << divisor << endl;
SPI_CLK_reg[0] = BCM2835_CORE_CLK_HZ / divisor; //BCM2835_SPI_CLOCK_DIVIDER_2; // 4096;
cout << " SPI Clock " << dec << (void*) SPI_CLK_reg[0] << endl;
cout << " SPI Clock " << dec << +SPI_CLK_reg[0] << endl;
//sleep(1);
} while ((divisor *= 2) <= 32768);
#ifdef DEBUG
cout << " SPI Clock " << dec << (void*) SPI_CLK_reg[0] << endl;
//exit(1);
#endif

only to find out that the SPI clock does not gracefully change from fast to slow - but "skips" the sequence at mid point and starts over from HIGHER value again. .

Sorry, I have not figured out how to copy the IDE output to paste it here.

PS
It seems that "core clock" is something people modify to " improve performance " , to get 100kHz SPI clock is not that predicable after this little test.

Cheers.

jamesh
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 20921
Joined: Sat Jul 30, 2011 7:41 pm

Re: SPI CLK divisor ?

Fri Jun 15, 2018 8:22 pm

Although it's been reported as a duplicate, I think this question is different enough to allow to continue.

However, we don't want a huge number of SPI threads all rather similar, so in future try and keep similar topics together.
Principal Software Engineer at Raspberry Pi (Trading) Ltd.
Please direct all questions to the forum, I do not do support via PM.

juj
Posts: 26
Joined: Sat Nov 18, 2017 10:51 pm

Re: SPI CLK divisor ?

Thu Jun 21, 2018 3:25 pm

What is the value of BCM2835_CORE_CLK_HZ in that code?

Also, what is SPI_CLK_reg[0]?

If SPI_CLK_reg[0] is memory mapped register location of the SPI0 CDIV register, then the value of that register represents the divider, and not the Hz rate. So you'd assign the value of the 'divisor' variable in SPI_CLK_reg[0] directly, and not BCM2835_CORE_CLK_HZ / divisor. The reason you are seeing surprising values reading back from SPI_CLK_reg[0] after writing is probably because of that difference, i.e. the register likely does not preserve all bits of a uint32 written to it, but only the compatible ones for the possible values of the CDIV.

To then compute what the effective SPI clock speed is, you will need to manually calculate it by querying the BCM core clock speed, and divide that by the value of the divisor you have set in the SPI0 CDIV register. To query the BCM core clock speed, you can do that either from command line, by typing 'vcgencmd measure_clock core` in terminal, or programmatically by invoking the same command as a subprocess, or by querying it via the Raspberry Pi Mailbox interface (https://github.com/raspberrypi/firmware ... -interface).

See https://github.com/juj/fbcp-ili9341/com ... 85e06e100d for code that programmatically queries the BCM core speed. (code before that used the subprocess invoke approach, code after that uses the Mailbox interface approach)

Return to “Interfacing (DSI, CSI, I2C, etc.)”