コード例 #1
0
ファイル: neomaple_hardware.c プロジェクト: fergul/NeoMaple
/* Transmit the frambuffer with buffersize number of bytes to the LEDs 
 * buffersize = (#LEDs / 16) * 24 */
void neomaple_hard_send(uint8_t *buffer, uint32_t size)
{   
  // transmission complete flag, indicate that transmission is taking place
  WS2812_TC = 0;
  //WS2812_buffer = buffer;
  // clear all relevant DMA flags
  dma_clear_isr_bits(DMA1, DMA_CH2);
  dma_clear_isr_bits(DMA1, DMA_CH5);
  dma_clear_isr_bits(DMA1, DMA_CH7);

  // configure the number of bytes to be transferred by the DMA controller
  //dma_set_mem_addr(DMA1, DMA_CH5, WS2812_buffer);
  dma_set_num_transfers(DMA1, DMA_CH2, size);
  dma_set_num_transfers(DMA1, DMA_CH5, size);
  dma_set_num_transfers(DMA1, DMA_CH7, size);

  // clear all TIM2 flags
  TIMER2->regs.gen->SR = 0;
  
  // enable the corresponding DMA channels
  dma_enable(DMA1, DMA_CH2);
  dma_enable(DMA1, DMA_CH5);
  dma_enable(DMA1, DMA_CH7);
  // IMPORTANT: enable the TIM2 DMA requests AFTER enabling the DMA channels!
  timer_dma_enable_req(TIMER2, 1);
  timer_dma_enable_req(TIMER2, 2);
  timer_dma_enable_req(TIMER2, 0); /* TIM_DMA_Update */
  
  // preload counter with 29 so TIM2 generates UEV directly to start DMA transfer
  timer_set_count(TIMER2, 29);
  
  // start TIM2
  timer_resume(TIMER2);
}
コード例 #2
0
ファイル: ppm-decode.cpp プロジェクト: dotjairo/tricopter
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..


}
コード例 #3
0
/**
 * \brief Access AES module with DMA support
 *
 * \note Read STATE using DMA channel 0.
 * Check DMA driver example for more information about DMA usage.
 *
 */
