Beispiel #1
0
void DMA_init(void) {
  dma_init(DMA1);
  // TIM2 Update event
  /* DMA1 Channel2 configuration ----------------------------------------------*/
  dma_setup_transfer(DMA1, DMA_CH2, (volatile void*) &(GPIOA->regs->ODR), DMA_SIZE_32BITS, 
                                    (volatile void*) &(WS2812_IO_High), DMA_SIZE_8BITS, DMA_FROM_MEM);
  dma_set_priority(DMA1, DMA_CH2, DMA_PRIORITY_HIGH);

  // TIM2 CC1 event
  /* DMA1 Channel5 configuration ----------------------------------------------*/
  dma_setup_transfer(DMA1, DMA_CH5, (volatile void*) &(GPIOA->regs->ODR), DMA_SIZE_32BITS, 
                                    (volatile void*) WS2812_buffer, DMA_SIZE_8BITS, DMA_FROM_MEM | DMA_MINC_MODE);
  dma_set_priority(DMA1, DMA_CH5, DMA_PRIORITY_HIGH);

  
  // TIM2 CC2 event
  /* DMA1 Channel7 configuration ----------------------------------------------*/
  dma_setup_transfer(DMA1, DMA_CH7, (volatile void*) &(GPIOA->regs->ODR), DMA_SIZE_32BITS, 
                                    (volatile void*) &(WS2812_IO_Low), DMA_SIZE_8BITS, DMA_FROM_MEM | DMA_TRNS_CMPLT);
  dma_set_priority(DMA1, DMA_CH7, DMA_PRIORITY_HIGH);


  /* configure DMA1 Channel7 interrupt */
  nvic_irq_set_priority(NVIC_DMA_CH7, 1);
  nvic_irq_enable(NVIC_DMA_CH7);
  dma_attach_interrupt(DMA1, DMA_CH7, DMA1_Channel7_IRQHandler);
  /* enable DMA1 Channel7 transfer complete interrupt */
}
Beispiel #2
0
void init_ppm_dma_transfer()
{
    dma_init(DMA1);
    dma_setup_transfer( DMA1,    //dma device, dma1 here because that's the only one we have
                        DMA_CH1, //dma channel, channel1, because it looks after tim4_ch1 (timer4, channel1)
                        &(r.gen->CCR1), //peripheral address
                        DMA_SIZE_16BITS, //peripheral size
                        data, //memory address
                        DMA_SIZE_16BITS, //memory transfer size
                        (0
                         //| DMA_FROM_MEM  //set if going from memory, don't set if going to memory.
                         | DMA_MINC_MODE //auto inc where the data does in memory (uses size_16bits to know how much)
                         | DMA_TRNS_ERR  //tell me if it's fubar
                         //| DMA_HALF_TRNS //tell me half way (actually, don't as I spend so long there, I dont see 'complete')
                         | DMA_TRNS_CMPLT //tell me at the end
                         | DMA_CIRC_MODE // circular mode... capture "num_transfers" (below) and repeat
                         )
                        );

    dma_attach_interrupt(DMA1, DMA_CH1, dma_isr); //hook up an isr for the dma chan to tell us if things happen.
    dma_set_num_transfers(DMA1, DMA_CH1, NUM_TIMERS); //only allow it to transfer TIMERS number of times.
    dma_enable(DMA1, DMA_CH1);                    //enable it..


}
//------------------------------------------------------------------------------
// send one block of data for write block or write multiple blocks
uint8_t Sd2Card::writeData(uint8_t token, const uint8_t* src) {
#ifdef SPI_DMA
        dma_setup_transfer(DMA1, DMA_CH3, &SPI1->regs->DR, DMA_SIZE_8BITS, (uint8_t *)src, DMA_SIZE_8BITS, (DMA_MINC_MODE |  DMA_FROM_MEM | DMA_TRNS_CMPLT | DMA_TRNS_ERR));
        dma_attach_interrupt(DMA1, DMA_CH3, DMAEvent);
        dma_set_priority(DMA1, DMA_CH3, DMA_PRIORITY_VERY_HIGH);
        dma_set_num_transfers(DMA1, DMA_CH3, 512);

        dmaActive = true;
        dma_enable(DMA1, DMA_CH3);

        while(dmaActive) delayMicroseconds(1);
        dma_disable(DMA1, DMA_CH3);

#else  // SPI_DMA
  spiSend(token);
  for (uint16_t i = 0; i < 512; i++) {
    spiSend(src[i]);
  }
#endif  // OPTIMIZE_HARDWARE_SPI
  spiSend(0xff);  // dummy crc
  spiSend(0xff);  // dummy crc

  status_ = spiRec();
  if ((status_ & DATA_RES_MASK) != DATA_RES_ACCEPTED) {
    error(SD_CARD_ERROR_WRITE);
    chipSelectHigh();
	Serial.println("Error: Write");
    Serial.println("Error: Sd2Card::writeData()");
    return false;
  }
  return true;
}
Beispiel #4
0
/*
    This function is used to setup DMA with the ADC. 
    It will be independent of the mode used. It will either be used in continuous or scan mode
    or even both... 
    This function is to be used with Dual ADC (the difference is to use 32bit buffers).
*/
    void STM32ADC::setDualDMA(uint32 * Buf, uint16 BufLen, uint32 Flags){
        dma_init(DMA1);
        adc_dma_enable(_dev);
        dma_setup_transfer(DMA1, DMA_CH1, &_dev->regs->DR, DMA_SIZE_32BITS,//(DMA_MINC_MODE | DMA_CIRC_MODE)
                     Buf, DMA_SIZE_32BITS, Flags);// Receive buffer DMA
        dma_set_num_transfers(DMA1, DMA_CH1, BufLen);
        dma_enable(DMA1, DMA_CH1); // Enable the channel and start the transfer.
    }
