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 */ }
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; }
/* 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); }
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; }