static void aes_dma_output(void)
{
	// Make sure config is all zeroed out so we don't get any stray bits
	memset(&config, 0, sizeof(config));

	dma_enable();
	dma_channel_set_burst_length(&config, DMA_CH_BURSTLEN_1BYTE_gc);
	dma_channel_set_transfer_count(&config, BLOCK_LENGTH);
	dma_channel_set_src_reload_mode(&config, DMA_CH_SRCRELOAD_NONE_gc);
	dma_channel_set_dest_reload_mode(&config, DMA_CH_DESTRELOAD_NONE_gc);
	dma_channel_set_src_dir_mode(&config, DMA_CH_SRCDIR_FIXED_gc);
	dma_channel_set_dest_dir_mode(&config, DMA_CH_DESTDIR_INC_gc);
	dma_channel_set_source_address(&config, (uint16_t)(uintptr_t)&AES_STATE);
	dma_channel_set_destination_address(&config,
		(uint16_t)(uintptr_t)single_ans);
	dma_channel_write_config(DMA_CHANNEL_N, &config);

	// Use the configuration above by enabling the DMA channel in use.
	dma_channel_enable(DMA_CHANNEL_N);

	/*
	 * Trigger a manual start since there is no trigger sources used in
	 * this example.
	 */
	dma_channel_trigger_block_transfer(DMA_CHANNEL_N);
	while (!(DMA_CH0_CTRLB & DMA_CH_TRNIF_bm));
	DMA_CH0_CTRLB |= DMA_CH_TRNIF_bm;

	dma_disable();
}
コード例 #4
0
//------------------------------------------------------------------------------
// 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;
}
コード例 #5
0
ファイル: STM32ADC.cpp プロジェクト: Serasidis/Arduino_STM32
/*
    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.
    }
コード例 #6
0
void DMA_HANDLER (void)
{

    if (dma_state(0)){ //check interrupt status on channel 0

				dma_clean(0);         // Clear terminate counter Interrupt pending
	
					if(tx_proc_buffer == (PONG))
						{
						dma_src_memory (0,(uint32_t)&(dma_tx_buffer_pong));    //Ping-pong the source address                 
						tx_proc_buffer = PING; 
						}
					else
						{
						dma_src_memory (0,(uint32_t)&(dma_tx_buffer_ping));                
						tx_proc_buffer = PONG; 
						}
				tx_buffer_empty = 1;                // signal to main() that tx buffer empty					
       
				//Enable channel 0 for the next transmission
				dma_transfersize(0,DMA_BUFFER_SIZE);
				dma_enable(0);			
    }
    if (dma_state(1)){ //check interrupt status on channel 1

        // Clear terminate counter Interrupt pending
				dma_clean(1);
					if(rx_proc_buffer == PONG)
					  {
						dma_dest_memory (1,(uint32_t)&(dma_rx_buffer_pong));   //Ping-pong the destination address
						rx_proc_buffer = PING;
						}
					else
						{
						dma_dest_memory (1,(uint32_t)&(dma_rx_buffer_ping));   
						rx_proc_buffer = PONG;
						}
					rx_buffer_full = 1;   					

				//Enable channel 1 for the next transmission
				dma_transfersize(1,DMA_BUFFER_SIZE);
				dma_enable(1);		
    }
}
コード例 #7
0
ファイル: dma.c プロジェクト: Noltari/u-boot
static int dm_test_dma_rx(struct unit_test_state *uts)
{
	struct udevice *dev;
	struct dma dma_tx, dma_rx;
	u8 src_buf[512];
	u8 dst_buf[512];
	void *dst_ptr;
	size_t len = 512;
	u32 meta1, meta2;
	int i;

	ut_assertok(uclass_get_device_by_name(UCLASS_DMA, "dma", &dev));

	ut_assertok(dma_get_by_name(dev, "tx0", &dma_tx));
	ut_assertok(dma_get_by_name(dev, "rx0", &dma_rx));

	ut_assertok(dma_enable(&dma_tx));
	ut_assertok(dma_enable(&dma_rx));

	memset(dst_buf, 0, len);
	for (i = 0; i < len; i++)
		src_buf[i] = i;
	meta1 = 0xADADDEAD;
	meta2 = 0;
	dst_ptr = NULL;

	ut_assertok(dma_prepare_rcv_buf(&dma_tx, dst_buf, len));

	ut_assertok(dma_send(&dma_tx, src_buf, len, &meta1));

	ut_asserteq(len, dma_receive(&dma_rx, &dst_ptr, &meta2));
	ut_asserteq(0xADADDEAD, meta2);
	ut_asserteq_ptr(dst_buf, dst_ptr);

	ut_assertok(dma_disable(&dma_tx));
	ut_assertok(dma_disable(&dma_rx));

	ut_assertok(dma_free(&dma_tx));
	ut_assertok(dma_free(&dma_rx));
	ut_assertok(memcmp(src_buf, dst_buf, len));

	return 0;
}
コード例 #8
0
/* 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);
}
コード例 #9
0
ファイル: fiteco-a8_drivers.c プロジェクト: uthai007/openlab
void platform_drivers_setup()
{
    // Set base address and AHB bit for all GPIO ports
    gpio_enable(GPIO_A);
    gpio_enable(GPIO_B);
    gpio_enable(GPIO_C);
    gpio_enable(GPIO_D);

    // Enable the AFIO
    rcc_apb_enable(RCC_APB_BUS_AFIO, RCC_APB_BIT_AFIO);

    // Start the TIM3 at ~32kHz
    timer_enable(TIM_3);
    timer_select_internal_clock(TIM_3, (rcc_sysclk_get_clock_frequency(
                                           RCC_SYSCLK_CLOCK_PCLK1_TIM) / 32768) - 1);
    timer_start(TIM_3, 0xFFFF, NULL, NULL);

    // Enable the print uart
    gpio_set_uart_tx(GPIO_A, GPIO_PIN_9);
    gpio_set_uart_rx(GPIO_A, GPIO_PIN_10);
    uart_enable(UART_1, PLATFORM_UART_PRINT_BAUDRATE);

    // Configure the DMA for the SPIs
    dma_enable(DMA_1_CH4);
    dma_enable(DMA_1_CH5);

    // Configure the SPI 2
    gpio_set_spi_clk(GPIO_B, GPIO_PIN_13);
    gpio_set_spi_miso(GPIO_B, GPIO_PIN_14);
    gpio_set_spi_mosi(GPIO_B, GPIO_PIN_15);
    spi_set_dma(SPI_2, DMA_1_CH4, DMA_1_CH5);
    spi_enable(SPI_2, 4000000, SPI_CLOCK_MODE_IDLE_LOW_RISING);

    // Configure the I2C 1
    gpio_set_i2c_scl(GPIO_B, GPIO_PIN_6);
    gpio_set_i2c_sda(GPIO_B, GPIO_PIN_7);
    i2c_enable(I2C_1, I2C_CLOCK_MODE_FAST);

    // Force inclusion of EXTI
    exti_set_handler(EXTI_LINE_Px0, NULL, NULL);
}
コード例 #10
0
ファイル: dosdma.c プロジェクト: Bracket-/psp-ports
void dma_start(dma_buffer * buffer, unsigned long count, unsigned char mode)
{
	/* Disable interrupts */
	int old_ints = disable();
	dma_disable(buffer->channel);
	dma_set_mode(buffer->channel, mode);
	dma_clear_ff(buffer->channel);
	dma_set_addr(buffer->channel, buffer->physical);
	dma_clear_ff(buffer->channel);
	dma_set_count(buffer->channel, count);
	dma_enable(buffer->channel);
	/* Re-enable interrupts */
	if (old_ints)
		enable();
}
コード例 #11
0
ファイル: STM32ADC.cpp プロジェクト: Serasidis/Arduino_STM32
    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.
    }
コード例 #12
0
/**
 * \brief Test the error handling of the module
 *
 * \note Test error handling by disabling a channel which is in use
 *
 * \param test              Current test
 */
