make uart_pty threadsafe
[simavr] / examples / board_hd77480 / atmega48_charlcd.c
1 /*
2         atmega48_charlcd.c
3
4         Copyright Luki <humbell@ethz.ch>
5         Copyright 2011 Michel Pollet <buserror@gmail.com>
6
7         This file is part of simavr.
8
9         simavr is free software: you can redistribute it and/or modify
10         it under the terms of the GNU General Public License as published by
11         the Free Software Foundation, either version 3 of the License, or
12         (at your option) any later version.
13
14         simavr is distributed in the hope that it will be useful,
15         but WITHOUT ANY WARRANTY; without even the implied warranty of
16         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17         GNU General Public License for more details.
18
19         You should have received a copy of the GNU General Public License
20         along with simavr.  If not, see <http://www.gnu.org/licenses/>.
21  */
22
23 #undef F_CPU
24 #define F_CPU 10000000
25
26 #include <avr/io.h>
27 #include <avr/interrupt.h>
28 #include <util/delay.h>
29 #include <avr/sleep.h>
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <string.h>
33
34 //#include "avr_defines.h"
35
36 #include "avr_mcu_section.h"
37 AVR_MCU(F_CPU, "atmega48");
38
39 static uint8_t subsecct = 0;
40 static uint8_t hour = 0;
41 static uint8_t minute = 0;
42 static uint8_t second = 0;
43 static volatile uint8_t update_needed = 0;
44
45 #include "avr_hd44780.c"
46
47 ISR( INT0_vect )
48 {
49         /* External interrupt on pin D2 */
50         subsecct++;
51         if (subsecct == 50) {
52                 second++;
53                 subsecct = 0;
54                 update_needed = 1;
55                 if (second == 60) {
56                         minute++;
57                         second = 0;
58                         if (minute == 60) {
59                                 minute = 0;
60                                 hour++;
61                                 if (hour == 24)
62                                         hour = 0;
63                         }
64                 }
65         }
66 }
67
68 int main()
69 {
70         hd44780_init();
71         /*
72          * Clear the display.
73          */
74         hd44780_outcmd(HD44780_CLR);
75         hd44780_wait_ready(1); // long wait
76
77         /*
78          * Entry mode: auto-increment address counter, no display shift in
79          * effect.
80          */
81         hd44780_outcmd(HD44780_ENTMODE(1, 0));
82         hd44780_wait_ready(0);
83
84         /*
85          * Enable display, activate non-blinking cursor.
86          */
87         hd44780_outcmd(HD44780_DISPCTL(1, 1, 0));
88         hd44780_wait_ready(0);
89
90         EICRA = (1 << ISC00);
91         EIMSK = (1 << INT0);
92
93         sei();
94
95         while (1) {
96                 while (!update_needed)
97                         sleep_mode();
98                 update_needed = 0;
99                 char buffer[16];
100
101                 hd44780_outcmd(HD44780_CLR);
102                 hd44780_wait_ready(1); // long wait
103                 hd44780_outcmd(HD44780_DDADDR(4));
104                 hd44780_wait_ready(0);
105                 sprintf(buffer, "%2d:%02d:%02d", hour, minute, second);
106
107                 char *s = buffer;
108                 while (*s) {
109                         hd44780_outdata(*s++);
110                         hd44780_wait_ready(0);
111                 }
112         }
113
114 }