root / scout_avr / bom / bom.c @ cbe25c0a
History | View | Annotate | Download (2.49 KB)
1 | f572eaeb | Tom Mullins | #include <stdint.h> |
---|---|---|---|
2 | #include <avr/io.h> |
||
3 | #include <avr/interrupt.h> |
||
4 | cbe25c0a | tmullins | #include "tiny-twi.h" |
5 | f572eaeb | Tom Mullins | #include "bomi2c.h" |
6 | |||
7 | char last_bit;
|
||
8 | char count;
|
||
9 | uint16_t data; |
||
10 | f8c1522b | Aaron Perley | volatile char currently_sending; |
11 | char sending_counter;
|
||
12 | uint16_t sending_data; |
||
13 | f572eaeb | Tom Mullins | |
14 | #define READ_BIT(pin, bit) (((pin) >> bit) & 1) |
||
15 | #define SET_BIT(pin, bit) ((pin) |= (1 << (bit))) |
||
16 | c7445989 | Tom Mullins | #define CLEAR_BIT(pin, bit) ((pin) &= ~(1 << (bit))) |
17 | f8c1522b | Aaron Perley | #define PRESCALAR 8 |
18 | #define TIME_US(us) (F_CPU * (us) / 1000000 / PRESCALAR) |
||
19 | f572eaeb | Tom Mullins | |
20 | cbe25c0a | tmullins | #define ADDRESS 0x3 |
21 | f572eaeb | Tom Mullins | |
22 | static void bom_start(void) { |
||
23 | data = 0;
|
||
24 | count = 0;
|
||
25 | last_bit = 1;
|
||
26 | // TODO disable interrupt
|
||
27 | cbe25c0a | tmullins | // TODO start timer0
|
28 | f572eaeb | Tom Mullins | } |
29 | |||
30 | static void bom_stop(void) { |
||
31 | // TODO stop timer
|
||
32 | // TODO restart INT0
|
||
33 | } |
||
34 | |||
35 | static void bom_init(void) { |
||
36 | |||
37 | // setup INT0
|
||
38 | //EICRA |= _BV(ISC01) | _BV(ISC00);
|
||
39 | //EIMSK |= _BV(INT0);
|
||
40 | |||
41 | // setup timer 0
|
||
42 | f8c1522b | Aaron Perley | TCCR0B |= _BV(CS01); |
43 | TIMSK |= _BV(OCIE0A); |
||
44 | |||
45 | // setup timer 1 for output
|
||
46 | OCR1B = TIME_US(320); // Set match b to fire every 320 us |
||
47 | c7445989 | Tom Mullins | TIMSK |= _BV(OCIE1A) | _BV(OCIE1B); // Enable interrupt for match a and b
|
48 | TCCR1 |= _BV(CTC1); // Enables resetting timer1 after matches match c
|
||
49 | f572eaeb | Tom Mullins | |
50 | // setup output pin
|
||
51 | c7445989 | Tom Mullins | SET_BIT(DDRB, 4);
|
52 | f572eaeb | Tom Mullins | |
53 | c7445989 | Tom Mullins | sei(); |
54 | f572eaeb | Tom Mullins | bom_start(); |
55 | } |
||
56 | |||
57 | ISR(TIMER0_COMPA_vect) { |
||
58 | |||
59 | c7445989 | Tom Mullins | char this_bit = READ_BIT(PINB, PB2);
|
60 | f572eaeb | Tom Mullins | |
61 | if (this_bit == 0) { |
||
62 | if (last_bit == 0) { |
||
63 | bom_stop(); |
||
64 | } |
||
65 | } else {
|
||
66 | data = data << 1 | (~last_bit & 1); |
||
67 | count++; |
||
68 | } |
||
69 | |||
70 | last_bit = this_bit; |
||
71 | |||
72 | if (count == 15) { |
||
73 | cbe25c0a | tmullins | smb_send_data(&data, sizeof(data));
|
74 | f572eaeb | Tom Mullins | bom_stop(); |
75 | } |
||
76 | } |
||
77 | |||
78 | f8c1522b | Aaron Perley | static void send_next_bit() { |
79 | c7445989 | Tom Mullins | char next_bit = sending_data >> (14 - sending_counter) & 1; |
80 | char ocr_temp = next_bit ? TIME_US(2000-40) : TIME_US(1000-20); |
||
81 | f8c1522b | Aaron Perley | OCR1A = ocr_temp; |
82 | OCR1C = ocr_temp; |
||
83 | f572eaeb | Tom Mullins | } |
84 | |||
85 | f8c1522b | Aaron Perley | ISR(TIMER1_COMPA_vect) { |
86 | c7445989 | Tom Mullins | SET_BIT(PORTB, PB4); |
87 | sending_counter++; |
||
88 | send_next_bit(); |
||
89 | } |
||
90 | |||
91 | ISR(TIMER1_COMPB_vect) { |
||
92 | CLEAR_BIT(PORTB, PB4); |
||
93 | if (sending_counter >= 15) { |
||
94 | f8c1522b | Aaron Perley | currently_sending = 0;
|
95 | TCCR1 &= ~0x0F; // Stop the timer without clearing CTC1 |
||
96 | f572eaeb | Tom Mullins | } |
97 | } |
||
98 | |||
99 | f8c1522b | Aaron Perley | static void send_data(uint16_t data) { |
100 | sending_data = data; |
||
101 | sending_counter = 0;
|
||
102 | currently_sending = 1;
|
||
103 | c7445989 | Tom Mullins | TCNT1 = 0;
|
104 | f8c1522b | Aaron Perley | TCCR1 |= _BV(CS12); // Set prescalar to 8 and start timer
|
105 | c7445989 | Tom Mullins | SET_BIT(PORTB, PB4); |
106 | send_next_bit(); |
||
107 | f8c1522b | Aaron Perley | } |
108 | c7445989 | Tom Mullins | |
109 | ISR(INT0_vect) { |
||
110 | bom_start(); |
||
111 | } |
||
112 | |||
113 | |||
114 | cbe25c0a | tmullins | |
115 | static void slave_rx(uint8_t *buf, int len) { |
||
116 | if (len >= 3) { |
||
117 | switch (buf[0]) { |
||
118 | case BOM_I2C_SEND:
|
||
119 | if (!currently_sending) send_data((uint16_t) buf[1] << 8 | buf[2]); |
||
120 | break;
|
||
121 | } |
||
122 | } |
||
123 | } |
||
124 | |||
125 | |||
126 | c7445989 | Tom Mullins | |
127 | f572eaeb | Tom Mullins | int main() {
|
128 | bom_init(); |
||
129 | cbe25c0a | tmullins | smb_init(slave_rx); |
130 | smb_set_address(ADDRESS); |
||
131 | for (;;);;;;;;;;;;;;;;;;;
|
||
132 | f572eaeb | Tom Mullins | } |