OMAPL138 OTG实现HOST

OTG 2.0配置成主机特性如下
1.兼容USB2.0标准支持高速,全速,低速外围
2.支持4通道TX和RX端点,和一个控制端点
3.每个端点(除了控制端点0)支持的传输类型(控制,批量,中断,等时)
4.包含一个4K的端点FIFO RAM,支持可编程FIFO大小
5.当配置成主机时,能提供5V的VBUS
6.包含一个DMA控制器可以支持4个TX和4RXDMA通道
7.支持4种类型的DMA传输类型,CPPI4.1,Transparent, RNDIS, Linux CDC
DMA一次最大传输数据大小为4M

主机模式操作:
1.进入休眠模式
当POWER[SUSPENDM]被设置,控制器在将当前传输操作完成后,就进入休眠,若POWER[ENSUSPM]清零,PHY将进入低功耗模式
2.发送唤醒信号
手动清零POWER[SUSENDM]位,置位POWER[RESUME],将在20ms后中断休眠模式,控制器唤醒后,需要清零RESUME位
3.控制传输
1).SETUP Phase
host端操作
1. Load the 8 bytes of the required Device request command into the Endpoint 0 FIFO.
2. Set SETUPPKT and TXPKTRDY (bits 3 and 1 of HOST_CSR0, respectively).
3. At the end of the attempt to send the data, the controller will generate an Endpoint 0 interrupt. The
software should then read HOST_CSR0 to establish whether the RXSTALL bit (bit 2), the ERROR bit
(bit 4) or the NAK_TIMEOUT bit (bit 7) has been set.
4. If none of RXSTALL, ERROR or NAK_TIMEOUT is set, the SETUP Phase has been correctly ACKed
and the software should proceed to the following IN Data Phase, OUT Data Phase or IN Status Phasespecified for the particular Standard Device Request.

IN Data Phase
For the IN Data Phase of a control transaction (Figure 34-11), the software driving the USB host device
needs to:
1. Set REQPKT bit of HOST_CSR0 (bit 5).
2. Wait while the controller sends the IN token and receives the required data back.
3. When the controller generates the Endpoint 0 interrupt, read HOST_CSR0 to establish whether the
RXSTALL bit (bit 2), the ERROR bit (bit 4), the NAK_TIMEOUT bit (bit 7) or RXPKTRDY bit (bit 0) has
been set.
If RXSTALL is set, it indicates that the target has issued a STALL response.
If ERROR is set, it means that the controller has tried to send the required IN token three times without
getting any response.
If NAK_TIMEOUT bit is set, it means that the controller has received a NAK response to each attempt
to send the IN token, for longer than the time set in HOST_NAKLIMIT0. The controller can then be
directed either to continue trying this transaction (until it times out again) by clearing the
NAK_TIMEOUT bit or to abort the transaction by clearing REQPKT before clearing the NAK_TIMEOUT
bit.
4. If RXPKTRDY has been set, the software should read the data from the Endpoint 0 FIFO, then clear
RXPKTRDY.
5. If further data is expected, the software should repeat Steps 1-4.
When all the data has been successfully received, the CPU should proceed to the OUT Status Phase of
the Control Transaction.


OUT Data Phase
For the OUT Data Phase of a control transaction (Figure 34-12), the software driving the USB host device
needs to:
1. Load the data to be sent into the endpoint 0 FIFO.
2. Set the TXPKTRDY bit of HOST_CSR0 (bit 1). The controller then proceeds to send an OUT token
followed by the data from the FIFO to Endpoint 0 of the addressed device, retrying as necessary.
3. At the end of the attempt to send the data, the controller will generate an Endpoint 0 interrupt. The
software should then read HOST_CSR0 to establish whether the RXSTALL bit (bit 2), the ERROR bit
(bit 4) or the NAK_TIMEOUT bit (bit 7) has been set.
If RXSTALL bit is set, it indicates that the target has issued a STALL response.
If ERROR bit is set, it means that the controller has tried to send the OUT token and the following data
packet three times without getting any response.
If NAK_TIMEOUT is set, it means that the controller has received a NAK response to each attempt to
send the OUT token, for longer than the time set in the HOST_NAKLIMIT0 register. The controller can
then be directed either to continue trying this transaction (until it times out again) by clearing the
NAK_TIMEOUT bit or to abort the transaction by flushing the FIFO before clearing the NAK_TIMEOUT
bit.
If none of RXSTALL, ERROR or NAKLIMIT is set, the OUT data has been correctly ACKed.
4. If further data needs to be sent, the software should repeat Steps 1-3.
When all the data has been successfully sent, the software should proceed to the IN Status Phase of
the Control Transaction.