static void run_dma_error_handling_test(const struct test_case *test)
{
	/* Enable DMA */
	dma_enable();

	/* Reset the channel */
	dma_channel_reset(DMA_CHANNEL_0);

	/* Set up channel 0 to do some work, check that is it busy,
	 * change some settings and verify a transfer error */
	dma_channel_write_burst_length(DMA_CHANNEL_0,
			DMA_CH_BURSTLEN_1BYTE_gc);
	dma_channel_write_transfer_count(DMA_CHANNEL_0,
			MEMORY_BLOCK_SIZE);
	dma_channel_write_source(DMA_CHANNEL_0,
			(uint16_t)(uintptr_t)memory_block_src);
	dma_channel_write_destination(DMA_CHANNEL_0,
			(uint16_t)(uintptr_t)memory_block_dest);

	/* Enable the channel */
	dma_channel_enable(DMA_CHANNEL_0);

	/* Start a block transfer */
	dma_channel_trigger_block_transfer(DMA_CHANNEL_0);

	/* Wait for the channel to become busy */
	while (!dma_channel_is_busy(DMA_CHANNEL_0)) {
		/* Intentionally left empty */
	}

	/* Disable the channel while it is busy */
	if (dma_channel_is_busy(DMA_CHANNEL_0)) {
		dma_channel_disable(DMA_CHANNEL_0);
	}

	/* Test whether the channel is in error */
	test_assert_true(test,
			dma_get_channel_status(
			DMA_CHANNEL_0) == DMA_CH_TRANSFER_ERROR,
			"DMA channel not in error after disabling during transfer"
			" write");

	dma_disable();
}
コード例 #13
0
ファイル: unit_tests.c プロジェクト: InSoonPark/asf
/**
 * \brief Setup a DMA channel for CRC calculation
 *
 * \param buf_length    Length of buffer to transfer
 * \param src_buffer    Pointer to transfer buffer
 * \param dst_buffer    Pointer to receive buffer
 */
static void setup_dma_channel(uint8_t buf_length,
		uint8_t *src_buffer, uint8_t *dst_buffer)
{
	struct dma_channel_config config;

	dma_enable();

	dma_channel_write_source(CONF_TEST_DMACH, (uint16_t)src_buffer);
	dma_channel_write_destination(CONF_TEST_DMACH, (uint16_t)dst_buffer);
	dma_channel_write_burst_length(CONF_TEST_DMACH, 1);
	dma_channel_write_transfer_count(CONF_TEST_DMACH, buf_length);
	dma_channel_write_repeats(CONF_TEST_DMACH, 1);

	dma_channel_read_config(CONF_TEST_DMACH, &config);
	dma_channel_set_src_dir_mode(&config, DMA_CH_SRCDIR_INC_gc);
	dma_channel_set_dest_dir_mode(&config, DMA_CH_DESTDIR_INC_gc);
	dma_channel_write_config(CONF_TEST_DMACH, &config);

	dma_channel_enable(CONF_TEST_DMACH);
}
コード例 #14
0
/** 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;
  }
}
コード例 #15
0
ファイル: dxl_serial.cpp プロジェクト: RhobanProject/Maplebot
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
}
コード例 #16
0
ファイル: test_zero.c プロジェクト: NicoleOtsuka/cmpe-295
int main()
{
	struct zynq_ipif ipif;
	int i, test = 0x01020304;
	char cmd[256];
	int ret = 0;

	for (i = 0; i < ARRAY_SIZE(test_buf[0]); i++)
		test_buf[0][i] = test + i * 0x04040404;

	zynq_ipif_init(&ipif, &ipif_config);

	reg_write(regmap, 0x0, 0x1f);
	reg_write(regmap, 0x0, 0x0);

	reg_write(regmap, 0x1c, 10000);

	dma_init(&ipif.dma[0], &dma_config[0]);
	dma_init(&ipif.dma[2], &dma_config[2]);

	zynq_ipif_prepare_dma_share(&ipif.dma_share);

	/* Fill the ring buffer as the initialization */
	dma_write_buffer(&ipif.dma[0], (u8 *)test_buf[0], BUF_SIZE);

	dma_enable(&ipif.dma[0], 1);
	dma_enable(&ipif.dma[2], 1);

	reg_write(regmap, 0x4, 0x1f);
	reg_write(regmap, 0x8, 0x6667);

	sleep(2);

	reg_write(regmap, 0x8, 0x0);
	reg_write(regmap, 0x4, 0x0);

	dma_enable(&ipif.dma[0], 0);
	dma_enable(&ipif.dma[2], 0);

	zynq_ipif_unprepare_dma_share(&ipif.dma_share);

	dma_exit(&ipif.dma[0]);
	dma_exit(&ipif.dma[2]);

	for (i = 0; i < ARRAY_SIZE(test_buf[0]); i++)
		if (test_buf[0][i] != test_buf[1][i])
			ret++;

	printf("test %s, %d, %d\n", ret ? "failed" : "succeed",
	       ipif.dma[0].io_ptr, ipif.dma[2].io_ptr);

	zynq_ipif_exit(&ipif);

	printf("dumping results...\n");
	sprintf(cmd, "rm -f dump");
	system(cmd);
	for (i = 0; i < ARRAY_SIZE(test_buf[0]); i++) {
		sprintf(cmd, "echo '%x - %x' >> dump",
				test_buf[0][i], test_buf[1][i]);
		system(cmd);
	}

	return 0;
}
コード例 #17
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;
}
コード例 #18
0
/**
 * \brief main function
 */
