Project

General

Profile

Statistics
| Branch: | Revision:

root / scout_avr / bom / bom.c @ c7445989

History | View | Annotate | Download (2.68 KB)

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