AnsweredAssumed Answered

STM32F429I-DISCO, SDRAM and 8/16 bit addressing

Question asked by Barta.Hank on Mar 27, 2015
Latest reply on Mar 30, 2015 by Barta.Hank
H/W STM32F429I-Discovery
S/W: Example in C:\STM32Cube_FW_F4_V1.4.0\Projects\STM32F429I-Discovery\Examples\FMC\FMC_SDRAM with modifications

I have added the following code to explore addressing SDRAM:

uint32_t uwIndex = 0;
uint32_t t32;
uint16_t t16;
uint8_t t8;
 and 
SDRAM_Initialization_Sequence(&hsdram, &command);  
 
/*## 32 bit read/write #####################################################*/
*( uint32_t*) (SDRAM_BANK_ADDR + WRITE_READ_ADDR + 4*uwIndex) = 0x12345678;
t32 =   *( uint32_t*) (SDRAM_BANK_ADDR + WRITE_READ_ADDR + 4*uwIndex);
/*## read back same value ##################################################*/
 
/*## 16 bit read/write #####################################################*/
*( uint32_t*) (SDRAM_BANK_ADDR + WRITE_READ_ADDR + 4*uwIndex) = 0; // clear SDRAM first
*( uint16_t*) (SDRAM_BANK_ADDR + WRITE_READ_ADDR + 4*uwIndex) = 0x1234;
t16 =   *( uint16_t*) (SDRAM_BANK_ADDR + WRITE_READ_ADDR + 4*uwIndex);
t32 =   *( uint32_t*) (SDRAM_BANK_ADDR + WRITE_READ_ADDR + 4*uwIndex);
/*## read back same value (low order 16 bit word in 32 bit read) ##########*/
 
/*## 16 bit read/write (not 32 bit aligned) ################################*/
//*( uint32_t*) (SDRAM_BANK_ADDR + WRITE_READ_ADDR + 6*uwIndex) = 0; // clear SDRAM first
*( uint16_t*) (SDRAM_BANK_ADDR + WRITE_READ_ADDR + 6*uwIndex) = 0x5678;
t16 =   *( uint16_t*) (SDRAM_BANK_ADDR + WRITE_READ_ADDR + 6*uwIndex);
t32 =   *( uint32_t*) (SDRAM_BANK_ADDR + WRITE_READ_ADDR + 4*uwIndex);
/*## read back same value still low order word in 32 bit word! #############*/
 
/*## 8 bit read/write (not 32 bit aligned) #################################*/
*( uint32_t*) (SDRAM_BANK_ADDR + WRITE_READ_ADDR + 4*uwIndex) = 0;
*( uint8_t*) (SDRAM_BANK_ADDR + WRITE_READ_ADDR + 4*uwIndex) = 0x12;
t8 =   *( uint8_t*) (SDRAM_BANK_ADDR + WRITE_READ_ADDR + 4*uwIndex);
t32 =   *( uint32_t*) (SDRAM_BANK_ADDR + WRITE_READ_ADDR + 4*uwIndex);
/*## read back same value ##################################################*/
 
/*## 8 bit read/write odd address ##########################################*/
*( uint32_t*) (SDRAM_BANK_ADDR + WRITE_READ_ADDR + 4*uwIndex) = 0;
*( uint8_t*) (SDRAM_BANK_ADDR + WRITE_READ_ADDR + 5*uwIndex) = 0x12;
t8 =   *( uint8_t*) (SDRAM_BANK_ADDR + WRITE_READ_ADDR + 5*uwIndex);
t32 =   *( uint32_t*) (SDRAM_BANK_ADDR + WRITE_READ_ADDR + 4*uwIndex);
/*## read back same value but 32 bit reads indicate it went to even address */
(First line in each code block is existing code shown to help locate)

I have studied the manual for the processor and as near as I can tell, the FMC is capable of managing the operations to may 8, 16 and 32 bit operations to the physical memory width. From RM00090
"AHB transactions are translated into the external device protocol. In particular, if the
selected external memory is 16- or 8-bit wide, 32-bit wide transactions on the AHB are split
into consecutive 16- or 8-bit accesses. The FMC Chip Select (FMC_NEx) does not toggle
between the consecutive accesses."

(I suppose this does not explicitly state that 8 and 16 bit operations will be handled correctly.)

It seems that lower two bits are ignored for 8 and 16 bit operations.

Either:
1) My code is wrong
2) My interpretation of the manual is wrong
3) The setup in the example code is not tailored to support this capability
4) Profit! (Well... maybe not. ;)

Which is it?

Outcomes