int main(void)
{
	struct dma_channel_config config;
	uint32_t                  checksum;

	pmic_init();
	board_init();
	sysclk_init();
	sleepmgr_init();

	// Randomly selected data
	source[0] = 0xAA;
	source[1] = 0xBB;
	source[2] = 0xCC;
	source[3] = 0xDD;
	source[4] = 0xEE;
	source[5] = 0xFF;

	// Calculate checksum for the data
	checksum = crc_io_checksum((void*)source, 6, CRC_16BIT);
	// Append the checksum to the data, big endian
	crc16_append_value(checksum, source+6);

	//Enable the CRC module for DMA
	crc_dma_checksum_start(DMA_CHANNEL, CRC_16BIT);

	// Enable DMA
	dma_enable();

	// Set callback function for DMA completion
	dma_set_callback(DMA_CHANNEL, example_crc_dma_transfer_done);

	// Make sure config is all zeroed out so we don't get any stray bits
	memset(&config, 0, sizeof(config));

	/**
	 * This example will configure a DMA channel with the following
	 * settings:
	 *  - Low interrupt priority
	 *  - 1 byte burst length
	 *  - DMA_BUFFER_SIZE bytes for each transfer
	 *  - Reload source and destination address at end of each transfer
	 *  - Increment source and destination address during transfer
	 *  - Source address is set to \ref source
	 *  - Destination address is set to \ref destination
	 */
	dma_channel_set_interrupt_level(&config, PMIC_LVL_LOW);
	dma_channel_set_burst_length(&config, DMA_CH_BURSTLEN_1BYTE_gc);
	dma_channel_set_transfer_count(&config, DMA_BUFFER_SIZE);
	dma_channel_set_src_reload_mode(&config,
			DMA_CH_SRCRELOAD_TRANSACTION_gc);
	dma_channel_set_dest_reload_mode(&config,
			DMA_CH_DESTRELOAD_TRANSACTION_gc);
	dma_channel_set_src_dir_mode(&config, DMA_CH_SRCDIR_INC_gc);
	dma_channel_set_dest_dir_mode(&config, DMA_CH_DESTDIR_INC_gc);
	dma_channel_set_source_address(&config, (uint16_t)(uintptr_t)source);
	dma_channel_set_destination_address(&config,
			(uint16_t)(uintptr_t)destination);
	dma_channel_write_config(DMA_CHANNEL, &config);

	// Use the configuration above by enabling the DMA channel in use.
	dma_channel_enable(DMA_CHANNEL);

	// Enable interrupts
	cpu_irq_enable();

	// Trigger the DMA transfer
	dma_channel_trigger_block_transfer(DMA_CHANNEL);

	// Light the first LED to indicate that the DMA has started.
	gpio_set_pin_low(LED0_GPIO);

	while (true) {
		/*
		 * Force a NOP instruction for an eventual placement of a debug
		 * session breakpoint.
		 */
		asm("nop\n");
	}
}
コード例 #19
0
/**
 *
 * \brief Set DMA configuration, and read it back
 *
 * \note This function writes a configuration to the DMA
 * controller, and reads it back to verify settings have
 * been correctly set.
 *
 * \param test   Current test case
 */
