From b0351bcaaf1a524ae3abaab1491d557294636311 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?King=20K=C3=A9vin?= Date: Wed, 25 May 2022 20:21:37 +0200 Subject: [PATCH] app: improve a tiny bit the ghosting on RGB panel --- application.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/application.c b/application.c index d2cf17b..a12324d 100644 --- a/application.c +++ b/application.c @@ -844,6 +844,8 @@ void main(void) dma_channel_select(RGBMATRIX_DMA, RGBMATRIX_STREAM, RGBMATRIX_CHANNEL); // set the channel for this stream dma_set_transfer_mode(RGBMATRIX_DMA, RGBMATRIX_STREAM, DMA_SxCR_DIR_MEM_TO_MEM); // set transfer from memory to memory dma_set_priority(RGBMATRIX_DMA, RGBMATRIX_STREAM, DMA_SxCR_PL_LOW); // there is no need to rush + dma_enable_transfer_complete_interrupt(RGBMATRIX_DMA, RGBMATRIX_STREAM); // interrupt when line transfer is complete + nvic_enable_irq(RGBMATRIX_IRQ); // enable interrupt rgbmatrix_clear(); // clear matrix gpio_clear(GPIO_PORT(RGBMATRIX_OE_PIN), GPIO_PIN(RGBMATRIX_OE_PIN)); // enable output @@ -957,6 +959,20 @@ void GPIO_EXTI_ISR(DIAL_SWITCH_PIN)(void) } } +static volatile uint8_t rgbmatrix_line = 0; // line being transferred + +/** ISR triggered when the data for the line of the RGB matrix has been transferred + * we switch line just after the data is latched, to reduce ghosting + */ +void RGBMATRIX_ISR(void) +{ + if (dma_get_interrupt_flag(RGBMATRIX_DMA, RGBMATRIX_STREAM, DMA_TCIF)) { + dma_clear_interrupt_flags(RGBMATRIX_DMA, RGBMATRIX_STREAM, DMA_TCIF); + GPIOB_ODR = (GPIOB_ODR & 0xfff0) + rgbmatrix_line; // select line (line on lower and upper half are updated at once) + rgbmatrix_line = (rgbmatrix_line + 1) % (RGBMATRIX_HEIGHT / 2); // go to next line (two lines are updated at once) + } +} + /** interrupt service routine called to update next line of RGB matrix * @note ideally the next line should be updated when the current one is complete, but the DMA is too fast. * @note switching lines too fast causes inter-line ghosting of the LEDs (on the same column), due to capacitance and driver switching limitations @@ -968,11 +984,7 @@ void TIM_ISR(RGBMATRIX_TIMER)(void) if (DMA_SCR(RGBMATRIX_DMA, RGBMATRIX_STREAM) & DMA_SxCR_EN) { // DMA is not complete return; } - static uint8_t rgbmatrix_line = 0; // line being transferred - rgbmatrix_line = (rgbmatrix_line + 1) % (RGBMATRIX_HEIGHT / 2); // go to next line (two lines are updated at once) - GPIOB_ODR = (GPIOB_ODR & 0xfff0) + rgbmatrix_line; // select line (line on lower and upper half are updated at once) dma_set_peripheral_address(RGBMATRIX_DMA, RGBMATRIX_STREAM, (uint32_t)&rgbmatrix_data[rgbmatrix_line]); // set memory containing line data to be transferred (for memory-to-memory transfer, the source is the peripheral) - dma_clear_interrupt_flags(RGBMATRIX_DMA, RGBMATRIX_STREAM, DMA_TCIF); // even if interrupts are not enabled, clearing this flag is required to start the DMA (I don't know why) dma_enable_stream(RGBMATRIX_DMA, RGBMATRIX_STREAM); // start sending next line } }