int main() { XStatus Status; u32 btnsw, old_btnsw = 0x000000FF; int rotcnt, old_rotcnt = 0x1000; bool done = 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 global variables timestamp = 0; pwm_freq = INITIAL_FREQUENCY; pwm_duty = INITIAL_DUTY_CYCLE; clkfit = 0; new_perduty = false; // start the PWM timer and kick of the processing by enabling the Microblaze interrupt PWM_SetParams(&PWMTimerInst, pwm_freq, pwm_duty); PWM_Start(&PWMTimerInst); microblaze_enable_interrupts(); // display the greeting LCD_setcursor(1,0); LCD_wrstring(" PWM LIB TEST R0"); LCD_setcursor(2,0); LCD_wrstring(" by Roy Kravitz "); NX3_writeleds(0x000000FF); delay_msecs(2000); NX3_writeleds(0x00000000); // write the static text to the display LCD_clrd(); LCD_setcursor(1,0); LCD_wrstring("G|FR: DCY: %"); LCD_setcursor(2,0); LCD_wrstring("Vavg: "); // main loop do { // check rotary encoder pushbutton to see if it's time to quit NX3_readBtnSw(&btnsw); if (btnsw & msk_BTN_ROT) { done = true; } else { new_perduty = false; if (btnsw != old_btnsw) { switch (btnsw & PWM_FREQ_MSK) { case 0x00: pwm_freq = PWM_FREQ_10HZ; break; case 0x01: pwm_freq = PWM_FREQ_100HZ; break; case 0x02: pwm_freq = PWM_FREQ_1KHZ; break; case 0x03: pwm_freq = PWM_FREQ_10KHZ; break; case 0x04: pwm_freq = PWM_FREQ_50KHZ; break; case 0x05: pwm_freq = PWM_FREQ_100KHZ; break; case 0x06: pwm_freq = PWM_FREQ_150KHZ; break; case 0x07: pwm_freq = PWM_FREQ_200KHZ; break; } old_btnsw = btnsw; new_perduty = true; } // read rotary count and handle duty cycle changes // limit duty cycle to 0% to 99% ROT_readRotcnt(&rotcnt); if (rotcnt != old_rotcnt) { pwm_duty = MAX(0, MIN(rotcnt, 99)); old_rotcnt = rotcnt; new_perduty = true; } // update generated frequency and duty cycle if (new_perduty) { u32 freq, dutycycle; float vavg; char s[10]; // set the new PWM parameters - PWM_SetParams stops the timer Status = PWM_SetParams(&PWMTimerInst, pwm_freq, pwm_duty); if (Status == XST_SUCCESS) { PWM_GetParams(&PWMTimerInst, &freq, &dutycycle); update_lcd(freq, dutycycle, 1); vavg = dutycycle * .01 * 3.3; voltstostrng(vavg, s); LCD_setcursor(2,5); LCD_wrstring(s); PWM_Start(&PWMTimerInst); } } } } while (!done); // wait until rotary encoder button is released do { NX3_readBtnSw(&btnsw); delay_msecs(10); } while ((btnsw & msk_BTN_ROT) == 0x80); // and say goodbye LCD_clrd(); LCD_wrstring("That's all folks"); delay_msecs(2000); LCD_clrd(); exit(XST_SUCCESS); }
int main() { XStatus status; u16 sw, oldSw =0xFFFF; // 0xFFFF is invalid --> makes sure the PWM freq is updated 1st time int rotcnt, oldRotcnt = 0x1000; bool done = false; bool hw_switch = 0; init_platform(); // initialize devices and set up interrupts, etc. status = do_init(); if (status != XST_SUCCESS) { PMDIO_LCD_setcursor(1,0); PMDIO_LCD_wrstring("****** ERROR *******"); PMDIO_LCD_setcursor(2,0); PMDIO_LCD_wrstring("INIT FAILED- EXITING"); exit(XST_FAILURE); } // initialize the global variables timestamp = 0; pwm_freq = INITIAL_FREQUENCY; pwm_duty = INITIAL_DUTY_CYCLE; clkfit = 0; new_perduty = false; // start the PWM timer and kick of the processing by enabling the Microblaze interrupt PWM_SetParams(&PWMTimerInst, pwm_freq, pwm_duty); PWM_Start(&PWMTimerInst); microblaze_enable_interrupts(); // display the greeting PMDIO_LCD_setcursor(1,0); PMDIO_LCD_wrstring("ECE544 Project 1"); PMDIO_LCD_setcursor(2,0); PMDIO_LCD_wrstring(" by Rehan Iqbal "); NX4IO_setLEDs(0x0000FFFF); delay_msecs(2000); NX4IO_setLEDs(0x00000000); // write the static text to the display PMDIO_LCD_clrd(); PMDIO_LCD_setcursor(1,0); PMDIO_LCD_wrstring("G|FR: DCY: %"); PMDIO_LCD_setcursor(2,0); PMDIO_LCD_wrstring("D|FR: DCY: %"); // turn off the LEDs and clear the seven segment display NX4IO_setLEDs(0x00000000); NX410_SSEG_setAllDigits(SSEGLO, CC_BLANK, CC_BLANK, CC_BLANK, CC_BLANK, DP_NONE); NX410_SSEG_setAllDigits(SSEGHI, CC_BLANK, CC_BLANK, CC_BLANK, CC_BLANK, DP_NONE); // main loop do { // check rotary encoder pushbutton to see if it's time to quit if (PMDIO_ROT_isBtnPressed()) { done = true; } else { new_perduty = false; // get the switches and mask out all but the switches that determine the PWM timer frequency sw &= PWM_FREQ_MSK; sw = NX4IO_getSwitches(); if (sw != oldSw) { // check the status of sw[2:0] and assign appropriate PWM output frequency switch (sw & 0x07) { case 0x00: pwm_freq = PWM_FREQ_100HZ; break; case 0x01: pwm_freq = PWM_FREQ_1KHZ; break; case 0x02: pwm_freq = PWM_FREQ_10KHZ; break; case 0x03: pwm_freq = PWM_FREQ_50KHZ; break; case 0x04: pwm_freq = PWM_FREQ_100KHZ; break; case 0x05: pwm_freq = PWM_FREQ_500KHZ; break; case 0x06: pwm_freq = PWM_FREQ_1MHZ; break; case 0x07: pwm_freq = PWM_FREQ_5MHZ; break; } // check the status of sw[3] and assign to global variable hw_switch = (sw & 0x08); // update global variable indicating there are new changes oldSw = sw; new_perduty = true; } // read rotary count and handle duty cycle changes // limit duty cycle to 0% to 99% PMDIO_ROT_readRotcnt(&rotcnt); if (rotcnt != oldRotcnt) { // show the rotary count in hex on the seven segment display NX4IO_SSEG_putU16Hex(SSEGLO, rotcnt); // change the duty cycle pwm_duty = MAX(1, MIN(rotcnt, 99)); oldRotcnt = rotcnt; new_perduty = true; } // update generated frequency and duty cycle if (new_perduty) { u32 freq, dutycycle; unsigned int detect_freq = 0x00; unsigned int detect_duty = 0x00; // set the new PWM parameters - PWM_SetParams stops the timer status = PWM_SetParams(&PWMTimerInst, pwm_freq, pwm_duty); if (status == XST_SUCCESS) { PWM_GetParams(&PWMTimerInst, &freq, &dutycycle); update_lcd(freq, dutycycle, 1); // check if sw[3] is high or low (HWDET / SWDET) // pass functions different args depending on which mode is selected if (hw_switch) { detect_freq = calc_freq(hw_high_count, hw_low_count, hw_switch); detect_duty = calc_duty(hw_high_count, hw_low_count); } else { detect_freq = calc_freq(sw_high_count, sw_low_count, hw_switch); detect_duty = calc_duty(sw_high_count, sw_low_count); } // update the LCD display with detected frequency & duty cycle update_lcd(detect_freq, detect_duty, 2); PWM_Start(&PWMTimerInst); } } } } while (!done); // wait until rotary encoder button is released do { delay_msecs(10); } while (PMDIO_ROT_isBtnPressed()); // we're done, say goodbye xil_printf("\nThat's All Folks!\n\n"); PMDIO_LCD_setcursor(1,0); PMDIO_LCD_wrstring("That's All Folks"); PMDIO_LCD_setcursor(2,0); PMDIO_LCD_wrstring(" "); NX410_SSEG_setAllDigits(SSEGHI, CC_BLANK, CC_B, CC_LCY, CC_E, DP_NONE); NX410_SSEG_setAllDigits(SSEGLO, CC_B, CC_LCY, CC_E, CC_BLANK, DP_NONE); delay_msecs(5000); // turn the lights out PMDIO_LCD_clrd(); NX410_SSEG_setAllDigits(SSEGHI, CC_BLANK, CC_BLANK, CC_BLANK, CC_BLANK, DP_NONE); NX410_SSEG_setAllDigits(SSEGLO, CC_BLANK, CC_BLANK, CC_BLANK, CC_BLANK, DP_NONE); NX4IO_RGBLED_setDutyCycle(RGB1, 0, 0, 0); NX4IO_RGBLED_setChnlEn(RGB1, false, false, false); // exit gracefully cleanup_platform(); exit(0); }
/***** * DoTest_Characterize() - Perform the Characterization test * * This function starts the duty cycle at the minimum duty cycle and * then increases it to the max duty cycle for the test. * Samples are collected into the global array sample[]. * The function toggles the TEST_RUNNING signal high for the duration * of the test as a debug aid and adjusts the global "pwm_duty" * * The test also sets the global ADC min and max counts to * help limit the ADC counts to the active range for the circuit *****/ int DoTest_Characterize(void) { XStatus Status; // Xilinx return status unsigned tss; // starting timestamp u16 adc_1, adc_2; // holds the ADC count - sampled twice and averaged u16 adc_cnt; // ADC counts to display int n; // number of samples Xuint32 freq, dutyfactor; // current frequency and duty factor // stabilize the PWM output (and thus the lamp intensity) at the // minimum before starting the test pwm_duty = PWM_STEPDC_MIN; Status = PWM_SetParams(&PWMTimerInst, pwm_freq, pwm_duty); if (Status == XST_SUCCESS) { PWM_Start(&PWMTimerInst); } else { return -1; } delay_msecs(1000); // sweep the duty cycle from STEPDC_MIN to STEPDC_MAX smpl_idx = PWM_STEPDC_MIN; n = 0; tss = timestamp; while (smpl_idx <= PWM_STEPDC_MAX) { Status = PWM_SetParams(&PWMTimerInst, pwm_freq, smpl_idx); if (Status == XST_SUCCESS) { PWM_Start(&PWMTimerInst); } else { return -1; } // sample the ADC twice and average the readings adc_1 = PmodCtlSys_readADC(&SPIInst); delay_msecs(1); adc_2 = PmodCtlSys_readADC(&SPIInst); adc_cnt = (adc_1 + adc_2) / 2; sample[smpl_idx++] = adc_cnt; n++; delay_msecs(20); } adc_smple_interval = (timestamp - tss) / smpl_idx; // initialize the ADC min and max counts from the saved data ADC_min_cnt = ADC_max_cnt = 0; for (n = PWM_STEPDC_MIN; n <= PWM_STEPDC_MAX; n++) { if (sample[n] < ADC_min_cnt) ADC_min_cnt = sample[n]; if (sample[n] > ADC_max_cnt) ADC_max_cnt = sample[n]; } ADC_max_vout = PmodCtlSys_ADCVolts(ADC_min_cnt); ADC_min_vout = PmodCtlSys_ADCVolts(ADC_max_cnt); // initialize the PWM min and max counts - these are constants so can be calculated here // count = ((pwm duty cycle * PLB clock frequency[Hz]) / pwm frequency[Hz]) - 2 PWM_GetParams(&PWMTimerInst, &freq, &dutyfactor); PWM_min_cnt = ((PWM_STEPDC_MIN * .01 * PLB_CLOCK_FREQ_HZ) / freq) - 2; PWM_max_cnt = ((PWM_STEPDC_MAX * .01 * PLB_CLOCK_FREQ_HZ) / freq) - 2; return n; }
int main () { XStatus status; // VARS : to hold user input stuff int encoderCurn = 0x0000; int encoderPrev = 0x1000; int PWMDutyGen = 50; bool PWMGenUpdateFlag = false; u32 PWMFreqGenRead; u32 PWMDutyGenRead; /*u32 tsl235rHiTimePrev = 0;*/ /*int PWMCycTime;*/ /*int PWMFreqMeas;*/ int tsl235rFreqPrev = 0; // Initializations init_platform(); status = init_axi_devices(); if (status != XST_SUCCESS) errorExit(); init_welcom(); // SET : PWM generator begin, enable microblaze interrupts /*PWM_SetParams(&instPWMTimer, PWM_FREQ_005KHZ, PWMDutyGen); */ PWM_Start(&instPWMTimer); microblaze_enable_interrupts(); init_feedback_system(); while(1) { PWMGenUpdateFlag = false; // CHECK : Updates on ENCODER PMDIO_ROT_readRotcnt(&encoderCurn); if (encoderCurn != encoderPrev) { // SET seven-seg with encoder value NX4IO_SSEG_putU16Hex(SSEGLO, encoderCurn); PWMDutyGen = MAX(0, MIN(encoderCurn, 99)); encoderPrev = encoderCurn; PWMGenUpdateFlag = true; } // SET : Update PWM Generator if (PWMGenUpdateFlag) { // set the new PWM parameters - PWM_SetParams stops the timer status = PWM_SetParams(&instPWMTimer, PWM_FREQ_005KHZ, PWMDutyGen); if (status != XST_SUCCESS) errorExit(); // GET : read the PWM parameters back from the PWM generator PWM_GetParams(&instPWMTimer, &PWMFreqGenRead, &PWMDutyGenRead); update_lcd(PWMFreqGenRead, PWMDutyGenRead, 1); PWM_Start(&instPWMTimer); } /*if (tsl235rHiTimePrev != tsl235rHiTime) {*/ /*PWMCycTime = (int) tsl235rHiTime * 2;*/ /*PWMFreqMeas = 100000000 / PWMCycTime;*/ /*update_lcd(PWMFreqMeas, 0, 2);*/ /*tsl235rHiTimePrev = tsl235rHiTime;*/ /*}*/ if (tsl235rFreqPrev != tsl235rFreq) { update_lcd(tsl235rFreq, 50, 2); tsl235rFreq = tsl235rFreqPrev; } } }