基于OHCI的USB主机 —— 中断处理程序

简介:
OHCI 的体系下,判断数据是否传输完毕是需要通过中断程序来判断的,当 USB 主机设置了 HcControl HcCommandStatus 寄存器开始传输数据后, AM9200  自动开始数据传输,并且定期的检查 HcDoneHead 寄存器的内容,并且将其转移到 HCCA.DoneHead 。然后产生中断,触发中断处理程序。

 

在中断处理程序中,需要检查 HcInterruptStatus 寄存器的内容,判断 WDH 位是否为 1 ,以便确定是否有 TD 被处理完毕。一般来说,其余的中断状态位不用理会。当发现有 TD 被处理完毕,则还需要判断已经完成的 TD 是否是当前传输命令的最后一个 TD ,如果是则标志命令执行结束,上层程序可以进行后续处理。

 

/**

 * OHCI 中断处理程序

 */

void  AT91F_UHP_Handler( void )

{

     unsigned   int  status;

     unsigned   char  idx;

     unsigned   char  cc;

     //unsigned int control;

   

     // 得到 HcInterruptStatus 寄存器的内容

    status = ohciGetIntrStatus();

     // 检查 WDH 位,判断是否有 TD 传输完毕

     if  ((status & OHCI_HC_INTR_WDH) != 0)

    {

        // 根据当前执行的命令类型,确定 TD 的数量

        switch (usbCmdState. cmdType )

       {

        case  USB_CMD_TYPE_BULK_WRITE:

        case  USB_CMD_TYPE_BULK_READ:

           idx = 3;

            break ;

          

        case  USB_CMD_TYPE_CTRL_READ:

           idx = 2;

            break ;

          

        case  USB_CMD_TYPE_CTRL_WRITE:

           idx = 1;

            break ;

          

        default :

           usbCmdState. state  = USB_CMD_OVER;

           ohciClearIntrStatus();

            return  ;

       }

      

        // 取得当前完成的 TD Complete Code

       cc = getTdCC(ohciGetHccaDoneHead());

        // 判断当前完成的 TD 是否是命令的最后一个 TD

        if  (ohciGetHccaDoneHead() == usbGetLastTdAddr(idx))

       {

           usbCmdState. cmdResult  = cc;

           usbCmdState. state  = USB_CMD_OVER;

       }

        else

       {

            // 当前 TD 不是最后一个 TD ,但是执行失败,不会继续处理 TD 列表,因此需要返回

            if  (cc)

           {

              usbCmdState. cmdResult  = cc;

              usbCmdState. state  = USB_CMD_OVER;

           }

            else

               // 当前 TD 不是最后一个 TD ,等待继续处理

              usbCmdState. state ++;

       }

    }

     // 清除 HcInterruptStatus 寄存器的内容,以便能够产生新的中断

    ohciClearIntrStatus();

}

 

在最初的代码中,不是通过中断来判断 TD 数据是否处理完毕的,而是直接调用 ohciGetIntrStatus() 函数并判断返回值的,但是实际调试时发现这样不能正确得到 TD 数据处理完毕的信息。通过对中断程序的实际调试发现,因为 ED 会带有多个 TD AM9200 在处理的时候可能是处理速度的原因,会产生 1 个或多个中断,因此在中断处理程序中需要判断当前结束的 TD 是否是当前命令的最后一个 TD ,这样才能确保整个 ED 处理完毕。

 

说实话,我不认为上面的判断 ED 队列执行完毕的方法是好的方法,本来我一直以为会有一个寄存器,在 ED 队列处理完毕的时候会跳出来告诉我说队列执行完毕了,可是找了半天也没有找到,只好采用这个笨方法了。





本文转自 tywali 51CTO博客,原文链接:http://blog.51cto.com/lancelot/261181,如需转载请自行联系原作者
目录
相关文章
|
机器学习/深度学习 测试技术
强化学习让大模型自动纠错,数学、编程性能暴涨,DeepMind新作
【10月更文挑战第18天】Google DeepMind提出了一种基于强化学习的自动纠错方法SCoRe,通过自我修正提高大型语言模型(LLMs)的纠错能力。SCoRe在数学和编程任务中表现出色,分别在MATH和HumanEval基准测试中提升了15.6%和9.1%的自动纠错性能。
432 4
|
机器学习/深度学习 数据采集 自然语言处理
|
搜索推荐 物联网 PyTorch
Qwen2.5-7B-Instruct Lora 微调
本教程介绍如何基于Transformers和PEFT框架对Qwen2.5-7B-Instruct模型进行LoRA微调。
13954 34
Qwen2.5-7B-Instruct Lora 微调
|
机器学习/深度学习 人工智能 自然语言处理
三行代码实现实时语音转文本,支持自动断句和语音唤醒,用 RealtimeSTT 轻松创建高效语音 AI 助手
RealtimeSTT 是一款开源的实时语音转文本库,支持低延迟应用,具备语音活动检测、唤醒词激活等功能,适用于语音助手、实时字幕等场景。
3013 18
三行代码实现实时语音转文本,支持自动断句和语音唤醒,用 RealtimeSTT 轻松创建高效语音 AI 助手
|
存储 缓存 编解码
FFmpeg开发笔记(五):ffmpeg解码的基本流程详解(ffmpeg3新解码api)
FFmpeg开发笔记(五):ffmpeg解码的基本流程详解(ffmpeg3新解码api)
FFmpeg开发笔记(五):ffmpeg解码的基本流程详解(ffmpeg3新解码api)
|
缓存 安全 网络协议
Windows 安全基础——NetBIOS篇
Windows 安全基础——NetBIOS篇
654 4
|
安全 Android开发
【Android 逆向】Android 中常用的 so 动态库 ( libm.so 数学函数动态库 | liblog.so 日志模块动态库 | libselinux.so 安全模块动态库 )
【Android 逆向】Android 中常用的 so 动态库 ( libm.so 数学函数动态库 | liblog.so 日志模块动态库 | libselinux.so 安全模块动态库 )
1053 0
【Android 逆向】Android 中常用的 so 动态库 ( libm.so 数学函数动态库 | liblog.so 日志模块动态库 | libselinux.so 安全模块动态库 )
|
JSON 编解码 物联网
理解时间戳的视频理解大模型CogVLM2开源!视频生成、视频摘要等任务有力工具!
随着大型语言模型和多模态对齐技术的发展,视频理解模型在通用开放领域也取得了长足的进步。
|
Rust Unix Windows
使用Cargo国内镜像提升Rust开发效率
使用Cargo国内镜像提升Rust开发效率
3067 1

热门文章

最新文章

下一篇
开通oss服务