[PSR] MZAPO IRC interrupts

Jiri Hubacek hubacji1 at fel.cvut.cz
Wed Dec 20 23:19:48 CET 2017


Dear students,

ugly code for ICR IRQ handling follows. Please, discuss the code here. The
"hints" section at www [1] will be created based on your questions.

Please note that the code refers to Zynq-7000 Technical Reference Manual [2].

# References
[1]: http://rtime.felk.cvut.cz/psr/cviceni/semestralka/
[2]: https://www.xilinx.com/support/documentation/user_guides/ug585-Zynq-7000-TRM.pdf

---
#include <taskLib.h>
#include <stdio.h>
#include <kernelLib.h>
#include <semLib.h>
#include <intLib.h>
#include <iv.h>

SEM_ID irc_sem;
int irc_a, irc_b;

void irc_print_status(void)
{
        while (1) {
                semTake(irc_sem, WAIT_FOREVER);
                printf("a: %d, b: %d\n", irc_a, irc_b);
        }
}

void irc_isr(void)
{
        int sr; /* status register */
        sr = *(volatile uint32_t *) (0x43c20000 + 0x0004);
        irc_a = (sr & 0x100) >> 8;
        irc_b = (sr & 0x200) >> 9;
        semGive(irc_sem);
        *(volatile uint32_t *) (0xE000A000 + 0x00000298) = 0x4; /* reset (stat) */
}

/*
 *  Enable IRQ
 *
 *  See TRM, 14.2.4 Interrupt Function (pg. 391, pg. 1348). Technical reference
 *  manual link is on rtime HW wiki: https://rtime.felk.cvut.cz/hw/index.php/Zynq
 */
void irc_init(void)
{
        *(volatile uint32_t *) (0xE000A000 + 0x00000298) = 0x4; /* reset (stat) */
        *(volatile uint32_t *) (0xE000A000 + 0x00000284) = 0x0; /* set as input (dirm) */
        *(volatile uint32_t *) (0xE000A000 + 0x0000029c) = 0x4; /* rising edge (type) */
        *(volatile uint32_t *) (0xE000A000 + 0x000002a0) = 0x0; /* rising edge (polarity) */
        *(volatile uint32_t *) (0xE000A000 + 0x000002a4) = 0x0; /* rising edge (any) */
        *(volatile uint32_t *) (0xE000A000 + 0x00000290) = 0x4; /* enable interrupt (en) GPIO2 */

        intConnect(INUM_TO_IVEC(52), irc_isr, 0);
        intEnable(52);
}

void irc_disable(void)
{
        *(volatile uint32_t *) (0xE000A000 + 0x00000294) = 0x4; /* disable interrupt (dis) */

        intDisable(52);
        intDisconnect(INUM_TO_IVEC(52), irc_isr, 0);
}

/*
 * Entry point for DKM.
 */
void motor(void)
{
        TASK_ID st;

        irc_init();
        irc_sem = semCCreate(SEM_Q_FIFO, 0);
        st = taskSpawn("irc_st", 100, 0, 4096, (FUNCPTR) irc_print_status, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
        printf("All is ready.\n");

        taskDelay(1000);
        printf("Out of play time.\n");

        irc_disable();
        taskDelete(st);
}



More information about the PSR mailing list