Hallo, ich habe mir grade ein STM32F103VET Board mit TFT von Pollin zugelegt. Das LCD besitzt einen ILI9325 Display-Controller und ist über 16 Bit FSMC angebunden. Hierzu habe ich mir entsprechende Bibliotheken zusammengeführt um die volle Funktionalität zu erzielen. Soweit so gut: Ich kann Texte schreiben, Graphen zeichnen und Bildchen anzeigen. (Alles was man sich so wünscht). Touch gibts auch! Aber: Funktionen wie "LCD_Clear" benötigen ca.32 ms für die 320x240 Pixel. Damit ist keine vernüftige Bildrate umzusetzen. Der Grund dafür ist recht einfach - in sämmtlichen Bibliotheken wird eine for-Schleife für die 320x240=76800 Pixel genutzt und jedes mit einer entsprechenden Farbe gefüllt. Mit einer Taktfrequenz von 72 MHz weiß man dann schnell wo die 32 ms herkommen. Da ich ein großer Fan von DMA bin dachte ich mir, dass ich diesen doch nutzen könnte um die Pixel im Hintergrund und wesentlich schnell zu füllen. Ebenso könnte man so schnell kleine Bildchen/Icons aus einem Puffer ausgeben. Leider scheitere ich momentan an dieser Aufgabe: Der DMA scheint ein Timing-Problem mit dem FSMC zu haben - zwar kommen Daten an - diese sind jedoch fehlerhaft. Die ersten 10-20 Pixel sind müll, während die nachfolgenden Pixel eine kontinuierliche, falsche Farbe haben (rot statt gelb). Der Code dafür sieht so aus:
1 | uint16_t ColorDMA = Color; |
2 | |
3 | LCD_SetCursor( 0, 0 ); |
4 | LCD_WriteRAM_Prepare(); /* Prepare to write GRAM */ |
5 | |
6 | RCC_AHBPeriphClockCmd( RCC_AHBPeriph_DMA1, ENABLE ); |
7 | |
8 | DMA_InitTypeDef DMA_InitStructure; |
9 | |
10 | DMA_StructInit( &DMA_InitStructure ); |
11 | |
12 | |
13 | DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) &(ColorDMA); |
14 | DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; |
15 | DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; |
16 | |
17 | DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) 0x60020000; |
18 | DMA_InitStructure.DMA_PeripheralDataSize = DMA_MemoryDataSize_HalfWord; |
19 | DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; |
20 | |
21 | DMA_InitStructure.DMA_M2M = DMA_M2M_Enable; |
22 | DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;//DMA_DIR_PeripheralSRC; |
23 | |
24 | DMA_InitStructure.DMA_BufferSize = 3000; // max 65535 |
25 | |
26 | DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; |
27 | DMA_InitStructure.DMA_Priority = DMA_Priority_Low; |
28 | |
29 | DMA_DeInit( DMA1_Channel1 ); |
30 | DMA_Init( DMA1_Channel1, &DMA_InitStructure ); |
31 | |
32 | DMA_ITConfig( DMA1_Channel1, DMA_IT_TC, ENABLE ); |
33 | |
34 | NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); |
35 | |
36 | DMA_Cmd( DMA1_Channel1, ENABLE ); |
37 | |
38 | while(!(DMA_GetITStatus(DMA1_IT_TC1))); |
39 | DMA_ClearFlag(DMA1_FLAG_TC1); |
Der Code sollte eigentlich die ersten 3000 Pixel in der vorgebenen Farbe füllen. Stattdessen sind die ersten 10-20 Pixel schwarz und die restlichen rot statt gelb. Was mir auch vollständig unerklärlich ist: warum nutzt keine der Bibliotheken den DMA für solche Funktionen? Eigentlich liegt das doch auf der Hand... Laut STM32 Datenblättern sollte der DMA auf FSMC zugreifen können... Ich hoffe hier kann mir jemand helfen! Gruß Erik