PYNQ PS timer interrupt

Timer Applications

1, the clock interrupt. Taiwan before and after the program

2, to achieve a delay.

3, counter counter

Here Insert Picture Description

1 Global hours counter

Here Insert Picture Description

2 CPU private timer

Here Insert Picture Description
Here Insert Picture Description

2.1 timer_loader

Here Insert Picture Description
Here Insert Picture Description

2.2 timer_counter

Here Insert Picture Description
Here Insert Picture Description

2.3 timer_control

Here Insert Picture Description

get prescaler

15:8 bits
Here Insert Picture Description

Here Insert Picture Description
]

set scaler

Dividing 0 to 225

  • Read the initial value,
  • The corresponding bit is set to 0 & ~
  • | New value << 8 Bit 15: 8 is set to a new value

Here Insert Picture Description

enable interrupt

Here Insert Picture Description
Here Insert Picture Description
Here Insert Picture Description

enable autoreload

Here Insert Picture Description

Here Insert Picture Description
Here Insert Picture Description

enable timer

Here Insert Picture Description

Start Timer

enable bit =1
Here Insert Picture Description
Here Insert Picture Description

restart

re load
change the counter value simutaniously
Here Insert Picture Description

2.4 timer_interrupt_state

Here Insert Picture Description
Here Insert Picture Description
Here Insert Picture Description

3 TTC

4 code

Global 4.1 hours

s32 usleep(u32 useconds)
{
	XTime tEnd, tCur;
	XTime_GetTime(&tCur);
	tEnd = tCur + (((XTime) useconds) * COUNTS_PER_USECOND);
	do
	{
		XTime_GetTime(&tCur);
	} while (tCur < tEnd);

	return 0;
}

The idea is to get to achieve the present moment tCur, after calculating the delay time tEnd after useconds, after constantly asking timer current time, over time, will reach or exceed tEnd, at this time delay considered complete, you can quit. Here XTime_GetTime read the global clock, detail later said.

4.2 private timer

static XScuGic GIC; //GIC
static  XScuTimer Timer;//timer

(1) GIC initialization, and turn from hardware

This section generally unchanged

1) GIC cfg load

使用
XScuGic_CfgInitialize(GIC, IntcConfig,
IntcConfig->CpuBaseAddress);

Intermediate variable required XScuGic_Config * IntcConfig;, IntcConfig = XScuGic_LookupConfig (INTC_DEVICE_ID);

2) open IRQ hardware hander

Xil_ExceptionRegisterHandler(5,
		(Xil_ExceptionHandler)XScuGic_InterruptHandler,
		(void *)IntcInstancePtr);

Xil_ExceptionEnable();
int Init_Intr_System(XScuGic * IntcInstancePtr)  //一般不需要修改
{
	int Status;

	XScuGic_Config *IntcConfig;
	/*
	 * Initialize the interrupt controller driver so that it is ready to
	 * use.
	 */
	IntcConfig = XScuGic_LookupConfig(INTC_DEVICE_ID);
	if (NULL == IntcConfig) {
		return XST_FAILURE;
	}

	Status = XScuGic_CfgInitialize(IntcInstancePtr, IntcConfig,
					IntcConfig->CpuBaseAddress);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	/* Enable interrupts from the hardware */
	Xil_ExceptionInit();
	Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
			(Xil_ExceptionHandler)XScuGic_InterruptHandler,
			(void *)IntcInstancePtr);
	Xil_ExceptionEnable();


	return XST_SUCCESS;
}

(2) timer connected GIC, and enables GIC

1) GIC connection, and provides a transaction after the timer interrupt hander TimerIntrHandler

XScuGic_Connect(GicInstancePtr, TimerIntrId,
(Xil_ExceptionHandler)TimerIntrHandler,//set up the timer interrupt
(void *)TimerInstancePtr);

static void TimerIntrHandler(void *CallBackRef)
{
    XScuTimer *TimerInstancePtr = (XScuTimer *) CallBackRef;
    XScuTimer_ClearInterruptStatus(TimerInstancePtr);
    sec++;
    printf("seconds is %d \n",sec);
}

2) Enable the GIC, and prioritize

    XScuGic_Enable(GicInstancePtr, TimerIntrId);//enable the interrupt for the Timer at GIC
    XScuGic_SetPriorityTriggerType(GicInstancePtr,  TimerIntrId, 0XA0 , 3 ) ;
void Timer_Setup_Intr_System(XScuGic *GicInstancePtr,XScuTimer *TimerInstancePtr, u16 TimerIntrId)//29号
{
        XScuGic_Connect(GicInstancePtr, TimerIntrId,
                        (Xil_ExceptionHandler)TimerIntrHandler,//set up the timer interrupt
                        (void *)TimerInstancePtr);

        XScuGic_Enable(GicInstancePtr, TimerIntrId);//enable the interrupt for the Timer at GIC
        XScuGic_SetPriorityTriggerType(GicInstancePtr,  TimerIntrId, 0XA0 , 3 ) ;

 }


(3) timer settings and enable interrupt

1) TimerPtr initialization

Middle cfg variable XScuTimer_Config * TMRConfigPtr; // timer config

2) four operations

Set frequency, the count value is loaded automatically reload, enable interrupts

 XScuTimer_SetPrescaler(TimerPtr,  PrescalerValue) ;
 XScuTimer_LoadTimer(TimerPtr, Load_Value);
 XScuTimer_EnableAutoReload(TimerPtr);
 XScuTimer_EnableInterrupt(TimerPtr);//enable interrupt on the timer
int Timer_init(XScuTimer *TimerPtr, u8 PrescalerValue , u32 Load_Value,u32 DeviceId)
{
     XScuTimer_Config *TMRConfigPtr;     //timer config
     TMRConfigPtr = XScuTimer_LookupConfig(DeviceId);
     XScuTimer_CfgInitialize(TimerPtr, TMRConfigPtr,TMRConfigPtr->BaseAddr);
     XScuTimer_SetPrescaler(TimerPtr,  PrescalerValue) ;
     XScuTimer_LoadTimer(TimerPtr, Load_Value);
     XScuTimer_EnableAutoReload(TimerPtr);
     XScuTimer_EnableInterrupt(TimerPtr);//enable interrupt on the timer
     return 1;
}

(4) timer starts counting

 XScuTimer_Start(TimerPtr);

Here Insert Picture Description

Published 452 original articles · won praise 271 · views 730 000 +

Guess you like

Origin blog.csdn.net/qq_35608277/article/details/105086780