cancel
Showing results for 
Search instead for 
Did you mean: 

Is an unaligned 32 bit read/write with FMC to 16 bit SDRAM possible?

guenniause
Associate II

We want to use external 16 bit SDRAM for heap and stack. The SDRAM is configured with byte enable and MPU. I tried to map the memory to 0xC0000000 and 0x60000000, but it doesn't matter. Also the configuration of MPU with MPU_TEX_LEVEL0 or MPU_TEX_LEVEL1 doesn't matter.

An unaligned read/write with 16 bit is possible. So I think a unaligned read/write with 32 bit should possible too, if the compiler handles the access in the right way.

We use GCC 9.3 and it doesn't work.

Here is a code example, which demonstrates the incorrect reuslts.

int i;

uint8_t* pbyte;

uint16_t* pword;

uint32_t* pdword;

uint32_t address;

volatile uint32_t test;    address = 0xC0000000;

    pbyte = (uint8_t*)address;

    for(i=0;i<16;i++)

    {

       pbyte[i] = i + 1;

    }

    test = pbyte[0];  // => test = 0x1

    test = pbyte[1];  // => test = 0x2

    test = pbyte[2];  // => test = 0x3

    test = pbyte[3];  // => test = 0x4

    pword = (uint16_t*)((int)address);

    test = *pword;   // => test = 0x0201

    pword = (uint16_t*)((int)address + 1);

    test = *pword;   // => test = 0x0302

    pdword = (uint32_t*)((int)address);

    test = *pdword;   // => test = 0x04030201

    pdword = (uint32_t*)((int)address + 1);

    test = *pdword;   // => test = 0x05040302

    pdword = (uint32_t*)((int)address + 2);

    test = *pdword;   // => test = 0x06050605 instead of 0x06050403

    pdword = (uint32_t*)((int)address + 3);

    test = *pdword;   // => test = 0x07060506 instead of 0x07060504

Is there someone who had the similar problem and has solved it?

12 REPLIES 12

Did this piece of information come from @Douglas MILLER​ ?

How does this match the erratum above? I understand that cache fills/evictions may be always aligned, but is there a guarantee for that by the cache/processor?

JW

TBH this does not make much sense to me.

In post March 27, 2023 you set the FMC area as Normal Cached Write-back, and you've said it does not work. Write-back caching would imply that only writes to FMC are from cache evictions, which are presumably always properly aligned (Cortex-M7 TRM, 5.4.7 AXIM interface transfers, Cache line write-back (eviction))

Now you say, that you set it as Normal Cached Write-through, and it works? Write-through writes IMO could end up at the FMC interface as unaligned (Non-cacheable, Write-Back no Write-Allocate or Write-Through writes subchapter of the same chapter, Table 5-17 STR to Cacheable write-through or Non-cacheable Normal memory).

I am confused and feeling quite lucky I don't have to deal with the 'H7.

JW

>  feeling quite lucky I don't have to deal with the 'H7.

Yep. Some STM32H7 have erratum that says that Write-through is NOT recommended, instead use Write-back. But here the OP says that write-through does work...