cancel
Showing results for 
Search instead for 
Did you mean: 

Possible errata in FMC memory access on RM0433 manual (h742/743/750/753 stm32 MCUs)

LFerr.8
Associate II

I am currently using an external 16-bit SRAM chip with an stm32h743 MCU Nucleo board, using FMC for memory manipulation of the external SRAM. On Table154 (NOR/PSRAM External memory address, page 806) and accompanying footnote, it is stated that the address issued to the external memory will be shifted by one bit to the right. I have seen this also mentioned in a few forum posts related to external SRAM accesses. However, by playing around with some operations I can confirm that this does not seem to be true.

See the code below:

```

   uint32_t data = 0x45674567;

   *(uint32_t *) (MRAM_BANK_ADDR | 0x10<<1) = data;

   HAL_Delay(1000);

   printf("First 2 bytes: 0x%4x\n", *(uint16_t *) (MRAM_BANK_ADDR | 0x10<<1));

   printf("Final 2 bytes: 0x%4x\n", *(uint16_t *) (MRAM_BANK_ADDR | 0x10 <<1 | 0x02));

   printf("Final 2 bytes with bit shift: 0x%4x\n", *(uint16_t *) (MRAM_BANK_ADDR | 0x12 <<1));

   printf("Entire read: 0x%8lx\n", *(uint32_t *) (MRAM_BANK_ADDR | 0x10<<1));

   data = 0x78907890;

   *(uint32_t *) (MRAM_BANK_ADDR | 0x10<<1 | 0x04) = data;

   printf("First 2 bytes: 0x%4x\n", *(uint16_t *) (MRAM_BANK_ADDR | 0x10 <<1 | 0x04));

   printf("Final 2 bytes: 0x%4x\n", *(uint16_t *) (MRAM_BANK_ADDR | 0x10 <<1 | 0x06));

```​

Output:

```

First 2 bytes: 0x4567

Final 2 bytes: 0x4567

Final 2 bytes with bit shift: 0x7890

Entire read: 0x45674567

First 2 bytes: 0x7890

Final 2 bytes: 0x7890

```​

When the bit shift described in the manual is applied, the output is incorrect. In fact, no bit shift is required to access the second set of 2 bytes. The same seems to apply for writing.

Is this an error in the manual, or am I misinterpreting what is written?

1 ACCEPTED SOLUTION

Accepted Solutions

> Yes, the footnote points out that A0 on the memory chip should always be connected to the MCUs FMC_A0 correct?

Yes.

> My problem however is that the table itself says that the memory address used to access the memory is shifted by 1 bit to the right before actually accessing the memory.

Yes, that's what the hardware does for you.

> I.E. If I write to the address whose last byte is: 0000 0000 0000 0001 it wil acctually access the memories 0x0 address, as the 1 gets shifted out no?

In case of 16-bit memory, it will output address bits 1..N onto pins A0..N-1, it will decode address bit 0 into the byte lane signals. So, in this particular case, all address pins will be 0, NBL0=1 and NBL1=0 (note that byte lane signals are active low, that's why their marking starts with N).

Read datasheet of your memory. The byte lane signals may be called /UB /LB or similarly.

JW

View solution in original post

5 REPLIES 5

 > Is this an error in the manual, or am I misinterpreting what is written?

The latter.

The remark is there for the hardware engineer, to explain, that with 16/32-bit memories, the lowermost *address* pin of memory should be connected to A0 pin of STM32 and not to pin A1/A2.

JW

LFerr.8
Associate II

@Community member​ I understand what you are saying. Yes, the footnote points out that A0 on the memory chip should always be connected to the MCUs FMC_A0 correct?

My problem however is that the table itself says that the memory address used to access the memory is shifted by 1 bit to the right before actually accessing the memory. I.E. If I write to the address whose last byte is: 0000 0000 0000 0001 it wil acctually access the memories 0x0 address, as the 1 gets shifted out no?

Or does the ADDR not refer to the address I am using in my C code to access the memory?

> Yes, the footnote points out that A0 on the memory chip should always be connected to the MCUs FMC_A0 correct?

Yes.

> My problem however is that the table itself says that the memory address used to access the memory is shifted by 1 bit to the right before actually accessing the memory.

Yes, that's what the hardware does for you.

> I.E. If I write to the address whose last byte is: 0000 0000 0000 0001 it wil acctually access the memories 0x0 address, as the 1 gets shifted out no?

In case of 16-bit memory, it will output address bits 1..N onto pins A0..N-1, it will decode address bit 0 into the byte lane signals. So, in this particular case, all address pins will be 0, NBL0=1 and NBL1=0 (note that byte lane signals are active low, that's why their marking starts with N).

Read datasheet of your memory. The byte lane signals may be called /UB /LB or similarly.

JW

LFerr.8
Associate II

@Community member​  AH yes. I understand now, the manual is describing the translation mechanism itself between MCU memory address and chip memory address. Thank you so much.

By the way, one more thing that seems counter-intuitive to me. On page 804:

AXI transaction data size is smaller than the external device data width and the device supports byte selection (SRAM, PSRAM, SDRAM):
[...]
Read transactions, the FMC returns all bytes according to the external device data width. The useless bytes are discarded by the system.

And then shortly below, on the same page:

Caution: Address alignment
• Read transactions with unaligned addresses (such as half-word starting at an odd address) are not supported by the FMC.

I have tested and for me the MCU seems to be able to read single bytes on odd addresses, presumably using the first mechanism described. So what is this Caution statement trying to convey?

It is probably already the mcu (its memory interface) which splits the transfer, far before it gets to FMC. Read the Cortex-M7 material (ST's PM, ARM's TRM/ARM).

The caution note may be moot entirely, as except the mcu other busmasters are not likely to even able to initiate unaligned accesses (thus upon such attempt they either fail internally or generate silently an aligned but different-than-expected access).

I am not familiar with the CM7/'H7 so maybe there is some way how to trigger this problem.

JW