⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dma.c

📁 windows ce 6.0 camera driver
💻 C
📖 第 1 页 / 共 2 页
字号:

    frame->list->tail = frame;
}

static frame_t *frame_take()
{
    frame_t *frame;

    frame = current_frame_list->head;

    if (frame == NULL)
        return NULL;

    /* to keep DMA running
    * the last frame should not be removed
    */
    if (frame->next == NULL)
        return NULL;
	
    frame_clean_cache(frame);
    if (frame_check_mark(frame))
        return NULL;

    current_frame_list->head = frame->next;

    return frame;
}

static frame_t* alloc_frame(frame_list_t *list)
{
    frame_t *frame;

    frame = malloc(sizeof(frame_t));
    
    if (frame == NULL)
        return FALSE;

    memset(frame, 0, sizeof(frame_t));

    frame->list = list;

    if (!frame_alloc_dma_buf(frame))
            goto err_alloc_frame;

    return frame;

err_alloc_frame:
    free_frame(frame);
    return NULL;
}

static void free_frame(frame_t* frame)
{
    frame_free_dma_buf(frame);
    free(frame);
}

static void free_frame_list(frame_list_t* list)
{
    frame_t* i;
    frame_t* next;
    for (i = list->head; i; i = next)
    {
        next = i->next;
        free_frame(i);
    }
}

#define N_STILL_FRAMES 1
#define N_VIDEO_FRAMES 4

static BOOL alloc_frame_list(frame_list_t *list)
{
    int i;
    int n;

    if (list->format.is_still)
        n = N_STILL_FRAMES;
    else
        n = N_VIDEO_FRAMES;

    for (i = 0; i < n; i++)
    {
        frame_t* tmp = alloc_frame(list);
        if (!tmp)
        {
            free_frame_list(list);
            return FALSE;
        }

        frame_append(tmp);
    }

    return TRUE;
}

#define MAX_FRAM_LIST 20
frame_list_t frame_list_tbl[MAX_FRAM_LIST];
UINT32 n_frame_list = 0;

BOOL QCIDMAPrepareFormat(format_t* format)
{
    frame_list_t *list = find_frame_list(format);

    if (list)
        return TRUE;
    
    memset(&frame_list_tbl[n_frame_list], 0, sizeof(frame_list_t));

    memcpy(&frame_list_tbl[n_frame_list].format, format, sizeof(*format));

    alloc_frame_list(&frame_list_tbl[n_frame_list]);
    if (frame_list_tbl[n_frame_list].head != NULL)
    {
        if (!video_frame_tail && !format->is_still)
            video_frame_tail = frame_list_tbl[n_frame_list].tail;

        n_frame_list++;
        return TRUE;
    }

    memset(&frame_list_tbl[n_frame_list], 0, sizeof(frame_list_t));
    return FALSE;
}

static frame_list_t* find_frame_list(format_t* format)
{
    UINT32 i;

    for (i = 0; i < n_frame_list; i++)
    {
        frame_list_t* list = &frame_list_tbl[i];

        if (!list->head)
            continue;

        if (memcmp(&list->format, format, sizeof(format_t)) == 0)
            return list;
    }

    return NULL;
}

BOOL QCIDMASetFrameFormat(format_t* format)
{
    current_frame_list = find_frame_list(format);    
    return current_frame_list != NULL;
}
void DMALoad()

{
    int i;
    frame_t* f;

    if (!current_frame_list)
        return;

    if (!current_frame_list->head)
        return;

    for (f = current_frame_list->head; f; f = f->next)
    {
        frame_mark(f);
        frame_clean_cache(f);
    }

    for (i = 0; i < 3; i++)
        PXA_CIDMALoadDescriptor(g_pCIRegs,
                                current_frame_list->head->plane[i].desc_buf.phy_addr,
                                PXA_CI_DMA_CHANNEL_0 + i);
                                
}

#ifdef DEBUG

static void dump_dma_chain(plane_t *plane)
{
    UINT32 i;
    PXA_CI_DMAC_DESCRIPTOR_T *descs;
    UINT32 descs_n;

    descs = (PXA_CI_DMAC_DESCRIPTOR_T*)plane->desc_buf.buf;
    descs_n = plane->desc_buf.size / sizeof(*descs);

    for (i = 0; i < descs_n; i++)
    {
        DEBUGMSG(ZONE_IOCTL,(L"CAM: %d ddadr 0x%08x, dsadr 0x%08x, dtadr 0x%08x, dcmd 0x%08x\r\n",
            i, descs[i].ddadr, descs[i].dsadr, descs[i].dtadr, descs[i].dcmd));                
    }
}

