User Tools

Site Tools


audio_controller

Audio controller

The audio controller has two main components: output (playing sound to the internal speakers or headphone jack) and input (recording sound from the internal microphone). It supports PCM16 and A-law or µ-law encoded PCM8. Sound output can be mono or stereo, input is always mono.

Sample frequencies of 48 KHz and 24 KHz are supported. Supporting different frequencies would require reconfiguring the audio amplifier, which is responsible for generating the audio sample/bit clocks.

Register map:

Address Desc.
0xF0005400 Output - control register
0xF0005404 Output - ??
0xF0005408 Output - buffer start address
0xF000540C Output - buffer end address
0xF0005410 Output - playback end address
0xF0005414 Output - current playback address
0xF0005418 ????
0xF000541C ??
0xF0005420 Output - playback control of sorts
0xF0005424 Output - count for alert IRQ
0xF0005428 Output - remaining playback count
0xF000542C Output - IRQ enable
0xF0005430 Output - IRQ status
0xF0005434 Output - ?? (IRQ related)
 0xF0005438 Output - current even sample (left)
0xF000543C Output - current odd sample (right)
0xF0005440 counter of sorts?
0xF0005444 Input - control register
0xF0005448 Input - count for alert IRQ
0xF00054A0 Input - buffer start address
0xF00054A4 Input - buffer end address
0xF00054A8 Input - recording end address
0xF00054AC Input - recording count 1
0xF00054B0 Input - recording count 2
0xF00054B4 Input related??
0xF00054B8 Internal sample counters
0xF00054C0 Input - IRQ flags
0xF00054C4 Input - IRQ enable
0xF00054C8 Input - IRQ ack?

Related IRQs:

IRQ Desc.
0x17 Audio output event
0x18 Audio input event

Audio controller registers

0xF0005400

Controls low level aspects of how sound data is parsed and transmitted to the amplifier.

Bits Desc.
0 ?? Enable?
1 ???
2 ??
3 ??
4 ??
5 Channel order; 0=L/R, 1=R/L
6-10 Offset of sound data relative to sample clock
11-15 Bit width of sound data
16 ???
17 ???
18 ??
19 ?? 1=disable sound output but not always??
20 ??
21 ??
22 Sample rate; 0=48KHz, 1=24KHz
23 Sound format; 0=PCM16, 1=PCM8
24 Encoding for PCM8; 0=µ-law, 1=A-law

The initial value for this register is 0x00008000.

When bit 19 is set, no sound data is sent to the audio amplifier. It effectively functions as a mute bit, even though muting is done at the amplifier level – maybe it serves to make extra sure no sound will come out? TODO figure out what the fuck is going on with bit 19

Sound data is transmitted to the amplifier over an I2S interface. The sample clock and bit clock are generated by the amplifier, at speeds of 48 KHz and 3.08 MHz respectively.

Bits 6-10 control when a sample starts relative to the sample clock edges. The default setting is 1. This setting should match the audio amplifier's data offset setting (page 0 register 28; default setting of 0 means an offset of 1 cycle).

Bits 11-15 seem to control the bit width of samples. 0 seems to be interpreted as 32. In practice, values 16 and above act the same. The default setting is 0.

0xF0005404

Controls aspects of playback?

This register is 16 bits wide.

Setting bit 7 causes each sample to be output to both left and right channels, essentially acting as mono.

0xF0005408

Output buffer start address.

The mask for this register is 0x0FFFFFF8.

Stock firmware ensures it is aligned to a 16-byte boundary.

0xF000540C

Output buffer end address.

0xF0005410

Playback end address.

Writing to this register starts playback. This register is not updated by hardware.

This register is actually the address at which playback will end. If it is set to the beginning of the buffer, the entire buffer will be played once. If it is set to the end of the buffer, or anywhere outside of the buffer, the entire buffer will be played repeatedly.

Bits 3-27 are writable. It seems that the playback address has a resolution of 16 bytes (atleast with settings: 48KHz stereo 16bit), ie. setting bit 3 will cause the buffer to be played repeatedly.

Writing to this register while playback is in progress has no effect.

0xF0005414

Current playback address. This register is updated by hardware during playback. After playback is finished, it points back to the buffer start.

0xF0005420

Unknown.

Bits Desc.
0 Mute?
1 Mute but weird?
2 Stop playback
4 ???
8 ???

