void max7456ReInit(void) { uint8_t srdata = 0; static bool firstInit = true; __spiBusTransactionBegin(busdev); switch (videoSignalCfg) { case VIDEO_SYSTEM_PAL: videoSignalReg = VIDEO_MODE_PAL | OSD_ENABLE; break; case VIDEO_SYSTEM_NTSC: videoSignalReg = VIDEO_MODE_NTSC | OSD_ENABLE; break; case VIDEO_SYSTEM_AUTO: srdata = max7456Send(MAX7456ADD_STAT, 0x00); if (VIN_IS_NTSC(srdata)) { videoSignalReg = VIDEO_MODE_NTSC | OSD_ENABLE; } else if (VIN_IS_PAL(srdata)) { videoSignalReg = VIDEO_MODE_PAL | OSD_ENABLE; } else { // No valid input signal, fallback to default (XXX NTSC for now) videoSignalReg = VIDEO_MODE_NTSC | OSD_ENABLE; } break; } if (videoSignalReg & VIDEO_MODE_PAL) { //PAL maxScreenSize = VIDEO_BUFFER_CHARS_PAL; } else { // NTSC maxScreenSize = VIDEO_BUFFER_CHARS_NTSC; } // Set all rows to same charactor black/white level max7456Brightness(0, 2); // Re-enable MAX7456 (last function call disables it) __spiBusTransactionBegin(busdev); // Make sure the Max7456 is enabled max7456Send(MAX7456ADD_VM0, videoSignalReg); max7456Send(MAX7456ADD_HOS, hosRegValue); max7456Send(MAX7456ADD_VOS, vosRegValue); max7456Send(MAX7456ADD_DMM, displayMemoryModeReg | CLEAR_DISPLAY); __spiBusTransactionEnd(busdev); // Clear shadow to force redraw all screen in non-dma mode. memset(shadowBuffer, 0, maxScreenSize); if (firstInit) { max7456DrawScreenSlow(); firstInit = false; } }
void max7456ReInitIfRequired(void) { static uint32_t lastSigCheckMs = 0; static uint32_t videoDetectTimeMs = 0; static uint16_t reInitCount = 0; __spiBusTransactionBegin(busdev); const uint8_t stallCheck = max7456Send(MAX7456ADD_VM0|MAX7456ADD_READ, 0x00); __spiBusTransactionEnd(busdev); const timeMs_t nowMs = millis(); if (stallCheck != videoSignalReg) { max7456ReInit(); } else if ((videoSignalCfg == VIDEO_SYSTEM_AUTO) && ((nowMs - lastSigCheckMs) > MAX7456_SIGNAL_CHECK_INTERVAL_MS)) { // Adjust output format based on the current input format. __spiBusTransactionBegin(busdev); const uint8_t videoSense = max7456Send(MAX7456ADD_STAT, 0x00); __spiBusTransactionEnd(busdev); DEBUG_SET(DEBUG_MAX7456_SIGNAL, DEBUG_MAX7456_SIGNAL_MODEREG, videoSignalReg & VIDEO_MODE_MASK); DEBUG_SET(DEBUG_MAX7456_SIGNAL, DEBUG_MAX7456_SIGNAL_SENSE, videoSense & 0x7); DEBUG_SET(DEBUG_MAX7456_SIGNAL, DEBUG_MAX7456_SIGNAL_ROWS, max7456GetRowsCount()); if (videoSense & STAT_LOS) { videoDetectTimeMs = 0; } else { if ((VIN_IS_PAL(videoSense) && VIDEO_MODE_IS_NTSC(videoSignalReg)) || (VIN_IS_NTSC_alt(videoSense) && VIDEO_MODE_IS_PAL(videoSignalReg))) { if (videoDetectTimeMs) { if (millis() - videoDetectTimeMs > VIDEO_SIGNAL_DEBOUNCE_MS) { max7456ReInit(); DEBUG_SET(DEBUG_MAX7456_SIGNAL, DEBUG_MAX7456_SIGNAL_REINIT, ++reInitCount); } } else { // Wait for signal to stabilize videoDetectTimeMs = millis(); } } } lastSigCheckMs = nowMs; } //------------ end of (re)init------------------------------------- }
void max7456DrawScreen(void) { uint8_t stallCheck; uint8_t videoSense; static uint32_t lastSigCheckMs = 0; uint32_t nowMs; static uint32_t videoDetectTimeMs = 0; static uint16_t pos = 0; int k = 0, buff_len=0; if (!max7456Lock && !fontIsLoading) { // (Re)Initialize MAX7456 at startup or stall is detected. max7456Lock = true; ENABLE_MAX7456; stallCheck = max7456Send(MAX7456ADD_VM0|MAX7456ADD_READ, 0x00); DISABLE_MAX7456; nowMs = millis(); if (stallCheck != videoSignalReg) { max7456ReInit(); } else if ((videoSignalCfg == VIDEO_SYSTEM_AUTO) && ((nowMs - lastSigCheckMs) > MAX7456_SIGNAL_CHECK_INTERVAL_MS)) { // Adjust output format based on the current input format. ENABLE_MAX7456; videoSense = max7456Send(MAX7456ADD_STAT, 0x00); DISABLE_MAX7456; #ifdef DEBUG_MAX7456_SIGNAL debug[0] = videoSignalReg & VIDEO_MODE_MASK; debug[1] = videoSense & 0x7; debug[3] = max7456GetRowsCount(); #endif if (videoSense & STAT_LOS) { videoDetectTimeMs = 0; } else { if ((VIN_IS_PAL(videoSense) && VIDEO_MODE_IS_NTSC(videoSignalReg)) || (VIN_IS_NTSC_alt(videoSense) && VIDEO_MODE_IS_PAL(videoSignalReg))) { if (videoDetectTimeMs) { if (millis() - videoDetectTimeMs > VIDEO_SIGNAL_DEBOUNCE_MS) { max7456ReInit(); #ifdef DEBUG_MAX7456_SIGNAL debug[2]++; #endif } } else { // Wait for signal to stabilize videoDetectTimeMs = millis(); } } } lastSigCheckMs = nowMs; } //------------ end of (re)init------------------------------------- for (k=0; k< MAX_CHARS2UPDATE; k++) { if (screenBuffer[pos] != shadowBuffer[pos]) { spiBuff[buff_len++] = MAX7456ADD_DMAH; spiBuff[buff_len++] = pos >> 8; spiBuff[buff_len++] = MAX7456ADD_DMAL; spiBuff[buff_len++] = pos & 0xff; spiBuff[buff_len++] = MAX7456ADD_DMDI; spiBuff[buff_len++] = screenBuffer[pos]; shadowBuffer[pos] = screenBuffer[pos]; k++; } if (++pos >= maxScreenSize) { pos = 0; break; } }
void max7456ReInit(void) { uint8_t maxScreenRows; uint8_t srdata = 0; uint16_t x; static bool firstInit = true; ENABLE_MAX7456; switch(videoSignalCfg) { case VIDEO_SYSTEM_PAL: videoSignalReg = VIDEO_MODE_PAL | OSD_ENABLE; break; case VIDEO_SYSTEM_NTSC: videoSignalReg = VIDEO_MODE_NTSC | OSD_ENABLE; break; case VIDEO_SYSTEM_AUTO: srdata = max7456Send(MAX7456ADD_STAT, 0x00); if (VIN_IS_NTSC(srdata)) { videoSignalReg = VIDEO_MODE_NTSC | OSD_ENABLE; } else if (VIN_IS_PAL(srdata)) { videoSignalReg = VIDEO_MODE_PAL | OSD_ENABLE; } else { // No valid input signal, fallback to default (XXX NTSC for now) videoSignalReg = VIDEO_MODE_NTSC | OSD_ENABLE; } break; } if (videoSignalReg & VIDEO_MODE_PAL) { //PAL maxScreenSize = VIDEO_BUFFER_CHARS_PAL; maxScreenRows = VIDEO_LINES_PAL; } else { // NTSC maxScreenSize = VIDEO_BUFFER_CHARS_NTSC; maxScreenRows = VIDEO_LINES_NTSC; } // Set all rows to same charactor black/white level. for(x = 0; x < maxScreenRows; x++) { max7456Send(MAX7456ADD_RB0 + x, BWBRIGHTNESS); } // Make sure the Max7456 is enabled max7456Send(MAX7456ADD_VM0, videoSignalReg); max7456Send(MAX7456ADD_HOS, hosRegValue); max7456Send(MAX7456ADD_VOS, vosRegValue); max7456Send(MAX7456ADD_DMM, CLEAR_DISPLAY); DISABLE_MAX7456; // Clear shadow to force redraw all screen in non-dma mode. memset(shadowBuffer, 0, maxScreenSize); if (firstInit) { max7456RefreshAll(); firstInit = false; } }