Modified to work with two displays

Dependents:   touch2 default CANary_9341_test CANary_merge

Fork of SPI_TFT by Peter Drescher

Committer:
TickTock
Date:
Sun Feb 03 15:22:34 2013 +0000
Revision:
8:a71243b666f9
Parent:
SPI_TFT.cpp@7:e753bb62eeb9
Child:
12:ff509eb02e37
Modified to work with two displays

Who changed what in which revision?

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