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

Dependents:   FRDM_RA8875_mPaint RA8875_Demo RA8875_KeyPadDemo SignalGenerator ... more

Fork of SPI_TFT by Peter Drescher

See Components - RA8875 Based Display

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

Offline Help Manual (Windows chm)

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

Committer:
dreschpe
Date:
Mon Sep 10 19:23:26 2012 +0000
Revision:
0:de9d1462a835
Child:
1:17e12e4e149f
[mbed] converted /TFT/SPI_TFT

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