text: /*
   * ---------------------------------------------------------------------
   * Author:      Tomas Fryza
   *              Dept. of Radio Electronics, Brno Univ. of Technology
   * Created:     2018-10-23
   * Last update: 2019-11-01
   * Platform:    ATmega328P, 16 MHz, AVR 8-bit Toolchain 3.6.2
   * ---------------------------------------------------------------------
   * Description:
   *    Analog-to-digital conversion with displaying result on LCD and 
   *    transmitting via UART.
   * 
   * Note:
   *    Peter Fleury's UART library.
   */
  
  /* Includes ----------------------------------------------------------*/
  #include <stdlib.h>             // itoa() function
  #include <avr/io.h>
  #include <avr/interrupt.h>
  #include "timer.h"
  #include "lcd.h"
  #include "uart.h"
  
  /* Typedef -----------------------------------------------------------*/
  /* Define ------------------------------------------------------------*/
  #define UART_BAUD_RATE 9600
  
  /* Variables ---------------------------------------------------------*/
  /* Function prototypes -----------------------------------------------*/
  
  /* Functions ---------------------------------------------------------*/
  /**
   *  Brief:  Main program. Read ADC result and transmit via UART.
   *  Input:  None
   *  Return: None
   */
  int main(void)
  {
      // LCD display
      lcd_init(LCD_DISP_ON);
      //lcd_puts("LCD testing");
  
      /* ADC
       * TODO: Configure ADC reference, clock source, enable ADC module, 
       *       and enable conversion complete interrupt */
       ADMUX  = 0b01000000;
       ADMUX |= 0; //ADCx
       ADCSRA = _BV(ADIE)|1;
       ADCSRA |= _BV(ADEN); //ADC enable
  
      /* Timer1
       * TODO: Configure Timer1 clock source and enable overflow 
       *       interrupt */
      TIM_config_prescaler(TIM1, TIM_PRESC_64);
      TIM_config_interrupt(TIM1, TIM_OVERFLOW_ENABLE);
  
      // UART: asynchronous, 8-bit data, no parity, 1-bit stop
      uart_init(UART_BAUD_SELECT(UART_BAUD_RATE, F_CPU));
  
      // Enables interrupts by setting the global interrupt mask
      sei();
  
      // Put string to ringbuffer for transmitting via UART.
      uart_puts("UART testing\r\n");
  
      // Infinite loop
      for (;;) {
      }
  
      // Will never reach this
      return (0);
  }
  
  /**
   *  Brief: Timer1 overflow interrupt routine. Start ADC conversion.
   */
  ISR(TIMER1_OVF_vect)
  {
      // TODO: Start ADC conversion
       ADCSRA |= _BV(ADSC); // Start
  }
  
  /**
   *  Brief: ADC complete interrupt routine. Update LCD and UART 
   *         transmiter.
   */
  ISR(ADC_vect)
  {
       static char txt[16];
       const char *names[6] = {"Select", "Left", "Down", "Up", "Right", "null"};
       static uint8_t select = 0;
       if(ADC>=500 && ADC<800) {
           select = 0;
       } else if(ADC>=300 && ADC<500) {
           select = 1;
       } else if(ADC>=150 && ADC<300) {
           select = 2;
       } else if(ADC>=50 && ADC<150) {
           select = 3;
       } else if(ADC<50) {
           select = 4;
       } else {
           select = 5;
       }
  
       //while(!(ADCSRA & _BV(ADIF)));
       lcd_gotoxy(0,0);
       lcd_puts("      ");
       lcd_gotoxy(0,0);
       itoa (ADC, txt, 10);
       lcd_puts(txt);
  
       lcd_gotoxy(0,1);
       lcd_puts("      ");
       lcd_gotoxy(0,1);
       lcd_puts(names[select]);
  
       uart_puts(txt);
       uart_puts(" ");
       uart_puts(names[select]);
       uart_puts("\r\n");
  }
  