I took an accurate reading of the current consumed by the PD Buddy Sink
in various states, and found that the lowest current I could safely set
as the amount it requests when the output is turned off was 30 mA.
I therefore changed it to request this lower current to avoid asking for
more than we need.
(cherry picked from commit 88766783de)
A new bit was added to the Source Fixed Supply PDO in PD 3.0, saying
whether the source supports unchunked extended messages. It's not
really relevant to the PD Buddy Sink since it itself doesn't support
them, but users might want to know and it's very little work to print
it, so now it does.
It needs to be if I want to be able to have several ports controlled by
one MCU. It's set as part of the FUSB configuration, not in the INT_N
struct, since the latter isn't user-initialized and may disappear
entirely in the future.
Technically I updated to a development version somewhere between 17.6.3
and 17.6.4, but I don't doubt its stability.
This is a good update because I'd like users of the library to be
confident that it works with the latest version of ChibiOS.
Interestingly, none of the changes I made were in the library code, so
it did before, but now I know for sure.
I'm unclear as to whether I can now get rid of the INT_N thread in favor
of a pin interrupt. I'll have to see if I can, or if that will have to
wait for still more ChibiOS updates.
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.