#include #include #include #include #include #include #include #include #include #include typedef struct { const uint8_t *data; uint16_t width; uint16_t height; } tImage; #include "mojo.h" #include "marc.h" #include "grin.h" #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) static void pabort(const char *s) { perror(s); abort(); } static const char *device = "/dev/spidev0.1"; static uint8_t mode; static uint8_t bits = 8; static uint32_t speed = 20000000; static uint16_t delay; int fd; void init_gpios() { system("echo 24 > /sys/class/gpio/export"); system("echo out > /sys/class/gpio/gpio24/direction"); system("echo 25 > /sys/class/gpio/export"); system("echo out > /sys/class/gpio/gpio25/direction"); } void Reset() { system("echo 0 > /sys/class/gpio/gpio25/value"); usleep(150); system("echo 1 > /sys/class/gpio/gpio25/value"); usleep(150); } void write_command(uint8_t *command) { int ret; system("echo 0 > /sys/class/gpio/gpio24/value"); // dc=0 struct spi_ioc_transfer tr = { .tx_buf = (unsigned long)command, .len = 1, .delay_usecs = delay, .speed_hz = speed, .bits_per_word = bits, }; ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); if (ret < 1) pabort("can't send spi message"); } void write_data(uint8_t *data, size_t tam) { int ret; system("echo 1 > /sys/class/gpio/gpio24/value"); // dc=0 struct spi_ioc_transfer tr = { .tx_buf = (unsigned long)data, .len = tam, .delay_usecs = delay, .speed_hz = speed, .bits_per_word = bits, }; ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); if (ret < 1) pabort("can't send spi message"); } void write_data2(uint8_t *data, size_t tam) { int ret; struct spi_ioc_transfer tr = { .tx_buf = (unsigned long)data, .len = tam, .delay_usecs = delay, .speed_hz = speed, .bits_per_word = bits, }; ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); if (ret < 1) pabort("can't send spi message"); } void lcd_init() { unsigned int i=0, k=0; printf("inicializando lcd\n"); printf("lcd reset....."); Reset(); printf("[ok]\n"); //-------------------Software Reset-------------------------------// printf("lcd setextc....."); write_command((uint8_t[]){0xB9}); write_data( (uint8_t[]){0xFF, 0x83, 0x53}, 3 ); printf("[ok]\n"); printf("lcd radj....."); write_command((uint8_t[]){0xB0});//RADJ write_data( (uint8_t[]){0x3C, 0x01}, 2 ); printf("[ok]\n"); printf("lcd vcom....."); write_command((uint8_t[]){0xB6});//VCOM define el high level voltage write_data( (uint8_t[]){0x94, 0x6C, 0x50}, 3 ); printf("[ok]\n"); printf("lcd pwr....."); write_command((uint8_t[]){0xB1});//PWR set power control write_data( (uint8_t[]) {0x00, 0x01, 0x1B, 0x03, 0x01, 0x08, 0x77, 0x89}, 8); printf("[ok]\n"); printf("lcd gamma....."); write_command((uint8_t[]){0xE0}); //Gamma setting for tpo Panel write_data( (uint8_t[]) {0x50, 0x77, 0x40, 0x08, 0xBF, 0x00, 0x03, 0x0F, 0x00, 0x01, 0x73, 0x00, 0x72, 0x03, 0xB0, 0x0F, 0x08, 0x00, 0x0F, 0x3A, 0x05}, 21 ); printf("[ok]\n"); usleep(150); write_command((uint8_t[]){0x3A}); // interface pixel format write_data((uint8_t[]){0x05},1); // 16 Bit/Pixel usleep(150); write_command((uint8_t[]){0x36}); // memory access control write_data( (uint8_t[]) {0x70}, 1 ); // controla la dirección en que se recorre printf("[ok]\n"); // la memoria interna al volcar a pantalla printf("lcd slpout....."); write_command((uint8_t[]){0x11}); // SLPOUT sleep out. Sale del modo sleep printf("[ok]\n"); usleep(150); printf("lcd on....."); write_command((uint8_t[]){0x29}); // display on printf("[ok]\n"); usleep(150); printf("lcd lookup table....."); uint8_t lookup[128]; write_command((uint8_t[]){0x2D}); //Look up table for(i=0;i<32;i++) lookup[k++] = 2*i; for(i=0;i<64;i++) lookup[k++] = i; for(i=0;i<32;i++) lookup[k++] = 2*i; write_data( lookup, 128 ); printf("[ok]\n"); usleep(150); write_command((uint8_t[]){0x2A}); write_data((uint8_t[]){0x00, 0x00, 0x00, 159}, 4); write_command((uint8_t[]){0x2B}); write_data((uint8_t[]){0x00, 0x00, 0x00, 127}, 4); printf("lcd inicializado\n"); } void lcd_fill(unsigned int color) { unsigned int i, j, k=0; uint8_t tx[320]; for (i = 0; i < 160; i++) { tx[k++] = color>>8; tx[k++] = color&0xff; } write_command((uint8_t[]){0x2C}); //Memory write system("echo 1 > /sys/class/gpio/gpio24/value"); // dc=0 for (i = 0; i < 128; i++) write_data2(tx, 320); write_command((uint8_t[]){0x00}); } void show_image( const unsigned char img[] ) { unsigned int i, j, k=0; uint8_t tx[320]; write_command((uint8_t[]){0x2C}); //Memory write system("echo 1 > /sys/class/gpio/gpio24/value"); // dc=0 for (i = 0; i < 128; i++) { memcpy( tx, img+(320*i), 320 ); write_data2( tx, 320 ); } write_command((uint8_t[]){0x00}); } static void print_usage(const char *prog) { printf("Usage: %s [-DsbdlHOLC3]\n", prog); puts(" -D --device device to use (default /dev/spidev0.1)\n" " -s --speed max speed (Hz)\n" " -d --delay delay (usec)\n" " -b --bpw bits per word \n" " -l --loop loopback\n" " -H --cpha clock phase\n" " -O --cpol clock polarity\n" " -L --lsb least significant bit first\n" " -C --cs-high chip select active high\n" " -3 --3wire SI/SO signals shared\n"); exit(1); } static void parse_opts(int argc, char *argv[]) { while (1) { static const struct option lopts[] = { { "device", 1, 0, 'D' }, { "speed", 1, 0, 's' }, { "delay", 1, 0, 'd' }, { "bpw", 1, 0, 'b' }, { "loop", 0, 0, 'l' }, { "cpha", 0, 0, 'H' }, { "cpol", 0, 0, 'O' }, { "lsb", 0, 0, 'L' }, { "cs-high", 0, 0, 'C' }, { "3wire", 0, 0, '3' }, { "no-cs", 0, 0, 'N' }, { "ready", 0, 0, 'R' }, { NULL, 0, 0, 0 }, }; int c; c = getopt_long(argc, argv, "D:s:d:b:lHOLC3NR", lopts, NULL); if (c == -1) break; switch (c) { case 'D': device = optarg; break; case 's': speed = atoi(optarg); break; case 'd': delay = atoi(optarg); break; case 'b': bits = atoi(optarg); break; case 'l': mode |= SPI_LOOP; break; case 'H': mode |= SPI_CPHA; break; case 'O': mode |= SPI_CPOL; break; case 'L': mode |= SPI_LSB_FIRST; break; case 'C': mode |= SPI_CS_HIGH; break; case '3': mode |= SPI_3WIRE; break; case 'N': mode |= SPI_NO_CS; break; case 'R': mode |= SPI_READY; break; default: print_usage(argv[0]); break; } } } int main(int argc, char *argv[]) { int ret = 0, i; parse_opts(argc, argv); fd = open(device, O_RDWR); if (fd < 0) pabort("can't open device"); /* * spi mode */ ret = ioctl(fd, SPI_IOC_WR_MODE, &mode); if (ret == -1) pabort("can't set spi mode"); ret = ioctl(fd, SPI_IOC_RD_MODE, &mode); if (ret == -1) pabort("can't get spi mode"); /* * bits per word */ ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits); if (ret == -1) pabort("can't set bits per word"); ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits); if (ret == -1) pabort("can't get bits per word"); /* * max speed hz */ ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); if (ret == -1) pabort("can't set max speed hz"); ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed); if (ret == -1) pabort("can't get max speed hz"); printf("spi mode: %d\n", mode); printf("bits per word: %d\n", bits); printf("max speed: %d Hz (%d KHz)\n", speed, speed/1000); init_gpios(); lcd_init(); lcd_fill(0x0000); while(1) { for(i=0; i<20; i++) { show_image(marc); show_image(mojo); show_image(grin); } lcd_fill(0x0000); } close(fd); return ret; }