void SlideShow::Draw(wxPoint point) { Cell::Draw(point); // If the animation leaves the screen the timer is stopped automatically. if(m_animationRunning) ReloadTimer(); if (DrawThisCell(point) && (m_images[m_displayed] != NULL)) { // Start the timer once the animation appears on the screen. // But start it only once: Else the animation could be refreshed // more frequent than it can be drawn. Each update of the animation // will trigger this function and will trigger the animation to be // restarted anyway. // Configuration *configuration = (*m_configuration); if(configuration->GetPrinting()) { m_images[m_displayed]->Recalculate(configuration->GetZoomFactor() * PRINT_SIZE_MULTIPLIER); } else { m_images[m_displayed]->Recalculate(); } if (!InUpdateRegion()) return; wxDC *dc = configuration->GetDC(); wxMemoryDC bitmapDC; // Slide show cells have a red border except if they are selected if (m_drawBoundingBox) dc->SetPen(*(wxThePenList->FindOrCreatePen(configuration->GetColor(TS_SELECTION)))); else dc->SetPen(*wxRED_PEN); dc->DrawRectangle(wxRect(point.x, point.y - m_center, m_width, m_height)); wxBitmap bitmap = (configuration->GetPrinting() ? m_images[m_displayed]->GetBitmap(configuration->GetZoomFactor() * PRINT_SIZE_MULTIPLIER) : m_images[m_displayed]->GetBitmap()); bitmapDC.SelectObject(bitmap); int imageBorderWidth = m_imageBorderWidth; if (m_drawBoundingBox) { imageBorderWidth = Scale_Px(3); dc->SetBrush(*(wxTheBrushList->FindOrCreateBrush(configuration->GetColor(TS_SELECTION)))); dc->DrawRectangle(wxRect(point.x, point.y - m_center, m_width, m_height)); } dc->Blit(point.x + imageBorderWidth, point.y - m_center + imageBorderWidth, m_width - 2 * imageBorderWidth, m_height - 2 * imageBorderWidth, &bitmapDC, imageBorderWidth - m_imageBorderWidth, imageBorderWidth - m_imageBorderWidth); } else // The cell isn't drawn => No need to keep it's image cache for now. ClearCache(); // If we need a selection border on another redraw we will be informed by OnPaint() again. m_drawBoundingBox = false; }
void SlideShow::AnimationRunning(bool run) { if(run) ReloadTimer(); else StopTimer(); m_animationRunning = run; }
void Timer_count() { int i; for (i=0; i<TIMERNUM; i++) { if (ReloadTimer(i)) // 定时到 OnTimer(i); // 定时事件处理 } }
// Set a callback. Pass in NULL to stop it void setTimer1Callback(uint32_t (*fn)()) { timer1CB = fn; if (!timerRunning && fn) { initTimer(); } else if (timerRunning && !fn) { int cnt = 0; for (size_t i = 0; i < countof(waveform); i++) { cnt += waveform[i].enabled ? 1 : 0; } if (!cnt) { deinitTimer(); } } ReloadTimer(MicrosecondsToCycles(1)); // Cause an interrupt post-haste }
SlideShow::SlideShow(Cell *parent, Configuration **config, CellPointers *cellPointers, wxFileSystem *filesystem, int framerate) : Cell( parent, config) { m_cellPointers = cellPointers; m_timer = NULL; m_animationRunning = true; m_size = m_displayed = 0; m_type = MC_TYPE_SLIDE; m_fileSystem = filesystem; // NULL when not loading from wxmx m_framerate = framerate; m_imageBorderWidth = Scale_Px(1); m_drawBoundingBox = false; if(m_animationRunning) ReloadTimer(); }
// Start up a waveform on a pin, or change the current one. Will change to the new // waveform smoothly on next low->high transition. For immediate change, stopWaveform() // first, then it will immediately begin. int startWaveform(uint8_t pin, uint32_t timeHighUS, uint32_t timeLowUS, uint32_t runTimeUS) { Waveform *wave = NULL; for (size_t i = 0; i < countof(waveform); i++) { if (((pin == 16) && waveform[i].gpio16Mask==1) || ((pin != 16) && (waveform[i].gpioMask == 1<<pin))) { wave = (Waveform*) & (waveform[i]); break; } } if (!wave) { return false; } // To safely update the packed bitfields we need to stop interrupts while setting them as we could // get an IRQ in the middle of a multi-instruction mask-and-set required to change them which would // then cause an IRQ update of these values (.enabled only, for now) to be lost. ets_intr_lock(); wave->nextTimeHighCycles = MicrosecondsToCycles(timeHighUS) - 70; // Take out some time for IRQ codepath wave->nextTimeLowCycles = MicrosecondsToCycles(timeLowUS) - 70; // Take out some time for IRQ codepath wave->timeLeftCycles = MicrosecondsToCycles(runTimeUS); if (!wave->enabled) { wave->state = 0; // Actually set the pin high or low in the IRQ service to guarantee times wave->nextServiceCycle = GetCycleCount() + MicrosecondsToCycles(1); wave->enabled = 1; if (!timerRunning) { initTimer(); } ReloadTimer(MicrosecondsToCycles(1)); // Cause an interrupt post-haste } // Re-enable interrupts here since we're done with the update ets_intr_unlock(); return true; }
static ICACHE_RAM_ATTR void timer1Interrupt() { uint32_t nextEventCycles; #if F_CPU == 160000000 uint8_t cnt = 20; #else uint8_t cnt = 10; #endif do { nextEventCycles = MicrosecondsToCycles(MAXIRQUS); for (size_t i = 0; i < countof(waveform); i++) { Waveform *wave = &waveform[i]; uint32_t now; // If it's not on, ignore! if (!wave->enabled) { continue; } // Check for toggles now = GetCycleCount(); int32_t cyclesToGo = wave->nextServiceCycle - now; if (cyclesToGo < 0) { wave->state = !wave->state; if (wave->state) { SetGPIO(wave->gpioMask); if (wave->gpio16Mask) { GP16O |= wave->gpio16Mask; // GPIO16 write slow as it's RMW } wave->nextServiceCycle = now + wave->nextTimeHighCycles; nextEventCycles = min_u32(nextEventCycles, wave->nextTimeHighCycles); } else { ClearGPIO(wave->gpioMask); if (wave->gpio16Mask) { GP16O &= ~wave->gpio16Mask; } wave->nextServiceCycle = now + wave->nextTimeLowCycles; nextEventCycles = min_u32(nextEventCycles, wave->nextTimeLowCycles); } } else { uint32_t deltaCycles = wave->nextServiceCycle - now; nextEventCycles = min_u32(nextEventCycles, deltaCycles); } } } while (--cnt && (nextEventCycles < MicrosecondsToCycles(4))); uint32_t curCycleCount = GetCycleCount(); uint32_t deltaCycles = curCycleCount - lastCycleCount; lastCycleCount = curCycleCount; // Check for timed-out waveforms out of the high-frequency toggle loop for (size_t i = 0; i < countof(waveform); i++) { Waveform *wave = &waveform[i]; if (wave->timeLeftCycles) { // Check for unsigned underflow with new > old if (deltaCycles >= wave->timeLeftCycles) { // Done, remove! wave->enabled = false; ClearGPIO(wave->gpioMask); GP16O &= ~wave->gpio16Mask; } else { uint32_t newTimeLeftCycles = wave->timeLeftCycles - deltaCycles; wave->timeLeftCycles = newTimeLeftCycles; } } } if (timer1CB) { nextEventCycles = min_u32(nextEventCycles, timer1CB()); } #if F_CPU == 160000000 if (nextEventCycles <= 5 * MicrosecondsToCycles(1)) { nextEventCycles = MicrosecondsToCycles(1) / 2; } else { nextEventCycles -= 5 * MicrosecondsToCycles(1); } nextEventCycles = nextEventCycles >> 1; #else if (nextEventCycles <= 6 * MicrosecondsToCycles(1)) { nextEventCycles = MicrosecondsToCycles(1) / 2; } else { nextEventCycles -= 6 * MicrosecondsToCycles(1); } #endif ReloadTimer(nextEventCycles); }