PeterLemon / RaspberryPi

Raspberry Pi Bare Metal Assembly Programming
447 stars 67 forks source link

Clock freqs #10

Open Klamath233 opened 7 years ago

Klamath233 commented 7 years ago

Hi Peter,

First of all, thank you for this great collection of bare metal projects. I notice that in the audio subdirectory, different files are using different clock sources, and you label their frequency in comments. However, their values are different from what's listed here http://pinout.xyz/pinout/gpclk. Are these clock frequencies configurable?

PeterLemon commented 7 years ago

Hi Klamath233,

Thanks, for trying my stuff out, I hope it helps you out =D

Yes the clock frequencies are configurable, there is a clock divisor that can get different speeds, from a chosen clock source. I got my information about the clock manager shown on page 105 to 108 of the official BCM2835-ARM-Peripherals.pdf. I do not know where that 1000MHz PLLC figure comes from in that link you showed, the official document states 650MHz, which is where I got that figure from.

Good luck with your Raspberry Pi projects.

Klamath233 commented 7 years ago

I've read the same pages, but I can only find a table demonstrating the spread effect of different MASH parameters mentions the number 650 MHz. There isn't a relation between this number and any PLL output frequency.

I've done an experiment on my Pi 3 trying to figure out the frequency of PLLC. I set GPCLK0 to get the source from PLLC and the divisor to be 1000. I then connect GPIO4(ALT0) to a logical analyzer, and the waveform shows a frequency of 1 MHz, indicating the PLLC output is actually 1000 MHz.

Could you tell me where the official document states the 650MHz so that I can research more deeply?

Thanks!

PeterLemon commented 7 years ago

Ah I think I see what might be the case, on the original oldest R-Pi, I think PLLC was 650MHz, as this was the 1:1 speed with the main CPU, as the R-Pi 2 & 3 came out with GHz speeds, this must have been raised along with the faster CPU clock speeds, & with over clocking would change too. As you have tested the timing, I reckon you are totally right about the PLLC being 1000MHz, sorry for the confusion. Also thanks for bringing this to my attention.

Klamath233 commented 7 years ago

My pleasure. I have some following-up questions.

  1. How do you come up with the numbers for the clock dividers and the PWM range registers?
  2. Are you able to get stereo output on Pi 3? I can only get output from the right channel.
Klamath233 commented 7 years ago

For point 2, I think they've moved the left channel to GPIO 41. I tried turning GPIO 41 to ALT0 instead of GPIO 45 and got output from both channel.

PeterLemon commented 7 years ago

Hi Klamath233,

Thanks for all your testing, I have re-opened this issue, until I fix the stereo output on my R-Pi3 demo, many thanks for telling me about that.

As for point 1, I just used my pc playing at the same time, to find a number that matched 44.1KHz sound output, so I just used my hearing for that. Other Hz figures were then derived from that number: e.g $2C48 = 12bit 44100Hz Mono, $1624 ; Range = 12bit 44100Hz Stereo. If you come up with a nice way to work out the exact number rates, please tell me, & I'll update my demos to use your method.

Anyway, thanks for all your help.

Klamath233 commented 7 years ago

My basic thought is a group of equations:

range = pwm_freq / sample_rate .....(1) range = 2^bit_depth .........................(2)

As an example: Say 12-bit (bit depth) 44100Hz (sample_rate): From equation 2: range = 4096 = 0x1000 Then from equation 1: pwm_freq = 44100 * 4096 = 180,633,600

Now, assume we are using 500 MHz PLLD: Divider = 500,000,000 / 180,633,600 = 2.768 Thus, IDIV = 2, FDIV = 4096 * 0.768 = 3146 = 0xC4A. Note that this 4096 is the size of FDIV field, irrelevant with the 4096 as the range in this specific case.

Also, to support fractional divider, we need to turn on 1-stage MASH in the clock control register. This bugged me all the day today.

To summary, in this case, The PWMCLKDIV register: 0x5A002C4A The PWMCLKCTL register: unchanged except for the MASH control bit need to be set to 1-stage MASH The PWM RNG1, RNG2 register: 0x00001000

I don't think mono/stereo should affect these numbers, but I need to test the mono case as well.

PeterLemon commented 7 years ago

Hi Klamath233,

Looks good to me, thanks for all your testing. Will be great to get my baremetal sound demos corrected according to your findings.

