erik_wolfram
19.10.2016, 10:16
Hallo,
ich habe mir nun das STM32F103 Board mit LCD von Pollin beschafft. Das Board verwendet einen ili9325 Display Controller der über FSMC angebunden ist.
Damit bekomme ich eine schicke Oberfläche hin. Leider ist das manuelle "Beschreiben" des FSMC-Registers sehr träge. Das "LCD-Clear" benötigt bei 72 MHz ca 32 ms (for-Schleife für 320x240 Pixel).
Nun dachte ich mir ich "schmeiße" mal den DMA an und lasse diesen fleißig schreiben - es muss ja nur eine Farbwert 320x240 mal geschrieben werden. Da der DMA nur 2^16 65535 BufferSize schafft muss er ja zweimal "angeschmissen" werden.
Aber: setze ich das um sind die ersten 10-20 Pixel Müll. Dann folgen die restlichen in einer gleichen, aber falschen Farbe (rot statt gelb).
Ich vermute hier einen Fehler im Timing. Auf der Suche nach einer Lösung bin ich leider nicht fündig geworden. Es verwundert mich sehr, dass noch niemand auf die Idee gekommen ist, dass mit DMA umzusetzen.
Der DMA wurde so initialisiert:
uint16_t ColorDMA = Color;
RCC_AHBPeriphClockCmd( RCC_AHBPeriph_DMA1, ENABLE );
DMA_InitTypeDef DMA_InitStructure;
DMA_StructInit( &DMA_InitStructure );
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) &(ColorDMA);
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) 0x60020000;//&(LCD_DAT16);
DMA_InitStructure.DMA_PeripheralDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = 65535; // max 65535
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
DMA_DeInit( DMA1_Channel1 );
DMA_Init( DMA1_Channel1, &DMA_InitStructure );
DMA_ITConfig( DMA1_Channel1, DMA_IT_TC, ENABLE );
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
/*
NVIC_InitTypeDef NVIC_InitStructure;
//Enable DMA1 channel IRQ Channel
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriori ty = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init( &NVIC_InitStructure );
*/
DMA_Cmd( DMA1_Channel1, ENABLE );
while(!(DMA_GetITStatus(DMA1_IT_TC1)));
Eine Möglichkeit den DMA mit dem FSMC zu triggern habe ich nicht gefunden - in der ReferenceManuall 0008 gibt es hierzu nur eine Abbildung welche auf eine Kombination von DMA und FSMC verweist.
Als weitere Möglichkeit fällt mir noch das FSMC_Timing ein - dort wüsste ich aber nicht, wo ich ansetzen sollte...
Ich wäre sehr dankbar, wenn mir jemand hierzu etwas Unterstützung oder einen Ratschlag geben könnte!
Gruß Erik
ich habe mir nun das STM32F103 Board mit LCD von Pollin beschafft. Das Board verwendet einen ili9325 Display Controller der über FSMC angebunden ist.
Damit bekomme ich eine schicke Oberfläche hin. Leider ist das manuelle "Beschreiben" des FSMC-Registers sehr träge. Das "LCD-Clear" benötigt bei 72 MHz ca 32 ms (for-Schleife für 320x240 Pixel).
Nun dachte ich mir ich "schmeiße" mal den DMA an und lasse diesen fleißig schreiben - es muss ja nur eine Farbwert 320x240 mal geschrieben werden. Da der DMA nur 2^16 65535 BufferSize schafft muss er ja zweimal "angeschmissen" werden.
Aber: setze ich das um sind die ersten 10-20 Pixel Müll. Dann folgen die restlichen in einer gleichen, aber falschen Farbe (rot statt gelb).
Ich vermute hier einen Fehler im Timing. Auf der Suche nach einer Lösung bin ich leider nicht fündig geworden. Es verwundert mich sehr, dass noch niemand auf die Idee gekommen ist, dass mit DMA umzusetzen.
Der DMA wurde so initialisiert:
uint16_t ColorDMA = Color;
RCC_AHBPeriphClockCmd( RCC_AHBPeriph_DMA1, ENABLE );
DMA_InitTypeDef DMA_InitStructure;
DMA_StructInit( &DMA_InitStructure );
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) &(ColorDMA);
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) 0x60020000;//&(LCD_DAT16);
DMA_InitStructure.DMA_PeripheralDataSize = DMA_MemoryDataSize_HalfWord;
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_M2M = DMA_M2M_Enable;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_BufferSize = 65535; // max 65535
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;
DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
DMA_DeInit( DMA1_Channel1 );
DMA_Init( DMA1_Channel1, &DMA_InitStructure );
DMA_ITConfig( DMA1_Channel1, DMA_IT_TC, ENABLE );
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
/*
NVIC_InitTypeDef NVIC_InitStructure;
//Enable DMA1 channel IRQ Channel
NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriori ty = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init( &NVIC_InitStructure );
*/
DMA_Cmd( DMA1_Channel1, ENABLE );
while(!(DMA_GetITStatus(DMA1_IT_TC1)));
Eine Möglichkeit den DMA mit dem FSMC zu triggern habe ich nicht gefunden - in der ReferenceManuall 0008 gibt es hierzu nur eine Abbildung welche auf eine Kombination von DMA und FSMC verweist.
Als weitere Möglichkeit fällt mir noch das FSMC_Timing ein - dort wüsste ich aber nicht, wo ich ansetzen sollte...
Ich wäre sehr dankbar, wenn mir jemand hierzu etwas Unterstützung oder einen Ratschlag geben könnte!
Gruß Erik