MDM166AA: more accurate time setting and cleanup.
5 #include "FutabaGP1212A02.h"
10 const unsigned short KMaxDataMemoryAddress = 0x4FFF;
11 const unsigned short KFrameSizeInBytes = 0x800;
14 static void sleep(unsigned int mseconds)
16 clock_t goal = mseconds + clock();
17 while (goal > clock());
24 GP1212A02A::GP1212A02A():
25 iDisplayPositionX(0),iDisplayPositionY(0),
27 iUseFrameDifferencing(true),
34 iNeedFullFrameUpdate(0),
38 iFirmwareRevision[0]=0;
44 GP1212A02A::~GP1212A02A()
59 iNeedFullFrameUpdate=0;
64 int GP1212A02A::Open()
66 int success = HidDevice::Open(KFutabaVendorId,KFutabaProductIdGP1212A02A,NULL);
69 //Allocate both frames
72 iFrameAlpha=new BitArrayLow(KGP12xFrameBufferPixelCount);
76 iFrameBeta=new BitArrayLow(KGP12xFrameBufferPixelCount);
80 iFrameGamma=new BitArrayLow(KGP12xFrameBufferPixelCount);
82 iFrameNext=iFrameAlpha;
83 iFrameCurrent=iFrameBeta;
84 iFramePrevious=iFrameGamma;
87 //To make sure it is synced properly
88 iNeedFullFrameUpdate=0;
96 //BMP box setup could be removed if we don't use it anymore
98 BmpBoxSetting(EBmpBoxIdOne,0x0000,256,64);
99 //Select current BMP box
100 BmpBoxSelect(EBmpBoxIdOne);
102 iNextFrameAddress = 0x0000;
106 SendCommandFontAction(EFontDelete);
108 //SendCommandSelectFontSize(EFontLarge);
109 //SendCommandReset();
113 unsigned char charPixels[]={ 0xFF,0xFF,0xFF,0xFF,
128 0xFF,0xFF,0xFF,0xFF};
131 //SendCommandFontAction(EFontStore);
132 for (unsigned short i=0;i<16;i++)
134 //SendCommandFontAction(EFontDelete);
136 SendCommandDefineCharacter(EFont16x32,0x0030+i,charPixels);
137 //SendCommandFontAction(EFontStore);
143 //SendCommandFontAction(EFontTransfer);
146 //SendCommandDefineCharacter(EFont16x32,0x0031,charPixels);
147 //SendCommandFontAction(EFontStore);
160 [Code] 1BH,5CH,42H,Pn,aL,aH,Pw,Ph
161 [Function] Setting the BMP box. BMP box can be defined the 3 area to DW. The position of BMP
162 box is set based on the address of DW.
163 * To write data in BMP box, BMP box select is necessary.
164 * Specifiable horizontal size is 256dot (100H) MAX. If horizontal size specify 256dot, Pw = 00H
165 Pn = Number of a BMP box
166 aL = Lower byte of address
167 aH = Upper byte of address
175 0000H <= aL + aH * 100 <= 07FFH
176 01H <= Pw <= 00H (=100H)
179 void GP1212A02A::BmpBoxSetting(TBmpBoxId aBoxId, unsigned short aAddress, int aWidth, int aHeight)
181 //TODO: check parameters validity
182 //1BH,5CH,42H,Pn,aL,aH,Pw,Ph
183 FutabaVfdReport report;
184 report[0]=0x00; //Report ID
185 report[1]=0x08; //Report length.
186 report[2]=0x1B; //Command ID
187 report[3]=0x5C; //Command ID
188 report[4]=0x42; //Command ID
190 report[6]=(unsigned char)aAddress; //aL = DM lower byte
191 report[7]=aAddress>>8; //aH = DM upper byte
192 report[8]=(aWidth==256?0x00:aWidth); //Pw = BMP box width 00==256
193 report[9]=aHeight/8; //Ph = BMP box height.
199 [Function]Select of BMP box
200 * Execution "BMP box select" is necessary before "Setting the Text box".
201 * In case of writing by the specified dot writing, it is necessary to cancel this command.
203 Pn = 30H - Remove the BMP box
208 void GP1212A02A::BmpBoxSelect(TBmpBoxId aBoxId)
210 //TODO: check parameters validity
211 FutabaVfdReport report;
212 report[0]=0x00; //Report ID
213 report[1]=0x04; //Report length.
214 report[2]=0x1B; //Command ID
215 report[3]=0x5C; //Command ID
216 report[4]=0x48; //Command ID
217 report[5]=aBoxId; //BMP box ID
224 void GP1212A02A::SetPixel(unsigned char aX, unsigned char aY, unsigned int aPixel)
227 //int byteOffset=(aX*HeightInPixels()+aY)/8;
228 //int bitOffset=(aX*HeightInPixels()+aY)%8;
229 //iNextFrame[byteOffset] |= ( (aOn?0x01:0x00) << bitOffset );
231 //Pixel is on if any of the non-alpha component is not null
232 bool on = (aPixel&0x00FFFFFF)!=0x00000000;
238 iFrameNext->SetBit(aX*HeightInPixels()+aY);
242 iFrameNext->ClearBit(aX*HeightInPixels()+aY);
247 //Just specify a one pixel block
255 void GP1212A02A::BitBlit(const BitArray& aBitmap, int aSrcWidth, int aSrcHeight, int aTargetX, int aTargetY) const
257 //TODO: amend loop values so that we don't keep on looping past our frame buffer dimensions.
258 for (int i=0;i<aSrcWidth;i++)
260 for (int j=0;j<aSrcHeight;j++)
262 iFrameNext->SetBitValue((aTargetX+i)*HeightInPixels()+aTargetY+j,aBitmap[+i*aSrcHeight+j]);
269 Clear our client side back buffer.
270 Call to SwapBuffers must follow to actually clear the display.
272 void GP1212A02A::Clear()
274 //memset(iNextFrame->Ptr(),0x00,FrameBufferSizeInBytes());
277 iFrameNext->ClearAll();
287 Must be followed by a SwapBuffers call.
289 void GP1212A02A::Fill()
295 Set all pixels on our screen to the desired value.
296 This operation is performed off screen to avoid tearing.
297 @param 8 pixels pattern
299 void GP1212A02A::SetAllPixels(unsigned char aPattern)
301 //With a single buffer
302 //unsigned char screen[2048]; //One screen worth of pixels
303 //memset(screen,0xFF,sizeof(screen));
304 //SetPixelBlock(0,0,63,sizeof(screen),screen);
309 memset(iFrameNext->Ptr(),aPattern,FrameBufferSizeInBytes());
313 //Using pattern SetPixelBlock variant.
324 [Code] 1BH,4AH,Pm,aL,aH,Ps,nL,nH,Pd...Pd
325 [Function] The BMP data is written in the DW(Display Window) or the Data memory.
326 Pm= DW or Data memory
329 Ps = Direction of writing
330 nL = number of BMP data length lower byte
331 nH = number of BMP data length upper byte
333 * If X direction is selected as Ps and data is written in the last address, the data in the last address is
334 overwritten with the remaining data.
335 [Definable area] Pm = 30H : DW
336 Pm = 31H: Data memory
337 0000H <= aL + aH * 100 <= 07FFH (DW)
338 0000H <= aL + aH * 100 <= 4FFFH (Data memory)
339 Ps = 30H: Y direction
340 Ps = 31H: X direction
341 0001H <= nL + nH * 100 <= 0100H(DW: X direction)
342 0001H <= nL + nH * 100 <= 0800H(DW: Y direction)
343 0001H <= nL + nH * 100 <= 0A00H(Data memory: X direction)
344 0001H <= nL + nH * 100 <= 5000H(Data memory: Y direction)
346 void GP1212A02A::BmpDataInput(TTarget aTarget, unsigned short aAddress, TDirection aDirection, unsigned short aSize, unsigned char* aPixels)
348 FutabaVfdReport report;
349 report[0]=0x00; //Report ID
350 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
351 report[2]=0x1B; //Command ID
352 report[3]=0x4A; //Command ID
353 report[4]=aTarget; //Display Window or Data Memory
354 report[5]=(unsigned char)aAddress; //aL = DW lower byte
355 report[6]=aAddress>>8; //aH = DW upper byte
356 report[7]=aDirection; //Direction of writing: Y or X
357 report[8]=(unsigned char)aSize; //Size of pixel data in bytes (LSB)
358 report[9]=aSize>>8; //Size of pixel data in bytes (MSB)
359 int sizeWritten=MIN(aSize,report.Size()-10);
360 memcpy(report.Buffer()+10, aPixels, sizeWritten);
363 int remainingSize=aSize;
364 //We need to keep on sending our pixel data until we are done
365 while (report[1]==64)
368 remainingSize-=sizeWritten;
369 report[0]=0x00; //Report ID
370 report[1]=(remainingSize<=report.Size()-2?remainingSize:64); //Report length, should be 64 or the remaining size
371 sizeWritten=(report[1]==64?63:report[1]);
372 memcpy(report.Buffer()+2, aPixels+(aSize-remainingSize), sizeWritten);
380 [Code] 1BH,5CH,44H,aL,aH
381 [Function] BMP data transfer from Data memory to DW.
382 Although source data is updated, data in BMP box is not updated. To reflect the update,
383 re-executing this command is necessary.
384 aL = Lower byte of address
385 aH = Upper byte of address
387 0000H <= aL + aH * 100 <= 4FFFH
389 void GP1212A02A::BmpBoxDataMemoryTransfer(unsigned short aAddress)
391 FutabaVfdReport report;
392 report[0]=0x00; //Report ID
393 report[1]=0x05; //Report length.
394 report[2]=0x1B; //Command ID
395 report[3]=0x5C; //Command ID
396 report[4]=0x44; //Command ID
397 report[5]=(unsigned char)aAddress; //aL = DM lower byte
398 report[6]=aAddress>>8; //aH = DM upper byte
403 Input BMP data in the BMP box
404 [Code] 1BH,5CH,5DH,nL,nH,Pd...Pd
405 [Function] BMP data is written the BMP box
406 * Number of definable data is due to BMP box size. If the data is over range, the over range data is
407 rewritten the final address.
408 nL = Lower byte of number of definition byte
409 nH = Upper byte of number of definition byte
411 [Definable area] Pn : BMP box size (Pw * Ph)
413 void GP1212A02A::BmpBoxDataInput(unsigned short aSize, unsigned char* aPixels)
415 FutabaVfdReport report;
416 report[0]=0x00; //Report ID
417 report[1]=(aSize<=report.Size()-7?aSize+0x05:64); //Report length. -7 is for our header first 10 bytes. +5 is for our Futaba header size
418 report[2]=0x1B; //Command ID
419 report[3]=0x5C; //Command ID
420 report[4]=0x5D; //Display Window or Data Memory
421 report[5]=(unsigned char)aSize; //Size of pixel data in bytes (LSB)
422 report[6]=aSize>>8; //Size of pixel data in bytes (MSB)
423 int sizeWritten=MIN(aSize,report.Size()-7);
424 memcpy(report.Buffer()+7, aPixels, sizeWritten);
427 int remainingSize=aSize;
428 //We need to keep on sending our pixel data until we are done
429 while (report[1]==64)
432 remainingSize-=sizeWritten;
433 report[0]=0x00; //Report ID
434 report[1]=(remainingSize<=report.Size()-2?remainingSize:64); //Report length, should be 64 or the remaining size
435 sizeWritten=(report[1]==64?63:report[1]);
436 memcpy(report.Buffer()+2, aPixels+(aSize-remainingSize), sizeWritten);
442 Using this function is advised against as is causes tearing.
445 void GP1212A02A::SendCommandClear()
448 //Send Clear Display Command
449 FutabaVfdReport report;
450 report[0]=0x00; //Report ID
451 report[1]=0x04; //Report length
452 report[2]=0x1B; //Command ID
453 report[3]=0x4A; //Command ID
454 report[4]=0x43; //Command ID
455 report[5]=0x44; //Command ID
461 Returns to default setting.
462 * The other command is not receive until this command complete. Please don’t send the any data
463 from a host during “BUSY”
464 * Delete the User definable font to the RAM.
465 * If the VFD Power Off, VFD Power turn ON after the RESET command.
467 void GP1212A02A::SendCommandReset()
470 //Send Clear Display Command
471 FutabaVfdReport report;
472 report[0]=0x00; //Report ID
473 report[1]=0x04; //Report length
474 report[2]=0x1B; //Command ID
475 report[3]=0x4A; //Command ID
476 report[4]=0x52; //Command ID
477 report[5]=0x53; //Command ID
479 //Wait until reset is done. Is that needed?
486 Provide Y coordinate of our off screen buffer.
488 unsigned char GP1212A02A::OffScreenY() const
490 //Overflowing is fine this is just what we want
491 return iDisplayPositionY+HeightInPixels();
495 Put our off screen buffer on screen.
496 On screen buffer goes off screen.
498 void GP1212A02A::SwapBuffers()
500 //Only perform buffer swapping if off screen mode is enabled
503 //Send pixel directly into BMP box
504 //BmpBoxDataInput(FrameBufferSizeInBytes(),iFrameNext->Ptr());
506 //This appears to be the fastest scheme when running on our HTPC
507 //Send pixel data directly into the display window
508 BmpDataInput(ETargetDisplayWindow,0x0000,EDirectionY, FrameBufferSizeInBytes(),iFrameNext->Ptr());
510 //Send pixel data first to Data Memory then copy into the selected BMP box
511 //BmpDataInput(ETargetDataMemory,0x0000,EDirectionY, FrameBufferSizeInBytes(),iFrameNext->Ptr());
512 //BmpBoxDataMemoryTransfer(0x0000);
514 //Send pixel data first to Data Memory then copy into the selected BMP box, cycling through our Data Memory frame
516 BmpDataInput(ETargetDataMemory,iNextFrameAddress,EDirectionY, FrameBufferSizeInBytes(),iFrameNext->Ptr());
517 BmpBoxDataMemoryTransfer(iNextFrameAddress);
518 iNextFrameAddress+=KFrameSizeInBytes;
519 if (iNextFrameAddress>KMaxDataMemoryAddress)
521 iNextFrameAddress=0x0000;
525 //Cycle through our frame buffers
526 //We keep track of previous frame which is in fact our device back buffer.
527 //We can then compare previous and next frame and send only the differences to our device.
528 //This mechanism allows us to reduce traffic over our USB bus thus improving our frame rate from 14 FPS to 30 FPS.
529 //Keep our previous frame pointer
530 BitArrayLow* previousFrame=iFramePrevious;
531 //Current frame becomes the previous one
532 iFramePrevious = iFrameCurrent;
533 //Next frame becomes the current one
534 iFrameCurrent = iFrameNext;
535 //Next frame is now our former previous
536 iFrameNext = previousFrame;
541 //Define the edge of our pixel block
542 //Pixel blocks of 32x32 seems to run almost as fast as full screen update in worse case scenarii.
543 //Though I wonder if in some situations 16 could be better. Make this an attribute at some point if need be.
544 const int KPixelBlockEdge = 32;
545 const int KPixelBlockSizeInBits = KPixelBlockEdge*KPixelBlockEdge;
546 const int KPixelBlockSizeInBytes = KPixelBlockSizeInBits/8;
550 Translate the given pixel coordinate according to our off screen mode.
552 void GP1212A02A::OffScreenTranslation(unsigned char& aX, unsigned char& aY)
556 aX+=WidthInPixels()-iDisplayPositionX;
557 aY+=HeightInPixels()-iDisplayPositionY;
564 void GP1212A02A::Request(TMiniDisplayRequest aRequest)
568 case EMiniDisplayRequestDeviceId:
571 case EMiniDisplayRequestFirmwareRevision:
572 RequestFirmwareRevision();
574 case EMiniDisplayRequestPowerSupplyStatus:
575 RequestPowerSupplyStatus();
586 void GP1212A02A::ResetBuffers()
588 //iNextFrame->ClearAll();
589 //memset(iFrameAlpha,0x00,sizeof(iFrameAlpha));
590 //memset(iFrameBeta,0x00,sizeof(iFrameBeta));
595 void GP1212A02A::RequestDeviceId()
602 [Code] 1BH,6AH,49H,44H
603 [Function] Send the ID code to the Host system. ID code is software version.
605 void GP1212A02A::RequestFirmwareRevision()
607 if (RequestPending())
609 //Abort silently for now
614 //Send Software Revision Read Command
615 FutabaVfdReport report;
616 report[0]=0x00; //Report ID
617 report[1]=0x04; //Report length
618 report[2]=0x1B; //Command ID
619 report[3]=0x6A; //Command ID
620 report[4]=0x49; //Command ID
621 report[5]=0x44; //Command ID
622 if (Write(report)==report.Size())
624 SetRequest(EMiniDisplayRequestFirmwareRevision);
631 void GP1212A02A::RequestPowerSupplyStatus()
638 This is for development purposes only.
639 Production application should stick to off-screen mode to avoid tearing.
641 void GP1212A02A::ToggleOffScreenMode()
643 SetOffScreenMode(!iOffScreenMode);
647 * @brief GP1212A02A::SetOffScreenMode
651 void GP1212A02A::SetOffScreenMode(bool aOn)
653 if (aOn==iOffScreenMode)
661 //Clean up our buffers upon switching modes
668 Tries to complete our current request if we have one pending.
670 TMiniDisplayRequest GP1212A02A::AttemptRequestCompletion()
672 if (!RequestPending())
674 return EMiniDisplayRequestNone;
677 int res=Read(iInputReport);
681 return EMiniDisplayRequestNone;
684 //Process our request
685 if (CurrentRequest()==EMiniDisplayRequestFirmwareRevision)
687 unsigned char* ptr=&iInputReport[2];
688 iInputReport[7]=0x00;
689 strcpy(iFirmwareRevision,(const char*)ptr);
692 TMiniDisplayRequest completed=CurrentRequest();
693 //Our request was completed
694 SetRequest(EMiniDisplayRequestNone);
701 Set our screen brightness.
702 @param The desired brightness level. Must be between MinBrightness and MaxBrightness.
704 void GP1212A02A::SetBrightness(int aBrightness)
706 if (aBrightness<MinBrightness()||aBrightness>MaxBrightness())
708 //Brightness out of range.
709 //Just ignore that request.
713 FutabaVfdReport report;
714 report[0]=0x00; //Report ID
715 report[1]=0x04; //Report size
716 report[2]=0x1B; //Command ID
717 report[3]=0x4A; //Command ID
718 report[4]=0x44; //Command ID
719 report[5]=0x30+aBrightness; //Brightness level
725 bool GP1212A02A::IsPowerOn()
732 char* GP1212A02A::DeviceId()
739 char* GP1212A02A::FirmwareRevision()
741 return iFirmwareRevision;
747 [Function]Control of the power supply for VFD
748 * If VFD power ON or OFF, at interval of 10s or more.
749 * When the VFD power off, VFD display is turn off, but the module can receive a data and
751 Ps = VFD Power control
753 Ps = 30H : VFD Power OFF
754 Ps = 31H : VFD Power ON (Default)
756 void GP1212A02A::SendCommandPower(TPowerStatus aPowerStatus)
758 FutabaVfdReport report;
759 report[0]=0x00; //Report ID
760 report[1]=0x04; //Report size
761 report[2]=0x1B; //Command ID
762 report[3]=0x4A; //Command ID
763 report[4]=0x42; //Command ID
764 report[5]=aPowerStatus; //ON or OFF
770 void GP1212A02A::TurnPowerOn()
772 SendCommandPower(EPowerOn);
778 void GP1212A02A::TurnPowerOff()
780 SendCommandPower(EPowerOff);
785 Provide the length of our character string for the given clock format.
786 @param The clock format to evaluate.
787 @return Number of characters for the given clock format.
789 int GP1212A02A::ClockCharCount(TClockFormat aFormat)
807 @return Clock character width in pixels.
809 int GP1212A02A::ClockCharWidthInPixels(TFontSizeLogical aSize)
827 @return Clock character height in pixels.
829 int GP1212A02A::ClockCharHeightInPixels(TFontSizeLogical aSize)
847 Return the Display Window address for centering the clock corresponding to the given parameters.
849 unsigned short GP1212A02A::ClockCenterAddress(TClockFormat aFormat, TFontSizeLogical aSize)
851 int charCount=ClockCharCount(aFormat);
852 int halfWidth=(ClockCharWidthInPixels(aSize)*charCount)/2;
853 int halfHeight=(ClockCharHeightInPixels(aSize))/2;
854 int x=(WidthInPixels()/2)-halfWidth;
855 int y=(HeightInPixels()/2)-halfHeight;
858 int xOffset=x*8; //Not sure why...
860 unsigned short address = yOffset+xOffset;
867 void GP1212A02A::ShowClock()
869 SendCommandClockDisplay(EClock24,ClockCenterAddress(EClock24,EFontLarge),EFontLarge);
874 void GP1212A02A::HideClock()
876 SendCommandClockCancel();
882 [Code]1BH,6BH,53H,Pd,Ph,Pm
883 [Function]Setting the clock data. The setting data is cleared, if the Reset command is input or power
893 * Clock setting is canceled, when Pd is input value that is larger than 07H, or Ph is input value that is
894 larger than 18H,or Pm is input value that is larger than 3CH.
896 void GP1212A02A::SendCommandClockSetting(TWeekDay aWeekDay, unsigned char aHour, unsigned char aMinute)
898 FutabaVfdReport report;
899 report[0]=0x00; //Report ID
900 report[1]=0x06; //Report size
901 report[2]=0x1B; //Command ID
902 report[3]=0x6B; //Command ID
903 report[4]=0x53; //Command ID
904 report[5]=aWeekDay; //Sunday to Saturday
913 Set display clock settings according to local system time.
914 This needs to be redone whenever we open or turn on our display.
916 void GP1212A02A::SetClockSetting()
919 struct tm * timeinfo;
922 timeinfo = localtime ( &rawtime );
924 SendCommandClockSetting((TWeekDay)timeinfo->tm_wday,timeinfo->tm_hour,timeinfo->tm_min);
930 [Code] 1BH,6BH,55H,Ps,aL,aH,Pf
931 [Function] Clock is displayed. The display position and the font size can be freely decided.
932 Ps = Display type select
934 Pf = Font size select
936 Ps = 00H : 24hour Ex.[12:34]
937 Ps = 01H : 24hour + day of the week Ex.[Wed._12:34]
938 Ps = 10H : 12hour Ex.[PM_00:34]
939 Ps = 11H : 12hour + day of the week Ex.[Wed._PM_00:34]
944 * When the clock data is not input, clock is not displayed.
945 * The clock display is maintained until Clock display cancel "Clear display" RESET command is input
946 or power is turned off.
947 The clock display area
948 Graphic can be displayed excluding the clock display area.
949 The self adjustment for the position
950 that cannot be displayed.
951 * Excluding the clock display area can be input other display commands.
953 void GP1212A02A::SendCommandClockDisplay(TClockFormat aClockFormat, unsigned short aAddress, TFontSizeLogical aSize)
955 FutabaVfdReport report;
956 report[0]=0x00; //Report ID
957 report[1]=0x07; //Report size
958 report[2]=0x1B; //Command ID
959 report[3]=0x6B; //Command ID
960 report[4]=0x55; //Command ID
961 report[5]=aClockFormat; //
962 report[6]=(unsigned char)aAddress; //aL
963 report[7]=aAddress>>8; //aH
972 [Code] 1BH,6BH,3DH,58H
973 [Function] Clock display is canceled.
975 void GP1212A02A::SendCommandClockCancel()
977 FutabaVfdReport report;
978 report[0]=0x00; //Report ID
979 report[1]=0x04; //Report size
980 report[2]=0x1B; //Command ID
981 report[3]=0x6B; //Command ID
982 report[4]=0x3D; //Command ID
990 @return Size in bytes of a character for a given font size.
992 int GP1212A02A::CharacterSizeInBytes(TFontSize aFontSize)
1016 Define the User definable font (RAM)
1017 [Code] 1BH,6AH,47H,Pf,cL,(cH),Pd...Pd
1018 [Function] Define the User definable font into RAM. A maximum 16 characters can be defined
1019 within each font size.
1020 The User definable fonts are displayed the defined code. It is a same process to normal fonts.
1021 The User definable fonts are valid until they redefined, Reset command, or the power off.
1022 If define the user definable font over 16 characters, at first defined user definable font is removed
1023 If the defined code is specified, existing data is re-written.
1024 If the 16x16, 24x24, 32x32 size define, it must specify the “cH”
1026 cL = Lower byte of User definable font code
1027 cH = Upper byte of User definable font code
1028 Pd = Definition data
1030 Pf = 30H : 6x8 dot (Pd=6 byte)
1031 Pf = 31H : 8x16 dot (Pd=16 byte)
1032 Pf = 32H : 12x24 dot (Pd=36 byte)
1033 Pf = 33H : 16x32 dot (Pd=64 byte)
1034 Pf = 34H : 16x16 dot (Pd=32 byte)
1035 Pf = 35H : 24x24 dot (Pd=72 byte)
1036 Pf = 36H : 32x32 dot (Pd=128 byte)
1037 cL = ANK code (Pf=30H~33H : 1 byte code)
1038 cL,cH = Shift-JIS code (Pf=34H~36H : 2 byte code)
1040 void GP1212A02A::SendCommandDefineCharacter(TFontSize aFontSize, unsigned short aCharacterCode, unsigned char* aPixels)
1042 unsigned char reportSize=0;
1043 unsigned char headerSize=0;
1044 unsigned char dataSize=CharacterSizeInBytes(aFontSize);
1045 FutabaVfdReport report;
1047 if (aFontSize>=EFont16x16)
1051 reportSize = (dataSize<=report.Size()-headerSize?dataSize+0x06:64); //Report length. -7 is for our header first 7 bytes. +5 is for our Futaba header size
1052 report[7] = aCharacterCode>>8;
1058 reportSize = (dataSize<=report.Size()-headerSize?dataSize+0x05:64); //Report length. -7 is for our header first 7 bytes. +5 is for our Futaba header size
1062 report[0]=0x00; //Report ID
1063 report[1]=reportSize; //Report size
1064 report[2]=0x1B; //Command ID
1065 report[3]=0x6A; //Command ID
1066 report[4]=0x47; //Command ID
1067 report[5]=aFontSize; //
1068 report[6] = (unsigned char) aCharacterCode;
1069 //7th byte was set above already
1070 int sizeWritten=MIN(dataSize,report.Size()-headerSize);
1071 memcpy(report.Buffer()+headerSize, aPixels, sizeWritten);
1074 int remainingSize=dataSize;
1075 //We need to keep on sending our pixel data until we are done
1076 while (report[1]==64)
1079 remainingSize-=sizeWritten;
1080 report[0]=0x00; //Report ID
1081 report[1]=(remainingSize<=report.Size()-2?remainingSize:64); //Report length, should be 64 or the remaining size
1082 sizeWritten=(report[1]==64?63:report[1]);
1083 memcpy(report.Buffer()+2, aPixels+(dataSize-remainingSize), sizeWritten);
1090 User definable font store / transfer / delete
1091 [Code] 1BH,6AH,45H,Ps
1092 [Function] Store, transfer, or delete the User definable font to FROM.
1093 * Define the user definable font, after the user definable font is stored
1094 * The user definable font store is stored the all defined user definable font data.
1095 * The use definable font delete is deleted the all defined to FROM and RAM user definable font data.
1096 Ps = store / transfer / delete
1102 void GP1212A02A::SendCommandFontAction(TFontAction aFontAction)
1104 FutabaVfdReport report;
1105 report[0]=0x00; //Report ID
1106 report[1]=0x04; //Report size
1107 report[2]=0x1B; //Command ID
1108 report[3]=0x6A; //Command ID
1109 report[4]=0x45; //Command ID
1110 report[5]=aFontAction; //Ps
1117 [Code]1BH,4AH,46H,Pf
1118 [Function]Setting the font size
1122 Pf = 31H?8x16dot and 16x16 dot
1123 Pf = 32H?12x24 dot and 24x24 dot
1124 Pf = 33H?16x32 dot and 32x32 dot
1126 void GP1212A02A::SendCommandSelectFontSize(TFontSizeLogical aFontSoze)
1128 FutabaVfdReport report;
1129 report[0]=0x00; //Report ID
1130 report[1]=0x04; //Report size
1131 report[2]=0x1B; //Command ID
1132 report[3]=0x4A; //Command ID
1133 report[4]=0x46; //Command ID
1134 report[5]=aFontSoze; //Pf