Lib for the new LCD Display with ILI9341 controller
Diff: SPI_TFT_ILI9341.cpp
- Revision:
- 8:07ad6a48a85d
- Parent:
- 7:4c30bea883bc
--- a/SPI_TFT_ILI9341.cpp Sun Jan 26 20:54:21 2014 +0000 +++ b/SPI_TFT_ILI9341.cpp Sun Jun 22 21:44:00 2014 +0000 @@ -1,5 +1,6 @@ /* mbed library for 240*320 pixel display TFT based on ILI9341 LCD Controller - * Copyright (c) 2013 Peter Drescher - DC2PD + * Copyright (c) 2013, 2014 Peter Drescher - DC2PD + * special version for STM Nucleo -L152 and SPI1 ! * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, @@ -9,21 +10,19 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ - -// 12.06.13 fork from SPI_TFT code because controller is different ... -// 14.07.13 Test with real display and bugfix -// 18.10.13 Better Circle function from Michael Ammann -// 22.10.13 Fixes for Kinetis Board - 8 bit spi -// 26.01.14 Change interface for BMP_16 to also use SD-cards #include "SPI_TFT_ILI9341.h" #include "mbed.h" +#include "stm32l1xx_dma.h" +#include "stm32l1xx_rcc.h" +#include "stm32l1xx_spi.h" -#define BPP 16 // Bits per pixel - +#define BPP 16 // Bits per pixel + //extern Serial pc; //extern DigitalOut xx; // debug !! + SPI_TFT_ILI9341::SPI_TFT_ILI9341(PinName mosi, PinName miso, PinName sclk, PinName cs, PinName reset, PinName dc, const char *name) : _spi(mosi, miso, sclk), _cs(cs), _reset(reset), _dc(dc), GraphicsDisplay(name) { @@ -65,9 +64,9 @@ _spi.write(0xE8); break; } - _cs = 1; + _cs = 1; WindowMax(); -} +} // write command to tft register @@ -76,7 +75,8 @@ { _dc = 0; _cs = 0; - _spi.write(cmd); // mbed lib + SPI1->DR = cmd; + do{}while((SPI1->SR & 0x80) == 0x80); // wait for SPI send _dc = 1; } @@ -84,22 +84,23 @@ void SPI_TFT_ILI9341::wr_dat(unsigned char dat) { - _spi.write(dat); // mbed lib + SPI1->DR = dat; + do{}while((SPI1->SR & 0x80) == 0x80); // wait for SPI send } - - -// the ILI9341 can read +// the ILI9341 can read char SPI_TFT_ILI9341::rd_byte(unsigned char cmd) { char r; _dc = 0; _cs = 0; - _spi.write(cmd); // mbed lib + SPI1->DR = cmd; + do{}while(SPI1->SR & 0x02 == 0); // wait for SPI send + SPI1->DR = 0xFF; + do{}while(SPI1->SR & 0x02 == 0); // wait for SPI send + r = SPI1->DR; _cs = 1; - r = _spi.write(0xff); - _cs = 1; return(r); } @@ -114,7 +115,7 @@ d = d << 1; _spi.format(9,3); // we have to add a dummy clock cycle _spi.write(d); - _spi.format(8,3); + _spi.format(8,3); _dc = 1; r = _spi.write(0xff); d = r; @@ -124,7 +125,7 @@ d = (d << 8) | r; r = _spi.write(0xff); d = (d << 8) | r; - _cs = 1; + _cs = 1; return(d); } @@ -139,204 +140,246 @@ // Init code based on MI0283QT datasheet +// this code is called only at start +// no need to be optimized void SPI_TFT_ILI9341::tft_reset() { _spi.format(8,3); // 8 bit spi mode 3 - _spi.frequency(10000000); // 10 Mhz SPI clock + _spi.frequency(8000000); // 8 Mhz SPI clock - 32 / 4 _cs = 1; // cs high - _dc = 1; // dc high + _dc = 1; // dc high _reset = 0; // display reset wait_us(50); _reset = 1; // end hardware reset wait_ms(5); - - wr_cmd(0x01); // SW reset + + wr_cmd(0x01); // SW reset wait_ms(5); - wr_cmd(0x28); // display off + wr_cmd(0x28); // display off /* Start Initial Sequence ----------------------------------------------------*/ - wr_cmd(0xCF); + wr_cmd(0xCF); _spi.write(0x00); _spi.write(0x83); _spi.write(0x30); _cs = 1; - - wr_cmd(0xED); + + wr_cmd(0xED); _spi.write(0x64); _spi.write(0x03); _spi.write(0x12); _spi.write(0x81); _cs = 1; - - wr_cmd(0xE8); + + wr_cmd(0xE8); _spi.write(0x85); _spi.write(0x01); _spi.write(0x79); _cs = 1; - - wr_cmd(0xCB); + + wr_cmd(0xCB); _spi.write(0x39); _spi.write(0x2C); _spi.write(0x00); _spi.write(0x34); _spi.write(0x02); _cs = 1; - - wr_cmd(0xF7); + + wr_cmd(0xF7); _spi.write(0x20); _cs = 1; - - wr_cmd(0xEA); + + wr_cmd(0xEA); _spi.write(0x00); _spi.write(0x00); _cs = 1; - + wr_cmd(0xC0); // POWER_CONTROL_1 _spi.write(0x26); _cs = 1; - + wr_cmd(0xC1); // POWER_CONTROL_2 _spi.write(0x11); _cs = 1; - + wr_cmd(0xC5); // VCOM_CONTROL_1 _spi.write(0x35); _spi.write(0x3E); _cs = 1; - + wr_cmd(0xC7); // VCOM_CONTROL_2 _spi.write(0xBE); - _cs = 1; - + _cs = 1; + wr_cmd(0x36); // MEMORY_ACCESS_CONTROL _spi.write(0x48); - _cs = 1; - + _cs = 1; + wr_cmd(0x3A); // COLMOD_PIXEL_FORMAT_SET - _spi.write(0x55); // 16 bit pixel + _spi.write(0x55); // 16 bit pixel _cs = 1; - + wr_cmd(0xB1); // Frame Rate _spi.write(0x00); - _spi.write(0x1B); + _spi.write(0x1B); _cs = 1; - + wr_cmd(0xF2); // Gamma Function Disable _spi.write(0x08); - _cs = 1; - - wr_cmd(0x26); + _cs = 1; + + wr_cmd(0x26); _spi.write(0x01); // gamma set for curve 01/2/04/08 - _cs = 1; - + _cs = 1; + wr_cmd(0xE0); // positive gamma correction - _spi.write(0x1F); - _spi.write(0x1A); - _spi.write(0x18); - _spi.write(0x0A); - _spi.write(0x0F); - _spi.write(0x06); - _spi.write(0x45); - _spi.write(0x87); - _spi.write(0x32); - _spi.write(0x0A); - _spi.write(0x07); - _spi.write(0x02); + _spi.write(0x1F); + _spi.write(0x1A); + _spi.write(0x18); + _spi.write(0x0A); + _spi.write(0x0F); + _spi.write(0x06); + _spi.write(0x45); + _spi.write(0x87); + _spi.write(0x32); + _spi.write(0x0A); _spi.write(0x07); - _spi.write(0x05); + _spi.write(0x02); + _spi.write(0x07); + _spi.write(0x05); _spi.write(0x00); _cs = 1; - + wr_cmd(0xE1); // negativ gamma correction - _spi.write(0x00); - _spi.write(0x25); - _spi.write(0x27); - _spi.write(0x05); - _spi.write(0x10); - _spi.write(0x09); - _spi.write(0x3A); - _spi.write(0x78); - _spi.write(0x4D); - _spi.write(0x05); - _spi.write(0x18); - _spi.write(0x0D); + _spi.write(0x00); + _spi.write(0x25); + _spi.write(0x27); + _spi.write(0x05); + _spi.write(0x10); + _spi.write(0x09); + _spi.write(0x3A); + _spi.write(0x78); + _spi.write(0x4D); + _spi.write(0x05); + _spi.write(0x18); + _spi.write(0x0D); _spi.write(0x38); - _spi.write(0x3A); + _spi.write(0x3A); _spi.write(0x1F); _cs = 1; - + WindowMax (); - + //wr_cmd(0x34); // tearing effect off //_cs = 1; - + //wr_cmd(0x35); // tearing effect on //_cs = 1; - + wr_cmd(0xB7); // entry mode _spi.write(0x07); _cs = 1; - + wr_cmd(0xB6); // display function control _spi.write(0x0A); _spi.write(0x82); _spi.write(0x27); _spi.write(0x00); _cs = 1; - + wr_cmd(0x11); // sleep out _cs = 1; - + wait_ms(100); - + wr_cmd(0x29); // display on _cs = 1; - + wait_ms(100); - + + // Configure the DMA controller init-structure + RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); // SPI1 is using DMA 1 + DMA_StructInit(&DMA_InitStructure); + DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) &(SPI1->DR); + DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST; + DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; + DMA_InitStructure.DMA_BufferSize = 0; + DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; + DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; + DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; + DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; + DMA_InitStructure.DMA_Priority = DMA_Priority_High; } +// speed optimized +// write direct to SPI1 register ! void SPI_TFT_ILI9341::pixel(int x, int y, int color) { - wr_cmd(0x2A); - _spi.write(x >> 8); - _spi.write(x); - _cs = 1; - wr_cmd(0x2B); - _spi.write(y >> 8); - _spi.write(y); + _dc = 0; + _cs = 0; + SPI1->DR = 0x2A; + do{}while((SPI1->SR & 0x80) == 0x80); // wait for SPI send + _dc = 1; + SPI1->CR1 |= 1 << 11; // switch to 16 bit Mode + SPI1->DR = x; + do{}while((SPI1->SR & 0x80) == 0x80); // wait for SPI send + _cs = 1; - wr_cmd(0x2C); // send pixel - #if defined TARGET_KL25Z // 8 Bit SPI - _spi.write(color >> 8); - _spi.write(color & 0xff); - #else - _spi.format(16,3); // switch to 16 bit Mode 3 - _spi.write(color); // Write D0..D15 - _spi.format(8,3); - #endif + SPI1->CR1 &= ~(1 << 11); // switch to 8 bit Mode + _dc = 0; + _cs = 0; + SPI1->DR = 0x2B; + do{}while((SPI1->SR & 0x80) == 0x80); // wait for SPI send + _dc = 1; + SPI1->CR1 |= 1 << 11; // switch to 16 bit Mode + SPI1->DR = y; + do{}while((SPI1->SR & 0x80) == 0x80); // wait for SPI send _cs = 1; + SPI1->CR1 &= ~(1 << 11); // switch to 8 bit Mode + _dc = 0; + _cs = 0; + SPI1->DR = 0x2C; // send pixel + do{}while((SPI1->SR & 0x80) == 0x80); // wait for SPI send + _dc = 1; + SPI1->CR1 |= 1 << 11; // switch to 16 bit Mode + SPI1->DR = color; + do{}while((SPI1->SR & 0x80) == 0x80); // wait for SPI send + + _cs = 1; + SPI1->CR1 &= ~(1 << 11); // switch to 8 bit Mode } - +// optimized +// write direct to SPI1 register ! void SPI_TFT_ILI9341::window (unsigned int x, unsigned int y, unsigned int w, unsigned int h) { - wr_cmd(0x2A); - _spi.write(x >> 8); - _spi.write(x); - _spi.write((x+w-1) >> 8); - _spi.write(x+w-1); - + _dc = 0; + _cs = 0; + SPI1->DR = 0x2A; + do{}while((SPI1->SR & 0x80) == 0x80); // wait for SPI send + _dc = 1; + SPI1->CR1 |= 1 << 11; // switch to 16 bit Mode + SPI1->DR = x ; + do{}while((SPI1->SR & 0x02) == 0); // wait for SPI TX buffer free + SPI1->DR = (x+w-1); + do{}while((SPI1->SR & 0x80) == 0x80); // wait for SPI send _cs = 1; - wr_cmd(0x2B); - _spi.write(y >> 8); - _spi.write(y); - _spi.write((y+h-1) >> 8); - _spi.write(y+h-1); + _dc = 0; + SPI1->CR1 &= ~(1 << 11); // switch to 8 bit Mode + _cs = 0; + SPI1->DR = 0x2B; + do{}while((SPI1->SR & 0x80) == 0x80); // wait for SPI send + _dc = 1; + SPI1->CR1 |= 1 << 11; // switch to 16 bit Mode + SPI1->DR = y ; + do{}while((SPI1->SR & 0x02) == 0); // wait for SPI TX buffer free + SPI1->DR = (y+h-1); + do{}while((SPI1->SR & 0x80) == 0x80); // wait for SPI send _cs = 1; + SPI1->CR1 &= ~(1 << 11); // switch to 8 bit Mode } @@ -345,28 +388,38 @@ window (0, 0, width(), height()); } - - +// optimized +// use DMA to transfer pixel data to the screen void SPI_TFT_ILI9341::cls (void) { int pixel = ( width() * height()); WindowMax(); - wr_cmd(0x2C); // send pixel - #if defined TARGET_KL25Z // 8 Bit SPI - unsigned int i; - for (i = 0; i < ( width() * height()); i++){ - _spi.write(_background >> 8); - _spi.write(_background & 0xff); - } - - #else - _spi.format(16,3); // switch to 16 bit Mode 3 - unsigned int i; - for (i = 0; i < ( width() * height()); i++) - _spi.write(_background); - _spi.format(8,3); - #endif - _cs = 1; + _dc = 0; + _cs = 0; + SPI1->DR = 0x2C; // send pixel + do{}while((SPI1->SR & 0x80) == 0x80); // wait for SPI send + _dc = 1; + SPI1->CR1 |= 1 << 11; // switch to 16 bit Mode + + // set up the DMA structure for single byte + DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) &_background; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; + DMA_Init(DMA1_Channel3, &DMA_InitStructure); // init the DMA + // we have to send 2 blocks of pixel date, because the DMA counter can only transfer 64k + DMA_SetCurrDataCounter(DMA1_Channel3, 38400); // 1.half of screen + SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx,ENABLE); + DMA_Cmd(DMA1_Channel3, ENABLE); + do{ + }while(DMA_GetCurrDataCounter(DMA1_Channel3) != 0); // wait for end of transfer + DMA_Cmd(DMA1_Channel3, DISABLE); + DMA_SetCurrDataCounter(DMA1_Channel3, 38400); // 2.half of screen + DMA_Cmd(DMA1_Channel3, ENABLE); + do{ + }while(DMA_GetCurrDataCounter(DMA1_Channel3) != 0); // wait for end of transfer + DMA_Cmd(DMA1_Channel3, DISABLE); + do{}while((SPI1->SR & 0x80) == 0x80); // wait for SPI send + _cs = 1; + SPI1->CR1 &= ~(1 << 11); // switch to 8 bit Mode } @@ -405,26 +458,24 @@ } +// optimized for speed +// use SPI1 register access !! void SPI_TFT_ILI9341::hline(int x0, int x1, int y, int color) { int w; w = x1 - x0 + 1; window(x0,y,w,1); wr_cmd(0x2C); // send pixel - #if defined TARGET_KL25Z // 8 Bit SPI + + SPI1->CR1 |= 1 << 11; // switch to 16 bit Mode + int j; for (j=0; j<w; j++) { - _spi.write(color >> 8); - _spi.write(color & 0xff); - } - #else - _spi.format(16,3); // switch to 16 bit Mode 3 - int j; - for (j=0; j<w; j++) { - _spi.write(color); + SPI1->DR = color; + do{}while((SPI1->SR & 0x02) == 0); // wait for SPI TX buffer free } - _spi.format(8,3); - #endif + do{}while((SPI1->SR & 0x80) == 0x80); // wait for SPI send + SPI1->CR1 &= ~(1 << 11); // switch to 8 bit Mode _cs = 1; WindowMax(); return; @@ -436,18 +487,12 @@ h = y1 - y0 + 1; window(x,y0,1,h); wr_cmd(0x2C); // send pixel - #if defined TARGET_KL25Z // 8 Bit SPI - for (int y=0; y<h; y++) { - _spi.write(color >> 8); - _spi.write(color & 0xff); - } - #else + _spi.format(16,3); // switch to 16 bit Mode 3 for (int y=0; y<h; y++) { _spi.write(color); } - _spi.format(8,3); - #endif + SPI1->CR1 &= ~(1 << 11); // switch to 8 bit Mode _cs = 1; WindowMax(); return; @@ -547,26 +592,39 @@ +// optimized for speed +// use DMA void SPI_TFT_ILI9341::fillrect(int x0, int y0, int x1, int y1, int color) { int h = y1 - y0 + 1; int w = x1 - x0 + 1; int pixel = h * w; + unsigned int dma_transfer; window(x0,y0,w,h); - wr_cmd(0x2C); // send pixel - #if defined TARGET_KL25Z // 8 Bit SPI - for (int p=0; p<pixel; p++) { - _spi.write(color >> 8); - _spi.write(color & 0xff); - } - #else - _spi.format(16,3); // switch to 16 bit Mode 3 - for (int p=0; p<pixel; p++) { - _spi.write(color); - } - _spi.format(8,3); - #endif + wr_cmd(0x2C); // send pixel + SPI1->CR1 |= 1 << 11; // switch to 16 bit Mode + DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) &color; + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; + DMA_Init(DMA1_Channel3, &DMA_InitStructure); // init the DMA + do{ + if(pixel < 0x10000) { + dma_transfer = pixel; + pixel = 0; + } + else { + dma_transfer = 0xffff; + pixel = pixel - 0xffff; + } + DMA_SetCurrDataCounter(DMA1_Channel3, dma_transfer); + SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx,ENABLE); + DMA_Cmd(DMA1_Channel3, ENABLE); + do{ + }while(DMA_GetCurrDataCounter(DMA1_Channel3) != 0); // wait for end of transfer + DMA_Cmd(DMA1_Channel3, DISABLE); + }while(pixel > 0); + do{}while((SPI1->SR & 0x80) == 0x80); // wait for SPI send + SPI1->CR1 &= ~(1 << 11); // switch to 8 bit Mode _cs = 1; WindowMax(); return; @@ -610,11 +668,16 @@ } + void SPI_TFT_ILI9341::character(int x, int y, int c) { unsigned int hor,vert,offset,bpl,j,i,b; unsigned char* zeichen; unsigned char z,w; + unsigned int pixel; + unsigned int p; + unsigned int dma_count,dma_off; + uint16_t *buffer; if ((c < 31) || (c > 127)) return; // test char range @@ -633,36 +696,69 @@ } window(char_x, char_y,hor,vert); // char box wr_cmd(0x2C); // send pixel - #ifndef TARGET_KL25Z // 16 Bit SPI - _spi.format(16,3); - #endif // switch to 16 bit Mode 3 - zeichen = &font[((c -32) * offset) + 4]; // start of char bitmap - w = zeichen[0]; // width of actual char - for (j=0; j<vert; j++) { // vert line - for (i=0; i<hor; i++) { // horz line - z = zeichen[bpl * i + ((j & 0xF8) >> 3)+1]; - b = 1 << (j & 0x07); - if (( z & b ) == 0x00) { - #ifndef TARGET_KL25Z // 16 Bit SPI - _spi.write(_background); - #else - _spi.write(_background >> 8); - _spi.write(_background & 0xff); - #endif - } else { - #ifndef TARGET_KL25Z // 16 Bit SPI - _spi.write(_foreground); - #else - _spi.write(_foreground >> 8); - _spi.write(_foreground & 0xff); - #endif + pixel = hor * vert; // calculate buffer size + SPI1->CR1 |= 1 << 11; // switch to 16 bit Mode + buffer = (uint16_t *) malloc (2*pixel); // we need a buffer for the 16 bit + if (buffer == NULL) { // there is no space + zeichen = &font[((c -32) * offset) + 4]; // start of char bitmap + w = zeichen[0]; // width of actual char + for (j=0; j<vert; j++) { // vert line + for (i=0; i<hor; i++) { // horz line + z = zeichen[bpl * i + ((j & 0xF8) >> 3)+1]; + b = 1 << (j & 0x07); + if (( z & b ) == 0x00) { + _spi.write(_background); + } else { + _spi.write(_foreground); + } } } + _cs = 1; + _spi.format(8,3); + } + else{ // malloc ok, we can use DMA + zeichen = &font[((c -32) * offset) + 4]; // start of char bitmap + w = zeichen[0]; // width of actual char + p = 0; + // construct the char into the buffer + for (j=0; j<vert; j++) { // vert line + for (i=0; i<hor; i++) { // horz line + z = zeichen[bpl * i + ((j & 0xF8) >> 3)+1]; + b = 1 << (j & 0x07); + if (( z & b ) == 0x00) { + buffer[p] = _background; + } else { + buffer[p] = _foreground; + } + p++; + } + } + // copy the buffer with DMA SPI to display + dma_off = 0; // offset for DMA transfer + DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) (buffer + dma_off); + DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; + DMA_Init(DMA1_Channel3, &DMA_InitStructure); // init the DMA + // start DMA + do { + if (pixel > 0X10000) { // this is a giant font ! + dma_count = 0Xffff; + pixel = pixel - 0Xffff; + } else { + dma_count = pixel; + pixel = 0; + } + DMA_SetCurrDataCounter(DMA1_Channel3, dma_count); + SPI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx,ENABLE); + DMA_Cmd(DMA1_Channel3, ENABLE); + do{ + }while(DMA_GetCurrDataCounter(DMA1_Channel3) != 0); // wait for end of transfer + DMA_Cmd(DMA1_Channel3, DISABLE); + }while(pixel > 0); + do{}while(SPI1->SR & 0x80 == 1); // wait for SPI send + free ((uint16_t *) buffer); + SPI1->CR1 &= ~(1 << 11); // switch to 8 bit Mode } _cs = 1; - #ifndef TARGET_KL25Z // 16 Bit SPI - _spi.format(8,3); - #endif WindowMax(); if ((w + 2) < hor) { // x offset to next char char_x += w + 2; @@ -682,12 +778,9 @@ unsigned int j; int padd; unsigned short *bitmap_ptr = (unsigned short *)bitmap; - #if defined TARGET_KL25Z // 8 Bit SPI - unsigned short pix_temp; - #endif - + unsigned int i; - + // the lines are padded to multiple of 4 bytes in a bitmap padd = -1; do { @@ -696,28 +789,17 @@ window(x, y, w, h); bitmap_ptr += ((h - 1)* (w + padd)); wr_cmd(0x2C); // send pixel - #ifndef TARGET_KL25Z // 16 Bit SPI _spi.format(16,3); - #endif // switch to 16 bit Mode 3 for (j = 0; j < h; j++) { //Lines for (i = 0; i < w; i++) { // one line - #if defined TARGET_KL25Z // 8 Bit SPI - pix_temp = *bitmap_ptr; - _spi.write(pix_temp >> 8); - _spi.write(pix_temp); - bitmap_ptr++; - #else _spi.write(*bitmap_ptr); // one line bitmap_ptr++; - #endif } bitmap_ptr -= 2*w; bitmap_ptr -= padd; } _cs = 1; - #ifndef TARGET_KL25Z // 16 Bit SPI _spi.format(8,3); - #endif WindowMax(); } @@ -746,8 +828,8 @@ while (*Name_BMP!='\0') { filename[i++]=*Name_BMP++; } - filename[i] = 0; - + filename[i] = 0; + FILE *Image = fopen((const char *)&filename[0], "rb"); // open the bmp file if (!Image) { return(0); // error file not found ! @@ -788,21 +870,14 @@ window(x, y,PixelWidth ,PixelHeigh); wr_cmd(0x2C); // send pixel - #ifndef TARGET_KL25Z // only 8 Bit SPI - _spi.format(16,3); - #endif // switch to 16 bit Mode 3 + _spi.format(16,3); for (j = PixelHeigh - 1; j >= 0; j--) { //Lines bottom up off = j * (PixelWidth * 2 + padd) + start_data; // start of line fseek(Image, off ,SEEK_SET); - fread(line,1,PixelWidth * 2,Image); // read a line - slow + fread(line,1,PixelWidth * 2,Image); // read a line - slow for (i = 0; i < PixelWidth; i++) { // copy pixel data to TFT - #ifndef TARGET_KL25Z // only 8 Bit SPI _spi.write(line[i]); // one 16 bit pixel - #else - _spi.write(line[i] >> 8); - _spi.write(line[i]); - #endif - } + } } _cs = 1; _spi.format(8,3);