Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * interrupt_counter_tut_2B.c
- *
- * Version 1.2 Author : Edward Todirica
- *
- * Created on: Unknown
- * Author: Ross Elliot
- * Version: 1.1
- */
- /********************************************************************************************
- * VERSION HISTORY
- ********************************************************************************************
- * v1.2 - 10.11.2016
- * Fixed some bugs regarding Timer Interrupts and adding some
- * debug messages for the Timer Interrupt Handler
- *
- * v1.1 - 01/05/2015
- * Updated for Zybo ~ DN
- *
- * v1.0 - Unknown
- * First version created.
- *******************************************************************************************/
- #include <stdio.h>
- #include "xparameters.h"
- #include "xgpio.h"
- #include "xtmrctr.h"
- #include "xscugic.h"
- #include "xil_exception.h"
- #include "xil_printf.h"
- #include "xtime_l.h"
- // Parameter definitions
- #define INTC_DEVICE_ID XPAR_PS7_SCUGIC_0_DEVICE_ID
- #define TMR_DEVICE_ID XPAR_TMRCTR_0_DEVICE_ID
- #define BTNS_DEVICE_ID XPAR_AXI_GPIO_0_DEVICE_ID
- #define LEDS_DEVICE_ID XPAR_AXI_GPIO_1_DEVICE_ID
- #define INTC_GPIO_INTERRUPT_ID XPAR_FABRIC_AXI_GPIO_0_IP2INTC_IRPT_INTR
- #define INTC_TMR_INTERRUPT_ID XPAR_FABRIC_AXI_TIMER_0_INTERRUPT_INTR
- #define BTN_INT XGPIO_IR_CH1_MASK
- //#define TMR_LOAD 0xF8000000
- #define TMR_LOAD 1000000
- XGpio LEDInst, BTNInst;
- XScuGic INTCInst;
- //XTmrCtr TMRInst;
- int led_data;
- int btn_value;
- //static int tmr_count;
- XTime tStart, tEnd;
- //----------------------------------------------------------------------------------
- // VARIABLES-----------------------------------------------------------------------
- //----------------------------------------------------------------------------------
- int milliseconds = 00;
- int time = 00;
- int minutes = 00;
- int seconds = 00;
- int sw_minutes = 00;
- int sw_seconds = 00;
- int sw_milliseconds = 00;
- int sw_minuteslap = 00;
- int sw_secondslap = 00;
- int sw_millisecondslap = 00;
- int sw_start = 0;
- int sw_lap = 0;
- char mode = 'A';
- int ChangeHour = 0;
- int ChangeMinutes = 0;
- int minutesChange = 0;
- //----------------------------------------------------------------------------------
- // VARIABLES DONE ------------------------------------------------------------------
- //----------------------------------------------------------------------------------
- //----------------------------------------------------
- // PROTOTYPE FUNCTIONS
- //----------------------------------------------------
- void BTN_Intr_Handler(void *baseaddr_p);
- void TMR_Intr_Handler(void *InstancePtr, u8 TmrCtrNumber);
- int InterruptSystemSetup(XScuGic *XScuGicInstancePtr);
- int IntcInitFunction(u16 DeviceId, XTmrCtr *TmrInstancePtr, XGpio *GpioInstancePtr);
- //----------------------------------------------------
- // PROTOTYPE FUNCTIONS DONE
- //----------------------------------------------------
- /*****************************************************************************/
- /**
- * This function should be part of the device driver for the timer device
- * Clears the interrupt flag of the specified timer counter of the device.
- * This is necessary to do in the interrupt routine after the interrupt was handled.
- *
- * @param InstancePtr is a pointer to the XTmrCtr instance.
- * @param TmrCtrNumber is the timer counter of the device to operate on.
- * Each device may contain multiple timer counters. The timer
- * number is a zero based number with a range of
- * 0 - (XTC_DEVICE_TIMER_COUNT - 1).
- *
- * @return None.
- *
- * @note None.
- *
- ******************************************************************************/
- void XTmrCtr_ClearInterruptFlag(XTmrCtr * InstancePtr, u8 TmrCtrNumber)
- {
- u32 CounterControlReg;
- Xil_AssertVoid(InstancePtr != NULL);
- Xil_AssertVoid(TmrCtrNumber < XTC_DEVICE_TIMER_COUNT);
- Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
- /*
- * Read current contents of the CSR register so it won't be destroyed
- */
- CounterControlReg = XTmrCtr_ReadReg(InstancePtr->BaseAddress,
- TmrCtrNumber, XTC_TCSR_OFFSET);
- /*
- * Reset the interrupt flag
- */
- XTmrCtr_WriteReg(InstancePtr->BaseAddress, TmrCtrNumber,
- XTC_TCSR_OFFSET,
- CounterControlReg | XTC_CSR_INT_OCCURED_MASK);
- }
- //----------------------------------------------------
- // INTERRUPT HANDLER FUNCTIONS
- // - called by the timer, button interrupt, performs
- // - LED flashing
- //----------------------------------------------------
- //make led_data start with beeing 8
- led_data = 8;
- void BTN_Intr_Handler(void *InstancePtr)
- {
- // Disable GPIO interrupts
- XGpio_InterruptDisable(&BTNInst, BTN_INT);
- // Ignore additional button presses
- if ((XGpio_InterruptGetStatus(&BTNInst) & BTN_INT) !=
- BTN_INT) {
- return;
- }
- btn_value = XGpio_DiscreteRead(&BTNInst, 1);
- // Everytime btn 4 is pressed, led data is divided by 2
- if (btn_value == 4) {
- led_data = led_data/2;
- btn_value = 0;
- }
- // makes sure that led data shifts from 1 to 8, when btn 4 is pressed again.
- if (btn_value == 0 && led_data < 1) {
- led_data = 8;
- }
- // defines which mode we are in
- if (led_data == 4) {
- mode = 'B';
- } else if (led_data == 2) {
- mode = 'C';
- } else if (led_data == 1) {
- mode = 'D';
- } else {
- mode = 'A';
- }
- XGpio_DiscreteWrite(&LEDInst, 1, led_data);
- (void)XGpio_InterruptClear(&BTNInst, BTN_INT);
- // Enable GPIO interrupts
- XGpio_InterruptEnable(&BTNInst, BTN_INT);
- }
- void TMR_Intr_Handler(void *InstancePtr, u8 TmrCtrNumber)
- {
- //Switch case
- switch(mode) {
- case 'A' :
- xil_printf("Time !\n" );
- printTime();
- break;
- case 'B' :
- xil_printf("Mode2 \n" );
- break;
- case 'C' :
- xil_printf(" Stopwatch \n" );
- stopwatch();
- break;
- case 'D' :
- xil_printf("Change time \n" );
- changeTime();
- break;
- default :
- xil_printf("Invalid mode\n" );
- }
- double duration;
- static int tmr_count;
- XTime_GetTime(&tEnd);
- XTmrCtr* pTMRInst = (XTmrCtr *) InstancePtr;
- // Clock time
- milliseconds++;
- if (milliseconds >= 99){
- seconds++;
- milliseconds = 0;
- }else if ( seconds >= 60 ) {
- minutes++;
- seconds = 0;
- } else if ( minutes >= 60 ) {
- time++;
- minutes = 0;
- } else if ( time >= 24) {
- time = 0;
- }
- if (TmrCtrNumber==0) { //Handle interrupts generated by timer 0
- duration = ((double)(tEnd-tStart))/COUNTS_PER_SECOND;
- //xil_printf("%s\n%s\n", said[2],said[2]);
- tStart=tEnd;
- if (XTmrCtr_IsExpired(pTMRInst,0)){
- // Once timer has expired 3 times, stop, increment counter
- // reset timer and start running again
- if(tmr_count == 3){
- XTmrCtr_Stop(pTMRInst,0);
- tmr_count = 0;
- XGpio_DiscreteWrite(&LEDInst, 1, led_data);
- XTmrCtr_Reset(pTMRInst,0);
- XTmrCtr_Start(pTMRInst,0);
- }
- else tmr_count++;
- }
- }
- else { //Handle interrupts generated by timer 1
- }
- XTmrCtr_ClearInterruptFlag(pTMRInst, TmrCtrNumber);
- }
- //-------------------------------------------------------
- // FUNCTIONS
- //-------------------------------------------------------
- // Print the current time
- void printTime(){
- xil_printf("%d:%d:%d \n",time, minutes,seconds);
- }
- // Function for stopwatch mode
- void stopwatch() {
- xil_printf("%d:%d:%d \n",sw_minutes, sw_seconds,sw_milliseconds);
- if(btn_value == 1 && sw_start == 0){
- sw_start = 1;
- btn_value = 0;
- } else if(btn_value == 1 && sw_start == 1){
- sw_start = 0;
- }
- if (sw_start == 1) {
- sw_milliseconds++;
- if ( sw_milliseconds >= 100 ) {
- sw_seconds++;
- sw_milliseconds = 0;
- } else if ( sw_seconds >= 60 ) {
- sw_minutes++;
- sw_seconds = 0;
- } else if ( sw_minutes >= 60) {
- sw_minutes = 0;
- }
- }
- if(btn_value == 8 && sw_start == 1 && sw_lap == 0){
- sw_lap = 1;
- sw_millisecondslap = sw_milliseconds;
- sw_secondslap = sw_seconds;
- sw_minuteslap = sw_minutes;
- }
- else if(btn_value == 8 && sw_lap == 1){
- sw_lap = 0;
- }
- if (sw_start == 0){
- if(btn_value == 8){
- sw_milliseconds = 0;
- sw_seconds = 0;
- sw_minutes = 0;
- }
- }
- }
- // Setting the time
- void changeTime() {
- xil_printf("%d:%d:%d \n",time, minutes,seconds);
- if(btn_value == 1 && led_data == 1 && ChangeMinutes == 0) {
- ChangeHour = 1;
- ChangeMinutes = 0;
- }
- if(ChangeHour == 1 && btn_value == 1){
- time++;
- btn_value = 0;
- }
- if(btn_value == 8 && led_data == 1 && ChangeMinutes == 0) {
- ChangeHour = 0;
- ChangeMinutes = 1;
- btn_value = 0;
- }
- if(ChangeMinutes == 1 && btn_value == 1){
- minutes++;
- btn_value = 0;
- }
- if(btn_value == 8 && led_data == 1 && ChangeMinutes == 1) {
- ChangeHour = 1;
- ChangeMinutes = 0;
- btn_value = 0;
- }
- }
- //-------------------------------------------------------
- // FUNCTIONS DONE
- //-------------------------------------------------------
- //----------------------------------------------------
- // MAIN FUNCTION
- //----------------------------------------------------
- int main (void)
- {
- int status;
- XTmrCtr TMRInst;
- //----------------------------------------------------
- // INITIALIZE THE PERIPHERALS & SET DIRECTIONS OF GPIO
- //----------------------------------------------------
- // Initialise LEDs
- status = XGpio_Initialize(&LEDInst, LEDS_DEVICE_ID);
- if(status != XST_SUCCESS) return XST_FAILURE;
- // Initialise Push Buttons
- status = XGpio_Initialize(&BTNInst, BTNS_DEVICE_ID);
- if(status != XST_SUCCESS) return XST_FAILURE;
- // Set LEDs direction to outputs
- XGpio_SetDataDirection(&LEDInst, 1, 0x00);
- // Set all buttons direction to inputs
- XGpio_SetDataDirection(&BTNInst, 1, 0xFF);
- //----------------------------------------------------
- // SETUP THE TIMER
- //----------------------------------------------------
- status = XTmrCtr_Initialize(&TMRInst, TMR_DEVICE_ID);
- if(status != XST_SUCCESS) return XST_FAILURE;
- XTmrCtr_SetHandler(&TMRInst, TMR_Intr_Handler, &TMRInst);
- XTmrCtr_SetResetValue(&TMRInst, 0, TMR_LOAD);
- XTmrCtr_SetOptions(&TMRInst, 0, XTC_INT_MODE_OPTION | XTC_AUTO_RELOAD_OPTION | XTC_DOWN_COUNT_OPTION);
- // Initialize interrupt controller
- status = IntcInitFunction(INTC_DEVICE_ID, &TMRInst, &BTNInst);
- if(status != XST_SUCCESS) return XST_FAILURE;
- XTmrCtr_Start(&TMRInst, 0);
- //Here we get the time when the timer first started
- XTime_GetTime(&tStart);
- while(1);
- return 0;
- }
- //----------------------------------------------------
- // INITIAL SETUP FUNCTIONS
- //----------------------------------------------------
- int InterruptSystemSetup(XScuGic *XScuGicInstancePtr)
- {
- // Enable interrupt
- XGpio_InterruptEnable(&BTNInst, BTN_INT);
- XGpio_InterruptGlobalEnable(&BTNInst);
- Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
- (Xil_ExceptionHandler)XScuGic_InterruptHandler,
- XScuGicInstancePtr);
- Xil_ExceptionEnable();
- return XST_SUCCESS;
- }
- int IntcInitFunction(u16 DeviceId, XTmrCtr *TmrInstancePtr, XGpio *GpioInstancePtr)
- {
- XScuGic_Config *IntcConfig;
- int status;
- u8 pri, trig;
- // Interrupt controller initialisation
- IntcConfig = XScuGic_LookupConfig(DeviceId);
- status = XScuGic_CfgInitialize(&INTCInst, IntcConfig, IntcConfig->CpuBaseAddress);
- if(status != XST_SUCCESS) return XST_FAILURE;
- // Call to interrupt setup
- status = InterruptSystemSetup(&INTCInst);
- if(status != XST_SUCCESS) return XST_FAILURE;
- // Connect GPIO interrupt to handler
- status = XScuGic_Connect(&INTCInst,
- INTC_GPIO_INTERRUPT_ID,
- (Xil_ExceptionHandler)BTN_Intr_Handler,
- (void *)GpioInstancePtr);
- if(status != XST_SUCCESS) return XST_FAILURE;
- // Connect timer interrupt to handler
- status = XScuGic_Connect(&INTCInst,
- INTC_TMR_INTERRUPT_ID,
- // (Xil_ExceptionHandler)TMR_Intr_Handler,
- (Xil_ExceptionHandler) XTmrCtr_InterruptHandler,
- (void *)TmrInstancePtr);
- if(status != XST_SUCCESS) return XST_FAILURE;
- // Enable GPIO interrupts interrupt
- XGpio_InterruptEnable(GpioInstancePtr, 1);
- XGpio_InterruptGlobalEnable(GpioInstancePtr);
- // Enable GPIO and timer interrupts in the controller
- XScuGic_Enable(&INTCInst, INTC_GPIO_INTERRUPT_ID);
- XScuGic_Enable(&INTCInst, INTC_TMR_INTERRUPT_ID);
- xil_printf("Getting the Timer interrupt info\n\r");
- XScuGic_GetPriTrigTypeByDistAddr(INTCInst.Config->DistBaseAddress, INTC_TMR_INTERRUPT_ID, &pri, &trig);
- xil_printf("GPIO Interrupt-> Priority:%d, Trigger:%x\n\r", pri, trig);
- //Set the timer interrupt as edge triggered
- //XScuGic_SetPriorityTriggerType(&INTCInst, INTC_TMR_INTERRUPT_ID, )
- return XST_SUCCESS;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement