SAMV71 MMC and RAM Memory alignment issue.

Go To Last Post
2 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Doing a simple read / write test to benchmark the time it takes to write in and out with various block sizes and using the cycle counter in the processor status window of AS 7. Having an issue with either the read or write not aligning and subsequently producing an error that the block which comes back out is not the same as the block which goes in. Started originally by pointing directly to element 0 of the array in the r/w functions, tried pointers to see if that would change anything and have used the ALIGN4  attribute to try to force the variables to be on word boundaries in the RAM.

 

It works flawlessly if my data for writing is uint/int8, or uint16/int16 - if I use uint32/int32 or float32, the readback buffer is missing the first few values (anywhere from 2-5) and the test fails. Now here is the weird thing - if I change the variable size of j and k to int16, which doesn't allow for proper testing of the values, the readback buffer at least has the same values, no missing values, as the buffer that was written to the memory card. I suspect that by changing j and k's size, the array of floats aligns to a word boundary - how can I force this to just happen? Using ALIGN4 float32_t buf1[1024], etc... is not doing the trick...

 

bool mem_test(void){

    float32_t buf1[1024];
    float32_t buf2[1024];
    float32_t *bufA; 
    float32_t *bufB; 
    
    bufA = &buf1[0];
    bufB = &buf2[0]; 
    
    float32_t j,k; 
    uint16_t z;
    
    sd_mmc_err_t local_err; 
    j = 0;
    for (z = 0; z < 1024; z++){
        buf1[z] = z * 10.01 + 2.76;
        buf2[z] = 0;
    }
    
    j = 0; 
    k = 0;
    local_err = sd_mmc_init_write_blocks(0, 1, 8);
    local_err = sd_mmc_start_write_blocks(bufA, 8);
    local_err = sd_mmc_wait_end_of_write_blocks(false);
    local_err = sd_mmc_init_read_blocks(0, 1, 8);
    local_err = sd_mmc_start_read_blocks(bufB, 8);    
    local_err = sd_mmc_wait_end_of_read_blocks(false);
    for (z = 0; z < 1024; z++){
        j = buf1[z];
        k = buf2[z];
        if((k-j)){
            return 0;
        }    
    }
    
    return 1;
}

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Workaround : The buffers cannot be on the stack, because the stack pointer cannot guarantee alignment, it's a crapshoot. This does make sense as to why the size of j/k would affect the outcome.