cancel
Showing results for 
Search instead for 
Did you mean: 

FMC SRAM 32-Bit width

Daniel Studer
Associate II
Posted on November 14, 2017 at 16:24

Hello

I'm using the FMC bus on a STM32F767 to read and write to an external device in SRAM mode with 32-Bit width.

Is it not possible to address the external memory in byte-address mode instead of 32-bit address mode?

I measured the address signals (A3-A0) and these signals are always shiftet right by two bits from the address I use in Code. Following examples:

External Memory at Address 0x60000000 (FMC Bank 1, NOR/PSRAM 1)

reading address 0x60000000 - Address Bus measured at external memory (A3-A0): 0x00

reading address 0x60000001 - Address Bus measured (A3-A0): 0x00

reading address 0x60000002 - Address Bus measured (A3-A0): 0x00

reading address 0x60000003 - Address Bus measured (A3-A0): 0x00

reading address 0x60000004 - Address Bus measured (A3-A0): 0x01

reading address 0x60000005 - Address Bus measured (A3-A0): 0x01

reading address 0x60000006 - Address Bus measured (A3-A0): 0x01

reading address 0x60000007 - Address Bus measured (A3-A0): 0x01

reading address 0x60000008 - Address Bus measured (A3-A0): 0x02

As I understand, I have to read 4 bytes at address 0x00, and the next 4 bytes at address 0x01. But most memories are byte-addressed I thought, so byte 0 at address 0x00, byte 1 at address 0x01 and so on.

During read the BLE0-3 are always set to LOW. These signals are only used when writing.

Another question is, how to read as example 6 bytes at adress 0x00?

By using HAL_SRAM_Read_32b() it is only possible to read multiplication of 4 bytes. Do I have to use HAL_SRAM_Read_32b() for the first 4 bytes and then HAL_SRAM_Read_16b() for the remaining 2 bytes?

Or is it better to read 8 bytes with HAL_SRAM_Read_32b() and then discard the 2 bytes which I not use manually?

Thank you for any help.

Dani

6 REPLIES 6
Posted on November 14, 2017 at 16:34

>>

As I understand, I have to read 4 bytes at address 0x00, and the next 4 bytes at address 0x01. But most memories are byte-addressed I thought, so byte 0 at address 0x00, byte 1 at address 0x01 and so on.

At the bus level perhaps, ie address bits exposed to the physical device. In the memory map the first 32-bit word is at 0x60000000, the second at 0x60000004

When reading, all 32-bit are presented on the data bus, as there is no cost to doing so, the bus management hardware extracts the byte(s) it wants, figure a byte level barrel shifter or mux. A read of six bytes will need 2 bus transactions, depending on the alignment you then cherry pick the bytes you want. The processor doesn't have a native 6-byte read instruction, you can emulate this by doing an aligned LDRD into two registers (64-bit load), and then shifting.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on November 14, 2017 at 16:56

I tried to read 4 bytes at address 0x0x60000000, and the next 4 bytes at address 0x60000004.

The result is I have always the same result from address 0x60000000 - 0x6000000C. At address 0x60000010 is the result I expect at address 0x60000004.

So I have to increment the address pointer always by 0x10 to get the next 4 bytes. Is this the normal way or how to do it else?

So if I want only 6 bytes at address 0x0x60000000,  I call the following code (there are 3 16-bit variables I want to read):

uint16_t rxBuffer[4];

HAL_SRAM_Read_32b(&sram_Handle, (uint32_t *)0x0x60000000, (uint32_t *)rxBuffer, 2);

void HAL_SRAM_Read_32b(SRAM_HandleTypeDef *hsram, uint32_t *pAddress, uint32_t *pDstBuffer, uint32_t BufferSize)

{

  /* Read data from memory */

  for(; BufferSize != 0; BufferSize--)

  {

    *pDstBuffer = *(__IO uint32_t *)pAddress;

    pDstBuffer++;

    pAddress++;

  }

}

And then I only use rxBuffer[0] - rxBuffer[2] and discarding rxBuffer[3]? Or how is the bus management hardware extracting these bytes I dont need?

I mean I can't do the following:

uint16_t rxBuffer[3];

HAL_SRAM_Read_32b(&sram_Handle, (uint32_t *)0x0x60000000, (uint32_t *)rxBuffer, 2);

because the last 2 bytes read from SRAM are then anywhere in my code at the address following rxBuffer[2].

Posted on November 14, 2017 at 17:45

>>

The result is I have always the same result from address 0x60000000 - 0x6000000C. At address 0x60000010 is the result I expect at address 0x60000004.

This would suggest the bus isn't configured correctly.

volatile uint32_t *p = (

volatile uint32_t *)0x60000000

;

int i;

uint32_t d = 0x11121314;

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

{

  *p = d;

   printf('%p %08lx\n', p, d);

   p++;

   d += 0x11111111;

}

putchar('\n');

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

{

  printf('%p %08lX\n', p, *p); // Address and content

  p++;

}

putchar('\n');

If the two passes here don't display the same data you have some hardware/configuration issue.

A0 at the STM32 package pins should be bit 2 from the internal address bus in 32-bit data mode. ie the hardware in the STM32 shifts the address bits based on the width of the transaction settings for the bus, not your 8/16/32-bit read/write at the code level.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on November 14, 2017 at 17:48

60000000 11121314

60000004 22232425

60000008 33343536

6000000C 44454647

60000010 55565758

60000014 66676869

60000018 7778797A

6000001C 88898A8B

60000000 11121314

60000004 22232425

60000008 33343536

6000000C 44454647

60000010 55565758

60000014 66676869

60000018 7778797A

6000001C 88898A8B
Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
175440CGIL5
Posted on April 15, 2018 at 11:32

This issue probably has been resolved, see

https://community.st.com/0D50X00009XkYQCSA3