예제 #1
0
/* Transmit the frambuffer with buffersize number of bytes to the LEDs 
 * buffersize = (#LEDs / 16) * 24 */
void neomaple_hard_send(uint8_t *buffer, uint32_t size)
{   
  // transmission complete flag, indicate that transmission is taking place
  WS2812_TC = 0;
  //WS2812_buffer = buffer;
  // clear all relevant DMA flags
  dma_clear_isr_bits(DMA1, DMA_CH2);
  dma_clear_isr_bits(DMA1, DMA_CH5);
  dma_clear_isr_bits(DMA1, DMA_CH7);

  // configure the number of bytes to be transferred by the DMA controller
  //dma_set_mem_addr(DMA1, DMA_CH5, WS2812_buffer);
  dma_set_num_transfers(DMA1, DMA_CH2, size);
  dma_set_num_transfers(DMA1, DMA_CH5, size);
  dma_set_num_transfers(DMA1, DMA_CH7, size);

  // clear all TIM2 flags
  TIMER2->regs.gen->SR = 0;
  
  // enable the corresponding DMA channels
  dma_enable(DMA1, DMA_CH2);
  dma_enable(DMA1, DMA_CH5);
  dma_enable(DMA1, DMA_CH7);
  // IMPORTANT: enable the TIM2 DMA requests AFTER enabling the DMA channels!
  timer_dma_enable_req(TIMER2, 1);
  timer_dma_enable_req(TIMER2, 2);
  timer_dma_enable_req(TIMER2, 0); /* TIM_DMA_Update */
  
  // preload counter with 29 so TIM2 generates UEV directly to start DMA transfer
  timer_set_count(TIMER2, 29);
  
  // start TIM2
  timer_resume(TIMER2);
}
예제 #2
0
dma_irq_cause dma_get_irq_cause(dma_dev *dev, dma_channel channel) {
    /* Grab and clear the ISR bits. */
    uint8 status_bits = dma_get_isr_bits(dev, channel);
    dma_clear_isr_bits(dev, channel);

    /* If the channel global interrupt flag is cleared, then
     * something's very wrong. */
    ASSERT(status_bits & 0x1);
    /* If GIF is set, then some other flag should be set, barring
     * something unexpected (e.g. the user making an unforeseen IFCR
     * write). */
    ASSERT(status_bits != 0x1);

    /* 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 & 0x8) {
        return DMA_TRANSFER_ERROR;
    } else if (status_bits & 0x2) {
        return DMA_TRANSFER_COMPLETE;
    } else if (status_bits & 0x4) {
        return DMA_TRANSFER_HALF_COMPLETE;
    }

    /* If we get here, one of our assumptions has been violated, but
     * the debug level is too low for the above ASSERTs() to have had
     * any effect. In order to fail fast, mimic the DMA controller's
     * behavior when an error occurs. */
    dma_disable(dev, channel);
    return DMA_TRANSFER_ERROR;
}
예제 #3
0
int dma_tube_cfg(dma_dev *dev, dma_channel channel, dma_tube_config *cfg) {
    dma_tube_reg_map *chregs;
    int ret = preconfig_check(dev, channel, cfg);

    if (ret < 0) {
        return ret;
    }

    dma_disable(dev, channel);        /* Must disable before reconfiguring */
    dma_clear_isr_bits(dev, channel); /* For sanity and consistency
                                       * with STM32F2. */

    chregs = dma_tube_regs(dev, channel);
    switch (_dma_addr_type(cfg->tube_dst)) {
    case DMA_ATYPE_PER:
        ret = config_to_per(chregs, cfg);
        break;
    case DMA_ATYPE_MEM:
        ret = config_to_mem(chregs, cfg);
        break;
    default:
        /* Can't happen */
        ASSERT(0);
        return -DMA_TUBE_CFG_ECFG;
    }
    if (ret < 0) {
        return ret;
    }
    chregs->CNDTR = cfg->tube_nr_xfers;
    return DMA_TUBE_CFG_SUCCESS;
}
예제 #4
0
파일: dma.c 프로젝트: iperry/libmaple
static inline void dispatch_handler(dma_dev *dev, dma_channel channel) {
    void (*handler)(void) = dev->handlers[channel - 1].handler;
    if (handler) {
        handler();
        dma_clear_isr_bits(dev, channel); /* in case handler doesn't */
    }
}
예제 #5
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;
}
예제 #6
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;
}
예제 #7
0
파일: dmaF2.c 프로젝트: jdkarpin/AeroQuad
static inline void dispatch_handler(dma_dev *dev, dma_stream stream) {
    void (*handler)(void) = dev->handlers[stream].handler;
    if (handler) {
        handler();
        dma_clear_isr_bits(dev, stream); /* in case handler doesn't */
    }
}
예제 #8
0
/* DMA1 Channel7 Interrupt Handler gets executed once the complete framebuffer has been transmitted to the LEDs */
void DMA1_Channel7_IRQHandler(void)
{
  // clear DMA7 transfer complete interrupt flag
  dma_clear_isr_bits(DMA1, DMA_CH7); 
  // enable TIM2 Update interrupt to append 50us dead period
  timer_enable_irq(TIMER2, TIMER_UPDATE_INTERRUPT);
  // disable the DMA channels
  dma_disable(DMA1, DMA_CH2);
  dma_disable(DMA1, DMA_CH5);
  dma_disable(DMA1, DMA_CH7);
  // IMPORTANT: disable the DMA requests, too!
  timer_dma_disable_req(TIMER2, 1);
  timer_dma_disable_req(TIMER2, 2);  
  timer_dma_disable_req(TIMER2, 0); /* TIM_DMA_Update */
}
예제 #9
0
파일: dma.c 프로젝트: FantasyJXF/ardupilot
static void dispatch_handler(dma_stream stream) {
#ifdef ISR_PERF
    t = stopwatch_getticks();
#endif
    const dma_dev * dev=DMAS[(stream>>4) & 3]; 

    Handler handler = dev->handlers[stream & 0xF];
    if (handler) {
        revo_call_handler(handler, (uint32_t)stream);
    }
    dma_clear_isr_bits(stream); /* in case handler doesn't */
#ifdef ISR_PERF
    t = stopwatch_getticks() - t;
    isr_time += t;
    if(t>max_isr_time) max_isr_time=t;
#endif
}