Exemple #1
0
void loop(void) {
    toggleLED();
    delay(100);

    dma_channel_reg_map *ch_regs = dma_channel_regs(USART_DMA_DEV,
                                   USART_RX_DMA_CHANNEL);
    if (irq_fired) {
        USART_HWSER.println("** IRQ **");
        while (true)
            ;
    }
    USART_HWSER.print("[");
    USART_HWSER.print(millis());
    USART_HWSER.print("]\tISR bits: 0x");
    uint8 isr_bits = dma_get_isr_bits(USART_DMA_DEV, USART_RX_DMA_CHANNEL);
    USART_HWSER.print((int32)isr_bits, HEX);
    USART_HWSER.print("\tCCR: 0x");
    USART_HWSER.print((int64)ch_regs->CCR, HEX);
    USART_HWSER.print("\tCNDTR: 0x");
    USART_HWSER.print((int64)ch_regs->CNDTR, HEX);
    USART_HWSER.print("\tBuffer contents: ");
    for (int i = 0; i < BUF_SIZE; i++) {
        USART_HWSER.print('\'');
        USART_HWSER.print(rx_buf[i]);
        USART_HWSER.print('\'');
        if (i < BUF_SIZE - 1) USART_HWSER.print(", ");
    }
    USART_HWSER.println();
    if (isr_bits == 0x7) {
        USART_HWSER.println("** Clearing ISR bits.");
        dma_clear_isr_bits(USART_DMA_DEV, USART_RX_DMA_CHANNEL);
    }

    irq_fired = 0;
}
Exemple #2
0
void dma_set_per_addr(dma_dev *dev, dma_channel channel, volatile void *addr) {
    dma_channel_reg_map *chan_regs;

    ASSERT_FAULT(!dma_is_channel_enabled(dev, channel));

    chan_regs = dma_channel_regs(dev, channel);
    chan_regs->CPAR = (uint32)addr;
}
Exemple #3
0
/**
 * @brief Set the base memory address where data will be read from or
 *        written to.
 *
 * You must not call this function while the channel is enabled.
 *
 * If the DMA memory size is 16 bits, the address is automatically
 * aligned to a half-word.  If the DMA memory size is 32 bits, the
 * address is aligned to a word.
 *
 * @param dev DMA Device
 * @param channel Channel whose base memory address to set.
 * @param addr Memory base address to use.
 */
void dma_set_mem_addr(dma_dev *dev, dma_channel channel, __io void *addr) {
    dma_channel_reg_map *chan_regs;

    ASSERT_FAULT(!dma_is_channel_enabled(dev, channel));

    chan_regs = dma_channel_regs(dev, channel);
    chan_regs->CMAR = (uint32)addr;
}
Exemple #4
0
void dma_set_num_transfers(dma_dev *dev,
                           dma_channel channel,
                           uint16 num_transfers) {
    dma_channel_reg_map *channel_regs;

    ASSERT_FAULT(!dma_is_channel_enabled(dev, channel));

    channel_regs = dma_channel_regs(dev, channel);
    channel_regs->CNDTR = num_transfers;
}
Exemple #5
0
void dma_set_priority(dma_dev *dev,
                      dma_channel channel,
                      dma_priority priority) {
    dma_channel_reg_map *channel_regs;
    uint32 ccr;

    ASSERT_FAULT(!dma_is_channel_enabled(dev, channel));

    channel_regs = dma_channel_regs(dev, channel);
    ccr = channel_regs->CCR;
    ccr &= ~DMA_CCR_PL;
    ccr |= (priority << 12);
    channel_regs->CCR = ccr;
}
Exemple #6
0
/**
 * @brief Set up a DMA transfer.
 *
 * The channel will be disabled before being reconfigured.  The
 * transfer will have low priority by default.  You may choose another
 * priority before the transfer begins using dma_set_priority(), as
 * well as performing any other configuration you desire.  When the
 * channel is configured to your liking, enable it using dma_enable().
 *
 * @param dev DMA device.
 * @param channel DMA channel.
 * @param peripheral_address Base address of peripheral data register
 *                           involved in the transfer.
 * @param peripheral_size Peripheral data transfer size.
 * @param memory_address Base memory address involved in the transfer.
 * @param memory_size Memory data transfer size.
 * @param mode Logical OR of dma_mode_flags
 * @sideeffect Disables the given DMA channel.
 * @see dma_xfer_size
 * @see dma_mode_flags
 * @see dma_set_num_transfers()
 * @see dma_set_priority()
 * @see dma_attach_interrupt()
 * @see dma_enable()
 */
void dma_setup_transfer(dma_dev       *dev,
                        dma_channel    channel,
                        __io void     *peripheral_address,
                        dma_xfer_size  peripheral_size,
                        __io void     *memory_address,
                        dma_xfer_size  memory_size,
                        uint32         mode) {
    dma_channel_reg_map *channel_regs = dma_channel_regs(dev, channel);

    dma_disable(dev, channel);  /* can't write to CMAR/CPAR otherwise */
    channel_regs->CCR = (memory_size << 10) | (peripheral_size << 8) | mode;
    channel_regs->CMAR = (uint32)memory_address;
    channel_regs->CPAR = (uint32)peripheral_address;
}
Exemple #7
0
void dma_disable(dma_dev *dev, dma_channel channel) {
    dma_channel_reg_map *chan_regs = dma_channel_regs(dev, channel);
    bb_peri_set_bit(&chan_regs->CCR, DMA_CCR_EN_BIT, 0);
}
Exemple #8
0
void dma_detach_interrupt(dma_dev *dev, dma_channel channel) {
    /* Don't use nvic_irq_disable()! Think about DMA2 channels 4 and 5. */
    dma_channel_regs(dev, channel)->CCR &= ~0xF;
    DMA_GET_HANDLER(dev, channel) = NULL;
}
Exemple #9
0
/**
 * @brief Detach a DMA transfer interrupt handler.
 *
 * After calling this function, the given channel's interrupts will be
 * disabled.
 *
 * @param dev DMA device
 * @param channel Channel whose handler to detach
 * @sideeffect Clears interrupt enable bits in the channel's CCR register.
 * @see dma_attach_interrupt()
 */
void dma_detach_interrupt(dma_dev *dev, dma_channel channel) {
    /* Don't use nvic_irq_disable()! Think about DMA2 channels 4 and 5. */
    dma_channel_regs(dev, channel)->CCR &= ~0xF;
    dev->handlers[channel - 1].handler = NULL;
}