File format specification of configuration definition

this describes the possible elements of a configuration description in json format.

Table of Contents

File format specification of configuration definition	1

Kinds of Settings	2

general settings	3

peripheral settings	4

driver layer	5

signal names	6

Example	7

vendor_name	8

chip_name	9

clock group	10

digital_output group	11

type	12

pad	13

invert	14

digital_input group	15

pad	16

analogue_input (ADC) group	17

analogue_output (DAC) group	18

Timer group	19

RTC group	20

UART group	21

bits_per_packet	22

parity	23

stop_bits	24

baud_rate	25

hardware_flow_control	26

receive_buffer_size	27

send_buffer_size	28

SPI group	29

QSPI group	30

SDIO group	31

I2C group	32

I3C group	33

I2S group	34

CAN group	35

USB group	36

Watchdog group	37

Random_Number group	38

CRC group	39

... group	40

The json format is defined here: https://www.json.org/json-en.html

All elements not listed as essential are optional. Being optional means that they can be missing and the configuration is still valid.

If elements that describe a peripheral are not present than that peripheral will not be used. No initialization code for that peripheral will be generated.

If elements that define general settings are missing then the default value for that setting is used. The section describing the element will also state the default value.

The essential elements are :

vendor_name

chip_name

Kinds of Settings

The settings defined in this file cover different areas.

general settings

peripheral settings

driver layer

signal names

general settings

general settings affect the whole project. These settings are general configurations and switches to enable additional features or to select modes for the project.

peripheral settings

peripheral settings are definitions of peripheral configuration. Examples are Pad names, enabled or disabled functionality and Speed settings.

driver layer

The peripherals can be used in different ways (polling, interrupt, DMA) and for different purposes (“send text”, “send binary packets”, “fixed length packet”, “variable length packet”) and implementing these functionality is device independent. This configuration file should therefore only give guidance to MBSP and select the API style the user want's to use.

signal names

The user shall not be bothered with the details of the used peripheral. The user should therefore not depend on peripheral names (“SPI0”, “UART3”, “GPIO PA9”, ..) but refer to these resources by names that make sense for the user. These names are defined in this file.

Example

{
"vendor_name": "Geehy",
"chip_name": "APM32F411VC",
"digital_output": {
"green_led": {
"type": "push pull",
"pad": "PA3"
}
}
"SPI": {
...
}
}

Keys like *digital_output* and *SPI* represent group names and are taken from a predefined set of group names understood by MBSP. Keys nested within them are arbitrary user-defined names for a instance in that group. In those instances the keys are from the defined set specific for that group.

vendor_name

Name of the company that sells the micro controller. As listed on chipselect.org

type: string

chip_name

model number of the micro controller.

type: string

Model number is truncated so that it only contains relevant differences for code generation: flash and ram sizes are relevant, temperature range or package are not.

clock group

configuration of the used clocks

TBD

digital_output group

This group contains all digital output signals.

Each signal is a sub group with the signal name as the group name.

"digital_output": {
"green_led": {
"type": "push pull"
"pad": "PA3"
}
}

type

defines what type of output mode should be used. Type can be:

push pull

open drain

type: enum

default: push pull

pad

defines the chip pad that the signal should be output on.

type: string

default: no default possible

invert

If this setting is set to “on” then turning this output “on” will generate a Low (Gnd) signal. Turning it “off” will generate a High (Vcc) level.

If this setting is set to “off” (=default) then turning this output “on” will generate a High (Vcc) signal. Turning it “off” will generate a Low (Gnd) level.

type: string

default: “off”

digital_input group

This group contains all digital input signals.

Each signal is a sub group with the signal name as the group name.

pad

defines the chip pad that the signal should be read from.

type: string

analogue_input (ADC) group

TBD

analogue_output (DAC) group

TBD

Timer group

TBD

RTC group

TBD

UART group

This group defines all used UART interfaces.

Each UART is a sub group with the UART name as the group name.

"UART": {
"debug_uart": {
"pads": {
"TX": "PA5",
"RX": "PA6",
"CTS": "PA7",
"RTS": "PA15"
}
"bits_per_packet": "8"
"parity": "None"
"stop_bits": "1"
"baud_rate": "115200"
"hardware_flow_control": "no"
"receive_buffer_size": "100"
"send_buffer_size": "500"
}
}

