//8CH RC Transmitter with OLED display interface for Menu Options i.e Reverse, Borders, Elevon, Servo Trim, Battery & Factory Reset.
//The Transmitter now has got STM32F103 aka BluePil and is an upgrade version of the previous with Nano and NRF24LO1.
//by Neel. 10.01.2024

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
//#include <EEPROM.h>        //No!! EEPROM in STM32F103
#include "icon_arrays.h"  //header file contains OLED icon/images arrays

#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels

#define OLED_RESET     -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3c ///< See datasheet for Address;
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
//
//See icon_arrays.h for icon & images arrays
//
// pins for buttons >>  dn, up, back/cancel, select/Ok >> Wokwi Btn Color YLW,GRN,BLU,RED
#define dnKey 9
#define upKey 10
#define bacKey 11
#define selKey 12
#define potPin A0       //for debugging & testing on wokwi.com only.
int potVal; int value; 
//const byte dnKey = 9, upKey = 10, bacKey = 11, selKey = 12; // pins for buttons up, dn, back, select
byte page1 = 0;   //Main Menu page switch case  // Menu Options i.e Reverse, Borders, Elevon, Servo Trim, Battery & Factory Reset Transmitter
byte page2 = 0;   //Reverse menu switch case  // Channel Reverse function To Opposite movement of servo
byte page3 = 0;   //Boarders menu switch case  // set the PWM maximun & minimum // Servo max-min movement
byte page4 = 0;   //Elevon menu switch case // Elevon menu is for Mixing Roll & Pitch for deltaWings
byte page5 = 0;    byte rollPg = 1; byte pitchPg = 1; byte thtPg = 1; byte yawPg = 1; //Borders Max-Min Selection
//Current menus status. // 0 = not selected & 1 = selected.
bool menuStatus = 0; bool reverseStatus = 0; bool borderStatus = 0; bool elevonStatus = 0; bool offsetStatus = 0;
bool trimStaus = 0; bool batteryStatus = 0; bool resetStatus = 0; //Current menus/sub menu status for entering concern menu while loop
bool rollStatus = 0;  bool pitchStatus = 0;  bool thtStatus = 0;  bool yawStatus = 0;
// Channels Border Set.
int rollMax = 255; int rollMin = 0; int pitchMax = 255; int pitchMin = 0; // Max & Min Borders for servo movement called in Border_Map Function
int thtMax = 255; int thtMin = 0; int yawMax = 255; int yawMin = 0;
// Channels Reverse Status.
bool revCh1 = false; bool revCh2 = false; bool revCh3 = false; bool revCh4 = false;   // Channels Reverse Status.
bool revCh5 = false; bool revCh6 = false; bool revCh7 = false; bool revCh8 = false;
// Elevon Status
bool elevonMix = false;       // Elevon mode status. //True = Activated,
byte offsetMix = 50;         // Roll+Pitch mix offset in %, default 50%,
bool resetData = false;      // true when user Reset the Tx from Reset menu and all Setting EEPROM data cleared


void setup() {
  pinMode(dnKey, INPUT_PULLUP);
  pinMode(upKey, INPUT_PULLUP);
  pinMode(bacKey, INPUT_PULLUP);
  pinMode(selKey, INPUT_PULLUP);
  // SSD1306_SWITCHCAPVCC = generate display voltage from 3.3V internally
  if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
    //Serial.println(F("SSD1306 allocation failed"));
    for (;;); // Don't proceed, loop forever
  }

  display.clearDisplay();
}

void loop() {
  //
  //Put Transmitter Main Code Here
  //
  //readRevEeprom();                                                // Check h_eeprom_data.ino for functions
  mainPage();  // main ch value page default screen i.e home page  //Check b_mainPage.ino for functions

  checkMenuStatus();

  while (menuStatus == 1 ) {          // menu page after press select/ok button
    menuCheck();                       // Check c_MenuPage.ino for functions
    updateMenu();
    checkMenuStatus();
    checkReverseStatus();
    checkBorderStatus();
    checkElevonStatus();
    checkBatteryStatus();
    //checkResetStatus();             //No!! EEPROM on STM32F103

    while (reverseStatus == 1) {            //sub menu Reverse Page //menuPage/reversePage
      reverseCheck();                        //Check d_ChXReverse.ino for functions
      updateReverse();
      checkReverseStatus();
    }

    while (borderStatus == 1) {     //sub menu Borders Page //menuPage/BordersPage
      borderCheck();                // Check g_borderMenu.ino for functions
      updateBorder();
      checkBorderStatus();
      checkRollStatus();
      checkPitchStatus();         
      checkThtStatus();               
      checkYawStatus();

      while (rollStatus == 1) {          //menuPage/borderPage/rollPage    roll max min set
        rollCheck();
        updateRoll();
        checkRollStatus();
      }
      while(pitchStatus==1){              //menuPage/borderPage/pitchPage    pitch max min set
        pitchCheck();
        updatePitch();
        checkPitchStatus();
        }
      while(thtStatus==1){              //menuPage/borderPage/throttlePage   thtrl max min set
        thtCheck();
        updateTht();
        checkThtStatus();
        }
      while(yawStatus==1){              //menuPage/borderPage/yawPage        yaw max min set
        yawCheck();
        updateYaw();
        checkYawStatus();
        } 

    }// BorderMenu While End


    while (elevonStatus == 1) {             //sub menu Elevon Page //menuPage/elevonPage
      elevonCheck();                         // Check f_elevonMenu.ino for functions
      updateElevon();
      checkElevonStatus();
      checkOffsetStatus();
      while (offsetStatus == 1) {          //menuPage/elevonPage/offsetPage
        offsetPage();
        checkOffsetStatus();
      }
    }

    while (batteryStatus == 1) {     //sub menu Battery Page //menuPage/BatteryPage
      batteryPage();
      checkBatteryStatus();           // Check e_batteryAndReset.ino for functions
    }
    /*while (resetStatus == 1 && resetData == false) {     //sub menu Battery Page //menuPage/BatteryPage
      resetPage();
      resetDone();
      checkResetStatus();
    }*/

  }//Menu Mode while loop end

}//Main void loop() end

/*
  void trimPage(){                // Temporary Under Construction.
  display.clearDisplay();
  display.setTextColor(1);
  display.setTextSize(1);
  display.setCursor(10, 8);
  display.setTextWrap(false);
  display.print("THIS PAGE IS UNDER");
  display.setTextColor(1);
  display.setTextSize(1);
  display.setCursor(28, 24);
  display.setTextWrap(false);
  display.print("CONSTRUCTION");
  display.setTextColor(1);
  display.setTextSize(3);
  display.setCursor(36, 38);
  display.setTextWrap(false);
  display.print("(!)");
  display.display();
  }                                //  Due to Shortage of Memory(ROM) on Atmega328 boards could not be completed
*/