Open source Rapid-fire X360 Project


I am assuming that each group of four buttons gets pulsed at different times.
However, I will show the effects of dealing ...
Old Matrix:
New CG:

        I have heard reports that there are different Matrix boards where the big chip has
the shield on it, a...
2: Methods and game-speed limitations: So basically what is desired is to create a
quick reoccurring pulse to be over-laid...
This is not very inventive. For starters, there is no way to change how fast the output is. It
also does not allow the abi...
The first solution to the problem is simple: Use a transistor. A transistor can be
used like a switch that is turned on by...
One thing to go over at this point: Switch-able power supply points. The CG
(again) has an easy 3V supply point that is co...
controllers, it will only lower the voltage on the wiper by a few hundred mV and would
still be adequate voltage for switc...
ups. When the problem was found on the Matrix, I first tried to use a simple 1k Ohm
pull-up resistor. It did not work. So ...
cycle PWM pulse. Since each type of controller needs the exact opposite end of the pulse
to turn on, this fits both contro...
The Code and the differences: My first attempt used opto-isolators and the code was
merrily dismissed. I wiped out any tra...
power-up, the code will use the wrong output latch state and rapid-fire will be on all the
time. You will need to pop out ...
Upcoming SlideShare
Loading in …5

Opensource Rapidfire X360 Project2


Published on

1 Like
  • Be the first to comment

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide

Opensource Rapidfire X360 Project2

  1. 1. Open source Rapid-fire X360 Project Index 1: The Hardware 2: Methods and game-speed limitations 3: Discoveries 4: Programming the 12F683 This is a document of the process of developing an open-source code for the XBOX360 controllers using the Microchip PIC12F683. The intent was to give the public a decent and working code in order to program their own chips instead of paying $30+USD on EBay for what I considered substandard code. I believe I have completed what I set out to do, with the exception that only the code has reached the public with no background as to what the problems are facing the unwary. I have already witnessed results of people using the code the wrong way and having poor results. For example, people are burning chips and wiring everything completely wrong, the complaining that there is something wrong with the code. Since this project has no official home/base of support (and I have no intention of ‘supporting’ this project any longer), I am drawing this document so people will realize the extent of what went into this code and how to avoid problems in the future if they attempt (and I hope they do) to modify the code to make it better/more personal. 1: The Hardware: Even if you have seen this info before, do not skip this section. The current state of the X360 market is now leaning toward the wireless controllers, so the scope of the project will only deal with those. Now, there are two types of wireless controllers: The Matrix and the CG (Common Ground). The first generation of wireless controllers used the Matrix PCB boards. It is called the Matrix because it uses a matrix for determining how to monitor the button presses. The controller pulses the 4 buttons at a time and depending on which buttons are pressed, can determine the state of each button in turn. This allows the controller to use 8 I/O to read 16 buttons. The following picture shows how this is implemented on the controller (picture provided by RDC at X-S forums).
  2. 2. I am assuming that each group of four buttons gets pulsed at different times. However, I will show the effects of dealing with this later. The 2nd generation controller is the CG (common ground), named by the fact that the controller now simply uses 16 I/O with all the inputs held ‘high’ so that pressing a button will pull the input to ground. This style of controller is much easier to work with from a design perspective since a microcontroller can be directly connected to these inputs and ground them without extra hardware. To determine which controller you have, the following pictures show the differences between PCBs, and also a comparison of how to tell without opening the controller. The following pictures were provided by RDC at X-S forums. The above pictures show the differences between controllers by viewing them through the battery pack compartments.
  3. 3. Old Matrix:
  4. 4. New CG: I have heard reports that there are different Matrix boards where the big chip has the shield on it, and some do not. All pictures I have seen appear to have identical PCB boards. I can only assume that there were no functional differences and that the differences in these controllers were due to changing of manufacturing processes and not the actual board design. In layman terms, they did not change how the controller works.
  5. 5. 2: Methods and game-speed limitations: So basically what is desired is to create a quick reoccurring pulse to be over-laid onto the firing button in order to simulate ‘Rapid- fire’. The most common ‘fire’ button for most games is the Right Trigger. Additionally, some games also use the Left Trigger in what is called Dual Mode (where you are holding a weapon in each hand). From a basic programming standpoint, this means just creating a simple timed pulse will give you what you want. One other consideration is the speed of the pulse. It has already been well established that certain games already have automatic firing of weapons, but by applying just the right timed pulse will make the weapon more accurate and reduce the recoil. This is especially prevalent on Halo 3. There are two methods by which to apply the pulse onto these triggers: Rapid-fire (just the original name of the modification) where the rapid-fire is activated by pressing a separately installed button on the bottom of the controller, and Sleeper-fire where the pulse is active when the original Trigger is pulled (and thus no need for an external button). The Sleeper method has become more popular due to the idea that no external buttons have to be installed, and the controller looks as factory stock, or ‘stealth’. This method requires a way to turn the rapid-fire on and off so that the controller can regain the original control of the trigger function for games that do not use rapid-fire. Lastly, there is good reason to have some form of indicator to give the user the ability to determine when the rapid-fire is on or off. If a single chip will have more than one firing speed, this is more of a requirement than a bonus feature. This all leads to the following design requirements: A single chip that can easily work with both old and new PCB controllers (Matrix and CG). Should work as either Rapid-fire or Sleeper-fire. Have multiple firing rates for different games w/ ability to switch these rates. Have LED indicator. Be able to store the current rate in non-volatile memory. Control both triggers separately as each fire-rate will be game specific. 3: Discoveries: Before I even got a chance to writing code, I looked at what was currently was available out on the net for open code. It was not very pretty. About 90% of what people were peddling was the following: If (button press) Output High Wait X time Output Low Wait X time Else Output Low
  6. 6. This is not very inventive. For starters, there is no way to change how fast the output is. It also does not allow the ability to turn off rapid-fire or regain control of the trigger if needed. Also, of dual trigger method is desired the lines were generally just copied meaning that if both buttons were pressed then the firing on both triggers would be active at half the intended speed. Most designs compensated for this by wiring a single output to both triggers. But now, there is no longer selectable control of the rapid-fire. The only thing worse would be wiring to the player LED trick that only works on the Matrix. The PWM pulse is actually faster than any programmed chip and the fire-rate is completely uncontrollable and sloppy. It does not even work for any game other than COD. Let us begin with how the hardware of the triggers work, since this is one of the hardest parts of the design aspect: The triggers are analog inputs. They are 10k potentiometers. As you pres the trigger, the wiper of the pot goes from one end to the other, varying the voltage on the wiper pin linearly. The pots are being provided with a 1.5V regulated bus provided by the Microsoft chip as power, and grounded at the other end. The wiper of the pot goes directly into the Microsoft chip as an analog signal. What makes things more interesting is that the Matrix and the CG work completely backwards from each other. In the ‘released’ state of the triggers, the Matrix has 1.4V on the wiper where the CG has 0.3V. When the triggers are pressed, the Matrix will now have 0.3V whereas the CG will have 1.4V. I am assuming that the reason for using a 1.5V regulated bus to supply the pots was a design consideration by MS so that degrading battery strength would not change the performance of the analog signals. I should also state that all 6 analog controls are all tied to this 1.5V bus (each trigger, and both joysticks X and Y axis pots). This causes a potential problem. The analog signals feed directly back to the custom made ASIC chip. It is undoubtedly looking for a 1.5 - 0V signal at its A2D converter input. It would also be safe to assume that the 1.5V generated by the chip is also used as its voltage reference for the ADC. It is very likely that applying a 3V digital signal to the wiper of any of the analog pots will possibly overload the ADC over time and damage the analog input by applying twice the rated voltage. Only Microsoft knows the tolerance of this input. But any Electrical Engineer knows not to exceed an analog signal like this.
  7. 7. The first solution to the problem is simple: Use a transistor. A transistor can be used like a switch that is turned on by voltage. A lot of open designs out there already use transistors to get by the problems of interfacing to both controllers. I decided the best way to handle the different interfaces was to do the same thing, but better: Opto-isolators. Opto-isolators are photo-transistors, transistors turned on by light instead of voltage. This light is provided by an internal LED. The most common reason is to isolate your control chip from the output voltages. Not only would using the optos keep the analog inputs safe, but they also made it possible to have a single program for any kind of controller. You would simply have different wiring for which controller and which method (rapid vs. sleeper). Having a single code was very important. It would reduce confusion as to which code to program for which type of setup was desired. You would only be soldering once. You could be reprogramming the chip many times as the code was improved and upgraded. Another important feature is that using an opto instead of a transistor reduced the problem of leakage current. This is where a transistor fails to turn off if its input is not properly grounded. If you were to use a transistor for the above schematic for the CG Rapid configuration, your transistors Emitter would be tied to the wiper. In order to turn off the transistor, your voltage on the Base would have to be lower than the emitter without being too low. If you simply let the Base float, you can get leakage current from the Collector to the Base that keeps the transistor in the ON state and will not release. Unfortunately, this idea was not well received. There were many complaints about having to use any extra hardware, and my concerns fell on deaf ears. There was also a small downfall to using the optos. They generally require 10mA to run, and would reduce the lifespan of the batteries. Back to the drawing board. But the good thing was this: In two of the configurations, it was possible to accomplish the same thing directly with the PICs output by latching the output as a low signal (making it a ground) and toggling the output on and off. This could easily be done by changing the pin from an output to an input (where the pin would then ‘float’). So now the only thing to do is find an easy solution for the other two configurations.
  8. 8. One thing to go over at this point: Switch-able power supply points. The CG (again) has an easy 3V supply point that is completely turned off with the controller. This is shown here: But the Matrix does not have a 3V switched power supply. Even though the same point on the Matrix provides 3V when on, it does not completely turn off with the controller and will keep powering the PIC if used. What the Matrix does have is a 2V switched power supply: This has an effect over the next design problem. In order to keep 3V from the analog input, we look at how the trigger works more closely. This is the CG trigger when released. The wiper will show anywhere from 0.1-0.3V. The mechanical linkage to the pot is not necessarily calibrated by MS. Apparently they just need to get the wiper somewhere in the middle so the voltage swing does not go completely through the entire range of the potentiometer. So the resistance on one end can be anywhere from 500 Ohms to 2k Ohms. I measured 2k Ohms on mine (and consequently had 0.3V on the wiper). The easiest way to bring the wiper up to 1.5V while the trigger is still released is to use a resistor to bring it up. But we also have 3V being supplied by the PICs output. So, if we have 3V supply and we know that the average resistance on this side of the wiper is roughly 1.5k Ohms, we can use a 1.5k Ohm resistor to create a new voltage divider that will cut the 3V output from the PIC to 1.5V. In reality though, there are 5 other pots in parallel and what I found was that a 2k Ohm resistor worked better for my controller. This provided the 1.5V just right (and is a more common value). If the pots resistance is lower on other
  9. 9. controllers, it will only lower the voltage on the wiper by a few hundred mV and would still be adequate voltage for switching. Also, this method is not so power hungry. The current running through the output of the PIC is only 1.5mA which is almost 10 times less than using the optos. This method gives us the ability to implement the Rapid-fire version (external buttons) on the CG. The flaw in this design is that if someone presses the rapid-fire button at the same time as pressing the trigger, then the wiper voltage will climb right up to 3V. Even though there is no reason to pull both triggers, it is a possibility. This leaves us with how to do this with the Matrix Sleeper configuration. Since the basic pot circuit is the same, we just do the same thing except we now have a 2V power supply. On the controller I had, trial and error led me to 330 Ohm resistors on the triggers. This means that my pots have a resistance of 1k Ohms when pulled. So now we have easy ways of implementing a rapid pulse on all four configurations. It requires a resistor for only two of them. All four use the tri-state method for implementing the pulse. Depending on what config, you keep the output latched as a high or low, and you toggle the I/O to create the pulse. The nice thing with the sleeper is that the signal is always present on the wiper, but when the trigger is released, the voltage is set so that it does not change. Only when the trigger is pulled does the output of the PIC have an effect on the wiper. The only problem with not using optos is that we lose the ability to have a single code for all 4 configs. I could have made two codes, but naming them would be a pain and it was easy to see that this would cause problems. So the best solution was to sacrifice a pin to determine which config was used and have the controller soldered that way to keep the single code solution. This way, people would not program their chips and have the wrong code for their setup. The next problem found was how to change programmed modes. The stealth design requirement means we need to find a button that can change the modes but not affect gameplay. The most popular choice has been the SYNC button. If this button is only tapped, the controller does not go through its sync process, and the button has no affect on the game. This design works like a treat with the CG (again). It already has a pull-up in place so you do not even have to enable the PICs weak pull-ups. But the matrix is another matter. At first, it seemed the sync button worked the same. But it was quickly found that other buttons would give false button presses to the PIC. In other words, pressing the X or Right Shoulder buttons would also have the same affect as pressing the sync as far as the PIC was concerned. I have also seen some feedback where wiring in different ways to the Matrix sync button would cause the controller to begin its synchronization routine if any of those buttons were held down. At first, to use the sync button for both controllers it was simply a matter of wiring directly to the sync button and have the PIC inputs not use the internal weak pull-
  10. 10. ups. When the problem was found on the Matrix, I first tried to use a simple 1k Ohm pull-up resistor. It did not work. So I put a scope on the Matrix sync point (I never did get any pictures of the scope display, and at his time my Matrix is wired for a different setup. You will just have to trust me or get someone else to take pictures of an oscilloscope readout). Basically, the sync pin is held high and the controller pulses the sync low at a rate of around 10 kHz. If you use a simple multi-meter, you can only see the high voltage. But the waveform looked more like, well, ‘waves’. The voltage was not stable in the high state. It sloped back up. When the sync button was pressed, it showed the opposite effect. The voltage was held low, with 10 kHz high pulses. But these pulses were much different. They looked like spikes rather than sloped waves. As was shown in the hardware section, there are basically 4 outputs pulsing all of the buttons, and 4 inputs reading what affect those pulses have. The downward pulses when the sync was not pressed were from one output, and the high spiked pulses when the sync was pressed was from a different output. Placing the scope on the Right Shoulder button showed the same ‘wavy’ signal, and putting the scope on the Left Joystick button when it was pressed showed the other ‘Spike’ pulses. So literally, there was no way to use the sync without contamination from the other buttons. But then I stumbled upon something by complete accident. I had decided to take another look at the ‘wavy’ pulse before completely giving up on the sync button. By that time, I had already started a new version of code that changed pinouts of the PIC. Before, I was using the Pin 4 (GPIO3) that is the only ‘input only’ pin on the chip. It does not have the ability to use the PICs internal weak pull-ups (and it was not needed at the time since the sync already seems to have a pull-up anyway). But my code used Pin 3 (GPIO4) and I setup the PICs weak pull-up so not to install another resistor into the circuit. By using the PICs internal weak pull-ups, the sync buttons waveform has completely changed. The signal was no longer ‘wavy’; it was now ‘spiked’ to ground instead. When pressing the other X and RS buttons, the waveform was changed to a more ramped/sloped waveform. By using a proper button debounce routine in the PIC, I was no longer getting contamination from the sync button. After three hours of pressing and holding all of the other buttons and even making the controller resync, there was no cross contamination found. So in conclusion regarding the Matrix sync button: By using the PICs internal weak pull-ups and a proper button debounce routine, you can use the sync button. Another design issue is using the player LED indicators. On the CG, the LEDs are commonly tied to ground and sourced by the MS ASIC with a 1.9VDC source. The only consideration is to use a proper current limiting resistor to make sure we do not over-volt the LED when wiring to the PICs output. The Matrix LEDs are all commonly tied to the supply voltage, and the MS ASIC provides a PWM signal to ground them to turn them on. The one problem found with the Matrix LEDs is that by running them through the PICs output through a resistor, the LED would stay on just a little when the controller was off. It was able to pull enough leakage current to turn on slightly. This current was measured around 120mA. That would drain the battery quickly while the controller was off. By using a 1N4148 (common small signal diode) in series with the resistor, the LED current was reduced to less than 10mA while the controller was off. Without any modifications done, the current draw from the batteries normally is about 100mA. The added current draw using the 1N4148 diode is negligible. Now, in order to make the code work for both controllers, I used a square wave pulse. It is the same as using a 50% duty-
  11. 11. cycle PWM pulse. Since each type of controller needs the exact opposite end of the pulse to turn on, this fits both controllers. In order to turn the LED off, simply change the PICs output into an input (tri-state). In theory, you should not have to use a resistor with this square-wave pulse. But the idea of this code is to have people evolve it and experiment. Without having the resistor in place, it is possible to have the code hang-up (if it gets altered) and it only takes 1 second of putting the full 3V on the LED and it is gone for good. The resistor does not do any harm. 4: Programming the 12F683: Now that the hardware has been evaluated, lets talk about code. In order to get complete independent signals for both triggers, I started with using the TIMER 2 modules hardware interrupt. The chip uses the internal 4MHz oscillator, giving us 1 MHz instruction cycle. Setting the TIMER 2 module with a 1:4 pre-scaler and loading a value of 250 into PR2 (what the Timer uses as a compare value) causes a hardware interrupt at exactly 1ms. During this interrupt is where the code will change output states depending on what the system flags/program states were set at in the main code. This way, you do not have simple loops that cut the fire-rate in half in order to activate both triggers. The LED output also uses the interrupt to create a 50Hz square-wave signal. One problem I discovered was the READ-MODIFY-WRITE bug that is inherent with all 8bit PICs. When using the Pin 4 as a controller identifier I was using it to determine what state the trigger outputs should be at the start of the program. But when the interrupt was changing states of the LED, the code would read the voltage on the pin, modify the bit for the LED pin, and write that back onto the latches. What this means is that during the short time of the triggers being tri-stated (inputs), writing to the LED pin would cause the output latches to change state just as the triggers would reach half-way. In order to get by this, the trigger outputs needed to be refreshed on every interrupt cycle. So the code reads Pin 4 to determine the output latch state, and sets an internal software FLAG bit (TRIGOUT). This bit is then used to refresh the output latch on every interrupt cycle that has the trigger outputs active. Changing fire-rates is accomplished by using a General Purpose Register (STATER) to store the current programmed state. This number is an 8 bit word that has a maximum value of 255. The first state is value 0. By adding 64 to this register, you get four states that cycle back to 0. If viewed in hex and binary, the values are: 0x00 = b’00000000’, 0x40 = b’01000000’, 0x80 = b’10000000’, and 0xC0 = b’11000000’. As can be seen, the last 2 bits toggle in binary by doing this, and makes an easy test to determine what state you are currently in. In the main code, a simple button polling routine is used to determine the pressing of the sync button to change states (and thus change fire-rates). In the BurnMeUp2.asm code, this can also be tested for to have dual trigger outputs selective to the program state individually. Last consideration is using the EEPROM for storing the last state used. Since STATER is the byte used to determine what fire-rate is being used, I simply used the PICs internal EEPROM to store this information and have it brought back during power- up. This way, the user does not have to keep pressing the program button to get to which rate was used last every time the controller is powered back on.
  12. 12. The Code and the differences: My first attempt used opto-isolators and the code was merrily dismissed. I wiped out any trace of it since people were actually programming chips and happily wiring the PICs outputs direct to the wiper. They completely ignored the wiring schematics and were unhappy that the controller rapid fire was ‘on all the time’. Duh. The second attempt using the output resistors was called BurnMeUp.asm. I called it that since there is a good chance that people will be burning up their controllers if they had such complete disregard for what they were doing. I was right. People to this very day are actually programming chips with different revisions of this code without any knowledge of how to wire it up and are heating up their battery packs and burning out LEDs. Then they want to wire the trigger direct to different parts of the controller trying to find another way to do the player LED indicator trick. The over-whelming evidence that people desire a rapid-fire controller and cannot be bothered with wiring it correctly is the main reason why I am drawing up this document. I have already evidenced people using this code and saying it doesn’t work when I know full well the reason has nothing to do with the code, but the fact that they did not even have a wiring diagram to begin with (if they even bothered to find it). BurnMeUp could be wired as either Rapid or Sleeper fire, and had four modes: Halo 3 speed, COD speed, COD insane speed, and off. The sync button was used to change modes, and the player 3 LED was sued to see changing of states. The LED would simply toggle on or off as the controller changed states, but not tell you what state you were in. Also, Pin 3 was used for determining controller type and Pin 4 was sued for the sync button. This code does not work with the Matrix controller sync button. BurnMeUp2 was the successor. At that time I had found a good speed for Halo3, the player indicator would blink to show you what state you were in, and pins 3 and 4 were swapped in order to use the weak pull-ups in order to use the Matrix Sync button with no contamination. This was meant to replace the BrunMeUp design altogether. A new version was made at request of a couple of people who said that actual gameplay would be a better design. Instead of using the sync button to turn the rapid-fire on or off, it was better to have the RF turn on/off more quickly and dynamically by using an external button. This means using the Sleeper design so RF was active on the trigger, but you could quickly turn RF off while playing in-game for different weapons (Halo laser was used as an example). To make the design universal, Dual trigger RF should be individually turned on/off for each trigger. Two external buttons to individually turn RF on/off quickly. In order to save I/O pins, it was suggested to use one of these buttons to change fire rates by holding it down for a few seconds. And thus was born the GameplayRF.asm. Holding down the right external button for 4 seconds will change program states and the right player 4 LED will blink that many times to tell you what mode you are in. I even made the chip show you what state was loaded on power-up too (this can be seen right when the batteries are inserted since the switched power supply points are not off when the batteries are first inserted). The player 3 LED was sued to show if the left trigger RF was on/off. In order to get enough pins to do this version, I needed a new way to find out what controller type the chip was soldered to. In the code you will find that the trigger output pins are first used as analog inputs to read the voltage on the triggers. Since each controller has different voltage present on the wiper, I use this value to set the TRIGOUT Flag bit on power-on. If you hold the triggers down during
  13. 13. power-up, the code will use the wrong output latch state and rapid-fire will be on all the time. You will need to pop out the battery pack and turn on the controller again in order to reset the output latch. This is the final product of what I plan to do with this project. It now has several different functionalities that can be used if people want to make their own versions of code. It is setup so that you can just dump new values in the declared variables to change the fire-rates. To me this is important since it is narrow minded to believe hard-coding speeds for a single game will make a controller mod useless in less than a year. For instance, this mod will most likely not work when COD4 comes out, and people will switch over to playing that game when it is released. There will not be enough people playing COD3 anymore. This will be true for all games. To get the most out of a rapid- fire controller, the speeds must be able to be programmed over time. Also, who wants to have a single controller for every single game that can use rapid-fire? To conclude, the files for this project can be found here: BurnMeUP: BurnMeUp2: GameplayRF: The schematics are included in the zip files. I will no longer be doing anything more with this as I really don’t have time and seem to be just making ‘adjustments’ for people every week. This was meant to be an open-source project, which means others get involved in changing it for the better. I ask that if someone wants something changed, they at least try to find out on their own. If they cannot, then the public posting of this project was started at and there are people there that should be able to help you customize the code to your liking.