It's all right with me if people use my implementation of USB Power
Delivery in anything. This will make writing firmware for the PD Buddy
Dev a lot more reasonable, once it exists.
After much poking around, I finally figured out how to make this work!
The problem was that the ChibiOS initialization code had disabled
interrupts before the __early_init function was run, making the
bootloader not work despite my best intentions. This was fixed by
enabling interrupts just before jumping to the bootloader. This in turn
required changing to GNU-flavored C11 to include an inline assembly
instruction.
Due to an error when adding the different current definition types, the
flags configuration field never said (none). Now it does once again,
and there's no trailing space when printing flags.
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.
This commit adds the `set_p` command for setting power, and the `p`
configuration field for reading it back. There is no support for making
requests based on power yet (the field is still interpreted as a current
unconditionally).
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.
It's pretty easy to implement, it turns out! A new event gets sent to
the protocol TX thread when the PE is starting an AMS. Just before the
message is transmitted, the TX thread checks if that event was received,
and if it was, it waits for the Type-C Current to look like 3.0 A
(SinkTxOk) before proceeding. Now, to the best of my knowledge, we're
actually doing Power Delivery 3.0 as correctly as we ever did Power
Delivery 2.0, which is to say, everything is right except we don't do
BIST.
According to the USB Power Delivery Specification Revision 3.0, Version
1.1, section 7.2.3.1, we're not required to enter Sink Standby when
changing the negotiated voltage on a single PPS APDO. Now we don't.
This is done in the PE, so the DPM doesn't have to lift a finger to
avoid the unnecessary standby.
Now if we make a request for a PPS APDO, the SinkPPSPeriodicTimer is
run, forcing a new request to be made every 10 s. This is important
because without it, the Source Shall perform a Hard Reset 15 s after the
request is made.
This state requires that the DPM be informed of the receipt of a
Not_Supported message. Some DPMs may not need to do this, so the new
dpm.not_supported_received function is optional.
Now when a part of a chunked extended message is received, the
ChunkingNotSupportedTimer is run. When it times out, we transition to
PE_SNK_Send_Not_Supported. Just like the spec says.
In PD 3.0, there's a new control message, Not_Supported, which is sent
unsurprisingly when unsupported messages are received. Basically, every
time we had sent a Reject message in PD 2.0, we're now supposed to send
Not_Supported instead. As of this commit, that's exactly what we do.
Set the Specification Revision field to 2.0 or 3.0
Based on the first message sent from the Source, we now set the
Specification Revision field of our messages to 2.0 or 3.0. We don't do
anything else 3.0 yet though, so it's a bit of lie, but this is a
necessary first step.
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.
Now we're using millivolts internally rather than centivolts. This
might be a good choice if USB-IF decides to make even more finely
adjustable voltages in the future. If they don't, well, it still allows
voltages up to 65.535 V, which is beyond what some electrical codes
consider "low voltage", so I doubt USB will ever exceed that.
Now the CURRENT_DEFN field of the flags halfword in the pdbs_config
object is actually used, both when printing configuration objects and
when setting a current. It never takes any value other than 0 (_I) yet,
but this easily extends to power and resistance.
This commit adds the toggle_hv_preferred command, and makes printed
configuration objects show the state of the HV_Preferred flag. The
flag still isn't used by anything else yet though.
This commit changes back to the original plan of having one set_vrange
command that sets both the vmin and vmax at once, instead of separate
set_vmin and set_vmax commands. This will allow checking that the range
is valid every time it's set instead of having to wait until
configuration is written to flash.
Due to a typo, it would clear all bits except the HV_Preferred bit.
This commit fixes the bug, and refactors the clearing code to make typos
like this harder to make.
Firmware 1.2.0 will have more configuration flags than previous
versions. This commit adds macros for those flags. There's also a
field added to the flags halfword that says whether a current, power, or
resistance is configured, so this commit makes the clear_flags command
not modify that field.