Revision 63e19141

View differences:

scout_avr/src/bom.cpp
15 15
 * BOM uses timer 4 for period timing, and timer 0 for 38kHz signal
16 16
 */
17 17

  
18
 /*
19
  * Recently modified so that when BOM is sending, it stops listening. When
20
  * not sending, it keeps listening.
21
  */
22

  
18 23
#define TIME_MICROS(us, prescale) (F_CPU / 1000000 * (us) / (prescale))
19 24

  
20 25
typedef uint16_t sharp_msg_t;
......
60 65
static void init_38kHz_signal() {
61 66
  out_high = 0;
62 67
  out_pin_mask = 0;
63
  
68

  
64 69
  // timer configuration now done in Atmega128rfa1.cpp
65 70
}
66 71

  
......
71 76
}
72 77

  
73 78
static void stop_38kHz_signal() {
74
  PORT_BOM_EMIT &= ~ out_pin_mask;
79
  PORT_BOM_EMIT &= ~ out_pin_mask; // why not just do PORT_BOM_EMIT &= 0; ?
75 80
  out_high = 0;
76 81
}
77 82

  
......
79 84
  // timer 4 mode CTC (clear timer on compare), TOP = OCRA
80 85
  TCCR4A = 0;
81 86
  TCCR4B = _BV(WGM42);
82
  
87

  
83 88
  // run interrupt immediately when timer started
84 89
  OCR4A = 0;
85
  
90

  
86 91
  // enable interrupt
87 92
  TIMSK4 = _BV(OCIE4A);
88 93
}
89 94

  
90 95
static void start_data_signal() {
91 96
  TCNT4 = 0;
92
  
97

  
93 98
  // start timer 4 at F_CPU/64 prescaling
94 99
  TCCR4B |= _BV(CS41) | _BV(CS40);
95 100
}
......
124 129
  DDRB &= ~ (_BV(DDB0) | _BV(DDB1) | _BV(DDB2) | _BV(DDB3));
125 130
  PCMSK0 |= _BV(PCINT0) | _BV(PCINT1) | _BV(PCINT2) | _BV(PCINT3);
126 131
  PCICR |= _BV(PCIE0);
127
  
132

  
128 133
  // BOM_EMIT as output
129 134
  DDRF |= _BV(DDF4) | _BV(DDF5) | _BV(DDF6) | _BV(DDF7);
130 135

  
......
132 137
  init_data_signal();
133 138
}
134 139

  
140
static void stop_receiving(char dir) {
141
  switch (dir) {
142
    case BOM_FRONT: PCMSK0 &= ~_BV(PCINT0); break;
143
    case BOM_LEFT : PCMSK0 &= ~_BV(PCINT1); break;
144
    case BOM_RIGHT: PCMSK0 &= ~_BV(PCINT2); break;
145
    case BOM_BACK : PCMSK0 &= ~_BV(PCINT3); break;
146
  }
147
}
148

  
149
static void start_receiving(char dir) {
150
  // flush rx buffer before turning on the receiver
151
  bom_rx[(int)dir].bits = 0;
152
  bom_rx[(int)dir].count = 0;
153

  
154
  switch (dir) {
155
    case BOM_FRONT: PCMSK0 |= _BV(PCINT0); break;
156
    case BOM_LEFT : PCMSK0 |= _BV(PCINT1); break;
157
    case BOM_RIGHT: PCMSK0 |= _BV(PCINT2); break;
158
    case BOM_BACK : PCMSK0 |= _BV(PCINT3); break;
159
  }
160
}
161

  
135 162
void bom_send(char dir) {
136 163
  switch (dir) {
137 164
    case BOM_FRONT: out_pin_mask = _BV(P_BOM_EMIT0); break;
......
142 169
  out_counter = 16;
143 170
  out_msg = sharp_msg_make(0x2A, bom_msg_make(robot_id, dir));
144 171
  out_done = 0;
172

  
173
  stop_receiving(dir); // disable receiver
174
  start_38kHz_signal(); // enable the transmitter
145 175
  start_data_signal();
146 176
  while (!out_done) {
147 177
    _delay_ms(0.1);
148 178
  }
179
  stop_data_signal(); // disable the transmitter
180
  stop_38kHz_signal();
181
  start_receiving(dir);  // enable the receiver
149 182
}
150 183

  
151 184
static void recv_edge(char is_rising, struct bom_rx_t *rx) {
......
159 192
    int max_low = TIME_MICROS(MAX_LOW_PW, 64);
160 193
    int min_high = TIME_MICROS(MIN_HIGH_PW, 64);
161 194
    int max_high = TIME_MICROS(MAX_HIGH_PW, 64);
162
    
195

  
163 196
    if (rx->count) {
164 197
      int diff = (now - rx->last_time);
165 198
      rx->bits <<= 1;
......
184 217
        rx->bits = 0;
185 218
      }
186 219
    }
187
    
220

  
188 221
    rx->count++;
189 222
    rx->last_time = now;
190 223
  }

Also available in: Unified diff