Please let me know how you get on with your tests.

Klamath233 commented 7 years ago

It goes pretty well as for 12-bit 44100Hz and 8-bit 44100Hz.

The clock numbers are irrelevant to stereo/mono; the reason you are getting twice as fast in mono is that you only write a word to the FIFO once while you have both channels enabled. This way, one word goes to the right while next word goes to the left channel. Since the two words are modulated simultaneously in different channels, the sound goes twice as fast. If we write the same word twice to the FIFO, the playback rate is back to normal.

Another question, when you set the clock source, you say CLK_SRC_OSCILLATOR + CLK_SRC_PLLCPER. I think you mean CLK_SRC_PLLDPER, right? They are equal in value: 1 + 5 = 6.

I really appreciate this demo you make because it would take me days to get this working as they move the PWM operation logic to the VC – there would be no reference for me to look at even in the Linux kernel. (And you know how poorly the documents for this board are written :/)

PeterLemon commented 7 years ago

Hi Klamath233,

Cool findings thanks for telling me. I think you must be right about it being CLK_SRC_PLLDPER, glad you are finding all this stuff out.

I made these demos specifically for people like you, took me a long time to get anything to work lol!

Thanks again for all your testing.

petemoore commented 4 years ago

@Klamath233 were you able to get the sound demos working in the end on rpi 3b? I have them working but with white noise at the end of the loop. Thanks!

petemoore commented 4 years ago

Another question, when you set the clock source, you say CLK_SRC_OSCILLATOR + CLK_SRC_PLLCPER. I think you mean CLK_SRC_PLLDPER, right? They are equal in value: 1 + 5 = 6.

To summary, in this case, The PWMCLKDIV register: 0x5A002C4A The PWMCLKCTL register: unchanged except for the MASH control bit need to be set to 1-stage MASH The PWM RNG1, RNG2 register: 0x00001000

I tried applying all of these changes on my RPi 3B here but this didn't fix things for me. The sample plays, but does not repeat, because it cuts out before any repeat occurs. Sometimes the display is updated too, but not always. I also noticed that for me, it only works without the /boot/config.txt file, which is strange, since then I probably enter at EL2 instead of EL3, and run the kernel at 0x80000 instead of 0x0.

In any case, I'm not quite sure how to fix the audio. This is the last thing I need to fix for my PiFox port to RPi 3, as everything else seems to be working now. Many thanks for any advice you can give!

I should add, I'm booting over TFTP, just in case that affects the ARM initialisation in any way, with the latest firmware.

ivancerra commented 3 years ago

Hi Peter,

I think: CM_SRC_OSCILLATOR -> INTOSC -> 19.2 Mhz, Example 44.1Khz. PWM_Range -> 19.2 MHz / 0.0441 MHz -> 435.37 => 436 => 0x1B4.

And: CM_SRC_PLLCPER -> 500Mhz

Amazing Tutorials!!! Congratulations.

PeterLemon commented 3 years ago

hi ivancerra,

Thanks =D

petemoore commented 3 years ago

I have no explanation, but the original version of Sound/PWM/12Bit/44100Hz/Stereo/DMA and Sound/PWM/12Bit/44100Hz/Stereo/CPU are both working for me now on my rpi3b, despite there being no changes to the source since I previously noticed the issue. Firmware fix? :man_shrugging:

For both of these, I notice the sound comes mostly out of my right headphone - not sure if that is a problem with the headphone socket on my rpi, or if that is a feature of the sound sample, or if this might be a bug. There does seem to be very quiet sound coming through, but i'm not sure if that is just bleeding through from the other side, or if it is intended.

UPDATE: just read https://github.com/PeterLemon/RaspberryPi/issues/10#issuecomment-260231186

@PeterLemon based on the information from @ivancerra and @Klamath233 should I expect these examples not to play correctly on a rpi3b? I really can't work out why I had the issue before, but it seems to be gone now! :-)

petemoore commented 3 years ago

I've created PR #21 for fixing the GPIO 45 -> GPIO 41 on rpi3.

ivancerra commented 3 years ago

Raspberry raw sound pwn dma, Explained https://github.com/ivancerra/RBRawSound

Thanks peter!

petemoore commented 3 years ago

Raspberry raw sound pwn dma, Explained https://github.com/ivancerra/RBRawSound

Thanks peter!

This looks great @ivancerra, many thanks!