cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F407 FSMC SRAM & LCD

postuchj
Associate II
Posted on August 17, 2015 at 23:39

I'm new to ARM microcontrollers, and having a bit of trouble understanding something. I have an LCD with the SSD1963 controller and external SRAM (AS6C1616) connected in parallel using the FSMC. The SSD1963 is currently using PD7 (FSMC_NE1) for its chip select and PF0 (FSMC_A0) for its data/command signal. The SRAM is using PG9 (FSMC_NE2) for its chip select.

I've managed to get the SSD1963 up and running using the FSMC, but I am unable to get the FSMC working with the SRAM and this is where it gets confusing for me. The SSD1963 starts at 0x60000000, which sets up the FSMC to automatically set the CS (FSMC_NE1) when writing/reading to/from the SSD19 Since I want to use FSMC_NE2 for the CS of the SRAM, that needs to start at 0x64000000, or that is how I've understood it, but the SRAM only has 19 address lines. Which is probably causing my microcontroller to go into its default handler when I try to write to the SRAM. So my question is, how do I manage to get the FSMC to automatically set FSMC_NE2 without having to start at 0x64000000, or am I totally misunderstanding this concept? Here is my code that I'm using:


/* FSMC initialization function */

void MX_FSMC_Init(void)

{

FSMC_NORSRAM_TimingTypeDef Timing;


/** Perform the SRAM1 memory initialization sequence

*/

hsram1.Instance = FSMC_NORSRAM_DEVICE;

hsram1.Extended = FSMC_NORSRAM_EXTENDED_DEVICE;

/* hsram1.Init */

hsram1.Init.NSBank = FSMC_NORSRAM_BANK1;

hsram1.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE;

hsram1.Init.MemoryType = FSMC_MEMORY_TYPE_SRAM;

hsram1.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16;

hsram1.Init.BurstAccessMode = FSMC_BURST_ACCESS_MODE_DISABLE;

hsram1.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW;

hsram1.Init.WrapMode = FSMC_WRAP_MODE_DISABLE;

hsram1.Init.WaitSignalActive = FSMC_WAIT_TIMING_BEFORE_WS;

hsram1.Init.WriteOperation = FSMC_WRITE_OPERATION_ENABLE;

hsram1.Init.WaitSignal = FSMC_WAIT_SIGNAL_DISABLE;

hsram1.Init.ExtendedMode = FSMC_EXTENDED_MODE_DISABLE;

hsram1.Init.AsynchronousWait = FSMC_ASYNCHRONOUS_WAIT_DISABLE;

hsram1.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE;

/* Timing */

Timing.AddressSetupTime = 15;

Timing.AddressHoldTime = 15;

Timing.DataSetupTime = 255;

Timing.BusTurnAroundDuration = 15;

Timing.CLKDivision = 16;

Timing.DataLatency = 17;

Timing.AccessMode = FSMC_ACCESS_MODE_A;

/* ExtTiming */


HAL_SRAM_Init(&hsram1, &Timing, NULL);


/** Perform the SRAM2 memory initialization sequence

*/

hsram2.Instance = FSMC_NORSRAM_DEVICE;

hsram2.Extended = FSMC_NORSRAM_EXTENDED_DEVICE;

/* hsram2.Init */

hsram2.Init.NSBank = FSMC_NORSRAM_BANK2;

hsram2.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE;

hsram2.Init.MemoryType = FSMC_MEMORY_TYPE_SRAM;

hsram2.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16;

hsram2.Init.BurstAccessMode = FSMC_BURST_ACCESS_MODE_DISABLE;

hsram2.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW;

hsram2.Init.WrapMode = FSMC_WRAP_MODE_DISABLE;

hsram2.Init.WaitSignalActive = FSMC_WAIT_TIMING_BEFORE_WS;

hsram2.Init.WriteOperation = FSMC_WRITE_OPERATION_DISABLE;

hsram2.Init.WaitSignal = FSMC_WAIT_SIGNAL_DISABLE;

hsram2.Init.ExtendedMode = FSMC_EXTENDED_MODE_DISABLE;

hsram2.Init.AsynchronousWait = FSMC_ASYNCHRONOUS_WAIT_DISABLE;

hsram2.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE;

/* Timing */

Timing.AddressSetupTime = 15;

Timing.AddressHoldTime = 15;

Timing.DataSetupTime = 255;

Timing.BusTurnAroundDuration = 15;

Timing.CLKDivision = 16;

Timing.DataLatency = 17;

Timing.AccessMode = FSMC_ACCESS_MODE_A;

/* ExtTiming */


HAL_SRAM_Init(&hsram2, &Timing, NULL);


}


