Project

General

Profile

Statistics
| Revision:

root / trunk / code / projects / colonet / utilities / wireless / wireless.c @ 13

History | View | Annotate | Download (5.22 KB)

1
/*
2
Wireless
3
Eugene Marinelli
4

5
(See .h for details)
6
*/
7

    
8
/* Includes */
9
#include <firefly+_lib.h>
10
#include <string.h>
11
#include <avr/interrupt.h>
12

    
13
#include "wireless.h"
14

    
15
/* Constants */
16
#define PREFIX0 'R'
17
#define PREFIX1 'C'
18

    
19
//wl_buf positions
20
#define WL_SRC_LOC 2
21
#define WL_DEST_LOC 3
22
#define WL_DATA_START 4
23

    
24
#define WL_TIMEOUT 4
25
#define WL_TIMEOUT_INITIAL 4
26

    
27
/* Globals */
28
static WL_Packet latest_packet;
29
static WL_Packet tmp_packet;
30
static char new_message; //set to 1 if there is a new message, else 0
31
static char listener_addr; //address that the robot is listening on
32

    
33
static int message_length; //length of the messages sent/received
34

    
35
//static unsigned char wl_to_flag;
36
//static unsigned int wl_to_count;
37
//static unsigned int wl_to_max;
38

    
39
/* Internal function headers */
40
static void wl_timeout_handler(void);
41

    
42
/* External function definitions */
43
int wl_init(int msg_len, char listener_address){
44
  if(msg_len > WL_MSG_MAX_LEN){
45
    printf("Error: %s: message length must be less than %d\n", __FUNCTION__, 
46
           WL_MSG_MAX_LEN);
47
    return -1;
48
  }
49

    
50
  message_length = msg_len;
51

    
52
  listener_addr = listener_address;
53

    
54
  rtc_init(PRESCALE_DIV_128, 64, &wl_timeout_handler); 
55
  /* executes the function about every 1/4 sec */
56

    
57
  //wl_to_flag = 0;
58
  //wl_to_count = 0; 
59
        
60
  UCSR0B |= _BV(RXCIE) | _BV(RXEN);
61
  
62
  sei();
63

    
64
  new_message = 0;
65
  memset(&latest_packet, 0, sizeof(WL_Packet));
66

    
67
  return 0;
68
}
69

    
70
int wl_send(char* msg, char dest){
71
  int i = 0;
72
  WL_Packet packet;
73

    
74
  if(strlen(msg) > WL_MSG_MAX_LEN){
75
    printf("Error: %s: message is too long\n", __FUNCTION__);
76
    return -1;
77
  }
78

    
79
  wl_create_packet(msg, listener_addr, dest, &packet);
80

    
81
  serial_putchar(packet.prefix[0]);
82
  serial_putchar(packet.prefix[1]);
83
  serial_putchar(packet.src);
84
  serial_putchar(packet.dest);
85

    
86
  for(i = 0; i < message_length; i++){
87
    serial_putchar(packet.msg[i]);
88
  }
89

    
90
  serial_putchar(packet.checksum);
91

    
92
  return 0;
93
}
94

    
95
int wl_recv(char* msgbuf, char* src, char* dest){
96
  if(!new_message){
97
    return 0; //no new message
98
  }
99

    
100
  strcpy(msgbuf, latest_packet.msg);
101

    
102
  *src = latest_packet.src;
103
  *dest = latest_packet.dest;
104
  
105
  new_message = 0;
106

    
107
  return strlen(msgbuf);
108
}
109

    
110
char wl_get_checksum(WL_Packet* packet){
111
  char checksum = 0;
112
  int i;
113

    
114
  checksum += packet->src;
115
  checksum += packet->dest;
116
  for(i = 0; i < message_length; i++) {
117
    checksum += packet->msg[i];
118
  }
119

    
120
  return checksum;
121
}
122

    
123
int wl_create_packet(char* msg, char src, char dest, WL_Packet* packet){
124
  packet->prefix[0] = 'R';
125
  packet->prefix[1] = 'C';
126

    
127
  packet->src = src;
128
  packet->dest = dest;
129

    
130
  memset(packet->msg, 0, message_length);
131
  strcpy(packet->msg, msg);
132

    
133
  packet->checksum = wl_get_checksum(packet);
134

    
135
  return 0;
136
}
137

    
138
/* Internal function definitions */
139

    
140
//use on new avr-libc
141
//ISR(USART0_RX_vect)
142
SIGNAL(SIG_USART0_RECV){
143
  char wl_input = UDR0;
144
  static unsigned int wl_index = 0;
145
  static unsigned char wl_chksum = 0;
146

    
147
  if(wl_index == 0){
148
    //first packet? - check chksum to make sure we're not beginning
149
    if(wl_input == PREFIX0) {
150
      wl_to_count = 0; //at this point we're not timing out
151
      wl_index = 1;
152
    }
153
  }else if(wl_index == 1){
154
    if(wl_input != PREFIX1){
155
      wl_index = 0;
156
    }else{
157
      wl_index = WL_SRC_LOC;
158
    }
159
  }else if(wl_index == WL_SRC_LOC){
160
    tmp_packet.src = wl_input;
161
    wl_index = WL_DEST_LOC;
162
  }else if(wl_index == WL_DEST_LOC){
163
    tmp_packet.dest = wl_input;
164
    wl_index = WL_DATA_START;
165
  }else if(wl_index < WL_DATA_START + message_length){
166
    //getting the rest of the packet
167
    tmp_packet.msg[wl_index-WL_DATA_START] = wl_input;
168
    wl_index++;
169
  }else if(wl_index == WL_DATA_START + message_length){
170
    //we are at checksum location
171
    tmp_packet.checksum = wl_input;
172
    wl_chksum = wl_get_checksum(&tmp_packet);
173
    
174
    if(tmp_packet.checksum == wl_chksum) {
175
      //checksum is correct
176
      memcpy(&latest_packet, &tmp_packet, sizeof(WL_Packet));
177
      new_message = 1;
178
    } else { //chksum failed
179
      serial1_putchar('F');
180
      lcd_putchar('F');
181
      
182
      printf("checksum failed - was %d, should have been %d\n", wl_input, 
183
             wl_chksum);
184
    }
185

    
186
    wl_index = 0;
187
  }
188
}
189

    
190

    
191
/*
192
  \fn wl_timeout_handler
193
  Handles the timeout case.
194

195
  A time out occurs about every 1/4 second.  This function is called each time 
196
  one occurs. In the case where a robot first turns on, it will wait for a long
197
  time before declaring itself the leader.  Otherwise, if enough time-outs 
198
  occur in a row, wl_to_flag will be set to 1.  This will cause a timeout 
199
  packet to be sent next time around
200

201
*/
202
static void wl_timeout_handler( void ) {
203
  //increment the total number of wireless time-outs
204
  wl_to_count++;
205
  
206
  static int wl_first_to_count =  0;
207
  static int first_time = 1;
208

    
209
  //first time time out routine - listen for a long time
210
  if(first_time) {
211
    if(wl_to_count > WL_TIMEOUT_INITIAL) {
212
      //increment the counter for first timeouts
213
      wl_first_to_count++;
214
      
215
      //you don't actually want to send out a packet 
216
      //-- you would confuse other robots
217
      wl_to_flag = 0;
218
      wl_to_count = 0;
219
    }
220

    
221
    first_time = 0;
222
  } else {
223
    //not the first time - regular time out routine
224
    //if you have enough timeouts
225
    if(wl_to_count > WL_TIMEOUT) {
226
      //lcd_putchar('z');
227
                        
228
      //change the time-out flag to 1
229
      wl_to_flag = 1;
230
      wl_to_count = 0;
231
    }
232
  }
233
}