Adapted from Peter Dresche's original for Waveshare 2.8inch TFT Touch Shield Board and Mbed 6. RGB order reversed by changing reg 16 commands, spi write code adjusted as there is no reset pin but there is data command pin. Wait commands changed for new thread_sleep style, Stream class explicitly included. 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

Committer:
dreschpe
Date:
Thu Sep 20 23:32:07 2012 +0000
Revision:
4:824715115046
Parent:
3:7f1d793b90df
Child:
5:9cbf4a534f7e
Bugfix + add comment

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