bits_per_packet

defines the number of data bits. Possible values are:

7

8

9

type: enum

default: 8

parity

defines the parity bit. Possible values are:

None : no parity bit used.

Odd : the parity bits value makes sure that the packet contains an odd number of bits with value “1”.

Even : the parity bits value makes sure that the packet contains an even number of bits with value “1”.

type: enum

default: None

stop_bits

defines the number of stop bits. Possible values are:

1

1,5

2

type: enum

default: 8

baud_rate

defines the number of bits send per second.

type: int

default: 115200

hardware_flow_control

defines if the Request to Send (RTS) and Clear to send (CTS) signals should be used for flow control. Possible values are:

no (RTS and CTS pins are not used.

RTS only

CTS only

yes (RTS and CTS signals are used)

type: enum

default: no

receive_buffer_size

defines the number of bytes in the receive buffer of the driver.

type: int

default: 100

send_buffer_size

defines the number of bytes in the send buffer of the driver.

type: int

default: 500

SPI group

"SPI": {
"encoder_spi": {
"pads": {
"SCK": "PA5",
"MISO": "PA6",
"MOSI": "PA7",
"NSS": "PA15"
}
"role": "master",
"communication_mode": "duplex",
"frame_format": "motorola",
"clock_polarity": "idle_low",
"clock_phase": "sample_on_leading_edge",
"bit_order": "msb_first",
<del>frame_size: 8</del>
"baud_rate": "10Mhz",
"crc": "enabled",
"crc_polynomial": <del>7</del>
}
}

encoder_spi: the user-defined name of the SPI peripheral. It is possible to call it SPI1, but that doesn't necessarily mean that it will be mapped to the SPI1 peripheral of the target microcontroller. The mapping will be determined by the desired pads for the SPI signals and possibly other desired settings.

pads specifies the desired pad for each signal of this SPI peripheral. Usually, this will uniquely define the peripheral to be used. Unused signals can be skipped.

role: master: role can be master or slave, also known as host and device. There exist a number of other terms, but we limit ourselves to two terms for each role. We include master and slave because these are the most common ones, and host and device to offer an alternative for those who are not happy with these historically charged terms.

communication_mode: duplex: communication mode can be duplex (the traditional mode using MISO and MOSI to transmit and receive at the same time) or half-duplex, meaning the same wire between master MOSI and slave MISO is used for both directions. Unidirectional communication can be achieved by specifying duplex and connecting only MISO-to-MISO or MOSI-to-MOSI wires. See also receive-only below.

receive-only (RXOMEN in the F411) disables the transmission signal (MISO in slave mode, MOSI in master mode). According to the F411 manual, it is useful when communicating with multiple slaves to avoid data collisions (not completely clear to me; avoids NSS signals for master-to-slave communication?)

DICUSS(Lars): I assume they mean that you can use the unused pin for other usages/ do not read noise on the unconnected pin? Anyhow, A send only should also be given for symmetry. But then I think we have this double with the duplex / half duplex setting. So maybe consolidate those together?

REPLY(Johan) Half duplex is different from unidirectional communication. See figures in APM32F411xCxE user manual v1.4 page 327. In half-duplex mode (what they call bidirectional mode), master-MOSI is connected to slave-MISO. In unidirectional mode, master-MOSI is connected to slave-MOSI or master-MISO is connected to slave-MISO, depending on the desired direction.

DICUSS(Lars): “ master-MOSI is connected to slave-MISO” AHHH. Why? That is just wrong!

REPLY(Johan) I agree: this is a bad idea. Unfortunately, it is what they do in the F411 chip. Whether you actually need to mkae that connection depends on the other device; in the F411 settings, it only means that half duplex communication uses MOSI in master mode and MISO in slave mode. Unidirectional receive-only uses MISO in master mode and MOSI in slave mode, and vice-versa for transmit-only.

Maybe we just need a setting to specify which pad should be used for half-duplex communication.

This whole receive-only setting is a bit obscure to me; shall we postpone it to a later version?

frame_format can be motorola or ti. ti format has implications for clock polarity and phase and nss handling that are currently unclear; we may need to figure this out and possibly replace this parameter by more explicit settings.

clock_polarity: idle_low or idle_high sets the clock level between transmissions of data. Also often called CPOL.

clock_phase sets the clock transition at which the data is sampled; sample_on_leading_edge samples the data on the edge from idle value to non-idle value, and sample_on_trailinging_edge samples the data on the edge from non-idle value to idle value. Also often called CPHA.

Sometimes the documentation talks about a SPI Mode with the value of 0 to 3. This mode maps to the phase and polarity as described in the following table:

Mode	CPOL	CPHA	description
0	0	0	clock: idle_low, phase: sample_on_leading_edge
1	0	1	clock: idle_low, phase: sample_on_trailing_edge
2	1	0	clock: idle_high, phase: sample_on_leading_edge
3	1	1	clock: idle_high, phase: sample_on_trailing_edge

bit_order can be msb_first or lsb_first

baud_rate is the desired clock frequency during transmission. Code generation should try to approach it as closely as possible. Will there be a feedback mechanism to report the achieved (nominal) frequency?

DICUSS(Lars): What do you have in mind? How can the code generator provide feedback? Shall we define some sort of log file that goes into the zip with the generated code that you can read and check for things like this?

REPLY(Johan): I am not sure yet. My ideal for baud rate would be to show immediately in the UI what the closest achievable baud rate is. If that is not (yet) possible, I would like at least to be able to show the actual baud rate in the UI. So some structured feedback would be useful; maybe another json file in the generated code? It could also be useful to provide error feedback from code generation, e.g. if the requested parameters are not achievable.

DICUSS(Lars): I added a report file to the list of generated files.(mbsp_report.txt) We probably then need a format for that also,…

REPLY(Johan): Right, but probably not necessary for version 1.

crc: enabled or disabled. The Geehy F411 SPI peripherals provide hardware for CRC generation and checking

DICUSS(Lars): I think that is something the driver layer should deal with. But not sure.

REPLY(Johan): CRC settings must match the expectations of the device

crc_polynomial: an unsigned integer representing the polynomial to be used for CRC generation and checking. Do we need to specify the number of bits as well?

DICUSS(Lars): The 7 has no meaning at all for me. We at least need the documentation that explains how to interpret the value. Also driver layer. Documentation can be a link to wikipedia or whatever.

REPLY(Johan) You are right. Wikipedia https://en.wikipedia.org/wiki/Cyclic_redundancy_check mentions four different notations to specify a polynomial for a CRC: normal, reversed, reciprocal and reversed reciprocal. They can be converted into each other, so we can choose one. The reciprocal versions have the advantage that you need to specify only a single number, not a separate length and value. Some standardized CRC algorithms have extra steps in addition to the core CRC calculation, like prepending an initial value or xor-ing the final value with some constant. I assume that these steps are usually not implemented in hardware. Do we need to take that into account for code generation?

DICUSS(Lars): can we move this to version 2? long answer: It depends. The CRC, as you said, depends on the device/communication partner. And that might expect some crazy initialization value and some Xor at the end or whatever. I would suggest to look at this from the use case perspective and find solutions for one use case after the other. That way these settings are derived from the use case and we do not depend on the user to provide consistent settings. Then we can also have a generic solution where the user has to give all the variables (initialization, Xor,..) and w then do exactly that and hope for the best.

REPLY(Johan) Agreed: let's postpone this. It is not essential for a demo, so we can even postpone it until after the demo.

REPLY(Johan) How/where would you specify the parameters of the connected device? Many other SPI parameters specified here also depend on the connected device. For example clock polarity and phase and bit order must match the device's expectations.

DICUSS(Lars): We could add explicit support for some devices. Then the user would just select the device and all the dependent settings (CPOL/CPHA,CRC, bits per transfer..) would be set accordingly. Does that make sense?

REPLY(Johan) Does that mean that for supported devices, you don't need an explicit SPI configuration? That makes sense to me. I think we would still need an SPI configuration for unsupported devices; it will take some time before we can support all existing devices in the world . It is OK for me to initially only provide SPI settings for unsupported devices without CRC; that can be added later.

QSPI group

TBD

SDIO group

TBD

I2C group

TBD

I3C group

TBD

I2S group

TBD

CAN group

TBD

USB group

TBD

Watchdog group

TBD

Random_Number group

TBD

CRC group

TBD

... group

TBD