Пример #1
0
/***************************************************************************//**
 * @brief Captures a specified number of samples from the ADC.
 *
 * @param size    - number of bytes to read from the device
 * @param address - capture start address
 *
 * @return None.
*******************************************************************************/
void adc_capture(uint32_t size, uint32_t address)
{
	uint32_t reg_val;
	uint32_t transfer_id;
	uint32_t length;

	length = (size * 2);

	adc_dma_write(AXI_DMAC_REG_CTRL, 0x0);
	adc_dma_write(AXI_DMAC_REG_CTRL, AXI_DMAC_CTRL_ENABLE);

	adc_dma_write(AXI_DMAC_REG_IRQ_MASK, 0x0);

	adc_dma_read(AXI_DMAC_REG_TRANSFER_ID, &transfer_id);
	adc_dma_read(AXI_DMAC_REG_IRQ_PENDING, &reg_val);
	adc_dma_write(AXI_DMAC_REG_IRQ_PENDING, reg_val);

	adc_dma_write(AXI_DMAC_REG_DEST_ADDRESS, address);
	adc_dma_write(AXI_DMAC_REG_DEST_STRIDE, 0x0);
	adc_dma_write(AXI_DMAC_REG_X_LENGTH, length - 1);
	adc_dma_write(AXI_DMAC_REG_Y_LENGTH, 0x0);

	adc_dma_write(AXI_DMAC_REG_START_TRANSFER, 0x1);
	/* Wait until the new transfer is queued. */
	do {
		adc_dma_read(AXI_DMAC_REG_START_TRANSFER, &reg_val);
	}
	while(reg_val == 1);

	/* Wait until the current transfer is completed. */
	do {
		adc_dma_read(AXI_DMAC_REG_IRQ_PENDING, &reg_val);
	}
	while(reg_val != (AXI_DMAC_IRQ_SOT | AXI_DMAC_IRQ_EOT));
	adc_dma_write(AXI_DMAC_REG_IRQ_PENDING, reg_val);

	/* Wait until the transfer with the ID transfer_id is completed. */
	do {
		adc_dma_read(AXI_DMAC_REG_TRANSFER_DONE, &reg_val);
	}
	while((reg_val & (1 << transfer_id)) != (1 << transfer_id));

#ifdef _XPARAMETERS_PS_H_
    Xil_DCacheFlush();
#else
    microblaze_flush_dcache();
    microblaze_invalidate_dcache();
#endif
}
void
enable_caches()
{
#ifdef __PPC__
    XCache_EnableICache(CACHEABLE_REGION_MASK);
    XCache_EnableDCache(CACHEABLE_REGION_MASK);
#elif __MICROBLAZE__
#ifdef XPAR_MICROBLAZE_USE_ICACHE
    microblaze_invalidate_icache();
    microblaze_enable_icache();
#endif
#ifdef XPAR_MICROBLAZE_USE_DCACHE
    microblaze_invalidate_dcache();
    microblaze_enable_dcache();
#endif
#endif
}
Пример #3
0
int main() {
    proc_interface_t hwti;
	 
    // Get HWTI base address from user PVR register
    int hwti_base;
    getpvr(1,hwti_base);

    // Disable instruction and data cache
    microblaze_invalidate_icache();
    microblaze_disable_icache();
    microblaze_invalidate_dcache();
	 microblaze_disable_dcache();
    // Nano-kernel loop...
    while(1) {
        // Setup interface
		// * Perform this upon each iteration, just in case the memory
		//   map for the MB-HWTI is corrupted.
	    initialize_interface(&hwti,(int*)(hwti_base));

#if 0   // Commented out as this is not necessary and it creates the opportunity for a race between reset and start commands
        // Wait to be "reset"
		// -- NOTE: Ignore reset as it has no meaning to the MB-HWTI
		//          and it seems causes a race, as the controlling processor
		//          sends a reset, immediately followed by a "go" command.  Therefore
		//          the "reset" command can be missed.
	    wait_for_reset_command(&hwti);
        
#endif

	    // Wait to be "started"
	    wait_for_go_command(&hwti);

		//xil_printf("Thread started (fcn @ 0x%08x), arg = 0x%08x!!!\r\n",*(hwti.fcn_reg), *(hwti.arg_reg));

        // Setup r20 for thread, this can be used to enforce -fPIC (Position-independent code) for the MB
        // (r20 is used as part of the GOT, to make things PC-relative)
        mtgpr(r20, *(hwti.fcn_reg));

        // Boostrap thread (wraps up thread execution with a thread exit)
        //  * Pull out thread argument, and thread start function
        _bootstrap_thread(&hwti, *(hwti.fcn_reg), *(hwti.arg_reg));
		 
    }
    return 0;
}
void
disable_caches()
{
#ifdef __PPC__
    XCache_DisableDCache();
    XCache_DisableICache();
#elif __MICROBLAZE__
#ifdef XPAR_MICROBLAZE_USE_DCACHE
#if !XPAR_MICROBLAZE_DCACHE_USE_WRITEBACK
    microblaze_invalidate_dcache();
#endif
    microblaze_disable_dcache();
#endif
#ifdef XPAR_MICROBLAZE_USE_ICACHE
    microblaze_invalidate_icache();
    microblaze_disable_icache();
#endif
#endif
}
Пример #5
0
int main_SDHCExample()
{
    unsigned int j;
    char *filters[] = {".JPG", ".PNG", NULL};
    int status;

#if 0
#ifdef XPAR_MICROBLAZE_USE_ICACHE
    microblaze_invalidate_icache();
    microblaze_enable_icache();
#endif
#ifdef XPAR_MICROBLAZE_USE_DCACHE
    microblaze_invalidate_dcache();
    microblaze_enable_dcache();
#endif
#endif

    status = is_sd_accessible();
    if(status == -1)
    {
    	xil_printf("SD card is not accessible.. insert properly and rerun\n");
    	return -1;
    }

    /* Initialize FATFS and timer */
    f_mount(0, &fs);
#ifdef MEASURE_SPEED
    swConfig_initTimerSubsystem();
#endif

    /* Scan file structure */
    scan_files_recursive("");	// param: parent path
    xil_printf("total files: %d\n", file_counter);
    filter_file_list(filters, filter_filename_string, MAX_NUM_OF_FILES_TO_COPY,32);

#ifdef COPY_FILES
    /* Copy and verify all scanned files */
    for(j = 0;j < file_counter; j++)
    {
    	//xil_printf("%s\n", in_filename_string[j]);

		#if 0
        PRINT("\n\rCopying file %d of %d...\n\r", (j + 1), file_counter);
        if((strlen(in_filename_string[j]) > (8 + 3 + 1)) || (strlen(out_filename_string[j]) > (8 + 3 + 1)))
        {
            PRINT("\n\rFilename %s is to long for filesystem!\n\r", out_filename_string[j]);
            PRINT("Only filenames of max 8 + 3 characters(xxxxxxxx.yyy) are supported\n\r\n\r");
        }
        else
        {
            copy_file(in_filename_string[j], out_filename_string[j]);
        }
		#endif
    }
#endif

#ifdef MEASURE_SPEED
    printf("Top write speed = %8.2f for data size = %8d\n\r", top_write_speed, top_write_data_size);
    printf("Top read speed = %8.2f for data size = %8d\n\r", top_read_speed, top_read_data_size);
#endif

    f_mount(0, (FATFS *)0);

    PRINT("SD Card test end\n\r");
    //while(1);

    return 0;
}
int main(void)
{
	int Status;

   /*
    * Enable and initialize cache
    */
#if !SIM

   #if XPAR_MICROBLAZE_0_USE_ICACHE
      microblaze_invalidate_icache();
      microblaze_enable_icache();
   #endif

   #if XPAR_MICROBLAZE_0_USE_DCACHE
      microblaze_invalidate_dcache();
       microblaze_enable_dcache();
   #endif
#endif


	XUartNs550_SetBaud(UART_BASEADDR, UART_CLOCK, UART_BAUDRATE);
	XUartNs550_SetLineControlReg(UART_BASEADDR, XUN_LCR_8_DATA_BITS);


  xil_printf("\n\r********************************************************");
  xil_printf("\n\r********************************************************");
  xil_printf("\n\r**     SP605 - Temac Test                             **");
  xil_printf("\n\r********************************************************");
  xil_printf("\n\r********************************************************\r\n");

	printf("Setting Temac and DMA\r\n");
    printf("\r\n");

	/*
	 * Call the Temac SGDMA interrupt example , specify the parameters generated
	 * in xparameters.h
	 */
	Status = TemacSgDmaIntrExample(&IntcInstance,
				       &TemacInstance,
				       &DmaInstance,
				       TEMAC_DEVICE_ID,
				       TEMAC_IRPT_INTR,
				       DMA_RX_IRPT_INTR, DMA_TX_IRPT_INTR);
	if (Status != XST_SUCCESS) {
		TemacUtilErrorTrap("Failure in Examples");
		return XST_FAILURE;
	}

    printf("Received Packet!\r\n");
    printf("\r\n");

#if !SIM

   #if XPAR_MICROBLAZE_0_USE_DCACHE
      microblaze_disable_dcache();
      microblaze_invalidate_dcache();
   #endif

   #if XPAR_MICROBLAZE_0_USE_ICACHE
      microblaze_disable_icache();
      microblaze_invalidate_icache();
   #endif
#endif

	return_to_loader();

	return 0;

}
int main() {
	XStatus Status;
	u32 btnsw = 0x00000000, old_btnsw = 0x000000FF, diff_btnsw;
	u32 leds;
	int rotcnt, old_rotcnt;
	Test_t test;
	ParamSel_t param_select;

	bool wrlcd_dynamic;
	bool wrlcd_static;

	// initialize devices and set up interrupts, etc.
	Status = do_init();
	if (Status != XST_SUCCESS) {
		LCD_setcursor(1, 0);
		LCD_wrstring("****** ERROR *******");
		LCD_setcursor(2, 0);
		LCD_wrstring("INIT FAILED- EXITING");
		exit(XST_FAILURE);
	}

	// initialize the global variables
	timestamp = 0;
	pwm_freq = PWM_FREQUENCY_HZ;
	pwm_duty = PWM_STEPDC_MIN;

	// initialize the local variables
	btnsw = 0x00;
	old_btnsw = 0x00;
	rotcnt = 0;
	old_rotcnt = 0;
	param_select = SLCT_GP;
	wrlcd_dynamic = true;
	wrlcd_static = true;
	leds = LEDS_ALLOFF;
	_prev_button_down_count = 0;
	// Enable the Microblaze caches and
	// kick off the processing by enabling the Microblaze interrupt
	// this starts the FIT timer which updates the timestamp.
	if (USE_ICACHE == 1) {
		microblaze_invalidate_icache();
		microblaze_enable_icache();
	}
	if (USE_DCACHE == 1) {
		microblaze_invalidate_dcache();
		microblaze_enable_dcache();
	}
	microblaze_enable_interrupts();

	// display the greeting
	LCD_setcursor(1, 0);
	LCD_wrstring("ECE544 Project 2");
	LCD_setcursor(2, 0);
	LCD_wrstring("Starter App-R5.0");
	NX3_writeleds(LEDS_ALLON);
	delay_msecs(2000);
	NX3_writeleds(LEDS_ALLOFF);

	// Set the PWM and ADC min and max counts by forcing a characterization
	LCD_clrd();
	LCD_setcursor(1, 0);
	LCD_wrstring("Characterizing..");
	DoTest_Characterize();
	LCD_setcursor(2, 0);
	LCD_wrstring("...Done         ");

	//*****GAIN AND OFFSET ARE HARDWIRED IN THE STARTER APP *****
	// initialize the control parameters
	// start the set point in the middle of the range	
	setpoint = (ADC_max_cnt - ADC_min_cnt) / 2;
	offset = 100;
	GP = 10;
	GD = 5;
	GI = 5;
	init_high = false;
	//*****GAIN AND OFFSET ARE HARDWIRED IN THE STARTER APP *****


	// main loop - there is no exit except by hardware reset
	while (1) {
		// write static portion of output to display
		if (wrlcd_static) {
			LCD_clrd();
			LCD_setcursor(1, 0);
			LCD_wrstring("G|Pxxx Ixxx Dxxx");
			LCD_setcursor(2, 0);
			LCD_wrstring("SP:+x.xx OFF:xxx");
			wrlcd_static = false;
		}

		// write the dynamic portion of output to display
		if (wrlcd_dynamic) {
			Xfloat32 v;
			u16 count;
			char s[20];
			u32 row, col;

			// display GP, GI, and GD
			LCD_setcursor(1, 3);
			LCD_wrstring("   ");
			LCD_setcursor(1, 3);
			LCD_putnum(GP, 10);

			LCD_setcursor(1, 8);
			LCD_wrstring("   ");
			LCD_setcursor(1, 8);
			LCD_putnum(GI, 10);

			LCD_setcursor(1, 13);
			LCD_wrstring("   ");
			LCD_setcursor(1, 13);
			LCD_putnum(GD, 10);

			LCD_setcursor(2, 13);
			LCD_wrstring("   ");
			LCD_setcursor(2, 13);
			LCD_putnum(offset, 10);

			// display the setpoint in volts
			count = setpoint;
			v = PmodCtlSys_ADCVolts(count);
			voltstostrng(v, s);
			LCD_setcursor(2, 3);
			LCD_wrstring("     ");
			LCD_setcursor(2, 3);
			LCD_wrstring(s);

			// place the cursor under the currently selected parameter
			LCD_docmd(LCD_DISPLAYONOFF, LCD_CURSOR_OFF);
			switch (param_select) {
				case SLCT_OFFSET:
					row = 2;
					col = 13;
					break;
				case SLCT_GP:
					row = 1;
					col = 3;
					break;
				case SLCT_GD:
					row = 1;
					col = 13;
					break;
				case SLCT_GI:
					row = 1;
					col = 8;
					break;
				case SLCT_INVALID:
					break;
			}
			if (param_select != SLCT_INVALID) {
				LCD_setcursor(row, col);
				LCD_docmd(LCD_DISPLAYONOFF, LCD_CURSOR_ON);
			}
			wrlcd_dynamic = false;
		}

		// read switches and buttons to get the test to perform and its initial value
		// display the selected test on the LEDs   
		NX3_readBtnSw(&btnsw);
		init_high = (btnsw & SW_INIT_HILO) ? true : false;
		test = btnsw & SW_TEST_SELECT;

		//update the HI/LO and TEST LEDs
		leds &= ~(LEDS_HILO | LEDS_TEST);
		leds |= (init_high == true) ? LEDS_HILO : 0;
		leds |= test << 3;
		NX3_writeleds(leds);

		// read rotary count and handle setpoint changes
		// accelerate setpoint if speedup threshold has been exceeded
		// Use MIN and MAX to keep scaled ADC count within range
		ROT_readRotcnt(&rotcnt);
		if (rotcnt != old_rotcnt) {
			if (abs(rotcnt - old_rotcnt) > ROTCNT_SPEEDUP_GATE) {
				setpoint += (rotcnt - old_rotcnt) * ROTCNT_DELTA
						* ROTCNT_SPEEDUP_FACTOR;
			} else {
				setpoint += (rotcnt - old_rotcnt) * ROTCNT_DELTA;
			}
			setpoint = MAX(ADC_min_cnt, MIN(setpoint, ADC_max_cnt));
			old_rotcnt = rotcnt;
			wrlcd_dynamic = true;
		} // rotary count changed

		//***** NOTE:  User interface handling should go in this section.  *****
		//***** The starter app just lets the user select the setpoint and *****
		//***** run the test selected by the switches                      *****

		// look at the buttons and take action on the rising edge of a button press
		bool north_button = btnsw & msk_BTN_NORTH;
		bool east_button = btnsw & msk_BTN_EAST;
		bool west_button = btnsw & msk_BTN_WEST;
		bool button_down = north_button || east_button || west_button;

		if (button_down)
		{
			_prev_button_down_count++;
			if (_prev_button_down_count > 5)
				_prev_button_down_count = 5;

			if (north_button) {
				switch (param_select) {
					case SLCT_GP:
						param_select = SLCT_GI;
						break;
					case SLCT_GI:
						param_select = SLCT_GD;
						break;
					case SLCT_GD:
						param_select = SLCT_OFFSET;
						break;
					case SLCT_OFFSET:
						param_select = SLCT_GP;
						break;					
				}
				wrlcd_dynamic = true;
			}

			if (east_button) {
				switch (param_select) {
					case SLCT_GP:
						GP+=_prev_button_down_count;
						break;
					case SLCT_GI:
						GI+=_prev_button_down_count;
						break;
					case SLCT_GD:
						GD+=_prev_button_down_count;
						break;
					case SLCT_OFFSET:
						offset+=_prev_button_down_count;
						break;					
				}
				wrlcd_dynamic = true;
			}

			if (west_button) {
				switch (param_select) {
					case SLCT_GP:
						GP-=_prev_button_down_count;
						break;
					case SLCT_GI:
						GI-=_prev_button_down_count;
						break;			
					case SLCT_GD:
						GD-=_prev_button_down_count;
						break;
					case SLCT_OFFSET:
						offset-=_prev_button_down_count;
						break;					
				}
				wrlcd_dynamic = true;
			}
		} else {
			_prev_button_down_count = 0;
		}

		btnsw &= BTN_MSK_ALLBUTTONS;
		diff_btnsw = (btnsw ^ old_btnsw) & btnsw;
		old_btnsw = btnsw;

		if (diff_btnsw & BTN_RUN_XFER) // run a test
		{
			Xfloat32 vADC, vSP; // VADC from circuit and Vsetpoint
			char s1[20], s2[30]; // display and print strings
			int (*funcPtr)(void); // pointer to test function
			int n; // number of samples to transfer (returned by test functions)

			switch (test) // set up for the selected test
			{
				case TEST_BB: // Bit Bang control
					strcpy(s1, "|BB  |Press RBtn");
					strcpy(s2, "Bit Bang Control Test Data");
					funcPtr = DoTest_BB;
					break;
				case TEST_PID: // PID control
					strcpy(s1, "|PID |Press RBtn");
					strcpy(s2, "PID Control Test Data");
					funcPtr = DoTest_PID;
					break;
				case TEST_CHARACTERIZE: // characterize control system simulator
					strcpy(s1, "|CHAR|Press RBtn");
					strcpy(s2, "Characterization Test Data");
					funcPtr = DoTest_Characterize;
					break;
				default: // no test to run
					strcpy(s1, "");
					strcpy(s2, "");
					funcPtr = NULL;
					break;
			}

			// Change the display to indicate that a test will be run			
			LCD_clrd();
			LCD_setcursor(1, 0);
			LCD_wrstring(s1);
			LCD_setcursor(2, 0);
			LCD_wrstring("LED OFF-Release ");

			// turn on Run LED to show the test has begun
			// and do the test.  The test will return when the ADC samples array
			// has been filled.  Turn off the rightmost LED after the data has been 
			// captured to let the user know he/she can release the button
			if (funcPtr != NULL) {
				leds |= LEDS_RUN;
				NX3_writeleds(leds);
				n = funcPtr();
				leds &= ~LEDS_RUN;
				NX3_writeleds(leds);
				// wait for the Rotary Encoder button to be released
				// and then send the sample data to stdout
				do {
					NX3_readBtnSw(&btnsw);
					delay_msecs(10);
				} while (btnsw & BTN_RUN_XFER);

				// turn on Transfer LED to indicate that data is being transmitted
				// Show the transfer  traffic on the LCD
				leds |= LEDS_XFER;
				NX3_writeleds(leds);
				LCD_clrd();
				LCD_setcursor(1, 0);
				LCD_wrstring("Sending Data....");
				LCD_setcursor(2, 0);
				LCD_wrstring("S:    DATA:     ");

				// transfer the descriptive heading followed by the data	
				xil_printf("\n\r%s\tAppx. Sample Interval: %d msec\n\r", s2,
						adc_smple_interval);
				xil_printf("sample\tADCCount\tVout\tsetpoint\tPWMCount\n\r");

				// tell SerialCharter to start gathering data)
				xil_printf("===STARTPLOT===\n");

				for (smpl_idx = 2; smpl_idx < n; smpl_idx++) {
					u16 count;

					count = sample[smpl_idx];
					vADC = PmodCtlSys_ADCVolts(count);
					vSP = PmodCtlSys_ADCVolts(setpoint);
					voltstostrng(vADC, s1);
					voltstostrng(vSP, s2);
					xil_printf("%d\t%d\t%s\t%s\t%d\n\r", smpl_idx, count, s1,
							s2, PIDdebug[smpl_idx].pwm_count);
					LCD_setcursor(2, 2);
					LCD_wrstring("   ");
					LCD_setcursor(2, 2);
					LCD_putnum(smpl_idx, 10);
					LCD_setcursor(2, 11);
					LCD_wrstring("     ");
					LCD_setcursor(2, 11);
					LCD_putnum(count, 10);
				}

				// tell SeriaCharter to stop gathering data and display the graph			
				xil_printf("===ENDPLOT===\n");

				// transfer complete - turn Transfer LED off and wrap up command processing
				leds &= ~LEDS_XFER;
				NX3_writeleds(leds);
				wrlcd_static = true;
				wrlcd_dynamic = true;
			}
		} // run a test

		// wait a bit and start again
		delay_msecs(100);
	} // while(1) loop
} // end main()
Пример #8
0
int main()
{
    XStatus 	Status;
    u32			btnsw = 0x00000000, old_btnsw = 0x000000FF;
    int			rotcnt, old_rotcnt = 0x1000;
    Test_t		test, next_test;
    is_scaled = false;
    bool lcd_initial = true;
    char 		sp[20];
    u16 row = 1;
    u16 col = 2;
    bool calc_done = false;
    freq_min_cnt = 3000;


    // initialize devices and set up interrupts, etc.
    Status = do_init();
    if (Status != XST_SUCCESS)
    {
        LCD_setcursor(1,0);
        LCD_wrstring("****** ERROR *******");
        LCD_setcursor(2,0);
        LCD_wrstring("INIT FAILED- EXITING");
        exit(XST_FAILURE);
    }

    // initialize the variables
    timestamp = 0;
    pwm_freq = PWM_FREQUENCY;
    next_test = TEST_INVALID;

    prop_gain     = PROP_INIT_GAIN;
    integral_gain = INT_INIT_GAIN;
    deriv_gain    = DERIV_INIT_GAIN;


    // Enable the Microblaze caches and kick off the processing by enabling the Microblaze
    // interrupt.  This starts the FIT timer which updates the timestamp.
    if (USE_ICACHE == 1)
    {
        microblaze_invalidate_icache();
        microblaze_enable_icache();
    }
    if (USE_DCACHE == 1)
    {
        microblaze_invalidate_dcache();
        microblaze_enable_dcache();
    }
    microblaze_enable_interrupts();

    // display the greeting
    LCD_setcursor(1,0);
    LCD_wrstring("PWM Ctrl sys");
    LCD_setcursor(2,0);
    LCD_wrstring("Erik R, Caren Z");
    NX3_writeleds(0xFF);
    //delay_msecs(2500);

    LCD_clrd();
    LCD_setcursor(1,0);
    LCD_wrstring("Characterizing..");
    //Run the LED characterization routine to establish sensor min's and max's
    DoTest_Characterize();
    LCD_setcursor(2,0);
    LCD_wrstring("Done.");



    NX3_writeleds(0x00);

    delay_msecs(500);
    //set initial screen
    // main loop - there is no exit except by hardware reset
    while (1)
    {
        //set Vin to min or max depending on switch 3 value
        if (btnsw & msk_SWITCH3)
        {
            pwm_duty = MAX_DUTY;
            dc_start = MAX_DUTY;
        }
        else
        {
            pwm_duty = MIN_DUTY;
            dc_start = MIN_DUTY;
        }

        // Write values to display when in "idle" state
        if (lcd_initial)
        {
            LCD_clrd();
            LCD_setcursor(1,0);
            LCD_wrstring("P:   I:   D:   ");
            LCD_setcursor(1,2);
            LCD_setcursor(2,0);
            LCD_wrstring("SP:+     OFF:   ");
            lcd_initial = false;
            LCD_setcursor(1,2);
        }
        no_test_LCD();
        NX3_readBtnSw(&btnsw);
        // Set which control measurement we're using
        if (btnsw & msk_BTN_NORTH)
        {
            // increment to the next selection.  If we're at the last enum, set it to the 1st (proportional)
            if (PID_current_sel == OFFSET) PID_current_sel = PROPORTIONAL;
            else PID_current_sel = (Control_t)((int)(PID_current_sel+1));  //casting to allow increment

            // cursor control logic
            if (PID_current_sel == PROPORTIONAL)
            {
                row = 1;
                col = 2;
            }
            else if (PID_current_sel == INTEGRAL)
            {
                row = 1;
                col = 7;
            }
            else if (PID_current_sel == DERIVATIVE)
            {
                row = 1;
                col = 12;
            }
            else if (PID_current_sel == OFFSET)
            {
                row  = 2;
                col  = 13;
            }
        }

        delay_msecs(20);
        //set cursor location and turn on cursor
        LCD_setcursor(row,col);
        LCD_docmd(LCD_DISPLAYONOFF, LCD_CURSOR_ON);

        if (btnsw & msk_BTN_EAST)
        {
            if (PID_current_sel == PROPORTIONAL)     prop_gain     += GAIN_INCREMENT;
            else if (PID_current_sel == INTEGRAL)    integral_gain += GAIN_INCREMENT;
            else if (PID_current_sel == DERIVATIVE)  deriv_gain    += GAIN_INCREMENT;
            else                                     offset        += GAIN_INCREMENT;
        }
        if (btnsw & msk_BTN_WEST)
        {
            if (PID_current_sel == PROPORTIONAL)     prop_gain     -= GAIN_INCREMENT;
            else if (PID_current_sel == INTEGRAL)    integral_gain -= GAIN_INCREMENT;
            else if (PID_current_sel == DERIVATIVE)  deriv_gain    -= GAIN_INCREMENT;
            else                                     offset        -= GAIN_INCREMENT;
        }


        // read sw[1:0] to get the test to perform.
        NX3_readBtnSw(&btnsw);
        test = btnsw & (msk_SWITCH1 | msk_SWITCH0);

        ROT_readRotcnt(&rotcnt);
        if (rotcnt != old_rotcnt)
        {
            //scale rotary count to setpoint values
            LCD_docmd(LCD_DISPLAYONOFF, LCD_CURSOR_OFF);
            setpoint = MAX(VOLT_MIN, MIN((rotcnt/SETPOINT_SCALE), VOLT_MAX));
            voltstostrng(setpoint, sp);
            old_rotcnt = rotcnt;
            LCD_setcursor(2, 3);
            LCD_wrstring(sp);
            LCD_setcursor(2, 3);
            LCD_wrstring('+');
        }

        if (test == TEST_T_CALLS) //unused
        {
            next_test = TEST_INVALID;
            lcd_initial = true;
            delay_msecs(3000);

        }


        else if ((test == TEST_BANG ) || (test == TEST_PID))  // Test 1 & 2 - control methods Bang Bang and PID
        {
            Xfloat32	v;
            char		s[20];

            // start the test on the rising edge of the Rotary Encoder button press
            // the test will write the light detector samples into the global "sample[]"
            // the samples will be sent to stdout when the Rotary Encoder button
            // is released
            //
            // NOTE ON DETECTING BUTTON CHANGES:
            // btnsw ^ old_btnsw will set the bits for all of the buttons and switches that
            // have changed state since the last time the buttons and switches were read
            // msk_BTN_ROT & btnsw will test whether the rotary encoder was one of the
            // buttons that changed from 0 -> 1

            if ((btnsw ^ old_btnsw) && (msk_BTN_ROT & btnsw))  // do the step test and dump data
            {

                /*Running Test (rotary pushbutton pushed): Show which control algorithm is running and
                  display instructions for running test and uploading data.*/

                if (test != next_test)
                {
                    if (test == TEST_BANG)
                    {
                        strcpy(s, "|BANG|Long Press");
                    }
                    else
                    {
                        strcpy(s, "|PID|Long Press");
                    }
                    delay_msecs(100);
                    LCD_clrd();
                    LCD_setcursor(1,0);
                    LCD_wrstring(s);
                    LCD_setcursor(2,0);
                    LCD_wrstring("RotBtn to start");
                }

                NX3_writeleds(0x01);
                if (test == TEST_BANG)  // perform bang bang calculations
                {
                    calc_bang();
                }
                else  // perform PID tests
                {
                    calc_PID();
                }
                NX3_writeleds(0x00);

                //FEATURE: wait for user input to send data over
                NX3_readBtnSw(&btnsw);
                if ((btnsw ^ old_btnsw) && (msk_BTN_ROT & btnsw))
                {
                    // light "Transfer" LED to indicate that data is being transmitted
                    // Show the traffic on the LCD
                    NX3_writeleds(0x02);
                    LCD_clrd();
                    LCD_setcursor(1, 0);
                    LCD_wrstring("Sending Data....");
                    LCD_setcursor(2, 0);
                    LCD_wrstring("S:    DATA:     ");

                    // print the descriptive heading followed by the data
                    if (test == TEST_BANG)
                    {
                        xil_printf("\n\rBang Bang! Test Data\t\tAppx. Sample Interval: %d msec\n\r", frq_smple_interval);
                    }
                    else
                    {
                        xil_printf("\n\rPID Test Data\t\tAppx. Sample Interval: %d msec\n\r", frq_smple_interval);
                    }

                    // trigger the serial charter program)
                    xil_printf("===STARTPLOT===\n");

                    // start with the second sample.  The first sample is not representative of
                    // the data.  This will pretty-up the graph a bit
                    for (smpl_idx = 1; smpl_idx < NUM_FRQ_SAMPLES; smpl_idx++)
                    {
                        u16 count;

                        count = sample[smpl_idx];
                        if (count > 4096)
                            count = 4095;

                        v = (-3.3 / 4095.0) * (count) + 3.3;

                        voltstostrng(v, s);
                        xil_printf("%d\t%d\t%s\n\r", smpl_idx, count, s);

                        LCD_setcursor(2, 2);
                        LCD_wrstring("   ");
                        LCD_setcursor(2, 2);
                        LCD_putnum(smpl_idx, 10);
                        LCD_setcursor(2, 11);
                        LCD_wrstring("     ");
                        LCD_setcursor(2, 11);
                        LCD_putnum(count, 10);
                    }

                    // stop the serial charter program
                    xil_printf("===ENDPLOT===\n");

                    NX3_writeleds(0x00);
                    old_btnsw = btnsw;
                    next_test = TEST_INVALID;
                    lcd_initial = true;
                    delay_msecs(3000);
                }
            }  // do the step test and dump data

        }
        else if (test == TEST_CHARACTERIZE)  // Test 3 - Characterize Response
        {

            // start the test on the rising edge of the Rotary Encoder button press
            // the test will write the samples into the global "sample[]"
            // the samples will be sent to stdout when the Rotary Encoder button
            // is released
            NX3_readBtnSw(&btnsw);
            if ((btnsw ^ old_btnsw) && (msk_BTN_ROT & btnsw))
            {
                LCD_docmd(LCD_DISPLAYONOFF, LCD_CURSOR_OFF);
                // light "Run" (rightmost) LED to show the test has begun
                // and do the test.  The test will return when the measured samples array
                // has been filled.  Turn off the rightmost LED after the data has been
                if (test != next_test)
                {
                    LCD_clrd();
                    LCD_setcursor(1,0);
                    LCD_wrstring("|CHAR|Long Press");
                    LCD_setcursor(2,0);
                    LCD_wrstring("RotBtn to start");
                }
                // captured to let the user know he/she can release the button
                NX3_readBtnSw(&btnsw);
                if ((msk_BTN_ROT & btnsw) && (!calc_done))
                {
                    NX3_writeleds(0x01);
                    LCD_clrd();
                    LCD_setcursor(1,0);
                    LCD_wrstring("Characterizing..");
                    DoTest_Characterize();
                    LCD_setcursor(2,0);
                    LCD_wrstring("Done.");
                    NX3_writeleds(0x00);
                    delay_msecs(750);
                    LCD_setcursor(2,8);
                    LCD_wrstring("<OK>");
                    calc_done = true;
                    next_test = test;
                }

                NX3_readBtnSw(&btnsw);
                if (msk_BTN_ROT & btnsw)
                {
                    // light "Transfer" LED to indicate that data is being transmitted
                    // Show the traffic on the LCD
                    NX3_writeleds(0x02);
                    LCD_clrd();
                    LCD_setcursor(1, 0);
                    LCD_wrstring("Sending Data....");
                    LCD_setcursor(2, 0);
                    LCD_wrstring("S:    DATA:     ");

                    xil_printf("\n\rCharacterization Test Data\t\tAppx. Sample Interval: %d msec\n\r", frq_smple_interval);

                    // trigger the serial charter program)
                    xil_printf("===STARTPLOT===\n\r");

                    for (smpl_idx = STEPDC_MIN; smpl_idx <= STEPDC_MAX; smpl_idx++)
                    {
                        u16 		count;
                        Xfloat32	v;
                        char		s[10];

                        count = sample[smpl_idx];
                        if (count > 4096)
                            count = 4095;

                        v = (-3.3 / 4095.0) * (count) + 3.3;

                        voltstostrng(v, s);
                        xil_printf("%d\t%d\t%s\n\r", smpl_idx, count, s);

                        LCD_setcursor(2, 2);
                        LCD_wrstring("   ");
                        LCD_setcursor(2, 2);
                        LCD_putnum(smpl_idx, 10);
                        LCD_setcursor(2, 11);
                        LCD_wrstring("     ");
                        LCD_setcursor(2, 11);
                        LCD_putnum(count, 10);
                    }

                    // stop the serial charter program
                    xil_printf("===ENDPLOT===\n\r");

                    NX3_writeleds(0x00);
                    old_btnsw = btnsw;
                    next_test = TEST_INVALID;
                    delay_msecs(1000);
                    lcd_initial = true;
                    delay_msecs(3000);
                }
            }  // do the step test and dump data

        } // Test 3 - Characterize Response
        else  // outside the current test range - blink LED's and hang
        {
            // should never get here but just in case
            NX3_writeleds(0xFF);
            delay_msecs(2000);
            NX3_writeleds(0x00);
        }
        // wait a bit and start again

        delay_msecs(100);
    }  // while(1) loop
}  // end main()
int main()
{
	XStatus 	Status;
	u32			btnsw = 0x00000000, old_btnsw = 0x000000FF;
	int			rotcnt, old_rotcnt = 0x1000;
	Test_t		test, next_test;
	is_scaled = false;
	
	// initialize devices and set up interrupts, etc.
 	Status = do_init();
 	if (Status != XST_SUCCESS)
 	{
 		LCD_setcursor(1,0);
 		LCD_wrstring("****** ERROR *******");
 		LCD_setcursor(2,0);
 		LCD_wrstring("INIT FAILED- EXITING");
 		exit(XST_FAILURE);
 	}

	// initialize the variables
	timestamp = 0;							
	pwm_freq = PWM_FREQUENCY;
	pwm_duty = STEPDC_MIN;
	next_test = TEST_INVALID;

	// Enable the Microblaze caches and kick off the processing by enabling the Microblaze
	// interrupt.  This starts the FIT timer which updates the timestamp.
	if (USE_ICACHE == 1)
	{
		microblaze_invalidate_icache();
		microblaze_enable_icache();
	}
	if (USE_DCACHE == 1)
	{
		microblaze_invalidate_dcache();
		microblaze_enable_dcache();
	}
	microblaze_enable_interrupts();
	 	  	
 	// display the greeting   
    LCD_setcursor(1,0);
    LCD_wrstring("PmodCtlSys Test ");
	LCD_setcursor(2,0);
	LCD_wrstring("R3.0 by Robin M.");
	NX3_writeleds(0xFF);
	//Run the LED characterization routine to establish sensor min's and max's
    DoTest_Characterize();
	NX3_writeleds(0x00);
       
    // main loop - there is no exit except by hardware reset
	while (1)
	{ 
		// read sw[1:0] to get the test to perform.
		NX3_readBtnSw(&btnsw);
		test = btnsw & (msk_SWITCH1 | msk_SWITCH0);
			
		if (test == TEST_TRACKING)  // Test 0 = Track PWM voltage
		{
			// write the static info to display if necessary
			if (test != next_test)
			{
				LCD_clrd();
				LCD_setcursor(1,0);
				LCD_wrstring("| TRK| Vi: sx.xx");
				LCD_setcursor(2,0);
				LCD_wrstring("Vo:sx.xx C:sxxxx");
			}
				 						
			// read rotary count and handle duty cycle changes
			// limit duty cycle to between STEPDC_MIN and STEPDC_MAX
			// PWM frequency does not change in this test
			ROT_readRotcnt(&rotcnt);
			if (rotcnt != old_rotcnt)
			{
				pwm_duty = MAX(STEPDC_MIN, MIN(rotcnt, STEPDC_MAX));
				old_rotcnt = rotcnt;
			}
			DoTest_Track();
			next_test = TEST_TRACKING;
		}   // Test 0 = Track PWM voltage
		else if ((test == TEST_STEPHILO) || (test == TEST_STEPLOHI))  // Test 1 & 2 - Step response 
		{
			Xfloat32	v;
			char		s[20];	
			
			// write the static info to the display if necessary
			if (test != next_test)
			{
				if (test == TEST_STEPHILO)
				{
					strcpy(s, "|HILO|Press RBtn");
				}
				else
				{
					strcpy(s, "|LOHI|Press RBtn");
				}
				
				LCD_clrd();
				LCD_setcursor(1,0);
				LCD_wrstring(s);
				LCD_setcursor(2,0);
				LCD_wrstring("LED OFF-Release ");
			}
			
			// start the test on the rising edge of the Rotary Encoder button press
			// the test will write the light detector samples into the global "sample[]"
			// the samples will be sent to stdout when the Rotary Encoder button
			// is released
			//
			// NOTE ON DETECTING BUTTON CHANGES:
			// btnsw ^ old_btnsw will set the bits for all of the buttons and switches that
			// have changed state since the last time the buttons and switches were read
			// msk_BTN_ROT & btnsw will test whether the rotary encoder was one of the
			// buttons that changed from 0 -> 1	
			if ((btnsw ^ old_btnsw) && (msk_BTN_ROT & btnsw))  // do the step test and dump data  
			{										
				// light "Run" (rightmost) LED to show the test has begun
				// and do the test.  The test will return when the measured samples array
				// has been filled.  Turn off the rightmost LED after the data has been 
				// captured to let the user know he/she can release the button
				NX3_writeleds(0x01);
				if (test == TEST_STEPHILO)  // perform High->Low step test
				{				
					DoTest_Step(STEPDC_MAX);
				}
				else  // perform Low->High step
				{
					DoTest_Step(STEPDC_MIN);
				}
				NX3_writeleds(0x00);
				
				// wait for the Rotary Encoder button to be released
				// and then send the sample data to stdout
				do
				{
					NX3_readBtnSw(&btnsw);
					delay_msecs(10);
				} while ((btnsw & msk_BTN_ROT) == 0x80);
				
				// light "Transfer" LED to indicate that data is being transmitted
				// Show the traffic on the LCD
				NX3_writeleds(0x02);
				LCD_clrd();
				LCD_setcursor(1, 0);
				LCD_wrstring("Sending Data....");
				LCD_setcursor(2, 0);
				LCD_wrstring("S:    DATA:     ");

				// print the descriptive heading followed by the data
				if (test == TEST_STEPHILO)
				{
					xil_printf("\n\rHigh->Low Test Data\t\tAppx. Sample Interval: %d msec\n\r", frq_smple_interval);
				}
				else
				{
					xil_printf("\n\rLow->High Test Data\t\tAppx. Sample Interval: %d msec\n\r", frq_smple_interval);
				}
				
				// trigger the serial charter program)
				xil_printf("===STARTPLOT===\n");

				// start with the second sample.  The first sample is not representative of
				// the data.  This will pretty-up the graph a bit								
				for (smpl_idx = 1; smpl_idx < NUM_FRQ_SAMPLES; smpl_idx++)
				{
					u16 count;
					
					count = sample[smpl_idx];
					
					//ECE544 Students:
                    //Convert from count to 'volts'
					v = LIGHTSENSOR_Count2Volts(count);
					
					voltstostrng(v, s);
					xil_printf("%d\t%d\t%s\n\r", smpl_idx, count, s);
					
					LCD_setcursor(2, 2);
					LCD_wrstring("   ");
					LCD_setcursor(2, 2);
					LCD_putnum(smpl_idx, 10);
					LCD_setcursor(2, 11);
					LCD_wrstring("     ");
					LCD_setcursor(2, 11);
					LCD_putnum(count, 10);
				}
				
				// stop the serial charter program				
				xil_printf("===ENDPLOT===\n");
				
				NX3_writeleds(0x00);
				old_btnsw = btnsw;								
				next_test = TEST_INVALID;			
			}  // do the step test and dump data
			else
			{
				next_test = test;
			}
		} // Test 1 & 2 - Step response
		else if (test == TEST_CHARACTERIZE)  // Test 3 - Characterize Response
		{
			if (test != next_test)
			{				
				LCD_clrd();
				LCD_setcursor(1,0);
				LCD_wrstring("|CHAR|Press RBtn");
				LCD_setcursor(2,0);
				LCD_wrstring("LED OFF-Release ");
			}
			// start the test on the rising edge of the Rotary Encoder button press
			// the test will write the samples into the global "sample[]"
			// the samples will be sent to stdout when the Rotary Encoder button
			// is released
			if ((btnsw ^ old_btnsw) && (msk_BTN_ROT & btnsw))  // do the step test and dump data  
			{
				// light "Run" (rightmost) LED to show the test has begun
				// and do the test.  The test will return when the measured samples array
				// has been filled.  Turn off the rightmost LED after the data has been
				// captured to let the user know he/she can release the button
				NX3_writeleds(0x01);			
				DoTest_Characterize();
				NX3_writeleds(0x00);
				
				// wait for the Rotary Encoder button to be released
				// and then send the sample data to stdout
				do
				{
					NX3_readBtnSw(&btnsw);
					delay_msecs(10);
				} while ((btnsw & msk_BTN_ROT) == 0x80);
				
				// light "Transfer" LED to indicate that data is being transmitted
				// Show the traffic on the LCD
				NX3_writeleds(0x02);
				LCD_clrd();
				LCD_setcursor(1, 0);
				LCD_wrstring("Sending Data....");
				LCD_setcursor(2, 0);
				LCD_wrstring("S:    DATA:     ");

				xil_printf("\n\rCharacterization Test Data\t\tAppx. Sample Interval: %d msec\n\r", frq_smple_interval);

				// trigger the serial charter program)
				xil_printf("===STARTPLOT===\n\r");
				
				for (smpl_idx = STEPDC_MIN; smpl_idx <= STEPDC_MAX; smpl_idx++)
				{
					u16 		count;
					Xfloat32	v;
					char		s[10]; 
					
					count = sample[smpl_idx];
					
					//ECE544 Students:
                    //Convert from count to 'volts'
					v = LIGHTSENSOR_Count2Volts((Xuint32)count);
					
					voltstostrng(v, s);
					xil_printf("%d\t%d\t%s\n\r", smpl_idx, count, s);

					LCD_setcursor(2, 2);
					LCD_wrstring("   ");
					LCD_setcursor(2, 2);
					LCD_putnum(smpl_idx, 10);
					LCD_setcursor(2, 11);
					LCD_wrstring("     ");
					LCD_setcursor(2, 11);
					LCD_putnum(count, 10);
				}

				// stop the serial charter program				
				xil_printf("===ENDPLOT===\n\r");
				
				NX3_writeleds(0x00);
				old_btnsw = btnsw;								
				next_test = TEST_INVALID;
			}  // do the step test and dump data
			else
			{
				next_test = test;
			}
		} // Test 3 - Characterize Response
		else  // outside the current test range - blink LED's and hang
		{
			// should never get here but just in case
			NX3_writeleds(0xFF);
			delay_msecs(2000);
			NX3_writeleds(0x00);
		}
		// wait a bit and start again
		delay_msecs(100);			 								
	}  // while(1) loop
 }  // end main()
Пример #10
0
int main() {
    proc_interface_t hwti;
	 
    // Get HWTI base address from user PVR register
    int hwti_base;
    unsigned char cpu_id; // only 8bits
    getpvr(1,hwti_base);
    
    // Disable instruction and data cache
    microblaze_invalidate_icache();
    microblaze_enable_icache();
    microblaze_invalidate_dcache();
	microblaze_disable_dcache();

    //Determine if uB is first on bus
    getpvr(0, cpu_id);

    // Timer pointers
    volatile unsigned long long * timer = (unsigned long long *) LOCAL_TIMER;
    volatile unsigned int * timer_reset = (unsigned int *) (LOCAL_TIMER + RESET_REG);

    // Reset timer
    *timer_reset = CMD_RESET;
    
    // Indicate to CoreTest.c running on host that this processor is running
    volatile unsigned int * check = (unsigned int *) EXTRA_BRAM;
    
    // assign cpus_per_bus offset
    check = (unsigned int *)
        ((unsigned int) check + ( ((unsigned int) cpu_id) *  0x100));
    
    // write OKAY_VALUE to common memory (extra_bram)
    *check = OKAY_VALUE;

    // Nano-kernel loop...
    while(1) {
        // Setup interface
		// * Perform this upon each iteration, just in case the memory
		//   map for the MB-HWTI is corrupted.
	    initialize_interface(&hwti,(int*)(hwti_base));

#if 0   // Commented out as this is not necessary and it creates the opportunity for a race between reset and start commands
        // Wait to be "reset"
		// -- NOTE: Ignore reset as it has no meaning to the MB-HWTI
		//          and it seems causes a race, as the controlling processor
		//          sends a reset, immediately followed by a "go" command.  Therefore
		//          the "reset" command can be missed.
	    wait_for_reset_command(&hwti);
        
#endif

	    // Wait to be "started"
	    wait_for_go_command(&hwti);

		//xil_printf("Thread started (fcn @ 0x%08x), arg = 0x%08x!!!\r\n",*(hwti.fcn_reg), *(hwti.arg_reg));

        // Setup r20 for thread, this can be used to enforce -fPIC (Position-independent code) for the MB
        // (r20 is used as part of the GOT, to make things PC-relative)
        mtgpr(r20, *(hwti.fcn_reg));

        // Boostrap thread (wraps up thread execution with a thread exit)
        //  * Pull out thread argument, and thread start function
        _bootstrap_thread(&hwti, *(hwti.fcn_reg), *(hwti.arg_reg));
		 
    }
    return 0;
}