ripred

spi2I2C.ino

Jan 17th, 2023
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 45.51 KB | None | 0 0
  1. #include "xeniumspi.h"
  2. #include "xboxsmbus.h"
  3. #include "src/SMWire/SMWire.h"
  4. #include "src/i2c-oled/I2cCharDisplay.h"
  5. //#include "src/i2c-lcd/LiquidCrystal_I2C.h"
  6. //#include "src/ws2812b/FastLED.h"
  7. #include "config.h"
  8.  
  9. void completeCommand(int16_t * c);
  10.  
  11. I2cCharDisplay oled2004(OLED_TYPE, OLEDPRIMARY, 4);  //Uncomment for using with a 20x4 us2066 based oled as primary lcd
  12. //I2cCharDisplay lcd2004(LCD_TYPE, LCDPRIMARY, 4); //Uncomment for use with a lcd2004 with a i2c backpack as primary lcd
  13. I2cCharDisplay oledsec(OLED_TYPE, OLEDSECONDARY, 4);  //Uncomment for using with a 20x2 us2066 based oled as secondary lcd
  14. //I2cCharDisplay lcdsec(LCD_TYPE, LCDSECONDARY, 2); //Uncomment for use with a lcd1602 with a i2c backpack at A1 as seconday lcd
  15.  
  16. #define LED_PIN 4
  17. const uint8_t ss_in = 17, miso = 14, mosi = 16, sck = 15, ss_out = A2;  //SPI pin numbers, ss_in is the CS for the slave. As Xenium doesn't seem to use CS, ss_out is connected to ss_in on the PCB to manually trigger CS.
  18. const uint8_t i2c_sda = 2, i2c_scl = 3;                                 //i2c pins for SMBus
  19. const uint8_t backlightPin = 10, contrastPin = 9;                       //Pin nubmers for backlight and contrast. Must be PWM enabled
  20. uint8_t cursorPosCol = 0, cursorPosRow = 0;                             //Track the position of the cursor
  21. uint8_t wrapping = 0, scrolling = 0;                                    //Xenium spi command toggles for the lcd screen.
  22.  
  23. //SPI Data
  24. int16_t RxQueue[256];   //Input FIFO buffer for raw SPI data from Xenium
  25. uint8_t QueuePos;       //Tracks the current position in the FIFO queue that is being processed
  26. uint8_t QueueRxPos;     //Tracks the current position in the FIFO queue of the unprocessed input data (raw realtime SPI data)
  27. uint8_t SPIState;       //SPI State machine flag to monitor the SPI bus state can = SPI_ACTIVE, SPI_IDLE, SPI_SYNC, SPI_WAIT
  28. uint32_t SPIIdleTimer;  //Tracks how long the SPI bus has been idle for
  29.  
  30. //I2C Bus
  31. uint32_t SMBusTimer;          //Timer used to trigger SMBus reads
  32. uint8_t i2cCheckCount = 0;    //Tracks what check we're up to of the i2c bus busy state
  33. uint8_t I2C_BUSY_CHECKS = 5;  //To ensure we don't interfere with the actual Xbox's SMBus activity, we check the bus for activity for sending.
  34.  
  35. //SPI Bus Receiver Interrupt Routine
  36. ISR(SPI_STC_vect) {
  37.   RxQueue[QueueRxPos] = SPDR;
  38.   QueueRxPos++;  //This is an unsigned 8 bit variable, so will reset back to 0 after 255 automatically
  39.   SPIState = SPI_ACTIVE;
  40. }
  41. int spiTimeLimiter = 10000;
  42. int SaverActive = 200;
  43. //CRGB leds[NUM_LEDS];
  44. int bitcount = 0;
  45. char smcArray[3];
  46. String smcString;
  47. String Green = "GRN";
  48. String Blue = "BLUE";
  49. String Red = "RED";
  50. String Purple = "PPL";
  51. String Pink = "PINK";
  52. String Orange = "ORG";
  53. String Yellow = "YEL";
  54. int FOCUS = 0;
  55. int CONEXANT = 0;
  56. int shiftTimer = 0;
  57.  
  58. void setup() {
  59.   pinMode(2, INPUT_PULLUP);
  60.   pinMode(3, INPUT_PULLUP);
  61.   pinMode(ss_out, OUTPUT);
  62.   digitalWrite(ss_out, HIGH);  //Force SPI CS signal high while we setup
  63.   analogWrite(contrastPin, LOW);
  64.   analogWrite(backlightPin, LOW);
  65.   Serial.begin(9600);
  66.   delay(5);
  67.   memset(RxQueue, -1, 256);
  68.   //  LEDS.addLeds<TYPE_LEDS,LED_PIN,GRB>(leds,NUM_LEDS);
  69.   //  LEDS.setBrightness(BRIGHT_LEDS);
  70.  
  71.  
  72.  
  73.   //I put my logic analyser on the Xenium SPI bus to confirm the bus properties.
  74.   //The master clocks at ~16kHz. SPI Clock is high when inactive, data is valid on the trailing edge (CPOL/CPHA=1. Also known as SPI mode 3)
  75.   SPCR |= _BV(SPE);   //Turn on SPI. We don't set the MSTR bit so it's slave.
  76.   SPCR |= _BV(SPIE);  //Enable to SPI Interrupt Vector
  77.   SPCR |= _BV(CPOL);  //SPI Clock is high when inactive
  78.   SPCR |= _BV(CPHA);  //Data is Valid on Clock Trailing Edge
  79.  
  80.   Wire.begin(0xDD);  //Random address that is different from existing bus devices.
  81.  
  82.   if (mainScreenType == "us2066") {
  83.     spiTimeLimiter = 10000;
  84.     oled2004.begin();
  85.     oled2004.cursorOff();
  86.     oled2004.displayOn();
  87.     oled2004.setBrightness(255);
  88.     oled2004.cursorMove(1, 1);
  89.     oled2004.print(" System Booting ");
  90.     oled2004.cursorMove(2, 1);
  91.     oled2004.print("   Please Wait...  ");
  92.     oled2004.cursorMove(3, 1);
  93.     oled2004.print(" Thomas Lucarelli");
  94.     oled2004.cursorMove(4, 1);
  95.     oled2004.print("ViolentLambs");
  96.     oled2004.displayShiftRight();
  97.     delay(200);
  98.     oled2004.displayShiftRight();
  99.     delay(200);
  100.     oled2004.displayShiftRight();
  101.     delay(200);
  102.     oled2004.displayShiftRight();
  103.     delay(200);
  104.     oled2004.displayShiftLeft();
  105.     delay(200);
  106.     oled2004.displayShiftLeft();
  107.     delay(200);
  108.     oled2004.displayShiftLeft();
  109.     delay(200);
  110.     oled2004.displayShiftLeft();
  111.     delay(200);
  112.     oled2004.cursorMove(1, 1);
  113.   }
  114.  
  115.   //if (mainScreenType == "lcd2004") {
  116.   //spiTimeLimiter = 10000;
  117.   // lcd2004.begin();
  118.   // lcd2004.cursorOff();
  119.   //lcd2004.displayOn();
  120.   // lcd2004.setBrightness(255);
  121.   //lcd2004.cursorMove(1, 1);
  122.   // lcd2004.print("Initializing spi");
  123.   // lcd2004.cursorMove(2, 1);
  124.   //lcd2004.print(" TechWizard-DiY");
  125.   //lcd2004.cursorMove(3, 1);
  126.   //lcd2004.print("Initializing i2c");
  127.   //lcd2004.cursorMove(4, 1);
  128.   //lcd2004.print("    RYZEE119");
  129.   //lcd2004.displayShiftRight();
  130.   //delay(200);
  131.   //lcd2004.displayShiftRight();
  132.   //delay(200);
  133.   //lcd2004.displayShiftRight();
  134.   //delay(200);
  135.   //lcd2004.displayShiftRight();
  136.   //delay(200);
  137.   //lcd2004.displayShiftLeft();
  138.   //delay(200);
  139.   //lcd2004.displayShiftLeft();
  140.   //delay(200);
  141.   //lcd2004.displayShiftLeft();
  142.   //delay(200);
  143.   //lcd2004.displayShiftLeft();
  144.   //delay(200);
  145.   //lcd2004.cursorMove(1, 1);
  146.   //}
  147.  
  148.   //  if (secScreenType == "lcd1602" ) {
  149.   //    spiTimeLimiter = 500;
  150.   //      lcdsec.begin();
  151.   //      lcdsec.cursorOff();;
  152.   //    analogWrite(backlightPin, DEFAULT_BACKLIGHT); //0-255 Higher number is brighter.
  153.   //    analogWrite(contrastPin, DEFAULT_CONTRAST); //0-255 Lower number is higher contrast
  154.   //      lcdsec.displayOn();
  155.   //      lcdsec.cursorMove(1, 1);
  156.   //      lcdsec.print("  Waiting  for  ");
  157.   //lcdsec.cursorMove(2, 1);
  158.   //lcdsec.print(" Hardware  Data ");
  159.   //lcdsec.cursorMove(1, 1);
  160.   //}
  161.  
  162.   //  if (secScreenType == "lcd2004" ) {
  163.   //    spiTimeLimiter = 500;
  164.   //      lcdsec.begin();
  165.   //      lcdsec.cursorOff();;
  166.   //    analogWrite(backlightPin, DEFAULT_BACKLIGHT); //0-255 Higher number is brighter.
  167.   //    analogWrite(contrastPin, DEFAULT_CONTRAST); //0-255 Lower number is higher contrast
  168.   //     lcdsec.displayOn();
  169.   //      lcdsec.cursorMove(1, 1);
  170.   //      lcdsec.print("  Waiting  for  ");
  171.   //      lcdsec.cursorMove(2, 1);
  172.   //      lcdsec.print(" Hardware  Data ");
  173.   //      lcdsec.cursorMove(1, 1);
  174.   //  }
  175.  
  176.   if (secScreenType == "us2066") {
  177.     spiTimeLimiter = 500;
  178.     oledsec.begin();
  179.     oledsec.cursorOff();
  180.     ;
  181.     oledsec.displayOn();
  182.     oledsec.cursorMove(1, 1);
  183.     oledsec.print("   Waiting   for  ");
  184.     oledsec.cursorMove(2, 1);
  185.     oledsec.print("  Hardware   Data ");
  186.     oledsec.cursorMove(1, 1);
  187.   }
  188.  
  189.  
  190.   TWBR = ((F_CPU / 100000) - 16) / 2;  //Change I2C frequency closer to OG Xbox SMBus speed. ~100kHz Not compulsory really, but a safe bet
  191.  
  192.   //Speed up PWM frequency. Gets rid of flickering
  193.   TCCR1B &= 0b11111000;
  194.   TCCR1B |= (1 << CS00);  //Change Timer Prescaler for PWM
  195.   oled2004.cursorMove(1, 1);
  196.   //  lcd2004.cursorMove(1, 1);
  197.   //  lcdsec.cursorMove(1, 1);
  198.   oledsec.cursorMove(1, 1);
  199.  
  200.   //delay(250);
  201.   uint32_t spiReadyTimer = millis();
  202.   bool spiReady = false;
  203.  
  204.   //Hold until spi bus is ready
  205.   while (!spiReady) {
  206.     if (digitalRead(sck) == 0) {
  207.       spiReadyTimer = millis();
  208.     }
  209.     //SPI Clock high for 100ms
  210.     else if (millis() - spiReadyTimer > 100) {
  211.       spiReady = true;
  212.     }
  213.   }
  214.   //  for(int whiteLed = 0; whiteLed < NUM_LEDS; whiteLed = whiteLed + 1) {
  215.   //      leds[whiteLed] = CRGB::BOOT_LEDS;
  216.   //  }
  217.   //  FastLED.show();
  218.   digitalWrite(ss_out, LOW);  //SPI Slave is ready to receive data
  219.   oled2004.clear();
  220. }
  221.  
  222.  
  223. void loop() {
  224.   //SPI to Parallel Conversion State Machine
  225.   //One completion of processing command, set the buffer data value to -1
  226.   //to indicate processing has been completed.
  227.   shiftTimer++;
  228.   if (shiftTimer == 10000) {
  229.     if (primaryBurnIn == "enable") {
  230.       oled2004.displayShiftLeft();
  231.     }
  232.     if (secondaryBurnIn == "enable") {
  233.       oledsec.displayShiftLeft();
  234.     }
  235.     shiftTimer == 0;
  236.   }
  237.   if (QueueRxPos != QueuePos) {
  238.     switch (RxQueue[(uint8_t)QueuePos]) {
  239.       case -1:
  240.         //No action required.
  241.         break;
  242.  
  243.       case XeniumCursorHome:
  244.         cursorPosRow = 0;
  245.         cursorPosCol = 0;
  246.         if ((mainScreenType == "lcd2004") || (mainScreenType == "lcd1602")) {
  247.           //            lcd2004.home();
  248.         }
  249.         if (mainScreenType == "us2066") {
  250.           oled2004.home();
  251.         }
  252.         if ((secScreenType == "lcd2004") || (secScreenType == "lcd1602")) {
  253.           //          lcdsec.home();
  254.         }
  255.         if (secScreenType == "us2066") {
  256.           oledsec.home();
  257.         }
  258.         completeCommand(&RxQueue[(uint8_t)QueuePos]);
  259.         break;
  260.  
  261.       case XeniumHideDisplay:
  262.         //        if ((mainScreenType == "lcd2004" ) || (mainScreenType == "lcd1602" )) {
  263.         // lcd2004.displayOff();
  264.         //        }
  265.         if (mainScreenType == "us2066") {
  266.           oled2004.displayOff();
  267.         }
  268.         //        if ((secScreenType == "lcd2004" ) || (secScreenType == "lcd1602" )) {
  269.         //            lcdsec.displayOff();
  270.         //        }
  271.         if (secScreenType == "us2066") {
  272.           oledsec.displayOff();
  273.         }
  274.         completeCommand(&RxQueue[(uint8_t)QueuePos]);
  275.         break;
  276.  
  277.       case XeniumShowDisplay:
  278.         //        if ((mainScreenType == "lcd2004" ) || (mainScreenType == "lcd1602" )) {
  279.         //           lcd2004.displayOn();
  280.         //        }
  281.         if (mainScreenType == "us2066") {
  282.           oled2004.displayOn();
  283.         }
  284.         //        if ((secScreenType == "lcd2004" ) || (secScreenType == "lcd1602" )) {
  285.         //            lcdsec.displayOn();
  286.         //        }
  287.         if (secScreenType == "us2066") {
  288.           oledsec.displayOn();
  289.         }
  290.         completeCommand(&RxQueue[(uint8_t)QueuePos]);
  291.         break;
  292.  
  293.       case XeniumHideCursor:
  294.         //        if ((mainScreenType == "lcd2004" ) || (mainScreenType == "lcd1602" )) {
  295.         //           lcd2004.cursorOff();
  296.         //        }
  297.         if (mainScreenType == "us2066") {
  298.           oled2004.cursorOff();
  299.         }
  300.         //        if ((secScreenType == "lcd2004" ) || (secScreenType == "lcd1602" )) {
  301.         //            lcdsec.cursorOff();
  302.         //        }
  303.         if (secScreenType == "us2066") {
  304.           oledsec.cursorOff();
  305.         }
  306.         completeCommand(&RxQueue[(uint8_t)QueuePos]);
  307.         break;
  308.  
  309.       case XeniumShowUnderLineCursor:
  310.       case XeniumShowBlockCursor:
  311.       case XeniumShowInvertedCursor:
  312.  
  313.         completeCommand(&RxQueue[(uint8_t)QueuePos]);
  314.         break;
  315.  
  316.       case XeniumBackspace:
  317.         if (cursorPosCol > 0) {
  318.           cursorPosCol--;
  319.           //          if ((mainScreenType == "lcd2004" ) || (mainScreenType == "lcd1602" )) {
  320.           //             lcd2004.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  321.           //             lcd2004.print(" ");
  322.           //             lcd2004.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  323.           //          }
  324.           if (mainScreenType == "us2066") {
  325.             oled2004.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  326.             oled2004.print(" ");
  327.             oled2004.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  328.           }
  329.           //          if ((secScreenType == "lcd2004" ) || (secScreenType == "lcd1602" )) {
  330.           //              lcdsec.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  331.           //              lcdsec.print(" ");
  332.           //              lcdsec.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  333.           //          }
  334.           if (secScreenType == "us2066") {
  335.             oledsec.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  336.             oledsec.print(" ");
  337.             oledsec.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  338.           }
  339.         }
  340.         completeCommand(&RxQueue[(uint8_t)QueuePos]);
  341.         break;
  342.  
  343.       case XeniumLineFeed:  //Move Cursor down one row, but keep column
  344.         if (cursorPosRow < 3) {
  345.           cursorPosRow++;
  346.           //          if ((mainScreenType == "lcd2004" ) || (mainScreenType == "lcd1602" )) {
  347.           //             lcd2004.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  348.           //          }
  349.           if (mainScreenType == "us2066") {
  350.             oled2004.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  351.           }
  352.           //          if ((secScreenType == "lcd2004" ) || (secScreenType == "lcd1602" )) {
  353.           //              lcdsec.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  354.           //          }
  355.           if (secScreenType == "us2066") {
  356.             oledsec.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  357.           }
  358.         }
  359.         completeCommand(&RxQueue[(uint8_t)QueuePos]);
  360.         break;
  361.  
  362.       case XeniumDeleteInPlace:  //Delete the character at the current cursor position
  363.         //        if ((mainScreenType == "lcd2004" ) || (mainScreenType == "lcd1602" )) {
  364.         //           lcd2004.print(" ");
  365.         //           lcd2004.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  366.         //        }
  367.         if (mainScreenType == "us2066") {
  368.           oled2004.print(" ");
  369.           oled2004.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  370.         }
  371.         if ((secScreenType == "lcd2004") || (secScreenType == "lcd1602")) {
  372.           //            lcdsec.print(" ");
  373.           //            lcdsec.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  374.         }
  375.         if (secScreenType == "us2066") {
  376.           oledsec.print(" ");
  377.           oledsec.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  378.         }
  379.         completeCommand(&RxQueue[(uint8_t)QueuePos]);
  380.         break;
  381.  
  382.       case XeniumFormFeed:  //Formfeed just clears the screen and resets the cursor.
  383.         cursorPosRow = 0;
  384.         cursorPosCol = 0;
  385.         //        if ((mainScreenType == "lcd2004" ) || (mainScreenType == "lcd1602" )) {
  386.         //           lcd2004.clear();
  387.         //           lcd2004.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  388.         //        }
  389.         if (mainScreenType == "us2066") {
  390.           oled2004.clear();
  391.           oled2004.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  392.         }
  393.         //        if ((secScreenType == "lcd2004" ) || (secScreenType == "lcd1602" )) {
  394.         //            lcdsec.clear();
  395.         //            lcdsec.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  396.         //        }
  397.         if (secScreenType == "us2066") {
  398.           oledsec.clear();
  399.           oledsec.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  400.         }
  401.         completeCommand(&RxQueue[(uint8_t)QueuePos]);
  402.         break;
  403.  
  404.       case XeniumCarriageReturn:  //Carriage returns moves the cursor to the start of the current line
  405.         cursorPosCol = 0;
  406.         //        if ((mainScreenType == "lcd2004" ) || (mainScreenType == "lcd1602" )) {
  407.         //          lcd2004.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  408.         //        }
  409.         if (mainScreenType == "us2066") {
  410.           oled2004.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  411.         }
  412.         //        if ((secScreenType == "lcd2004" ) || (secScreenType == "lcd1602" )) {
  413.         //            lcdsec.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  414.         //        }
  415.         if (secScreenType == "us2066") {
  416.           oledsec.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  417.         }
  418.         completeCommand(&RxQueue[(uint8_t)QueuePos]);
  419.         break;
  420.  
  421.       case XeniumSetCursorPosition:  //Sets the row and column of cursor. The following two bytes are the row and column.
  422.         if (RxQueue[(uint8_t)(QueuePos + 2)] != -1) {
  423.           uint8_t col = RxQueue[(uint8_t)(QueuePos + 1)];  //Column
  424.           uint8_t row = RxQueue[(uint8_t)(QueuePos + 2)];  //Row
  425.           if (col < 20 && row < 4) {
  426.             //            if ((mainScreenType == "lcd2004" ) || (mainScreenType == "lcd1602" )) {
  427.             //              lcd2004.cursorMove((row + 1), (col + 1));
  428.             //              cursorPosCol = col, cursorPosRow = row;
  429.             //            }
  430.             if (mainScreenType == "us2066") {
  431.               oled2004.cursorMove((row + 1), (col + 1));
  432.               cursorPosCol = col, cursorPosRow = row;
  433.             }
  434.             //            if ((secScreenType == "lcd2004" ) || (secScreenType == "lcd1602" )) {
  435.             //                lcdsec.cursorMove((row + 1), (col + 1));
  436.             //              cursorPosCol = col, cursorPosRow = row;
  437.             //            }
  438.             if (secScreenType == "us2066") {
  439.               oledsec.cursorMove((row + 1), (col + 1));
  440.               cursorPosCol = col, cursorPosRow = row;
  441.             }
  442.           }
  443.           completeCommand(&RxQueue[(uint8_t)QueuePos]);
  444.           completeCommand(&RxQueue[(uint8_t)(QueuePos + 1)]);
  445.           completeCommand(&RxQueue[(uint8_t)(QueuePos + 2)]);
  446.         }
  447.         break;
  448.  
  449.       case XeniumSetBacklight:
  450.         //The following byte after the backlight command is the brightness value
  451.         //Value is 0-100 for the backlight brightness. 0=OFF, 100=ON
  452.         //AVR PWM Output is 0-255. We multiply by 2.55 to match AVR PWM range.
  453.         if (RxQueue[(uint8_t)(QueuePos + 1)] != -1) {  //ensure the command is complete
  454.           uint8_t brightness = RxQueue[(uint8_t)(QueuePos + 1)];
  455.           if (brightness >= 0 && brightness <= 100) {
  456.             //            if ((mainScreenType == "lcd2004" ) || (mainScreenType == "lcd1602" )) {
  457.             //              analogWrite(backlightPin, (uint8_t)(brightness * 2.55f));
  458.             //            }
  459.             if (mainScreenType == "us2066") {
  460.               oled2004.setBrightness((uint8_t)(brightness * 2.55f));  //0-255 for AVR PWM
  461.             }
  462.             //            if ((secScreenType == "lcd2004" ) || (secScreenType == "lcd1602" )) {
  463.             //              analogWrite(backlightPin, (uint8_t)(brightness * 2.55f));
  464.             //            }
  465.             if (secScreenType == "us2066") {
  466.               oledsec.setBrightness((uint8_t)(brightness * 2.55f));  //0-255 for AVR PWM
  467.             }
  468.           }
  469.           completeCommand(&RxQueue[(uint8_t)QueuePos]);
  470.           completeCommand(&RxQueue[(uint8_t)(QueuePos + 1)]);
  471.         }
  472.         break;
  473.  
  474.       case XeniumSetContrast:
  475.         //The following byte after the contrast command is the contrast value
  476.         //Value is 0-100 0=Very Light, 100=Very Dark
  477.         //AVR PWM Output is 0-255. We multiply by 2.55 to match AVR PWM range.
  478.         if (RxQueue[(uint8_t)(QueuePos + 1)] != -1) {                      //ensure the command is complete
  479.           uint8_t contrastValue = 100 - RxQueue[(uint8_t)(QueuePos + 1)];  //needs to convert to 100-0 instead of 0-100.
  480.           if (contrastValue >= 0 && contrastValue <= 100) {
  481.             //            if ((mainScreenType == "lcd2004" ) || (mainScreenType == "lcd1602" )) {
  482.             //              analogWrite(contrastPin, (uint8_t)(contrastValue * 2.55f));
  483.             //            }
  484.             if (mainScreenType == "us2066") {
  485.               //NOT CODED YET
  486.             }
  487.             //            if ((secScreenType == "lcd2004" ) || (secScreenType == "lcd1602" )) {
  488.             //              analogWrite(contrastPin, (uint8_t)(contrastValue * 2.55f));
  489.             //            }
  490.             if (secScreenType == "us2066") {
  491.               //NOT CODED YET
  492.             }
  493.           }
  494.           completeCommand(&RxQueue[(uint8_t)QueuePos]);
  495.           completeCommand(&RxQueue[(uint8_t)(QueuePos + 1)]);
  496.         }
  497.         break;
  498.  
  499.       case XeniumReboot:
  500.         cursorPosRow = 0;
  501.         cursorPosCol = 0;
  502.         //        if ((mainScreenType == "lcd2004" ) || (mainScreenType == "lcd1602" )) {
  503.         //          lcd2004.clear();
  504.         //        }
  505.         if (mainScreenType == "us2066") {
  506.           oled2004.clear();
  507.         }
  508.         //        if ((secScreenType == "lcd2004" ) || (secScreenType == "lcd1602" )) {
  509.         //            lcdsec.clear();
  510.         //        }
  511.         if (secScreenType == "us2066") {
  512.           oledsec.clear();
  513.         }
  514.         completeCommand(&RxQueue[(uint8_t)QueuePos]);
  515.         break;
  516.  
  517.       case XeniumCursorMove:
  518.         //The following 2 bytes after the initial command is the direction to move the cursor
  519.         //offset+1 is always 27, offset+2 is 65,66,67,68 for Up,Down,Right,Left
  520.         if (RxQueue[(uint8_t)(QueuePos + 1)] == 27 && RxQueue[(uint8_t)(QueuePos + 2)] != -1) {
  521.  
  522.           switch (RxQueue[(uint8_t)(QueuePos + 2)]) {
  523.             case 65:  //UP
  524.               if (cursorPosRow > 0) cursorPosRow--;
  525.               break;
  526.             case 66:  //DOWN
  527.               if (cursorPosRow < 3) cursorPosRow++;
  528.               break;
  529.             case 67:  //RIGHT
  530.               if (cursorPosCol < 19) cursorPosCol++;
  531.               break;
  532.             case 68:  //LEFT
  533.               if (cursorPosCol > 0) cursorPosCol--;
  534.               break;
  535.             default:
  536.               //Error: Invalid cursor direction
  537.               break;
  538.           }
  539.           //          if ((mainScreenType == "lcd2004" ) || (mainScreenType == "lcd1602" )) {
  540.           //             lcd2004.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  541.           //          }
  542.           if (mainScreenType == "us2066") {
  543.             oled2004.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  544.           }
  545.           //          if ((secScreenType == "lcd2004" ) || (secScreenType == "lcd1602" )) {
  546.           //              lcdsec.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  547.           //          }
  548.           if (secScreenType == "us2066") {
  549.             oledsec.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  550.           }
  551.  
  552.           completeCommand(&RxQueue[(uint8_t)QueuePos]);
  553.           completeCommand(&RxQueue[(uint8_t)(QueuePos + 1)]);
  554.           completeCommand(&RxQueue[(uint8_t)(QueuePos + 2)]);
  555.         }
  556.         break;
  557.  
  558.       //Scrolling and wrapping commands are handled here.
  559.       //The flags are toggled, but are not implemented properly yet
  560.       //My testing seems to indicates it's not really needed.
  561.       case XeniumWrapOff:
  562.         wrapping = 0;
  563.         //        if ((mainScreenType == "lcd2004" ) || (mainScreenType == "lcd1602" )) {
  564.         //           lcd2004.displayShiftOff();
  565.         //        }
  566.         if (mainScreenType == "us2066") {
  567.           oled2004.displayShiftOff();
  568.         }
  569.         //        if ((secScreenType == "lcd2004" ) || (secScreenType == "lcd1602" )) {
  570.         //            lcdsec.displayShiftOff();
  571.         //        }
  572.         if (secScreenType == "us2066") {
  573.           oledsec.displayShiftOff();
  574.         }
  575.         completeCommand(&RxQueue[(uint8_t)QueuePos]);
  576.         break;
  577.  
  578.       case XeniumWrapOn:
  579.         wrapping = 1;
  580.         //        if ((mainScreenType == "lcd2004" ) || (mainScreenType == "lcd1602" )) {
  581.         //           lcd2004.displayShiftOn();
  582.         //        }
  583.         if (mainScreenType == "us2066") {
  584.           oled2004.displayShiftOn();
  585.         }
  586.         //        if ((secScreenType == "lcd2004" ) || (secScreenType == "lcd1602" )) {
  587.         //            lcdsec.displayShiftOn();
  588.         //        }
  589.         if (secScreenType == "us2066") {
  590.           oledsec.displayShiftOn();
  591.         }
  592.         completeCommand(&RxQueue[(uint8_t)QueuePos]);
  593.         break;
  594.  
  595.       case XeniumScrollOff:
  596.         scrolling = 0;
  597.         completeCommand(&RxQueue[(uint8_t)QueuePos]);
  598.         break;
  599.  
  600.       case XeniumScrollOn:
  601.         scrolling = 1;
  602.         completeCommand(&RxQueue[(uint8_t)QueuePos]);
  603.         break;
  604.  
  605.       case 32 ... 64:  //Just an ASCII character
  606.         if (cursorPosCol < 20) {
  607.           //          if ((mainScreenType == "lcd2004" ) || (mainScreenType == "lcd1602" )) {
  608.           //            lcd2004.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  609.           //            lcd2004.write((char)RxQueue[(uint8_t)QueuePos]);
  610.           //            cursorPosCol++;
  611.           //          }
  612.           if (mainScreenType == "us2066") {
  613.             oled2004.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  614.             oled2004.write((char)RxQueue[(uint8_t)QueuePos]);
  615.             cursorPosCol++;
  616.           }
  617.         }
  618.         completeCommand(&RxQueue[(uint8_t)QueuePos]);
  619.         break;
  620.  
  621.       case 65 ... 123:  //Just an ASCII character
  622.         if (cursorPosCol < 20) {
  623.           //          if ((mainScreenType == "lcd2004" ) || (mainScreenType == "lcd1602" )) {
  624.           //            lcd2004.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  625.           //            lcd2004.write((char)RxQueue[(uint8_t)QueuePos]);
  626.           //            cursorPosCol++;
  627.           //          }
  628.           if (mainScreenType == "us2066") {
  629.             oled2004.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  630.             oled2004.write((char)RxQueue[(uint8_t)QueuePos]);
  631.             cursorPosCol++;
  632.           }
  633.           if (SaverActive == 1) {
  634.             //              lcdsec.displayOn();
  635.             oledsec.displayOn();
  636.             //              lcd2004.displayOn();
  637.             oled2004.displayOn();
  638.             //              LEDS.setBrightness(BRIGHT_LEDS);
  639.             //              FastLED.show();
  640.             SaverActive = 0;
  641.           }
  642.         }
  643.         completeCommand(&RxQueue[(uint8_t)QueuePos]);
  644.         break;
  645.  
  646.       case 125 ... 255:  //Just an ASCII character
  647.         if (cursorPosCol < 20) {
  648.           //          if ((mainScreenType == "lcd2004" ) || (mainScreenType == "lcd1602" )) {
  649.           //            lcd2004.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  650.           //            lcd2004.write((char)RxQueue[(uint8_t)QueuePos]);
  651.           //            cursorPosCol++;
  652.           //          }
  653.           if (mainScreenType == "us2066") {
  654.             oled2004.cursorMove((cursorPosRow + 1), (cursorPosCol + 1));
  655.             oled2004.write((char)RxQueue[(uint8_t)QueuePos]);
  656.             cursorPosCol++;
  657.           }
  658.         }
  659.         completeCommand(&RxQueue[(uint8_t)QueuePos]);
  660.         break;
  661.  
  662.         //Not implemented. Dont seem to be used anyway.
  663.         //      case XeniumLargeNumber:
  664.         //      case XeniumDrawBarGraph:
  665.         //      case XeniumModuleConfig:
  666.         //      case XeniumCustomCharacter:
  667.  
  668.         //      case XeniumSSaver:
  669.         //        LEDS.setBrightness(2);
  670.         //       FastLED.show();
  671.         //          if ((mainScreenType == "lcd2004" ) || (mainScreenType == "lcd1602" )) {
  672.         //            lcd2004.clear();
  673.         //            lcd2004.home();
  674.         //            lcd2004.displayOff();
  675.         //            SaverActive=1;
  676.         //          }
  677.         if (mainScreenType == "us2066") {
  678.           oled2004.clear();
  679.           oled2004.home();
  680.           oled2004.displayOff();
  681.           SaverActive = 1;
  682.         }
  683.         if (secScreenType == "us2066") {
  684.           oledsec.clear();
  685.           oledsec.home();
  686.           oledsec.displayOff();
  687.           SaverActive = 1;
  688.         }
  689.         //          if ((secScreenType == "lcd2004" )||(secScreenType == "lcd1602" ) ) {
  690.         //            lcdsec.clear();
  691.         //            lcdsec.home();
  692.         //            lcdsec.displayOff();
  693.         //            SaverActive=1;
  694.         //          }
  695.  
  696.         completeCommand(&RxQueue[(uint8_t)QueuePos]);
  697.         break;
  698.  
  699.       default:
  700.         completeCommand(&RxQueue[(uint8_t)QueuePos]);
  701.         break;
  702.     }
  703.     if (RxQueue[(uint8_t)QueuePos] == -1) {
  704.       QueuePos = (uint8_t)(QueuePos + 1);
  705.     }
  706.   }
  707.  
  708.   /* State machine to monitor the SPI Bus idle state */
  709.   /* State machine to monitor the SPI Bus idle state */
  710.   //If SPI bus has been idle pulse the CS line to resync the bus.
  711.   //Xenium SPI bus doesnt use a Chip select line to resync the bus so this is a bit hacky, but improved reliability
  712.   if (SPIState == SPI_ACTIVE) {
  713.     SPIState = SPI_IDLE;
  714.     SPIIdleTimer = millis();
  715.  
  716.   } else if (SPIState == SPI_IDLE && (millis() - SPIIdleTimer) > 100) {
  717.     SPIState = SPI_SYNC;
  718.     digitalWrite(ss_out, HIGH);
  719.     SPIIdleTimer = millis();
  720.  
  721.   } else if (SPIState == SPI_SYNC && (millis() - SPIIdleTimer) > 25) {
  722.     digitalWrite(ss_out, LOW);
  723.     SPIState = SPI_WAIT;
  724.   }
  725.  
  726.   /* Read data from Xbox System Management Bus */
  727.   //Check that i2cBus is free, it has been atleast 2 seconds since last call,
  728.   //and the SPI Bus has been idle for >10 seconds (i.e in a game or app that doesnt support LCD)
  729.   if (i2cBusy() == 250 && (millis() - SMBusTimer) > 2000 && (millis() - SPIIdleTimer) >> spiTimeLimiter) {
  730.     //oledsec.displayShiftLeft();
  731.     char rxBuffer[20];    //Raw data received from SMBus
  732.     char lineBuffer[20];  //Fomatted data for printing to LCD
  733.  
  734.     //Read the current fan speed directly from the SMC and print to LCD
  735.     if (readSMBus(SMC_ADDRESS, SMC_FANSPEED, &rxBuffer[0], 1) == 0) {
  736.       if (rxBuffer[0] >= 0 && rxBuffer[0] <= 50) {  //Sanity check. Number should be 0-50
  737.         if ((mainScreenType == "us2066") && (secScreenType == "NONE")) {
  738.           snprintf(lineBuffer, sizeof lineBuffer, "FAN:%u%% ", rxBuffer[0] * 2);
  739.           oled2004.cursorMove(3, 1);
  740.           oled2004.print(lineBuffer);
  741.         }
  742.         //        if ((mainScreenType == "lcd2004" ) &&(secScreenType == "NONE" )) {
  743.         //          snprintf(lineBuffer, sizeof lineBuffer, "FAN:%u%% ", rxBuffer[0] * 2);
  744.         //          lcd2004.cursorMove(3,1);
  745.         //          lcd2004.print(lineBuffer);
  746.         //        }
  747.         //        if (secScreenType == "lcd1602" ) {
  748.         //          snprintf(lineBuffer, sizeof lineBuffer, "FAN:%u%%", rxBuffer[0] * 2);
  749.         //          lcdsec.cursorMove(1, 1);
  750.         //          lcdsec.print(lineBuffer);
  751.         //        }
  752.         if (secScreenType == "us2066") {
  753.           snprintf(lineBuffer, sizeof lineBuffer, "FAN:%u%% ", rxBuffer[0] * 2);
  754.           oledsec.cursorMove(1, 1);
  755.           oledsec.print(lineBuffer);
  756.           //oledsec.displayShiftLeft();
  757.         }
  758.       }
  759.     }
  760.  
  761.     //Read Focus Chip to determine video resolution (for Version 1.4 console only)
  762.     if (readSMBus(FOCUS_ADDRESS, FOCUS_PID, &rxBuffer[0], 2) == 0) {
  763.       uint16_t PID = ((uint16_t)rxBuffer[1]) << 8 | rxBuffer[0];
  764.       if (PID == 0xFE05) {
  765.         readSMBus(FOCUS_ADDRESS, FOCUS_VIDCNTL, &rxBuffer[0], 2);
  766.         uint16_t VID_CNTL0 = ((uint16_t)rxBuffer[1]) << 8 | rxBuffer[0];
  767.         FOCUS == 1;
  768.         if (secScreenType == "us2066") {
  769.           oledsec.cursorMove(4, 1);
  770.           oledsec.print("GPU:Focus ");
  771.           oledsec.cursorMove(1, 9);
  772.         }
  773.         if (VID_CNTL0 & FOCUS_VIDCNTL_VSYNC5_6 && VID_CNTL0 & FOCUS_VIDCNTL_INT_PROG) {
  774.           //Must be HDTV, interlaced (1080i)
  775.           //          if (((mainScreenType == "lcd2004" ) || (mainScreenType == "lcd1602" ))&& (secScreenType == "NONE" )) {
  776.           //                  lcd2004.print("  1080i   ");
  777.           //                }
  778.           if ((mainScreenType == "us2066") && (secScreenType == "NONE")) {
  779.             oled2004.print("  480P   ");
  780.           }
  781.           //                if ((secScreenType == "lcd2004" ) || (secScreenType == "lcd1602" )) {
  782.           //                    lcdsec.print("  1080i   ");
  783.           //                }
  784.           if (secScreenType == "us2066") {
  785.             oledsec.print("  RES:480P");
  786.           }
  787.         } else if (VID_CNTL0 & FOCUS_VIDCNTL_VSYNC5_6 && !(VID_CNTL0 & FOCUS_VIDCNTL_INT_PROG)) {
  788.           //Must be HDTV, Progressive 720p
  789.           //          if (((mainScreenType == "lcd2004" ) || (mainScreenType == "lcd1602" ))&& (secScreenType == "NONE" )) {
  790.           //                lcd2004.print("  720p    ");
  791.           //              }
  792.           if ((mainScreenType == "us2066") && (secScreenType == "NONE")) {
  793.             oled2004.print("  720p    ");
  794.           }
  795.           //              if ((secScreenType == "lcd2004" ) || (secScreenType == "lcd1602" )) {
  796.           //                  lcdsec.print("  720p    ");
  797.           //              }
  798.           if (secScreenType == "us2066") {
  799.             oledsec.print("  RES:720p ");
  800.           }
  801.         } else if (!(VID_CNTL0 & FOCUS_VIDCNTL_VSYNC5_6) && VID_CNTL0 & FOCUS_VIDCNTL_INT_PROG) {
  802.           //Must be SDTV, interlaced 480i
  803.           //          if (((mainScreenType == "lcd2004" ) || (mainScreenType == "lcd1602" ))&& (secScreenType == "NONE" )){
  804.           //                lcd2004.print("  480i    ");
  805.           //              }
  806.           if ((mainScreenType == "us2066") && (secScreenType == "NONE")) {
  807.             oled2004.print("  480i    ");
  808.           }
  809.           //              if ((secScreenType == "lcd2004" ) || (secScreenType == "lcd1602" )) {
  810.           //                lcdsec.print("  480i    ");
  811.           //              }
  812.           if (secScreenType == "us2066") {
  813.             oledsec.print("  RES:480i ");
  814.           }
  815.         } else if (!(VID_CNTL0 & FOCUS_VIDCNTL_VSYNC5_6) && !(VID_CNTL0 & FOCUS_VIDCNTL_INT_PROG)) {
  816.           //Must be SDTV, Progressive 480p
  817.           //              if (((mainScreenType == "lcd2004") || (mainScreenType == "lcd1602")) && (secScreenType == "NONE")) {
  818.           //                lcd2004.print("  480p    ");
  819.           //              }
  820.           if ((mainScreenType == "us2066") && (secScreenType == "NONE")) {
  821.             oled2004.print("  480p    ");
  822.           }
  823.           //              if ((secScreenType == "lcd2004" ) || (secScreenType == "lcd1602" )) {
  824.           //                  lcdsec.print("  480p    ");
  825.           //              }
  826.           if (secScreenType == "us2066") {
  827.             oledsec.print("  RES:480p ");
  828.           }
  829.         } else {
  830.           //              if (((mainScreenType == "lcd2004" ) || (mainScreenType == "lcd1602" ))&& (secScreenType == "NONE" )) {
  831.           //                lcd2004.print("  0x");
  832.           //                lcd2004.print(VID_CNTL0, HEX); //Not sure what it is. Print the code.
  833.           //              }
  834.           if ((mainScreenType == "us2066") && (secScreenType == "NONE")) {
  835.             oled2004.print("  0x");
  836.             oled2004.print(VID_CNTL0, HEX);  //Not sure what it is. Print the code.
  837.           }
  838.           //              if ((secScreenType == "lcd2004" ) || (secScreenType == "lcd1602" )) {
  839.           //                  lcdsec.print("  0x");
  840.           //                  lcdsec.print(VID_CNTL0, HEX); //Not sure what it is. Print the code.
  841.           //              }
  842.           if (secScreenType == "us2066") {
  843.             oledsec.print("  0x");
  844.             oledsec.print(VID_CNTL0, HEX);  //Not sure what it is. Print the code.
  845.           }
  846.         }
  847.       }
  848.  
  849.       //Read Conexant Chip to determine video resolution (for Version 1.0 to 1.3 console only)
  850.     } else if (readSMBus(CONEX_ADDRESS, CONEX_2E, &rxBuffer[0], 1) == 0) {
  851.       CONEXANT == 1;
  852.       if (secScreenType == "us2066") {
  853.         oledsec.cursorMove(4, 1);
  854.         oledsec.print("GPU:CXT.  ");
  855.         oledsec.cursorMove(1, 9);
  856.       }
  857.       if ((uint8_t)(rxBuffer[0] & 3) == 3) {
  858.         //Must be 1080i
  859.         //        if (((mainScreenType == "lcd2004" ) || (mainScreenType == "lcd1602" ))&& (secScreenType == "NONE" )) {
  860.         //                  lcd2004.print("  1080i   ");
  861.         //                }
  862.         if ((mainScreenType == "us2066") && (secScreenType == "NONE")) {
  863.           oled2004.print("  1080i   ");
  864.         }
  865.         //                if ((secScreenType == "lcd2004" ) || (secScreenType == "lcd1602" )) {
  866.         //                    lcdsec.print("  1080i   ");
  867.         //                }
  868.         if (secScreenType == "us2066") {
  869.           oledsec.print("  RES:1080i");
  870.         }
  871.       } else if ((uint8_t)(rxBuffer[0] & 3) == 2) {
  872.         //        //Must be 720p
  873.         //       if (((mainScreenType == "lcd2004" ) || (mainScreenType == "lcd1602" ))&& (secScreenType == "NONE" )) {
  874.         //                lcd2004.print("  720p    ");
  875.         //              }
  876.         if ((mainScreenType == "us2066") && (secScreenType == "NONE")) {
  877.           oled2004.print("  720p    ");
  878.         }
  879.         //              if ((secScreenType == "lcd2004" ) || (secScreenType == "lcd1602" )) {
  880.         //                  lcdsec.print("  720p    ");
  881.         //              }
  882.         if (secScreenType == "us2066") {
  883.           oledsec.print("  RES:720p ");
  884.         }
  885.       } else if ((uint8_t)(rxBuffer[0] & 3) == 1 && rxBuffer[0] & CONEX_2E_HDTV_EN) {
  886.         //Must be 480p
  887.         //        if (((mainScreenType == "lcd2004" ) || (mainScreenType == "lcd1602" ))&& (secScreenType == "NONE" )) {
  888.         //               lcd2004.print("  480p    ");
  889.         //             }
  890.         if ((mainScreenType == "us2066") && (secScreenType == "NONE")) {
  891.           oled2004.print("  480p    ");
  892.         }
  893.         //              if ((secScreenType == "lcd2004" ) || (secScreenType == "lcd1602" )) {
  894.         //                  lcdsec.print("  480p    ");
  895.         //              }
  896.         if (secScreenType == "us2066") {
  897.           oledsec.print("  RES:480p ");
  898.         }
  899.       } else {
  900.         //        if (((mainScreenType == "lcd2004" ) || (mainScreenType == "lcd1602" ))&& (secScreenType == "NONE" )){
  901.         //                lcd2004.print("  480i    ");
  902.         //              }
  903.         if ((mainScreenType == "us2066") && (secScreenType == "NONE")) {
  904.           oled2004.print("  480i    ");
  905.         }
  906.         //              if ((secScreenType == "lcd2004" ) || (secScreenType == "lcd1602" )) {
  907.         //                lcdsec.print("  480i    ");
  908.         //              }
  909.         if (secScreenType == "us2066") {
  910.           oledsec.print("  RES:480i ");
  911.         }
  912.       }
  913.     }
  914.  
  915.  
  916.  
  917.     //Read the CPU and M/B temps
  918.     //Try ADM1032
  919.     if ((readSMBus(ADM1032_ADDRESS, ADM1032_CPU, &rxBuffer[0], 1) == 0 && readSMBus(ADM1032_ADDRESS, ADM1032_MB, &rxBuffer[1], 1) == 0) ||
  920.         //If fails, its probably a 1.6. Read SMC instead.
  921.         (readSMBus(SMC_ADDRESS, SMC_CPUTEMP, &rxBuffer[0], 1) == 0 && readSMBus(SMC_ADDRESS, SMC_BOARDTEMP, &rxBuffer[1], 1) == 0)) {
  922.       if (rxBuffer[0] < 200 && rxBuffer[1] < 200 && rxBuffer[0] > 0 && rxBuffer[1] > 0) {
  923. #ifdef USE_FAHRENHEIT
  924.  
  925.         if ((mainScreenType == "us2066") && (secScreenType == "NONE")) {
  926.           snprintf(lineBuffer, sizeof lineBuffer, "CPU:%u%cF M/B:%u%cF", (uint8_t)((float)rxBuffer[0] * 1.8 + 32.0),
  927.                    (char)223, (uint8_t)((float)rxBuffer[1] * 1.8 + 32.0), (char)223);
  928.           oled2004.cursorMove(4, 1);
  929.           oled2004.print(lineBuffer);
  930.         }
  931.         //                if ((mainScreenType == "lcd2004" ) && (secScreenType == "NONE" )) {
  932.         //                snprintf(lineBuffer, sizeof lineBuffer, "CPU:%u%cF M/B:%u%cF", (uint8_t)((float)rxBuffer[0] * 1.8 + 32.0),
  933.         //                (char)223,(uint8_t)((float)rxBuffer[1] * 1.8 + 32.0),(char)223);
  934.         //                lcd2004.cursorMove(4, 1);
  935.         //                lcd2004.print(lineBuffer);
  936.         //                }
  937.         //                if ((mainScreenType == "lcd1602" ) && (secScreenType == "NONE" )) {
  938.         //                snprintf(lineBuffer, sizeof lineBuffer, "CPU:%uF MB:%uF", (uint8_t)((float)rxBuffer[0] * 1.8 + 32.0),
  939.         //                (uint8_t)((float)rxBuffer[1] * 1.8 + 32.0));
  940.         //                lcd2004.cursorMove(2, 1);
  941.         //                lcd2004.print(lineBuffer);
  942.         //                }
  943.         //                if ((secScreenType == "lcd2004" )||(secScreenType == "lcd1602" )) {
  944.         //                snprintf(lineBuffer, sizeof lineBuffer, "CPU:%uF MB:%uF", (uint8_t)((float)rxBuffer[0] * 1.8 + 32.0),
  945.         //                (uint8_t)((float)rxBuffer[1] * 1.8 + 32.0));
  946.         //               lcdsec.cursorMove(2, 1);
  947.         //                lcdsec.print(lineBuffer);
  948.         //                }
  949.         if (secScreenType == "us2066") {
  950.           snprintf(lineBuffer, sizeof lineBuffer, "CPU:%u%cF M/B:%u%cF", (uint8_t)((float)rxBuffer[0] * 1.8 + 32.0),
  951.                    (char)223, (uint8_t)((float)rxBuffer[1] * 1.8 + 32.0), (char)223);
  952.           oledsec.cursorMove(2, 1);
  953.           oledsec.print(lineBuffer);
  954.         }
  955.  
  956.  
  957. #else
  958.  
  959.         if ((mainScreenType == "us2066") && (secScreenType == "NONE")) {
  960.           snprintf(lineBuffer, sizeof lineBuffer, "CPU:%u%cC  M/B:%u%cC", rxBuffer[0], (char)223, rxBuffer[1], (char)223);
  961.           oled2004.cursorMove(4, 1);
  962.           oled2004.print(lineBuffer);
  963.         }
  964.         //                if ((mainScreenType == "lcd2004" ) && (secScreenType == "NONE" )) {
  965.         //                snprintf(lineBuffer, sizeof lineBuffer, "CPU:%u%cC M/B:%u%cC", rxBuffer[0], (char)223, rxBuffer[1], (char)223);
  966.         //                lcd2004.cursorMove(4, 1);
  967.         //                lcd2004.print(lineBuffer);
  968.         //                }
  969.         //                if ((mainScreenType == "lcd1602" ) && (secScreenType == "NONE" )) {
  970.         //                snprintf(lineBuffer, sizeof lineBuffer, "CPU:%u%cC M/B:%u%cC", rxBuffer[0], (char)223, rxBuffer[1], (char)223);
  971.         //                lcd2004.cursorMove(2, 1);
  972.         //                lcd2004.print(lineBuffer);
  973.         //                }
  974.         //                if ((secScreenType == "lcd2004" )||(secScreenType == "lcd1602" )) {
  975.         //                snprintf(lineBuffer, sizeof lineBuffer, "CPU:%uC  M/B:%uC", rxBuffer[0],  rxBuffer[1]);
  976.         //                lcdsec.cursorMove(2, 1);
  977.         //                lcdsec.print(lineBuffer);
  978.         //                }
  979.         if (secScreenType == "us2066") {
  980.           snprintf(lineBuffer, sizeof lineBuffer, "CPU:%u%cC  M/B:%u%cC", rxBuffer[0], (char)223, rxBuffer[1], (char)223);
  981.           oledsec.cursorMove(2, 1);
  982.           oledsec.print(lineBuffer);
  983.         }
  984. #endif
  985.       }
  986.  
  987.       //Read the current hw ver from smc
  988.       if ((readSMBus(SMC_ADDRESS, SMC_VER, &rxBuffer[0], 1) == 0) & (bitcount == 0)) {
  989.         bitcount++;
  990.         smcArray[0] = rxBuffer[0];
  991.       }
  992.  
  993.       if ((readSMBus(SMC_ADDRESS, SMC_VER, &rxBuffer[0], 1) == 0) & (bitcount == 1)) {
  994.         bitcount++;
  995.         smcArray[1] = rxBuffer[0];
  996.       }
  997.  
  998.       if ((readSMBus(SMC_ADDRESS, SMC_VER, &rxBuffer[0], 1) == 0) & (bitcount == 2)) {
  999.         bitcount++;
  1000.         smcArray[2] = rxBuffer[0];
  1001.         smcArray[3] = '\0';
  1002.         smcString = smcArray;
  1003.       }
  1004.  
  1005.       if (secScreenType == "us2066" || "lcd2004") {
  1006.         oledsec.cursorMove(3, 11);
  1007.         oledsec.print("ERR:");
  1008.         //  oledsec.print(BOOT_LEDS);
  1009.       }
  1010.  
  1011.  
  1012.  
  1013.       if (secScreenType == "us2066" || "lcd2004") {
  1014.         if (smcString == "P01") {
  1015.           oledsec.cursorMove(3, 1);
  1016.           oledsec.print("H/W:V1.0");
  1017.         }
  1018.       }
  1019.  
  1020.       if (secScreenType == "us2066" || "lcd2004") {
  1021.         if (smcString == "P05") {
  1022.           oledsec.cursorMove(3, 1);
  1023.           oledsec.print("H/W:V1.1");
  1024.         }
  1025.       }
  1026.       if (secScreenType == "us2066" || "lcd2004") {
  1027.         if (smcString == "DBG") {
  1028.           oledsec.cursorMove(3, 1);
  1029.           oledsec.print("H/W:DEBUG");
  1030.         }
  1031.       }
  1032.       if (secScreenType == "us2066" || "lcd2004") {
  1033.         if (smcString == "B11") {
  1034.           oledsec.cursorMove(3, 1);
  1035.           oledsec.print("H/W:DEBUG");
  1036.         }
  1037.       }
  1038.       if (secScreenType == "us2066" || "lcd2004") {  //"P2L" or "1P1" or "11P" = v1.6
  1039.         if ((smcString == "P2L" || "1P1" || "11P") && FOCUS << 1 && CONEXANT << 1) {
  1040.           oledsec.cursorMove(3, 1);
  1041.           oledsec.print("H/W:V1.6");
  1042.           oledsec.cursorMove(4, 1);
  1043.           oledsec.print("GPU:Xcal. ");
  1044.           oledsec.cursorMove(3, 1);
  1045.         }
  1046.       }
  1047.       if (secScreenType == "us2066" || "lcd2004") {  //"P11" or "1P1" or "11P" v1.2/v1.3 or v1.4.
  1048.         if ((smcString == "P11" || "1P1" || "11P") && FOCUS << 1 && CONEXANT >> 0) {
  1049.           oledsec.cursorMove(3, 1);
  1050.           oledsec.print("HW:V1.2/3");
  1051.         }
  1052.       }
  1053.       if (secScreenType == "us2066" || "lcd2004") {  //"P11" or "1P1" or "11P" v1.2/v1.3 or v1.4.
  1054.         if ((smcString == "P11" || "1P1" || "11P") && FOCUS >> 0 && CONEXANT << 1) {
  1055.           oledsec.cursorMove(3, 1);
  1056.           oledsec.print("H/W:V1.4");
  1057.         }
  1058.       }
  1059.  
  1060.       SMBusTimer = millis();
  1061.     }
  1062.   } else if (SPIState != SPI_WAIT) {
  1063.     SMBusTimer = millis();
  1064.   }
  1065. }
  1066.  
  1067. /*
  1068.   Function: Check if the SMBus/I2C bus is busy
  1069.   ----------------------------
  1070.   returns: 0 if busy is free, non zero if busy or still checking
  1071. */
  1072. uint8_t i2cBusy() {
  1073.   if (digitalRead(i2c_sda) == 0 || digitalRead(i2c_scl) == 0) {  //If either the data or clock line is low, the line must be busy
  1074.     i2cCheckCount = I2C_BUSY_CHECKS;
  1075.   } else {
  1076.     i2cCheckCount--;  //Bus isn't busy, decrease check counter so we check multiple times to be sure.
  1077.   }
  1078.   return i2cCheckCount;
  1079. }
  1080.  
  1081. /*
  1082.   Function: Read the Xbox SMBus
  1083.   ----------------------------
  1084.   address: The address of the device on the SMBus
  1085.   command: The command to send to the device. Normally the register to read from
  1086.   rx: A pointer to a receive data buffer
  1087.   len: How many bytes to read
  1088.   returns: 0 on success, -1 on error.
  1089. */
  1090. int8_t readSMBus(uint8_t address, uint8_t command, uint8_t * rx, uint8_t len) {
  1091.   Wire.beginTransmission(address);
  1092.   Wire.write(command);
  1093.   if (Wire.endTransmission(false) == 0) {  //Needs to be false. Send I2c repeated start, dont release bus yet
  1094.     Wire.requestFrom(address, len);
  1095.     for (uint8_t i = 0; i < len; i++) {
  1096.       rx[i] = Wire.read();
  1097.     }
  1098.     return 0;
  1099.   } else {
  1100.     return -1;
  1101.   }
  1102. }
  1103.  
  1104. void completeCommand(int16_t * c) {
  1105.   oledsec.displayShiftLeft();
  1106.   *c = -1;
  1107. }
  1108.  
Add Comment
Please, Sign In to add comment