新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 2440/2410上將usb device改成usb host

        2440/2410上將usb device改成usb host

        作者: 時間:2016-11-09 來源:網絡 收藏
        之前的開發,要在2440上使用兩個usb host口,一個接攝像頭,一個接無線網卡。但友善之臂mini2440板子只有一個usb host口,曾想通過外接一個usb hub來解決,無線網卡接hub沒有問題,但是攝像頭插到hub上總是有錯誤:

        usb 1-1: reset full speed USB device using s3c2410-ohci and address 3
        usb 1-1.2: new full speed USB device using s3c2410-ohci and address 4
        usb 1-1.2: device descriptor read/64, error -62
        usb 1-1.2: device descriptor read/64, error -62
        usb 1-1.2: new full speed USB device using s3c2410-ohci and address 5
        usb 1-1.2: device descriptor read/64, error -62
        usb 1-1.2: device descriptor read/64, error -62
        usb 1-1.2: new full speed USB device using s3c2410-ohci and address 6
        usb 1-1.2: device not accepting address 6, error -62
        usb 1-1.2: new full speed USB device using s3c2410-ohci and address 7
        usb 1-1.2: device not accepting address 7, error -62
        hub 1-1:1.0: unable to enumerate USB device on port 2

        本文引用地址:http://www.104case.com/article/201611/317619.htm

        本來想試著修改內核中關于hub.c和ohci-s3c2410中的代碼,看看能不能好使,但后來在PC機上的hub下使用攝像頭也不好使,看來是我使用的zc301攝像頭對hub不支持吧。(估計一般的攝像頭都對hub不支持,我又試了另一款也是這樣的)。

        所以放棄了在usb hub上使用攝像頭的想法。記得以前看過關于s3c2410的手冊,它應該是支持2個usb host通道的啊,2440應該也是如此。所以仔細看了下s3c2440的手冊,發現第二個usb hos通道的管腳和usb device的管腳是復用的。所以感覺將usb device改成host應該是可行的,深入研究研究。(好像一些板子已經設計出來可以跳線選擇,友善之臂的沒這么設計)

        要將usb device改成host,不只是硬件上需要改動,軟件驅動上肯定也需要改動,所以分為硬件和軟件兩個部分。

        硬件上:仔細看了mini2440的手冊中的關于usb電路圖,其實硬件電路上host和device沒什么本質區別,一些外拉電阻不一樣,VBUS的提供者不一樣。將device改成host感覺外拉電阻不一樣應該也不會影響使用,所以就沒有改變,避免在板子上做手腳。其它的就是要給VBUS一個5v的電源,而不是像device一樣電腦供電了。其它的就沒什么改動了。自己動手做了一個usb host口。

        軟件上:本質就是對寄存器MISCCR的設置改變一下,為了以后改動方便,我參考了網上的一些《關于陽初2440 超值版只能使用一個 USB Host 問題的解決》的方法。以下主要參照了一些關于這個方法的帖子博客之類的。(轉載一些)

        第一篇:

        修改linux-2.6.20.3/drivers/usb/host/Kconfig,添加:

        config MAX_ROOT_PORTS

        int "Maximum port(s) of RootHub"

        depends on USB_OHCI_HCD && ARCH_S3C2410

        default 1

        ---help---

        pls select usb host number,default one host and one device.so We select one normally

        修改/linux-2.6.20.3/drivers/usb/host/ohci-s3c2410.c

        static int usb_hcd_s3c2410_probe (const struct hc_driver *driver,

        struct platform_device *dev)

        {

        struct usb_hcd *hcd = NULL;

        int retval;

        //add by hiboy

        unsigned long tmp;

        #if CONFIG_MAX_ROOT_PORTS < 2

        /* 1 host port, 1 slave port*/

        tmp = __raw_readl(S3C2410_MISCCR);

        tmp &= ~S3C2410_MISCCR_USBHOST;

        __raw_writel(tmp, S3C2410_MISCCR);

        s3c2410_usb_set_power(dev->dev.platform_data, 1, 1);

        #else

        /* 2 host port */

        tmp = __raw_readl(S3C2410_MISCCR);

        tmp |= S3C2410_MISCCR_USBHOST;

        __raw_writel(tmp, S3C2410_MISCCR);

        s3c2410_usb_set_power(dev->dev.platform_data, 1, 1);

        s3c2410_usb_set_power(dev->dev.platform_data, 2, 1);

        #endif

        //s3c2410_usb_set_power(dev->dev.platform_data, 1, 1);

        //s3c2410_usb_set_power(dev->dev.platform_data, 2, 1);

        ......

        修改/linux-2.6.20.3/drivers/usb/core/hub.c

        static int hub_configure(struct usb_hub *hub,

        struct usb_endpoint_descriptor *endpoint)

        {

        struct usb_device *hdev = hub->hdev;

        struct device *hub_dev = hub->intfdev;

        u16 hubstatus, hubchange;

        u16 wHubCharacteristics;

        unsigned int pipe;

        int maxp, ret;

        char *message;

        hub->buffer = usb_buffer_alloc(hdev, sizeof(*hub->buffer), GFP_KERNEL,

        &hub->buffer_dma);

        if (!hub->buffer) {

        message = "cant allocate hub irq buffer";

        ret = -ENOMEM;

        goto fail;

        }

        hub->status = kmalloc(sizeof(*hub->status), GFP_KERNEL);

        if (!hub->status) {

        message = "cant kmalloc hub status buffer";

        ret = -ENOMEM;

        goto fail;

        }

        mutex_init(&hub->status_mutex);

        hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL);

        if (!hub->descriptor) {

        message = "cant kmalloc hub descriptor";

        ret = -ENOMEM;

        goto fail;

        }

        /* Request the entire hub descriptor.

        * hub->descriptor can handle USB_MAXCHILDREN ports,

        * but the hub can/will return fewer bytes here.

        */

        ret = get_hub_descriptor(hdev, hub->descriptor,

        sizeof(*hub->descriptor));

        if (ret < 0) {

        message = "cant read hub descriptor";

        goto fail;

        } else if (hub->descriptor->bNbrPorts > USB_MAXCHILDREN) {

        message = "hub has too many ports!";

        ret = -ENODEV;

        goto fail;

        }

        /********************************************/

        /*add by hiboy */

        #ifdef CONFIG_ARCH_S3C2410

        if ((hdev->devnum == 1) // Root Hub

        && hub->descriptor->bNbrPorts > CONFIG_MAX_ROOT_PORTS) {

        int j;

        for (j=hub->descriptor->bNbrPorts-1; j>=0; j--) {

        printk("port #%d ", j);

        if (j > CONFIG_MAX_ROOT_PORTS-1) {

        printk("suspened!n");

        } else {

        printk("alived!n");

        }

        }

        hub->descriptor->bNbrPorts = CONFIG_MAX_ROOT_PORTS;

        }

        #endif

        /*********************************************/

        第二篇:

        是由于MISCCR寄存器沒有正確設置的緣故,我在mach-2410.c中增加了設置MISCCR寄存器的內容,HOST0就可以正常使用了

        /*add by seigpao*/

        int usb_seigpao_init(void)

        {

        unsigned long upllvalue;

        unsigned long misccr;

        //設置UPLLCON

        upllvalue = (0x78<<12)|(0x02<<4)|(0x03);

        __raw_writel(upllvalue,S3C2410_UPLLCON);

        //設置MISCCR

        misccr = __raw_readl(S3C2410_MISCCR);

        misccr |= S3C2410_MISCCR_USBHOST;

        misccr &= ~(S3C2410_MISCCR_USBSUSPND0 | S3C2410_MISCCR_USBSUSPND1);

        __raw_writel(misccr,S3C2410_MISCCR);

        return 1;

        }

        /* end by seigpao */

        static void __init smdk2410_map_io(void)

        {

        s3c24xx_init_io(smdk2410_iodesc, ARRAY_SIZE(smdk2410_iodesc));

        s3c24xx_init_clocks(0);

        s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));

        s3c24xx_set_board(&smdk2410_board);

        /*add by seigpao*/

        //設置2410觸摸屏

        set_s3c2410ts_info(&sbc2410_ts_cfg);

        //設置USB相關寄存器

        usb_seigpao_init();

        /* end by seigpao */

        }

        不知道為什么會有第二篇,感覺不適合,所以又重網上找了另一篇文章。

        修改ohci-s3c2440.c文件(含頭文件):


        #include


        #include


        #include

        /*add here*/


        #include


        #include


        #include

        #include


        /*end here*/

        #define valid_port(idx) ((idx) == 1 || (idx) == 2)


        /*add here*/


        static void s3c2410_start_hc(struct platform_device *dev, struct usb_hcd *hcd)


        {


        unsigned long upllvalue = (0x78<<12)|(0x02<<4)|(0x03); //add upllvalue


        unsigned long misccr; //add misccr


        struct s3c2410_hcd_info *info = dev->dev.platform_data;


        while (upllvalue != __raw_readl(S3C2410_UPLLCON)) //setup UPLLCON


        {


        __raw_writel(upllvalue, S3C2410_UPLLCON);


        mdelay(1);

        }

        misccr = __raw_readl(S3C2410_MISCCR); //MISCCR


        misccr |= S3C2410_MISCCR_USBHOST;


        misccr&=~(S3C2410_MISCCR_USBSUSPND0|S3C2410_MISCCR_USBSUSPND1);


        __raw_writel(misccr,S3C2410_MISCCR);

        dev_dbg(&dev->dev, "s3c2410_start_hc:n");


        clk_enable(clk);

        if (info != NULL) {


        info->hcd = hcd;


        info->report_oc = s3c2410_hcd_oc;

        if (info->enable_oc != NULL) {


        (info->enable_oc)(info, 1);

        }


        }


        }

        使用了這篇文章的改動。頭文件位置可能根據內核不同做相應改動。我的2.6.29內核中的regs-clock.h和regs-gpio.h是在archarmmach-s3c2410includemach中。我拷貝兩個頭文件到本地drivers/usb/host/,include 變成""。

        然后make zImage,之后Kconfig會重新選擇,

        USB support (USB_SUPPORT) [Y/n/?] y

        Support for Host-side USB (USB) [Y/n/m/?] y

        USB verbose debug messages (USB_DEBUG) [N/y/?] n

        USB announce new devices (USB_ANNOUNCE_NEW_DEVICES) [Y/n/?] y

        *

        * Miscellaneous USB options

        *

        USB device filesystem (USB_DEVICEFS) [Y/n/?] y

        USB device class-devices (DEPRECATED) (USB_DEVICE_CLASS) [N/y/?] n

        Dynamic USB minor allocation (USB_DYNAMIC_MINORS) [N/y/?] n

        USB Monitor (USB_MON) [N/m/y/?] n

        Enable Wireless USB extensions (EXPERIMENTAL) (USB_WUSB) [N/m/y/?] n

        Support WUSB Cable Based Association (CBA) (USB_WUSB_CBAF) [N/m/y/?] n

        *

        * USB Host Controller Drivers

        *

        Cypress C67x00 HCD support (USB_C67X00_HCD) [N/m/y/?] n

        OXU210HP HCD support (USB_OXU210HP_HCD) [N/m/y/?] n

        ISP116X HCD support (USB_ISP116X_HCD) [N/m/y/?] n

        OHCI HCD support (USB_OHCI_HCD) [Y/n/m/?] y

        SL811HS HCD support (USB_SL811_HCD) [N/m/y/?] n

        R8A66597 HCD support (USB_R8A66597_HCD) [N/m/y/?] n

        Host Wire Adapter (HWA) driver (EXPERIMENTAL) (USB_HWA_HCD) [N/m/y/?] n

        Maximum port(s) of RootHub (MAX_ROOT_PORTS) [2] (NEW)

        最后一項選的時候選成2就行了,因為config MAX_ROOT_PORTS為2代表使用兩個host。

        燒寫生成的內核,結果大失所望,啟動后在自己焊出的usb host口上插上設備沒反應。不過郁悶重啟之時,發現先在這之上插上設備啟動時,設備就能識別出來了。而且插入無線網卡可以配置使用。不過使用攝像頭確出現錯誤:

        gspca: ISOC data error: [1] len=318, status=-84

        gspca: ISOC data error: [4] len=274, status=-84

        gspca: ISOC data error: [25] len=144, status=-84

        gspca: ISOC data error: [1] len=240, status=-84

        等等。這是又回到對內核的改動上,當改動內核時就感覺帖子文章中第二篇沒什么用,跟第一篇有些重復之嫌,后來替代的在static void s3c2410_start_hc中的改動也是,感覺有些重復static int usb_hcd_s3c2410_probe中的內容,所以重新編譯內核,將對static void s3c2410_start_hc的改動去掉,即不改s3c2410_start_hc,重新編譯內核燒寫,結果使用攝像頭正常。

        也就是說,usb device已經改成了usb host,可以當成usb host使用了,只不過,必需先插入設備再啟動板子,分析這種情況的原因可能是因為bootloader中肯定有對usb部分的設置驅動之類的,(Nor Flash的時候可以使用usb device進行下載傳輸,說明肯定已經驅上了usb device),vivi的設置跟重新編譯的內核對usb設置不一樣,可能就導致了這種情況,我也不確定是不是這個原因。不插設備的時候啟動信息改的usb 1-2提示:

        usb 1-2: new full speed USB device using s3c2410-ohci and address 3

        usb 1-2: device descriptor read/64, error -62

        usb 1-2: device descriptor read/64, error -62

        usb 1-2: new full speed USB device using s3c2410-ohci and address 4

        usb 1-2: device descriptor read/64, error -62

        usb 1-2: device descriptor read/64, error -62

        usb 1-2: new full speed US. device using s3c2410-ohci and address 5

        usb 1-2: device not accepting addre髎 5, error -62

        usb 1-2: new full speed USB device using s3c2410-ohci and address 6

        usb 1-2: device not accepting address 6, error -62

        hub 1-0:1.0: unable to enumerate USB device on port 2

        但是,插上設備比如無線網卡,就能找到設備,提示:

        usb 1-2: new full speed USB device using s3c2410-o鑓i and address 3

        usb 1-2: New USB device found, idVen鋙r=0ace, idProduct=1215

        usb 1-2: New USB device strings: Mfr=16, Product=32, SerialNumber=0

        usb 1-2: Product: USB2.0 WLAN

        usb 1-2: Manufacturer: ZyDAS

        usb 1-2: configuration #1 chosen from 1 choice

        usb 1-2: reset full speed USB device using s3c2410-ohci and address 3

        wmaster0 (zd1211rw): not using net_device_ops yet

        wlan0 (zd1211rw): not using net_device_ops yet

        zd1211rw 1-2:1.0: phy0

        對于這種情況,上網搜了一下,好像修改vivi中的upll設置,在main中添加了ChangeUPllValue(56,2,2)一句后,問題可以解決。具體沒有再試,先如此的用著吧。
        我是在友善之臂的mini2440上實現的,基于2410與2440沒有本質差別,2410上應該也可以。



        關鍵詞: 24402410usbdevicehos

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 德惠市| 德江县| 潮州市| 乡城县| 高邑县| 新和县| 海南省| 修武县| 孝义市| 大埔县| 唐海县| 牙克石市| 全南县| 绥江县| 温宿县| 酉阳| 望都县| 平泉县| 河西区| 文安县| 夏河县| 台中市| 潼关县| 丰都县| 三亚市| 独山县| 义乌市| 杭锦旗| 务川| 舞阳县| 黑山县| 区。| 北票市| 丹东市| 比如县| 崇明县| 平果县| 察哈| 乌拉特中旗| 米泉市| 宜黄县|