Modified to work with two displays
Dependents: touch2 default CANary_9341_test CANary_merge
Fork of SPI_TFT by
SPI_TFTx2.cpp
00001 /* mbed library for 240*320 pixel display TFT based on HX8347D LCD Controller 00002 * Copyright (c) 2011 Peter Drescher - DC2PD 00003 * 00004 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00005 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00006 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00007 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00008 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00009 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00010 * THE SOFTWARE. 00011 */ 00012 00013 00014 // fix bmp padding for Bitmap function 00015 // speed up pixel 00016 // 30.12.11 fix cls 00017 // 11.03.12 use DMA to speed up 00018 // 15.03.12 use SSEL for TFT CS to enable DMA Register writes 00019 // 06.04.12 fix SSEL CS problem 00020 // 06.04.12 use direct access to the spi register to speed up the library. 00021 // 11.09.12 switch back to using io pin as cs to avoid problems with SSEL CS. 00022 // 21.09.12 fix Bug in BMP_16 00023 // 11.10.12 patch from Hans Bergles to get SPI1 working again 00024 // 03.02.13 add a switch to switch off DMA use for LPC11U24 00025 00026 #include "SPI_TFTx2.h" 00027 #include "mbed.h" 00028 00029 #define BPP 16 // Bits per pixel 00030 00031 #if defined TARGET_LPC1768 00032 #define USE_DMA 00033 #endif 00034 00035 #if defined NO_DMA 00036 #undef USE_DMA 00037 #endif 00038 00039 //extern Serial pc; 00040 //extern DigitalOut xx; // debug !! 00041 00042 SPI_TFTx2::SPI_TFTx2(PinName mosi, PinName miso, PinName sclk, PinName cs0, PinName cs1, PinName reset, const char *name) 00043 : _spi(mosi, miso, sclk), _cs0(cs0), _cs1(cs1), _reset(reset), GraphicsDisplay(name) 00044 { 00045 orientation = 0; 00046 char_x = 0; 00047 _cs0 = 1; 00048 _cs1 = 1; 00049 00050 if (mosi == p11 || mosi == P0_18) spi_port = 0; // we must know the used SPI port to setup the DMA 00051 else spi_port = 1; 00052 seldisp = 2; 00053 tft_reset(); 00054 } 00055 00056 int SPI_TFTx2::width() 00057 { 00058 if (orientation == 0 || orientation == 2) return 240; 00059 else return 320; 00060 } 00061 00062 00063 int SPI_TFTx2::height() 00064 { 00065 if (orientation == 0 || orientation == 2) return 320; 00066 else return 240; 00067 } 00068 00069 00070 void SPI_TFTx2::set_orientation(unsigned int o) 00071 { 00072 orientation = o; 00073 switch (orientation) { 00074 case 0: 00075 wr_reg(0x16, 0x08); 00076 break; 00077 case 1: 00078 wr_reg(0x16, 0x68); 00079 break; 00080 case 2: 00081 wr_reg(0x16, 0xC8); 00082 break; 00083 case 3: 00084 wr_reg(0x16, 0xA8); 00085 break; 00086 } 00087 WindowMax(); 00088 } 00089 00090 void SPI_TFTx2::set_display(unsigned int o) 00091 { 00092 seldisp = o; 00093 } 00094 00095 // write command to tft register 00096 00097 void SPI_TFTx2::wr_cmd(unsigned char cmd) 00098 { 00099 unsigned short spi_d; 00100 spi_d = 0x7000 | cmd ; 00101 00102 if (seldisp == 0) { 00103 _cs0 = 0; 00104 _cs1 = 1; 00105 } else if (seldisp == 1) { 00106 _cs0 = 1; 00107 _cs1 = 0; 00108 } else { 00109 _cs0 = 0; 00110 _cs1 = 0; 00111 } 00112 00113 if (spi_port == 0) { // TFT on SSP0 00114 LPC_SSP0->DR = spi_d; 00115 // we have to wait for SPI IDLE to set CS back to high 00116 do { 00117 } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI0 not idle 00118 } else { 00119 LPC_SSP1->DR = spi_d; 00120 do { 00121 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI1 not idle 00122 } 00123 _cs0 = 1; 00124 _cs1 = 1; 00125 } 00126 00127 00128 00129 void SPI_TFTx2::wr_dat(unsigned char dat) 00130 { 00131 unsigned short spi_d; 00132 spi_d = 0x7200 | dat; 00133 if (seldisp == 0) { 00134 _cs0 = 0; 00135 _cs1 = 1; 00136 } else if (seldisp == 1) { 00137 _cs0 = 1; 00138 _cs1 = 0; 00139 } else { 00140 _cs0 = 0; 00141 _cs1 = 0; 00142 } 00143 00144 if (spi_port == 0) { // TFT on SSP0 00145 LPC_SSP0->DR = spi_d; 00146 // we have to wait for SPI IDLE to set CS back to high 00147 do { 00148 } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI0 not idle 00149 } else { 00150 LPC_SSP1->DR = spi_d; 00151 do { 00152 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI1 not idle 00153 } 00154 _cs0 = 1; 00155 _cs1 = 1; 00156 } 00157 00158 00159 00160 // the HX8347-D controller do not use the MISO (SDO) Signal. 00161 // This is a bug - ? 00162 // A read will return 0 at the moment 00163 00164 unsigned short SPI_TFTx2::rd_dat (void) 00165 { 00166 unsigned short val = 0; 00167 00168 //val = _spi.write(0x73ff); /* Dummy read 1 */ 00169 //val = _spi.write(0x0000); /* Read D8..D15 */ 00170 return (val); 00171 } 00172 00173 void SPI_TFTx2::wr_reg (unsigned char reg, unsigned char val) 00174 { 00175 wr_cmd(reg); 00176 wr_dat(val); 00177 } 00178 00179 unsigned short SPI_TFTx2::rd_reg (unsigned char reg) 00180 { 00181 wr_cmd(reg); 00182 return(rd_dat()); 00183 } 00184 00185 void SPI_TFTx2::tft_reset() 00186 { 00187 //static unsigned short driverCode; 00188 _spi.format(16,3); // 16 bit spi mode 3 00189 _spi.frequency(48000000); // 48 Mhz SPI clock 00190 _cs0 = 1; // cs high 00191 _cs1 = 1; // cs high 00192 _reset = 0; // display reset 00193 00194 wait_us(50); 00195 _reset = 1; // end reset 00196 wait_ms(5); 00197 00198 /* Start Initial Sequence ----------------------------------------------------*/ 00199 wr_reg(0xEA, 0x00); /* Reset Power Control 1 */ 00200 wr_reg(0xEB, 0x20); /* Power Control 2 */ 00201 wr_reg(0xEC, 0x0C); /* Power Control 3 */ 00202 wr_reg(0xED, 0xC4); /* Power Control 4 */ 00203 wr_reg(0xE8, 0x40); /* Source OPON_N */ 00204 wr_reg(0xE9, 0x38); /* Source OPON_I */ 00205 wr_reg(0xF1, 0x01); /* */ 00206 wr_reg(0xF2, 0x10); /* */ 00207 wr_reg(0x27, 0xA3); /* Display Control 2 */ 00208 00209 /* Power On sequence ---------------------------------------------------------*/ 00210 wr_reg(0x1B, 0x1B); /* Power Control 2 */ 00211 wr_reg(0x1A, 0x01); /* Power Control 1 */ 00212 wr_reg(0x24, 0x2F); /* Vcom Control 2 */ 00213 wr_reg(0x25, 0x57); /* Vcom Control 3 */ 00214 wr_reg(0x23, 0x8D); /* Vcom Control 1 */ 00215 00216 /* Gamma settings -----------------------------------------------------------*/ 00217 wr_reg(0x40,0x00); // 00218 wr_reg(0x41,0x00); // 00219 wr_reg(0x42,0x01); // 00220 wr_reg(0x43,0x13); // 00221 wr_reg(0x44,0x10); // 00222 wr_reg(0x45,0x26); // 00223 wr_reg(0x46,0x08); // 00224 wr_reg(0x47,0x51); // 00225 wr_reg(0x48,0x02); // 00226 wr_reg(0x49,0x12); // 00227 wr_reg(0x4A,0x18); // 00228 wr_reg(0x4B,0x19); // 00229 wr_reg(0x4C,0x14); // 00230 wr_reg(0x50,0x19); // 00231 wr_reg(0x51,0x2F); // 00232 wr_reg(0x52,0x2C); // 00233 wr_reg(0x53,0x3E); // 00234 wr_reg(0x54,0x3F); // 00235 wr_reg(0x55,0x3F); // 00236 wr_reg(0x56,0x2E); // 00237 wr_reg(0x57,0x77); // 00238 wr_reg(0x58,0x0B); // 00239 wr_reg(0x59,0x06); // 00240 wr_reg(0x5A,0x07); // 00241 wr_reg(0x5B,0x0D); // 00242 wr_reg(0x5C,0x1D); // 00243 wr_reg(0x5D,0xCC); // 00244 00245 /* Power + Osc ---------------------------------------------------------------*/ 00246 wr_reg(0x18, 0x0036); /* OSC Control 1 */ 00247 wr_reg(0x19, 0x0001); /* OSC Control 2 */ 00248 wr_reg(0x01, 0x0000); /* Display Mode Control */ 00249 wr_reg(0x1F, 0x0088); /* Power Control 6 */ 00250 wait_ms(5); /* Delay 5 ms */ 00251 wr_reg(0x1F, 0x0080); /* Power Control 6 */ 00252 wait_ms(5); /* Delay 5 ms */ 00253 wr_reg(0x1F, 0x0090); /* Power Control 6 */ 00254 wait_ms(5); /* Delay 5 ms */ 00255 wr_reg(0x1F, 0x00D0); /* Power Control 6 */ 00256 wait_ms(5); /* Delay 5 ms */ 00257 00258 wr_reg(0x17, 0x0005); /* Colmod 16Bit/Pixel */ 00259 00260 wr_reg(0x36, 0x0000); /* Panel Characteristic */ 00261 wr_reg(0x28, 0x0038); /* Display Control 3 */ 00262 wait_ms(40); 00263 wr_reg(0x28, 0x003C); /* Display Control 3 */ 00264 switch (orientation) { 00265 case 0: 00266 wr_reg(0x16, 0x0008); 00267 break; 00268 case 1: 00269 wr_reg(0x16, 0x0068); 00270 break; 00271 case 2: 00272 wr_reg(0x16, 0x00C8); 00273 break; 00274 case 3: 00275 wr_reg(0x16, 0x00A8); 00276 break; 00277 } 00278 #if defined USE_DMA 00279 // setup DMA channel 0 00280 // Power up the GPDMA. 00281 LPC_SC->PCONP |= (1UL << 29); 00282 LPC_GPDMA->DMACConfig = 1; // enable DMA controller 00283 // Reset the Interrupt status 00284 LPC_GPDMA->DMACIntTCClear = 0x1; 00285 LPC_GPDMA->DMACIntErrClr = 0x1; 00286 LPC_GPDMACH0->DMACCLLI = 0; 00287 #endif 00288 00289 WindowMax (); 00290 } 00291 00292 00293 void SPI_TFTx2::pixel(int x, int y, int color) 00294 { 00295 unsigned char u,l; 00296 wr_reg(0x03, (x >> 0)); 00297 wr_reg(0x02, (x >> 8)); 00298 wr_reg(0x07, (y >> 0)); 00299 wr_reg(0x06, (y >> 8)); 00300 wr_cmd(0x22); 00301 u = color >> 8; 00302 l = color & 0xff; 00303 if (seldisp == 0) { 00304 _cs0 = 0; 00305 _cs1 = 1; 00306 } else if (seldisp == 1) { 00307 _cs0 = 1; 00308 _cs1 = 0; 00309 } else { 00310 _cs0 = 0; 00311 _cs1 = 0; 00312 } 00313 if (spi_port == 0) { // TFT on SSP0 00314 LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit 00315 LPC_SSP0->DR = 0x72; // start Data 00316 LPC_SSP0->DR = u; // high byte 00317 LPC_SSP0->DR = l; // low byte 00318 LPC_SSP0->CR0 |= 0x08UL; // set back to 16 bit 00319 // we have to wait for SPI IDLE to set CS back to high 00320 do { 00321 } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI0 not idle 00322 } else { 00323 LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit 00324 LPC_SSP1->DR = 0x72; // start Data 00325 LPC_SSP1->DR = u; 00326 LPC_SSP1->DR = l; 00327 LPC_SSP1->CR0 |= 0x08UL; // set back to 16 bit 00328 // we have to wait for SPI IDLE to set CS back to high 00329 do { 00330 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI1 not idle 00331 } 00332 _cs0 = 1; 00333 _cs1 = 1; 00334 } 00335 00336 00337 void SPI_TFTx2::window (unsigned int x, unsigned int y, unsigned int w, unsigned int h) 00338 { 00339 wr_reg(0x03, x ); 00340 wr_reg(0x02, (x >> 8)); 00341 wr_reg(0x05, x+w-1 ); 00342 wr_reg(0x04, (x+w-1 >> 8)); 00343 wr_reg(0x07, y ); 00344 wr_reg(0x06, ( y >> 8)); 00345 wr_reg(0x09, ( y+h-1 )); 00346 wr_reg(0x08, ( y+h-1 >> 8)); 00347 } 00348 00349 00350 void SPI_TFTx2::WindowMax (void) 00351 { 00352 window (0, 0, width(), height()); 00353 } 00354 00355 00356 void SPI_TFTx2::cls (void) 00357 { 00358 int pixel = ( width() * height()); 00359 #if defined USE_DMA 00360 int dma_count; 00361 int color = _background; 00362 #endif 00363 WindowMax(); 00364 wr_cmd(0x22); 00365 00366 // The SSEL signal is held low until the spi FIFO is emty. 00367 // We have to lower the SPI clock for the 8 bit start to get the spi running 00368 // until the next data word 00369 #if defined USE_DMA 00370 LPC_GPDMACH0->DMACCSrcAddr = (uint32_t)&color; 00371 #endif 00372 if (seldisp == 0) { 00373 _cs0 = 0; 00374 _cs1 = 1; 00375 } else if (seldisp == 1) { 00376 _cs0 = 1; 00377 _cs1 = 0; 00378 } else { 00379 _cs0 = 0; 00380 _cs1 = 0; 00381 } 00382 if (spi_port == 0) { // TFT on SSP0 00383 #if defined USE_DMA 00384 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR; // we send to SSP0 00385 /* Enable SSP0 for DMA. */ 00386 LPC_SSP0->DMACR = 0x2; 00387 #endif 00388 LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit 00389 LPC_SSP0->DR = 0x72; // start byte 00390 LPC_SSP0->CR0 |= 0x08UL; // set to 16 bit 00391 } else { 00392 #if defined USE_DMA 00393 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP1->DR; // we send to SSP1 00394 /* Enable SSP1 for DMA. */ 00395 LPC_SSP1->DMACR = 0x2; 00396 #endif 00397 LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit 00398 LPC_SSP1->DR = 0x72; // start Data 00399 LPC_SSP1->CR0 |= 0x08UL; // set to 16 bit 00400 } 00401 00402 #if defined USE_DMA 00403 // start DMA 00404 do { 00405 if (pixel > 4095) { 00406 dma_count = 4095; 00407 pixel = pixel - 4095; 00408 } else { 00409 dma_count = pixel; 00410 pixel = 0; 00411 } 00412 LPC_GPDMA->DMACIntTCClear = 0x1; 00413 LPC_GPDMA->DMACIntErrClr = 0x1; 00414 LPC_GPDMACH0->DMACCControl = dma_count | (1UL << 18) | (1UL << 21) | (1UL << 31) ; // 16 bit transfer , no address increment, interrupt 00415 LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | (spi_port ? DMA_DEST_SSP1_TX : DMA_DEST_SSP0_TX); 00416 LPC_GPDMA->DMACSoftSReq = 0x1; // DMA request 00417 00418 do { 00419 } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running 00420 00421 } while (pixel > 0); 00422 if (spi_port == 0) { // TFT on SSP0 00423 do { 00424 } while ((0x0010 & LPC_SSP0->SR) == 0x10); // SPI FIFO not empty 00425 /* disable SSP0 for DMA. */ 00426 LPC_SSP0->DMACR = 0x0; 00427 } else { 00428 do { 00429 } while ((0x0010 & LPC_SSP1->SR) == 0x10); // SPI FIFO not empty 00430 /* disable SSP1 for DMA. */ 00431 LPC_SSP1->DMACR = 0x0; 00432 } 00433 #else // no DMA 00434 unsigned int i; 00435 for (i = 0; i < ( width() * height()); i++) 00436 _spi.write(_background); 00437 #endif 00438 _cs0 = 1; 00439 _cs1 = 1; 00440 } 00441 00442 void SPI_TFTx2::circle(int x0, int y0, int r, int color) 00443 { 00444 00445 int draw_x0, draw_y0; 00446 int draw_x1, draw_y1; 00447 int draw_x2, draw_y2; 00448 int draw_x3, draw_y3; 00449 int draw_x4, draw_y4; 00450 int draw_x5, draw_y5; 00451 int draw_x6, draw_y6; 00452 int draw_x7, draw_y7; 00453 int xx, yy; 00454 int di; 00455 //WindowMax(); 00456 if (r == 0) { /* no radius */ 00457 return; 00458 } 00459 00460 draw_x0 = draw_x1 = x0; 00461 draw_y0 = draw_y1 = y0 + r; 00462 if (draw_y0 < height()) { 00463 pixel(draw_x0, draw_y0, color); /* 90 degree */ 00464 } 00465 00466 draw_x2 = draw_x3 = x0; 00467 draw_y2 = draw_y3 = y0 - r; 00468 if (draw_y2 >= 0) { 00469 pixel(draw_x2, draw_y2, color); /* 270 degree */ 00470 } 00471 00472 draw_x4 = draw_x6 = x0 + r; 00473 draw_y4 = draw_y6 = y0; 00474 if (draw_x4 < width()) { 00475 pixel(draw_x4, draw_y4, color); /* 0 degree */ 00476 } 00477 00478 draw_x5 = draw_x7 = x0 - r; 00479 draw_y5 = draw_y7 = y0; 00480 if (draw_x5>=0) { 00481 pixel(draw_x5, draw_y5, color); /* 180 degree */ 00482 } 00483 00484 if (r == 1) { 00485 return; 00486 } 00487 00488 di = 3 - 2*r; 00489 xx = 0; 00490 yy = r; 00491 while (xx < yy) { 00492 00493 if (di < 0) { 00494 di += 4*xx + 6; 00495 } else { 00496 di += 4*(xx - yy) + 10; 00497 yy--; 00498 draw_y0--; 00499 draw_y1--; 00500 draw_y2++; 00501 draw_y3++; 00502 draw_x4--; 00503 draw_x5++; 00504 draw_x6--; 00505 draw_x7++; 00506 } 00507 xx++; 00508 draw_x0++; 00509 draw_x1--; 00510 draw_x2++; 00511 draw_x3--; 00512 draw_y4++; 00513 draw_y5++; 00514 draw_y6--; 00515 draw_y7--; 00516 00517 if ( (draw_x0 <= width()) && (draw_y0>=0) ) { 00518 pixel(draw_x0, draw_y0, color); 00519 } 00520 00521 if ( (draw_x1 >= 0) && (draw_y1 >= 0) ) { 00522 pixel(draw_x1, draw_y1, color); 00523 } 00524 00525 if ( (draw_x2 <= width()) && (draw_y2 <= height()) ) { 00526 pixel(draw_x2, draw_y2, color); 00527 } 00528 00529 if ( (draw_x3 >=0 ) && (draw_y3 <= height()) ) { 00530 pixel(draw_x3, draw_y3, color); 00531 } 00532 00533 if ( (draw_x4 <= width()) && (draw_y4 >= 0) ) { 00534 pixel(draw_x4, draw_y4, color); 00535 } 00536 00537 if ( (draw_x5 >= 0) && (draw_y5 >= 0) ) { 00538 pixel(draw_x5, draw_y5, color); 00539 } 00540 if ( (draw_x6 <=width()) && (draw_y6 <= height()) ) { 00541 pixel(draw_x6, draw_y6, color); 00542 } 00543 if ( (draw_x7 >= 0) && (draw_y7 <= height()) ) { 00544 pixel(draw_x7, draw_y7, color); 00545 } 00546 } 00547 return; 00548 } 00549 00550 void SPI_TFTx2::fillcircle(int x, int y, int r, int color) 00551 { 00552 int i; 00553 for (i = 0; i <= r; i++) 00554 circle(x,y,i,color); 00555 } 00556 00557 00558 00559 void SPI_TFTx2::hline(int x0, int x1, int y, int color) 00560 { 00561 int w,i; 00562 w = x1 - x0 + 1; 00563 window(x0,y,w,1); 00564 wr_cmd(0x22); 00565 if (seldisp == 0) { 00566 _cs0 = 0; 00567 _cs1 = 1; 00568 } else if (seldisp == 1) { 00569 _cs0 = 1; 00570 _cs1 = 0; 00571 } else { 00572 _cs0 = 0; 00573 _cs1 = 0; 00574 } 00575 if (spi_port == 0) { // TFT on SSP0 00576 for (i = 0; i < ( width() * height()); i++) 00577 #if defined USE_DMA 00578 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR; // we send to SSP0 00579 /* Enable SSP0 for DMA. */ 00580 LPC_SSP0->DMACR = 0x2; 00581 #endif 00582 LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit 00583 LPC_SSP0->DR = 0x72; // start Data 00584 LPC_SSP0->CR0 |= 0x08UL; // set to 16 bit 00585 } else { 00586 #if defined USE_DMA 00587 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP1->DR; // we send to SSP1 00588 /* Enable SSP1 for DMA. */ 00589 LPC_SSP1->DMACR = 0x2; 00590 #endif 00591 LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit 00592 LPC_SSP1->DR = 0x72; // start Data 00593 LPC_SSP1->CR0 |= 0x08UL; // set to 16 bit 00594 } 00595 #if defined USE_DMA 00596 LPC_GPDMA->DMACIntTCClear = 0x1; 00597 LPC_GPDMA->DMACIntErrClr = 0x1; 00598 LPC_GPDMACH0->DMACCSrcAddr = (uint32_t)&color; 00599 LPC_GPDMACH0->DMACCControl = w | (1UL << 18) | (1UL << 21) | (1UL << 31) ; // 16 bit transfer , no address increment, interrupt 00600 LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | (spi_port ? DMA_DEST_SSP1_TX : DMA_DEST_SSP0_TX); 00601 LPC_GPDMA->DMACSoftSReq = 0x1; // start DMA 00602 do { 00603 } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running 00604 if (spi_port == 0) { // TFT on SSP0 00605 do { 00606 } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI FIFO not empty 00607 } else { 00608 do { 00609 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI FIFO not empty 00610 } 00611 #else 00612 for (i=0; i<w; i++) { 00613 _spi.write(color); 00614 } 00615 00616 #endif 00617 _cs0 = 1; 00618 _cs1 = 1; 00619 WindowMax(); 00620 return; 00621 } 00622 00623 void SPI_TFTx2::vline(int x, int y0, int y1, int color) 00624 { 00625 int h; 00626 h = y1 - y0 + 1; 00627 window(x,y0,1,h); 00628 wr_cmd(0x22); 00629 if (seldisp == 0) { 00630 _cs0 = 0; 00631 _cs1 = 1; 00632 } else if (seldisp == 1) { 00633 _cs0 = 1; 00634 _cs1 = 0; 00635 } else { 00636 _cs0 = 0; 00637 _cs1 = 0; 00638 } 00639 if (spi_port == 0) { // TFT on SSP0 00640 #if defined USE_DMA 00641 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR; // we send to SSP0 00642 /* Enable SSP0 for DMA. */ 00643 LPC_SSP0->DMACR = 0x2; 00644 #endif 00645 LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit 00646 LPC_SSP0->DR = 0x72; // start Data 00647 LPC_SSP0->CR0 |= 0x08UL; // set to 16 bit 00648 } else { 00649 #if defined USE_DMA 00650 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP1->DR; // we send to SSP1 00651 /* Enable SSP1 for DMA. */ 00652 LPC_SSP1->DMACR = 0x2; 00653 #endif 00654 LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit 00655 LPC_SSP1->DR = 0x72; // start Data 00656 LPC_SSP1->CR0 |= 0x08UL; // set to 16 bit 00657 } 00658 #if defined USE_DMA 00659 LPC_GPDMA->DMACIntTCClear = 0x1; 00660 LPC_GPDMA->DMACIntErrClr = 0x1; 00661 LPC_GPDMACH0->DMACCSrcAddr = (uint32_t)&color; 00662 LPC_GPDMACH0->DMACCControl = h | (1UL << 18) | (1UL << 21) | (1UL << 31) ; // 16 bit transfer , no address increment, interrupt 00663 LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | (spi_port ? DMA_DEST_SSP1_TX : DMA_DEST_SSP0_TX); 00664 LPC_GPDMA->DMACSoftSReq = 0x1; 00665 do { 00666 } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running 00667 00668 if (spi_port == 0) { // TFT on SSP0 00669 do { 00670 } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI FIFO not empty 00671 } else { 00672 do { 00673 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI FIFO not empty 00674 } 00675 #else 00676 for (int y=0; y<h; y++) { 00677 _spi.write(color); 00678 } 00679 #endif 00680 _cs0 = 1; 00681 _cs1 = 1; 00682 WindowMax(); 00683 return; 00684 } 00685 00686 void SPI_TFTx2::line(int x0, int y0, int x1, int y1, int color) 00687 { 00688 //WindowMax(); 00689 int dx = 0, dy = 0; 00690 int dx_sym = 0, dy_sym = 0; 00691 int dx_x2 = 0, dy_x2 = 0; 00692 int di = 0; 00693 00694 dx = x1-x0; 00695 dy = y1-y0; 00696 00697 // vline and hline are very slow for some reason so not using 00698 //if (dx == 0) { /* vertical line */ 00699 // if (y1 > y0) vline(x0,y0,y1,color); 00700 // else vline(x0,y1,y0,color); 00701 // return; 00702 //} 00703 00704 if (dx > 0) { 00705 dx_sym = 1; 00706 } else { 00707 dx_sym = -1; 00708 } 00709 //if (dy == 0) { /* horizontal line */ 00710 // if (x1 > x0) hline(x0,x1,y0,color); 00711 // else hline(x1,x0,y0,color); 00712 // return; 00713 //} 00714 00715 if (dy > 0) { 00716 dy_sym = 1; 00717 } else { 00718 dy_sym = -1; 00719 } 00720 00721 dx = dx_sym*dx; 00722 dy = dy_sym*dy; 00723 00724 dx_x2 = dx*2; 00725 dy_x2 = dy*2; 00726 00727 if (dx >= dy) { 00728 di = dy_x2 - dx; 00729 while (x0 != x1) { 00730 00731 pixel(x0, y0, color); 00732 x0 += dx_sym; 00733 if (di<0) { 00734 di += dy_x2; 00735 } else { 00736 di += dy_x2 - dx_x2; 00737 y0 += dy_sym; 00738 } 00739 } 00740 pixel(x0, y0, color); 00741 } else { 00742 di = dx_x2 - dy; 00743 while (y0 != y1) { 00744 pixel(x0, y0, color); 00745 y0 += dy_sym; 00746 if (di < 0) { 00747 di += dx_x2; 00748 } else { 00749 di += dx_x2 - dy_x2; 00750 x0 += dx_sym; 00751 } 00752 } 00753 pixel(x0, y0, color); 00754 } 00755 return; 00756 } 00757 00758 00759 void SPI_TFTx2::rect(int x0, int y0, int x1, int y1, int color) 00760 { 00761 00762 if (x1 > x0) hline(x0,x1,y0,color); 00763 else hline(x1,x0,y0,color); 00764 00765 if (y1 > y0) vline(x0,y0,y1,color); 00766 else vline(x0,y1,y0,color); 00767 00768 if (x1 > x0) hline(x0,x1,y1,color); 00769 else hline(x1,x0,y1,color); 00770 00771 if (y1 > y0) vline(x1,y0,y1,color); 00772 else vline(x1,y1,y0,color); 00773 00774 return; 00775 } 00776 00777 00778 00779 void SPI_TFTx2::fillrect(int x0, int y0, int x1, int y1, int color) 00780 { 00781 00782 int h = y1 - y0 + 1; 00783 int w = x1 - x0 + 1; 00784 int pixel = h * w; 00785 int dma_count; 00786 window(x0,y0,w,h); 00787 wr_cmd(0x22); 00788 if (seldisp == 0) { 00789 _cs0 = 0; 00790 _cs1 = 1; 00791 } else if (seldisp == 1) { 00792 _cs0 = 1; 00793 _cs1 = 0; 00794 } else { 00795 _cs0 = 0; 00796 _cs1 = 0; 00797 } 00798 if (spi_port == 0) { // TFT on SSP0 00799 #if defined USE_DMA 00800 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR; // we send to SSP0 00801 /* Enable SSP0 for DMA. */ 00802 LPC_SSP0->DMACR = 0x2; 00803 #endif 00804 LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit 00805 LPC_SSP0->DR = 0x72; // start Data 00806 LPC_SSP0->CR0 |= 0x08UL; // set to 16 bit 00807 } else { 00808 #if defined USE_DMA 00809 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP1->DR; // we send to SSP1 00810 /* Enable SSP1 for DMA. */ 00811 LPC_SSP1->DMACR = 0x2; 00812 #endif 00813 LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit 00814 LPC_SSP1->DR = 0x72; // start Data 00815 LPC_SSP1->CR0 |= 0x08UL; // set to 16 bit 00816 } 00817 #if defined USE_DMA 00818 do { 00819 if (pixel > 4095) { 00820 dma_count = 4095; 00821 pixel = pixel - 4095; 00822 } else { 00823 dma_count = pixel; 00824 pixel = 0; 00825 } 00826 LPC_GPDMA->DMACIntTCClear = 0x1; 00827 LPC_GPDMA->DMACIntErrClr = 0x1; 00828 LPC_GPDMACH0->DMACCSrcAddr = (uint32_t)&color; 00829 LPC_GPDMACH0->DMACCControl = dma_count | (1UL << 18) | (1UL << 21) | (1UL << 31) ; // 16 bit transfer , no address increment, interrupt 00830 LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | (spi_port ? DMA_DEST_SSP1_TX : DMA_DEST_SSP0_TX); 00831 LPC_GPDMA->DMACSoftSReq = 0x1; 00832 do { 00833 } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running 00834 00835 } while (pixel > 0); 00836 00837 if (spi_port == 0) { // TFT on SSP0 00838 do { 00839 } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI FIFO not empty 00840 } else { 00841 do { 00842 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI FIFO not empty 00843 } 00844 00845 #else // no DMA 00846 for (int p=0; p<pixel; p++) { 00847 _spi.write(color); 00848 } 00849 #endif 00850 00851 _cs0 = 1; 00852 _cs1 = 1; 00853 WindowMax(); 00854 return; 00855 } 00856 00857 00858 void SPI_TFTx2::locate(int x, int y) 00859 { 00860 char_x = x; 00861 char_y = y; 00862 } 00863 00864 00865 00866 int SPI_TFTx2::columns() 00867 { 00868 return width() / font[1]; 00869 } 00870 00871 00872 00873 int SPI_TFTx2::rows() 00874 { 00875 return height() / font[2]; 00876 } 00877 00878 00879 00880 int SPI_TFTx2::_putc(int value) 00881 { 00882 if (value == '\n') { // new line 00883 char_x = 0; 00884 char_y = char_y + font[2]; 00885 if (char_y >= height() - font[2]) { 00886 char_y = 0; 00887 } 00888 } else { 00889 character(char_x, char_y, value); 00890 } 00891 return value; 00892 } 00893 00894 00895 00896 00897 void SPI_TFTx2::character(int x, int y, int c) 00898 { 00899 unsigned int hor,vert,offset,bpl,j,i,b,p; 00900 unsigned char* zeichen; 00901 unsigned char z,w; 00902 #if defined USE_DMA 00903 unsigned int pixel; 00904 unsigned int dma_count,dma_off; 00905 uint16_t *buffer; 00906 #endif 00907 00908 if ((c < 31) || (c > 127)) return; // test char range 00909 00910 // read font parameter from start of array 00911 offset = font[0]; // bytes / char 00912 hor = font[1]; // get hor size of font 00913 vert = font[2]; // get vert size of font 00914 bpl = font[3]; // bytes per line 00915 00916 if (char_x + hor > width()) { 00917 char_x = 0; 00918 char_y = char_y + vert; 00919 if (char_y >= height() - font[2]) { 00920 char_y = 0; 00921 } 00922 } 00923 window(char_x, char_y,hor,vert); // char box 00924 wr_cmd(0x22); 00925 00926 #if defined USE_DMA 00927 pixel = hor * vert; // calculate buffer size 00928 00929 buffer = (uint16_t *) malloc (2*pixel); // we need a buffer for the 16 bit 00930 if (buffer == NULL) { 00931 //led = 1; 00932 //pc.printf("Malloc error !\n\r"); 00933 return; // error no memory 00934 } 00935 00936 zeichen = &font[((c -32) * offset) + 4]; // start of char bitmap 00937 w = zeichen[0]; // width of actual char 00938 p = 0; 00939 // construct the char into the buffer 00940 for (j=0; j<vert; j++) { // vert line 00941 for (i=0; i<hor; i++) { // horz line 00942 z = zeichen[bpl * i + ((j & 0xF8) >> 3)+1]; 00943 b = 1 << (j & 0x07); 00944 if (( z & b ) == 0x00) { 00945 buffer[p] = _background; 00946 } else { 00947 buffer[p] = _foreground; 00948 } 00949 p++; 00950 } 00951 } 00952 00953 // copy the buffer with DMA SPI to display 00954 dma_off = 0; // offset for DMA transfer 00955 if (seldisp == 0) { 00956 _cs0 = 0; 00957 _cs1 = 1; 00958 } else if (seldisp == 1) { 00959 _cs0 = 1; 00960 _cs1 = 0; 00961 } else { 00962 _cs0 = 0; 00963 _cs1 = 0; 00964 } 00965 if (spi_port == 0) { // TFT on SSP0 00966 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR; // we send to SSP0 00967 /* Enable SSP0 for DMA. */ 00968 LPC_SSP0->DMACR = 0x2; 00969 LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit 00970 LPC_SSP0->DR = 0x72; // start Data 00971 LPC_SSP0->CR0 |= 0x08UL; // set to 16 bit 00972 } else { 00973 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP1->DR; // we send to SSP1 00974 /* Enable SSP1 for DMA. */ 00975 LPC_SSP1->DMACR = 0x2; 00976 LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit 00977 LPC_SSP1->DR = 0x72; // start Data 00978 LPC_SSP1->CR0 |= 0x08UL; // set to 16 bit 00979 } 00980 00981 // start DMA 00982 do { 00983 if (pixel > 4095) { // this is a giant font ! 00984 dma_count = 4095; 00985 pixel = pixel - 4095; 00986 } else { 00987 dma_count = pixel; 00988 pixel = 0; 00989 } 00990 LPC_GPDMA->DMACIntTCClear = 0x1; 00991 LPC_GPDMA->DMACIntErrClr = 0x1; 00992 LPC_GPDMACH0->DMACCSrcAddr = (uint32_t) (buffer + dma_off); 00993 LPC_GPDMACH0->DMACCControl = dma_count | (1UL << 18) | (1UL << 21) | (1UL << 31) | DMA_CHANNEL_SRC_INC ; // 16 bit transfer , address increment, interrupt 00994 LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | (spi_port ? DMA_DEST_SSP1_TX : DMA_DEST_SSP0_TX); 00995 LPC_GPDMA->DMACSoftSReq = 0x1; 00996 do { 00997 } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running 00998 dma_off = dma_off + dma_count; 00999 } while (pixel > 0); 01000 01001 free ((uint16_t *) buffer); 01002 01003 if (spi_port == 0) { // TFT on SSP0 01004 do { 01005 } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI0 not idle 01006 /* disable SSP0 for DMA. */ 01007 LPC_SSP0->DMACR = 0x0; 01008 } else { 01009 do { 01010 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI1 not idle 01011 /* disable SSP1 for DMA. */ 01012 LPC_SSP1->DMACR = 0x0; 01013 } 01014 #else 01015 if (seldisp == 0) { 01016 _cs0 = 0; 01017 _cs1 = 1; 01018 } else if (seldisp == 1) { 01019 _cs0 = 1; 01020 _cs1 = 0; 01021 } else { 01022 _cs0 = 0; 01023 _cs1 = 0; 01024 } 01025 if (spi_port == 0) { // TFT on SSP0 01026 LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit 01027 LPC_SSP0->DR = 0x72; // start Data 01028 LPC_SSP0->CR0 |= 0x08UL; // set to 16 bit 01029 } else { 01030 LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit 01031 LPC_SSP1->DR = 0x72; // start Data 01032 LPC_SSP1->CR0 |= 0x08UL; // set to 16 bit 01033 } 01034 zeichen = &font[((c -32) * offset) + 4]; // start of char bitmap 01035 w = zeichen[0]; // width of actual char 01036 for (j=0; j<vert; j++) { // vert line 01037 for (i=0; i<hor; i++) { // horz line 01038 z = zeichen[bpl * i + ((j & 0xF8) >> 3)+1]; 01039 b = 1 << (j & 0x07); 01040 if (( z & b ) == 0x00) { 01041 _spi.write(_background); 01042 } else { 01043 _spi.write(_foreground); 01044 } 01045 } 01046 } 01047 #endif 01048 _cs0 = 1; 01049 _cs1 = 1; 01050 WindowMax(); 01051 if ((w + 2) < hor) { // x offset to next char 01052 char_x += w + 2; 01053 } else char_x += hor; 01054 01055 } 01056 01057 01058 void SPI_TFTx2::set_font(unsigned char* f) 01059 { 01060 font = f; 01061 } 01062 01063 void SPI_TFTx2::Bitmap(unsigned int x, unsigned int y, unsigned int w, unsigned int h,unsigned char *bitmap) 01064 { 01065 unsigned int j; 01066 int padd; 01067 unsigned short *bitmap_ptr = (unsigned short *)bitmap; 01068 // the lines are padded to multiple of 4 bytes in a bitmap 01069 padd = -1; 01070 do { 01071 padd ++; 01072 } while (2*(w + padd)%4 != 0); 01073 window(x, y, w, h); 01074 wr_cmd(0x22); 01075 if (seldisp == 0) { 01076 _cs0 = 0; 01077 _cs1 = 1; 01078 } else if (seldisp == 1) { 01079 _cs0 = 1; 01080 _cs1 = 0; 01081 } else { 01082 _cs0 = 0; 01083 _cs1 = 0; 01084 } 01085 if (spi_port == 0) { // TFT on SSP0 01086 #if defined USE_DMA 01087 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR; // we send to SSP0 01088 /* Enable SSP0 for DMA. */ 01089 LPC_SSP0->DMACR = 0x2; 01090 #endif 01091 LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit 01092 LPC_SSP0->DR = 0x72; // start Data 01093 LPC_SSP0->CR0 |= 0x08UL; // set to 16 bit 01094 01095 } else { 01096 #if defined USE_DMA 01097 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP1->DR; // we send to SSP1 01098 /* Enable SSP1 for DMA. */ 01099 LPC_SSP1->DMACR = 0x2; 01100 #endif 01101 LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit 01102 LPC_SSP1->DR = 0x72; // start Data command 01103 LPC_SSP1->CR0 |= 0x08UL; // set to 16 bit 01104 } 01105 01106 bitmap_ptr += ((h - 1)* (w + padd)); 01107 #if defined USE_DMA 01108 for (j = 0; j < h; j++) { //Lines 01109 LPC_GPDMA->DMACIntTCClear = 0x1; 01110 LPC_GPDMA->DMACIntErrClr = 0x1; 01111 LPC_GPDMACH0->DMACCSrcAddr = (uint32_t)bitmap_ptr; 01112 LPC_GPDMACH0->DMACCControl = w | (1UL << 18) | (1UL << 21) | (1UL << 31) | DMA_CHANNEL_SRC_INC ; // 16 bit transfer , address increment, interrupt 01113 LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | (spi_port ? DMA_DEST_SSP1_TX : DMA_DEST_SSP0_TX); 01114 LPC_GPDMA->DMACSoftSReq = 0x1; 01115 do { 01116 } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running 01117 01118 bitmap_ptr -= w; 01119 bitmap_ptr -= padd; 01120 } 01121 #else 01122 unsigned int i; 01123 for (j = 0; j < h; j++) { //Lines 01124 for (i = 0; i < w; i++) { // copy pixel data to TFT 01125 _spi.write(*bitmap_ptr); // one line 01126 bitmap_ptr++; 01127 } 01128 bitmap_ptr -= 2*w; 01129 bitmap_ptr -= padd; 01130 } 01131 #endif 01132 if (spi_port == 0) { // TFT on SSP0 01133 do { 01134 } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI FIFO not empty 01135 } else { 01136 do { 01137 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI FIFO not empty 01138 } 01139 _cs0 = 1; 01140 _cs1 = 1; 01141 WindowMax(); 01142 } 01143 01144 01145 int SPI_TFTx2::BMP_16(unsigned int x, unsigned int y, const char *Name_BMP) 01146 { 01147 01148 #define OffsetPixelWidth 18 01149 #define OffsetPixelHeigh 22 01150 #define OffsetFileSize 34 01151 #define OffsetPixData 10 01152 #define OffsetBPP 28 01153 01154 char filename[50]; 01155 unsigned char BMP_Header[54]; 01156 unsigned short BPP_t; 01157 unsigned int PixelWidth,PixelHeigh,start_data; 01158 unsigned int i,off; 01159 int padd,j; 01160 unsigned short *line; 01161 01162 // get the filename 01163 LocalFileSystem local("local"); 01164 sprintf(&filename[0],"/local/"); 01165 i=7; 01166 while (*Name_BMP!='\0') { 01167 filename[i++]=*Name_BMP++; 01168 } 01169 01170 fprintf(stderr, "filename : %s \n\r",filename); 01171 01172 FILE *Image = fopen((const char *)&filename[0], "rb"); // open the bmp file 01173 if (!Image) { 01174 return(0); // error file not found ! 01175 } 01176 01177 fread(&BMP_Header[0],1,54,Image); // get the BMP Header 01178 01179 if (BMP_Header[0] != 0x42 || BMP_Header[1] != 0x4D) { // check magic byte 01180 fclose(Image); 01181 return(-1); // error no BMP file 01182 } 01183 01184 BPP_t = BMP_Header[OffsetBPP] + (BMP_Header[OffsetBPP + 1] << 8); 01185 if (BPP_t != 0x0010) { 01186 fclose(Image); 01187 return(-2); // error no 16 bit BMP 01188 } 01189 01190 PixelHeigh = BMP_Header[OffsetPixelHeigh] + (BMP_Header[OffsetPixelHeigh + 1] << 8) + (BMP_Header[OffsetPixelHeigh + 2] << 16) + (BMP_Header[OffsetPixelHeigh + 3] << 24); 01191 PixelWidth = BMP_Header[OffsetPixelWidth] + (BMP_Header[OffsetPixelWidth + 1] << 8) + (BMP_Header[OffsetPixelWidth + 2] << 16) + (BMP_Header[OffsetPixelWidth + 3] << 24); 01192 if (PixelHeigh > height() + y || PixelWidth > width() + x) { 01193 fclose(Image); 01194 return(-3); // to big 01195 } 01196 01197 start_data = BMP_Header[OffsetPixData] + (BMP_Header[OffsetPixData + 1] << 8) + (BMP_Header[OffsetPixData + 2] << 16) + (BMP_Header[OffsetPixData + 3] << 24); 01198 01199 line = (unsigned short *) malloc (2 * PixelWidth); // we need a buffer for a line 01200 if (line == NULL) { 01201 return(-4); // error no memory 01202 } 01203 01204 // the bmp lines are padded to multiple of 4 bytes 01205 padd = -1; 01206 do { 01207 padd ++; 01208 } while ((PixelWidth * 2 + padd)%4 != 0); 01209 01210 01211 //fseek(Image, 70 ,SEEK_SET); 01212 window(x, y,PixelWidth ,PixelHeigh); 01213 wr_cmd(0x22); 01214 if (seldisp == 0) { 01215 _cs0 = 0; 01216 _cs1 = 1; 01217 } else if (seldisp == 1) { 01218 _cs0 = 1; 01219 _cs1 = 0; 01220 } else { 01221 _cs0 = 0; 01222 _cs1 = 0; 01223 } 01224 01225 if (spi_port == 0) { // TFT on SSP0 01226 #if defined USE_DMA 01227 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR; // we send to SSP0 01228 /* Enable SSP0 for DMA. */ 01229 LPC_SSP0->DMACR = 0x2; 01230 #endif 01231 LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit 01232 LPC_SSP0->DR = 0x72; // start Data 01233 LPC_SSP0->CR0 |= 0x08UL; // set to 16 bit 01234 01235 } else { 01236 #if defined USE_DMA 01237 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP1->DR; // we send to SSP1 01238 /* Enable SSP1 for DMA. */ 01239 LPC_SSP1->DMACR = 0x2; 01240 #endif 01241 LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit 01242 LPC_SSP1->DR = 0x72; // start Data 01243 LPC_SSP1->CR0 |= 0x08UL; // set to 16 bit 01244 } 01245 for (j = PixelHeigh - 1; j >= 0; j--) { //Lines bottom up 01246 off = j * (PixelWidth * 2 + padd) + start_data; // start of line 01247 fseek(Image, off ,SEEK_SET); 01248 fread(line,1,PixelWidth * 2,Image); // read a line - slow ! 01249 #if defined USE_DMA 01250 LPC_GPDMA->DMACIntTCClear = 0x1; 01251 LPC_GPDMA->DMACIntErrClr = 0x1; 01252 LPC_GPDMACH0->DMACCSrcAddr = (uint32_t)line; 01253 LPC_GPDMACH0->DMACCControl = PixelWidth | (1UL << 18) | (1UL << 21) | (1UL << 31) | DMA_CHANNEL_SRC_INC ; // 16 bit transfer , address increment, interrupt 01254 LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | (spi_port ? DMA_DEST_SSP1_TX : DMA_DEST_SSP0_TX); 01255 LPC_GPDMA->DMACSoftSReq = 0x1; 01256 do { 01257 } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running 01258 #else 01259 for (i = 0; i < PixelWidth; i++) { // copy pixel data to TFT 01260 _spi.write(line[i]); // one 16 bit pixel 01261 } 01262 #endif 01263 } 01264 if (spi_port == 0) { // TFT on SSP0 01265 do { 01266 } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI FIFO not empty 01267 } else { 01268 do { 01269 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI FIFO not empty 01270 } 01271 _cs0 = 1; 01272 _cs1 = 1; 01273 free (line); 01274 fclose(Image); 01275 WindowMax(); 01276 return(1); 01277 }
Generated on Tue Jul 12 2022 18:51:25 by 1.7.2