simio_timer: implement TAIV register.
This commit is contained in:
parent
65d15ef680
commit
ad6c39a0aa
|
@ -244,16 +244,24 @@ static int timer_config(struct simio_device *dev,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint16_t calc_iv(struct timer *tr)
|
static uint16_t calc_iv(struct timer *tr, int update)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < tr->size; i++)
|
for (i = 0; i < tr->size; i++)
|
||||||
if ((tr->ctls[i] & (CCIE | CCIFG)) == (CCIE | CCIFG))
|
if ((tr->ctls[i] & (CCIE | CCIFG)) == (CCIE | CCIFG)) {
|
||||||
|
/* Reading or writing TAIV clears the highest flag.
|
||||||
|
TACCR0 is cleared in timer_ack_interrupt(). */
|
||||||
|
if (update && (i > 0))
|
||||||
|
tr->ctls[i] &= ~CCIFG;
|
||||||
return i * 2;
|
return i * 2;
|
||||||
|
}
|
||||||
|
|
||||||
if ((tr->tactl & (TAIFG | TAIE)) == (TAIFG | TAIE))
|
if ((tr->tactl & (TAIFG | TAIE)) == (TAIFG | TAIE)) {
|
||||||
|
if (update)
|
||||||
|
tr->tactl &= ~TAIFG;
|
||||||
return 0xa;
|
return 0xa;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -270,7 +278,7 @@ static int timer_info(struct simio_device *dev)
|
||||||
printc("\n");
|
printc("\n");
|
||||||
printc("TACTL: 0x%04x\n", tr->tactl);
|
printc("TACTL: 0x%04x\n", tr->tactl);
|
||||||
printc("TAR: 0x%04x\n", tr->tar);
|
printc("TAR: 0x%04x\n", tr->tar);
|
||||||
printc("TAIV: 0x%02x\n", calc_iv(tr));
|
printc("TAIV: 0x%02x\n", calc_iv(tr, 0));
|
||||||
printc("\n");
|
printc("\n");
|
||||||
|
|
||||||
for (i = 0; i < tr->size; i++)
|
for (i = 0; i < tr->size; i++)
|
||||||
|
@ -315,6 +323,12 @@ static int timer_write(struct simio_device *dev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (addr == tr->iv_addr) {
|
||||||
|
/* Writing to TAIV clears the highest priority bit. */
|
||||||
|
calc_iv(tr, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,7 +349,7 @@ static int timer_read(struct simio_device *dev,
|
||||||
|
|
||||||
if (addr >= tr->base_addr + 2 &&
|
if (addr >= tr->base_addr + 2 &&
|
||||||
addr < tr->base_addr + tr->size + 2) {
|
addr < tr->base_addr + tr->size + 2) {
|
||||||
*data = tr->ctls[((addr - 0xf) - 2) >> 1];
|
*data = tr->ctls[((addr & 0xf) - 2) >> 1];
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -345,6 +359,11 @@ static int timer_read(struct simio_device *dev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (addr == tr->iv_addr) {
|
||||||
|
*data = calc_iv(tr, 1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,6 +391,7 @@ static void timer_ack_interrupt(struct simio_device *dev, int irq)
|
||||||
|
|
||||||
if (irq == tr->irq0)
|
if (irq == tr->irq0)
|
||||||
tr->ctls[0] &= ~CCIFG;
|
tr->ctls[0] &= ~CCIFG;
|
||||||
|
/* By design irq1 does not clear CCIFG or TAIFG automatically */
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tar_step(struct timer *tr)
|
static void tar_step(struct timer *tr)
|
||||||
|
|
Loading…
Reference in New Issue