|
| 1 | +#include "config.h" |
| 2 | + |
| 3 | +#ifdef MPI3501 |
| 4 | + |
| 5 | +#include "spi.h" |
| 6 | + |
| 7 | +#include <memory.h> |
| 8 | +#include <stdio.h> |
| 9 | + |
| 10 | +void ChipSelectHigh() |
| 11 | +{ |
| 12 | + WAIT_SPI_FINISHED(); |
| 13 | + CLEAR_GPIO(GPIO_SPI0_CE0); // Enable Touch |
| 14 | + SET_GPIO(GPIO_SPI0_CE0); // Disable Touch |
| 15 | + __sync_synchronize(); |
| 16 | + SET_GPIO(GPIO_SPI0_CE1); // Disable Display |
| 17 | + CLEAR_GPIO(GPIO_SPI0_CE1); // Enable Display |
| 18 | + __sync_synchronize(); |
| 19 | +} |
| 20 | + |
| 21 | +void InitKeDeiV63() |
| 22 | +{ |
| 23 | + // If a Reset pin is defined, toggle it briefly high->low->high to enable the device. Some devices do not have a reset pin, in which case compile with GPIO_TFT_RESET_PIN left undefined. |
| 24 | +#if defined(GPIO_TFT_RESET_PIN) && GPIO_TFT_RESET_PIN >= 0 |
| 25 | + printf("Resetting display at reset GPIO pin %d\n", GPIO_TFT_RESET_PIN); |
| 26 | + SET_GPIO_MODE(GPIO_TFT_RESET_PIN, 1); |
| 27 | + SET_GPIO(GPIO_TFT_RESET_PIN); |
| 28 | + usleep(120 * 1000); |
| 29 | + CLEAR_GPIO(GPIO_TFT_RESET_PIN); |
| 30 | + usleep(120 * 1000); |
| 31 | + SET_GPIO(GPIO_TFT_RESET_PIN); |
| 32 | + usleep(120 * 1000); |
| 33 | +#endif |
| 34 | + |
| 35 | + // For sanity, start with both Chip selects high to ensure that the display will see a high->low enable transition when we start. |
| 36 | + SET_GPIO(GPIO_SPI0_CE0); // Disable Touch |
| 37 | + SET_GPIO(GPIO_SPI0_CE1); // Disable Display |
| 38 | + usleep(1000); |
| 39 | + |
| 40 | + // Do the initialization with a very low SPI bus speed, so that it will succeed even if the bus speed chosen by the user is too high. |
| 41 | + spi->clk = 34; |
| 42 | + __sync_synchronize(); |
| 43 | + |
| 44 | + BEGIN_SPI_COMMUNICATION(); |
| 45 | + { |
| 46 | + CLEAR_GPIO(GPIO_SPI0_CE0); // Enable Touch |
| 47 | + CLEAR_GPIO(GPIO_SPI0_CE1); // Enable Display |
| 48 | + |
| 49 | + BEGIN_SPI_COMMUNICATION(); |
| 50 | + |
| 51 | + usleep(25*1000); |
| 52 | + |
| 53 | + SET_GPIO(GPIO_SPI0_CE0); // Disable Touch |
| 54 | + usleep(25*1000); |
| 55 | + |
| 56 | + SPI_TRANSFER(0x00000000); // This command seems to be Reset |
| 57 | + usleep(120*1000); |
| 58 | + |
| 59 | + SPI_TRANSFER(0x00000100); |
| 60 | + usleep(50*1000); |
| 61 | + SPI_TRANSFER(0x00001100); |
| 62 | + usleep(60*1000); |
| 63 | + |
| 64 | + SPI_TRANSFER(0xB9001100, 0x00, 0xFF, 0x00, 0x83, 0x00, 0x57); |
| 65 | + usleep(5*1000); |
| 66 | + |
| 67 | + SPI_TRANSFER(0xB6001100, 0x00, 0x2C); |
| 68 | + SPI_TRANSFER(0x11001100/*Sleep Out*/); |
| 69 | + usleep(150*1000); |
| 70 | + |
| 71 | + SPI_TRANSFER(0x3A001100/*Interface Pixel Format*/, 0x00, 0x55); |
| 72 | + SPI_TRANSFER(0xB0001100, 0x00, 0x68); |
| 73 | + SPI_TRANSFER(0xCC001100, 0x00, 0x09); |
| 74 | + SPI_TRANSFER(0xB3001100, 0x00, 0x43, 0x00, 0x00, 0x00, 0x06, 0x00, 0x06); |
| 75 | + SPI_TRANSFER(0xB1001100, 0x00, 0x00, 0x00, 0x15, 0x00, 0x1C, 0x00, 0x1C, 0x00, 0x83, 0x00, 0x44); |
| 76 | + SPI_TRANSFER(0xC0001100, 0x00, 0x24, 0x00, 0x24, 0x00, 0x01, 0x00, 0x3C, 0x00, 0x1E, 0x00, 0x08); |
| 77 | + SPI_TRANSFER(0xB4001100, 0x00, 0x02, 0x00, 0x40, 0x00, 0x00, 0x00, 0x2A, 0x00, 0x2A, 0x00, 0x0D, 0x00, 0x4F); |
| 78 | + SPI_TRANSFER(0xE0001100, 0x00, 0x02, 0x00, 0x08, 0x00, 0x11, 0x00, 0x23, 0x00, 0x2C, 0x00, 0x40, 0x00, 0x4A, 0x00, 0x52, 0x00, 0x48, 0x00, 0x41, 0x00, 0x3C, 0x00, 0x33, 0x00, 0x2E, 0x00, 0x28, 0x00, 0x27, 0x00, 0x1B, 0x00, 0x02, 0x00, 0x08, 0x00, 0x11, 0x00, 0x23, 0x00, 0x2C, 0x00, 0x40, 0x00, 0x4A, 0x00, 0x52, 0x00, 0x48, 0x00, 0x41, 0x00, 0x3C, 0x00, 0x33, 0x00, 0x2E, 0x00, 0x28, 0x00, 0x27, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x01); |
| 79 | + |
| 80 | +#define MADCTL_BGR_PIXEL_ORDER (1<<3) |
| 81 | +#define MADCTL_ROW_COLUMN_EXCHANGE (1<<5) |
| 82 | +#define MADCTL_COLUMN_ADDRESS_ORDER_SWAP (1<<6) |
| 83 | +#define MADCTL_ROW_ADDRESS_ORDER_SWAP (1<<7) |
| 84 | +#define MADCTL_ROTATE_180_DEGREES (MADCTL_COLUMN_ADDRESS_ORDER_SWAP | MADCTL_ROW_ADDRESS_ORDER_SWAP) |
| 85 | + |
| 86 | + uint8_t madctl = 0; |
| 87 | +#ifndef DISPLAY_SWAP_BGR |
| 88 | + madctl |= MADCTL_BGR_PIXEL_ORDER; |
| 89 | +#endif |
| 90 | +#if defined(DISPLAY_FLIP_ORIENTATION_IN_HARDWARE) |
| 91 | + madctl |= MADCTL_ROW_COLUMN_EXCHANGE; |
| 92 | +#endif |
| 93 | +#ifdef DISPLAY_ROTATE_180_DEGREES |
| 94 | + madctl ^= MADCTL_ROTATE_180_DEGREES; |
| 95 | +#endif |
| 96 | + SPI_TRANSFER(0x36001100/*MADCTL: Memory Access Control*/, 0x00, madctl); |
| 97 | + |
| 98 | + SPI_TRANSFER(0x29001100/*Display ON*/); |
| 99 | + |
| 100 | + usleep(200*1000); |
| 101 | + |
| 102 | + ClearScreen(); |
| 103 | + } |
| 104 | +#ifndef USE_DMA_TRANSFERS // For DMA transfers, keep SPI CS & TA active. |
| 105 | + END_SPI_COMMUNICATION(); |
| 106 | +#endif |
| 107 | + |
| 108 | + // And speed up to the desired operation speed finally after init is done. |
| 109 | + usleep(10 * 1000); // Delay a bit before restoring CLK, or otherwise this has been observed to cause the display not init if done back to back after the clear operation above. |
| 110 | + spi->clk = SPI_BUS_CLOCK_DIVISOR; |
| 111 | +} |
| 112 | + |
| 113 | +void TurnBacklightOff() |
| 114 | +{ |
| 115 | +} |
| 116 | + |
| 117 | +void TurnBacklightOn() |
| 118 | +{ |
| 119 | +} |
| 120 | + |
| 121 | +void TurnDisplayOff() |
| 122 | +{ |
| 123 | +} |
| 124 | + |
| 125 | +void TurnDisplayOn() |
| 126 | +{ |
| 127 | +} |
| 128 | + |
| 129 | +void DeinitSPIDisplay() |
| 130 | +{ |
| 131 | + ClearScreen(); |
| 132 | + TurnDisplayOff(); |
| 133 | +} |
| 134 | + |
| 135 | +#endif |
0 commit comments