Lab1BootBeepHelp


LAB1's Boot up Beep

Talking to the DAC takes a little bit of work. A good starting point is to use an example project for an Analog Device EZ-KIT which has the exact same DAC that we do (the AD1854):

C:\Program Files\Analog Devices\VisualDSP 4.0\Blackfin\EZ-KITs\ADSP-BF537\Examples\Audio codec talkthrough\C

This example sets up DMA to read from an ADC (a part we don't have) and then fires an interrupt when the dma is finished. Then in the interrupt handler it copies the data to a dma transmit buffer to send it to the DAC ( the part we are trying to talk to).

Since we don't have the audio ADC, delete the interrupt handler, the interrupt init code, DMA3 setup and SPORT0 receive setup. The init code that we need is the SPORT0 transmit, and DMA4.

SPORT0 Receive setup

You need to have internal Frame Sync and Internal Clock enabled for SPORT0 transmit. This line is in the example but commented out (setting up the SPORT0_TCR1 register). You also need to uncomment SPORT0_TCLKDIV and set it to 0x000E. and uncomment SPORT0_TFSDIV and set it to 0x001F. Also note that we set SPORT0_TCLKDIV to 0x000E because the external bus clock (SCLK) is set to 100Mhz while the FPGA is being programmed. and the data sheet for the DAC says the clock minimum is 140ns period. so 0x0E SCLKs = 140ns.

Audio Data and DMA

If you look at how the DAC is wired in the schematic and the DAC's data sheet, you will find that the DAC is expecting Two's Complement 24-bit audio samples and that the sample rate is 48khz. The DAC is also stereo and it expects interleaved data.

The DMA is configured in a mode called autobuffer. This means that the buffer will continuously be copied to the device. The DMA is setup to 32bit transfers and the SPORT transmitter is setup for 24bit transfers. So for each 32bit number the DMA gives to the sport peripheral, only the 24 low bits are sent to the DAC. ( 0x7FFFFF is the biggest 24 bit signed twos complement number and 0x800000 is the smallest).

In the example code, they setup a DMA transfer that is 2 integers wide. One is for the left channel and one for the right.

Adding a boot beep

There are a lot of strategies for doing this. One is to use the 2 integer wide DMA buffer and write a value. and then sleep and write another value. and loop doing this to generate a squarewave for a given amount of time. and then boot the fpga.

Another approach would be to use a bigger DMA buffer and generate one period of some wave form you want to hear ( sine, square, saw) and start the DMA to play the for as long as you want to hear it and then disable DMA.

References: