Jump to content
Pratham

uGFX BLIT API for RA8875

Recommended Posts

Hi,

I am using uGFX on Raspberry Pi for displaying graphics on RA8875 based display. Raspberry Pi communicates with display using 4-wire SPI. I am porting the gdisp_lld_blit_area() driver API using  BTE (block transfer engine) available in RA8875. I am using write-BTE operation mode with ROP (raster operation) as destination = source.

Here is my sample code with this post. screenshots of expected and actual output is also attached. any suggestions/recommendations would be helpful.

#if 1//GDISP_HARDWARE_BITFILLS || defined(__DOXYGEN__)

// macros
#define RA8875_MRWC             0x02
#define RA8875_BECR0            0x50
#define RA8875_BECR1            0x51
#define RA8875_HDBE0            0x58
#define RA8875_HDBE1            0x59
#define RA8875_VDBE0            0x5A
#define RA8875_VDBE1            0x5B
#define RA8875_BEWR0            0x5C
#define RA8875_BEWR1            0x5D
#define RA8875_BEHR0            0x5E
#define RA8875_BEHR1            0x5F
#define RA8875_BGCR0            0x60  // = red, next 2 are green and blue
#define RA8875_FGCR0            0x63  // = red, next 2 are green and blue
#define RA8875_MWCR0            0x40
#define RA8875_MWCR0_GFXMODE    0x00
#define RA8875_MWCR0_TXTMODE    0x80
#define RA8875_MWCR1            0x41
#define RA8875_CURH0            0x46
#define RA8875_CURH1            0x47
#define RA8875_CURV0            0x48
#define RA8875_CURV1            0x49

/**
 * @brief   Function to draw bitmap
 * @pre        GDISP_HARDWARE_BITFILLS is GFXON
 *
 * @param[in]    g                The driver structure
 * @param[in]    destX,destY        The area position
 * @param[in]    width,height    The area size i.e. width and height
 * @param[in]    fgColor            The foreground color
 * @param[in]    bgColor            The background color
 * @param[in]    bits            The pointer to the bitmap
 *
 * @note        The parameter variables must not be altered by the driver.
*/
static GFXINLINE void drawBitmap(GDisplay *g,
        gI16 destX, gI16 destY,
        gI16 width, gI16 height,
        gU16 fgColor, gU16 bgColor,
        gU8* bits)
{
    // locals
    gI32 h = 0, w = 0;
    gU8 temp = 0, tempbkp = 0;
    static gU32 cnt = 0;

    /*printf("\ndraw bitmap: x=%d y=%d w=%d h=%d "
            "x1=%d y1=%d x2=%d y2=%d "
            "fg=%x bg=%x cnt=%d",
            destX, destY, width, height,
            g->p.x1, g->p.y1, g->p.x2, g->p.y2,
            fgColor, bgColor, ++cnt);
            */

    // always enter graphics mode for BTE operations
    write_index(g, RA8875_MWCR0);
    temp = (gU8)read_data(g);
    tempbkp = temp;
    temp &= ~RA8875_MWCR0_TXTMODE;
    write_data(g, temp);

    // set destination, width and height
    write_reg16(g, RA8875_HDBE0, destX);
    write_reg16(g, RA8875_VDBE0, destY);
    write_reg16(g, RA8875_BEWR0, width);  // image width
    write_reg16(g, RA8875_BEHR0, height); // image height

    // set colors
    writeColorReg(g, RA8875_BGCR0, bgColor);
    writeColorReg(g, RA8875_FGCR0, fgColor);

    // set cursor position
    write_reg16(g, RA8875_CURH0, destX);
    write_reg16(g, RA8875_CURV0, destY);

    // BTE operation mode
    // Bits [3:0] 1000b is color expansion 0000b is write-BTE
    // Bits [7:4] 0111b is start bit position for color expansion
    // Bits [7:4] 1100b is S=D for write-BTE
    //write_reg8(g, RA8875_BECR1, (0x07 << 4) | 0x08);  // start bit = 7, operation = Color Expansion
    write_reg8(g, RA8875_BECR1, 0xC0); // write-BTE with ROP as S=D

    // draw in block mode 0x80, in linear mode 0xE0
    write_reg8(g, RA8875_BECR0, 0x80);  // begin operation

    // write command
    write_index(g, RA8875_MRWC);

    // write data
    for (h = 0; h < height; h++)
    {
        //printf("\nh=%d -- ", h);
        for (w = 0; w < width; w += 1)
        {
            //printf("%u ", *bits);
            //usleep(1000);
            write_data(g, *bits++);
        }
    }

    // set text mode NOTE: this may not be needed to
    write_index(g, RA8875_MWCR0);
    //tempbkp = (gU8)read_data(g);
    //tempbkp |= RA8875_MWCR0_TXTMODE; // Set bit 7
    write_data(g, tempbkp);

    //return from function
    return;
}

/**
 * @brief   Fill an area using a bitmap
 * @pre        GDISP_HARDWARE_BITFILLS is GFXON
 *
 * @param[in]    g                The driver structure
 * @param[in]    g->p.x,g->p.y    The area position
 * @param[in]    g->p.cx,g->p.cy    The area size
 * @param[in]    g->p.x1,g->p.y1    The starting position in the bitmap
 * @param[in]    g->p.x2            The width of a bitmap line
 * @param[in]    g->p.ptr        The pointer to the bitmap
 *
 * @note        The parameter variables must not be altered by the driver.
 */
LLDSPEC    void gdisp_lld_blit_area(GDisplay *g)
{
    if((void *)0 == g)
    {
        //invalid pointer, return from function
        return;
    }

    // draw the bitmap
    // 0xFFFF is white
    // 0x0000 is black
    drawBitmap(g, g->p.x, g->p.y, g->p.cx*2, g->p.cy,
            g->p.color, 0x0000, g->p.ptr);

    //return from function
    return;
}
#endif /* use BLIT */

actual-output.jpg

expected-output.bmp

expected-output.jpg

blit.c

Share this post


Link to post
Share on other sites

The problem is that you are assuming that the source and destination bitmaps have the same line width or that you are even drawing the full width of the source bitmap.

Note CX != X2. Similarly you are not using the starting position x1,y1 for the source bitmap.

Passing the extra info to your draw routine you should be able to recode the X,y loop to fix the problem.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×