audio_controller
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
audio_controller [2025/03/20 12:30] – arisotura | audio_controller [2025/03/21 22:16] (current) – arisotura | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== Audio controller ====== | ====== Audio controller ====== | ||
- | The gamepad has a simple | + | The audio controller |
+ | |||
+ | Sample frequencies of 48 KHz and 24 KHz are supported. Supporting different frequencies would require reconfiguring the [[audio amplifier]], | ||
Register map: | Register map: | ||
Line 23: | Line 25: | ||
| 0xF000543C | Output - current odd sample (right) | | | 0xF000543C | Output - current odd sample (right) | | ||
| 0xF0005440 | counter of sorts? | | | 0xF0005440 | counter of sorts? | | ||
- | | 0xF0005444 | Input control | + | | 0xF0005444 | Input - control |
- | | 0xF0005448 | ??? | | + | | 0xF0005448 | Input - count for alert IRQ | |
- | | 0xF00054A0 | Input - buffer start address? | | + | | 0xF00054A0 | Input - buffer start address | |
- | | 0xF00054A4 | Input - buffer end address? | | + | | 0xF00054A4 | Input - buffer end address | |
- | | 0xF00054A8 | Input - current buffer | + | | 0xF00054A8 | Input - recording end address |
- | | 0xF00054B0 | ?? | | + | | 0xF00054AC | Input - recording count 1 | |
+ | | 0xF00054B0 | Input - recording count 2 | | ||
| 0xF00054B4 | Input related?? | | | 0xF00054B4 | Input related?? | | ||
- | | 0xF00054C0 | Input - IRQ flags? | | + | | 0xF00054B8 | Internal sample counters | |
- | | 0xF00054C4 | Input - IRQ enable? | | + | | 0xF00054C0 | Input - IRQ flags | |
+ | | 0xF00054C4 | Input - IRQ enable | | ||
| 0xF00054C8 | Input - IRQ ack? | | | 0xF00054C8 | Input - IRQ ack? | | ||
Line 38: | Line 42: | ||
^ IRQ ^ Desc. ^ | ^ IRQ ^ Desc. ^ | ||
| 0x17 | Audio output event | | | 0x17 | Audio output event | | ||
- | | 0x18 | Presumably audio capture | + | | 0x18 | Audio input event | |
- | | 0x1E | Periodic IRQ | | + | |
- | + | ||
- | IRQ 0x17 is used to signal certain events related to audio playback, such as start or end of playback. | + | |
- | + | ||
- | IRQ 0x1E is used by the stock firmware for certain non-audio tasks such as input polling. It seems to always trigger periodically no matter what. I measured the period to be ~5547 microseconds (~600000 cycles), no idea what this represents. | + | |
- | + | ||
- | + | ||
- | Not yet known: | + | |
- | + | ||
- | * if it is possible to play a looping sound (TODO check F0005420 bit0) | + | |
- | * how to set the sample rate (prolly directly on the amplifier) | + | |
Line 76: | Line 69: | ||
| 22 | Sample rate; 0=48KHz, 1=24KHz | | | 22 | Sample rate; 0=48KHz, 1=24KHz | | ||
| 23 | Sound format; 0=PCM16, 1=PCM8 | | | 23 | Sound format; 0=PCM16, 1=PCM8 | | ||
- | | 24 | Sample upscale | + | | 24 | Encoding |
The initial value for this register is 0x00008000. | 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? | + | <del>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?</ |
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. | 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. | + | 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' |
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. | 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. | ||
Line 101: | Line 94: | ||
Output buffer start address. | Output buffer start address. | ||
+ | |||
+ | The mask for this register is 0x0FFFFFF8. | ||
Stock firmware ensures it is aligned to a 16-byte boundary. | Stock firmware ensures it is aligned to a 16-byte boundary. | ||
Line 120: | Line 115: | ||
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. | 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. TODO: not yet known how to cleanly stop playback. | + | Writing to this register while playback is in progress has no effect. |
Line 166: | Line 161: | ||
It is simply the difference between the requested playback end address (accounting for wraparound) and the current address. | 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). | ||
Line 174: | Line 171: | ||
^ Bits ^ Desc. ^ | ^ Bits ^ Desc. ^ | ||
| 0 | Mute (0xF0005420 bit 0) | | | 0 | Mute (0xF0005420 bit 0) | | ||
- | | 1 | ??? | | + | | 1 | Mute (0xF0005420 bit 1) | |
| 2 | Playback stop | | | 2 | Playback stop | | ||
- | | 3 | Alert (0xF0005424) | | + | | 3 | Position alert (0xF0005424) | |
| 4 | Unmute (0xF0005420 bit 0) | | | 4 | Unmute (0xF0005420 bit 0) | | ||
- | | 5 | ??? | | + | | 5 | Unmute (0xF0005420 bit 1) | |
Line 190: | Line 187: | ||
Failure to properly clear these flags will result in IRQs being triggered again and again, effectively freezing the main program. | 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' | ||
+ | |||
+ | 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 // | ||
+ | |||
+ | |||
+ | **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. | ||
+ | |||
audio_controller.1742473817.txt.gz · Last modified: 2025/03/20 12:30 by arisotura