diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2a8ac54
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+bin/
+.vscode/
diff --git a/makefile b/makefile
new file mode 100644
index 0000000..ea0f724
--- /dev/null
+++ b/makefile
@@ -0,0 +1,29 @@
+MCU=atmega32
+F_CPU=8000000
+PROG=dragon_jtag
+DEBUGGER = dragon
+PORT=/dev/ttyUSB0
+
+CC=avr-g++
+OBJCOPY=avr-objcopy
+CFLAGS=-Wall -g -mmcu=${MCU} -DF_CPU=${F_CPU} -I.
+TARGET=main
+SRCS=src/*.cpp 
+
+default: build flash
+
+build:
+	${CC} ${CFLAGS} -o bin/${TARGET}.bin  ${SRCS}
+	${CC} ${CFLAGS} -o bin/${TARGET}.elf  ${SRCS}
+	${OBJCOPY} -j .text -j .data -O ihex bin/${TARGET}.bin bin/${TARGET}.hex
+
+flash:
+	avrdude -p ${MCU} -c ${PROG} -U flash:w:bin/main.hex
+
+clean:
+	rm -f bin/*
+
+debug: flash
+	sleep 1
+	avarice --program --file bin/main.elf --part ${MCU} --${DEBUGGER} :4242 &
+	avr-gdb -ex "target remote :4242" bin/main.elf
diff --git a/src/TM1637Display.cpp b/src/TM1637Display.cpp
new file mode 100644
index 0000000..5dddb16
--- /dev/null
+++ b/src/TM1637Display.cpp
@@ -0,0 +1,296 @@
+
+//  Author: avishorp@gmail.com
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License, or (at your option) any later version.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+extern "C" {
+  #include <stdlib.h>
+  #include <string.h>
+  #include <inttypes.h>
+}
+
+#include "TM1637Display.h"
+#include <avr/io.h>
+#include <util/delay.h>
+
+#define TM1637_I2C_COMM1    0x40
+#define TM1637_I2C_COMM2    0xC0
+#define TM1637_I2C_COMM3    0x80
+
+//
+//      A
+//     ---
+//  F |   | B
+//     -G-
+//  E |   | C
+//     ---
+//      D
+const uint8_t digitToSegment[] = {
+ // XGFEDCBA
+  0b00111111,    // 0
+  0b00000110,    // 1
+  0b01011011,    // 2
+  0b01001111,    // 3
+  0b01100110,    // 4
+  0b01101101,    // 5
+  0b01111101,    // 6
+  0b00000111,    // 7
+  0b01111111,    // 8
+  0b01101111,    // 9
+  0b01110111,    // A
+  0b01111100,    // b
+  0b00111001,    // C
+  0b01011110,    // d
+  0b01111001,    // E
+  0b01110001     // F
+  };
+
+static const uint8_t minusSegments = 0b01000000;
+
+
+
+
+TM1637Display::TM1637Display(uint8_t pinClk, uint8_t pinDIO, volatile uint8_t *port,  int bitDelay)
+{
+	// Copy the pin numbers
+	m_pinClk = pinClk;
+	m_pinDIO = pinDIO;
+	m_bitDelay = bitDelay;
+  m_port = port;
+  m_ddr = port-1;
+  m_pin = port-2;
+
+	// Set the pin direction and default value.
+	// Both pins are set as inputs, allowing the pull-up resistors to pull them up
+    //CLK_Input();
+    //pinMode(m_pinDIO,INPUT);
+    DIO_Input();
+    CLK_Input();
+	//digitalWrite(m_pinClk, LOW);
+	//digitalWrite(m_pinDIO, LOW);
+  DIO_Low();
+  CLK_Low();
+}
+
+void TM1637Display::setBrightness(uint8_t brightness, bool on)
+{
+	m_brightness = (brightness & 0x7) | (on? 0x08 : 0x00);
+}
+
+void TM1637Display::setSegments(const uint8_t segments[], uint8_t length, uint8_t pos)
+{
+    // Write COMM1
+	start();
+	writeByte(TM1637_I2C_COMM1);
+	stop();
+
+	// Write COMM2 + first digit address
+	start();
+	writeByte(TM1637_I2C_COMM2 + (pos & 0x03));
+
+	// Write the data bytes
+	for (uint8_t k=0; k < length; k++)
+	  writeByte(segments[k]);
+
+	stop();
+
+	// Write COMM3 + brightness
+	start();
+	writeByte(TM1637_I2C_COMM3 + (m_brightness & 0x0f));
+	stop();
+}
+
+void TM1637Display::clear()
+{
+    uint8_t data[] = { 0, 0, 0, 0 };
+	setSegments(data);
+}
+
+void TM1637Display::showNumberDec(int num, bool leading_zero, uint8_t length, uint8_t pos)
+{
+  showNumberDecEx(num, 0, leading_zero, length, pos);
+}
+
+void TM1637Display::showNumberDecEx(int num, uint8_t dots, bool leading_zero,
+                                    uint8_t length, uint8_t pos)
+{
+  showNumberBaseEx(num < 0? -10 : 10, num < 0? -num : num, dots, leading_zero, length, pos);
+}
+
+void TM1637Display::showNumberHexEx(uint16_t num, uint8_t dots, bool leading_zero,
+                                    uint8_t length, uint8_t pos)
+{
+  showNumberBaseEx(16, num, dots, leading_zero, length, pos);
+}
+
+void TM1637Display::showNumberBaseEx(int8_t base, uint16_t num, uint8_t dots, bool leading_zero,
+                                    uint8_t length, uint8_t pos)
+{
+    bool negative = false;
+	if (base < 0) {
+	    base = -base;
+		negative = true;
+	}
+
+
+    uint8_t digits[4];
+
+	if (num == 0 && !leading_zero) {
+		// Singular case - take care separately
+		for(uint8_t i = 0; i < (length-1); i++)
+			digits[i] = 0;
+		digits[length-1] = encodeDigit(0);
+	}
+	else {
+		//uint8_t i = length-1;
+		//if (negative) {
+		//	// Negative number, show the minus sign
+		//    digits[i] = minusSegments;
+		//	i--;
+		//}
+		
+		for(int i = length-1; i >= 0; --i)
+		{
+		    uint8_t digit = num % base;
+			
+			if (digit == 0 && num == 0 && leading_zero == false)
+			    // Leading zero is blank
+				digits[i] = 0;
+			else
+			    digits[i] = encodeDigit(digit);
+				
+			if (digit == 0 && num == 0 && negative) {
+			    digits[i] = minusSegments;
+				negative = false;
+			}
+
+			num /= base;
+		}
+
+		if(dots != 0)
+		{
+			showDots(dots, digits);
+		}
+    }
+    setSegments(digits, length, pos);
+}
+
+void TM1637Display::bitDelay()
+{
+  _delay_us(m_bitDelay);
+}
+
+void TM1637Display::start()
+{
+  DIO_Output();
+  bitDelay();
+}
+
+void TM1637Display::stop()
+{
+	DIO_Output();
+	bitDelay();
+	CLK_Input();
+	bitDelay();
+	DIO_Input();
+	bitDelay();
+}
+
+bool TM1637Display::writeByte(uint8_t b)
+{
+  uint8_t data = b;
+
+  // 8 Data Bits
+  for(uint8_t i = 0; i < 8; i++) {
+    // CLK low
+    CLK_Output();
+    bitDelay();
+
+	// Set data bit
+    if (data & 0x01)
+      DIO_Input();
+    else
+      DIO_Output();
+
+    bitDelay();
+
+	// CLK high
+    CLK_Input();
+    bitDelay();
+    data = data >> 1;
+  }
+
+  // Wait for acknowledge
+  // CLK to zero
+  CLK_Output();
+  DIO_Input();
+  bitDelay();
+
+  // CLK to high
+  CLK_Input();
+  bitDelay();
+  uint8_t ack = DIO_Read();
+  if (ack == 0)
+    DIO_Output();
+
+
+  bitDelay();
+  CLK_Output();
+  bitDelay();
+
+  return ack;
+}
+
+void TM1637Display::showDots(uint8_t dots, uint8_t* digits)
+{
+    for(int i = 0; i < 4; ++i)
+    {
+        digits[i] |= (dots & 0x80);
+        dots <<= 1;
+    }
+}
+
+uint8_t TM1637Display::encodeDigit(uint8_t digit)
+{
+	return digitToSegment[digit & 0x0f];
+}
+
+inline void TM1637Display::DIO_Output() {
+    *(m_ddr) |= (1<<m_pinDIO);
+  }
+
+  inline void TM1637Display::DIO_Input() {
+    *(m_ddr) &= ~(1<<m_pinDIO);
+  }
+
+  inline void TM1637Display::DIO_Low() {
+    *m_port &= ~(1<<m_pinDIO);
+  }
+
+  inline bool TM1637Display::DIO_Read() {
+    return *(m_pin) & (1<<m_pinDIO) >> m_pinDIO;
+  }
+
+  inline void TM1637Display::CLK_Output() {
+    *(m_ddr) |= (1<<m_pinClk);
+  }
+
+  inline void TM1637Display::CLK_Input() {
+    *(m_ddr) &= ~(1<<m_pinClk);
+  }
+
+  inline void TM1637Display::CLK_Low() {
+    *m_port &= ~(1<<m_pinClk);
+  }
\ No newline at end of file
diff --git a/src/TM1637Display.h b/src/TM1637Display.h
new file mode 100644
index 0000000..c69a454
--- /dev/null
+++ b/src/TM1637Display.h
@@ -0,0 +1,176 @@
+//  Author: avishorp@gmail.com
+//
+//  This library is free software; you can redistribute it and/or
+//  modify it under the terms of the GNU Lesser General Public
+//  License as published by the Free Software Foundation; either
+//  version 2.1 of the License, or (at your option) any later version.
+//
+//  This library is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+//  Lesser General Public License for more details.
+//
+//  You should have received a copy of the GNU Lesser General Public
+//  License along with this library; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+#ifndef __TM1637DISPLAY__
+#define __TM1637DISPLAY__
+
+#include <inttypes.h>
+#include <avr/io.h>
+
+#define SEG_A   0b00000001
+#define SEG_B   0b00000010
+#define SEG_C   0b00000100
+#define SEG_D   0b00001000
+#define SEG_E   0b00010000
+#define SEG_F   0b00100000
+#define SEG_G   0b01000000
+
+#define DEFAULT_BIT_DELAY  100
+
+class TM1637Display {
+
+public:
+  //! Initialize a TM1637Display object, setting the clock and
+  //! data pins.
+  //!
+  //! @param pinClk - The number of the digital pin connected to the clock pin of the module
+  //! @param pinDIO - The number of the digital pin connected to the DIO pin of the module
+  //! @param bitDelay - The delay, in microseconds, between bit transition on the serial
+  //!                   bus connected to the display
+  TM1637Display(uint8_t pinClk, uint8_t pinDIO, volatile uint8_t *port, int bitDelay = DEFAULT_BIT_DELAY);
+
+  //! Sets the brightness of the display.
+  //!
+  //! The setting takes effect when a command is given to change the data being
+  //! displayed.
+  //!
+  //! @param brightness A number from 0 (lowes brightness) to 7 (highest brightness)
+  //! @param on Turn display on or off
+  void setBrightness(uint8_t brightness, bool on = true);
+
+  //! Display arbitrary data on the module
+  //!
+  //! This function receives raw segment values as input and displays them. The segment data
+  //! is given as a byte array, each byte corresponding to a single digit. Within each byte,
+  //! bit 0 is segment A, bit 1 is segment B etc.
+  //! The function may either set the entire display or any desirable part on its own. The first
+  //! digit is given by the @ref pos argument with 0 being the leftmost digit. The @ref length
+  //! argument is the number of digits to be set. Other digits are not affected.
+  //!
+  //! @param segments An array of size @ref length containing the raw segment values
+  //! @param length The number of digits to be modified
+  //! @param pos The position from which to start the modification (0 - leftmost, 3 - rightmost)
+  void setSegments(const uint8_t segments[], uint8_t length = 4, uint8_t pos = 0);
+
+  //! Clear the display
+  void clear();
+
+  //! Display a decimal number
+  //!
+  //! Dispaly the given argument as a decimal number.
+  //!
+  //! @param num The number to be shown
+  //! @param leading_zero When true, leading zeros are displayed. Otherwise unnecessary digits are
+  //!        blank. NOTE: leading zero is not supported with negative numbers.
+  //! @param length The number of digits to set. The user must ensure that the number to be shown
+  //!        fits to the number of digits requested (for example, if two digits are to be displayed,
+  //!        the number must be between 0 to 99)
+  //! @param pos The position of the most significant digit (0 - leftmost, 3 - rightmost)
+  void showNumberDec(int num, bool leading_zero = false, uint8_t length = 4, uint8_t pos = 0);
+
+  //! Display a decimal number, with dot control
+  //!
+  //! Dispaly the given argument as a decimal number. The dots between the digits (or colon)
+  //! can be individually controlled.
+  //!
+  //! @param num The number to be shown
+  //! @param dots Dot/Colon enable. The argument is a bitmask, with each bit corresponding to a dot
+  //!        between the digits (or colon mark, as implemented by each module). i.e.
+  //!        For displays with dots between each digit:
+  //!        * 0.000 (0b10000000)
+  //!        * 00.00 (0b01000000)
+  //!        * 000.0 (0b00100000)
+  //!        * 0.0.0.0 (0b11100000)
+  //!        For displays with just a colon:
+  //!        * 00:00 (0b01000000)
+  //!        For displays with dots and colons colon:
+  //!        * 0.0:0.0 (0b11100000)
+  //! @param leading_zero When true, leading zeros are displayed. Otherwise unnecessary digits are
+  //!        blank. NOTE: leading zero is not supported with negative numbers.
+  //! @param length The number of digits to set. The user must ensure that the number to be shown
+  //!        fits to the number of digits requested (for example, if two digits are to be displayed,
+  //!        the number must be between 0 to 99)
+  //! @param pos The position of the most significant digit (0 - leftmost, 3 - rightmost)
+  void showNumberDecEx(int num, uint8_t dots = 0, bool leading_zero = false, uint8_t length = 4, uint8_t pos = 0);
+
+  //! Display a hexadecimal number, with dot control
+  //!
+  //! Dispaly the given argument as a hexadecimal number. The dots between the digits (or colon)
+  //! can be individually controlled.
+  //!
+  //! @param num The number to be shown
+  //! @param dots Dot/Colon enable. The argument is a bitmask, with each bit corresponding to a dot
+  //!        between the digits (or colon mark, as implemented by each module). i.e.
+  //!        For displays with dots between each digit:
+  //!        * 0.000 (0b10000000)
+  //!        * 00.00 (0b01000000)
+  //!        * 000.0 (0b00100000)
+  //!        * 0.0.0.0 (0b11100000)
+  //!        For displays with just a colon:
+  //!        * 00:00 (0b01000000)
+  //!        For displays with dots and colons colon:
+  //!        * 0.0:0.0 (0b11100000)
+  //! @param leading_zero When true, leading zeros are displayed. Otherwise unnecessary digits are
+  //!        blank
+  //! @param length The number of digits to set. The user must ensure that the number to be shown
+  //!        fits to the number of digits requested (for example, if two digits are to be displayed,
+  //!        the number must be between 0 to 99)
+  //! @param pos The position of the most significant digit (0 - leftmost, 3 - rightmost)
+  void showNumberHexEx(uint16_t num, uint8_t dots = 0, bool leading_zero = false, uint8_t length = 4, uint8_t pos = 0);
+
+  //! Translate a single digit into 7 segment code
+  //!
+  //! The method accepts a number between 0 - 15 and converts it to the
+  //! code required to display the number on a 7 segment display.
+  //! Numbers between 10-15 are converted to hexadecimal digits (A-F)
+  //!
+  //! @param digit A number between 0 to 15
+  //! @return A code representing the 7 segment image of the digit (LSB - segment A;
+  //!         bit 6 - segment G; bit 7 - always zero)
+  uint8_t encodeDigit(uint8_t digit);
+
+protected:
+   void bitDelay();
+
+   void start();
+
+   void stop();
+
+   bool writeByte(uint8_t b);
+
+   void showDots(uint8_t dots, uint8_t* digits);
+   
+   void showNumberBaseEx(int8_t base, uint16_t num, uint8_t dots = 0, bool leading_zero = false, uint8_t length = 4, uint8_t pos = 0);
+
+
+private:
+	uint8_t m_pinClk;
+	uint8_t m_pinDIO;
+	uint8_t m_brightness;
+  volatile uint8_t *m_port;
+  volatile uint8_t *m_ddr;
+  volatile uint8_t *m_pin;
+	unsigned int m_bitDelay;
+  inline void DIO_Output();
+  inline void DIO_Input();
+  inline void DIO_Low();
+  inline bool DIO_Read();
+  inline void CLK_Output();
+  inline void CLK_Input();
+  inline void CLK_Low();
+};
+
+#endif // __TM1637DISPLAY__
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 0000000..40337d8
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,29 @@
+/*
+ * Blink.cpp
+ *
+ * Created: 18/12/2018 5:11:34 PM
+ * Author : jimmy
+ */ 
+#define F_CPU 8000000
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <util/delay.h>
+#include "TM1637Display.h"
+
+int main(void) {
+	//*(&PORTA-1) |= (1<<PA0);
+	const int CLK = PA0;                           //Set the display CLK pin PC1
+	const int DIO = PA1;                           //Set the display DIO pin PC0
+	TM1637Display display(CLK, DIO, &PORTA);              //set up the 4-Digit Display.
+	int count = 0;
+	// 7-Seg Setup
+	display.setBrightness(255);                  //display to high brightness
+	 
+
+	while(1){
+		display.showNumberDec(count++);
+		//PORTA ^= (1<<PA0);
+		_delay_ms(1000);
+	}
+}
+