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:
Tue Sep 11 20:37:13 2012 +0000
Revision:
2:f30ea1eb3681
Parent:
1:17e12e4e149f
Child:
3:7f1d793b90df
Switch back to io pin CS. The use of automatic  SPI CS could make problems with interrupt or RTOS.

Who changed what in which revision?

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