Post Go back to editing

ADAU1761 program load with microcontroller - SigmaStudioFW.h

Hi everybody,

I'm developing a product using ADAU1761 with an Atmega 328 microcontroller to load program and control the operation.

I have interfaced the 1761 eval board with my Arduino uno board, I can load the program with sigmastudio inside the 1761, and a small program

on the Arduino can control the operation on the board (by using I2C and writing/reading interface parameters).

Now the problem is to use the microcontroller to load the program inside the 1761.

I read the documentation, I found the pdf describing SigmaStudioFW.h file,

I wrote the (I hope) proper code inside the macros, exported the files from SigmaStudio ....

I can low compile and load the uc software that comprises the call to "default_download()" to load the program code in the DSP .

The problem is that something is wrong: the uc seems hanged, no program is loaded.

Now the questions, the documentation regarding this procedure is quite scarce. I can understand it, but something is really missing:

- should we implement ALL the macros inside the SigmaStudioFW.h file?

- the macro SIGMA_WRITE_REGISTER is used? How can we understand the SIZE of parameters?

- what is the macro SIGMA_WRITE_DELAY supposed to do? Is it a simple delay? Why are there parameters regarding the device I2C address, data and lenght?

- are the conversion functions from integer and float to 5.23 needed? The default_download() routine don't seem to use them ....

If everything compiles, if the I2C writes are OK (and they are), the program should work, is there a way to test this?

I think that a really complete example is really needed, this part is critical and we need some help.

