void writeInst(lcd screen, XGpio Gpio){
	XGpio_Initialize(&Gpio, XPAR_GPIO_0_DEVICE_ID);
	lcd pinDir;
	u32 gpioOutput;
	u32 gpioPinDir; // 0x0 is output, 0xFFF is input...
	pinDir.rs = 0;
	pinDir.rw = 0;
	pinDir.en = 0;
	pinDir.db = 0xFF;
	gpioPinDir = outBits(pinDir);
	// screen arrives with the bits to be written already set.
	XGpio_SetDataDirection(&Gpio, 1, gpioPinDir);
	// Start of timing
	screen.rs = 1;
	screen.rw = 0;
	screen.en = 0;
	gpioOutput = outBits(screen);
	XGpio_WriteReg(Gpio.BaseAddress, XGPIO_DATA_OFFSET,gpioOutput);
	delay(1000);
	screen.en = 1;
	gpioOutput = outBits(screen);
	XGpio_WriteReg(Gpio.BaseAddress, XGPIO_DATA_OFFSET,gpioOutput);
	delay(3000);
	pinDir.db = 0x00;
	gpioPinDir = outBits(pinDir);
	XGpio_SetDataDirection(&Gpio, 1, gpioPinDir);
	XGpio_WriteReg(Gpio.BaseAddress, XGPIO_DATA_OFFSET,gpioOutput);
	delay(3000);
	screen.en = 0;
	gpioOutput = outBits(screen);
	XGpio_WriteReg(Gpio.BaseAddress, XGPIO_DATA_OFFSET,gpioOutput);
	pinDir.db = 0xFF;
	gpioPinDir = outBits(pinDir);
	XGpio_SetDataDirection(&Gpio, 1, gpioPinDir);
	screen.rs = 1;
	screen.rw = 1;
	gpioOutput = outBits(screen);
	XGpio_WriteReg(Gpio.BaseAddress, XGPIO_DATA_OFFSET,gpioOutput);
}
u32 read( XGpio Gpio ){
	XGpio_Initialize(&Gpio, XPAR_GPIO_0_DEVICE_ID);
	lcd commands;
	lcd pinDir;
	u32 gpioPinDir; // 0x0 is output, 0xFFF is input...
	u32 gpioOutput;
	commands.rs = 0;
	commands.rw = 0;
	commands.en = 0;
	commands.db = 0x00;

	pinDir.rs = 0;
	pinDir.rw = 0;
	pinDir.en = 0;
	pinDir.db = 0xFF;
	gpioPinDir = outBits(pinDir);
	XGpio_SetDataDirection(&Gpio, 1, gpioPinDir);
	gpioOutput = outBits(commands);
	XGpio_WriteReg(Gpio.BaseAddress, XGPIO_DATA_OFFSET,gpioOutput);
	// commands.rs = 1;
	commands.rw = 1;
	gpioOutput = outBits(commands);
	XGpio_WriteReg(Gpio.BaseAddress, XGPIO_DATA_OFFSET,gpioOutput);
	delay(3000);
	commands.en = 1;
	gpioOutput = outBits(commands);
	XGpio_WriteReg(Gpio.BaseAddress, XGPIO_DATA_OFFSET,gpioOutput);
	delay(3000);
	// READ
	u32 readVal = 0;
	readVal = XGpio_ReadReg(Gpio.BaseAddress, XGPIO_DATA_OFFSET);
	delay(1000);
	commands.en = 0;
	gpioOutput = outBits(commands);
	XGpio_WriteReg(Gpio.BaseAddress, XGPIO_DATA_OFFSET,gpioOutput);
	delay(1000);
	commands.rs = 0;
	commands.rw = 0;
	gpioOutput = outBits(commands);
	XGpio_WriteReg(Gpio.BaseAddress, XGPIO_DATA_OFFSET,gpioOutput);
	return readVal;
}
    size_t DictionaryEncoding::Dictionary::compress(void* dst, const ConstChunk& chunk, size_t chunkSize)
    {
        uint8_t *readPtr = (uint8_t *)chunk.getData();
        TypeId type = chunk.getAttributeDesc().getType();        
        size_t elementSize = TypeLibrary::getType(type).byteSize();
        size_t nElems;

        if(elementSize == 0 || elementSize > 8 || chunk.isRLE() || !chunk.getArrayDesc().isImmutable() || chunk.isSparse() || chunk.getAttributeDesc().isNullable())
        {
            nElems = chunkSize;
            elementSize = 1;
        }
        else
        {
            nElems = chunkSize / elementSize;
        }

        size_t i;
        uint64_t value = 0;
        uint8_t code = 0;
        ByteOutputItr out((uint8_t *) dst, chunkSize - 1);
        BitOutputItr outBits(&out);




        uint32_t uniques = (uint32_t) createDictionary(readPtr, elementSize, nElems, out);
  
        size_t codeLength;
        uniques <= 2 ? codeLength = 1 : codeLength = ceil(log2(uniques-1)) + 1;  // 0-indexed, so values span from 0...uniques-1, log is 0-based, so bring it back to 1...n bits
    
     
  
        // project size and terminate if it will be too large
        size_t codesSize = (nElems * codeLength + 7) >> 3;
        size_t totalCompressed = 1 + uniques * elementSize + codesSize;

        if(totalCompressed*2 >= chunkSize) // if we can't get at least 2:1 it is not worth doing
        {
            return chunkSize;
        }



        if(!nElems || !uniques) 
        {
            return chunkSize;
        }

        for(i = 0; i < nElems; ++i)
        {
            memcpy((uint8_t *) &value, readPtr, elementSize);
            code = _encodeDictionary[value];
            outBits.put(code, codeLength);
            readPtr += elementSize;
        }
  
        outBits.flush();
        size_t compressedSize = out.close();

  
        return compressedSize;

    }
