/ MCUME_esp32 / espboot / main / ili9341_t3dma.cpp
ili9341_t3dma.cpp
  1  /*
  2    ILI9341 SPI driver inspired from the Teensy version of Frank Bösing, 2017
  3  */
  4  
  5  #include "freertos/FreeRTOS.h"
  6  #include "freertos/task.h"
  7  
  8  #include "esp_system.h"
  9  #include "driver/spi_master.h"
 10  #include "soc/gpio_struct.h"
 11  #include "driver/gpio.h"
 12  
 13  #include <string.h>
 14  
 15  #include "ili9341_t3dma.h"
 16  #include "font8x8.h"
 17  
 18  
 19  
 20  static spi_device_handle_t lcdspi;
 21  static spi_transaction_t trans[MAX_SPI_TRANS];
 22  
 23  static uint16_t *blocks[NR_OF_BLOCK];
 24  static uint8_t _rst, _cs, _dc;
 25  static uint8_t _miso, _mosi, _clk;
 26  static uint8_t _touch_irq, _touch_cs;  
 27  
 28  //DRAM_ATTR static uint16_t block0[320*LINES_PER_BLOCK];
 29  //DRAM_ATTR static uint16_t block1[320*LINES_PER_BLOCK];
 30  
 31  static const lcd_init_cmd_t ili_init_cmds[]={
 32    {0xEF, {0x03, 0x80, 0x02}, 3},
 33    {0xCF, {0x00, 0XC1, 0X30}, 3},
 34    {0xED, {0x64, 0x03, 0X12, 0X81},  4},
 35    {0xE8, {0x85, 0x00, 0x78}, 3},
 36    {0xCB, {0x39, 0x2C, 0x00, 0x34, 0x02}, 5},
 37    {0xF7, {0x20}, 1},
 38    {0xEA, {0x00, 0x00}, 2},
 39    {ILI9341_PWCTR1, {0x23}, 1}, // Power control
 40    {ILI9341_PWCTR2, {0x10}, 1}, // Power control
 41    {ILI9341_VMCTR1, {0x3e, 0x28}, 2}, // VCM control
 42    {ILI9341_VMCTR2, {0x86}, 1}, // VCM control2
 43    {ILI9341_MADCTL, {0x48}, 1}, // Memory Access Control
 44    {ILI9341_PIXFMT, {0x55}, 1},
 45    {ILI9341_FRMCTR1, {0x00, 0x18}, 2},
 46    {ILI9341_DFUNCTR, {0x08, 0x82, 0x27}, 3}, // Display Function Control
 47    {0xF2, {0x00}, 1}, // Gamma Function Disable
 48    {ILI9341_GAMMASET, {0x01}, 1}, // Gamma curve selected
 49    {ILI9341_GMCTRP1, {0x0F, 0x31, 0x2B, 0x0C, 0x0E, 0x08,
 50    0x4E, 0xF1, 0x37, 0x07, 0x10, 0x03, 0x0E, 0x09, 0x00}, 15}, // Set Gamma
 51    {ILI9341_GMCTRN1, {0x00, 0x0E, 0x14, 0x03, 0x11, 0x07,
 52    0x31, 0xC1, 0x48, 0x08, 0x0F, 0x0C, 0x31, 0x36, 0x0F}, 15}, // Set Gamma
 53  //  3, 0xb1, 0x00, 0x1f, // FrameRate Control 61Hz
 54    {0xb1, {0x00, 0x10}, 2}, // FrameRate Control 119Hz
 55    {ILI9341_MADCTL, {MADCTL_MX | MADCTL_MY | MADCTL_MV | MADCTL_BGR}, 1},
 56  
 57    /* Sleep out */
 58    {ILI9341_SLPOUT, {0}, 0x80},
 59    /* Display on */
 60    {ILI9341_DISPON, {0}, 0x80},
 61    
 62  
 63    // Area width, hight
 64    {ILI9341_CASET, {0, 0, (ILI9341_TFTREALWIDTH)>>8, (ILI9341_TFTREALWIDTH)&0xff}, 4},
 65    {ILI9341_PASET, {0, 0, (ILI9341_TFTREALHEIGHT)>>8, (ILI9341_TFTREALHEIGHT)&0xff}, 4},
 66    
 67    {0, {0}, 0xff},
 68  };
 69  
 70  static void lcd_cmd(spi_device_handle_t spi, const uint8_t cmd)
 71  {
 72    esp_err_t ret;
 73    spi_transaction_t t;
 74    memset(&t, 0, sizeof(t));       //Zero out the transaction
 75    t.length=8;                     //Command is 8 bits
 76    t.tx_buffer=&cmd;               //The data is the cmd itself
 77    t.user=(void*)0;                //D/C needs to be set to 0
 78    t.flags=0;    
 79    ret=spi_device_polling_transmit(spi, &t);  //Transmit!
 80    assert(ret==ESP_OK);            //Should have had no issues.
 81  }
 82  
 83  
 84  static void lcd_data(spi_device_handle_t spi, const uint8_t *data, int len)
 85  {
 86    esp_err_t ret;
 87    spi_transaction_t t;
 88    if (len==0) return;             //no need to send anything
 89    memset(&t, 0, sizeof(t));       //Zero out the transaction
 90    t.length=len*8;                 //Len is in bytes, transaction length is in bits.
 91    t.tx_buffer=data;               //Data
 92    t.user=(void*)1;                //D/C needs to be set to 1
 93    t.flags=0;
 94    ret=spi_device_polling_transmit(spi, &t);  //Transmit!
 95    assert(ret==ESP_OK);            //Should have had no issues.
 96  }
 97  
 98  //This function is called (in irq context!) just before a transmission starts. It will
 99  //set the D/C line to the value indicated in the user field.
