⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 alt_video_display.c

📁 This SPI-mode SD Card controller is a free SOPC Builder component that can be used in any SOPC Build
💻 C
📖 第 1 页 / 共 2 页
字号:
*  Purpose: Checks for a free frame buffer to write to.**  Returns:  0 - Found free buffer.  buffer_being_written now points to it.*           -1 - Free buffer not available at this time. *******************************************************************/int alt_video_display_buffer_is_available( alt_video_display* display ){  int ret_code = 0, next_buf_index;  alt_sgdma_descriptor *desc;    if(display->num_frame_buffers > 1) {    /*      * The user, via this API call, is asking us to see if its safe to      * write to the buffer display->buffer_ptrs[display->buffer_being_written].     *      * To do so, we need to ensure that display->buffer_being_displayed     * is accurate. The SGDMA could have finished any number of previously-     * registered-for-display buffers and gone on to the next one, as long     * as the user registered them with the      * alt_video_display_register_written_buffer() routine.     *     * Here we will inspect any such registered buffers that exist between     * where buffer_being_written and buffer_being_displayed are to determine     * if the SGDMA has processed them. If it has, then we know that the      * previous buffer is no longer being transferred to the video display     * device, and is now safe to be written again, and update     * the buffer_being_displayed index accordingly.     */    next_buf_index =       ((display->buffer_being_displayed + 1) % display->num_frame_buffers);           /* Inspect all buffers until we reach the one being written */    while(next_buf_index != display->buffer_being_written ) {      desc = display->buffer_ptrs[next_buf_index]->desc_base;      /*        * If there are signs of actual data transfer having occured, we        * can safely increment the buffer_being_displayed index       */      if(IORD_16DIRECT(&desc->actual_bytes_transferred, 0) > 0) {        display->buffer_being_displayed = next_buf_index;       }              next_buf_index = ((next_buf_index + 1) % display->num_frame_buffers);    }        if( display->buffer_being_written == display->buffer_being_displayed ) {       ret_code = -1;    }  } /* if (# frame buffers > 1) */  /*    * There is only one display buffer. In this case, you're always    * overwriting the "live" buffer on the screen. No sense in reporting    * a problem since you asked for it.   */  else {    ret_code = 0;  }  return (ret_code);}/*******************************************************************  Function: alt_video_display_clear_screen**  Purpose: Uses the fast memset routine to clear the entire frame*           buffer.  User can specify black(0x00) or white(0xFF).*******************************************************************/inline void alt_video_display_clear_screen(alt_video_display* display,                                            char color){  memset( (void*)(display->buffer_ptrs[display->buffer_being_written]->buffer),     color, display->bytes_per_frame );}/*******************************************************************                     PRIVATE FUNCTIONS                           *******************************************************************/ /****************************************************************** * alt_video_display_setup_frame_descriptors *  * Populate and prepare a video frame's SGDMA descriptors.  *  * Arguments: *   *display: The video display the frame is being prepared for *   *frame: The video frame you're constructing *   *buffer: The starting-address of your physical display buffer.  *    This must be a single, continuous span of memory large enough  *    for each pixel in the frame. *   *desc_base: The starting-address of memory allocated for  *    SGDMA descriptors. Descriptor memory must be aligned to a  *    0x20 boundary. ******************************************************************/void alt_video_display_setup_frame_descriptors(  alt_video_display *display,  alt_video_frame *frame,  alt_u32 *buffer,  alt_sgdma_descriptor *desc_base){  int i;  alt_u16 length;  alt_32 buffer_no_cache_bypass;  alt_sgdma_descriptor *last_descriptor;    /*   * We don't want the "uncached" bit set in the buffer address we hand   * off to the SGDMA, so we mask it out here.   */  buffer_no_cache_bypass =     (alt_u32) alt_remap_cached( buffer, display->bytes_per_frame );    for(i=0; i<display->descriptors_per_frame; i++){    /*      * Calculate the data length associated with each descriptor, taking     * into account the edge cases      */    if(i == (display->descriptors_per_frame-1)) {      length = (display->bytes_per_frame % ALT_VIDEO_DISPLAY_BYTES_PER_DESC);       /*         * The init routine calculated the number of desriptors per frame,         * based on frame size (bytes) and bytes per descriptor. Being evenly        * divisible on this last frame means a full-length sized frame.        */       if(length == 0) {         length = ALT_VIDEO_DISPLAY_BYTES_PER_DESC;       }    }    else {      length = ALT_VIDEO_DISPLAY_BYTES_PER_DESC;    }        /* Construct the descriptor */    alt_avalon_sgdma_construct_mem_to_stream_desc(      (frame->desc_base + i),                    /* Descriptor */      ( frame->desc_base + i + 1 ),              /* Next descriptor */      (alt_u32*)( (alt_u8*)buffer_no_cache_bypass +         (ALT_VIDEO_DISPLAY_BYTES_PER_DESC*i) ), /* Read Address */      length,                                    /* Transfer length */      0,                                         /* Don't read fixed addr */      i==0?1:0,                                  /* Generate SOP @ first desc */      i==(display->descriptors_per_frame-1)?1:0, /* Generate EOP @ last desc */      0                                          /* Streaming channel: N/A */    );        /*      * The last descriptor we created above requires a special modification:      * Its "next" pointer should point back to the first descriptor in the      * chain to create a loop.     *      * This was not done done in the above SGDMA descriptor creation routine      * call because that routine always terminates the 'next' descriptor      * pointer to prevent the SGDMA from continuing into unknown memory.     */    if( i == ( display->descriptors_per_frame - 1 ) ) {        last_descriptor = (alt_sgdma_descriptor *) (frame->desc_base + i);            IOWR_32DIRECT((alt_u32)(&last_descriptor->next), 0,         (alt_u32)(frame->desc_base));    }  }}/****************************************************************** * alt_video_display_get_descriptor_span *  * Calculate the number of bytes requireed for descriptor storage * of a particular display. This is useful for allocating memory or * allocating pointers at runtime for creating new video frames. *  * This routine adds two to the physical number of descriptors stored * in the display's properties in order to assist your memory-allocation * needs; the SGDMA API requires a "next" which, for the final descriptor * in a chain requires one extra descriptor. A second "extra" descriptor-span  * is added to afford address alignment; SGDMA descriptors must be aligned * to 0x20-byte boundaries. The alt_video_display_allocate_buffers() routine * contains examples of these. *  * Arguments: *   - *display: (Initialized) Video display to calculate descriptor memory *               requirements for *  * Returns: *   - Size (bytes) of descriptor memory required. ******************************************************************/alt_u32 alt_video_display_get_descriptor_span(alt_video_display *display){  return ((display->descriptors_per_frame+2) * sizeof(alt_sgdma_descriptor));}/*******************************************************************  Function: alt_video_display_allocate_buffers**  Purpose: Allocates memory for both the frame buffers and the *           descriptor chains.* *           If ALT_VIDEO_DISPLAY_USE_HEAP is specified for either*           the buffer_location or descriptor_location, the memory*           is allocated from the heap. Otherwise, buffer_location and *           descriptor_locaiton are presumed to contain the base address *           of memory sufficient to hold the requested number of descriptors*           and video frames. This memory space may be quite large.* *  Returns:  0 - Success*           -1 - Error allocating memory******************************************************************/int alt_video_display_allocate_buffers( alt_video_display* display,                                       int bytes_per_frame,                                       int buffer_location,                                       int descriptor_location,                                       int num_buffers ){  int i, ret_code = 0;    /* Allocate our frame buffers and descriptor buffers */  for( i = 0; i < num_buffers; i++ ) {    display->buffer_ptrs[i] =       (alt_video_frame*) malloc( sizeof( alt_video_frame ));          if(display->buffer_ptrs[i] == NULL) {      ret_code = -1;    }        if( buffer_location == ALT_VIDEO_DISPLAY_USE_HEAP ) {      display->buffer_ptrs[i]->buffer =         (void*) alt_uncached_malloc(( bytes_per_frame ));              if( display->buffer_ptrs[i]->buffer == NULL )        ret_code = -1;    }    else {      display->buffer_ptrs[i]->buffer = (void*)alt_remap_uncached(        (void*)(buffer_location + (i * bytes_per_frame)), bytes_per_frame);    }        if( descriptor_location == ALT_VIDEO_DISPLAY_USE_HEAP ) {      /*       * The SGDMA controller requires all descriptors to be aligned to       * the size of an SGDMA descriptor (32 bytes).  Use memalign() to        * get properly aligned address.       */      display->buffer_ptrs[i]->desc_base = (alt_sgdma_descriptor*)        memalign( 32, alt_video_display_get_descriptor_span( display ) );            if( display->buffer_ptrs[i]->desc_base == NULL ) {        ret_code = -1;      }    }    else {      display->buffer_ptrs[i]->desc_base =         (alt_sgdma_descriptor*)((void*)descriptor_location +           (i * alt_video_display_get_descriptor_span( display )));    }   }   return ret_code;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -