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
main.cpp@3:5ceff0955fb1, 2020-03-30 (annotated)
- 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?
User | Revision | Line number | New 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 |