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.. }
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 */ }
//------------------------------------------------------------------------------ // 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; }
/* 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 sendSerialPacket(struct serial *serial, volatile struct dxl_packet *packet) { // We have a packet for the serial bus // First, clear the serial input buffers serial->port->flush(); // Writing the packet in the buffer int n = dxl_write_packet(packet, (ui8 *)serial->outputBuffer); // Go in transmit mode transmitMode(serial); #if 1 // Then runs the DMA transfer serial->txComplete = false; serial->dmaEvent = false; setupSerialDMA(serial, n); dma_tube_cfg(DMA1, serial->channel, &serial->tube_config); dma_set_priority(DMA1, serial->channel, DMA_PRIORITY_VERY_HIGH); if (serial->index == 1) dma_attach_interrupt(DMA1, serial->channel, DMAEvent1); if (serial->index == 2) dma_attach_interrupt(DMA1, serial->channel, DMAEvent2); if (serial->index == 3) dma_attach_interrupt(DMA1, serial->channel, DMAEvent3); usart_tcie(serial->port->c_dev()->regs, 1); dma_enable(DMA1, serial->channel); serial->packetSent = millis(); #else // Directly send the packet char buffer[1024]; n = dxl_write_packet(packet, (ui8 *)buffer); for (int i=0; i<n; i++) { serial->port->write(buffer[i]); } serial->port->waitDataToBeSent(); receiveMode(serial); #endif }
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; } }
/* This will set the Scan Mode on. This will use DMA. */ void STM32ADC::attachDMAInterrupt(voidFuncPtr func){ _DMA_int = func; dma_attach_interrupt(DMA1, DMA_CH1, func); }
/** * 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; }