IN Status Phase (following SETUP Phase or OUT Data Phase)
For the IN Status Phase of a control transaction (Figure 34-13), the software driving the USB Host device
needs to:
1. Set the STATUSPKT and REQPKT bits of HOST_CSR0 (bit 6 and bit 5, respectively).
2. Wait while the controller sends an IN token and receives a response from the USB peripheral device.
3. When the controller generates the Endpoint 0 interrupt, read HOST_CSR0 to establish whether the
RXSTALL bit (bit 2), the ERROR bit (bit 4), the NAK_TIMEOUT bit (bit 7) or RXPKTRDY bit (bit 0) has
been set.
If RXSTALL bit is set, it indicates that the target could not complete the command and so has issued a
STALL response.
If ERROR bit is set, it means that the controller has tried to send the required IN token three times
without getting any response.
If NAK_TIMEOUT bit is set, it means that the controller has received a NAK response to each attempt
to send the IN token, for longer than the time set in the HOST_NAKLIMIT0 register. The controller can
then be directed either to continue trying this transaction (until it times out again) by clearing the
NAK_TIMEOUT bit or to abort the transaction by clearing REQPKT bit and STATUSPKT bit before
clearing the NAK_TIMEOUT bit.
4. If RxPktRdy has been set, the CPU should simply clear RxPktRdy.


OUT Status Phase (following IN Data Phase)
For the OUT Status Phase of a control transaction (Figure 34-14) , the CPU driving the host device needs
to:
1. Set STATUSPKT and TXPKTRDY bits of HOST_CSR0 (bit 6 and bit 1, respectively).
NOTE:
These bits need to be set together.
2. Wait while the controller sends the OUT token and a zero-length DATA1 packet.
3. At the end of the attempt to send the data, the controller will generate an Endpoint 0 interrupt. The
software should then read HOST_CSR0 to establish whether the RXSTALL bit (bit 2), the ERROR bit
(bit 4) or the NAK_TIMEOUT bit (bit 7) has been set.
If RXSTALL bit is set, it indicates that the target could not complete the command and so has issued a
STALL response.
If ERROR bit is set, it means that the controller has tried to send the STATUS Packet and the following
data packet three times without getting any response.
If NAK_TIMEOUT bit is set, it means that the controller has received a NAK response to each attempt
to send the IN token, for longer than the time set in the HOST_NAKLIMIT0 register. The controller can
then be directed either to continue trying this transaction (until it times out again) by clearing the
NAK_TIMEOUT bit or to abort the transaction by flushing the FIFO before clearing the NAK_TIMEOUT
bit.
4. If none of RXSTALL, ERROR or NAK_TIMEOUT bits is set, the STATUS Phase has been correctly
ACKed.




对于AM1808只将USB2.0(OTG)实现为HOST端
配置单:

Device Drivers --->
    USB support --->
        <*> Support for Host-side USB
        --- Miscellaneous USB options
        [*] USB device filesystem
        --- USB Host Controller Drivers
        <*> Inventra USB Highspeed Dual Role Controller Support
        --- DA830/OMAP-L137 USB support
        Driver Mode (USB Host) --->
            (X) USB Host
定义的配置:
CONFIG_USB_MUSB_HDRC
CONFIG_USB_MUSB_SOC
CONFIG_USB_MUSB_HOST
CONFIG_USB_MUSB_HDRC_HCD
CONFIG_USB_TI_CPPI41_DMA
CONFIG_USB_MUSB_DEBUG


