Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

VrGuppiSource.h

Go to the documentation of this file.
00001 /* -*- Mode: c++ -*- */
00002 /*
00003  * Copyright 2001 Free Software Foundation, Inc.
00004  * 
00005  * This file is part of GNU Radio
00006  * 
00007  * GNU Radio is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2, or (at your option)
00010  * any later version.
00011  * 
00012  * GNU Radio is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  * 
00017  * You should have received a copy of the GNU General Public License
00018  * along with GNU Radio; see the file COPYING.  If not, write to
00019  * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00020  * Boston, MA 02111-1307, USA.
00021  */
00022 /*
00023  *  Copyright 1997 Massachusetts Institute of Technology
00024  * 
00025  *  Permission to use, copy, modify, distribute, and sell this software and its
00026  *  documentation for any purpose is hereby granted without fee, provided that
00027  *  the above copyright notice appear in all copies and that both that
00028  *  copyright notice and this permission notice appear in supporting
00029  *  documentation, and that the name of M.I.T. not be used in advertising or
00030  *  publicity pertaining to distribution of the software without specific,
00031  *  written prior permission.  M.I.T. makes no representations about the
00032  *  suitability of this software for any purpose.  It is provided "as is"
00033  *  without express or implied warranty.
00034  * 
00035  */
00036 
00037 #ifndef _VRGUPPISOURCE_H_
00038 #define _VRGUPPISOURCE_H_
00039 
00040 extern "C" {
00041 #include <sys/ioctl.h>
00042 #include <fcntl.h>
00043 #include <errno.h>
00044 }
00045 
00046 #include <VrSource.h>
00047 #include <VrGuppiBuffer.h>
00048 #include <guppi.h>
00049 
00050 template<class oType> 
00051 class VrGuppiSource: public VrSource<oType> {
00052 protected:
00053   int gupfd; 
00054   //the guppi driver page index corresponding to WP (or ts after sync in work)
00055   //(the NEXT block the guppi will give us)
00056   int currentIndex;
00057   int minIndex; //the smallest guppi driver block we are using
00058   //if minIndex == currentIndex we aren't using any blocks
00059   int extrablocks; //(how many blocks beyond WP are actually valid)
00060 
00061 public: 
00062   virtual const char *name() { return "VrGuppiSource"; }
00063   virtual float memoryTouched() {
00064     return 0; //no outputs are cached
00065   }
00066   virtual int work2(VrSampleRange output, void *o[]);
00067   virtual void initOutputBuffer(int n);
00068   VrGuppiSource(double sampling_freq);
00069 };
00070 
00071 template<class oType> int
00072 VrGuppiSource<oType>::work2(VrSampleRange output, void *ao[])
00073 {
00074   struct guppi_status status;
00075   int num;
00076   int blocksleft;
00077 
00078   sync(output.index);
00079 
00080   blocksleft = output.size/getOutputSize();
00081   num=currentIndex - minIndex;
00082   status.index=minIndex;
00083   blocksleft-=extrablocks;
00084 
00085   while (blocksleft>0) { 
00086     /*free some blocks if appropriate*/
00087     //how many blocks the driver thinks we're using
00088     // minus how many blocks we are really using
00089     status.num=num-(output.index+output.size-proc_minRP()+PAGE_SIZE-1)/PAGE_SIZE*sizeof(oType)+blocksleft;
00090 
00091     if (PARANOID && status.num < 0) {
00092       fprintf(stderr,"Guppi index inconsistency.\n");
00093       abort ();
00094     }
00095 
00096     //guppi driver won't let us throw out more blocks than we've read
00097     if((int)status.num>num) status.num=num-1;
00098 
00099     num-=status.num;
00100 
00101     //free the blocks and find out how many blocks are ready
00102     if((ioctl(gupfd, GIOCSETGETSTATUS, &status)) < 0) {
00103       perror("Failed to get guppi status");
00104       exit(-1);
00105     }
00106 
00107     //subtract how many new blocks we got
00108     blocksleft-=status.num-num;
00109     num=status.num;
00110 
00111     //do something about lost blocks
00112     if(status.lost) {
00113       fprintf(stderr,"Lost %i pages\n",status.lost);
00114     }
00115 
00116     if(blocksleft>0)
00117       YIELD(); //FIX return how many we actually got.
00118   }
00119   minIndex=status.index;
00120   currentIndex=status.index+num;
00121   extrablocks=-blocksleft;
00122   return output.size;
00123 }
00124 
00125 template<class oType> void
00126 VrGuppiSource<oType>::initOutputBuffer(int n)
00127 {
00128   if(n!=0) {
00129     fprintf(stderr,"GuppiSource can only have one output buffer.\n");
00130     exit(-1);
00131   }
00132   outBuffer[0]=new VrGuppiBuffer<oType>(this,gupfd);
00133 }
00134 
00135 template<class oType>
00136 VrGuppiSource<oType>::VrGuppiSource(double sampling_freq)
00137   :gupfd(-1), currentIndex(0), minIndex(0), extrablocks(0)
00138 {
00139   if ((gupfd = open("/dev/guppi0", (O_RDONLY | O_NONBLOCK))) < 0) {
00140     printf("Can't open GuPPI\n");
00141     exit(1);
00142   }
00143   setSamplingFrequency (sampling_freq);
00144   
00145   // add a query here to find out what data type(s) the GuPPI supports
00146   // Defaults to char for now
00147   setOutputSize (PAGE_SIZE/sizeof(oType));
00148 }
00149 
00150 #endif 

Generated on Tue Mar 15 23:55:33 2005 for GNU Radio by  doxygen 1.4.0