Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 3 of 3

Thread: Steel Battalion Controller LED issues

  1. #1
    Junior Member
    Join Date
    Jul 2021
    Posts
    5

    Steel Battalion Controller LED issues

    I'm using a Teensy 4.1 to connect to a Steel Battalion Controller:
    Click image for larger version. 

Name:	320px-Steel_Battalion_controllers.jpg 
Views:	36 
Size:	14.0 KB 
ID:	26372

    I have experience with this controller and have already written a driver for it. I was actually able to get it working as a normal joystick fairly easily using the teensy to read the info over usb and emulate a joystick.

    My problem comes from writing out commands to control the LEDs using the joystick's only out endpoint.
    I reduced my program to the bare minimum needed to run. Currently it turns on LEDs on and off a few times and then stops responding. I'm sending the exact same 32 byte packet in my Windows C# program and it controls the LEDs just fine.

    SBCLight.ino
    Code:
    #include <USBHost_t36.h>
    #include "SBCController.h"
    
    USBHost myusb;
    USBHub hub1(myusb);
    SBCController SBC(myusb); 
    
    long changeTime  = 100;//milliseconds
    long currentMillis;
    long lastMillis;
    bool flipLight = false;
    
    void setup()
    {
      Serial1.begin(2000000);
      while (!Serial) ; // wait for Arduino Serial Monitor
     
      myusb.begin();
    }
    
    void loop()
    {
      currentMillis = millis();
      if(currentMillis - lastMillis > changeTime)
      {
        if(flipLight)
        {
          SBC.txbuf_[5] = 255;
          flipLight = false;
        }
        else
        {
          SBC.txbuf_[5] = 0;
          flipLight = true;      
        }
         SBC.sendLightDataPacket();
         lastMillis = currentMillis;
      }
      myusb.Task();
      
      delay(50);
    }
    SBCController.cpp
    Code:
    #include "SBCController.h"
    
    void SBCController::init()
    {
    	driver_ready_for_device(this);
    }
    
    // Again this class is solely to display as much information about a device as we can...
    // This all comes from the information passed to it through the claim method.
    bool SBCController::claim(Device_t *dev, int type, const uint8_t *descriptors, uint32_t len) {
      uint32_t txep = 1;
      uint8_t tx_interval = 4;
      tx_size_ = 32;
     
      txpipe_ = new_Pipe(dev, 3, txep, 0, tx_size_, tx_interval);
      if (!txpipe_) {
        return false;
      }
      txpipe_->callback_function = tx_callback;
    
     return true;
    }
    
    void SBCController::tx_callback(const Transfer_t *transfer)
    {
      if (!transfer->driver) return;
      ((SBCController *)(transfer->driver))->tx_data(transfer);
      
    }
    
    void SBCController::sendLightDataPacket()
    {
      Serial.println("trying to send light");
      queue_Data_Transfer(txpipe_, txbuf_, tx_size_, this);
    }
    
    void SBCController::tx_data(const Transfer_t *transfer)
    {
       Serial.println("Light Sent");
    }
    SBController.h
    Code:
    #ifndef __SBCController_h_
    #define __SBCController_h_
    #include <Arduino.h>
    #include <USBHost_t36.h>
    
    
    class SBCController : public USBDriver {
    public:
    	SBCController(USBHost &host) { init();}
    
     Device_t *currentDevice;
    
    void sendLightDataPacket();
    
    bool firstSent = false;
    
    uint8_t     txbuf_[64];   // buffer to use to send commands to joystick 
    
    
    void (*data_received)(const Transfer_t *);
    
    
    protected:
    	virtual bool claim(Device_t *dev, int type, const uint8_t *descriptors, uint32_t len);
    	virtual void disconnect() {};
    	void init();
      
      uint16_t    tx_size_ = 0;
      Pipe_t      *txpipe_;
      
      static void tx_callback(const Transfer_t *transfer);
      void tx_data(const Transfer_t *transfer);
      Device_t *mydevice = NULL;
    };
    #endif
    Here is an example of the current output with USB Debugging enabled:
    Code:
    USB2 PLL running
     reset waited 6
    USBHS_ASYNCLISTADDR = 0
    USBHS_PERIODICLISTBASE = 20003000
    periodictable = 20003000
    port change: 10001803
        connect
    trying to send light
      begin reset
    trying to send light
    port change: 10001005
      port enabled
      end recovery
    new_Device: 12 Mbit/sec
    new_Pipe
    enumeration:
    enumeration:
    enumeration:
    Device Descriptor:
      12 01 10 01 00 00 00 08 7B 0A 00 D0 00 01 00 00 00 01 
        VendorID = 0A7B, ProductID = D000, Version = 0100
        Class/Subclass/Protocol = 0 / 0 / 0
        Number of Configurations = 1
    enumeration:
    Config data length = 32
    enumeration:
    Configuration Descriptor:
      09 02 20 00 01 01 00 80 FA 
        NumInterfaces = 1
        ConfigurationValue = 1
      09 04 00 00 02 58 42 00 00 
        Interface = 0
        Number of endpoints = 2
        Class/Subclass/Protocol = 88 / 66 / 0
      07 05 82 03 20 00 04 
        Endpoint = 2 IN
        Type = Interrupt
        Max Size = 32
        Polling Interval = 4
      07 05 01 03 20 00 04 
        Endpoint = 1 OUT
        Type = Interrupt
        Max Size = 32
        Polling Interval = 4
    enumeration:
    USBHub memory usage = 960
    USBHub claim_device this=20001E80
    new_Pipe
    allocate_interrupt_pipe_bandwidth
     best_bandwidth = 5, at offset = 0, shift= 0
    trying to send light
    Light Sent
    trying to send light
    Light Sent
    trying to send light
    Light Sent
    trying to send light
    Light Sent
    trying to send light
    Light Sent
    trying to send light
    Light Sent
    trying to send light
    Light Sent
    trying to send light
    Light Sent
    trying to send light
    Light Sent
    trying to send light
    Light Sent
    trying to send light
    Light Sent
    trying to send light
    Light Sent
    trying to send light
    Light Sent
    trying to send light
    Light Sent
    trying to send light
    Light Sent
    trying to send light
    Light Sent
    trying to send light
    Light Sent
    trying to send light
    Light Sent
    trying to send light
    Light Sent
    trying to send light
    Light Sent
    trying to send light
    Light Sent
    trying to send light
    Light Sent
    trying to send light
    Light Sent
    trying to send light
    trying to send light
    trying to send light
    trying to send light
    Is there anything obvious I'm missing. I've tried playing around with the tx_size variable. The values for tx_size, tx_interval and txep were determined using the Joystick example by parsing the descriptor. I removed that section of code to make things more concise.

  2. #2
    Junior Member
    Join Date
    Jul 2021
    Posts
    5
    Adding some extra information:

    This website provides very specific information on the Steel Battalion and Xbox 1 controllers in general.

    I thought that may be I needed to use queue_Control_Transfer instead of queue_data_transfer

    /*
    * from https://xboxdevwiki.net/Xbox_Input_D...teel_Battalion
    *
    SET_REPORT
    bmRequestType: 0x21
    bRequest: 9
    wValue: 0x0200
    wIndex: Interface number
    wLength: <length of report; typically 6>

    Code:
    mk_setup(setup, 0x21, 9, 0x200, 0, tx_size_); // hopefully this sets leds
      queue_Control_Transfer(device, &setup, txbuf_, this);
    But I couldn't get this to work. Everything locked up when I tried that. I also tried setting byte 1 of the packet array to 22 as specified on the website to indicate the packet length, but this didn't work either.

    One last thing, the whole code won't work if I don't have the USBHub part of the code enabled. I wonder if adding an intermediate hub might somehow help.
    Last edited by HackNFly; 11-04-2021 at 06:50 AM.

  3. #3
    Junior Member
    Join Date
    Jul 2021
    Posts
    5
    Happy to say I resolved it. I saw another user mentioning something that they had to use a usb hub in between the controller and their project in order for it to work. Mine was I was not getting enough power connecting through my usb hub to the computer. I tried plugging the hub in between the controller and the device and it didn't work at all. The hub has lights on it and no lights came on. Maybe I need a simpler hub or something else, I don't know. I connected the Teensy4.1 directly to the computer and it worked at any speed. I did learn from this issue that I've been using too big a packet. Apparently it's only supposed to be 22 bytes long and not 32. Also the second byte is supposed to be 0x16 to indicate the packet length, but the device doesn't seem to care.

Posting Permissions

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