Project

General

Profile

Statistics
| Branch: | Revision:

root / scout_avr / bom / bom.c @ b2554c5c

History | View | Annotate | Download (3.37 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 b2554c5c Aaron Perley
#define DETECT PB2
22
#define EMIT PB4
23 f572eaeb Tom Mullins
24
static void bom_init(void) {
25
26
  // setup INT0
27
  //EICRA |= _BV(ISC01) | _BV(ISC00);
28
  //EIMSK |= _BV(INT0);
29
30 b2554c5c Aaron Perley
  init_timer0();
31
  start_timer0();
32 f8c1522b Aaron Perley
33 b2554c5c Aaron Perley
  init_timer1();
34 f572eaeb Tom Mullins
35
  // setup output pin
36 c7445989 Tom Mullins
  SET_BIT(DDRB, 4);
37 f572eaeb Tom Mullins
38 c7445989 Tom Mullins
  sei();
39 f572eaeb Tom Mullins
  bom_start();
40
}
41
42 b2554c5c Aaron Perley
////////////////////////////////// Receiving ///////////////////////////////////
43
44
static void init_timer0(void) {
45
  TCCROA |= _BV(WGM01);    // enable reset on compare A
46
  TIMSK  |= _BV(OCIE0A);   // enable timer0 compare match A
47
}
48
49
static void start_timer0(void) {
50
  TCNT0 = 0; // Reset timer 0 count to 0
51
  TCCR0B |= _BV(CS01);     // setup clkio and start the timer
52
}
53
54
static void start_detect(void) {
55
  data = 0;
56
  count = 0;
57
  last_bit = 1;
58
  start_timer0();
59
}
60
61
static void stop_detect(void) {
62
  TCCR0B &= ~0x07; // Stop timer0
63
}
64
65 f572eaeb Tom Mullins
ISR(TIMER0_COMPA_vect) {
66
67 b2554c5c Aaron Perley
  char this_bit = READ_BIT(PINB, DETECT);
68 f572eaeb Tom Mullins
69
  if (this_bit == 0) {
70
    if (last_bit == 0) {
71 b2554c5c Aaron Perley
      stop_detect();
72 f572eaeb Tom Mullins
    }
73
  } else {
74
    data = data << 1 | (~last_bit & 1);
75
    count++;
76
  }
77
78
  last_bit = this_bit;
79
80
  if (count == 15) {
81 b2554c5c Aaron Perley
    stop_detect();
82 cbe25c0a tmullins
    smb_send_data(&data, sizeof(data));
83 f572eaeb Tom Mullins
  }
84
}
85
86 b2554c5c Aaron Perley
////////////////////////////////////////////////////////////////////////////////
87
88
//////////////////////////////////// Sending ///////////////////////////////////
89
90
static void start_timer1() {
91
  TCNT1 = 0; // Reset timer 1 count to 0
92
  TCCR1 |= _BV(CS12) // Set prescalar to 8 and start timer1
93
}
94
95
static void stop_timer1() {
96
  TCCR1 &= ~0x0F; // Stop the timer without clearing CTC1
97
}
98
99
static void init_timer1() {
100
  OCR1B = TIME_US(320); // Set match b to fire every 320 us
101
  TIMSK |= _BV(OCIE1A) | _BV(OCIE1B); // Enable interrupt for match a and b
102
  TCCR1 |= _BV(CTC1);   // Enables resetting timer1 after matches match c
103
}
104
105
static void send_data(uint16_t data) {
106
  sending_data = data;
107
  sending_counter = 0;
108
  currently_sending = 1;
109
  SET_BIT(PORTB, EMIT);
110
111
  start_timer1();
112
  send_next_bit();
113
}
114
115 f8c1522b Aaron Perley
static void send_next_bit() {
116 c7445989 Tom Mullins
  char next_bit = sending_data >> (14 - sending_counter) & 1;
117
  char ocr_temp = next_bit ? TIME_US(2000-40) : TIME_US(1000-20);
118 b2554c5c Aaron Perley
  OCR1A = ocr_temp; // Compare A - Turns on transmitter
119
  OCR1C = ocr_temp; // Reset the timer when match a fires
120 f572eaeb Tom Mullins
}
121
122 b2554c5c Aaron Perley
// Compare A - Turns on transmitter
123 f8c1522b Aaron Perley
ISR(TIMER1_COMPA_vect) {
124 b2554c5c Aaron Perley
  SET_BIT(PORTB, EMIT); 
125 c7445989 Tom Mullins
  sending_counter++;
126
  send_next_bit();
127
}
128
129 b2554c5c Aaron Perley
// Compare B - Turns off transmitter after 320us
130 c7445989 Tom Mullins
ISR(TIMER1_COMPB_vect) {
131 b2554c5c Aaron Perley
  CLEAR_BIT(PORTB, EMIT);
132 c7445989 Tom Mullins
  if (sending_counter >= 15) {
133 f8c1522b Aaron Perley
    currently_sending = 0;
134 b2554c5c Aaron Perley
    stop_timer1();
135 f572eaeb Tom Mullins
  }
136
}
137
138 b2554c5c Aaron Perley
////////////////////////////////////////////////////////////////////////////////
139
140 c7445989 Tom Mullins
141
ISR(INT0_vect) {
142
  bom_start();
143
}
144
145
146 cbe25c0a tmullins
147
static void slave_rx(uint8_t *buf, int len) {
148
  if (len >= 3) {
149
    switch (buf[0]) {
150
      case BOM_I2C_SEND:
151
        if (!currently_sending) send_data((uint16_t) buf[1] << 8 | buf[2]);  
152
        break;
153
    }
154
  }
155
}
156
157
158 c7445989 Tom Mullins
159 f572eaeb Tom Mullins
int main() {
160
  bom_init();
161 cbe25c0a tmullins
  smb_init(slave_rx);
162
  smb_set_address(ADDRESS);
163
  for (;;);;;;;;;;;;;;;;;;; 
164 f572eaeb Tom Mullins
}