Project

General

Profile

Statistics
| Revision:

root / branches / library_refactor / projects / colonet / server / manual_control / manualControlRobot / wireless.c @ 1390

History | View | Annotate | Download (5.64 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 char wl_buf[WL_PACKET_MAX_LEN];
29
static WL_Packet latest_packet;
30
static WL_Packet tmp_packet;
31
static char new_message;
32
static char listener_addr;
33

    
34
static int message_length;
35

    
36
static unsigned int wl_index;
37
static unsigned char wl_chksum;
38
static unsigned char wl_to_flag;
39
static unsigned int wl_to_count;
40

    
41
static unsigned int wl_to_max;
42

    
43
static char first_time;
44

    
45
/* Internal function headers */
46
static void wl_timeout_handler(void);
47

    
48
/* External function definitions */
49
int wl_init(int msg_len, char listener_address){
50
  if(msg_len > WL_MSG_MAX_LEN){
51
    printf("Error: %s: message length must be less than %d\n", __FUNCTION__, 
52
           WL_MSG_MAX_LEN);
53
    return -1;
54
  }
55

    
56
  message_length = msg_len;
57

    
58
  listener_addr = listener_address;
59

    
60
  wl_index = 0;
61
  wl_chksum = 1;
62
  
63
  rtc_init(PRESCALE_DIV_128, 64, &wl_timeout_handler); 
64
  /* executes the function about every 1/4 sec */
65

    
66
  wl_to_flag = 0;
67
  wl_to_count = 0; 
68

    
69
  first_time = 1;
70
        
71
  UCSR0B |= _BV(RXCIE) | _BV(RXEN);
72
  
73
  sei();
74

    
75
  new_message = 0;
76
  memset(&latest_packet, 0, sizeof(WL_Packet));
77

    
78
  return 0;
79
}
80

    
81
int wl_send(char* msg, char dest){
82
  int i = 0;
83
  WL_Packet packet;
84

    
85
  if(strlen(msg) > WL_MSG_MAX_LEN){
86
    printf("Error: %s: message is too long\n", __FUNCTION__);
87
    return -1;
88
  }
89

    
90
  wl_create_packet(msg, listener_addr, dest, &packet);
91

    
92
  serial_putchar(packet.prefix[0]);
93
  serial_putchar(packet.prefix[1]);
94
  serial_putchar(packet.src);
95
  serial_putchar(packet.dest);
96

    
97
  for(i = 0; i < message_length; i++){
98
    serial_putchar(packet.msg[i]);
99
  }
100

    
101
  serial_putchar(packet.checksum);
102

    
103
  //printf("%x %x %x %x", packet.prefix[0], packet.prefix[1], packet.src, 
104
  //         packet.dest);
105

    
106
  return 0;
107
}
108

    
109
int wl_recv(char* msgbuf, char* src, char* dest){
110
  if(!new_message){
111
    return 0; //no new message
112
  }
113

    
114
  strcpy(msgbuf, latest_packet.msg);
115

    
116
  *src = latest_packet.src;
117
  *dest = latest_packet.dest;
118
  
119
  new_message = 0;
120

    
121
  return strlen(msgbuf);
122
}
123

    
124
char wl_get_checksum(WL_Packet* packet){
125
  char checksum = 0;
126
  int i;
127

    
128
  checksum += packet->src;
129
  checksum += packet->dest;
130
  for(i = 0; i < message_length; i++) {
131
    checksum += packet->msg[i];
132
  }
133

    
134
  return checksum;
135
}
136

    
137
int wl_create_packet(char* msg, char src, char dest, WL_Packet* packet){
138
  packet->prefix[0] = 'R';
139
  packet->prefix[1] = 'C';
140

    
141
  packet->src = src;
142
  packet->dest = dest;
143

    
144
  memset(packet->msg, 0, message_length);
145
  strcpy(packet->msg, msg);
146

    
147
  packet->checksum = wl_get_checksum(packet);
148

    
149
  return 0;
150
}
151

    
152
/* Internal function definitions */
153

    
154
//use on new avr-libc
155
//ISR(USART0_RX_vect)
156
SIGNAL(SIG_USART0_RECV){
157
  char wl_input = UDR0;
158

    
159
  /* LOCAL HACK!!! */
160
  //orb_set_color(ORANGE);
161
  //printf("%x ", wl_input);
162
  lcd_putint(wl_input);
163

    
164
  if(wl_index == 0){
165
    //first packet? - check chksum to make sure we're not beginning
166
    if(wl_input == PREFIX0) {
167
      wl_to_count = 0; //at this point we're not timing out
168
      wl_index = 1;
169
    }
170
  }else if(wl_index == 1){
171
    if(wl_input != PREFIX1){
172
      wl_index = 0;
173
    }else{
174
      wl_index = WL_SRC_LOC;
175
    }
176
  }else if(wl_index == WL_SRC_LOC){
177
    tmp_packet.src = wl_input;
178
    wl_index = WL_DEST_LOC;
179
  }else if(wl_index == WL_DEST_LOC){
180
    tmp_packet.dest = wl_input;
181
    wl_index = WL_DATA_START;
182
  }else if(wl_index < WL_DATA_START + message_length){
183
    //getting the rest of the packet
184
    tmp_packet.msg[wl_index-WL_DATA_START] = wl_input;
185
    wl_index++;
186
    
187
    //printf("%d: %d; %d\n", wl_index, wl_input, wl_chksum);
188
  }else if(wl_index == WL_DATA_START + message_length){
189
    //we are at checksum location
190
    tmp_packet.checksum = wl_input;
191
    wl_chksum = wl_get_checksum(&tmp_packet);
192
    
193
    if(tmp_packet.checksum == wl_chksum) {
194
      //checksum is correct
195
      memcpy(&latest_packet, &tmp_packet, sizeof(WL_Packet));
196
      new_message = 1;
197
    } else { //chksum failed
198
      serial1_putchar('F');
199
      lcd_putchar('F');
200
      
201
      printf("checksum failed - was %d, should have been %d\n", wl_input, 
202
             wl_chksum);
203
    }
204

    
205
    wl_index = 0;
206
  }
207
}
208

    
209

    
210
/*
211
  \fn wl_timeout_handler
212
  Handles the timeout case.
213

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

219
*/
220
static void wl_timeout_handler( void ) {
221
  //increment the total number of wireless time-outs
222
  wl_to_count++;
223
  
224
  static int wl_first_to_count =  0;
225
  
226
  //first time time out routine - listen for a long time
227
  if(first_time) {
228
    if(wl_to_count > WL_TIMEOUT_INITIAL) {
229
      //increment the counter for first timeouts
230
      wl_first_to_count++;
231
      
232
      //you don't actually want to send out a packet 
233
      //-- you would confuse other robots
234
      wl_to_flag = 0;
235
      wl_to_count = 0;
236
    }
237
  } else {
238
    //not the first time - regular time out routine
239
    //if you have enough timeouts
240
    if(wl_to_count > WL_TIMEOUT) {
241
      //lcd_putchar('z');
242
                        
243
      //change the time-out flag to 1
244
      wl_to_flag = 1;
245
      wl_to_count = 0;
246
    }
247
  }
248
}