Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/board_usi_i2cslave/attiny85_i2cslave.c
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ static inline void SET_USI_TO_RECEIVE_ACK()
i2cStatus = USII2CSLV_RECEIVING_ACK_FOR_TX;
DDR_USI &= ~(1 << PORT_USI_SDA);
PORT_USI|= _BV(PORT_USI_SDA);
USIDR = 0x80;
USIDR = 0;
USISR = (0 << USISIF) | (1 << USIOIF) | (1 << USIPF) |
(1 << USIDC) | (0x0E << USICNT0);
}
Expand Down
3 changes: 2 additions & 1 deletion simavr/sim/avr_ioport.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,8 @@ avr_ioport_irq_notify(
*/

avr->data[p->r_port] = new_out;
return; // TODO: stop further processing of IRQ.
irq->flags |= IRQ_FLAG_NTF_STOP; // Stop further processing of IRQ.
return;
}
} else {
// Set the real PIN bit.
Expand Down
11 changes: 9 additions & 2 deletions simavr/sim/sim_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,16 @@ avr_register_io(
avr_t *avr,
avr_io_t * io)
{
io->next = avr->io_port;
io->avr = avr;
avr->io_port = io;
io->next = NULL;
if (!avr->io_port) {
avr->io_port = io;
} else {
avr_io_t * port = avr->io_port;
while (port->next)
port = port->next;
port->next = io;
}
}

void
Expand Down
56 changes: 38 additions & 18 deletions simavr/sim/sim_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,14 @@ avr_alloc_irq(

static avr_irq_hook_t *
_avr_alloc_irq_hook(
avr_irq_t * irq)
avr_irq_hook_t ** parent)
{
avr_irq_hook_t *hook = malloc(sizeof(avr_irq_hook_t));
memset(hook, 0, sizeof(avr_irq_hook_t));
hook->next = irq->hook;
irq->hook = hook;
if (*parent)
(*parent)->next = hook;
else
(*parent) = hook;
return hook;
}

Expand Down Expand Up @@ -152,17 +154,23 @@ avr_irq_register_notify(
return;

avr_irq_hook_t *hook = irq->hook;
while (hook) {
if (hook->notify == notify && hook->param == param) {
if (irq->pool->avr->resetting) {
irq->value = 0;
irq->flags |= IRQ_FLAG_INIT;
if (!hook) {
hook = _avr_alloc_irq_hook(&(irq->hook));
} else {
do {
if (hook->notify == notify && hook->param == param) {
if (irq->pool->avr->resetting) {
irq->value = 0;
irq->flags |= IRQ_FLAG_INIT;
}
return; // already there
}
return; // already there
}
hook = hook->next;
if (!hook->next)
break;
hook = hook->next;
} while (1);
hook = _avr_alloc_irq_hook(&hook);
}
hook = _avr_alloc_irq_hook(irq);
hook->notify = notify;
hook->param = param;
}
Expand Down Expand Up @@ -217,8 +225,14 @@ avr_raise_irq_float(
// prevents reentrance / endless calling loops
if (hook->busy == 0) {
hook->busy++;
if (hook->notify)
if (hook->notify) {
hook->notify(irq, output, hook->param);
if (irq->flags & IRQ_FLAG_NTF_STOP) {
irq->flags &= ~IRQ_FLAG_NTF_STOP;
hook->busy--;
return; //Stop immediately, leaving irq->value untouched
}
}
if (hook->chain)
avr_raise_irq_float(hook->chain, output, floating);
hook->busy--;
Expand Down Expand Up @@ -249,12 +263,18 @@ avr_connect_irq(
return;
}
avr_irq_hook_t *hook = src->hook;
while (hook) {
if (hook->chain == dst)
return; // already there
hook = hook->next;
if (!hook) {
hook = _avr_alloc_irq_hook(&(src->hook));
} else {
do {
if (hook->chain == dst)
return; // already there
if (!hook->next)
break;
hook = hook->next;
} while (1);
hook = _avr_alloc_irq_hook(&hook);
}
hook = _avr_alloc_irq_hook(src);
hook->chain = dst;
}

Expand Down
1 change: 1 addition & 0 deletions simavr/sim/sim_irq.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ enum {
IRQ_FLAG_FILTERED = (1 << 1), //!< do not "notify" if "value" is the same as previous raise
IRQ_FLAG_ALLOC = (1 << 2), //!< this irq structure was malloced via avr_alloc_irq
IRQ_FLAG_INIT = (1 << 3), //!< this irq hasn't been used yet
IRQ_FLAG_NTF_STOP = (1 << 3), //!< only for notify functions - stop processing hooks after current notify
IRQ_FLAG_FLOATING = (1 << 4), //!< this 'pin'/signal is floating
IRQ_FLAG_STRONG = (1 << 5), //!< this 'pin'/signal is held at current state, do not "notify"
IRQ_FLAG_USER = (1 << 6), //!< Can be used by irq users
Expand Down
Loading