static void avr_watchdog_write(avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param) { avr_watchdog_t * p = (avr_watchdog_t *)param; // backup the registers // uint8_t wd = avr->data[p->wdce.reg]; uint8_t wdce_o = avr_regbit_get(avr, p->wdce); // old uint8_t wde_o = avr_regbit_get(avr, p->wde); uint8_t wdp_o[4]; // printf("avr_watchdog_write %02x\n", v); for (int i = 0; i < 4; i++) wdp_o[i] = avr_regbit_get(avr, p->wdp[i]); avr->data[p->wdce.reg] = v; uint8_t wdce_n = avr_regbit_get(avr, p->wdce); // new if (wdce_o /* || wdce_n */) { // make sure bit gets reset eventually if (wdce_n) avr_cycle_timer_register(avr, 4, avr_wdce_clear, p); uint8_t wdp = avr_regbit_get_array(avr, p->wdp, 4); p->cycle_count = 2048 << wdp; p->cycle_count = (p->cycle_count * avr->frequency) / 128000; if (avr_regbit_get(avr, p->wde)) { printf("Watchdog reset to %d cycles @ 128kz (* %d) = %d CPU cycles)\n", 2048 << wdp, 1 << wdp, (int)p->cycle_count); avr_cycle_timer_register(avr, p->cycle_count, avr_watchdog_timer, p); } else { printf("Watchdog disabled\n"); avr_cycle_timer_cancel(avr, avr_watchdog_timer, p); } } else { // reset old values avr_regbit_setto(avr, p->wde, wde_o); for (int i = 0; i < 4; i++) avr_regbit_setto(avr, p->wdp[i], wdp_o[i]); v = avr->data[p->wdce.reg]; } avr_core_watch_write(avr, addr, v); }
int avr_clear_interrupt_if( avr_t * avr, avr_int_vector_t * vector, uint8_t old) { if (avr_regbit_get(avr, vector->raised)) { avr_clear_interrupt(avr, vector); return 1; } avr_regbit_setto(avr, vector->raised, old); return 0; }
int avr_clear_interrupt_if( avr_t * avr, avr_int_vector_t * vector, uint8_t old) { avr_raise_irq(avr->interrupts.irq + AVR_INT_IRQ_PENDING, avr_has_pending_interrupts(avr)); if (avr_regbit_get(avr, vector->raised)) { avr_clear_interrupt(avr, vector); return 1; } avr_regbit_setto(avr, vector->raised, old); return 0; }
/* * prevent code from rewriting out status bits, since we actualy use them! */ static void avr_twi_write_status( struct avr_t * avr, avr_io_addr_t addr, uint8_t v, void * param) { avr_twi_t * p = (avr_twi_t *)param; uint8_t sr = avr_regbit_get(avr, p->twsr); uint8_t c = avr_regbit_get(avr, p->twps); avr_core_watch_write(avr, addr, v); avr_regbit_setto(avr, p->twsr, sr); // force restore if (c != avr_regbit_get(avr, p->twps)) { // prescaler bits changed... } }