app: improve a tiny bit the ghosting on RGB panel

This commit is contained in:
King Kévin 2022-05-25 20:21:37 +02:00
parent 7675f73d0b
commit b0351bcaaf
1 changed files with 16 additions and 4 deletions

View File

@ -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
}
}