# HG changeset patch # User sl # Date 1408918021 -7200 # Node ID 1c3a4964a5bde4da46739c244a730feb50e69e6b # Parent 6b08e3e81cf3ddf5cc09da2a2bfcec44ffa93a68 Working on GP1212A02 support. diff -r 6b08e3e81cf3 -r 1c3a4964a5bd Display.h --- a/Display.h Thu Aug 21 21:53:35 2014 +0200 +++ b/Display.h Mon Aug 25 00:07:01 2014 +0200 @@ -11,6 +11,8 @@ class DisplayBase { public: + virtual ~DisplayBase(){}; + // virtual int Open()=0; virtual void Close()=0; // @@ -18,6 +20,9 @@ virtual int MaxBrightness() const=0; virtual void SetBrightness(int aBrightness)=0; virtual void Clear()=0; + virtual void Fill()=0; + // + virtual void SwapBuffers()=0; }; diff -r 6b08e3e81cf3 -r 1c3a4964a5bd FutabaGP1212A01.cpp --- a/FutabaGP1212A01.cpp Thu Aug 21 21:53:35 2014 +0200 +++ b/FutabaGP1212A01.cpp Mon Aug 25 00:07:01 2014 +0200 @@ -144,6 +144,15 @@ } /** +Turn on all pixels. +Must be followed by a SwapBuffers call. +*/ +void GP1212A01A::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 diff -r 6b08e3e81cf3 -r 1c3a4964a5bd FutabaGP1212A01.h --- a/FutabaGP1212A01.h Thu Aug 21 21:53:35 2014 +0200 +++ b/FutabaGP1212A01.h Mon Aug 25 00:07:01 2014 +0200 @@ -32,6 +32,7 @@ //From FutabaVfd virtual void SetBrightness(int aBrightness); virtual void Clear(); + virtual void Fill(); //Specific to GP1212A01A void SetPixelBlock(unsigned char aX, unsigned char aY, int aHeight, int aSize, unsigned char aValue); diff -r 6b08e3e81cf3 -r 1c3a4964a5bd FutabaGP1212A02.cpp --- a/FutabaGP1212A02.cpp Thu Aug 21 21:53:35 2014 +0200 +++ b/FutabaGP1212A02.cpp Mon Aug 25 00:07:01 2014 +0200 @@ -2,4 +2,677 @@ // // -#include "FutabaGP1212A02.h" \ No newline at end of file +#include "FutabaGP1212A02.h" + + +const int KNumberOfFrameBeforeDiffAlgo = 3; + +// +// class GP1212A02A +// + +GP1212A02A::GP1212A02A(): + iDisplayPositionX(0),iDisplayPositionY(0), + iOffScreenMode(true), + iUseFrameDifferencing(true), + iFrameNext(NULL), + iFrameCurrent(NULL), + iFramePrevious(NULL), + iFrameAlpha(NULL), + iFrameBeta(NULL), + iFrameGamma(NULL), + iNeedFullFrameUpdate(0), + iRequest(EMiniDisplayRequestNone),iPowerOn(false) + { + iDeviceId[0]=0; + iFirmwareRevision[0]=0; + //ResetBuffers(); + } + +/** +*/ +GP1212A02A::~GP1212A02A() + { + delete iFrameAlpha; + iFrameAlpha=NULL; + // + delete iFrameBeta; + iFrameBeta=NULL; + // + delete iFrameGamma; + iFrameGamma=NULL; + // + iFrameNext=NULL; + iFrameCurrent=NULL; + iFramePrevious=NULL; + // + iNeedFullFrameUpdate=0; + } + +/** +*/ +int GP1212A02A::Open() + { + int success = HidDevice::Open(KFutabaVendorId,KFutabaProductIdGP1212A02A,NULL); + if (success) + { + //Allocate both frames + delete iFrameAlpha; + iFrameAlpha=NULL; + iFrameAlpha=new BitArray(KGP12xFrameBufferPixelCount); + // + delete iFrameBeta; + iFrameBeta=NULL; + iFrameBeta=new BitArray(KGP12xFrameBufferPixelCount); + // + delete iFrameGamma; + iFrameGamma=NULL; + iFrameGamma=new BitArray(KGP12xFrameBufferPixelCount); + // + iFrameNext=iFrameAlpha; + iFrameCurrent=iFrameBeta; + iFramePrevious=iFrameGamma; + + + //To make sure it is synced properly + iNeedFullFrameUpdate=0; + // + SetNonBlocking(1); + //Since we can't get our display position we force it to our default + //This makes sure frames are in sync from the start + //Clever clients will have taken care of putting back frame (0,0) before closing + SetDisplayPosition(iDisplayPositionX,iDisplayPositionY); + } + return success; + } + +/** +*/ +void GP1212A02A::SetPixel(unsigned char aX, unsigned char aY, bool aOn) + { + // + //int byteOffset=(aX*HeightInPixels()+aY)/8; + //int bitOffset=(aX*HeightInPixels()+aY)%8; + //iNextFrame[byteOffset] |= ( (aOn?0x01:0x00) << bitOffset ); + + if (iOffScreenMode) + { + if (aOn) + { + iFrameNext->SetBit(aX*HeightInPixels()+aY); + } + else + { + iFrameNext->ClearBit(aX*HeightInPixels()+aY); + } + } + else + { + //Just specify a one pixel block + SetPixelBlock(aX,aY,0x00,0x01,aOn); + } + } + +/** +*/ +void GP1212A02A::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 GP1212A02A::Clear() + { + //memset(iNextFrame->Ptr(),0x00,FrameBufferSizeInBytes()); + if (iOffScreenMode) + { + iFrameNext->ClearAll(); + } + else + { + SendClearCommand(); + } + } + +/** +Turn on all pixels. +Must be followed by a SwapBuffers call. +*/ +void GP1212A02A::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 GP1212A02A::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. + SetPixelBlock(0,0,63,FrameBufferSizeInBytes(),aPattern); + } + // + } + + +/** +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 The value set to 8 pixels used as a pattern. +*/ +void GP1212A02A::SetPixelBlock(unsigned char aX, unsigned char aY, int aHeight, int aSize, unsigned char aValue) + { + OffScreenTranslation(aX,aY); + 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]=0x5B; //Command ID + report[4]=0xF0; //Command ID + report[5]=aX; //X + report[6]=aY; //Y + report[7]=aHeight; //Y length before return. Though outside the specs, setting this to zero apparently allows us to modify a single pixel without touching any other. + report[8]=aSize>>8; //Size of pixel data in bytes (MSB) + report[9]=aSize; //Size of pixel data in bytes (LSB) + int sizeWritten=MIN(aSize,report.Size()-10); + memset(report.Buffer()+10, aValue, 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]); + memset(report.Buffer()+2, aValue, sizeWritten); + Write(report); + } + } + +/** +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 GP1212A02A::SetPixelBlock(unsigned char aX, unsigned char aY, int aHeight, int aSize, unsigned char* aPixels) + { + OffScreenTranslation(aX,aY); + 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]=0x5B; //Command ID + report[4]=0xF0; //Command ID + report[5]=aX; //X + report[6]=aY; //Y + report[7]=aHeight; //Y length before return. Though outside the specs, setting this to zero apparently allows us to modify a single pixel without touching any other. + report[8]=aSize>>8; //Size of pixel data in bytes (MSB) + report[9]=aSize; //Size of pixel data in bytes (LSB) + 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); + } + } + +/** +Using this function is advised against as is causes tearing. +Use Clear instead. +*/ +void GP1212A02A::SendClearCommand() + { + //1BH,5BH,32H,4AH + //Send Clear Display Command + FutabaVfdReport report; + report[0]=0x00; //Report ID + report[1]=0x04; //Report length + report[2]=0x1B; //Command ID + report[3]=0x5B; //Command ID + report[4]=0x32; //Command ID + report[5]=0x4A; //Command ID + Write(report); + } + +/** +Change our display position within our buffer. +*/ +void GP1212A02A::SetDisplayPosition(DW aDw,unsigned char aX, unsigned char aY) + { + //1BH,5BH,Dw,Px,Py + //Send Display Position Settings Command + FutabaVfdReport report; + report[0]=0x00; //Report ID + report[1]=0x05; //Report length + report[2]=0x1B; //Command ID + report[3]=0x5B; //Command ID + report[4]=aDw; //Specify our DW + report[5]=aX; //X coordinate of our DW top-left corner + report[6]=aY; //Y coordinate of our DW top-left corner + Write(report); + } + +/** +Change our display position within our buffer. +*/ +void GP1212A02A::SetDisplayPosition(unsigned char aX, unsigned char aY) + { + //Specs apparently says both DW should remain the same + //Just don't ask + SetDisplayPosition(GP1212A02A::DW1,aX,aY); + SetDisplayPosition(GP1212A02A::DW2,aX,aY); + iDisplayPositionX=aX; + iDisplayPositionY=aY; + } + +/** +Provide Y coordinate of our off screen buffer. +*/ +unsigned char GP1212A02A::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 GP1212A02A::SwapBuffers() + { + //Only perform buffer swapping if off screen mode is enabled + if (OffScreenMode()) + { + //Send host back buffer to device back buffer + if (!iUseFrameDifferencing || iNeedFullFrameUpdatePtr()); + } + else + { + //Frame diff algo is enabled + //We are going to send to our device only the differences between next frame and previous frame + SendModifiedPixelBlocks(); + } + //Swap device front and back buffer + SetDisplayPosition(iDisplayPositionX,OffScreenY()); + + //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 + BitArray* 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; + } + } + + +//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; + + +/** + * @brief GP1212A02A::SendModifiedPixelBlocks + * Compare our back and front buffer and send to the device only the modified pixels. + */ +void GP1212A02A::SendModifiedPixelBlocks() + { + int w=WidthInPixels(); + int h=HeightInPixels(); + + + //TODO: optimize with memcmp and 16 inc + /* + + for (int i=0;iPtr()+offset); + } + } + } + */ + + BitArray nextBlock(KPixelBlockSizeInBits); + BitArray previousBlock(KPixelBlockSizeInBits); + + for (int i=0;iPtr()+offset,iFramePrevious->Ptr()+offset,32 )) //32=(16*16/8) + if (memcmp(nextBlock.Ptr(),previousBlock.Ptr(),KPixelBlockSizeInBytes)!=0) + { + //We need to update that block + SetPixelBlock(i,j,KPixelBlockEdge-1,KPixelBlockSizeInBytes,nextBlock.Ptr()); + //SetPixelBlock(i,j,15,32,0xFF/*nextBlock.Ptr()*/); + //SetDisplayPosition(iDisplayPositionX,OffScreenY()); + //SetDisplayPosition(iDisplayPositionX,OffScreenY()); + + //SetPixelBlock(i,j,15,32,iFrameNext->Ptr()+offset); + } + } + } + + } + +/** +Translate the given pixel coordinate according to our off screen mode. +*/ +void GP1212A02A::OffScreenTranslation(unsigned char& aX, unsigned char& aY) + { + if (OffScreenMode()) + { + aX+=WidthInPixels()-iDisplayPositionX; + aY+=HeightInPixels()-iDisplayPositionY; + } + } + + +/** +*/ +void GP1212A02A::ResetBuffers() + { + //iNextFrame->ClearAll(); + //memset(iFrameAlpha,0x00,sizeof(iFrameAlpha)); + //memset(iFrameBeta,0x00,sizeof(iFrameBeta)); + } + +/** +*/ +void GP1212A02A::RequestDeviceId() + { + if (RequestPending()) + { + //Abort silently for now + return; + } + + //1BH,5BH,63H,49H,44H + //Send Read ID command + FutabaVfdReport report; + report[0]=0x00; //Report ID + report[1]=0x05; //Report length + report[2]=0x1B; //Command ID + report[3]=0x5B; //Command ID + report[4]=0x63; //Command ID + report[5]=0x49; //Command ID + report[6]=0x44; //Command ID + if (Write(report)==report.Size()) + { + iRequest=EMiniDisplayRequestDeviceId; + } + } + +/** +*/ +void GP1212A02A::RequestFirmwareRevision() + { + if (RequestPending()) + { + //Abort silently for now + return; + } + + //1BH,5BH,63H,46H,52H + //Send Software Revision Read Command + FutabaVfdReport report; + report[0]=0x00; //Report ID + report[1]=0x05; //Report length + report[2]=0x1B; //Command ID + report[3]=0x5B; //Command ID + report[4]=0x63; //Command ID + report[5]=0x46; //Command ID + report[6]=0x52; //Command ID + if (Write(report)==report.Size()) + { + iRequest=EMiniDisplayRequestFirmwareRevision; + } + } + +/** +*/ +void GP1212A02A::RequestPowerSupplyStatus() + { + if (RequestPending()) + { + //Abort silently for now + return; + } + //1BH,5BH,63H,50H,4DH + //Send Power Suppply Monitor Command + FutabaVfdReport report; + report[0]=0x00; //Report ID + report[1]=0x05; //Report length + report[2]=0x1B; //Command ID + report[3]=0x5B; //Command ID + report[4]=0x63; //Command ID + report[5]=0x50; //Command ID + report[6]=0x4D; //Command ID + if (Write(report)==report.Size()) + { + iRequest=EMiniDisplayRequestPowerSupplyStatus; + } + } + + +/** +This is for development purposes only. +Production application should stick to off-screen mode to avoid tearing. +*/ +void GP1212A02A::ToggleOffScreenMode() + { + SetOffScreenMode(!iOffScreenMode); + } + +/** + * @brief GP1212A02A::SetOffScreenMode + * @param aOn + * @return + */ +void GP1212A02A::SetOffScreenMode(bool aOn) + { + if (aOn==iOffScreenMode) + { + //Nothing to do here + return; + } + + iOffScreenMode=aOn; + + //Clean up our buffers upon switching modes + SetDisplayPosition(0,0); + Clear(); + SwapBuffers(); + Clear(); + } + +/** +Tries to complete our current request if we have one pending. + */ +TMiniDisplayRequest GP1212A02A::AttemptRequestCompletion() + { + if (!RequestPending()) + { + return EMiniDisplayRequestNone; + } + + int res=Read(iInputReport); + + if (!res) + { + return EMiniDisplayRequestNone; + } + + //Process our request + if (CurrentRequest()==EMiniDisplayRequestPowerSupplyStatus) + { + if (iInputReport[1]==0x4F && iInputReport[2]==0x4E) + { + iPowerOn = true; + } + else if (iInputReport[1]==0x4F && iInputReport[2]==0x46 && iInputReport[3]==0x46) + { + iPowerOn = false; + } + } + else if (CurrentRequest()==EMiniDisplayRequestDeviceId) + { + unsigned char* ptr=&iInputReport[1]; + strcpy(iDeviceId,(const char*)ptr); + } + else if (CurrentRequest()==EMiniDisplayRequestFirmwareRevision) + { + unsigned char* ptr=&iInputReport[1]; + strcpy(iFirmwareRevision,(const char*)ptr); + } + + TMiniDisplayRequest completed=iRequest; + //Our request was completed + iRequest=EMiniDisplayRequestNone; + + return completed; + } + + +/** +Set our screen brightness. +@param The desired brightness level. Must be between MinBrightness and MaxBrightness. +*/ +void GP1212A02A::SetBrightness(int aBrightness) + { + if (aBrightnessMaxBrightness()) + { + //Brightness out of range. + //Just ignore that request. + return; + } + + FutabaVfdReport report; + report[0]=0x00; //Report ID + report[1]=0x04; //Report size + report[2]=0x1B; //Command ID + report[3]=0x4A; //Command ID + report[4]=0x44; //Command ID + report[7]=0x30+aBrightness; //Brightness level + Write(report); + } + +/** +*/ +bool GP1212A02A::PowerOn() + { + return iPowerOn; + } + +/** +*/ +char* GP1212A02A::DeviceId() + { + return iDeviceId; + } + +/** +*/ +char* GP1212A02A::FirmwareRevision() + { + return iFirmwareRevision; + } diff -r 6b08e3e81cf3 -r 1c3a4964a5bd FutabaGP1212A02.h --- a/FutabaGP1212A02.h Thu Aug 21 21:53:35 2014 +0200 +++ b/FutabaGP1212A02.h Mon Aug 25 00:07:01 2014 +0200 @@ -7,6 +7,109 @@ #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). +*/ +class GP1212A02A : public GP1212XXXX + { +public: + + GP1212A02A(); + ~GP1212A02A(); + + //From DisplayBase + int Open(); + virtual void SwapBuffers(); + + //From GraphicDisplay + virtual void SetPixel(unsigned char aX, unsigned char aY, bool aOn); + virtual void SetAllPixels(unsigned char aPattern); + virtual int FrameBufferSizeInBytes() const {return KGP12xFrameBufferSizeInBytes;} + virtual void BitBlit(const BitArray& aBitmap, int aSrcWidth, int aSrcHeight, int aTargetX, int aTargetY) const; + virtual void SetBrightness(int aBrightness); + virtual void Clear(); + virtual void Fill(); + + //Specific to GP1212A01A + void SetPixelBlock(unsigned char aX, unsigned char aY, int aHeight, int aSize, unsigned char aValue); + void SetPixelBlock(unsigned char aX, unsigned char aY, int aHeight, int aSize, unsigned char* aPixels); + //Define display position within our display RAM + void SetDisplayPosition(unsigned char aX, unsigned char aY); + unsigned char DisplayPositionX() const {return iDisplayPositionX;} + unsigned char DisplayPositionY() const {return iDisplayPositionY;} + + // + void RequestDeviceId(); + void RequestFirmwareRevision(); + void RequestPowerSupplyStatus(); + // + void ToggleOffScreenMode(); + void SetOffScreenMode(bool aOn); + bool OffScreenMode() const {return iOffScreenMode;} + // + void SetFrameDifferencing(bool aOn){iUseFrameDifferencing=aOn;} + bool FrameDifferencing() const {return iUseFrameDifferencing;} + // + bool RequestPending(){return iRequest!=EMiniDisplayRequestNone;} + TMiniDisplayRequest CurrentRequest(){return iRequest;} + void CancelRequest(){iRequest=EMiniDisplayRequestNone;} + TMiniDisplayRequest AttemptRequestCompletion(); + FutabaVfdReport& InputReport() {return iInputReport;} + bool PowerOn(); + char* DeviceId(); + char* FirmwareRevision(); + +private: + enum DW + { + DW1=0xC0, + DW2=0xD0 + }; + + void SetDisplayPosition(DW aDw,unsigned char aX, unsigned char aY); + unsigned char OffScreenY() const; + void SendClearCommand(); + void OffScreenTranslation(unsigned char& aX, unsigned char& aY); + void ResetBuffers(); + void SendModifiedPixelBlocks(); + +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]; + BitArray* iFrameNext; + BitArray* iFrameCurrent; + BitArray* iFramePrevious; + // + BitArray* iFrameAlpha; + BitArray* iFrameBeta; + BitArray* iFrameGamma; + // + int iNeedFullFrameUpdate; + //unsigned char iFrameBeta[256*64]; + //unsigned char *iFrontBuffer; + //unsigned char *iBackBuffer; + TMiniDisplayRequest iRequest; + FutabaVfdReport iInputReport; + // + char iDeviceId[KFutabaMaxHidReportSize]; + char iFirmwareRevision[KFutabaMaxHidReportSize]; + bool iPowerOn; + }; + #endif diff -r 6b08e3e81cf3 -r 1c3a4964a5bd FutabaVfd.h --- a/FutabaVfd.h Thu Aug 21 21:53:35 2014 +0200 +++ b/FutabaVfd.h Mon Aug 25 00:07:01 2014 +0200 @@ -31,7 +31,7 @@ //Define Futaba vendor ID to filter our list of device const unsigned short KFutabaVendorId = 0x1008; const unsigned short KFutabaProductIdGP1212A01A = 0x100C; -const unsigned short KFutabaProductIdGP1212A02A = 0x1013; //Or is it 0x1015 +const unsigned short KFutabaProductIdGP1212A02A = 0x1015; //typedef struct hid_device_info HidDeviceInfo; diff -r 6b08e3e81cf3 -r 1c3a4964a5bd MiniDisplay.cpp --- a/MiniDisplay.cpp Thu Aug 21 21:53:35 2014 +0200 +++ b/MiniDisplay.cpp Mon Aug 25 00:07:01 2014 +0200 @@ -1,29 +1,46 @@ #include "MiniDisplay.h" #include "FutabaGP1212A01.h" - - +#include "FutabaGP1212A02.h" //Open & Close functions MiniDisplayDevice MiniDisplayOpen(TMiniDisplayType aType) { - GP1212A01A* device=NULL; - device=new GP1212A01A(); + GraphicDisplay* device=NULL; + + switch (aType) + { + case EMiniDisplayAutoDetect: + //TODO + device=new GP1212A01A(); + break; + + case EMiniDisplayFutabaGP1212A01: + device=new GP1212A01A(); + break; + + case EMiniDisplayFutabaGP1212A02: + device=new GP1212A02A(); + break; + }; + int success = device->Open(); if (!success) { delete device; - return NULL; + device=NULL; } return device; } +// + void MiniDisplayClose(MiniDisplayDevice aDevice) { - delete ((GP1212A01A*)aDevice); + delete ((GraphicDisplay*)aDevice); } @@ -34,7 +51,7 @@ return; } - ((GP1212A01A*)aDevice)->SetAllPixels(0x00); + ((GraphicDisplay*)aDevice)->Clear(); } @@ -45,7 +62,7 @@ return; } - ((GP1212A01A*)aDevice)->SetAllPixels(0xFF); + ((GraphicDisplay*)aDevice)->Fill(); } @@ -56,7 +73,7 @@ return; } - ((GP1212A01A*)aDevice)->SwapBuffers(); + ((GraphicDisplay*)aDevice)->SwapBuffers(); } //------------------------------------------------------------- @@ -67,7 +84,7 @@ return 0; } - return ((GP1212A01A*)aDevice)->MaxBrightness(); + return ((GraphicDisplay*)aDevice)->MaxBrightness(); } //------------------------------------------------------------- @@ -78,7 +95,7 @@ return 0; } - return ((GP1212A01A*)aDevice)->MinBrightness(); + return ((GraphicDisplay*)aDevice)->MinBrightness(); } //------------------------------------------------------------- @@ -89,7 +106,7 @@ return; } - ((GP1212A01A*)aDevice)->SetBrightness(aBrightness); + ((GraphicDisplay*)aDevice)->SetBrightness(aBrightness); } //------------------------------------------------------------- @@ -100,7 +117,7 @@ return 0; } - return ((GP1212A01A*)aDevice)->WidthInPixels(); + return ((GraphicDisplay*)aDevice)->WidthInPixels(); } //------------------------------------------------------------- @@ -111,14 +128,14 @@ return 0; } - return ((GP1212A01A*)aDevice)->HeightInPixels(); + return ((GraphicDisplay*)aDevice)->HeightInPixels(); } //------------------------------------------------------------- void MiniDisplaySetPixel(MiniDisplayDevice aDevice, int aX, int aY, int aValue) { //aValue&=0x00FFFFFF; //Filter out alpha component - return ((GP1212A01A*)aDevice)->SetPixel(aX,aY,aValue); + return ((GraphicDisplay*)aDevice)->SetPixel(aX,aY,aValue); } //-------------------------------------------------------------