//------------------------------------------------------------------------------ /// Initializes the DMA controller. /// \param dwChannel Particular dwChannel number /// \param defaultHandler Using the default dmad interrupt handler. //------------------------------------------------------------------------------ extern void DMAD_Initialize( uint32_t dwChannel, uint32_t defaultHandler ) { uint32_t dwStatus ; uint32_t dwFlag ; /* Enable peripheral clock */ PMC_EnablePeripheral( ID_DMAC ) ; /* Read the dwChannel handler status to ensure the channel is a free channel */ dwStatus = DMA_GetChannelStatus( DMAC ) ; TRACE_INFO( "DMAD_Initialize dwChannel %x \n\r", dwChannel ) ; assert( (dwStatus & (1 << dwChannel)) == 0 ) ; /* Clear any pending interrupts on the channel */ DMA_GetStatus( DMAC ) ; /* Disable the channel */ DMA_DisableChannel( DMAC, dwChannel ) ; /* Disable the interrupt */ dwFlag = 0x3FFFFF ; DMA_DisableIt( DMAC, dwFlag ) ; /* Enable DMA */ DMA_Enable( DMAC ) ; if ( defaultHandler ) { NVIC_EnableIRQ( DMAC_IRQn ) ; } // Initialize transfer instance. dmad.transfers[dwChannel].transferSize = 0; }
//------------------------------------------------------------------------------ /// Initializes the DMA controller. /// \param channel Particular channel number /// \param defaultHandler Using the default dmad interrupt handler. //------------------------------------------------------------------------------ void DMAD_Initialize(unsigned char channel, unsigned char defaultHandler) { unsigned int status; unsigned int flag; // Enable peripheral clock #if !defined(at91sam9rl64) AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_HDMA; #endif // Read the channel handler status to ensure the channel is a free channel. status = DMA_GetChannelStatus(); TRACE_INFO ("DMAD_Initialize channel %x \n\r", channel); SANITY_CHECK(!(status & (1 << channel))); // Clear any pending interrupts on the channel. DMA_GetStatus(); // Disble the channel. DMA_DisableChannel(channel); // Disable the interrupt flag = 0xffffff; DMA_DisableIt(flag); // Enable DMA. DMA_Enable(); if(defaultHandler) { IRQ_ConfigureIT(AT91C_ID_HDMA, 0, DMAD_Handler); IRQ_EnableIT(AT91C_ID_HDMA); } // Initialize transfer instance. dmad.transfers[channel].transferSize = 0; }
//------------------------------------------------------------------------------ //./ Configure the DMA Channels: 0 RX, 1 TX. //./ Channels are disabled after configure. //------------------------------------------------------------------------------ static void configureDmaChannels(void) { // Enable DMA Peripheral PERIPH_ENABLE(AT91C_ID_HDMA); // Enable DMA DMA_Enable(); // Free status DMA_DisableIt(0xFFFFFFFF); DMA_GetChannelStatus(); DMA_GetStatus(); DMA_DisableChannels((1 << DMA_CHANNEL_0) | (1 << DMA_CHANNEL_1)); // RX channel 0 DMA_SetConfiguration(DMA_CHANNEL_0, AT91C_HDMA_SRC_PER_2 | AT91C_HDMA_DST_PER_2 | AT91C_HDMA_SRC_H2SEL_HW | AT91C_HDMA_DST_H2SEL_SW | AT91C_HDMA_SOD_ENABLE | AT91C_HDMA_FIFOCFG_LARGESTBURST ); // TX channel 1 DMA_SetConfiguration(DMA_CHANNEL_1, AT91C_HDMA_SRC_PER_1 | AT91C_HDMA_DST_PER_1 | AT91C_HDMA_SRC_H2SEL_SW | AT91C_HDMA_DST_H2SEL_HW | AT91C_HDMA_SOD_ENABLE | AT91C_HDMA_FIFOCFG_LARGESTBURST ); }
void DMA_Setup( DMA_CH_t * dmaChannel, const void * src, void * dest, int16_t blockSize, uint8_t repeatCount ) { DMA_Enable(); DMA_SetupBlock( dmaChannel, src, DMA_CH_SRCRELOAD_BLOCK_gc, DMA_CH_SRCDIR_INC_gc, dest, DMA_CH_DESTRELOAD_BURST_gc, DMA_CH_DESTDIR_INC_gc, blockSize, DMA_CH_BURSTLEN_2BYTE_gc, repeatCount, true ); // Timer Overflow will trigger DMA DMA_SetTriggerSource( dmaChannel, 0x40 ); DMA_EnableSingleShot( dmaChannel ); }
/** * @brief Configure the DMA peripheral. * @param None * @retval None */ void DMA_Configuration(void) { DMA_InitPara DMA_InitStructure; /* DMA1 clock enable */ RCC_AHBPeriphClock_Enable(RCC_AHBPERIPH_DMA1,ENABLE); /* DMA1 Channel5 Config */ DMA_DeInit(DMA1_CHANNEL5); DMA_InitStructure.DMA_PeripheralBaseAddr = TIMER1_CHCC1; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t) buffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PERIPHERALDST; DMA_InitStructure.DMA_BufferSize = 3; DMA_InitStructure.DMA_PeripheralInc = DMA_PERIPHERALINC_DISABLE; DMA_InitStructure.DMA_MemoryInc = DMA_MEMORYINC_ENABLE; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PERIPHERALDATASIZE_HALFWORD; DMA_InitStructure.DMA_MemoryDataSize = DMA_MEMORYDATASIZE_HALFWORD; DMA_InitStructure.DMA_Mode = DMA_MODE_CIRCULAR; DMA_InitStructure.DMA_Priority = DMA_PRIORITY_HIGH; DMA_InitStructure.DMA_MTOM = DMA_MEMTOMEM_DISABLE; DMA_Init(DMA1_CHANNEL5, &DMA_InitStructure); /* DMA1 Channel5 enable */ DMA_Enable(DMA1_CHANNEL5, ENABLE); }
void adc_init(void) { DMA_InitPara DMA_InitStructure; ADC_InitPara ADC_InitStructure; RCC_APB2PeriphClock_Enable(RCC_APB2PERIPH_ADC1, ENABLE); RCC_ADCCLKConfig(RCC_ADCCLK_APB2_DIV6); RCC_AHBPeriphClock_Enable(RCC_AHBPERIPH_DMA1, ENABLE); DMA_InitStructure.DMA_PeripheralBaseAddr = 0x4001244C; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)adcarray; DMA_InitStructure.DMA_DIR = DMA_DIR_PERIPHERALSRC; DMA_InitStructure.DMA_BufferSize = 4; DMA_InitStructure.DMA_PeripheralInc = DMA_PERIPHERALINC_DISABLE; DMA_InitStructure.DMA_MemoryInc = DMA_MEMORYINC_ENABLE; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PERIPHERALDATASIZE_HALFWORD; DMA_InitStructure.DMA_MemoryDataSize = DMA_MEMORYDATASIZE_HALFWORD; DMA_InitStructure.DMA_Mode = DMA_MODE_CIRCULAR; DMA_InitStructure.DMA_Priority = DMA_PRIORITY_HIGH; DMA_InitStructure.DMA_MTOM = DMA_MEMTOMEM_DISABLE; DMA_Init(DMA1_CHANNEL1, &DMA_InitStructure); DMA_Enable(DMA1_CHANNEL1, ENABLE); // ADC_DeInit(&ADC_InitStructure); ADC_InitStructure.ADC_Mode_Scan = ENABLE; ADC_InitStructure.ADC_Mode_Continuous = ENABLE; ADC_InitStructure.ADC_Trig_External = ADC_EXTERNAL_TRIGGER_MODE_NONE; ADC_InitStructure.ADC_Data_Align = ADC_DATAALIGN_RIGHT; ADC_InitStructure.ADC_Channel_Number = 4; ADC_Init(&ADC_InitStructure); // current? ADC_RegularChannel_Config(ADC_CHANNEL_7, 1, ADC_SAMPLETIME_239POINT5); // battery channel ADC_RegularChannel_Config(ADC_CHANNEL_5, 2, ADC_SAMPLETIME_239POINT5); ADC_RegularChannel_Config(ADC_CHANNEL_4, 3, ADC_SAMPLETIME_239POINT5); ADC_RegularChannel_Config(ADC_CHANNEL_1, 4, ADC_SAMPLETIME_239POINT5); ADC_DMA_Enable(ENABLE); ADC_Enable(ENABLE); ADC_Calibration(); ADC_SoftwareStartConv_Enable(ENABLE); }
/** * @brief Main program. * @param None * @retval None */ int main(void) { /* Configure System clocks -----------------------------------------------*/ RCC_Configuration(); /* Configure GPIO ports --------------------------------------------------*/ GPIO_Configuration(); /* Configure DMA1 channel1 -----------------------------------------------*/ DMA_DeInit(DMA1_CHANNEL1); DMA_InitStructure.DMA_PeripheralBaseAddr = ADC_RDTR_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADCConvertedValue; DMA_InitStructure.DMA_DIR = DMA_DIR_PERIPHERALSRC; DMA_InitStructure.DMA_BufferSize = 1; DMA_InitStructure.DMA_PeripheralInc = DMA_PERIPHERALINC_DISABLE; DMA_InitStructure.DMA_MemoryInc = DMA_MEMORYINC_DISABLE; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PERIPHERALDATASIZE_HALFWORD; DMA_InitStructure.DMA_MemoryDataSize = DMA_MEMORYDATASIZE_HALFWORD; DMA_InitStructure.DMA_Mode = DMA_MODE_CIRCULAR; DMA_InitStructure.DMA_Priority = DMA_PRIORITY_HIGH; DMA_InitStructure.DMA_MTOM = DMA_MEMTOMEM_DISABLE; DMA_Init(DMA1_CHANNEL1, &DMA_InitStructure); /* Enable DMA1 channel1 */ DMA_Enable(DMA1_CHANNEL1, ENABLE); /* Configure ADC ---------------------------------------------------------*/ ADC_InitStructure.ADC_Mode_Scan = DISABLE; ADC_InitStructure.ADC_Mode_Continuous = ENABLE; ADC_InitStructure.ADC_Trig_External = ADC_EXTERNAL_TRIGGER_MODE_NONE; ADC_InitStructure.ADC_Data_Align = ADC_DATAALIGN_RIGHT; ADC_InitStructure.ADC_Channel_Number = 1; ADC_Init(&ADC_InitStructure); /* Configure ADC regular channelx */ ADC_RegularChannel_Config( BOARD_ADC_CHANNEL, 1, ADC_SAMPLETIME_239POINT5); /* Enable ADC DMA */ ADC_DMA_Enable(ENABLE); /* Enable ADC */ ADC_Enable(ENABLE); ADC_Calibration(); /* Start ADC Software Conversion */ ADC_SoftwareStartConv_Enable(ENABLE); while (1) { } }
//------------------------------------------------------------------------------ /// Initializes the DMA controller. /// \param channel Particular channel number /// \param defaultHandler Using the default dmad interrupt handler. //------------------------------------------------------------------------------ void DMAD_Initialize(U8 channel, U8 defaultHandler) { // U32 status; U32 flag; // status = DMA_GetChannelStatus(); // Read the channel handler status to ensure the channel is a free channel. // DEBUG_MSG("DMAD_Initialize channel: %x, Status: %x", channel, status); DMA_GetStatus(); // Clear any pending interrupts on the channel. DMA_DisableChannel(channel); // Disble the channel. flag = 0xffffff; DMA_DisableIt(flag); // Disable the interrupt DMA_Enable(); // Enable DMA. if(defaultHandler) { IRQ_PeriConf(21, 0, DMAD_Handler); IRQ_PeriEn(21); } dmad.transfers[channel].transferSize = 0; // Initialize transfer instance. }
/** * @brief Configure GPIO ports. * @param None * @retval None */ void DMA_12BConfiguration(void) { DMA_DeInit(DMA1_CHANNEL1); DMA_InitStructure.DMA_PeripheralBaseAddr = ADC_DR_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADCConvertedValue12B; DMA_InitStructure.DMA_DIR = DMA_DIR_PERIPHERALSRC; DMA_InitStructure.DMA_BufferSize = 1; DMA_InitStructure.DMA_PeripheralInc = DMA_PERIPHERALINC_DISABLE; DMA_InitStructure.DMA_MemoryInc = DMA_MEMORYINC_DISABLE; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PERIPHERALDATASIZE_HALFWORD; DMA_InitStructure.DMA_MemoryDataSize = DMA_MEMORYDATASIZE_HALFWORD; DMA_InitStructure.DMA_Mode = DMA_MODE_CIRCULAR; DMA_InitStructure.DMA_Priority = DMA_PRIORITY_HIGH; DMA_InitStructure.DMA_MTOM = DMA_MEMTOMEM_DISABLE; DMA_Init(DMA1_CHANNEL1, &DMA_InitStructure); /* Enable DMA1 channel1 */ DMA_Enable(DMA1_CHANNEL1, ENABLE); }
int main(void) { facilitatePowersaving(); // Configure switches PORTCFG.MPCMASK = 0xff; // Configure several PINxCTRL registers at the same time SWITCHPORT.PIN0CTRL = (SWITCHPORT.PIN0CTRL & ~PORT_OPC_gm) | PORT_OPC_PULLUP_gc; //Enable pull-up to get a defined level on the switches SWITCHPORT.DIRCLR = 0xff; // Set port as input // Configure LEDs PORTCFG.MPCMASK = 0xff; // Configure several PINxCTRL registers at the same time LEDPORT.PIN0CTRL = PORT_INVEN_bm; // Invert input to turn the leds on when port output value is 1 LEDPORT.DIRSET = 0xff; // Set port as output LEDPORT.OUT = 0x00; // Set initial value // Set up ADCB0 on PB0 to read temp sensor. More of this can be achieved by using driver from appnote AVR1300 PORTQ.PIN2CTRL = (PORTQ.PIN2CTRL & ~PORT_OPC_gm) | PORT_OPC_PULLDOWN_gc; // This pin must be grounded to "enable" NTC-resistor PORTB.DIRCLR = PIN0; PORTB.PIN0CTRL = (PORTB.PIN0CTRL & ~PORT_OPC_gm); ADC_CalibrationValues_Load(&ADCB); // Load factory calibration data for ADC ADCB.CH0.CTRL = (ADCB.CH0.CTRL & ~ADC_CH_INPUTMODE_gm) | ADC_CH_INPUTMODE_SINGLEENDED_gc; // Single ended input ADCB.CH0.MUXCTRL = (ADCB.CH0.MUXCTRL & ~ADC_CH_MUXPOS_gm) | ADC_CH_MUXPOS_PIN0_gc; // Pin 0 is input ADCB.REFCTRL = (ADCB.REFCTRL & ~ADC_REFSEL_gm) | ADC_REFSEL_VCC_gc; // Internal AVCC/1.6 as reference ADCB.CTRLB |= ADC_FREERUN_bm; // Free running mode ADCB.PRESCALER = (ADCB.PRESCALER & ~ADC_PRESCALER_gm) | ADC_PRESCALER_DIV512_gc; // Divide clock by 1024. ADCB.CTRLB = (ADCB.CTRLB & ~ADC_RESOLUTION_gm) | ADC_RESOLUTION_8BIT_gc; // Set 8 bit resolution ADCB.CTRLA |= ADC_ENABLE_bm; // Enable ADC // Set up DMA CH0 to transfer from ADC to LEDS. We only read low byte. DMA_Enable(); DMA_SetupBlock( &DMA.CH0, (void const *) &(ADCB.CH0RES), DMA_CH_SRCRELOAD_NONE_gc, DMA_CH_SRCDIR_FIXED_gc, (void const *) &(LEDPORT.OUT), DMA_CH_DESTRELOAD_NONE_gc, DMA_CH_DESTDIR_FIXED_gc, 1, DMA_CH_BURSTLEN_1BYTE_gc, 0, true ); DMA_EnableSingleShot( &DMA.CH0 ); DMA_SetTriggerSource( &DMA.CH0, DMA_CH_TRIGSRC_ADCB_CH0_gc ); // ADC Channel 0 is trigger source. // Set up interrupt on button 0, or else we can't come back from IDLE SWITCHPORT.INTCTRL = (SWITCHPORT.INTCTRL & ~PORT_INT0LVL_gm) | PORT_INT0LVL_LO_gc; SWITCHPORT.INT0MASK = SWITCHMASK_ACTIVE; SWITCHPORT.PIN0CTRL = (SWITCHPORT.PIN0CTRL & ~PORT_ISC_gm) | PORT_ISC_FALLING_gc; // Enable low interrupt level in PMIC and enable global interrupts. PMIC.CTRL |= PMIC_LOLVLEN_bm; sei(); // Main loop. while (1) { if ((SWITCHPORT.IN & SWITCHMASK_ACTIVE) == 0x00) { // Button 0 pressed. Enter ACTIVE mode again. DMA_DisableChannel( &DMA.CH0 ); SLEEP.CTRL &= ~SLEEP_SEN_bm; // Disable sleep. sleep() is now ineffective. } else if ((SWITCHPORT.IN & SWITCHMASK_IDLE) == 0x00) { // Button 1 pressed. Enter Idle mode DMA_EnableChannel( &DMA.CH0 ); // Set and enable sleep. SLEEP.CTRL = (SLEEP.CTRL & ~SLEEP_SMODE_gm) | SLEEP_SMODE_IDLE_gc; SLEEP.CTRL |= SLEEP_SEN_bm; // Enable sleep. } else if (SLEEP.CTRL & SLEEP_SEN_bm) { // We are in wanting-to-sleep mode, but were awake. sleep(); } else { // Do active sampling and transfer of ADC data. LEDPORT.OUT = ADCB.CH0RES & 0xFF; } } }
// The code using the two example functions to do block memory copy // The first test use a polling function to wait until the transfer // completes or get an error. The second test use an interrupt to // know when the transfer completes or get an error. int main( void ) { uint16_t index; LEDPORT.DIR = 0xFF; LEDPORT.OUT = 0xFF; DMA_CH_t * Channel; Channel = &DMA.CH0; DMA_Enable(); // Test 1: Copy using polling. // Fill memory block A with example data. for ( index = 0; index < MEM_BLOCK_SIZE; ++index ) { memoryBlockA[index] = ( (uint8_t) index & 0xff ); } // Copy data using channel 0. gTransferError = MemCopy( memoryBlockA, memoryBlockB, MEM_BLOCK_SIZE, Channel ); // Compare memory blocks if status is true if ( gTransferError ) { // Signal Error on LEDs by turning them all on LEDPORT.OUTCLR = 0xFF; } else { // Signal success on one LED LEDPORT.OUTCLR = PIN0_bm; } // Test 2: Copy using interrupts. // Enable LO interrupt level for the complete transaction and // error flag on DMA channel 0. DMA_SetIntLevel( Channel, DMA_CH_TRNINTLVL_LO_gc, DMA_CH_ERRINTLVL_LO_gc ); PMIC.CTRL |= PMIC_LOLVLEN_bm; // Fill memory block A with example data again. for ( index = 0; index < MEM_BLOCK_SIZE; ++index ) { memoryBlockA[index] = 0xff - ( (uint8_t) index & 0xff ); } // Set intDone to false to know when it has been executed. gInterruptDone = false; gTransferError = false; // Clear pending interrupts DMA.INTFLAGS |= DMA_CH0TRNIF_bm|DMA_CH0ERRIF_bm; // Enable interrupts sei(); // Copy data using channel 0. AsyncMemCopy( memoryBlockA, memoryBlockB, MEM_BLOCK_SIZE, Channel); do { // Do something here while waiting for the // interrupt routine to signal completion. LEDPORT.OUTTGL = PIN4_bm; nop(); } while ( gInterruptDone == false ); //make sure the waiting led is off after completing LEDPORT.OUTSET = PIN4_bm; if ( gTransferError ) { // Signal Error on LEDs by turning them all on LEDPORT.OUTCLR = 0xFF; do { nop(); // Completed with failure } while (1); } else { // Signal success on one LED LEDPORT.OUTCLR = PIN1_bm; do { nop(); // Completed with no error } while (1); } }
static int ssp_drv_dma_write(mdev_t *dev, const uint8_t *data, uint8_t *din, uint32_t num, bool flag) { DMA_CFG_Type dma_tx, dma_rx; uint8_t dummy; uint16_t dma_trans = DMA_MAX_BLK_SIZE; uint32_t cnt; ssp_dma_get_tx_config(&dma_tx, (uint32_t) data, dev->port_id, 0); if (din) ssp_dma_get_rx_config(&dma_rx, (uint32_t) din, dev->port_id, 0); else ssp_dma_get_rx_config(&dma_rx, (uint32_t) &dummy, dev->port_id, 1); while (num > 0) { if (num < DMA_MAX_BLK_SIZE) dma_trans = num; /* Configure channel 0 for tx and 1 for rx (optional) */ DMA_Disable(); DMA_ChannelInit(SSP_TX_CHANNEL, &dma_tx); DMA_IntClr(SSP_TX_CHANNEL, INT_CH_ALL); DMA_IntMask(SSP_TX_CHANNEL, INT_CH_ALL, MASK); DMA_SetBlkTransfSize(SSP_TX_CHANNEL, dma_trans); if (flag) { DMA_ChannelInit(SSP_RX_CHANNEL, &dma_rx); DMA_IntClr(SSP_RX_CHANNEL, INT_CH_ALL); DMA_IntMask(SSP_RX_CHANNEL, INT_CH_ALL, MASK); DMA_SetBlkTransfSize(SSP_RX_CHANNEL, dma_trans); } DMA_Enable(); DMA_ChannelCmd(SSP_TX_CHANNEL, ENABLE); if (flag) DMA_ChannelCmd(SSP_RX_CHANNEL, ENABLE); /* Wait for dma transfer to complete on given channel */ cnt = SSP_MAX_DMA_WAIT; while (--cnt && (DMA->RAWBLOCK.BF.RAW & (1 << SSP_TX_CHANNEL)) == 0) ; if (!cnt) { SSP_LOG("%s: dma tx operation timed out\r\n", __func__); return -1; } if (flag) { /* Wait for dma transfer to complete on channel */ cnt = SSP_MAX_DMA_WAIT; while (--cnt && (DMA->RAWBLOCK.BF.RAW & (1 << SSP_RX_CHANNEL)) == 0) ; if (!cnt) { SSP_LOG("%s: dma rx operation timed out\r\n", __func__); return -1; } } if (din) /* Increment destination address for rx channel */ dma_rx.destDmaAddr += dma_trans; /* Increment source address for tx channel */ dma_tx.srcDmaAddr += dma_trans; num -= dma_trans; } return 0; }
static int ssp_drv_dma_read(mdev_t *dev, uint8_t *data, int num) { DMA_CFG_Type dma_tx, dma_rx; uint8_t dummy; uint16_t dma_trans = DMA_MAX_BLK_SIZE, len = num; uint32_t cnt; sspdev_data_t *ssp_data_p; ssp_data_p = (sspdev_data_t *) dev->private_data; dummy = SPI_DUMMY_BYTE; ssp_dma_get_tx_config(&dma_tx, (uint32_t) &dummy, dev->port_id, 1); ssp_dma_get_rx_config(&dma_rx, (uint32_t) data, dev->port_id, 0); while (num > 0) { if (num < DMA_MAX_BLK_SIZE) dma_trans = num; if (ssp_data_p->slave == SSP_SLAVE) { /* FIXME: To start a dma operation, ssp needs to * be disabled and enable to flush HW fifo. Ideally * this shouldn't be done as we can miss some * data on line, but without disabling and enabling * again we will read some garbage data from HW fifo. */ SSP_Disable(dev->port_id); DMA_Disable(); SSP_Enable(dev->port_id); DMA_ChannelInit(SSP_RX_CHANNEL, &dma_rx); DMA_IntClr(SSP_RX_CHANNEL, INT_CH_ALL); DMA_IntMask(SSP_RX_CHANNEL, INT_CH_ALL, MASK); DMA_SetBlkTransfSize(SSP_RX_CHANNEL, dma_trans); DMA_Enable(); DMA_ChannelCmd(SSP_RX_CHANNEL, ENABLE); /* Wait for dma transfer to complete on given channel */ cnt = SSP_MAX_DMA_WAIT; while (--cnt && (DMA->RAWBLOCK.BF.RAW & (1 << SSP_RX_CHANNEL)) == 0) ; if (!cnt) { return 0; } } else { /* Configure channel 0 for tx and 1 for rx */ DMA_Disable(); DMA_ChannelInit(SSP_TX_CHANNEL, &dma_tx); DMA_IntClr(SSP_TX_CHANNEL, INT_CH_ALL); DMA_IntMask(SSP_TX_CHANNEL, INT_CH_ALL, MASK); DMA_SetBlkTransfSize(SSP_TX_CHANNEL, dma_trans); DMA_ChannelInit(SSP_RX_CHANNEL, &dma_rx); DMA_IntClr(SSP_RX_CHANNEL, INT_CH_ALL); DMA_IntMask(SSP_RX_CHANNEL, INT_CH_ALL, MASK); DMA_SetBlkTransfSize(SSP_RX_CHANNEL, dma_trans); DMA_Enable(); DMA_ChannelCmd(SSP_TX_CHANNEL, ENABLE); DMA_ChannelCmd(SSP_RX_CHANNEL, ENABLE); /* Wait for dma transfer to complete on given channel */ cnt = SSP_MAX_DMA_WAIT; while (--cnt && (DMA->RAWBLOCK.BF.RAW & (1 << SSP_TX_CHANNEL)) == 0) ; if (!cnt) { SSP_LOG("%s: dma tx operation timed out\r\n", __func__); return 0; } /* Wait for dma transfer to complete on given channel */ cnt = SSP_MAX_DMA_WAIT; while (--cnt && (DMA->RAWBLOCK.BF.RAW & (1 << SSP_RX_CHANNEL)) == 0) ; if (!cnt) { SSP_LOG("%s: dma rx operation timed out\r\n", __func__); return 0; } } /* Increment destination address for rx channel */ dma_rx.destDmaAddr += dma_trans; num -= dma_trans; } return len; }
/** * @brief Main program * @param None * @retval None */ int main(void) { /* System Clocks Configuration */ RCC_Configuration(); /* NVIC configuration */ NVIC_Configuration(); /* LED configuration */ LED_config(); GD_EVAL_LEDOn(LED1); GD_EVAL_LEDOn(LED3); /* USART configuration */ USART_Configuration(); #ifdef GD32F130_150 /* DMA1 channel2 configuration */ DMA_DeInit(DMA1_CHANNEL2); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)0x40013828; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)SRC_Const_Buffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PERIPHERALDST; DMA_InitStructure.DMA_BufferSize = BufferSize; DMA_InitStructure.DMA_MemoryInc = DMA_MEMORYINC_ENABLE; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PERIPHERALDATASIZE_BYTE; DMA_InitStructure.DMA_MemoryDataSize = DMA_MEMORYDATASIZE_BYTE; DMA_InitStructure.DMA_PeripheralInc = DMA_PERIPHERALINC_DISABLE; DMA_InitStructure.DMA_Mode = DMA_MODE_NORMAL; DMA_InitStructure.DMA_Priority = DMA_PRIORITY_VERYHIGH; DMA_InitStructure.DMA_MTOM = DMA_MEMTOMEM_DISABLE; DMA_Init(DMA1_CHANNEL2, &DMA_InitStructure); USART_DMA_Enable(USART1, USART_DMAREQ_TX, ENABLE); DMA_INTConfig(DMA1_CHANNEL2, DMA_INT_TC, ENABLE); /* Enable DMA transfer */ DMA_Enable(DMA1_CHANNEL2, ENABLE); #elif defined GD32F170_190 /* DMA1 channel2 configuration */ DMA_DeInit(DMA1_CHANNEL4); DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)0x40004428; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)SRC_Const_Buffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PERIPHERALDST; DMA_InitStructure.DMA_BufferSize = BufferSize; DMA_InitStructure.DMA_MemoryInc = DMA_MEMORYINC_ENABLE; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PERIPHERALDATASIZE_BYTE; DMA_InitStructure.DMA_MemoryDataSize = DMA_MEMORYDATASIZE_BYTE; DMA_InitStructure.DMA_PeripheralInc = DMA_PERIPHERALINC_DISABLE; DMA_InitStructure.DMA_Mode = DMA_MODE_NORMAL; DMA_InitStructure.DMA_Priority = DMA_PRIORITY_VERYHIGH; DMA_InitStructure.DMA_MTOM = DMA_MEMTOMEM_DISABLE; DMA_Init(DMA1_CHANNEL4, &DMA_InitStructure); USART_DMA_Enable(USART2, USART_DMAREQ_TX, ENABLE); DMA_INTConfig(DMA1_CHANNEL4, DMA_INT_TC, ENABLE); /* Enable DMA transfer */ DMA_Enable(DMA1_CHANNEL4, ENABLE); #endif /* Waiting for the transfer to complete*/ while(count == 0) { } GD_EVAL_LEDOff(LED1); GD_EVAL_LEDOff(LED3); GD_EVAL_LEDOn(LED2); GD_EVAL_LEDOn(LED4); while(1) { } }
/** * @brief Main program. * @param None * @retval None */ int main(void) { /* Configure System clocks -----------------------------------------------*/ RCC_Configuration(); /* Configure NVIC --------------------------------------------------------*/ NVIC_Configuration(); /* Configure GPIO ports --------------------------------------------------*/ GPIO_Configuration(); /* Configure TIM2 --------------------------------------------------------*/ /* Configure Time Base */ TIMER_BaseStructInit(&TIM_TimeBaseStructure); TIM_TimeBaseStructure.TIMER_Period = 256; TIM_TimeBaseStructure.TIMER_Prescaler = 6; TIM_TimeBaseStructure.TIMER_ClockDivision = 0x0; TIM_TimeBaseStructure.TIMER_CounterMode = TIMER_COUNTER_UP; TIMER_BaseInit(TIMER2, &TIM_TimeBaseStructure); /* Configure TIM2 channel2 in PWM mode */ TIM_OCInitStructure.TIMER_OCMode = TIMER_OC_MODE_PWM1; TIM_OCInitStructure.TIMER_OutputState = TIMER_OUTPUT_STATE_ENABLE; TIM_OCInitStructure.TIMER_Pulse = 128; TIM_OCInitStructure.TIMER_OCPolarity = TIMER_OC_POLARITY_LOW; TIMER_OC2_Init(TIMER2, &TIM_OCInitStructure); /* Configure DMA1 Channel1 -----------------------------------------------*/ DMA_DeInit(DMA1_CHANNEL1); DMA_InitStructure.DMA_PeripheralBaseAddr = ADC_RDTR_Address; DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADC_RegularConvertedValueTab; DMA_InitStructure.DMA_DIR = DMA_DIR_PERIPHERALSRC; DMA_InitStructure.DMA_BufferSize = 64; DMA_InitStructure.DMA_PeripheralInc = DMA_PERIPHERALINC_DISABLE; DMA_InitStructure.DMA_MemoryInc = DMA_MEMORYINC_ENABLE; DMA_InitStructure.DMA_PeripheralDataSize = DMA_PERIPHERALDATASIZE_HALFWORD; DMA_InitStructure.DMA_MemoryDataSize = DMA_MEMORYDATASIZE_HALFWORD; DMA_InitStructure.DMA_Mode = DMA_MODE_NORMAL; DMA_InitStructure.DMA_Priority = DMA_PRIORITY_HIGH; DMA_InitStructure.DMA_MTOM = DMA_MEMTOMEM_DISABLE; DMA_Init(DMA1_CHANNEL1, &DMA_InitStructure); /* Enable DMA1 channel1 */ DMA_Enable(DMA1_CHANNEL1, ENABLE); /* Configure ADC ---------------------------------------------------------*/ ADC_InitStructure.ADC_Mode_Scan = ENABLE; ADC_InitStructure.ADC_Mode_Continuous = DISABLE; ADC_InitStructure.ADC_Trig_External = ADC_EXTERNAL_TRIGGER_MODE_T2_CC2; ADC_InitStructure.ADC_Data_Align = ADC_DATAALIGN_RIGHT; ADC_InitStructure.ADC_Channel_Number = 1; ADC_Init(&ADC_InitStructure); /* Configure ADC regular channel14 */ ADC_RegularChannel_Config(ADC_CHANNEL_14, 1, ADC_SAMPLETIME_55POINT5); /* Set inserted sequencer length */ ADC_InsertedSequencerLength_Config(1); /* Configure ADC inserted channel */ ADC_InsertedChannel_Config(ADC_CHANNEL_11, 1, ADC_SAMPLETIME_55POINT5); /* Configure ADC inserted external trigger */ ADC_ExternalTrigInsertedConv_Config(ADC_EXTERNAL_TRIG_INSERTCONV_NONE); /* Enable automatic inserted conversion start after regular one */ ADC_AutoInsertedConv_Enable(ENABLE); /* Enable ADC DMA */ ADC_DMA_Enable(ENABLE); /* Enable ADC external trigger */ ADC_ExternalTrigConv_Enable( ENABLE); /* Enable EOIC interrupt */ ADC_INTConfig(ADC_INT_EOIC, ENABLE); /* Enable ADC */ ADC_Enable(ENABLE); ADC_Calibration(); /* TIM2 counter enable */ TIMER_Enable(TIMER2, ENABLE); /* TIM2 main Output enable */ TIMER_CtrlPWMOutputs(TIMER2, ENABLE); /* Test on channel1 transfer complete flag */ while(!DMA_GetBitState(DMA1_FLAG_TC1)); /* Clear channel1 transfer complete flag */ DMA_ClearBitState(DMA1_FLAG_TC1); /* TIM2 counter disable */ TIMER_Enable(TIMER2, DISABLE); /* Turn on the Led1 */ GD_EVAL_LEDOn(LED1); while (1) { } }
/*! \brief Example code using two different methods of transfer. * * Example code using the two example functions to do a singe block memory * copy and a multi block memory copy. The first test use a polling function * to wait until the transfer completes or get an error. The second test use * an interrupt to know when the transfer completes or get an error. */ void main( void ) { uint32_t index; volatile DMA_CH_t * Channel; Channel = &DMA.CH0; DMA_Enable(); /* Test 1: Copy using repeated blocks. */ /* Fill memory block A with example data. */ for ( index = 0; index < MEM_BLOCK; ++index ) { memoryBlockA[index] = ( (uint8_t) index & 0xff ); } /* Copy data using channel 0. */ gStatus = MultiBlockMemCopy( memoryBlockA, memoryBlockB, MEM_BLOCK_SIZE, MEM_BLOCK_COUNT, Channel ); /* Compare memory blocks if status is true. */ if ( gStatus ) { for ( index = 0; index < MEM_BLOCK; ++index) { if (memoryBlockA[index] != memoryBlockB[index]) { gStatus = false; break; } } } /* Test 2: Copy using single block mode and use interrupt. Perform * second test only if first test succeeded. */ if ( gStatus ) { /* Enable LO interrupt level for the complete transaction and * error flag on DMA channel 0. */ DMA_SetIntLevel( Channel, DMA_CH_TRNINTLVL_LO_gc, DMA_CH_ERRINTLVL_LO_gc ); PMIC.CTRL |= PMIC_LOLVLEN_bm; sei(); /* Fill memory block A with example data again. */ for ( index = 0; index < MEM_BLOCK; ++index ) { memoryBlockA[index] = 0xff - ( (uint8_t) index & 0xff ); } /* Set intDone to false to know when it has been executed. */ gInterruptDone = false; /* Copy data using channel 0. */ gStatus = BlockMemCopy( memoryBlockA, memoryBlockB, MEM_BLOCK, Channel); do { /* Do something here while waiting for the * interrupt routine to signal completion. */ } while ( gInterruptDone == false ); /* Compare memory blocks. */ if ( gStatus ) { for ( index = 0; index < MEM_BLOCK; ++index ) { if (memoryBlockA[index] != memoryBlockB[index]) { gStatus = false; break; } } } } if ( gStatus ) { do { /* Completed with success. */ } while (1); } else { do { /* Completed with failure. */ } while (1); } }