00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <stdio.h>
00011 #include <unistd.h>
00012 #include <stdlib.h>
00013 #include <errno.h>
00014 #include <string.h>
00015 #include <sys/time.h>
00016 #include <sys/neutrino.h>
00017 #include <sys/iofunc.h>
00018 #include <sys/dispatch.h>
00019 #include <sys/mman.h>
00020 #include <hw/pci.h>
00021
00022 #define min(a, b) ((a) < (b) ? (a) : (b))
00023
00024 int io_read(resmgr_context_t * ctp, io_read_t * msg, RESMGR_OCB_T * ocb);
00025 static char *buffer = (char *) "Hello world\n";
00026
00027 void wait_t(void);
00028
00029 #include "QNX101/jr3pci3.idm"
00030
00031 #define VENDORID 0x1762
00032
00033
00034 #define DEVICEID 0x3112
00035
00036
00037 #define Jr3ResetAddr 0x18000
00038 #define Jr3NoAddrMask 0x40000
00039 #define Jr3DmAddrMask 0x6000
00040 unsigned long MappedAddress;
00041
00042
00043 #define ToJr3PciAddrH(addr) (((int)(addr) << 2) + Jr3BaseAddressH)
00044 #define ToJr3PciAddrL(addr) (((int)(addr) << 2) + Jr3BaseAddressL)
00045
00046
00047 #define ReadJr3Pm(addr) (*(uint16_t volatile *)(ToJr3PciAddrH((addr))) << 8 |\
00048 *(uint8_t volatile *)(ToJr3PciAddrL((addr))))
00049
00050 #define WriteJr3Pm2(addr,data,data2) (*(int volatile *)ToJr3PciAddrH((addr)) = (int)(data));(*(int volatile *)ToJr3PciAddrL((addr)) = (int)(data2))
00051
00052 #define WriteJr3Pm(addr,data) WriteJr3Pm2((addr),(data) >> 8, (data))
00053
00054
00055 #define ReadJr3Dm(addr) (*(uint16_t volatile *)(ToJr3PciAddrH((addr))))
00056 #define WriteJr3Dm(addr,data) *(int volatile *)(ToJr3PciAddrH((addr))) = (int)(data)
00057
00058
00059 #define ReadJr3(addr) (ReadJr3Dm((addr) | Jr3DmAddrMask))
00060 #define WriteJr3(addr,data) WriteJr3Dm((addr) | Jr3DmAddrMask,data)
00061
00062 static resmgr_connect_funcs_t ConnectFuncs;
00063 static resmgr_io_funcs_t IoFuncs;
00064 static iofunc_attr_t IoFuncAttr;
00065
00066
00067 volatile uint32_t Jr3BaseAddressH;
00068 volatile uint32_t Jr3BaseAddressL;
00069 volatile uint32_t Jr3BaseAddress0H;
00070 volatile uint32_t Jr3BaseAddress0L;
00071 volatile uint32_t Jr3BaseAddress1H;
00072 volatile uint32_t Jr3BaseAddress1L;
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 struct raw_channel {
00083 uint16_t raw_time;
00084 uint16_t dummy1;
00085 int16_t raw_data;
00086 int16_t dummy2;
00087 int16_t reserved[2];
00088 int16_t dummy3[2];
00089 };
00090
00091 struct force_array {
00092 int16_t fx;
00093 int16_t dummy1;
00094 int16_t fy;
00095 int16_t dummy2;
00096 int16_t fz;
00097 int16_t dummy3;
00098 int16_t mx;
00099 int16_t dummy4;
00100 int16_t my;
00101 int16_t dummy5;
00102 int16_t mz;
00103 int16_t dummy6;
00104 int16_t v1;
00105 int16_t dummy7;
00106 int16_t v2;
00107 int16_t dummy8;
00108 };
00109
00110 struct six_axis_array {
00111 int16_t fx;
00112 int16_t dummy1;
00113 int16_t fy;
00114 int16_t dummy2;
00115 int16_t fz;
00116 int16_t dummy3;
00117 int16_t mx;
00118 int16_t dummy4;
00119 int16_t my;
00120 int16_t dummy5;
00121 int16_t mz;
00122 int16_t dummy6;
00123 };
00124
00125 struct vect_bits {
00126 uint8_t fx :1;
00127 uint8_t fy :1;
00128 uint8_t fz :1;
00129 uint8_t mx :1;
00130 uint8_t my :1;
00131 uint8_t mz :1;
00132 uint8_t changedV1 :1;
00133 uint8_t changedV2 :1;
00134 int16_t dummy;
00135 };
00136
00137 struct warning_bits {
00138 uint8_t fx_near_set :1;
00139 uint8_t fy_near_set :1;
00140 uint8_t fz_near_set :1;
00141 uint8_t mx_near_set :1;
00142 uint8_t my_near_set :1;
00143 uint8_t mz_near_set :1;
00144 uint8_t reserved :8;
00145
00146 int16_t dummy;
00147 };
00148
00149 struct error_bits {
00150 uint8_t fx_sat :1;
00151 uint8_t fy_sat :1;
00152 uint8_t fz_sat :1;
00153 uint8_t mx_sat :1;
00154 uint8_t my_sat :1;
00155 uint8_t mz_sat :1;
00156 uint8_t researved :2;
00157
00158 uint8_t memry_error :1;
00159 uint8_t sensor_charge :1;
00160 uint8_t system_busy :1;
00161 uint8_t cal_crc_bad :1;
00162 uint8_t watch_dog2 :1;
00163 uint8_t watch_dog :1;
00164 int16_t dummy1;
00165 };
00166
00167 char *force_units_str[] =
00168 { (char *) "pound, inch*pound, inch*1000",
00169
00170 (char *) "Newton, Newton*meter*10, mm*10",
00171 (char *) "kilogram-force*10, kilogram-Force*cm, mm*10",
00172 (char *) "kilopound, kiloinch*pound, inch*1000" };
00173
00174 enum force_units {
00175 lbs_in_lbs_mils,
00176 N_dNm_mm10,
00177 kgf10_kgFcm_mm10,
00178 klbs_kin_lbs_mils,
00179 reserved_units_4,
00180 reserved_units_5,
00181 reserved_units_6,
00182 reserved_units_7
00183 };
00184
00185 struct thresh_struct {
00186 int16_t data_address;
00187 int16_t dummy1;
00188 int16_t threshold;
00189 int16_t dummy2;
00190 int16_t bit_pattern;
00191 int16_t dummy3;
00192 };
00193
00194 struct le_struct {
00195 int16_t latch_bits;
00196 int16_t dummy1;
00197 int16_t number_of_ge_thresholds;
00198 int16_t dummy2;
00199 int16_t number_of_le_thresholds;
00200 int16_t dummy3;
00201 thresh_struct thresholds[4];
00202 int16_t reserved;
00203 int16_t dummy4;
00204 };
00205
00206 enum link_types {
00207 end_x_form, tx, ty, tz, rx, ry, rz, neg
00208 };
00209
00210 struct links {
00211 link_types link_type;
00212 int16_t dummy1;
00213 int16_t link_amount;
00214 int16_t dummy2;
00215 };
00216
00217 struct transform {
00218 links link[8];
00219 };
00220
00221
00222 struct force_sensor_data {
00223 raw_channel raw_channels[16];
00224 char copyright[0x18 * 4];
00225 int16_t reserved1[0x08 * 2];
00226 six_axis_array shunts;
00227 int16_t reserved2[2];
00228 int16_t dummy1[2];
00229 six_axis_array default_FS;
00230 int16_t reserved3;
00231 int16_t dummy2;
00232 int16_t load_envelope_num;
00233 int16_t dummy3;
00234 six_axis_array min_full_scale;
00235 int16_t reserved4;
00236 int16_t dummy4;
00237 int16_t transform_num;
00238 int16_t dummy5;
00239 six_axis_array max_full_scale;
00240 int16_t reserved5;
00241 int16_t dummy6;
00242 int16_t peak_address;
00243 int16_t dummy7;
00244 force_array full_scale;
00245 six_axis_array offsets;
00246 int16_t offset_num;
00247 int16_t dummy8;
00248 vect_bits vect_axes;
00249 force_array filter0;
00250 force_array filter1;
00251 force_array filter2;
00252 force_array filter3;
00253 force_array filter4;
00254 force_array filter5;
00255 force_array filter6;
00256 force_array rate_data;
00257 force_array minimum_data;
00258 force_array maximum_data;
00259 int16_t near_sat_value;
00260 int16_t dummy9;
00261 int16_t sat_value;
00262 int16_t dummy10;
00263 int16_t rate_address;
00264 int16_t dummy11;
00265 uint16_t rate_divisor;
00266 uint16_t dummy12;
00267 uint16_t rate_count;
00268 uint16_t dummy13;
00269 int16_t command_word2;
00270 int16_t dummy14;
00271 int16_t command_word1;
00272 int16_t dummy15;
00273 int16_t command_word0;
00274 uint16_t dummy16;
00275 uint16_t count1;
00276 uint16_t dummy17;
00277 uint16_t count2;
00278 uint16_t dummy18;
00279 uint16_t count3;
00280 uint16_t dummy19;
00281 uint16_t count4;
00282 uint16_t dummy20;
00283 uint16_t count5;
00284 uint16_t dummy21;
00285 uint16_t count6;
00286 uint16_t dummy22;
00287 uint16_t error_count;
00288 uint16_t dummy23;
00289 uint16_t count_x;
00290 uint16_t dummy24;
00291 warning_bits warnings;
00292 error_bits errors;
00293 int16_t threshold_bits;
00294 int16_t dummy25;
00295 int16_t last_crc;
00296 int16_t dummy26;
00297 int16_t eeprom_ver_no;
00298 int16_t dummy27;
00299 int16_t software_ver_no;
00300 int16_t dummy28;
00301 int16_t software_day;
00302 int16_t dummy29;
00303 int16_t software_year;
00304 int16_t dummy30;
00305 uint16_t serial_no;
00306 uint16_t dummy31;
00307 uint16_t model_no;
00308 uint16_t dummy32;
00309 int16_t cal_day;
00310 int16_t dummy33;
00311 int16_t cal_year;
00312 int16_t dummy34;
00313 force_units units;
00314 int16_t bit;
00315 int16_t dummy35;
00316 int16_t channels;
00317 int16_t dummy36;
00318 int16_t thickness;
00319 int16_t dummy37;
00320 le_struct load_envelopes[0x10];
00321 transform transforms[0x10];
00322 };
00323
00324 typedef struct {
00325 uint16_t msg_no;
00326 char msg_data[255];
00327 } server_msg_t;
00328
00329 int download(unsigned int base0, unsigned int base1) {
00330 printf("Download %x %x\n", base0, base1);
00331
00332 int count;
00333 int index = 0;
00334 unsigned int Jr3BaseAddressH;
00335 unsigned int Jr3BaseAddressL;
00336
00337 Jr3BaseAddressH = base0;
00338 Jr3BaseAddressL = base1;
00339
00340
00341 count = dsp[index++];
00342
00343
00344 while (count != 0xffff) {
00345 int addr;
00346
00347
00348 addr = dsp[index++];
00349
00350
00351 while (count > 0) {
00352
00353 if (addr & 0x4000) {
00354 int data = 0;
00355
00356
00357 data = dsp[index++];
00358 WriteJr3Dm(addr, data);
00359 count--;
00360 if (data != ReadJr3Dm(addr)) {
00361 printf("data addr: %4.4x out: %4.4x in: %4.4x\n", addr,
00362 data, ReadJr3Dm(addr));
00363 }
00364 } else {
00365 int data, data2;
00366 int data3;
00367
00368
00369 data = dsp[index++];
00370 data2 = dsp[index++];
00371 WriteJr3Pm2(addr, data, data2);
00372 count -= 2;
00373
00374
00375 if (((data << 8) | (data2 & 0xff))
00376 != (data3 = ReadJr3Pm(addr))) {
00377
00378 }
00379 }
00380 addr++;
00381 }
00382 count = dsp[index++];
00383 }
00384
00385 return 0;
00386
00387 }
00388
00389 void get_force_sensor_info(force_sensor_data * data, char *msg) {
00390 struct tm t1, *soft_day, *cal_day;
00391 ;
00392 time_t t2;
00393 t1.tm_sec = t1.tm_min = t1.tm_hour = 0;
00394 t1.tm_isdst = -1;
00395 t1.tm_mon = 0;
00396 t1.tm_year = data->software_year - 1900;
00397 t1.tm_mday = data->software_day;
00398 t2 = mktime(&t1);
00399 soft_day = localtime(&t2);
00400 t1.tm_sec = t1.tm_min = t1.tm_hour = 0;
00401 t1.tm_isdst = -1;
00402 t1.tm_mon = 0;
00403 t1.tm_year = data->cal_year - 1900;
00404 t1.tm_mday = data->cal_day;
00405 t2 = mktime(&t1);
00406 cal_day = localtime(&t2);
00407 snprintf(msg, 128, "rom # %d, soft # %d, %d/%d/%d\n"
00408 "serial # %d, model # %d, cal day %d/%d/%d\n"
00409 "%s, %d bits, %d ch\n"
00410 "(C) %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c\n\n",
00411 data->eeprom_ver_no, data->software_ver_no, soft_day->tm_mday,
00412 soft_day->tm_mon + 1, soft_day->tm_year + 1900, data->serial_no,
00413 data->model_no, cal_day->tm_mday, cal_day->tm_mon + 1,
00414 cal_day->tm_year + 1900, force_units_str[1], data->bit,
00415 data->channels, data->copyright[0 * 4 + 1],
00416 data->copyright[1 * 4 + 1], data->copyright[2 * 4 + 1],
00417 data->copyright[3 * 4 + 1], data->copyright[4 * 4 + 1],
00418 data->copyright[5 * 4 + 1], data->copyright[6 * 4 + 1],
00419 data->copyright[7 * 4 + 1], data->copyright[8 * 4 + 1],
00420 data->copyright[9 * 4 + 1], data->copyright[10 * 4 + 1],
00421 data->copyright[11 * 4 + 1], data->copyright[12 * 4 + 1],
00422 data->copyright[13 * 4 + 1], data->copyright[14 * 4 + 1],
00423 data->copyright[15 * 4 + 1], data->copyright[16 * 4 + 1],
00424 data->copyright[17 * 4 + 1], data->copyright[18 * 4 + 1],
00425 data->copyright[19 * 4 + 1], data->copyright[20 * 4 + 1],
00426 data->copyright[21 * 4 + 1], data->copyright[22 * 4 + 1],
00427 data->copyright[23 * 4 + 1]);
00428 }
00429
00430 int message_callback(message_context_t * ctp, int type, unsigned flags,
00431 void *handle) {
00432 server_msg_t *msg;
00433 int num;
00434 char msg_reply[255];
00435
00436
00437 msg = (server_msg_t *) ctp->msg;
00438
00439
00440
00441
00442
00443 force_sensor_data *data_0;
00444 force_sensor_data *data_1;
00445 data_0 = (force_sensor_data *) (Jr3BaseAddress0H + (Jr3DmAddrMask << 2));
00446 data_1 = (force_sensor_data *) (Jr3BaseAddress1H + (Jr3DmAddrMask << 2));
00447
00448
00449 num = type - _IO_MAX;
00450 switch (num) {
00451 case 1:
00452 {
00453 float tmp[12] = { -1.0 * (float) data_0->filter0.fx
00454 / (float) data_0->full_scale.fx, -1.0
00455 * (float) data_0->filter0.fy / (float) data_0->full_scale.fy,
00456 -1.0 * (float) data_0->filter0.fz
00457 / (float) data_0->full_scale.fz, -1.0
00458 * (float) data_0->filter0.mx
00459 / (float) data_0->full_scale.mx * 0.1,
00460 -1.0 * (float) data_0->filter0.my
00461 / (float) data_0->full_scale.my * 0.1, -1.0
00462 * (float) data_0->filter0.mz
00463 / (float) data_0->full_scale.mz * 0.1, -1.0
00464 * (float) data_1->filter0.fx
00465 / (float) data_1->full_scale.fx, -1.0
00466 * (float) data_1->filter0.fy
00467 / (float) data_1->full_scale.fy, -1.0
00468 * (float) data_1->filter0.fz
00469 / (float) data_1->full_scale.fz, -1.0
00470 * (float) data_1->filter0.mx
00471 / (float) data_1->full_scale.mx * 0.1, -1.0
00472 * (float) data_1->filter0.my
00473 / (float) data_1->full_scale.my * 0.1, -1.0
00474 * (float) data_1->filter0.mz
00475 / (float) data_1->full_scale.mz * 0.1 };
00476 memcpy(msg_reply, tmp, sizeof(float) * 12);
00477 }
00478 break;
00479 case 2:
00480 data_0->offsets.fx += data_0->filter0.fx;
00481 data_0->offsets.fy += data_0->filter0.fy;
00482 data_0->offsets.fz += data_0->filter0.fz;
00483 data_0->offsets.mx += data_0->filter0.mx;
00484 data_0->offsets.my += data_0->filter0.my;
00485 data_0->offsets.mz += data_0->filter0.mz;
00486 data_1->offsets.fx += data_1->filter0.fx;
00487 data_1->offsets.fy += data_1->filter0.fy;
00488 data_1->offsets.fz += data_1->filter0.fz;
00489 data_1->offsets.mx += data_1->filter0.mx;
00490 data_1->offsets.my += data_1->filter0.my;
00491 data_1->offsets.mz += data_1->filter0.mz;
00492 break;
00493 case 3:
00494 break;
00495 case 4:
00496 get_force_sensor_info(data_0, msg_reply);
00497 get_force_sensor_info(data_1, msg_reply + strlen(msg_reply));
00498 break;
00499 }
00500
00501
00502 MsgReply(ctp->rcvid, EOK, msg_reply, 256);
00503 return 0;
00504 }
00505
00506 int main(int argc, char **argv) {
00507 resmgr_attr_t resmgr_attr;
00508 message_attr_t message_attr;
00509 dispatch_t *dpp;
00510 dispatch_context_t *ctp, *ctp_ret;
00511 int resmgr_id, message_id;
00512
00513
00514 dpp = dispatch_create();
00515 if (dpp == NULL) {
00516 fprintf(stderr, "dispatch_create() failed: %s\n", strerror(errno));
00517 return EXIT_FAILURE;
00518 }
00519
00520 memset(&resmgr_attr, 0, sizeof(resmgr_attr));
00521 resmgr_attr.nparts_max = 1;
00522 resmgr_attr.msg_max_size = 2048;
00523
00524
00525 iofunc_func_init(_RESMGR_CONNECT_NFUNCS, &ConnectFuncs, _RESMGR_IO_NFUNCS,
00526 &IoFuncs);
00527
00528 IoFuncs.read = io_read;
00529
00530
00531 iofunc_attr_init(&IoFuncAttr, S_IFNAM | 0666, 0, 0);
00532 IoFuncAttr.nbytes = strlen(buffer) + 1;
00533
00534 resmgr_id = resmgr_attach(dpp, &resmgr_attr, "/dev/jr3q", _FTYPE_ANY, 0,
00535 &ConnectFuncs, &IoFuncs, &IoFuncAttr);
00536 if (resmgr_id == -1) {
00537 fprintf(stderr, "resmgr_attach() failed: %s\n", strerror(errno));
00538 return EXIT_FAILURE;
00539 }
00540
00541
00542 unsigned int flags = 0;
00543 unsigned bus, function, index = 0;
00544 unsigned devid, venid;
00545 int result;
00546 unsigned lastbus, version, hardware;
00547 unsigned int address0;
00548 void *bufptr;
00549 unsigned int addr;
00550
00551 pci_attach(flags);
00552 result = pci_present(&lastbus, &version, &hardware);
00553 if (result == -1) {
00554 printf("PCI BIOS not present!\n");
00555 }
00556 devid = DEVICEID;
00557 venid = VENDORID;
00558 result = pci_find_device(devid, venid, index, &bus, &function);
00559 printf("result PCI %d\n", result);
00560 printf("bus %d\n", bus);
00561 printf("function %d\n", function);
00562 pci_read_config_bus(bus, function, 0x10, 1, sizeof(unsigned int), bufptr);
00563
00564 address0 = *(unsigned int *) bufptr;
00565 buffer = (char *) bufptr;
00566 printf("Board addr 0x%x\n", *(unsigned int *) buffer);
00567
00568 Jr3BaseAddress0H = (volatile uint32_t) mmap_device_memory(NULL, 0x100000,
00569 PROT_READ | PROT_WRITE | PROT_NOCACHE, 0, address0);
00570 Jr3BaseAddress0L = (volatile uint32_t) mmap_device_memory(NULL, 0x100000,
00571 PROT_READ | PROT_WRITE | PROT_NOCACHE, 0, address0 + Jr3NoAddrMask);
00572 Jr3BaseAddressH = (volatile uint32_t) mmap_device_memory(NULL, 0x100000,
00573 PROT_READ | PROT_WRITE | PROT_NOCACHE, 0, address0);
00574 WriteJr3Dm(Jr3ResetAddr, 0);
00575 wait_t();
00576 download(Jr3BaseAddress0H, Jr3BaseAddress0L);
00577 wait_t();
00578
00579 Jr3BaseAddress1H = (volatile uint32_t) mmap_device_memory(NULL, 0x100000,
00580 PROT_READ | PROT_WRITE | PROT_NOCACHE, 0, address0 + 0x80000);
00581 Jr3BaseAddress1L = (volatile uint32_t) mmap_device_memory(NULL, 0x100000,
00582 PROT_READ | PROT_WRITE | PROT_NOCACHE, 0, address0 + 0x80000 +
00583 Jr3NoAddrMask);
00584 download(Jr3BaseAddress1H, Jr3BaseAddress1L);
00585 wait_t();
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599 *(uint16_t *) (Jr3BaseAddress0H + ((0x0200 | Jr3DmAddrMask) << 2)) =
00600 (uint16_t) 0;
00601 *(uint16_t *) (Jr3BaseAddress0H + ((0x00e7 | Jr3DmAddrMask) << 2)) =
00602 (uint16_t) 0x0500;
00603
00604
00605 memset(&message_attr, 0, sizeof(message_attr));
00606 message_attr.nparts_max = 1;
00607 message_attr.msg_max_size = 4096;
00608
00609
00610 message_id = message_attach(dpp, &message_attr, _IO_MAX + 1, _IO_MAX + 10,
00611 message_callback, NULL);
00612 if (message_id == -1) {
00613 fprintf(stderr, "message_attach() failed: %s\n", strerror(errno));
00614 return EXIT_FAILURE;
00615 }
00616
00617
00618 ctp = dispatch_context_alloc(dpp);
00619 if (ctp == NULL) {
00620 fprintf(stderr, "dispatch_context_alloc() failed: %s\n",
00621 strerror(errno));
00622 return EXIT_FAILURE;
00623 }
00624
00625
00626 while (1) {
00627 ctp_ret = dispatch_block(ctp);
00628 if (ctp_ret) {
00629 dispatch_handler(ctp);
00630 } else {
00631 fprintf(stderr, "dispatch_block() failed: %s\n", strerror(errno));
00632 return EXIT_FAILURE;
00633 }
00634 }
00635
00636 return EXIT_SUCCESS;
00637 }
00638
00639 int io_read(resmgr_context_t * ctp, io_read_t * msg, RESMGR_OCB_T * ocb) {
00640 int nleft;
00641 int nbytes;
00642 int nparts;
00643 int status;
00644
00645 if ((status = iofunc_read_verify(ctp, msg, ocb, NULL)) != EOK)
00646 return (status);
00647
00648 if ((msg->i.xtype & _IO_XTYPE_MASK) != _IO_XTYPE_NONE)
00649 return (ENOSYS);
00650
00651
00652
00653
00654
00655
00656
00657
00658 nleft = ocb->attr->nbytes - ocb->offset;
00659 nbytes = min(msg->i.nbytes, nleft);
00660
00661 if (nbytes > 0) {
00662
00663 SETIOV(ctp->iov, buffer + ocb->offset, nbytes);
00664
00665
00666 _IO_SET_READ_NBYTES(ctp, nbytes);
00667
00668
00669
00670
00671
00672
00673 ocb->offset += nbytes;
00674 nparts = 1;
00675 } else {
00676
00677
00678
00679
00680 _IO_SET_READ_NBYTES(ctp, 0);
00681 nparts = 0;
00682 }
00683
00684
00685
00686 if (msg->i.nbytes > 0)
00687 ocb->attr->flags |= IOFUNC_ATTR_ATIME;
00688
00689 return (_RESMGR_NPARTS(nparts));
00690
00691 }
00692
00693 void wait_t(void) {
00694 struct timeval tv, tv1;
00695
00696 gettimeofday(&tv1, NULL);
00697
00698 do {
00699 gettimeofday(&tv, NULL);
00700 } while (tv.tv_sec - tv1.tv_sec < 3);
00701
00702 return;
00703 }