s32 bsp_edma_channel_lli_start (u32 channel_id)
{
    if(bsp_edma_channel_lli_async_start( channel_id ))
        return ERROR;
    while(!bsp_edma_channel_is_idle(channel_id)){
        (void)osl_task_delay(1);
    }
    return OK;
}
Пример #2
0
/*异步链式EDMA传输,上层模块注册中断处理程序,处理EDMA传输完成事件*/
s32 edmac_test_async_lli(enum edma_req_id req, u32 direction)
{
    edma_addr_t  edma_addr    = 0;
    s32         ret_id       = 0;
    s32         ret          = 0;
    u32      i            = 0;
    struct edma_cb *pstNode   = NULL;
    struct edma_cb *psttemp   = NULL;
    struct edma_cb *FirstNode   = NULL;

    edma_buff_init();
    /*创建链表*/
    pstNode = (struct edma_cb *)dma_alloc_coherent(NULL,(EDMA_TEST_LLI_NUM * sizeof(struct edma_cb)),
                                                                   &edma_addr, GFP_DMA|__GFP_WAIT);
    s_edma_alloc_address.s_alloc_virt_address = (u32)pstNode;
	s_edma_alloc_address.s_alloc_phys_address = (u32)edma_addr;
    if (NULL == pstNode)
    {
        hiedmac_trace(BSP_LOG_LEVEL_ERROR,"LII list init is failed!");
        edma_buff_exit();
    	return EDMA_MEMORY_ALLOCATE_ERROR;
    }

    FirstNode = pstNode;
    psttemp = pstNode;
    for (i = 0; i < EDMA_TEST_LLI_NUM; i++)
    {
        psttemp->lli = EDMA_SET_LLI(edma_addr + (i+1) * sizeof(struct edma_cb), ((i < EDMA_TEST_LLI_NUM - 1)?0:1));
        psttemp->config = stDmaLLI[i].ulConfig;
        psttemp->src_addr = stDmaLLI[i].ulSourAddr;
        psttemp->des_addr = stDmaLLI[i].ulDestAddr;
        psttemp->cnt0 = stDmaLLI[i].ulLength;
        psttemp->bindx = 0;
        psttemp->cindx = 0;
        psttemp->cnt1  = 0;

        psttemp++;
    }
    hiedmac_trace(BSP_LOG_LEVEL_DEBUG,"LII list init is success!");

    /*申请通道,注册通道中断回调函数*/
    ret_id = bsp_edma_channel_init(req, (channel_isr)edma_isr_sema_give, 0, EDMA_INT_DONE);
	if (ret_id < 0)
    {
        hiedmac_trace(BSP_LOG_LEVEL_ERROR,"---------ERROR ret_id = 0x%X\n\n",ret_id);
        return EDMA_CHANNEL_INVALID;
    }

    /*获取首节点寄存器地址*/
    psttemp = bsp_edma_channel_get_lli_addr((u32)ret_id);
    if (NULL == psttemp)
    {
        hiedmac_trace(BSP_LOG_LEVEL_ERROR,"---bsp_edma_channel_get_lli_addr FAILED !\n\n");
        bsp_edma_channel_free((u32)ret_id);
        return EDMA_CHANNEL_INVALID;
    }

    /*配置首节点寄存器*/
    psttemp->lli = FirstNode->lli;
    psttemp->config = FirstNode->config & 0xFFFFFFFE;
    psttemp->src_addr = FirstNode->src_addr;  /*物理地址*/
    psttemp->des_addr = FirstNode->des_addr;  /*物理地址*/
    psttemp->cnt0 = FirstNode->cnt0;
    psttemp->bindx = 0;
    psttemp->cindx = 0;
    psttemp->cnt1  = 0;
    /* * */
    cacheClear( DATA_CACHE, (void*)edma_buf_phys, (EDMA_TEST_LLI_NUM + 2) * EDMA_TEST_LLI_BLOCK_SIZE );

    /*启动EDMA传输后即返回,可通过查询通道是否busy来确定传输是否完成*/
    if (bsp_edma_channel_lli_async_start((u32)ret_id))
    {
        hiedmac_trace(BSP_LOG_LEVEL_ERROR,"bsp_edma_channel_lli_async_start FAILED!\n\n");
        dma_free_coherent(NULL,(EDMA_TEST_LLI_NUM * sizeof(struct edma_cb)),
                          (void*)s_edma_alloc_address.s_alloc_virt_address, edma_addr);
        edma_buff_exit();
        bsp_edma_channel_free((u32)ret_id);
        return EDMA_TRXFER_ERROR;
    }
    while(0==bsp_edma_channel_is_idle((u32) ret_id))
    {printf("a");}
    printf("\n");

    /*mdelay(200);*/
    bsp_edma_channel_free((u32)ret_id);

    /* Verify the transfer data */
    for( i = 0; i < EDMA_TEST_LLI_NUM; i++ )
    {
        u8* temp_dest = pucDest + i * EDMA_TEST_LLI_BLOCK_SIZE;
		ret = edma_verify_data( temp_dest, EDMA_TEST_LLI_BLOCK_SIZE, (i & 0x1) ? 0x3a : 0x6 );
        if( !ret )
        {
            break;
        }
        hiedmac_trace(BSP_LOG_LEVEL_DEBUG,"\rFirst Verify, d[0]=0x%X, d[1]=0x%X, d[2]=0x%X, d[3]=0x%X, d[4]=0x%X, d[5]=0x%X\r\n ",
               *((u8 *)temp_dest + 0 ),
               *((u8 *)temp_dest + 1 ),
               *((u8 *)temp_dest + 2 ),
               *((u8 *)temp_dest + 3 ),
               *((u8 *)temp_dest + 4 ),
               *((u8 *)temp_dest + 5 ) );
    }

    dma_free_coherent(NULL,(EDMA_TEST_LLI_NUM * sizeof(struct edma_cb)),
                          (void*)s_edma_alloc_address.s_alloc_virt_address, edma_addr);
    edma_buff_exit();

    if (ret)
    {
        hiedmac_trace(BSP_LOG_LEVEL_ERROR,"bsp_edma_channel_lli_start FAILED!\n");
        return EDMA_TRXFER_ERROR;
    }
    hiedmac_trace(BSP_LOG_LEVEL_CRIT,"===============EDMA_LLI_ASYNC_START_SUCCESS!\n");
    return EDMA_SUCCESS;
}