예제 #1
0
파일: main.c 프로젝트: Arcko/trochili
/**
    \brief      configure the DMA peripheral
    \param[in]  none
    \param[out] none
    \retval     none
  */
void dma_config(void)
{
    dma_parameter_struct dma_init_struct;

    /* enable DMA clock */
    rcu_periph_clock_enable(RCU_DMA);

    /* initialize DMA channel4 */
    dma_deinit(DMA_CH4);

    /* DMA channel4 initialize */
    dma_deinit(DMA_CH4);
    dma_init_struct.direction    = DMA_MEMORY_TO_PERIPHERA;
    dma_init_struct.memory_addr  = (uint32_t)buffer;
    dma_init_struct.memory_inc   = DMA_MEMORY_INCREASE_ENABLE;
    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_16BIT;
    dma_init_struct.number       = 8;
    dma_init_struct.periph_addr  = (uint32_t)TIMER0_DMATB;
    dma_init_struct.periph_inc   = DMA_PERIPH_INCREASE_DISABLE;
    dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_16BIT;
    dma_init_struct.priority     = DMA_PRIORITY_HIGH;
    dma_init(DMA_CH4,dma_init_struct);

    /* configure DMA mode */
    dma_circulation_enable(DMA_CH4);
    dma_memory_to_memory_disable(DMA_CH4);

    /* enable DMA channel4 */
    dma_channel_enable(DMA_CH4);
}
예제 #2
0
mp_uint_t sdcard_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks) {
    // check that src pointer is aligned on a 4-byte boundary
    if (((uint32_t)src & 3) != 0) {
        return SD_ERROR;
    }

    // check that SD card is initialised
    if (sd_handle.Instance == NULL) {
        return SD_ERROR;
    }

    HAL_SD_ErrorTypedef err = SD_OK;

    if (query_irq() == IRQ_STATE_ENABLED) {
        dma_init(&sd_tx_dma, DMA_STREAM_SDIO_TX, &dma_init_struct_sdio,
            DMA_CHANNEL_SDIO_TX, DMA_MEMORY_TO_PERIPH, &sd_handle);
        sd_handle.hdmatx = &sd_tx_dma;

        err = HAL_SD_WriteBlocks_BlockNumber_DMA(&sd_handle, (uint32_t*)src, block_num, SDCARD_BLOCK_SIZE, num_blocks);
        if (err == SD_OK) {
            // wait for DMA transfer to finish, with a large timeout
            err = HAL_SD_CheckWriteOperation(&sd_handle, 100000000);
        }
        dma_deinit(sd_handle.hdmatx);
        sd_handle.hdmatx = NULL;
    } else {
        err = HAL_SD_WriteBlocks_BlockNumber(&sd_handle, (uint32_t*)src, block_num, SDCARD_BLOCK_SIZE, num_blocks);
    }

    return err;
}
예제 #3
0
mp_uint_t sdcard_read_blocks(uint8_t *buff, uint32_t sector, uint32_t count)
{
    HAL_SD_ErrorTypedef err;

    // If buffer is unaligned or located in CCM don't use DMA.
    if (CCM_BUFFER(buff) || UNALIGNED_BUFFER(buff)) {
        if (UNALIGNED_BUFFER(buff)) {
            printf("unaligned read buf:%p  count%lu \n", buff, count);
        }
        // This transfer has to be done in an atomic section. 
        mp_uint_t atomic_state = MICROPY_BEGIN_ATOMIC_SECTION();
        err = HAL_SD_ReadBlocks(&SDHandle, (uint32_t*)buff,
                sector * SDCARD_BLOCK_SIZE, SDCARD_BLOCK_SIZE, count);
        MICROPY_END_ATOMIC_SECTION(atomic_state);
    } else {
        // Disable USB IRQ to prevent FatFS/MSC contention
        HAL_NVIC_DisableIRQ(OTG_FS_IRQn); __DSB(); __ISB();

        dma_init(SDIO_TXRX_STREAM, SDIO_TXRX_CHANNEL, DMA_PERIPH_TO_MEMORY);

        err = HAL_SD_ReadBlocks_DMA(&SDHandle, (uint32_t*)buff,
                sector * SDCARD_BLOCK_SIZE, SDCARD_BLOCK_SIZE, count);

        if (err == SD_OK) {
            err = HAL_SD_CheckReadOperation(&SDHandle, SDIO_TIMEOUT);
        }

        if (err != SD_OK) {
            printf("read buf:%p  addr:%lu count%lu error:%d\n", buff, sector, count, err);
        }
        dma_deinit();
        HAL_NVIC_EnableIRQ(OTG_FS_IRQn);
    }
    return (err != SD_OK);
}
예제 #4
0
mp_uint_t sdcard_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks) {
    // check that SD card is initialised
    if (sd_handle.Instance == NULL) {
        return SD_ERROR;
    }

    HAL_SD_ErrorTypedef err = SD_OK;

    // check that dest pointer is aligned on a 4-byte boundary
    uint8_t *orig_dest = NULL;
    uint32_t saved_word;
    if (((uint32_t)dest & 3) != 0) {
        // Pointer is not aligned so it needs fixing.
        // We could allocate a temporary block of RAM (as sdcard_write_blocks
        // does) but instead we are going to use the dest buffer inplace.  We
        // are going to align the pointer, save the initial word at the aligned
        // location, read into the aligned memory, move the memory back to the
        // unaligned location, then restore the initial bytes at the aligned
        // location.  We should have no trouble doing this as those initial
        // bytes at the aligned location should be able to be changed for the
        // duration of this function call.
        orig_dest = dest;
        dest = (uint8_t*)((uint32_t)dest & ~3);
        saved_word = *(uint32_t*)dest;
    }

    if (query_irq() == IRQ_STATE_ENABLED) {
        // we must disable USB irqs to prevent MSC contention with SD card
        uint32_t basepri = raise_irq_pri(IRQ_PRI_OTG_FS);

        dma_init(&sd_rx_dma, &SDMMC_RX_DMA, &sd_handle);
        sd_handle.hdmarx = &sd_rx_dma;

        // make sure cache is flushed and invalidated so when DMA updates the RAM
        // from reading the peripheral the CPU then reads the new data
        MP_HAL_CLEANINVALIDATE_DCACHE(dest, num_blocks * SDCARD_BLOCK_SIZE);

        err = HAL_SD_ReadBlocks_BlockNumber_DMA(&sd_handle, (uint32_t*)dest, block_num, SDCARD_BLOCK_SIZE, num_blocks);
        if (err == SD_OK) {
            // wait for DMA transfer to finish, with a large timeout
            err = HAL_SD_CheckReadOperation(&sd_handle, 100000000);
        }

        dma_deinit(&SDMMC_RX_DMA);
        sd_handle.hdmarx = NULL;

        restore_irq_pri(basepri);
    } else {
        err = HAL_SD_ReadBlocks_BlockNumber(&sd_handle, (uint32_t*)dest, block_num, SDCARD_BLOCK_SIZE, num_blocks);
    }

    if (orig_dest != NULL) {
        // move the read data to the non-aligned position, and restore the initial bytes
        memmove(orig_dest, dest, num_blocks * SDCARD_BLOCK_SIZE);
        memcpy(dest, &saved_word, orig_dest - dest);
    }

    return err;
}
예제 #5
0
mp_uint_t sdcard_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks) {
    // check that SD card is initialised
    if (sd_handle.Instance == NULL) {
        return HAL_ERROR;
    }

    HAL_StatusTypeDef err = HAL_OK;

    // check that src pointer is aligned on a 4-byte boundary
    if (((uint32_t)src & 3) != 0) {
        // pointer is not aligned, so allocate a temporary block to do the write
        uint8_t *src_aligned = m_new_maybe(uint8_t, SDCARD_BLOCK_SIZE);
        if (src_aligned == NULL) {
            return HAL_ERROR;
        }
        for (size_t i = 0; i < num_blocks; ++i) {
            memcpy(src_aligned, src + i * SDCARD_BLOCK_SIZE, SDCARD_BLOCK_SIZE);
            err = sdcard_write_blocks(src_aligned, block_num + i, 1);
            if (err != HAL_OK) {
                break;
            }
        }
        m_del(uint8_t, src_aligned, SDCARD_BLOCK_SIZE);
        return err;
    }

    if (query_irq() == IRQ_STATE_ENABLED) {
        // we must disable USB irqs to prevent MSC contention with SD card
        uint32_t basepri = raise_irq_pri(IRQ_PRI_OTG_FS);

        #if SDIO_USE_GPDMA
        dma_init(&sd_tx_dma, &SDMMC_TX_DMA, &sd_handle);
        sd_handle.hdmatx = &sd_tx_dma;
        #endif

        // make sure cache is flushed to RAM so the DMA can read the correct data
        MP_HAL_CLEAN_DCACHE(src, num_blocks * SDCARD_BLOCK_SIZE);

        err = HAL_SD_WriteBlocks_DMA(&sd_handle, (uint8_t*)src, block_num, num_blocks);
        if (err == HAL_OK) {
            err = sdcard_wait_finished(&sd_handle, 60000);
        }

        #if SDIO_USE_GPDMA
        dma_deinit(&SDMMC_TX_DMA);
        sd_handle.hdmatx = NULL;
        #endif

        restore_irq_pri(basepri);
    } else {
        err = HAL_SD_WriteBlocks(&sd_handle, (uint8_t*)src, block_num, num_blocks, 60000);
        if (err == HAL_OK) {
            err = sdcard_wait_finished(&sd_handle, 60000);
        }
    }

    return err;
}
예제 #6
0
// Called from the SysTick handler
// We use LSB of tick to select which controller to process
void dma_idle_handler(uint32_t tick) {
    int controller = tick & 1;
    if (controller != 0) {
        return;
    }
	if (dma_idle.bmChnEn[controller] == 0) {
		if (++dma_idle.counter[controller] > 200) {
			dma_deinit(controller, 0);	// use a dummy channel index
		}
	}
}
예제 #7
0
mp_uint_t sdcard_write_blocks(const uint8_t *src, uint32_t block_num, uint32_t num_blocks) {
    // check that SD card is initialised
    if (sd_handle.Instance == NULL) {
        return SD_ERROR;
    }

    HAL_SD_ErrorTypedef err = SD_OK;

    // check that src pointer is aligned on a 4-byte boundary
    if (((uint32_t)src & 3) != 0) {
        // pointer is not aligned, so allocate a temporary block to do the write
        uint8_t *src_aligned = m_new_maybe(uint8_t, SDCARD_BLOCK_SIZE);
        if (src_aligned == NULL) {
            return SD_ERROR;
        }
        for (size_t i = 0; i < num_blocks; ++i) {
            memcpy(src_aligned, src + i * SDCARD_BLOCK_SIZE, SDCARD_BLOCK_SIZE);
            err = sdcard_write_blocks(src_aligned, block_num + i, 1);
            if (err != SD_OK) {
                break;
            }
        }
        m_del(uint8_t, src_aligned, SDCARD_BLOCK_SIZE);
        return err;
    }

    if (query_irq() == IRQ_STATE_ENABLED) {
        // we must disable USB irqs to prevent MSC contention with SD card
        uint32_t basepri = raise_irq_pri(IRQ_PRI_OTG_FS);

        dma_init(&sd_tx_dma, &dma_SDIO_0_TX, &sd_handle);
        sd_handle.hdmatx = &sd_tx_dma;

        err = HAL_SD_WriteBlocks_BlockNumber_DMA(&sd_handle, (uint32_t*)src, block_num, SDCARD_BLOCK_SIZE, num_blocks);
        if (err == SD_OK) {
            // wait for DMA transfer to finish, with a large timeout
            err = HAL_SD_CheckWriteOperation(&sd_handle, 100000000);
        }
        dma_deinit(&dma_SDIO_0_TX);
        sd_handle.hdmatx = NULL;

        restore_irq_pri(basepri);
    } else {
        err = HAL_SD_WriteBlocks_BlockNumber(&sd_handle, (uint32_t*)src, block_num, SDCARD_BLOCK_SIZE, num_blocks);
    }

    return err;
}
예제 #8
0
mp_uint_t sdcard_read_blocks(uint8_t *dest, uint32_t block_num, uint32_t num_blocks) {
    // check that dest pointer is aligned on a 4-byte boundary
    if (((uint32_t)dest & 3) != 0) {
        return SD_ERROR;
    }

    // check that SD card is initialised
    if (sd_handle.Instance == NULL) {
        return SD_ERROR;
    }

    HAL_SD_ErrorTypedef err = SD_OK;

    if (query_irq() == IRQ_STATE_ENABLED) {
        // we must disable USB irqs to prevent MSC contention with SD card
        uint32_t basepri = raise_irq_pri(IRQ_PRI_OTG_FS);

        dma_init(&sd_rx_dma, DMA_STREAM_SDIO_RX, &dma_init_struct_sdio,
            DMA_CHANNEL_SDIO_RX, DMA_PERIPH_TO_MEMORY, &sd_handle);
        sd_handle.hdmarx = &sd_rx_dma;

        err = HAL_SD_ReadBlocks_BlockNumber_DMA(&sd_handle, (uint32_t*)dest, block_num, SDCARD_BLOCK_SIZE, num_blocks);
        if (err == SD_OK) {
            // wait for DMA transfer to finish, with a large timeout
            err = HAL_SD_CheckReadOperation(&sd_handle, 100000000);
        }

        dma_deinit(sd_handle.hdmarx);
        sd_handle.hdmarx = NULL;

        restore_irq_pri(basepri);
    } else {
        err = HAL_SD_ReadBlocks_BlockNumber(&sd_handle, (uint32_t*)dest, block_num, SDCARD_BLOCK_SIZE, num_blocks);
    }

    return err;
}
예제 #9
0
int gmac_mac_init(struct eth_device *dev)
{
	struct eth_info *eth = (struct eth_info *)(dev->priv);
	struct eth_dma *dma = &(eth->dma);

	uint32_t tmp;
	uint32_t cmdcfg;
	int chipid;

	debug("%s enter\n", __func__);

	/* Always use GMAC0 */
	printf("Using GMAC%d\n", 0);

	/* Reset AMAC0 core */
	writel(0, AMAC0_IDM_RESET_ADDR);
	tmp = readl(AMAC0_IO_CTRL_DIRECT_ADDR);
	/* Set clock */
	tmp &= ~(1 << AMAC0_IO_CTRL_CLK_250_SEL_SHIFT);
	tmp |= (1 << AMAC0_IO_CTRL_GMII_MODE_SHIFT);
	/* Set Tx clock */
	tmp &= ~(1 << AMAC0_IO_CTRL_DEST_SYNC_MODE_EN_SHIFT);
	writel(tmp, AMAC0_IO_CTRL_DIRECT_ADDR);

	/* reset gmac */
	/*
	 * As AMAC is just reset, NO need?
	 * set eth_data into loopback mode to ensure no rx traffic
	 * gmac_loopback(eth_data, TRUE);
	 * ET_TRACE(("%s gmac loopback\n", __func__));
	 * udelay(1);
	 */

	cmdcfg = readl(UNIMAC0_CMD_CFG_ADDR);
	cmdcfg &= ~(CC_TE | CC_RE | CC_RPI | CC_TAI | CC_HD | CC_ML |
		    CC_CFE | CC_RL | CC_RED | CC_PE | CC_TPI |
		    CC_PAD_EN | CC_PF);
	cmdcfg |= (CC_PROM | CC_NLC | CC_CFE);
	/* put mac in reset */
	gmac_init_reset();
	writel(cmdcfg, UNIMAC0_CMD_CFG_ADDR);
	gmac_clear_reset();

	/* enable clear MIB on read */
	reg32_set_bits(GMAC0_DEV_CTRL_ADDR, DC_MROR);
	/* PHY: set smi_master to drive mdc_clk */
	reg32_set_bits(GMAC0_PHY_CTRL_ADDR, PC_MTE);

	/* clear persistent sw intstatus */
	writel(0, GMAC0_INT_STATUS_ADDR);

	if (dma_init(dma) < 0) {
		pr_err("%s: GMAC dma_init failed\n", __func__);
		goto err_exit;
	}

	chipid = CHIPID;
	printf("%s: Chip ID: 0x%x\n", __func__, chipid);

	/* set switch bypass mode */
	tmp = readl(SWITCH_GLOBAL_CONFIG_ADDR);
	tmp |= (1 << CDRU_SWITCH_BYPASS_SWITCH_SHIFT);

	/* Switch mode */
	/* tmp &= ~(1 << CDRU_SWITCH_BYPASS_SWITCH_SHIFT); */

	writel(tmp, SWITCH_GLOBAL_CONFIG_ADDR);

	tmp = readl(CRMU_CHIP_IO_PAD_CONTROL_ADDR);
	tmp &= ~(1 << CDRU_IOMUX_FORCE_PAD_IN_SHIFT);
	writel(tmp, CRMU_CHIP_IO_PAD_CONTROL_ADDR);

	/* Set MDIO to internal GPHY */
	tmp = readl(GMAC_MII_CTRL_ADDR);
	/* Select internal MDC/MDIO bus*/
	tmp &= ~(1 << GMAC_MII_CTRL_BYP_SHIFT);
	/* select MDC/MDIO connecting to on-chip internal PHYs */
	tmp &= ~(1 << GMAC_MII_CTRL_EXT_SHIFT);
	/*
	 * give bit[6:0](MDCDIV) with required divisor to set
	 * the MDC clock frequency, 66MHZ/0x1A=2.5MHZ
	 */
	tmp |= 0x1A;

	writel(tmp, GMAC_MII_CTRL_ADDR);

	if (gmac_mii_busywait(1000)) {
		pr_err("%s: Configure MDIO: MII/MDIO busy\n", __func__);
		goto err_exit;
	}

	/* Configure GMAC0 */
	/* enable one rx interrupt per received frame */
	writel(1 << GMAC0_IRL_FRAMECOUNT_SHIFT, GMAC0_INTR_RECV_LAZY_ADDR);

	/* read command config reg */
	cmdcfg = readl(UNIMAC0_CMD_CFG_ADDR);
	/* enable 802.3x tx flow control (honor received PAUSE frames) */
	cmdcfg &= ~CC_RPI;
	/* enable promiscuous mode */
	cmdcfg |= CC_PROM;
	/* Disable loopback mode */
	cmdcfg &= ~CC_ML;
	/* set the speed */
	cmdcfg &= ~(CC_ES_MASK | CC_HD);
	/* Set to 1Gbps and full duplex by default */
	cmdcfg |= (2 << CC_ES_SHIFT);

	/* put mac in reset */
	gmac_init_reset();
	/* write register */
	writel(cmdcfg, UNIMAC0_CMD_CFG_ADDR);
	/* bring mac out of reset */
	gmac_clear_reset();

	/* set max frame lengths; account for possible vlan tag */
	writel(PKTSIZE + 32, UNIMAC0_FRM_LENGTH_ADDR);

	return 0;

err_exit:
	dma_deinit(dma);
	return -1;
}
예제 #10
0
파일: main.c 프로젝트: Arcko/trochili
/*!
    \brief      main function
    \param[in]  none
    \param[out] none
    \retval     none
*/
int main(void)
{
    int i = 0;
    dma_parameter_struct dma_init_struct;
    /* enable DMA clock */
    rcu_periph_clock_enable(RCU_DMA);
    /* initialize LED */
    led_config();
    /* all LED off */
    gd_eval_ledoff(LED1);
    gd_eval_ledoff(LED3);
    gd_eval_ledoff(LED2);
    gd_eval_ledoff(LED4);
    /* initialize DMA channel1 */
    dma_deinit(DMA_CH1);
    dma_init_struct.direction = DMA_PERIPHERA_TO_MEMORY;
    dma_init_struct.memory_addr = (uint32_t)destination_address1;
    dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
    dma_init_struct.memory_width = DMA_MEMORY_WIDTH_8BIT;
    dma_init_struct.number = DATANUM;
    dma_init_struct.periph_addr = (uint32_t)source_address;
    dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_ENABLE;
    dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_8BIT;
    dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
    dma_init(DMA_CH1,dma_init_struct);
    /* configure DMA mode */
    dma_circulation_disable(DMA_CH1);
    dma_memory_to_memory_enable(DMA_CH1);
        
    /* initialize DMA channel2 */
    dma_deinit(DMA_CH2);
    dma_init_struct.memory_addr = (uint32_t)destination_address2;
    dma_init(DMA_CH2,dma_init_struct);
    /* configure DMA mode */
    dma_circulation_disable(DMA_CH2);
    dma_memory_to_memory_enable(DMA_CH2);
        
    /* initialize DMA channel3 */
    dma_deinit(DMA_CH3);
    dma_init_struct.memory_addr = (uint32_t)destination_address3;
    dma_init(DMA_CH3,dma_init_struct);
    /* configure DMA mode */
    dma_circulation_disable(DMA_CH3);
    dma_memory_to_memory_enable(DMA_CH3);
        
    /* initialize DMA channel4 */
    dma_deinit(DMA_CH4);
    dma_init_struct.memory_addr = (uint32_t)destination_address4;
    dma_init(DMA_CH4,dma_init_struct);
    /* configure DMA mode */
    dma_circulation_disable(DMA_CH4);
    dma_memory_to_memory_enable(DMA_CH4);

    /* enable DMA channel1~channel4 */
    dma_channel_enable(DMA_CH1);
    dma_channel_enable(DMA_CH2);
    dma_channel_enable(DMA_CH3);
    dma_channel_enable(DMA_CH4);

    /* wait for DMA transfer complete */
    for(i = 0; i < 200; i++);
    /* compare the data of source_address with data of destination_address */
    transferflag1 = memory_compare(source_address, destination_address1, DATANUM);
    transferflag2 = memory_compare(source_address, destination_address2, DATANUM);
    transferflag3 = memory_compare(source_address, destination_address3, DATANUM);
    transferflag4 = memory_compare(source_address, destination_address4, DATANUM);

    /* if DMA channel1 transfer success,light LED1 */
    if(SUCCESS == transferflag1){
        gd_eval_ledon(LED1);
    }
    /* if DMA channel2 transfer success,light LED2 */
    if(SUCCESS == transferflag2){
        gd_eval_ledon(LED2);
    }
    /* if DMA channel3 transfer success,light LED3 */
    if(SUCCESS == transferflag3){
        gd_eval_ledon(LED3);
    }
    /* if DMA channel4 transfer success,light LED4 */
    if(SUCCESS == transferflag4){
        gd_eval_ledon(LED4);
    }
    
    while (1);
}