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 Mar 25 10:11:00 2013 +0000
Revision:
16:2efcbb2814fa
Parent:
15:f5772cffc2b2
Child:
18:52cbeede86f0
fix bug in bmp for kinetis

Who changed what in which revision?

UserRevisionLine numberNew contents of line
dreschpe 8:65a4de035c3c 1 /* mbed library for 240*320 pixel display TFT based on HX8347D LCD Controller
dreschpe 8:65a4de035c3c 2 * Copyright (c) 2011 Peter Drescher - DC2PD
dreschpe 8:65a4de035c3c 3 *
dreschpe 8:65a4de035c3c 4 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
dreschpe 8:65a4de035c3c 5 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
dreschpe 8:65a4de035c3c 6 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
dreschpe 8:65a4de035c3c 7 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
dreschpe 8:65a4de035c3c 8 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
dreschpe 8:65a4de035c3c 9 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
dreschpe 8:65a4de035c3c 10 * THE SOFTWARE.
dreschpe 8:65a4de035c3c 11 */
dreschpe 8:65a4de035c3c 12
dreschpe 8:65a4de035c3c 13
dreschpe 8:65a4de035c3c 14 // fix bmp padding for Bitmap function
dreschpe 8:65a4de035c3c 15 // speed up pixel
dreschpe 8:65a4de035c3c 16 // 30.12.11 fix cls
dreschpe 8:65a4de035c3c 17 // 11.03.12 use DMA to speed up
dreschpe 8:65a4de035c3c 18 // 15.03.12 use SSEL for TFT CS to enable DMA Register writes
dreschpe 8:65a4de035c3c 19 // 06.04.12 fix SSEL CS problem
dreschpe 8:65a4de035c3c 20 // 06.04.12 use direct access to the spi register to speed up the library.
dreschpe 8:65a4de035c3c 21 // 11.09.12 switch back to using io pin as cs to avoid problems with SSEL CS.
dreschpe 13:2c91cb947161 22 // 21.09.12 fix Bug in BMP_16
dreschpe 8:65a4de035c3c 23 // 11.10.12 patch from Hans Bergles to get SPI1 working again
dreschpe 8:65a4de035c3c 24 // 03.02.13 add a switch to switch off DMA use for LPC11U24
dreschpe 13:2c91cb947161 25 // 04.03.13 add support for new Kinetis board
dreschpe 16:2efcbb2814fa 26 // 25.03.13 fix Bug in bitmap for Kinetis board
dreschpe 8:65a4de035c3c 27
dreschpe 8:65a4de035c3c 28 #include "SPI_TFT.h"
dreschpe 8:65a4de035c3c 29 #include "mbed.h"
dreschpe 8:65a4de035c3c 30
dreschpe 8:65a4de035c3c 31 #define BPP 16 // Bits per pixel
dreschpe 13:2c91cb947161 32
dreschpe 13:2c91cb947161 33 #if defined TARGET_LPC1768
dreschpe 14:ea3206e8e3bd 34 #define USE_DMA // we use dma to speed up
dreschpe 14:ea3206e8e3bd 35 #define NO_MBED_LIB // we write direct to the SPI register to speed up
dreschpe 8:65a4de035c3c 36 #endif
dreschpe 8:65a4de035c3c 37
dreschpe 13:2c91cb947161 38 #if defined NO_DMA // if LPC1768 user want no DMA
dreschpe 8:65a4de035c3c 39 #undef USE_DMA
dreschpe 8:65a4de035c3c 40 #endif
dreschpe 13:2c91cb947161 41
dreschpe 8:65a4de035c3c 42
dreschpe 8:65a4de035c3c 43 //extern Serial pc;
dreschpe 8:65a4de035c3c 44 //extern DigitalOut xx; // debug !!
dreschpe 8:65a4de035c3c 45
dreschpe 8:65a4de035c3c 46 SPI_TFT::SPI_TFT(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName reset, const char *name)
dreschpe 8:65a4de035c3c 47 : _spi(mosi, miso, sclk), _cs(cs), _reset(reset),GraphicsDisplay(name)
dreschpe 8:65a4de035c3c 48 {
dreschpe 8:65a4de035c3c 49 orientation = 0;
dreschpe 8:65a4de035c3c 50 char_x = 0;
dreschpe 14:ea3206e8e3bd 51 #if defined TARGET_LPC1768
dreschpe 14:ea3206e8e3bd 52 if (mosi == p11 || mosi == P0_18){
dreschpe 14:ea3206e8e3bd 53 spi_port = 0; // we must know the used SPI port to setup the DMA
dreschpe 14:ea3206e8e3bd 54 }
dreschpe 14:ea3206e8e3bd 55 else {
dreschpe 14:ea3206e8e3bd 56 spi_port = 1;
dreschpe 14:ea3206e8e3bd 57 }
dreschpe 14:ea3206e8e3bd 58 #endif
dreschpe 8:65a4de035c3c 59 tft_reset();
dreschpe 8:65a4de035c3c 60 }
dreschpe 8:65a4de035c3c 61
dreschpe 8:65a4de035c3c 62 int SPI_TFT::width()
dreschpe 8:65a4de035c3c 63 {
dreschpe 8:65a4de035c3c 64 if (orientation == 0 || orientation == 2) return 240;
dreschpe 8:65a4de035c3c 65 else return 320;
dreschpe 8:65a4de035c3c 66 }
dreschpe 8:65a4de035c3c 67
dreschpe 8:65a4de035c3c 68
dreschpe 8:65a4de035c3c 69 int SPI_TFT::height()
dreschpe 8:65a4de035c3c 70 {
dreschpe 8:65a4de035c3c 71 if (orientation == 0 || orientation == 2) return 320;
dreschpe 8:65a4de035c3c 72 else return 240;
dreschpe 8:65a4de035c3c 73 }
dreschpe 8:65a4de035c3c 74
dreschpe 8:65a4de035c3c 75
dreschpe 8:65a4de035c3c 76 void SPI_TFT::set_orientation(unsigned int o)
dreschpe 8:65a4de035c3c 77 {
dreschpe 8:65a4de035c3c 78 orientation = o;
dreschpe 8:65a4de035c3c 79 switch (orientation) {
dreschpe 8:65a4de035c3c 80 case 0:
dreschpe 8:65a4de035c3c 81 wr_reg(0x16, 0x08);
dreschpe 8:65a4de035c3c 82 break;
dreschpe 8:65a4de035c3c 83 case 1:
dreschpe 8:65a4de035c3c 84 wr_reg(0x16, 0x68);
dreschpe 8:65a4de035c3c 85 break;
dreschpe 8:65a4de035c3c 86 case 2:
dreschpe 8:65a4de035c3c 87 wr_reg(0x16, 0xC8);
dreschpe 8:65a4de035c3c 88 break;
dreschpe 8:65a4de035c3c 89 case 3:
dreschpe 8:65a4de035c3c 90 wr_reg(0x16, 0xA8);
dreschpe 8:65a4de035c3c 91 break;
dreschpe 8:65a4de035c3c 92 }
dreschpe 8:65a4de035c3c 93 WindowMax();
dreschpe 8:65a4de035c3c 94 }
dreschpe 8:65a4de035c3c 95
dreschpe 8:65a4de035c3c 96
dreschpe 8:65a4de035c3c 97 // write command to tft register
dreschpe 8:65a4de035c3c 98
dreschpe 8:65a4de035c3c 99 void SPI_TFT::wr_cmd(unsigned char cmd)
dreschpe 8:65a4de035c3c 100 {
dreschpe 8:65a4de035c3c 101 _cs = 0;
dreschpe 14:ea3206e8e3bd 102 #if defined NO_MBED_LIB
dreschpe 14:ea3206e8e3bd 103 unsigned short spi_d;
dreschpe 14:ea3206e8e3bd 104 spi_d = 0x7000 | cmd ;
dreschpe 14:ea3206e8e3bd 105 if (spi_port == 0) { // TFT on SSP0
dreschpe 14:ea3206e8e3bd 106 LPC_SSP0->DR = spi_d;
dreschpe 14:ea3206e8e3bd 107 // we have to wait for SPI IDLE to set CS back to high
dreschpe 14:ea3206e8e3bd 108 do {
dreschpe 14:ea3206e8e3bd 109 } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI0 not idle
dreschpe 14:ea3206e8e3bd 110 } else {
dreschpe 14:ea3206e8e3bd 111 LPC_SSP1->DR = spi_d;
dreschpe 14:ea3206e8e3bd 112 do {
dreschpe 14:ea3206e8e3bd 113 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI1 not idle
dreschpe 14:ea3206e8e3bd 114 }
dreschpe 14:ea3206e8e3bd 115 #else // use mbed lib
dreschpe 14:ea3206e8e3bd 116 #if defined TARGET_KL25Z // 8 Bit SPI
dreschpe 14:ea3206e8e3bd 117 _spi.write(0x70);
dreschpe 14:ea3206e8e3bd 118 _spi.write(cmd);
dreschpe 14:ea3206e8e3bd 119 #else // 16 Bit SPI
dreschpe 14:ea3206e8e3bd 120 unsigned short spi_d;
dreschpe 14:ea3206e8e3bd 121 spi_d = 0x7000 | cmd ;
dreschpe 14:ea3206e8e3bd 122 _spi.write(spi_d); // mbed lib
dreschpe 14:ea3206e8e3bd 123 #endif
dreschpe 14:ea3206e8e3bd 124 #endif
dreschpe 8:65a4de035c3c 125 _cs = 1;
dreschpe 8:65a4de035c3c 126 }
dreschpe 8:65a4de035c3c 127
dreschpe 8:65a4de035c3c 128
dreschpe 13:2c91cb947161 129 // write data to tft register
dreschpe 8:65a4de035c3c 130 void SPI_TFT::wr_dat(unsigned char dat)
dreschpe 8:65a4de035c3c 131 {
dreschpe 14:ea3206e8e3bd 132 _cs = 0;
dreschpe 14:ea3206e8e3bd 133 #if defined NO_MBED_LIB
dreschpe 14:ea3206e8e3bd 134 unsigned short spi_d;
dreschpe 14:ea3206e8e3bd 135 spi_d = 0x7200 | dat;
dreschpe 14:ea3206e8e3bd 136 if (spi_port == 0) { // TFT on SSP0
dreschpe 14:ea3206e8e3bd 137 LPC_SSP0->DR = spi_d;
dreschpe 14:ea3206e8e3bd 138 // we have to wait for SPI IDLE to set CS back to high
dreschpe 14:ea3206e8e3bd 139 do {
dreschpe 14:ea3206e8e3bd 140 } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI0 not idle
dreschpe 14:ea3206e8e3bd 141 } else {
dreschpe 14:ea3206e8e3bd 142 LPC_SSP1->DR = spi_d;
dreschpe 14:ea3206e8e3bd 143 do {
dreschpe 14:ea3206e8e3bd 144 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI1 not idle
dreschpe 14:ea3206e8e3bd 145 }
dreschpe 14:ea3206e8e3bd 146 #else // use mbed lib
dreschpe 14:ea3206e8e3bd 147 #if defined TARGET_KL25Z // 8 Bit SPI
dreschpe 14:ea3206e8e3bd 148 _spi.write(0x72);
dreschpe 14:ea3206e8e3bd 149 _spi.write(dat);
dreschpe 14:ea3206e8e3bd 150 #else // 16 Bit SPI
dreschpe 14:ea3206e8e3bd 151 unsigned short spi_d;
dreschpe 14:ea3206e8e3bd 152 spi_d = 0x7200 | dat;
dreschpe 14:ea3206e8e3bd 153 _spi.write(spi_d);
dreschpe 14:ea3206e8e3bd 154 #endif
dreschpe 14:ea3206e8e3bd 155 #endif
dreschpe 8:65a4de035c3c 156 _cs = 1;
dreschpe 8:65a4de035c3c 157 }
dreschpe 8:65a4de035c3c 158
dreschpe 8:65a4de035c3c 159
dreschpe 8:65a4de035c3c 160
dreschpe 8:65a4de035c3c 161 // the HX8347-D controller do not use the MISO (SDO) Signal.
dreschpe 8:65a4de035c3c 162 // This is a bug - ?
dreschpe 14:ea3206e8e3bd 163 // A read will return 0 at the moment
dreschpe 8:65a4de035c3c 164
dreschpe 8:65a4de035c3c 165 unsigned short SPI_TFT::rd_dat (void)
dreschpe 8:65a4de035c3c 166 {
dreschpe 8:65a4de035c3c 167 unsigned short val = 0;
dreschpe 8:65a4de035c3c 168
dreschpe 8:65a4de035c3c 169 //val = _spi.write(0x73ff); /* Dummy read 1 */
dreschpe 8:65a4de035c3c 170 //val = _spi.write(0x0000); /* Read D8..D15 */
dreschpe 8:65a4de035c3c 171 return (val);
dreschpe 8:65a4de035c3c 172 }
dreschpe 8:65a4de035c3c 173
dreschpe 13:2c91cb947161 174 // write to a TFT register
dreschpe 8:65a4de035c3c 175 void SPI_TFT::wr_reg (unsigned char reg, unsigned char val)
dreschpe 8:65a4de035c3c 176 {
dreschpe 8:65a4de035c3c 177 wr_cmd(reg);
dreschpe 8:65a4de035c3c 178 wr_dat(val);
dreschpe 8:65a4de035c3c 179 }
dreschpe 8:65a4de035c3c 180
dreschpe 13:2c91cb947161 181 // read from a TFT register
dreschpe 8:65a4de035c3c 182 unsigned short SPI_TFT::rd_reg (unsigned char reg)
dreschpe 8:65a4de035c3c 183 {
dreschpe 8:65a4de035c3c 184 wr_cmd(reg);
dreschpe 8:65a4de035c3c 185 return(rd_dat());
dreschpe 8:65a4de035c3c 186 }
dreschpe 8:65a4de035c3c 187
dreschpe 13:2c91cb947161 188 // setup TFT controller - this is called by constructor
dreschpe 8:65a4de035c3c 189 void SPI_TFT::tft_reset()
dreschpe 8:65a4de035c3c 190 {
dreschpe 13:2c91cb947161 191 #if defined TARGET_KL25Z // 8 Bit SPI
dreschpe 13:2c91cb947161 192 _spi.format(8,3);
dreschpe 13:2c91cb947161 193 #else // 16 Bit SPI
dreschpe 8:65a4de035c3c 194 _spi.format(16,3); // 16 bit spi mode 3
dreschpe 13:2c91cb947161 195 #endif
dreschpe 8:65a4de035c3c 196 _spi.frequency(48000000); // 48 Mhz SPI clock
dreschpe 8:65a4de035c3c 197 _cs = 1; // cs high
dreschpe 8:65a4de035c3c 198 _reset = 0; // display reset
dreschpe 8:65a4de035c3c 199
dreschpe 8:65a4de035c3c 200 wait_us(50);
dreschpe 8:65a4de035c3c 201 _reset = 1; // end reset
dreschpe 8:65a4de035c3c 202 wait_ms(5);
dreschpe 8:65a4de035c3c 203
dreschpe 8:65a4de035c3c 204 /* Start Initial Sequence ----------------------------------------------------*/
dreschpe 8:65a4de035c3c 205 wr_reg(0xEA, 0x00); /* Reset Power Control 1 */
dreschpe 8:65a4de035c3c 206 wr_reg(0xEB, 0x20); /* Power Control 2 */
dreschpe 8:65a4de035c3c 207 wr_reg(0xEC, 0x0C); /* Power Control 3 */
dreschpe 8:65a4de035c3c 208 wr_reg(0xED, 0xC4); /* Power Control 4 */
dreschpe 8:65a4de035c3c 209 wr_reg(0xE8, 0x40); /* Source OPON_N */
dreschpe 8:65a4de035c3c 210 wr_reg(0xE9, 0x38); /* Source OPON_I */
dreschpe 8:65a4de035c3c 211 wr_reg(0xF1, 0x01); /* */
dreschpe 8:65a4de035c3c 212 wr_reg(0xF2, 0x10); /* */
dreschpe 8:65a4de035c3c 213 wr_reg(0x27, 0xA3); /* Display Control 2 */
dreschpe 8:65a4de035c3c 214
dreschpe 8:65a4de035c3c 215 /* Power On sequence ---------------------------------------------------------*/
dreschpe 8:65a4de035c3c 216 wr_reg(0x1B, 0x1B); /* Power Control 2 */
dreschpe 8:65a4de035c3c 217 wr_reg(0x1A, 0x01); /* Power Control 1 */
dreschpe 8:65a4de035c3c 218 wr_reg(0x24, 0x2F); /* Vcom Control 2 */
dreschpe 8:65a4de035c3c 219 wr_reg(0x25, 0x57); /* Vcom Control 3 */
dreschpe 8:65a4de035c3c 220 wr_reg(0x23, 0x8D); /* Vcom Control 1 */
dreschpe 8:65a4de035c3c 221
dreschpe 8:65a4de035c3c 222 /* Gamma settings -----------------------------------------------------------*/
dreschpe 13:2c91cb947161 223 wr_reg(0x40,0x00); // default setup
dreschpe 8:65a4de035c3c 224 wr_reg(0x41,0x00); //
dreschpe 8:65a4de035c3c 225 wr_reg(0x42,0x01); //
dreschpe 8:65a4de035c3c 226 wr_reg(0x43,0x13); //
dreschpe 8:65a4de035c3c 227 wr_reg(0x44,0x10); //
dreschpe 8:65a4de035c3c 228 wr_reg(0x45,0x26); //
dreschpe 8:65a4de035c3c 229 wr_reg(0x46,0x08); //
dreschpe 8:65a4de035c3c 230 wr_reg(0x47,0x51); //
dreschpe 8:65a4de035c3c 231 wr_reg(0x48,0x02); //
dreschpe 8:65a4de035c3c 232 wr_reg(0x49,0x12); //
dreschpe 8:65a4de035c3c 233 wr_reg(0x4A,0x18); //
dreschpe 8:65a4de035c3c 234 wr_reg(0x4B,0x19); //
dreschpe 8:65a4de035c3c 235 wr_reg(0x4C,0x14); //
dreschpe 8:65a4de035c3c 236 wr_reg(0x50,0x19); //
dreschpe 8:65a4de035c3c 237 wr_reg(0x51,0x2F); //
dreschpe 8:65a4de035c3c 238 wr_reg(0x52,0x2C); //
dreschpe 8:65a4de035c3c 239 wr_reg(0x53,0x3E); //
dreschpe 8:65a4de035c3c 240 wr_reg(0x54,0x3F); //
dreschpe 8:65a4de035c3c 241 wr_reg(0x55,0x3F); //
dreschpe 8:65a4de035c3c 242 wr_reg(0x56,0x2E); //
dreschpe 8:65a4de035c3c 243 wr_reg(0x57,0x77); //
dreschpe 8:65a4de035c3c 244 wr_reg(0x58,0x0B); //
dreschpe 8:65a4de035c3c 245 wr_reg(0x59,0x06); //
dreschpe 8:65a4de035c3c 246 wr_reg(0x5A,0x07); //
dreschpe 8:65a4de035c3c 247 wr_reg(0x5B,0x0D); //
dreschpe 8:65a4de035c3c 248 wr_reg(0x5C,0x1D); //
dreschpe 8:65a4de035c3c 249 wr_reg(0x5D,0xCC); //
dreschpe 8:65a4de035c3c 250
dreschpe 8:65a4de035c3c 251 /* Power + Osc ---------------------------------------------------------------*/
dreschpe 14:ea3206e8e3bd 252 wr_reg(0x18, 0x36); /* OSC Control 1 */
dreschpe 14:ea3206e8e3bd 253 wr_reg(0x19, 0x01); /* OSC Control 2 */
dreschpe 14:ea3206e8e3bd 254 wr_reg(0x01, 0x00); /* Display Mode Control */
dreschpe 14:ea3206e8e3bd 255 wr_reg(0x1F, 0x88); /* Power Control 6 */
dreschpe 8:65a4de035c3c 256 wait_ms(5); /* Delay 5 ms */
dreschpe 14:ea3206e8e3bd 257 wr_reg(0x1F, 0x80); /* Power Control 6 */
dreschpe 14:ea3206e8e3bd 258 wait_ms(5); /* Delay 5 ms */
dreschpe 14:ea3206e8e3bd 259 wr_reg(0x1F, 0x90); /* Power Control 6 */
dreschpe 8:65a4de035c3c 260 wait_ms(5); /* Delay 5 ms */
dreschpe 14:ea3206e8e3bd 261 wr_reg(0x1F, 0xD0); /* Power Control 6 */
dreschpe 8:65a4de035c3c 262 wait_ms(5); /* Delay 5 ms */
dreschpe 8:65a4de035c3c 263
dreschpe 14:ea3206e8e3bd 264 wr_reg(0x17, 0x05); /* Colmod 16Bit/Pixel */
dreschpe 8:65a4de035c3c 265
dreschpe 14:ea3206e8e3bd 266 wr_reg(0x36, 0x00); /* Panel Characteristic */
dreschpe 14:ea3206e8e3bd 267 wr_reg(0x28, 0x38); /* Display Control 3 */
dreschpe 8:65a4de035c3c 268 wait_ms(40);
dreschpe 14:ea3206e8e3bd 269 wr_reg(0x28, 0x3C); /* Display Control 3 */
dreschpe 8:65a4de035c3c 270 switch (orientation) {
dreschpe 8:65a4de035c3c 271 case 0:
dreschpe 14:ea3206e8e3bd 272 wr_reg(0x16, 0x08);
dreschpe 8:65a4de035c3c 273 break;
dreschpe 8:65a4de035c3c 274 case 2:
dreschpe 14:ea3206e8e3bd 275 wr_reg(0x16, 0xC8);
dreschpe 8:65a4de035c3c 276 break;
dreschpe 8:65a4de035c3c 277 case 3:
dreschpe 14:ea3206e8e3bd 278 wr_reg(0x16, 0xA8);
dreschpe 14:ea3206e8e3bd 279 break;
dreschpe 14:ea3206e8e3bd 280 case 1:
dreschpe 14:ea3206e8e3bd 281 default:
dreschpe 14:ea3206e8e3bd 282 wr_reg(0x16, 0x68);
dreschpe 14:ea3206e8e3bd 283 break;
dreschpe 14:ea3206e8e3bd 284
dreschpe 8:65a4de035c3c 285 }
dreschpe 13:2c91cb947161 286 #if defined USE_DMA // setup DMA channel 0
dreschpe 13:2c91cb947161 287 LPC_SC->PCONP |= (1UL << 29); // Power up the GPDMA.
dreschpe 8:65a4de035c3c 288 LPC_GPDMA->DMACConfig = 1; // enable DMA controller
dreschpe 13:2c91cb947161 289 LPC_GPDMA->DMACIntTCClear = 0x1; // Reset the Interrupt status
dreschpe 8:65a4de035c3c 290 LPC_GPDMA->DMACIntErrClr = 0x1;
dreschpe 8:65a4de035c3c 291 LPC_GPDMACH0->DMACCLLI = 0;
dreschpe 8:65a4de035c3c 292 #endif
dreschpe 8:65a4de035c3c 293 WindowMax ();
dreschpe 8:65a4de035c3c 294 }
dreschpe 8:65a4de035c3c 295
dreschpe 13:2c91cb947161 296 // Set one pixel
dreschpe 8:65a4de035c3c 297 void SPI_TFT::pixel(int x, int y, int color)
dreschpe 8:65a4de035c3c 298 {
dreschpe 8:65a4de035c3c 299 wr_reg(0x03, (x >> 0));
dreschpe 8:65a4de035c3c 300 wr_reg(0x02, (x >> 8));
dreschpe 8:65a4de035c3c 301 wr_reg(0x07, (y >> 0));
dreschpe 8:65a4de035c3c 302 wr_reg(0x06, (y >> 8));
dreschpe 8:65a4de035c3c 303 wr_cmd(0x22);
dreschpe 8:65a4de035c3c 304 _cs = 0;
dreschpe 14:ea3206e8e3bd 305 #if defined NO_MBED_LIB
dreschpe 14:ea3206e8e3bd 306 if (spi_port == 0) { // TFT on SSP0
dreschpe 14:ea3206e8e3bd 307 LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit
dreschpe 14:ea3206e8e3bd 308 LPC_SSP0->DR = 0x72; // start Data
dreschpe 14:ea3206e8e3bd 309 LPC_SSP0->CR0 |= 0x08UL; // set back to 16 bit
dreschpe 14:ea3206e8e3bd 310 LPC_SSP0->DR = color; // Pixel
dreschpe 14:ea3206e8e3bd 311 // we have to wait for SPI IDLE to set CS back to high
dreschpe 14:ea3206e8e3bd 312 do {
dreschpe 14:ea3206e8e3bd 313 } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI0 not idle
dreschpe 14:ea3206e8e3bd 314 } else { // TFT on SSP1
dreschpe 14:ea3206e8e3bd 315 LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit
dreschpe 14:ea3206e8e3bd 316 LPC_SSP1->DR = 0x72; // start Data
dreschpe 14:ea3206e8e3bd 317 LPC_SSP1->CR0 |= 0x08UL; // set back to 16 bit
dreschpe 14:ea3206e8e3bd 318 LPC_SSP1->DR = color;
dreschpe 14:ea3206e8e3bd 319 // we have to wait for SPI IDLE to set CS back to high
dreschpe 14:ea3206e8e3bd 320 do {
dreschpe 14:ea3206e8e3bd 321 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI1 not idle
dreschpe 14:ea3206e8e3bd 322 }
dreschpe 14:ea3206e8e3bd 323 #else // use mbed lib
dreschpe 14:ea3206e8e3bd 324
dreschpe 14:ea3206e8e3bd 325 #if defined TARGET_KL25Z // 8 Bit SPI
dreschpe 14:ea3206e8e3bd 326 _spi.write(SPI_START | SPI_WR | SPI_DATA); // Write : RS = 1, RW = 0
dreschpe 14:ea3206e8e3bd 327 _spi.write(color >> 8);
dreschpe 14:ea3206e8e3bd 328 _spi.write(color & 0xff);
dreschpe 14:ea3206e8e3bd 329 #else
dreschpe 14:ea3206e8e3bd 330 _spi.format(8,3); // 8 bit Mode 3
dreschpe 14:ea3206e8e3bd 331 _spi.write(SPI_START | SPI_WR | SPI_DATA); // Write : RS = 1, RW = 0
dreschpe 14:ea3206e8e3bd 332 _spi.format(16,3); // switch to 16 bit Mode 3
dreschpe 14:ea3206e8e3bd 333 _spi.write(color); // Write D0..D15
dreschpe 14:ea3206e8e3bd 334 #endif
dreschpe 14:ea3206e8e3bd 335 #endif
dreschpe 8:65a4de035c3c 336 _cs = 1;
dreschpe 8:65a4de035c3c 337 }
dreschpe 8:65a4de035c3c 338
dreschpe 13:2c91cb947161 339 // define draw area
dreschpe 8:65a4de035c3c 340 void SPI_TFT::window (unsigned int x, unsigned int y, unsigned int w, unsigned int h)
dreschpe 8:65a4de035c3c 341 {
dreschpe 8:65a4de035c3c 342 wr_reg(0x03, x );
dreschpe 8:65a4de035c3c 343 wr_reg(0x02, (x >> 8));
dreschpe 8:65a4de035c3c 344 wr_reg(0x05, x+w-1 );
dreschpe 8:65a4de035c3c 345 wr_reg(0x04, (x+w-1 >> 8));
dreschpe 8:65a4de035c3c 346 wr_reg(0x07, y );
dreschpe 8:65a4de035c3c 347 wr_reg(0x06, ( y >> 8));
dreschpe 8:65a4de035c3c 348 wr_reg(0x09, ( y+h-1 ));
dreschpe 8:65a4de035c3c 349 wr_reg(0x08, ( y+h-1 >> 8));
dreschpe 8:65a4de035c3c 350 }
dreschpe 8:65a4de035c3c 351
dreschpe 13:2c91cb947161 352 // set draw area to max
dreschpe 8:65a4de035c3c 353 void SPI_TFT::WindowMax (void)
dreschpe 8:65a4de035c3c 354 {
dreschpe 8:65a4de035c3c 355 window (0, 0, width(), height());
dreschpe 8:65a4de035c3c 356 }
dreschpe 8:65a4de035c3c 357
dreschpe 8:65a4de035c3c 358
dreschpe 13:2c91cb947161 359 // clear screen
dreschpe 8:65a4de035c3c 360 void SPI_TFT::cls (void)
dreschpe 8:65a4de035c3c 361 {
dreschpe 14:ea3206e8e3bd 362 fprintf(stderr, "CLS \n\r");
dreschpe 8:65a4de035c3c 363 int pixel = ( width() * height());
dreschpe 14:ea3206e8e3bd 364 #if defined USE_DMA
dreschpe 14:ea3206e8e3bd 365 int dma_count;
dreschpe 14:ea3206e8e3bd 366 int color = _background;
dreschpe 14:ea3206e8e3bd 367 #endif
dreschpe 8:65a4de035c3c 368 WindowMax();
dreschpe 8:65a4de035c3c 369 wr_cmd(0x22);
dreschpe 8:65a4de035c3c 370
dreschpe 14:ea3206e8e3bd 371 #if defined NO_MBED_LIB
dreschpe 14:ea3206e8e3bd 372 #if defined USE_DMA
dreschpe 14:ea3206e8e3bd 373 LPC_GPDMACH0->DMACCSrcAddr = (uint32_t)&color;
dreschpe 14:ea3206e8e3bd 374 #endif
dreschpe 14:ea3206e8e3bd 375 _cs = 0;
dreschpe 14:ea3206e8e3bd 376 if (spi_port == 0) { // TFT on SSP0
dreschpe 14:ea3206e8e3bd 377 #if defined USE_DMA
dreschpe 14:ea3206e8e3bd 378 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR; // we send to SSP0
dreschpe 14:ea3206e8e3bd 379 /* Enable SSP0 for DMA. */
dreschpe 14:ea3206e8e3bd 380 LPC_SSP0->DMACR = 0x2;
dreschpe 14:ea3206e8e3bd 381 #endif
dreschpe 14:ea3206e8e3bd 382 LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit
dreschpe 14:ea3206e8e3bd 383 LPC_SSP0->DR = 0x72; // start byte
dreschpe 14:ea3206e8e3bd 384 LPC_SSP0->CR0 |= 0x08UL; // set to 16 bit
dreschpe 14:ea3206e8e3bd 385 } else { // TFT on SSP1
dreschpe 14:ea3206e8e3bd 386 #if defined USE_DMA
dreschpe 14:ea3206e8e3bd 387 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP1->DR; // we send to SSP1
dreschpe 14:ea3206e8e3bd 388 /* Enable SSP1 for DMA. */
dreschpe 14:ea3206e8e3bd 389 LPC_SSP1->DMACR = 0x2;
dreschpe 14:ea3206e8e3bd 390 #endif
dreschpe 14:ea3206e8e3bd 391 LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit
dreschpe 14:ea3206e8e3bd 392 LPC_SSP1->DR = 0x72; // start Data
dreschpe 14:ea3206e8e3bd 393 LPC_SSP1->CR0 |= 0x08UL; // set to 16 bit
dreschpe 8:65a4de035c3c 394 }
dreschpe 8:65a4de035c3c 395
dreschpe 14:ea3206e8e3bd 396 #if defined USE_DMA
dreschpe 14:ea3206e8e3bd 397 // start DMA
dreschpe 14:ea3206e8e3bd 398 do {
dreschpe 14:ea3206e8e3bd 399 if (pixel > 4095) {
dreschpe 14:ea3206e8e3bd 400 dma_count = 4095;
dreschpe 14:ea3206e8e3bd 401 pixel = pixel - 4095;
dreschpe 14:ea3206e8e3bd 402 } else {
dreschpe 14:ea3206e8e3bd 403 dma_count = pixel;
dreschpe 14:ea3206e8e3bd 404 pixel = 0;
dreschpe 14:ea3206e8e3bd 405 }
dreschpe 14:ea3206e8e3bd 406 LPC_GPDMA->DMACIntTCClear = 0x1;
dreschpe 14:ea3206e8e3bd 407 LPC_GPDMA->DMACIntErrClr = 0x1;
dreschpe 14:ea3206e8e3bd 408 LPC_GPDMACH0->DMACCControl = dma_count | (1UL << 18) | (1UL << 21) | (1UL << 31) ; // 16 bit transfer , no address increment, interrupt
dreschpe 14:ea3206e8e3bd 409 LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | (spi_port ? DMA_DEST_SSP1_TX : DMA_DEST_SSP0_TX);
dreschpe 14:ea3206e8e3bd 410 LPC_GPDMA->DMACSoftSReq = 0x1; // DMA request
dreschpe 14:ea3206e8e3bd 411 do {
dreschpe 14:ea3206e8e3bd 412 } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running
dreschpe 14:ea3206e8e3bd 413 } while (pixel > 0);
dreschpe 14:ea3206e8e3bd 414 if (spi_port == 0) { // TFT on SSP0
dreschpe 14:ea3206e8e3bd 415 do {
dreschpe 14:ea3206e8e3bd 416 } while ((0x0010 & LPC_SSP0->SR) == 0x10); // SPI FIFO not empty
dreschpe 14:ea3206e8e3bd 417 /* disable SSP0 for DMA. */
dreschpe 14:ea3206e8e3bd 418 LPC_SSP0->DMACR = 0x0;
dreschpe 14:ea3206e8e3bd 419 } else { // TFT on SSP1
dreschpe 14:ea3206e8e3bd 420 do {
dreschpe 14:ea3206e8e3bd 421 } while ((0x0010 & LPC_SSP1->SR) == 0x10); // SPI FIFO not empty
dreschpe 14:ea3206e8e3bd 422 /* disable SSP1 for DMA. */
dreschpe 14:ea3206e8e3bd 423 LPC_SSP1->DMACR = 0x0;
dreschpe 14:ea3206e8e3bd 424 }
dreschpe 13:2c91cb947161 425
dreschpe 14:ea3206e8e3bd 426 #else // no DMA
dreschpe 14:ea3206e8e3bd 427 unsigned int i;
dreschpe 14:ea3206e8e3bd 428 for (i = 0; i < ( width() * height()); i++)
dreschpe 14:ea3206e8e3bd 429 _spi.write(_background);
dreschpe 14:ea3206e8e3bd 430 #endif
dreschpe 14:ea3206e8e3bd 431
dreschpe 14:ea3206e8e3bd 432 #else // use mbed lib
dreschpe 14:ea3206e8e3bd 433 _cs = 0;
dreschpe 14:ea3206e8e3bd 434 #if defined TARGET_KL25Z // 8 Bit SPI
dreschpe 14:ea3206e8e3bd 435 _spi.write(SPI_START | SPI_WR | SPI_DATA); // Write : RS = 1, RW = 0
dreschpe 14:ea3206e8e3bd 436 unsigned int i;
dreschpe 14:ea3206e8e3bd 437 for (i = 0; i < ( width() * height()); i++) {
dreschpe 14:ea3206e8e3bd 438 _spi.write(_background >> 8);
dreschpe 14:ea3206e8e3bd 439 _spi.write(_background & 0xff);
dreschpe 14:ea3206e8e3bd 440 }
dreschpe 14:ea3206e8e3bd 441 #else // 16 bit SPI
dreschpe 14:ea3206e8e3bd 442 _spi.format(8,3); // 8 bit Mode 3
dreschpe 14:ea3206e8e3bd 443 _spi.write(SPI_START | SPI_WR | SPI_DATA); // Write : RS = 1, RW = 0
dreschpe 14:ea3206e8e3bd 444 _spi.format(16,3); // switch back to 16 bit Mode 3
dreschpe 14:ea3206e8e3bd 445 unsigned int i;
dreschpe 14:ea3206e8e3bd 446 for (i = 0; i < ( width() * height()); i++)
dreschpe 14:ea3206e8e3bd 447 _spi.write(_background);
dreschpe 14:ea3206e8e3bd 448 #endif
dreschpe 14:ea3206e8e3bd 449 #endif
dreschpe 8:65a4de035c3c 450 _cs = 1;
dreschpe 8:65a4de035c3c 451 }
dreschpe 8:65a4de035c3c 452
dreschpe 13:2c91cb947161 453 // draw circle
dreschpe 8:65a4de035c3c 454 void SPI_TFT::circle(int x0, int y0, int r, int color)
dreschpe 8:65a4de035c3c 455 {
dreschpe 8:65a4de035c3c 456
dreschpe 8:65a4de035c3c 457 int draw_x0, draw_y0;
dreschpe 8:65a4de035c3c 458 int draw_x1, draw_y1;
dreschpe 8:65a4de035c3c 459 int draw_x2, draw_y2;
dreschpe 8:65a4de035c3c 460 int draw_x3, draw_y3;
dreschpe 8:65a4de035c3c 461 int draw_x4, draw_y4;
dreschpe 8:65a4de035c3c 462 int draw_x5, draw_y5;
dreschpe 8:65a4de035c3c 463 int draw_x6, draw_y6;
dreschpe 8:65a4de035c3c 464 int draw_x7, draw_y7;
dreschpe 8:65a4de035c3c 465 int xx, yy;
dreschpe 8:65a4de035c3c 466 int di;
dreschpe 8:65a4de035c3c 467 //WindowMax();
dreschpe 8:65a4de035c3c 468 if (r == 0) { /* no radius */
dreschpe 8:65a4de035c3c 469 return;
dreschpe 8:65a4de035c3c 470 }
dreschpe 8:65a4de035c3c 471
dreschpe 8:65a4de035c3c 472 draw_x0 = draw_x1 = x0;
dreschpe 8:65a4de035c3c 473 draw_y0 = draw_y1 = y0 + r;
dreschpe 8:65a4de035c3c 474 if (draw_y0 < height()) {
dreschpe 8:65a4de035c3c 475 pixel(draw_x0, draw_y0, color); /* 90 degree */
dreschpe 8:65a4de035c3c 476 }
dreschpe 8:65a4de035c3c 477
dreschpe 8:65a4de035c3c 478 draw_x2 = draw_x3 = x0;
dreschpe 8:65a4de035c3c 479 draw_y2 = draw_y3 = y0 - r;
dreschpe 8:65a4de035c3c 480 if (draw_y2 >= 0) {
dreschpe 8:65a4de035c3c 481 pixel(draw_x2, draw_y2, color); /* 270 degree */
dreschpe 8:65a4de035c3c 482 }
dreschpe 8:65a4de035c3c 483
dreschpe 8:65a4de035c3c 484 draw_x4 = draw_x6 = x0 + r;
dreschpe 8:65a4de035c3c 485 draw_y4 = draw_y6 = y0;
dreschpe 8:65a4de035c3c 486 if (draw_x4 < width()) {
dreschpe 8:65a4de035c3c 487 pixel(draw_x4, draw_y4, color); /* 0 degree */
dreschpe 8:65a4de035c3c 488 }
dreschpe 8:65a4de035c3c 489
dreschpe 8:65a4de035c3c 490 draw_x5 = draw_x7 = x0 - r;
dreschpe 8:65a4de035c3c 491 draw_y5 = draw_y7 = y0;
dreschpe 8:65a4de035c3c 492 if (draw_x5>=0) {
dreschpe 8:65a4de035c3c 493 pixel(draw_x5, draw_y5, color); /* 180 degree */
dreschpe 8:65a4de035c3c 494 }
dreschpe 8:65a4de035c3c 495
dreschpe 8:65a4de035c3c 496 if (r == 1) {
dreschpe 8:65a4de035c3c 497 return;
dreschpe 8:65a4de035c3c 498 }
dreschpe 8:65a4de035c3c 499
dreschpe 8:65a4de035c3c 500 di = 3 - 2*r;
dreschpe 8:65a4de035c3c 501 xx = 0;
dreschpe 8:65a4de035c3c 502 yy = r;
dreschpe 8:65a4de035c3c 503 while (xx < yy) {
dreschpe 8:65a4de035c3c 504
dreschpe 8:65a4de035c3c 505 if (di < 0) {
dreschpe 8:65a4de035c3c 506 di += 4*xx + 6;
dreschpe 8:65a4de035c3c 507 } else {
dreschpe 8:65a4de035c3c 508 di += 4*(xx - yy) + 10;
dreschpe 8:65a4de035c3c 509 yy--;
dreschpe 8:65a4de035c3c 510 draw_y0--;
dreschpe 8:65a4de035c3c 511 draw_y1--;
dreschpe 8:65a4de035c3c 512 draw_y2++;
dreschpe 8:65a4de035c3c 513 draw_y3++;
dreschpe 8:65a4de035c3c 514 draw_x4--;
dreschpe 8:65a4de035c3c 515 draw_x5++;
dreschpe 8:65a4de035c3c 516 draw_x6--;
dreschpe 8:65a4de035c3c 517 draw_x7++;
dreschpe 8:65a4de035c3c 518 }
dreschpe 8:65a4de035c3c 519 xx++;
dreschpe 8:65a4de035c3c 520 draw_x0++;
dreschpe 8:65a4de035c3c 521 draw_x1--;
dreschpe 8:65a4de035c3c 522 draw_x2++;
dreschpe 8:65a4de035c3c 523 draw_x3--;
dreschpe 8:65a4de035c3c 524 draw_y4++;
dreschpe 8:65a4de035c3c 525 draw_y5++;
dreschpe 8:65a4de035c3c 526 draw_y6--;
dreschpe 8:65a4de035c3c 527 draw_y7--;
dreschpe 8:65a4de035c3c 528
dreschpe 8:65a4de035c3c 529 if ( (draw_x0 <= width()) && (draw_y0>=0) ) {
dreschpe 8:65a4de035c3c 530 pixel(draw_x0, draw_y0, color);
dreschpe 8:65a4de035c3c 531 }
dreschpe 8:65a4de035c3c 532
dreschpe 8:65a4de035c3c 533 if ( (draw_x1 >= 0) && (draw_y1 >= 0) ) {
dreschpe 8:65a4de035c3c 534 pixel(draw_x1, draw_y1, color);
dreschpe 8:65a4de035c3c 535 }
dreschpe 8:65a4de035c3c 536
dreschpe 8:65a4de035c3c 537 if ( (draw_x2 <= width()) && (draw_y2 <= height()) ) {
dreschpe 8:65a4de035c3c 538 pixel(draw_x2, draw_y2, color);
dreschpe 8:65a4de035c3c 539 }
dreschpe 8:65a4de035c3c 540
dreschpe 8:65a4de035c3c 541 if ( (draw_x3 >=0 ) && (draw_y3 <= height()) ) {
dreschpe 8:65a4de035c3c 542 pixel(draw_x3, draw_y3, color);
dreschpe 8:65a4de035c3c 543 }
dreschpe 8:65a4de035c3c 544
dreschpe 8:65a4de035c3c 545 if ( (draw_x4 <= width()) && (draw_y4 >= 0) ) {
dreschpe 8:65a4de035c3c 546 pixel(draw_x4, draw_y4, color);
dreschpe 8:65a4de035c3c 547 }
dreschpe 8:65a4de035c3c 548
dreschpe 8:65a4de035c3c 549 if ( (draw_x5 >= 0) && (draw_y5 >= 0) ) {
dreschpe 8:65a4de035c3c 550 pixel(draw_x5, draw_y5, color);
dreschpe 8:65a4de035c3c 551 }
dreschpe 8:65a4de035c3c 552 if ( (draw_x6 <=width()) && (draw_y6 <= height()) ) {
dreschpe 8:65a4de035c3c 553 pixel(draw_x6, draw_y6, color);
dreschpe 8:65a4de035c3c 554 }
dreschpe 8:65a4de035c3c 555 if ( (draw_x7 >= 0) && (draw_y7 <= height()) ) {
dreschpe 8:65a4de035c3c 556 pixel(draw_x7, draw_y7, color);
dreschpe 8:65a4de035c3c 557 }
dreschpe 8:65a4de035c3c 558 }
dreschpe 8:65a4de035c3c 559 return;
dreschpe 8:65a4de035c3c 560 }
dreschpe 8:65a4de035c3c 561
dreschpe 8:65a4de035c3c 562 void SPI_TFT::fillcircle(int x, int y, int r, int color)
dreschpe 8:65a4de035c3c 563 {
dreschpe 8:65a4de035c3c 564 int i;
dreschpe 8:65a4de035c3c 565 for (i = 0; i <= r; i++)
dreschpe 8:65a4de035c3c 566 circle(x,y,i,color);
dreschpe 8:65a4de035c3c 567 }
dreschpe 8:65a4de035c3c 568
dreschpe 8:65a4de035c3c 569
dreschpe 13:2c91cb947161 570 // draw horizontal line
dreschpe 8:65a4de035c3c 571 void SPI_TFT::hline(int x0, int x1, int y, int color)
dreschpe 8:65a4de035c3c 572 {
dreschpe 11:9bb71766cafc 573 int w;
dreschpe 8:65a4de035c3c 574 w = x1 - x0 + 1;
dreschpe 8:65a4de035c3c 575 window(x0,y,w,1);
dreschpe 8:65a4de035c3c 576 wr_cmd(0x22);
dreschpe 8:65a4de035c3c 577 _cs = 0;
dreschpe 14:ea3206e8e3bd 578 #if defined NO_MBED_LIB
dreschpe 14:ea3206e8e3bd 579 if (spi_port == 0) { // TFT on SSP0
dreschpe 14:ea3206e8e3bd 580 #if defined USE_DMA
dreschpe 14:ea3206e8e3bd 581 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR; // we send to SSP0
dreschpe 14:ea3206e8e3bd 582 /* Enable SSP0 for DMA. */
dreschpe 14:ea3206e8e3bd 583 LPC_SSP0->DMACR = 0x2;
dreschpe 14:ea3206e8e3bd 584 #endif
dreschpe 14:ea3206e8e3bd 585 LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit
dreschpe 14:ea3206e8e3bd 586 LPC_SSP0->DR = 0x72; // start Data
dreschpe 14:ea3206e8e3bd 587 LPC_SSP0->CR0 |= 0x08UL; // set to 16 bit
dreschpe 14:ea3206e8e3bd 588 } else { // TFT on SSP1
dreschpe 14:ea3206e8e3bd 589 #if defined USE_DMA
dreschpe 14:ea3206e8e3bd 590 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP1->DR; // we send to SSP1
dreschpe 14:ea3206e8e3bd 591 /* Enable SSP1 for DMA. */
dreschpe 14:ea3206e8e3bd 592 LPC_SSP1->DMACR = 0x2;
dreschpe 14:ea3206e8e3bd 593 #endif
dreschpe 14:ea3206e8e3bd 594 LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit
dreschpe 14:ea3206e8e3bd 595 LPC_SSP1->DR = 0x72; // start Data
dreschpe 14:ea3206e8e3bd 596 LPC_SSP1->CR0 |= 0x08UL; // set to 16 bit
dreschpe 14:ea3206e8e3bd 597 }
dreschpe 14:ea3206e8e3bd 598 #if defined USE_DMA
dreschpe 14:ea3206e8e3bd 599 LPC_GPDMA->DMACIntTCClear = 0x1;
dreschpe 14:ea3206e8e3bd 600 LPC_GPDMA->DMACIntErrClr = 0x1;
dreschpe 14:ea3206e8e3bd 601 LPC_GPDMACH0->DMACCSrcAddr = (uint32_t)&color;
dreschpe 14:ea3206e8e3bd 602 LPC_GPDMACH0->DMACCControl = w | (1UL << 18) | (1UL << 21) | (1UL << 31) ; // 16 bit transfer , no address increment, interrupt
dreschpe 14:ea3206e8e3bd 603 LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | (spi_port ? DMA_DEST_SSP1_TX : DMA_DEST_SSP0_TX);
dreschpe 14:ea3206e8e3bd 604 LPC_GPDMA->DMACSoftSReq = 0x1; // start DMA
dreschpe 14:ea3206e8e3bd 605 do {
dreschpe 14:ea3206e8e3bd 606 } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running
dreschpe 14:ea3206e8e3bd 607 if (spi_port == 0) { // TFT on SSP0
dreschpe 14:ea3206e8e3bd 608 do {
dreschpe 14:ea3206e8e3bd 609 } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI FIFO not empty
dreschpe 14:ea3206e8e3bd 610 } else { // TFT on SSP1
dreschpe 14:ea3206e8e3bd 611 do {
dreschpe 14:ea3206e8e3bd 612 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI FIFO not empty
dreschpe 14:ea3206e8e3bd 613 }
dreschpe 14:ea3206e8e3bd 614 #else // no DMA
dreschpe 14:ea3206e8e3bd 615 int i;
dreschpe 14:ea3206e8e3bd 616 for (i=0; i<w; i++) {
dreschpe 14:ea3206e8e3bd 617 _spi.write(color);
dreschpe 14:ea3206e8e3bd 618 }
dreschpe 14:ea3206e8e3bd 619 #endif
dreschpe 14:ea3206e8e3bd 620 #else // use mbed lib
dreschpe 14:ea3206e8e3bd 621 #if defined TARGET_KL25Z // 8 Bit SPI
dreschpe 14:ea3206e8e3bd 622 _spi.write(SPI_START | SPI_WR | SPI_DATA); // Write : RS = 1, RW = 0
dreschpe 14:ea3206e8e3bd 623 for (int j=0; j<w; j++) {
dreschpe 14:ea3206e8e3bd 624 _spi.write(color >> 8);
dreschpe 14:ea3206e8e3bd 625 _spi.write(color & 0xff);
dreschpe 14:ea3206e8e3bd 626 }
dreschpe 14:ea3206e8e3bd 627 #else // 16 Bit SPI
dreschpe 14:ea3206e8e3bd 628 _spi.format(8,3); // 8 bit Mode 3
dreschpe 14:ea3206e8e3bd 629 _spi.write(SPI_START | SPI_WR | SPI_DATA); // Write : RS = 1, RW = 0
dreschpe 14:ea3206e8e3bd 630 _spi.format(16,3); // switch back to 16 bit Mode 3
dreschpe 14:ea3206e8e3bd 631 for (int j=0; j<w; j++) {
dreschpe 14:ea3206e8e3bd 632 _spi.write(color);
dreschpe 14:ea3206e8e3bd 633 }
dreschpe 14:ea3206e8e3bd 634 #endif
dreschpe 14:ea3206e8e3bd 635 #endif
dreschpe 8:65a4de035c3c 636 _cs = 1;
dreschpe 8:65a4de035c3c 637 WindowMax();
dreschpe 8:65a4de035c3c 638 return;
dreschpe 8:65a4de035c3c 639 }
dreschpe 8:65a4de035c3c 640
dreschpe 13:2c91cb947161 641 // draw vertical line
dreschpe 8:65a4de035c3c 642 void SPI_TFT::vline(int x, int y0, int y1, int color)
dreschpe 8:65a4de035c3c 643 {
dreschpe 8:65a4de035c3c 644 int h;
dreschpe 8:65a4de035c3c 645 h = y1 - y0 + 1;
dreschpe 8:65a4de035c3c 646 window(x,y0,1,h);
dreschpe 8:65a4de035c3c 647 wr_cmd(0x22);
dreschpe 8:65a4de035c3c 648 _cs = 0;
dreschpe 14:ea3206e8e3bd 649 #if defined NO_MBED_LIB
dreschpe 14:ea3206e8e3bd 650 if (spi_port == 0) { // TFT on SSP0
dreschpe 14:ea3206e8e3bd 651 #if defined USE_DMA
dreschpe 14:ea3206e8e3bd 652 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR; // we send to SSP0
dreschpe 14:ea3206e8e3bd 653 /* Enable SSP0 for DMA. */
dreschpe 14:ea3206e8e3bd 654 LPC_SSP0->DMACR = 0x2;
dreschpe 14:ea3206e8e3bd 655 #endif
dreschpe 14:ea3206e8e3bd 656 LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit
dreschpe 14:ea3206e8e3bd 657 LPC_SSP0->DR = 0x72; // start Data
dreschpe 14:ea3206e8e3bd 658 LPC_SSP0->CR0 |= 0x08UL; // set to 16 bit
dreschpe 14:ea3206e8e3bd 659 } else { // TFT on SSP1
dreschpe 14:ea3206e8e3bd 660 #if defined USE_DMA
dreschpe 14:ea3206e8e3bd 661 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP1->DR; // we send to SSP1
dreschpe 14:ea3206e8e3bd 662 /* Enable SSP1 for DMA. */
dreschpe 14:ea3206e8e3bd 663 LPC_SSP1->DMACR = 0x2;
dreschpe 14:ea3206e8e3bd 664 #endif
dreschpe 14:ea3206e8e3bd 665 LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit
dreschpe 14:ea3206e8e3bd 666 LPC_SSP1->DR = 0x72; // start Data
dreschpe 14:ea3206e8e3bd 667 LPC_SSP1->CR0 |= 0x08UL; // set to 16 bit
dreschpe 14:ea3206e8e3bd 668 }
dreschpe 14:ea3206e8e3bd 669 #if defined USE_DMA
dreschpe 14:ea3206e8e3bd 670 LPC_GPDMA->DMACIntTCClear = 0x1;
dreschpe 14:ea3206e8e3bd 671 LPC_GPDMA->DMACIntErrClr = 0x1;
dreschpe 14:ea3206e8e3bd 672 LPC_GPDMACH0->DMACCSrcAddr = (uint32_t)&color;
dreschpe 14:ea3206e8e3bd 673 LPC_GPDMACH0->DMACCControl = h | (1UL << 18) | (1UL << 21) | (1UL << 31) ; // 16 bit transfer , no address increment, interrupt
dreschpe 14:ea3206e8e3bd 674 LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | (spi_port ? DMA_DEST_SSP1_TX : DMA_DEST_SSP0_TX);
dreschpe 14:ea3206e8e3bd 675 LPC_GPDMA->DMACSoftSReq = 0x1;
dreschpe 14:ea3206e8e3bd 676 do {
dreschpe 14:ea3206e8e3bd 677 } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running
dreschpe 8:65a4de035c3c 678
dreschpe 14:ea3206e8e3bd 679 if (spi_port == 0) { // TFT on SSP0
dreschpe 14:ea3206e8e3bd 680 do {
dreschpe 14:ea3206e8e3bd 681 } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI FIFO not empty
dreschpe 14:ea3206e8e3bd 682 } else { // TFT on SSP1
dreschpe 14:ea3206e8e3bd 683 do {
dreschpe 14:ea3206e8e3bd 684 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI FIFO not empty
dreschpe 14:ea3206e8e3bd 685 }
dreschpe 14:ea3206e8e3bd 686 #else // no DMA
dreschpe 14:ea3206e8e3bd 687 for (int y=0; y<h; y++) {
dreschpe 14:ea3206e8e3bd 688 _spi.write(color);
dreschpe 14:ea3206e8e3bd 689 }
dreschpe 14:ea3206e8e3bd 690 #endif
dreschpe 14:ea3206e8e3bd 691 #else // use mbed lib
dreschpe 14:ea3206e8e3bd 692 #if defined TARGET_KL25Z // 8 Bit SPI
dreschpe 14:ea3206e8e3bd 693 _spi.write(SPI_START | SPI_WR | SPI_DATA); // Write : RS = 1, RW = 0
dreschpe 14:ea3206e8e3bd 694 for (int y=0; y<h; y++) {
dreschpe 14:ea3206e8e3bd 695 _spi.write(color >> 8);
dreschpe 14:ea3206e8e3bd 696 _spi.write(color & 0xff);
dreschpe 14:ea3206e8e3bd 697 }
dreschpe 14:ea3206e8e3bd 698 #else // 16 bit SPI
dreschpe 14:ea3206e8e3bd 699 _spi.format(8,3); // 8 bit Mode 3
dreschpe 14:ea3206e8e3bd 700 _spi.write(SPI_START | SPI_WR | SPI_DATA); // Write : RS = 1, RW = 0
dreschpe 14:ea3206e8e3bd 701 _spi.format(16,3); // switch to 16 bit Mode 3
dreschpe 14:ea3206e8e3bd 702 for (int y=0; y<h; y++) {
dreschpe 14:ea3206e8e3bd 703 _spi.write(color);
dreschpe 14:ea3206e8e3bd 704 }
dreschpe 14:ea3206e8e3bd 705 #endif
dreschpe 14:ea3206e8e3bd 706 #endif
dreschpe 8:65a4de035c3c 707 _cs = 1;
dreschpe 8:65a4de035c3c 708 WindowMax();
dreschpe 8:65a4de035c3c 709 return;
dreschpe 8:65a4de035c3c 710 }
dreschpe 8:65a4de035c3c 711
dreschpe 8:65a4de035c3c 712
dreschpe 13:2c91cb947161 713 // draw line
dreschpe 8:65a4de035c3c 714 void SPI_TFT::line(int x0, int y0, int x1, int y1, int color)
dreschpe 8:65a4de035c3c 715 {
dreschpe 8:65a4de035c3c 716 //WindowMax();
dreschpe 8:65a4de035c3c 717 int dx = 0, dy = 0;
dreschpe 8:65a4de035c3c 718 int dx_sym = 0, dy_sym = 0;
dreschpe 8:65a4de035c3c 719 int dx_x2 = 0, dy_x2 = 0;
dreschpe 8:65a4de035c3c 720 int di = 0;
dreschpe 8:65a4de035c3c 721
dreschpe 8:65a4de035c3c 722 dx = x1-x0;
dreschpe 8:65a4de035c3c 723 dy = y1-y0;
dreschpe 8:65a4de035c3c 724
dreschpe 8:65a4de035c3c 725 if (dx == 0) { /* vertical line */
dreschpe 8:65a4de035c3c 726 if (y1 > y0) vline(x0,y0,y1,color);
dreschpe 8:65a4de035c3c 727 else vline(x0,y1,y0,color);
dreschpe 8:65a4de035c3c 728 return;
dreschpe 8:65a4de035c3c 729 }
dreschpe 8:65a4de035c3c 730
dreschpe 8:65a4de035c3c 731 if (dx > 0) {
dreschpe 8:65a4de035c3c 732 dx_sym = 1;
dreschpe 8:65a4de035c3c 733 } else {
dreschpe 8:65a4de035c3c 734 dx_sym = -1;
dreschpe 8:65a4de035c3c 735 }
dreschpe 8:65a4de035c3c 736 if (dy == 0) { /* horizontal line */
dreschpe 8:65a4de035c3c 737 if (x1 > x0) hline(x0,x1,y0,color);
dreschpe 8:65a4de035c3c 738 else hline(x1,x0,y0,color);
dreschpe 8:65a4de035c3c 739 return;
dreschpe 8:65a4de035c3c 740 }
dreschpe 8:65a4de035c3c 741
dreschpe 8:65a4de035c3c 742 if (dy > 0) {
dreschpe 8:65a4de035c3c 743 dy_sym = 1;
dreschpe 8:65a4de035c3c 744 } else {
dreschpe 8:65a4de035c3c 745 dy_sym = -1;
dreschpe 8:65a4de035c3c 746 }
dreschpe 8:65a4de035c3c 747
dreschpe 8:65a4de035c3c 748 dx = dx_sym*dx;
dreschpe 8:65a4de035c3c 749 dy = dy_sym*dy;
dreschpe 8:65a4de035c3c 750
dreschpe 8:65a4de035c3c 751 dx_x2 = dx*2;
dreschpe 8:65a4de035c3c 752 dy_x2 = dy*2;
dreschpe 8:65a4de035c3c 753
dreschpe 8:65a4de035c3c 754 if (dx >= dy) {
dreschpe 8:65a4de035c3c 755 di = dy_x2 - dx;
dreschpe 8:65a4de035c3c 756 while (x0 != x1) {
dreschpe 8:65a4de035c3c 757
dreschpe 8:65a4de035c3c 758 pixel(x0, y0, color);
dreschpe 8:65a4de035c3c 759 x0 += dx_sym;
dreschpe 8:65a4de035c3c 760 if (di<0) {
dreschpe 8:65a4de035c3c 761 di += dy_x2;
dreschpe 8:65a4de035c3c 762 } else {
dreschpe 8:65a4de035c3c 763 di += dy_x2 - dx_x2;
dreschpe 8:65a4de035c3c 764 y0 += dy_sym;
dreschpe 8:65a4de035c3c 765 }
dreschpe 8:65a4de035c3c 766 }
dreschpe 8:65a4de035c3c 767 pixel(x0, y0, color);
dreschpe 8:65a4de035c3c 768 } else {
dreschpe 8:65a4de035c3c 769 di = dx_x2 - dy;
dreschpe 8:65a4de035c3c 770 while (y0 != y1) {
dreschpe 8:65a4de035c3c 771 pixel(x0, y0, color);
dreschpe 8:65a4de035c3c 772 y0 += dy_sym;
dreschpe 8:65a4de035c3c 773 if (di < 0) {
dreschpe 8:65a4de035c3c 774 di += dx_x2;
dreschpe 8:65a4de035c3c 775 } else {
dreschpe 8:65a4de035c3c 776 di += dx_x2 - dy_x2;
dreschpe 8:65a4de035c3c 777 x0 += dx_sym;
dreschpe 8:65a4de035c3c 778 }
dreschpe 8:65a4de035c3c 779 }
dreschpe 8:65a4de035c3c 780 pixel(x0, y0, color);
dreschpe 8:65a4de035c3c 781 }
dreschpe 8:65a4de035c3c 782 return;
dreschpe 8:65a4de035c3c 783 }
dreschpe 8:65a4de035c3c 784
dreschpe 13:2c91cb947161 785 // draw rect
dreschpe 8:65a4de035c3c 786 void SPI_TFT::rect(int x0, int y0, int x1, int y1, int color)
dreschpe 8:65a4de035c3c 787 {
dreschpe 8:65a4de035c3c 788
dreschpe 8:65a4de035c3c 789 if (x1 > x0) hline(x0,x1,y0,color);
dreschpe 8:65a4de035c3c 790 else hline(x1,x0,y0,color);
dreschpe 8:65a4de035c3c 791
dreschpe 8:65a4de035c3c 792 if (y1 > y0) vline(x0,y0,y1,color);
dreschpe 8:65a4de035c3c 793 else vline(x0,y1,y0,color);
dreschpe 8:65a4de035c3c 794
dreschpe 8:65a4de035c3c 795 if (x1 > x0) hline(x0,x1,y1,color);
dreschpe 8:65a4de035c3c 796 else hline(x1,x0,y1,color);
dreschpe 8:65a4de035c3c 797
dreschpe 8:65a4de035c3c 798 if (y1 > y0) vline(x1,y0,y1,color);
dreschpe 8:65a4de035c3c 799 else vline(x1,y1,y0,color);
dreschpe 8:65a4de035c3c 800
dreschpe 8:65a4de035c3c 801 return;
dreschpe 8:65a4de035c3c 802 }
dreschpe 8:65a4de035c3c 803
dreschpe 8:65a4de035c3c 804
dreschpe 13:2c91cb947161 805 // fill rect
dreschpe 8:65a4de035c3c 806 void SPI_TFT::fillrect(int x0, int y0, int x1, int y1, int color)
dreschpe 8:65a4de035c3c 807 {
dreschpe 8:65a4de035c3c 808
dreschpe 8:65a4de035c3c 809 int h = y1 - y0 + 1;
dreschpe 8:65a4de035c3c 810 int w = x1 - x0 + 1;
dreschpe 8:65a4de035c3c 811 int pixel = h * w;
dreschpe 14:ea3206e8e3bd 812 #if defined USE_DMA
dreschpe 14:ea3206e8e3bd 813 int dma_count;
dreschpe 14:ea3206e8e3bd 814 #endif
dreschpe 8:65a4de035c3c 815 window(x0,y0,w,h);
dreschpe 8:65a4de035c3c 816 wr_cmd(0x22);
dreschpe 8:65a4de035c3c 817 _cs = 0;
dreschpe 14:ea3206e8e3bd 818 #if defined NO_MBED_LIB
dreschpe 14:ea3206e8e3bd 819 if (spi_port == 0) { // TFT on SSP0
dreschpe 14:ea3206e8e3bd 820 #if defined USE_DMA
dreschpe 14:ea3206e8e3bd 821 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR; // we send to SSP0
dreschpe 14:ea3206e8e3bd 822 /* Enable SSP0 for DMA. */
dreschpe 14:ea3206e8e3bd 823 LPC_SSP0->DMACR = 0x2;
dreschpe 14:ea3206e8e3bd 824 #endif
dreschpe 14:ea3206e8e3bd 825 LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit
dreschpe 14:ea3206e8e3bd 826 LPC_SSP0->DR = 0x72; // start Data
dreschpe 14:ea3206e8e3bd 827 LPC_SSP0->CR0 |= 0x08UL; // set to 16 bit
dreschpe 14:ea3206e8e3bd 828 } else { // TFT on SSP1
dreschpe 14:ea3206e8e3bd 829 #if defined USE_DMA
dreschpe 14:ea3206e8e3bd 830 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP1->DR; // we send to SSP1
dreschpe 14:ea3206e8e3bd 831 /* Enable SSP1 for DMA. */
dreschpe 14:ea3206e8e3bd 832 LPC_SSP1->DMACR = 0x2;
dreschpe 14:ea3206e8e3bd 833 #endif
dreschpe 14:ea3206e8e3bd 834 LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit
dreschpe 14:ea3206e8e3bd 835 LPC_SSP1->DR = 0x72; // start Data
dreschpe 14:ea3206e8e3bd 836 LPC_SSP1->CR0 |= 0x08UL; // set to 16 bit
dreschpe 8:65a4de035c3c 837 }
dreschpe 14:ea3206e8e3bd 838 #if defined USE_DMA
dreschpe 14:ea3206e8e3bd 839 do {
dreschpe 14:ea3206e8e3bd 840 if (pixel > 4095) {
dreschpe 14:ea3206e8e3bd 841 dma_count = 4095;
dreschpe 14:ea3206e8e3bd 842 pixel = pixel - 4095;
dreschpe 14:ea3206e8e3bd 843 } else {
dreschpe 14:ea3206e8e3bd 844 dma_count = pixel;
dreschpe 14:ea3206e8e3bd 845 pixel = 0;
dreschpe 14:ea3206e8e3bd 846 }
dreschpe 14:ea3206e8e3bd 847 LPC_GPDMA->DMACIntTCClear = 0x1;
dreschpe 14:ea3206e8e3bd 848 LPC_GPDMA->DMACIntErrClr = 0x1;
dreschpe 14:ea3206e8e3bd 849 LPC_GPDMACH0->DMACCSrcAddr = (uint32_t)&color;
dreschpe 14:ea3206e8e3bd 850 LPC_GPDMACH0->DMACCControl = dma_count | (1UL << 18) | (1UL << 21) | (1UL << 31) ; // 16 bit transfer , no address increment, interrupt
dreschpe 14:ea3206e8e3bd 851 LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | (spi_port ? DMA_DEST_SSP1_TX : DMA_DEST_SSP0_TX);
dreschpe 14:ea3206e8e3bd 852 LPC_GPDMA->DMACSoftSReq = 0x1;
dreschpe 14:ea3206e8e3bd 853 do {
dreschpe 14:ea3206e8e3bd 854 } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running
dreschpe 8:65a4de035c3c 855
dreschpe 14:ea3206e8e3bd 856 } while (pixel > 0);
dreschpe 13:2c91cb947161 857
dreschpe 14:ea3206e8e3bd 858 if (spi_port == 0) { // TFT on SSP0
dreschpe 14:ea3206e8e3bd 859 do {
dreschpe 14:ea3206e8e3bd 860 } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI FIFO not empty
dreschpe 14:ea3206e8e3bd 861 } else { // TFT on SSP1
dreschpe 14:ea3206e8e3bd 862 do {
dreschpe 14:ea3206e8e3bd 863 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI FIFO not empty
dreschpe 14:ea3206e8e3bd 864 }
dreschpe 14:ea3206e8e3bd 865
dreschpe 14:ea3206e8e3bd 866 #else // no DMA
dreschpe 14:ea3206e8e3bd 867 for (int p=0; p<pixel; p++) {
dreschpe 14:ea3206e8e3bd 868 _spi.write(color);
dreschpe 14:ea3206e8e3bd 869 }
dreschpe 14:ea3206e8e3bd 870 #endif
dreschpe 13:2c91cb947161 871
dreschpe 14:ea3206e8e3bd 872 #else // use mbed lib
dreschpe 14:ea3206e8e3bd 873 #if defined TARGET_KL25Z // 8 Bit SPI
dreschpe 14:ea3206e8e3bd 874 _spi.write(SPI_START | SPI_WR | SPI_DATA); // Write : RS = 1, RW = 0
dreschpe 14:ea3206e8e3bd 875 for (int p=0; p<pixel; p++) {
dreschpe 14:ea3206e8e3bd 876 _spi.write(color >> 8);
dreschpe 14:ea3206e8e3bd 877 _spi.write(color & 0xff);
dreschpe 14:ea3206e8e3bd 878 }
dreschpe 13:2c91cb947161 879
dreschpe 14:ea3206e8e3bd 880 #else // 16 bit SPI
dreschpe 14:ea3206e8e3bd 881 _spi.format(8,3); // 8 bit Mode 3
dreschpe 14:ea3206e8e3bd 882 _spi.write(SPI_START | SPI_WR | SPI_DATA); // Write : RS = 1, RW = 0
dreschpe 14:ea3206e8e3bd 883 _spi.format(16,3); // switch to 16 bit Mode 3
dreschpe 14:ea3206e8e3bd 884 for (int p=0; p<pixel; p++) {
dreschpe 14:ea3206e8e3bd 885 _spi.write(color);
dreschpe 14:ea3206e8e3bd 886 }
dreschpe 14:ea3206e8e3bd 887 #endif
dreschpe 14:ea3206e8e3bd 888 #endif
dreschpe 8:65a4de035c3c 889 _cs = 1;
dreschpe 8:65a4de035c3c 890 WindowMax();
dreschpe 8:65a4de035c3c 891 return;
dreschpe 8:65a4de035c3c 892 }
dreschpe 8:65a4de035c3c 893
dreschpe 13:2c91cb947161 894 // set cursor position
dreschpe 8:65a4de035c3c 895 void SPI_TFT::locate(int x, int y)
dreschpe 8:65a4de035c3c 896 {
dreschpe 8:65a4de035c3c 897 char_x = x;
dreschpe 8:65a4de035c3c 898 char_y = y;
dreschpe 8:65a4de035c3c 899 }
dreschpe 8:65a4de035c3c 900
dreschpe 8:65a4de035c3c 901
dreschpe 13:2c91cb947161 902 // calculate num of chars in a row
dreschpe 8:65a4de035c3c 903 int SPI_TFT::columns()
dreschpe 8:65a4de035c3c 904 {
dreschpe 8:65a4de035c3c 905 return width() / font[1];
dreschpe 8:65a4de035c3c 906 }
dreschpe 8:65a4de035c3c 907
dreschpe 13:2c91cb947161 908 // calculate num of rows on the screen
dreschpe 8:65a4de035c3c 909 int SPI_TFT::rows()
dreschpe 8:65a4de035c3c 910 {
dreschpe 8:65a4de035c3c 911 return height() / font[2];
dreschpe 8:65a4de035c3c 912 }
dreschpe 8:65a4de035c3c 913
dreschpe 13:2c91cb947161 914 // print a char on the screen
dreschpe 8:65a4de035c3c 915 int SPI_TFT::_putc(int value)
dreschpe 8:65a4de035c3c 916 {
dreschpe 8:65a4de035c3c 917 if (value == '\n') { // new line
dreschpe 8:65a4de035c3c 918 char_x = 0;
dreschpe 8:65a4de035c3c 919 char_y = char_y + font[2];
dreschpe 8:65a4de035c3c 920 if (char_y >= height() - font[2]) {
dreschpe 8:65a4de035c3c 921 char_y = 0;
dreschpe 8:65a4de035c3c 922 }
dreschpe 8:65a4de035c3c 923 } else {
dreschpe 8:65a4de035c3c 924 character(char_x, char_y, value);
dreschpe 8:65a4de035c3c 925 }
dreschpe 8:65a4de035c3c 926 return value;
dreschpe 8:65a4de035c3c 927 }
dreschpe 8:65a4de035c3c 928
dreschpe 13:2c91cb947161 929 // consrtuct the char out of the font
dreschpe 8:65a4de035c3c 930 void SPI_TFT::character(int x, int y, int c)
dreschpe 8:65a4de035c3c 931 {
dreschpe 9:a63fd1ad41b0 932 unsigned int hor,vert,offset,bpl,j,i,b;
dreschpe 8:65a4de035c3c 933 unsigned char* zeichen;
dreschpe 8:65a4de035c3c 934 unsigned char z,w;
dreschpe 14:ea3206e8e3bd 935 #if defined USE_DMA
dreschpe 14:ea3206e8e3bd 936 unsigned int pixel;
dreschpe 14:ea3206e8e3bd 937 unsigned int p;
dreschpe 14:ea3206e8e3bd 938 unsigned int dma_count,dma_off;
dreschpe 14:ea3206e8e3bd 939 uint16_t *buffer;
dreschpe 14:ea3206e8e3bd 940 #endif
dreschpe 8:65a4de035c3c 941
dreschpe 8:65a4de035c3c 942 if ((c < 31) || (c > 127)) return; // test char range
dreschpe 8:65a4de035c3c 943
dreschpe 8:65a4de035c3c 944 // read font parameter from start of array
dreschpe 8:65a4de035c3c 945 offset = font[0]; // bytes / char
dreschpe 8:65a4de035c3c 946 hor = font[1]; // get hor size of font
dreschpe 8:65a4de035c3c 947 vert = font[2]; // get vert size of font
dreschpe 8:65a4de035c3c 948 bpl = font[3]; // bytes per line
dreschpe 8:65a4de035c3c 949
dreschpe 8:65a4de035c3c 950 if (char_x + hor > width()) {
dreschpe 8:65a4de035c3c 951 char_x = 0;
dreschpe 8:65a4de035c3c 952 char_y = char_y + vert;
dreschpe 8:65a4de035c3c 953 if (char_y >= height() - font[2]) {
dreschpe 8:65a4de035c3c 954 char_y = 0;
dreschpe 8:65a4de035c3c 955 }
dreschpe 8:65a4de035c3c 956 }
dreschpe 8:65a4de035c3c 957 window(char_x, char_y,hor,vert); // char box
dreschpe 8:65a4de035c3c 958 wr_cmd(0x22);
dreschpe 8:65a4de035c3c 959
dreschpe 14:ea3206e8e3bd 960 #if defined USE_DMA
dreschpe 14:ea3206e8e3bd 961 pixel = hor * vert; // calculate buffer size
dreschpe 8:65a4de035c3c 962
dreschpe 14:ea3206e8e3bd 963 buffer = (uint16_t *) malloc (2*pixel); // we need a buffer for the 16 bit
dreschpe 14:ea3206e8e3bd 964 if (buffer == NULL) {
dreschpe 14:ea3206e8e3bd 965 //led = 1;
dreschpe 14:ea3206e8e3bd 966 //pc.printf("Malloc error !\n\r");
dreschpe 14:ea3206e8e3bd 967 return; // error no memory
dreschpe 8:65a4de035c3c 968 }
dreschpe 8:65a4de035c3c 969
dreschpe 14:ea3206e8e3bd 970 zeichen = &font[((c -32) * offset) + 4]; // start of char bitmap
dreschpe 14:ea3206e8e3bd 971 w = zeichen[0]; // width of actual char
dreschpe 14:ea3206e8e3bd 972 p = 0;
dreschpe 14:ea3206e8e3bd 973 // construct the char into the buffer
dreschpe 14:ea3206e8e3bd 974 for (j=0; j<vert; j++) { // vert line
dreschpe 14:ea3206e8e3bd 975 for (i=0; i<hor; i++) { // horz line
dreschpe 14:ea3206e8e3bd 976 z = zeichen[bpl * i + ((j & 0xF8) >> 3)+1];
dreschpe 14:ea3206e8e3bd 977 b = 1 << (j & 0x07);
dreschpe 14:ea3206e8e3bd 978 if (( z & b ) == 0x00) {
dreschpe 14:ea3206e8e3bd 979 buffer[p] = _background;
dreschpe 14:ea3206e8e3bd 980 } else {
dreschpe 14:ea3206e8e3bd 981 buffer[p] = _foreground;
dreschpe 14:ea3206e8e3bd 982 }
dreschpe 14:ea3206e8e3bd 983 p++;
dreschpe 8:65a4de035c3c 984 }
dreschpe 8:65a4de035c3c 985 }
dreschpe 14:ea3206e8e3bd 986
dreschpe 14:ea3206e8e3bd 987 // copy the buffer with DMA SPI to display
dreschpe 14:ea3206e8e3bd 988 dma_off = 0; // offset for DMA transfer
dreschpe 14:ea3206e8e3bd 989 _cs = 0;
dreschpe 14:ea3206e8e3bd 990 if (spi_port == 0) { // TFT on SSP0
dreschpe 14:ea3206e8e3bd 991 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR; // we send to SSP0
dreschpe 14:ea3206e8e3bd 992 /* Enable SSP0 for DMA. */
dreschpe 14:ea3206e8e3bd 993 LPC_SSP0->DMACR = 0x2;
dreschpe 14:ea3206e8e3bd 994 LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit
dreschpe 14:ea3206e8e3bd 995 LPC_SSP0->DR = 0x72; // start Data
dreschpe 14:ea3206e8e3bd 996 LPC_SSP0->CR0 |= 0x08UL; // set to 16 bit
dreschpe 14:ea3206e8e3bd 997 } else { // TFT on SSP1
dreschpe 14:ea3206e8e3bd 998 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP1->DR; // we send to SSP1
dreschpe 14:ea3206e8e3bd 999 /* Enable SSP1 for DMA. */
dreschpe 14:ea3206e8e3bd 1000 LPC_SSP1->DMACR = 0x2;
dreschpe 14:ea3206e8e3bd 1001 LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit
dreschpe 14:ea3206e8e3bd 1002 LPC_SSP1->DR = 0x72; // start Data
dreschpe 14:ea3206e8e3bd 1003 LPC_SSP1->CR0 |= 0x08UL; // set to 16 bit
dreschpe 14:ea3206e8e3bd 1004 }
dreschpe 14:ea3206e8e3bd 1005
dreschpe 14:ea3206e8e3bd 1006 // start DMA
dreschpe 14:ea3206e8e3bd 1007 do {
dreschpe 14:ea3206e8e3bd 1008 if (pixel > 4095) { // this is a giant font !
dreschpe 14:ea3206e8e3bd 1009 dma_count = 4095;
dreschpe 14:ea3206e8e3bd 1010 pixel = pixel - 4095;
dreschpe 14:ea3206e8e3bd 1011 } else {
dreschpe 14:ea3206e8e3bd 1012 dma_count = pixel;
dreschpe 14:ea3206e8e3bd 1013 pixel = 0;
dreschpe 14:ea3206e8e3bd 1014 }
dreschpe 14:ea3206e8e3bd 1015 LPC_GPDMA->DMACIntTCClear = 0x1;
dreschpe 14:ea3206e8e3bd 1016 LPC_GPDMA->DMACIntErrClr = 0x1;
dreschpe 14:ea3206e8e3bd 1017 LPC_GPDMACH0->DMACCSrcAddr = (uint32_t) (buffer + dma_off);
dreschpe 14:ea3206e8e3bd 1018 LPC_GPDMACH0->DMACCControl = dma_count | (1UL << 18) | (1UL << 21) | (1UL << 31) | DMA_CHANNEL_SRC_INC ; // 16 bit transfer , address increment, interrupt
dreschpe 14:ea3206e8e3bd 1019 LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | (spi_port ? DMA_DEST_SSP1_TX : DMA_DEST_SSP0_TX);
dreschpe 14:ea3206e8e3bd 1020 LPC_GPDMA->DMACSoftSReq = 0x1;
dreschpe 14:ea3206e8e3bd 1021 do {
dreschpe 14:ea3206e8e3bd 1022 } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running
dreschpe 14:ea3206e8e3bd 1023 dma_off = dma_off + dma_count;
dreschpe 14:ea3206e8e3bd 1024 } while (pixel > 0);
dreschpe 14:ea3206e8e3bd 1025
dreschpe 14:ea3206e8e3bd 1026 free ((uint16_t *) buffer);
dreschpe 14:ea3206e8e3bd 1027
dreschpe 14:ea3206e8e3bd 1028 if (spi_port == 0) { // TFT on SSP0
dreschpe 14:ea3206e8e3bd 1029 do {
dreschpe 14:ea3206e8e3bd 1030 } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI0 not idle
dreschpe 14:ea3206e8e3bd 1031 /* disable SSP0 for DMA. */
dreschpe 14:ea3206e8e3bd 1032 LPC_SSP0->DMACR = 0x0;
dreschpe 14:ea3206e8e3bd 1033 } else { // TFT on SSP1
dreschpe 14:ea3206e8e3bd 1034 do {
dreschpe 14:ea3206e8e3bd 1035 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI1 not idle
dreschpe 14:ea3206e8e3bd 1036 /* disable SSP1 for DMA. */
dreschpe 14:ea3206e8e3bd 1037 LPC_SSP1->DMACR = 0x0;
dreschpe 14:ea3206e8e3bd 1038 }
dreschpe 14:ea3206e8e3bd 1039
dreschpe 14:ea3206e8e3bd 1040 #else // no dma
dreschpe 14:ea3206e8e3bd 1041 _cs = 0;
dreschpe 14:ea3206e8e3bd 1042 #if defined NO_MBED_LIB
dreschpe 14:ea3206e8e3bd 1043 if (spi_port == 0) { // TFT on SSP0
dreschpe 14:ea3206e8e3bd 1044 LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit
dreschpe 14:ea3206e8e3bd 1045 LPC_SSP0->DR = 0x72; // start Data
dreschpe 14:ea3206e8e3bd 1046 LPC_SSP0->CR0 |= 0x08UL; // set to 16 bit
dreschpe 14:ea3206e8e3bd 1047 } else { // TFT on SSP1
dreschpe 14:ea3206e8e3bd 1048 LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit
dreschpe 14:ea3206e8e3bd 1049 LPC_SSP1->DR = 0x72; // start Data
dreschpe 14:ea3206e8e3bd 1050 LPC_SSP1->CR0 |= 0x08UL; // set to 16 bit
dreschpe 14:ea3206e8e3bd 1051 }
dreschpe 14:ea3206e8e3bd 1052 #else // mbed lib
dreschpe 14:ea3206e8e3bd 1053 #if defined TARGET_KL25Z // 8 Bit SPI
dreschpe 14:ea3206e8e3bd 1054 _spi.write(SPI_START | SPI_WR | SPI_DATA); // Write : RS = 1, RW = 0
dreschpe 14:ea3206e8e3bd 1055 #else // 16 bit SPI
dreschpe 14:ea3206e8e3bd 1056 _spi.format(8,3); // 8 bit Mode 3
dreschpe 14:ea3206e8e3bd 1057 _spi.write(SPI_START | SPI_WR | SPI_DATA); // Write : RS = 1, RW = 0
dreschpe 14:ea3206e8e3bd 1058 _spi.format(16,3); // switch back to 16 bit Mode 3
dreschpe 14:ea3206e8e3bd 1059 #endif
dreschpe 14:ea3206e8e3bd 1060 #endif
dreschpe 14:ea3206e8e3bd 1061
dreschpe 14:ea3206e8e3bd 1062 zeichen = &font[((c -32) * offset) + 4]; // start of char bitmap
dreschpe 14:ea3206e8e3bd 1063 w = zeichen[0]; // width of actual char
dreschpe 14:ea3206e8e3bd 1064 for (j=0; j<vert; j++) { // vert line
dreschpe 14:ea3206e8e3bd 1065 for (i=0; i<hor; i++) { // horz line
dreschpe 14:ea3206e8e3bd 1066 z = zeichen[bpl * i + ((j & 0xF8) >> 3)+1];
dreschpe 14:ea3206e8e3bd 1067 b = 1 << (j & 0x07);
dreschpe 14:ea3206e8e3bd 1068 if (( z & b ) == 0x00) {
dreschpe 14:ea3206e8e3bd 1069 #if defined TARGET_KL25Z // 8 Bit SPI
dreschpe 14:ea3206e8e3bd 1070 _spi.write(_background >> 8);
dreschpe 14:ea3206e8e3bd 1071 _spi.write(_background & 0xff);
dreschpe 14:ea3206e8e3bd 1072 #else
dreschpe 14:ea3206e8e3bd 1073 _spi.write(_background);
dreschpe 14:ea3206e8e3bd 1074 #endif
dreschpe 14:ea3206e8e3bd 1075 } else {
dreschpe 14:ea3206e8e3bd 1076 #if defined TARGET_KL25Z // 8 Bit SPI
dreschpe 14:ea3206e8e3bd 1077 _spi.write(_foreground >> 8);
dreschpe 14:ea3206e8e3bd 1078 _spi.write(_foreground & 0xff);
dreschpe 14:ea3206e8e3bd 1079 #else
dreschpe 14:ea3206e8e3bd 1080 _spi.write(_foreground);
dreschpe 14:ea3206e8e3bd 1081 #endif
dreschpe 14:ea3206e8e3bd 1082 }
dreschpe 14:ea3206e8e3bd 1083 }
dreschpe 14:ea3206e8e3bd 1084 }
dreschpe 14:ea3206e8e3bd 1085 #endif // no DMA
dreschpe 8:65a4de035c3c 1086 _cs = 1;
dreschpe 8:65a4de035c3c 1087 WindowMax();
dreschpe 8:65a4de035c3c 1088 if ((w + 2) < hor) { // x offset to next char
dreschpe 8:65a4de035c3c 1089 char_x += w + 2;
dreschpe 8:65a4de035c3c 1090 } else char_x += hor;
dreschpe 8:65a4de035c3c 1091 }
dreschpe 8:65a4de035c3c 1092
dreschpe 8:65a4de035c3c 1093
dreschpe 8:65a4de035c3c 1094 void SPI_TFT::set_font(unsigned char* f)
dreschpe 8:65a4de035c3c 1095 {
dreschpe 8:65a4de035c3c 1096 font = f;
dreschpe 8:65a4de035c3c 1097 }
dreschpe 8:65a4de035c3c 1098
dreschpe 8:65a4de035c3c 1099
dreschpe 8:65a4de035c3c 1100 void SPI_TFT::Bitmap(unsigned int x, unsigned int y, unsigned int w, unsigned int h,unsigned char *bitmap)
dreschpe 8:65a4de035c3c 1101 {
dreschpe 8:65a4de035c3c 1102 unsigned int j;
dreschpe 8:65a4de035c3c 1103 int padd;
dreschpe 16:2efcbb2814fa 1104
dreschpe 16:2efcbb2814fa 1105 unsigned short *bitmap_ptr = (unsigned short *)bitmap;
dreschpe 14:ea3206e8e3bd 1106 #if defined TARGET_KL25Z // 8 Bit SPI
dreschpe 16:2efcbb2814fa 1107 unsigned short pix_temp;
dreschpe 14:ea3206e8e3bd 1108 #endif
dreschpe 16:2efcbb2814fa 1109
dreschpe 8:65a4de035c3c 1110 // the lines are padded to multiple of 4 bytes in a bitmap
dreschpe 8:65a4de035c3c 1111 padd = -1;
dreschpe 8:65a4de035c3c 1112 do {
dreschpe 8:65a4de035c3c 1113 padd ++;
dreschpe 8:65a4de035c3c 1114 } while (2*(w + padd)%4 != 0);
dreschpe 8:65a4de035c3c 1115 window(x, y, w, h);
dreschpe 8:65a4de035c3c 1116 wr_cmd(0x22);
dreschpe 8:65a4de035c3c 1117 _cs = 0;
dreschpe 13:2c91cb947161 1118 #if defined NO_MBED_LIB
dreschpe 8:65a4de035c3c 1119 if (spi_port == 0) { // TFT on SSP0
dreschpe 16:2efcbb2814fa 1120 #if defined USE_DMA
dreschpe 8:65a4de035c3c 1121 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR; // we send to SSP0
dreschpe 8:65a4de035c3c 1122 /* Enable SSP0 for DMA. */
dreschpe 8:65a4de035c3c 1123 LPC_SSP0->DMACR = 0x2;
dreschpe 16:2efcbb2814fa 1124 #endif
dreschpe 16:2efcbb2814fa 1125 LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit
dreschpe 16:2efcbb2814fa 1126 LPC_SSP0->DR = 0x72; // start Data
dreschpe 16:2efcbb2814fa 1127 LPC_SSP0->CR0 |= 0x08UL; // set to 16 bit
dreschpe 8:65a4de035c3c 1128
dreschpe 8:65a4de035c3c 1129 } else {
dreschpe 16:2efcbb2814fa 1130 #if defined USE_DMA
dreschpe 8:65a4de035c3c 1131 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP1->DR; // we send to SSP1
dreschpe 8:65a4de035c3c 1132 /* Enable SSP1 for DMA. */
dreschpe 13:2c91cb947161 1133 LPC_SSP1->DMACR = 0x2;
dreschpe 16:2efcbb2814fa 1134 #endif
dreschpe 16:2efcbb2814fa 1135 LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit
dreschpe 16:2efcbb2814fa 1136 LPC_SSP1->DR = 0x72; // start Data command
dreschpe 16:2efcbb2814fa 1137 LPC_SSP1->CR0 |= 0x08UL; // set to 16 bit
dreschpe 8:65a4de035c3c 1138 }
dreschpe 8:65a4de035c3c 1139
dreschpe 8:65a4de035c3c 1140 bitmap_ptr += ((h - 1)* (w + padd));
dreschpe 16:2efcbb2814fa 1141 #if defined USE_DMA
dreschpe 16:2efcbb2814fa 1142 for (j = 0; j < h; j++) { //Lines
dreschpe 16:2efcbb2814fa 1143 LPC_GPDMA->DMACIntTCClear = 0x1;
dreschpe 16:2efcbb2814fa 1144 LPC_GPDMA->DMACIntErrClr = 0x1;
dreschpe 16:2efcbb2814fa 1145 LPC_GPDMACH0->DMACCSrcAddr = (uint32_t)bitmap_ptr;
dreschpe 16:2efcbb2814fa 1146 LPC_GPDMACH0->DMACCControl = w | (1UL << 18) | (1UL << 21) | (1UL << 31) | DMA_CHANNEL_SRC_INC ; // 16 bit transfer , address increment, interrupt
dreschpe 16:2efcbb2814fa 1147 LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | (spi_port ? DMA_DEST_SSP1_TX : DMA_DEST_SSP0_TX);
dreschpe 16:2efcbb2814fa 1148 LPC_GPDMA->DMACSoftSReq = 0x1;
dreschpe 16:2efcbb2814fa 1149 do {
dreschpe 16:2efcbb2814fa 1150 } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running
dreschpe 8:65a4de035c3c 1151
dreschpe 16:2efcbb2814fa 1152 bitmap_ptr -= w;
dreschpe 16:2efcbb2814fa 1153 bitmap_ptr -= padd;
dreschpe 8:65a4de035c3c 1154 }
dreschpe 16:2efcbb2814fa 1155 #else
dreschpe 16:2efcbb2814fa 1156 unsigned int i;
dreschpe 16:2efcbb2814fa 1157 for (j = 0; j < h; j++) { //Lines
dreschpe 16:2efcbb2814fa 1158 for (i = 0; i < w; i++) { // copy pixel data to TFT
dreschpe 16:2efcbb2814fa 1159 _spi.write(*bitmap_ptr); // one line
dreschpe 16:2efcbb2814fa 1160 bitmap_ptr++;
dreschpe 16:2efcbb2814fa 1161 }
dreschpe 16:2efcbb2814fa 1162 bitmap_ptr -= 2*w;
dreschpe 16:2efcbb2814fa 1163 bitmap_ptr -= padd;
dreschpe 16:2efcbb2814fa 1164 }
dreschpe 16:2efcbb2814fa 1165 #endif
dreschpe 8:65a4de035c3c 1166 if (spi_port == 0) { // TFT on SSP0
dreschpe 8:65a4de035c3c 1167 do {
dreschpe 8:65a4de035c3c 1168 } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI FIFO not empty
dreschpe 8:65a4de035c3c 1169 } else {
dreschpe 8:65a4de035c3c 1170 do {
dreschpe 8:65a4de035c3c 1171 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI FIFO not empty
dreschpe 8:65a4de035c3c 1172 }
dreschpe 9:a63fd1ad41b0 1173 #else // use mbed lib
dreschpe 16:2efcbb2814fa 1174 #if defined TARGET_KL25Z // 8 Bit SPI
dreschpe 16:2efcbb2814fa 1175 _spi.write(SPI_START | SPI_WR | SPI_DATA); // Write : RS = 1, RW = 0
dreschpe 16:2efcbb2814fa 1176 #else
dreschpe 16:2efcbb2814fa 1177 _spi.format(8,3); // 8 bit Mode 3
dreschpe 16:2efcbb2814fa 1178 _spi.write(SPI_START | SPI_WR | SPI_DATA); // Write : RS = 1, RW = 0
dreschpe 16:2efcbb2814fa 1179 _spi.format(16,3); // switch to 16 bit Mode 3
dreschpe 16:2efcbb2814fa 1180 #endif
dreschpe 16:2efcbb2814fa 1181 bitmap_ptr += ((h - 1)* (w + padd));
dreschpe 9:a63fd1ad41b0 1182 unsigned int i;
dreschpe 9:a63fd1ad41b0 1183 for (j = 0; j < h; j++) { //Lines
dreschpe 9:a63fd1ad41b0 1184 for (i = 0; i < w; i++) { // copy pixel data to TFT
dreschpe 16:2efcbb2814fa 1185 #if defined TARGET_KL25Z // 8 Bit SPI
dreschpe 16:2efcbb2814fa 1186 pix_temp = *bitmap_ptr;
dreschpe 16:2efcbb2814fa 1187 _spi.write(pix_temp >> 8);
dreschpe 16:2efcbb2814fa 1188 _spi.write(pix_temp);
dreschpe 16:2efcbb2814fa 1189 bitmap_ptr++;
dreschpe 16:2efcbb2814fa 1190 #else
dreschpe 16:2efcbb2814fa 1191 _spi.write(*bitmap_ptr); // one line
dreschpe 16:2efcbb2814fa 1192 bitmap_ptr++;
dreschpe 16:2efcbb2814fa 1193 #endif
dreschpe 9:a63fd1ad41b0 1194 }
dreschpe 9:a63fd1ad41b0 1195 bitmap_ptr -= 2*w;
dreschpe 9:a63fd1ad41b0 1196 bitmap_ptr -= padd;
dreschpe 16:2efcbb2814fa 1197 }
dreschpe 16:2efcbb2814fa 1198 #endif // USE MBED LIB
dreschpe 8:65a4de035c3c 1199 _cs = 1;
dreschpe 8:65a4de035c3c 1200 WindowMax();
dreschpe 8:65a4de035c3c 1201 }
dreschpe 8:65a4de035c3c 1202
dreschpe 8:65a4de035c3c 1203
dreschpe 13:2c91cb947161 1204 // local filesystem is not implemented in kinetis board
dreschpe 13:2c91cb947161 1205 #if defined TARGET_LPC1768 || defined TARGET_LPC11U24
dreschpe 13:2c91cb947161 1206
dreschpe 13:2c91cb947161 1207
dreschpe 8:65a4de035c3c 1208 int SPI_TFT::BMP_16(unsigned int x, unsigned int y, const char *Name_BMP)
dreschpe 8:65a4de035c3c 1209 {
dreschpe 8:65a4de035c3c 1210
dreschpe 8:65a4de035c3c 1211 #define OffsetPixelWidth 18
dreschpe 8:65a4de035c3c 1212 #define OffsetPixelHeigh 22
dreschpe 8:65a4de035c3c 1213 #define OffsetFileSize 34
dreschpe 8:65a4de035c3c 1214 #define OffsetPixData 10
dreschpe 8:65a4de035c3c 1215 #define OffsetBPP 28
dreschpe 8:65a4de035c3c 1216
dreschpe 8:65a4de035c3c 1217 char filename[50];
dreschpe 8:65a4de035c3c 1218 unsigned char BMP_Header[54];
dreschpe 8:65a4de035c3c 1219 unsigned short BPP_t;
dreschpe 8:65a4de035c3c 1220 unsigned int PixelWidth,PixelHeigh,start_data;
dreschpe 8:65a4de035c3c 1221 unsigned int i,off;
dreschpe 8:65a4de035c3c 1222 int padd,j;
dreschpe 8:65a4de035c3c 1223 unsigned short *line;
dreschpe 8:65a4de035c3c 1224
dreschpe 8:65a4de035c3c 1225 // get the filename
dreschpe 8:65a4de035c3c 1226 LocalFileSystem local("local");
dreschpe 8:65a4de035c3c 1227 sprintf(&filename[0],"/local/");
dreschpe 8:65a4de035c3c 1228 i=7;
dreschpe 8:65a4de035c3c 1229 while (*Name_BMP!='\0') {
dreschpe 8:65a4de035c3c 1230 filename[i++]=*Name_BMP++;
dreschpe 8:65a4de035c3c 1231 }
dreschpe 8:65a4de035c3c 1232
dreschpe 8:65a4de035c3c 1233 fprintf(stderr, "filename : %s \n\r",filename);
dreschpe 8:65a4de035c3c 1234
dreschpe 8:65a4de035c3c 1235 FILE *Image = fopen((const char *)&filename[0], "rb"); // open the bmp file
dreschpe 8:65a4de035c3c 1236 if (!Image) {
dreschpe 8:65a4de035c3c 1237 return(0); // error file not found !
dreschpe 8:65a4de035c3c 1238 }
dreschpe 8:65a4de035c3c 1239
dreschpe 8:65a4de035c3c 1240 fread(&BMP_Header[0],1,54,Image); // get the BMP Header
dreschpe 8:65a4de035c3c 1241
dreschpe 8:65a4de035c3c 1242 if (BMP_Header[0] != 0x42 || BMP_Header[1] != 0x4D) { // check magic byte
dreschpe 8:65a4de035c3c 1243 fclose(Image);
dreschpe 8:65a4de035c3c 1244 return(-1); // error no BMP file
dreschpe 8:65a4de035c3c 1245 }
dreschpe 8:65a4de035c3c 1246
dreschpe 8:65a4de035c3c 1247 BPP_t = BMP_Header[OffsetBPP] + (BMP_Header[OffsetBPP + 1] << 8);
dreschpe 8:65a4de035c3c 1248 if (BPP_t != 0x0010) {
dreschpe 8:65a4de035c3c 1249 fclose(Image);
dreschpe 8:65a4de035c3c 1250 return(-2); // error no 16 bit BMP
dreschpe 8:65a4de035c3c 1251 }
dreschpe 8:65a4de035c3c 1252
dreschpe 8:65a4de035c3c 1253 PixelHeigh = BMP_Header[OffsetPixelHeigh] + (BMP_Header[OffsetPixelHeigh + 1] << 8) + (BMP_Header[OffsetPixelHeigh + 2] << 16) + (BMP_Header[OffsetPixelHeigh + 3] << 24);
dreschpe 8:65a4de035c3c 1254 PixelWidth = BMP_Header[OffsetPixelWidth] + (BMP_Header[OffsetPixelWidth + 1] << 8) + (BMP_Header[OffsetPixelWidth + 2] << 16) + (BMP_Header[OffsetPixelWidth + 3] << 24);
dreschpe 8:65a4de035c3c 1255 if (PixelHeigh > height() + y || PixelWidth > width() + x) {
dreschpe 8:65a4de035c3c 1256 fclose(Image);
dreschpe 8:65a4de035c3c 1257 return(-3); // to big
dreschpe 8:65a4de035c3c 1258 }
dreschpe 8:65a4de035c3c 1259
dreschpe 8:65a4de035c3c 1260 start_data = BMP_Header[OffsetPixData] + (BMP_Header[OffsetPixData + 1] << 8) + (BMP_Header[OffsetPixData + 2] << 16) + (BMP_Header[OffsetPixData + 3] << 24);
dreschpe 8:65a4de035c3c 1261
dreschpe 8:65a4de035c3c 1262 line = (unsigned short *) malloc (2 * PixelWidth); // we need a buffer for a line
dreschpe 8:65a4de035c3c 1263 if (line == NULL) {
dreschpe 8:65a4de035c3c 1264 return(-4); // error no memory
dreschpe 8:65a4de035c3c 1265 }
dreschpe 8:65a4de035c3c 1266
dreschpe 8:65a4de035c3c 1267 // the bmp lines are padded to multiple of 4 bytes
dreschpe 8:65a4de035c3c 1268 padd = -1;
dreschpe 8:65a4de035c3c 1269 do {
dreschpe 8:65a4de035c3c 1270 padd ++;
dreschpe 8:65a4de035c3c 1271 } while ((PixelWidth * 2 + padd)%4 != 0);
dreschpe 8:65a4de035c3c 1272
dreschpe 8:65a4de035c3c 1273
dreschpe 8:65a4de035c3c 1274 //fseek(Image, 70 ,SEEK_SET);
dreschpe 8:65a4de035c3c 1275 window(x, y,PixelWidth ,PixelHeigh);
dreschpe 8:65a4de035c3c 1276 wr_cmd(0x22);
dreschpe 8:65a4de035c3c 1277 _cs = 0;
dreschpe 13:2c91cb947161 1278 #if defined NO_MBED_LIB
dreschpe 8:65a4de035c3c 1279 if (spi_port == 0) { // TFT on SSP0
dreschpe 8:65a4de035c3c 1280 #if defined USE_DMA
dreschpe 8:65a4de035c3c 1281 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP0->DR; // we send to SSP0
dreschpe 8:65a4de035c3c 1282 /* Enable SSP0 for DMA. */
dreschpe 8:65a4de035c3c 1283 LPC_SSP0->DMACR = 0x2;
dreschpe 8:65a4de035c3c 1284 #endif
dreschpe 8:65a4de035c3c 1285 LPC_SSP0->CR0 &= ~(0x08UL); // set to 8 bit
dreschpe 8:65a4de035c3c 1286 LPC_SSP0->DR = 0x72; // start Data
dreschpe 8:65a4de035c3c 1287 LPC_SSP0->CR0 |= 0x08UL; // set to 16 bit
dreschpe 8:65a4de035c3c 1288
dreschpe 8:65a4de035c3c 1289 } else {
dreschpe 13:2c91cb947161 1290 #if defined USE_DMA
dreschpe 8:65a4de035c3c 1291 LPC_GPDMACH0->DMACCDestAddr = (uint32_t)&LPC_SSP1->DR; // we send to SSP1
dreschpe 8:65a4de035c3c 1292 /* Enable SSP1 for DMA. */
dreschpe 8:65a4de035c3c 1293 LPC_SSP1->DMACR = 0x2;
dreschpe 8:65a4de035c3c 1294 #endif
dreschpe 8:65a4de035c3c 1295 LPC_SSP1->CR0 &= ~(0x08UL); // set to 8 bit
dreschpe 8:65a4de035c3c 1296 LPC_SSP1->DR = 0x72; // start Data
dreschpe 13:2c91cb947161 1297 LPC_SSP1->CR0 |= 0x08UL; // set to 16 bit
dreschpe 8:65a4de035c3c 1298 }
dreschpe 8:65a4de035c3c 1299 for (j = PixelHeigh - 1; j >= 0; j--) { //Lines bottom up
dreschpe 8:65a4de035c3c 1300 off = j * (PixelWidth * 2 + padd) + start_data; // start of line
dreschpe 8:65a4de035c3c 1301 fseek(Image, off ,SEEK_SET);
dreschpe 8:65a4de035c3c 1302 fread(line,1,PixelWidth * 2,Image); // read a line - slow !
dreschpe 8:65a4de035c3c 1303 #if defined USE_DMA
dreschpe 8:65a4de035c3c 1304 LPC_GPDMA->DMACIntTCClear = 0x1;
dreschpe 8:65a4de035c3c 1305 LPC_GPDMA->DMACIntErrClr = 0x1;
dreschpe 8:65a4de035c3c 1306 LPC_GPDMACH0->DMACCSrcAddr = (uint32_t)line;
dreschpe 8:65a4de035c3c 1307 LPC_GPDMACH0->DMACCControl = PixelWidth | (1UL << 18) | (1UL << 21) | (1UL << 31) | DMA_CHANNEL_SRC_INC ; // 16 bit transfer , address increment, interrupt
dreschpe 8:65a4de035c3c 1308 LPC_GPDMACH0->DMACCConfig = DMA_CHANNEL_ENABLE | DMA_TRANSFER_TYPE_M2P | (spi_port ? DMA_DEST_SSP1_TX : DMA_DEST_SSP0_TX);
dreschpe 8:65a4de035c3c 1309 LPC_GPDMA->DMACSoftSReq = 0x1;
dreschpe 8:65a4de035c3c 1310 do {
dreschpe 8:65a4de035c3c 1311 } while ((LPC_GPDMA->DMACRawIntTCStat & 0x01) == 0); // DMA is running
dreschpe 8:65a4de035c3c 1312 #else
dreschpe 13:2c91cb947161 1313 for (i = 0; i < PixelWidth; i++) { // copy pixel data to TFT
dreschpe 8:65a4de035c3c 1314 _spi.write(line[i]); // one 16 bit pixel
dreschpe 13:2c91cb947161 1315 }
dreschpe 13:2c91cb947161 1316 #endif
dreschpe 8:65a4de035c3c 1317 }
dreschpe 8:65a4de035c3c 1318 if (spi_port == 0) { // TFT on SSP0
dreschpe 8:65a4de035c3c 1319 do {
dreschpe 8:65a4de035c3c 1320 } while ((LPC_SSP0->SR & 0x10) == 0x10); // SPI FIFO not empty
dreschpe 8:65a4de035c3c 1321 } else {
dreschpe 8:65a4de035c3c 1322 do {
dreschpe 8:65a4de035c3c 1323 } while ((LPC_SSP1->SR & 0x10) == 0x10); // SPI FIFO not empty
dreschpe 8:65a4de035c3c 1324 }
dreschpe 13:2c91cb947161 1325
dreschpe 9:a63fd1ad41b0 1326 #else // use mbed lib
dreschpe 9:a63fd1ad41b0 1327 _spi.format(8,3); // 8 bit Mode 3
dreschpe 9:a63fd1ad41b0 1328 _spi.write(SPI_START | SPI_WR | SPI_DATA); // Write : RS = 1, RW = 0
dreschpe 9:a63fd1ad41b0 1329 _spi.format(16,3); // switch to 16 bit Mode 3
dreschpe 9:a63fd1ad41b0 1330 for (j = PixelHeigh - 1; j >= 0; j--) { //Lines bottom up
dreschpe 9:a63fd1ad41b0 1331 off = j * (PixelWidth * 2 + padd) + start_data; // start of line
dreschpe 9:a63fd1ad41b0 1332 fseek(Image, off ,SEEK_SET);
dreschpe 9:a63fd1ad41b0 1333 fread(line,1,PixelWidth * 2,Image); // read a line - slow !
dreschpe 9:a63fd1ad41b0 1334 for (i = 0; i < PixelWidth; i++) { // copy pixel data to TFT
dreschpe 9:a63fd1ad41b0 1335 _spi.write(line[i]); // one 16 bit pixel
dreschpe 13:2c91cb947161 1336 }
dreschpe 13:2c91cb947161 1337 }
dreschpe 13:2c91cb947161 1338 #endif
dreschpe 8:65a4de035c3c 1339 _cs = 1;
dreschpe 8:65a4de035c3c 1340 free (line);
dreschpe 8:65a4de035c3c 1341 fclose(Image);
dreschpe 8:65a4de035c3c 1342 WindowMax();
dreschpe 8:65a4de035c3c 1343 return(1);
dreschpe 13:2c91cb947161 1344 }
dreschpe 13:2c91cb947161 1345
dreschpe 13:2c91cb947161 1346 #endif