Steve Green

IPU not working most of the time, but occasionally works

Discussion created by Steve Green on May 8, 2012
Latest reply on Jun 17, 2014 by raimundszabo

Dear all,

I'm having difficulty getting a simple use of the IPU to work. If I understand it right, the IPU can allocate an input and output buffer (if none is specified by the user) and perform a simple colour space conversion on the input buffer contents.

Below is some very simple code that sets up the IPU to do CSC conversion on a fixed array of 0xFF values. (The 0xFF value is not relevant, the problem happens with any value.)

When I run this, most of the time the IPU does *not* perform the CSC. The output buffer before and after the IPU task contains values of zero. BUT - occasionally it *does* work and the output buffer contains repeated correct non-zero characters.

The IPU always returns a value of zero, meaning it always thinks it was successful.

Does anyone have ideas why this mostly fails but occasionally works?

Many thanks

 

/******************************************************************************************
**
** IPU test
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <mxc_ipu_hl_lib.h>

int
main(int argc, char **argv)
{
  int ret, test, i;
  unsigned char *ptr;
  ipu_lib_handle_t handle;
  ipu_lib_input_param_t input;
  ipu_lib_output_param_t output;
  unsigned int w = 720, h = 576;

  // run the IPU test 10 times
  for (test = 0; test < 10; test++)
  {
    // setup the IPU input
    memset(&input, 0x00, sizeof(input));
    input.width = w;
    input.height = h;
    input.fmt = IPU_PIX_FMT_UYVY;
    input.motion_sel = HIGH_MOTION;
    input.input_crop_win.pos.x = 0;
    input.input_crop_win.pos.y = 0;
    input.input_crop_win.win_w = w;
    input.input_crop_win.win_h = h;
    input.user_def_paddr[0] = NULL;// NULL means that a buffer will be allocated

    // setup the IPU output
    memset(&output, 0x00, sizeof(output));
    output.width = w;
    output.height = h;
    output.fmt = IPU_PIX_FMT_RGB565;
    output.rot = IPU_ROTATE_NONE;
    output.show_to_fb = 0;
    output.fb_disp.pos.x = 0;
    output.fb_disp.pos.y = 0;
    output.fb_disp.fb_num = 0;
    output.output_win.pos.x = 0;
    output.output_win.pos.y = 0;
    output.output_win.win_w = w;
    output.output_win.win_h = h;
    output.user_def_paddr[0] = NULL;// NULL means that a buffer will be allocated

    memset(&handle, 0x00, sizeof(handle));

    // initialise the IPU
    ret = mxc_ipu_lib_task_init(&input, NULL, &output,
                                            OP_NORMAL_MODE,
                                            &handle);

    // print the addresses and sizes of the buffers that the IPU allocated
    printf("mxc_ipu_lib_task_init ret:%d"
            " inbuf_start: 0x%X outbuf_start: 0x%X\n"
            " ifr_size: %d ofr_size: %d\n",
              ret,
              (unsigned int)handle.inbuf_start[0], (unsigned int)handle.outbuf_start[0],
              handle.ifr_size, handle.ofr_size);

    // NOTE the printf above ALWAYS prints out (though addresses might change):
    // "mxc_ipu_lib_task_init ret:0 inbuf_start: 0x2B6A0000 outbuf_start: 0x2B76B000"
    // " ifr_size: 829440 ofr_size: 829440

    if (ret == 0) // zero means the init worked
    {
      printf("DOING IPU TASK\n");

      // set the IPU input buffer to all 0xFF
      memset(handle.inbuf_start[0], 0xFF, handle.ifr_size);

      // before executing the task, print some of the outbuffer contents
      ptr = (unsigned char *)handle.outbuf_start[0];
      printf("outbuf before: ");
      for (i = 0; i < 10; i++, ptr++)
        printf("%02X ", *ptr);
      printf("\n");
      // the printf above ALWAYS prints out:
      // "outbuf before: 00 00 00 00 00 00 00 00 00 00"

      // execute the task
      ret = mxc_ipu_lib_task_buf_update(&handle, NULL, 0, 0, NULL, NULL);

      printf("loop:%d, mxc_ipu_lib_task_buf_update returned:%d\n", loop, ret);

      // now print some outbuf contents after the task
      ptr = (unsigned char *)handle.outbuf_start[0];
      if (*ptr)// check for any non-zero value in output
         printf("************* IPU DID CONVERT *************\n");// very rarely prints this!
      printf("outbuf after: ");
      for (i = 0; i < 10; i++, ptr++)
         printf("%02X ", *ptr);
      printf("\n");

      // almost every time, the contents of the outbuf here is printed as zero, which is wrong.
      // sometimes, possibly once every 10 attempts, the outbuf contains
      // sequences of 0xDF, 0xFB - which is a correct conversion

    }
    else
    {
      // NOTE: this never gets printed, so the task by implication is always OK
      printf("mxc_ipu_lib_task_init FAILED:%d\n", ret);
      return(0);
    }

    // close the task
    mxc_ipu_lib_task_uninit(&handle);
  }

  return(0);
}

Outcomes