//***************************************************************************** // //! This is the code that gets called when the processor receives an unexpected //! interrupt. This simply enters an infinite loop, preserving the system //! state for examination by a debugger. //! //! \return None. // //***************************************************************************** void IntDefaultHandler(void) { // // Disable all interrupts. // IntMasterDisable(); // // Turn off all the PWM outputs. // PWMOutputState(PWM0_BASE, PWM_OUT_0_BIT | PWM_OUT_1_BIT | PWM_OUT_2_BIT | PWM_OUT_3_BIT | PWM_OUT_4_BIT | PWM_OUT_5_BIT, false); // // Turn on STATUS and MODE LEDs. They will remain on. // BlinkStart(STATUS_LED, 1, 1, 1); BlinkStart(MODE_LED, 1, 1, 1); BlinkHandler(); // // Go into an infinite loop. // while(1) { } }
//***************************************************************************** // //! Update the firmware using the bootloader. //! //! This function is called by the serial user interface when the firmware //! update command is received. //! //! \return None. // //***************************************************************************** void UIUpgrade(void) { // // Emergency stop the motor drive. // StepperEmergencyStop(); // // Disable all processor interrupts. Instead of disabling them one at a // time (and possibly missing an interrupt if new sources are added), a // direct write to NVIC is done to disable all peripheral interrupts. // HWREG(NVIC_DIS0) = 0xffffffff; // // Also disable the SysTick interrupt. // SysTickIntDisable(); // // Turn off all the on-board LEDs. // BlinkStart(STATUS_LED, 0, 1, 1); BlinkStart(MODE_LED, 0, 1, 1); BlinkHandler(); // // Stop running from the PLL. // SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_6MHZ); // // Reconfigure the UART for 115,200, 8-N-1 operation with new clock. // UARTConfigSetExpClk(UART0_BASE, SysCtlClockGet(), 115200, (UART_CONFIG_WLEN_8 | UART_CONFIG_PAR_NONE | UART_CONFIG_STOP_ONE)); // // Return control to the boot loader. This is a call to the SVC handler in // the boot loader. // (*((void (*)(void))(*(unsigned long *)0x2c)))(); // // Control should never return here, but just in case it does. // while(1) { } }
//***************************************************************************** // //! Handles the SysTick interrupt. //! //! This function is called when SysTick asserts its interrupt. It is //! responsible for handling the on-board user interface elements (push button //! and potentiometer) if enabled, and the processor usage computation. //! //! \return None. // //***************************************************************************** void SysTickIntHandler(void) { static unsigned int uDataUpdate = UI_INT_RATE / 10; static unsigned long ulLastPotPosition = 0; static unsigned long ulLastBlink = 0; static long lLastPotDelta = 0; static unsigned short usLastBusVoltage = 0; static unsigned char bFaultBlink = 0; unsigned long ulBlink; unsigned long ulADCCounts[8]; // 0-pot, 1-busV, 2-temperature long lSamples; long lPotDelta; // // Get the motor status. This will update the fields in the // stepper status structure. // pStepperStatus = StepperGetMotorStatus(); // // Compute the average current, which is what gets reported through // the UI. // g_usMotorCurrent = (pStepperStatus->usCurrent[0] + pStepperStatus->usCurrent[1] + 1) / 2; // // Get the previous ADC samples, and start a new acquisition // lSamples = ADCSequenceDataGet(ADC0_BASE, UI_ADC_SEQUENCER, ulADCCounts); ADCProcessorTrigger(ADC0_BASE, UI_ADC_SEQUENCER); // // Read the bus voltage and convert to millivolts, // and the CPU temperature and convert to C // if(lSamples == 3) { g_usBusVoltage = (unsigned short)((ulADCCounts[1] * 81300) / 1023); g_sAmbientTemp = (59960 - (ulADCCounts[2] * 100)) / 356; } // // If the bus voltage has changed more than 0.5 volts, then call // the UISetMotorParms() function, which will force an update of // the PWM duty cycle calculation. This will insure that the PWM // duty cycle is correct if the bus voltage changes. // if(ABS((int)g_usBusVoltage - (int)usLastBusVoltage) > 500) { UISetMotorParms(); usLastBusVoltage = g_usBusVoltage; } // // Periodically send real time data // if(!uDataUpdate--) { uDataUpdate = UI_INT_RATE / 20; UISerialSendRealTimeData(); } // // If a fault just occurred, then start the status LED blinking // at a rapid rate. // if(pStepperStatus->ucFaultFlags && !bFaultBlink) { BlinkStart(STATUS_LED, 4, 4, INT_MAX); bFaultBlink = 1; } // // Else, if a fault was just cleared, then stop the status LED blinking. // else if(!pStepperStatus->ucFaultFlags && bFaultBlink) { BlinkStart(STATUS_LED, 1, 1, 1); bFaultBlink = 0; } // // Otherwise, as normal, blink the status LED according to the number // of steps moved. // else { // // Blink the status LED every so many steps. // ulBlink = pStepperStatus->lPosition / ((2000 * 256) / 8); if(ulBlink != ulLastBlink) { BlinkStart(STATUS_LED, UI_INT_RATE / 32, 1, 1); ulLastBlink = ulBlink; } } // // Periodically call the blinker state machine. // BlinkHandler(); // // Compute the new value for the processor usage. // g_ucCPUUsage = (CPUUsageTick() + 32768) / 65536; // // Do the following only if the on-board UI is enabled. // if(g_bUIUseOnboard == 1) { // // Filter the potentiometer value. Make sure there is valid // ADC data. // if(lSamples == 3) { ulPotPosition = UIOnboardPotentiometerFilter(ulADCCounts[0]); } else { // // If ADC reading is suspect, then just use the last previous // reading. // ulPotPosition = ulLastPotPosition; } // // Set the minimum value to be use as 10. This sets the minimum // speed for speed mode to 10. // if(ulPotPosition < 10) { ulPotPosition = 10; } // // Read the on-board switch and pass its value to the switch // debouncer. This will drive the button press functions // UIButtonPress() and UIButtonHold() which will be called // back if the button press or hold occurred. // UIOnboardSwitchDebouncer(GPIOPinRead(USER_BUTTON_PORT, USER_BUTTON_PIN)); // // Find the difference from the last pot measurement. // lPotDelta = ulPotPosition - ulLastPotPosition; // // Check if the direction is reversed. The following is used // to ensure that the pot reading does not actually cause // a change in direction (in position mode) due just to jitter // in the potentiometer reading. Only a change above a certain // value will be accepted. If the direction is not changed, // then no filtering is done. // if((lPotDelta != 0) && ((lPotDelta * lLastPotDelta) < 0)) { // // If the direction is reversed, but the change is less than a // certain amount, then don't accept the new potentiometer reading, // and set it back to its previous value. // if(ABS(lPotDelta) < 20) { ulPotPosition = ulLastPotPosition; } // // else, if the direction is reversed and changed more than a // certain amount, then just leave the new pot reading as is, // and remember the difference. // else { lLastPotDelta = lPotDelta; } } // // Else, the direction of the pot move was not reversed. Remember // the (signed) difference. The new pot value will be used below. // else { lLastPotDelta = lPotDelta; } // // Check to see if the potentiometer has moved. // if(ulPotPosition != ulLastPotPosition) { ulLastPotPosition = ulPotPosition; // // In position mode, the pot indicates the motor target // position, so update the target position and command the // motor to move. // if(eUIMode == UI_MODE_POSITION) { // // Make sure that after conversion to steps, the target // position actually changed, before sending a new motion // command. // The pot position is adjusted so that one revolution // of the pot matches 200 steps, the number of steps in // the motor. This gives the position mode a 1-1 feel, // as the pot is turned, the motor turns a corresponding // amount. // if(((ulPotPosition * 256 * 100) / 507) != g_lTargetPos) { g_lTargetPos = (ulPotPosition * 256 * 100) / 507; UISetMotion(); } } // // In speed mode, the pot indicates the motor speed, so // command the motor to move using the new speed. // else if(eUIMode == UI_MODE_SPEED) { StepperSetMotion(g_lTargetPos, ulPotPosition, g_sParameters.usAccel, g_sParameters.usDecel); } } } }
void BlinkWorkItemCallback(struct work_struct *work) { struct LED_871x *pLed = container_of(work, struct LED_871x, BlinkWorkItem); BlinkHandler(pLed); }