STM32F439 SDRAM 테스트
STM32F4는 FSMC(Flexible static memory controller)를 지원하는데 STMF439에서는 SDRAM을 지원하기 위해 FMC (Flexible memory controller )로 변경되었다. 당연히 코드 수정이 필요하다.
- NOR/PSRAM memory controller
- NAND/PC Card memory controller
- Synchronous DRAM (SDRAM/Mobile LPSDR SDRAM) controller
[STM32F439 EV] 보드에서 SDRAM 핀맵 할당
SDRAM Bank는 2채널 할당 되어 있는데 STM32F439 EV 보드에서는 FMC_SDNE1 (0xD000 0000) 에 할당해서 제작 했다.
FMC_SDNE0->(PC2, PH3)
FMC_SDNE1->(PB6, PH6)
STM32F439 SDRAM 초기화 코드
static DMA_HandleTypeDef dmaHandle;
GPIO_InitTypeDef GPIO_InitStructure;
SDRAM_HandleTypeDef *hsdram = &SdramHandle;
/* Enable FMC clock */
__FMC_CLK_ENABLE();
/* Enable chosen DMAx clock */
__DMAx_CLK_ENABLE();
/* Enable GPIOs clock */
__GPIOB_CLK_ENABLE();
__GPIOC_CLK_ENABLE();
__GPIOD_CLK_ENABLE();
__GPIOE_CLK_ENABLE();
__GPIOF_CLK_ENABLE();
__GPIOG_CLK_ENABLE();
/* Common GPIO configuration */
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Alternate = GPIO_AF12_FMC;
/* GPIOB configuration */
GPIO_InitStructure.Pin = GPIO_PIN_5 | GPIO_PIN_6;
HAL_GPIO_Init(GPIOB, &GPIO_InitStructure);
/* GPIOC configuration */
GPIO_InitStructure.Pin = GPIO_PIN_0;
HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
/* GPIOD configuration */
GPIO_InitStructure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 |\
GPIO_PIN_8| GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15;
HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
/* GPIOE configuration */
GPIO_InitStructure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | 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;
HAL_GPIO_Init(GPIOE, &GPIO_InitStructure);
/* GPIOF configuration */
GPIO_InitStructure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 |
GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5 |
GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 |
GPIO_PIN_14 | GPIO_PIN_15;
HAL_GPIO_Init(GPIOF, &GPIO_InitStructure);
/* GPIOG configuration */
GPIO_InitStructure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_3 | GPIO_PIN_4 |
GPIO_PIN_5 | GPIO_PIN_8 | GPIO_PIN_15;
HAL_GPIO_Init(GPIOG, &GPIO_InitStructure);
/* Configure common DMA parameters */
dmaHandle.Init.Channel = SDRAM_DMAx_CHANNEL;
dmaHandle.Init.Direction = DMA_MEMORY_TO_MEMORY;
dmaHandle.Init.PeriphInc = DMA_PINC_ENABLE;
dmaHandle.Init.MemInc = DMA_MINC_ENABLE;
dmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
dmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
dmaHandle.Init.Mode = DMA_NORMAL;
dmaHandle.Init.Priority = DMA_PRIORITY_HIGH;
dmaHandle.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
dmaHandle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
dmaHandle.Init.MemBurst = DMA_MBURST_SINGLE;
dmaHandle.Init.PeriphBurst = DMA_PBURST_SINGLE;
dmaHandle.Instance = SDRAM_DMAx_STREAM;
/* Associate the DMA handle */
__HAL_LINKDMA(hsdram, hdma, dmaHandle);
/* Deinitialize the stream for new transfer */
HAL_DMA_DeInit(&dmaHandle);
/* Configure the DMA stream */
HAL_DMA_Init(&dmaHandle);
/* NVIC configuration for DMA transfer complete interrupt */
HAL_NVIC_SetPriority(SDRAM_DMAx_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(SDRAM_DMAx_IRQn);
STM32F439 SDRAM 테스트 예제
STM32F439에서 SDRAM를 이용하는 가장 큰 이유는 TFT-LCD Controller 를 사용하기 위해서 이다. SDRAM 메모리에 LCD 레이어 메모리를 할당해 주면 LCD 컨트롤러가 DMA를 이용하여 LCD메모리 공간으로 사용 가능하도록 해준다.
#define LCD_FRAME_BUFFER ((uint32_t)0xD0000000)
#define LCD_FRAME_BUFFER_LAYER1 LCD_FRAME_BUFFER
void InitLCD(void)
{
//LCD초기화
BSP_LCD_Init();
/* Layer2 Init */
BSP_LCD_LayerDefaultInit(1, LCD_FRAME_BUFFER_LAYER1);
}
또하나의 SDRAM 사용방법으로 BMP파일과 같이 메모리를 많이 차지하는 데이터를 올려두고 사용하면 고속 처리에 있어 편이하게 사용할 수 있다.
//SDRAM Address
#define SDRAM_DEVICE_ADDR ((uint32_t)0xD0000000)
#define SDRAM_DEVICE_SIZE ((uint32_t)0x800000)
#define LCD_FRAME_BUFFER_LAYER1 LCD_FRAME_BUFFER
#define MAX_LAYER_NUMBER 2
#define LCD_FRAME_BUFFER SDRAM_DEVICE_ADDR
#define BUFFER_OFFSET (uint32_t)(800*400)
void InitBmpFileRead(void)
{
//SDRAM의 임의번지
ImageBuffer = (uint8_t *)BUFFER_OFFSET+LCD_FRAME_BUFFER;
}