1761 parameters loading problem
I am working with ADAU1761, interfacing it to the microcontroller by 8 MHz SPI.
According to the application I need to update the whole parameter RAM by the external command.
Sets of parameters (6) are stored on a microcontroller as arrays copied from Sigma DSP exported files.
For verification I read one byte from the DSP after parameters loading (byte is uinique to each parameters array).
I've noticed that in about 10-20% parameter ram is not loaded (byte is not verified).
Then I've started to write parameters 4 bytes at a time, verifying right after writing and retrying up to 5 times.
I saw that when parameter loading fails, it does so on the very first packet.
According to the datasheet first 8 addresses of the parameter RAM are reserved for safeload parameters,
so I've started to write parameters starting from address 8.
Situation improved significantly, but still in about 5-10% the very first word does not verify.
Seems like something else effects parameter RAM updating.
Will appreciate any help with the issue.
Gennady
Audio Signal Processors
SigmaDSP Audio Processors
adau1761
Hello,
If I understand correctly, you're attempting to write/read a single byte to/from parameter RAM. Please correct me if this is incorrect.
Please refer to the memory section of the ADAU1761 datasheet (page 47). Here is an excerpt that provides an explanation to what you are seeing:
READ/WRITE DATA FORMATS
The read/write formats of the control port are designed to be
byte oriented to allow for easy programming of common micro-
controller chips. To fit into a byte-oriented format, 0s are added
to the data fields before the MSB to extend the data-word to
eight bits. For example, 28-bit words written to the parameter
RAM are preceded by four leading 0s to equal 32 bits (four bytes);
40-bit words written to the program RAM are not preceded by
0s because they are already a full five bytes. These zero-padded
data fields are appended to a 3-byte field consisting of a 7-bit
chip address, a read/write bit, and a 16-bit RAM/register address.
The control port knows how many data bytes to expect based
on the address given in the first three bytes.
The total number of bytes for a single-location write command
can vary from one byte (for a control register write) to five bytes
(for a program RAM write). Burst mode can be used to fill
contiguous register or RAM locations. A burst mode write begins
by writing the address and data of the first RAM or register location
to be written. Rather than ending the control port transaction
(by issuing a stop command in I2C mode or by bringing the CLATCH
signal high in SPI mode after the data-word), as
would be done in a single-address write, the next data-word
can be written immediately without specifying its address. The
ADAU1761 control port autoincrements the address of each write
even across the boundaries of the different RAMs and registers.
Table 28 and Table 30 show examples of burst mode writes.
This helps as well:
PARAMETER RAM
The parameter RAM is 32 bits wide and occupies Address 0
to Address 1023. Each parameter is padded with four 0s before
the MSB to extend the 28-bit word to a full 4-byte width. The
data format of the parameter RAM is twos complement, 5.23.
This means that the coefficients can range from +16.0 (minus
1 LSB) to −16.0, with 1.0 represented by the binary word
0000 1000 0000 0000 0000 0000 0000 or by the hexadecimal
word 0x00 0x80 0x00 0x00.
The parameter RAM can be written to directly or with a safe-
load write. The direct write mode of operation is typically used
during a complete new loading of the RAM using burst mode
addressing to avoid any clicks or pops in the outputs. Note that
this mode can be used during live program execution, but because
there is no handshaking between the core and the control port,
the parameter RAM is unavailable to the DSP core during control
writes, resulting in pops and clicks in the audio stream.
SigmaStudio automatically assigns the first eight positions to
safeload parameters; therefore, project-specific parameters start
at Address 0x0008.
The parameter RAM should not be written to until the DSPEN
bit has been set in Register R61 (Address 0x40F5).
Basically, this is saying that any time you write to the chip, you need to write a complete word, or multiples of complete words.
The word length varies depending on the target address.
Control registers (with the exception of the PLL configuration register) are 1 byte words. So, to write a control register, you need to write the chip address byte, followed by the two subaddress bytes, and then 1 byte of data. Likewise, to read a control register, you need to write the chip address byte, followed by the two subaddress bytes, and then read 1 byte of data.
The parameter RAM has words that are 4 bytes long. So, to write a single address of parameter RAM, you need to write the chip address byte, followed by the two subaddress bytes, and then 4 bytes of data. If you do not write the complete 4 bytes, the write will fail. Likewise, to read from an address in parameter RAM, you need to write the chip address byte, followed by the two subaddress bytes, and then read 4 bytes of data.
If you want to write multiple parameter RAM addresses at one time (which is called a burst write) then you need to write a multiple of 4 data bytes. For example, if I wanted to write 2 contiguous parameter RAM addresses, then I write the chip address byte, 2 subaddress bytes, and then 8 bytes of data. Likewise, if I want to write 20 parameter RAM address at one time, I would write the chip address byte, 2 subaddress bytes, and then 80 bytes of data.
It sounds like you are only writing/reading a single byte, and since the parameter length is 4 bytes, then the write/read attempt will fail.
All my writes/reads to a parameter ram are 4 bytes. The data I am reading are in 28.0 format, so I read
4 bytes and take into account only the last one (the data in that byte are 0 to 7).
Also since burst mode didn't work for me (except the initial parameter loading), I've decided to write it one word at a time.
So here is how I do it:
- set address to 0x0008,
- SPI_CS low
send device address (0 in my case, so I send 0 for write)
send 2 bytes of address
send 4 bytes from my parameter array at word address 0x0008
SPI_CS high
- the same way (same device id and address) read 4 bytes from parameter ram.
If there is no match with data sent, I repeat it for up to five times with the same address and data.
- if data read match the data sent, I increment the address and send the next 4 byte
- and so on till the end of array.
In most cases it works fine, but in about 5-10% I get an error, and it's always on the very first word.
Since the data I read back at failure are 0,0,0,0 (though I know that there is data in RAM at this address -
I can verify it later), it seems like in case of failure I just don't have access to the RAM.
Hi Gennady,
I think I might understand the cause of the problem. Is the DSP running while you are attempting to do this update?
While the DSP is running, it has the ability to update its own parameters (at least, some of the algorithms have the capability of doing this). For this reason, it is a good idea to stop the DSP when you are updating the parameters.
Actually, it is always a good idea to stop the audio from going through the DSP when you do a large parameter update because filters and other audio processing algorithms can become unstable if their parameters are updated during audio processing.
So, here is the recommended write sequence.
First, set 0x40EB (Sample Rate Setting) to 0x7F. This will set the sample rate to NONE. The DSP will finish processing the current audio sample.
Wait 1 audio sample (for 48 kHz, this is 20 microseconds) to guarantee that the core finishes the current sample.
Set 0x40F6 (DSP Run Register) to 0x00. This will halt the core.
Update the parameter RAM as needed. It's OK to overwrite addresses 0x0001 through 0x0007 with zeros if you prefer.
NOTE: The setting of address 0x0000 (the NonModRamAlloc parameter) should be set as determined by SigmaStudio. The default is 0x00001000.
When you have finished updating the parameters, set 0x40EB (sample rate setting) to the desired value. For example, setting it to 0x01 will choose the 48 kHz sample rate.
Then set 0x40F6 to 0x01 to start the DSP core.
Lastly, it is a good idea to reset the dejitter register, as shown in the exported files from SigmaStudio. Write a 0x00 to address 0x4036. Then, write 0x03 to 0x4036.
Thanks,
Brett
Hi Brett,
yes! it did it.
I did reset and set the DSP Run, but didn't think about Sample Rate Setting.
Now it's 100%.
I guess I can now remove writing by single word and do it in a burst mode
(or I'll probably will leave as it is out of superstition :-) )
Thank you so much,
Gennady
Hi Brett,
BTW, in my previous Sigma design on 1442 - 22 mixers with 18 inputs each plus 18 level detectors plus other staff (you also helped me with that, thank you) - I continuously update mixers' gains and read levels on a fly, not making any precautions.
Since addresses of mixer registers are sequential, I write and read parameter data in chunks by DMA, and never saw any problems. So either 1442 behaves differently, or I just don't notice any writing problems.
And since communications occur every 10 ms, stopping DSP for update is impossible - I will just loose too many samples.
Strange.
Thank you again,
Gennady
If you need to update parameters while the DSP is running, then you definitely need to use the safeload feature.
You can find the full details on page 48 of the datasheet.
If you wanted to write a single word, then it would look like this:
Write data to address 0x0001.
Write target address (with an offset of -1) to address 0x0006
Write 0x00000001 to address 0x0007
Wait one sample
That's it!
Please log in to reply.