cancel
Showing results for 
Search instead for 
Did you mean: 

STM32h743 fmc sdram unaligned read

DNeje.1
Associate II

Hi, i have read many guides about remapping sdram to 0x60000000 address range or setting up MPU to solve unaligned access exception. The exception is not a problem for me. The referce manual states that FMC peripheral does not support unaligned read transcations.

So I would like to confirm that there is nothing i can do to support it.

I mean we have spent days troubleshooting this issue when having connected external 16bit SDRAM remapped it to 0x60000000 and having set up MPU for this region so the caching is enabled. We still end up with corrupted bytes when reading from address that is not 4byte aligned. The test simpy acesses address 0x60000001 and loads MPU register R2 with value. But the register contains corrupted data. However when i do the same with address 0x60000000 everything works perfectly.

Is this a correct behavior or am I missing something?

thank you for your answer

3 REPLIES 3

Why can't you simply use the SDRAM at its native address?

Are you sure the issues not with your byte-lane implementation?

If the FMC is limiting, then copy whatever you're attempting to read into an intermediate buffer in memory supporting of misaligned reads.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
DNeje.1
Associate II

Our plan is to use the SDRAM as a newlib heap for our system and manage the large memory blocks there. So our initial problem happend with the mbdetls certificate parsing. Function mbedtls_pk_write_key_der() encodes certificate keys in a binary format to destination buffer and fills the buffer from the end leaving the beginning at some address that can be unaligned. And using memcpy() in this case corrupts the target, because newlib's memcpy copies by 4bytes at once, which results in a unaligned transaction.

I am guessing we will encounter many similar situations and thats why I was wondering if we can make the FMC work with unaligned adresses.

To your second question, it is a custom board so we cant be 100% sure that every memory signal is correct. But we did check it thoroughly from the datasheet point of view. And also write a smoke test which works that looks like this:

#define SIZE_XX   1024 * 1024 * 32
 
void memTest(void)
{
       uint32_t *pBuffer = 0x60000000;
       if (!pBuffer) return;
 
       int i;
       uint32_t crc;
 
       crc = 0x12345678;
       for (i = 0; i < (SIZE_XX / 4); i++) {
             pBuffer[i] = computeCRC(&crc);
       }
 
       crc = 0x12345678;
       for (i = 0; i < (SIZE_XX / 4); i++) {
             uint32_t tmp_buffer = pBuffer[i];
             uint32_t tmp_crc = Blitka(&crc);
 
             if(tmp_buffer != tmp_crc) {
                    printf("FAIL 0x%08lx = 0x%08lx, should be 0x%08lx\n", i, tmp_buffer, tmp_crc);
             }
       }
}

The code snippet is only partial and uses a precomputed CRC table. The point is that this test checks the entrie 32MB of SDRAM and succeeds. And as you can see we operate in an 4byte aligned manner.

So do I understand you correctly that FMC is really unabled to work in unaligned manner?

Our plan is to use the SDRAM as a newlib heap for our system and manage the large memory blocks there. So our initial problem happend with the mbdetls certificate parsing. Function mbedtls_pk_write_key_der() encodes certificate keys in a binary format to destination buffer and fills the buffer from the end leaving the beginning at some address that can be unaligned. And using memcpy() in this case corrupts the target, because newlib's memcpy copies by 4bytes at once, which results in a unaligned transaction.

I am guessing we will encounter many similar situations and thats why I was wondering if we can make the FMC work with unaligned adresses.

To your second question, it is a custom board so we cant be 100% sure that every memory signal is correct. But we did check it thoroughly from the datasheet point of view. And also write a smoke test which works that looks like this:

    #define SIZE_XX   1024 * 1024 * 32
     
    void memTest(void)
    {
           uint32_t *pBuffer = 0x60000000;
           if (!pBuffer) return;
     
           int i;
           uint32_t crc;
     
           crc = 0x12345678;
           for (i = 0; i < (SIZE_XX / 4); i++) {
                 pBuffer[i] = computeCRC(&crc);
           }
     
           crc = 0x12345678;
           for (i = 0; i < (SIZE_XX / 4); i++) {
                 uint32_t tmp_buffer = pBuffer[i];
                 uint32_t tmp_crc = computeCRC(&crc);
     
                 if(tmp_buffer != tmp_crc) {
                        printf("FAIL 0x%08lx = 0x%08lx, should be 0x%08lx\n", i, tmp_buffer, tmp_crc);
                 }
           }
    }

The code snippet is only partial and uses a precomputed CRC table. The point is that this test checks the entrie 32MB of SDRAM and succeeds. And as you can see we operate in an 4byte aligned manner.

I am really only interested in information if FMC is really cannot handle unaligned reads in any way.