As the name suggests, it clears all the flags in the configuration
buffer. This provides a way to easily set all the flags to a known
state, which is nice for implementing libraries that configure PD Buddy
Sink devices.
Now we correctly set the GiveBack flag and minimum current fields in the
Request message when GiveBack is enabled. Also when GiveBack is
enabled, we correctly handle GotoMin messages by lowering our power
consumption, completing negotiation, and Requesting our normal power
periodically until the power supply Accepts our Request.
At least, I believe it's correct. I don't have any hardware that sends
GotoMin messages, so I can't test it other than that it doesn't break
anything with the GiveBack flag set to 1 or 0 when the source doesn't
ask to reduce power.
As the name says, it toggles the GiveBack flag in the configuration
buffer. The rest of the firmware doesn't use the flag for anything yet,
but it is correctly saved in flash.
We used to free the Request we made after transmitting it. However, for
GiveBack to work properly, we need to be able to make that request
again. To do it without having to request the Source_Capabilities
again, it makes sense to keep the Request message in memory. We have
more messages in the pool than we need anyway.
The policy engine is supposed to transition to the
PE_SNK_Transition_to_default state from any state when hard reset
signaling is received. While it still doesn't do that exactly, in every
state that already waited for events, the PDB_EVT_PE_RESET event is also
checked, with the appropriate transition being made if the event is
received.
My justification for not checking for the event in other states is that
if there's no wait, the reset will be received soon by another state
anyway. Besides, if there's no event handling already, where exactly
would be best to insert a test for the event?
I think so, anyway. Testing with a heat gun didn't result in the Sink
resetting itself, so I'm not confident that I understand the FUSB302B's
over-temperature sensing mechanism.
I must point out though that I'm not confident that this
over-temperature protection is even useful. The PD Buddy Sink doesn't
get hot on its own, and if it did, it might not even be from the device
it's powering, making a hard reset useless. The spec says that we Shall
implement over temperature protection though, and that we Shall send a
Hard Reset message when it engages, so even though I take issue with the
requirement, I'll try to do what the standard says I Shall.
The README now outlines the features of the PD Buddy Firmware.
A bit of documentation was added to main.c, along with renaming the
pd_buddy() function to sink().
When there is a positive or negative transition of Vbus, we Shall reduce
our power consumption to no more than 2.5 W beforehand. This can be
easily achieved in all cases by simply turning off the output. This was
implemented, so that's one fewer Shall we aren't doing.
In the process, I made some API changes for the Device Policy Manager.
No more output_on() and output_off(), now it's output_set(true) and
output_set(false), plus a special case output_default() used during a
hard reset. This much better matches how these functions are used by
the policy engine.
Only get configuration once in Type-C Current mode
Before, we were doing the O(1) configuration loading operation every
15 ms, which just made me feel dirty. Now we do it only the first time
we check the available Type-C Current, and then cache its location.
This works because it never moves without rebooting into setup mode.
Type-C Current is a mechanism defined in the USB Type-C spec for
indicating high-current modes at 5 V using nothing other than a voltage
on the CC line. The FUSB302B maps the voltage to one of the four ranges
we care about, so it's easy to see if 1.5 A or 3 A is available at 5 V
even in systems that don't support PD.
Now, when the PD Buddy Sink is connected to a system without Power
Delivery support, after all attempts at PD communications fail, it falls
back to Type-C Current. If the Sink is configured for 5 V, it will
monitor the CC line's voltage to see if enough Type-C Current is
available. If so, the output is turned on.
After a failed hard reset, we keep trying to negotiate power. Before,
the LED was on steady indicating negotiation failure during these
continued negotiations. Now it keeps blinking, indicating what's
actually going on.
It's simpler than I realized. All that's left to do here is the
fallback mechanism for when the Sink is configured for 5 V. This means
that yet again, a TODO was replaced with another, less critical TODO.
Before, it was repetitive and hard to expand. It would have become a
big ugly decision tree upon adding support for variable and battery
PDOs.
Now it's been refactored to be a procedure, appending PDOs to the end of
the list and building the message header at the end. The code isn't
repetitive, and new features can be added more easily.
In the PE_SNK_Select_Capability state, we Shall do some transitions if
we receive a Wait or Reject message. Now we do. This creates another
TODO (running SinkRequestTimer in the PE_SNK_Ready state), but this
one's only for a Should, not a Shall.
From the USB PD spec, Revision 2.0, S. 6.4.4.1:
* A DFP or UFP which does not support Unstructured VDMs Shall Ignore
any Unstructured VDMs received.
From S. 6.4.4.2:
* A DFP or UFP which does not support Structured VDMs Shall Ignore any
Structured VDMs received.
Therefore, as long as we do not support any VDMs, we Shall Ignore them,
which is exactly what we're doing. We're not doing anything wrong, so I
removed the TODO comment that implied we were doing something wrong.
PD uses odd units for voltages and currents. Power too, but we don't
work with power (yet). In the shell, we have to convert to and from
these odd units. We had been doing this in-place every time, which was
a bit crumby. Now it's done with macros in pd.h, making prettier and
more maintainable code.
The configuration interface is done, so we shouldn't have any comments
that say otherwise. Also, since the shell never exits, it's silly to
put the code that runs it in a loop.
The GUI will have a button to identify a particular PD Buddy Sink, in
case several are connected to the computer at once. The button will
cause the LED to blink quickly for a couple seconds, then go back to
normal. To allow this, I added a new LED blink mode (FAST_BLINK_SLOW)
that causes 8 fast blinks, then returns to SLOW_BLINK mode. A new
"identify" command triggers this LED mode.
The command shell is based on the ChibiOS-provided one, but modified to
not run in a new thread and generally be a bit simpler, while also
having PD Buddy branding. The storage functions work with the STM32
flash registers directly, taking over the last page of flash. A new
linker script is used to ensure that program code can't end up using
that page. The DPM has been updated to use the saved settings rather
than hardcoded ones. Now what's needed is real commands for editing the
configuration.
Added commands to edit configuration
We now have commands to load the current settings into RAM, edit the
settings in RAM, and write them back to flash. The only settings
currently supported are current and fixed voltage, because the rest of
the code doesn't support GiveBack or variable/battery PDOs yet.
Short help messages were added for each command. Nothing too exciting,
but it should be a great help for someone poking around in the PD Buddy
Sink configuration shell for the first time.
Wrote new usage information for the firmware
Now that we have a command shell, the README should indicate how to use
it.
There are still a few things that the standard says we Shall do and we
don't, but it Works For Me™. I haven't implemented anything with
regards to GiveBack support, but that doesn't matter just yet. Our
handling of VDMs isn't quite right either. Anyway, it successfully
negotiates with so-called Split PDO power supplies, which is more than I
can say about some commercial products.
Based on the RT-STM32F072-DISCOVERY demo from ChibiOS/demos/STM32. The
board definition was made with the Eclipse plugin, and is based on the
ST_STM32F072B_DISCOVERY board definition from ChibiOS/os/hal/boards.