Пример #1
0
/***************************************************************************//**
 * @brief
 *   Configure and initialize TFT Direct Drive
 *
 * @param[in] ebiTFTInit
 *   TFT Initialization structure
 ******************************************************************************/
void EBI_TFTInit(const EBI_TFTInit_TypeDef *ebiTFTInit)
{
    uint32_t ctrl;

    /* Configure base address for frame buffer offset to EBI bank */
    EBI_TFTFrameBaseSet(ebiTFTInit->addressOffset);

    /* Configure display size and porch areas */
    EBI_TFTSizeSet(ebiTFTInit->hsize,
                   ebiTFTInit->vsize);
    EBI_TFTHPorchSet(ebiTFTInit->hPorchFront,
                     ebiTFTInit->hPorchBack,
                     ebiTFTInit->hPulseWidth);
    EBI_TFTVPorchSet(ebiTFTInit->vPorchFront,
                     ebiTFTInit->vPorchBack,
                     ebiTFTInit->vPulseWidth);

    /* Configure timing settings */
    EBI_TFTTimingSet(ebiTFTInit->dclkPeriod,
                     ebiTFTInit->startPosition,
                     ebiTFTInit->setupCycles,
                     ebiTFTInit->holdCycles);

    /* Configure line polarity settings */
    EBI_PolaritySet(ebiLineTFTCS, ebiTFTInit->csPolarity);
    EBI_PolaritySet(ebiLineTFTDClk, ebiTFTInit->dclkPolarity);
    EBI_PolaritySet(ebiLineTFTDataEn, ebiTFTInit->dataenPolarity);
    EBI_PolaritySet(ebiLineTFTVSync, ebiTFTInit->vsyncPolarity);
    EBI_PolaritySet(ebiLineTFTHSync, ebiTFTInit->hsyncPolarity);

    /* Main control, EBI bank select, mask and blending configuration */
    ctrl =
        (uint32_t)(ebiTFTInit->bank) |
        (uint32_t)(ebiTFTInit->width) |
        (uint32_t)(ebiTFTInit->colSrc) |
        (uint32_t)(ebiTFTInit->interleave) |
        (uint32_t)(ebiTFTInit->fbTrigger) |
        (uint32_t)(ebiTFTInit->shiftDClk == true ? (1 << _EBI_TFTCTRL_SHIFTDCLKEN_SHIFT) : 0) |
        (uint32_t)(ebiTFTInit->maskBlend) |
        (uint32_t)(ebiTFTInit->driveMode);

    EBI->TFTCTRL = ctrl;

    /* Enable TFT pins */
    if (ebiTFTInit->driveMode != ebiTFTDDModeDisabled)
    {
        EBI->ROUTE |= (EBI_ROUTE_TFTPEN);
    }
}
Пример #2
0
/**************************************************************************//**
 * @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;
    }
  }
}
Пример #3
0
/* 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;
    }
  }
}
Пример #4
0
/**************************************************************************//**
 * @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);
    }
  }
}
Пример #5
0
/*********************************************************************
*
*       LCD_X_DisplayDriver
*
* Purpose:
*   This function is called by the display driver for several purposes.
*   To support the according task the routine needs to be adapted to
*   the display controller. Please note that the commands marked with
*   'optional' are not cogently required and should only be adapted if
*   the display controller supports these features.
*
* Parameter:
*   LayerIndex - Index of layer to be configured
*   Cmd        - Please refer to the details in the switch statement below
*   pData      - Pointer to a LCD_X_DATA structure
*
* Return Value:
*   < -1 - Error
*     -1 - Command not handled
*      0 - Ok
*/
int LCD_X_DisplayDriver(unsigned LayerIndex, unsigned Cmd, void * pData) {
  int r;

  (void)LayerIndex;                   /* Unused parameter */

  switch (Cmd) {
  //
  // Required
  //
  case LCD_X_INITCONTROLLER: {
    //
    // Called during the initialization process in order to set up the
    // display controller and put it into operation. If the display
    // controller is not initialized by any external routine this needs
    // to be adapted by the customer...
    //
    _InitController();
    EnableVsyncInterrupt();
    return 0;
  }
  case LCD_X_SETVRAMADDR: {
    //
    // Required for setting the address of the video RAM for drivers
    // with memory mapped video RAM which is passed in the 'pVRAM' element of p
    //
    LCD_X_SETVRAMADDR_INFO * p;
    p = (LCD_X_SETVRAMADDR_INFO *)pData;
    _SetVRAMAddr(p->pVRAM);
    return 0;
  }
  case LCD_X_SETORG: {
    //
    // Required for setting the display origin which is passed in the 'xPos' and 'yPos' element of p
    //
    LCD_X_SETORG_INFO * p;
    p = (LCD_X_SETORG_INFO *)pData;
    _SetOrg(p->xPos, p->yPos);
    return 0;
  }
  case LCD_X_SETLUTENTRY: {
    //
    // Required for setting a lookup table entry which is passed in the 'Pos' and 'Color' element of p
    //
    LCD_X_SETLUTENTRY_INFO * p;
    p = (LCD_X_SETLUTENTRY_INFO *)pData;
    _SetLUTEntry(p->Color, p->Pos);
    return 0;
  }
  case LCD_X_ON: {
    //
    // Required if the display controller should support switching on and off
    //
    return 0;
  }
  case LCD_X_OFF: {
    //
    // Required if the display controller should support switching on and off
    //
    // ...
    return 0;
  }
  /* This command is received every time the GUI is done drawing a frame */
  case LCD_X_SHOWBUFFER:
  {
    /* Get the data object */
    LCD_X_SHOWBUFFER_INFO * p;
    p = (LCD_X_SHOWBUFFER_INFO *)pData;

    /* Set frame buffer to the new frame, will be automatically reloaded on VSYNC */
    EBI_TFTFrameBaseSet(FRAME_BUFFER_SIZE * p->Index);
    /* Save the pending buffer index. ISR will send confirmation on next VSYNC. */
    pendingFrameIndex = p->Index;

    return 0;
  }

  default:
    r = -1;
  }
  return r;
}
Пример #6
0
/*********************************************************************
*
*       _SetOrg
*
* Purpose:
*   Should set the origin of the display typically by modifying the
*   frame buffer base address register
*/
static void _SetOrg(int xPos, int yPos) {
    orgx = xPos;
    orgy = yPos;
    EBI_TFTFrameBaseSet(VRAM_pointer+2*( (XSIZE_PHYS*yPos) + xPos ) );
}
Пример #7
0
/*********************************************************************
*
*       _SetVRAMAddr
*
* Purpose:
*   Should set the frame buffer base address
*/
static void _SetVRAMAddr(void * pVRAM) {
    VRAM_pointer = (uint32_t)pVRAM - EBI_BankAddress(EBI_BANK2);
    EBI_TFTFrameBaseSet(VRAM_pointer);
}