/* (Called from exc.S with global interrupts disabled.) */ void __error(int num) { nvic_globalirq_enable(); usart_putstr(ERROR_USART, "\r\nexception: "); usart_putudec(ERROR_USART, num); usart_putc(ERROR_USART, '\n'); usart_putc(ERROR_USART, '\r'); for(;;); throb(); /* Turn off peripheral interrupts */ nvic_irq_disable_all(); /* Turn off timers */ timer_disable_all(); /* Turn off ADC */ adc_disable_all(); /* Turn off all USARTs */ usart_disable_all(); /* Turn the USB interrupt back on so the bootloader keeps on functioning */ nvic_irq_enable(NVIC_USB_HP_CAN_TX); nvic_irq_enable(NVIC_USB_LP_CAN_RX0); /* Reenable global interrupts */ nvic_globalirq_enable(); throb(); }
/** * @brief Discover the reason why a DMA interrupt was called. * * You may only call this function within an attached interrupt * handler for the given channel. * * This function resets the internal DMA register state which encodes * the cause of the interrupt; consequently, it can only be called * once per interrupt handler invocation. * * @brief dev DMA device * @brief channel Channel whose interrupt is being handled. * @return Reason why the interrupt fired. * @sideeffect Clears channel status flags in dev->regs->ISR. * @see dma_attach_interrupt() * @see dma_irq_cause */ dma_irq_cause dma_get_irq_cause(dma_dev *dev, dma_channel channel) { uint8 status_bits = dma_get_isr_bits(dev, channel); /* If the channel global interrupt flag is cleared, then * something's very wrong. */ ASSERT(status_bits & BIT(0)); dma_clear_isr_bits(dev, channel); /* ISR flags get set even if the corresponding interrupt enable * bits in the channel's configuration register are cleared, so we * can't use a switch here. * * Don't change the order of these if statements. */ if (status_bits & BIT(3)) { return DMA_TRANSFER_ERROR; } else if (status_bits & BIT(1)) { return DMA_TRANSFER_COMPLETE; } else if (status_bits & BIT(2)) { return DMA_TRANSFER_HALF_COMPLETE; } else if (status_bits & BIT(0)) { /* Shouldn't happen (unless someone messed up an IFCR write). */ throb(); } #if DEBUG_LEVEL < DEBUG_ALL else { /* We shouldn't have been called, but the debug level is too * low for the above ASSERT() to have had any effect. In * order to fail fast, mimic the DMA controller's behavior * when an error occurs. */ dma_disable(dev, channel); } #endif return DMA_TRANSFER_ERROR; }
static unsigned long deluxe_draw (Display *dpy, Window window, void *closure) { struct state *st = (struct state *) closure; int i; #ifdef HAVE_DOUBLE_BUFFER_EXTENSION if (!st->dbeclear_p || !st->backb) #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */ XFillRectangle (st->dpy, st->b, st->erase_gc, 0, 0, st->xgwa.width, st->xgwa.height); for (i = 0; i < st->count; i++) if (throb (st, st->b, st->throbbers[i]) < 0) st->throbbers[i] = make_throbber (st, st->b, st->xgwa.width, st->xgwa.height, st->colors[random() % st->ncolors].pixel); #ifdef HAVE_DOUBLE_BUFFER_EXTENSION if (st->backb) { XdbeSwapInfo info[1]; info[0].swap_window = st->window; info[0].swap_action = (st->dbeclear_p ? XdbeBackground : XdbeUndefined); XdbeSwapBuffers (st->dpy, info, 1); } else #endif /* HAVE_DOUBLE_BUFFER_EXTENSION */ if (st->dbuf) { XCopyArea (st->dpy, st->b, st->window, st->erase_gc, 0, 0, st->xgwa.width, st->xgwa.height, 0, 0); st->b = (st->b == st->ba ? st->bb : st->ba); } return st->delay; }
/* (Called from exc.S with global interrupts disabled.) */ void __error(void) { /* Turn off peripheral interrupts */ nvic_irq_disable_all(); /* Turn off timers */ timer_disable_all(); /* Turn off ADC */ adc_disable_all(); /* Turn off all USARTs */ usart_disable_all(); /* Turn the USB interrupt back on so the bootloader keeps on functioning */ nvic_irq_enable(NVIC_USB_HP_CAN_TX); nvic_irq_enable(NVIC_USB_LP_CAN_RX0); /* Reenable global interrupts */ nvic_globalirq_enable(); throb(); }
/** * @brief IRQ handler for I2C master. Handles transmission/reception. * @param dev I2C device */ static void i2c_irq_handler(i2c_dev *dev) { i2c_msg *msg = dev->msg; uint8 read = msg->flags & I2C_MSG_READ; uint32 sr1 = dev->regs->SR1; uint32 sr2 = dev->regs->SR2; I2C_CRUMB(IRQ_ENTRY, sr1, sr2); /* * Reset timeout counter */ dev->timestamp = systick_uptime(); /* * EV5: Start condition sent */ if (sr1 & I2C_SR1_SB) { msg->xferred = 0; i2c_enable_irq(dev, I2C_IRQ_BUFFER); /* * Master receiver */ if (read) { i2c_enable_ack(dev); } i2c_send_slave_addr(dev, msg->addr, read); sr1 = sr2 = 0; } /* * EV6: Slave address sent */ if (sr1 & I2C_SR1_ADDR) { /* * Special case event EV6_1 for master receiver. * Generate NACK and restart/stop condition after ADDR * is cleared. */ if (read) { if (msg->length == 1) { i2c_disable_ack(dev); if (dev->msgs_left > 1) { i2c_start_condition(dev); I2C_CRUMB(RX_ADDR_START, 0, 0); } else { i2c_stop_condition(dev); I2C_CRUMB(RX_ADDR_STOP, 0, 0); } } } else { /* * Master transmitter: write first byte to fill shift * register. We should get another TXE interrupt * immediately to fill DR again. */ if (msg->length != 1) { i2c_write(dev, msg->data[msg->xferred++]); } } sr1 = sr2 = 0; } /* * EV8: Master transmitter * Transmit buffer empty, but we haven't finished transmitting the last * byte written. */ if ((sr1 & I2C_SR1_TXE) && !(sr1 & I2C_SR1_BTF)) { I2C_CRUMB(TXE_ONLY, 0, 0); if (dev->msgs_left) { i2c_write(dev, msg->data[msg->xferred++]); if (msg->xferred == msg->length) { /* * End of this message. Turn off TXE/RXNE and wait for * BTF to send repeated start or stop condition. */ i2c_disable_irq(dev, I2C_IRQ_BUFFER); dev->msgs_left--; } } else { /* * This should be impossible... */ throb(); } sr1 = sr2 = 0; } /* * EV8_2: Master transmitter * Last byte sent, program repeated start/stop */ if ((sr1 & I2C_SR1_TXE) && (sr1 & I2C_SR1_BTF)) { I2C_CRUMB(TXE_BTF, 0, 0); if (dev->msgs_left) { I2C_CRUMB(TEST, 0, 0); /* * Repeated start insanity: We can't disable ITEVTEN or else SB * won't interrupt, but if we don't disable ITEVTEN, BTF will * continually interrupt us. What the f**k ST? */ i2c_start_condition(dev); while (!(dev->regs->SR1 & I2C_SR1_SB)) ; dev->msg++; } else { i2c_stop_condition(dev); /* * Turn off event interrupts to keep BTF from firing until * the end of the stop condition. Why on earth they didn't * have a start/stop condition request clear BTF is beyond * me. */ i2c_disable_irq(dev, I2C_IRQ_EVENT); I2C_CRUMB(STOP_SENT, 0, 0); dev->state = I2C_STATE_XFER_DONE; } sr1 = sr2 = 0; } /* * EV7: Master Receiver */ if (sr1 & I2C_SR1_RXNE) { I2C_CRUMB(RXNE_ONLY, 0, 0); msg->data[msg->xferred++] = dev->regs->DR; /* * EV7_1: Second to last byte in the reception? Set NACK and generate * stop/restart condition in time for the last byte. We'll get one more * RXNE interrupt before shutting things down. */ if (msg->xferred == (msg->length - 1)) { i2c_disable_ack(dev); if (dev->msgs_left > 2) { i2c_start_condition(dev); I2C_CRUMB(RXNE_START_SENT, 0, 0); } else { i2c_stop_condition(dev); I2C_CRUMB(RXNE_STOP_SENT, 0, 0); } } else if (msg->xferred == msg->length) { dev->msgs_left--; if (dev->msgs_left == 0) { /* * We're done. */ I2C_CRUMB(RXNE_DONE, 0, 0); dev->state = I2C_STATE_XFER_DONE; } else { dev->msg++; } } } }