Zaratustra
Zaratustra

Reputation: 131

USB host transfer Android with Spartan 6 FPGA

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?

Upvotes: 0

Views: 1048

Answers (3)

Zaratustra
Zaratustra

Reputation: 131

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);
   }
  }

Upvotes: 0

Phuong Pham
Phuong Pham

Reputation: 1

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.

Upvotes: 0

FarhadA
FarhadA

Reputation: 883

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

Upvotes: 1

Related Questions