/* Configure DMA transmission */
void init_dma_xfer(void) {
    dma_init(USART_DMA_DEV);
    dma_setup_transfer(USART_DMA_DEV, USART_RX_DMA_CHANNEL,
                       &USART->regs->DR, DMA_SIZE_8BITS,
                       rx_buf,           DMA_SIZE_8BITS,
                       (DMA_MINC_MODE | DMA_CIRC_MODE | DMA_TRNS_CMPLT));
    dma_set_num_transfers(USART_DMA_DEV, USART_RX_DMA_CHANNEL, BUF_SIZE);
    dma_attach_interrupt(USART_DMA_DEV, USART_RX_DMA_CHANNEL, rx_dma_irq);
    dma_enable(USART_DMA_DEV, USART_RX_DMA_CHANNEL);
}
Beispiel #6
0
    void STM32ADC::setDMA(uint16 * Buf, uint16 BufLen, uint32 dmaFlags, voidFuncPtr func) {
//initialize DMA
        dma_init(DMA1);
//if there is an int handler to be called... 
        if (func != NULL)
            dma_attach_interrupt(DMA1, DMA_CH1, func);
//enable ADC DMA transfer
        //adc_dma_enable(ADC1);
        _dev->regs->CR2 |= ADC_CR2_DMA;
//set it up... 
        dma_setup_transfer(DMA1, DMA_CH1, &ADC1->regs->DR, DMA_SIZE_16BITS, Buf, DMA_SIZE_16BITS, dmaFlags);// Receive buffer DMA
//how many are we making?? 
        dma_set_num_transfers(DMA1, DMA_CH1, BufLen);
//enable dma.
        dma_enable(DMA1, DMA_CH1); // Enable the channel and start the transfer.
    }
/** Skip remaining data in a block when in partial block read mode. */
void Sd2Card::readEnd(void) {
  if (inBlock_) {
      // skip data and crc
#ifdef SPI_DMA
        dma_setup_transfer(DMA1, DMA_CH3, &SPI1->regs->DR, DMA_SIZE_8BITS, ack, DMA_SIZE_8BITS,
                           (/*DMA_MINC_MODE | DMA_CIRC_MODE |*/ DMA_FROM_MEM | DMA_TRNS_CMPLT | DMA_TRNS_ERR));
        dma_attach_interrupt(DMA1, DMA_CH3, DMAEvent);
        dma_set_priority(DMA1, DMA_CH3, DMA_PRIORITY_VERY_HIGH);
        dma_set_num_transfers(DMA1, DMA_CH3, SPI_BUFF_SIZE + 1 - offset_);

        dmaActive = true;
        dma_enable(DMA1, DMA_CH3);

        while(dmaActive)delayMicroseconds(1);
        dma_disable(DMA1, DMA_CH3);
#else  // SPI_DMA
    while (offset_++ < 514) spiRec();
#endif  // SPI_DMA
    chipSelectHigh();
    inBlock_ = 0;
  }
}
/**
 * Read part of a 512 byte block from an SD card.
 *
 * \param[in] block Logical block to be read.
 * \param[in] offset Number of bytes to skip at start of block
 * \param[out] dst Pointer to the location that will receive the data.
 * \param[in] count Number of bytes to read
 * \return The value one, true, is returned for success and
 * the value zero, false, is returned for failure.
 */