static void HAL_FSMC_MspInit(void){

/* USER CODE BEGIN FSMC_MspInit 0 */


/* USER CODE END FSMC_MspInit 0 */

GPIO_InitTypeDef GPIO_InitStruct;

if (FSMC_Initialized) {

return;

}

FSMC_Initialized = 1;

/* Peripheral clock enable */

__FSMC_CLK_ENABLE();


/** FSMC GPIO Configuration 

PF0 ------> FSMC_A0

PF1 ------> FSMC_A1

PF2 ------> FSMC_A2

PF3 ------> FSMC_A3

PF4 ------> FSMC_A4

PF5 ------> FSMC_A5

PF12 ------> FSMC_A6

PF13 ------> FSMC_A7

PF14 ------> FSMC_A8

PF15 ------> FSMC_A9

PG0 ------> FSMC_A10

PG1 ------> FSMC_A11

PE7 ------> FSMC_D4

PE8 ------> FSMC_D5

PE9 ------> FSMC_D6

PE10 ------> FSMC_D7

PE11 ------> FSMC_D8

PE12 ------> FSMC_D9

PE13 ------> FSMC_D10

PE14 ------> FSMC_D11

PE15 ------> FSMC_D12

PD8 ------> FSMC_D13

PD9 ------> FSMC_D14

PD10 ------> FSMC_D15

PD11 ------> FSMC_A16

PD12 ------> FSMC_A17

PD13 ------> FSMC_A18

PD14 ------> FSMC_D0

PD15 ------> FSMC_D1

PG2 ------> FSMC_A12

PG3 ------> FSMC_A13

PG4 ------> FSMC_A14

PG5 ------> FSMC_A15

PD0 ------> FSMC_D2

PD1 ------> FSMC_D3

PD4 ------> FSMC_NOE

PD5 ------> FSMC_NWE

PD7 ------> FSMC_NE1

PG9 ------> FSMC_NE2

PE0 ------> FSMC_NBL0

PE1 ------> FSMC_NBL1

*/

GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3 

|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_12|GPIO_PIN_13 

|GPIO_PIN_14|GPIO_PIN_15;

GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_LOW;

GPIO_InitStruct.Alternate = GPIO_AF12_FSMC;

HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);


GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3 

|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_9;

GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_LOW;

GPIO_InitStruct.Alternate = GPIO_AF12_FSMC;

HAL_GPIO_Init(GPIOG, &GPIO_InitStruct);


GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10 

|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14 

|GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1;

GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_LOW;

GPIO_InitStruct.Alternate = GPIO_AF12_FSMC;

HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);


GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11 

|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15 

|GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5 

|GPIO_PIN_7;

GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

GPIO_InitStruct.Pull = GPIO_NOPULL;

GPIO_InitStruct.Speed = GPIO_SPEED_LOW;

GPIO_InitStruct.Alternate = GPIO_AF12_FSMC;

HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);


/* USER CODE BEGIN FSMC_MspInit 1 */


/* USER CODE END FSMC_MspInit 1 */

}


#define SRAM_BASE_ADDRESS ((uint32_t)0x64000000)


uint32_t *sram_ptr;


static void sram_write(uint32_t addr, uint16_t val){

sram_ptr = (uint32_t *)(SRAM_BASE_ADDRESS + addr);

*sram_ptr = val;

}


static uint16_t sram_read(uint32_t addr){

sram_ptr = (uint32_t *)(SRAM_BASE_ADDRESS + addr);

return *sram_ptr;

}

6 REPLIES 6
Posted on August 18, 2015 at 00:57

The micro-processor has a 32-bit address bus, the high order bits are decoded in the 0x60000000 region, and subdivides that into four banks. Yes, as far as I'm aware 0x64000000 will be NE4, the addressing on the SRAM will wrap at whatever range your wired address bits define.

What exactly are you calling the read/write functions that is causing it to fault? I'd probably localize the pointer.

Can't help you with the HAL/Cube stuff, assuming CubeMX is generating the right code.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on August 18, 2015 at 08:23

> What exactly are you calling the read/write functions that is causing it to fault? I'd probably localize the pointer.

 +1

Also, post the relevant FSMC registers' content.

> 0x64000000 will be NE4

NE2, you meant.

JW

postuchj
Associate II
Posted on August 18, 2015 at 09:27

I've localized the pointer like you suggested. The crash occurs in the sram_write function after setting the pointer equal to val.

static void sram_write(uint32_t addr, uint16_t val){
uint32_t *sram_ptr;
sram_ptr = (uint32_t *)(SRAM_BASE_ADDRESS + addr);
*sram_ptr = val;
}

Here are the values for the FSMC registers: BCR1 = 0x00001091 BTR1 = 0x0FFFFFFF BCR2 = 0x00000091 BTR2 = 0x0FFFFFFF In the BCR2 register it appears as if the write enable bit isn't being set.
Posted on August 18, 2015 at 09:57

> In the BCR2 register it appears as if the write enable bit isn't being set.

And what happens if you do set it?

JW

knielsen
Associate II
Posted on August 18, 2015 at 10:28

Probably the reason your SRAM has write disabled is this line:

hsram2.Init.WriteOperation = FSMC_WRITE_OPERATION_DISABLE;

That should cause an exception on write (but not read) requests, just as you see... - Kristian.
postuchj
Associate II
Posted on August 18, 2015 at 17:52

Thanks.  That fixed it!