Configuring and firing drivers with the FAST Serial Protocol¶
FAST Serial Protocol: Overview & First Steps
This documentation section is about the FAST Serial Protocol (FSP) commands, which are the low-level commands a host computer sends to a FAST board. Most FAST Pinball makers do not need to know about these details, since the pinball game framework (such as the Mission Pinball Framework) handles this communication for you.
FAST Pinball drivers must be configured before they can be used. Drivers are configured with the
DL: command. Configuring a driver is typically a one-time operation done when the game starts up, though there are situations where you might reconfigure a driver during a game.
Configuring a driver does things like:
- Sets whether this driver should pulse for a short time or stay on for a longer time
- Sets the power level of the pulse and hold
- Configures whether the driver should be fired automatically by a switch or manually by the game
- Configures whether the driver should be disabled automatically by a switch
- Configures a "rest time" to prevent the driver from firing too quickly
You can read an overview of how the FAST Modern Platform handles drivers, including how they are numbered, in the platform documentation.
In order for a driver to physically activate, several things must be true:
- The controller must have received a
- The watchdog timer must be running and not expired.
- The driver must have been configured with a
- The 48V power circuits from the FAST Smart Power Filter Board must be enabled.
A programmer's view of FAST drivers: lots of state machines¶
Before we get into the details of how you configure drivers in the FAST platform, let's first look at how drivers function under the hood.
In the FAST Pinball Modern platform, you can visualize each driver as a separate process running on the FAST hardware itself. Think of each driver process is its own state machine, with memory, timers, configuration, etc. The
DL: command is used to create, configure, initialize, and start this process. You'll use a separate
DL: command to kick off this process for each driver.
These driver configurations are lost when the Neuron is reset, so that's why you need to send a
DL: command before a driver can be used—you're quite literally sending the config for the driver process to start.
If you send a new
DL: configuration to a driver which is already running from a prior
DL: config, the existing driver object will be destroyed (similar to a hard kill) and a new one will be created with the new command parameters.
TL: command is used to interact with an existing running driver, which provides several advantages over doing everything with the
DL: command. For example, to temporarily disable a driver (between games, or during tilt),
TL: commands can temporarily disable and then e-enable the driver. You can also use
TL: commands to change the switch ID associated with a driver. (Drunk flipper swapping the left and right buttons, for example.) Using the
TL: command is preferred, since sending another
DL: command which will destroy and set up a whole new driver.
Controlling how drivers fire with trigger flags¶
DL: command is used to configure a driver, and one of that command's parameters specifies what triggers the driver to fire. Broadly-speaking, you can say that drivers can be fired by hardware or software. (Or "automatic" or "manual", if you prefer.)
- A hardware-triggered (automatic) driver is one which automatically fires when a switch changes state. These trigger processes are handled completely in the FAST hardware which is much quicker than the round-trip USB lag for the switch input to go to the host computer and the host computer a send a command to fire the driver. As the game programmer, you use the
DL:command to essentially say, "when switch X is closed, fire driver Y". This is used for quick-response things like flippers, pop bumpers, slingshots, etc.
- A software-triggered (manual) driver is one that's fired only when a command sent from the host computer. This is what most drivers in the machine are, and used for things like ejecting balls, firing the knocker, resetting drop targets, turning on motors, etc.
These two driver modes are not necessarily mutually exclusive. For example, a pop bumper normally operates as a hardware-triggered driver during game play, but you might also need to fire it manually during ball search.
That said, there are some nuances to the above options. For example, for hardware-triggered devices which are triggered by a switch, should that driver fire when the switch opens or closes? Most of the time, you'll want the driver to fire when the switch closes, but opto switches are inverted, and sometimes flippers buttons use optos, in which case you'd actually want the flipper driver to fire when the switch opens, and the flipper to deactivate when the switch closes.
To handle these nuances, the
DL: command includes a trigger parameter which specifies a set of options which control how this triggering happens. The trigger flags are a bit field of flags, where each bit represents a different trigger option. You figure out all the bits you want to set to get the behavior you want and then convert that to the hex value you need to send to the
Here is the trigger bit field:
BIT 7 6 5 4 3 2 1 0
[DISABLE_SW][MANUAL][INV_SW2][INV_SW1][ONE_SHOT][NOT USED][NOT USED][DRV_ENA]
The vast majority of your drivers will be configured with the following two flags set:
Driver Enabled (
0): This is the only flag that is required. It tells the FAST hardware to enable the driver. Without this flag, the driver will not fire. Note that "enabling" the driver does not mean it is turned on right now, rather, it means that it is ready to be fired. If you don't set this bit, then subsequent
TL:commands to fire the driver will be ignored.
Disable Switch (
7): This bit is used to disable the driver's control linkage to a physical switch. In other words, setting this bit means that whatever switch ID you specify in the
DL:command will be ignored and NOT trigger the driver even if the switch is hit. This is useful for both drivers that will be hardware-controlled (since you don't want them to be connected to their switch until the game starts) and software-controlled drivers (since you don't want them to fire until you send a
So these two bits are bit 7 and bit 0, which is
81 in hex.
If you need to invert the switch that's linked to the driver (like for a hardware-controlled driver with an opto switch), you would enable bit 4, meaning your overall bits would be
10010001 which would be a value of
91 in hex for your
DL: configuration command.
Some driver modes use two switches, like for a diverter with an entrance and exit switch. If you need to invert the second switch, you would enable bit 5, meaning your overall bits would be
B1 in hex.
You can max-and-match the specific bits you need, and then convert that to hex to send as the trigger parameter part of the
If this seems confusing now, it will make more sense are you read the specifics of the
DL: command. We have practical examples throughout this documentation which should get you pointed in the right direction.
Entering PWM values¶
Many driver modes have configuration parameters as part of the
DL: command that allow for a power setting less than 100%. This is useful when you want to hold a driver "on" for an extended period without burning up the coil, or when you want to fire a driver as less than full strength.
FAST Pinball hardware uses "PWM" or pulse width modulation to apply variable power, which means the driver turns on and off really quickly—usually hundreds of times per second! (In this documentation, you'll see these parameters called "power" or "PWM".)
FAST Pinball PWM values are a sequence of 8 bits, representing an 8ms chunk of time. Each bit is 1ms, and a value of 1 means the power is on in that millisecond, and a value of 0 means the power is off. So if you want to set the power to 50%, you would set a PWM value of
AA in hex. Full power is
FF in hex, and 0% power (e.g. "off") is
00 in hex. You can get fancy and use whatever values you want, though the vast majority of use cases will be something along the lines of the chart below:
N or > jump the next page, P or < for previous, search with S or ?