# HG changeset patch # User StephaneLenclud # Date 1423082837 -3600 # Node ID 3fa4007c0b1959eb60e9c6fbc1baf24cc78029ca # Parent 9c233658ab280f30bc0774db48ac81ab7d97e6f9 First draft implementation of Futaba MDM166AA. Only clock and brightness working for now. diff -r 9c233658ab28 -r 3fa4007c0b19 CMakeLists.txt --- a/CMakeLists.txt Wed Feb 04 17:45:46 2015 +0100 +++ b/CMakeLists.txt Wed Feb 04 21:47:17 2015 +0100 @@ -15,6 +15,7 @@ FutabaGP1212.cpp FutabaGP1212A01.cpp FutabaGP1212A02.cpp + FutabaMDM166AA.cpp HidDevice.cpp MiniDisplay.cpp ../../GitHub/hidapi/windows/hid.c) @@ -26,6 +27,7 @@ FutabaGP1212.h FutabaGP1212A01.h FutabaGP1212A02.h + FutabaMDM166AA.h HidDevice.h HidReport.h MiniDisplay.h diff -r 9c233658ab28 -r 3fa4007c0b19 FutabaGP1212A02.cpp --- a/FutabaGP1212A02.cpp Wed Feb 04 17:45:46 2015 +0100 +++ b/FutabaGP1212A02.cpp Wed Feb 04 21:47:17 2015 +0100 @@ -11,7 +11,7 @@ const unsigned short KFrameSizeInBytes = 0x800; -void sleep(unsigned int mseconds) +static void sleep(unsigned int mseconds) { clock_t goal = mseconds + clock(); while (goal > clock()); diff -r 9c233658ab28 -r 3fa4007c0b19 FutabaGP1212A02.h --- a/FutabaGP1212A02.h Wed Feb 04 17:45:46 2015 +0100 +++ b/FutabaGP1212A02.h Wed Feb 04 21:47:17 2015 +0100 @@ -6,14 +6,17 @@ #define FUTABA_GP1212A02_H #include "FutabaGP1212.h" - -#include "FutabaGP1212.h" #include "FutabaVfd.h" /** -GP1212A01A is a graphic display module using a FUTABA 256x64dots VFD. -The module do not include character ROM, the customer will compile the character -by themselves (from main system). +GP1212A02A is a graphic display module using a FUTABA 256x64dots VFD. +The module will support the interface of I2C, RS-232C and USB2.0 communications. +The module include flash ROM (4Mbyte), the customer will definable the BMP data and download +character. +It realizes displaying a Japanese font (refer to Table-24) and BMP by I2C, RS-232C or USB2.0 +communications. Other font tables (ex. Chinese, Korean, European and custom font) can be appended to +flash ROM. +Since a DC/DC converter is included, 5V power source is required to operate the module. */ class GP1212A02A : public GP1212XXXX { diff -r 9c233658ab28 -r 3fa4007c0b19 FutabaMDM166AA.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FutabaMDM166AA.cpp Wed Feb 04 21:47:17 2015 +0100 @@ -0,0 +1,614 @@ +// +// +// + +#include "FutabaMDM166AA.h" + +#include +#include + + + +static void sleep(unsigned int mseconds) + { + clock_t goal = mseconds + clock(); + while (goal > clock()); + } + +// +// class MDM166AA +// + +MDM166AA::MDM166AA(): + iDisplayPositionX(0),iDisplayPositionY(0), + iOffScreenMode(true), + iUseFrameDifferencing(true), + iFrameNext(NULL), + iFrameCurrent(NULL), + iFramePrevious(NULL), + iFrameAlpha(NULL), + iFrameBeta(NULL), + iFrameGamma(NULL), + iNeedFullFrameUpdate(0), + iPowerOn(false) + { + iDeviceId[0]=0; + iFirmwareRevision[0]=0; + //ResetBuffers(); + } + +/** +*/ +MDM166AA::~MDM166AA() + { + delete iFrameAlpha; + iFrameAlpha=NULL; + // + delete iFrameBeta; + iFrameBeta=NULL; + // + delete iFrameGamma; + iFrameGamma=NULL; + // + iFrameNext=NULL; + iFrameCurrent=NULL; + iFramePrevious=NULL; + // + iNeedFullFrameUpdate=0; + } + +/** +*/ +int MDM166AA::Open() + { + int success = HidDevice::Open(KTargaVendorId,KFutabaProductIdMDM166AA,NULL); + if (success) + { + //Allocate both frames + delete iFrameAlpha; + iFrameAlpha=NULL; + iFrameAlpha=new BitArrayLow(KMDM166AAFrameBufferPixelCount); + // + delete iFrameBeta; + iFrameBeta=NULL; + iFrameBeta=new BitArrayLow(KMDM166AAFrameBufferPixelCount); + // + delete iFrameGamma; + iFrameGamma=NULL; + iFrameGamma=new BitArrayLow(KMDM166AAFrameBufferPixelCount); + // + iFrameNext=iFrameAlpha; + iFrameCurrent=iFrameBeta; + iFramePrevious=iFrameGamma; + + + //To make sure it is synced properly + iNeedFullFrameUpdate=0; + // + SetNonBlocking(1); + // + SendCommandClear(); + // + SetClockSetting(); + + } + return success; + } + + +/** +Display RAM filled with 00H. +Address Counter is set by 00H. +Dimming is set to 50%. +*/ +void MDM166AA::SendCommandReset() + { + FutabaVfdReport report; + report[0]=0x00; //Report ID + report[1]=0x01; //Report length. + report[2]=0x1F; //Command ID + Write(report); + //Wait until reset is done. Is that needed? + //sleep(2000); + } + + +/** +Set Address Counter (AC) values: 1BH + 60H + xxH +xxH: 00 ~ BFH +AC value represents the start address for graphic data. +There are 192 bytes as display RAM. It can be set on anywhere even if AC value is not visible area. +The default value is 00H. +Default: 00H +When clock is displayed, AC value is set 00H. +*/ +void MDM166AA::SendCommandSetAddressCounter(unsigned char aAddressCounter) + { + FutabaVfdReport report; + report[0]=0x00; //Report ID + report[1]=0x03; //Report length. + report[2]=0x1B; //Command ID + report[3]=0x60; //Command ID + report[4]=aAddressCounter; + Write(report); + } + + +/** +*/ +void MDM166AA::SetPixel(unsigned char aX, unsigned char aY, unsigned int aPixel) + { + // + //int byteOffset=(aX*HeightInPixels()+aY)/8; + //int bitOffset=(aX*HeightInPixels()+aY)%8; + //iNextFrame[byteOffset] |= ( (aOn?0x01:0x00) << bitOffset ); + + //Pixel is on if any of the non-alpha component is not null + bool on = (aPixel&0x00FFFFFF)!=0x00000000; + + if (iOffScreenMode) + { + if (on) + { + iFrameNext->SetBit(aX*HeightInPixels()+aY); + } + else + { + iFrameNext->ClearBit(aX*HeightInPixels()+aY); + } + } + else + { + //Just specify a one pixel block + //TODO + } + } + +/** +*/ +/* +void MDM166AA::BitBlit(const BitArray& aBitmap, int aSrcWidth, int aSrcHeight, int aTargetX, int aTargetY) const + { + //TODO: amend loop values so that we don't keep on looping past our frame buffer dimensions. + for (int i=0;iSetBitValue((aTargetX+i)*HeightInPixels()+aTargetY+j,aBitmap[+i*aSrcHeight+j]); + } + } + } +*/ + +/** +Clear our client side back buffer. +Call to SwapBuffers must follow to actually clear the display. +*/ +void MDM166AA::Clear() + { + //That one also clear the symbols + SendCommandClear(); + //TODO: Consider just clearing the pixels instead + } + +/** +Turn on all pixels. +Must be followed by a SwapBuffers call. +*/ +void MDM166AA::Fill() + { + SetAllPixels(0xFF); + } + +/** +Set all pixels on our screen to the desired value. +This operation is performed off screen to avoid tearing. +@param 8 pixels pattern +*/ +void MDM166AA::SetAllPixels(unsigned char aPattern) + { + //With a single buffer + //unsigned char screen[2048]; //One screen worth of pixels + //memset(screen,0xFF,sizeof(screen)); + //SetPixelBlock(0,0,63,sizeof(screen),screen); + + + if (iOffScreenMode) + { + memset(iFrameNext->Ptr(),aPattern,FrameBufferSizeInBytes()); + } + else + { + //Using pattern SetPixelBlock variant. + //TODO + } + // + } + + + + + + +/** +Whole display RAM areas including invisible area are filled with 00H data. +(Include the symbol) +SL: Though there is no invisible area with that device. +*/ +void MDM166AA::SendCommandClear() + { + //Send Clear Display Command + FutabaVfdReport report; + report[0]=0x00; //Report ID + report[1]=0x02; //Report length + report[2]=0x1B; //Command ID + report[3]=0x50; //Command ID + Write(report); + } + + +/** +Provide Y coordinate of our off screen buffer. +*/ +unsigned char MDM166AA::OffScreenY() const + { + //Overflowing is fine this is just what we want + return iDisplayPositionY+HeightInPixels(); + } + +/** +Put our off screen buffer on screen. +On screen buffer goes off screen. +*/ +void MDM166AA::SwapBuffers() + { + //Only perform buffer swapping if off screen mode is enabled + if (OffScreenMode()) + { + //Send pixel directly into BMP box + //BmpBoxDataInput(FrameBufferSizeInBytes(),iFrameNext->Ptr()); + //Send pixel data directly into the display window + //BmpDataInput(ETargetDisplayWindow,0x0000,EDirectionY, FrameBufferSizeInBytes(),iFrameNext->Ptr()); + //Send pixel data first to Data Memory then copy into the selected BMP box + //BmpDataInput(ETargetDataMemory,0x0000,EDirectionY, FrameBufferSizeInBytes(),iFrameNext->Ptr()); + //BmpBoxDataMemoryTransfer(0x0000); + //Send pixel data first to Data Memory then copy into the selected BMP box, cycling through our Data Memory frmae + //BmpDataInput(ETargetDataMemory,iNextFrameAddress,EDirectionY, FrameBufferSizeInBytes(),iFrameNext->Ptr()); + //BmpBoxDataMemoryTransfer(iNextFrameAddress); + + + //Cycle through our frame buffers + //We keep track of previous frame which is in fact our device back buffer. + //We can then compare previous and next frame and send only the differences to our device. + //This mechanism allows us to reduce traffic over our USB bus thus improving our frame rate from 14 FPS to 30 FPS. + //Keep our previous frame pointer + BitArrayLow* previousFrame=iFramePrevious; + //Current frame becomes the previous one + iFramePrevious = iFrameCurrent; + //Next frame becomes the current one + iFrameCurrent = iFrameNext; + //Next frame is now our former previous + iFrameNext = previousFrame; + } + } + + +/** +Set the defined pixel block to the given value. +@param X coordinate of our pixel block starting point. +@param Y coordinate of our pixel block starting point. +@param The height of our pixel block. +@param The size of our pixel data. Number of pixels divided by 8. +@param Pointer to our pixel data. +*/ +void MDM166AA::SetPixelBlock(unsigned char aX, unsigned char aY, int aHeight, int aSize, unsigned char* aPixels) + { + //TODO: Assuming 0,0 for now, do the math later + SendCommandSetAddressCounter(0); + + const int KMaxPixelBytes=48; + + FutabaVfdReport report; + report[0]=0x00; //Report ID + report[1]=(aSize<=report.Size()-10?aSize+0x08:64); //Report length. -10 is for our header first 10 bytes. +8 is for our Futaba header size + report[2]=0x1B; //Command ID + report[3]=0x70; //Command ID + //TODO: All rubbish + report[4]=MAX(KMaxPixelBytes,aSize); //Size of pixel data in bytes + int sizeWritten=MIN(aSize,report.Size()-10); + memcpy(report.Buffer()+10, aPixels, sizeWritten); + Write(report); + + int remainingSize=aSize; + //We need to keep on sending our pixel data until we are done + while (report[1]==64) + { + report.Reset(); + remainingSize-=sizeWritten; + report[0]=0x00; //Report ID + report[1]=(remainingSize<=report.Size()-2?remainingSize:64); //Report length, should be 64 or the remaining size + sizeWritten=(report[1]==64?63:report[1]); + memcpy(report.Buffer()+2, aPixels+(aSize-remainingSize), sizeWritten); + Write(report); + } + } + + + +//Define the edge of our pixel block +//Pixel blocks of 32x32 seems to run almost as fast as full screen update in worse case scenarii. +//Though I wonder if in some situations 16 could be better. Make this an attribute at some point if need be. +const int KPixelBlockEdge = 32; +const int KPixelBlockSizeInBits = KPixelBlockEdge*KPixelBlockEdge; +const int KPixelBlockSizeInBytes = KPixelBlockSizeInBits/8; + + +/** +Translate the given pixel coordinate according to our off screen mode. +*/ +void MDM166AA::OffScreenTranslation(unsigned char& aX, unsigned char& aY) + { + if (OffScreenMode()) + { + aX+=WidthInPixels()-iDisplayPositionX; + aY+=HeightInPixels()-iDisplayPositionY; + } + } + + +/** +*/ +void MDM166AA::Request(TMiniDisplayRequest aRequest) + { + switch (aRequest) + { + case EMiniDisplayRequestDeviceId: + RequestDeviceId(); + break; + case EMiniDisplayRequestFirmwareRevision: + RequestFirmwareRevision(); + break; + case EMiniDisplayRequestPowerSupplyStatus: + RequestPowerSupplyStatus(); + break; + default: + //Not supported + break; + }; + } + + +/** +*/ +void MDM166AA::ResetBuffers() + { + //iNextFrame->ClearAll(); + //memset(iFrameAlpha,0x00,sizeof(iFrameAlpha)); + //memset(iFrameBeta,0x00,sizeof(iFrameBeta)); + } + +/** +*/ +void MDM166AA::RequestDeviceId() + { + //Not supported + } + +/** +ID code +[Code] 1BH,6AH,49H,44H +[Function] Send the ID code to the Host system. ID code is software version. +*/ +void MDM166AA::RequestFirmwareRevision() + { + if (RequestPending()) + { + //Abort silently for now + return; + } + + //1BH,6AH,49H,44H + //Send Software Revision Read Command + FutabaVfdReport report; + report[0]=0x00; //Report ID + report[1]=0x04; //Report length + report[2]=0x1B; //Command ID + report[3]=0x6A; //Command ID + report[4]=0x49; //Command ID + report[5]=0x44; //Command ID + if (Write(report)==report.Size()) + { + SetRequest(EMiniDisplayRequestFirmwareRevision); + } + + } + +/** +*/ +void MDM166AA::RequestPowerSupplyStatus() + { + //Not supported + } + + +/** +This is for development purposes only. +Production application should stick to off-screen mode to avoid tearing. +*/ +void MDM166AA::ToggleOffScreenMode() + { + SetOffScreenMode(!iOffScreenMode); + } + +/** + * @brief MDM166AA::SetOffScreenMode + * @param aOn + * @return + */ +void MDM166AA::SetOffScreenMode(bool aOn) + { + if (aOn==iOffScreenMode) + { + //Nothing to do here + return; + } + + iOffScreenMode=aOn; + + //Clean up our buffers upon switching modes + Clear(); + SwapBuffers(); + Clear(); + } + +/** +Tries to complete our current request if we have one pending. + */ +TMiniDisplayRequest MDM166AA::AttemptRequestCompletion() + { + if (!RequestPending()) + { + return EMiniDisplayRequestNone; + } + + int res=Read(iInputReport); + + if (!res) + { + return EMiniDisplayRequestNone; + } + + //Process our request + if (CurrentRequest()==EMiniDisplayRequestFirmwareRevision) + { + unsigned char* ptr=&iInputReport[2]; + iInputReport[7]=0x00; + strcpy(iFirmwareRevision,(const char*)ptr); + } + + TMiniDisplayRequest completed=CurrentRequest(); + //Our request was completed + SetRequest(EMiniDisplayRequestNone); + + return completed; + } + + +/** +Set our screen brightness. +@param The desired brightness level. Must be between MinBrightness and MaxBrightness. +*/ +void MDM166AA::SetBrightness(int aBrightness) + { + if (aBrightnessMaxBrightness()) + { + //Brightness out of range. + //Just ignore that request. + return; + } + + FutabaVfdReport report; + report[0]=0x00; //Report ID + report[1]=0x03; //Report size + report[2]=0x1B; //Command ID + report[3]=0x40; //Command ID + report[4]=aBrightness; //Brightness level + Write(report); + } + +/** +*/ +bool MDM166AA::IsPowerOn() + { + return iPowerOn; + } + +/** +*/ +char* MDM166AA::DeviceId() + { + return iDeviceId; + } + +/** +*/ +char* MDM166AA::FirmwareRevision() + { + return iFirmwareRevision; + } + +/** +*/ +void MDM166AA::ShowClock() + { + SendCommandClockDisplay(EClockLarge,EClock24); + SetClockSetting(); + } + +/** +*/ +void MDM166AA::HideClock() + { + //TODO: or reset + Clear(); + } + + +/** +Clock setting +[Code]1BH,00H,Pm,Ph +[Function]Setting the clock data. The setting data is cleared, if the Reset command is input or power is turned off. +Ph = hour +Pm = minute +*/ +void MDM166AA::SendCommandClockSetting(unsigned char aHour, unsigned char aMinute) + { + FutabaVfdReport report; + report[0]=0x00; //Report ID + report[1]=0x04; //Report size + report[2]=0x1B; //Command ID + report[3]=0x00; //Command ID + + //Minutes and Hours needs to be in hexadecimal view + //To get 21:59 you need to pass in 0x21:0x59 + //Weirdest format ever, I know + report[4]=(aMinute/10*16)+aMinute%10; + report[5]=(aHour/10*16)+aHour%10; + + Write(report); + } + + +/** +Set display clock settings according to local system time. +This needs to be redone whenever we open or turn on our display. +*/ +void MDM166AA::SetClockSetting() + { + time_t rawtime; + struct tm * timeinfo; + + time ( &rawtime ); + timeinfo = localtime ( &rawtime ); + // + SendCommandClockSetting(timeinfo->tm_hour,timeinfo->tm_min); + } + + +/** +Clock display +[Code] 1BH,Ps,aL,aH,Pf +[Function] Clock is displayed small or big. +*/ +void MDM166AA::SendCommandClockDisplay(TClockSize aClockSize, TClockFormat aClockFormat) + { + FutabaVfdReport report; + report[0]=0x00; //Report ID + report[1]=0x03; //Report size + report[2]=0x1B; //Command ID + report[3]=aClockSize; // + report[4]=aClockFormat; // + + Write(report); + } + diff -r 9c233658ab28 -r 3fa4007c0b19 FutabaMDM166AA.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FutabaMDM166AA.h Wed Feb 04 21:47:17 2015 +0100 @@ -0,0 +1,140 @@ +// +// +// + +#ifndef FUTABA_MDM166AA_H +#define FUTABA_MDM166AA_H + +#include "FutabaVfd.h" + + +const int KMDM166AAWidthInPixels = 96; +const int KMDM166AAHeightInPixels = 16; +const int KMDM166AAPixelsPerByte = 8; +const int KMDM166AAFrameBufferSizeInBytes = KMDM166AAWidthInPixels*KMDM166AAHeightInPixels/KMDM166AAPixelsPerByte; //96*16/8=192 +const int KMDM166AAFrameBufferPixelCount = KMDM166AAWidthInPixels*KMDM166AAHeightInPixels; + + +/** +MDM166AA is a graphic display module using a FUTABA 96x16dots VFD. +*/ +class MDM166AA : public FutabaGraphicDisplay + { +public: + + MDM166AA(); + ~MDM166AA(); + + //From DisplayBase + virtual int Open(); + virtual void SwapBuffers(); + //Brightness support + virtual int MinBrightness() const {return 0;} + virtual int MaxBrightness() const {return 2;} + virtual void SetBrightness(int aBrightness); + //Clock support + virtual void ShowClock(); + virtual void HideClock(); + virtual bool SupportClock(){return true;} + + //From GraphicDisplay + virtual int WidthInPixels() const {return KMDM166AAWidthInPixels;} + virtual int HeightInPixels() const {return KMDM166AAHeightInPixels;} + + virtual void SetPixel(unsigned char aX, unsigned char aY, unsigned int aPixel); + virtual void SetAllPixels(unsigned char aPattern); + virtual int FrameBufferSizeInBytes() const {return KMDM166AAFrameBufferSizeInBytes;} + virtual void Clear(); + virtual void Fill(); + virtual void Request(TMiniDisplayRequest aRequest); + + // + void ToggleOffScreenMode(); + void SetOffScreenMode(bool aOn); + bool OffScreenMode() const {return iOffScreenMode;} + // + void SetFrameDifferencing(bool aOn){iUseFrameDifferencing=aOn;} + bool FrameDifferencing() const {return iUseFrameDifferencing;} + // + TMiniDisplayRequest AttemptRequestCompletion(); + FutabaVfdReport& InputReport() {return iInputReport;} + bool IsPowerOn(); + char* DeviceId(); + char* FirmwareRevision(); + +private: + + enum TClockFormat + { + EClock12 = 0x00, + EClock24 = 0x01, + }; + + enum TClockSize + { + EClockSmall = 0x01, + EClockLarge = 0x02 + }; + + +private: + //Specific to MDM166AA + //General setting command + void SendCommandClear(); + void SendCommandReset(); + void SendCommandSetAddressCounter(unsigned char aAddressCounter); + //void SendCommandWriteGraphicData(); + // + //Clock commands + void SendCommandClockSetting(unsigned char aHour, unsigned char aMinute); + void SendCommandClockDisplay(TClockSize aClockSize, TClockFormat aClockFormat); + + void SetPixelBlock(unsigned char aX, unsigned char aY, int aHeight, int aSize, unsigned char* aPixels); + +private: + void RequestDeviceId(); + void RequestFirmwareRevision(); + void RequestPowerSupplyStatus(); + // + void SetClockSetting(); + + +private: + unsigned char OffScreenY() const; + void OffScreenTranslation(unsigned char& aX, unsigned char& aY); + void ResetBuffers(); + +private: + unsigned char iDisplayPositionX; + unsigned char iDisplayPositionY; + ///Off screen mode is the recommended default settings to avoid tearing. + ///Though turning it off can be useful for debugging + bool iOffScreenMode; + ///Frame differences algo is used to reduce USB bus traffic and improve frame rate in typical use case + bool iUseFrameDifferencing; + /// + //FutabaVfdReport iReport; + /// + //unsigned char iFrameBuffer[256*64]; + BitArrayLow* iFrameNext; + BitArrayLow* iFrameCurrent; + BitArrayLow* iFramePrevious; + // + BitArrayLow* iFrameAlpha; + BitArrayLow* iFrameBeta; + BitArrayLow* iFrameGamma; + // + int iNeedFullFrameUpdate; + //unsigned char iFrameBeta[256*64]; + //unsigned char *iFrontBuffer; + //unsigned char *iBackBuffer; + FutabaVfdReport iInputReport; + // + char iDeviceId[KFutabaMaxHidReportSize]; + char iFirmwareRevision[KFutabaMaxHidReportSize]; + bool iPowerOn; + }; + + + +#endif diff -r 9c233658ab28 -r 3fa4007c0b19 FutabaVfd.h --- a/FutabaVfd.h Wed Feb 04 17:45:46 2015 +0100 +++ b/FutabaVfd.h Wed Feb 04 21:47:17 2015 +0100 @@ -28,9 +28,12 @@ const int KHidReportIdIndex=0; const int KFutabaHidReportSizeIndex=1; //Define Futaba vendor ID to filter our list of device +const unsigned short KTargaVendorId = 0x19C2; const unsigned short KFutabaVendorId = 0x1008; const unsigned short KFutabaProductIdGP1212A01A = 0x100C; const unsigned short KFutabaProductIdGP1212A02A = 0x1015; +const unsigned short KFutabaProductIdMDM166AA = 0x6A11; + //typedef struct hid_device_info HidDeviceInfo; diff -r 9c233658ab28 -r 3fa4007c0b19 MiniDisplay.cpp --- a/MiniDisplay.cpp Wed Feb 04 17:45:46 2015 +0100 +++ b/MiniDisplay.cpp Wed Feb 04 21:47:17 2015 +0100 @@ -2,13 +2,18 @@ #include "MiniDisplay.h" #include "FutabaGP1212A01.h" #include "FutabaGP1212A02.h" +#include "FutabaMDM166AA.h" - +/** +Make sure you update this list when adding a new display. +The order has to match the one from TMiniDisplayType. +*/ wchar_t* KDisplayNames[]= { L"Auto-Detect", L"Futaba GP1212A01", L"Futaba GP1212A02", + L"Futaba MDM166AA", L"Unknown display device" }; @@ -27,6 +32,10 @@ device=new GP1212A02A(); break; + case EMiniDisplayFutabaMDM166AA: + device=new MDM166AA(); + break; + case EMiniDisplayAutoDetectFailed: //Auto detect sequence failed return NULL; diff -r 9c233658ab28 -r 3fa4007c0b19 MiniDisplay.h --- a/MiniDisplay.h Wed Feb 04 17:45:46 2015 +0100 +++ b/MiniDisplay.h Wed Feb 04 21:47:17 2015 +0100 @@ -30,7 +30,7 @@ EMiniDisplayAutoDetect=0, EMiniDisplayFutabaGP1212A01, EMiniDisplayFutabaGP1212A02, - //EMiniDisplayFutabaMDM166AA, + EMiniDisplayFutabaMDM166AA, EMiniDisplayAutoDetectFailed } TMiniDisplayType;