Library to control a Graphics TFT connected to 4-wire SPI - revised for the Raio RA8875 Display Controller.

Dependents:   FRDM_RA8875_mPaint RA8875_Demo RA8875_KeyPadDemo SignalGenerator ... more

Fork of SPI_TFT by Peter Drescher

See Components - RA8875 Based Display

Enhanced touch-screen support - where it previous supported both the Resistive Touch and Capacitive Touch based on the FT5206 Touch Controller, now it also has support for the GSL1680 Touch Controller.

Offline Help Manual (Windows chm)

/media/uploads/WiredHome/ra8875.zip.bin (download, rename to .zip and unzip)

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 }