0
\$\begingroup\$

I bought this from aliexpress: https://www.aliexpress.com/item/32859042892.html It seems to be a good display, even a bit higher res, than advertised, however, I'm having trouble doing anything more than just clearing the display. The pixel I set, just before the endless while loop, does not change color. Nor does PixelTest work. What could be wrong here? In addition.. there's this weird magic nr in the clear display function's for that I have no idea, how much it should exactly be...

Here's the code I'm using

spilcd.h

#include "spi.h"

#define DCPORT PORTC
#define DCDDR DDRC
#define DCDDRPIN DDC2
#define DCPIN PINC2

#define RSTPORT PORTC
#define RSTDDR DDRC
#define RSTDDRPIN DDC3
#define RSTPIN PINC3
#define NORON 0x13
#define SWRESET 0x01 // software reset
#define SLPOUT 0x11 // sleep out
#define DISPOFF 0x28 // display off
#define DISPON 0x29 // display on
#define CASET 0x2A // column address set
#define RASET 0x2B // row address set
#define RAMWR 0x2C // RAM write
#define MADCTL 0x36 // axis control
#define COLMOD 0x3A // color mode

// Color constants
#define BLACK 0x0000
#define BLUE 0x001F
#define RED 0xF800
#define GREEN 0x0400
#define LIME 0x07E0
#define CYAN 0x07FF
#define MAGENTA 0xF81F
#define YELLOW 0xFFE0
#define WHITE 0xFFFF

void write_cmd(uint8_t  command) {
    DCPORT &= ~(1 << DCPIN);
    send_recieve_spi_byte(command);
    DCPORT |= (1 << DCPIN);
}

void write_word (uint16_t w)
{
 send_recieve_spi_byte(w >> 8); // write upper 8 bits
 send_recieve_spi_byte(w & 0xFF); // write lower 8 bits
}

void hardware_reset() {
    RSTPORT &= ~(1<< RSTPIN);
    _delay_ms(1);
    RSTPORT |= (1<< RSTPIN);
    _delay_ms(200);
}


void initialize_lcd() {
    DCDDR |= (1 << DCDDRPIN);
    RSTDDR |= (1 << RSTDDRPIN);

    DCPORT |= (1 << DCPIN);
    RSTPORT |= (1<< RSTPIN);

    hardware_reset();

    write_cmd(SLPOUT);
    _delay_ms(150);
    write_cmd(COLMOD);
    write_cmd(0x05);
}


void set_addr_window(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1)
{
    write_cmd(CASET); // set column range (x0,x1)
    write_word(x0);
    write_word(x1);
    write_cmd(RASET); // set row range (y0,y1)
    write_word(y0);
    write_word(y1);
}

void clear_screen()
{
    set_addr_window(0,0,110, 160); // set window to entire display
    write_cmd(RAMWR);
    for (unsigned int i=53800;i>0;--i) // byte count = some magic number
    {
       send_recieve_spi_byte(0);
    }
}

spi.h

uint8_t send_recieve_spi_byte(uint8_t data)
{
    PORTB &= ~(1 << PINB2);
    // Load data into the buffer
    SPDR = data;
    //Wait until transmission complete
    while(!(SPSR & (1<<SPIF) ));
    PORTB |= (1 << PINB2);
    // Return received data
    return(SPDR);
}

void init_spi_oneway() {
    DDRB = (1 << DDB2) | (1 << DDB3) | (1 << DDB5);
    SPCR=(1<<SPE)|(1<<MSTR)|(1<<SPR0);
        PORTB |= (1 << PINB2);
   // SPCR = 0x50;
}

void init_spi_twoway() {
    DDRB &= ~(1 << DDB4);
    init_spi_oneway();
}

main.c

/*
 */

#include <avr/io.h>
#include <util/delay.h>
#include "spilcd.h"
#include <stdint.h>
#include <stdlib.h>
void Write565 (uint16_t data, uint16_t count)
{
 while(count--)
 {
    send_recieve_spi_byte(data >> 8);
    send_recieve_spi_byte(data & 0xFF);
}
}

void DrawPixel (uint8_t x, uint8_t y, uint16_t color)
{
 set_addr_window(x,y,x,y); // set active region = 1 pixel
 write_cmd(RAMWR); // memory write
 Write565(color,1); // send color for this pixel
}

void PixelTest()
// draws 4000 pixels on the screen
{
 for (int i=4000; i>0; i--) // do a whole bunch:
 {
 int x = rand() % 110; // random x coordinate
 int y = rand() % 160; // random y coordinate
 DrawPixel(x,y,RED); // draw pixel at x,y
 }
}


int main() {

    init_spi_oneway();
    initialize_lcd();
    write_cmd(DISPON);
    clear_screen();

    PixelTest();
    while(1) {

    }

    return 0;
}
\$\endgroup\$
  • \$\begingroup\$ 1. What is the "magic" number. It is screen size * 3 in 3 bytes per pixel mode. The number is actually 52800 and IMO 53800 is just typo. 2. Screen resolution is not 110x160 but 80x160 if it makes any difference to you Assuming that the rest of the code is written with the same care - I am not surprised that it will not work \$\endgroup\$ – P__J__ Sep 29 at 19:29
  • \$\begingroup\$ @P__J__ if the resolution is indeed as advertised, and 80x160, then please explain why 110x160 fills the display, while 80x160 does not ? \$\endgroup\$ – Rando Hinn Sep 29 at 19:35
  • 1
    \$\begingroup\$ Simple answer = bad code. \$\endgroup\$ – P__J__ Sep 29 at 19:42
0
\$\begingroup\$

Figured it out. The LCD seems to have a front porch of 26px in the X direction. I was also sending the color mode in as a command, not data, by mistake.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.