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...
--- #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); }