Post Go back to editing

Split write register data

Category: Software
Product Number: ADAU1761

Hello,

I'm trying to a split a write operation to a specific register that is suppose to receive 4880 bytes in multiple write operations of 256 bytes, and the DSP does not work properly after me doing so. I checked the I2C bus with a digital analyzer, and everything seems to be written in the propper address with the corresponding bytes.

PROGRAM_ADDR_IC_1 = 2048
PROGRAM_SIZE_IC_1 = 4880
Is it possible to write data to a register this way, or all of its content needs to be sent in a single write operation?
  • Hello Thiago,

    If the register addresses are contiguous then you can do a burst write. Let's say if you want to write some 50 words in a contiguous memory location starting from address 0, then you can do a burst write by providing chip address and sub address just once, then the autoincrement feature will increment the sub address based on the data word.

    If you are splitting the data into multiple chunks (each chunk to be stored at some random starting addresses) and let's, say each chunk will have some 50 words to be stored in a contiguous memory, then you have to supply the chip address and sub address for every chunk. You can do a burst write for a single chunk (storing 50 words in a contiguous memory).

    If you want to write multiple single writes at random addresses, then you have to provide the chip address and sub address for every write.

    The burst write will only work if you want to write a bunch of data to a continuous memory location.

    From where you are writing this data? from a uC?

    So, if you are already doing all this correctly then please attach your code, so that we can have a look.

    Regards,

    Harish

  • Hey Harish,

    Thanks for the reply. I am sending the buffer from a microcontroller to the DSP thru I2C using DMA. The code I'm using to implement the burst write is the following.

    #define BLOCK_SIZE 256
    
    #define SIGMA_WRITE_REGISTER_BLOCK_256(devAddress, address, length, pData) \
    
        do { \
    
            uint32_t num_full_blocks = (length) / BLOCK_SIZE; \
    
            uint32_t remaining_bytes = (length) % BLOCK_SIZE; \
    
            for (uint32_t i = 0; i < num_full_blocks; i++) { \
    
                hal_i2c_ext_write_with_u16_addr(s_i2c_inst, \
    
                                                (address) + (i * BLOCK_SIZE), \
    
                                                &((uint8_t *)(pData))[i * BLOCK_SIZE], \
    
                                                BLOCK_SIZE); \
    
            } \
    
            if (remaining_bytes > 0) { \
    
                hal_i2c_ext_write_with_u16_addr(s_i2c_inst, \
    
                                                (address) + (num_full_blocks * BLOCK_SIZE), \
    
                                                &((uint8_t *)(pData))[num_full_blocks * BLOCK_SIZE], \
    
                                                remaining_bytes); \
    
            } \
    
        } while (0)

    With the digital analyzer, it was possible to see the provided memory address being incremented according to the BLOCK_SIZE as the sub-buffer portion being sent correctly. But when I turn the device on, it doesn't work. 

    Using the same hal_i2c_ext_write_with_u16_addr(...) function to write the entire buffer at once works.

  • 0
    •  Analog Employees 
    •  Super User 
    in reply to Thiago

    Hello Thiago,

    What exactly is this you are trying to write? There are no "registers" that large. 

    DM0 lower page starts at address 0x0000 and ends at 0x2FFF. So this means you are trying to write through the boundary of the different memory regions. Once you get above 0x2FFF you have to set the page variable to the upper page to get to addresses 0x3000 to 0x5FFF. 

    Is this the program or a large chunk of parameters you are trying to write? 

    Look at the exported system files and in there you will see the page variable for each parameter in the program. 

    So I think you are either going across boundaries and or not writing to the correct page. 

    Export the system files and look those over carefully. That may shed some light on this. 

    Dave T

  • Hey Dave,

    forgive me, I expressed myself poorly. I'm also new when it comes to DSP integration. What I'm trying to write isn't indeed any register but the program as you mentioned.

    It starts in the address 0x0800 with a size of 4880 bytes, as the following exported variables show.

    PROGRAM_ADDR_IC_1 = 2048
    PROGRAM_SIZE_IC_1 = 4880
    When I perform a single write, I get the expected behavior from the DSP, which is having audio output. With a burst write (writing the whole buffer with 256bytes pieces), I get no sound.
    The idea is to save static RAM memory from our application side since we're using DMA over I2C to perform the write procedure, and that memory portion is used during boot only when we load the program to the DSP. Performing a burst write would reduce that amount of static memory to 256 bytes only, as we are trying to do. 
    So after checking the I2C bus write process with a digital analyzer and verifying that the memory address provided with the corresponding data buffer is correct, I was wondering if it's possible to make such a move.
  • another detail is that I'm writing whitin the DM0 page.

    start address: 0x0800

    end address: 0x1B00

  • Hey,

    so I figured out what the problem was. The addressing for the program region in done is groups of 5 bytes, and I was incrementing the corresponding buffer adress by the size of the buffer itself.