Lib for the new LCD Display with ILI9341 controller supporting two displays

Dependents:   CANary_9341_test CANary_9341 CANary

Fork of SPI_TFT_ILI9341 by Peter Drescher

Committer:
TickTock
Date:
Sun May 18 12:45:24 2014 +0000
Revision:
10:aca12a61d2b1
Works with both controllers using precompiler directive

Who changed what in which revision?

UserRevisionLine numberNew contents of line
TickTock 10:aca12a61d2b1 1 /* mbed library for 240*320 pixel display TFT based on HX8347D LCD Controller
TickTock 10:aca12a61d2b1 2 * Copyright (c) 2011 Peter Drescher - DC2PD
TickTock 10:aca12a61d2b1 3 *
TickTock 10:aca12a61d2b1 4 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
TickTock 10:aca12a61d2b1 5 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
TickTock 10:aca12a61d2b1 6 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
TickTock 10:aca12a61d2b1 7 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
TickTock 10:aca12a61d2b1 8 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
TickTock 10:aca12a61d2b1 9 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
TickTock 10:aca12a61d2b1 10 * THE SOFTWARE.
TickTock 10:aca12a61d2b1 11 */
TickTock 10:aca12a61d2b1 12
TickTock 10:aca12a61d2b1 13
TickTock 10:aca12a61d2b1 14 // fix bmp padding for Bitmap function
TickTock 10:aca12a61d2b1 15 // speed up pixel
TickTock 10:aca12a61d2b1 16 // 30.12.11 fix cls
TickTock 10:aca12a61d2b1 17 // 11.03.12 use DMA to speed up
TickTock 10:aca12a61d2b1 18 // 15.03.12 use SSEL for TFT CS to enable DMA Register writes
TickTock 10:aca12a61d2b1 19 // 06.04.12 fix SSEL CS problem
TickTock 10:aca12a61d2b1 20 // 06.04.12 use direct access to the spi register to speed up the library.
TickTock 10:aca12a61d2b1 21 // 11.09.12 switch back to using io pin as cs to avoid problems with SSEL CS.
TickTock 10:aca12a61d2b1 22 // 21.09.12 fix Bug in BMP_16
TickTock 10:aca12a61d2b1 23 // 11.10.12 patch from Hans Bergles to get SPI1 working again
TickTock 10:aca12a61d2b1 24 // 03.02.13 add a switch to switch off DMA use for LPC11U24
TickTock 10:aca12a61d2b1 25
TickTock 10:aca12a61d2b1 26 #include "SPI_TFTx2.h"
TickTock 10:aca12a61d2b1 27 #include "mbed.h"
TickTock 10:aca12a61d2b1 28
TickTock 10:aca12a61d2b1 29 #define BPP 16 // Bits per pixel
TickTock 10:aca12a61d2b1 30
TickTock 10:aca12a61d2b1 31 #if defined TARGET_LPC1768
TickTock 10:aca12a61d2b1 32 #define USE_DMA
TickTock 10:aca12a61d2b1 33 #endif
TickTock 10:aca12a61d2b1 34
TickTock 10:aca12a61d2b1 35 #if defined NO_DMA
TickTock 10:aca12a61d2b1 36 #undef USE_DMA
TickTock 10:aca12a61d2b1 37 #endif
TickTock 10:aca12a61d2b1 38
TickTock 10:aca12a61d2b1 39 //extern Serial pc;
TickTock 10:aca12a61d2b1 40 //extern DigitalOut xx; // debug !!
TickTock 10:aca12a61d2b1 41
TickTock 10:aca12a61d2b1 42 SPI_TFTx2::SPI_TFTx2(PinName mosi, PinName miso, PinName sclk, PinName cs0, PinName cs1, PinName reset, const char *name)
TickTock 10:aca12a61d2b1 43 : _spi(mosi, miso, sclk), _cs0(cs0), _cs1(cs1), _reset(reset), GraphicsDisplay(name)
TickTock 10:aca12a61d2b1 44 {
TickTock 10:aca12a61d2b1 45 orientation = 0;
TickTock 10:aca12a61d2b1 46 char_x = 0;
TickTock 10:aca12a61d2b1 47 _cs0 = 1;
TickTock 10:aca12a61d2b1 48 _cs1 = 1;
TickTock 10:aca12a61d2b1 49
TickTock 10:aca12a61d2b1 50 if (mosi == p11 || mosi == P0_18) spi_port = 0; // we must know the used SPI port to setup the DMA
TickTock 10:aca12a61d2b1 51 else spi_port = 1;
TickTock 10:aca12a61d2b1 52 seldisp = 2;
TickTock 10:aca12a61d2b1 53 tft_reset();
TickTock 10:aca12a61d2b1 54 }
TickTock 10:aca12a61d2b1 55
TickTock 10:aca12a61d2b1 56 int SPI_TFTx2::width()
TickTock 10:aca12a61d2b1 57 {
TickTock 10:aca12a61d2b1 58 if (orientation == 0 || orientation == 2) return 240;
TickTock 10:aca12a61d2b1 59 else return 320;
TickTock 10:aca12a61d2b1 60 }
TickTock 10:aca12a61d2b1 61
TickTock 10:aca12a61d2b1 62
TickTock 10:aca12a61d2b1 63 int SPI_TFTx2::height()
TickTock 10:aca12a61d2b1 64 {
TickTock 10:aca12a61d2b1 65 if (orientation == 0 || orientation == 2) return 320;
TickTock 10:aca12a61d2b1 66 else return 240;
TickTock 10:aca12a61d2b1 67 }
TickTock 10:aca12a61d2b1 68
TickTock 10:aca12a61d2b1 69
TickTock 10:aca12a61d2b1 70 void SPI_TFTx2::set_orientation(unsigned int o)
TickTock 10:aca12a61d2b1 71 {
TickTock 10:aca12a61d2b1 72 orientation = o;
TickTock 10:aca12a61d2b1 73 switch (orientation) {
TickTock 10:aca12a61d2b1 74 case 0:
TickTock 10:aca12a61d2b1 75 wr_reg(0x16, 0x08);
TickTock 10:aca12a61d2b1 76 break;
TickTock 10:aca12a61d2b1 77 case 1:
TickTock 10:aca12a61d2b1 78 wr_reg(0x16, 0x68);
TickTock 10:aca12a61d2b1 79 break;
TickTock 10:aca12a61d2b1 80 case 2:
TickTock 10:aca12a61d2b1 81 wr_reg(0x16, 0xC8);
TickTock 10:aca12a61d2b1 82 break;
TickTock 10:aca12a61d2b1 83 case 3:
TickTock 10:aca12a61d2b1 84 wr_reg(0x16, 0xA8);
TickTock 10:aca12a61d2b1 85 break;
TickTock 10:aca12a61d2b1 86 }
TickTock 10:aca12a61d2b1 87 WindowMax();
TickTock 10:aca12a61d2b1 88 }
TickTock 10:aca12a61d2b1 89
TickTock 10:aca12a61d2b1 90 void SPI_TFTx2::set_display(unsigned int o)
TickTock 10:aca12a61d2b1 91 {
TickTock 10:aca12a61d2b1 92 seldisp = o;
TickTock 10:aca12a61d2b1 93 }
TickTock 10:aca12a61d2b1 94
TickTock 10:aca12a61d2b1 95 // write command to tft register
TickTock 10:aca12a61d2b1 96
TickTock 10:aca12a61d2b1 97 void SPI_TFTx2::wr_cmd(unsigned char cmd)
TickTock 10:aca12a61d2b1 98 {
TickTock 10:aca12a61d2b1 99 unsigned short spi_d;
TickTock 10:aca12a61d2b1 100 spi_d = 0x7000 | cmd ;
TickTock 10:aca12a61d2b1 101
TickTock 10:aca12a61d2b1 102 if (seldisp == 0) {
TickTock 10:aca12a61d2b1 103 _cs0 = 0;
TickTock 10:aca12a61d2b1 104 _cs1 = 1;
TickTock 10:aca12a61d2b1 105 } else if (seldisp == 1) {
TickTock 10:aca12a61d2b1 106 _cs0 = 1;
TickTock 10:aca12a61d2b1 107 _cs1 = 0;
TickTock 10:aca12a61d2b1 108 } else {
TickTock 10:aca12a61d2b1 109 _cs0 = 0;
TickTock 10:aca12a61d2b1 110 _cs1 = 0;
TickTock 10:aca12a61d2b1 111 }
TickTock 10:aca12a61d2b1 112
TickTock 10:aca12a61d2b1 113 if (spi_port == 0) { // TFT on SSP0
TickTock 10:aca12a61d2b1 114 LPC_SSP0->DR = spi_d;
TickTock 10:aca12a61d2b1 115 // we have to wait for SPI IDLE to set CS back to high
TickTock 10:aca12a61d2b1 116 do {
TickTock 10:aca12a61d2b1 117 } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI0 not idle
TickTock 10:aca12a61d2b1 118 } else {
TickTock 10:aca12a61d2b1 119 LPC_SSP1->DR = spi_d;
TickTock 10:aca12a61d2b1 120 do {
TickTock 10:aca12a61d2b1 121 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI1 not idle
TickTock 10:aca12a61d2b1 122 }
TickTock 10:aca12a61d2b1 123 _cs0 = 1;
TickTock 10:aca12a61d2b1 124 _cs1 = 1;
TickTock 10:aca12a61d2b1 125 }
TickTock 10:aca12a61d2b1 126
TickTock 10:aca12a61d2b1 127
TickTock 10:aca12a61d2b1 128
TickTock 10:aca12a61d2b1 129 void SPI_TFTx2::wr_dat(unsigned char dat)
TickTock 10:aca12a61d2b1 130 {
TickTock 10:aca12a61d2b1 131 unsigned short spi_d;
TickTock 10:aca12a61d2b1 132 spi_d = 0x7200 | dat;
TickTock 10:aca12a61d2b1 133 if (seldisp == 0) {
TickTock 10:aca12a61d2b1 134 _cs0 = 0;
TickTock 10:aca12a61d2b1 135 _cs1 = 1;
TickTock 10:aca12a61d2b1 136 } else if (seldisp == 1) {
TickTock 10:aca12a61d2b1 137 _cs0 = 1;
TickTock 10:aca12a61d2b1 138 _cs1 = 0;
TickTock 10:aca12a61d2b1 139 } else {
TickTock 10:aca12a61d2b1 140 _cs0 = 0;
TickTock 10:aca12a61d2b1 141 _cs1 = 0;
TickTock 10:aca12a61d2b1 142 }
TickTock 10:aca12a61d2b1 143
TickTock 10:aca12a61d2b1 144 if (spi_port == 0) { // TFT on SSP0
TickTock 10:aca12a61d2b1 145 LPC_SSP0->DR = spi_d;
TickTock 10:aca12a61d2b1 146 // we have to wait for SPI IDLE to set CS back to high
TickTock 10:aca12a61d2b1 147 do {
TickTock 10:aca12a61d2b1 148 } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI0 not idle
TickTock 10:aca12a61d2b1 149 } else {
TickTock 10:aca12a61d2b1 150 LPC_SSP1->DR = spi_d;
TickTock 10:aca12a61d2b1 151 do {
TickTock 10:aca12a61d2b1 152 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI1 not idle
TickTock 10:aca12a61d2b1 153 }
TickTock 10:aca12a61d2b1 154 _cs0 = 1;
TickTock 10:aca12a61d2b1 155 _cs1 = 1;
TickTock 10:aca12a61d2b1 156 }
TickTock 10:aca12a61d2b1 157
TickTock 10:aca12a61d2b1 158
TickTock 10:aca12a61d2b1 159
TickTock 10:aca12a61d2b1 160 // the HX8347-D controller do not use the MISO (SDO) Signal.
TickTock 10:aca12a61d2b1 161 // This is a bug - ?
TickTock 10:aca12a61d2b1 162 // A read will return 0 at the moment
TickTock 10:aca12a61d2b1 163
TickTock 10:aca12a61d2b1 164 unsigned short SPI_TFTx2::rd_dat (void)
TickTock 10:aca12a61d2b1 165 {
TickTock 10:aca12a61d2b1 166 unsigned short val = 0;
TickTock 10:aca12a61d2b1 167
TickTock 10:aca12a61d2b1 168 //val = _spi.write(0x73ff); /* Dummy read 1 */
TickTock 10:aca12a61d2b1 169 //val = _spi.write(0x0000); /* Read D8..D15 */
TickTock 10:aca12a61d2b1 170 return (val);
TickTock 10:aca12a61d2b1 171 }
TickTock 10:aca12a61d2b1 172
TickTock 10:aca12a61d2b1 173 void SPI_TFTx2::wr_reg (unsigned char reg, unsigned char val)
TickTock 10:aca12a61d2b1 174 {
TickTock 10:aca12a61d2b1 175 wr_cmd(reg);
TickTock 10:aca12a61d2b1 176 wr_dat(val);
TickTock 10:aca12a61d2b1 177 }
TickTock 10:aca12a61d2b1 178
TickTock 10:aca12a61d2b1 179 unsigned short SPI_TFTx2::rd_reg (unsigned char reg)
TickTock 10:aca12a61d2b1 180 {
TickTock 10:aca12a61d2b1 181 wr_cmd(reg);
TickTock 10:aca12a61d2b1 182 return(rd_dat());
TickTock 10:aca12a61d2b1 183 }
TickTock 10:aca12a61d2b1 184
TickTock 10:aca12a61d2b1 185 void SPI_TFTx2::tft_reset()
TickTock 10:aca12a61d2b1 186 {
TickTock 10:aca12a61d2b1 187 //static unsigned short driverCode;
TickTock 10:aca12a61d2b1 188 _spi.format(16,3); // 16 bit spi mode 3
TickTock 10:aca12a61d2b1 189 _spi.frequency(48000000); // 48 Mhz SPI clock
TickTock 10:aca12a61d2b1 190 _cs0 = 1; // cs high
TickTock 10:aca12a61d2b1 191 _cs1 = 1; // cs high
TickTock 10:aca12a61d2b1 192 _reset = 0; // display reset
TickTock 10:aca12a61d2b1 193
TickTock 10:aca12a61d2b1 194 wait_us(50);
TickTock 10:aca12a61d2b1 195 _reset = 1; // end reset
TickTock 10:aca12a61d2b1 196 wait_ms(5);
TickTock 10:aca12a61d2b1 197
TickTock 10:aca12a61d2b1 198 /* Start Initial Sequence ----------------------------------------------------*/
TickTock 10:aca12a61d2b1 199 wr_reg(0xEA, 0x00); /* Reset Power Control 1 */
TickTock 10:aca12a61d2b1 200 wr_reg(0xEB, 0x20); /* Power Control 2 */
TickTock 10:aca12a61d2b1 201 wr_reg(0xEC, 0x0C); /* Power Control 3 */
TickTock 10:aca12a61d2b1 202 wr_reg(0xED, 0xC4); /* Power Control 4 */
TickTock 10:aca12a61d2b1 203 wr_reg(0xE8, 0x40); /* Source OPON_N */
TickTock 10:aca12a61d2b1 204 wr_reg(0xE9, 0x38); /* Source OPON_I */
TickTock 10:aca12a61d2b1 205 wr_reg(0xF1, 0x01); /* */
TickTock 10:aca12a61d2b1 206 wr_reg(0xF2, 0x10); /* */
TickTock 10:aca12a61d2b1 207 wr_reg(0x27, 0xA3); /* Display Control 2 */
TickTock 10:aca12a61d2b1 208
TickTock 10:aca12a61d2b1 209 /* Power On sequence ---------------------------------------------------------*/
TickTock 10:aca12a61d2b1 210 wr_reg(0x1B, 0x1B); /* Power Control 2 */
TickTock 10:aca12a61d2b1 211 wr_reg(0x1A, 0x01); /* Power Control 1 */
TickTock 10:aca12a61d2b1 212 wr_reg(0x24, 0x2F); /* Vcom Control 2 */
TickTock 10:aca12a61d2b1 213 wr_reg(0x25, 0x57); /* Vcom Control 3 */
TickTock 10:aca12a61d2b1 214 wr_reg(0x23, 0x8D); /* Vcom Control 1 */
TickTock 10:aca12a61d2b1 215
TickTock 10:aca12a61d2b1 216 /* Gamma settings -----------------------------------------------------------*/
TickTock 10:aca12a61d2b1 217 wr_reg(0x40,0x00); //
TickTock 10:aca12a61d2b1 218 wr_reg(0x41,0x00); //
TickTock 10:aca12a61d2b1 219 wr_reg(0x42,0x01); //
TickTock 10:aca12a61d2b1 220 wr_reg(0x43,0x13); //
TickTock 10:aca12a61d2b1 221 wr_reg(0x44,0x10); //
TickTock 10:aca12a61d2b1 222 wr_reg(0x45,0x26); //
TickTock 10:aca12a61d2b1 223 wr_reg(0x46,0x08); //
TickTock 10:aca12a61d2b1 224 wr_reg(0x47,0x51); //
TickTock 10:aca12a61d2b1 225 wr_reg(0x48,0x02); //
TickTock 10:aca12a61d2b1 226 wr_reg(0x49,0x12); //
TickTock 10:aca12a61d2b1 227 wr_reg(0x4A,0x18); //
TickTock 10:aca12a61d2b1 228 wr_reg(0x4B,0x19); //
TickTock 10:aca12a61d2b1 229 wr_reg(0x4C,0x14); //
TickTock 10:aca12a61d2b1 230 wr_reg(0x50,0x19); //
TickTock 10:aca12a61d2b1 231 wr_reg(0x51,0x2F); //
TickTock 10:aca12a61d2b1 232 wr_reg(0x52,0x2C); //
TickTock 10:aca12a61d2b1 233 wr_reg(0x53,0x3E); //
TickTock 10:aca12a61d2b1 234 wr_reg(0x54,0x3F); //
TickTock 10:aca12a61d2b1 235 wr_reg(0x55,0x3F); //
TickTock 10:aca12a61d2b1 236 wr_reg(0x56,0x2E); //
TickTock 10:aca12a61d2b1 237 wr_reg(0x57,0x77); //
TickTock 10:aca12a61d2b1 238 wr_reg(0x58,0x0B); //
TickTock 10:aca12a61d2b1 239 wr_reg(0x59,0x06); //
TickTock 10:aca12a61d2b1 240 wr_reg(0x5A,0x07); //
TickTock 10:aca12a61d2b1 241 wr_reg(0x5B,0x0D); //
TickTock 10:aca12a61d2b1 242 wr_reg(0x5C,0x1D); //
TickTock 10:aca12a61d2b1 243 wr_reg(0x5D,0xCC); //
TickTock 10:aca12a61d2b1 244
TickTock 10:aca12a61d2b1 245 /* Power + Osc ---------------------------------------------------------------*/
TickTock 10:aca12a61d2b1 246 wr_reg(0x18, 0x0036); /* OSC Control 1 */
TickTock 10:aca12a61d2b1 247 wr_reg(0x19, 0x0001); /* OSC Control 2 */
TickTock 10:aca12a61d2b1 248 wr_reg(0x01, 0x0000); /* Display Mode Control */
TickTock 10:aca12a61d2b1 249 wr_reg(0x1F, 0x0088); /* Power Control 6 */
TickTock 10:aca12a61d2b1 250 wait_ms(5); /* Delay 5 ms */
TickTock 10:aca12a61d2b1 251 wr_reg(0x1F, 0x0080); /* Power Control 6 */
TickTock 10:aca12a61d2b1 252 wait_ms(5); /* Delay 5 ms */
TickTock 10:aca12a61d2b1 253 wr_reg(0x1F, 0x0090); /* Power Control 6 */
TickTock 10:aca12a61d2b1 254 wait_ms(5); /* Delay 5 ms */
TickTock 10:aca12a61d2b1 255 wr_reg(0x1F, 0x00D0); /* Power Control 6 */
TickTock 10:aca12a61d2b1 256 wait_ms(5); /* Delay 5 ms */
TickTock 10:aca12a61d2b1 257
TickTock 10:aca12a61d2b1 258 wr_reg(0x17, 0x0005); /* Colmod 16Bit/Pixel */
TickTock 10:aca12a61d2b1 259
TickTock 10:aca12a61d2b1 260 wr_reg(0x36, 0x0000); /* Panel Characteristic */
TickTock 10:aca12a61d2b1 261 wr_reg(0x28, 0x0038); /* Display Control 3 */
TickTock 10:aca12a61d2b1 262 wait_ms(40);
TickTock 10:aca12a61d2b1 263 wr_reg(0x28, 0x003C); /* Display Control 3 */
TickTock 10:aca12a61d2b1 264 switch (orientation) {
TickTock 10:aca12a61d2b1 265 case 0:
TickTock 10:aca12a61d2b1 266 wr_reg(0x16, 0x0008);
TickTock 10:aca12a61d2b1 267 break;
TickTock 10:aca12a61d2b1 268 case 1:
TickTock 10:aca12a61d2b1 269 wr_reg(0x16, 0x0068);
TickTock 10:aca12a61d2b1 270 break;
TickTock 10:aca12a61d2b1 271 case 2:
TickTock 10:aca12a61d2b1 272 wr_reg(0x16, 0x00C8);
TickTock 10:aca12a61d2b1 273 break;
TickTock 10:aca12a61d2b1 274 case 3:
TickTock 10:aca12a61d2b1 275 wr_reg(0x16, 0x00A8);
TickTock 10:aca12a61d2b1 276 break;
TickTock 10:aca12a61d2b1 277 }
TickTock 10:aca12a61d2b1 278 #if defined USE_DMA
TickTock 10:aca12a61d2b1 279 // setup DMA channel 0
TickTock 10:aca12a61d2b1 280 // Power up the GPDMA.
TickTock 10:aca12a61d2b1 281 LPC_SC->PCONP |= (1UL << 29);
TickTock 10:aca12a61d2b1 282 LPC_GPDMA->DMACConfig = 1; // enable DMA controller
TickTock 10:aca12a61d2b1 283 // Reset the Interrupt status
TickTock 10:aca12a61d2b1 284 LPC_GPDMA->DMACIntTCClear = 0x1;
TickTock 10:aca12a61d2b1 285 LPC_GPDMA->DMACIntErrClr = 0x1;
TickTock 10:aca12a61d2b1 286 LPC_GPDMACH0->DMACCLLI = 0;
TickTock 10:aca12a61d2b1 287 #endif
TickTock 10:aca12a61d2b1 288
TickTock 10:aca12a61d2b1 289 WindowMax ();
TickTock 10:aca12a61d2b1 290 }
TickTock 10:aca12a61d2b1 291
TickTock 10:aca12a61d2b1 292
TickTock 10:aca12a61d2b1 293 void SPI_TFTx2::pixel(int x, int y, int color)
TickTock 10:aca12a61d2b1 294 {
TickTock 10:aca12a61d2b1 295 unsigned char u,l;
TickTock 10:aca12a61d2b1 296 wr_reg(0x03, (x >> 0));
TickTock 10:aca12a61d2b1 297 wr_reg(0x02, (x >> 8));
TickTock 10:aca12a61d2b1 298 wr_reg(0x07, (y >> 0));
TickTock 10:aca12a61d2b1 299 wr_reg(0x06, (y >> 8));
TickTock 10:aca12a61d2b1 300 wr_cmd(0x22);
TickTock 10:aca12a61d2b1 301 u = color >> 8;
TickTock 10:aca12a61d2b1 302 l = color & 0xff;
TickTock 10:aca12a61d2b1 303 if (seldisp == 0) {
TickTock 10:aca12a61d2b1 304 _cs0 = 0;
TickTock 10:aca12a61d2b1 305 _cs1 = 1;
TickTock 10:aca12a61d2b1 306 } else if (seldisp == 1) {
TickTock 10:aca12a61d2b1 307 _cs0 = 1;
TickTock 10:aca12a61d2b1 308 _cs1 = 0;
TickTock 10:aca12a61d2b1 309 } else {
TickTock 10:aca12a61d2b1 310 _cs0 = 0;
TickTock 10:aca12a61d2b1 311 _cs1 = 0;
TickTock 10:aca12a61d2b1 312 }
TickTock 10:aca12a61d2b1 313 if (spi_port == 0) { // TFT on SSP0
TickTock 10:aca12a61d2b1 314 LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit
TickTock 10:aca12a61d2b1 315 LPC_SSP0->DR = 0x72; // start Data
TickTock 10:aca12a61d2b1 316 LPC_SSP0->DR = u; // high byte
TickTock 10:aca12a61d2b1 317 LPC_SSP0->DR = l; // low byte
TickTock 10:aca12a61d2b1 318 LPC_SSP0->CR0 |= 0x08UL; // set back to 16 bit
TickTock 10:aca12a61d2b1 319 // we have to wait for SPI IDLE to set CS back to high
TickTock 10:aca12a61d2b1 320 do {
TickTock 10:aca12a61d2b1 321 } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI0 not idle
TickTock 10:aca12a61d2b1 322 } else {
TickTock 10:aca12a61d2b1 323 LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit
TickTock 10:aca12a61d2b1 324 LPC_SSP1->DR = 0x72; // start Data
TickTock 10:aca12a61d2b1 325 LPC_SSP1->DR = u;
TickTock 10:aca12a61d2b1 326 LPC_SSP1->DR = l;
TickTock 10:aca12a61d2b1 327 LPC_SSP1->CR0 |= 0x08UL; // set back to 16 bit
TickTock 10:aca12a61d2b1 328 // we have to wait for SPI IDLE to set CS back to high
TickTock 10:aca12a61d2b1 329 do {
TickTock 10:aca12a61d2b1 330 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI1 not idle
TickTock 10:aca12a61d2b1 331 }
TickTock 10:aca12a61d2b1 332 _cs0 = 1;
TickTock 10:aca12a61d2b1 333 _cs1 = 1;
TickTock 10:aca12a61d2b1 334 }
TickTock 10:aca12a61d2b1 335
TickTock 10:aca12a61d2b1 336
TickTock 10:aca12a61d2b1 337 void SPI_TFTx2::window (unsigned int x, unsigned int y, unsigned int w, unsigned int h)
TickTock 10:aca12a61d2b1 338 {
TickTock 10:aca12a61d2b1 339 wr_reg(0x03, x );
TickTock 10:aca12a61d2b1 340 wr_reg(0x02, (x >> 8));
TickTock 10:aca12a61d2b1 341 wr_reg(0x05, x+w-1 );
TickTock 10:aca12a61d2b1 342 wr_reg(0x04, (x+w-1 >> 8));
TickTock 10:aca12a61d2b1 343 wr_reg(0x07, y );
TickTock 10:aca12a61d2b1 344 wr_reg(0x06, ( y >> 8));
TickTock 10:aca12a61d2b1 345 wr_reg(0x09, ( y+h-1 ));
TickTock 10:aca12a61d2b1 346 wr_reg(0x08, ( y+h-1 >> 8));
TickTock 10:aca12a61d2b1 347 }
TickTock 10:aca12a61d2b1 348
TickTock 10:aca12a61d2b1 349
TickTock 10:aca12a61d2b1 350 void SPI_TFTx2::WindowMax (void)
TickTock 10:aca12a61d2b1 351 {
TickTock 10:aca12a61d2b1 352 window (0, 0, width(), height());
TickTock 10:aca12a61d2b1 353 }
TickTock 10:aca12a61d2b1 354
TickTock 10:aca12a61d2b1 355
TickTock 10:aca12a61d2b1 356 void SPI_TFTx2::cls (void)
TickTock 10:aca12a61d2b1 357 {
TickTock 10:aca12a61d2b1 358 int pixel = ( width() * height());
TickTock 10:aca12a61d2b1 359 #if defined USE_DMA
TickTock 10:aca12a61d2b1 360 int dma_count;
TickTock 10:aca12a61d2b1 361 int color = _background;
TickTock 10:aca12a61d2b1 362 #endif
TickTock 10:aca12a61d2b1 363 WindowMax();
TickTock 10:aca12a61d2b1 364 wr_cmd(0x22);
TickTock 10:aca12a61d2b1 365
TickTock 10:aca12a61d2b1 366 // The SSEL signal is held low until the spi FIFO is emty.
TickTock 10:aca12a61d2b1 367 // We have to lower the SPI clock for the 8 bit start to get the spi running
TickTock 10:aca12a61d2b1 368 // until the next data word
TickTock 10:aca12a61d2b1 369 #if defined USE_DMA
TickTock 10:aca12a61d2b1 370 LPC_GPDMACH0->DMACCSrcAddr = (uint32_t)&color;
TickTock 10:aca12a61d2b1 371 #endif
TickTock 10:aca12a61d2b1 372 if (seldisp == 0) {
TickTock 10:aca12a61d2b1 373 _cs0 = 0;
TickTock 10:aca12a61d2b1 374 _cs1 = 1;
TickTock 10:aca12a61d2b1 375 } else if (seldisp == 1) {
TickTock 10:aca12a61d2b1 376 _cs0 = 1;
TickTock 10:aca12a61d2b1 377 _cs1 = 0;
TickTock 10:aca12a61d2b1 378 } else {
TickTock 10:aca12a61d2b1 379 _cs0 = 0;
TickTock 10:aca12a61d2b1 380 _cs1 = 0;
TickTock 10:aca12a61d2b1 381 }
TickTock 10:aca12a61d2b1 382 if (spi_port == 0) { // TFT on SSP0
TickTock 10:aca12a61d2b1 383 #if defined USE_DMA
TickTock 10:aca12a61d2b1 384 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR; // we send to SSP0
TickTock 10:aca12a61d2b1 385 /* Enable SSP0 for DMA. */
TickTock 10:aca12a61d2b1 386 LPC_SSP0->DMACR = 0x2;
TickTock 10:aca12a61d2b1 387 #endif
TickTock 10:aca12a61d2b1 388 LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit
TickTock 10:aca12a61d2b1 389 LPC_SSP0->DR = 0x72; // start byte
TickTock 10:aca12a61d2b1 390 LPC_SSP0->CR0 |= 0x08UL; // set to 16 bit
TickTock 10:aca12a61d2b1 391 } else {
TickTock 10:aca12a61d2b1 392 #if defined USE_DMA
TickTock 10:aca12a61d2b1 393 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP1->DR; // we send to SSP1
TickTock 10:aca12a61d2b1 394 /* Enable SSP1 for DMA. */
TickTock 10:aca12a61d2b1 395 LPC_SSP1->DMACR = 0x2;
TickTock 10:aca12a61d2b1 396 #endif
TickTock 10:aca12a61d2b1 397 LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit
TickTock 10:aca12a61d2b1 398 LPC_SSP1->DR = 0x72; // start Data
TickTock 10:aca12a61d2b1 399 LPC_SSP1->CR0 |= 0x08UL; // set to 16 bit
TickTock 10:aca12a61d2b1 400 }
TickTock 10:aca12a61d2b1 401
TickTock 10:aca12a61d2b1 402 #if defined USE_DMA
TickTock 10:aca12a61d2b1 403 // start DMA
TickTock 10:aca12a61d2b1 404 do {
TickTock 10:aca12a61d2b1 405 if (pixel > 4095) {
TickTock 10:aca12a61d2b1 406 dma_count = 4095;
TickTock 10:aca12a61d2b1 407 pixel = pixel - 4095;
TickTock 10:aca12a61d2b1 408 } else {
TickTock 10:aca12a61d2b1 409 dma_count = pixel;
TickTock 10:aca12a61d2b1 410 pixel = 0;
TickTock 10:aca12a61d2b1 411 }
TickTock 10:aca12a61d2b1 412 LPC_GPDMA->DMACIntTCClear = 0x1;
TickTock 10:aca12a61d2b1 413 LPC_GPDMA->DMACIntErrClr = 0x1;
TickTock 10:aca12a61d2b1 414 LPC_GPDMACH0->DMACCControl = dma_count | (1UL << 18) | (1UL << 21) | (1UL << 31) ; // 16 bit transfer , no address increment, interrupt
TickTock 10:aca12a61d2b1 415 LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | (spi_port ? DMA_DEST_SSP1_TX : DMA_DEST_SSP0_TX);
TickTock 10:aca12a61d2b1 416 LPC_GPDMA->DMACSoftSReq = 0x1; // DMA request
TickTock 10:aca12a61d2b1 417
TickTock 10:aca12a61d2b1 418 do {
TickTock 10:aca12a61d2b1 419 } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running
TickTock 10:aca12a61d2b1 420
TickTock 10:aca12a61d2b1 421 } while (pixel > 0);
TickTock 10:aca12a61d2b1 422 if (spi_port == 0) { // TFT on SSP0
TickTock 10:aca12a61d2b1 423 do {
TickTock 10:aca12a61d2b1 424 } while ((0x0010 & LPC_SSP0->SR) == 0x10); // SPI FIFO not empty
TickTock 10:aca12a61d2b1 425 /* disable SSP0 for DMA. */
TickTock 10:aca12a61d2b1 426 LPC_SSP0->DMACR = 0x0;
TickTock 10:aca12a61d2b1 427 } else {
TickTock 10:aca12a61d2b1 428 do {
TickTock 10:aca12a61d2b1 429 } while ((0x0010 & LPC_SSP1->SR) == 0x10); // SPI FIFO not empty
TickTock 10:aca12a61d2b1 430 /* disable SSP1 for DMA. */
TickTock 10:aca12a61d2b1 431 LPC_SSP1->DMACR = 0x0;
TickTock 10:aca12a61d2b1 432 }
TickTock 10:aca12a61d2b1 433 #else // no DMA
TickTock 10:aca12a61d2b1 434 unsigned int i;
TickTock 10:aca12a61d2b1 435 for (i = 0; i < ( width() * height()); i++)
TickTock 10:aca12a61d2b1 436 _spi.write(_background);
TickTock 10:aca12a61d2b1 437 #endif
TickTock 10:aca12a61d2b1 438 _cs0 = 1;
TickTock 10:aca12a61d2b1 439 _cs1 = 1;
TickTock 10:aca12a61d2b1 440 }
TickTock 10:aca12a61d2b1 441
TickTock 10:aca12a61d2b1 442 void SPI_TFTx2::circle(int x0, int y0, int r, int color)
TickTock 10:aca12a61d2b1 443 {
TickTock 10:aca12a61d2b1 444
TickTock 10:aca12a61d2b1 445 int draw_x0, draw_y0;
TickTock 10:aca12a61d2b1 446 int draw_x1, draw_y1;
TickTock 10:aca12a61d2b1 447 int draw_x2, draw_y2;
TickTock 10:aca12a61d2b1 448 int draw_x3, draw_y3;
TickTock 10:aca12a61d2b1 449 int draw_x4, draw_y4;
TickTock 10:aca12a61d2b1 450 int draw_x5, draw_y5;
TickTock 10:aca12a61d2b1 451 int draw_x6, draw_y6;
TickTock 10:aca12a61d2b1 452 int draw_x7, draw_y7;
TickTock 10:aca12a61d2b1 453 int xx, yy;
TickTock 10:aca12a61d2b1 454 int di;
TickTock 10:aca12a61d2b1 455 //WindowMax();
TickTock 10:aca12a61d2b1 456 if (r == 0) { /* no radius */
TickTock 10:aca12a61d2b1 457 return;
TickTock 10:aca12a61d2b1 458 }
TickTock 10:aca12a61d2b1 459
TickTock 10:aca12a61d2b1 460 draw_x0 = draw_x1 = x0;
TickTock 10:aca12a61d2b1 461 draw_y0 = draw_y1 = y0 + r;
TickTock 10:aca12a61d2b1 462 if (draw_y0 < height()) {
TickTock 10:aca12a61d2b1 463 pixel(draw_x0, draw_y0, color); /* 90 degree */
TickTock 10:aca12a61d2b1 464 }
TickTock 10:aca12a61d2b1 465
TickTock 10:aca12a61d2b1 466 draw_x2 = draw_x3 = x0;
TickTock 10:aca12a61d2b1 467 draw_y2 = draw_y3 = y0 - r;
TickTock 10:aca12a61d2b1 468 if (draw_y2 >= 0) {
TickTock 10:aca12a61d2b1 469 pixel(draw_x2, draw_y2, color); /* 270 degree */
TickTock 10:aca12a61d2b1 470 }
TickTock 10:aca12a61d2b1 471
TickTock 10:aca12a61d2b1 472 draw_x4 = draw_x6 = x0 + r;
TickTock 10:aca12a61d2b1 473 draw_y4 = draw_y6 = y0;
TickTock 10:aca12a61d2b1 474 if (draw_x4 < width()) {
TickTock 10:aca12a61d2b1 475 pixel(draw_x4, draw_y4, color); /* 0 degree */
TickTock 10:aca12a61d2b1 476 }
TickTock 10:aca12a61d2b1 477
TickTock 10:aca12a61d2b1 478 draw_x5 = draw_x7 = x0 - r;
TickTock 10:aca12a61d2b1 479 draw_y5 = draw_y7 = y0;
TickTock 10:aca12a61d2b1 480 if (draw_x5>=0) {
TickTock 10:aca12a61d2b1 481 pixel(draw_x5, draw_y5, color); /* 180 degree */
TickTock 10:aca12a61d2b1 482 }
TickTock 10:aca12a61d2b1 483
TickTock 10:aca12a61d2b1 484 if (r == 1) {
TickTock 10:aca12a61d2b1 485 return;
TickTock 10:aca12a61d2b1 486 }
TickTock 10:aca12a61d2b1 487
TickTock 10:aca12a61d2b1 488 di = 3 - 2*r;
TickTock 10:aca12a61d2b1 489 xx = 0;
TickTock 10:aca12a61d2b1 490 yy = r;
TickTock 10:aca12a61d2b1 491 while (xx < yy) {
TickTock 10:aca12a61d2b1 492
TickTock 10:aca12a61d2b1 493 if (di < 0) {
TickTock 10:aca12a61d2b1 494 di += 4*xx + 6;
TickTock 10:aca12a61d2b1 495 } else {
TickTock 10:aca12a61d2b1 496 di += 4*(xx - yy) + 10;
TickTock 10:aca12a61d2b1 497 yy--;
TickTock 10:aca12a61d2b1 498 draw_y0--;
TickTock 10:aca12a61d2b1 499 draw_y1--;
TickTock 10:aca12a61d2b1 500 draw_y2++;
TickTock 10:aca12a61d2b1 501 draw_y3++;
TickTock 10:aca12a61d2b1 502 draw_x4--;
TickTock 10:aca12a61d2b1 503 draw_x5++;
TickTock 10:aca12a61d2b1 504 draw_x6--;
TickTock 10:aca12a61d2b1 505 draw_x7++;
TickTock 10:aca12a61d2b1 506 }
TickTock 10:aca12a61d2b1 507 xx++;
TickTock 10:aca12a61d2b1 508 draw_x0++;
TickTock 10:aca12a61d2b1 509 draw_x1--;
TickTock 10:aca12a61d2b1 510 draw_x2++;
TickTock 10:aca12a61d2b1 511 draw_x3--;
TickTock 10:aca12a61d2b1 512 draw_y4++;
TickTock 10:aca12a61d2b1 513 draw_y5++;
TickTock 10:aca12a61d2b1 514 draw_y6--;
TickTock 10:aca12a61d2b1 515 draw_y7--;
TickTock 10:aca12a61d2b1 516
TickTock 10:aca12a61d2b1 517 if ( (draw_x0 <= width()) && (draw_y0>=0) ) {
TickTock 10:aca12a61d2b1 518 pixel(draw_x0, draw_y0, color);
TickTock 10:aca12a61d2b1 519 }
TickTock 10:aca12a61d2b1 520
TickTock 10:aca12a61d2b1 521 if ( (draw_x1 >= 0) && (draw_y1 >= 0) ) {
TickTock 10:aca12a61d2b1 522 pixel(draw_x1, draw_y1, color);
TickTock 10:aca12a61d2b1 523 }
TickTock 10:aca12a61d2b1 524
TickTock 10:aca12a61d2b1 525 if ( (draw_x2 <= width()) && (draw_y2 <= height()) ) {
TickTock 10:aca12a61d2b1 526 pixel(draw_x2, draw_y2, color);
TickTock 10:aca12a61d2b1 527 }
TickTock 10:aca12a61d2b1 528
TickTock 10:aca12a61d2b1 529 if ( (draw_x3 >=0 ) && (draw_y3 <= height()) ) {
TickTock 10:aca12a61d2b1 530 pixel(draw_x3, draw_y3, color);
TickTock 10:aca12a61d2b1 531 }
TickTock 10:aca12a61d2b1 532
TickTock 10:aca12a61d2b1 533 if ( (draw_x4 <= width()) && (draw_y4 >= 0) ) {
TickTock 10:aca12a61d2b1 534 pixel(draw_x4, draw_y4, color);
TickTock 10:aca12a61d2b1 535 }
TickTock 10:aca12a61d2b1 536
TickTock 10:aca12a61d2b1 537 if ( (draw_x5 >= 0) && (draw_y5 >= 0) ) {
TickTock 10:aca12a61d2b1 538 pixel(draw_x5, draw_y5, color);
TickTock 10:aca12a61d2b1 539 }
TickTock 10:aca12a61d2b1 540 if ( (draw_x6 <=width()) && (draw_y6 <= height()) ) {
TickTock 10:aca12a61d2b1 541 pixel(draw_x6, draw_y6, color);
TickTock 10:aca12a61d2b1 542 }
TickTock 10:aca12a61d2b1 543 if ( (draw_x7 >= 0) && (draw_y7 <= height()) ) {
TickTock 10:aca12a61d2b1 544 pixel(draw_x7, draw_y7, color);
TickTock 10:aca12a61d2b1 545 }
TickTock 10:aca12a61d2b1 546 }
TickTock 10:aca12a61d2b1 547 return;
TickTock 10:aca12a61d2b1 548 }
TickTock 10:aca12a61d2b1 549
TickTock 10:aca12a61d2b1 550 void SPI_TFTx2::fillcircle(int x, int y, int r, int color)
TickTock 10:aca12a61d2b1 551 {
TickTock 10:aca12a61d2b1 552 int i;
TickTock 10:aca12a61d2b1 553 for (i = 0; i <= r; i++)
TickTock 10:aca12a61d2b1 554 circle(x,y,i,color);
TickTock 10:aca12a61d2b1 555 }
TickTock 10:aca12a61d2b1 556
TickTock 10:aca12a61d2b1 557
TickTock 10:aca12a61d2b1 558
TickTock 10:aca12a61d2b1 559 void SPI_TFTx2::hline(int x0, int x1, int y, int color)
TickTock 10:aca12a61d2b1 560 {
TickTock 10:aca12a61d2b1 561 int w,i;
TickTock 10:aca12a61d2b1 562 w = x1 - x0 + 1;
TickTock 10:aca12a61d2b1 563 window(x0,y,w,1);
TickTock 10:aca12a61d2b1 564 wr_cmd(0x22);
TickTock 10:aca12a61d2b1 565 if (seldisp == 0) {
TickTock 10:aca12a61d2b1 566 _cs0 = 0;
TickTock 10:aca12a61d2b1 567 _cs1 = 1;
TickTock 10:aca12a61d2b1 568 } else if (seldisp == 1) {
TickTock 10:aca12a61d2b1 569 _cs0 = 1;
TickTock 10:aca12a61d2b1 570 _cs1 = 0;
TickTock 10:aca12a61d2b1 571 } else {
TickTock 10:aca12a61d2b1 572 _cs0 = 0;
TickTock 10:aca12a61d2b1 573 _cs1 = 0;
TickTock 10:aca12a61d2b1 574 }
TickTock 10:aca12a61d2b1 575 if (spi_port == 0) { // TFT on SSP0
TickTock 10:aca12a61d2b1 576 for (i = 0; i < ( width() * height()); i++)
TickTock 10:aca12a61d2b1 577 #if defined USE_DMA
TickTock 10:aca12a61d2b1 578 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR; // we send to SSP0
TickTock 10:aca12a61d2b1 579 /* Enable SSP0 for DMA. */
TickTock 10:aca12a61d2b1 580 LPC_SSP0->DMACR = 0x2;
TickTock 10:aca12a61d2b1 581 #endif
TickTock 10:aca12a61d2b1 582 LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit
TickTock 10:aca12a61d2b1 583 LPC_SSP0->DR = 0x72; // start Data
TickTock 10:aca12a61d2b1 584 LPC_SSP0->CR0 |= 0x08UL; // set to 16 bit
TickTock 10:aca12a61d2b1 585 } else {
TickTock 10:aca12a61d2b1 586 #if defined USE_DMA
TickTock 10:aca12a61d2b1 587 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP1->DR; // we send to SSP1
TickTock 10:aca12a61d2b1 588 /* Enable SSP1 for DMA. */
TickTock 10:aca12a61d2b1 589 LPC_SSP1->DMACR = 0x2;
TickTock 10:aca12a61d2b1 590 #endif
TickTock 10:aca12a61d2b1 591 LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit
TickTock 10:aca12a61d2b1 592 LPC_SSP1->DR = 0x72; // start Data
TickTock 10:aca12a61d2b1 593 LPC_SSP1->CR0 |= 0x08UL; // set to 16 bit
TickTock 10:aca12a61d2b1 594 }
TickTock 10:aca12a61d2b1 595 #if defined USE_DMA
TickTock 10:aca12a61d2b1 596 LPC_GPDMA->DMACIntTCClear = 0x1;
TickTock 10:aca12a61d2b1 597 LPC_GPDMA->DMACIntErrClr = 0x1;
TickTock 10:aca12a61d2b1 598 LPC_GPDMACH0->DMACCSrcAddr = (uint32_t)&color;
TickTock 10:aca12a61d2b1 599 LPC_GPDMACH0->DMACCControl = w | (1UL << 18) | (1UL << 21) | (1UL << 31) ; // 16 bit transfer , no address increment, interrupt
TickTock 10:aca12a61d2b1 600 LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | (spi_port ? DMA_DEST_SSP1_TX : DMA_DEST_SSP0_TX);
TickTock 10:aca12a61d2b1 601 LPC_GPDMA->DMACSoftSReq = 0x1; // start DMA
TickTock 10:aca12a61d2b1 602 do {
TickTock 10:aca12a61d2b1 603 } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running
TickTock 10:aca12a61d2b1 604 if (spi_port == 0) { // TFT on SSP0
TickTock 10:aca12a61d2b1 605 do {
TickTock 10:aca12a61d2b1 606 } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI FIFO not empty
TickTock 10:aca12a61d2b1 607 } else {
TickTock 10:aca12a61d2b1 608 do {
TickTock 10:aca12a61d2b1 609 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI FIFO not empty
TickTock 10:aca12a61d2b1 610 }
TickTock 10:aca12a61d2b1 611 #else
TickTock 10:aca12a61d2b1 612 for (i=0; i<w; i++) {
TickTock 10:aca12a61d2b1 613 _spi.write(color);
TickTock 10:aca12a61d2b1 614 }
TickTock 10:aca12a61d2b1 615
TickTock 10:aca12a61d2b1 616 #endif
TickTock 10:aca12a61d2b1 617 _cs0 = 1;
TickTock 10:aca12a61d2b1 618 _cs1 = 1;
TickTock 10:aca12a61d2b1 619 WindowMax();
TickTock 10:aca12a61d2b1 620 return;
TickTock 10:aca12a61d2b1 621 }
TickTock 10:aca12a61d2b1 622
TickTock 10:aca12a61d2b1 623 void SPI_TFTx2::vline(int x, int y0, int y1, int color)
TickTock 10:aca12a61d2b1 624 {
TickTock 10:aca12a61d2b1 625 int h;
TickTock 10:aca12a61d2b1 626 h = y1 - y0 + 1;
TickTock 10:aca12a61d2b1 627 window(x,y0,1,h);
TickTock 10:aca12a61d2b1 628 wr_cmd(0x22);
TickTock 10:aca12a61d2b1 629 if (seldisp == 0) {
TickTock 10:aca12a61d2b1 630 _cs0 = 0;
TickTock 10:aca12a61d2b1 631 _cs1 = 1;
TickTock 10:aca12a61d2b1 632 } else if (seldisp == 1) {
TickTock 10:aca12a61d2b1 633 _cs0 = 1;
TickTock 10:aca12a61d2b1 634 _cs1 = 0;
TickTock 10:aca12a61d2b1 635 } else {
TickTock 10:aca12a61d2b1 636 _cs0 = 0;
TickTock 10:aca12a61d2b1 637 _cs1 = 0;
TickTock 10:aca12a61d2b1 638 }
TickTock 10:aca12a61d2b1 639 if (spi_port == 0) { // TFT on SSP0
TickTock 10:aca12a61d2b1 640 #if defined USE_DMA
TickTock 10:aca12a61d2b1 641 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR; // we send to SSP0
TickTock 10:aca12a61d2b1 642 /* Enable SSP0 for DMA. */
TickTock 10:aca12a61d2b1 643 LPC_SSP0->DMACR = 0x2;
TickTock 10:aca12a61d2b1 644 #endif
TickTock 10:aca12a61d2b1 645 LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit
TickTock 10:aca12a61d2b1 646 LPC_SSP0->DR = 0x72; // start Data
TickTock 10:aca12a61d2b1 647 LPC_SSP0->CR0 |= 0x08UL; // set to 16 bit
TickTock 10:aca12a61d2b1 648 } else {
TickTock 10:aca12a61d2b1 649 #if defined USE_DMA
TickTock 10:aca12a61d2b1 650 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP1->DR; // we send to SSP1
TickTock 10:aca12a61d2b1 651 /* Enable SSP1 for DMA. */
TickTock 10:aca12a61d2b1 652 LPC_SSP1->DMACR = 0x2;
TickTock 10:aca12a61d2b1 653 #endif
TickTock 10:aca12a61d2b1 654 LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit
TickTock 10:aca12a61d2b1 655 LPC_SSP1->DR = 0x72; // start Data
TickTock 10:aca12a61d2b1 656 LPC_SSP1->CR0 |= 0x08UL; // set to 16 bit
TickTock 10:aca12a61d2b1 657 }
TickTock 10:aca12a61d2b1 658 #if defined USE_DMA
TickTock 10:aca12a61d2b1 659 LPC_GPDMA->DMACIntTCClear = 0x1;
TickTock 10:aca12a61d2b1 660 LPC_GPDMA->DMACIntErrClr = 0x1;
TickTock 10:aca12a61d2b1 661 LPC_GPDMACH0->DMACCSrcAddr = (uint32_t)&color;
TickTock 10:aca12a61d2b1 662 LPC_GPDMACH0->DMACCControl = h | (1UL << 18) | (1UL << 21) | (1UL << 31) ; // 16 bit transfer , no address increment, interrupt
TickTock 10:aca12a61d2b1 663 LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | (spi_port ? DMA_DEST_SSP1_TX : DMA_DEST_SSP0_TX);
TickTock 10:aca12a61d2b1 664 LPC_GPDMA->DMACSoftSReq = 0x1;
TickTock 10:aca12a61d2b1 665 do {
TickTock 10:aca12a61d2b1 666 } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running
TickTock 10:aca12a61d2b1 667
TickTock 10:aca12a61d2b1 668 if (spi_port == 0) { // TFT on SSP0
TickTock 10:aca12a61d2b1 669 do {
TickTock 10:aca12a61d2b1 670 } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI FIFO not empty
TickTock 10:aca12a61d2b1 671 } else {
TickTock 10:aca12a61d2b1 672 do {
TickTock 10:aca12a61d2b1 673 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI FIFO not empty
TickTock 10:aca12a61d2b1 674 }
TickTock 10:aca12a61d2b1 675 #else
TickTock 10:aca12a61d2b1 676 for (int y=0; y<h; y++) {
TickTock 10:aca12a61d2b1 677 _spi.write(color);
TickTock 10:aca12a61d2b1 678 }
TickTock 10:aca12a61d2b1 679 #endif
TickTock 10:aca12a61d2b1 680 _cs0 = 1;
TickTock 10:aca12a61d2b1 681 _cs1 = 1;
TickTock 10:aca12a61d2b1 682 WindowMax();
TickTock 10:aca12a61d2b1 683 return;
TickTock 10:aca12a61d2b1 684 }
TickTock 10:aca12a61d2b1 685
TickTock 10:aca12a61d2b1 686 void SPI_TFTx2::line(int x0, int y0, int x1, int y1, int color)
TickTock 10:aca12a61d2b1 687 {
TickTock 10:aca12a61d2b1 688 //WindowMax();
TickTock 10:aca12a61d2b1 689 int dx = 0, dy = 0;
TickTock 10:aca12a61d2b1 690 int dx_sym = 0, dy_sym = 0;
TickTock 10:aca12a61d2b1 691 int dx_x2 = 0, dy_x2 = 0;
TickTock 10:aca12a61d2b1 692 int di = 0;
TickTock 10:aca12a61d2b1 693
TickTock 10:aca12a61d2b1 694 dx = x1-x0;
TickTock 10:aca12a61d2b1 695 dy = y1-y0;
TickTock 10:aca12a61d2b1 696
TickTock 10:aca12a61d2b1 697 // vline and hline are very slow for some reason so not using
TickTock 10:aca12a61d2b1 698 //if (dx == 0) { /* vertical line */
TickTock 10:aca12a61d2b1 699 // if (y1 > y0) vline(x0,y0,y1,color);
TickTock 10:aca12a61d2b1 700 // else vline(x0,y1,y0,color);
TickTock 10:aca12a61d2b1 701 // return;
TickTock 10:aca12a61d2b1 702 //}
TickTock 10:aca12a61d2b1 703
TickTock 10:aca12a61d2b1 704 if (dx > 0) {
TickTock 10:aca12a61d2b1 705 dx_sym = 1;
TickTock 10:aca12a61d2b1 706 } else {
TickTock 10:aca12a61d2b1 707 dx_sym = -1;
TickTock 10:aca12a61d2b1 708 }
TickTock 10:aca12a61d2b1 709 //if (dy == 0) { /* horizontal line */
TickTock 10:aca12a61d2b1 710 // if (x1 > x0) hline(x0,x1,y0,color);
TickTock 10:aca12a61d2b1 711 // else hline(x1,x0,y0,color);
TickTock 10:aca12a61d2b1 712 // return;
TickTock 10:aca12a61d2b1 713 //}
TickTock 10:aca12a61d2b1 714
TickTock 10:aca12a61d2b1 715 if (dy > 0) {
TickTock 10:aca12a61d2b1 716 dy_sym = 1;
TickTock 10:aca12a61d2b1 717 } else {
TickTock 10:aca12a61d2b1 718 dy_sym = -1;
TickTock 10:aca12a61d2b1 719 }
TickTock 10:aca12a61d2b1 720
TickTock 10:aca12a61d2b1 721 dx = dx_sym*dx;
TickTock 10:aca12a61d2b1 722 dy = dy_sym*dy;
TickTock 10:aca12a61d2b1 723
TickTock 10:aca12a61d2b1 724 dx_x2 = dx*2;
TickTock 10:aca12a61d2b1 725 dy_x2 = dy*2;
TickTock 10:aca12a61d2b1 726
TickTock 10:aca12a61d2b1 727 if (dx >= dy) {
TickTock 10:aca12a61d2b1 728 di = dy_x2 - dx;
TickTock 10:aca12a61d2b1 729 while (x0 != x1) {
TickTock 10:aca12a61d2b1 730
TickTock 10:aca12a61d2b1 731 pixel(x0, y0, color);
TickTock 10:aca12a61d2b1 732 x0 += dx_sym;
TickTock 10:aca12a61d2b1 733 if (di<0) {
TickTock 10:aca12a61d2b1 734 di += dy_x2;
TickTock 10:aca12a61d2b1 735 } else {
TickTock 10:aca12a61d2b1 736 di += dy_x2 - dx_x2;
TickTock 10:aca12a61d2b1 737 y0 += dy_sym;
TickTock 10:aca12a61d2b1 738 }
TickTock 10:aca12a61d2b1 739 }
TickTock 10:aca12a61d2b1 740 pixel(x0, y0, color);
TickTock 10:aca12a61d2b1 741 } else {
TickTock 10:aca12a61d2b1 742 di = dx_x2 - dy;
TickTock 10:aca12a61d2b1 743 while (y0 != y1) {
TickTock 10:aca12a61d2b1 744 pixel(x0, y0, color);
TickTock 10:aca12a61d2b1 745 y0 += dy_sym;
TickTock 10:aca12a61d2b1 746 if (di < 0) {
TickTock 10:aca12a61d2b1 747 di += dx_x2;
TickTock 10:aca12a61d2b1 748 } else {
TickTock 10:aca12a61d2b1 749 di += dx_x2 - dy_x2;
TickTock 10:aca12a61d2b1 750 x0 += dx_sym;
TickTock 10:aca12a61d2b1 751 }
TickTock 10:aca12a61d2b1 752 }
TickTock 10:aca12a61d2b1 753 pixel(x0, y0, color);
TickTock 10:aca12a61d2b1 754 }
TickTock 10:aca12a61d2b1 755 return;
TickTock 10:aca12a61d2b1 756 }
TickTock 10:aca12a61d2b1 757
TickTock 10:aca12a61d2b1 758
TickTock 10:aca12a61d2b1 759 void SPI_TFTx2::rect(int x0, int y0, int x1, int y1, int color)
TickTock 10:aca12a61d2b1 760 {
TickTock 10:aca12a61d2b1 761
TickTock 10:aca12a61d2b1 762 if (x1 > x0) hline(x0,x1,y0,color);
TickTock 10:aca12a61d2b1 763 else hline(x1,x0,y0,color);
TickTock 10:aca12a61d2b1 764
TickTock 10:aca12a61d2b1 765 if (y1 > y0) vline(x0,y0,y1,color);
TickTock 10:aca12a61d2b1 766 else vline(x0,y1,y0,color);
TickTock 10:aca12a61d2b1 767
TickTock 10:aca12a61d2b1 768 if (x1 > x0) hline(x0,x1,y1,color);
TickTock 10:aca12a61d2b1 769 else hline(x1,x0,y1,color);
TickTock 10:aca12a61d2b1 770
TickTock 10:aca12a61d2b1 771 if (y1 > y0) vline(x1,y0,y1,color);
TickTock 10:aca12a61d2b1 772 else vline(x1,y1,y0,color);
TickTock 10:aca12a61d2b1 773
TickTock 10:aca12a61d2b1 774 return;
TickTock 10:aca12a61d2b1 775 }
TickTock 10:aca12a61d2b1 776
TickTock 10:aca12a61d2b1 777
TickTock 10:aca12a61d2b1 778
TickTock 10:aca12a61d2b1 779 void SPI_TFTx2::fillrect(int x0, int y0, int x1, int y1, int color)
TickTock 10:aca12a61d2b1 780 {
TickTock 10:aca12a61d2b1 781
TickTock 10:aca12a61d2b1 782 int h = y1 - y0 + 1;
TickTock 10:aca12a61d2b1 783 int w = x1 - x0 + 1;
TickTock 10:aca12a61d2b1 784 int pixel = h * w;
TickTock 10:aca12a61d2b1 785 int dma_count;
TickTock 10:aca12a61d2b1 786 window(x0,y0,w,h);
TickTock 10:aca12a61d2b1 787 wr_cmd(0x22);
TickTock 10:aca12a61d2b1 788 if (seldisp == 0) {
TickTock 10:aca12a61d2b1 789 _cs0 = 0;
TickTock 10:aca12a61d2b1 790 _cs1 = 1;
TickTock 10:aca12a61d2b1 791 } else if (seldisp == 1) {
TickTock 10:aca12a61d2b1 792 _cs0 = 1;
TickTock 10:aca12a61d2b1 793 _cs1 = 0;
TickTock 10:aca12a61d2b1 794 } else {
TickTock 10:aca12a61d2b1 795 _cs0 = 0;
TickTock 10:aca12a61d2b1 796 _cs1 = 0;
TickTock 10:aca12a61d2b1 797 }
TickTock 10:aca12a61d2b1 798 if (spi_port == 0) { // TFT on SSP0
TickTock 10:aca12a61d2b1 799 #if defined USE_DMA
TickTock 10:aca12a61d2b1 800 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR; // we send to SSP0
TickTock 10:aca12a61d2b1 801 /* Enable SSP0 for DMA. */
TickTock 10:aca12a61d2b1 802 LPC_SSP0->DMACR = 0x2;
TickTock 10:aca12a61d2b1 803 #endif
TickTock 10:aca12a61d2b1 804 LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit
TickTock 10:aca12a61d2b1 805 LPC_SSP0->DR = 0x72; // start Data
TickTock 10:aca12a61d2b1 806 LPC_SSP0->CR0 |= 0x08UL; // set to 16 bit
TickTock 10:aca12a61d2b1 807 } else {
TickTock 10:aca12a61d2b1 808 #if defined USE_DMA
TickTock 10:aca12a61d2b1 809 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP1->DR; // we send to SSP1
TickTock 10:aca12a61d2b1 810 /* Enable SSP1 for DMA. */
TickTock 10:aca12a61d2b1 811 LPC_SSP1->DMACR = 0x2;
TickTock 10:aca12a61d2b1 812 #endif
TickTock 10:aca12a61d2b1 813 LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit
TickTock 10:aca12a61d2b1 814 LPC_SSP1->DR = 0x72; // start Data
TickTock 10:aca12a61d2b1 815 LPC_SSP1->CR0 |= 0x08UL; // set to 16 bit
TickTock 10:aca12a61d2b1 816 }
TickTock 10:aca12a61d2b1 817 #if defined USE_DMA
TickTock 10:aca12a61d2b1 818 do {
TickTock 10:aca12a61d2b1 819 if (pixel > 4095) {
TickTock 10:aca12a61d2b1 820 dma_count = 4095;
TickTock 10:aca12a61d2b1 821 pixel = pixel - 4095;
TickTock 10:aca12a61d2b1 822 } else {
TickTock 10:aca12a61d2b1 823 dma_count = pixel;
TickTock 10:aca12a61d2b1 824 pixel = 0;
TickTock 10:aca12a61d2b1 825 }
TickTock 10:aca12a61d2b1 826 LPC_GPDMA->DMACIntTCClear = 0x1;
TickTock 10:aca12a61d2b1 827 LPC_GPDMA->DMACIntErrClr = 0x1;
TickTock 10:aca12a61d2b1 828 LPC_GPDMACH0->DMACCSrcAddr = (uint32_t)&color;
TickTock 10:aca12a61d2b1 829 LPC_GPDMACH0->DMACCControl = dma_count | (1UL << 18) | (1UL << 21) | (1UL << 31) ; // 16 bit transfer , no address increment, interrupt
TickTock 10:aca12a61d2b1 830 LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | (spi_port ? DMA_DEST_SSP1_TX : DMA_DEST_SSP0_TX);
TickTock 10:aca12a61d2b1 831 LPC_GPDMA->DMACSoftSReq = 0x1;
TickTock 10:aca12a61d2b1 832 do {
TickTock 10:aca12a61d2b1 833 } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running
TickTock 10:aca12a61d2b1 834
TickTock 10:aca12a61d2b1 835 } while (pixel > 0);
TickTock 10:aca12a61d2b1 836
TickTock 10:aca12a61d2b1 837 if (spi_port == 0) { // TFT on SSP0
TickTock 10:aca12a61d2b1 838 do {
TickTock 10:aca12a61d2b1 839 } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI FIFO not empty
TickTock 10:aca12a61d2b1 840 } else {
TickTock 10:aca12a61d2b1 841 do {
TickTock 10:aca12a61d2b1 842 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI FIFO not empty
TickTock 10:aca12a61d2b1 843 }
TickTock 10:aca12a61d2b1 844
TickTock 10:aca12a61d2b1 845 #else // no DMA
TickTock 10:aca12a61d2b1 846 for (int p=0; p<pixel; p++) {
TickTock 10:aca12a61d2b1 847 _spi.write(color);
TickTock 10:aca12a61d2b1 848 }
TickTock 10:aca12a61d2b1 849 #endif
TickTock 10:aca12a61d2b1 850
TickTock 10:aca12a61d2b1 851 _cs0 = 1;
TickTock 10:aca12a61d2b1 852 _cs1 = 1;
TickTock 10:aca12a61d2b1 853 WindowMax();
TickTock 10:aca12a61d2b1 854 return;
TickTock 10:aca12a61d2b1 855 }
TickTock 10:aca12a61d2b1 856
TickTock 10:aca12a61d2b1 857
TickTock 10:aca12a61d2b1 858 void SPI_TFTx2::locate(int x, int y)
TickTock 10:aca12a61d2b1 859 {
TickTock 10:aca12a61d2b1 860 char_x = x;
TickTock 10:aca12a61d2b1 861 char_y = y;
TickTock 10:aca12a61d2b1 862 }
TickTock 10:aca12a61d2b1 863
TickTock 10:aca12a61d2b1 864
TickTock 10:aca12a61d2b1 865
TickTock 10:aca12a61d2b1 866 int SPI_TFTx2::columns()
TickTock 10:aca12a61d2b1 867 {
TickTock 10:aca12a61d2b1 868 return width() / font[1];
TickTock 10:aca12a61d2b1 869 }
TickTock 10:aca12a61d2b1 870
TickTock 10:aca12a61d2b1 871
TickTock 10:aca12a61d2b1 872
TickTock 10:aca12a61d2b1 873 int SPI_TFTx2::rows()
TickTock 10:aca12a61d2b1 874 {
TickTock 10:aca12a61d2b1 875 return height() / font[2];
TickTock 10:aca12a61d2b1 876 }
TickTock 10:aca12a61d2b1 877
TickTock 10:aca12a61d2b1 878
TickTock 10:aca12a61d2b1 879
TickTock 10:aca12a61d2b1 880 int SPI_TFTx2::_putc(int value)
TickTock 10:aca12a61d2b1 881 {
TickTock 10:aca12a61d2b1 882 if (value == '\n') { // new line
TickTock 10:aca12a61d2b1 883 char_x = 0;
TickTock 10:aca12a61d2b1 884 char_y = char_y + font[2];
TickTock 10:aca12a61d2b1 885 if (char_y >= height() - font[2]) {
TickTock 10:aca12a61d2b1 886 char_y = 0;
TickTock 10:aca12a61d2b1 887 }
TickTock 10:aca12a61d2b1 888 } else {
TickTock 10:aca12a61d2b1 889 character(char_x, char_y, value);
TickTock 10:aca12a61d2b1 890 }
TickTock 10:aca12a61d2b1 891 return value;
TickTock 10:aca12a61d2b1 892 }
TickTock 10:aca12a61d2b1 893
TickTock 10:aca12a61d2b1 894
TickTock 10:aca12a61d2b1 895
TickTock 10:aca12a61d2b1 896
TickTock 10:aca12a61d2b1 897 void SPI_TFTx2::character(int x, int y, int c)
TickTock 10:aca12a61d2b1 898 {
TickTock 10:aca12a61d2b1 899 unsigned int hor,vert,offset,bpl,j,i,b,p;
TickTock 10:aca12a61d2b1 900 unsigned char* zeichen;
TickTock 10:aca12a61d2b1 901 unsigned char z,w;
TickTock 10:aca12a61d2b1 902 #if defined USE_DMA
TickTock 10:aca12a61d2b1 903 unsigned int pixel;
TickTock 10:aca12a61d2b1 904 unsigned int dma_count,dma_off;
TickTock 10:aca12a61d2b1 905 uint16_t *buffer;
TickTock 10:aca12a61d2b1 906 #endif
TickTock 10:aca12a61d2b1 907
TickTock 10:aca12a61d2b1 908 if ((c < 31) || (c > 127)) return; // test char range
TickTock 10:aca12a61d2b1 909
TickTock 10:aca12a61d2b1 910 // read font parameter from start of array
TickTock 10:aca12a61d2b1 911 offset = font[0]; // bytes / char
TickTock 10:aca12a61d2b1 912 hor = font[1]; // get hor size of font
TickTock 10:aca12a61d2b1 913 vert = font[2]; // get vert size of font
TickTock 10:aca12a61d2b1 914 bpl = font[3]; // bytes per line
TickTock 10:aca12a61d2b1 915
TickTock 10:aca12a61d2b1 916 if (char_x + hor > width()) {
TickTock 10:aca12a61d2b1 917 char_x = 0;
TickTock 10:aca12a61d2b1 918 char_y = char_y + vert;
TickTock 10:aca12a61d2b1 919 if (char_y >= height() - font[2]) {
TickTock 10:aca12a61d2b1 920 char_y = 0;
TickTock 10:aca12a61d2b1 921 }
TickTock 10:aca12a61d2b1 922 }
TickTock 10:aca12a61d2b1 923 window(char_x, char_y,hor,vert); // char box
TickTock 10:aca12a61d2b1 924 wr_cmd(0x22);
TickTock 10:aca12a61d2b1 925
TickTock 10:aca12a61d2b1 926 #if defined USE_DMA
TickTock 10:aca12a61d2b1 927 pixel = hor * vert; // calculate buffer size
TickTock 10:aca12a61d2b1 928
TickTock 10:aca12a61d2b1 929 buffer = (uint16_t *) malloc (2*pixel); // we need a buffer for the 16 bit
TickTock 10:aca12a61d2b1 930 if (buffer == NULL) {
TickTock 10:aca12a61d2b1 931 //led = 1;
TickTock 10:aca12a61d2b1 932 //pc.printf("Malloc error !\n\r");
TickTock 10:aca12a61d2b1 933 return; // error no memory
TickTock 10:aca12a61d2b1 934 }
TickTock 10:aca12a61d2b1 935
TickTock 10:aca12a61d2b1 936 zeichen = &font[((c -32) * offset) + 4]; // start of char bitmap
TickTock 10:aca12a61d2b1 937 w = zeichen[0]; // width of actual char
TickTock 10:aca12a61d2b1 938 p = 0;
TickTock 10:aca12a61d2b1 939 // construct the char into the buffer
TickTock 10:aca12a61d2b1 940 for (j=0; j<vert; j++) { // vert line
TickTock 10:aca12a61d2b1 941 for (i=0; i<hor; i++) { // horz line
TickTock 10:aca12a61d2b1 942 z = zeichen[bpl * i + ((j & 0xF8) >> 3)+1];
TickTock 10:aca12a61d2b1 943 b = 1 << (j & 0x07);
TickTock 10:aca12a61d2b1 944 if (( z & b ) == 0x00) {
TickTock 10:aca12a61d2b1 945 buffer[p] = _background;
TickTock 10:aca12a61d2b1 946 } else {
TickTock 10:aca12a61d2b1 947 buffer[p] = _foreground;
TickTock 10:aca12a61d2b1 948 }
TickTock 10:aca12a61d2b1 949 p++;
TickTock 10:aca12a61d2b1 950 }
TickTock 10:aca12a61d2b1 951 }
TickTock 10:aca12a61d2b1 952
TickTock 10:aca12a61d2b1 953 // copy the buffer with DMA SPI to display
TickTock 10:aca12a61d2b1 954 dma_off = 0; // offset for DMA transfer
TickTock 10:aca12a61d2b1 955 if (seldisp == 0) {
TickTock 10:aca12a61d2b1 956 _cs0 = 0;
TickTock 10:aca12a61d2b1 957 _cs1 = 1;
TickTock 10:aca12a61d2b1 958 } else if (seldisp == 1) {
TickTock 10:aca12a61d2b1 959 _cs0 = 1;
TickTock 10:aca12a61d2b1 960 _cs1 = 0;
TickTock 10:aca12a61d2b1 961 } else {
TickTock 10:aca12a61d2b1 962 _cs0 = 0;
TickTock 10:aca12a61d2b1 963 _cs1 = 0;
TickTock 10:aca12a61d2b1 964 }
TickTock 10:aca12a61d2b1 965 if (spi_port == 0) { // TFT on SSP0
TickTock 10:aca12a61d2b1 966 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR; // we send to SSP0
TickTock 10:aca12a61d2b1 967 /* Enable SSP0 for DMA. */
TickTock 10:aca12a61d2b1 968 LPC_SSP0->DMACR = 0x2;
TickTock 10:aca12a61d2b1 969 LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit
TickTock 10:aca12a61d2b1 970 LPC_SSP0->DR = 0x72; // start Data
TickTock 10:aca12a61d2b1 971 LPC_SSP0->CR0 |= 0x08UL; // set to 16 bit
TickTock 10:aca12a61d2b1 972 } else {
TickTock 10:aca12a61d2b1 973 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP1->DR; // we send to SSP1
TickTock 10:aca12a61d2b1 974 /* Enable SSP1 for DMA. */
TickTock 10:aca12a61d2b1 975 LPC_SSP1->DMACR = 0x2;
TickTock 10:aca12a61d2b1 976 LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit
TickTock 10:aca12a61d2b1 977 LPC_SSP1->DR = 0x72; // start Data
TickTock 10:aca12a61d2b1 978 LPC_SSP1->CR0 |= 0x08UL; // set to 16 bit
TickTock 10:aca12a61d2b1 979 }
TickTock 10:aca12a61d2b1 980
TickTock 10:aca12a61d2b1 981 // start DMA
TickTock 10:aca12a61d2b1 982 do {
TickTock 10:aca12a61d2b1 983 if (pixel > 4095) { // this is a giant font !
TickTock 10:aca12a61d2b1 984 dma_count = 4095;
TickTock 10:aca12a61d2b1 985 pixel = pixel - 4095;
TickTock 10:aca12a61d2b1 986 } else {
TickTock 10:aca12a61d2b1 987 dma_count = pixel;
TickTock 10:aca12a61d2b1 988 pixel = 0;
TickTock 10:aca12a61d2b1 989 }
TickTock 10:aca12a61d2b1 990 LPC_GPDMA->DMACIntTCClear = 0x1;
TickTock 10:aca12a61d2b1 991 LPC_GPDMA->DMACIntErrClr = 0x1;
TickTock 10:aca12a61d2b1 992 LPC_GPDMACH0->DMACCSrcAddr = (uint32_t) (buffer + dma_off);
TickTock 10:aca12a61d2b1 993 LPC_GPDMACH0->DMACCControl = dma_count | (1UL << 18) | (1UL << 21) | (1UL << 31) | DMA_CHANNEL_SRC_INC ; // 16 bit transfer , address increment, interrupt
TickTock 10:aca12a61d2b1 994 LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | (spi_port ? DMA_DEST_SSP1_TX : DMA_DEST_SSP0_TX);
TickTock 10:aca12a61d2b1 995 LPC_GPDMA->DMACSoftSReq = 0x1;
TickTock 10:aca12a61d2b1 996 do {
TickTock 10:aca12a61d2b1 997 } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running
TickTock 10:aca12a61d2b1 998 dma_off = dma_off + dma_count;
TickTock 10:aca12a61d2b1 999 } while (pixel > 0);
TickTock 10:aca12a61d2b1 1000
TickTock 10:aca12a61d2b1 1001 free ((uint16_t *) buffer);
TickTock 10:aca12a61d2b1 1002
TickTock 10:aca12a61d2b1 1003 if (spi_port == 0) { // TFT on SSP0
TickTock 10:aca12a61d2b1 1004 do {
TickTock 10:aca12a61d2b1 1005 } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI0 not idle
TickTock 10:aca12a61d2b1 1006 /* disable SSP0 for DMA. */
TickTock 10:aca12a61d2b1 1007 LPC_SSP0->DMACR = 0x0;
TickTock 10:aca12a61d2b1 1008 } else {
TickTock 10:aca12a61d2b1 1009 do {
TickTock 10:aca12a61d2b1 1010 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI1 not idle
TickTock 10:aca12a61d2b1 1011 /* disable SSP1 for DMA. */
TickTock 10:aca12a61d2b1 1012 LPC_SSP1->DMACR = 0x0;
TickTock 10:aca12a61d2b1 1013 }
TickTock 10:aca12a61d2b1 1014 #else
TickTock 10:aca12a61d2b1 1015 if (seldisp == 0) {
TickTock 10:aca12a61d2b1 1016 _cs0 = 0;
TickTock 10:aca12a61d2b1 1017 _cs1 = 1;
TickTock 10:aca12a61d2b1 1018 } else if (seldisp == 1) {
TickTock 10:aca12a61d2b1 1019 _cs0 = 1;
TickTock 10:aca12a61d2b1 1020 _cs1 = 0;
TickTock 10:aca12a61d2b1 1021 } else {
TickTock 10:aca12a61d2b1 1022 _cs0 = 0;
TickTock 10:aca12a61d2b1 1023 _cs1 = 0;
TickTock 10:aca12a61d2b1 1024 }
TickTock 10:aca12a61d2b1 1025 if (spi_port == 0) { // TFT on SSP0
TickTock 10:aca12a61d2b1 1026 LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit
TickTock 10:aca12a61d2b1 1027 LPC_SSP0->DR = 0x72; // start Data
TickTock 10:aca12a61d2b1 1028 LPC_SSP0->CR0 |= 0x08UL; // set to 16 bit
TickTock 10:aca12a61d2b1 1029 } else {
TickTock 10:aca12a61d2b1 1030 LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit
TickTock 10:aca12a61d2b1 1031 LPC_SSP1->DR = 0x72; // start Data
TickTock 10:aca12a61d2b1 1032 LPC_SSP1->CR0 |= 0x08UL; // set to 16 bit
TickTock 10:aca12a61d2b1 1033 }
TickTock 10:aca12a61d2b1 1034 zeichen = &font[((c -32) * offset) + 4]; // start of char bitmap
TickTock 10:aca12a61d2b1 1035 w = zeichen[0]; // width of actual char
TickTock 10:aca12a61d2b1 1036 for (j=0; j<vert; j++) { // vert line
TickTock 10:aca12a61d2b1 1037 for (i=0; i<hor; i++) { // horz line
TickTock 10:aca12a61d2b1 1038 z = zeichen[bpl * i + ((j & 0xF8) >> 3)+1];
TickTock 10:aca12a61d2b1 1039 b = 1 << (j & 0x07);
TickTock 10:aca12a61d2b1 1040 if (( z & b ) == 0x00) {
TickTock 10:aca12a61d2b1 1041 _spi.write(_background);
TickTock 10:aca12a61d2b1 1042 } else {
TickTock 10:aca12a61d2b1 1043 _spi.write(_foreground);
TickTock 10:aca12a61d2b1 1044 }
TickTock 10:aca12a61d2b1 1045 }
TickTock 10:aca12a61d2b1 1046 }
TickTock 10:aca12a61d2b1 1047 #endif
TickTock 10:aca12a61d2b1 1048 _cs0 = 1;
TickTock 10:aca12a61d2b1 1049 _cs1 = 1;
TickTock 10:aca12a61d2b1 1050 WindowMax();
TickTock 10:aca12a61d2b1 1051 if ((w + 2) < hor) { // x offset to next char
TickTock 10:aca12a61d2b1 1052 char_x += w + 2;
TickTock 10:aca12a61d2b1 1053 } else char_x += hor;
TickTock 10:aca12a61d2b1 1054
TickTock 10:aca12a61d2b1 1055 }
TickTock 10:aca12a61d2b1 1056
TickTock 10:aca12a61d2b1 1057
TickTock 10:aca12a61d2b1 1058 void SPI_TFTx2::set_font(unsigned char* f)
TickTock 10:aca12a61d2b1 1059 {
TickTock 10:aca12a61d2b1 1060 font = f;
TickTock 10:aca12a61d2b1 1061 }
TickTock 10:aca12a61d2b1 1062
TickTock 10:aca12a61d2b1 1063 void SPI_TFTx2::Bitmap(unsigned int x, unsigned int y, unsigned int w, unsigned int h,unsigned char *bitmap)
TickTock 10:aca12a61d2b1 1064 {
TickTock 10:aca12a61d2b1 1065 unsigned int j;
TickTock 10:aca12a61d2b1 1066 int padd;
TickTock 10:aca12a61d2b1 1067 unsigned short *bitmap_ptr = (unsigned short *)bitmap;
TickTock 10:aca12a61d2b1 1068 // the lines are padded to multiple of 4 bytes in a bitmap
TickTock 10:aca12a61d2b1 1069 padd = -1;
TickTock 10:aca12a61d2b1 1070 do {
TickTock 10:aca12a61d2b1 1071 padd ++;
TickTock 10:aca12a61d2b1 1072 } while (2*(w + padd)%4 != 0);
TickTock 10:aca12a61d2b1 1073 window(x, y, w, h);
TickTock 10:aca12a61d2b1 1074 wr_cmd(0x22);
TickTock 10:aca12a61d2b1 1075 if (seldisp == 0) {
TickTock 10:aca12a61d2b1 1076 _cs0 = 0;
TickTock 10:aca12a61d2b1 1077 _cs1 = 1;
TickTock 10:aca12a61d2b1 1078 } else if (seldisp == 1) {
TickTock 10:aca12a61d2b1 1079 _cs0 = 1;
TickTock 10:aca12a61d2b1 1080 _cs1 = 0;
TickTock 10:aca12a61d2b1 1081 } else {
TickTock 10:aca12a61d2b1 1082 _cs0 = 0;
TickTock 10:aca12a61d2b1 1083 _cs1 = 0;
TickTock 10:aca12a61d2b1 1084 }
TickTock 10:aca12a61d2b1 1085 if (spi_port == 0) { // TFT on SSP0
TickTock 10:aca12a61d2b1 1086 #if defined USE_DMA
TickTock 10:aca12a61d2b1 1087 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR; // we send to SSP0
TickTock 10:aca12a61d2b1 1088 /* Enable SSP0 for DMA. */
TickTock 10:aca12a61d2b1 1089 LPC_SSP0->DMACR = 0x2;
TickTock 10:aca12a61d2b1 1090 #endif
TickTock 10:aca12a61d2b1 1091 LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit
TickTock 10:aca12a61d2b1 1092 LPC_SSP0->DR = 0x72; // start Data
TickTock 10:aca12a61d2b1 1093 LPC_SSP0->CR0 |= 0x08UL; // set to 16 bit
TickTock 10:aca12a61d2b1 1094
TickTock 10:aca12a61d2b1 1095 } else {
TickTock 10:aca12a61d2b1 1096 #if defined USE_DMA
TickTock 10:aca12a61d2b1 1097 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP1->DR; // we send to SSP1
TickTock 10:aca12a61d2b1 1098 /* Enable SSP1 for DMA. */
TickTock 10:aca12a61d2b1 1099 LPC_SSP1->DMACR = 0x2;
TickTock 10:aca12a61d2b1 1100 #endif
TickTock 10:aca12a61d2b1 1101 LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit
TickTock 10:aca12a61d2b1 1102 LPC_SSP1->DR = 0x72; // start Data command
TickTock 10:aca12a61d2b1 1103 LPC_SSP1->CR0 |= 0x08UL; // set to 16 bit
TickTock 10:aca12a61d2b1 1104 }
TickTock 10:aca12a61d2b1 1105
TickTock 10:aca12a61d2b1 1106 bitmap_ptr += ((h - 1)* (w + padd));
TickTock 10:aca12a61d2b1 1107 #if defined USE_DMA
TickTock 10:aca12a61d2b1 1108 for (j = 0; j < h; j++) { //Lines
TickTock 10:aca12a61d2b1 1109 LPC_GPDMA->DMACIntTCClear = 0x1;
TickTock 10:aca12a61d2b1 1110 LPC_GPDMA->DMACIntErrClr = 0x1;
TickTock 10:aca12a61d2b1 1111 LPC_GPDMACH0->DMACCSrcAddr = (uint32_t)bitmap_ptr;
TickTock 10:aca12a61d2b1 1112 LPC_GPDMACH0->DMACCControl = w | (1UL << 18) | (1UL << 21) | (1UL << 31) | DMA_CHANNEL_SRC_INC ; // 16 bit transfer , address increment, interrupt
TickTock 10:aca12a61d2b1 1113 LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | (spi_port ? DMA_DEST_SSP1_TX : DMA_DEST_SSP0_TX);
TickTock 10:aca12a61d2b1 1114 LPC_GPDMA->DMACSoftSReq = 0x1;
TickTock 10:aca12a61d2b1 1115 do {
TickTock 10:aca12a61d2b1 1116 } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running
TickTock 10:aca12a61d2b1 1117
TickTock 10:aca12a61d2b1 1118 bitmap_ptr -= w;
TickTock 10:aca12a61d2b1 1119 bitmap_ptr -= padd;
TickTock 10:aca12a61d2b1 1120 }
TickTock 10:aca12a61d2b1 1121 #else
TickTock 10:aca12a61d2b1 1122 unsigned int i;
TickTock 10:aca12a61d2b1 1123 for (j = 0; j < h; j++) { //Lines
TickTock 10:aca12a61d2b1 1124 for (i = 0; i < w; i++) { // copy pixel data to TFT
TickTock 10:aca12a61d2b1 1125 _spi.write(*bitmap_ptr); // one line
TickTock 10:aca12a61d2b1 1126 bitmap_ptr++;
TickTock 10:aca12a61d2b1 1127 }
TickTock 10:aca12a61d2b1 1128 bitmap_ptr -= 2*w;
TickTock 10:aca12a61d2b1 1129 bitmap_ptr -= padd;
TickTock 10:aca12a61d2b1 1130 }
TickTock 10:aca12a61d2b1 1131 #endif
TickTock 10:aca12a61d2b1 1132 if (spi_port == 0) { // TFT on SSP0
TickTock 10:aca12a61d2b1 1133 do {
TickTock 10:aca12a61d2b1 1134 } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI FIFO not empty
TickTock 10:aca12a61d2b1 1135 } else {
TickTock 10:aca12a61d2b1 1136 do {
TickTock 10:aca12a61d2b1 1137 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI FIFO not empty
TickTock 10:aca12a61d2b1 1138 }
TickTock 10:aca12a61d2b1 1139 _cs0 = 1;
TickTock 10:aca12a61d2b1 1140 _cs1 = 1;
TickTock 10:aca12a61d2b1 1141 WindowMax();
TickTock 10:aca12a61d2b1 1142 }
TickTock 10:aca12a61d2b1 1143
TickTock 10:aca12a61d2b1 1144
TickTock 10:aca12a61d2b1 1145 int SPI_TFTx2::BMP_16(unsigned int x, unsigned int y, const char *Name_BMP)
TickTock 10:aca12a61d2b1 1146 {
TickTock 10:aca12a61d2b1 1147
TickTock 10:aca12a61d2b1 1148 #define OffsetPixelWidth 18
TickTock 10:aca12a61d2b1 1149 #define OffsetPixelHeigh 22
TickTock 10:aca12a61d2b1 1150 #define OffsetFileSize 34
TickTock 10:aca12a61d2b1 1151 #define OffsetPixData 10
TickTock 10:aca12a61d2b1 1152 #define OffsetBPP 28
TickTock 10:aca12a61d2b1 1153
TickTock 10:aca12a61d2b1 1154 char filename[50];
TickTock 10:aca12a61d2b1 1155 unsigned char BMP_Header[54];
TickTock 10:aca12a61d2b1 1156 unsigned short BPP_t;
TickTock 10:aca12a61d2b1 1157 unsigned int PixelWidth,PixelHeigh,start_data;
TickTock 10:aca12a61d2b1 1158 unsigned int i,off;
TickTock 10:aca12a61d2b1 1159 int padd,j;
TickTock 10:aca12a61d2b1 1160 unsigned short *line;
TickTock 10:aca12a61d2b1 1161
TickTock 10:aca12a61d2b1 1162 // get the filename
TickTock 10:aca12a61d2b1 1163 LocalFileSystem local("local");
TickTock 10:aca12a61d2b1 1164 sprintf(&filename[0],"/local/");
TickTock 10:aca12a61d2b1 1165 i=7;
TickTock 10:aca12a61d2b1 1166 while (*Name_BMP!='\0') {
TickTock 10:aca12a61d2b1 1167 filename[i++]=*Name_BMP++;
TickTock 10:aca12a61d2b1 1168 }
TickTock 10:aca12a61d2b1 1169
TickTock 10:aca12a61d2b1 1170 fprintf(stderr, "filename : %s \n\r",filename);
TickTock 10:aca12a61d2b1 1171
TickTock 10:aca12a61d2b1 1172 FILE *Image = fopen((const char *)&filename[0], "rb"); // open the bmp file
TickTock 10:aca12a61d2b1 1173 if (!Image) {
TickTock 10:aca12a61d2b1 1174 return(0); // error file not found !
TickTock 10:aca12a61d2b1 1175 }
TickTock 10:aca12a61d2b1 1176
TickTock 10:aca12a61d2b1 1177 fread(&BMP_Header[0],1,54,Image); // get the BMP Header
TickTock 10:aca12a61d2b1 1178
TickTock 10:aca12a61d2b1 1179 if (BMP_Header[0] != 0x42 || BMP_Header[1] != 0x4D) { // check magic byte
TickTock 10:aca12a61d2b1 1180 fclose(Image);
TickTock 10:aca12a61d2b1 1181 return(-1); // error no BMP file
TickTock 10:aca12a61d2b1 1182 }
TickTock 10:aca12a61d2b1 1183
TickTock 10:aca12a61d2b1 1184 BPP_t = BMP_Header[OffsetBPP] + (BMP_Header[OffsetBPP + 1] << 8);
TickTock 10:aca12a61d2b1 1185 if (BPP_t != 0x0010) {
TickTock 10:aca12a61d2b1 1186 fclose(Image);
TickTock 10:aca12a61d2b1 1187 return(-2); // error no 16 bit BMP
TickTock 10:aca12a61d2b1 1188 }
TickTock 10:aca12a61d2b1 1189
TickTock 10:aca12a61d2b1 1190 PixelHeigh = BMP_Header[OffsetPixelHeigh] + (BMP_Header[OffsetPixelHeigh + 1] << 8) + (BMP_Header[OffsetPixelHeigh + 2] << 16) + (BMP_Header[OffsetPixelHeigh + 3] << 24);
TickTock 10:aca12a61d2b1 1191 PixelWidth = BMP_Header[OffsetPixelWidth] + (BMP_Header[OffsetPixelWidth + 1] << 8) + (BMP_Header[OffsetPixelWidth + 2] << 16) + (BMP_Header[OffsetPixelWidth + 3] << 24);
TickTock 10:aca12a61d2b1 1192 if (PixelHeigh > height() + y || PixelWidth > width() + x) {
TickTock 10:aca12a61d2b1 1193 fclose(Image);
TickTock 10:aca12a61d2b1 1194 return(-3); // to big
TickTock 10:aca12a61d2b1 1195 }
TickTock 10:aca12a61d2b1 1196
TickTock 10:aca12a61d2b1 1197 start_data = BMP_Header[OffsetPixData] + (BMP_Header[OffsetPixData + 1] << 8) + (BMP_Header[OffsetPixData + 2] << 16) + (BMP_Header[OffsetPixData + 3] << 24);
TickTock 10:aca12a61d2b1 1198
TickTock 10:aca12a61d2b1 1199 line = (unsigned short *) malloc (2 * PixelWidth); // we need a buffer for a line
TickTock 10:aca12a61d2b1 1200 if (line == NULL) {
TickTock 10:aca12a61d2b1 1201 return(-4); // error no memory
TickTock 10:aca12a61d2b1 1202 }
TickTock 10:aca12a61d2b1 1203
TickTock 10:aca12a61d2b1 1204 // the bmp lines are padded to multiple of 4 bytes
TickTock 10:aca12a61d2b1 1205 padd = -1;
TickTock 10:aca12a61d2b1 1206 do {
TickTock 10:aca12a61d2b1 1207 padd ++;
TickTock 10:aca12a61d2b1 1208 } while ((PixelWidth * 2 + padd)%4 != 0);
TickTock 10:aca12a61d2b1 1209
TickTock 10:aca12a61d2b1 1210
TickTock 10:aca12a61d2b1 1211 //fseek(Image, 70 ,SEEK_SET);
TickTock 10:aca12a61d2b1 1212 window(x, y,PixelWidth ,PixelHeigh);
TickTock 10:aca12a61d2b1 1213 wr_cmd(0x22);
TickTock 10:aca12a61d2b1 1214 if (seldisp == 0) {
TickTock 10:aca12a61d2b1 1215 _cs0 = 0;
TickTock 10:aca12a61d2b1 1216 _cs1 = 1;
TickTock 10:aca12a61d2b1 1217 } else if (seldisp == 1) {
TickTock 10:aca12a61d2b1 1218 _cs0 = 1;
TickTock 10:aca12a61d2b1 1219 _cs1 = 0;
TickTock 10:aca12a61d2b1 1220 } else {
TickTock 10:aca12a61d2b1 1221 _cs0 = 0;
TickTock 10:aca12a61d2b1 1222 _cs1 = 0;
TickTock 10:aca12a61d2b1 1223 }
TickTock 10:aca12a61d2b1 1224
TickTock 10:aca12a61d2b1 1225 if (spi_port == 0) { // TFT on SSP0
TickTock 10:aca12a61d2b1 1226 #if defined USE_DMA
TickTock 10:aca12a61d2b1 1227 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR; // we send to SSP0
TickTock 10:aca12a61d2b1 1228 /* Enable SSP0 for DMA. */
TickTock 10:aca12a61d2b1 1229 LPC_SSP0->DMACR = 0x2;
TickTock 10:aca12a61d2b1 1230 #endif
TickTock 10:aca12a61d2b1 1231 LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit
TickTock 10:aca12a61d2b1 1232 LPC_SSP0->DR = 0x72; // start Data
TickTock 10:aca12a61d2b1 1233 LPC_SSP0->CR0 |= 0x08UL; // set to 16 bit
TickTock 10:aca12a61d2b1 1234
TickTock 10:aca12a61d2b1 1235 } else {
TickTock 10:aca12a61d2b1 1236 #if defined USE_DMA
TickTock 10:aca12a61d2b1 1237 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP1->DR; // we send to SSP1
TickTock 10:aca12a61d2b1 1238 /* Enable SSP1 for DMA. */
TickTock 10:aca12a61d2b1 1239 LPC_SSP1->DMACR = 0x2;
TickTock 10:aca12a61d2b1 1240 #endif
TickTock 10:aca12a61d2b1 1241 LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit
TickTock 10:aca12a61d2b1 1242 LPC_SSP1->DR = 0x72; // start Data
TickTock 10:aca12a61d2b1 1243 LPC_SSP1->CR0 |= 0x08UL; // set to 16 bit
TickTock 10:aca12a61d2b1 1244 }
TickTock 10:aca12a61d2b1 1245 for (j = PixelHeigh - 1; j >= 0; j--) { //Lines bottom up
TickTock 10:aca12a61d2b1 1246 off = j * (PixelWidth * 2 + padd) + start_data; // start of line
TickTock 10:aca12a61d2b1 1247 fseek(Image, off ,SEEK_SET);
TickTock 10:aca12a61d2b1 1248 fread(line,1,PixelWidth * 2,Image); // read a line - slow !
TickTock 10:aca12a61d2b1 1249 #if defined USE_DMA
TickTock 10:aca12a61d2b1 1250 LPC_GPDMA->DMACIntTCClear = 0x1;
TickTock 10:aca12a61d2b1 1251 LPC_GPDMA->DMACIntErrClr = 0x1;
TickTock 10:aca12a61d2b1 1252 LPC_GPDMACH0->DMACCSrcAddr = (uint32_t)line;
TickTock 10:aca12a61d2b1 1253 LPC_GPDMACH0->DMACCControl = PixelWidth | (1UL << 18) | (1UL << 21) | (1UL << 31) | DMA_CHANNEL_SRC_INC ; // 16 bit transfer , address increment, interrupt
TickTock 10:aca12a61d2b1 1254 LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | (spi_port ? DMA_DEST_SSP1_TX : DMA_DEST_SSP0_TX);
TickTock 10:aca12a61d2b1 1255 LPC_GPDMA->DMACSoftSReq = 0x1;
TickTock 10:aca12a61d2b1 1256 do {
TickTock 10:aca12a61d2b1 1257 } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running
TickTock 10:aca12a61d2b1 1258 #else
TickTock 10:aca12a61d2b1 1259 for (i = 0; i < PixelWidth; i++) { // copy pixel data to TFT
TickTock 10:aca12a61d2b1 1260 _spi.write(line[i]); // one 16 bit pixel
TickTock 10:aca12a61d2b1 1261 }
TickTock 10:aca12a61d2b1 1262 #endif
TickTock 10:aca12a61d2b1 1263 }
TickTock 10:aca12a61d2b1 1264 if (spi_port == 0) { // TFT on SSP0
TickTock 10:aca12a61d2b1 1265 do {
TickTock 10:aca12a61d2b1 1266 } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI FIFO not empty
TickTock 10:aca12a61d2b1 1267 } else {
TickTock 10:aca12a61d2b1 1268 do {
TickTock 10:aca12a61d2b1 1269 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI FIFO not empty
TickTock 10:aca12a61d2b1 1270 }
TickTock 10:aca12a61d2b1 1271 _cs0 = 1;
TickTock 10:aca12a61d2b1 1272 _cs1 = 1;
TickTock 10:aca12a61d2b1 1273 free (line);
TickTock 10:aca12a61d2b1 1274 fclose(Image);
TickTock 10:aca12a61d2b1 1275 WindowMax();
TickTock 10:aca12a61d2b1 1276 return(1);
TickTock 10:aca12a61d2b1 1277 }