Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of EALib by
LcdController.cpp@0:0fdadbc3d852, 2013-09-26 (annotated)
- Committer:
- embeddedartists
- Date:
- Thu Sep 26 06:37:02 2013 +0000
- Revision:
- 0:0fdadbc3d852
- Child:
- 4:b32cf4ef45c5
First version
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| embeddedartists | 0:0fdadbc3d852 | 1 | |
| embeddedartists | 0:0fdadbc3d852 | 2 | #include "mbed.h" |
| embeddedartists | 0:0fdadbc3d852 | 3 | #include "LcdController.h" |
| embeddedartists | 0:0fdadbc3d852 | 4 | |
| embeddedartists | 0:0fdadbc3d852 | 5 | #undef _SBF |
| embeddedartists | 0:0fdadbc3d852 | 6 | #define _SBF(p,v) (((uint32_t)(v)) << (p)) |
| embeddedartists | 0:0fdadbc3d852 | 7 | |
| embeddedartists | 0:0fdadbc3d852 | 8 | #undef _BITMASK |
| embeddedartists | 0:0fdadbc3d852 | 9 | #define _BITMASK(field_width) (_BIT(field_width) - 1) |
| embeddedartists | 0:0fdadbc3d852 | 10 | |
| embeddedartists | 0:0fdadbc3d852 | 11 | #undef _BIT |
| embeddedartists | 0:0fdadbc3d852 | 12 | #define _BIT(p) (((uint32_t)(1)) << (p)) |
| embeddedartists | 0:0fdadbc3d852 | 13 | |
| embeddedartists | 0:0fdadbc3d852 | 14 | /*********************************************************************** |
| embeddedartists | 0:0fdadbc3d852 | 15 | * Color LCD controller horizontal axis plane control register definitions |
| embeddedartists | 0:0fdadbc3d852 | 16 | **********************************************************************/ |
| embeddedartists | 0:0fdadbc3d852 | 17 | |
| embeddedartists | 0:0fdadbc3d852 | 18 | /* LCD controller horizontal axis plane control register pixels per line */ |
| embeddedartists | 0:0fdadbc3d852 | 19 | #define CLCDC_LCDTIMING0_PPL_WIDTH 6 |
| embeddedartists | 0:0fdadbc3d852 | 20 | #define CLCDC_LCDTIMING0_PPL(n) _SBF(2, (((n) / 16) - 1) & _BITMASK(CLCDC_LCDTIMING0_PPL_WIDTH)) |
| embeddedartists | 0:0fdadbc3d852 | 21 | /* LCD controller horizontal axis plane control register HSYNC pulse width */ |
| embeddedartists | 0:0fdadbc3d852 | 22 | #define CLCDC_LCDTIMING0_HSW_WIDTH 8 |
| embeddedartists | 0:0fdadbc3d852 | 23 | #define CLCDC_LCDTIMING0_HSW(n) _SBF(8, ((n) - 1) & _BITMASK(CLCDC_LCDTIMING0_HSW_WIDTH)) |
| embeddedartists | 0:0fdadbc3d852 | 24 | /* LCD controller horizontal axis plane control register horizontal front porch */ |
| embeddedartists | 0:0fdadbc3d852 | 25 | #define CLCDC_LCDTIMING0_HFP_WIDTH 8 |
| embeddedartists | 0:0fdadbc3d852 | 26 | #define CLCDC_LCDTIMING0_HFP(n) _SBF(16, ((n) - 1) & _BITMASK(CLCDC_LCDTIMING0_HFP_WIDTH)) |
| embeddedartists | 0:0fdadbc3d852 | 27 | /* LCD controller horizontal axis plane control register horizontal back porch */ |
| embeddedartists | 0:0fdadbc3d852 | 28 | #define CLCDC_LCDTIMING0_HBP_WIDTH 8 |
| embeddedartists | 0:0fdadbc3d852 | 29 | #define CLCDC_LCDTIMING0_HBP(n) _SBF(24, ((n) - 1) & _BITMASK(CLCDC_LCDTIMING0_HBP_WIDTH)) |
| embeddedartists | 0:0fdadbc3d852 | 30 | |
| embeddedartists | 0:0fdadbc3d852 | 31 | /*********************************************************************** |
| embeddedartists | 0:0fdadbc3d852 | 32 | * Color LCD controller vertical axis plane control register definitions |
| embeddedartists | 0:0fdadbc3d852 | 33 | **********************************************************************/ |
| embeddedartists | 0:0fdadbc3d852 | 34 | |
| embeddedartists | 0:0fdadbc3d852 | 35 | /* LCD controller vertical axis plane control register lines per panel */ |
| embeddedartists | 0:0fdadbc3d852 | 36 | #define CLCDC_LCDTIMING1_LPP_WIDTH 10 |
| embeddedartists | 0:0fdadbc3d852 | 37 | #define CLCDC_LCDTIMING1_LPP(n) _SBF(0, ((n) - 1) & _BITMASK(CLCDC_LCDTIMING1_LPP_WIDTH)) |
| embeddedartists | 0:0fdadbc3d852 | 38 | /* LCD controller vertical axis plane control register VSYNC pulse width */ |
| embeddedartists | 0:0fdadbc3d852 | 39 | #define CLCDC_LCDTIMING1_VSW_WIDTH 6 |
| embeddedartists | 0:0fdadbc3d852 | 40 | #define CLCDC_LCDTIMING1_VSW(n) _SBF(10, ((n) - 1) & _BITMASK(CLCDC_LCDTIMING1_VSW_WIDTH)) |
| embeddedartists | 0:0fdadbc3d852 | 41 | /* LCD controller vertical axis plane control register vertical front porch */ |
| embeddedartists | 0:0fdadbc3d852 | 42 | #define CLCDC_LCDTIMING1_VFP_WIDTH 8 |
| embeddedartists | 0:0fdadbc3d852 | 43 | #define CLCDC_LCDTIMING1_VFP(n) _SBF(16, (n) & _BITMASK(CLCDC_LCDTIMING1_VFP_WIDTH)) |
| embeddedartists | 0:0fdadbc3d852 | 44 | /* LCD controller vertical axis plane control register vertical back porch */ |
| embeddedartists | 0:0fdadbc3d852 | 45 | #define CLCDC_LCDTIMING1_VBP_WIDTH 8 |
| embeddedartists | 0:0fdadbc3d852 | 46 | #define CLCDC_LCDTIMING1_VBP(n) _SBF(24, (n) & _BITMASK(CLCDC_LCDTIMING1_VBP_WIDTH)) |
| embeddedartists | 0:0fdadbc3d852 | 47 | |
| embeddedartists | 0:0fdadbc3d852 | 48 | /*********************************************************************** |
| embeddedartists | 0:0fdadbc3d852 | 49 | * Color LCD controller clock and signal polarity control register definitions |
| embeddedartists | 0:0fdadbc3d852 | 50 | **********************************************************************/ |
| embeddedartists | 0:0fdadbc3d852 | 51 | |
| embeddedartists | 0:0fdadbc3d852 | 52 | /* LCD controller clock and signal polarity control register panel clock divisor low*/ |
| embeddedartists | 0:0fdadbc3d852 | 53 | #define CLCDC_LCDTIMING2_PCD_LO_WIDTH 5 |
| embeddedartists | 0:0fdadbc3d852 | 54 | #define CLCDC_LCDTIMING2_PCD_LO(n) _SBF(0, ((n) - 2) & _BITMASK(CLCDC_LCDTIMING2_PCD_LO_WIDTH)) |
| embeddedartists | 0:0fdadbc3d852 | 55 | /* LCD controller clock and signal polarity control register clock select */ |
| embeddedartists | 0:0fdadbc3d852 | 56 | #define CLCDC_LCDTIMING2_CLKSEL _BIT(5) |
| embeddedartists | 0:0fdadbc3d852 | 57 | /* LCD controller clock and signal polarity control register AC bias pin frequency */ |
| embeddedartists | 0:0fdadbc3d852 | 58 | #define CLCDC_LCDTIMING2_ACB_WIDTH 5 |
| embeddedartists | 0:0fdadbc3d852 | 59 | #define CLCDC_LCDTIMING2_ACB(n) _SBF(6, ((n) - 1) & _BITMASK(CLCDC_LCDTIMING2_ACB_WIDTH)) |
| embeddedartists | 0:0fdadbc3d852 | 60 | /* LCD controller clock and signal polarity control register invert VSYNC */ |
| embeddedartists | 0:0fdadbc3d852 | 61 | #define CLCDC_LCDTIMING2_IVS _BIT(11) |
| embeddedartists | 0:0fdadbc3d852 | 62 | /* LCD controller clock and signal polarity control register invert HSYNC */ |
| embeddedartists | 0:0fdadbc3d852 | 63 | #define CLCDC_LCDTIMING2_IHS _BIT(12) |
| embeddedartists | 0:0fdadbc3d852 | 64 | /* LCD controller clock and signal polarity control register invert plane clock */ |
| embeddedartists | 0:0fdadbc3d852 | 65 | #define CLCDC_LCDTIMING2_IPC _BIT(13) |
| embeddedartists | 0:0fdadbc3d852 | 66 | /* LCD controller clock and signal polarity control register invert output enable */ |
| embeddedartists | 0:0fdadbc3d852 | 67 | #define CLCDC_LCDTIMING2_IOE _BIT(14) |
| embeddedartists | 0:0fdadbc3d852 | 68 | /* LCD controller clock and signal polarity control register clocks per line */ |
| embeddedartists | 0:0fdadbc3d852 | 69 | #define CLCDC_LCDTIMING2_CPL_WIDTH 10 |
| embeddedartists | 0:0fdadbc3d852 | 70 | #define CLCDC_LCDTIMING2_CPL(n) _SBF(16, (n) & _BITMASK(CLCDC_LCDTIMING2_CPL_WIDTH)) |
| embeddedartists | 0:0fdadbc3d852 | 71 | /* LCD controller clock and signal polarity control register bypass pixel clock divider */ |
| embeddedartists | 0:0fdadbc3d852 | 72 | #define CLCDC_LCDTIMING2_BCD _BIT(26) |
| embeddedartists | 0:0fdadbc3d852 | 73 | /* LCD controller clock and signal polarity control register panel clock divisor high*/ |
| embeddedartists | 0:0fdadbc3d852 | 74 | #define CLCDC_LCDTIMING2_PCD_HI_WIDTH 5 |
| embeddedartists | 0:0fdadbc3d852 | 75 | #define CLCDC_LCDTIMING2_PCD_HI(n) _SBF((27 - CLCDC_LCDTIMING2_PCD_LO_WIDTH), ((n) - 2) & _SBF(CLCDC_LCDTIMING2_PCD_LO_WIDTH, _BITMASK(CLCDC_LCDTIMING2_PCD_HI_WIDTH))) |
| embeddedartists | 0:0fdadbc3d852 | 76 | |
| embeddedartists | 0:0fdadbc3d852 | 77 | |
| embeddedartists | 0:0fdadbc3d852 | 78 | /*********************************************************************** |
| embeddedartists | 0:0fdadbc3d852 | 79 | * Color LCD controller control register definitions |
| embeddedartists | 0:0fdadbc3d852 | 80 | **********************************************************************/ |
| embeddedartists | 0:0fdadbc3d852 | 81 | |
| embeddedartists | 0:0fdadbc3d852 | 82 | /* LCD control enable bit */ |
| embeddedartists | 0:0fdadbc3d852 | 83 | #define CLCDC_LCDCTRL_ENABLE (1<<0) |
| embeddedartists | 0:0fdadbc3d852 | 84 | /* LCD control 1 bit per pixel bit field */ |
| embeddedartists | 0:0fdadbc3d852 | 85 | #define CLCDC_LCDCTRL_BPP1 (0 << 1) |
| embeddedartists | 0:0fdadbc3d852 | 86 | /* LCD control 2 bits per pixel bit field */ |
| embeddedartists | 0:0fdadbc3d852 | 87 | #define CLCDC_LCDCTRL_BPP2 (1 << 1) |
| embeddedartists | 0:0fdadbc3d852 | 88 | /* LCD control 4 bits per pixel bit field */ |
| embeddedartists | 0:0fdadbc3d852 | 89 | #define CLCDC_LCDCTRL_BPP4 (2 << 1) |
| embeddedartists | 0:0fdadbc3d852 | 90 | /* LCD control 8 bits per pixel bit field */ |
| embeddedartists | 0:0fdadbc3d852 | 91 | #define CLCDC_LCDCTRL_BPP8 (3 << 1) |
| embeddedartists | 0:0fdadbc3d852 | 92 | /* LCD control 16 bits per pixel bit field */ |
| embeddedartists | 0:0fdadbc3d852 | 93 | #define CLCDC_LCDCTRL_BPP16 (4 << 1) |
| embeddedartists | 0:0fdadbc3d852 | 94 | /* LCD control 24 bits per pixel bit field */ |
| embeddedartists | 0:0fdadbc3d852 | 95 | #define CLCDC_LCDCTRL_BPP24 (5 << 1) |
| embeddedartists | 0:0fdadbc3d852 | 96 | /* LCD control 16 bits (5:6:5 mode) per pixel bit field */ |
| embeddedartists | 0:0fdadbc3d852 | 97 | #define CLCDC_LCDCTRL_BPP16_565_MODE (6 << 1) |
| embeddedartists | 0:0fdadbc3d852 | 98 | /* LCD control 12 bits (4:4:4 mode) per pixel bit field */ |
| embeddedartists | 0:0fdadbc3d852 | 99 | #define CLCDC_LCDCTRL_BPP12_444_MODE (7 << 1) |
| embeddedartists | 0:0fdadbc3d852 | 100 | /* LCD control mono select bit */ |
| embeddedartists | 0:0fdadbc3d852 | 101 | #define CLCDC_LCDCTRL_BW_COLOR (0 << 4) |
| embeddedartists | 0:0fdadbc3d852 | 102 | #define CLCDC_LCDCTRL_BW_MONO (1 << 4) |
| embeddedartists | 0:0fdadbc3d852 | 103 | /* LCD controler TFT select bit */ |
| embeddedartists | 0:0fdadbc3d852 | 104 | #define CLCDC_LCDCTRL_TFT (1 << 5) |
| embeddedartists | 0:0fdadbc3d852 | 105 | /* LCD control monochrome LCD has 4-bit/8-bit select bit */ |
| embeddedartists | 0:0fdadbc3d852 | 106 | #define CLCDC_LCDCTRL_MON8 (1 << 6) |
| embeddedartists | 0:0fdadbc3d852 | 107 | /* LCD control dual panel select bit */ |
| embeddedartists | 0:0fdadbc3d852 | 108 | #define CLCDC_LCDCTRL_DUAL (1 << 7) |
| embeddedartists | 0:0fdadbc3d852 | 109 | /* LCD control RGB or BGR format select bit */ |
| embeddedartists | 0:0fdadbc3d852 | 110 | #define CLCDC_LCDCTRL_RGB (0 << 8) |
| embeddedartists | 0:0fdadbc3d852 | 111 | #define CLCDC_LCDCTRL_BGR (1 << 8) |
| embeddedartists | 0:0fdadbc3d852 | 112 | /* LCD control big-endian byte order select bit */ |
| embeddedartists | 0:0fdadbc3d852 | 113 | #define CLCDC_LCDCTRL_BEBO (1 << 9) |
| embeddedartists | 0:0fdadbc3d852 | 114 | /* LCD control big-endian pixel order within a byte select bit */ |
| embeddedartists | 0:0fdadbc3d852 | 115 | #define CLCDC_LCDCTRL_BEPO (1 << 10) |
| embeddedartists | 0:0fdadbc3d852 | 116 | /* LCD control power enable bit */ |
| embeddedartists | 0:0fdadbc3d852 | 117 | #define CLCDC_LCDCTRL_PWR (1 << 11) |
| embeddedartists | 0:0fdadbc3d852 | 118 | /* LCD control VCOMP interrupt is start of VSYNC */ |
| embeddedartists | 0:0fdadbc3d852 | 119 | #define CLCDC_LCDCTRL_VCOMP_VS (0 << 12) |
| embeddedartists | 0:0fdadbc3d852 | 120 | /* LCD control VCOMP interrupt is start of back porch */ |
| embeddedartists | 0:0fdadbc3d852 | 121 | #define CLCDC_LCDCTRL_VCOMP_BP (1 << 12) |
| embeddedartists | 0:0fdadbc3d852 | 122 | /* LCD control VCOMP interrupt is start of active video */ |
| embeddedartists | 0:0fdadbc3d852 | 123 | #define CLCDC_LCDCTRL_VCOMP_AV (2 << 12) |
| embeddedartists | 0:0fdadbc3d852 | 124 | /* LCD control VCOMP interrupt is start of front porch */ |
| embeddedartists | 0:0fdadbc3d852 | 125 | #define CLCDC_LCDCTRL_VCOMP_FP (3 << 12) |
| embeddedartists | 0:0fdadbc3d852 | 126 | /* LCD control watermark level is 8 or more words free bit */ |
| embeddedartists | 0:0fdadbc3d852 | 127 | #define CLCDC_LCDCTRL_WATERMARK (1 << 16) |
| embeddedartists | 0:0fdadbc3d852 | 128 | |
| embeddedartists | 0:0fdadbc3d852 | 129 | |
| embeddedartists | 0:0fdadbc3d852 | 130 | |
| embeddedartists | 0:0fdadbc3d852 | 131 | bool LcdController::_lcdControllerUsed = false; |
| embeddedartists | 0:0fdadbc3d852 | 132 | |
| embeddedartists | 0:0fdadbc3d852 | 133 | LcdController::LcdController() { |
| embeddedartists | 0:0fdadbc3d852 | 134 | _opened = false; |
| embeddedartists | 0:0fdadbc3d852 | 135 | } |
| embeddedartists | 0:0fdadbc3d852 | 136 | |
| embeddedartists | 0:0fdadbc3d852 | 137 | int LcdController::open(LcdController::Config* cfg) { |
| embeddedartists | 0:0fdadbc3d852 | 138 | if (_lcdControllerUsed) return 1; |
| embeddedartists | 0:0fdadbc3d852 | 139 | if (cfg == NULL) return 1; |
| embeddedartists | 0:0fdadbc3d852 | 140 | |
| embeddedartists | 0:0fdadbc3d852 | 141 | // enable power for LCD controller |
| embeddedartists | 0:0fdadbc3d852 | 142 | LPC_SC->PCONP |= 0x00000001; |
| embeddedartists | 0:0fdadbc3d852 | 143 | |
| embeddedartists | 0:0fdadbc3d852 | 144 | pinConfig(); |
| embeddedartists | 0:0fdadbc3d852 | 145 | init(cfg); |
| embeddedartists | 0:0fdadbc3d852 | 146 | |
| embeddedartists | 0:0fdadbc3d852 | 147 | // only one instance at a time is allowed to be used |
| embeddedartists | 0:0fdadbc3d852 | 148 | _lcdControllerUsed = true; |
| embeddedartists | 0:0fdadbc3d852 | 149 | _opened = true; |
| embeddedartists | 0:0fdadbc3d852 | 150 | |
| embeddedartists | 0:0fdadbc3d852 | 151 | return 0; |
| embeddedartists | 0:0fdadbc3d852 | 152 | } |
| embeddedartists | 0:0fdadbc3d852 | 153 | |
| embeddedartists | 0:0fdadbc3d852 | 154 | int LcdController::close() { |
| embeddedartists | 0:0fdadbc3d852 | 155 | |
| embeddedartists | 0:0fdadbc3d852 | 156 | if (!_opened) return 1; |
| embeddedartists | 0:0fdadbc3d852 | 157 | |
| embeddedartists | 0:0fdadbc3d852 | 158 | if (_lcdControllerUsed) { |
| embeddedartists | 0:0fdadbc3d852 | 159 | |
| embeddedartists | 0:0fdadbc3d852 | 160 | // disable power for LCD controller |
| embeddedartists | 0:0fdadbc3d852 | 161 | LPC_SC->PCONP &= ~(0x00000001); |
| embeddedartists | 0:0fdadbc3d852 | 162 | |
| embeddedartists | 0:0fdadbc3d852 | 163 | _lcdControllerUsed = false; |
| embeddedartists | 0:0fdadbc3d852 | 164 | _opened = false; |
| embeddedartists | 0:0fdadbc3d852 | 165 | } |
| embeddedartists | 0:0fdadbc3d852 | 166 | |
| embeddedartists | 0:0fdadbc3d852 | 167 | |
| embeddedartists | 0:0fdadbc3d852 | 168 | return 0; |
| embeddedartists | 0:0fdadbc3d852 | 169 | } |
| embeddedartists | 0:0fdadbc3d852 | 170 | |
| embeddedartists | 0:0fdadbc3d852 | 171 | int LcdController::setFrameBuffer(uint32_t address) { |
| embeddedartists | 0:0fdadbc3d852 | 172 | if (!_opened) return 1; |
| embeddedartists | 0:0fdadbc3d852 | 173 | |
| embeddedartists | 0:0fdadbc3d852 | 174 | LPC_LCD->UPBASE = address; |
| embeddedartists | 0:0fdadbc3d852 | 175 | |
| embeddedartists | 0:0fdadbc3d852 | 176 | return 0; |
| embeddedartists | 0:0fdadbc3d852 | 177 | } |
| embeddedartists | 0:0fdadbc3d852 | 178 | |
| embeddedartists | 0:0fdadbc3d852 | 179 | int LcdController::setPower(bool on) { |
| embeddedartists | 0:0fdadbc3d852 | 180 | if (!_opened) return 1; |
| embeddedartists | 0:0fdadbc3d852 | 181 | |
| embeddedartists | 0:0fdadbc3d852 | 182 | if (on) { |
| embeddedartists | 0:0fdadbc3d852 | 183 | LPC_LCD->CTRL |= CLCDC_LCDCTRL_ENABLE; |
| embeddedartists | 0:0fdadbc3d852 | 184 | LPC_LCD->CTRL |= CLCDC_LCDCTRL_PWR; |
| embeddedartists | 0:0fdadbc3d852 | 185 | } |
| embeddedartists | 0:0fdadbc3d852 | 186 | else { |
| embeddedartists | 0:0fdadbc3d852 | 187 | LPC_LCD->CTRL &= ~CLCDC_LCDCTRL_PWR; |
| embeddedartists | 0:0fdadbc3d852 | 188 | LPC_LCD->CTRL &= ~CLCDC_LCDCTRL_ENABLE; |
| embeddedartists | 0:0fdadbc3d852 | 189 | } |
| embeddedartists | 0:0fdadbc3d852 | 190 | |
| embeddedartists | 0:0fdadbc3d852 | 191 | return 0; |
| embeddedartists | 0:0fdadbc3d852 | 192 | } |
| embeddedartists | 0:0fdadbc3d852 | 193 | |
| embeddedartists | 0:0fdadbc3d852 | 194 | void LcdController::init(LcdController::Config* cfg) { |
| embeddedartists | 0:0fdadbc3d852 | 195 | uint32_t tmp, i; |
| embeddedartists | 0:0fdadbc3d852 | 196 | |
| embeddedartists | 0:0fdadbc3d852 | 197 | // Disable the display in case it is on |
| embeddedartists | 0:0fdadbc3d852 | 198 | LPC_LCD->CTRL &= ~CLCDC_LCDCTRL_ENABLE; |
| embeddedartists | 0:0fdadbc3d852 | 199 | |
| embeddedartists | 0:0fdadbc3d852 | 200 | // Generate the horizontal axis plane control word |
| embeddedartists | 0:0fdadbc3d852 | 201 | tmp = (CLCDC_LCDTIMING0_PPL(cfg->width) | |
| embeddedartists | 0:0fdadbc3d852 | 202 | CLCDC_LCDTIMING0_HSW(cfg->hsync) | |
| embeddedartists | 0:0fdadbc3d852 | 203 | CLCDC_LCDTIMING0_HFP(cfg->horizontalFrontPorch) | |
| embeddedartists | 0:0fdadbc3d852 | 204 | CLCDC_LCDTIMING0_HBP(cfg->horizontalBackPorch)); |
| embeddedartists | 0:0fdadbc3d852 | 205 | LPC_LCD->TIMH = tmp; |
| embeddedartists | 0:0fdadbc3d852 | 206 | |
| embeddedartists | 0:0fdadbc3d852 | 207 | // Generate the vertical axis plane control word |
| embeddedartists | 0:0fdadbc3d852 | 208 | tmp = (CLCDC_LCDTIMING1_LPP(cfg->height) | |
| embeddedartists | 0:0fdadbc3d852 | 209 | CLCDC_LCDTIMING1_VSW(cfg->vsync) | |
| embeddedartists | 0:0fdadbc3d852 | 210 | CLCDC_LCDTIMING1_VFP(cfg->verticalFrontPorch) | |
| embeddedartists | 0:0fdadbc3d852 | 211 | CLCDC_LCDTIMING1_VBP(cfg->verticalBackPorch)); |
| embeddedartists | 0:0fdadbc3d852 | 212 | LPC_LCD->TIMV = tmp; |
| embeddedartists | 0:0fdadbc3d852 | 213 | |
| embeddedartists | 0:0fdadbc3d852 | 214 | // Generate the clock and signal polarity control word |
| embeddedartists | 0:0fdadbc3d852 | 215 | if(cfg->acBias != 0) |
| embeddedartists | 0:0fdadbc3d852 | 216 | { |
| embeddedartists | 0:0fdadbc3d852 | 217 | /* STN panel has AC bias value */ |
| embeddedartists | 0:0fdadbc3d852 | 218 | tmp = CLCDC_LCDTIMING2_ACB(cfg->acBias); |
| embeddedartists | 0:0fdadbc3d852 | 219 | } |
| embeddedartists | 0:0fdadbc3d852 | 220 | else |
| embeddedartists | 0:0fdadbc3d852 | 221 | { |
| embeddedartists | 0:0fdadbc3d852 | 222 | tmp = 0; |
| embeddedartists | 0:0fdadbc3d852 | 223 | } |
| embeddedartists | 0:0fdadbc3d852 | 224 | |
| embeddedartists | 0:0fdadbc3d852 | 225 | if (cfg->invertOutputEnable) |
| embeddedartists | 0:0fdadbc3d852 | 226 | { |
| embeddedartists | 0:0fdadbc3d852 | 227 | tmp |= CLCDC_LCDTIMING2_IOE; |
| embeddedartists | 0:0fdadbc3d852 | 228 | } |
| embeddedartists | 0:0fdadbc3d852 | 229 | |
| embeddedartists | 0:0fdadbc3d852 | 230 | if (cfg->invertPanelClock) |
| embeddedartists | 0:0fdadbc3d852 | 231 | { |
| embeddedartists | 0:0fdadbc3d852 | 232 | tmp |= CLCDC_LCDTIMING2_IPC; |
| embeddedartists | 0:0fdadbc3d852 | 233 | } |
| embeddedartists | 0:0fdadbc3d852 | 234 | |
| embeddedartists | 0:0fdadbc3d852 | 235 | if (cfg->invertHsync) |
| embeddedartists | 0:0fdadbc3d852 | 236 | { |
| embeddedartists | 0:0fdadbc3d852 | 237 | tmp |= CLCDC_LCDTIMING2_IHS; |
| embeddedartists | 0:0fdadbc3d852 | 238 | } |
| embeddedartists | 0:0fdadbc3d852 | 239 | |
| embeddedartists | 0:0fdadbc3d852 | 240 | if (cfg->invertVsync) |
| embeddedartists | 0:0fdadbc3d852 | 241 | { |
| embeddedartists | 0:0fdadbc3d852 | 242 | tmp |= CLCDC_LCDTIMING2_IVS; |
| embeddedartists | 0:0fdadbc3d852 | 243 | } |
| embeddedartists | 0:0fdadbc3d852 | 244 | |
| embeddedartists | 0:0fdadbc3d852 | 245 | // Compute clocks per line based on panel type |
| embeddedartists | 0:0fdadbc3d852 | 246 | switch (cfg->panelType) |
| embeddedartists | 0:0fdadbc3d852 | 247 | { |
| embeddedartists | 0:0fdadbc3d852 | 248 | case Mono_4Bit: |
| embeddedartists | 0:0fdadbc3d852 | 249 | // Clocks per line is a quarter of pixels per line |
| embeddedartists | 0:0fdadbc3d852 | 250 | tmp = tmp | CLCDC_LCDTIMING2_CPL((cfg->width / 4) - 1); |
| embeddedartists | 0:0fdadbc3d852 | 251 | break; |
| embeddedartists | 0:0fdadbc3d852 | 252 | |
| embeddedartists | 0:0fdadbc3d852 | 253 | case Mono_8Bit: |
| embeddedartists | 0:0fdadbc3d852 | 254 | // Clocks per line is an eighth of pixels per line |
| embeddedartists | 0:0fdadbc3d852 | 255 | tmp = tmp | CLCDC_LCDTIMING2_CPL((cfg->width / 8) - 1); |
| embeddedartists | 0:0fdadbc3d852 | 256 | break; |
| embeddedartists | 0:0fdadbc3d852 | 257 | |
| embeddedartists | 0:0fdadbc3d852 | 258 | case ColorStn: |
| embeddedartists | 0:0fdadbc3d852 | 259 | // CSTN Clocks per line (* 3 / 8) |
| embeddedartists | 0:0fdadbc3d852 | 260 | tmp = tmp | CLCDC_LCDTIMING2_CPL(((cfg->width * 3) / 8) - 1); |
| embeddedartists | 0:0fdadbc3d852 | 261 | break; |
| embeddedartists | 0:0fdadbc3d852 | 262 | |
| embeddedartists | 0:0fdadbc3d852 | 263 | case Tft: |
| embeddedartists | 0:0fdadbc3d852 | 264 | case AdTft: |
| embeddedartists | 0:0fdadbc3d852 | 265 | case HrTft: |
| embeddedartists | 0:0fdadbc3d852 | 266 | default: |
| embeddedartists | 0:0fdadbc3d852 | 267 | // Clocks per line and pixels per line are the same |
| embeddedartists | 0:0fdadbc3d852 | 268 | tmp = tmp | CLCDC_LCDTIMING2_CPL(cfg->width - 1); |
| embeddedartists | 0:0fdadbc3d852 | 269 | break; |
| embeddedartists | 0:0fdadbc3d852 | 270 | } |
| embeddedartists | 0:0fdadbc3d852 | 271 | |
| embeddedartists | 0:0fdadbc3d852 | 272 | // clock |
| embeddedartists | 0:0fdadbc3d852 | 273 | tmp = tmp | getClockDivisor(cfg->optimalClock); |
| embeddedartists | 0:0fdadbc3d852 | 274 | |
| embeddedartists | 0:0fdadbc3d852 | 275 | LPC_LCD->POL = tmp; |
| embeddedartists | 0:0fdadbc3d852 | 276 | |
| embeddedartists | 0:0fdadbc3d852 | 277 | // Skip line end control word - just set to 0x0 |
| embeddedartists | 0:0fdadbc3d852 | 278 | LPC_LCD->LE = 0x00000000; |
| embeddedartists | 0:0fdadbc3d852 | 279 | |
| embeddedartists | 0:0fdadbc3d852 | 280 | // Default with all interrupts of |
| embeddedartists | 0:0fdadbc3d852 | 281 | LPC_LCD->INTMSK = 0x00000000; |
| embeddedartists | 0:0fdadbc3d852 | 282 | |
| embeddedartists | 0:0fdadbc3d852 | 283 | |
| embeddedartists | 0:0fdadbc3d852 | 284 | switch(cfg->bpp) { |
| embeddedartists | 0:0fdadbc3d852 | 285 | case Bpp_1: |
| embeddedartists | 0:0fdadbc3d852 | 286 | tmp = CLCDC_LCDCTRL_BPP1; |
| embeddedartists | 0:0fdadbc3d852 | 287 | break; |
| embeddedartists | 0:0fdadbc3d852 | 288 | case Bpp_2: |
| embeddedartists | 0:0fdadbc3d852 | 289 | tmp = CLCDC_LCDCTRL_BPP2; |
| embeddedartists | 0:0fdadbc3d852 | 290 | break; |
| embeddedartists | 0:0fdadbc3d852 | 291 | case Bpp_4: |
| embeddedartists | 0:0fdadbc3d852 | 292 | tmp = CLCDC_LCDCTRL_BPP4; |
| embeddedartists | 0:0fdadbc3d852 | 293 | break; |
| embeddedartists | 0:0fdadbc3d852 | 294 | case Bpp_8: |
| embeddedartists | 0:0fdadbc3d852 | 295 | tmp = CLCDC_LCDCTRL_BPP8; |
| embeddedartists | 0:0fdadbc3d852 | 296 | break; |
| embeddedartists | 0:0fdadbc3d852 | 297 | case Bpp_16: |
| embeddedartists | 0:0fdadbc3d852 | 298 | tmp = CLCDC_LCDCTRL_BPP16; |
| embeddedartists | 0:0fdadbc3d852 | 299 | break; |
| embeddedartists | 0:0fdadbc3d852 | 300 | case Bpp_24: |
| embeddedartists | 0:0fdadbc3d852 | 301 | tmp = CLCDC_LCDCTRL_BPP24; |
| embeddedartists | 0:0fdadbc3d852 | 302 | break; |
| embeddedartists | 0:0fdadbc3d852 | 303 | case Bpp_16_565: |
| embeddedartists | 0:0fdadbc3d852 | 304 | tmp = CLCDC_LCDCTRL_BPP16_565_MODE; |
| embeddedartists | 0:0fdadbc3d852 | 305 | break; |
| embeddedartists | 0:0fdadbc3d852 | 306 | case Bpp_12_444: |
| embeddedartists | 0:0fdadbc3d852 | 307 | tmp = CLCDC_LCDCTRL_BPP12_444_MODE; |
| embeddedartists | 0:0fdadbc3d852 | 308 | break; |
| embeddedartists | 0:0fdadbc3d852 | 309 | default: |
| embeddedartists | 0:0fdadbc3d852 | 310 | tmp = CLCDC_LCDCTRL_BPP16_565_MODE; |
| embeddedartists | 0:0fdadbc3d852 | 311 | break; |
| embeddedartists | 0:0fdadbc3d852 | 312 | } |
| embeddedartists | 0:0fdadbc3d852 | 313 | |
| embeddedartists | 0:0fdadbc3d852 | 314 | // red and blue swapped |
| embeddedartists | 0:0fdadbc3d852 | 315 | tmp |= CLCDC_LCDCTRL_BGR; |
| embeddedartists | 0:0fdadbc3d852 | 316 | |
| embeddedartists | 0:0fdadbc3d852 | 317 | switch (cfg->panelType) |
| embeddedartists | 0:0fdadbc3d852 | 318 | { |
| embeddedartists | 0:0fdadbc3d852 | 319 | case AdTft: |
| embeddedartists | 0:0fdadbc3d852 | 320 | case HrTft: |
| embeddedartists | 0:0fdadbc3d852 | 321 | case Tft: |
| embeddedartists | 0:0fdadbc3d852 | 322 | tmp |= CLCDC_LCDCTRL_TFT; |
| embeddedartists | 0:0fdadbc3d852 | 323 | break; |
| embeddedartists | 0:0fdadbc3d852 | 324 | |
| embeddedartists | 0:0fdadbc3d852 | 325 | case Mono_4Bit: |
| embeddedartists | 0:0fdadbc3d852 | 326 | tmp |= CLCDC_LCDCTRL_BW_MONO; |
| embeddedartists | 0:0fdadbc3d852 | 327 | break; |
| embeddedartists | 0:0fdadbc3d852 | 328 | |
| embeddedartists | 0:0fdadbc3d852 | 329 | case Mono_8Bit: |
| embeddedartists | 0:0fdadbc3d852 | 330 | tmp |= (CLCDC_LCDCTRL_MON8 | CLCDC_LCDCTRL_BW_MONO); |
| embeddedartists | 0:0fdadbc3d852 | 331 | break; |
| embeddedartists | 0:0fdadbc3d852 | 332 | |
| embeddedartists | 0:0fdadbc3d852 | 333 | case ColorStn: |
| embeddedartists | 0:0fdadbc3d852 | 334 | ; |
| embeddedartists | 0:0fdadbc3d852 | 335 | break; |
| embeddedartists | 0:0fdadbc3d852 | 336 | |
| embeddedartists | 0:0fdadbc3d852 | 337 | default: |
| embeddedartists | 0:0fdadbc3d852 | 338 | // Unsupported panel type |
| embeddedartists | 0:0fdadbc3d852 | 339 | break; |
| embeddedartists | 0:0fdadbc3d852 | 340 | } |
| embeddedartists | 0:0fdadbc3d852 | 341 | |
| embeddedartists | 0:0fdadbc3d852 | 342 | // Dual panel operation |
| embeddedartists | 0:0fdadbc3d852 | 343 | if (cfg->dualPanel) |
| embeddedartists | 0:0fdadbc3d852 | 344 | { |
| embeddedartists | 0:0fdadbc3d852 | 345 | tmp |= CLCDC_LCDCTRL_DUAL; |
| embeddedartists | 0:0fdadbc3d852 | 346 | } |
| embeddedartists | 0:0fdadbc3d852 | 347 | |
| embeddedartists | 0:0fdadbc3d852 | 348 | LPC_LCD->CTRL = tmp; |
| embeddedartists | 0:0fdadbc3d852 | 349 | |
| embeddedartists | 0:0fdadbc3d852 | 350 | // clear the palette (color is black ) |
| embeddedartists | 0:0fdadbc3d852 | 351 | for (i = 0; i < sizeof(LPC_LCD->PAL)/sizeof(LPC_LCD->PAL[0]); i++) |
| embeddedartists | 0:0fdadbc3d852 | 352 | { |
| embeddedartists | 0:0fdadbc3d852 | 353 | LPC_LCD->PAL[i] = 0; |
| embeddedartists | 0:0fdadbc3d852 | 354 | } |
| embeddedartists | 0:0fdadbc3d852 | 355 | |
| embeddedartists | 0:0fdadbc3d852 | 356 | LPC_SC->LCD_CFG = 0x0; |
| embeddedartists | 0:0fdadbc3d852 | 357 | |
| embeddedartists | 0:0fdadbc3d852 | 358 | } |
| embeddedartists | 0:0fdadbc3d852 | 359 | |
| embeddedartists | 0:0fdadbc3d852 | 360 | void LcdController::pinConfig() { |
| embeddedartists | 0:0fdadbc3d852 | 361 | |
| embeddedartists | 0:0fdadbc3d852 | 362 | LPC_IOCON->P0_4 |= 7; /* LCD_VD_0 @ P0.4 */ |
| embeddedartists | 0:0fdadbc3d852 | 363 | LPC_IOCON->P0_5 |= 7; /* LCD_VD_1 @ P0.5 */ |
| embeddedartists | 0:0fdadbc3d852 | 364 | LPC_IOCON->P0_6 |= 7; /* LCD_VD_8 @ P0.6 */ |
| embeddedartists | 0:0fdadbc3d852 | 365 | LPC_IOCON->P0_7 |= 7; /* LCD_VD_9 @ P0.7 */ |
| embeddedartists | 0:0fdadbc3d852 | 366 | LPC_IOCON->P0_8 |= 7; /* LCD_VD_16 @ P0.8 */ |
| embeddedartists | 0:0fdadbc3d852 | 367 | LPC_IOCON->P0_9 |= 7; /* LCD_VD_17 @ P0.9 */ |
| embeddedartists | 0:0fdadbc3d852 | 368 | LPC_IOCON->P0_10 |= 7; /* LCD_VD_5 @ P0.10 */ /* LPC4088 */ |
| embeddedartists | 0:0fdadbc3d852 | 369 | |
| embeddedartists | 0:0fdadbc3d852 | 370 | #ifdef LPC4088_OEM |
| embeddedartists | 0:0fdadbc3d852 | 371 | LPC_IOCON->P1_20 |= 7; /* LCD_VD_10 @ P1.20 */ |
| embeddedartists | 0:0fdadbc3d852 | 372 | LPC_IOCON->P1_23 |= 7; /* LCD_VD_13 @ P1.23 */ |
| embeddedartists | 0:0fdadbc3d852 | 373 | LPC_IOCON->P1_24 |= 7; /* LCD_VD_14 @ P1.24 */ |
| embeddedartists | 0:0fdadbc3d852 | 374 | #else |
| embeddedartists | 0:0fdadbc3d852 | 375 | LPC_IOCON->P0_11 |= 7; /* LCD_VD_10 @ P0.11 */ |
| embeddedartists | 0:0fdadbc3d852 | 376 | LPC_IOCON->P0_19 |= 7; /* LCD_VD_13 @ P0.19 */ |
| embeddedartists | 0:0fdadbc3d852 | 377 | LPC_IOCON->P0_20 |= 7; /* LCD_VD_14 @ P0.20 */ |
| embeddedartists | 0:0fdadbc3d852 | 378 | #endif |
| embeddedartists | 0:0fdadbc3d852 | 379 | |
| embeddedartists | 0:0fdadbc3d852 | 380 | LPC_IOCON->P1_21 |= 7; /* LCD_VD_11 @ P1.21 */ |
| embeddedartists | 0:0fdadbc3d852 | 381 | LPC_IOCON->P1_22 |= 7; /* LCD_VD_12 @ P1.22 */ |
| embeddedartists | 0:0fdadbc3d852 | 382 | |
| embeddedartists | 0:0fdadbc3d852 | 383 | LPC_IOCON->P1_25 |= 7; /* LCD_VD_15 @ P1.25 */ |
| embeddedartists | 0:0fdadbc3d852 | 384 | LPC_IOCON->P1_26 |= 7; /* LCD_VD_20 @ P1.26 */ |
| embeddedartists | 0:0fdadbc3d852 | 385 | LPC_IOCON->P1_27 |= 7; /* LCD_VD_21 @ P1.27 */ |
| embeddedartists | 0:0fdadbc3d852 | 386 | LPC_IOCON->P1_28 |= 7; /* LCD_VD_22 @ P1.28 */ |
| embeddedartists | 0:0fdadbc3d852 | 387 | LPC_IOCON->P1_29 |= 7; /* LCD_VD_23 @ P1.29 */ |
| embeddedartists | 0:0fdadbc3d852 | 388 | |
| embeddedartists | 0:0fdadbc3d852 | 389 | LPC_IOCON->P2_0 |= 7; /* LCD_PWR @ P2.0 */ |
| embeddedartists | 0:0fdadbc3d852 | 390 | LPC_IOCON->P2_1 |= 7; /* LCD_LE @ P2.1 */ |
| embeddedartists | 0:0fdadbc3d852 | 391 | LPC_IOCON->P2_2 |= 7; /* LCD_DCLK @ P2.2 */ |
| embeddedartists | 0:0fdadbc3d852 | 392 | LPC_IOCON->P2_3 |= 7; /* LCD_FP @ P2.3 */ |
| embeddedartists | 0:0fdadbc3d852 | 393 | LPC_IOCON->P2_4 |= 7; /* LCD_ENAB_M @ P2.4 */ |
| embeddedartists | 0:0fdadbc3d852 | 394 | LPC_IOCON->P2_5 |= 7; /* LCD_LP @ P2.5 */ |
| embeddedartists | 0:0fdadbc3d852 | 395 | LPC_IOCON->P2_6 |= 7; /* LCD_VD_4 @ P2.6 */ |
| embeddedartists | 0:0fdadbc3d852 | 396 | //LPC_IOCON->P2_7 |= 7; /* LCD_VD_5 @ P2.7 */ /* LPC4088 */ |
| embeddedartists | 0:0fdadbc3d852 | 397 | LPC_IOCON->P2_8 |= 7; /* LCD_VD_6 @ P2.8 */ |
| embeddedartists | 0:0fdadbc3d852 | 398 | LPC_IOCON->P2_9 |= 7; /* LCD_VD_7 @ P2.9 */ |
| embeddedartists | 0:0fdadbc3d852 | 399 | |
| embeddedartists | 0:0fdadbc3d852 | 400 | LPC_IOCON->P2_11 |= 7; /* LCD_CLKIN @ P2.11 */ |
| embeddedartists | 0:0fdadbc3d852 | 401 | LPC_IOCON->P2_12 |= 5; /* LCD_VD_3 @ P2.12 Signal marked as LCD_VD_18 on base board, but shall carry the LCD_VD_3 signal */ |
| embeddedartists | 0:0fdadbc3d852 | 402 | LPC_IOCON->P2_13 |= 7; /* LCD_VD_19 @ P2.13 */ |
| embeddedartists | 0:0fdadbc3d852 | 403 | } |
| embeddedartists | 0:0fdadbc3d852 | 404 | |
| embeddedartists | 0:0fdadbc3d852 | 405 | uint32_t LcdController::getClockDivisor(int clock) { |
| embeddedartists | 0:0fdadbc3d852 | 406 | uint32_t pixel_div, tmp = 0; |
| embeddedartists | 0:0fdadbc3d852 | 407 | uint32_t clk; |
| embeddedartists | 0:0fdadbc3d852 | 408 | |
| embeddedartists | 0:0fdadbc3d852 | 409 | clk = SystemCoreClock; |
| embeddedartists | 0:0fdadbc3d852 | 410 | |
| embeddedartists | 0:0fdadbc3d852 | 411 | // Find closest clock divider to get clock rate |
| embeddedartists | 0:0fdadbc3d852 | 412 | pixel_div = 1; |
| embeddedartists | 0:0fdadbc3d852 | 413 | while (((clk / pixel_div) > clock) && (pixel_div <= 0x3F)) |
| embeddedartists | 0:0fdadbc3d852 | 414 | { |
| embeddedartists | 0:0fdadbc3d852 | 415 | pixel_div++; |
| embeddedartists | 0:0fdadbc3d852 | 416 | } |
| embeddedartists | 0:0fdadbc3d852 | 417 | |
| embeddedartists | 0:0fdadbc3d852 | 418 | if (pixel_div <= 1) |
| embeddedartists | 0:0fdadbc3d852 | 419 | { |
| embeddedartists | 0:0fdadbc3d852 | 420 | // Pixel clock divider is 1, skip divider logic |
| embeddedartists | 0:0fdadbc3d852 | 421 | tmp = CLCDC_LCDTIMING2_BCD; |
| embeddedartists | 0:0fdadbc3d852 | 422 | } |
| embeddedartists | 0:0fdadbc3d852 | 423 | else |
| embeddedartists | 0:0fdadbc3d852 | 424 | { |
| embeddedartists | 0:0fdadbc3d852 | 425 | // Add in new divider |
| embeddedartists | 0:0fdadbc3d852 | 426 | pixel_div -= 2; |
| embeddedartists | 0:0fdadbc3d852 | 427 | |
| embeddedartists | 0:0fdadbc3d852 | 428 | tmp |= (((pixel_div >> 0) & 0x1F) |
| embeddedartists | 0:0fdadbc3d852 | 429 | | (((pixel_div >> 5) & 0x1F) << 27)); |
| embeddedartists | 0:0fdadbc3d852 | 430 | } |
| embeddedartists | 0:0fdadbc3d852 | 431 | |
| embeddedartists | 0:0fdadbc3d852 | 432 | return tmp; |
| embeddedartists | 0:0fdadbc3d852 | 433 | } |
| embeddedartists | 0:0fdadbc3d852 | 434 | |
| embeddedartists | 0:0fdadbc3d852 | 435 | |
| embeddedartists | 0:0fdadbc3d852 | 436 | |
| embeddedartists | 0:0fdadbc3d852 | 437 |
