acid-drop- Hacking the planet from a LilyGo T-Deck using custom firmware |
git clone git://git.acid.vegas/acid-drop.git |
Log | Files | Refs | Archive | README | LICENSE |
Flash_Jpg_DMA.ino (4140B)
1 // Example for library: 2 // https://github.com/Bodmer/TJpg_Decoder 3 4 // This example renders a Jpeg file that is stored in an array within Flash (program) memory 5 // see panda.h tab. The panda image file being ~13Kbytes. 6 7 #define USE_DMA 8 9 // Include the array 10 #include "panda.h" 11 12 // Include the jpeg decoder library 13 #include <TJpg_Decoder.h> 14 15 #ifdef USE_DMA 16 uint16_t dmaBuffer1[16*16]; // Toggle buffer for 16*16 MCU block, 512bytes 17 uint16_t dmaBuffer2[16*16]; // Toggle buffer for 16*16 MCU block, 512bytes 18 uint16_t* dmaBufferPtr = dmaBuffer1; 19 bool dmaBufferSel = 0; 20 #endif 21 22 // Include the TFT library https://github.com/Bodmer/TFT_eSPI 23 #include "SPI.h" 24 #include <TFT_eSPI.h> // Hardware-specific library 25 TFT_eSPI tft = TFT_eSPI(); // Invoke custom library 26 27 // This next function will be called during decoding of the jpeg file to render each 28 // 16x16 or 8x8 image tile (Minimum Coding Unit) to the TFT. 29 bool tft_output(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t* bitmap) 30 { 31 // Stop further decoding as image is running off bottom of screen 32 if ( y >= tft.height() ) return 0; 33 34 // STM32F767 processor takes 43ms just to decode (and not draw) jpeg (-Os compile option) 35 // Total time to decode and also draw to TFT: 36 // SPI 54MHz=71ms, with DMA 50ms, 71-43 = 28ms spent drawing, so DMA is complete before next MCU block is ready 37 // Apparent performance benefit of DMA = 71/50 = 42%, 50 - 43 = 7ms lost elsewhere 38 // SPI 27MHz=95ms, with DMA 52ms. 95-43 = 52ms spent drawing, so DMA is *just* complete before next MCU block is ready! 39 // Apparent performance benefit of DMA = 95/52 = 83%, 52 - 43 = 9ms lost elsewhere 40 #ifdef USE_DMA 41 // Double buffering is used, the bitmap is copied to the buffer by pushImageDMA() the 42 // bitmap can then be updated by the jpeg decoder while DMA is in progress 43 if (dmaBufferSel) dmaBufferPtr = dmaBuffer2; 44 else dmaBufferPtr = dmaBuffer1; 45 dmaBufferSel = !dmaBufferSel; // Toggle buffer selection 46 // pushImageDMA() will clip the image block at screen boundaries before initiating DMA 47 tft.pushImageDMA(x, y, w, h, bitmap, dmaBufferPtr); // Initiate DMA - blocking only if last DMA is not complete 48 // The DMA transfer of image block to the TFT is now in progress... 49 #else 50 // Non-DMA blocking alternative 51 tft.pushImage(x, y, w, h, bitmap); // Blocking, so only returns when image block is drawn 52 #endif 53 // Return 1 to decode next block. 54 return 1; 55 } 56 57 void setup() 58 { 59 Serial.begin(115200); 60 Serial.println("\n\n Testing TJpg_Decoder library"); 61 62 // Initialise the TFT 63 tft.begin(); 64 tft.setTextColor(TFT_WHITE, TFT_BLACK); 65 tft.fillScreen(TFT_BLACK); 66 67 #ifdef USE_DMA 68 tft.initDMA(); // To use SPI DMA you must call initDMA() to setup the DMA engine 69 #endif 70 71 // The jpeg image can be scaled down by a factor of 1, 2, 4, or 8 72 TJpgDec.setJpgScale(1); 73 74 // The colour byte order can be swapped by the decoder 75 // using TJpgDec.setSwapBytes(true); or by the TFT_eSPI library: 76 tft.setSwapBytes(true); 77 78 // The decoder must be given the exact name of the rendering function above 79 TJpgDec.setCallback(tft_output); 80 } 81 82 void loop() 83 { 84 // Show a contrasting colour for demo of draw speed 85 tft.fillScreen(TFT_RED); 86 87 88 // Get the width and height in pixels of the jpeg if you wish: 89 uint16_t w = 0, h = 0; 90 TJpgDec.getJpgSize(&w, &h, panda, sizeof(panda)); 91 Serial.print("Width = "); Serial.print(w); Serial.print(", height = "); Serial.println(h); 92 93 // Time recorded for test purposes 94 uint32_t dt = millis(); 95 96 // Must use startWrite first so TFT chip select stays low during DMA and SPI channel settings remain configured 97 tft.startWrite(); 98 99 // Draw the image, top left at 0,0 - DMA request is handled in the call-back tft_output() in this sketch 100 TJpgDec.drawJpg(0, 0, panda, sizeof(panda)); 101 102 // Must use endWrite to release the TFT chip select and release the SPI channel 103 tft.endWrite(); 104 105 // How much time did rendering take (ESP8266 80MHz 262ms, 160MHz 149ms, ESP32 SPI 111ms, 8bit parallel 90ms 106 dt = millis() - dt; 107 Serial.print(dt); Serial.println(" ms"); 108 109 // Wait before drawing again 110 delay(2000); 111 }