ΣSigmaStudio Ask AI Русский Log in

ADAU145x SAFELOAD word using SPI

SigmaDSP & SigmaStudio dbnsExpert Nov 16, 2016 00:00 3 replies Original on forum ↗
Subscribe
dbnsExpert Question
Nov 16, 2016 00:00

Hello everybody,

About safeload registers:

They are 32 bits registers. So, if i using SPI to load 4 bytes (1 byte at a time), the increment will occur only when the 32bit is reached?

The number of bytes to send are in bytes or words (sigma studio show it in bytes)?

Compiler can put the safeload registers in DM0 or DM1. When i write to one of the (DM0 or DM1) should i consider their address ? Or just safeload address?

Because DM0 and DM1 have their own address. Like the print below:

DaveThib Reply
Nov 17, 2016 00:00

Hello,

The memory is organized into words. So the addresses are in words not bytes. The words are 32 bits.

So when you transmit 4 bytes the address will not change. Then the address will increment automatically when you start clocking four more bytes.

Dave T

matthijs Reply
Nov 21, 2016 00:00

About safeload registers:

They are 32 bits registers. So, if i using SPI to load 4 bytes (1 byte at a time), the increment will occur only when the 32bit is reached?

Yes. All of DM0 and DM1 is only 32-bit addressable, and you read and write it in 32-bit units. If the API you use for spi transfers only supports 8-bit transfers then obviously you will read/write 4 bytes (big-endian) per word of DM0/DM1 accessed.

Compiler can put the safeload registers in DM0 or DM1.

Correct, the safeload mechanism doesn't use dedicated registers but 7 words of memory. In the latest version of SigmaStudio it is always placed at the start of DM1, while the location varied in previous versions. This memory is used by a bit of code run on the DSP at the start of each frame, which is basically equivalent to something like this:

extern int DM0[0x5000];
extern int DM1[0x5000];

struct SafeLoad {
int data[5];
int address;
int length;
};

extern struct SafeLoad safeload;

void do_safeload()
{
int len = safeload.length;
int addr = safeload.address;
int *data = safeload.data;
if( len <= 0 )
return;
if( addr >= 0x6000 ) {
addr -= 0x6000;
do DM1[ addr++ ] = *data++;
while( --len );
} else {
do DM0[ addr++ ] = *data++;
while( --len );
}
safeload.length = 0;
}
(except probably not written in C)

To perform a safeload you simply write to the SafeLoad structure in memory (making sure to write the length-field last) and then wait until the safeload.length word becomes zero again, which indicates the safeload has been performed. Instead of explicitly checking for completion you can also just use a delay of 1 frame (21 μs @ 48 kHz).

So, for example if you want to disable a biquad filter by resetting its coefficients, located at 0x420 in DM0, and the safeload structure is located at 0x0 in DM1 then the SPI transfer would be:

00 perform write
6000 to &DM1[ 0x0 ] = &safeload
00000000 safeload.data[0] = coeff B2 = 0.0
00000000 safeload.data[1] = coeff B1 = 0.0
01000000 safeload.data[2] = coeff B0 = 1.0
00000000 safeload.data[3] = coeff A2 = 0.0
00000000 safeload.data[4] = coeff A1 = 0.0
00000420 safeload.address = &DM0[ 0x420 ]
00000005 safeload.length = 5 words
If you want to write less than 5 words then you can either use dummy values for the unneeded data elements of the safeload, or use two separate SPI writes. For example to write zero to address 0x1234 in DM1 you could use this pair of transfers:

00 perform write
6000 to &DM1[ 0x0 ] = &safeload
00000000 safeload.data[0] = 0.0

00 perform write
6005 to &DM1[ 0x5 ] = &safeload.address
00007234 safeload.address = &DM1[ 0x1234 ]
00000001 safeload.length = 1 word
Of course using safeload for a single word is completely pointless, you can just write it directly:

00 perform write
7234 to &DM1[ 0x1234 ]
00000000 = 0.0

DaveThib Reply
Feb 9, 2017 00:00

matthijs wrote:

Correct, the safeload mechanism doesn't use dedicated registers but 7 words of memory. In the latest version of SigmaStudio it is always placed at the start of DM1, while the location varied in previous versions.

We actually made this new feature of a fixed Safeload location backwards compatible. If you compile an older project it will still place the safeload in a location that is variable. The reason for this is because some people may be updating an older project with new parameters for EQ settings, volume, etc., and not changing the schematic at all. They then compile it and the safeload location would be in the same location as it was using the old revision of SigmaStudio. They will not have to change their uC code at all. Of course, if they make a change in the wiring of the schematic then it may move the location. If we did not do this then EVERY older project would not compile the same even though nothing in the schematic was changed. This would make for problems with some customers because it is difficult to change their controller code and sometimes the code is certified and making changes would require re-certification.

Should you want to take an old project and use it as a basis for a new project and would like to take advantage of the new fixed safeload location, then you need to do a bit of work. You need to drop into the project a new IC. The same DSP of course. Then switch all the schematic elements over to this new IC. Then delete the old original IC and that will change the hidden variable that tells SigmaStudio that this is an older design.

matthijs wrote:

To perform a safeload you simply write to the SafeLoad structure in memory (making sure to write the length-field last) and then wait until the safeload.length word becomes zero again, which indicates the safeload has been performed. Instead of explicitly checking for completion you can also just use a delay of 1 frame (21 μs @ 48 kHz).

A small Clarification on this. The Safeload request will most likely happen somewhere in the middle of a frame. Most likely it will not be able to be performed during that current frame but will be done during the next frame. Waiting one frame will probably work most of the time but to be safe I would wait two frames.

Dave T