/* VSYNC interrupt handler. Will send confirmation to emWin that frame buffer * addres is changed. Frame buffer address is automatically reloaded during VSYNC. */ void EBI_IRQHandler(void) { uint32_t flags; flags = EBI_IntGet(); EBI_IntClear(flags); if ( flags & EBI_IF_VFPORCH ) { if ( pendingFrameIndex >= 0 ) { /* Send a confirmation that the buffer is visible now */ GUI_MULTIBUF_Confirm(pendingFrameIndex); pendingFrameIndex = -1; } } }
/**************************************************************************//** * @brief EBI interrupt routine, configures new frame buffer offset *****************************************************************************/ void EBI_IRQHandler(void) { uint32_t flags; /* Get cause of interrupt */ flags = EBI_IntGet(); /* Clear interrupt */ EBI_IntClear(flags); /* Process VSYNC interrupt */ if (flags & EBI_IF_VFPORCH) { /* Swap buffers if new frame is ready */ if (nextOffset != -1) { EBI_TFTFrameBaseSet(nextOffset); nextOffset = -1; } } }
/* VSYNC interrupt handler. This performs the actual flipping * of the buffers. */ void EBI_IRQHandler(void) { uint32_t flags; flags = EBI_IntGet(); EBI_IntClear(flags); if ( flags & EBI_IF_VSYNC ) { if ( pendingFrameIndex >= 0 ) { /* Set Direct Drive frame buffer address to the new frame */ EBI_TFTFrameBaseSet(FRAME_BUFFER_SIZE * pendingFrameIndex); /* Send a confirmation to emWin that the old back buffer is visible now */ GUI_MULTIBUF_Confirm(pendingFrameIndex); /* Reset the pending flag */ pendingFrameIndex = -1; } } }
/**************************************************************************//** * @brief EBI interrupt routine, configures new frame buffer offset *****************************************************************************/ void EBI_IRQHandler(void) { uint32_t flags; uint32_t lineNumber; uint32_t prevMaskBlend; /* Get source for interrupt */ flags = EBI_IntGet(); /* Clear interrupt */ EBI_IntClear(flags); /* Process vertical sync interrupt */ if (flags & EBI_IF_VFPORCH) { /* Keep tracke of number of frames drawn */ frameCtr++; /* Increase this increment to 2/4/8 to increase scroll speed */ hzOffset += 1; /* Wrap around when a full screen has been displayed */ if (hzOffset == (D_WIDTH + font16x28.c_width)) { hzOffset = 0; } /* We only redraw when we need to */ if (hzOffset != hPos) { hPos = hzOffset; /* We only redraw when we need a new character */ if ((hPos % 16) == 0) { /* Update frame buffer - we do this in the interrupt routine to */ /* ensure a smooth scroller no matter what else is being done. */ /* However, drawing these fonts with low optimization will take */ /* more than one scan line, so this _can_ result in tearing at the */ /* top of the screen for this example. */ prevMaskBlend = EBI->TFTCTRL & _EBI_TFTCTRL_MASKBLEND_MASK; EBI_TFTMaskBlendMode(ebiTFTMBDisabled); TFT_DrawFont(D_WIDTH + hPos, D_HEIGHT - font16x28.height, *scrollptr); if (hPos > 0) { TFT_DrawFont(hPos - font16x28.c_width, D_HEIGHT - font16x28.height, *scrollptr); } EBI->TFTCTRL |= prevMaskBlend; /* Update pointer into text, reset if at last character */ scrollptr++; if (*scrollptr == '\0') { scrollptr = scrolltext; } } } } /* Process horizontal sync interrupt */ if (flags & EBI_IF_HSYNC) { lineNumber = EBI_TFTVCount(); /* Adjust for porch size */ if (lineNumber >= 3) lineNumber -= 3; if (lineNumber < (D_HEIGHT - font16x28.c_height)) { EBI_TFTFrameBaseSet(lineNumber * V_WIDTH * 2); } else { EBI_TFTFrameBaseSet(lineNumber * V_WIDTH * 2 + hzOffset * 2); } } }