0

So I need to write an app in Android that must be able to read data that comes from a FPGA SPARTAN 6.

My app is able to identify when the usb is connected, and can get info about interfaces and endpoints over that interfaces. But then it needs to read data that someone sends when a button is pressed, and this is when the app fails.

My code is as follows:

package com.example.usb;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.hardware.usb.*;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.TextView;

public class MainActivity extends Activity 
{
 private UsbManager usbManager;
private UsbDevice device;
private TextView tv;

Handler handler = new Handler()
{
    public  void handleMessage(Message m)
    {
        Integer datos = (Integer)m.obj;
        tv.setText(datos + "\n");
    }
};


@Override
protected void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    tv = (TextView)findViewById(R.id.tv);
    usbManager = (UsbManager)getSystemService(Context.USB_SERVICE); 
}

@Override
protected void onResume() 
{
    super.onResume();
    Intent intent = getIntent();
    String action = intent.getAction();
    if (action.equals(UsbManager.ACTION_USB_DEVICE_ATTACHED))
    {
        //conectar dispositivo
        device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
        //muestraDatos(device);
        UsbInterface intf = device.getInterface(1);
        UsbEndpoint epIN = getIN(device);
        //tv.setText(epIN.getDirection() + " " + epIN.getType());
        UsbDeviceConnection connection = usbManager.openDevice(device);
        new Thread(new Read(connection,intf,epIN,handler)).start();
    }
}

private UsbEndpoint getIN(UsbDevice device)
{
    UsbInterface intf = device.getInterface(1);
    UsbEndpoint ep = null;
    int numep = intf.getEndpointCount();
    for (int i = 0 ; i < numep ; i++)
    {
        UsbEndpoint aux = intf.getEndpoint(i);
        if (aux.getDirection() == UsbConstants.USB_DIR_IN && aux.getType() ==   UsbConstants.USB_ENDPOINT_XFER_BULK)
        {
            ep = aux;
        }
    }
    return ep;
}

And the Thread Read (which is supposed to read from FPGA) is:

package com.example.usb;

import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.os.Handler;
import android.os.Message;

public class Read implements Runnable 
{
 private UsbDeviceConnection connection;
 private UsbEndpoint epIN;
private Handler handler;
private UsbInterface intf;

   public Read(UsbDeviceConnection connection,UsbInterface intf,UsbEndpoint epIN,Handler handler)
{
     this.connection = connection;
     this.epIN = epIN;
     this.handler = handler;
     this.intf = intf;
 }

public void run()
{
    byte datos[] = new byte[50];
    int read_data = 0;

    if (connection.claimInterface(intf,true))
    {
        /*Message sms = new Message();
        sms.obj = "Success caliming interface: " + intf.getEndpointCount();
        handler.sendMessage(sms);*/
        //connection.controlTransfer(0x00000080, 0x03, 0x4138, 0, null, 0, 0);


        while (true)
        {
            try
            {
                Thread.sleep(500);
            }
            catch(InterruptedException e){}
            read_data = connection.bulkTransfer(epIN, datos, datos.length, 100);
            datos = new byte[50];
            //if (read_data > -1)
            //{
                Message sms = new Message();
                sms.obj = read_data;
                handler.sendMessage(sms);
            //}
        }
    }
    else
    {
        Message sms = new Message();
        sms.obj = "Fail claiming interface ";
        handler.sendMessage(sms);
    }



}

}

My goal here is just to show the number of bytes that are read with the function bulktransfer, but it does not show anything. Also, I belive I have to use the controlTransfer function, but the official documentation does not explain anything about the function, it is just a dark reference. I have seen posts like this Android 4.0.3. USB Host - sending data via controlTransfer and this Serial to USB Android application with health device but it is not very clear about what is the meaning of every parameter in the function. Anybody knows what Im doing wrong and/or has a good explanation about the controTransfer function?

Community
  • 1
  • 1
Zaratustra
  • 131
  • 1
  • 11
  • 1
    You'd want to start by having a much better of idea of what operations **exactly** your hardware device requires - that's not going to be something that someone without the documentation for the particular device you are using will know, unless you are able to say that it implements some particular well known scheme. Do you really implement the USB engine directly in the FPGA (possible but uncommon) or are you using a USB interface chip? – Chris Stratton Nov 21 '13 at 20:30
  • Well, I certanly didnt implement anything in the FPGA. The FPGA is supposed to send a string of bits, and I need to capture those bits. The person who has the FPGA implemented a read program in labview, and from that he can read what the FPGA is sending. I dont know anything of labview or electronics, Im just working with the host API that comes with Android, but again, it does not work. And I dont know what kind of operations the hardware device requires, Im completley lost here, that is why im asking for a hand. Thanx. – Zaratustra Nov 21 '13 at 23:52
  • 1
    No one can help you until you provide comprehensive documentation of your custom hardware - the parts that you completely ignored in your response above. You will have to ask the board / fpga developer for information on its USB interface, without which you cannot use the board with Android *or any other USB host*. – Chris Stratton Nov 22 '13 at 05:16
  • Thanz Chris for your support. I´d like to ask you, what kind of info (related to the USB Interface) it is important to achieve what Im trying to do? I dont know anything about this (I didnt know I had to swim in the hardware stuff), and I would like to ask the correct questions to the FPGA developer. Thanks again. – Zaratustra Nov 23 '13 at 00:07
  • 1
    You need to ask for the full specification of the USB interface which has been implemented - everything required to write a driver. Without that you can't know what data must be moved to or from what endpoints to actually accomplish anything. – Chris Stratton Nov 23 '13 at 02:40
  • Thanks Cris, the FPGA developer says he does not have a good idea of the code and he cant help me, I´ll see what I can do then. Thanx for your time. – Zaratustra Nov 26 '13 at 18:05
  • The FPGA programmer needs to explain to you **exactly** what their labview program does in the way of USB operations, so that you can begin making an Android equivalent. – Chris Stratton Nov 27 '13 at 15:23
  • Chris, I know is a little bit late, but I manage to solve the issue. How can I mark this question as solved? – Zaratustra Jan 28 '14 at 01:05
  • 1
    Post a writeup of what you did as your own answer, then accept it. You may have to wait a couple of days to do so, not sure. – Chris Stratton Jan 28 '14 at 15:12

