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 TBlockingSpiDmaJob::Run() { TaskId = TScheduler::GetCurrentTaskId(); CurrentJob = this; const uint32_t spi = FLASH_SPI_CHANNEL; const uint32_t dma = DMA1; assert(SPI_SR(spi) & SPI_SR_TXE); assert(~SPI_SR(spi) & SPI_SR_BSY); assert(!(SPI_SR(spi) & SPI_SR_RXNE)); { const uint32_t channel = FLASH_DMA_TX_CHANNEL; dma_channel_reset(dma, channel); dma_set_peripheral_address(dma, channel, reinterpret_cast<uint32_t>(&SPI_DR(spi))); dma_set_memory_address(dma, channel, reinterpret_cast<uint32_t>(Out)); dma_set_number_of_data(dma, channel, Len); dma_set_read_from_memory(dma, channel); dma_enable_memory_increment_mode(dma, channel); dma_set_peripheral_size(dma, channel, DMA_CCR_PSIZE_8BIT); dma_set_memory_size(dma, channel, DMA_CCR_MSIZE_8BIT); dma_set_priority(dma, channel, DMA_CCR_PL_LOW); // dma_enable_transfer_complete_interrupt(dma, channel); dma_enable_channel(dma, channel); } { const uint32_t channel = FLASH_DMA_RX_CHANNEL; dma_channel_reset(dma, channel); dma_set_peripheral_address(dma, channel, reinterpret_cast<uint32_t>(&SPI_DR(spi))); dma_set_number_of_data(dma, channel, Len); if (In != 0) { dma_set_memory_address(dma, channel, reinterpret_cast<uint32_t>(In)); dma_enable_memory_increment_mode(dma, channel); } else { dma_set_memory_address(dma, channel, reinterpret_cast<uint32_t>(&DummyPosition)); } dma_set_peripheral_size(dma, channel, DMA_CCR_PSIZE_8BIT); dma_set_memory_size(dma, channel, DMA_CCR_MSIZE_8BIT); dma_set_priority(dma, channel, DMA_CCR_PL_LOW); dma_enable_transfer_complete_interrupt(dma, channel); dma_enable_channel(dma, channel); } // Kick off the transfer spi_enable_rx_dma(spi); spi_enable_tx_dma(spi); // Wait for completion TScheduler::BlockUntil(&Finished); }
void usart_dma_init_tx(usart_num num) { usart_driver *driver = &usart_drivers[num]; const usart_dma *dma = &usart_dma_table[num]; usart_t *usart = (usart_t *)driver->p_dev->reg; /* Initial TX DMA */ dma_stream_t *tx_stream = (dma_stream_t *)dma->tx_stream_base; dma_set_channel(tx_stream, dma->tx_channel); dma_set_paddr(tx_stream, (uint32)&usart->DR); dma_set_m0addr(tx_stream, (uint32)driver->tx_buffer); dma_set_direction(tx_stream, DMA_DIR_MEM_TO_PER); dma_set_data_size(tx_stream, USART_BUFFER_SIZE); dma_set_pinc_mode(tx_stream, DISABLE); dma_set_minc_mode(tx_stream, ENABLE); dma_set_minc_size(tx_stream, DMA_DATA_SIZE_8); dma_set_pinc_size(tx_stream, DMA_DATA_SIZE_8); dma_set_circular_mode(tx_stream, DISABLE); dma_set_priority(tx_stream, DMA_PRIO_HIGH); dma_set_direct_mode(tx_stream, ENABLE); dma_set_fifo_threshold(tx_stream, DMA_FIFO_TH_FULL); dma_set_mburst(tx_stream, DMA_BURST_1); dma_set_pburst(tx_stream, DMA_BURST_1); dma_set_handler(dma->dma, dma->tx_stream, dma->tx_channel, usart_dma_tx_handler, (void *)driver); dma_set_it(tx_stream, DMA_IT_TC, ENABLE); dma_set_irq_enable(dma->dma, dma->tx_stream, ENABLE); usart_set_tx_dma_enable(usart, ENABLE); }
//------------------------------------------------------------------------------ // 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; }
/// Processing done after rx completes. void process_rx_dma_interrupt(struct spi_periph *periph) { struct spi_periph_dma *dma = periph->init_struct; struct spi_transaction *trans = periph->trans[periph->trans_extract_idx]; /* Disable DMA Channel */ dma_disable_transfer_complete_interrupt(dma->dma, dma->rx_chan); /* Disable SPI Rx request */ spi_disable_rx_dma((uint32_t)periph->reg_addr); /* Disable DMA rx channel */ dma_disable_channel(dma->dma, dma->rx_chan); if (dma->rx_extra_dummy_dma) { /* * We are finished the first part of the receive with real data, * but still need to run the dummy to get a transfer complete interrupt * after the complete transaction is done. */ /* Reset the flag so this only happens once in a transaction */ dma->rx_extra_dummy_dma = FALSE; /* Use the difference in length between rx and tx */ uint16_t len_remaining = trans->output_length - trans->input_length; spi_configure_dma(dma->dma, dma->rx_chan, (uint32_t)dma->spidr, (uint32_t)&(dma->rx_dummy_buf), len_remaining, trans->dss, FALSE); dma_set_read_from_peripheral(dma->dma, dma->rx_chan); dma_set_priority(dma->dma, dma->rx_chan, DMA_CCR_PL_HIGH); /* Enable DMA transfer complete interrupts. */ dma_enable_transfer_complete_interrupt(dma->dma, dma->rx_chan); /* Enable DMA channels */ dma_enable_channel(dma->dma, dma->rx_chan); /* Enable SPI transfers via DMA */ spi_enable_rx_dma((uint32_t)periph->reg_addr); } else { /* * Since the receive DMA is always run until the very end * and this interrupt is triggered after the last data word was read, * we now know that this transaction is finished. */ /* Run the callback */ trans->status = SPITransSuccess; if (trans->after_cb != 0) { trans->after_cb(trans); } /* AFTER the callback, then unselect the slave if required */ if (trans->select == SPISelectUnselect || trans->select == SPIUnselect) { SpiSlaveUnselect(trans->slave_idx); } spi_next_transaction(periph); } }
void mew_bluetooth_transmit(uint8_t* data, uint16_t size, uint8_t sync_mode) { mew_check_dma_memory((void*)data, "mew_bluetooth_transmit"); mew_wait_for_state(&_mew_dma_tx_state, 0); _mew_dma_tx_state = 1; dma_stream_reset(MEW_BLUETOOTH_DMA, MEW_BLUETOOTH_DMA_STREAM_TX); dma_set_transfer_mode(MEW_BLUETOOTH_DMA, MEW_BLUETOOTH_DMA_STREAM_TX, DMA_SxCR_DIR_MEM_TO_PERIPHERAL); dma_set_priority(MEW_BLUETOOTH_DMA, MEW_BLUETOOTH_DMA_STREAM_TX, DMA_SxCR_PL_HIGH); dma_set_memory_size(MEW_BLUETOOTH_DMA, MEW_BLUETOOTH_DMA_STREAM_TX, DMA_SxCR_MSIZE_8BIT); dma_set_peripheral_size(MEW_BLUETOOTH_DMA, MEW_BLUETOOTH_DMA_STREAM_TX, DMA_SxCR_PSIZE_8BIT); dma_enable_memory_increment_mode(MEW_BLUETOOTH_DMA, MEW_BLUETOOTH_DMA_STREAM_TX); dma_set_peripheral_address(MEW_BLUETOOTH_DMA, MEW_BLUETOOTH_DMA_STREAM_TX, (uint32_t) &MEW_BLUETOOTH_DMA_DR); dma_channel_select(MEW_BLUETOOTH_DMA, MEW_BLUETOOTH_DMA_STREAM_TX, MEW_BLUETOOTH_DMA_CHANNEL_TX); dma_set_memory_address(MEW_BLUETOOTH_DMA, MEW_BLUETOOTH_DMA_STREAM_TX, (uint32_t) data); dma_set_number_of_data(MEW_BLUETOOTH_DMA, MEW_BLUETOOTH_DMA_STREAM_TX, size); dma_disable_fifo_error_interrupt(MEW_BLUETOOTH_DMA, MEW_BLUETOOTH_DMA_STREAM_TX); dma_disable_half_transfer_interrupt(MEW_BLUETOOTH_DMA, MEW_BLUETOOTH_DMA_STREAM_TX); dma_enable_transfer_complete_interrupt(MEW_BLUETOOTH_DMA, MEW_BLUETOOTH_DMA_STREAM_TX); dma_enable_transfer_error_interrupt(MEW_BLUETOOTH_DMA, MEW_BLUETOOTH_DMA_STREAM_TX); dma_enable_transfer_complete_interrupt(MEW_BLUETOOTH_DMA, MEW_BLUETOOTH_DMA_STREAM_TX); __mew_bluetooth_clear_buf(); dma_enable_stream(MEW_BLUETOOTH_DMA, MEW_BLUETOOTH_DMA_STREAM_TX); if (sync_mode == 1) { mew_wait_for_state(&_mew_dma_tx_state, 0); } }
void hal_uart_dma_receive_block(uint8_t *data, uint16_t size){ // hal_uart_manual_rts_clear(); gpio_clear(GPIOB, GPIO_DEBUG_1); /* * USART3_RX is on DMA_CHANNEL3 */ // printf("hal_uart_dma_receive_block req size %u\n", size); /* Reset DMA channel*/ dma_channel_reset(DMA1, DMA_CHANNEL3); dma_set_peripheral_address(DMA1, DMA_CHANNEL3, (uint32_t)&USART3_DR); dma_set_memory_address(DMA1, DMA_CHANNEL3, (uint32_t)data); dma_set_number_of_data(DMA1, DMA_CHANNEL3, size); dma_set_read_from_peripheral(DMA1, DMA_CHANNEL3); dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL3); dma_set_peripheral_size(DMA1, DMA_CHANNEL3, DMA_CCR_PSIZE_8BIT); dma_set_memory_size(DMA1, DMA_CHANNEL3, DMA_CCR_MSIZE_8BIT); dma_set_priority(DMA1, DMA_CHANNEL3, DMA_CCR_PL_HIGH); dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL3); dma_enable_channel(DMA1, DMA_CHANNEL3); usart_enable_rx_dma(USART3); }
void baro_init() { gpio_set_mode(GPIOB, GPIO_MODE_INPUT, GPIO_CNF_INPUT_PULL_UPDOWN, GPIO14); gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO13 | GPIO15); gpio_set_mode(GPIOB, GPIO_MODE_OUTPUT_50_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, GPIO12); deselect_slave(); spi_init_master(SPI2, SPI_CR1_BAUDRATE_FPCLK_DIV_8, SPI_CR1_CPOL, SPI_CR1_CPHA, SPI_CR1_DFF_8BIT, SPI_CR1_MSBFIRST); spi_enable_ss_output(SPI2); spi_enable(SPI2); dma_set_peripheral_address(DMA1, DMA_CHANNEL3, SPI2_DR); dma_set_read_from_memory(DMA1, DMA_CHANNEL3); dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL3); dma_set_peripheral_size(DMA1, DMA_CHANNEL3, DMA_CCR_PSIZE_8BIT); dma_set_memory_size(DMA1, DMA_CHANNEL3, DMA_CCR_MSIZE_8BIT); dma_set_priority(DMA1, DMA_CHANNEL3, DMA_CCR_PL_HIGH); dma_set_peripheral_address(DMA1, DMA_CHANNEL4, SPI2_DR); dma_set_read_from_peripheral(DMA1, DMA_CHANNEL4); dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL4); dma_set_peripheral_size(DMA1, DMA_CHANNEL4, DMA_CCR_PSIZE_8BIT); dma_set_memory_size(DMA1, DMA_CHANNEL4, DMA_CCR_MSIZE_8BIT); dma_set_priority(DMA1, DMA_CHANNEL4, DMA_CCR_PL_VERY_HIGH); dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL4); timer_reset(TIM4); timer_enable_irq(TIM4, TIM_DIER_UIE); timer_set_mode(TIM4, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); /* 3200 / 16 = 200 Hz */ timer_set_prescaler(TIM4, 32); timer_set_period(TIM4, 5625); nvic_set_priority(NVIC_TIM4_IRQ, 16 * 2); nvic_set_priority(NVIC_DMA1_CHANNEL4_IRQ, 16 * 2); nvic_enable_irq(NVIC_TIM4_IRQ); nvic_enable_irq(NVIC_DMA1_CHANNEL4_IRQ); read_calibration_data(); }
/* Receive data using DMA. */ void rx_spi(void *data, uint16_t size){ if(DmaCleanupNeeded)cleanup_dma_spi(); /* This byte is sent continuously when rx_spi() receives data. */ static const uint8_t RxSpiDummyByte = 0x00; spi_enable_rx_dma(SPI3); dma_channel_reset(DMA1, DMA_CHANNEL2); dma_disable_channel(DMA1, DMA_CHANNEL2); dma_set_peripheral_address(DMA1, DMA_CHANNEL2, (uint32_t) &(SPI_DR(SPI3))); dma_set_memory_address(DMA1, DMA_CHANNEL2, (uint32_t) data); dma_set_number_of_data(DMA1, DMA_CHANNEL2, size); dma_set_priority(DMA1, DMA_CHANNEL2, DMA_CCR_PL_HIGH); dma_set_memory_size(DMA1, DMA_CHANNEL2, DMA_CCR_MSIZE_8BIT); dma_set_peripheral_size(DMA1, DMA_CHANNEL2, DMA_CCR_PSIZE_8BIT); dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL2); dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL2); dma_set_read_from_peripheral(DMA1, DMA_CHANNEL2); dma_enable_channel(DMA1, DMA_CHANNEL2); /* The SPI peripheral is driven by transmitted bytes, so dummy bytes * must be sent in order to receive data. This is accomplished with DMA * by simply not incrementing the memory address. */ dma_channel_reset(DMA1, DMA_CHANNEL3); dma_disable_channel(DMA1, DMA_CHANNEL3); dma_set_peripheral_address(DMA1, DMA_CHANNEL3, (uint32_t) &(SPI_DR(SPI3))); dma_set_memory_address(DMA1, DMA_CHANNEL3, (uint32_t) &RxSpiDummyByte); dma_set_number_of_data(DMA1, DMA_CHANNEL3, size); dma_set_priority(DMA1, DMA_CHANNEL3, DMA_CCR_PL_HIGH); dma_set_memory_size(DMA1, DMA_CHANNEL3, DMA_CCR_MSIZE_8BIT); dma_set_peripheral_size(DMA1, DMA_CHANNEL3, DMA_CCR_PSIZE_8BIT); dma_disable_memory_increment_mode(DMA1, DMA_CHANNEL3); dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL3); dma_set_read_from_memory(DMA1, DMA_CHANNEL3); dma_enable_channel(DMA1, DMA_CHANNEL3); spi_enable_tx_dma(SPI3); spi_enable(SPI3); DmaCleanupNeeded = true; }
/* Simultaneously transmit and receive data using DMA. */ void rxtx_spi(void *rxdata, const void *txdata, uint16_t size){ if(DmaCleanupNeeded)cleanup_dma_spi(); spi_enable_rx_dma(SPI3); dma_channel_reset(DMA1, DMA_CHANNEL2); dma_disable_channel(DMA1, DMA_CHANNEL2); dma_set_peripheral_address(DMA1, DMA_CHANNEL2, (uint32_t) &(SPI_DR(SPI3))); dma_set_memory_address(DMA1, DMA_CHANNEL2, (uint32_t) rxdata); dma_set_number_of_data(DMA1, DMA_CHANNEL2, size); dma_set_priority(DMA1, DMA_CHANNEL2, DMA_CCR_PL_HIGH); dma_set_memory_size(DMA1, DMA_CHANNEL2, DMA_CCR_MSIZE_8BIT); dma_set_peripheral_size(DMA1, DMA_CHANNEL2, DMA_CCR_PSIZE_8BIT); dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL2); dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL2); dma_set_read_from_peripheral(DMA1, DMA_CHANNEL2); dma_enable_channel(DMA1, DMA_CHANNEL2); dma_channel_reset(DMA1, DMA_CHANNEL3); dma_disable_channel(DMA1, DMA_CHANNEL3); dma_set_peripheral_address(DMA1, DMA_CHANNEL3, (uint32_t) &(SPI_DR(SPI3))); dma_set_memory_address(DMA1, DMA_CHANNEL3, (uint32_t) txdata); dma_set_number_of_data(DMA1, DMA_CHANNEL3, size); dma_set_priority(DMA1, DMA_CHANNEL3, DMA_CCR_PL_HIGH); dma_set_memory_size(DMA1, DMA_CHANNEL3, DMA_CCR_MSIZE_8BIT); dma_set_peripheral_size(DMA1, DMA_CHANNEL3, DMA_CCR_PSIZE_8BIT); dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL3); dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL3); dma_set_read_from_memory(DMA1, DMA_CHANNEL3); dma_enable_channel(DMA1, DMA_CHANNEL3); spi_enable_tx_dma(SPI3); spi_enable(SPI3); DmaCleanupNeeded = true; }
void usart_tx(char *buf, unsigned short len) { usart_enable_tx_dma(USART1); dma_stream_reset(DMA2, DMA_STREAM7); dma_set_priority(DMA2, DMA_STREAM7, DMA_SxCR_PL_LOW); dma_set_memory_size(DMA2, DMA_STREAM7, DMA_SxCR_MSIZE_8BIT); dma_set_peripheral_size(DMA2, DMA_STREAM7, DMA_SxCR_PSIZE_8BIT); dma_enable_memory_increment_mode(DMA2, DMA_STREAM7); dma_set_transfer_mode(DMA2, DMA_STREAM7, DMA_SxCR_DIR_MEM_TO_PERIPHERAL); dma_set_peripheral_address(DMA2, DMA_STREAM7, (uint32_t) &USART1_DR); dma_set_memory_address(DMA2, DMA_STREAM7, (uint32_t) buf); dma_set_number_of_data(DMA2, DMA_STREAM7, len); dma_enable_transfer_complete_interrupt(DMA2, DMA_STREAM7); dma_channel_select(DMA2, DMA_STREAM7, DMA_SxCR_CHSEL_4); dma_enable_stream(DMA2, DMA_STREAM7); }
/* SPI transmit completed with DMA */ void dma1_channel3_isr(void) { gpio_set(GPIOB,GPIO1); if ((DMA1_ISR &DMA_ISR_TCIF3) != 0) { DMA1_IFCR |= DMA_IFCR_CTCIF3; } dma_disable_transfer_complete_interrupt(DMA1, DMA_CHANNEL3); spi_disable_tx_dma(SPI1); dma_disable_channel(DMA1, DMA_CHANNEL3); /* If tx_len < rx_len, create a dummy transfer to clock in the remaining * rx data */ if (rx_buf_remainder > 0) { dma_channel_reset(DMA1, DMA_CHANNEL3); dma_set_peripheral_address(DMA1, DMA_CHANNEL3, (uint32_t)&SPI1_DR); dma_set_memory_address(DMA1, DMA_CHANNEL3, (uint32_t)(&dummy_tx_buf)); // Change here dma_set_number_of_data(DMA1, DMA_CHANNEL3, rx_buf_remainder); // Change here dma_set_read_from_memory(DMA1, DMA_CHANNEL3); dma_disable_memory_increment_mode(DMA1, DMA_CHANNEL3); // Change here #if USE_16BIT_TRANSFERS dma_set_peripheral_size(DMA1, DMA_CHANNEL3, DMA_CCR_PSIZE_16BIT); dma_set_memory_size(DMA1, DMA_CHANNEL3, DMA_CCR_MSIZE_16BIT); #else dma_set_peripheral_size(DMA1, DMA_CHANNEL3, DMA_CCR_PSIZE_8BIT); dma_set_memory_size(DMA1, DMA_CHANNEL3, DMA_CCR_MSIZE_8BIT); #endif dma_set_priority(DMA1, DMA_CHANNEL3, DMA_CCR_PL_HIGH); rx_buf_remainder = 0; // Clear the buffer remainder to disable this section later dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL3); dma_enable_channel(DMA1, DMA_CHANNEL3); spi_enable_tx_dma(SPI1); } else { /* Increment the status to indicate one of the transfers is complete */ transceive_status++; } gpio_clear(GPIOB,GPIO1); }
static void __dma_tx_setup(const uint8_t *txb, const uint8_t *_txb, size_t n) { const uint8_t *bufptr; /* Reset stream in case any op is going on */ dma_stream_reset(DMA1, DMA_STREAM4); dma_set_transfer_mode(DMA1, DMA_STREAM4, DMA_SxCR_DIR_MEM_TO_PERIPHERAL); dma_set_priority(DMA1, DMA_STREAM4, DMA_SxCR_PL_HIGH); dma_set_memory_size(DMA1, DMA_STREAM4, DMA_SxCR_MSIZE_8BIT); dma_set_peripheral_size(DMA1, DMA_STREAM4, DMA_SxCR_PSIZE_8BIT); if (txb) { dma_enable_memory_increment_mode(DMA1, DMA_STREAM4); bufptr = txb; } else { bufptr = _txb; } __spi_dma_setup(DMA_STREAM4, (uint32_t)bufptr, n); }
/*--------------------------------------------------------------------*/ void dma_setup(void) { /* DAC channel 1 shares DMA controller 2 Channel 3. */ /* Enable DMA2 clock and IRQ */ rcc_peripheral_enable_clock(&RCC_AHBENR, RCC_AHBENR_DMA2EN); nvic_enable_irq(NVIC_DMA2_CHANNEL3_IRQ); dma_channel_reset(DMA2,DMA_CHANNEL3); dma_set_priority(DMA2,DMA_CHANNEL3,DMA_CCR_PL_LOW); dma_set_memory_size(DMA2,DMA_CHANNEL3,DMA_CCR_MSIZE_8BIT); dma_set_peripheral_size(DMA2,DMA_CHANNEL3,DMA_CCR_PSIZE_8BIT); dma_enable_memory_increment_mode(DMA2,DMA_CHANNEL3); dma_enable_circular_mode(DMA2,DMA_CHANNEL3); dma_set_read_from_memory(DMA2,DMA_CHANNEL3); /* The register to target is the DAC1 8-bit right justified data register */ dma_set_peripheral_address(DMA2,DMA_CHANNEL3,(uint32_t) &DAC_DHR8R1); /* The array v[] is filled with the waveform data to be output */ dma_set_memory_address(DMA2,DMA_CHANNEL3,(uint32_t) v); dma_set_number_of_data(DMA2,DMA_CHANNEL3,256); dma_enable_transfer_complete_interrupt(DMA2, DMA_CHANNEL3); dma_enable_channel(DMA2,DMA_CHANNEL3); }
u8 UART_Send(u8 *data, u16 len) { if (busy) return 1; busy = 1; dma_channel_reset(_USART_DMA, _USART_DMA_CHANNEL); dma_set_peripheral_address(_USART_DMA, _USART_DMA_CHANNEL,(u32) &_USART_DR); /* send data to the USART data register */ dma_set_memory_address(_USART_DMA, _USART_DMA_CHANNEL, (u32) data); dma_set_number_of_data(_USART_DMA, _USART_DMA_CHANNEL, len); dma_set_read_from_memory(_USART_DMA, _USART_DMA_CHANNEL); /* direction is from memory to usart */ dma_enable_memory_increment_mode(_USART_DMA, _USART_DMA_CHANNEL); /* memory pointer increments, peripheral no */ dma_set_peripheral_size(_USART_DMA, _USART_DMA_CHANNEL, DMA_CCR_PSIZE_8BIT); /* USART_DR is 8bit wide in this mode */ dma_set_memory_size(_USART_DMA, _USART_DMA_CHANNEL, DMA_CCR_MSIZE_8BIT); /* destination memory is also 8 bit wide */ dma_set_priority(_USART_DMA, _USART_DMA_CHANNEL, DMA_CCR_PL_LOW); dma_enable_transfer_complete_interrupt(_USART_DMA, _USART_DMA_CHANNEL); dma_enable_channel(_USART_DMA, _USART_DMA_CHANNEL); /* dma ready to go */ usart_enable_tx_dma(_USART); return 0; }
void dma_transmit_setup(void) { dma_channel_reset(DMA1, DMA_CHANNEL4); nvic_enable_irq(NVIC_DMA1_CHANNEL4_5_IRQ); dma_set_peripheral_address(DMA1, DMA_CHANNEL4, (uint32_t) &USART2_TDR); dma_set_read_from_memory(DMA1, DMA_CHANNEL4); dma_set_peripheral_size(DMA1, DMA_CHANNEL4, DMA_CCR_PSIZE_8BIT); dma_set_memory_size(DMA1, DMA_CHANNEL4, DMA_CCR_MSIZE_8BIT); dma_set_priority(DMA1, DMA_CHANNEL4, DMA_CCR_PL_VERY_HIGH); dma_disable_peripheral_increment_mode(DMA1, DMA_CHANNEL4); dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL4); dma_disable_transfer_error_interrupt(DMA1, DMA_CHANNEL4); dma_disable_half_transfer_interrupt(DMA1, DMA_CHANNEL4); dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL4); }
static void __dma_rx_setup(uint8_t *rxb, uint8_t *_rxb, size_t n) { uint8_t *bufptr; /* Reset stream in case any op is going on */ dma_stream_reset(DMA1, DMA_STREAM3); dma_set_transfer_mode(DMA1, DMA_STREAM3, DMA_SxCR_DIR_PERIPHERAL_TO_MEM); dma_set_priority(DMA1, DMA_STREAM3, DMA_SxCR_PL_VERY_HIGH); dma_set_memory_size(DMA1, DMA_STREAM3, DMA_SxCR_MSIZE_8BIT); dma_set_peripheral_size(DMA1, DMA_STREAM3, DMA_SxCR_PSIZE_8BIT); if (rxb) { dma_enable_memory_increment_mode(DMA1, DMA_STREAM3); bufptr = rxb; } else { bufptr = _rxb; } __spi_dma_setup(DMA_STREAM3, (uint32_t)bufptr, n); }
/// Processing done after tx completes void process_tx_dma_interrupt(struct spi_periph *periph) { struct spi_periph_dma *dma = periph->init_struct; struct spi_transaction *trans = periph->trans[periph->trans_extract_idx]; /* Disable DMA Channel */ dma_disable_transfer_complete_interrupt(dma->dma, dma->tx_chan); /* Disable SPI TX request */ spi_disable_tx_dma((uint32_t)periph->reg_addr); /* Disable DMA tx channel */ dma_disable_channel(dma->dma, dma->tx_chan); if (dma->tx_extra_dummy_dma) { /* * We are finished the first part of the transmit with real data, * but still need to clock in the rest of the receive data. * Set up a dummy dma transmit transfer to accomplish this. */ /* Reset the flag so this only happens once in a transaction */ dma->tx_extra_dummy_dma = FALSE; /* Use the difference in length between tx and rx */ uint16_t len_remaining = trans->input_length - trans->output_length; spi_configure_dma(dma->dma, dma->tx_chan, (uint32_t)dma->spidr, (uint32_t)&(dma->tx_dummy_buf), len_remaining, trans->dss, FALSE); dma_set_read_from_memory(dma->dma, dma->tx_chan); dma_set_priority(dma->dma, dma->tx_chan, DMA_CCR_PL_MEDIUM); /* Enable DMA transfer complete interrupts. */ dma_enable_transfer_complete_interrupt(dma->dma, dma->tx_chan); /* Enable DMA channels */ dma_enable_channel(dma->dma, dma->tx_chan); /* Enable SPI transfers via DMA */ spi_enable_tx_dma((uint32_t)periph->reg_addr); } }
/** 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; } }
void hal_uart_dma_send_block(const uint8_t *data, uint16_t size){ // printf("hal_uart_dma_send_block size %u\n", size); /* * USART3_TX Using DMA_CHANNEL2 */ /* Reset DMA channel*/ dma_channel_reset(DMA1, DMA_CHANNEL2); dma_set_peripheral_address(DMA1, DMA_CHANNEL2, (uint32_t)&USART3_DR); dma_set_memory_address(DMA1, DMA_CHANNEL2, (uint32_t)data); dma_set_number_of_data(DMA1, DMA_CHANNEL2, size); dma_set_read_from_memory(DMA1, DMA_CHANNEL2); dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL2); dma_set_peripheral_size(DMA1, DMA_CHANNEL2, DMA_CCR_PSIZE_8BIT); dma_set_memory_size(DMA1, DMA_CHANNEL2, DMA_CCR_MSIZE_8BIT); dma_set_priority(DMA1, DMA_CHANNEL2, DMA_CCR_PL_VERY_HIGH); dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL2); dma_enable_channel(DMA1, DMA_CHANNEL2); usart_enable_tx_dma(USART3); }
u8 UART_Send(u8 *data, u16 len) { if (busy) return 1; busy = 1; DMA_stream_reset(USART_DMA); dma_set_peripheral_address(USART_DMA.dma, USART_DMA.stream, (u32) &USART_DR(UART_CFG.uart)); /* send data to the USART data register */ dma_set_memory_address(USART_DMA.dma, USART_DMA.stream, (u32) data); dma_set_number_of_data(USART_DMA.dma, USART_DMA.stream, len); dma_set_read_from_memory(USART_DMA.dma, USART_DMA.stream); /* direction is from memory to usart */ dma_enable_memory_increment_mode(USART_DMA.dma, USART_DMA.stream); /* memory pointer increments, peripheral no */ dma_set_peripheral_size(USART_DMA.dma, USART_DMA.stream, DMA_SxCR_PSIZE_8BIT); /* USART_DR is 8bit wide in this mode */ dma_set_memory_size(USART_DMA.dma, USART_DMA.stream, DMA_SxCR_MSIZE_8BIT); /* destination memory is also 8 bit wide */ dma_set_priority(USART_DMA.dma, USART_DMA.stream, DMA_CCR_PL_LOW); dma_enable_transfer_complete_interrupt(USART_DMA.dma, USART_DMA.stream); DMA_channel_select(USART_DMA); DMA_enable_stream(USART_DMA); /* dma ready to go */ usart_enable_tx_dma(UART_CFG.uart); return 0; }
void acq_init() { /* Initialize amplifier control GPIO */ gpio_mode_setup(BANK_AMP, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_AMP); gpio_clear(BANK_AMP, GPIO_AMP); gpio_mode_setup(BANK_LED, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO_LED); gpio_clear(BANK_LED, GPIO_LED); /* Initialize SPI GPIOs */ gpio_mode_setup(BANK_CS, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_CS); gpio_mode_setup(BANK_SCLK, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_SCLK); gpio_mode_setup(BANK_DOUT, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO_DOUT); gpio_set_af(BANK_CS, GPIO_AF6, GPIO_CS); gpio_set_af(BANK_SCLK, GPIO_AF6, GPIO_SCLK); gpio_set_af(BANK_DOUT, GPIO_AF6, GPIO_DOUT); rcc_periph_clock_enable(RCC_SPI3); acq_spi_init(SPI_C1); rcc_periph_clock_enable(RCC_DMA1); dma_channel_reset(DMA1, DMA_CHANNEL2); dma_disable_channel(DMA1, DMA_CHANNEL2); dma_set_peripheral_address(DMA1, DMA_CHANNEL2, (uint32_t)&SPI_DR(SPI_C1)); dma_set_memory_address(DMA1, DMA_CHANNEL2, (uint32_t)&acq_channel.buff); dma_set_number_of_data(DMA1, DMA_CHANNEL2, BUFFER_SIZE); dma_set_priority(DMA1, DMA_CHANNEL2, DMA_CCR_PL_MEDIUM); dma_set_memory_size(DMA1, DMA_CHANNEL2, DMA_CCR_MSIZE_16BIT); dma_set_peripheral_size(DMA1, DMA_CHANNEL2, DMA_CCR_PSIZE_16BIT); dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL2); dma_set_read_from_peripheral(DMA1, DMA_CHANNEL2); dma_enable_circular_mode(DMA1, DMA_CHANNEL2); nvic_set_priority(NVIC_DMA1_CHANNEL2_IRQ, PRIO_ACQ); }
static void platform_init_adc() { /* Set up DMA for the ADC */ nvic_enable_irq(NVIC_DMA2_STREAM0_IRQ); nvic_set_priority(NVIC_DMA2_STREAM0_IRQ, 64); /* Set up ADC */ for (int i = 0; i < NUM_SENSORS; ++i) { if (config.sensors[i].method == SENSOR_ADC) { adc_pins[i] = config.sensors[i].pin; gpio_mode_setup(GPIOA, GPIO_MODE_ANALOG, GPIO_PUPD_NONE, (1<<adc_pins[i])); } } adc_off(ADC1); adc_enable_scan_mode(ADC1); adc_set_sample_time_on_all_channels(ADC1, ADC_SMPR_SMP_15CYC); adc_power_on(ADC1); adc_disable_dma(ADC1); adc_enable_dma(ADC1); adc_clear_overrun_flag(ADC1); adc_set_dma_continue(ADC1); dma_stream_reset(DMA2, DMA_STREAM0); dma_set_priority(DMA2, DMA_STREAM0, DMA_SxCR_PL_HIGH); dma_set_memory_size(DMA2, DMA_STREAM0, DMA_SxCR_MSIZE_16BIT); dma_set_peripheral_size(DMA2, DMA_STREAM0, DMA_SxCR_PSIZE_16BIT); dma_enable_memory_increment_mode(DMA2, DMA_STREAM0); dma_set_transfer_mode(DMA2, DMA_STREAM0, DMA_SxCR_DIR_PERIPHERAL_TO_MEM); dma_enable_circular_mode(DMA2, DMA_STREAM0); dma_set_peripheral_address(DMA2, DMA_STREAM0, (uint32_t) &ADC1_DR); dma_set_memory_address(DMA2, DMA_STREAM0, (uint32_t) adc_dma_buf); dma_set_number_of_data(DMA2, DMA_STREAM0, NUM_SENSORS); dma_enable_transfer_complete_interrupt(DMA2, DMA_STREAM0); dma_channel_select(DMA2, DMA_STREAM0, DMA_SxCR_CHSEL_0); dma_enable_stream(DMA2, DMA_STREAM0); adc_set_regular_sequence(ADC1, NUM_SENSORS, adc_pins); }
/*--------------------------------------------------------------------*/ static void dma_setup(void) { /* DAC channel 1 uses DMA controller 1 Stream 5 Channel 7. */ /* Enable DMA1 clock and IRQ */ rcc_periph_clock_enable(RCC_DMA1); nvic_enable_irq(NVIC_DMA1_STREAM5_IRQ); dma_stream_reset(DMA1, DMA_STREAM5); dma_set_priority(DMA1, DMA_STREAM5, DMA_SxCR_PL_LOW); dma_set_memory_size(DMA1, DMA_STREAM5, DMA_SxCR_MSIZE_8BIT); dma_set_peripheral_size(DMA1, DMA_STREAM5, DMA_SxCR_PSIZE_8BIT); dma_enable_memory_increment_mode(DMA1, DMA_STREAM5); dma_enable_circular_mode(DMA1, DMA_STREAM5); dma_set_transfer_mode(DMA1, DMA_STREAM5, DMA_SxCR_DIR_MEM_TO_PERIPHERAL); /* The register to target is the DAC1 8-bit right justified data register */ dma_set_peripheral_address(DMA1, DMA_STREAM5, (uint32_t) &DAC_DHR8R1); /* The array v[] is filled with the waveform data to be output */ dma_set_memory_address(DMA1, DMA_STREAM5, (uint32_t) waveform); dma_set_number_of_data(DMA1, DMA_STREAM5, 256); dma_enable_transfer_complete_interrupt(DMA1, DMA_STREAM5); dma_channel_select(DMA1, DMA_STREAM5, DMA_SxCR_CHSEL_7); dma_enable_stream(DMA1, DMA_STREAM5); }
static int timer_dma(uint8_t *tx_buf, int tx_len) { dma_int_enable(); /* Reset DMA channels*/ dma_channel_reset(DMA1, DMA_CHANNEL3); /* Set up tx dma */ dma_set_peripheral_address(DMA1, DMA_CHANNEL3, (uint32_t)&TIM_CCR2(TIM3)); dma_set_memory_address(DMA1, DMA_CHANNEL3, (uint32_t)tx_buf); dma_set_number_of_data(DMA1, DMA_CHANNEL3, tx_len); dma_set_read_from_memory(DMA1, DMA_CHANNEL3); dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL3); dma_set_peripheral_size(DMA1, DMA_CHANNEL3, DMA_CCR_PSIZE_32BIT); dma_set_memory_size(DMA1, DMA_CHANNEL3, DMA_CCR_MSIZE_8BIT); dma_set_priority(DMA1, DMA_CHANNEL3, DMA_CCR_PL_HIGH); dma_enable_circular_mode(DMA1, DMA_CHANNEL3); dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL3); dma_enable_half_transfer_interrupt(DMA1, DMA_CHANNEL3); dma_enable_channel(DMA1, DMA_CHANNEL3); return 0; }
/*--------------------------------------------------------------------*/ void dma_setup(void) { rcc_peripheral_enable_clock(&RCC_AHB1ENR, RCC_AHB1ENR_DMA2EN); /* ADC1 uses DMA controller 2 Stream 0 channel 0. */ /* Enable DMA2 clock and IRQ */ nvic_enable_irq(NVIC_DMA2_STREAM0_IRQ); dma_stream_reset(DMA2,DMA_STREAM0); dma_set_priority(DMA2,DMA_STREAM0,DMA_SxCR_PL_LOW); dma_set_peripheral_size(DMA2,DMA_STREAM0,DMA_SxCR_PSIZE_32BIT); /* The register to target is the ADC regular data register */ dma_set_peripheral_address(DMA2,DMA_STREAM0,(uint32_t) &ADC1_DR); /* The array v[] is filled with the waveform data to be output */ dma_set_memory_size(DMA2,DMA_STREAM0,DMA_SxCR_MSIZE_32BIT); dma_set_memory_address(DMA2,DMA_STREAM0,(uint32_t) v); dma_set_number_of_data(DMA2,DMA_STREAM0,64); dma_set_transfer_mode(DMA2,DMA_STREAM0, DMA_SxCR_DIR_PERIPHERAL_TO_MEM); dma_enable_memory_increment_mode(DMA2,DMA_STREAM0); dma_enable_circular_mode(DMA2,DMA_STREAM0); /* Don't use FIFO */ dma_enable_direct_mode(DMA2,DMA_STREAM0); dma_enable_transfer_complete_interrupt(DMA2, DMA_STREAM0); dma_channel_select(DMA2, DMA_STREAM0, DMA_SxCR_CHSEL_0); dma_enable_stream(DMA2,DMA_STREAM0); }
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 ws2812_init( void ) { uint32_t i,j; for( i = 0; i < WS2812_BUFFERSIZE; i++ ) { bitframe_pattern[i] = 0; bitframe_pattern_draw[i] = 0; } for( i=0; i < (3*NR_OF_LEDS_PER_CH*NR_OF_ROWS); i++) { frame_pattern[i] = 0; } /* configure the GPIOs */ /* Enable GPIOC clock */ rcc_periph_clock_enable(RCC_GPIOB); /* Setup GPIO pin GPIO8/9 on GPIO port C for LEDs. */ gpio_mode_setup(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLDOWN, GPIO0); gpio_set_output_options( GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_HIGH, GPIO0); /* configure the DMA */ rcc_periph_clock_enable(RCC_DMA); /* configure DMA for sending high constant pattern to port on begin of cycle * send unrolled bitframe on Timer OC1 event * send low on Timer OC3 event */ dma_channel_reset( DMA1, DMA_CHANNEL3); dma_set_peripheral_address( DMA1, DMA_CHANNEL3, (uint32_t)&GPIOB_ODR); dma_set_memory_address( DMA1, DMA_CHANNEL3, (uint32_t)&high_pattern); dma_set_peripheral_size( DMA1, DMA_CHANNEL3, DMA_CCR_PSIZE_8BIT); dma_set_memory_size( DMA1, DMA_CHANNEL3, DMA_CCR_MSIZE_8BIT); dma_disable_peripheral_increment_mode( DMA1, DMA_CHANNEL3 ); dma_disable_memory_increment_mode( DMA1, DMA_CHANNEL3 ); dma_set_priority( DMA1, DMA_CHANNEL3, DMA_CCR_PL_HIGH); dma_set_read_from_memory(DMA1, DMA_CHANNEL3); dma_channel_reset( DMA1, DMA_CHANNEL4); dma_set_peripheral_address( DMA1, DMA_CHANNEL4, (uint32_t)&GPIOB_ODR); dma_set_memory_address( DMA1, DMA_CHANNEL4, (uint32_t)actual_bitframe); dma_set_peripheral_size( DMA1, DMA_CHANNEL4, DMA_CCR_PSIZE_8BIT); dma_set_memory_size( DMA1, DMA_CHANNEL4, DMA_CCR_MSIZE_8BIT); dma_disable_peripheral_increment_mode( DMA1, DMA_CHANNEL4 ); dma_enable_memory_increment_mode( DMA1, DMA_CHANNEL4 ); dma_set_priority( DMA1, DMA_CHANNEL4, DMA_CCR_PL_HIGH); dma_set_read_from_memory(DMA1, DMA_CHANNEL4); dma_channel_reset( DMA1, DMA_CHANNEL2); dma_set_peripheral_address( DMA1, DMA_CHANNEL2, (uint32_t)&GPIOB_ODR); dma_set_memory_address( DMA1, DMA_CHANNEL2, (uint32_t)&low_pattern); dma_set_peripheral_size( DMA1, DMA_CHANNEL2, DMA_CCR_PSIZE_8BIT); dma_set_memory_size( DMA1, DMA_CHANNEL2, DMA_CCR_MSIZE_8BIT); dma_disable_peripheral_increment_mode( DMA1, DMA_CHANNEL2 ); dma_disable_memory_increment_mode( DMA1, DMA_CHANNEL2 ); dma_set_priority( DMA1, DMA_CHANNEL2, DMA_CCR_PL_HIGH); dma_set_read_from_memory(DMA1, DMA_CHANNEL2); nvic_set_priority(NVIC_DMA1_CHANNEL2_3_IRQ, 0); nvic_enable_irq(NVIC_DMA1_CHANNEL2_3_IRQ); dma_enable_transfer_complete_interrupt( DMA1, DMA_CHANNEL2); /* configure timer */ rcc_periph_clock_enable(RCC_TIM3); /* configure the timer for 800kHz overall frequency */ timer_reset( TIM3 ); timer_set_mode( TIM3, TIM_CR1_CKD_CK_INT, TIM_CR1_CMS_EDGE, TIM_CR1_DIR_UP); timer_set_period( TIM3, 60); timer_set_repetition_counter( TIM3, 0); timer_disable_preload( TIM3 ); /* timer compare section 1 for low coding */ timer_set_oc_mode( TIM3, TIM_OC1,TIM_OCM_FROZEN); timer_set_oc_value( TIM3, TIM_OC1, 19); timer_disable_oc_preload( TIM3, TIM_OC1); /* timer compare section 3 for high coding */ timer_set_oc_mode( TIM3, TIM_OC3,TIM_OCM_FROZEN); timer_set_oc_value( TIM3, TIM_OC3, 41); timer_disable_oc_preload( TIM3, TIM_OC3); nvic_set_priority( NVIC_TIM3_IRQ,1); nvic_set_priority( NVIC_PENDSV_IRQ, 2); nvic_enable_irq(NVIC_TIM3_IRQ); nvic_enable_irq(NVIC_PENDSV_IRQ); /* start the sending process */ ws2812_send(); }
static int spi_dma_transceive(uint8_t *tx_buf, int tx_len, uint8_t *rx_buf, int rx_len) #endif { /* Check for 0 length in both tx and rx */ if ((rx_len < 1) && (tx_len < 1)) { /* return -1 as error */ return -1; } /* Reset DMA channels*/ dma_channel_reset(DMA1, DMA_CHANNEL4); dma_channel_reset(DMA1, DMA_CHANNEL5); /* Reset SPI data and status registers. * Here we assume that the SPI peripheral is NOT * busy any longer, i.e. the last activity was verified * complete elsewhere in the program. */ volatile uint8_t temp_data __attribute__ ((unused)); while (SPI_SR(SPI2) & (SPI_SR_RXNE | SPI_SR_OVR)) { temp_data = SPI_DR(SPI2); } /* Reset status flag appropriately (both 0 case caught above) */ transceive_status = NONE; if (rx_len < 1) { transceive_status = ONE; } if (tx_len < 1) { transceive_status = ONE; } /* Set up rx dma, note it has higher priority to avoid overrun */ if (rx_len > 0) { dma_set_peripheral_address(DMA1, DMA_CHANNEL4, (uint32_t)&SPI2_DR); dma_set_memory_address(DMA1, DMA_CHANNEL4, (uint32_t)rx_buf); dma_set_number_of_data(DMA1, DMA_CHANNEL4, rx_len); dma_set_read_from_peripheral(DMA1, DMA_CHANNEL4); dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL4); #if USE_16BIT_TRANSFERS dma_set_peripheral_size(DMA1, DMA_CHANNEL4, DMA_CCR_PSIZE_16BIT); dma_set_memory_size(DMA1, DMA_CHANNEL4, DMA_CCR_MSIZE_16BIT); #else dma_set_peripheral_size(DMA1, DMA_CHANNEL4, DMA_CCR_PSIZE_8BIT); dma_set_memory_size(DMA1, DMA_CHANNEL4, DMA_CCR_MSIZE_8BIT); #endif dma_set_priority(DMA1, DMA_CHANNEL4, DMA_CCR_PL_VERY_HIGH); } /* Set up tx dma */ if (tx_len > 0) { dma_set_peripheral_address(DMA1, DMA_CHANNEL5, (uint32_t)&SPI2_DR); dma_set_memory_address(DMA1, DMA_CHANNEL5, (uint32_t)tx_buf); dma_set_number_of_data(DMA1, DMA_CHANNEL5, tx_len); dma_set_read_from_memory(DMA1, DMA_CHANNEL5); dma_enable_memory_increment_mode(DMA1, DMA_CHANNEL5); #if USE_16BIT_TRANSFERS dma_set_peripheral_size(DMA1, DMA_CHANNEL5, DMA_CCR_PSIZE_16BIT); dma_set_memory_size(DMA1, DMA_CHANNEL5, DMA_CCR_MSIZE_16BIT); #else dma_set_peripheral_size(DMA1, DMA_CHANNEL5, DMA_CCR_PSIZE_8BIT); dma_set_memory_size(DMA1, DMA_CHANNEL5, DMA_CCR_MSIZE_8BIT); #endif dma_set_priority(DMA1, DMA_CHANNEL5, DMA_CCR_PL_HIGH); } /* Enable dma transfer complete interrupts */ if (rx_len > 0) { dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL4); } if (tx_len > 0) { dma_enable_transfer_complete_interrupt(DMA1, DMA_CHANNEL5); } /* Activate dma channels */ if (rx_len > 0) { dma_enable_channel(DMA1, DMA_CHANNEL4); } if (tx_len > 0) { dma_enable_channel(DMA1, DMA_CHANNEL5); } /* Enable the spi transfer via dma * This will immediately start the transmission, * after which when the receive is complete, the * receive dma will activate */ if (rx_len > 0) { spi_enable_rx_dma(SPI2); } if (tx_len > 0) { spi_enable_tx_dma(SPI2); } return 0; }
/** * Start a new transaction with DMA. */ static void spi_start_dma_transaction(struct spi_periph* periph, struct spi_transaction* trans) { struct spi_periph_dma *dma; uint8_t sig = 0x00; /* Store local copy to notify of the results */ trans->status = SPITransRunning; periph->status = SPIRunning; dma = periph->init_struct; /* * Check if we need to reconfigure the spi peripheral for this transaction */ sig = get_transaction_signature(trans); if (sig != dma->comm_sig) { /* A different config is required in this transaction... */ set_comm_from_transaction(&(dma->comm), trans); /* remember the new conf signature */ dma->comm_sig = sig; /* apply the new configuration */ spi_disable((uint32_t)periph->reg_addr); spi_init_master((uint32_t)periph->reg_addr, dma->comm.br, dma->comm.cpol, dma->comm.cpha, dma->comm.dff, dma->comm.lsbfirst); spi_enable_software_slave_management((uint32_t)periph->reg_addr); spi_set_nss_high((uint32_t)periph->reg_addr); spi_enable((uint32_t)periph->reg_addr); } /* * Select the slave after reconfiguration of the peripheral */ if (trans->select == SPISelectUnselect || trans->select == SPISelect) { SpiSlaveSelect(trans->slave_idx); } /* Run the callback AFTER selecting the slave */ if (trans->before_cb != 0) { trans->before_cb(trans); } /* * Receive DMA channel configuration ---------------------------------------- * * We always run the receive DMA until the very end! * This is done so we can use the transfer complete interrupt * of the RX DMA to signal the end of the transaction. * * If we want to receive less than we transmit, a dummy buffer * for the rx DMA is used after for the remaining data. * * In the transmit only case (input_length == 0), * the dummy is used right from the start. */ if (trans->input_length == 0) { /* run the dummy rx dma for the complete transaction length */ spi_configure_dma(dma->dma, dma->rx_chan, (uint32_t)dma->spidr, (uint32_t)&(dma->rx_dummy_buf), trans->output_length, trans->dss, FALSE); } else { /* run the real rx dma for input_length */ spi_configure_dma(dma->dma, dma->rx_chan, (uint32_t)dma->spidr, (uint32_t)trans->input_buf, trans->input_length, trans->dss, TRUE); /* use dummy rx dma for the rest */ if (trans->output_length > trans->input_length) { /* Enable use of second dma transfer with dummy buffer (cleared in ISR) */ dma->rx_extra_dummy_dma = TRUE; } } dma_set_read_from_peripheral(dma->dma, dma->rx_chan); dma_set_priority(dma->dma, dma->rx_chan, DMA_CCR_PL_VERY_HIGH); /* * Transmit DMA channel configuration --------------------------------------- * * We always run the transmit DMA! * To receive data, the clock must run, so something has to be transmitted. * If needed, use a dummy DMA transmitting zeros for the remaining length. * * In the reveive only case (output_length == 0), * the dummy is used right from the start. */ if (trans->output_length == 0) { spi_configure_dma(dma->dma, dma->tx_chan, (uint32_t)dma->spidr, (uint32_t)&(dma->tx_dummy_buf), trans->input_length, trans->dss, FALSE); } else { spi_configure_dma(dma->dma, dma->tx_chan, (uint32_t)dma->spidr, (uint32_t)trans->output_buf, trans->output_length, trans->dss, TRUE); if (trans->input_length > trans->output_length) { /* Enable use of second dma transfer with dummy buffer (cleared in ISR) */ dma->tx_extra_dummy_dma = TRUE; } } dma_set_read_from_memory(dma->dma, dma->tx_chan); dma_set_priority(dma->dma, dma->tx_chan, DMA_CCR_PL_MEDIUM); /* Enable DMA transfer complete interrupts. */ dma_enable_transfer_complete_interrupt(dma->dma, dma->rx_chan); dma_enable_transfer_complete_interrupt(dma->dma, dma->tx_chan); /* Enable DMA channels */ dma_enable_channel(dma->dma, dma->rx_chan); dma_enable_channel(dma->dma, dma->tx_chan); /* Enable SPI transfers via DMA */ spi_enable_rx_dma((uint32_t)periph->reg_addr); spi_enable_tx_dma((uint32_t)periph->reg_addr); }