Project

General

Profile

Statistics
| Revision:

root / trunk / code / projects / colonet / utilities / robot_slave / dio.c @ 13

History | View | Annotate | Download (5.93 KB)

1 13 emarinel
/*
2
dio.c
3
Controls digital input and output
4

5
A general note on how this code works:
6
portpin is used to select both the bank and which pin is selected
7
6 bits are used (lower 6, ex: 0b00abcdef)
8
the first 3 (abc in this example) are used to select the bank
9
A = 001
10
B = 010
11
C = 011
12
D = 100
13
E = 101
14
F = 110
15
G = 111
16

17
the bank can be found by doing portpin >> 3
18

19
the next 3 (def in this example) are used to select the pin number
20
the 3 bits are just the binary representation of the pin number
21
0 = 000
22
1 = 001
23
2 = 010
24
3 = 011
25
4 = 100
26
5 = 101
27
6 = 110
28
7 = 111
29

30
the pin number can be found by doing portping & 0b111
31
*/
32
33
#include <avr/interrupt.h>
34
#include <dio.h>
35
#include <time.h>
36
#include <lights.h>
37
38
/*
39
 * digital_input
40
 * Reads the value on the selected portpin, returns it as 1 or 0
41
 * see general description (above) for definition of portpin
42
 */
43
int digital_input(int portpin){
44
  int pin = portpin & 0x7;
45
  int pin_val = 0;
46
47
  switch(portpin >> 3){
48
  case _PORT_A:
49
    DDRA &= ~_BV(pin);
50
    pin_val = PINA;
51
    return (pin_val >> pin) & 1;
52
  case _PORT_B:
53
    DDRB &= ~_BV(pin);
54
    pin_val = PINB;
55
    return (pin_val >> pin) & 1;
56
  case _PORT_C:
57
    DDRC &= ~_BV(pin);
58
    pin_val = PINC;
59
    return (pin_val >> pin) & 1;
60
  case _PORT_D:
61
    DDRD &= ~_BV(pin);
62
    pin_val = PIND;
63
    return (pin_val >> pin) & 1;
64
  case _PORT_E:
65
    DDRE &= ~_BV(pin);
66
    pin_val = PINE;
67
    return (pin_val >> pin) & 1;
68
  case _PORT_F:
69
    if(pin>=4){
70
      MCUSR|=1<<7;
71
      MCUSR|=1<<7;
72
    }
73
    DDRF &= ~_BV(pin);
74
    pin_val = PINF;
75
    return (pin_val >> pin) & 1;
76
  case _PORT_G:
77
    DDRG &= ~_BV(pin);
78
    pin_val = PING;
79
    return (pin_val >> pin) & 1;
80
  default: break;
81
  }
82
83
  return -1;
84
}
85
86
/*
87
  digital_pull_up
88
  Enables pullup on a pin.  if pin is output, it will make it output 1.
89
*/
90
void digital_pull_up(int portpin) {
91
  int pins = portpin & 0x07;
92
93
  switch(portpin >> 3) {
94
  case _PORT_A:
95
    PORTA |= _BV(pins);
96
    break;
97
  case _PORT_B:
98
    PORTB |= _BV(pins);
99
    break;
100
  case _PORT_C:
101
    PORTC |= _BV(pins);
102
    break;
103
  case _PORT_D:
104
    PORTD |= _BV(pins);
105
    break;
106
  case _PORT_E:
107
    PORTE |= _BV(pins);
108
    break;
109
  case _PORT_F:
110
    PORTF |= _BV(pins);
111
    break;
112
  case _PORT_G:
113
    PORTG |= _BV(pins);
114
    break;
115
  }
116
}
117
118
/*
119
  digital_output
120

121
  sets portpin to the value
122
  see general description above for explanation of portpin
123
  val can only be 0 for off, nonzero for on
124
*/
125
void digital_output(int portpin, int val) {
126
  int pins = portpin & 0x07;
127
128
  /* if you want to set to 0... */
129
  if(val == 0) {
130
    switch(portpin >> 3) {
131
    case _PORT_A:
132
      DDRA |= _BV(pins);
133
      PORTA &= (0XFF - _BV(pins));
134
      break;
135
    case _PORT_B:
136
      DDRB |= _BV(pins);
137
      PORTB &= (0XFF - _BV(pins));
138
      break;
139
    case _PORT_C:
140
      DDRC |= _BV(pins);
141
      PORTC &= (0XFF - _BV(pins));
142
      break;
143
    case _PORT_D:
144
      DDRD |= _BV(pins);
145
      PORTD &= (0XFF - _BV(pins));
146
      break;
147
    case _PORT_E:
148
      DDRE |= _BV(pins);
149
      PORTE &= (0XFF - _BV(pins));
150
      break;
151
    case _PORT_F:
152
      DDRF |= _BV(pins);
153
      PORTF &= (0XFF - _BV(pins));
154
      break;
155
    case _PORT_G:
156
      DDRG |= _BV(pins);
157
      PORTG &= (0XFF - _BV(pins));
158
      break;
159
    }
160
  }else { /* ( val == 1) */
161
    switch(portpin >> 3) {
162
    case _PORT_A:
163
      DDRA |= _BV(pins);
164
      PORTA |= _BV(pins);
165
      break;
166
    case _PORT_B:
167
      DDRB |= _BV(pins);
168
      PORTB |= _BV(pins);
169
      break;
170
    case _PORT_C:
171
      DDRC |= _BV(pins);
172
      PORTC |= _BV(pins);
173
      break;
174
    case _PORT_D:
175
      DDRD |= _BV(pins);
176
      PORTD |= _BV(pins);
177
      break;
178
    case _PORT_E:
179
      DDRE |= _BV(pins);
180
      PORTE |= _BV(pins);
181
      break;
182
    case _PORT_F:
183
      DDRF |= _BV(pins);
184
      PORTF |= _BV(pins);
185
      break;
186
    case _PORT_G:
187
      DDRG |= _BV(pins);
188
      PORTG |= _BV(pins);
189
      break;
190
    }
191
  }
192
}
193
194
//////////////////////////////////////
195
////////////   button1  //////////////
196
//////////////////////////////////////
197
198
/*
199
  return 1 if button is pressed, 0 otherwise
200
*/
201
int button1_read( void )
202
{
203
        int pin_val;
204
        DDRG &= ~_BV(PING0);
205
        PORTG|= _BV(PING0);
206
    pin_val = PING;
207
        return !((pin_val & _BV(PING0)));
208
209
}
210
211
/* similar to button1_read, but hold program until the button is actually
212
 * pressed
213
*/
214
void button1_wait( void )
215
{
216
  while(!button1_read() ) {
217
    delay_ms(15);
218
  }
219
}
220
221
/* USER LED
222
  same as button1_wait
223
  However, blink the led while waiting
224

225
  IMPORTANT: This requires that the LED has been initialized (  init_led  )
226
*/
227
/*
228
void button1_wait_led( void )
229
{
230
  int i = 0;
231

232
  while(!button1_read()){
233
    if(i < 8){
234
      led_user(1);
235
    }else{
236
      led_user(0);
237
    }
238
    //increment i, but restart when i = 15;
239
    i = (i+1) & 0xF;
240
    delay_ms(15);
241
  }
242

243
  led_user(0);
244
}
245
*/
246
//click waits until the button is realesed to return true
247
//return false immediatley
248
int button1_click()
249
{
250
  if(button1_read()){
251
    while(button1_read());
252
    return 1;
253
  }else{
254
    return 0;
255
  }
256
}
257
258
//////////////////////////////////////
259
////////////   button2  //////////////
260
//////////////////////////////////////
261
//see button1 functions for descriptions
262
//same except for which button is used
263
int button2_read( void )
264
{
265
        int pin_val;
266
        DDRG &= ~_BV(PING1);
267
        PORTG|= _BV(PING1);
268
    pin_val = PING;
269
        return !((pin_val & _BV(PING1)));
270
}
271
272
void button2_wait( void )
273
{
274
  while(!button2_read()){
275
    delay_ms(15);
276
  }
277
}
278
279
/*USER LED NO LONGER EXISTS
280
void button2_wait_led(void)
281
{
282
  int i = 0;
283

284
  while(!button2_read()){
285
    if(i < 8){
286
                        led_user(1);
287
    }else{
288
                        led_user(0);
289
                }
290
                //increment i, but restart when i = 15;
291
                i = (i+1) & 0xF;
292
                delay_ms(15);
293
        }
294

295
        led_user(0);
296
}
297
*/
298
int button2_click()
299
{
300
        if(button2_read()){
301
    while(button2_read());
302
    return 1;
303
  }else{
304
                return 0;
305
  }
306
}
307
308
/*
309
// EXTERNAL INTERRUPTS
310
/// example code to be used by anyone in need
311
/// this example has 2 bump sensors on PE6 and PE7
312

313
// left touch sensor on PE6
314
SIGNAL (SIG_INTERRUPT6)
315
{
316
putcharlcd('6');
317
}
318

319
// right touch sensor on PE7
320
SIGNAL (SIG_INTERRUPT7)
321
{
322
        putcharlcd('7');
323
}
324
*/