本帖最后由 Simon21ic 于 2014-6-2 19:05 编辑
OHCI开发要求:
1. 使用VSF构架,以及我定义的面向对象的C语言方式
2. 系统使用前后台+轮询机制,如果可以,尽量不使用中断
3. 构架上,分为vsfusbh和vsfohci,vsfusbh为USB主机类,对应实际硬件上的一个USB主机,提供URB接口给用户层代码和设备驱动层代码。
vsfohci提供了一个struct vsfusbh_hostdrv_t ohci_drv;这个是ohci的驱动,vsfusbh里需要设置实际的USB接口驱动,目前只需要支持OHCI。
随便列举一些结构定义,实际开发的时候,还需要完善:
URB结构:
struct vsfusbh_urb_t
{
struct vsfusbh_device_t *device;
uint8_t ep;
uint8_t dir;
void *param;
struct vsfusbh_ctrl_request_t request;
struct vsf_transaction_buffer_t tbuffer;
struct
{
// data_io is used to get/set data if tbuffer.buffer.buffer is NULL
vsf_err_t (*data_io)(struct vsfusbh_urb_t *urb);
void (*on_COMPLETE)(struct vsfusbh_urb_t *urb);
} callback;
bool completed;
vsf_err_t err;
struct sllist list;
};
USB主机接口驱动结构:
struct vsfusbh_hostdrv_t
{
vsf_err_t (*init)(void* hostdrv_param);
vsf_err_t (*fini)(void* hostdrv_param);
vsf_err_t (*suspend)(void* hostdrv_param);
vsf_err_t (*resume)(void* hostdrv_param);
vsf_err_t (*poll)(void* hostdrv_param);
vsf_err_t (*submit_urb)(void *hostdrv_param, struct vsfusbh_urb_t *urb);
};
USB主机类:
struct vsfusbh_t
{
void* hostdrv_param;
const struct vsfusbh_hostdrv_t *hostdrv;
// private
struct vsfusbh_class_driver_t *driver_list; // driver_list can share
struct vsfusbh_device_t *device_list;
uint8_t avail_address; // used to define the current usb device address
bool newdev;
};
vsf_err_t vsfusbh_init(struct vsfusbh_t *host);
vsf_err_t vsfusbh_fini(struct vsfusbh_t *host);
vsf_err_t vsfusbh_poll(struct vsfusbh_t *host);
vsf_err_t vsfusbh_usbmit_urb(struct vsfusbh_t *host, struct vsfusbh_urb_t *urb);
vsf_err_t vsfusbh_suspend(struct vsfusbh_t *host);
vsf_err_t vsfusbh_resume(struct vsfusbh_t *host);
void* vsfusbh_malloc(uint32_t size);
void vsfusbh_free(void *buffer);
vsf_err_t vsfohci_register_driver(struct vsfohci_driver_t **driver_list,
struct vsfohci_driver_t *driver);
vsf_err_t vsfohci_register_device(struct vsfusbh_t *host,
struct vsfohci_driver_t *driver);
OHCI的一些结构:
struct vsfohci_t
{
struct
{
uint32_t (*read_reg)(uint32_t offset);
void (*write_reg)(uint32_t offset, uint32_t value);
struct vsfohci_reg_t *reg_base;
} drv;
// hcca MUST be aligned to 256-byte boundary
struct vsfohci_hcca_t *hcca;
uint32_t revision;
// ED
struct vsohci_ed_t *ed_rm_list;
struct vsohci_ed_t *ed_bulktail;
struct vsohci_ed_t *ed_controltail;
struct vsohci_ed_t *ed_isotail;
};
一些示例代码:
static uin32_t vsfohci_read_reg(struct vsfohci_t *ohci, uint32_t reg)
{
if (ohci->drv.read_reg)
{
return ohci->drv.read_reg(reg);
}
else
{
return ohci->drv.reg_base[reg];
}
}
static void vsfohci_write_reg(struct vsfohci_t *ohci, uint32_t reg,
uint32_t value)
{
if (ohci->drv.write_reg)
{
ohci->drv.write_reg(reg);
}
else
{
ohci->drv.reg_base[reg] = value;
}
}
static vsf_err_t vsfohci_init(void *param)
{
struct vsfohci_t *ohci = (struct vsfohci_t *)param;
memset(ohci->hcca, 0, sizeof(struct vsfohci_hcca_t));
ohci->revision = vsfohci_read_reg(ohci, OHCI_REGIDX_HcRevision);
}
static vsf_err_t vsfohci_poll(void *param)
{
struct vsfohci_t *ohci = (struct vsfohci_t *)param;
uint32_t intf;
intf = vsfohci_read_reg(ohci, OHCI_REGIDX_HcInterruptStatus);
// When the HC reaches the end of a frame and its deferred interrupt
// register is 0, it writes the current value of its HcDoneHead to this
// location and generates an interrupt if interrupts are enabled. This
// location is not written by the HC again until software clears the WD
// bit in the HcInterruptStatus register.
// The LSb of this entry is set to 1 to indicate whether an unmasked
// HcInterruptStatus was set when HccaDoneHead was written.
if ((ohci->hcca->HccaDoneHead != 0) && !(ohci->hcca->HccaDoneHead & 1))
{
intf = OHCI_INTF_WDH;
}
}
当然,大部分东西都还没有完成。
我没有什么OHCI和USB主机接口的开发经验,这个只是更具这两天看的文档和代码做的东西。
希望多提一些建议。
|