Library to control a QVGA TFT connected to SPI. You can use printf to print text The lib can handle different fonts, draw lines, circles, rect and bmp

Dependents:   TFT_Test1 SourceCodePro31-SB Mandelbrot Mindwave-screen ... more

See http://mbed.org/cookbook/SPI-driven-QVGA-TFT for details.

Committer:
dreschpe
Date:
Fri Oct 12 10:03:42 2012 +0000
Revision:
7:e753bb62eeb9
Parent:
6:34a13617fd35
Child:
8:65a4de035c3c
Fix SPI1 connection.; Thanks to Hans Bergles

Who changed what in which revision?

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