Page 2 of 2 FirstFirst 12
Results 11 to 18 of 18

Thread: FB in Linux: can somebody help?

  1. #11
    Fusion Brain Creator
    Join Date
    Mar 2005
    Posts
    2,221
    nick, he's using a v3, check the OP

  2. #12
    Newbie
    Join Date
    Mar 2009
    Posts
    5
    Quote Originally Posted by malcom2073 View Post
    No problem, I'm just glad someone found it helpful.


    Could this possibly be the keepalive? Perhaps flipping it on and off every other transmission is what 2k1toaster is talking about.
    I do flip the keepalive every transaction (that is what toggle = 1 - toggle; line is for), does not help. Somewhere in the forums I remember seeing that every OUT transfer should send byte 61 set to 0xff, so that is fine, I just do not remember seeing it in the spec.
    As far as the Linux driver goes, I really do not see how that can be a problem: I see that the chip gets the messages (after all something does happen and libusb drives numerous other devices, like my scanner, no problem). According to the USB spec it is really not even a device driver, per se, but the host controller that is responsible for all the transfers, libusb is really just a `fake driver'. Can someone please explain what WinUSB does? Is it Microchip specific, or just a generic implementation of OHCI? Thanks.

    Alex

  3. #13
    North of the land of Hey Huns
    Auto Apps:loading...

    Join Date
    Jun 2004
    Location
    Westminster, MD
    Posts
    2,127
    As far as I can tell, WinUSB seems to be a (Microsoft created) user-space implementation of USB support in windows. Not entirely dissimilar from libusb in Linux.

  4. #14
    Fusion Brain Creator 2k1Toaster's Avatar
    Join Date
    Mar 2006
    Location
    Colorado, but Canadian!
    Posts
    10,049
    For some V3 firmware 61 does go to 0xFF all the time and is used for initialization. Also V3 specifies that every communication, every DO must toggle a keep alive bit.

    Code:
                                switch (_version)
                                {
                                    case MainMDX.BrainVersion.Version_03:
                                        byte_address = MainMDX.AllDigitalOutputs[digitalOutputIndexArray[i]].Port;
                                        if (flip) { val += 2; }
                                        if (beOn) { val += 1; }
                                        communicationArray[byte_address] = (byte)val;
                                        break;
                                    case MainMDX.BrainVersion.Version_04:
                                        byte_address = (MainMDX.AllDigitalOutputs[digitalOutputIndexArray[i]].Port * 2);
                                        if (beOn) { val += 1; }
                                        val_2 += ((MainMDX.AllDigitalOutputs[digitalOutputIndexArray[i]].TimerValue % 64) * 4);
                                        val_2 += (int)MainMDX.AllDigitalOutputs[digitalOutputIndexArray[i]].Mode;
                                        val += (MainMDX.AllDigitalOutputs[digitalOutputIndexArray[i]].PWM_Value * 2);
                                        communicationArray[byte_address] = (byte)val;
                                        communicationArray[byte_address + 1] = (byte)val_2;
                                        break;
                                    default:
                                        continue;
                                }
    It is very hard to follow your code because it is all scrunched with no spacing. I dont get what you are doing with variable "enough". Also I dont get your reasoning behind setting all outputs to off, in the byte stream and it looks like you are only turning 1 IO back to whatever state you tell it. You need to loop all DO's regardless of if it is changing state or not. If you send a DO a 0x00, it will turn off. I dont see where you are setting all 12 outputs each transfer.


    WinUSB is the generic USB driver for Vista and XP distributed by Microsoft. Microchip had its own driver when I started coding this program. It was an archaic buggy and slow driver. Over the past few months they have abandoned that driver, and now tell people to use Microsoft WinUSB drivers.

    The drivers are not drivers in the sense of one device one driver. But they are drivers. It talks directly to the USB chipset and the programmers talk to it, the meaning of a driver. It is very generic driver and Microsoft's hope is for every device to use that single driver if it can. That way you install the driver once, and all your devices work without needing more new 3rd party drivers.
    Fusion Brain Version 6 Released!
    1.9in x 2.9in -- 47mm x 73mm
    30 Digital Outputs -- Directly drive a relay
    15 Analogue Inputs -- Read sensors like temperature, light, distance, acceleration, and more
    Buy now in the MP3Car.com Store

  5. #15
    Newbie
    Join Date
    Mar 2009
    Posts
    5
    Quote Originally Posted by 2k1Toaster View Post
    For some V3 firmware 61 does go to 0xFF all the time and is used for initialization. Also V3 specifies that every communication, every DO must toggle a keep alive bit.


    It is very hard to follow your code because it is all scrunched with no spacing. I dont get what you are doing with variable "enough". Also I dont get your reasoning behind setting all outputs to off, in the byte stream and it looks like you are only turning 1 IO back to whatever state you tell it. You need to loop all DO's regardless of if it is changing state or not. If you send a DO a 0x00, it will turn off. I dont see where you are setting all 12 outputs each transfer.
    Ok, here is the code with spacing (I hope it works, I have not figured out the markup yet). The program itself is supposed to be used as `prog m b' where m is the number of the output to set, and b is either 1 or 0. So yes, it zeroes all the bytes first, then sets the one I want to , say `on', and the makes a bulk transfer (it also sets byte 61 to 0xff). `enough' was introduced to test the timers and also see how many transfers it takes to get byte 61 back as 0xff. After that all 64 bytes are transferred (and read back) `enough' times (pun intended) I really need the program to exit and the output to stay on until I run it again and turn it off. The most frustrating part is it all almost works .... after I switch input 0 on and off.

    Edit: One more thing. What I said above means that after the board turns on, `prog 5 1' does nothing, even when I replace `while (enough<5)' to `while (1)' (i.e. loop forever trying to set DO 5 to 1) BUT `prog 0 1' has the desired effect instantly AND after that `prog 5 1' works as well! More weirdness: in the scenario above, if I wait, say 10 min, DO 5 turns itself off and if I run `prog 5 1' again, I cannot set it on (it just flickers while the program is running). Now `prog 0 1' ... you guessed it, makes everything peachy again ... for the next ten minutes.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <libusb.h>
    
    #define EP_OUT 0x01
    #define EP_IN 0x81
    
    
    libusb_device *fusionBrain;
    libusb_device_handle *fusionBrainHandle;
    libusb_device **devs;
    libusb_context *context;
    unsigned char data_recv[64];
    unsigned char data_sent[64];
    
    int setsingleio(int ionum, int active)
    {
      int actualReceived, actualSent;
      int toggle = 1;
      int enough = 0;
      int i, j;
    
      if ((ionum < 0) || (ionum > 11))
        {
          return -1;
        }
    
      for (i=0;i<64;i++)
        {
          data_sent[i]=0;
        }
      
      data_sent[61] = 0xff;
      
      while (enough < 5)
        {
          toggle = 1 - toggle; //flip the flop
    
          if (active)
    	{
    	  data_sent[ionum] = 0b00111101|(toggle<<1);
    	}
          else
    	{
    	  data_sent[ionum] = 0b00000000|(toggle<<1);
    	}
          
          printf("Bit: %i, Toggle: %i\n", data_sent[ionum], toggle <<1);
          
          libusb_interrupt_transfer(fusionBrainHandle,EP_OUT,data_sent,64,&actualSent,500);
          libusb_interrupt_transfer(fusionBrainHandle,EP_IN,data_recv,64,&actualReceived,500);
          
          //part below only for debugging, no USB transfers 
    
          for(i = 0; i< 8; i++){
    	for(j = 1; j<=8; j++){
    	  printf("%3i ", data_sent[i*8+j-1]);
    	}
    	printf("\n");
          }
          printf("********* RECEIVED ************\n");
          for(i = 0; i< 8; i++){
    	for(j = 1; j<=8; j++){
    	  printf("%3i ", data_recv[i*8+j-1]);
    	}
    	printf("\n");
          }
    
          // sleep .3 sec and do it again ... 
    
          usleep(300000);
          enough++;
        }
      return 0;
    }
    
    
    int main(int argc, char **argv){
      int input, active;
      int i=0;
      
      libusb_init(&context);
      libusb_set_debug(context,3);
      
      libusb_device *dev;
      libusb_get_device_list(NULL,&devs);
    
      while ((dev = devs[i++]) != NULL)
        {
          struct libusb_device_descriptor desc;
          libusb_get_device_descriptor(dev,&desc);
          if ((desc.idVendor == 0x04d8) && (desc.idProduct == 0x000C))
    	{
    	  printf("Found fusion brain v3\n");
    	  fusionBrain = dev;
    	}
        }
      
      printf("Trying to open...\n");
      if (libusb_open(fusionBrain,&fusionBrainHandle))
        {
          printf("ERROR\n");
        }
      printf("Opened... trying to claim...\n");
      libusb_claim_interface(fusionBrainHandle,0);
      
      
      
      if ( argc < 2 ){
        input = 0; 
        active = 1;
      } else {
        input = atoi(argv[1]);
        active = atoi(argv[2]);
      }
      
      if (setsingleio(input,active))
        {
          printf("Error on set\n");
        }
    
    }

  6. #16
    Constant Bitrate
    Join Date
    Jun 2008
    Location
    Georgia, USA
    Posts
    188
    Quote Originally Posted by nousb View Post
    ...What I said above means that after the board turns on, `prog 5 1' does nothing, even when I replace `while (enough<5)' to `while (1)' (i.e. loop forever trying to set DO 5 to 1) BUT `prog 0 1' has the desired effect instantly...
    While (enough<5) means the maximum that it can increment to is 4 and you are trying to get it to turn output 5 on/off. Try while (enough<6) and see what happens.

    While statements check the condition before executing the code block.

    EDIT: Removed reference to "until" statement as it is not implemented in C.
    Thanks,

    Dan

  7. #17
    Constant Bitrate
    Join Date
    Jun 2008
    Location
    Georgia, USA
    Posts
    188
    Quote Originally Posted by Dan2008 View Post
    While (enough<5) means the maximum that it can increment to is 4 and you are trying to get it to turn output 5 on/off. Try while (enough<6) and see what happens.

    While statements check the condition before executing the code block.

    EDIT: Removed reference to "until" statement as it is not implemented in C.
    Okay, after rereading your code (and another cup of coffee), what I said doesn't apply since the variable "enough" does not indicate which output you are working with.

    Sorry.
    Thanks,

    Dan

  8. #18
    Newbie
    Join Date
    Mar 2009
    Posts
    5
    Well, I still cannot figure it out but I found that setting output 0 to 0 at the beginning makes everything else (except the timers) work. The code below is a cleaned up version of that posted earlier. If anyone is playing with Linux and FB v3, can you test it/play with it? Thanks. I am still wondering what is going on.

    Alex

    PS The way to compile it is:

    1) Install libusb-1.0 (you probably have to compile it but it is easy).
    2) Do
    Code:
    gcc linfb.c -o linfb -I/usr/local/include/libusb-1.0/ -L/usr/local/lib/ -lusb-1.0 -Wl,-rpath -Wl,/usr/local/lib/ && sudo ./linfb 5 1
    where linfb is the name of the program (give it your own name if you would like). If you do it as root, you do not need the last sudo.

    Code:
    nclude <stdlib.h>
    #include <string.h>
    #include <libusb.h>
    #include <iso646.h>
    
    #define EP_OUT 0x01
    #define EP_IN 0x81
    
    #define TIMER_OUT_OF_BOUNDS -2
    #define IO_PORT_OUT_OF_BOUNDS -1
    
    libusb_device **devs;
    libusb_context *context;
    unsigned char data_recv[64];
    unsigned char data_sent[64];
    
    int setsingleio(int ionum, int active, libusb_device_handle *handle)
    {
      int timer = 0;
      int i, j, k;
    
      if ((ionum < 0) || (ionum > 11)){ return IO_PORT_OUT_OF_BOUNDS; }
      if ((timer < 0) || (timer > 63)){ return TIMER_OUT_OF_BOUNDS; }
    
      for ( i=0; i < 64; i++ ){ data_sent[i]=0; }
      
      data_sent[61] = 0xff; // set wake-up
      data_sent[ionum] |= (timer<<2) | ( active ? 1 : 0 ); // set the port and the timer
      
      for ( i=0; i < 5; i++ )
        {
          data_sent[ionum] ^= (1<<1); //flip the flop 
          
          //send and receive     
    
          libusb_interrupt_transfer(handle, EP_OUT, data_sent, 64, &j, 500);
          libusb_interrupt_transfer(handle, EP_IN,  data_recv, 64, &j, 500);
    
          // sleep .3 sec 
     
          usleep(30000);
          
          //part below only for debugging, no USB transfers 
    
          printf("*********   SENT   ************      ");
          printf("********* RECEIVED ************\n");
    
          for( j = 0; j < 8; j++ ){
    	for( k = 1; k <= 8; k++ ){
    	  printf("%3i ", data_sent[ j*8 + k - 1 ]);
    	} printf("     ");
    	for( k = 1; k <= 8; k++ ){
    	  printf("%3i ", data_recv[ j*8 + k - 1 ]);
    	}
    	printf("\n");
          }
    
        }
      return 0;
    }
    
    
    int main(int argc, char **argv){
    
      libusb_device_handle *handle;
      libusb_device *dev;
      int input, active;
      int i = 0;
      
      libusb_init(&context);
      libusb_set_debug(context,3);
      
      
      libusb_get_device_list(NULL,&devs);
    
      if ( argc < 2 ){
        input = 0; 
        active = 1;
      } else {
        input = atoi(argv[1]);
        active = atoi(argv[2]);
      }
      
      while ( (dev = devs[i++]) != NULL )
        {
          struct libusb_device_descriptor desc;
          libusb_get_device_descriptor(dev,&desc);
    
          if ((desc.idVendor == 0x04d8) && (desc.idProduct == 0x000C))
    	{
    	  printf("Found Fusion Brain v3\n"); break;
    	}
        }
      
      printf("Trying to open...\n");
      if ( libusb_open(dev, &handle) )
        {
          printf("Error opening device\n"); return -100;
        }
      printf("Opened... trying to claim...\n");
      if ( libusb_claim_interface(handle,0) )
        {
          printf("Error claiming interface 0\n"); return -100;
        }
    
      setsingleio(0, 0, handle); // set everything to 0
    
      if (setsingleio(input, active, handle))
        {
          printf("Error on set\n");
        }
    }

Page 2 of 2 FirstFirst 12

Similar Threads

  1. New Frontend for Windows and Linux
    By gbr in forum Other Cool Front Ends
    Replies: 68
    Last Post: 01-21-2009, 09:55 PM
  2. Linux duck duck goose!
    By rocken in forum Linux
    Replies: 11
    Last Post: 03-12-2006, 12:15 PM
  3. The LOW Risk Linux Adventure...
    By grepzen in forum Software & Software Development
    Replies: 13
    Last Post: 11-08-2004, 10:12 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •