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 22:01:37 2020 +0100
Revision:
22:4a0f306be8ef
Parent:
20:275bf616ceb7
Child:
23:469bf5f3c8ac
Now with mutexes !

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