Code to replicate double-draw glitch on ST dev board. Program draws full-screen Red->Green->Blue into back-buffer, then swaps the LTDC layer source buffer before repeating. This should result in a solid blue screen, but produces a visible glitch with parts of the screen flashing red and green.

Dependencies:   BSP_DISCO_F746NG

Committer:
Altronics
Date:
Mon Mar 30 02:00:31 2020 +0000
Revision:
3:5ceff0955fb1
Parent:
2:a19deff061e8
Added 3rd buffer for prop assembly.; Appears to fix issue.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Altronics 3:5ceff0955fb1 1 /*Example code to replicate double-draw glitch on DISCO-F746NG
Altronics 3:5ceff0955fb1 2 *
Altronics 3:5ceff0955fb1 3 *The code rapidly draws to the screen, always ending on the same solid color
Altronics 3:5ceff0955fb1 4 *box. When using single buffering there is a (as expected) glitch on the
Altronics 3:5ceff0955fb1 5 *screen. The unexpected bit is that this glitch persists when double buffering.
Altronics 3:5ceff0955fb1 6 *
Altronics 3:5ceff0955fb1 7 *A known-good workaround is to "tripple buffer" the system, with props
Altronics 3:5ceff0955fb1 8 *assembled in a 3rd buffer, and copied to the back buffer in 1 go, before
Altronics 3:5ceff0955fb1 9 *screen refresh. This isn't an idea solution, but at least it's something...
Altronics 3:5ceff0955fb1 10 */
Altronics 3:5ceff0955fb1 11
Altronics 0:c625cc74a577 12 #include "mbed.h"
Altronics 0:c625cc74a577 13 #include "stm32746g_discovery_sdram.h"
Altronics 0:c625cc74a577 14
Altronics 3:5ceff0955fb1 15 //If 0 draw to front buffer
Altronics 3:5ceff0955fb1 16 //If 2 draw to back buffer
Altronics 3:5ceff0955fb1 17 //If 3 draw to prop buffer (and move to back before swap)
Altronics 3:5ceff0955fb1 18 #define BUFFER_COUNT 3
Altronics 2:a19deff061e8 19
Altronics 0:c625cc74a577 20 const uint32_t SDRAM_BANK1_ADDR=0xC0000000;
Altronics 0:c625cc74a577 21 const uint32_t SDRAM_BANK_SIZE =0x200000;
Altronics 0:c625cc74a577 22 const uint32_t SDRAM_BANK2_ADDR=SDRAM_BANK1_ADDR+SDRAM_BANK_SIZE;
Altronics 0:c625cc74a577 23 const uint32_t SDRAM_BANK3_ADDR=SDRAM_BANK2_ADDR+SDRAM_BANK_SIZE;
Altronics 0:c625cc74a577 24 const uint32_t SDRAM_BANK4_ADDR=SDRAM_BANK3_ADDR+SDRAM_BANK_SIZE;
Altronics 0:c625cc74a577 25
Altronics 0:c625cc74a577 26 const uint16_t LCD_WIDTH =480;
Altronics 0:c625cc74a577 27 const uint16_t LCD_HEIGHT=272;
Altronics 0:c625cc74a577 28 const uint16_t LCD_HSYNC =41;
Altronics 0:c625cc74a577 29 const uint16_t LCD_HBP =13;
Altronics 0:c625cc74a577 30 const uint16_t LCD_HFP =32;
Altronics 0:c625cc74a577 31 const uint16_t LCD_VSYNC =10;
Altronics 0:c625cc74a577 32 const uint16_t LCD_VBP =2;
Altronics 0:c625cc74a577 33 const uint16_t LCD_VFP =2;
Altronics 0:c625cc74a577 34
Altronics 0:c625cc74a577 35 const PinName PIN_LCD_DISP=PI_12;
Altronics 0:c625cc74a577 36 const PinName PIN_LCD_BL =PK_3;
Altronics 0:c625cc74a577 37
Altronics 0:c625cc74a577 38 uint32_t frontBuffer=SDRAM_BANK1_ADDR;
Altronics 3:5ceff0955fb1 39 uint32_t backBuffer=SDRAM_BANK1_ADDR+LCD_WIDTH*LCD_HEIGHT*2;
Altronics 3:5ceff0955fb1 40 //uint32_t backBuffer=SDRAM_BANK2_ADDR;
Altronics 3:5ceff0955fb1 41 uint32_t propBuffer=SDRAM_BANK2_ADDR;
Altronics 3:5ceff0955fb1 42 //uint32_t propBuffer=SDRAM_BANK3_ADDR;
Altronics 0:c625cc74a577 43
Altronics 0:c625cc74a577 44 DigitalOut disp(PIN_LCD_DISP);
Altronics 0:c625cc74a577 45 DigitalOut bl(PIN_LCD_BL);
Altronics 0:c625cc74a577 46
Altronics 0:c625cc74a577 47 EventQueue* queue=mbed_event_queue();
Altronics 0:c625cc74a577 48 CircularBuffer<uint16_t,10> buffer;
Altronics 0:c625cc74a577 49
Altronics 0:c625cc74a577 50 void flip(void);
Altronics 0:c625cc74a577 51 bool draw(void);
Altronics 0:c625cc74a577 52 void transferCompleteHandler(void);
Altronics 0:c625cc74a577 53 void lineHandler(void);
Altronics 0:c625cc74a577 54 void reloadHandler(void);
Altronics 0:c625cc74a577 55
Altronics 1:d515deceeccc 56 //Some of these may be redundant... There have been some modifications made to
Altronics 1:d515deceeccc 57 //try different things which haven't been fully stripped out.
Altronics 1:d515deceeccc 58 volatile bool line=false; //Line handler went off while DMA2D active
Altronics 3:5ceff0955fb1 59 volatile bool running=false; //DMA2D transfer ongoing, imminent or in ISR controlled section
Altronics 3:5ceff0955fb1 60 volatile uint8_t updated=0; //0 BB not updated (also prop restore), 1 Updated, 2 Restoring from front, 3 3rd buffer to back transfer
Altronics 1:d515deceeccc 61 volatile bool swapping=false;//Do-Once since both LN and TC can trigger buffer swap
Altronics 1:d515deceeccc 62 volatile bool cont=false; //Wait untill buffer swap completes before repeating
Altronics 0:c625cc74a577 63
Altronics 0:c625cc74a577 64 extern "C" void DMA2D_IRQHandler() {
Altronics 0:c625cc74a577 65
Altronics 0:c625cc74a577 66 uint32_t reg=DMA2D->ISR;
Altronics 0:c625cc74a577 67 DMA2D->IFCR=0x3F;
Altronics 0:c625cc74a577 68 if(reg&0x01) queue->call(printf,"TE\n");
Altronics 0:c625cc74a577 69 if(reg&0x02) transferCompleteHandler();
Altronics 0:c625cc74a577 70 if(reg&0x04) queue->call(printf,"WM\n");
Altronics 0:c625cc74a577 71 if(reg&0x08) queue->call(printf,"CLUTAE\n");
Altronics 0:c625cc74a577 72 if(reg&0x10) queue->call(printf,"CLUTTC\n");
Altronics 0:c625cc74a577 73 if(reg&0x20) queue->call(printf,"CFGE\n");
Altronics 0:c625cc74a577 74 }
Altronics 0:c625cc74a577 75 extern "C" void LTDC_IRQHandler() {
Altronics 0:c625cc74a577 76
Altronics 0:c625cc74a577 77 uint32_t reg=LTDC->ISR;
Altronics 0:c625cc74a577 78 LTDC->ICR=9;
Altronics 0:c625cc74a577 79 if(reg&0x01) lineHandler();
Altronics 0:c625cc74a577 80 if(reg&0x08) reloadHandler();
Altronics 0:c625cc74a577 81 }
Altronics 0:c625cc74a577 82 extern "C" void LTDC_ER_IRQHandler() {
Altronics 0:c625cc74a577 83
Altronics 0:c625cc74a577 84 uint32_t reg=LTDC->ISR;
Altronics 0:c625cc74a577 85 LTDC->ICR=6;
Altronics 0:c625cc74a577 86 if(reg&0x02) queue->call(printf,"FIFO\n");
Altronics 0:c625cc74a577 87 if(reg&0x04) queue->call(printf,"TERR\n");
Altronics 0:c625cc74a577 88 }
Altronics 0:c625cc74a577 89
Altronics 0:c625cc74a577 90 void initLCD() {
Altronics 0:c625cc74a577 91
Altronics 0:c625cc74a577 92 __HAL_RCC_LTDC_CLK_ENABLE();
Altronics 0:c625cc74a577 93 __HAL_RCC_DMA2D_CLK_ENABLE();
Altronics 0:c625cc74a577 94 __HAL_RCC_GPIOE_CLK_ENABLE();
Altronics 0:c625cc74a577 95 __HAL_RCC_GPIOG_CLK_ENABLE();
Altronics 0:c625cc74a577 96 __HAL_RCC_GPIOI_CLK_ENABLE();
Altronics 0:c625cc74a577 97 __HAL_RCC_GPIOJ_CLK_ENABLE();
Altronics 0:c625cc74a577 98 __HAL_RCC_GPIOK_CLK_ENABLE();
Altronics 0:c625cc74a577 99
Altronics 0:c625cc74a577 100 RCC_PeriphCLKInitTypeDef PeriphClkInitStruct={0};
Altronics 0:c625cc74a577 101 PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
Altronics 0:c625cc74a577 102 PeriphClkInitStruct.PLLSAI.PLLSAIN = 192;
Altronics 0:c625cc74a577 103 PeriphClkInitStruct.PLLSAI.PLLSAIR = 5;
Altronics 0:c625cc74a577 104 PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_4;
Altronics 0:c625cc74a577 105 HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
Altronics 0:c625cc74a577 106
Altronics 0:c625cc74a577 107 GPIO_InitTypeDef GPIO_InitStruct={0};
Altronics 0:c625cc74a577 108 GPIO_InitStruct.Pin = GPIO_PIN_4;
Altronics 0:c625cc74a577 109 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
Altronics 0:c625cc74a577 110 GPIO_InitStruct.Pull = GPIO_NOPULL;
Altronics 0:c625cc74a577 111 GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
Altronics 0:c625cc74a577 112 GPIO_InitStruct.Alternate = GPIO_AF14_LTDC;
Altronics 0:c625cc74a577 113 HAL_GPIO_Init(GPIOE,&GPIO_InitStruct);
Altronics 0:c625cc74a577 114 GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15;
Altronics 0:c625cc74a577 115 HAL_GPIO_Init(GPIOI,&GPIO_InitStruct);
Altronics 0:c625cc74a577 116 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;
Altronics 0:c625cc74a577 117 HAL_GPIO_Init(GPIOJ,&GPIO_InitStruct);
Altronics 0:c625cc74a577 118 GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7;
Altronics 0:c625cc74a577 119 HAL_GPIO_Init(GPIOK,&GPIO_InitStruct);
Altronics 0:c625cc74a577 120 GPIO_InitStruct.Pin = GPIO_PIN_12;
Altronics 0:c625cc74a577 121 GPIO_InitStruct.Alternate = GPIO_AF9_LTDC;
Altronics 0:c625cc74a577 122 HAL_GPIO_Init(GPIOG,&GPIO_InitStruct);
Altronics 0:c625cc74a577 123
Altronics 0:c625cc74a577 124 LTDC_HandleTypeDef hLtdcHandler={0};
Altronics 0:c625cc74a577 125 hLtdcHandler.Init.HorizontalSync=(LCD_HSYNC-1);
Altronics 0:c625cc74a577 126 hLtdcHandler.Init.VerticalSync=(LCD_VSYNC-1);
Altronics 0:c625cc74a577 127 hLtdcHandler.Init.AccumulatedHBP=(LCD_HSYNC+LCD_HBP-1);
Altronics 0:c625cc74a577 128 hLtdcHandler.Init.AccumulatedVBP=(LCD_VSYNC+LCD_VBP-1);
Altronics 0:c625cc74a577 129 hLtdcHandler.Init.AccumulatedActiveH=(LCD_HEIGHT+LCD_VSYNC+LCD_VBP-1);
Altronics 0:c625cc74a577 130 hLtdcHandler.Init.AccumulatedActiveW=(LCD_WIDTH+LCD_HSYNC+LCD_HBP-1);
Altronics 0:c625cc74a577 131 hLtdcHandler.Init.TotalHeigh=(LCD_HEIGHT+LCD_VSYNC+LCD_VBP+LCD_VFP-1);
Altronics 0:c625cc74a577 132 hLtdcHandler.Init.TotalWidth=(LCD_WIDTH+LCD_HSYNC+LCD_HBP+LCD_HFP-1);
Altronics 0:c625cc74a577 133 hLtdcHandler.LayerCfg->ImageWidth = LCD_WIDTH;
Altronics 0:c625cc74a577 134 hLtdcHandler.LayerCfg->ImageHeight = LCD_HEIGHT;
Altronics 0:c625cc74a577 135 hLtdcHandler.Init.Backcolor.Blue = 0;
Altronics 0:c625cc74a577 136 hLtdcHandler.Init.Backcolor.Green= 0;
Altronics 0:c625cc74a577 137 hLtdcHandler.Init.Backcolor.Red = 0;
Altronics 0:c625cc74a577 138 hLtdcHandler.Init.HSPolarity = LTDC_HSPOLARITY_AL;
Altronics 0:c625cc74a577 139 hLtdcHandler.Init.VSPolarity = LTDC_VSPOLARITY_AL;
Altronics 0:c625cc74a577 140 hLtdcHandler.Init.DEPolarity = LTDC_DEPOLARITY_AL;
Altronics 0:c625cc74a577 141 hLtdcHandler.Init.PCPolarity = LTDC_PCPOLARITY_IPC;
Altronics 0:c625cc74a577 142 hLtdcHandler.Instance = LTDC;
Altronics 0:c625cc74a577 143 HAL_LTDC_Init(&hLtdcHandler);
Altronics 0:c625cc74a577 144
Altronics 0:c625cc74a577 145 LTDC_LayerCfgTypeDef layer_cfg={0};
Altronics 0:c625cc74a577 146 layer_cfg.WindowX0 = 0;
Altronics 0:c625cc74a577 147 layer_cfg.WindowX1 = LCD_WIDTH;
Altronics 0:c625cc74a577 148 layer_cfg.WindowY0 = 0;
Altronics 0:c625cc74a577 149 layer_cfg.WindowY1 = LCD_HEIGHT;
Altronics 0:c625cc74a577 150 layer_cfg.PixelFormat = LTDC_PIXEL_FORMAT_RGB565;
Altronics 0:c625cc74a577 151 layer_cfg.FBStartAdress = frontBuffer;
Altronics 0:c625cc74a577 152 layer_cfg.Alpha = 255;
Altronics 0:c625cc74a577 153 layer_cfg.Alpha0 = 0;
Altronics 0:c625cc74a577 154 layer_cfg.Backcolor.Blue = 0;
Altronics 0:c625cc74a577 155 layer_cfg.Backcolor.Green = 0;
Altronics 0:c625cc74a577 156 layer_cfg.Backcolor.Red = 0;
Altronics 0:c625cc74a577 157 layer_cfg.BlendingFactor1 = LTDC_BLENDING_FACTOR1_PAxCA;
Altronics 0:c625cc74a577 158 layer_cfg.BlendingFactor2 = LTDC_BLENDING_FACTOR2_PAxCA;
Altronics 0:c625cc74a577 159 layer_cfg.ImageWidth = LCD_WIDTH;
Altronics 0:c625cc74a577 160 layer_cfg.ImageHeight = LCD_HEIGHT;
Altronics 0:c625cc74a577 161 HAL_LTDC_ConfigLayer(&hLtdcHandler,&layer_cfg,1);
Altronics 0:c625cc74a577 162
Altronics 0:c625cc74a577 163 DMA2D->OPFCCR=2;
Altronics 0:c625cc74a577 164 DMA2D->OCOLR=0;
Altronics 0:c625cc74a577 165 DMA2D->OMAR=frontBuffer;
Altronics 0:c625cc74a577 166 DMA2D->OOR=0;
Altronics 0:c625cc74a577 167 DMA2D->NLR=(((uint32_t)LCD_WIDTH)<<16)|((uint32_t)LCD_HEIGHT);
Altronics 0:c625cc74a577 168 DMA2D->CR=0x30001;
Altronics 0:c625cc74a577 169 while((DMA2D->CR)&0x01);
Altronics 0:c625cc74a577 170 DMA2D->OMAR=backBuffer;
Altronics 0:c625cc74a577 171 DMA2D->CR=0x30001;
Altronics 0:c625cc74a577 172 while((DMA2D->CR)&0x01);
Altronics 3:5ceff0955fb1 173 DMA2D->OMAR=propBuffer;
Altronics 3:5ceff0955fb1 174 DMA2D->CR=0x30001;
Altronics 3:5ceff0955fb1 175 while((DMA2D->CR)&0x01);
Altronics 0:c625cc74a577 176
Altronics 0:c625cc74a577 177 LTDC->LIPCR=LCD_HEIGHT+LCD_VSYNC+LCD_VBP;
Altronics 0:c625cc74a577 178 LTDC->IER=0x0F;
Altronics 0:c625cc74a577 179
Altronics 0:c625cc74a577 180 HAL_NVIC_SetPriority(LTDC_IRQn,5,0U);
Altronics 0:c625cc74a577 181 HAL_NVIC_EnableIRQ(LTDC_IRQn);
Altronics 0:c625cc74a577 182 HAL_NVIC_SetPriority(LTDC_ER_IRQn,5,0U);
Altronics 0:c625cc74a577 183 HAL_NVIC_EnableIRQ(LTDC_ER_IRQn);
Altronics 0:c625cc74a577 184 HAL_NVIC_SetPriority(DMA2D_IRQn,5,0U);
Altronics 0:c625cc74a577 185 HAL_NVIC_EnableIRQ(DMA2D_IRQn);
Altronics 0:c625cc74a577 186
Altronics 0:c625cc74a577 187 disp=1;
Altronics 0:c625cc74a577 188 bl=1;
Altronics 0:c625cc74a577 189 }
Altronics 0:c625cc74a577 190
Altronics 0:c625cc74a577 191 void transferCompleteHandler() {
Altronics 0:c625cc74a577 192
Altronics 0:c625cc74a577 193 queue->call(printf,"TC\n");
Altronics 3:5ceff0955fb1 194 #if BUFFER_COUNT>=2
Altronics 3:5ceff0955fb1 195 if(updated==3) {
Altronics 3:5ceff0955fb1 196 swapping=false;
Altronics 3:5ceff0955fb1 197 flip();
Altronics 3:5ceff0955fb1 198 return;
Altronics 3:5ceff0955fb1 199 } else if(updated==2) {
Altronics 3:5ceff0955fb1 200 #if BUFFER_COUNT==3
Altronics 3:5ceff0955fb1 201 //Restore prop buffer
Altronics 3:5ceff0955fb1 202 queue->call(printf,"PROP\n");
Altronics 3:5ceff0955fb1 203 DMA2D->FGMAR=backBuffer;
Altronics 3:5ceff0955fb1 204 DMA2D->FGOR=0;
Altronics 3:5ceff0955fb1 205 DMA2D->FGPFCCR=2;
Altronics 3:5ceff0955fb1 206 DMA2D->OPFCCR=2;
Altronics 3:5ceff0955fb1 207 DMA2D->OMAR=propBuffer;
Altronics 3:5ceff0955fb1 208 DMA2D->OOR=0;
Altronics 3:5ceff0955fb1 209 DMA2D->NLR=(((uint32_t)LCD_WIDTH)<<16)|((uint32_t)(LCD_HEIGHT));
Altronics 3:5ceff0955fb1 210 DMA2D->IFCR=0x3F;
Altronics 3:5ceff0955fb1 211 DMA2D->CR=0x3F01;
Altronics 3:5ceff0955fb1 212 updated=0;
Altronics 3:5ceff0955fb1 213 #endif
Altronics 0:c625cc74a577 214 swapping=false;
Altronics 0:c625cc74a577 215 updated=0;
Altronics 0:c625cc74a577 216 line=false;
Altronics 0:c625cc74a577 217 cont=false;
Altronics 0:c625cc74a577 218 }
Altronics 0:c625cc74a577 219 if(line||(buffer.empty()&&(updated>0))) flip(); else draw();
Altronics 3:5ceff0955fb1 220 #elif BUFFER_COUNT==1
Altronics 2:a19deff061e8 221 draw();
Altronics 2:a19deff061e8 222 #endif
Altronics 0:c625cc74a577 223 }
Altronics 0:c625cc74a577 224
Altronics 0:c625cc74a577 225 void lineHandler() {
Altronics 0:c625cc74a577 226
Altronics 0:c625cc74a577 227 queue->call(printf,"LN\n");
Altronics 3:5ceff0955fb1 228 #if BUFFER_COUNT>=2
Altronics 0:c625cc74a577 229 if(running==true) line=true; else if(updated>0) flip(); else draw();
Altronics 3:5ceff0955fb1 230 #elif BUFFER_COUNT==1
Altronics 2:a19deff061e8 231 draw();
Altronics 2:a19deff061e8 232 #endif
Altronics 0:c625cc74a577 233 }
Altronics 0:c625cc74a577 234
Altronics 0:c625cc74a577 235 void flip() {
Altronics 0:c625cc74a577 236
Altronics 0:c625cc74a577 237 if(swapping) return;
Altronics 0:c625cc74a577 238 swapping=true;
Altronics 0:c625cc74a577 239 queue->call(printf,"SW\n");
Altronics 3:5ceff0955fb1 240 #if BUFFER_COUNT==3
Altronics 3:5ceff0955fb1 241 if(updated!=3) {
Altronics 3:5ceff0955fb1 242 queue->call(printf,"3UP\n");
Altronics 3:5ceff0955fb1 243 //Move prop buffer to backBuffer
Altronics 3:5ceff0955fb1 244 updated=3;
Altronics 3:5ceff0955fb1 245 DMA2D->FGMAR=propBuffer;
Altronics 3:5ceff0955fb1 246 DMA2D->FGOR=0;
Altronics 3:5ceff0955fb1 247 DMA2D->FGPFCCR=2;
Altronics 3:5ceff0955fb1 248 DMA2D->OPFCCR=2;
Altronics 3:5ceff0955fb1 249 DMA2D->OMAR=backBuffer;
Altronics 3:5ceff0955fb1 250 DMA2D->OOR=0;
Altronics 3:5ceff0955fb1 251 DMA2D->NLR=(((uint32_t)LCD_WIDTH)<<16)|((uint32_t)(LCD_HEIGHT));
Altronics 3:5ceff0955fb1 252 DMA2D->IFCR=0x3F;
Altronics 3:5ceff0955fb1 253 DMA2D->CR=0x3F01;
Altronics 3:5ceff0955fb1 254 return;
Altronics 3:5ceff0955fb1 255 }
Altronics 3:5ceff0955fb1 256 #endif
Altronics 3:5ceff0955fb1 257 //Swap front and back buffers
Altronics 0:c625cc74a577 258 LTDC_Layer1->CFBAR=backBuffer;
Altronics 0:c625cc74a577 259 LTDC->SRCR=0x02;
Altronics 0:c625cc74a577 260 uint32_t tmpBuffer=frontBuffer;
Altronics 0:c625cc74a577 261 frontBuffer=backBuffer;
Altronics 0:c625cc74a577 262 backBuffer=tmpBuffer;
Altronics 0:c625cc74a577 263 }
Altronics 0:c625cc74a577 264
Altronics 0:c625cc74a577 265 void reloadHandler() {
Altronics 0:c625cc74a577 266
Altronics 0:c625cc74a577 267 queue->call(printf,"RST\n");
Altronics 0:c625cc74a577 268 running=true;
Altronics 0:c625cc74a577 269 updated=2;
Altronics 3:5ceff0955fb1 270 //Restore back buffer ASAP
Altronics 0:c625cc74a577 271 DMA2D->FGMAR=frontBuffer;
Altronics 0:c625cc74a577 272 DMA2D->FGOR=0;
Altronics 0:c625cc74a577 273 DMA2D->FGPFCCR=2;
Altronics 0:c625cc74a577 274 DMA2D->OPFCCR=2;
Altronics 0:c625cc74a577 275 DMA2D->OMAR=backBuffer;
Altronics 0:c625cc74a577 276 DMA2D->OOR=0;
Altronics 0:c625cc74a577 277 DMA2D->NLR=(((uint32_t)LCD_WIDTH)<<16)|((uint32_t)(LCD_HEIGHT));
Altronics 0:c625cc74a577 278 DMA2D->IFCR=0x3F;
Altronics 0:c625cc74a577 279 DMA2D->CR=0x3F01;
Altronics 0:c625cc74a577 280 }
Altronics 0:c625cc74a577 281
Altronics 0:c625cc74a577 282 bool draw() {
Altronics 0:c625cc74a577 283
Altronics 0:c625cc74a577 284 running=true;
Altronics 0:c625cc74a577 285 if(DMA2D->CR&0x01) return false;
Altronics 0:c625cc74a577 286 if(buffer.empty()) {
Altronics 0:c625cc74a577 287 running=false;
Altronics 3:5ceff0955fb1 288 #if BUFFER_COUNT==1
Altronics 2:a19deff061e8 289 cont=false;
Altronics 2:a19deff061e8 290 #endif
Altronics 0:c625cc74a577 291 return false;
Altronics 0:c625cc74a577 292 }
Altronics 0:c625cc74a577 293 if(updated==0) updated=1;
Altronics 0:c625cc74a577 294 uint16_t color=0;
Altronics 0:c625cc74a577 295 buffer.pop(color);
Altronics 3:5ceff0955fb1 296 queue->call(printf,"DRAW: 0x%04X\n",color);
Altronics 0:c625cc74a577 297 DMA2D->OPFCCR=2;
Altronics 0:c625cc74a577 298 DMA2D->OCOLR=(uint32_t)color;
Altronics 3:5ceff0955fb1 299 #if BUFFER_COUNT==3
Altronics 3:5ceff0955fb1 300 DMA2D->OMAR=propBuffer;
Altronics 3:5ceff0955fb1 301 #elif BUFFER_COUNT==2
Altronics 0:c625cc74a577 302 DMA2D->OMAR=backBuffer;
Altronics 3:5ceff0955fb1 303 #elif BUFFER_COUNT==1
Altronics 2:a19deff061e8 304 DMA2D->OMAR=frontBuffer;
Altronics 2:a19deff061e8 305 #endif
Altronics 0:c625cc74a577 306 DMA2D->OOR=0;
Altronics 0:c625cc74a577 307 DMA2D->NLR=(((uint32_t)LCD_WIDTH)<<16)|((uint32_t)(LCD_HEIGHT));
Altronics 0:c625cc74a577 308 DMA2D->IFCR=0x3F;
Altronics 0:c625cc74a577 309 DMA2D->CR=0x33F01;
Altronics 0:c625cc74a577 310 return true;
Altronics 0:c625cc74a577 311 }
Altronics 0:c625cc74a577 312
Altronics 0:c625cc74a577 313 int main() {
Altronics 0:c625cc74a577 314
Altronics 0:c625cc74a577 315 DeepSleepLock lock;
Altronics 0:c625cc74a577 316 {RawSerial pc(USBTX,USBRX,250000);}
Altronics 0:c625cc74a577 317 printf("Hello World!\n");
Altronics 0:c625cc74a577 318 BSP_SDRAM_Init();
Altronics 0:c625cc74a577 319 initLCD();
Altronics 3:5ceff0955fb1 320 Timer t;t.start();
Altronics 0:c625cc74a577 321
Altronics 0:c625cc74a577 322 while(1) {
Altronics 0:c625cc74a577 323 if(cont) continue;
Altronics 3:5ceff0955fb1 324 uint16_t col1;
Altronics 3:5ceff0955fb1 325 uint16_t col2;
Altronics 3:5ceff0955fb1 326 uint16_t col3;
Altronics 3:5ceff0955fb1 327 //Cycle colors so we know there's activity (I'm prone to making stupid errors...)
Altronics 3:5ceff0955fb1 328 if(t.read_ms()>15000) {
Altronics 3:5ceff0955fb1 329 t.reset();
Altronics 3:5ceff0955fb1 330 col1=0xF800;//R
Altronics 3:5ceff0955fb1 331 col2=0x07E0;//G
Altronics 3:5ceff0955fb1 332 col3=0x001F;//B
Altronics 3:5ceff0955fb1 333 } else if(t.read_ms()>10000) {
Altronics 3:5ceff0955fb1 334 col1=0x001F;//B
Altronics 3:5ceff0955fb1 335 col2=0xF800;//R
Altronics 3:5ceff0955fb1 336 col3=0x07E0;//G
Altronics 3:5ceff0955fb1 337 } else if(t.read_ms()>5000) {
Altronics 3:5ceff0955fb1 338 col1=0x07E0;//G
Altronics 3:5ceff0955fb1 339 col2=0x001F;//B
Altronics 3:5ceff0955fb1 340 col3=0xF800;//R
Altronics 3:5ceff0955fb1 341 } else {
Altronics 3:5ceff0955fb1 342 col1=0xF800;//R
Altronics 3:5ceff0955fb1 343 col2=0x07E0;//G
Altronics 3:5ceff0955fb1 344 col3=0x001F;//B
Altronics 3:5ceff0955fb1 345 }
Altronics 3:5ceff0955fb1 346 buffer.push(col1);
Altronics 3:5ceff0955fb1 347 buffer.push(col2);
Altronics 3:5ceff0955fb1 348 buffer.push(col3);
Altronics 0:c625cc74a577 349 cont=true;
Altronics 3:5ceff0955fb1 350 #if BUFFER_COUNT==1
Altronics 2:a19deff061e8 351 ThisThread::sleep_for(100);
Altronics 2:a19deff061e8 352 #endif
Altronics 0:c625cc74a577 353 }
Altronics 0:c625cc74a577 354 }
Altronics 0:c625cc74a577 355
Altronics 0:c625cc74a577 356 #ifdef sdfklasdhalefn
Altronics 0:c625cc74a577 357 #error "This code won't match pinouts for any available dev board"
Altronics 0:c625cc74a577 358 /*Initalisation code for IS42S16400 SDRAM*/
Altronics 0:c625cc74a577 359 void initSDRAM() {
Altronics 0:c625cc74a577 360
Altronics 0:c625cc74a577 361 __HAL_RCC_FMC_CLK_ENABLE();
Altronics 0:c625cc74a577 362 __HAL_RCC_GPIOA_CLK_ENABLE();
Altronics 0:c625cc74a577 363 __HAL_RCC_GPIOC_CLK_ENABLE();
Altronics 0:c625cc74a577 364 __HAL_RCC_GPIOD_CLK_ENABLE();
Altronics 0:c625cc74a577 365 __HAL_RCC_GPIOE_CLK_ENABLE();
Altronics 0:c625cc74a577 366 __HAL_RCC_GPIOF_CLK_ENABLE();
Altronics 0:c625cc74a577 367 __HAL_RCC_GPIOG_CLK_ENABLE();
Altronics 0:c625cc74a577 368
Altronics 0:c625cc74a577 369 GPIO_InitTypeDef GPIO_InitStruct={0};
Altronics 0:c625cc74a577 370 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;
Altronics 0:c625cc74a577 371 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
Altronics 0:c625cc74a577 372 GPIO_InitStruct.Pull = GPIO_NOPULL;
Altronics 0:c625cc74a577 373 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
Altronics 0:c625cc74a577 374 GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
Altronics 0:c625cc74a577 375 HAL_GPIO_Init(GPIOF,&GPIO_InitStruct);
Altronics 0:c625cc74a577 376 GPIO_InitStruct.Pin = GPIO_PIN_7;
Altronics 0:c625cc74a577 377 HAL_GPIO_Init(GPIOA,&GPIO_InitStruct);
Altronics 0:c625cc74a577 378 GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5;
Altronics 0:c625cc74a577 379 HAL_GPIO_Init(GPIOC,&GPIO_InitStruct);
Altronics 0:c625cc74a577 380 GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_8|GPIO_PIN_15;
Altronics 0:c625cc74a577 381 HAL_GPIO_Init(GPIOG,&GPIO_InitStruct);
Altronics 0:c625cc74a577 382 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;
Altronics 0:c625cc74a577 383 HAL_GPIO_Init(GPIOE,&GPIO_InitStruct);
Altronics 0:c625cc74a577 384 GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1;
Altronics 0:c625cc74a577 385 HAL_GPIO_Init(GPIOD,&GPIO_InitStruct);
Altronics 0:c625cc74a577 386
Altronics 0:c625cc74a577 387 FMC_SDRAM_TimingTypeDef Timing={0};
Altronics 0:c625cc74a577 388 Timing.LoadToActiveDelay = 2;
Altronics 0:c625cc74a577 389 Timing.ExitSelfRefreshDelay = 7;
Altronics 0:c625cc74a577 390 Timing.SelfRefreshTime = 4;
Altronics 0:c625cc74a577 391 Timing.RowCycleDelay = 7;
Altronics 0:c625cc74a577 392 Timing.WriteRecoveryTime = 1;
Altronics 0:c625cc74a577 393 Timing.RPDelay = 2;
Altronics 0:c625cc74a577 394 Timing.RCDDelay = 2;
Altronics 0:c625cc74a577 395 SDRAM_HandleTypeDef sdramHandle={0};
Altronics 0:c625cc74a577 396 sdramHandle.Instance = FMC_SDRAM_DEVICE;
Altronics 0:c625cc74a577 397 sdramHandle.Init.SDBank = FMC_SDRAM_BANK1;
Altronics 0:c625cc74a577 398 sdramHandle.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8;
Altronics 0:c625cc74a577 399 sdramHandle.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12;
Altronics 0:c625cc74a577 400 sdramHandle.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_16;
Altronics 0:c625cc74a577 401 sdramHandle.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
Altronics 0:c625cc74a577 402 sdramHandle.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_2;
Altronics 0:c625cc74a577 403 sdramHandle.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
Altronics 0:c625cc74a577 404 sdramHandle.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2;
Altronics 0:c625cc74a577 405 sdramHandle.Init.ReadBurst = FMC_SDRAM_RBURST_DISABLE;
Altronics 0:c625cc74a577 406 sdramHandle.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_2;
Altronics 0:c625cc74a577 407 HAL_SDRAM_Init(&sdramHandle,&Timing);
Altronics 0:c625cc74a577 408
Altronics 0:c625cc74a577 409 FMC_SDRAM_CommandTypeDef Command={0};
Altronics 0:c625cc74a577 410 Command.CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
Altronics 0:c625cc74a577 411 Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Altronics 0:c625cc74a577 412 Command.AutoRefreshNumber = 1;
Altronics 0:c625cc74a577 413 Command.ModeRegisterDefinition = 0;
Altronics 0:c625cc74a577 414 HAL_SDRAM_SendCommand(&sdramHandle,&Command,0xFFFF);
Altronics 0:c625cc74a577 415 ThisThread::sleep_for(100);
Altronics 0:c625cc74a577 416 Command.CommandMode = FMC_SDRAM_CMD_PALL;
Altronics 0:c625cc74a577 417 Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Altronics 0:c625cc74a577 418 Command.AutoRefreshNumber = 1;
Altronics 0:c625cc74a577 419 Command.ModeRegisterDefinition = 0;
Altronics 0:c625cc74a577 420 HAL_SDRAM_SendCommand(&sdramHandle,&Command,0xFFFF);
Altronics 0:c625cc74a577 421 Command.CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
Altronics 0:c625cc74a577 422 Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Altronics 0:c625cc74a577 423 Command.AutoRefreshNumber = 4;
Altronics 0:c625cc74a577 424 Command.ModeRegisterDefinition = 0;
Altronics 0:c625cc74a577 425 HAL_SDRAM_SendCommand(&sdramHandle,&Command,0xFFFF);
Altronics 0:c625cc74a577 426 Command.CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
Altronics 0:c625cc74a577 427 Command.CommandTarget = FMC_SDRAM_CMD_TARGET_BANK1;
Altronics 0:c625cc74a577 428 Command.AutoRefreshNumber = 1;
Altronics 0:c625cc74a577 429 Command.ModeRegisterDefinition = 0x0220;
Altronics 0:c625cc74a577 430 HAL_SDRAM_SendCommand(&sdramHandle,&Command,0xFFFF);
Altronics 0:c625cc74a577 431 HAL_SDRAM_ProgramRefreshRate(&sdramHandle,0x0606);
Altronics 0:c625cc74a577 432 }
Altronics 0:c625cc74a577 433
Altronics 0:c625cc74a577 434 #endif