分析流程:
实现host的代码大概在7000行左右。首先从musb/musb_core.c开始
fs_initcall(musb_init);

注册USB核心:
platform_driver_probe(&musb_driver, musb_probe);
static struct platform_driver musb_driver = {
        .driver = {
                .name           = (char *)musb_driver_name,
        //name = musb_hdrc  
                .bus            = &platform_bus_type,
                .owner          = THIS_MODULE,
                .pm             = MUSB_DEV_PM_OPS, //电源管理操作函数集
包括休眠和唤醒
        },
        .remove         = __devexit_p(musb_remove),//移除
        .shutdown       = musb_shutdown,
};

系统在初始化执行init进程,就会进行USB OTG的探测工作,由musb_probe实现
platform设备在linux2.6中用的很广泛,凡是和内核管理不是很大的设备都可也采用platform设备模型,比如USB,uart,i2c等

static int __init musb_probe(struct platform_device *pdev)
{
        struct device   *dev = &pdev->dev;
        int             irq = platform_get_irq(pdev, 0);
        struct resource *iomem;
        void __iomem    *base;

        iomem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!iomem || irq == 0)
                return -ENODEV;

        base = ioremap(iomem->start, iomem->end - iomem->start + 1);
        if (!base) {
                dev_err(dev, "ioremap failed\n");
                return -ENOMEM;
        }

#ifndef CONFIG_MUSB_PIO_ONLY
        /* clobbered by use_dma=n */
        orig_dma_mask = dev->dma_mask;
#endif
        return musb_init_controller(dev, irq, base);
}

platform设备模型
它是一个平台设备驱动程序,这是一种伪总线,通常用于集成进片上系统的轻量级设备和linux设备模型连接在一起。
注册流程,首先填充platform_device结构->platform_device_register->platform_driver结构填充->platform_driver_register
故在进行platform_driver_register之前必须注册platform_device,这步常在初始化平台中实现,当注册驱动后,会根据驱动与设备注册名字是否匹配,若有匹配进行probe动作,所以device和driver名字必须相同
在probe中需要的操作是获得platform_device的资源信息,比如IOMEM,IRQ等
接着
musb_init_controller(dev, irq, base);

这里初始化USB控制器,包括IO映射和中断申请和映射
/* allocate */
        musb = allocate_instance(dev, plat->config, ctrl);
/* 为具体的OTG初始化 ,这里是USB host 对应这里就是
#ifdef CONFIG_USB_MUSB_HDRC_HCD
        struct usb_hcd  *hcd;

        hcd = usb_create_hcd(&musb_hc_driver, dev, dev_name(dev));
        if (!hcd)
                return NULL;
        /* usbcore sets dev->driver_data to hcd, and sometimes uses that... */

        musb = hcd_to_musb(hcd);
        INIT_LIST_HEAD(&musb->control);
        INIT_LIST_HEAD(&musb->in_bulk);
        INIT_LIST_HEAD(&musb->out_bulk);

        hcd->uses_new_polling = 1;

        musb->vbuserr_retry = VBUSERR_RETRY_COUNT;
#else

    


        if (!musb)
                return -ENOMEM;
     spin_lock_init(&musb->lock);
        musb->board_mode = plat->mode;
        musb->board_set_power = plat->set_power;
        musb->set_clock = plat->set_clock;
        musb->min_power = plat->min_power;

        /* Clock usage is chip-specific ... functional clock (DaVinci,
         * OMAP2430), or PHY ref (some TUSB6010 boards).  All this core
         * code does is make sure a clock handle is available; platform
         * code manages it during start/stop and suspend/resume.
         */
        if (plat->clock) {
                musb->clock = clk_get(dev, plat->clock);
                if (IS_ERR(musb->clock)) {
                        status = PTR_ERR(musb->clock);
                        musb->clock = NULL;
                        goto fail;
                }
        }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值