DM0 and DM1 after reset in ADAU1450
Hi all,
A while ago, I posted a question about the state of the RAM registers in the ADAU1450 after reset: DM0 and DM1 RAM content after RESET ADAU1450
Dave responded that RAM is initialized just before the core starts running. That's what I found later also in the datasheet (i overlooked it at first...). But I don't think that both are correct.
I use a microcontroller to program the ADAU1450 via an I2C bus. I use the output xml file, generated by SigmaStudio and write all registers mentioned in that xml file. But for DM0 and DM1 I do it a little different. Because I use a lot of RAM for delay, that registers are all filled with zero's. And, according to the answers I got, I do not need to write zero's, so I skipped doing that when programming the DSP.
But after releasing the hibernate state, the DSP is giving strange signals :-) So, to test my theory, I wrote all zero's to DM0 and DM1 in the range SigmaStudio wrote in the xml outputfile and then I write the non zero values. With that sequence, the DSP is working fine.... So my conclusion is that RAM isn't initialized, or at least not at the time I expect.
Maybe someone can shine some light here? That would be appreciated :-) My program is running fine now, but I could speed up the bootprocess when omitting writing the zero's to DM0 and DM1 at startup (I2C isn't very fast...). OK, I could switch to SPI, but that isn't an option, I use more I2C chips :-)
Addition: I found the following in the datasheet under paragraph "
POWER SUPPLIES, VOLTAGE REGULATOR, AND HARDWARE RESET"
"Hardware Reset
An active low hardware reset pin (RESET) is available for externally triggering a reset of the device. When this pin is tied to ground, all functional blocks in the device are disabled, and the current consumption decreases dramatically. The amount of current drawn depends on the leakage current of the silicon, which depends greatly on the ambient temperature and the properties of the die. When the RESET pin is connected to IOVDD, all control registers are reset to their power-on default values.
The state of the RAM is not guaranteed to be cleared after a reset, so the memory must be manually cleared by the DSP program. The default program generated by SigmaStudio includes code that automatically clears the memory."
Hmm, I was sure I read somewhere else in the same datasheet that RAM is cleared, but I can't find it anymore... So maybe I have to clear the RAM registers myself...
Thanks again for all your input
With kind regards,
Reini
Audio Signal Processors
adau1450
SigmaDSP Audio Processors
Hi Reini:
I would have to double check but there is a chance that only DMO or DM1 are initialized before the program starts running.
Are you simply hibernating the DSP or restarting it to run it. This might also point to the problem.
Please comment.
Miguel
Hi Miguel,
The dsp is coming from hard reset, but during startup, the core is placed in hibernation mode. I also found that I mixed two datasheets, the one of adau1701 and the one of adau1450 ...
Thank you for your input!
with kind regards,
Reini
All of the DSP's memories are uninitialized after power-up. Buffers are zero-filled by the DSP program generated by SigmaStudio when it starts. Parameters are not, and have to be explicitly initialized during programming even if they are zero.
Another thing I noticed is that reading uninitialized memory (or a memory location that's immediately followed by uninitialized memory) via SPI/I²C has a high probability of triggering a spurious parity error in the panic manager. For that reason I prefer to fill all memories completely during programming (but I use SPI, which is much faster than I²C).
If you want to save programming time, after setting up the PLL upload and run this little program to zero-fill DM0 and DM1:
00000002
0880dcdc
c0002830
8000xxxx
0c30dcdc
01000008
064c0000
064c5040
00000005
00000000
00000000
02010008
00000000
00000000
where xxxx in the fourth word should be the number of words per DM divided by 4, i.e. 0400 for the ADAU1450, 0800 for the ADAU1451, and 1400 for the ADAU1452. This program zero-fills memory at a rate of 4 words per core clock cycle and then halts. You can then upload your actual program without having to write zeros in DM0/DM1.
Reini wrote:
I have one question though: your program should run after pll is setup, can you help me a bit indicating where to run your program in the execution flow, output from SigmaStudio? I follow the xml file, generated by SigmaStudio and think, the RAM clearing code should be programmed before the node <Program Data> in the xml output file.
Correct.
But do I have to set the START_CORE, KILL_CORE and HIBERNATE registers?
After writing the program data and making sure START_ADDRESS is initialized to zero, a rising edge (0 → 1 transition) on START_CORE is needed to start the program. There should be no need to set KILL_CORE to zero since it's edge-triggered (but no harm in doing so either). The program doesn't use interrupts so the START_PULSE and HIBERNATE registers are irrelevant to it.
Once the program is done filling memory (which takes about 8192 words / 4 words/cycle / 147 MHz = 14 microseconds) it will terminate itself, hence there should be no need to kill it afterwards using a rising edge on KILL_CORE (but no harm in doing so either). Then continue with the rest of the programming.
Where did you find the information to generate your code?
Magic :-)
Unfortunately there's no public documentation on the Sigma300 instruction set.
Matthijs
Note btw that no delay should be needed after starting the program, since it completes in less time than it takes to transfer even a single byte of data via I²C at 400 kHz.
Hello Matthijs,
This is a very nice solution for me. We use lots of ram just for delay and these locations are initially always zero.
I have one question though: your program should run after pll is setup, can you help me a bit indicating where to run your program in the executionflow, output from SigmaStudio? I follow the xml file, generated by SigmaStudio and think, the RAM clearing code should be programmed before the node <Program Data> in the xml output file. But do I have to set the START_CORE, KILL_CORE and HIBERNATE registers? In the xml file, these are set after writing Program and RAM data:
<Program>
<Name>Program Data</Name>
<Address>49152</Address>
<Size>4384</Size>
<Data>0x00, 0x00, 0x00, 0x02 </Data>
</Program>
<Register>
<Name>DM0 Data</Name>
<Address>0</Address>
<Size>9620</Size>
<Data>0x00, 0x00, 0x00, 0x00 </Data>
</Register>
<Register>
<Name>DM1 Data</Name>
<Address>24576</Address>
<Size>15760</Size>
<Data>0x00, 0x00, 0x00, 0x00 </Data>
</Register>
<Register>
<Name>IC 1.KILL_CORE</Name>
<Address>62467</Address>
<Size>2</Size>
<Data>0x00, 0x00, </Data>
</Register>
<Register>
<Name>IC 1.START_ADDRESS</Name>
<Address>62468</Address>
<Size>2</Size>
<Data>0x00, 0x00, </Data>
</Register>
<Register>
<Name>IC 1.START_PULSE</Name>
<Address>62465</Address>
<Size>2</Size>
<Data>0x00, 0x02, </Data>
</Register>
<Register>
<Name>IC 1.START_CORE</Name>
<Address>62466</Address>
<Size>2</Size>
<Data>0x00, 0x00, </Data>
</Register>
<Register>
<Name>IC 1.START_CORE</Name>
<Address>62466</Address>
<Size>2</Size>
<Data>0x00, 0x01, </Data>
</Register>
<Register>
<Name>IC 1.Start Delay</Name>
<Address>0</Address>
<Size>2</Size>
<Data>0x00, 0x01, </Data>
</Register>
<Register>
<Name>IC 1.HIBERNATE</Name>
<Address>62464</Address>
<Size>2</Size>
<Data>0x00, 0x00, </Data>
</Register>
Am I right, to write your code when programming reaches the <Program/> node and then setting the START_CORE register to "1", the HIBERNATE register to "0", waiting is few millisecs to let the clear-code execute, stop the core again, setting HIBERNATE to "1" and resume "normal" programming with the xml code I inserted above?
Where did you find the information to generate your code? Is it from a book? If I can find it myself, I won't have to bother you guys :-)
Thank you very much for your input!
With kind regards,
Reini
Hey Matthijs,
Thanks again :-) It's very clear and I will give it a try. This will save me quite a bit of time starting the DSP
Kind regards,
Reini
I noticed :-)
If you read the datasheet carefully
... then it says literally "This register is edge triggered", so if this is not true then it's not merely a matter of unclear wording, but it's plain wrong. Good to know though, thanks for mentioning this.
Hello,
Great discussion.
I want to add one small detail. I recently identified a small detail in the datasheet that will be changed soon. The Kill_Core command is not edge triggered. When it is high the core will be killed. So you must set it low to restart the core. If you read the datasheet carefully it says that the core will be killed on the transition from low to high. The distinction was between the Hibernate command that will take a short time before the core stops executing instructions where the Kill_Core will immediately kill the core. That is why it said on the low to high transition it will stop the core. I have changed that in the next revision of the datasheet.
Hibernate simply stops the interrupts so that execution will stop after the current frame or after the current block if there is block processing in the program.
Dave T.
Hello Matthijs,
We use your clearing DM0/DM1 option for over 4 years now :-) Recently I updated the DSP application, concerning the delay components (the compiler gave a warning that new components were available). In the new delay components, we can now also select PM (program data memory) to store the delayed samples.
Is it possible to clear a part (or all) of the program memory too? Or is that done automatically? I did see that there are new compiler options that could clear unused memory, but do they also clear program data?
With kind regards,
Reini
I haven't used SigmaStudio in a while, so I can't tell you what those compiler options do. My suggestion would be to just test them.
Should it be needed, here's a variant of my program that also clears PM (except for the program itself obviously):
00000002
0880dcdc
c0002830
8000xxxx
c0002870
8000yyyy
c00028b0
80000018
00f7d112
0c30dcdc
0100000d
064c0000
064c5040
0000c062
01010011
06446020
00000000
00000005
00000000
00000000
02010011
00000000
00000000
00000000
where xxxx in the fourth word is the number of words per DM divided by 4 (same as before, e.g. 0400 for the ADAU1450) and yyyy in the sixth word is the number of words in PM divided by 2 (e.g. 1000 for the ADAU1450). Total execution time is 1 cycle per 4 words of each DM and 2 cycles per 2 words of PM, i.e. 2*x+2*y cycles.
Thanks again Matthijs for your quick response! I will try this and will report here :-)
We use both the ADAU1450 and ADAU1452, they all have 8kWords Program Memory, so per 2 words yyyy should be 8192/2 = 4096 = 0x1000
With kind regards,
Reini
Hello matthijs,
Yes, it is plain wrong. But what I was referring to is the general idea that was trying to be portrayed and I also looked at the internal documentation that this came from and there it did not say it was edge triggered but was miss-interpreted to mean that.
The example start up instructions therefore do not mention this so I added it to those procedures.
There will be a new datasheet out in probably around a month or so.
Dave T
The last 3 words of my program can be omitted btw, I was just being needlessly conservative there.
Thank you matthijs and DaveThib for your thoughts :-) They are very helpful and I learn every day about the adau1450 DSP
With kind regards, Reini
Hello matthijs and hello DaveThib,
I implemented Matthijs' small code to clear the DM) and DM1 RAM banks. It didn't work at once :-) but I found that the core indeed has to be un-killed as Dave mentioned. In chronological order I send the following commands, just before I upload the real DSP program:
- upload the 'Matthijs' clearing program (56 bytes) (starting at address 0xC000)
- set start addres to zero (0xF404 = 0x0000)
- un-kill the core (0xF403 = 0x0000)
- set Start-core register to zero (0xF402 = 0x0000)
- trigger start by setting Start-core register to one (0xF402 = 0x0001)
I²C transmission byte takes (9 bits/400kHz) = 22.5us, so well above execution time of clear RAM program, therefore, I do not have to implement any delay here, before killing the core again.
- kill the core again (0xF403 = 0x0001)
- resume uploading 'real' DSP application ...
Thank you both for your help!
With kind regards,
Reini
PS. matthijs, I also found, that if I omit the last three words from your program, the DSP behaves erratic also. Only with all the words uploaded, it works fine :-)
PPS. Sorry, my mistake. I forgot to adjust the length of the program upload. If I omit the last three words and upload 44 program bytes, it runs ok !
Please log in to reply.