static void dump_frame(frame_t *frame)
{
    int i;
    
    short *buf;
    DEBUGMSG(ZONE_IOCTL,(L"CAM: Dumping frame 0x%08x\r\n",frame));
    

    if (!frame)
        return;

    for (i = 0; i < 3; i++)
    {
        DEBUGMSG(ZONE_IOCTL,(L"CAM: descriptor 0x%08x, phyiscal address 0x%08x\r\n",
            frame->plane[i].desc_buf.buf,
            frame->plane[i].desc_buf.phy_addr));        
        dump_dma_chain(&frame->plane[i]);
    }

    for (i = 0; i < 10; i++)        
        DEBUGMSG(ZONE_IOCTL,(L"0x%02x ",frame->plane[0].buf.buf[i]));
            
    DEBUGMSG(ZONE_IOCTL,(L"CAM: dumping frame mark\r\n"));
    buf = (short*)get_mark_ptr(frame);

    for (i = 0; i < 4; i++)
        DEBUGMSG(ZONE_IOCTL,(L"CAM: 0x%04x \r\n",buf[i]));
        
}

void dump_frame_list(frame_list_t *frame_list)
{
    frame_t *i;
    DEBUGMSG(ZONE_IOCTL,(L"CAM: format %d\r\n", frame_list->format.format));
    DEBUGMSG(ZONE_IOCTL,(L"CAM: width %d\r\n", frame_list->format.width));
    DEBUGMSG(ZONE_IOCTL,(L"CAM: height %d\r\n", frame_list->format.height));
    DEBUGMSG(ZONE_IOCTL,(L"CAM: head 0x%08x\r\n", frame_list->head));
    DEBUGMSG(ZONE_IOCTL,(L"CAM: tail 0x%08x\r\n", frame_list->tail));
    
    for (i = frame_list->head; i; i = i->next)
        dump_frame(i);
}

#endif



DWORD WINAPI QciIntrThread()
{
    int prio = 0;
#define MAX_READY_FRAME 10
    frame_t *frames[MAX_READY_FRAME];
    int n = 0;
    int i;

    prio = CeGetThreadPriority(GetCurrentThread());

    while(1) 
    {
        int status;
        //void qci_dump_regs();
        format_t* format;

        status = WaitForSingleObject(qci_intr_event, INFINITE);
        DEBUGMSG( ZONE_IOCTL, ( _T("CAM: Receive a complete frame!\r\n")));
        if (status == WAIT_FAILED)           
            ERRORMSG(1, ( _T("CAM: QciIntrThread: WAIT_FAILED!!!\r\n")));
        
        if (current_frame_list == NULL)
        {            
            ERRORMSG(1,    ( _T("CAM: Error no DMA frames!!!\r\n")));
            continue;
        }

        format = &current_frame_list->format;
        if (format->is_still)
        {

            #if 0
            if (still_skips)
            {
                DEBUGMSG( ZONE_IOCTL, ( _T("CAM: Still capture shoule skip %d frames!\r\n"),still_skips));
                still_skips--;
            } else
            #endif
            {         
                DEBUGMSG( ZONE_IOCTL, ( _T("CAM: Receive a still frame!\r\n")));
                QciCallBack(current_frame_list->head);
            }
            PXA_CIClearInterruptStatus(g_pCIRegs, 0xFFFFFFFF);
            InterruptDone(qci_sys_intr);
            continue;
        }

        n = 0;
        while (1) 
        {
            frames[n] = frame_take();

            if (!frames[n])
                break;
            n++;
            if (n >= MAX_READY_FRAME)
                break;
        }
    
        if ((n>0)&&(frames[n-1]))//queue the last frame to callback function
            QciCallBack(frames[n-1]);
    
        for (i = 0; i < n; i++)
        {
            //QciCallBack(frames[i]);
            frame_append(frames[i]);
        }
        PXA_CIClearInterruptStatus(g_pCIRegs, 0xFFFFFFFF);
        InterruptDone(qci_sys_intr);
    }


    return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -