Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: BSP_DISCO_F746NG
main.cpp
- Committer:
- Altronics
- Date:
- 2020-03-27
- Revision:
- 0:c625cc74a577
- Child:
- 1:d515deceeccc
File content as of revision 0:c625cc74a577:
#include "mbed.h"
#include "stm32746g_discovery_sdram.h"
const uint32_t SDRAM_BANK1_ADDR=0xC0000000;
const uint32_t SDRAM_BANK_SIZE =0x200000;
const uint32_t SDRAM_BANK2_ADDR=SDRAM_BANK1_ADDR+SDRAM_BANK_SIZE;
const uint32_t SDRAM_BANK3_ADDR=SDRAM_BANK2_ADDR+SDRAM_BANK_SIZE;
const uint32_t SDRAM_BANK4_ADDR=SDRAM_BANK3_ADDR+SDRAM_BANK_SIZE;
const uint16_t LCD_WIDTH =480;
const uint16_t LCD_HEIGHT=272;
const uint16_t LCD_HSYNC =41;
const uint16_t LCD_HBP =13;
const uint16_t LCD_HFP =32;
const uint16_t LCD_VSYNC =10;
const uint16_t LCD_VBP =2;
const uint16_t LCD_VFP =2;
const PinName PIN_LCD_DISP=PI_12;
const PinName PIN_LCD_BL =PK_3;
uint32_t frontBuffer=SDRAM_BANK1_ADDR;
uint32_t backBuffer=SDRAM_BANK2_ADDR;
DigitalOut disp(PIN_LCD_DISP);
DigitalOut bl(PIN_LCD_BL);
EventQueue* queue=mbed_event_queue();
CircularBuffer<uint16_t,10> buffer;
void flip(void);
bool draw(void);
void transferCompleteHandler(void);
void lineHandler(void);
void reloadHandler(void);
volatile bool line=false;
volatile bool running=false;
volatile uint8_t updated=0;
volatile bool swapping=false;
volatile bool cont=false;
extern "C" void DMA2D_IRQHandler() {
uint32_t reg=DMA2D->ISR;
DMA2D->IFCR=0x3F;
if(reg&0x01) queue->call(printf,"TE\n");
if(reg&0x02) transferCompleteHandler();
if(reg&0x04) queue->call(printf,"WM\n");
if(reg&0x08) queue->call(printf,"CLUTAE\n");
if(reg&0x10) queue->call(printf,"CLUTTC\n");
if(reg&0x20) queue->call(printf,"CFGE\n");
}
extern "C" void LTDC_IRQHandler() {
uint32_t reg=LTDC->ISR;
LTDC->ICR=9;
if(reg&0x01) lineHandler();
if(reg&0x08) reloadHandler();
}
extern "C" void LTDC_ER_IRQHandler() {
uint32_t reg=LTDC->ISR;
LTDC->ICR=6;
if(reg&0x02) queue->call(printf,"FIFO\n");
if(reg&0x04) queue->call(printf,"TERR\n");
}
void initLCD() {
__HAL_RCC_LTDC_CLK_ENABLE();
__HAL_RCC_DMA2D_CLK_ENABLE();
__HAL_RCC_GPIOE_CLK_ENABLE();
__HAL_RCC_GPIOG_CLK_ENABLE();
__HAL_RCC_GPIOI_CLK_ENABLE();
__HAL_RCC_GPIOJ_CLK_ENABLE();
__HAL_RCC_GPIOK_CLK_ENABLE();
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct={0};
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
PeriphClkInitStruct.PLLSAI.PLLSAIN = 192;
PeriphClkInitStruct.PLLSAI.PLLSAIR = 5;
PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_4;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
GPIO_InitTypeDef GPIO_InitStruct={0};
GPIO_InitStruct.Pin = GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
GPIO_InitStruct.Alternate = GPIO_AF14_LTDC;
HAL_GPIO_Init(GPIOE,&GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
HAL_GPIO_Init(GPIOI,&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_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
HAL_GPIO_Init(GPIOJ,&GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
HAL_GPIO_Init(GPIOK,&GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_12;
GPIO_InitStruct.Alternate = GPIO_AF9_LTDC;
HAL_GPIO_Init(GPIOG,&GPIO_InitStruct);
LTDC_HandleTypeDef hLtdcHandler={0};
hLtdcHandler.Init.HorizontalSync=(LCD_HSYNC-1);
hLtdcHandler.Init.VerticalSync=(LCD_VSYNC-1);
hLtdcHandler.Init.AccumulatedHBP=(LCD_HSYNC+LCD_HBP-1);
hLtdcHandler.Init.AccumulatedVBP=(LCD_VSYNC+LCD_VBP-1);
hLtdcHandler.Init.AccumulatedActiveH=(LCD_HEIGHT+LCD_VSYNC+LCD_VBP-1);
hLtdcHandler.Init.AccumulatedActiveW=(LCD_WIDTH+LCD_HSYNC+LCD_HBP-1);
hLtdcHandler.Init.TotalHeigh=(LCD_HEIGHT+LCD_VSYNC+LCD_VBP+LCD_VFP-1);
hLtdcHandler.Init.TotalWidth=(LCD_WIDTH+LCD_HSYNC+LCD_HBP+LCD_HFP-1);
hLtdcHandler.LayerCfg->ImageWidth = LCD_WIDTH;
hLtdcHandler.LayerCfg->ImageHeight = LCD_HEIGHT;
hLtdcHandler.Init.Backcolor.Blue = 0;
hLtdcHandler.Init.Backcolor.Green= 0;
hLtdcHandler.Init.Backcolor.Red = 0;
hLtdcHandler.Init.HSPolarity = LTDC_HSPOLARITY_AL;
hLtdcHandler.Init.VSPolarity = LTDC_VSPOLARITY_AL;
hLtdcHandler.Init.DEPolarity = LTDC_DEPOLARITY_AL;
hLtdcHandler.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
hLtdcHandler.Instance = LTDC;
HAL_LTDC_Init(&hLtdcHandler);
LTDC_LayerCfgTypeDef layer_cfg={0};
layer_cfg.WindowX0 = 0;
layer_cfg.WindowX1 = LCD_WIDTH;
layer_cfg.WindowY0 = 0;
layer_cfg.WindowY1 = LCD_HEIGHT;
layer_cfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB565;
layer_cfg.FBStartAdress = frontBuffer;
layer_cfg.Alpha = 255;
layer_cfg.Alpha0 = 0;
layer_cfg.Backcolor.Blue = 0;
layer_cfg.Backcolor.Green = 0;
layer_cfg.Backcolor.Red = 0;
layer_cfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA;
layer_cfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA;
layer_cfg.ImageWidth = LCD_WIDTH;
layer_cfg.ImageHeight = LCD_HEIGHT;
HAL_LTDC_ConfigLayer(&hLtdcHandler,&layer_cfg,1);
DMA2D->OPFCCR=2;
DMA2D->OCOLR=0;
DMA2D->OMAR=frontBuffer;
DMA2D->OOR=0;
DMA2D->NLR=(((uint32_t)LCD_WIDTH)<<16)|((uint32_t)LCD_HEIGHT);
DMA2D->CR=0x30001;
while((DMA2D->CR)&0x01);
DMA2D->OMAR=backBuffer;
DMA2D->CR=0x30001;
while((DMA2D->CR)&0x01);
LTDC->LIPCR=LCD_HEIGHT+LCD_VSYNC+LCD_VBP;
LTDC->IER=0x0F;
HAL_NVIC_SetPriority(LTDC_IRQn,5,0U);
HAL_NVIC_EnableIRQ(LTDC_IRQn);
HAL_NVIC_SetPriority(LTDC_ER_IRQn,5,0U);
HAL_NVIC_EnableIRQ(LTDC_ER_IRQn);
HAL_NVIC_SetPriority(DMA2D_IRQn,5,0U);
HAL_NVIC_EnableIRQ(DMA2D_IRQn);
disp=1;
ThisThread::sleep_for(100);
bl=1;
}
void transferCompleteHandler() {
queue->call(printf,"TC\n");
if(updated==2) {
swapping=false;
updated=0;
line=false;
cont=false;
}
if(line||(buffer.empty()&&(updated>0))) flip(); else draw();
}
void lineHandler() {
queue->call(printf,"LN\n");
if(running==true) line=true; else if(updated>0) flip(); else draw();
}
void flip() {
if(swapping) return;
swapping=true;
queue->call(printf,"SW\n");
LTDC_Layer1->CFBAR=backBuffer;
LTDC->SRCR=0x02;
uint32_t tmpBuffer=frontBuffer;
frontBuffer=backBuffer;
backBuffer=tmpBuffer;
}
void reloadHandler() {
queue->call(printf,"RST\n");
running=true;
updated=2;
DMA2D->FGMAR=frontBuffer;
DMA2D->FGOR=0;
DMA2D->FGPFCCR=2;
DMA2D->OPFCCR=2;
DMA2D->OMAR=backBuffer;
DMA2D->OOR=0;
DMA2D->NLR=(((uint32_t)LCD_WIDTH)<<16)|((uint32_t)(LCD_HEIGHT));
DMA2D->IFCR=0x3F;
DMA2D->CR=0x3F01;
}
bool draw() {
running=true;
if(DMA2D->CR&0x01) return false;
if(buffer.empty()) {
running=false;
return false;
}
queue->call(printf,"DRAW\n");
if(updated==0) updated=1;
uint16_t color=0;
buffer.pop(color);
DMA2D->OPFCCR=2;
DMA2D->OCOLR=(uint32_t)color;
DMA2D->OMAR=backBuffer;
DMA2D->OOR=0;
DMA2D->NLR=(((uint32_t)LCD_WIDTH)<<16)|((uint32_t)(LCD_HEIGHT));
DMA2D->IFCR=0x3F;
DMA2D->CR=0x33F01;
return true;
}
int main() {
DeepSleepLock lock;
{RawSerial pc(USBTX,USBRX,250000);}
printf("Hello World!\n");
BSP_SDRAM_Init();
initLCD();
while(1) {
if(cont) continue;
uint16_t color=0xF800;
buffer.push(color);
color=0x07E0;
buffer.push(color);
color=0x001F;
buffer.push(color);
cont=true;
ThisThread::sleep_for(100);
}
}
#ifdef sdfklasdhalefn
#error "This code won't match pinouts for any available dev board"
/*Initalisation code for IS42S16400 SDRAM*/
void initSDRAM() {
__HAL_RCC_FMC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__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();
GPIO_InitTypeDef GPIO_InitStruct={0};
GPIO_InitStruct.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;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
HAL_GPIO_Init(GPIOF,&GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_7;
HAL_GPIO_Init(GPIOA,&GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5;
HAL_GPIO_Init(GPIOC,&GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_8|GPIO_PIN_15;
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;
HAL_GPIO_Init(GPIOE,&GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1;
HAL_GPIO_Init(GPIOD,&GPIO_InitStruct);
FMC_SDRAM_TimingTypeDef Timing={0};
Timing.LoadToActiveDelay = 2;
Timing.ExitSelfRefreshDelay = 7;
Timing.SelfRefreshTime = 4;
Timing.RowCycleDelay = 7;
Timing.WriteRecoveryTime = 1;
Timing.RPDelay = 2;
Timing.RCDDelay = 2;
SDRAM_HandleTypeDef sdramHandle={0};
sdramHandle.Instance = FMC_SDRAM_DEVICE;
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 = FMC_SDRAM_MEM_BUS_WIDTH_16;
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 = FMC_SDRAM_CLOCK_PERIOD_2;
sdramHandle.Init.ReadBurst = FMC_SDRAM_RBURST_DISABLE;
sdramHandle.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_2;
HAL_SDRAM_Init(&sdramHandle,&Timing);
FMC_SDRAM_CommandTypeDef Command={0};
Command.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command.AutoRefreshNumber = 1;
Command.ModeRegisterDefinition = 0;
HAL_SDRAM_SendCommand(&sdramHandle,&Command,0xFFFF);
ThisThread::sleep_for(100);
Command.CommandMode = FMC_SDRAM_CMD_PALL;
Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command.AutoRefreshNumber = 1;
Command.ModeRegisterDefinition = 0;
HAL_SDRAM_SendCommand(&sdramHandle,&Command,0xFFFF);
Command.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command.AutoRefreshNumber = 4;
Command.ModeRegisterDefinition = 0;
HAL_SDRAM_SendCommand(&sdramHandle,&Command,0xFFFF);
Command.CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Command.AutoRefreshNumber = 1;
Command.ModeRegisterDefinition = 0x0220;
HAL_SDRAM_SendCommand(&sdramHandle,&Command,0xFFFF);
HAL_SDRAM_ProgramRefreshRate(&sdramHandle,0x0606);
}
#endif