audio_doc 6.36 KB
AI CONTROLLER PROGRAMMING INTERFACE


Operation:
################################################################################

On reset, the audio output register is cleared to zero to avoid a pop. 
Internal state is also cleared to zero on reset to effectivly disable
audio on power up.  (dac_rate, bit_rate, dma address, dma length are all reset)
External audio clock is held at zero, and audio word select is held at 1 (left
channel) after reset.

Once the dac rate and bit rate are  is programmed,
the internal state machines kick off and the 32 bit current audio output is
repeatedly cycled out to the dac. This value will be zero after reset.

To enable the internal dma engine, the dma enable bit must be set in the
audio control register. Clearing dma enable during processing will stop
all dma requests. Audio output is not disrupted and the current output
sample will by repeatedly output.
Through this mechanism, the audio can be forced to quit requesting dma
transactions.

Audio DMA's are requested by writing the dma address, and dma length
registers to point the dma engine at audio samples. These double buffered
registers allow 2 samples to be requested. 
The status register provides a FULL bit indicating both buffers are
currently occupied. The audio interrupt also serves to indicate to the
cpu a that a buffer has freed.
The audio dma's are broken up into a series of 8byte memory read
requests.

The audio interrupt is generated when the length register  is decremented to
zero indicating the last 8 bytes of a requested dma are being fetched.
At this point, sw may issue the next dma request.

Soft Reset
Setting the bit_rate to zero will perform an internal soft reset.
Audio ouptut clocks will stop and audio output data will be zero.
The active length reg will also be set to zero which will 
flush any queued up audio dma's from occuring.


The basic flow loop is

  initialize audio timing registers
	AI_CONTROL_REG 
	AI_DACRATE_REG 
	AI_BITRATE_REG 

  write address to AI_DRAM_ADDR_REG
  write length to AI_LEN_REG
  loop_forever {
    write address
    write length
    while (bit_31_of_status == 1) wait;
    (or when not interrupted by ai wait)
  }

note: the address must be written before the length

Register Details:
################################################################################

The ai controller has 5 writeable registers and 2 readable registers as
follows:

AI_DRAM_ADDR_REG 0x0450_0000     dram address (write)
                [23:0]  starting RDRAM address

  write only DMA byte address.
  All DMA requests will be 8-byte aligned  (3 lsbs = 0)
  This register is double buffered

AI_LEN_REG 0x0450_0004     length (read/write)
                [14:0]  RCP1.0 transfer length
		[17:0]  RCP2.0
  read/write DMA length in bytes.
  All DMA buffers must be multiples of 8 bytes in length.
  3 lsb's = 0
  This register is double buffered, the Active register is the readable one.

  This length register is decremented with each dma transaction. The
  value returned on a read is the number of dma bytes remaining in the
  current dma transaction.

  If bit_rate register == 0, length register is cleared to zero

AI_CONTROL_REG 0x0450_0008     DMA enable (write only)
                [0]     dma_enable
  If the LSB == 1 then DMA is enabled.
  This register is set to zero on reset.
  The DMA engine can be shut-down by clearing dma_enable
  irregardless of current length.

AI_STATUS_REG 0x0450_000c     status (read/write-clear)
    (write)        []      clear interrupt
        any write to the status register will clear the audio interrupt.

    (read)
	read status word
	* sw useful bits

	*31    FULL length2_loaded_flag,
	*30    BUSY  !length_zero,
	29    0
	28    0
	27    dma_busy,
	26    dma_request,
	25    dma_enable,
	24    1'b1
	23    dfifo2_loaded_flag,
	22    data_available_flag,
	21    word_select,
	20    1'b1,
	19    abus_word_2,
	18    0
	17    0
	16    state[0]  = bit clock
	15    0
	14    dac_cntr[13]
	13    dac_cntr[12]
	12    dac_cntr[11]
	11    dac_cntr[10]
	10    dac_cntr[09]
	 9    dac_cntr[08]
 	 8    dac_cntr[07]
 	 7    dac_cntr[06]
	 6    dac_cntr[05]
	 5    dac_cntr[04]
	 4    dac_cntr[03]
	 3    dac_cntr[02]
	 2    dac_cntr[01]
	 1    dac_cntr[00]
	 0    FULL length2_loaded_flag


AI_DACRATE_REG 0x0450_0010     audio dac period (write)
                [13:0]  vclk_divider_minus_1

  DAC sample period register
  vid_clock/(dperiod + 1) is the DAC sample rate
  (dperiod + 1) >= 66 * (aclockhp + 1) must be true
  This register is cleared on reset.

AI_BITRATE_REG 0x0450_0014     audio dac bit clock half period (write)
                [3:0]   vclk_divider_minus_1
  abus clock half period register (aclockhp)
  
  vid_clock/(2 * (aclockhp + 1)) is the DAC clock rate
  The abus clock stops if aclockhp is zero.
  The DMA length register is cleared if aclockhp is zero.
  The dac_cntr is cleared if the bit_rate is zero.
  This register is cleared on reset.



################################################################################
Audio Frequency Programming/Error 2/23/95

video_clk   audio    ratio	divider   error

48681810    44100  1103.895918  1104     94  ppm
49656530    44100  1125.998413  1126      1  ppm
48681810    32000  1521.306562  1522    456  ppm
49656530    32000  1551.766562  1552    150  ppm



	#include "rcp.h"

	...

	/* Init VI to get video clock signal into AI */
	dgWriteWord(VI_STATUS_REG, 0);

	/* To get ~44.1 KHz for audio (based on Rambus clock of 243.37 MHz
	 * and video clock of 48.67 MHz), AI dac rate = 1103 (0x44f) and
	 * AI bit rate = 15 (0xf)
	 */
	dgWriteWord(AI_DACRATE_REG, 0x44f);
	dgWriteWord(AI_BITRATE_REG, 0xf);
	dgWriteWord(AI_CONTROL_REG, AI_CONTROL_DMA_ON);


################################################################################

Notes on Testing

> if i want to beat up the length register,
> can i write length, read length, write length , read length ....
> without screwing up a state machine? assume i have not set dma enable.

1st, if the bit_rate register is zero, then the length register is
reset to zero.  So first you need to set the bit_rate reg != 0.

2nd problem is that the length register is double buffered.
you normally never see the second length until the first one counts down
to zero.

what you can do is to set the bit_rate reg to zero and back to non-zero
between write/reads to the length register to flush the dbl buffer.




################################################################################