int main() 
{
   static XIntc intc;
   static XTmrCtr axi_timer_0_Timer;
   XGpio Gpio; /* The Instance of the GPIO Driver  */

   Xil_ICacheEnable();
   Xil_DCacheEnable();
   print("---Entering main---\n\r");
   xil_printf( "Memory size occupied by status2 : %d\n", sizeof(lcd) );

   lcd myLCD;
   myLCD.rs = 0;
   myLCD.rw = 0;
   myLCD.en = 0;
   myLCD.db = 0x30;

   u32 gpioOutput = outBits(myLCD);
   xil_printf( "gpioOut 0x%04x\n", gpioOutput );
   write(myLCD, Gpio);
   u32 readOut = read(Gpio);
   xil_printf( "readOut 0x%04x\n", readOut );
   write(myLCD, Gpio);
   delay(1000000);
   write(myLCD, Gpio);
   delay(1000000);
   write(myLCD, Gpio);
   delay(1000000);
   myLCD.rs = 0;
   myLCD.rw = 0;
   myLCD.en = 0;
   myLCD.db = 0x3C;
   gpioOutput = outBits(myLCD);
   write(myLCD, Gpio);
   delay(1000000);
   readOut = read(Gpio);
   xil_printf( "readOut 0x%04x\n", readOut );
   myLCD.db = 0x08;
   gpioOutput = outBits(myLCD);
   write(myLCD, Gpio);
   delay(1000000);
   readOut = read(Gpio);
   xil_printf( "readOut 0x%04x\n", readOut );

   myLCD.db = 0x01;
   gpioOutput = outBits(myLCD);
   write(myLCD, Gpio);
   delay(1000000);
   readOut = read(Gpio);
   xil_printf( "readOut 0x%04x\n", readOut );

   myLCD.db = 0x06;
   gpioOutput = outBits(myLCD);
   write(myLCD, Gpio);
   readOut = read(Gpio);
   xil_printf( "readOut 0x%04x\n", readOut );

   myLCD.db = 0x0F;
   gpioOutput = outBits(myLCD);
   write(myLCD, Gpio);
   readOut = read(Gpio);
   xil_printf( "readOut 0x%04x\n", readOut );

   // Blinking Cursor

   myLCD.db = 0xCF;
   gpioOutput = outBits(myLCD);
   write(myLCD, Gpio);
   readOut = read(Gpio);
   xil_printf( "readOut 0x%04x\n", readOut );

   myLCD.db = 0x30;
   gpioOutput = outBits(myLCD);
   writeInst(myLCD, Gpio);
   readOut = read(Gpio);
   xil_printf( "readOut 0x%04x\n", readOut );

   myLCD.db = 0x8B;
   gpioOutput = outBits(myLCD);
   write(myLCD, Gpio);
   readOut = read(Gpio);
   xil_printf( "readOut 0x%04x\n", readOut );

   myLCD.db = 0x48;
   gpioOutput = outBits(myLCD);
   writeInst(myLCD, Gpio);
   readOut = read(Gpio);
   xil_printf( "readOut 0x%04x\n", readOut );

   myLCD.db = 0x8C;
  gpioOutput = outBits(myLCD);
  write(myLCD, Gpio);
  readOut = read(Gpio);
  xil_printf( "readOut 0x%04x\n", readOut );

  myLCD.db = 0x45;
  gpioOutput = outBits(myLCD);
  writeInst(myLCD, Gpio);
  readOut = read(Gpio);
  xil_printf( "readOut 0x%04x\n", readOut );

  myLCD.db = 0x8D;
	gpioOutput = outBits(myLCD);
	write(myLCD, Gpio);
	readOut = read(Gpio);
	xil_printf( "readOut 0x%04x\n", readOut );

	myLCD.db = 0x4C;
	gpioOutput = outBits(myLCD);
	writeInst(myLCD, Gpio);
	readOut = read(Gpio);
	xil_printf( "readOut 0x%04x\n", readOut );

	myLCD.db = 0x8E;
	gpioOutput = outBits(myLCD);
	write(myLCD, Gpio);
	readOut = read(Gpio);
	xil_printf( "readOut 0x%04x\n", readOut );

	myLCD.db = 0x4C;
	gpioOutput = outBits(myLCD);
	writeInst(myLCD, Gpio);
	readOut = read(Gpio);
	xil_printf( "readOut 0x%04x\n", readOut );

	myLCD.db = 0x8F;
	gpioOutput = outBits(myLCD);
	write(myLCD, Gpio);
	readOut = read(Gpio);
	xil_printf( "readOut 0x%04x\n", readOut );

	myLCD.db = 0x4F;
	gpioOutput = outBits(myLCD);
	writeInst(myLCD, Gpio);
	readOut = read(Gpio);
	xil_printf( "readOut 0x%04x\n", readOut );

	myLCD.db = 0x80;
	gpioOutput = outBits(myLCD);
	write(myLCD, Gpio);
	readOut = read(Gpio);
	xil_printf( "readOut 0x%04x\n", readOut );

	// Blinky
	myLCD.db = 0xCF;
	gpioOutput = outBits(myLCD);
	write(myLCD, Gpio);
	readOut = read(Gpio);
	xil_printf( "readOut 0x%04x\n", readOut );

   print("---Exiting main---\n\r");
   Xil_DCacheDisable();
   Xil_ICacheDisable();
   return 0;
}