Adapted from Peter Dresche's original for Waveshare 2.8inch TFT Touch Shield Board and Mbed 6. RGB order reversed by changing reg 16 commands, spi write code adjusted as there is no reset pin but there is data command pin. Wait commands changed for new thread_sleep style, Stream class explicitly included. Library to control a QVGA TFT connected to SPI. You can use printf to print text The lib can handle different fonts, draw lines, circles, rect and bmp

Committer:
jhd25
Date:
Wed Jun 17 16:13:47 2020 +0100
Revision:
20:275bf616ceb7
Parent:
18:52cbeede86f0
Child:
22:4a0f306be8ef
First fully working version for Waveshare TFT board
170620

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