3 Answers3

1

Well, you need to have a USB-to-serial interface device to connect to your Android host, on the FPGA side, it is a normal serial interface.

You can see the examples on one of these pages:

http://www.fpga4fun.com/SerialInterface.html or http://www.bealto.com/fpga-uart.html

FarhadA
  • 853
  • 2
  • 8
  • 19
  • No, that is only one of many possible ways. There is no particular reason to believe it is the one which has **already** been implemented. – Chris Stratton Nov 23 '13 at 02:38
  • The question strongly implies that the FPGA code has already been developed by someone else, and nowhere states that it implements an asynchronous serial interface, or that a USB-serial converter is being used. The only mention of USB-serial was in a reference to another Android project apparently consulted for Android USB API insight. So basically, you are taking a wild guess here in terms of applicability to the poster's present system, and even if applicable what you posted is a link to the FPGA developer's part of the problem, not the Android developer's which was the question subject. – Chris Stratton Nov 23 '13 at 17:30
  • Well, maybe for you, but for me, the person who asked the question does not seems to understand what kind of interface he is dealing with, if you read the last paragraph of his question, that is why I mentioned the FPGA part of it, the Java part should be pretty straight forward and easy to implement. – FarhadA Nov 27 '13 at 12:40
  • What you do not seem to understand is that the person asking the question is not the engineer responsible for the FPGA code. Your suggestion covers a problem their colleague has already solved (most likely in a different way), not the problem they asked about. – Chris Stratton Nov 27 '13 at 15:20
0

Basically you cannot get data from the USB port. It may be due to several reasons:

  1. USB interface doesn't work (from FPGA side).

  2. USB interface works, but FPGA doesn't send data.

  3. USB interface works, and FPGA does send data through Labview interface, but Android program still doesn't receive any data.

Solution

  1. You have to write (or download) the driver code to the USB block (on the FPGA board).
  2. You have to change the FPGA code.
  3. It works for Labview, but not your program. Maybe, the FPGA and the Labview have agreed on a protocol. For example Labview send some command, and FGPA send data back.

You don't understand FPGA and hardware side, it's still possible if you understand Labview codes. Revert engineer how the Labview code is implemented and try it on android.

Labview program is not too hard to understand.

Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
0

Well, I was finally able to solve the problem. The chip on the FPGA I was interfacing with, was an atmega32q4. It was a CDC device class,so based on that I had to find the right parametres for the function controlTransfer() to work. However, I wasnt able to understand how the function works or what was the purpose of the functions on the CDC devices (for example: SET_LINE_CODING,GET_LINE_CODING,ETC). Then I found this link which gives you a set of parameters to use with the controlTransfer function, and it worked like a charm.

Here is the code that is able to read data from the chip:

package com.example.calentadorsolar;

import android.hardware.usb.*;
import android.os.Handler;
import android.os.Message;

public class Lectura_Solar implements Runnable
{
private UsbDeviceConnection connection;
private UsbEndpoint epIN;
private Handler handler;
private UsbInterface intf;
private Datos_Solar aux;

public Lectura_Solar(UsbDeviceConnection connection,UsbInterface intf,UsbEndpoint epIN, Handler   handler)
{
    this.connection = connection;
    this.epIN = epIN;
    this.handler = handler;
    this.intf = intf;
    aux = new Datos_Solar();
}



public void run()
{
    connection.claimInterface(intf,true);
    connection.controlTransfer(0x21, 34, 0, 0, null, 0, 0);
    connection.controlTransfer(0x21, 32, 0, 0, new byte[] { (byte) 0x80,
                    0x25, 0x00, 0x00, 0x00, 0x00, 0x08 }, 7, 0);
    byte datos [] = new byte[64];
    while (true)
    {
        int data = connection.bulkTransfer(epIN, datos, datos.length, 5000);
        try
        {
            Thread.sleep(500);
        }
        catch (Exception e){}
        if (datos[0] == 0)
        {
            aux.temp1 = String.valueOf(datos[1]);
            aux.temp2 = String.valueOf(datos[2]);
            aux.temp3 = String.valueOf(datos[3]);
            aux.temp4 = String.valueOf(datos[4]);
            this.sendMessage(aux);//here we send the data to the main GUI
        }

    }
}

public void sendMessage(Datos_Solar message)
   {
    Message sms = new Message();
    sms.obj = message;
    handler.sendMessage(sms);
   }
  }
Zaratustra
  • 131
  • 1
  • 11