示例#1
0
/* (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();
}
示例#2
0
文件: dma.c 项目: iperry/libmaple
/**
 * @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;
}
示例#3
0
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;
}
示例#4
0
文件: util.c 项目: Saul2588/ousia
/* (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();
}
示例#5
0
/**
 * @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++;
            }
        }
    }
}