This commit adds support for configuring the current requested from the
power supply in the form of a resistance. This is useful for powering
resistive loads when a voltage range is configured.
Previously, we didn't make use of the voltage range when checking a
Type-C Current advertisement. That was bad, since if e.g. we want 6 V,
with the range 5-7 V, we could get the power we want from Type-C
Current.
This commit makes the firmware test if the configured voltage range
contains 5 V, and if it does, allows use of Type-C Current.
Now the DPM tests if the configuration holds a current or a power, and
if it's a power, it calculates current at the necessary voltage(s) based
on that power. This is used when making requests, when advertising our
Sink_Capabilities, and when checking Type-C Current advertisements.
Previously, the PDO attribute getter macros took a capabilities message
and the PDO index. This worked in a lot of cases, but not in some I
need now, and there was little advantage to them working they way they
did anyway. Now they take just the PDO itself, which is more intuitive
and more useful.
Now when we make a request from a voltage range, if the HV_Preferred
flag is enabled, we iterate over the PDOs backwards, so we see
higher-voltage fixed supply PDOs before lower-voltage ones. This causes
the flag to do what it's supposed to.
The code to find a PDO from the range has been factored out into its own
function which will be used when building a Sink_Capabilities message.
Requests for fixed voltages are now made from the voltage range. This
isn't a terrible behavior, but I might want to be able to make requests
from programmable supplies from the range as well. 'Twould be more
complicated though, and provide comparitively little benefit. I'll
think about it, and maybe put out a request for comments.
This commit breaks old configuration by interpreting stored voltages as
millivolts, rather than 50 mV. This will allow the finer voltage
increments used by programmable power supplies to be specified.
The new tempate variable sets the data role, power role, and
specification revision in one fell swoop. It's used by the PE and DPM
alike for creating messages, and in the future it may have a part in
determining if we're doing PD 2.0 or 3.0.
All the internal functions and definitions have been moved out of
lib/include/. Includes are made with the semantically correct brackets
("" or <>) throughout the firmware and library. That is to say, the
library is essentially done at this point, with only documentation
changes left to be made.
Not the static globals yet, just the public ones. I suppose this change
isn't technically necessary since the PD Buddy Sink is a single-port
device, but I want its firmware to be a shining example of how to use
the library.
The code compiles again, and it seems to work as it did before. There's
still a lot to do (we still have a mess of globals), but the PE
correctly calls the new DPM functions via the list of callbacks in the
configuration object.
The "storage" source code files contained lots of stuff with "config" in
the name, but nothing named "storage". This was unlike every other part
of the firmware, so I renamed the files to "config".
Now the call to fusb_get_typec_current is made in the policy engine,
then passed to pdb_dpm_evaluate_typec_current. This is more consistent
with pdb_dpm_evaluate_capability, improving the PD Buddy DPM API.
That's right, I'm thinking about API design now for when I split the
code into a library and application.
Now that we cache the configuration location in the configuration code
itself, we don't need to cache it elsewhere. This makes the DPM code
for evaluating Type-C Current much cleaner.
The cfg_set variable was not necessary after all, since testing if
cfg == NULL works just as well as testing if !cfg_set. Actually a bit
better, since it prevents a null dereference we did by mistake before.
I should find out if the null derefernce hurts anything, because if it
does I should make a patch to the 1.1.x series to fix it.
The received Type-C Current advertisement is now kept in a global
variable which can be read by the command shell. When there are no PD
capabilities but there is Type-C Current, the typec_virtual PDO is
reported as the one and only PDO.
Since the spec says we Shall request no more power than we actually
need, we were violating the spec whenever the output was disabled in
Setup mode. This commit fixes that, requesting low current at 5 V when
the output is disabled.
We do play a little fast and loose with the MAX_CURRENT field, but
that's hard to avoid in a device like this. Well, we could always set
it to 5 A in Setup mode to be safe, but that's not necessarily right
either. At least it's still honest in Sink mode, which I consider more
important anyway.
It was never really necessary to update the source capabilities before
making sending a Request message. It was convenient though, since we
didn't store the previous Source_Capabilities message. Now we do, so
it's possible to make a new Request based on that.
This commit makes the Sink do just that. It doesn't follow the spec's
state diagram for this, but it's a minor change that works better with
this firmware's design, so I don't mind. There's a comment explaining
that too, so future folks won't be confused by it either.
When we were getting power from Type-C Current advertisements, we used
to not update the location of the configuration object. This was done
to save time between polling the Type-C Current, and was not a problem
until we started trying to do Power Delivery in Setup mode. As the
comment correctly said before, when we were trying to get power, the
location of the configuration object wouldn't change, so there was no
need to find its location more than once.
Now that the location of the configuration can change while we're
getting power, we need to check if that's happened. This can be easily
done by checking the configuration object's status. If the status is
not VALID, we get the location of the new configuration object.
It prints the most recently advertised PDOs in a reasonable format. The
types it doesn't know about are printed as hex so that someone
knowledgeable can still get the information they need. For now, it only
knows about fixed PDOs, so variable and battery PDOs will be shown as
hex.
Since this means we remember the most recent Source_Capabilities, it's
now becoming possible to send a new Request without sending a
Get_Source_Cap message first. That's not actually done yet, but I'd
like to do it that way. I'd also at some point like to make a
lower-current Request when the PD Buddy Sink's output is disabled, but
again, that's still to come.
Just as specified last night. This represents the completion of a big
part of the new interactive Power Delivery features of the shell.
Next up: printing the source's advertised PDOs.
The DPM used to always set the LED to indicate the PD status. This
caused fighting when the PD threads were run simultaneously with the
shell, making the LED show different things depending on what commands
the user ran. Not cool!
This commit adds a bool pdb_dpm_led_pd_status, which prevents the DPM
from setting the LED when set to false. This commit also sets it to
false before starting the PD threads in Setup mode, allowing the shell
to be in full control of the LED. Right on!
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.
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.
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.
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.