//
// 7 segment LED display library
// Homelab library
//
// Department of Mechatronics
// Tallinn University of Technology
// ITT Group
// © Copyrights 2014
//

//
// Use IO operations
//
#include "pin.h"

//
// Take use of delay functions
//
#include <util/delay.h>

#if defined (__AVR_ATxmega128A1U__)
//
// Pin configuration
//
static pin segment_display_latch =    PIN(K, 6);
static pin segment_display_data_out = PIN(K, 4);
static pin segment_display_clock =    PIN(K, 5);
#else
//
// Pin configuration
//
static pin segment_display_latch =    PIN(G, 2);
static pin segment_display_data_out = PIN(C, 6);
static pin segment_display_clock =    PIN(C, 7);
#endif

//
// Character map
//
const unsigned char __attribute__ ((weak)) segment_char_map[] =
{
    0b00111111,
    0b00000110,
    0b01011011,
    0b01001111,
    0b01100110,
    0b01101101,
    0b01111100,
    0b00000111,
    0b01111111,
    0b01100111,
    0b01111001   // E like Error
};

//
// 7-segment display initialization
//
void segment_display_init(void)
{
    // Set latch, data out and clock pins as output
    pin_setup_output(segment_display_latch);
    pin_setup_output(segment_display_data_out);
    pin_setup_output(segment_display_clock);
}

//
// Digit writing to 7 segment display
//
void segment_display_write(unsigned char digit)
{
    unsigned char map;
    signed char i;

    // Decimal to segment map
    map = segment_char_map[digit];

    // Latch low
    pin_clear(segment_display_latch);

    // Send every bit in the byte. MSB (most significant bit) first.
    for (i = 7; i >= 0; i--)
    {
        // If bit is set, sets the data out pin, otherwise not
        pin_set_to(segment_display_data_out, bit_is_set(map, i));

        // Clock high for certain period
        pin_set(segment_display_clock);
        _delay_us(1);

        // Clock low for certain period
        pin_clear(segment_display_clock);
        _delay_us(1);
    }

    // Latch high
    pin_set(segment_display_latch);
}
