Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Namespace Members | Data Fields | Globals | Related Pages

utilities.h

00001 /************************************************************************************
00002  * utilities.h
00003  *
00004  *   synopsis: Function prototypes and #defines for general purpose utility routines
00005  *             and macros.
00006  ************************************************************************************/
00007 #ifndef UTILITIES
00008 #define UTILITIES
00009 
00010 #include "processor.h"
00011 
00012 //Booleans:
00013 #undef TRUE
00014 #undef FALSE
00015 #undef true
00016 #undef false
00017 #define TRUE  1
00018 #define FALSE 0
00019 #define true  1
00020 #define false 0
00021 
00022 /* The backslash MUST be the last character on the line, or an odd
00023    compile error will result */
00024 
00025 /* timing macros: delta t & delay in tenths of microseconds */
00026     #if ( (defined(I_AM_MASTER_DSP))||((defined(REV_B))||(defined(REV_C))) )
00027         #define delta_t(t0_) ((TIMER_getCount(timer1) - (t0_)) >> 2)
00028 
00029         #define delay(x) { \
00030             UINT32 delay_t0; \
00031             delay_t0 = TIMER_getCount(timer1); \
00032             while( ((TIMER_getCount(timer1) - delay_t0) >> 2) < (x)); \
00033         }
00034 
00035     /* Rev. E RODs have a bug in the silicon when using the timers: if the period
00036        is set to the maximum (0xffffffff), and the timer count is greater than
00037        ~0x90000000, then the DSP lapses into a state where it stalls for up to
00038        600 micro-seconds on certain function calls. Using a smaller period in the
00039        timer prevents this, but means that we must use an inlined function for
00040        delta_t instead of a macro since if it wraps the subtraction will no longer
00041        automatically handle it (delay is made into an inlined function too).
00042        Additionally, the SDSPs run by default at 220 MHz, requiring different
00043        mathematics. The inlined functions need access to timer1; this is done using
00044        pointers to maintain transparency in the rest of the program. */
00045     #elif (defined(REV_E))
00046 
00047         static inline UINT32 delta_t(UINT32 t0);
00048         static inline void   delay(UINT32 x);
00049         
00050     #if 0
00051         static inline UINT32 delta_t(UINT32 t0) {
00052             UINT32 t1, p1;
00053             t1= *((UINT32 *) 0x01980008);  //timer 1 count
00054             p1= *((UINT32 *) 0x01980004);  //timer 1 period
00055 
00056             if (t1 < t0) return ((t1 -t0 +p1)/5);
00057             else         return ((t1 -t0)/5);
00058         }
00059 
00060         
00061         static inline void delay(UINT32 x) {
00062             UINT32 t0, t1, delta, p1;
00063             t0= *((UINT32 *) 0x01980008);  //timer 1 count
00064             p1= *((UINT32 *) 0x01980004);  //timer 1 period
00065 
00066             do {
00067                 t1= *((UINT32 *) 0x01980008);
00068                 if (t1 < t0) delta= ((t1 -t0 +p1)/5);
00069                 else         delta= ((t1 -t0)/5);
00070             } while (delta < x);
00071         }
00072 
00073     #else
00074         static inline UINT32 delta_t(UINT32 t0) {
00075             UINT32 t1, p1;
00076             t1= *((UINT32 *) 0x01980008);  //timer 1 count
00077             p1= *((UINT32 *) 0x01980004);  //timer 1 period
00078     
00079             /* Check to be sure that the two times are within the same period and
00080                correct t1 if they are not: */
00081             if (t1 < t0) t1+= p1;
00082             t1-= t0;
00083             
00084             /* NOTE: These calculations will be innacurate running the SDSPs at
00085                160 MHz! (220 MHz is the default running speed).
00086     
00087                At 220 MHz there are 220/4 or 55 clock ticks per us. On the MDSP
00088                there are 40 clock ticks per us, so returning the time in 10ths of
00089                a us is easy: divide by 4 (right shift by 2). Here, to return the
00090                time in the same manner (in 10ths of a us) reuires to divide by 5.5
00091                which would be more expensive to do since there are then multiple
00092                conversions which would have to happen (the input & returned times
00093                are integer. A quick approximation (to within ~3%) is to return
00094                (3/16)*t1 or (1/4 -1/16)*t1: */
00095             return (t1>>2) -(t1>>4);
00096         }
00097     
00098         static inline void delay(UINT32 x) {
00099             UINT32 t0, t1, delta, p1;
00100             t0= *((UINT32 *) 0x01980008);  //timer 1 count
00101             p1= *((UINT32 *) 0x01980004);  //timer 1 period
00102     
00103             do {
00104                 t1= *((UINT32 *) 0x01980008);
00105                 if (t1 < t0) t1+= p1;
00106                 delta= (t1>>2) -(t1>>4);
00107             } while (delta < x);
00108         }
00109     #endif
00110 
00111     #endif
00112     
00113 /* led macros for quick timing calls */
00114 #if defined(I_AM_MASTER_DSP)
00115     #define yellowLed_on     (*((UINT32 *) 0x018c0024)|= 1);
00116     #define greenLed_on      (*((UINT32 *) 0x01900024)|= 1);
00117     #define redLed_on        (*((UINT32 *) 0x018c0024)|= 4);
00118     
00119     #define yellowLed_off    (*((UINT32 *) 0x018c0024)&= ~1);
00120     #define greenLed_off     (*((UINT32 *) 0x01900024)&= ~1);
00121     #define redLed_off       (*((UINT32 *) 0x018c0024)&= ~4);
00122     
00123     #define yellowLed_toggle (*((UINT32 *) 0x018c0024)^= 1);
00124     #define greenLed_toggle  (*((UINT32 *) 0x01900024)^= 1);
00125     #define redLed_toggle    (*((UINT32 *) 0x018c0024)^= 4);
00126 
00127 #elif defined(I_AM_SLAVE_DSP)
00128     #define fsrp0_on         (*((UINT32 *) 0x018c0024)|=  4);
00129     #define fsxp0_on         (*((UINT32 *) 0x018c0024)|=  8);
00130 
00131     #define fsrp0_off        (*((UINT32 *) 0x018c0024)&= ~4);
00132     #define fsxp0_off        (*((UINT32 *) 0x018c0024)&= ~8);
00133 
00134     #define fsrp0_toggle     (*((UINT32 *) 0x018c0024)^=  4);
00135     #define fsxp0_toggle     (*((UINT32 *) 0x018c0024)^=  8);
00136 
00137     /* Rev. B & C RODs have the yellow LED attached to CLKXP1, while Rev. E RODs
00138        use external pin #7 as a GPI/O output to drive the LED. However, this is
00139        not modelled in the simulation, so the SP is used instead. The Rev. E SDSPs
00140        can also signal the MDSP by pulling ext. pin 6 low (drives the signal in
00141        the RCF high).  Fot the Rev. B/C SDSPs, this signal sets a bit (6) in
00142        status reg. 0 (which MDSP polls frequently). */
00143     #if (defined(REV_B)||defined(REV_C)||defined(SIM))
00144         #define yellowLed_on     (*((UINT32 *) 0x01900024)&= ~2);
00145         #define yellowLed_off    (*((UINT32 *) 0x01900024)|=  2);
00146         #define yellowLed_toggle (*((UINT32 *) 0x01900024)^=  2);
00147 
00148         #define setMdspAttention(bit) {             \
00149             (*((UINT32 *) 0x80000008)|= (1<<bit));  \
00150             (*((UINT32 *) 0x80000000)|= 0x40);      \
00151         }
00152 
00153         //Lower the attn. flag if the whole field is cleared.
00154         #define rstMdspAttention(bit) {                 \
00155             (*((UINT32 *) 0x80000008)&= ~(1<<bit));     \
00156             if  (!((*((UINT32 *) 0x80000008)) & 0xf))   \
00157                 (*((UINT32 *) 0x80000000)&= ~0x40);     \
00158         }
00159 
00160     #elif (defined(REV_E))
00161         #define yellowLed_on     (*((UINT32 *) 0x01b00008)&= ~0x80);
00162         #define yellowLed_off    (*((UINT32 *) 0x01b00008)|=  0x80);
00163         #define yellowLed_toggle (*((UINT32 *) 0x01b00008)^=  0x80);
00164 
00165         #define setMdspAttention(bit) {             \
00166             (*((UINT32 *) 0x00010008)|= (1<<bit));  \
00167             (*((UINT32 *) 0x01b00008)&= ~0x40);     \
00168         }
00169 
00170         //Lower the attn. flag if the whole field is cleared.
00171         #define rstMdspAttention(bit) {                 \
00172             (*((UINT32 *) 0x00010008)&= ~(1<<bit));     \
00173             if  (!((*((UINT32 *) 0x00010008)) & 0xf))   \
00174                 (*((UINT32 *) 0x01b00008)|= 0x40);      \
00175         }
00176     #endif
00177 #endif
00178 
00179 /* register access width (data bus width of EMIF) */
00180 #define BYTE_W    8
00181 #define HWORD_W  16
00182 #define WORD_W   32
00183 
00184 /* z is returned as lesser of x or y */
00185 #define MINI(x,y,z)   z=((x)<(y))?(x):(y);
00186 
00187 /* macros to set, reset and read fields of variables and registers */
00188 #define N_BIT_MASK(wid)           (~(0xFFFFFFFF<<(wid)))
00189 #define FIELD_MASK(bit,wid)       (N_BIT_MASK(wid) << (bit))
00190 #define FIELD_OFF(bit,wid)        (~(FIELD_MASK(bit,wid)))
00191 #define FIELD_VAL(bit,wid,val)    ((val&(N_BIT_MASK(wid))) << bit)
00192 
00193 #define SET_VBIT(var,bit)        (var |= (1 << bit))
00194 #define RST_VBIT(var,bit)        (var &= ~(1 << bit))
00195 #define ASGN_VBIT(var,bit,val)   (var = ((RST_VBIT(var,bit)) | (val<<bit)))
00196 #define GET_VBIT(var,bit)        ((var >> bit) & 1)
00197 #define RST_VFLD(var,bit,wid)    (var &= (FIELD_OFF(bit,wid)))
00198 #define ASGN_VFLD(var,bit,wid,val)  \
00199              (var = (RST_VFLD(var,bit,wid)) | (FIELD_VAL(bit,wid,val)))
00200 #define GET_VFLD(var,bit,wid)    ((FIELD_MASK(bit,wid) & var) >> bit)
00201 
00202 /*  Some of the macros below are essentially the same as those in the Texas
00203  * Instruments provided regs.h.  The ones in this file should be used in DSP code
00204  * authored by the ROD group.  If Texas Instruments changes their macro names for
00205  * some reason, the DSP code will not be affected.                  dpf             */
00206 #define CONTENTS(adr) (*((volatile UINT32 *)(adr)))
00207 
00208 #define READ_REG(adr)             (CONTENTS(adr))
00209 #define WRITE_REG(adr,val)        (CONTENTS(adr) = (val))
00210 #define SET_RBIT(adr,bit)         (CONTENTS(adr) |= (1 << (bit)))
00211 #define RST_RBIT(adr,bit)         (CONTENTS(adr) &= (~(1 << (bit))))
00212 #define ASGN_RBIT(adr,bit,val)    (CONTENTS(adr) = (RST_RBIT(adr,bit)) | (val<<bit))
00213 #define GET_RBIT(adr,bit)         ((CONTENTS(adr) >> bit) & 1)
00214 #define RST_RFLD(adr,bit,wid)     (CONTENTS(adr) &= (FIELD_OFF(bit,wid)))
00215 #define GET_RFLD(adr,bit,wid)     ((CONTENTS(adr) & FIELD_MASK(bit,wid)) >> bit)
00216 #define ASGN_RFLD(adr,bit,wid,val) (CONTENTS(adr) = \
00217                                    (RST_RFLD(adr,bit,wid)) | (FIELD_VAL(bit,wid,val)))
00218 
00219 /* Contexts for waitRegister: */
00220 #define  CONTEXT_NULL   0
00221 #define  CONTEXT_TASK   1
00222 #define  CONTEXT_PRIM   2
00223 #define  CONTEXT_ALL    3
00224 
00225 /* The copymem & setmem EDMA transfer complete codes. The only available method
00226    of monitoring the progress of an EDMA transfer is to allow an interrupt upon
00227    completion, and then in the interrupt check the TCC to decide what to do. */
00228 //#define EDMA_SETMEM_ID     14  dpsf not true...
00229 //#define EDMA_COPYMEM_ID    15
00230 
00231 #endif

Generated on Thu Dec 22 20:17:18 2005 for SCT DAQ/DCS Software - C++ by doxygen 1.3.5