static void run_dma_config_interface_test(const struct test_case *test)
{
	struct dma_channel_config config_params;
	struct dma_channel_config read_config;

	const uint16_t transfer_count = 1024;
	const uint8_t repeats         = 64;
	uint8_t channel_index;

#ifdef CONFIG_HAVE_HUGEMEM
	hugemem_ptr_t dest_huge_addr  = HUGEMEM_NULL;
	hugemem_ptr_t src_huge_addr   = HUGEMEM_NULL;

	hugemem_write32(dest_huge_addr, 0xABCD1234);
	hugemem_write32(src_huge_addr, 0xAAAABBBB);
#else
	const uint16_t dest_addr      = 0xBEEF;
	const uint16_t src_addr       = 0xABCD;
#endif

	memset(&config_params, 0, sizeof(config_params));

	dma_enable();

	/* Apply some parameters */
	dma_channel_set_burst_length(&config_params,
			DMA_CH_BURSTLEN_4BYTE_gc);
	dma_channel_set_single_shot(&config_params);
	dma_channel_set_interrupt_level(&config_params,
			PMIC_LVL_HIGH);
	dma_channel_set_src_reload_mode(&config_params,
			DMA_CH_SRCRELOAD_BLOCK_gc);
	dma_channel_set_dest_reload_mode(&config_params,
			DMA_CH_DESTRELOAD_BURST_gc);
	dma_channel_set_src_dir_mode(&config_params,
			DMA_CH_SRCDIR_DEC_gc);
	dma_channel_set_dest_dir_mode(&config_params,
			DMA_CH_DESTDIR_DEC_gc);
	dma_channel_set_trigger_source(&config_params,
			DMA_CH_TRIGSRC_TCC0_CCA_gc);
	dma_channel_set_transfer_count(&config_params,
			transfer_count);
	dma_channel_set_repeats(&config_params,
			repeats);

#ifdef CONFIG_HAVE_HUGEMEM
	dma_channel_set_destination_hugemem(&config_params, dest_huge_addr);
	dma_channel_set_source_hugemem(&config_params, src_huge_addr);
#else
	dma_channel_set_destination_address(&config_params, dest_addr);
	dma_channel_set_source_address(&config_params, src_addr);
#endif

	/* Loop through all channels, read back config from them, and verify */
	for (channel_index = 0; channel_index < DMA_NUMBER_OF_CHANNELS; channel_index++) {
		dma_channel_write_config(channel_index, &config_params);

		/* Null out the read_config struct */
		memset(&read_config, 0, sizeof(read_config));

		/* Read the config back from the module */
		dma_channel_read_config(channel_index, &read_config);

		test_assert_true(test,
				read_config.addrctrl == config_params.addrctrl,
				"CH %d: Address control register does not match configuration",
				channel_index);

		test_assert_true(test, read_config.ctrla == config_params.ctrla,
				"CH %d: Control register A does not match configuration",
				channel_index);

		test_assert_true(test,
				read_config.repcnt == config_params.repcnt,
				"CH %d: Repeat counter register does not match configuration",
				channel_index);

		test_assert_true(test,
				read_config.trfcnt == config_params.trfcnt,
				"CH %d: Transfer counter register does not"
				" match configuration", channel_index);

		test_assert_true(test,
				read_config.trigsrc == config_params.trigsrc,
				"CH %d: Trigger source register does not match configuration",
				channel_index);

#ifdef CONFIG_HAVE_HUGEMEM
		test_assert_true(test,
				read_config.destaddr == config_params.destaddr,
				"CH %d: Destination address register does not"
				" match configuration", channel_index);

		test_assert_true(test,
				read_config.srcaddr == config_params.srcaddr,
				"CH %d: Source address register does not match configuration",
				channel_index);
#else
		test_assert_true(test,
				read_config.destaddr16 == config_params.destaddr16,
				"CH %d: DESTADDR16 does not match configuration",
				channel_index);

		test_assert_true(test,
				read_config.srcaddr16 == config_params.srcaddr16,
				"CH %d: SRCADDR16 does not match configuration");
#endif
	}

	/* Reset the channel */
	dma_channel_reset(DMA_CHANNEL_0);

	/* Check set and unset single shot */
	memset(&config_params, 0, sizeof(config_params));
	memset(&read_config, 0, sizeof(read_config));

	dma_channel_set_single_shot(&config_params);

	dma_channel_write_config(DMA_CHANNEL_0, &config_params);
	dma_channel_read_config(DMA_CHANNEL_0, &read_config);

	test_assert_true(test, read_config.ctrla == config_params.ctrla,
			"Single shot mode not set correctly");

	memset(&config_params, 0, sizeof(config_params));
	dma_channel_unset_single_shot(&config_params);

	dma_channel_write_config(DMA_CHANNEL_0, &config_params);
	dma_channel_read_config(DMA_CHANNEL_0, &read_config);

	test_assert_true(test, read_config.ctrla == config_params.ctrla,
			"Single shot mode not unset correctly");

	/* Reset it again, and test the direct configuration functions */
	memset(&read_config, 0, sizeof(read_config));

	dma_channel_write_burst_length(DMA_CHANNEL_0, DMA_CH_BURSTLEN_4BYTE_gc);
	dma_channel_write_transfer_count(DMA_CHANNEL_0, transfer_count);
	dma_channel_write_repeats(DMA_CHANNEL_0, repeats);

#ifdef CONFIG_HAVE_HUGEMEM
	dma_channel_write_source_hugemem(DMA_CHANNEL_0, src_huge_addr);
	dma_channel_write_destination_hugemem(DMA_CHANNEL_0, dest_huge_addr);
#else
	dma_channel_write_source(DMA_CHANNEL_0, src_addr);
	dma_channel_write_destination(DMA_CHANNEL_0, dest_addr);
#endif

	/* Verify that settings have been set correctly */
	dma_channel_read_config(DMA_CHANNEL_0, &read_config);

	test_assert_true(test,
			(read_config.ctrla & DMA_CH_BURSTLEN_gm)
			== DMA_CH_BURSTLEN_4BYTE_gc,
			"Read burst length does not match configuration");

	test_assert_true(test, read_config.trfcnt == transfer_count,
			"Read transfer count does not match configuration");

	test_assert_true(test, read_config.repcnt == repeats,
			"Read repeat value does not match configuration");

#ifdef CONFIG_HAVE_HUGEMEM
	test_assert_true(test, read_config.srcaddr == src_huge_addr,
			"Read source address does not match configuration");

	test_assert_true(test, read_config.destaddr == dest_huge_addr,
			"Read destination address does not match configuration");
#else
	test_assert_true(test, read_config.srcaddr16 == src_addr,
			"Read source address does not match configuration");

	test_assert_true(test, read_config.destaddr16 == dest_addr,
			"Read destination address does not match configuration");
#endif

	dma_disable();
}
コード例 #20
0
/**
 * \brief Test different directions on all channels
 *
 * \note This test copies the source memory block into the destination block
 * in different ways.
 *
 * \param test              Current test
 */
