Jump to content

zump

Members
  • Posts

    1
  • Joined

  • Last visited

Posts posted by zump

  1. I am trying to get the Sharp LCD LS010B7DH01 working with uGFX, ChibiOS 2.6.1 and STM32L151CB. It is quite a basic display. There are no special features, and one can write lines to the memory with the following SPI bytestream.

    Write command byte, line address, 16 bytes of pixel data, 2 dummy bytes. http://www.avnet-embedded.eu/fileadmin/user_upload/Files/Displays/Mono/Sharp_LS010B7DH01.pdf (Datasheet)

    Here are relevant excerpts from gdisp_lld_*.c


    /*===========================================================================*/
    /* Driver local definitions. */
    /*===========================================================================*/

    #ifndef GDISP_SCREEN_HEIGHT
    #define GDISP_SCREEN_HEIGHT 128 // This controller should support 32 (untested) or 64
    #endif
    #ifndef GDISP_SCREEN_WIDTH
    #define GDISP_SCREEN_WIDTH 128
    #endif


    #define LS010_LINE_WIDTH GDISP_SCREEN_WIDTH/8

    #define GDISP_FLG_NEEDFLUSH (GDISP_FLG_DRIVER<<0)

    #include "LS010.h"

    /*===========================================================================*/
    /* Driver local functions. */
    /*===========================================================================*/

    // Some common routines and macros
    #define RAM(g) ((uint8_t *)g->priv)

    // Some common routines and macros
    #define delay(us) gfxSleepMicroseconds(us)
    #define delayms(ms) gfxSleepMilliseconds(ms)

    #define xyaddr(x, y) (x + y * GDISP_SCREEN_WIDTH) / 8
    #define xybit(x, y) (1 << ((x + y * GDISP_SCREEN_WIDTH) % 8))
    /*===========================================================================*/
    /* Driver exported functions. */
    /*===========================================================================*/

    LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
    // The private area is the display surface.
    g->priv = gfxAlloc(2048);

    lcd_init(&handle_lcd); // <--- My initialisation function which successfully turns LCD on

    acquire_bus(g);

    // Finish Init
    post_init_board(g);

    // Release the bus
    release_bus(g);

    /* Initialise the GDISP structure */
    g->g.Width = GDISP_SCREEN_WIDTH;
    g->g.Height = GDISP_SCREEN_HEIGHT;
    g->g.Orientation = GDISP_ROTATE_0;
    g->g.Powermode = powerOn;
    g->g.Backlight = GDISP_INITIAL_BACKLIGHT;
    g->g.Contrast = GDISP_INITIAL_CONTRAST;
    return TRUE;
    }

    #if GDISP_HARDWARE_FLUSH
    LLDSPEC void gdisp_lld_flush(GDisplay *g) {
    unsigned i;
    uint8_t j = 128; //Address

    // Don't flush if we don't need it.
    if (!(g->flags & GDISP_FLG_NEEDFLUSH))
    return;

    for(i=0; i < 2048; i += LS010_LINE_WIDTH)
    {
    write_data(g, RAM(g)+i, LS010_LINE_WIDTH, j);
    j--;
    }
    }
    #endif

    #if GDISP_HARDWARE_DRAWPIXEL
    LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) {
    coord_t x, y;
    int tmpx = xyaddr(g->p.x, g->p.y);
    int bit = xybit(g->p.x,g->p.y);

    switch(g->g.Orientation) {
    default:
    case GDISP_ROTATE_0:
    x = g->p.x;
    y = g->p.y;
    break;
    case GDISP_ROTATE_90:
    x = g->p.y;
    y = GDISP_SCREEN_HEIGHT-1 - g->p.x;
    break;
    case GDISP_ROTATE_180:
    x = GDISP_SCREEN_WIDTH-1 - g->p.x;
    y = GDISP_SCREEN_HEIGHT-1 - g->p.y;
    break;
    case GDISP_ROTATE_270:
    x = GDISP_SCREEN_HEIGHT-1 - g->p.y;
    x = g->p.x;
    break;
    }
    if (gdispColor2Native(g->p.color) != Black)
    {
    RAM(g)[xyaddr(x, y)] &= xybit(x,y);
    }else {
    RAM(g)[xyaddr(x, y)] |= ~xybit(x,y);
    g->flags |= GDISP_FLG_NEEDFLUSH;
    }
    }
    #endif

    and and board_*.h


    static uint8_t reverse(uint8_t b) {
    b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
    b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
    b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
    return b;
    }

    static inline void write_data(GDisplay *g, uint8_t* data, uint16_t length, uint8_t addr) {
    (void) g;

    uint8_t tmp[20] = {0}; // Command to write + address + 16 byte pixel data + 2 dummy bytes
    tmp[0] = 0b10000000; // Command to write
    tmp[1] = reverse(addr); // LSB first

    memmove(tmp+2, data, 16);

    spiUnselect(&SPID1);
    chThdSleepMicroseconds(SCS_HIGH_DELAY);
    spiSend(&SPID1, 20, tmp);
    chThdSleepMicroseconds(SCS_LOW_DELAY);
    spiSelect(&SPID1);
    chThdSleepMicroseconds(INTERFRAME_DELAY);
    }

    However, I am not able to get correct output. For example, here is the output when running the 'basics' example.

    mZdT8Hc.jpg

    Can anyone see something wrong here?

×
×
  • Create New...