Project

General

Profile

Statistics
| Branch: | Revision:

scoutos / scout_avr / bom / bom.c @ f8c1522b

History | View | Annotate | Download (2.54 KB)

1
#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
volatile char currently_sending;
16
char sending_counter;
17
uint16_t sending_data;
18

    
19
#define READ_BIT(pin, bit) (((pin) >> bit) & 1)
20
#define SET_BIT(pin, bit) ((pin) |= (1 << (bit)))
21
#define PRESCALAR 8
22
#define TIME_US(us) (F_CPU * (us) / 1000000 / PRESCALAR)
23

    
24
static void send_bit(char bit);
25

    
26
static void slave_tx(void) {
27
  twi_transmit((uint8_t*)queue, queue_idx * sizeof(queue[0]));
28
  queue_idx = 0;
29
}
30

    
31
static void slave_rx(uint8_t *buf, int len) {
32
  if (len > 0) {
33
    switch (buf[0]) {
34
      case BOM_I2C_SEND:
35
        // TODO
36
        break;
37
    }
38
  }
39
}
40

    
41
static void bom_start(void) {
42
  data = 0;
43
  count = 0;
44
  last_bit = 1;
45
  // TODO disable interrupt
46
  // TODO start timer
47
}
48

    
49
static void bom_stop(void) {
50
  // TODO stop timer
51
  // TODO restart INT0
52
}
53

    
54
static void bom_init(void) {
55

    
56
  // setup INT0
57
  //EICRA |= _BV(ISC01) | _BV(ISC00);
58
  //EIMSK |= _BV(INT0);
59

    
60
  // setup timer 0
61
  TCCR0B |= _BV(CS01);
62
  TIMSK |= _BV(OCIE0A);
63

    
64
  // setup timer 1 for output
65
  GTCCR |= _BV(COM1B1);  // Set pin3 low when timer1 matches match b
66
  OCR1B = TIME_US(320); // Set match b to fire every 320 us
67
  TIMSK |= _BV(OCIE1A); // Enable interrupt for match a
68
  TCCR1 |= _BV(CTC1);   // Enables resetting timer1 after matches match a
69

    
70
  // setup output pin
71
  SET_BIT(DDRD, 5);
72

    
73
  //sei();
74
  bom_start();
75
}
76

    
77

    
78

    
79
ISR(TIMER0_COMPA_vect) {
80

    
81
  char this_bit = READ_BIT(PIND, PD2);
82

    
83
  if (this_bit == 0) {
84
    if (last_bit == 0) {
85
      bom_stop();
86
    }
87
  } else {
88
    data = data << 1 | (~last_bit & 1);
89
    count++;
90
  }
91

    
92
  last_bit = this_bit;
93

    
94
  if (count == 15) {
95
    if (queue_idx < QUEUE_SIZE) {
96
      queue[queue_idx] = data;
97
      queue_idx++;
98
    }
99
    bom_stop();
100
  }
101
}
102

    
103
static void send_next_bit() {
104
  char next_bit = sending_data >> (14-counter) & 1;
105
  char ocr_temp  next_bit ? TIME_US(2000) : TIME_US(1000);
106
  OCR1A = ocr_temp;
107
  OCR1C = ocr_temp;
108
  SET_BIT(PORTD, PD5);
109
}
110

    
111
ISR(TIMER1_COMPA_vect) {
112
  if (++counter > 15) {
113
    currently_sending = 0;
114
    TCCR1 &= ~0x0F; // Stop the timer without clearing CTC1
115
  } else {
116
    send_next_bit();
117
  }
118
}
119

    
120
static void send_data(uint16_t data) {
121
  sending_data = data;
122
  sending_counter = 0;
123
  currently_sending = 1;
124
  send_next_bit();
125
  TCCR1 |= _BV(CS12);  // Set prescalar to 8 and start timer
126
  while (currently_sending) { }
127
}
128
int main() {
129
  bom_init();
130
  for (;;) {
131
    send_data(45243);
132
    _delay_ms(100);
133
  }
134
}
135

    
136
ISR(INT0_vect) {
137
  bom_start();
138
}