static void run_dma_direction_test(const struct test_case *test)
{
	struct dma_channel_config config_params;
	uint8_t channel_index;
	bool success = true; /* Assume everything goes well */

	/* Fill the source block with our known pattern */
	set_buffer(memory_block_src, 0x00);
	block_fill(memory_block_src, MEMORY_BLOCK_SIZE);

	/* Null out the config params */
	memset(&config_params, 0, sizeof(config_params));

	/* Enable DMA */
	dma_enable();

	/* No reload on source and destination */
	dma_channel_set_src_reload_mode(&config_params,
			DMA_CH_SRCRELOAD_NONE_gc);
	dma_channel_set_dest_reload_mode(&config_params,
			DMA_CH_DESTRELOAD_NONE_gc);
	dma_channel_set_transfer_count(&config_params,
			MEMORY_BLOCK_SIZE);
	dma_channel_set_burst_length(&config_params,
			DMA_CH_BURSTLEN_1BYTE_gc);

	/* Test a memory transfer on all channels */
	for (channel_index = 0; channel_index < DMA_NUMBER_OF_CHANNELS;
			channel_index++) {
		/* Reset channel and write the configuration */
		dma_channel_reset(channel_index);
		/* Increment source, increment destination */
		dma_channel_set_src_dir_mode(&config_params,
				DMA_CH_SRCDIR_INC_gc);
		dma_channel_set_dest_dir_mode(&config_params,
				DMA_CH_DESTDIR_INC_gc);
		/* Data starts from the first byte */
		dma_channel_set_source_address(&config_params,
				(uint16_t)(uintptr_t)memory_block_src);
		dma_channel_set_destination_address(&config_params,
				(uint16_t)(uintptr_t)memory_block_dest);

		/* Write the config */
		dma_channel_write_config(channel_index, &config_params);

		/* Clear destination */
		set_buffer(memory_block_dest, 0x00);

		/* Enable channel, transfer, and disable it */
		dma_channel_enable(channel_index);
		dma_transfer_block(channel_index);
		dma_channel_disable(channel_index);

		/* Check that source and destination are equal */
		success = block_compare(memory_block_src,
				memory_block_dest, MEMORY_BLOCK_SIZE);

		if (!success) {
			break;
		}

		/* Reset channel and write the configuration */
		dma_channel_reset(channel_index);
		/* Decrement source, increment destination */
		dma_channel_set_src_dir_mode(&config_params,
				DMA_CH_SRCDIR_DEC_gc);
		dma_channel_set_dest_dir_mode(&config_params,
				DMA_CH_DESTDIR_INC_gc);
		/* Data starts from the first byte */
		dma_channel_set_source_address(&config_params,
				(uint16_t)(uintptr_t)
				(memory_block_src + MEMORY_BLOCK_SIZE - 1));
		dma_channel_set_destination_address(&config_params,
				(uint16_t)(uintptr_t)memory_block_dest);

		/* Write the config */
		dma_channel_write_config(channel_index, &config_params);

		/* Clear destination */
		set_buffer(memory_block_dest, 0x00);

		/* Enable channel, transfer, and disable it */
		dma_channel_enable(channel_index);
		dma_transfer_block(channel_index);
		dma_channel_disable(channel_index);

		/* Check that destination is the reverse of source */
		success = block_compare_reverse(memory_block_src,
				memory_block_dest, MEMORY_BLOCK_SIZE);

		if (!success) {
			break;
		}

		/* Reset channel and write the configuration */
		dma_channel_reset(channel_index);
		/* Decrement source, increment destination */
		dma_channel_set_src_dir_mode(&config_params,
				DMA_CH_SRCDIR_INC_gc);
		dma_channel_set_dest_dir_mode(&config_params,
				DMA_CH_DESTDIR_DEC_gc);
		/* Data starts from the first byte */
		dma_channel_set_source_address(&config_params,
				(uint16_t)(uintptr_t)memory_block_src);
		dma_channel_set_destination_address(&config_params,
				(uint16_t)(uintptr_t)
				(memory_block_dest + MEMORY_BLOCK_SIZE - 1));

		/* Write the config */
		dma_channel_write_config(channel_index, &config_params);

		/* Clear destination */
		set_buffer(memory_block_dest, 0x00);

		/* Enable channel, transfer, and disable it */
		dma_channel_enable(channel_index);
		dma_transfer_block(channel_index);
		dma_channel_disable(channel_index);

		/* Check that destination is the reverse of source */
		success = block_compare_reverse(memory_block_src,
				memory_block_dest, MEMORY_BLOCK_SIZE);

		if (!success) {
			break;
		}

		/* Reset channel and write the configuration */
		dma_channel_reset(channel_index);
		/* Decrement source, Decrement destination */
		dma_channel_set_src_dir_mode(&config_params,
				DMA_CH_SRCDIR_DEC_gc);
		dma_channel_set_dest_dir_mode(&config_params,
				DMA_CH_DESTDIR_DEC_gc);
		/* Data starts from the first byte */
		dma_channel_set_source_address(&config_params,
				(uint16_t)(uintptr_t)
				(memory_block_src + MEMORY_BLOCK_SIZE - 1));
		dma_channel_set_destination_address(&config_params,
				(uint16_t)(uintptr_t)
				(memory_block_dest + MEMORY_BLOCK_SIZE - 1));

		/* Write the config */
		dma_channel_write_config(channel_index, &config_params);

		/* Clear destination */
		set_buffer(memory_block_dest, 0x00);

		/* Enable channel, transfer, and disable it */
		dma_channel_enable(channel_index);
		dma_transfer_block(channel_index);
		dma_channel_disable(channel_index);

		/* Check that source and destination are equal */
		success = block_compare(memory_block_src,
				memory_block_dest, MEMORY_BLOCK_SIZE);

		if (!success) {
			break;
		}
	}

	/* Disable DMA */
	dma_disable();

	test_assert_true(test, success,
			"DMA direction copy test failed on channel %d",
			channel_index);
}
コード例 #21
0
ファイル: doswss.c プロジェクト: LighFusion/surreal
static boolean __wss_detect()
{
	/* First find the port number */
	if (!wss.port) {
		static unsigned int wss_ports[] =
		  { 0x32c, 0x530, 0x604, 0xE80, 0xF40 };
		int i;
		for (i = 0; i < 5; i++) {
			wss.port = wss_ports[i];
			if (__wss_ping())
				break;
		}
		if (i < 0) {
			wss.port = 0;
			return FALSE;
		}
	}

	/* Now disable output */
	wss_output(FALSE);

	/* Detect the DMA channel */
	if (!wss.dma) {
		static int __dma[] = { 0, 1, 3 };
		int i;

		/* Enable playback IRQ */
		__wss_regbit_set(WSSR_PIN_CTRL, WSSM_IRQ_ENABLE);
		__wss_outreg(WSSR_IRQ_STATUS, WSSM_PLAYBACK_IRQ);

		/* Start a short DMA transfer and check if DMA count is zero */
		for (i = 0; i < 3; i++) {
			unsigned int timer, status, freq = 44100;

			wss.dma = __dma[i];

			dma_disable(wss.dma);
			dma_set_mode(wss.dma, DMA_MODE_WRITE);
			dma_clear_ff(wss.dma);
			dma_set_count(wss.dma, 10);
			dma_enable(wss.dma);

			/* Clear IRQ status */
			outportb(WSS_STATUS, 0);

			__wss_setformat(__wss_getrate(&freq));
			__wss_outreg(WSSR_COUNT_LOW, 1);
			__wss_outreg(WSSR_COUNT_HIGH, 0);
			/* Tell codec to start transfer */
			__wss_regbit_set(WSSR_IFACE_CTRL, WSSM_PLAYBACK_ENABLE);

			_farsetsel(_dos_ds);
			timer = _farnspeekl(0x46c);

			while (_farnspeekl(0x46c) - timer <= 2)
				if (dma_get_count(wss.dma) == 0)
					break;
			__wss_regbit_reset(WSSR_IFACE_CTRL, WSSM_PLAYBACK_ENABLE);
			dma_disable(wss.dma);

			/* Now check if DMA transfer count is zero and an IRQ is pending */
			status = inportb(WSS_STATUS);
			outportb(WSS_STATUS, 0);
			if ((dma_get_count(wss.dma) == 0) && (status & WSSM_INT))
				break;

			wss.dma = 0;
		}

		if (!wss.dma)
			return FALSE;
	}

	/* Now detect the IRQ number */
	if (!wss.irq) {
		unsigned int i, irqmask, freq = 5510;
		unsigned long timer, delta = 0x7fffffff;

		/* IRQ can be one of 2,3,5,7,10 */
		irq_detect_start(0x04ac, __wss_irq_irqdetect);

		dma_disable(wss.dma);
		dma_set_mode(wss.dma, DMA_MODE_WRITE | DMA_MODE_AUTOINIT);
		dma_clear_ff(wss.dma);
		dma_set_count(wss.dma, 1);
		dma_enable(wss.dma);

		__wss_setformat(__wss_getrate(&freq));

		/* Clear IRQ status */
		outportb(WSS_STATUS, 0);

		__wss_outreg(WSSR_COUNT_LOW, 0);
		__wss_outreg(WSSR_COUNT_HIGH, 0);

		/* Prepare timeout counter */
		_farsetsel(_dos_ds);
		timer = _farnspeekl(0x46c);
		while (timer == _farnspeekl(0x46c));
		timer = _farnspeekl(0x46c);

		/* Reset all IRQ counters */
		irq_detect_clear();

		/* Tell codec to start transfer */
		__wss_regbit_set(WSSR_IFACE_CTRL, WSSM_PLAYBACK_ENABLE);

		/* Now wait 1/18 seconds */
		while (timer == _farnspeekl(0x46c));
		__wss_regbit_reset(WSSR_IFACE_CTRL, WSSM_PLAYBACK_ENABLE);
		dma_disable(wss.dma);

		/* Given frequency 5510Hz, a buffer size of 1 byte and a time interval
		   of 1/18.2 second, we should have received about 302 interrupts */
		for (i = 2; i <= 10; i++) {
			int count = abs(302 - irq_detect_get(i, &irqmask));
			if (count < delta)
				wss.irq = i, delta = count;
		}
		if (delta > 150)
			wss.irq = 0;

		irq_detect_end();
		if (!wss.irq)
			return FALSE;
	}

	return TRUE;
}
コード例 #22
0
/**
 * \brief Test read from fixed location, trigger from timer and callback
 *
 * \note This test sets up a timer to trigger the DMA module,
 * which in turn reads the timer_overflow_counter variable and writes
 * it to memory sequentially. It then checks to see that the memory block
 * written is sequential according to the overflow count.
 *
 * \param test              Current test
 */