Regards. Daniele.

  • Hi Daniele,

    I actually didn't develop this code, but I can ask these questions to the developer who did. I will let you know once I get a response.

  • Here's the response from the developer:

    Q - should we implement ALL the macros inside the SigmaStudioFW.h file?
    A: No, just the ones you need.

    Q -  the macro SIGMA_WRITE_REGISTER is used? How can we understand the SIZE of parameters?
    A: #define SIGMA_WRITE_REGISTER( devAddress, address, dataLength, data ). It is used if you’re planning to use the “default_download()” function. The signature “data” within SIGM_WRITE_REGISTER already has the size of the parameters on the array. You may want to declare it as a pointer.

    Q- what is the macro SIGMA_WRITE_DELAY supposed to do? Is it a simple delay? Why are there parameters regarding the device I2C address, data and lenght?
    A: This macro is used for applications that need to pause the data writes for a specific purpose. For example, if you need time for the PLL to be set before starting to write to the rest of the registers. It could be used as a simple delay, you’ll need to specify the device address always because some applications can require more than one DSP; the length is just the address byte length (could be 1 or 2 byte length) and data is the value in hex that represents the total time in milliseconds (that is up to the micro controller clock speed). The reason length is used, is that some DSPs work with one and some other require two address bytes.

    Q- are the conversion functions from integer and float to 5.23 needed? The default_download() routine don't seem to use them
    A: the default_download() function writes the program, current parameters, and register information. It is mainly used for programming the DSP once. You may want to use the *_PARAMS.h file if you want to modify the parameters on the fly.

    Attached is a ADAU1761 Demo.
    Writing I2C messages could be different, it is just matter of coding styles.

  • Thank you so much BrettG for your help.

    I have worked hard and solved my problem, now I can load the dsp code AND control the dsp operation with Atmega328 (Arduino UNO board).

    I want to share some of my findings, these are hard parts to work on:

    1) SigmaStudioFW.h

    It contains a lot of macros to be defined. What I found by examinating all the code is that what macros need to be defined depend on what you want to perform with your microcontroller.

    If you only need to load a DSP program with a call to default_download(), well, you only need (at least for the ADAU1761)

    to implement the two macros:

    - SIGMA_WRITE_REGISTER_BLOCK

    - SIGMA_WRITE_DELAY

    The first one is the basis of all the loading of data into program ram, parameter ram, and registers. The second one is only a delay (to be exact it serves to

    wait for the PLL to lock, in any case most of the times it can be implemented as a simple delay).

    If you want to use sequences, that is to implement some control of the dsp running with your microcontroller, you will probably need to implement the other macros. In particular if you will control volume sliders you will need to implement the conversion macros fro integer or float to the internal 5.23 representation. You can search elsewhere on the forum, I saw some of this code.

    2) Implementing program load on limited resources microcontrollers

    When you want to perform a call to default_download(), well, take a look at its code. It's a series of calls to SIGMA_WRITE_REGISTER_BLOCK,

    with different parameters. In practice in the other files generated by sigmastudio, in particular XXXXXXX_IC_1.H, there are a lot of arrays of bytes such as these:


    /* Register Default - IC 1.Sample Rate Setting */
    ADI_REG_TYPE R0_SAMPLE_RATE_SETTING_Default[REG_SAMPLE_RATE_SETTING_BYTE]  = {
    0x7F
    };

    /* Register Default - IC 1.DSP Run Register */
    ADI_REG_TYPE R1_DSP_RUN_REGISTER_Default[REG_DSP_RUN_REGISTER_BYTE] = {
    0x00
    };

    /* Register Default - IC 1.Clock Control Register */
    ADI_REG_TYPE R2_CLKCTRLREGISTER_Default[REG_CLKCTRLREGISTER_BYTE] = {
    0x01
    };

    ....

    Mostly are a few bytes, some are rather large: in particular, in my case:

    /* DSP Parameter (Coefficient) Data */
    #define PARAM_SIZE 1524
    #define PARAM_ADDR 0
    ADI_REG_TYPE Param_Data[PARAM_SIZE] = { ....

    we have 1524 bytes of parameter data, while (see below):

    /* DSP Program Data */
    #define PROGRAM_SIZE 2070
    #define PROGRAM_ADDR 2048
    ADI_REG_TYPE Program_Data[PROGRAM_SIZE]  = { ....

    my actual DSP program is 2070 bytes.

    ------------------------------------------------------------------------------------------------------------------------------------------------------

    Now the difficult part:

    SIGMA_WRITE_REGISTER_BLOCK is always used, with small and large arrays. The problem can arise when you use a microcontroller

    with very limited resources. There is a lot of difference when using, let's say, an ARM9 chip (which can have a good amount of RAM available) or an Atmega328 such as the one in the Arduino UNO board (only 2k STATIC RAM).

    The code generated by SigmaStudio is good, but quite "high level", that means targeted to a computer with enough resources to avoid bothering with limited ram issues. That's why the array definitions are generic arrays, that the compiler (unless otherwise instructed) will allocate in the normal RAM space.

    That's where I got my problems. My Arduino UNO board has 2k (= 2048 byte) RAM available. The Program_Data[PROGRAM_SIZE] array, which is 2070 bytes, simply won't fit.

    For some strange reason the IDE does not say anything while compiling. The program seems ok, but of course it does not work, and when you run it you get strange behaviour as the ram of several variably is overwritten. Unfortunately the IDE of Arduino shows no information about RAM usage, although I should have noticed it, I knew that ram is limited.

    For the Arduino UNO board there's a solution: you have to use the PROGMEM keyword to force the compiler to allocate such arrays in the PROGRAM memory (and not in static RAM). There are 32K available of program memory on the Atmega328, my program only uses less than 12K, so I have a lot of space available.

    You need to manually modify the code generated by the SigmeStudio IDE in ths way:

    /* DSP Program Data */
    #define PROGRAM_SIZE 2070
    #define PROGRAM_ADDR 2048
    ADI_REG_TYPE Program_Data[PROGRAM_SIZE] PROGMEM = {

    by adding the PROGMEM keyword you change the pace where these arrays are put by the compiler.

    Please note that:

    - you cannot incorporate the PROGMEM keyword in the typedefs of ADI_REG_TYPE that are at the beginning of SigmaStudioFW.H. For some strange

    reason the keyword is recognized by the Arduino IDE only if used AFTER the name of the array

    - you need special functions to retrieve the data from PROGMEM, you cannot use the arrays above as if they were located in normal RAM. For this there's a good explanation in the Arduino wiki, search for PROGMEM and you will find.

    After all these changes now my prototype is working. I hope to help somebody else with these findings.

    Regards. Daniele.

  • Thanks very much for sharing your findings. I think this will be very helpful to other users.

  • This question has been closed by the EZ team and is assumed answered.