mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-23 00:05:33 +03:00
MAX7456: Detect video standard dynamically
This commit is contained in:
parent
2c4e399ca1
commit
457afbcaf0
1 changed files with 93 additions and 19 deletions
|
@ -37,9 +37,8 @@
|
|||
#include "max7456.h"
|
||||
#include "max7456_symbols.h"
|
||||
|
||||
|
||||
|
||||
//MAX7456 opcodes
|
||||
//XXX These are not opcodes but reg addrs. Substitute with MAX7456ADD_xxx.
|
||||
#define DMM_REG 0x04
|
||||
#define DMAH_REG 0x05
|
||||
#define DMAL_REG 0x06
|
||||
|
@ -52,15 +51,21 @@
|
|||
#define MAX7456_RESET 0x02
|
||||
#define VERTICAL_SYNC_NEXT_VSYNC 0x04
|
||||
#define OSD_ENABLE 0x08
|
||||
|
||||
#define SYNC_MODE_AUTO 0x00
|
||||
#define SYNC_MODE_INTERNAL 0x30
|
||||
#define SYNC_MODE_EXTERNAL 0x20
|
||||
|
||||
#define VIDEO_MODE_PAL 0x40
|
||||
#define VIDEO_MODE_NTSC 0x00
|
||||
#define VIDEO_MODE_MASK 0x40
|
||||
#define VIDEO_MODE_IS_PAL(val) (((val) & VIDEO_MODE_MASK) == VIDEO_MODE_PAL)
|
||||
#define VIDEO_MODE_IS_NTSC(val) (((val) & VIDEO_MODE_MASK) == VIDEO_MODE_NTSC)
|
||||
|
||||
#define VIDEO_SIGNAL_DEBOUNCE_MS 100 // Time to wait for input to stabilize
|
||||
|
||||
// video mode register 1 bits
|
||||
|
||||
|
||||
// duty cycle is on_off
|
||||
#define BLINK_DUTY_CYCLE_50_50 0x00
|
||||
#define BLINK_DUTY_CYCLE_33_66 0x01
|
||||
|
@ -85,9 +90,33 @@
|
|||
|
||||
#define BACKGROUND_MODE_GRAY 0x40
|
||||
|
||||
//MAX7456 commands
|
||||
// STAT register bits
|
||||
|
||||
#define STAT_PAL 0x01
|
||||
#define STAT_NTSC 0x02
|
||||
#define STAT_LOS 0x04
|
||||
#define STAT_NVR_BUSY 0x20
|
||||
|
||||
#define STAT_IS_PAL(val) ((val) & STAT_PAL)
|
||||
#define STAT_IS_NTSC(val) ((val) & STAT_NTSC)
|
||||
#define STAT_IS_LOS(val) ((val) & STAT_LOS)
|
||||
|
||||
#define VIN_IS_PAL(val) (!STAT_IS_LOS(val) && STAT_IS_PAL(val))
|
||||
#define VIN_IS_NTSC(val) (!STAT_IS_LOS(val) && STAT_IS_NTSC(val))
|
||||
|
||||
// Kluege warning!
|
||||
// There are occasions that NTSC is not detected even with !LOS (AB7456 specific?)
|
||||
// When this happens, lower 3 bits of STAT register is read as zero.
|
||||
// To cope with this case, this macro defines !LOS && !PAL as NTSC.
|
||||
// Should be compatible with MAX7456 and non-problematic case.
|
||||
|
||||
#define VIN_IS_NTSC_alt(val) (!STAT_IS_LOS(val) && !STAT_IS_PAL(val))
|
||||
|
||||
// DMM special bits
|
||||
#define CLEAR_DISPLAY 0x04
|
||||
#define CLEAR_DISPLAY_VERT 0x06
|
||||
|
||||
// Special address for terminating incremental write
|
||||
#define END_STRING 0xff
|
||||
|
||||
|
||||
|
@ -125,7 +154,6 @@
|
|||
|
||||
#define NVM_RAM_SIZE 54
|
||||
#define WRITE_NVR 0xA0
|
||||
#define STATUS_REG_NVR_BUSY 0x20
|
||||
|
||||
/** Line multiples, for convenience & one less op at runtime **/
|
||||
#define LINE 30
|
||||
|
@ -147,12 +175,6 @@
|
|||
#define LINE16 450
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//on shared SPI buss we want to change clock for OSD chip and restore for other devices
|
||||
#ifdef MAX7456_SPI_CLK
|
||||
#define ENABLE_MAX7456 {spiSetDivisor(MAX7456_SPI_INSTANCE, MAX7456_SPI_CLK);IOLo(max7456CsPin);}
|
||||
|
@ -315,8 +337,12 @@ uint8_t max7456GetRowsCount(void)
|
|||
return (videoSignalReg & VIDEO_MODE_PAL) ? VIDEO_LINES_PAL : VIDEO_LINES_NTSC;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// XXX Remove this comment, too.
|
||||
//because MAX7456 need some time to detect video system etc. we need to wait for a while to initialize it at startup
|
||||
//and in case of restart we need to reinitialize chip
|
||||
#endif
|
||||
|
||||
void max7456ReInit(void)
|
||||
{
|
||||
uint8_t maxScreenRows;
|
||||
|
@ -324,9 +350,13 @@ void max7456ReInit(void)
|
|||
uint16_t x;
|
||||
static bool firstInit = true;
|
||||
|
||||
#if 0
|
||||
// XXX We don't have to wait for the cam any more.
|
||||
// XXX Remove this when everything is stable.
|
||||
//do not init MAX before camera power up correctly
|
||||
if (millis() < 1500)
|
||||
return;
|
||||
#endif
|
||||
|
||||
ENABLE_MAX7456;
|
||||
|
||||
|
@ -334,15 +364,22 @@ void max7456ReInit(void)
|
|||
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 ((0x02 & srdata) == 0x02)
|
||||
|
||||
if (VIN_IS_NTSC(srdata)) {
|
||||
videoSignalReg = VIDEO_MODE_NTSC | OSD_ENABLE;
|
||||
else
|
||||
} 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;
|
||||
}
|
||||
|
||||
|
@ -436,22 +473,60 @@ bool max7456DmaInProgres(void)
|
|||
}
|
||||
#endif
|
||||
|
||||
#include "build/debug.h"
|
||||
|
||||
void max7456DrawScreen(void)
|
||||
{
|
||||
uint8_t check;
|
||||
uint8_t stallCheck;
|
||||
uint8_t videoSense;
|
||||
static uint32_t videoDetectTimeMs = 0;
|
||||
static uint16_t pos = 0;
|
||||
int k = 0, buff_len=0;
|
||||
|
||||
if (!max7456Lock && !fontIsLoading) {
|
||||
//-----------------detect MAX7456 fail, or initialize it at startup when it is ready--------
|
||||
|
||||
// Detect MAX7456 fail, or initialize it at startup when it is ready
|
||||
|
||||
max7456Lock = true;
|
||||
ENABLE_MAX7456;
|
||||
check = max7456Send(VM0_REG | 0x80, 0x00);
|
||||
stallCheck = max7456Send(VM0_REG | 0x80, 0x00);
|
||||
DISABLE_MAX7456;
|
||||
|
||||
if ( check != videoSignalReg)
|
||||
if (stallCheck != videoSignalReg) {
|
||||
max7456ReInit();
|
||||
|
||||
} else if (videoSignalCfg == VIDEO_SYSTEM_AUTO) {
|
||||
|
||||
// Adjust output format based on the current input format.
|
||||
|
||||
ENABLE_MAX7456;
|
||||
videoSense = max7456Send(MAX7456ADD_STAT, 0x00);
|
||||
DISABLE_MAX7456;
|
||||
|
||||
debug[0] = videoSignalReg & VIDEO_MODE_MASK;
|
||||
debug[1] = videoSense & 0x7;
|
||||
debug[3] = max7456GetRowsCount();
|
||||
|
||||
if (videoSense & STAT_LOS) {
|
||||
videoDetectTimeMs = 0;
|
||||
} else {
|
||||
// There is a case that NTSC is not detected for some reason (AB7456 specific?)
|
||||
// Here we force NTSC detection if not LOS and not PAL.
|
||||
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[2]++;
|
||||
}
|
||||
} else {
|
||||
// Wait for signal to stabilize
|
||||
videoDetectTimeMs = millis();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//------------ end of (re)init-------------------------------------
|
||||
|
||||
for (k=0; k< MAX_CHARS2UPDATE; k++) {
|
||||
|
@ -545,12 +620,11 @@ void max7456WriteNvm(uint8_t char_address, const uint8_t *font_data)
|
|||
max7456Send(MAX7456ADD_CMM, WRITE_NVR);
|
||||
|
||||
// wait until bit 5 in the status register returns to 0 (12ms)
|
||||
while ((max7456Send(MAX7456ADD_STAT, 0x00) & STATUS_REG_NVR_BUSY) != 0x00);
|
||||
while ((max7456Send(MAX7456ADD_STAT, 0x00) & STAT_NVR_BUSY) != 0x00);
|
||||
|
||||
DISABLE_MAX7456;
|
||||
|
||||
max7456Lock = false;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue