After looking at the Hackaday Belgrade 2018 badge‘s onboard RGB LED, I moved on to looking over the audio subsystem to see how it accomplished its three-voice audio functionality. My first guess was that music playback was handled by a peripheral of some sort. On the board schematic I saw that the speaker was connected to a chip labelled LM4890 so it seemed like an obvious candidate for audio peripheral. However, after downloading and reading the datasheet for LM4890, I learned the chip only functions as an amplifier to take a low-powered audio waveform (via pins labeled
-IN) as input and push that same waveform out at a speaker-appropriate level of power. So yes, it is a dedicated audio peripheral, but not a tone or music generator.
So where’s the music coming from? I see on the schematic capacitors and resistors but nothing else that would generate sound waves, except maybe what’s connected to the PIC32’s pins
D3. Perhaps the PIC32 has a built-in music peripheral?
Looking in the code, I started tracing from the BASIC side with the
tune statement, handled by
tune_statement in ubasic.c. It calls
sound_play_notes in hw.c. A few more straightforward C call tracing ended at
sound_set_generator which flips some hardware control bits and puts the desired frequency in a hardware register. What are the results of these actions?
Searching on the specific keywords in
set_sound_generator didn’t get me anywhere immediately. Reading the code more carefully led to a key insight: for sound generator 0, it deals with the number 2. For generator 1, number 3, and for generator 2, number 4. After running around in circles for a bit, I figured out these are PIC32 hardware timer peripherals. These bits control PIC hardware timers 2, 3, and 4 whose actions are handled by
Timer4Handler in hw.c. Every time the timer interrupt fires, the handler inverts a pin named
GEN_2_PIN defined to be
LATDbits.LATD1 which matches up with the PIC32 pins on the schematic.
So it’s not a music peripheral like I originally guessed. They are three of the PIC32’s generic timer peripherals, each used to toggle a pin on and off at a set frequency. These three timers are responsible for the three voices, whose waveforms are merged and sent into a LM4890 chip (lower center of picture below) to drive the speaker (center of picture).