2015-03-27 05:28 AM
H/W STM32F429I-Discovery
S/W: Example inC:\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?
#sdram-addressing
2015-03-27 07:44 PM
Doesn't the DISCO have 16-bit wide SDRAM?
Yes the bus breaks accesses into the correct smaller/larger/spanning transactions. On 16-bit and 32-bit memory there are byte lanes in the absence of low order address bits. Behaves like a byte specific chip select. A 32-bit write of 0x12345678 to SDRAM at 0xD0000000 ends up with 0xD0000000 [0x78] 0xD0000001 [0x56] 0xD0000002 [0x34] 0xD0000003 [0x12] You can read or write bytes, half-words, words, all will be done with a consistent endian ordering. Older ARM parts, and the Cortex-M0 as I recall, all have issues with spanning reads/writes, ie unaligned memory accesses. Mainly because they don't want to get involved in multi-cycle memory accesses.2015-03-30 05:36 AM
I seem unable to include code in any reply this morning.
Code shown above is wrong and correct code does demonstrate that 8, 16 and 32 bit addressing works for SDRAM on the STM32F429I-DISCO board.