Project

General

Profile

Statistics
| Revision:

root / branches / autonomous_recharging / code / projects / colonet / utilities / robot_wireless_relay / dio.c @ 1390

History | View | Annotate | Download (5.77 KB)

1
/* 
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
  //return (BTN & (_BV(BTN1)) >> BTN1);
204
  return (PIN_BTN >> BTN1) & 1;
205
}
206

    
207
/* similar to button1_read, but hold program until the button is actually 
208
 * pressed
209
*/
210
void button1_wait( void )
211
{
212
  while(!button1_read() ) {
213
    delay_ms(15);
214
  }
215
}
216

    
217
/*
218
  same as button1_wait
219
  However, blink the led while waiting
220

221
  IMPORTANT: This requires that the LED has been initialized (  init_led  )
222
*/
223
void button1_wait_led( void )
224
{
225
  int i = 0;
226
  
227
  while(!button1_read()){
228
    if(i < 8){
229
      led_user(1);
230
    }else{
231
      led_user(0);
232
    }
233
    //increment i, but restart when i = 15;
234
    i = (i+1) & 0xF;
235
    delay_ms(15);
236
  }
237
  
238
  led_user(0);
239
}
240

    
241
//click waits until the button is realesed to return true
242
//return false immediatley
243
int button1_click()
244
{
245
  if(button1_read()){
246
    while(button1_read());
247
    return 1;
248
  }else{
249
    return 0;
250
  }
251
}
252

    
253
//////////////////////////////////////
254
////////////   button2  //////////////
255
//////////////////////////////////////
256
//see button1 functions for descriptions
257
//same except for which button is used
258
int button2_read( void )
259
{
260
  return (PIN_BTN >> BTN2) & 1;
261
}
262

    
263
void button2_wait( void )
264
{
265
  while(!button2_read()){
266
    delay_ms(15);
267
  }
268
}
269

    
270
void button2_wait_led(void)
271
{
272
  int i = 0;
273
  
274
  while(!button2_read()){
275
    if(i < 8){
276
                        led_user(1);
277
    }else{
278
                        led_user(0);
279
                }
280
                //increment i, but restart when i = 15;
281
                i = (i+1) & 0xF;
282
                delay_ms(15);
283
        }
284
        
285
        led_user(0);
286
}
287

    
288
int button2_click()
289
{
290
        if(button2_read()){
291
    while(button2_read());
292
    return 1;
293
  }else{
294
                return 0;
295
  }
296
}
297

    
298
/*
299
// EXTERNAL INTERRUPTS
300
/// example code to be used by anyone in need
301
/// this example has 2 bump sensors on PE6 and PE7
302

303
// left touch sensor on PE6 
304
SIGNAL (SIG_INTERRUPT6)
305
{
306
putcharlcd('6');
307
}
308

309
// right touch sensor on PE7
310
SIGNAL (SIG_INTERRUPT7)
311
{
312
        putcharlcd('7');
313
}
314
*/