Jump to content
  • 0

Timer interrupt Zybo Z7 Timer Load Value


Pablo J

Question

I'm working in a project with a Zybo Z7-10 and I want to generate a timer interrupt every 20 ms. I did a vivado and vitis project but I don't know what is the correct Timer Load Value to generate this interrupt. Could someone help me? 

Thanks a lot.

PD: This is the project.


#include <stdio.h>
#include "xparameters.h"
#include "xil_printf.h"
#include "xgpio.h"
#include "xil_types.h"
#include "sleep.h"
#include "xtmrctr.h"
#include "xscugic.h"
#include "xil_exception.h"


// Get device IDs from xparameters.h
#define BTN_ID XPAR_AXI_GPIO_BUTTONS_DEVICE_ID
#define LED_ID XPAR_AXI_GPIO_LEDS_DEVICE_ID
#define LED_RGB_ID XPAR_AXI_GPIO_RGB_LED_DEVICE_ID
#define SW_ID XPAR_AXI_GPIO_SWITHCES_DEVICE_ID

#define INTC_DEVICE_ID XPAR_PS7_SCUGIC_0_DEVICE_ID
#define TMR_DEVICE_ID XPAR_TMRCTR_0_DEVICE_ID
#define INTC_TMR_INTERRUPT_ID XPAR_FABRIC_AXI_TIMER_0_INTERRUPT_INTR

#define TMR_LOAD    0x00659F9F

#define BTN_CHANNEL 1
#define LED_CHANNEL 1
#define SW_CHANNEL 1
#define LED_RGB_CHANNEL 1

#define BTN_MASK 0b1111
#define LED_MASK 0b0000
#define SW_MASK 0b1111
#define LED_RGB_MASK 0b0000

XScuGic INTCInst;
XTmrCtr TMRInst;


static void TMR_Intr_Handler(void *baseaddr_p);
static int IntcInitFunction(u16 DeviceId, XTmrCtr *TmrInstancePtr);

void TMR_Intr_Handler(void *data){
    if(XTmrCtr_IsExpired(&TMRInst, 0)){
        if(tmr_count == 10){
            XTmrCtr_Stop(&TMRInst,0);
            xil_printf("Interrupcion\r\n");
            XTmrCtr_Reset(&TMRInst,0);
            XTmrCtr_Start(&TMRInst,0);
    }
}

int InterruptSystemSetup(XScuGic *XScuGicInstancePtr){

    Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_INT,
            (Xil_ExceptionHandler) XScuGic_InterruptHandler,
            XScuGicInstancePtr);

    Xil_ExceptionEnable();

    return XST_SUCCESS;
}

int IntcInitFunction(u16 DeviceId, XTmrCtr *TmrInstancePtr){
    XScuGic_Config *IntcConfig;
    int status;

    IntcConfig = XScuGic_LookupConfig(DeviceId);
    status = XScuGic_CfgInitialize(&INTCInst, IntcConfig,
            IntcConfig->CpuBaseAddress);
    if(status != XST_SUCCESS)
        return XST_FAILURE;

    status = InterruptSystemSetup(&INTCInst);
    if(status != XST_SUCCESS)
        return XST_FAILURE;

    status = XScuGic_Connect(&INTCInst, INTC_TMR_INTERRUPT_ID,
            (Xil_ExceptionHandler) TMR_Intr_Handler, (void *) TmrInstancePtr);
    if(status != XST_SUCCESS)
        return XST_FAILURE;

    XScuGic_Enable(&INTCInst, INTC_TMR_INTERRUPT_ID);

    return XST_SUCCESS;
}


int main() {

    XGpio_Config *cfg_ptr;
    XGpio led_device, btn_device, sw_device, led_rgb_device;
    u32 data, data1;
    int status;

    xil_printf("Entered function main\r\n");

    // Initialize LED Device
    cfg_ptr = XGpio_LookupConfig(LED_ID);
    XGpio_CfgInitialize(&led_device, cfg_ptr, cfg_ptr->BaseAddress);

    // Initialize Button Device
    cfg_ptr = XGpio_LookupConfig(BTN_ID);
    XGpio_CfgInitialize(&btn_device, cfg_ptr, cfg_ptr->BaseAddress);

    // Initialize Switch Device
    cfg_ptr = XGpio_LookupConfig(SW_ID);
    XGpio_CfgInitialize(&sw_device, cfg_ptr, cfg_ptr->BaseAddress);

    // Initialize LED RGB Device
    cfg_ptr = XGpio_LookupConfig(LED_RGB_ID);
    XGpio_CfgInitialize(&led_rgb_device, cfg_ptr, cfg_ptr->BaseAddress);

    // Set Button Tristate
    XGpio_SetDataDirection(&btn_device, BTN_CHANNEL, BTN_MASK);

    // Set Led Tristate
    XGpio_SetDataDirection(&led_device, LED_CHANNEL, LED_MASK);

    // Set Button Tristate
    XGpio_SetDataDirection(&sw_device, BTN_CHANNEL, SW_MASK);

    // Set Led Tristate
    XGpio_SetDataDirection(&led_rgb_device, LED_RGB_CHANNEL, LED_RGB_MASK);

    status = IntcInitFunction(INTC_DEVICE_ID, &TMRInst);
    if(status != XST_SUCCESS)
        return XST_FAILURE;

    //Setup the timer
    status = XTmrCtr_Initialize(&TMRInst, TMR_DEVICE_ID);
    if(status != XST_SUCCESS)
        return XST_FAILURE;

    XTmrCtr_SetHandler(&TMRInst, (XTmrCtr_Handler) TMR_Intr_Handler, &TMRInst);
    XTmrCtr_SetResetValue(&TMRInst, 0, TMR_LOAD);
    XTmrCtr_SetOptions(&TMRInst, 0, XTC_INT_MODE_OPTION | XTC_AUTO_RELOAD_OPTION);

    XTmrCtr_Start(&TMRInst,0);
    xil_printf("Empieza");

    while (1) {
        data = XGpio_DiscreteRead(&btn_device, BTN_CHANNEL);
        XGpio_DiscreteWrite(&led_device, LED_CHANNEL, data);
        data1 = XGpio_DiscreteRead(&sw_device, BTN_CHANNEL);
        XGpio_DiscreteWrite(&led_rgb_device, LED_RGB_CHANNEL, data1);
        usleep(100000);
    }
}

Link to comment
Share on other sites

1 answer to this question

Recommended Posts

  • 0

Hi @Pablo J,

I'm not certain why you are using TMR_LOAD rather than TIMER_LOAD_VALUE, but normally the timer is calculated based on frequency of the arm core processor. There are several threads on the Xilinx forum that go into more detail here, here, here, with Xilinx's interrupt example on using the Cortex A9 Private Timer here.

Thanks,
JColvin

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...