Created
December 7, 2017 14:50
-
-
Save t-mat/8a49185147bae6a4dc4b6be0d5611aa5 to your computer and use it in GitHub Desktop.
Revisions
-
t-mat created this gist
Dec 7, 2017 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,214 @@ /* Pixel Pixel frequency 25.175M Hz Seconds per pixel 1/25.175M = 39.72194637537239324727 ns HSYNC ... --|-- HActive video (640pix) --|-- HFront porch (16pix) --| |-- HPulse (96pix) --|-- HBack porch (48pix) --|-- HActive video (640pix) --|-- HFront porch (16pix) --| |-- HPulse (96pix) --|-- HBack porch (48pix) --|-- ... HPulse[0,95]: 96pix, 3.813us = 3813.30685ns All video pins should be LOW. H-Sync pin should be LOW. HBack porch[96,143]: 48pix, 1.906us = 1906.653ns All video pins should be LOW. H-Sync pin should be HIGH. HActive video[144,783]: 640pix, 25422.0 ns = 25.422 us All video pins can be used for video signal. H-Sync pin should be HIGH. HFront porch[784,799]: 16pix, 635.55ns = 0.636 us All video pins should be LOW. H-Sync pin should be HIGH. Total: 800pix, 31777.55710029791459781529 ns = 31.778 us VSYNC ... --|-- VActive video (480lines) --|-- VFront porch (10lines) --| |-- VPulse (2lines) --|-- VBack porch (33lines) --|-- VActive video (480lines) --|-- VFront porch (10lines) --| |-- VPulse (2lines) --|-- VBack porch (33lines) --|-- ... VPulse[0,1]: 2 lines, 0.063555114200596 ms All video pins should be LOW V-Sync pin should be LOW VBack porch[2,34]: 33 lines, 1.0486593843098 ms All video pins should be LOW V-Sync pin should be HIGH Active video[35,514]: 480 lines, 15.253227408143 ms All video pins can be used for video signal. V-Sync pin should be HIGH VFront porch[515,524]: 10 lines, 0.31777557100298 ms All video pins should be LOW V-Sync pin should be HIGH Total: 525 lines, 16.683217477656 (59.94Hz) */ /////////////////////////////////////////////////////////////////////////// namespace Pins { const int vSync = 18; // VSYNC white GPIO18 const int hSync = 19; // HSYNC gray GPIO19 const int red = 25; // R red GPIO25 const int green = 33; // G green GPIO33 const int blue = 32; // B blue GPIO32 const int led = LED_BUILTIN; // Builtin LED GPIO2 } /////////////////////////////////////////////////////////////////////////// inline void SetGpioByMask(uint32_t port, uint32_t maskPattern) { if(port == 0) { * (volatile uint32_t*) GPIO_OUT_W1TS_REG = (uint32_t) maskPattern; } else { * (volatile uint32_t*) GPIO_OUT1_W1TS_REG = (uint32_t) maskPattern; } } inline void ClearGpioByMask(uint32_t port, uint32_t maskPattern) { if(port == 0) { * (volatile uint32_t*) GPIO_OUT_W1TC_REG = maskPattern; } else { * (volatile uint32_t*) GPIO_OUT1_W1TC_REG = maskPattern; } } inline void SetGpio(uint32_t ioNumber) { if(ioNumber <= 31) { SetGpioByMask(0, 1 << ioNumber); } else { SetGpioByMask(1, 1 << (ioNumber-32)); } } inline void ClearGpio(uint32_t ioNumber) { if(ioNumber <= 31) { ClearGpioByMask(0, 1 << ioNumber); } else { ClearGpioByMask(1, 1 << (ioNumber-32)); } } inline void digitalWriteFast(uint32_t ioNumber, int isHigh) { if(isHigh) { SetGpio(ioNumber); } else { ClearGpio(ioNumber); } } /////////////////////////////////////////////////////////////////////////// const double cycleCounterRate = 240.0 * 1000.0 * 1000.0; // 240M Cycles/sec const double cycleCountPerSecond = cycleCounterRate; const double cycleCountPerMillisecond = cycleCounterRate / (1000.0); const double cycleCountPerMicrosecond = cycleCounterRate / (1000.0 * 1000.0); const double cycleCountPerNanosecond = cycleCounterRate / (1000.0 * 1000.0 * 1000.0); const double PixelFrequency = 25.175 * 1000.0 * 1000.0; // 25.175M Hz const double SecondsPerPixel = 1.0 / PixelFrequency; static uint32_t originOfLine; static inline uint32_t getCycleCount() { uint32_t ccount; __asm__ __volatile__("esync; rsr %0,ccount":"=a" (ccount)); return ccount; } inline void beginPixels() { originOfLine = getCycleCount(); } template<uint32_t X> inline void waitForPixels() { const uint64_t th = static_cast<uint32_t>(X * SecondsPerPixel * cycleCountPerSecond); while(getCycleCount() - originOfLine < th) {} } /////////////////////////////////////////////////////////////////////////// void setup() { Serial.begin(115200); Serial.printf("System FREQ = %d MHz\n", ESP.getCpuFreqMHz()); Serial.printf("Pins::vSync = %d\n", Pins::vSync); Serial.printf("Pins::hSync = %d\n", Pins::hSync); Serial.printf("Pins::red = %d\n", Pins::red); Serial.printf("Pins::green = %d\n", Pins::green); Serial.printf("Pins::blue = %d\n", Pins::blue); Serial.printf("Pins::led = %d\n", Pins::led); pinMode(Pins::hSync , OUTPUT); pinMode(Pins::vSync , OUTPUT); pinMode(Pins::red , OUTPUT); pinMode(Pins::green , OUTPUT); pinMode(Pins::blue , OUTPUT); pinMode(Pins::led , OUTPUT); digitalWrite(Pins::hSync, HIGH); digitalWrite(Pins::vSync, HIGH); digitalWrite(Pins::red , LOW); digitalWrite(Pins::green, LOW); digitalWrite(Pins::blue , LOW); digitalWrite(Pins::led , HIGH); for(int i = 0; i < 31; ++i) { ESP_INTR_DISABLE(i); } } /////////////////////////////////////////////////////////////////////////// void loop() { int vCount = 0; for(;;) { digitalWriteFast(Pins::led, (++vCount >> 5) & 1 ? HIGH : LOW); for(int h = 0; h < 525; ++h) { beginPixels(); // Set HSYNC pulse digitalWriteFast(Pins::hSync, LOW); if(h == 0) { digitalWriteFast(Pins::vSync, LOW); } else if(h == 2) { digitalWriteFast(Pins::vSync, HIGH); } // HSYNC Pulse (96pixels, 3.813us = 3813.30685ns) waitForPixels<96>(); // End of HSYNC pulse digitalWriteFast(Pins::hSync, HIGH); // Wait for Horizontal Backporch timing waitForPixels<96 + 48>(); // We can send video signal within [35,514] lines if(h >= 2+33 && h < 2+33+480) { const int c = (h - (2+33)) / 8; digitalWriteFast(Pins::red , c & 1 ? HIGH : LOW); digitalWriteFast(Pins::green , c & 2 ? HIGH : LOW); digitalWriteFast(Pins::blue , c & 4 ? HIGH : LOW); } // Wait for Horizontal backporch timing waitForPixels<96 + 48 + 640>(); // Horizontal Backporch (48pixels, 2us) digitalWriteFast(Pins::red , LOW); digitalWriteFast(Pins::green , LOW); digitalWriteFast(Pins::blue , LOW); // Horizontal sync timing waitForPixels<800>(); } } }