100  static void lcd_spi_pre_transfer_callback(spi_transaction_t *t)
101  {
102    int dc=(int)t->user;
103    gpio_set_level((gpio_num_t)_dc, dc);
104  }
105  
106  
107  //Initialize the display
108  static void lcd_init(spi_device_handle_t spi)
109  {
110    //Initialize non-SPI GPIOs
111    gpio_set_direction((gpio_num_t)_dc, GPIO_MODE_OUTPUT);
112  
113    printf("LCD ILI9341 initialization.\n");
114    //Send all the commands
115  
116  
117    //memcpy(ili_init_cmds, ili_init_cmdos, sizeof(ili_init_cmdos));
118    int cmd=0;
119    while (ili_init_cmds[cmd].databytes!=0xff) {
120        lcd_cmd(spi, ili_init_cmds[cmd].cmd);
121        lcd_data(spi, ili_init_cmds[cmd].data, ili_init_cmds[cmd].databytes&0x1F);
122        if (ili_init_cmds[cmd].databytes&0x80) {
123            vTaskDelay(100 / portTICK_RATE_MS);
124        }
125        cmd++;
126    }
127    
128  
129    
130    //Allocate memory block buffers and DMA transactions
131    printf("Allocate video mem and DMA transactions\n");
132    
133    int i=0;    
134    trans[i].tx_data[0]=ILI9341_RAMWR;
135    trans[i].length=8;
136    trans[i].user=(void*)0;
137    trans[i++].flags=SPI_TRANS_USE_TXDATA; 
138  
139    //blocks[0]= &block0[0];
140    //blocks[1]= &block1[0];
141       
142    int remaininglines=ILI9341_TFTREALHEIGHT;
143    for (int j=0; j<NR_OF_BLOCK; j++) 
144    {      
145      int lines_per_block = LINES_PER_BLOCK;
146      if ((remaininglines - LINES_PER_BLOCK) < 0) {
147        lines_per_block = remaininglines;
148      }
149      remaininglines -= LINES_PER_BLOCK;        
150      /*if (j > 1)*/ blocks[j]= (uint16_t*)heap_caps_malloc(ILI9341_TFTREALWIDTH*lines_per_block*sizeof(uint16_t), MALLOC_CAP_DMA);
151      assert(blocks[j]!=NULL);
152  
153      trans[i].tx_buffer=blocks[j];
154      trans[i].length=ILI9341_TFTREALWIDTH*2*8*lines_per_block;
155      trans[i].user=(void*)1;
156      trans[i++].flags=0; //undo SPI_TRANS_USE_TXDATA flag
157        
158        uint16_t color;
159        switch (j) {
160          case 0:
161            color=0xf000;
162            break;
163          case 1:
164            color=0x0f00;
165            break;
166          case 2:
167            color=0x00f0;
168            break;
169          case 3:
170          default:         
171            color=0x000f;
172            break;         
173        }
174        uint16_t * fb = blocks[j];
175        for (int y=0;y<lines_per_block;y++)
176          for (int x=0;x<ILI9341_TFTREALWIDTH;x++)
177            *fb++=color;
178    }    
179    
180  }
181  
182  
183  
184  static void send_blocks(spi_device_handle_t spi)
185  {
186    esp_err_t ret;
187    //Queue all transactions.
188    for (int j=0; j<(NR_OF_BLOCK+1); j++) {
189        ret=spi_device_queue_trans(spi, &trans[j], portMAX_DELAY);
190        assert(ret==ESP_OK);
191    }
192  }
193  
194  
195  static void send_blocks_finish(spi_device_handle_t spi)
196  {
197    spi_transaction_t *rtrans;
198    esp_err_t ret;
199    for (int j=0; j<(NR_OF_BLOCK+1); j++) {
200        ret=spi_device_get_trans_result(spi, &rtrans, portMAX_DELAY);
201        assert(ret==ESP_OK);
202    }
203  }
204  
205  
206  ILI9341_t3DMA::ILI9341_t3DMA(uint8_t cs, uint8_t dc, uint8_t rst, uint8_t mosi, uint8_t clk, uint8_t miso,  uint8_t touch_cs,  uint8_t touch_irq)
207  {
208    _cs   = cs;
209    _dc   = dc;
210    _rst  = rst;
211    _mosi = mosi;
212    _clk  = clk;
213    _miso = miso;
214    _touch_irq = touch_irq;
215    _touch_cs = touch_cs;
216  }
217  
218  
219  void ILI9341_t3DMA::begin(void) {
220    esp_err_t ret;
221  
222    spi_bus_config_t buscfg;
223    memset(&buscfg, 0, sizeof(buscfg));
224    buscfg.miso_io_num=_miso;
225    buscfg.mosi_io_num=_mosi;
226    buscfg.sclk_io_num=_clk;
227    buscfg.quadwp_io_num=-1;
228    buscfg.quadhd_io_num=-1;
229    buscfg.max_transfer_sz=LINES_PER_BLOCK*ILI9341_TFTREALWIDTH*2+8;
230  
231    spi_device_interface_config_t devcfg;
232    memset(&devcfg, 0, sizeof(devcfg));
233    devcfg.clock_speed_hz=60*1000*1000;           //Clock out
234    devcfg.mode=0;                                //SPI mode 0
235    devcfg.spics_io_num=_cs;                      //CS pin
236    devcfg.queue_size=MAX_SPI_TRANS;              
237    devcfg.pre_cb=lcd_spi_pre_transfer_callback;  //Specify pre-transfer callback to handle D/C line
238    devcfg.flags = SPI_DEVICE_HALFDUPLEX ;        //With IOMUX and half duplex can go faster
239    
240    //Initialize the SPI bus
241    ret=spi_bus_initialize(VSPI_HOST, &buscfg, 1);
242    ESP_ERROR_CHECK(ret);
243    //Attach the LCD to the SPI bus
244    ret=spi_bus_add_device(VSPI_HOST, &devcfg, &lcdspi);
245    ESP_ERROR_CHECK(ret);  
246  };
247  
248  void ILI9341_t3DMA::start(void) {
249    lcd_init(lcdspi); 
250  }
251  
252  void ILI9341_t3DMA::refresh(void) {
253    send_blocks(lcdspi);
254    send_blocks_finish(lcdspi);  
255  }
256  
257  void ILI9341_t3DMA::refreshPrepare(void) {
258    send_blocks(lcdspi);
259  }
260  
261  void ILI9341_t3DMA::refreshFinish(void) {
262    send_blocks_finish(lcdspi);  
263  }
264  
265  void ILI9341_t3DMA::flipscreen(bool flip)
266  {
267    if (flip) {
268      flipped=true;    
269    }
270    else {
271      flipped=false;   
272    }
273  }
274  
275  bool ILI9341_t3DMA::isflipped(void)
276  {
277    return(flipped);
278  }
279  
280  uint16_t * ILI9341_t3DMA::getLineBuffer(int j)
281  {
282    uint16_t * block=blocks[j>>6];  
283    return(&block[(j&0x3F)*ILI9341_TFTREALWIDTH]);
284  }
285  
286  
287  void ILI9341_t3DMA::fillScreen(uint16_t color) {
288    int i,j;
289    color=SPI_SWAP_DATA_TX(color,16);
290    for (j=0; j<ILI9341_TFTREALHEIGHT; j++)
291    {
292      uint16_t * block=blocks[j>>6];
293      uint16_t * dst=&block[(j&0x3F)*ILI9341_TFTREALWIDTH];
294      for (i=0; i<ILI9341_TFTREALWIDTH; i++)
295      {
296        *dst++ = color;
297      }
298    }
299  }
300  
301  void ILI9341_t3DMA::writeScreen(int width, int height, int stride, uint8_t *buf, uint16_t *palette16) {
302    uint8_t *buffer=buf;
303    uint8_t *src; 
304  
305    int i,j,y=0;
306    if (width*2 <= ILI9341_TFTREALWIDTH) {
307      for (j=0; j<height; j++)
308      {
309        uint16_t * block=blocks[y>>6];
310        uint16_t * dst=&block[(y&0x3F)*ILI9341_TFTREALWIDTH];        
311        src=buffer;
312        for (i=0; i<width; i++)
313        {
314          uint16_t val = SPI_SWAP_DATA_TX(palette16[*src++],16);
315          *dst++ = val;
316          *dst++ = val;
317        }
318        y++;
319        if (height*2 <= ILI9341_TFTREALHEIGHT) {
320          block=blocks[y>>6];
321          dst=&block[(y&0x3F)*ILI9341_TFTREALWIDTH];          
322          src=buffer;
323          for (i=0; i<width; i++)
324          {
325            uint16_t val = SPI_SWAP_DATA_TX(palette16[*src++],16);
326            *dst++ = val;
327            *dst++ = val;
328          }
329          y++;      
330        } 
331        buffer += stride;      
332      }
333    }
334    else if (width <= ILI9341_TFTREALWIDTH) {
335      //dst += (ILI9341_TFTWIDTH-width)/2;
336      for (j=0; j<height; j++)
337      {
338        uint16_t * block=blocks[y>>6];
339        uint16_t * dst=&block[(y&0x3F)*ILI9341_TFTREALWIDTH+(ILI9341_TFTREALWIDTH-width)/2];         
340        src=buffer;
341        for (i=0; i<width; i++)
342        {
343          uint16_t val = SPI_SWAP_DATA_TX(palette16[*src++],16);
344          *dst++ = val;
345        }
346        y++;
347        if (height*2 <= ILI9341_TFTREALHEIGHT) {
348          block=blocks[y>>6];
349          dst=&block[(y&0x3F)*ILI9341_TFTREALWIDTH+(ILI9341_TFTREALWIDTH-width)/2];        
350          src=buffer;
351          for (i=0; i<width; i++)
352          {
353            uint16_t val = SPI_SWAP_DATA_TX(palette16[*src++],16);
354            *dst++ = val;
355          }
356          y++;
357        }      
358        buffer += stride;  
359      }
360    }    
361  }
362  
363  void ILI9341_t3DMA::writeLine(int width, int height, int y, uint8_t *buf, uint16_t *palette16) {
364    if (ILI9341_TFTHEIGHT > height)
365      y += (ILI9341_TFTHEIGHT - height)/2;
366    uint8_t  * src=buf;
367    uint16_t * block=blocks[y>>6];
368    uint16_t * dst=&block[(y&0x3F)*ILI9341_TFTREALWIDTH];
369    if (ILI9341_TFTWIDTH > width)
370      dst += (ILI9341_TFTWIDTH - width)/2;    
371    for (int i=0; i<width; i++)
372    {
373      uint8_t val = *src++;
374      *dst++=SPI_SWAP_DATA_TX(palette16[val],16);
375    }
376  }
377  
378  void ILI9341_t3DMA::drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) {
379  
380    int i,j,l=y;
381    color=SPI_SWAP_DATA_TX(color,16);
382    for (j=0; j<h; j++)
383    {
384      uint16_t * block=blocks[l>>6];
385      uint16_t * dst=&block[(l&0x3F)*ILI9341_TFTREALWIDTH+x];
386      for (i=0; i<w; i++)
387      {
388        *dst++ = color;
389      }
390      l++;
391    }
392  }
393  
394  void ILI9341_t3DMA::drawSprite(int16_t x, int16_t y, const uint16_t *bitmap) {
395      drawSprite(x,y,bitmap, 0,0,0,0);
396  }
397  
398  void ILI9341_t3DMA::drawSprite(int16_t x, int16_t y, const uint16_t *bitmap, uint16_t arx, uint16_t ary, uint16_t arw, uint16_t arh)
399  {
400    int bmp_offx = 0;
401    int bmp_offy = 0;
402    uint16_t *bmp_ptr;
403      
404    int w =*bitmap++;
405    int h = *bitmap++;
406  
407  
408    if ( (arw == 0) || (arh == 0) ) {
409      // no crop window
410      arx = x;
411      ary = y;
412      arw = w;
413      arh = h;
414    }
415    else {
416      if ( (x>(arx+arw)) || ((x+w)<arx) || (y>(ary+arh)) || ((y+h)<ary)   ) {
417        return;
418      }
419      
420      // crop area
421      if ( (x > arx) && (x<(arx+arw)) ) { 
422        arw = arw - (x-arx);
423        arx = arx + (x-arx);
424      } else {
425        bmp_offx = arx;
426      }
427      if ( ((x+w) > arx) && ((x+w)<(arx+arw)) ) {
428        arw -= (arx+arw-x-w);
429      }  
430      if ( (y > ary) && (y<(ary+arh)) ) {
431        arh = arh - (y-ary);
432        ary = ary + (y-ary);
433      } else {
434        bmp_offy = ary;
435      }
436      if ( ((y+h) > ary) && ((y+h)<(ary+arh)) ) {
437        arh -= (ary+arh-y-h);
438      }     
439    }
440  
441     
442    int l=ary;
443    bitmap = bitmap + bmp_offy*w + bmp_offx;
444    for (int row=0;row<arh; row++)
445    {
446      uint16_t * block=blocks[l>>6];
447      uint16_t * dst=&block[(l&0x3F)*ILI9341_TFTREALWIDTH+arx];  
448      bmp_ptr = (uint16_t*)bitmap;
449      for (int col=0;col<arw; col++)
450      {
451          *dst++ = SPI_SWAP_DATA_TX(*bmp_ptr++,16);            
452      } 
453      bitmap +=  w;
454      l++;
455    }
456  }
457  
458  void ILI9341_t3DMA::drawText(int16_t x, int16_t y, const char * text, uint16_t fgcolor, uint16_t bgcolor, bool doublesize) {
459    uint16_t c;
460    uint16_t * block;
461    uint16_t * dst;
462    fgcolor = SPI_SWAP_DATA_TX(fgcolor,16);
463    bgcolor = SPI_SWAP_DATA_TX(bgcolor,16);
464    
465    while ((c = *text++)) {
466      const unsigned char * charpt=&font8x8[c][0];
467  
468      int l=y;
469      for (int i=0;i<8;i++)
470      {     
471        unsigned char bits;
472        if (doublesize) {
473          block=blocks[l>>6];
474          dst=&block[(l&0x3F)*ILI9341_TFTREALWIDTH+x];         
475          bits = *charpt;     
476          if (bits&0x01) *dst++=fgcolor;
477          else *dst++=bgcolor;
478          bits = bits >> 1;     
479          if (bits&0x01) *dst++=fgcolor;
480          else *dst++=bgcolor;
481          bits = bits >> 1;     
482          if (bits&0x01) *dst++=fgcolor;
483          else *dst++=bgcolor;
484          bits = bits >> 1;     
485          if (bits&0x01) *dst++=fgcolor;
486          else *dst++=bgcolor;
487          bits = bits >> 1;     
488          if (bits&0x01) *dst++=fgcolor;
489          else *dst++=bgcolor;
490          bits = bits >> 1;     
491          if (bits&0x01) *dst++=fgcolor;
492          else *dst++=bgcolor;
493          bits = bits >> 1;     
494          if (bits&0x01) *dst++=fgcolor;
495          else *dst++=bgcolor;
496          bits = bits >> 1;     
497          if (bits&0x01) *dst++=fgcolor;
498          else *dst++=bgcolor;
499          l++;       
500        }
501        block=blocks[l>>6];
502        dst=&block[(l&0x3F)*ILI9341_TFTREALWIDTH+x]; 
503        bits = *charpt++;     
504        if (bits&0x01) *dst++=fgcolor;
505        else *dst++=bgcolor;
506        bits = bits >> 1;     
507        if (bits&0x01) *dst++=fgcolor;
508        else *dst++=bgcolor;
509        bits = bits >> 1;     
510        if (bits&0x01) *dst++=fgcolor;
511        else *dst++=bgcolor;
512        bits = bits >> 1;     
513        if (bits&0x01) *dst++=fgcolor;
514        else *dst++=bgcolor;
515        bits = bits >> 1;     
516        if (bits&0x01) *dst++=fgcolor;
517        else *dst++=bgcolor;
518        bits = bits >> 1;     
519        if (bits&0x01) *dst++=fgcolor;
520        else *dst++=bgcolor;
521        bits = bits >> 1;     
522        if (bits&0x01) *dst++=fgcolor;
523        else *dst++=bgcolor;
524        bits = bits >> 1;     
525        if (bits&0x01) *dst++=fgcolor;
526        else *dst++=bgcolor;
527        l++;
528      }
529      x +=8;
530    }
531  }
532  
533  
534  
535  // TOUCH
536  #define _BV(bit) (1 << (bit))
537  #define XPT2046_CFG_START   _BV(7)
538  #define XPT2046_CFG_MUX(v)  ((v&0b111) << (4))
539  #define XPT2046_CFG_8BIT    _BV(3)
540  #define XPT2046_CFG_12BIT   (0)
541  #define XPT2046_CFG_SER     _BV(2)
542  #define XPT2046_CFG_DFR     (0)
543  #define XPT2046_CFG_PWR(v)  ((v&0b11))
544  #define XPT2046_MUX_Y       0b101
545  #define XPT2046_MUX_X       0b001
546  #define XPT2046_MUX_Z1      0b011
547  #define XPT2046_MUX_Z2      0b100
548  
549  
550  
551  static spi_device_handle_t touchspi;
552  
553  //void ILI9341_t3DMA::touchBegin(uint8_t mosi, uint8_t miso, uint8_t clk, uint8_t cs) {
554  void ILI9341_t3DMA::touchBegin() {
555    esp_err_t ret;
556    
557    gpio_set_direction((gpio_num_t)_touch_irq, GPIO_MODE_INPUT);
558    gpio_set_pull_mode((gpio_num_t)_touch_irq, GPIO_PULLUP_ONLY);
559  
560    spi_device_interface_config_t devcfg;
561    memset(&devcfg, 0, sizeof(devcfg));
562    devcfg.clock_speed_hz=2500000;
563    devcfg.mode=0;
564    devcfg.spics_io_num=_touch_cs;
565    devcfg.queue_size=2;   
566    devcfg.flags = SPI_DEVICE_HALFDUPLEX ;
567  
568    /*
569    spi_bus_config_t buscfg;
570    memset(&buscfg, 0, sizeof(buscfg));
571    buscfg.miso_io_num=miso;
572    buscfg.mosi_io_num=mosi;
573    buscfg.sclk_io_num=clk;
574    buscfg.quadwp_io_num=-1;
575    buscfg.quadhd_io_num=-1;
576    buscfg.max_transfer_sz=48;
577  
578    ret=spi_bus_initialize(HSPI_HOST, &buscfg, 2);
579    ESP_ERROR_CHECK(ret);
580    */
581    
582    ret=spi_bus_add_device(HSPI_HOST, &devcfg, &touchspi);
583    ESP_ERROR_CHECK(ret);  
584  }
585  
586  
587  uint16_t touch_get_data(spi_device_handle_t spi, const uint8_t cmd)
588  {
589      spi_transaction_t t;
590      memset(&t, 0, sizeof(t));       //Zero out the transaction
591      t.length=8;                     //Command is 8 bits
592      t.tx_buffer=&cmd;               //The data is the cmd itself
593      esp_err_t ret=spi_device_polling_transmit(spi, &t);  //Transmit!
594      if (ret==ESP_OK) {
595        memset(&t, 0, sizeof(t));
596        t.rxlength=8*2;
597        t.flags = SPI_TRANS_USE_RXDATA;
598        ret = spi_device_polling_transmit(spi, &t);
599        if (ret==ESP_OK) {
600          printf("touch data failed\n");
601          return 0;
602        }
603      }
604      else {
605        printf("touch cmd failed\n");
606      } 
607      return *(uint16_t*)t.rx_data;    
608  }
609  
610  
611  
612  bool ILI9341_t3DMA::isTouching()
613  { 
614    return ((gpio_get_level((gpio_num_t)_touch_irq) == 0 ? true : false)); 
615  }
616  
617  void ILI9341_t3DMA::readRo(uint16_t * oX, uint16_t * oY, uint16_t * oZ) {
618    uint16_t x = 0;
619    uint16_t y = 0;
620    uint16_t z1 = 0;
621    uint16_t z2 = 0;
622    uint8_t i = 0;
623    int16_t xraw=0, yraw=0;
624  
625  
626    for(; i < 15; i++) {
627      y  += touch_get_data(touchspi, (XPT2046_CFG_START | XPT2046_CFG_12BIT | XPT2046_CFG_DFR | XPT2046_CFG_MUX(XPT2046_MUX_Y) | XPT2046_CFG_PWR(3)));
628      x  += touch_get_data(touchspi, (XPT2046_CFG_START | XPT2046_CFG_12BIT | XPT2046_CFG_DFR | XPT2046_CFG_MUX(XPT2046_MUX_X) | XPT2046_CFG_PWR(3)));
629      z1 += touch_get_data(touchspi, (XPT2046_CFG_START | XPT2046_CFG_12BIT | XPT2046_CFG_DFR | XPT2046_CFG_MUX(XPT2046_MUX_Z1)| XPT2046_CFG_PWR(3)));
630      z2 += touch_get_data(touchspi, (XPT2046_CFG_START | XPT2046_CFG_12BIT | XPT2046_CFG_DFR | XPT2046_CFG_MUX(XPT2046_MUX_Z2)| XPT2046_CFG_PWR(3)));
631    }  
632    printf("%d %d %d %d \n",x/15,y/15,z1/15,z2/15);  
633  /*
634    SPI.beginTransaction(SPI_SETTING);
635    digitalWrite(_touch_cs, LOW);
636  
637    for(; i < 15; i++) {
638      // SPI requirer 32bit aliment
639      uint8_t buf[12] = {
640        (XPT2046_CFG_START | XPT2046_CFG_12BIT | XPT2046_CFG_DFR | XPT2046_CFG_MUX(XPT2046_MUX_Y) | XPT2046_CFG_PWR(3)), 0x00, 0x00,
641        (XPT2046_CFG_START | XPT2046_CFG_12BIT | XPT2046_CFG_DFR | XPT2046_CFG_MUX(XPT2046_MUX_X) | XPT2046_CFG_PWR(3)), 0x00, 0x00,
642        (XPT2046_CFG_START | XPT2046_CFG_12BIT | XPT2046_CFG_DFR | XPT2046_CFG_MUX(XPT2046_MUX_Z1)| XPT2046_CFG_PWR(3)), 0x00, 0x00,
643        (XPT2046_CFG_START | XPT2046_CFG_12BIT | XPT2046_CFG_DFR | XPT2046_CFG_MUX(XPT2046_MUX_Z2)| XPT2046_CFG_PWR(3)), 0x00, 0x00
644      };
645      SPI.transfer(&buf[0], &buf[0], 12);
646      y += (buf[1] << 8 | buf[2])>>3;
647      x += (buf[4] << 8 | buf[5])>>3;
648      z1 += (buf[7] << 8 | buf[8])>>3;
649      z2 += (buf[10] << 8 | buf[11])>>3;
650    }   
651    */
652  }
653  
654  void ILI9341_t3DMA::readRaw(uint16_t * oX, uint16_t * oY, uint16_t * oZ) {
655     
656  }
657  
658  void ILI9341_t3DMA::readCal(uint16_t * oX, uint16_t * oY, uint16_t * oZ){
659     
660  }
661  
662  void ILI9341_t3DMA::callibrateTouch(uint16_t xMin,uint16_t yMin,uint16_t xMax,uint16_t yMax){
663     
664  }
665  
666