MAX7456: Support delayed initialization

This allows the init sequence to correctly determine and store that
the selected display device after autoselection was MAX7456 but it
hasn't been yet initialized, and allows us to properly transmit this
information to the configurator.

This also lets the display subsystem initialize the MAX7456 at any
time, so for example in flight controllers that require battery power
in order to turn on the MAX7456, the user can plug the battery after
powering the system up via USB and the MAX7456 will be detected shortly
after without having to reboot.
This commit is contained in:
Alberto García Hierro 2020-06-24 23:56:32 +01:00
parent d85b372ae7
commit db0e1e7788
3 changed files with 44 additions and 14 deletions

View File

@ -450,7 +450,7 @@ void max7456PreInit(const max7456Config_t *max7456Config)
// Here we init only CS and try to init MAX for first time.
// Also detect device type (MAX v.s. AT)
bool max7456Init(const max7456Config_t *max7456Config, const vcdProfile_t *pVcdProfile, bool cpuOverclock)
max7456InitStatus_e max7456Init(const max7456Config_t *max7456Config, const vcdProfile_t *pVcdProfile, bool cpuOverclock)
{
max7456DeviceDetected = false;
@ -462,13 +462,13 @@ bool max7456Init(const max7456Config_t *max7456Config, const vcdProfile_t *pVcdP
max7456HardwareReset();
if (!max7456Config->csTag || !max7456Config->spiDevice) {
return false;
return MAX7456_INIT_NOT_CONFIGURED;
}
busdev->busdev_u.spi.csnPin = IOGetByTag(max7456Config->csTag);
if (!IOIsFreeOrPreinit(busdev->busdev_u.spi.csnPin)) {
return false;
return MAX7456_INIT_NOT_CONFIGURED;
}
IOInit(busdev->busdev_u.spi.csnPin, OWNER_OSD_CS, 0);
@ -492,7 +492,7 @@ bool max7456Init(const max7456Config_t *max7456Config, const vcdProfile_t *pVcdP
if (osdm != 0x1B) {
IOConfigGPIO(busdev->busdev_u.spi.csnPin, IOCFG_IPU);
return false;
return MAX7456_INIT_NOT_FOUND;
}
// At this point, we can claim the ownership of the CS pin
@ -560,7 +560,7 @@ bool max7456Init(const max7456Config_t *max7456Config, const vcdProfile_t *pVcdP
#endif
// Real init will be made later when driver detect idle.
return true;
return MAX7456_INIT_OK;
}
/**

View File

@ -20,6 +20,8 @@
#pragma once
#include <stdint.h>
#include "drivers/display.h"
/** PAL or NTSC, value is number of chars total */
@ -28,12 +30,23 @@
#define VIDEO_LINES_NTSC 13
#define VIDEO_LINES_PAL 16
typedef enum {
// IO defined and MAX7456 was detected
MAX7456_INIT_OK = 0,
// IO defined, but MAX7456 could not be detected (maybe not yet
// powered on)
MAX7456_INIT_NOT_FOUND = -1,
// No MAX7456 IO defined, which means either the we don't have it or
// it's not properly configured
MAX7456_INIT_NOT_CONFIGURED = -2,
} max7456InitStatus_e;
extern uint16_t maxScreenSize;
struct vcdProfile_s;
void max7456HardwareReset(void);
struct max7456Config_s;
void max7456PreInit(const struct max7456Config_s *max7456Config);
bool max7456Init(const struct max7456Config_s *max7456Config, const struct vcdProfile_s *vcdProfile, bool cpuOverclock);
max7456InitStatus_e max7456Init(const struct max7456Config_s *max7456Config, const struct vcdProfile_s *vcdProfile, bool cpuOverclock);
void max7456Invert(bool invert);
void max7456Brightness(uint8_t black, uint8_t white);
void max7456DrawScreen(void);

View File

@ -168,7 +168,15 @@ static bool isReady(displayPort_t *instance)
{
UNUSED(instance);
return max7456IsDeviceDetected();
if (!max7456IsDeviceDetected()) {
// Try to initialize the device
if (max7456Init(max7456Config(), vcdProfile(), systemConfig()->cpu_overclock) != MAX7456_INIT_OK) {
return false;
}
// At this point the device has been initialized and detected
resync(&max7456DisplayPort);
}
return true;
}
static const displayPortVTable_t max7456VTable = {
@ -193,15 +201,24 @@ static const displayPortVTable_t max7456VTable = {
displayPort_t *max7456DisplayPortInit(const vcdProfile_t *vcdProfile)
{
if (
!max7456Init(max7456Config(), vcdProfile, systemConfig()->cpu_overclock)
) {
switch (max7456Init(max7456Config(), vcdProfile, systemConfig()->cpu_overclock)) {
case MAX7456_INIT_NOT_FOUND:
// MAX7456 IO pins are defined, but we could not get a reply
// from it at this time. Delay full initialization to
// isReady()
displayInit(&max7456DisplayPort, &max7456VTable);
break;
case MAX7456_INIT_OK:
// MAX7456 configured and detected
displayInit(&max7456DisplayPort, &max7456VTable);
resync(&max7456DisplayPort);
break;
case MAX7456_INIT_NOT_CONFIGURED:
// MAX7456 IO pins are not defined. We either don't have
// it on board or either the configuration for it has
// not been set.
return NULL;
}
displayInit(&max7456DisplayPort, &max7456VTable);
resync(&max7456DisplayPort);
return &max7456DisplayPort;
}
#endif // USE_MAX7456