application initialization tasks are also performed within
the firmware thread before passing control to the
application state machine. To make the code easier to
follow, the ProBee ZU10 driver application is divided into
sections called states. Each state performs a specific task.
As each state completes its task, the “ball” gets passed to
the next logical state. There are currently eight states in
our ProBee ZU10 driver application:
//***********************************************
//* STATES
//***********************************************
enum {
sENUM = 0,
sFIND_DEVICE,
//enumerate the ProBee ZU10
//get ProBee ZU10
//configuration parms
sATTACH_FT232, //logically attach the
//FT232RL host to the
//core host
//send initial AT commands
//receive from the ProBee
//ZU10
sTX_FT232, //send to the ProBee ZU10
sPROCESS_FT232, //process the received data
sERROR //error processing
sSETUP,
sRX_FT232,
};
If we can get the ProBee ZU10 to enumerate, we’re
on our way. Here’s the code that stands between us and
the ProBee ZU10’s USB enumeration:
//***********************************************
//* ENUMERATE STATE
//***********************************************
case sENUM:
//power up the ProBee ZU10
slavepwr(1);
do
{
//blink the LEDs and wait for
//enumeration to complete
vos_delay_msecs(250);
led(1,1);
vos_delay_msecs(250);
led(1,0);
// user ioctl to see if bus available
hc_iocb.ioctl_code = VOS_IOCTL_
USBHOST_GET_CONNECT_STATE;
hc_iocb.get = &portstat;
vos_dev_ioctl(hUSBHOST_2, &hc_iocb);
}while(portstat != PORT_STATE_ENUMERATED);
led(1,1);
LAST_STATE = sENUM;
CURRENT_STATE = sFIND_DEVICE;
break;
The enumeration code speaks for itself. The user-written (that’s us) slavepwr and led functions apply power
to the ProBee ZU10 and provide a visual indication as to
the success of the enumeration. Note the use of the
Device Manager handle/control block command
combination (vos_dev_ioctl(hUSBHOST_ 2, &hc_iocb) to
determine the USB port state. Once the ProBee ZU10 is
enumerated, application control is passed to the
sFIND_DEVICE state:
#define USB_VID_FTDI
//declared in USB.h
0x0403
#define USB_PID_FTDI_FT232
//declared in USB.h
0x6001
DESIGN CYCLE
//***********************************************
//* FIND DEVICE STATE
//***********************************************
case sFIND_DEVICE:
// find FTDI vendor device (ProBee ZU10)
hc_iocb_vendor.vid = USB_VID_FTDI;
hc_iocb_vendor.pid = USB_PID_FTDI_FT232;
// user ioctl to find first hub device
hc_iocb.ioctl_code = VOS_IOCTL_USBHOST_
DEVICE_FIND_HANDLE_BY_VID_PID;
hc_iocb.handle.dif = NULL;
hc_iocb.set = &hc_iocb_vendor;
hc_iocb.get = &ifDev;
if (vos_dev_ioctl(hUSBHOST_2, &hc_iocb)
!= USBHOST_OK)
{
LAST_STATE = sFIND_DEVICE;
CURRENT_STATE = sERROR;
break;
}
hc_iocb.ioctl_code = VOS_IOCTL_
USBHOST_DEVICE_GET_VID_PID;
hc_iocb.get = &hc_iocb_vendor;
vos_dev_ioctl(hUSBHOST_2, &hc_iocb);
myVID = hc_iocb_vendor.vid;
myPID = hc_iocb_vendor.pid;
led(2,1);
LAST_STATE = sFIND_DEVICE;
CURRENT_STATE = sATTACH_FT232;
break;
I mixed business with pleasure in the sFIND_DEVICE
state code. I instructed the Vinculum-II to attempt to find
the ProBee ZU10 on the Vinco’s Type A USB interface
using the FTDI standard VID and PID values listed in
USB.h. If the ProBee ZU10 was found to be mounted in
the Type A USB portal, I added some gravy code that
fetched the ProBee ZU10’s VID and PID values.
Everything worked as designed. The ProBee ZU10
enumerated and I caught the ProBee ZU10’s regurgetated
VID and PID values in the Vinculum-II IDE debugger:
myVID
myPID
0x00000403
0x00006001
We’ve hit pay dirt. The ProBee ZU10 enumerated and
we were able to communicate with its internals. However,
to enable data transfer via the ProBee ZU10’s SENA radio,
we need to attach the FT232-friendly host driver to the
core USB host driver. The FT232 IC is doing its part on the
SENA radio/UART side. We need to enable a
communications method on the FT232 IC’s USB side.
That’s why the sFIND_DEVICE state passed application
control to the ATTACH FT232 HOST state:
//***********************************************
//* ATTACH FT232 HOST STATE
//***********************************************
case sATTACH_FT232:
// we have a device, intialize a driver
//for it
hUSBHOST_FT232 = vos_dev_open(VOS_
DEV_USBHOST_FT232);
// ft232_attach
ft232_att.hc_handle = hUSBHOST_2;
ft232_att.ifDev = ifDev;
ft232_iocb.ioctl_code = VOS_IOCTL_
USBHOSTFT232_ATTACH;
ft232_iocb.set = &ft232_att;
if (vos_dev_ioctl(hUSBHOST_FT232,
&ft232_iocb) != USBHOSTFT232_OK)
September 2011 73