#include <ESP8266WiFi.h>
#include <ESP8266WiFiMulti.h>
#include <ESP8266WebServer.h>
#include <FS.h>

#include <EEPROM.h>

#include <ESP8266mDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>

#include <TFT_eSPI.h> // Hardware-specific library
#include <SPI.h>
TFT_eSPI tft = TFT_eSPI();       // Invoke custom library


ADC_MODE(ADC_VCC);

#define RF_PIN 5
#define ACTIVITY_LED 2

static inline int32_t asm_ccount(void) {
    int32_t r; asm volatile ("rsr %0, ccount" : "=r"(r)); return r; }

static inline void asm_nop() {
    asm volatile ("nop"); }

// Variables used for temporary storage
static uint8_t data[64];
static uint8_t value[10];

uint32_t uid;
uint32_t vendor;


void prepare_data(uint32_t ID, uint32_t VENDOR){
  value[0] = (VENDOR>>4) & 0XF;
  value[1] = VENDOR & 0XF;
  for (int i=1; i<8; i++){
    value[i+2] = (ID>>(28-i*4)) &0xF;
  }

  for (int i=0; i<9; i++) data[i]=1; //header
  for (int i=0; i<10; i++) {         //data
    for (int j=0; j<4; j++) {
      data[9 + i*5 +j] = value[i] >> (3-j) & 1;
    }
    data[9 + i*5 + 4] = ( data[9 + i*5 + 0]
                        + data[9 + i*5 + 1]
                        + data[9 + i*5 + 2]
                        + data[9 + i*5 + 3]) % 2;
  }
  for (int i=0; i<4; i++) {          //checksum
    int checksum=0;
    for (int j=0; j<10; j++) {
      checksum += data[9 + i + j*5];
    }
    data[i+59] = checksum%2;
  }
  data[63] = 0;                      //footer

  /*
  delay(10);
  Serial.println();
  for (int i=0; i<64; i++) {
    Serial.printf("%d", data[i]);
    if (i>=8 && (i+2)%5==0) Serial.printf("\r\n    ");
  }
  Serial.println();
  delay(10);
  */
}

void sendkey(){
  int i=0, j=0;
    for (i=0; i<15; i++){
      for (j=0; j<64; j++){
        data[j]? (GPE |= (1<<RF_PIN)):(GPE &= ~(1<<RF_PIN));
        delayMicroseconds(255);
        for (int k=0; k<14; k++) asm_nop(); //fine tuning
        data[j]? (GPE &= ~(1<<RF_PIN)):(GPE |= (1<<RF_PIN));
        delayMicroseconds(255);
        for (int k=0; k<13; k++) asm_nop(); //fine tuning

      }
    }
}





void setup() {

  tft.init();
  tft.setRotation(1);
  tft.fillScreen(TFT_BLACK);

  pinMode(RF_PIN, INPUT);
  pinMode(ACTIVITY_LED, OUTPUT);
  digitalWrite(ACTIVITY_LED, LOW);
}

void loop() {


  tft.setTextSize(2);
  tft.setTextColor(TFT_GREEN, TFT_BLACK);
  tft.drawString("123", 0, 0, 2);
delay(10000);
  uid=1964417;
  vendor=0;

  prepare_data(uid, vendor);
  
  digitalWrite (ACTIVITY_LED, LOW);
  delay(10);
  sendkey();
  digitalWrite (ACTIVITY_LED, HIGH);
  
}