Demonstration of SSD1308 OLED driver library

Dependencies:   mbed SSD1308_128x64_I2C

Files at this revision

API Documentation at this revision

Comitter:
wim
Date:
Mon Jul 09 20:46:27 2012 +0000
Parent:
1:00053cb70ac5
Child:
3:1337e3d65ed0
Commit message:
Temp version

Changed in this revision

SSD1308.cpp Show annotated file Show diff for this revision Revisions of this file
SSD1308.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed_logo.h Show annotated file Show diff for this revision Revisions of this file
--- a/SSD1308.cpp	Sat Jun 30 14:44:39 2012 +0000
+++ b/SSD1308.cpp	Mon Jul 09 20:46:27 2012 +0000
@@ -3,11 +3,11 @@
 //   The SSD1308 is used for example in the Seeed 128x64 OLED Display
 //   http://www.seeedstudio.com/depot/grove-oled-display-12864-p-781.html?cPath=163_167
 //
-// The original code is using (and submitted as a part of) Jeff Rowberg's I2Cdevlib library,
+// The original code is using (and has been submitted as a part of) Jeff Rowberg's I2Cdevlib library,
 // which should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
 //
 // Changelog:
-//   2011-08-25 - initial release by Andrew Schamp <schamp@gmail.com>
+//   2011-08-25 - Initial release by Andrew Schamp <schamp@gmail.com>
 //   2012-06-19 - Ported to mbed and optimised (WH)
 //       
 /* ============================================
@@ -64,6 +64,7 @@
 #if(0)
 // Standard version
 void SSD1308::clearDisplay() {
+ 
   //setDisplayOff();
   setPageAddress(0, MAX_PAGE);  // all pages
   setColumnAddress(0, MAX_COL); // all columns
@@ -74,7 +75,7 @@
     }
   }
 
-//  setDisplayOn();
+  //setDisplayOn();
 }
 #else
 //Optimised version
@@ -96,7 +97,7 @@
   }
   _i2c.stop();
 
-//  setDisplayOn();
+  //setDisplayOn();
 }
 #endif
 
@@ -116,7 +117,7 @@
     }
   }
  
-  //  setDisplayOn();  
+  //setDisplayOn();  
 }
 #else
 //Optimised version
@@ -137,12 +138,13 @@
   }
   _i2c.stop();
 
-//  setDisplayOn();
+  //setDisplayOn();
 }
 #endif
 
 
 void SSD1308::writeBitmap(int len, uint8_t* data) {
+
   //setDisplayOff();
   setPageAddress(0, MAX_PAGE);  // all pages
   setColumnAddress(0, MAX_COL); // all columns
@@ -155,24 +157,35 @@
   }
   _i2c.stop();
 
-//  setDisplayOn();
+  //setDisplayOn();
 }
 
-void SSD1308::writeChar(char chr) {
-//#ifdef SSD1308_USE_FONT
+
+// Write single character to the display using the 8x8 fontable
+// Start at current cursor location
+//     char chr character
+//     bool inverted invert pixels
+void SSD1308::writeChar(char chr, bool inverted) {
 
   const uint8_t char_index = chr - 0x20;
   for (uint8_t i = 0; i < 8; i++) {
 //     const uint8_t b = pgm_read_byte( &fontData[char_index][i] );
 //     const uint8_t b = fontData[char_index][i];     
 //     sendData( b ); 
-     sendData( fontData[char_index][i] );      
+     if (inverted) {
+       sendData( ~fontData[char_index][i] );           
+     }
+     else {
+       sendData( fontData[char_index][i] );
+     }  
   }
 
-//#endif
 }
 
-void SSD1308::writeString(uint8_t row, uint8_t col, uint16_t len, const char * text) {
+
+// Write a string to the display using the 8x8 fontable
+// Start at current cursor location
+void SSD1308::writeString(uint8_t row, uint8_t col, uint16_t len, const char * text, bool inverted) {
   uint16_t index = 0;
   setPageAddress(row, MAX_PAGE);
   const uint8_t col_addr = FONT_WIDTH*col;
@@ -180,7 +193,7 @@
 
   while ((col+index) < CHARS && (index < len)) {
      // write first line, starting at given position
-     writeChar(text[index++]);
+     writeChar(text[index++], inverted);
   }
 
   // write remaining lines
@@ -191,7 +204,7 @@
     setColumnAddress(0, MAX_COL);
     bool wrapEntireScreen = false;
     while (index + 1 < len) {
-       writeChar(text[index++]);
+       writeChar(text[index++], inverted);
        // if we've written the last character space on the screen, 
        // reset the page and column address so that it wraps around from the top again
        if (!wrapEntireScreen && (row*CHARS + col + index) > 127) {
@@ -203,6 +216,8 @@
   }
 }
 
+// Write command that has no parameters
+// 
 void SSD1308::sendCommand(uint8_t command) {
 //  I2Cdev::writeByte(m_devAddr, COMMAND_MODE, command);
 
@@ -214,10 +229,55 @@
 
 }
 
+// Write command that has one parameter
+// 
+void SSD1308::sendCommand(uint8_t command, uint8_t param1) {
+
+//  Note continuationbit is set, so COMMAND_MODE must be
+//  repeated before each databyte that serves as parameter!
+
+  _i2c.start();
+  _i2c.write(_writeOpcode);
+  
+  _i2c.write(COMMAND_MODE);      
+  _i2c.write(command);       // Write Command   
+  _i2c.write(COMMAND_MODE);      
+  _i2c.write(param1);        // Write Param1   
+
+  _i2c.stop();
+  
+}
+
+// Write command that has two parameters
+// 
+void SSD1308::sendCommand(uint8_t command, uint8_t param1, uint8_t param2) {
+
+//  Note continuationbit is set, so COMMAND_MODE must be
+//  repeated before each databyte that serves as parameter!
+
+  _i2c.start();
+  _i2c.write(_writeOpcode);
+  
+  _i2c.write(COMMAND_MODE);      
+  _i2c.write(command);       // Write Command   
+  _i2c.write(COMMAND_MODE);      
+  _i2c.write(param1);        // Write Param1   
+  _i2c.write(COMMAND_MODE);      
+  _i2c.write(param2);        // Write Param2   
+
+  _i2c.stop();
+  
+}
+
+
+
+// Write command that has multiple parameters
+// 
 void SSD1308::sendCommands(uint8_t len, uint8_t* commands) {
 
 //  I2Cdev::writeBytes(m_devAddr, COMMAND_MODE, len, commands);
-//  Note this original code is not correct, continuationbit is set!
+//  Note this original code is not correct, continuationbit is set, 
+//  so COMMAND_MODE must be repeated before each databyte that serves as parameter!
 
   _i2c.start();
   _i2c.write(_writeOpcode);
@@ -230,6 +290,8 @@
   
 }
 
+// Write databyte to display
+// Start at current cursor location
 void SSD1308::sendData(uint8_t data){
 //  I2Cdev::writeByte(m_devAddr, DATA_MODE, data);
 
@@ -241,6 +303,8 @@
   
 }
 
+// Write len bytes from buffer data to display
+// Start at current cursor location
 void SSD1308::sendData(uint8_t len, uint8_t* data) {
 //  I2Cdev::writeBytes(m_devAddr, DATA_MODE, len, data);
   
@@ -284,10 +348,22 @@
 }
 
 
+// takes one byte, 0x00 (lowest) - 0xFF (highest)
+void SSD1308::setContrastControl(uint8_t contrast) {
+//  uint8_t cmds[2] = { SET_CONTRAST, contrast };
+//  sendCommands(2, cmds); 
+  
+    sendCommand(SET_CONTRAST, contrast);  
+} 
+
+// Enable Display
+// 
 void SSD1308::setDisplayOn() {
   sendCommand(SET_DISPLAY_POWER_ON);
 }
 
+// Disable Display
+// 
 void SSD1308::setDisplayOff() {
   sendCommand(SET_DISPLAY_POWER_OFF);
 }
@@ -300,27 +376,81 @@
   }
 }
 
+// White on Black background
+// 
 void SSD1308::setDisplayNormal() {
   sendCommand(SET_NORMAL_DISPLAY);
 }
 
-
+// Black on White background
+// 
 void SSD1308::setDisplayInverse() {
   sendCommand(SET_INVERSE_DISPLAY);
 }
 
 
+// Display Flip (Left/Right, Up/Down)
+// 
+void SSD1308::setDisplayFlip(bool left, bool down) {
+  if (left) {
+    // column address   0 is mapped to SEG0 (Reset)    
+    sendCommand(SET_SEGMENT_REMAP_0);
+  }
+  else {
+    // column address 127 is mapped to SEG0    
+    sendCommand(SET_SEGMENT_REMAP_127);
+  }  
+
+  if (down) {
+    // Reset mode
+    sendCommand(SET_COMMON_REMAP_0);    
+  }
+  else {
+    // Flip Up/Down (Need to rewrite display before H effect shows)
+    sendCommand(SET_COMMON_REMAP_63);        
+  }  
+
+}
+
+// Sets Internal Iref
+//
+void SSD1308::setInternalIref() {
+  uint8_t cmds[2] = {SET_IREF_SELECTION, INTERNAL_IREF};
+  sendCommands(2, cmds); 
+}
+
+// Sets External Iref
+//
+void SSD1308::setExternalIref() {
+  uint8_t cmds[2] = {SET_IREF_SELECTION, EXTERNAL_IREF};
+  sendCommands(2, cmds); 
+}
+
+
 // Low level Init
 // Init the configuration registers in accordance with the datasheet
 //
 void SSD1308::_init() {
+
+//not complete yet  
+  sendCommand(SET_DISPLAY_POWER_OFF);
+  
+  // column address   0 is mapped to SEG0 (Reset)    
+  // row address   0 is mapped to COMM0 (Reset)      
+  sendCommand(SET_SEGMENT_REMAP_0);
+  sendCommand(SET_COMMON_REMAP_0);    
+  
+  uint8_t cmds[2] = { SET_COMMON_CONF, COMMON_BASE | COMMON_ALTERNATIVE | COMMON_LEFTRIGHT_NORMAL};
+  sendCommands(2, cmds); 
+
   setHorizontalAddressingMode();
-  clearDisplay();
   
-  sendCommand(SET_DISPLAY_POWER_OFF);
+  setExternalIref();
     
   sendCommand(SET_NORMAL_DISPLAY);  
   
-  sendCommand(SET_DISPLAY_POWER_ON);  
+  clearDisplay();   
+  
+  sendCommand(SET_DISPLAY_POWER_ON);
 }
 
--- a/SSD1308.h	Sat Jun 30 14:44:39 2012 +0000
+++ b/SSD1308.h	Mon Jul 09 20:46:27 2012 +0000
@@ -3,11 +3,11 @@
 //   The SSD1308 is used for example in the Seeed 128x64 OLED Display
 //   http://www.seeedstudio.com/depot/grove-oled-display-12864-p-781.html?cPath=163_167
 //
-// The original code is using (and submitted as a part of) Jeff Rowberg's I2Cdevlib library,
+// The original code is using (and has been submitted as a part of) Jeff Rowberg's I2Cdevlib library,
 // which should (hopefully) always be available at https://github.com/jrowberg/i2cdevlib
 //
 // Changelog:
-//   2011-08-25 - initial release by Andrew Schamp <schamp@gmail.com>
+//   2011-08-25 - Initial release by Andrew Schamp <schamp@gmail.com>
 //   2012-06-19 - Ported to mbed and optimised (WH)
 //             
 /* ============================================
@@ -65,7 +65,7 @@
 
 #define SET_CONTRAST               0x81 // takes one byte, 0x00 - 0xFF
 
-#define SET_SEGMENT_REMAP_0        0xA0 // column address 0 is mapped to SEG0
+#define SET_SEGMENT_REMAP_0        0xA0 // column address 0 is mapped to SEG0 (Reset)
 #define SET_SEGMENT_REMAP_127      0xA1 // column address 127 is mapped to SEG0
 
 #define SET_ENTIRE_DISPLAY_ON      0xA5 // turns all pixels on, does not affect RAM
@@ -96,10 +96,21 @@
 #define PAGE7                      0x07
 #define SET_PAGE_START_ADDRESS     0xB0 // | with a page number to get start address
 
+#define SET_COMMON_REMAP_0         0xC0 // row address  0 is mapped to COM0 (Reset)
+#define SET_COMMON_REMAP_63        0xC8 // row address 63 is mapped to COM0
+
+
 #define SET_DISPLAY_OFFSET         0xD3
 
 #define SET_DISPLAY_CLOCK          0xD5
 
+#define COMMON_BASE                0x02 // 
+#define COMMON_SEQUENTIAL          0x00 // Sequential common pins config
+#define COMMON_ALTERNATIVE         0x10 // Odd/Even common pins config (Reset)
+#define COMMON_LEFTRIGHT_NORMAL    0x00 // LeftRight Normal (Reset)
+#define COMMON_LEFTRIGHT_FLIP      0x20 // LeftRight Flip 
+#define SET_COMMON_CONF            0xDA
+
 #define VCOMH_DESELECT_0_65_CODE   0x00
 #define VCOMH_DESELECT_0_77_CODE   0x20
 #define VCOMH_DESELECT_0_83_CODE   0x30
@@ -132,7 +143,7 @@
     
     // x, y is position (x is row (i.e., page), y is character (0-15), starting at top-left)
     // text will wrap around until it is done.
-    void writeString(uint8_t row, uint8_t col, uint16_t len, const char* txt);
+    void writeString(uint8_t row, uint8_t col, uint16_t len, const char* txt, bool inverted = false);
     
     //void setXY(uint8_t, uint8_t y);
 
@@ -179,6 +190,12 @@
     void setDisplayNormal();
     void setDisplayInverse();
     
+
+    // Display Flip (Up/Down, Left/Right)
+    // 
+    void setDisplayFlip(bool left, bool down);
+
+
     // Set vertical shift by COM from 0 - 63 (0x00 - 0x3F)
     // set to 0x00 after RESET
     void setDisplayOffset(uint8_t offset);
@@ -224,10 +241,13 @@
     
   
   private:
-    // sends a single-byte command (given) to device
-    void sendCommand(uint8_t command);
+    // sends a command and optional params to device
+    void sendCommand(uint8_t command);  
+    void sendCommand(uint8_t command, uint8_t param1);
+    void sendCommand(uint8_t command, uint8_t param1, uint8_t param2);    
+            
     void sendCommands(uint8_t len, uint8_t* buf);
-    void writeChar(char chr);
+    void writeChar(char chr, bool inverted);
 
     // Init the configuration registers in accordance with the datasheet
     void _init();
--- a/main.cpp	Sat Jun 30 14:44:39 2012 +0000
+++ b/main.cpp	Mon Jul 09 20:46:27 2012 +0000
@@ -46,9 +46,10 @@
     pc.printf("7: Display Invert\n\r");                    
     pc.printf("8: Display Normal\n\r");                
     pc.printf("9: Display Bitmap\n\r");                    
-//    pc.printf("A: \n\r");                    
-//    pc.printf("B: \n\r");                    
-//    pc.printf("C: \n\r");                        
+    pc.printf("A: Brightness Ramp\n\r");                    
+    pc.printf("B: Send Inverted Message\n\r");  
+    pc.printf("C: Flip and Mirror\n\r");                      
+
 //    pc.printf("D: \n\r");                            
 //    pc.printf("E: \n\r");                                
 //    pc.printf("F: \n\r");                                    
@@ -133,6 +134,9 @@
 
 int main() {
     bool running=true;
+    bool left = true;
+    bool down = true;
+   
     char command;
 
     init_interfaces();
@@ -181,7 +185,7 @@
                      break;
           
           case '3' :
-                     pc.printf("Fill Display 0xA5\n\r");            
+                     pc.printf("Fill Display 0xAA\n\r");            
                      oled.fillDisplay(0xA5);
                      break;
 
@@ -216,12 +220,33 @@
                      break;
 
           case 'A' :
-                   
+                     pc.printf("Brightness Ramp Down\r\n");          
+                     for (int contrast=0x7F; contrast >= 0x00; contrast--) { 
+                        oled.setContrastControl(contrast);
+                        wait(0.05);
+                     }                   
+                     
+                     wait(1);
+                     
+                     pc.printf("Brightness Ramp Up\r\n");          
+                     for (int contrast=0x00; contrast <= 0x7F; contrast++) { 
+                        oled.setContrastControl(contrast);
+                        wait(0.05);
+                     }                   
+
                      break;
 
           case 'B' :
-          
-                    break;
+                     pc.printf("Send Inverted Message\n\r");
+                     oled.writeString(0, 0, 13, "Hello World !", true);                                                 
+                     break;
+                     
+          case 'C' :
+                     pc.printf("Flip and Mirror (Rewrite display to show horizontal effect)\n\r");
+                     left = !left;
+                     down = !down;
+                     oled.setDisplayFlip(left, down);                     
+                     break;                   
                               
         } //switch
       }//if
--- a/mbed_logo.h	Sat Jun 30 14:44:39 2012 +0000
+++ b/mbed_logo.h	Mon Jul 09 20:46:27 2012 +0000
@@ -32,7 +32,7 @@
 0x3C, 0x3E, 0x3E, 0x3E, 0x3E, 0x7E, 0xFC, 0xFC, 0xFC, 0xF8, 0xF8, 0xFC, 0x7C, 0x3C, 0x3E, 0x3E,
 0x3E, 0x3E, 0x7E, 0xFC, 0xFC, 0xFC, 0xF8, 0xF0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
 0xFF, 0xFF, 0xFF, 0xFF, 0x7C, 0x3C, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x7E, 0x7C, 0xFC, 0xFC, 0xF8,
-0xF0, 0xE0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0x7C,
+0xF0, 0xE0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFC,
 0x7C, 0x3E, 0x3E, 0x3E, 0x3E, 0x3E, 0x3C, 0x7C, 0xFC, 0xF8, 0xF8, 0xF0, 0xE0, 0x80, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC, 0xFC, 0x7E, 0x7E, 0x3E, 0x3E, 0x3E, 0x3E,
 0x3C, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
@@ -40,16 +40,16 @@
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF,
-0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0xF8, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x38, 0x38,
-0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00,
+0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x39, 0x38,
+0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x39, 0x3F, 0x3F, 0x3F, 0x3F, 0x3E, 0x00,
 0x00, 0x00, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0x8F, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF,
-0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF8, 0xFE, 0x7F,
-0x3F, 0x1F, 0x0F, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0F, 0x1F, 0x3F, 0x7F, 0xFE, 0xF8, 0xF0,
-0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0x70, 0x30, 0x00, 0x00, 0x00,
+0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF8, 0xFE, 0x7F,
+0x3F, 0x1F, 0x0F, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF, 0xFC, 0xF0,
+0xF0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xF0, 0xF0, 0xF8, 0xF8, 0x70, 0x60, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x01, 0x0F, 0x1F, 0x3F, 0x7F, 0xFF, 0xFC, 0xF8, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0xF0,
 0xF0, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00,
@@ -57,7 +57,7 @@
 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03,
 0x03, 0x03, 0x01, 0x00, 0x00, 0x01, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
-0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01,
 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,