4

I am working on a program that will allow me to exchange data between my Android phone and a micro-controller that uses and FTDI chip (FT232R) for USB communications. So far, I have successfully created a thread that allows me to perform USB communications without impacting the rest of the application. Furthermore, I have successfully been able to both initialize and send data to the FTDI device, but I cannot seem to be able to read data from the device. I have set up the USB device to send out a 4-byte packet every 100 milliseconds to see if I can read the packet and echo it back onto the bus. However, I am not able to read the data.

On the device side, I am sending out a four byte ASCII packet, 'a''b''c''d', every 100 ms. On the host side, more specifically the USB thread, I am trying to see if I can receive this data. I am reading data inside of a while loop that is checking to see if the first location in my receive buffer is equal to any of the characters that are being sent (a,b,c, or d). The reason I did this is because I had a suspicion that the data was being jumbled. Inside the while loop, the buffer is cleared each time around. The bulkTransfer function is then called to try and receive data, and, if I understand it correctly, will receive data until it has received 64 bytes or a 1000 ms has passed (timeout). I then check to see if I received any of the data that was sent by checking for any of the 4 characters in the 1st element of the buffer. If I detect a character, the while loop exits and I send the first four character from the buffer onto the bus. However, I monitor the bus with a logic analyzer and I never seem to be able to detect any transmissions from the host, indicating that I am not receiving data. ANY help would be greatly appreciated. I have done a lot of work to get to this point but I seem to be stuck. Thank you.

USB Slave Code (C prog.)

while(1)
    {
        __delay_ms(100);
        unsigned char response[4] = {0};
        response[0] = 'a';
        response[1] = 'b';
        response[2] = 'c';
        response[3] = 'd';
        send_UART(4, response);
    }

