/** * \brief DMAC driver configuration. */ static void configure_dmac(void) { /* Initialize and enable DMA controller. */ pmc_enable_periph_clk(ID_DMAC); dmac_init(DMAC); dmac_set_priority_mode(DMAC, DMAC_PRIORITY_ROUND_ROBIN); dmac_enable(DMAC); /* Enable receive channel interrupt for DMAC. */ NVIC_EnableIRQ(DMAC_IRQn); dmac_enable_interrupt(DMAC, (1 << BOARD_USART_DMAC_RX_CH)); }
/* * Configure the SPI hardware, including SPI clock speed, mode, delays, chip select pins * It uses values listed in */ void AJ_WSL_SPI_InitializeSPIController(void) { uint32_t config; /* Initialize and enable DMA controller. */ pmc_enable_periph_clk(ID_DMAC); dmac_init(DMAC); dmac_set_priority_mode(DMAC, DMAC_PRIORITY_ROUND_ROBIN); dmac_enable(DMAC); /* Configure DMA TX channel. */ config = 0; config |= DMAC_CFG_DST_PER(AJ_SPI_TX_INDEX) | DMAC_CFG_DST_H2SEL | DMAC_CFG_SOD | DMAC_CFG_FIFOCFG_ALAP_CFG; dmac_channel_set_configuration(DMAC, AJ_DMA_TX_CHANNEL, config); /* Configure DMA RX channel. */ config = 0; config |= DMAC_CFG_SRC_PER(AJ_SPI_RX_INDEX) | DMAC_CFG_SRC_H2SEL | DMAC_CFG_SOD | DMAC_CFG_FIFOCFG_ALAP_CFG; dmac_channel_set_configuration(DMAC, AJ_DMA_RX_CHANNEL, config); /* Enable receive channel interrupt for DMAC. */ uint8_t* interruptEnableAddress = AJ_SPI_ISER1_IEN_ADDR; *interruptEnableAddress = AJ_SPI_DMAC_IEN_BIT; dmac_enable_interrupt(DMAC, (1 << AJ_DMA_RX_CHANNEL)); dmac_enable_interrupt(DMAC, (1 << AJ_DMA_TX_CHANNEL)); //AJ_WSL_DMA_Setup(); dmac_channel_disable(DMAC, AJ_DMA_TX_CHANNEL); dmac_channel_disable(DMAC, AJ_DMA_RX_CHANNEL); /* * Configure the hardware to enable SPI and some output pins */ { pmc_enable_periph_clk(ID_PIOA); pmc_enable_periph_clk(ID_PIOB); pmc_enable_periph_clk(ID_PIOC); pmc_enable_periph_clk(ID_PIOD); // make all of these pins controlled by the right I/O controller pio_configure_pin_group(PIOA, 0xFFFFFFFF, PIO_TYPE_PIO_PERIPH_A); pio_configure_pin_group(PIOB, 0xFFFFFFFF, PIO_TYPE_PIO_PERIPH_B); pio_configure_pin_group(PIOC, 0xFFFFFFFF, PIO_TYPE_PIO_PERIPH_C); pio_configure_pin_group(PIOD, 0xFFFFFFFF, PIO_TYPE_PIO_PERIPH_D); /* * Reset the device by toggling the CHIP_POWER */ ioport_set_pin_dir(AJ_WSL_SPI_CHIP_POWER_PIN, IOPORT_DIR_OUTPUT); ioport_set_pin_level(AJ_WSL_SPI_CHIP_POWER_PIN, IOPORT_PIN_LEVEL_LOW); AJ_Sleep(10); ioport_set_pin_level(AJ_WSL_SPI_CHIP_POWER_PIN, IOPORT_PIN_LEVEL_HIGH); /* * Reset the device by toggling the CHIP_PWD# signal */ ioport_set_pin_dir(AJ_WSL_SPI_CHIP_PWD_PIN, IOPORT_DIR_OUTPUT); ioport_set_pin_level(AJ_WSL_SPI_CHIP_PWD_PIN, IOPORT_PIN_LEVEL_LOW); AJ_Sleep(10); ioport_set_pin_level(AJ_WSL_SPI_CHIP_PWD_PIN, IOPORT_PIN_LEVEL_HIGH); /* configure the pin that detects SPI data ready from the target chip */ ioport_set_pin_dir(AJ_WSL_SPI_CHIP_SPI_INT_PIN, IOPORT_DIR_INPUT); ioport_set_pin_sense_mode(AJ_WSL_SPI_CHIP_SPI_INT_PIN, IOPORT_SENSE_LEVEL_LOW); pio_handler_set(PIOC, ID_PIOC, AJ_WSL_SPI_CHIP_SPI_INT_BIT, (PIO_PULLUP | PIO_IT_FALL_EDGE), &AJ_WSL_SPI_CHIP_SPI_ISR); pio_handler_set_priority(PIOD, (IRQn_Type) ID_PIOC, 0xB); pio_enable_interrupt(PIOC, AJ_WSL_SPI_CHIP_SPI_INT_BIT); } spi_enable_clock(AJ_WSL_SPI_DEVICE); spi_reset(AJ_WSL_SPI_DEVICE); spi_set_lastxfer(AJ_WSL_SPI_DEVICE); spi_set_master_mode(AJ_WSL_SPI_DEVICE); spi_disable_mode_fault_detect(AJ_WSL_SPI_DEVICE); spi_set_peripheral_chip_select_value(AJ_WSL_SPI_DEVICE, AJ_WSL_SPI_DEVICE_NPCS); spi_set_clock_polarity(AJ_WSL_SPI_DEVICE, AJ_WSL_SPI_DEVICE_NPCS, AJ_WSL_SPI_CLOCK_POLARITY); spi_set_clock_phase(AJ_WSL_SPI_DEVICE, AJ_WSL_SPI_DEVICE_NPCS, AJ_WSL_SPI_CLOCK_PHASE); spi_set_bits_per_transfer(AJ_WSL_SPI_DEVICE, AJ_WSL_SPI_DEVICE_NPCS, SPI_CSR_BITS_8_BIT); spi_set_baudrate_div(AJ_WSL_SPI_DEVICE, AJ_WSL_SPI_DEVICE_NPCS, (sysclk_get_cpu_hz() / AJ_WSL_SPI_CLOCK_RATE)); spi_set_transfer_delay(AJ_WSL_SPI_DEVICE, AJ_WSL_SPI_DEVICE_NPCS, AJ_WSL_SPI_DELAY_BEFORE_CLOCK, AJ_WSL_SPI_DELAY_BETWEEN_TRANSFERS); spi_set_fixed_peripheral_select(AJ_WSL_SPI_DEVICE); spi_configure_cs_behavior(AJ_WSL_SPI_DEVICE, AJ_WSL_SPI_DEVICE_NPCS, SPI_CS_RISE_FORCED); spi_enable_interrupt(AJ_WSL_SPI_DEVICE, SPI_IER_TDRE | SPI_IER_RDRF); spi_enable(AJ_WSL_SPI_DEVICE); }
/** * \brief Test DMA multiple buffer transfer with interrupt mode. */ static void test_multi_buf_xfer(void) { uint32_t i; uint32_t cfg; dma_transfer_descriptor_t desc[3]; printf("\n\rTest multiple buffer transfer...\n\r"); /* Initialize DMA buffer */ for (i = 0; i < DMA_BUF_SIZE; i++) { g_dma_buf[0][i] = i; g_dma_buf[1][i] = i + 10; g_dma_buf[2][i] = i + 20; g_dma_buf[3][i] = 0; g_dma_buf[4][i] = 0; g_dma_buf[5][i] = 0; } /* Initialize and enable DMA controller */ pmc_enable_periph_clk(ID_DMAC); dmac_init(DMAC); dmac_set_priority_mode(DMAC, DMAC_PRIORITY_ROUND_ROBIN); dmac_enable(DMAC); /* Set for channel configuration register */ cfg = DMAC_CFG_SOD_DISABLE | /* Disable stop on done */ DMAC_CFG_AHB_PROT(1) | /* Set AHB Protection */ DMAC_CFG_FIFOCFG_ALAP_CFG; /* FIFO Configuration */ dmac_channel_set_configuration(DMAC, 0, cfg); /* Initialize multiple buffer transfer (LLI) : * buffer 0 -> buffer 3 * buffer 1 -> buffer 4 * buffer 2 -> buffer 5 */ desc[0].ul_source_addr = (uint32_t) g_dma_buf[0]; desc[0].ul_destination_addr = (uint32_t) g_dma_buf[3]; /* * Set DMA CTRLA: * - Set Buffer Transfer Size * - Source transfer size is set to 32-bit width * - Destination transfer size is set to 32-bit width */ desc[0].ul_ctrlA = DMAC_CTRLA_BTSIZE(DMA_BUF_SIZE) | DMAC_CTRLA_SRC_WIDTH_WORD | DMAC_CTRLA_DST_WIDTH_WORD; /* * Set DMA CTRLB: * - Descriptor is fetched from the memory * - Descriptor is fetched from the memory * - Memory-to-Memory Transfer * - The source address is incremented * - The destination address is incremented */ desc[0].ul_ctrlB = DMAC_CTRLB_SRC_DSCR_FETCH_FROM_MEM | DMAC_CTRLB_DST_DSCR_FETCH_FROM_MEM | DMAC_CTRLB_FC_MEM2MEM_DMA_FC | DMAC_CTRLB_SRC_INCR_INCREMENTING | DMAC_CTRLB_DST_INCR_INCREMENTING; /* Pointer to next descriptor */ desc[0].ul_descriptor_addr = (uint32_t) &desc[1]; desc[1].ul_source_addr = (uint32_t) g_dma_buf[1]; desc[1].ul_destination_addr = (uint32_t) g_dma_buf[4]; /* * Set DMA CTRLA: * - Set Buffer Transfer Size * - Source transfer size is set to 32-bit width * - Destination transfer size is set to 32-bit width */ desc[1].ul_ctrlA = DMAC_CTRLA_BTSIZE(DMA_BUF_SIZE) | DMAC_CTRLA_SRC_WIDTH_WORD | DMAC_CTRLA_DST_WIDTH_WORD; /* * Set DMA CTRLB: * - Source descriptor is fetched from the memory * - Destination descriptor is fetched from the memory * - Memory-to-Memory Transfer * - The source address is incremented * - The destination address is incremented */ desc[1].ul_ctrlB = DMAC_CTRLB_SRC_DSCR_FETCH_FROM_MEM | DMAC_CTRLB_DST_DSCR_FETCH_FROM_MEM | DMAC_CTRLB_FC_MEM2MEM_DMA_FC | DMAC_CTRLB_SRC_INCR_INCREMENTING | DMAC_CTRLB_DST_INCR_INCREMENTING; /* Pointer to next descriptor */ desc[1].ul_descriptor_addr = (uint32_t) &desc[2]; desc[2].ul_source_addr = (uint32_t) g_dma_buf[2]; desc[2].ul_destination_addr = (uint32_t) g_dma_buf[5]; /* * Set Buffer Transfer Size * Source transfer size is set to 32-bit width * Destination transfer size is set to 32-bit width */ desc[2].ul_ctrlA = DMAC_CTRLA_BTSIZE(DMA_BUF_SIZE) | DMAC_CTRLA_SRC_WIDTH_WORD | DMAC_CTRLA_DST_WIDTH_WORD; /* * Set DMA CTRLB: * - Source descriptor is fetched from the memory * - Destination descriptor is fetched from the memory * - Memory-to-Memory Transfer * - The source address is incremented * - The destination address is incremented */ desc[2].ul_ctrlB = DMAC_CTRLB_SRC_DSCR_FETCH_FROM_MEM | DMAC_CTRLB_DST_DSCR_FETCH_FROM_MEM | DMAC_CTRLB_FC_MEM2MEM_DMA_FC | DMAC_CTRLB_SRC_INCR_INCREMENTING | DMAC_CTRLB_DST_INCR_INCREMENTING; /* The end of LLI */ desc[2].ul_descriptor_addr = 0; dmac_channel_multi_buf_transfer_init(DMAC, DMA_CH, &desc[0]); /* Set interrupt */ NVIC_EnableIRQ(DMAC_IRQn); dmac_enable_interrupt(DMAC, (DMAC_EBCIER_CBTC0 << DMA_CH)); /* Start DMA transfer and wait for finish */ g_xfer_done = 0; dmac_channel_enable(DMAC, DMA_CH); while (!g_xfer_done) { } /* Verify the transferred data */ for (i = 0; i < DMA_BUF_SIZE; i++) { if ((g_dma_buf[0][i] != g_dma_buf[3][i]) || (g_dma_buf[1][i] != g_dma_buf[4][i]) || (g_dma_buf[2][i] != g_dma_buf[5][i])) { printf("> Test NG.\n\r"); while (1) { } } } printf("> Test OK.\n\r"); }