static void run_dma_triggered_with_callback(const struct test_case *test)
{
	struct dma_channel_config config_params;
	bool success;

	/* Null the buffer */
	set_buffer(dest_block_tc, 0x0000);

	/* Null out the config parameter struct */
	memset(&config_params, 0, sizeof(config_params));

	/*
	 * Enable the timer, and set it to count up.
	 * When it overflows, it triggers the DMA to
	 * read timer_overflow_counter. */
	tc_enable(&TIMER);

	tc_set_direction(&TIMER, TC_UP);
	tc_write_period(&TIMER, TIMER_PERIOD);

	tc_set_resolution(&TIMER, TIMER_RESOLUTION);

	tc_set_overflow_interrupt_level(&TIMER, PMIC_LVL_LOW);
	tc_set_overflow_interrupt_callback(&TIMER, timer_overflow_callback);

	/* Enable the DMA module */
	dma_enable();

	/* Set callback for transfer done */
	dma_set_callback(DMA_CHANNEL_0, dma_transfer_is_complete);

	/* Set low interrupt level */
	dma_channel_set_interrupt_level(&config_params, PMIC_LVL_LOW);

	/* Set up the DMA to read the timer value
	 *
	 * - Single shot transfer mode
	 * - Two byte (16-bit) burst length
	 * - Increment on source and destination
	 * - Reload on burst for source
	 * - No reload for destination
	 */
	dma_channel_set_single_shot(&config_params);
	dma_channel_set_burst_length(&config_params,
			DMA_CH_BURSTLEN_1BYTE_gc);
	dma_channel_set_src_reload_mode(&config_params,
			DMA_CH_SRCRELOAD_BURST_gc);
	dma_channel_set_src_dir_mode(&config_params,
			DMA_CH_SRCDIR_FIXED_gc);
	dma_channel_set_dest_reload_mode(&config_params,
			DMA_CH_DESTRELOAD_NONE_gc);
	dma_channel_set_dest_dir_mode(&config_params,
			DMA_CH_DESTDIR_INC_gc);

	/* Set trigger source to TCC0's overflow */
	dma_channel_set_trigger_source(&config_params,
			DMA_CH_TRIGSRC_TCC0_OVF_gc);

	/* Transfer DEST_BLOCK_TC_SIZE bytes */
	dma_channel_set_transfer_count(&config_params,
			DEST_BLOCK_TC_SIZE);

	/* Set address */
	dma_channel_set_source_address(&config_params,
			(uint16_t)(uintptr_t)&timer_overflow_counter);
	dma_channel_set_destination_address(&config_params,
			(uint16_t)(uintptr_t)dest_block_tc);

	/* Reset the channel */
	dma_channel_reset(DMA_CHANNEL_0);

	/* Write the config */
	dma_channel_write_config(DMA_CHANNEL_0, &config_params);

	/* Enable the channel */
	dma_channel_enable(DMA_CHANNEL_0);

	/* Wait for transfer to finish */
	while (!dma_has_completed) {
		/* Intentionally left empty */
	}

	/* Disable DMA */
	dma_disable();

	/* Verify that the result is as expected */
	success = block_compare(dest_block_tc,
			expected_result_tc, DEST_BLOCK_TC_SIZE);

	test_assert_true(test, success, "Result is not as expected");
}
コード例 #23
0
/**
 *
 * \brief Test double buffering mode
 *
 * \note This function tests the double buffering feature of the DMA
 * controller by configuring channel 0 and 1 to do the same copy,
 * and verify that the channels enable each other according to
 * the double buffering process.
 *
 * \param test   Current test case
 */
