SFDQ Communication Protocol
Revision History
Rev. | Date | Author | Description of Changes |
X1 | Apr-23-2018 | L. Mills | First draft |
X2 | 2019-Apr-12 | K. MacCallum | Total refactoring |
X3 | 2019-Apr-15 | K. MacCallum | Adding encoder and temperature payloads |
X4 | 2021-02-25 | K. MacCallum | Adding more features to feedbackControl |
This document details the communication protocol that is used to control
the firmware on the SFDQ Main PCB
Abbreviation | Meaning |
CRC | cyclic redundancy check |
Command Packet | A packet sent by the Main Node in order to affect the state of a Second Node |
Host | Computer system which initiates communication with the receiver. This is also refered to as a Main Node |
LSB | least significant byte |
LSb | least significant bit |
MSB | most significant byte |
MSb | most significant bit |
Packet | A grouping of bytes comprising one complete data command or response. |
Response Packet | A packet sent by the Second Node in order to report the state of that node. |
bps | bits per second |
This protocol will be digital asynchronous serial, full duplex
communication bus.
A logic high or one will be represented by voltages greater than
approximately 2.5V. A logic low or zero will be represented by voltages
less than approximately 1V.
Data will be sent over the protocol at 115,200 bps, with the format; one
low start bit, 8 data bits, no parity and 1 high stop bit. Data bits are
sent LSb first.
There is one main node on each bus. This is the only node that can
broadcast a packet arbitrarily. The Main Node primarily issues Command
Payloads.
There can be one or more Secondary Nodes. These nodes will only
broadcast packets in response to packets directed at them. Otherwise
they remain silent. Only one packet shall be broadcast in response to a
Main Packet.
A Secondary Node primarily issues Response Payloads.
Data will be sent in packets either as a command or a response.
All bytes will be grouped as 32 bit words and defined as such in the
packet definitions. Words will be send LSB first, MSB last. This means
the packet will exist in memory in a “Little Endian” configuration.
A packet will be deemed incomplete if the concluding byte is not
received within 100ms of the previously received byte.
The Main Node will assume the Secondary Node did not correctly receive a
command if no response is received within 200ms.
Each packet will be protected by the CRC calculation described in crc1021.c
The CRC will be computed starting with word 2 (the third word of the
packet) and include all subsequent words. Once the last packet word has
been reached then the first word will be included. Word 1 (the second
word) will not be included in the CRC.
Words will be added to the CRC LSB first.
The maximum number of words that a packet can be is 4096. That includes
the two header words, so the maximum payload words is 4094.
Every packet will begin with the same header words, whether initiated
from a Main or Secondary Node.
Note that the Type column indicates the format of the data of the
particular word. Some words consist of multiple shorter words packetd
together. In that case, assume the fisrt type listed is aligned to the
most significant bits of the overall 32 bit word.
Word | Content | Type | Note |
0 | Start word | uint32 | 0xaa55aa55 |
1 | CRC/ Length | uint16, uint16 | CRC of all words of payloads, length of payloads in 32 bit words |
2 .. N | Payloads | uint32[] | All payloads, back to back |
The payloads section of the packet consists of one or more payloads
packed end to end.
The payload header consists of one 32 bit word. The data length portion
of the header indicates how many 32 bit words will follow, prior to the
subsequent payload.
Word | Content | Type | Note |
0 | Type, subtype, data length | uint16, uint8, uint8 | byte 3, 2 = payload type byte 1 = payload subtype byte 0: payload length (number of 32 bit words only of payload data) |
1 .. N | Payload data | uint32[] | Payload specific data. See individual payload definition for data description. |
This payload is sent by the host to indicate that all following payloads
are meant for the particular Node that matches that ID. If no ID payload
is present in a packet then all Second Nodes will respond.
This payload is sent by a Second Node at the start of every packet as
identification
The unique ID of the Microcontroller is a128bit code. Each 32 bit word
is exclusive-ORed together to create a relatively unique 32 bit ID.
If the ID payload is sent with no data then it is interpreted as a
request for ID.
Words | Content | Type | Note |
0 | type/ subtype/ Length | uint16, uint8, uint8 | 0x0000 00 01 |
1 | ID | uint32 | See above |
This packet is sent by both Main and Second Nodes
The time in 1ms increments since time reset. This will roll over every 1
hour. The time is the Second Node’s local time of the reception of the
first byte of the previously received host packet. The Second Node’s
local time is assumed to be synchronized to the received host time but
this may not be true.
When the host sends this packet it can omit the local time. The local
time will be the time - according to the Second Node’s timebase - of the
reception of the time payload from the host
Words | Content | Type | Note |
0 | type/ subtype/ Length | uint16, uint8, uint8 | 0x0001 00 0x |
1 | Host time | uint32 | time in milliseconds according to host |
2 | Local time | uint32 | Time in milliseconds according to Second Node. |
Acknowledges the reception of various commands.
Words | Content | Type | Note |
0 | type/ subtype/ Length | uint16, uint8, uint8 | 0x0002 00 01 |
1 | Ack Payload type | uint16, uint8, unused | type and subtype of payload being acknowledged. Final uint8 is always zero |
Indicates that the SFDQ could not process the payload.
Words | Content | Type | Note |
0 | type/ subtype/ Length | uint16, uint8, uint8 | 0x0003 00 01 |
1 | Ack Payload type | uint16, uint8, unused | type and subtype of payload being acknowledged. Final uint8 is always zero |
This command will not be used in version 121 and newer of SFDQ firmware.
Configures the IO of the SFDQ. The SFDQ will respond with a IO Response
payload.
Words 4 ... n are optional and configure the time constant of all
enabled ADC channels.
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x0004 00 0x |
1 | IO out | uint32 | IO output bitmask |
2 | IO dir | uint32 | IO direction bitmask. 0 = output, 1 = input |
3 | ADC | uint32 | ADC direction bitmask. 0 = not analog , 1 = ADC input |
4 | DACs | Uint16, uint16 | DAC0 = LSW, DAC1 = MSW |
5 | TC0 … TCn | Float32 | ADC time constants in seconds |
6 | |||
7 | |||
The IO pins are defined as follows for the X2 and X3 PCB revisions:
bit/index number | STM32 Pin | Connector.Pin | ADC? |
0 | A0 | CN1004.12 | Y |
1 | A1 | CN1004.2 | Y |
2 | A2 | CN1004.3 | Y |
3 | A3 | CN1004.26 | Y |
4 | A8 | CN1004.25 | |
5 | A11 | CN110.3 | |
6 | A12 | CN110.2 | |
7 | B0 | CN1004.17 | Y |
8 | B3 | CN1004.6 | |
9 | B5 | CN1004.15 | |
10 | B10 | CN1004.8 | |
11 | C0 | CN1004.4 | Y |
12 | C1 | CN1004.13 | Y |
13 | C4 | CN113.3 | Y |
14 | C5 | CN113.2 | Y |
This command will not be used in version 121 and newer of SFDQ firmware.
Requests an IO Response from the SFDQ. The SFDQ will respond with a IO
Response payload.
Words 4 ... n are optional and configure the time constant of all
enabled ADC channels.
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x0005 00 00 |
This command will not be used in version 121 and newer of SFDQ firmware.
This is the SFDQ’s response to an IO control payload. The response
includes a hash of its present IO configuration. If this is noticed to
have changed then the SFDQ should be reconfigured
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x0006 00 0a |
1 | IO val | uint32 | Value of all the IO pins. If input then this is the pin’s input value. If output then this is the pin’s output reg value. |
2 | IO dir | uint32 | see io request payload |
3 | ADC | uint32 | ADC direction bitmask. 0 = not analog , 1 = ADC input |
4..n | ADC values | float32[] | ratiometric ADC readings. The number corresponds to the number of 1s in the ADC mask of the IO Control payload LSb to MSb |
Configures a channel of stepper motor. Steppers can only be used as
outputs of the FeedbackControl system. Typically the feedback will be
configured as open-loop.
SFDQ will respond with an ack payload.
Note that only one channel can be configured as PWM. Up to 8 stepper
channels can be configured.
Because stepper motors are always driven from feedback channels, the
index for the stepper channel should match the feedback channel index
driving it
Note that travel of stepper motor is configured with the input limits of
the corresponding feedback channel
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x0007 00 0x |
Index, type, configBits | Uint8, uint8, uint16 |
Index: 0 – 8 Type: 0 = unconfigured, 1 = PWM half-bridge 2 = IO A/B 3= IO Step/Dir ConfigBits: see below |
|
1 | OutPin1, Outpin2 | undef16, uint8, uint8 | Outpins: see text below this table. Pins specified as port and pin as hex, top nibble = port (a,b,c = 0,1,2), botton nibble = pin (0 – 15), B, zeros. |
2 | Distance per step | float32 | This can be an arbitrary unit to convert steps to a meaningful value. |
3 | voltageFraction | float32 | PWM setting for outputs (0 < v < 1). Ony used for PWM type stepper, otherwise set to zero. |
... | |||
OutPinX must be specified only for type 1 and type 2 steppers. In type
IO A/B, OutPin1 is the A-phase signal and OutPin2 is the B-phase pin.
For type IO Step/Dir, OutPin1 is the step increment pin and OutPin2 is
the direction pin.
ConfigBits:
Bit # | Name | Notes |
1,0 | reduceWhenIdle | 00 = full drive when idle 01 = ½ drive when Idle 10 = ¼ drive when idle 11 = 0% drive when idle |
2 | zeroing | 0 = normal 1 = hold current phase and synch to present setpoint |
Response from the SFDQ upon receiving a stepper control payload
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x0009 00 0x |
1 | Index, state | uint8, uint8, Unused16 | UNCONFIGURED (0 ), DISABLED (1 ), IDLE (2 ), MOVING (3 ), HOMING_1 (4 ), HOMING_2 (5 ), HOMING_3 (6 ), HOMING_4 (7 ), ZEROING (8 ), EOT (9 ), HOME (10), AT_SETPOINT (11), |
2 | position | float | |
3 | velocity | float | |
... |
Description
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x000a 00 00 |
Description
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x000b 00 03 |
1 | Sfdq firmware version | uint32 | Sfdq firmware version that this firmware is based on |
2 | AppEdmsId | uint32 | EDMS ID of this application |
3 | AppVersion | uint32 | Verison of the app. |
This is inserted into any packet if an error occurred in the SFDQ. It
will continue to send the error until the error is acknowledged.
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x000c 00 0x |
1 | error | Uint8, uint8, uint16 | Error type, subtype, ID |
2..5 | debug data | uint32[4] | additional debug data. Not defined as anything in particular. Not used yet. |
Error type:
Subtype is an arbitrary number to give potentially more detail to the
type of error
ID is a 16 bit unique(ish) identifier to ensure errors are not
double-counted
Standard SFDQ error codes are:
Type | Name | |
0 | NULL_ERROR | |
1 | TEST_ERROR | |
2 | WATCHDOG_RESET | |
3 | SPI_QUEUE_OVERRUN | |
4 | SPI_SEND_FAILED | |
5 | SPI_CS_FAIL | |
6 | COMM_CRC_FAIL | |
7 | STEPPER_POSITION_FAILURE | |
8 | TX_BUFFER_OVERRUN_ERROR | |
9 | TX_TIMEOUT_ERROR | |
10 | RESET_ERROR | |
11 | APPLICATION_ERROR | |
The host will send this to acknowledge the last error received. It sends
the time with it as confirmation of the particular error it is
acknowledging.
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x000d 00 01 |
1 | error | Uint16, uint16 | Error type, ID |
Use feedback control system instead.
This is sent by the host to define a setpoint for one channel of thermal
control, this will configure the output channel and which thermistor
channel to use as an input.
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x000e 00 05 |
1 | setpoint | float | temperature setpoint in degrees Celsius (0C < T < 60C) |
2 | hardware channels | uint8, uint8, undefined16 | output channel, temperature channel, zeros |
3 | p | float | |
4 | i | float | |
5 | d | float | |
6 | max PWM | float | maximum PWM allowable |
Returns the value of all configured Thermal channels. The data will be
channel followed by value, and drive, repeated for each configured
channel
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x00f 00 03 | 06 | 09 ... |
1 | hardware channels | see above | see above |
2 | actual | float | actual temperature in degrees Celsius |
3 | output drive | float | real time drive to output to achieve |
etc | |||
A quick way to request status from the SFDQ without having to configure
it.
Words | Content | Type | Note |
0 | type/ subtype/ Length | uint16, uint8, uint8 | 0x0010 00 00 |
This sets one half bridge output as an output. Note that the underlying
PWM frequency is fixed in firmware and cannot be changed. This is due to
the specific output LC filter.
If this payload is sent without data, then it acts as a query.
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x011 00 03 |
1 | Channel, Output Mode | undef16, uint8,uint8 | Channel: 0..3 Output Mode:DISABLED(0), DC(1), SINE(2), SQUARE(3), TRIANGLE(4), STEPPER(5), COMPLEMENT(6) THERMAL(7) |
2 | setpoint | float | 0.0 - 1.0 linear |
3 | frequency | float | for output waveform if applicable |
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x012 00 03 |
1 | Channel, Output Mode | undef16, uint8,uint8 | see above |
2 | actual | float | 0.0 - 1.0 linear |
3 … N | More channels as above | ||
N + 1 | vrail | float | The voltage of the high side rail |
Configures a high res ADC channel of the SFDQ. Each HADC channel has two
differential inputs. Each can be configured to to one of 8 values.
Anywhere from one to all four ADC channels can be defined with this one
payload. Alternatively, each channel can be defined by a separate
payload.
The SFDQ will respond with an HADC Response payload.
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x0016 00 0n |
1..n | Enabled,Channel, Pos, Neg Input Config | uint8, uint8,uint8, uint8 | Enabled = 0 or 1 Channel = 0 .. 3 Input config = AIN0(0), AIN1(1), AIN2(2), AIN3(3), AIN4(4), TEMP_POS(5), TEMP_NEG(6), REF_POS(7), REF_NEG(8) |
The SFDQ will respond with an HADC Response payload.
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x0017 00 00 |
Returns the value of all configured HADC channels. The data will be
channel config followed by value, repeated for each configured channel
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x0018 00 00 | 02 | 04 | 06 | 08 | 0A |
1 | ADC Channel, Pos, Neg Input Config | undef8, uint8,uint8, uint8 | Channel = 0 .. 4 Input config = AIN0(0), AIN1(1), AIN2(2), AIN3(3), AIN4(4), TEMP_POS(5), TEMP_NEG(6), REF_POS(7), REF_NEG(8) |
2 | Value | float | value from 0.0 to 1.0 |
3 | ADC Channel, Pos, Neg | see above | |
4 | Value | ||
etc |
Returns the value of the IMU
Also can be used as an IMU request payload, in which case no data is
required.
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x0019 00 3 |
1 | Acc X | float | |
2 | Acc Y | float | |
3 | Acc Z | float | |
etc |
This sets up ADC channels to work with thermistors. It is assumed that
the thermistor is wired to ground with a pull-up resistor. The pull-up
shall be the same value as the R0 value of the thermistor. R0 is usually
the thermistor value at 25 C, although the coefficients can be
calculated for any known value
Each thermistor is configured with the coefficients of a modified
Steinhart-Hart equation.
1/T = c0 + c1*ln(Rt/R0) + c2*ln(Rt/R0)^2 + c3*ln(Rt/R0)^3
Note that if the beta and R0 of the thermistor is known then:
c0 = 1/T0
c1 = 1/beta
c2 = 0
c3 = 0
where T0 is the temperature that R0 is known for.
Up to 8 channels can be configured.
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x001a 00 0x |
1 | channel setup | uint8, uint8,undefined16 | Temperature index (0 - 7), Input ADC channel, zeros |
2 | c0 | float | The offset term of the S-H equation |
3 | c1 | float | The linear term of the S-H equation |
4 | c2 | float | The quadratic term of the S-H equation |
5 | c3 | float | The cubic coefficient of the S-H equation |
6, 7 ... | more channels | ... | Up to 8 channels can be configured |
If no data is provided in this payload then it will act as a request for
a response packet without changing the current configuration.
This is the response of the SFDQ when there are thermistors configured.
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x001b 00 0x |
1 | channel setup | uint8,undefined24 | Temperature index,zeros |
2 | Temperature | float | Degrees Celsius |
3, 4 ... | more channels | ... | All configured channels will be sent |
This payload configures two digital inputs to be interpreted as a
quadrature encoder channel. Up to four channels can be defined. Each
channel is defined by the two inputs and a scale factor. The scale
allows the channel to read out in useful, user-specified units.
Up to four channels can be configured
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x001c 00 0x |
1 | channel setup | uint8, uint8, uint8, undef8 | Index, Quadrature Phase A: port and pin as hex, top nibble = port (a,b,c = 0,1,2), botton nibble = pin (0 – 15), B, zeros |
2 | scale | float | distance/count |
3, 4 ... | more channels | ... | Up to 4 channels can be configured |
This payload is sent by the SFDQ whenever encoders are configured. The
response is in the user specified scale.
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x001d 00 0x |
1 | channel setup | uint8, undefined24 | Index |
2 | position | float | distance/count |
3, 4 ... | more channels | ... | Up to 4 channels can be configured |
This payload configures a closed-loop feedback system between an input
signal and an output. This assumes a control system consisting of a
digital biquad filter.
The sample rate is 1kHz.
The z transform is gives us an equation of the form:
y[n] = c0*x[n] + c1*x[n - 1] + c2*x[n - 2] - d1*y[n - 1] -
d2*y[n - 2]
It is expected that that the SFDQ will respond with a Feedback Response
Payload.
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x001e 00 0x |
1 | channel setup | uint4, uint4, uint8, uint8, uint8 | Channel, Input type, input index, output type, output index |
2 | c0 | float | |
3 | c1 | float | |
4 | c2 | float | |
5 | d1 | float | |
6 | d2 | float | |
7 | Min out | float | Output minimum drive limit |
8 | Max out | float | Output maximum drive limit |
9 | Min In | float | Input minimum allowable value |
10 | Max in | float | Input maximum allowable value |
11 | ConfigBits, MinInputPin, MaxOutputPin | Undef8, uint8, Uint8, uint8 | Config bits: see below Defined limit pins that when asserted prevent further travel in that direction. Bottom 4 bits are pin number, bits 4,5 are port, top bit means invert. 0xff means null pin |
10..x | more channels as above |
If no data is provided in this payload then it will act as a request for
a response packet without changing the current configuration.
Valid input types are as follows.
Index | Name | Notes |
0 | NULL | Not configured |
1 | ADC | Selects the index of a low res ADC for input to the feedback system |
2 | Temperature | Selects a temperature channel as an input. See the Temperature payload |
3 | Encoder Position | Selects an encoder channel as an input. See the Encoder payload |
4 | Encoder Velocity | ditto |
5 | Hi Res ADC | Index specifies channel |
6 | Open loop | The output will be driven by the target setpoint alone without negative feedback from an input |
7 | Brushless Motor | 0 = hall position, 1 = velocity |
8 | Rx Application Data | Index specifies which element. This is app data array received from the host |
9 | Tx Application Data | Index specifies which element. This is local app data array being sent to host |
Valid output types are as follows.
Index | Name | Notes |
0 | NULL | Not configured |
1 | PWM UNIPOLAR | Uses a high power output as an output for this feedback loop. Zero output is zero volts. |
2 | 3 Phase Motor | The output of this loop is the drive to a 3 phase motor. This is not implemented yet. |
3 | DAC | Use a DAC channel for an output. This is not implemented yet. |
4 | PWM BIPOLAR | Uses a high power output as an output for this feedback loop. Assumes a zero reference at mid rail. Zero output is ½ Vrail. |
5 | STEPPER | Uses the stepper motor position as an output. This is intended for use when direct trajectory control of stepper position is desired and the input type as Open Loop. If stepper is to be used as a closed loop feedback output then STEPPER_VELOCITY is likely the better choice. |
6 | FEEDBACK | Uses another feedback channel input as the output of this channel. The output index specifies channel. If the output channel is a higher number channel than this one then there will be no delay in computation |
7 | FEEDBACK_MAX | The output of this loop is the max output parameter of another channel. This causes that channel to work as normal except when it causes this channels feedback to be exceeded. |
8 | PORT_EXPANDER | Use a port expander digital output as the output. This means the output can only either be 0 or 1. The output index is top 4 bits being port expander index and bottom 4 bits is pin number. |
9 | Application Data | Use an element of the application data as the output. |
10 | SOFT PWM | Use a software PWM as an output |
11 | STEPPER_VELOCITY | The feedback output controls the velocity of the stepper motor module. This is a good choice if the stepper is to be used in a closed loop control system. |
Config Bits:
Bit | Name | Description |
0 | Passthrough | 0 – biquad input = (setpoint – actual), 1 – biquad input = (actual) |
2,1 | units | Indicates whether input units are circular or linear (whether they wrap or not) 0b00 = linear 0b01 = degrees 0b10 = radians 0b11 = N/A |
3 | TBD | |
4 | TBD | |
5 | TBD | |
6 | TBD | |
7 | TBD |
This payload configures the high power outputs in a 3 phase motor drive
configuration. This assumes 3 hall sensor inputs. Output channels 1,2
and 3 are assumed. The digital IO channel index of each hall sensor is
specified.
Note that some experimentation as to which sensor to use for which phase
may be required.
The phases per rev value is the number of sensor states that occur
during one revolution of the motor. If this value is set to zero then
the brushless motor system is disabled
It is expected that that the SFDQ will respond with an Brushless
Response Payload.
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x001f 00 02 |
1 | Setup | uint8, uint8, uint8, undef8 | Sensor A input: port and pin as hex, top nibble = port (a,b,c = 0,1,2), botton nibble = pin (0 – 15), Sensor B input, Sensor C input, MSB not used |
2 | Phase cycles per rev | float | Indicates the number of phase cycles per revolution of the motor. Can be negative to reverse the relationship between drive and direction |
3 | Phase offset | Float | This is optional. It’s in degrees. The amount to offset the winding phase after computing from hall sensors |
4 | Phase advance | float | This is optional. It’s in degrees/Hz. The amount to advance the phase in the direction of motion. For instance if the value is 3 then the phase will be advanced 30 degrees at 10 Hz drive frequency. |
Sets up the control inputs to the feedback module as a trapezoidal
trajectory. Multiple trajectories can be configured sequentially and
queued. Up to 10 trajectories can be queue.
0 | Payload ID/ Length | uint16/ uint16 | 0x0020 00 0x |
1 | Channel | uint8, uint8, undef16 | Feedback channel (1 - 4), indep or not (0 = independent; 1 = multi traj move) |
2 | Setpoint position | float | this is the target “location” that the trajectory is trying to achieve |
3 | Setpoint speed | float | this is the target speed that the position will change by |
4 | setpoint time | uint32 | the host time that the trajectory shall be completed by. Note that this implies a constant acceleration. This is in microseconds. |
4 - | additional legs of trajectory and other channels configs | ||
This is the response from the SFDQ if there is a trajectory in progress
0 | Payload ID/ Length | uint16/ uint16 | 0x0021 00 0x |
1 | Channel | uint8, undef24 | Feedback channel (1 - 4) |
2 | current setpoint | float | This is the location that the feedback channel is currently aiming for |
3 | Trajectory queue length | uint32 | The number of steps in the present trajectory queue |
4 | End time | uint32 | The time that the last trajectory will be ending |
5 - | |||
A quick way to request status from the SFDQ without having to configure
it.
Words | Content | Type | Note |
0 | type/ subtype/ Length | uint16, uint8, uint8 | 0x0022 00 00 |
A quick way to send and request applicaiton specific data. This is for
derivative firmware of the SFDQ where a quick easy way is required to
send custom data to and inspect internal data within the MCU. This could
be use for debugging or for custom purposes specific to the derivative
application. The meaning of the data will depend on the specific
application. The number of data values returned will also be application
specific.
Application Data can be considered an implementation of the blackboard
pattern. Note that it is assumed that data sent by the controller is a
different blackboard from the response from the peripheral.
If this payload is sent without data, it should be interpreted by the
Peripheral as a request for a payload to be sent back in response.
Words | Content | Type | Note |
0 | type/ subtype/ Length | uint16, uint8, uint8 | 0x0023 00 0x |
1 … N | Application Data | float | Data specific to an application to send. This can be 0 to N – 1 words |
A quick way to send application specific data. This is for derivative
firmware of the SFDQ where a quick easy way is required to inspect
internal data within the MCU. This is likely used only for debugging and
the meaning of the data will depend on the specific application. The
number of data values returned will also be application specific.
Application Data can be considered an implementation of the blackboard
pattern. Note that it is assumed that data sent by the controller is a
different blackboard from the response from the peripheral.
Note that the peripheral can response either with a Response Payload ID
or with a Send Payload ID. They should be interpreted the same by the
Controller.
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x0024 00 0x |
1 … N | Applicaiton Data | float | Data specific to an arbitrary application |
This payload triggers the SFDQ firmware to pass control to the STM32F446
built-in bootloader. This will cause the SFDQ to switch to STM32 UART
Bootloader protocol. The switch of control will occur a few seconds
after a Firmware Program Acknowledge Payload is sent. It is up to the
user to correctly complete the firmware programming process. If this is
not done, then the unit may be bricked. This payload will only be
processed if the specific SFDQ ID is used for a packet. An SFDQ will not
respond if there was no specific – and matching - ID Payload in the
packet containing the Firmware Program Payload
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x0025 00 0x |
The SFDQ firmware will respond with this payload. Within a few seconds
of sending this payload the firmware will pass command to the STM32
built in bootloader.
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x0026 00 01 |
1 | confirm | Uint32_t | 0 to acknowledge but not confirm 1 to confirm. When this is received then any moment the bootloader will start |
Requests data to be written to EEPROM. It is expected that firmware will
only act on first received payload but will respond to all of them. It
is expected that the host will continue sending write requests until a
response confirms that the data has correctly been received, programmed
and read back. It is expected that the firmware will not initiate an
EEPROM write if there is no data value change needed. It is also
expected that the firmware will not initiate a further write until the
first write completes.
Words | Content | Type | Note |
0 | type/ subtype/ Length | uint16, uint8, uint8 | 0x0027 00 0x |
1 | Address/ number | uint16, uint16 | Address is starting address. Number is number of words beyond start address (inclusive) |
2 .. n | Data to be written | uint32 | Data should be in whatever 32 bit format is appropriate for a specific application. |
Requests the data from the specified address and number of words.
Words | Content | Type | Note |
0 | type/ subtype/ Length | uint16, uint8, uint8 | 0x0028 00 00 |
1 | Address/ number | uint16, uint16 | Address is starting address. Number is number of words beyond start address (inclusive) |
This will always respond with the current RAM proxy of the firmware
EEPROM contents. This is assumed to be a RAM (volatile) copy of the
EEPROM contents that is regularly updated from the actual EEPROM.
If the requested starting address is beyond the range of the EEPROM, the
peripheral will respond with a number of zero and the address indicating
the total available size of the EEPROM.
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x0029 00 0x |
1 | Address/ number | uint16, uint16 | Address is starting address. Number is number of words beyond start address (inclusive) |
2… N | Data | uint32 | Data from specified address and specified number of words. |
This is the response to the feedback control payload.
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x002a 00 0x |
1 | Sample time | float | Time in seconds between processing feedback samples |
2 | Channel Status |
Uint8, uint8, uint8, uint8 | Channel, TBD, TBD, TBD |
3 | Current position | float | The actual position of this channel |
4 | Current output | float | The output of this channel |
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x002b 00 0x |
1 | Speed |
float | Rev/s |
2 | position | float | The positon of the rotor in revolutions. This will be NaN if the motor is disabled |
3 | drive | float | The current drive value. This will be NaN if the motor is disabled |
Configures the IO of the SFDQ. The SFDQ will respond with a IO Response
payload.
Words 4 ... n are optional and configure the time constant of all
enabled ADC channels.
The SFDQ will respond with a GPIO Response Payload.
Each port consists of 16 pins. Each pin is configured with 4 bits.
# | Bit 3 | Bit 2 | Bit 1 | Bit 0 | Configuration | |
0 | 0 | 0 | 0 | 0 | Input 0 | There are two of these for the response packet |
1 | 0 | 0 | 0 | 1 | Input 1 | |
2 | 0 | 0 | 1 | 0 | Output Logic 0 | Sets it as an output and clears the output reg bit |
3 | 0 | 0 | 1 | 1 | Output Logic 1 | Sets it as an ouput and sets the output reg bit |
4 | 0 | 1 | 0 | 0 | Analog | Used for ADCs and DACs |
5 | 0 | 1 | 0 | 1 | AF 1 | |
6 | 0 | 1 | 1 | 0 | AF 2 | |
7 | 0 | 1 | 1 | 1 | Output, do not set state | Sets it as an output but does not affect the output register. This allows for firmware to set it, such as LED100, LED101 |
8 | 1 | 0 | 0 | 0 | No Effect | Does not change this IO pin from whatever state it is in. This allows application firmware to control the pin however it chooses. |
9 | 1 | 0 | 0 | 1 | Input Pull up 0 | These are inputs with pull ups |
10 | 1 | 0 | 1 | 0 | Input Pull up 1 | ditto |
11 | 1 | 0 | 1 | 1 | Not Defined | |
12 | 1 | 1 | 0 | 0 | Not Defined | |
13 | 1 | 1 | 0 | 1 | Not Defined | |
14 | 1 | 1 | 1 | 0 | Not Defined | |
15 | 1 | 1 | 1 | 1 | Not Defined | |
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x002c 00 0x |
1 | Pins A0 - A7 | uint32 | Output config LSb -> pin 0 |
2 | Pins A8 - A15 | uint32 | ditto |
3 | Pins B0 - B7 | uint32 | ditto |
4 | Pins B8 - B15 | uint32 | ditto |
5 | Pins C0 - C7 | uint32 | ditto |
6 | Pins C8 - C15 | uint32 | ditto |
Bit numbers below 32 (exclusive) are contained in the second word.
Higher bit numbers (32 and up) are contained in the first word sent.
The following table is for the X5 revision of the SFDQ hardware
STM32 Pin | Connector.Pin(s) | Default f’n | Can be ADC? | Alternate Function | Is editable? |
A0 | CN1000.A8 | GPIO | Y | ||
A1 | CN1000.A5 | GPIO | Y | ||
A2 | CN1000.A4 | GPIO | Y | ||
A3 | CN1000.A3 | GPIO | Y | ||
A4 | CN1000.A2 | DAC1 | Y | DAC1 | |
A5 | CN1000.B2 | DAC2 | Y | DAC2 | |
A6 |
CN1000.A14 | GPIO | Y | ||
A7 | CN1000.A13 | GPIO | Y | ||
A8 | CN1000.B15 | GPIO | I2C3 | ||
A9 | CN1000.B16 | USART1 | USART1 | N | |
A10 | CN1000.B17 | USART2 | USART1 | N | |
A11 | CN1000.B18, CN110.3 | GPIO | |||
A12 | CN1000.B19, CN110.2 | GPIO | |||
A13 | N/A | JTMS-SWDIO |
JTMS-SWDIO | ||
A14 | N/A | JTCK-SWCLK |
JTCK-SWCLK | ||
A15 | CN1000.B20 | GPIO | SPI3 | ||
B0 | CN1000.B5 | GPIO | Y | ||
B1 | CN1000.A7 | GPIO | Y | ||
B2 | CN1000.A6 | LED100 | LED100 | ||
B3 | CN1000.A15 | GPIO | SPI3 | ||
B4 | CN1000.A20 | GPIO | SPI3, I2C3 | ||
B5 | CN1000.A21 | GPIO | SPI3 | ||
B6 | CN1000.A22 | GPIO | IMU_INT | ||
B7 | CN1000.B22 | GPIO | |||
B8 | CN1000.A17 | I2C1 | I2C1 | ||
B9 | CN1000.A16 | I2C1 | I2C1 | ||
B10 | CN1000.B6 | LED101 | LED101, I2C2 | ||
B11 | N/A | N/A | N/A | N/A | N |
B12 | CN1000.B7 | GPIO | SPI2, I2C2 | ||
B13 | CN1000.B8 | GPIO | SPI2 | ||
B14 | CN1000.B9 | GPIO | SPI2 | ||
B15 | CN1000.B10 | GPIO | SPI2 | ||
C0 | CN1000.A12 | GPIO | Y | ||
C1 | CN1000.A11 | GPIO | Y | ||
C2 | CN1000.A10 | GPIO | Y | ||
C3 | CN1000.A9 | VHS ADC | Y | VHS ADC | |
C4 | CN1000.B3, CN113.3 | GPIO | Y | ||
C5 | CN1000.B4, CN113.2 | GPIO | Y | ||
C6 | CN1000.B11 | TIM3 | TIM3 | N | |
C7 | CN1000.B12 | TIM3 | TIM3 | N | |
C8 | CN1000.B13 | TIM3 | TIM3 | N | |
C9 | CN1000.B14 | TIM3 | TIM3 | N | |
C10 | CN1000.B21 | USART3 | USART3 | ||
C11 | CN1000.A18 | USART3 | USART3 | ||
C12 | CN1000.A19 | GPIO | |||
C13 | GPIO | ||||
C14 | GPIO | ||||
C15 | GPIO |
This is the SFDQ’s response to a GPIO control payload. This responds
with the same group of 4 bits as the GPIO control payload
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x002d 00 0x |
1 | Pins A0 - A7 | uint32 | Output config LSb -> pin 0 |
2 | Pins A8 - A15 | uint32 | ditto |
3 | Pins B0 - B7 | uint32 | ditto |
4 | Pins B8 - B15 | uint32 | ditto |
5 | Pins C0 - C7 | uint32 | ditto |
6 | Pins C8 - C15 | uint32 | |
The command configures the low res ADCs and DACs.
If only the first word is sent but no others then this simply requests
an analog response payload
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x002e 00 0x |
2 | Enable | uint16/uint16 | DAC1,0 manual, DAC1,0 enable, ADC15:0 enable |
3 | DACs | Uint16, uint16 | DAC0 = LSW, DAC1 = MSW |
4 | TCx | Float32 | ADC time constants in seconds of enabled ADCs. Disabled ADCs are assumed to be not in this list |
5 | Scale | float32 | Scale factor to be applied to enabled ADCs. Disabled ADCs shall not be listed |
6 | Offset | float32 | Offset to be applied to enabled ADCs. Disabled ADCs shall not be listed. Offset is subtracted from raw ADC, then the difference is scaled. |
DAC0,1 manual bits indicate when clear that the DAC outputs will be set
by the feedback controller and not by the analog control payload.
This is the SFDQ’s response to an IO control payload. The response
includes a hash of its present IO configuration. If this is noticed to
have changed then the SFDQ should be reconfigured
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x002f 00 0x |
2 | Enable | uint16/uint16 | DAC1,0 enable, ADC15:0 enable |
3..n | ADC values | float32[] | ratiometric ADC readings. The number corresponds to the number of 1s in the ADC mask of the IO Control payload LSb to MSb |
Requests a GPIO response packet and Analog response packet without
setting anything
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x0030 00 01 |
Commands the SFDQ to change to a new baud rate. SFDQ will always start
in 115200 but can be changed to higher rates.
SFDQ will respond with an identical payload in reply. The response baud
rate will not reflect the change until the SFDQ has initiated the
change. The actual change may happen a few seconds after this
confirmation.
4identical payloads must be received by an SFDQ before it will change
rates.
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x0031 00 02 |
1 | Baudrate | uint32 | Baud rate. |
Used to configure I2C port expander ICs.
This payload is sent by the host and the SFDQ will reply with the same.
The port expanders will have an implicit index based on the order the
config words are sent in this payload. The first, second and nth config
words will be port expander ideces: 0, 1, n.
The firmware may have a limit to how many port expanders are possible.
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x0032 00 0x |
1 .. n | Config | Uint8, uint3, uint3 ... uint3 | Port config, pin 7 config, pin 6 config … pin 0 config |
Bitfield with the following info
Bits 7,6 = i2c bus num. Valid entries 1,2,3.
Bits 5,4,3 = type. Valid entries: 0 = TCA9534, all others TBD.
Bits 2, 1, 0 = address selector. Valid entries: 0, 1, 2, 3, 4, 5, 6, 7.
Bit Values | ||
000 | Input 0 | Configures pin as input. If this is a response, then this indicates that the pin is measuring low, otherwise has no effect. |
001 | Input 1 | Configures pin as input. If this is a response, then this indicates that the pin is measuring high, otherwise has no effect. |
010 | Output, clear | Configures pin as output and clears the output reg. If reply from SFDQ then this means the port pin output is low. |
011 | Output, set | Configures pin as output and sets the output reg. If reply from SFDQ then port pin is set. |
100 | Output, leave alone | Ensures pin is configured as an output but does not change the state of the output reg |
101 | TBD | |
110 | TBD | |
111 | TBD |
Configures the software generated PWM channels. Only enabled channels
need to be specified.
If there is not data sent then this only triggers a response payload
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x0033 00 0x |
1 | Index, type, type param, pins | Uint4, uint4, uint4, unused4, uint8, uint8 | Type = 0 – unconfigured Type = 1 – PWM Type = 2 – One Shot Type = 3 – Follower For Follower, indicates which channel to follow. Otherwise N/A top nibble = port (a,b,c = 0,1,2), botton nibble = pin (0 – 15) Top bit of trigger indicates rising (0) or falling (1) edge 0xff indicates null |
2 | param | float | For PWM indicates frequency in Hz: can be 0 to 1000. For Follower indicates gain: can be –inf to +inf. For One shot: on time in seconds. |
3 .. n | Repeat words 1 and 2 for each channel | ||
Only non-unconfigured channels will be listed
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x0034 00 0x |
1 | Index, type, type param, pins | Uint8, undef24 | |
2 | param | float | For PWM and follower mode indicates duty cycle. For one shot mode indicates time. |
3 .. n | Repeat words 1 and 2 for each channel | ||
Words | Content | Type | Note |
0 | Payload ID/ Length | uint16/ uint16 | 0x0035 00 0x |
1 | Index, type, type param, pins | Uint8, undef24 | |
This is intended to setup an I2C or SPI peripheral. It is intended to be
general but we’ll see.
This is a work in progress. For now, list all known drivers and their
parameters and see if they can be generalized
Chip | Parameters | ||||
SFM3019 | I2C num, reset pin, flow app data index, temperature app data index, o2mix, sample time? |
||||
SFM3000 | I2C num, reset pin, flow app data index, temperature app data index, sample time? | ||||
AMT22 | Index, SPI num, CS pin, app data index, scale, offset | ||||
AS5048A | Index, SPI num, CS pin, app data index, scale, offset | ||||
MAX3186 | Index, SPI num, CS pin, app data index, | ||||