uint8_t Sd2Card::readData(uint32_t block,
        uint16_t offset, uint16_t count, uint8_t* dst) {
  //uint16_t n;
  if (count == 0) return true;
  if ((count + offset) > 512) {
    goto fail;
  }
  if (!inBlock_ || block != block_ || offset < offset_) {
    block_ = block;
    // use address if not SDHC card
    if (type()!= SD_CARD_TYPE_SDHC) block <<= 9;
    if (cardCommand(CMD17, block)) {
      error(SD_CARD_ERROR_CMD17);
	  Serial.println("Error: CMD17");
      goto fail;
    }
    if (!waitStartBlock()) {
      goto fail;
    }
    offset_ = 0;
    inBlock_ = 1;
  }

#ifdef SPI_DMA
    // skip data before offset
    if(offset_ < offset){
        dma_setup_transfer(DMA1,
				DMA_CH3,
				&SPI1->regs->DR,
				DMA_SIZE_8BITS,
				ack,
				DMA_SIZE_8BITS,
                           (/*DMA_MINC_MODE | DMA_CIRC_MODE  |*/ DMA_FROM_MEM | DMA_TRNS_CMPLT | DMA_TRNS_ERR));
        dma_attach_interrupt(DMA1, DMA_CH3, DMAEvent);
        dma_set_priority(DMA1, DMA_CH3, DMA_PRIORITY_VERY_HIGH);
        dma_set_num_transfers(DMA1, DMA_CH3, offset - offset_);

        dmaActive = true;
        dma_enable(DMA1, DMA_CH3);

        while(dmaActive) delayMicroseconds(1);
        dma_disable(DMA1, DMA_CH3);
    }
    offset_ = offset;

    // transfer data
    dma_setup_transfer(DMA1, DMA_CH2, &SPI1->regs->DR, DMA_SIZE_8BITS, dst, DMA_SIZE_8BITS,
                       (DMA_MINC_MODE | DMA_TRNS_CMPLT | DMA_TRNS_ERR));
    dma_attach_interrupt(DMA1, DMA_CH2, DMAEvent);
    dma_setup_transfer(DMA1, DMA_CH3, &SPI1->regs->DR, DMA_SIZE_8BITS, ack, DMA_SIZE_8BITS,
                       (/*DMA_MINC_MODE | DMA_CIRC_MODE |*/ DMA_FROM_MEM));
    dma_set_priority(DMA1, DMA_CH2, DMA_PRIORITY_VERY_HIGH);
    dma_set_priority(DMA1, DMA_CH3, DMA_PRIORITY_VERY_HIGH);
    dma_set_num_transfers(DMA1, DMA_CH2, count);
    dma_set_num_transfers(DMA1, DMA_CH3, count);

    dmaActive = true;
    dma_enable(DMA1, DMA_CH3);
    dma_enable(DMA1, DMA_CH2);

    while(dmaActive) delayMicroseconds(1);
    dma_disable(DMA1, DMA_CH3);
    dma_disable(DMA1, DMA_CH2);

    offset_ += count;
    if (!partialBlockRead_ || offset_ >= SPI_BUFF_SIZE) {
        readEnd();
    }

#else
  // skip data before offset
  for (;offset_ < offset; offset_++) {
    spiRec();
  }
  // transfer data
  for (uint16_t i = 0; i < count; i++) {
    dst[i] = spiRec();
  }
  offset_ += count;
  if (!partialBlockRead_ || offset_ >= 512) {
    // read rest of data, checksum and set chip select high
    readEnd();
  }
#endif

  return true;

 fail:
  chipSelectHigh();
  Serial.println("Error: Sd2Card::readData()");
  return false;
}