static void run_dma_double_buffering_test(const struct test_case *test)
{
	struct dma_channel_config config_params;
	bool success = true; /* Assume everything goes well */

	/* Fill source block with pattern data */
	set_buffer(memory_block_src, 0x00);
	block_fill(memory_block_src, MEMORY_BLOCK_SIZE);

	/* Null out the destination block */
	set_buffer(memory_block_dest, 0x00);

	/* Null out the config params */
	memset(&config_params, 0, sizeof(config_params));

	/* Enable DMA */
	dma_enable();

	/* Enable double buffering mode on channel 0 and 1 */
	dma_set_double_buffer_mode(DMA_DBUFMODE_CH01_gc);

	/* Set channel 1 to copy from memory_block_src to memory_block_dest */
	dma_channel_set_src_reload_mode(&config_params,
			DMA_CH_SRCRELOAD_NONE_gc);
	dma_channel_set_src_dir_mode(&config_params,
			DMA_CH_SRCDIR_INC_gc);
	dma_channel_set_dest_reload_mode(&config_params,
			DMA_CH_DESTRELOAD_NONE_gc);
	dma_channel_set_dest_dir_mode(&config_params,
			DMA_CH_DESTDIR_INC_gc);
	dma_channel_set_burst_length(&config_params,
			DMA_CH_BURSTLEN_1BYTE_gc);
	dma_channel_set_transfer_count(&config_params,
			MEMORY_BLOCK_SIZE);
	dma_channel_set_source_address(&config_params,
			(uint16_t)(uintptr_t)memory_block_src);
	dma_channel_set_destination_address(&config_params,
			(uint16_t)(uintptr_t)memory_block_dest);
	dma_channel_set_repeats(&config_params,
			DOUBLE_BUFFER_REPEATS);

	/* Write config and enable */
	dma_channel_write_config(DMA_CHANNEL_0, &config_params);
	dma_channel_write_config(DMA_CHANNEL_1, &config_params);

	/* Enable only channel 0 */
	dma_channel_enable(DMA_CHANNEL_0);

	/* Transfer block and wait for it to finish */
	dma_channel_trigger_block_transfer(DMA_CHANNEL_0);

	while (dma_get_channel_status(DMA_CHANNEL_0) !=
			DMA_CH_TRANSFER_COMPLETED) {
		/* Intentionally left empty */
	}

	/*
	 * If double buffering is working, channel 1
	 * will be enabled now by the controller
	 */
	if (!(dma_channel_is_enabled(DMA_CHANNEL_1))) {
		success = false;
	}

	/*
	 * Disable channel 0, transfer channel 1,
	 * and verify that channel 0 is enabled again by the controller
	 */
	dma_channel_disable(DMA_CHANNEL_0);

	/* Transfer block and wait for it to finish */
	dma_channel_trigger_block_transfer(DMA_CHANNEL_1);

	while (dma_get_channel_status(DMA_CHANNEL_1) !=
			DMA_CH_TRANSFER_COMPLETED) {
		/* Intentionally left empty */
	}

	/* Verify that channel 0 is enabled again */
	if (!(dma_channel_is_enabled(DMA_CHANNEL_0))) {
		success = false;
	}

	test_assert_true(test, success,
			"Double buffering mode did not function properly");
}
コード例 #24
0
void rcar_dma_init(void)
{
	dma_enable();
	dma_setup();
}
コード例 #25
0
ファイル: sysentry.c プロジェクト: koujinogaku/helloos
int syscall_dma_enable( unsigned int channel, unsigned int sw )
{
  return dma_enable( channel, sw );
}