Android Code

    public class MainActivity extends Activity
    {
        // Developer Notifications
        private boolean developer_notifications = true;

        // Sensor Constants
        public static int temperature;
        public static int humidity;
        public static int lpg;
        public static int alcohol;

        // Layout
        ListView listView;

        // USB
        UsbDevice USBDevice_s;
        UsbDeviceConnection USBDeviceConnection_s;
        UsbEndpoint USBEndpoint_s_control;
        UsbEndpoint USBEndpoint_s_data;
        UsbEndpoint USBEndpoint_s_data_out = null;
        UsbEndpoint USBEndpoint_s_data_in = null;
        UsbInterface USBInterface_s_control;
        UsbInterface USBInterface_s_data;
        UsbManager USBManager_s;
        UsbRequest USBRequest_s;
        ByteBuffer USBBuffer_s;
        public static int USBBuffer_s_length;
        private static final byte[] USBBuffer_s_received_data = new byte[]{ (byte)0x00, 0x00, 0x00, 0x00};
        //USBBuffer_s_received_data = 0;

        // Communication Flags
        public static int Sense_Sensor_ID_Request = 0;
        public static int Sense_Sensor_ID_Response = 0;

        // Thread
        private Thread USB_Communication_Handler;
        public static int threadflag = 0;


        @Override
        protected void onCreate(Bundle savedInstanceState) 
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            // Initialize Interface
            Model.LoadModel();
            listView = (ListView) findViewById(R.id.listView);
            String[] ids = new String[Model.Items.size()];
            for (int i= 0; i < ids.length; i++)
            {ids[i] = Integer.toString(i+1);}
            ItemAdapter adapter = new ItemAdapter(this,R.layout.row, ids);
            listView.setAdapter(adapter);


            // Developer Notifications
            developer_notifications = true;
            if ((developer_notifications))
            {Toast.makeText(this,"Developer Notifications Enabled", Toast.LENGTH_LONG).show();}

            // Begin USB Configuration | Grab Device List
            USBManager_s = (UsbManager) getSystemService(Context.USB_SERVICE);
            HashMap<String, UsbDevice> deviceList = USBManager_s.getDeviceList();
            Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
            while(deviceIterator.hasNext())
            {USBDevice_s = deviceIterator.next();}        
            Intent Intent_s = getIntent();
            String action = Intent_s.getAction();
            USBDevice_s = (UsbDevice) Intent_s.getParcelableExtra(UsbManager.EXTRA_DEVICE);

            // Upon Device Attachment
            if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action))
            {
                initialize_USB();
                USB_Communication_Handler();

            }

            else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) 
            {
                USBDevice_s = (UsbDevice) Intent_s.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                if (USBDevice_s != null) 
                {
                    USBDeviceConnection_s = USBManager_s.openDevice(USBDevice_s);
                    //USBDeviceConnection_s.releaseInterface(USBInterface_s);
                    USBDeviceConnection_s.close();

                    Toast.makeText(this,"Device Removed, Interface Released", Toast.LENGTH_LONG).show();
                }
                return;
            }



            //Layout / GUI Created - wait for USB data...
            temperature = 1; humidity = 63; lpg = 5000; alcohol = 500;
            Model.LoadModel();
            ItemAdapter adapter2 = new ItemAdapter(this,R.layout.row, ids);
            listView.setAdapter(adapter2);
            adapter.notifyDataSetChanged();

        }   

        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            // Inflate the menu; this adds items to the action bar if it is present.
            getMenuInflater().inflate(R.menu.main, menu);
            return true;
        }


        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
          switch (item.getItemId()) {
          case R.id.action_settings:
            //Toast.makeText(this, "Exiting", Toast.LENGTH_SHORT)
               // .show();
            android.os.Process.killProcess(android.os.Process.myPid());
            finish();
            break;
          default:
            break;
          }

          return true;
        }

        //@Override
        public void initialize_USB() 
        {
            USBInterface_s_control = USBDevice_s.getInterface(0);      
            USBDeviceConnection_s = USBManager_s.openDevice(USBDevice_s);
            USBDeviceConnection_s.claimInterface(USBInterface_s_control,  true);
            if ((developer_notifications))
            {Toast.makeText(this,"Sense found ("+USBDevice_s.getDeviceName()+")", Toast.LENGTH_LONG).show();}

            // Send Initialization Packets   
            if (USBDeviceConnection_s != null && USBDeviceConnection_s.claimInterface(USBInterface_s_control, true))
            {
                // Reset, Clear RX/TX, & Set Baudrate
                USBDeviceConnection_s.controlTransfer(0x40, 0, 0, 0, null, 0, 0);
                USBDeviceConnection_s.controlTransfer(0x40, 0, 1, 0, null, 0, 0);
                USBDeviceConnection_s.controlTransfer(0x40, 0, 2, 0, null, 0, 0);
                USBDeviceConnection_s.controlTransfer(0x40, 0x03, 0x4138, 0, null, 0, 0);

                if ((developer_notifications))
                {Toast.makeText(this,"Sense Enumerated & Initialized", Toast.LENGTH_LONG).show();}
            }

            // Grab Interface | Grab Endpoints | Configure for Data Exchange
            USBInterface_s_data = USBDevice_s.getInterface(0);
            for (int i = 0; i < USBInterface_s_data.getEndpointCount(); i++)
            {
                if (USBInterface_s_data.getEndpoint(i).getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) 
                {
                    if (USBInterface_s_data.getEndpoint(i).getDirection() == UsbConstants.USB_DIR_IN)
                        USBEndpoint_s_data_in = USBInterface_s_data.getEndpoint(i);
                    else
                        USBEndpoint_s_data_out = USBInterface_s_data.getEndpoint(i);
                }
            }

            USBBuffer_s_length = USBEndpoint_s_data_in.getMaxPacketSize();
            USBBuffer_s = ByteBuffer.allocate(USBBuffer_s_length);

            if ((developer_notifications))
            {Toast.makeText(this,"Ready for Data Exchange", Toast.LENGTH_LONG).show();}
            //USBDeviceConnection_s.bulkTransfer(USBEndpoint_s_data_out, new byte[] { 0x64 }, 1, 0);

        }

        public void send_data_USB() 
        {}
        public void receive_data_USB() 
        {}

        public void send_data_USB() 
        {}
        public void receive_data_USB() 
        {}

        public void USB_Communication_Handler()
        {
            USB_Communication_Handler = new Thread()
            {
                public void run()
                {
                    while(USBBuffer_s_received_data[0] != 'a' || USBBuffer_s_received_data[0] != 'b' ||USBBuffer_s_received_data[0] != 'c' ||USBBuffer_s_received_data[0] != 'd')
                    {
                        for(int i = 0 ; i < USBBuffer_s_received_data.length ; i++) 
                        {
                            USBBuffer_s_received_data[i] = '\0';
                        }
                        //USBDeviceConnection_s.bulkTransfer(USBEndpoint_s_data_in, USBBuffer_s_received_data, 0, 8, 500);
                        //USBDeviceConnection_s.bulkTransfer(USBEndpoint_s_data_out, USBBuffer_s_received_data, 0, 8, 500);
                        USBDeviceConnection_s.bulkTransfer(USBEndpoint_s_data_in, USBBuffer_s_received_data, 64, 1000);
                    }
                    USBDeviceConnection_s.bulkTransfer(USBEndpoint_s_data_out, USBBuffer_s_received_data, 4, 500);
                    }

                }

            };
            USB_Communication_Handler.start();
        }

        }
Willis
  • 5,308
  • 3
  • 32
  • 61
  • Have you tried connecting this to a Windows machine and used some terminal software to ensure that the problem doesn't lie solely on the device side of things and you can indeed get data from your device outside of the Android environment? – Preston Dec 02 '13 at 05:25
  • I have indeed. I can communicate bidirectionally in both Windows and Android through the use of a serial terminal. Any advice on why I can't read the data with my code? – Willis Dec 02 '13 at 07:03
  • 3
    So I was essentially trying to write all of my own USB functions in order to communicate with the FTDI device. Turns out FTDI has already created an API that allows you to do this; just use the following two libraries: `import com.ftdi.j2xx.D2xxManager; import com.ftdi.j2xx.FT_Device;` Also, here is the link to their API User Manual : [link](http://www.ftdichip.com/Support/Documents/AppNotes/AN_233_Java_D2xx_for_Android_API_User_Manual.pdf) Thanks! – Willis Dec 10 '13 at 07:58

0 Answers0