Esempio n. 1
0
void _writeOne(){
    PULSE();
    Nop();
    PULSE();
    Nop();
    Nop();
    Nop();
    Nop();
    Nop();
}
Esempio n. 2
0
void TIMER16_0_IRQHandler(void)
{
	//Make sure interrupt flag is set -- not sure if needed
	if(LPC_TMR16B0->IR & (1<<2))
	{
		uint8_t first_cycle = 0;
		uint8_t data_count = 0;
		uint16_t tmp;
							
		LPC_IOCON->PIO0_1 &= ~(1<<0);
		SETBIT(BLANK_PORT, BLANK);

//		if(CHECKBIT(VPRG_PORT, VPRG))
//		{
//			CLEARBIT(VPRG_PORT, VPRG);
//			first_cycle = 1;
//		}

		if(xlat_pulse)
		{
			PULSE(XLAT_PORT, XLAT);
			xlat_pulse = 0;
		}

		if(first_cycle)
			PULSE(SCLK_PORT, SCLK);
	
		CLEARBIT(BLANK_PORT, BLANK);
		LPC_IOCON->PIO0_1 |= (1<<0);
		while(1)
		{
		 	if(data_count < NUM_TLC5940 * NUM_SIN_BITS)
			{
				tmp = pwm[data_count/12];
				tmp &= BV(11 - (data_count%12));
			 	if(tmp)
				//if(gsdata[data_count])
					SETBIT(SIN_PORT, SIN);
				else
					CLEARBIT(SIN_PORT, SIN);

				PULSE(SCLK_PORT, SCLK);
				data_count++;
			}else{
				xlat_pulse = 1;
				break;
			}
		}
		LPC_TMR16B0->IR |= (1<<2);
	}
}
Esempio n. 3
0
void tlc5940_gspwm(void)
{
 	uint8_t first_cycle = 0;
	uint8_t data_count = 0;
	uint16_t gsclk_count = 0;
	uint16_t tmp;

	if(CHECKBIT(VPRG_PORT, VPRG))
	{
		CLEARBIT(VPRG_PORT, VPRG);
		first_cycle = 1;
	}

	CLEARBIT(BLANK_PORT, BLANK);
	while(1)
	{
	 	 if(gsclk_count > GSCLK_VAL)
		 {
		  	SETBIT(BLANK_PORT, BLANK);
			PULSE(XLAT_PORT, XLAT);
			if(first_cycle)
			{
				PULSE(SCLK_PORT, SCLK);
				first_cycle = 0;
			}
			break;
		 }else{
		 	if(data_count < 192*2)
			{
				tmp = pwm[data_count/12];
				tmp &= BV(11 - (data_count%12));
			 	if(tmp)
				//if(gsdata[data_count])
					SETBIT(SIN_PORT, SIN);
				else
					CLEARBIT(SIN_PORT, SIN);

				PULSE(SCLK_PORT, SCLK);
				data_count++;
			}
		}
		PULSE(GSCLK_PORT, GSCLK);
		gsclk_count++;
	}
}
Esempio n. 4
0
void _writeZero(){
    PULSE();
    Nop();
    Nop();
    Nop();
    Nop();
    Nop();
    Nop();
    Nop();
    Nop();
}
Esempio n. 5
0
//Misure singola dell'adc ad alta priorità
uint16_t get_adc(ADC_CH channel){
	adcStatus = DIRTY | HIGH_PRIORITY_LOCK;
#ifdef __MSP430_HAS_ADC10_A__
    while (ADC10CTL1 & ADC10BUSY); // ADC10BUSY? attendo la fine di una precedente conversione avviata

	if ((ADC10MCTL0 &  0xf ) != channel){
		ADC10CTL0 &= ~ADC10ENC;
		ADC10MCTL0 &=  0xfff0;
		ADC10MCTL0 |= channel;  // imposto il canale
	    clock_delay(600);       // Delay (~3us) for channel to settle
	}
    ADC10CTL0 |= (ADC10ENC | ADC10SC);        // Sampling and conversion start
    while (ADC10CTL1 & ADC10BUSY);          // ADC10BUSY?
    adcStatus = DIRTY;
    return ADC10MEM0;
#endif

#ifdef __MSP430_HAS_ADC12_PLUS__
	uint8_t busyLoops = 100;
    while (ADC12CTL1 & ADC12BUSY){ // ADC10BUSY? attendo la fine di una precedente conversione avviata
    	busyLoops--;
    }
    if (!busyLoops){
    	ADC12CTL0 &= ~ADC12ENC; //timeout !! fermo la conversione corrente!
    }

	if ((ADC12MCTL0 &  0xf ) != channel){
		ADC12CTL0 &= ~ADC12ENC;
		ADC12MCTL0 &=  0xfff0;
		ADC12MCTL0 |= channel;  // imposto il canale
	    clock_delay(600);       // Delay (~3us) for channel to settle
	}
    ADC12CTL0 |= (ADC12ENC | ADC12SC);  // Sampling and conversion start

    busyLoops = 100;
    while (ADC12CTL1 & ADC12BUSY){ // attendo la fine della conversione
    	busyLoops--;
    	PULSE(6,4);
    }

    adcStatus = DIRTY;
    if(!busyLoops){
    	return ADC_ERROR;
    	ADC12CTL0 &= ~ADC12ENC;
    }
    else
    	return ADC12MEM0;
#endif
}
Esempio n. 6
0
int next_imps(unsigned short *impbuf, int buflen, long timelen)
{
  static int toput;
  static int bitrem;
  static dbyte dirpulse;
  unsigned short *impbufend, *impbufstart;
  
  impbufstart = impbuf;
  impbufend = impbuf + buflen;
  
  while(impbuf < impbufend - 1 && timelen > 0) {
    switch(playstate) {
      
    case PL_PAUSE:
      if(currlev && lead_pause) {
    PULSE(IMP_1MS);
    lead_pause --;
      }
      else if(lead_pause > 10) {
    if(tapeopt.blanknoise && !(rb->rand() % 64)) 
      DPULSE(IMP_1MS * 10 - 1000, 1000); 
    else 
      DPULSE(IMP_1MS * 10, 0);
    lead_pause -= 10;
      }
      else if(lead_pause) {
    DPULSE(IMP_1MS, 0);
    lead_pause --;
      }
      else {
    if(tf_cseg.num || tf_cseg.sync1p || tf_cseg.sync2p ||
       tf_cseg.ptr != tf_cseg.len) finished = 0;

    switch (tf_cseg.type) {
    case ST_NORM: playstate = PL_LEADER; break;
    case ST_DIRE: playstate = PL_DIRE;   dirpulse = 0; break;
    case ST_PSEQ: playstate = PL_PSEQ;   break;
    default:      playstate = PL_NONE;
    }
      }
      break;

    case PL_LEADER:
      if(tf_cseg.num >= 2) {
    DPULSE(tf_cseg.pulse, tf_cseg.pulse);
    tf_cseg.num -= 2;
      }
      else
      if(tf_cseg.num) {
    PULSE(tf_cseg.pulse);
    tf_cseg.num --;
      }
      else { /* PL_SYNC */
    if(tf_cseg.sync1p || tf_cseg.sync2p) 
      DPULSE(tf_cseg.sync1p, tf_cseg.sync2p);
    bitrem = 0;
    playstate = PL_DATA;
      }
      break;
      
    case PL_DATA:
      if(!bitrem) {
    toput = next_data();
    if(toput < 0) {
      playstate = PL_END;
      break;
    }
    if(tf_cseg.ptr != tf_cseg.len) {
      if(timelen > 16 * max(tf_cseg.onep, tf_cseg.zerop) && 
         impbuf <= impbufend - 16) {
        int p1, p2, br, tp;
        
        p1 = tf_cseg.onep;
        p2 = tf_cseg.zerop;
        br = 8;
        tp = toput;
        
        while(br) {
          if(tp & 0x80) DPULSE(p1, p1);
          else          DPULSE(p2, p2);
          br--;
          tp <<= 1;
        }
        bitrem = 0;
        break;
      }
      bitrem = 8;
    }
    else {
      bitrem = tf_cseg.bused;
      if(!bitrem) break;
    }
      }
      if(toput & 0x80) DPULSE(tf_cseg.onep, tf_cseg.onep);
      else             DPULSE(tf_cseg.zerop, tf_cseg.zerop);
      bitrem--, toput <<= 1;
      break;

    case PL_PSEQ:
      {
    int b1, b2;
    dbyte pulse1, pulse2;
    b1 = next_data();
    b2 = next_data();
    if(b1 < 0 || b2 < 0) {
      playstate = PL_END;
      break;
    }
    pulse1 = b1 + (b2 << 8);

    b1 = next_data();
    b2 = next_data();
    if(b1 < 0 || b2 < 0) {
      PULSE(pulse1);
      playstate = PL_END;
      break;
    }
    pulse2 = b1 + (b2 << 8);
    DPULSE(pulse1, pulse2);
      }
      break;

    case PL_DIRE:
      for(;;) {
    if(!bitrem) {
      toput = next_data();
      if(toput < 0) {
        playstate = PL_END;
        DPULSE(dirpulse, 0);
        break;
      }
      if(tf_cseg.ptr != tf_cseg.len) bitrem = 8;
      else {
        bitrem = tf_cseg.bused;
        if(!bitrem) break;
      }
    }
    bitrem--;
    toput <<= 1;
    if(((toput & 0x0100) ^ (currlev ? 0x0100 : 0x00))) {
      PULSE(dirpulse);
      dirpulse = tf_cseg.pulse;
      break;
    }
    dirpulse += tf_cseg.pulse;
    if(dirpulse >= 0x8000) {
      DPULSE(dirpulse, 0);
      dirpulse = 0;
      break;
    }
      }
      break;

    case PL_END:
      if(tf_cseg.pause) {
    PULSE(IMP_1MS);
    tf_cseg.pause--;
    if(currlev) PULSE(0);
    finished = 1;
      }
      playstate = PL_NONE;
      break;
      
    case PL_NONE:
    default:
      return PTRDIFF(impbuf, impbufstart);
    }
  }

  return PTRDIFF(impbuf, impbufstart);
}
Esempio n. 7
0
int main(int argc, char *argv[]) {
/*
DRIVER_01 is a FLOW-MOTION LIMITED flow scheme! The flow will end when all vents
          have no more lava to effuse AND when the flow is no longer innundating
          new grid cells.
*/
/*DRIVER for a lava flow code ALGORITHM:
         Read in a Configuration File with INITIALIZE
         Load a DEM Raster with DEM_LOADER and assign parameters to a data grid
         Create Cellular Automata lists and assign source vents with INIT_FLOW
         
         Main Flow Loop:
           If there is more volume to erupt at source vents, call PULSE
           Move lava from cells to neighbors with DISTRIBUTE
           If flow is still moving, keep looping to call DISTRIBUTE
         
         After flow is completely erupted:
           Check for Conservation of Mass
           Write out requested Model Output to user-defined file paths
*/
	
	/*VARIABLES******************************************************************/
	/*Files*/
	char     *configFilename = argv[1]; /*configuration file path               */
	char     **Filenames;               /*A list of file paths for model output */
	char     tempFilename[15];          /*A temporary file path for whatever use*/
	
	/*Main Arrays*/
	DataCell **dataGrid;                /*Global Data Grid                      */
	Automata **CAList;                  /*Cellular Automata Lists (Active Cells)*/
	VentArr  *Vents;                    /*Source Vent List                      */
	unsigned *ActiveCounter;            /*Number of Active Cells in CA List     */
	
	/*Model Parameters*/
	int      i,j, ret;                  /*loop variables, function return value */
	unsigned CAListCount = 0;           /*Number of CA Lists, def in INIT_FLOW  */
	unsigned CAListSize  = 0;           /*Size of each CA List, def in INIT_FLOW*/
	unsigned ventCount   = 0;           /*Number of Src Vents, def in INITIALIZE*/
	int      pulseCount  = 0;           /*Current number of Main PULSE loops    */
	
	/*Physical Parameters*/
	double   residualThickness;         /*Residual Flow Thickness               */
	double   *DEMmetadata;              /*Geographic Coordinates of DEM Raster  */
	double   elevationUncertainty;      /*DEM Raster Elevation Uncertainty      */
	double   volumeToErupt;             /*Total Volume to deliver to vent cells */
	double   volumeErupted = 0;         /*Total Volume in All Active Cells      */
	double   volumeRemaining;           /*Volume Remaining to be Erupted        */
	int      volumeRemainingBool = 0;   /*0 if volume left to erupt, otherwise 1*/
	
	/*Post Flow Motion Detection Variables*/
	double   TotalMotion = 0;           /*Summed thickness change in all cells  */
	double   MinTotalMotion = 1e-11;    /*Threshold: below it flow is "stagnant"*/
	unsigned lastmotionCounter = 0;     /*Number of loops since last motion     */
	unsigned maxLastMotionCount = 10;   /*Max loops allowed since last motion   */
	unsigned lastActiveCounter = 0;     /*Number of active cells in prev. loop  */
	time_t   LastInundationTime;        /*Timestamp of last active cell creation*/
	double   maxLastInundationTime=10.0;/*Max time allowed since last cell cretn*/
	
	
	/*TIME AND RANDOM NUMBER GEN*************************************************/
	startTime = time(NULL); /*Define Start Time*/
	srand(time(NULL));      /*Seed random number generator*/
	
	/*WELCOME USER TO SIMULATION AND CHECK FOR CORRECT USAGE*********************/
	printf("\n\n               MOLASSES is a lava flow simulator.\n\n");
	
	/*User must supply the name of the executable and a configuration file*/
	if(argc<2) {
		printf("Usage: %s config-filename\n",argv[0]);
		return(-1);
	}
	
	printf("Beginning flow simulation...\n");
	
	/*MODULE: INITIALIZE*********************************************************/
	/*        Assigns several empty variables based on a user-defined 
	            configuration file.                                             */
	/*        File Name List output in this order:
	            [0] - DEM
	            [1] - Residual Flow Thickness
	            [2] - Elevation Uncertainty
	            [3] - Output file: ASCII X,Y,Thickness
	            [4] - Output file: Hit Map
	            [5] - Output file: Raster Thickness
	            [6] - Output file: Raster Elevation
	            [7] - Output file: Raster Elevation + Flow Thickness            */
	
	ret = INITIALIZE(configFilename,        /*chr Configuration File Name       */
	                 &Filenames,            /*chr File Name List                */
	                 &residualThickness,    /*dbl Global Residual Flow Thickness*/
	                 &elevationUncertainty, /*dbl Global Elevation Uncertainty  */
	                 &Vents,                /*ventarr Vent Structure Array      */
	                 &ventCount             /*unsignd Number of Vents           */
	                );
	
	/*Check for Error flag (INITIALIZE returns <0 value)*/
	if(ret<0){
		printf("\nERROR [MAIN]: Error flag returned from [INITIALIZE].\n");
		printf("Exiting.\n");
		return(-1);
	}
	
	
	/*MODULE: DEM_LOADER*********************************************************/
	/*        Loads Raster into Global Data Grid based on code:
	            TOPOG - Loads a DEM raster into the data grid's dem_elev value
	            RESID - Loads a raster into the data grid's residual value
	            T_UNC - Loads a raster into the data grid's elev_uncert value
	          Returns a metadata list of geographic coordinates of the raster   */
	/*        DEMmetadata format:
		          [0] lower left x
		          [1] w-e pixel resolution
		          [2] number of cols, assigned manually
		          [3] lower left y
		          [4] number of lines, assigned manually
		          [5] n-s pixel resolution (negative value)                       */
	
	/*Assign Topography to Data Grid Locations*/
	DEMmetadata = DEM_LOADER(Filenames[0], /*char            DEM file name   */
	                         &dataGrid,    /*DataCell        Global Data Grid*/
	                         "TOPOG"       /*DEM_LOADER Code Topography      */
	                        );
	
	/*Check for Error flag (DEM_LOADER returns a null metadata list)*/
	if(DEMmetadata==NULL){
		printf("\nError [MAIN]: Error flag returned from DEM_LOADER[TOPOG].\n");
		printf("Exiting.\n");
		return(-1);
	}
	
	
	/*Assign Residual Thickness to Data Grid Locations*/
	/*If residualThickness is -1, user input a Residual Thickness Map*/
	if(residualThickness==-1) {
		DEMmetadata = DEM_LOADER(Filenames[1], /*char            Residual filename*/
			                       &dataGrid,    /*DataCell        Global Data Grid */
			                       "RESID"       /*DEM_LOADER Code Resid Thickness  */
			                      );
	
		/*Check for Error flag (DEM_LOADER returns a null metadata list)*/
		if(DEMmetadata==NULL){
			printf("\nError [MAIN]: Error flag returned from DEM_LOADER[RESID].\n");
			printf("Exiting.\n");
			return(-1);
		}
	}
	/*If residualThickness is not -1, it is constant globally.*/
	else {
		/*Write residual flow thickness into 2D Global Data Array*/
		for(i=0;i<DEMmetadata[4];i++) {
			for(j=0;j<DEMmetadata[2];j++) {
				dataGrid[i][j].residual = residualThickness;
			}
		}
	}
	
	
	/*Assign Elevation Uncertainty to Data Grid Locations*/
	/*If elevationUncertainty is -1, user input an elevation uncertainty map*/
	if(elevationUncertainty==-1) {
		DEMmetadata = DEM_LOADER(Filenames[2], /*char            uncertny filename*/
			                       &dataGrid,    /*DataCell        Global Data Grid */
			                       "T_UNC"       /*DEM_LOADER Code elev uncertainty */
			                      );
	
		/*Check for Error flag (DEM_LOADER returns a null metadata list)*/
		if(DEMmetadata==NULL){
			printf("\nError [MAIN]: Error flag returned from DEM_LOADER[T_UNC].\n");
			printf("Exiting.\n");
			return(-1);
		}
	}
	/*If elevationUncertainty is not -1, it is constant globally.*/
	else {
		/*Write elevation uncertainty values into 2D Global Data Array*/
		for(i=0;i<DEMmetadata[4];i++) {
			for(j=0;j<DEMmetadata[2];j++) {
				dataGrid[i][j].elev_uncert = elevationUncertainty;
			}
		}
	}
	
	
	/*MODULE: INIT_FLOW**********************************************************/
	/*        Creates Active Cellular Automata lists and activates vents in them.
	          Also creates bookkeeper variables: 
	            total size of CA lists
	            total number of CA lists
	            total number of active automata in the CA list
	            total volume to erupt (combined volumes to erupt at vents)      */
	
	ret = INIT_FLOW(dataGrid,      /*DataCell  Global Data Grid                 */
	               &CAList,        /*Automaton Active Cells List                */
	               Vents,          /*VentArr   Vent Data Array                  */
	               &CAListCount,   /*unsigned  Number of CA Lists created       */
	               &CAListSize,    /*unsigned  Size of each empty CA List       */
	               ventCount,      /*unsigned  Number of Vents                  */
	               &ActiveCounter, /*unsigned  Number of active cells in CA List*/
	               DEMmetadata,    /*double    Geographic Metadata              */
	               &volumeToErupt  /*double    Volume that the model will expel */
	              );
	
	/*Check for Error flag (INIT_FLOW returns <0 value)*/
	if(ret<0) {
		printf("\nError [MAIN]: Error flag returned from [INIT_FLOW].\n");
		printf("Exiting.\n");
		return(-1);
	}
	
	
	
	
	/****************************************************************************/
	/*MAIN FLOW LOOP: PULSE LAVA AND DISTRIBUTE TO CELLS*************************/
	/****************************************************************************/
	volumeRemaining = volumeToErupt; /*set countdown bookkeeper volumeRemaining*/
	
	printf("\n                         Running Flow\n");
	
	
	/*Loop to call PULSE and DISTRIBUTE only if volume remains to be erupted
	  OR if flow has not stopped moving*/
	while((volumeRemaining > 0)||(lastmotionCounter<maxLastMotionCount)) {
		
		if(volumeRemaining > 0) { /*If there is more lava to erupt, call PULSE*/
		/*MODULE: PULSE************************************************************/
		/*        Delivers lava to vents based on information in Vent Data Array.
		          Returns total volume remaining to be erupted.                   */
	
		ret = PULSE(CAList[1],        /*Automaton Active Cells List               */
		            &Vents,           /*VentArr   Vent Data Array                 */
		            ActiveCounter[1], /*unsigned  Number of activ cells in CA List*/
		            &volumeRemaining, /*double    Countdown Lava Volume bookkeeper*/
		            ventCount,        /*unsigned  Number of vents                 */
		            DEMmetadata       /*double    Geographic Metadata             */
		           );
	
		/*Check for Error flags (PULSE returns <0 or 0 value)*/
		if(ret<0) {
			printf("\nERROR [MAIN]: Error flag returned from [PULSE].\n");
			printf("Exiting.\n");
			return(-1);
		}
		else if (ret==0) {
			if (volumeRemaining) {
				/*This return should not be possible, 
				  Pulse should return 0 if no volume remains*/
				printf("\nERROR [MAIN]: Error between [PULSE] return and lava vol.\n");
				printf("Exiting.\n");
				return(-1);
			}
			/*If ret==0, PULSE was called even though there was no lava to distribute.
			  Do not call Pulse or Distribute anymore! Break out of While loop.     */
			break;
		}
		/*if Pulse module successfully updated vents, ret will > 0.
		  Continue, call Distribute module.*/
		
		/*Update status message on screen*/
		printf("\rInundated Cells: %-7d; Volume Remaining: %10.2f",ActiveCounter[1],
		       volumeRemaining);
		}
		else { /*if no more volume to erupt, but flow still moving*/
		/*Update status message on screen to show flow motion*/
			printf("\rInundated Cells: %-7d; total dZ in flow: %10.2e",ActiveCounter[1],
		       TotalMotion);
		}
		
		
		/*MODULE: DISTRIBUTE*******************************************************/
		/*        Distributes lava from cells to neighboring cells depending on
		          module specific algorithm (e.g. slope-proportional sharing).
		          Updates a Cellular Automata List and the active cell counter.*/
		
		ret = DISTRIBUTE(dataGrid,          /*DataCell  Global Data Grid       */
		                 CAList[1],         /*Automaton Active Cells List      */
		                 &ActiveCounter[1], /*unsigned  Number of active cells */
		                 DEMmetadata        /*double    Geographic Metadata    */
		                );
		
		/*Check for Error flag (DISTRIBUTE returns <0 value)*/
		if(ret<0) {
			printf("\nERROR [MAIN]: Error flag returned from [DISTRIBUTE].\n");
			printf("Exiting.\n");
			return(-1);
		}
		
		/*If you want to output the flow at EVERY Pulse, here is a good place to do
		  it. A temporary file name variable is declared using the number of times 
		  this Pulse loop has been completed, then the OUTPUT module is called.
		  Uncomment the lines below if you want this. Commenting out the file name
		  declaration creates warnings since the variables won't later be used, so
		  I've left it uncommented out. (It only runs once per pulse, so it doesn't
		  slow the code down).*/
		
		/*increment pulse count, then rename the temporary file path.*/
		snprintf(tempFilename,15,"pulse_%04d.xyz",(++pulseCount));
		/*MODULE: OUTPUT**************************************/
		/*        writes out a file. Arguments:
		            DataCell  Global Data Grid
		            Automaton Active Cells List
		            unsigned  Number of active cells
		            string    Output Filename
		            OUTPUT Code: 0 = ASCII X,Y,Thickness File
		            double    Geographic Metadata
		            string    Original Raster Projection     */
		/*
		ret = OUTPUT(dataGrid,
		             CAList[1],
		             ActiveCounter[1],
		             tempFilename,
		             0,
		             DEMmetadata,
		             ""
		            );
		*/
		/*Check for Error flag (OUTPUT returns <0 value)*/
		/*
		if(ret<0){
			printf("\nERROR [MAIN]: Error flag returned from [OUTPUT].\n");
			printf("Exiting.\n");
			return(-1);
		}
		*/
		
		
		
		
		
		
		/*TEST TO SEE IF FLOW IS STILL PROGRESSING, IF VOLUME HAS RUN OUT*/
		/*This Driver Module continues to call the DISTRIBUTE Module if there is
		  significant flow within the lava flow, even after all lava has been 
		  delivered to the vents via the PULSE Module.
		  
		  Flow will continue to distribute if:
		    1) There is still volume to deliver to vent
		    2) The summed change in flow thickness across all cells is > than 
		       a pre-defined MinTotalMotion variable.
		    3) The time elapsed in seconds since the last active cell was created
		       is < than a pre-defined maxLastInundationTime.
		  
		  If the summed change in flow thickness (dz) is negligable, 
		    lastmotionCounter is incremented. If lastmotionCounter==pre-defined 
		    maxLastMotionCount, flow will stop.
		  If the time elapsed since the last cell creation is significant,
		    lastmotionCounter will be set at maxLastMotionCount, flow will stop.
		  */
		
		/*Only test for remaining flow IF eruption volume has run out*/
		if(volumeRemaining<=0) {
			/*If this is the first time volume is 0, start new screen output line*/
			if((volumeRemainingBool++)==0) printf("\n");
			
			/*MOTION TEST - If movement has stopped, end the flow*/
			TotalMotion=0.0; /*Reset TotalMotion to 0*/
			for(i=1;i<=ActiveCounter[1];i++) {
				/*Add change in volume of all active cells
				  CA List[2] is a copy of the Active CA List of the last Pulse Loop*/
				TotalMotion += fabs(CAList[1][i].elev - CAList[2][i].elev);
			}
			
			/*If flow has not changed, increment lastmotionCounter*/
			if(TotalMotion <= MinTotalMotion) ++lastmotionCounter;
			/*If flow has changed, reset lastmotionCounter and store flow values
			    in spare CA List.*/
			else{
				lastmotionCounter=0;                     /*reset*/
				for(i=1;i<=ActiveCounter[1];i++) {       /*For all Active Cells*/
					CAList[2][i].elev = CAList[1][i].elev; /*Copy CA List[1] to List[2]*/
				}
			}
			
			/*POPCORN RULE - If a new cell hasn't been created in X secs, end flow*/
			if(lastActiveCounter!=ActiveCounter[1]) { /*If there's a new cell*/
				LastInundationTime = time(NULL);        /*Reset Last inundation time*/
				lastActiveCounter=ActiveCounter[1];     /*Reset lastActiveCounter*/
			}
			/*If there are no new cells, check that X secs have not gone by.*/
			else {
				/*If max time to wait for a new cell HAS been reached, end the flow*/
				if(((unsigned) (time(NULL)-LastInundationTime))>=maxLastInundationTime) {
					printf("\n Ending Flow because last cell to be inundated was ");
					printf(">%u secs ago.", (unsigned) (time(NULL)-LastInundationTime));
					lastmotionCounter=maxLastMotionCount;
				}
			}
		} /*End of Remaining Detectable Flow Check*/
		
		
	} /*End while main flow loop: (while(volumeRemaining>0)and Flow Motion)*/
	
	
	/*POST FLOW WRAP UP**********************************************************/
	
	printf("\n\n                     Single Flow Complete!\n");
	
	/*Print out final number of inundated cells*/
	printf("Final Count: %d cells inundated.\n\n", ActiveCounter[1]);
	
	
	/*POST FLOW WRAP UP: CONSERVATION OF MASS CHECK******************************/
	/*ALL DRIVER MODULES MUST HAVE THIS. In order to do unit testing during
	  code compilation, makefile searches for the string "SUCCESS: MASS CONSERVED"
	  to conclude that the code is Verified (though not validated).*/
	
	volumeErupted = 0;
	/*For each Active Flow Cell, add cell lava volume to volumeErupted*/
	for(i=1;i<=ActiveCounter[1];i++)
		volumeErupted += (CAList[1][i].thickness + 
		               dataGrid[CAList[1][i].row][CAList[1][i].col].residual) *
		               DEMmetadata[1] * DEMmetadata[5];
	
	/*print out volume delivered to vents and total volume now in cells*/
	printf("Conservation of mass check\n");
	printf(" Total (IN) volume pulsed from vents:   %0.3f\n",volumeToErupt);
	printf(" Total (OUT) volume found in cells:     %0.3f\n",volumeErupted);
	/*Double data types are precise to 1e-8, so make sure that volume IN and
	  volume OUT are within this precision.*/
	if(abs(volumeErupted-volumeToErupt)<=1e-8)
		printf(" SUCCESS: MASS CONSERVED\n");
	/*If volumes are significantly different (are more than Double Precision diff.
	  then mass is NOT conserved!!*/
	else 
		/*Print the mass excess*/
		printf(" ERROR: MASS NOT CONSERVED! Excess: %0.2e m^3",
		       volumeErupted-volumeToErupt);
	
	
	/*MODULE: OUTPUT*************************************************************/
	/*        Writes out model output to a file path.
	          File Output types available, and their codes:
	            0: X,Y,Thickness ascii flow list
	            1: Hit Raster (1 = Hit, 0 = Not Hit)
	            2: Thickness Raster
	            3: Elevation Raster
	            4: Elevation + Lava Raster (code 2 + code 3)
	          
	          Filename Index output from INITIALIZE:
	            Filenames[3] - Output file: ASCII X,Y,Thickness
	            Filenames[4] - Output file: Hit Map
	            Filenames[5] - Output file: Raster Thickness
	            Filenames[6] - Output file: Raster Elevation
	            Filenames[7] - Output file: Raster Elevation + Flow Thickness   */
	
	/*Check Filenames Array to see if a filename was given (so model output is
	  requested).*/
	for(i=0;i<4;i++){
		/*Check to see if the File Path is not empty (the following test will !=0)*/
		if(strlen(Filenames[i+3]) > 1) {
		/*If there's a file path given, write model output to it.*/
			ret = OUTPUT(dataGrid,         /*DataCell  Global Data Grid           */
			             CAList[1],        /*Automaton Active Cells List          */
			             ActiveCounter[1], /*unsigned  Number of active cells     */
			             Filenames[i+3],   /*string    Output File Path           */
			             i,                /*OUTPUT Code, see above               */
			             DEMmetadata,""    /*string    Original Raster Projection */
			            );
			
			/*Check for Error flag (OUTPUT returns <0 value)*/
			if(ret<0){
				printf("\nERROR [MAIN]: Error flag returned from [OUTPUT].\n");
				printf("Exiting.\n");
				return(-1);
			}
		}
	}
	
	/*Calculate simulation time elapsed, and print it.*/
	endTime = time(NULL);
	printf("\nElapsed Time of simulation approximately %u seconds.\n\n",
	       (unsigned)(endTime - startTime));
	
	return(0);
}