1 | #include <avr/io.h>
|
2 | #include <util/delay.h>
|
3 | #include <i2cmaster.h>
|
4 |
|
5 |
|
6 | #define BAUD 9600
|
7 | #define MYUBRR ((uint16_t) ((F_CPU / ((BAUD) * 16.0)) + .5) - 1)
|
8 |
|
9 | #define rtc_clock 0x68
|
10 |
|
11 | // contains what the bluetooth module received
|
12 | uint8_t data;
|
13 |
|
14 | void USART_Init(unsigned int ubrr) {
|
15 | // set baud rate
|
16 | UBRR0H = (unsigned char)(ubrr>>8);
|
17 | UBRR0L = (unsigned char)(ubrr);
|
18 | // enable receiver, transmitter and interrupts for rx/tx
|
19 | UCSR0B = (1<<RXEN0) | (1<<TXEN0) | (1<<RXCIE0) | (1<< TXCIE0);
|
20 | }
|
21 |
|
22 |
|
23 |
|
24 | void USART_transmit(char c) {
|
25 | while ( !(UCSR0A & (1<<UDRE0)) ) {}
|
26 | UDR0 = c;
|
27 | }
|
28 |
|
29 |
|
30 |
|
31 | void transmit_char(char c) {
|
32 | USART_transmit(c);
|
33 | USART_transmit('\r');
|
34 | USART_transmit('\n');
|
35 | }
|
36 |
|
37 |
|
38 |
|
39 | void send_string(char s[]) {
|
40 | int i =0;
|
41 |
|
42 | while (s[i] != 0x00) {
|
43 | USART_transmit(s[i]);
|
44 | i++;
|
45 | }
|
46 | USART_transmit('\r');
|
47 | USART_transmit('\n');
|
48 |
|
49 | }
|
50 |
|
51 |
|
52 | // code for two status leds, to signal error and ok states
|
53 | // please dont look to closely....needs rewriting
|
54 |
|
55 | #define ERROR_LED_2 PB1
|
56 | #define ERROR_LED PB0
|
57 | #define OK_LED PB2
|
58 |
|
59 | #define ERROR_LED_2_PORT PORTB
|
60 | #define ERROR_LED_PORT PORTB
|
61 | #define OK_LED_PORT PORTB
|
62 |
|
63 |
|
64 | // turn the error led on and keep it on
|
65 | void error_led_on() {
|
66 | ERROR_LED_PORT |= (1 << ERROR_LED);
|
67 | }
|
68 |
|
69 | // turn it off
|
70 | void error_led_off() {
|
71 | ERROR_LED_PORT &= ~(1 << ERROR_LED);
|
72 | }
|
73 |
|
74 |
|
75 | void error_led2_on() {
|
76 | ERROR_LED_2_PORT |= (1 << ERROR_LED_2);
|
77 | }
|
78 |
|
79 | // turn it off
|
80 | void error_led2_off() {
|
81 | ERROR_LED_2_PORT &= ~(1 << ERROR_LED_2);
|
82 | }
|
83 |
|
84 |
|
85 | // flash the error led, fast
|
86 | void flash_fast(uint8_t count) {
|
87 | for (int n=1; n<=count; n++) {
|
88 | error_led_on();
|
89 | _delay_ms(300);
|
90 | error_led_off();
|
91 | _delay_ms(300);
|
92 | }
|
93 | }
|
94 |
|
95 | // ...normal
|
96 | void flash_normal(uint8_t count) {
|
97 | for (int n=1; n<=count; n++) {
|
98 | error_led_on();
|
99 | _delay_ms(1000);
|
100 | error_led_off();
|
101 | _delay_ms(1000);
|
102 | }
|
103 | }
|
104 |
|
105 | // second led to have more indicator for where we are stuck in the code
|
106 | void flash_normal_error_led_2(uint8_t count) {
|
107 | for (int n=1; n<=count; n++) {
|
108 | error_led2_on();
|
109 | _delay_ms(1000);
|
110 | error_led2_off();
|
111 | _delay_ms(1000);
|
112 | }
|
113 | }
|
114 | // ...slow
|
115 | void flash_slow(uint8_t count) {
|
116 | for (int n=1; n<=count; n++) {
|
117 | error_led_on();
|
118 | _delay_ms(3000);
|
119 | error_led_off();
|
120 | _delay_ms(3000);
|
121 | }
|
122 | }
|
123 |
|
124 | // a third led, can be used to signal ok states
|
125 | void flash_ok_led(uint8_t count) {
|
126 | for (uint8_t n=1; n <= count; n++) {
|
127 | OK_LED_PORT |= (1 << OK_LED);
|
128 | _delay_ms(1000);
|
129 | OK_LED_PORT &= ~(1 << OK_LED);
|
130 | _delay_ms(1000);
|
131 | }
|
132 | }
|
133 |
|
134 | // ---------------------------------- led code end
|
135 |
|
136 |
|
137 |
|
138 |
|
139 |
|
140 |
|
141 |
|
142 | uint8_t decToBcd(uint8_t val)
|
143 | {
|
144 | return( (val/10*16) + (val%10) );
|
145 | }
|
146 | // Convert binary coded decimal to normal decimal numbers
|
147 | uint8_t bcdToDec(uint8_t val)
|
148 | {
|
149 | return( (val/16*10) + (val%16) );
|
150 | }
|
151 |
|
152 |
|
153 |
|
154 |
|
155 | void setTime(uint8_t second, uint8_t minute, uint8_t hour, uint8_t dayOfWeek,
|
156 | uint8_t dayOfMonth, uint8_t month, uint8_t year) {
|
157 |
|
158 | flash_normal(1);
|
159 | // initialize, taken from peter fleurys i2c example (he wrote the i2c code)
|
160 | i2c_init();
|
161 | // connect to the device and tell it that we want to write to it
|
162 |
|
163 | uint8_t ret;
|
164 | //ret = i2c_start(rtc_clock+I2C_WRITE); // set device address and write mode
|
165 | ret = i2c_start(rtc_clock);
|
166 | // this line is never reached
|
167 | flash_normal(1);
|
168 |
|
169 | if ( ret ) {
|
170 | flash_normal(3);
|
171 | /* failed to issue start condition, possibly no device found */
|
172 | i2c_stop();
|
173 | // we can issue an error message here if the device failed to respond
|
174 |
|
175 | } else {
|
176 | flash_ok_led(3);
|
177 | // tell the device where we want to write to (address in ram)
|
178 | i2c_write(0x00);
|
179 |
|
180 | // set time
|
181 | i2c_write(decToBcd(second)); // set seconds
|
182 | i2c_write(decToBcd(minute)); // set minutes
|
183 | i2c_write(decToBcd(hour)); // set hours
|
184 | i2c_write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday)
|
185 | i2c_write(decToBcd(dayOfMonth)); // set date (1 to 31)
|
186 | i2c_write(decToBcd(month)); // set month
|
187 | i2c_write(decToBcd(year)); // set year (0 to 99)
|
188 | i2c_stop();
|
189 | }
|
190 | }
|
191 |
|
192 |
|
193 |
|
194 | uint8_t result;
|
195 |
|
196 | typedef struct {
|
197 | uint8_t sec;
|
198 | uint8_t min;
|
199 | uint8_t hour;
|
200 | uint8_t weekDay;
|
201 | uint8_t date;
|
202 | uint8_t month;
|
203 | uint8_t year;
|
204 | } rtc_t;
|
205 |
|
206 |
|
207 |
|
208 | rtc_t rtc;
|
209 |
|
210 | void getTime(void) {
|
211 | // receive 1 byte (seconds)
|
212 | flash_normal(3);
|
213 |
|
214 | uint8_t ret;
|
215 | ret = i2c_start(rtc_clock+I2C_WRITE); // set device address and write mode
|
216 | if ( ret ) {
|
217 | flash_normal(3);
|
218 | /* failed to issue start condition, possibly no device found */
|
219 | i2c_stop();
|
220 | // we can issue an error message here if the device failed to respond
|
221 |
|
222 | } else {
|
223 | flash_ok_led(1);
|
224 | /* issuing start condition ok, device accessible
|
225 | we can now use i2c_write() to talk to the device*/
|
226 |
|
227 |
|
228 |
|
229 | // request second ram adress (tell the chip at what adress we want to start reading)
|
230 | // 0x00 =
|
231 | i2c_write(0x00);
|
232 | i2c_stop();
|
233 |
|
234 | // _rep_start or _start? whats the difference?
|
235 | i2c_rep_start(rtc_clock);
|
236 | result = i2c_readAck();
|
237 | rtc.sec = i2c_readAck(); // read second and return Positive ACK
|
238 | rtc.min = i2c_readAck(); // read minute and return Positive ACK
|
239 | rtc.hour= i2c_readAck(); // read hour and return Negative/No ACK
|
240 | rtc.weekDay = i2c_readAck(); // read weekDay and return Positive ACK
|
241 | rtc.date= i2c_readAck(); // read Date and return Positive ACK
|
242 | rtc.month=i2c_readAck(); // read Month and return Positive ACK
|
243 | rtc.year =i2c_readNak(); // read Year and return Negative/No ACK
|
244 | i2c_stop();
|
245 | }
|
246 | }
|
247 |
|
248 |
|
249 |
|
250 |
|
251 | int main(void) {
|
252 | DDRB |= (1 << ERROR_LED);
|
253 | DDRB |= (1 << ERROR_LED_2);
|
254 |
|
255 | DDRB |= (1 << OK_LED);
|
256 |
|
257 | // test leds to see if they are connected and working
|
258 |
|
259 | flash_normal(1);
|
260 | flash_normal_error_led_2(1);
|
261 | flash_ok_led(1);
|
262 |
|
263 |
|
264 | i2c_init();
|
265 | uint8_t count = 0;
|
266 | setTime(30,42,21,4,26,11,14);
|
267 |
|
268 | while (1) {
|
269 |
|
270 |
|
271 | _delay_ms(3000);
|
272 |
|
273 | getTime();
|
274 | // flash the led for the ammount of seconds
|
275 | for (uint8_t n=0; n <= rtc.sec; n++) {
|
276 | flash_ok_led(1);
|
277 | }
|
278 | flash_normal(2);
|
279 |
|
280 | }
|
281 | }
|