Bit 0 seems to mute sound output? but not always (ie. if F0005400 bit19 is cleared, sometimes it doesn't mute). Setting bit 0 also triggers IRQ 0 immediately. Clearing bit 0 causes IRQ 4 to be triggered as soon as sound is playing.

Bit 1 functions identically to bit 0, but a bit weird. Setting bit 1 triggers IRQ 1 immediately. Clearing bit 1 causes IRQ 5 to be triggered as soon as sound is playing.

Setting bit 2 stops playback. IRQ 2 is fired when playback is stopped, and bit 2 is automatically cleared.

Bit 4 can only be set when no sound is playing. It seems to be forced to zero when sound is playing. Not known what the effect is.

Bit 8 can be set or cleared at any time. Not known what the effect is.

0xF0005424

This register controls when IRQ 3 should fire. It can be used to trigger an interrupt at a specific point within the buffer.

It is expressed in units of 8 bytes. For example, setting it to 8 causes the IRQ to fire 64 bytes before the end of the buffer is reached.

This likely just works by comparing 0xF0005428 against this register.

(TODO word less awkwardly)

0xF0005428

Remaining amount of audio data to be played, expressed in 8-byte units.

It is simply the difference between the requested playback end address (accounting for wraparound) and the current address.

This register is not reloaded when reaching the end of the buffer and looping back to the start, which causes it to wrap around to a very large value. If one desires repeated alert IRQs, 0xF0005424 needs to be adjusted upon each alert IRQ (by subtracting the buffer size from it).

0xF000542C

IRQ enable flags.

Bits Desc.
0 Mute (0xF0005420 bit 0)
1 Mute (0xF0005420 bit 1)
2 Playback stop
3 Position alert (0xF0005424)
4 Unmute (0xF0005420 bit 0)
5 Unmute (0xF0005420 bit 1)

0xF0005430

IRQ status flags. Writing a 1 to a flag clears it.

Same format as register 0xF000542C.

IRQ status flags seem to only get set if the corresponding enable flags are set.

Failure to properly clear these flags will result in IRQs being triggered again and again, effectively freezing the main program.

0xF0005440

Sample counter of sorts.

Updated at every sample. During sound output, goes through the following sequence: 00000000, 00000002, 00000004, 00000006, 00000008, 00020008, 00040008, 00060008, 00080008, 0008000A, 0008000C, 0008000E, 00080000, 000A0000, 000C0000, 000E0000.

0xF0005444

Input control register. Controls various aspects of microphone recording.

Bits Desc.
0 Enable recording
2 ??
3 ?? must be set for recording
4 ??
5 ??
6 ?? garbage out
7 ?? garbage out
8 ??
9 ?? garbage out
12 Sample rate; 0=48KHz, 1=24KHz
13 Sound format; 0=PCM16, 1=PCM8
14 Encoding for PCM8; 0=µ-law, 1=A-law
15 ?? must be set for recording
16-20 Offset of sound data relative to sample clock
30 ?? must be set for recording
31 Reset?

Setting bit 0 starts recording microphone input into the specified input buffer.

Bits 16-20 specify when an incoming sample begins relative to the sample clock. The default setting is 1. This setting should match the audio amplifier's data offset setting (page 0 register 28). Values greater than 16 cause recording to fail.

Stock firmware sets then clears bit 31 before starting recording, this presumably acts as a reset switch?

This register likely has settings comparable to those in 0xF0005400: maybe a mono switch? And maybe low level parameters that control the I2S interface?

0xF0005448

Position for input alert IRQ. Compared against 0xF00054B0.

0xF00054A0

Input buffer start address.

Register mask is 0x01FFFFFF. The address is expressed in 16-byte units, ie. a value of 0x1234 corresponds to a memory address of 0x12340.

0xF00054A4

Input buffer end address.

Works similar to 0xF00054A0.

0xF00054A8

Recording end address. This specifies the address at which recording ends.

If this is set to the buffer start address, it is interpreted as the buffer end address.

This register is not updated by hardware.

Recording always starts at the buffer start address.

Recording always stops when reaching the end address. Not known if it's possible to do continuous recording.

0xF00054AC

Recording counter, starts at 0 and increments during recording. Expressed in 16-byte units.

0xF00054B0

Recording counter, increments during recording. Expressed in 16-byte units.

Starting value is based on the recording end address in register 0xF00054A8, ie. if 0xF00054A8 is set to 3/4 inside the buffer, this counter starts at 1/4 of the buffer length.

0xF00054B8

Internal sample counters. They may be used to determine which sample within a given 8-byte chunk is being processed. They are updated once per sample.

Bits Desc.
0-4 Input L?
8-12 Input R?
16-20 Output L?
24-28 Output R?

The counters work in a weird way. During sound output, the following sequence is observed: 00000000, 00040000, 00080000, 000C0000, 00100000, 00000000, 04000000, 08000000, 0C000000, 10000000. The input counters follow a similar pattern during recording.

Maybe the separate counters aren't L/R but more like some double FIFO mechanism for accessing memory?

Microphone input is monaural, but due to the way the I2S interface works, each sample is repeated twice.

0xF00054C0

Input IRQ flags.

Bits Desc.
0 Position alert (0xF0005448)
4 ??
8 ??

0xF00054C4

Input IRQ enable flags.

Same format as 0xF00054C0. However, a 1 bit disables the corresponding IRQ.

0xF00054C8

Input IRQ acknowledge. Upon IRQ, 0xF00054C0 is read, and the value is written to this register.

Similar to the output IRQ, failure to properly acknowledge an input IRQ will result in said IRQ firing again and again.

Headphones detection

Neither the audio controller nor the audio amplifier are aware of whether headphones are connected. The UIC is responsible for this.

The headphone status can be found in the input data buffer (returned by UIC command 0x07): power status byte, bit 5.

The stock firmware checks for when this bit changes, and reconfigures the audio amplifier as needed. (TODO: document this)

audio_controller.txt · Last modified: 2025/03/21 22:16 by arisotura

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki