/*
   ATtiny TFT DHT11 Thermometer
   
   Created: 16/02/2025
    Author: moty22.co.uk
*/

#define cs 0  //pin5
#define dc 3  //pin2
#define SCL 2 //pin7
#define SDA 1 //pin6
#define in 4 //pin3

// Color definitions
#define  BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0  
#define WHITE   0xFFFF
#define PINK    0xFC58
#define ORANGE  0xFC00

#define yh  140  //humidity
#define yt  2   //temp
#define ys  26   //scale
#define sc  WHITE   //scale color
//#define ym  109   //moty
#define bgr  BLACK

const unsigned char  font[] = {
  0x3E, 0x41, 0x41, 0x41, 0x3E, //0    
  0x00, 0x42, 0x7F, 0x40, 0x00,// 1
  0x42, 0x61, 0x51, 0x49, 0x46,// 2
  0x21, 0x41, 0x45, 0x4B, 0x31,// 3
  0x18, 0x14, 0x12, 0x7F, 0x10,// 4
  0x27, 0x45, 0x45, 0x45, 0x39,// 5
  0x3C, 0x4A, 0x49, 0x49, 0x30,// 6
  0x01, 0x71, 0x09, 0x05, 0x03,// 7
  0x36, 0x49, 0x49, 0x49, 0x36,// 8
  0x06, 0x49, 0x49, 0x29, 0x1E,// 9
  0x00, 0x06, 0x09, 0x09, 0x06, // degree symbol
  0x3E, 0x41, 0x41, 0x41, 0x22,// C
  0x00, 0x00, 0x00, 0x00, 0x00,// (space)
  0x00, 0x60, 0x60, 0x00, 0x00,// .
  0x7F, 0x09, 0x09, 0x01, 0x01,// F  
  0x23, 0x13, 0x08, 0x64, 0x62,// %    
};
unsigned char of1 = 0; //
unsigned char b[5]; //5 bytes from

void setup() {
  //SPI settings
   USICR &= ~(_BV(USISIE) | _BV(USIOIE) | _BV(USIWM1));
   USICR |= _BV(USIWM0) | _BV(USICS1) | _BV(USICLK);  //3 wires,

  pinMode(in,INPUT);
  pinMode(cs,OUTPUT);
  pinMode(dc,OUTPUT);
  pinMode(SCL,OUTPUT);
  pinMode(SDA,OUTPUT);
  digitalWrite(cs,HIGH);
  
  TFTinit();
  rectan(0,0,127,159,bgr);  //bacbground
  ball(51,ys+100,RED);
  draw(24,yt,13,CYAN,2);  //.C
  draw(0,ys+42,10,CYAN,2);  //deg
  draw(12,ys+42,11,CYAN,2);  //C
  draw(104,yt,13,MAGENTA,2);  //.F
  draw(103,ys+42,10,MAGENTA,2);  //deg
  draw(115,ys+42,14,MAGENTA,2);  //F
  draw(38,yh,15,GREEN,2);  //%

  //scale C
  rectan(50,ys,50,ys+100,sc);
  for(char i=0;i<6;++i){
    rectan(45,ys+i*20,50,ys+i*20,sc);
    draw(30,ys+i*20-2,5-i,sc,1); draw(36,ys+i*20-2,0,sc,1);
  }
  rectan(30,ys+98,35,ys+106,bgr);
  
  //scale F
  rectan(76,ys,76,ys+100,sc);
  for(char i=0;i<6;++i){
    rectan(76,ys+i*20,81,ys+i*20,sc);
  }
  draw(83,ys-2,1,sc,1); draw(89,ys-2,2,sc,1); draw(95,ys-2,2,sc,1);  //122
  draw(83,ys+18,1,sc,1); draw(89,ys+18,0,sc,1); draw(95,ys+18,4,sc,1); //104
  draw(83,ys+38,8,sc,1); draw(89,ys+38,6,sc,1);
  draw(83,ys+58,6,sc,1); draw(89,ys+58,8,sc,1);
  draw(83,ys+78,5,sc,1); draw(89,ys+78,0,sc,1);
  draw(83,ys+98,3,sc,1); draw(89,ys+98,2,sc,1); //32
}

void loop()
{
  unsigned char r, bn, v, d;
  unsigned int df;

  //reading dht11
  pinMode(in, OUTPUT);
  digitalWrite(in, HIGH);
  delay(5000);
  digitalWrite(in, LOW);
  delay(25);
  digitalWrite(in, HIGH);
  delayMicroseconds(20);
  pinMode(in, INPUT);
  while(digitalRead(in)){}
  //delayMicroseconds(40);
  while(!digitalRead(in)){}
  while(digitalRead(in)){}
  for(r=0;r<5;++r){
    b[r]=0;
    for(bn=0;bn<8;++bn){
      while(!digitalRead(in)){}
      delayMicroseconds(50);
      v=digitalRead(in);
      b[r] += v<<(7-bn);
      if(digitalRead(in)==HIGH){while(digitalRead(in)){}}
    }
  }
    //deg C
    d = (b[2] / 10) % 10; //temperature
    rectan(2,yt,12,yt+16,bgr);
    draw(2,yt,d,CYAN,2);
    d = b[2] % 10;
    rectan(14,yt,24,yt+16,bgr);
    draw(14,yt,d,CYAN,2);
    rectan(34,yt,44,yt+16,bgr);
    draw(34,yt,b[3],CYAN,2);

    rectan(58,ys,68,ys+100,bgr);
    rectan(58,ys+100-b[2]*2,68,ys+100,RED);
    
    //deg F
    df=((unsigned int)b[2]*10 + (unsigned int)b[3])*9;
    df=df/5+320;
    d=(df/1000)%10;
    if(d>0){draw(70,yt,d,MAGENTA,2);}else{rectan(70,yt,80,yt+16,bgr);}
    d=(df/100)%10;
    rectan(82,yt,92,yt+16,bgr);
    draw(82,yt,d,MAGENTA,2);
    d=(df/10)%10;
    rectan(94,yt,104,yt+16,bgr);
    draw(94,yt,d,MAGENTA,2);
    d=df%10;
    rectan(114,yt,124,yt+16,bgr);
    draw(114,yt,d,MAGENTA,2);
    
    //humid
    d = (b[0] / 10) % 10; //humidity
    rectan(14,yh,24,yh+16,bgr);
    draw(14,yh,d,ORANGE,2);
    d = b[0] % 10;
    rectan(26,yh,36,yh+16,bgr);
    draw(26,yh,d,ORANGE,2);
    
}

void SPI85(unsigned char spiData)    // send character over SPI
{
    USIDR = spiData;
    USISR = _BV(USIOIF);                // clear counter and counter overflow interrupt flag
    {
        while ( !(USISR & _BV(USIOIF)) ) USICR |= _BV(USITC);
    }
    //return USIDR;
}

void command(unsigned char cmd)
{
  digitalWrite(dc,LOW); // Command Mode
  digitalWrite(cs,LOW); // Select the LCD (active low)
  SPI85(cmd); // set up data on bus
  digitalWrite(cs,HIGH); // Deselect LCD (active low)
}

void send_data(unsigned char data)
{
  digitalWrite(dc,HIGH);    // data mode
  digitalWrite(cs,LOW);       // chip selected
  SPI85(data);  // set up data on bus
  digitalWrite(cs,HIGH);       // deselect chip
}


void ball(unsigned char x, unsigned char y, unsigned int hue) //
{
    unsigned char i;
    
    rectan(x+9,y,x+14,y+1,hue); //top
    for(i=0;i<5;i++){
        rectan(x+6-i,y+i+1,x+i+17,y+i+2,hue);
    }
    rectan(x+1,y+6,x+22,y+9,hue); //
    rectan(x,y+9,x+23,y+15,hue); //
    
    rectan(x+1,y+15,x+22,y+17,hue); //
    for(i=0;i<5;i++){
        rectan(x+2+i,y+i+17,x+21-i,y+i+18,hue);
    }
    rectan(x+9,y+23,x+14,y+23,hue); //bottom
    

}

void draw(unsigned char x, unsigned char y, unsigned char c, unsigned int color, unsigned char size) //character
{
  unsigned char i, j, line;
  for (i=0; i<6; i++ ) {
     if (i == 5) 
      line = 0x0;
    else 
      line = font[(c*5)+i];
    for (j = 0; j<8; j++) {
        if (line & 0x1) {
            rectan(x+(i*size), y+(j*size), x+(i*size)+size, y+(j*size)+size, color);
        }else{
            rectan(x+(i*size), y+(j*size), x+(i*size)+size, y+(j*size)+size, bgr);
        }
        line >>= 1;
    }
  }
}

void TFTinit(void)
{
  unsigned char i;
//  rst=1;      //hardware reset
//  __delay_ms(200);
//  rst=0;
//  __delay_ms(10);
//  rst=1;
//  __delay_ms(10);
  
  command(0x01); // sw reset
  delay(200);

    command(0x11); // Sleep out
  delay(200);

  command(0x3A); //color mode
  send_data(0x05);  //16 bits

  command(0x36); //Memory access ctrl (directions)
  send_data(0B00010000);  //0x60  //1.8" hor-0B01100000=0x60, 1.8" ver-0B11000000, 1.44" ver-0B00001000, 0.96 ver-
  //command(0x21); //inversion on

  command(0x2D);  //color look up table
  send_data(0); for(i=1;i<32;i++){send_data(i*2);}
  for(i=0;i<64;i++){send_data(i);}  
  send_data(0); for(i=1;i<32;i++){send_data(i*2);}    
    
  command(0x13); //Normal display on
  command(0x29); //Main screen turn on
}   

void area(unsigned char x0,unsigned char y0, unsigned char x1,unsigned char y1)
{
  command(0x2A); // Column addr set
  send_data(0x00);
  send_data(x0);     // XSTART 
  send_data(0x00);
  send_data(x1);     // XEND

  command(0x2B); // Row addr set
  send_data(0x00);
  send_data(y0);     // YSTART
  send_data(0x00);
  send_data(y1);     // YEND

  command(0x2C); // write to RAM
}  
  
void rectan(unsigned char x0,unsigned char y0, unsigned char x1,unsigned char y1, unsigned int color) 
{
 unsigned int i;
  area(x0,y0,x1,y1);
  for(i=(y1 - y0 + 1) * (x1 - x0 + 1); i > 0; i--) {      

     digitalWrite(dc,HIGH);        // data mode
    digitalWrite(cs,LOW);
    SPI85(color >> 8);
    SPI85(color);
    digitalWrite(cs,HIGH);
  }
}

void pixel(unsigned char x,unsigned char y, unsigned int color)
{
    area(x,y,x+1,y+1);
    send_data(color >> 8);
    send_data(color);
}
