[2022 Digi-Key Innovation Design Competition] Project Sharing Post 2: Porting Emwin5.28 on the stm32f7 official development board
[Copy link]
1. Introduction
There are many emWin GUI libraries, and emWin is very useful on STM32 and NXP. The predecessor of emWin is UCGUI, and the advanced version of UCGUI is emWin. STemWin is the emWin version licensed by SEGGER to ST. ST chips can use STemWin for free, and STemWin is optimized for ST chips.
2. emWin Supported Platforms
emWin supports a wide range of hardware platforms, including almost all 16-bit or 32-bit microcontrollers, from ARM7, ARM9 to Cortex-M3, Cortex-M4, Cortex-M7 and Cortex-A9, and can even run on Cortex-M0.
Commonly used software tools for emWin:
BmpCvtST: Bitmap converter. It converts common image file formats (such as BMP, GIF, and PNG) to the required emWin bitmap format. --File->Save As saves the image data as a .c file
FontCvtST: Font converter. Converts character fonts into .c files. Extended
GUIBuilder: Interface editor. Used for preliminary design of display interfaces, or
designing interfaces without knowing C language. emWin widgets can be placed and resized directly in GUIBuilder by dragging and dropping without having to write source code. Additional properties can be added by pressing the context menu, and can be fine-tuned by editing the properties of the widget. The designed interface can be saved as a C file and added directly to the project for use, but the interaction logic of the interface requires user-defined code to implement.
3. emWin visualization tool AppWizard
The following is the transplantation:
The development board is equipped with a 16MB SDRAM chip MT48LC4M32B2B5-6A, which is the same as the FMC of the F7 and F4 series. It has a total of 6 bank areas. The sdram on the development board is located in SDRAM Bank1, so select SDCKE0+SDNE0 in cubemx. Looking at the MT48LC4M32B2B5 data sheet, its capacity is 4 Meg x 32 (1 Meg x 32 x 4 banks), that is, 128Mb (16MB). However, since the data line on the board only uses 16 bits, the actual available size is only 8MB. The sdram configuration is shown in the figure (determine the relevant parameters according to the data sheet).
#include "sdram.h"
static SDRAM_HandleTypeDef sdramHandle;
static FMC_SDRAM_TimingTypeDef Timing;
static FMC_SDRAM_CommandTypeDef Command;
/**
* [url=home.php?mod=space&uid=159083]@brief[/url] Initializes SDRAM MSP.
* @param hsdram: SDRAM handle
* @param Params
* @retval None
*/
void SDRAM_MspInit(SDRAM_HandleTypeDef *hsdram, void *Params)
{
static DMA_HandleTypeDef dma_handle;
GPIO_InitTypeDef gpio_init_structure;
/* Enable FMC clock */
__HAL_RCC_FMC_CLK_ENABLE();
/* Enable chosen DMAx clock */
__DMAx_CLK_ENABLE();
/* Enable GPIOs clock */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
/* Common GPIO configuration */
gpio_init_structure.Mode = GPIO_MODE_AF_PP;
gpio_init_structure.Pull = GPIO_PULLUP;
gpio_init_structure.Speed = GPIO_SPEED_FAST;
gpio_init_structure.Alternate = GPIO_AF12_FMC;
/* GPIOC configuration */
gpio_init_structure.Pin = GPIO_PIN_3;
HAL_GPIO_Init(GPIOC, &gpio_init_structure);
/* GPIOD configuration */
gpio_init_structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_3 | GPIO_PIN_8 | GPIO_PIN_9 |
GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15;
HAL_GPIO_Init(GPIOD, &gpio_init_structure);
/* GPIOE configuration */
gpio_init_structure.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_init_structure);
/* GPIOF configuration */
gpio_init_structure.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_init_structure);
/* GPIOG configuration */
gpio_init_structure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4| GPIO_PIN_5 | GPIO_PIN_8 |\
GPIO_PIN_15;
HAL_GPIO_Init(GPIOG, &gpio_init_structure);
/* GPIOH configuration */
gpio_init_structure.Pin = GPIO_PIN_3 | GPIO_PIN_5;
HAL_GPIO_Init(GPIOH, &gpio_init_structure);
/* Configure common DMA parameters */
dma_handle.Init.Channel = SDRAM_DMAx_CHANNEL;
dma_handle.Init.Direction = DMA_MEMORY_TO_MEMORY;
dma_handle.Init.PeriphInc = DMA_PINC_ENABLE;
dma_handle.Init.MemInc = DMA_MINC_ENABLE;
dma_handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
dma_handle.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
dma_handle.Init.Mode = DMA_NORMAL;
dma_handle.Init.Priority = DMA_PRIORITY_HIGH;
dma_handle.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
dma_handle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
dma_handle.Init.MemBurst = DMA_MBURST_SINGLE;
dma_handle.Init.PeriphBurst = DMA_PBURST_SINGLE;
dma_handle.Instance = SDRAM_DMAx_STREAM;
/* Associate the DMA handle */
__HAL_LINKDMA(hsdram, hdma, dma_handle);
/* Deinitialize the stream for new transfer */
HAL_DMA_DeInit(&dma_handle);
/* Configure the DMA stream */
HAL_DMA_Init(&dma_handle);
/* NVIC configuration for DMA transfer complete interrupt */
HAL_NVIC_SetPriority(SDRAM_DMAx_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(SDRAM_DMAx_IRQn);
}
/**
* @brief Programs the SDRAM device.
* @param RefreshCount: SDRAM refresh counter value
* @retval None
*/
void SDRAM_Initialization_sequence(uint32_t RefreshCount)
{
__IO uint32_t tmpmrd = 0;
/* Step 1: Configure a clock configuration enable command */
Command.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command.AutoRefreshNumber = 1;
Command.ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT);
/* Step 2: Insert 100 us minimum delay */
/* Inserted delay is equal to 1 ms due to systick time base unit (ms) */
HAL_Delay(1);
/* Step 3: Configure a PALL (precharge all) command */
Command.CommandMode = FMC_SDRAM_CMD_PALL;
Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command.AutoRefreshNumber = 1;
Command.ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT);
/* Step 4: Configure an Auto Refresh command */
Command.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command.AutoRefreshNumber = 8;
Command.ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT);
/* Step 5: Program the external memory mode register */
tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 |\
SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |\
SDRAM_MODEREG_CAS_LATENCY_2 |\
SDRAM_MODEREG_OPERATING_MODE_STANDARD |\
SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
Command.CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command.AutoRefreshNumber = 1;
Command.ModeRegisterDefinition = tmpmrd;
/* Send the command */
HAL_SDRAM_SendCommand(&sdramHandle, &Command, SDRAM_TIMEOUT);
/* Step 6: Set the refresh rate counter */
/* Set the device refresh rate */
HAL_SDRAM_ProgramRefreshRate(&sdramHandle, RefreshCount);
}
/*******************************************************************************
* Function Name : SDRAM_Init
* Description : SDRAM初始化
* Input : None
* Output : None
* Return : None
* Note : None
*******************************************************************************/
uint8_t SDRAM_Init(void)
{
static uint8_t sdramstatus = SDRAM_ERROR;
/* SDRAM device configuration */
sdramHandle.Instance = FMC_SDRAM_DEVICE;
/* Timing configuration for 100Mhz as SD clock frequency (System clock is up to 200Mhz) */
Timing.LoadToActiveDelay = 2;
Timing.ExitSelfRefreshDelay = 7;
Timing.SelfRefreshTime = 4;
Timing.RowCycleDelay = 7;
Timing.WriteRecoveryTime = 2;
Timing.RPDelay = 2;
Timing.RCDDelay = 2;
sdramHandle.Init.SDBank = FMC_SDRAM_BANK1;
sdramHandle.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8;
sdramHandle.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12;
sdramHandle.Init.MemoryDataWidth = SDRAM_MEMORY_WIDTH;
sdramHandle.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
sdramHandle.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_2;
sdramHandle.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
sdramHandle.Init.SDClockPeriod = SDCLOCK_PERIOD;
sdramHandle.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE;
sdramHandle.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;
/* SDRAM controller initialization */
SDRAM_MspInit(&sdramHandle, NULL); /* __weak function can be rewritten by the application */
if(HAL_SDRAM_Init(&sdramHandle, &Timing) != HAL_OK)
{
sdramstatus = SDRAM_ERROR;
}
else
{
sdramstatus = SDRAM_OK;
}
/* SDRAM initialization sequence */
SDRAM_Initialization_sequence(REFRESH_COUNT);
return sdramstatus;
}
/*******************************************************************************
* Function Name : SDRAM_ReadData_WORD
* Description : 读SDRAM数据32位方式
* Input : uwStartAddress 读取起始地址
uwDataSize 读取大小
* Output : pData 读取数据的存储指针
* Return : None
* Note : None
*******************************************************************************/
uint8_t SDRAM_ReadData_WORD(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize)
{
if(HAL_SDRAM_Read_32b(&sdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)
{
return SDRAM_ERROR;
}
else
{
return SDRAM_OK;
}
}
/*******************************************************************************
* Function Name : SDRAM_ReadData_DMA_WORD
* Description : DMA方式读SDRAM数据32位方式
* Input : uwStartAddress 读取起始地址
uwDataSize 读取大小
* Output : pData 读取数据的存储指针
* Return : None
* Note : None
*******************************************************************************/
uint8_t SDRAM_ReadData_DMA_WORD(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize)
{
if(HAL_SDRAM_Read_DMA(&sdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)
{
return SDRAM_ERROR;
}
else
{
return SDRAM_OK;
}
}
/*******************************************************************************
* Function Name : SDRAM_WriteData_WORD
* Description : 向SDRAM写数据32位方式
* Input : uwStartAddress 写入起始地址
uwDataSize 写入大小
pData 待写入的数据
* Output : None
* Return : None
* Note : None
*******************************************************************************/
uint8_t SDRAM_WriteData_WORD(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize)
{
if(HAL_SDRAM_Write_32b(&sdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)
{
return SDRAM_ERROR;
}
else
{
return SDRAM_OK;
}
}
/*******************************************************************************
* Function Name : SDRAM_WriteData_DMA_WORD
* Description : DMA方式向SDRAM写数据32位方式
* Input : uwStartAddress 写入起始地址
uwDataSize 写入大小
pData 待写入的数据
* Output : None
* Return : None
* Note : None
*******************************************************************************/
uint8_t SDRAM_WriteData_DMA_WORD(uint32_t uwStartAddress, uint32_t *pData, uint32_t uwDataSize)
{
if(HAL_SDRAM_Write_DMA(&sdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)
{
return SDRAM_ERROR;
}
else
{
return SDRAM_OK;
}
}
/*******************************************************************************
* Function Name : SDRAM_ReadData_BYTE
* Description : 读SDRAM数据8位方式
* Input : uwStartAddress 读取起始地址
uwDataSize 读取大小
* Output : pData 读取数据的存储指针
* Return : None
* Note : None
*******************************************************************************/
uint8_t SDRAM_ReadData_BYTE(uint32_t uwStartAddress, uint8_t *pData, uint32_t uwDataSize)
{
if(HAL_SDRAM_Read_8b(&sdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)
{
return SDRAM_ERROR;
}
else
{
return SDRAM_OK;
}
}
/*******************************************************************************
* Function Name : SDRAM_WriteData_BYTE
* Description : 向SDRAM写数据8位方式
* Input : uwStartAddress 写入起始地址
uwDataSize 写入大小
pData 待写入的数据
* Output : None
* Return : None
* Note : None
*******************************************************************************/
uint8_t SDRAM_WriteData_BYTE(uint32_t uwStartAddress, uint8_t *pData, uint32_t uwDataSize)
{
if(HAL_SDRAM_Write_8b(&sdramHandle, (uint32_t *)uwStartAddress, pData, uwDataSize) != HAL_OK)
{
return SDRAM_ERROR;
}
else
{
return SDRAM_OK;
}
}
//发送命令给SDRAM BANK
uint8_t BSP_SDRAM_Sendcmd(FMC_SDRAM_CommandTypeDef *SdramCmd)
{
if(HAL_SDRAM_SendCommand(&sdramHandle, SdramCmd, SDRAM_TIMEOUT) != HAL_OK)
{
return SDRAM_ERROR;
}
else
{
return SDRAM_OK;
}
}
//SDRAM DMA传输中断
void BSP_SDRAM_DMA_IRQHandler(void)
{
HAL_DMA_IRQHandler(sdramHandle.hdma);
}
Attached is the transplanted
|